gradebook column position now saves to db

if an assignment, aggregate or total column is
reordered in the gradebook, the custom ordering
will be saved to the user's preferences. if any
column is resized, that size will be saved to
the user's preferences for that assignment id.
this allows column size and column position
settings to persist between multiple computers
/ browsers.

closes CNVS-17052

Change-Id: Ibe77de372b17764233a7662c3fc8517ddc9df1dc
Reviewed-on: https://gerrit.instructure.com/52017
Tested-by: Jenkins
Reviewed-by: Spencer Olson <solson@instructure.com>
QA-Review: Deepeeca Soundarrajan <dsoundarrajan@instructure.com>
Product-Review: Dylan Ross <dross@instructure.com>
This commit is contained in:
Dylan Ross 2015-04-30 09:18:54 -06:00
parent ac853ceb4d
commit ddbaeb9364
5 changed files with 104 additions and 44 deletions

View File

@ -87,6 +87,8 @@ define [
@mgpEnabled = ENV.GRADEBOOK_OPTIONS.multiple_grading_periods_enabled
@gradingPeriods = ENV.GRADEBOOK_OPTIONS.active_grading_periods
@gradingPeriodToShow = @getGradingPeriodToShow()
@gradebookColumnSizeSettings = ENV.GRADEBOOK_OPTIONS.gradebook_column_size_settings
@gradebookColumnOrderSettings = ENV.GRADEBOOK_OPTIONS.gradebook_column_order_settings
$.subscribe 'assignment_group_weights_changed', @handleAssignmentGroupWeightChange
$.subscribe 'assignment_muting_toggled', @handleAssignmentMutingChange
@ -334,13 +336,11 @@ define [
potential_students
getStoredSortOrder: =>
userSettings.contextGet('sort_grade_columns_by') || { sortType: @defaultSortType }
@gradebookColumnOrderSettings || {sortType: @defaultSortType}
setStoredSortOrder: (newSortOrder) =>
if newSortOrder.sortType == @defaultSortType
userSettings.contextRemove('sort_grade_columns_by')
else
userSettings.contextSet('sort_grade_columns_by', newSortOrder)
url = ENV.GRADEBOOK_OPTIONS.gradebook_column_order_settings_url
$.ajaxJSON(url, 'POST', {column_order: newSortOrder})
onColumnsReordered: =>
# determine if assignment columns or custom columns were reordered
@ -374,9 +374,9 @@ define [
@$columnArrangementTogglers.each ->
$(this).closest('li').showIf $(this).data('arrangeColumnsBy') isnt newSortOrder.sortType
arrangeColumnsBy: (newSortOrder) =>
arrangeColumnsBy: (newSortOrder, isFirstArrangement) =>
@setArrangementTogglersVisibility(newSortOrder)
@setStoredSortOrder(newSortOrder)
@setStoredSortOrder(newSortOrder) unless isFirstArrangement
columns = @grid.getColumns()
frozen = columns.splice(0, @numberOfFrozenCols)
@ -932,8 +932,8 @@ define [
@$columnArrangementTogglers = $('#gradebook-toolbar [data-arrange-columns-by]').bind 'click', (event) =>
event.preventDefault()
newSortOrder = { sortType: $(event.currentTarget).data('arrangeColumnsBy') }
@arrangeColumnsBy(newSortOrder)
@arrangeColumnsBy(@getStoredSortOrder())
@arrangeColumnsBy(newSortOrder, false)
@arrangeColumnsBy(@getStoredSortOrder(), true)
$('#gradebook_settings').show().kyleMenu()
@ -1079,11 +1079,20 @@ define [
@setAssignmentWarnings()
studentColumnWidth = 150
identifierColumnWidth = 100
if @gradebookColumnSizeSettings
if @gradebookColumnSizeSettings['student']
studentColumnWidth = parseInt(@gradebookColumnSizeSettings['student'])
if @gradebookColumnSizeSettings['secondary_identifier']
identifierColumnWidth = parseInt(@gradebookColumnSizeSettings['secondary_identifier'])
@parentColumns = [
id: 'student'
name: htmlEscape I18n.t 'student_name', 'Student Name'
field: 'display_name'
width: 150
width: studentColumnWidth
cssClass: "meta-cell"
resizable: true
sortable: true
@ -1092,7 +1101,7 @@ define [
id: 'secondary_identifier'
name: htmlEscape I18n.t 'secondary_id', 'Secondary ID'
field: 'secondary_identifier'
width: 100
width: identifierColumnWidth
cssClass: "meta-cell secondary_identifier_cell"
resizable: true
sortable: true
@ -1106,6 +1115,11 @@ define [
SubmissionCell.out_of
minWidth = if outOfFormatter then 70 else 90
fieldName = "assignment_#{id}"
assignmentWidth = testWidth(assignment.name, minWidth, columnWidths.assignment.default_max)
if @gradebookColumnSizeSettings && @gradebookColumnSizeSettings[fieldName]
assignmentWidth = parseInt(@gradebookColumnSizeSettings[fieldName])
columnDef =
id: fieldName
field: fieldName
@ -1117,7 +1131,7 @@ define [
SubmissionCell
minWidth: columnWidths.assignment.min,
maxWidth: columnWidths.assignment.max,
width: testWidth(assignment.name, minWidth, columnWidths.assignment.default_max),
width: assignmentWidth
sortable: true
toolTip: assignment.name
type: 'assignment'
@ -1134,22 +1148,33 @@ define [
columnDef
@aggregateColumns = for id, group of @assignmentGroups
fieldName = "assignment_group_#{id}"
aggregateWidth = testWidth(group.name, columnWidths.assignmentGroup.min, columnWidths.assignmentGroup.default_max)
if @gradebookColumnSizeSettings && @gradebookColumnSizeSettings[fieldName]
aggregateWidth = parseInt(@gradebookColumnSizeSettings[fieldName])
{
id: "assignment_group_#{id}"
field: "assignment_group_#{id}"
id: fieldName
field: fieldName
formatter: @groupTotalFormatter
name: @assignmentGroupHtml(group.name, group.group_weight)
toolTip: group.name
object: group
minWidth: columnWidths.assignmentGroup.min,
maxWidth: columnWidths.assignmentGroup.max,
width: testWidth(group.name, columnWidths.assignmentGroup.min, columnWidths.assignmentGroup.default_max)
width: aggregateWidth
cssClass: "meta-cell assignment-group-cell",
sortable: true
type: 'assignment_group'
}
total = I18n.t "total", "Total"
totalWidth = testWidth("Total", columnWidths.total.min, columnWidths.total.max)
if @gradebookColumnSizeSettings && @gradebookColumnSizeSettings['total_grade']
totalWidth = @gradebookColumnSizeSettings['total_grade']
total_column =
id: "total_grade"
field: "total_grade"
@ -1161,7 +1186,7 @@ define [
toolTip: total
minWidth: columnWidths.total.min
maxWidth: columnWidths.total.max
width: testWidth("Total", columnWidths.total.min, columnWidths.total.max)
width: totalWidth
cssClass: if @totalColumnInFront then 'meta-cell' else 'total-cell'
sortable: true
type: 'total_grade'
@ -1214,11 +1239,23 @@ define [
false
@grid.onColumnsReordered.subscribe @onColumnsReordered
@grid.onBeforeEditCell.subscribe @onBeforeEditCell
@grid.onColumnsResized.subscribe @onColumnsResized
@onGridInit()
onColumnsResized: (event, obj) =>
grid = obj.grid
columns = grid.getColumns()
_.each columns, (column) =>
if column.previousWidth && column.width != column.previousWidth
@saveColumnWidthPreference(column.id, column.width)
saveColumnWidthPreference: (id, newWidth) ->
url = ENV.GRADEBOOK_OPTIONS.gradebook_column_size_settings_url
$.ajaxJSON(url, 'POST', {column_id: id, column_size: newWidth})
onBeforeEditCell: (event, {row, cell}) =>
$cell = @grid.getCellNode(row, cell)
return false if $($cell).hasClass("cannot_edit") || $($cell).find(".gradebook-cell").hasClass("cannot_edit")

View File

@ -251,7 +251,11 @@ class GradebooksController < ApplicationController
:sis_app_url => Setting.get('sis_app_url', nil),
:sis_app_token => Setting.get('sis_app_token', nil),
:post_grades_feature_enabled => @context.feature_enabled?(:post_grades),
:list_students_by_sortable_name_enabled => @context.feature_enabled?(:gradebook_list_students_by_sortable_name)
:list_students_by_sortable_name_enabled => @context.feature_enabled?(:gradebook_list_students_by_sortable_name),
:gradebook_column_size_settings => @current_user.preferences[:gradebook_column_size],
:gradebook_column_size_settings_url => change_gradebook_column_size_course_gradebook_url,
:gradebook_column_order_settings => @current_user.preferences[:gradebook_column_order].try(:[], @context.id),
:gradebook_column_order_settings_url => save_gradebook_column_order_course_gradebook_url
}
end
@ -420,6 +424,30 @@ class GradebooksController < ApplicationController
@headers = false
end
def change_gradebook_column_size
if authorized_action(@context, @current_user, :manage_grades)
unless @current_user.preferences.key?(:gradebook_column_size)
@current_user.preferences[:gradebook_column_size] = {}
end
@current_user.preferences[:gradebook_column_size][params[:column_id]] = params[:column_size]
@current_user.save!
render json: nil
end
end
def save_gradebook_column_order
if authorized_action(@context, @current_user, :manage_grades)
unless @current_user.preferences.key?(:gradebook_column_order)
@current_user.preferences[:gradebook_column_order] = {}
end
@current_user.preferences[:gradebook_column_order][@context.id] = params[:column_order]
@current_user.save!
render json: nil
end
end
def change_gradebook_version
@current_user.preferences[:gradebook_version] = params[:version]
@current_user.save!

View File

@ -192,6 +192,8 @@ CanvasRails::Application.routes.draw do
post :speed_grader_settings
get :history
post :update_submission
post :change_gradebook_column_size
post :save_gradebook_column_order
end
end

View File

@ -134,18 +134,14 @@ describe "assignment column headers" do
end
it "should load custom column ordering" do
# since drag and drop doesn't work, we'll just have to store a fake configuration and make sure it gets loaded.
script = <<-JS
sortOrder = {
sortType: 'custom',
customOrder: [#{@third_assignment.id}, #{@second_assignment.id}, #{@first_assignment.id}] };
localStorage.setItem('_#{@user.id}_course_#{@course.id}_sort_grade_columns_by', JSON.stringify(sortOrder));
JS
driver.execute_script(script)
@user.preferences[:gradebook_column_order] = {}
@user.preferences[:gradebook_column_order][@course.id] = {
sortType: 'custom',
customOrder: ["#{@third_assignment.id}", "#{@second_assignment.id}", "#{@first_assignment.id}"]
}
@user.save!
get "/courses/#{@course.id}/gradebook2"
wait_for_ajaximations
first_row_cells = find_slick_cells(0, f('#gradebook_grid .container_1'))
validate_cell_text(first_row_cells[0], '-')
validate_cell_text(first_row_cells[1], @assignment_2_points)
@ -159,14 +155,12 @@ describe "assignment column headers" do
end
it "should put new assignments at the end when columns have custom order" do
script = <<-JS
sortOrder = {
sortType: 'custom',
customOrder: [#{@third_assignment.id}, #{@second_assignment.id}, #{@first_assignment.id}] };
localStorage.setItem('_#{@user.id}_course_#{@course.id}_sort_grade_columns_by', JSON.stringify(sortOrder));
JS
driver.execute_script(script)
@user.preferences[:gradebook_column_order] = {}
@user.preferences[:gradebook_column_order][@course.id] = {
sortType: 'custom',
customOrder: ["#{@third_assignment.id}", "#{@second_assignment.id}", "#{@first_assignment.id}"]
}
@user.save!
@fourth_assignment = assignment_model({
:course => @course,
:name => "new assignment",
@ -187,13 +181,13 @@ describe "assignment column headers" do
end
it "should maintain order of remaining assignments if an assignment is destroyed" do
script = <<-JS
sortOrder = {
sortType: 'custom',
customOrder: [#{@third_assignment.id}, #{@second_assignment.id}, #{@first_assignment.id}] };
localStorage.setItem('_#{@user.id}_course_#{@course.id}_sort_grade_columns_by', JSON.stringify(sortOrder));
JS
driver.execute_script(script)
@user.preferences[:gradebook_column_order] = {}
@user.preferences[:gradebook_column_order][@course.id] = {
sortType: 'custom',
customOrder: ["#{@third_assignment.id}", "#{@second_assignment.id}", "#{@first_assignment.id}"]
}
@user.save!
@first_assignment.destroy
get "/courses/#{@course.id}/gradebook2"

View File

@ -159,7 +159,6 @@ describe "gradebook2" do
it "should handle muting/unmuting correctly" do
get "/courses/#{@course.id}/gradebook2"
toggle_muting(@second_assignment)
expect(fj(".container_1 .slick-header-column[id*='assignment_#{@second_assignment.id}'] .muted")).to be_displayed
expect(@second_assignment.reload).to be_muted