MDL-68463 user: Rewrite participant bulk actions in ES

This commit is contained in:
Andrew Nicols
2020-05-18 20:00:47 +08:00
parent d85118369d
commit bae72dd06d
10 changed files with 296 additions and 294 deletions
+2
View File
@@ -0,0 +1,2 @@
function _typeof(a){"@babel/helpers - typeof";if("function"==typeof Symbol&&"symbol"==typeof Symbol.iterator){_typeof=function(a){return typeof a}}else{_typeof=function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a}}return _typeof(a)}define ("core_user/local/participants/bulkactions",["exports","core_user/repository","core/str","core/modal_events","core/modal_factory","core/templates","core/toast"],function(a,b,c,d,e,f,g){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.showSendMessage=a.showAddNote=void 0;b=j(b);c=j(c);d=h(d);e=h(e);f=h(f);function h(a){return a&&a.__esModule?a:{default:a}}function i(){if("function"!=typeof WeakMap)return null;var a=new WeakMap;i=function(){return a};return a}function j(a){if(a&&a.__esModule){return a}if(null===a||"object"!==_typeof(a)&&"function"!=typeof a){return{default:a}}var b=i();if(b&&b.has(a)){return b.get(a)}var c={},d=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var e in a){if(Object.prototype.hasOwnProperty.call(a,e)){var f=d?Object.getOwnPropertyDescriptor(a,e):null;if(f&&(f.get||f.set)){Object.defineProperty(c,e,f)}else{c[e]=a[e]}}}c.default=a;if(b){b.set(a,c)}return c}var k=function(a,b,g,h){if(!b.length){return Promise.resolve()}var i=[];for(var m in g){switch(m){case"draft":i.push({value:"personal",label:g[m]});break;case"public":i.push({value:"course",label:g[m],selected:1});break;case"site":i.push({value:m,label:g[m]});break;}}var j={stateNames:i,stateHelpIcon:h.innerHTML},k=null;if(1===b.length){k=c.get_string("addbulknotesingle","core_notes")}else{k=c.get_string("addbulknote","core_notes",b.length)}return e.default.create({type:e.default.types.SAVE_CANCEL,body:f.default.render("core_user/add_bulk_note",j),title:k,buttons:{save:k},removeOnClose:!0}).then(function(c){c.getRoot().on(d.default.save,function(){return l(a,b,c)});c.show();return c})};a.showAddNote=k;var l=function(a,d,e){var f=e.getRoot().find("form textarea").val(),h=e.getRoot().find("form select").val(),i=d.map(function(b){return{userid:b,text:f,courseid:a,publishstate:h}});return b.createNotesForUsers(i).then(function(a){if(1===a.length){return c.get_string("addbulknotedonesingle","core_notes")}else{return c.get_string("addbulknotedone","core_notes",a.length)}}).then(function(a){return(0,g.add)(a)}).catch(Notification.exception)},m=function(a){if(!a.length){return Promise.resolve()}var b;if(1===a.length){b=c.get_string("sendbulkmessagesingle","core_message")}else{b=c.get_string("sendbulkmessage","core_message",a.length)}return e.default.create({type:e.default.types.SAVE_CANCEL,body:f.default.render("core_user/send_bulk_message",{}),title:b,buttons:{save:b},removeOnClose:!0}).then(function(b){b.getRoot().on(d.default.save,function(){n(b,a)});b.show();return b})};a.showSendMessage=m;var n=function(a,d){var e=a.getRoot().find("form textarea").val(),f=d.map(function(a){return{touserid:a,text:e}});return b.sendMessagesToUsers(f).then(function(a){if(1==a.length){return c.get_string("sendbulkmessagesentsingle","core_message")}else{return c.get_string("sendbulkmessagesent","core_message",a.length)}}).then(function(a){return(0,g.add)(a)}).catch(Notification.exception)}});
//# sourceMappingURL=bulkactions.min.js.map
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,2 +1,2 @@
define ("core_user/participants",["jquery","core/str","core/modal_factory","core/modal_events","core/templates","core/notification","core/ajax","core/custom_interaction_events"],function(a,b,c,d,e,f,g,h){var i={BULKACTIONSELECT:"#formactionid",BULKUSERCHECKBOXES:"input.usercheckbox",BULKUSERNOSCHECKBOXES:"input.usercheckbox[value='0']",BULKUSERSELECTEDCHECKBOXES:"input.usercheckbox:checked",BULKACTIONFORM:"#participantsform",CHECKALLBUTTON:"#checkall",CHECKALLNOSBUTTON:"#checkallnos"},j=function(a){this.courseId=a.courseid;this.noteStateNames=a.noteStateNames;this.stateHelpIcon=a.stateHelpIcon;this.attachEventListeners()};j.prototype.modal=null;j.prototype.courseId=-1;j.prototype.noteStateNames={};j.prototype.stateHelpIcon="";j.prototype.attachEventListeners=function(){h.define(i.BULKACTIONSELECT,[h.events.accessibleChange]);a(i.BULKACTIONSELECT).on(h.events.accessibleChange,function(b){var c=a(b.target).val();if(-1!==c.indexOf("#")){b.preventDefault();var d=[];a(i.BULKUSERSELECTEDCHECKBOXES).each(function(b,c){var e=a(c).attr("name"),f=e.replace("user","");d.push(f)});if("#messageselect"==c){this.showSendMessage(d).fail(f.exception)}else if("#addgroupnote"==c){this.showAddNote(d).fail(f.exception)}a(i.BULKACTIONSELECT+" option[value=\"\"]").prop("selected","selected")}else if(""!==c){if(0<a(i.BULKUSERSELECTEDCHECKBOXES).length){a(i.BULKACTIONFORM).submit()}else{a(i.BULKACTIONSELECT+" option[value=\"\"]").prop("selected","selected")}}}.bind(this));a(i.CHECKALLBUTTON).on("click",function(){var b=a(this).data("showallink");if(b){window.location=b}});a(i.CHECKALLNOSBUTTON).on("click",function(){a(i.BULKUSERNOSCHECKBOXES).prop("checked",!0)})};j.prototype.showAddNote=function(f){if(0==f.length){return a.Deferred().resolve().promise()}var g=[];for(var h in this.noteStateNames){switch(h){case"draft":g.push({value:"personal",label:this.noteStateNames[h]});break;case"public":g.push({value:"course",label:this.noteStateNames[h],selected:1});break;case"site":g.push({value:h,label:this.noteStateNames[h]});break;}}var j={stateNames:g,stateHelpIcon:this.stateHelpIcon},k=null;if(1==f.length){k=b.get_string("addbulknotesingle","core_notes")}else{k=b.get_string("addbulknote","core_notes",f.length)}return a.when(c.create({type:c.types.SAVE_CANCEL,body:e.render("core_user/add_bulk_note",j)}),k).then(function(b,c){this.modal=b;this.modal.setTitle(c);this.modal.setSaveButtonText(c);this.modal.getRoot().on(d.hidden,function(){var b=a("#user-notifications [role=alert]");if(b.length){b.focus()}else{a(i.BULKACTIONSELECT).focus()}this.modal.getRoot().remove()}.bind(this));this.modal.getRoot().on(d.save,this.submitAddNote.bind(this,f));this.modal.show();return this.modal}.bind(this))};j.prototype.submitAddNote=function(a){var c=this.modal.getRoot().find("form textarea").val(),d=this.modal.getRoot().find("form select").val(),e=[],h=0;for(h=0;h<a.length;h++){e.push({userid:a[h],text:c,courseid:this.courseId,publishstate:d})}return g.call([{methodname:"core_notes_create_notes",args:{notes:e}}])[0].then(function(a){if(1==a.length){return b.get_string("addbulknotedonesingle","core_notes")}else{return b.get_string("addbulknotedone","core_notes",a.length)}}).then(function(a){f.addNotification({message:a,type:"success"});return!0}).catch(f.exception)};j.prototype.showSendMessage=function(f){if(0==f.length){return a.Deferred().resolve().promise()}var g=null;if(1==f.length){g=b.get_string("sendbulkmessagesingle","core_message")}else{g=b.get_string("sendbulkmessage","core_message",f.length)}return a.when(c.create({type:c.types.SAVE_CANCEL,body:e.render("core_user/send_bulk_message",{})}),g).then(function(b,c){this.modal=b;this.modal.setTitle(c);this.modal.setSaveButtonText(c);this.modal.getRoot().on(d.hidden,function(){a(i.BULKACTIONSELECT).focus();this.modal.getRoot().remove()}.bind(this));this.modal.getRoot().on(d.save,this.submitSendMessage.bind(this,f));this.modal.show();return this.modal}.bind(this))};j.prototype.submitSendMessage=function(a){var c=this.modal.getRoot().find("form textarea").val(),d=[],e=0;for(e=0;e<a.length;e++){d.push({touserid:a[e],text:c})}return g.call([{methodname:"core_message_send_instant_messages",args:{messages:d}}])[0].then(function(a){if(1==a.length){return b.get_string("sendbulkmessagesentsingle","core_message")}else{return b.get_string("sendbulkmessagesent","core_message",a.length)}}).then(function(a){f.addNotification({message:a,type:"success"});return!0}).catch(f.exception)};return{init:function init(a){return new j(a)}}});
define ("core_user/participants",["exports","core_table/local/dynamic/selectors","core/modal_events","core/notification","core/custom_interaction_events","core_user/local/participants/bulkactions"],function(a,b,c,d,e,f){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;b=g(b);c=g(c);d=g(d);e=g(e);function g(a){return a&&a.__esModule?a:{default:a}}var h={bulkActionSelect:"#formactionid",bulkUserCheckBoxes:"input.usercheckbox",bulkUserSelectedCheckBoxes:"input.usercheckbox:checked",checkAllButton:"#checkall",stateHelpIcon:"[data-region=\"state-help-icon\"]",tableForm:function tableForm(a){return"form[data-table-unique-id=\"".concat(a,"\"]")}};a.init=function init(a){var g=a.uniqueid,i=a.noteStateNames,j=void 0===i?{}:i,k=document.querySelector(h.tableForm(g)),l=function(a){return k.querySelector(b.default.main.fromRegionId(a))},m=function(){k.querySelector(h.bulkActionSelect).addEventListener(e.default.events.accessibleChange,function(a){var b=a.target.value,e=l(g),i=e.querySelectorAll(h.bulkUserSelectedCheckBoxes);if(-1!==b.indexOf("#")){a.preventDefault();var m=[];i.forEach(function(a){m.push(a.getAttribute("name").replace("user",""))});var o;if("#messageselect"===b){o=(0,f.showSendMessage)(m)}else if("#addgroupnote"===b){o=(0,f.showAddNote)(k.dataset.courseId,m,j,k.querySelector(h.stateHelpIcon))}if(o){o.then(function(a){a.getRoot().on(c.default.hidden,function(){var a=k.querySelector(h.bulkActionSelect);a.focus()});return a}).catch(d.default.exception)}}else if(""!==b&&i.length){a.target.form.submit()}n(a.target)});k.addEventListener("click",function(a){var b=a.target.closest(h.checkAllButton);if(b){var c=b.dataset.showalllink;if(c){window.location=c}}})},n=function(a){a.value=""};m()}});
//# sourceMappingURL=participants.min.js.map
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,2 +1,2 @@
define ("core_user/repository",["exports","core/ajax"],function(a,b){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.submitUserEnrolmentForm=a.unenrolUser=void 0;a.unenrolUser=function unenrolUser(a){return(0,b.call)([{methodname:"core_enrol_unenrol_user_enrolment",args:{ueid:a}}])[0]};a.submitUserEnrolmentForm=function submitUserEnrolmentForm(a){return(0,b.call)([{methodname:"core_enrol_submit_user_enrolment_form",args:{formdata:a}}])[0]}});
define ("core_user/repository",["exports","core/ajax"],function(a,b){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.sendMessagesToUsers=a.createNotesForUsers=a.submitUserEnrolmentForm=a.unenrolUser=void 0;a.unenrolUser=function unenrolUser(a){return(0,b.call)([{methodname:"core_enrol_unenrol_user_enrolment",args:{ueid:a}}])[0]};a.submitUserEnrolmentForm=function submitUserEnrolmentForm(a){return(0,b.call)([{methodname:"core_enrol_submit_user_enrolment_form",args:{formdata:a}}])[0]};a.createNotesForUsers=function createNotesForUsers(a){return(0,b.call)([{methodname:"core_notes_create_notes",args:{notes:a}}])[0]};a.sendMessagesToUsers=function sendMessagesToUsers(a){return(0,b.call)([{methodname:"core_message_send_instant_messages",args:{messages:a}}])[0]}});
//# sourceMappingURL=repository.min.js.map
+1 -1
View File
@@ -1 +1 @@
{"version":3,"sources":["../src/repository.js"],"names":["unenrolUser","userEnrolmentId","methodname","args","ueid","submitUserEnrolmentForm","formdata"],"mappings":"gMA8B2B,QAAdA,CAAAA,WAAc,CAAAC,CAAe,CAAI,CAC1C,MAAO,WAAU,CAAC,CACdC,UAAU,CAAE,mCADE,CAEdC,IAAI,CAAE,CACFC,IAAI,CAAEH,CADJ,CAFQ,CAAD,CAAV,EAKH,CALG,CAMV,C,2BAQsC,QAA1BI,CAAAA,uBAA0B,CAAAC,CAAQ,CAAI,CAC/C,MAAO,WAAU,CAAC,CACdJ,UAAU,CAAE,uCADE,CAEdC,IAAI,CAAE,CACFG,QAAQ,CAARA,CADE,CAFQ,CAAD,CAAV,EAKH,CALG,CAMV,C","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 * Module to handle AJAX interactions.\n *\n * @module core_user/repository\n * @copyright 2020 Andrew Nicols <[email protected]>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport {call as fetchMany} from 'core/ajax';\n\n/**\n * Unenrol the user with the specified user enrolmentid ID.\n *\n * @param {Number} userEnrolmentId\n * @return {Promise}\n */\nexport const unenrolUser = userEnrolmentId => {\n return fetchMany([{\n methodname: 'core_enrol_unenrol_user_enrolment',\n args: {\n ueid: userEnrolmentId,\n },\n }])[0];\n};\n\n/**\n * Submit the user enrolment form with the specified form data.\n *\n * @param {String} formdata\n * @return {Promise}\n */\nexport const submitUserEnrolmentForm = formdata => {\n return fetchMany([{\n methodname: 'core_enrol_submit_user_enrolment_form',\n args: {\n formdata,\n },\n }])[0];\n};\n"],"file":"repository.min.js"}
{"version":3,"sources":["../src/repository.js"],"names":["unenrolUser","userEnrolmentId","methodname","args","ueid","submitUserEnrolmentForm","formdata","createNotesForUsers","notes","sendMessagesToUsers","messages"],"mappings":"4OA8B2B,QAAdA,CAAAA,WAAc,CAAAC,CAAe,CAAI,CAC1C,MAAO,WAAU,CAAC,CACdC,UAAU,CAAE,mCADE,CAEdC,IAAI,CAAE,CACFC,IAAI,CAAEH,CADJ,CAFQ,CAAD,CAAV,EAKH,CALG,CAMV,C,2BAQsC,QAA1BI,CAAAA,uBAA0B,CAAAC,CAAQ,CAAI,CAC/C,MAAO,WAAU,CAAC,CACdJ,UAAU,CAAE,uCADE,CAEdC,IAAI,CAAE,CACFG,QAAQ,CAARA,CADE,CAFQ,CAAD,CAAV,EAKH,CALG,CAMV,C,uBAEkC,QAAtBC,CAAAA,mBAAsB,CAAAC,CAAK,CAAI,CACxC,MAAO,WAAU,CAAC,CACdN,UAAU,CAAE,yBADE,CAEdC,IAAI,CAAE,CACFK,KAAK,CAALA,CADE,CAFQ,CAAD,CAAV,EAKH,CALG,CAMV,C,uBAEkC,QAAtBC,CAAAA,mBAAsB,CAAAC,CAAQ,CAAI,CAC3C,MAAO,WAAU,CAAC,CACdR,UAAU,CAAE,oCADE,CAEdC,IAAI,CAAE,CAACO,QAAQ,CAARA,CAAD,CAFQ,CAAD,CAAV,EAGH,CAHG,CAIV,C","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 * Module to handle AJAX interactions.\n *\n * @module core_user/repository\n * @copyright 2020 Andrew Nicols <[email protected]>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport {call as fetchMany} from 'core/ajax';\n\n/**\n * Unenrol the user with the specified user enrolmentid ID.\n *\n * @param {Number} userEnrolmentId\n * @return {Promise}\n */\nexport const unenrolUser = userEnrolmentId => {\n return fetchMany([{\n methodname: 'core_enrol_unenrol_user_enrolment',\n args: {\n ueid: userEnrolmentId,\n },\n }])[0];\n};\n\n/**\n * Submit the user enrolment form with the specified form data.\n *\n * @param {String} formdata\n * @return {Promise}\n */\nexport const submitUserEnrolmentForm = formdata => {\n return fetchMany([{\n methodname: 'core_enrol_submit_user_enrolment_form',\n args: {\n formdata,\n },\n }])[0];\n};\n\nexport const createNotesForUsers = notes => {\n return fetchMany([{\n methodname: 'core_notes_create_notes',\n args: {\n notes\n }\n }])[0];\n};\n\nexport const sendMessagesToUsers = messages => {\n return fetchMany([{\n methodname: 'core_message_send_instant_messages',\n args: {messages}\n }])[0];\n};\n"],"file":"repository.min.js"}
@@ -0,0 +1,191 @@
// 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/>.
/**
* Bulk actions for lists of participants.
*
* @module core_user/local/participants/bulkactions
* @package core_user
* @copyright 2020 Andrew Nicols <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import * as Repository from 'core_user/repository';
import * as Str from 'core/str';
import ModalEvents from 'core/modal_events';
import ModalFactory from 'core/modal_factory';
import Templates from 'core/templates';
import {add as notifyUser} from 'core/toast';
/**
* Show the add note popup
*
* @param {Number} courseid
* @param {Number[]} users
* @param {String[]} noteStateNames
* @param {HTMLElement} stateHelpIcon
* @return {Promise}
*/
export const showAddNote = (courseid, users, noteStateNames, stateHelpIcon) => {
if (!users.length) {
// No users were selected.
return Promise.resolve();
}
const states = [];
for (let key in noteStateNames) {
switch (key) {
case 'draft':
states.push({value: 'personal', label: noteStateNames[key]});
break;
case 'public':
states.push({value: 'course', label: noteStateNames[key], selected: 1});
break;
case 'site':
states.push({value: key, label: noteStateNames[key]});
break;
}
}
const context = {
stateNames: states,
stateHelpIcon: stateHelpIcon.innerHTML,
};
let titlePromise = null;
if (users.length === 1) {
titlePromise = Str.get_string('addbulknotesingle', 'core_notes');
} else {
titlePromise = Str.get_string('addbulknote', 'core_notes', users.length);
}
return ModalFactory.create({
type: ModalFactory.types.SAVE_CANCEL,
body: Templates.render('core_user/add_bulk_note', context),
title: titlePromise,
buttons: {
save: titlePromise,
},
removeOnClose: true,
})
.then(modal => {
modal.getRoot().on(ModalEvents.save, () => submitAddNote(courseid, users, modal));
modal.show();
return modal;
});
};
/**
* Add a note to this list of users.
*
* @param {Number} courseid
* @param {Number[]} users
* @param {Modal} modal
* @return {Promise}
*/
const submitAddNote = (courseid, users, modal) => {
const text = modal.getRoot().find('form textarea').val();
const publishstate = modal.getRoot().find('form select').val();
const notes = users.map(userid => {
return {
userid,
text,
courseid,
publishstate,
};
});
return Repository.createNotesForUsers(notes)
.then(noteIds => {
if (noteIds.length === 1) {
return Str.get_string('addbulknotedonesingle', 'core_notes');
} else {
return Str.get_string('addbulknotedone', 'core_notes', noteIds.length);
}
})
.then(msg => notifyUser(msg))
.catch(Notification.exception);
};
/**
* Show the send message popup.
*
* @param {Number[]} users
* @return {Promise}
*/
export const showSendMessage = users => {
if (!users.length) {
// Nothing to do.
return Promise.resolve();
}
let titlePromise;
if (users.length === 1) {
titlePromise = Str.get_string('sendbulkmessagesingle', 'core_message');
} else {
titlePromise = Str.get_string('sendbulkmessage', 'core_message', users.length);
}
return ModalFactory.create({
type: ModalFactory.types.SAVE_CANCEL,
body: Templates.render('core_user/send_bulk_message', {}),
title: titlePromise,
buttons: {
save: titlePromise,
},
removeOnClose: true,
})
.then(modal => {
modal.getRoot().on(ModalEvents.save, () => {
submitSendMessage(modal, users);
});
modal.show();
return modal;
});
};
/**
* Send a message to these users.
*
* @param {Modal} modal
* @param {Number[]} users
* @return {Promise}
*/
const submitSendMessage = (modal, users) => {
const text = modal.getRoot().find('form textarea').val();
const messages = users.map(touserid => {
return {
touserid,
text,
};
});
return Repository.sendMessagesToUsers(messages)
.then(messageIds => {
if (messageIds.length == 1) {
return Str.get_string('sendbulkmessagesentsingle', 'core_message');
} else {
return Str.get_string('sendbulkmessagesent', 'core_message', messageIds.length);
}
})
.then(msg => notifyUser(msg))
.catch(Notification.exception);
};
+70 -285
View File
@@ -22,310 +22,95 @@
* @copyright 2017 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define(['jquery', 'core/str', 'core/modal_factory', 'core/modal_events', 'core/templates', 'core/notification', 'core/ajax',
'core/custom_interaction_events'],
function($, Str, ModalFactory, ModalEvents, Templates, Notification, Ajax, CustomEvents) {
var SELECTORS = {
BULKACTIONSELECT: "#formactionid",
BULKUSERCHECKBOXES: "input.usercheckbox",
BULKUSERNOSCHECKBOXES: "input.usercheckbox[value='0']",
BULKUSERSELECTEDCHECKBOXES: "input.usercheckbox:checked",
BULKACTIONFORM: "#participantsform",
CHECKALLBUTTON: "#checkall",
CHECKALLNOSBUTTON: "#checkallnos"
};
import DynamicTableSelectors from 'core_table/local/dynamic/selectors';
import ModalEvents from 'core/modal_events';
import Notification from 'core/notification';
import CustomEvents from 'core/custom_interaction_events';
import {showAddNote, showSendMessage} from 'core_user/local/participants/bulkactions';
const Selectors = {
bulkActionSelect: "#formactionid",
bulkUserCheckBoxes: "input.usercheckbox",
bulkUserSelectedCheckBoxes: "input.usercheckbox:checked",
checkAllButton: "#checkall",
stateHelpIcon: '[data-region="state-help-icon"]',
tableForm: uniqueId => `form[data-table-unique-id="${uniqueId}"]`,
};
export const init = ({
uniqueid,
noteStateNames = {},
}) => {
const root = document.querySelector(Selectors.tableForm(uniqueid));
const getTableFromUniqueId = uniqueId => root.querySelector(DynamicTableSelectors.main.fromRegionId(uniqueId));
/**
* Constructor
* Private method.
*
* @param {Object} options Object containing options. Contextid is required.
* Each call to templates.render gets it's own instance of this class.
*/
var Participants = function(options) {
this.courseId = options.courseid;
this.noteStateNames = options.noteStateNames;
this.stateHelpIcon = options.stateHelpIcon;
this.attachEventListeners();
};
// Class variables and functions.
/**
* @var {Modal} modal
* @method registerEventListeners
* @private
*/
Participants.prototype.modal = null;
const registerEventListeners = () => {
root.querySelector(Selectors.bulkActionSelect).addEventListener(CustomEvents.events.accessibleChange, e => {
const action = e.target.value;
const tableRoot = getTableFromUniqueId(uniqueid);
const checkboxes = tableRoot.querySelectorAll(Selectors.bulkUserSelectedCheckBoxes);
/**
* @var {int} courseId
* @private
*/
Participants.prototype.courseId = -1;
/**
* @var {Object} noteStateNames
* @private
*/
Participants.prototype.noteStateNames = {};
/**
* @var {String} stateHelpIcon
* @private
*/
Participants.prototype.stateHelpIcon = "";
/**
* Private method
*
* @method attachEventListeners
* @private
*/
Participants.prototype.attachEventListeners = function() {
CustomEvents.define(SELECTORS.BULKACTIONSELECT, [CustomEvents.events.accessibleChange]);
$(SELECTORS.BULKACTIONSELECT).on(CustomEvents.events.accessibleChange, function(e) {
var action = $(e.target).val();
if (action.indexOf('#') !== -1) {
e.preventDefault();
var ids = [];
$(SELECTORS.BULKUSERSELECTEDCHECKBOXES).each(function(index, ele) {
var name = $(ele).attr('name');
var id = name.replace('user', '');
ids.push(id);
const ids = [];
checkboxes.forEach(checkbox => {
ids.push(checkbox.getAttribute('name').replace('user', ''));
});
if (action == '#messageselect') {
this.showSendMessage(ids).fail(Notification.exception);
} else if (action == '#addgroupnote') {
this.showAddNote(ids).fail(Notification.exception);
let bulkAction;
if (action === '#messageselect') {
bulkAction = showSendMessage(ids);
} else if (action === '#addgroupnote') {
bulkAction = showAddNote(
root.dataset.courseId,
ids,
noteStateNames,
root.querySelector(Selectors.stateHelpIcon)
);
}
$(SELECTORS.BULKACTIONSELECT + ' option[value=""]').prop('selected', 'selected');
} else if (action !== '') {
if ($(SELECTORS.BULKUSERSELECTEDCHECKBOXES).length > 0) {
$(SELECTORS.BULKACTIONFORM).submit();
} else {
$(SELECTORS.BULKACTIONSELECT + ' option[value=""]').prop('selected', 'selected');
}
}
}.bind(this));
$(SELECTORS.CHECKALLBUTTON).on('click', function() {
var showallink = $(this).data('showallink');
if (showallink) {
window.location = showallink;
if (bulkAction) {
bulkAction
.then(modal => {
modal.getRoot().on(ModalEvents.hidden, () => {
// Focus on the action select when the dialog is closed.
const bulkActionSelector = root.querySelector(Selectors.bulkActionSelect);
bulkActionSelector.focus();
});
return modal;
})
.catch(Notification.exception);
}
} else if (action !== '' && checkboxes.length) {
e.target.form.submit();
}
resetBulkAction(e.target);
});
$(SELECTORS.CHECKALLNOSBUTTON).on('click', function() {
$(SELECTORS.BULKUSERNOSCHECKBOXES).prop('checked', true);
root.addEventListener('click', e => {
const checkAllButton = e.target.closest(Selectors.checkAllButton);
if (checkAllButton) {
const showAllLink = checkAllButton.dataset.showalllink;
if (showAllLink) {
window.location = showAllLink;
}
}
});
};
/**
* Show the add note popup
*
* @method showAddNote
* @private
* @param {int[]} users
* @return {Promise}
*/
Participants.prototype.showAddNote = function(users) {
if (users.length == 0) {
// Nothing to do.
return $.Deferred().resolve().promise();
}
var states = [];
for (var key in this.noteStateNames) {
switch (key) {
case 'draft':
states.push({value: 'personal', label: this.noteStateNames[key]});
break;
case 'public':
states.push({value: 'course', label: this.noteStateNames[key], selected: 1});
break;
case 'site':
states.push({value: key, label: this.noteStateNames[key]});
break;
}
}
var context = {stateNames: states, stateHelpIcon: this.stateHelpIcon};
var titlePromise = null;
if (users.length == 1) {
titlePromise = Str.get_string('addbulknotesingle', 'core_notes');
} else {
titlePromise = Str.get_string('addbulknote', 'core_notes', users.length);
}
return $.when(
ModalFactory.create({
type: ModalFactory.types.SAVE_CANCEL,
body: Templates.render('core_user/add_bulk_note', context)
}),
titlePromise
).then(function(modal, title) {
// Keep a reference to the modal.
this.modal = modal;
this.modal.setTitle(title);
this.modal.setSaveButtonText(title);
// We want to focus on the action select when the dialog is closed.
this.modal.getRoot().on(ModalEvents.hidden, function() {
var notification = $('#user-notifications [role=alert]');
if (notification.length) {
notification.focus();
} else {
$(SELECTORS.BULKACTIONSELECT).focus();
}
this.modal.getRoot().remove();
}.bind(this));
this.modal.getRoot().on(ModalEvents.save, this.submitAddNote.bind(this, users));
this.modal.show();
return this.modal;
}.bind(this));
const resetBulkAction = bulkActionSelect => {
bulkActionSelect.value = '';
};
/**
* Add a note to this list of users.
*
* @method submitAddNote
* @private
* @param {int[]} users
* @return {Promise}
*/
Participants.prototype.submitAddNote = function(users) {
var noteText = this.modal.getRoot().find('form textarea').val();
var publishState = this.modal.getRoot().find('form select').val();
var notes = [],
i = 0;
for (i = 0; i < users.length; i++) {
notes.push({userid: users[i], text: noteText, courseid: this.courseId, publishstate: publishState});
}
return Ajax.call([{
methodname: 'core_notes_create_notes',
args: {notes: notes}
}])[0].then(function(noteIds) {
if (noteIds.length == 1) {
return Str.get_string('addbulknotedonesingle', 'core_notes');
} else {
return Str.get_string('addbulknotedone', 'core_notes', noteIds.length);
}
}).then(function(msg) {
Notification.addNotification({
message: msg,
type: "success"
});
return true;
}).catch(Notification.exception);
};
/**
* Show the send message popup.
*
* @method showSendMessage
* @private
* @param {int[]} users
* @return {Promise}
*/
Participants.prototype.showSendMessage = function(users) {
if (users.length == 0) {
// Nothing to do.
return $.Deferred().resolve().promise();
}
var titlePromise = null;
if (users.length == 1) {
titlePromise = Str.get_string('sendbulkmessagesingle', 'core_message');
} else {
titlePromise = Str.get_string('sendbulkmessage', 'core_message', users.length);
}
return $.when(
ModalFactory.create({
type: ModalFactory.types.SAVE_CANCEL,
body: Templates.render('core_user/send_bulk_message', {})
}),
titlePromise
).then(function(modal, title) {
// Keep a reference to the modal.
this.modal = modal;
this.modal.setTitle(title);
this.modal.setSaveButtonText(title);
// We want to focus on the action select when the dialog is closed.
this.modal.getRoot().on(ModalEvents.hidden, function() {
$(SELECTORS.BULKACTIONSELECT).focus();
this.modal.getRoot().remove();
}.bind(this));
this.modal.getRoot().on(ModalEvents.save, this.submitSendMessage.bind(this, users));
this.modal.show();
return this.modal;
}.bind(this));
};
/**
* Send a message to these users.
*
* @method submitSendMessage
* @private
* @param {int[]} users
* @param {Event} e Form submission event.
* @return {Promise}
*/
Participants.prototype.submitSendMessage = function(users) {
var messageText = this.modal.getRoot().find('form textarea').val();
var messages = [],
i = 0;
for (i = 0; i < users.length; i++) {
messages.push({touserid: users[i], text: messageText});
}
return Ajax.call([{
methodname: 'core_message_send_instant_messages',
args: {messages: messages}
}])[0].then(function(messageIds) {
if (messageIds.length == 1) {
return Str.get_string('sendbulkmessagesentsingle', 'core_message');
} else {
return Str.get_string('sendbulkmessagesent', 'core_message', messageIds.length);
}
}).then(function(msg) {
Notification.addNotification({
message: msg,
type: "success"
});
return true;
}).catch(Notification.exception);
};
return /** @alias module:core_user/participants */ {
// Public variables and functions.
/**
* Initialise the unified user filter.
*
* @method init
* @param {Object} options - List of options.
* @return {Participants}
*/
'init': function(options) {
return new Participants(options);
}
};
});
registerEventListeners();
};
+16
View File
@@ -51,3 +51,19 @@ export const submitUserEnrolmentForm = formdata => {
},
}])[0];
};
export const createNotesForUsers = notes => {
return fetchMany([{
methodname: 'core_notes_create_notes',
args: {
notes
}
}])[0];
};
export const sendMessagesToUsers = messages => {
return fetchMany([{
methodname: 'core_message_send_instant_messages',
args: {messages}
}])[0];
};
+12 -5
View File
@@ -289,7 +289,13 @@ ob_end_clean();
echo html_writer::tag('p', get_string('participantscount', 'moodle', $participanttable->totalrows));
if ($bulkoperations) {
echo '<form action="action_redir.php" method="post" id="participantsform">';
echo html_writer::start_tag('form', [
'action' => 'action_redir.php',
'method' => 'post',
'id' => 'participantsform',
'data-course-id' => $course->id,
'data-table-unique-id' => $participanttable->uniqueid,
]);
echo '<div>';
echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
echo '<input type="hidden" name="returnto" value="'.s($PAGE->url->out(false)).'" />';
@@ -392,13 +398,14 @@ if ($bulkoperations) {
echo html_writer::tag('div', $label . $select);
echo '<input type="hidden" name="id" value="' . $course->id . '" />';
echo '<div class="d-none" data-region="state-help-icon">' . $OUTPUT->help_icon('publishstate', 'notes') . '</div>';
echo '</div></div></div>';
echo '</form>';
$options = new stdClass();
$options->courseid = $course->id;
$options->noteStateNames = note_get_state_names();
$options->stateHelpIcon = $OUTPUT->help_icon('publishstate', 'notes');
$options = (object) [
'uniqueid' => $participanttable->uniqueid,
'noteStateNames' => note_get_state_names(),
];
$PAGE->requires->js_call_amd('core_user/participants', 'init', [$options]);
}