From 3ca85eac1228f281212b306f3e7ddfded96f7dd8 Mon Sep 17 00:00:00 2001 From: Kaustav Banerjee Date: Mon, 12 Jun 2023 13:37:20 +0530 Subject: [PATCH] feat: default grade designations configurable from settings (#541) (cherry picked from commit 7a7af8cdc16416ec8e3289f9482e734b58145b0e) (cherry picked from commit 94754317c3f8709b7cd8980cbf2f9e5181494fb0) --- cms/djangoapps/contentstore/views/course.py | 1 + cms/envs/common.py | 8 ++++++++ cms/static/js/factories/settings_graders.js | 5 +++-- cms/static/js/views/settings/grading.js | 9 ++++++--- cms/static/sass/views/_settings.scss | 10 +++++----- cms/templates/settings_graders.html | 3 ++- 6 files changed, 25 insertions(+), 11 deletions(-) diff --git a/cms/djangoapps/contentstore/views/course.py b/cms/djangoapps/contentstore/views/course.py index a3714195296c..17ce3eea18b1 100644 --- a/cms/djangoapps/contentstore/views/course.py +++ b/cms/djangoapps/contentstore/views/course.py @@ -1365,6 +1365,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_block.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 cf69ac5f1c77..8bce01ff1c52 100644 --- a/cms/envs/common.py +++ b/cms/envs/common.py @@ -2338,6 +2338,14 @@ # Rate limit for regrading tasks that a grading policy change can kick off POLICY_CHANGE_TASK_RATE_LIMIT = '900/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 4320204035ac..684545cc730e 100644 --- a/cms/static/js/views/settings/grading.js +++ b/cms/static/js/views/settings/grading.js @@ -24,7 +24,7 @@ function(ValidatingView, _, $, ui, GraderView, StringUtils, HtmlUtils) { '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 @@ function(ValidatingView, _, $, ui, GraderView, StringUtils, HtmlUtils) { $('#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 @@ function(ValidatingView, _, $, ui, GraderView, StringUtils, HtmlUtils) { 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,7 +378,9 @@ function(ValidatingView, _, $, ui, GraderView, StringUtils, HtmlUtils) { this.descendingCutoffs = _.sortBy(this.descendingCutoffs, function(gradeEle) { return -gradeEle.cutoff; }); }, - revertView: function() { + setupGradeDesignations: function(gradeDesignations) { + if (Array.isArray(gradeDesignations) && gradeDesignations.length > 1) { this.GRADES = gradeDesignations; } + },revertView: function() { var self = this; this.model.fetch({ success: function() { 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}, ); });