diff --git a/lang/en/message.php b/lang/en/message.php index a10d483e95687..2080a0f823137 100644 --- a/lang/en/message.php +++ b/lang/en/message.php @@ -118,6 +118,7 @@ $string['messagepreferences'] = 'Message preferences'; $string['messages'] = 'Messages'; $string['messagesselected:'] = 'Messages selected:'; +$string['messagetextrequired'] = 'Please enter message text'; $string['messagingdatahasnotbeenmigrated'] = 'Your messages are temporarily unavailable due to upgrades in the messaging infrastructure. Please wait for them to be migrated.'; $string['muteconversation'] = 'Mute'; $string['mutedconversation'] = 'Muted conversation'; diff --git a/user/amd/build/local/participants/bulkactions.min.js b/user/amd/build/local/participants/bulkactions.min.js index 90f87b3499a38..f46ac9855acd7 100644 --- a/user/amd/build/local/participants/bulkactions.min.js +++ b/user/amd/build/local/participants/bulkactions.min.js @@ -1,2 +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)}}); +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/notification","core/templates","core/toast"],function(a,b,c,d,e,f,g,h){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.showSendMessage=a.showAddNote=void 0;b=k(b);c=k(c);d=i(d);e=i(e);f=i(f);g=i(g);function i(a){return a&&a.__esModule?a:{default:a}}function j(){if("function"!=typeof WeakMap)return null;var a=new WeakMap;j=function(){return a};return a}function k(a){if(a&&a.__esModule){return a}if(null===a||"object"!==_typeof(a)&&"function"!=typeof a){return{default:a}}var b=j();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 l=function(a,b,f,h){if(!b.length){return Promise.resolve()}var i=[];for(var l in f){switch(l){case"draft":i.push({value:"personal",label:f[l]});break;case"public":i.push({value:"course",label:f[l],selected:1});break;case"site":i.push({value:l,label:f[l]});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:g.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 m(a,b,c)});c.show();return c})};a.showAddNote=l;var m=function(a,d,e){var g=e.getRoot().find("form textarea").val(),i=e.getRoot().find("form select").val(),j=d.map(function(b){return{userid:b,text:g,courseid:a,publishstate:i}});return b.createNotesForUsers(j).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,h.add)(a)}).catch(f.default.exception)},n=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:g.default.render("core_user/send_bulk_message",{}),title:b,buttons:{save:b},removeOnClose:!0}).then(function(b){b.getRoot().on(d.default.save,function(c){var d=b.getRoot().find("form textarea").val();if(""===d.trim()){b.getRoot().find("[data-role=\"messagetextrequired\"]").removeAttr("hidden");c.preventDefault();return}o(b,a,d)});b.show();return b})};a.showSendMessage=n;var o=function(a,d,e){var g=d.map(function(a){return{touserid:a,text:e}});return b.sendMessagesToUsers(g).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,h.add)(a)}).catch(f.default.exception)}}); //# sourceMappingURL=bulkactions.min.js.map diff --git a/user/amd/build/local/participants/bulkactions.min.js.map b/user/amd/build/local/participants/bulkactions.min.js.map index c09406ff260e2..72bebf55dcc99 100644 --- a/user/amd/build/local/participants/bulkactions.min.js.map +++ b/user/amd/build/local/participants/bulkactions.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["../../../src/local/participants/bulkactions.js"],"names":["showAddNote","courseid","users","noteStateNames","stateHelpIcon","length","Promise","resolve","states","key","push","value","label","selected","context","stateNames","innerHTML","titlePromise","Str","get_string","ModalFactory","create","type","types","SAVE_CANCEL","body","Templates","render","title","buttons","save","removeOnClose","then","modal","getRoot","on","ModalEvents","submitAddNote","show","text","find","val","publishstate","notes","map","userid","Repository","createNotesForUsers","noteIds","msg","catch","Notification","exception","showSendMessage","submitSendMessage","messages","touserid","sendMessagesToUsers","messageIds"],"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 .\n\n/**\n * Bulk actions for lists of participants.\n *\n * @module core_user/local/participants/bulkactions\n * @package core_user\n * @copyright 2020 Andrew Nicols \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport * as Repository from 'core_user/repository';\nimport * as Str from 'core/str';\nimport ModalEvents from 'core/modal_events';\nimport ModalFactory from 'core/modal_factory';\nimport Templates from 'core/templates';\nimport {add as notifyUser} from 'core/toast';\n\n/**\n * Show the add note popup\n *\n * @param {Number} courseid\n * @param {Number[]} users\n * @param {String[]} noteStateNames\n * @param {HTMLElement} stateHelpIcon\n * @return {Promise}\n */\nexport const showAddNote = (courseid, users, noteStateNames, stateHelpIcon) => {\n if (!users.length) {\n // No users were selected.\n return Promise.resolve();\n }\n\n const states = [];\n for (let key in noteStateNames) {\n switch (key) {\n case 'draft':\n states.push({value: 'personal', label: noteStateNames[key]});\n break;\n case 'public':\n states.push({value: 'course', label: noteStateNames[key], selected: 1});\n break;\n case 'site':\n states.push({value: key, label: noteStateNames[key]});\n break;\n }\n }\n\n const context = {\n stateNames: states,\n stateHelpIcon: stateHelpIcon.innerHTML,\n };\n\n let titlePromise = null;\n if (users.length === 1) {\n titlePromise = Str.get_string('addbulknotesingle', 'core_notes');\n } else {\n titlePromise = Str.get_string('addbulknote', 'core_notes', users.length);\n }\n\n return ModalFactory.create({\n type: ModalFactory.types.SAVE_CANCEL,\n body: Templates.render('core_user/add_bulk_note', context),\n title: titlePromise,\n buttons: {\n save: titlePromise,\n },\n removeOnClose: true,\n })\n .then(modal => {\n modal.getRoot().on(ModalEvents.save, () => submitAddNote(courseid, users, modal));\n\n modal.show();\n\n return modal;\n });\n};\n\n/**\n * Add a note to this list of users.\n *\n * @param {Number} courseid\n * @param {Number[]} users\n * @param {Modal} modal\n * @return {Promise}\n */\nconst submitAddNote = (courseid, users, modal) => {\n const text = modal.getRoot().find('form textarea').val();\n const publishstate = modal.getRoot().find('form select').val();\n\n const notes = users.map(userid => {\n return {\n userid,\n text,\n courseid,\n publishstate,\n };\n });\n\n return Repository.createNotesForUsers(notes)\n .then(noteIds => {\n if (noteIds.length === 1) {\n return Str.get_string('addbulknotedonesingle', 'core_notes');\n } else {\n return Str.get_string('addbulknotedone', 'core_notes', noteIds.length);\n }\n })\n .then(msg => notifyUser(msg))\n .catch(Notification.exception);\n};\n\n/**\n * Show the send message popup.\n *\n * @param {Number[]} users\n * @return {Promise}\n */\nexport const showSendMessage = users => {\n if (!users.length) {\n // Nothing to do.\n return Promise.resolve();\n }\n\n let titlePromise;\n if (users.length === 1) {\n titlePromise = Str.get_string('sendbulkmessagesingle', 'core_message');\n } else {\n titlePromise = Str.get_string('sendbulkmessage', 'core_message', users.length);\n }\n\n return ModalFactory.create({\n type: ModalFactory.types.SAVE_CANCEL,\n body: Templates.render('core_user/send_bulk_message', {}),\n title: titlePromise,\n buttons: {\n save: titlePromise,\n },\n removeOnClose: true,\n })\n .then(modal => {\n modal.getRoot().on(ModalEvents.save, () => {\n submitSendMessage(modal, users);\n });\n\n modal.show();\n\n return modal;\n });\n};\n\n/**\n * Send a message to these users.\n *\n * @param {Modal} modal\n * @param {Number[]} users\n * @return {Promise}\n */\nconst submitSendMessage = (modal, users) => {\n const text = modal.getRoot().find('form textarea').val();\n\n const messages = users.map(touserid => {\n return {\n touserid,\n text,\n };\n });\n\n return Repository.sendMessagesToUsers(messages)\n .then(messageIds => {\n if (messageIds.length == 1) {\n return Str.get_string('sendbulkmessagesentsingle', 'core_message');\n } else {\n return Str.get_string('sendbulkmessagesent', 'core_message', messageIds.length);\n }\n })\n .then(msg => notifyUser(msg))\n .catch(Notification.exception);\n};\n"],"file":"bulkactions.min.js"} \ No newline at end of file +{"version":3,"sources":["../../../src/local/participants/bulkactions.js"],"names":["showAddNote","courseid","users","noteStateNames","stateHelpIcon","length","Promise","resolve","states","key","push","value","label","selected","context","stateNames","innerHTML","titlePromise","Str","get_string","ModalFactory","create","type","types","SAVE_CANCEL","body","Templates","render","title","buttons","save","removeOnClose","then","modal","getRoot","on","ModalEvents","submitAddNote","show","text","find","val","publishstate","notes","map","userid","Repository","createNotesForUsers","noteIds","msg","catch","Notification","exception","showSendMessage","e","trim","removeAttr","preventDefault","submitSendMessage","messages","touserid","sendMessagesToUsers","messageIds"],"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 .\n\n/**\n * Bulk actions for lists of participants.\n *\n * @module core_user/local/participants/bulkactions\n * @package core_user\n * @copyright 2020 Andrew Nicols \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport * as Repository from 'core_user/repository';\nimport * as Str from 'core/str';\nimport ModalEvents from 'core/modal_events';\nimport ModalFactory from 'core/modal_factory';\nimport Notification from 'core/notification';\nimport Templates from 'core/templates';\nimport {add as notifyUser} from 'core/toast';\n\n/**\n * Show the add note popup\n *\n * @param {Number} courseid\n * @param {Number[]} users\n * @param {String[]} noteStateNames\n * @param {HTMLElement} stateHelpIcon\n * @return {Promise}\n */\nexport const showAddNote = (courseid, users, noteStateNames, stateHelpIcon) => {\n if (!users.length) {\n // No users were selected.\n return Promise.resolve();\n }\n\n const states = [];\n for (let key in noteStateNames) {\n switch (key) {\n case 'draft':\n states.push({value: 'personal', label: noteStateNames[key]});\n break;\n case 'public':\n states.push({value: 'course', label: noteStateNames[key], selected: 1});\n break;\n case 'site':\n states.push({value: key, label: noteStateNames[key]});\n break;\n }\n }\n\n const context = {\n stateNames: states,\n stateHelpIcon: stateHelpIcon.innerHTML,\n };\n\n let titlePromise = null;\n if (users.length === 1) {\n titlePromise = Str.get_string('addbulknotesingle', 'core_notes');\n } else {\n titlePromise = Str.get_string('addbulknote', 'core_notes', users.length);\n }\n\n return ModalFactory.create({\n type: ModalFactory.types.SAVE_CANCEL,\n body: Templates.render('core_user/add_bulk_note', context),\n title: titlePromise,\n buttons: {\n save: titlePromise,\n },\n removeOnClose: true,\n })\n .then(modal => {\n modal.getRoot().on(ModalEvents.save, () => submitAddNote(courseid, users, modal));\n\n modal.show();\n\n return modal;\n });\n};\n\n/**\n * Add a note to this list of users.\n *\n * @param {Number} courseid\n * @param {Number[]} users\n * @param {Modal} modal\n * @return {Promise}\n */\nconst submitAddNote = (courseid, users, modal) => {\n const text = modal.getRoot().find('form textarea').val();\n const publishstate = modal.getRoot().find('form select').val();\n\n const notes = users.map(userid => {\n return {\n userid,\n text,\n courseid,\n publishstate,\n };\n });\n\n return Repository.createNotesForUsers(notes)\n .then(noteIds => {\n if (noteIds.length === 1) {\n return Str.get_string('addbulknotedonesingle', 'core_notes');\n } else {\n return Str.get_string('addbulknotedone', 'core_notes', noteIds.length);\n }\n })\n .then(msg => notifyUser(msg))\n .catch(Notification.exception);\n};\n\n/**\n * Show the send message popup.\n *\n * @param {Number[]} users\n * @return {Promise}\n */\nexport const showSendMessage = users => {\n if (!users.length) {\n // Nothing to do.\n return Promise.resolve();\n }\n\n let titlePromise;\n if (users.length === 1) {\n titlePromise = Str.get_string('sendbulkmessagesingle', 'core_message');\n } else {\n titlePromise = Str.get_string('sendbulkmessage', 'core_message', users.length);\n }\n\n return ModalFactory.create({\n type: ModalFactory.types.SAVE_CANCEL,\n body: Templates.render('core_user/send_bulk_message', {}),\n title: titlePromise,\n buttons: {\n save: titlePromise,\n },\n removeOnClose: true,\n })\n .then(modal => {\n modal.getRoot().on(ModalEvents.save, (e) => {\n const text = modal.getRoot().find('form textarea').val();\n if (text.trim() === '') {\n modal.getRoot().find('[data-role=\"messagetextrequired\"]').removeAttr('hidden');\n e.preventDefault();\n return;\n }\n\n submitSendMessage(modal, users, text);\n });\n\n modal.show();\n\n return modal;\n });\n};\n\n/**\n * Send a message to these users.\n *\n * @param {Modal} modal\n * @param {Number[]} users\n * @param {String} text\n * @return {Promise}\n */\nconst submitSendMessage = (modal, users, text) => {\n const messages = users.map(touserid => {\n return {\n touserid,\n text,\n };\n });\n\n return Repository.sendMessagesToUsers(messages)\n .then(messageIds => {\n if (messageIds.length == 1) {\n return Str.get_string('sendbulkmessagesentsingle', 'core_message');\n } else {\n return Str.get_string('sendbulkmessagesent', 'core_message', messageIds.length);\n }\n })\n .then(msg => notifyUser(msg))\n .catch(Notification.exception);\n};\n"],"file":"bulkactions.min.js"} \ No newline at end of file diff --git a/user/amd/src/local/participants/bulkactions.js b/user/amd/src/local/participants/bulkactions.js index 3872f71ef5a2c..aa792b32ac803 100644 --- a/user/amd/src/local/participants/bulkactions.js +++ b/user/amd/src/local/participants/bulkactions.js @@ -26,6 +26,7 @@ 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 Notification from 'core/notification'; import Templates from 'core/templates'; import {add as notifyUser} from 'core/toast'; @@ -151,8 +152,15 @@ export const showSendMessage = users => { removeOnClose: true, }) .then(modal => { - modal.getRoot().on(ModalEvents.save, () => { - submitSendMessage(modal, users); + modal.getRoot().on(ModalEvents.save, (e) => { + const text = modal.getRoot().find('form textarea').val(); + if (text.trim() === '') { + modal.getRoot().find('[data-role="messagetextrequired"]').removeAttr('hidden'); + e.preventDefault(); + return; + } + + submitSendMessage(modal, users, text); }); modal.show(); @@ -166,11 +174,10 @@ export const showSendMessage = users => { * * @param {Modal} modal * @param {Number[]} users + * @param {String} text * @return {Promise} */ -const submitSendMessage = (modal, users) => { - const text = modal.getRoot().find('form textarea').val(); - +const submitSendMessage = (modal, users, text) => { const messages = users.map(touserid => { return { touserid, diff --git a/user/templates/send_bulk_message.mustache b/user/templates/send_bulk_message.mustache index 34f9c91427ffc..a448116378b8f 100644 --- a/user/templates/send_bulk_message.mustache +++ b/user/templates/send_bulk_message.mustache @@ -33,6 +33,9 @@

+ {{#js}} require(['core/auto_rows'], function(AutoRows) { diff --git a/user/tests/behat/bulk_message.feature b/user/tests/behat/bulk_message.feature index 266124ed13a86..067dea7a9fb67 100644 --- a/user/tests/behat/bulk_message.feature +++ b/user/tests/behat/bulk_message.feature @@ -25,8 +25,11 @@ Feature: Bulk message And I navigate to course participants And I click on "Select all" "checkbox" And I set the field "With selected users..." to "Send a message" - And I should see "Send message to 3 people" + And "Send message to 3 people" "dialogue" should exist + # Try to send an empty message. + When I press "Send message to 3 people" + Then I should see "Please enter message text" And I set the following fields to these values: | bulk-message | "Hello world!" | - When I press "Send message to 3 people" - Then I should see "Message sent to 3 people" + And I press "Send message to 3 people" + And I should see "Message sent to 3 people"