1 {"version":3,"sources":["../../../../../src/local/grades/local/grader/user_picker.js"],"names":["UserPicker","userList","showUserCallback","preChangeUserCallback","currentUserIndex","render","bind","setUserId","userId","userIndex","findIndex","user","id","parseInt","Error","root","document","createElement","renderNavigator","html","js","Templates","replaceNodeContents","showUser","currentUser","registerEventListeners","renderForPromise","context","Promise","all","renderUserChange","userRegion","querySelector","Selectors","regions","addEventListener","e","button","target","closest","actions","changeUser","whole","spinner","updateIndex","dataset","direction","resolve","length","total","displayIndex","users","initialUserId","userPicker"],"mappings":"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","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 <http://www.gnu.org/licenses/>.\n\n/**\n * This module will tie together all of the different calls the gradable module will make.\n *\n * @module mod_forum/local/grades/local/grader/user_picker\n * @package mod_forum\n * @copyright 2019 Mathew May <mathew.solutions>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Templates from 'core/templates';\nimport Selectors from './user_picker/selectors';\nimport {addIconToContainerWithPromise} from 'core/loadingicon';\n\nconst templatePath = 'mod_forum/local/grades/local/grader';\n\nclass UserPicker {\n\n /**\n * Constructor for the User Picker.\n *\n * @param {Array} userList List of users\n * @param {Function} showUserCallback The callback used to display the user\n * @param {Function} preChangeUserCallback The callback to use before changing user\n */\n constructor(userList, showUserCallback, preChangeUserCallback) {\n this.userList = userList;\n this.showUserCallback = showUserCallback;\n this.preChangeUserCallback = preChangeUserCallback;\n this.currentUserIndex = 0;\n\n // Ensure that render is bound correctly.\n this.render = this.render.bind(this);\n this.setUserId = this.setUserId.bind(this);\n }\n\n /**\n * Set the current userid without rendering the change.\n * To show the user, call showUser too.\n *\n * @param {Number} userId\n */\n setUserId(userId) {\n // Determine the current index based on the user ID.\n const userIndex = this.userList.findIndex(user => {\n return user.id === parseInt(userId);\n });\n\n if (userIndex === -1) {\n throw Error(`User with id ${userId} not found`);\n }\n\n this.currentUserIndex = userIndex;\n }\n\n /**\n * Render the user picker.\n */\n async render() {\n // Create the root node.\n this.root = document.createElement('div');\n\n const {html, js} = await this.renderNavigator();\n Templates.replaceNodeContents(this.root, html, js);\n\n // Call the showUser function to show the first user immediately.\n await this.showUser(this.currentUser);\n\n // Ensure that the event listeners are all bound.\n this.registerEventListeners();\n }\n\n /**\n * Render the navigator itself.\n *\n * @returns {Promise}\n */\n renderNavigator() {\n return Templates.renderForPromise(`${templatePath}/user_picker`, {});\n }\n\n /**\n * Render the current user details for the picker.\n *\n * @param {Object} context The data used to render the user picker.\n * @returns {Promise}\n */\n renderUserChange(context) {\n return Templates.renderForPromise(`${templatePath}/user_picker/user`, context);\n }\n\n /**\n * Show the specified user in the picker.\n *\n * @param {Object} user\n */\n async showUser(user) {\n const [{html, js}] = await Promise.all([this.renderUserChange(user), this.showUserCallback(user)]);\n const userRegion = this.root.querySelector(Selectors.regions.userRegion);\n Templates.replaceNodeContents(userRegion, html, js);\n }\n\n /**\n * Register the event listeners for the user picker.\n */\n registerEventListeners() {\n this.root.addEventListener('click', async e => {\n const button = e.target.closest(Selectors.actions.changeUser);\n if (button) {\n const whole = document.querySelector('[data-region=\"unified-grader\"]');\n const spinner = addIconToContainerWithPromise(whole);\n\n await this.preChangeUserCallback(this.currentUser);\n this.updateIndex(parseInt(button.dataset.direction));\n await this.showUser(this.currentUser);\n\n spinner.resolve();\n }\n });\n }\n\n /**\n * Update the current user index.\n *\n * @param {Number} direction\n * @returns {Number}}\n */\n updateIndex(direction) {\n this.currentUserIndex += direction;\n\n // Loop around the edges.\n if (this.currentUserIndex < 0) {\n this.currentUserIndex = this.userList.length - 1;\n } else if (this.currentUserIndex > this.userList.length - 1) {\n this.currentUserIndex = 0;\n }\n\n return this.currentUserIndex;\n }\n\n /**\n * Get the details of the user currently shown with the total number of users, and the 1-indexed count of the\n * current user.\n *\n * @returns {Object}\n */\n get currentUser() {\n return {\n ...this.userList[this.currentUserIndex],\n total: this.userList.length,\n displayIndex: this.currentUserIndex + 1,\n };\n }\n\n /**\n * Get the root node for the User Picker.\n *\n * @returns {HTMLElement}\n */\n get rootNode() {\n return this.root;\n }\n}\n\n/**\n * Create a new user picker.\n *\n * @param {Array} users The list of users\n * @param {Function} showUserCallback The function to call to show a specific user\n * @param {Function} preChangeUserCallback The fucntion to call to save the grade for the current user\n * @param {Number} [currentUserID] The userid of the current user\n * @returns {UserPicker}\n */\nexport default async(users, showUserCallback, preChangeUserCallback, {\n initialUserId = null,\n } = {}\n) => {\n const userPicker = new UserPicker(users, showUserCallback, preChangeUserCallback);\n if (initialUserId) {\n userPicker.setUserId(initialUserId);\n }\n await userPicker.render();\n\n return userPicker;\n};\n"],"file":"user_picker.min.js"}