diff --git a/grade/report/user/amd/build/user.min.js b/grade/report/user/amd/build/user.min.js index 85735074c39..fdf30495d3f 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/pending","core/templates","core/custom_interaction_events","core_grades/searchwidget/repository","core_grades/searchwidget/basewidget","core/str","core/url"],(function(_exports,_pending,Templates,_custom_interaction_events,Repository,WidgetBase,_str,_url){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 _interopRequireWildcard(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]}return newObj.default=obj,cache&&cache.set(obj,newObj),newObj}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}} +define("gradereport_user/user",["exports","core/pending","core/templates","core_grades/searchwidget/repository","core_grades/searchwidget/basewidget","core/str","core/url","jquery","core_grades/searchwidget/selectors"],(function(_exports,_pending,Templates,Repository,WidgetBase,_str,_url,_jquery,Selectors){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 _interopRequireWildcard(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]}return newObj.default=obj,cache&&cache.set(obj,newObj),newObj}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}} /** - * A small modal to search users within the gradebook. + * A widget to search users within the gradebook. * * @module gradereport_user/user * @copyright 2022 Mathew May * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_pending=_interopRequireDefault(_pending),Templates=_interopRequireWildcard(Templates),_custom_interaction_events=_interopRequireDefault(_custom_interaction_events),Repository=_interopRequireWildcard(Repository),WidgetBase=_interopRequireWildcard(WidgetBase),_url=_interopRequireDefault(_url);_exports.init=()=>{const pendingPromise=new _pending.default;registerListenerEvents(),pendingPromise.resolve()};const registerListenerEvents=()=>{const events=["click",_custom_interaction_events.default.events.activate,_custom_interaction_events.default.events.keyboardActivate];_custom_interaction_events.default.define(document,events);let{bodyPromiseResolver:bodyPromiseResolver,bodyPromise:bodyPromise}=WidgetBase.promisesAndResolvers();events.forEach((event=>{document.addEventListener(event,(async e=>{const trigger=e.target.closest(".userwidget");if(trigger){const courseID=trigger.dataset.courseid,groupId=trigger.dataset.groupid;e.preventDefault();const actionBaseUrl=_url.default.relativeUrl("/grade/report/user/index.php",{},!1),data=await Repository.userFetch(courseID,actionBaseUrl,groupId).catch((async e=>{const errorTemplateData={errormessage:e.message};bodyPromiseResolver(await Templates.render("core_grades/searchwidget/error",errorTemplateData))}));if(data===[])return;const allUsersOptionName=await(0,_str.get_string)("allusersnum","gradereport_user",data.users.length),allUsersOption=await Templates.render("core_grades/searchwidget/searchitem",{id:0,name:allUsersOptionName,url:_url.default.relativeUrl("/grade/report/user/index.php",{id:courseID,userid:0},!1)});WidgetBase.init(bodyPromise,data.users,searchUsers(),(0,_str.get_string)("selectauser","grades"),allUsersOption)}}))})),bodyPromiseResolver(Templates.render("core_grades/searchwidget/user/usersearch_body",{displayunsearchablecontent:!0}))},searchUsers=()=>()=>(users,searchTerm)=>{if(""===searchTerm)return users;searchTerm=searchTerm.toLowerCase();const searchResults=[];return users.forEach((user=>{user.fullname.toLowerCase().includes(searchTerm)&&searchResults.push(user)})),searchResults}})); + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_pending=_interopRequireDefault(_pending),Templates=_interopRequireWildcard(Templates),Repository=_interopRequireWildcard(Repository),WidgetBase=_interopRequireWildcard(WidgetBase),_url=_interopRequireDefault(_url),_jquery=_interopRequireDefault(_jquery),Selectors=_interopRequireWildcard(Selectors);_exports.init=()=>{const pendingPromise=new _pending.default;registerListenerEvents(),pendingPromise.resolve()};const registerListenerEvents=()=>{let{bodyPromiseResolver:bodyPromiseResolver,bodyPromise:bodyPromise}=WidgetBase.promisesAndResolvers();const dropdownMenuContainer=document.querySelector(Selectors.elements.getSearchWidgetDropdownSelector("user"));(0,_jquery.default)(Selectors.elements.getSearchWidgetSelector("user")).on("show.bs.dropdown",(async e=>{const courseID=e.relatedTarget.dataset.courseid,groupId=e.relatedTarget.dataset.groupid,actionBaseUrl=_url.default.relativeUrl("/grade/report/user/index.php",{},!1);await WidgetBase.showLoader(dropdownMenuContainer);const data=await Repository.userFetch(courseID,actionBaseUrl,groupId).catch((async e=>{const errorTemplateData={errormessage:e.message};bodyPromiseResolver(await Templates.render("core_grades/searchwidget/error",errorTemplateData))}));if(data===[])return;const allUsersOptionName=await(0,_str.get_string)("allusersnum","gradereport_user",data.users.length),allUsersOption=await Templates.render("core_grades/searchwidget/searchitem",{id:0,name:allUsersOptionName,url:_url.default.relativeUrl("/grade/report/user/index.php",{id:courseID,userid:0},!1)});await WidgetBase.init(dropdownMenuContainer,bodyPromise,data.users,searchUsers(),allUsersOption),bodyPromiseResolver(Templates.render("core_grades/searchwidget/user/usersearch_body",{displayunsearchablecontent:!0}))})),(0,_jquery.default)(Selectors.elements.getSearchWidgetSelector("user")).on("hide.bs.dropdown",(()=>{dropdownMenuContainer.innerHTML=""}))},searchUsers=()=>()=>(users,searchTerm)=>{if(""===searchTerm)return users;searchTerm=searchTerm.toLowerCase();const searchResults=[];return users.forEach((user=>{user.fullname.toLowerCase().includes(searchTerm)&&searchResults.push(user)})),searchResults}})); //# 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 82a3f8ed0fd..47dec3c23c7 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 * A small modal to search users within the gradebook.\n *\n * @module gradereport_user/user\n * @copyright 2022 Mathew May \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Pending from 'core/pending';\nimport * as Templates from 'core/templates';\nimport CustomEvents from \"core/custom_interaction_events\";\nimport * as Repository from 'core_grades/searchwidget/repository';\nimport * as WidgetBase from 'core_grades/searchwidget/basewidget';\nimport {get_string as getString} from 'core/str';\nimport Url from 'core/url';\n\n/**\n * Our entry point into starting to build the search widget.\n * It'll eventually, based upon the listeners, open the search widget and allow filtering.\n *\n * @method init\n */\nexport const init = () => {\n const pendingPromise = new Pending();\n registerListenerEvents();\n pendingPromise.resolve();\n};\n\n/**\n * Register user search widget related event listeners.\n *\n * @method registerListenerEvents\n */\nconst registerListenerEvents = () => {\n const events = [\n 'click',\n CustomEvents.events.activate,\n CustomEvents.events.keyboardActivate\n ];\n CustomEvents.define(document, events);\n\n let {bodyPromiseResolver, bodyPromise} = WidgetBase.promisesAndResolvers();\n\n // Register events.\n events.forEach((event) => {\n document.addEventListener(event, async(e) => {\n const trigger = e.target.closest('.userwidget');\n if (trigger) {\n const courseID = trigger.dataset.courseid;\n const groupId = trigger.dataset.groupid;\n e.preventDefault();\n\n const actionBaseUrl = Url.relativeUrl('/grade/report/user/index.php', {}, false);\n // If an error occurs while fetching the data, display the error within the modal.\n const data = await Repository.userFetch(courseID, actionBaseUrl, groupId).catch(async(e) => {\n const errorTemplateData = {\n 'errormessage': e.message\n };\n bodyPromiseResolver(\n await Templates.render('core_grades/searchwidget/error', errorTemplateData)\n );\n });\n\n // Early return if there is no module data.\n if (data === []) {\n return;\n }\n\n // The HTML for the 'All users' option which will be rendered in the non-searchable content are of the widget.\n const allUsersOptionName = await getString('allusersnum', 'gradereport_user', data.users.length);\n const allUsersOption = await Templates.render('core_grades/searchwidget/searchitem', {\n id: 0,\n name: allUsersOptionName,\n url: Url.relativeUrl('/grade/report/user/index.php', {id: courseID, userid: 0}, false),\n });\n\n WidgetBase.init(\n bodyPromise,\n data.users,\n searchUsers(),\n getString('selectauser', 'grades'),\n allUsersOption\n );\n }\n });\n });\n // Resolvers for passed functions in the modal creation.\n bodyPromiseResolver(Templates.render(\n 'core_grades/searchwidget/user/usersearch_body', {displayunsearchablecontent: true}\n ));\n};\n\n/**\n * Define how we want to search and filter users when the user decides to input a search value.\n *\n * @method registerListenerEvents\n * @returns {function(): function(*, *): (*)}\n */\nconst searchUsers = () => {\n return () => {\n return (users, searchTerm) => {\n if (searchTerm === '') {\n return users;\n }\n searchTerm = searchTerm.toLowerCase();\n const searchResults = [];\n users.forEach((user) => {\n const userName = user.fullname.toLowerCase();\n if (userName.includes(searchTerm)) {\n searchResults.push(user);\n }\n });\n return searchResults;\n };\n };\n};\n"],"names":["pendingPromise","Pending","registerListenerEvents","resolve","events","CustomEvents","activate","keyboardActivate","define","document","bodyPromiseResolver","bodyPromise","WidgetBase","promisesAndResolvers","forEach","event","addEventListener","async","trigger","e","target","closest","courseID","dataset","courseid","groupId","groupid","preventDefault","actionBaseUrl","Url","relativeUrl","data","Repository","userFetch","catch","errorTemplateData","message","Templates","render","allUsersOptionName","users","length","allUsersOption","id","name","url","userid","init","searchUsers","displayunsearchablecontent","searchTerm","toLowerCase","searchResults","user","fullname","includes","push"],"mappings":";;;;;;;qYAqCoB,WACVA,eAAiB,IAAIC,iBAC3BC,yBACAF,eAAeG,iBAQbD,uBAAyB,WACrBE,OAAS,CACX,QACAC,mCAAaD,OAAOE,SACpBD,mCAAaD,OAAOG,qDAEXC,OAAOC,SAAUL,YAE1BM,oBAACA,oBAADC,YAAsBA,aAAeC,WAAWC,uBAGpDT,OAAOU,SAASC,QACZN,SAASO,iBAAiBD,OAAOE,MAAAA,UACvBC,QAAUC,EAAEC,OAAOC,QAAQ,kBAC7BH,QAAS,OACHI,SAAWJ,QAAQK,QAAQC,SAC3BC,QAAUP,QAAQK,QAAQG,QAChCP,EAAEQ,uBAEIC,cAAgBC,aAAIC,YAAY,+BAAgC,IAAI,GAEpEC,WAAaC,WAAWC,UAAUX,SAAUM,cAAeH,SAASS,OAAMjB,MAAAA,UACtEkB,kBAAoB,cACNhB,EAAEiB,SAEtB1B,0BACU2B,UAAUC,OAAO,iCAAkCH,0BAK7DJ,OAAS,gBAKPQ,yBAA2B,mBAAU,cAAe,mBAAoBR,KAAKS,MAAMC,QACnFC,qBAAuBL,UAAUC,OAAO,sCAAuC,CACjFK,GAAI,EACJC,KAAML,mBACNM,IAAKhB,aAAIC,YAAY,+BAAgC,CAACa,GAAIrB,SAAUwB,OAAQ,IAAI,KAGpFlC,WAAWmC,KACPpC,YACAoB,KAAKS,MACLQ,eACA,mBAAU,cAAe,UACzBN,uBAMhBhC,oBAAoB2B,UAAUC,OAC1B,gDAAiD,CAACW,4BAA4B,MAUhFD,YAAc,IACT,IACI,CAACR,MAAOU,iBACQ,KAAfA,kBACOV,MAEXU,WAAaA,WAAWC,oBAClBC,cAAgB,UACtBZ,MAAM1B,SAASuC,OACMA,KAAKC,SAASH,cAClBI,SAASL,aAClBE,cAAcI,KAAKH,SAGpBD"} \ 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 * A widget to search users within the gradebook.\n *\n * @module gradereport_user/user\n * @copyright 2022 Mathew May \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Pending from 'core/pending';\nimport * as Templates from 'core/templates';\nimport * as Repository from 'core_grades/searchwidget/repository';\nimport * as WidgetBase from 'core_grades/searchwidget/basewidget';\nimport {get_string as getString} from 'core/str';\nimport Url from 'core/url';\nimport $ from 'jquery';\nimport * as Selectors from 'core_grades/searchwidget/selectors';\n\n/**\n * Our entry point into starting to build the search widget.\n * It'll eventually, based upon the listeners, open the search widget and allow filtering.\n *\n * @method init\n */\nexport const init = () => {\n const pendingPromise = new Pending();\n registerListenerEvents();\n pendingPromise.resolve();\n};\n\n/**\n * Register user search widget related event listeners.\n *\n * @method registerListenerEvents\n */\nconst registerListenerEvents = () => {\n let {bodyPromiseResolver, bodyPromise} = WidgetBase.promisesAndResolvers();\n const dropdownMenuContainer = document.querySelector(Selectors.elements.getSearchWidgetDropdownSelector('user'));\n\n // Handle the 'shown.bs.dropdown' event (Fired when the dropdown menu is fully displayed).\n $(Selectors.elements.getSearchWidgetSelector('user')).on('show.bs.dropdown', async(e) => {\n const courseID = e.relatedTarget.dataset.courseid;\n const groupId = e.relatedTarget.dataset.groupid;\n const actionBaseUrl = Url.relativeUrl('/grade/report/user/index.php', {}, false);\n // Display a loading icon in the dropdown menu container until the body promise is resolved.\n await WidgetBase.showLoader(dropdownMenuContainer);\n\n // If an error occurs while fetching the data, display the error within the dropdown menu.\n const data = await Repository.userFetch(courseID, actionBaseUrl, groupId).catch(async(e) => {\n const errorTemplateData = {\n 'errormessage': e.message\n };\n bodyPromiseResolver(\n await Templates.render('core_grades/searchwidget/error', errorTemplateData)\n );\n });\n\n // Early return if there is no module data.\n if (data === []) {\n return;\n }\n\n // The HTML for the 'All users' option which will be rendered in the non-searchable content are of the widget.\n const allUsersOptionName = await getString('allusersnum', 'gradereport_user', data.users.length);\n const allUsersOption = await Templates.render('core_grades/searchwidget/searchitem', {\n id: 0,\n name: allUsersOptionName,\n url: Url.relativeUrl('/grade/report/user/index.php', {id: courseID, userid: 0}, false),\n });\n\n await WidgetBase.init(\n dropdownMenuContainer,\n bodyPromise,\n data.users,\n searchUsers(),\n allUsersOption\n );\n\n // Resolvers for passed functions in the dropdown menu creation.\n bodyPromiseResolver(Templates.render(\n 'core_grades/searchwidget/user/usersearch_body', {displayunsearchablecontent: true}\n ));\n });\n\n // Handle the 'hide.bs.dropdown' event (Fired when the dropdown menu is being closed).\n $(Selectors.elements.getSearchWidgetSelector('user')).on('hide.bs.dropdown', () => {\n // Reset the state once the user menu dropdown is closed.\n dropdownMenuContainer.innerHTML = '';\n });\n};\n\n/**\n * Define how we want to search and filter users when the user decides to input a search value.\n *\n * @method registerListenerEvents\n * @returns {function(): function(*, *): (*)}\n */\nconst searchUsers = () => {\n return () => {\n return (users, searchTerm) => {\n if (searchTerm === '') {\n return users;\n }\n searchTerm = searchTerm.toLowerCase();\n const searchResults = [];\n users.forEach((user) => {\n const userName = user.fullname.toLowerCase();\n if (userName.includes(searchTerm)) {\n searchResults.push(user);\n }\n });\n return searchResults;\n };\n };\n};\n"],"names":["pendingPromise","Pending","registerListenerEvents","resolve","bodyPromiseResolver","bodyPromise","WidgetBase","promisesAndResolvers","dropdownMenuContainer","document","querySelector","Selectors","elements","getSearchWidgetDropdownSelector","getSearchWidgetSelector","on","async","courseID","e","relatedTarget","dataset","courseid","groupId","groupid","actionBaseUrl","Url","relativeUrl","showLoader","data","Repository","userFetch","catch","errorTemplateData","message","Templates","render","allUsersOptionName","users","length","allUsersOption","id","name","url","userid","init","searchUsers","displayunsearchablecontent","innerHTML","searchTerm","toLowerCase","searchResults","forEach","user","fullname","includes","push"],"mappings":";;;;;;;4YAsCoB,WACVA,eAAiB,IAAIC,iBAC3BC,yBACAF,eAAeG,iBAQbD,uBAAyB,SACvBE,oBAACA,oBAADC,YAAsBA,aAAeC,WAAWC,6BAC9CC,sBAAwBC,SAASC,cAAcC,UAAUC,SAASC,gCAAgC,6BAGtGF,UAAUC,SAASE,wBAAwB,SAASC,GAAG,oBAAoBC,MAAAA,UACnEC,SAAWC,EAAEC,cAAcC,QAAQC,SACnCC,QAAUJ,EAAEC,cAAcC,QAAQG,QAClCC,cAAgBC,aAAIC,YAAY,+BAAgC,IAAI,SAEpEpB,WAAWqB,WAAWnB,6BAGtBoB,WAAaC,WAAWC,UAAUb,SAAUO,cAAeF,SAASS,OAAMf,MAAAA,UACtEgB,kBAAoB,cACNd,EAAEe,SAEtB7B,0BACU8B,UAAUC,OAAO,iCAAkCH,0BAK7DJ,OAAS,gBAKPQ,yBAA2B,mBAAU,cAAe,mBAAoBR,KAAKS,MAAMC,QACnFC,qBAAuBL,UAAUC,OAAO,sCAAuC,CACjFK,GAAI,EACJC,KAAML,mBACNM,IAAKjB,aAAIC,YAAY,+BAAgC,CAACc,GAAIvB,SAAU0B,OAAQ,IAAI,WAG9ErC,WAAWsC,KACbpC,sBACAH,YACAuB,KAAKS,MACLQ,cACAN,gBAIJnC,oBAAoB8B,UAAUC,OAC1B,gDAAiD,CAACW,4BAA4B,4BAKpFnC,UAAUC,SAASE,wBAAwB,SAASC,GAAG,oBAAoB,KAEzEP,sBAAsBuC,UAAY,OAUpCF,YAAc,IACT,IACI,CAACR,MAAOW,iBACQ,KAAfA,kBACOX,MAEXW,WAAaA,WAAWC,oBAClBC,cAAgB,UACtBb,MAAMc,SAASC,OACMA,KAAKC,SAASJ,cAClBK,SAASN,aAClBE,cAAcK,KAAKH,SAGpBF"} \ 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 4a2f66517b9..54a753e7bd0 100644 --- a/grade/report/user/amd/src/user.js +++ b/grade/report/user/amd/src/user.js @@ -14,7 +14,7 @@ // along with Moodle. If not, see . /** - * A small modal to search users within the gradebook. + * A widget to search users within the gradebook. * * @module gradereport_user/user * @copyright 2022 Mathew May @@ -23,11 +23,12 @@ import Pending from 'core/pending'; import * as Templates from 'core/templates'; -import CustomEvents from "core/custom_interaction_events"; import * as Repository from 'core_grades/searchwidget/repository'; import * as WidgetBase from 'core_grades/searchwidget/basewidget'; import {get_string as getString} from 'core/str'; import Url from 'core/url'; +import $ from 'jquery'; +import * as Selectors from 'core_grades/searchwidget/selectors'; /** * Our entry point into starting to build the search widget. @@ -47,62 +48,59 @@ export const init = () => { * @method registerListenerEvents */ const registerListenerEvents = () => { - const events = [ - 'click', - CustomEvents.events.activate, - CustomEvents.events.keyboardActivate - ]; - CustomEvents.define(document, events); - let {bodyPromiseResolver, bodyPromise} = WidgetBase.promisesAndResolvers(); + const dropdownMenuContainer = document.querySelector(Selectors.elements.getSearchWidgetDropdownSelector('user')); - // Register events. - events.forEach((event) => { - document.addEventListener(event, async(e) => { - const trigger = e.target.closest('.userwidget'); - if (trigger) { - const courseID = trigger.dataset.courseid; - const groupId = trigger.dataset.groupid; - e.preventDefault(); + // Handle the 'shown.bs.dropdown' event (Fired when the dropdown menu is fully displayed). + $(Selectors.elements.getSearchWidgetSelector('user')).on('show.bs.dropdown', async(e) => { + const courseID = e.relatedTarget.dataset.courseid; + const groupId = e.relatedTarget.dataset.groupid; + const actionBaseUrl = Url.relativeUrl('/grade/report/user/index.php', {}, false); + // Display a loading icon in the dropdown menu container until the body promise is resolved. + await WidgetBase.showLoader(dropdownMenuContainer); - const actionBaseUrl = Url.relativeUrl('/grade/report/user/index.php', {}, false); - // If an error occurs while fetching the data, display the error within the modal. - const data = await Repository.userFetch(courseID, actionBaseUrl, groupId).catch(async(e) => { - const errorTemplateData = { - 'errormessage': e.message - }; - bodyPromiseResolver( - await Templates.render('core_grades/searchwidget/error', errorTemplateData) - ); - }); - - // Early return if there is no module data. - if (data === []) { - return; - } - - // The HTML for the 'All users' option which will be rendered in the non-searchable content are of the widget. - const allUsersOptionName = await getString('allusersnum', 'gradereport_user', data.users.length); - const allUsersOption = await Templates.render('core_grades/searchwidget/searchitem', { - id: 0, - name: allUsersOptionName, - url: Url.relativeUrl('/grade/report/user/index.php', {id: courseID, userid: 0}, false), - }); - - WidgetBase.init( - bodyPromise, - data.users, - searchUsers(), - getString('selectauser', 'grades'), - allUsersOption - ); - } + // If an error occurs while fetching the data, display the error within the dropdown menu. + const data = await Repository.userFetch(courseID, actionBaseUrl, groupId).catch(async(e) => { + const errorTemplateData = { + 'errormessage': e.message + }; + bodyPromiseResolver( + await Templates.render('core_grades/searchwidget/error', errorTemplateData) + ); }); + + // Early return if there is no module data. + if (data === []) { + return; + } + + // The HTML for the 'All users' option which will be rendered in the non-searchable content are of the widget. + const allUsersOptionName = await getString('allusersnum', 'gradereport_user', data.users.length); + const allUsersOption = await Templates.render('core_grades/searchwidget/searchitem', { + id: 0, + name: allUsersOptionName, + url: Url.relativeUrl('/grade/report/user/index.php', {id: courseID, userid: 0}, false), + }); + + await WidgetBase.init( + dropdownMenuContainer, + bodyPromise, + data.users, + searchUsers(), + allUsersOption + ); + + // Resolvers for passed functions in the dropdown menu creation. + bodyPromiseResolver(Templates.render( + 'core_grades/searchwidget/user/usersearch_body', {displayunsearchablecontent: true} + )); + }); + + // Handle the 'hide.bs.dropdown' event (Fired when the dropdown menu is being closed). + $(Selectors.elements.getSearchWidgetSelector('user')).on('hide.bs.dropdown', () => { + // Reset the state once the user menu dropdown is closed. + dropdownMenuContainer.innerHTML = ''; }); - // Resolvers for passed functions in the modal creation. - bodyPromiseResolver(Templates.render( - 'core_grades/searchwidget/user/usersearch_body', {displayunsearchablecontent: true} - )); }; /** diff --git a/grade/report/user/styles.css b/grade/report/user/styles.css index fa84f0e9299..05335c51e98 100644 --- a/grade/report/user/styles.css +++ b/grade/report/user/styles.css @@ -148,7 +148,7 @@ align-items: center; } -.path-grade-report-user .user-selector .userinitials { +.path-grade-report-user .search-widget[data-searchtype="user"] .userinitials { width: 40px; height: 40px; } diff --git a/grade/report/user/templates/user_selector.mustache b/grade/report/user/templates/user_selector.mustache index 985fa0c0b50..2616f27f96b 100644 --- a/grade/report/user/templates/user_selector.mustache +++ b/grade/report/user/templates/user_selector.mustache @@ -38,8 +38,8 @@ } } }} -
-