MDL-76246 gradereport_singleview: Make the user search widget a combobox

This commit is contained in:
Shamim Rezaie
2023-03-22 20:59:14 +11:00
parent 3db5625fc9
commit d856c48639
4 changed files with 59 additions and 14 deletions
+2 -2
View File
@@ -1,10 +1,10 @@
define("gradereport_singleview/user",["exports","core/pending","core/templates","core_grades/searchwidget/repository","core_grades/searchwidget/basewidget","core/url","jquery","core_grades/searchwidget/selectors"],(function(_exports,_pending,Templates,Repository,WidgetBase,_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}}
define("gradereport_singleview/user",["exports","core/local/aria/focuslock","core/pending","core/templates","core_grades/searchwidget/repository","core_grades/searchwidget/basewidget","core/url","jquery","core_grades/searchwidget/selectors"],(function(_exports,FocusLockManager,_pending,Templates,Repository,WidgetBase,_url,_jquery,Selectors){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}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}
/**
* A small modal to search users within the gradebook.
*
* @module gradereport_singleview/user
* @copyright 2022 Mathew May <mathew.solutions>
* @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),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/singleview/index.php",{item:"user"},!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))}));data!==[]&&(await WidgetBase.init(dropdownMenuContainer,bodyPromise,data.users,searchUsers()),bodyPromiseResolver(Templates.render("core_grades/searchwidget/user/usersearch_body",[])))})),(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}}));
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,FocusLockManager=_interopRequireWildcard(FocusLockManager),_pending=_interopRequireDefault(_pending),Templates=_interopRequireWildcard(Templates),Repository=_interopRequireWildcard(Repository),WidgetBase=_interopRequireWildcard(WidgetBase),_url=_interopRequireDefault(_url),_jquery=_interopRequireDefault(_jquery),Selectors=_interopRequireWildcard(Selectors);_exports.init=()=>{if(document.querySelector(Selectors.elements.getSearchWidgetSelector("user"))){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")),menuContainer=document.querySelector(Selectors.elements.getSearchWidgetSelector("user")),inputElement=menuContainer.querySelector('input[name="userid"]');(0,_jquery.default)(menuContainer).on("show.bs.dropdown",(async e=>{const courseId=e.relatedTarget.dataset.courseid,groupId=e.relatedTarget.dataset.groupid,actionBaseUrl=_url.default.relativeUrl("/grade/report/singleview/index.php",{item:"user"},!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))}));data!==[]&&(await WidgetBase.init(dropdownMenuContainer,bodyPromise,data.users,searchUsers(),null,afterSelect),bodyPromiseResolver(Templates.render("core_grades/searchwidget/user/usersearch_body",[])),FocusLockManager.trapFocus(dropdownMenuContainer))})),(0,_jquery.default)(menuContainer).on("hide.bs.dropdown",(()=>{FocusLockManager.untrapFocus()})),inputElement.addEventListener("change",(e=>{const courseId=menuContainer.querySelector(".dropdown-toggle").dataset.courseid,actionUrl=_url.default.relativeUrl("/grade/report/singleview/index.php",{id:courseId,item:"user",userid:e.target.value},!1);location.href=actionUrl,e.stopPropagation()}))},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},afterSelect=selected=>{const menuContainer=document.querySelector(Selectors.elements.getSearchWidgetSelector("user")),inputElement=menuContainer.querySelector('input[name="userid"]');(0,_jquery.default)(menuContainer).dropdown("hide"),inputElement.value!=selected&&(inputElement.value=selected,inputElement.dispatchEvent(new Event("change",{bubbles:!0})))}}));
//# sourceMappingURL=user.min.js.map
File diff suppressed because one or more lines are too long
+54 -11
View File
@@ -21,6 +21,7 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import * as FocusLockManager from 'core/local/aria/focuslock';
import Pending from 'core/pending';
import * as Templates from 'core/templates';
import * as Repository from 'core_grades/searchwidget/repository';
@@ -36,9 +37,11 @@ import * as Selectors from 'core_grades/searchwidget/selectors';
* @method init
*/
export const init = () => {
const pendingPromise = new Pending();
registerListenerEvents();
pendingPromise.resolve();
if (document.querySelector(Selectors.elements.getSearchWidgetSelector('user'))) {
const pendingPromise = new Pending();
registerListenerEvents();
pendingPromise.resolve();
}
};
/**
@@ -49,17 +52,19 @@ export const init = () => {
const registerListenerEvents = () => {
let {bodyPromiseResolver, bodyPromise} = WidgetBase.promisesAndResolvers();
const dropdownMenuContainer = document.querySelector(Selectors.elements.getSearchWidgetDropdownSelector('user'));
const menuContainer = document.querySelector(Selectors.elements.getSearchWidgetSelector('user'));
const inputElement = menuContainer.querySelector('input[name="userid"]');
// 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;
$(menuContainer).on('show.bs.dropdown', async(e) => {
const courseId = e.relatedTarget.dataset.courseid;
const groupId = e.relatedTarget.dataset.groupid;
const actionBaseUrl = Url.relativeUrl('/grade/report/singleview/index.php', {item: 'user'}, false);
// Display a loading icon in the dropdown menu container until the body promise is resolved.
await WidgetBase.showLoader(dropdownMenuContainer);
// 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 data = await Repository.userFetch(courseId, actionBaseUrl, groupId).catch(async(e) => {
const errorTemplateData = {
'errormessage': e.message
};
@@ -77,24 +82,45 @@ const registerListenerEvents = () => {
dropdownMenuContainer,
bodyPromise,
data.users,
searchUsers()
searchUsers(),
null,
afterSelect
);
// Resolvers for passed functions in the dropdown menu creation.
bodyPromiseResolver(Templates.render('core_grades/searchwidget/user/usersearch_body', []));
// Lock tab control. It has to be locked because the dropdown's role is dialog.
FocusLockManager.trapFocus(dropdownMenuContainer);
});
// 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 = '';
$(menuContainer).on('hide.bs.dropdown', () => {
FocusLockManager.untrapFocus();
});
inputElement.addEventListener('change', e => {
const toggle = menuContainer.querySelector('.dropdown-toggle');
const courseId = toggle.dataset.courseid;
const actionUrl = Url.relativeUrl(
'/grade/report/singleview/index.php',
{
id: courseId,
item: 'user',
userid: e.target.value
},
false
);
location.href = actionUrl;
e.stopPropagation();
});
};
/**
* Define how we want to search and filter users when the user decides to input a search value.
*
* @method registerListenerEvents
* @method searchUsers
* @returns {function(): function(*, *): (*)}
*/
const searchUsers = () => {
@@ -115,3 +141,20 @@ const searchUsers = () => {
};
};
};
/**
* Define the action to be performed when an item is selected by the search widget.
*
* @param {String} selected The selected item's value.
*/
const afterSelect = (selected) => {
const menuContainer = document.querySelector(Selectors.elements.getSearchWidgetSelector('user'));
const inputElement = menuContainer.querySelector('input[name="userid"]');
$(menuContainer).dropdown('hide'); // Otherwise the dropdown stays open when user choose an option using keyboard.
if (inputElement.value != selected) {
inputElement.value = selected;
inputElement.dispatchEvent(new Event('change', {bubbles: true}));
}
};
+2
View File
@@ -46,6 +46,7 @@ class gradereport_singleview_renderer extends plugin_renderer_base {
public function users_selector(object $course, ?int $userid = null, ?int $groupid = null): string {
$data = [
'name' => 'userid',
'courseid' => $course->id,
'groupid' => $groupid ?? 0,
];
@@ -58,6 +59,7 @@ class gradereport_singleview_renderer extends plugin_renderer_base {
'text' => fullname($user),
'additionaltext' => $user->email,
];
$data['userid'] = $userid;
}
$this->page->requires->js_call_amd('gradereport_singleview/user', 'init');