���ѧۧݧ�ӧ�� �ާ֧ߧ֧էا֧� - ���֧էѧܧ�ڧ��ӧѧ�� - /home3/cpr76684/public_html/searchwidget.tar
���ѧ٧ѧ�
selectors.js 0000644 00000002676 15152024513 0007116 0 ustar 00 // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * Selectors for the search widget. * * @module core_grades/searchwidget/selectors * @copyright 2022 Mihail Geshoski <mihail@moodle.com> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ export default { regions: { searchResults: '[data-region="search-results-container-widget"]', unsearchableContent: '[data-region="unsearchable-content-container-widget"]', }, actions: { search: '[data-action="search"]', clearSearch: '[data-action="clearsearch"]', }, elements: { getSearchWidgetSelector: searchtype => `.search-widget[data-searchtype="${searchtype}"]`, getSearchWidgetDropdownSelector: searchtype => `.search-widget[data-searchtype="${searchtype}"] .dropdown-menu`, }, }; basewidget.js 0000644 00000016173 15152024513 0007226 0 ustar 00 // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * A widget to search users or grade items within the gradebook. * * @module core_grades/searchwidget/basewidget * @copyright 2022 Mathew May <mathew.solutions> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ import {debounce} from 'core/utils'; import * as Templates from 'core/templates'; import * as Selectors from 'core_grades/searchwidget/selectors'; import Notification from 'core/notification'; /** * Build the base searching widget. * * @method init * @param {HTMLElement} widgetContentContainer The selector for the widget container element. * @param {Promise} bodyPromise The promise from the callee of the contents to place in the widget container. * @param {Array} data An array of all the data generated by the callee. * @param {Function} searchFunc Partially applied function we need to manage search the passed dataset. * @param {string|null} unsearchableContent The content rendered in a non-searchable area. */ export const init = async(widgetContentContainer, bodyPromise, data, searchFunc, unsearchableContent = null) => { bodyPromise.then(async(bodyContent) => { // Render the body content. widgetContentContainer.innerHTML = bodyContent; // Render the unsearchable content if defined. if (unsearchableContent) { const unsearchableContentContainer = widgetContentContainer.querySelector(Selectors.regions.unsearchableContent); unsearchableContentContainer.innerHTML += unsearchableContent; } const searchResultsContainer = widgetContentContainer.querySelector(Selectors.regions.searchResults); // Display a loader until the search results are rendered. await showLoader(searchResultsContainer); // Render the search results. await renderSearchResults(searchResultsContainer, data); registerListenerEvents(widgetContentContainer, data, searchFunc); }).catch(Notification.exception); }; /** * Register the event listeners for the search widget. * * @method registerListenerEvents * @param {HTMLElement} widgetContentContainer The selector for the widget container element. * @param {Array} data An array of all the data generated by the callee. * @param {Function} searchFunc Partially applied function we need to manage search the passed dataset. */ export const registerListenerEvents = (widgetContentContainer, data, searchFunc) => { const searchResultsContainer = widgetContentContainer.querySelector(Selectors.regions.searchResults); const searchInput = widgetContentContainer.querySelector(Selectors.actions.search); // We want to focus on the first known user interable element within the dropdown. searchInput.focus(); const clearSearchButton = widgetContentContainer.querySelector(Selectors.actions.clearSearch); // The search input is triggered. searchInput.addEventListener('input', debounce(async() => { // If search query is present display the 'clear search' button, otherwise hide it. if (searchInput.value.length > 0) { clearSearchButton.classList.remove('d-none'); } else { clearSearchButton.classList.add('d-none'); } // Display the search results. await renderSearchResults( searchResultsContainer, debounceCallee( searchInput.value, data, searchFunc() ) ); }, 300)); // Clear search is triggered. clearSearchButton.addEventListener('click', async(e) => { e.stopPropagation(); // Clear the entered search query in the search bar. searchInput.value = ""; searchInput.focus(); clearSearchButton.classList.add('d-none'); // Display all results. await renderSearchResults( searchResultsContainer, debounceCallee( searchInput.value, data, searchFunc() ) ); }); }; /** * Renders the loading placeholder for the search widget. * * @method showLoader * @param {HTMLElement} container The DOM node where we'll render the loading placeholder. */ export const showLoader = async(container) => { const {html, js} = await Templates.renderForPromise('core_grades/searchwidget/loading', {}); Templates.replaceNodeContents(container, html, js); }; /** * We have a small helper that'll call the curried search function allowing callers to filter * the data set however we want rather than defining how data must be filtered. * * @method debounceCallee * @param {String} searchValue The input from the user that we'll search against. * @param {Array} data An array of all the data generated by the callee. * @param {Function} searchFunction Partially applied function we need to manage search the passed dataset. * @return {Array} The filtered subset of the provided data that we'll then render into the results. */ const debounceCallee = (searchValue, data, searchFunction) => { if (searchValue.length > 0) { // Search query is present. return searchFunction(data, searchValue); } return data; }; /** * Given the output of the callers' search function, render out the results into the search results container. * * @method renderSearchResults * @param {HTMLElement} searchResultsContainer The DOM node of the widget where we'll render the provided results. * @param {Array} searchResultsData The filtered subset of the provided data that we'll then render into the results. */ const renderSearchResults = async(searchResultsContainer, searchResultsData) => { const templateData = { 'searchresults': searchResultsData, }; // Build up the html & js ready to place into the help section. const {html, js} = await Templates.renderForPromise('core_grades/searchwidget/searchresults', templateData); await Templates.replaceNodeContents(searchResultsContainer, html, js); }; /** * We want to create the basic promises and hooks that the caller will implement, so we can build the search widget * ahead of time and allow the caller to resolve their promises once complete. * * @method promisesAndResolvers * @returns {{bodyPromise: Promise, bodyPromiseResolver}} */ export const promisesAndResolvers = () => { // We want to show the widget instantly but loading whilst waiting for our data. let bodyPromiseResolver; const bodyPromise = new Promise(resolve => { bodyPromiseResolver = resolve; }); return {bodyPromiseResolver, bodyPromise}; }; repository.js 0000644 00000005300 15152024513 0007315 0 ustar 00 // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * A repo for the search widget. * * @module core_grades/searchwidget/repository * @copyright 2022 Mathew May <mathew.solutions> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ import ajax from 'core/ajax'; /** * Given a course ID, we want to fetch the enrolled learners, so we may fetch their reports. * * @method userFetch * @param {int} courseid ID of the course to fetch the users of. * @param {string} actionBaseUrl The base URL for the user option. * @param {int} groupId ID of the group to fetch the users of. * @return {object} jQuery promise */ export const userFetch = (courseid, actionBaseUrl, groupId) => { const request = { methodname: 'core_grades_get_enrolled_users_for_search_widget', args: { courseid: courseid, actionbaseurl: actionBaseUrl, groupid: groupId, }, }; return ajax.call([request])[0]; }; /** * Given a course ID, we want to fetch the groups, so we may fetch their users. * * @method groupFetch * @param {int} courseid ID of the course to fetch the users of. * @param {string} actionBaseUrl The base URL for the group action. * @return {object} jQuery promise */ export const groupFetch = (courseid, actionBaseUrl) => { const request = { methodname: 'core_grades_get_groups_for_search_widget', args: { courseid: courseid, actionbaseurl: actionBaseUrl, }, }; return ajax.call([request])[0]; }; /** * Given a course ID, we want to fetch the gradable items, so we may fetch reports based on activity items. * Note: This will be worked upon in the single view issue. * * @method gradeitemFetch * @param {int} courseid ID of the course to fetch the users of. * @return {object} jQuery promise */ export const gradeitemFetch = (courseid) => { const request = { methodname: 'gradereport_singleview_get_grade_items_for_search_widget', args: { courseid: courseid, }, }; return ajax.call([request])[0]; }; group.js 0000644 00000010573 15152024513 0006242 0 ustar 00 // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * A widget to search groups within the gradebook. * * @module core_grades/searchwidget/group * @copyright 2022 Mathew May <mathew.solutions> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ import Pending from 'core/pending'; import * as Templates from 'core/templates'; import * as Repository from 'core_grades/searchwidget/repository'; import * as WidgetBase from 'core_grades/searchwidget/basewidget'; import $ from 'jquery'; import * as Selectors from 'core_grades/searchwidget/selectors'; /** * Whether the event listener has already been registered for this module. * * @type {boolean} */ let registered = false; /** * Our entry point into starting to build the group search widget. * * It'll eventually, based upon the listeners, open the search widget and allow filtering. * * @method init */ export const init = () => { if (registered) { return; } const pendingPromise = new Pending(); registerListenerEvents(); pendingPromise.resolve(); registered = true; }; /** * Register event listeners. * * @method registerListenerEvents */ const registerListenerEvents = () => { let {bodyPromiseResolver, bodyPromise} = WidgetBase.promisesAndResolvers(); const dropdownMenuContainer = document.querySelector(Selectors.elements.getSearchWidgetDropdownSelector('group')); // Handle the 'shown.bs.dropdown' event (Fired when the dropdown menu is fully displayed). $(Selectors.elements.getSearchWidgetSelector('group')).on('show.bs.dropdown', async(e) => { const courseID = e.relatedTarget.dataset.courseid; const actionBaseUrl = e.relatedTarget.dataset.actionBaseUrl; // 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.groupFetch(courseID, actionBaseUrl).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; } await WidgetBase.init( dropdownMenuContainer, bodyPromise, data.groups, searchGroups(), ); }); // Resolvers for passed functions in the dropdown creation. bodyPromiseResolver(Templates.render( 'core_grades/searchwidget/group/groupsearch_body', [] )); // Handle the 'hide.bs.dropdown' event (Fired when the dropdown menu is being closed). $(Selectors.elements.getSearchWidgetSelector('group')).on('hide.bs.dropdown', () => { // Reset the state once the groups menu dropdown is closed. dropdownMenuContainer.innerHTML = ''; }); }; /** * Define how we want to search and filter groups when the user decides to input a search value. * * @method registerListenerEvents * @returns {function(): function(*, *): (*)} */ const searchGroups = () => { return () => { return (groups, searchTerm) => { if (searchTerm === '') { return groups; } searchTerm = searchTerm.toLowerCase(); const searchResults = []; groups.forEach((group) => { const groupName = group.name.toLowerCase(); if (groupName.includes(searchTerm)) { searchResults.push(group); } }); return searchResults; }; }; }; group/groupsearch_body.mustache 0000644 00000002230 15152217751 0012775 0 ustar 00 {{! This file is part of Moodle - http://moodle.org/ Moodle is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Moodle is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Moodle. If not, see <http://www.gnu.org/licenses/>. }} {{! @template core_grades/searchwidget/group/groupsearch_body The body of the group widget. Example context (json): {} }} {{< core/search_input_auto }} {{$label}}{{#str}} searchgroups, core_grades {{/str}}{{/label}} {{$placeholder}}{{#str}} searchgroups, core_grades {{/str}}{{/placeholder}} {{/ core/search_input_auto }} <div class="searchresultscontainer" data-region="search-results-container-widget" aria-live="polite"></div> searchitem.mustache 0000644 00000003272 15152217751 0010435 0 ustar 00 {{! This file is part of Moodle - http://moodle.org/ Moodle is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Moodle is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Moodle. If not, see <http://www.gnu.org/licenses/>. }} {{! @template core_grades/searchwidget/searchitem Search result line items. Example context (json): { "id": "1", "name": "Quiz 1", "url": "http://foo.bar/gradereport/?userid=25", "fullname": "Cameron Greeve", "active": true } }} <li class="w-100 result-row" role="none" id="result-row-{{id}}"> {{#name}} <a role="menuitem" id="item-{{id}}" href="{{url}}" class="dropdown-item d-flex px-2 py-1" tabindex="-1""> <span class="pull-left result-cell text-truncate mr-2"> {{name}} </span> </a> {{/name}} {{^name}} <a role="menuitem" id="user-{{id}}" href="{{url}}" class="dropdown-item d-flex px-2 py-1 align-items-center" tabindex="-1"> <span class="w-50 pull-left text-truncate mr-2"> {{fullname}} </span> <span class="w-50 pull-left text-truncate small email"> {{email}} </span> </a> {{/name}} </li> searchresults.mustache 0000644 00000003365 15152217751 0011203 0 ustar 00 {{! This file is part of Moodle - http://moodle.org/ Moodle is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Moodle is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Moodle. If not, see <http://www.gnu.org/licenses/>. }} {{! @template core_grades/searchwidget/searchresults The wrapper in which our search results will be rendered Example context (json): { "searchresults": [ { "id": "1", "name": "Quiz 1", "url": "http://foo.bar/gradereport/?userid=25", "fullname": "Cameron Greeve", "sendmessage": "http://foo.bar/message/index.php?id=25", "addcontact": "http://foo.bar/message/index.php?user1=2&user2=14&addcontact=14&sesskey=XXXXX", "currentuser": "2" } ] } }} <div class="searchresultitemscontainer-wrapper dropdown"> <ul class="searchresultitemscontainer d-flex flex-column mw-100 position-relative py-2 list-group" role="menu" data-region="search-result-items-container" tabindex="0"> {{#searchresults}} {{>core_grades/searchwidget/searchitem}} {{/searchresults}} {{^searchresults}} <p>{{#str}} resultsfound, core, 0 {{/str}}</p> {{/searchresults}} </ul> </div> user/usersearch_body.mustache 0000644 00000002610 15152217751 0012443 0 ustar 00 {{! This file is part of Moodle - http://moodle.org/ Moodle is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Moodle is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Moodle. If not, see <http://www.gnu.org/licenses/>. }} {{! @template core_grades/searchwidget/user/usersearch_body The body of the user widget. Example context (json): { "displayunsearchablecontent": true } }} {{< core/search_input_auto }} {{$label}}{{#str}} searchusers, core_grades {{/str}}{{/label}} {{$placeholder}}{{#str}} searchusers, core_grades {{/str}}{{/placeholder}} {{/ core/search_input_auto }} <div class="searchresultscontainer" data-region="search-results-container-widget" aria-live="polite"></div> {{#displayunsearchablecontent}} <div class="unsearchablecontentcontainer" data-region="unsearchable-content-container-widget" role="menu" aria-live="polite"></div> {{/displayunsearchablecontent}} error.mustache 0000644 00000002356 15152217751 0007444 0 ustar 00 {{! This file is part of Moodle - http://moodle.org/ Moodle is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Moodle is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Moodle. If not, see <http://www.gnu.org/licenses/>. }} {{! @template core_grades/searchwidget/error Chooser error template. Variables required for this template: * errormessage - The error message Example context (json): { "errormessage": "Error" } }} <div class="p-2 px-sm-5 py-sm-4"> <div class="alert alert-danger" role="alert"> <h5 class="alert-heading"> <i class="fa fa-exclamation-circle fa-fw text-danger"></i> {{#str}} error, error {{/str}} </h5> <hr> <p class="text-break">{{{errormessage}}}</p> </div> </div> loading.mustache 0000644 00000001705 15152217751 0007725 0 ustar 00 {{! This file is part of Moodle - http://moodle.org/ Moodle is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Moodle is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Moodle. If not, see <http://www.gnu.org/licenses/>. }} {{! @template core_grades/searchwidget/loading This template renders the loading placeholder for the search widget. Example context (json): {} }} <div class="d-flex w-100 h-100 justify-content-center align-items-center"> {{> core/loading }} </div>
| ver. 1.4 |
Github
|
.
| PHP 7.4.33 | ���֧ߧ֧�ѧ�ڧ� ����ѧߧڧ��: 0 |
proxy
|
phpinfo
|
���ѧ����ۧܧ�