From ac1d386443ea0532ea2fdc04265c05a6205fd7b1 Mon Sep 17 00:00:00 2001 From: Mihail Geshoski Date: Tue, 13 Aug 2024 11:24:15 +0800 Subject: [PATCH 1/8] MDL-82681 mod_assign: Add Marker to Advanced submission filters Adds 'Marker' filter to the 'Advanced' filters component on the assignment submissions page. --- .../grading/extra_filters_dropdown.min.js | 2 +- .../grading/extra_filters_dropdown.min.js.map | 2 +- .../grading/extra_filters_dropdown.js | 17 +- .../classes/output/grading_actionmenu.php | 16 ++ mod/assign/locallib.php | 11 +- .../extra_filters_dropdown_body.mustache | 26 ++++ .../tests/behat/filter_by_marker.feature | 145 +++++++++++++----- .../tests/behat/grading_app_filters.feature | 4 +- 8 files changed, 179 insertions(+), 44 deletions(-) diff --git a/mod/assign/amd/build/actionbar/grading/extra_filters_dropdown.min.js b/mod/assign/amd/build/actionbar/grading/extra_filters_dropdown.min.js index 9b74c2a4f65..75e9e43117f 100644 --- a/mod/assign/amd/build/actionbar/grading/extra_filters_dropdown.min.js +++ b/mod/assign/amd/build/actionbar/grading/extra_filters_dropdown.min.js @@ -5,6 +5,6 @@ define("mod_assign/actionbar/grading/extra_filters_dropdown",["exports","core/lo * @module mod_assign/actionbar/grading/extra_filters_dropdown * @copyright 2024 Mihail Geshoski * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_jquery=(obj=_jquery)&&obj.__esModule?obj:{default:obj};const Selectors_extraFiltersDropdown=".dropdown.extrafilters",Selectors_extraFiltersClose='a[data-action="close"]',Selectors_workflowFilterElement='select[name="workflowfilter"]',restoreAppliedWorkflowFilter=async extraFiltersDropdown=>{const appliedWorkflowFilter=await(0,_repository.getUserPreference)("assign_workflowfilter");extraFiltersDropdown.getElement().querySelector(Selectors_workflowFilterElement).value=appliedWorkflowFilter};_exports.init=()=>{const extraFiltersDropdown=(0,_dialog.getDropdownDialog)(Selectors_extraFiltersDropdown);extraFiltersDropdown&&(extraFiltersDropdown=>{extraFiltersDropdown.getElement().addEventListener("click",(e=>{e.target.closest(Selectors_extraFiltersClose)&&(e.preventDefault(),extraFiltersDropdown.setVisible(!1))})),(0,_jquery.default)(extraFiltersDropdown.getElement()).on("hide.bs.dropdown",(()=>{restoreAppliedWorkflowFilter(extraFiltersDropdown)}))})(extraFiltersDropdown)}})); + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_jquery=(obj=_jquery)&&obj.__esModule?obj:{default:obj};const Selectors_extraFiltersDropdown=".dropdown.extrafilters",Selectors_extraFiltersClose='a[data-action="close"]',Selectors_workflowFilterElement='select[name="workflowfilter"]',Selectors_markerFilterElement='select[name="markingallocationfilter"]',restoreAppliedWorkflowFilter=async extraFiltersDropdown=>{const appliedWorkflowFilter=await(0,_repository.getUserPreference)("assign_workflowfilter");extraFiltersDropdown.getElement().querySelector(Selectors_workflowFilterElement).value=appliedWorkflowFilter},restoreAppliedMarkerFilter=async extraFiltersDropdown=>{const markerFilterSelect=extraFiltersDropdown.getElement().querySelector(Selectors_markerFilterElement);if(markerFilterSelect){const appliedMarkerFilter=await(0,_repository.getUserPreference)("assign_markerfilter");markerFilterSelect.value=appliedMarkerFilter}};_exports.init=()=>{const extraFiltersDropdown=(0,_dialog.getDropdownDialog)(Selectors_extraFiltersDropdown);extraFiltersDropdown&&(extraFiltersDropdown=>{extraFiltersDropdown.getElement().addEventListener("click",(e=>{e.target.closest(Selectors_extraFiltersClose)&&(e.preventDefault(),extraFiltersDropdown.setVisible(!1))})),(0,_jquery.default)(extraFiltersDropdown.getElement()).on("hide.bs.dropdown",(()=>{restoreAppliedWorkflowFilter(extraFiltersDropdown),restoreAppliedMarkerFilter(extraFiltersDropdown)}))})(extraFiltersDropdown)}})); //# sourceMappingURL=extra_filters_dropdown.min.js.map \ No newline at end of file diff --git a/mod/assign/amd/build/actionbar/grading/extra_filters_dropdown.min.js.map b/mod/assign/amd/build/actionbar/grading/extra_filters_dropdown.min.js.map index 89a6b2cef65..70b5ffa61ba 100644 --- a/mod/assign/amd/build/actionbar/grading/extra_filters_dropdown.min.js.map +++ b/mod/assign/amd/build/actionbar/grading/extra_filters_dropdown.min.js.map @@ -1 +1 @@ -{"version":3,"file":"extra_filters_dropdown.min.js","sources":["../../../src/actionbar/grading/extra_filters_dropdown.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\nimport {getDropdownDialog} from 'core/local/dropdown/dialog';\nimport {getUserPreference} from 'core_user/repository';\nimport $ from 'jquery';\n\n/**\n * Module for the extra filters dropdown on the submissions page.\n *\n * @module mod_assign/actionbar/grading/extra_filters_dropdown\n * @copyright 2024 Mihail Geshoski \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n/** @constant {Object} The object containing the relevant selectors. */\nconst Selectors = {\n extraFiltersDropdown: '.dropdown.extrafilters',\n extraFiltersClose: 'a[data-action=\"close\"]',\n workflowFilterElement: 'select[name=\"workflowfilter\"]'\n};\n\n/**\n * Register event listeners for the extra filters dropdown.\n *\n * @param {DropdownDialog} extraFiltersDropdown The dropdown dialog instance.\n */\nconst registerEventListeners = (extraFiltersDropdown) => {\n // Click event listener to the extra filters dropdown element.\n extraFiltersDropdown.getElement().addEventListener('click', e => {\n // The target is the 'Close' button.\n if (e.target.closest(Selectors.extraFiltersClose)) {\n e.preventDefault();\n extraFiltersDropdown.setVisible(false);\n }\n });\n // Event listener triggered upon hiding of the dropdown.\n $(extraFiltersDropdown.getElement()).on('hide.bs.dropdown', () => {\n // Restore the filters to their stored preference values once the dropdown is closed.\n restoreAppliedWorkflowFilter(extraFiltersDropdown);\n });\n};\n\n/**\n * Restores the currently applied workflow filter to its stored preference value.\n *\n * @param {DropdownDialog} extraFiltersDropdown The dropdown dialog instance.\n */\nconst restoreAppliedWorkflowFilter = async(extraFiltersDropdown) => {\n const appliedWorkflowFilter = await getUserPreference('assign_workflowfilter');\n const workflowFilterSelect = extraFiltersDropdown.getElement().querySelector(Selectors.workflowFilterElement);\n workflowFilterSelect.value = appliedWorkflowFilter;\n};\n\n/**\n * Initialize module.\n */\nexport const init = () => {\n const extraFiltersDropdown = getDropdownDialog(Selectors.extraFiltersDropdown);\n if (extraFiltersDropdown) {\n registerEventListeners(extraFiltersDropdown);\n }\n};\n"],"names":["Selectors","restoreAppliedWorkflowFilter","async","appliedWorkflowFilter","extraFiltersDropdown","getElement","querySelector","value","addEventListener","e","target","closest","preventDefault","setVisible","on","registerEventListeners"],"mappings":";;;;;;;gJA4BMA,+BACoB,yBADpBA,4BAEiB,yBAFjBA,gCAGqB,gCA6BrBC,6BAA+BC,MAAAA,6BAC3BC,4BAA8B,iCAAkB,yBACzBC,qBAAqBC,aAAaC,cAAcN,iCACxDO,MAAQJ,qCAMb,WACVC,sBAAuB,6BAAkBJ,gCAC3CI,sBAhCwBA,CAAAA,uBAE5BA,qBAAqBC,aAAaG,iBAAiB,SAASC,IAEpDA,EAAEC,OAAOC,QAAQX,+BACjBS,EAAEG,iBACFR,qBAAqBS,YAAW,2BAItCT,qBAAqBC,cAAcS,GAAG,oBAAoB,KAExDb,6BAA6BG,0BAqB7BW,CAAuBX"} \ No newline at end of file +{"version":3,"file":"extra_filters_dropdown.min.js","sources":["../../../src/actionbar/grading/extra_filters_dropdown.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\nimport {getDropdownDialog} from 'core/local/dropdown/dialog';\nimport {getUserPreference} from 'core_user/repository';\nimport $ from 'jquery';\n\n/**\n * Module for the extra filters dropdown on the submissions page.\n *\n * @module mod_assign/actionbar/grading/extra_filters_dropdown\n * @copyright 2024 Mihail Geshoski \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n/** @constant {Object} The object containing the relevant selectors. */\nconst Selectors = {\n extraFiltersDropdown: '.dropdown.extrafilters',\n extraFiltersClose: 'a[data-action=\"close\"]',\n workflowFilterElement: 'select[name=\"workflowfilter\"]',\n markerFilterElement: 'select[name=\"markingallocationfilter\"]'\n};\n\n/**\n * Register event listeners for the extra filters dropdown.\n *\n * @param {DropdownDialog} extraFiltersDropdown The dropdown dialog instance.\n */\nconst registerEventListeners = (extraFiltersDropdown) => {\n // Click event listener to the extra filters dropdown element.\n extraFiltersDropdown.getElement().addEventListener('click', e => {\n // The target is the 'Close' button.\n if (e.target.closest(Selectors.extraFiltersClose)) {\n e.preventDefault();\n extraFiltersDropdown.setVisible(false);\n }\n });\n // Event listener triggered upon hiding of the dropdown.\n $(extraFiltersDropdown.getElement()).on('hide.bs.dropdown', () => {\n // Restore the filters to their stored preference values once the dropdown is closed.\n restoreAppliedWorkflowFilter(extraFiltersDropdown);\n restoreAppliedMarkerFilter(extraFiltersDropdown);\n });\n};\n\n/**\n * Restores the currently applied workflow filter to its stored preference value.\n *\n * @param {DropdownDialog} extraFiltersDropdown The dropdown dialog instance.\n */\nconst restoreAppliedWorkflowFilter = async(extraFiltersDropdown) => {\n const appliedWorkflowFilter = await getUserPreference('assign_workflowfilter');\n const workflowFilterSelect = extraFiltersDropdown.getElement().querySelector(Selectors.workflowFilterElement);\n workflowFilterSelect.value = appliedWorkflowFilter;\n};\n\n/**\n * Restores the currently applied marker filter to its stored preference value.\n *\n * @param {DropdownDialog} extraFiltersDropdown The dropdown dialog instance.\n */\nconst restoreAppliedMarkerFilter = async(extraFiltersDropdown) => {\n const markerFilterSelect = extraFiltersDropdown.getElement().querySelector(Selectors.markerFilterElement);\n if (markerFilterSelect) {\n const appliedMarkerFilter = await getUserPreference('assign_markerfilter');\n markerFilterSelect.value = appliedMarkerFilter;\n }\n};\n\n/**\n * Initialize module.\n */\nexport const init = () => {\n const extraFiltersDropdown = getDropdownDialog(Selectors.extraFiltersDropdown);\n if (extraFiltersDropdown) {\n registerEventListeners(extraFiltersDropdown);\n }\n};\n"],"names":["Selectors","restoreAppliedWorkflowFilter","async","appliedWorkflowFilter","extraFiltersDropdown","getElement","querySelector","value","restoreAppliedMarkerFilter","markerFilterSelect","appliedMarkerFilter","addEventListener","e","target","closest","preventDefault","setVisible","on","registerEventListeners"],"mappings":";;;;;;;gJA4BMA,+BACoB,yBADpBA,4BAEiB,yBAFjBA,gCAGqB,gCAHrBA,8BAImB,yCA8BnBC,6BAA+BC,MAAAA,6BAC3BC,4BAA8B,iCAAkB,yBACzBC,qBAAqBC,aAAaC,cAAcN,iCACxDO,MAAQJ,uBAQ3BK,2BAA6BN,MAAAA,6BACzBO,mBAAqBL,qBAAqBC,aAAaC,cAAcN,kCACvES,mBAAoB,OACdC,0BAA4B,iCAAkB,uBACpDD,mBAAmBF,MAAQG,oCAOf,WACVN,sBAAuB,6BAAkBJ,gCAC3CI,sBA9CwBA,CAAAA,uBAE5BA,qBAAqBC,aAAaM,iBAAiB,SAASC,IAEpDA,EAAEC,OAAOC,QAAQd,+BACjBY,EAAEG,iBACFX,qBAAqBY,YAAW,2BAItCZ,qBAAqBC,cAAcY,GAAG,oBAAoB,KAExDhB,6BAA6BG,sBAC7BI,2BAA2BJ,0BAkC3Bc,CAAuBd"} \ No newline at end of file diff --git a/mod/assign/amd/src/actionbar/grading/extra_filters_dropdown.js b/mod/assign/amd/src/actionbar/grading/extra_filters_dropdown.js index eae64fd6e97..1e9fa2c3f0c 100644 --- a/mod/assign/amd/src/actionbar/grading/extra_filters_dropdown.js +++ b/mod/assign/amd/src/actionbar/grading/extra_filters_dropdown.js @@ -29,7 +29,8 @@ import $ from 'jquery'; const Selectors = { extraFiltersDropdown: '.dropdown.extrafilters', extraFiltersClose: 'a[data-action="close"]', - workflowFilterElement: 'select[name="workflowfilter"]' + workflowFilterElement: 'select[name="workflowfilter"]', + markerFilterElement: 'select[name="markingallocationfilter"]' }; /** @@ -50,6 +51,7 @@ const registerEventListeners = (extraFiltersDropdown) => { $(extraFiltersDropdown.getElement()).on('hide.bs.dropdown', () => { // Restore the filters to their stored preference values once the dropdown is closed. restoreAppliedWorkflowFilter(extraFiltersDropdown); + restoreAppliedMarkerFilter(extraFiltersDropdown); }); }; @@ -64,6 +66,19 @@ const restoreAppliedWorkflowFilter = async(extraFiltersDropdown) => { workflowFilterSelect.value = appliedWorkflowFilter; }; +/** + * Restores the currently applied marker filter to its stored preference value. + * + * @param {DropdownDialog} extraFiltersDropdown The dropdown dialog instance. + */ +const restoreAppliedMarkerFilter = async(extraFiltersDropdown) => { + const markerFilterSelect = extraFiltersDropdown.getElement().querySelector(Selectors.markerFilterElement); + if (markerFilterSelect) { + const appliedMarkerFilter = await getUserPreference('assign_markerfilter'); + markerFilterSelect.value = appliedMarkerFilter; + } +}; + /** * Initialize module. */ diff --git a/mod/assign/classes/output/grading_actionmenu.php b/mod/assign/classes/output/grading_actionmenu.php index 542a02843b1..7613db27757 100644 --- a/mod/assign/classes/output/grading_actionmenu.php +++ b/mod/assign/classes/output/grading_actionmenu.php @@ -308,6 +308,14 @@ class grading_actionmenu implements templatable, renderable { $dropdowncontentdata['filters']['markingworkflow'] = [ 'workflowfilteroptions' => $this->assign->get_marking_workflow_filters(true), ]; + + // If marking allocation is enabled and the user has the capability to manage marker allocations. + if ($this->assign->get_instance()->markingallocation && + has_capability('mod/assign:manageallocations', $this->assign->get_context())) { + $dropdowncontentdata['filters']['markingallocation'] = [ + 'markingallocationoptions' => $this->assign->get_marking_allocation_filters(true), + ]; + } } // If there are no available filters, return null. @@ -350,6 +358,14 @@ class grading_actionmenu implements templatable, renderable { if (get_user_preferences('assign_workflowfilter')) { $appliedextrafilterscount++; } + + $canallocatemarker = $this->assign->get_instance()->markingallocation && + has_capability('mod/assign:manageallocations', $this->assign->get_context()); + + if ($canallocatemarker && get_user_preferences('assign_markerfilter')) { + $appliedextrafilterscount++; + } + } return $appliedextrafilterscount; diff --git a/mod/assign/locallib.php b/mod/assign/locallib.php index c09f3c0ac94..d3ece3fcd94 100644 --- a/mod/assign/locallib.php +++ b/mod/assign/locallib.php @@ -4525,6 +4525,15 @@ class assign { set_user_preference('assign_workflowfilter', $workflowfilter); } + // Retrieve the 'markingallocationfilter' parameter, or set it to null if not provided. + $markingallocationfilter = optional_param('markingallocationfilter', null, PARAM_ALPHANUMEXT); + // Check if the parameter is not null and if it exists in the list of valid marking allocation filters. + if ($markingallocationfilter !== null && + array_key_exists($markingallocationfilter, $this->get_marking_allocation_filters())) { + // Save the valid 'markingallocationfilter' value as a user preference. + set_user_preference('assign_markerfilter', $markingallocationfilter); + } + $controller = $gradingmanager->get_active_controller(); $showquickgrading = empty($controller) && $this->can_grade(); $quickgrading = get_user_preferences('assign_quickgrading', false); @@ -9612,7 +9621,7 @@ class assign { } return $result; } - return $markingworkflowoptions; + return $markingallocationoptions; } /** diff --git a/mod/assign/templates/actionbar/grading/extra_filters_dropdown_body.mustache b/mod/assign/templates/actionbar/grading/extra_filters_dropdown_body.mustache index 6245c3de59d..a53b22a39e6 100644 --- a/mod/assign/templates/actionbar/grading/extra_filters_dropdown_body.mustache +++ b/mod/assign/templates/actionbar/grading/extra_filters_dropdown_body.mustache @@ -25,6 +25,11 @@ * key - The key of the workflow filter option * name - The name of the workflow filter option * active - Whether the workflow filter option is currently active + * markingallocation + * markingallocationoptions - Array of marking allocation filter options + * key - The key of the marking allocation filter option + * name - The name of the marking allocation filter option + * active - Whether the marking allocation filter option is currently active Example context (json): { @@ -41,6 +46,15 @@ "active": true } ] + }, + "markingallocation": { + "markingallocationoptions": [ + { + "key": "-1", + "name": "No marker", + "active": true + } + ] } } ] @@ -63,6 +77,18 @@ {{/markingworkflow}} + {{#markingallocation}} +
+ + +
+ {{/markingallocation}} {{/filters}}
{{#str}}closebuttontitle{{/str}} diff --git a/mod/assign/tests/behat/filter_by_marker.feature b/mod/assign/tests/behat/filter_by_marker.feature index 964d29d921a..89926bfb224 100644 --- a/mod/assign/tests/behat/filter_by_marker.feature +++ b/mod/assign/tests/behat/filter_by_marker.feature @@ -4,48 +4,117 @@ Feature: In an assignment, teachers can filter displayed submissions by assigned As a teacher I need to view submissions allocated to markers. + Background: + Given the following "courses" exist: + | fullname | shortname | category | + | Course 1 | C1 | 0 | + And the following "users" exist: + | username | firstname | lastname | email | + | teacher1 | Teacher | 1 | teacher1@example.com | + | student1 | Student | 1 | student1@example.com | + | student2 | Student | 2 | student2@example.com | + | marker1 | Marker | 1 | marker1@example.com | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + | student1 | C1 | student | + | student2 | C1 | student | + | marker1 | C1 | teacher | + And the following "activity" exists: + | activity | assign | + | course | C1 | + | name | Test assignment name | + + @javascript + Scenario: The marker filter is available only when marking workflow and marking allocation is enabled in the assignment + Given I am on the "Test assignment name" Activity page logged in as teacher1 + And I navigate to "Submissions" in current page administration + And I change window size to "large" + And I click on "Advanced" "button" in the ".tertiary-navigation" "css_element" + And "Marker" "select" should not exist in the ".extrafilters .dropdown-menu" "css_element" + And I am on the "Test assignment name" "assign activity editing" page + And I expand all fieldsets + When I set the field "Use marking workflow" to "Yes" + And I set the field "Use marking allocation" to "Yes" + And I press "Save and display" + And I navigate to "Submissions" in current page administration + And I click on "Advanced" "button" in the ".tertiary-navigation" "css_element" + Then "Marker" "select" should exist in the ".extrafilters .dropdown-menu" "css_element" + And the field "Marker" matches value "No filter" + And the "Marker" select box should contain "No filter" + And the "Marker" select box should contain "No marker" + And the "Marker" select box should contain "Teacher 1" + And the "Marker" select box should contain "Marker 1" + And the "Marker" select box should not contain "Student 1" + And the "Marker" select box should not contain "Student 2" + @javascript Scenario: Allocate markers to submissions and filter by marker - Given the following "courses" exist: - | fullname | shortname | category | groupmode | - | Course 1 | C1 | 0 | 1 | - And the following "users" exist: - | username | firstname | lastname | email | - | teacher1 | Teacher | 1 | teacher1@example.com | - | student1 | Student | 1 | student1@example.com | - | student2 | Student | 2 | student2@example.com | - | marker1 | Marker | 1 | marker1@example.com | - And the following "course enrolments" exist: - | user | course | role | - | teacher1 | C1 | editingteacher | - | student1 | C1 | student | - | student2 | C1 | student | - | marker1 | C1 | teacher | - And the following "activity" exists: - | activity | assign | - | course | C1 | - | name | Test assignment name | - | intro | Submit your online text | - | submissiondrafts | 0 | - | assignsubmission_onlinetext_enabled | 1 | - | assignsubmission_file_enabled | 0 | - | markingworkflow | 1 | - | markingallocation | 1 | - And I am on the "Test assignment name" Activity page logged in as teacher1 + Given I am on the "Test assignment name" "assign activity editing" page logged in as teacher1 + And I expand all fieldsets + And I set the field "Use marking workflow" to "Yes" + And I set the field "Use marking allocation" to "Yes" + And I press "Save and display" + And I am on the "Test assignment name" "assign activity" page And I go to "Student 1" "Test assignment name" activity advanced grading page And I set the field "allocatedmarker" to "Marker 1" And I set the field "Notify student" to "0" And I press "Save changes" - And I click on "Edit settings" "link" - - When I am on the "Test assignment name" Activity page + And I am on the "Test assignment name" Activity page And I navigate to "Submissions" in current page administration - And I set the field "markerfilter" to "Marker 1" - Then I should see "Student 1" - And I should not see "Student 2" - And I set the field "markerfilter" to "No marker" - And I should not see "Student 1" - And I should see "Student 2" - And I set the field "markerfilter" to "No filter" - And I should see "Student 1" - And I should see "Student 2" + And I change window size to "large" + # Set the Marker filter to 'Marker 1'. + And I click on "Advanced" "button" in the ".tertiary-navigation" "css_element" + And I set the field "Marker" in the ".extrafilters .dropdown-menu" "css_element" to "Marker 1" + When I click on "Apply" "button" in the ".extrafilters .dropdown-menu" "css_element" + # Ensure only Student 1 is now displayed in the submissions table. + Then the following should exist in the "submissions" table: + | -2- | + | Student 1 | + And the following should not exist in the "submissions" table: + | -2- | + | Student 2 | + # Ensure the badge indicating the number of applied filters is present. + And ".badge" "css_element" should exist in the ".extrafilters .dropdown-toggle" "css_element" + And I should see "+1" in the ".extrafilters .badge" "css_element" + # Ensure the filter remains applied when navigating away from and returning to the assignment submissions page. + And I am on the "Test assignment name" Activity page + And I navigate to "Submissions" in current page administration + And the following should exist in the "submissions" table: + | -2- | + | Student 1 | + And the following should not exist in the "submissions" table: + | -2- | + | Student 2 | + And I click on "Advanced" "button" in the ".tertiary-navigation" "css_element" + And the field "Marker" matches value "Marker 1" + # Ensure the filter is not applied unless the 'Apply' button is pressed. + And I set the field "Marker" in the ".extrafilters .dropdown-menu" "css_element" to "No marker" + And I click on "Close" "link" in the ".extrafilters .dropdown-menu" "css_element" + And the following should exist in the "submissions" table: + | -2- | + | Student 1 | + And the following should not exist in the "submissions" table: + | -2- | + | Student 2 | + And I click on "Advanced" "button" in the ".tertiary-navigation" "css_element" + And the field "Marker" matches value "Marker 1" + # Set the Marker filter to 'No marker'. + And I set the field "Marker" in the ".extrafilters .dropdown-menu" "css_element" to "No marker" + And I click on "Apply" "button" in the ".extrafilters .dropdown-menu" "css_element" + # Ensure only Student 2 is now displayed in the submissions table. + And the following should exist in the "submissions" table: + | -2- | + | Student 2 | + And the following should not exist in the "submissions" table: + | -2- | + | Student 1 | + # Set the Marker filter to 'No filter'. + And I click on "Advanced" "button" in the ".tertiary-navigation" "css_element" + And I set the field "Marker" in the ".extrafilters .dropdown-menu" "css_element" to "No filter" + And I click on "Apply" "button" in the ".extrafilters .dropdown-menu" "css_element" + # Ensure all student are now displayed in the submissions table. + And the following should exist in the "submissions" table: + | -2- | + | Student 1 | + | Student 2 | diff --git a/mod/assign/tests/behat/grading_app_filters.feature b/mod/assign/tests/behat/grading_app_filters.feature index 5a56ee14097..d142c70f251 100644 --- a/mod/assign/tests/behat/grading_app_filters.feature +++ b/mod/assign/tests/behat/grading_app_filters.feature @@ -47,8 +47,8 @@ Feature: In an assignment, teachers can change filters in the grading app And I am on the "Test assignment name &" Activity page And I navigate to "Submissions" in current page administration And I set the field "Status" to "Not submitted" - And I set the field "markerfilter" to "Marker 1" And I click on "Advanced" "button" in the ".tertiary-navigation" "css_element" + And I set the field "Marker" in the ".extrafilters .dropdown-menu" "css_element" to "Marker 1" And I set the field "Marking state" in the ".extrafilters .dropdown-menu" "css_element" to "In marking" And I click on "Apply" "button" in the ".extrafilters .dropdown-menu" "css_element" And I change window size to "large" @@ -76,6 +76,6 @@ Feature: In an assignment, teachers can change filters in the grading app And I set the field "workflowfilter" to "In marking" And I click on "View all submissions" "link" Then the field "Status" matches value "Not submitted" - And the field "markerfilter" matches value "Marker 1" And I click on "Advanced" "button" in the ".tertiary-navigation" "css_element" + And the field "Marker" matches value "Marker 1" And the field "Marking state" matches value "In marking" From 9265ab5ca801bd429e1dbbc707e253c1d2acf28f Mon Sep 17 00:00:00 2001 From: Mihail Geshoski Date: Tue, 13 Aug 2024 11:25:29 +0800 Subject: [PATCH 2/8] MDL-82681 mod_assign: Add Suspended participants to Advanced filters Adds 'Suspended participants' filter to the 'Advanced' filters component on the assignment submissions page. --- .../grading/extra_filters_dropdown.min.js | 2 +- .../grading/extra_filters_dropdown.min.js.map | 2 +- .../grading/extra_filters_dropdown.js | 37 ++++++- .../classes/output/grading_actionmenu.php | 10 ++ mod/assign/lang/en/assign.php | 1 + mod/assign/locallib.php | 8 ++ .../extra_filters_dropdown_body.mustache | 12 +++ .../behat/filter_by_marking_workflow.feature | 4 +- .../filter_suspended_participants.feature | 98 +++++++++++++++++++ 9 files changed, 168 insertions(+), 6 deletions(-) create mode 100644 mod/assign/tests/behat/filter_suspended_participants.feature diff --git a/mod/assign/amd/build/actionbar/grading/extra_filters_dropdown.min.js b/mod/assign/amd/build/actionbar/grading/extra_filters_dropdown.min.js index 75e9e43117f..58d4d99f7b1 100644 --- a/mod/assign/amd/build/actionbar/grading/extra_filters_dropdown.min.js +++ b/mod/assign/amd/build/actionbar/grading/extra_filters_dropdown.min.js @@ -5,6 +5,6 @@ define("mod_assign/actionbar/grading/extra_filters_dropdown",["exports","core/lo * @module mod_assign/actionbar/grading/extra_filters_dropdown * @copyright 2024 Mihail Geshoski * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_jquery=(obj=_jquery)&&obj.__esModule?obj:{default:obj};const Selectors_extraFiltersDropdown=".dropdown.extrafilters",Selectors_extraFiltersClose='a[data-action="close"]',Selectors_workflowFilterElement='select[name="workflowfilter"]',Selectors_markerFilterElement='select[name="markingallocationfilter"]',restoreAppliedWorkflowFilter=async extraFiltersDropdown=>{const appliedWorkflowFilter=await(0,_repository.getUserPreference)("assign_workflowfilter");extraFiltersDropdown.getElement().querySelector(Selectors_workflowFilterElement).value=appliedWorkflowFilter},restoreAppliedMarkerFilter=async extraFiltersDropdown=>{const markerFilterSelect=extraFiltersDropdown.getElement().querySelector(Selectors_markerFilterElement);if(markerFilterSelect){const appliedMarkerFilter=await(0,_repository.getUserPreference)("assign_markerfilter");markerFilterSelect.value=appliedMarkerFilter}};_exports.init=()=>{const extraFiltersDropdown=(0,_dialog.getDropdownDialog)(Selectors_extraFiltersDropdown);extraFiltersDropdown&&(extraFiltersDropdown=>{extraFiltersDropdown.getElement().addEventListener("click",(e=>{e.target.closest(Selectors_extraFiltersClose)&&(e.preventDefault(),extraFiltersDropdown.setVisible(!1))})),(0,_jquery.default)(extraFiltersDropdown.getElement()).on("hide.bs.dropdown",(()=>{restoreAppliedWorkflowFilter(extraFiltersDropdown),restoreAppliedMarkerFilter(extraFiltersDropdown)}))})(extraFiltersDropdown)}})); + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_jquery=(obj=_jquery)&&obj.__esModule?obj:{default:obj};const Selectors_extraFiltersDropdown=".dropdown.extrafilters",Selectors_extraFiltersClose='a[data-action="close"]',Selectors_workflowFilterElement='select[name="workflowfilter"]',Selectors_markerFilterElement='select[name="markingallocationfilter"]',Selectors_suspendedParticipantsFilterCheckbox='input[type="checkbox"][name="suspendedparticipantsfilter"]',Selectors_suspendedParticipantsFilterHidden='input[type="hidden"][name="suspendedparticipantsfilter"]',restoreAppliedWorkflowFilter=async extraFiltersDropdown=>{const appliedWorkflowFilter=await(0,_repository.getUserPreference)("assign_workflowfilter");extraFiltersDropdown.getElement().querySelector(Selectors_workflowFilterElement).value=appliedWorkflowFilter},restoreAppliedMarkerFilter=async extraFiltersDropdown=>{const markerFilterSelect=extraFiltersDropdown.getElement().querySelector(Selectors_markerFilterElement);if(markerFilterSelect){const appliedMarkerFilter=await(0,_repository.getUserPreference)("assign_markerfilter");markerFilterSelect.value=appliedMarkerFilter}},restoreAppliedSuspendedParticipantsFilter=async extraFiltersDropdown=>{const suspendedParticipantsFilterCheckbox=extraFiltersDropdown.getElement().querySelector(Selectors_suspendedParticipantsFilterCheckbox);if(suspendedParticipantsFilterCheckbox){const suspendedParticipantsFilterHidden=suspendedParticipantsFilterCheckbox.parentNode.querySelector(Selectors_suspendedParticipantsFilterHidden),showOnlyActiveParticipants=await(0,_repository.getUserPreference)("grade_report_showonlyactiveenrol");suspendedParticipantsFilterCheckbox.checked=!showOnlyActiveParticipants,suspendedParticipantsFilterHidden.disabled=!showOnlyActiveParticipants}};_exports.init=()=>{const extraFiltersDropdown=(0,_dialog.getDropdownDialog)(Selectors_extraFiltersDropdown);extraFiltersDropdown&&(extraFiltersDropdown=>{extraFiltersDropdown.getElement().addEventListener("click",(e=>{e.target.closest(Selectors_extraFiltersClose)&&(e.preventDefault(),extraFiltersDropdown.setVisible(!1))})),extraFiltersDropdown.getElement().addEventListener("change",(e=>{const suspendedParticipantsFilterCheckbox=e.target.closest(Selectors_suspendedParticipantsFilterCheckbox);suspendedParticipantsFilterCheckbox&&(suspendedParticipantsFilterCheckbox.parentNode.querySelector(Selectors_suspendedParticipantsFilterHidden).disabled=suspendedParticipantsFilterCheckbox.checked)})),(0,_jquery.default)(extraFiltersDropdown.getElement()).on("hide.bs.dropdown",(()=>{restoreAppliedWorkflowFilter(extraFiltersDropdown),restoreAppliedMarkerFilter(extraFiltersDropdown),restoreAppliedSuspendedParticipantsFilter(extraFiltersDropdown)}))})(extraFiltersDropdown)}})); //# sourceMappingURL=extra_filters_dropdown.min.js.map \ No newline at end of file diff --git a/mod/assign/amd/build/actionbar/grading/extra_filters_dropdown.min.js.map b/mod/assign/amd/build/actionbar/grading/extra_filters_dropdown.min.js.map index 70b5ffa61ba..a9dd34f8c61 100644 --- a/mod/assign/amd/build/actionbar/grading/extra_filters_dropdown.min.js.map +++ b/mod/assign/amd/build/actionbar/grading/extra_filters_dropdown.min.js.map @@ -1 +1 @@ -{"version":3,"file":"extra_filters_dropdown.min.js","sources":["../../../src/actionbar/grading/extra_filters_dropdown.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\nimport {getDropdownDialog} from 'core/local/dropdown/dialog';\nimport {getUserPreference} from 'core_user/repository';\nimport $ from 'jquery';\n\n/**\n * Module for the extra filters dropdown on the submissions page.\n *\n * @module mod_assign/actionbar/grading/extra_filters_dropdown\n * @copyright 2024 Mihail Geshoski \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n/** @constant {Object} The object containing the relevant selectors. */\nconst Selectors = {\n extraFiltersDropdown: '.dropdown.extrafilters',\n extraFiltersClose: 'a[data-action=\"close\"]',\n workflowFilterElement: 'select[name=\"workflowfilter\"]',\n markerFilterElement: 'select[name=\"markingallocationfilter\"]'\n};\n\n/**\n * Register event listeners for the extra filters dropdown.\n *\n * @param {DropdownDialog} extraFiltersDropdown The dropdown dialog instance.\n */\nconst registerEventListeners = (extraFiltersDropdown) => {\n // Click event listener to the extra filters dropdown element.\n extraFiltersDropdown.getElement().addEventListener('click', e => {\n // The target is the 'Close' button.\n if (e.target.closest(Selectors.extraFiltersClose)) {\n e.preventDefault();\n extraFiltersDropdown.setVisible(false);\n }\n });\n // Event listener triggered upon hiding of the dropdown.\n $(extraFiltersDropdown.getElement()).on('hide.bs.dropdown', () => {\n // Restore the filters to their stored preference values once the dropdown is closed.\n restoreAppliedWorkflowFilter(extraFiltersDropdown);\n restoreAppliedMarkerFilter(extraFiltersDropdown);\n });\n};\n\n/**\n * Restores the currently applied workflow filter to its stored preference value.\n *\n * @param {DropdownDialog} extraFiltersDropdown The dropdown dialog instance.\n */\nconst restoreAppliedWorkflowFilter = async(extraFiltersDropdown) => {\n const appliedWorkflowFilter = await getUserPreference('assign_workflowfilter');\n const workflowFilterSelect = extraFiltersDropdown.getElement().querySelector(Selectors.workflowFilterElement);\n workflowFilterSelect.value = appliedWorkflowFilter;\n};\n\n/**\n * Restores the currently applied marker filter to its stored preference value.\n *\n * @param {DropdownDialog} extraFiltersDropdown The dropdown dialog instance.\n */\nconst restoreAppliedMarkerFilter = async(extraFiltersDropdown) => {\n const markerFilterSelect = extraFiltersDropdown.getElement().querySelector(Selectors.markerFilterElement);\n if (markerFilterSelect) {\n const appliedMarkerFilter = await getUserPreference('assign_markerfilter');\n markerFilterSelect.value = appliedMarkerFilter;\n }\n};\n\n/**\n * Initialize module.\n */\nexport const init = () => {\n const extraFiltersDropdown = getDropdownDialog(Selectors.extraFiltersDropdown);\n if (extraFiltersDropdown) {\n registerEventListeners(extraFiltersDropdown);\n }\n};\n"],"names":["Selectors","restoreAppliedWorkflowFilter","async","appliedWorkflowFilter","extraFiltersDropdown","getElement","querySelector","value","restoreAppliedMarkerFilter","markerFilterSelect","appliedMarkerFilter","addEventListener","e","target","closest","preventDefault","setVisible","on","registerEventListeners"],"mappings":";;;;;;;gJA4BMA,+BACoB,yBADpBA,4BAEiB,yBAFjBA,gCAGqB,gCAHrBA,8BAImB,yCA8BnBC,6BAA+BC,MAAAA,6BAC3BC,4BAA8B,iCAAkB,yBACzBC,qBAAqBC,aAAaC,cAAcN,iCACxDO,MAAQJ,uBAQ3BK,2BAA6BN,MAAAA,6BACzBO,mBAAqBL,qBAAqBC,aAAaC,cAAcN,kCACvES,mBAAoB,OACdC,0BAA4B,iCAAkB,uBACpDD,mBAAmBF,MAAQG,oCAOf,WACVN,sBAAuB,6BAAkBJ,gCAC3CI,sBA9CwBA,CAAAA,uBAE5BA,qBAAqBC,aAAaM,iBAAiB,SAASC,IAEpDA,EAAEC,OAAOC,QAAQd,+BACjBY,EAAEG,iBACFX,qBAAqBY,YAAW,2BAItCZ,qBAAqBC,cAAcY,GAAG,oBAAoB,KAExDhB,6BAA6BG,sBAC7BI,2BAA2BJ,0BAkC3Bc,CAAuBd"} \ No newline at end of file +{"version":3,"file":"extra_filters_dropdown.min.js","sources":["../../../src/actionbar/grading/extra_filters_dropdown.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\nimport {getDropdownDialog} from 'core/local/dropdown/dialog';\nimport {getUserPreference} from 'core_user/repository';\nimport $ from 'jquery';\n\n/**\n * Module for the extra filters dropdown on the submissions page.\n *\n * @module mod_assign/actionbar/grading/extra_filters_dropdown\n * @copyright 2024 Mihail Geshoski \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n/** @constant {Object} The object containing the relevant selectors. */\nconst Selectors = {\n extraFiltersDropdown: '.dropdown.extrafilters',\n extraFiltersClose: 'a[data-action=\"close\"]',\n workflowFilterElement: 'select[name=\"workflowfilter\"]',\n markerFilterElement: 'select[name=\"markingallocationfilter\"]',\n suspendedParticipantsFilterCheckbox: 'input[type=\"checkbox\"][name=\"suspendedparticipantsfilter\"]',\n suspendedParticipantsFilterHidden: 'input[type=\"hidden\"][name=\"suspendedparticipantsfilter\"]'\n};\n\n/**\n * Register event listeners for the extra filters dropdown.\n *\n * @param {DropdownDialog} extraFiltersDropdown The dropdown dialog instance.\n */\nconst registerEventListeners = (extraFiltersDropdown) => {\n // Click event listener to the extra filters dropdown element.\n extraFiltersDropdown.getElement().addEventListener('click', e => {\n // The target is the 'Close' button.\n if (e.target.closest(Selectors.extraFiltersClose)) {\n e.preventDefault();\n extraFiltersDropdown.setVisible(false);\n }\n });\n\n // Change event listener to the extra filters dropdown element.\n extraFiltersDropdown.getElement().addEventListener('change', e => {\n const suspendedParticipantsFilterCheckbox = e.target.closest(Selectors.suspendedParticipantsFilterCheckbox);\n // The target is the 'Suspended participants' filter checkbox.\n if (suspendedParticipantsFilterCheckbox) {\n // The 'Suspended participants' filter uses a hidden input and a checkbox. The hidden input is used to\n // submit '0' as a workaround when the checkbox is unchecked since unchecked checkboxes are not submitted\n // with the form. Therefore, we need to enable or disable the hidden input based on the checkbox state.\n const suspendedParticipantsFilterHidden = suspendedParticipantsFilterCheckbox.parentNode\n .querySelector(Selectors.suspendedParticipantsFilterHidden);\n suspendedParticipantsFilterHidden.disabled = suspendedParticipantsFilterCheckbox.checked;\n }\n });\n\n // Event listener triggered upon hiding of the dropdown.\n $(extraFiltersDropdown.getElement()).on('hide.bs.dropdown', () => {\n // Restore the filters to their stored preference values once the dropdown is closed.\n restoreAppliedWorkflowFilter(extraFiltersDropdown);\n restoreAppliedMarkerFilter(extraFiltersDropdown);\n restoreAppliedSuspendedParticipantsFilter(extraFiltersDropdown);\n });\n};\n\n/**\n * Restores the currently applied workflow filter to its stored preference value.\n *\n * @param {DropdownDialog} extraFiltersDropdown The dropdown dialog instance.\n */\nconst restoreAppliedWorkflowFilter = async(extraFiltersDropdown) => {\n const appliedWorkflowFilter = await getUserPreference('assign_workflowfilter');\n const workflowFilterSelect = extraFiltersDropdown.getElement().querySelector(Selectors.workflowFilterElement);\n workflowFilterSelect.value = appliedWorkflowFilter;\n};\n\n/**\n * Restores the currently applied marker filter to its stored preference value.\n *\n * @param {DropdownDialog} extraFiltersDropdown The dropdown dialog instance.\n */\nconst restoreAppliedMarkerFilter = async(extraFiltersDropdown) => {\n const markerFilterSelect = extraFiltersDropdown.getElement().querySelector(Selectors.markerFilterElement);\n if (markerFilterSelect) {\n const appliedMarkerFilter = await getUserPreference('assign_markerfilter');\n markerFilterSelect.value = appliedMarkerFilter;\n }\n};\n\n/**\n * Restores the currently suspended participants filter to its stored preference value.\n *\n * @param {DropdownDialog} extraFiltersDropdown The dropdown dialog instance.\n */\nconst restoreAppliedSuspendedParticipantsFilter = async(extraFiltersDropdown) => {\n const suspendedParticipantsFilterCheckbox = extraFiltersDropdown.getElement()\n .querySelector(Selectors.suspendedParticipantsFilterCheckbox);\n if (suspendedParticipantsFilterCheckbox) {\n const suspendedParticipantsFilterHidden = suspendedParticipantsFilterCheckbox.parentNode\n .querySelector(Selectors.suspendedParticipantsFilterHidden);\n const showOnlyActiveParticipants = await getUserPreference('grade_report_showonlyactiveenrol');\n suspendedParticipantsFilterCheckbox.checked = !showOnlyActiveParticipants;\n suspendedParticipantsFilterHidden.disabled = !showOnlyActiveParticipants;\n }\n};\n\n/**\n * Initialize module.\n */\nexport const init = () => {\n const extraFiltersDropdown = getDropdownDialog(Selectors.extraFiltersDropdown);\n if (extraFiltersDropdown) {\n registerEventListeners(extraFiltersDropdown);\n }\n};\n"],"names":["Selectors","restoreAppliedWorkflowFilter","async","appliedWorkflowFilter","extraFiltersDropdown","getElement","querySelector","value","restoreAppliedMarkerFilter","markerFilterSelect","appliedMarkerFilter","restoreAppliedSuspendedParticipantsFilter","suspendedParticipantsFilterCheckbox","suspendedParticipantsFilterHidden","parentNode","showOnlyActiveParticipants","checked","disabled","addEventListener","e","target","closest","preventDefault","setVisible","on","registerEventListeners"],"mappings":";;;;;;;gJA4BMA,+BACoB,yBADpBA,4BAEiB,yBAFjBA,gCAGqB,gCAHrBA,8BAImB,yCAJnBA,8CAKmC,6DALnCA,4CAMiC,2DA8CjCC,6BAA+BC,MAAAA,6BAC3BC,4BAA8B,iCAAkB,yBACzBC,qBAAqBC,aAAaC,cAAcN,iCACxDO,MAAQJ,uBAQ3BK,2BAA6BN,MAAAA,6BACzBO,mBAAqBL,qBAAqBC,aAAaC,cAAcN,kCACvES,mBAAoB,OACdC,0BAA4B,iCAAkB,uBACpDD,mBAAmBF,MAAQG,sBAS7BC,0CAA4CT,MAAAA,6BACxCU,oCAAsCR,qBAAqBC,aAC5DC,cAAcN,kDACfY,oCAAqC,OAC/BC,kCAAoCD,oCAAoCE,WACzER,cAAcN,6CACbe,iCAAmC,iCAAkB,oCAC3DH,oCAAoCI,SAAWD,2BAC/CF,kCAAkCI,UAAYF,2CAOlC,WACVX,sBAAuB,6BAAkBJ,gCAC3CI,sBA/EwBA,CAAAA,uBAE5BA,qBAAqBC,aAAaa,iBAAiB,SAASC,IAEpDA,EAAEC,OAAOC,QAAQrB,+BACjBmB,EAAEG,iBACFlB,qBAAqBmB,YAAW,OAKxCnB,qBAAqBC,aAAaa,iBAAiB,UAAUC,UACnDP,oCAAsCO,EAAEC,OAAOC,QAAQrB,+CAEzDY,sCAI0CA,oCAAoCE,WACzER,cAAcN,6CACeiB,SAAWL,oCAAoCI,gCAKvFZ,qBAAqBC,cAAcmB,GAAG,oBAAoB,KAExDvB,6BAA6BG,sBAC7BI,2BAA2BJ,sBAC3BO,0CAA0CP,0BAmD1CqB,CAAuBrB"} \ No newline at end of file diff --git a/mod/assign/amd/src/actionbar/grading/extra_filters_dropdown.js b/mod/assign/amd/src/actionbar/grading/extra_filters_dropdown.js index 1e9fa2c3f0c..3509d16ed52 100644 --- a/mod/assign/amd/src/actionbar/grading/extra_filters_dropdown.js +++ b/mod/assign/amd/src/actionbar/grading/extra_filters_dropdown.js @@ -30,7 +30,9 @@ const Selectors = { extraFiltersDropdown: '.dropdown.extrafilters', extraFiltersClose: 'a[data-action="close"]', workflowFilterElement: 'select[name="workflowfilter"]', - markerFilterElement: 'select[name="markingallocationfilter"]' + markerFilterElement: 'select[name="markingallocationfilter"]', + suspendedParticipantsFilterCheckbox: 'input[type="checkbox"][name="suspendedparticipantsfilter"]', + suspendedParticipantsFilterHidden: 'input[type="hidden"][name="suspendedparticipantsfilter"]' }; /** @@ -47,11 +49,27 @@ const registerEventListeners = (extraFiltersDropdown) => { extraFiltersDropdown.setVisible(false); } }); + + // Change event listener to the extra filters dropdown element. + extraFiltersDropdown.getElement().addEventListener('change', e => { + const suspendedParticipantsFilterCheckbox = e.target.closest(Selectors.suspendedParticipantsFilterCheckbox); + // The target is the 'Suspended participants' filter checkbox. + if (suspendedParticipantsFilterCheckbox) { + // The 'Suspended participants' filter uses a hidden input and a checkbox. The hidden input is used to + // submit '0' as a workaround when the checkbox is unchecked since unchecked checkboxes are not submitted + // with the form. Therefore, we need to enable or disable the hidden input based on the checkbox state. + const suspendedParticipantsFilterHidden = suspendedParticipantsFilterCheckbox.parentNode + .querySelector(Selectors.suspendedParticipantsFilterHidden); + suspendedParticipantsFilterHidden.disabled = suspendedParticipantsFilterCheckbox.checked; + } + }); + // Event listener triggered upon hiding of the dropdown. $(extraFiltersDropdown.getElement()).on('hide.bs.dropdown', () => { // Restore the filters to their stored preference values once the dropdown is closed. restoreAppliedWorkflowFilter(extraFiltersDropdown); restoreAppliedMarkerFilter(extraFiltersDropdown); + restoreAppliedSuspendedParticipantsFilter(extraFiltersDropdown); }); }; @@ -79,6 +97,23 @@ const restoreAppliedMarkerFilter = async(extraFiltersDropdown) => { } }; +/** + * Restores the currently suspended participants filter to its stored preference value. + * + * @param {DropdownDialog} extraFiltersDropdown The dropdown dialog instance. + */ +const restoreAppliedSuspendedParticipantsFilter = async(extraFiltersDropdown) => { + const suspendedParticipantsFilterCheckbox = extraFiltersDropdown.getElement() + .querySelector(Selectors.suspendedParticipantsFilterCheckbox); + if (suspendedParticipantsFilterCheckbox) { + const suspendedParticipantsFilterHidden = suspendedParticipantsFilterCheckbox.parentNode + .querySelector(Selectors.suspendedParticipantsFilterHidden); + const showOnlyActiveParticipants = await getUserPreference('grade_report_showonlyactiveenrol'); + suspendedParticipantsFilterCheckbox.checked = !showOnlyActiveParticipants; + suspendedParticipantsFilterHidden.disabled = !showOnlyActiveParticipants; + } +}; + /** * Initialize module. */ diff --git a/mod/assign/classes/output/grading_actionmenu.php b/mod/assign/classes/output/grading_actionmenu.php index 7613db27757..b02af750ab9 100644 --- a/mod/assign/classes/output/grading_actionmenu.php +++ b/mod/assign/classes/output/grading_actionmenu.php @@ -318,6 +318,12 @@ class grading_actionmenu implements templatable, renderable { } } + if (has_capability('moodle/course:viewsuspendedusers', $this->assign->get_context())) { + $dropdowncontentdata['filters']['suspendedparticipants'] = [ + 'active' => !$this->assign->show_only_active_users(), + ]; + } + // If there are no available filters, return null. if (empty($dropdowncontentdata['filters'])) { return null; @@ -365,7 +371,11 @@ class grading_actionmenu implements templatable, renderable { if ($canallocatemarker && get_user_preferences('assign_markerfilter')) { $appliedextrafilterscount++; } + } + // If suspended participants are included. + if (!$this->assign->show_only_active_users()) { + $appliedextrafilterscount++; } return $appliedextrafilterscount; diff --git a/mod/assign/lang/en/assign.php b/mod/assign/lang/en/assign.php index c0a84efc89c..9cf48536afa 100644 --- a/mod/assign/lang/en/assign.php +++ b/mod/assign/lang/en/assign.php @@ -344,6 +344,7 @@ Note that this setting has no effect on the comments box on the grading page.'; $string['hideshow'] = 'Hide/Show'; $string['hiddenuser'] = 'Participant '; $string['inactiveoverridehelp'] = '* This override is inactive because the user\'s access to the activity is restricted. This can be due to group or role assignments, other access restrictions, or the activity being hidden.'; +$string['includesuspendedparticipants'] = 'Include suspended participants'; $string['indicator:cognitivedepth'] = 'Assignment cognitive'; $string['indicator:cognitivedepth_help'] = 'This indicator is based on the cognitive depth reached by the student in an assignment activity.'; $string['indicator:cognitivedepthdef'] = 'Assignment cognitive'; diff --git a/mod/assign/locallib.php b/mod/assign/locallib.php index d3ece3fcd94..ca00b74d9a6 100644 --- a/mod/assign/locallib.php +++ b/mod/assign/locallib.php @@ -4534,6 +4534,14 @@ class assign { set_user_preference('assign_markerfilter', $markingallocationfilter); } + // Retrieve the 'suspendedparticipantsfilter' parameter, or set it to null if not provided. + $suspendedparticipantsfilter = optional_param('suspendedparticipantsfilter', null, PARAM_BOOL); + if ($suspendedparticipantsfilter !== null && + has_capability('moodle/course:viewsuspendedusers', $this->get_context())) { + // Save the 'suspendedparticipantsfilter' value as a user preference. + set_user_preference('grade_report_showonlyactiveenrol', !$suspendedparticipantsfilter); + } + $controller = $gradingmanager->get_active_controller(); $showquickgrading = empty($controller) && $this->can_grade(); $quickgrading = get_user_preferences('assign_quickgrading', false); diff --git a/mod/assign/templates/actionbar/grading/extra_filters_dropdown_body.mustache b/mod/assign/templates/actionbar/grading/extra_filters_dropdown_body.mustache index a53b22a39e6..a3e4f46e023 100644 --- a/mod/assign/templates/actionbar/grading/extra_filters_dropdown_body.mustache +++ b/mod/assign/templates/actionbar/grading/extra_filters_dropdown_body.mustache @@ -30,6 +30,8 @@ * key - The key of the marking allocation filter option * name - The name of the marking allocation filter option * active - Whether the marking allocation filter option is currently active + * suspendedparticipants + * active - Whether the suspended participants filter is currently active Example context (json): { @@ -55,6 +57,9 @@ "active": true } ] + }, + "suspendedparticipants": { + "active": true } } ] @@ -89,6 +94,13 @@
{{/markingallocation}} + {{#suspendedparticipants}} +
+ + + +
+ {{/suspendedparticipants}} {{/filters}}
{{#str}}closebuttontitle{{/str}} diff --git a/mod/assign/tests/behat/filter_by_marking_workflow.feature b/mod/assign/tests/behat/filter_by_marking_workflow.feature index ef909fb90cb..ead8c521cd4 100644 --- a/mod/assign/tests/behat/filter_by_marking_workflow.feature +++ b/mod/assign/tests/behat/filter_by_marking_workflow.feature @@ -30,15 +30,13 @@ Feature: In an assignment, teachers can filter displayed submissions by marking Given I am on the "Test assignment" Activity page logged in as teacher1 And I navigate to "Submissions" in current page administration And I change window size to "large" - And "Advanced" "button" should not exist in the ".tertiary-navigation" "css_element" When I am on the "Test assignment" "assign activity editing" page And I expand all fieldsets And I set the field "Use marking workflow" to "Yes" And I press "Save and display" And I navigate to "Submissions" in current page administration - Then "Advanced" "button" should exist in the ".tertiary-navigation" "css_element" And I click on "Advanced" "button" in the ".tertiary-navigation" "css_element" - And "Marking state" "select" should exist in the ".extrafilters .dropdown-menu" "css_element" + Then "Marking state" "select" should exist in the ".extrafilters .dropdown-menu" "css_element" And the field "Marking state" matches value "No filter" And the "Marking state" select box should contain "No filter" And the "Marking state" select box should contain "Not marked" diff --git a/mod/assign/tests/behat/filter_suspended_participants.feature b/mod/assign/tests/behat/filter_suspended_participants.feature new file mode 100644 index 00000000000..6ae2128d307 --- /dev/null +++ b/mod/assign/tests/behat/filter_suspended_participants.feature @@ -0,0 +1,98 @@ +@mod @mod_assign +Feature: In an assignment, teachers can include or exclude submissions from suspended participants + In order to manage submissions more easily + As a teacher + I need to be able to include or exclude submissions from suspended participants. + + Background: + Given the following "courses" exist: + | fullname | shortname | category | + | Course 1 | C1 | 0 | + And the following "users" exist: + | username | firstname | lastname | email | + | teacher1 | Teacher | 1 | teacher1@example.com | + | student1 | Student | 1 | student1@example.com | + | student2 | Student | 2 | student2@example.com | + And the following "course enrolments" exist: + | user | course | role | status | + | teacher1 | C1 | editingteacher | 0 | + | student1 | C1 | student | 0 | + | student2 | C1 | student | 1 | + And the following "activity" exists: + | activity | assign | + | course | C1 | + | name | Test assignment name | + + @javascript + Scenario: The suspended participants filter is available only when the teacher has the capability to view suspended participants + Given the following "permission overrides" exist: + | capability | permission | role | contextlevel | reference | + | moodle/course:viewsuspendedusers | Prevent | editingteacher | Course | C1 | + And I am on the "Test assignment name" Activity page logged in as teacher1 + And I navigate to "Submissions" in current page administration + When I change window size to "large" + # Ensure the Advanced filters component is not available. This validates that the Suspended participants filer is + # not available as well since it's part of this component. + Then "Advanced" "button" should not exist in the ".tertiary-navigation" "css_element" + And the following "permission overrides" exist: + | capability | permission | role | contextlevel | reference | + | moodle/course:viewsuspendedusers | Allow | editingteacher | Course | C1 | + And I reload the page + And "Advanced" "button" should exist in the ".tertiary-navigation" "css_element" + And I click on "Advanced" "button" in the ".tertiary-navigation" "css_element" + And "Include suspended participants" "checkbox" should exist in the ".extrafilters .dropdown-menu" "css_element" + And the field "Include suspended participants" matches value "" + + @javascript + Scenario: Teacher can include or exclude submissions from suspended participants + Given I am on the "Test assignment name" Activity page logged in as teacher1 + And I navigate to "Submissions" in current page administration + And I change window size to "large" + And the following should exist in the "submissions" table: + | -2- | + | Student 1 | + And the following should not exist in the "submissions" table: + | -2- | + | Student 2 | + # Set to include submissions from suspended participants. + And I click on "Advanced" "button" in the ".tertiary-navigation" "css_element" + When I click on "Include suspended participants" "checkbox" in the ".extrafilters .dropdown-menu" "css_element" + And I click on "Apply" "button" in the ".extrafilters .dropdown-menu" "css_element" + # Ensure that the suspended Student 2 is now also displayed in the submissions table. + Then the following should exist in the "submissions" table: + | -2- | + | Student 1 | + | Student 2 | + # Ensure the badge indicating the number of applied filters is present. + And ".badge" "css_element" should exist in the ".extrafilters .dropdown-toggle" "css_element" + And I should see "+1" in the ".extrafilters .badge" "css_element" + # Ensure the filter remains applied when navigating away from and returning to the assignment submissions page. + And I am on the "Test assignment name" Activity page + And I navigate to "Submissions" in current page administration + And the following should exist in the "submissions" table: + | -2- | + | Student 1 | + | Student 2 | + And I click on "Advanced" "button" in the ".tertiary-navigation" "css_element" + And the field "Include suspended participants" matches value "1" + # Ensure the filter is not applied unless the 'Apply' button is pressed. + And I click on "Include suspended participants" "checkbox" in the ".extrafilters .dropdown-menu" "css_element" + And the field "Include suspended participants" matches value "" + And I click on "Close" "link" in the ".extrafilters .dropdown-menu" "css_element" + And the following should exist in the "submissions" table: + | -2- | + | Student 1 | + | Student 2 | + And I click on "Advanced" "button" in the ".tertiary-navigation" "css_element" + And the field "Include suspended participants" matches value "1" + # Set to exclude submissions from suspended participants. + And I click on "Include suspended participants" "checkbox" in the ".extrafilters .dropdown-menu" "css_element" + And the field "Include suspended participants" matches value "" + And I click on "Apply" "button" in the ".extrafilters .dropdown-menu" "css_element" + # Ensure only Student 1 is now displayed in the submissions table. + And the following should exist in the "submissions" table: + | -2- | + | Student 1 | + And the following should not exist in the "submissions" table: + | -2- | + | Student 2 | From a97231fc067ab4a0d9b2e2860434398f48f5e9bf Mon Sep 17 00:00:00 2001 From: Mihail Geshoski Date: Tue, 13 Aug 2024 11:27:52 +0800 Subject: [PATCH 3/8] MDL-82681 mod_assign: Reset Marker and Suspended participants filters Extends the functionality of the 'Clear all' filters option to reset the new 'Marker' and 'Suspended participants' filters on the assignment submissions page. --- .../classes/output/grading_actionmenu.php | 2 + .../tests/behat/filter_by_marker.feature | 39 +++++++++++++++++++ .../behat/filter_by_marking_workflow.feature | 2 +- .../filter_suspended_participants.feature | 30 ++++++++++++++ 4 files changed, 72 insertions(+), 1 deletion(-) diff --git a/mod/assign/classes/output/grading_actionmenu.php b/mod/assign/classes/output/grading_actionmenu.php index b02af750ab9..da5e4d6e6f8 100644 --- a/mod/assign/classes/output/grading_actionmenu.php +++ b/mod/assign/classes/output/grading_actionmenu.php @@ -126,6 +126,8 @@ class grading_actionmenu implements templatable, renderable { 'group' => 0, 'status' => '', 'workflowfilter' => '', + 'markingallocationfilter' => '', + 'suspendedparticipantsfilter' => 0, ]); $data['pagereset'] = $url->out(false); } diff --git a/mod/assign/tests/behat/filter_by_marker.feature b/mod/assign/tests/behat/filter_by_marker.feature index 89926bfb224..8022cbd11b3 100644 --- a/mod/assign/tests/behat/filter_by_marker.feature +++ b/mod/assign/tests/behat/filter_by_marker.feature @@ -118,3 +118,42 @@ Feature: In an assignment, teachers can filter displayed submissions by assigned | -2- | | Student 1 | | Student 2 | + + @javascript + Scenario: The applied marker filter can be reset using the 'Clear all' option + Given I am on the "Test assignment name" "assign activity editing" page logged in as teacher1 + And I expand all fieldsets + And I set the field "Use marking workflow" to "Yes" + And I set the field "Use marking allocation" to "Yes" + And I press "Save and display" + And I am on the "Test assignment name" "assign activity" page + And I change window size to "large" + And I go to "Student 1" "Test assignment name" activity advanced grading page + # Allocate Marker 1 as the marker of Student 1. + And I set the field "allocatedmarker" to "Marker 1" + And I set the field "Notify student" to "0" + And I press "Save changes" + And I follow "View all submissions" + # Ensure the 'Clear all' option is not available until the marker filter has been applied. + And "Clear all" "link" should not exist in the ".tertiary-navigation" "css_element" + # Set the Marker filter to 'Marker 1'. + And I click on "Advanced" "button" in the ".tertiary-navigation" "css_element" + And I set the field "Marker" in the ".extrafilters .dropdown-menu" "css_element" to "Marker 1" + And I click on "Apply" "button" in the ".extrafilters .dropdown-menu" "css_element" + # Ensure only Student 1 is now displayed in the submissions table. + And the following should exist in the "submissions" table: + | -2- | + | Student 1 | + And the following should not exist in the "submissions" table: + | -2- | + | Student 2 | + # Ensure the 'Clear all' option is now available. + And "Clear all" "link" should exist in the ".tertiary-navigation" "css_element" + # Ensure the marker filter is reset when the 'Clear All' option is triggered. + When I click on "Clear all" "link" in the ".tertiary-navigation" "css_element" + Then the following should exist in the "submissions" table: + | -2- | + | Student 1 | + | Student 2 | + And I click on "Advanced" "button" in the ".tertiary-navigation" "css_element" + And the field "Marker" matches value "No filter" diff --git a/mod/assign/tests/behat/filter_by_marking_workflow.feature b/mod/assign/tests/behat/filter_by_marking_workflow.feature index ead8c521cd4..e9d1edcfaea 100644 --- a/mod/assign/tests/behat/filter_by_marking_workflow.feature +++ b/mod/assign/tests/behat/filter_by_marking_workflow.feature @@ -138,7 +138,7 @@ Feature: In an assignment, teachers can filter displayed submissions by marking And I set the field "Marking state" in the ".extrafilters .dropdown-menu" "css_element" to "In marking" And I click on "Apply" "button" in the ".extrafilters .dropdown-menu" "css_element" # Ensure only Student 2 is now displayed in the submissions table. - Then the following should exist in the "submissions" table: + And the following should exist in the "submissions" table: | -2- | | Student 2 | And the following should not exist in the "submissions" table: diff --git a/mod/assign/tests/behat/filter_suspended_participants.feature b/mod/assign/tests/behat/filter_suspended_participants.feature index 6ae2128d307..a74be5a4e02 100644 --- a/mod/assign/tests/behat/filter_suspended_participants.feature +++ b/mod/assign/tests/behat/filter_suspended_participants.feature @@ -96,3 +96,33 @@ Feature: In an assignment, teachers can include or exclude submissions from susp And the following should not exist in the "submissions" table: | -2- | | Student 2 | + + @javascript + Scenario: The applied suspended participants filter can be reset using the 'Clear all' option + Given I am on the "Test assignment name" Activity page logged in as teacher1 + And I navigate to "Submissions" in current page administration + And I change window size to "large" + # Ensure the 'Clear all' option is not available until the suspended participants filter has been applied. + And "Clear all" "link" should not exist in the ".tertiary-navigation" "css_element" + # Set to include submissions from suspended participants. + And I click on "Advanced" "button" in the ".tertiary-navigation" "css_element" + And I click on "Include suspended participants" "checkbox" in the ".extrafilters .dropdown-menu" "css_element" + And the field "Include suspended participants" matches value "1" + And I click on "Apply" "button" in the ".extrafilters .dropdown-menu" "css_element" + # Ensure that the suspended Student 2 is now also displayed in the submissions table. + And the following should exist in the "submissions" table: + | -2- | + | Student 1 | + | Student 2 | + # Ensure the 'Clear all' option is now available. + And "Clear all" "link" should exist in the ".tertiary-navigation" "css_element" + # Ensure the marker filter is reset when the 'Clear All' option is triggered. + When I click on "Clear all" "link" in the ".tertiary-navigation" "css_element" + Then the following should exist in the "submissions" table: + | -2- | + | Student 1 | + And the following should not exist in the "submissions" table: + | -2- | + | Student 2 | + And I click on "Advanced" "button" in the ".tertiary-navigation" "css_element" + And the field "Include suspended participants" matches value "" From ca293159e7090f5eaf65bcf9f1076cace1b09506 Mon Sep 17 00:00:00 2001 From: Mihail Geshoski Date: Tue, 13 Aug 2024 10:49:20 +0800 Subject: [PATCH 4/8] MDL-82681 mod_assign: Clean up old filters Removes the old Marker and Suspended participants filters from the assignment submissions page, along with all associated logic. Also, cleans up residual code from the old marking workflow filter that was not properly removed in MDL-82508. --- .../form/grading_options_temp_form.php | 11 ---- mod/assign/locallib.php | 59 ------------------- mod/assign/module.js | 12 ---- 3 files changed, 82 deletions(-) diff --git a/mod/assign/classes/form/grading_options_temp_form.php b/mod/assign/classes/form/grading_options_temp_form.php index e5f6ee2fdee..26d8063c826 100644 --- a/mod/assign/classes/form/grading_options_temp_form.php +++ b/mod/assign/classes/form/grading_options_temp_form.php @@ -51,17 +51,6 @@ class grading_options_temp_form extends \moodleform { $mform->disable_form_change_checker(); $mform->addElement('header', 'general', get_string('gradingoptions', 'assign')); - if (!empty($instance['markingallocationopt'])) { - $markingfilter = get_string('markerfilter', 'assign'); - $mform->addElement('select', 'markerfilter', $markingfilter, $instance['markingallocationopt']); - } - - // Show active/suspended user option. - if ($instance['showonlyactiveenrolopt']) { - $mform->addElement('checkbox', 'showonlyactiveenrol', get_string('showonlyactiveenrol', 'grades')); - $mform->addHelpButton('showonlyactiveenrol', 'showonlyactiveenrol', 'grades'); - $mform->setDefault('showonlyactiveenrol', $instance['showonlyactiveenrol']); - } // Hidden params. $mform->addElement('hidden', 'contextid', $instance['contextid']); diff --git a/mod/assign/locallib.php b/mod/assign/locallib.php index ca00b74d9a6..75b68c53607 100644 --- a/mod/assign/locallib.php +++ b/mod/assign/locallib.php @@ -4515,7 +4515,6 @@ class assign { $perpage = $this->get_assign_perpage(); $filter = get_user_preferences('assign_filter', ''); - $markerfilter = get_user_preferences('assign_markerfilter', ''); // Retrieve the 'workflowfilter' parameter, or set it to null if not provided. $workflowfilter = optional_param('workflowfilter', null, PARAM_ALPHA); @@ -4545,38 +4544,18 @@ class assign { $controller = $gradingmanager->get_active_controller(); $showquickgrading = empty($controller) && $this->can_grade(); $quickgrading = get_user_preferences('assign_quickgrading', false); - $showonlyactiveenrolopt = has_capability('moodle/course:viewsuspendedusers', $this->context); $markingallocation = $this->get_instance()->markingworkflow && $this->get_instance()->markingallocation && has_capability('mod/assign:manageallocations', $this->context); - // Get markers to use in drop lists. - $markingallocationoptions = array(); - if ($markingallocation) { - list($sort, $params) = users_order_by_sql('u'); - // Only enrolled users could be assigned as potential markers. - $markers = get_enrolled_users($this->context, 'mod/assign:grade', 0, 'u.*', $sort); - $markingallocationoptions[''] = get_string('filternone', 'assign'); - $markingallocationoptions[ASSIGN_MARKER_FILTER_NO_MARKER] = get_string('markerfilternomarker', 'assign'); - $viewfullnames = has_capability('moodle/site:viewfullnames', $this->context); - foreach ($markers as $marker) { - $markingallocationoptions[$marker->id] = fullname($marker, $viewfullnames); - } - } $markingworkflow = $this->get_instance()->markingworkflow; - // Get marking states to show in form. - $markingworkflowoptions = $this->get_marking_workflow_filters(); // Print options for changing the filter and changing the number of results per page. $gradingoptionsformparams = [ 'cm' => $cmid, 'contextid' => $this->context->id, 'userid' => $USER->id, - 'markingworkflowopt' => $markingworkflowoptions, - 'markingallocationopt' => $markingallocationoptions, - 'showonlyactiveenrolopt' => $showonlyactiveenrolopt, - 'showonlyactiveenrol' => $this->show_only_active_users(), ]; $classoptions = array('class'=>'gradingoptionsform'); @@ -4587,7 +4566,6 @@ class assign { $classoptions); $gradingoptionsdata = new stdClass(); - $gradingoptionsdata->markerfilter = $markerfilter; $gradingoptionsform->set_data($gradingoptionsdata); $buttons = new \mod_assign\output\grading_actionmenu(cmid: $this->get_course_module()->id, assign: $this); @@ -7404,50 +7382,13 @@ class assign { $this->require_view_grades(); require_sesskey(); - if (!is_null($this->context)) { - $showonlyactiveenrolopt = has_capability('moodle/course:viewsuspendedusers', $this->context); - } else { - $showonlyactiveenrolopt = false; - } - - $markingallocation = $this->get_instance()->markingworkflow && - $this->get_instance()->markingallocation && - has_capability('mod/assign:manageallocations', $this->context); - // Get markers to use in drop lists. - $markingallocationoptions = array(); - if ($markingallocation) { - $markingallocationoptions[''] = get_string('filternone', 'assign'); - $markingallocationoptions[ASSIGN_MARKER_FILTER_NO_MARKER] = get_string('markerfilternomarker', 'assign'); - list($sort, $params) = users_order_by_sql('u'); - // Only enrolled users could be assigned as potential markers. - $markers = get_enrolled_users($this->context, 'mod/assign:grade', 0, 'u.*', $sort); - foreach ($markers as $marker) { - $markingallocationoptions[$marker->id] = fullname($marker); - } - } - - // Get marking states to show in form. - $markingworkflowoptions = $this->get_marking_workflow_filters(); - $gradingoptionsparams = [ 'cm' => $this->get_course_module()->id, 'contextid' => $this->context->id, 'userid' => $USER->id, - 'markingworkflowopt' => $markingworkflowoptions, - 'markingallocationopt' => $markingallocationoptions, - 'showonlyactiveenrolopt' => $showonlyactiveenrolopt, - 'showonlyactiveenrol' => $this->show_only_active_users(), ]; $mform = new mod_assign\form\grading_options_temp_form(null, $gradingoptionsparams); if ($formdata = $mform->get_data()) { - if (isset($formdata->markerfilter)) { - set_user_preference('assign_markerfilter', $formdata->markerfilter); - } - if (!empty($showonlyactiveenrolopt)) { - $showonlyactiveenrol = isset($formdata->showonlyactiveenrol); - set_user_preference('grade_report_showonlyactiveenrol', $showonlyactiveenrol); - $this->showonlyactiveenrol = $showonlyactiveenrol; - } } } diff --git a/mod/assign/module.js b/mod/assign/module.js index 18e601b10ce..0198fd10df0 100644 --- a/mod/assign/module.js +++ b/mod/assign/module.js @@ -80,18 +80,6 @@ M.mod_assign.init_grading_table = function(Y) { M.mod_assign.init_grading_options = function(Y) { Y.use('node', function(Y) { - var markerfilterelement = Y.one('#id_markerfilter'); - if (markerfilterelement) { - markerfilterelement.on('change', function(e) { - Y.one('form.gradingoptionsform').submit(); - }); - } - var showonlyactiveenrolelement = Y.one('#id_showonlyactiveenrol'); - if (showonlyactiveenrolelement) { - showonlyactiveenrolelement.on('change', function(e) { - Y.one('form.gradingoptionsform').submit(); - }); - } var downloadasfolderselement = Y.one('#id_downloadasfolders'); if (downloadasfolderselement) { downloadasfolderselement.on('change', function(e) { From 15fc229e77f1443dfd7c4d28d1d43137a93c819f Mon Sep 17 00:00:00 2001 From: Mihail Geshoski Date: Mon, 16 Sep 2024 17:51:19 +0800 Subject: [PATCH 5/8] MDL-82681 mod_assign: Revert improper code removal The grading_options_form class was deprecated in 4.5, and a temporary copy of this class was introduced to facilitate the migration of its elements across different areas of the submission page, ensuring no breakages if any external code is using this form (MDL-82857). However, the process_save_grading_options() method, which processes data from this form, was modified and this should not have occurred. To maintain proper backward compatibility, a similar approach should be taken by introducing a temporary copy of the method. Both the temporary method and temporary form class should be removed once the migration of elements is complete. --- .../form/grading_options_temp_form.php | 2 +- mod/assign/locallib.php | 89 +++++++++++++++++++ mod/assign/module.js | 36 +++++++- 3 files changed, 125 insertions(+), 2 deletions(-) diff --git a/mod/assign/classes/form/grading_options_temp_form.php b/mod/assign/classes/form/grading_options_temp_form.php index 26d8063c826..1573d7ff6af 100644 --- a/mod/assign/classes/form/grading_options_temp_form.php +++ b/mod/assign/classes/form/grading_options_temp_form.php @@ -59,7 +59,7 @@ class grading_options_temp_form extends \moodleform { $mform->setType('id', PARAM_INT); $mform->addElement('hidden', 'userid', $instance['userid']); $mform->setType('userid', PARAM_INT); - $mform->addElement('hidden', 'action', 'saveoptions'); + $mform->addElement('hidden', 'action', 'saveoptionstemp'); $mform->setType('action', PARAM_ALPHA); // Buttons. diff --git a/mod/assign/locallib.php b/mod/assign/locallib.php index 75b68c53607..795df233f34 100644 --- a/mod/assign/locallib.php +++ b/mod/assign/locallib.php @@ -638,6 +638,10 @@ class assign { $this->process_save_grading_options(); $action = 'redirect'; $nextpageparams['action'] = 'grading'; + } else if ($action == 'saveoptionstemp') { + $this->process_save_grading_options_temp(); + $action = 'redirect'; + $nextpageparams['action'] = 'grading'; } else if ($action == 'saveextension') { $action = 'grantextension'; if ($this->process_save_extension($mform)) { @@ -7382,6 +7386,91 @@ class assign { $this->require_view_grades(); require_sesskey(); + // Is advanced grading enabled? + $gradingmanager = get_grading_manager($this->get_context(), 'mod_assign', 'submissions'); + $controller = $gradingmanager->get_active_controller(); + $showquickgrading = empty($controller); + if (!is_null($this->context)) { + $showonlyactiveenrolopt = has_capability('moodle/course:viewsuspendedusers', $this->context); + } else { + $showonlyactiveenrolopt = false; + } + + $markingallocation = $this->get_instance()->markingworkflow && + $this->get_instance()->markingallocation && + has_capability('mod/assign:manageallocations', $this->context); + // Get markers to use in drop lists. + $markingallocationoptions = array(); + if ($markingallocation) { + $markingallocationoptions[''] = get_string('filternone', 'assign'); + $markingallocationoptions[ASSIGN_MARKER_FILTER_NO_MARKER] = get_string('markerfilternomarker', 'assign'); + list($sort, $params) = users_order_by_sql('u'); + // Only enrolled users could be assigned as potential markers. + $markers = get_enrolled_users($this->context, 'mod/assign:grade', 0, 'u.*', $sort); + foreach ($markers as $marker) { + $markingallocationoptions[$marker->id] = fullname($marker); + } + } + + // Get marking states to show in form. + $markingworkflowoptions = $this->get_marking_workflow_filters(); + + $gradingoptionsparams = [ + 'cm' => $this->get_course_module()->id, + 'contextid' => $this->context->id, + 'userid' => $USER->id, + 'submissionsenabled' => $this->is_any_submission_plugin_enabled(), + 'showquickgrading' => $showquickgrading, + 'quickgrading' => false, + 'markingworkflowopt' => $markingworkflowoptions, + 'markingallocationopt' => $markingallocationoptions, + 'showonlyactiveenrolopt' => $showonlyactiveenrolopt, + 'showonlyactiveenrol' => $this->show_only_active_users(), + 'downloadasfolders' => get_user_preferences('assign_downloadasfolders', 1) + ]; + $mform = new mod_assign_grading_options_form(null, $gradingoptionsparams); + if ($formdata = $mform->get_data()) { + set_user_preference('assign_perpage', $formdata->perpage); + if (isset($formdata->filter)) { + set_user_preference('assign_filter', $formdata->filter); + } + if (isset($formdata->markerfilter)) { + set_user_preference('assign_markerfilter', $formdata->markerfilter); + } + if (isset($formdata->workflowfilter)) { + set_user_preference('assign_workflowfilter', $formdata->workflowfilter); + } + if ($showquickgrading) { + set_user_preference('assign_quickgrading', isset($formdata->quickgrading)); + } + if (isset($formdata->downloadasfolders)) { + set_user_preference('assign_downloadasfolders', 1); // Enabled. + } else { + set_user_preference('assign_downloadasfolders', 0); // Disabled. + } + if (!empty($showonlyactiveenrolopt)) { + $showonlyactiveenrol = isset($formdata->showonlyactiveenrol); + set_user_preference('grade_report_showonlyactiveenrol', $showonlyactiveenrol); + $this->showonlyactiveenrol = $showonlyactiveenrol; + } + } + } + + /** + * Save grading options. + * + * @return void + */ + protected function process_save_grading_options_temp() { + global $USER, $CFG; + + // Include grading options form. + require_once($CFG->dirroot . '/mod/assign/gradingoptionsform.php'); + + // Need submit permission to submit an assignment. + $this->require_view_grades(); + require_sesskey(); + $gradingoptionsparams = [ 'cm' => $this->get_course_module()->id, 'contextid' => $this->context->id, diff --git a/mod/assign/module.js b/mod/assign/module.js index 0198fd10df0..ed19eab52a2 100644 --- a/mod/assign/module.js +++ b/mod/assign/module.js @@ -80,9 +80,43 @@ M.mod_assign.init_grading_table = function(Y) { M.mod_assign.init_grading_options = function(Y) { Y.use('node', function(Y) { + var paginationelement = Y.one('#id_perpage'); + paginationelement.on('change', function() { + Y.one('form.gradingoptionsform').submit(); + }); + var filterelement = Y.one('#id_filter'); + if (filterelement) { + filterelement.on('change', function() { + Y.one('form.gradingoptionsform').submit(); + }); + } + var markerfilterelement = Y.one('#id_markerfilter'); + if (markerfilterelement) { + markerfilterelement.on('change', function() { + Y.one('form.gradingoptionsform').submit(); + }); + } + var workflowfilterelement = Y.one('#id_workflowfilter'); + if (workflowfilterelement) { + workflowfilterelement.on('change', function() { + Y.one('form.gradingoptionsform').submit(); + }); + } + var quickgradingelement = Y.one('#id_quickgrading'); + if (quickgradingelement) { + quickgradingelement.on('change', function() { + Y.one('form.gradingoptionsform').submit(); + }); + } + var showonlyactiveenrolelement = Y.one('#id_showonlyactiveenrol'); + if (showonlyactiveenrolelement) { + showonlyactiveenrolelement.on('change', function() { + Y.one('form.gradingoptionsform').submit(); + }); + } var downloadasfolderselement = Y.one('#id_downloadasfolders'); if (downloadasfolderselement) { - downloadasfolderselement.on('change', function(e) { + downloadasfolderselement.on('change', function() { Y.one('form.gradingoptionsform').submit(); }); } From f86a9fd520c0bd83926aa50d76559c845c6627aa Mon Sep 17 00:00:00 2001 From: Mihail Geshoski Date: Mon, 16 Sep 2024 18:17:36 +0800 Subject: [PATCH 6/8] MDL-82681 mod_assign: Remove temporary class grading_options_temp_form The grading_options_temp_form class and process_save_grading_options_temp() method were temporarily introduced to migrate form elements across the submission page while preserving the original class and method, as they are part of the public API and may be used by external code. Now that the migration is complete, both the temporary class and method can be removed. --- .../form/grading_options_temp_form.php | 69 ------------------- mod/assign/locallib.php | 51 -------------- 2 files changed, 120 deletions(-) delete mode 100644 mod/assign/classes/form/grading_options_temp_form.php diff --git a/mod/assign/classes/form/grading_options_temp_form.php b/mod/assign/classes/form/grading_options_temp_form.php deleted file mode 100644 index 1573d7ff6af..00000000000 --- a/mod/assign/classes/form/grading_options_temp_form.php +++ /dev/null @@ -1,69 +0,0 @@ -. - -/** - * This file contains the temporary form used on the submissions page to apply assignment grading options. - * - * @package mod_assign - * @copyright 2024 Mihail Geshoski - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace mod_assign\form; - -defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); - -require_once($CFG->libdir.'/formslib.php'); -require_once($CFG->dirroot . '/mod/assign/locallib.php'); - -/** - * Assignment grading options temporary form. - * - * This form class is a copy of mod_assign_grading_options_form. The only purpose of this form is to be temporarily used - * on the submission page until the gradual removal of the current form elements is completed. After that, this form - * class will be removed. - * - * @package mod_assign - * @copyright 2024 Mihail Geshoski - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class grading_options_temp_form extends \moodleform { - /** - * Define this form - called from the parent constructor. - */ - public function definition() { - $mform = $this->_form; - $instance = $this->_customdata; - - $mform->disable_form_change_checker(); - - $mform->addElement('header', 'general', get_string('gradingoptions', 'assign')); - - // Hidden params. - $mform->addElement('hidden', 'contextid', $instance['contextid']); - $mform->setType('contextid', PARAM_INT); - $mform->addElement('hidden', 'id', $instance['cm']); - $mform->setType('id', PARAM_INT); - $mform->addElement('hidden', 'userid', $instance['userid']); - $mform->setType('userid', PARAM_INT); - $mform->addElement('hidden', 'action', 'saveoptionstemp'); - $mform->setType('action', PARAM_ALPHA); - - // Buttons. - $this->add_action_buttons(false, get_string('updatetable', 'assign')); - } -} - diff --git a/mod/assign/locallib.php b/mod/assign/locallib.php index 795df233f34..40e2671a2d6 100644 --- a/mod/assign/locallib.php +++ b/mod/assign/locallib.php @@ -638,10 +638,6 @@ class assign { $this->process_save_grading_options(); $action = 'redirect'; $nextpageparams['action'] = 'grading'; - } else if ($action == 'saveoptionstemp') { - $this->process_save_grading_options_temp(); - $action = 'redirect'; - $nextpageparams['action'] = 'grading'; } else if ($action == 'saveextension') { $action = 'grantextension'; if ($this->process_save_extension($mform)) { @@ -4555,23 +4551,6 @@ class assign { $markingworkflow = $this->get_instance()->markingworkflow; - // Print options for changing the filter and changing the number of results per page. - $gradingoptionsformparams = [ - 'cm' => $cmid, - 'contextid' => $this->context->id, - 'userid' => $USER->id, - ]; - - $classoptions = array('class'=>'gradingoptionsform'); - $gradingoptionsform = new \mod_assign\form\grading_options_temp_form(null, - $gradingoptionsformparams, - 'post', - '', - $classoptions); - - $gradingoptionsdata = new stdClass(); - $gradingoptionsform->set_data($gradingoptionsdata); - $buttons = new \mod_assign\output\grading_actionmenu(cmid: $this->get_course_module()->id, assign: $this); $actionformtext = $this->get_renderer()->render($buttons); $currenturl = new moodle_url('/mod/assign/view.php', ['id' => $this->get_course_module()->id, 'action' => 'grading']); @@ -4638,11 +4617,6 @@ class assign { $SESSION->mod_assign_useridlist[$this->get_useridlist_key()] = $useridlist; } - $assignform = new assign_form('gradingoptionsform', - $gradingoptionsform, - 'M.mod_assign.init_grading_options'); - $o .= $this->get_renderer()->render($assignform); - $currentgroup = groups_get_activity_group($this->get_course_module(), true); $users = array_keys($this->list_participants($currentgroup, true)); if (count($users) != 0 && $this->can_grade()) { @@ -7456,31 +7430,6 @@ class assign { } } - /** - * Save grading options. - * - * @return void - */ - protected function process_save_grading_options_temp() { - global $USER, $CFG; - - // Include grading options form. - require_once($CFG->dirroot . '/mod/assign/gradingoptionsform.php'); - - // Need submit permission to submit an assignment. - $this->require_view_grades(); - require_sesskey(); - - $gradingoptionsparams = [ - 'cm' => $this->get_course_module()->id, - 'contextid' => $this->context->id, - 'userid' => $USER->id, - ]; - $mform = new mod_assign\form\grading_options_temp_form(null, $gradingoptionsparams); - if ($formdata = $mform->get_data()) { - } - } - /** * @deprecated since 2.7 */ From 8f3ca13260de9b984ff0be0fe2f8ee01a09a8362 Mon Sep 17 00:00:00 2001 From: Mihail Geshoski Date: Thu, 19 Sep 2024 22:33:21 +0800 Subject: [PATCH 7/8] MDL-82681 mod_assign: Modify mod_assign_grading_options_form deprecation This form class has been deprecated in MDL-82857, following the standard class deprecation policy. It is highly unlikely that any external code is using it; therefore, the form class has been removed, while the file remains to prevent fatal errors from attempts to require or include it. This approachy aligns with recent form deprecations in the quiz module. Additionally, any code using this form and its supporting functions, such as M.mod_assign.init_grading_options, has been removed. --- mod/assign/gradingoptionsform.php | 111 ++---------------------------- mod/assign/lang/en/assign.php | 2 +- mod/assign/lang/en/deprecated.txt | 1 + mod/assign/locallib.php | 83 ---------------------- mod/assign/module.js | 45 ------------ mod/assign/styles.css | 4 -- 6 files changed, 6 insertions(+), 240 deletions(-) diff --git a/mod/assign/gradingoptionsform.php b/mod/assign/gradingoptionsform.php index 0699d16f4c5..cb541f9698f 100644 --- a/mod/assign/gradingoptionsform.php +++ b/mod/assign/gradingoptionsform.php @@ -15,115 +15,12 @@ // along with Moodle. If not, see . /** - * This file contains the forms to create and edit an instance of this module + * File only retained to prevent fatal errors in code that tries to require/include this. * - * @package mod_assign - * @copyright 2012 NetSpot {@link http://www.netspot.com.au} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @deprecated since 4.5. This file is no longer required. + * @todo This file should be removed in Moodle 6.0. See MDL-82876. */ defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.'); - -require_once($CFG->libdir.'/formslib.php'); -require_once($CFG->dirroot . '/mod/assign/locallib.php'); - -/** - * Assignment grading options form - * - * @deprecated since 4.5 - * @package mod_assign - * @copyright 2012 NetSpot {@link http://www.netspot.com.au} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -#[\core\attribute\deprecated( - replacement: null, - since: '4.5', - reason: 'It is no longer used.', - mdl: 'MDL-82857', -)] -class mod_assign_grading_options_form extends moodleform { - /** - * Define this form - called from the parent constructor. - * - * @deprecated since 4.5 - */ - #[\core\attribute\deprecated( - replacement: null, - since: '4.5', - reason: 'It is no longer used.', - mdl: 'MDL-82857', - )] - public function definition() { - \core\deprecation::emit_deprecation_if_present(__FUNCTION__); - $mform = $this->_form; - $instance = $this->_customdata; - - $mform->disable_form_change_checker(); - - $mform->addElement('header', 'general', get_string('gradingoptions', 'assign')); - // Visible elements. - $options = array(10 => '10', 20 => '20', 50 => '50', 100 => '100', -1 => get_string('all')); - $maxperpage = get_config('assign', 'maxperpage'); - if (isset($maxperpage) && $maxperpage != -1) { - unset($options[-1]); - foreach ($options as $val) { - if ($val > $maxperpage) { - unset($options[$val]); - } - } - } - $mform->addElement('select', 'perpage', get_string('assignmentsperpage', 'assign'), $options); - $options = array('' => get_string('filternone', 'assign'), - ASSIGN_FILTER_NOT_SUBMITTED => get_string('filternotsubmitted', 'assign'), - ASSIGN_FILTER_DRAFT => get_string('filterdraft', 'assign'), - ASSIGN_FILTER_SUBMITTED => get_string('filtersubmitted', 'assign'), - ASSIGN_FILTER_REQUIRE_GRADING => get_string('filterrequiregrading', 'assign'), - ASSIGN_FILTER_GRANTED_EXTENSION => get_string('filtergrantedextension', 'assign')); - if ($instance['submissionsenabled']) { - $mform->addElement('select', 'filter', get_string('filter', 'assign'), $options); - } - if (!empty($instance['markingallocationopt'])) { - $markingfilter = get_string('markerfilter', 'assign'); - $mform->addElement('select', 'markerfilter', $markingfilter, $instance['markingallocationopt']); - } - if (!empty($instance['markingworkflowopt'])) { - $workflowfilter = get_string('workflowfilter', 'assign'); - $mform->addElement('select', 'workflowfilter', $workflowfilter, $instance['markingworkflowopt']); - } - // Quickgrading. - if ($instance['showquickgrading']) { - $mform->addElement('checkbox', 'quickgrading', get_string('quickgrading', 'assign')); - $mform->addHelpButton('quickgrading', 'quickgrading', 'assign'); - $mform->setDefault('quickgrading', $instance['quickgrading']); - } - - // Show active/suspended user option. - if ($instance['showonlyactiveenrolopt']) { - $mform->addElement('checkbox', 'showonlyactiveenrol', get_string('showonlyactiveenrol', 'grades')); - $mform->addHelpButton('showonlyactiveenrol', 'showonlyactiveenrol', 'grades'); - $mform->setDefault('showonlyactiveenrol', $instance['showonlyactiveenrol']); - } - - // Place student downloads in seperate folders. - if ($instance['submissionsenabled']) { - $mform->addElement('checkbox', 'downloadasfolders', get_string('downloadasfolders', 'assign')); - $mform->addHelpButton('downloadasfolders', 'downloadasfolders', 'assign'); - $mform->setDefault('downloadasfolders', $instance['downloadasfolders']); - } - - // Hidden params. - $mform->addElement('hidden', 'contextid', $instance['contextid']); - $mform->setType('contextid', PARAM_INT); - $mform->addElement('hidden', 'id', $instance['cm']); - $mform->setType('id', PARAM_INT); - $mform->addElement('hidden', 'userid', $instance['userid']); - $mform->setType('userid', PARAM_INT); - $mform->addElement('hidden', 'action', 'saveoptions'); - $mform->setType('action', PARAM_ALPHA); - - // Buttons. - $this->add_action_buttons(false, get_string('updatetable', 'assign')); - } -} - +debugging('This file is no longer required in Moodle 4.5+. Please do not include/require it.', DEBUG_DEVELOPER); diff --git a/mod/assign/lang/en/assign.php b/mod/assign/lang/en/assign.php index 9cf48536afa..81844b4d146 100644 --- a/mod/assign/lang/en/assign.php +++ b/mod/assign/lang/en/assign.php @@ -331,7 +331,6 @@ $string['gradingdueduedatevalidation'] = 'Remind me to grade by date cannot be e $string['gradingduefromdatevalidation'] = 'Remind me to grade by date cannot be earlier than the allow submissions from date.'; $string['gradechangessaveddetail'] = 'The changes to the grade and feedback were saved'; $string['gradingmethodpreview'] = 'Grading criteria'; -$string['gradingoptions'] = 'Options'; $string['gradingstatus'] = 'Grading status'; $string['gradingstudent'] = 'Grading student'; $string['gradingsummary'] = 'Grading summary'; @@ -709,6 +708,7 @@ $string['attemptreopenmethod_none'] = 'Never'; $string['choosegradingaction'] = 'Grading action'; $string['downloadasfolders_help'] = 'Assignment submissions may be downloaded in folders. Each submission is then put in a separate folder, with the folder structure kept for any subfolders, and files are not renamed.'; $string['editaction'] = 'Actions...'; +$string['gradingoptions'] = 'Options'; $string['groupoverridesdeleted'] = 'Group overrides deleted'; $string['saveallquickgradingchanges'] = 'Save all quick grading changes'; $string['updategrade'] = 'Update grade'; diff --git a/mod/assign/lang/en/deprecated.txt b/mod/assign/lang/en/deprecated.txt index 1a8c51e3756..0eea43306c2 100644 --- a/mod/assign/lang/en/deprecated.txt +++ b/mod/assign/lang/en/deprecated.txt @@ -7,3 +7,4 @@ viewgrader,mod_assign downloadasfolders_help,mod_assign editaction,mod_assign saveallquickgradingchanges,mod_assign +gradingoptions,mod_assign diff --git a/mod/assign/locallib.php b/mod/assign/locallib.php index 40e2671a2d6..a7cd878c56b 100644 --- a/mod/assign/locallib.php +++ b/mod/assign/locallib.php @@ -634,10 +634,6 @@ class assign { } else if ($action == 'quickgrade') { $message = $this->process_save_quick_grades(); $action = 'quickgradingresult'; - } else if ($action == 'saveoptions') { - $this->process_save_grading_options(); - $action = 'redirect'; - $nextpageparams['action'] = 'grading'; } else if ($action == 'saveextension') { $action = 'grantextension'; if ($this->process_save_extension($mform)) { @@ -4480,8 +4476,6 @@ class assign { protected function view_grading_table() { global $USER, $CFG, $SESSION, $PAGE, $OUTPUT; - // Include grading options form. - require_once($CFG->dirroot . '/mod/assign/gradingoptionsform.php'); require_once($CFG->dirroot . '/mod/assign/quickgradingform.php'); $submittedfilter = optional_param('status', null, PARAM_ALPHA); @@ -7351,83 +7345,6 @@ class assign { * @return void */ protected function process_save_grading_options() { - global $USER, $CFG; - - // Include grading options form. - require_once($CFG->dirroot . '/mod/assign/gradingoptionsform.php'); - - // Need submit permission to submit an assignment. - $this->require_view_grades(); - require_sesskey(); - - // Is advanced grading enabled? - $gradingmanager = get_grading_manager($this->get_context(), 'mod_assign', 'submissions'); - $controller = $gradingmanager->get_active_controller(); - $showquickgrading = empty($controller); - if (!is_null($this->context)) { - $showonlyactiveenrolopt = has_capability('moodle/course:viewsuspendedusers', $this->context); - } else { - $showonlyactiveenrolopt = false; - } - - $markingallocation = $this->get_instance()->markingworkflow && - $this->get_instance()->markingallocation && - has_capability('mod/assign:manageallocations', $this->context); - // Get markers to use in drop lists. - $markingallocationoptions = array(); - if ($markingallocation) { - $markingallocationoptions[''] = get_string('filternone', 'assign'); - $markingallocationoptions[ASSIGN_MARKER_FILTER_NO_MARKER] = get_string('markerfilternomarker', 'assign'); - list($sort, $params) = users_order_by_sql('u'); - // Only enrolled users could be assigned as potential markers. - $markers = get_enrolled_users($this->context, 'mod/assign:grade', 0, 'u.*', $sort); - foreach ($markers as $marker) { - $markingallocationoptions[$marker->id] = fullname($marker); - } - } - - // Get marking states to show in form. - $markingworkflowoptions = $this->get_marking_workflow_filters(); - - $gradingoptionsparams = [ - 'cm' => $this->get_course_module()->id, - 'contextid' => $this->context->id, - 'userid' => $USER->id, - 'submissionsenabled' => $this->is_any_submission_plugin_enabled(), - 'showquickgrading' => $showquickgrading, - 'quickgrading' => false, - 'markingworkflowopt' => $markingworkflowoptions, - 'markingallocationopt' => $markingallocationoptions, - 'showonlyactiveenrolopt' => $showonlyactiveenrolopt, - 'showonlyactiveenrol' => $this->show_only_active_users(), - 'downloadasfolders' => get_user_preferences('assign_downloadasfolders', 1) - ]; - $mform = new mod_assign_grading_options_form(null, $gradingoptionsparams); - if ($formdata = $mform->get_data()) { - set_user_preference('assign_perpage', $formdata->perpage); - if (isset($formdata->filter)) { - set_user_preference('assign_filter', $formdata->filter); - } - if (isset($formdata->markerfilter)) { - set_user_preference('assign_markerfilter', $formdata->markerfilter); - } - if (isset($formdata->workflowfilter)) { - set_user_preference('assign_workflowfilter', $formdata->workflowfilter); - } - if ($showquickgrading) { - set_user_preference('assign_quickgrading', isset($formdata->quickgrading)); - } - if (isset($formdata->downloadasfolders)) { - set_user_preference('assign_downloadasfolders', 1); // Enabled. - } else { - set_user_preference('assign_downloadasfolders', 0); // Disabled. - } - if (!empty($showonlyactiveenrolopt)) { - $showonlyactiveenrol = isset($formdata->showonlyactiveenrol); - set_user_preference('grade_report_showonlyactiveenrol', $showonlyactiveenrol); - $this->showonlyactiveenrol = $showonlyactiveenrol; - } - } } /** diff --git a/mod/assign/module.js b/mod/assign/module.js index ed19eab52a2..771eb65908d 100644 --- a/mod/assign/module.js +++ b/mod/assign/module.js @@ -78,51 +78,6 @@ M.mod_assign.init_grading_table = function(Y) { }); }; -M.mod_assign.init_grading_options = function(Y) { - Y.use('node', function(Y) { - var paginationelement = Y.one('#id_perpage'); - paginationelement.on('change', function() { - Y.one('form.gradingoptionsform').submit(); - }); - var filterelement = Y.one('#id_filter'); - if (filterelement) { - filterelement.on('change', function() { - Y.one('form.gradingoptionsform').submit(); - }); - } - var markerfilterelement = Y.one('#id_markerfilter'); - if (markerfilterelement) { - markerfilterelement.on('change', function() { - Y.one('form.gradingoptionsform').submit(); - }); - } - var workflowfilterelement = Y.one('#id_workflowfilter'); - if (workflowfilterelement) { - workflowfilterelement.on('change', function() { - Y.one('form.gradingoptionsform').submit(); - }); - } - var quickgradingelement = Y.one('#id_quickgrading'); - if (quickgradingelement) { - quickgradingelement.on('change', function() { - Y.one('form.gradingoptionsform').submit(); - }); - } - var showonlyactiveenrolelement = Y.one('#id_showonlyactiveenrol'); - if (showonlyactiveenrolelement) { - showonlyactiveenrolelement.on('change', function() { - Y.one('form.gradingoptionsform').submit(); - }); - } - var downloadasfolderselement = Y.one('#id_downloadasfolders'); - if (downloadasfolderselement) { - downloadasfolderselement.on('change', function() { - Y.one('form.gradingoptionsform').submit(); - }); - } - }); -}; - M.mod_assign.init_plugin_summary = function(Y, subtype, type, submissionid) { var suffix = subtype + '_' + type + '_' + submissionid; var classname = 'contract_' + suffix; diff --git a/mod/assign/styles.css b/mod/assign/styles.css index fe257d123ef..176e9ea8a45 100644 --- a/mod/assign/styles.css +++ b/mod/assign/styles.css @@ -43,10 +43,6 @@ font-weight: 900; } -.path-mod-assign.jsenabled .gradingoptionsform [type=submit] { - display: none; -} - .path-mod-assign.jsenabled .gradingtable .c1 select { display: none; } From 2c2e9982d6c2060eec14350a62dcaa9d0fbb89c3 Mon Sep 17 00:00:00 2001 From: Mihail Geshoski Date: Thu, 19 Sep 2024 22:55:03 +0800 Subject: [PATCH 8/8] MDL-82681 mod_assign: Deprecate process_save_grading_options() --- .upgradenotes/MDL-82681-2024091902542827.yml | 7 +++++++ mod/assign/locallib.php | 9 +++++++++ 2 files changed, 16 insertions(+) create mode 100644 .upgradenotes/MDL-82681-2024091902542827.yml diff --git a/.upgradenotes/MDL-82681-2024091902542827.yml b/.upgradenotes/MDL-82681-2024091902542827.yml new file mode 100644 index 00000000000..a2d8f58d672 --- /dev/null +++ b/.upgradenotes/MDL-82681-2024091902542827.yml @@ -0,0 +1,7 @@ +issueNumber: MDL-82681 +notes: + mod_assign: + - message: >- + The method process_save_grading_options() has been deprecated as it is + no longer used. + type: deprecated diff --git a/mod/assign/locallib.php b/mod/assign/locallib.php index a7cd878c56b..c791a8a97ba 100644 --- a/mod/assign/locallib.php +++ b/mod/assign/locallib.php @@ -7342,9 +7342,18 @@ class assign { /** * Save grading options. * + * @deprecated since Moodle 4.5 + * @todo Final deprecation in Moodle 6.0. See MDL-82876. * @return void */ + #[\core\attribute\deprecated( + 'null', + since: '4.5', + reason: 'It is no longer used.', + mdl: 'MDL-82681', + )] protected function process_save_grading_options() { + \core\deprecation::emit_deprecation_if_present([self::class, __FUNCTION__]); } /**