Commit | Line | Data |
---|---|---|
bae67469 MM |
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/>. | |
15 | ||
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'; | |
bae67469 | 25 | import Selectors from './local/grader/selectors'; |
45c0584c | 26 | import getUserPicker from './local/grader/user_picker'; |
bae67469 | 27 | import {createLayout as createFullScreenWindow} from 'mod_forum/local/layout/fullscreen'; |
f281c616 | 28 | import getGradingPanelFunctions from './local/grader/gradingpanel'; |
77ee8778 AN |
29 | import {add as addToast} from 'core/toast'; |
30 | import {get_string as getString} from 'core/str'; | |
bae67469 MM |
31 | |
32 | const templateNames = { | |
33 | grader: { | |
34 | app: 'mod_forum/local/grades/grader', | |
35 | }, | |
36 | }; | |
37 | ||
38 | const displayUserPicker = (root, html) => { | |
39 | const pickerRegion = root.querySelector(Selectors.regions.pickerRegion); | |
40 | Templates.replaceNodeContents(pickerRegion, html, ''); | |
41 | }; | |
42 | ||
f281c616 AN |
43 | const fetchContentFromRender = (html, js) => { |
44 | return [html, js]; | |
45 | }; | |
46 | ||
47 | const getUpdateUserContentFunction = (root, getContentForUser, getGradeForUser) => { | |
bae67469 MM |
48 | return async(user) => { |
49 | const [ | |
f281c616 AN |
50 | [html, js], |
51 | userGrade, | |
bae67469 | 52 | ] = await Promise.all([ |
f281c616 AN |
53 | getContentForUser(user.id).then(fetchContentFromRender), |
54 | getGradeForUser(user.id), | |
bae67469 MM |
55 | ]); |
56 | Templates.replaceNodeContents(root.querySelector(Selectors.regions.moduleReplace), html, js); | |
f281c616 AN |
57 | |
58 | const [ | |
59 | gradingPanelHtml, | |
60 | gradingPanelJS | |
61 | ] = await Templates.render(userGrade.templatename, userGrade.grade).then(fetchContentFromRender); | |
62 | Templates.replaceNodeContents(root.querySelector(Selectors.regions.gradingPanel), gradingPanelHtml, gradingPanelJS); | |
bae67469 MM |
63 | }; |
64 | }; | |
65 | ||
eaee6477 | 66 | const registerEventListeners = (graderLayout, userPicker, saveGradeFunction) => { |
bae67469 MM |
67 | const graderContainer = graderLayout.getContainer(); |
68 | graderContainer.addEventListener('click', (e) => { | |
69 | if (e.target.closest(Selectors.buttons.toggleFullscreen)) { | |
70 | e.stopImmediatePropagation(); | |
71 | e.preventDefault(); | |
72 | graderLayout.toggleFullscreen(); | |
eaee6477 AN |
73 | |
74 | return; | |
75 | } | |
76 | ||
77 | if (e.target.closest(Selectors.buttons.closeGrader)) { | |
bae67469 MM |
78 | e.stopImmediatePropagation(); |
79 | e.preventDefault(); | |
80 | ||
81 | graderLayout.close(); | |
eaee6477 AN |
82 | |
83 | return; | |
84 | } | |
85 | ||
86 | if (e.target.closest(Selectors.buttons.saveGrade)) { | |
87 | saveGradeFunction(userPicker.currentUser); | |
bae67469 MM |
88 | } |
89 | }); | |
90 | }; | |
91 | ||
77ee8778 AN |
92 | /** |
93 | * Get the function used to save a user grade. | |
94 | * | |
95 | * @param {Element} root The contaienr | |
96 | * @param {Function} setGradeForUser The function that will be called. | |
97 | * @return {Function} | |
98 | */ | |
f281c616 | 99 | const getSaveUserGradeFunction = (root, setGradeForUser) => { |
77ee8778 AN |
100 | return async user => { |
101 | try { | |
102 | const result = await setGradeForUser(user.id, root.querySelector(Selectors.regions.gradingPanel)); | |
103 | addToast(await getString('grades:gradesavedfor', 'mod_forum', user)); | |
104 | ||
105 | return result; | |
106 | } catch (error) { | |
107 | throw error; | |
108 | } | |
f281c616 AN |
109 | }; |
110 | }; | |
111 | ||
eaee6477 AN |
112 | /** |
113 | * Launch the grader interface with the specified parameters. | |
114 | * | |
115 | * @param {Function} getListOfUsers A function to get the list of users | |
116 | * @param {Function} getContentForUser A function to get the content for a specific user | |
117 | * @param {Function} getGradeForUser A function get the grade details for a specific user | |
118 | * @param {Function} setGradeForUser A function to set the grade for a specific user | |
119 | */ | |
f281c616 | 120 | export const launch = async(getListOfUsers, getContentForUser, getGradeForUser, setGradeForUser, { |
aa04b722 | 121 | initialUserId = null, moduleName |
bae67469 MM |
122 | } = {}) => { |
123 | ||
124 | const [ | |
125 | graderLayout, | |
126 | graderHTML, | |
127 | userList, | |
128 | ] = await Promise.all([ | |
129 | createFullScreenWindow({fullscreen: false, showLoader: false}), | |
d3b890f8 | 130 | Templates.render(templateNames.grader.app, {moduleName: moduleName}), |
bae67469 MM |
131 | getListOfUsers(), |
132 | ]); | |
133 | const graderContainer = graderLayout.getContainer(); | |
134 | ||
45c0584c AN |
135 | const saveGradeFunction = getSaveUserGradeFunction(graderContainer, setGradeForUser); |
136 | ||
bae67469 | 137 | Templates.replaceNodeContents(graderContainer, graderHTML, ''); |
f281c616 AN |
138 | const updateUserContent = getUpdateUserContentFunction(graderContainer, getContentForUser, getGradeForUser); |
139 | ||
45c0584c AN |
140 | // Fetch the userpicker for display. |
141 | const userPicker = await getUserPicker( | |
f281c616 | 142 | userList, |
f281c616 | 143 | updateUserContent, |
aa04b722 AN |
144 | saveGradeFunction, |
145 | { | |
146 | initialUserId, | |
147 | }, | |
f281c616 | 148 | ); |
bae67469 | 149 | |
eaee6477 AN |
150 | // Register all event listeners. |
151 | registerEventListeners(graderLayout, userPicker, saveGradeFunction); | |
152 | ||
45c0584c AN |
153 | // Display the newly created user picker. |
154 | displayUserPicker(graderContainer, userPicker.rootNode); | |
bae67469 | 155 | }; |
f281c616 AN |
156 | |
157 | export {getGradingPanelFunctions}; |