MDL-74610 quiz: multiple grades - UI improvements

This commit is contained in:
Tim Hunt
2024-04-09 15:11:45 +01:00
parent 2ad60df93d
commit d55e486a7e
13 changed files with 71 additions and 50 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2 -5
View File
@@ -52,17 +52,15 @@ const SELECTORS = {
* Call the Ajax service to create a quiz grade item.
*
* @param {Number} quizId id of the quiz to update.
* @param {String} name name of the grade item to create.
* @returns {Promise<Object>} a promise that resolves to the template context required to re-render the page.
*/
const createGradeItem = (
quizId,
name
) => callServiceAndReturnRenderingData({
methodname: 'mod_quiz_create_grade_items',
args: {
quizid: quizId,
quizgradeitems: [{name: name}],
quizgradeitems: [{name: ''}],
}
});
@@ -413,8 +411,7 @@ const handleAddGradeItemClick = (e) => {
const quizId = e.target.dataset.quizId;
getString('gradeitemdefaultname', 'quiz')
.then((name) => createGradeItem(quizId, name))
createGradeItem(quizId)
.then(reRenderPage)
.then(() => {
pending.resolve();
+2 -1
View File
@@ -49,7 +49,8 @@ class create_grade_items extends external_api {
'quizid' => new external_value(PARAM_INT, 'The quiz to update slots for.'),
'quizgradeitems' => new external_multiple_structure(
new external_single_structure([
'name' => new external_value(PARAM_TEXT, 'The name for the grade item to create.'),
'name' => new external_value(PARAM_TEXT,
'The name for the grade item to create. If empty string, a sensible default is used.'),
])
),
]);
@@ -90,6 +90,9 @@ class edit_grading_page implements renderable, templatable {
// Add the relevant slots ot each section.
foreach ($this->structure->get_slots() as $slot) {
if (!$this->structure->is_real_question($slot->slot)) {
continue;
}
// Mark the right choice as selected.
$choices = $gradeitemchoices;
if ($slot->quizgradeitemid) {
+3 -3
View File
@@ -57,16 +57,16 @@ class edit_nav_actions implements renderable, templatable {
// Build the navigation drop-down.
$questionsurl = new moodle_url('/mod/quiz/edit.php', ['cmid' => $this->cmid]);
$complexgradingurl = new moodle_url('/mod/quiz/editgrading.php', ['cmid' => $this->cmid]);
$gradeitemsetupurl = new moodle_url('/mod/quiz/editgrading.php', ['cmid' => $this->cmid]);
$menu = [
$questionsurl->out(false) => get_string('questions', 'quiz'),
$complexgradingurl->out(false) => get_string('complexgrading', 'quiz'),
$gradeitemsetupurl->out(false) => get_string('gradeitemsetup', 'quiz'),
];
$overridesnav = new url_select(
$menu,
$this->whichpage === self::SUMMARY ? $questionsurl->out(false) : $complexgradingurl->out(false),
$this->whichpage === self::SUMMARY ? $questionsurl->out(false) : $gradeitemsetupurl->out(false),
null
);
$overridesnav->set_label(get_string('quizsetupnavigation', 'quiz'), ['class' => 'sr-only']);
+10
View File
@@ -1514,6 +1514,16 @@ class structure {
'COALESCE(MAX(sortorder) + 1, 1)',
['quizid' => $this->get_quizid()]);
// If name is blank, supply a default.
if ((string) $gradeitemdata->name === '') {
$count = 0;
do {
$count += 1;
$gradeitemdata->name = get_string('gradeitemdefaultname', 'quiz', $count);
} while ($DB->record_exists('quiz_grade_items',
['quizid' => $this->get_quizid(), 'name' => $gradeitemdata->name]));
}
$transaction = $DB->start_delegated_transaction();
// Create the grade item.
-1
View File
@@ -55,7 +55,6 @@ $quizhasattempts = quiz_has_attempts($quiz->id);
// Initialise output.
$PAGE->set_pagelayout('incourse');
$PAGE->set_pagetype('mod-quiz-edit');
$output = $PAGE->get_renderer('mod_quiz', 'edit');
+9 -10
View File
@@ -191,7 +191,6 @@ $string['completionminattemptserror'] = 'Minimum number of attempts must be lowe
$string['completionpassorattemptsexhausteddesc'] = 'Student must achieve a passing grade, or exhaust all available attempts to complete this activity';
$string['completionattemptsexhausted'] = 'Passing grade or all available attempts completed';
$string['completionattemptsexhausted_help'] = 'Mark quiz complete when the student has exhausted the maximum number of attempts.';
$string['complexgrading'] = 'Multiple grade setup';
$string['configadaptive'] = 'If you choose Yes for this option then the student will be allowed multiple responses to a question even within the same attempt at the quiz.';
$string['configattemptsallowed'] = 'Restriction on the number of attempts students are allowed at the quiz.';
$string['configdecimaldigits'] = 'Number of digits that should be shown after the decimal point when displaying grades.';
@@ -440,20 +439,21 @@ $string['gradeaverage'] = 'Average grade';
$string['gradeboundary'] = 'Grade boundary';
$string['gradeessays'] = 'Grade essays';
$string['gradehighest'] = 'Highest grade';
$string['gradeitemdefaultname'] = 'New grade item';
$string['gradeitemdefaultname'] = 'New grade item {$a}';
$string['gradeitemdelete'] = 'Delete grade item {$a}';
$string['gradeitemedit'] = 'Edit name of grade item {$a}';
$string['gradeitemmarkscheme'] = 'Mark scheme';
$string['gradeitemmarkscheme'] = 'Assign grade items';
$string['gradeitemnewname'] = 'New name for grade item {$a}';
$string['gradeitemnoneselected'] = '[none]';
$string['gradeitemnoslots'] = 'No questions have been added to the quiz yet. Please add the questions to the quiz before setting up grading.';
$string['gradeitemnoslots'] = 'This quiz has no questions yet. Please add questions first, then return here to set up grade items.';
$string['gradeitems'] = 'Grade items';
$string['gradeitemsautosetup'] = 'Setup a grade for each section';
$string['gradeitemsetup'] = 'Quiz grading setup (advanced view)';
$string['gradeitemsnoneyet'] = 'This quiz does not yet have any grade items defined, just a simple overall score will be used.';
$string['gradeitemsremoveall'] = 'Reset advanced grading setup';
$string['gradeitemsremoveallconfirm'] = 'Reset grading setup?';
$string['gradeitemsremoveallmessage'] = 'This will only clear the advanced grading setup. It will not change which questions are in the quiz.';
$string['gradeitemsetup'] = 'Grade items setup';
$string['gradeitemsnoneyet'] = 'Create grade items within your quiz. Allocate questions or quiz sections to these grade items to break down grade results into different areas.';
$string['gradeitemsremoveall'] = 'Reset setup';
$string['gradeitemsremoveallconfirm'] = 'Reset grade items setup?';
$string['gradeitemsremoveallmessage'] = 'This will delete all grade items and unassign questions and sections from them.<br><br>This action will not affect the questions and sections themselves, nor existing attempts within the quiz.';
$string['gradeitemsremovealltitle'] = 'Reset grade items setup';
$string['grademethod'] = 'Grading method';
$string['grademethod_help'] = 'When multiple attempts are allowed, the following methods are available for calculating the final quiz grade:
@@ -756,7 +756,6 @@ $string['publish'] = 'Publish';
$string['publishedit'] = 'You must have permission in the publishing course to add or edit questions in this category';
$string['qbrief'] = 'Q. {$a}';
$string['qname'] = 'name';
$string['qnumberbrief'] = 'No.';
$string['qti'] = 'IMS QTI format';
$string['qtypename'] = 'type, name';
$string['question'] = 'Question';
+3
View File
@@ -1090,6 +1090,9 @@ table.quizreviewsummary td.cell {
color: #000;
text-align: right;
}
#page-mod-quiz-editgrading .inplaceeditable .quickeditlink {
color: var(--primary);
}
#page-mod-quiz-edit .inplaceeditable .quickeditlink {
color: var(--primary);
text-decoration: none;
+15 -12
View File
@@ -81,8 +81,6 @@
<h2>{{#str}} gradeitemsetup, quiz {{/str}}</h2>
<h3>{{#str}} gradeitems, grades {{/str}}</h3>
{{^hasgradeitems}}
{{#nogradeitems}}
{{> core/notification_info}}
@@ -91,17 +89,18 @@
{{#hasgradeitems}}
<table class="generaltable table-responsive" id="mod_quiz-grade-item-list" data-quiz-id="{{quizid}}">
<caption class="sr-only"> {{#str}} gradeitems, grades {{/str}} </caption>
<thead>
<tr>
<th scope="col">{{#str}} gradeitem, grades {{/str}}</th>
<th scope="col">{{#str}} actions {{/str}}</th>
<th scope="col">{{#str}} totalmarks, quiz {{/str}}</th>
<th scope="col">{{#str}} actions {{/str}}</th>
</tr>
</thead>
<tbody>
{{#gradeitems}}
<tr data-quiz-grade-item-id="{{id}}">
<th scope="row" class="align-middle py-1">
<th scope="row" class="align-middle font-weight-normal py-1">
<span class="inplaceeditable inplaceeditable-text w-100"
data-raw-name="{{name}}" data-edit-label="{{#str}} gradeitemnewname, quiz, {{{displayname}}} {{/str}}">
<a href="#" class="quickeditlink w-100" data-action-edit="1" title="{{#str}} gradeitemedit, quiz, {{{displayname}}} {{/str}}">
@@ -112,6 +111,9 @@
</a>
</span>
</th>
<td class="align-middle text-right py-1">
{{summarks}}
</td>
<td class="align-middle text-center py-1">
{{^isused}}
<a href="#" data-action-delete="1">
@@ -119,9 +121,6 @@
</a>
{{/isused}}
</td>
<td class="align-middle text-right py-1">
{{summarks}}
</td>
</tr>
{{/gradeitems}}
</tbody>
@@ -131,10 +130,6 @@
<div class="mb-5">
<button type="button" class="btn btn-secondary" id="mod_quiz-add_grade_item"
data-quiz-id="{{quizid}}">{{#str}} additem, grades{{/str}}</button>
{{#hasgradeitems}}
<button type="button" class="btn btn-danger" id="mod_quiz-grades_reset_all"
data-quiz-id="{{quizid}}">{{#str}} gradeitemsremoveall, quiz{{/str}}</button>
{{/hasgradeitems}}
{{^hasgradeitems}}
{{#hasmultiplesections}}
<button type="button" class="btn btn-secondary" id="mod_quiz-grades_auto_setup"
@@ -153,9 +148,10 @@
{{#hasslots}}
<table class="generaltable table-responsive" id="mod_quiz-slot-list" data-quiz-id="{{quizid}}">
<caption class="sr-only"> {{#str}} gradeitemmarkscheme, quiz {{/str}} </caption>
<thead>
<tr>
<th scope="col">{{#str}} qnumberbrief, quiz {{/str}}</th>
<th scope="col">{{#str}} numberabbr, quiz {{/str}}</th>
<th scope="col">{{#str}} question, quiz {{/str}}</th>
<th scope="col">{{#str}} marks, quiz {{/str}}</th>
<th scope="col">{{#str}} gradeitem, grades {{/str}}</th>
@@ -188,4 +184,11 @@
</table>
{{/hasslots}}
<div>
{{#hasgradeitems}}
<h3>{{#str}} gradeitemsremovealltitle, quiz {{/str}}</h3>
<button type="button" class="btn btn-danger" id="mod_quiz-grades_reset_all"
data-quiz-id="{{quizid}}">{{#str}} gradeitemsremoveall, quiz {{/str}}</button>
{{/hasgradeitems}}
</div>
</div>
+1 -1
View File
@@ -322,7 +322,7 @@ class behat_mod_quiz extends behat_question_base {
}
// Grade item.
if (array_key_exists('grade item', $questiondata)) {
if (array_key_exists('grade item', $questiondata) && trim($questiondata['grade item']) !== '') {
$extraslotproperties['quizgradeitemid'] =
$DB->get_field('quiz_grade_items', 'id',
['quizid' => $quiz->id, 'name' => $questiondata['grade item']], MUST_EXIST);
@@ -18,10 +18,11 @@ Feature: Setup multiple grades for a quiz
| contextlevel | reference | name |
| Course | C1 | Test questions |
And the following "questions" exist:
| questioncategory | qtype | name | questiontext |
| Test questions | truefalse | Question A | This is question 01 |
| Test questions | truefalse | Question B | This is question 02 |
| Test questions | truefalse | Question C | This is question 03 |
| questioncategory | qtype | name | questiontext |
| Test questions | description | Info | Some information |
| Test questions | truefalse | Question A | This is question 01 |
| Test questions | truefalse | Question B | This is question 02 |
| Test questions | truefalse | Question C | This is question 03 |
And the following "activities" exist:
| activity | name | course |
| quiz | Quiz 1 | C1 |
@@ -35,6 +36,7 @@ Feature: Setup multiple grades for a quiz
| Quiz 1 | Unused grade item |
And quiz "Quiz 1" contains the following questions:
| question | page | grade item |
| Info | 1 | |
| Question A | 1 | Intuition |
| Question B | 1 | Intelligence |
| Question C | 2 | Intuition |
@@ -56,19 +58,23 @@ Feature: Setup multiple grades for a quiz
And the field "Question C" matches value "Intuition"
And "3" row "Marks" column of "mod_quiz-slot-list" table should contain "1.00"
And I should not see "Info"
@javascript
Scenario: A grade item can be created and renamed
Given quiz "Quiz 1" contains the following questions:
| question | page |
| Question A | 1 |
When I am on the "Quiz 1" "mod_quiz > multiple grades setup" page logged in as teacher
And I should see "This quiz does not yet have any grade items defined"
And I should see "Create grade items within your quiz. Allocate questions or quiz sections to these grade items to break down grade results into different areas."
And I press "Add grade item"
Then "New grade item" "table_row" should exist
And I click on "Edit" "link" in the "New grade item" "table_row"
Then "New grade item 1" "table_row" should exist
And I press "Add grade item"
Then "New grade item 2" "table_row" should exist
And I click on "Edit" "link" in the "New grade item 1" "table_row"
And I set the field "New name for grade item" to "Intelligence"
And I press enter
And I should not see "New grade item"
And I should not see "New grade item 1"
And "Intelligence" "table_row" should exist
@javascript
@@ -97,7 +103,7 @@ Feature: Setup multiple grades for a quiz
When I am on the "Quiz 1" "mod_quiz > multiple grades setup" page logged in as teacher
And I follow "Delete grade item Unused grade item"
Then I should not see "Unused grade item"
And I should see "This quiz does not yet have any grade items defined"
And I should see "Create grade items within your quiz. Allocate questions or quiz sections to these grade items to break down grade results into different areas."
@javascript
Scenario: Grade item for a slot can be changed
@@ -130,14 +136,14 @@ Feature: Setup multiple grades for a quiz
| Question C | 2 | Intuition |
When I am on the "Quiz 1" "mod_quiz > multiple grades setup" page logged in as teacher
And I press "Reset advanced grading setup"
And I click on "Reset" "button" in the "Reset grading setup?" "dialogue"
And I press "Reset setup"
And I click on "Reset" "button" in the "Reset grade items setup?" "dialogue"
Then I should see "This quiz does not yet have any grade items defined, just a simple overall score will be used."
Then I should see "Create grade items within your quiz. Allocate questions or quiz sections to these grade items to break down grade results into different areas."
And the field "Question A" matches value "[none]"
And the field "Question B" matches value "[none]"
And the field "Question C" matches value "[none]"
And I should not see "Reset advanced grading setup"
And I should not see "Reset grade items setup"
@javascript
Scenario: Reset all can be cancelled
@@ -145,8 +151,8 @@ Feature: Setup multiple grades for a quiz
| quiz | name |
| Quiz 1 | Intuition |
When I am on the "Quiz 1" "mod_quiz > multiple grades setup" page logged in as teacher
And I press "Reset advanced grading setup"
And I click on "Cancel" "button" in the "Reset grading setup?" "dialogue"
And I press "Reset setup"
And I click on "Cancel" "button" in the "Reset grade items setup?" "dialogue"
Then I should see "Intuition"
@javascript