diff --git a/.upgradenotes/MDL-80744-2024062407163290.yml b/.upgradenotes/MDL-80744-2024062407163290.yml new file mode 100644 index 00000000000..c92a3760e80 --- /dev/null +++ b/.upgradenotes/MDL-80744-2024062407163290.yml @@ -0,0 +1,20 @@ +issueNumber: MDL-80744 +notes: + core_grades: + - message: >- + The behat step definition + behat_grade::i_confirm_in_search_within_the_gradebook_widget_exists has + been deprecated. Please use + behat_general::i_confirm_in_search_combobox_exists instead. + type: deprecated + - message: >- + The behat step definition + behat_grade::i_confirm_in_search_within_the_gradebook_widget_does_not_exist + has been deprecated. Please use + behat_general::i_confirm_in_search_combobox_does_not_exist instead. + type: deprecated + - message: >- + The behat step definition behat_grade::i_click_on_in_search_widget has + been deprecated. Please use behat_general::i_click_on_in_search_combobox + instead. + type: deprecated diff --git a/completion/tests/behat/activity_completion_criteria.feature b/completion/tests/behat/activity_completion_criteria.feature index 1679166a4d5..24d085ff6e5 100644 --- a/completion/tests/behat/activity_completion_criteria.feature +++ b/completion/tests/behat/activity_completion_criteria.feature @@ -112,7 +112,7 @@ Feature: Allow to mark course as completed without cron for activity completion Given I am on the "Completion course" "grades > Single View > View" page logged in as "teacher1" And I click on "Users" "link" in the ".page-toggler" "css_element" And I turn editing mode on - And I click on "Student First" in the "user" search widget + And I click on "Student First" in the "Search users" search combo box And I set the field "Override for Test assignment name" to "1" When I set the following fields to these values: | Grade for Test assignment name | 10.00 | diff --git a/course/classes/output/actionbar/renderer.php b/course/classes/output/actionbar/renderer.php index 26f0f1b243f..adc5b7e89a2 100644 --- a/course/classes/output/actionbar/renderer.php +++ b/course/classes/output/actionbar/renderer.php @@ -25,6 +25,17 @@ namespace core_course\output\actionbar; */ class renderer extends \plugin_renderer_base { + /** + * Renders the user selector trigger element in the action bar. + * + * @param user_selector $userselector The user selector object. + * @return string The HTML output. + */ + public function render_user_selector(user_selector $userselector): string { + $data = $userselector->export_for_template($this); + return parent::render_from_template($userselector->get_template(), $data); + } + /** * Renders the group selector trigger element in the action bar. * diff --git a/course/classes/output/actionbar/user_selector.php b/course/classes/output/actionbar/user_selector.php new file mode 100644 index 00000000000..6afba7196c2 --- /dev/null +++ b/course/classes/output/actionbar/user_selector.php @@ -0,0 +1,96 @@ +. + +namespace core_course\output\actionbar; + +use core\output\comboboxsearch; +use moodle_url; +use stdClass; + +/** + * Renderable class for the user selector element in the action bar. + * + * @package core_course + * @copyright 2024 Ilya Tregubov + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class user_selector extends comboboxsearch { + + /** + * The class constructor. + * + * @param stdClass $course The course object. + * @param moodle_url $resetlink The reset link. + * @param int|null $userid The user ID. + * @param int|null $groupid The group ID. + * @param string $usersearch The user search query. + * @param int|null $instanceid The instance ID. + */ + public function __construct( + stdClass $course, + moodle_url $resetlink, + ?int $userid = null, + ?int $groupid = null, + string $usersearch = '', + ?int $instanceid = null + ) { + + $userselectorontent = $this->user_selector_output($course, $resetlink, $userid, $groupid, $usersearch, $instanceid); + parent::__construct(true, $userselectorontent, null, 'user-search d-flex', + null, 'usersearchdropdown overflow-auto', null, false); + } + + /** + * Method that generates the output for the user selector. + * + * @param stdClass $course The course object. + * @param moodle_url|null $resetlink The reset link. + * @param int|null $userid The user ID. + * @param int|null $groupid The group ID. + * @param string $usersearch The user search query. + * @param int|null $instanceid The instance ID. + * @return string The HTML output. + */ + private function user_selector_output( + stdClass $course, + ?moodle_url $resetlink = null, + ?int $userid = null, + ?int $groupid = null, + string $usersearch = '', + ?int $instanceid = null + ): string { + global $OUTPUT; + + // If the user ID is set, it indicates that a user has been selected. In this case, override the user search + // string with the full name of the selected user. + if ($userid) { + $usersearch = fullname(\core_user::get_user($userid)); + } + + return $OUTPUT->render_from_template('core_user/comboboxsearch/user_selector', [ + 'currentvalue' => $usersearch, + 'courseid' => $course->id, + 'instance' => $instanceid ?? rand(), + 'resetlink' => $resetlink->out(false), + 'group' => $groupid ?? 0, + 'name' => 'usersearch', + 'value' => json_encode([ + 'userid' => $userid, + 'search' => $usersearch, + ]), + ]); + } +} diff --git a/grade/report/grader/amd/build/user.min.js b/grade/report/grader/amd/build/user.min.js index 89ef7719ca6..b4f4ecdbaf6 100644 --- a/grade/report/grader/amd/build/user.min.js +++ b/grade/report/grader/amd/build/user.min.js @@ -1,10 +1,10 @@ -define("gradereport_grader/user",["exports","core_user/comboboxsearch/user","core/url","gradereport_grader/local/user/repository"],(function(_exports,_user,_url,Repository){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}} +define("gradereport_grader/user",["exports","core_user/comboboxsearch/user","gradereport_grader/local/user/repository"],(function(_exports,_user,Repository){var obj; /** * Allow the user to search for learners within the grader report. * * @module gradereport_grader/user * @copyright 2023 Mathew May * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_user=_interopRequireDefault(_user),_url=_interopRequireDefault(_url),Repository=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(Repository);const selectors_component=".user-search",selectors_courseid='[data-region="courseid"]',courseID=document.querySelector(selectors_component).querySelector(selectors_courseid).dataset.courseid;class User extends _user.default{constructor(){super()}static init(){return new User}fetchDataset(){return Repository.userFetch(courseID).then((r=>r.users))}selectAllResultsLink(){return _url.default.relativeUrl("/grade/report/grader/index.php",{id:courseID,gpr_search:this.getSearchTerm()},!1)}selectOneLink(userID){return _url.default.relativeUrl("/grade/report/grader/index.php",{id:courseID,gpr_search:this.getSearchTerm(),gpr_userid:userID},!1)}}return _exports.default=User,_exports.default})); + */function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_user=(obj=_user)&&obj.__esModule?obj:{default:obj},Repository=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(Repository);const selectors_component=".user-search",selectors_courseid='[data-region="courseid"]',courseID=document.querySelector(selectors_component).querySelector(selectors_courseid).dataset.courseid;class User extends _user.default{constructor(baseUrl){super(),this.baseUrl=baseUrl}static init(baseUrl){return new User(baseUrl)}fetchDataset(){return Repository.userFetch(courseID).then((r=>r.users))}selectAllResultsLink(){const url=new URL(this.baseUrl);return url.searchParams.set("gpr_search",this.getSearchTerm()),url.toString()}selectOneLink(userID){const url=new URL(this.baseUrl);return url.searchParams.set("gpr_search",this.getSearchTerm()),url.searchParams.set("gpr_userid",userID),url.toString()}}return _exports.default=User,_exports.default})); //# sourceMappingURL=user.min.js.map \ No newline at end of file diff --git a/grade/report/grader/amd/build/user.min.js.map b/grade/report/grader/amd/build/user.min.js.map index 4da4df8ac4b..b7993a91d25 100644 --- a/grade/report/grader/amd/build/user.min.js.map +++ b/grade/report/grader/amd/build/user.min.js.map @@ -1 +1 @@ -{"version":3,"file":"user.min.js","sources":["../src/user.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\n/**\n * Allow the user to search for learners within the grader report.\n *\n * @module gradereport_grader/user\n * @copyright 2023 Mathew May \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport UserSearch from 'core_user/comboboxsearch/user';\nimport Url from 'core/url';\nimport * as Repository from 'gradereport_grader/local/user/repository';\n\n// Define our standard lookups.\nconst selectors = {\n component: '.user-search',\n courseid: '[data-region=\"courseid\"]',\n};\nconst component = document.querySelector(selectors.component);\nconst courseID = component.querySelector(selectors.courseid).dataset.courseid;\n\nexport default class User extends UserSearch {\n\n constructor() {\n super();\n }\n\n static init() {\n return new User();\n }\n\n /**\n * Get the data we will be searching against in this component.\n *\n * @returns {Promise<*>}\n */\n fetchDataset() {\n return Repository.userFetch(courseID).then((r) => r.users);\n }\n\n /**\n * Build up the view all link.\n *\n * @returns {string|*}\n */\n selectAllResultsLink() {\n return Url.relativeUrl('/grade/report/grader/index.php', {\n id: courseID,\n gpr_search: this.getSearchTerm()\n }, false);\n }\n\n /**\n * Build up the link that is dedicated to a particular result.\n *\n * @param {Number} userID The ID of the user selected.\n * @returns {string|*}\n */\n selectOneLink(userID) {\n return Url.relativeUrl('/grade/report/grader/index.php', {\n id: courseID,\n gpr_search: this.getSearchTerm(),\n gpr_userid: userID,\n }, false);\n }\n}\n"],"names":["selectors","courseID","document","querySelector","dataset","courseid","User","UserSearch","constructor","fetchDataset","Repository","userFetch","then","r","users","selectAllResultsLink","Url","relativeUrl","id","gpr_search","this","getSearchTerm","selectOneLink","userID","gpr_userid"],"mappings":";;;;;;;q0BA2BMA,oBACS,eADTA,mBAEQ,2BAGRC,SADYC,SAASC,cAAcH,qBACdG,cAAcH,oBAAoBI,QAAQC,eAEhDC,aAAaC,cAE9BC,2CAKW,IAAIF,KAQfG,sBACWC,WAAWC,UAAUV,UAAUW,MAAMC,GAAMA,EAAEC,QAQxDC,8BACWC,aAAIC,YAAY,iCAAkC,CACrDC,GAAIjB,SACJkB,WAAYC,KAAKC,kBAClB,GASPC,cAAcC,eACHP,aAAIC,YAAY,iCAAkC,CACrDC,GAAIjB,SACJkB,WAAYC,KAAKC,gBACjBG,WAAYD,SACb"} \ No newline at end of file +{"version":3,"file":"user.min.js","sources":["../src/user.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\n/**\n * Allow the user to search for learners within the grader report.\n *\n * @module gradereport_grader/user\n * @copyright 2023 Mathew May \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport UserSearch from 'core_user/comboboxsearch/user';\nimport * as Repository from 'gradereport_grader/local/user/repository';\n\n// Define our standard lookups.\nconst selectors = {\n component: '.user-search',\n courseid: '[data-region=\"courseid\"]',\n};\nconst component = document.querySelector(selectors.component);\nconst courseID = component.querySelector(selectors.courseid).dataset.courseid;\n\nexport default class User extends UserSearch {\n\n /**\n * Construct the class.\n * @param {string} baseUrl The base URL for the page.\n */\n constructor(baseUrl) {\n super();\n this.baseUrl = baseUrl;\n }\n\n static init(baseUrl) {\n return new User(baseUrl);\n }\n\n /**\n * Get the data we will be searching against in this component.\n *\n * @returns {Promise<*>}\n */\n fetchDataset() {\n return Repository.userFetch(courseID).then((r) => r.users);\n }\n\n /**\n * Build up the view all link.\n *\n * @returns {string|*}\n */\n selectAllResultsLink() {\n const url = new URL(this.baseUrl);\n url.searchParams.set('gpr_search', this.getSearchTerm());\n return url.toString();\n }\n\n /**\n * Build up the link that is dedicated to a particular result.\n *\n * @param {Number} userID The ID of the user selected.\n * @returns {string|*}\n */\n selectOneLink(userID) {\n const url = new URL(this.baseUrl);\n url.searchParams.set('gpr_search', this.getSearchTerm());\n url.searchParams.set('gpr_userid', userID);\n return url.toString();\n }\n}\n"],"names":["selectors","courseID","document","querySelector","dataset","courseid","User","UserSearch","constructor","baseUrl","fetchDataset","Repository","userFetch","then","r","users","selectAllResultsLink","url","URL","this","searchParams","set","getSearchTerm","toString","selectOneLink","userID"],"mappings":";;;;;;;skCA0BMA,oBACS,eADTA,mBAEQ,2BAGRC,SADYC,SAASC,cAAcH,qBACdG,cAAcH,oBAAoBI,QAAQC,eAEhDC,aAAaC,cAM9BC,YAAYC,sBAEHA,QAAUA,oBAGPA,gBACD,IAAIH,KAAKG,SAQpBC,sBACWC,WAAWC,UAAUX,UAAUY,MAAMC,GAAMA,EAAEC,QAQxDC,6BACUC,IAAM,IAAIC,IAAIC,KAAKV,gBACzBQ,IAAIG,aAAaC,IAAI,aAAcF,KAAKG,iBACjCL,IAAIM,WASfC,cAAcC,cACJR,IAAM,IAAIC,IAAIC,KAAKV,gBACzBQ,IAAIG,aAAaC,IAAI,aAAcF,KAAKG,iBACxCL,IAAIG,aAAaC,IAAI,aAAcI,QAC5BR,IAAIM"} \ No newline at end of file diff --git a/grade/report/grader/amd/src/user.js b/grade/report/grader/amd/src/user.js index 82c5992d760..396aa323f9d 100644 --- a/grade/report/grader/amd/src/user.js +++ b/grade/report/grader/amd/src/user.js @@ -21,7 +21,6 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ import UserSearch from 'core_user/comboboxsearch/user'; -import Url from 'core/url'; import * as Repository from 'gradereport_grader/local/user/repository'; // Define our standard lookups. @@ -34,12 +33,17 @@ const courseID = component.querySelector(selectors.courseid).dataset.courseid; export default class User extends UserSearch { - constructor() { + /** + * Construct the class. + * @param {string} baseUrl The base URL for the page. + */ + constructor(baseUrl) { super(); + this.baseUrl = baseUrl; } - static init() { - return new User(); + static init(baseUrl) { + return new User(baseUrl); } /** @@ -57,10 +61,9 @@ export default class User extends UserSearch { * @returns {string|*} */ selectAllResultsLink() { - return Url.relativeUrl('/grade/report/grader/index.php', { - id: courseID, - gpr_search: this.getSearchTerm() - }, false); + const url = new URL(this.baseUrl); + url.searchParams.set('gpr_search', this.getSearchTerm()); + return url.toString(); } /** @@ -70,10 +73,9 @@ export default class User extends UserSearch { * @returns {string|*} */ selectOneLink(userID) { - return Url.relativeUrl('/grade/report/grader/index.php', { - id: courseID, - gpr_search: this.getSearchTerm(), - gpr_userid: userID, - }, false); + const url = new URL(this.baseUrl); + url.searchParams.set('gpr_search', this.getSearchTerm()); + url.searchParams.set('gpr_userid', userID); + return url.toString(); } } diff --git a/grade/report/grader/classes/output/action_bar.php b/grade/report/grader/classes/output/action_bar.php index e7fa25e1008..b6483093926 100644 --- a/grade/report/grader/classes/output/action_bar.php +++ b/grade/report/grader/classes/output/action_bar.php @@ -117,30 +117,14 @@ class action_bar extends \core_grades\output\action_bar { } $resetlink = new moodle_url('/grade/report/grader/index.php', ['id' => $courseid]); - $searchinput = $OUTPUT->render_from_template('core_user/comboboxsearch/user_selector', [ - 'currentvalue' => $this->usersearch, - 'courseid' => $courseid, - 'instance' => rand(), - 'resetlink' => $resetlink->out(false), - 'group' => 0, - 'name' => 'usersearch', - 'value' => json_encode([ - 'userid' => $this->userid, - 'search' => $this->usersearch, - ]), - ]); - $searchdropdown = new comboboxsearch( - true, - $searchinput, - null, - 'user-search d-flex', - null, - 'usersearchdropdown overflow-auto', - null, - false, + $userselectorrenderer = new \core_course\output\actionbar\user_selector( + course: $course, + resetlink: $resetlink, + userid: $this->userid, + groupid: 0, + usersearch: $this->usersearch ); - $data['searchdropdown'] = $searchdropdown->export_for_template($output); - + $data['searchdropdown'] = $userselectorrenderer->export_for_template($output); // The collapsed column dialog is aligned to the edge of the screen, we need to place it such that it also aligns. $collapsemenudirection = right_to_left() ? 'dropdown-menu-left' : 'dropdown-menu-right'; diff --git a/grade/report/grader/index.php b/grade/report/grader/index.php index ad44a4683d0..307b9015e03 100644 --- a/grade/report/grader/index.php +++ b/grade/report/grader/index.php @@ -45,11 +45,12 @@ $graderreportsifirst = optional_param('sifirst', null, PARAM_NOTAGS); $graderreportsilast = optional_param('silast', null, PARAM_NOTAGS); $studentsperpage = optional_param('perpage', null, PARAM_INT); +$baseurl = new moodle_url('/grade/report/grader/index.php', ['id' => $courseid]); $PAGE->set_url(new moodle_url('/grade/report/grader/index.php', array('id'=>$courseid))); $PAGE->set_pagelayout('report'); $PAGE->requires->js_call_amd('gradereport_grader/stickycolspan', 'init'); -$PAGE->requires->js_call_amd('gradereport_grader/user', 'init'); +$PAGE->requires->js_call_amd('gradereport_grader/user', 'init', [$baseurl->out(false)]); $PAGE->requires->js_call_amd('gradereport_grader/feedback_modal', 'init'); $PAGE->requires->js_call_amd('core_grades/gradebooksetup_forms', 'init'); @@ -60,7 +61,6 @@ if (!$course = $DB->get_record('course', array('id' => $courseid))) { // Conditionally add the group JS if we have groups enabled. if ($course->groupmode) { - $baseurl = new moodle_url('/grade/report/grader/index.php', ['id' => $courseid]); $PAGE->requires->js_call_amd('core_course/actionbar/group', 'init', [$baseurl->out(false)]); } diff --git a/grade/report/grader/tests/behat/groupsearch.feature b/grade/report/grader/tests/behat/groupsearch.feature index 668f9b958cd..2f46c091828 100644 --- a/grade/report/grader/tests/behat/groupsearch.feature +++ b/grade/report/grader/tests/behat/groupsearch.feature @@ -36,13 +36,13 @@ Feature: Group searching functionality within the grader report. Then ".groupsearchwidget" "css_element" should not exist Scenario: A teacher can search for and find a group to display - Given I confirm "Tutor group" in "group" search within the gradebook widget exists - And I confirm "Marker group" in "group" search within the gradebook widget exists + Given I confirm "Tutor group" exists in the "Search groups" search combo box + And I confirm "Marker group" exists in the "Search groups" search combo box When I set the field "Search groups" to "tutor" And I wait until "Marker group" "option_role" does not exist - Then I confirm "Tutor group" in "group" search within the gradebook widget exists - And I confirm "Marker group" in "group" search within the gradebook widget does not exist - And I click on "Tutor group" in the "group" search widget + Then I confirm "Tutor group" exists in the "Search groups" search combo box + And I confirm "Marker group" does not exist in the "Search groups" search combo box + And I click on "Tutor group" in the "Search groups" search combo box # The search input remains in the field on reload this is in keeping with other search implementations. And I click on ".groupsearchwidget" "css_element" And the field "Search groups" matches value "tutor" @@ -52,22 +52,22 @@ Feature: Group searching functionality within the grader report. Scenario: A teacher can only see the group members in the 'user' search widget after selecting a group option # Confirm that all users are initially displayed in the 'user' search widget. Given I set the field "Search users" to "Student" - And I confirm "Student 1" in "user" search within the gradebook widget exists - And I confirm "Student 2" in "user" search within the gradebook widget exists + And I confirm "Student 1" exists in the "Search users" search combo box + And I confirm "Student 2" exists in the "Search users" search combo box # Select a particular group from the 'group' search widget. - When I click on "Default group" in the "group" search widget + When I click on "Default group" in the "Search groups" search combo box # Confirm that only users which are members of the selected group are displayed in the 'user' search widget. And I set the field "Search users" to "Student" - Then I confirm "Student 1" in "user" search within the gradebook widget exists - And I confirm "Student 2" in "user" search within the gradebook widget does not exist - And I click on "Tutor group" in the "group" search widget + Then I confirm "Student 1" exists in the "Search users" search combo box + And I confirm "Student 2" does not exist in the "Search users" search combo box + And I click on "Tutor group" in the "Search groups" search combo box And I set the field "Search users" to "Student" - And I confirm "Student 1" in "user" search within the gradebook widget does not exist - And I confirm "Student 2" in "user" search within the gradebook widget does not exist - And I click on "All participants" in the "group" search widget + And I confirm "Student 1" does not exist in the "Search users" search combo box + And I confirm "Student 2" does not exist in the "Search users" search combo box + And I click on "All participants" in the "Search groups" search combo box And I set the field "Search users" to "Student" - And I confirm "Student 1" in "user" search within the gradebook widget exists - And I confirm "Student 2" in "user" search within the gradebook widget exists + And I confirm "Student 1" exists in the "Search users" search combo box + And I confirm "Student 2" exists in the "Search users" search combo box @accessibility Scenario: A teacher can set focus and search using the input with a keyboard diff --git a/grade/report/grader/tests/behat/tertiary_name_filter.feature b/grade/report/grader/tests/behat/tertiary_name_filter.feature index f962bf861eb..ec8cc66df05 100644 --- a/grade/report/grader/tests/behat/tertiary_name_filter.feature +++ b/grade/report/grader/tests/behat/tertiary_name_filter.feature @@ -150,7 +150,7 @@ Feature: Within the grader report, test that we can open our generic filter drop Scenario: A teacher can search and then filter by first or last name Given I set the field "Search users" to "Student 1" - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box And I click on "Filter by name" "combobox" And I select "S" in the "First name" "core_grades > initials bar" When I press "Apply" diff --git a/grade/report/grader/tests/behat/tertiary_navigation_searching.feature b/grade/report/grader/tests/behat/tertiary_navigation_searching.feature index 3f787e7a89c..fba2ed8c8b9 100644 --- a/grade/report/grader/tests/behat/tertiary_navigation_searching.feature +++ b/grade/report/grader/tests/behat/tertiary_navigation_searching.feature @@ -54,8 +54,8 @@ Feature: Within the grader report, test that we can search for users | Teacher 1 | When I set the field "Search users" to "Turtle" And I wait until "View all results (1)" "option_role" exists - And I confirm "Turtle Manatee" in "user" search within the gradebook widget exists - And I confirm "User Example" in "user" search within the gradebook widget does not exist + And I confirm "Turtle Manatee" exists in the "Search users" search combo box + And I confirm "User Example" does not exist in the "Search users" search combo box And I click on "Turtle Manatee" "list_item" # Business case: This will trigger a page reload and can not dynamically update the table. And I wait until the page is ready @@ -76,7 +76,7 @@ Feature: Within the grader report, test that we can search for users Scenario: A teacher can search the grader report to find specified users # Case: Standard search. - Given I click on "Dummy" in the "user" search widget + Given I click on "Dummy" in the "Search users" search combo box And the following should exist in the "user-grades" table: | -1- | | Dummy User | @@ -106,14 +106,14 @@ Feature: Within the grader report, test that we can search for users # Case: Multiple users found and select only one result. Then I set the field "Search users" to "User" And I wait until "View all results (3)" "option_role" exists - And I confirm "Dummy User" in "user" search within the gradebook widget exists - And I confirm "User Example" in "user" search within the gradebook widget exists - And I confirm "User Test" in "user" search within the gradebook widget exists - And I confirm "Turtle Manatee" in "user" search within the gradebook widget does not exist + And I confirm "Dummy User" exists in the "Search users" search combo box + And I confirm "User Example" exists in the "Search users" search combo box + And I confirm "User Test" exists in the "Search users" search combo box + And I confirm "Turtle Manatee" does not exist in the "Search users" search combo box # Check if the matched field names (by lines) includes some identifiable info to help differentiate similar users. - And I confirm "User (student2@example.com)" in "user" search within the gradebook widget exists - And I confirm "User (student3@example.com)" in "user" search within the gradebook widget exists - And I confirm "User (student4@example.com)" in "user" search within the gradebook widget exists + And I confirm "User (student2@example.com)" exists in the "Search users" search combo box + And I confirm "User (student3@example.com)" exists in the "Search users" search combo box + And I confirm "User (student4@example.com)" exists in the "Search users" search combo box And I click on "Dummy User" "list_item" And I wait until the page is ready And the following should exist in the "user-grades" table: @@ -156,7 +156,7 @@ Feature: Within the grader report, test that we can search for users | Dummy User | Scenario: A teacher can quickly tell that a search is active on the current table - When I click on "Turtle" in the "user" search widget + When I click on "Turtle" in the "Search users" search combo box # The search input should contain the name of the user we have selected, so that it is clear that the result pertains to a specific user. Then the field "Search users" matches value "Turtle Manatee" # Test if we can then further retain the turtle result set and further filter from there. @@ -171,54 +171,54 @@ Feature: Within the grader report, test that we can search for users And I set the field "Search users" to "@example.com" And I wait until "View all results (5)" "option_role" exists # Note: All learners match this email & showing emails is current default. - And I confirm "Dummy User" in "user" search within the gradebook widget exists - And I confirm "User Example" in "user" search within the gradebook widget exists - And I confirm "User Test" in "user" search within the gradebook widget exists - And I confirm "Student 1" in "user" search within the gradebook widget exists - And I confirm "Turtle Manatee" in "user" search within the gradebook widget exists + And I confirm "Dummy User" exists in the "Search users" search combo box + And I confirm "User Example" exists in the "Search users" search combo box + And I confirm "User Test" exists in the "Search users" search combo box + And I confirm "Student 1" exists in the "Search users" search combo box + And I confirm "Turtle Manatee" exists in the "Search users" search combo box # Search on the country field. When I set the field "Search users" to "JP" And I wait until "Turtle Manatee" "list_item" does not exist - And I confirm "Dummy User" in "user" search within the gradebook widget exists - And I confirm "User Test" in "user" search within the gradebook widget exists + And I confirm "Dummy User" exists in the "Search users" search combo box + And I confirm "User Test" exists in the "Search users" search combo box # Search on the city field. And I set the field "Search users" to "Hanoi" And I wait until "User Test" "list_item" does not exist - Then I confirm "Student 1" in "user" search within the gradebook widget exists + Then I confirm "Student 1" exists in the "Search users" search combo box # Search on the institution field. And I set the field "Search users" to "ABCD" And I wait until "Dummy User" "list_item" exists - And I confirm "User Example" in "user" search within the gradebook widget exists - And I confirm "User Test" in "user" search within the gradebook widget exists - And I confirm "Student 1" in "user" search within the gradebook widget exists - And I confirm "Turtle Manatee" in "user" search within the gradebook widget exists + And I confirm "User Example" exists in the "Search users" search combo box + And I confirm "User Test" exists in the "Search users" search combo box + And I confirm "Student 1" exists in the "Search users" search combo box + And I confirm "Turtle Manatee" exists in the "Search users" search combo box # Search on the department field. And I set the field "Search users" to "ABC3" And I wait until "User Example" "list_item" does not exist - And I confirm "User Test" in "user" search within the gradebook widget exists - And I confirm "Turtle Manatee" in "user" search within the gradebook widget exists + And I confirm "User Test" exists in the "Search users" search combo box + And I confirm "Turtle Manatee" exists in the "Search users" search combo box # Search on the phone1 field. And I set the field "Search users" to "4365899871" And I wait until "User Test" "list_item" does not exist - And I confirm "Dummy User" in "user" search within the gradebook widget exists + And I confirm "Dummy User" exists in the "Search users" search combo box # Search on the phone2 field. And I set the field "Search users" to "2149871323" And I wait until "Dummy User" "list_item" does not exist - And I confirm "User Test" in "user" search within the gradebook widget exists + And I confirm "User Test" exists in the "Search users" search combo box # Search on the institution field then press enter to show the record set. And I set the field "Search users" to "ABC" And I wait until "Turtle Manatee" "list_item" exists - And I confirm "Dummy User" in "user" search within the gradebook widget exists - And I confirm "User Example" in "user" search within the gradebook widget exists - And I confirm "User Test" in "user" search within the gradebook widget exists - And I confirm "Student 1" in "user" search within the gradebook widget exists + And I confirm "Dummy User" exists in the "Search users" search combo box + And I confirm "User Example" exists in the "Search users" search combo box + And I confirm "User Test" exists in the "Search users" search combo box + And I confirm "Student 1" exists in the "Search users" search combo box And I press the down key And I press the enter key And I wait "1" seconds @@ -292,7 +292,7 @@ Feature: Within the grader report, test that we can search for users And the focused element is "Clear search input" "button" And I press the enter key And I wait until the page is ready - And I confirm "Turtle Manatee" in "user" search within the gradebook widget does not exist + And I confirm "Turtle Manatee" does not exist in the "Search users" search combo box Scenario: Once a teacher searches, it'll apply the currently set filters and inform the teacher as such # Set up a basic filtering case. @@ -314,7 +314,7 @@ Feature: Within the grader report, test that we can search for users # Begin the search checking if we are adhering the filters. When I set the field "Search users" to "Turtle" - Then I confirm "Turtle Manatee" in "user" search within the gradebook widget does not exist + Then I confirm "Turtle Manatee" does not exist in the "Search users" search combo box Scenario: A teacher can reset the search and filters all at once Given I set the field "Search users" to "Turtle" @@ -329,7 +329,7 @@ Feature: Within the grader report, test that we can search for users And the following should exist in the "user-grades" table: | -1- | | Turtle Manatee | - And I click on "Default group" in the "group" search widget + And I click on "Default group" in the "Search groups" search combo box And the following should exist in the "user-grades" table: | -1- | | Turtle Manatee | @@ -353,7 +353,7 @@ Feature: Within the grader report, test that we can search for users When I set the field "Search users" to "42" # One of the users' phone numbers also matches. And I wait until "View all results (2)" "option_role" exists - Then I confirm "Student s42" in "user" search within the gradebook widget exists + Then I confirm "Student s42" exists in the "Search users" search combo box Scenario: As a teacher I save grades using search and pagination Given "42" "users" exist with the following data: diff --git a/grade/report/lib.php b/grade/report/lib.php index 76db309c995..a49effe5746 100644 --- a/grade/report/lib.php +++ b/grade/report/lib.php @@ -485,108 +485,15 @@ abstract class grade_report { // A user wants to return a subset of learners that match their search criteria. if ($this->usersearch !== '' && $this->userid === -1) { - // Get the fields for all contexts because there is a special case later where it allows - // matches of fields you can't access if they are on your own account. - $userfields = fields::for_identity(null, false)->with_userpic(); - ['mappings' => $mappings] = (array)$userfields->get_sql('u', true); [ 'where' => $keywordswhere, 'params' => $keywordsparams, - ] = $this->get_users_search_sql($mappings, $userfields->get_required_fields()); + ] = \core_user::get_users_search_sql($this->context, $this->usersearch); $this->userwheresql .= " AND $keywordswhere"; $this->userwheresql_params = array_merge($this->userwheresql_params, $keywordsparams); } } - /** - * Prepare SQL where clause and associated parameters for any user searching being performed. - * This mostly came from core_user\table\participants_search with some slight modifications four our use case. - * - * @param array $mappings Array of field mappings (fieldname => SQL code for the value) - * @param array $userfields An array that we cast from user profile fields to search within. - * @return array SQL query data in the format ['where' => '', 'params' => []]. - */ - protected function get_users_search_sql(array $mappings, array $userfields): array { - global $DB, $USER; - - $canviewfullnames = has_capability('moodle/site:viewfullnames', $this->context); - - $params = []; - $searchkey1 = 'search01'; - $searchkey2 = 'search02'; - $searchkey3 = 'search03'; - - $conditions = []; - - // Search by fullname. - [$fullname, $fullnameparams] = fields::get_sql_fullname('u', $canviewfullnames); - $conditions[] = $DB->sql_like($fullname, ':' . $searchkey1, false, false); - $params = array_merge($params, $fullnameparams); - - // Search by email. - $email = $DB->sql_like('email', ':' . $searchkey2, false, false); - - if (!in_array('email', $userfields)) { - $maildisplay = 'maildisplay0'; - $userid1 = 'userid01'; - // Prevent users who hide their email address from being found by others - // who aren't allowed to see hidden email addresses. - $email = "(". $email ." AND (" . - "u.maildisplay <> :$maildisplay " . - "OR u.id = :$userid1". // Users can always find themselves. - "))"; - $params[$maildisplay] = core_user::MAILDISPLAY_HIDE; - $params[$userid1] = $USER->id; - } - - $conditions[] = $email; - - // Search by idnumber. - $idnumber = $DB->sql_like('idnumber', ':' . $searchkey3, false, false); - - if (!in_array('idnumber', $userfields)) { - $userid2 = 'userid02'; - // Users who aren't allowed to see idnumbers should at most find themselves - // when searching for an idnumber. - $idnumber = "(". $idnumber . " AND u.id = :$userid2)"; - $params[$userid2] = $USER->id; - } - - $conditions[] = $idnumber; - - // Search all user identify fields. - $extrasearchfields = fields::get_identity_fields(null, false); - foreach ($extrasearchfields as $fieldindex => $extrasearchfield) { - if (in_array($extrasearchfield, ['email', 'idnumber', 'country'])) { - // Already covered above. - continue; - } - // The param must be short (max 32 characters) so don't include field name. - $param = $searchkey3 . '_ident' . $fieldindex; - $fieldsql = $mappings[$extrasearchfield]; - $condition = $DB->sql_like($fieldsql, ':' . $param, false, false); - $params[$param] = "%$this->usersearch%"; - - if (!in_array($extrasearchfield, $userfields)) { - // User cannot see this field, but allow match if their own account. - $userid3 = 'userid03_ident' . $fieldindex; - $condition = "(". $condition . " AND u.id = :$userid3)"; - $params[$userid3] = $USER->id; - } - $conditions[] = $condition; - } - - $where = "(". implode(" OR ", $conditions) .") "; - $params[$searchkey1] = "%$this->usersearch%"; - $params[$searchkey2] = "%$this->usersearch%"; - $params[$searchkey3] = "%$this->usersearch%"; - - return [ - 'where' => $where, - 'params' => $params, - ]; - } - /** * Returns an arrow icon inside an tag, for the purpose of sorting a column. * @param string $direction diff --git a/grade/report/singleview/amd/build/grade.min.js b/grade/report/singleview/amd/build/grade.min.js index f2b9953674b..836dacd706e 100644 --- a/grade/report/singleview/amd/build/grade.min.js +++ b/grade/report/singleview/amd/build/grade.min.js @@ -1,3 +1,3 @@ -define("gradereport_singleview/grade",["exports","core_grades/comboboxsearch/grade","core/url"],(function(_exports,_grade,_url){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_grade=_interopRequireDefault(_grade),_url=_interopRequireDefault(_url);const selectors_component=".grade-search",selectors_courseid='[data-region="courseid"]',component=document.querySelector(selectors_component);class GradeItems extends _grade.default{constructor(){var obj,key,value;super(),obj=this,key="courseID",value=component.querySelector(selectors_courseid).dataset.courseid,key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value}static init(){return new GradeItems}selectOneLink(gradeID){return _url.default.relativeUrl("/grade/report/singleview/index.php",{id:this.courseID,gradesearchvalue:this.getSearchTerm(),item:"grade",itemid:gradeID},!1)}}return _exports.default=GradeItems,_exports.default})); +define("gradereport_singleview/grade",["exports","core_grades/comboboxsearch/grade"],(function(_exports,_grade){var obj;Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_grade=(obj=_grade)&&obj.__esModule?obj:{default:obj};const selectors_component=".grade-search",selectors_courseid='[data-region="courseid"]',component=document.querySelector(selectors_component);class GradeItems extends _grade.default{constructor(baseUrl){super(),function(obj,key,value){key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value}(this,"courseID",component.querySelector(selectors_courseid).dataset.courseid),this.baseUrl=baseUrl}static init(baseUrl){return new GradeItems(baseUrl)}selectOneLink(gradeID){const url=new URL(this.baseUrl);return url.searchParams.set("gradesearchvalue",this.getSearchTerm()),url.searchParams.set("item","grade"),url.searchParams.set("itemid",gradeID),url.toString()}}return _exports.default=GradeItems,_exports.default})); //# sourceMappingURL=grade.min.js.map \ No newline at end of file diff --git a/grade/report/singleview/amd/build/grade.min.js.map b/grade/report/singleview/amd/build/grade.min.js.map index 1875accdc21..8b78de04084 100644 --- a/grade/report/singleview/amd/build/grade.min.js.map +++ b/grade/report/singleview/amd/build/grade.min.js.map @@ -1 +1 @@ -{"version":3,"file":"grade.min.js","sources":["../src/grade.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\n/**\n * Allow the user to search for grades within the singleview report.\n *\n * @module gradereport_singleview/grade\n * @copyright 2023 Mathew May \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport GradeItemSearch from 'core_grades/comboboxsearch/grade';\nimport Url from 'core/url';\n\n// Define our standard lookups.\nconst selectors = {\n component: '.grade-search',\n courseid: '[data-region=\"courseid\"]',\n};\nconst component = document.querySelector(selectors.component);\n\nexport default class GradeItems extends GradeItemSearch {\n\n courseID = component.querySelector(selectors.courseid).dataset.courseid;\n\n constructor() {\n super();\n }\n\n static init() {\n return new GradeItems();\n }\n\n /**\n * Build up the link that is dedicated to a particular result.\n *\n * @param {Number} gradeID The ID of the grade item selected.\n * @returns {string|*}\n */\n selectOneLink(gradeID) {\n return Url.relativeUrl('/grade/report/singleview/index.php', {\n id: this.courseID,\n gradesearchvalue: this.getSearchTerm(),\n item: 'grade',\n itemid: gradeID,\n }, false);\n }\n}\n"],"names":["selectors","component","document","querySelector","GradeItems","GradeItemSearch","constructor","dataset","courseid","selectOneLink","gradeID","Url","relativeUrl","id","this","courseID","gradesearchvalue","getSearchTerm","item","itemid"],"mappings":"gXA0BMA,oBACS,gBADTA,mBAEQ,2BAERC,UAAYC,SAASC,cAAcH,2BAEpBI,mBAAmBC,eAIpCC,sEAFWL,UAAUE,cAAcH,oBAAoBO,QAAQC,+IAOpD,IAAIJ,WASfK,cAAcC,gBACHC,aAAIC,YAAY,qCAAsC,CACzDC,GAAIC,KAAKC,SACTC,iBAAkBF,KAAKG,gBACvBC,KAAM,QACNC,OAAQT,UACT"} \ No newline at end of file +{"version":3,"file":"grade.min.js","sources":["../src/grade.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\n/**\n * Allow the user to search for grades within the singleview report.\n *\n * @module gradereport_singleview/grade\n * @copyright 2023 Mathew May \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport GradeItemSearch from 'core_grades/comboboxsearch/grade';\n\n// Define our standard lookups.\nconst selectors = {\n component: '.grade-search',\n courseid: '[data-region=\"courseid\"]',\n};\nconst component = document.querySelector(selectors.component);\n\nexport default class GradeItems extends GradeItemSearch {\n\n courseID = component.querySelector(selectors.courseid).dataset.courseid;\n\n /**\n * Construct the class.\n *\n * @param {string} baseUrl The base URL for the page.\n */\n constructor(baseUrl) {\n super();\n this.baseUrl = baseUrl;\n }\n\n static init(baseUrl) {\n return new GradeItems(baseUrl);\n }\n\n /**\n * Build up the link that is dedicated to a particular result.\n *\n * @param {Number} gradeID The ID of the grade item selected.\n * @returns {string|*}\n */\n selectOneLink(gradeID) {\n const url = new URL(this.baseUrl);\n url.searchParams.set('gradesearchvalue', this.getSearchTerm());\n url.searchParams.set('item', 'grade');\n url.searchParams.set('itemid', gradeID);\n return url.toString();\n }\n}\n"],"names":["selectors","component","document","querySelector","GradeItems","GradeItemSearch","constructor","baseUrl","dataset","courseid","selectOneLink","gradeID","url","URL","this","searchParams","set","getSearchTerm","toString"],"mappings":"oQAyBMA,oBACS,gBADTA,mBAEQ,2BAERC,UAAYC,SAASC,cAAcH,2BAEpBI,mBAAmBC,eASpCC,YAAYC,2KAPDN,UAAUE,cAAcH,oBAAoBQ,QAAQC,eAStDF,QAAUA,oBAGPA,gBACD,IAAIH,WAAWG,SAS1BG,cAAcC,eACJC,IAAM,IAAIC,IAAIC,KAAKP,gBACzBK,IAAIG,aAAaC,IAAI,mBAAoBF,KAAKG,iBAC9CL,IAAIG,aAAaC,IAAI,OAAQ,SAC7BJ,IAAIG,aAAaC,IAAI,SAAUL,SACxBC,IAAIM"} \ No newline at end of file diff --git a/grade/report/singleview/amd/build/user.min.js b/grade/report/singleview/amd/build/user.min.js index 0c6f67481f4..2a192228f91 100644 --- a/grade/report/singleview/amd/build/user.min.js +++ b/grade/report/singleview/amd/build/user.min.js @@ -1,10 +1,10 @@ -define("gradereport_singleview/user",["exports","core_user/comboboxsearch/user","core/url","core/templates","core_grades/searchwidget/repository"],(function(_exports,_user,_url,_templates,Repository){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}} +define("gradereport_singleview/user",["exports","core_user/comboboxsearch/user","core/templates","core_grades/searchwidget/repository"],(function(_exports,_user,_templates,Repository){var obj; /** * Allow the user to search for learners within the singleview report. * * @module gradereport_singleview/user * @copyright 2023 Mathew May * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_user=_interopRequireDefault(_user),_url=_interopRequireDefault(_url),Repository=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(Repository);class User extends _user.default{constructor(){super()}static init(){return new User}async renderDropdown(){const{html:html,js:js}=await(0,_templates.renderForPromise)("core_user/comboboxsearch/resultset",{instance:this.instance,users:this.getMatchedResults().slice(0,5),hasresults:this.getMatchedResults().length>0,searchterm:this.getSearchTerm()});(0,_templates.replaceNodeContents)(this.getHTMLElements().searchDropdown,html,js),this.searchInput.removeAttribute("aria-activedescendant")}selectAllResultsLink(){return null}selectOneLink(userID){return _url.default.relativeUrl("/grade/report/singleview/index.php",{id:this.courseID,searchvalue:this.getSearchTerm(),item:"user",userid:userID},!1)}fetchDataset(){const gts="string"==typeof this.groupID&&""===this.groupID?0:this.groupID;return Repository.userFetch(this.courseID,gts).then((r=>r.users))}}return _exports.default=User,_exports.default})); + */function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_user=(obj=_user)&&obj.__esModule?obj:{default:obj},Repository=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(Repository);class User extends _user.default{constructor(baseUrl){super(),this.baseUrl=baseUrl}static init(baseUrl){return new User(baseUrl)}async renderDropdown(){const{html:html,js:js}=await(0,_templates.renderForPromise)("core_user/comboboxsearch/resultset",{instance:this.instance,users:this.getMatchedResults().slice(0,5),hasresults:this.getMatchedResults().length>0,searchterm:this.getSearchTerm()});(0,_templates.replaceNodeContents)(this.getHTMLElements().searchDropdown,html,js),this.searchInput.removeAttribute("aria-activedescendant")}selectAllResultsLink(){return null}selectOneLink(userID){const url=new URL(this.baseUrl);return url.searchParams.set("searchvalue",this.getSearchTerm()),url.searchParams.set("item","user"),url.searchParams.set("userid",userID),url.toString()}fetchDataset(){const gts="string"==typeof this.groupID&&""===this.groupID?0:this.groupID;return Repository.userFetch(this.courseID,gts).then((r=>r.users))}}return _exports.default=User,_exports.default})); //# sourceMappingURL=user.min.js.map \ No newline at end of file diff --git a/grade/report/singleview/amd/build/user.min.js.map b/grade/report/singleview/amd/build/user.min.js.map index c66de9c8a70..3a5e1f51479 100644 --- a/grade/report/singleview/amd/build/user.min.js.map +++ b/grade/report/singleview/amd/build/user.min.js.map @@ -1 +1 @@ -{"version":3,"file":"user.min.js","sources":["../src/user.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\n/**\n * Allow the user to search for learners within the singleview report.\n *\n * @module gradereport_singleview/user\n * @copyright 2023 Mathew May \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport UserSearch from 'core_user/comboboxsearch/user';\nimport Url from 'core/url';\nimport {renderForPromise, replaceNodeContents} from 'core/templates';\nimport * as Repository from 'core_grades/searchwidget/repository';\n\nexport default class User extends UserSearch {\n\n constructor() {\n super();\n }\n\n static init() {\n return new User();\n }\n\n /**\n * Build the content then replace the node.\n */\n async renderDropdown() {\n const {html, js} = await renderForPromise('core_user/comboboxsearch/resultset', {\n instance: this.instance,\n users: this.getMatchedResults().slice(0, 5),\n hasresults: this.getMatchedResults().length > 0,\n searchterm: this.getSearchTerm(),\n });\n replaceNodeContents(this.getHTMLElements().searchDropdown, html, js);\n // Remove aria-activedescendant when the available options change.\n this.searchInput.removeAttribute('aria-activedescendant');\n }\n\n /**\n * Stub out default required function unused here.\n * @returns {null}\n */\n selectAllResultsLink() {\n return null;\n }\n\n /**\n * Build up the view all link that is dedicated to a particular result.\n *\n * @param {Number} userID The ID of the user selected.\n * @returns {string|*}\n */\n selectOneLink(userID) {\n return Url.relativeUrl('/grade/report/singleview/index.php', {\n id: this.courseID,\n searchvalue: this.getSearchTerm(),\n item: 'user',\n userid: userID,\n }, false);\n }\n\n /**\n * Get the data we will be searching against in this component.\n *\n * @returns {Promise<*>}\n */\n fetchDataset() {\n // Small typing checks as sometimes groups don't exist therefore the element returns a empty string.\n const gts = typeof (this.groupID) === \"string\" && this.groupID === '' ? 0 : this.groupID;\n return Repository.userFetch(this.courseID, gts).then((r) => r.users);\n }\n}\n"],"names":["User","UserSearch","constructor","html","js","instance","this","users","getMatchedResults","slice","hasresults","length","searchterm","getSearchTerm","getHTMLElements","searchDropdown","searchInput","removeAttribute","selectAllResultsLink","selectOneLink","userID","Url","relativeUrl","id","courseID","searchvalue","item","userid","fetchDataset","gts","groupID","Repository","userFetch","then","r"],"mappings":";;;;;;;q0BA2BqBA,aAAaC,cAE9BC,2CAKW,IAAIF,kCAOLG,KAACA,KAADC,GAAOA,UAAY,+BAAiB,qCAAsC,CAC5EC,SAAUC,KAAKD,SACfE,MAAOD,KAAKE,oBAAoBC,MAAM,EAAG,GACzCC,WAAYJ,KAAKE,oBAAoBG,OAAS,EAC9CC,WAAYN,KAAKO,qDAEDP,KAAKQ,kBAAkBC,eAAgBZ,KAAMC,SAE5DY,YAAYC,gBAAgB,yBAOrCC,8BACW,KASXC,cAAcC,eACHC,aAAIC,YAAY,qCAAsC,CACzDC,GAAIjB,KAAKkB,SACTC,YAAanB,KAAKO,gBAClBa,KAAM,OACNC,OAAQP,SACT,GAQPQ,qBAEUC,IAAgC,iBAAlBvB,KAAKwB,SAA0C,KAAjBxB,KAAKwB,QAAiB,EAAIxB,KAAKwB,eAC1EC,WAAWC,UAAU1B,KAAKkB,SAAUK,KAAKI,MAAMC,GAAMA,EAAE3B"} \ No newline at end of file +{"version":3,"file":"user.min.js","sources":["../src/user.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\n/**\n * Allow the user to search for learners within the singleview report.\n *\n * @module gradereport_singleview/user\n * @copyright 2023 Mathew May \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport UserSearch from 'core_user/comboboxsearch/user';\nimport {renderForPromise, replaceNodeContents} from 'core/templates';\nimport * as Repository from 'core_grades/searchwidget/repository';\n\nexport default class User extends UserSearch {\n\n /**\n * Construct the class.\n *\n * @param {string} baseUrl The base URL for the page.\n */\n constructor(baseUrl) {\n super();\n this.baseUrl = baseUrl;\n }\n\n static init(baseUrl) {\n return new User(baseUrl);\n }\n\n /**\n * Build the content then replace the node.\n */\n async renderDropdown() {\n const {html, js} = await renderForPromise('core_user/comboboxsearch/resultset', {\n instance: this.instance,\n users: this.getMatchedResults().slice(0, 5),\n hasresults: this.getMatchedResults().length > 0,\n searchterm: this.getSearchTerm(),\n });\n replaceNodeContents(this.getHTMLElements().searchDropdown, html, js);\n // Remove aria-activedescendant when the available options change.\n this.searchInput.removeAttribute('aria-activedescendant');\n }\n\n /**\n * Stub out default required function unused here.\n * @returns {null}\n */\n selectAllResultsLink() {\n return null;\n }\n\n /**\n * Build up the view all link that is dedicated to a particular result.\n *\n * @param {Number} userID The ID of the user selected.\n * @returns {string|*}\n */\n selectOneLink(userID) {\n const url = new URL(this.baseUrl);\n url.searchParams.set('searchvalue', this.getSearchTerm());\n url.searchParams.set('item', 'user');\n url.searchParams.set('userid', userID);\n return url.toString();\n }\n\n /**\n * Get the data we will be searching against in this component.\n *\n * @returns {Promise<*>}\n */\n fetchDataset() {\n // Small typing checks as sometimes groups don't exist therefore the element returns a empty string.\n const gts = typeof (this.groupID) === \"string\" && this.groupID === '' ? 0 : this.groupID;\n return Repository.userFetch(this.courseID, gts).then((r) => r.users);\n }\n}\n"],"names":["User","UserSearch","constructor","baseUrl","html","js","instance","this","users","getMatchedResults","slice","hasresults","length","searchterm","getSearchTerm","getHTMLElements","searchDropdown","searchInput","removeAttribute","selectAllResultsLink","selectOneLink","userID","url","URL","searchParams","set","toString","fetchDataset","gts","groupID","Repository","userFetch","courseID","then","r"],"mappings":";;;;;;;skCA0BqBA,aAAaC,cAO9BC,YAAYC,sBAEHA,QAAUA,oBAGPA,gBACD,IAAIH,KAAKG,sCAOVC,KAACA,KAADC,GAAOA,UAAY,+BAAiB,qCAAsC,CAC5EC,SAAUC,KAAKD,SACfE,MAAOD,KAAKE,oBAAoBC,MAAM,EAAG,GACzCC,WAAYJ,KAAKE,oBAAoBG,OAAS,EAC9CC,WAAYN,KAAKO,qDAEDP,KAAKQ,kBAAkBC,eAAgBZ,KAAMC,SAE5DY,YAAYC,gBAAgB,yBAOrCC,8BACW,KASXC,cAAcC,cACJC,IAAM,IAAIC,IAAIhB,KAAKJ,gBACzBmB,IAAIE,aAAaC,IAAI,cAAelB,KAAKO,iBACzCQ,IAAIE,aAAaC,IAAI,OAAQ,QAC7BH,IAAIE,aAAaC,IAAI,SAAUJ,QACxBC,IAAII,WAQfC,qBAEUC,IAAgC,iBAAlBrB,KAAKsB,SAA0C,KAAjBtB,KAAKsB,QAAiB,EAAItB,KAAKsB,eAC1EC,WAAWC,UAAUxB,KAAKyB,SAAUJ,KAAKK,MAAMC,GAAMA,EAAE1B"} \ No newline at end of file diff --git a/grade/report/singleview/amd/src/grade.js b/grade/report/singleview/amd/src/grade.js index d63e493be89..e999376743a 100644 --- a/grade/report/singleview/amd/src/grade.js +++ b/grade/report/singleview/amd/src/grade.js @@ -21,7 +21,6 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ import GradeItemSearch from 'core_grades/comboboxsearch/grade'; -import Url from 'core/url'; // Define our standard lookups. const selectors = { @@ -34,12 +33,18 @@ export default class GradeItems extends GradeItemSearch { courseID = component.querySelector(selectors.courseid).dataset.courseid; - constructor() { + /** + * Construct the class. + * + * @param {string} baseUrl The base URL for the page. + */ + constructor(baseUrl) { super(); + this.baseUrl = baseUrl; } - static init() { - return new GradeItems(); + static init(baseUrl) { + return new GradeItems(baseUrl); } /** @@ -49,11 +54,10 @@ export default class GradeItems extends GradeItemSearch { * @returns {string|*} */ selectOneLink(gradeID) { - return Url.relativeUrl('/grade/report/singleview/index.php', { - id: this.courseID, - gradesearchvalue: this.getSearchTerm(), - item: 'grade', - itemid: gradeID, - }, false); + const url = new URL(this.baseUrl); + url.searchParams.set('gradesearchvalue', this.getSearchTerm()); + url.searchParams.set('item', 'grade'); + url.searchParams.set('itemid', gradeID); + return url.toString(); } } diff --git a/grade/report/singleview/amd/src/user.js b/grade/report/singleview/amd/src/user.js index caa16f0640a..df46757da08 100644 --- a/grade/report/singleview/amd/src/user.js +++ b/grade/report/singleview/amd/src/user.js @@ -21,18 +21,23 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ import UserSearch from 'core_user/comboboxsearch/user'; -import Url from 'core/url'; import {renderForPromise, replaceNodeContents} from 'core/templates'; import * as Repository from 'core_grades/searchwidget/repository'; export default class User extends UserSearch { - constructor() { + /** + * Construct the class. + * + * @param {string} baseUrl The base URL for the page. + */ + constructor(baseUrl) { super(); + this.baseUrl = baseUrl; } - static init() { - return new User(); + static init(baseUrl) { + return new User(baseUrl); } /** @@ -65,12 +70,11 @@ export default class User extends UserSearch { * @returns {string|*} */ selectOneLink(userID) { - return Url.relativeUrl('/grade/report/singleview/index.php', { - id: this.courseID, - searchvalue: this.getSearchTerm(), - item: 'user', - userid: userID, - }, false); + const url = new URL(this.baseUrl); + url.searchParams.set('searchvalue', this.getSearchTerm()); + url.searchParams.set('item', 'user'); + url.searchParams.set('userid', userID); + return url.toString(); } /** diff --git a/grade/report/singleview/index.php b/grade/report/singleview/index.php index dd1034330e1..50fc0f5bc31 100644 --- a/grade/report/singleview/index.php +++ b/grade/report/singleview/index.php @@ -164,18 +164,18 @@ if ($PAGE->user_allowed_editing() && !$PAGE->theme->haseditswitch) { $reportname = $report->screen->heading(); +$baseurl = new moodle_url('/grade/report/singleview/index.php', ['id' => $courseid, 'item' => $itemtype]); if ($itemtype == 'user' || $itemtype == 'user_select') { - $PAGE->requires->js_call_amd('gradereport_singleview/user', 'init'); + $PAGE->requires->js_call_amd('gradereport_singleview/user', 'init', [$baseurl->out(false)]); $actionbar = new \gradereport_singleview\output\action_bar($context, $report, 'user'); } else if ($itemtype == 'grade' || $itemtype == 'grade_select') { - $PAGE->requires->js_call_amd('gradereport_singleview/grade', 'init'); + $PAGE->requires->js_call_amd('gradereport_singleview/grade', 'init', [$baseurl->out(false)]); $actionbar = new \gradereport_singleview\output\action_bar($context, $report, 'grade'); } else { $actionbar = new \core_grades\output\general_action_bar($context, new moodle_url('/grade/report/singleview/index.php', ['id' => $courseid]), 'report', 'singleview'); } if ($course->groupmode && $itemtype !== 'select') { - $baseurl = new moodle_url('/grade/report/singleview/index.php', ['id' => $courseid, 'item' => $itemtype]); $PAGE->requires->js_call_amd('core_course/actionbar/group', 'init', [$baseurl->out(false)]); } diff --git a/grade/report/singleview/renderer.php b/grade/report/singleview/renderer.php index caee3494d83..57217313440 100644 --- a/grade/report/singleview/renderer.php +++ b/grade/report/singleview/renderer.php @@ -45,36 +45,24 @@ class gradereport_singleview_renderer extends plugin_renderer_base { * @return string The raw HTML to render. */ public function users_selector(object $course, ?int $userid = null, ?int $groupid = null): string { + $actionbarrenderer = $this->page->get_renderer('core_course', 'actionbar'); $resetlink = new moodle_url('/grade/report/singleview/index.php', ['id' => $course->id, 'group' => $groupid ?? 0]); - $submitteduserid = optional_param('userid', '', PARAM_INT); + $usersearch = ''; - if ($submitteduserid) { - $user = core_user::get_user($submitteduserid); - $currentvalue = fullname($user); - } else { - $currentvalue = ''; + if ($userid) { + $user = core_user::get_user($userid); + $usersearch = fullname($user); } - $data = [ - 'currentvalue' => $currentvalue, - 'courseid' => $course->id, - 'instance' => rand(), - 'group' => $groupid ?? 0, - 'resetlink' => $resetlink->out(false), - 'name' => 'userid', - 'value' => $submitteduserid ?? '', - ]; - $dropdown = new comboboxsearch( - true, - $this->render_from_template('core_user/comboboxsearch/user_selector', $data), - null, - 'user-search d-flex', - null, - 'usersearchdropdown overflow-auto', - null, - false, + return $actionbarrenderer->render( + new \core_course\output\actionbar\user_selector( + course: $course, + resetlink: $resetlink, + userid: $userid, + groupid: $groupid, + usersearch: $usersearch + ) ); - return $this->render_from_template($dropdown->get_template(), $dropdown->export_for_template($this)); } /** diff --git a/grade/report/singleview/tests/behat/gradeitemsearch.feature b/grade/report/singleview/tests/behat/gradeitemsearch.feature index e78f350fbce..cbac97a4bb7 100644 --- a/grade/report/singleview/tests/behat/gradeitemsearch.feature +++ b/grade/report/singleview/tests/behat/gradeitemsearch.feature @@ -22,13 +22,13 @@ Feature: Given we have opted to search for a grade item, Lets find and search th Scenario: A teacher can search for and find a grade item to view Given I click on "Grade items" "link" in the ".page-toggler" "css_element" And I click on ".gradesearchwidget" "css_element" - When I confirm "Test assignment one" in "grade" search within the gradebook widget exists - And I confirm "Test assignment two" in "grade" search within the gradebook widget exists + When I confirm "Test assignment one" exists in the "Search items" search combo box + And I confirm "Test assignment two" exists in the "Search items" search combo box Then I set the field "Search items" to "two" And I wait until "Test assignment one" "option_role" does not exist - And I confirm "Test assignment one" in "grade" search within the gradebook widget does not exist - And I confirm "Test assignment two" in "grade" search within the gradebook widget exists - And I click on "Test assignment two" in the "grade" search widget + And I confirm "Test assignment one" does not exist in the "Search items" search combo box + And I confirm "Test assignment two" exists in the "Search items" search combo box + And I click on "Test assignment two" in the "Search items" search combo box # The search input remains in the field on reload this is in keeping with other search implementations. And I click on ".gradesearchwidget" "css_element" And the field "Search items" matches value "two" diff --git a/grade/report/singleview/tests/behat/reportswitching.feature b/grade/report/singleview/tests/behat/reportswitching.feature index 176b946150b..885ad3afca1 100644 --- a/grade/report/singleview/tests/behat/reportswitching.feature +++ b/grade/report/singleview/tests/behat/reportswitching.feature @@ -20,7 +20,7 @@ Feature: Given we land on the index page, select what type of report we wish to Given I am on the "Course 1" "grades > Single view > View" page logged in as "teacher1" And I click on "Grade items" "link" in the ".page-toggler" "css_element" And "Search users" "field" should not exist - And I confirm "Test assignment one" in "grade" search within the gradebook widget exists + And I confirm "Test assignment one" exists in the "Search items" search combo box When I click on "Users" "link" in the ".page-toggler" "css_element" Then "Search users" "field" should exist And "Select a grade item" "combobox" should not exist diff --git a/grade/report/singleview/tests/behat/singleview.feature b/grade/report/singleview/tests/behat/singleview.feature index 5475a4204fb..9b0583f5940 100644 --- a/grade/report/singleview/tests/behat/singleview.feature +++ b/grade/report/singleview/tests/behat/singleview.feature @@ -60,7 +60,7 @@ Feature: We can use Single view Scenario: I can update grades, add feedback and exclude grades. Given I navigate to "View > Single view" in the course gradebook And I click on "Users" "link" in the ".page-toggler" "css_element" - And I click on "Student" in the "user" search widget + And I click on "Student" in the "Search users" search combo box And I turn editing mode on And I set the field "Override for Test assignment one" to "1" When I set the following fields to these values: @@ -88,7 +88,7 @@ Feature: We can use Single view Then I should see "Grades were set for 2 items" And the field "Grade for Ann, Jill, Grainne, Beauchamp" matches value "12.05" And the field "Exclude for Jane, Nina, Niamh, Cholmondely" matches value "1" - And I click on "new grade item 1" in the "grade" search widget + And I click on "new grade item 1" in the "Search items" search combo box And I set the field "Grade for Ann, Jill, Grainne, Beauchamp" to "Very good" And I press "Save" Then I should see "Grades were set for 1 items" @@ -97,7 +97,7 @@ Feature: We can use Single view | Ann, Jill, Grainne, Beauchamp | Very good | And I am on the "Course 1" "grades > Single view > View" page logged in as "teacher2" And I click on "Users" "link" in the ".page-toggler" "css_element" - And I click on "Student" in the "user" search widget + And I click on "Student" in the "Search users" search combo box And I turn editing mode on And the "Exclude for Test assignment one" "checkbox" should be disabled And the "Override for Test assignment one" "checkbox" should be enabled @@ -157,9 +157,9 @@ Feature: We can use Single view And I open the action menu in "Test assignment four" "table_row" And I choose "Show all grades" in the open action menu Then I should see "Test assignment four" - And I click on "Test assignment three" in the "grade" search widget + And I click on "Test assignment three" in the "Search items" search combo box Then I should see "Test assignment three" - And I click on "Test assignment four" in the "grade" search widget + And I click on "Test assignment four" in the "Search items" search combo box Then I should see "Test assignment four" Scenario: Activities are clickable only when it has a valid activity page. @@ -181,7 +181,7 @@ Feature: We can use Single view Scenario: Teacher sees his last viewed user report when navigating back to the gradebook singleview report. Given I navigate to "View > Single view" in the course gradebook - And I click on "Gronya,Beecham" in the "user" search widget + And I click on "Gronya,Beecham" in the "Search users" search combo box And I should see "Gronya,Beecham" in the "region-main" "region" When I am on the "Course 1" "grades > Single view > View" page Then I should not see "Search for a user to view all their grades" in the "region-main" "region" @@ -192,7 +192,7 @@ Feature: We can use Single view Scenario: Teacher sees his last viewed grade item report when navigating back to the gradebook singleview report. Given I navigate to "View > Single view" in the course gradebook And I click on "Grade items" "link" - And I click on "Test assignment one" in the "grade" search widget + And I click on "Test assignment one" in the "Search items" search combo box And I should see "Test assignment one" in the "region-main" "region" When I am on the "Course 1" "grades > Single view > View" page Then I should not see "Select a grade item above" in the "region-main" "region" @@ -212,9 +212,9 @@ Feature: We can use Single view And I set the field "Group mode" to "Visible groups" And I press "Save and display" And I navigate to "View > Single view" in the course gradebook - And I click on "Nee,Chumlee" in the "user" search widget + And I click on "Nee,Chumlee" in the "Search users" search combo box And I navigate to "View > Grader report" in the course gradebook - And I click on "Group 1" in the "group" search widget + And I click on "Group 1" in the "Search groups" search combo box When I navigate to "View > Single view" in the course gradebook Then I should see "Nee,Chumlee" in the "region-main" "region" And I should not see "Search for a user to view all their grades" in the "region-main" "region" @@ -231,16 +231,16 @@ Feature: We can use Single view And I set the field "Group mode" to "Visible groups" And I press "Save and display" And I navigate to "View > Single view" in the course gradebook - And I click on "Gronya,Beecham" in the "user" search widget + And I click on "Gronya,Beecham" in the "Search users" search combo box And I navigate to "View > Grader report" in the course gradebook - And I click on "Group 1" in the "group" search widget + And I click on "Group 1" in the "Search groups" search combo box When I navigate to "View > Single view" in the course gradebook Then I should see "Search for a user to view all their grades" in the "region-main" "region" And I should not see "Gronya,Beecham" in the "region-main" "region" Scenario: Teacher does not see his last viewed user report if that user is no longer enrolled in the course. Given I navigate to "View > Single view" in the course gradebook - And I click on "Gronya,Beecham" in the "user" search widget + And I click on "Gronya,Beecham" in the "Search users" search combo box And I navigate to course participants And I click on "Unenrol" "icon" in the "Gronya,Beecham" "table_row" And I click on "Unenrol" "button" in the "Unenrol" "dialogue" @@ -251,7 +251,7 @@ Feature: We can use Single view Scenario: Teacher does not see his last viewed grade item report if the item no longer exists in the course. Given I navigate to "View > Single view" in the course gradebook And I click on "Grade items" "link" - And I click on "Test assignment four" in the "grade" search widget + And I click on "Test assignment four" in the "Search items" search combo box And I am on "Course 1" course homepage with editing mode on And I delete "Test assignment four" activity And I run all adhoc tasks diff --git a/grade/report/singleview/tests/behat/usersearch.feature b/grade/report/singleview/tests/behat/usersearch.feature index 0540d5ce535..d47cfb08812 100644 --- a/grade/report/singleview/tests/behat/usersearch.feature +++ b/grade/report/singleview/tests/behat/usersearch.feature @@ -37,8 +37,8 @@ Feature: Within the singleview report, a teacher can search for users. Given I should see "Search users" And I should see "Search for a user to view all their grades" When I set the field "Search users" to "Turtle" - And I confirm "Turtle Manatee" in "user" search within the gradebook widget exists - And I confirm "User Example" in "user" search within the gradebook widget does not exist + And I confirm "Turtle Manatee" exists in the "Search users" search combo box + And I confirm "User Example" does not exist in the "Search users" search combo box And I click on "Turtle Manatee" "list_item" # Business case: This will trigger a page reload and can not dynamically update the table. And I wait until the page is ready @@ -55,7 +55,7 @@ Feature: Within the singleview report, a teacher can search for users. Scenario: A teacher can search the single view report to find specified users # Case: Standard search. - Given I click on "Dummy" in the "user" search widget + Given I click on "Dummy" in the "Search users" search combo box And "Dummy User" "heading" should exist And "Teacher 1" "heading" should not exist And "Student 1" "heading" should not exist @@ -77,14 +77,14 @@ Feature: Within the singleview report, a teacher can search for users. # Case: Multiple users found and select only one result. Then I set the field "Search users" to "User" And I wait until "Dummy User" "option_role" exists - And I confirm "Dummy User" in "user" search within the gradebook widget exists - And I confirm "User Example" in "user" search within the gradebook widget exists - And I confirm "User Test" in "user" search within the gradebook widget exists - And I confirm "Turtle Manatee" in "user" search within the gradebook widget does not exist + And I confirm "Dummy User" exists in the "Search users" search combo box + And I confirm "User Example" exists in the "Search users" search combo box + And I confirm "User Test" exists in the "Search users" search combo box + And I confirm "Turtle Manatee" does not exist in the "Search users" search combo box # Check if the matched field names (by lines) includes some identifiable info to help differentiate similar users. - And I confirm "User (student2@example.com)" in "user" search within the gradebook widget exists - And I confirm "User (student3@example.com)" in "user" search within the gradebook widget exists - And I confirm "User (student4@example.com)" in "user" search within the gradebook widget exists + And I confirm "User (student2@example.com)" exists in the "Search users" search combo box + And I confirm "User (student3@example.com)" exists in the "Search users" search combo box + And I confirm "User (student4@example.com)" exists in the "Search users" search combo box And I click on "Dummy User" "list_item" And I wait until the page is ready And "Dummy User" "heading" should exist @@ -101,7 +101,7 @@ Feature: Within the singleview report, a teacher can search for users. And I wait until "No results for \"a\"" "text" exists Scenario: A teacher can quickly tell that a search is active on the current table - Given I click on "Turtle" in the "user" search widget + Given I click on "Turtle" in the "Search users" search combo box And I wait until the page is ready # The search input remains in the field on reload this is in keeping with other search implementations. When the field "Search users" matches value "Turtle Manatee" @@ -118,55 +118,55 @@ Feature: Within the singleview report, a teacher can search for users. And I set the field "Search users" to "@example.com" And I wait until "Dummy User" "list_item" exists # Note: All learners match this email & showing emails is current default. - And I confirm "Dummy User" in "user" search within the gradebook widget exists - And I confirm "User Example" in "user" search within the gradebook widget exists - And I confirm "User Test" in "user" search within the gradebook widget exists - And I confirm "Student 1" in "user" search within the gradebook widget exists - And I confirm "Turtle Manatee" in "user" search within the gradebook widget exists + And I confirm "Dummy User" exists in the "Search users" search combo box + And I confirm "User Example" exists in the "Search users" search combo box + And I confirm "User Test" exists in the "Search users" search combo box + And I confirm "Student 1" exists in the "Search users" search combo box + And I confirm "Turtle Manatee" exists in the "Search users" search combo box # Search on the country field. When I set the field "Search users" to "JP" And I wait until "Dummy User" "list_item" exists And I wait until "Turtle Manatee" "list_item" does not exist - And I confirm "Dummy User" in "user" search within the gradebook widget exists - And I confirm "User Test" in "user" search within the gradebook widget exists + And I confirm "Dummy User" exists in the "Search users" search combo box + And I confirm "User Test" exists in the "Search users" search combo box # Search on the city field. And I set the field "Search users" to "Hanoi" And I wait until "User Test" "list_item" does not exist - Then I confirm "Student 1" in "user" search within the gradebook widget exists + Then I confirm "Student 1" exists in the "Search users" search combo box # Search on the institution field. And I set the field "Search users" to "ABCD" And I wait until "Dummy User" "list_item" exists - And I confirm "User Example" in "user" search within the gradebook widget exists - And I confirm "User Test" in "user" search within the gradebook widget exists - And I confirm "Student 1" in "user" search within the gradebook widget exists - And I confirm "Turtle Manatee" in "user" search within the gradebook widget exists + And I confirm "User Example" exists in the "Search users" search combo box + And I confirm "User Test" exists in the "Search users" search combo box + And I confirm "Student 1" exists in the "Search users" search combo box + And I confirm "Turtle Manatee" exists in the "Search users" search combo box # Search on the department field. And I set the field "Search users" to "ABC3" And I wait until "User Example" "list_item" does not exist - And I confirm "User Test" in "user" search within the gradebook widget exists - And I confirm "Turtle Manatee" in "user" search within the gradebook widget exists + And I confirm "User Test" exists in the "Search users" search combo box + And I confirm "Turtle Manatee" exists in the "Search users" search combo box # Search on the phone1 field. And I set the field "Search users" to "4365899871" And I wait until "User Test" "list_item" does not exist - And I confirm "Dummy User" in "user" search within the gradebook widget exists + And I confirm "Dummy User" exists in the "Search users" search combo box # Search on the phone2 field. And I set the field "Search users" to "2149871323" And I wait until "Dummy User" "list_item" does not exist - And I confirm "User Test" in "user" search within the gradebook widget exists + And I confirm "User Test" exists in the "Search users" search combo box # Search on the institution field then press enter to show the record set. And I set the field "Search users" to "ABC" And "Turtle Manatee" "list_item" should exist - And I confirm "Dummy User" in "user" search within the gradebook widget exists - And I confirm "User Example" in "user" search within the gradebook widget exists - And I confirm "User Test" in "user" search within the gradebook widget exists - And I confirm "Student 1" in "user" search within the gradebook widget exists + And I confirm "Dummy User" exists in the "Search users" search combo box + And I confirm "User Example" exists in the "Search users" search combo box + And I confirm "User Test" exists in the "Search users" search combo box + And I confirm "Student 1" exists in the "Search users" search combo box And I press the down key And I press the enter key And I wait until the page is ready @@ -219,4 +219,4 @@ Feature: Within the singleview report, a teacher can search for users. And I press the tab key And the focused element is "Clear search input" "button" in the ".user-search" "css_element" And I press the enter key - And I confirm "Turtle Manatee" in "user" search within the gradebook widget does not exist + And I confirm "Turtle Manatee" does not exist in the "Search users" search combo box diff --git a/grade/report/user/amd/build/user.min.js b/grade/report/user/amd/build/user.min.js index 754146210fd..0cefe288bdd 100644 --- a/grade/report/user/amd/build/user.min.js +++ b/grade/report/user/amd/build/user.min.js @@ -1,10 +1,10 @@ -define("gradereport_user/user",["exports","core_user/comboboxsearch/user","core/url","core/templates","core_grades/searchwidget/repository"],(function(_exports,_user,_url,_templates,Repository){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}} +define("gradereport_user/user",["exports","core_user/comboboxsearch/user","core/templates","core_grades/searchwidget/repository"],(function(_exports,_user,_templates,Repository){var obj; /** * Allow the user to search for learners within the user report. * * @module gradereport_user/user * @copyright 2023 Mathew May * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_user=_interopRequireDefault(_user),_url=_interopRequireDefault(_url),Repository=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(Repository);class User extends _user.default{constructor(){super()}static init(){return new User}async renderDropdown(){const{html:html,js:js}=await(0,_templates.renderForPromise)("core_user/comboboxsearch/resultset",{users:this.getMatchedResults().slice(0,5),hasresults:this.getMatchedResults().length>0,instance:this.instance,matches:this.getDatasetSize(),searchterm:this.getSearchTerm(),selectall:this.selectAllResultsLink()});(0,_templates.replaceNodeContents)(this.getHTMLElements().searchDropdown,html,js),this.searchInput.removeAttribute("aria-activedescendant")}selectAllResultsLink(){return _url.default.relativeUrl("/grade/report/user/index.php",{id:this.courseID,userid:0,searchvalue:this.getSearchTerm()},!1)}selectOneLink(userID){return _url.default.relativeUrl("/grade/report/user/index.php",{id:this.courseID,searchvalue:this.getSearchTerm(),userid:userID},!1)}fetchDataset(){const gts="string"==typeof this.groupID&&""===this.groupID?0:this.groupID;return Repository.userFetch(this.courseID,gts).then((r=>r.users))}}return _exports.default=User,_exports.default})); + */function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_user=(obj=_user)&&obj.__esModule?obj:{default:obj},Repository=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(Repository);class User extends _user.default{constructor(baseUrl){super(),this.baseUrl=baseUrl}static init(baseUrl){return new User(baseUrl)}async renderDropdown(){const{html:html,js:js}=await(0,_templates.renderForPromise)("core_user/comboboxsearch/resultset",{users:this.getMatchedResults().slice(0,5),hasresults:this.getMatchedResults().length>0,instance:this.instance,matches:this.getDatasetSize(),searchterm:this.getSearchTerm(),selectall:this.selectAllResultsLink()});(0,_templates.replaceNodeContents)(this.getHTMLElements().searchDropdown,html,js),this.searchInput.removeAttribute("aria-activedescendant")}selectAllResultsLink(){const url=new URL(this.baseUrl);return url.searchParams.set("userid",0),url.searchParams.set("searchvalue",this.getSearchTerm()),url.toString()}selectOneLink(userID){const url=new URL(this.baseUrl);return url.searchParams.set("userid",userID),url.searchParams.set("searchvalue",this.getSearchTerm()),url.toString()}fetchDataset(){const gts="string"==typeof this.groupID&&""===this.groupID?0:this.groupID;return Repository.userFetch(this.courseID,gts).then((r=>r.users))}}return _exports.default=User,_exports.default})); //# sourceMappingURL=user.min.js.map \ No newline at end of file diff --git a/grade/report/user/amd/build/user.min.js.map b/grade/report/user/amd/build/user.min.js.map index 0ecff160bb2..db89acd630f 100644 --- a/grade/report/user/amd/build/user.min.js.map +++ b/grade/report/user/amd/build/user.min.js.map @@ -1 +1 @@ -{"version":3,"file":"user.min.js","sources":["../src/user.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\n/**\n * Allow the user to search for learners within the user report.\n *\n * @module gradereport_user/user\n * @copyright 2023 Mathew May \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport UserSearch from 'core_user/comboboxsearch/user';\nimport Url from 'core/url';\nimport {renderForPromise, replaceNodeContents} from 'core/templates';\nimport * as Repository from 'core_grades/searchwidget/repository';\n\nexport default class User extends UserSearch {\n\n constructor() {\n super();\n }\n\n static init() {\n return new User();\n }\n\n /**\n * Build the content then replace the node.\n */\n async renderDropdown() {\n const {html, js} = await renderForPromise('core_user/comboboxsearch/resultset', {\n users: this.getMatchedResults().slice(0, 5),\n hasresults: this.getMatchedResults().length > 0,\n instance: this.instance,\n matches: this.getDatasetSize(),\n searchterm: this.getSearchTerm(),\n selectall: this.selectAllResultsLink(),\n });\n replaceNodeContents(this.getHTMLElements().searchDropdown, html, js);\n // Remove aria-activedescendant when the available options change.\n this.searchInput.removeAttribute('aria-activedescendant');\n }\n\n /**\n * Build up the view all link.\n *\n * @returns {string|*}\n */\n selectAllResultsLink() {\n return Url.relativeUrl('/grade/report/user/index.php', {\n id: this.courseID,\n userid: 0,\n searchvalue: this.getSearchTerm()\n }, false);\n }\n\n /**\n * Build up the link that is dedicated to a particular result.\n *\n * @param {Number} userID The ID of the user selected.\n * @returns {string|*}\n */\n selectOneLink(userID) {\n return Url.relativeUrl('/grade/report/user/index.php', {\n id: this.courseID,\n searchvalue: this.getSearchTerm(),\n userid: userID,\n }, false);\n }\n\n /**\n * Get the data we will be searching against in this component.\n *\n * @returns {Promise<*>}\n */\n fetchDataset() {\n // Small typing checks as sometimes groups don't exist therefore the element returns a empty string.\n const gts = typeof (this.groupID) === \"string\" && this.groupID === '' ? 0 : this.groupID;\n return Repository.userFetch(this.courseID, gts).then((r) => r.users);\n }\n}\n"],"names":["User","UserSearch","constructor","html","js","users","this","getMatchedResults","slice","hasresults","length","instance","matches","getDatasetSize","searchterm","getSearchTerm","selectall","selectAllResultsLink","getHTMLElements","searchDropdown","searchInput","removeAttribute","Url","relativeUrl","id","courseID","userid","searchvalue","selectOneLink","userID","fetchDataset","gts","groupID","Repository","userFetch","then","r"],"mappings":";;;;;;;q0BA2BqBA,aAAaC,cAE9BC,2CAKW,IAAIF,kCAOLG,KAACA,KAADC,GAAOA,UAAY,+BAAiB,qCAAsC,CAC5EC,MAAOC,KAAKC,oBAAoBC,MAAM,EAAG,GACzCC,WAAYH,KAAKC,oBAAoBG,OAAS,EAC9CC,SAAUL,KAAKK,SACfC,QAASN,KAAKO,iBACdC,WAAYR,KAAKS,gBACjBC,UAAWV,KAAKW,4DAEAX,KAAKY,kBAAkBC,eAAgBhB,KAAMC,SAE5DgB,YAAYC,gBAAgB,yBAQrCJ,8BACWK,aAAIC,YAAY,+BAAgC,CACnDC,GAAIlB,KAAKmB,SACTC,OAAQ,EACRC,YAAarB,KAAKS,kBACnB,GASPa,cAAcC,eACHP,aAAIC,YAAY,+BAAgC,CACnDC,GAAIlB,KAAKmB,SACTE,YAAarB,KAAKS,gBAClBW,OAAQG,SACT,GAQPC,qBAEUC,IAAgC,iBAAlBzB,KAAK0B,SAA0C,KAAjB1B,KAAK0B,QAAiB,EAAI1B,KAAK0B,eAC1EC,WAAWC,UAAU5B,KAAKmB,SAAUM,KAAKI,MAAMC,GAAMA,EAAE/B"} \ No newline at end of file +{"version":3,"file":"user.min.js","sources":["../src/user.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\n/**\n * Allow the user to search for learners within the user report.\n *\n * @module gradereport_user/user\n * @copyright 2023 Mathew May \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport UserSearch from 'core_user/comboboxsearch/user';\nimport {renderForPromise, replaceNodeContents} from 'core/templates';\nimport * as Repository from 'core_grades/searchwidget/repository';\n\nexport default class User extends UserSearch {\n\n /**\n * Construct the class.\n *\n * @param {string} baseUrl The base URL for the page.\n */\n constructor(baseUrl) {\n super();\n this.baseUrl = baseUrl;\n }\n\n static init(baseUrl) {\n return new User(baseUrl);\n }\n\n /**\n * Build the content then replace the node.\n */\n async renderDropdown() {\n const {html, js} = await renderForPromise('core_user/comboboxsearch/resultset', {\n users: this.getMatchedResults().slice(0, 5),\n hasresults: this.getMatchedResults().length > 0,\n instance: this.instance,\n matches: this.getDatasetSize(),\n searchterm: this.getSearchTerm(),\n selectall: this.selectAllResultsLink(),\n });\n replaceNodeContents(this.getHTMLElements().searchDropdown, html, js);\n // Remove aria-activedescendant when the available options change.\n this.searchInput.removeAttribute('aria-activedescendant');\n }\n\n /**\n * Build up the view all link.\n *\n * @returns {string|*}\n */\n selectAllResultsLink() {\n const url = new URL(this.baseUrl);\n url.searchParams.set('userid', 0);\n url.searchParams.set('searchvalue', this.getSearchTerm());\n return url.toString();\n }\n\n /**\n * Build up the link that is dedicated to a particular result.\n *\n * @param {Number} userID The ID of the user selected.\n * @returns {string|*}\n */\n selectOneLink(userID) {\n const url = new URL(this.baseUrl);\n url.searchParams.set('userid', userID);\n url.searchParams.set('searchvalue', this.getSearchTerm());\n return url.toString();\n }\n\n /**\n * Get the data we will be searching against in this component.\n *\n * @returns {Promise<*>}\n */\n fetchDataset() {\n // Small typing checks as sometimes groups don't exist therefore the element returns a empty string.\n const gts = typeof (this.groupID) === \"string\" && this.groupID === '' ? 0 : this.groupID;\n return Repository.userFetch(this.courseID, gts).then((r) => r.users);\n }\n}\n"],"names":["User","UserSearch","constructor","baseUrl","html","js","users","this","getMatchedResults","slice","hasresults","length","instance","matches","getDatasetSize","searchterm","getSearchTerm","selectall","selectAllResultsLink","getHTMLElements","searchDropdown","searchInput","removeAttribute","url","URL","searchParams","set","toString","selectOneLink","userID","fetchDataset","gts","groupID","Repository","userFetch","courseID","then","r"],"mappings":";;;;;;;skCA0BqBA,aAAaC,cAO9BC,YAAYC,sBAEHA,QAAUA,oBAGPA,gBACD,IAAIH,KAAKG,sCAOVC,KAACA,KAADC,GAAOA,UAAY,+BAAiB,qCAAsC,CAC5EC,MAAOC,KAAKC,oBAAoBC,MAAM,EAAG,GACzCC,WAAYH,KAAKC,oBAAoBG,OAAS,EAC9CC,SAAUL,KAAKK,SACfC,QAASN,KAAKO,iBACdC,WAAYR,KAAKS,gBACjBC,UAAWV,KAAKW,4DAEAX,KAAKY,kBAAkBC,eAAgBhB,KAAMC,SAE5DgB,YAAYC,gBAAgB,yBAQrCJ,6BACUK,IAAM,IAAIC,IAAIjB,KAAKJ,gBACzBoB,IAAIE,aAAaC,IAAI,SAAU,GAC/BH,IAAIE,aAAaC,IAAI,cAAenB,KAAKS,iBAClCO,IAAII,WASfC,cAAcC,cACJN,IAAM,IAAIC,IAAIjB,KAAKJ,gBACzBoB,IAAIE,aAAaC,IAAI,SAAUG,QAC/BN,IAAIE,aAAaC,IAAI,cAAenB,KAAKS,iBAClCO,IAAII,WAQfG,qBAEUC,IAAgC,iBAAlBxB,KAAKyB,SAA0C,KAAjBzB,KAAKyB,QAAiB,EAAIzB,KAAKyB,eAC1EC,WAAWC,UAAU3B,KAAK4B,SAAUJ,KAAKK,MAAMC,GAAMA,EAAE/B"} \ No newline at end of file diff --git a/grade/report/user/amd/src/user.js b/grade/report/user/amd/src/user.js index bdc8d24a46c..a738f43aa49 100644 --- a/grade/report/user/amd/src/user.js +++ b/grade/report/user/amd/src/user.js @@ -21,18 +21,23 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ import UserSearch from 'core_user/comboboxsearch/user'; -import Url from 'core/url'; import {renderForPromise, replaceNodeContents} from 'core/templates'; import * as Repository from 'core_grades/searchwidget/repository'; export default class User extends UserSearch { - constructor() { + /** + * Construct the class. + * + * @param {string} baseUrl The base URL for the page. + */ + constructor(baseUrl) { super(); + this.baseUrl = baseUrl; } - static init() { - return new User(); + static init(baseUrl) { + return new User(baseUrl); } /** @@ -58,11 +63,10 @@ export default class User extends UserSearch { * @returns {string|*} */ selectAllResultsLink() { - return Url.relativeUrl('/grade/report/user/index.php', { - id: this.courseID, - userid: 0, - searchvalue: this.getSearchTerm() - }, false); + const url = new URL(this.baseUrl); + url.searchParams.set('userid', 0); + url.searchParams.set('searchvalue', this.getSearchTerm()); + return url.toString(); } /** @@ -72,11 +76,10 @@ export default class User extends UserSearch { * @returns {string|*} */ selectOneLink(userID) { - return Url.relativeUrl('/grade/report/user/index.php', { - id: this.courseID, - searchvalue: this.getSearchTerm(), - userid: userID, - }, false); + const url = new URL(this.baseUrl); + url.searchParams.set('userid', userID); + url.searchParams.set('searchvalue', this.getSearchTerm()); + return url.toString(); } /** diff --git a/grade/report/user/classes/output/action_bar.php b/grade/report/user/classes/output/action_bar.php index 254c4e049cc..e21c58ee7fb 100644 --- a/grade/report/user/classes/output/action_bar.php +++ b/grade/report/user/classes/output/action_bar.php @@ -37,6 +37,9 @@ class action_bar extends \core_grades\output\action_bar { /** @var int|null $currentgroupid The user report view mode. */ protected $currentgroupid; + /** @var string $usersearch String to search matching users. */ + protected $usersearch; + /** * The class constructor. * @@ -44,12 +47,20 @@ class action_bar extends \core_grades\output\action_bar { * @param int $userview The user report view mode. * @param int|null $userid The user ID or 0 if displaying all users. * @param int|null $currentgroupid The ID of the current group. + * @param string $usersearch String to search matching user. */ - public function __construct(\context $context, int $userview, ?int $userid = null, ?int $currentgroupid = null) { + public function __construct( + \context $context, + int $userview, + ?int $userid = null, + ?int $currentgroupid = null, + string $usersearch = '' + ) { parent::__construct($context); $this->userview = $userview; $this->userid = $userid; $this->currentgroupid = $currentgroupid; + $this->usersearch = $usersearch; } /** @@ -88,7 +99,12 @@ class action_bar extends \core_grades\output\action_bar { } $data['userselector'] = [ 'courseid' => $courseid, - 'content' => $userreportrenderer->users_selector(get_course($courseid), $this->userid, $this->currentgroupid) + 'content' => $userreportrenderer->users_selector( + course: get_course($courseid), + userid: $this->userid, + groupid: $this->currentgroupid, + usersearch: $this->usersearch + ), ]; // Do not output the 'view mode' selector when in zero state or when the current user is viewing its own report. diff --git a/grade/report/user/index.php b/grade/report/user/index.php index d5cd825223c..b481c4faf58 100644 --- a/grade/report/user/index.php +++ b/grade/report/user/index.php @@ -28,6 +28,7 @@ require_once $CFG->dirroot.'/grade/lib.php'; require_once $CFG->dirroot.'/grade/report/user/lib.php'; $courseid = required_param('id', PARAM_INT); +// 0 - view all reports. null - view own report. non-zero and non-null - view other user report. $userid = optional_param('userid', null, PARAM_INT); $userview = optional_param('userview', 0, PARAM_INT); diff --git a/grade/report/user/renderer.php b/grade/report/user/renderer.php index bae070df34e..e403a51ce0d 100644 --- a/grade/report/user/renderer.php +++ b/grade/report/user/renderer.php @@ -88,42 +88,23 @@ class gradereport_user_renderer extends plugin_renderer_base { * @param object $course The course object. * @param int|null $userid The user ID. * @param int|null $groupid The group ID. + * @param string $usersearch Search string. * @return string The raw HTML to render. * @throws coding_exception */ - public function users_selector(object $course, ?int $userid = null, ?int $groupid = null): string { + public function users_selector(object $course, ?int $userid = null, ?int $groupid = null, string $usersearch = ''): string { + $actionbarrenderer = $this->page->get_renderer('core_course', 'actionbar'); $resetlink = new moodle_url('/grade/report/user/index.php', ['id' => $course->id, 'group' => 0]); - $submitteduserid = optional_param('userid', '', PARAM_INT); - - if ($submitteduserid) { - $user = core_user::get_user($submitteduserid); - $currentvalue = fullname($user); - } else { - $currentvalue = ''; - } - - $data = [ - 'currentvalue' => $currentvalue, - 'instance' => rand(), - 'resetlink' => $resetlink->out(false), - 'name' => 'userid', - 'value' => $submitteduserid ?? '', - 'courseid' => $course->id, - 'group' => $groupid ?? 0, - ]; - - $searchdropdown = new comboboxsearch( - true, - $this->render_from_template('core_user/comboboxsearch/user_selector', $data), - null, - 'user-search d-flex', - null, - 'usersearchdropdown overflow-auto', - null, - false, + $baseurl = new moodle_url('/grade/report/user/index.php', ['id' => $course->id]); + $this->page->requires->js_call_amd('gradereport_user/user', 'init', [$baseurl->out(false)]); + $userselector = new \core_course\output\actionbar\user_selector( + course: $course, + resetlink: $resetlink, + userid: $userid, + groupid: $groupid, + usersearch: $usersearch ); - $this->page->requires->js_call_amd('gradereport_user/user', 'init'); - return $this->render_from_template($searchdropdown->get_template(), $searchdropdown->export_for_template($this)); + return $actionbarrenderer->render($userselector); } /** diff --git a/grade/report/user/tests/behat/groupsearch.feature b/grade/report/user/tests/behat/groupsearch.feature index a32e27c2d9c..42e65ebcf1c 100644 --- a/grade/report/user/tests/behat/groupsearch.feature +++ b/grade/report/user/tests/behat/groupsearch.feature @@ -38,13 +38,13 @@ Feature: Group searching functionality within the user report. Then ".groupsearchwidget" "css_element" should not exist Scenario: A teacher can search for and find a group to find a user in - Given I confirm "Tutor group" in "group" search within the gradebook widget exists - And I confirm "Marker group" in "group" search within the gradebook widget exists + Given I confirm "Tutor group" exists in the "Search groups" search combo box + And I confirm "Marker group" exists in the "Search groups" search combo box When I set the field "Search groups" to "tutor" And I wait "1" seconds - Then I confirm "Tutor group" in "group" search within the gradebook widget exists - And I confirm "Marker group" in "group" search within the gradebook widget does not exist - And I click on "Tutor group" in the "group" search widget + Then I confirm "Tutor group" exists in the "Search groups" search combo box + And I confirm "Marker group" does not exist in the "Search groups" search combo box + And I click on "Tutor group" in the "Search groups" search combo box # The search input remains in the field on reload this is in keeping with other search implementations. And I click on ".groupsearchwidget" "css_element" And the field "Search groups" matches value "tutor" @@ -54,22 +54,22 @@ Feature: Group searching functionality within the user report. Scenario: A teacher can only see the group members in the 'user' search widget after selecting a group option # Confirm that all users are initially displayed in the 'user' search widget. Given I set the field "Search users" to "Student" - And I confirm "Student 1" in "user" search within the gradebook widget exists - And I confirm "Student 2" in "user" search within the gradebook widget exists + And I confirm "Student 1" exists in the "Search users" search combo box + And I confirm "Student 2" exists in the "Search users" search combo box # Select a particular group from the 'group' search widget. - When I click on "Default group" in the "group" search widget + When I click on "Default group" in the "Search groups" search combo box # Confirm that only users which are members of the selected group are displayed in the 'user' search widget. And I set the field "Search users" to "Student" - Then I confirm "Student 1" in "user" search within the gradebook widget exists - And I confirm "Student 2" in "user" search within the gradebook widget does not exist - And I click on "Tutor group" in the "group" search widget + Then I confirm "Student 1" exists in the "Search users" search combo box + And I confirm "Student 2" does not exist in the "Search users" search combo box + And I click on "Tutor group" in the "Search groups" search combo box And I set the field "Search users" to "Student" - And I confirm "Student 1" in "user" search within the gradebook widget does not exist - And I confirm "Student 2" in "user" search within the gradebook widget does not exist - And I click on "All participants" in the "group" search widget + And I confirm "Student 1" does not exist in the "Search users" search combo box + And I confirm "Student 2" does not exist in the "Search users" search combo box + And I click on "All participants" in the "Search groups" search combo box And I set the field "Search users" to "Student" - And I confirm "Student 1" in "user" search within the gradebook widget exists - And I confirm "Student 2" in "user" search within the gradebook widget exists + And I confirm "Student 1" exists in the "Search users" search combo box + And I confirm "Student 2" exists in the "Search users" search combo box @accessibility Scenario: A teacher can set focus and search using the input with a keyboard diff --git a/grade/report/user/tests/behat/toggle_grade_categories.feature b/grade/report/user/tests/behat/toggle_grade_categories.feature index ddcd995c9e6..55429c840c6 100644 --- a/grade/report/user/tests/behat/toggle_grade_categories.feature +++ b/grade/report/user/tests/behat/toggle_grade_categories.feature @@ -28,7 +28,7 @@ Feature: User can toggle the visibility of the grade categories within the user Scenario: A teacher can search for and find a user to view Given I am on the "Course" "grades > User report > View" page logged in as "teacher1" - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box And I should see "Test assignment one" in the "user-grade" "table" And I should see "Test assignment two" in the "user-grade" "table" And I should see "Category 1 total" in the "user-grade" "table" diff --git a/grade/report/user/tests/behat/user_report_navigation.feature b/grade/report/user/tests/behat/user_report_navigation.feature index 00dd1212eb9..706049ae077 100644 --- a/grade/report/user/tests/behat/user_report_navigation.feature +++ b/grade/report/user/tests/behat/user_report_navigation.feature @@ -26,7 +26,7 @@ Feature: Teacher can navigate to the previous or next user report. And I am on the "Course" "grades > User report > View" page logged in as "teacher1" Scenario: A teacher can navigate to the next user report - Given I click on "Student 1" in the "user" search widget + Given I click on "Student 1" in the "Search users" search combo box And "Student 1" "heading" should exist And ".previous" "css_element" should not exist in the ".user-navigation" "css_element" And ".next" "css_element" should exist in the ".user-navigation" "css_element" @@ -44,7 +44,7 @@ Feature: Teacher can navigate to the previous or next user report. And ".next" "css_element" should not exist in the ".user-navigation" "css_element" Scenario: A teacher can navigate to the previous user report - Given I click on "Student 3" in the "user" search widget + Given I click on "Student 3" in the "Search users" search combo box And "Student 3" "heading" should exist And ".previous" "css_element" should exist in the ".user-navigation" "css_element" And I should see "Student 2" in the ".previous" "css_element" diff --git a/grade/report/user/tests/behat/user_view.feature b/grade/report/user/tests/behat/user_view.feature index 388b21910ca..38f4ea2cc5d 100644 --- a/grade/report/user/tests/behat/user_view.feature +++ b/grade/report/user/tests/behat/user_view.feature @@ -52,7 +52,7 @@ Feature: View the user report as the student will see it | activity | course | idnumber | name | intro | grade | | quiz | C1 | q1 | Test quiz one | Submit something! | 100 | When I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box And I should see "Course 1 & '\"" And I should not see "Course 1 & '\"" And I set the field "View report as" to "Myself" @@ -77,7 +77,7 @@ Feature: View the user report as the student will see it | activity | course | idnumber | name | intro | grade | | quiz | C1 | q1 | Test quiz one | Submit something! | 100 | When I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box And I set the field "View report as" to "User" Then the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | @@ -126,7 +126,7 @@ Feature: View the user report as the student will see it And I set the field with xpath "//select[@name='report_user_showtotalsifcontainhidden']" to "Show totals excluding hidden items" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - When I click on "Student 1" in the "user" search widget + When I click on "Student 1" in the "Search users" search combo box And I set the field "View report as" to "User" Then the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | @@ -163,7 +163,7 @@ Feature: View the user report as the student will see it And I set the field with xpath "//select[@name='report_user_showtotalsifcontainhidden']" to "Show totals including hidden items" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - When I click on "Student 1" in the "user" search widget + When I click on "Student 1" in the "Search users" search combo box And I set the field "View report as" to "User" Then the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | @@ -204,7 +204,7 @@ Feature: View the user report as the student will see it And I set the field with xpath "//select[@name='report_user_showtotalsifcontainhidden']" to "Show totals excluding hidden items" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - When I click on "Student 1" in the "user" search widget + When I click on "Student 1" in the "Search users" search combo box And I set the field "View report as" to "User" Then the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | diff --git a/grade/report/user/tests/behat/usersearch.feature b/grade/report/user/tests/behat/usersearch.feature index 6f969081be2..370acd7a3d2 100644 --- a/grade/report/user/tests/behat/usersearch.feature +++ b/grade/report/user/tests/behat/usersearch.feature @@ -38,8 +38,8 @@ Feature: Within the User report, a teacher can search for users. And I should see "Search for a user to view their report" When I set the field "Search users" to "Turtle" And "View all results (5)" "option_role" should exist - And I confirm "Turtle Manatee" in "user" search within the gradebook widget exists - And I confirm "User Example" in "user" search within the gradebook widget does not exist + And I confirm "Turtle Manatee" exists in the "Search users" search combo box + And I confirm "User Example" does not exist in the "Search users" search combo box And I click on "Turtle Manatee" "list_item" # Business case: This will trigger a page reload and can not dynamically update the table. And I wait until the page is ready @@ -56,7 +56,7 @@ Feature: Within the User report, a teacher can search for users. Scenario: A teacher can search the user report to find specified users # Case: Standard search. - Given I click on "Dummy" in the "user" search widget + Given I click on "Dummy" in the "Search users" search combo box And "Dummy User" "heading" should exist And "Teacher 1" "heading" should not exist And "Student 1" "heading" should not exist @@ -77,14 +77,14 @@ Feature: Within the User report, a teacher can search for users. # Case: Multiple users found and select only one result. Then I set the field "Search users" to "User" And "View all results (5)" "option_role" should exist - And I confirm "Dummy User" in "user" search within the gradebook widget exists - And I confirm "User Example" in "user" search within the gradebook widget exists - And I confirm "User Test" in "user" search within the gradebook widget exists - And I confirm "Turtle Manatee" in "user" search within the gradebook widget does not exist + And I confirm "Dummy User" exists in the "Search users" search combo box + And I confirm "User Example" exists in the "Search users" search combo box + And I confirm "User Test" exists in the "Search users" search combo box + And I confirm "Turtle Manatee" does not exist in the "Search users" search combo box # Check if the matched field names (by lines) includes some identifiable info to help differentiate similar users. - And I confirm "User (student2@example.com)" in "user" search within the gradebook widget exists - And I confirm "User (student3@example.com)" in "user" search within the gradebook widget exists - And I confirm "User (student4@example.com)" in "user" search within the gradebook widget exists + And I confirm "User (student2@example.com)" exists in the "Search users" search combo box + And I confirm "User (student3@example.com)" exists in the "Search users" search combo box + And I confirm "User (student4@example.com)" exists in the "Search users" search combo box And I click on "Dummy User" "list_item" And I wait until the page is ready And "Dummy User" "heading" should exist @@ -121,7 +121,7 @@ Feature: Within the User report, a teacher can search for users. And I should see "No results for \"a\"" Scenario: A teacher can quickly tell that a search is active on the current table - When I click on "Turtle" in the "user" search widget + When I click on "Turtle" in the "Search users" search combo box # The search input should contain the name of the user we have selected, so that it is clear that the result pertains to a specific user. Then the field "Search users" matches value "Turtle Manatee" And I wait until "View all results (5)" "link" does not exist @@ -137,55 +137,55 @@ Feature: Within the User report, a teacher can search for users. And I set the field "Search users" to "@example.com" And "View all results (5)" "option_role" should exist # Note: All learners match this email & showing emails is current default. - And I confirm "Dummy User" in "user" search within the gradebook widget exists - And I confirm "User Example" in "user" search within the gradebook widget exists - And I confirm "User Test" in "user" search within the gradebook widget exists - And I confirm "Student 1" in "user" search within the gradebook widget exists - And I confirm "Turtle Manatee" in "user" search within the gradebook widget exists + And I confirm "Dummy User" exists in the "Search users" search combo box + And I confirm "User Example" exists in the "Search users" search combo box + And I confirm "User Test" exists in the "Search users" search combo box + And I confirm "Student 1" exists in the "Search users" search combo box + And I confirm "Turtle Manatee" exists in the "Search users" search combo box # Search on the country field. When I set the field "Search users" to "JP" And "View all results (5)" "option_role" should exist And I wait until "Turtle Manatee" "list_item" does not exist - And I confirm "Dummy User" in "user" search within the gradebook widget exists - And I confirm "User Test" in "user" search within the gradebook widget exists + And I confirm "Dummy User" exists in the "Search users" search combo box + And I confirm "User Test" exists in the "Search users" search combo box # Search on the city field. And I set the field "Search users" to "Hanoi" And I wait until "User Test" "list_item" does not exist - Then I confirm "Student 1" in "user" search within the gradebook widget exists + Then I confirm "Student 1" exists in the "Search users" search combo box # Search on the institution field. And I set the field "Search users" to "ABCD" And "Dummy User" "list_item" should exist - And I confirm "User Example" in "user" search within the gradebook widget exists - And I confirm "User Test" in "user" search within the gradebook widget exists - And I confirm "Student 1" in "user" search within the gradebook widget exists - And I confirm "Turtle Manatee" in "user" search within the gradebook widget exists + And I confirm "User Example" exists in the "Search users" search combo box + And I confirm "User Test" exists in the "Search users" search combo box + And I confirm "Student 1" exists in the "Search users" search combo box + And I confirm "Turtle Manatee" exists in the "Search users" search combo box # Search on the department field. And I set the field "Search users" to "ABC3" And I wait until "User Example" "list_item" does not exist - And I confirm "User Test" in "user" search within the gradebook widget exists - And I confirm "Turtle Manatee" in "user" search within the gradebook widget exists + And I confirm "User Test" exists in the "Search users" search combo box + And I confirm "Turtle Manatee" exists in the "Search users" search combo box # Search on the phone1 field. And I set the field "Search users" to "4365899871" And I wait until "User Test" "list_item" does not exist - And I confirm "Dummy User" in "user" search within the gradebook widget exists + And I confirm "Dummy User" exists in the "Search users" search combo box # Search on the phone2 field. And I set the field "Search users" to "2149871323" And I wait until "Dummy User" "list_item" does not exist - And I confirm "User Test" in "user" search within the gradebook widget exists + And I confirm "User Test" exists in the "Search users" search combo box # Search on the institution field then press enter to show the record set. And I set the field "Search users" to "ABC" And "Turtle Manatee" "list_item" should exist - And I confirm "Dummy User" in "user" search within the gradebook widget exists - And I confirm "User Example" in "user" search within the gradebook widget exists - And I confirm "User Test" in "user" search within the gradebook widget exists - And I confirm "Student 1" in "user" search within the gradebook widget exists + And I confirm "Dummy User" exists in the "Search users" search combo box + And I confirm "User Example" exists in the "Search users" search combo box + And I confirm "User Test" exists in the "Search users" search combo box + And I confirm "Student 1" exists in the "Search users" search combo box And I press the up key And I press the enter key And I wait until the page is ready diff --git a/grade/report/user/tests/behat/view_usereport.feature b/grade/report/user/tests/behat/view_usereport.feature index 03d8169f3c1..d4dbad98c7b 100644 --- a/grade/report/user/tests/behat/view_usereport.feature +++ b/grade/report/user/tests/behat/view_usereport.feature @@ -25,7 +25,7 @@ Feature: We can use the user report | student1 | C1 | student | And I am on the "Course 1" "grades > User report > View" page logged in as "teacher1" And I should see "Search for a user to view their report" in the "region-main" "region" - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box And I should see "Student 1" in the "region-main" "region" When I am on the "Course 1" "grades > User report > View" page Then I should not see "Search for a user to view their report" in the "region-main" "region" @@ -51,9 +51,9 @@ Feature: We can use the user report | user | group | | student2 | G1 | And I am on the "Course 1" "grades > User report > View" page logged in as "teacher1" - And I click on "Student 2" in the "user" search widget + And I click on "Student 2" in the "Search users" search combo box And I navigate to "View > Grader report" in the course gradebook - And I click on "Group 1" in the "group" search widget + And I click on "Group 1" in the "Search groups" search combo box When I navigate to "View > User report" in the course gradebook Then I should see "Student 2" in the "region-main" "region" And I should not see "Search for a user to view their report" in the "region-main" "region" @@ -76,9 +76,9 @@ Feature: We can use the user report | user | group | | student2 | G1 | And I am on the "Course 1" "grades > User report > View" page logged in as "teacher1" - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box And I navigate to "View > Grader report" in the course gradebook - And I click on "Group 1" in the "group" search widget + And I click on "Group 1" in the "Search groups" search combo box When I navigate to "View > User report" in the course gradebook Then I should see "Search for a user to view their report" in the "region-main" "region" And I should not see "Student 1" in the "region-main" "region" @@ -95,7 +95,7 @@ Feature: We can use the user report | student1 | C1 | student | | student2 | C1 | student | And I am on the "Course 1" "grades > User report > View" page logged in as "teacher1" - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box And I should see "Student 1" in the "region-main" "region" And I navigate to course participants And I click on "Unenrol" "icon" in the "Student 1" "table_row" diff --git a/grade/tests/behat/behat_grade.php b/grade/tests/behat/behat_grade.php index 1a136f11a90..631a49e2364 100644 --- a/grade/tests/behat/behat_grade.php +++ b/grade/tests/behat/behat_grade.php @@ -304,99 +304,4 @@ class behat_grade extends behat_base { protected function select_in_gradebook_navigation_selector() { \core\deprecation::emit_deprecation_if_present([self::class, __FUNCTION__]); } - - /** - * We tend to use this series of steps a bit so define em once. - * - * @param string $haystack What are we searching within? - * @param string $needle What are we looking for? - * @param bool $fieldset Do we want to set the search field at the same time? - * @return string - * @throws coding_exception - */ - private function get_dropdown_selector(string $haystack, string $needle, bool $fieldset = true): string { - $this->execute("behat_general::wait_until_the_page_is_ready"); - - // Set the default field to search and handle any special preamble. - $string = get_string('searchusers', 'core'); - $selector = '.usersearchdropdown'; - if (strtolower($haystack) === 'group') { - $string = get_string('searchgroups', 'core'); - $selector = '.groupsearchdropdown'; - $trigger = ".groupsearchwidget"; - $node = $this->find("css_element", $selector); - if (!$node->isVisible()) { - $this->execute("behat_general::i_click_on", [$trigger, "css_element"]); - } - } else if (strtolower($haystack) === 'grade') { - $string = get_string('searchitems', 'core'); - $selector = '.gradesearchdropdown'; - $trigger = ".gradesearchwidget"; - $node = $this->find("css_element", $selector); - if (!$node->isVisible()) { - $this->execute("behat_general::i_click_on", [$trigger, "css_element"]); - } - } - - if ($fieldset) { - $this->execute("behat_forms::set_field_value", [$string, $needle]); - $this->execute("behat_general::wait_until_exists", [$needle, "list_item"]); - } - return $selector; - } - - /** - * Confirm if a value is within the search widget within the gradebook. - * - * Examples: - * - I confirm "User" in "user" search within the gradebook widget exists - * - I confirm "Group" in "group" search within the gradebook widget exists - * - I confirm "Grade item" in "grade" search within the gradebook widget exists - * - * @Given /^I confirm "(?P(?:[^"]|\\")*)" in "(?P(?:[^"]|\\")*)" search within the gradebook widget exists$/ - * @param string $needle The value to search for. - * @param string $haystack The type of the search widget. - */ - public function i_confirm_in_search_within_the_gradebook_widget_exists($needle, $haystack) { - $this->execute("behat_general::assert_element_contains_text", - [$needle, $this->get_dropdown_selector($haystack, $needle, false), "css_element"]); - } - - /** - * Confirm if a value is not within the search widget within the gradebook. - * - * Examples: - * - I confirm "User" in "user" search within the gradebook widget does not exist - * - I confirm "Group" in "group" search within the gradebook widget does not exist - * - I confirm "Grade item" in "grade" search within the gradebook widget does not exist - * - * @Given /^I confirm "(?P(?:[^"]|\\")*)" in "(?P(?:[^"]|\\")*)" search within the gradebook widget does not exist$/ - * @param string $needle The value to search for. - * @param string $haystack The type of the search widget. - */ - public function i_confirm_in_search_within_the_gradebook_widget_does_not_exist($needle, $haystack) { - $this->execute("behat_general::assert_element_not_contains_text", - [$needle, $this->get_dropdown_selector($haystack, $needle, false), "css_element"]); - } - - /** - * Clicks on an option from the specified search widget in the current gradebook page. - * - * Examples: - * - I click on "Student" in the "user" search widget - * - I click on "Group" in the "group" search widget - * - I click on "Grade item" in the "grade" search widget - * - * @Given /^I click on "(?P(?:[^"]|\\")*)" in the "(?P(?:[^"]|\\")*)" search widget$/ - * @param string $needle The value to search for. - * @param string $haystack The type of the search widget. - */ - public function i_click_on_in_search_widget(string $needle, string $haystack) { - $selector = $this->get_dropdown_selector($haystack, $needle); - $this->execute('behat_general::i_click_on_in_the', [ - $needle, "list_item", - $selector, "css_element" - ]); - $this->execute("behat_general::i_wait_to_be_redirected"); - } } diff --git a/grade/tests/behat/behat_grade_deprecated.php b/grade/tests/behat/behat_grade_deprecated.php index e77641251f5..c2fb7512879 100644 --- a/grade/tests/behat/behat_grade_deprecated.php +++ b/grade/tests/behat/behat_grade_deprecated.php @@ -53,4 +53,133 @@ class behat_grade_deprecated extends behat_deprecated_base { $this->execute('behat_forms::i_set_the_field_to', array($this->escape($fieldstr), $this->escape($feedback))); } + + /** + * Confirm if a value is within the search widget within the gradebook. + * + * Examples: + * - I confirm "User" in "user" search within the gradebook widget exists + * - I confirm "Group" in "group" search within the gradebook widget exists + * - I confirm "Grade item" in "grade" search within the gradebook widget exists + * + * @Given /^I confirm "(?P(?:[^"]|\\")*)" in "(?P(?:[^"]|\\")*)" search within the gradebook widget exists$/ + * @param string $needle The value to search for. + * @param string $haystack The type of the search widget. + * @deprecated since 4.5 + */ + public function i_confirm_in_search_within_the_gradebook_widget_exists($needle, $haystack) { + $this->deprecated_message('behat_general::i_confirm_in_search_combobox_exists'); + + $this->execute("behat_general::wait_until_the_page_is_ready"); + + // Set the default field to search and handle any special preamble. + $selector = '.usersearchdropdown'; + if (strtolower($haystack) === 'group') { + $selector = '.groupsearchdropdown'; + $trigger = ".groupsearchwidget"; + $node = $this->find("css_element", $selector); + if (!$node->isVisible()) { + $this->execute("behat_general::i_click_on", [$trigger, "css_element"]); + } + } else if (strtolower($haystack) === 'grade') { + $selector = '.gradesearchdropdown'; + $trigger = ".gradesearchwidget"; + $node = $this->find("css_element", $selector); + if (!$node->isVisible()) { + $this->execute("behat_general::i_click_on", [$trigger, "css_element"]); + } + } + + $this->execute("behat_general::assert_element_contains_text", + [$needle, $selector, "css_element"]); + } + + /** + * Confirm if a value is not within the search widget within the gradebook. + * + * Examples: + * - I confirm "User" in "user" search within the gradebook widget does not exist + * - I confirm "Group" in "group" search within the gradebook widget does not exist + * - I confirm "Grade item" in "grade" search within the gradebook widget does not exist + * + * @Given /^I confirm "(?P(?:[^"]|\\")*)" in "(?P(?:[^"]|\\")*)" search within the gradebook widget does not exist$/ + * @param string $needle The value to search for. + * @param string $haystack The type of the search widget. + * @deprecated since 4.5 + */ + public function i_confirm_in_search_within_the_gradebook_widget_does_not_exist($needle, $haystack) { + $this->deprecated_message('behat_general::i_confirm_in_search_combobox_does_not_exist'); + + $this->execute("behat_general::wait_until_the_page_is_ready"); + + // Set the default field to search and handle any special preamble. + $selector = '.usersearchdropdown'; + if (strtolower($haystack) === 'group') { + $selector = '.groupsearchdropdown'; + $trigger = ".groupsearchwidget"; + $node = $this->find("css_element", $selector); + if (!$node->isVisible()) { + $this->execute("behat_general::i_click_on", [$trigger, "css_element"]); + } + } else if (strtolower($haystack) === 'grade') { + $selector = '.gradesearchdropdown'; + $trigger = ".gradesearchwidget"; + $node = $this->find("css_element", $selector); + if (!$node->isVisible()) { + $this->execute("behat_general::i_click_on", [$trigger, "css_element"]); + } + } + + $this->execute("behat_general::assert_element_not_contains_text", + [$needle, $selector, "css_element"]); + } + + /** + * Clicks on an option from the specified search widget in the current gradebook page. + * + * Examples: + * - I click on "Student" in the "user" search widget + * - I click on "Group" in the "group" search widget + * - I click on "Grade item" in the "grade" search widget + * + * @Given /^I click on "(?P(?:[^"]|\\")*)" in the "(?P(?:[^"]|\\")*)" search widget$/ + * @param string $needle The value to search for. + * @param string $haystack The type of the search widget. + * @deprecated since 4.5 + */ + public function i_click_on_in_search_widget(string $needle, string $haystack) { + $this->deprecated_message('behat_general::i_click_on_in_search_combobox'); + + $this->execute("behat_general::wait_until_the_page_is_ready"); + + // Set the default field to search and handle any special preamble. + $string = get_string('searchusers', 'core'); + $selector = '.usersearchdropdown'; + if (strtolower($haystack) === 'group') { + $string = get_string('searchgroups', 'core'); + $selector = '.groupsearchdropdown'; + $trigger = ".groupsearchwidget"; + $node = $this->find("css_element", $selector); + if (!$node->isVisible()) { + $this->execute("behat_general::i_click_on", [$trigger, "css_element"]); + } + } else if (strtolower($haystack) === 'grade') { + $string = get_string('searchitems', 'core'); + $selector = '.gradesearchdropdown'; + $trigger = ".gradesearchwidget"; + $node = $this->find("css_element", $selector); + if (!$node->isVisible()) { + $this->execute("behat_general::i_click_on", [$trigger, "css_element"]); + } + } + + $this->execute("behat_forms::set_field_value", [$string, $needle]); + $this->execute("behat_general::wait_until_exists", [$needle, "list_item"]); + + $this->execute('behat_general::i_click_on_in_the', [ + $needle, "list_item", + $selector, "css_element", + ]); + $this->execute("behat_general::i_wait_to_be_redirected"); + } } diff --git a/grade/tests/behat/grade_aggregation.feature b/grade/tests/behat/grade_aggregation.feature index ea728cfa725..7329d47d401 100644 --- a/grade/tests/behat/grade_aggregation.feature +++ b/grade/tests/behat/grade_aggregation.feature @@ -345,7 +345,7 @@ Feature: We can use calculated grade totals And I set the field "Show weightings" to "Show" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box And I set the field "View report as" to "Myself" And the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Contribution to course total | @@ -542,7 +542,7 @@ Feature: We can use calculated grade totals And I navigate to "View > Grader report" in the course gradebook Then I should see "75.00 (16.85 %)" in the ".course" "css_element" And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box And I set the field "View report as" to "Myself" And the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Contribution to course total | diff --git a/grade/tests/behat/grade_calculated_grade_items.feature b/grade/tests/behat/grade_calculated_grade_items.feature index e3f7cb50658..81e6e3a99cd 100644 --- a/grade/tests/behat/grade_calculated_grade_items.feature +++ b/grade/tests/behat/grade_calculated_grade_items.feature @@ -41,7 +41,7 @@ Feature: Calculated grade items can be used in the gradebook And I give the grade "75.00" to the user "Student 1" for the grade item "grade item 1" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box And the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | grade item 1 | - | 75.00 | 0–100 | 75.00 % | - | @@ -71,7 +71,7 @@ Feature: Calculated grade items can be used in the gradebook And I give the grade "75.00" to the user "Student 1" for the grade item "grade item 1" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box And the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | grade item 1 | - | 75.00 | 0–100 | 75.00 % | - | @@ -84,13 +84,13 @@ Feature: Calculated grade items can be used in the gradebook And I give the grade "65.00" to the user "Student 2" for the grade item "grade item 1" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - When I click on "Student 1" in the "user" search widget + When I click on "Student 1" in the "Search users" search combo box Then the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | grade item 1 | - | 75.00 | 0–100 | 75.00 % | - | | Calc cat total | 100.00 % | 37.50 | 0–40 | 93.75 % | - | | Course total | - | 37.50 | 0–40 | 93.75 % | - | - And I click on "Student 2" in the "user" search widget + And I click on "Student 2" in the "Search users" search combo box And the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | grade item 1 | - | 65.00 | 0–100 | 65.00 % | - | @@ -101,13 +101,13 @@ Feature: Calculated grade items can be used in the gradebook | Min and max grades used in calculation | Initial min and max grades | And I press "Save changes" And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box And the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | grade item 1 | - | 75.00 | 0–100 | 75.00 % | - | | Calc cat total | 100.00 % | 37.50 | 0–40 | 93.75 % | - | | Course total | - | 37.50 | 0–40 | 93.75 % | - | - And I click on "Student 2" in the "user" search widget + And I click on "Student 2" in the "Search users" search combo box And the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | grade item 1 | - | 65.00 | 0–100 | 65.00 % | - | @@ -137,7 +137,7 @@ Feature: Calculated grade items can be used in the gradebook And I give the grade "75.00" to the user "Student 1" for the grade item "grade item 1" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - When I click on "Student 1" in the "user" search widget + When I click on "Student 1" in the "Search users" search combo box Then the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | grade item 1 | 66.67 % | 75.00 | 0–100 | 75.00 % | 50.00 % | @@ -151,13 +151,13 @@ Feature: Calculated grade items can be used in the gradebook And I give the grade "65.00" to the user "Student 2" for the grade item "grade item 1" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box And the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | grade item 1 | 71.43 % | 75.00 | 0–100 | 75.00 % | 53.57 % | | calc item | 28.57 % | 37.50 | 0–40 | 93.75 % | 26.79 % | | Course total | - | 112.50 | 0–140 | 80.36 % | - | - And I click on "Student 2" in the "user" search widget + And I click on "Student 2" in the "Search users" search combo box And the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | grade item 1 | 71.43 % | 65.00 | 0–100 | 65.00 % | 46.43 % | diff --git a/grade/tests/behat/grade_calculated_grade_items_20150627.feature b/grade/tests/behat/grade_calculated_grade_items_20150627.feature index 2157f99c6c7..38282e47424 100644 --- a/grade/tests/behat/grade_calculated_grade_items_20150627.feature +++ b/grade/tests/behat/grade_calculated_grade_items_20150627.feature @@ -42,7 +42,7 @@ Feature: Gradebook calculations for calculated grade items before the fix 201506 And I give the grade "75.00" to the user "Student 1" for the grade item "grade item 1" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box And the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | grade item 1 | - | 75.00 | 0–100 | 75.00 % | - | @@ -70,7 +70,7 @@ Feature: Gradebook calculations for calculated grade items before the fix 201506 And I give the grade "75.00" to the user "Student 1" for the grade item "grade item 1" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box And the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | grade item 1 | - | 75.00 | 0–100 | 75.00 % | - | @@ -83,13 +83,13 @@ Feature: Gradebook calculations for calculated grade items before the fix 201506 And I give the grade "65.00" to the user "Student 2" for the grade item "grade item 1" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - When I click on "Student 1" in the "user" search widget + When I click on "Student 1" in the "Search users" search combo box Then the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | grade item 1 | - | 75.00 | 0–100 | 75.00 % | - | | Calc cat total | 100.00 % | 37.50 | 0–100 | 37.50 % | - | | Course total | - | 37.50 | 0–100 | 37.50 % | - | - And I click on "Student 2" in the "user" search widget + And I click on "Student 2" in the "Search users" search combo box And the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | grade item 1 | - | 65.00 | 0–100 | 65.00 % | - | @@ -100,13 +100,13 @@ Feature: Gradebook calculations for calculated grade items before the fix 201506 | Min and max grades used in calculation | Initial min and max grades | And I press "Save changes" And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box And the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | grade item 1 | - | 75.00 | 0–100 | 75.00 % | - | | Calc cat total | 100.00 % | 37.50 | 0–100 | 37.50 % | - | | Course total | - | 37.50 | 0–100 | 37.50 % | - | - And I click on "Student 2" in the "user" search widget + And I click on "Student 2" in the "Search users" search combo box And the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | grade item 1 | - | 65.00 | 0–100 | 65.00 % | - | @@ -136,7 +136,7 @@ Feature: Gradebook calculations for calculated grade items before the fix 201506 And I give the grade "75.00" to the user "Student 1" for the grade item "grade item 1" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - When I click on "Student 1" in the "user" search widget + When I click on "Student 1" in the "Search users" search combo box Then the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | grade item 1 | 50.00 % | 75.00 | 0–100 | 75.00 % | 37.50 % | @@ -150,13 +150,13 @@ Feature: Gradebook calculations for calculated grade items before the fix 201506 And I give the grade "65.00" to the user "Student 2" for the grade item "grade item 1" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box And the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | grade item 1 | 50.00 % | 75.00 | 0–100 | 75.00 % | 37.50 % | | calc item | 50.00 % | 37.50 | 0–100 | 37.50 % | 18.75 % | | Course total | - | 112.50 | 0–200 | 56.25 % | - | - And I click on "Student 2" in the "user" search widget + And I click on "Student 2" in the "Search users" search combo box And the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | grade item 1 | 50.00 % | 65.00 | 0–100 | 65.00 % | 32.50 % | diff --git a/grade/tests/behat/grade_calculated_weights.feature b/grade/tests/behat/grade_calculated_weights.feature index 6f2179887dc..60f149d7104 100644 --- a/grade/tests/behat/grade_calculated_weights.feature +++ b/grade/tests/behat/grade_calculated_weights.feature @@ -57,7 +57,7 @@ Feature: We can understand the gradebook user report And I set the following settings for grade item "Course 1" of type "course" on "setup" page: | Aggregation | Mean of grades | And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box # Check the values in the weights column. Then the following should exist in the "user-grade" table: @@ -82,7 +82,7 @@ Feature: We can understand the gradebook user report And I set the following settings for grade item "Sub category" of type "category" on "setup" page: | Item weight | 1.0 | And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box # Check the values in the weights column. Then the following should exist in the "user-grade" table: @@ -103,7 +103,7 @@ Feature: We can understand the gradebook user report And I set the following settings for grade item "Test assignment three" of type "gradeitem" on "setup" page: | Extra credit | 1 | And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box # Check the values in the weights column. Then the following should exist in the "user-grade" table: @@ -122,7 +122,7 @@ Feature: We can understand the gradebook user report And I set the following settings for grade item "Test assignment three" of type "gradeitem" on "setup" page: | Extra credit weight | 1.0 | And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box # Check the values in the weights column. Then the following should exist in the "user-grade" table: @@ -139,7 +139,7 @@ Feature: We can understand the gradebook user report And I set the following settings for grade item "Course 1" of type "course" on "setup" page: | Aggregation | Median of grades | And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box # Check the values in the weights column. Then the following should exist in the "user-grade" table: @@ -156,7 +156,7 @@ Feature: We can understand the gradebook user report And I set the following settings for grade item "Course 1" of type "course" on "setup" page: | Aggregation | Lowest grade | And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box # Check the values in the weights column. Then the following should exist in the "user-grade" table: @@ -173,7 +173,7 @@ Feature: We can understand the gradebook user report And I set the following settings for grade item "Course 1" of type "course" on "setup" page: | Aggregation | Highest grade | And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box # Check the values in the weights column. Then the following should exist in the "user-grade" table: @@ -190,7 +190,7 @@ Feature: We can understand the gradebook user report And I set the following settings for grade item "Course 1" of type "course" on "setup" page: | Aggregation | Mode of grades | And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box # Check the values in the weights column. Then the following should exist in the "user-grade" table: @@ -212,7 +212,7 @@ Feature: We can understand the gradebook user report And I set the following settings for grade item "Test assignment three" of type "gradeitem" on "setup" page: | aggregationcoef | 1 | And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box # Check the values in the weights column. Then the following should exist in the "user-grade" table: @@ -231,7 +231,7 @@ Feature: We can understand the gradebook user report And I set the following settings for grade item "Test assignment three" of type "gradeitem" on "setup" page: | Extra credit | 1 | And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box # Check the values in the weights column. Then the following should exist in the "user-grade" table: diff --git a/grade/tests/behat/grade_contribution_with_extra_credit.feature b/grade/tests/behat/grade_contribution_with_extra_credit.feature index a4eae0a9e22..5e29d1376a3 100644 --- a/grade/tests/behat/grade_contribution_with_extra_credit.feature +++ b/grade/tests/behat/grade_contribution_with_extra_credit.feature @@ -60,7 +60,7 @@ Feature: Extra credit contributions are normalised when going out of bounds And I set the following settings for grade item "Manual item 4" of type "gradeitem" on "setup" page: | aggregationcoef | 1 | And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box Then the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Contribution to course total | | Manual item 1 | | 80.00 | | diff --git a/grade/tests/behat/grade_grade_minmax_change.feature b/grade/tests/behat/grade_grade_minmax_change.feature index 07724dd1470..bfa2384bffc 100644 --- a/grade/tests/behat/grade_grade_minmax_change.feature +++ b/grade/tests/behat/grade_grade_minmax_change.feature @@ -42,11 +42,11 @@ Feature: We can change the maximum and minimum number of points for manual items | Rescale existing grades | No | | Maximum grade | 10 | And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box Then the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Contribution to course total | | Manual item 1 | 100.00 % | 10.00 | 100.00 % | - And I click on "Student 2" in the "user" search widget + And I click on "Student 2" in the "Search users" search combo box And the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Contribution to course total | | Manual item 1 | 100.00 % | 8.00 | 80.00 % | @@ -58,11 +58,11 @@ Feature: We can change the maximum and minimum number of points for manual items | Maximum grade | 20 | And I click on "Save" "button" in the "Edit grade item" "dialogue" And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box And the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Contribution to course total | | Manual item 1 | 100.00 % | 20.00 | 100.00 % | - And I click on "Student 2" in the "user" search widget + And I click on "Student 2" in the "Search users" search combo box And the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Contribution to course total | | Manual item 1 | 100.00 % | 16.00 | 80.00 % | diff --git a/grade/tests/behat/grade_hidden_items.feature b/grade/tests/behat/grade_hidden_items.feature index 6362959a22f..088b84962d3 100644 --- a/grade/tests/behat/grade_hidden_items.feature +++ b/grade/tests/behat/grade_hidden_items.feature @@ -46,7 +46,7 @@ Feature: Student and teacher's view of aggregated grade items is consistent when And I set the following settings for grade item "Test assignment four" of type "gradeitem" on "grader" page: | Hidden | 1 | And I am on the "Course 1" "grades > User report > View" page - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box And I set the field "View report as" to "Myself" Then the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | diff --git a/grade/tests/behat/grade_hidden_items_locked_category.feature b/grade/tests/behat/grade_hidden_items_locked_category.feature index d3967259e67..d1e3e2fcf8f 100644 --- a/grade/tests/behat/grade_hidden_items_locked_category.feature +++ b/grade/tests/behat/grade_hidden_items_locked_category.feature @@ -39,7 +39,7 @@ Feature: Hidden grade items should be hidden when grade category is locked, but Scenario: Hidden grade items in locked category is hidden for teacher Given I am on the "Course 1" "grades > User report > View" page logged in as teacher1 - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box When I set the field "View report as" to "Myself" Then the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | diff --git a/grade/tests/behat/grade_mingrade.feature b/grade/tests/behat/grade_mingrade.feature index 32328fedc83..4dec7f364ee 100644 --- a/grade/tests/behat/grade_mingrade.feature +++ b/grade/tests/behat/grade_mingrade.feature @@ -63,7 +63,7 @@ Feature: We can use a minimum grade different than zero And I give the grade "50.00" to the user "Student 2" for the grade item "Manual item 6" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box Then the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Contribution to course total | | Manual item 1 | 18.18 % | -25.00 | -4.55 % | @@ -72,7 +72,7 @@ Feature: We can use a minimum grade different than zero | Manual item 4 | 66.67 % | -10.00 | -1.82 % | | Manual item 5 | 50.00 % | 50.00 | 9.09 % | | Manual item 6 | 50.00 % | 75.00 | 13.64 % | - And I click on "Student 2" in the "user" search widget + And I click on "Student 2" in the "Search users" search combo box And the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Contribution to course total | | Manual item 1 | 18.18 % | 0.00 | 0.00 % | diff --git a/grade/tests/behat/grade_minmax.feature b/grade/tests/behat/grade_minmax.feature index 8e8096d16d5..72fad7b8432 100644 --- a/grade/tests/behat/grade_minmax.feature +++ b/grade/tests/behat/grade_minmax.feature @@ -72,7 +72,7 @@ Feature: We can choose what min or max grade to use when aggregating grades. And I give the grade "10.00" to the user "Student 2" for the grade item "MI 3" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box And the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | MI 1 | 20.00 % | 75.00 | 0–100 | 75.00 % | 15.00 % | @@ -82,7 +82,7 @@ Feature: We can choose what min or max grade to use when aggregating grades. | MI 5 | 20.00 % | 100.00 | 0–100 | 100.00 % | 20.00 % | | CAT1 total | 40.00 % | 150.00 | 0–200 | 75.00 % | - | | Course total | - | 350.00 | 0–500 | 70.00 % | - | - And I click on "Student 2" in the "user" search widget + And I click on "Student 2" in the "Search users" search combo box And the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | MI 1 | 33.33 % | 20.00 | 0–100 | 20.00 % | 6.67 % | @@ -102,7 +102,7 @@ Feature: We can choose what min or max grade to use when aggregating grades. | Maximum grade | 50.00 | | Minimum grade | 5.00 | And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box And the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | MI 1 | 12.50 % | 75.00 | 5–50 | 100.00 % | 18.75 % | @@ -112,7 +112,7 @@ Feature: We can choose what min or max grade to use when aggregating grades. | MI 5 | 25.00 % | 100.00 | 0–100 | 100.00 % | 25.00 % | | CAT1 total | 37.50 % | 150.00 | 0–150 | 100.00 % | - | | Course total | - | 350.00 | 0–400 | 87.50 % | - | - And I click on "Student 2" in the "user" search widget + And I click on "Student 2" in the "Search users" search combo box And the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | MI 1 | 25.00 % | 20.00 | 5–50 | 33.33 % | 10.00 % | @@ -127,12 +127,12 @@ Feature: We can choose what min or max grade to use when aggregating grades. | Rescale existing grades | No | | Maximum grade | 200.00 | And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box And the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | MI 5 | 40.00 % | 150.00 | 0–200 | 75.00 % | 30.00 % | | Course total | - | 400.00 | 0–500 | 80.00 % | - | - And I click on "Student 2" in the "user" search widget + And I click on "Student 2" in the "Search users" search combo box And the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | MI 5 | 66.67 % | 30.00 | 0–200 | 15.00 % | 10.00 % | @@ -141,7 +141,7 @@ Feature: We can choose what min or max grade to use when aggregating grades. When I set the field "Min and max grades used in calculation" to "Initial min and max grades" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box Then the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | MI 1 | 16.67 % | 75.00 | 0–100 | 75.00 % | 12.50 % | @@ -151,7 +151,7 @@ Feature: We can choose what min or max grade to use when aggregating grades. | MI 5 | 33.33 % | 150.00 | 0–200 | 75.00 % | 25.00 % | | CAT1 total | 33.33 % | 150.00 | 0–200 | 75.00 % | - | | Course total | - | 400.00 | 0–600 | 66.67 % | - | - And I click on "Student 2" in the "user" search widget + And I click on "Student 2" in the "Search users" search combo box And the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | MI 1 | 25.00 % | 20.00 | 0–100 | 20.00 % | 5.00 % | diff --git a/grade/tests/behat/grade_natural_exclude_empty.feature b/grade/tests/behat/grade_natural_exclude_empty.feature index ae9cca41a81..a7f325cfe9c 100644 --- a/grade/tests/behat/grade_natural_exclude_empty.feature +++ b/grade/tests/behat/grade_natural_exclude_empty.feature @@ -40,7 +40,7 @@ Feature: Weights in natural aggregation are adjusted if the items are excluded f And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box Then the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | Test assignment one | 28.57 % | 80.00 | 0–100 | 80.00 % | 22.86 % | @@ -61,7 +61,7 @@ Feature: Weights in natural aggregation are adjusted if the items are excluded f And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box Then the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | Test assignment one | 66.67 % | 80.00 | 0–100 | 80.00 % | 53.33 % | @@ -80,7 +80,7 @@ Feature: Weights in natural aggregation are adjusted if the items are excluded f And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box Then the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | Test assignment one | 0.00 %( Empty ) | - | 0–100 | - | 0.00 % | @@ -107,7 +107,7 @@ Feature: Weights in natural aggregation are adjusted if the items are excluded f And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box Then the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | Test assignment one | 0.00 %( Extra credit ) | 80.00 | 0–100 | 80.00 % | 0.00 % | @@ -132,7 +132,7 @@ Feature: Weights in natural aggregation are adjusted if the items are excluded f And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box Then the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | Test assignment one | 50.00 % | 80.00 | 0–100 | 80.00 % | 40.00 % | @@ -156,7 +156,7 @@ Feature: Weights in natural aggregation are adjusted if the items are excluded f And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box Then the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | Test assignment one | 83.33 % | 80.00 | 0–100 | 80.00 % | 66.67 % | @@ -178,7 +178,7 @@ Feature: Weights in natural aggregation are adjusted if the items are excluded f And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box Then the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | Test assignment one | 0.00 %( Empty ) | - | 0–100 | - | 0.00 % | @@ -205,7 +205,7 @@ Feature: Weights in natural aggregation are adjusted if the items are excluded f And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box Then the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | Test assignment one | 50.00 % | 80.00 | 0–100 | 80.00 % | 40.00 % | @@ -231,7 +231,7 @@ Feature: Weights in natural aggregation are adjusted if the items are excluded f And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box Then the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | Test assignment one | 83.33 % | 80.00 | 0–100 | 80.00 % | 66.67 % | @@ -255,7 +255,7 @@ Feature: Weights in natural aggregation are adjusted if the items are excluded f And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box Then the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | Test assignment one | 0.00 %( Empty ) | - | 0–100 | - | 0.00 % | diff --git a/grade/tests/behat/grade_natural_exclude_empty_20150619.feature b/grade/tests/behat/grade_natural_exclude_empty_20150619.feature index 9027455bb46..b3871d2aec3 100644 --- a/grade/tests/behat/grade_natural_exclude_empty_20150619.feature +++ b/grade/tests/behat/grade_natural_exclude_empty_20150619.feature @@ -41,7 +41,7 @@ Feature: Gradebook calculations for extra credit items before the fix 20150619 And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box Then the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | Test assignment one | 28.57 % | 80.00 | 0–100 | 80.00 % | 22.86 % | @@ -62,7 +62,7 @@ Feature: Gradebook calculations for extra credit items before the fix 20150619 And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box Then the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | Test assignment one | 66.67 % | 80.00 | 0–100 | 80.00 % | 53.33 % | @@ -81,7 +81,7 @@ Feature: Gradebook calculations for extra credit items before the fix 20150619 And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box Then the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | Test assignment one | 0.00 %( Empty ) | - | 0–100 | - | 0.00 % | @@ -108,7 +108,7 @@ Feature: Gradebook calculations for extra credit items before the fix 20150619 And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box Then the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | Test assignment one | 0.00 %( Extra credit ) | 80.00 | 0–100 | 80.00 % | 0.00 % | @@ -133,7 +133,7 @@ Feature: Gradebook calculations for extra credit items before the fix 20150619 And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box Then the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | Test assignment one | 50.00 % | 80.00 | 0–100 | 80.00 % | 40.00 % | @@ -158,7 +158,7 @@ Feature: Gradebook calculations for extra credit items before the fix 20150619 And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box Then the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | Test assignment one | 83.33 % | 80.00 | 0–100 | 80.00 % | 66.67 % | @@ -181,7 +181,7 @@ Feature: Gradebook calculations for extra credit items before the fix 20150619 And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box Then the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | Test assignment one | 0.00 %( Empty ) | - | 0–100 | - | 0.00 % | @@ -208,7 +208,7 @@ Feature: Gradebook calculations for extra credit items before the fix 20150619 And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box Then the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | Test assignment one | 50.00 % | 80.00 | 0–100 | 80.00 % | 40.00 % | @@ -235,7 +235,7 @@ Feature: Gradebook calculations for extra credit items before the fix 20150619 And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box Then the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | Test assignment one | 83.33 % | 80.00 | 0–100 | 80.00 % | 66.67 % | @@ -260,7 +260,7 @@ Feature: Gradebook calculations for extra credit items before the fix 20150619 And I give the grade "8.00" to the user "Student 1" for the grade item "Test assignment five (extra)" And I press "Save changes" And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box Then the following should exist in the "user-grade" table: | Grade item | Calculated weight | Grade | Range | Percentage | Contribution to course total | | Test assignment one | 0.00 %( Empty ) | - | 0–100 | - | 0.00 % | diff --git a/grade/tests/behat/grade_scales.feature b/grade/tests/behat/grade_scales.feature index fee7dd54f35..96423911da7 100644 --- a/grade/tests/behat/grade_scales.feature +++ b/grade/tests/behat/grade_scales.feature @@ -84,7 +84,7 @@ Feature: View gradebook when scales are used | Range | F–A | 0.00–5.00 | 0.00–5.00 | | Overall average | C | 3.00 | 3.00 | And I navigate to "View > User report" in the course gradebook - And I click on "Student 3" in the "user" search widget + And I click on "Student 3" in the "Search users" search combo box And the following should exist in the "user-grade" table: | Grade item | Grade | Range | Percentage | Contribution to course total | | Test assignment one | C | F–A | 50.00 % | 60.00 % | @@ -127,7 +127,7 @@ Feature: View gradebook when scales are used | Range | F–A | 1.00–5.00 | 0.00–100.00 | | Overall average | C | 3.00 | | And I navigate to "View > User report" in the course gradebook - And I click on "Student 3" in the "user" search widget + And I click on "Student 3" in the "Search users" search combo box And the following should exist in the "user-grade" table: | Grade item | Grade | Range | Percentage | Contribution to course total | | Test assignment one | C | F–A | 50.00 % | | diff --git a/grade/tests/behat/grade_scales_aggregation.feature b/grade/tests/behat/grade_scales_aggregation.feature index 3ce40aa582e..5c4b5ef968e 100644 --- a/grade/tests/behat/grade_scales_aggregation.feature +++ b/grade/tests/behat/grade_scales_aggregation.feature @@ -44,7 +44,7 @@ Feature: Control the aggregation of the scales And I set the following settings for grade item "Course 1" of type "course" on "grader" page: | Aggregation | | And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box Then the following should exist in the "user-grade" table: | Grade item | Grade | Percentage | Contribution to course total | | Grade me | 10.00 | 10.00 % | | @@ -55,7 +55,7 @@ Feature: Control the aggregation of the scales And I set the following administration settings values: | grade_includescalesinaggregation | 1 | And I am on the "Course 1" "grades > User report > View" page logged in as "teacher1" - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box And the following should exist in the "user-grade" table: | Grade item | Grade | Percentage | Contribution to course total | | Grade me | 10.00 | 10.00 % | | diff --git a/grade/tests/behat/grade_single_item_scales.feature b/grade/tests/behat/grade_single_item_scales.feature index 16024ed456d..bffa93d71eb 100644 --- a/grade/tests/behat/grade_single_item_scales.feature +++ b/grade/tests/behat/grade_single_item_scales.feature @@ -65,13 +65,13 @@ Feature: View gradebook when single item scales are used | Range | Ace!–Ace! | 0.00–1.00 | 0.00–1.00 | | Overall average | Ace! | 1.00 | 1.00 | And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box And the following should exist in the "user-grade" table: | Grade item | Grade | Range | Contribution to course total | | Test assignment one | Ace! | Ace!–Ace! | 100.00 % | | ENFR Sub category 1 total | 1.00 | 0–1 | - | | Course total | 1.00 | 0–1 | - | - And I click on "Student 2" in the "user" search widget + And I click on "Student 2" in the "Search users" search combo box And the following should exist in the "user-grade" table: | Grade item | Grade | Range | Contribution to course total | | Test assignment one | - | Ace!–Ace! | - | @@ -100,7 +100,7 @@ Feature: View gradebook when single item scales are used | Range | Ace!–Ace! | 0.00–100.0 | 0.00–100.00 | | Overall average | Ace! | | | And I navigate to "View > User report" in the course gradebook - And I click on "Student 1" in the "user" search widget + And I click on "Student 1" in the "Search users" search combo box And the following should exist in the "user-grade" table: | Grade item | Grade | Range | Contribution to course total | | Test assignment one | Ace! | Ace!–Ace! | | diff --git a/lib/classes/user.php b/lib/classes/user.php index 77ab9304f54..e9ed15379c4 100644 --- a/lib/classes/user.php +++ b/lib/classes/user.php @@ -22,6 +22,8 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +use core_user\fields; + defined('MOODLE_INTERNAL') || die(); /** @@ -1489,4 +1491,97 @@ class core_user { return $initials; } + /** + * Prepare SQL where clause and associated parameters for any user searching being performed. + * This mostly came from core_user\table\participants_search with some slight modifications four our use case. + * + * @param context $context Context we are in. + * @param string $usersearch Array of field mappings (fieldname => SQL code for the value) + * @return array SQL query data in the format ['where' => '', 'params' => []]. + */ + public static function get_users_search_sql(context $context, string $usersearch = ''): array { + global $DB, $USER; + + $userfields = fields::for_identity($context, false)->with_userpic(); + ['mappings' => $mappings] = (array)$userfields->get_sql('u', true); + $userfields = $userfields->get_required_fields(); + + $canviewfullnames = has_capability('moodle/site:viewfullnames', $context); + + $params = []; + $searchkey1 = 'search01'; + $searchkey2 = 'search02'; + $searchkey3 = 'search03'; + + $conditions = []; + + // Search by fullname. + [$fullname, $fullnameparams] = fields::get_sql_fullname('u', $canviewfullnames); + $conditions[] = $DB->sql_like($fullname, ':' . $searchkey1, false, false); + $params = array_merge($params, $fullnameparams); + + // Search by email. + $email = $DB->sql_like('email', ':' . $searchkey2, false, false); + + if (!in_array('email', $userfields)) { + $maildisplay = 'maildisplay0'; + $userid1 = 'userid01'; + // Prevent users who hide their email address from being found by others + // who aren't allowed to see hidden email addresses. + $email = "(". $email ." AND (" . + "u.maildisplay <> :$maildisplay " . + "OR u.id = :$userid1". // Users can always find themselves. + "))"; + $params[$maildisplay] = self::MAILDISPLAY_HIDE; + $params[$userid1] = $USER->id; + } + + $conditions[] = $email; + + // Search by idnumber. + $idnumber = $DB->sql_like('idnumber', ':' . $searchkey3, false, false); + + if (!in_array('idnumber', $userfields)) { + $userid2 = 'userid02'; + // Users who aren't allowed to see idnumbers should at most find themselves + // when searching for an idnumber. + $idnumber = "(". $idnumber . " AND u.id = :$userid2)"; + $params[$userid2] = $USER->id; + } + + $conditions[] = $idnumber; + + // Search all user identify fields. + $extrasearchfields = fields::get_identity_fields(null, false); + foreach ($extrasearchfields as $fieldindex => $extrasearchfield) { + if (in_array($extrasearchfield, ['email', 'idnumber', 'country'])) { + // Already covered above. + continue; + } + // The param must be short (max 32 characters) so don't include field name. + $param = $searchkey3 . '_ident' . $fieldindex; + $fieldsql = $mappings[$extrasearchfield]; + $condition = $DB->sql_like($fieldsql, ':' . $param, false, false); + $params[$param] = "%$usersearch%"; + + if (!in_array($extrasearchfield, $userfields)) { + // User cannot see this field, but allow match if their own account. + $userid3 = 'userid03_ident' . $fieldindex; + $condition = "(". $condition . " AND u.id = :$userid3)"; + $params[$userid3] = $USER->id; + } + $conditions[] = $condition; + } + + $where = "(". implode(" OR ", $conditions) .") "; + $params[$searchkey1] = "%$usersearch%"; + $params[$searchkey2] = "%$usersearch%"; + $params[$searchkey3] = "%$usersearch%"; + + return [ + 'where' => $where, + 'params' => $params, + ]; + } + } diff --git a/lib/templates/comboboxsearch.mustache b/lib/templates/comboboxsearch.mustache index 1bd27ed686c..7cce39369c9 100644 --- a/lib/templates/comboboxsearch.mustache +++ b/lib/templates/comboboxsearch.mustache @@ -49,7 +49,7 @@ {{#buttonheader}} {{.}} {{/buttonheader}} -