Skip to content

Commit

Permalink
allow filtering assignment columns by module
Browse files Browse the repository at this point in the history
closes CNVS-36724

test plan:
* Create a course with multiple modules and at least one student
* Ensure each module has at least two assignments
* Create an assignment outside of any modules as well
* Go to Gradezilla
* Verify that you see a column for each assignment you created
  for that course, including assignments from all modules and
  assignments that aren't part of any module
* From the View menu, ensure "Modules" is selected in the Filters
  menu group
* Verify that a button labelled "All Modules" shows up next to
  the other filters (or next to the Search field if no other
  filters are in play)
* Click on the "All Modules" button and verify that you see the
  names of all the modules you created for this course

* Choose one of the modules
* Verify the button now changes to say the name of the module
  instead of "All Modules"
* Verify that there is no page reload
* Verify that only columns for assignments from the selected
  module are now visible
* Select a different filter from the module filter
* Verify the button now changes to say the name of the new module
* Verify that there is no page reload
* Verify that only columns for assignments from the selected
  module are now visible
* Select "All Modules" again
* Verify that you see a column for each assignment you created
  for that course, including assignments from all modules and
  assignments that aren't part of any module

Change-Id: I657c65f54f209bdd245a0d1c103436164c16e147
Reviewed-on: https://gerrit.instructure.com/114222
Tested-by: Jenkins
Reviewed-by: Keith T. Garner <[email protected]>
Reviewed-by: Derek Bender <[email protected]>
QA-Review: KC Naegle <[email protected]>
Product-Review: Christi Wruck
  • Loading branch information
sjaveed committed Jun 8, 2017
1 parent 596cb80 commit ff501e5
Show file tree
Hide file tree
Showing 7 changed files with 365 additions and 11 deletions.
56 changes: 50 additions & 6 deletions app/coffeescripts/gradezilla/Gradebook.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ define [
'jsx/gradezilla/default_gradebook/components/GradebookMenu'
'jsx/gradezilla/default_gradebook/components/ViewOptionsMenu'
'jsx/gradezilla/default_gradebook/components/ActionMenu'
'jsx/gradezilla/default_gradebook/components/ModuleFilter'
'jsx/gradezilla/default_gradebook/components/GridColor'
'jsx/gradezilla/default_gradebook/components/StatusesModal'
'jsx/gradezilla/default_gradebook/components/GradebookSettingsModal'
Expand Down Expand Up @@ -102,10 +103,10 @@ define [
SubmissionCell, NumberCompare, natcompare, ConvertCase, htmlEscape, SetDefaultGradeDialogManager,
CurveGradesDialogManager, GradebookApi, CellEditorFactory, studentRowHeaderConstants, AssignmentColumnHeader,
AssignmentGroupColumnHeader, AssignmentRowCellPropFactory, CustomColumnHeader, StudentColumnHeader, StudentRowHeader,
TotalGradeColumnHeader, GradebookMenu, ViewOptionsMenu, ActionMenu, GridColor, StatusesModal, GradebookSettingsModal,
PostGradesStore, PostGradesApp, SubmissionStateMap, DownloadSubmissionsDialogManager, ReuploadSubmissionsDialogManager,
GroupTotalCellTemplate, SectionMenuView, GradingPeriodMenuView, GradebookKeyboardNav, AssignmentMuterDialogManager,
assignmentHelper, { default: Button }, { default: IconSettingsSolid }) ->
TotalGradeColumnHeader, GradebookMenu, ViewOptionsMenu, ActionMenu, ModuleFilter, GridColor, StatusesModal,
GradebookSettingsModal, PostGradesStore, PostGradesApp, SubmissionStateMap, DownloadSubmissionsDialogManager,
ReuploadSubmissionsDialogManager, GroupTotalCellTemplate, SectionMenuView, GradingPeriodMenuView, GradebookKeyboardNav,
AssignmentMuterDialogManager, assignmentHelper, { default: Button }, { default: IconSettingsSolid }) ->

isAdmin = =>
_.contains(ENV.current_user_roles, 'admin')
Expand Down Expand Up @@ -232,7 +233,9 @@ define [

dataLoader = DataLoader.loadGradebookData(
assignmentGroupsURL: @options.assignment_groups_url
assignmentGroupsParams: { exclude_response_fields: @fieldsToExcludeFromAssignments }
assignmentGroupsParams:
exclude_response_fields: @fieldsToExcludeFromAssignments
include: @fieldsToIncludeWithAssignments
contextModulesURL: @options.context_modules_url
customColumnsURL: @options.custom_columns_url

Expand Down Expand Up @@ -633,7 +636,8 @@ define [
assignmentFilters = [
@filterAssignmentBySubmissionTypes,
@filterAssignmentByPublishedStatus,
@filterAssignmentByGradingPeriod
@filterAssignmentByGradingPeriod,
@filterAssignmentByModule
]

matchesAllFilters = (assignment) =>
Expand All @@ -653,6 +657,15 @@ define [
return true unless @isFilteringColumnsByGradingPeriod()
@getGradingPeriodToShow() in @listGradingPeriodsForAssignment(assignment.id)

filterAssignmentByModule: (assignment) =>
contextModuleFilterSetting = @getFilterColumnsBySetting('contextModuleId')
return true unless contextModuleFilterSetting
# Firefox returns a value of "null" (String) for this when nothing is set. The comparison
# to 'null' below is a result of that
return true if contextModuleFilterSetting == '0' || contextModuleFilterSetting == 'null'

@getFilterColumnsBySetting('contextModuleId') in (assignment.module_ids || [])

## Course Content Event Handlers

handleAssignmentMutingChange: (assignment) =>
Expand Down Expand Up @@ -1098,6 +1111,35 @@ define [
@setAssignmentWarnings()
@updateColumnsAndRenderViewOptionsMenu()

updateCurrentModule: (moduleId) =>
if @getFilterColumnsBySetting('contextModuleId') != moduleId
@setFilterColumnsBySetting('contextModuleId', moduleId)
@saveSettings()
@setAssignmentWarnings()
@updateColumnsAndRenderViewOptionsMenu()
@updateModulesFilterVisibility()

updateModulesFilterVisibility: () ->
mountPoint = document.getElementById('modules-filter-container')

if @listContextModules()?.length > 0 and 'modules' in @gridDisplaySettings.selectedViewOptionsFilters
modules = [
{
id: '0'
name: I18n.t('All Modules')
position: -1
}
].concat(@listContextModules())
props =
modules: modules
onSelect: @updateCurrentModule
selectedModuleId: @getFilterColumnsBySetting('contextModuleId') || '0'

@moduleFilterMenu = renderComponent(ModuleFilter, mountPoint, props)
else if @moduleFilterMenu?
ReactDOM.unmountComponentAtNode(mountPoint)
@moduleFilterMenu = null

initSubmissionStateMap: =>
@submissionStateMap = new SubmissionStateMap
hasGradingPeriods: @gradingPeriodSet?
Expand Down Expand Up @@ -1279,6 +1321,7 @@ define [
renderFilters: =>
@updateSectionFilterVisibility()
@updateGradingPeriodFilterVisibility()
@updateModulesFilterVisibility()

renderGridColor: =>
gridColorMountPoint = document.querySelector('[data-component="GridColor"]')
Expand Down Expand Up @@ -1816,6 +1859,7 @@ define [
not @isFilteringColumnsByGradingPeriod()

fieldsToExcludeFromAssignments: ['description', 'needs_grading_count', 'in_closed_grading_period']
fieldsToIncludeWithAssignments: ['module_ids']

studentsUrl: ->
switch
Expand Down
5 changes: 4 additions & 1 deletion app/controllers/gradebook_settings_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ def update
def gradebook_settings_params
params.require(:gradebook_settings).permit(
{
filter_columns_by: [:grading_period_id],
filter_columns_by: [
:context_module_id,
:grading_period_id
],
selected_view_options_filters: []
},
:show_concluded_enrollments,
Expand Down
5 changes: 5 additions & 0 deletions app/controllers/gradebooks_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,11 @@ def change_gradebook_version
redirect_to polymorphic_url([@context, 'gradebook'])
end

def visible_modules?
@visible_modules ||= @context.modules_visible_to(@current_user)
end
helper_method :visible_modules?

private

def set_gradebook_warnings(groups, assignments)
Expand Down
84 changes: 84 additions & 0 deletions app/jsx/gradezilla/default_gradebook/components/ModuleFilter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright (C) 2017 - present Instructure, Inc.
*
* This file is part of Canvas.
*
* Canvas is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, version 3 of the License.
*
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import React from 'react';
import { arrayOf, func, number, shape, string } from 'prop-types';
import IconMiniArrowDownSolid from 'instructure-icons/lib/Solid/IconMiniArrowDownSolid';
import Button from 'instructure-ui/lib/components/Button';
import { MenuItem } from 'instructure-ui/lib/components/Menu';
import PopoverMenu from 'instructure-ui/lib/components/PopoverMenu';

function currentlySelectedModule (modules, selectedModuleId) {
const selectedModule = modules.find(module => module.id === selectedModuleId);

return selectedModule || {};
}

function sortedModules (modules) {
return modules.sort((a, b) => (a.position - b.position));
}

class ModuleFilter extends React.Component {
static propTypes = {
modules: arrayOf(
shape({
id: string.isRequired,
name: string.isRequired,
position: number.isRequired
})).isRequired,
onSelect: func.isRequired,
selectedModuleId: string.isRequired
};

onSelectModule = (_event, value) => {
this.props.onSelect(value);
}

bindMenuContent = (menuContent) => {
this.menuContent = menuContent;
}

render () {
const { name } = currentlySelectedModule(this.props.modules, this.props.selectedModuleId);

return (
<PopoverMenu
trigger={
<Button>
{name}<IconMiniArrowDownSolid />
</Button>
}
contentRef={this.bindMenuContent}
onSelect={this.onSelectModule}
>
{
sortedModules(this.props.modules).map(module => (
<MenuItem
key={module.id}
value={module.id}
>
{module.name}
</MenuItem>
))
}
</PopoverMenu>
)
}
}

export default ModuleFilter;
4 changes: 4 additions & 0 deletions app/views/gradebooks/gradezilla/gradebook.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@
<div class="gradebook-filter-container" id="grading-periods-filter-container"></div>
<% end %>

<% if visible_modules? %>
<div class="gradebook-filter-container" id="modules-filter-container"></div>
<% end %>

<div class="gradebook-filter-container section-button-placeholder"></div>

<div class="gradebook-filter-container gradebook_filter" style="display:none">
Expand Down
Loading

0 comments on commit ff501e5

Please sign in to comment.