MDL-66906 mod_forum: Show learners their grades in a Modal
authorMathew May <mathewm@hotmail.co.nz>
Wed, 16 Oct 2019 06:20:05 +0000 (14:20 +0800)
committerMathew May <mathewm@hotmail.co.nz>
Tue, 12 Nov 2019 08:17:04 +0000 (16:17 +0800)
26 files changed:
grade/classes/component_gradeitem.php
grade/classes/grades/grader/gradingpanel/point/external/fetch.php
grade/classes/grades/grader/gradingpanel/point/external/store.php
grade/classes/grades/grader/gradingpanel/scale/external/fetch.php
grade/classes/grades/grader/gradingpanel/scale/external/store.php
grade/grading/form/guide/classes/grades/grader/gradingpanel/external/fetch.php
grade/grading/form/rubric/classes/grades/grader/gradingpanel/external/fetch.php
mod/forum/amd/build/grades/grader.min.js
mod/forum/amd/build/grades/grader.min.js.map
mod/forum/amd/build/grades/grader/selectors.min.js
mod/forum/amd/build/grades/grader/selectors.min.js.map
mod/forum/amd/build/local/grades/grader.min.js
mod/forum/amd/build/local/grades/grader.min.js.map
mod/forum/amd/src/grades/grader.js
mod/forum/amd/src/grades/grader/selectors.js
mod/forum/amd/src/local/grades/grader.js
mod/forum/classes/grades/forum_gradeitem.php
mod/forum/classes/local/renderers/discussion_list.php
mod/forum/lang/en/forum.php
mod/forum/templates/discussion_list.mustache
mod/forum/templates/grades/view_grade_button.mustache [new file with mode: 0644]
mod/forum/templates/local/grades/view_grade.mustache [new file with mode: 0644]
mod/forum/view.php
theme/boost/scss/moodle/grade.scss
theme/boost/style/moodle.css
theme/classic/style/moodle.css

index 0f5ec62..1245b02 100644 (file)
@@ -407,6 +407,37 @@ abstract class component_gradeitem {
      */
     abstract public function get_all_grades(): array;
 
+    /**
+     * Get the grade item instance id.
+     *
+     * This is typically the cmid in the case of an activity, and relates to the iteminstance field in the grade_items
+     * table.
+     *
+     * @return int
+     */
+    abstract public function get_grade_instance_id(): int;
+
+    /**
+     * Get the core grade item from the current component grade item.
+     * This is mainly used to access the max grade for a gradeitem
+     *
+     * @return \grade_item The grade item
+     */
+    public function get_grade_item(): \grade_item {
+        global $CFG;
+        require_once("{$CFG->libdir}/gradelib.php");
+
+        [$itemtype, $itemmodule] = \core_component::normalize_component($this->component);
+        $gradeitem = \grade_item::fetch([
+            'itemtype' => $itemtype,
+            'itemmodule' => $itemmodule,
+            'itemnumber' => $this->itemnumber,
+            'iteminstance' => $this->get_grade_instance_id(),
+        ]);
+
+        return $gradeitem;
+    }
+
     /**
      * Create or update the grade.
      *
index 4c86bbd..5feb55d 100644 (file)
@@ -131,8 +131,9 @@ class fetch extends external_api {
         $gradeduser = \core_user::get_user($gradeduserid);
         $hasgrade = $gradeitem->user_has_grade($gradeduser);
         $grade = $gradeitem->get_grade_for_user($gradeduser, $USER);
+        $maxgrade = (int) $gradeitem->get_grade_item()->grademax;
 
-        return self::get_fetch_data($grade, $hasgrade);
+        return self::get_fetch_data($grade, $hasgrade, $maxgrade);
     }
 
     /**
@@ -140,14 +141,17 @@ class fetch extends external_api {
      *
      * @param stdClass $grade
      * @param bool $hasgrade
+     * @param int $maxgrade
      * @return array
      */
-    public static function get_fetch_data(stdClass $grade, bool $hasgrade): array {
+    public static function get_fetch_data(stdClass $grade, bool $hasgrade, int $maxgrade): array {
         return [
             'templatename' => 'core_grades/grades/grader/gradingpanel/point',
             'hasgrade' => $hasgrade,
             'grade' => [
                 'grade' => $grade->grade,
+                'usergrade' => $grade->grade,
+                'maxgrade' => $maxgrade,
                 'timecreated' => $grade->timecreated,
                 'timemodified' => $grade->timemodified,
             ],
@@ -167,6 +171,8 @@ class fetch extends external_api {
             'hasgrade' => new external_value(PARAM_BOOL, 'Does the user have a grade?'),
             'grade' => new external_single_structure([
                 'grade' => new external_value(PARAM_FLOAT, 'The numeric grade'),
+                'usergrade' => new external_value(PARAM_RAW, 'Current user grade'),
+                'maxgrade' => new external_value(PARAM_RAW, 'Max possible grade'),
                 'timecreated' => new external_value(PARAM_INT, 'The time that the grade was created'),
                 'timemodified' => new external_value(PARAM_INT, 'The time that the grade was last updated'),
             ]),
index 469a62a..6ca3f99 100644 (file)
@@ -172,7 +172,7 @@ class store extends external_api {
         // Fetch the updated grade back out.
         $grade = $gradeitem->get_grade_for_user($gradeduser, $USER);
 
-        return fetch::get_fetch_data($grade, $hasgrade);
+        return fetch::get_fetch_data($grade, $hasgrade, 0);
     }
 
     /**
index 3e10f5b..6d2e12b 100644 (file)
@@ -129,7 +129,9 @@ class fetch extends external_api {
 
         $gradeduser = \core_user::get_user($gradeduserid);
 
-        return self::get_fetch_data($gradeitem, $gradeduser);
+        $maxgrade = (int) $gradeitem->get_grade_item()->grademax;
+
+        return self::get_fetch_data($gradeitem, $gradeduser, $maxgrade);
     }
 
     /**
@@ -137,9 +139,10 @@ class fetch extends external_api {
      *
      * @param gradeitem $gradeitem
      * @param stdClass $gradeduser
+     * @param int $maxgrade
      * @return array
      */
-    public static function get_fetch_data(gradeitem $gradeitem, stdClass $gradeduser): array {
+    public static function get_fetch_data(gradeitem $gradeitem, stdClass $gradeduser, int $maxgrade): array {
         global $USER;
 
         $hasgrade = $gradeitem->user_has_grade($gradeduser);
@@ -160,6 +163,8 @@ class fetch extends external_api {
             'hasgrade' => $hasgrade,
             'grade' => [
                 'options' => $values,
+                'usergrade' => $grade->grade,
+                'maxgrade' => $maxgrade,
                 'timecreated' => $grade->timecreated,
                 'timemodified' => $grade->timemodified,
             ],
@@ -186,6 +191,8 @@ class fetch extends external_api {
                     ]),
                     'The description of the grade option'
                 ),
+                'usergrade' => new external_value(PARAM_RAW, 'Current user grade'),
+                'maxgrade' => new external_value(PARAM_RAW, 'Max possible grade'),
                 'timecreated' => new external_value(PARAM_INT, 'The time that the grade was created'),
                 'timemodified' => new external_value(PARAM_INT, 'The time that the grade was last updated'),
             ]),
index 8a3f5ed..41d2b52 100644 (file)
@@ -165,7 +165,7 @@ class store extends external_api {
             $gradeitem->send_student_notification($gradeduser, $USER);
         }
 
-        return fetch::get_fetch_data($gradeitem, $gradeduser);
+        return fetch::get_fetch_data($gradeitem, $gradeduser, 0);
     }
 
     /**
index 6225ce3..6fe6008 100644 (file)
@@ -156,6 +156,7 @@ class fetch extends external_api {
         $fillings = $instance->get_guide_filling();
         $context = $controller->get_context();
         $definitionid = (int) $definition->id;
+        $maxgrade = max(array_keys($controller->get_grade_range()));
 
         $criterion = [];
         if ($definition->guide_criteria) {
@@ -224,6 +225,8 @@ class fetch extends external_api {
                 'criterion' => $criterion,
                 'hascomments' => !empty($comments),
                 'comments' => $comments,
+                'usergrade' => $grade->grade,
+                'maxgrade' => $maxgrade,
                 'timecreated' => $grade->timecreated,
                 'timemodified' => $grade->timemodified,
             ],
@@ -264,6 +267,8 @@ class fetch extends external_api {
                     ]),
                     'Frequently used comments'
                 ),
+                'usergrade' => new external_value(PARAM_RAW, 'Current user grade'),
+                'maxgrade' => new external_value(PARAM_RAW, 'Max possible grade'),
                 'timecreated' => new external_value(PARAM_INT, 'The time that the grade was created'),
                 'timemodified' => new external_value(PARAM_INT, 'The time that the grade was last updated'),
             ]),
index 18d01de..2684662 100644 (file)
@@ -148,7 +148,7 @@ class fetch extends external_api {
         $fillings = $instance->get_rubric_filling();
         $context = $controller->get_context();
         $definitionid = (int) $definition->id;
-
+        $maxgrade = max(array_keys($controller->get_grade_range()));
         $teacherdescription = self::get_formatted_text(
             $context,
             $definitionid,
@@ -237,6 +237,8 @@ class fetch extends external_api {
                 'rubricmode' => 'evaluate editable',
                 'teacherdescription' => $teacherdescription,
                 'canedit' => false,
+                'usergrade' => $grade->grade,
+                'maxgrade' => $maxgrade,
                 'timecreated' => $grade->timecreated,
                 'timemodified' => $grade->timemodified,
             ],
@@ -272,7 +274,8 @@ class fetch extends external_api {
                         ])),
                     ])
                 ),
-                'timecreated' => new external_value(PARAM_INT, 'The time that the grade was created'),
+                'usergrade' => new external_value(PARAM_RAW, 'Current user grade'),
+                'maxgrade' => new external_value(PARAM_RAW, 'Max possible grade'),
                 'timemodified' => new external_value(PARAM_INT, 'The time that the grade was last updated'),
             ]),
             'warnings' => new external_warnings(),
index 5dc6ae0..474f58f 100644 (file)
Binary files a/mod/forum/amd/build/grades/grader.min.js and b/mod/forum/amd/build/grades/grader.min.js differ
index 672eada..ea33ac3 100644 (file)
Binary files a/mod/forum/amd/build/grades/grader.min.js.map and b/mod/forum/amd/build/grades/grader.min.js.map differ
index 791d1c9..7a73e1b 100644 (file)
Binary files a/mod/forum/amd/build/grades/grader/selectors.min.js and b/mod/forum/amd/build/grades/grader/selectors.min.js differ
index ec64fb3..d2cdccf 100644 (file)
Binary files a/mod/forum/amd/build/grades/grader/selectors.min.js.map and b/mod/forum/amd/build/grades/grader/selectors.min.js.map differ
index 7c5b5c5..16a94e6 100644 (file)
Binary files a/mod/forum/amd/build/local/grades/grader.min.js and b/mod/forum/amd/build/local/grades/grader.min.js differ
index 0d57193..997f2ec 100644 (file)
Binary files a/mod/forum/amd/build/local/grades/grader.min.js.map and b/mod/forum/amd/build/local/grades/grader.min.js.map differ
index eade666..7811f4a 100644 (file)
@@ -142,6 +142,28 @@ const launchWholeForumGrading = async(rootNode) => {
     );
 };
 
+/**
+ * Launch the Grader.
+ *
+ * @param {HTMLElement} rootNode the root HTML element describing what is to be graded
+ */
+const launchViewGrading = async rootNode => {
+    const data = rootNode.dataset;
+    const gradingPanelFunctions = await Grader.getGradingPanelFunctions(
+        'mod_forum',
+        data.contextid,
+        data.gradingComponent,
+        data.gradingComponentSubtype,
+        data.gradableItemtype
+    );
+
+    await Grader.view(
+        gradingPanelFunctions.getter,
+        data.userid,
+        data.name
+    );
+};
+
 /**
  * Register listeners to launch the grading panel.
  */
@@ -167,5 +189,26 @@ export const registerLaunchListeners = () => {
                 throw Error('Unable to find a valid gradable item');
             }
         }
+        if (e.target.matches(Selectors.viewGrade)) {
+            e.preventDefault();
+            const rootNode = findGradableNode(e.target);
+
+            if (!rootNode) {
+                throw Error('Unable to find a gradable item');
+            }
+
+            if (rootNode.matches(Selectors.gradableItems.wholeForum)) {
+                // Note: The preventDefault must be before any async function calls because the function becomes async
+                // at that point and the default action is implemented.
+                e.preventDefault();
+                try {
+                    await launchViewGrading(rootNode);
+                } catch (error) {
+                    Notification.exception(error);
+                }
+            } else {
+                throw Error('Unable to find a valid gradable item');
+            }
+        }
     });
 };
index 65e87d2..ef9602a 100644 (file)
@@ -29,4 +29,5 @@ export default {
     },
     expandConversation: '[data-action="view-context"]',
     posts: '[data-region="posts"]',
+    viewGrade: '[data-grade-action="view"]',
 };
index 65eb6a5..2b30018 100644 (file)
@@ -32,6 +32,8 @@ import {failedUpdate} from 'core_grades/grades/grader/gradingpanel/normalise';
 import {addIconToContainerWithPromise} from 'core/loadingicon';
 import {debounce} from 'core/utils';
 import {fillInitialValues} from 'core_grades/grades/grader/gradingpanel/comparison';
+import * as Modal from 'core/modal_factory';
+import * as ModalEvents from 'core/modal_events';
 
 const templateNames = {
     grader: {
@@ -388,4 +390,49 @@ export const launch = async(getListOfUsers, getContentForUser, getGradeForUser,
     displayUserPicker(graderContainer, userPicker.rootNode);
 };
 
+/**
+ * Show the grade for a specific user.
+ *
+ * @param {Function} getGradeForUser A function get the grade details for a specific user
+ * @param {Number} userid The ID of a specific user
+ */
+export const view = async(getGradeForUser, userid, moduleName) => {
+
+    const [
+        userGrade,
+        modal,
+    ] = await Promise.all([
+        getGradeForUser(userid),
+        Modal.create({
+            title: moduleName,
+            large: true,
+            type: Modal.types.CANCEL
+        }),
+    ]);
+
+    const spinner = addIconToContainerWithPromise(modal.getRoot());
+
+    // Handle hidden event.
+    modal.getRoot().on(ModalEvents.hidden, function() {
+        // Destroy when hidden.
+        modal.destroy();
+    });
+
+    modal.show();
+    const output = document.createElement('div');
+    const {html, js} = await Templates.renderForPromise('mod_forum/local/grades/view_grade', userGrade);
+    Templates.replaceNodeContents(output, html, js);
+
+    // Note: We do not use await here because it messes with the Modal transitions.
+    const [gradeHTML, gradeJS] = await renderGradeTemplate(userGrade);
+    const gradeReplace = output.querySelector('[data-region="grade-template"]');
+    Templates.replaceNodeContents(gradeReplace, gradeHTML, gradeJS);
+    modal.setBody(output.outerHTML);
+    spinner.resolve();
+};
+
+const renderGradeTemplate = async(userGrade) => {
+    const {html, js} = await Templates.renderForPromise(userGrade.templatename, userGrade.grade);
+    return [html, js];
+};
 export {getGradingPanelFunctions};
index 0918615..42b1421 100644 (file)
@@ -29,8 +29,7 @@ namespace mod_forum\grades;
 use coding_exception;
 use context;
 use core_grades\component_gradeitem;
-use core_grades\component_gradeitems;
-use gradingform_instance;
+use core_grades\local\gradeitem as gradeitem;
 use mod_forum\local\container as forum_container;
 use mod_forum\local\entities\forum as forum_entity;
 use required_capability_exception;
@@ -225,6 +224,18 @@ class forum_gradeitem extends component_gradeitem {
         ]);
     }
 
+    /**
+     * Get the grade item instance id.
+     *
+     * This is typically the cmid in the case of an activity, and relates to the iteminstance field in the grade_items
+     * table.
+     *
+     * @return int
+     */
+    public function get_grade_instance_id(): int {
+        return (int) $this->forum->get_id();
+    }
+
     /**
      * Create or update the grade.
      *
index 5937443..96a0725 100644 (file)
@@ -207,6 +207,7 @@ class discussion_list {
                 'excludesubscription' => true
             ],
             'totaldiscussioncount' => $alldiscussionscount,
+            'userid' => $user->id,
             'visiblediscussioncount' => count($discussions)
         ];
 
index c853a2a..39951e3 100644 (file)
@@ -745,6 +745,9 @@ $string['viewconversation'] = 'View discussion';
 
 $string['grade_forum_header'] = 'Whole forum grading';
 $string['grade_forum_title'] = 'Grade';
+$string['gradingstatus'] = 'Grade status:';
+$string['graded'] = 'Graded';
+$string['notgraded'] = 'Not graded';
 $string['gradeforrating'] = 'Grade for rating: {$a->str_long_grade}';
 $string['gradeforratinghidden'] = 'Grade for rating hidden';
 $string['gradeforwholeforum'] = 'Grade for forum: {$a->str_long_grade}';
@@ -755,6 +758,7 @@ $string['grades:gradesavedfor'] = 'Grade saved for {$a->fullname}';
 $string['grades:gradesavefailed'] = 'Unable to save grade for {$a->fullname}: {$a->error}';
 $string['showmoreusers'] = 'Show more users';
 $string['nousersmatch'] = 'No user(s) found for given criteria';
+$string['viewgrades'] = 'View grades';
 
 // Deprecated since Moodle 3.8.
 $string['cannotdeletediscussioninsinglediscussion'] = 'You cannot delete the first post in a single discussion';
index 633cd71..4e6c5ff 100644 (file)
                 {{> mod_forum/grades/grade_button }}
             {{/forum.state.gradingenabled}}
         {{/forum.capabilities.grade}}
+        {{^forum.capabilities.grade}}
+            {{#forum.state.gradingenabled}}
+                {{> mod_forum/grades/view_grade_button }}
+            {{/forum.state.gradingenabled}}
+        {{/forum.capabilities.grade}}
     </div>
     {{#forum.capabilities.create}}
         <div class="collapse m-t-1 p-b-1" id="collapseAddForm">
diff --git a/mod/forum/templates/grades/view_grade_button.mustache b/mod/forum/templates/grades/view_grade_button.mustache
new file mode 100644 (file)
index 0000000..5a65a34
--- /dev/null
@@ -0,0 +1,50 @@
+{{!
+    This file is part of Moodle - http://moodle.org/
+
+    Moodle is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Moodle 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 General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+}}
+{{!
+    @template mod_forum/grades/grade_button
+
+    Template which defines a forum post for sending in a single-post HTML email.
+
+    Classes required for JS:
+    * none
+
+    Data attributes required for JS:
+    * none
+
+    Example context (json):
+    {
+    }
+}}
+<button
+    class="btn btn-secondary"
+    data-grade-action="view"
+    data-contextid="{{contextid}}"
+    data-cmid="{{cmid}}"
+    data-name="{{name}}"
+    data-group="{{groupid}}"
+    data-userid="{{userid}}"
+    data-grading-component="{{gradingcomponent}}"
+    data-grading-component-subtype="{{gradingcomponentsubtype}}"
+    data-gradable-itemtype="forum"
+    >
+        {{#str}}viewgrades, forum{{/str}}
+</button>
+{{#js}}
+    require(['mod_forum/grades/grader'], function(Grader) {
+    Grader.registerLaunchListeners();
+    });
+{{/js}}
diff --git a/mod/forum/templates/local/grades/view_grade.mustache b/mod/forum/templates/local/grades/view_grade.mustache
new file mode 100644 (file)
index 0000000..9b4e953
--- /dev/null
@@ -0,0 +1,69 @@
+{{!
+    This file is part of Moodle - http://moodle.org/
+
+    Moodle is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Moodle 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 General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+}}
+{{!
+    @template mod_forum/local/grades/local/view_grade
+
+    Classes required for JS:
+    * none
+
+    Data attributes required for JS:
+    * data-region="grade-template"
+
+    Context variables required for this template:
+    * none
+
+    Example context (json):
+    {
+        "templatename": "core_grades/grades/grader/gradingpanel/point",
+        "grade": {
+            "usergrade": 55,
+            "maxgrade": 100,
+            "timemodified": 1573543598
+        },
+        "hasgrade": true
+    }
+}}
+<div class="container-fluid grade-display" data-region="view-grade">
+    {{#grade}}
+        <div class="row-fluid px-3">
+            <h5 class="font-weight-bold description">{{#str}}grade{{/str}}:</h5>
+            <p class="ml-auto">{{usergrade}} / {{maxgrade}}</p>
+        </div>
+        <div class="row-fluid px-3">
+            <h5 class="font-weight-bold description">{{#str}}date{{/str}}:</h5>
+            <p class="ml-auto">{{#userdate}}{{timemodified}}, {{#str}} strftimedate, langconfig {{/str}}{{/userdate}}</p>
+        </div>
+    {{/grade}}
+    <div class="row-fluid px-3">
+        <h5 class="font-weight-bold description">
+            {{#str}}gradingstatus, forum{{/str}}
+        </h5>
+        <p class="ml-auto">
+            {{#hasgrade}}
+                {{#str}}graded, forum{{/str}}
+            {{/hasgrade}}
+            {{^hasgrade}}
+                {{#str}}notgraded, forum{{/str}}
+            {{/hasgrade}}
+        </p>
+    </div>
+    <div class="row-fluid p-3">
+        <fieldset class="w-100" disabled="disabled">
+            <div class="w-100" data-region="grade-template"></div>
+        </fieldset>
+    </div>
+</div>
index 5f0a4bf..7b96475 100644 (file)
@@ -171,8 +171,9 @@ $groupid = groups_get_activity_group($cm, true) ?: null;
 $rendererfactory = mod_forum\local\container::get_renderer_factory();
 switch ($forum->get_type()) {
     case 'single':
+        $forumgradeitem = forum_gradeitem::load_from_forum_entity($forum);
         if ($capabilitymanager->can_grade($USER)) {
-            $forumgradeitem = forum_gradeitem::load_from_forum_entity($forum);
+
             if ($forumgradeitem->is_grading_enabled()) {
                 $groupid = groups_get_activity_group($cm, true) ?: null;
                 $gradeobj = (object) [
@@ -189,6 +190,22 @@ switch ($forum->get_type()) {
                 ];
                 echo $OUTPUT->render_from_template('mod_forum/grades/grade_button', $gradeobj);
             }
+        } else {
+            if ($forumgradeitem->is_grading_enabled()) {
+                $groupid = groups_get_activity_group($cm, true) ?: null;
+                $gradeobj = (object) [
+                    'contextid' => $forum->get_context()->id,
+                    'cmid' => $cmid,
+                    'name' => $forum->get_name(),
+                    'courseid' => $course->id,
+                    'coursename' => $course->shortname,
+                    'groupid' => $groupid,
+                    'userid' => $USER->id,
+                    'gradingcomponent' => $forumgradeitem->get_grading_component_name(),
+                    'gradingcomponentsubtype' => $forumgradeitem->get_grading_component_subtype(),
+                ];
+                $OUTPUT->render_from_template('mod_forum/grades/view_grade_button', $gradeobj);
+            }
         }
         $discussion = $discussionvault->get_last_discussion_in_forum($forum);
         $discussioncount = $discussionvault->get_count_discussions_in_forum($forum);
index a29c0d8..e20b86b 100644 (file)
         }
     }
 }
-
+.grade-display {
+    .description {
+        font-size: 1rem;
+    }
+}
 .criterion {
     .description {
         font-size: 1rem;
index 6c4ea40..e9128b9 100644 (file)
@@ -17708,6 +17708,9 @@ p.arrow_button {
     margin-left: 5px;
     margin-right: 12px; }
 
+.grade-display .description {
+  font-size: 1rem; }
+
 .criterion .description {
   font-size: 1rem; }
 
index a39cc29..2775731 100644 (file)
@@ -17981,6 +17981,9 @@ p.arrow_button {
     margin-left: 5px;
     margin-right: 12px; }
 
+.grade-display .description {
+  font-size: 1rem; }
+
 .criterion .description {
   font-size: 1rem; }