%PDF- %PDF-
Direktori : /home/vacivi36/ava/mod/forum/amd/src/local/grades/local/grader/ |
Current File : /home/vacivi36/ava/mod/forum/amd/src/local/grades/local/grader/user_picker.js |
// 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/>. /** * This module will tie together all of the different calls the gradable module will make. * * @module mod_forum/local/grades/local/grader/user_picker * @copyright 2019 Mathew May <mathew.solutions> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ import Templates from 'core/templates'; import Selectors from './user_picker/selectors'; import {get_string as getString} from 'core/str'; const templatePath = 'mod_forum/local/grades/local/grader'; /** * The Grader User Picker. * * @class mod_forum/local/grades/local/grader/user_picker */ class UserPicker { /** * Constructor for the User Picker. * * @constructor mod_forum/local/grades/local/grader/user_picker * @param {Array} userList List of users * @param {Function} showUserCallback The callback used to display the user * @param {Function} preChangeUserCallback The callback to use before changing user */ constructor(userList, showUserCallback, preChangeUserCallback) { this.userList = userList; this.showUserCallback = showUserCallback; this.preChangeUserCallback = preChangeUserCallback; this.currentUserIndex = 0; // Ensure that render is bound correctly. this.render = this.render.bind(this); this.setUserId = this.setUserId.bind(this); } /** * Set the current userid without rendering the change. * To show the user, call showUser too. * * @param {Number} userId */ setUserId(userId) { // Determine the current index based on the user ID. const userIndex = this.userList.findIndex(user => { return user.id === parseInt(userId); }); if (userIndex === -1) { throw Error(`User with id ${userId} not found`); } this.currentUserIndex = userIndex; } /** * Render the user picker. */ async render() { // Create the root node. this.root = document.createElement('div'); const {html, js} = await this.renderNavigator(); Templates.replaceNodeContents(this.root, html, js); // Call the showUser function to show the first user immediately. await this.showUser(this.currentUser); // Ensure that the event listeners are all bound. this.registerEventListeners(); } /** * Render the navigator itself. * * @returns {Promise} */ renderNavigator() { return Templates.renderForPromise(`${templatePath}/user_picker`, {}); } /** * Render the current user details for the picker. * * @param {Object} context The data used to render the user picker. * @returns {Promise} */ renderUserChange(context) { return Templates.renderForPromise(`${templatePath}/user_picker/user`, context); } /** * Show the specified user in the picker. * * @param {Object} user */ async showUser(user) { const [{html, js}] = await Promise.all([this.renderUserChange(user), this.showUserCallback(user)]); const userRegion = this.root.querySelector(Selectors.regions.userRegion); Templates.replaceNodeContents(userRegion, html, js); // Update the hidden now-grading region so screen readers can announce the user that's currently being graded. const currentUserRegion = this.root.querySelector(Selectors.regions.currentUser); currentUserRegion.textContent = await getString('nowgradinguser', 'mod_forum', user.fullname); } /** * Register the event listeners for the user picker. */ registerEventListeners() { this.root.addEventListener('click', async(e) => { const button = e.target.closest(Selectors.actions.changeUser); if (button) { const result = await this.preChangeUserCallback(this.currentUser); if (!result.failed) { this.updateIndex(parseInt(button.dataset.direction)); await this.showUser(this.currentUser); } } }); } /** * Update the current user index. * * @param {Number} direction * @returns {Number}} */ updateIndex(direction) { this.currentUserIndex += direction; // Loop around the edges. if (this.currentUserIndex < 0) { this.currentUserIndex = this.userList.length - 1; } else if (this.currentUserIndex > this.userList.length - 1) { this.currentUserIndex = 0; } return this.currentUserIndex; } /** * Get the details of the user currently shown with the total number of users, and the 1-indexed count of the * current user. * * @returns {Object} */ get currentUser() { return { ...this.userList[this.currentUserIndex], total: this.userList.length, displayIndex: this.currentUserIndex + 1, }; } /** * Get the root node for the User Picker. * * @returns {HTMLElement} */ get rootNode() { return this.root; } } /** * Create a new user picker. * * @param {Array} users The list of users * @param {Function} showUserCallback The function to call to show a specific user * @param {Function} preChangeUserCallback The fucntion to call to save the grade for the current user * @param {Number} [currentUserID] The userid of the current user * @returns {UserPicker} */ export default async( users, showUserCallback, preChangeUserCallback, { initialUserId = null, } = {} ) => { const userPicker = new UserPicker(users, showUserCallback, preChangeUserCallback); if (initialUserId) { userPicker.setUserId(initialUserId); } await userPicker.render(); return userPicker; };