diff --git a/cms/djangoapps/contentstore/views/course.py b/cms/djangoapps/contentstore/views/course.py index 1b0872583b56..e9d5fe8566d6 100644 --- a/cms/djangoapps/contentstore/views/course.py +++ b/cms/djangoapps/contentstore/views/course.py @@ -1327,6 +1327,7 @@ def grading_handler(request, course_key_string, grader_index=None): 'grading_url': reverse_course_url('grading_handler', course_key), 'is_credit_course': is_credit_course(course_key), 'mfe_proctored_exam_settings_url': get_proctored_exam_settings_url(course_module.id), + 'default_grade_designations': settings.DEFAULT_GRADE_DESIGNATIONS }) elif 'application/json' in request.META.get('HTTP_ACCEPT', ''): if request.method == 'GET': diff --git a/cms/envs/common.py b/cms/envs/common.py index 01a5fc692843..b67078b4cdad 100644 --- a/cms/envs/common.py +++ b/cms/envs/common.py @@ -2327,6 +2327,14 @@ # Rate limit for regrading tasks that a grading policy change can kick off POLICY_CHANGE_TASK_RATE_LIMIT = '300/h' +# .. setting_name: DEFAULT_GRADE_DESIGNATIONS +# .. setting_default: ['A', 'B', 'C', 'D'] +# .. setting_description: The default 'pass' grade cutoff designations to be used. The failure grade +# is always 'F' and should not be included in this list. +# .. setting_warning: The DEFAULT_GRADE_DESIGNATIONS list must have more than one designation, +# or else ['A', 'B', 'C', 'D'] will be used as the default grade designations. +DEFAULT_GRADE_DESIGNATIONS = ['A', 'B', 'C', 'D'] + ############## Settings for CourseGraph ############################ # .. setting_name: COURSEGRAPH_JOB_QUEUE diff --git a/cms/static/js/factories/settings_graders.js b/cms/static/js/factories/settings_graders.js index 2be17111e0e2..b59961acbd42 100644 --- a/cms/static/js/factories/settings_graders.js +++ b/cms/static/js/factories/settings_graders.js @@ -2,7 +2,7 @@ define([ 'jquery', 'js/views/settings/grading', 'js/models/settings/course_grading_policy' ], function($, GradingView, CourseGradingPolicyModel) { 'use strict'; - return function(courseDetails, gradingUrl) { + return function(courseDetails, gradingUrl, gradeDesignations) { var model, editor; $('form :input') @@ -17,7 +17,8 @@ define([ model.urlRoot = gradingUrl; editor = new GradingView({ el: $('.settings-grading'), - model: model + model: model, + gradeDesignations: gradeDesignations }); editor.render(); }; diff --git a/cms/static/js/views/settings/grading.js b/cms/static/js/views/settings/grading.js index e226147bdde1..e689ff11b850 100644 --- a/cms/static/js/views/settings/grading.js +++ b/cms/static/js/views/settings/grading.js @@ -24,7 +24,7 @@ define(['js/views/validation', 'focus :input': 'inputFocus', 'blur :input': 'inputUnfocus' }, - initialize: function() { + initialize: function(options) { // load template for grading view var self = this; this.template = HtmlUtils.template( @@ -34,6 +34,7 @@ define(['js/views/validation', $('#course_grade_cutoff-tpl').text() ); this.setupCutoffs(); + this.setupGradeDesignations(options.gradeDesignations); this.listenTo(this.model, 'invalid', this.handleValidationError); this.listenTo(this.model, 'change', this.showNotificationBar); @@ -297,7 +298,7 @@ define(['js/views/validation', addNewGrade: function(e) { e.preventDefault(); var gradeLength = this.descendingCutoffs.length; // cutoffs doesn't include fail/f so this is only the passing grades - if (gradeLength > 3) { + if (gradeLength > this.GRADES.length - 1) { // TODO shouldn't we disable the button return; } @@ -377,6 +378,9 @@ define(['js/views/validation', this.descendingCutoffs = _.sortBy(this.descendingCutoffs, function(gradeEle) { return -gradeEle.cutoff; }); }, + setupGradeDesignations: function(gradeDesignations) { + if (Array.isArray(gradeDesignations) && gradeDesignations.length > 1) { this.GRADES = gradeDesignations; } + }, revertView: function() { var self = this; this.model.fetch({ diff --git a/cms/static/sass/views/_settings.scss b/cms/static/sass/views/_settings.scss index 10d2ccc3272a..a786f6f2082a 100644 --- a/cms/static/sass/views/_settings.scss +++ b/cms/static/sass/views/_settings.scss @@ -777,23 +777,23 @@ height: 17px; } - &:nth-child(1) { + &:nth-child(5n+1) { background: #4fe696; } - &:nth-child(2) { + &:nth-child(5n+2) { background: #ffdf7e; } - &:nth-child(3) { + &:nth-child(5n+3) { background: #ffb657; } - &:nth-child(4) { + &:nth-child(5n+4) { background: #ef54a1; } - &:nth-child(5), + &:nth-child(5n+5), &.bar-fail { background: #fb336c; } diff --git a/cms/templates/settings_graders.html b/cms/templates/settings_graders.html index ac7119177978..d8b7d3bc0ebd 100644 --- a/cms/templates/settings_graders.html +++ b/cms/templates/settings_graders.html @@ -34,7 +34,8 @@ SettingsGradersFactory( _.extend(${dump_js_escaped_json(course_details, cls=CourseSettingsEncoder) | n, decode.utf8}, {is_credit_course: ${is_credit_course | n, dump_js_escaped_json}}), - "${grading_url | n, js_escaped_string}" + "${grading_url | n, js_escaped_string}", + ${default_grade_designations | n, dump_js_escaped_json}, ); });