MDL-66828 mod_forum: Display notification on grade save
[moodle.git] / mod / forum / amd / src / local / grades / grader.js
1 // This file is part of Moodle - http://moodle.org/
2 //
3 // Moodle is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 3 of the License, or
6 // (at your option) any later version.
7 //
8 // Moodle is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16 /**
17  * This module will tie together all of the different calls the gradable module will make.
18  *
19  * @module     mod_forum/local/grades/grader
20  * @package    mod_forum
21  * @copyright  2019 Mathew May <mathew.solutions>
22  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
24 import Templates from 'core/templates';
25 // TODO import Notification from 'core/notification';
26 import Selectors from './local/grader/selectors';
27 import * as UserPicker from './local/grader/user_picker';
28 import {createLayout as createFullScreenWindow} from 'mod_forum/local/layout/fullscreen';
29 import getGradingPanelFunctions from './local/grader/gradingpanel';
30 import {add as addToast} from 'core/toast';
31 import {get_string as getString} from 'core/str';
33 const templateNames = {
34     grader: {
35         app: 'mod_forum/local/grades/grader',
36     },
37 };
39 const displayUserPicker = (root, html) => {
40     const pickerRegion = root.querySelector(Selectors.regions.pickerRegion);
41     Templates.replaceNodeContents(pickerRegion, html, '');
42 };
44 const fetchContentFromRender = (html, js) => {
45     return [html, js];
46 };
48 const getUpdateUserContentFunction = (root, getContentForUser, getGradeForUser) => {
49     return async(user) => {
50         const [
51             [html, js],
52             userGrade,
53         ] = await Promise.all([
54             getContentForUser(user.id).then(fetchContentFromRender),
55             getGradeForUser(user.id),
56         ]);
57         Templates.replaceNodeContents(root.querySelector(Selectors.regions.moduleReplace), html, js);
59         const [
60             gradingPanelHtml,
61             gradingPanelJS
62         ] = await Templates.render(userGrade.templatename, userGrade.grade).then(fetchContentFromRender);
63         Templates.replaceNodeContents(root.querySelector(Selectors.regions.gradingPanel), gradingPanelHtml, gradingPanelJS);
64     };
65 };
67 const registerEventListeners = (graderLayout) => {
68     const graderContainer = graderLayout.getContainer();
69     graderContainer.addEventListener('click', (e) => {
70         if (e.target.closest(Selectors.buttons.toggleFullscreen)) {
71             e.stopImmediatePropagation();
72             e.preventDefault();
73             graderLayout.toggleFullscreen();
74         } else if (e.target.closest(Selectors.buttons.closeGrader)) {
75             e.stopImmediatePropagation();
76             e.preventDefault();
78             graderLayout.close();
79         }
80     });
81 };
83 /**
84  * Get the function used to save a user grade.
85  *
86  * @param {Element} root The contaienr
87  * @param {Function} setGradeForUser The function that will be called.
88  * @return {Function}
89  */
90 const getSaveUserGradeFunction = (root, setGradeForUser) => {
91     return async user => {
92         try {
93             const result = await setGradeForUser(user.id, root.querySelector(Selectors.regions.gradingPanel));
94             addToast(await getString('grades:gradesavedfor', 'mod_forum', user));
96             return result;
97         } catch (error) {
98             throw error;
99         }
100     };
101 };
103 // Make this explicit rather than object
104 export const launch = async(getListOfUsers, getContentForUser, getGradeForUser, setGradeForUser, {
105     initialUserId = 0, moduleName
106 } = {}) => {
108     const [
109         graderLayout,
110         graderHTML,
111         userList,
112     ] = await Promise.all([
113         createFullScreenWindow({fullscreen: false, showLoader: false}),
114         Templates.render(templateNames.grader.app, {moduleName: moduleName}),
115         getListOfUsers(),
116     ]);
117     const graderContainer = graderLayout.getContainer();
119     Templates.replaceNodeContents(graderContainer, graderHTML, '');
120     registerEventListeners(graderLayout);
121     const updateUserContent = getUpdateUserContentFunction(graderContainer, getContentForUser, getGradeForUser);
123     const pickerHTML = await UserPicker.buildPicker(
124         userList,
125         initialUserId,
126         updateUserContent,
127         getSaveUserGradeFunction(graderContainer, setGradeForUser)
128     );
130     displayUserPicker(graderContainer, pickerHTML);
131 };
133 export {getGradingPanelFunctions};