diff --git a/admin/tool/analytics/amd/build/log_info.min.js b/admin/tool/analytics/amd/build/log_info.min.js index 71c8acc96cf..7118542688a 100644 --- a/admin/tool/analytics/amd/build/log_info.min.js +++ b/admin/tool/analytics/amd/build/log_info.min.js @@ -1,10 +1,10 @@ +define("tool_analytics/log_info",["exports","core/modal","core/str"],(function(_exports,_modal,_str){var obj; /** - * Shows a dialogue with info about this logs. - * - * @module tool_analytics/log_info - * @copyright 2017 David Monllao {@link http://www.davidmonllao.com} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -define("tool_analytics/log_info",["jquery","core/str","core/modal_factory","core/notification"],(function($,str,ModalFactory,Notification){return{loadInfo:function(id,info){var link=$('[data-model-log-id="'+id+'"]');str.get_string("loginfo","tool_analytics").then((function(langString){var bodyInfo=$(""),ModalFactory.create({title:langString,body:bodyInfo.html(),large:!0},link)})).catch(Notification.exception)}}})); + * Shows a dialogue with info about this logs. + * + * @module tool_analytics/log_info + * @copyright 2017 David Monllao {@link http://www.davidmonllao.com} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.loadInfo=void 0,_modal=(obj=_modal)&&obj.__esModule?obj:{default:obj};_exports.loadInfo=(id,info)=>{document.addEventListener("click",(e=>{const link=e.target.closest('[data-model-log-id="'.concat(id,'"]'));if(!link)return;e.preventDefault();const bodyInfo=document.createElement("ul");info.forEach((item=>{const li=document.createElement("li");li.innerHTML=item,bodyInfo.append(li)})),_modal.default.create({title:(0,_str.get_string)("loginfo","tool_analytics"),body:bodyInfo.outerHTML,large:!0,show:!0,removeOnClose:!0},link)}))}})); //# sourceMappingURL=log_info.min.js.map \ No newline at end of file diff --git a/admin/tool/analytics/amd/build/log_info.min.js.map b/admin/tool/analytics/amd/build/log_info.min.js.map index 38c60d0eedc..2a0bffe209b 100644 --- a/admin/tool/analytics/amd/build/log_info.min.js.map +++ b/admin/tool/analytics/amd/build/log_info.min.js.map @@ -1 +1 @@ -{"version":3,"file":"log_info.min.js","sources":["../src/log_info.js"],"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 * Shows a dialogue with info about this logs.\n *\n * @module tool_analytics/log_info\n * @copyright 2017 David Monllao {@link http://www.davidmonllao.com}\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(['jquery', 'core/str', 'core/modal_factory', 'core/notification'], function($, str, ModalFactory, Notification) {\n\n return /** @alias module:tool_analytics/log_info */ {\n\n /**\n * Prepares a modal info for a log's results.\n *\n * @method loadInfo\n * @param {int} id\n * @param {string[]} info\n */\n loadInfo: function(id, info) {\n\n var link = $('[data-model-log-id=\"' + id + '\"]');\n str.get_string('loginfo', 'tool_analytics').then(function(langString) {\n\n var bodyInfo = $(\"\");\n\n return ModalFactory.create({\n title: langString,\n body: bodyInfo.html(),\n large: true,\n }, link);\n\n }).catch(Notification.exception);\n }\n };\n});\n"],"names":["define","$","str","ModalFactory","Notification","loadInfo","id","info","link","get_string","then","langString","bodyInfo","forEach","item","append","create","title","body","html","large","catch","exception"],"mappings":";;;;;;;AAsBAA,iCAAO,CAAC,SAAU,WAAY,qBAAsB,sBAAsB,SAASC,EAAGC,IAAKC,aAAcC,oBAEjD,CAShDC,SAAU,SAASC,GAAIC,UAEfC,KAAOP,EAAE,uBAAyBK,GAAK,MAC3CJ,IAAIO,WAAW,UAAW,kBAAkBC,MAAK,SAASC,gBAElDC,SAAWX,EAAE,eACjBM,KAAKM,SAAQ,SAASC,MAClBF,SAASG,OAAO,OAASD,KAAO,YAEpCF,SAASG,OAAO,SAETZ,aAAaa,OAAO,CACvBC,MAAON,WACPO,KAAMN,SAASO,OACfC,OAAO,GACRZ,SAEJa,MAAMjB,aAAakB"} \ No newline at end of file +{"version":3,"file":"log_info.min.js","sources":["../src/log_info.js"],"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 * Shows a dialogue with info about this logs.\n *\n * @module tool_analytics/log_info\n * @copyright 2017 David Monllao {@link http://www.davidmonllao.com}\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Modal from 'core/modal';\nimport {get_string as getString} from 'core/str';\n\n/**\n * Prepares a modal info for a log's results.\n *\n * @param {Number} id\n * @param {string[]} info\n */\nexport const loadInfo = (id, info) => {\n document.addEventListener('click', (e) => {\n const link = e.target.closest(`[data-model-log-id=\"${id}\"]`);\n if (!link) {\n return;\n }\n e.preventDefault();\n const bodyInfo = document.createElement('ul');\n info.forEach((item) => {\n const li = document.createElement('li');\n li.innerHTML = item;\n bodyInfo.append(li);\n });\n\n Modal.create({\n title: getString('loginfo', 'tool_analytics'),\n body: bodyInfo.outerHTML,\n large: true,\n show: true,\n removeOnClose: true,\n }, link);\n });\n};\n"],"names":["id","info","document","addEventListener","e","link","target","closest","preventDefault","bodyInfo","createElement","forEach","item","li","innerHTML","append","create","title","body","outerHTML","large","show","removeOnClose"],"mappings":";;;;;;;8JA+BwB,CAACA,GAAIC,QACzBC,SAASC,iBAAiB,SAAUC,UAC1BC,KAAOD,EAAEE,OAAOC,sCAA+BP,cAChDK,YAGLD,EAAEI,uBACIC,SAAWP,SAASQ,cAAc,MACxCT,KAAKU,SAASC,aACJC,GAAKX,SAASQ,cAAc,MAClCG,GAAGC,UAAYF,KACfH,SAASM,OAAOF,sBAGdG,OAAO,CACTC,OAAO,mBAAU,UAAW,kBAC5BC,KAAMT,SAASU,UACfC,OAAO,EACPC,MAAM,EACNC,eAAe,GAChBjB"} \ No newline at end of file diff --git a/admin/tool/analytics/amd/build/model.min.js b/admin/tool/analytics/amd/build/model.min.js index 6c8812c6022..0b545b5e1db 100644 --- a/admin/tool/analytics/amd/build/model.min.js +++ b/admin/tool/analytics/amd/build/model.min.js @@ -5,6 +5,6 @@ * @copyright 2017 David Monllao * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -define("tool_analytics/model",["jquery","core/str","core/log","core/notification","core/modal_factory","core/modal_events","core/templates"],(function($,Str,log,Notification,ModalFactory,ModalEvents,Templates){var actionsList={clear:{title:{key:"clearpredictions",component:"tool_analytics"},body:{key:"clearmodelpredictions",component:"tool_analytics"}},delete:{title:{key:"delete",component:"tool_analytics"},body:{key:"deletemodelconfirmation",component:"tool_analytics"}}};return{confirmAction:function(actionId,actionType){$('[data-action-id="'+actionId+'"]').on("click",(function(ev){ev.preventDefault();var a=$(ev.currentTarget);if(void 0!==actionsList[actionType]){var wrap,reqStrings=[actionsList[actionType].title,actionsList[actionType].body];reqStrings[1].param=(wrap=$(a).closest("[data-model-name]")).length?wrap.attr("data-model-name"):(log.error("Unexpected DOM error - unable to obtain the model name"),"");var stringsPromise=Str.get_strings(reqStrings),modalPromise=ModalFactory.create({type:ModalFactory.types.SAVE_CANCEL});$.when(stringsPromise,modalPromise).then((function(strings,modal){return modal.setTitle(strings[0]),modal.setBody(strings[1]),modal.setSaveButtonText(strings[0]),modal.getRoot().on(ModalEvents.save,(function(){window.location.href=a.attr("href")})),modal.show(),modal})).fail(Notification.exception)}else log.error('Action "'+actionType+'" is not allowed.')}))},selectEvaluationOptions:function(actionId,trainedOnlyExternally){$('[data-action-id="'+actionId+'"]').on("click",(function(ev){ev.preventDefault();var a=$(ev.currentTarget),timeSplittingMethods=$(this).attr("data-timesplitting-methods"),stringsPromise=Str.get_strings([{key:"evaluatemodel",component:"tool_analytics"},{key:"evaluate",component:"tool_analytics"}]),modalPromise=ModalFactory.create({type:ModalFactory.types.SAVE_CANCEL}),bodyPromise=Templates.render("tool_analytics/evaluation_options",{trainedexternally:trainedOnlyExternally,timesplittingmethods:JSON.parse(timeSplittingMethods)});$.when(stringsPromise,modalPromise).then((function(strings,modal){return modal.getRoot().on(ModalEvents.hidden,modal.destroy.bind(modal)),modal.setTitle(strings[0]),modal.setSaveButtonText(strings[1]),modal.setBody(bodyPromise),modal.getRoot().on(ModalEvents.save,(function(){"trainedmodel"==$("input[name='evaluationmode']:checked").val()&&a.attr("href",a.attr("href")+"&mode=trainedmodel");var timeSplittingMethod=$("#id-evaluation-timesplitting").val();a.attr("href",a.attr("href")+"×plitting="+timeSplittingMethod),window.location.href=a.attr("href")})),modal.show(),modal})).fail(Notification.exception)}))},selectExportOptions:function(actionId,isTrained){$('[data-action-id="'+actionId+'"]').on("click",(function(ev){ev.preventDefault();var a=$(ev.currentTarget);if(!isTrained)return a.attr("href",a.attr("href")+"&action=exportmodel&includeweights=0"),void(window.location.href=a.attr("href"));var stringsPromise=Str.get_strings([{key:"export",component:"tool_analytics"}]),modalPromise=ModalFactory.create({type:ModalFactory.types.SAVE_CANCEL}),bodyPromise=Templates.render("tool_analytics/export_options",{});$.when(stringsPromise,modalPromise).then((function(strings,modal){return modal.getRoot().on(ModalEvents.hidden,modal.destroy.bind(modal)),modal.setTitle(strings[0]),modal.setSaveButtonText(strings[0]),modal.setBody(bodyPromise),modal.getRoot().on(ModalEvents.save,(function(){"exportdata"==$("input[name='exportoption']:checked").val()?a.attr("href",a.attr("href")+"&action=exportdata"):(a.attr("href",a.attr("href")+"&action=exportmodel"),$("#id-includeweights").is(":checked")?a.attr("href",a.attr("href")+"&includeweights=1"):a.attr("href",a.attr("href")+"&includeweights=0")),window.location.href=a.attr("href")})),modal.show(),modal})).fail(Notification.exception)}))}}})); +define("tool_analytics/model",["jquery","core/str","core/log","core/notification","core/modal_save_cancel","core/modal_cancel","core/modal_events","core/templates"],(function($,Str,log,Notification,ModalSaveCancel,ModalCancel,ModalEvents,Templates){var actionsList={clear:{title:{key:"clearpredictions",component:"tool_analytics"},body:{key:"clearmodelpredictions",component:"tool_analytics"}},delete:{title:{key:"delete",component:"tool_analytics"},body:{key:"deletemodelconfirmation",component:"tool_analytics"}}};return{confirmAction:function(actionId,actionType){$('[data-action-id="'+actionId+'"]').on("click",(function(ev){ev.preventDefault();var a=$(ev.currentTarget);if(void 0!==actionsList[actionType]){var wrap,reqStrings=[actionsList[actionType].title,actionsList[actionType].body];reqStrings[1].param=(wrap=$(a).closest("[data-model-name]")).length?wrap.attr("data-model-name"):(log.error("Unexpected DOM error - unable to obtain the model name"),"");var stringsPromise=Str.get_strings(reqStrings),modalPromise=ModalSaveCancel.create({});$.when(stringsPromise,modalPromise).then((function(strings,modal){return modal.setTitle(strings[0]),modal.setBody(strings[1]),modal.setSaveButtonText(strings[0]),modal.getRoot().on(ModalEvents.save,(function(){window.location.href=a.attr("href")})),modal.show(),modal})).fail(Notification.exception)}else log.error('Action "'+actionType+'" is not allowed.')}))},selectEvaluationOptions:function(actionId,trainedOnlyExternally){$('[data-action-id="'+actionId+'"]').on("click",(function(ev){ev.preventDefault();var a=$(ev.currentTarget),timeSplittingMethods=$(this).attr("data-timesplitting-methods");ModalSaveCancel.create({title:Str.get_string("evaluatemodel","tool_analytics"),body:Templates.render("tool_analytics/evaluation_options",{trainedexternally:trainedOnlyExternally,timesplittingmethods:JSON.parse(timeSplittingMethods)}),removeOnClose:!0,buttons:{save:Str.get_string("evaluate","tool_analytics")},show:!0}).then((modal=>(modal.getRoot().on(ModalEvents.save,(function(){"trainedmodel"==$("input[name='evaluationmode']:checked").val()&&a.attr("href",a.attr("href")+"&mode=trainedmodel");var timeSplittingMethod=$("#id-evaluation-timesplitting").val();a.attr("href",a.attr("href")+"×plitting="+timeSplittingMethod),window.location.href=a.attr("href")})),modal))).catch(Notification.exception)}))},selectExportOptions:function(actionId,isTrained){$('[data-action-id="'+actionId+'"]').on("click",(function(ev){ev.preventDefault();var a=$(ev.currentTarget);if(!isTrained)return a.attr("href",a.attr("href")+"&action=exportmodel&includeweights=0"),void(window.location.href=a.attr("href"));var stringsPromise=Str.get_strings([{key:"export",component:"tool_analytics"}]),modalPromise=ModalCancel.create({body:Templates.render("tool_analytics/export_options",{}),removeOnClose:!0});$.when(stringsPromise,modalPromise).then((function(strings,modal){return modal.setTitle(strings[0]),modal.setSaveButtonText(strings[0]),modal.getRoot().on(ModalEvents.save,(function(){"exportdata"==$("input[name='exportoption']:checked").val()?a.attr("href",a.attr("href")+"&action=exportdata"):(a.attr("href",a.attr("href")+"&action=exportmodel"),$("#id-includeweights").is(":checked")?a.attr("href",a.attr("href")+"&includeweights=1"):a.attr("href",a.attr("href")+"&includeweights=0")),window.location.href=a.attr("href")})),modal.show(),modal})).fail(Notification.exception)}))}}})); //# sourceMappingURL=model.min.js.map \ No newline at end of file diff --git a/admin/tool/analytics/amd/build/model.min.js.map b/admin/tool/analytics/amd/build/model.min.js.map index f50f1c0f05a..301a869387c 100644 --- a/admin/tool/analytics/amd/build/model.min.js.map +++ b/admin/tool/analytics/amd/build/model.min.js.map @@ -1 +1 @@ -{"version":3,"file":"model.min.js","sources":["../src/model.js"],"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 * AMD module for model actions confirmation.\n *\n * @module tool_analytics/model\n * @copyright 2017 David Monllao\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(['jquery', 'core/str', 'core/log', 'core/notification', 'core/modal_factory', 'core/modal_events', 'core/templates'],\n function($, Str, log, Notification, ModalFactory, ModalEvents, Templates) {\n\n /**\n * List of actions that require confirmation and confirmation message.\n */\n var actionsList = {\n clear: {\n title: {\n key: 'clearpredictions',\n component: 'tool_analytics'\n }, body: {\n key: 'clearmodelpredictions',\n component: 'tool_analytics'\n }\n\n },\n 'delete': {\n title: {\n key: 'delete',\n component: 'tool_analytics'\n }, body: {\n key: 'deletemodelconfirmation',\n component: 'tool_analytics'\n }\n }\n };\n\n /**\n * Returns the model name.\n *\n * @param {Object} actionItem The action item DOM node.\n * @return {String}\n */\n var getModelName = function(actionItem) {\n var wrap = $(actionItem).closest('[data-model-name]');\n\n if (wrap.length) {\n return wrap.attr('data-model-name');\n\n } else {\n log.error('Unexpected DOM error - unable to obtain the model name');\n return '';\n }\n };\n\n /** @alias module:tool_analytics/model */\n return {\n\n /**\n * Displays a confirm modal window before executing the action.\n *\n * @param {String} actionId\n * @param {String} actionType\n */\n confirmAction: function(actionId, actionType) {\n $('[data-action-id=\"' + actionId + '\"]').on('click', function(ev) {\n ev.preventDefault();\n\n var a = $(ev.currentTarget);\n\n if (typeof actionsList[actionType] === \"undefined\") {\n log.error('Action \"' + actionType + '\" is not allowed.');\n return;\n }\n\n var reqStrings = [\n actionsList[actionType].title,\n actionsList[actionType].body\n ];\n reqStrings[1].param = getModelName(a);\n\n var stringsPromise = Str.get_strings(reqStrings);\n var modalPromise = ModalFactory.create({type: ModalFactory.types.SAVE_CANCEL});\n\n $.when(stringsPromise, modalPromise).then(function(strings, modal) {\n modal.setTitle(strings[0]);\n modal.setBody(strings[1]);\n modal.setSaveButtonText(strings[0]);\n modal.getRoot().on(ModalEvents.save, function() {\n window.location.href = a.attr('href');\n });\n modal.show();\n return modal;\n }).fail(Notification.exception);\n });\n },\n\n /**\n * Displays evaluation mode and time-splitting method choices.\n *\n * @param {String} actionId\n * @param {Boolean} trainedOnlyExternally\n */\n selectEvaluationOptions: function(actionId, trainedOnlyExternally) {\n $('[data-action-id=\"' + actionId + '\"]').on('click', function(ev) {\n ev.preventDefault();\n\n var a = $(ev.currentTarget);\n\n var timeSplittingMethods = $(this).attr('data-timesplitting-methods');\n\n var stringsPromise = Str.get_strings([\n {\n key: 'evaluatemodel',\n component: 'tool_analytics'\n }, {\n key: 'evaluate',\n component: 'tool_analytics'\n }\n ]);\n var modalPromise = ModalFactory.create({type: ModalFactory.types.SAVE_CANCEL});\n var bodyPromise = Templates.render('tool_analytics/evaluation_options', {\n trainedexternally: trainedOnlyExternally,\n timesplittingmethods: JSON.parse(timeSplittingMethods)\n });\n\n $.when(stringsPromise, modalPromise).then(function(strings, modal) {\n\n\n modal.getRoot().on(ModalEvents.hidden, modal.destroy.bind(modal));\n\n modal.setTitle(strings[0]);\n modal.setSaveButtonText(strings[1]);\n modal.setBody(bodyPromise);\n\n modal.getRoot().on(ModalEvents.save, function() {\n\n // Evaluation mode.\n var evaluationMode = $(\"input[name='evaluationmode']:checked\").val();\n if (evaluationMode == 'trainedmodel') {\n a.attr('href', a.attr('href') + '&mode=trainedmodel');\n }\n\n // Selected time-splitting id.\n var timeSplittingMethod = $(\"#id-evaluation-timesplitting\").val();\n a.attr('href', a.attr('href') + '×plitting=' + timeSplittingMethod);\n\n window.location.href = a.attr('href');\n return;\n });\n\n modal.show();\n return modal;\n }).fail(Notification.exception);\n });\n },\n\n /**\n * Displays export options.\n *\n * We have two main options: export training data and export configuration.\n * The 2nd option has an extra option: include the trained algorithm weights.\n *\n * @param {String} actionId\n * @param {Boolean} isTrained\n */\n selectExportOptions: function(actionId, isTrained) {\n $('[data-action-id=\"' + actionId + '\"]').on('click', function(ev) {\n ev.preventDefault();\n\n var a = $(ev.currentTarget);\n\n if (!isTrained) {\n // Export the model configuration if the model is not trained. We can't export anything else.\n a.attr('href', a.attr('href') + '&action=exportmodel&includeweights=0');\n window.location.href = a.attr('href');\n return;\n }\n\n var stringsPromise = Str.get_strings([\n {\n key: 'export',\n component: 'tool_analytics'\n }\n ]);\n var modalPromise = ModalFactory.create({type: ModalFactory.types.SAVE_CANCEL});\n var bodyPromise = Templates.render('tool_analytics/export_options', {});\n\n $.when(stringsPromise, modalPromise).then(function(strings, modal) {\n\n modal.getRoot().on(ModalEvents.hidden, modal.destroy.bind(modal));\n\n modal.setTitle(strings[0]);\n modal.setSaveButtonText(strings[0]);\n modal.setBody(bodyPromise);\n\n modal.getRoot().on(ModalEvents.save, function() {\n\n var exportOption = $(\"input[name='exportoption']:checked\").val();\n\n if (exportOption == 'exportdata') {\n a.attr('href', a.attr('href') + '&action=exportdata');\n\n } else {\n a.attr('href', a.attr('href') + '&action=exportmodel');\n if ($(\"#id-includeweights\").is(':checked')) {\n a.attr('href', a.attr('href') + '&includeweights=1');\n } else {\n a.attr('href', a.attr('href') + '&includeweights=0');\n }\n }\n\n window.location.href = a.attr('href');\n return;\n });\n\n modal.show();\n return modal;\n }).fail(Notification.exception);\n });\n }\n };\n});\n"],"names":["define","$","Str","log","Notification","ModalFactory","ModalEvents","Templates","actionsList","clear","title","key","component","body","confirmAction","actionId","actionType","on","ev","preventDefault","a","currentTarget","wrap","reqStrings","param","closest","length","attr","error","stringsPromise","get_strings","modalPromise","create","type","types","SAVE_CANCEL","when","then","strings","modal","setTitle","setBody","setSaveButtonText","getRoot","save","window","location","href","show","fail","exception","selectEvaluationOptions","trainedOnlyExternally","timeSplittingMethods","this","bodyPromise","render","trainedexternally","timesplittingmethods","JSON","parse","hidden","destroy","bind","val","timeSplittingMethod","selectExportOptions","isTrained","is"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"model.min.js","sources":["../src/model.js"],"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 * AMD module for model actions confirmation.\n *\n * @module tool_analytics/model\n * @copyright 2017 David Monllao\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n 'jquery', 'core/str', 'core/log', 'core/notification', 'core/modal_save_cancel',\n 'core/modal_cancel', 'core/modal_events', 'core/templates'],\n function($, Str, log, Notification, ModalSaveCancel, ModalCancel, ModalEvents, Templates) {\n\n /**\n * List of actions that require confirmation and confirmation message.\n */\n var actionsList = {\n clear: {\n title: {\n key: 'clearpredictions',\n component: 'tool_analytics'\n }, body: {\n key: 'clearmodelpredictions',\n component: 'tool_analytics'\n }\n\n },\n 'delete': {\n title: {\n key: 'delete',\n component: 'tool_analytics'\n }, body: {\n key: 'deletemodelconfirmation',\n component: 'tool_analytics'\n }\n }\n };\n\n /**\n * Returns the model name.\n *\n * @param {Object} actionItem The action item DOM node.\n * @return {String}\n */\n var getModelName = function(actionItem) {\n var wrap = $(actionItem).closest('[data-model-name]');\n\n if (wrap.length) {\n return wrap.attr('data-model-name');\n\n } else {\n log.error('Unexpected DOM error - unable to obtain the model name');\n return '';\n }\n };\n\n /** @alias module:tool_analytics/model */\n return {\n\n /**\n * Displays a confirm modal window before executing the action.\n *\n * @param {String} actionId\n * @param {String} actionType\n */\n confirmAction: function(actionId, actionType) {\n $('[data-action-id=\"' + actionId + '\"]').on('click', function(ev) {\n ev.preventDefault();\n\n var a = $(ev.currentTarget);\n\n if (typeof actionsList[actionType] === \"undefined\") {\n log.error('Action \"' + actionType + '\" is not allowed.');\n return;\n }\n\n var reqStrings = [\n actionsList[actionType].title,\n actionsList[actionType].body\n ];\n reqStrings[1].param = getModelName(a);\n\n var stringsPromise = Str.get_strings(reqStrings);\n var modalPromise = ModalSaveCancel.create({});\n\n $.when(stringsPromise, modalPromise).then(function(strings, modal) {\n modal.setTitle(strings[0]);\n modal.setBody(strings[1]);\n modal.setSaveButtonText(strings[0]);\n modal.getRoot().on(ModalEvents.save, function() {\n window.location.href = a.attr('href');\n });\n modal.show();\n return modal;\n }).fail(Notification.exception);\n });\n },\n\n /**\n * Displays evaluation mode and time-splitting method choices.\n *\n * @param {String} actionId\n * @param {Boolean} trainedOnlyExternally\n */\n selectEvaluationOptions: function(actionId, trainedOnlyExternally) {\n $('[data-action-id=\"' + actionId + '\"]').on('click', function(ev) {\n ev.preventDefault();\n\n var a = $(ev.currentTarget);\n\n var timeSplittingMethods = $(this).attr('data-timesplitting-methods');\n\n ModalSaveCancel.create({\n title: Str.get_string('evaluatemodel', 'tool_analytics'),\n body: Templates.render('tool_analytics/evaluation_options', {\n trainedexternally: trainedOnlyExternally,\n timesplittingmethods: JSON.parse(timeSplittingMethods)\n }),\n removeOnClose: true,\n buttons: {\n save: Str.get_string('evaluate', 'tool_analytics'),\n },\n show: true,\n })\n .then((modal) => {\n modal.getRoot().on(ModalEvents.save, function() {\n // Evaluation mode.\n var evaluationMode = $(\"input[name='evaluationmode']:checked\").val();\n if (evaluationMode == 'trainedmodel') {\n a.attr('href', a.attr('href') + '&mode=trainedmodel');\n }\n\n // Selected time-splitting id.\n var timeSplittingMethod = $(\"#id-evaluation-timesplitting\").val();\n a.attr('href', a.attr('href') + '×plitting=' + timeSplittingMethod);\n\n window.location.href = a.attr('href');\n return;\n });\n\n return modal;\n }).catch(Notification.exception);\n });\n },\n\n /**\n * Displays export options.\n *\n * We have two main options: export training data and export configuration.\n * The 2nd option has an extra option: include the trained algorithm weights.\n *\n * @param {String} actionId\n * @param {Boolean} isTrained\n */\n selectExportOptions: function(actionId, isTrained) {\n $('[data-action-id=\"' + actionId + '\"]').on('click', function(ev) {\n ev.preventDefault();\n\n var a = $(ev.currentTarget);\n\n if (!isTrained) {\n // Export the model configuration if the model is not trained. We can't export anything else.\n a.attr('href', a.attr('href') + '&action=exportmodel&includeweights=0');\n window.location.href = a.attr('href');\n return;\n }\n\n var stringsPromise = Str.get_strings([\n {\n key: 'export',\n component: 'tool_analytics'\n }\n ]);\n var modalPromise = ModalCancel.create({\n body: Templates.render('tool_analytics/export_options', {}),\n removeOnClose: true,\n });\n\n $.when(stringsPromise, modalPromise).then(function(strings, modal) {\n modal.setTitle(strings[0]);\n modal.setSaveButtonText(strings[0]);\n\n modal.getRoot().on(ModalEvents.save, function() {\n\n var exportOption = $(\"input[name='exportoption']:checked\").val();\n\n if (exportOption == 'exportdata') {\n a.attr('href', a.attr('href') + '&action=exportdata');\n\n } else {\n a.attr('href', a.attr('href') + '&action=exportmodel');\n if ($(\"#id-includeweights\").is(':checked')) {\n a.attr('href', a.attr('href') + '&includeweights=1');\n } else {\n a.attr('href', a.attr('href') + '&includeweights=0');\n }\n }\n\n window.location.href = a.attr('href');\n return;\n });\n\n modal.show();\n return modal;\n }).fail(Notification.exception);\n });\n }\n };\n});\n"],"names":["define","$","Str","log","Notification","ModalSaveCancel","ModalCancel","ModalEvents","Templates","actionsList","clear","title","key","component","body","confirmAction","actionId","actionType","on","ev","preventDefault","a","currentTarget","wrap","reqStrings","param","closest","length","attr","error","stringsPromise","get_strings","modalPromise","create","when","then","strings","modal","setTitle","setBody","setSaveButtonText","getRoot","save","window","location","href","show","fail","exception","selectEvaluationOptions","trainedOnlyExternally","timeSplittingMethods","this","get_string","render","trainedexternally","timesplittingmethods","JSON","parse","removeOnClose","buttons","val","timeSplittingMethod","catch","selectExportOptions","isTrained","is"],"mappings":"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"} \ No newline at end of file diff --git a/admin/tool/analytics/amd/src/log_info.js b/admin/tool/analytics/amd/src/log_info.js index 90a683a4be6..7941212fd8a 100644 --- a/admin/tool/analytics/amd/src/log_info.js +++ b/admin/tool/analytics/amd/src/log_info.js @@ -20,35 +20,35 @@ * @copyright 2017 David Monllao {@link http://www.davidmonllao.com} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -define(['jquery', 'core/str', 'core/modal_factory', 'core/notification'], function($, str, ModalFactory, Notification) { +import Modal from 'core/modal'; +import {get_string as getString} from 'core/str'; - return /** @alias module:tool_analytics/log_info */ { - - /** - * Prepares a modal info for a log's results. - * - * @method loadInfo - * @param {int} id - * @param {string[]} info - */ - loadInfo: function(id, info) { - - var link = $('[data-model-log-id="' + id + '"]'); - str.get_string('loginfo', 'tool_analytics').then(function(langString) { - - var bodyInfo = $("
    "); - info.forEach(function(item) { - bodyInfo.append('
  • ' + item + '
  • '); - }); - bodyInfo.append("
"); - - return ModalFactory.create({ - title: langString, - body: bodyInfo.html(), - large: true, - }, link); - - }).catch(Notification.exception); +/** + * Prepares a modal info for a log's results. + * + * @param {Number} id + * @param {string[]} info + */ +export const loadInfo = (id, info) => { + document.addEventListener('click', (e) => { + const link = e.target.closest(`[data-model-log-id="${id}"]`); + if (!link) { + return; } - }; -}); + e.preventDefault(); + const bodyInfo = document.createElement('ul'); + info.forEach((item) => { + const li = document.createElement('li'); + li.innerHTML = item; + bodyInfo.append(li); + }); + + Modal.create({ + title: getString('loginfo', 'tool_analytics'), + body: bodyInfo.outerHTML, + large: true, + show: true, + removeOnClose: true, + }, link); + }); +}; diff --git a/admin/tool/analytics/amd/src/model.js b/admin/tool/analytics/amd/src/model.js index 966c6cc416e..921935157aa 100644 --- a/admin/tool/analytics/amd/src/model.js +++ b/admin/tool/analytics/amd/src/model.js @@ -20,8 +20,10 @@ * @copyright 2017 David Monllao * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -define(['jquery', 'core/str', 'core/log', 'core/notification', 'core/modal_factory', 'core/modal_events', 'core/templates'], - function($, Str, log, Notification, ModalFactory, ModalEvents, Templates) { +define([ + 'jquery', 'core/str', 'core/log', 'core/notification', 'core/modal_save_cancel', + 'core/modal_cancel', 'core/modal_events', 'core/templates'], + function($, Str, log, Notification, ModalSaveCancel, ModalCancel, ModalEvents, Templates) { /** * List of actions that require confirmation and confirmation message. @@ -93,7 +95,7 @@ define(['jquery', 'core/str', 'core/log', 'core/notification', 'core/modal_facto reqStrings[1].param = getModelName(a); var stringsPromise = Str.get_strings(reqStrings); - var modalPromise = ModalFactory.create({type: ModalFactory.types.SAVE_CANCEL}); + var modalPromise = ModalSaveCancel.create({}); $.when(stringsPromise, modalPromise).then(function(strings, modal) { modal.setTitle(strings[0]); @@ -122,32 +124,20 @@ define(['jquery', 'core/str', 'core/log', 'core/notification', 'core/modal_facto var timeSplittingMethods = $(this).attr('data-timesplitting-methods'); - var stringsPromise = Str.get_strings([ - { - key: 'evaluatemodel', - component: 'tool_analytics' - }, { - key: 'evaluate', - component: 'tool_analytics' - } - ]); - var modalPromise = ModalFactory.create({type: ModalFactory.types.SAVE_CANCEL}); - var bodyPromise = Templates.render('tool_analytics/evaluation_options', { - trainedexternally: trainedOnlyExternally, - timesplittingmethods: JSON.parse(timeSplittingMethods) - }); - - $.when(stringsPromise, modalPromise).then(function(strings, modal) { - - - modal.getRoot().on(ModalEvents.hidden, modal.destroy.bind(modal)); - - modal.setTitle(strings[0]); - modal.setSaveButtonText(strings[1]); - modal.setBody(bodyPromise); - + ModalSaveCancel.create({ + title: Str.get_string('evaluatemodel', 'tool_analytics'), + body: Templates.render('tool_analytics/evaluation_options', { + trainedexternally: trainedOnlyExternally, + timesplittingmethods: JSON.parse(timeSplittingMethods) + }), + removeOnClose: true, + buttons: { + save: Str.get_string('evaluate', 'tool_analytics'), + }, + show: true, + }) + .then((modal) => { modal.getRoot().on(ModalEvents.save, function() { - // Evaluation mode. var evaluationMode = $("input[name='evaluationmode']:checked").val(); if (evaluationMode == 'trainedmodel') { @@ -162,9 +152,8 @@ define(['jquery', 'core/str', 'core/log', 'core/notification', 'core/modal_facto return; }); - modal.show(); return modal; - }).fail(Notification.exception); + }).catch(Notification.exception); }); }, @@ -196,16 +185,14 @@ define(['jquery', 'core/str', 'core/log', 'core/notification', 'core/modal_facto component: 'tool_analytics' } ]); - var modalPromise = ModalFactory.create({type: ModalFactory.types.SAVE_CANCEL}); - var bodyPromise = Templates.render('tool_analytics/export_options', {}); + var modalPromise = ModalCancel.create({ + body: Templates.render('tool_analytics/export_options', {}), + removeOnClose: true, + }); $.when(stringsPromise, modalPromise).then(function(strings, modal) { - - modal.getRoot().on(ModalEvents.hidden, modal.destroy.bind(modal)); - modal.setTitle(strings[0]); modal.setSaveButtonText(strings[0]); - modal.setBody(bodyPromise); modal.getRoot().on(ModalEvents.save, function() { diff --git a/admin/tool/dataprivacy/amd/build/add_category.min.js b/admin/tool/dataprivacy/amd/build/add_category.min.js index 63a1d972b27..8e48f782a04 100644 --- a/admin/tool/dataprivacy/amd/build/add_category.min.js +++ b/admin/tool/dataprivacy/amd/build/add_category.min.js @@ -5,6 +5,6 @@ * @copyright 2018 David Monllao * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -define("tool_dataprivacy/add_category",["jquery","core/str","core/ajax","core/notification","core/modal_factory","core/modal_events","core/fragment","core_form/changechecker"],(function($,Str,Ajax,Notification,ModalFactory,ModalEvents,Fragment,FormChangeChecker){var SELECTORS_CATEGORY_LINK='[data-add-element="category"]',AddCategory=function(contextId){this.contextId=contextId;this.strings=Str.get_strings([{key:"addcategory",component:"tool_dataprivacy"},{key:"save",component:"admin"}]),this.registerEventListeners()};return AddCategory.prototype.contextId=0,AddCategory.prototype.strings=0,AddCategory.prototype.registerEventListeners=function(){var trigger=$(SELECTORS_CATEGORY_LINK);trigger.on("click",function(){return this.strings.then(function(strings){ModalFactory.create({type:ModalFactory.types.SAVE_CANCEL,title:strings[0],body:""},trigger).done(function(modal){this.setupFormModal(modal,strings[1])}.bind(this))}.bind(this)).fail(Notification.exception)}.bind(this))},AddCategory.prototype.getBody=function(formdata){var params=null;return void 0!==formdata&&(params={jsonformdata:JSON.stringify(formdata)}),Fragment.loadFragment("tool_dataprivacy","addcategory_form",this.contextId,params)},AddCategory.prototype.setupFormModal=function(modal,saveText){modal.setLarge(),modal.setSaveButtonText(saveText),modal.getRoot().on(ModalEvents.hidden,this.destroy.bind(this)),modal.setBody(this.getBody()),modal.getRoot().on(ModalEvents.save,this.submitForm.bind(this)),modal.getRoot().on("submit","form",this.submitFormAjax.bind(this)),this.modal=modal,modal.show()},AddCategory.prototype.submitForm=function(e){e.preventDefault(),this.modal.getRoot().find("form").submit()},AddCategory.prototype.submitFormAjax=function(e){e.preventDefault();var formData=this.modal.getRoot().find("form").serialize();Ajax.call([{methodname:"tool_dataprivacy_create_category_form",args:{jsonformdata:JSON.stringify(formData)},done:function(data){data.validationerrors?this.modal.setBody(this.getBody(formData)):this.close()}.bind(this),fail:Notification.exception}])},AddCategory.prototype.close=function(){this.destroy(),document.location.reload()},AddCategory.prototype.destroy=function(){FormChangeChecker.resetAllFormDirtyStates(),this.modal.destroy()},AddCategory.prototype.removeListeners=function(){$(SELECTORS_CATEGORY_LINK).off("click")},{getInstance:function(contextId){return new AddCategory(contextId)}}})); +define("tool_dataprivacy/add_category",["jquery","core/str","core/ajax","core/notification","core/modal_save_cancel","core/modal_events","core/fragment","core_form/changechecker"],(function($,Str,Ajax,Notification,ModalSaveCancel,ModalEvents,Fragment,FormChangeChecker){var SELECTORS_CATEGORY_LINK='[data-add-element="category"]',AddCategory=function(contextId){this.contextId=contextId;this.strings=Str.get_strings([{key:"addcategory",component:"tool_dataprivacy"},{key:"save",component:"admin"}]),this.registerEventListeners()};return AddCategory.prototype.contextId=0,AddCategory.prototype.strings=0,AddCategory.prototype.registerEventListeners=function(){$(SELECTORS_CATEGORY_LINK).on("click",function(){this.strings.then(function(strings){return Promise.all([ModalSaveCancel.create({title:strings[0],body:""}),strings[1]]).then(function(_ref){let[modal,string]=_ref;return this.setupFormModal(modal,string),modal}.bind(this))}.bind(this)).catch(Notification.exception)}.bind(this))},AddCategory.prototype.getBody=function(formdata){var params=null;return void 0!==formdata&&(params={jsonformdata:JSON.stringify(formdata)}),Fragment.loadFragment("tool_dataprivacy","addcategory_form",this.contextId,params)},AddCategory.prototype.setupFormModal=function(modal,saveText){modal.setLarge(),modal.setSaveButtonText(saveText),modal.getRoot().on(ModalEvents.hidden,this.destroy.bind(this)),modal.setBody(this.getBody()),modal.getRoot().on(ModalEvents.save,this.submitForm.bind(this)),modal.getRoot().on("submit","form",this.submitFormAjax.bind(this)),this.modal=modal,modal.show()},AddCategory.prototype.submitForm=function(e){e.preventDefault(),this.modal.getRoot().find("form").submit()},AddCategory.prototype.submitFormAjax=function(e){e.preventDefault();var formData=this.modal.getRoot().find("form").serialize();Ajax.call([{methodname:"tool_dataprivacy_create_category_form",args:{jsonformdata:JSON.stringify(formData)},done:function(data){data.validationerrors?this.modal.setBody(this.getBody(formData)):this.close()}.bind(this),fail:Notification.exception}])},AddCategory.prototype.close=function(){this.destroy(),document.location.reload()},AddCategory.prototype.destroy=function(){FormChangeChecker.resetAllFormDirtyStates(),this.modal.destroy()},AddCategory.prototype.removeListeners=function(){$(SELECTORS_CATEGORY_LINK).off("click")},{getInstance:function(contextId){return new AddCategory(contextId)}}})); //# sourceMappingURL=add_category.min.js.map \ No newline at end of file diff --git a/admin/tool/dataprivacy/amd/build/add_category.min.js.map b/admin/tool/dataprivacy/amd/build/add_category.min.js.map index 2ee9d89dc99..55a0d1f9c75 100644 --- a/admin/tool/dataprivacy/amd/build/add_category.min.js.map +++ b/admin/tool/dataprivacy/amd/build/add_category.min.js.map @@ -1 +1 @@ -{"version":3,"file":"add_category.min.js","sources":["../src/add_category.js"],"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 * Module to add categories.\n *\n * @module tool_dataprivacy/add_category\n * @copyright 2018 David Monllao\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n 'jquery',\n 'core/str',\n 'core/ajax',\n 'core/notification',\n 'core/modal_factory',\n 'core/modal_events',\n 'core/fragment',\n 'core_form/changechecker',\n], function(\n $,\n Str,\n Ajax,\n Notification,\n ModalFactory,\n ModalEvents,\n Fragment,\n FormChangeChecker\n) {\n\n var SELECTORS = {\n CATEGORY_LINK: '[data-add-element=\"category\"]',\n };\n\n var AddCategory = function(contextId) {\n this.contextId = contextId;\n\n var stringKeys = [\n {\n key: 'addcategory',\n component: 'tool_dataprivacy'\n },\n {\n key: 'save',\n component: 'admin'\n }\n ];\n this.strings = Str.get_strings(stringKeys);\n\n this.registerEventListeners();\n };\n\n /**\n * @var {int} contextId\n * @private\n */\n AddCategory.prototype.contextId = 0;\n\n /**\n * @var {Promise}\n * @private\n */\n AddCategory.prototype.strings = 0;\n\n AddCategory.prototype.registerEventListeners = function() {\n\n var trigger = $(SELECTORS.CATEGORY_LINK);\n trigger.on('click', function() {\n return this.strings.then(function(strings) {\n ModalFactory.create({\n type: ModalFactory.types.SAVE_CANCEL,\n title: strings[0],\n body: '',\n }, trigger).done(function(modal) {\n this.setupFormModal(modal, strings[1]);\n }.bind(this));\n }.bind(this))\n .fail(Notification.exception);\n }.bind(this));\n\n };\n\n /**\n * @method getBody\n * @param {Object} formdata\n * @private\n * @return {Promise}\n */\n AddCategory.prototype.getBody = function(formdata) {\n\n var params = null;\n if (typeof formdata !== \"undefined\") {\n params = {jsonformdata: JSON.stringify(formdata)};\n }\n // Get the content of the modal.\n return Fragment.loadFragment('tool_dataprivacy', 'addcategory_form', this.contextId, params);\n };\n\n AddCategory.prototype.setupFormModal = function(modal, saveText) {\n modal.setLarge();\n\n modal.setSaveButtonText(saveText);\n\n // We want to reset the form every time it is opened.\n modal.getRoot().on(ModalEvents.hidden, this.destroy.bind(this));\n\n modal.setBody(this.getBody());\n\n // We catch the modal save event, and use it to submit the form inside the modal.\n // Triggering a form submission will give JS validation scripts a chance to check for errors.\n modal.getRoot().on(ModalEvents.save, this.submitForm.bind(this));\n // We also catch the form submit event and use it to submit the form with ajax.\n modal.getRoot().on('submit', 'form', this.submitFormAjax.bind(this));\n\n this.modal = modal;\n\n modal.show();\n };\n\n /**\n * This triggers a form submission, so that any mform elements can do final tricks before the form submission is processed.\n *\n * @method submitForm\n * @param {Event} e Form submission event.\n * @private\n */\n AddCategory.prototype.submitForm = function(e) {\n e.preventDefault();\n this.modal.getRoot().find('form').submit();\n };\n\n AddCategory.prototype.submitFormAjax = function(e) {\n // We don't want to do a real form submission.\n e.preventDefault();\n\n // Convert all the form elements values to a serialised string.\n var formData = this.modal.getRoot().find('form').serialize();\n\n Ajax.call([{\n methodname: 'tool_dataprivacy_create_category_form',\n args: {jsonformdata: JSON.stringify(formData)},\n done: function(data) {\n if (data.validationerrors) {\n this.modal.setBody(this.getBody(formData));\n } else {\n this.close();\n }\n }.bind(this),\n fail: Notification.exception\n }]);\n };\n\n AddCategory.prototype.close = function() {\n this.destroy();\n document.location.reload();\n };\n\n AddCategory.prototype.destroy = function() {\n FormChangeChecker.resetAllFormDirtyStates();\n this.modal.destroy();\n };\n\n AddCategory.prototype.removeListeners = function() {\n $(SELECTORS.CATEGORY_LINK).off('click');\n };\n\n return /** @alias module:tool_dataprivacy/add_category */ {\n getInstance: function(contextId) {\n return new AddCategory(contextId);\n }\n };\n }\n);\n\n"],"names":["define","$","Str","Ajax","Notification","ModalFactory","ModalEvents","Fragment","FormChangeChecker","SELECTORS","AddCategory","contextId","strings","get_strings","key","component","registerEventListeners","prototype","trigger","on","this","then","create","type","types","SAVE_CANCEL","title","body","done","modal","setupFormModal","bind","fail","exception","getBody","formdata","params","jsonformdata","JSON","stringify","loadFragment","saveText","setLarge","setSaveButtonText","getRoot","hidden","destroy","setBody","save","submitForm","submitFormAjax","show","e","preventDefault","find","submit","formData","serialize","call","methodname","args","data","validationerrors","close","document","location","reload","resetAllFormDirtyStates","removeListeners","off","getInstance"],"mappings":";;;;;;;AAsBAA,uCAAO,CACH,SACA,WACA,YACA,oBACA,qBACA,oBACA,gBACA,4BACD,SACCC,EACAC,IACAC,KACAC,aACAC,aACAC,YACAC,SACAC,uBAGQC,wBACe,gCAGfC,YAAc,SAASC,gBAClBA,UAAYA,eAYZC,QAAUV,IAAIW,YAVF,CACb,CACIC,IAAK,cACLC,UAAW,oBAEf,CACID,IAAK,OACLC,UAAW,gBAKdC,iCAOTN,YAAYO,UAAUN,UAAY,EAMlCD,YAAYO,UAAUL,QAAU,EAEhCF,YAAYO,UAAUD,uBAAyB,eAEvCE,QAAUjB,EAAEQ,yBAChBS,QAAQC,GAAG,QAAS,kBACTC,KAAKR,QAAQS,KAAK,SAAST,SAC9BP,aAAaiB,OAAO,CAChBC,KAAMlB,aAAamB,MAAMC,YACzBC,MAAOd,QAAQ,GACfe,KAAM,IACPT,SAASU,KAAK,SAASC,YACjBC,eAAeD,MAAOjB,QAAQ,KACrCmB,KAAKX,QACTW,KAAKX,OACNY,KAAK5B,aAAa6B,YACrBF,KAAKX,QAUXV,YAAYO,UAAUiB,QAAU,SAASC,cAEjCC,OAAS,iBACW,IAAbD,WACPC,OAAS,CAACC,aAAcC,KAAKC,UAAUJ,YAGpC5B,SAASiC,aAAa,mBAAoB,mBAAoBpB,KAAKT,UAAWyB,SAGzF1B,YAAYO,UAAUa,eAAiB,SAASD,MAAOY,UACnDZ,MAAMa,WAENb,MAAMc,kBAAkBF,UAGxBZ,MAAMe,UAAUzB,GAAGb,YAAYuC,OAAQzB,KAAK0B,QAAQf,KAAKX,OAEzDS,MAAMkB,QAAQ3B,KAAKc,WAInBL,MAAMe,UAAUzB,GAAGb,YAAY0C,KAAM5B,KAAK6B,WAAWlB,KAAKX,OAE1DS,MAAMe,UAAUzB,GAAG,SAAU,OAAQC,KAAK8B,eAAenB,KAAKX,YAEzDS,MAAQA,MAEbA,MAAMsB,QAUVzC,YAAYO,UAAUgC,WAAa,SAASG,GACxCA,EAAEC,sBACGxB,MAAMe,UAAUU,KAAK,QAAQC,UAGtC7C,YAAYO,UAAUiC,eAAiB,SAASE,GAE5CA,EAAEC,qBAGEG,SAAWpC,KAAKS,MAAMe,UAAUU,KAAK,QAAQG,YAEjDtD,KAAKuD,KAAK,CAAC,CACPC,WAAY,wCACZC,KAAM,CAACvB,aAAcC,KAAKC,UAAUiB,WACpC5B,KAAM,SAASiC,MACPA,KAAKC,sBACAjC,MAAMkB,QAAQ3B,KAAKc,QAAQsB,gBAE3BO,SAEXhC,KAAKX,MACPY,KAAM5B,aAAa6B,cAI3BvB,YAAYO,UAAU8C,MAAQ,gBACrBjB,UACLkB,SAASC,SAASC,UAGtBxD,YAAYO,UAAU6B,QAAU,WAC5BtC,kBAAkB2D,+BACbtC,MAAMiB,WAGfpC,YAAYO,UAAUmD,gBAAkB,WACpCnE,EAAEQ,yBAAyB4D,IAAI,UAGuB,CACtDC,YAAa,SAAS3D,kBACX,IAAID,YAAYC"} \ No newline at end of file +{"version":3,"file":"add_category.min.js","sources":["../src/add_category.js"],"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 * Module to add categories.\n *\n * @module tool_dataprivacy/add_category\n * @copyright 2018 David Monllao\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n 'jquery',\n 'core/str',\n 'core/ajax',\n 'core/notification',\n 'core/modal_save_cancel',\n 'core/modal_events',\n 'core/fragment',\n 'core_form/changechecker',\n], function(\n $,\n Str,\n Ajax,\n Notification,\n ModalSaveCancel,\n ModalEvents,\n Fragment,\n FormChangeChecker\n) {\n\n var SELECTORS = {\n CATEGORY_LINK: '[data-add-element=\"category\"]',\n };\n\n var AddCategory = function(contextId) {\n this.contextId = contextId;\n\n var stringKeys = [\n {\n key: 'addcategory',\n component: 'tool_dataprivacy'\n },\n {\n key: 'save',\n component: 'admin'\n }\n ];\n this.strings = Str.get_strings(stringKeys);\n\n this.registerEventListeners();\n };\n\n /**\n * @var {int} contextId\n * @private\n */\n AddCategory.prototype.contextId = 0;\n\n /**\n * @var {Promise}\n * @private\n */\n AddCategory.prototype.strings = 0;\n\n AddCategory.prototype.registerEventListeners = function() {\n\n var trigger = $(SELECTORS.CATEGORY_LINK);\n trigger.on('click', function() {\n this.strings.then(function(strings) {\n return Promise.all([\n ModalSaveCancel.create({\n title: strings[0],\n body: '',\n }),\n strings[1],\n ]).then(function([modal, string]) {\n this.setupFormModal(modal, string);\n return modal;\n }.bind(this));\n }.bind(this))\n .catch(Notification.exception);\n }.bind(this));\n\n };\n\n /**\n * @method getBody\n * @param {Object} formdata\n * @private\n * @return {Promise}\n */\n AddCategory.prototype.getBody = function(formdata) {\n\n var params = null;\n if (typeof formdata !== \"undefined\") {\n params = {jsonformdata: JSON.stringify(formdata)};\n }\n // Get the content of the modal.\n return Fragment.loadFragment('tool_dataprivacy', 'addcategory_form', this.contextId, params);\n };\n\n AddCategory.prototype.setupFormModal = function(modal, saveText) {\n modal.setLarge();\n\n modal.setSaveButtonText(saveText);\n\n // We want to reset the form every time it is opened.\n modal.getRoot().on(ModalEvents.hidden, this.destroy.bind(this));\n\n modal.setBody(this.getBody());\n\n // We catch the modal save event, and use it to submit the form inside the modal.\n // Triggering a form submission will give JS validation scripts a chance to check for errors.\n modal.getRoot().on(ModalEvents.save, this.submitForm.bind(this));\n // We also catch the form submit event and use it to submit the form with ajax.\n modal.getRoot().on('submit', 'form', this.submitFormAjax.bind(this));\n\n this.modal = modal;\n\n modal.show();\n };\n\n /**\n * This triggers a form submission, so that any mform elements can do final tricks before the form submission is processed.\n *\n * @method submitForm\n * @param {Event} e Form submission event.\n * @private\n */\n AddCategory.prototype.submitForm = function(e) {\n e.preventDefault();\n this.modal.getRoot().find('form').submit();\n };\n\n AddCategory.prototype.submitFormAjax = function(e) {\n // We don't want to do a real form submission.\n e.preventDefault();\n\n // Convert all the form elements values to a serialised string.\n var formData = this.modal.getRoot().find('form').serialize();\n\n Ajax.call([{\n methodname: 'tool_dataprivacy_create_category_form',\n args: {jsonformdata: JSON.stringify(formData)},\n done: function(data) {\n if (data.validationerrors) {\n this.modal.setBody(this.getBody(formData));\n } else {\n this.close();\n }\n }.bind(this),\n fail: Notification.exception\n }]);\n };\n\n AddCategory.prototype.close = function() {\n this.destroy();\n document.location.reload();\n };\n\n AddCategory.prototype.destroy = function() {\n FormChangeChecker.resetAllFormDirtyStates();\n this.modal.destroy();\n };\n\n AddCategory.prototype.removeListeners = function() {\n $(SELECTORS.CATEGORY_LINK).off('click');\n };\n\n return /** @alias module:tool_dataprivacy/add_category */ {\n getInstance: function(contextId) {\n return new AddCategory(contextId);\n }\n };\n }\n);\n"],"names":["define","$","Str","Ajax","Notification","ModalSaveCancel","ModalEvents","Fragment","FormChangeChecker","SELECTORS","AddCategory","contextId","strings","get_strings","key","component","registerEventListeners","prototype","on","then","Promise","all","create","title","body","modal","string","setupFormModal","bind","this","catch","exception","getBody","formdata","params","jsonformdata","JSON","stringify","loadFragment","saveText","setLarge","setSaveButtonText","getRoot","hidden","destroy","setBody","save","submitForm","submitFormAjax","show","e","preventDefault","find","submit","formData","serialize","call","methodname","args","done","data","validationerrors","close","fail","document","location","reload","resetAllFormDirtyStates","removeListeners","off","getInstance"],"mappings":";;;;;;;AAsBAA,uCAAO,CACH,SACA,WACA,YACA,oBACA,yBACA,oBACA,gBACA,4BACD,SACCC,EACAC,IACAC,KACAC,aACAC,gBACAC,YACAC,SACAC,uBAGQC,wBACe,gCAGfC,YAAc,SAASC,gBAClBA,UAAYA,eAYZC,QAAUV,IAAIW,YAVF,CACb,CACIC,IAAK,cACLC,UAAW,oBAEf,CACID,IAAK,OACLC,UAAW,gBAKdC,iCAOTN,YAAYO,UAAUN,UAAY,EAMlCD,YAAYO,UAAUL,QAAU,EAEhCF,YAAYO,UAAUD,uBAAyB,WAE7Bf,EAAEQ,yBACRS,GAAG,QAAS,gBACXN,QAAQO,KAAK,SAASP,gBAChBQ,QAAQC,IAAI,CACfhB,gBAAgBiB,OAAO,CACnBC,MAAOX,QAAQ,GACfY,KAAM,KAEVZ,QAAQ,KACTO,KAAK,mBAAUM,MAAOC,yBAChBC,eAAeF,MAAOC,QACpBD,OACTG,KAAKC,QACTD,KAAKC,OACNC,MAAM1B,aAAa2B,YACtBH,KAAKC,QAUXnB,YAAYO,UAAUe,QAAU,SAASC,cAEjCC,OAAS,iBACW,IAAbD,WACPC,OAAS,CAACC,aAAcC,KAAKC,UAAUJ,YAGpC1B,SAAS+B,aAAa,mBAAoB,mBAAoBT,KAAKlB,UAAWuB,SAGzFxB,YAAYO,UAAUU,eAAiB,SAASF,MAAOc,UACnDd,MAAMe,WAENf,MAAMgB,kBAAkBF,UAGxBd,MAAMiB,UAAUxB,GAAGZ,YAAYqC,OAAQd,KAAKe,QAAQhB,KAAKC,OAEzDJ,MAAMoB,QAAQhB,KAAKG,WAInBP,MAAMiB,UAAUxB,GAAGZ,YAAYwC,KAAMjB,KAAKkB,WAAWnB,KAAKC,OAE1DJ,MAAMiB,UAAUxB,GAAG,SAAU,OAAQW,KAAKmB,eAAepB,KAAKC,YAEzDJ,MAAQA,MAEbA,MAAMwB,QAUVvC,YAAYO,UAAU8B,WAAa,SAASG,GACxCA,EAAEC,sBACG1B,MAAMiB,UAAUU,KAAK,QAAQC,UAGtC3C,YAAYO,UAAU+B,eAAiB,SAASE,GAE5CA,EAAEC,qBAGEG,SAAWzB,KAAKJ,MAAMiB,UAAUU,KAAK,QAAQG,YAEjDpD,KAAKqD,KAAK,CAAC,CACPC,WAAY,wCACZC,KAAM,CAACvB,aAAcC,KAAKC,UAAUiB,WACpCK,KAAM,SAASC,MACPA,KAAKC,sBACApC,MAAMoB,QAAQhB,KAAKG,QAAQsB,gBAE3BQ,SAEXlC,KAAKC,MACPkC,KAAM3D,aAAa2B,cAI3BrB,YAAYO,UAAU6C,MAAQ,gBACrBlB,UACLoB,SAASC,SAASC,UAGtBxD,YAAYO,UAAU2B,QAAU,WAC5BpC,kBAAkB2D,+BACb1C,MAAMmB,WAGflC,YAAYO,UAAUmD,gBAAkB,WACpCnE,EAAEQ,yBAAyB4D,IAAI,UAGuB,CACtDC,YAAa,SAAS3D,kBACX,IAAID,YAAYC"} \ No newline at end of file diff --git a/admin/tool/dataprivacy/amd/build/add_purpose.min.js b/admin/tool/dataprivacy/amd/build/add_purpose.min.js index 1a949a9f722..a0515e3f706 100644 --- a/admin/tool/dataprivacy/amd/build/add_purpose.min.js +++ b/admin/tool/dataprivacy/amd/build/add_purpose.min.js @@ -5,6 +5,6 @@ * @copyright 2018 David Monllao * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -define("tool_dataprivacy/add_purpose",["jquery","core/str","core/ajax","core/notification","core/modal_factory","core/modal_events","core/fragment","core_form/changechecker"],(function($,Str,Ajax,Notification,ModalFactory,ModalEvents,Fragment,FormChangeChecker){var SELECTORS_PURPOSE_LINK='[data-add-element="purpose"]',AddPurpose=function(contextId){this.contextId=contextId;this.strings=Str.get_strings([{key:"addpurpose",component:"tool_dataprivacy"},{key:"save",component:"admin"}]),this.registerEventListeners()};return AddPurpose.prototype.contextId=0,AddPurpose.prototype.strings=0,AddPurpose.prototype.registerEventListeners=function(){var trigger=$(SELECTORS_PURPOSE_LINK);trigger.on("click",function(){return this.strings.then(function(strings){ModalFactory.create({type:ModalFactory.types.SAVE_CANCEL,title:strings[0],body:""},trigger).done(function(modal){this.setupFormModal(modal,strings[1])}.bind(this))}.bind(this)).fail(Notification.exception)}.bind(this))},AddPurpose.prototype.getBody=function(formdata){var params=null;return void 0!==formdata&&(params={jsonformdata:JSON.stringify(formdata)}),Fragment.loadFragment("tool_dataprivacy","addpurpose_form",this.contextId,params)},AddPurpose.prototype.setupFormModal=function(modal,saveText){modal.setLarge(),modal.setSaveButtonText(saveText),modal.getRoot().on(ModalEvents.hidden,this.destroy.bind(this)),modal.setBody(this.getBody()),modal.getRoot().on(ModalEvents.save,this.submitForm.bind(this)),modal.getRoot().on("submit","form",this.submitFormAjax.bind(this)),this.modal=modal,modal.show()},AddPurpose.prototype.submitForm=function(e){e.preventDefault(),this.modal.getRoot().find("form").submit()},AddPurpose.prototype.submitFormAjax=function(e){e.preventDefault();var formData=this.modal.getRoot().find("form").serialize();Ajax.call([{methodname:"tool_dataprivacy_create_purpose_form",args:{jsonformdata:JSON.stringify(formData)},done:function(data){data.validationerrors?this.modal.setBody(this.getBody(formData)):this.close()}.bind(this),fail:Notification.exception}])},AddPurpose.prototype.close=function(){this.destroy(),document.location.reload()},AddPurpose.prototype.destroy=function(){FormChangeChecker.resetAllFormDirtyStates(),this.modal.destroy()},AddPurpose.prototype.removeListeners=function(){$(SELECTORS_PURPOSE_LINK).off("click")},{getInstance:function(contextId){return new AddPurpose(contextId)}}})); +define("tool_dataprivacy/add_purpose",["jquery","core/str","core/ajax","core/notification","core/modal_save_cancel","core/modal_events","core/fragment","core_form/changechecker"],(function($,Str,Ajax,Notification,ModalSaveCancel,ModalEvents,Fragment,FormChangeChecker){var SELECTORS_PURPOSE_LINK='[data-add-element="purpose"]',AddPurpose=function(contextId){this.contextId=contextId;this.strings=Str.get_strings([{key:"addpurpose",component:"tool_dataprivacy"},{key:"save",component:"admin"}]),this.registerEventListeners()};return AddPurpose.prototype.contextId=0,AddPurpose.prototype.strings=0,AddPurpose.prototype.registerEventListeners=function(){$(SELECTORS_PURPOSE_LINK).on("click",function(){this.strings.then(function(strings){return Promise.all([ModalSaveCancel.create({title:strings[0],body:""}),strings[1]]).then(function(_ref){let[modal,string]=_ref;this.setupFormModal(modal,string)}.bind(this))}.bind(this)).catch(Notification.exception)}.bind(this))},AddPurpose.prototype.getBody=function(formdata){var params=null;return void 0!==formdata&&(params={jsonformdata:JSON.stringify(formdata)}),Fragment.loadFragment("tool_dataprivacy","addpurpose_form",this.contextId,params)},AddPurpose.prototype.setupFormModal=function(modal,saveText){modal.setLarge(),modal.setSaveButtonText(saveText),modal.getRoot().on(ModalEvents.hidden,this.destroy.bind(this)),modal.setBody(this.getBody()),modal.getRoot().on(ModalEvents.save,this.submitForm.bind(this)),modal.getRoot().on("submit","form",this.submitFormAjax.bind(this)),this.modal=modal,modal.show()},AddPurpose.prototype.submitForm=function(e){e.preventDefault(),this.modal.getRoot().find("form").submit()},AddPurpose.prototype.submitFormAjax=function(e){e.preventDefault();var formData=this.modal.getRoot().find("form").serialize();Ajax.call([{methodname:"tool_dataprivacy_create_purpose_form",args:{jsonformdata:JSON.stringify(formData)},done:function(data){data.validationerrors?this.modal.setBody(this.getBody(formData)):this.close()}.bind(this),fail:Notification.exception}])},AddPurpose.prototype.close=function(){this.destroy(),document.location.reload()},AddPurpose.prototype.destroy=function(){FormChangeChecker.resetAllFormDirtyStates(),this.modal.destroy()},AddPurpose.prototype.removeListeners=function(){$(SELECTORS_PURPOSE_LINK).off("click")},{getInstance:function(contextId){return new AddPurpose(contextId)}}})); //# sourceMappingURL=add_purpose.min.js.map \ No newline at end of file diff --git a/admin/tool/dataprivacy/amd/build/add_purpose.min.js.map b/admin/tool/dataprivacy/amd/build/add_purpose.min.js.map index 6b9b9f5b460..4e2e496cb02 100644 --- a/admin/tool/dataprivacy/amd/build/add_purpose.min.js.map +++ b/admin/tool/dataprivacy/amd/build/add_purpose.min.js.map @@ -1 +1 @@ -{"version":3,"file":"add_purpose.min.js","sources":["../src/add_purpose.js"],"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 * Module to add purposes.\n *\n * @module tool_dataprivacy/add_purpose\n * @copyright 2018 David Monllao\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n 'jquery',\n 'core/str',\n 'core/ajax',\n 'core/notification',\n 'core/modal_factory',\n 'core/modal_events',\n 'core/fragment',\n 'core_form/changechecker',\n], function(\n $,\n Str,\n Ajax,\n Notification,\n ModalFactory,\n ModalEvents,\n Fragment,\n FormChangeChecker\n) {\n\n var SELECTORS = {\n PURPOSE_LINK: '[data-add-element=\"purpose\"]',\n };\n\n var AddPurpose = function(contextId) {\n this.contextId = contextId;\n\n var stringKeys = [\n {\n key: 'addpurpose',\n component: 'tool_dataprivacy'\n },\n {\n key: 'save',\n component: 'admin'\n }\n ];\n this.strings = Str.get_strings(stringKeys);\n\n this.registerEventListeners();\n };\n\n /**\n * @var {int} contextId\n * @private\n */\n AddPurpose.prototype.contextId = 0;\n\n /**\n * @var {Promise}\n * @private\n */\n AddPurpose.prototype.strings = 0;\n\n AddPurpose.prototype.registerEventListeners = function() {\n\n var trigger = $(SELECTORS.PURPOSE_LINK);\n trigger.on('click', function() {\n return this.strings.then(function(strings) {\n ModalFactory.create({\n type: ModalFactory.types.SAVE_CANCEL,\n title: strings[0],\n body: '',\n }, trigger).done(function(modal) {\n this.setupFormModal(modal, strings[1]);\n }.bind(this));\n }.bind(this))\n .fail(Notification.exception);\n }.bind(this));\n\n };\n\n /**\n * @method getBody\n * @param {Object} formdata\n * @private\n * @return {Promise}\n */\n AddPurpose.prototype.getBody = function(formdata) {\n\n var params = null;\n if (typeof formdata !== \"undefined\") {\n params = {jsonformdata: JSON.stringify(formdata)};\n }\n // Get the content of the modal.\n return Fragment.loadFragment('tool_dataprivacy', 'addpurpose_form', this.contextId, params);\n };\n\n AddPurpose.prototype.setupFormModal = function(modal, saveText) {\n modal.setLarge();\n\n modal.setSaveButtonText(saveText);\n\n // We want to reset the form every time it is opened.\n modal.getRoot().on(ModalEvents.hidden, this.destroy.bind(this));\n\n modal.setBody(this.getBody());\n\n // We catch the modal save event, and use it to submit the form inside the modal.\n // Triggering a form submission will give JS validation scripts a chance to check for errors.\n modal.getRoot().on(ModalEvents.save, this.submitForm.bind(this));\n // We also catch the form submit event and use it to submit the form with ajax.\n modal.getRoot().on('submit', 'form', this.submitFormAjax.bind(this));\n\n this.modal = modal;\n\n modal.show();\n };\n\n /**\n * This triggers a form submission, so that any mform elements can do final tricks before the form submission is processed.\n *\n * @method submitForm\n * @param {Event} e Form submission event.\n * @private\n */\n AddPurpose.prototype.submitForm = function(e) {\n e.preventDefault();\n this.modal.getRoot().find('form').submit();\n };\n\n AddPurpose.prototype.submitFormAjax = function(e) {\n // We don't want to do a real form submission.\n e.preventDefault();\n\n // Convert all the form elements values to a serialised string.\n var formData = this.modal.getRoot().find('form').serialize();\n\n Ajax.call([{\n methodname: 'tool_dataprivacy_create_purpose_form',\n args: {jsonformdata: JSON.stringify(formData)},\n done: function(data) {\n if (data.validationerrors) {\n this.modal.setBody(this.getBody(formData));\n } else {\n this.close();\n }\n }.bind(this),\n\n fail: Notification.exception\n }]);\n };\n\n AddPurpose.prototype.close = function() {\n this.destroy();\n document.location.reload();\n };\n\n AddPurpose.prototype.destroy = function() {\n FormChangeChecker.resetAllFormDirtyStates();\n this.modal.destroy();\n };\n\n AddPurpose.prototype.removeListeners = function() {\n $(SELECTORS.PURPOSE_LINK).off('click');\n };\n\n return /** @alias module:tool_dataprivacy/add_purpose */ {\n getInstance: function(contextId) {\n return new AddPurpose(contextId);\n }\n };\n }\n);\n\n"],"names":["define","$","Str","Ajax","Notification","ModalFactory","ModalEvents","Fragment","FormChangeChecker","SELECTORS","AddPurpose","contextId","strings","get_strings","key","component","registerEventListeners","prototype","trigger","on","this","then","create","type","types","SAVE_CANCEL","title","body","done","modal","setupFormModal","bind","fail","exception","getBody","formdata","params","jsonformdata","JSON","stringify","loadFragment","saveText","setLarge","setSaveButtonText","getRoot","hidden","destroy","setBody","save","submitForm","submitFormAjax","show","e","preventDefault","find","submit","formData","serialize","call","methodname","args","data","validationerrors","close","document","location","reload","resetAllFormDirtyStates","removeListeners","off","getInstance"],"mappings":";;;;;;;AAsBAA,sCAAO,CACH,SACA,WACA,YACA,oBACA,qBACA,oBACA,gBACA,4BACD,SACCC,EACAC,IACAC,KACAC,aACAC,aACAC,YACAC,SACAC,uBAGQC,uBACc,+BAGdC,WAAa,SAASC,gBACjBA,UAAYA,eAYZC,QAAUV,IAAIW,YAVF,CACb,CACIC,IAAK,aACLC,UAAW,oBAEf,CACID,IAAK,OACLC,UAAW,gBAKdC,iCAOTN,WAAWO,UAAUN,UAAY,EAMjCD,WAAWO,UAAUL,QAAU,EAE/BF,WAAWO,UAAUD,uBAAyB,eAEtCE,QAAUjB,EAAEQ,wBAChBS,QAAQC,GAAG,QAAS,kBACTC,KAAKR,QAAQS,KAAK,SAAST,SAC9BP,aAAaiB,OAAO,CAChBC,KAAMlB,aAAamB,MAAMC,YACzBC,MAAOd,QAAQ,GACfe,KAAM,IACPT,SAASU,KAAK,SAASC,YACjBC,eAAeD,MAAOjB,QAAQ,KACrCmB,KAAKX,QACTW,KAAKX,OACNY,KAAK5B,aAAa6B,YACrBF,KAAKX,QAUXV,WAAWO,UAAUiB,QAAU,SAASC,cAEhCC,OAAS,iBACW,IAAbD,WACPC,OAAS,CAACC,aAAcC,KAAKC,UAAUJ,YAGpC5B,SAASiC,aAAa,mBAAoB,kBAAmBpB,KAAKT,UAAWyB,SAGxF1B,WAAWO,UAAUa,eAAiB,SAASD,MAAOY,UAClDZ,MAAMa,WAENb,MAAMc,kBAAkBF,UAGxBZ,MAAMe,UAAUzB,GAAGb,YAAYuC,OAAQzB,KAAK0B,QAAQf,KAAKX,OAEzDS,MAAMkB,QAAQ3B,KAAKc,WAInBL,MAAMe,UAAUzB,GAAGb,YAAY0C,KAAM5B,KAAK6B,WAAWlB,KAAKX,OAE1DS,MAAMe,UAAUzB,GAAG,SAAU,OAAQC,KAAK8B,eAAenB,KAAKX,YAEzDS,MAAQA,MAEbA,MAAMsB,QAUVzC,WAAWO,UAAUgC,WAAa,SAASG,GACvCA,EAAEC,sBACGxB,MAAMe,UAAUU,KAAK,QAAQC,UAGtC7C,WAAWO,UAAUiC,eAAiB,SAASE,GAE3CA,EAAEC,qBAGEG,SAAWpC,KAAKS,MAAMe,UAAUU,KAAK,QAAQG,YAEjDtD,KAAKuD,KAAK,CAAC,CACPC,WAAY,uCACZC,KAAM,CAACvB,aAAcC,KAAKC,UAAUiB,WACpC5B,KAAM,SAASiC,MACPA,KAAKC,sBACAjC,MAAMkB,QAAQ3B,KAAKc,QAAQsB,gBAE3BO,SAEXhC,KAAKX,MAEPY,KAAM5B,aAAa6B,cAI3BvB,WAAWO,UAAU8C,MAAQ,gBACpBjB,UACLkB,SAASC,SAASC,UAGtBxD,WAAWO,UAAU6B,QAAU,WAC3BtC,kBAAkB2D,+BACbtC,MAAMiB,WAGfpC,WAAWO,UAAUmD,gBAAkB,WACnCnE,EAAEQ,wBAAwB4D,IAAI,UAGuB,CACrDC,YAAa,SAAS3D,kBACX,IAAID,WAAWC"} \ No newline at end of file +{"version":3,"file":"add_purpose.min.js","sources":["../src/add_purpose.js"],"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 * Module to add purposes.\n *\n * @module tool_dataprivacy/add_purpose\n * @copyright 2018 David Monllao\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n 'jquery',\n 'core/str',\n 'core/ajax',\n 'core/notification',\n 'core/modal_save_cancel',\n 'core/modal_events',\n 'core/fragment',\n 'core_form/changechecker',\n], function(\n $,\n Str,\n Ajax,\n Notification,\n ModalSaveCancel,\n ModalEvents,\n Fragment,\n FormChangeChecker\n) {\n\n var SELECTORS = {\n PURPOSE_LINK: '[data-add-element=\"purpose\"]',\n };\n\n var AddPurpose = function(contextId) {\n this.contextId = contextId;\n\n var stringKeys = [\n {\n key: 'addpurpose',\n component: 'tool_dataprivacy'\n },\n {\n key: 'save',\n component: 'admin'\n }\n ];\n this.strings = Str.get_strings(stringKeys);\n\n this.registerEventListeners();\n };\n\n /**\n * @var {int} contextId\n * @private\n */\n AddPurpose.prototype.contextId = 0;\n\n /**\n * @var {Promise}\n * @private\n */\n AddPurpose.prototype.strings = 0;\n\n AddPurpose.prototype.registerEventListeners = function() {\n\n var trigger = $(SELECTORS.PURPOSE_LINK);\n trigger.on('click', function() {\n this.strings.then(function(strings) {\n return Promise.all([\n ModalSaveCancel.create({\n title: strings[0],\n body: '',\n }),\n strings[1],\n ]).then(function([modal, string]) {\n this.setupFormModal(modal, string);\n }.bind(this));\n }.bind(this))\n .catch(Notification.exception);\n }.bind(this));\n\n };\n\n /**\n * @method getBody\n * @param {Object} formdata\n * @private\n * @return {Promise}\n */\n AddPurpose.prototype.getBody = function(formdata) {\n\n var params = null;\n if (typeof formdata !== \"undefined\") {\n params = {jsonformdata: JSON.stringify(formdata)};\n }\n // Get the content of the modal.\n return Fragment.loadFragment('tool_dataprivacy', 'addpurpose_form', this.contextId, params);\n };\n\n AddPurpose.prototype.setupFormModal = function(modal, saveText) {\n modal.setLarge();\n\n modal.setSaveButtonText(saveText);\n\n // We want to reset the form every time it is opened.\n modal.getRoot().on(ModalEvents.hidden, this.destroy.bind(this));\n\n modal.setBody(this.getBody());\n\n // We catch the modal save event, and use it to submit the form inside the modal.\n // Triggering a form submission will give JS validation scripts a chance to check for errors.\n modal.getRoot().on(ModalEvents.save, this.submitForm.bind(this));\n // We also catch the form submit event and use it to submit the form with ajax.\n modal.getRoot().on('submit', 'form', this.submitFormAjax.bind(this));\n\n this.modal = modal;\n\n modal.show();\n };\n\n /**\n * This triggers a form submission, so that any mform elements can do final tricks before the form submission is processed.\n *\n * @method submitForm\n * @param {Event} e Form submission event.\n * @private\n */\n AddPurpose.prototype.submitForm = function(e) {\n e.preventDefault();\n this.modal.getRoot().find('form').submit();\n };\n\n AddPurpose.prototype.submitFormAjax = function(e) {\n // We don't want to do a real form submission.\n e.preventDefault();\n\n // Convert all the form elements values to a serialised string.\n var formData = this.modal.getRoot().find('form').serialize();\n\n Ajax.call([{\n methodname: 'tool_dataprivacy_create_purpose_form',\n args: {jsonformdata: JSON.stringify(formData)},\n done: function(data) {\n if (data.validationerrors) {\n this.modal.setBody(this.getBody(formData));\n } else {\n this.close();\n }\n }.bind(this),\n\n fail: Notification.exception\n }]);\n };\n\n AddPurpose.prototype.close = function() {\n this.destroy();\n document.location.reload();\n };\n\n AddPurpose.prototype.destroy = function() {\n FormChangeChecker.resetAllFormDirtyStates();\n this.modal.destroy();\n };\n\n AddPurpose.prototype.removeListeners = function() {\n $(SELECTORS.PURPOSE_LINK).off('click');\n };\n\n return /** @alias module:tool_dataprivacy/add_purpose */ {\n getInstance: function(contextId) {\n return new AddPurpose(contextId);\n }\n };\n }\n);\n"],"names":["define","$","Str","Ajax","Notification","ModalSaveCancel","ModalEvents","Fragment","FormChangeChecker","SELECTORS","AddPurpose","contextId","strings","get_strings","key","component","registerEventListeners","prototype","on","then","Promise","all","create","title","body","modal","string","setupFormModal","bind","this","catch","exception","getBody","formdata","params","jsonformdata","JSON","stringify","loadFragment","saveText","setLarge","setSaveButtonText","getRoot","hidden","destroy","setBody","save","submitForm","submitFormAjax","show","e","preventDefault","find","submit","formData","serialize","call","methodname","args","done","data","validationerrors","close","fail","document","location","reload","resetAllFormDirtyStates","removeListeners","off","getInstance"],"mappings":";;;;;;;AAsBAA,sCAAO,CACH,SACA,WACA,YACA,oBACA,yBACA,oBACA,gBACA,4BACD,SACCC,EACAC,IACAC,KACAC,aACAC,gBACAC,YACAC,SACAC,uBAGQC,uBACc,+BAGdC,WAAa,SAASC,gBACjBA,UAAYA,eAYZC,QAAUV,IAAIW,YAVF,CACb,CACIC,IAAK,aACLC,UAAW,oBAEf,CACID,IAAK,OACLC,UAAW,gBAKdC,iCAOTN,WAAWO,UAAUN,UAAY,EAMjCD,WAAWO,UAAUL,QAAU,EAE/BF,WAAWO,UAAUD,uBAAyB,WAE5Bf,EAAEQ,wBACRS,GAAG,QAAS,gBACXN,QAAQO,KAAK,SAASP,gBAChBQ,QAAQC,IAAI,CACfhB,gBAAgBiB,OAAO,CACnBC,MAAOX,QAAQ,GACfY,KAAM,KAEVZ,QAAQ,KACTO,KAAK,mBAAUM,MAAOC,kBAChBC,eAAeF,MAAOC,SAC7BE,KAAKC,QACTD,KAAKC,OACNC,MAAM1B,aAAa2B,YACtBH,KAAKC,QAUXnB,WAAWO,UAAUe,QAAU,SAASC,cAEhCC,OAAS,iBACW,IAAbD,WACPC,OAAS,CAACC,aAAcC,KAAKC,UAAUJ,YAGpC1B,SAAS+B,aAAa,mBAAoB,kBAAmBT,KAAKlB,UAAWuB,SAGxFxB,WAAWO,UAAUU,eAAiB,SAASF,MAAOc,UAClDd,MAAMe,WAENf,MAAMgB,kBAAkBF,UAGxBd,MAAMiB,UAAUxB,GAAGZ,YAAYqC,OAAQd,KAAKe,QAAQhB,KAAKC,OAEzDJ,MAAMoB,QAAQhB,KAAKG,WAInBP,MAAMiB,UAAUxB,GAAGZ,YAAYwC,KAAMjB,KAAKkB,WAAWnB,KAAKC,OAE1DJ,MAAMiB,UAAUxB,GAAG,SAAU,OAAQW,KAAKmB,eAAepB,KAAKC,YAEzDJ,MAAQA,MAEbA,MAAMwB,QAUVvC,WAAWO,UAAU8B,WAAa,SAASG,GACvCA,EAAEC,sBACG1B,MAAMiB,UAAUU,KAAK,QAAQC,UAGtC3C,WAAWO,UAAU+B,eAAiB,SAASE,GAE3CA,EAAEC,qBAGEG,SAAWzB,KAAKJ,MAAMiB,UAAUU,KAAK,QAAQG,YAEjDpD,KAAKqD,KAAK,CAAC,CACPC,WAAY,uCACZC,KAAM,CAACvB,aAAcC,KAAKC,UAAUiB,WACpCK,KAAM,SAASC,MACPA,KAAKC,sBACApC,MAAMoB,QAAQhB,KAAKG,QAAQsB,gBAE3BQ,SAEXlC,KAAKC,MAEPkC,KAAM3D,aAAa2B,cAI3BrB,WAAWO,UAAU6C,MAAQ,gBACpBlB,UACLoB,SAASC,SAASC,UAGtBxD,WAAWO,UAAU2B,QAAU,WAC3BpC,kBAAkB2D,+BACb1C,MAAMmB,WAGflC,WAAWO,UAAUmD,gBAAkB,WACnCnE,EAAEQ,wBAAwB4D,IAAI,UAGuB,CACrDC,YAAa,SAAS3D,kBACX,IAAID,WAAWC"} \ No newline at end of file diff --git a/admin/tool/dataprivacy/amd/build/categoriesactions.min.js b/admin/tool/dataprivacy/amd/build/categoriesactions.min.js index 4fe615bab59..f469e21157a 100644 --- a/admin/tool/dataprivacy/amd/build/categoriesactions.min.js +++ b/admin/tool/dataprivacy/amd/build/categoriesactions.min.js @@ -1,10 +1,10 @@ +define("tool_dataprivacy/categoriesactions",["exports","core/ajax","core/notification","core/str","core/modal_events","core/modal_save_cancel"],(function(_exports,Ajax,Notification,Str,_modal_events,_modal_save_cancel){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireWildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}return newObj.default=obj,cache&&cache.set(obj,newObj),newObj} /** - * AMD module for categories actions. - * - * @module tool_dataprivacy/categoriesactions - * @copyright 2018 David Monllao - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -define("tool_dataprivacy/categoriesactions",["jquery","core/ajax","core/notification","core/str","core/modal_factory","core/modal_events"],(function($,Ajax,Notification,Str,ModalFactory,ModalEvents){var ACTIONS_DELETE='[data-action="deletecategory"]',CategoriesActions=function(){this.registerEvents()};return CategoriesActions.prototype.registerEvents=function(){$(ACTIONS_DELETE).click((function(e){e.preventDefault();var id=$(this).data("id"),stringkeys=[{key:"deletecategory",component:"tool_dataprivacy"},{key:"deletecategorytext",component:"tool_dataprivacy",param:$(this).data("name")},{key:"delete"}];Str.get_strings(stringkeys).then((function(langStrings){var title=langStrings[0],confirmMessage=langStrings[1],buttonText=langStrings[2];return ModalFactory.create({title:title,body:confirmMessage,type:ModalFactory.types.SAVE_CANCEL}).then((function(modal){return modal.setSaveButtonText(buttonText),modal.getRoot().on(ModalEvents.save,(function(){var request={methodname:"tool_dataprivacy_delete_category",args:{id:id}};Ajax.call([request])[0].done((function(data){data.result?$('tr[data-categoryid="'+id+'"]').remove():Notification.addNotification({message:data.warnings[0].message,type:"error"})})).fail(Notification.exception)})),modal.getRoot().on(ModalEvents.hidden,(function(){modal.destroy()})),modal}))})).done((function(modal){modal.show()})).fail(Notification.exception)}))},{init:function(){return new CategoriesActions}}})); + * AMD module for categories actions. + * + * @module tool_dataprivacy/categoriesactions + * @copyright 2018 David Monllao + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,Ajax=_interopRequireWildcard(Ajax),Notification=_interopRequireWildcard(Notification),Str=_interopRequireWildcard(Str),_modal_events=_interopRequireDefault(_modal_events),_modal_save_cancel=_interopRequireDefault(_modal_save_cancel);const ACTIONS_DELETE='[data-action="deletecategory"]';return _exports.default=class{static init(){return new this}constructor(){this.registerEvents()}deleteCategory(id){return Ajax.call([{methodname:"tool_dataprivacy_delete_category",args:{id:id}}])[0]}handleCategoryRemoval(id){this.deleteCategory(id).then((data=>{var _document$querySelect;data.result?null===(_document$querySelect=document.querySelector('tr[data-categoryid="'.concat(id,'"]')))||void 0===_document$querySelect||_document$querySelect.remove():Notification.addNotification({message:data.warnings[0].message,type:"error"})})).catch(Notification.exception)}registerEvents(){document.addEventListener("click",(e=>{const target=e.target.closest(ACTIONS_DELETE);target&&(e.preventDefault(),this.confirmCategoryRemoval(target))}))}confirmCategoryRemoval(target){const id=target.dataset.id;var stringkeys=[{key:"deletecategory",component:"tool_dataprivacy"},{key:"deletecategorytext",component:"tool_dataprivacy",param:target.dataset.name},{key:"delete"}];Str.get_strings(stringkeys).then((_ref=>{let[title,body,save]=_ref;return _modal_save_cancel.default.create({title:title,body:body,buttons:{save:save},show:!0,removeOnClose:!0})})).then((modal=>(modal.getRoot().on(_modal_events.default.save,(()=>this.handleCategoryRemoval(id))),modal))).catch(Notification.exception)}},_exports.default})); //# sourceMappingURL=categoriesactions.min.js.map \ No newline at end of file diff --git a/admin/tool/dataprivacy/amd/build/categoriesactions.min.js.map b/admin/tool/dataprivacy/amd/build/categoriesactions.min.js.map index 683666ec3bb..d04b5dc865c 100644 --- a/admin/tool/dataprivacy/amd/build/categoriesactions.min.js.map +++ b/admin/tool/dataprivacy/amd/build/categoriesactions.min.js.map @@ -1 +1 @@ -{"version":3,"file":"categoriesactions.min.js","sources":["../src/categoriesactions.js"],"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 * AMD module for categories actions.\n *\n * @module tool_dataprivacy/categoriesactions\n * @copyright 2018 David Monllao\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n 'jquery',\n 'core/ajax',\n 'core/notification',\n 'core/str',\n 'core/modal_factory',\n 'core/modal_events'],\nfunction($, Ajax, Notification, Str, ModalFactory, ModalEvents) {\n\n /**\n * List of action selectors.\n *\n * @type {{DELETE: string}}\n */\n var ACTIONS = {\n DELETE: '[data-action=\"deletecategory\"]',\n };\n\n /**\n * CategoriesActions class.\n */\n var CategoriesActions = function() {\n this.registerEvents();\n };\n\n /**\n * Register event listeners.\n */\n CategoriesActions.prototype.registerEvents = function() {\n $(ACTIONS.DELETE).click(function(e) {\n e.preventDefault();\n\n var id = $(this).data('id');\n var categoryname = $(this).data('name');\n var stringkeys = [\n {\n key: 'deletecategory',\n component: 'tool_dataprivacy'\n },\n {\n key: 'deletecategorytext',\n component: 'tool_dataprivacy',\n param: categoryname\n },\n {\n key: 'delete'\n }\n ];\n\n Str.get_strings(stringkeys).then(function(langStrings) {\n var title = langStrings[0];\n var confirmMessage = langStrings[1];\n var buttonText = langStrings[2];\n return ModalFactory.create({\n title: title,\n body: confirmMessage,\n type: ModalFactory.types.SAVE_CANCEL\n }).then(function(modal) {\n modal.setSaveButtonText(buttonText);\n\n // Handle save event.\n modal.getRoot().on(ModalEvents.save, function() {\n\n var request = {\n methodname: 'tool_dataprivacy_delete_category',\n args: {'id': id}\n };\n\n Ajax.call([request])[0].done(function(data) {\n if (data.result) {\n $('tr[data-categoryid=\"' + id + '\"]').remove();\n } else {\n Notification.addNotification({\n message: data.warnings[0].message,\n type: 'error'\n });\n }\n }).fail(Notification.exception);\n });\n\n // Handle hidden event.\n modal.getRoot().on(ModalEvents.hidden, function() {\n // Destroy when hidden.\n modal.destroy();\n });\n\n return modal;\n });\n }).done(function(modal) {\n modal.show();\n\n }).fail(Notification.exception);\n });\n };\n\n return /** @alias module:tool_dataprivacy/categoriesactions */ {\n // Public variables and functions.\n\n /**\n * Initialise the module.\n *\n * @method init\n * @return {CategoriesActions}\n */\n 'init': function() {\n return new CategoriesActions();\n }\n };\n});\n"],"names":["define","$","Ajax","Notification","Str","ModalFactory","ModalEvents","ACTIONS","CategoriesActions","registerEvents","prototype","click","e","preventDefault","id","this","data","stringkeys","key","component","param","get_strings","then","langStrings","title","confirmMessage","buttonText","create","body","type","types","SAVE_CANCEL","modal","setSaveButtonText","getRoot","on","save","request","methodname","args","call","done","result","remove","addNotification","message","warnings","fail","exception","hidden","destroy","show"],"mappings":";;;;;;;AAsBAA,4CAAO,CACH,SACA,YACA,oBACA,WACA,qBACA,sBACJ,SAASC,EAAGC,KAAMC,aAAcC,IAAKC,aAAcC,iBAO3CC,eACQ,iCAMRC,kBAAoB,gBACfC,yBAMTD,kBAAkBE,UAAUD,eAAiB,WACzCR,EAAEM,gBAAgBI,OAAM,SAASC,GAC7BA,EAAEC,qBAEEC,GAAKb,EAAEc,MAAMC,KAAK,MAElBC,WAAa,CACb,CACIC,IAAK,iBACLC,UAAW,oBAEf,CACID,IAAK,qBACLC,UAAW,mBACXC,MATWnB,EAAEc,MAAMC,KAAK,SAW5B,CACIE,IAAK,WAIbd,IAAIiB,YAAYJ,YAAYK,MAAK,SAASC,iBAClCC,MAAQD,YAAY,GACpBE,eAAiBF,YAAY,GAC7BG,WAAaH,YAAY,UACtBlB,aAAasB,OAAO,CACvBH,MAAOA,MACPI,KAAMH,eACNI,KAAMxB,aAAayB,MAAMC,cAC1BT,MAAK,SAASU,cACbA,MAAMC,kBAAkBP,YAGxBM,MAAME,UAAUC,GAAG7B,YAAY8B,MAAM,eAE7BC,QAAU,CACVC,WAAY,mCACZC,KAAM,IAAOzB,KAGjBZ,KAAKsC,KAAK,CAACH,UAAU,GAAGI,MAAK,SAASzB,MAC9BA,KAAK0B,OACLzC,EAAE,uBAAyBa,GAAK,MAAM6B,SAEtCxC,aAAayC,gBAAgB,CACzBC,QAAS7B,KAAK8B,SAAS,GAAGD,QAC1BhB,KAAM,aAGfkB,KAAK5C,aAAa6C,cAIzBhB,MAAME,UAAUC,GAAG7B,YAAY2C,QAAQ,WAEnCjB,MAAMkB,aAGHlB,YAEZS,MAAK,SAAST,OACbA,MAAMmB,UAEPJ,KAAK5C,aAAa6C,eAIkC,MASnD,kBACG,IAAIxC"} \ No newline at end of file +{"version":3,"file":"categoriesactions.min.js","sources":["../src/categoriesactions.js"],"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 * AMD module for categories actions.\n *\n * @module tool_dataprivacy/categoriesactions\n * @copyright 2018 David Monllao\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport * as Ajax from 'core/ajax';\nimport * as Notification from 'core/notification';\nimport * as Str from 'core/str';\nimport ModalEvents from 'core/modal_events';\nimport ModalSaveCancel from 'core/modal_save_cancel';\n\n/**\n * List of action selectors.\n *\n * @type {{DELETE: string}}\n */\nconst ACTIONS = {\n DELETE: '[data-action=\"deletecategory\"]',\n};\n\nexport default class CategoriesActions {\n\n static init() {\n return new this();\n }\n\n /**\n * CategoriesActions class.\n */\n constructor() {\n this.registerEvents();\n }\n\n deleteCategory(id) {\n return Ajax.call([{\n methodname: 'tool_dataprivacy_delete_category',\n args: {id}\n }])[0];\n }\n\n handleCategoryRemoval(id) {\n this.deleteCategory(id)\n .then((data) => {\n if (data.result) {\n document.querySelector(`tr[data-categoryid=\"${id}\"]`)?.remove();\n } else {\n Notification.addNotification({\n message: data.warnings[0].message,\n type: 'error'\n });\n }\n\n return;\n })\n .catch(Notification.exception);\n\n }\n\n /**\n * Register event listeners.\n */\n registerEvents() {\n document.addEventListener('click', (e) => {\n const target = e.target.closest(ACTIONS.DELETE);\n if (!target) {\n return;\n }\n\n e.preventDefault();\n\n this.confirmCategoryRemoval(target);\n });\n }\n\n confirmCategoryRemoval(target) {\n const id = target.dataset.id;\n var categoryname = target.dataset.name;\n var stringkeys = [\n {\n key: 'deletecategory',\n component: 'tool_dataprivacy'\n },\n {\n key: 'deletecategorytext',\n component: 'tool_dataprivacy',\n param: categoryname\n },\n {\n key: 'delete'\n }\n ];\n\n Str.get_strings(stringkeys).then(([\n title,\n body,\n save,\n ]) => ModalSaveCancel.create({\n title,\n body,\n buttons: {\n save,\n },\n show: true,\n removeOnClose: true,\n }))\n .then((modal) => {\n // Handle save event.\n modal.getRoot().on(ModalEvents.save, () => this.handleCategoryRemoval(id));\n\n return modal;\n })\n .catch(Notification.exception);\n }\n}\n"],"names":["ACTIONS","this","constructor","registerEvents","deleteCategory","id","Ajax","call","methodname","args","handleCategoryRemoval","then","data","result","document","querySelector","remove","Notification","addNotification","message","warnings","type","catch","exception","addEventListener","e","target","closest","preventDefault","confirmCategoryRemoval","dataset","stringkeys","key","component","param","name","Str","get_strings","_ref","title","body","save","ModalSaveCancel","create","buttons","show","removeOnClose","modal","getRoot","on","ModalEvents"],"mappings":";;;;;;;oUAiCMA,eACM,oFAMG,IAAIC,KAMfC,mBACSC,iBAGTC,eAAeC,WACJC,KAAKC,KAAK,CAAC,CACdC,WAAY,mCACZC,KAAM,CAACJ,GAAAA,OACP,GAGRK,sBAAsBL,SACbD,eAAeC,IACfM,MAAMC,iCACCA,KAAKC,qCACLC,SAASC,4CAAqCV,kEAASW,SAEvDC,aAAaC,gBAAgB,CACzBC,QAASP,KAAKQ,SAAS,GAAGD,QAC1BE,KAAM,aAMjBC,MAAML,aAAaM,WAO5BpB,iBACIW,SAASU,iBAAiB,SAAUC,UAC1BC,OAASD,EAAEC,OAAOC,QAAQ3B,gBAC3B0B,SAILD,EAAEG,sBAEGC,uBAAuBH,YAIpCG,uBAAuBH,cACbrB,GAAKqB,OAAOI,QAAQzB,OAEtB0B,WAAa,CACb,CACIC,IAAK,iBACLC,UAAW,oBAEf,CACID,IAAK,qBACLC,UAAW,mBACXC,MATWR,OAAOI,QAAQK,MAW9B,CACIH,IAAK,WAIbI,IAAIC,YAAYN,YAAYpB,MAAK2B,WAC7BC,MACAC,KACAC,kBACEC,2BAAgBC,OAAO,CACzBJ,MAAAA,MACAC,KAAAA,KACAI,QAAS,CACLH,KAAAA,MAEJI,MAAM,EACNC,eAAe,OAElBnC,MAAMoC,QAEHA,MAAMC,UAAUC,GAAGC,sBAAYT,MAAM,IAAMxC,KAAKS,sBAAsBL,MAE/D0C,SAEVzB,MAAML,aAAaM"} \ No newline at end of file diff --git a/admin/tool/dataprivacy/amd/build/data_deletion.min.js b/admin/tool/dataprivacy/amd/build/data_deletion.min.js index 212a020c29a..ca0eb0f8619 100644 --- a/admin/tool/dataprivacy/amd/build/data_deletion.min.js +++ b/admin/tool/dataprivacy/amd/build/data_deletion.min.js @@ -5,6 +5,6 @@ * @copyright 2018 Jun Pataleta * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -define("tool_dataprivacy/data_deletion",["jquery","core/ajax","core/notification","core/str","core/modal_factory","core/modal_events"],(function($,Ajax,Notification,Str,ModalFactory,ModalEvents){var ACTIONS_MARK_FOR_DELETION='[data-action="markfordeletion"]',ACTIONS_SELECT_ALL='[data-action="selectall"]',SELECTORS_SELECTCONTEXT=".selectcontext",DataDeletionActions=function(){this.registerEvents()};return DataDeletionActions.prototype.registerEvents=function(){$(ACTIONS_MARK_FOR_DELETION).click((function(e){e.preventDefault();var ids,keys,wsfunction,modalTitle,selectedIds=[];$(SELECTORS_SELECTCONTEXT).each((function(){var checkbox=$(this);checkbox.is(":checked")&&selectedIds.push(checkbox.val())})),ids=selectedIds,keys=[{key:"confirm",component:"moodle"},{key:"confirmcontextdeletion",component:"tool_dataprivacy"}],wsfunction="tool_dataprivacy_confirm_contexts_for_deletion",modalTitle="",Str.get_strings(keys).then((function(langStrings){modalTitle=langStrings[0];var confirmMessage=langStrings[1];return ModalFactory.create({title:modalTitle,body:confirmMessage,type:ModalFactory.types.SAVE_CANCEL})})).then((function(modal){return modal.setSaveButtonText(modalTitle),modal.getRoot().on(ModalEvents.save,(function(){var request={methodname:wsfunction,args:{ids:ids}};Ajax.call([request])[0].done((function(data){data.result?window.location.reload():Notification.addNotification({message:data.warnings[0].message,type:"error"})})).fail(Notification.exception)})),modal.getRoot().on(ModalEvents.hidden,(function(){modal.destroy()})),modal})).done((function(modal){modal.show()})).fail(Notification.exception)})),$(ACTIONS_SELECT_ALL).change((function(e){e.preventDefault(),$(this).is(":checked")?$(SELECTORS_SELECTCONTEXT).attr("checked","checked"):$(SELECTORS_SELECTCONTEXT).removeAttr("checked")}))},DataDeletionActions})); +define("tool_dataprivacy/data_deletion",["jquery","core/ajax","core/notification","core/str","core/modal_save_cancel","core/modal_events"],(function($,Ajax,Notification,Str,ModalSaveCancel,ModalEvents){var ACTIONS_MARK_FOR_DELETION='[data-action="markfordeletion"]',ACTIONS_SELECT_ALL='[data-action="selectall"]',SELECTORS_SELECTCONTEXT=".selectcontext",DataDeletionActions=function(){this.registerEvents()};return DataDeletionActions.prototype.registerEvents=function(){$(ACTIONS_MARK_FOR_DELETION).click((function(e){e.preventDefault();var ids,keys,wsfunction,modalTitle,selectedIds=[];$(SELECTORS_SELECTCONTEXT).each((function(){var checkbox=$(this);checkbox.is(":checked")&&selectedIds.push(checkbox.val())})),ids=selectedIds,keys=[{key:"confirm",component:"moodle"},{key:"confirmcontextdeletion",component:"tool_dataprivacy"}],wsfunction="tool_dataprivacy_confirm_contexts_for_deletion",modalTitle="",Str.get_strings(keys).then((function(langStrings){modalTitle=langStrings[0];var confirmMessage=langStrings[1];return ModalSaveCancel.create({title:modalTitle,body:confirmMessage})})).then((function(modal){return modal.setSaveButtonText(modalTitle),modal.getRoot().on(ModalEvents.save,(function(){var request={methodname:wsfunction,args:{ids:ids}};Ajax.call([request])[0].done((function(data){data.result?window.location.reload():Notification.addNotification({message:data.warnings[0].message,type:"error"})})).fail(Notification.exception)})),modal.getRoot().on(ModalEvents.hidden,(function(){modal.destroy()})),modal})).done((function(modal){modal.show()})).fail(Notification.exception)})),$(ACTIONS_SELECT_ALL).change((function(e){e.preventDefault(),$(this).is(":checked")?$(SELECTORS_SELECTCONTEXT).attr("checked","checked"):$(SELECTORS_SELECTCONTEXT).removeAttr("checked")}))},DataDeletionActions})); //# sourceMappingURL=data_deletion.min.js.map \ No newline at end of file diff --git a/admin/tool/dataprivacy/amd/build/data_deletion.min.js.map b/admin/tool/dataprivacy/amd/build/data_deletion.min.js.map index 79fec21d7e6..f2300cf3c6b 100644 --- a/admin/tool/dataprivacy/amd/build/data_deletion.min.js.map +++ b/admin/tool/dataprivacy/amd/build/data_deletion.min.js.map @@ -1 +1 @@ -{"version":3,"file":"data_deletion.min.js","sources":["../src/data_deletion.js"],"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 * Request actions.\n *\n * @module tool_dataprivacy/data_deletion\n * @copyright 2018 Jun Pataleta\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n 'jquery',\n 'core/ajax',\n 'core/notification',\n 'core/str',\n 'core/modal_factory',\n 'core/modal_events'],\nfunction($, Ajax, Notification, Str, ModalFactory, ModalEvents) {\n\n /**\n * List of action selectors.\n *\n * @type {{MARK_FOR_DELETION: string}}\n * @type {{SELECT_ALL: string}}\n */\n var ACTIONS = {\n MARK_FOR_DELETION: '[data-action=\"markfordeletion\"]',\n SELECT_ALL: '[data-action=\"selectall\"]',\n };\n\n /**\n * List of selectors.\n *\n * @type {{SELECTCONTEXT: string}}\n */\n var SELECTORS = {\n SELECTCONTEXT: '.selectcontext',\n };\n\n /**\n * DataDeletionActions class.\n */\n var DataDeletionActions = function() {\n this.registerEvents();\n };\n\n /**\n * Register event listeners.\n */\n DataDeletionActions.prototype.registerEvents = function() {\n $(ACTIONS.MARK_FOR_DELETION).click(function(e) {\n e.preventDefault();\n\n var selectedIds = [];\n $(SELECTORS.SELECTCONTEXT).each(function() {\n var checkbox = $(this);\n if (checkbox.is(':checked')) {\n selectedIds.push(checkbox.val());\n }\n });\n showConfirmation(selectedIds);\n });\n\n $(ACTIONS.SELECT_ALL).change(function(e) {\n e.preventDefault();\n\n var selectallnone = $(this);\n if (selectallnone.is(':checked')) {\n $(SELECTORS.SELECTCONTEXT).attr('checked', 'checked');\n } else {\n $(SELECTORS.SELECTCONTEXT).removeAttr('checked');\n }\n });\n };\n\n /**\n * Show the confirmation dialogue.\n *\n * @param {Array} ids The array of expired context record IDs.\n */\n function showConfirmation(ids) {\n var keys = [\n {\n key: 'confirm',\n component: 'moodle'\n },\n {\n key: 'confirmcontextdeletion',\n component: 'tool_dataprivacy'\n }\n ];\n var wsfunction = 'tool_dataprivacy_confirm_contexts_for_deletion';\n\n var modalTitle = '';\n Str.get_strings(keys).then(function(langStrings) {\n modalTitle = langStrings[0];\n var confirmMessage = langStrings[1];\n return ModalFactory.create({\n title: modalTitle,\n body: confirmMessage,\n type: ModalFactory.types.SAVE_CANCEL\n });\n }).then(function(modal) {\n modal.setSaveButtonText(modalTitle);\n\n // Handle save event.\n modal.getRoot().on(ModalEvents.save, function() {\n // Confirm the request.\n var params = {\n 'ids': ids\n };\n\n var request = {\n methodname: wsfunction,\n args: params\n };\n\n Ajax.call([request])[0].done(function(data) {\n if (data.result) {\n window.location.reload();\n } else {\n Notification.addNotification({\n message: data.warnings[0].message,\n type: 'error'\n });\n }\n }).fail(Notification.exception);\n });\n\n // Handle hidden event.\n modal.getRoot().on(ModalEvents.hidden, function() {\n // Destroy when hidden.\n modal.destroy();\n });\n\n return modal;\n }).done(function(modal) {\n modal.show();\n }).fail(Notification.exception);\n }\n\n return DataDeletionActions;\n});\n"],"names":["define","$","Ajax","Notification","Str","ModalFactory","ModalEvents","ACTIONS","SELECTORS","DataDeletionActions","registerEvents","prototype","click","e","preventDefault","ids","keys","wsfunction","modalTitle","selectedIds","each","checkbox","this","is","push","val","key","component","get_strings","then","langStrings","confirmMessage","create","title","body","type","types","SAVE_CANCEL","modal","setSaveButtonText","getRoot","on","save","request","methodname","args","call","done","data","result","window","location","reload","addNotification","message","warnings","fail","exception","hidden","destroy","show","change","attr","removeAttr"],"mappings":";;;;;;;AAsBAA,wCAAO,CACH,SACA,YACA,oBACA,WACA,qBACA,sBACJ,SAASC,EAAGC,KAAMC,aAAcC,IAAKC,aAAcC,iBAQ3CC,0BACmB,kCADnBA,mBAEY,4BAQZC,wBACe,iBAMfC,oBAAsB,gBACjBC,yBAMTD,oBAAoBE,UAAUD,eAAiB,WAC3CT,EAAEM,2BAA2BK,OAAM,SAASC,GACxCA,EAAEC,qBA6BgBC,IAClBC,KAUAC,WAEAC,WAxCIC,YAAc,GAClBlB,EAAEO,yBAAyBY,MAAK,eACxBC,SAAWpB,EAAEqB,MACbD,SAASE,GAAG,aACZJ,YAAYK,KAAKH,SAASI,UAuBhBV,IApBDI,YAqBjBH,KAAO,CACP,CACIU,IAAK,UACLC,UAAW,UAEf,CACID,IAAK,yBACLC,UAAW,qBAGfV,WAAa,iDAEbC,WAAa,GACjBd,IAAIwB,YAAYZ,MAAMa,MAAK,SAASC,aAChCZ,WAAaY,YAAY,OACrBC,eAAiBD,YAAY,UAC1BzB,aAAa2B,OAAO,CACvBC,MAAOf,WACPgB,KAAMH,eACNI,KAAM9B,aAAa+B,MAAMC,iBAE9BR,MAAK,SAASS,cACbA,MAAMC,kBAAkBrB,YAGxBoB,MAAME,UAAUC,GAAGnC,YAAYoC,MAAM,eAM7BC,QAAU,CACVC,WAAY3B,WACZ4B,KANS,KACF9B,MAQXb,KAAK4C,KAAK,CAACH,UAAU,GAAGI,MAAK,SAASC,MAC9BA,KAAKC,OACLC,OAAOC,SAASC,SAEhBjD,aAAakD,gBAAgB,CACzBC,QAASN,KAAKO,SAAS,GAAGD,QAC1BnB,KAAM,aAGfqB,KAAKrD,aAAasD,cAIzBnB,MAAME,UAAUC,GAAGnC,YAAYoD,QAAQ,WAEnCpB,MAAMqB,aAGHrB,SACRS,MAAK,SAAST,OACbA,MAAMsB,UACPJ,KAAKrD,aAAasD,cA3ErBxD,EAAEM,oBAAoBsD,QAAO,SAAShD,GAClCA,EAAEC,iBAEkBb,EAAEqB,MACJC,GAAG,YACjBtB,EAAEO,yBAAyBsD,KAAK,UAAW,WAE3C7D,EAAEO,yBAAyBuD,WAAW,eAuE3CtD"} \ No newline at end of file +{"version":3,"file":"data_deletion.min.js","sources":["../src/data_deletion.js"],"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 * Request actions.\n *\n * @module tool_dataprivacy/data_deletion\n * @copyright 2018 Jun Pataleta\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n 'jquery',\n 'core/ajax',\n 'core/notification',\n 'core/str',\n 'core/modal_save_cancel',\n 'core/modal_events'],\nfunction($, Ajax, Notification, Str, ModalSaveCancel, ModalEvents) {\n\n /**\n * List of action selectors.\n *\n * @type {{MARK_FOR_DELETION: string}}\n * @type {{SELECT_ALL: string}}\n */\n var ACTIONS = {\n MARK_FOR_DELETION: '[data-action=\"markfordeletion\"]',\n SELECT_ALL: '[data-action=\"selectall\"]',\n };\n\n /**\n * List of selectors.\n *\n * @type {{SELECTCONTEXT: string}}\n */\n var SELECTORS = {\n SELECTCONTEXT: '.selectcontext',\n };\n\n /**\n * DataDeletionActions class.\n */\n var DataDeletionActions = function() {\n this.registerEvents();\n };\n\n /**\n * Register event listeners.\n */\n DataDeletionActions.prototype.registerEvents = function() {\n $(ACTIONS.MARK_FOR_DELETION).click(function(e) {\n e.preventDefault();\n\n var selectedIds = [];\n $(SELECTORS.SELECTCONTEXT).each(function() {\n var checkbox = $(this);\n if (checkbox.is(':checked')) {\n selectedIds.push(checkbox.val());\n }\n });\n showConfirmation(selectedIds);\n });\n\n $(ACTIONS.SELECT_ALL).change(function(e) {\n e.preventDefault();\n\n var selectallnone = $(this);\n if (selectallnone.is(':checked')) {\n $(SELECTORS.SELECTCONTEXT).attr('checked', 'checked');\n } else {\n $(SELECTORS.SELECTCONTEXT).removeAttr('checked');\n }\n });\n };\n\n /**\n * Show the confirmation dialogue.\n *\n * @param {Array} ids The array of expired context record IDs.\n */\n function showConfirmation(ids) {\n var keys = [\n {\n key: 'confirm',\n component: 'moodle'\n },\n {\n key: 'confirmcontextdeletion',\n component: 'tool_dataprivacy'\n }\n ];\n var wsfunction = 'tool_dataprivacy_confirm_contexts_for_deletion';\n\n var modalTitle = '';\n Str.get_strings(keys).then(function(langStrings) {\n modalTitle = langStrings[0];\n var confirmMessage = langStrings[1];\n return ModalSaveCancel.create({\n title: modalTitle,\n body: confirmMessage,\n });\n }).then(function(modal) {\n modal.setSaveButtonText(modalTitle);\n\n // Handle save event.\n modal.getRoot().on(ModalEvents.save, function() {\n // Confirm the request.\n var params = {\n 'ids': ids\n };\n\n var request = {\n methodname: wsfunction,\n args: params\n };\n\n Ajax.call([request])[0].done(function(data) {\n if (data.result) {\n window.location.reload();\n } else {\n Notification.addNotification({\n message: data.warnings[0].message,\n type: 'error'\n });\n }\n }).fail(Notification.exception);\n });\n\n // Handle hidden event.\n modal.getRoot().on(ModalEvents.hidden, function() {\n // Destroy when hidden.\n modal.destroy();\n });\n\n return modal;\n }).done(function(modal) {\n modal.show();\n }).fail(Notification.exception);\n }\n\n return DataDeletionActions;\n});\n"],"names":["define","$","Ajax","Notification","Str","ModalSaveCancel","ModalEvents","ACTIONS","SELECTORS","DataDeletionActions","registerEvents","prototype","click","e","preventDefault","ids","keys","wsfunction","modalTitle","selectedIds","each","checkbox","this","is","push","val","key","component","get_strings","then","langStrings","confirmMessage","create","title","body","modal","setSaveButtonText","getRoot","on","save","request","methodname","args","call","done","data","result","window","location","reload","addNotification","message","warnings","type","fail","exception","hidden","destroy","show","change","attr","removeAttr"],"mappings":";;;;;;;AAsBAA,wCAAO,CACH,SACA,YACA,oBACA,WACA,yBACA,sBACJ,SAASC,EAAGC,KAAMC,aAAcC,IAAKC,gBAAiBC,iBAQ9CC,0BACmB,kCADnBA,mBAEY,4BAQZC,wBACe,iBAMfC,oBAAsB,gBACjBC,yBAMTD,oBAAoBE,UAAUD,eAAiB,WAC3CT,EAAEM,2BAA2BK,OAAM,SAASC,GACxCA,EAAEC,qBA6BgBC,IAClBC,KAUAC,WAEAC,WAxCIC,YAAc,GAClBlB,EAAEO,yBAAyBY,MAAK,eACxBC,SAAWpB,EAAEqB,MACbD,SAASE,GAAG,aACZJ,YAAYK,KAAKH,SAASI,UAuBhBV,IApBDI,YAqBjBH,KAAO,CACP,CACIU,IAAK,UACLC,UAAW,UAEf,CACID,IAAK,yBACLC,UAAW,qBAGfV,WAAa,iDAEbC,WAAa,GACjBd,IAAIwB,YAAYZ,MAAMa,MAAK,SAASC,aAChCZ,WAAaY,YAAY,OACrBC,eAAiBD,YAAY,UAC1BzB,gBAAgB2B,OAAO,CAC1BC,MAAOf,WACPgB,KAAMH,oBAEXF,MAAK,SAASM,cACbA,MAAMC,kBAAkBlB,YAGxBiB,MAAME,UAAUC,GAAGhC,YAAYiC,MAAM,eAM7BC,QAAU,CACVC,WAAYxB,WACZyB,KANS,KACF3B,MAQXb,KAAKyC,KAAK,CAACH,UAAU,GAAGI,MAAK,SAASC,MAC9BA,KAAKC,OACLC,OAAOC,SAASC,SAEhB9C,aAAa+C,gBAAgB,CACzBC,QAASN,KAAKO,SAAS,GAAGD,QAC1BE,KAAM,aAGfC,KAAKnD,aAAaoD,cAIzBpB,MAAME,UAAUC,GAAGhC,YAAYkD,QAAQ,WAEnCrB,MAAMsB,aAGHtB,SACRS,MAAK,SAAST,OACbA,MAAMuB,UACPJ,KAAKnD,aAAaoD,cA1ErBtD,EAAEM,oBAAoBoD,QAAO,SAAS9C,GAClCA,EAAEC,iBAEkBb,EAAEqB,MACJC,GAAG,YACjBtB,EAAEO,yBAAyBoD,KAAK,UAAW,WAE3C3D,EAAEO,yBAAyBqD,WAAW,eAsE3CpD"} \ No newline at end of file diff --git a/admin/tool/dataprivacy/amd/build/data_registry.min.js b/admin/tool/dataprivacy/amd/build/data_registry.min.js index 5dd4d5ed6eb..0716dff4f9f 100644 --- a/admin/tool/dataprivacy/amd/build/data_registry.min.js +++ b/admin/tool/dataprivacy/amd/build/data_registry.min.js @@ -5,6 +5,6 @@ * @copyright 2018 David Monllao * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -define("tool_dataprivacy/data_registry",["jquery","core/str","core/ajax","core/notification","core/templates","core/modal_factory","core/modal_events","core/fragment","tool_dataprivacy/add_purpose","tool_dataprivacy/add_category"],(function($,Str,Ajax,Notification,Templates,ModalFactory,ModalEvents,Fragment,AddPurpose,AddCategory){var SELECTORS_TREE_NODES="[data-context-tree-node=1]",SELECTORS_FORM_CONTAINER="#context-form-container",DataRegistry=function(systemContextId,initContextLevel,initContextId){this.systemContextId=systemContextId,this.currentContextLevel=initContextLevel,this.currentContextId=initContextId,this.init()};return DataRegistry.prototype.systemContextId=0,DataRegistry.prototype.currentContextLevel=0,DataRegistry.prototype.currentContextId=0,DataRegistry.prototype.addpurpose=null,DataRegistry.prototype.addcategory=null,DataRegistry.prototype.init=function(){this.addpurpose=AddPurpose.getInstance(this.systemContextId),this.addcategory=AddCategory.getInstance(this.systemContextId);this.strings=Str.get_strings([{key:"changessaved",component:"moodle"},{key:"contextpurposecategorysaved",component:"tool_dataprivacy"},{key:"noblockstoload",component:"tool_dataprivacy"},{key:"noactivitiestoload",component:"tool_dataprivacy"},{key:"nocoursestoload",component:"tool_dataprivacy"}]),this.registerEventListeners(),this.currentContextId?this.loadForm("context_form",[this.currentContextId],this.submitContextFormAjax.bind(this)):this.loadForm("contextlevel_form",[this.currentContextLevel],this.submitContextLevelFormAjax.bind(this))},DataRegistry.prototype.registerEventListeners=function(){$(SELECTORS_TREE_NODES).on("click",function(ev){ev.preventDefault();var trigger=$(ev.currentTarget);$(SELECTORS_TREE_NODES).removeClass("active"),trigger.addClass("active");var contextLevel=trigger.data("contextlevel"),contextId=trigger.data("contextid");if(contextLevel)window.history.pushState({},null,"?contextlevel="+contextLevel),this.addpurpose.removeListeners(),this.addcategory.removeListeners(),this.currentContextLevel=contextLevel,this.loadForm("contextlevel_form",[this.currentContextLevel],this.submitContextLevelFormAjax.bind(this));else if(contextId)window.history.pushState({},null,"?contextid="+contextId),this.addpurpose.removeListeners(),this.addcategory.removeListeners(),this.currentContextId=contextId,this.loadForm("context_form",[this.currentContextId],this.submitContextFormAjax.bind(this));else{var expandContextId=trigger.data("expandcontextid"),expandElement=trigger.data("expandelement"),expanded=trigger.data("expanded");expandElement&&(expanded?this.collapse(trigger):!trigger.data("loaded")&&expandContextId&&expandElement?(trigger.find("> i").removeClass("fa-plus"),trigger.find("> i").addClass("fa-circle-o-notch fa-spin"),this.loadExtra(trigger,expandContextId,expandElement)):this.expand(trigger))}}.bind(this))},DataRegistry.prototype.removeListeners=function(){$(SELECTORS_TREE_NODES).off("click")},DataRegistry.prototype.loadForm=function(fragmentName,fragmentArgs,formSubmitCallback){this.clearForm(),Fragment.loadFragment("tool_dataprivacy",fragmentName,this.systemContextId,fragmentArgs).done(function(html,js){$(SELECTORS_FORM_CONTAINER).html(html),Templates.runTemplateJS(js),this.addpurpose.registerEventListeners(),this.addcategory.registerEventListeners(),$(SELECTORS_FORM_CONTAINER).on("submit","form",formSubmitCallback)}.bind(this)).fail(Notification.exception)},DataRegistry.prototype.clearForm=function(){$(SELECTORS_FORM_CONTAINER).off("submit","form")},DataRegistry.prototype.submitForm=function(e){e.preventDefault(),$(SELECTORS_FORM_CONTAINER).find("form").submit()},DataRegistry.prototype.submitContextLevelFormAjax=function(e){this.submitFormAjax(e,"tool_dataprivacy_set_contextlevel_form")},DataRegistry.prototype.submitContextFormAjax=function(e){this.submitFormAjax(e,"tool_dataprivacy_set_context_form")},DataRegistry.prototype.submitFormAjax=function(e,saveMethodName){e.preventDefault();var formData=$(SELECTORS_FORM_CONTAINER).find("form").serialize();return this.strings.then((function(strings){Ajax.call([{methodname:saveMethodName,args:{jsonformdata:JSON.stringify(formData)},done:function(){Notification.alert(strings[0],strings[1])},fail:Notification.exception}])})).catch(Notification.exception)},DataRegistry.prototype.loadExtra=function(parentNode,expandContextId,expandElement){Ajax.call([{methodname:"tool_dataprivacy_tree_extra_branches",args:{contextid:expandContextId,element:expandElement},done:function(data){0!=data.branches.length?Templates.render("tool_dataprivacy/context_tree_branches",data).then(function(html){parentNode.after(html),this.removeListeners(),this.registerEventListeners(),this.expand(parentNode),parentNode.data("loaded",1)}.bind(this)).fail(Notification.exception):this.noElements(parentNode,expandElement)}.bind(this),fail:Notification.exception}])},DataRegistry.prototype.noElements=function(node,expandElement){node.data("expandcontextid",""),node.data("expandelement",""),this.strings.then((function(strings){var key=2;"module"==expandElement?key=3:"course"==expandElement&&(key=4),node.text(strings[key])})).fail(Notification.exception)},DataRegistry.prototype.collapse=function(node){node.data("expanded",0),node.siblings("nav").addClass("hidden"),node.find("> i").removeClass("fa-minus"),node.find("> i").addClass("fa-plus")},DataRegistry.prototype.expand=function(node){node.data("expanded",1),node.siblings("nav").removeClass("hidden"),node.find("> i").removeClass("fa-plus"),node.find("> i").removeClass("fa-circle-o-notch fa-spin"),node.find("> i").addClass("fa-minus")},{init:function(systemContextId,initContextLevel,initContextId){return new DataRegistry(systemContextId,initContextLevel,initContextId)}}})); +define("tool_dataprivacy/data_registry",["jquery","core/str","core/ajax","core/notification","core/templates","core/fragment","tool_dataprivacy/add_purpose","tool_dataprivacy/add_category"],(function($,Str,Ajax,Notification,Templates,Fragment,AddPurpose,AddCategory){var SELECTORS_TREE_NODES="[data-context-tree-node=1]",SELECTORS_FORM_CONTAINER="#context-form-container",DataRegistry=function(systemContextId,initContextLevel,initContextId){this.systemContextId=systemContextId,this.currentContextLevel=initContextLevel,this.currentContextId=initContextId,this.init()};return DataRegistry.prototype.systemContextId=0,DataRegistry.prototype.currentContextLevel=0,DataRegistry.prototype.currentContextId=0,DataRegistry.prototype.addpurpose=null,DataRegistry.prototype.addcategory=null,DataRegistry.prototype.init=function(){this.addpurpose=AddPurpose.getInstance(this.systemContextId),this.addcategory=AddCategory.getInstance(this.systemContextId);this.strings=Str.get_strings([{key:"changessaved",component:"moodle"},{key:"contextpurposecategorysaved",component:"tool_dataprivacy"},{key:"noblockstoload",component:"tool_dataprivacy"},{key:"noactivitiestoload",component:"tool_dataprivacy"},{key:"nocoursestoload",component:"tool_dataprivacy"}]),this.registerEventListeners(),this.currentContextId?this.loadForm("context_form",[this.currentContextId],this.submitContextFormAjax.bind(this)):this.loadForm("contextlevel_form",[this.currentContextLevel],this.submitContextLevelFormAjax.bind(this))},DataRegistry.prototype.registerEventListeners=function(){$(SELECTORS_TREE_NODES).on("click",function(ev){ev.preventDefault();var trigger=$(ev.currentTarget);$(SELECTORS_TREE_NODES).removeClass("active"),trigger.addClass("active");var contextLevel=trigger.data("contextlevel"),contextId=trigger.data("contextid");if(contextLevel)window.history.pushState({},null,"?contextlevel="+contextLevel),this.addpurpose.removeListeners(),this.addcategory.removeListeners(),this.currentContextLevel=contextLevel,this.loadForm("contextlevel_form",[this.currentContextLevel],this.submitContextLevelFormAjax.bind(this));else if(contextId)window.history.pushState({},null,"?contextid="+contextId),this.addpurpose.removeListeners(),this.addcategory.removeListeners(),this.currentContextId=contextId,this.loadForm("context_form",[this.currentContextId],this.submitContextFormAjax.bind(this));else{var expandContextId=trigger.data("expandcontextid"),expandElement=trigger.data("expandelement"),expanded=trigger.data("expanded");expandElement&&(expanded?this.collapse(trigger):!trigger.data("loaded")&&expandContextId&&expandElement?(trigger.find("> i").removeClass("fa-plus"),trigger.find("> i").addClass("fa-circle-o-notch fa-spin"),this.loadExtra(trigger,expandContextId,expandElement)):this.expand(trigger))}}.bind(this))},DataRegistry.prototype.removeListeners=function(){$(SELECTORS_TREE_NODES).off("click")},DataRegistry.prototype.loadForm=function(fragmentName,fragmentArgs,formSubmitCallback){this.clearForm(),Fragment.loadFragment("tool_dataprivacy",fragmentName,this.systemContextId,fragmentArgs).done(function(html,js){$(SELECTORS_FORM_CONTAINER).html(html),Templates.runTemplateJS(js),this.addpurpose.registerEventListeners(),this.addcategory.registerEventListeners(),$(SELECTORS_FORM_CONTAINER).on("submit","form",formSubmitCallback)}.bind(this)).fail(Notification.exception)},DataRegistry.prototype.clearForm=function(){$(SELECTORS_FORM_CONTAINER).off("submit","form")},DataRegistry.prototype.submitForm=function(e){e.preventDefault(),$(SELECTORS_FORM_CONTAINER).find("form").submit()},DataRegistry.prototype.submitContextLevelFormAjax=function(e){this.submitFormAjax(e,"tool_dataprivacy_set_contextlevel_form")},DataRegistry.prototype.submitContextFormAjax=function(e){this.submitFormAjax(e,"tool_dataprivacy_set_context_form")},DataRegistry.prototype.submitFormAjax=function(e,saveMethodName){e.preventDefault();var formData=$(SELECTORS_FORM_CONTAINER).find("form").serialize();return this.strings.then((function(strings){Ajax.call([{methodname:saveMethodName,args:{jsonformdata:JSON.stringify(formData)},done:function(){Notification.alert(strings[0],strings[1])},fail:Notification.exception}])})).catch(Notification.exception)},DataRegistry.prototype.loadExtra=function(parentNode,expandContextId,expandElement){Ajax.call([{methodname:"tool_dataprivacy_tree_extra_branches",args:{contextid:expandContextId,element:expandElement},done:function(data){0!=data.branches.length?Templates.render("tool_dataprivacy/context_tree_branches",data).then(function(html){parentNode.after(html),this.removeListeners(),this.registerEventListeners(),this.expand(parentNode),parentNode.data("loaded",1)}.bind(this)).fail(Notification.exception):this.noElements(parentNode,expandElement)}.bind(this),fail:Notification.exception}])},DataRegistry.prototype.noElements=function(node,expandElement){node.data("expandcontextid",""),node.data("expandelement",""),this.strings.then((function(strings){var key=2;"module"==expandElement?key=3:"course"==expandElement&&(key=4),node.text(strings[key])})).fail(Notification.exception)},DataRegistry.prototype.collapse=function(node){node.data("expanded",0),node.siblings("nav").addClass("hidden"),node.find("> i").removeClass("fa-minus"),node.find("> i").addClass("fa-plus")},DataRegistry.prototype.expand=function(node){node.data("expanded",1),node.siblings("nav").removeClass("hidden"),node.find("> i").removeClass("fa-plus"),node.find("> i").removeClass("fa-circle-o-notch fa-spin"),node.find("> i").addClass("fa-minus")},{init:function(systemContextId,initContextLevel,initContextId){return new DataRegistry(systemContextId,initContextLevel,initContextId)}}})); //# sourceMappingURL=data_registry.min.js.map \ No newline at end of file diff --git a/admin/tool/dataprivacy/amd/build/data_registry.min.js.map b/admin/tool/dataprivacy/amd/build/data_registry.min.js.map index 235aef226ce..e437b694fda 100644 --- a/admin/tool/dataprivacy/amd/build/data_registry.min.js.map +++ b/admin/tool/dataprivacy/amd/build/data_registry.min.js.map @@ -1 +1 @@ -{"version":3,"file":"data_registry.min.js","sources":["../src/data_registry.js"],"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 * Request actions.\n *\n * @module tool_dataprivacy/data_registry\n * @copyright 2018 David Monllao\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(['jquery', 'core/str', 'core/ajax', 'core/notification', 'core/templates', 'core/modal_factory',\n 'core/modal_events', 'core/fragment', 'tool_dataprivacy/add_purpose', 'tool_dataprivacy/add_category'],\n function($, Str, Ajax, Notification, Templates, ModalFactory, ModalEvents, Fragment, AddPurpose, AddCategory) {\n\n var SELECTORS = {\n TREE_NODES: '[data-context-tree-node=1]',\n FORM_CONTAINER: '#context-form-container',\n };\n\n var DataRegistry = function(systemContextId, initContextLevel, initContextId) {\n this.systemContextId = systemContextId;\n this.currentContextLevel = initContextLevel;\n this.currentContextId = initContextId;\n this.init();\n };\n\n /**\n * @var {int} systemContextId\n * @private\n */\n DataRegistry.prototype.systemContextId = 0;\n\n /**\n * @var {int} currentContextLevel\n * @private\n */\n DataRegistry.prototype.currentContextLevel = 0;\n\n /**\n * @var {int} currentContextId\n * @private\n */\n DataRegistry.prototype.currentContextId = 0;\n\n /**\n * @var {AddPurpose} addpurpose\n * @private\n */\n DataRegistry.prototype.addpurpose = null;\n\n /**\n * @var {AddCategory} addcategory\n * @private\n */\n DataRegistry.prototype.addcategory = null;\n\n DataRegistry.prototype.init = function() {\n // Add purpose and category modals always at system context.\n this.addpurpose = AddPurpose.getInstance(this.systemContextId);\n this.addcategory = AddCategory.getInstance(this.systemContextId);\n\n var stringKeys = [\n {\n key: 'changessaved',\n component: 'moodle'\n }, {\n key: 'contextpurposecategorysaved',\n component: 'tool_dataprivacy'\n }, {\n key: 'noblockstoload',\n component: 'tool_dataprivacy'\n }, {\n key: 'noactivitiestoload',\n component: 'tool_dataprivacy'\n }, {\n key: 'nocoursestoload',\n component: 'tool_dataprivacy'\n }\n ];\n this.strings = Str.get_strings(stringKeys);\n\n this.registerEventListeners();\n\n // Load the default context level form.\n if (this.currentContextId) {\n this.loadForm('context_form', [this.currentContextId], this.submitContextFormAjax.bind(this));\n } else {\n this.loadForm('contextlevel_form', [this.currentContextLevel], this.submitContextLevelFormAjax.bind(this));\n }\n };\n\n DataRegistry.prototype.registerEventListeners = function() {\n $(SELECTORS.TREE_NODES).on('click', function(ev) {\n ev.preventDefault();\n\n var trigger = $(ev.currentTarget);\n\n // Active node.\n $(SELECTORS.TREE_NODES).removeClass('active');\n trigger.addClass('active');\n\n var contextLevel = trigger.data('contextlevel');\n var contextId = trigger.data('contextid');\n if (contextLevel) {\n // Context level level.\n\n window.history.pushState({}, null, '?contextlevel=' + contextLevel);\n\n // Remove previous add purpose and category listeners to avoid memory leaks.\n this.addpurpose.removeListeners();\n this.addcategory.removeListeners();\n\n // Load the context level form.\n this.currentContextLevel = contextLevel;\n this.loadForm('contextlevel_form', [this.currentContextLevel], this.submitContextLevelFormAjax.bind(this));\n } else if (contextId) {\n // Context instance level.\n\n window.history.pushState({}, null, '?contextid=' + contextId);\n\n // Remove previous add purpose and category listeners to avoid memory leaks.\n this.addpurpose.removeListeners();\n this.addcategory.removeListeners();\n\n // Load the context level form.\n this.currentContextId = contextId;\n this.loadForm('context_form', [this.currentContextId], this.submitContextFormAjax.bind(this));\n } else {\n // Expandable nodes.\n\n var expandContextId = trigger.data('expandcontextid');\n var expandElement = trigger.data('expandelement');\n var expanded = trigger.data('expanded');\n\n // Extra checking that there is an expandElement because we remove it after loading 0 branches.\n if (expandElement) {\n\n if (!expanded) {\n if (trigger.data('loaded') || !expandContextId || !expandElement) {\n this.expand(trigger);\n } else {\n\n trigger.find('> i').removeClass('fa-plus');\n trigger.find('> i').addClass('fa-circle-o-notch fa-spin');\n this.loadExtra(trigger, expandContextId, expandElement);\n }\n } else {\n this.collapse(trigger);\n }\n }\n }\n\n }.bind(this));\n };\n\n DataRegistry.prototype.removeListeners = function() {\n $(SELECTORS.TREE_NODES).off('click');\n };\n\n DataRegistry.prototype.loadForm = function(fragmentName, fragmentArgs, formSubmitCallback) {\n\n this.clearForm();\n\n var fragment = Fragment.loadFragment('tool_dataprivacy', fragmentName, this.systemContextId, fragmentArgs);\n fragment.done(function(html, js) {\n\n $(SELECTORS.FORM_CONTAINER).html(html);\n Templates.runTemplateJS(js);\n\n this.addpurpose.registerEventListeners();\n this.addcategory.registerEventListeners();\n\n // We also catch the form submit event and use it to submit the form with ajax.\n $(SELECTORS.FORM_CONTAINER).on('submit', 'form', formSubmitCallback);\n\n }.bind(this)).fail(Notification.exception);\n };\n\n DataRegistry.prototype.clearForm = function() {\n // Remove previous listeners.\n $(SELECTORS.FORM_CONTAINER).off('submit', 'form');\n };\n\n /**\n * This triggers a form submission, so that any mform elements can do final tricks before the form submission is processed.\n *\n * @method submitForm\n * @param {Event} e Form submission event.\n * @private\n */\n DataRegistry.prototype.submitForm = function(e) {\n e.preventDefault();\n $(SELECTORS.FORM_CONTAINER).find('form').submit();\n };\n\n DataRegistry.prototype.submitContextLevelFormAjax = function(e) {\n this.submitFormAjax(e, 'tool_dataprivacy_set_contextlevel_form');\n };\n\n DataRegistry.prototype.submitContextFormAjax = function(e) {\n this.submitFormAjax(e, 'tool_dataprivacy_set_context_form');\n };\n\n DataRegistry.prototype.submitFormAjax = function(e, saveMethodName) {\n // We don't want to do a real form submission.\n e.preventDefault();\n\n // Convert all the form elements values to a serialised string.\n var formData = $(SELECTORS.FORM_CONTAINER).find('form').serialize();\n return this.strings.then(function(strings) {\n Ajax.call([{\n methodname: saveMethodName,\n args: {jsonformdata: JSON.stringify(formData)},\n done: function() {\n Notification.alert(strings[0], strings[1]);\n },\n fail: Notification.exception\n }]);\n return;\n }).catch(Notification.exception);\n\n };\n\n DataRegistry.prototype.loadExtra = function(parentNode, expandContextId, expandElement) {\n\n Ajax.call([{\n methodname: 'tool_dataprivacy_tree_extra_branches',\n args: {\n contextid: expandContextId,\n element: expandElement,\n },\n done: function(data) {\n if (data.branches.length == 0) {\n this.noElements(parentNode, expandElement);\n return;\n }\n Templates.render('tool_dataprivacy/context_tree_branches', data)\n .then(function(html) {\n parentNode.after(html);\n this.removeListeners();\n this.registerEventListeners();\n this.expand(parentNode);\n parentNode.data('loaded', 1);\n return;\n }.bind(this))\n .fail(Notification.exception);\n }.bind(this),\n fail: Notification.exception\n }]);\n };\n\n DataRegistry.prototype.noElements = function(node, expandElement) {\n node.data('expandcontextid', '');\n node.data('expandelement', '');\n this.strings.then(function(strings) {\n\n // 2 = blocks, 3 = activities, 4 = courses (although courses is not likely really).\n var key = 2;\n if (expandElement == 'module') {\n key = 3;\n } else if (expandElement == 'course') {\n key = 4;\n }\n node.text(strings[key]);\n return;\n }).fail(Notification.exception);\n };\n\n DataRegistry.prototype.collapse = function(node) {\n node.data('expanded', 0);\n node.siblings('nav').addClass('hidden');\n node.find('> i').removeClass('fa-minus');\n node.find('> i').addClass('fa-plus');\n };\n\n DataRegistry.prototype.expand = function(node) {\n node.data('expanded', 1);\n node.siblings('nav').removeClass('hidden');\n node.find('> i').removeClass('fa-plus');\n // Also remove the spinning one if data was just loaded.\n node.find('> i').removeClass('fa-circle-o-notch fa-spin');\n node.find('> i').addClass('fa-minus');\n };\n return /** @alias module:tool_dataprivacy/data_registry */ {\n\n /**\n * Initialise the page.\n *\n * @param {Number} systemContextId\n * @param {Number} initContextLevel\n * @param {Number} initContextId\n * @return {DataRegistry}\n */\n init: function(systemContextId, initContextLevel, initContextId) {\n return new DataRegistry(systemContextId, initContextLevel, initContextId);\n }\n };\n }\n);\n\n"],"names":["define","$","Str","Ajax","Notification","Templates","ModalFactory","ModalEvents","Fragment","AddPurpose","AddCategory","SELECTORS","DataRegistry","systemContextId","initContextLevel","initContextId","currentContextLevel","currentContextId","init","prototype","addpurpose","addcategory","getInstance","this","strings","get_strings","key","component","registerEventListeners","loadForm","submitContextFormAjax","bind","submitContextLevelFormAjax","on","ev","preventDefault","trigger","currentTarget","removeClass","addClass","contextLevel","data","contextId","window","history","pushState","removeListeners","expandContextId","expandElement","expanded","collapse","find","loadExtra","expand","off","fragmentName","fragmentArgs","formSubmitCallback","clearForm","loadFragment","done","html","js","runTemplateJS","fail","exception","submitForm","e","submit","submitFormAjax","saveMethodName","formData","serialize","then","call","methodname","args","jsonformdata","JSON","stringify","alert","catch","parentNode","contextid","element","branches","length","render","after","noElements","node","text","siblings"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"data_registry.min.js","sources":["../src/data_registry.js"],"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 * Request actions.\n *\n * @module tool_dataprivacy/data_registry\n * @copyright 2018 David Monllao\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(['jquery', 'core/str', 'core/ajax', 'core/notification', 'core/templates',\n 'core/fragment', 'tool_dataprivacy/add_purpose', 'tool_dataprivacy/add_category'],\n function($, Str, Ajax, Notification, Templates, Fragment, AddPurpose, AddCategory) {\n\n var SELECTORS = {\n TREE_NODES: '[data-context-tree-node=1]',\n FORM_CONTAINER: '#context-form-container',\n };\n\n var DataRegistry = function(systemContextId, initContextLevel, initContextId) {\n this.systemContextId = systemContextId;\n this.currentContextLevel = initContextLevel;\n this.currentContextId = initContextId;\n this.init();\n };\n\n /**\n * @var {int} systemContextId\n * @private\n */\n DataRegistry.prototype.systemContextId = 0;\n\n /**\n * @var {int} currentContextLevel\n * @private\n */\n DataRegistry.prototype.currentContextLevel = 0;\n\n /**\n * @var {int} currentContextId\n * @private\n */\n DataRegistry.prototype.currentContextId = 0;\n\n /**\n * @var {AddPurpose} addpurpose\n * @private\n */\n DataRegistry.prototype.addpurpose = null;\n\n /**\n * @var {AddCategory} addcategory\n * @private\n */\n DataRegistry.prototype.addcategory = null;\n\n DataRegistry.prototype.init = function() {\n // Add purpose and category modals always at system context.\n this.addpurpose = AddPurpose.getInstance(this.systemContextId);\n this.addcategory = AddCategory.getInstance(this.systemContextId);\n\n var stringKeys = [\n {\n key: 'changessaved',\n component: 'moodle'\n }, {\n key: 'contextpurposecategorysaved',\n component: 'tool_dataprivacy'\n }, {\n key: 'noblockstoload',\n component: 'tool_dataprivacy'\n }, {\n key: 'noactivitiestoload',\n component: 'tool_dataprivacy'\n }, {\n key: 'nocoursestoload',\n component: 'tool_dataprivacy'\n }\n ];\n this.strings = Str.get_strings(stringKeys);\n\n this.registerEventListeners();\n\n // Load the default context level form.\n if (this.currentContextId) {\n this.loadForm('context_form', [this.currentContextId], this.submitContextFormAjax.bind(this));\n } else {\n this.loadForm('contextlevel_form', [this.currentContextLevel], this.submitContextLevelFormAjax.bind(this));\n }\n };\n\n DataRegistry.prototype.registerEventListeners = function() {\n $(SELECTORS.TREE_NODES).on('click', function(ev) {\n ev.preventDefault();\n\n var trigger = $(ev.currentTarget);\n\n // Active node.\n $(SELECTORS.TREE_NODES).removeClass('active');\n trigger.addClass('active');\n\n var contextLevel = trigger.data('contextlevel');\n var contextId = trigger.data('contextid');\n if (contextLevel) {\n // Context level level.\n\n window.history.pushState({}, null, '?contextlevel=' + contextLevel);\n\n // Remove previous add purpose and category listeners to avoid memory leaks.\n this.addpurpose.removeListeners();\n this.addcategory.removeListeners();\n\n // Load the context level form.\n this.currentContextLevel = contextLevel;\n this.loadForm('contextlevel_form', [this.currentContextLevel], this.submitContextLevelFormAjax.bind(this));\n } else if (contextId) {\n // Context instance level.\n\n window.history.pushState({}, null, '?contextid=' + contextId);\n\n // Remove previous add purpose and category listeners to avoid memory leaks.\n this.addpurpose.removeListeners();\n this.addcategory.removeListeners();\n\n // Load the context level form.\n this.currentContextId = contextId;\n this.loadForm('context_form', [this.currentContextId], this.submitContextFormAjax.bind(this));\n } else {\n // Expandable nodes.\n\n var expandContextId = trigger.data('expandcontextid');\n var expandElement = trigger.data('expandelement');\n var expanded = trigger.data('expanded');\n\n // Extra checking that there is an expandElement because we remove it after loading 0 branches.\n if (expandElement) {\n\n if (!expanded) {\n if (trigger.data('loaded') || !expandContextId || !expandElement) {\n this.expand(trigger);\n } else {\n\n trigger.find('> i').removeClass('fa-plus');\n trigger.find('> i').addClass('fa-circle-o-notch fa-spin');\n this.loadExtra(trigger, expandContextId, expandElement);\n }\n } else {\n this.collapse(trigger);\n }\n }\n }\n\n }.bind(this));\n };\n\n DataRegistry.prototype.removeListeners = function() {\n $(SELECTORS.TREE_NODES).off('click');\n };\n\n DataRegistry.prototype.loadForm = function(fragmentName, fragmentArgs, formSubmitCallback) {\n\n this.clearForm();\n\n var fragment = Fragment.loadFragment('tool_dataprivacy', fragmentName, this.systemContextId, fragmentArgs);\n fragment.done(function(html, js) {\n\n $(SELECTORS.FORM_CONTAINER).html(html);\n Templates.runTemplateJS(js);\n\n this.addpurpose.registerEventListeners();\n this.addcategory.registerEventListeners();\n\n // We also catch the form submit event and use it to submit the form with ajax.\n $(SELECTORS.FORM_CONTAINER).on('submit', 'form', formSubmitCallback);\n\n }.bind(this)).fail(Notification.exception);\n };\n\n DataRegistry.prototype.clearForm = function() {\n // Remove previous listeners.\n $(SELECTORS.FORM_CONTAINER).off('submit', 'form');\n };\n\n /**\n * This triggers a form submission, so that any mform elements can do final tricks before the form submission is processed.\n *\n * @method submitForm\n * @param {Event} e Form submission event.\n * @private\n */\n DataRegistry.prototype.submitForm = function(e) {\n e.preventDefault();\n $(SELECTORS.FORM_CONTAINER).find('form').submit();\n };\n\n DataRegistry.prototype.submitContextLevelFormAjax = function(e) {\n this.submitFormAjax(e, 'tool_dataprivacy_set_contextlevel_form');\n };\n\n DataRegistry.prototype.submitContextFormAjax = function(e) {\n this.submitFormAjax(e, 'tool_dataprivacy_set_context_form');\n };\n\n DataRegistry.prototype.submitFormAjax = function(e, saveMethodName) {\n // We don't want to do a real form submission.\n e.preventDefault();\n\n // Convert all the form elements values to a serialised string.\n var formData = $(SELECTORS.FORM_CONTAINER).find('form').serialize();\n return this.strings.then(function(strings) {\n Ajax.call([{\n methodname: saveMethodName,\n args: {jsonformdata: JSON.stringify(formData)},\n done: function() {\n Notification.alert(strings[0], strings[1]);\n },\n fail: Notification.exception\n }]);\n return;\n }).catch(Notification.exception);\n\n };\n\n DataRegistry.prototype.loadExtra = function(parentNode, expandContextId, expandElement) {\n\n Ajax.call([{\n methodname: 'tool_dataprivacy_tree_extra_branches',\n args: {\n contextid: expandContextId,\n element: expandElement,\n },\n done: function(data) {\n if (data.branches.length == 0) {\n this.noElements(parentNode, expandElement);\n return;\n }\n Templates.render('tool_dataprivacy/context_tree_branches', data)\n .then(function(html) {\n parentNode.after(html);\n this.removeListeners();\n this.registerEventListeners();\n this.expand(parentNode);\n parentNode.data('loaded', 1);\n return;\n }.bind(this))\n .fail(Notification.exception);\n }.bind(this),\n fail: Notification.exception\n }]);\n };\n\n DataRegistry.prototype.noElements = function(node, expandElement) {\n node.data('expandcontextid', '');\n node.data('expandelement', '');\n this.strings.then(function(strings) {\n\n // 2 = blocks, 3 = activities, 4 = courses (although courses is not likely really).\n var key = 2;\n if (expandElement == 'module') {\n key = 3;\n } else if (expandElement == 'course') {\n key = 4;\n }\n node.text(strings[key]);\n return;\n }).fail(Notification.exception);\n };\n\n DataRegistry.prototype.collapse = function(node) {\n node.data('expanded', 0);\n node.siblings('nav').addClass('hidden');\n node.find('> i').removeClass('fa-minus');\n node.find('> i').addClass('fa-plus');\n };\n\n DataRegistry.prototype.expand = function(node) {\n node.data('expanded', 1);\n node.siblings('nav').removeClass('hidden');\n node.find('> i').removeClass('fa-plus');\n // Also remove the spinning one if data was just loaded.\n node.find('> i').removeClass('fa-circle-o-notch fa-spin');\n node.find('> i').addClass('fa-minus');\n };\n return /** @alias module:tool_dataprivacy/data_registry */ {\n\n /**\n * Initialise the page.\n *\n * @param {Number} systemContextId\n * @param {Number} initContextLevel\n * @param {Number} initContextId\n * @return {DataRegistry}\n */\n init: function(systemContextId, initContextLevel, initContextId) {\n return new DataRegistry(systemContextId, initContextLevel, initContextId);\n }\n };\n }\n);\n"],"names":["define","$","Str","Ajax","Notification","Templates","Fragment","AddPurpose","AddCategory","SELECTORS","DataRegistry","systemContextId","initContextLevel","initContextId","currentContextLevel","currentContextId","init","prototype","addpurpose","addcategory","getInstance","this","strings","get_strings","key","component","registerEventListeners","loadForm","submitContextFormAjax","bind","submitContextLevelFormAjax","on","ev","preventDefault","trigger","currentTarget","removeClass","addClass","contextLevel","data","contextId","window","history","pushState","removeListeners","expandContextId","expandElement","expanded","collapse","find","loadExtra","expand","off","fragmentName","fragmentArgs","formSubmitCallback","clearForm","loadFragment","done","html","js","runTemplateJS","fail","exception","submitForm","e","submit","submitFormAjax","saveMethodName","formData","serialize","then","call","methodname","args","jsonformdata","JSON","stringify","alert","catch","parentNode","contextid","element","branches","length","render","after","noElements","node","text","siblings"],"mappings":"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"} \ No newline at end of file diff --git a/admin/tool/dataprivacy/amd/build/defaultsactions.min.js b/admin/tool/dataprivacy/amd/build/defaultsactions.min.js index 765cd98cf54..21e4d69620c 100644 --- a/admin/tool/dataprivacy/amd/build/defaultsactions.min.js +++ b/admin/tool/dataprivacy/amd/build/defaultsactions.min.js @@ -5,6 +5,6 @@ * @copyright 2018 Jun Pataleta * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -define("tool_dataprivacy/defaultsactions",["jquery","core/ajax","core/notification","core/str","core/modal_factory","core/modal_events","core/templates"],(function($,Ajax,Notification,Str,ModalFactory,ModalEvents,Templates){var ACTIONS_EDIT_LEVEL_DEFAULTS='[data-action="edit-level-defaults"]',ACTIONS_NEW_ACTIVITY_DEFAULTS='[data-action="new-activity-defaults"]',ACTIONS_EDIT_ACTIVITY_DEFAULTS='[data-action="edit-activity-defaults"]',ACTIONS_DELETE_ACTIVITY_DEFAULTS='[data-action="delete-activity-defaults"]',DefaultsActions=function(){this.registerEvents()};function showDefaultsFormModal(title,contextLevel,category,purpose,activity,categoryOptions,purposeOptions,activityOptions){null!==category&&categoryOptions.forEach((function(currentValue){currentValue.id===category&&(currentValue.selected=!0)})),null!==purpose&&purposeOptions.forEach((function(currentValue){currentValue.id===purpose&&(currentValue.selected=!0)}));var templateContext={contextlevel:contextLevel,categoryoptions:categoryOptions,purposeoptions:purposeOptions};null!==activityOptions&&activityOptions.length&&(null===activity?templateContext.newactivitydefaults=!0:activityOptions.forEach((function(currentValue){activity===currentValue.name&&(currentValue.selected=!0)})),templateContext.modemodule=!0,templateContext.activityoptions=activityOptions),ModalFactory.create({title:title,body:Templates.render("tool_dataprivacy/category_purpose_form",templateContext),type:ModalFactory.types.SAVE_CANCEL,large:!0}).then((function(modal){return modal.getRoot().on(ModalEvents.save,(function(){var activity=$("#activity"),activityVal=void 0!==activity?activity.val():null,override=$("#override"),overrideVal=void 0!==override&&override.is(":checked");setContextDefaults($("#contextlevel").val(),$("#category").val(),$("#purpose").val(),activityVal,overrideVal)})),modal.getRoot().on(ModalEvents.hidden,(function(){modal.destroy()})),modal.show(),modal})).catch(Notification.exception)}function setContextDefaults(contextLevel,category,purpose,activity,override){var request={methodname:"tool_dataprivacy_set_context_defaults",args:{contextlevel:contextLevel,category:category,purpose:purpose,override:override,activity:activity}};Ajax.call([request])[0].done((function(data){data.result&&window.location.reload()}))}return DefaultsActions.prototype.registerEvents=function(){$(ACTIONS_EDIT_LEVEL_DEFAULTS).click((function(e){e.preventDefault();var button=$(this),contextLevel=button.data("contextlevel"),category=button.data("category"),purpose=button.data("purpose"),promises=Ajax.call([{methodname:"tool_dataprivacy_get_category_options",args:{}},{methodname:"tool_dataprivacy_get_purpose_options",args:{}}]),titlePromise=Str.get_string("editdefaults","tool_dataprivacy",$("#defaults-header").text());$.when(promises[0],promises[1],titlePromise).then((function(categoryResponse,purposeResponse,title){var categories=categoryResponse.options,purposes=purposeResponse.options;return showDefaultsFormModal(title,contextLevel,category,purpose,null,categories,purposes,null),!0})).catch(Notification.exception)})),$(ACTIONS_NEW_ACTIVITY_DEFAULTS).click((function(e){e.preventDefault();var contextLevel=$(this).data("contextlevel"),promises=Ajax.call([{methodname:"tool_dataprivacy_get_category_options",args:{}},{methodname:"tool_dataprivacy_get_purpose_options",args:{}},{methodname:"tool_dataprivacy_get_activity_options",args:{nodefaults:!0}}]),titlePromise=Str.get_string("addnewdefaults","tool_dataprivacy");$.when(promises[0],promises[1],promises[2],titlePromise).then((function(categoryResponse,purposeResponse,activityResponse,title){var categories=categoryResponse.options,purposes=purposeResponse.options,activities=activityResponse.options;return showDefaultsFormModal(title,contextLevel,null,null,null,categories,purposes,activities),!0})).catch(Notification.exception)})),$(ACTIONS_EDIT_ACTIVITY_DEFAULTS).click((function(e){e.preventDefault();var button=$(this),contextLevel=button.data("contextlevel"),category=button.data("category"),purpose=button.data("purpose"),activity=button.data("activityname"),promises=Ajax.call([{methodname:"tool_dataprivacy_get_category_options",args:{}},{methodname:"tool_dataprivacy_get_purpose_options",args:{}},{methodname:"tool_dataprivacy_get_activity_options",args:{}}]),titlePromise=Str.get_string("editmoduledefaults","tool_dataprivacy");$.when(promises[0],promises[1],promises[2],titlePromise).then((function(categoryResponse,purposeResponse,activityResponse,title){var categories=categoryResponse.options,purposes=purposeResponse.options,activities=activityResponse.options;return showDefaultsFormModal(title,contextLevel,category,purpose,activity,categories,purposes,activities),!0})).catch(Notification.exception)})),$(ACTIONS_DELETE_ACTIVITY_DEFAULTS).click((function(e){e.preventDefault();var button=$(this),contextLevel=button.data("contextlevel"),activity=button.data("activityname"),activityDisplayName=button.data("activitydisplayname");ModalFactory.create({title:Str.get_string("deletedefaults","tool_dataprivacy",activityDisplayName),body:Templates.render("tool_dataprivacy/delete_activity_defaults",{activityname:activityDisplayName}),type:ModalFactory.types.SAVE_CANCEL,large:!0}).then((function(modal){return modal.setSaveButtonText(Str.get_string("delete")),modal.getRoot().on(ModalEvents.save,(function(){setContextDefaults(contextLevel,-1,-1,activity,!1)})),modal.getRoot().on(ModalEvents.hidden,(function(){modal.destroy()})),modal.show(),!0})).catch(Notification.exception)}))},{init:function(){return new DefaultsActions}}})); +define("tool_dataprivacy/defaultsactions",["jquery","core/ajax","core/notification","core/str","core/modal_save_cancel","core/modal_events","core/templates"],(function($,Ajax,Notification,Str,ModalSaveCancel,ModalEvents,Templates){var ACTIONS_EDIT_LEVEL_DEFAULTS='[data-action="edit-level-defaults"]',ACTIONS_NEW_ACTIVITY_DEFAULTS='[data-action="new-activity-defaults"]',ACTIONS_EDIT_ACTIVITY_DEFAULTS='[data-action="edit-activity-defaults"]',ACTIONS_DELETE_ACTIVITY_DEFAULTS='[data-action="delete-activity-defaults"]',DefaultsActions=function(){this.registerEvents()};function showDefaultsFormModal(title,contextLevel,category,purpose,activity,categoryOptions,purposeOptions,activityOptions){null!==category&&categoryOptions.forEach((function(currentValue){currentValue.id===category&&(currentValue.selected=!0)})),null!==purpose&&purposeOptions.forEach((function(currentValue){currentValue.id===purpose&&(currentValue.selected=!0)}));var templateContext={contextlevel:contextLevel,categoryoptions:categoryOptions,purposeoptions:purposeOptions};null!==activityOptions&&activityOptions.length&&(null===activity?templateContext.newactivitydefaults=!0:activityOptions.forEach((function(currentValue){activity===currentValue.name&&(currentValue.selected=!0)})),templateContext.modemodule=!0,templateContext.activityoptions=activityOptions),ModalSaveCancel.create({title:title,body:Templates.render("tool_dataprivacy/category_purpose_form",templateContext),large:!0,show:!0,removeOnClose:!0}).then((function(modal){return modal.getRoot().on(ModalEvents.save,(function(){var activity=$("#activity"),activityVal=void 0!==activity?activity.val():null,override=$("#override"),overrideVal=void 0!==override&&override.is(":checked");setContextDefaults($("#contextlevel").val(),$("#category").val(),$("#purpose").val(),activityVal,overrideVal)})),modal})).catch(Notification.exception)}function setContextDefaults(contextLevel,category,purpose,activity,override){var request={methodname:"tool_dataprivacy_set_context_defaults",args:{contextlevel:contextLevel,category:category,purpose:purpose,override:override,activity:activity}};Ajax.call([request])[0].done((function(data){data.result&&window.location.reload()}))}return DefaultsActions.prototype.registerEvents=function(){$(ACTIONS_EDIT_LEVEL_DEFAULTS).click((function(e){e.preventDefault();var button=$(this),contextLevel=button.data("contextlevel"),category=button.data("category"),purpose=button.data("purpose"),promises=Ajax.call([{methodname:"tool_dataprivacy_get_category_options",args:{}},{methodname:"tool_dataprivacy_get_purpose_options",args:{}}]),titlePromise=Str.get_string("editdefaults","tool_dataprivacy",$("#defaults-header").text());$.when(promises[0],promises[1],titlePromise).then((function(categoryResponse,purposeResponse,title){var categories=categoryResponse.options,purposes=purposeResponse.options;return showDefaultsFormModal(title,contextLevel,category,purpose,null,categories,purposes,null),!0})).catch(Notification.exception)})),$(ACTIONS_NEW_ACTIVITY_DEFAULTS).click((function(e){e.preventDefault();var contextLevel=$(this).data("contextlevel"),promises=Ajax.call([{methodname:"tool_dataprivacy_get_category_options",args:{}},{methodname:"tool_dataprivacy_get_purpose_options",args:{}},{methodname:"tool_dataprivacy_get_activity_options",args:{nodefaults:!0}}]),titlePromise=Str.get_string("addnewdefaults","tool_dataprivacy");$.when(promises[0],promises[1],promises[2],titlePromise).then((function(categoryResponse,purposeResponse,activityResponse,title){var categories=categoryResponse.options,purposes=purposeResponse.options,activities=activityResponse.options;return showDefaultsFormModal(title,contextLevel,null,null,null,categories,purposes,activities),!0})).catch(Notification.exception)})),$(ACTIONS_EDIT_ACTIVITY_DEFAULTS).click((function(e){e.preventDefault();var button=$(this),contextLevel=button.data("contextlevel"),category=button.data("category"),purpose=button.data("purpose"),activity=button.data("activityname"),promises=Ajax.call([{methodname:"tool_dataprivacy_get_category_options",args:{}},{methodname:"tool_dataprivacy_get_purpose_options",args:{}},{methodname:"tool_dataprivacy_get_activity_options",args:{}}]),titlePromise=Str.get_string("editmoduledefaults","tool_dataprivacy");$.when(promises[0],promises[1],promises[2],titlePromise).then((function(categoryResponse,purposeResponse,activityResponse,title){var categories=categoryResponse.options,purposes=purposeResponse.options,activities=activityResponse.options;return showDefaultsFormModal(title,contextLevel,category,purpose,activity,categories,purposes,activities),!0})).catch(Notification.exception)})),$(ACTIONS_DELETE_ACTIVITY_DEFAULTS).click((function(e){e.preventDefault();var button=$(this),contextLevel=button.data("contextlevel"),activity=button.data("activityname"),activityDisplayName=button.data("activitydisplayname");ModalSaveCancel.create({title:Str.get_string("deletedefaults","tool_dataprivacy",activityDisplayName),body:Templates.render("tool_dataprivacy/delete_activity_defaults",{activityname:activityDisplayName}),large:!0,show:!0,removeOnClose:!0}).then((function(modal){return modal.setSaveButtonText(Str.get_string("delete")),modal.getRoot().on(ModalEvents.save,(function(){setContextDefaults(contextLevel,-1,-1,activity,!1)})),!0})).catch(Notification.exception)}))},{init:function(){return new DefaultsActions}}})); //# sourceMappingURL=defaultsactions.min.js.map \ No newline at end of file diff --git a/admin/tool/dataprivacy/amd/build/defaultsactions.min.js.map b/admin/tool/dataprivacy/amd/build/defaultsactions.min.js.map index 50b7d083a24..2f4d03018e6 100644 --- a/admin/tool/dataprivacy/amd/build/defaultsactions.min.js.map +++ b/admin/tool/dataprivacy/amd/build/defaultsactions.min.js.map @@ -1 +1 @@ -{"version":3,"file":"defaultsactions.min.js","sources":["../src/defaultsactions.js"],"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 * AMD module for data registry defaults actions.\n *\n * @module tool_dataprivacy/defaultsactions\n * @copyright 2018 Jun Pataleta\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n 'jquery',\n 'core/ajax',\n 'core/notification',\n 'core/str',\n 'core/modal_factory',\n 'core/modal_events',\n 'core/templates'],\nfunction($, Ajax, Notification, Str, ModalFactory, ModalEvents, Templates) {\n\n /**\n * List of action selectors.\n *\n * @type {{EDIT_LEVEL_DEFAULTS: string}}\n * @type {{NEW_ACTIVITY_DEFAULTS: string}}\n * @type {{EDIT_ACTIVITY_DEFAULTS: string}}\n * @type {{DELETE_ACTIVITY_DEFAULTS: string}}\n */\n var ACTIONS = {\n EDIT_LEVEL_DEFAULTS: '[data-action=\"edit-level-defaults\"]',\n NEW_ACTIVITY_DEFAULTS: '[data-action=\"new-activity-defaults\"]',\n EDIT_ACTIVITY_DEFAULTS: '[data-action=\"edit-activity-defaults\"]',\n DELETE_ACTIVITY_DEFAULTS: '[data-action=\"delete-activity-defaults\"]'\n };\n\n /** @type {{INHERIT: Number}} **/\n var INHERIT = -1;\n\n /**\n * DefaultsActions class.\n */\n var DefaultsActions = function() {\n this.registerEvents();\n };\n\n /**\n * Register event listeners.\n */\n DefaultsActions.prototype.registerEvents = function() {\n $(ACTIONS.EDIT_LEVEL_DEFAULTS).click(function(e) {\n e.preventDefault();\n\n var button = $(this);\n var contextLevel = button.data('contextlevel');\n var category = button.data('category');\n var purpose = button.data('purpose');\n\n // Get options.\n var requests = [\n {methodname: 'tool_dataprivacy_get_category_options', args: {}},\n {methodname: 'tool_dataprivacy_get_purpose_options', args: {}}\n ];\n\n var promises = Ajax.call(requests);\n var titlePromise = Str.get_string('editdefaults', 'tool_dataprivacy', $('#defaults-header').text());\n $.when(promises[0], promises[1], titlePromise).then(function(categoryResponse, purposeResponse, title) {\n var categories = categoryResponse.options;\n var purposes = purposeResponse.options;\n showDefaultsFormModal(title, contextLevel, category, purpose, null, categories, purposes, null);\n\n return true;\n }).catch(Notification.exception);\n });\n\n $(ACTIONS.NEW_ACTIVITY_DEFAULTS).click(function(e) {\n e.preventDefault();\n\n var button = $(this);\n var contextLevel = button.data('contextlevel');\n\n // Get options.\n var requests = [\n {methodname: 'tool_dataprivacy_get_category_options', args: {}},\n {methodname: 'tool_dataprivacy_get_purpose_options', args: {}},\n {methodname: 'tool_dataprivacy_get_activity_options', args: {'nodefaults': true}}\n ];\n\n var promises = Ajax.call(requests);\n var titlePromise = Str.get_string('addnewdefaults', 'tool_dataprivacy');\n\n $.when(promises[0], promises[1], promises[2], titlePromise).then(\n function(categoryResponse, purposeResponse, activityResponse, title) {\n var categories = categoryResponse.options;\n var purposes = purposeResponse.options;\n var activities = activityResponse.options;\n\n showDefaultsFormModal(title, contextLevel, null, null, null, categories, purposes, activities);\n\n return true;\n\n }).catch(Notification.exception);\n }\n );\n\n $(ACTIONS.EDIT_ACTIVITY_DEFAULTS).click(function(e) {\n e.preventDefault();\n\n var button = $(this);\n var contextLevel = button.data('contextlevel');\n var category = button.data('category');\n var purpose = button.data('purpose');\n var activity = button.data('activityname');\n\n // Get options.\n var requests = [\n {methodname: 'tool_dataprivacy_get_category_options', args: {}},\n {methodname: 'tool_dataprivacy_get_purpose_options', args: {}},\n {methodname: 'tool_dataprivacy_get_activity_options', args: {}}\n ];\n\n var promises = Ajax.call(requests);\n var titlePromise = Str.get_string('editmoduledefaults', 'tool_dataprivacy');\n\n $.when(promises[0], promises[1], promises[2], titlePromise).then(\n function(categoryResponse, purposeResponse, activityResponse, title) {\n var categories = categoryResponse.options;\n var purposes = purposeResponse.options;\n var activities = activityResponse.options;\n\n showDefaultsFormModal(title, contextLevel, category, purpose, activity, categories, purposes, activities);\n\n return true;\n\n }).catch(Notification.exception);\n }\n );\n\n $(ACTIONS.DELETE_ACTIVITY_DEFAULTS).click(function(e) {\n e.preventDefault();\n\n var button = $(this);\n var contextLevel = button.data('contextlevel');\n var activity = button.data('activityname');\n var activityDisplayName = button.data('activitydisplayname');\n // Set category and purpose to inherit (-1).\n var category = INHERIT;\n var purpose = INHERIT;\n\n ModalFactory.create({\n title: Str.get_string('deletedefaults', 'tool_dataprivacy', activityDisplayName),\n body: Templates.render('tool_dataprivacy/delete_activity_defaults', {\"activityname\": activityDisplayName}),\n type: ModalFactory.types.SAVE_CANCEL,\n large: true\n }).then(function(modal) {\n modal.setSaveButtonText(Str.get_string('delete'));\n\n // Handle save event.\n modal.getRoot().on(ModalEvents.save, function() {\n setContextDefaults(contextLevel, category, purpose, activity, false);\n });\n\n // Handle hidden event.\n modal.getRoot().on(ModalEvents.hidden, function() {\n // Destroy when hidden.\n modal.destroy();\n });\n\n modal.show();\n\n return true;\n }).catch(Notification.exception);\n });\n };\n\n /**\n * Prepares and renders the modal for setting the defaults for the given context level/plugin.\n *\n * @param {String} title The modal's title.\n * @param {Number} contextLevel The context level to set defaults for.\n * @param {Number} category The current category ID.\n * @param {Number} purpose The current purpose ID.\n * @param {String} activity The plugin name of the activity. Optional.\n * @param {Array} categoryOptions The list of category options.\n * @param {Array} purposeOptions The list of purpose options.\n * @param {Array} activityOptions The list of activity options. Optional.\n */\n function showDefaultsFormModal(title, contextLevel, category, purpose, activity,\n categoryOptions, purposeOptions, activityOptions) {\n\n if (category !== null) {\n categoryOptions.forEach(function(currentValue) {\n if (currentValue.id === category) {\n currentValue.selected = true;\n }\n });\n }\n\n if (purpose !== null) {\n purposeOptions.forEach(function(currentValue) {\n if (currentValue.id === purpose) {\n currentValue.selected = true;\n }\n });\n }\n\n var templateContext = {\n \"contextlevel\": contextLevel,\n \"categoryoptions\": categoryOptions,\n \"purposeoptions\": purposeOptions\n };\n\n // Check the activityOptions parameter that was passed.\n if (activityOptions !== null && activityOptions.length) {\n // Check the activity parameter that was passed.\n if (activity === null) {\n // We're setting a new defaults for a module.\n templateContext.newactivitydefaults = true;\n\n } else {\n // Edit mode. Set selection.\n activityOptions.forEach(function(currentValue) {\n if (activity === currentValue.name) {\n currentValue.selected = true;\n }\n });\n }\n\n templateContext.modemodule = true;\n templateContext.activityoptions = activityOptions;\n }\n\n ModalFactory.create({\n title: title,\n body: Templates.render('tool_dataprivacy/category_purpose_form', templateContext),\n type: ModalFactory.types.SAVE_CANCEL,\n large: true\n }).then(function(modal) {\n\n // Handle save event.\n modal.getRoot().on(ModalEvents.save, function() {\n var activity = $('#activity');\n var activityVal = typeof activity !== 'undefined' ? activity.val() : null;\n var override = $('#override');\n var overrideVal = typeof override !== 'undefined' ? override.is(':checked') : false;\n\n setContextDefaults($('#contextlevel').val(), $('#category').val(), $('#purpose').val(), activityVal, overrideVal);\n });\n\n // Handle hidden event.\n modal.getRoot().on(ModalEvents.hidden, function() {\n // Destroy when hidden.\n modal.destroy();\n });\n\n modal.show();\n\n return modal;\n }).catch(Notification.exception);\n }\n\n /**\n * Calls a the tool_dataprivacy_set_context_defaults WS function.\n *\n * @param {Number} contextLevel The context level.\n * @param {Number} category The category ID.\n * @param {Number} purpose The purpose ID.\n * @param {String} activity The plugin name of the activity module.\n * @param {Boolean} override Whether to override custom instances.\n */\n function setContextDefaults(contextLevel, category, purpose, activity, override) {\n var request = {\n methodname: 'tool_dataprivacy_set_context_defaults',\n args: {\n 'contextlevel': contextLevel,\n 'category': category,\n 'purpose': purpose,\n 'override': override,\n 'activity': activity\n }\n };\n\n Ajax.call([request])[0].done(function(data) {\n if (data.result) {\n window.location.reload();\n }\n });\n }\n\n return /** @alias module:tool_dataprivacy/defaultsactions */ {\n // Public variables and functions.\n\n /**\n * Initialise the module.\n *\n * @method init\n * @return {DefaultsActions}\n */\n 'init': function() {\n return new DefaultsActions();\n }\n };\n});\n"],"names":["define","$","Ajax","Notification","Str","ModalFactory","ModalEvents","Templates","ACTIONS","DefaultsActions","registerEvents","showDefaultsFormModal","title","contextLevel","category","purpose","activity","categoryOptions","purposeOptions","activityOptions","forEach","currentValue","id","selected","templateContext","length","newactivitydefaults","name","modemodule","activityoptions","create","body","render","type","types","SAVE_CANCEL","large","then","modal","getRoot","on","save","activityVal","val","override","overrideVal","is","setContextDefaults","hidden","destroy","show","catch","exception","request","methodname","args","call","done","data","result","window","location","reload","prototype","click","e","preventDefault","button","this","promises","titlePromise","get_string","text","when","categoryResponse","purposeResponse","categories","options","purposes","activityResponse","activities","activityDisplayName","setSaveButtonText"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"defaultsactions.min.js","sources":["../src/defaultsactions.js"],"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 * AMD module for data registry defaults actions.\n *\n * @module tool_dataprivacy/defaultsactions\n * @copyright 2018 Jun Pataleta\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n 'jquery',\n 'core/ajax',\n 'core/notification',\n 'core/str',\n 'core/modal_save_cancel',\n 'core/modal_events',\n 'core/templates'],\nfunction($, Ajax, Notification, Str, ModalSaveCancel, ModalEvents, Templates) {\n\n /**\n * List of action selectors.\n *\n * @type {{EDIT_LEVEL_DEFAULTS: string}}\n * @type {{NEW_ACTIVITY_DEFAULTS: string}}\n * @type {{EDIT_ACTIVITY_DEFAULTS: string}}\n * @type {{DELETE_ACTIVITY_DEFAULTS: string}}\n */\n var ACTIONS = {\n EDIT_LEVEL_DEFAULTS: '[data-action=\"edit-level-defaults\"]',\n NEW_ACTIVITY_DEFAULTS: '[data-action=\"new-activity-defaults\"]',\n EDIT_ACTIVITY_DEFAULTS: '[data-action=\"edit-activity-defaults\"]',\n DELETE_ACTIVITY_DEFAULTS: '[data-action=\"delete-activity-defaults\"]'\n };\n\n /** @type {{INHERIT: Number}} **/\n var INHERIT = -1;\n\n /**\n * DefaultsActions class.\n */\n var DefaultsActions = function() {\n this.registerEvents();\n };\n\n /**\n * Register event listeners.\n */\n DefaultsActions.prototype.registerEvents = function() {\n $(ACTIONS.EDIT_LEVEL_DEFAULTS).click(function(e) {\n e.preventDefault();\n\n var button = $(this);\n var contextLevel = button.data('contextlevel');\n var category = button.data('category');\n var purpose = button.data('purpose');\n\n // Get options.\n var requests = [\n {methodname: 'tool_dataprivacy_get_category_options', args: {}},\n {methodname: 'tool_dataprivacy_get_purpose_options', args: {}}\n ];\n\n var promises = Ajax.call(requests);\n var titlePromise = Str.get_string('editdefaults', 'tool_dataprivacy', $('#defaults-header').text());\n $.when(promises[0], promises[1], titlePromise).then(function(categoryResponse, purposeResponse, title) {\n var categories = categoryResponse.options;\n var purposes = purposeResponse.options;\n showDefaultsFormModal(title, contextLevel, category, purpose, null, categories, purposes, null);\n\n return true;\n }).catch(Notification.exception);\n });\n\n $(ACTIONS.NEW_ACTIVITY_DEFAULTS).click(function(e) {\n e.preventDefault();\n\n var button = $(this);\n var contextLevel = button.data('contextlevel');\n\n // Get options.\n var requests = [\n {methodname: 'tool_dataprivacy_get_category_options', args: {}},\n {methodname: 'tool_dataprivacy_get_purpose_options', args: {}},\n {methodname: 'tool_dataprivacy_get_activity_options', args: {'nodefaults': true}}\n ];\n\n var promises = Ajax.call(requests);\n var titlePromise = Str.get_string('addnewdefaults', 'tool_dataprivacy');\n\n $.when(promises[0], promises[1], promises[2], titlePromise).then(\n function(categoryResponse, purposeResponse, activityResponse, title) {\n var categories = categoryResponse.options;\n var purposes = purposeResponse.options;\n var activities = activityResponse.options;\n\n showDefaultsFormModal(title, contextLevel, null, null, null, categories, purposes, activities);\n\n return true;\n\n }).catch(Notification.exception);\n }\n );\n\n $(ACTIONS.EDIT_ACTIVITY_DEFAULTS).click(function(e) {\n e.preventDefault();\n\n var button = $(this);\n var contextLevel = button.data('contextlevel');\n var category = button.data('category');\n var purpose = button.data('purpose');\n var activity = button.data('activityname');\n\n // Get options.\n var requests = [\n {methodname: 'tool_dataprivacy_get_category_options', args: {}},\n {methodname: 'tool_dataprivacy_get_purpose_options', args: {}},\n {methodname: 'tool_dataprivacy_get_activity_options', args: {}}\n ];\n\n var promises = Ajax.call(requests);\n var titlePromise = Str.get_string('editmoduledefaults', 'tool_dataprivacy');\n\n $.when(promises[0], promises[1], promises[2], titlePromise).then(\n function(categoryResponse, purposeResponse, activityResponse, title) {\n var categories = categoryResponse.options;\n var purposes = purposeResponse.options;\n var activities = activityResponse.options;\n\n showDefaultsFormModal(title, contextLevel, category, purpose, activity, categories, purposes, activities);\n\n return true;\n\n }).catch(Notification.exception);\n }\n );\n\n $(ACTIONS.DELETE_ACTIVITY_DEFAULTS).click(function(e) {\n e.preventDefault();\n\n var button = $(this);\n var contextLevel = button.data('contextlevel');\n var activity = button.data('activityname');\n var activityDisplayName = button.data('activitydisplayname');\n // Set category and purpose to inherit (-1).\n var category = INHERIT;\n var purpose = INHERIT;\n\n ModalSaveCancel.create({\n title: Str.get_string('deletedefaults', 'tool_dataprivacy', activityDisplayName),\n body: Templates.render('tool_dataprivacy/delete_activity_defaults', {\"activityname\": activityDisplayName}),\n large: true,\n show: true,\n removeOnClose: true,\n }).then(function(modal) {\n modal.setSaveButtonText(Str.get_string('delete'));\n\n // Handle save event.\n modal.getRoot().on(ModalEvents.save, function() {\n setContextDefaults(contextLevel, category, purpose, activity, false);\n });\n\n return true;\n }).catch(Notification.exception);\n });\n };\n\n /**\n * Prepares and renders the modal for setting the defaults for the given context level/plugin.\n *\n * @param {String} title The modal's title.\n * @param {Number} contextLevel The context level to set defaults for.\n * @param {Number} category The current category ID.\n * @param {Number} purpose The current purpose ID.\n * @param {String} activity The plugin name of the activity. Optional.\n * @param {Array} categoryOptions The list of category options.\n * @param {Array} purposeOptions The list of purpose options.\n * @param {Array} activityOptions The list of activity options. Optional.\n */\n function showDefaultsFormModal(title, contextLevel, category, purpose, activity,\n categoryOptions, purposeOptions, activityOptions) {\n\n if (category !== null) {\n categoryOptions.forEach(function(currentValue) {\n if (currentValue.id === category) {\n currentValue.selected = true;\n }\n });\n }\n\n if (purpose !== null) {\n purposeOptions.forEach(function(currentValue) {\n if (currentValue.id === purpose) {\n currentValue.selected = true;\n }\n });\n }\n\n var templateContext = {\n \"contextlevel\": contextLevel,\n \"categoryoptions\": categoryOptions,\n \"purposeoptions\": purposeOptions\n };\n\n // Check the activityOptions parameter that was passed.\n if (activityOptions !== null && activityOptions.length) {\n // Check the activity parameter that was passed.\n if (activity === null) {\n // We're setting a new defaults for a module.\n templateContext.newactivitydefaults = true;\n\n } else {\n // Edit mode. Set selection.\n activityOptions.forEach(function(currentValue) {\n if (activity === currentValue.name) {\n currentValue.selected = true;\n }\n });\n }\n\n templateContext.modemodule = true;\n templateContext.activityoptions = activityOptions;\n }\n\n ModalSaveCancel.create({\n title: title,\n body: Templates.render('tool_dataprivacy/category_purpose_form', templateContext),\n large: true,\n show: true,\n removeOnClose: true,\n }).then(function(modal) {\n\n // Handle save event.\n modal.getRoot().on(ModalEvents.save, function() {\n var activity = $('#activity');\n var activityVal = typeof activity !== 'undefined' ? activity.val() : null;\n var override = $('#override');\n var overrideVal = typeof override !== 'undefined' ? override.is(':checked') : false;\n\n setContextDefaults($('#contextlevel').val(), $('#category').val(), $('#purpose').val(), activityVal, overrideVal);\n });\n\n return modal;\n }).catch(Notification.exception);\n }\n\n /**\n * Calls a the tool_dataprivacy_set_context_defaults WS function.\n *\n * @param {Number} contextLevel The context level.\n * @param {Number} category The category ID.\n * @param {Number} purpose The purpose ID.\n * @param {String} activity The plugin name of the activity module.\n * @param {Boolean} override Whether to override custom instances.\n */\n function setContextDefaults(contextLevel, category, purpose, activity, override) {\n var request = {\n methodname: 'tool_dataprivacy_set_context_defaults',\n args: {\n 'contextlevel': contextLevel,\n 'category': category,\n 'purpose': purpose,\n 'override': override,\n 'activity': activity\n }\n };\n\n Ajax.call([request])[0].done(function(data) {\n if (data.result) {\n window.location.reload();\n }\n });\n }\n\n return /** @alias module:tool_dataprivacy/defaultsactions */ {\n // Public variables and functions.\n\n /**\n * Initialise the module.\n *\n * @method init\n * @return {DefaultsActions}\n */\n 'init': function() {\n return new DefaultsActions();\n }\n };\n});\n"],"names":["define","$","Ajax","Notification","Str","ModalSaveCancel","ModalEvents","Templates","ACTIONS","DefaultsActions","registerEvents","showDefaultsFormModal","title","contextLevel","category","purpose","activity","categoryOptions","purposeOptions","activityOptions","forEach","currentValue","id","selected","templateContext","length","newactivitydefaults","name","modemodule","activityoptions","create","body","render","large","show","removeOnClose","then","modal","getRoot","on","save","activityVal","val","override","overrideVal","is","setContextDefaults","catch","exception","request","methodname","args","call","done","data","result","window","location","reload","prototype","click","e","preventDefault","button","this","promises","titlePromise","get_string","text","when","categoryResponse","purposeResponse","categories","options","purposes","activityResponse","activities","activityDisplayName","setSaveButtonText"],"mappings":"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"} \ No newline at end of file diff --git a/admin/tool/dataprivacy/amd/build/purposesactions.min.js b/admin/tool/dataprivacy/amd/build/purposesactions.min.js index edcabcf6e51..a98320e715b 100644 --- a/admin/tool/dataprivacy/amd/build/purposesactions.min.js +++ b/admin/tool/dataprivacy/amd/build/purposesactions.min.js @@ -1,10 +1,17 @@ +define("tool_dataprivacy/purposesactions",["exports","core/ajax","core/notification","core/str","core/modal_events","core/modal_save_cancel"],(function(_exports,Ajax,Notification,Str,_modal_events,_modal_save_cancel){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireWildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}return newObj.default=obj,cache&&cache.set(obj,newObj),newObj} /** - * AMD module for purposes actions. - * - * @module tool_dataprivacy/purposesactions - * @copyright 2018 David Monllao - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -define("tool_dataprivacy/purposesactions",["jquery","core/ajax","core/notification","core/str","core/modal_factory","core/modal_events"],(function($,Ajax,Notification,Str,ModalFactory,ModalEvents){var ACTIONS_DELETE='[data-action="deletepurpose"]',PurposesActions=function(){this.registerEvents()};return PurposesActions.prototype.registerEvents=function(){$(ACTIONS_DELETE).click((function(e){e.preventDefault();var id=$(this).data("id"),stringkeys=[{key:"deletepurpose",component:"tool_dataprivacy"},{key:"deletepurposetext",component:"tool_dataprivacy",param:$(this).data("name")},{key:"delete"}];Str.get_strings(stringkeys).then((function(langStrings){var title=langStrings[0],confirmMessage=langStrings[1],buttonText=langStrings[2];return ModalFactory.create({title:title,body:confirmMessage,type:ModalFactory.types.SAVE_CANCEL}).then((function(modal){return modal.setSaveButtonText(buttonText),modal.getRoot().on(ModalEvents.save,(function(){var request={methodname:"tool_dataprivacy_delete_purpose",args:{id:id}};Ajax.call([request])[0].done((function(data){data.result?$('tr[data-purposeid="'+id+'"]').remove():Notification.addNotification({message:data.warnings[0].message,type:"error"})})).fail(Notification.exception)})),modal.getRoot().on(ModalEvents.hidden,(function(){modal.destroy()})),modal}))})).done((function(modal){modal.show()})).fail(Notification.exception)}))},{init:function(){return new PurposesActions}}})); + * AMD module for purposes actions. + * + * @module tool_dataprivacy/purposesactions + * @copyright 2018 David Monllao + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +/** + * Module for purpose actions. + * + * @module tool_dataprivacy/purposeactions + * @copyright 2018 David Monllao + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,Ajax=_interopRequireWildcard(Ajax),Notification=_interopRequireWildcard(Notification),Str=_interopRequireWildcard(Str),_modal_events=_interopRequireDefault(_modal_events),_modal_save_cancel=_interopRequireDefault(_modal_save_cancel);const ACTIONS_DELETE='[data-action="deletepurpose"]';return _exports.default=class{static init(){return new this}constructor(){this.registerEvents()}deletePurpose(id){return Ajax.call([{methodname:"tool_dataprivacy_delete_purpose",args:{id:id}}])[0]}handleRemoval(id){this.deletePurpose(id).then((data=>{var _document$querySelect;data.result?null===(_document$querySelect=document.querySelector('tr[data-purposeid="'.concat(id,'"]')))||void 0===_document$querySelect||_document$querySelect.remove():Notification.addNotification({message:data.warnings[0].message,type:"error"})})).catch(Notification.exception)}registerEvents(){document.addEventListener("click",(e=>{const target=e.target.closest(ACTIONS_DELETE);target&&(e.preventDefault(),this.confirmRemoval(target))}))}confirmRemoval(target){const id=target.dataset.id;var stringkeys=[{key:"deletepurpose",component:"tool_dataprivacy"},{key:"deletepurposetext",component:"tool_dataprivacy",param:target.dataset.name},{key:"delete"}];Str.get_strings(stringkeys).then((_ref=>{let[title,body,save]=_ref;return _modal_save_cancel.default.create({title:title,body:body,buttons:{save:save},show:!0,removeOnClose:!0})})).then((modal=>(modal.getRoot().on(_modal_events.default.save,(()=>this.handleRemoval(id))),modal))).catch(Notification.exception)}},_exports.default})); //# sourceMappingURL=purposesactions.min.js.map \ No newline at end of file diff --git a/admin/tool/dataprivacy/amd/build/purposesactions.min.js.map b/admin/tool/dataprivacy/amd/build/purposesactions.min.js.map index 6e7f8f4da8f..898130ed29c 100644 --- a/admin/tool/dataprivacy/amd/build/purposesactions.min.js.map +++ b/admin/tool/dataprivacy/amd/build/purposesactions.min.js.map @@ -1 +1 @@ -{"version":3,"file":"purposesactions.min.js","sources":["../src/purposesactions.js"],"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 * AMD module for purposes actions.\n *\n * @module tool_dataprivacy/purposesactions\n * @copyright 2018 David Monllao\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n 'jquery',\n 'core/ajax',\n 'core/notification',\n 'core/str',\n 'core/modal_factory',\n 'core/modal_events'],\nfunction($, Ajax, Notification, Str, ModalFactory, ModalEvents) {\n\n /**\n * List of action selectors.\n *\n * @type {{DELETE: string}}\n */\n var ACTIONS = {\n DELETE: '[data-action=\"deletepurpose\"]',\n };\n\n /**\n * PurposesActions class.\n */\n var PurposesActions = function() {\n this.registerEvents();\n };\n\n /**\n * Register event listeners.\n */\n PurposesActions.prototype.registerEvents = function() {\n $(ACTIONS.DELETE).click(function(e) {\n e.preventDefault();\n\n var id = $(this).data('id');\n var purposename = $(this).data('name');\n var stringkeys = [\n {\n key: 'deletepurpose',\n component: 'tool_dataprivacy'\n },\n {\n key: 'deletepurposetext',\n component: 'tool_dataprivacy',\n param: purposename\n },\n {\n key: 'delete'\n }\n ];\n\n Str.get_strings(stringkeys).then(function(langStrings) {\n var title = langStrings[0];\n var confirmMessage = langStrings[1];\n var buttonText = langStrings[2];\n return ModalFactory.create({\n title: title,\n body: confirmMessage,\n type: ModalFactory.types.SAVE_CANCEL\n }).then(function(modal) {\n modal.setSaveButtonText(buttonText);\n\n // Handle save event.\n modal.getRoot().on(ModalEvents.save, function() {\n\n var request = {\n methodname: 'tool_dataprivacy_delete_purpose',\n args: {'id': id}\n };\n\n Ajax.call([request])[0].done(function(data) {\n if (data.result) {\n $('tr[data-purposeid=\"' + id + '\"]').remove();\n } else {\n Notification.addNotification({\n message: data.warnings[0].message,\n type: 'error'\n });\n }\n }).fail(Notification.exception);\n });\n\n // Handle hidden event.\n modal.getRoot().on(ModalEvents.hidden, function() {\n // Destroy when hidden.\n modal.destroy();\n });\n\n return modal;\n });\n }).done(function(modal) {\n modal.show();\n\n }).fail(Notification.exception);\n });\n };\n\n return /** @alias module:tool_dataprivacy/purposesactions */ {\n // Public variables and functions.\n\n /**\n * Initialise the module.\n *\n * @method init\n * @return {PurposesActions}\n */\n 'init': function() {\n return new PurposesActions();\n }\n };\n});\n"],"names":["define","$","Ajax","Notification","Str","ModalFactory","ModalEvents","ACTIONS","PurposesActions","registerEvents","prototype","click","e","preventDefault","id","this","data","stringkeys","key","component","param","get_strings","then","langStrings","title","confirmMessage","buttonText","create","body","type","types","SAVE_CANCEL","modal","setSaveButtonText","getRoot","on","save","request","methodname","args","call","done","result","remove","addNotification","message","warnings","fail","exception","hidden","destroy","show"],"mappings":";;;;;;;AAsBAA,0CAAO,CACH,SACA,YACA,oBACA,WACA,qBACA,sBACJ,SAASC,EAAGC,KAAMC,aAAcC,IAAKC,aAAcC,iBAO3CC,eACQ,gCAMRC,gBAAkB,gBACbC,yBAMTD,gBAAgBE,UAAUD,eAAiB,WACvCR,EAAEM,gBAAgBI,OAAM,SAASC,GAC7BA,EAAEC,qBAEEC,GAAKb,EAAEc,MAAMC,KAAK,MAElBC,WAAa,CACb,CACIC,IAAK,gBACLC,UAAW,oBAEf,CACID,IAAK,oBACLC,UAAW,mBACXC,MATUnB,EAAEc,MAAMC,KAAK,SAW3B,CACIE,IAAK,WAIbd,IAAIiB,YAAYJ,YAAYK,MAAK,SAASC,iBAClCC,MAAQD,YAAY,GACpBE,eAAiBF,YAAY,GAC7BG,WAAaH,YAAY,UACtBlB,aAAasB,OAAO,CACvBH,MAAOA,MACPI,KAAMH,eACNI,KAAMxB,aAAayB,MAAMC,cAC1BT,MAAK,SAASU,cACbA,MAAMC,kBAAkBP,YAGxBM,MAAME,UAAUC,GAAG7B,YAAY8B,MAAM,eAE7BC,QAAU,CACVC,WAAY,kCACZC,KAAM,IAAOzB,KAGjBZ,KAAKsC,KAAK,CAACH,UAAU,GAAGI,MAAK,SAASzB,MAC9BA,KAAK0B,OACLzC,EAAE,sBAAwBa,GAAK,MAAM6B,SAErCxC,aAAayC,gBAAgB,CACzBC,QAAS7B,KAAK8B,SAAS,GAAGD,QAC1BhB,KAAM,aAGfkB,KAAK5C,aAAa6C,cAIzBhB,MAAME,UAAUC,GAAG7B,YAAY2C,QAAQ,WAEnCjB,MAAMkB,aAGHlB,YAEZS,MAAK,SAAST,OACbA,MAAMmB,UAEPJ,KAAK5C,aAAa6C,eAIgC,MASjD,kBACG,IAAIxC"} \ No newline at end of file +{"version":3,"file":"purposesactions.min.js","sources":["../src/purposesactions.js"],"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 * AMD module for purposes actions.\n *\n * @module tool_dataprivacy/purposesactions\n * @copyright 2018 David Monllao\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n// 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 * Module for purpose actions.\n *\n * @module tool_dataprivacy/purposeactions\n * @copyright 2018 David Monllao\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport * as Ajax from 'core/ajax';\nimport * as Notification from 'core/notification';\nimport * as Str from 'core/str';\nimport ModalEvents from 'core/modal_events';\nimport ModalSaveCancel from 'core/modal_save_cancel';\n\n/**\n * List of action selectors.\n *\n * @type {{DELETE: string}}\n */\nconst ACTIONS = {\n DELETE: '[data-action=\"deletepurpose\"]',\n};\n\nexport default class PurposeActions {\n\n static init() {\n return new this();\n }\n\n constructor() {\n this.registerEvents();\n }\n\n deletePurpose(id) {\n return Ajax.call([{\n methodname: 'tool_dataprivacy_delete_purpose',\n args: {id}\n }])[0];\n }\n\n handleRemoval(id) {\n this.deletePurpose(id)\n .then((data) => {\n if (data.result) {\n document.querySelector(`tr[data-purposeid=\"${id}\"]`)?.remove();\n } else {\n Notification.addNotification({\n message: data.warnings[0].message,\n type: 'error'\n });\n }\n\n return;\n })\n .catch(Notification.exception);\n\n }\n\n /**\n * Register event listeners.\n */\n registerEvents() {\n document.addEventListener('click', (e) => {\n const target = e.target.closest(ACTIONS.DELETE);\n if (!target) {\n return;\n }\n\n e.preventDefault();\n\n this.confirmRemoval(target);\n });\n }\n\n confirmRemoval(target) {\n const id = target.dataset.id;\n var purposename = target.dataset.name;\n var stringkeys = [\n {\n key: 'deletepurpose',\n component: 'tool_dataprivacy'\n },\n {\n key: 'deletepurposetext',\n component: 'tool_dataprivacy',\n param: purposename\n },\n {\n key: 'delete'\n }\n ];\n\n Str.get_strings(stringkeys).then(([\n title,\n body,\n save,\n ]) => ModalSaveCancel.create({\n title,\n body,\n buttons: {\n save,\n },\n show: true,\n removeOnClose: true,\n }))\n .then((modal) => {\n // Handle save event.\n modal.getRoot().on(ModalEvents.save, () => this.handleRemoval(id));\n\n return modal;\n })\n .catch(Notification.exception);\n }\n}\n"],"names":["ACTIONS","this","constructor","registerEvents","deletePurpose","id","Ajax","call","methodname","args","handleRemoval","then","data","result","document","querySelector","remove","Notification","addNotification","message","warnings","type","catch","exception","addEventListener","e","target","closest","preventDefault","confirmRemoval","dataset","stringkeys","key","component","param","name","Str","get_strings","_ref","title","body","save","ModalSaveCancel","create","buttons","show","removeOnClose","modal","getRoot","on","ModalEvents"],"mappings":";;;;;;;;;;;;;;oUAuDMA,eACM,mFAMG,IAAIC,KAGfC,mBACSC,iBAGTC,cAAcC,WACHC,KAAKC,KAAK,CAAC,CACdC,WAAY,kCACZC,KAAM,CAACJ,GAAAA,OACP,GAGRK,cAAcL,SACLD,cAAcC,IACdM,MAAMC,iCACCA,KAAKC,qCACLC,SAASC,2CAAoCV,kEAASW,SAEtDC,aAAaC,gBAAgB,CACzBC,QAASP,KAAKQ,SAAS,GAAGD,QAC1BE,KAAM,aAMjBC,MAAML,aAAaM,WAO5BpB,iBACIW,SAASU,iBAAiB,SAAUC,UAC1BC,OAASD,EAAEC,OAAOC,QAAQ3B,gBAC3B0B,SAILD,EAAEG,sBAEGC,eAAeH,YAI5BG,eAAeH,cACLrB,GAAKqB,OAAOI,QAAQzB,OAEtB0B,WAAa,CACb,CACIC,IAAK,gBACLC,UAAW,oBAEf,CACID,IAAK,oBACLC,UAAW,mBACXC,MATUR,OAAOI,QAAQK,MAW7B,CACIH,IAAK,WAIbI,IAAIC,YAAYN,YAAYpB,MAAK2B,WAC7BC,MACAC,KACAC,kBACEC,2BAAgBC,OAAO,CACzBJ,MAAAA,MACAC,KAAAA,KACAI,QAAS,CACLH,KAAAA,MAEJI,MAAM,EACNC,eAAe,OAEdnC,MAAMoC,QAEHA,MAAMC,UAAUC,GAAGC,sBAAYT,MAAM,IAAMxC,KAAKS,cAAcL,MAEvD0C,SAEVzB,MAAML,aAAaM"} \ No newline at end of file diff --git a/admin/tool/dataprivacy/amd/build/requestactions.min.js b/admin/tool/dataprivacy/amd/build/requestactions.min.js index 82cfeef3951..cb93f29fa90 100644 --- a/admin/tool/dataprivacy/amd/build/requestactions.min.js +++ b/admin/tool/dataprivacy/amd/build/requestactions.min.js @@ -5,6 +5,6 @@ * @copyright 2018 Jun Pataleta * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -define("tool_dataprivacy/requestactions",["jquery","core/ajax","core/notification","core/str","core/modal_factory","core/modal_events","core/templates","tool_dataprivacy/data_request_modal","tool_dataprivacy/events","tool_dataprivacy/selectedcourses"],(function($,Ajax,Notification,Str,ModalFactory,ModalEvents,Templates,ModalDataRequest,DataPrivacyEvents,SelectedCourses){var ACTIONS_APPROVE_REQUEST='[data-action="approve"]',ACTIONS_DENY_REQUEST='[data-action="deny"]',ACTIONS_VIEW_REQUEST='[data-action="view"]',ACTIONS_MARK_COMPLETE='[data-action="complete"]',ACTIONS_CONFIRM_BULK_ACTION='[id="confirm-bulk-action"]',ACTIONS_SELECT_ALL='[data-action="selectall"]',ACTIONS_APPROVE_REQUEST_SELECT_COURSE='[data-action="approve-selected-courses"]',BULK_ACTIONS_APPROVE=1,BULK_ACTIONS_DENY=2,SELECTORS_SELECT_REQUEST=".selectrequests",RequestActions=function(){this.registerEvents()};function approveEventWsData(requestId){return{wsfunction:"tool_dataprivacy_approve_data_request",wsparams:{requestid:requestId}}}function denyEventWsData(requestId){return{wsfunction:"tool_dataprivacy_deny_data_request",wsparams:{requestid:requestId}}}function showConfirmation(action,wsdata){var keys=[];switch(action){case DataPrivacyEvents.approve:keys=[{key:"approverequest",component:"tool_dataprivacy"},{key:"confirmapproval",component:"tool_dataprivacy"}];break;case DataPrivacyEvents.bulkApprove:keys=[{key:"bulkapproverequests",component:"tool_dataprivacy"},{key:"confirmbulkapproval",component:"tool_dataprivacy"}];break;case DataPrivacyEvents.deny:keys=[{key:"denyrequest",component:"tool_dataprivacy"},{key:"confirmdenial",component:"tool_dataprivacy"}];break;case DataPrivacyEvents.bulkDeny:keys=[{key:"bulkdenyrequests",component:"tool_dataprivacy"},{key:"confirmbulkdenial",component:"tool_dataprivacy"}];break;case DataPrivacyEvents.complete:keys=[{key:"markcomplete",component:"tool_dataprivacy"},{key:"confirmcompletion",component:"tool_dataprivacy"}]}var modalTitle="";Str.get_strings(keys).then((function(langStrings){modalTitle=langStrings[0];var confirmMessage=langStrings[1];return ModalFactory.create({title:modalTitle,body:confirmMessage,type:ModalFactory.types.SAVE_CANCEL})})).then((function(modal){modal.setSaveButtonText(modalTitle),modal.getRoot().on(ModalEvents.save,(function(){handleSave(wsdata.wsfunction,wsdata.wsparams)})),modal.getRoot().on(ModalEvents.hidden,(function(){modal.destroy()})),modal.show()})).catch(Notification.exception)}function handleSave(wsfunction,params){var request={methodname:wsfunction,args:params};Ajax.call([request])[0].done((function(data){data.result?window.location.reload():Notification.addNotification({message:data.warnings[0].message,type:"error"})})).fail(Notification.exception)}return RequestActions.prototype.registerEvents=function(){$(ACTIONS_VIEW_REQUEST).click((function(e){e.preventDefault();var requestId=$(this).data("requestid"),contextId=$(this).data("contextid"),request={methodname:"tool_dataprivacy_get_data_request",args:{requestid:requestId}},promises=Ajax.call([request]);$.when(promises[0]).then((function(data){return data.result?data.result:(Notification.addNotification({message:data.warnings[0].message,type:"error"}),!1)})).then((function(data){var body=Templates.render("tool_dataprivacy/request_details",data),templateContext={approvedeny:data.approvedeny,canmarkcomplete:data.canmarkcomplete,allowfiltering:data.allowfiltering};return ModalFactory.create({title:data.typename,body:body,type:ModalDataRequest.TYPE,large:!0,templateContext:templateContext})})).then((function(modal){modal.getRoot().on(DataPrivacyEvents.approve,(function(){showConfirmation(DataPrivacyEvents.approve,approveEventWsData(requestId))})),modal.getRoot().on(DataPrivacyEvents.deny,(function(){showConfirmation(DataPrivacyEvents.deny,denyEventWsData(requestId))})),modal.getRoot().on(DataPrivacyEvents.complete,(function(){handleSave("tool_dataprivacy_mark_complete",{requestid:requestId})})),modal.getRoot().on(ModalEvents.hidden,(function(){modal.destroy()})),modal.getRoot().on(DataPrivacyEvents.approveSelectCourses,(function(){new SelectedCourses(contextId,requestId)})),modal.show()})).catch(Notification.exception)})),$(ACTIONS_APPROVE_REQUEST_SELECT_COURSE).click((function(e){e.preventDefault();var requestId=$(this).data("requestid"),contextId=$(this).data("contextid");new SelectedCourses(contextId,requestId)})),$(ACTIONS_APPROVE_REQUEST).click((function(e){e.preventDefault();var requestId=$(this).data("requestid");showConfirmation(DataPrivacyEvents.approve,approveEventWsData(requestId))})),$(ACTIONS_DENY_REQUEST).click((function(e){e.preventDefault();var requestId=$(this).data("requestid");showConfirmation(DataPrivacyEvents.deny,denyEventWsData(requestId))})),$(ACTIONS_MARK_COMPLETE).click((function(e){e.preventDefault();var requestId=$(this).data("requestid");showConfirmation(DataPrivacyEvents.complete,function(requestId){return{wsfunction:"tool_dataprivacy_mark_complete",wsparams:{requestid:requestId}}}(requestId))})),$(ACTIONS_CONFIRM_BULK_ACTION).click((function(){var requestIds=[],actionEvent="",wsdata={},bulkActionKeys=[{key:"selectbulkaction",component:"tool_dataprivacy"},{key:"selectdatarequests",component:"tool_dataprivacy"},{key:"ok"}],bulkaction=parseInt($("#bulk-action").val());if(bulkaction==BULK_ACTIONS_APPROVE||bulkaction==BULK_ACTIONS_DENY)if($(".selectrequests:checked").each((function(){requestIds.push($(this).val())})),requestIds.length<1)Str.get_strings(bulkActionKeys).done((function(langStrings){Notification.alert("",langStrings[1],langStrings[2])})).fail(Notification.exception);else{switch(bulkaction){case BULK_ACTIONS_APPROVE:actionEvent=DataPrivacyEvents.bulkApprove,wsdata=function(requestIds){return{wsfunction:"tool_dataprivacy_bulk_approve_data_requests",wsparams:{requestids:requestIds}}}(requestIds);break;case BULK_ACTIONS_DENY:actionEvent=DataPrivacyEvents.bulkDeny,wsdata=function(requestIds){return{wsfunction:"tool_dataprivacy_bulk_deny_data_requests",wsparams:{requestids:requestIds}}}(requestIds)}showConfirmation(actionEvent,wsdata)}else Str.get_strings(bulkActionKeys).done((function(langStrings){Notification.alert("",langStrings[0],langStrings[2])})).fail(Notification.exception)})),$(ACTIONS_SELECT_ALL).change((function(e){e.preventDefault();var selectAll=$(this).is(":checked");$(SELECTORS_SELECT_REQUEST).prop("checked",selectAll)}))},RequestActions})); +define("tool_dataprivacy/requestactions",["jquery","core/ajax","core/notification","core/str","core/modal_save_cancel","core/modal_events","core/templates","tool_dataprivacy/data_request_modal","tool_dataprivacy/events","tool_dataprivacy/selectedcourses"],(function($,Ajax,Notification,Str,ModalSaveCancel,ModalEvents,Templates,ModalDataRequest,DataPrivacyEvents,SelectedCourses){var ACTIONS_APPROVE_REQUEST='[data-action="approve"]',ACTIONS_DENY_REQUEST='[data-action="deny"]',ACTIONS_VIEW_REQUEST='[data-action="view"]',ACTIONS_MARK_COMPLETE='[data-action="complete"]',ACTIONS_CONFIRM_BULK_ACTION='[id="confirm-bulk-action"]',ACTIONS_SELECT_ALL='[data-action="selectall"]',ACTIONS_APPROVE_REQUEST_SELECT_COURSE='[data-action="approve-selected-courses"]',BULK_ACTIONS_APPROVE=1,BULK_ACTIONS_DENY=2,SELECTORS_SELECT_REQUEST=".selectrequests",RequestActions=function(){this.registerEvents()};function approveEventWsData(requestId){return{wsfunction:"tool_dataprivacy_approve_data_request",wsparams:{requestid:requestId}}}function denyEventWsData(requestId){return{wsfunction:"tool_dataprivacy_deny_data_request",wsparams:{requestid:requestId}}}function showConfirmation(action,wsdata){var keys=[];switch(action){case DataPrivacyEvents.approve:keys=[{key:"approverequest",component:"tool_dataprivacy"},{key:"confirmapproval",component:"tool_dataprivacy"}];break;case DataPrivacyEvents.bulkApprove:keys=[{key:"bulkapproverequests",component:"tool_dataprivacy"},{key:"confirmbulkapproval",component:"tool_dataprivacy"}];break;case DataPrivacyEvents.deny:keys=[{key:"denyrequest",component:"tool_dataprivacy"},{key:"confirmdenial",component:"tool_dataprivacy"}];break;case DataPrivacyEvents.bulkDeny:keys=[{key:"bulkdenyrequests",component:"tool_dataprivacy"},{key:"confirmbulkdenial",component:"tool_dataprivacy"}];break;case DataPrivacyEvents.complete:keys=[{key:"markcomplete",component:"tool_dataprivacy"},{key:"confirmcompletion",component:"tool_dataprivacy"}]}var modalTitle="";Str.get_strings(keys).then((function(langStrings){modalTitle=langStrings[0];var confirmMessage=langStrings[1];return ModalSaveCancel.create({title:modalTitle,body:confirmMessage})})).then((function(modal){modal.setSaveButtonText(modalTitle),modal.getRoot().on(ModalEvents.save,(function(){handleSave(wsdata.wsfunction,wsdata.wsparams)})),modal.getRoot().on(ModalEvents.hidden,(function(){modal.destroy()})),modal.show()})).catch(Notification.exception)}function handleSave(wsfunction,params){var request={methodname:wsfunction,args:params};Ajax.call([request])[0].done((function(data){data.result?window.location.reload():Notification.addNotification({message:data.warnings[0].message,type:"error"})})).fail(Notification.exception)}return RequestActions.prototype.registerEvents=function(){$(ACTIONS_VIEW_REQUEST).click((function(e){e.preventDefault();var requestId=$(this).data("requestid"),contextId=$(this).data("contextid"),request={methodname:"tool_dataprivacy_get_data_request",args:{requestid:requestId}},promises=Ajax.call([request]);$.when(promises[0]).then((function(data){return data.result?data.result:(Notification.addNotification({message:data.warnings[0].message,type:"error"}),!1)})).then((function(data){var body=Templates.render("tool_dataprivacy/request_details",data),templateContext={approvedeny:data.approvedeny,canmarkcomplete:data.canmarkcomplete,allowfiltering:data.allowfiltering};return ModalDataRequest.create({title:data.typename,body:body,large:!0,templateContext:templateContext})})).then((function(modal){modal.getRoot().on(DataPrivacyEvents.approve,(function(){showConfirmation(DataPrivacyEvents.approve,approveEventWsData(requestId))})),modal.getRoot().on(DataPrivacyEvents.deny,(function(){showConfirmation(DataPrivacyEvents.deny,denyEventWsData(requestId))})),modal.getRoot().on(DataPrivacyEvents.complete,(function(){handleSave("tool_dataprivacy_mark_complete",{requestid:requestId})})),modal.getRoot().on(ModalEvents.hidden,(function(){modal.destroy()})),modal.getRoot().on(DataPrivacyEvents.approveSelectCourses,(function(){new SelectedCourses(contextId,requestId)})),modal.show()})).catch(Notification.exception)})),$(ACTIONS_APPROVE_REQUEST_SELECT_COURSE).click((function(e){e.preventDefault();var requestId=$(this).data("requestid"),contextId=$(this).data("contextid");new SelectedCourses(contextId,requestId)})),$(ACTIONS_APPROVE_REQUEST).click((function(e){e.preventDefault();var requestId=$(this).data("requestid");showConfirmation(DataPrivacyEvents.approve,approveEventWsData(requestId))})),$(ACTIONS_DENY_REQUEST).click((function(e){e.preventDefault();var requestId=$(this).data("requestid");showConfirmation(DataPrivacyEvents.deny,denyEventWsData(requestId))})),$(ACTIONS_MARK_COMPLETE).click((function(e){e.preventDefault();var requestId=$(this).data("requestid");showConfirmation(DataPrivacyEvents.complete,function(requestId){return{wsfunction:"tool_dataprivacy_mark_complete",wsparams:{requestid:requestId}}}(requestId))})),$(ACTIONS_CONFIRM_BULK_ACTION).click((function(){var requestIds=[],actionEvent="",wsdata={},bulkActionKeys=[{key:"selectbulkaction",component:"tool_dataprivacy"},{key:"selectdatarequests",component:"tool_dataprivacy"},{key:"ok"}],bulkaction=parseInt($("#bulk-action").val());if(bulkaction==BULK_ACTIONS_APPROVE||bulkaction==BULK_ACTIONS_DENY)if($(".selectrequests:checked").each((function(){requestIds.push($(this).val())})),requestIds.length<1)Str.get_strings(bulkActionKeys).done((function(langStrings){Notification.alert("",langStrings[1],langStrings[2])})).fail(Notification.exception);else{switch(bulkaction){case BULK_ACTIONS_APPROVE:actionEvent=DataPrivacyEvents.bulkApprove,wsdata=function(requestIds){return{wsfunction:"tool_dataprivacy_bulk_approve_data_requests",wsparams:{requestids:requestIds}}}(requestIds);break;case BULK_ACTIONS_DENY:actionEvent=DataPrivacyEvents.bulkDeny,wsdata=function(requestIds){return{wsfunction:"tool_dataprivacy_bulk_deny_data_requests",wsparams:{requestids:requestIds}}}(requestIds)}showConfirmation(actionEvent,wsdata)}else Str.get_strings(bulkActionKeys).done((function(langStrings){Notification.alert("",langStrings[0],langStrings[2])})).fail(Notification.exception)})),$(ACTIONS_SELECT_ALL).change((function(e){e.preventDefault();var selectAll=$(this).is(":checked");$(SELECTORS_SELECT_REQUEST).prop("checked",selectAll)}))},RequestActions})); //# sourceMappingURL=requestactions.min.js.map \ No newline at end of file diff --git a/admin/tool/dataprivacy/amd/build/requestactions.min.js.map b/admin/tool/dataprivacy/amd/build/requestactions.min.js.map index b890d09131d..1af5964ab61 100644 --- a/admin/tool/dataprivacy/amd/build/requestactions.min.js.map +++ b/admin/tool/dataprivacy/amd/build/requestactions.min.js.map @@ -1 +1 @@ -{"version":3,"file":"requestactions.min.js","sources":["../src/requestactions.js"],"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 * Request actions.\n *\n * @module tool_dataprivacy/requestactions\n * @copyright 2018 Jun Pataleta\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n 'jquery',\n 'core/ajax',\n 'core/notification',\n 'core/str',\n 'core/modal_factory',\n 'core/modal_events',\n 'core/templates',\n 'tool_dataprivacy/data_request_modal',\n 'tool_dataprivacy/events',\n 'tool_dataprivacy/selectedcourses'],\nfunction($, Ajax, Notification, Str, ModalFactory, ModalEvents, Templates, ModalDataRequest, DataPrivacyEvents, SelectedCourses) {\n\n /**\n * List of action selectors.\n *\n * @type {{APPROVE_REQUEST: string}}\n * @type {{DENY_REQUEST: string}}\n * @type {{VIEW_REQUEST: string}}\n * @type {{MARK_COMPLETE: string}}\n * @type {{CHANGE_BULK_ACTION: string}}\n * @type {{CONFIRM_BULK_ACTION: string}}\n * @type {{SELECT_ALL: string}}\n */\n var ACTIONS = {\n APPROVE_REQUEST: '[data-action=\"approve\"]',\n DENY_REQUEST: '[data-action=\"deny\"]',\n VIEW_REQUEST: '[data-action=\"view\"]',\n MARK_COMPLETE: '[data-action=\"complete\"]',\n CHANGE_BULK_ACTION: '[id=\"bulk-action\"]',\n CONFIRM_BULK_ACTION: '[id=\"confirm-bulk-action\"]',\n SELECT_ALL: '[data-action=\"selectall\"]',\n APPROVE_REQUEST_SELECT_COURSE: '[data-action=\"approve-selected-courses\"]',\n };\n\n /**\n * List of available bulk actions.\n *\n * @type {{APPROVE: number}}\n * @type {{DENY: number}}\n */\n var BULK_ACTIONS = {\n APPROVE: 1,\n DENY: 2\n };\n\n /**\n * List of selectors.\n *\n * @type {{SELECT_REQUEST: string}}\n */\n var SELECTORS = {\n SELECT_REQUEST: '.selectrequests'\n };\n\n /**\n * RequestActions class.\n */\n var RequestActions = function() {\n this.registerEvents();\n };\n\n /**\n * Register event listeners.\n */\n RequestActions.prototype.registerEvents = function() {\n $(ACTIONS.VIEW_REQUEST).click(function(e) {\n e.preventDefault();\n\n var requestId = $(this).data('requestid');\n var contextId = $(this).data('contextid');\n\n // Cancel the request.\n var params = {\n 'requestid': requestId\n };\n\n var request = {\n methodname: 'tool_dataprivacy_get_data_request',\n args: params\n };\n\n var promises = Ajax.call([request]);\n $.when(promises[0]).then(function(data) {\n if (data.result) {\n return data.result;\n }\n // Fail.\n Notification.addNotification({\n message: data.warnings[0].message,\n type: 'error'\n });\n return false;\n\n }).then(function(data) {\n var body = Templates.render('tool_dataprivacy/request_details', data);\n var templateContext = {\n approvedeny: data.approvedeny,\n canmarkcomplete: data.canmarkcomplete,\n allowfiltering: data.allowfiltering\n };\n return ModalFactory.create({\n title: data.typename,\n body: body,\n type: ModalDataRequest.TYPE,\n large: true,\n templateContext: templateContext\n });\n\n }).then(function(modal) {\n // Handle approve event.\n modal.getRoot().on(DataPrivacyEvents.approve, function() {\n showConfirmation(DataPrivacyEvents.approve, approveEventWsData(requestId));\n });\n\n // Handle deny event.\n modal.getRoot().on(DataPrivacyEvents.deny, function() {\n showConfirmation(DataPrivacyEvents.deny, denyEventWsData(requestId));\n });\n\n // Handle send event.\n modal.getRoot().on(DataPrivacyEvents.complete, function() {\n var params = {\n 'requestid': requestId\n };\n handleSave('tool_dataprivacy_mark_complete', params);\n });\n\n // Handle hidden event.\n modal.getRoot().on(ModalEvents.hidden, function() {\n // Destroy when hidden.\n modal.destroy();\n });\n\n modal.getRoot().on(DataPrivacyEvents.approveSelectCourses, function() {\n new SelectedCourses(contextId, requestId);\n });\n\n // Show the modal!\n modal.show();\n\n return;\n\n }).catch(Notification.exception);\n });\n\n $(ACTIONS.APPROVE_REQUEST_SELECT_COURSE).click(function(e) {\n e.preventDefault();\n\n var requestId = $(this).data('requestid');\n var contextId = $(this).data('contextid');\n\n new SelectedCourses(contextId, requestId);\n });\n\n $(ACTIONS.APPROVE_REQUEST).click(function(e) {\n e.preventDefault();\n\n var requestId = $(this).data('requestid');\n showConfirmation(DataPrivacyEvents.approve, approveEventWsData(requestId));\n });\n\n $(ACTIONS.DENY_REQUEST).click(function(e) {\n e.preventDefault();\n\n var requestId = $(this).data('requestid');\n showConfirmation(DataPrivacyEvents.deny, denyEventWsData(requestId));\n });\n\n $(ACTIONS.MARK_COMPLETE).click(function(e) {\n e.preventDefault();\n\n var requestId = $(this).data('requestid');\n showConfirmation(DataPrivacyEvents.complete, completeEventWsData(requestId));\n });\n\n $(ACTIONS.CONFIRM_BULK_ACTION).click(function() {\n var requestIds = [];\n var actionEvent = '';\n var wsdata = {};\n var bulkActionKeys = [\n {\n key: 'selectbulkaction',\n component: 'tool_dataprivacy'\n },\n {\n key: 'selectdatarequests',\n component: 'tool_dataprivacy'\n },\n {\n key: 'ok'\n }\n ];\n\n var bulkaction = parseInt($('#bulk-action').val());\n\n if (bulkaction != BULK_ACTIONS.APPROVE && bulkaction != BULK_ACTIONS.DENY) {\n Str.get_strings(bulkActionKeys).done(function(langStrings) {\n Notification.alert('', langStrings[0], langStrings[2]);\n }).fail(Notification.exception);\n\n return;\n }\n\n $(\".selectrequests:checked\").each(function() {\n requestIds.push($(this).val());\n });\n\n if (requestIds.length < 1) {\n Str.get_strings(bulkActionKeys).done(function(langStrings) {\n Notification.alert('', langStrings[1], langStrings[2]);\n }).fail(Notification.exception);\n\n return;\n }\n\n switch (bulkaction) {\n case BULK_ACTIONS.APPROVE:\n actionEvent = DataPrivacyEvents.bulkApprove;\n wsdata = bulkApproveEventWsData(requestIds);\n break;\n case BULK_ACTIONS.DENY:\n actionEvent = DataPrivacyEvents.bulkDeny;\n wsdata = bulkDenyEventWsData(requestIds);\n }\n\n showConfirmation(actionEvent, wsdata);\n });\n\n $(ACTIONS.SELECT_ALL).change(function(e) {\n e.preventDefault();\n\n var selectAll = $(this).is(':checked');\n $(SELECTORS.SELECT_REQUEST).prop('checked', selectAll);\n });\n };\n\n /**\n * Return the webservice data for the approve request action.\n *\n * @param {Number} requestId The ID of the request.\n * @return {Object}\n */\n function approveEventWsData(requestId) {\n return {\n 'wsfunction': 'tool_dataprivacy_approve_data_request',\n 'wsparams': {'requestid': requestId}\n };\n }\n\n /**\n * Return the webservice data for the bulk approve request action.\n *\n * @param {Array} requestIds The array of request ID's.\n * @return {Object}\n */\n function bulkApproveEventWsData(requestIds) {\n return {\n 'wsfunction': 'tool_dataprivacy_bulk_approve_data_requests',\n 'wsparams': {'requestids': requestIds}\n };\n }\n\n /**\n * Return the webservice data for the deny request action.\n *\n * @param {Number} requestId The ID of the request.\n * @return {Object}\n */\n function denyEventWsData(requestId) {\n return {\n 'wsfunction': 'tool_dataprivacy_deny_data_request',\n 'wsparams': {'requestid': requestId}\n };\n }\n\n /**\n * Return the webservice data for the bulk deny request action.\n *\n * @param {Array} requestIds The array of request ID's.\n * @return {Object}\n */\n function bulkDenyEventWsData(requestIds) {\n return {\n 'wsfunction': 'tool_dataprivacy_bulk_deny_data_requests',\n 'wsparams': {'requestids': requestIds}\n };\n }\n\n /**\n * Return the webservice data for the complete request action.\n *\n * @param {Number} requestId The ID of the request.\n * @return {Object}\n */\n function completeEventWsData(requestId) {\n return {\n 'wsfunction': 'tool_dataprivacy_mark_complete',\n 'wsparams': {'requestid': requestId}\n };\n }\n\n /**\n * Show the confirmation dialogue.\n *\n * @param {String} action The action name.\n * @param {Object} wsdata Object containing ws data.\n */\n function showConfirmation(action, wsdata) {\n var keys = [];\n\n switch (action) {\n case DataPrivacyEvents.approve:\n keys = [\n {\n key: 'approverequest',\n component: 'tool_dataprivacy'\n },\n {\n key: 'confirmapproval',\n component: 'tool_dataprivacy'\n }\n ];\n break;\n case DataPrivacyEvents.bulkApprove:\n keys = [\n {\n key: 'bulkapproverequests',\n component: 'tool_dataprivacy'\n },\n {\n key: 'confirmbulkapproval',\n component: 'tool_dataprivacy'\n }\n ];\n break;\n case DataPrivacyEvents.deny:\n keys = [\n {\n key: 'denyrequest',\n component: 'tool_dataprivacy'\n },\n {\n key: 'confirmdenial',\n component: 'tool_dataprivacy'\n }\n ];\n break;\n case DataPrivacyEvents.bulkDeny:\n keys = [\n {\n key: 'bulkdenyrequests',\n component: 'tool_dataprivacy'\n },\n {\n key: 'confirmbulkdenial',\n component: 'tool_dataprivacy'\n }\n ];\n break;\n case DataPrivacyEvents.complete:\n keys = [\n {\n key: 'markcomplete',\n component: 'tool_dataprivacy'\n },\n {\n key: 'confirmcompletion',\n component: 'tool_dataprivacy'\n }\n ];\n break;\n }\n\n var modalTitle = '';\n Str.get_strings(keys).then(function(langStrings) {\n modalTitle = langStrings[0];\n var confirmMessage = langStrings[1];\n return ModalFactory.create({\n title: modalTitle,\n body: confirmMessage,\n type: ModalFactory.types.SAVE_CANCEL\n });\n }).then(function(modal) {\n modal.setSaveButtonText(modalTitle);\n\n // Handle save event.\n modal.getRoot().on(ModalEvents.save, function() {\n handleSave(wsdata.wsfunction, wsdata.wsparams);\n });\n\n // Handle hidden event.\n modal.getRoot().on(ModalEvents.hidden, function() {\n // Destroy when hidden.\n modal.destroy();\n });\n\n modal.show();\n\n return;\n\n }).catch(Notification.exception);\n }\n\n /**\n * Calls a web service function and reloads the page on success and shows a notification.\n * Displays an error notification, otherwise.\n *\n * @param {String} wsfunction The web service function to call.\n * @param {Object} params The parameters for the web service functoon.\n */\n function handleSave(wsfunction, params) {\n // Confirm the request.\n var request = {\n methodname: wsfunction,\n args: params\n };\n\n Ajax.call([request])[0].done(function(data) {\n if (data.result) {\n // On success, reload the page so that the data request table will be updated.\n // TODO: Probably in the future, better to reload the table or the target data request via AJAX.\n window.location.reload();\n } else {\n // Add the notification.\n Notification.addNotification({\n message: data.warnings[0].message,\n type: 'error'\n });\n }\n }).fail(Notification.exception);\n }\n\n return RequestActions;\n});\n"],"names":["define","$","Ajax","Notification","Str","ModalFactory","ModalEvents","Templates","ModalDataRequest","DataPrivacyEvents","SelectedCourses","ACTIONS","BULK_ACTIONS","SELECTORS","RequestActions","registerEvents","approveEventWsData","requestId","denyEventWsData","showConfirmation","action","wsdata","keys","approve","key","component","bulkApprove","deny","bulkDeny","complete","modalTitle","get_strings","then","langStrings","confirmMessage","create","title","body","type","types","SAVE_CANCEL","modal","setSaveButtonText","getRoot","on","save","handleSave","wsfunction","wsparams","hidden","destroy","show","catch","exception","params","request","methodname","args","call","done","data","result","window","location","reload","addNotification","message","warnings","fail","prototype","click","e","preventDefault","this","contextId","promises","when","render","templateContext","approvedeny","canmarkcomplete","allowfiltering","typename","TYPE","large","approveSelectCourses","completeEventWsData","requestIds","actionEvent","bulkActionKeys","bulkaction","parseInt","val","each","push","length","alert","bulkApproveEventWsData","bulkDenyEventWsData","change","selectAll","is","prop"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"requestactions.min.js","sources":["../src/requestactions.js"],"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 * Request actions.\n *\n * @module tool_dataprivacy/requestactions\n * @copyright 2018 Jun Pataleta\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n 'jquery',\n 'core/ajax',\n 'core/notification',\n 'core/str',\n 'core/modal_save_cancel',\n 'core/modal_events',\n 'core/templates',\n 'tool_dataprivacy/data_request_modal',\n 'tool_dataprivacy/events',\n 'tool_dataprivacy/selectedcourses'\n], function(\n $, Ajax, Notification, Str, ModalSaveCancel, ModalEvents, Templates, ModalDataRequest, DataPrivacyEvents, SelectedCourses\n) {\n\n /**\n * List of action selectors.\n *\n * @type {{APPROVE_REQUEST: string}}\n * @type {{DENY_REQUEST: string}}\n * @type {{VIEW_REQUEST: string}}\n * @type {{MARK_COMPLETE: string}}\n * @type {{CHANGE_BULK_ACTION: string}}\n * @type {{CONFIRM_BULK_ACTION: string}}\n * @type {{SELECT_ALL: string}}\n */\n var ACTIONS = {\n APPROVE_REQUEST: '[data-action=\"approve\"]',\n DENY_REQUEST: '[data-action=\"deny\"]',\n VIEW_REQUEST: '[data-action=\"view\"]',\n MARK_COMPLETE: '[data-action=\"complete\"]',\n CHANGE_BULK_ACTION: '[id=\"bulk-action\"]',\n CONFIRM_BULK_ACTION: '[id=\"confirm-bulk-action\"]',\n SELECT_ALL: '[data-action=\"selectall\"]',\n APPROVE_REQUEST_SELECT_COURSE: '[data-action=\"approve-selected-courses\"]',\n };\n\n /**\n * List of available bulk actions.\n *\n * @type {{APPROVE: number}}\n * @type {{DENY: number}}\n */\n var BULK_ACTIONS = {\n APPROVE: 1,\n DENY: 2\n };\n\n /**\n * List of selectors.\n *\n * @type {{SELECT_REQUEST: string}}\n */\n var SELECTORS = {\n SELECT_REQUEST: '.selectrequests'\n };\n\n /**\n * RequestActions class.\n */\n var RequestActions = function() {\n this.registerEvents();\n };\n\n /**\n * Register event listeners.\n */\n RequestActions.prototype.registerEvents = function() {\n $(ACTIONS.VIEW_REQUEST).click(function(e) {\n e.preventDefault();\n\n var requestId = $(this).data('requestid');\n var contextId = $(this).data('contextid');\n\n // Cancel the request.\n var params = {\n 'requestid': requestId\n };\n\n var request = {\n methodname: 'tool_dataprivacy_get_data_request',\n args: params\n };\n\n var promises = Ajax.call([request]);\n $.when(promises[0]).then(function(data) {\n if (data.result) {\n return data.result;\n }\n // Fail.\n Notification.addNotification({\n message: data.warnings[0].message,\n type: 'error'\n });\n return false;\n\n }).then(function(data) {\n var body = Templates.render('tool_dataprivacy/request_details', data);\n var templateContext = {\n approvedeny: data.approvedeny,\n canmarkcomplete: data.canmarkcomplete,\n allowfiltering: data.allowfiltering\n };\n return ModalDataRequest.create({\n title: data.typename,\n body: body,\n large: true,\n templateContext: templateContext\n });\n\n }).then(function(modal) {\n // Handle approve event.\n modal.getRoot().on(DataPrivacyEvents.approve, function() {\n showConfirmation(DataPrivacyEvents.approve, approveEventWsData(requestId));\n });\n\n // Handle deny event.\n modal.getRoot().on(DataPrivacyEvents.deny, function() {\n showConfirmation(DataPrivacyEvents.deny, denyEventWsData(requestId));\n });\n\n // Handle send event.\n modal.getRoot().on(DataPrivacyEvents.complete, function() {\n var params = {\n 'requestid': requestId\n };\n handleSave('tool_dataprivacy_mark_complete', params);\n });\n\n // Handle hidden event.\n modal.getRoot().on(ModalEvents.hidden, function() {\n // Destroy when hidden.\n modal.destroy();\n });\n\n modal.getRoot().on(DataPrivacyEvents.approveSelectCourses, function() {\n new SelectedCourses(contextId, requestId);\n });\n\n // Show the modal!\n modal.show();\n\n return;\n\n }).catch(Notification.exception);\n });\n\n $(ACTIONS.APPROVE_REQUEST_SELECT_COURSE).click(function(e) {\n e.preventDefault();\n\n var requestId = $(this).data('requestid');\n var contextId = $(this).data('contextid');\n\n new SelectedCourses(contextId, requestId);\n });\n\n $(ACTIONS.APPROVE_REQUEST).click(function(e) {\n e.preventDefault();\n\n var requestId = $(this).data('requestid');\n showConfirmation(DataPrivacyEvents.approve, approveEventWsData(requestId));\n });\n\n $(ACTIONS.DENY_REQUEST).click(function(e) {\n e.preventDefault();\n\n var requestId = $(this).data('requestid');\n showConfirmation(DataPrivacyEvents.deny, denyEventWsData(requestId));\n });\n\n $(ACTIONS.MARK_COMPLETE).click(function(e) {\n e.preventDefault();\n\n var requestId = $(this).data('requestid');\n showConfirmation(DataPrivacyEvents.complete, completeEventWsData(requestId));\n });\n\n $(ACTIONS.CONFIRM_BULK_ACTION).click(function() {\n var requestIds = [];\n var actionEvent = '';\n var wsdata = {};\n var bulkActionKeys = [\n {\n key: 'selectbulkaction',\n component: 'tool_dataprivacy'\n },\n {\n key: 'selectdatarequests',\n component: 'tool_dataprivacy'\n },\n {\n key: 'ok'\n }\n ];\n\n var bulkaction = parseInt($('#bulk-action').val());\n\n if (bulkaction != BULK_ACTIONS.APPROVE && bulkaction != BULK_ACTIONS.DENY) {\n Str.get_strings(bulkActionKeys).done(function(langStrings) {\n Notification.alert('', langStrings[0], langStrings[2]);\n }).fail(Notification.exception);\n\n return;\n }\n\n $(\".selectrequests:checked\").each(function() {\n requestIds.push($(this).val());\n });\n\n if (requestIds.length < 1) {\n Str.get_strings(bulkActionKeys).done(function(langStrings) {\n Notification.alert('', langStrings[1], langStrings[2]);\n }).fail(Notification.exception);\n\n return;\n }\n\n switch (bulkaction) {\n case BULK_ACTIONS.APPROVE:\n actionEvent = DataPrivacyEvents.bulkApprove;\n wsdata = bulkApproveEventWsData(requestIds);\n break;\n case BULK_ACTIONS.DENY:\n actionEvent = DataPrivacyEvents.bulkDeny;\n wsdata = bulkDenyEventWsData(requestIds);\n }\n\n showConfirmation(actionEvent, wsdata);\n });\n\n $(ACTIONS.SELECT_ALL).change(function(e) {\n e.preventDefault();\n\n var selectAll = $(this).is(':checked');\n $(SELECTORS.SELECT_REQUEST).prop('checked', selectAll);\n });\n };\n\n /**\n * Return the webservice data for the approve request action.\n *\n * @param {Number} requestId The ID of the request.\n * @return {Object}\n */\n function approveEventWsData(requestId) {\n return {\n 'wsfunction': 'tool_dataprivacy_approve_data_request',\n 'wsparams': {'requestid': requestId}\n };\n }\n\n /**\n * Return the webservice data for the bulk approve request action.\n *\n * @param {Array} requestIds The array of request ID's.\n * @return {Object}\n */\n function bulkApproveEventWsData(requestIds) {\n return {\n 'wsfunction': 'tool_dataprivacy_bulk_approve_data_requests',\n 'wsparams': {'requestids': requestIds}\n };\n }\n\n /**\n * Return the webservice data for the deny request action.\n *\n * @param {Number} requestId The ID of the request.\n * @return {Object}\n */\n function denyEventWsData(requestId) {\n return {\n 'wsfunction': 'tool_dataprivacy_deny_data_request',\n 'wsparams': {'requestid': requestId}\n };\n }\n\n /**\n * Return the webservice data for the bulk deny request action.\n *\n * @param {Array} requestIds The array of request ID's.\n * @return {Object}\n */\n function bulkDenyEventWsData(requestIds) {\n return {\n 'wsfunction': 'tool_dataprivacy_bulk_deny_data_requests',\n 'wsparams': {'requestids': requestIds}\n };\n }\n\n /**\n * Return the webservice data for the complete request action.\n *\n * @param {Number} requestId The ID of the request.\n * @return {Object}\n */\n function completeEventWsData(requestId) {\n return {\n 'wsfunction': 'tool_dataprivacy_mark_complete',\n 'wsparams': {'requestid': requestId}\n };\n }\n\n /**\n * Show the confirmation dialogue.\n *\n * @param {String} action The action name.\n * @param {Object} wsdata Object containing ws data.\n */\n function showConfirmation(action, wsdata) {\n var keys = [];\n\n switch (action) {\n case DataPrivacyEvents.approve:\n keys = [\n {\n key: 'approverequest',\n component: 'tool_dataprivacy'\n },\n {\n key: 'confirmapproval',\n component: 'tool_dataprivacy'\n }\n ];\n break;\n case DataPrivacyEvents.bulkApprove:\n keys = [\n {\n key: 'bulkapproverequests',\n component: 'tool_dataprivacy'\n },\n {\n key: 'confirmbulkapproval',\n component: 'tool_dataprivacy'\n }\n ];\n break;\n case DataPrivacyEvents.deny:\n keys = [\n {\n key: 'denyrequest',\n component: 'tool_dataprivacy'\n },\n {\n key: 'confirmdenial',\n component: 'tool_dataprivacy'\n }\n ];\n break;\n case DataPrivacyEvents.bulkDeny:\n keys = [\n {\n key: 'bulkdenyrequests',\n component: 'tool_dataprivacy'\n },\n {\n key: 'confirmbulkdenial',\n component: 'tool_dataprivacy'\n }\n ];\n break;\n case DataPrivacyEvents.complete:\n keys = [\n {\n key: 'markcomplete',\n component: 'tool_dataprivacy'\n },\n {\n key: 'confirmcompletion',\n component: 'tool_dataprivacy'\n }\n ];\n break;\n }\n\n var modalTitle = '';\n Str.get_strings(keys).then(function(langStrings) {\n modalTitle = langStrings[0];\n var confirmMessage = langStrings[1];\n return ModalSaveCancel.create({\n title: modalTitle,\n body: confirmMessage,\n });\n }).then(function(modal) {\n modal.setSaveButtonText(modalTitle);\n\n // Handle save event.\n modal.getRoot().on(ModalEvents.save, function() {\n handleSave(wsdata.wsfunction, wsdata.wsparams);\n });\n\n // Handle hidden event.\n modal.getRoot().on(ModalEvents.hidden, function() {\n // Destroy when hidden.\n modal.destroy();\n });\n\n modal.show();\n\n return;\n\n }).catch(Notification.exception);\n }\n\n /**\n * Calls a web service function and reloads the page on success and shows a notification.\n * Displays an error notification, otherwise.\n *\n * @param {String} wsfunction The web service function to call.\n * @param {Object} params The parameters for the web service functoon.\n */\n function handleSave(wsfunction, params) {\n // Confirm the request.\n var request = {\n methodname: wsfunction,\n args: params\n };\n\n Ajax.call([request])[0].done(function(data) {\n if (data.result) {\n // On success, reload the page so that the data request table will be updated.\n // TODO: Probably in the future, better to reload the table or the target data request via AJAX.\n window.location.reload();\n } else {\n // Add the notification.\n Notification.addNotification({\n message: data.warnings[0].message,\n type: 'error'\n });\n }\n }).fail(Notification.exception);\n }\n\n return RequestActions;\n});\n"],"names":["define","$","Ajax","Notification","Str","ModalSaveCancel","ModalEvents","Templates","ModalDataRequest","DataPrivacyEvents","SelectedCourses","ACTIONS","BULK_ACTIONS","SELECTORS","RequestActions","registerEvents","approveEventWsData","requestId","denyEventWsData","showConfirmation","action","wsdata","keys","approve","key","component","bulkApprove","deny","bulkDeny","complete","modalTitle","get_strings","then","langStrings","confirmMessage","create","title","body","modal","setSaveButtonText","getRoot","on","save","handleSave","wsfunction","wsparams","hidden","destroy","show","catch","exception","params","request","methodname","args","call","done","data","result","window","location","reload","addNotification","message","warnings","type","fail","prototype","click","e","preventDefault","this","contextId","promises","when","render","templateContext","approvedeny","canmarkcomplete","allowfiltering","typename","large","approveSelectCourses","completeEventWsData","requestIds","actionEvent","bulkActionKeys","bulkaction","parseInt","val","each","push","length","alert","bulkApproveEventWsData","bulkDenyEventWsData","change","selectAll","is","prop"],"mappings":"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"} \ No newline at end of file diff --git a/admin/tool/dataprivacy/amd/build/selectedcourses.min.js b/admin/tool/dataprivacy/amd/build/selectedcourses.min.js index bce8782921f..7d830948aaf 100644 --- a/admin/tool/dataprivacy/amd/build/selectedcourses.min.js +++ b/admin/tool/dataprivacy/amd/build/selectedcourses.min.js @@ -1,3 +1,3 @@ -define("tool_dataprivacy/selectedcourses",["exports","core/ajax","core/notification","core/modal_factory","core/modal_events","core/fragment","core/prefetch","core/str"],(function(_exports,_ajax,_notification,_modal_factory,_modal_events,_fragment,_prefetch,_str){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _defineProperty(obj,key,value){return key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_ajax=_interopRequireDefault(_ajax),_notification=_interopRequireDefault(_notification),_modal_factory=_interopRequireDefault(_modal_factory),_modal_events=_interopRequireDefault(_modal_events),_fragment=_interopRequireDefault(_fragment),(0,_prefetch.prefetchStrings)("tool_dataprivacy",["selectcourses","approverequest","errornoselectedcourse"]);return _exports.default=class{constructor(contextId,requestId){_defineProperty(this,"contextId",0),_defineProperty(this,"requestId",0),this.contextId=contextId,this.requestId=requestId,_modal_factory.default.create({type:_modal_factory.default.types.SAVE_CANCEL,title:(0,_str.getString)("selectcourses","tool_dataprivacy"),body:this.getBody({requestid:requestId}),large:!0,removeOnClose:!0,buttons:{save:(0,_str.getString)("approverequest","tool_dataprivacy")}}).then((modal=>(this.modal=modal,modal))).then((modal=>(modal.getRoot().on(_modal_events.default.save,this.submitForm.bind(this)),modal.getRoot().on("submit","form",this.submitFormAjax.bind(this)),modal.show(),modal))).catch(_notification.default.exception)}getBody(formdata){const params=formdata?{jsonformdata:JSON.stringify(formdata)}:null;return _fragment.default.loadFragment("tool_dataprivacy","selectcourses_form",this.contextId,params)}submitForm(e){e.preventDefault(),this.modal.getRoot().find("form").submit()}submitFormAjax(e){e.preventDefault();let formData=this.modal.getRoot().find("form").serialize();if(-1===formData.indexOf("coursecontextids")){const customSelect=this.modal.getRoot().find(".custom-select"),invalidText=this.modal.getRoot().find(".invalid-feedback");return customSelect.addClass("is-invalid"),invalidText.attr("style","display: block"),void(0,_str.getString)("errornoselectedcourse","tool_dataprivacy").then((value=>{invalidText.empty().append(value)})).catch(_notification.default.exception)}_ajax.default.call([{methodname:"tool_dataprivacy_submit_selected_courses_form",args:{requestid:this.requestId,jsonformdata:JSON.stringify(formData)}}])[0].then((data=>(data.warnings.length>0?this.modal.setBody(this.getBody(formData)):(this.modal.destroy(),document.location.reload()),data))).catch((error=>_notification.default.exception(error)))}},_exports.default})); +define("tool_dataprivacy/selectedcourses",["exports","core/ajax","core/notification","core/modal_save_cancel","core/modal_events","core/fragment","core/prefetch","core/str"],(function(_exports,_ajax,_notification,_modal_save_cancel,_modal_events,_fragment,_prefetch,_str){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _defineProperty(obj,key,value){return key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_ajax=_interopRequireDefault(_ajax),_notification=_interopRequireDefault(_notification),_modal_save_cancel=_interopRequireDefault(_modal_save_cancel),_modal_events=_interopRequireDefault(_modal_events),_fragment=_interopRequireDefault(_fragment),(0,_prefetch.prefetchStrings)("tool_dataprivacy",["selectcourses","approverequest","errornoselectedcourse"]);return _exports.default=class{constructor(contextId,requestId){_defineProperty(this,"contextId",0),_defineProperty(this,"requestId",0),this.contextId=contextId,this.requestId=requestId,_modal_save_cancel.default.create({title:(0,_str.getString)("selectcourses","tool_dataprivacy"),body:this.getBody({requestid:requestId}),large:!0,removeOnClose:!0,buttons:{save:(0,_str.getString)("approverequest","tool_dataprivacy")}}).then((modal=>(this.modal=modal,modal))).then((modal=>(modal.getRoot().on(_modal_events.default.save,this.submitForm.bind(this)),modal.getRoot().on("submit","form",this.submitFormAjax.bind(this)),modal.show(),modal))).catch(_notification.default.exception)}getBody(formdata){const params=formdata?{jsonformdata:JSON.stringify(formdata)}:null;return _fragment.default.loadFragment("tool_dataprivacy","selectcourses_form",this.contextId,params)}submitForm(e){e.preventDefault(),this.modal.getRoot().find("form").submit()}submitFormAjax(e){e.preventDefault();let formData=this.modal.getRoot().find("form").serialize();if(-1===formData.indexOf("coursecontextids")){const customSelect=this.modal.getRoot().find(".custom-select"),invalidText=this.modal.getRoot().find(".invalid-feedback");return customSelect.addClass("is-invalid"),invalidText.attr("style","display: block"),void(0,_str.getString)("errornoselectedcourse","tool_dataprivacy").then((value=>{invalidText.empty().append(value)})).catch(_notification.default.exception)}_ajax.default.call([{methodname:"tool_dataprivacy_submit_selected_courses_form",args:{requestid:this.requestId,jsonformdata:JSON.stringify(formData)}}])[0].then((data=>(data.warnings.length>0?this.modal.setBody(this.getBody(formData)):(this.modal.destroy(),document.location.reload()),data))).catch((error=>_notification.default.exception(error)))}},_exports.default})); //# sourceMappingURL=selectedcourses.min.js.map \ No newline at end of file diff --git a/admin/tool/dataprivacy/amd/build/selectedcourses.min.js.map b/admin/tool/dataprivacy/amd/build/selectedcourses.min.js.map index e2833445b3d..2721c92edbc 100644 --- a/admin/tool/dataprivacy/amd/build/selectedcourses.min.js.map +++ b/admin/tool/dataprivacy/amd/build/selectedcourses.min.js.map @@ -1 +1 @@ -{"version":3,"file":"selectedcourses.min.js","sources":["../src/selectedcourses.js"],"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 * Selected courses.\n *\n * @module tool_dataprivacy/selectedcourses\n * @copyright 2021 The Open University\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since Moodle 4.3\n */\n\nimport Ajax from 'core/ajax';\nimport Notification from 'core/notification';\nimport ModalFactory from 'core/modal_factory';\nimport ModalEvents from 'core/modal_events';\nimport Fragment from 'core/fragment';\nimport {prefetchStrings} from 'core/prefetch';\nimport {getString} from 'core/str';\n\nprefetchStrings('tool_dataprivacy', [\n 'selectcourses',\n 'approverequest',\n 'errornoselectedcourse',\n]);\n\n/**\n * Selected Courses popup modal.\n *\n */\nexport default class SelectedCourses {\n /**\n * @var {String} contextId Context ID to load the fragment.\n * @private\n */\n contextId = 0;\n\n /**\n * @var {String} requestId ID of data export request.\n * @private\n */\n requestId = 0;\n\n /**\n * Constructor\n *\n * @param {String} contextId Context ID to load the fragment.\n * @param {String} requestId ID of data export request.\n */\n constructor(contextId, requestId) {\n this.contextId = contextId;\n this.requestId = requestId;\n // Now create the modal.\n ModalFactory.create({\n type: ModalFactory.types.SAVE_CANCEL,\n title: getString('selectcourses', 'tool_dataprivacy'),\n body: this.getBody({requestid: requestId}),\n large: true,\n removeOnClose: true,\n buttons: {\n save: getString('approverequest', 'tool_dataprivacy'),\n },\n }).then((modal) => {\n this.modal = modal;\n\n return modal;\n }).then((modal) => {\n // We catch the modal save event, and use it to submit the form inside the modal.\n // Triggering a form submission will give JS validation scripts a chance to check for errors.\n modal.getRoot().on(ModalEvents.save, this.submitForm.bind(this));\n\n // We also catch the form submit event and use it to submit the form with ajax.\n modal.getRoot().on('submit', 'form', this.submitFormAjax.bind(this));\n modal.show();\n return modal;\n }).catch(Notification.exception);\n }\n\n /**\n * Get body of modal.\n *\n * @method getBody\n * @param {Object} formdata\n * @private\n * @return {Promise}\n */\n getBody(formdata) {\n const params = formdata ? {jsonformdata: JSON.stringify(formdata)} : null;\n\n // Get the content of the modal.\n return Fragment.loadFragment('tool_dataprivacy', 'selectcourses_form', this.contextId, params);\n }\n\n /**\n * This triggers a form submission, so that any mform elements can do final tricks before the form submission is processed.\n *\n * @method submitForm\n * @param {Event} e Form submission event.\n * @private\n */\n submitForm(e) {\n e.preventDefault();\n this.modal.getRoot().find('form').submit();\n }\n\n /**\n * Submit select courses form using ajax.\n *\n * @method submitFormAjax\n * @private\n * @param {Event} e Form submission event.\n */\n submitFormAjax(e) {\n e.preventDefault();\n\n // Convert all the form elements values to a serialised string.\n let formData = this.modal.getRoot().find('form').serialize();\n\n if (formData.indexOf('coursecontextids') === -1) {\n const customSelect = this.modal.getRoot().find('.custom-select');\n const invalidText = this.modal.getRoot().find('.invalid-feedback');\n customSelect.addClass('is-invalid');\n invalidText.attr('style', 'display: block');\n getString('errornoselectedcourse', 'tool_dataprivacy').then(value => {\n invalidText.empty().append(value);\n return;\n }).catch(Notification.exception);\n return;\n }\n\n Ajax.call([{\n methodname: 'tool_dataprivacy_submit_selected_courses_form',\n args: {requestid: this.requestId, jsonformdata: JSON.stringify(formData)},\n }])[0]\n .then((data) => {\n if (data.warnings.length > 0) {\n this.modal.setBody(this.getBody(formData));\n } else {\n this.modal.destroy();\n document.location.reload();\n }\n return data;\n })\n .catch((error) => Notification.exception(error));\n }\n}\n"],"names":["constructor","contextId","requestId","create","type","ModalFactory","types","SAVE_CANCEL","title","body","this","getBody","requestid","large","removeOnClose","buttons","save","then","modal","getRoot","on","ModalEvents","submitForm","bind","submitFormAjax","show","catch","Notification","exception","formdata","params","jsonformdata","JSON","stringify","Fragment","loadFragment","e","preventDefault","find","submit","formData","serialize","indexOf","customSelect","invalidText","addClass","attr","value","empty","append","call","methodname","args","data","warnings","length","setBody","destroy","document","location","reload","error"],"mappings":"01BAgCgB,mBAAoB,CAChC,gBACA,iBACA,wDA0BAA,YAAYC,UAAWC,4CAdX,oCAMA,QASHD,UAAYA,eACZC,UAAYA,iCAEJC,OAAO,CAChBC,KAAMC,uBAAaC,MAAMC,YACzBC,OAAO,kBAAU,gBAAiB,oBAClCC,KAAMC,KAAKC,QAAQ,CAACC,UAAWV,YAC/BW,OAAO,EACPC,eAAe,EACfC,QAAS,CACLC,MAAM,kBAAU,iBAAkB,uBAEvCC,MAAMC,aACAA,MAAQA,MAENA,SACRD,MAAMC,QAGLA,MAAMC,UAAUC,GAAGC,sBAAYL,KAAMN,KAAKY,WAAWC,KAAKb,OAG1DQ,MAAMC,UAAUC,GAAG,SAAU,OAAQV,KAAKc,eAAeD,KAAKb,OAC9DQ,MAAMO,OACCP,SACRQ,MAAMC,sBAAaC,WAW1BjB,QAAQkB,gBACEC,OAASD,SAAW,CAACE,aAAcC,KAAKC,UAAUJ,WAAa,YAG9DK,kBAASC,aAAa,mBAAoB,qBAAsBzB,KAAKT,UAAW6B,QAU3FR,WAAWc,GACPA,EAAEC,sBACGnB,MAAMC,UAAUmB,KAAK,QAAQC,SAUtCf,eAAeY,GACXA,EAAEC,qBAGEG,SAAW9B,KAAKQ,MAAMC,UAAUmB,KAAK,QAAQG,gBAEH,IAA1CD,SAASE,QAAQ,oBAA4B,OACvCC,aAAejC,KAAKQ,MAAMC,UAAUmB,KAAK,kBACzCM,YAAclC,KAAKQ,MAAMC,UAAUmB,KAAK,4BAC9CK,aAAaE,SAAS,cACtBD,YAAYE,KAAK,QAAS,yCAChB,wBAAyB,oBAAoB7B,MAAK8B,QACxDH,YAAYI,QAAQC,OAAOF,UAE5BrB,MAAMC,sBAAaC,yBAIrBsB,KAAK,CAAC,CACPC,WAAY,gDACZC,KAAM,CAACxC,UAAWF,KAAKR,UAAW6B,aAAcC,KAAKC,UAAUO,cAC/D,GACHvB,MAAMoC,OACCA,KAAKC,SAASC,OAAS,OAClBrC,MAAMsC,QAAQ9C,KAAKC,QAAQ6B,iBAE3BtB,MAAMuC,UACXC,SAASC,SAASC,UAEfP,QAEV3B,OAAOmC,OAAUlC,sBAAaC,UAAUiC"} \ No newline at end of file +{"version":3,"file":"selectedcourses.min.js","sources":["../src/selectedcourses.js"],"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 * Selected courses.\n *\n * @module tool_dataprivacy/selectedcourses\n * @copyright 2021 The Open University\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since Moodle 4.3\n */\n\nimport Ajax from 'core/ajax';\nimport Notification from 'core/notification';\nimport ModalSaveCancel from 'core/modal_save_cancel';\nimport ModalEvents from 'core/modal_events';\nimport Fragment from 'core/fragment';\nimport {prefetchStrings} from 'core/prefetch';\nimport {getString} from 'core/str';\n\nprefetchStrings('tool_dataprivacy', [\n 'selectcourses',\n 'approverequest',\n 'errornoselectedcourse',\n]);\n\n/**\n * Selected Courses popup modal.\n *\n */\nexport default class SelectedCourses {\n /**\n * @var {String} contextId Context ID to load the fragment.\n * @private\n */\n contextId = 0;\n\n /**\n * @var {String} requestId ID of data export request.\n * @private\n */\n requestId = 0;\n\n /**\n * Constructor\n *\n * @param {String} contextId Context ID to load the fragment.\n * @param {String} requestId ID of data export request.\n */\n constructor(contextId, requestId) {\n this.contextId = contextId;\n this.requestId = requestId;\n // Now create the modal.\n ModalSaveCancel.create({\n title: getString('selectcourses', 'tool_dataprivacy'),\n body: this.getBody({requestid: requestId}),\n large: true,\n removeOnClose: true,\n buttons: {\n save: getString('approverequest', 'tool_dataprivacy'),\n },\n }).then((modal) => {\n this.modal = modal;\n\n return modal;\n }).then((modal) => {\n // We catch the modal save event, and use it to submit the form inside the modal.\n // Triggering a form submission will give JS validation scripts a chance to check for errors.\n modal.getRoot().on(ModalEvents.save, this.submitForm.bind(this));\n\n // We also catch the form submit event and use it to submit the form with ajax.\n modal.getRoot().on('submit', 'form', this.submitFormAjax.bind(this));\n modal.show();\n return modal;\n }).catch(Notification.exception);\n }\n\n /**\n * Get body of modal.\n *\n * @method getBody\n * @param {Object} formdata\n * @private\n * @return {Promise}\n */\n getBody(formdata) {\n const params = formdata ? {jsonformdata: JSON.stringify(formdata)} : null;\n\n // Get the content of the modal.\n return Fragment.loadFragment('tool_dataprivacy', 'selectcourses_form', this.contextId, params);\n }\n\n /**\n * This triggers a form submission, so that any mform elements can do final tricks before the form submission is processed.\n *\n * @method submitForm\n * @param {Event} e Form submission event.\n * @private\n */\n submitForm(e) {\n e.preventDefault();\n this.modal.getRoot().find('form').submit();\n }\n\n /**\n * Submit select courses form using ajax.\n *\n * @method submitFormAjax\n * @private\n * @param {Event} e Form submission event.\n */\n submitFormAjax(e) {\n e.preventDefault();\n\n // Convert all the form elements values to a serialised string.\n let formData = this.modal.getRoot().find('form').serialize();\n\n if (formData.indexOf('coursecontextids') === -1) {\n const customSelect = this.modal.getRoot().find('.custom-select');\n const invalidText = this.modal.getRoot().find('.invalid-feedback');\n customSelect.addClass('is-invalid');\n invalidText.attr('style', 'display: block');\n getString('errornoselectedcourse', 'tool_dataprivacy').then(value => {\n invalidText.empty().append(value);\n return;\n }).catch(Notification.exception);\n return;\n }\n\n Ajax.call([{\n methodname: 'tool_dataprivacy_submit_selected_courses_form',\n args: {requestid: this.requestId, jsonformdata: JSON.stringify(formData)},\n }])[0]\n .then((data) => {\n if (data.warnings.length > 0) {\n this.modal.setBody(this.getBody(formData));\n } else {\n this.modal.destroy();\n document.location.reload();\n }\n return data;\n })\n .catch((error) => Notification.exception(error));\n }\n}\n"],"names":["constructor","contextId","requestId","create","title","body","this","getBody","requestid","large","removeOnClose","buttons","save","then","modal","getRoot","on","ModalEvents","submitForm","bind","submitFormAjax","show","catch","Notification","exception","formdata","params","jsonformdata","JSON","stringify","Fragment","loadFragment","e","preventDefault","find","submit","formData","serialize","indexOf","customSelect","invalidText","addClass","attr","value","empty","append","call","methodname","args","data","warnings","length","setBody","destroy","document","location","reload","error"],"mappings":"02BAgCgB,mBAAoB,CAChC,gBACA,iBACA,wDA0BAA,YAAYC,UAAWC,4CAdX,oCAMA,QASHD,UAAYA,eACZC,UAAYA,qCAEDC,OAAO,CACnBC,OAAO,kBAAU,gBAAiB,oBAClCC,KAAMC,KAAKC,QAAQ,CAACC,UAAWN,YAC/BO,OAAO,EACPC,eAAe,EACfC,QAAS,CACLC,MAAM,kBAAU,iBAAkB,uBAEvCC,MAAMC,aACAA,MAAQA,MAENA,SACRD,MAAMC,QAGLA,MAAMC,UAAUC,GAAGC,sBAAYL,KAAMN,KAAKY,WAAWC,KAAKb,OAG1DQ,MAAMC,UAAUC,GAAG,SAAU,OAAQV,KAAKc,eAAeD,KAAKb,OAC9DQ,MAAMO,OACCP,SACRQ,MAAMC,sBAAaC,WAW1BjB,QAAQkB,gBACEC,OAASD,SAAW,CAACE,aAAcC,KAAKC,UAAUJ,WAAa,YAG9DK,kBAASC,aAAa,mBAAoB,qBAAsBzB,KAAKL,UAAWyB,QAU3FR,WAAWc,GACPA,EAAEC,sBACGnB,MAAMC,UAAUmB,KAAK,QAAQC,SAUtCf,eAAeY,GACXA,EAAEC,qBAGEG,SAAW9B,KAAKQ,MAAMC,UAAUmB,KAAK,QAAQG,gBAEH,IAA1CD,SAASE,QAAQ,oBAA4B,OACvCC,aAAejC,KAAKQ,MAAMC,UAAUmB,KAAK,kBACzCM,YAAclC,KAAKQ,MAAMC,UAAUmB,KAAK,4BAC9CK,aAAaE,SAAS,cACtBD,YAAYE,KAAK,QAAS,yCAChB,wBAAyB,oBAAoB7B,MAAK8B,QACxDH,YAAYI,QAAQC,OAAOF,UAE5BrB,MAAMC,sBAAaC,yBAIrBsB,KAAK,CAAC,CACPC,WAAY,gDACZC,KAAM,CAACxC,UAAWF,KAAKJ,UAAWyB,aAAcC,KAAKC,UAAUO,cAC/D,GACHvB,MAAMoC,OACCA,KAAKC,SAASC,OAAS,OAClBrC,MAAMsC,QAAQ9C,KAAKC,QAAQ6B,iBAE3BtB,MAAMuC,UACXC,SAASC,SAASC,UAEfP,QAEV3B,OAAOmC,OAAUlC,sBAAaC,UAAUiC"} \ No newline at end of file diff --git a/admin/tool/dataprivacy/amd/src/add_category.js b/admin/tool/dataprivacy/amd/src/add_category.js index 469b52e8a61..84e4b4cf680 100644 --- a/admin/tool/dataprivacy/amd/src/add_category.js +++ b/admin/tool/dataprivacy/amd/src/add_category.js @@ -25,7 +25,7 @@ define([ 'core/str', 'core/ajax', 'core/notification', - 'core/modal_factory', + 'core/modal_save_cancel', 'core/modal_events', 'core/fragment', 'core_form/changechecker', @@ -34,7 +34,7 @@ define([ Str, Ajax, Notification, - ModalFactory, + ModalSaveCancel, ModalEvents, Fragment, FormChangeChecker @@ -78,16 +78,19 @@ define([ var trigger = $(SELECTORS.CATEGORY_LINK); trigger.on('click', function() { - return this.strings.then(function(strings) { - ModalFactory.create({ - type: ModalFactory.types.SAVE_CANCEL, - title: strings[0], - body: '', - }, trigger).done(function(modal) { - this.setupFormModal(modal, strings[1]); + this.strings.then(function(strings) { + return Promise.all([ + ModalSaveCancel.create({ + title: strings[0], + body: '', + }), + strings[1], + ]).then(function([modal, string]) { + this.setupFormModal(modal, string); + return modal; }.bind(this)); }.bind(this)) - .fail(Notification.exception); + .catch(Notification.exception); }.bind(this)); }; @@ -183,4 +186,3 @@ define([ }; } ); - diff --git a/admin/tool/dataprivacy/amd/src/add_purpose.js b/admin/tool/dataprivacy/amd/src/add_purpose.js index bf10868c8a2..8b083863804 100644 --- a/admin/tool/dataprivacy/amd/src/add_purpose.js +++ b/admin/tool/dataprivacy/amd/src/add_purpose.js @@ -25,7 +25,7 @@ define([ 'core/str', 'core/ajax', 'core/notification', - 'core/modal_factory', + 'core/modal_save_cancel', 'core/modal_events', 'core/fragment', 'core_form/changechecker', @@ -34,7 +34,7 @@ define([ Str, Ajax, Notification, - ModalFactory, + ModalSaveCancel, ModalEvents, Fragment, FormChangeChecker @@ -78,16 +78,18 @@ define([ var trigger = $(SELECTORS.PURPOSE_LINK); trigger.on('click', function() { - return this.strings.then(function(strings) { - ModalFactory.create({ - type: ModalFactory.types.SAVE_CANCEL, - title: strings[0], - body: '', - }, trigger).done(function(modal) { - this.setupFormModal(modal, strings[1]); + this.strings.then(function(strings) { + return Promise.all([ + ModalSaveCancel.create({ + title: strings[0], + body: '', + }), + strings[1], + ]).then(function([modal, string]) { + this.setupFormModal(modal, string); }.bind(this)); }.bind(this)) - .fail(Notification.exception); + .catch(Notification.exception); }.bind(this)); }; @@ -184,4 +186,3 @@ define([ }; } ); - diff --git a/admin/tool/dataprivacy/amd/src/categoriesactions.js b/admin/tool/dataprivacy/amd/src/categoriesactions.js index f07b5710cbf..6beae90774a 100644 --- a/admin/tool/dataprivacy/amd/src/categoriesactions.js +++ b/admin/tool/dataprivacy/amd/src/categoriesactions.js @@ -20,112 +20,112 @@ * @copyright 2018 David Monllao * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -define([ - 'jquery', - 'core/ajax', - 'core/notification', - 'core/str', - 'core/modal_factory', - 'core/modal_events'], -function($, Ajax, Notification, Str, ModalFactory, ModalEvents) { +import * as Ajax from 'core/ajax'; +import * as Notification from 'core/notification'; +import * as Str from 'core/str'; +import ModalEvents from 'core/modal_events'; +import ModalSaveCancel from 'core/modal_save_cancel'; - /** - * List of action selectors. - * - * @type {{DELETE: string}} - */ - var ACTIONS = { - DELETE: '[data-action="deletecategory"]', - }; +/** + * List of action selectors. + * + * @type {{DELETE: string}} + */ +const ACTIONS = { + DELETE: '[data-action="deletecategory"]', +}; + +export default class CategoriesActions { + + static init() { + return new this(); + } /** * CategoriesActions class. */ - var CategoriesActions = function() { + constructor() { this.registerEvents(); - }; + } + + deleteCategory(id) { + return Ajax.call([{ + methodname: 'tool_dataprivacy_delete_category', + args: {id} + }])[0]; + } + + handleCategoryRemoval(id) { + this.deleteCategory(id) + .then((data) => { + if (data.result) { + document.querySelector(`tr[data-categoryid="${id}"]`)?.remove(); + } else { + Notification.addNotification({ + message: data.warnings[0].message, + type: 'error' + }); + } + + return; + }) + .catch(Notification.exception); + + } /** * Register event listeners. */ - CategoriesActions.prototype.registerEvents = function() { - $(ACTIONS.DELETE).click(function(e) { + registerEvents() { + document.addEventListener('click', (e) => { + const target = e.target.closest(ACTIONS.DELETE); + if (!target) { + return; + } + e.preventDefault(); - var id = $(this).data('id'); - var categoryname = $(this).data('name'); - var stringkeys = [ - { - key: 'deletecategory', - component: 'tool_dataprivacy' - }, - { - key: 'deletecategorytext', - component: 'tool_dataprivacy', - param: categoryname - }, - { - key: 'delete' - } - ]; - - Str.get_strings(stringkeys).then(function(langStrings) { - var title = langStrings[0]; - var confirmMessage = langStrings[1]; - var buttonText = langStrings[2]; - return ModalFactory.create({ - title: title, - body: confirmMessage, - type: ModalFactory.types.SAVE_CANCEL - }).then(function(modal) { - modal.setSaveButtonText(buttonText); - - // Handle save event. - modal.getRoot().on(ModalEvents.save, function() { - - var request = { - methodname: 'tool_dataprivacy_delete_category', - args: {'id': id} - }; - - Ajax.call([request])[0].done(function(data) { - if (data.result) { - $('tr[data-categoryid="' + id + '"]').remove(); - } else { - Notification.addNotification({ - message: data.warnings[0].message, - type: 'error' - }); - } - }).fail(Notification.exception); - }); - - // Handle hidden event. - modal.getRoot().on(ModalEvents.hidden, function() { - // Destroy when hidden. - modal.destroy(); - }); - - return modal; - }); - }).done(function(modal) { - modal.show(); - - }).fail(Notification.exception); + this.confirmCategoryRemoval(target); }); - }; + } - return /** @alias module:tool_dataprivacy/categoriesactions */ { - // Public variables and functions. + confirmCategoryRemoval(target) { + const id = target.dataset.id; + var categoryname = target.dataset.name; + var stringkeys = [ + { + key: 'deletecategory', + component: 'tool_dataprivacy' + }, + { + key: 'deletecategorytext', + component: 'tool_dataprivacy', + param: categoryname + }, + { + key: 'delete' + } + ]; - /** - * Initialise the module. - * - * @method init - * @return {CategoriesActions} - */ - 'init': function() { - return new CategoriesActions(); - } - }; -}); + Str.get_strings(stringkeys).then(([ + title, + body, + save, + ]) => ModalSaveCancel.create({ + title, + body, + buttons: { + save, + }, + show: true, + removeOnClose: true, + })) + .then((modal) => { + // Handle save event. + modal.getRoot().on(ModalEvents.save, () => this.handleCategoryRemoval(id)); + + return modal; + }) + .catch(Notification.exception); + } +} diff --git a/admin/tool/dataprivacy/amd/src/data_deletion.js b/admin/tool/dataprivacy/amd/src/data_deletion.js index 07917e2414a..7486cc15892 100644 --- a/admin/tool/dataprivacy/amd/src/data_deletion.js +++ b/admin/tool/dataprivacy/amd/src/data_deletion.js @@ -25,9 +25,9 @@ define([ 'core/ajax', 'core/notification', 'core/str', - 'core/modal_factory', + 'core/modal_save_cancel', 'core/modal_events'], -function($, Ajax, Notification, Str, ModalFactory, ModalEvents) { +function($, Ajax, Notification, Str, ModalSaveCancel, ModalEvents) { /** * List of action selectors. @@ -107,10 +107,9 @@ function($, Ajax, Notification, Str, ModalFactory, ModalEvents) { Str.get_strings(keys).then(function(langStrings) { modalTitle = langStrings[0]; var confirmMessage = langStrings[1]; - return ModalFactory.create({ + return ModalSaveCancel.create({ title: modalTitle, body: confirmMessage, - type: ModalFactory.types.SAVE_CANCEL }); }).then(function(modal) { modal.setSaveButtonText(modalTitle); diff --git a/admin/tool/dataprivacy/amd/src/data_registry.js b/admin/tool/dataprivacy/amd/src/data_registry.js index 5f21baddb0a..244d837ed5a 100644 --- a/admin/tool/dataprivacy/amd/src/data_registry.js +++ b/admin/tool/dataprivacy/amd/src/data_registry.js @@ -20,9 +20,9 @@ * @copyright 2018 David Monllao * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -define(['jquery', 'core/str', 'core/ajax', 'core/notification', 'core/templates', 'core/modal_factory', - 'core/modal_events', 'core/fragment', 'tool_dataprivacy/add_purpose', 'tool_dataprivacy/add_category'], - function($, Str, Ajax, Notification, Templates, ModalFactory, ModalEvents, Fragment, AddPurpose, AddCategory) { +define(['jquery', 'core/str', 'core/ajax', 'core/notification', 'core/templates', + 'core/fragment', 'tool_dataprivacy/add_purpose', 'tool_dataprivacy/add_category'], + function($, Str, Ajax, Notification, Templates, Fragment, AddPurpose, AddCategory) { var SELECTORS = { TREE_NODES: '[data-context-tree-node=1]', @@ -309,4 +309,3 @@ define(['jquery', 'core/str', 'core/ajax', 'core/notification', 'core/templates' }; } ); - diff --git a/admin/tool/dataprivacy/amd/src/defaultsactions.js b/admin/tool/dataprivacy/amd/src/defaultsactions.js index 688648d463b..743dc4bbbd5 100644 --- a/admin/tool/dataprivacy/amd/src/defaultsactions.js +++ b/admin/tool/dataprivacy/amd/src/defaultsactions.js @@ -25,10 +25,10 @@ define([ 'core/ajax', 'core/notification', 'core/str', - 'core/modal_factory', + 'core/modal_save_cancel', 'core/modal_events', 'core/templates'], -function($, Ajax, Notification, Str, ModalFactory, ModalEvents, Templates) { +function($, Ajax, Notification, Str, ModalSaveCancel, ModalEvents, Templates) { /** * List of action selectors. @@ -158,11 +158,12 @@ function($, Ajax, Notification, Str, ModalFactory, ModalEvents, Templates) { var category = INHERIT; var purpose = INHERIT; - ModalFactory.create({ + ModalSaveCancel.create({ title: Str.get_string('deletedefaults', 'tool_dataprivacy', activityDisplayName), body: Templates.render('tool_dataprivacy/delete_activity_defaults', {"activityname": activityDisplayName}), - type: ModalFactory.types.SAVE_CANCEL, - large: true + large: true, + show: true, + removeOnClose: true, }).then(function(modal) { modal.setSaveButtonText(Str.get_string('delete')); @@ -171,14 +172,6 @@ function($, Ajax, Notification, Str, ModalFactory, ModalEvents, Templates) { setContextDefaults(contextLevel, category, purpose, activity, false); }); - // Handle hidden event. - modal.getRoot().on(ModalEvents.hidden, function() { - // Destroy when hidden. - modal.destroy(); - }); - - modal.show(); - return true; }).catch(Notification.exception); }); @@ -241,11 +234,12 @@ function($, Ajax, Notification, Str, ModalFactory, ModalEvents, Templates) { templateContext.activityoptions = activityOptions; } - ModalFactory.create({ + ModalSaveCancel.create({ title: title, body: Templates.render('tool_dataprivacy/category_purpose_form', templateContext), - type: ModalFactory.types.SAVE_CANCEL, - large: true + large: true, + show: true, + removeOnClose: true, }).then(function(modal) { // Handle save event. @@ -258,14 +252,6 @@ function($, Ajax, Notification, Str, ModalFactory, ModalEvents, Templates) { setContextDefaults($('#contextlevel').val(), $('#category').val(), $('#purpose').val(), activityVal, overrideVal); }); - // Handle hidden event. - modal.getRoot().on(ModalEvents.hidden, function() { - // Destroy when hidden. - modal.destroy(); - }); - - modal.show(); - return modal; }).catch(Notification.exception); } diff --git a/admin/tool/dataprivacy/amd/src/purposesactions.js b/admin/tool/dataprivacy/amd/src/purposesactions.js index 903eaaa3537..18d63efc545 100644 --- a/admin/tool/dataprivacy/amd/src/purposesactions.js +++ b/admin/tool/dataprivacy/amd/src/purposesactions.js @@ -20,112 +20,131 @@ * @copyright 2018 David Monllao * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -define([ - 'jquery', - 'core/ajax', - 'core/notification', - 'core/str', - 'core/modal_factory', - 'core/modal_events'], -function($, Ajax, Notification, Str, ModalFactory, ModalEvents) { +// 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 . - /** - * List of action selectors. - * - * @type {{DELETE: string}} - */ - var ACTIONS = { - DELETE: '[data-action="deletepurpose"]', - }; +/** + * Module for purpose actions. + * + * @module tool_dataprivacy/purposeactions + * @copyright 2018 David Monllao + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +import * as Ajax from 'core/ajax'; +import * as Notification from 'core/notification'; +import * as Str from 'core/str'; +import ModalEvents from 'core/modal_events'; +import ModalSaveCancel from 'core/modal_save_cancel'; - /** - * PurposesActions class. - */ - var PurposesActions = function() { +/** + * List of action selectors. + * + * @type {{DELETE: string}} + */ +const ACTIONS = { + DELETE: '[data-action="deletepurpose"]', +}; + +export default class PurposeActions { + + static init() { + return new this(); + } + + constructor() { this.registerEvents(); - }; + } + + deletePurpose(id) { + return Ajax.call([{ + methodname: 'tool_dataprivacy_delete_purpose', + args: {id} + }])[0]; + } + + handleRemoval(id) { + this.deletePurpose(id) + .then((data) => { + if (data.result) { + document.querySelector(`tr[data-purposeid="${id}"]`)?.remove(); + } else { + Notification.addNotification({ + message: data.warnings[0].message, + type: 'error' + }); + } + + return; + }) + .catch(Notification.exception); + + } /** * Register event listeners. */ - PurposesActions.prototype.registerEvents = function() { - $(ACTIONS.DELETE).click(function(e) { + registerEvents() { + document.addEventListener('click', (e) => { + const target = e.target.closest(ACTIONS.DELETE); + if (!target) { + return; + } + e.preventDefault(); - var id = $(this).data('id'); - var purposename = $(this).data('name'); - var stringkeys = [ - { - key: 'deletepurpose', - component: 'tool_dataprivacy' - }, - { - key: 'deletepurposetext', - component: 'tool_dataprivacy', - param: purposename - }, - { - key: 'delete' - } - ]; - - Str.get_strings(stringkeys).then(function(langStrings) { - var title = langStrings[0]; - var confirmMessage = langStrings[1]; - var buttonText = langStrings[2]; - return ModalFactory.create({ - title: title, - body: confirmMessage, - type: ModalFactory.types.SAVE_CANCEL - }).then(function(modal) { - modal.setSaveButtonText(buttonText); - - // Handle save event. - modal.getRoot().on(ModalEvents.save, function() { - - var request = { - methodname: 'tool_dataprivacy_delete_purpose', - args: {'id': id} - }; - - Ajax.call([request])[0].done(function(data) { - if (data.result) { - $('tr[data-purposeid="' + id + '"]').remove(); - } else { - Notification.addNotification({ - message: data.warnings[0].message, - type: 'error' - }); - } - }).fail(Notification.exception); - }); - - // Handle hidden event. - modal.getRoot().on(ModalEvents.hidden, function() { - // Destroy when hidden. - modal.destroy(); - }); - - return modal; - }); - }).done(function(modal) { - modal.show(); - - }).fail(Notification.exception); + this.confirmRemoval(target); }); - }; + } - return /** @alias module:tool_dataprivacy/purposesactions */ { - // Public variables and functions. + confirmRemoval(target) { + const id = target.dataset.id; + var purposename = target.dataset.name; + var stringkeys = [ + { + key: 'deletepurpose', + component: 'tool_dataprivacy' + }, + { + key: 'deletepurposetext', + component: 'tool_dataprivacy', + param: purposename + }, + { + key: 'delete' + } + ]; - /** - * Initialise the module. - * - * @method init - * @return {PurposesActions} - */ - 'init': function() { - return new PurposesActions(); - } - }; -}); + Str.get_strings(stringkeys).then(([ + title, + body, + save, + ]) => ModalSaveCancel.create({ + title, + body, + buttons: { + save, + }, + show: true, + removeOnClose: true, + })) + .then((modal) => { + // Handle save event. + modal.getRoot().on(ModalEvents.save, () => this.handleRemoval(id)); + + return modal; + }) + .catch(Notification.exception); + } +} diff --git a/admin/tool/dataprivacy/amd/src/requestactions.js b/admin/tool/dataprivacy/amd/src/requestactions.js index 8de4637aee1..76dca583216 100644 --- a/admin/tool/dataprivacy/amd/src/requestactions.js +++ b/admin/tool/dataprivacy/amd/src/requestactions.js @@ -25,13 +25,15 @@ define([ 'core/ajax', 'core/notification', 'core/str', - 'core/modal_factory', + 'core/modal_save_cancel', 'core/modal_events', 'core/templates', 'tool_dataprivacy/data_request_modal', 'tool_dataprivacy/events', - 'tool_dataprivacy/selectedcourses'], -function($, Ajax, Notification, Str, ModalFactory, ModalEvents, Templates, ModalDataRequest, DataPrivacyEvents, SelectedCourses) { + 'tool_dataprivacy/selectedcourses' +], function( + $, Ajax, Notification, Str, ModalSaveCancel, ModalEvents, Templates, ModalDataRequest, DataPrivacyEvents, SelectedCourses +) { /** * List of action selectors. @@ -121,10 +123,9 @@ function($, Ajax, Notification, Str, ModalFactory, ModalEvents, Templates, Modal canmarkcomplete: data.canmarkcomplete, allowfiltering: data.allowfiltering }; - return ModalFactory.create({ + return ModalDataRequest.create({ title: data.typename, body: body, - type: ModalDataRequest.TYPE, large: true, templateContext: templateContext }); @@ -398,10 +399,9 @@ function($, Ajax, Notification, Str, ModalFactory, ModalEvents, Templates, Modal Str.get_strings(keys).then(function(langStrings) { modalTitle = langStrings[0]; var confirmMessage = langStrings[1]; - return ModalFactory.create({ + return ModalSaveCancel.create({ title: modalTitle, body: confirmMessage, - type: ModalFactory.types.SAVE_CANCEL }); }).then(function(modal) { modal.setSaveButtonText(modalTitle); diff --git a/admin/tool/dataprivacy/amd/src/selectedcourses.js b/admin/tool/dataprivacy/amd/src/selectedcourses.js index 5449f4e9a9e..16f406a9439 100644 --- a/admin/tool/dataprivacy/amd/src/selectedcourses.js +++ b/admin/tool/dataprivacy/amd/src/selectedcourses.js @@ -24,7 +24,7 @@ import Ajax from 'core/ajax'; import Notification from 'core/notification'; -import ModalFactory from 'core/modal_factory'; +import ModalSaveCancel from 'core/modal_save_cancel'; import ModalEvents from 'core/modal_events'; import Fragment from 'core/fragment'; import {prefetchStrings} from 'core/prefetch'; @@ -63,8 +63,7 @@ export default class SelectedCourses { this.contextId = contextId; this.requestId = requestId; // Now create the modal. - ModalFactory.create({ - type: ModalFactory.types.SAVE_CANCEL, + ModalSaveCancel.create({ title: getString('selectcourses', 'tool_dataprivacy'), body: this.getBody({requestid: requestId}), large: true, diff --git a/admin/tool/policy/amd/build/acceptmodal.min.js b/admin/tool/policy/amd/build/acceptmodal.min.js index 2c1c4f907a9..e0ecc9e84cf 100644 --- a/admin/tool/policy/amd/build/acceptmodal.min.js +++ b/admin/tool/policy/amd/build/acceptmodal.min.js @@ -5,6 +5,6 @@ * @copyright 2018 Marina Glancy * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -define("tool_policy/acceptmodal",["jquery","core/str","core/modal_factory","core/modal_events","core/notification","core/fragment","core/ajax","core_form/changechecker"],(function($,Str,ModalFactory,ModalEvents,Notification,Fragment,Ajax,FormChangeChecker){var AcceptOnBehalf=function(contextid){this.contextid=contextid,this.init()};return AcceptOnBehalf.prototype.modal=null,AcceptOnBehalf.prototype.contextid=-1,AcceptOnBehalf.prototype.currentTrigger=null,AcceptOnBehalf.prototype.triggers={SINGLE:"a[data-action=acceptmodal]",BULK:"input[data-action=acceptmodal]"},AcceptOnBehalf.prototype.init=function(){$(this.triggers.SINGLE).on("click",function(e){e.preventDefault(),this.currentTrigger=$(e.currentTarget);var href=$(e.currentTarget).attr("href"),formData=href.slice(href.indexOf("?")+1);this.showFormModal(formData)}.bind(this)),$(this.triggers.BULK).on("click",function(e){e.preventDefault(),this.currentTrigger=$(e.currentTarget);var form=$(e.currentTarget).closest("form");if(form.find('input[type=checkbox][name="userids[]"]:checked').length){var formData=form.serialize();this.showFormModal(formData)}else Str.get_strings([{key:"notice"},{key:"selectusersforconsent",component:"tool_policy"},{key:"ok"}]).then((function(strings){Notification.alert(strings[0],strings[1],strings[2])})).fail(Notification.exception)}.bind(this))},AcceptOnBehalf.prototype.showFormModal=function(formData){for(var action,params=formData.split("&"),i=0;i.\n\n/**\n * Add policy consent modal to the page\n *\n * @module tool_policy/acceptmodal\n * @copyright 2018 Marina Glancy\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n 'jquery',\n 'core/str',\n 'core/modal_factory',\n 'core/modal_events',\n 'core/notification',\n 'core/fragment',\n 'core/ajax',\n 'core_form/changechecker',\n], function(\n $,\n Str,\n ModalFactory,\n ModalEvents,\n Notification,\n Fragment,\n Ajax,\n FormChangeChecker\n) {\n\n \"use strict\";\n\n /**\n * Constructor\n *\n * @param {int} contextid\n *\n * Each call to init gets it's own instance of this class.\n */\n var AcceptOnBehalf = function(contextid) {\n this.contextid = contextid;\n this.init();\n };\n\n /**\n * @var {Modal} modal\n * @private\n */\n AcceptOnBehalf.prototype.modal = null;\n\n /**\n * @var {int} contextid\n * @private\n */\n AcceptOnBehalf.prototype.contextid = -1;\n\n /**\n * @var {object} currentTrigger The triggered HTML jQuery object\n * @private\n */\n AcceptOnBehalf.prototype.currentTrigger = null;\n\n /**\n * @var {object} triggers The trigger selectors\n * @private\n */\n AcceptOnBehalf.prototype.triggers = {\n SINGLE: 'a[data-action=acceptmodal]',\n BULK: 'input[data-action=acceptmodal]'\n };\n\n /**\n * Initialise the class.\n *\n * @private\n */\n AcceptOnBehalf.prototype.init = function() {\n // Initialise for links accepting policies for individual users.\n $(this.triggers.SINGLE).on('click', function(e) {\n e.preventDefault();\n this.currentTrigger = $(e.currentTarget);\n var href = $(e.currentTarget).attr('href'),\n formData = href.slice(href.indexOf('?') + 1);\n this.showFormModal(formData);\n }.bind(this));\n\n // Initialise for multiple users acceptance form.\n $(this.triggers.BULK).on('click', function(e) {\n e.preventDefault();\n this.currentTrigger = $(e.currentTarget);\n var form = $(e.currentTarget).closest('form');\n if (form.find('input[type=checkbox][name=\"userids[]\"]:checked').length) {\n var formData = form.serialize();\n this.showFormModal(formData);\n } else {\n Str.get_strings([\n {key: 'notice'},\n {key: 'selectusersforconsent', component: 'tool_policy'},\n {key: 'ok'}\n ]).then(function(strings) {\n Notification.alert(strings[0], strings[1], strings[2]);\n return;\n }).fail(Notification.exception);\n }\n }.bind(this));\n };\n\n /**\n * Show modal with a form\n *\n * @param {String} formData\n */\n AcceptOnBehalf.prototype.showFormModal = function(formData) {\n var action;\n var params = formData.split('&');\n for (var i = 0; i < params.length; i++) {\n var pair = params[i].split('=');\n if (pair[0] == 'action') {\n action = pair[1];\n }\n }\n // Fetch the title string.\n Str.get_strings([\n {key: 'statusformtitleaccept', component: 'tool_policy'},\n {key: 'iagreetothepolicy', component: 'tool_policy'},\n {key: 'statusformtitlerevoke', component: 'tool_policy'},\n {key: 'irevokethepolicy', component: 'tool_policy'},\n {key: 'statusformtitledecline', component: 'tool_policy'},\n {key: 'declinethepolicy', component: 'tool_policy'}\n ]).then(function(strings) {\n var title;\n var saveText;\n if (action == 'accept') {\n title = strings[0];\n saveText = strings[1];\n } else if (action == 'revoke') {\n title = strings[2];\n saveText = strings[3];\n } else if (action == 'decline') {\n title = strings[4];\n saveText = strings[5];\n }\n // Create the modal.\n return ModalFactory.create({\n type: ModalFactory.types.SAVE_CANCEL,\n title: title,\n body: ''\n }).done(function(modal) {\n this.modal = modal;\n this.setupFormModal(formData, saveText);\n }.bind(this));\n }.bind(this))\n .catch(Notification.exception);\n };\n\n /**\n * Setup form inside a modal\n *\n * @param {String} formData\n * @param {String} saveText\n */\n AcceptOnBehalf.prototype.setupFormModal = function(formData, saveText) {\n var modal = this.modal;\n\n modal.setLarge();\n\n modal.setSaveButtonText(saveText);\n\n // We want to reset the form every time it is opened.\n modal.getRoot().on(ModalEvents.hidden, this.destroy.bind(this));\n\n modal.setBody(this.getBody(formData));\n\n // We catch the modal save event, and use it to submit the form inside the modal.\n // Triggering a form submission will give JS validation scripts a chance to check for errors.\n modal.getRoot().on(ModalEvents.save, this.submitForm.bind(this));\n // We also catch the form submit event and use it to submit the form with ajax.\n modal.getRoot().on('submit', 'form', this.submitFormAjax.bind(this));\n\n modal.show();\n };\n\n /**\n * Load the body of the modal (contains the form)\n *\n * @method getBody\n * @private\n * @param {String} formData\n * @return {Promise}\n */\n AcceptOnBehalf.prototype.getBody = function(formData) {\n if (typeof formData === \"undefined\") {\n formData = {};\n }\n // Get the content of the modal.\n var params = {jsonformdata: JSON.stringify(formData)};\n return Fragment.loadFragment('tool_policy', 'accept_on_behalf', this.contextid, params);\n };\n\n /**\n * Submit the form inside the modal via AJAX request\n *\n * @method submitFormAjax\n * @private\n * @param {Event} e Form submission event.\n */\n AcceptOnBehalf.prototype.submitFormAjax = function(e) {\n // We don't want to do a real form submission.\n e.preventDefault();\n\n // Convert all the form elements values to a serialised string.\n var formData = this.modal.getRoot().find('form').serialize();\n\n var requests = Ajax.call([{\n methodname: 'tool_policy_submit_accept_on_behalf',\n args: {jsonformdata: JSON.stringify(formData)}\n }]);\n requests[0].done(function(data) {\n if (data.validationerrors) {\n this.modal.setBody(this.getBody(formData));\n } else {\n this.close();\n }\n }.bind(this)).fail(Notification.exception);\n };\n\n /**\n * This triggers a form submission, so that any mform elements can do final tricks before the form submission is processed.\n *\n * @method submitForm\n * @param {Event} e Form submission event.\n * @private\n */\n AcceptOnBehalf.prototype.submitForm = function(e) {\n e.preventDefault();\n this.modal.getRoot().find('form').submit();\n };\n\n /**\n * Close the modal\n */\n AcceptOnBehalf.prototype.close = function() {\n this.destroy();\n document.location.reload();\n };\n\n /**\n * Destroy the modal\n */\n AcceptOnBehalf.prototype.destroy = function() {\n FormChangeChecker.resetAllFormDirtyStates();\n this.modal.destroy();\n this.currentTrigger.focus();\n };\n\n return /** @alias module:tool_policy/acceptmodal */ {\n // Public variables and functions.\n /**\n * Attach event listeners to initialise this module.\n *\n * @method init\n * @param {int} contextid The contextid for the course.\n * @return {AcceptOnBehalf}\n */\n getInstance: function(contextid) {\n return new AcceptOnBehalf(contextid);\n }\n };\n });\n"],"names":["define","$","Str","ModalFactory","ModalEvents","Notification","Fragment","Ajax","FormChangeChecker","AcceptOnBehalf","contextid","init","prototype","modal","currentTrigger","triggers","SINGLE","BULK","this","on","e","preventDefault","currentTarget","href","attr","formData","slice","indexOf","showFormModal","bind","form","closest","find","length","serialize","get_strings","key","component","then","strings","alert","fail","exception","action","params","split","i","pair","title","saveText","create","type","types","SAVE_CANCEL","body","done","setupFormModal","catch","setLarge","setSaveButtonText","getRoot","hidden","destroy","setBody","getBody","save","submitForm","submitFormAjax","show","jsonformdata","JSON","stringify","loadFragment","call","methodname","args","data","validationerrors","close","submit","document","location","reload","resetAllFormDirtyStates","focus","getInstance"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"acceptmodal.min.js","sources":["../src/acceptmodal.js"],"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 * Add policy consent modal to the page\n *\n * @module tool_policy/acceptmodal\n * @copyright 2018 Marina Glancy\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n 'jquery',\n 'core/str',\n 'core/modal_save_cancel',\n 'core/modal_events',\n 'core/notification',\n 'core/fragment',\n 'core/ajax',\n 'core_form/changechecker',\n], function(\n $,\n Str,\n ModalSaveCancel,\n ModalEvents,\n Notification,\n Fragment,\n Ajax,\n FormChangeChecker\n) {\n\n \"use strict\";\n\n /**\n * Constructor\n *\n * @param {int} contextid\n *\n * Each call to init gets it's own instance of this class.\n */\n var AcceptOnBehalf = function(contextid) {\n this.contextid = contextid;\n this.init();\n };\n\n /**\n * @var {Modal} modal\n * @private\n */\n AcceptOnBehalf.prototype.modal = null;\n\n /**\n * @var {int} contextid\n * @private\n */\n AcceptOnBehalf.prototype.contextid = -1;\n\n /**\n * @var {object} currentTrigger The triggered HTML jQuery object\n * @private\n */\n AcceptOnBehalf.prototype.currentTrigger = null;\n\n /**\n * @var {object} triggers The trigger selectors\n * @private\n */\n AcceptOnBehalf.prototype.triggers = {\n SINGLE: 'a[data-action=acceptmodal]',\n BULK: 'input[data-action=acceptmodal]'\n };\n\n /**\n * Initialise the class.\n *\n * @private\n */\n AcceptOnBehalf.prototype.init = function() {\n // Initialise for links accepting policies for individual users.\n $(this.triggers.SINGLE).on('click', function(e) {\n e.preventDefault();\n this.currentTrigger = $(e.currentTarget);\n var href = $(e.currentTarget).attr('href'),\n formData = href.slice(href.indexOf('?') + 1);\n this.showFormModal(formData);\n }.bind(this));\n\n // Initialise for multiple users acceptance form.\n $(this.triggers.BULK).on('click', function(e) {\n e.preventDefault();\n this.currentTrigger = $(e.currentTarget);\n var form = $(e.currentTarget).closest('form');\n if (form.find('input[type=checkbox][name=\"userids[]\"]:checked').length) {\n var formData = form.serialize();\n this.showFormModal(formData);\n } else {\n Str.get_strings([\n {key: 'notice'},\n {key: 'selectusersforconsent', component: 'tool_policy'},\n {key: 'ok'}\n ]).then(function(strings) {\n Notification.alert(strings[0], strings[1], strings[2]);\n return;\n }).fail(Notification.exception);\n }\n }.bind(this));\n };\n\n /**\n * Show modal with a form\n *\n * @param {String} formData\n */\n AcceptOnBehalf.prototype.showFormModal = function(formData) {\n var action;\n var params = formData.split('&');\n for (var i = 0; i < params.length; i++) {\n var pair = params[i].split('=');\n if (pair[0] == 'action') {\n action = pair[1];\n }\n }\n // Fetch the title string.\n Str.get_strings([\n {key: 'statusformtitleaccept', component: 'tool_policy'},\n {key: 'iagreetothepolicy', component: 'tool_policy'},\n {key: 'statusformtitlerevoke', component: 'tool_policy'},\n {key: 'irevokethepolicy', component: 'tool_policy'},\n {key: 'statusformtitledecline', component: 'tool_policy'},\n {key: 'declinethepolicy', component: 'tool_policy'}\n ]).then(function(strings) {\n var title;\n var saveText;\n if (action == 'accept') {\n title = strings[0];\n saveText = strings[1];\n } else if (action == 'revoke') {\n title = strings[2];\n saveText = strings[3];\n } else if (action == 'decline') {\n title = strings[4];\n saveText = strings[5];\n }\n // Create the modal.\n return ModalSaveCancel.create({\n title: title,\n body: ''\n }).then(function(modal) {\n this.modal = modal;\n this.setupFormModal(formData, saveText);\n }.bind(this));\n }.bind(this))\n .catch(Notification.exception);\n };\n\n /**\n * Setup form inside a modal\n *\n * @param {String} formData\n * @param {String} saveText\n */\n AcceptOnBehalf.prototype.setupFormModal = function(formData, saveText) {\n var modal = this.modal;\n\n modal.setLarge();\n\n modal.setSaveButtonText(saveText);\n\n // We want to reset the form every time it is opened.\n modal.getRoot().on(ModalEvents.hidden, this.destroy.bind(this));\n\n modal.setBody(this.getBody(formData));\n\n // We catch the modal save event, and use it to submit the form inside the modal.\n // Triggering a form submission will give JS validation scripts a chance to check for errors.\n modal.getRoot().on(ModalEvents.save, this.submitForm.bind(this));\n // We also catch the form submit event and use it to submit the form with ajax.\n modal.getRoot().on('submit', 'form', this.submitFormAjax.bind(this));\n\n modal.show();\n };\n\n /**\n * Load the body of the modal (contains the form)\n *\n * @method getBody\n * @private\n * @param {String} formData\n * @return {Promise}\n */\n AcceptOnBehalf.prototype.getBody = function(formData) {\n if (typeof formData === \"undefined\") {\n formData = {};\n }\n // Get the content of the modal.\n var params = {jsonformdata: JSON.stringify(formData)};\n return Fragment.loadFragment('tool_policy', 'accept_on_behalf', this.contextid, params);\n };\n\n /**\n * Submit the form inside the modal via AJAX request\n *\n * @method submitFormAjax\n * @private\n * @param {Event} e Form submission event.\n */\n AcceptOnBehalf.prototype.submitFormAjax = function(e) {\n // We don't want to do a real form submission.\n e.preventDefault();\n\n // Convert all the form elements values to a serialised string.\n var formData = this.modal.getRoot().find('form').serialize();\n\n var requests = Ajax.call([{\n methodname: 'tool_policy_submit_accept_on_behalf',\n args: {jsonformdata: JSON.stringify(formData)}\n }]);\n requests[0].done(function(data) {\n if (data.validationerrors) {\n this.modal.setBody(this.getBody(formData));\n } else {\n this.close();\n }\n }.bind(this)).fail(Notification.exception);\n };\n\n /**\n * This triggers a form submission, so that any mform elements can do final tricks before the form submission is processed.\n *\n * @method submitForm\n * @param {Event} e Form submission event.\n * @private\n */\n AcceptOnBehalf.prototype.submitForm = function(e) {\n e.preventDefault();\n this.modal.getRoot().find('form').submit();\n };\n\n /**\n * Close the modal\n */\n AcceptOnBehalf.prototype.close = function() {\n this.destroy();\n document.location.reload();\n };\n\n /**\n * Destroy the modal\n */\n AcceptOnBehalf.prototype.destroy = function() {\n FormChangeChecker.resetAllFormDirtyStates();\n this.modal.destroy();\n this.currentTrigger.focus();\n };\n\n return /** @alias module:tool_policy/acceptmodal */ {\n // Public variables and functions.\n /**\n * Attach event listeners to initialise this module.\n *\n * @method init\n * @param {int} contextid The contextid for the course.\n * @return {AcceptOnBehalf}\n */\n getInstance: function(contextid) {\n return new AcceptOnBehalf(contextid);\n }\n };\n });\n"],"names":["define","$","Str","ModalSaveCancel","ModalEvents","Notification","Fragment","Ajax","FormChangeChecker","AcceptOnBehalf","contextid","init","prototype","modal","currentTrigger","triggers","SINGLE","BULK","this","on","e","preventDefault","currentTarget","href","attr","formData","slice","indexOf","showFormModal","bind","form","closest","find","length","serialize","get_strings","key","component","then","strings","alert","fail","exception","action","params","split","i","pair","title","saveText","create","body","setupFormModal","catch","setLarge","setSaveButtonText","getRoot","hidden","destroy","setBody","getBody","save","submitForm","submitFormAjax","show","jsonformdata","JSON","stringify","loadFragment","call","methodname","args","done","data","validationerrors","close","submit","document","location","reload","resetAllFormDirtyStates","focus","getInstance"],"mappings":"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"} \ No newline at end of file diff --git a/admin/tool/policy/amd/build/managedocsactions.min.js b/admin/tool/policy/amd/build/managedocsactions.min.js index fb447ea00ea..571a039960d 100644 --- a/admin/tool/policy/amd/build/managedocsactions.min.js +++ b/admin/tool/policy/amd/build/managedocsactions.min.js @@ -5,6 +5,6 @@ * @copyright 2018 David Mudrák * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -define("tool_policy/managedocsactions",["jquery","core/log","core/config","core/str","core/modal_factory","core/modal_events"],(function($,Log,Config,Str,ModalFactory,ModalEvents){var ACTION_LINKS="[data-action]",ACTION_MAKE_CURRENT='[data-action="makecurrent"]',ACTION_INACTIVATE='[data-action="inactivate"]',ACTION_DELETE='[data-action="delete"]';function ManageDocsActions(base){this.base=base,this.initEvents()}return ManageDocsActions.prototype.initEvents=function(){this.base.on("click",ACTION_LINKS,(function(e){e.stopPropagation();var promise,strings,link=$(e.currentTarget);if(link.is(ACTION_MAKE_CURRENT))promise=Str.get_strings([{key:"activating",component:"tool_policy"},{key:"activateconfirm",component:"tool_policy",param:{name:link.closest("[data-policy-name]").attr("data-policy-name"),revision:link.closest("[data-policy-revision]").attr("data-policy-revision")}},{key:"activateconfirmyes",component:"tool_policy"}]);else if(link.is(ACTION_INACTIVATE))promise=Str.get_strings([{key:"inactivating",component:"tool_policy"},{key:"inactivatingconfirm",component:"tool_policy",param:{name:link.closest("[data-policy-name]").attr("data-policy-name"),revision:link.closest("[data-policy-revision]").attr("data-policy-revision")}},{key:"inactivatingconfirmyes",component:"tool_policy"}]);else{if(!link.is(ACTION_DELETE))return void Log.error("unknown action type detected","tool_policy/managedocsactions");promise=Str.get_strings([{key:"deleting",component:"tool_policy"},{key:"deleteconfirm",component:"tool_policy",param:{name:link.closest("[data-policy-name]").attr("data-policy-name"),revision:link.closest("[data-policy-revision]").attr("data-policy-revision")}},{key:"delete",component:"core"}])}e.preventDefault(),promise.then((function(strs){return strings=strs,ModalFactory.create({title:strings[0],body:strings[1],type:ModalFactory.types.SAVE_CANCEL})})).then((function(modal){return modal.setSaveButtonText(strings[2]),modal.getRoot().on(ModalEvents.save,(function(){window.location.href=link.attr("href")+"&sesskey="+Config.sesskey+"&confirm=1"})),modal.getRoot().on(ModalEvents.hidden,(function(){modal.destroy()})),modal.show(),!0})).catch((function(e){return Log.error(e),!1}))}))},{init:function(baseid){var base=$(document.getElementById(baseid));if(base.length)return new ManageDocsActions(base);throw new Error("managedocsactions: Invalid base element identifier")}}})); +define("tool_policy/managedocsactions",["jquery","core/log","core/config","core/str","core/modal_save_cancel","core/modal_events"],(function($,Log,Config,Str,ModalSaveCancel,ModalEvents){var ACTION_LINKS="[data-action]",ACTION_MAKE_CURRENT='[data-action="makecurrent"]',ACTION_INACTIVATE='[data-action="inactivate"]',ACTION_DELETE='[data-action="delete"]';function ManageDocsActions(base){this.base=base,this.initEvents()}return ManageDocsActions.prototype.initEvents=function(){this.base.on("click",ACTION_LINKS,(function(e){e.stopPropagation();var promise,strings,link=$(e.currentTarget);if(link.is(ACTION_MAKE_CURRENT))promise=Str.get_strings([{key:"activating",component:"tool_policy"},{key:"activateconfirm",component:"tool_policy",param:{name:link.closest("[data-policy-name]").attr("data-policy-name"),revision:link.closest("[data-policy-revision]").attr("data-policy-revision")}},{key:"activateconfirmyes",component:"tool_policy"}]);else if(link.is(ACTION_INACTIVATE))promise=Str.get_strings([{key:"inactivating",component:"tool_policy"},{key:"inactivatingconfirm",component:"tool_policy",param:{name:link.closest("[data-policy-name]").attr("data-policy-name"),revision:link.closest("[data-policy-revision]").attr("data-policy-revision")}},{key:"inactivatingconfirmyes",component:"tool_policy"}]);else{if(!link.is(ACTION_DELETE))return void Log.error("unknown action type detected","tool_policy/managedocsactions");promise=Str.get_strings([{key:"deleting",component:"tool_policy"},{key:"deleteconfirm",component:"tool_policy",param:{name:link.closest("[data-policy-name]").attr("data-policy-name"),revision:link.closest("[data-policy-revision]").attr("data-policy-revision")}},{key:"delete",component:"core"}])}e.preventDefault(),promise.then((function(strs){return strings=strs,ModalSaveCancel.create({title:strings[0],body:strings[1]})})).then((function(modal){return modal.setSaveButtonText(strings[2]),modal.getRoot().on(ModalEvents.save,(function(){window.location.href=link.attr("href")+"&sesskey="+Config.sesskey+"&confirm=1"})),modal.getRoot().on(ModalEvents.hidden,(function(){modal.destroy()})),modal.show(),!0})).catch((function(e){return Log.error(e),!1}))}))},{init:function(baseid){var base=$(document.getElementById(baseid));if(base.length)return new ManageDocsActions(base);throw new Error("managedocsactions: Invalid base element identifier")}}})); //# sourceMappingURL=managedocsactions.min.js.map \ No newline at end of file diff --git a/admin/tool/policy/amd/build/managedocsactions.min.js.map b/admin/tool/policy/amd/build/managedocsactions.min.js.map index d2962520b4e..ee02c522fd7 100644 --- a/admin/tool/policy/amd/build/managedocsactions.min.js.map +++ b/admin/tool/policy/amd/build/managedocsactions.min.js.map @@ -1 +1 @@ -{"version":3,"file":"managedocsactions.min.js","sources":["../src/managedocsactions.js"],"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 * Adds support for confirmation via JS modal for some management actions at the Manage policies page.\n *\n * @module tool_policy/managedocsactions\n * @copyright 2018 David Mudrák \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n 'jquery',\n 'core/log',\n 'core/config',\n 'core/str',\n 'core/modal_factory',\n 'core/modal_events'\n], function($, Log, Config, Str, ModalFactory, ModalEvents) {\n\n \"use strict\";\n\n /**\n * List of action selectors.\n *\n * @property {string} LINKS - Selector for all action links\n * @property {string} MAKE_CURRENT\n */\n var ACTION = {\n LINKS: '[data-action]',\n MAKE_CURRENT: '[data-action=\"makecurrent\"]',\n INACTIVATE: '[data-action=\"inactivate\"]',\n DELETE: '[data-action=\"delete\"]'\n };\n\n /**\n * @constructor\n * @param {Element} base - Management area wrapping element\n */\n function ManageDocsActions(base) {\n this.base = base;\n\n this.initEvents();\n }\n\n /**\n * Register event listeners.\n */\n ManageDocsActions.prototype.initEvents = function() {\n var self = this;\n\n self.base.on('click', ACTION.LINKS, function(e) {\n e.stopPropagation();\n\n var link = $(e.currentTarget);\n var promise;\n var strings;\n\n if (link.is(ACTION.MAKE_CURRENT)) {\n promise = Str.get_strings([\n {key: 'activating', component: 'tool_policy'},\n {key: 'activateconfirm', component: 'tool_policy', param: {\n name: link.closest('[data-policy-name]').attr('data-policy-name'),\n revision: link.closest('[data-policy-revision]').attr('data-policy-revision')\n }},\n {key: 'activateconfirmyes', component: 'tool_policy'}\n ]);\n\n } else if (link.is(ACTION.INACTIVATE)) {\n promise = Str.get_strings([\n {key: 'inactivating', component: 'tool_policy'},\n {key: 'inactivatingconfirm', component: 'tool_policy', param: {\n name: link.closest('[data-policy-name]').attr('data-policy-name'),\n revision: link.closest('[data-policy-revision]').attr('data-policy-revision')\n }},\n {key: 'inactivatingconfirmyes', component: 'tool_policy'}\n ]);\n\n } else if (link.is(ACTION.DELETE)) {\n promise = Str.get_strings([\n {key: 'deleting', component: 'tool_policy'},\n {key: 'deleteconfirm', component: 'tool_policy', param: {\n name: link.closest('[data-policy-name]').attr('data-policy-name'),\n revision: link.closest('[data-policy-revision]').attr('data-policy-revision')\n }},\n {key: 'delete', component: 'core'}\n ]);\n\n } else {\n Log.error('unknown action type detected', 'tool_policy/managedocsactions');\n return;\n }\n\n e.preventDefault();\n\n promise.then(function(strs) {\n strings = strs;\n return ModalFactory.create({\n title: strings[0],\n body: strings[1],\n type: ModalFactory.types.SAVE_CANCEL\n });\n\n }).then(function(modal) {\n modal.setSaveButtonText(strings[2]);\n modal.getRoot().on(ModalEvents.save, function() {\n window.location.href = link.attr('href') + '&sesskey=' + Config.sesskey + '&confirm=1';\n });\n\n modal.getRoot().on(ModalEvents.hidden, function() {\n modal.destroy();\n });\n\n modal.show();\n return true;\n\n }).catch(function(e) {\n Log.error(e);\n return false;\n });\n });\n };\n\n return {\n /**\n * Factory method returning instance of the ManageDocsActions\n *\n * @param {String} baseid - ID of the management area wrapping element\n * @return {ManageDocsActions}\n */\n init: function(baseid) {\n var base = $(document.getElementById(baseid));\n\n if (base.length) {\n return new ManageDocsActions(base);\n\n } else {\n throw new Error(\"managedocsactions: Invalid base element identifier\");\n }\n }\n };\n});\n"],"names":["define","$","Log","Config","Str","ModalFactory","ModalEvents","ACTION","ManageDocsActions","base","initEvents","prototype","this","on","e","stopPropagation","promise","strings","link","currentTarget","is","get_strings","key","component","param","name","closest","attr","revision","error","preventDefault","then","strs","create","title","body","type","types","SAVE_CANCEL","modal","setSaveButtonText","getRoot","save","window","location","href","sesskey","hidden","destroy","show","catch","init","baseid","document","getElementById","length","Error"],"mappings":";;;;;;;AAsBAA,uCAAO,CACH,SACA,WACA,cACA,WACA,qBACA,sBACD,SAASC,EAAGC,IAAKC,OAAQC,IAAKC,aAAcC,iBAUvCC,aACO,gBADPA,oBAEc,8BAFdA,kBAGY,6BAHZA,cAIQ,kCAOHC,kBAAkBC,WAClBA,KAAOA,UAEPC,oBAMTF,kBAAkBG,UAAUD,WAAa,WAC1BE,KAENH,KAAKI,GAAG,QAASN,cAAc,SAASO,GACzCA,EAAEC,sBAGEC,QACAC,QAFAC,KAAOjB,EAAEa,EAAEK,kBAIXD,KAAKE,GAAGb,qBACRS,QAAUZ,IAAIiB,YAAY,CACtB,CAACC,IAAK,aAAcC,UAAW,eAC/B,CAACD,IAAK,kBAAmBC,UAAW,cAAeC,MAAO,CACtDC,KAAMP,KAAKQ,QAAQ,sBAAsBC,KAAK,oBAC9CC,SAAUV,KAAKQ,QAAQ,0BAA0BC,KAAK,0BAE1D,CAACL,IAAK,qBAAsBC,UAAW,sBAGxC,GAAIL,KAAKE,GAAGb,mBACfS,QAAUZ,IAAIiB,YAAY,CACtB,CAACC,IAAK,eAAgBC,UAAW,eACjC,CAACD,IAAK,sBAAuBC,UAAW,cAAeC,MAAO,CAC1DC,KAAMP,KAAKQ,QAAQ,sBAAsBC,KAAK,oBAC9CC,SAAUV,KAAKQ,QAAQ,0BAA0BC,KAAK,0BAE1D,CAACL,IAAK,yBAA0BC,UAAW,qBAG5C,CAAA,IAAIL,KAAKE,GAAGb,2BAWfL,IAAI2B,MAAM,+BAAgC,iCAV1Cb,QAAUZ,IAAIiB,YAAY,CACtB,CAACC,IAAK,WAAYC,UAAW,eAC7B,CAACD,IAAK,gBAAiBC,UAAW,cAAeC,MAAO,CACpDC,KAAMP,KAAKQ,QAAQ,sBAAsBC,KAAK,oBAC9CC,SAAUV,KAAKQ,QAAQ,0BAA0BC,KAAK,0BAE1D,CAACL,IAAK,SAAUC,UAAW,UAQnCT,EAAEgB,iBAEFd,QAAQe,MAAK,SAASC,aAClBf,QAAUe,KACH3B,aAAa4B,OAAO,CACvBC,MAAOjB,QAAQ,GACfkB,KAAMlB,QAAQ,GACdmB,KAAM/B,aAAagC,MAAMC,iBAG9BP,MAAK,SAASQ,cACbA,MAAMC,kBAAkBvB,QAAQ,IAChCsB,MAAME,UAAU5B,GAAGP,YAAYoC,MAAM,WACjCC,OAAOC,SAASC,KAAO3B,KAAKS,KAAK,QAAU,YAAcxB,OAAO2C,QAAU,gBAG9EP,MAAME,UAAU5B,GAAGP,YAAYyC,QAAQ,WACnCR,MAAMS,aAGVT,MAAMU,QACC,KAERC,OAAM,SAASpC,UACdZ,IAAI2B,MAAMf,IACH,SAKZ,CAOHqC,KAAM,SAASC,YACP3C,KAAOR,EAAEoD,SAASC,eAAeF,YAEjC3C,KAAK8C,cACE,IAAI/C,kBAAkBC,YAGvB,IAAI+C,MAAM"} \ No newline at end of file +{"version":3,"file":"managedocsactions.min.js","sources":["../src/managedocsactions.js"],"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 * Adds support for confirmation via JS modal for some management actions at the Manage policies page.\n *\n * @module tool_policy/managedocsactions\n * @copyright 2018 David Mudrák \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n 'jquery',\n 'core/log',\n 'core/config',\n 'core/str',\n 'core/modal_save_cancel',\n 'core/modal_events'\n], function($, Log, Config, Str, ModalSaveCancel, ModalEvents) {\n\n \"use strict\";\n\n /**\n * List of action selectors.\n *\n * @property {string} LINKS - Selector for all action links\n * @property {string} MAKE_CURRENT\n */\n var ACTION = {\n LINKS: '[data-action]',\n MAKE_CURRENT: '[data-action=\"makecurrent\"]',\n INACTIVATE: '[data-action=\"inactivate\"]',\n DELETE: '[data-action=\"delete\"]'\n };\n\n /**\n * @constructor\n * @param {Element} base - Management area wrapping element\n */\n function ManageDocsActions(base) {\n this.base = base;\n\n this.initEvents();\n }\n\n /**\n * Register event listeners.\n */\n ManageDocsActions.prototype.initEvents = function() {\n var self = this;\n\n self.base.on('click', ACTION.LINKS, function(e) {\n e.stopPropagation();\n\n var link = $(e.currentTarget);\n var promise;\n var strings;\n\n if (link.is(ACTION.MAKE_CURRENT)) {\n promise = Str.get_strings([\n {key: 'activating', component: 'tool_policy'},\n {key: 'activateconfirm', component: 'tool_policy', param: {\n name: link.closest('[data-policy-name]').attr('data-policy-name'),\n revision: link.closest('[data-policy-revision]').attr('data-policy-revision')\n }},\n {key: 'activateconfirmyes', component: 'tool_policy'}\n ]);\n\n } else if (link.is(ACTION.INACTIVATE)) {\n promise = Str.get_strings([\n {key: 'inactivating', component: 'tool_policy'},\n {key: 'inactivatingconfirm', component: 'tool_policy', param: {\n name: link.closest('[data-policy-name]').attr('data-policy-name'),\n revision: link.closest('[data-policy-revision]').attr('data-policy-revision')\n }},\n {key: 'inactivatingconfirmyes', component: 'tool_policy'}\n ]);\n\n } else if (link.is(ACTION.DELETE)) {\n promise = Str.get_strings([\n {key: 'deleting', component: 'tool_policy'},\n {key: 'deleteconfirm', component: 'tool_policy', param: {\n name: link.closest('[data-policy-name]').attr('data-policy-name'),\n revision: link.closest('[data-policy-revision]').attr('data-policy-revision')\n }},\n {key: 'delete', component: 'core'}\n ]);\n\n } else {\n Log.error('unknown action type detected', 'tool_policy/managedocsactions');\n return;\n }\n\n e.preventDefault();\n\n promise.then(function(strs) {\n strings = strs;\n return ModalSaveCancel.create({\n title: strings[0],\n body: strings[1],\n });\n\n }).then(function(modal) {\n modal.setSaveButtonText(strings[2]);\n modal.getRoot().on(ModalEvents.save, function() {\n window.location.href = link.attr('href') + '&sesskey=' + Config.sesskey + '&confirm=1';\n });\n\n modal.getRoot().on(ModalEvents.hidden, function() {\n modal.destroy();\n });\n\n modal.show();\n return true;\n\n }).catch(function(e) {\n Log.error(e);\n return false;\n });\n });\n };\n\n return {\n /**\n * Factory method returning instance of the ManageDocsActions\n *\n * @param {String} baseid - ID of the management area wrapping element\n * @return {ManageDocsActions}\n */\n init: function(baseid) {\n var base = $(document.getElementById(baseid));\n\n if (base.length) {\n return new ManageDocsActions(base);\n\n } else {\n throw new Error(\"managedocsactions: Invalid base element identifier\");\n }\n }\n };\n});\n"],"names":["define","$","Log","Config","Str","ModalSaveCancel","ModalEvents","ACTION","ManageDocsActions","base","initEvents","prototype","this","on","e","stopPropagation","promise","strings","link","currentTarget","is","get_strings","key","component","param","name","closest","attr","revision","error","preventDefault","then","strs","create","title","body","modal","setSaveButtonText","getRoot","save","window","location","href","sesskey","hidden","destroy","show","catch","init","baseid","document","getElementById","length","Error"],"mappings":";;;;;;;AAsBAA,uCAAO,CACH,SACA,WACA,cACA,WACA,yBACA,sBACD,SAASC,EAAGC,IAAKC,OAAQC,IAAKC,gBAAiBC,iBAU1CC,aACO,gBADPA,oBAEc,8BAFdA,kBAGY,6BAHZA,cAIQ,kCAOHC,kBAAkBC,WAClBA,KAAOA,UAEPC,oBAMTF,kBAAkBG,UAAUD,WAAa,WAC1BE,KAENH,KAAKI,GAAG,QAASN,cAAc,SAASO,GACzCA,EAAEC,sBAGEC,QACAC,QAFAC,KAAOjB,EAAEa,EAAEK,kBAIXD,KAAKE,GAAGb,qBACRS,QAAUZ,IAAIiB,YAAY,CACtB,CAACC,IAAK,aAAcC,UAAW,eAC/B,CAACD,IAAK,kBAAmBC,UAAW,cAAeC,MAAO,CACtDC,KAAMP,KAAKQ,QAAQ,sBAAsBC,KAAK,oBAC9CC,SAAUV,KAAKQ,QAAQ,0BAA0BC,KAAK,0BAE1D,CAACL,IAAK,qBAAsBC,UAAW,sBAGxC,GAAIL,KAAKE,GAAGb,mBACfS,QAAUZ,IAAIiB,YAAY,CACtB,CAACC,IAAK,eAAgBC,UAAW,eACjC,CAACD,IAAK,sBAAuBC,UAAW,cAAeC,MAAO,CAC1DC,KAAMP,KAAKQ,QAAQ,sBAAsBC,KAAK,oBAC9CC,SAAUV,KAAKQ,QAAQ,0BAA0BC,KAAK,0BAE1D,CAACL,IAAK,yBAA0BC,UAAW,qBAG5C,CAAA,IAAIL,KAAKE,GAAGb,2BAWfL,IAAI2B,MAAM,+BAAgC,iCAV1Cb,QAAUZ,IAAIiB,YAAY,CACtB,CAACC,IAAK,WAAYC,UAAW,eAC7B,CAACD,IAAK,gBAAiBC,UAAW,cAAeC,MAAO,CACpDC,KAAMP,KAAKQ,QAAQ,sBAAsBC,KAAK,oBAC9CC,SAAUV,KAAKQ,QAAQ,0BAA0BC,KAAK,0BAE1D,CAACL,IAAK,SAAUC,UAAW,UAQnCT,EAAEgB,iBAEFd,QAAQe,MAAK,SAASC,aAClBf,QAAUe,KACH3B,gBAAgB4B,OAAO,CAC1BC,MAAOjB,QAAQ,GACfkB,KAAMlB,QAAQ,QAGnBc,MAAK,SAASK,cACbA,MAAMC,kBAAkBpB,QAAQ,IAChCmB,MAAME,UAAUzB,GAAGP,YAAYiC,MAAM,WACjCC,OAAOC,SAASC,KAAOxB,KAAKS,KAAK,QAAU,YAAcxB,OAAOwC,QAAU,gBAG9EP,MAAME,UAAUzB,GAAGP,YAAYsC,QAAQ,WACnCR,MAAMS,aAGVT,MAAMU,QACC,KAERC,OAAM,SAASjC,UACdZ,IAAI2B,MAAMf,IACH,SAKZ,CAOHkC,KAAM,SAASC,YACPxC,KAAOR,EAAEiD,SAASC,eAAeF,YAEjCxC,KAAK2C,cACE,IAAI5C,kBAAkBC,YAGvB,IAAI4C,MAAM"} \ No newline at end of file diff --git a/admin/tool/policy/amd/build/policyactions.min.js b/admin/tool/policy/amd/build/policyactions.min.js index ec338571b8e..29a742b76dd 100644 --- a/admin/tool/policy/amd/build/policyactions.min.js +++ b/admin/tool/policy/amd/build/policyactions.min.js @@ -5,6 +5,6 @@ * @copyright 2018 Sara Arjona (sara@moodle.com) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -define("tool_policy/policyactions",["jquery","core/ajax","core/notification","core/modal_factory","core/modal_events"],(function($,Ajax,Notification,ModalFactory,ModalEvents){var PolicyActions=function(root){this.registerEvents(root)};return PolicyActions.prototype.registerEvents=function(root){root.on("click",(function(e){e.preventDefault();var request={methodname:"tool_policy_get_policy_version",args:{versionid:$(this).data("versionid"),behalfid:$(this).data("behalfid")}},modalTitle=$.Deferred(),modalBody=$.Deferred(),modal=ModalFactory.create({title:modalTitle,body:modalBody,large:!0}).then((function(modal){return modal.getRoot().on(ModalEvents.hidden,(function(){modal.destroy()})),modal})).then((function(modal){return modal.show(),modal})).catch(Notification.exception),promises=Ajax.call([request]);$.when(promises[0]).then((function(data){if(data.result.policy)return modalTitle.resolve(data.result.policy.name),modalBody.resolve(data.result.policy.content),data;throw new Error(data.warnings[0].message)})).catch((function(message){return modal.then((function(modal){return modal.hide(),modal.destroy(),modal})).catch(Notification.exception),Notification.addNotification({message:message,type:"error"})}))}))},{init:function(root){return root=$(root),new PolicyActions(root)}}})); +define("tool_policy/policyactions",["jquery","core/ajax","core/notification","core/modal"],(function($,Ajax,Notification,Modal){var PolicyActions=function(root){this.registerEvents(root)};return PolicyActions.prototype.registerEvents=function(root){root.on("click",(function(e){e.preventDefault();var request={methodname:"tool_policy_get_policy_version",args:{versionid:$(this).data("versionid"),behalfid:$(this).data("behalfid")}},modalTitle=$.Deferred(),modalBody=$.Deferred(),modal=Modal.create({title:modalTitle,body:modalBody,large:!0,removeOnClose:!0,show:!0}).catch(Notification.exception),promises=Ajax.call([request]);$.when(promises[0]).then((function(data){if(data.result.policy)return modalTitle.resolve(data.result.policy.name),modalBody.resolve(data.result.policy.content),data;throw new Error(data.warnings[0].message)})).catch((function(message){return modal.then((function(modal){return modal.hide(),modal})).catch(Notification.exception),Notification.addNotification({message:message,type:"error"})}))}))},{init:function(root){return root=$(root),new PolicyActions(root)}}})); //# sourceMappingURL=policyactions.min.js.map \ No newline at end of file diff --git a/admin/tool/policy/amd/build/policyactions.min.js.map b/admin/tool/policy/amd/build/policyactions.min.js.map index fb97f1b84ae..3f1311f855a 100644 --- a/admin/tool/policy/amd/build/policyactions.min.js.map +++ b/admin/tool/policy/amd/build/policyactions.min.js.map @@ -1 +1 @@ -{"version":3,"file":"policyactions.min.js","sources":["../src/policyactions.js"],"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 * Policy actions.\n *\n * @module tool_policy/policyactions\n * @copyright 2018 Sara Arjona (sara@moodle.com)\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n 'jquery',\n 'core/ajax',\n 'core/notification',\n 'core/modal_factory',\n 'core/modal_events'],\nfunction($, Ajax, Notification, ModalFactory, ModalEvents) {\n\n /**\n * PolicyActions class.\n *\n * @param {jQuery} root\n */\n var PolicyActions = function(root) {\n this.registerEvents(root);\n };\n\n /**\n * Register event listeners.\n *\n * @param {jQuery} root\n */\n PolicyActions.prototype.registerEvents = function(root) {\n root.on(\"click\", function(e) {\n e.preventDefault();\n\n var versionid = $(this).data('versionid');\n var behalfid = $(this).data('behalfid');\n\n var params = {\n 'versionid': versionid,\n 'behalfid': behalfid\n };\n\n var request = {\n methodname: 'tool_policy_get_policy_version',\n args: params\n };\n\n var modalTitle = $.Deferred();\n var modalBody = $.Deferred();\n\n var modal = ModalFactory.create({\n title: modalTitle,\n body: modalBody,\n large: true\n })\n .then(function(modal) {\n // Handle hidden event.\n modal.getRoot().on(ModalEvents.hidden, function() {\n // Destroy when hidden.\n modal.destroy();\n });\n\n return modal;\n })\n .then(function(modal) {\n modal.show();\n\n return modal;\n })\n .catch(Notification.exception);\n\n // Make the request now that the modal is configured.\n var promises = Ajax.call([request]);\n $.when(promises[0]).then(function(data) {\n if (data.result.policy) {\n modalTitle.resolve(data.result.policy.name);\n modalBody.resolve(data.result.policy.content);\n\n return data;\n } else {\n throw new Error(data.warnings[0].message);\n }\n }).catch(function(message) {\n modal.then(function(modal) {\n modal.hide();\n modal.destroy();\n\n return modal;\n })\n .catch(Notification.exception);\n\n return Notification.addNotification({\n message: message,\n type: 'error'\n });\n });\n });\n\n };\n\n return /** @alias module:tool_policy/policyactions */ {\n // Public variables and functions.\n\n /**\n * Initialise the actions helper.\n *\n * @method init\n * @param {object} root\n * @return {PolicyActions}\n */\n 'init': function(root) {\n root = $(root);\n return new PolicyActions(root);\n }\n };\n});\n"],"names":["define","$","Ajax","Notification","ModalFactory","ModalEvents","PolicyActions","root","registerEvents","prototype","on","e","preventDefault","request","methodname","args","this","data","modalTitle","Deferred","modalBody","modal","create","title","body","large","then","getRoot","hidden","destroy","show","catch","exception","promises","call","when","result","policy","resolve","name","content","Error","warnings","message","hide","addNotification","type"],"mappings":";;;;;;;AAsBAA,mCAAO,CACH,SACA,YACA,oBACA,qBACA,sBACJ,SAASC,EAAGC,KAAMC,aAAcC,aAAcC,iBAOtCC,cAAgB,SAASC,WACpBC,eAAeD,cAQxBD,cAAcG,UAAUD,eAAiB,SAASD,MAC9CA,KAAKG,GAAG,SAAS,SAASC,GACtBA,EAAEC,qBAUEC,QAAU,CACVC,WAAY,iCACZC,KAPS,WAHGd,EAAEe,MAAMC,KAAK,sBACdhB,EAAEe,MAAMC,KAAK,cAYxBC,WAAajB,EAAEkB,WACfC,UAAYnB,EAAEkB,WAEdE,MAAQjB,aAAakB,OAAO,CAC5BC,MAAOL,WACPM,KAAMJ,UACNK,OAAO,IAEVC,MAAK,SAASL,cAEXA,MAAMM,UAAUjB,GAAGL,YAAYuB,QAAQ,WAEnCP,MAAMQ,aAGHR,SAEVK,MAAK,SAASL,cACXA,MAAMS,OAECT,SAEVU,MAAM5B,aAAa6B,WAGhBC,SAAW/B,KAAKgC,KAAK,CAACrB,UAC1BZ,EAAEkC,KAAKF,SAAS,IAAIP,MAAK,SAAST,SAC1BA,KAAKmB,OAAOC,cACZnB,WAAWoB,QAAQrB,KAAKmB,OAAOC,OAAOE,MACtCnB,UAAUkB,QAAQrB,KAAKmB,OAAOC,OAAOG,SAE9BvB,WAED,IAAIwB,MAAMxB,KAAKyB,SAAS,GAAGC,YAEtCZ,OAAM,SAASY,gBACdtB,MAAMK,MAAK,SAASL,cAChBA,MAAMuB,OACNvB,MAAMQ,UAECR,SAEVU,MAAM5B,aAAa6B,WAEb7B,aAAa0C,gBAAgB,CAChCF,QAASA,QACTG,KAAM,iBAOgC,MAU1C,SAASvC,aACbA,KAAON,EAAEM,MACF,IAAID,cAAcC"} \ No newline at end of file +{"version":3,"file":"policyactions.min.js","sources":["../src/policyactions.js"],"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 * Policy actions.\n *\n * @module tool_policy/policyactions\n * @copyright 2018 Sara Arjona (sara@moodle.com)\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n 'jquery',\n 'core/ajax',\n 'core/notification',\n 'core/modal',\n], function($, Ajax, Notification, Modal) {\n\n /**\n * PolicyActions class.\n *\n * @param {jQuery} root\n */\n var PolicyActions = function(root) {\n this.registerEvents(root);\n };\n\n /**\n * Register event listeners.\n *\n * @param {jQuery} root\n */\n PolicyActions.prototype.registerEvents = function(root) {\n root.on(\"click\", function(e) {\n e.preventDefault();\n\n var versionid = $(this).data('versionid');\n var behalfid = $(this).data('behalfid');\n\n var params = {\n 'versionid': versionid,\n 'behalfid': behalfid\n };\n\n var request = {\n methodname: 'tool_policy_get_policy_version',\n args: params\n };\n\n var modalTitle = $.Deferred();\n var modalBody = $.Deferred();\n\n var modal = Modal.create({\n title: modalTitle,\n body: modalBody,\n large: true,\n removeOnClose: true,\n show: true,\n })\n .catch(Notification.exception);\n\n // Make the request now that the modal is configured.\n var promises = Ajax.call([request]);\n $.when(promises[0]).then(function(data) {\n if (data.result.policy) {\n modalTitle.resolve(data.result.policy.name);\n modalBody.resolve(data.result.policy.content);\n\n return data;\n } else {\n throw new Error(data.warnings[0].message);\n }\n }).catch(function(message) {\n modal.then(function(modal) {\n modal.hide();\n\n return modal;\n })\n .catch(Notification.exception);\n\n return Notification.addNotification({\n message: message,\n type: 'error'\n });\n });\n });\n\n };\n\n return /** @alias module:tool_policy/policyactions */ {\n // Public variables and functions.\n\n /**\n * Initialise the actions helper.\n *\n * @method init\n * @param {object} root\n * @return {PolicyActions}\n */\n 'init': function(root) {\n root = $(root);\n return new PolicyActions(root);\n }\n };\n});\n"],"names":["define","$","Ajax","Notification","Modal","PolicyActions","root","registerEvents","prototype","on","e","preventDefault","request","methodname","args","this","data","modalTitle","Deferred","modalBody","modal","create","title","body","large","removeOnClose","show","catch","exception","promises","call","when","then","result","policy","resolve","name","content","Error","warnings","message","hide","addNotification","type"],"mappings":";;;;;;;AAsBAA,mCAAO,CACH,SACA,YACA,oBACA,eACD,SAASC,EAAGC,KAAMC,aAAcC,WAO3BC,cAAgB,SAASC,WACpBC,eAAeD,cAQxBD,cAAcG,UAAUD,eAAiB,SAASD,MAC9CA,KAAKG,GAAG,SAAS,SAASC,GACtBA,EAAEC,qBAUEC,QAAU,CACVC,WAAY,iCACZC,KAPS,WAHGb,EAAEc,MAAMC,KAAK,sBACdf,EAAEc,MAAMC,KAAK,cAYxBC,WAAahB,EAAEiB,WACfC,UAAYlB,EAAEiB,WAEdE,MAAQhB,MAAMiB,OAAO,CACrBC,MAAOL,WACPM,KAAMJ,UACNK,OAAO,EACPC,eAAe,EACfC,MAAM,IAETC,MAAMxB,aAAayB,WAGhBC,SAAW3B,KAAK4B,KAAK,CAAClB,UAC1BX,EAAE8B,KAAKF,SAAS,IAAIG,MAAK,SAAShB,SAC1BA,KAAKiB,OAAOC,cACZjB,WAAWkB,QAAQnB,KAAKiB,OAAOC,OAAOE,MACtCjB,UAAUgB,QAAQnB,KAAKiB,OAAOC,OAAOG,SAE9BrB,WAED,IAAIsB,MAAMtB,KAAKuB,SAAS,GAAGC,YAEtCb,OAAM,SAASa,gBACdpB,MAAMY,MAAK,SAASZ,cAChBA,MAAMqB,OAECrB,SAEVO,MAAMxB,aAAayB,WAEbzB,aAAauC,gBAAgB,CAChCF,QAASA,QACTG,KAAM,iBAOgC,MAU1C,SAASrC,aACbA,KAAOL,EAAEK,MACF,IAAID,cAAcC"} \ No newline at end of file diff --git a/admin/tool/policy/amd/src/acceptmodal.js b/admin/tool/policy/amd/src/acceptmodal.js index 31f7241255a..1d6c564339e 100644 --- a/admin/tool/policy/amd/src/acceptmodal.js +++ b/admin/tool/policy/amd/src/acceptmodal.js @@ -23,7 +23,7 @@ define([ 'jquery', 'core/str', - 'core/modal_factory', + 'core/modal_save_cancel', 'core/modal_events', 'core/notification', 'core/fragment', @@ -32,7 +32,7 @@ define([ ], function( $, Str, - ModalFactory, + ModalSaveCancel, ModalEvents, Notification, Fragment, @@ -153,11 +153,10 @@ define([ saveText = strings[5]; } // Create the modal. - return ModalFactory.create({ - type: ModalFactory.types.SAVE_CANCEL, + return ModalSaveCancel.create({ title: title, body: '' - }).done(function(modal) { + }).then(function(modal) { this.modal = modal; this.setupFormModal(formData, saveText); }.bind(this)); diff --git a/admin/tool/policy/amd/src/managedocsactions.js b/admin/tool/policy/amd/src/managedocsactions.js index 162905f892f..2cde45c35c4 100644 --- a/admin/tool/policy/amd/src/managedocsactions.js +++ b/admin/tool/policy/amd/src/managedocsactions.js @@ -25,9 +25,9 @@ define([ 'core/log', 'core/config', 'core/str', - 'core/modal_factory', + 'core/modal_save_cancel', 'core/modal_events' -], function($, Log, Config, Str, ModalFactory, ModalEvents) { +], function($, Log, Config, Str, ModalSaveCancel, ModalEvents) { "use strict"; @@ -106,10 +106,9 @@ define([ promise.then(function(strs) { strings = strs; - return ModalFactory.create({ + return ModalSaveCancel.create({ title: strings[0], body: strings[1], - type: ModalFactory.types.SAVE_CANCEL }); }).then(function(modal) { diff --git a/admin/tool/policy/amd/src/policyactions.js b/admin/tool/policy/amd/src/policyactions.js index c4c7bf1e807..45fc07fb68d 100644 --- a/admin/tool/policy/amd/src/policyactions.js +++ b/admin/tool/policy/amd/src/policyactions.js @@ -24,9 +24,8 @@ define([ 'jquery', 'core/ajax', 'core/notification', - 'core/modal_factory', - 'core/modal_events'], -function($, Ajax, Notification, ModalFactory, ModalEvents) { + 'core/modal', +], function($, Ajax, Notification, Modal) { /** * PolicyActions class. @@ -62,24 +61,12 @@ function($, Ajax, Notification, ModalFactory, ModalEvents) { var modalTitle = $.Deferred(); var modalBody = $.Deferred(); - var modal = ModalFactory.create({ + var modal = Modal.create({ title: modalTitle, body: modalBody, - large: true - }) - .then(function(modal) { - // Handle hidden event. - modal.getRoot().on(ModalEvents.hidden, function() { - // Destroy when hidden. - modal.destroy(); - }); - - return modal; - }) - .then(function(modal) { - modal.show(); - - return modal; + large: true, + removeOnClose: true, + show: true, }) .catch(Notification.exception); @@ -97,7 +84,6 @@ function($, Ajax, Notification, ModalFactory, ModalEvents) { }).catch(function(message) { modal.then(function(modal) { modal.hide(); - modal.destroy(); return modal; }) diff --git a/blocks/amd/build/add_modal.min.js b/blocks/amd/build/add_modal.min.js index ac5b2410399..573ab5de3f9 100644 --- a/blocks/amd/build/add_modal.min.js +++ b/blocks/amd/build/add_modal.min.js @@ -1,10 +1,10 @@ -define("core_block/add_modal",["exports","core/modal_factory","core/templates","core/str","core/ajax","core_form/modalform"],(function(_exports,_modal_factory,_templates,_str,_ajax,_modalform){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}} +define("core_block/add_modal",["exports","core/templates","core/str","core/ajax","core_form/modalform","core/modal_cancel"],(function(_exports,_templates,_str,_ajax,_modalform,_modal_cancel){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}} /** * Show an add block modal instead of doing it on a separate page. * * @module core_block/add_modal * @copyright 2016 Damyon Wiese * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_modal_factory=_interopRequireDefault(_modal_factory),_templates=_interopRequireDefault(_templates),_ajax=_interopRequireDefault(_ajax),_modalform=_interopRequireDefault(_modalform);const SELECTORS_ADD_BLOCK='[data-key="addblock"]',SELECTORS_SHOW_BLOCK_FORM='[data-action="showaddblockform"][data-blockname][data-blockform]';let listenerEventsRegistered=!1;const registerListenerEvents=(addBlockUrl,pagehash)=>{let addBlockModal=null;document.addEventListener("click",(e=>{const showAddBlockForm=e.target.closest(SELECTORS_SHOW_BLOCK_FORM);if(showAddBlockForm){e.preventDefault();const modalForm=new _modalform.default({modalConfig:{title:(0,_str.getString)("addblock","core_block",showAddBlockForm.getAttribute("data-blocktitle"))},args:{blockname:showAddBlockForm.getAttribute("data-blockname"),pagehash:pagehash,blockregion:showAddBlockForm.getAttribute("data-blockregion")},formClass:showAddBlockForm.getAttribute("data-blockform"),returnFocus:showAddBlockForm});modalForm.addEventListener(modalForm.events.FORM_SUBMITTED,(()=>{addBlockModal.destroy(),window.location.reload()})),modalForm.show()}const addBlock=e.target.closest(SELECTORS_ADD_BLOCK);if(addBlock){e.preventDefault();let addBlockModalUrl=null!=addBlockUrl?addBlockUrl:addBlock.dataset.url;buildAddBlockModal().then((modal=>{addBlockModal=modal;const modalBody=renderBlocks(addBlockModalUrl,pagehash,addBlock.getAttribute("data-blockregion"));return modal.setBody(modalBody),modal.show(),modalBody})).catch((()=>{addBlockModal.destroy()}))}}))},buildAddBlockModal=()=>_modal_factory.default.create({type:_modal_factory.default.types.CANCEL,title:(0,_str.getString)("addblock")}),renderBlocks=async(addBlockUrl,pagehash,region)=>{const blocks=await getAddableBlocks(pagehash);return _templates.default.render("core/add_block_body",{blocks:blocks,url:addBlockUrl,blockregion:region,pagehash:pagehash})},getAddableBlocks=async pagehash=>{const request={methodname:"core_block_fetch_addable_blocks",args:{pagecontextid:0,pagetype:"",pagelayout:"",subpage:"",pagehash:pagehash}};return _ajax.default.call([request])[0]};_exports.init=function(){let addBlockUrl=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,pagehash=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";listenerEventsRegistered||(registerListenerEvents(addBlockUrl,pagehash),listenerEventsRegistered=!0)}})); + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_templates=_interopRequireDefault(_templates),_ajax=_interopRequireDefault(_ajax),_modalform=_interopRequireDefault(_modalform),_modal_cancel=_interopRequireDefault(_modal_cancel);const SELECTORS_ADD_BLOCK='[data-key="addblock"]',SELECTORS_SHOW_BLOCK_FORM='[data-action="showaddblockform"][data-blockname][data-blockform]';let listenerEventsRegistered=!1;const registerListenerEvents=(addBlockUrl,pagehash)=>{let addBlockModal=null;document.addEventListener("click",(e=>{const showAddBlockForm=e.target.closest(SELECTORS_SHOW_BLOCK_FORM);if(showAddBlockForm){e.preventDefault();const modalForm=new _modalform.default({modalConfig:{title:(0,_str.getString)("addblock","core_block",showAddBlockForm.getAttribute("data-blocktitle"))},args:{blockname:showAddBlockForm.getAttribute("data-blockname"),pagehash:pagehash,blockregion:showAddBlockForm.getAttribute("data-blockregion")},formClass:showAddBlockForm.getAttribute("data-blockform"),returnFocus:showAddBlockForm});modalForm.addEventListener(modalForm.events.FORM_SUBMITTED,(()=>{addBlockModal.destroy(),window.location.reload()})),modalForm.show()}const addBlock=e.target.closest(SELECTORS_ADD_BLOCK);if(addBlock){e.preventDefault();let addBlockModalUrl=null!=addBlockUrl?addBlockUrl:addBlock.dataset.url;buildAddBlockModal().then((modal=>{addBlockModal=modal;const modalBody=renderBlocks(addBlockModalUrl,pagehash,addBlock.getAttribute("data-blockregion"));return modal.setBody(modalBody),modal.show(),modalBody})).catch((()=>{addBlockModal.destroy()}))}}))},buildAddBlockModal=()=>_modal_cancel.default.create({title:(0,_str.getString)("addblock")}),renderBlocks=async(addBlockUrl,pagehash,region)=>{const blocks=await getAddableBlocks(pagehash);return _templates.default.render("core/add_block_body",{blocks:blocks,url:addBlockUrl,blockregion:region,pagehash:pagehash})},getAddableBlocks=async pagehash=>{const request={methodname:"core_block_fetch_addable_blocks",args:{pagecontextid:0,pagetype:"",pagelayout:"",subpage:"",pagehash:pagehash}};return _ajax.default.call([request])[0]};_exports.init=function(){let addBlockUrl=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,pagehash=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";listenerEventsRegistered||(registerListenerEvents(addBlockUrl,pagehash),listenerEventsRegistered=!0)}})); //# sourceMappingURL=add_modal.min.js.map \ No newline at end of file diff --git a/blocks/amd/build/add_modal.min.js.map b/blocks/amd/build/add_modal.min.js.map index 8ad213dd9f5..75b95adb5be 100644 --- a/blocks/amd/build/add_modal.min.js.map +++ b/blocks/amd/build/add_modal.min.js.map @@ -1 +1 @@ -{"version":3,"file":"add_modal.min.js","sources":["../src/add_modal.js"],"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 * Show an add block modal instead of doing it on a separate page.\n *\n * @module core_block/add_modal\n * @copyright 2016 Damyon Wiese \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport ModalFactory from 'core/modal_factory';\nimport Templates from 'core/templates';\nimport {getString} from 'core/str';\nimport Ajax from 'core/ajax';\nimport ModalForm from \"core_form/modalform\";\n\nconst SELECTORS = {\n ADD_BLOCK: '[data-key=\"addblock\"]',\n SHOW_BLOCK_FORM: '[data-action=\"showaddblockform\"][data-blockname][data-blockform]'\n};\n\n// Ensure we only add our listeners once.\nlet listenerEventsRegistered = false;\n\n/**\n * Register related event listeners.\n *\n * @method registerListenerEvents\n * @param {String|null} addBlockUrl The add block URL\n * @param {String} pagehash\n */\nconst registerListenerEvents = (addBlockUrl, pagehash) => {\n let addBlockModal = null;\n document.addEventListener('click', e => {\n\n const showAddBlockForm = e.target.closest(SELECTORS.SHOW_BLOCK_FORM);\n if (showAddBlockForm) {\n e.preventDefault();\n\n const modalForm = new ModalForm({\n modalConfig: {\n title: getString('addblock', 'core_block',\n showAddBlockForm.getAttribute('data-blocktitle')),\n },\n args: {blockname: showAddBlockForm.getAttribute('data-blockname'), pagehash,\n blockregion: showAddBlockForm.getAttribute('data-blockregion')},\n formClass: showAddBlockForm.getAttribute('data-blockform'),\n returnFocus: showAddBlockForm,\n });\n\n modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, () => {\n addBlockModal.destroy();\n window.location.reload();\n });\n\n modalForm.show();\n }\n\n const addBlock = e.target.closest(SELECTORS.ADD_BLOCK);\n if (addBlock) {\n e.preventDefault();\n\n let addBlockModalUrl = addBlockUrl ?? addBlock.dataset.url;\n\n buildAddBlockModal()\n .then(modal => {\n addBlockModal = modal;\n const modalBody = renderBlocks(addBlockModalUrl, pagehash,\n addBlock.getAttribute('data-blockregion'));\n modal.setBody(modalBody);\n modal.show();\n\n return modalBody;\n })\n .catch(() => {\n addBlockModal.destroy();\n });\n }\n });\n};\n\n/**\n * Method that creates the 'add block' modal.\n *\n * @method buildAddBlockModal\n * @returns {Promise} The modal promise (modal's body will be rendered later).\n */\nconst buildAddBlockModal = () => {\n return ModalFactory.create({\n type: ModalFactory.types.CANCEL,\n title: getString('addblock')\n });\n};\n\n/**\n * Method that renders the list of available blocks.\n *\n * @method renderBlocks\n * @param {String} addBlockUrl The add block URL\n * @param {String} pagehash\n * @param {String} region\n * @return {Promise}\n */\nconst renderBlocks = async(addBlockUrl, pagehash, region) => {\n // Fetch all addable blocks in the given page.\n const blocks = await getAddableBlocks(pagehash);\n\n return Templates.render('core/add_block_body', {\n blocks: blocks,\n url: addBlockUrl,\n blockregion: region,\n pagehash\n });\n};\n\n/**\n * Method that fetches all addable blocks in a given page.\n *\n * @method getAddableBlocks\n * @param {String} pagehash\n * @return {Promise}\n */\nconst getAddableBlocks = async(pagehash) => {\n const request = {\n methodname: 'core_block_fetch_addable_blocks',\n args: {\n pagecontextid: 0,\n pagetype: '',\n pagelayout: '',\n subpage: '',\n pagehash: pagehash,\n },\n };\n\n return Ajax.call([request])[0];\n};\n\n/**\n * Set up the actions.\n *\n * @method init\n * @param {String} addBlockUrl The add block URL\n * @param {String} pagehash\n */\nexport const init = (addBlockUrl = null, pagehash = '') => {\n if (!listenerEventsRegistered) {\n registerListenerEvents(addBlockUrl, pagehash);\n listenerEventsRegistered = true;\n }\n};\n"],"names":["SELECTORS","listenerEventsRegistered","registerListenerEvents","addBlockUrl","pagehash","addBlockModal","document","addEventListener","e","showAddBlockForm","target","closest","preventDefault","modalForm","ModalForm","modalConfig","title","getAttribute","args","blockname","blockregion","formClass","returnFocus","events","FORM_SUBMITTED","destroy","window","location","reload","show","addBlock","addBlockModalUrl","dataset","url","buildAddBlockModal","then","modal","modalBody","renderBlocks","setBody","catch","ModalFactory","create","type","types","CANCEL","async","region","blocks","getAddableBlocks","Templates","render","request","methodname","pagecontextid","pagetype","pagelayout","subpage","Ajax","call"],"mappings":";;;;;;;8QA6BMA,oBACS,wBADTA,0BAEe,uEAIjBC,0BAA2B,QASzBC,uBAAyB,CAACC,YAAaC,gBACrCC,cAAgB,KACpBC,SAASC,iBAAiB,SAASC,UAEzBC,iBAAmBD,EAAEE,OAAOC,QAAQX,8BACtCS,iBAAkB,CAClBD,EAAEI,uBAEIC,UAAY,IAAIC,mBAAU,CAC5BC,YAAa,CACTC,OAAO,kBAAU,WAAY,aACzBP,iBAAiBQ,aAAa,qBAEtCC,KAAM,CAACC,UAAWV,iBAAiBQ,aAAa,kBAAmBb,SAAAA,SAC/DgB,YAAaX,iBAAiBQ,aAAa,qBAC/CI,UAAWZ,iBAAiBQ,aAAa,kBACzCK,YAAab,mBAGjBI,UAAUN,iBAAiBM,UAAUU,OAAOC,gBAAgB,KACxDnB,cAAcoB,UACdC,OAAOC,SAASC,YAGpBf,UAAUgB,aAGRC,SAAWtB,EAAEE,OAAOC,QAAQX,wBAC9B8B,SAAU,CACVtB,EAAEI,qBAEEmB,iBAAmB5B,MAAAA,YAAAA,YAAe2B,SAASE,QAAQC,IAEvDC,qBACKC,MAAKC,QACF/B,cAAgB+B,YACVC,UAAYC,aAAaP,iBAAkB3B,SAC7C0B,SAASb,aAAa,4BAC1BmB,MAAMG,QAAQF,WACdD,MAAMP,OAECQ,aAEVG,OAAM,KACHnC,cAAcoB,kBAY5BS,mBAAqB,IAChBO,uBAAaC,OAAO,CACvBC,KAAMF,uBAAaG,MAAMC,OACzB7B,OAAO,kBAAU,cAanBsB,aAAeQ,MAAM3C,YAAaC,SAAU2C,gBAExCC,aAAeC,iBAAiB7C,iBAE/B8C,mBAAUC,OAAO,sBAAuB,CAC3CH,OAAQA,OACRf,IAAK9B,YACLiB,YAAa2B,OACb3C,SAAAA,YAWF6C,iBAAmBH,MAAAA,iBACfM,QAAU,CACZC,WAAY,kCACZnC,KAAM,CACFoC,cAAe,EACfC,SAAU,GACVC,WAAY,GACZC,QAAS,GACTrD,SAAUA,kBAIXsD,cAAKC,KAAK,CAACP,UAAU,kBAUZ,eAACjD,mEAAc,KAAMC,gEAAW,GAC3CH,2BACDC,uBAAuBC,YAAaC,UACpCH,0BAA2B"} \ No newline at end of file +{"version":3,"file":"add_modal.min.js","sources":["../src/add_modal.js"],"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 * Show an add block modal instead of doing it on a separate page.\n *\n * @module core_block/add_modal\n * @copyright 2016 Damyon Wiese \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Templates from 'core/templates';\nimport {getString} from 'core/str';\nimport Ajax from 'core/ajax';\nimport ModalForm from \"core_form/modalform\";\nimport CancelModal from 'core/modal_cancel';\n\nconst SELECTORS = {\n ADD_BLOCK: '[data-key=\"addblock\"]',\n SHOW_BLOCK_FORM: '[data-action=\"showaddblockform\"][data-blockname][data-blockform]'\n};\n\n// Ensure we only add our listeners once.\nlet listenerEventsRegistered = false;\n\n/**\n * Register related event listeners.\n *\n * @method registerListenerEvents\n * @param {String|null} addBlockUrl The add block URL\n * @param {String} pagehash\n */\nconst registerListenerEvents = (addBlockUrl, pagehash) => {\n let addBlockModal = null;\n document.addEventListener('click', e => {\n\n const showAddBlockForm = e.target.closest(SELECTORS.SHOW_BLOCK_FORM);\n if (showAddBlockForm) {\n e.preventDefault();\n\n const modalForm = new ModalForm({\n modalConfig: {\n title: getString('addblock', 'core_block',\n showAddBlockForm.getAttribute('data-blocktitle')),\n },\n args: {blockname: showAddBlockForm.getAttribute('data-blockname'), pagehash,\n blockregion: showAddBlockForm.getAttribute('data-blockregion')},\n formClass: showAddBlockForm.getAttribute('data-blockform'),\n returnFocus: showAddBlockForm,\n });\n\n modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, () => {\n addBlockModal.destroy();\n window.location.reload();\n });\n\n modalForm.show();\n }\n\n const addBlock = e.target.closest(SELECTORS.ADD_BLOCK);\n if (addBlock) {\n e.preventDefault();\n\n let addBlockModalUrl = addBlockUrl ?? addBlock.dataset.url;\n\n buildAddBlockModal()\n .then(modal => {\n addBlockModal = modal;\n const modalBody = renderBlocks(addBlockModalUrl, pagehash,\n addBlock.getAttribute('data-blockregion'));\n modal.setBody(modalBody);\n modal.show();\n\n return modalBody;\n })\n .catch(() => {\n addBlockModal.destroy();\n });\n }\n });\n};\n\n/**\n * Method that creates the 'add block' modal.\n *\n * @method buildAddBlockModal\n * @returns {Promise} The modal promise (modal's body will be rendered later).\n */\nconst buildAddBlockModal = () => CancelModal.create({\n title: getString('addblock'),\n});\n\n/**\n * Method that renders the list of available blocks.\n *\n * @method renderBlocks\n * @param {String} addBlockUrl The add block URL\n * @param {String} pagehash\n * @param {String} region\n * @return {Promise}\n */\nconst renderBlocks = async(addBlockUrl, pagehash, region) => {\n // Fetch all addable blocks in the given page.\n const blocks = await getAddableBlocks(pagehash);\n\n return Templates.render('core/add_block_body', {\n blocks: blocks,\n url: addBlockUrl,\n blockregion: region,\n pagehash\n });\n};\n\n/**\n * Method that fetches all addable blocks in a given page.\n *\n * @method getAddableBlocks\n * @param {String} pagehash\n * @return {Promise}\n */\nconst getAddableBlocks = async(pagehash) => {\n const request = {\n methodname: 'core_block_fetch_addable_blocks',\n args: {\n pagecontextid: 0,\n pagetype: '',\n pagelayout: '',\n subpage: '',\n pagehash: pagehash,\n },\n };\n\n return Ajax.call([request])[0];\n};\n\n/**\n * Set up the actions.\n *\n * @method init\n * @param {String} addBlockUrl The add block URL\n * @param {String} pagehash\n */\nexport const init = (addBlockUrl = null, pagehash = '') => {\n if (!listenerEventsRegistered) {\n registerListenerEvents(addBlockUrl, pagehash);\n listenerEventsRegistered = true;\n }\n};\n"],"names":["SELECTORS","listenerEventsRegistered","registerListenerEvents","addBlockUrl","pagehash","addBlockModal","document","addEventListener","e","showAddBlockForm","target","closest","preventDefault","modalForm","ModalForm","modalConfig","title","getAttribute","args","blockname","blockregion","formClass","returnFocus","events","FORM_SUBMITTED","destroy","window","location","reload","show","addBlock","addBlockModalUrl","dataset","url","buildAddBlockModal","then","modal","modalBody","renderBlocks","setBody","catch","CancelModal","create","async","region","blocks","getAddableBlocks","Templates","render","request","methodname","pagecontextid","pagetype","pagelayout","subpage","Ajax","call"],"mappings":";;;;;;;4QA6BMA,oBACS,wBADTA,0BAEe,uEAIjBC,0BAA2B,QASzBC,uBAAyB,CAACC,YAAaC,gBACrCC,cAAgB,KACpBC,SAASC,iBAAiB,SAASC,UAEzBC,iBAAmBD,EAAEE,OAAOC,QAAQX,8BACtCS,iBAAkB,CAClBD,EAAEI,uBAEIC,UAAY,IAAIC,mBAAU,CAC5BC,YAAa,CACTC,OAAO,kBAAU,WAAY,aACzBP,iBAAiBQ,aAAa,qBAEtCC,KAAM,CAACC,UAAWV,iBAAiBQ,aAAa,kBAAmBb,SAAAA,SAC/DgB,YAAaX,iBAAiBQ,aAAa,qBAC/CI,UAAWZ,iBAAiBQ,aAAa,kBACzCK,YAAab,mBAGjBI,UAAUN,iBAAiBM,UAAUU,OAAOC,gBAAgB,KACxDnB,cAAcoB,UACdC,OAAOC,SAASC,YAGpBf,UAAUgB,aAGRC,SAAWtB,EAAEE,OAAOC,QAAQX,wBAC9B8B,SAAU,CACVtB,EAAEI,qBAEEmB,iBAAmB5B,MAAAA,YAAAA,YAAe2B,SAASE,QAAQC,IAEvDC,qBACKC,MAAKC,QACF/B,cAAgB+B,YACVC,UAAYC,aAAaP,iBAAkB3B,SAC7C0B,SAASb,aAAa,4BAC1BmB,MAAMG,QAAQF,WACdD,MAAMP,OAECQ,aAEVG,OAAM,KACHnC,cAAcoB,kBAY5BS,mBAAqB,IAAMO,sBAAYC,OAAO,CAChD1B,OAAO,kBAAU,cAYfsB,aAAeK,MAAMxC,YAAaC,SAAUwC,gBAExCC,aAAeC,iBAAiB1C,iBAE/B2C,mBAAUC,OAAO,sBAAuB,CAC3CH,OAAQA,OACRZ,IAAK9B,YACLiB,YAAawB,OACbxC,SAAAA,YAWF0C,iBAAmBH,MAAAA,iBACfM,QAAU,CACZC,WAAY,kCACZhC,KAAM,CACFiC,cAAe,EACfC,SAAU,GACVC,WAAY,GACZC,QAAS,GACTlD,SAAUA,kBAIXmD,cAAKC,KAAK,CAACP,UAAU,kBAUZ,eAAC9C,mEAAc,KAAMC,gEAAW,GAC3CH,2BACDC,uBAAuBC,YAAaC,UACpCH,0BAA2B"} \ No newline at end of file diff --git a/blocks/amd/src/add_modal.js b/blocks/amd/src/add_modal.js index 74732917433..5b3ad5aade5 100644 --- a/blocks/amd/src/add_modal.js +++ b/blocks/amd/src/add_modal.js @@ -21,11 +21,11 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -import ModalFactory from 'core/modal_factory'; import Templates from 'core/templates'; import {getString} from 'core/str'; import Ajax from 'core/ajax'; import ModalForm from "core_form/modalform"; +import CancelModal from 'core/modal_cancel'; const SELECTORS = { ADD_BLOCK: '[data-key="addblock"]', @@ -98,12 +98,9 @@ const registerListenerEvents = (addBlockUrl, pagehash) => { * @method buildAddBlockModal * @returns {Promise} The modal promise (modal's body will be rendered later). */ -const buildAddBlockModal = () => { - return ModalFactory.create({ - type: ModalFactory.types.CANCEL, - title: getString('addblock') - }); -}; +const buildAddBlockModal = () => CancelModal.create({ + title: getString('addblock'), +}); /** * Method that renders the list of available blocks. diff --git a/calendar/amd/build/calendar.min.js b/calendar/amd/build/calendar.min.js index be24c1a68ff..082b1d167cc 100644 --- a/calendar/amd/build/calendar.min.js +++ b/calendar/amd/build/calendar.min.js @@ -9,6 +9,6 @@ * @copyright 2017 Simey Lameze * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -define("core_calendar/calendar",["jquery","core/templates","core/notification","core_calendar/repository","core_calendar/events","core_calendar/view_manager","core_calendar/crud","core_calendar/selectors","core/config"],(function($,Templates,Notification,CalendarRepository,CalendarEvents,CalendarViewManager,CalendarCrud,CalendarSelectors,Config){var SELECTORS_DAY="[data-region='day']",SELECTORS_DAY_CONTENT="[data-region='day-content']",SELECTORS_LOADING_ICON=".loading-icon",SELECTORS_VIEW_DAY_LINK="[data-action='view-day-link']",SELECTORS_CALENDAR_MONTH_WRAPPER=".calendarwrapper",handleMoveEvent=function(e,eventId,originElement,destinationElement){var originTimestamp=null,destinationTimestamp=destinationElement.attr("data-day-timestamp");originElement&&(originTimestamp=originElement.attr("data-day-timestamp")),originElement&&originTimestamp==destinationTimestamp||Templates.render("core/loading",{}).then((function(html,js){destinationElement.find(SELECTORS_DAY_CONTENT).addClass("hidden"),Templates.appendNodeContents(destinationElement,html,js),originElement&&(originElement.find(SELECTORS_DAY_CONTENT).addClass("hidden"),Templates.appendNodeContents(originElement,html,js))})).then((function(){return CalendarRepository.updateEventStartDay(eventId,destinationTimestamp)})).then((function(){$("body").trigger(CalendarEvents.eventMoved,[eventId,originElement,destinationElement])})).always((function(){var destinationLoadingElement=destinationElement.find(SELECTORS_LOADING_ICON);if(destinationElement.find(SELECTORS_DAY_CONTENT).removeClass("hidden"),Templates.replaceNode(destinationLoadingElement,"",""),originElement){var originLoadingElement=originElement.find(SELECTORS_LOADING_ICON);originElement.find(SELECTORS_DAY_CONTENT).removeClass("hidden"),Templates.replaceNode(originLoadingElement,"","")}})).fail(Notification.exception)},registerEventListeners=function(root){const viewingFullCalendar=document.getElementById(CalendarSelectors.fullCalendarView);root.on("click",SELECTORS_VIEW_DAY_LINK,(function(e){var dayLink=$(e.target).closest(SELECTORS_VIEW_DAY_LINK),year=dayLink.data("year"),month=dayLink.data("month"),day=dayLink.data("day"),courseId=dayLink.data("courseid"),categoryId=dayLink.data("categoryid");const url="?view=day&time="+dayLink.data("timestamp");viewingFullCalendar?CalendarViewManager.refreshDayContent(root,year,month,day,courseId,categoryId,root,"core_calendar/calendar_day").then((function(){return e.preventDefault(),CalendarViewManager.updateUrl(url)})).fail(Notification.exception):window.location.assign(Config.wwwroot+"/calendar/view.php"+url)})),root.on("change",CalendarSelectors.elements.courseSelector,(function(){var courseId=$(this).val();CalendarViewManager.reloadCurrentMonth(root,courseId,null).then((function(){return root.find(CalendarSelectors.elements.courseSelector).val(courseId)})).fail(Notification.exception)}));var eventFormPromise=CalendarCrud.registerEventFormModal(root),contextId=$(SELECTORS_CALENDAR_MONTH_WRAPPER).data("context-id");!function(root,eventFormModalPromise){var body=$("body");body.on(CalendarEvents.created,(function(){CalendarViewManager.reloadCurrentMonth(root)})),body.on(CalendarEvents.deleted,(function(){CalendarViewManager.reloadCurrentMonth(root)})),body.on(CalendarEvents.updated,(function(){CalendarViewManager.reloadCurrentMonth(root)})),body.on(CalendarEvents.editActionEvent,(function(e,url){window.location.assign(url)})),body.on(CalendarEvents.moveEvent,handleMoveEvent),body.on(CalendarEvents.eventMoved,(function(){CalendarViewManager.reloadCurrentMonth(root)})),CalendarCrud.registerEditListeners(root,eventFormModalPromise)}(root,eventFormPromise),contextId&&root.on("click",SELECTORS_DAY,(function(e){var target=$(e.target);const displayingSmallBlockCalendar="side-pre"===root.parents("aside").data("blockregion");if(!viewingFullCalendar&&displayingSmallBlockCalendar){const url="?view=day&time="+target.closest(SELECTORS_DAY).data("day-timestamp");window.location.assign(Config.wwwroot+"/calendar/view.php"+url)}else{if(!target.closest(SELECTORS_VIEW_DAY_LINK).length){var startTime=$(this).attr("data-new-event-timestamp");eventFormPromise.then((function(modal){var wrapper=target.closest(CalendarSelectors.wrapper);modal.setCourseId(wrapper.data("courseid"));var categoryId=wrapper.data("categoryid");void 0!==categoryId&&modal.setCategoryId(categoryId),modal.setContextId(wrapper.data("contextId")),modal.setStartTime(startTime),modal.show()})).fail(Notification.exception)}}e.preventDefault()}))};return{init:function(root){root=$(root),CalendarViewManager.init(root),registerEventListeners(root)}}})); +define("core_calendar/calendar",["jquery","core/templates","core/notification","core_calendar/repository","core_calendar/events","core_calendar/view_manager","core_calendar/crud","core_calendar/selectors","core/config"],(function($,Templates,Notification,CalendarRepository,CalendarEvents,CalendarViewManager,CalendarCrud,CalendarSelectors,Config){var SELECTORS_DAY="[data-region='day']",SELECTORS_DAY_CONTENT="[data-region='day-content']",SELECTORS_LOADING_ICON=".loading-icon",SELECTORS_VIEW_DAY_LINK="[data-action='view-day-link']",SELECTORS_CALENDAR_MONTH_WRAPPER=".calendarwrapper",handleMoveEvent=function(e,eventId,originElement,destinationElement){var originTimestamp=null,destinationTimestamp=destinationElement.attr("data-day-timestamp");originElement&&(originTimestamp=originElement.attr("data-day-timestamp")),originElement&&originTimestamp==destinationTimestamp||Templates.render("core/loading",{}).then((function(html,js){destinationElement.find(SELECTORS_DAY_CONTENT).addClass("hidden"),Templates.appendNodeContents(destinationElement,html,js),originElement&&(originElement.find(SELECTORS_DAY_CONTENT).addClass("hidden"),Templates.appendNodeContents(originElement,html,js))})).then((function(){return CalendarRepository.updateEventStartDay(eventId,destinationTimestamp)})).then((function(){$("body").trigger(CalendarEvents.eventMoved,[eventId,originElement,destinationElement])})).always((function(){var destinationLoadingElement=destinationElement.find(SELECTORS_LOADING_ICON);if(destinationElement.find(SELECTORS_DAY_CONTENT).removeClass("hidden"),Templates.replaceNode(destinationLoadingElement,"",""),originElement){var originLoadingElement=originElement.find(SELECTORS_LOADING_ICON);originElement.find(SELECTORS_DAY_CONTENT).removeClass("hidden"),Templates.replaceNode(originLoadingElement,"","")}})).catch(Notification.exception)},registerEventListeners=function(root){const viewingFullCalendar=document.getElementById(CalendarSelectors.fullCalendarView);root.on("click",SELECTORS_VIEW_DAY_LINK,(function(e){var dayLink=$(e.target).closest(SELECTORS_VIEW_DAY_LINK),year=dayLink.data("year"),month=dayLink.data("month"),day=dayLink.data("day"),courseId=dayLink.data("courseid"),categoryId=dayLink.data("categoryid");const url="?view=day&time="+dayLink.data("timestamp");viewingFullCalendar?CalendarViewManager.refreshDayContent(root,year,month,day,courseId,categoryId,root,"core_calendar/calendar_day").then((function(){return e.preventDefault(),CalendarViewManager.updateUrl(url)})).catch(Notification.exception):window.location.assign(Config.wwwroot+"/calendar/view.php"+url)})),root.on("change",CalendarSelectors.elements.courseSelector,(function(){var courseId=$(this).val();CalendarViewManager.reloadCurrentMonth(root,courseId,null).then((function(){return root.find(CalendarSelectors.elements.courseSelector).val(courseId)})).catch(Notification.exception)}));var eventFormPromise=CalendarCrud.registerEventFormModal(root),contextId=$(SELECTORS_CALENDAR_MONTH_WRAPPER).data("context-id");!function(root,eventFormModalPromise){var body=$("body");body.on(CalendarEvents.created,(function(){CalendarViewManager.reloadCurrentMonth(root)})),body.on(CalendarEvents.deleted,(function(){CalendarViewManager.reloadCurrentMonth(root)})),body.on(CalendarEvents.updated,(function(){CalendarViewManager.reloadCurrentMonth(root)})),body.on(CalendarEvents.editActionEvent,(function(e,url){window.location.assign(url)})),body.on(CalendarEvents.moveEvent,handleMoveEvent),body.on(CalendarEvents.eventMoved,(function(){CalendarViewManager.reloadCurrentMonth(root)})),CalendarCrud.registerEditListeners(root,eventFormModalPromise)}(root,eventFormPromise),contextId&&root.on("click",SELECTORS_DAY,(function(e){var target=$(e.target);const displayingSmallBlockCalendar="side-pre"===root.parents("aside").data("blockregion");if(!viewingFullCalendar&&displayingSmallBlockCalendar){const url="?view=day&time="+target.closest(SELECTORS_DAY).data("day-timestamp");window.location.assign(Config.wwwroot+"/calendar/view.php"+url)}else{if(!target.closest(SELECTORS_VIEW_DAY_LINK).length){var startTime=$(this).attr("data-new-event-timestamp");eventFormPromise.then((function(modal){var wrapper=target.closest(CalendarSelectors.wrapper);modal.setCourseId(wrapper.data("courseid"));var categoryId=wrapper.data("categoryid");void 0!==categoryId&&modal.setCategoryId(categoryId),modal.setContextId(wrapper.data("contextId")),modal.setStartTime(startTime),modal.show()})).catch(Notification.exception)}}e.preventDefault()}))};return{init:function(root){root=$(root),CalendarViewManager.init(root),registerEventListeners(root)}}})); //# sourceMappingURL=calendar.min.js.map \ No newline at end of file diff --git a/calendar/amd/build/calendar.min.js.map b/calendar/amd/build/calendar.min.js.map index 3a943a59bea..8142be57611 100644 --- a/calendar/amd/build/calendar.min.js.map +++ b/calendar/amd/build/calendar.min.js.map @@ -1 +1 @@ -{"version":3,"file":"calendar.min.js","sources":["../src/calendar.js"],"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 * This module is the highest level module for the calendar. It is\n * responsible for initialising all of the components required for\n * the calendar to run. It also coordinates the interaction between\n * components by listening for and responding to different events\n * triggered within the calendar UI.\n *\n * @module core_calendar/calendar\n * @copyright 2017 Simey Lameze \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n 'jquery',\n 'core/templates',\n 'core/notification',\n 'core_calendar/repository',\n 'core_calendar/events',\n 'core_calendar/view_manager',\n 'core_calendar/crud',\n 'core_calendar/selectors',\n 'core/config',\n],\nfunction(\n $,\n Templates,\n Notification,\n CalendarRepository,\n CalendarEvents,\n CalendarViewManager,\n CalendarCrud,\n CalendarSelectors,\n Config,\n) {\n\n var SELECTORS = {\n ROOT: \"[data-region='calendar']\",\n DAY: \"[data-region='day']\",\n NEW_EVENT_BUTTON: \"[data-action='new-event-button']\",\n DAY_CONTENT: \"[data-region='day-content']\",\n LOADING_ICON: '.loading-icon',\n VIEW_DAY_LINK: \"[data-action='view-day-link']\",\n CALENDAR_MONTH_WRAPPER: \".calendarwrapper\",\n TODAY: '.today',\n DAY_NUMBER_CIRCLE: '.day-number-circle',\n DAY_NUMBER: '.day-number'\n };\n\n /**\n * Handler for the drag and drop move event. Provides a loading indicator\n * while the request is sent to the server to update the event start date.\n *\n * Triggers a eventMoved calendar javascript event if the event was successfully\n * updated.\n *\n * @param {event} e The calendar move event\n * @param {int} eventId The event id being moved\n * @param {object|null} originElement The jQuery element for where the event is moving from\n * @param {object} destinationElement The jQuery element for where the event is moving to\n */\n var handleMoveEvent = function(e, eventId, originElement, destinationElement) {\n var originTimestamp = null;\n var destinationTimestamp = destinationElement.attr('data-day-timestamp');\n\n if (originElement) {\n originTimestamp = originElement.attr('data-day-timestamp');\n }\n\n // If the event has actually changed day.\n if (!originElement || originTimestamp != destinationTimestamp) {\n Templates.render('core/loading', {})\n .then(function(html, js) {\n // First we show some loading icons in each of the days being affected.\n destinationElement.find(SELECTORS.DAY_CONTENT).addClass('hidden');\n Templates.appendNodeContents(destinationElement, html, js);\n\n if (originElement) {\n originElement.find(SELECTORS.DAY_CONTENT).addClass('hidden');\n Templates.appendNodeContents(originElement, html, js);\n }\n return;\n })\n .then(function() {\n // Send a request to the server to make the change.\n return CalendarRepository.updateEventStartDay(eventId, destinationTimestamp);\n })\n .then(function() {\n // If the update was successful then broadcast an event letting the calendar\n // know that an event has been moved.\n $('body').trigger(CalendarEvents.eventMoved, [eventId, originElement, destinationElement]);\n return;\n })\n .always(function() {\n // Always remove the loading icons regardless of whether the update\n // request was successful or not.\n var destinationLoadingElement = destinationElement.find(SELECTORS.LOADING_ICON);\n destinationElement.find(SELECTORS.DAY_CONTENT).removeClass('hidden');\n Templates.replaceNode(destinationLoadingElement, '', '');\n\n if (originElement) {\n var originLoadingElement = originElement.find(SELECTORS.LOADING_ICON);\n originElement.find(SELECTORS.DAY_CONTENT).removeClass('hidden');\n Templates.replaceNode(originLoadingElement, '', '');\n }\n return;\n })\n .fail(Notification.exception);\n }\n };\n\n /**\n * Listen to and handle any calendar events fired by the calendar UI.\n *\n * @method registerCalendarEventListeners\n * @param {object} root The calendar root element\n * @param {object} eventFormModalPromise A promise reolved with the event form modal\n */\n var registerCalendarEventListeners = function(root, eventFormModalPromise) {\n var body = $('body');\n\n body.on(CalendarEvents.created, function() {\n CalendarViewManager.reloadCurrentMonth(root);\n });\n body.on(CalendarEvents.deleted, function() {\n CalendarViewManager.reloadCurrentMonth(root);\n });\n body.on(CalendarEvents.updated, function() {\n CalendarViewManager.reloadCurrentMonth(root);\n });\n body.on(CalendarEvents.editActionEvent, function(e, url) {\n // Action events needs to be edit directly on the course module.\n window.location.assign(url);\n });\n // Handle the event fired by the drag and drop code.\n body.on(CalendarEvents.moveEvent, handleMoveEvent);\n // When an event is successfully moved we should updated the UI.\n body.on(CalendarEvents.eventMoved, function() {\n CalendarViewManager.reloadCurrentMonth(root);\n });\n\n CalendarCrud.registerEditListeners(root, eventFormModalPromise);\n };\n\n /**\n * Register event listeners for the module.\n *\n * @param {object} root The calendar root element\n */\n var registerEventListeners = function(root) {\n const viewingFullCalendar = document.getElementById(CalendarSelectors.fullCalendarView);\n // Listen the click on the day link to render the day view.\n root.on('click', SELECTORS.VIEW_DAY_LINK, function(e) {\n var dayLink = $(e.target).closest(SELECTORS.VIEW_DAY_LINK);\n var year = dayLink.data('year'),\n month = dayLink.data('month'),\n day = dayLink.data('day'),\n courseId = dayLink.data('courseid'),\n categoryId = dayLink.data('categoryid');\n const url = '?view=day&time=' + dayLink.data('timestamp');\n if (viewingFullCalendar) {\n CalendarViewManager.refreshDayContent(root, year, month, day, courseId, categoryId, root,\n 'core_calendar/calendar_day').then(function() {\n e.preventDefault();\n return CalendarViewManager.updateUrl(url);\n }).fail(Notification.exception);\n } else {\n window.location.assign(Config.wwwroot + '/calendar/view.php' + url);\n }\n });\n\n root.on('change', CalendarSelectors.elements.courseSelector, function() {\n var selectElement = $(this);\n var courseId = selectElement.val();\n CalendarViewManager.reloadCurrentMonth(root, courseId, null)\n .then(function() {\n // We need to get the selector again because the content has changed.\n return root.find(CalendarSelectors.elements.courseSelector).val(courseId);\n })\n .fail(Notification.exception);\n });\n\n var eventFormPromise = CalendarCrud.registerEventFormModal(root),\n contextId = $(SELECTORS.CALENDAR_MONTH_WRAPPER).data('context-id');\n registerCalendarEventListeners(root, eventFormPromise);\n\n if (contextId) {\n // Bind click events to calendar days.\n root.on('click', SELECTORS.DAY, function(e) {\n var target = $(e.target);\n const displayingSmallBlockCalendar = root.parents('aside').data('blockregion') === 'side-pre';\n\n if (!viewingFullCalendar && displayingSmallBlockCalendar) {\n const dateContainer = target.closest(SELECTORS.DAY);\n const url = '?view=day&time=' + dateContainer.data('day-timestamp');\n window.location.assign(Config.wwwroot + '/calendar/view.php' + url);\n } else {\n const hasViewDayLink = target.closest(SELECTORS.VIEW_DAY_LINK).length;\n const shouldShowNewEventModal = !hasViewDayLink;\n if (shouldShowNewEventModal) {\n var startTime = $(this).attr('data-new-event-timestamp');\n eventFormPromise.then(function(modal) {\n var wrapper = target.closest(CalendarSelectors.wrapper);\n modal.setCourseId(wrapper.data('courseid'));\n\n var categoryId = wrapper.data('categoryid');\n if (typeof categoryId !== 'undefined') {\n modal.setCategoryId(categoryId);\n }\n\n modal.setContextId(wrapper.data('contextId'));\n modal.setStartTime(startTime);\n modal.show();\n return;\n }).fail(Notification.exception);\n }\n }\n e.preventDefault();\n });\n }\n };\n\n return {\n init: function(root) {\n root = $(root);\n CalendarViewManager.init(root);\n registerEventListeners(root);\n }\n };\n});\n"],"names":["define","$","Templates","Notification","CalendarRepository","CalendarEvents","CalendarViewManager","CalendarCrud","CalendarSelectors","Config","SELECTORS","handleMoveEvent","e","eventId","originElement","destinationElement","originTimestamp","destinationTimestamp","attr","render","then","html","js","find","addClass","appendNodeContents","updateEventStartDay","trigger","eventMoved","always","destinationLoadingElement","removeClass","replaceNode","originLoadingElement","fail","exception","registerEventListeners","root","viewingFullCalendar","document","getElementById","fullCalendarView","on","dayLink","target","closest","year","data","month","day","courseId","categoryId","url","refreshDayContent","preventDefault","updateUrl","window","location","assign","wwwroot","elements","courseSelector","this","val","reloadCurrentMonth","eventFormPromise","registerEventFormModal","contextId","eventFormModalPromise","body","created","deleted","updated","editActionEvent","moveEvent","registerEditListeners","registerCalendarEventListeners","displayingSmallBlockCalendar","parents","length","startTime","modal","wrapper","setCourseId","setCategoryId","setContextId","setStartTime","show","init"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"calendar.min.js","sources":["../src/calendar.js"],"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 * This module is the highest level module for the calendar. It is\n * responsible for initialising all of the components required for\n * the calendar to run. It also coordinates the interaction between\n * components by listening for and responding to different events\n * triggered within the calendar UI.\n *\n * @module core_calendar/calendar\n * @copyright 2017 Simey Lameze \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n 'jquery',\n 'core/templates',\n 'core/notification',\n 'core_calendar/repository',\n 'core_calendar/events',\n 'core_calendar/view_manager',\n 'core_calendar/crud',\n 'core_calendar/selectors',\n 'core/config',\n],\nfunction(\n $,\n Templates,\n Notification,\n CalendarRepository,\n CalendarEvents,\n CalendarViewManager,\n CalendarCrud,\n CalendarSelectors,\n Config,\n) {\n\n var SELECTORS = {\n ROOT: \"[data-region='calendar']\",\n DAY: \"[data-region='day']\",\n NEW_EVENT_BUTTON: \"[data-action='new-event-button']\",\n DAY_CONTENT: \"[data-region='day-content']\",\n LOADING_ICON: '.loading-icon',\n VIEW_DAY_LINK: \"[data-action='view-day-link']\",\n CALENDAR_MONTH_WRAPPER: \".calendarwrapper\",\n TODAY: '.today',\n DAY_NUMBER_CIRCLE: '.day-number-circle',\n DAY_NUMBER: '.day-number'\n };\n\n /**\n * Handler for the drag and drop move event. Provides a loading indicator\n * while the request is sent to the server to update the event start date.\n *\n * Triggers a eventMoved calendar javascript event if the event was successfully\n * updated.\n *\n * @param {event} e The calendar move event\n * @param {int} eventId The event id being moved\n * @param {object|null} originElement The jQuery element for where the event is moving from\n * @param {object} destinationElement The jQuery element for where the event is moving to\n */\n var handleMoveEvent = function(e, eventId, originElement, destinationElement) {\n var originTimestamp = null;\n var destinationTimestamp = destinationElement.attr('data-day-timestamp');\n\n if (originElement) {\n originTimestamp = originElement.attr('data-day-timestamp');\n }\n\n // If the event has actually changed day.\n if (!originElement || originTimestamp != destinationTimestamp) {\n Templates.render('core/loading', {})\n .then(function(html, js) {\n // First we show some loading icons in each of the days being affected.\n destinationElement.find(SELECTORS.DAY_CONTENT).addClass('hidden');\n Templates.appendNodeContents(destinationElement, html, js);\n\n if (originElement) {\n originElement.find(SELECTORS.DAY_CONTENT).addClass('hidden');\n Templates.appendNodeContents(originElement, html, js);\n }\n return;\n })\n .then(function() {\n // Send a request to the server to make the change.\n return CalendarRepository.updateEventStartDay(eventId, destinationTimestamp);\n })\n .then(function() {\n // If the update was successful then broadcast an event letting the calendar\n // know that an event has been moved.\n $('body').trigger(CalendarEvents.eventMoved, [eventId, originElement, destinationElement]);\n return;\n })\n .always(function() {\n // Always remove the loading icons regardless of whether the update\n // request was successful or not.\n var destinationLoadingElement = destinationElement.find(SELECTORS.LOADING_ICON);\n destinationElement.find(SELECTORS.DAY_CONTENT).removeClass('hidden');\n Templates.replaceNode(destinationLoadingElement, '', '');\n\n if (originElement) {\n var originLoadingElement = originElement.find(SELECTORS.LOADING_ICON);\n originElement.find(SELECTORS.DAY_CONTENT).removeClass('hidden');\n Templates.replaceNode(originLoadingElement, '', '');\n }\n return;\n })\n .catch(Notification.exception);\n }\n };\n\n /**\n * Listen to and handle any calendar events fired by the calendar UI.\n *\n * @method registerCalendarEventListeners\n * @param {object} root The calendar root element\n * @param {object} eventFormModalPromise A promise reolved with the event form modal\n */\n var registerCalendarEventListeners = function(root, eventFormModalPromise) {\n var body = $('body');\n\n body.on(CalendarEvents.created, function() {\n CalendarViewManager.reloadCurrentMonth(root);\n });\n body.on(CalendarEvents.deleted, function() {\n CalendarViewManager.reloadCurrentMonth(root);\n });\n body.on(CalendarEvents.updated, function() {\n CalendarViewManager.reloadCurrentMonth(root);\n });\n body.on(CalendarEvents.editActionEvent, function(e, url) {\n // Action events needs to be edit directly on the course module.\n window.location.assign(url);\n });\n // Handle the event fired by the drag and drop code.\n body.on(CalendarEvents.moveEvent, handleMoveEvent);\n // When an event is successfully moved we should updated the UI.\n body.on(CalendarEvents.eventMoved, function() {\n CalendarViewManager.reloadCurrentMonth(root);\n });\n\n CalendarCrud.registerEditListeners(root, eventFormModalPromise);\n };\n\n /**\n * Register event listeners for the module.\n *\n * @param {object} root The calendar root element\n */\n var registerEventListeners = function(root) {\n const viewingFullCalendar = document.getElementById(CalendarSelectors.fullCalendarView);\n // Listen the click on the day link to render the day view.\n root.on('click', SELECTORS.VIEW_DAY_LINK, function(e) {\n var dayLink = $(e.target).closest(SELECTORS.VIEW_DAY_LINK);\n var year = dayLink.data('year'),\n month = dayLink.data('month'),\n day = dayLink.data('day'),\n courseId = dayLink.data('courseid'),\n categoryId = dayLink.data('categoryid');\n const url = '?view=day&time=' + dayLink.data('timestamp');\n if (viewingFullCalendar) {\n CalendarViewManager.refreshDayContent(root, year, month, day, courseId, categoryId, root,\n 'core_calendar/calendar_day').then(function() {\n e.preventDefault();\n return CalendarViewManager.updateUrl(url);\n }).catch(Notification.exception);\n } else {\n window.location.assign(Config.wwwroot + '/calendar/view.php' + url);\n }\n });\n\n root.on('change', CalendarSelectors.elements.courseSelector, function() {\n var selectElement = $(this);\n var courseId = selectElement.val();\n CalendarViewManager.reloadCurrentMonth(root, courseId, null)\n .then(function() {\n // We need to get the selector again because the content has changed.\n return root.find(CalendarSelectors.elements.courseSelector).val(courseId);\n })\n .catch(Notification.exception);\n });\n\n var eventFormPromise = CalendarCrud.registerEventFormModal(root),\n contextId = $(SELECTORS.CALENDAR_MONTH_WRAPPER).data('context-id');\n registerCalendarEventListeners(root, eventFormPromise);\n\n if (contextId) {\n // Bind click events to calendar days.\n root.on('click', SELECTORS.DAY, function(e) {\n var target = $(e.target);\n const displayingSmallBlockCalendar = root.parents('aside').data('blockregion') === 'side-pre';\n\n if (!viewingFullCalendar && displayingSmallBlockCalendar) {\n const dateContainer = target.closest(SELECTORS.DAY);\n const url = '?view=day&time=' + dateContainer.data('day-timestamp');\n window.location.assign(Config.wwwroot + '/calendar/view.php' + url);\n } else {\n const hasViewDayLink = target.closest(SELECTORS.VIEW_DAY_LINK).length;\n const shouldShowNewEventModal = !hasViewDayLink;\n if (shouldShowNewEventModal) {\n var startTime = $(this).attr('data-new-event-timestamp');\n eventFormPromise.then(function(modal) {\n var wrapper = target.closest(CalendarSelectors.wrapper);\n modal.setCourseId(wrapper.data('courseid'));\n\n var categoryId = wrapper.data('categoryid');\n if (typeof categoryId !== 'undefined') {\n modal.setCategoryId(categoryId);\n }\n\n modal.setContextId(wrapper.data('contextId'));\n modal.setStartTime(startTime);\n modal.show();\n return;\n }).catch(Notification.exception);\n }\n }\n e.preventDefault();\n });\n }\n };\n\n return {\n init: function(root) {\n root = $(root);\n CalendarViewManager.init(root);\n registerEventListeners(root);\n }\n };\n});\n"],"names":["define","$","Templates","Notification","CalendarRepository","CalendarEvents","CalendarViewManager","CalendarCrud","CalendarSelectors","Config","SELECTORS","handleMoveEvent","e","eventId","originElement","destinationElement","originTimestamp","destinationTimestamp","attr","render","then","html","js","find","addClass","appendNodeContents","updateEventStartDay","trigger","eventMoved","always","destinationLoadingElement","removeClass","replaceNode","originLoadingElement","catch","exception","registerEventListeners","root","viewingFullCalendar","document","getElementById","fullCalendarView","on","dayLink","target","closest","year","data","month","day","courseId","categoryId","url","refreshDayContent","preventDefault","updateUrl","window","location","assign","wwwroot","elements","courseSelector","this","val","reloadCurrentMonth","eventFormPromise","registerEventFormModal","contextId","eventFormModalPromise","body","created","deleted","updated","editActionEvent","moveEvent","registerEditListeners","registerCalendarEventListeners","displayingSmallBlockCalendar","parents","length","startTime","modal","wrapper","setCourseId","setCategoryId","setContextId","setStartTime","show","init"],"mappings":"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"} \ No newline at end of file diff --git a/calendar/amd/build/crud.min.js b/calendar/amd/build/crud.min.js index 30b5bea95b8..b7564a561d8 100644 --- a/calendar/amd/build/crud.min.js +++ b/calendar/amd/build/crud.min.js @@ -5,6 +5,6 @@ * @copyright 2017 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -define("core_calendar/crud",["jquery","core/str","core/notification","core/modal_factory","core/modal_events","core_calendar/modal_event_form","core_calendar/repository","core_calendar/events","core_calendar/modal_delete","core_calendar/selectors","core/pending"],(function($,Str,Notification,ModalFactory,ModalEvents,ModalEventForm,CalendarRepository,CalendarEvents,ModalDelete,CalendarSelectors,Pending){return{registerRemove:function(root){root.on("click",CalendarSelectors.actions.remove,(function(e){var eventSource=$(this).closest(CalendarSelectors.eventItem);!function(eventId,eventTitle,eventCount){var deletePromise,pendingPromise=new Pending("core_calendar/crud:confirmDeletion"),deleteStrings=[{key:"deleteevent",component:"calendar"}],isRepeatedEvent=(eventCount=parseInt(eventCount,10))>1;isRepeatedEvent?(deleteStrings.push({key:"confirmeventseriesdelete",component:"calendar",param:{name:eventTitle,count:eventCount}}),deletePromise=ModalFactory.create({type:ModalDelete.TYPE})):(deleteStrings.push({key:"confirmeventdelete",component:"calendar",param:eventTitle}),deletePromise=ModalFactory.create({type:ModalFactory.types.SAVE_CANCEL}));var stringsPromise=Str.get_strings(deleteStrings);$.when(stringsPromise,deletePromise).then((function(strings,deleteModal){return deleteModal.setRemoveOnClose(!0),deleteModal.setTitle(strings[0]),deleteModal.setBody(strings[1]),isRepeatedEvent||deleteModal.setSaveButtonText(strings[0]),deleteModal.show(),deleteModal.getRoot().on(ModalEvents.save,(function(){var pendingPromise=new Pending("calendar/crud:initModal:deletedevent");CalendarRepository.deleteEvent(eventId,!1).then((function(){$("body").trigger(CalendarEvents.deleted,[eventId,!1])})).then(pendingPromise.resolve).catch(Notification.exception)})),deleteModal.getRoot().on(CalendarEvents.deleteAll,(function(){var pendingPromise=new Pending("calendar/crud:initModal:deletedallevent");CalendarRepository.deleteEvent(eventId,!0).then((function(){$("body").trigger(CalendarEvents.deleted,[eventId,!0])})).then(pendingPromise.resolve).catch(Notification.exception)})),deleteModal})).then((function(modal){return pendingPromise.resolve(),modal})).catch(Notification.exception)}(eventSource.data("eventId"),eventSource.data("eventTitle"),eventSource.data("eventCount")),e.preventDefault()}))},registerEditListeners:function(root,eventFormModalPromise){var pendingPromise=new Pending("core_calendar/crud:registerEditListeners");return eventFormModalPromise.then((function(modal){return $("body").on(CalendarEvents.editEvent,(function(e,eventId){var target=root.find("[data-event-id=".concat(eventId,"]")),calendarWrapper=root.find(CalendarSelectors.wrapper);modal.setEventId(eventId),modal.setContextId(calendarWrapper.data("contextId")),modal.setReturnElement(target),modal.show(),e.stopImmediatePropagation()})),modal})).then((function(modal){return pendingPromise.resolve(),modal})).catch(Notification.exception)},registerEventFormModal:function(root){var eventFormPromise=ModalFactory.create({type:ModalEventForm.TYPE,large:!0});return root.on("click",CalendarSelectors.actions.create,(function(e){eventFormPromise.then((function(modal){var wrapper=root.find(CalendarSelectors.wrapper),categoryId=wrapper.data("categoryid");void 0!==categoryId&&modal.setCategoryId(categoryId);var today=root.find(CalendarSelectors.today),firstDay=root.find(CalendarSelectors.day);!today.length&&firstDay.length&&modal.setStartTime(firstDay.data("newEventTimestamp")),modal.setContextId(wrapper.data("contextId")),modal.setCourseId(wrapper.data("courseid")),modal.show()})).fail(Notification.exception),e.preventDefault()})),root.on("click",CalendarSelectors.actions.edit,(function(e){e.preventDefault();var target=$(e.currentTarget),calendarWrapper=target.closest(CalendarSelectors.wrapper),eventWrapper=target.closest(CalendarSelectors.eventItem);eventFormPromise.then((function(modal){modal.setEventId(eventWrapper.data("eventId")),modal.setContextId(calendarWrapper.data("contextId")),modal.setCourseId(eventWrapper.data("courseId")),modal.show(),e.stopImmediatePropagation()})).fail(Notification.exception)})),eventFormPromise}}})); +define("core_calendar/crud",["jquery","core/str","core/notification","core/modal_events","core_calendar/modal_event_form","core_calendar/repository","core_calendar/events","core_calendar/modal_delete","core_calendar/selectors","core/pending","core/modal_save_cancel"],(function($,Str,Notification,ModalEvents,ModalEventForm,CalendarRepository,CalendarEvents,CalendarModalDelete,CalendarSelectors,Pending,ModalSaveCancel){return{registerRemove:function(root){root.on("click",CalendarSelectors.actions.remove,(function(e){var eventSource=$(this).closest(CalendarSelectors.eventItem);!function(eventId,eventTitle,eventCount){var deletePromise,pendingPromise=new Pending("core_calendar/crud:confirmDeletion"),deleteStrings=[{key:"deleteevent",component:"calendar"}],isRepeatedEvent=(eventCount=parseInt(eventCount,10))>1;isRepeatedEvent?(deleteStrings.push({key:"confirmeventseriesdelete",component:"calendar",param:{name:eventTitle,count:eventCount}}),deletePromise=CalendarModalDelete.create()):(deleteStrings.push({key:"confirmeventdelete",component:"calendar",param:eventTitle}),deletePromise=ModalSaveCancel.create());var stringsPromise=Str.get_strings(deleteStrings);$.when(stringsPromise,deletePromise).then((function(strings,deleteModal){return deleteModal.setRemoveOnClose(!0),deleteModal.setTitle(strings[0]),deleteModal.setBody(strings[1]),isRepeatedEvent||deleteModal.setSaveButtonText(strings[0]),deleteModal.show(),deleteModal.getRoot().on(ModalEvents.save,(function(){var pendingPromise=new Pending("calendar/crud:initModal:deletedevent");CalendarRepository.deleteEvent(eventId,!1).then((function(){$("body").trigger(CalendarEvents.deleted,[eventId,!1])})).then(pendingPromise.resolve).catch(Notification.exception)})),deleteModal.getRoot().on(CalendarEvents.deleteAll,(function(){var pendingPromise=new Pending("calendar/crud:initModal:deletedallevent");CalendarRepository.deleteEvent(eventId,!0).then((function(){$("body").trigger(CalendarEvents.deleted,[eventId,!0])})).then(pendingPromise.resolve).catch(Notification.exception)})),deleteModal})).then((function(modal){return pendingPromise.resolve(),modal})).catch(Notification.exception)}(eventSource.data("eventId"),eventSource.data("eventTitle"),eventSource.data("eventCount")),e.preventDefault()}))},registerEditListeners:function(root,eventFormModalPromise){var pendingPromise=new Pending("core_calendar/crud:registerEditListeners");return eventFormModalPromise.then((function(modal){return $("body").on(CalendarEvents.editEvent,(function(e,eventId){var target=root.find("[data-event-id=".concat(eventId,"]")),calendarWrapper=root.find(CalendarSelectors.wrapper);modal.setEventId(eventId),modal.setContextId(calendarWrapper.data("contextId")),modal.setReturnElement(target),modal.show(),e.stopImmediatePropagation()})),modal})).then((function(modal){return pendingPromise.resolve(),modal})).catch(Notification.exception)},registerEventFormModal:function(root){var eventFormPromise=ModalEventForm.create();return root.on("click",CalendarSelectors.actions.create,(function(e){eventFormPromise.then((function(modal){var wrapper=root.find(CalendarSelectors.wrapper),categoryId=wrapper.data("categoryid");void 0!==categoryId&&modal.setCategoryId(categoryId);var today=root.find(CalendarSelectors.today),firstDay=root.find(CalendarSelectors.day);!today.length&&firstDay.length&&modal.setStartTime(firstDay.data("newEventTimestamp")),modal.setContextId(wrapper.data("contextId")),modal.setCourseId(wrapper.data("courseid")),modal.show()})).fail(Notification.exception),e.preventDefault()})),root.on("click",CalendarSelectors.actions.edit,(function(e){e.preventDefault();var target=$(e.currentTarget),calendarWrapper=target.closest(CalendarSelectors.wrapper),eventWrapper=target.closest(CalendarSelectors.eventItem);eventFormPromise.then((function(modal){modal.setEventId(eventWrapper.data("eventId")),modal.setContextId(calendarWrapper.data("contextId")),modal.setCourseId(eventWrapper.data("courseId")),modal.show(),e.stopImmediatePropagation()})).fail(Notification.exception)})),eventFormPromise}}})); //# sourceMappingURL=crud.min.js.map \ No newline at end of file diff --git a/calendar/amd/build/crud.min.js.map b/calendar/amd/build/crud.min.js.map index de481ef9645..1888d3d9e66 100644 --- a/calendar/amd/build/crud.min.js.map +++ b/calendar/amd/build/crud.min.js.map @@ -1 +1 @@ -{"version":3,"file":"crud.min.js","sources":["../src/crud.js"],"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 * A module to handle CRUD operations within the UI.\n *\n * @module core_calendar/crud\n * @copyright 2017 Andrew Nicols \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n 'jquery',\n 'core/str',\n 'core/notification',\n 'core/modal_factory',\n 'core/modal_events',\n 'core_calendar/modal_event_form',\n 'core_calendar/repository',\n 'core_calendar/events',\n 'core_calendar/modal_delete',\n 'core_calendar/selectors',\n 'core/pending',\n],\nfunction(\n $,\n Str,\n Notification,\n ModalFactory,\n ModalEvents,\n ModalEventForm,\n CalendarRepository,\n CalendarEvents,\n ModalDelete,\n CalendarSelectors,\n Pending\n) {\n\n /**\n * Prepares the action for the summary modal's delete action.\n *\n * @param {Number} eventId The ID of the event.\n * @param {string} eventTitle The event title.\n * @param {Number} eventCount The number of events in the series.\n * @return {Promise}\n */\n function confirmDeletion(eventId, eventTitle, eventCount) {\n var pendingPromise = new Pending('core_calendar/crud:confirmDeletion');\n var deleteStrings = [\n {\n key: 'deleteevent',\n component: 'calendar'\n },\n ];\n\n eventCount = parseInt(eventCount, 10);\n var deletePromise;\n var isRepeatedEvent = eventCount > 1;\n if (isRepeatedEvent) {\n deleteStrings.push({\n key: 'confirmeventseriesdelete',\n component: 'calendar',\n param: {\n name: eventTitle,\n count: eventCount,\n },\n });\n\n deletePromise = ModalFactory.create(\n {\n type: ModalDelete.TYPE\n }\n );\n } else {\n deleteStrings.push({\n key: 'confirmeventdelete',\n component: 'calendar',\n param: eventTitle\n });\n\n\n deletePromise = ModalFactory.create({\n type: ModalFactory.types.SAVE_CANCEL,\n });\n }\n\n var stringsPromise = Str.get_strings(deleteStrings);\n\n var finalPromise = $.when(stringsPromise, deletePromise)\n .then(function(strings, deleteModal) {\n deleteModal.setRemoveOnClose(true);\n deleteModal.setTitle(strings[0]);\n deleteModal.setBody(strings[1]);\n if (!isRepeatedEvent) {\n deleteModal.setSaveButtonText(strings[0]);\n }\n\n deleteModal.show();\n\n deleteModal.getRoot().on(ModalEvents.save, function() {\n var pendingPromise = new Pending('calendar/crud:initModal:deletedevent');\n CalendarRepository.deleteEvent(eventId, false)\n .then(function() {\n $('body').trigger(CalendarEvents.deleted, [eventId, false]);\n return;\n })\n .then(pendingPromise.resolve)\n .catch(Notification.exception);\n });\n\n deleteModal.getRoot().on(CalendarEvents.deleteAll, function() {\n var pendingPromise = new Pending('calendar/crud:initModal:deletedallevent');\n CalendarRepository.deleteEvent(eventId, true)\n .then(function() {\n $('body').trigger(CalendarEvents.deleted, [eventId, true]);\n return;\n })\n .then(pendingPromise.resolve)\n .catch(Notification.exception);\n });\n\n return deleteModal;\n })\n .then(function(modal) {\n pendingPromise.resolve();\n\n return modal;\n })\n .catch(Notification.exception);\n\n return finalPromise;\n }\n\n /**\n * Create the event form modal for creating new events and\n * editing existing events.\n *\n * @method registerEventFormModal\n * @param {object} root The calendar root element\n * @return {object} The create modal promise\n */\n var registerEventFormModal = function(root) {\n var eventFormPromise = ModalFactory.create({\n type: ModalEventForm.TYPE,\n large: true\n });\n\n // Bind click event on the new event button.\n root.on('click', CalendarSelectors.actions.create, function(e) {\n eventFormPromise.then(function(modal) {\n var wrapper = root.find(CalendarSelectors.wrapper);\n\n var categoryId = wrapper.data('categoryid');\n if (typeof categoryId !== 'undefined') {\n modal.setCategoryId(categoryId);\n }\n\n // Attempt to find the cell for today.\n // If it can't be found, then use the start time of the first day on the calendar.\n var today = root.find(CalendarSelectors.today);\n var firstDay = root.find(CalendarSelectors.day);\n if (!today.length && firstDay.length) {\n modal.setStartTime(firstDay.data('newEventTimestamp'));\n }\n\n modal.setContextId(wrapper.data('contextId'));\n modal.setCourseId(wrapper.data('courseid'));\n modal.show();\n return;\n })\n .fail(Notification.exception);\n\n e.preventDefault();\n });\n\n root.on('click', CalendarSelectors.actions.edit, function(e) {\n e.preventDefault();\n var target = $(e.currentTarget),\n calendarWrapper = target.closest(CalendarSelectors.wrapper),\n eventWrapper = target.closest(CalendarSelectors.eventItem);\n\n eventFormPromise.then(function(modal) {\n // When something within the calendar tells us the user wants\n // to edit an event then show the event form modal.\n modal.setEventId(eventWrapper.data('eventId'));\n\n modal.setContextId(calendarWrapper.data('contextId'));\n modal.setCourseId(eventWrapper.data('courseId'));\n modal.show();\n\n e.stopImmediatePropagation();\n return;\n }).fail(Notification.exception);\n });\n\n\n return eventFormPromise;\n };\n /**\n * Register the listeners required to remove the event.\n *\n * @param {jQuery} root\n */\n function registerRemove(root) {\n root.on('click', CalendarSelectors.actions.remove, function(e) {\n // Fetch the event title, count, and pass them into the new dialogue.\n var eventSource = $(this).closest(CalendarSelectors.eventItem);\n var eventId = eventSource.data('eventId'),\n eventTitle = eventSource.data('eventTitle'),\n eventCount = eventSource.data('eventCount');\n confirmDeletion(eventId, eventTitle, eventCount);\n\n e.preventDefault();\n });\n }\n\n /**\n * Register the listeners required to edit the event.\n *\n * @param {jQuery} root\n * @param {Promise} eventFormModalPromise\n * @returns {Promise}\n */\n function registerEditListeners(root, eventFormModalPromise) {\n var pendingPromise = new Pending('core_calendar/crud:registerEditListeners');\n\n return eventFormModalPromise\n .then(function(modal) {\n // When something within the calendar tells us the user wants\n // to edit an event then show the event form modal.\n $('body').on(CalendarEvents.editEvent, function(e, eventId) {\n var target = root.find(`[data-event-id=${eventId}]`),\n calendarWrapper = root.find(CalendarSelectors.wrapper);\n\n modal.setEventId(eventId);\n modal.setContextId(calendarWrapper.data('contextId'));\n modal.setReturnElement(target);\n modal.show();\n\n e.stopImmediatePropagation();\n });\n return modal;\n })\n .then(function(modal) {\n pendingPromise.resolve();\n\n return modal;\n })\n .catch(Notification.exception);\n }\n\n return {\n registerRemove: registerRemove,\n registerEditListeners: registerEditListeners,\n registerEventFormModal: registerEventFormModal\n };\n});\n"],"names":["define","$","Str","Notification","ModalFactory","ModalEvents","ModalEventForm","CalendarRepository","CalendarEvents","ModalDelete","CalendarSelectors","Pending","registerRemove","root","on","actions","remove","e","eventSource","this","closest","eventItem","eventId","eventTitle","eventCount","deletePromise","pendingPromise","deleteStrings","key","component","isRepeatedEvent","parseInt","push","param","name","count","create","type","TYPE","types","SAVE_CANCEL","stringsPromise","get_strings","when","then","strings","deleteModal","setRemoveOnClose","setTitle","setBody","setSaveButtonText","show","getRoot","save","deleteEvent","trigger","deleted","resolve","catch","exception","deleteAll","modal","confirmDeletion","data","preventDefault","registerEditListeners","eventFormModalPromise","editEvent","target","find","calendarWrapper","wrapper","setEventId","setContextId","setReturnElement","stopImmediatePropagation","registerEventFormModal","eventFormPromise","large","categoryId","setCategoryId","today","firstDay","day","length","setStartTime","setCourseId","fail","edit","currentTarget","eventWrapper"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"crud.min.js","sources":["../src/crud.js"],"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 * A module to handle CRUD operations within the UI.\n *\n * @module core_calendar/crud\n * @copyright 2017 Andrew Nicols \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n 'jquery',\n 'core/str',\n 'core/notification',\n 'core/modal_events',\n 'core_calendar/modal_event_form',\n 'core_calendar/repository',\n 'core_calendar/events',\n 'core_calendar/modal_delete',\n 'core_calendar/selectors',\n 'core/pending',\n 'core/modal_save_cancel',\n],\nfunction(\n $,\n Str,\n Notification,\n ModalEvents,\n ModalEventForm,\n CalendarRepository,\n CalendarEvents,\n CalendarModalDelete,\n CalendarSelectors,\n Pending,\n ModalSaveCancel,\n) {\n\n /**\n * Prepares the action for the summary modal's delete action.\n *\n * @param {Number} eventId The ID of the event.\n * @param {string} eventTitle The event title.\n * @param {Number} eventCount The number of events in the series.\n * @return {Promise}\n */\n function confirmDeletion(eventId, eventTitle, eventCount) {\n var pendingPromise = new Pending('core_calendar/crud:confirmDeletion');\n var deleteStrings = [\n {\n key: 'deleteevent',\n component: 'calendar'\n },\n ];\n\n eventCount = parseInt(eventCount, 10);\n var deletePromise;\n var isRepeatedEvent = eventCount > 1;\n if (isRepeatedEvent) {\n deleteStrings.push({\n key: 'confirmeventseriesdelete',\n component: 'calendar',\n param: {\n name: eventTitle,\n count: eventCount,\n },\n });\n\n deletePromise = CalendarModalDelete.create();\n } else {\n deleteStrings.push({\n key: 'confirmeventdelete',\n component: 'calendar',\n param: eventTitle\n });\n\n\n deletePromise = ModalSaveCancel.create();\n }\n\n var stringsPromise = Str.get_strings(deleteStrings);\n\n var finalPromise = $.when(stringsPromise, deletePromise)\n .then(function(strings, deleteModal) {\n deleteModal.setRemoveOnClose(true);\n deleteModal.setTitle(strings[0]);\n deleteModal.setBody(strings[1]);\n if (!isRepeatedEvent) {\n deleteModal.setSaveButtonText(strings[0]);\n }\n\n deleteModal.show();\n\n deleteModal.getRoot().on(ModalEvents.save, function() {\n var pendingPromise = new Pending('calendar/crud:initModal:deletedevent');\n CalendarRepository.deleteEvent(eventId, false)\n .then(function() {\n $('body').trigger(CalendarEvents.deleted, [eventId, false]);\n return;\n })\n .then(pendingPromise.resolve)\n .catch(Notification.exception);\n });\n\n deleteModal.getRoot().on(CalendarEvents.deleteAll, function() {\n var pendingPromise = new Pending('calendar/crud:initModal:deletedallevent');\n CalendarRepository.deleteEvent(eventId, true)\n .then(function() {\n $('body').trigger(CalendarEvents.deleted, [eventId, true]);\n return;\n })\n .then(pendingPromise.resolve)\n .catch(Notification.exception);\n });\n\n return deleteModal;\n })\n .then(function(modal) {\n pendingPromise.resolve();\n\n return modal;\n })\n .catch(Notification.exception);\n\n return finalPromise;\n }\n\n /**\n * Create the event form modal for creating new events and\n * editing existing events.\n *\n * @method registerEventFormModal\n * @param {object} root The calendar root element\n * @return {object} The create modal promise\n */\n var registerEventFormModal = function(root) {\n var eventFormPromise = ModalEventForm.create();\n\n // Bind click event on the new event button.\n root.on('click', CalendarSelectors.actions.create, function(e) {\n eventFormPromise.then(function(modal) {\n var wrapper = root.find(CalendarSelectors.wrapper);\n\n var categoryId = wrapper.data('categoryid');\n if (typeof categoryId !== 'undefined') {\n modal.setCategoryId(categoryId);\n }\n\n // Attempt to find the cell for today.\n // If it can't be found, then use the start time of the first day on the calendar.\n var today = root.find(CalendarSelectors.today);\n var firstDay = root.find(CalendarSelectors.day);\n if (!today.length && firstDay.length) {\n modal.setStartTime(firstDay.data('newEventTimestamp'));\n }\n\n modal.setContextId(wrapper.data('contextId'));\n modal.setCourseId(wrapper.data('courseid'));\n modal.show();\n return;\n })\n .fail(Notification.exception);\n\n e.preventDefault();\n });\n\n root.on('click', CalendarSelectors.actions.edit, function(e) {\n e.preventDefault();\n var target = $(e.currentTarget),\n calendarWrapper = target.closest(CalendarSelectors.wrapper),\n eventWrapper = target.closest(CalendarSelectors.eventItem);\n\n eventFormPromise.then(function(modal) {\n // When something within the calendar tells us the user wants\n // to edit an event then show the event form modal.\n modal.setEventId(eventWrapper.data('eventId'));\n\n modal.setContextId(calendarWrapper.data('contextId'));\n modal.setCourseId(eventWrapper.data('courseId'));\n modal.show();\n\n e.stopImmediatePropagation();\n return;\n }).fail(Notification.exception);\n });\n\n\n return eventFormPromise;\n };\n /**\n * Register the listeners required to remove the event.\n *\n * @param {jQuery} root\n */\n function registerRemove(root) {\n root.on('click', CalendarSelectors.actions.remove, function(e) {\n // Fetch the event title, count, and pass them into the new dialogue.\n var eventSource = $(this).closest(CalendarSelectors.eventItem);\n var eventId = eventSource.data('eventId'),\n eventTitle = eventSource.data('eventTitle'),\n eventCount = eventSource.data('eventCount');\n confirmDeletion(eventId, eventTitle, eventCount);\n\n e.preventDefault();\n });\n }\n\n /**\n * Register the listeners required to edit the event.\n *\n * @param {jQuery} root\n * @param {Promise} eventFormModalPromise\n * @returns {Promise}\n */\n function registerEditListeners(root, eventFormModalPromise) {\n var pendingPromise = new Pending('core_calendar/crud:registerEditListeners');\n\n return eventFormModalPromise\n .then(function(modal) {\n // When something within the calendar tells us the user wants\n // to edit an event then show the event form modal.\n $('body').on(CalendarEvents.editEvent, function(e, eventId) {\n var target = root.find(`[data-event-id=${eventId}]`),\n calendarWrapper = root.find(CalendarSelectors.wrapper);\n\n modal.setEventId(eventId);\n modal.setContextId(calendarWrapper.data('contextId'));\n modal.setReturnElement(target);\n modal.show();\n\n e.stopImmediatePropagation();\n });\n return modal;\n })\n .then(function(modal) {\n pendingPromise.resolve();\n\n return modal;\n })\n .catch(Notification.exception);\n }\n\n return {\n registerRemove: registerRemove,\n registerEditListeners: registerEditListeners,\n registerEventFormModal: registerEventFormModal\n };\n});\n"],"names":["define","$","Str","Notification","ModalEvents","ModalEventForm","CalendarRepository","CalendarEvents","CalendarModalDelete","CalendarSelectors","Pending","ModalSaveCancel","registerRemove","root","on","actions","remove","e","eventSource","this","closest","eventItem","eventId","eventTitle","eventCount","deletePromise","pendingPromise","deleteStrings","key","component","isRepeatedEvent","parseInt","push","param","name","count","create","stringsPromise","get_strings","when","then","strings","deleteModal","setRemoveOnClose","setTitle","setBody","setSaveButtonText","show","getRoot","save","deleteEvent","trigger","deleted","resolve","catch","exception","deleteAll","modal","confirmDeletion","data","preventDefault","registerEditListeners","eventFormModalPromise","editEvent","target","find","calendarWrapper","wrapper","setEventId","setContextId","setReturnElement","stopImmediatePropagation","registerEventFormModal","eventFormPromise","categoryId","setCategoryId","today","firstDay","day","length","setStartTime","setCourseId","fail","edit","currentTarget","eventWrapper"],"mappings":"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"} \ No newline at end of file diff --git a/calendar/amd/build/manage_subscriptions.min.js b/calendar/amd/build/manage_subscriptions.min.js index 27c40627c0e..277f658f27f 100644 --- a/calendar/amd/build/manage_subscriptions.min.js +++ b/calendar/amd/build/manage_subscriptions.min.js @@ -1,4 +1,4 @@ -define("core_calendar/manage_subscriptions",["exports","core_calendar/selectors","core_calendar/repository","core/modal_factory","core/modal_events","core/notification","core/prefetch","core/str","core/local/inplace_editable/events"],(function(_exports,CalendarSelectors,CalendarRepository,Modal,ModalEvents,_notification,_prefetch,_str,_events){var obj;function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireWildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}return newObj.default=obj,cache&&cache.set(obj,newObj),newObj} +define("core_calendar/manage_subscriptions",["exports","core_calendar/selectors","core_calendar/repository","core/modal_save_cancel","core/modal_events","core/notification","core/prefetch","core/str","core/local/inplace_editable/events"],(function(_exports,CalendarSelectors,CalendarRepository,_modal_save_cancel,ModalEvents,_notification,_prefetch,_str,_events){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireWildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}return newObj.default=obj,cache&&cache.set(obj,newObj),newObj} /** * A module to handle Delete/Update operations of the manage subscription page. * @@ -6,6 +6,6 @@ define("core_calendar/manage_subscriptions",["exports","core_calendar/selectors" * @copyright 2021 Huong Nguyen * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @since 4.0 - */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,CalendarSelectors=_interopRequireWildcard(CalendarSelectors),CalendarRepository=_interopRequireWildcard(CalendarRepository),Modal=_interopRequireWildcard(Modal),ModalEvents=_interopRequireWildcard(ModalEvents),_prefetch=(obj=_prefetch)&&obj.__esModule?obj:{default:obj};const getSubscriptionName=element=>element.closest("tr").dataset.subname,registerEventListeners=()=>{document.addEventListener("click",(e=>{const deleteAction=e.target.closest(CalendarSelectors.actions.deleteSubscription);if(deleteAction){e.preventDefault();((element,messageCode)=>{const subscriptionName=getSubscriptionName(element);return Modal.create({type:Modal.types.SAVE_CANCEL,title:(0,_str.getString)("confirmation","admin"),body:(0,_str.getString)(messageCode,"calendar",subscriptionName),buttons:{save:(0,_str.getString)("yes")}}).then((modal=>(modal.getRoot().on(ModalEvents.hidden,(()=>{element.focus()})),modal.show(),modal)))})(deleteAction,"confirmsubscriptiondelete").then((modal=>(modal.getRoot().on(ModalEvents.save,(()=>{const subscriptionId=parseInt(deleteAction.closest("tr").dataset.subid);CalendarRepository.deleteSubscription(subscriptionId).then((data=>{const response=(async(element,data)=>{const subscriptionName=getSubscriptionName(element),message=data.status?await(0,_str.getString)("subscriptionremoved","calendar",subscriptionName):data.warnings[0].message,type=data.status?"info":"error";return(0,_notification.addNotification)({message:message,type:type})})(deleteAction,data);return response.then((()=>{const subscriptionRow=(subscriptionId=>document.querySelector('tr[data-subid="'.concat(subscriptionId,'"]')))(subscriptionId);return subscriptionRow.remove()}))})).catch(_notification.exception)})),modal))).catch(_notification.exception)}})),document.addEventListener(_events.eventTypes.elementUpdated,(e=>{"core_calendar"==e.target.getAttribute("data-component")&&(0,_notification.fetchNotifications)()}))};_exports.init=()=>{_prefetch.default.prefetchStrings("moodle",["yes"]),_prefetch.default.prefetchStrings("core_admin",["confirmation"]),_prefetch.default.prefetchStrings("core_calendar",["confirmsubscriptiondelete","subscriptionremoved"]),registerEventListeners()}})); + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,CalendarSelectors=_interopRequireWildcard(CalendarSelectors),CalendarRepository=_interopRequireWildcard(CalendarRepository),_modal_save_cancel=_interopRequireDefault(_modal_save_cancel),ModalEvents=_interopRequireWildcard(ModalEvents),_prefetch=_interopRequireDefault(_prefetch);const getSubscriptionName=element=>element.closest("tr").dataset.subname,registerEventListeners=()=>{document.addEventListener("click",(e=>{const deleteAction=e.target.closest(CalendarSelectors.actions.deleteSubscription);if(deleteAction){e.preventDefault();((element,messageCode)=>{const subscriptionName=getSubscriptionName(element);return _modal_save_cancel.default.create({title:(0,_str.getString)("confirmation","admin"),body:(0,_str.getString)(messageCode,"calendar",subscriptionName),buttons:{save:(0,_str.getString)("yes")}}).then((modal=>(modal.getRoot().on(ModalEvents.hidden,(()=>{element.focus()})),modal.show(),modal)))})(deleteAction,"confirmsubscriptiondelete").then((modal=>(modal.getRoot().on(ModalEvents.save,(()=>{const subscriptionId=parseInt(deleteAction.closest("tr").dataset.subid);CalendarRepository.deleteSubscription(subscriptionId).then((data=>{const response=(async(element,data)=>{const subscriptionName=getSubscriptionName(element),message=data.status?await(0,_str.getString)("subscriptionremoved","calendar",subscriptionName):data.warnings[0].message,type=data.status?"info":"error";return(0,_notification.addNotification)({message:message,type:type})})(deleteAction,data);return response.then((()=>{const subscriptionRow=(subscriptionId=>document.querySelector('tr[data-subid="'.concat(subscriptionId,'"]')))(subscriptionId);return subscriptionRow.remove()}))})).catch(_notification.exception)})),modal))).catch(_notification.exception)}})),document.addEventListener(_events.eventTypes.elementUpdated,(e=>{"core_calendar"==e.target.getAttribute("data-component")&&(0,_notification.fetchNotifications)()}))};_exports.init=()=>{_prefetch.default.prefetchStrings("moodle",["yes"]),_prefetch.default.prefetchStrings("core_admin",["confirmation"]),_prefetch.default.prefetchStrings("core_calendar",["confirmsubscriptiondelete","subscriptionremoved"]),registerEventListeners()}})); //# sourceMappingURL=manage_subscriptions.min.js.map \ No newline at end of file diff --git a/calendar/amd/build/manage_subscriptions.min.js.map b/calendar/amd/build/manage_subscriptions.min.js.map index 21c9c397fc0..19b3f60a970 100644 --- a/calendar/amd/build/manage_subscriptions.min.js.map +++ b/calendar/amd/build/manage_subscriptions.min.js.map @@ -1 +1 @@ -{"version":3,"file":"manage_subscriptions.min.js","sources":["../src/manage_subscriptions.js"],"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 * A module to handle Delete/Update operations of the manage subscription page.\n *\n * @module core_calendar/manage_subscriptions\n * @copyright 2021 Huong Nguyen \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 4.0\n */\n\nimport * as CalendarSelectors from 'core_calendar/selectors';\nimport * as CalendarRepository from 'core_calendar/repository';\nimport * as Modal from 'core/modal_factory';\nimport * as ModalEvents from 'core/modal_events';\nimport {exception as displayException, addNotification, fetchNotifications} from 'core/notification';\nimport Prefetch from 'core/prefetch';\nimport {getString} from 'core/str';\nimport {eventTypes} from 'core/local/inplace_editable/events';\n\n/**\n * Get subscription id for given element.\n *\n * @param {HTMLElement} element update/delete link\n * @return {Number}\n */\nconst getSubscriptionId = element => {\n return parseInt(element.closest('tr').dataset.subid);\n};\n\n/**\n * Get subscription name for given element.\n *\n * @param {HTMLElement} element update/delete link\n * @return {String}\n */\nconst getSubscriptionName = element => {\n return element.closest('tr').dataset.subname;\n};\n\n/**\n * Get subscription table row for subscription id.\n *\n * @param {string} subscriptionId Subscription id\n * @return {Element}\n */\nconst getSubscriptionRow = subscriptionId => {\n return document.querySelector(`tr[data-subid=\"${subscriptionId}\"]`);\n};\n\n/**\n * Create modal.\n *\n * @param {HTMLElement} element\n * @param {string} messageCode Message code.\n * @return {promise} Promise for modal\n */\nconst createModal = (element, messageCode) => {\n const subscriptionName = getSubscriptionName(element);\n return Modal.create({\n type: Modal.types.SAVE_CANCEL,\n title: getString('confirmation', 'admin'),\n body: getString(messageCode, 'calendar', subscriptionName),\n buttons: {\n save: getString('yes')\n },\n }).then(modal => {\n modal.getRoot().on(ModalEvents.hidden, () => {\n element.focus();\n });\n modal.show();\n return modal;\n });\n};\n\n/**\n * Response handler for delete action.\n *\n * @param {HTMLElement} element\n * @param {Object} data\n * @return {Promise}\n */\nconst responseHandlerForDelete = async(element, data) => {\n const subscriptionName = getSubscriptionName(element);\n const message = data.status ? await getString('subscriptionremoved', 'calendar', subscriptionName) : data.warnings[0].message;\n const type = data.status ? 'info' : 'error';\n return addNotification({message, type});\n};\n\n/**\n * Register events for update/delete links.\n */\nconst registerEventListeners = () => {\n document.addEventListener('click', e => {\n const deleteAction = e.target.closest(CalendarSelectors.actions.deleteSubscription);\n if (deleteAction) {\n e.preventDefault();\n const modalPromise = createModal(deleteAction, 'confirmsubscriptiondelete');\n modalPromise.then(modal => {\n modal.getRoot().on(ModalEvents.save, () => {\n const subscriptionId = getSubscriptionId(deleteAction);\n CalendarRepository.deleteSubscription(subscriptionId).then(data => {\n const response = responseHandlerForDelete(deleteAction, data);\n return response.then(() => {\n const subscriptionRow = getSubscriptionRow(subscriptionId);\n return subscriptionRow.remove();\n });\n }).catch(displayException);\n });\n\n return modal;\n }).catch(displayException);\n }\n });\n\n document.addEventListener(eventTypes.elementUpdated, e => {\n const inplaceEditable = e.target;\n if (inplaceEditable.getAttribute('data-component') == 'core_calendar') {\n fetchNotifications();\n }\n });\n};\n\n/**\n * Initialises.\n */\nexport const init = () => {\n Prefetch.prefetchStrings('moodle', ['yes']);\n Prefetch.prefetchStrings('core_admin', ['confirmation']);\n Prefetch.prefetchStrings('core_calendar', ['confirmsubscriptiondelete', 'subscriptionremoved']);\n registerEventListeners();\n};\n"],"names":["getSubscriptionName","element","closest","dataset","subname","registerEventListeners","document","addEventListener","e","deleteAction","target","CalendarSelectors","actions","deleteSubscription","preventDefault","messageCode","subscriptionName","Modal","create","type","types","SAVE_CANCEL","title","body","buttons","save","then","modal","getRoot","on","ModalEvents","hidden","focus","show","createModal","subscriptionId","parseInt","subid","CalendarRepository","data","response","async","message","status","warnings","responseHandlerForDelete","subscriptionRow","querySelector","getSubscriptionRow","remove","catch","displayException","eventTypes","elementUpdated","getAttribute","prefetchStrings"],"mappings":";;;;;;;;sWAiDMA,oBAAsBC,SACjBA,QAAQC,QAAQ,MAAMC,QAAQC,QAuDnCC,uBAAyB,KAC3BC,SAASC,iBAAiB,SAASC,UACzBC,aAAeD,EAAEE,OAAOR,QAAQS,kBAAkBC,QAAQC,uBAC5DJ,aAAc,CACdD,EAAEM,iBAvCM,EAACb,QAASc,qBACpBC,iBAAmBhB,oBAAoBC,gBACtCgB,MAAMC,OAAO,CAChBC,KAAMF,MAAMG,MAAMC,YAClBC,OAAO,kBAAU,eAAgB,SACjCC,MAAM,kBAAUR,YAAa,WAAYC,kBACzCQ,QAAS,CACLC,MAAM,kBAAU,UAErBC,MAAKC,QACJA,MAAMC,UAAUC,GAAGC,YAAYC,QAAQ,KACnC9B,QAAQ+B,WAEZL,MAAMM,OACCN,UA0BkBO,CAAYzB,aAAc,6BAClCiB,MAAKC,QACdA,MAAMC,UAAUC,GAAGC,YAAYL,MAAM,WAC3BU,eAzEfC,SAyEkD3B,aAzEjCP,QAAQ,MAAMC,QAAQkC,OA0E9BC,mBAAmBzB,mBAAmBsB,gBAAgBT,MAAKa,aACjDC,SApBGC,OAAMxC,QAASsC,cACtCvB,iBAAmBhB,oBAAoBC,SACvCyC,QAAUH,KAAKI,aAAe,kBAAU,sBAAuB,WAAY3B,kBAAoBuB,KAAKK,SAAS,GAAGF,QAChHvB,KAAOoB,KAAKI,OAAS,OAAS,eAC7B,iCAAgB,CAACD,QAAAA,QAASvB,KAAAA,QAgBI0B,CAAyBpC,aAAc8B,aACjDC,SAASd,MAAK,WACXoB,gBA1DPX,CAAAA,gBAChB7B,SAASyC,uCAAgCZ,sBAyDAa,CAAmBb,uBACpCW,gBAAgBG,eAE5BC,MAAMC,4BAGNxB,SACRuB,MAAMC,6BAIjB7C,SAASC,iBAAiB6C,mBAAWC,gBAAgB7C,IAEK,iBAD9BA,EAAEE,OACN4C,aAAa,4EASrB,uBACPC,gBAAgB,SAAU,CAAC,0BAC3BA,gBAAgB,aAAc,CAAC,mCAC/BA,gBAAgB,gBAAiB,CAAC,4BAA6B,wBACxElD"} \ No newline at end of file +{"version":3,"file":"manage_subscriptions.min.js","sources":["../src/manage_subscriptions.js"],"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 * A module to handle Delete/Update operations of the manage subscription page.\n *\n * @module core_calendar/manage_subscriptions\n * @copyright 2021 Huong Nguyen \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 4.0\n */\n\nimport * as CalendarSelectors from 'core_calendar/selectors';\nimport * as CalendarRepository from 'core_calendar/repository';\nimport ModalSaveCancel from 'core/modal_save_cancel';\nimport * as ModalEvents from 'core/modal_events';\nimport {exception as displayException, addNotification, fetchNotifications} from 'core/notification';\nimport Prefetch from 'core/prefetch';\nimport {getString} from 'core/str';\nimport {eventTypes} from 'core/local/inplace_editable/events';\n\n/**\n * Get subscription id for given element.\n *\n * @param {HTMLElement} element update/delete link\n * @return {Number}\n */\nconst getSubscriptionId = element => {\n return parseInt(element.closest('tr').dataset.subid);\n};\n\n/**\n * Get subscription name for given element.\n *\n * @param {HTMLElement} element update/delete link\n * @return {String}\n */\nconst getSubscriptionName = element => {\n return element.closest('tr').dataset.subname;\n};\n\n/**\n * Get subscription table row for subscription id.\n *\n * @param {string} subscriptionId Subscription id\n * @return {Element}\n */\nconst getSubscriptionRow = subscriptionId => {\n return document.querySelector(`tr[data-subid=\"${subscriptionId}\"]`);\n};\n\n/**\n * Create modal.\n *\n * @param {HTMLElement} element\n * @param {string} messageCode Message code.\n * @return {promise} Promise for modal\n */\nconst createModal = (element, messageCode) => {\n const subscriptionName = getSubscriptionName(element);\n return ModalSaveCancel.create({\n title: getString('confirmation', 'admin'),\n body: getString(messageCode, 'calendar', subscriptionName),\n buttons: {\n save: getString('yes')\n },\n }).then(modal => {\n modal.getRoot().on(ModalEvents.hidden, () => {\n element.focus();\n });\n modal.show();\n return modal;\n });\n};\n\n/**\n * Response handler for delete action.\n *\n * @param {HTMLElement} element\n * @param {Object} data\n * @return {Promise}\n */\nconst responseHandlerForDelete = async(element, data) => {\n const subscriptionName = getSubscriptionName(element);\n const message = data.status ? await getString('subscriptionremoved', 'calendar', subscriptionName) : data.warnings[0].message;\n const type = data.status ? 'info' : 'error';\n return addNotification({message, type});\n};\n\n/**\n * Register events for update/delete links.\n */\nconst registerEventListeners = () => {\n document.addEventListener('click', e => {\n const deleteAction = e.target.closest(CalendarSelectors.actions.deleteSubscription);\n if (deleteAction) {\n e.preventDefault();\n const modalPromise = createModal(deleteAction, 'confirmsubscriptiondelete');\n modalPromise.then(modal => {\n modal.getRoot().on(ModalEvents.save, () => {\n const subscriptionId = getSubscriptionId(deleteAction);\n CalendarRepository.deleteSubscription(subscriptionId).then(data => {\n const response = responseHandlerForDelete(deleteAction, data);\n return response.then(() => {\n const subscriptionRow = getSubscriptionRow(subscriptionId);\n return subscriptionRow.remove();\n });\n }).catch(displayException);\n });\n\n return modal;\n }).catch(displayException);\n }\n });\n\n document.addEventListener(eventTypes.elementUpdated, e => {\n const inplaceEditable = e.target;\n if (inplaceEditable.getAttribute('data-component') == 'core_calendar') {\n fetchNotifications();\n }\n });\n};\n\n/**\n * Initialises.\n */\nexport const init = () => {\n Prefetch.prefetchStrings('moodle', ['yes']);\n Prefetch.prefetchStrings('core_admin', ['confirmation']);\n Prefetch.prefetchStrings('core_calendar', ['confirmsubscriptiondelete', 'subscriptionremoved']);\n registerEventListeners();\n};\n"],"names":["getSubscriptionName","element","closest","dataset","subname","registerEventListeners","document","addEventListener","e","deleteAction","target","CalendarSelectors","actions","deleteSubscription","preventDefault","messageCode","subscriptionName","ModalSaveCancel","create","title","body","buttons","save","then","modal","getRoot","on","ModalEvents","hidden","focus","show","createModal","subscriptionId","parseInt","subid","CalendarRepository","data","response","async","message","status","warnings","type","responseHandlerForDelete","subscriptionRow","querySelector","getSubscriptionRow","remove","catch","displayException","eventTypes","elementUpdated","getAttribute","prefetchStrings"],"mappings":";;;;;;;;+WAiDMA,oBAAsBC,SACjBA,QAAQC,QAAQ,MAAMC,QAAQC,QAsDnCC,uBAAyB,KAC3BC,SAASC,iBAAiB,SAASC,UACzBC,aAAeD,EAAEE,OAAOR,QAAQS,kBAAkBC,QAAQC,uBAC5DJ,aAAc,CACdD,EAAEM,iBAtCM,EAACb,QAASc,qBACpBC,iBAAmBhB,oBAAoBC,gBACtCgB,2BAAgBC,OAAO,CAC1BC,OAAO,kBAAU,eAAgB,SACjCC,MAAM,kBAAUL,YAAa,WAAYC,kBACzCK,QAAS,CACLC,MAAM,kBAAU,UAErBC,MAAKC,QACJA,MAAMC,UAAUC,GAAGC,YAAYC,QAAQ,KACnC3B,QAAQ4B,WAEZL,MAAMM,OACCN,UA0BkBO,CAAYtB,aAAc,6BAClCc,MAAKC,QACdA,MAAMC,UAAUC,GAAGC,YAAYL,MAAM,WAC3BU,eAxEfC,SAwEkDxB,aAxEjCP,QAAQ,MAAMC,QAAQ+B,OAyE9BC,mBAAmBtB,mBAAmBmB,gBAAgBT,MAAKa,aACjDC,SApBGC,OAAMrC,QAASmC,cACtCpB,iBAAmBhB,oBAAoBC,SACvCsC,QAAUH,KAAKI,aAAe,kBAAU,sBAAuB,WAAYxB,kBAAoBoB,KAAKK,SAAS,GAAGF,QAChHG,KAAON,KAAKI,OAAS,OAAS,eAC7B,iCAAgB,CAACD,QAAAA,QAASG,KAAAA,QAgBIC,CAAyBlC,aAAc2B,aACjDC,SAASd,MAAK,WACXqB,gBAzDPZ,CAAAA,gBAChB1B,SAASuC,uCAAgCb,sBAwDAc,CAAmBd,uBACpCY,gBAAgBG,eAE5BC,MAAMC,4BAGNzB,SACRwB,MAAMC,6BAIjB3C,SAASC,iBAAiB2C,mBAAWC,gBAAgB3C,IAEK,iBAD9BA,EAAEE,OACN0C,aAAa,4EASrB,uBACPC,gBAAgB,SAAU,CAAC,0BAC3BA,gBAAgB,aAAc,CAAC,mCAC/BA,gBAAgB,gBAAiB,CAAC,4BAA6B,wBACxEhD"} \ No newline at end of file diff --git a/calendar/amd/build/modal_event_form.min.js b/calendar/amd/build/modal_event_form.min.js index 8086b436ab6..58aaca6b672 100644 --- a/calendar/amd/build/modal_event_form.min.js +++ b/calendar/amd/build/modal_event_form.min.js @@ -1,3 +1,3 @@ -define("core_calendar/modal_event_form",["exports","jquery","core/custom_interaction_events","core/modal","core_form/events","./events","core/str","core/notification","core/fragment","core_calendar/repository"],(function(_exports,_jquery,CustomEvents,_modal,FormEvents,_events2,Str,Notification,Fragment,Repository){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireWildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}return newObj.default=obj,cache&&cache.set(obj,newObj),newObj}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _defineProperty(obj,key,value){return key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_jquery=_interopRequireDefault(_jquery),CustomEvents=_interopRequireWildcard(CustomEvents),_modal=_interopRequireDefault(_modal),FormEvents=_interopRequireWildcard(FormEvents),_events2=_interopRequireDefault(_events2),Str=_interopRequireWildcard(Str),Notification=_interopRequireWildcard(Notification),Fragment=_interopRequireWildcard(Fragment),Repository=_interopRequireWildcard(Repository);const SELECTORS_SAVE_BUTTON='[data-action="save"]',SELECTORS_LOADING_ICON_CONTAINER='[data-region="loading-icon-container"]';class ModalEventForm extends _modal.default{constructor(root){super(root),this.eventId=null,this.startTime=null,this.courseId=null,this.categoryId=null,this.contextId=null,this.reloadingBody=!1,this.reloadingTitle=!1,this.saveButton=this.getFooter().find(SELECTORS_SAVE_BUTTON)}setContextId(id){this.contextId=id}getContextId(){return this.contextId}setCourseId(id){this.courseId=id}getCourseId(){return this.courseId}setCategoryId(id){this.categoryId=id}getCategoryId(){return this.categoryId}hasCourseId(){return null!==this.courseId}hasCategoryId(){return null!==this.categoryId}setEventId(id){this.eventId=id}getEventId(){return this.eventId}hasEventId(){return null!==this.eventId}setStartTime(time){this.startTime=time}getStartTime(){return this.startTime}hasStartTime(){return null!==this.startTime}getForm(){return this.getBody().find("form")}disableButtons(){this.saveButton.prop("disabled",!0)}enableButtons(){this.saveButton.prop("disabled",!1)}reloadTitleContent(){return this.reloadingTitle||(this.reloadingTitle=!0,this.hasEventId()?this.titlePromise=Str.get_string("editevent","calendar"):this.titlePromise=Str.get_string("newevent","calendar"),this.titlePromise.then((string=>(this.setTitle(string),string))).catch(Notification.exception).always((()=>{this.reloadingTitle=!1}))),this.titlePromise}reloadBodyContent(formData){if(this.reloadingBody)return this.bodyPromise;this.reloadingBody=!0,this.disableButtons();const args={};return this.hasEventId()&&(args.eventid=this.getEventId()),this.hasStartTime()&&(args.starttime=this.getStartTime()),this.hasCourseId()&&(args.courseid=this.getCourseId()),this.hasCategoryId()&&(args.categoryid=this.getCategoryId()),void 0!==formData&&(args.formdata=formData),this.bodyPromise=Fragment.loadFragment("calendar","event_form",this.getContextId(),args),this.setBody(this.bodyPromise),this.bodyPromise.then((()=>{this.enableButtons()})).catch(Notification.exception).always((()=>{this.reloadingBody=!1})),this.bodyPromise}reloadAllContent(){return _jquery.default.when(this.reloadTitleContent(),this.reloadBodyContent())}show(){this.reloadAllContent(),super.show(this)}hide(){super.hide(this),this.setEventId(null),this.setStartTime(null),this.setCourseId(null),this.setCategoryId(null)}getFormData(){return this.getForm().serialize()}save(){const loadingContainer=this.saveButton.find(SELECTORS_LOADING_ICON_CONTAINER),invalid=this.getForm().find('[aria-invalid="true"]');if(invalid.length)return invalid.first().focus(),Promise.resolve();loadingContainer.removeClass("hidden"),this.disableButtons();const formData=this.getFormData();return Repository.submitCreateUpdateForm(formData).then((response=>{if(response.validationerror)this.reloadBodyContent(formData);else{const isExisting=this.hasEventId();this.hide(),isExisting?(0,_jquery.default)("body").trigger(_events2.default.updated,[response.event]):(0,_jquery.default)("body").trigger(_events2.default.created,[response.event])}})).catch(Notification.exception).always((()=>{loadingContainer.addClass("hidden"),this.enableButtons()}))}registerEventListeners(){super.registerEventListeners(this),this.getModal().on(CustomEvents.events.activate,SELECTORS_SAVE_BUTTON,((e,data)=>{this.getForm().submit(),data.originalEvent.preventDefault(),e.stopPropagation()})),this.getModal().on("submit",(e=>{FormEvents.notifyFormSubmittedByJavascript(this.getForm()[0]),this.save(),e.preventDefault(),e.stopPropagation()}))}}return _exports.default=ModalEventForm,_defineProperty(ModalEventForm,"TYPE","core_calendar-modal_event_form"),_defineProperty(ModalEventForm,"TEMPLATE","calendar/modal_event_form"),ModalEventForm.registerModalType(),_exports.default})); +define("core_calendar/modal_event_form",["exports","jquery","core/custom_interaction_events","core/modal","core_form/events","./events","core/str","core/notification","core/fragment","core_calendar/repository"],(function(_exports,_jquery,CustomEvents,_modal,FormEvents,_events2,Str,Notification,Fragment,Repository){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireWildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}return newObj.default=obj,cache&&cache.set(obj,newObj),newObj}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _defineProperty(obj,key,value){return key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_jquery=_interopRequireDefault(_jquery),CustomEvents=_interopRequireWildcard(CustomEvents),_modal=_interopRequireDefault(_modal),FormEvents=_interopRequireWildcard(FormEvents),_events2=_interopRequireDefault(_events2),Str=_interopRequireWildcard(Str),Notification=_interopRequireWildcard(Notification),Fragment=_interopRequireWildcard(Fragment),Repository=_interopRequireWildcard(Repository);const SELECTORS_SAVE_BUTTON='[data-action="save"]',SELECTORS_LOADING_ICON_CONTAINER='[data-region="loading-icon-container"]';class ModalEventForm extends _modal.default{constructor(root){super(root),this.eventId=null,this.startTime=null,this.courseId=null,this.categoryId=null,this.contextId=null,this.reloadingBody=!1,this.reloadingTitle=!1,this.saveButton=this.getFooter().find(SELECTORS_SAVE_BUTTON)}configure(modalConfig){modalConfig.large=!0,super.configure(modalConfig)}setContextId(id){this.contextId=id}getContextId(){return this.contextId}setCourseId(id){this.courseId=id}getCourseId(){return this.courseId}setCategoryId(id){this.categoryId=id}getCategoryId(){return this.categoryId}hasCourseId(){return null!==this.courseId}hasCategoryId(){return null!==this.categoryId}setEventId(id){this.eventId=id}getEventId(){return this.eventId}hasEventId(){return null!==this.eventId}setStartTime(time){this.startTime=time}getStartTime(){return this.startTime}hasStartTime(){return null!==this.startTime}getForm(){return this.getBody().find("form")}disableButtons(){this.saveButton.prop("disabled",!0)}enableButtons(){this.saveButton.prop("disabled",!1)}reloadTitleContent(){return this.reloadingTitle||(this.reloadingTitle=!0,this.hasEventId()?this.titlePromise=Str.get_string("editevent","calendar"):this.titlePromise=Str.get_string("newevent","calendar"),this.titlePromise.then((string=>(this.setTitle(string),string))).catch(Notification.exception).always((()=>{this.reloadingTitle=!1}))),this.titlePromise}reloadBodyContent(formData){if(this.reloadingBody)return this.bodyPromise;this.reloadingBody=!0,this.disableButtons();const args={};return this.hasEventId()&&(args.eventid=this.getEventId()),this.hasStartTime()&&(args.starttime=this.getStartTime()),this.hasCourseId()&&(args.courseid=this.getCourseId()),this.hasCategoryId()&&(args.categoryid=this.getCategoryId()),void 0!==formData&&(args.formdata=formData),this.bodyPromise=Fragment.loadFragment("calendar","event_form",this.getContextId(),args),this.setBody(this.bodyPromise),this.bodyPromise.then((()=>{this.enableButtons()})).catch(Notification.exception).always((()=>{this.reloadingBody=!1})),this.bodyPromise}reloadAllContent(){return _jquery.default.when(this.reloadTitleContent(),this.reloadBodyContent())}show(){this.reloadAllContent(),super.show(this)}hide(){super.hide(this),this.setEventId(null),this.setStartTime(null),this.setCourseId(null),this.setCategoryId(null)}getFormData(){return this.getForm().serialize()}save(){const loadingContainer=this.saveButton.find(SELECTORS_LOADING_ICON_CONTAINER),invalid=this.getForm().find('[aria-invalid="true"]');if(invalid.length)return invalid.first().focus(),Promise.resolve();loadingContainer.removeClass("hidden"),this.disableButtons();const formData=this.getFormData();return Repository.submitCreateUpdateForm(formData).then((response=>{if(response.validationerror)this.reloadBodyContent(formData);else{const isExisting=this.hasEventId();this.hide(),isExisting?(0,_jquery.default)("body").trigger(_events2.default.updated,[response.event]):(0,_jquery.default)("body").trigger(_events2.default.created,[response.event])}})).catch(Notification.exception).always((()=>{loadingContainer.addClass("hidden"),this.enableButtons()}))}registerEventListeners(){super.registerEventListeners(this),this.getModal().on(CustomEvents.events.activate,SELECTORS_SAVE_BUTTON,((e,data)=>{this.getForm().submit(),data.originalEvent.preventDefault(),e.stopPropagation()})),this.getModal().on("submit",(e=>{FormEvents.notifyFormSubmittedByJavascript(this.getForm()[0]),this.save(),e.preventDefault(),e.stopPropagation()}))}}return _exports.default=ModalEventForm,_defineProperty(ModalEventForm,"TYPE","core_calendar-modal_event_form"),_defineProperty(ModalEventForm,"TEMPLATE","calendar/modal_event_form"),ModalEventForm.registerModalType(),_exports.default})); //# sourceMappingURL=modal_event_form.min.js.map \ No newline at end of file diff --git a/calendar/amd/build/modal_event_form.min.js.map b/calendar/amd/build/modal_event_form.min.js.map index 79790b47882..a68ddc571bb 100644 --- a/calendar/amd/build/modal_event_form.min.js.map +++ b/calendar/amd/build/modal_event_form.min.js.map @@ -1 +1 @@ -{"version":3,"file":"modal_event_form.min.js","sources":["../src/modal_event_form.js"],"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 * Contain the logic for the quick add or update event modal.\n *\n * @module core_calendar/modal_event_form\n * @copyright 2017 Ryan Wyllie \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport $ from 'jquery';\nimport * as CustomEvents from 'core/custom_interaction_events';\nimport Modal from 'core/modal';\nimport * as FormEvents from 'core_form/events';\nimport CalendarEvents from './events';\nimport * as Str from 'core/str';\nimport * as Notification from 'core/notification';\nimport * as Fragment from 'core/fragment';\nimport * as Repository from 'core_calendar/repository';\n\nconst SELECTORS = {\n SAVE_BUTTON: '[data-action=\"save\"]',\n LOADING_ICON_CONTAINER: '[data-region=\"loading-icon-container\"]',\n};\n\nexport default class ModalEventForm extends Modal {\n static TYPE = 'core_calendar-modal_event_form';\n static TEMPLATE = 'calendar/modal_event_form';\n\n /**\n * Constructor for the Modal.\n *\n * @param {object} root The root jQuery element for the modal\n */\n constructor(root) {\n super(root);\n\n this.eventId = null;\n this.startTime = null;\n this.courseId = null;\n this.categoryId = null;\n this.contextId = null;\n this.reloadingBody = false;\n this.reloadingTitle = false;\n this.saveButton = this.getFooter().find(SELECTORS.SAVE_BUTTON);\n }\n\n /**\n * Set the context id to the given value.\n *\n * @method setContextId\n * @param {Number} id The event id\n */\n setContextId(id) {\n this.contextId = id;\n }\n\n /**\n * Retrieve the current context id, if any.\n *\n * @method getContextId\n * @return {Number|null} The event id\n */\n getContextId() {\n return this.contextId;\n }\n\n /**\n * Set the course id to the given value.\n *\n * @method setCourseId\n * @param {Number} id The event id\n */\n setCourseId(id) {\n this.courseId = id;\n }\n\n /**\n * Retrieve the current course id, if any.\n *\n * @method getCourseId\n * @return {Number|null} The event id\n */\n getCourseId() {\n return this.courseId;\n }\n\n /**\n * Set the category id to the given value.\n *\n * @method setCategoryId\n * @param {Number} id The event id\n */\n setCategoryId(id) {\n this.categoryId = id;\n }\n\n /**\n * Retrieve the current category id, if any.\n *\n * @method getCategoryId\n * @return {Number|null} The event id\n */\n getCategoryId() {\n return this.categoryId;\n }\n\n /**\n * Check if the modal has an course id.\n *\n * @method hasCourseId\n * @return {bool}\n */\n hasCourseId() {\n return this.courseId !== null;\n }\n\n /**\n * Check if the modal has an category id.\n *\n * @method hasCategoryId\n * @return {bool}\n */\n hasCategoryId() {\n return this.categoryId !== null;\n }\n\n /**\n * Set the event id to the given value.\n *\n * @method setEventId\n * @param {Number} id The event id\n */\n setEventId(id) {\n this.eventId = id;\n }\n\n /**\n * Retrieve the current event id, if any.\n *\n * @method getEventId\n * @return {Number|null} The event id\n */\n getEventId() {\n return this.eventId;\n }\n\n /**\n * Check if the modal has an event id.\n *\n * @method hasEventId\n * @return {bool}\n */\n hasEventId() {\n return this.eventId !== null;\n }\n\n /**\n * Set the start time to the given value.\n *\n * @method setStartTime\n * @param {Number} time The start time\n */\n setStartTime(time) {\n this.startTime = time;\n }\n\n /**\n * Retrieve the current start time, if any.\n *\n * @method getStartTime\n * @return {Number|null} The start time\n */\n getStartTime() {\n return this.startTime;\n }\n\n /**\n * Check if the modal has start time.\n *\n * @method hasStartTime\n * @return {bool}\n */\n hasStartTime() {\n return this.startTime !== null;\n }\n\n /**\n * Get the form element from the modal.\n *\n * @method getForm\n * @return {object}\n */\n getForm() {\n return this.getBody().find('form');\n }\n\n /**\n * Disable the buttons in the footer.\n *\n * @method disableButtons\n */\n disableButtons() {\n this.saveButton.prop('disabled', true);\n }\n\n /**\n * Enable the buttons in the footer.\n *\n * @method enableButtons\n */\n enableButtons() {\n this.saveButton.prop('disabled', false);\n }\n\n /**\n * Reload the title for the modal to the appropriate value\n * depending on whether we are creating a new event or\n * editing an existing event.\n *\n * @method reloadTitleContent\n * @return {object} A promise resolved with the new title text\n */\n reloadTitleContent() {\n if (this.reloadingTitle) {\n return this.titlePromise;\n }\n\n this.reloadingTitle = true;\n\n if (this.hasEventId()) {\n this.titlePromise = Str.get_string('editevent', 'calendar');\n } else {\n this.titlePromise = Str.get_string('newevent', 'calendar');\n }\n\n this.titlePromise.then((string) => {\n this.setTitle(string);\n return string;\n })\n .catch(Notification.exception)\n .always(() => {\n this.reloadingTitle = false;\n return;\n });\n\n return this.titlePromise;\n }\n\n /**\n * Send a request to the server to get the event_form in a fragment\n * and render the result in the body of the modal.\n *\n * If serialised form data is provided then it will be sent in the\n * request to the server to have the form rendered with the data. This\n * is used when the form had a server side error and we need the server\n * to re-render it for us to display the error to the user.\n *\n * @method reloadBodyContent\n * @param {string} formData The serialised form data\n * @return {object} A promise resolved with the fragment html and js from\n */\n reloadBodyContent(formData) {\n if (this.reloadingBody) {\n return this.bodyPromise;\n }\n\n this.reloadingBody = true;\n this.disableButtons();\n\n const args = {};\n\n if (this.hasEventId()) {\n args.eventid = this.getEventId();\n }\n\n if (this.hasStartTime()) {\n args.starttime = this.getStartTime();\n }\n\n if (this.hasCourseId()) {\n args.courseid = this.getCourseId();\n }\n\n if (this.hasCategoryId()) {\n args.categoryid = this.getCategoryId();\n }\n\n if (typeof formData !== 'undefined') {\n args.formdata = formData;\n }\n\n this.bodyPromise = Fragment.loadFragment('calendar', 'event_form', this.getContextId(), args);\n\n this.setBody(this.bodyPromise);\n\n this.bodyPromise.then(() => {\n this.enableButtons();\n return;\n })\n .catch(Notification.exception)\n .always(() => {\n this.reloadingBody = false;\n return;\n });\n\n return this.bodyPromise;\n }\n\n /**\n * Reload both the title and body content.\n *\n * @method reloadAllContent\n * @return {object} promise\n */\n reloadAllContent() {\n return $.when(this.reloadTitleContent(), this.reloadBodyContent());\n }\n\n /**\n * Kick off a reload the modal content before showing it. This\n * is to allow us to re-use the same modal for creating and\n * editing different events within the page.\n *\n * We do the reload when showing the modal rather than hiding it\n * to save a request to the server if the user closes the modal\n * and never re-opens it.\n *\n * @method show\n */\n show() {\n this.reloadAllContent();\n super.show(this);\n }\n\n /**\n * Clear the event id from the modal when it's closed so\n * that it is loaded fresh next time it's displayed.\n *\n * The event id will be set by the calling code if it wants\n * to edit a specific event.\n *\n * @method hide\n */\n hide() {\n super.hide(this);\n this.setEventId(null);\n this.setStartTime(null);\n this.setCourseId(null);\n this.setCategoryId(null);\n }\n\n /**\n * Get the serialised form data.\n *\n * @method getFormData\n * @return {string} serialised form data\n */\n getFormData() {\n return this.getForm().serialize();\n }\n\n /**\n * Send the form data to the server to create or update\n * an event.\n *\n * If there is a server side validation error then we re-request the\n * rendered form (with the data) from the server in order to get the\n * server side errors to display.\n *\n * On success the modal is hidden and the page is reloaded so that the\n * new event will display.\n *\n * @method save\n * @return {object} A promise\n */\n save() {\n const loadingContainer = this.saveButton.find(SELECTORS.LOADING_ICON_CONTAINER);\n\n // Now the change events have run, see if there are any \"invalid\" form fields.\n const invalid = this.getForm().find('[aria-invalid=\"true\"]');\n\n // If we found invalid fields, focus on the first one and do not submit via ajax.\n if (invalid.length) {\n invalid.first().focus();\n return Promise.resolve();\n }\n\n loadingContainer.removeClass('hidden');\n this.disableButtons();\n\n const formData = this.getFormData();\n // Send the form data to the server for processing.\n return Repository.submitCreateUpdateForm(formData)\n .then((response) => {\n if (response.validationerror) {\n // If there was a server side validation error then\n // we need to re-request the rendered form from the server\n // in order to display the error for the user.\n this.reloadBodyContent(formData);\n return;\n } else {\n // Check whether this was a new event or not.\n // The hide function unsets the form data so grab this before the hide.\n const isExisting = this.hasEventId();\n\n // No problemo! Our work here is done.\n this.hide();\n\n // Trigger the appropriate calendar event so that the view can be updated.\n if (isExisting) {\n $('body').trigger(CalendarEvents.updated, [response.event]);\n } else {\n $('body').trigger(CalendarEvents.created, [response.event]);\n }\n }\n\n return;\n })\n .catch(Notification.exception)\n .always(() => {\n // Regardless of success or error we should always stop\n // the loading icon and re-enable the buttons.\n loadingContainer.addClass('hidden');\n this.enableButtons();\n\n return;\n });\n }\n\n /**\n * Set up all of the event handling for the modal.\n *\n * @method registerEventListeners\n * @fires event:uploadStarted\n * @fires event:formSubmittedByJavascript\n */\n registerEventListeners() {\n // Apply parent event listeners.\n super.registerEventListeners(this);\n\n // When the user clicks the save button we trigger the form submission. We need to\n // trigger an actual submission because there is some JS code in the form that is\n // listening for this event and doing some stuff (e.g. saving draft areas etc).\n this.getModal().on(CustomEvents.events.activate, SELECTORS.SAVE_BUTTON, (e, data) => {\n this.getForm().submit();\n data.originalEvent.preventDefault();\n e.stopPropagation();\n });\n\n // Catch the submit event before it is actually processed by the browser and\n // prevent the submission. We'll take it from here.\n this.getModal().on('submit', (e) => {\n FormEvents.notifyFormSubmittedByJavascript(this.getForm()[0]);\n\n this.save();\n\n // Stop the form from actually submitting and prevent it's\n // propagation because we have already handled the event.\n e.preventDefault();\n e.stopPropagation();\n });\n }\n}\n\nModalEventForm.registerModalType();\n"],"names":["SELECTORS","ModalEventForm","Modal","constructor","root","eventId","startTime","courseId","categoryId","contextId","reloadingBody","reloadingTitle","saveButton","this","getFooter","find","setContextId","id","getContextId","setCourseId","getCourseId","setCategoryId","getCategoryId","hasCourseId","hasCategoryId","setEventId","getEventId","hasEventId","setStartTime","time","getStartTime","hasStartTime","getForm","getBody","disableButtons","prop","enableButtons","reloadTitleContent","titlePromise","Str","get_string","then","string","setTitle","catch","Notification","exception","always","reloadBodyContent","formData","bodyPromise","args","eventid","starttime","courseid","categoryid","formdata","Fragment","loadFragment","setBody","reloadAllContent","$","when","show","hide","getFormData","serialize","save","loadingContainer","invalid","length","first","focus","Promise","resolve","removeClass","Repository","submitCreateUpdateForm","response","validationerror","isExisting","trigger","CalendarEvents","updated","event","created","addClass","registerEventListeners","getModal","on","CustomEvents","events","activate","e","data","submit","originalEvent","preventDefault","stopPropagation","FormEvents","notifyFormSubmittedByJavascript","registerModalType"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"modal_event_form.min.js","sources":["../src/modal_event_form.js"],"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 * Contain the logic for the quick add or update event modal.\n *\n * @module core_calendar/modal_event_form\n * @copyright 2017 Ryan Wyllie \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport $ from 'jquery';\nimport * as CustomEvents from 'core/custom_interaction_events';\nimport Modal from 'core/modal';\nimport * as FormEvents from 'core_form/events';\nimport CalendarEvents from './events';\nimport * as Str from 'core/str';\nimport * as Notification from 'core/notification';\nimport * as Fragment from 'core/fragment';\nimport * as Repository from 'core_calendar/repository';\n\nconst SELECTORS = {\n SAVE_BUTTON: '[data-action=\"save\"]',\n LOADING_ICON_CONTAINER: '[data-region=\"loading-icon-container\"]',\n};\n\nexport default class ModalEventForm extends Modal {\n static TYPE = 'core_calendar-modal_event_form';\n static TEMPLATE = 'calendar/modal_event_form';\n\n /**\n * Constructor for the Modal.\n *\n * @param {object} root The root jQuery element for the modal\n */\n constructor(root) {\n super(root);\n\n this.eventId = null;\n this.startTime = null;\n this.courseId = null;\n this.categoryId = null;\n this.contextId = null;\n this.reloadingBody = false;\n this.reloadingTitle = false;\n this.saveButton = this.getFooter().find(SELECTORS.SAVE_BUTTON);\n }\n\n configure(modalConfig) {\n modalConfig.large = true;\n super.configure(modalConfig);\n }\n\n /**\n * Set the context id to the given value.\n *\n * @method setContextId\n * @param {Number} id The event id\n */\n setContextId(id) {\n this.contextId = id;\n }\n\n /**\n * Retrieve the current context id, if any.\n *\n * @method getContextId\n * @return {Number|null} The event id\n */\n getContextId() {\n return this.contextId;\n }\n\n /**\n * Set the course id to the given value.\n *\n * @method setCourseId\n * @param {Number} id The event id\n */\n setCourseId(id) {\n this.courseId = id;\n }\n\n /**\n * Retrieve the current course id, if any.\n *\n * @method getCourseId\n * @return {Number|null} The event id\n */\n getCourseId() {\n return this.courseId;\n }\n\n /**\n * Set the category id to the given value.\n *\n * @method setCategoryId\n * @param {Number} id The event id\n */\n setCategoryId(id) {\n this.categoryId = id;\n }\n\n /**\n * Retrieve the current category id, if any.\n *\n * @method getCategoryId\n * @return {Number|null} The event id\n */\n getCategoryId() {\n return this.categoryId;\n }\n\n /**\n * Check if the modal has an course id.\n *\n * @method hasCourseId\n * @return {bool}\n */\n hasCourseId() {\n return this.courseId !== null;\n }\n\n /**\n * Check if the modal has an category id.\n *\n * @method hasCategoryId\n * @return {bool}\n */\n hasCategoryId() {\n return this.categoryId !== null;\n }\n\n /**\n * Set the event id to the given value.\n *\n * @method setEventId\n * @param {Number} id The event id\n */\n setEventId(id) {\n this.eventId = id;\n }\n\n /**\n * Retrieve the current event id, if any.\n *\n * @method getEventId\n * @return {Number|null} The event id\n */\n getEventId() {\n return this.eventId;\n }\n\n /**\n * Check if the modal has an event id.\n *\n * @method hasEventId\n * @return {bool}\n */\n hasEventId() {\n return this.eventId !== null;\n }\n\n /**\n * Set the start time to the given value.\n *\n * @method setStartTime\n * @param {Number} time The start time\n */\n setStartTime(time) {\n this.startTime = time;\n }\n\n /**\n * Retrieve the current start time, if any.\n *\n * @method getStartTime\n * @return {Number|null} The start time\n */\n getStartTime() {\n return this.startTime;\n }\n\n /**\n * Check if the modal has start time.\n *\n * @method hasStartTime\n * @return {bool}\n */\n hasStartTime() {\n return this.startTime !== null;\n }\n\n /**\n * Get the form element from the modal.\n *\n * @method getForm\n * @return {object}\n */\n getForm() {\n return this.getBody().find('form');\n }\n\n /**\n * Disable the buttons in the footer.\n *\n * @method disableButtons\n */\n disableButtons() {\n this.saveButton.prop('disabled', true);\n }\n\n /**\n * Enable the buttons in the footer.\n *\n * @method enableButtons\n */\n enableButtons() {\n this.saveButton.prop('disabled', false);\n }\n\n /**\n * Reload the title for the modal to the appropriate value\n * depending on whether we are creating a new event or\n * editing an existing event.\n *\n * @method reloadTitleContent\n * @return {object} A promise resolved with the new title text\n */\n reloadTitleContent() {\n if (this.reloadingTitle) {\n return this.titlePromise;\n }\n\n this.reloadingTitle = true;\n\n if (this.hasEventId()) {\n this.titlePromise = Str.get_string('editevent', 'calendar');\n } else {\n this.titlePromise = Str.get_string('newevent', 'calendar');\n }\n\n this.titlePromise.then((string) => {\n this.setTitle(string);\n return string;\n })\n .catch(Notification.exception)\n .always(() => {\n this.reloadingTitle = false;\n return;\n });\n\n return this.titlePromise;\n }\n\n /**\n * Send a request to the server to get the event_form in a fragment\n * and render the result in the body of the modal.\n *\n * If serialised form data is provided then it will be sent in the\n * request to the server to have the form rendered with the data. This\n * is used when the form had a server side error and we need the server\n * to re-render it for us to display the error to the user.\n *\n * @method reloadBodyContent\n * @param {string} formData The serialised form data\n * @return {object} A promise resolved with the fragment html and js from\n */\n reloadBodyContent(formData) {\n if (this.reloadingBody) {\n return this.bodyPromise;\n }\n\n this.reloadingBody = true;\n this.disableButtons();\n\n const args = {};\n\n if (this.hasEventId()) {\n args.eventid = this.getEventId();\n }\n\n if (this.hasStartTime()) {\n args.starttime = this.getStartTime();\n }\n\n if (this.hasCourseId()) {\n args.courseid = this.getCourseId();\n }\n\n if (this.hasCategoryId()) {\n args.categoryid = this.getCategoryId();\n }\n\n if (typeof formData !== 'undefined') {\n args.formdata = formData;\n }\n\n this.bodyPromise = Fragment.loadFragment('calendar', 'event_form', this.getContextId(), args);\n\n this.setBody(this.bodyPromise);\n\n this.bodyPromise.then(() => {\n this.enableButtons();\n return;\n })\n .catch(Notification.exception)\n .always(() => {\n this.reloadingBody = false;\n return;\n });\n\n return this.bodyPromise;\n }\n\n /**\n * Reload both the title and body content.\n *\n * @method reloadAllContent\n * @return {object} promise\n */\n reloadAllContent() {\n return $.when(this.reloadTitleContent(), this.reloadBodyContent());\n }\n\n /**\n * Kick off a reload the modal content before showing it. This\n * is to allow us to re-use the same modal for creating and\n * editing different events within the page.\n *\n * We do the reload when showing the modal rather than hiding it\n * to save a request to the server if the user closes the modal\n * and never re-opens it.\n *\n * @method show\n */\n show() {\n this.reloadAllContent();\n super.show(this);\n }\n\n /**\n * Clear the event id from the modal when it's closed so\n * that it is loaded fresh next time it's displayed.\n *\n * The event id will be set by the calling code if it wants\n * to edit a specific event.\n *\n * @method hide\n */\n hide() {\n super.hide(this);\n this.setEventId(null);\n this.setStartTime(null);\n this.setCourseId(null);\n this.setCategoryId(null);\n }\n\n /**\n * Get the serialised form data.\n *\n * @method getFormData\n * @return {string} serialised form data\n */\n getFormData() {\n return this.getForm().serialize();\n }\n\n /**\n * Send the form data to the server to create or update\n * an event.\n *\n * If there is a server side validation error then we re-request the\n * rendered form (with the data) from the server in order to get the\n * server side errors to display.\n *\n * On success the modal is hidden and the page is reloaded so that the\n * new event will display.\n *\n * @method save\n * @return {object} A promise\n */\n save() {\n const loadingContainer = this.saveButton.find(SELECTORS.LOADING_ICON_CONTAINER);\n\n // Now the change events have run, see if there are any \"invalid\" form fields.\n const invalid = this.getForm().find('[aria-invalid=\"true\"]');\n\n // If we found invalid fields, focus on the first one and do not submit via ajax.\n if (invalid.length) {\n invalid.first().focus();\n return Promise.resolve();\n }\n\n loadingContainer.removeClass('hidden');\n this.disableButtons();\n\n const formData = this.getFormData();\n // Send the form data to the server for processing.\n return Repository.submitCreateUpdateForm(formData)\n .then((response) => {\n if (response.validationerror) {\n // If there was a server side validation error then\n // we need to re-request the rendered form from the server\n // in order to display the error for the user.\n this.reloadBodyContent(formData);\n return;\n } else {\n // Check whether this was a new event or not.\n // The hide function unsets the form data so grab this before the hide.\n const isExisting = this.hasEventId();\n\n // No problemo! Our work here is done.\n this.hide();\n\n // Trigger the appropriate calendar event so that the view can be updated.\n if (isExisting) {\n $('body').trigger(CalendarEvents.updated, [response.event]);\n } else {\n $('body').trigger(CalendarEvents.created, [response.event]);\n }\n }\n\n return;\n })\n .catch(Notification.exception)\n .always(() => {\n // Regardless of success or error we should always stop\n // the loading icon and re-enable the buttons.\n loadingContainer.addClass('hidden');\n this.enableButtons();\n\n return;\n });\n }\n\n /**\n * Set up all of the event handling for the modal.\n *\n * @method registerEventListeners\n * @fires event:uploadStarted\n * @fires event:formSubmittedByJavascript\n */\n registerEventListeners() {\n // Apply parent event listeners.\n super.registerEventListeners(this);\n\n // When the user clicks the save button we trigger the form submission. We need to\n // trigger an actual submission because there is some JS code in the form that is\n // listening for this event and doing some stuff (e.g. saving draft areas etc).\n this.getModal().on(CustomEvents.events.activate, SELECTORS.SAVE_BUTTON, (e, data) => {\n this.getForm().submit();\n data.originalEvent.preventDefault();\n e.stopPropagation();\n });\n\n // Catch the submit event before it is actually processed by the browser and\n // prevent the submission. We'll take it from here.\n this.getModal().on('submit', (e) => {\n FormEvents.notifyFormSubmittedByJavascript(this.getForm()[0]);\n\n this.save();\n\n // Stop the form from actually submitting and prevent it's\n // propagation because we have already handled the event.\n e.preventDefault();\n e.stopPropagation();\n });\n }\n}\n\nModalEventForm.registerModalType();\n"],"names":["SELECTORS","ModalEventForm","Modal","constructor","root","eventId","startTime","courseId","categoryId","contextId","reloadingBody","reloadingTitle","saveButton","this","getFooter","find","configure","modalConfig","large","setContextId","id","getContextId","setCourseId","getCourseId","setCategoryId","getCategoryId","hasCourseId","hasCategoryId","setEventId","getEventId","hasEventId","setStartTime","time","getStartTime","hasStartTime","getForm","getBody","disableButtons","prop","enableButtons","reloadTitleContent","titlePromise","Str","get_string","then","string","setTitle","catch","Notification","exception","always","reloadBodyContent","formData","bodyPromise","args","eventid","starttime","courseid","categoryid","formdata","Fragment","loadFragment","setBody","reloadAllContent","$","when","show","hide","getFormData","serialize","save","loadingContainer","invalid","length","first","focus","Promise","resolve","removeClass","Repository","submitCreateUpdateForm","response","validationerror","isExisting","trigger","CalendarEvents","updated","event","created","addClass","registerEventListeners","getModal","on","CustomEvents","events","activate","e","data","submit","originalEvent","preventDefault","stopPropagation","FormEvents","notifyFormSubmittedByJavascript","registerModalType"],"mappings":"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"} \ No newline at end of file diff --git a/calendar/amd/build/view_manager.min.js b/calendar/amd/build/view_manager.min.js index b496055ee51..6355e784c87 100644 --- a/calendar/amd/build/view_manager.min.js +++ b/calendar/amd/build/view_manager.min.js @@ -1,10 +1,10 @@ -define("core_calendar/view_manager",["exports","jquery","core/templates","core/notification","core_calendar/repository","core_calendar/events","core_calendar/selectors","core/modal_factory","core/modal_events","core_calendar/summary_modal","core/custom_interaction_events","core/str","core/pending","core/prefetch"],(function(_exports,_jquery,_templates,_notification,CalendarRepository,_events,CalendarSelectors,_modal_factory,_modal_events,_summary_modal,_custom_interaction_events,_str,_pending,_prefetch){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireWildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}return newObj.default=obj,cache&&cache.set(obj,newObj),newObj}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}} +define("core_calendar/view_manager",["exports","jquery","core/templates","core/notification","core_calendar/repository","core_calendar/events","core_calendar/selectors","core/modal_events","core_calendar/summary_modal","core/custom_interaction_events","core/str","core/pending","core/prefetch"],(function(_exports,_jquery,_templates,_notification,CalendarRepository,_events,CalendarSelectors,_modal_events,_summary_modal,_custom_interaction_events,_str,_pending,_prefetch){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireWildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}return newObj.default=obj,cache&&cache.set(obj,newObj),newObj}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}} /** * A javascript module to handler calendar view changes. * * @module core_calendar/view_manager * @copyright 2017 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.updateUrl=_exports.reloadCurrentUpcoming=_exports.reloadCurrentMonth=_exports.reloadCurrentDay=_exports.registerEventListenersForMonthDetailed=_exports.refreshMonthContent=_exports.refreshDayContent=_exports.init=_exports.foldDayEvents=_exports.changeMonth=_exports.changeDay=void 0,_jquery=_interopRequireDefault(_jquery),_templates=_interopRequireDefault(_templates),_notification=_interopRequireDefault(_notification),CalendarRepository=_interopRequireWildcard(CalendarRepository),_events=_interopRequireDefault(_events),CalendarSelectors=_interopRequireWildcard(CalendarSelectors),_modal_factory=_interopRequireDefault(_modal_factory),_modal_events=_interopRequireDefault(_modal_events),_summary_modal=_interopRequireDefault(_summary_modal),_custom_interaction_events=_interopRequireDefault(_custom_interaction_events),_pending=_interopRequireDefault(_pending);const foldDayEvents=()=>{const days=(0,_jquery.default)(CalendarSelectors.elements.monthDetailed).find(CalendarSelectors.day);0!==days.length&&days.each((function(){const dayContainer=(0,_jquery.default)(this),eventsSelector="".concat(CalendarSelectors.elements.dateContent," ul li[data-event-eventtype]"),filteredEventsSelector="".concat(CalendarSelectors.elements.dateContent,' ul li[data-event-filtered="true"]'),moreEventsSelector="".concat(CalendarSelectors.elements.dateContent,' [data-action="view-more-events"]'),events=dayContainer.find(eventsSelector);if(0===events.length)return;const numberOfFiltered=dayContainer.find(filteredEventsSelector).length,numberOfEvents=events.length-numberOfFiltered;let count=1;events.each((function(){const event=(0,_jquery.default)(this);"true"!==event.attr("data-event-filtered")?count>5-(5===numberOfEvents?0:1)?(event.attr("data-event-folded","true"),event.hide()):(event.attr("data-event-folded","false"),event.show(),count++):event.attr("data-event-folded","false")}));const moreEventsLink=dayContainer.find(moreEventsSelector);if(numberOfEvents>5){const numberOfHiddenEvents=numberOfEvents-5+1;moreEventsLink.show(),(0,_str.getString)("moreevents","calendar",numberOfHiddenEvents).then((str=>{const link=moreEventsLink.find("strong a");return moreEventsLink.attr("data-event-folded","false"),link.text(str),str})).fail()}else moreEventsLink.hide()}))};_exports.foldDayEvents=foldDayEvents;const registerEventListenersForMonthDetailed=pendingId=>{const events="".concat(_events.default.viewUpdated);(0,_jquery.default)("body").on(events,(function(e){foldDayEvents()})),foldDayEvents(),(0,_jquery.default)("body").on(_events.default.filterChanged,(function(e,data){const root=(0,_jquery.default)(CalendarSelectors.elements.monthDetailed),pending=new _pending.default(pendingId),target=root.find(CalendarSelectors.eventType[data.type]),transitionPromise=_jquery.default.Deferred();data.hidden?transitionPromise.then((function(){return target.attr("data-event-filtered","true"),target.hide().promise()})).fail():transitionPromise.then((function(){return target.attr("data-event-filtered","false"),target.show().promise()})).fail(),transitionPromise.then((function(){foldDayEvents()})).always(pending.resolve).fail(),transitionPromise.resolve()}))};_exports.registerEventListenersForMonthDetailed=registerEventListenersForMonthDetailed;const refreshMonthContent=function(root,year,month,courseId,categoryId){let target=arguments.length>5&&void 0!==arguments[5]?arguments[5]:null,template=arguments.length>6&&void 0!==arguments[6]?arguments[6]:"",day=arguments.length>7&&void 0!==arguments[7]?arguments[7]:1;startLoading(root),target=target||root.find(CalendarSelectors.wrapper),template=template||root.attr("data-template"),M.util.js_pending([root.get("id"),year,month,courseId].join("-"));const includenavigation=root.data("includenavigation"),mini=root.data("mini"),viewMode=target.data("view");return CalendarRepository.getCalendarMonthData(year,month,courseId,categoryId,includenavigation,mini,day,viewMode).then((context=>_templates.default.render(template,context))).then(((html,js)=>_templates.default.replaceNode(target,html,js))).then((()=>{document.querySelector("body").dispatchEvent(new CustomEvent(_events.default.viewUpdated))})).always((()=>(M.util.js_complete([root.get("id"),year,month,courseId].join("-")),stopLoading(root)))).fail(_notification.default.exception)};_exports.refreshMonthContent=refreshMonthContent;const changeMonth=function(root,url,year,month,courseId,categoryId){let day=arguments.length>6&&void 0!==arguments[6]?arguments[6]:1;return refreshMonthContent(root,year,month,courseId,categoryId,null,"",day).then((function(){url.length&&"#"!==url&&updateUrl(url);for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++)args[_key]=arguments[_key];return args})).then((function(){(0,_jquery.default)("body").trigger(_events.default.monthChanged,[year,month,courseId,categoryId]);for(var _len2=arguments.length,args=new Array(_len2),_key2=0;_key2<_len2;_key2++)args[_key2]=arguments[_key2];return args}))};_exports.changeMonth=changeMonth;_exports.reloadCurrentMonth=function(root){let courseId=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,categoryId=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;const year=root.find(CalendarSelectors.wrapper).data("year"),month=root.find(CalendarSelectors.wrapper).data("month"),day=root.find(CalendarSelectors.wrapper).data("day");return courseId=courseId||root.find(CalendarSelectors.wrapper).data("courseid"),categoryId=categoryId||root.find(CalendarSelectors.wrapper).data("categoryid"),refreshMonthContent(root,year,month,courseId,categoryId,null,"",day).then((function(){(0,_jquery.default)("body").trigger(_events.default.courseChanged,[year,month,courseId,categoryId]);for(var _len3=arguments.length,args=new Array(_len3),_key3=0;_key3<_len3;_key3++)args[_key3]=arguments[_key3];return args}))};const refreshDayContent=function(root,year,month,day,courseId,categoryId){let target=arguments.length>6&&void 0!==arguments[6]?arguments[6]:null,template=arguments.length>7&&void 0!==arguments[7]?arguments[7]:"";startLoading(root),target&&0!=target.length||(target=root.find(CalendarSelectors.wrapper)),template=template||root.attr("data-template"),M.util.js_pending([root.get("id"),year,month,day,courseId,categoryId].join("-"));const includenavigation=root.data("includenavigation");return CalendarRepository.getCalendarDayData(year,month,day,courseId,categoryId,includenavigation).then((context=>(context.viewingday=!0,context.showviewselector=!0,_templates.default.render(template,context)))).then(((html,js)=>_templates.default.replaceNode(target,html,js))).then((()=>{document.querySelector("body").dispatchEvent(new CustomEvent(_events.default.viewUpdated))})).always((()=>(M.util.js_complete([root.get("id"),year,month,day,courseId,categoryId].join("-")),stopLoading(root)))).fail(_notification.default.exception)};_exports.refreshDayContent=refreshDayContent;_exports.reloadCurrentDay=function(root){let courseId=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,categoryId=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;const wrapper=root.find(CalendarSelectors.wrapper),year=wrapper.data("year"),month=wrapper.data("month"),day=wrapper.data("day");return courseId=courseId||root.find(CalendarSelectors.wrapper).data("courseid"),categoryId=categoryId||root.find(CalendarSelectors.wrapper).data("categoryid"),refreshDayContent(root,year,month,day,courseId,categoryId)};const changeDay=(root,url,year,month,day,courseId,categoryId)=>refreshDayContent(root,year,month,day,courseId,categoryId).then((function(){url.length&&"#"!==url&&updateUrl(url);for(var _len4=arguments.length,args=new Array(_len4),_key4=0;_key4<_len4;_key4++)args[_key4]=arguments[_key4];return args})).then((function(){(0,_jquery.default)("body").trigger(_events.default.dayChanged,[year,month,courseId,categoryId]);for(var _len5=arguments.length,args=new Array(_len5),_key5=0;_key5<_len5;_key5++)args[_key5]=arguments[_key5];return args}));_exports.changeDay=changeDay;const updateUrl=url=>{document.getElementById(CalendarSelectors.fullCalendarView)&&window.history.pushState({},"",url)};_exports.updateUrl=updateUrl;const startLoading=root=>{root.find(CalendarSelectors.containers.loadingIcon).removeClass("hidden")},stopLoading=root=>{root.find(CalendarSelectors.containers.loadingIcon).addClass("hidden")},reloadCurrentUpcoming=function(root){let courseId=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,categoryId=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,target=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,template=arguments.length>4&&void 0!==arguments[4]?arguments[4]:"";return startLoading(root),target=target||root.find(CalendarSelectors.wrapper),template=template||root.attr("data-template"),courseId=courseId||root.find(CalendarSelectors.wrapper).data("courseid"),categoryId=categoryId||root.find(CalendarSelectors.wrapper).data("categoryid"),CalendarRepository.getCalendarUpcomingData(courseId,categoryId).then((context=>(context.viewingupcoming=!0,context.showviewselector=!0,_templates.default.render(template,context)))).then(((html,js)=>_templates.default.replaceNode(target,html,js))).then((()=>{document.querySelector("body").dispatchEvent(new CustomEvent(_events.default.viewUpdated))})).always((function(){return stopLoading(root)})).fail(_notification.default.exception)};_exports.reloadCurrentUpcoming=reloadCurrentUpcoming;const renderEventSummaryModal=eventId=>{const pendingPromise=new _pending.default("core_calendar/view_manager:renderEventSummaryModal");return CalendarRepository.getEventById(eventId).then((getEventResponse=>{if(!getEventResponse.event)throw new Error("Error encountered while trying to fetch calendar event with ID: "+eventId);return getEventResponse.event})).then((eventData=>{const modalParams={title:eventData.name,type:_summary_modal.default.TYPE,body:_templates.default.render("core_calendar/event_summary_body",eventData),templateContext:{canedit:eventData.canedit,candelete:eventData.candelete,headerclasses:(eventType=eventData.normalisedeventtype,"calendar_event_"+eventType),isactionevent:eventData.isactionevent,url:eventData.url,action:eventData.action}};var eventType;return _modal_factory.default.create(modalParams)})).then((modal=>(modal.getRoot().on(_modal_events.default.hidden,(function(){modal.destroy()})),modal.show(),modal))).then((modal=>(pendingPromise.resolve(),modal))).catch(_notification.default.exception)};_exports.init=(root,view)=>{(0,_prefetch.prefetchStrings)("calendar",["moreevents"]),foldDayEvents(),(root=>{(root=(0,_jquery.default)(root)).on("click",CalendarSelectors.links.eventLink,(e=>{const target=e.target;let eventLink=null,eventId=null;const pendingPromise=new _pending.default("core_calendar/view_manager:eventLink:click");eventLink=target.matches(CalendarSelectors.actions.viewEvent)?target:target.closest(CalendarSelectors.actions.viewEvent),eventId=eventLink?eventLink.dataset.eventId:target.querySelector(CalendarSelectors.actions.viewEvent).dataset.eventId,eventId?(e.preventDefault(),e.stopPropagation(),renderEventSummaryModal(eventId).then(pendingPromise.resolve).catch()):pendingPromise.resolve()})),root.on("click",CalendarSelectors.links.navLink,(e=>{const wrapper=root.find(CalendarSelectors.wrapper),view=wrapper.data("view"),courseId=wrapper.data("courseid"),categoryId=wrapper.data("categoryid"),link=e.currentTarget;"month"===view||"monthblock"===view?(changeMonth(root,link.href,link.dataset.year,link.dataset.month,courseId,categoryId,link.dataset.day),e.preventDefault()):"day"===view&&(changeDay(root,link.href,link.dataset.year,link.dataset.month,link.dataset.day,courseId,categoryId),e.preventDefault())}));const viewSelector=root.find(CalendarSelectors.viewSelector);_custom_interaction_events.default.define(viewSelector,[_custom_interaction_events.default.events.activate]),viewSelector.on(_custom_interaction_events.default.events.activate,(e=>{e.preventDefault();const option=e.target;if(option.classList.contains("active"))return;const view=option.dataset.view,year=option.dataset.year,month=option.dataset.month,day=option.dataset.day,courseId=option.dataset.courseid,categoryId=option.dataset.categoryid;"month"==view?refreshMonthContent(root,year,month,courseId,categoryId,root,"core_calendar/calendar_month",day).then((()=>{updateUrl("?view=month")})).fail(_notification.default.exception):"day"==view?refreshDayContent(root,year,month,day,courseId,categoryId,root,"core_calendar/calendar_day").then((()=>{updateUrl("?view=day")})).fail(_notification.default.exception):"upcoming"==view&&reloadCurrentUpcoming(root,courseId,categoryId,root,"core_calendar/calendar_upcoming").then((()=>{updateUrl("?view=upcoming")})).fail(_notification.default.exception)}))})(root);const calendarTable=root.find(CalendarSelectors.elements.monthDetailed);if(calendarTable.length){"month-detailed-".concat(calendarTable.id,"-filterChanged");registerEventListenersForMonthDetailed(calendarTable)}}})); + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.updateUrl=_exports.reloadCurrentUpcoming=_exports.reloadCurrentMonth=_exports.reloadCurrentDay=_exports.registerEventListenersForMonthDetailed=_exports.refreshMonthContent=_exports.refreshDayContent=_exports.init=_exports.foldDayEvents=_exports.changeMonth=_exports.changeDay=void 0,_jquery=_interopRequireDefault(_jquery),_templates=_interopRequireDefault(_templates),_notification=_interopRequireDefault(_notification),CalendarRepository=_interopRequireWildcard(CalendarRepository),_events=_interopRequireDefault(_events),CalendarSelectors=_interopRequireWildcard(CalendarSelectors),_modal_events=_interopRequireDefault(_modal_events),_summary_modal=_interopRequireDefault(_summary_modal),_custom_interaction_events=_interopRequireDefault(_custom_interaction_events),_pending=_interopRequireDefault(_pending);const foldDayEvents=()=>{const days=(0,_jquery.default)(CalendarSelectors.elements.monthDetailed).find(CalendarSelectors.day);0!==days.length&&days.each((function(){const dayContainer=(0,_jquery.default)(this),eventsSelector="".concat(CalendarSelectors.elements.dateContent," ul li[data-event-eventtype]"),filteredEventsSelector="".concat(CalendarSelectors.elements.dateContent,' ul li[data-event-filtered="true"]'),moreEventsSelector="".concat(CalendarSelectors.elements.dateContent,' [data-action="view-more-events"]'),events=dayContainer.find(eventsSelector);if(0===events.length)return;const numberOfFiltered=dayContainer.find(filteredEventsSelector).length,numberOfEvents=events.length-numberOfFiltered;let count=1;events.each((function(){const event=(0,_jquery.default)(this);"true"!==event.attr("data-event-filtered")?count>5-(5===numberOfEvents?0:1)?(event.attr("data-event-folded","true"),event.hide()):(event.attr("data-event-folded","false"),event.show(),count++):event.attr("data-event-folded","false")}));const moreEventsLink=dayContainer.find(moreEventsSelector);if(numberOfEvents>5){const numberOfHiddenEvents=numberOfEvents-5+1;moreEventsLink.show(),(0,_str.getString)("moreevents","calendar",numberOfHiddenEvents).then((str=>{const link=moreEventsLink.find("strong a");return moreEventsLink.attr("data-event-folded","false"),link.text(str),str})).fail()}else moreEventsLink.hide()}))};_exports.foldDayEvents=foldDayEvents;const registerEventListenersForMonthDetailed=pendingId=>{const events="".concat(_events.default.viewUpdated);(0,_jquery.default)("body").on(events,(function(e){foldDayEvents()})),foldDayEvents(),(0,_jquery.default)("body").on(_events.default.filterChanged,(function(e,data){const root=(0,_jquery.default)(CalendarSelectors.elements.monthDetailed),pending=new _pending.default(pendingId),target=root.find(CalendarSelectors.eventType[data.type]),transitionPromise=_jquery.default.Deferred();data.hidden?transitionPromise.then((function(){return target.attr("data-event-filtered","true"),target.hide().promise()})).fail():transitionPromise.then((function(){return target.attr("data-event-filtered","false"),target.show().promise()})).fail(),transitionPromise.then((function(){foldDayEvents()})).always(pending.resolve).fail(),transitionPromise.resolve()}))};_exports.registerEventListenersForMonthDetailed=registerEventListenersForMonthDetailed;const refreshMonthContent=function(root,year,month,courseId,categoryId){let target=arguments.length>5&&void 0!==arguments[5]?arguments[5]:null,template=arguments.length>6&&void 0!==arguments[6]?arguments[6]:"",day=arguments.length>7&&void 0!==arguments[7]?arguments[7]:1;startLoading(root),target=target||root.find(CalendarSelectors.wrapper),template=template||root.attr("data-template"),M.util.js_pending([root.get("id"),year,month,courseId].join("-"));const includenavigation=root.data("includenavigation"),mini=root.data("mini"),viewMode=target.data("view");return CalendarRepository.getCalendarMonthData(year,month,courseId,categoryId,includenavigation,mini,day,viewMode).then((context=>_templates.default.render(template,context))).then(((html,js)=>_templates.default.replaceNode(target,html,js))).then((()=>{document.querySelector("body").dispatchEvent(new CustomEvent(_events.default.viewUpdated))})).always((()=>(M.util.js_complete([root.get("id"),year,month,courseId].join("-")),stopLoading(root)))).fail(_notification.default.exception)};_exports.refreshMonthContent=refreshMonthContent;const changeMonth=function(root,url,year,month,courseId,categoryId){let day=arguments.length>6&&void 0!==arguments[6]?arguments[6]:1;return refreshMonthContent(root,year,month,courseId,categoryId,null,"",day).then((function(){url.length&&"#"!==url&&updateUrl(url);for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++)args[_key]=arguments[_key];return args})).then((function(){(0,_jquery.default)("body").trigger(_events.default.monthChanged,[year,month,courseId,categoryId]);for(var _len2=arguments.length,args=new Array(_len2),_key2=0;_key2<_len2;_key2++)args[_key2]=arguments[_key2];return args}))};_exports.changeMonth=changeMonth;_exports.reloadCurrentMonth=function(root){let courseId=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,categoryId=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;const year=root.find(CalendarSelectors.wrapper).data("year"),month=root.find(CalendarSelectors.wrapper).data("month"),day=root.find(CalendarSelectors.wrapper).data("day");return courseId=courseId||root.find(CalendarSelectors.wrapper).data("courseid"),categoryId=categoryId||root.find(CalendarSelectors.wrapper).data("categoryid"),refreshMonthContent(root,year,month,courseId,categoryId,null,"",day).then((function(){(0,_jquery.default)("body").trigger(_events.default.courseChanged,[year,month,courseId,categoryId]);for(var _len3=arguments.length,args=new Array(_len3),_key3=0;_key3<_len3;_key3++)args[_key3]=arguments[_key3];return args}))};const refreshDayContent=function(root,year,month,day,courseId,categoryId){let target=arguments.length>6&&void 0!==arguments[6]?arguments[6]:null,template=arguments.length>7&&void 0!==arguments[7]?arguments[7]:"";startLoading(root),target&&0!=target.length||(target=root.find(CalendarSelectors.wrapper)),template=template||root.attr("data-template"),M.util.js_pending([root.get("id"),year,month,day,courseId,categoryId].join("-"));const includenavigation=root.data("includenavigation");return CalendarRepository.getCalendarDayData(year,month,day,courseId,categoryId,includenavigation).then((context=>(context.viewingday=!0,context.showviewselector=!0,_templates.default.render(template,context)))).then(((html,js)=>_templates.default.replaceNode(target,html,js))).then((()=>{document.querySelector("body").dispatchEvent(new CustomEvent(_events.default.viewUpdated))})).always((()=>(M.util.js_complete([root.get("id"),year,month,day,courseId,categoryId].join("-")),stopLoading(root)))).fail(_notification.default.exception)};_exports.refreshDayContent=refreshDayContent;_exports.reloadCurrentDay=function(root){let courseId=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,categoryId=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;const wrapper=root.find(CalendarSelectors.wrapper),year=wrapper.data("year"),month=wrapper.data("month"),day=wrapper.data("day");return courseId=courseId||root.find(CalendarSelectors.wrapper).data("courseid"),categoryId=categoryId||root.find(CalendarSelectors.wrapper).data("categoryid"),refreshDayContent(root,year,month,day,courseId,categoryId)};const changeDay=(root,url,year,month,day,courseId,categoryId)=>refreshDayContent(root,year,month,day,courseId,categoryId).then((function(){url.length&&"#"!==url&&updateUrl(url);for(var _len4=arguments.length,args=new Array(_len4),_key4=0;_key4<_len4;_key4++)args[_key4]=arguments[_key4];return args})).then((function(){(0,_jquery.default)("body").trigger(_events.default.dayChanged,[year,month,courseId,categoryId]);for(var _len5=arguments.length,args=new Array(_len5),_key5=0;_key5<_len5;_key5++)args[_key5]=arguments[_key5];return args}));_exports.changeDay=changeDay;const updateUrl=url=>{document.getElementById(CalendarSelectors.fullCalendarView)&&window.history.pushState({},"",url)};_exports.updateUrl=updateUrl;const startLoading=root=>{root.find(CalendarSelectors.containers.loadingIcon).removeClass("hidden")},stopLoading=root=>{root.find(CalendarSelectors.containers.loadingIcon).addClass("hidden")},reloadCurrentUpcoming=function(root){let courseId=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,categoryId=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,target=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,template=arguments.length>4&&void 0!==arguments[4]?arguments[4]:"";return startLoading(root),target=target||root.find(CalendarSelectors.wrapper),template=template||root.attr("data-template"),courseId=courseId||root.find(CalendarSelectors.wrapper).data("courseid"),categoryId=categoryId||root.find(CalendarSelectors.wrapper).data("categoryid"),CalendarRepository.getCalendarUpcomingData(courseId,categoryId).then((context=>(context.viewingupcoming=!0,context.showviewselector=!0,_templates.default.render(template,context)))).then(((html,js)=>_templates.default.replaceNode(target,html,js))).then((()=>{document.querySelector("body").dispatchEvent(new CustomEvent(_events.default.viewUpdated))})).always((function(){return stopLoading(root)})).fail(_notification.default.exception)};_exports.reloadCurrentUpcoming=reloadCurrentUpcoming;const renderEventSummaryModal=eventId=>{const pendingPromise=new _pending.default("core_calendar/view_manager:renderEventSummaryModal");return CalendarRepository.getEventById(eventId).then((getEventResponse=>{if(!getEventResponse.event)throw new Error("Error encountered while trying to fetch calendar event with ID: "+eventId);return getEventResponse.event})).then((eventData=>{const modalParams={title:eventData.name,body:_templates.default.render("core_calendar/event_summary_body",eventData),templateContext:{canedit:eventData.canedit,candelete:eventData.candelete,headerclasses:(eventType=eventData.normalisedeventtype,"calendar_event_"+eventType),isactionevent:eventData.isactionevent,url:eventData.url,action:eventData.action}};var eventType;return _summary_modal.default.create(modalParams)})).then((modal=>(modal.getRoot().on(_modal_events.default.hidden,(function(){modal.destroy()})),modal.show(),modal))).then((modal=>(pendingPromise.resolve(),modal))).catch(_notification.default.exception)};_exports.init=(root,view)=>{(0,_prefetch.prefetchStrings)("calendar",["moreevents"]),foldDayEvents(),(root=>{(root=(0,_jquery.default)(root)).on("click",CalendarSelectors.links.eventLink,(e=>{const target=e.target;let eventLink=null,eventId=null;const pendingPromise=new _pending.default("core_calendar/view_manager:eventLink:click");eventLink=target.matches(CalendarSelectors.actions.viewEvent)?target:target.closest(CalendarSelectors.actions.viewEvent),eventId=eventLink?eventLink.dataset.eventId:target.querySelector(CalendarSelectors.actions.viewEvent).dataset.eventId,eventId?(e.preventDefault(),e.stopPropagation(),renderEventSummaryModal(eventId).then(pendingPromise.resolve).catch()):pendingPromise.resolve()})),root.on("click",CalendarSelectors.links.navLink,(e=>{const wrapper=root.find(CalendarSelectors.wrapper),view=wrapper.data("view"),courseId=wrapper.data("courseid"),categoryId=wrapper.data("categoryid"),link=e.currentTarget;"month"===view||"monthblock"===view?(changeMonth(root,link.href,link.dataset.year,link.dataset.month,courseId,categoryId,link.dataset.day),e.preventDefault()):"day"===view&&(changeDay(root,link.href,link.dataset.year,link.dataset.month,link.dataset.day,courseId,categoryId),e.preventDefault())}));const viewSelector=root.find(CalendarSelectors.viewSelector);_custom_interaction_events.default.define(viewSelector,[_custom_interaction_events.default.events.activate]),viewSelector.on(_custom_interaction_events.default.events.activate,(e=>{e.preventDefault();const option=e.target;if(option.classList.contains("active"))return;const view=option.dataset.view,year=option.dataset.year,month=option.dataset.month,day=option.dataset.day,courseId=option.dataset.courseid,categoryId=option.dataset.categoryid;"month"==view?refreshMonthContent(root,year,month,courseId,categoryId,root,"core_calendar/calendar_month",day).then((()=>{updateUrl("?view=month")})).fail(_notification.default.exception):"day"==view?refreshDayContent(root,year,month,day,courseId,categoryId,root,"core_calendar/calendar_day").then((()=>{updateUrl("?view=day")})).fail(_notification.default.exception):"upcoming"==view&&reloadCurrentUpcoming(root,courseId,categoryId,root,"core_calendar/calendar_upcoming").then((()=>{updateUrl("?view=upcoming")})).fail(_notification.default.exception)}))})(root);const calendarTable=root.find(CalendarSelectors.elements.monthDetailed);if(calendarTable.length){"month-detailed-".concat(calendarTable.id,"-filterChanged");registerEventListenersForMonthDetailed(calendarTable)}}})); //# sourceMappingURL=view_manager.min.js.map \ No newline at end of file diff --git a/calendar/amd/build/view_manager.min.js.map b/calendar/amd/build/view_manager.min.js.map index 7dfc4bbe4a2..bd3a11c343e 100644 --- a/calendar/amd/build/view_manager.min.js.map +++ b/calendar/amd/build/view_manager.min.js.map @@ -1 +1 @@ -{"version":3,"file":"view_manager.min.js","sources":["../src/view_manager.js"],"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 * A javascript module to handler calendar view changes.\n *\n * @module core_calendar/view_manager\n * @copyright 2017 Andrew Nicols \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport $ from 'jquery';\nimport Templates from 'core/templates';\nimport Notification from 'core/notification';\nimport * as CalendarRepository from 'core_calendar/repository';\nimport CalendarEvents from 'core_calendar/events';\nimport * as CalendarSelectors from 'core_calendar/selectors';\nimport ModalFactory from 'core/modal_factory';\nimport ModalEvents from 'core/modal_events';\nimport SummaryModal from 'core_calendar/summary_modal';\nimport CustomEvents from 'core/custom_interaction_events';\nimport {getString} from 'core/str';\nimport Pending from 'core/pending';\nimport {prefetchStrings} from 'core/prefetch';\n\n/**\n * Limit number of events per day\n *\n */\nconst LIMIT_DAY_EVENTS = 5;\n\n/**\n * Hide day events if more than 5.\n *\n */\nexport const foldDayEvents = () => {\n const root = $(CalendarSelectors.elements.monthDetailed);\n const days = root.find(CalendarSelectors.day);\n if (days.length === 0) {\n return;\n }\n days.each(function() {\n const dayContainer = $(this);\n const eventsSelector = `${CalendarSelectors.elements.dateContent} ul li[data-event-eventtype]`;\n const filteredEventsSelector = `${CalendarSelectors.elements.dateContent} ul li[data-event-filtered=\"true\"]`;\n const moreEventsSelector = `${CalendarSelectors.elements.dateContent} [data-action=\"view-more-events\"]`;\n const events = dayContainer.find(eventsSelector);\n if (events.length === 0) {\n return;\n }\n\n const filteredEvents = dayContainer.find(filteredEventsSelector);\n const numberOfFiltered = filteredEvents.length;\n const numberOfEvents = events.length - numberOfFiltered;\n\n let count = 1;\n events.each(function() {\n const event = $(this);\n const isNotFiltered = event.attr('data-event-filtered') !== 'true';\n const offset = (numberOfEvents === LIMIT_DAY_EVENTS) ? 0 : 1;\n if (isNotFiltered) {\n if (count > LIMIT_DAY_EVENTS - offset) {\n event.attr('data-event-folded', 'true');\n event.hide();\n } else {\n event.attr('data-event-folded', 'false');\n event.show();\n count++;\n }\n } else {\n // It's being filtered out.\n event.attr('data-event-folded', 'false');\n }\n });\n\n const moreEventsLink = dayContainer.find(moreEventsSelector);\n if (numberOfEvents > LIMIT_DAY_EVENTS) {\n const numberOfHiddenEvents = numberOfEvents - LIMIT_DAY_EVENTS + 1;\n moreEventsLink.show();\n getString('moreevents', 'calendar', numberOfHiddenEvents).then(str => {\n const link = moreEventsLink.find('strong a');\n moreEventsLink.attr('data-event-folded', 'false');\n link.text(str);\n return str;\n }).fail();\n } else {\n moreEventsLink.hide();\n }\n });\n};\n\n/**\n * Register and handle month calendar events.\n *\n * @param {string} pendingId pending id.\n */\nexport const registerEventListenersForMonthDetailed = (pendingId) => {\n const events = `${CalendarEvents.viewUpdated}`;\n $('body').on(events, function(e) {\n foldDayEvents(e);\n });\n foldDayEvents();\n $('body').on(CalendarEvents.filterChanged, function(e, data) {\n const root = $(CalendarSelectors.elements.monthDetailed);\n const pending = new Pending(pendingId);\n const target = root.find(CalendarSelectors.eventType[data.type]);\n const transitionPromise = $.Deferred();\n if (data.hidden) {\n transitionPromise.then(function() {\n target.attr('data-event-filtered', 'true');\n return target.hide().promise();\n }).fail();\n } else {\n transitionPromise.then(function() {\n target.attr('data-event-filtered', 'false');\n return target.show().promise();\n }).fail();\n }\n\n transitionPromise.then(function() {\n foldDayEvents();\n return;\n })\n .always(pending.resolve)\n .fail();\n\n transitionPromise.resolve();\n });\n};\n\n/**\n * Register event listeners for the module.\n *\n * @param {object} root The root element.\n */\nconst registerEventListeners = (root) => {\n root = $(root);\n\n // Bind click events to event links.\n root.on('click', CalendarSelectors.links.eventLink, (e) => {\n const target = e.target;\n let eventLink = null;\n let eventId = null;\n const pendingPromise = new Pending('core_calendar/view_manager:eventLink:click');\n\n if (target.matches(CalendarSelectors.actions.viewEvent)) {\n eventLink = target;\n } else {\n eventLink = target.closest(CalendarSelectors.actions.viewEvent);\n }\n\n if (eventLink) {\n eventId = eventLink.dataset.eventId;\n } else {\n eventId = target.querySelector(CalendarSelectors.actions.viewEvent).dataset.eventId;\n }\n\n if (eventId) {\n // A link was found. Show the modal.\n\n e.preventDefault();\n // We've handled the event so stop it from bubbling\n // and causing the day click handler to fire.\n e.stopPropagation();\n\n renderEventSummaryModal(eventId)\n .then(pendingPromise.resolve)\n .catch();\n } else {\n pendingPromise.resolve();\n }\n });\n\n root.on('click', CalendarSelectors.links.navLink, (e) => {\n const wrapper = root.find(CalendarSelectors.wrapper);\n const view = wrapper.data('view');\n const courseId = wrapper.data('courseid');\n const categoryId = wrapper.data('categoryid');\n const link = e.currentTarget;\n\n if (view === 'month' || view === 'monthblock') {\n changeMonth(root, link.href, link.dataset.year, link.dataset.month, courseId, categoryId, link.dataset.day);\n e.preventDefault();\n } else if (view === 'day') {\n changeDay(root, link.href, link.dataset.year, link.dataset.month, link.dataset.day, courseId, categoryId);\n e.preventDefault();\n }\n });\n\n const viewSelector = root.find(CalendarSelectors.viewSelector);\n CustomEvents.define(viewSelector, [CustomEvents.events.activate]);\n viewSelector.on(\n CustomEvents.events.activate,\n (e) => {\n e.preventDefault();\n\n const option = e.target;\n if (option.classList.contains('active')) {\n return;\n }\n\n const view = option.dataset.view,\n year = option.dataset.year,\n month = option.dataset.month,\n day = option.dataset.day,\n courseId = option.dataset.courseid,\n categoryId = option.dataset.categoryid;\n\n if (view == 'month') {\n refreshMonthContent(root, year, month, courseId, categoryId, root, 'core_calendar/calendar_month', day)\n .then(() => {\n updateUrl('?view=month');\n }).fail(Notification.exception);\n } else if (view == 'day') {\n refreshDayContent(root, year, month, day, courseId, categoryId, root, 'core_calendar/calendar_day')\n .then(() => {\n updateUrl('?view=day');\n }).fail(Notification.exception);\n } else if (view == 'upcoming') {\n reloadCurrentUpcoming(root, courseId, categoryId, root, 'core_calendar/calendar_upcoming')\n .then(() => {\n updateUrl('?view=upcoming');\n }).fail(Notification.exception);\n }\n }\n );\n};\n\n/**\n * Refresh the month content.\n *\n * @param {object} root The root element.\n * @param {number} year Year\n * @param {number} month Month\n * @param {number} courseId The id of the course whose events are shown\n * @param {number} categoryId The id of the category whose events are shown\n * @param {object} target The element being replaced. If not specified, the calendarwrapper is used.\n * @param {string} template The template to be rendered.\n * @param {number} day Day (optional)\n * @return {promise}\n */\nexport const refreshMonthContent = (root, year, month, courseId, categoryId, target = null, template = '', day = 1) => {\n startLoading(root);\n\n target = target || root.find(CalendarSelectors.wrapper);\n template = template || root.attr('data-template');\n M.util.js_pending([root.get('id'), year, month, courseId].join('-'));\n const includenavigation = root.data('includenavigation');\n const mini = root.data('mini');\n const viewMode = target.data('view');\n return CalendarRepository.getCalendarMonthData(year, month, courseId, categoryId, includenavigation, mini, day, viewMode)\n .then(context => {\n return Templates.render(template, context);\n })\n .then((html, js) => {\n return Templates.replaceNode(target, html, js);\n })\n .then(() => {\n document.querySelector('body').dispatchEvent(new CustomEvent(CalendarEvents.viewUpdated));\n return;\n })\n .always(() => {\n M.util.js_complete([root.get('id'), year, month, courseId].join('-'));\n return stopLoading(root);\n })\n .fail(Notification.exception);\n};\n\n/**\n * Handle changes to the current calendar view.\n *\n * @param {object} root The container element\n * @param {string} url The calendar url to be shown\n * @param {number} year Year\n * @param {number} month Month\n * @param {number} courseId The id of the course whose events are shown\n * @param {number} categoryId The id of the category whose events are shown\n * @param {number} day Day (optional)\n * @return {promise}\n */\nexport const changeMonth = (root, url, year, month, courseId, categoryId, day = 1) => {\n return refreshMonthContent(root, year, month, courseId, categoryId, null, '', day)\n .then((...args) => {\n if (url.length && url !== '#') {\n updateUrl(url);\n }\n return args;\n })\n .then((...args) => {\n $('body').trigger(CalendarEvents.monthChanged, [year, month, courseId, categoryId]);\n return args;\n });\n};\n\n/**\n * Reload the current month view data.\n *\n * @param {object} root The container element.\n * @param {number} courseId The course id.\n * @param {number} categoryId The id of the category whose events are shown\n * @return {promise}\n */\nexport const reloadCurrentMonth = (root, courseId = 0, categoryId = 0) => {\n const year = root.find(CalendarSelectors.wrapper).data('year');\n const month = root.find(CalendarSelectors.wrapper).data('month');\n const day = root.find(CalendarSelectors.wrapper).data('day');\n\n courseId = courseId || root.find(CalendarSelectors.wrapper).data('courseid');\n categoryId = categoryId || root.find(CalendarSelectors.wrapper).data('categoryid');\n\n return refreshMonthContent(root, year, month, courseId, categoryId, null, '', day).\n then((...args) => {\n $('body').trigger(CalendarEvents.courseChanged, [year, month, courseId, categoryId]);\n return args;\n });\n};\n\n\n/**\n * Refresh the day content.\n *\n * @param {object} root The root element.\n * @param {number} year Year\n * @param {number} month Month\n * @param {number} day Day\n * @param {number} courseId The id of the course whose events are shown\n * @param {number} categoryId The id of the category whose events are shown\n * @param {object} target The element being replaced. If not specified, the calendarwrapper is used.\n * @param {string} template The template to be rendered.\n *\n * @return {promise}\n */\nexport const refreshDayContent = (root, year, month, day, courseId, categoryId, target = null, template = '') => {\n startLoading(root);\n\n if (!target || target.length == 0){\n target = root.find(CalendarSelectors.wrapper);\n }\n template = template || root.attr('data-template');\n M.util.js_pending([root.get('id'), year, month, day, courseId, categoryId].join('-'));\n const includenavigation = root.data('includenavigation');\n return CalendarRepository.getCalendarDayData(year, month, day, courseId, categoryId, includenavigation)\n .then((context) => {\n context.viewingday = true;\n context.showviewselector = true;\n return Templates.render(template, context);\n })\n .then((html, js) => {\n return Templates.replaceNode(target, html, js);\n })\n .then(() => {\n document.querySelector('body').dispatchEvent(new CustomEvent(CalendarEvents.viewUpdated));\n return;\n })\n .always(() => {\n M.util.js_complete([root.get('id'), year, month, day, courseId, categoryId].join('-'));\n return stopLoading(root);\n })\n .fail(Notification.exception);\n};\n\n/**\n * Reload the current day view data.\n *\n * @param {object} root The container element.\n * @param {number} courseId The course id.\n * @param {number} categoryId The id of the category whose events are shown\n * @return {promise}\n */\nexport const reloadCurrentDay = (root, courseId = 0, categoryId = 0) => {\n const wrapper = root.find(CalendarSelectors.wrapper);\n const year = wrapper.data('year');\n const month = wrapper.data('month');\n const day = wrapper.data('day');\n\n courseId = courseId || root.find(CalendarSelectors.wrapper).data('courseid');\n categoryId = categoryId || root.find(CalendarSelectors.wrapper).data('categoryid');\n\n return refreshDayContent(root, year, month, day, courseId, categoryId);\n};\n\n/**\n * Handle changes to the current calendar view.\n *\n * @param {object} root The root element.\n * @param {String} url The calendar url to be shown\n * @param {Number} year Year\n * @param {Number} month Month\n * @param {Number} day Day\n * @param {Number} courseId The id of the course whose events are shown\n * @param {Number} categoryId The id of the category whose events are shown\n * @return {promise}\n */\nexport const changeDay = (root, url, year, month, day, courseId, categoryId) => {\n return refreshDayContent(root, year, month, day, courseId, categoryId)\n .then((...args) => {\n if (url.length && url !== '#') {\n updateUrl(url);\n }\n return args;\n })\n .then((...args) => {\n $('body').trigger(CalendarEvents.dayChanged, [year, month, courseId, categoryId]);\n return args;\n });\n};\n\n/**\n * Update calendar URL.\n *\n * @param {String} url The calendar url to be updated.\n */\nexport const updateUrl = (url) => {\n const viewingFullCalendar = document.getElementById(CalendarSelectors.fullCalendarView);\n\n // We want to update the url only if the user is viewing the full calendar.\n if (viewingFullCalendar) {\n window.history.pushState({}, '', url);\n }\n};\n\n/**\n * Set the element state to loading.\n *\n * @param {object} root The container element\n * @method startLoading\n */\nconst startLoading = (root) => {\n const loadingIconContainer = root.find(CalendarSelectors.containers.loadingIcon);\n\n loadingIconContainer.removeClass('hidden');\n};\n\n/**\n * Remove the loading state from the element.\n *\n * @param {object} root The container element\n * @method stopLoading\n */\nconst stopLoading = (root) => {\n const loadingIconContainer = root.find(CalendarSelectors.containers.loadingIcon);\n\n loadingIconContainer.addClass('hidden');\n};\n\n/**\n * Reload the current month view data.\n *\n * @param {object} root The container element.\n * @param {number} courseId The course id.\n * @param {number} categoryId The id of the category whose events are shown\n * @param {object} target The element being replaced. If not specified, the calendarwrapper is used.\n * @param {string} template The template to be rendered.\n * @return {promise}\n */\nexport const reloadCurrentUpcoming = (root, courseId = 0, categoryId = 0, target = null, template = '') => {\n startLoading(root);\n\n target = target || root.find(CalendarSelectors.wrapper);\n template = template || root.attr('data-template');\n courseId = courseId || root.find(CalendarSelectors.wrapper).data('courseid');\n categoryId = categoryId || root.find(CalendarSelectors.wrapper).data('categoryid');\n\n return CalendarRepository.getCalendarUpcomingData(courseId, categoryId)\n .then((context) => {\n context.viewingupcoming = true;\n context.showviewselector = true;\n return Templates.render(template, context);\n })\n .then((html, js) => {\n return Templates.replaceNode(target, html, js);\n })\n .then(() => {\n document.querySelector('body').dispatchEvent(new CustomEvent(CalendarEvents.viewUpdated));\n return;\n })\n .always(function() {\n return stopLoading(root);\n })\n .fail(Notification.exception);\n};\n\n/**\n * Get the CSS class to apply for the given event type.\n *\n * @param {string} eventType The calendar event type\n * @return {string}\n */\nconst getEventTypeClassFromType = (eventType) => {\n return 'calendar_event_' + eventType;\n};\n\n/**\n * Render the event summary modal.\n *\n * @param {Number} eventId The calendar event id.\n * @returns {Promise}\n */\nconst renderEventSummaryModal = (eventId) => {\n const pendingPromise = new Pending('core_calendar/view_manager:renderEventSummaryModal');\n\n // Calendar repository promise.\n return CalendarRepository.getEventById(eventId)\n .then((getEventResponse) => {\n if (!getEventResponse.event) {\n throw new Error('Error encountered while trying to fetch calendar event with ID: ' + eventId);\n }\n\n return getEventResponse.event;\n })\n .then(eventData => {\n // Build the modal parameters from the event data.\n const modalParams = {\n title: eventData.name,\n type: SummaryModal.TYPE,\n body: Templates.render('core_calendar/event_summary_body', eventData),\n templateContext: {\n canedit: eventData.canedit,\n candelete: eventData.candelete,\n headerclasses: getEventTypeClassFromType(eventData.normalisedeventtype),\n isactionevent: eventData.isactionevent,\n url: eventData.url,\n action: eventData.action\n }\n };\n\n // Create the modal.\n return ModalFactory.create(modalParams);\n })\n .then(modal => {\n // Handle hidden event.\n modal.getRoot().on(ModalEvents.hidden, function() {\n // Destroy when hidden.\n modal.destroy();\n });\n\n // Finally, render the modal!\n modal.show();\n\n return modal;\n })\n .then(modal => {\n pendingPromise.resolve();\n\n return modal;\n })\n .catch(Notification.exception);\n};\n\nexport const init = (root, view) => {\n prefetchStrings('calendar', ['moreevents']);\n foldDayEvents();\n registerEventListeners(root, view);\n const calendarTable = root.find(CalendarSelectors.elements.monthDetailed);\n if (calendarTable.length) {\n const pendingId = `month-detailed-${calendarTable.id}-filterChanged`;\n registerEventListenersForMonthDetailed(calendarTable, pendingId);\n }\n};\n"],"names":["foldDayEvents","days","CalendarSelectors","elements","monthDetailed","find","day","length","each","dayContainer","this","eventsSelector","dateContent","filteredEventsSelector","moreEventsSelector","events","numberOfFiltered","numberOfEvents","count","event","attr","hide","show","moreEventsLink","numberOfHiddenEvents","then","str","link","text","fail","registerEventListenersForMonthDetailed","pendingId","CalendarEvents","viewUpdated","on","e","filterChanged","data","root","pending","Pending","target","eventType","type","transitionPromise","$","Deferred","hidden","promise","always","resolve","refreshMonthContent","year","month","courseId","categoryId","template","startLoading","wrapper","M","util","js_pending","get","join","includenavigation","mini","viewMode","CalendarRepository","getCalendarMonthData","context","Templates","render","html","js","replaceNode","document","querySelector","dispatchEvent","CustomEvent","js_complete","stopLoading","Notification","exception","changeMonth","url","updateUrl","args","trigger","monthChanged","courseChanged","refreshDayContent","getCalendarDayData","viewingday","showviewselector","changeDay","dayChanged","getElementById","fullCalendarView","window","history","pushState","containers","loadingIcon","removeClass","addClass","reloadCurrentUpcoming","getCalendarUpcomingData","viewingupcoming","renderEventSummaryModal","eventId","pendingPromise","getEventById","getEventResponse","Error","eventData","modalParams","title","name","SummaryModal","TYPE","body","templateContext","canedit","candelete","headerclasses","normalisedeventtype","isactionevent","action","ModalFactory","create","modal","getRoot","ModalEvents","destroy","catch","view","links","eventLink","matches","actions","viewEvent","closest","dataset","preventDefault","stopPropagation","navLink","currentTarget","href","viewSelector","define","CustomEvents","activate","option","classList","contains","courseid","categoryid","registerEventListeners","calendarTable","id"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"view_manager.min.js","sources":["../src/view_manager.js"],"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 * A javascript module to handler calendar view changes.\n *\n * @module core_calendar/view_manager\n * @copyright 2017 Andrew Nicols \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport $ from 'jquery';\nimport Templates from 'core/templates';\nimport Notification from 'core/notification';\nimport * as CalendarRepository from 'core_calendar/repository';\nimport CalendarEvents from 'core_calendar/events';\nimport * as CalendarSelectors from 'core_calendar/selectors';\nimport ModalEvents from 'core/modal_events';\nimport SummaryModal from 'core_calendar/summary_modal';\nimport CustomEvents from 'core/custom_interaction_events';\nimport {getString} from 'core/str';\nimport Pending from 'core/pending';\nimport {prefetchStrings} from 'core/prefetch';\n\n/**\n * Limit number of events per day\n *\n */\nconst LIMIT_DAY_EVENTS = 5;\n\n/**\n * Hide day events if more than 5.\n *\n */\nexport const foldDayEvents = () => {\n const root = $(CalendarSelectors.elements.monthDetailed);\n const days = root.find(CalendarSelectors.day);\n if (days.length === 0) {\n return;\n }\n days.each(function() {\n const dayContainer = $(this);\n const eventsSelector = `${CalendarSelectors.elements.dateContent} ul li[data-event-eventtype]`;\n const filteredEventsSelector = `${CalendarSelectors.elements.dateContent} ul li[data-event-filtered=\"true\"]`;\n const moreEventsSelector = `${CalendarSelectors.elements.dateContent} [data-action=\"view-more-events\"]`;\n const events = dayContainer.find(eventsSelector);\n if (events.length === 0) {\n return;\n }\n\n const filteredEvents = dayContainer.find(filteredEventsSelector);\n const numberOfFiltered = filteredEvents.length;\n const numberOfEvents = events.length - numberOfFiltered;\n\n let count = 1;\n events.each(function() {\n const event = $(this);\n const isNotFiltered = event.attr('data-event-filtered') !== 'true';\n const offset = (numberOfEvents === LIMIT_DAY_EVENTS) ? 0 : 1;\n if (isNotFiltered) {\n if (count > LIMIT_DAY_EVENTS - offset) {\n event.attr('data-event-folded', 'true');\n event.hide();\n } else {\n event.attr('data-event-folded', 'false');\n event.show();\n count++;\n }\n } else {\n // It's being filtered out.\n event.attr('data-event-folded', 'false');\n }\n });\n\n const moreEventsLink = dayContainer.find(moreEventsSelector);\n if (numberOfEvents > LIMIT_DAY_EVENTS) {\n const numberOfHiddenEvents = numberOfEvents - LIMIT_DAY_EVENTS + 1;\n moreEventsLink.show();\n getString('moreevents', 'calendar', numberOfHiddenEvents).then(str => {\n const link = moreEventsLink.find('strong a');\n moreEventsLink.attr('data-event-folded', 'false');\n link.text(str);\n return str;\n }).fail();\n } else {\n moreEventsLink.hide();\n }\n });\n};\n\n/**\n * Register and handle month calendar events.\n *\n * @param {string} pendingId pending id.\n */\nexport const registerEventListenersForMonthDetailed = (pendingId) => {\n const events = `${CalendarEvents.viewUpdated}`;\n $('body').on(events, function(e) {\n foldDayEvents(e);\n });\n foldDayEvents();\n $('body').on(CalendarEvents.filterChanged, function(e, data) {\n const root = $(CalendarSelectors.elements.monthDetailed);\n const pending = new Pending(pendingId);\n const target = root.find(CalendarSelectors.eventType[data.type]);\n const transitionPromise = $.Deferred();\n if (data.hidden) {\n transitionPromise.then(function() {\n target.attr('data-event-filtered', 'true');\n return target.hide().promise();\n }).fail();\n } else {\n transitionPromise.then(function() {\n target.attr('data-event-filtered', 'false');\n return target.show().promise();\n }).fail();\n }\n\n transitionPromise.then(function() {\n foldDayEvents();\n return;\n })\n .always(pending.resolve)\n .fail();\n\n transitionPromise.resolve();\n });\n};\n\n/**\n * Register event listeners for the module.\n *\n * @param {object} root The root element.\n */\nconst registerEventListeners = (root) => {\n root = $(root);\n\n // Bind click events to event links.\n root.on('click', CalendarSelectors.links.eventLink, (e) => {\n const target = e.target;\n let eventLink = null;\n let eventId = null;\n const pendingPromise = new Pending('core_calendar/view_manager:eventLink:click');\n\n if (target.matches(CalendarSelectors.actions.viewEvent)) {\n eventLink = target;\n } else {\n eventLink = target.closest(CalendarSelectors.actions.viewEvent);\n }\n\n if (eventLink) {\n eventId = eventLink.dataset.eventId;\n } else {\n eventId = target.querySelector(CalendarSelectors.actions.viewEvent).dataset.eventId;\n }\n\n if (eventId) {\n // A link was found. Show the modal.\n\n e.preventDefault();\n // We've handled the event so stop it from bubbling\n // and causing the day click handler to fire.\n e.stopPropagation();\n\n renderEventSummaryModal(eventId)\n .then(pendingPromise.resolve)\n .catch();\n } else {\n pendingPromise.resolve();\n }\n });\n\n root.on('click', CalendarSelectors.links.navLink, (e) => {\n const wrapper = root.find(CalendarSelectors.wrapper);\n const view = wrapper.data('view');\n const courseId = wrapper.data('courseid');\n const categoryId = wrapper.data('categoryid');\n const link = e.currentTarget;\n\n if (view === 'month' || view === 'monthblock') {\n changeMonth(root, link.href, link.dataset.year, link.dataset.month, courseId, categoryId, link.dataset.day);\n e.preventDefault();\n } else if (view === 'day') {\n changeDay(root, link.href, link.dataset.year, link.dataset.month, link.dataset.day, courseId, categoryId);\n e.preventDefault();\n }\n });\n\n const viewSelector = root.find(CalendarSelectors.viewSelector);\n CustomEvents.define(viewSelector, [CustomEvents.events.activate]);\n viewSelector.on(\n CustomEvents.events.activate,\n (e) => {\n e.preventDefault();\n\n const option = e.target;\n if (option.classList.contains('active')) {\n return;\n }\n\n const view = option.dataset.view,\n year = option.dataset.year,\n month = option.dataset.month,\n day = option.dataset.day,\n courseId = option.dataset.courseid,\n categoryId = option.dataset.categoryid;\n\n if (view == 'month') {\n refreshMonthContent(root, year, month, courseId, categoryId, root, 'core_calendar/calendar_month', day)\n .then(() => {\n updateUrl('?view=month');\n }).fail(Notification.exception);\n } else if (view == 'day') {\n refreshDayContent(root, year, month, day, courseId, categoryId, root, 'core_calendar/calendar_day')\n .then(() => {\n updateUrl('?view=day');\n }).fail(Notification.exception);\n } else if (view == 'upcoming') {\n reloadCurrentUpcoming(root, courseId, categoryId, root, 'core_calendar/calendar_upcoming')\n .then(() => {\n updateUrl('?view=upcoming');\n }).fail(Notification.exception);\n }\n }\n );\n};\n\n/**\n * Refresh the month content.\n *\n * @param {object} root The root element.\n * @param {number} year Year\n * @param {number} month Month\n * @param {number} courseId The id of the course whose events are shown\n * @param {number} categoryId The id of the category whose events are shown\n * @param {object} target The element being replaced. If not specified, the calendarwrapper is used.\n * @param {string} template The template to be rendered.\n * @param {number} day Day (optional)\n * @return {promise}\n */\nexport const refreshMonthContent = (root, year, month, courseId, categoryId, target = null, template = '', day = 1) => {\n startLoading(root);\n\n target = target || root.find(CalendarSelectors.wrapper);\n template = template || root.attr('data-template');\n M.util.js_pending([root.get('id'), year, month, courseId].join('-'));\n const includenavigation = root.data('includenavigation');\n const mini = root.data('mini');\n const viewMode = target.data('view');\n return CalendarRepository.getCalendarMonthData(year, month, courseId, categoryId, includenavigation, mini, day, viewMode)\n .then(context => {\n return Templates.render(template, context);\n })\n .then((html, js) => {\n return Templates.replaceNode(target, html, js);\n })\n .then(() => {\n document.querySelector('body').dispatchEvent(new CustomEvent(CalendarEvents.viewUpdated));\n return;\n })\n .always(() => {\n M.util.js_complete([root.get('id'), year, month, courseId].join('-'));\n return stopLoading(root);\n })\n .fail(Notification.exception);\n};\n\n/**\n * Handle changes to the current calendar view.\n *\n * @param {object} root The container element\n * @param {string} url The calendar url to be shown\n * @param {number} year Year\n * @param {number} month Month\n * @param {number} courseId The id of the course whose events are shown\n * @param {number} categoryId The id of the category whose events are shown\n * @param {number} day Day (optional)\n * @return {promise}\n */\nexport const changeMonth = (root, url, year, month, courseId, categoryId, day = 1) => {\n return refreshMonthContent(root, year, month, courseId, categoryId, null, '', day)\n .then((...args) => {\n if (url.length && url !== '#') {\n updateUrl(url);\n }\n return args;\n })\n .then((...args) => {\n $('body').trigger(CalendarEvents.monthChanged, [year, month, courseId, categoryId]);\n return args;\n });\n};\n\n/**\n * Reload the current month view data.\n *\n * @param {object} root The container element.\n * @param {number} courseId The course id.\n * @param {number} categoryId The id of the category whose events are shown\n * @return {promise}\n */\nexport const reloadCurrentMonth = (root, courseId = 0, categoryId = 0) => {\n const year = root.find(CalendarSelectors.wrapper).data('year');\n const month = root.find(CalendarSelectors.wrapper).data('month');\n const day = root.find(CalendarSelectors.wrapper).data('day');\n\n courseId = courseId || root.find(CalendarSelectors.wrapper).data('courseid');\n categoryId = categoryId || root.find(CalendarSelectors.wrapper).data('categoryid');\n\n return refreshMonthContent(root, year, month, courseId, categoryId, null, '', day).\n then((...args) => {\n $('body').trigger(CalendarEvents.courseChanged, [year, month, courseId, categoryId]);\n return args;\n });\n};\n\n\n/**\n * Refresh the day content.\n *\n * @param {object} root The root element.\n * @param {number} year Year\n * @param {number} month Month\n * @param {number} day Day\n * @param {number} courseId The id of the course whose events are shown\n * @param {number} categoryId The id of the category whose events are shown\n * @param {object} target The element being replaced. If not specified, the calendarwrapper is used.\n * @param {string} template The template to be rendered.\n *\n * @return {promise}\n */\nexport const refreshDayContent = (root, year, month, day, courseId, categoryId, target = null, template = '') => {\n startLoading(root);\n\n if (!target || target.length == 0){\n target = root.find(CalendarSelectors.wrapper);\n }\n template = template || root.attr('data-template');\n M.util.js_pending([root.get('id'), year, month, day, courseId, categoryId].join('-'));\n const includenavigation = root.data('includenavigation');\n return CalendarRepository.getCalendarDayData(year, month, day, courseId, categoryId, includenavigation)\n .then((context) => {\n context.viewingday = true;\n context.showviewselector = true;\n return Templates.render(template, context);\n })\n .then((html, js) => {\n return Templates.replaceNode(target, html, js);\n })\n .then(() => {\n document.querySelector('body').dispatchEvent(new CustomEvent(CalendarEvents.viewUpdated));\n return;\n })\n .always(() => {\n M.util.js_complete([root.get('id'), year, month, day, courseId, categoryId].join('-'));\n return stopLoading(root);\n })\n .fail(Notification.exception);\n};\n\n/**\n * Reload the current day view data.\n *\n * @param {object} root The container element.\n * @param {number} courseId The course id.\n * @param {number} categoryId The id of the category whose events are shown\n * @return {promise}\n */\nexport const reloadCurrentDay = (root, courseId = 0, categoryId = 0) => {\n const wrapper = root.find(CalendarSelectors.wrapper);\n const year = wrapper.data('year');\n const month = wrapper.data('month');\n const day = wrapper.data('day');\n\n courseId = courseId || root.find(CalendarSelectors.wrapper).data('courseid');\n categoryId = categoryId || root.find(CalendarSelectors.wrapper).data('categoryid');\n\n return refreshDayContent(root, year, month, day, courseId, categoryId);\n};\n\n/**\n * Handle changes to the current calendar view.\n *\n * @param {object} root The root element.\n * @param {String} url The calendar url to be shown\n * @param {Number} year Year\n * @param {Number} month Month\n * @param {Number} day Day\n * @param {Number} courseId The id of the course whose events are shown\n * @param {Number} categoryId The id of the category whose events are shown\n * @return {promise}\n */\nexport const changeDay = (root, url, year, month, day, courseId, categoryId) => {\n return refreshDayContent(root, year, month, day, courseId, categoryId)\n .then((...args) => {\n if (url.length && url !== '#') {\n updateUrl(url);\n }\n return args;\n })\n .then((...args) => {\n $('body').trigger(CalendarEvents.dayChanged, [year, month, courseId, categoryId]);\n return args;\n });\n};\n\n/**\n * Update calendar URL.\n *\n * @param {String} url The calendar url to be updated.\n */\nexport const updateUrl = (url) => {\n const viewingFullCalendar = document.getElementById(CalendarSelectors.fullCalendarView);\n\n // We want to update the url only if the user is viewing the full calendar.\n if (viewingFullCalendar) {\n window.history.pushState({}, '', url);\n }\n};\n\n/**\n * Set the element state to loading.\n *\n * @param {object} root The container element\n * @method startLoading\n */\nconst startLoading = (root) => {\n const loadingIconContainer = root.find(CalendarSelectors.containers.loadingIcon);\n\n loadingIconContainer.removeClass('hidden');\n};\n\n/**\n * Remove the loading state from the element.\n *\n * @param {object} root The container element\n * @method stopLoading\n */\nconst stopLoading = (root) => {\n const loadingIconContainer = root.find(CalendarSelectors.containers.loadingIcon);\n\n loadingIconContainer.addClass('hidden');\n};\n\n/**\n * Reload the current month view data.\n *\n * @param {object} root The container element.\n * @param {number} courseId The course id.\n * @param {number} categoryId The id of the category whose events are shown\n * @param {object} target The element being replaced. If not specified, the calendarwrapper is used.\n * @param {string} template The template to be rendered.\n * @return {promise}\n */\nexport const reloadCurrentUpcoming = (root, courseId = 0, categoryId = 0, target = null, template = '') => {\n startLoading(root);\n\n target = target || root.find(CalendarSelectors.wrapper);\n template = template || root.attr('data-template');\n courseId = courseId || root.find(CalendarSelectors.wrapper).data('courseid');\n categoryId = categoryId || root.find(CalendarSelectors.wrapper).data('categoryid');\n\n return CalendarRepository.getCalendarUpcomingData(courseId, categoryId)\n .then((context) => {\n context.viewingupcoming = true;\n context.showviewselector = true;\n return Templates.render(template, context);\n })\n .then((html, js) => {\n return Templates.replaceNode(target, html, js);\n })\n .then(() => {\n document.querySelector('body').dispatchEvent(new CustomEvent(CalendarEvents.viewUpdated));\n return;\n })\n .always(function() {\n return stopLoading(root);\n })\n .fail(Notification.exception);\n};\n\n/**\n * Get the CSS class to apply for the given event type.\n *\n * @param {string} eventType The calendar event type\n * @return {string}\n */\nconst getEventTypeClassFromType = (eventType) => {\n return 'calendar_event_' + eventType;\n};\n\n/**\n * Render the event summary modal.\n *\n * @param {Number} eventId The calendar event id.\n * @returns {Promise}\n */\nconst renderEventSummaryModal = (eventId) => {\n const pendingPromise = new Pending('core_calendar/view_manager:renderEventSummaryModal');\n\n // Calendar repository promise.\n return CalendarRepository.getEventById(eventId)\n .then((getEventResponse) => {\n if (!getEventResponse.event) {\n throw new Error('Error encountered while trying to fetch calendar event with ID: ' + eventId);\n }\n\n return getEventResponse.event;\n })\n .then(eventData => {\n // Build the modal parameters from the event data.\n const modalParams = {\n title: eventData.name,\n body: Templates.render('core_calendar/event_summary_body', eventData),\n templateContext: {\n canedit: eventData.canedit,\n candelete: eventData.candelete,\n headerclasses: getEventTypeClassFromType(eventData.normalisedeventtype),\n isactionevent: eventData.isactionevent,\n url: eventData.url,\n action: eventData.action\n }\n };\n\n // Create the modal.\n return SummaryModal.create(modalParams);\n })\n .then(modal => {\n // Handle hidden event.\n modal.getRoot().on(ModalEvents.hidden, function() {\n // Destroy when hidden.\n modal.destroy();\n });\n\n // Finally, render the modal!\n modal.show();\n\n return modal;\n })\n .then(modal => {\n pendingPromise.resolve();\n\n return modal;\n })\n .catch(Notification.exception);\n};\n\nexport const init = (root, view) => {\n prefetchStrings('calendar', ['moreevents']);\n foldDayEvents();\n registerEventListeners(root, view);\n const calendarTable = root.find(CalendarSelectors.elements.monthDetailed);\n if (calendarTable.length) {\n const pendingId = `month-detailed-${calendarTable.id}-filterChanged`;\n registerEventListenersForMonthDetailed(calendarTable, pendingId);\n }\n};\n"],"names":["foldDayEvents","days","CalendarSelectors","elements","monthDetailed","find","day","length","each","dayContainer","this","eventsSelector","dateContent","filteredEventsSelector","moreEventsSelector","events","numberOfFiltered","numberOfEvents","count","event","attr","hide","show","moreEventsLink","numberOfHiddenEvents","then","str","link","text","fail","registerEventListenersForMonthDetailed","pendingId","CalendarEvents","viewUpdated","on","e","filterChanged","data","root","pending","Pending","target","eventType","type","transitionPromise","$","Deferred","hidden","promise","always","resolve","refreshMonthContent","year","month","courseId","categoryId","template","startLoading","wrapper","M","util","js_pending","get","join","includenavigation","mini","viewMode","CalendarRepository","getCalendarMonthData","context","Templates","render","html","js","replaceNode","document","querySelector","dispatchEvent","CustomEvent","js_complete","stopLoading","Notification","exception","changeMonth","url","updateUrl","args","trigger","monthChanged","courseChanged","refreshDayContent","getCalendarDayData","viewingday","showviewselector","changeDay","dayChanged","getElementById","fullCalendarView","window","history","pushState","containers","loadingIcon","removeClass","addClass","reloadCurrentUpcoming","getCalendarUpcomingData","viewingupcoming","renderEventSummaryModal","eventId","pendingPromise","getEventById","getEventResponse","Error","eventData","modalParams","title","name","body","templateContext","canedit","candelete","headerclasses","normalisedeventtype","isactionevent","action","SummaryModal","create","modal","getRoot","ModalEvents","destroy","catch","view","links","eventLink","matches","actions","viewEvent","closest","dataset","preventDefault","stopPropagation","navLink","currentTarget","href","viewSelector","define","CustomEvents","activate","option","classList","contains","courseid","categoryid","registerEventListeners","calendarTable","id"],"mappings":"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"} \ No newline at end of file diff --git a/calendar/amd/src/calendar.js b/calendar/amd/src/calendar.js index af23c03efcb..d710d853680 100644 --- a/calendar/amd/src/calendar.js +++ b/calendar/amd/src/calendar.js @@ -118,7 +118,7 @@ function( } return; }) - .fail(Notification.exception); + .catch(Notification.exception); } }; @@ -176,7 +176,7 @@ function( 'core_calendar/calendar_day').then(function() { e.preventDefault(); return CalendarViewManager.updateUrl(url); - }).fail(Notification.exception); + }).catch(Notification.exception); } else { window.location.assign(Config.wwwroot + '/calendar/view.php' + url); } @@ -190,7 +190,7 @@ function( // We need to get the selector again because the content has changed. return root.find(CalendarSelectors.elements.courseSelector).val(courseId); }) - .fail(Notification.exception); + .catch(Notification.exception); }); var eventFormPromise = CalendarCrud.registerEventFormModal(root), @@ -225,7 +225,7 @@ function( modal.setStartTime(startTime); modal.show(); return; - }).fail(Notification.exception); + }).catch(Notification.exception); } } e.preventDefault(); diff --git a/calendar/amd/src/crud.js b/calendar/amd/src/crud.js index d2f77411df7..24dfcdddf2b 100644 --- a/calendar/amd/src/crud.js +++ b/calendar/amd/src/crud.js @@ -24,7 +24,6 @@ define([ 'jquery', 'core/str', 'core/notification', - 'core/modal_factory', 'core/modal_events', 'core_calendar/modal_event_form', 'core_calendar/repository', @@ -32,19 +31,20 @@ define([ 'core_calendar/modal_delete', 'core_calendar/selectors', 'core/pending', + 'core/modal_save_cancel', ], function( $, Str, Notification, - ModalFactory, ModalEvents, ModalEventForm, CalendarRepository, CalendarEvents, - ModalDelete, + CalendarModalDelete, CalendarSelectors, - Pending + Pending, + ModalSaveCancel, ) { /** @@ -77,11 +77,7 @@ function( }, }); - deletePromise = ModalFactory.create( - { - type: ModalDelete.TYPE - } - ); + deletePromise = CalendarModalDelete.create(); } else { deleteStrings.push({ key: 'confirmeventdelete', @@ -90,9 +86,7 @@ function( }); - deletePromise = ModalFactory.create({ - type: ModalFactory.types.SAVE_CANCEL, - }); + deletePromise = ModalSaveCancel.create(); } var stringsPromise = Str.get_strings(deleteStrings); @@ -151,10 +145,7 @@ function( * @return {object} The create modal promise */ var registerEventFormModal = function(root) { - var eventFormPromise = ModalFactory.create({ - type: ModalEventForm.TYPE, - large: true - }); + var eventFormPromise = ModalEventForm.create(); // Bind click event on the new event button. root.on('click', CalendarSelectors.actions.create, function(e) { diff --git a/calendar/amd/src/manage_subscriptions.js b/calendar/amd/src/manage_subscriptions.js index 674c3023e81..3d5f0ba4f7a 100644 --- a/calendar/amd/src/manage_subscriptions.js +++ b/calendar/amd/src/manage_subscriptions.js @@ -24,7 +24,7 @@ import * as CalendarSelectors from 'core_calendar/selectors'; import * as CalendarRepository from 'core_calendar/repository'; -import * as Modal from 'core/modal_factory'; +import ModalSaveCancel from 'core/modal_save_cancel'; import * as ModalEvents from 'core/modal_events'; import {exception as displayException, addNotification, fetchNotifications} from 'core/notification'; import Prefetch from 'core/prefetch'; @@ -70,8 +70,7 @@ const getSubscriptionRow = subscriptionId => { */ const createModal = (element, messageCode) => { const subscriptionName = getSubscriptionName(element); - return Modal.create({ - type: Modal.types.SAVE_CANCEL, + return ModalSaveCancel.create({ title: getString('confirmation', 'admin'), body: getString(messageCode, 'calendar', subscriptionName), buttons: { diff --git a/calendar/amd/src/modal_event_form.js b/calendar/amd/src/modal_event_form.js index c7e6f2a56bd..dc4b0599424 100644 --- a/calendar/amd/src/modal_event_form.js +++ b/calendar/amd/src/modal_event_form.js @@ -58,6 +58,11 @@ export default class ModalEventForm extends Modal { this.saveButton = this.getFooter().find(SELECTORS.SAVE_BUTTON); } + configure(modalConfig) { + modalConfig.large = true; + super.configure(modalConfig); + } + /** * Set the context id to the given value. * diff --git a/calendar/amd/src/view_manager.js b/calendar/amd/src/view_manager.js index a8ce1ea6e63..3d36a55cb5d 100644 --- a/calendar/amd/src/view_manager.js +++ b/calendar/amd/src/view_manager.js @@ -27,7 +27,6 @@ import Notification from 'core/notification'; import * as CalendarRepository from 'core_calendar/repository'; import CalendarEvents from 'core_calendar/events'; import * as CalendarSelectors from 'core_calendar/selectors'; -import ModalFactory from 'core/modal_factory'; import ModalEvents from 'core/modal_events'; import SummaryModal from 'core_calendar/summary_modal'; import CustomEvents from 'core/custom_interaction_events'; @@ -524,7 +523,6 @@ const renderEventSummaryModal = (eventId) => { // Build the modal parameters from the event data. const modalParams = { title: eventData.name, - type: SummaryModal.TYPE, body: Templates.render('core_calendar/event_summary_body', eventData), templateContext: { canedit: eventData.canedit, @@ -537,7 +535,7 @@ const renderEventSummaryModal = (eventId) => { }; // Create the modal. - return ModalFactory.create(modalParams); + return SummaryModal.create(modalParams); }) .then(modal => { // Handle hidden event. diff --git a/contentbank/amd/build/actions.min.js b/contentbank/amd/build/actions.min.js index 1d2b4707306..2296b18df5d 100644 --- a/contentbank/amd/build/actions.min.js +++ b/contentbank/amd/build/actions.min.js @@ -5,6 +5,6 @@ * @copyright 2020 Sara Arjona * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -define("core_contentbank/actions",["jquery","core/ajax","core/notification","core/str","core/templates","core/url","core/modal_factory","core/modal_events"],(function($,Ajax,Notification,Str,Templates,Url,ModalFactory,ModalEvents){var ACTIONS_DELETE_CONTENT='[data-action="deletecontent"]',ACTIONS_RENAME_CONTENT='[data-action="renamecontent"]',ACTIONS_SET_CONTENT_VISIBILITY='[data-action="setcontentvisibility"]',ACTIONS_COPY_CONTENT='[data-action="copycontent"]',Actions=function(){this.registerEvents()};return Actions.prototype.registerEvents=function(){$(ACTIONS_DELETE_CONTENT).click((function(e){e.preventDefault();var contentname=$(this).data("contentname"),contentuses=$(this).data("uses"),contentid=$(this).data("contentid"),contextid=$(this).data("contextid"),strings=[{key:"deletecontent",component:"core_contentbank"},{key:"deletecontentconfirm",component:"core_contentbank",param:{name:contentname}},{key:"deletecontentconfirmlinked",component:"core_contentbank"},{key:"delete",component:"core"}],deleteButtonText="";Str.get_strings(strings).then((function(langStrings){var modalTitle=langStrings[0],modalContent=langStrings[1];return contentuses>0&&(modalContent+=" "+langStrings[2]),deleteButtonText=langStrings[3],ModalFactory.create({title:modalTitle,body:modalContent,type:ModalFactory.types.SAVE_CANCEL,large:!0})})).done((function(modal){modal.setSaveButtonText(deleteButtonText),modal.getRoot().on(ModalEvents.save,(function(){return function(contentid,contextid){var request={methodname:"core_contentbank_delete_content",args:{contentids:{contentid:contentid}}},requestType="success";Ajax.call([request])[0].then((function(data){return data.result?"contentdeleted":(requestType="error","contentnotdeleted")})).done((function(message){var params={contextid:contextid};"success"==requestType?params.statusmsg=message:params.errormsg=message,window.location.href=Url.relativeUrl("contentbank/index.php",params,!1)})).fail(Notification.exception)}(contentid,contextid)})),modal.getRoot().on(ModalEvents.hidden,(function(){modal.destroy()})),modal.show()})).catch(Notification.exception)})),$(ACTIONS_RENAME_CONTENT).click((function(e){e.preventDefault();var contentname=$(this).data("contentname"),contentid=$(this).data("contentid"),saveButtonText="";Str.get_strings([{key:"renamecontent",component:"core_contentbank"},{key:"rename",component:"core_contentbank"}]).then((function(langStrings){var modalTitle=langStrings[0];return saveButtonText=langStrings[1],ModalFactory.create({title:modalTitle,body:Templates.render("core_contentbank/renamecontent",{contentid:contentid,name:contentname}),type:ModalFactory.types.SAVE_CANCEL})})).then((function(modal){modal.setSaveButtonText(saveButtonText),modal.getRoot().on(ModalEvents.save,(function(e){var newname=$("#newname").val().trim();if(newname)!function(contentid,name){var request={methodname:"core_contentbank_rename_content",args:{contentid:contentid,name:name}},requestType="success";Ajax.call([request])[0].then((function(data){return data.result?"contentrenamed":(requestType="error",data.warnings[0].message)})).then((function(message){var params=null;"success"==requestType?(params={id:contentid,statusmsg:message},window.location.href=Url.relativeUrl("contentbank/view.php",params,!1)):(Notification.addNotification({message:message,type:"error"}),Notification.fetchNotifications())})).catch(Notification.exception)}(contentid,newname);else{Str.get_strings([{key:"error"},{key:"emptynamenotallowed",component:"core_contentbank"}]).then((function(langStrings){Notification.alert(langStrings[0],langStrings[1])})).catch(Notification.exception),e.preventDefault()}})),modal.getRoot().on(ModalEvents.hidden,(function(){modal.destroy()})),modal.show()})).catch(Notification.exception)})),$(ACTIONS_COPY_CONTENT).click((function(e){e.preventDefault();var contentname=$(this).data("contentname"),contentid=$(this).data("contentid");let errorTitle,errorMessage;Str.get_strings([{key:"copycontent",component:"core_contentbank"},{key:"error"},{key:"emptynamenotallowed",component:"core_contentbank"}]).then((function(langStrings){var modalTitle=langStrings[0];return errorTitle=langStrings[1],errorMessage=langStrings[2],ModalFactory.create({title:modalTitle,body:Templates.render("core_contentbank/copycontent",{contentid:contentid,name:contentname}),type:ModalFactory.types.SAVE_CANCEL})})).then((function(modal){modal.getRoot().on(ModalEvents.save,(function(){var newname=$("#newname").val().trim();if(!newname)return Notification.alert(errorTitle,errorMessage),!1;!function(contentid,name){var request={methodname:"core_contentbank_copy_content",args:{contentid:contentid,name:name}};Ajax.call([request])[0].then((function(data){if(0==data.id)return Notification.addNotification({message:data.warnings[0].message,type:"error"}),Notification.fetchNotifications(),data.warnings[0].message;{let params={id:data.id,statusmsg:"contentcopied"};window.location.href=Url.relativeUrl("contentbank/view.php",params,!1)}return""})).catch(Notification.exception)}(contentid,newname)})),modal.getRoot().on(ModalEvents.hidden,(function(){modal.destroy()})),modal.show()})).catch(Notification.exception)})),$(ACTIONS_SET_CONTENT_VISIBILITY).click((function(e){e.preventDefault(),function(contentid,visibility){var request={methodname:"core_contentbank_set_content_visibility",args:{contentid:contentid,visibility:visibility}},requestType="success";Ajax.call([request])[0].then((function(data){return data.result?"contentvisibilitychanged":(requestType="error",data.warnings[0].message)})).then((function(message){var params=null;"success"==requestType?(params={id:contentid,statusmsg:message},window.location.href=Url.relativeUrl("contentbank/view.php",params,!1)):(Notification.addNotification({message:message,type:"error"}),Notification.fetchNotifications())})).catch(Notification.exception)}($(this).data("contentid"),$(this).data("visibility"))}))},{init:function(){return new Actions}}})); +define("core_contentbank/actions",["jquery","core/ajax","core/notification","core/str","core/templates","core/url","core/modal_save_cancel","core/modal_events"],(function($,Ajax,Notification,Str,Templates,Url,ModalSaveCancel,ModalEvents){var ACTIONS_DELETE_CONTENT='[data-action="deletecontent"]',ACTIONS_RENAME_CONTENT='[data-action="renamecontent"]',ACTIONS_SET_CONTENT_VISIBILITY='[data-action="setcontentvisibility"]',ACTIONS_COPY_CONTENT='[data-action="copycontent"]',Actions=function(){this.registerEvents()};return Actions.prototype.registerEvents=function(){$(ACTIONS_DELETE_CONTENT).click((function(e){e.preventDefault();var contentname=$(this).data("contentname"),contentuses=$(this).data("uses"),contentid=$(this).data("contentid"),contextid=$(this).data("contextid"),strings=[{key:"deletecontent",component:"core_contentbank"},{key:"deletecontentconfirm",component:"core_contentbank",param:{name:contentname}},{key:"deletecontentconfirmlinked",component:"core_contentbank"},{key:"delete",component:"core"}],deleteButtonText="";Str.get_strings(strings).then((function(langStrings){var modalTitle=langStrings[0],modalContent=langStrings[1];return contentuses>0&&(modalContent+=" "+langStrings[2]),deleteButtonText=langStrings[3],ModalSaveCancel.create({title:modalTitle,body:modalContent,large:!0,removeOnClose:!0,show:!0,buttons:{save:deleteButtonText}})})).then((function(modal){modal.getRoot().on(ModalEvents.save,(function(){return function(contentid,contextid){var request={methodname:"core_contentbank_delete_content",args:{contentids:{contentid:contentid}}},requestType="success";Ajax.call([request])[0].then((function(data){return data.result?"contentdeleted":(requestType="error","contentnotdeleted")})).done((function(message){var params={contextid:contextid};"success"==requestType?params.statusmsg=message:params.errormsg=message,window.location.href=Url.relativeUrl("contentbank/index.php",params,!1)})).fail(Notification.exception)}(contentid,contextid)}))})).catch(Notification.exception)})),$(ACTIONS_RENAME_CONTENT).click((function(e){e.preventDefault();var contentname=$(this).data("contentname"),contentid=$(this).data("contentid"),saveButtonText="";Str.get_strings([{key:"renamecontent",component:"core_contentbank"},{key:"rename",component:"core_contentbank"}]).then((function(langStrings){var modalTitle=langStrings[0];return saveButtonText=langStrings[1],ModalSaveCancel.create({title:modalTitle,body:Templates.render("core_contentbank/renamecontent",{contentid:contentid,name:contentname}),removeOnClose:!0,show:!0,buttons:{save:saveButtonText}})})).then((function(modal){modal.getRoot().on(ModalEvents.save,(function(e){var newname=$("#newname").val().trim();if(newname)!function(contentid,name){var request={methodname:"core_contentbank_rename_content",args:{contentid:contentid,name:name}},requestType="success";Ajax.call([request])[0].then((function(data){return data.result?"contentrenamed":(requestType="error",data.warnings[0].message)})).then((function(message){var params=null;"success"==requestType?(params={id:contentid,statusmsg:message},window.location.href=Url.relativeUrl("contentbank/view.php",params,!1)):(Notification.addNotification({message:message,type:"error"}),Notification.fetchNotifications())})).catch(Notification.exception)}(contentid,newname);else{Str.get_strings([{key:"error"},{key:"emptynamenotallowed",component:"core_contentbank"}]).then((function(langStrings){Notification.alert(langStrings[0],langStrings[1])})).catch(Notification.exception),e.preventDefault()}}))})).catch(Notification.exception)})),$(ACTIONS_COPY_CONTENT).click((function(e){e.preventDefault();var contentname=$(this).data("contentname"),contentid=$(this).data("contentid");let errorTitle,errorMessage;Str.get_strings([{key:"copycontent",component:"core_contentbank"},{key:"error"},{key:"emptynamenotallowed",component:"core_contentbank"}]).then((function(langStrings){var modalTitle=langStrings[0];return errorTitle=langStrings[1],errorMessage=langStrings[2],ModalSaveCancel.create({title:modalTitle,body:Templates.render("core_contentbank/copycontent",{contentid:contentid,name:contentname}),removeOnClose:!0,show:!0})})).then((function(modal){modal.getRoot().on(ModalEvents.save,(function(){var newname=$("#newname").val().trim();if(!newname)return Notification.alert(errorTitle,errorMessage),!1;!function(contentid,name){var request={methodname:"core_contentbank_copy_content",args:{contentid:contentid,name:name}};Ajax.call([request])[0].then((function(data){if(0==data.id)return Notification.addNotification({message:data.warnings[0].message,type:"error"}),Notification.fetchNotifications(),data.warnings[0].message;{let params={id:data.id,statusmsg:"contentcopied"};window.location.href=Url.relativeUrl("contentbank/view.php",params,!1)}return""})).catch(Notification.exception)}(contentid,newname)}))})).catch(Notification.exception)})),$(ACTIONS_SET_CONTENT_VISIBILITY).click((function(e){e.preventDefault(),function(contentid,visibility){var request={methodname:"core_contentbank_set_content_visibility",args:{contentid:contentid,visibility:visibility}},requestType="success";Ajax.call([request])[0].then((function(data){return data.result?"contentvisibilitychanged":(requestType="error",data.warnings[0].message)})).then((function(message){var params=null;"success"==requestType?(params={id:contentid,statusmsg:message},window.location.href=Url.relativeUrl("contentbank/view.php",params,!1)):(Notification.addNotification({message:message,type:"error"}),Notification.fetchNotifications())})).catch(Notification.exception)}($(this).data("contentid"),$(this).data("visibility"))}))},{init:function(){return new Actions}}})); //# sourceMappingURL=actions.min.js.map \ No newline at end of file diff --git a/contentbank/amd/build/actions.min.js.map b/contentbank/amd/build/actions.min.js.map index 8c862cc79b1..aa29e9d40a1 100644 --- a/contentbank/amd/build/actions.min.js.map +++ b/contentbank/amd/build/actions.min.js.map @@ -1 +1 @@ -{"version":3,"file":"actions.min.js","sources":["../src/actions.js"],"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 * Module to manage content bank actions, such as delete or rename.\n *\n * @module core_contentbank/actions\n * @copyright 2020 Sara Arjona \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n 'jquery',\n 'core/ajax',\n 'core/notification',\n 'core/str',\n 'core/templates',\n 'core/url',\n 'core/modal_factory',\n 'core/modal_events'],\nfunction($, Ajax, Notification, Str, Templates, Url, ModalFactory, ModalEvents) {\n\n /**\n * List of action selectors.\n *\n * @type {{DELETE_CONTENT: string}}\n */\n var ACTIONS = {\n DELETE_CONTENT: '[data-action=\"deletecontent\"]',\n RENAME_CONTENT: '[data-action=\"renamecontent\"]',\n SET_CONTENT_VISIBILITY: '[data-action=\"setcontentvisibility\"]',\n COPY_CONTENT: '[data-action=\"copycontent\"]',\n };\n\n /**\n * Actions class.\n */\n var Actions = function() {\n this.registerEvents();\n };\n\n /**\n * Register event listeners.\n */\n Actions.prototype.registerEvents = function() {\n $(ACTIONS.DELETE_CONTENT).click(function(e) {\n e.preventDefault();\n\n var contentname = $(this).data('contentname');\n var contentuses = $(this).data('uses');\n var contentid = $(this).data('contentid');\n var contextid = $(this).data('contextid');\n\n var strings = [\n {\n key: 'deletecontent',\n component: 'core_contentbank'\n },\n {\n key: 'deletecontentconfirm',\n component: 'core_contentbank',\n param: {\n name: contentname,\n }\n },\n {\n key: 'deletecontentconfirmlinked',\n component: 'core_contentbank',\n },\n {\n key: 'delete',\n component: 'core'\n },\n ];\n\n var deleteButtonText = '';\n Str.get_strings(strings).then(function(langStrings) {\n var modalTitle = langStrings[0];\n var modalContent = langStrings[1];\n if (contentuses > 0) {\n modalContent += ' ' + langStrings[2];\n }\n deleteButtonText = langStrings[3];\n\n return ModalFactory.create({\n title: modalTitle,\n body: modalContent,\n type: ModalFactory.types.SAVE_CANCEL,\n large: true\n });\n }).done(function(modal) {\n modal.setSaveButtonText(deleteButtonText);\n modal.getRoot().on(ModalEvents.save, function() {\n // The action is now confirmed, sending an action for it.\n return deleteContent(contentid, contextid);\n });\n\n // Handle hidden event.\n modal.getRoot().on(ModalEvents.hidden, function() {\n // Destroy when hidden.\n modal.destroy();\n });\n\n // Show the modal.\n modal.show();\n\n return;\n }).catch(Notification.exception);\n });\n\n $(ACTIONS.RENAME_CONTENT).click(function(e) {\n e.preventDefault();\n\n var contentname = $(this).data('contentname');\n var contentid = $(this).data('contentid');\n\n var strings = [\n {\n key: 'renamecontent',\n component: 'core_contentbank'\n },\n {\n key: 'rename',\n component: 'core_contentbank'\n },\n ];\n\n var saveButtonText = '';\n Str.get_strings(strings).then(function(langStrings) {\n var modalTitle = langStrings[0];\n saveButtonText = langStrings[1];\n\n return ModalFactory.create({\n title: modalTitle,\n body: Templates.render('core_contentbank/renamecontent', {'contentid': contentid, 'name': contentname}),\n type: ModalFactory.types.SAVE_CANCEL\n });\n }).then(function(modal) {\n modal.setSaveButtonText(saveButtonText);\n modal.getRoot().on(ModalEvents.save, function(e) {\n // The action is now confirmed, sending an action for it.\n var newname = $(\"#newname\").val().trim();\n if (newname) {\n renameContent(contentid, newname);\n } else {\n var errorStrings = [\n {\n key: 'error',\n },\n {\n key: 'emptynamenotallowed',\n component: 'core_contentbank',\n },\n ];\n Str.get_strings(errorStrings).then(function(langStrings) {\n Notification.alert(langStrings[0], langStrings[1]);\n }).catch(Notification.exception);\n e.preventDefault();\n }\n });\n\n // Handle hidden event.\n modal.getRoot().on(ModalEvents.hidden, function() {\n // Destroy when hidden.\n modal.destroy();\n });\n\n // Show the modal.\n modal.show();\n\n return;\n }).catch(Notification.exception);\n });\n\n $(ACTIONS.COPY_CONTENT).click(function(e) {\n e.preventDefault();\n\n var contentname = $(this).data('contentname');\n var contentid = $(this).data('contentid');\n\n var strings = [\n {\n key: 'copycontent',\n component: 'core_contentbank'\n },\n {\n key: 'error',\n },\n {\n key: 'emptynamenotallowed',\n component: 'core_contentbank',\n },\n ];\n\n let errorTitle, errorMessage;\n Str.get_strings(strings).then(function(langStrings) {\n var modalTitle = langStrings[0];\n errorTitle = langStrings[1];\n errorMessage = langStrings[2];\n\n return ModalFactory.create({\n title: modalTitle,\n body: Templates.render('core_contentbank/copycontent', {'contentid': contentid, 'name': contentname}),\n type: ModalFactory.types.SAVE_CANCEL\n });\n }).then(function(modal) {\n modal.getRoot().on(ModalEvents.save, function() {\n // The action is now confirmed, sending an action for it.\n var newname = $(\"#newname\").val().trim();\n if (newname) {\n copyContent(contentid, newname);\n } else {\n Notification.alert(errorTitle, errorMessage);\n return false;\n }\n });\n\n // Handle hidden event.\n modal.getRoot().on(ModalEvents.hidden, function() {\n // Destroy when hidden.\n modal.destroy();\n });\n\n // Show the modal.\n modal.show();\n }).catch(Notification.exception);\n });\n\n $(ACTIONS.SET_CONTENT_VISIBILITY).click(function(e) {\n e.preventDefault();\n\n var contentid = $(this).data('contentid');\n var visibility = $(this).data('visibility');\n\n setContentVisibility(contentid, visibility);\n });\n };\n\n /**\n * Delete content from the content bank.\n *\n * @param {int} contentid The content to delete.\n * @param {int} contextid The contextid where the content belongs.\n */\n function deleteContent(contentid, contextid) {\n var request = {\n methodname: 'core_contentbank_delete_content',\n args: {\n contentids: {contentid}\n }\n };\n\n var requestType = 'success';\n Ajax.call([request])[0].then(function(data) {\n if (data.result) {\n return 'contentdeleted';\n }\n requestType = 'error';\n return 'contentnotdeleted';\n\n }).done(function(message) {\n var params = {\n contextid: contextid\n };\n if (requestType == 'success') {\n params.statusmsg = message;\n } else {\n params.errormsg = message;\n }\n // Redirect to the main content bank page and display the message as a notification.\n window.location.href = Url.relativeUrl('contentbank/index.php', params, false);\n }).fail(Notification.exception);\n }\n\n /**\n * Rename content in the content bank.\n *\n * @param {int} contentid The content to rename.\n * @param {string} name The new name for the content.\n */\n function renameContent(contentid, name) {\n var request = {\n methodname: 'core_contentbank_rename_content',\n args: {\n contentid: contentid,\n name: name\n }\n };\n var requestType = 'success';\n Ajax.call([request])[0].then(function(data) {\n if (data.result) {\n return 'contentrenamed';\n }\n requestType = 'error';\n return data.warnings[0].message;\n\n }).then(function(message) {\n var params = null;\n if (requestType == 'success') {\n params = {\n id: contentid,\n statusmsg: message\n };\n // Redirect to the content view page and display the message as a notification.\n window.location.href = Url.relativeUrl('contentbank/view.php', params, false);\n } else {\n // Fetch error notifications.\n Notification.addNotification({\n message: message,\n type: 'error'\n });\n Notification.fetchNotifications();\n }\n return;\n }).catch(Notification.exception);\n }\n\n /**\n * Copy content in the content bank.\n *\n * @param {int} contentid The content to copy.\n * @param {string} name The name for the new content.\n */\n function copyContent(contentid, name) {\n var request = {\n methodname: 'core_contentbank_copy_content',\n args: {\n contentid: contentid,\n name: name\n }\n };\n Ajax.call([request])[0].then(function(data) {\n if (data.id == 0) {\n // Fetch error notifications.\n Notification.addNotification({\n message: data.warnings[0].message,\n type: 'error'\n });\n Notification.fetchNotifications();\n return data.warnings[0].message;\n } else {\n let params = {\n id: data.id,\n statusmsg: 'contentcopied'\n };\n // Redirect to the content view page and display the message as a notification.\n window.location.href = Url.relativeUrl('contentbank/view.php', params, false);\n }\n return '';\n }).catch(Notification.exception);\n }\n\n /**\n * Set content visibility in the content bank.\n *\n * @param {int} contentid The content to modify\n * @param {int} visibility The new visibility value\n */\n function setContentVisibility(contentid, visibility) {\n var request = {\n methodname: 'core_contentbank_set_content_visibility',\n args: {\n contentid: contentid,\n visibility: visibility\n }\n };\n var requestType = 'success';\n Ajax.call([request])[0].then(function(data) {\n if (data.result) {\n return 'contentvisibilitychanged';\n }\n requestType = 'error';\n return data.warnings[0].message;\n\n }).then(function(message) {\n var params = null;\n if (requestType == 'success') {\n params = {\n id: contentid,\n statusmsg: message\n };\n // Redirect to the content view page and display the message as a notification.\n window.location.href = Url.relativeUrl('contentbank/view.php', params, false);\n } else {\n // Fetch error notifications.\n Notification.addNotification({\n message: message,\n type: 'error'\n });\n Notification.fetchNotifications();\n }\n return;\n }).catch(Notification.exception);\n }\n\n return /** @alias module:core_contentbank/actions */ {\n // Public variables and functions.\n\n /**\n * Initialise the contentbank actions.\n *\n * @method init\n * @return {Actions}\n */\n 'init': function() {\n return new Actions();\n }\n };\n});\n"],"names":["define","$","Ajax","Notification","Str","Templates","Url","ModalFactory","ModalEvents","ACTIONS","Actions","registerEvents","prototype","click","e","preventDefault","contentname","this","data","contentuses","contentid","contextid","strings","key","component","param","name","deleteButtonText","get_strings","then","langStrings","modalTitle","modalContent","create","title","body","type","types","SAVE_CANCEL","large","done","modal","setSaveButtonText","getRoot","on","save","request","methodname","args","contentids","requestType","call","result","message","params","statusmsg","errormsg","window","location","href","relativeUrl","fail","exception","deleteContent","hidden","destroy","show","catch","saveButtonText","render","newname","val","trim","warnings","id","addNotification","fetchNotifications","renameContent","alert","errorTitle","errorMessage","copyContent","visibility","setContentVisibility"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"actions.min.js","sources":["../src/actions.js"],"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 * Module to manage content bank actions, such as delete or rename.\n *\n * @module core_contentbank/actions\n * @copyright 2020 Sara Arjona \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n 'jquery',\n 'core/ajax',\n 'core/notification',\n 'core/str',\n 'core/templates',\n 'core/url',\n 'core/modal_save_cancel',\n 'core/modal_events'],\nfunction($, Ajax, Notification, Str, Templates, Url, ModalSaveCancel, ModalEvents) {\n\n /**\n * List of action selectors.\n *\n * @type {{DELETE_CONTENT: string}}\n */\n var ACTIONS = {\n DELETE_CONTENT: '[data-action=\"deletecontent\"]',\n RENAME_CONTENT: '[data-action=\"renamecontent\"]',\n SET_CONTENT_VISIBILITY: '[data-action=\"setcontentvisibility\"]',\n COPY_CONTENT: '[data-action=\"copycontent\"]',\n };\n\n /**\n * Actions class.\n */\n var Actions = function() {\n this.registerEvents();\n };\n\n /**\n * Register event listeners.\n */\n Actions.prototype.registerEvents = function() {\n $(ACTIONS.DELETE_CONTENT).click(function(e) {\n e.preventDefault();\n\n var contentname = $(this).data('contentname');\n var contentuses = $(this).data('uses');\n var contentid = $(this).data('contentid');\n var contextid = $(this).data('contextid');\n\n var strings = [\n {\n key: 'deletecontent',\n component: 'core_contentbank'\n },\n {\n key: 'deletecontentconfirm',\n component: 'core_contentbank',\n param: {\n name: contentname,\n }\n },\n {\n key: 'deletecontentconfirmlinked',\n component: 'core_contentbank',\n },\n {\n key: 'delete',\n component: 'core'\n },\n ];\n\n var deleteButtonText = '';\n Str.get_strings(strings).then(function(langStrings) {\n var modalTitle = langStrings[0];\n var modalContent = langStrings[1];\n if (contentuses > 0) {\n modalContent += ' ' + langStrings[2];\n }\n deleteButtonText = langStrings[3];\n\n return ModalSaveCancel.create({\n title: modalTitle,\n body: modalContent,\n large: true,\n removeOnClose: true,\n show: true,\n buttons: {\n save: deleteButtonText,\n },\n });\n }).then(function(modal) {\n modal.getRoot().on(ModalEvents.save, function() {\n // The action is now confirmed, sending an action for it.\n return deleteContent(contentid, contextid);\n });\n\n return;\n }).catch(Notification.exception);\n });\n\n $(ACTIONS.RENAME_CONTENT).click(function(e) {\n e.preventDefault();\n\n var contentname = $(this).data('contentname');\n var contentid = $(this).data('contentid');\n\n var strings = [\n {\n key: 'renamecontent',\n component: 'core_contentbank'\n },\n {\n key: 'rename',\n component: 'core_contentbank'\n },\n ];\n\n var saveButtonText = '';\n Str.get_strings(strings).then(function(langStrings) {\n var modalTitle = langStrings[0];\n saveButtonText = langStrings[1];\n\n return ModalSaveCancel.create({\n title: modalTitle,\n body: Templates.render('core_contentbank/renamecontent', {'contentid': contentid, 'name': contentname}),\n removeOnClose: true,\n show: true,\n buttons: {\n save: saveButtonText,\n },\n });\n }).then(function(modal) {\n modal.getRoot().on(ModalEvents.save, function(e) {\n // The action is now confirmed, sending an action for it.\n var newname = $(\"#newname\").val().trim();\n if (newname) {\n renameContent(contentid, newname);\n } else {\n var errorStrings = [\n {\n key: 'error',\n },\n {\n key: 'emptynamenotallowed',\n component: 'core_contentbank',\n },\n ];\n Str.get_strings(errorStrings).then(function(langStrings) {\n Notification.alert(langStrings[0], langStrings[1]);\n }).catch(Notification.exception);\n e.preventDefault();\n }\n });\n\n return;\n }).catch(Notification.exception);\n });\n\n $(ACTIONS.COPY_CONTENT).click(function(e) {\n e.preventDefault();\n\n var contentname = $(this).data('contentname');\n var contentid = $(this).data('contentid');\n\n var strings = [\n {\n key: 'copycontent',\n component: 'core_contentbank'\n },\n {\n key: 'error',\n },\n {\n key: 'emptynamenotallowed',\n component: 'core_contentbank',\n },\n ];\n\n let errorTitle, errorMessage;\n Str.get_strings(strings).then(function(langStrings) {\n var modalTitle = langStrings[0];\n errorTitle = langStrings[1];\n errorMessage = langStrings[2];\n\n return ModalSaveCancel.create({\n title: modalTitle,\n body: Templates.render('core_contentbank/copycontent', {'contentid': contentid, 'name': contentname}),\n removeOnClose: true,\n show: true,\n });\n }).then(function(modal) {\n modal.getRoot().on(ModalEvents.save, function() {\n // The action is now confirmed, sending an action for it.\n var newname = $(\"#newname\").val().trim();\n if (newname) {\n copyContent(contentid, newname);\n } else {\n Notification.alert(errorTitle, errorMessage);\n return false;\n }\n });\n return;\n }).catch(Notification.exception);\n });\n\n $(ACTIONS.SET_CONTENT_VISIBILITY).click(function(e) {\n e.preventDefault();\n\n var contentid = $(this).data('contentid');\n var visibility = $(this).data('visibility');\n\n setContentVisibility(contentid, visibility);\n });\n };\n\n /**\n * Delete content from the content bank.\n *\n * @param {int} contentid The content to delete.\n * @param {int} contextid The contextid where the content belongs.\n */\n function deleteContent(contentid, contextid) {\n var request = {\n methodname: 'core_contentbank_delete_content',\n args: {\n contentids: {contentid}\n }\n };\n\n var requestType = 'success';\n Ajax.call([request])[0].then(function(data) {\n if (data.result) {\n return 'contentdeleted';\n }\n requestType = 'error';\n return 'contentnotdeleted';\n\n }).done(function(message) {\n var params = {\n contextid: contextid\n };\n if (requestType == 'success') {\n params.statusmsg = message;\n } else {\n params.errormsg = message;\n }\n // Redirect to the main content bank page and display the message as a notification.\n window.location.href = Url.relativeUrl('contentbank/index.php', params, false);\n }).fail(Notification.exception);\n }\n\n /**\n * Rename content in the content bank.\n *\n * @param {int} contentid The content to rename.\n * @param {string} name The new name for the content.\n */\n function renameContent(contentid, name) {\n var request = {\n methodname: 'core_contentbank_rename_content',\n args: {\n contentid: contentid,\n name: name\n }\n };\n var requestType = 'success';\n Ajax.call([request])[0].then(function(data) {\n if (data.result) {\n return 'contentrenamed';\n }\n requestType = 'error';\n return data.warnings[0].message;\n\n }).then(function(message) {\n var params = null;\n if (requestType == 'success') {\n params = {\n id: contentid,\n statusmsg: message\n };\n // Redirect to the content view page and display the message as a notification.\n window.location.href = Url.relativeUrl('contentbank/view.php', params, false);\n } else {\n // Fetch error notifications.\n Notification.addNotification({\n message: message,\n type: 'error'\n });\n Notification.fetchNotifications();\n }\n return;\n }).catch(Notification.exception);\n }\n\n /**\n * Copy content in the content bank.\n *\n * @param {int} contentid The content to copy.\n * @param {string} name The name for the new content.\n */\n function copyContent(contentid, name) {\n var request = {\n methodname: 'core_contentbank_copy_content',\n args: {\n contentid: contentid,\n name: name\n }\n };\n Ajax.call([request])[0].then(function(data) {\n if (data.id == 0) {\n // Fetch error notifications.\n Notification.addNotification({\n message: data.warnings[0].message,\n type: 'error'\n });\n Notification.fetchNotifications();\n return data.warnings[0].message;\n } else {\n let params = {\n id: data.id,\n statusmsg: 'contentcopied'\n };\n // Redirect to the content view page and display the message as a notification.\n window.location.href = Url.relativeUrl('contentbank/view.php', params, false);\n }\n return '';\n }).catch(Notification.exception);\n }\n\n /**\n * Set content visibility in the content bank.\n *\n * @param {int} contentid The content to modify\n * @param {int} visibility The new visibility value\n */\n function setContentVisibility(contentid, visibility) {\n var request = {\n methodname: 'core_contentbank_set_content_visibility',\n args: {\n contentid: contentid,\n visibility: visibility\n }\n };\n var requestType = 'success';\n Ajax.call([request])[0].then(function(data) {\n if (data.result) {\n return 'contentvisibilitychanged';\n }\n requestType = 'error';\n return data.warnings[0].message;\n\n }).then(function(message) {\n var params = null;\n if (requestType == 'success') {\n params = {\n id: contentid,\n statusmsg: message\n };\n // Redirect to the content view page and display the message as a notification.\n window.location.href = Url.relativeUrl('contentbank/view.php', params, false);\n } else {\n // Fetch error notifications.\n Notification.addNotification({\n message: message,\n type: 'error'\n });\n Notification.fetchNotifications();\n }\n return;\n }).catch(Notification.exception);\n }\n\n return /** @alias module:core_contentbank/actions */ {\n // Public variables and functions.\n\n /**\n * Initialise the contentbank actions.\n *\n * @method init\n * @return {Actions}\n */\n 'init': function() {\n return new Actions();\n }\n };\n});\n"],"names":["define","$","Ajax","Notification","Str","Templates","Url","ModalSaveCancel","ModalEvents","ACTIONS","Actions","registerEvents","prototype","click","e","preventDefault","contentname","this","data","contentuses","contentid","contextid","strings","key","component","param","name","deleteButtonText","get_strings","then","langStrings","modalTitle","modalContent","create","title","body","large","removeOnClose","show","buttons","save","modal","getRoot","on","request","methodname","args","contentids","requestType","call","result","done","message","params","statusmsg","errormsg","window","location","href","relativeUrl","fail","exception","deleteContent","catch","saveButtonText","render","newname","val","trim","warnings","id","addNotification","type","fetchNotifications","renameContent","alert","errorTitle","errorMessage","copyContent","visibility","setContentVisibility"],"mappings":"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"} \ No newline at end of file diff --git a/contentbank/amd/src/actions.js b/contentbank/amd/src/actions.js index c9b457c9894..5dd0c389f94 100644 --- a/contentbank/amd/src/actions.js +++ b/contentbank/amd/src/actions.js @@ -27,9 +27,9 @@ define([ 'core/str', 'core/templates', 'core/url', - 'core/modal_factory', + 'core/modal_save_cancel', 'core/modal_events'], -function($, Ajax, Notification, Str, Templates, Url, ModalFactory, ModalEvents) { +function($, Ajax, Notification, Str, Templates, Url, ModalSaveCancel, ModalEvents) { /** * List of action selectors. @@ -93,28 +93,22 @@ function($, Ajax, Notification, Str, Templates, Url, ModalFactory, ModalEvents) } deleteButtonText = langStrings[3]; - return ModalFactory.create({ + return ModalSaveCancel.create({ title: modalTitle, body: modalContent, - type: ModalFactory.types.SAVE_CANCEL, - large: true + large: true, + removeOnClose: true, + show: true, + buttons: { + save: deleteButtonText, + }, }); - }).done(function(modal) { - modal.setSaveButtonText(deleteButtonText); + }).then(function(modal) { modal.getRoot().on(ModalEvents.save, function() { // The action is now confirmed, sending an action for it. return deleteContent(contentid, contextid); }); - // Handle hidden event. - modal.getRoot().on(ModalEvents.hidden, function() { - // Destroy when hidden. - modal.destroy(); - }); - - // Show the modal. - modal.show(); - return; }).catch(Notification.exception); }); @@ -141,13 +135,16 @@ function($, Ajax, Notification, Str, Templates, Url, ModalFactory, ModalEvents) var modalTitle = langStrings[0]; saveButtonText = langStrings[1]; - return ModalFactory.create({ + return ModalSaveCancel.create({ title: modalTitle, body: Templates.render('core_contentbank/renamecontent', {'contentid': contentid, 'name': contentname}), - type: ModalFactory.types.SAVE_CANCEL + removeOnClose: true, + show: true, + buttons: { + save: saveButtonText, + }, }); }).then(function(modal) { - modal.setSaveButtonText(saveButtonText); modal.getRoot().on(ModalEvents.save, function(e) { // The action is now confirmed, sending an action for it. var newname = $("#newname").val().trim(); @@ -170,15 +167,6 @@ function($, Ajax, Notification, Str, Templates, Url, ModalFactory, ModalEvents) } }); - // Handle hidden event. - modal.getRoot().on(ModalEvents.hidden, function() { - // Destroy when hidden. - modal.destroy(); - }); - - // Show the modal. - modal.show(); - return; }).catch(Notification.exception); }); @@ -209,10 +197,11 @@ function($, Ajax, Notification, Str, Templates, Url, ModalFactory, ModalEvents) errorTitle = langStrings[1]; errorMessage = langStrings[2]; - return ModalFactory.create({ + return ModalSaveCancel.create({ title: modalTitle, body: Templates.render('core_contentbank/copycontent', {'contentid': contentid, 'name': contentname}), - type: ModalFactory.types.SAVE_CANCEL + removeOnClose: true, + show: true, }); }).then(function(modal) { modal.getRoot().on(ModalEvents.save, function() { @@ -225,15 +214,7 @@ function($, Ajax, Notification, Str, Templates, Url, ModalFactory, ModalEvents) return false; } }); - - // Handle hidden event. - modal.getRoot().on(ModalEvents.hidden, function() { - // Destroy when hidden. - modal.destroy(); - }); - - // Show the modal. - modal.show(); + return; }).catch(Notification.exception); }); diff --git a/course/amd/build/actions.min.js b/course/amd/build/actions.min.js index 4dafca283b5..512f61b7f6c 100644 --- a/course/amd/build/actions.min.js +++ b/course/amd/build/actions.min.js @@ -6,6 +6,6 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @since 3.3 */ -define("core_course/actions",["jquery","core/ajax","core/templates","core/notification","core/str","core/url","core/yui","core/modal_copy_to_clipboard","core/modal_factory","core/modal_events","core/key_codes","core/log","core_courseformat/courseeditor","core/event_dispatcher","core_course/events"],(function($,ajax,templates,notification,str,url,Y,ModalCopyToClipboard,ModalFactory,ModalEvents,KeyCodes,log,editor,EventDispatcher,CourseEvents){const componentActions=["moveSection","moveCm","addSection","deleteSection","cmDelete","cmDuplicate","sectionHide","sectionShow","cmHide","cmShow","cmStealth","sectionHighlight","sectionUnhighlight","cmMoveRight","cmMoveLeft","cmNoGroups","cmVisibleGroups","cmSeparateGroups"],courseeditor=editor.getCurrentCourseEditor();let formatname;var CSS_EDITINPROGRESS="editinprogress",CSS_EDITINGMOVE="editing_move",SELECTOR={ACTIVITYLI:"li.activity",ACTIONAREA:".actions",ACTIVITYACTION:"a.cm-edit-action",MENU:".moodle-actionmenu[data-enhance=moodle-core-actionmenu]",TOGGLE:".toggle-display,.dropdown-toggle",SECTIONLI:"li.section",SECTIONACTIONMENU:".section_action_menu",SECTIONITEM:'[data-for="section_title"]',ADDSECTIONS:".changenumsections [data-add-sections]",SECTIONBADGES:'[data-region="sectionbadges"]'};Y.use("moodle-course-coursebase",(function(){var courseformatselector=M.course.format.get_section_selector();courseformatselector&&(SELECTOR.SECTIONLI=courseformatselector)}));const dispatchEvent=function(eventName,detail,container,options){return container instanceof Element||void 0===container.get||(container=container.get(0)),EventDispatcher.dispatchEvent(eventName,detail,container,options)};var getModuleId=function(element){const item=element.get(0);if(item.dataset.id)return item.dataset.id;let id;return Y.use("moodle-course-util",(function(Y){id=Y.Moodle.core_course.util.cm.getId(Y.Node(item))})),id},addActivitySpinner=function(activity){activity.addClass(CSS_EDITINPROGRESS);var actionarea=activity.find(SELECTOR.ACTIONAREA).get(0);if(actionarea){var spinner=M.util.add_spinner(Y,Y.Node(actionarea));return spinner.show(),void 0!==activity.data("id")&&courseeditor.dispatch("cmLock",[activity.data("id")],!0),spinner}return null},addSectionSpinner=function(sectionelement){sectionelement.addClass(CSS_EDITINPROGRESS);var actionarea=sectionelement.find(SELECTOR.SECTIONACTIONMENU).get(0);if(actionarea){var spinner=M.util.add_spinner(Y,Y.Node(actionarea));return spinner.show(),void 0!==sectionelement.data("id")&&courseeditor.dispatch("sectionLock",[sectionelement.data("id")],!0),spinner}return null},addSectionLightbox=function(sectionelement){const item=sectionelement.get(0);var lightbox=M.util.add_lightbox(Y,Y.Node(item));return"section"==item.dataset.for&&item.dataset.id&&(courseeditor.dispatch("sectionLock",[item.dataset.id],!0),lightbox.setAttribute("data-state","section"),lightbox.setAttribute("data-state-id",item.dataset.id)),lightbox.show(),lightbox},removeSpinner=function(element,spinner,delay){window.setTimeout((function(){if(element.removeClass(CSS_EDITINPROGRESS),spinner&&spinner.hide(),void 0!==element.data("id")){const mutation="section"===element.data("for")?"sectionLock":"cmLock";courseeditor.dispatch(mutation,[element.data("id")],!1)}}),delay)},removeLightbox=function(lightbox,delay){lightbox&&window.setTimeout((function(){lightbox.hide(),lightbox.getAttribute("data-state")&&courseeditor.dispatch("".concat(lightbox.getAttribute("data-state"),"Lock"),[lightbox.getAttribute("data-state-id")],!1)}),delay)},initActionMenu=function(elementid){Y.use("moodle-course-coursebase",(function(){M.course.coursebase.invoke_function("setup_for_resource","#"+elementid)})),M.core.actionmenu&&M.core.actionmenu.newDOMNode&&M.core.actionmenu.newDOMNode(Y.one("#"+elementid))},editModule=function(moduleElement,cmid,target){var lightbox,action=target.attr("data-action"),spinner=addActivitySpinner(moduleElement),promises=ajax.call([{methodname:"core_course_edit_module",args:{id:cmid,action:action,sectionreturn:target.attr("data-sectionreturn")?target.attr("data-sectionreturn"):0}}],!0);"duplicate"===action&&(lightbox=addSectionLightbox(target.closest(SELECTOR.SECTIONLI))),$.when.apply($,promises).done((function(data){var mainElement,tabables,isInside,foundElement,elementToFocus=(mainElement=moduleElement,tabables=$("a:visible"),isInside=!1,foundElement=null,tabables.each((function(){if($.contains(mainElement[0],this))isInside=!0;else if(isInside)return foundElement=this,!1;return!0})),foundElement);moduleElement.replaceWith(data);let affectedids=[];$("
"+data+"
").find(SELECTOR.ACTIVITYLI).each((function(index){initActionMenu($(this).attr("id")),0===index&&(!function(elementId,action){var mainelement=$("#"+elementId),selector="[data-action="+action+"]";"groupsseparate"!==action&&"groupsvisible"!==action&&"groupsnone"!==action||(selector="[data-action=groupsseparate],[data-action=groupsvisible],[data-action=groupsnone]"),mainelement.find(selector).is(":visible")?mainelement.find(selector).focus():mainelement.find(SELECTOR.MENU).find(SELECTOR.TOGGLE).focus()}($(this).attr("id"),action),elementToFocus=null),affectedids.push(getModuleId($(this)))})),elementToFocus&&elementToFocus.focus(),removeSpinner(moduleElement,spinner,400),removeLightbox(lightbox,400),moduleElement.trigger($.Event("coursemoduleedited",{ajaxreturn:data,action:action})),courseeditor.dispatch("legacyActivityAction",action,cmid,affectedids)})).fail((function(ex){removeSpinner(moduleElement,spinner),removeLightbox(lightbox);var e=$.Event("coursemoduleeditfailed",{exception:ex,action:action});moduleElement.trigger(e),e.isDefaultPrevented()||notification.exception(ex)}))},refreshModule=function(element,cmid,sectionreturn){void 0===sectionreturn&&(sectionreturn=courseeditor.sectionReturn);const activityElement=$(element);var spinner=addActivitySpinner(activityElement),promises=ajax.call([{methodname:"core_course_get_module",args:{id:cmid,sectionreturn:sectionreturn}}],!0);return new Promise(((resolve,reject)=>{$.when.apply($,promises).done((function(data){removeSpinner(activityElement,spinner,400),replaceActivityHtmlWith(data),resolve(data)})).fail((function(){removeSpinner(activityElement,spinner),reject()}))}))},confirmDeleteModule=function(mainelement,onconfirm){var modtypename=mainelement.attr("class").match(/modtype_([^\s]*)/)[1],modulename=function(element){var name;Y.use("moodle-course-util",(function(Y){name=Y.Moodle.core_course.util.cm.getName(Y.Node(element.get(0)))}));const state=courseeditor.state,cmid=getModuleId(element);var _state$cm$get;return!name&&state&&cmid&&(name=null===(_state$cm$get=state.cm.get(cmid))||void 0===_state$cm$get?void 0:_state$cm$get.name),name}(mainelement);str.get_string("pluginname",modtypename).done((function(pluginname){var plugindata={type:pluginname,name:modulename};str.get_strings([{key:"confirm",component:"core"},{key:null===modulename?"deletechecktype":"deletechecktypename",param:plugindata},{key:"yes"},{key:"no"}]).done((function(s){notification.confirm(s[0],s[1],s[2],s[3],onconfirm)}))}))},replaceActionItem=function(actionitem,image,stringname,stringcomponent,newaction){var stringRequests=[{key:stringname,component:stringcomponent}];return str.get_strings(stringRequests).then((function(strings){return actionitem.find("span.menu-action-text").html(strings[0]),templates.renderPix(image,"core")})).then((function(pixhtml){actionitem.find(".icon").replaceWith(pixhtml),actionitem.attr("data-action",newaction)})).catch(notification.exception)},defaultEditSectionHandler=function(sectionElement,actionItem,data,courseformat,sectionid){var action=actionItem.attr("data-action");if("hide"===action||"show"===action){if("hide"===action?(sectionElement.addClass("hidden"),setSectionBadge(sectionElement[0],"hiddenfromstudents",!0,!1),replaceActionItem(actionItem,"i/show","showfromothers","format_"+courseformat,"show")):(setSectionBadge(sectionElement[0],"hiddenfromstudents",!1,!1),sectionElement.removeClass("hidden"),replaceActionItem(actionItem,"i/hide","hidefromothers","format_"+courseformat,"hide")),void 0!==data.modules)for(var i in data.modules)replaceActivityHtmlWith(data.modules[i]);void 0!==data.section_availability&§ionElement.find(".section_availability").first().replaceWith(data.section_availability);void 0!==courseeditor.state.section.get(sectionid)&&courseeditor.dispatch("sectionState",[sectionid])}else if("setmarker"===action){var oldmarker=$(SELECTOR.SECTIONLI+".current"),oldActionItem=oldmarker.find(SELECTOR.SECTIONACTIONMENU+" a[data-action=removemarker]");oldmarker.removeClass("current"),replaceActionItem(oldActionItem,"i/marker","highlight","core","setmarker"),sectionElement.addClass("current"),replaceActionItem(actionItem,"i/marked","highlightoff","core","removemarker"),courseeditor.dispatch("legacySectionAction",action,sectionid),setSectionBadge(sectionElement[0],"iscurrent",!0,!0)}else"removemarker"===action&&(sectionElement.removeClass("current"),replaceActionItem(actionItem,"i/marker","highlight","core","setmarker"),courseeditor.dispatch("legacySectionAction",action,sectionid),setSectionBadge(sectionElement[0],"iscurrent",!1,!0))};var replaceActivityHtmlWith=function(activityHTML){$("
"+activityHTML+"
").find(SELECTOR.ACTIVITYLI).each((function(){var id=$(this).attr("id");let focusedPath=function(id){const element=document.getElementById(id);if(element&&element.contains(document.activeElement))return element.querySelector(SELECTOR.ACTIONAREA).contains(document.activeElement)?"".concat(SELECTOR.ACTIONAREA,' [tabindex="0"]'):document.activeElement.id?"#".concat(document.activeElement.id):void 0}(id);if($(SELECTOR.ACTIVITYLI+"#"+id).replaceWith(activityHTML),initActionMenu(id),focusedPath){var _newItem$querySelecto;null===(_newItem$querySelecto=document.getElementById(id).querySelector(focusedPath))||void 0===_newItem$querySelecto||_newItem$querySelecto.focus()}}))},editSection=function(sectionElement,sectionid,target,courseformat){var action=target.attr("data-action"),sectionreturn=target.attr("data-sectionreturn")?target.attr("data-sectionreturn"):0;if(courseeditor.supportComponents&&componentActions.includes(action))return!1;var spinner=addSectionSpinner(sectionElement),promises=ajax.call([{methodname:"core_course_edit_section",args:{id:sectionid,action:action,sectionreturn:sectionreturn}}],!0),lightbox=addSectionLightbox(sectionElement);return $.when.apply($,promises).done((function(dataencoded){var data=$.parseJSON(dataencoded);removeSpinner(sectionElement,spinner),removeLightbox(lightbox),sectionElement.find(SELECTOR.SECTIONACTIONMENU).find(SELECTOR.TOGGLE).focus();var e=$.Event("coursesectionedited",{ajaxreturn:data,action:action});sectionElement.trigger(e),e.isDefaultPrevented()||defaultEditSectionHandler(sectionElement,target,data,courseformat,sectionid)})).fail((function(ex){removeSpinner(sectionElement,spinner),removeLightbox(lightbox);var e=$.Event("coursesectioneditfailed",{exception:ex,action:action});sectionElement.trigger(e),e.isDefaultPrevented()||notification.exception(ex)})),!0},setSectionBadge=function(sectionElement,badgetype,add,removeOther){const sectionbadges=sectionElement.querySelector(SELECTOR.SECTIONBADGES);if(!sectionbadges)return;const badge=sectionbadges.querySelector('[data-type="'+badgetype+'"]');badge&&(add?(removeOther&&document.querySelectorAll('[data-type="'+badgetype+'"]').forEach((b=>{b.classList.add("d-none")})),badge.classList.remove("d-none")):badge.classList.add("d-none"))};return Y.use("moodle-course-coursebase",(function(){M.course.coursebase.register_module({set_visibility_resource_ui:function(args){var mainelement=$(args.element.getDOMNode()),cmid=getModuleId(mainelement);if(cmid){var sectionreturn=mainelement.find("."+CSS_EDITINGMOVE).attr("data-sectionreturn");refreshModule(mainelement,cmid,sectionreturn)}},updateMovedCmState:params=>{const cm=courseeditor.state.cm.get(params.cmid);void 0!==cm&&courseeditor.dispatch("sectionState",[cm.sectionid]),courseeditor.dispatch("cmState",[params.cmid])},updateMovedSectionState:()=>{courseeditor.dispatch("courseState")}})})),courseeditor.addMutations({legacyActivityAction:function(statemanager,action,cmid,affectedids){const state=statemanager.state,cm=state.cm.get(cmid);if(void 0===cm)return;const section=state.section.get(cm.sectionid);if(void 0!==section){switch(courseeditor.dispatch("cmLock",[cm.id],!0),statemanager.setReadOnly(!1),cm.locked=!1,action){case"delete":section.cmlist=section.cmlist.reduce(((cmlist,current)=>(current!=cmid&&cmlist.push(current),cmlist)),[]),state.cm.delete(cmid);break;case"hide":case"show":case"duplicate":courseeditor.dispatch("cmState",affectedids)}statemanager.setReadOnly(!0)}},legacySectionAction:function(statemanager,action,sectionid){const state=statemanager.state,section=state.section.get(sectionid);if(void 0!==section){switch(statemanager.setReadOnly(!1),section.locked=!0,statemanager.setReadOnly(!0),statemanager.setReadOnly(!1),section.locked=!1,action){case"setmarker":state.section.forEach((current=>{current.id!=sectionid&&(current.current=!1)})),section.current=!0;break;case"removemarker":section.current=!1}statemanager.setReadOnly(!0)}}}),{initCoursePage:function(courseformat){formatname=courseformat,$("body").on("click keypress",SELECTOR.ACTIVITYLI+" "+SELECTOR.ACTIVITYACTION+"[data-action]",(function(e){if("keypress"!==e.type||13===e.keyCode){var actionItem=$(this),moduleElement=actionItem.closest(SELECTOR.ACTIVITYLI),action=actionItem.attr("data-action"),moduleId=getModuleId(moduleElement);switch(action){case"moveleft":case"moveright":case"delete":case"duplicate":case"hide":case"stealth":case"show":case"groupsseparate":case"groupsvisible":case"groupsnone":break;default:return}moduleId&&(e.preventDefault(),"delete"===action?confirmDeleteModule(moduleElement,(function(){editModule(moduleElement,moduleId,actionItem)})):editModule(moduleElement,moduleId,actionItem))}})),$("body").on("click keypress",SELECTOR.SECTIONLI+" "+SELECTOR.SECTIONACTIONMENU+"[data-sectionid] a[data-action]",(function(e){if("keypress"===e.type&&13!==e.keyCode)return;var actionItem=$(this),sectionElement=actionItem.closest(SELECTOR.SECTIONLI),sectionId=actionItem.closest(SELECTOR.SECTIONACTIONMENU).attr("data-sectionid");if("permalink"===actionItem.attr("data-action"))return e.preventDefault(),void ModalCopyToClipboard.create({text:actionItem.attr("href")},str.get_string("sectionlink","course"));let isExecuted=!0;var message,onconfirm;actionItem.attr("data-confirm")?(message=actionItem.attr("data-confirm"),onconfirm=function(){isExecuted=editSection(sectionElement,sectionId,actionItem,courseformat)},str.get_strings([{key:"confirm"},{key:"yes"},{key:"no"}]).done((function(s){notification.confirm(s[0],message,s[1],s[2],onconfirm)}))):isExecuted=editSection(sectionElement,sectionId,actionItem,courseformat),isExecuted&&e.preventDefault()})),$("body").on("updated","".concat(SELECTOR.SECTIONLI," ").concat(SELECTOR.SECTIONITEM," [data-inplaceeditable]"),(function(e){if(e.ajaxreturn&&e.ajaxreturn.itemid){void 0!==courseeditor.state.section.get(e.ajaxreturn.itemid)&&courseeditor.dispatch("sectionState",[e.ajaxreturn.itemid])}})),$("body").on("updated","".concat(SELECTOR.ACTIVITYLI," [data-inplaceeditable]"),(function(e){e.ajaxreturn&&e.ajaxreturn.itemid&&courseeditor.dispatch("cmState",[e.ajaxreturn.itemid])})),courseeditor.supportComponents&&componentActions.includes("addSection")||str.get_string("numberweeks").done((function(strNumberSections){var trigger=$(SELECTOR.ADDSECTIONS),modalTitle=trigger.attr("data-add-sections"),newSections=trigger.attr("data-new-sections"),modalBody=$('
');modalBody.find("label").html(strNumberSections),ModalFactory.create({title:modalTitle,type:ModalFactory.types.SAVE_CANCEL,body:modalBody.html()},trigger).done((function(modal){var numSections=$(modal.getBody()).find("#add_section_numsections"),addSections=function(){""+parseInt(numSections.val())===numSections.val()&&parseInt(numSections.val())>=1&&(document.location=trigger.attr("href")+"&numsections="+parseInt(numSections.val()))};modal.setSaveButtonText(modalTitle),modal.getRoot().on(ModalEvents.shown,(function(){numSections.focus().select().on("keydown",(function(e){e.keyCode===KeyCodes.enter&&addSections()}))})),modal.getRoot().on(ModalEvents.save,(function(e){e.preventDefault(),addSections()}))}))}))},replaceSectionActionItem:function(sectionelement,selector,image,stringname,stringcomponent,newaction){log.debug("replaceSectionActionItem() is deprecated and will be removed.");var actionitem=sectionelement.find(SELECTOR.SECTIONACTIONMENU+" "+selector);replaceActionItem(actionitem,image,stringname,stringcomponent,newaction)},refreshModule:refreshModule,refreshSection:function(element,sectionid,sectionreturn){void 0===sectionreturn&&(sectionreturn=courseeditor.sectionReturn);const sectionElement=$(element),promises=ajax.call([{methodname:"core_course_edit_section",args:{id:sectionid,action:"refresh",sectionreturn:sectionreturn}}],!0);var spinner=addSectionSpinner(sectionElement);return new Promise(((resolve,reject)=>{$.when.apply($,promises).done((dataencoded=>{removeSpinner(sectionElement,spinner);const data=$.parseJSON(dataencoded),newSectionElement=$(data.content);sectionElement.replaceWith(newSectionElement),$("".concat(SELECTOR.SECTIONLI,"#").concat(sectionid," ").concat(SELECTOR.ACTIVITYLI)).each(((index,activity)=>{initActionMenu(activity.data("id"))}));dispatchEvent(CourseEvents.sectionRefreshed,{ajaxreturn:data,action:"refresh",newSectionElement:newSectionElement.get(0)},newSectionElement).defaultPrevented||defaultEditSectionHandler(newSectionElement,$(SELECTOR.SECTIONLI+"#"+sectionid),data,formatname,sectionid),resolve(data)})).fail((ex=>{dispatchEvent("coursesectionrefreshfailed",{exception:ex,action:"refresh"},sectionElement).defaultPrevented||notification.exception(ex),reject()}))}))}}})); +define("core_course/actions",["jquery","core/ajax","core/templates","core/notification","core/str","core/url","core/yui","core/modal_copy_to_clipboard","core/modal_save_cancel","core/modal_events","core/key_codes","core/log","core_courseformat/courseeditor","core/event_dispatcher","core_course/events"],(function($,ajax,templates,notification,str,url,Y,ModalCopyToClipboard,ModalSaveCancel,ModalEvents,KeyCodes,log,editor,EventDispatcher,CourseEvents){const componentActions=["moveSection","moveCm","addSection","deleteSection","cmDelete","cmDuplicate","sectionHide","sectionShow","cmHide","cmShow","cmStealth","sectionHighlight","sectionUnhighlight","cmMoveRight","cmMoveLeft","cmNoGroups","cmVisibleGroups","cmSeparateGroups"],courseeditor=editor.getCurrentCourseEditor();let formatname;var CSS_EDITINPROGRESS="editinprogress",CSS_EDITINGMOVE="editing_move",SELECTOR={ACTIVITYLI:"li.activity",ACTIONAREA:".actions",ACTIVITYACTION:"a.cm-edit-action",MENU:".moodle-actionmenu[data-enhance=moodle-core-actionmenu]",TOGGLE:".toggle-display,.dropdown-toggle",SECTIONLI:"li.section",SECTIONACTIONMENU:".section_action_menu",SECTIONITEM:'[data-for="section_title"]',ADDSECTIONS:".changenumsections [data-add-sections]",SECTIONBADGES:'[data-region="sectionbadges"]'};Y.use("moodle-course-coursebase",(function(){var courseformatselector=M.course.format.get_section_selector();courseformatselector&&(SELECTOR.SECTIONLI=courseformatselector)}));const dispatchEvent=function(eventName,detail,container,options){return container instanceof Element||void 0===container.get||(container=container.get(0)),EventDispatcher.dispatchEvent(eventName,detail,container,options)};var getModuleId=function(element){const item=element.get(0);if(item.dataset.id)return item.dataset.id;let id;return Y.use("moodle-course-util",(function(Y){id=Y.Moodle.core_course.util.cm.getId(Y.Node(item))})),id},addActivitySpinner=function(activity){activity.addClass(CSS_EDITINPROGRESS);var actionarea=activity.find(SELECTOR.ACTIONAREA).get(0);if(actionarea){var spinner=M.util.add_spinner(Y,Y.Node(actionarea));return spinner.show(),void 0!==activity.data("id")&&courseeditor.dispatch("cmLock",[activity.data("id")],!0),spinner}return null},addSectionSpinner=function(sectionelement){sectionelement.addClass(CSS_EDITINPROGRESS);var actionarea=sectionelement.find(SELECTOR.SECTIONACTIONMENU).get(0);if(actionarea){var spinner=M.util.add_spinner(Y,Y.Node(actionarea));return spinner.show(),void 0!==sectionelement.data("id")&&courseeditor.dispatch("sectionLock",[sectionelement.data("id")],!0),spinner}return null},addSectionLightbox=function(sectionelement){const item=sectionelement.get(0);var lightbox=M.util.add_lightbox(Y,Y.Node(item));return"section"==item.dataset.for&&item.dataset.id&&(courseeditor.dispatch("sectionLock",[item.dataset.id],!0),lightbox.setAttribute("data-state","section"),lightbox.setAttribute("data-state-id",item.dataset.id)),lightbox.show(),lightbox},removeSpinner=function(element,spinner,delay){window.setTimeout((function(){if(element.removeClass(CSS_EDITINPROGRESS),spinner&&spinner.hide(),void 0!==element.data("id")){const mutation="section"===element.data("for")?"sectionLock":"cmLock";courseeditor.dispatch(mutation,[element.data("id")],!1)}}),delay)},removeLightbox=function(lightbox,delay){lightbox&&window.setTimeout((function(){lightbox.hide(),lightbox.getAttribute("data-state")&&courseeditor.dispatch("".concat(lightbox.getAttribute("data-state"),"Lock"),[lightbox.getAttribute("data-state-id")],!1)}),delay)},initActionMenu=function(elementid){Y.use("moodle-course-coursebase",(function(){M.course.coursebase.invoke_function("setup_for_resource","#"+elementid)})),M.core.actionmenu&&M.core.actionmenu.newDOMNode&&M.core.actionmenu.newDOMNode(Y.one("#"+elementid))},editModule=function(moduleElement,cmid,target){var lightbox,action=target.attr("data-action"),spinner=addActivitySpinner(moduleElement),promises=ajax.call([{methodname:"core_course_edit_module",args:{id:cmid,action:action,sectionreturn:target.attr("data-sectionreturn")?target.attr("data-sectionreturn"):0}}],!0);"duplicate"===action&&(lightbox=addSectionLightbox(target.closest(SELECTOR.SECTIONLI))),$.when.apply($,promises).done((function(data){var mainElement,tabables,isInside,foundElement,elementToFocus=(mainElement=moduleElement,tabables=$("a:visible"),isInside=!1,foundElement=null,tabables.each((function(){if($.contains(mainElement[0],this))isInside=!0;else if(isInside)return foundElement=this,!1;return!0})),foundElement);moduleElement.replaceWith(data);let affectedids=[];$("
"+data+"
").find(SELECTOR.ACTIVITYLI).each((function(index){initActionMenu($(this).attr("id")),0===index&&(!function(elementId,action){var mainelement=$("#"+elementId),selector="[data-action="+action+"]";"groupsseparate"!==action&&"groupsvisible"!==action&&"groupsnone"!==action||(selector="[data-action=groupsseparate],[data-action=groupsvisible],[data-action=groupsnone]"),mainelement.find(selector).is(":visible")?mainelement.find(selector).focus():mainelement.find(SELECTOR.MENU).find(SELECTOR.TOGGLE).focus()}($(this).attr("id"),action),elementToFocus=null),affectedids.push(getModuleId($(this)))})),elementToFocus&&elementToFocus.focus(),removeSpinner(moduleElement,spinner,400),removeLightbox(lightbox,400),moduleElement.trigger($.Event("coursemoduleedited",{ajaxreturn:data,action:action})),courseeditor.dispatch("legacyActivityAction",action,cmid,affectedids)})).fail((function(ex){removeSpinner(moduleElement,spinner),removeLightbox(lightbox);var e=$.Event("coursemoduleeditfailed",{exception:ex,action:action});moduleElement.trigger(e),e.isDefaultPrevented()||notification.exception(ex)}))},refreshModule=function(element,cmid,sectionreturn){void 0===sectionreturn&&(sectionreturn=courseeditor.sectionReturn);const activityElement=$(element);var spinner=addActivitySpinner(activityElement),promises=ajax.call([{methodname:"core_course_get_module",args:{id:cmid,sectionreturn:sectionreturn}}],!0);return new Promise(((resolve,reject)=>{$.when.apply($,promises).done((function(data){removeSpinner(activityElement,spinner,400),replaceActivityHtmlWith(data),resolve(data)})).fail((function(){removeSpinner(activityElement,spinner),reject()}))}))},confirmDeleteModule=function(mainelement,onconfirm){var modtypename=mainelement.attr("class").match(/modtype_([^\s]*)/)[1],modulename=function(element){var name;Y.use("moodle-course-util",(function(Y){name=Y.Moodle.core_course.util.cm.getName(Y.Node(element.get(0)))}));const state=courseeditor.state,cmid=getModuleId(element);var _state$cm$get;return!name&&state&&cmid&&(name=null===(_state$cm$get=state.cm.get(cmid))||void 0===_state$cm$get?void 0:_state$cm$get.name),name}(mainelement);str.get_string("pluginname",modtypename).done((function(pluginname){var plugindata={type:pluginname,name:modulename};str.get_strings([{key:"confirm",component:"core"},{key:null===modulename?"deletechecktype":"deletechecktypename",param:plugindata},{key:"yes"},{key:"no"}]).done((function(s){notification.confirm(s[0],s[1],s[2],s[3],onconfirm)}))}))},replaceActionItem=function(actionitem,image,stringname,stringcomponent,newaction){var stringRequests=[{key:stringname,component:stringcomponent}];return str.get_strings(stringRequests).then((function(strings){return actionitem.find("span.menu-action-text").html(strings[0]),templates.renderPix(image,"core")})).then((function(pixhtml){actionitem.find(".icon").replaceWith(pixhtml),actionitem.attr("data-action",newaction)})).catch(notification.exception)},defaultEditSectionHandler=function(sectionElement,actionItem,data,courseformat,sectionid){var action=actionItem.attr("data-action");if("hide"===action||"show"===action){if("hide"===action?(sectionElement.addClass("hidden"),setSectionBadge(sectionElement[0],"hiddenfromstudents",!0,!1),replaceActionItem(actionItem,"i/show","showfromothers","format_"+courseformat,"show")):(setSectionBadge(sectionElement[0],"hiddenfromstudents",!1,!1),sectionElement.removeClass("hidden"),replaceActionItem(actionItem,"i/hide","hidefromothers","format_"+courseformat,"hide")),void 0!==data.modules)for(var i in data.modules)replaceActivityHtmlWith(data.modules[i]);void 0!==data.section_availability&§ionElement.find(".section_availability").first().replaceWith(data.section_availability);void 0!==courseeditor.state.section.get(sectionid)&&courseeditor.dispatch("sectionState",[sectionid])}else if("setmarker"===action){var oldmarker=$(SELECTOR.SECTIONLI+".current"),oldActionItem=oldmarker.find(SELECTOR.SECTIONACTIONMENU+" a[data-action=removemarker]");oldmarker.removeClass("current"),replaceActionItem(oldActionItem,"i/marker","highlight","core","setmarker"),sectionElement.addClass("current"),replaceActionItem(actionItem,"i/marked","highlightoff","core","removemarker"),courseeditor.dispatch("legacySectionAction",action,sectionid),setSectionBadge(sectionElement[0],"iscurrent",!0,!0)}else"removemarker"===action&&(sectionElement.removeClass("current"),replaceActionItem(actionItem,"i/marker","highlight","core","setmarker"),courseeditor.dispatch("legacySectionAction",action,sectionid),setSectionBadge(sectionElement[0],"iscurrent",!1,!0))};var replaceActivityHtmlWith=function(activityHTML){$("
"+activityHTML+"
").find(SELECTOR.ACTIVITYLI).each((function(){var id=$(this).attr("id");let focusedPath=function(id){const element=document.getElementById(id);if(element&&element.contains(document.activeElement))return element.querySelector(SELECTOR.ACTIONAREA).contains(document.activeElement)?"".concat(SELECTOR.ACTIONAREA,' [tabindex="0"]'):document.activeElement.id?"#".concat(document.activeElement.id):void 0}(id);if($(SELECTOR.ACTIVITYLI+"#"+id).replaceWith(activityHTML),initActionMenu(id),focusedPath){var _newItem$querySelecto;null===(_newItem$querySelecto=document.getElementById(id).querySelector(focusedPath))||void 0===_newItem$querySelecto||_newItem$querySelecto.focus()}}))},editSection=function(sectionElement,sectionid,target,courseformat){var action=target.attr("data-action"),sectionreturn=target.attr("data-sectionreturn")?target.attr("data-sectionreturn"):0;if(courseeditor.supportComponents&&componentActions.includes(action))return!1;var spinner=addSectionSpinner(sectionElement),promises=ajax.call([{methodname:"core_course_edit_section",args:{id:sectionid,action:action,sectionreturn:sectionreturn}}],!0),lightbox=addSectionLightbox(sectionElement);return $.when.apply($,promises).done((function(dataencoded){var data=$.parseJSON(dataencoded);removeSpinner(sectionElement,spinner),removeLightbox(lightbox),sectionElement.find(SELECTOR.SECTIONACTIONMENU).find(SELECTOR.TOGGLE).focus();var e=$.Event("coursesectionedited",{ajaxreturn:data,action:action});sectionElement.trigger(e),e.isDefaultPrevented()||defaultEditSectionHandler(sectionElement,target,data,courseformat,sectionid)})).fail((function(ex){removeSpinner(sectionElement,spinner),removeLightbox(lightbox);var e=$.Event("coursesectioneditfailed",{exception:ex,action:action});sectionElement.trigger(e),e.isDefaultPrevented()||notification.exception(ex)})),!0},setSectionBadge=function(sectionElement,badgetype,add,removeOther){const sectionbadges=sectionElement.querySelector(SELECTOR.SECTIONBADGES);if(!sectionbadges)return;const badge=sectionbadges.querySelector('[data-type="'+badgetype+'"]');badge&&(add?(removeOther&&document.querySelectorAll('[data-type="'+badgetype+'"]').forEach((b=>{b.classList.add("d-none")})),badge.classList.remove("d-none")):badge.classList.add("d-none"))};return Y.use("moodle-course-coursebase",(function(){M.course.coursebase.register_module({set_visibility_resource_ui:function(args){var mainelement=$(args.element.getDOMNode()),cmid=getModuleId(mainelement);if(cmid){var sectionreturn=mainelement.find("."+CSS_EDITINGMOVE).attr("data-sectionreturn");refreshModule(mainelement,cmid,sectionreturn)}},updateMovedCmState:params=>{const cm=courseeditor.state.cm.get(params.cmid);void 0!==cm&&courseeditor.dispatch("sectionState",[cm.sectionid]),courseeditor.dispatch("cmState",[params.cmid])},updateMovedSectionState:()=>{courseeditor.dispatch("courseState")}})})),courseeditor.addMutations({legacyActivityAction:function(statemanager,action,cmid,affectedids){const state=statemanager.state,cm=state.cm.get(cmid);if(void 0===cm)return;const section=state.section.get(cm.sectionid);if(void 0!==section){switch(courseeditor.dispatch("cmLock",[cm.id],!0),statemanager.setReadOnly(!1),cm.locked=!1,action){case"delete":section.cmlist=section.cmlist.reduce(((cmlist,current)=>(current!=cmid&&cmlist.push(current),cmlist)),[]),state.cm.delete(cmid);break;case"hide":case"show":case"duplicate":courseeditor.dispatch("cmState",affectedids)}statemanager.setReadOnly(!0)}},legacySectionAction:function(statemanager,action,sectionid){const state=statemanager.state,section=state.section.get(sectionid);if(void 0!==section){switch(statemanager.setReadOnly(!1),section.locked=!0,statemanager.setReadOnly(!0),statemanager.setReadOnly(!1),section.locked=!1,action){case"setmarker":state.section.forEach((current=>{current.id!=sectionid&&(current.current=!1)})),section.current=!0;break;case"removemarker":section.current=!1}statemanager.setReadOnly(!0)}}}),{initCoursePage:function(courseformat){if(formatname=courseformat,$("body").on("click keypress",SELECTOR.ACTIVITYLI+" "+SELECTOR.ACTIVITYACTION+"[data-action]",(function(e){if("keypress"!==e.type||13===e.keyCode){var actionItem=$(this),moduleElement=actionItem.closest(SELECTOR.ACTIVITYLI),action=actionItem.attr("data-action"),moduleId=getModuleId(moduleElement);switch(action){case"moveleft":case"moveright":case"delete":case"duplicate":case"hide":case"stealth":case"show":case"groupsseparate":case"groupsvisible":case"groupsnone":break;default:return}moduleId&&(e.preventDefault(),"delete"===action?confirmDeleteModule(moduleElement,(function(){editModule(moduleElement,moduleId,actionItem)})):editModule(moduleElement,moduleId,actionItem))}})),$("body").on("click keypress",SELECTOR.SECTIONLI+" "+SELECTOR.SECTIONACTIONMENU+"[data-sectionid] a[data-action]",(function(e){if("keypress"===e.type&&13!==e.keyCode)return;var actionItem=$(this),sectionElement=actionItem.closest(SELECTOR.SECTIONLI),sectionId=actionItem.closest(SELECTOR.SECTIONACTIONMENU).attr("data-sectionid");if("permalink"===actionItem.attr("data-action"))return e.preventDefault(),void ModalCopyToClipboard.create({text:actionItem.attr("href")},str.get_string("sectionlink","course"));let isExecuted=!0;var message,onconfirm;actionItem.attr("data-confirm")?(message=actionItem.attr("data-confirm"),onconfirm=function(){isExecuted=editSection(sectionElement,sectionId,actionItem,courseformat)},str.get_strings([{key:"confirm"},{key:"yes"},{key:"no"}]).done((function(s){notification.confirm(s[0],message,s[1],s[2],onconfirm)}))):isExecuted=editSection(sectionElement,sectionId,actionItem,courseformat),isExecuted&&e.preventDefault()})),$("body").on("updated","".concat(SELECTOR.SECTIONLI," ").concat(SELECTOR.SECTIONITEM," [data-inplaceeditable]"),(function(e){if(e.ajaxreturn&&e.ajaxreturn.itemid){void 0!==courseeditor.state.section.get(e.ajaxreturn.itemid)&&courseeditor.dispatch("sectionState",[e.ajaxreturn.itemid])}})),$("body").on("updated","".concat(SELECTOR.ACTIVITYLI," [data-inplaceeditable]"),(function(e){e.ajaxreturn&&e.ajaxreturn.itemid&&courseeditor.dispatch("cmState",[e.ajaxreturn.itemid])})),courseeditor.supportComponents&&componentActions.includes("addSection"))return;const trigger=$(SELECTOR.ADDSECTIONS),modalTitle=trigger.attr("data-add-sections"),newSections=trigger.attr("data-new-sections");str.get_string("numberweeks").then((function(strNumberSections){var modalBody=$('
');return modalBody.find("label").html(strNumberSections),modalBody.html()})).then((body=>ModalSaveCancel.create({body:body,title:modalTitle}))).then((function(modal){var numSections=$(modal.getBody()).find("#add_section_numsections"),addSections=function(){""+parseInt(numSections.val())===numSections.val()&&parseInt(numSections.val())>=1&&(document.location=trigger.attr("href")+"&numsections="+parseInt(numSections.val()))};return modal.setSaveButtonText(modalTitle),modal.getRoot().on(ModalEvents.shown,(function(){numSections.focus().select().on("keydown",(function(e){e.keyCode===KeyCodes.enter&&addSections()}))})),modal.getRoot().on(ModalEvents.save,(function(e){e.preventDefault(),addSections()})),trigger.on("click",(e=>{e.preventDefault(),modal.show()})),modal})).catch(notification.exception)},replaceSectionActionItem:function(sectionelement,selector,image,stringname,stringcomponent,newaction){log.debug("replaceSectionActionItem() is deprecated and will be removed.");var actionitem=sectionelement.find(SELECTOR.SECTIONACTIONMENU+" "+selector);replaceActionItem(actionitem,image,stringname,stringcomponent,newaction)},refreshModule:refreshModule,refreshSection:function(element,sectionid,sectionreturn){void 0===sectionreturn&&(sectionreturn=courseeditor.sectionReturn);const sectionElement=$(element),promises=ajax.call([{methodname:"core_course_edit_section",args:{id:sectionid,action:"refresh",sectionreturn:sectionreturn}}],!0);var spinner=addSectionSpinner(sectionElement);return new Promise(((resolve,reject)=>{$.when.apply($,promises).done((dataencoded=>{removeSpinner(sectionElement,spinner);const data=$.parseJSON(dataencoded),newSectionElement=$(data.content);sectionElement.replaceWith(newSectionElement),$("".concat(SELECTOR.SECTIONLI,"#").concat(sectionid," ").concat(SELECTOR.ACTIVITYLI)).each(((index,activity)=>{initActionMenu(activity.data("id"))}));dispatchEvent(CourseEvents.sectionRefreshed,{ajaxreturn:data,action:"refresh",newSectionElement:newSectionElement.get(0)},newSectionElement).defaultPrevented||defaultEditSectionHandler(newSectionElement,$(SELECTOR.SECTIONLI+"#"+sectionid),data,formatname,sectionid),resolve(data)})).fail((ex=>{dispatchEvent("coursesectionrefreshfailed",{exception:ex,action:"refresh"},sectionElement).defaultPrevented||notification.exception(ex),reject()}))}))}}})); //# sourceMappingURL=actions.min.js.map \ No newline at end of file diff --git a/course/amd/build/actions.min.js.map b/course/amd/build/actions.min.js.map index f4fb0108058..5a2abddf29e 100644 --- a/course/amd/build/actions.min.js.map +++ b/course/amd/build/actions.min.js.map @@ -1 +1 @@ -{"version":3,"file":"actions.min.js","sources":["../src/actions.js"],"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 * Various actions on modules and sections in the editing mode - hiding, duplicating, deleting, etc.\n *\n * @module core_course/actions\n * @copyright 2016 Marina Glancy\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 3.3\n */\ndefine(\n [\n 'jquery',\n 'core/ajax',\n 'core/templates',\n 'core/notification',\n 'core/str',\n 'core/url',\n 'core/yui',\n 'core/modal_copy_to_clipboard',\n 'core/modal_factory',\n 'core/modal_events',\n 'core/key_codes',\n 'core/log',\n 'core_courseformat/courseeditor',\n 'core/event_dispatcher',\n 'core_course/events'\n ],\n function(\n $,\n ajax,\n templates,\n notification,\n str,\n url,\n Y,\n ModalCopyToClipboard,\n ModalFactory,\n ModalEvents,\n KeyCodes,\n log,\n editor,\n EventDispatcher,\n CourseEvents\n ) {\n\n // Eventually, core_courseformat/local/content/actions will handle all actions for\n // component compatible formats and the default actions.js won't be necessary anymore.\n // Meanwhile, we filter the migrated actions.\n const componentActions = [\n 'moveSection', 'moveCm', 'addSection', 'deleteSection', 'cmDelete', 'cmDuplicate', 'sectionHide', 'sectionShow',\n 'cmHide', 'cmShow', 'cmStealth', 'sectionHighlight', 'sectionUnhighlight', 'cmMoveRight', 'cmMoveLeft',\n 'cmNoGroups', 'cmVisibleGroups', 'cmSeparateGroups',\n ];\n\n // The course reactive instance.\n const courseeditor = editor.getCurrentCourseEditor();\n\n // The current course format name (loaded on init).\n let formatname;\n\n var CSS = {\n EDITINPROGRESS: 'editinprogress',\n SECTIONDRAGGABLE: 'sectiondraggable',\n EDITINGMOVE: 'editing_move'\n };\n var SELECTOR = {\n ACTIVITYLI: 'li.activity',\n ACTIONAREA: '.actions',\n ACTIVITYACTION: 'a.cm-edit-action',\n MENU: '.moodle-actionmenu[data-enhance=moodle-core-actionmenu]',\n TOGGLE: '.toggle-display,.dropdown-toggle',\n SECTIONLI: 'li.section',\n SECTIONACTIONMENU: '.section_action_menu',\n SECTIONITEM: '[data-for=\"section_title\"]',\n ADDSECTIONS: '.changenumsections [data-add-sections]',\n SECTIONBADGES: '[data-region=\"sectionbadges\"]',\n };\n\n Y.use('moodle-course-coursebase', function() {\n var courseformatselector = M.course.format.get_section_selector();\n if (courseformatselector) {\n SELECTOR.SECTIONLI = courseformatselector;\n }\n });\n\n /**\n * Dispatch event wrapper.\n *\n * Old jQuery events will be replaced by native events gradually.\n *\n * @method dispatchEvent\n * @param {String} eventName The name of the event\n * @param {Object} detail Any additional details to pass into the eveent\n * @param {Node|HTMLElement} container The point at which to dispatch the event\n * @param {Object} options\n * @param {Boolean} options.bubbles Whether to bubble up the DOM\n * @param {Boolean} options.cancelable Whether preventDefault() can be called\n * @param {Boolean} options.composed Whether the event can bubble across the ShadowDOM boundary\n * @returns {CustomEvent}\n */\n const dispatchEvent = function(eventName, detail, container, options) {\n // Most actions still uses jQuery node instead of regular HTMLElement.\n if (!(container instanceof Element) && container.get !== undefined) {\n container = container.get(0);\n }\n return EventDispatcher.dispatchEvent(eventName, detail, container, options);\n };\n\n /**\n * Wrapper for Y.Moodle.core_course.util.cm.getId\n *\n * @param {JQuery} element\n * @returns {Integer}\n */\n var getModuleId = function(element) {\n // Check if we have a data-id first.\n const item = element.get(0);\n if (item.dataset.id) {\n return item.dataset.id;\n }\n // Use YUI way if data-id is not present.\n let id;\n Y.use('moodle-course-util', function(Y) {\n id = Y.Moodle.core_course.util.cm.getId(Y.Node(item));\n });\n return id;\n };\n\n /**\n * Wrapper for Y.Moodle.core_course.util.cm.getName\n *\n * @param {JQuery} element\n * @returns {String}\n */\n var getModuleName = function(element) {\n var name;\n Y.use('moodle-course-util', function(Y) {\n name = Y.Moodle.core_course.util.cm.getName(Y.Node(element.get(0)));\n });\n // Check if we have the name in the course state.\n const state = courseeditor.state;\n const cmid = getModuleId(element);\n if (!name && state && cmid) {\n name = state.cm.get(cmid)?.name;\n }\n return name;\n };\n\n /**\n * Wrapper for M.util.add_spinner for an activity\n *\n * @param {JQuery} activity\n * @returns {Node}\n */\n var addActivitySpinner = function(activity) {\n activity.addClass(CSS.EDITINPROGRESS);\n var actionarea = activity.find(SELECTOR.ACTIONAREA).get(0);\n if (actionarea) {\n var spinner = M.util.add_spinner(Y, Y.Node(actionarea));\n spinner.show();\n // Lock the activity state element.\n if (activity.data('id') !== undefined) {\n courseeditor.dispatch('cmLock', [activity.data('id')], true);\n }\n return spinner;\n }\n return null;\n };\n\n /**\n * Wrapper for M.util.add_spinner for a section\n *\n * @param {JQuery} sectionelement\n * @returns {Node}\n */\n var addSectionSpinner = function(sectionelement) {\n sectionelement.addClass(CSS.EDITINPROGRESS);\n var actionarea = sectionelement.find(SELECTOR.SECTIONACTIONMENU).get(0);\n if (actionarea) {\n var spinner = M.util.add_spinner(Y, Y.Node(actionarea));\n spinner.show();\n // Lock the section state element.\n if (sectionelement.data('id') !== undefined) {\n courseeditor.dispatch('sectionLock', [sectionelement.data('id')], true);\n }\n return spinner;\n }\n return null;\n };\n\n /**\n * Wrapper for M.util.add_lightbox\n *\n * @param {JQuery} sectionelement\n * @returns {Node}\n */\n var addSectionLightbox = function(sectionelement) {\n const item = sectionelement.get(0);\n var lightbox = M.util.add_lightbox(Y, Y.Node(item));\n if (item.dataset.for == 'section' && item.dataset.id) {\n courseeditor.dispatch('sectionLock', [item.dataset.id], true);\n lightbox.setAttribute('data-state', 'section');\n lightbox.setAttribute('data-state-id', item.dataset.id);\n }\n lightbox.show();\n return lightbox;\n };\n\n /**\n * Removes the spinner element\n *\n * @param {JQuery} element\n * @param {Node} spinner\n * @param {Number} delay\n */\n var removeSpinner = function(element, spinner, delay) {\n window.setTimeout(function() {\n element.removeClass(CSS.EDITINPROGRESS);\n if (spinner) {\n spinner.hide();\n }\n // Unlock the state element.\n if (element.data('id') !== undefined) {\n const mutation = (element.data('for') === 'section') ? 'sectionLock' : 'cmLock';\n courseeditor.dispatch(mutation, [element.data('id')], false);\n }\n }, delay);\n };\n\n /**\n * Removes the lightbox element\n *\n * @param {Node} lightbox lighbox YUI element returned by addSectionLightbox\n * @param {Number} delay\n */\n var removeLightbox = function(lightbox, delay) {\n if (lightbox) {\n window.setTimeout(function() {\n lightbox.hide();\n // Unlock state if necessary.\n if (lightbox.getAttribute('data-state')) {\n courseeditor.dispatch(\n `${lightbox.getAttribute('data-state')}Lock`,\n [lightbox.getAttribute('data-state-id')],\n false\n );\n }\n }, delay);\n }\n };\n\n /**\n * Initialise action menu for the element (section or module)\n *\n * @param {String} elementid CSS id attribute of the element\n */\n var initActionMenu = function(elementid) {\n // Initialise action menu in the new activity.\n Y.use('moodle-course-coursebase', function() {\n M.course.coursebase.invoke_function('setup_for_resource', '#' + elementid);\n });\n if (M.core.actionmenu && M.core.actionmenu.newDOMNode) {\n M.core.actionmenu.newDOMNode(Y.one('#' + elementid));\n }\n };\n\n /**\n * Returns focus to the element that was clicked or \"Edit\" link if element is no longer visible.\n *\n * @param {String} elementId CSS id attribute of the element\n * @param {String} action data-action property of the element that was clicked\n */\n var focusActionItem = function(elementId, action) {\n var mainelement = $('#' + elementId);\n var selector = '[data-action=' + action + ']';\n if (action === 'groupsseparate' || action === 'groupsvisible' || action === 'groupsnone') {\n // New element will have different data-action.\n selector = '[data-action=groupsseparate],[data-action=groupsvisible],[data-action=groupsnone]';\n }\n if (mainelement.find(selector).is(':visible')) {\n mainelement.find(selector).focus();\n } else {\n // Element not visible, focus the \"Edit\" link.\n mainelement.find(SELECTOR.MENU).find(SELECTOR.TOGGLE).focus();\n }\n };\n\n /**\n * Find next after the element\n *\n * @param {JQuery} mainElement element that is about to be deleted\n * @returns {JQuery}\n */\n var findNextFocusable = function(mainElement) {\n var tabables = $(\"a:visible\");\n var isInside = false;\n var foundElement = null;\n tabables.each(function() {\n if ($.contains(mainElement[0], this)) {\n isInside = true;\n } else if (isInside) {\n foundElement = this;\n return false; // Returning false in .each() is equivalent to \"break;\" inside the loop in php.\n }\n return true;\n });\n return foundElement;\n };\n\n /**\n * Performs an action on a module (moving, deleting, duplicating, hiding, etc.)\n *\n * @param {JQuery} moduleElement activity element we perform action on\n * @param {Number} cmid\n * @param {JQuery} target the element (menu item) that was clicked\n */\n var editModule = function(moduleElement, cmid, target) {\n var action = target.attr('data-action');\n var spinner = addActivitySpinner(moduleElement);\n var promises = ajax.call([{\n methodname: 'core_course_edit_module',\n args: {id: cmid,\n action: action,\n sectionreturn: target.attr('data-sectionreturn') ? target.attr('data-sectionreturn') : 0\n }\n }], true);\n\n var lightbox;\n if (action === 'duplicate') {\n lightbox = addSectionLightbox(target.closest(SELECTOR.SECTIONLI));\n }\n $.when.apply($, promises)\n .done(function(data) {\n var elementToFocus = findNextFocusable(moduleElement);\n moduleElement.replaceWith(data);\n let affectedids = [];\n // Initialise action menu for activity(ies) added as a result of this.\n $('
' + data + '
').find(SELECTOR.ACTIVITYLI).each(function(index) {\n initActionMenu($(this).attr('id'));\n if (index === 0) {\n focusActionItem($(this).attr('id'), action);\n elementToFocus = null;\n }\n // Save any activity id in cmids.\n affectedids.push(getModuleId($(this)));\n });\n // In case of activity deletion focus the next focusable element.\n if (elementToFocus) {\n elementToFocus.focus();\n }\n // Remove spinner and lightbox with a delay.\n removeSpinner(moduleElement, spinner, 400);\n removeLightbox(lightbox, 400);\n // Trigger event that can be observed by course formats.\n moduleElement.trigger($.Event('coursemoduleedited', {ajaxreturn: data, action: action}));\n\n // Modify cm state.\n courseeditor.dispatch('legacyActivityAction', action, cmid, affectedids);\n\n }).fail(function(ex) {\n // Remove spinner and lightbox.\n removeSpinner(moduleElement, spinner);\n removeLightbox(lightbox);\n // Trigger event that can be observed by course formats.\n var e = $.Event('coursemoduleeditfailed', {exception: ex, action: action});\n moduleElement.trigger(e);\n if (!e.isDefaultPrevented()) {\n notification.exception(ex);\n }\n });\n };\n\n /**\n * Requests html for the module via WS core_course_get_module and updates the module on the course page\n *\n * Used after d&d of the module to another section\n *\n * @param {JQuery|Element} element\n * @param {Number} cmid\n * @param {Number} sectionreturn\n * @return {Promise} the refresh promise\n */\n var refreshModule = function(element, cmid, sectionreturn) {\n\n if (sectionreturn === undefined) {\n sectionreturn = courseeditor.sectionReturn;\n }\n\n const activityElement = $(element);\n var spinner = addActivitySpinner(activityElement);\n var promises = ajax.call([{\n methodname: 'core_course_get_module',\n args: {id: cmid, sectionreturn: sectionreturn}\n }], true);\n\n return new Promise((resolve, reject) => {\n $.when.apply($, promises)\n .done(function(data) {\n removeSpinner(activityElement, spinner, 400);\n replaceActivityHtmlWith(data);\n resolve(data);\n }).fail(function() {\n removeSpinner(activityElement, spinner);\n reject();\n });\n });\n };\n\n /**\n * Requests html for the section via WS core_course_edit_section and updates the section on the course page\n *\n * @param {JQuery|Element} element\n * @param {Number} sectionid\n * @param {Number} sectionreturn\n * @return {Promise} the refresh promise\n */\n var refreshSection = function(element, sectionid, sectionreturn) {\n\n if (sectionreturn === undefined) {\n sectionreturn = courseeditor.sectionReturn;\n }\n\n const sectionElement = $(element);\n const action = 'refresh';\n const promises = ajax.call([{\n methodname: 'core_course_edit_section',\n args: {id: sectionid, action, sectionreturn},\n }], true);\n\n var spinner = addSectionSpinner(sectionElement);\n return new Promise((resolve, reject) => {\n $.when.apply($, promises)\n .done(dataencoded => {\n\n removeSpinner(sectionElement, spinner);\n const data = $.parseJSON(dataencoded);\n\n const newSectionElement = $(data.content);\n sectionElement.replaceWith(newSectionElement);\n\n // Init modules menus.\n $(`${SELECTOR.SECTIONLI}#${sectionid} ${SELECTOR.ACTIVITYLI}`).each(\n (index, activity) => {\n initActionMenu(activity.data('id'));\n }\n );\n\n // Trigger event that can be observed by course formats.\n const event = dispatchEvent(\n CourseEvents.sectionRefreshed,\n {\n ajaxreturn: data,\n action: action,\n newSectionElement: newSectionElement.get(0),\n },\n newSectionElement\n );\n\n if (!event.defaultPrevented) {\n defaultEditSectionHandler(\n newSectionElement, $(SELECTOR.SECTIONLI + '#' + sectionid),\n data,\n formatname,\n sectionid\n );\n }\n resolve(data);\n }).fail(ex => {\n // Trigger event that can be observed by course formats.\n const event = dispatchEvent(\n 'coursesectionrefreshfailed',\n {exception: ex, action: action},\n sectionElement\n );\n if (!event.defaultPrevented) {\n notification.exception(ex);\n }\n reject();\n });\n });\n };\n\n /**\n * Displays the delete confirmation to delete a module\n *\n * @param {JQuery} mainelement activity element we perform action on\n * @param {function} onconfirm function to execute on confirm\n */\n var confirmDeleteModule = function(mainelement, onconfirm) {\n var modtypename = mainelement.attr('class').match(/modtype_([^\\s]*)/)[1];\n var modulename = getModuleName(mainelement);\n\n str.get_string('pluginname', modtypename).done(function(pluginname) {\n var plugindata = {\n type: pluginname,\n name: modulename\n };\n str.get_strings([\n {key: 'confirm', component: 'core'},\n {key: modulename === null ? 'deletechecktype' : 'deletechecktypename', param: plugindata},\n {key: 'yes'},\n {key: 'no'}\n ]).done(function(s) {\n notification.confirm(s[0], s[1], s[2], s[3], onconfirm);\n }\n );\n });\n };\n\n /**\n * Displays the delete confirmation to delete a section\n *\n * @param {String} message confirmation message\n * @param {function} onconfirm function to execute on confirm\n */\n var confirmEditSection = function(message, onconfirm) {\n str.get_strings([\n {key: 'confirm'}, // TODO link text\n {key: 'yes'},\n {key: 'no'}\n ]).done(function(s) {\n notification.confirm(s[0], message, s[1], s[2], onconfirm);\n }\n );\n };\n\n /**\n * Replaces an action menu item with another one (for example Show->Hide, Set marker->Remove marker)\n *\n * @param {JQuery} actionitem\n * @param {String} image new image name (\"i/show\", \"i/hide\", etc.)\n * @param {String} stringname new string for the action menu item\n * @param {String} stringcomponent\n * @param {String} newaction new value for data-action attribute of the link\n * @return {Promise} promise which is resolved when the replacement has completed\n */\n var replaceActionItem = function(actionitem, image, stringname,\n stringcomponent, newaction) {\n\n var stringRequests = [{key: stringname, component: stringcomponent}];\n // Do not provide an icon with duplicate, different text to the menu item.\n\n return str.get_strings(stringRequests).then(function(strings) {\n actionitem.find('span.menu-action-text').html(strings[0]);\n\n return templates.renderPix(image, 'core');\n }).then(function(pixhtml) {\n actionitem.find('.icon').replaceWith(pixhtml);\n actionitem.attr('data-action', newaction);\n return;\n }).catch(notification.exception);\n };\n\n /**\n * Default post-processing for section AJAX edit actions.\n *\n * This can be overridden in course formats by listening to event coursesectionedited:\n *\n * $('body').on('coursesectionedited', 'li.section', function(e) {\n * var action = e.action,\n * sectionElement = $(e.target),\n * data = e.ajaxreturn;\n * // ... Do some processing here.\n * e.preventDefault(); // Prevent default handler.\n * });\n *\n * @param {JQuery} sectionElement\n * @param {JQuery} actionItem\n * @param {Object} data\n * @param {String} courseformat\n * @param {Number} sectionid\n */\n var defaultEditSectionHandler = function(sectionElement, actionItem, data, courseformat, sectionid) {\n var action = actionItem.attr('data-action');\n if (action === 'hide' || action === 'show') {\n if (action === 'hide') {\n sectionElement.addClass('hidden');\n setSectionBadge(sectionElement[0], 'hiddenfromstudents', true, false);\n replaceActionItem(actionItem, 'i/show',\n 'showfromothers', 'format_' + courseformat, 'show');\n } else {\n setSectionBadge(sectionElement[0], 'hiddenfromstudents', false, false);\n sectionElement.removeClass('hidden');\n replaceActionItem(actionItem, 'i/hide',\n 'hidefromothers', 'format_' + courseformat, 'hide');\n }\n // Replace the modules with new html (that indicates that they are now hidden or not hidden).\n if (data.modules !== undefined) {\n for (var i in data.modules) {\n replaceActivityHtmlWith(data.modules[i]);\n }\n }\n // Replace the section availability information.\n if (data.section_availability !== undefined) {\n sectionElement.find('.section_availability').first().replaceWith(data.section_availability);\n }\n // Modify course state.\n const section = courseeditor.state.section.get(sectionid);\n if (section !== undefined) {\n courseeditor.dispatch('sectionState', [sectionid]);\n }\n } else if (action === 'setmarker') {\n var oldmarker = $(SELECTOR.SECTIONLI + '.current'),\n oldActionItem = oldmarker.find(SELECTOR.SECTIONACTIONMENU + ' ' + 'a[data-action=removemarker]');\n oldmarker.removeClass('current');\n replaceActionItem(oldActionItem, 'i/marker',\n 'highlight', 'core', 'setmarker');\n sectionElement.addClass('current');\n replaceActionItem(actionItem, 'i/marked',\n 'highlightoff', 'core', 'removemarker');\n courseeditor.dispatch('legacySectionAction', action, sectionid);\n setSectionBadge(sectionElement[0], 'iscurrent', true, true);\n } else if (action === 'removemarker') {\n sectionElement.removeClass('current');\n replaceActionItem(actionItem, 'i/marker',\n 'highlight', 'core', 'setmarker');\n courseeditor.dispatch('legacySectionAction', action, sectionid);\n setSectionBadge(sectionElement[0], 'iscurrent', false, true);\n }\n };\n\n /**\n * Get the focused element path in an activity if any.\n *\n * This method is used to restore focus when the activity HTML is refreshed.\n * Only the main course editor elements can be refocused as they are always present\n * even if the activity content changes.\n *\n * @param {String} id the element id the activity element\n * @return {String|undefined} the inner path of the focused element or undefined\n */\n const getActivityFocusedElement = function(id) {\n const element = document.getElementById(id);\n if (!element || !element.contains(document.activeElement)) {\n return undefined;\n }\n // Check if the actions menu toggler is focused.\n if (element.querySelector(SELECTOR.ACTIONAREA).contains(document.activeElement)) {\n return `${SELECTOR.ACTIONAREA} [tabindex=\"0\"]`;\n }\n // Return the current element id if any.\n if (document.activeElement.id) {\n return `#${document.activeElement.id}`;\n }\n return undefined;\n };\n\n /**\n * Replaces the course module with the new html (used to update module after it was edited or its visibility was changed).\n *\n * @param {String} activityHTML\n */\n var replaceActivityHtmlWith = function(activityHTML) {\n $('
' + activityHTML + '
').find(SELECTOR.ACTIVITYLI).each(function() {\n // Extract id from the new activity html.\n var id = $(this).attr('id');\n // Check if the current focused element is inside the activity.\n let focusedPath = getActivityFocusedElement(id);\n // Find the existing element with the same id and replace its contents with new html.\n $(SELECTOR.ACTIVITYLI + '#' + id).replaceWith(activityHTML);\n // Initialise action menu.\n initActionMenu(id);\n // Re-focus the previous elements.\n if (focusedPath) {\n const newItem = document.getElementById(id);\n newItem.querySelector(focusedPath)?.focus();\n }\n\n });\n };\n\n /**\n * Performs an action on a module (moving, deleting, duplicating, hiding, etc.)\n *\n * @param {JQuery} sectionElement section element we perform action on\n * @param {Nunmber} sectionid\n * @param {JQuery} target the element (menu item) that was clicked\n * @param {String} courseformat\n * @return {boolean} true the action call is sent to the server or false if it is ignored.\n */\n var editSection = function(sectionElement, sectionid, target, courseformat) {\n var action = target.attr('data-action'),\n sectionreturn = target.attr('data-sectionreturn') ? target.attr('data-sectionreturn') : 0;\n\n // Filter direct component handled actions.\n if (courseeditor.supportComponents && componentActions.includes(action)) {\n return false;\n }\n\n var spinner = addSectionSpinner(sectionElement);\n var promises = ajax.call([{\n methodname: 'core_course_edit_section',\n args: {id: sectionid, action: action, sectionreturn: sectionreturn}\n }], true);\n\n var lightbox = addSectionLightbox(sectionElement);\n $.when.apply($, promises)\n .done(function(dataencoded) {\n var data = $.parseJSON(dataencoded);\n removeSpinner(sectionElement, spinner);\n removeLightbox(lightbox);\n sectionElement.find(SELECTOR.SECTIONACTIONMENU).find(SELECTOR.TOGGLE).focus();\n // Trigger event that can be observed by course formats.\n var e = $.Event('coursesectionedited', {ajaxreturn: data, action: action});\n sectionElement.trigger(e);\n if (!e.isDefaultPrevented()) {\n defaultEditSectionHandler(sectionElement, target, data, courseformat, sectionid);\n }\n }).fail(function(ex) {\n // Remove spinner and lightbox.\n removeSpinner(sectionElement, spinner);\n removeLightbox(lightbox);\n // Trigger event that can be observed by course formats.\n var e = $.Event('coursesectioneditfailed', {exception: ex, action: action});\n sectionElement.trigger(e);\n if (!e.isDefaultPrevented()) {\n notification.exception(ex);\n }\n });\n return true;\n };\n\n /**\n * Sets the section badge in the section header.\n *\n * @param {JQuery} sectionElement section element we perform action on\n * @param {String} badgetype the type of badge this is for\n * @param {bool} add true to add, false to remove\n * @param {boolean} removeOther in case of adding a badge, whether to remove all other.\n */\n var setSectionBadge = function(sectionElement, badgetype, add, removeOther) {\n const sectionbadges = sectionElement.querySelector(SELECTOR.SECTIONBADGES);\n if (!sectionbadges) {\n return;\n }\n const badge = sectionbadges.querySelector('[data-type=\"' + badgetype + '\"]');\n if (!badge) {\n return;\n }\n if (add) {\n if (removeOther) {\n document.querySelectorAll('[data-type=\"' + badgetype + '\"]').forEach((b) => {\n b.classList.add('d-none');\n });\n }\n badge.classList.remove('d-none');\n } else {\n badge.classList.add('d-none');\n }\n };\n\n // Register a function to be executed after D&D of an activity.\n Y.use('moodle-course-coursebase', function() {\n M.course.coursebase.register_module({\n // Ignore camelcase eslint rule for the next line because it is an expected name of the callback.\n // eslint-disable-next-line camelcase\n set_visibility_resource_ui: function(args) {\n var mainelement = $(args.element.getDOMNode());\n var cmid = getModuleId(mainelement);\n if (cmid) {\n var sectionreturn = mainelement.find('.' + CSS.EDITINGMOVE).attr('data-sectionreturn');\n refreshModule(mainelement, cmid, sectionreturn);\n }\n },\n /**\n * Update the course state when some cm is moved via YUI.\n * @param {*} params\n */\n updateMovedCmState: (params) => {\n const state = courseeditor.state;\n\n // Update old section.\n const cm = state.cm.get(params.cmid);\n if (cm !== undefined) {\n courseeditor.dispatch('sectionState', [cm.sectionid]);\n }\n // Update cm state.\n courseeditor.dispatch('cmState', [params.cmid]);\n },\n /**\n * Update the course state when some section is moved via YUI.\n */\n updateMovedSectionState: () => {\n courseeditor.dispatch('courseState');\n },\n });\n });\n\n // From Moodle 4.0 all edit actions are being re-implemented as state mutation.\n // This means all method from this \"actions\" module will be deprecated when all the course\n // interface is migrated to reactive components.\n // Most legacy actions did not provide enough information to regenarate the course so they\n // use the mutations courseState, sectionState and cmState to get the updated state from\n // the server. However, some activity actions where we can prevent an extra webservice\n // call by implementing an adhoc mutation.\n courseeditor.addMutations({\n /**\n * Compatibility function to update Moodle 4.0 course state using legacy actions.\n *\n * This method only updates some actions which does not require to use cmState mutation\n * to get updated data form the server.\n *\n * @param {Object} statemanager the current state in read write mode\n * @param {String} action the performed action\n * @param {Number} cmid the affected course module id\n * @param {Array} affectedids all affected cm ids (for duplicate action)\n */\n legacyActivityAction: function(statemanager, action, cmid, affectedids) {\n\n const state = statemanager.state;\n const cm = state.cm.get(cmid);\n if (cm === undefined) {\n return;\n }\n const section = state.section.get(cm.sectionid);\n if (section === undefined) {\n return;\n }\n\n // Send the element is locked.\n courseeditor.dispatch('cmLock', [cm.id], true);\n\n // Now we do the real mutation.\n statemanager.setReadOnly(false);\n\n // This unlocked will take effect when the read only is restored.\n cm.locked = false;\n\n switch (action) {\n case 'delete':\n // Remove from section.\n section.cmlist = section.cmlist.reduce(\n (cmlist, current) => {\n if (current != cmid) {\n cmlist.push(current);\n }\n return cmlist;\n },\n []\n );\n // Delete form list.\n state.cm.delete(cmid);\n break;\n\n case 'hide':\n case 'show':\n case 'duplicate':\n courseeditor.dispatch('cmState', affectedids);\n break;\n }\n statemanager.setReadOnly(true);\n },\n legacySectionAction: function(statemanager, action, sectionid) {\n\n const state = statemanager.state;\n const section = state.section.get(sectionid);\n if (section === undefined) {\n return;\n }\n\n // Send the element is locked. Reactive events are only triggered when the state\n // read only mode is restored. We want to notify the interface the element is\n // locked so we need to do a quick lock operation before performing the rest\n // of the mutation.\n statemanager.setReadOnly(false);\n section.locked = true;\n statemanager.setReadOnly(true);\n\n // Now we do the real mutation.\n statemanager.setReadOnly(false);\n\n // This locked will take effect when the read only is restored.\n section.locked = false;\n\n switch (action) {\n case 'setmarker':\n // Remove previous marker.\n state.section.forEach((current) => {\n if (current.id != sectionid) {\n current.current = false;\n }\n });\n section.current = true;\n break;\n\n case 'removemarker':\n section.current = false;\n break;\n }\n statemanager.setReadOnly(true);\n },\n });\n\n return /** @alias module:core_course/actions */ {\n\n /**\n * Initialises course page\n *\n * @method init\n * @param {String} courseformat name of the current course format (for fetching strings)\n */\n initCoursePage: function(courseformat) {\n\n formatname = courseformat;\n\n // Add a handler for course module actions.\n $('body').on('click keypress', SELECTOR.ACTIVITYLI + ' ' +\n SELECTOR.ACTIVITYACTION + '[data-action]', function(e) {\n if (e.type === 'keypress' && e.keyCode !== 13) {\n return;\n }\n var actionItem = $(this),\n moduleElement = actionItem.closest(SELECTOR.ACTIVITYLI),\n action = actionItem.attr('data-action'),\n moduleId = getModuleId(moduleElement);\n switch (action) {\n case 'moveleft':\n case 'moveright':\n case 'delete':\n case 'duplicate':\n case 'hide':\n case 'stealth':\n case 'show':\n case 'groupsseparate':\n case 'groupsvisible':\n case 'groupsnone':\n break;\n default:\n // Nothing to do here!\n return;\n }\n if (!moduleId) {\n return;\n }\n e.preventDefault();\n if (action === 'delete') {\n // Deleting requires confirmation.\n confirmDeleteModule(moduleElement, function() {\n editModule(moduleElement, moduleId, actionItem);\n });\n } else {\n editModule(moduleElement, moduleId, actionItem);\n }\n });\n\n // Add a handler for section show/hide actions.\n $('body').on('click keypress', SELECTOR.SECTIONLI + ' ' +\n SELECTOR.SECTIONACTIONMENU + '[data-sectionid] ' +\n 'a[data-action]', function(e) {\n if (e.type === 'keypress' && e.keyCode !== 13) {\n return;\n }\n var actionItem = $(this),\n sectionElement = actionItem.closest(SELECTOR.SECTIONLI),\n sectionId = actionItem.closest(SELECTOR.SECTIONACTIONMENU).attr('data-sectionid');\n\n if (actionItem.attr('data-action') === 'permalink') {\n e.preventDefault();\n ModalCopyToClipboard.create({\n text: actionItem.attr('href'),\n }, str.get_string('sectionlink', 'course')\n );\n return;\n }\n\n let isExecuted = true;\n if (actionItem.attr('data-confirm')) {\n // Action requires confirmation.\n confirmEditSection(actionItem.attr('data-confirm'), function() {\n isExecuted = editSection(sectionElement, sectionId, actionItem, courseformat);\n });\n } else {\n isExecuted = editSection(sectionElement, sectionId, actionItem, courseformat);\n }\n // Prevent any other module from capturing the action if it is already in execution.\n if (isExecuted) {\n e.preventDefault();\n }\n });\n\n // The section and activity names are edited using inplace editable.\n // The \"update\" jQuery event must be captured in order to update the course state.\n $('body').on('updated', `${SELECTOR.SECTIONLI} ${SELECTOR.SECTIONITEM} [data-inplaceeditable]`, function(e) {\n if (e.ajaxreturn && e.ajaxreturn.itemid) {\n const state = courseeditor.state;\n const section = state.section.get(e.ajaxreturn.itemid);\n if (section !== undefined) {\n courseeditor.dispatch('sectionState', [e.ajaxreturn.itemid]);\n }\n }\n });\n $('body').on('updated', `${SELECTOR.ACTIVITYLI} [data-inplaceeditable]`, function(e) {\n if (e.ajaxreturn && e.ajaxreturn.itemid) {\n courseeditor.dispatch('cmState', [e.ajaxreturn.itemid]);\n }\n });\n\n // Component-based formats don't use modals to create sections.\n if (courseeditor.supportComponents && componentActions.includes('addSection')) {\n return;\n }\n\n // Add a handler for \"Add sections\" link to ask for a number of sections to add.\n str.get_string('numberweeks').done(function(strNumberSections) {\n var trigger = $(SELECTOR.ADDSECTIONS),\n modalTitle = trigger.attr('data-add-sections'),\n newSections = trigger.attr('data-new-sections');\n var modalBody = $('
' +\n '
');\n modalBody.find('label').html(strNumberSections);\n ModalFactory.create({\n title: modalTitle,\n type: ModalFactory.types.SAVE_CANCEL,\n body: modalBody.html()\n }, trigger)\n .done(function(modal) {\n var numSections = $(modal.getBody()).find('#add_section_numsections'),\n addSections = function() {\n // Check if value of the \"Number of sections\" is a valid positive integer and redirect\n // to adding a section script.\n if ('' + parseInt(numSections.val()) === numSections.val() && parseInt(numSections.val()) >= 1) {\n document.location = trigger.attr('href') + '&numsections=' + parseInt(numSections.val());\n }\n };\n modal.setSaveButtonText(modalTitle);\n modal.getRoot().on(ModalEvents.shown, function() {\n // When modal is shown focus and select the input and add a listener to keypress of \"Enter\".\n numSections.focus().select().on('keydown', function(e) {\n if (e.keyCode === KeyCodes.enter) {\n addSections();\n }\n });\n });\n modal.getRoot().on(ModalEvents.save, function(e) {\n // When modal \"Add\" button is pressed.\n e.preventDefault();\n addSections();\n });\n });\n });\n },\n\n /**\n * Replaces a section action menu item with another one (for example Show->Hide, Set marker->Remove marker)\n *\n * This method can be used by course formats in their listener to the coursesectionedited event\n *\n * @deprecated since Moodle 3.9\n * @param {JQuery} sectionelement\n * @param {String} selector CSS selector inside the section element, for example \"a[data-action=show]\"\n * @param {String} image new image name (\"i/show\", \"i/hide\", etc.)\n * @param {String} stringname new string for the action menu item\n * @param {String} stringcomponent\n * @param {String} newaction new value for data-action attribute of the link\n */\n replaceSectionActionItem: function(sectionelement, selector, image, stringname,\n stringcomponent, newaction) {\n log.debug('replaceSectionActionItem() is deprecated and will be removed.');\n var actionitem = sectionelement.find(SELECTOR.SECTIONACTIONMENU + ' ' + selector);\n replaceActionItem(actionitem, image, stringname, stringcomponent, newaction);\n },\n // Method to refresh a module.\n refreshModule,\n refreshSection,\n };\n });\n"],"names":["define","$","ajax","templates","notification","str","url","Y","ModalCopyToClipboard","ModalFactory","ModalEvents","KeyCodes","log","editor","EventDispatcher","CourseEvents","componentActions","courseeditor","getCurrentCourseEditor","formatname","CSS","SELECTOR","ACTIVITYLI","ACTIONAREA","ACTIVITYACTION","MENU","TOGGLE","SECTIONLI","SECTIONACTIONMENU","SECTIONITEM","ADDSECTIONS","SECTIONBADGES","use","courseformatselector","M","course","format","get_section_selector","dispatchEvent","eventName","detail","container","options","Element","undefined","get","getModuleId","element","item","dataset","id","Moodle","core_course","util","cm","getId","Node","addActivitySpinner","activity","addClass","actionarea","find","spinner","add_spinner","show","data","dispatch","addSectionSpinner","sectionelement","addSectionLightbox","lightbox","add_lightbox","for","setAttribute","removeSpinner","delay","window","setTimeout","removeClass","hide","mutation","removeLightbox","getAttribute","initActionMenu","elementid","coursebase","invoke_function","core","actionmenu","newDOMNode","one","editModule","moduleElement","cmid","target","action","attr","promises","call","methodname","args","sectionreturn","closest","when","apply","done","mainElement","tabables","isInside","foundElement","elementToFocus","each","contains","this","replaceWith","affectedids","index","elementId","mainelement","selector","is","focus","focusActionItem","push","trigger","Event","ajaxreturn","fail","ex","e","exception","isDefaultPrevented","refreshModule","sectionReturn","activityElement","Promise","resolve","reject","replaceActivityHtmlWith","confirmDeleteModule","onconfirm","modtypename","match","modulename","name","getName","state","_state$cm$get","getModuleName","get_string","pluginname","plugindata","type","get_strings","key","component","param","s","confirm","replaceActionItem","actionitem","image","stringname","stringcomponent","newaction","stringRequests","then","strings","html","renderPix","pixhtml","catch","defaultEditSectionHandler","sectionElement","actionItem","courseformat","sectionid","setSectionBadge","modules","i","section_availability","first","section","oldmarker","oldActionItem","activityHTML","focusedPath","document","getElementById","activeElement","querySelector","getActivityFocusedElement","editSection","supportComponents","includes","dataencoded","parseJSON","badgetype","add","removeOther","sectionbadges","badge","querySelectorAll","forEach","b","classList","remove","register_module","set_visibility_resource_ui","getDOMNode","updateMovedCmState","params","updateMovedSectionState","addMutations","legacyActivityAction","statemanager","setReadOnly","locked","cmlist","reduce","current","delete","legacySectionAction","initCoursePage","on","keyCode","moduleId","preventDefault","sectionId","create","text","isExecuted","message","itemid","strNumberSections","modalTitle","newSections","modalBody","title","types","SAVE_CANCEL","body","modal","numSections","getBody","addSections","parseInt","val","location","setSaveButtonText","getRoot","shown","select","enter","save","replaceSectionActionItem","debug","refreshSection","newSectionElement","content","sectionRefreshed","defaultPrevented"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"actions.min.js","sources":["../src/actions.js"],"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 * Various actions on modules and sections in the editing mode - hiding, duplicating, deleting, etc.\n *\n * @module core_course/actions\n * @copyright 2016 Marina Glancy\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 3.3\n */\ndefine(\n [\n 'jquery',\n 'core/ajax',\n 'core/templates',\n 'core/notification',\n 'core/str',\n 'core/url',\n 'core/yui',\n 'core/modal_copy_to_clipboard',\n 'core/modal_save_cancel',\n 'core/modal_events',\n 'core/key_codes',\n 'core/log',\n 'core_courseformat/courseeditor',\n 'core/event_dispatcher',\n 'core_course/events'\n ],\n function(\n $,\n ajax,\n templates,\n notification,\n str,\n url,\n Y,\n ModalCopyToClipboard,\n ModalSaveCancel,\n ModalEvents,\n KeyCodes,\n log,\n editor,\n EventDispatcher,\n CourseEvents\n ) {\n\n // Eventually, core_courseformat/local/content/actions will handle all actions for\n // component compatible formats and the default actions.js won't be necessary anymore.\n // Meanwhile, we filter the migrated actions.\n const componentActions = [\n 'moveSection', 'moveCm', 'addSection', 'deleteSection', 'cmDelete', 'cmDuplicate', 'sectionHide', 'sectionShow',\n 'cmHide', 'cmShow', 'cmStealth', 'sectionHighlight', 'sectionUnhighlight', 'cmMoveRight', 'cmMoveLeft',\n 'cmNoGroups', 'cmVisibleGroups', 'cmSeparateGroups',\n ];\n\n // The course reactive instance.\n const courseeditor = editor.getCurrentCourseEditor();\n\n // The current course format name (loaded on init).\n let formatname;\n\n var CSS = {\n EDITINPROGRESS: 'editinprogress',\n SECTIONDRAGGABLE: 'sectiondraggable',\n EDITINGMOVE: 'editing_move'\n };\n var SELECTOR = {\n ACTIVITYLI: 'li.activity',\n ACTIONAREA: '.actions',\n ACTIVITYACTION: 'a.cm-edit-action',\n MENU: '.moodle-actionmenu[data-enhance=moodle-core-actionmenu]',\n TOGGLE: '.toggle-display,.dropdown-toggle',\n SECTIONLI: 'li.section',\n SECTIONACTIONMENU: '.section_action_menu',\n SECTIONITEM: '[data-for=\"section_title\"]',\n ADDSECTIONS: '.changenumsections [data-add-sections]',\n SECTIONBADGES: '[data-region=\"sectionbadges\"]',\n };\n\n Y.use('moodle-course-coursebase', function() {\n var courseformatselector = M.course.format.get_section_selector();\n if (courseformatselector) {\n SELECTOR.SECTIONLI = courseformatselector;\n }\n });\n\n /**\n * Dispatch event wrapper.\n *\n * Old jQuery events will be replaced by native events gradually.\n *\n * @method dispatchEvent\n * @param {String} eventName The name of the event\n * @param {Object} detail Any additional details to pass into the eveent\n * @param {Node|HTMLElement} container The point at which to dispatch the event\n * @param {Object} options\n * @param {Boolean} options.bubbles Whether to bubble up the DOM\n * @param {Boolean} options.cancelable Whether preventDefault() can be called\n * @param {Boolean} options.composed Whether the event can bubble across the ShadowDOM boundary\n * @returns {CustomEvent}\n */\n const dispatchEvent = function(eventName, detail, container, options) {\n // Most actions still uses jQuery node instead of regular HTMLElement.\n if (!(container instanceof Element) && container.get !== undefined) {\n container = container.get(0);\n }\n return EventDispatcher.dispatchEvent(eventName, detail, container, options);\n };\n\n /**\n * Wrapper for Y.Moodle.core_course.util.cm.getId\n *\n * @param {JQuery} element\n * @returns {Integer}\n */\n var getModuleId = function(element) {\n // Check if we have a data-id first.\n const item = element.get(0);\n if (item.dataset.id) {\n return item.dataset.id;\n }\n // Use YUI way if data-id is not present.\n let id;\n Y.use('moodle-course-util', function(Y) {\n id = Y.Moodle.core_course.util.cm.getId(Y.Node(item));\n });\n return id;\n };\n\n /**\n * Wrapper for Y.Moodle.core_course.util.cm.getName\n *\n * @param {JQuery} element\n * @returns {String}\n */\n var getModuleName = function(element) {\n var name;\n Y.use('moodle-course-util', function(Y) {\n name = Y.Moodle.core_course.util.cm.getName(Y.Node(element.get(0)));\n });\n // Check if we have the name in the course state.\n const state = courseeditor.state;\n const cmid = getModuleId(element);\n if (!name && state && cmid) {\n name = state.cm.get(cmid)?.name;\n }\n return name;\n };\n\n /**\n * Wrapper for M.util.add_spinner for an activity\n *\n * @param {JQuery} activity\n * @returns {Node}\n */\n var addActivitySpinner = function(activity) {\n activity.addClass(CSS.EDITINPROGRESS);\n var actionarea = activity.find(SELECTOR.ACTIONAREA).get(0);\n if (actionarea) {\n var spinner = M.util.add_spinner(Y, Y.Node(actionarea));\n spinner.show();\n // Lock the activity state element.\n if (activity.data('id') !== undefined) {\n courseeditor.dispatch('cmLock', [activity.data('id')], true);\n }\n return spinner;\n }\n return null;\n };\n\n /**\n * Wrapper for M.util.add_spinner for a section\n *\n * @param {JQuery} sectionelement\n * @returns {Node}\n */\n var addSectionSpinner = function(sectionelement) {\n sectionelement.addClass(CSS.EDITINPROGRESS);\n var actionarea = sectionelement.find(SELECTOR.SECTIONACTIONMENU).get(0);\n if (actionarea) {\n var spinner = M.util.add_spinner(Y, Y.Node(actionarea));\n spinner.show();\n // Lock the section state element.\n if (sectionelement.data('id') !== undefined) {\n courseeditor.dispatch('sectionLock', [sectionelement.data('id')], true);\n }\n return spinner;\n }\n return null;\n };\n\n /**\n * Wrapper for M.util.add_lightbox\n *\n * @param {JQuery} sectionelement\n * @returns {Node}\n */\n var addSectionLightbox = function(sectionelement) {\n const item = sectionelement.get(0);\n var lightbox = M.util.add_lightbox(Y, Y.Node(item));\n if (item.dataset.for == 'section' && item.dataset.id) {\n courseeditor.dispatch('sectionLock', [item.dataset.id], true);\n lightbox.setAttribute('data-state', 'section');\n lightbox.setAttribute('data-state-id', item.dataset.id);\n }\n lightbox.show();\n return lightbox;\n };\n\n /**\n * Removes the spinner element\n *\n * @param {JQuery} element\n * @param {Node} spinner\n * @param {Number} delay\n */\n var removeSpinner = function(element, spinner, delay) {\n window.setTimeout(function() {\n element.removeClass(CSS.EDITINPROGRESS);\n if (spinner) {\n spinner.hide();\n }\n // Unlock the state element.\n if (element.data('id') !== undefined) {\n const mutation = (element.data('for') === 'section') ? 'sectionLock' : 'cmLock';\n courseeditor.dispatch(mutation, [element.data('id')], false);\n }\n }, delay);\n };\n\n /**\n * Removes the lightbox element\n *\n * @param {Node} lightbox lighbox YUI element returned by addSectionLightbox\n * @param {Number} delay\n */\n var removeLightbox = function(lightbox, delay) {\n if (lightbox) {\n window.setTimeout(function() {\n lightbox.hide();\n // Unlock state if necessary.\n if (lightbox.getAttribute('data-state')) {\n courseeditor.dispatch(\n `${lightbox.getAttribute('data-state')}Lock`,\n [lightbox.getAttribute('data-state-id')],\n false\n );\n }\n }, delay);\n }\n };\n\n /**\n * Initialise action menu for the element (section or module)\n *\n * @param {String} elementid CSS id attribute of the element\n */\n var initActionMenu = function(elementid) {\n // Initialise action menu in the new activity.\n Y.use('moodle-course-coursebase', function() {\n M.course.coursebase.invoke_function('setup_for_resource', '#' + elementid);\n });\n if (M.core.actionmenu && M.core.actionmenu.newDOMNode) {\n M.core.actionmenu.newDOMNode(Y.one('#' + elementid));\n }\n };\n\n /**\n * Returns focus to the element that was clicked or \"Edit\" link if element is no longer visible.\n *\n * @param {String} elementId CSS id attribute of the element\n * @param {String} action data-action property of the element that was clicked\n */\n var focusActionItem = function(elementId, action) {\n var mainelement = $('#' + elementId);\n var selector = '[data-action=' + action + ']';\n if (action === 'groupsseparate' || action === 'groupsvisible' || action === 'groupsnone') {\n // New element will have different data-action.\n selector = '[data-action=groupsseparate],[data-action=groupsvisible],[data-action=groupsnone]';\n }\n if (mainelement.find(selector).is(':visible')) {\n mainelement.find(selector).focus();\n } else {\n // Element not visible, focus the \"Edit\" link.\n mainelement.find(SELECTOR.MENU).find(SELECTOR.TOGGLE).focus();\n }\n };\n\n /**\n * Find next
after the element\n *\n * @param {JQuery} mainElement element that is about to be deleted\n * @returns {JQuery}\n */\n var findNextFocusable = function(mainElement) {\n var tabables = $(\"a:visible\");\n var isInside = false;\n var foundElement = null;\n tabables.each(function() {\n if ($.contains(mainElement[0], this)) {\n isInside = true;\n } else if (isInside) {\n foundElement = this;\n return false; // Returning false in .each() is equivalent to \"break;\" inside the loop in php.\n }\n return true;\n });\n return foundElement;\n };\n\n /**\n * Performs an action on a module (moving, deleting, duplicating, hiding, etc.)\n *\n * @param {JQuery} moduleElement activity element we perform action on\n * @param {Number} cmid\n * @param {JQuery} target the element (menu item) that was clicked\n */\n var editModule = function(moduleElement, cmid, target) {\n var action = target.attr('data-action');\n var spinner = addActivitySpinner(moduleElement);\n var promises = ajax.call([{\n methodname: 'core_course_edit_module',\n args: {id: cmid,\n action: action,\n sectionreturn: target.attr('data-sectionreturn') ? target.attr('data-sectionreturn') : 0\n }\n }], true);\n\n var lightbox;\n if (action === 'duplicate') {\n lightbox = addSectionLightbox(target.closest(SELECTOR.SECTIONLI));\n }\n $.when.apply($, promises)\n .done(function(data) {\n var elementToFocus = findNextFocusable(moduleElement);\n moduleElement.replaceWith(data);\n let affectedids = [];\n // Initialise action menu for activity(ies) added as a result of this.\n $('
' + data + '
').find(SELECTOR.ACTIVITYLI).each(function(index) {\n initActionMenu($(this).attr('id'));\n if (index === 0) {\n focusActionItem($(this).attr('id'), action);\n elementToFocus = null;\n }\n // Save any activity id in cmids.\n affectedids.push(getModuleId($(this)));\n });\n // In case of activity deletion focus the next focusable element.\n if (elementToFocus) {\n elementToFocus.focus();\n }\n // Remove spinner and lightbox with a delay.\n removeSpinner(moduleElement, spinner, 400);\n removeLightbox(lightbox, 400);\n // Trigger event that can be observed by course formats.\n moduleElement.trigger($.Event('coursemoduleedited', {ajaxreturn: data, action: action}));\n\n // Modify cm state.\n courseeditor.dispatch('legacyActivityAction', action, cmid, affectedids);\n\n }).fail(function(ex) {\n // Remove spinner and lightbox.\n removeSpinner(moduleElement, spinner);\n removeLightbox(lightbox);\n // Trigger event that can be observed by course formats.\n var e = $.Event('coursemoduleeditfailed', {exception: ex, action: action});\n moduleElement.trigger(e);\n if (!e.isDefaultPrevented()) {\n notification.exception(ex);\n }\n });\n };\n\n /**\n * Requests html for the module via WS core_course_get_module and updates the module on the course page\n *\n * Used after d&d of the module to another section\n *\n * @param {JQuery|Element} element\n * @param {Number} cmid\n * @param {Number} sectionreturn\n * @return {Promise} the refresh promise\n */\n var refreshModule = function(element, cmid, sectionreturn) {\n\n if (sectionreturn === undefined) {\n sectionreturn = courseeditor.sectionReturn;\n }\n\n const activityElement = $(element);\n var spinner = addActivitySpinner(activityElement);\n var promises = ajax.call([{\n methodname: 'core_course_get_module',\n args: {id: cmid, sectionreturn: sectionreturn}\n }], true);\n\n return new Promise((resolve, reject) => {\n $.when.apply($, promises)\n .done(function(data) {\n removeSpinner(activityElement, spinner, 400);\n replaceActivityHtmlWith(data);\n resolve(data);\n }).fail(function() {\n removeSpinner(activityElement, spinner);\n reject();\n });\n });\n };\n\n /**\n * Requests html for the section via WS core_course_edit_section and updates the section on the course page\n *\n * @param {JQuery|Element} element\n * @param {Number} sectionid\n * @param {Number} sectionreturn\n * @return {Promise} the refresh promise\n */\n var refreshSection = function(element, sectionid, sectionreturn) {\n\n if (sectionreturn === undefined) {\n sectionreturn = courseeditor.sectionReturn;\n }\n\n const sectionElement = $(element);\n const action = 'refresh';\n const promises = ajax.call([{\n methodname: 'core_course_edit_section',\n args: {id: sectionid, action, sectionreturn},\n }], true);\n\n var spinner = addSectionSpinner(sectionElement);\n return new Promise((resolve, reject) => {\n $.when.apply($, promises)\n .done(dataencoded => {\n\n removeSpinner(sectionElement, spinner);\n const data = $.parseJSON(dataencoded);\n\n const newSectionElement = $(data.content);\n sectionElement.replaceWith(newSectionElement);\n\n // Init modules menus.\n $(`${SELECTOR.SECTIONLI}#${sectionid} ${SELECTOR.ACTIVITYLI}`).each(\n (index, activity) => {\n initActionMenu(activity.data('id'));\n }\n );\n\n // Trigger event that can be observed by course formats.\n const event = dispatchEvent(\n CourseEvents.sectionRefreshed,\n {\n ajaxreturn: data,\n action: action,\n newSectionElement: newSectionElement.get(0),\n },\n newSectionElement\n );\n\n if (!event.defaultPrevented) {\n defaultEditSectionHandler(\n newSectionElement, $(SELECTOR.SECTIONLI + '#' + sectionid),\n data,\n formatname,\n sectionid\n );\n }\n resolve(data);\n }).fail(ex => {\n // Trigger event that can be observed by course formats.\n const event = dispatchEvent(\n 'coursesectionrefreshfailed',\n {exception: ex, action: action},\n sectionElement\n );\n if (!event.defaultPrevented) {\n notification.exception(ex);\n }\n reject();\n });\n });\n };\n\n /**\n * Displays the delete confirmation to delete a module\n *\n * @param {JQuery} mainelement activity element we perform action on\n * @param {function} onconfirm function to execute on confirm\n */\n var confirmDeleteModule = function(mainelement, onconfirm) {\n var modtypename = mainelement.attr('class').match(/modtype_([^\\s]*)/)[1];\n var modulename = getModuleName(mainelement);\n\n str.get_string('pluginname', modtypename).done(function(pluginname) {\n var plugindata = {\n type: pluginname,\n name: modulename\n };\n str.get_strings([\n {key: 'confirm', component: 'core'},\n {key: modulename === null ? 'deletechecktype' : 'deletechecktypename', param: plugindata},\n {key: 'yes'},\n {key: 'no'}\n ]).done(function(s) {\n notification.confirm(s[0], s[1], s[2], s[3], onconfirm);\n }\n );\n });\n };\n\n /**\n * Displays the delete confirmation to delete a section\n *\n * @param {String} message confirmation message\n * @param {function} onconfirm function to execute on confirm\n */\n var confirmEditSection = function(message, onconfirm) {\n str.get_strings([\n {key: 'confirm'}, // TODO link text\n {key: 'yes'},\n {key: 'no'}\n ]).done(function(s) {\n notification.confirm(s[0], message, s[1], s[2], onconfirm);\n }\n );\n };\n\n /**\n * Replaces an action menu item with another one (for example Show->Hide, Set marker->Remove marker)\n *\n * @param {JQuery} actionitem\n * @param {String} image new image name (\"i/show\", \"i/hide\", etc.)\n * @param {String} stringname new string for the action menu item\n * @param {String} stringcomponent\n * @param {String} newaction new value for data-action attribute of the link\n * @return {Promise} promise which is resolved when the replacement has completed\n */\n var replaceActionItem = function(actionitem, image, stringname,\n stringcomponent, newaction) {\n\n var stringRequests = [{key: stringname, component: stringcomponent}];\n // Do not provide an icon with duplicate, different text to the menu item.\n\n return str.get_strings(stringRequests).then(function(strings) {\n actionitem.find('span.menu-action-text').html(strings[0]);\n\n return templates.renderPix(image, 'core');\n }).then(function(pixhtml) {\n actionitem.find('.icon').replaceWith(pixhtml);\n actionitem.attr('data-action', newaction);\n return;\n }).catch(notification.exception);\n };\n\n /**\n * Default post-processing for section AJAX edit actions.\n *\n * This can be overridden in course formats by listening to event coursesectionedited:\n *\n * $('body').on('coursesectionedited', 'li.section', function(e) {\n * var action = e.action,\n * sectionElement = $(e.target),\n * data = e.ajaxreturn;\n * // ... Do some processing here.\n * e.preventDefault(); // Prevent default handler.\n * });\n *\n * @param {JQuery} sectionElement\n * @param {JQuery} actionItem\n * @param {Object} data\n * @param {String} courseformat\n * @param {Number} sectionid\n */\n var defaultEditSectionHandler = function(sectionElement, actionItem, data, courseformat, sectionid) {\n var action = actionItem.attr('data-action');\n if (action === 'hide' || action === 'show') {\n if (action === 'hide') {\n sectionElement.addClass('hidden');\n setSectionBadge(sectionElement[0], 'hiddenfromstudents', true, false);\n replaceActionItem(actionItem, 'i/show',\n 'showfromothers', 'format_' + courseformat, 'show');\n } else {\n setSectionBadge(sectionElement[0], 'hiddenfromstudents', false, false);\n sectionElement.removeClass('hidden');\n replaceActionItem(actionItem, 'i/hide',\n 'hidefromothers', 'format_' + courseformat, 'hide');\n }\n // Replace the modules with new html (that indicates that they are now hidden or not hidden).\n if (data.modules !== undefined) {\n for (var i in data.modules) {\n replaceActivityHtmlWith(data.modules[i]);\n }\n }\n // Replace the section availability information.\n if (data.section_availability !== undefined) {\n sectionElement.find('.section_availability').first().replaceWith(data.section_availability);\n }\n // Modify course state.\n const section = courseeditor.state.section.get(sectionid);\n if (section !== undefined) {\n courseeditor.dispatch('sectionState', [sectionid]);\n }\n } else if (action === 'setmarker') {\n var oldmarker = $(SELECTOR.SECTIONLI + '.current'),\n oldActionItem = oldmarker.find(SELECTOR.SECTIONACTIONMENU + ' ' + 'a[data-action=removemarker]');\n oldmarker.removeClass('current');\n replaceActionItem(oldActionItem, 'i/marker',\n 'highlight', 'core', 'setmarker');\n sectionElement.addClass('current');\n replaceActionItem(actionItem, 'i/marked',\n 'highlightoff', 'core', 'removemarker');\n courseeditor.dispatch('legacySectionAction', action, sectionid);\n setSectionBadge(sectionElement[0], 'iscurrent', true, true);\n } else if (action === 'removemarker') {\n sectionElement.removeClass('current');\n replaceActionItem(actionItem, 'i/marker',\n 'highlight', 'core', 'setmarker');\n courseeditor.dispatch('legacySectionAction', action, sectionid);\n setSectionBadge(sectionElement[0], 'iscurrent', false, true);\n }\n };\n\n /**\n * Get the focused element path in an activity if any.\n *\n * This method is used to restore focus when the activity HTML is refreshed.\n * Only the main course editor elements can be refocused as they are always present\n * even if the activity content changes.\n *\n * @param {String} id the element id the activity element\n * @return {String|undefined} the inner path of the focused element or undefined\n */\n const getActivityFocusedElement = function(id) {\n const element = document.getElementById(id);\n if (!element || !element.contains(document.activeElement)) {\n return undefined;\n }\n // Check if the actions menu toggler is focused.\n if (element.querySelector(SELECTOR.ACTIONAREA).contains(document.activeElement)) {\n return `${SELECTOR.ACTIONAREA} [tabindex=\"0\"]`;\n }\n // Return the current element id if any.\n if (document.activeElement.id) {\n return `#${document.activeElement.id}`;\n }\n return undefined;\n };\n\n /**\n * Replaces the course module with the new html (used to update module after it was edited or its visibility was changed).\n *\n * @param {String} activityHTML\n */\n var replaceActivityHtmlWith = function(activityHTML) {\n $('
' + activityHTML + '
').find(SELECTOR.ACTIVITYLI).each(function() {\n // Extract id from the new activity html.\n var id = $(this).attr('id');\n // Check if the current focused element is inside the activity.\n let focusedPath = getActivityFocusedElement(id);\n // Find the existing element with the same id and replace its contents with new html.\n $(SELECTOR.ACTIVITYLI + '#' + id).replaceWith(activityHTML);\n // Initialise action menu.\n initActionMenu(id);\n // Re-focus the previous elements.\n if (focusedPath) {\n const newItem = document.getElementById(id);\n newItem.querySelector(focusedPath)?.focus();\n }\n\n });\n };\n\n /**\n * Performs an action on a module (moving, deleting, duplicating, hiding, etc.)\n *\n * @param {JQuery} sectionElement section element we perform action on\n * @param {Nunmber} sectionid\n * @param {JQuery} target the element (menu item) that was clicked\n * @param {String} courseformat\n * @return {boolean} true the action call is sent to the server or false if it is ignored.\n */\n var editSection = function(sectionElement, sectionid, target, courseformat) {\n var action = target.attr('data-action'),\n sectionreturn = target.attr('data-sectionreturn') ? target.attr('data-sectionreturn') : 0;\n\n // Filter direct component handled actions.\n if (courseeditor.supportComponents && componentActions.includes(action)) {\n return false;\n }\n\n var spinner = addSectionSpinner(sectionElement);\n var promises = ajax.call([{\n methodname: 'core_course_edit_section',\n args: {id: sectionid, action: action, sectionreturn: sectionreturn}\n }], true);\n\n var lightbox = addSectionLightbox(sectionElement);\n $.when.apply($, promises)\n .done(function(dataencoded) {\n var data = $.parseJSON(dataencoded);\n removeSpinner(sectionElement, spinner);\n removeLightbox(lightbox);\n sectionElement.find(SELECTOR.SECTIONACTIONMENU).find(SELECTOR.TOGGLE).focus();\n // Trigger event that can be observed by course formats.\n var e = $.Event('coursesectionedited', {ajaxreturn: data, action: action});\n sectionElement.trigger(e);\n if (!e.isDefaultPrevented()) {\n defaultEditSectionHandler(sectionElement, target, data, courseformat, sectionid);\n }\n }).fail(function(ex) {\n // Remove spinner and lightbox.\n removeSpinner(sectionElement, spinner);\n removeLightbox(lightbox);\n // Trigger event that can be observed by course formats.\n var e = $.Event('coursesectioneditfailed', {exception: ex, action: action});\n sectionElement.trigger(e);\n if (!e.isDefaultPrevented()) {\n notification.exception(ex);\n }\n });\n return true;\n };\n\n /**\n * Sets the section badge in the section header.\n *\n * @param {JQuery} sectionElement section element we perform action on\n * @param {String} badgetype the type of badge this is for\n * @param {bool} add true to add, false to remove\n * @param {boolean} removeOther in case of adding a badge, whether to remove all other.\n */\n var setSectionBadge = function(sectionElement, badgetype, add, removeOther) {\n const sectionbadges = sectionElement.querySelector(SELECTOR.SECTIONBADGES);\n if (!sectionbadges) {\n return;\n }\n const badge = sectionbadges.querySelector('[data-type=\"' + badgetype + '\"]');\n if (!badge) {\n return;\n }\n if (add) {\n if (removeOther) {\n document.querySelectorAll('[data-type=\"' + badgetype + '\"]').forEach((b) => {\n b.classList.add('d-none');\n });\n }\n badge.classList.remove('d-none');\n } else {\n badge.classList.add('d-none');\n }\n };\n\n // Register a function to be executed after D&D of an activity.\n Y.use('moodle-course-coursebase', function() {\n M.course.coursebase.register_module({\n // Ignore camelcase eslint rule for the next line because it is an expected name of the callback.\n // eslint-disable-next-line camelcase\n set_visibility_resource_ui: function(args) {\n var mainelement = $(args.element.getDOMNode());\n var cmid = getModuleId(mainelement);\n if (cmid) {\n var sectionreturn = mainelement.find('.' + CSS.EDITINGMOVE).attr('data-sectionreturn');\n refreshModule(mainelement, cmid, sectionreturn);\n }\n },\n /**\n * Update the course state when some cm is moved via YUI.\n * @param {*} params\n */\n updateMovedCmState: (params) => {\n const state = courseeditor.state;\n\n // Update old section.\n const cm = state.cm.get(params.cmid);\n if (cm !== undefined) {\n courseeditor.dispatch('sectionState', [cm.sectionid]);\n }\n // Update cm state.\n courseeditor.dispatch('cmState', [params.cmid]);\n },\n /**\n * Update the course state when some section is moved via YUI.\n */\n updateMovedSectionState: () => {\n courseeditor.dispatch('courseState');\n },\n });\n });\n\n // From Moodle 4.0 all edit actions are being re-implemented as state mutation.\n // This means all method from this \"actions\" module will be deprecated when all the course\n // interface is migrated to reactive components.\n // Most legacy actions did not provide enough information to regenarate the course so they\n // use the mutations courseState, sectionState and cmState to get the updated state from\n // the server. However, some activity actions where we can prevent an extra webservice\n // call by implementing an adhoc mutation.\n courseeditor.addMutations({\n /**\n * Compatibility function to update Moodle 4.0 course state using legacy actions.\n *\n * This method only updates some actions which does not require to use cmState mutation\n * to get updated data form the server.\n *\n * @param {Object} statemanager the current state in read write mode\n * @param {String} action the performed action\n * @param {Number} cmid the affected course module id\n * @param {Array} affectedids all affected cm ids (for duplicate action)\n */\n legacyActivityAction: function(statemanager, action, cmid, affectedids) {\n\n const state = statemanager.state;\n const cm = state.cm.get(cmid);\n if (cm === undefined) {\n return;\n }\n const section = state.section.get(cm.sectionid);\n if (section === undefined) {\n return;\n }\n\n // Send the element is locked.\n courseeditor.dispatch('cmLock', [cm.id], true);\n\n // Now we do the real mutation.\n statemanager.setReadOnly(false);\n\n // This unlocked will take effect when the read only is restored.\n cm.locked = false;\n\n switch (action) {\n case 'delete':\n // Remove from section.\n section.cmlist = section.cmlist.reduce(\n (cmlist, current) => {\n if (current != cmid) {\n cmlist.push(current);\n }\n return cmlist;\n },\n []\n );\n // Delete form list.\n state.cm.delete(cmid);\n break;\n\n case 'hide':\n case 'show':\n case 'duplicate':\n courseeditor.dispatch('cmState', affectedids);\n break;\n }\n statemanager.setReadOnly(true);\n },\n legacySectionAction: function(statemanager, action, sectionid) {\n\n const state = statemanager.state;\n const section = state.section.get(sectionid);\n if (section === undefined) {\n return;\n }\n\n // Send the element is locked. Reactive events are only triggered when the state\n // read only mode is restored. We want to notify the interface the element is\n // locked so we need to do a quick lock operation before performing the rest\n // of the mutation.\n statemanager.setReadOnly(false);\n section.locked = true;\n statemanager.setReadOnly(true);\n\n // Now we do the real mutation.\n statemanager.setReadOnly(false);\n\n // This locked will take effect when the read only is restored.\n section.locked = false;\n\n switch (action) {\n case 'setmarker':\n // Remove previous marker.\n state.section.forEach((current) => {\n if (current.id != sectionid) {\n current.current = false;\n }\n });\n section.current = true;\n break;\n\n case 'removemarker':\n section.current = false;\n break;\n }\n statemanager.setReadOnly(true);\n },\n });\n\n return /** @alias module:core_course/actions */ {\n\n /**\n * Initialises course page\n *\n * @method init\n * @param {String} courseformat name of the current course format (for fetching strings)\n */\n initCoursePage: function(courseformat) {\n\n formatname = courseformat;\n\n // Add a handler for course module actions.\n $('body').on('click keypress', SELECTOR.ACTIVITYLI + ' ' +\n SELECTOR.ACTIVITYACTION + '[data-action]', function(e) {\n if (e.type === 'keypress' && e.keyCode !== 13) {\n return;\n }\n var actionItem = $(this),\n moduleElement = actionItem.closest(SELECTOR.ACTIVITYLI),\n action = actionItem.attr('data-action'),\n moduleId = getModuleId(moduleElement);\n switch (action) {\n case 'moveleft':\n case 'moveright':\n case 'delete':\n case 'duplicate':\n case 'hide':\n case 'stealth':\n case 'show':\n case 'groupsseparate':\n case 'groupsvisible':\n case 'groupsnone':\n break;\n default:\n // Nothing to do here!\n return;\n }\n if (!moduleId) {\n return;\n }\n e.preventDefault();\n if (action === 'delete') {\n // Deleting requires confirmation.\n confirmDeleteModule(moduleElement, function() {\n editModule(moduleElement, moduleId, actionItem);\n });\n } else {\n editModule(moduleElement, moduleId, actionItem);\n }\n });\n\n // Add a handler for section show/hide actions.\n $('body').on('click keypress', SELECTOR.SECTIONLI + ' ' +\n SELECTOR.SECTIONACTIONMENU + '[data-sectionid] ' +\n 'a[data-action]', function(e) {\n if (e.type === 'keypress' && e.keyCode !== 13) {\n return;\n }\n var actionItem = $(this),\n sectionElement = actionItem.closest(SELECTOR.SECTIONLI),\n sectionId = actionItem.closest(SELECTOR.SECTIONACTIONMENU).attr('data-sectionid');\n\n if (actionItem.attr('data-action') === 'permalink') {\n e.preventDefault();\n ModalCopyToClipboard.create({\n text: actionItem.attr('href'),\n }, str.get_string('sectionlink', 'course')\n );\n return;\n }\n\n let isExecuted = true;\n if (actionItem.attr('data-confirm')) {\n // Action requires confirmation.\n confirmEditSection(actionItem.attr('data-confirm'), function() {\n isExecuted = editSection(sectionElement, sectionId, actionItem, courseformat);\n });\n } else {\n isExecuted = editSection(sectionElement, sectionId, actionItem, courseformat);\n }\n // Prevent any other module from capturing the action if it is already in execution.\n if (isExecuted) {\n e.preventDefault();\n }\n });\n\n // The section and activity names are edited using inplace editable.\n // The \"update\" jQuery event must be captured in order to update the course state.\n $('body').on('updated', `${SELECTOR.SECTIONLI} ${SELECTOR.SECTIONITEM} [data-inplaceeditable]`, function(e) {\n if (e.ajaxreturn && e.ajaxreturn.itemid) {\n const state = courseeditor.state;\n const section = state.section.get(e.ajaxreturn.itemid);\n if (section !== undefined) {\n courseeditor.dispatch('sectionState', [e.ajaxreturn.itemid]);\n }\n }\n });\n $('body').on('updated', `${SELECTOR.ACTIVITYLI} [data-inplaceeditable]`, function(e) {\n if (e.ajaxreturn && e.ajaxreturn.itemid) {\n courseeditor.dispatch('cmState', [e.ajaxreturn.itemid]);\n }\n });\n\n // Component-based formats don't use modals to create sections.\n if (courseeditor.supportComponents && componentActions.includes('addSection')) {\n return;\n }\n\n // Add a handler for \"Add sections\" link to ask for a number of sections to add.\n const trigger = $(SELECTOR.ADDSECTIONS);\n const modalTitle = trigger.attr('data-add-sections');\n const newSections = trigger.attr('data-new-sections');\n str.get_string('numberweeks')\n .then(function(strNumberSections) {\n var modalBody = $('
' +\n '
');\n modalBody.find('label').html(strNumberSections);\n\n return modalBody.html();\n })\n .then((body) => ModalSaveCancel.create({\n body,\n title: modalTitle,\n }))\n .then(function(modal) {\n var numSections = $(modal.getBody()).find('#add_section_numsections'),\n addSections = function() {\n // Check if value of the \"Number of sections\" is a valid positive integer and redirect\n // to adding a section script.\n if ('' + parseInt(numSections.val()) === numSections.val() && parseInt(numSections.val()) >= 1) {\n document.location = trigger.attr('href') + '&numsections=' + parseInt(numSections.val());\n }\n };\n modal.setSaveButtonText(modalTitle);\n modal.getRoot().on(ModalEvents.shown, function() {\n // When modal is shown focus and select the input and add a listener to keypress of \"Enter\".\n numSections.focus().select().on('keydown', function(e) {\n if (e.keyCode === KeyCodes.enter) {\n addSections();\n }\n });\n });\n modal.getRoot().on(ModalEvents.save, function(e) {\n // When modal \"Add\" button is pressed.\n e.preventDefault();\n addSections();\n });\n\n trigger.on('click', (e) => {\n e.preventDefault();\n modal.show();\n });\n\n return modal;\n })\n .catch(notification.exception);\n },\n\n /**\n * Replaces a section action menu item with another one (for example Show->Hide, Set marker->Remove marker)\n *\n * This method can be used by course formats in their listener to the coursesectionedited event\n *\n * @deprecated since Moodle 3.9\n * @param {JQuery} sectionelement\n * @param {String} selector CSS selector inside the section element, for example \"a[data-action=show]\"\n * @param {String} image new image name (\"i/show\", \"i/hide\", etc.)\n * @param {String} stringname new string for the action menu item\n * @param {String} stringcomponent\n * @param {String} newaction new value for data-action attribute of the link\n */\n replaceSectionActionItem: function(sectionelement, selector, image, stringname,\n stringcomponent, newaction) {\n log.debug('replaceSectionActionItem() is deprecated and will be removed.');\n var actionitem = sectionelement.find(SELECTOR.SECTIONACTIONMENU + ' ' + selector);\n replaceActionItem(actionitem, image, stringname, stringcomponent, newaction);\n },\n // Method to refresh a module.\n refreshModule,\n refreshSection,\n };\n });\n"],"names":["define","$","ajax","templates","notification","str","url","Y","ModalCopyToClipboard","ModalSaveCancel","ModalEvents","KeyCodes","log","editor","EventDispatcher","CourseEvents","componentActions","courseeditor","getCurrentCourseEditor","formatname","CSS","SELECTOR","ACTIVITYLI","ACTIONAREA","ACTIVITYACTION","MENU","TOGGLE","SECTIONLI","SECTIONACTIONMENU","SECTIONITEM","ADDSECTIONS","SECTIONBADGES","use","courseformatselector","M","course","format","get_section_selector","dispatchEvent","eventName","detail","container","options","Element","undefined","get","getModuleId","element","item","dataset","id","Moodle","core_course","util","cm","getId","Node","addActivitySpinner","activity","addClass","actionarea","find","spinner","add_spinner","show","data","dispatch","addSectionSpinner","sectionelement","addSectionLightbox","lightbox","add_lightbox","for","setAttribute","removeSpinner","delay","window","setTimeout","removeClass","hide","mutation","removeLightbox","getAttribute","initActionMenu","elementid","coursebase","invoke_function","core","actionmenu","newDOMNode","one","editModule","moduleElement","cmid","target","action","attr","promises","call","methodname","args","sectionreturn","closest","when","apply","done","mainElement","tabables","isInside","foundElement","elementToFocus","each","contains","this","replaceWith","affectedids","index","elementId","mainelement","selector","is","focus","focusActionItem","push","trigger","Event","ajaxreturn","fail","ex","e","exception","isDefaultPrevented","refreshModule","sectionReturn","activityElement","Promise","resolve","reject","replaceActivityHtmlWith","confirmDeleteModule","onconfirm","modtypename","match","modulename","name","getName","state","_state$cm$get","getModuleName","get_string","pluginname","plugindata","type","get_strings","key","component","param","s","confirm","replaceActionItem","actionitem","image","stringname","stringcomponent","newaction","stringRequests","then","strings","html","renderPix","pixhtml","catch","defaultEditSectionHandler","sectionElement","actionItem","courseformat","sectionid","setSectionBadge","modules","i","section_availability","first","section","oldmarker","oldActionItem","activityHTML","focusedPath","document","getElementById","activeElement","querySelector","getActivityFocusedElement","editSection","supportComponents","includes","dataencoded","parseJSON","badgetype","add","removeOther","sectionbadges","badge","querySelectorAll","forEach","b","classList","remove","register_module","set_visibility_resource_ui","getDOMNode","updateMovedCmState","params","updateMovedSectionState","addMutations","legacyActivityAction","statemanager","setReadOnly","locked","cmlist","reduce","current","delete","legacySectionAction","initCoursePage","on","keyCode","moduleId","preventDefault","sectionId","create","text","isExecuted","message","itemid","modalTitle","newSections","strNumberSections","modalBody","body","title","modal","numSections","getBody","addSections","parseInt","val","location","setSaveButtonText","getRoot","shown","select","enter","save","replaceSectionActionItem","debug","refreshSection","newSectionElement","content","sectionRefreshed","defaultPrevented"],"mappings":";;;;;;;;AAuBAA,6BACI,CACI,SACA,YACA,iBACA,oBACA,WACA,WACA,WACA,+BACA,yBACA,oBACA,iBACA,WACA,iCACA,wBACA,uBAEJ,SACIC,EACAC,KACAC,UACAC,aACAC,IACAC,IACAC,EACAC,qBACAC,gBACAC,YACAC,SACAC,IACAC,OACAC,gBACAC,oBAMMC,iBAAmB,CACrB,cAAe,SAAU,aAAc,gBAAiB,WAAY,cAAe,cAAe,cAClG,SAAU,SAAU,YAAa,mBAAoB,qBAAsB,cAAe,aAC1F,aAAc,kBAAmB,oBAI/BC,aAAeJ,OAAOK,6BAGxBC,eAEAC,mBACgB,iBADhBA,gBAGa,eAEbC,SAAW,CACXC,WAAY,cACZC,WAAY,WACZC,eAAgB,mBAChBC,KAAM,0DACNC,OAAQ,mCACRC,UAAW,aACXC,kBAAmB,uBACnBC,YAAa,6BACbC,YAAa,yCACbC,cAAe,iCAGnBxB,EAAEyB,IAAI,4BAA4B,eAC1BC,qBAAuBC,EAAEC,OAAOC,OAAOC,uBACvCJ,uBACAZ,SAASM,UAAYM,+BAmBvBK,cAAgB,SAASC,UAAWC,OAAQC,UAAWC,gBAEnDD,qBAAqBE,cAA8BC,IAAlBH,UAAUI,MAC7CJ,UAAYA,UAAUI,IAAI,IAEvB/B,gBAAgBwB,cAAcC,UAAWC,OAAQC,UAAWC,cASnEI,YAAc,SAASC,eAEjBC,KAAOD,QAAQF,IAAI,MACrBG,KAAKC,QAAQC,UACNF,KAAKC,QAAQC,OAGpBA,UACJ3C,EAAEyB,IAAI,sBAAsB,SAASzB,GACjC2C,GAAK3C,EAAE4C,OAAOC,YAAYC,KAAKC,GAAGC,MAAMhD,EAAEiD,KAAKR,UAE5CE,IA6BPO,mBAAqB,SAASC,UAC9BA,SAASC,SAASvC,wBACdwC,WAAaF,SAASG,KAAKxC,SAASE,YAAYsB,IAAI,MACpDe,WAAY,KACRE,QAAU5B,EAAEmB,KAAKU,YAAYxD,EAAGA,EAAEiD,KAAKI,oBAC3CE,QAAQE,YAEoBpB,IAAxBc,SAASO,KAAK,OACdhD,aAAaiD,SAAS,SAAU,CAACR,SAASO,KAAK,QAAQ,GAEpDH,eAEJ,MASPK,kBAAoB,SAASC,gBAC7BA,eAAeT,SAASvC,wBACpBwC,WAAaQ,eAAeP,KAAKxC,SAASO,mBAAmBiB,IAAI,MACjEe,WAAY,KACRE,QAAU5B,EAAEmB,KAAKU,YAAYxD,EAAGA,EAAEiD,KAAKI,oBAC3CE,QAAQE,YAE0BpB,IAA9BwB,eAAeH,KAAK,OACpBhD,aAAaiD,SAAS,cAAe,CAACE,eAAeH,KAAK,QAAQ,GAE/DH,eAEJ,MASPO,mBAAqB,SAASD,sBACxBpB,KAAOoB,eAAevB,IAAI,OAC5ByB,SAAWpC,EAAEmB,KAAKkB,aAAahE,EAAGA,EAAEiD,KAAKR,aACrB,WAApBA,KAAKC,QAAQuB,KAAoBxB,KAAKC,QAAQC,KAC9CjC,aAAaiD,SAAS,cAAe,CAAClB,KAAKC,QAAQC,KAAK,GACxDoB,SAASG,aAAa,aAAc,WACpCH,SAASG,aAAa,gBAAiBzB,KAAKC,QAAQC,KAExDoB,SAASN,OACFM,UAUPI,cAAgB,SAAS3B,QAASe,QAASa,OAC3CC,OAAOC,YAAW,cACd9B,QAAQ+B,YAAY1D,oBAChB0C,SACAA,QAAQiB,YAGenC,IAAvBG,QAAQkB,KAAK,MAAqB,OAC5Be,SAAoC,YAAxBjC,QAAQkB,KAAK,OAAwB,cAAgB,SACvEhD,aAAaiD,SAASc,SAAU,CAACjC,QAAQkB,KAAK,QAAQ,MAE3DU,QASHM,eAAiB,SAASX,SAAUK,OAChCL,UACAM,OAAOC,YAAW,WACdP,SAASS,OAELT,SAASY,aAAa,eACtBjE,aAAaiD,mBACNI,SAASY,aAAa,sBACzB,CAACZ,SAASY,aAAa,mBACvB,KAGTP,QASPQ,eAAiB,SAASC,WAE1B7E,EAAEyB,IAAI,4BAA4B,WAC9BE,EAAEC,OAAOkD,WAAWC,gBAAgB,qBAAsB,IAAMF,cAEhElD,EAAEqD,KAAKC,YAActD,EAAEqD,KAAKC,WAAWC,YACvCvD,EAAEqD,KAAKC,WAAWC,WAAWlF,EAAEmF,IAAI,IAAMN,aAsD7CO,WAAa,SAASC,cAAeC,KAAMC,YAWvCxB,SAVAyB,OAASD,OAAOE,KAAK,eACrBlC,QAAUL,mBAAmBmC,eAC7BK,SAAW/F,KAAKgG,KAAK,CAAC,CACtBC,WAAY,0BACZC,KAAM,CAAClD,GAAI2C,KACPE,OAAQA,OACRM,cAAeP,OAAOE,KAAK,sBAAwBF,OAAOE,KAAK,sBAAwB,MAE3F,GAGW,cAAXD,SACAzB,SAAWD,mBAAmByB,OAAOQ,QAAQjF,SAASM,aAE1D1B,EAAEsG,KAAKC,MAAMvG,EAAGgG,UACXQ,MAAK,SAASxC,UAvCUyC,YACzBC,SACAC,SACAC,aAqCQC,gBAxCiBJ,YAwCkBd,cAvC3Ce,SAAW1G,EAAE,aACb2G,UAAW,EACXC,aAAe,KACnBF,SAASI,MAAK,cACN9G,EAAE+G,SAASN,YAAY,GAAIO,MAC3BL,UAAW,OACR,GAAIA,gBACPC,aAAeI,MACR,SAEJ,KAEJJ,cA4BCjB,cAAcsB,YAAYjD,UACtBkD,YAAc,GAElBlH,EAAE,QAAUgE,KAAO,UAAUJ,KAAKxC,SAASC,YAAYyF,MAAK,SAASK,OACjEjC,eAAelF,EAAEgH,MAAMjB,KAAK,OACd,IAAVoB,SAnEE,SAASC,UAAWtB,YAClCuB,YAAcrH,EAAE,IAAMoH,WACtBE,SAAW,gBAAkBxB,OAAS,IAC3B,mBAAXA,QAA0C,kBAAXA,QAAyC,eAAXA,SAE7DwB,SAAW,qFAEXD,YAAYzD,KAAK0D,UAAUC,GAAG,YAC9BF,YAAYzD,KAAK0D,UAAUE,QAG3BH,YAAYzD,KAAKxC,SAASI,MAAMoC,KAAKxC,SAASK,QAAQ+F,QAyD1CC,CAAgBzH,EAAEgH,MAAMjB,KAAK,MAAOD,QACpCe,eAAiB,MAGrBK,YAAYQ,KAAK7E,YAAY7C,EAAEgH,WAG/BH,gBACAA,eAAeW,QAGnB/C,cAAckB,cAAe9B,QAAS,KACtCmB,eAAeX,SAAU,KAEzBsB,cAAcgC,QAAQ3H,EAAE4H,MAAM,qBAAsB,CAACC,WAAY7D,KAAM8B,OAAQA,UAG/E9E,aAAaiD,SAAS,uBAAwB6B,OAAQF,KAAMsB,gBAE7DY,MAAK,SAASC,IAEbtD,cAAckB,cAAe9B,SAC7BmB,eAAeX,cAEX2D,EAAIhI,EAAE4H,MAAM,yBAA0B,CAACK,UAAWF,GAAIjC,OAAQA,SAClEH,cAAcgC,QAAQK,GACjBA,EAAEE,sBACH/H,aAAa8H,UAAUF,QAenCI,cAAgB,SAASrF,QAAS8C,KAAMQ,oBAElBzD,IAAlByD,gBACAA,cAAgBpF,aAAaoH,qBAG3BC,gBAAkBrI,EAAE8C,aACtBe,QAAUL,mBAAmB6E,iBAC7BrC,SAAW/F,KAAKgG,KAAK,CAAC,CACtBC,WAAY,yBACZC,KAAM,CAAClD,GAAI2C,KAAMQ,cAAeA,kBAChC,UAEG,IAAIkC,SAAQ,CAACC,QAASC,UACzBxI,EAAEsG,KAAKC,MAAMvG,EAAGgG,UACXQ,MAAK,SAASxC,MACXS,cAAc4D,gBAAiBxE,QAAS,KACxC4E,wBAAwBzE,MACxBuE,QAAQvE,SACT8D,MAAK,WACJrD,cAAc4D,gBAAiBxE,SAC/B2E,gBAqFZE,oBAAsB,SAASrB,YAAasB,eACxCC,YAAcvB,YAAYtB,KAAK,SAAS8C,MAAM,oBAAoB,GAClEC,WApWY,SAAShG,aACrBiG,KACJzI,EAAEyB,IAAI,sBAAsB,SAASzB,GACjCyI,KAAOzI,EAAE4C,OAAOC,YAAYC,KAAKC,GAAG2F,QAAQ1I,EAAEiD,KAAKT,QAAQF,IAAI,cAG7DqG,MAAQjI,aAAaiI,MACrBrD,KAAO/C,YAAYC,kCACpBiG,MAAQE,OAASrD,OAClBmD,2BAAOE,MAAM5F,GAAGT,IAAIgD,sCAAbsD,cAAoBH,MAExBA,KAyVUI,CAAc9B,aAE/BjH,IAAIgJ,WAAW,aAAcR,aAAapC,MAAK,SAAS6C,gBAChDC,WAAa,CACbC,KAAMF,WACNN,KAAMD,YAEV1I,IAAIoJ,YAAY,CACZ,CAACC,IAAK,UAAWC,UAAW,QAC5B,CAACD,IAAoB,OAAfX,WAAsB,kBAAoB,sBAAuBa,MAAOL,YAC9E,CAACG,IAAK,OACN,CAACA,IAAK,QACPjD,MAAK,SAASoD,GACTzJ,aAAa0J,QAAQD,EAAE,GAAIA,EAAE,GAAIA,EAAE,GAAIA,EAAE,GAAIjB,kBAiCzDmB,kBAAoB,SAASC,WAAYC,MAAOC,WACjBC,gBAAiBC,eAE5CC,eAAiB,CAAC,CAACX,IAAKQ,WAAYP,UAAWQ,yBAG5C9J,IAAIoJ,YAAYY,gBAAgBC,MAAK,SAASC,gBACjDP,WAAWnG,KAAK,yBAAyB2G,KAAKD,QAAQ,IAE/CpK,UAAUsK,UAAUR,MAAO,WACnCK,MAAK,SAASI,SACbV,WAAWnG,KAAK,SAASqD,YAAYwD,SACrCV,WAAWhE,KAAK,cAAeoE,cAEhCO,MAAMvK,aAAa8H,YAsBtB0C,0BAA4B,SAASC,eAAgBC,WAAY7G,KAAM8G,aAAcC,eACjFjF,OAAS+E,WAAW9E,KAAK,kBACd,SAAXD,QAAgC,SAAXA,OAAmB,IACzB,SAAXA,QACA8E,eAAelH,SAAS,UACxBsH,gBAAgBJ,eAAe,GAAI,sBAAsB,GAAM,GAC/Dd,kBAAkBe,WAAY,SAC1B,iBAAkB,UAAYC,aAAc,UAEhDE,gBAAgBJ,eAAe,GAAI,sBAAsB,GAAO,GAChEA,eAAe/F,YAAY,UAC3BiF,kBAAkBe,WAAY,SAC1B,iBAAkB,UAAYC,aAAc,cAG/BnI,IAAjBqB,KAAKiH,YACA,IAAIC,KAAKlH,KAAKiH,QACfxC,wBAAwBzE,KAAKiH,QAAQC,SAIXvI,IAA9BqB,KAAKmH,sBACLP,eAAehH,KAAK,yBAAyBwH,QAAQnE,YAAYjD,KAAKmH,2BAI1DxI,IADA3B,aAAaiI,MAAMoC,QAAQzI,IAAImI,YAE3C/J,aAAaiD,SAAS,eAAgB,CAAC8G,iBAExC,GAAe,cAAXjF,OAAwB,KAC3BwF,UAAYtL,EAAEoB,SAASM,UAAY,YACnC6J,cAAgBD,UAAU1H,KAAKxC,SAASO,kBAATP,gCACnCkK,UAAUzG,YAAY,WACtBiF,kBAAkByB,cAAe,WAC7B,YAAa,OAAQ,aACzBX,eAAelH,SAAS,WACxBoG,kBAAkBe,WAAY,WAC1B,eAAgB,OAAQ,gBAC5B7J,aAAaiD,SAAS,sBAAuB6B,OAAQiF,WACrDC,gBAAgBJ,eAAe,GAAI,aAAa,GAAM,OACpC,iBAAX9E,SACP8E,eAAe/F,YAAY,WAC3BiF,kBAAkBe,WAAY,WAC1B,YAAa,OAAQ,aACzB7J,aAAaiD,SAAS,sBAAuB6B,OAAQiF,WACrDC,gBAAgBJ,eAAe,GAAI,aAAa,GAAO,SAmC3DnC,wBAA0B,SAAS+C,cACnCxL,EAAE,QAAUwL,aAAe,UAAU5H,KAAKxC,SAASC,YAAYyF,MAAK,eAE5D7D,GAAKjD,EAAEgH,MAAMjB,KAAK,UAElB0F,YA1BsB,SAASxI,UACjCH,QAAU4I,SAASC,eAAe1I,OACnCH,SAAYA,QAAQiE,SAAS2E,SAASE,sBAIvC9I,QAAQ+I,cAAczK,SAASE,YAAYyF,SAAS2E,SAASE,yBACnDxK,SAASE,8BAGnBoK,SAASE,cAAc3I,cACZyI,SAASE,cAAc3I,WAehB6I,CAA0B7I,OAE5CjD,EAAEoB,SAASC,WAAa,IAAM4B,IAAIgE,YAAYuE,cAE9CtG,eAAejC,IAEXwI,YAAa,yDACGC,SAASC,eAAe1I,IAChC4I,cAAcJ,qEAAcjE,aAe5CuE,YAAc,SAASnB,eAAgBG,UAAWlF,OAAQiF,kBACtDhF,OAASD,OAAOE,KAAK,eACrBK,cAAgBP,OAAOE,KAAK,sBAAwBF,OAAOE,KAAK,sBAAwB,KAGxF/E,aAAagL,mBAAqBjL,iBAAiBkL,SAASnG,eACrD,MAGPjC,QAAUK,kBAAkB0G,gBAC5B5E,SAAW/F,KAAKgG,KAAK,CAAC,CACtBC,WAAY,2BACZC,KAAM,CAAClD,GAAI8H,UAAWjF,OAAQA,OAAQM,cAAeA,kBACrD,GAEA/B,SAAWD,mBAAmBwG,uBAClC5K,EAAEsG,KAAKC,MAAMvG,EAAGgG,UACXQ,MAAK,SAAS0F,iBACPlI,KAAOhE,EAAEmM,UAAUD,aACvBzH,cAAcmG,eAAgB/G,SAC9BmB,eAAeX,UACfuG,eAAehH,KAAKxC,SAASO,mBAAmBiC,KAAKxC,SAASK,QAAQ+F,YAElEQ,EAAIhI,EAAE4H,MAAM,sBAAuB,CAACC,WAAY7D,KAAM8B,OAAQA,SAClE8E,eAAejD,QAAQK,GAClBA,EAAEE,sBACHyC,0BAA0BC,eAAgB/E,OAAQ7B,KAAM8G,aAAcC,cAE3EjD,MAAK,SAASC,IAEbtD,cAAcmG,eAAgB/G,SAC9BmB,eAAeX,cAEX2D,EAAIhI,EAAE4H,MAAM,0BAA2B,CAACK,UAAWF,GAAIjC,OAAQA,SACnE8E,eAAejD,QAAQK,GAClBA,EAAEE,sBACH/H,aAAa8H,UAAUF,QAG5B,GAWPiD,gBAAkB,SAASJ,eAAgBwB,UAAWC,IAAKC,mBACrDC,cAAgB3B,eAAeiB,cAAczK,SAASU,mBACvDyK,2BAGCC,MAAQD,cAAcV,cAAc,eAAiBO,UAAY,MAClEI,QAGDH,KACIC,aACAZ,SAASe,iBAAiB,eAAiBL,UAAY,MAAMM,SAASC,IAClEA,EAAEC,UAAUP,IAAI,aAGxBG,MAAMI,UAAUC,OAAO,WAEvBL,MAAMI,UAAUP,IAAI,mBAK5B/L,EAAEyB,IAAI,4BAA4B,WAC9BE,EAAEC,OAAOkD,WAAW0H,gBAAgB,CAGhCC,2BAA4B,SAAS5G,UAC7BkB,YAAcrH,EAAEmG,KAAKrD,QAAQkK,cAC7BpH,KAAO/C,YAAYwE,gBACnBzB,KAAM,KACFQ,cAAgBiB,YAAYzD,KAAK,IAAMzC,iBAAiB4E,KAAK,sBACjEoC,cAAcd,YAAazB,KAAMQ,iBAOzC6G,mBAAqBC,eAIX7J,GAHQrC,aAAaiI,MAGV5F,GAAGT,IAAIsK,OAAOtH,WACpBjD,IAAPU,IACArC,aAAaiD,SAAS,eAAgB,CAACZ,GAAG0H,YAG9C/J,aAAaiD,SAAS,UAAW,CAACiJ,OAAOtH,QAK7CuH,wBAAyB,KACrBnM,aAAaiD,SAAS,qBAYlCjD,aAAaoM,aAAa,CAYtBC,qBAAsB,SAASC,aAAcxH,OAAQF,KAAMsB,mBAEjD+B,MAAQqE,aAAarE,MACrB5F,GAAK4F,MAAM5F,GAAGT,IAAIgD,cACbjD,IAAPU,gBAGEgI,QAAUpC,MAAMoC,QAAQzI,IAAIS,GAAG0H,mBACrBpI,IAAZ0I,gBAKJrK,aAAaiD,SAAS,SAAU,CAACZ,GAAGJ,KAAK,GAGzCqK,aAAaC,aAAY,GAGzBlK,GAAGmK,QAAS,EAEJ1H,YACC,SAEDuF,QAAQoC,OAASpC,QAAQoC,OAAOC,QAC5B,CAACD,OAAQE,WACDA,SAAW/H,MACX6H,OAAO/F,KAAKiG,SAETF,SAEX,IAGJxE,MAAM5F,GAAGuK,OAAOhI,gBAGf,WACA,WACA,YACD5E,aAAaiD,SAAS,UAAWiD,aAGzCoG,aAAaC,aAAY,KAE7BM,oBAAqB,SAASP,aAAcxH,OAAQiF,iBAE1C9B,MAAQqE,aAAarE,MACrBoC,QAAUpC,MAAMoC,QAAQzI,IAAImI,mBAClBpI,IAAZ0I,gBAQJiC,aAAaC,aAAY,GACzBlC,QAAQmC,QAAS,EACjBF,aAAaC,aAAY,GAGzBD,aAAaC,aAAY,GAGzBlC,QAAQmC,QAAS,EAET1H,YACC,YAEDmD,MAAMoC,QAAQqB,SAASiB,UACfA,QAAQ1K,IAAM8H,YACd4C,QAAQA,SAAU,MAG1BtC,QAAQsC,SAAU,YAGjB,eACDtC,QAAQsC,SAAU,EAG1BL,aAAaC,aAAY,OAIe,CAQ5CO,eAAgB,SAAShD,iBAErB5J,WAAa4J,aAGb9K,EAAE,QAAQ+N,GAAG,iBAAkB3M,SAASC,WAAa,IAC7CD,SAASG,eAAiB,iBAAiB,SAASyG,MACzC,aAAXA,EAAEuB,MAAqC,KAAdvB,EAAEgG,aAG3BnD,WAAa7K,EAAEgH,MACfrB,cAAgBkF,WAAWxE,QAAQjF,SAASC,YAC5CyE,OAAS+E,WAAW9E,KAAK,eACzBkI,SAAWpL,YAAY8C,sBACnBG,YACC,eACA,gBACA,aACA,gBACA,WACA,cACA,WACA,qBACA,oBACA,kCAMJmI,WAGLjG,EAAEkG,iBACa,WAAXpI,OAEA4C,oBAAoB/C,eAAe,WAC/BD,WAAWC,cAAesI,SAAUpD,eAGxCnF,WAAWC,cAAesI,SAAUpD,iBAK5C7K,EAAE,QAAQ+N,GAAG,iBAAkB3M,SAASM,UAAY,IACxCN,SAASO,kBADUP,mCAED,SAAS4G,MACpB,aAAXA,EAAEuB,MAAqC,KAAdvB,EAAEgG,mBAG3BnD,WAAa7K,EAAEgH,MACf4D,eAAiBC,WAAWxE,QAAQjF,SAASM,WAC7CyM,UAAYtD,WAAWxE,QAAQjF,SAASO,mBAAmBoE,KAAK,qBAE7B,cAAnC8E,WAAW9E,KAAK,sBAChBiC,EAAEkG,sBACF3N,qBAAqB6N,OAAO,CACxBC,KAAMxD,WAAW9E,KAAK,SACvB3F,IAAIgJ,WAAW,cAAe,eAKjCkF,YAAa,EAlcJ,IAASC,QAAS5F,UAmc3BkC,WAAW9E,KAAK,iBAncEwI,QAqcC1D,WAAW9E,KAAK,gBArcR4C,UAqcyB,WAChD2F,WAAavC,YAAYnB,eAAgBuD,UAAWtD,WAAYC,eArchF1K,IAAIoJ,YAAY,CACZ,CAACC,IAAK,WACN,CAACA,IAAK,OACN,CAACA,IAAK,QACPjD,MAAK,SAASoD,GACTzJ,aAAa0J,QAAQD,EAAE,GAAI2E,QAAS3E,EAAE,GAAIA,EAAE,GAAIjB,eAmc5C2F,WAAavC,YAAYnB,eAAgBuD,UAAWtD,WAAYC,cAGhEwD,YACAtG,EAAEkG,oBAMVlO,EAAE,QAAQ+N,GAAG,oBAAc3M,SAASM,sBAAaN,SAASQ,wCAAsC,SAASoG,MACjGA,EAAEH,YAAcG,EAAEH,WAAW2G,OAAQ,MAGrB7L,IAFF3B,aAAaiI,MACLoC,QAAQzI,IAAIoF,EAAEH,WAAW2G,SAE3CxN,aAAaiD,SAAS,eAAgB,CAAC+D,EAAEH,WAAW2G,aAIhExO,EAAE,QAAQ+N,GAAG,oBAAc3M,SAASC,uCAAqC,SAAS2G,GAC1EA,EAAEH,YAAcG,EAAEH,WAAW2G,QAC7BxN,aAAaiD,SAAS,UAAW,CAAC+D,EAAEH,WAAW2G,YAKnDxN,aAAagL,mBAAqBjL,iBAAiBkL,SAAS,2BAK1DtE,QAAU3H,EAAEoB,SAASS,aACrB4M,WAAa9G,QAAQ5B,KAAK,qBAC1B2I,YAAc/G,QAAQ5B,KAAK,qBACjC3F,IAAIgJ,WAAW,eACdiB,MAAK,SAASsE,uBACPC,UAAY5O,EAAE,qHACsD0O,YAAc,6BACtFE,UAAUhL,KAAK,SAAS2G,KAAKoE,mBAEtBC,UAAUrE,UAEpBF,MAAMwE,MAASrO,gBAAgB4N,OAAO,CACnCS,KAAAA,KACAC,MAAOL,eAEVpE,MAAK,SAAS0E,WACPC,YAAchP,EAAE+O,MAAME,WAAWrL,KAAK,4BAC1CsL,YAAc,WAGN,GAAKC,SAASH,YAAYI,SAAWJ,YAAYI,OAASD,SAASH,YAAYI,QAAU,IACzF1D,SAAS2D,SAAW1H,QAAQ5B,KAAK,QAAU,gBAAkBoJ,SAASH,YAAYI,gBAG1FL,MAAMO,kBAAkBb,YACxBM,MAAMQ,UAAUxB,GAAGtN,YAAY+O,OAAO,WAElCR,YAAYxH,QAAQiI,SAAS1B,GAAG,WAAW,SAAS/F,GAC5CA,EAAEgG,UAAYtN,SAASgP,OACvBR,oBAIZH,MAAMQ,UAAUxB,GAAGtN,YAAYkP,MAAM,SAAS3H,GAE1CA,EAAEkG,iBACFgB,iBAGJvH,QAAQoG,GAAG,SAAU/F,IACjBA,EAAEkG,iBACFa,MAAMhL,UAGHgL,SAEVrE,MAAMvK,aAAa8H,YAgBxB2H,yBAA0B,SAASzL,eAAgBmD,SAAU0C,MAAOC,WAC5BC,gBAAiBC,WACrDxJ,IAAIkP,MAAM,qEACN9F,WAAa5F,eAAeP,KAAKxC,SAASO,kBAAoB,IAAM2F,UACxEwC,kBAAkBC,WAAYC,MAAOC,WAAYC,gBAAiBC,YAGtEhC,cAAAA,cACA2H,eAjpBiB,SAAShN,QAASiI,UAAW3E,oBAExBzD,IAAlByD,gBACAA,cAAgBpF,aAAaoH,qBAG3BwC,eAAiB5K,EAAE8C,SAEnBkD,SAAW/F,KAAKgG,KAAK,CAAC,CACxBC,WAAY,2BACZC,KAAM,CAAClD,GAAI8H,UAAWjF,OAHX,UAGmBM,cAAAA,kBAC9B,OAEAvC,QAAUK,kBAAkB0G,uBACzB,IAAItC,SAAQ,CAACC,QAASC,UACzBxI,EAAEsG,KAAKC,MAAMvG,EAAGgG,UACXQ,MAAK0F,cAEFzH,cAAcmG,eAAgB/G,eACxBG,KAAOhE,EAAEmM,UAAUD,aAEnB6D,kBAAoB/P,EAAEgE,KAAKgM,SACjCpF,eAAe3D,YAAY8I,mBAG3B/P,YAAKoB,SAASM,sBAAaqJ,sBAAa3J,SAASC,aAAcyF,MAC3D,CAACK,MAAO1D,YACJyB,eAAezB,SAASO,KAAK,UAKvB3B,cACVvB,aAAamP,iBACb,CACIpI,WAAY7D,KACZ8B,OA7BL,UA8BKiK,kBAAmBA,kBAAkBnN,IAAI,IAE7CmN,mBAGOG,kBACPvF,0BACIoF,kBAAmB/P,EAAEoB,SAASM,UAAY,IAAMqJ,WAChD/G,KACA9C,WACA6J,WAGRxC,QAAQvE,SACT8D,MAAKC,KAEU1F,cACV,6BACA,CAAC4F,UAAWF,GAAIjC,OAhDjB,WAiDC8E,gBAEOsF,kBACP/P,aAAa8H,UAAUF,IAE3BS"} \ No newline at end of file diff --git a/course/amd/build/activitychooser.min.js b/course/amd/build/activitychooser.min.js index 054731e7e49..d67954d0ab6 100644 --- a/course/amd/build/activitychooser.min.js +++ b/course/amd/build/activitychooser.min.js @@ -1,10 +1,10 @@ -define("core_course/activitychooser",["exports","core_course/local/activitychooser/dialogue","core_course/local/activitychooser/repository","core_course/local/activitychooser/selectors","core/custom_interaction_events","core/templates","core/modal_factory","core/str","core/pending"],(function(_exports,ChooserDialogue,Repository,_selectors,_custom_interaction_events,Templates,ModalFactory,_str,_pending){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireWildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}return newObj.default=obj,cache&&cache.set(obj,newObj),newObj} +define("core_course/activitychooser",["exports","core_course/local/activitychooser/dialogue","core_course/local/activitychooser/repository","core_course/local/activitychooser/selectors","core/custom_interaction_events","core/templates","core/str","core/modal","core/pending"],(function(_exports,ChooserDialogue,Repository,_selectors,_custom_interaction_events,Templates,_str,_modal,_pending){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireWildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}return newObj.default=obj,cache&&cache.set(obj,newObj),newObj} /** * A type of dialogue used as for choosing modules in a course. * * @module core_course/activitychooser * @copyright 2020 Mathew May * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,ChooserDialogue=_interopRequireWildcard(ChooserDialogue),Repository=_interopRequireWildcard(Repository),_selectors=_interopRequireDefault(_selectors),_custom_interaction_events=_interopRequireDefault(_custom_interaction_events),Templates=_interopRequireWildcard(Templates),ModalFactory=_interopRequireWildcard(ModalFactory),_pending=_interopRequireDefault(_pending);let initialized=!1;_exports.init=(courseId,chooserConfig)=>{const pendingPromise=new _pending.default;registerListenerEvents(courseId,chooserConfig),pendingPromise.resolve()};const registerListenerEvents=(courseId,chooserConfig)=>{if(initialized)return;const events=["click",_custom_interaction_events.default.events.activate,_custom_interaction_events.default.events.keyboardActivate],fetchModuleData=(()=>{let innerPromise=null;return()=>(innerPromise||(innerPromise=new Promise((resolve=>{resolve(Repository.activityModules(courseId))}))),innerPromise)})(),fetchFooterData=(()=>{let footerInnerPromise=null;return sectionId=>(footerInnerPromise||(footerInnerPromise=new Promise((resolve=>{resolve(Repository.fetchFooterData(courseId,sectionId))}))),footerInnerPromise)})();_custom_interaction_events.default.define(document,events),events.forEach((event=>{document.addEventListener(event,(async e=>{if(e.target.closest(_selectors.default.elements.sectionmodchooser)){let caller;const sectionDiv=e.target.closest(_selectors.default.elements.section),button=e.target.closest(_selectors.default.elements.sectionmodchooser);let bodyPromiseResolver;caller=null!==sectionDiv&§ionDiv.hasAttribute("data-sectionid")?sectionDiv:button;const bodyPromise=new Promise((resolve=>{bodyPromiseResolver=resolve})),footerData=await fetchFooterData(caller.dataset.sectionid),sectionModal=buildModal(bodyPromise,footerData),data=await fetchModuleData().catch((async e=>{const errorTemplateData={errormessage:e.message};bodyPromiseResolver(await Templates.render("core_course/local/activitychooser/error",errorTemplateData))}));if(!data)return;const builtModuleData=sectionIdMapper(data,caller.dataset.sectionid,caller.dataset.sectionreturnid,caller.dataset.beforemod);ChooserDialogue.displayChooser(sectionModal,builtModuleData,partiallyAppliedFavouriteManager(data,caller.dataset.sectionid),footerData),bodyPromiseResolver(await Templates.render("core_course/activitychooser",templateDataBuilder(builtModuleData,chooserConfig)))}}))})),initialized=!0},sectionIdMapper=(webServiceData,id,sectionreturnid,beforemod)=>{const newData=JSON.parse(JSON.stringify(webServiceData));return newData.content_items.forEach((module=>{module.link+="§ion="+id+"&sr="+(null!=sectionreturnid?sectionreturnid:0)+"&beforemod="+(null!=beforemod?beforemod:0)})),newData.content_items},templateDataBuilder=(data,chooserConfig)=>{let activities=[],resources=[],showAll=!0,showActivities=!1,showResources=!1;const tabMode=parseInt(chooserConfig.tabmode),favourites=data.filter((mod=>!0===mod.favourite)),recommended=data.filter((mod=>!0===mod.recommended));(tabMode=>-1!==[0,3,2,5].indexOf(tabMode))(tabMode)&&(activities=data.filter((mod=>0===mod.archetype)),resources=data.filter((mod=>1===mod.archetype)),showActivities=!0,showResources=!0,2!==tabMode&&5!==tabMode||(showAll=!1));const recommendedBeginning=-1!==[3,4,5].indexOf(tabMode),favouritesFirst=!!favourites.length,recommendedFirst=!1===favouritesFirst&&!0===recommendedBeginning&&!!recommended.length;return{default:data,showAll:showAll,activities:activities,showActivities:showActivities,activitiesFirst:!1===showAll&&!1===favouritesFirst&&!1===recommendedFirst,resources:resources,showResources:showResources,favourites:favourites,recommended:recommended,recommendedFirst:recommendedFirst,recommendedBeginning:recommendedBeginning,favouritesFirst:favouritesFirst,fallback:!0===showAll&&!1===favouritesFirst&&!1===recommendedFirst}},buildModal=(bodyPromise,footer)=>ModalFactory.create({type:ModalFactory.types.DEFAULT,title:(0,_str.getString)("addresourceoractivity"),body:bodyPromise,footer:footer.customfootertemplate,large:!0,scrollable:!1,templateContext:{classes:"modchooser"}}).then((modal=>(modal.show(),modal))),partiallyAppliedFavouriteManager=(moduleData,sectionId)=>async(internal,favourite,modalBody)=>{const favouriteArea=modalBody.querySelector(_selectors.default.render.favourites),favouriteButtons=modalBody.querySelectorAll('[data-internal="'.concat(internal,'"] ').concat(_selectors.default.actions.optionActions.manageFavourite)),favouriteTabNav=modalBody.querySelector(_selectors.default.regions.favouriteTabNav),result=moduleData.content_items.find((_ref=>{let{name:name}=_ref;return name===internal})),newFaves={};if(result)if(favourite){result.favourite=!0,newFaves.content_items=moduleData.content_items.filter((mod=>!0===mod.favourite));const builtFaves=sectionIdMapper(newFaves,sectionId),{html:html,js:js}=await Templates.renderForPromise("core_course/local/activitychooser/favourites",{favourites:builtFaves});await Templates.replaceNodeContents(favouriteArea,html,js),Array.from(favouriteButtons).forEach((element=>{element.classList.remove("text-muted"),element.classList.add("text-primary"),element.dataset.favourited="true",element.setAttribute("aria-pressed",!0),element.firstElementChild.classList.remove("fa-star-o"),element.firstElementChild.classList.add("fa-star")})),favouriteTabNav.classList.remove("d-none")}else{result.favourite=!1;const nodeToRemove=favouriteArea.querySelector('[data-internal="'.concat(internal,'"]'));nodeToRemove.parentNode.removeChild(nodeToRemove),Array.from(favouriteButtons).forEach((element=>{element.classList.add("text-muted"),element.classList.remove("text-primary"),element.dataset.favourited="false",element.setAttribute("aria-pressed",!1),element.firstElementChild.classList.remove("fa-star"),element.firstElementChild.classList.add("fa-star-o")}));0===moduleData.content_items.filter((mod=>!0===mod.favourite)).length&&((favouriteTabNav,modalBody)=>{if(favouriteTabNav.tabIndex=-1,favouriteTabNav.classList.add("d-none"),favouriteTabNav.classList.contains("active")){favouriteTabNav.classList.remove("active"),favouriteTabNav.setAttribute("aria-selected","false"),modalBody.querySelector(_selectors.default.regions.favouriteTab).classList.remove("active");const defaultTabNav=modalBody.querySelector(_selectors.default.regions.defaultTabNav),activitiesTabNav=modalBody.querySelector(_selectors.default.regions.activityTabNav);!1===defaultTabNav.classList.contains("d-none")?(defaultTabNav.classList.add("active"),defaultTabNav.setAttribute("aria-selected","true"),defaultTabNav.tabIndex=0,defaultTabNav.focus(),modalBody.querySelector(_selectors.default.regions.defaultTab).classList.add("active")):(activitiesTabNav.classList.add("active"),activitiesTabNav.setAttribute("aria-selected","true"),activitiesTabNav.tabIndex=0,activitiesTabNav.focus(),modalBody.querySelector(_selectors.default.regions.activityTab).classList.add("active"))}})(favouriteTabNav,modalBody)}}})); + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,ChooserDialogue=_interopRequireWildcard(ChooserDialogue),Repository=_interopRequireWildcard(Repository),_selectors=_interopRequireDefault(_selectors),_custom_interaction_events=_interopRequireDefault(_custom_interaction_events),Templates=_interopRequireWildcard(Templates),_modal=_interopRequireDefault(_modal),_pending=_interopRequireDefault(_pending);let initialized=!1;_exports.init=(courseId,chooserConfig)=>{const pendingPromise=new _pending.default;registerListenerEvents(courseId,chooserConfig),pendingPromise.resolve()};const registerListenerEvents=(courseId,chooserConfig)=>{if(initialized)return;const events=["click",_custom_interaction_events.default.events.activate,_custom_interaction_events.default.events.keyboardActivate],fetchModuleData=(()=>{let innerPromise=null;return()=>(innerPromise||(innerPromise=new Promise((resolve=>{resolve(Repository.activityModules(courseId))}))),innerPromise)})(),fetchFooterData=(()=>{let footerInnerPromise=null;return sectionId=>(footerInnerPromise||(footerInnerPromise=new Promise((resolve=>{resolve(Repository.fetchFooterData(courseId,sectionId))}))),footerInnerPromise)})();_custom_interaction_events.default.define(document,events),events.forEach((event=>{document.addEventListener(event,(async e=>{if(e.target.closest(_selectors.default.elements.sectionmodchooser)){let caller;const sectionDiv=e.target.closest(_selectors.default.elements.section),button=e.target.closest(_selectors.default.elements.sectionmodchooser);let bodyPromiseResolver;caller=null!==sectionDiv&§ionDiv.hasAttribute("data-sectionid")?sectionDiv:button;const bodyPromise=new Promise((resolve=>{bodyPromiseResolver=resolve})),footerData=await fetchFooterData(caller.dataset.sectionid),sectionModal=buildModal(bodyPromise,footerData),data=await fetchModuleData().catch((async e=>{const errorTemplateData={errormessage:e.message};bodyPromiseResolver(await Templates.render("core_course/local/activitychooser/error",errorTemplateData))}));if(!data)return;const builtModuleData=sectionIdMapper(data,caller.dataset.sectionid,caller.dataset.sectionreturnid,caller.dataset.beforemod);ChooserDialogue.displayChooser(sectionModal,builtModuleData,partiallyAppliedFavouriteManager(data,caller.dataset.sectionid),footerData),bodyPromiseResolver(await Templates.render("core_course/activitychooser",templateDataBuilder(builtModuleData,chooserConfig)))}}))})),initialized=!0},sectionIdMapper=(webServiceData,id,sectionreturnid,beforemod)=>{const newData=JSON.parse(JSON.stringify(webServiceData));return newData.content_items.forEach((module=>{module.link+="§ion="+id+"&sr="+(null!=sectionreturnid?sectionreturnid:0)+"&beforemod="+(null!=beforemod?beforemod:0)})),newData.content_items},templateDataBuilder=(data,chooserConfig)=>{let activities=[],resources=[],showAll=!0,showActivities=!1,showResources=!1;const tabMode=parseInt(chooserConfig.tabmode),favourites=data.filter((mod=>!0===mod.favourite)),recommended=data.filter((mod=>!0===mod.recommended));(tabMode=>-1!==[0,3,2,5].indexOf(tabMode))(tabMode)&&(activities=data.filter((mod=>0===mod.archetype)),resources=data.filter((mod=>1===mod.archetype)),showActivities=!0,showResources=!0,2!==tabMode&&5!==tabMode||(showAll=!1));const recommendedBeginning=-1!==[3,4,5].indexOf(tabMode),favouritesFirst=!!favourites.length,recommendedFirst=!1===favouritesFirst&&!0===recommendedBeginning&&!!recommended.length;return{default:data,showAll:showAll,activities:activities,showActivities:showActivities,activitiesFirst:!1===showAll&&!1===favouritesFirst&&!1===recommendedFirst,resources:resources,showResources:showResources,favourites:favourites,recommended:recommended,recommendedFirst:recommendedFirst,recommendedBeginning:recommendedBeginning,favouritesFirst:favouritesFirst,fallback:!0===showAll&&!1===favouritesFirst&&!1===recommendedFirst}},buildModal=(body,footer)=>_modal.default.create({body:body,title:(0,_str.getString)("addresourceoractivity"),footer:footer.customfootertemplate,large:!0,scrollable:!1,templateContext:{classes:"modchooser"},show:!0}),partiallyAppliedFavouriteManager=(moduleData,sectionId)=>async(internal,favourite,modalBody)=>{const favouriteArea=modalBody.querySelector(_selectors.default.render.favourites),favouriteButtons=modalBody.querySelectorAll('[data-internal="'.concat(internal,'"] ').concat(_selectors.default.actions.optionActions.manageFavourite)),favouriteTabNav=modalBody.querySelector(_selectors.default.regions.favouriteTabNav),result=moduleData.content_items.find((_ref=>{let{name:name}=_ref;return name===internal})),newFaves={};if(result)if(favourite){result.favourite=!0,newFaves.content_items=moduleData.content_items.filter((mod=>!0===mod.favourite));const builtFaves=sectionIdMapper(newFaves,sectionId),{html:html,js:js}=await Templates.renderForPromise("core_course/local/activitychooser/favourites",{favourites:builtFaves});await Templates.replaceNodeContents(favouriteArea,html,js),Array.from(favouriteButtons).forEach((element=>{element.classList.remove("text-muted"),element.classList.add("text-primary"),element.dataset.favourited="true",element.setAttribute("aria-pressed",!0),element.firstElementChild.classList.remove("fa-star-o"),element.firstElementChild.classList.add("fa-star")})),favouriteTabNav.classList.remove("d-none")}else{result.favourite=!1;const nodeToRemove=favouriteArea.querySelector('[data-internal="'.concat(internal,'"]'));nodeToRemove.parentNode.removeChild(nodeToRemove),Array.from(favouriteButtons).forEach((element=>{element.classList.add("text-muted"),element.classList.remove("text-primary"),element.dataset.favourited="false",element.setAttribute("aria-pressed",!1),element.firstElementChild.classList.remove("fa-star"),element.firstElementChild.classList.add("fa-star-o")}));0===moduleData.content_items.filter((mod=>!0===mod.favourite)).length&&((favouriteTabNav,modalBody)=>{if(favouriteTabNav.tabIndex=-1,favouriteTabNav.classList.add("d-none"),favouriteTabNav.classList.contains("active")){favouriteTabNav.classList.remove("active"),favouriteTabNav.setAttribute("aria-selected","false"),modalBody.querySelector(_selectors.default.regions.favouriteTab).classList.remove("active");const defaultTabNav=modalBody.querySelector(_selectors.default.regions.defaultTabNav),activitiesTabNav=modalBody.querySelector(_selectors.default.regions.activityTabNav);!1===defaultTabNav.classList.contains("d-none")?(defaultTabNav.classList.add("active"),defaultTabNav.setAttribute("aria-selected","true"),defaultTabNav.tabIndex=0,defaultTabNav.focus(),modalBody.querySelector(_selectors.default.regions.defaultTab).classList.add("active")):(activitiesTabNav.classList.add("active"),activitiesTabNav.setAttribute("aria-selected","true"),activitiesTabNav.tabIndex=0,activitiesTabNav.focus(),modalBody.querySelector(_selectors.default.regions.activityTab).classList.add("active"))}})(favouriteTabNav,modalBody)}}})); //# sourceMappingURL=activitychooser.min.js.map \ No newline at end of file diff --git a/course/amd/build/activitychooser.min.js.map b/course/amd/build/activitychooser.min.js.map index 9eb8b58f57b..1a8212daaf6 100644 --- a/course/amd/build/activitychooser.min.js.map +++ b/course/amd/build/activitychooser.min.js.map @@ -1 +1 @@ -{"version":3,"file":"activitychooser.min.js","sources":["../src/activitychooser.js"],"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 * A type of dialogue used as for choosing modules in a course.\n *\n * @module core_course/activitychooser\n * @copyright 2020 Mathew May \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport * as ChooserDialogue from 'core_course/local/activitychooser/dialogue';\nimport * as Repository from 'core_course/local/activitychooser/repository';\nimport selectors from 'core_course/local/activitychooser/selectors';\nimport CustomEvents from 'core/custom_interaction_events';\nimport * as Templates from 'core/templates';\nimport * as ModalFactory from 'core/modal_factory';\nimport {getString} from 'core/str';\nimport Pending from 'core/pending';\n\n// Set up some JS module wide constants that can be added to in the future.\n\n// Tab config options.\nconst ALLACTIVITIESRESOURCES = 0;\nconst ACTIVITIESRESOURCES = 2;\nconst ALLACTIVITIESRESOURCESREC = 3;\nconst ONLYALLREC = 4;\nconst ACTIVITIESRESOURCESREC = 5;\n\n\n// Module types.\nconst ACTIVITY = 0;\nconst RESOURCE = 1;\n\nlet initialized = false;\n\n/**\n * Set up the activity chooser.\n *\n * @method init\n * @param {Number} courseId Course ID to use later on in fetchModules()\n * @param {Object} chooserConfig Any PHP config settings that we may need to reference\n */\nexport const init = (courseId, chooserConfig) => {\n const pendingPromise = new Pending();\n\n registerListenerEvents(courseId, chooserConfig);\n\n pendingPromise.resolve();\n};\n\n/**\n * Once a selection has been made make the modal & module information and pass it along\n *\n * @method registerListenerEvents\n * @param {Number} courseId\n * @param {Object} chooserConfig Any PHP config settings that we may need to reference\n */\nconst registerListenerEvents = (courseId, chooserConfig) => {\n\n // Ensure we only add our listeners once.\n if (initialized) {\n return;\n }\n\n const events = [\n 'click',\n CustomEvents.events.activate,\n CustomEvents.events.keyboardActivate\n ];\n\n const fetchModuleData = (() => {\n let innerPromise = null;\n\n return () => {\n if (!innerPromise) {\n innerPromise = new Promise((resolve) => {\n resolve(Repository.activityModules(courseId));\n });\n }\n\n return innerPromise;\n };\n })();\n\n const fetchFooterData = (() => {\n let footerInnerPromise = null;\n\n return (sectionId) => {\n if (!footerInnerPromise) {\n footerInnerPromise = new Promise((resolve) => {\n resolve(Repository.fetchFooterData(courseId, sectionId));\n });\n }\n\n return footerInnerPromise;\n };\n })();\n\n CustomEvents.define(document, events);\n\n // Display module chooser event listeners.\n events.forEach((event) => {\n document.addEventListener(event, async(e) => {\n if (e.target.closest(selectors.elements.sectionmodchooser)) {\n let caller;\n // We need to know who called this.\n // Standard courses use the ID in the main section info.\n const sectionDiv = e.target.closest(selectors.elements.section);\n // Front page courses need some special handling.\n const button = e.target.closest(selectors.elements.sectionmodchooser);\n\n // If we don't have a section ID use the fallback ID.\n // We always want the sectionDiv caller first as it keeps track of section ID's after DnD changes.\n // The button attribute is always just a fallback for us as the section div is not always available.\n // A YUI change could be done maybe to only update the button attribute but we are going for minimal change here.\n if (sectionDiv !== null && sectionDiv.hasAttribute('data-sectionid')) {\n // We check for attributes just in case of outdated contrib course formats.\n caller = sectionDiv;\n } else {\n caller = button;\n }\n\n // We want to show the modal instantly but loading whilst waiting for our data.\n let bodyPromiseResolver;\n const bodyPromise = new Promise(resolve => {\n bodyPromiseResolver = resolve;\n });\n\n const footerData = await fetchFooterData(caller.dataset.sectionid);\n const sectionModal = buildModal(bodyPromise, footerData);\n\n // Now we have a modal we should start fetching data.\n // If an error occurs while fetching the data, display the error within the modal.\n const data = await fetchModuleData().catch(async(e) => {\n const errorTemplateData = {\n 'errormessage': e.message\n };\n bodyPromiseResolver(await Templates.render('core_course/local/activitychooser/error', errorTemplateData));\n });\n\n // Early return if there is no module data.\n if (!data) {\n return;\n }\n\n // Apply the section id to all the module instance links.\n const builtModuleData = sectionIdMapper(\n data,\n caller.dataset.sectionid,\n caller.dataset.sectionreturnid,\n caller.dataset.beforemod\n );\n\n ChooserDialogue.displayChooser(\n sectionModal,\n builtModuleData,\n partiallyAppliedFavouriteManager(data, caller.dataset.sectionid),\n footerData,\n );\n\n bodyPromiseResolver(await Templates.render(\n 'core_course/activitychooser',\n templateDataBuilder(builtModuleData, chooserConfig)\n ));\n }\n });\n });\n\n initialized = true;\n};\n\n/**\n * Given the web service data and an ID we want to make a deep copy\n * of the WS data then add on the section ID to the addoption URL\n *\n * @method sectionIdMapper\n * @param {Object} webServiceData Our original data from the Web service call\n * @param {Number} id The ID of the section we need to append to the links\n * @param {Number|null} sectionreturnid The ID of the section return we need to append to the links\n * @param {Number|null} beforemod The ID of the cm we need to append to the links\n * @return {Array} [modules] with URL's built\n */\nconst sectionIdMapper = (webServiceData, id, sectionreturnid, beforemod) => {\n // We need to take a fresh deep copy of the original data as an object is a reference type.\n const newData = JSON.parse(JSON.stringify(webServiceData));\n newData.content_items.forEach((module) => {\n module.link += '§ion=' + id + '&sr=' + (sectionreturnid ?? 0) + '&beforemod=' + (beforemod ?? 0);\n });\n return newData.content_items;\n};\n\n/**\n * Given an array of modules we want to figure out where & how to place them into our template object\n *\n * @method templateDataBuilder\n * @param {Array} data our modules to manipulate into a Templatable object\n * @param {Object} chooserConfig Any PHP config settings that we may need to reference\n * @return {Object} Our built object ready to render out\n */\nconst templateDataBuilder = (data, chooserConfig) => {\n // Setup of various bits and pieces we need to mutate before throwing it to the wolves.\n let activities = [];\n let resources = [];\n let showAll = true;\n let showActivities = false;\n let showResources = false;\n\n // Tab mode can be the following [All, Resources & Activities, All & Activities & Resources].\n const tabMode = parseInt(chooserConfig.tabmode);\n\n // Filter the incoming data to find favourite & recommended modules.\n const favourites = data.filter(mod => mod.favourite === true);\n const recommended = data.filter(mod => mod.recommended === true);\n\n // Whether the activities and resources tabs should be displayed or not.\n const showActivitiesAndResources = (tabMode) => {\n const acceptableModes = [\n ALLACTIVITIESRESOURCES,\n ALLACTIVITIESRESOURCESREC,\n ACTIVITIESRESOURCES,\n ACTIVITIESRESOURCESREC,\n ];\n\n return acceptableModes.indexOf(tabMode) !== -1;\n };\n\n // These modes need Activity & Resource tabs.\n if (showActivitiesAndResources(tabMode)) {\n // Filter the incoming data to find activities then resources.\n activities = data.filter(mod => mod.archetype === ACTIVITY);\n resources = data.filter(mod => mod.archetype === RESOURCE);\n showActivities = true;\n showResources = true;\n\n // We want all of the previous information but no 'All' tab.\n if (tabMode === ACTIVITIESRESOURCES || tabMode === ACTIVITIESRESOURCESREC) {\n showAll = false;\n }\n }\n\n const recommendedBeforeTabs = [\n ALLACTIVITIESRESOURCESREC,\n ONLYALLREC,\n ACTIVITIESRESOURCESREC,\n ];\n // Whether the recommended tab should be displayed before the All/Activities/Resources tabs.\n const recommendedBeginning = recommendedBeforeTabs.indexOf(tabMode) !== -1;\n\n // Given the results of the above filters lets figure out what tab to set active.\n // We have some favourites.\n const favouritesFirst = !!favourites.length;\n const recommendedFirst = favouritesFirst === false && recommendedBeginning === true && !!recommended.length;\n // We are in tabMode 2 without any favourites.\n const activitiesFirst = showAll === false && favouritesFirst === false && recommendedFirst === false;\n // We have nothing fallback to show all modules.\n const fallback = showAll === true && favouritesFirst === false && recommendedFirst === false;\n\n return {\n 'default': data,\n showAll: showAll,\n activities: activities,\n showActivities: showActivities,\n activitiesFirst: activitiesFirst,\n resources: resources,\n showResources: showResources,\n favourites: favourites,\n recommended: recommended,\n recommendedFirst: recommendedFirst,\n recommendedBeginning: recommendedBeginning,\n favouritesFirst: favouritesFirst,\n fallback: fallback,\n };\n};\n\n/**\n * Given an object we want to build a modal ready to show\n *\n * @method buildModal\n * @param {Promise} bodyPromise\n * @param {String|Boolean} footer Either a footer to add or nothing\n * @return {Object} The modal ready to display immediately and render body in later.\n */\nconst buildModal = (bodyPromise, footer) => {\n return ModalFactory.create({\n type: ModalFactory.types.DEFAULT,\n title: getString('addresourceoractivity'),\n body: bodyPromise,\n footer: footer.customfootertemplate,\n large: true,\n scrollable: false,\n templateContext: {\n classes: 'modchooser'\n }\n })\n .then(modal => {\n modal.show();\n return modal;\n });\n};\n\n/**\n * A small helper function to handle the case where there are no more favourites\n * and we need to mess a bit with the available tabs in the chooser\n *\n * @method nullFavouriteDomManager\n * @param {HTMLElement} favouriteTabNav Dom node of the favourite tab nav\n * @param {HTMLElement} modalBody Our current modals' body\n */\nconst nullFavouriteDomManager = (favouriteTabNav, modalBody) => {\n favouriteTabNav.tabIndex = -1;\n favouriteTabNav.classList.add('d-none');\n // Need to set active to an available tab.\n if (favouriteTabNav.classList.contains('active')) {\n favouriteTabNav.classList.remove('active');\n favouriteTabNav.setAttribute('aria-selected', 'false');\n const favouriteTab = modalBody.querySelector(selectors.regions.favouriteTab);\n favouriteTab.classList.remove('active');\n const defaultTabNav = modalBody.querySelector(selectors.regions.defaultTabNav);\n const activitiesTabNav = modalBody.querySelector(selectors.regions.activityTabNav);\n if (defaultTabNav.classList.contains('d-none') === false) {\n defaultTabNav.classList.add('active');\n defaultTabNav.setAttribute('aria-selected', 'true');\n defaultTabNav.tabIndex = 0;\n defaultTabNav.focus();\n const defaultTab = modalBody.querySelector(selectors.regions.defaultTab);\n defaultTab.classList.add('active');\n } else {\n activitiesTabNav.classList.add('active');\n activitiesTabNav.setAttribute('aria-selected', 'true');\n activitiesTabNav.tabIndex = 0;\n activitiesTabNav.focus();\n const activitiesTab = modalBody.querySelector(selectors.regions.activityTab);\n activitiesTab.classList.add('active');\n }\n\n }\n};\n\n/**\n * Export a curried function where the builtModules has been applied.\n * We have our array of modules so we can rerender the favourites area and have all of the items sorted.\n *\n * @method partiallyAppliedFavouriteManager\n * @param {Array} moduleData This is our raw WS data that we need to manipulate\n * @param {Number} sectionId We need this to add the sectionID to the URL's in the faves area after rerender\n * @return {Function} partially applied function so we can manipulate DOM nodes easily & update our internal array\n */\nconst partiallyAppliedFavouriteManager = (moduleData, sectionId) => {\n /**\n * Curried function that is being returned.\n *\n * @param {String} internal Internal name of the module to manage\n * @param {Boolean} favourite Is the caller adding a favourite or removing one?\n * @param {HTMLElement} modalBody What we need to update whilst we are here\n */\n return async(internal, favourite, modalBody) => {\n const favouriteArea = modalBody.querySelector(selectors.render.favourites);\n\n // eslint-disable-next-line max-len\n const favouriteButtons = modalBody.querySelectorAll(`[data-internal=\"${internal}\"] ${selectors.actions.optionActions.manageFavourite}`);\n const favouriteTabNav = modalBody.querySelector(selectors.regions.favouriteTabNav);\n const result = moduleData.content_items.find(({name}) => name === internal);\n const newFaves = {};\n if (result) {\n if (favourite) {\n result.favourite = true;\n\n // eslint-disable-next-line camelcase\n newFaves.content_items = moduleData.content_items.filter(mod => mod.favourite === true);\n\n const builtFaves = sectionIdMapper(newFaves, sectionId);\n\n const {html, js} = await Templates.renderForPromise('core_course/local/activitychooser/favourites',\n {favourites: builtFaves});\n\n await Templates.replaceNodeContents(favouriteArea, html, js);\n\n Array.from(favouriteButtons).forEach((element) => {\n element.classList.remove('text-muted');\n element.classList.add('text-primary');\n element.dataset.favourited = 'true';\n element.setAttribute('aria-pressed', true);\n element.firstElementChild.classList.remove('fa-star-o');\n element.firstElementChild.classList.add('fa-star');\n });\n\n favouriteTabNav.classList.remove('d-none');\n } else {\n result.favourite = false;\n\n const nodeToRemove = favouriteArea.querySelector(`[data-internal=\"${internal}\"]`);\n\n nodeToRemove.parentNode.removeChild(nodeToRemove);\n\n Array.from(favouriteButtons).forEach((element) => {\n element.classList.add('text-muted');\n element.classList.remove('text-primary');\n element.dataset.favourited = 'false';\n element.setAttribute('aria-pressed', false);\n element.firstElementChild.classList.remove('fa-star');\n element.firstElementChild.classList.add('fa-star-o');\n });\n const newFaves = moduleData.content_items.filter(mod => mod.favourite === true);\n\n if (newFaves.length === 0) {\n nullFavouriteDomManager(favouriteTabNav, modalBody);\n }\n }\n }\n };\n};\n"],"names":["initialized","courseId","chooserConfig","pendingPromise","Pending","registerListenerEvents","resolve","events","CustomEvents","activate","keyboardActivate","fetchModuleData","innerPromise","Promise","Repository","activityModules","fetchFooterData","footerInnerPromise","sectionId","define","document","forEach","event","addEventListener","async","e","target","closest","selectors","elements","sectionmodchooser","caller","sectionDiv","section","button","bodyPromiseResolver","hasAttribute","bodyPromise","footerData","dataset","sectionid","sectionModal","buildModal","data","catch","errorTemplateData","message","Templates","render","builtModuleData","sectionIdMapper","sectionreturnid","beforemod","ChooserDialogue","displayChooser","partiallyAppliedFavouriteManager","templateDataBuilder","webServiceData","id","newData","JSON","parse","stringify","content_items","module","link","activities","resources","showAll","showActivities","showResources","tabMode","parseInt","tabmode","favourites","filter","mod","favourite","recommended","indexOf","showActivitiesAndResources","archetype","recommendedBeginning","favouritesFirst","length","recommendedFirst","activitiesFirst","fallback","footer","ModalFactory","create","type","types","DEFAULT","title","body","customfootertemplate","large","scrollable","templateContext","classes","then","modal","show","moduleData","internal","modalBody","favouriteArea","querySelector","favouriteButtons","querySelectorAll","actions","optionActions","manageFavourite","favouriteTabNav","regions","result","find","_ref","name","newFaves","builtFaves","html","js","renderForPromise","replaceNodeContents","Array","from","element","classList","remove","add","favourited","setAttribute","firstElementChild","nodeToRemove","parentNode","removeChild","tabIndex","contains","favouriteTab","defaultTabNav","activitiesTabNav","activityTabNav","focus","defaultTab","activityTab","nullFavouriteDomManager"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"activitychooser.min.js","sources":["../src/activitychooser.js"],"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 * A type of dialogue used as for choosing modules in a course.\n *\n * @module core_course/activitychooser\n * @copyright 2020 Mathew May \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport * as ChooserDialogue from 'core_course/local/activitychooser/dialogue';\nimport * as Repository from 'core_course/local/activitychooser/repository';\nimport selectors from 'core_course/local/activitychooser/selectors';\nimport CustomEvents from 'core/custom_interaction_events';\nimport * as Templates from 'core/templates';\nimport {getString} from 'core/str';\nimport Modal from 'core/modal';\nimport Pending from 'core/pending';\n\n// Set up some JS module wide constants that can be added to in the future.\n\n// Tab config options.\nconst ALLACTIVITIESRESOURCES = 0;\nconst ACTIVITIESRESOURCES = 2;\nconst ALLACTIVITIESRESOURCESREC = 3;\nconst ONLYALLREC = 4;\nconst ACTIVITIESRESOURCESREC = 5;\n\n\n// Module types.\nconst ACTIVITY = 0;\nconst RESOURCE = 1;\n\nlet initialized = false;\n\n/**\n * Set up the activity chooser.\n *\n * @method init\n * @param {Number} courseId Course ID to use later on in fetchModules()\n * @param {Object} chooserConfig Any PHP config settings that we may need to reference\n */\nexport const init = (courseId, chooserConfig) => {\n const pendingPromise = new Pending();\n\n registerListenerEvents(courseId, chooserConfig);\n\n pendingPromise.resolve();\n};\n\n/**\n * Once a selection has been made make the modal & module information and pass it along\n *\n * @method registerListenerEvents\n * @param {Number} courseId\n * @param {Object} chooserConfig Any PHP config settings that we may need to reference\n */\nconst registerListenerEvents = (courseId, chooserConfig) => {\n\n // Ensure we only add our listeners once.\n if (initialized) {\n return;\n }\n\n const events = [\n 'click',\n CustomEvents.events.activate,\n CustomEvents.events.keyboardActivate\n ];\n\n const fetchModuleData = (() => {\n let innerPromise = null;\n\n return () => {\n if (!innerPromise) {\n innerPromise = new Promise((resolve) => {\n resolve(Repository.activityModules(courseId));\n });\n }\n\n return innerPromise;\n };\n })();\n\n const fetchFooterData = (() => {\n let footerInnerPromise = null;\n\n return (sectionId) => {\n if (!footerInnerPromise) {\n footerInnerPromise = new Promise((resolve) => {\n resolve(Repository.fetchFooterData(courseId, sectionId));\n });\n }\n\n return footerInnerPromise;\n };\n })();\n\n CustomEvents.define(document, events);\n\n // Display module chooser event listeners.\n events.forEach((event) => {\n document.addEventListener(event, async(e) => {\n if (e.target.closest(selectors.elements.sectionmodchooser)) {\n let caller;\n // We need to know who called this.\n // Standard courses use the ID in the main section info.\n const sectionDiv = e.target.closest(selectors.elements.section);\n // Front page courses need some special handling.\n const button = e.target.closest(selectors.elements.sectionmodchooser);\n\n // If we don't have a section ID use the fallback ID.\n // We always want the sectionDiv caller first as it keeps track of section ID's after DnD changes.\n // The button attribute is always just a fallback for us as the section div is not always available.\n // A YUI change could be done maybe to only update the button attribute but we are going for minimal change here.\n if (sectionDiv !== null && sectionDiv.hasAttribute('data-sectionid')) {\n // We check for attributes just in case of outdated contrib course formats.\n caller = sectionDiv;\n } else {\n caller = button;\n }\n\n // We want to show the modal instantly but loading whilst waiting for our data.\n let bodyPromiseResolver;\n const bodyPromise = new Promise(resolve => {\n bodyPromiseResolver = resolve;\n });\n\n const footerData = await fetchFooterData(caller.dataset.sectionid);\n const sectionModal = buildModal(bodyPromise, footerData);\n\n // Now we have a modal we should start fetching data.\n // If an error occurs while fetching the data, display the error within the modal.\n const data = await fetchModuleData().catch(async(e) => {\n const errorTemplateData = {\n 'errormessage': e.message\n };\n bodyPromiseResolver(await Templates.render('core_course/local/activitychooser/error', errorTemplateData));\n });\n\n // Early return if there is no module data.\n if (!data) {\n return;\n }\n\n // Apply the section id to all the module instance links.\n const builtModuleData = sectionIdMapper(\n data,\n caller.dataset.sectionid,\n caller.dataset.sectionreturnid,\n caller.dataset.beforemod\n );\n\n ChooserDialogue.displayChooser(\n sectionModal,\n builtModuleData,\n partiallyAppliedFavouriteManager(data, caller.dataset.sectionid),\n footerData,\n );\n\n bodyPromiseResolver(await Templates.render(\n 'core_course/activitychooser',\n templateDataBuilder(builtModuleData, chooserConfig)\n ));\n }\n });\n });\n\n initialized = true;\n};\n\n/**\n * Given the web service data and an ID we want to make a deep copy\n * of the WS data then add on the section ID to the addoption URL\n *\n * @method sectionIdMapper\n * @param {Object} webServiceData Our original data from the Web service call\n * @param {Number} id The ID of the section we need to append to the links\n * @param {Number|null} sectionreturnid The ID of the section return we need to append to the links\n * @param {Number|null} beforemod The ID of the cm we need to append to the links\n * @return {Array} [modules] with URL's built\n */\nconst sectionIdMapper = (webServiceData, id, sectionreturnid, beforemod) => {\n // We need to take a fresh deep copy of the original data as an object is a reference type.\n const newData = JSON.parse(JSON.stringify(webServiceData));\n newData.content_items.forEach((module) => {\n module.link += '§ion=' + id + '&sr=' + (sectionreturnid ?? 0) + '&beforemod=' + (beforemod ?? 0);\n });\n return newData.content_items;\n};\n\n/**\n * Given an array of modules we want to figure out where & how to place them into our template object\n *\n * @method templateDataBuilder\n * @param {Array} data our modules to manipulate into a Templatable object\n * @param {Object} chooserConfig Any PHP config settings that we may need to reference\n * @return {Object} Our built object ready to render out\n */\nconst templateDataBuilder = (data, chooserConfig) => {\n // Setup of various bits and pieces we need to mutate before throwing it to the wolves.\n let activities = [];\n let resources = [];\n let showAll = true;\n let showActivities = false;\n let showResources = false;\n\n // Tab mode can be the following [All, Resources & Activities, All & Activities & Resources].\n const tabMode = parseInt(chooserConfig.tabmode);\n\n // Filter the incoming data to find favourite & recommended modules.\n const favourites = data.filter(mod => mod.favourite === true);\n const recommended = data.filter(mod => mod.recommended === true);\n\n // Whether the activities and resources tabs should be displayed or not.\n const showActivitiesAndResources = (tabMode) => {\n const acceptableModes = [\n ALLACTIVITIESRESOURCES,\n ALLACTIVITIESRESOURCESREC,\n ACTIVITIESRESOURCES,\n ACTIVITIESRESOURCESREC,\n ];\n\n return acceptableModes.indexOf(tabMode) !== -1;\n };\n\n // These modes need Activity & Resource tabs.\n if (showActivitiesAndResources(tabMode)) {\n // Filter the incoming data to find activities then resources.\n activities = data.filter(mod => mod.archetype === ACTIVITY);\n resources = data.filter(mod => mod.archetype === RESOURCE);\n showActivities = true;\n showResources = true;\n\n // We want all of the previous information but no 'All' tab.\n if (tabMode === ACTIVITIESRESOURCES || tabMode === ACTIVITIESRESOURCESREC) {\n showAll = false;\n }\n }\n\n const recommendedBeforeTabs = [\n ALLACTIVITIESRESOURCESREC,\n ONLYALLREC,\n ACTIVITIESRESOURCESREC,\n ];\n // Whether the recommended tab should be displayed before the All/Activities/Resources tabs.\n const recommendedBeginning = recommendedBeforeTabs.indexOf(tabMode) !== -1;\n\n // Given the results of the above filters lets figure out what tab to set active.\n // We have some favourites.\n const favouritesFirst = !!favourites.length;\n const recommendedFirst = favouritesFirst === false && recommendedBeginning === true && !!recommended.length;\n // We are in tabMode 2 without any favourites.\n const activitiesFirst = showAll === false && favouritesFirst === false && recommendedFirst === false;\n // We have nothing fallback to show all modules.\n const fallback = showAll === true && favouritesFirst === false && recommendedFirst === false;\n\n return {\n 'default': data,\n showAll: showAll,\n activities: activities,\n showActivities: showActivities,\n activitiesFirst: activitiesFirst,\n resources: resources,\n showResources: showResources,\n favourites: favourites,\n recommended: recommended,\n recommendedFirst: recommendedFirst,\n recommendedBeginning: recommendedBeginning,\n favouritesFirst: favouritesFirst,\n fallback: fallback,\n };\n};\n\n/**\n * Given an object we want to build a modal ready to show\n *\n * @method buildModal\n * @param {Promise} body\n * @param {String|Boolean} footer Either a footer to add or nothing\n * @return {Object} The modal ready to display immediately and render body in later.\n */\nconst buildModal = (body, footer) => Modal.create({\n body,\n title: getString('addresourceoractivity'),\n footer: footer.customfootertemplate,\n large: true,\n scrollable: false,\n templateContext: {\n classes: 'modchooser'\n },\n show: true,\n});\n\n/**\n * A small helper function to handle the case where there are no more favourites\n * and we need to mess a bit with the available tabs in the chooser\n *\n * @method nullFavouriteDomManager\n * @param {HTMLElement} favouriteTabNav Dom node of the favourite tab nav\n * @param {HTMLElement} modalBody Our current modals' body\n */\nconst nullFavouriteDomManager = (favouriteTabNav, modalBody) => {\n favouriteTabNav.tabIndex = -1;\n favouriteTabNav.classList.add('d-none');\n // Need to set active to an available tab.\n if (favouriteTabNav.classList.contains('active')) {\n favouriteTabNav.classList.remove('active');\n favouriteTabNav.setAttribute('aria-selected', 'false');\n const favouriteTab = modalBody.querySelector(selectors.regions.favouriteTab);\n favouriteTab.classList.remove('active');\n const defaultTabNav = modalBody.querySelector(selectors.regions.defaultTabNav);\n const activitiesTabNav = modalBody.querySelector(selectors.regions.activityTabNav);\n if (defaultTabNav.classList.contains('d-none') === false) {\n defaultTabNav.classList.add('active');\n defaultTabNav.setAttribute('aria-selected', 'true');\n defaultTabNav.tabIndex = 0;\n defaultTabNav.focus();\n const defaultTab = modalBody.querySelector(selectors.regions.defaultTab);\n defaultTab.classList.add('active');\n } else {\n activitiesTabNav.classList.add('active');\n activitiesTabNav.setAttribute('aria-selected', 'true');\n activitiesTabNav.tabIndex = 0;\n activitiesTabNav.focus();\n const activitiesTab = modalBody.querySelector(selectors.regions.activityTab);\n activitiesTab.classList.add('active');\n }\n\n }\n};\n\n/**\n * Export a curried function where the builtModules has been applied.\n * We have our array of modules so we can rerender the favourites area and have all of the items sorted.\n *\n * @method partiallyAppliedFavouriteManager\n * @param {Array} moduleData This is our raw WS data that we need to manipulate\n * @param {Number} sectionId We need this to add the sectionID to the URL's in the faves area after rerender\n * @return {Function} partially applied function so we can manipulate DOM nodes easily & update our internal array\n */\nconst partiallyAppliedFavouriteManager = (moduleData, sectionId) => {\n /**\n * Curried function that is being returned.\n *\n * @param {String} internal Internal name of the module to manage\n * @param {Boolean} favourite Is the caller adding a favourite or removing one?\n * @param {HTMLElement} modalBody What we need to update whilst we are here\n */\n return async(internal, favourite, modalBody) => {\n const favouriteArea = modalBody.querySelector(selectors.render.favourites);\n\n // eslint-disable-next-line max-len\n const favouriteButtons = modalBody.querySelectorAll(`[data-internal=\"${internal}\"] ${selectors.actions.optionActions.manageFavourite}`);\n const favouriteTabNav = modalBody.querySelector(selectors.regions.favouriteTabNav);\n const result = moduleData.content_items.find(({name}) => name === internal);\n const newFaves = {};\n if (result) {\n if (favourite) {\n result.favourite = true;\n\n // eslint-disable-next-line camelcase\n newFaves.content_items = moduleData.content_items.filter(mod => mod.favourite === true);\n\n const builtFaves = sectionIdMapper(newFaves, sectionId);\n\n const {html, js} = await Templates.renderForPromise('core_course/local/activitychooser/favourites',\n {favourites: builtFaves});\n\n await Templates.replaceNodeContents(favouriteArea, html, js);\n\n Array.from(favouriteButtons).forEach((element) => {\n element.classList.remove('text-muted');\n element.classList.add('text-primary');\n element.dataset.favourited = 'true';\n element.setAttribute('aria-pressed', true);\n element.firstElementChild.classList.remove('fa-star-o');\n element.firstElementChild.classList.add('fa-star');\n });\n\n favouriteTabNav.classList.remove('d-none');\n } else {\n result.favourite = false;\n\n const nodeToRemove = favouriteArea.querySelector(`[data-internal=\"${internal}\"]`);\n\n nodeToRemove.parentNode.removeChild(nodeToRemove);\n\n Array.from(favouriteButtons).forEach((element) => {\n element.classList.add('text-muted');\n element.classList.remove('text-primary');\n element.dataset.favourited = 'false';\n element.setAttribute('aria-pressed', false);\n element.firstElementChild.classList.remove('fa-star');\n element.firstElementChild.classList.add('fa-star-o');\n });\n const newFaves = moduleData.content_items.filter(mod => mod.favourite === true);\n\n if (newFaves.length === 0) {\n nullFavouriteDomManager(favouriteTabNav, modalBody);\n }\n }\n }\n };\n};\n"],"names":["initialized","courseId","chooserConfig","pendingPromise","Pending","registerListenerEvents","resolve","events","CustomEvents","activate","keyboardActivate","fetchModuleData","innerPromise","Promise","Repository","activityModules","fetchFooterData","footerInnerPromise","sectionId","define","document","forEach","event","addEventListener","async","e","target","closest","selectors","elements","sectionmodchooser","caller","sectionDiv","section","button","bodyPromiseResolver","hasAttribute","bodyPromise","footerData","dataset","sectionid","sectionModal","buildModal","data","catch","errorTemplateData","message","Templates","render","builtModuleData","sectionIdMapper","sectionreturnid","beforemod","ChooserDialogue","displayChooser","partiallyAppliedFavouriteManager","templateDataBuilder","webServiceData","id","newData","JSON","parse","stringify","content_items","module","link","activities","resources","showAll","showActivities","showResources","tabMode","parseInt","tabmode","favourites","filter","mod","favourite","recommended","indexOf","showActivitiesAndResources","archetype","recommendedBeginning","favouritesFirst","length","recommendedFirst","activitiesFirst","fallback","body","footer","Modal","create","title","customfootertemplate","large","scrollable","templateContext","classes","show","moduleData","internal","modalBody","favouriteArea","querySelector","favouriteButtons","querySelectorAll","actions","optionActions","manageFavourite","favouriteTabNav","regions","result","find","_ref","name","newFaves","builtFaves","html","js","renderForPromise","replaceNodeContents","Array","from","element","classList","remove","add","favourited","setAttribute","firstElementChild","nodeToRemove","parentNode","removeChild","tabIndex","contains","favouriteTab","defaultTabNav","activitiesTabNav","activityTabNav","focus","defaultTab","activityTab","nullFavouriteDomManager"],"mappings":"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"} \ No newline at end of file diff --git a/course/amd/build/copy_modal.min.js b/course/amd/build/copy_modal.min.js index ae99782a2e8..9e5e5cb8147 100644 --- a/course/amd/build/copy_modal.min.js +++ b/course/amd/build/copy_modal.min.js @@ -1,13 +1,13 @@ +define("core_course/copy_modal",["exports","core/str","core/modal","core/ajax","core/fragment","core/notification","core/config"],(function(_exports,_str,_modal,ajax,Fragment,_notification,Config){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireWildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}return newObj.default=obj,cache&&cache.set(obj,newObj),newObj}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}} /** - * This module provides the course copy modal from the course and - * category management screen. - * - * @module core_course/copy_modal - * @copyright 2020 onward The Moodle Users Association - * @author Matt Porritt - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - * @since 3.9 - */ -define("core_course/copy_modal",["jquery","core/str","core/modal_factory","core/modal_events","core/ajax","core/fragment","core/notification","core/config"],(function($,Str,ModalFactory,ModalEvents,ajax,Fragment,Notification,Config){var contextid,course,modalObj,CopyModal={},spinner='

';function updateModalBody(formdata){void 0===formdata&&(formdata={});var params={jsonformdata:JSON.stringify(formdata),courseid:course.id};modalObj.setBody(spinner),Str.get_string("copycoursetitle","backup",course.shortname).then((function(title){modalObj.setTitle(title),modalObj.setBody(Fragment.loadFragment("course","new_base_form",contextid,params))})).catch((function(){Notification.exception(new Error("Failed to load string: copycoursetitle"))}))}function processModalForm(e){e.preventDefault();var copyform=modalObj.getRoot().find("form").serialize(),formjson=JSON.stringify(copyform),invalid=$.merge(modalObj.getRoot().find('[aria-invalid="true"]'),modalObj.getRoot().find(".error"));invalid.length?invalid.first().focus():ajax.call([{methodname:"core_backup_submit_copy_form",args:{jsonformdata:formjson}}])[0].done((function(){if(modalObj.setBody(spinner),modalObj.hide(),1==e.formredirect){let redirect=Config.wwwroot+"/backup/copyprogress.php?id="+course.id;window.location.assign(redirect)}})).fail((function(){updateModalBody(copyform)}))}return CopyModal.init=function(context){contextid=context,Str.get_string("loading").then((function(title){ModalFactory.create({type:ModalFactory.types.DEFAULT,title:title,body:spinner,large:!0}).done((function(modal){(modalObj=modal).getRoot().on("click","#id_submitreturn",processModalForm),modalObj.getRoot().on("click","#id_submitdisplay",(function(e){e.formredirect=!0,processModalForm(e)})),modalObj.getRoot().on("click","#id_cancel",(function(e){e.preventDefault(),modalObj.setBody(spinner),modalObj.hide()}))}))})).catch((function(){Notification.exception(new Error("Failed to load string: loading"))})),$(".action-copy").on("click",(function(e){e.preventDefault();let url=new URL(this.getAttribute("href")),courseid=new URLSearchParams(url.search).get("id");ajax.call([{methodname:"core_course_get_courses",args:{options:{ids:[courseid]}}}])[0].done((function(response){course=response[0],updateModalBody()})).fail((function(){Notification.exception(new Error("Failed to load course"))})),modalObj.show()}))},CopyModal})); + * This module provides the course copy modal from the course and + * category management screen. + * + * @module core_course/copy_modal + * @copyright 2020 onward The Moodle Users Association + * @author Matt Porritt + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since 3.9 + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_modal=_interopRequireDefault(_modal),ajax=_interopRequireWildcard(ajax),Fragment=_interopRequireWildcard(Fragment),_notification=_interopRequireDefault(_notification),Config=_interopRequireWildcard(Config);class CopyModal{static init(context){return new CopyModal(context)}constructor(context){this.contextid=context,this.registerEventListeners()}registerEventListeners(){document.addEventListener("click",(e=>{const copyAction=e.target.closest(".action-copy");if(!copyAction)return;e.preventDefault();const url=new URL(copyAction.href),params=new URLSearchParams(url.search);this.fetchCourseData(params.get("id")).then((_ref=>{let[course]=_ref;return this.createModal(course)})).catch((error=>_notification.default.exception(error)))}))}fetchCourseData(courseid){return ajax.call([{methodname:"core_course_get_courses",args:{options:{ids:[courseid]}}}])[0]}submitBackupRequest(jsonformdata){return ajax.call([{methodname:"core_backup_submit_copy_form",args:{jsonformdata:jsonformdata}}])[0]}createModal(course){let formdata=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const params={jsonformdata:JSON.stringify(formdata),courseid:course.id};return _modal.default.create({title:(0,_str.get_string)("copycoursetitle","backup",course.shortname),body:Fragment.loadFragment("course","new_base_form",this.contextid,params),large:!0,show:!0,removeOnClose:!0}).then((modal=>(modal.getRoot().on("click","#id_submitreturn",(e=>{this.processModalForm(course,modal,e)})),modal.getRoot().on("click","#id_cancel",(e=>{e.preventDefault(),modal.hide()})),modal.getRoot().on("click","#id_submitdisplay",(e=>{e.formredirect=!0,this.processModalForm(course,modal,e)})),modal)))}processModalForm(course,modal,e){e.preventDefault();const copyform=modal.getRoot().find("form").serialize(),formjson=JSON.stringify(copyform),invalid=modal.getRoot()[0].querySelectorAll('[aria-invalid="true"], .error');invalid.length?invalid[0].focus():(modal.hide(),this.submitBackupRequest(formjson).then((()=>{if(1==e.formredirect){const redirect="".concat(Config.wwwroot,"/backup/copyprogress.php?id=").concat(course.id);window.location.assign(redirect)}})).catch((()=>{this.createModal(course,copyform)})))}}return _exports.default=CopyModal,_exports.default})); //# sourceMappingURL=copy_modal.min.js.map \ No newline at end of file diff --git a/course/amd/build/copy_modal.min.js.map b/course/amd/build/copy_modal.min.js.map index c7adc406ac3..079fc925a3c 100644 --- a/course/amd/build/copy_modal.min.js.map +++ b/course/amd/build/copy_modal.min.js.map @@ -1 +1 @@ -{"version":3,"file":"copy_modal.min.js","sources":["../src/copy_modal.js"],"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 * This module provides the course copy modal from the course and\n * category management screen.\n *\n * @module core_course/copy_modal\n * @copyright 2020 onward The Moodle Users Association \n * @author Matt Porritt \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 3.9\n */\n\ndefine(['jquery', 'core/str', 'core/modal_factory', 'core/modal_events',\n 'core/ajax', 'core/fragment', 'core/notification', 'core/config'],\n function($, Str, ModalFactory, ModalEvents, ajax, Fragment, Notification, Config) {\n\n /**\n * Module level variables.\n */\n var CopyModal = {};\n var contextid;\n var course;\n var modalObj;\n var spinner = '

'\n + ''\n + '

';\n\n /**\n * Creates the modal for the course copy form\n *\n * @private\n */\n function createModal() {\n // Get the Title String.\n Str.get_string('loading').then(function(title) {\n // Create the Modal.\n ModalFactory.create({\n type: ModalFactory.types.DEFAULT,\n title: title,\n body: spinner,\n large: true\n })\n .done(function(modal) {\n modalObj = modal;\n // Explicitly handle form click events.\n modalObj.getRoot().on('click', '#id_submitreturn', processModalForm);\n modalObj.getRoot().on('click', '#id_submitdisplay', function(e) {\n e.formredirect = true;\n processModalForm(e);\n\n });\n modalObj.getRoot().on('click', '#id_cancel', function(e) {\n e.preventDefault();\n modalObj.setBody(spinner);\n modalObj.hide();\n });\n });\n return;\n }).catch(function() {\n Notification.exception(new Error('Failed to load string: loading'));\n });\n }\n\n /**\n * Updates the body of the modal window.\n *\n * @param {Object} formdata\n * @private\n */\n function updateModalBody(formdata) {\n if (typeof formdata === \"undefined\") {\n formdata = {};\n }\n\n var params = {\n 'jsonformdata': JSON.stringify(formdata),\n 'courseid': course.id\n };\n\n modalObj.setBody(spinner);\n Str.get_string('copycoursetitle', 'backup', course.shortname).then(function(title) {\n modalObj.setTitle(title);\n modalObj.setBody(Fragment.loadFragment('course', 'new_base_form', contextid, params));\n return;\n }).catch(function() {\n Notification.exception(new Error('Failed to load string: copycoursetitle'));\n });\n }\n\n /**\n * Updates Moodle form with selected information.\n *\n * @param {Object} e\n * @private\n */\n function processModalForm(e) {\n e.preventDefault(); // Stop modal from closing.\n\n // Form data.\n var copyform = modalObj.getRoot().find('form').serialize();\n var formjson = JSON.stringify(copyform);\n\n // Handle invalid form fields for better UX.\n var invalid = $.merge(\n modalObj.getRoot().find('[aria-invalid=\"true\"]'),\n modalObj.getRoot().find('.error')\n );\n\n if (invalid.length) {\n invalid.first().focus();\n return;\n }\n\n // Submit form via ajax.\n ajax.call([{\n methodname: 'core_backup_submit_copy_form',\n args: {\n jsonformdata: formjson\n },\n }])[0].done(function() {\n // For submission succeeded.\n modalObj.setBody(spinner);\n modalObj.hide();\n\n if (e.formredirect == true) {\n // We are redirecting to copy progress display.\n let redirect = Config.wwwroot + \"/backup/copyprogress.php?id=\" + course.id;\n window.location.assign(redirect);\n }\n\n }).fail(function() {\n // Form submission failed server side, redisplay with errors.\n updateModalBody(copyform);\n });\n }\n\n /**\n * Initialise the class.\n *\n * @method\n * @param {Object} context\n * @public\n */\n CopyModal.init = function(context) {\n contextid = context;\n // Setup the initial Modal.\n createModal();\n\n // Setup the click handlers on the copy buttons.\n $('.action-copy').on('click', function(e) {\n e.preventDefault(); // Stop. Hammer time.\n let url = new URL(this.getAttribute('href'));\n let params = new URLSearchParams(url.search);\n let courseid = params.get('id');\n\n ajax.call([{ // Get the course information.\n methodname: 'core_course_get_courses',\n args: {\n 'options': {'ids': [courseid]},\n },\n }])[0].done(function(response) {\n // We have the course info get the modal content.\n course = response[0];\n updateModalBody();\n\n }).fail(function() {\n Notification.exception(new Error('Failed to load course'));\n });\n\n modalObj.show();\n });\n\n };\n\n return CopyModal;\n});\n"],"names":["define","$","Str","ModalFactory","ModalEvents","ajax","Fragment","Notification","Config","contextid","course","modalObj","CopyModal","spinner","updateModalBody","formdata","params","JSON","stringify","id","setBody","get_string","shortname","then","title","setTitle","loadFragment","catch","exception","Error","processModalForm","e","preventDefault","copyform","getRoot","find","serialize","formjson","invalid","merge","length","first","focus","call","methodname","args","jsonformdata","done","hide","formredirect","redirect","wwwroot","window","location","assign","fail","init","context","create","type","types","DEFAULT","body","large","modal","on","url","URL","this","getAttribute","courseid","URLSearchParams","search","get","response","show"],"mappings":";;;;;;;;;;AA0BAA,gCAAO,CAAC,SAAU,WAAY,qBAAsB,oBAC5C,YAAa,gBAAiB,oBAAqB,gBACnD,SAASC,EAAGC,IAAKC,aAAcC,YAAaC,KAAMC,SAAUC,aAAcC,YAM1EC,UACAC,OACAC,SAHAC,UAAY,GAIZC,QAAU,yFA8CLC,gBAAgBC,eACG,IAAbA,WACPA,SAAW,QAGXC,OAAS,cACWC,KAAKC,UAAUH,mBACnBL,OAAOS,IAG3BR,SAASS,QAAQP,SACjBX,IAAImB,WAAW,kBAAmB,SAAUX,OAAOY,WAAWC,MAAK,SAASC,OACxEb,SAASc,SAASD,OAClBb,SAASS,QAAQd,SAASoB,aAAa,SAAU,gBAAiBjB,UAAWO,YAE9EW,OAAM,WACLpB,aAAaqB,UAAU,IAAIC,MAAM,uDAUhCC,iBAAiBC,GACtBA,EAAEC,qBAGEC,SAAWtB,SAASuB,UAAUC,KAAK,QAAQC,YAC3CC,SAAWpB,KAAKC,UAAUe,UAG1BK,QAAUrC,EAAEsC,MACR5B,SAASuB,UAAUC,KAAK,yBACxBxB,SAASuB,UAAUC,KAAK,WAG5BG,QAAQE,OACRF,QAAQG,QAAQC,QAKpBrC,KAAKsC,KAAK,CAAC,CACPC,WAAY,+BACZC,KAAM,CACFC,aAAcT,aAElB,GAAGU,MAAK,cAERpC,SAASS,QAAQP,SACjBF,SAASqC,OAEa,GAAlBjB,EAAEkB,aAAsB,KAEpBC,SAAW1C,OAAO2C,QAAU,+BAAiCzC,OAAOS,GACxEiC,OAAOC,SAASC,OAAOJ,cAG5BK,MAAK,WAEJzC,gBAAgBmB,oBAWxBrB,UAAU4C,KAAO,SAASC,SACtBhD,UAAYgD,QA9GZvD,IAAImB,WAAW,WAAWE,MAAK,SAASC,OAEpCrB,aAAauD,OAAO,CAChBC,KAAMxD,aAAayD,MAAMC,QACzBrC,MAAOA,MACPsC,KAAMjD,QACNkD,OAAO,IAEVhB,MAAK,SAASiB,QACXrD,SAAWqD,OAEF9B,UAAU+B,GAAG,QAAS,mBAAoBnC,kBACnDnB,SAASuB,UAAU+B,GAAG,QAAS,qBAAqB,SAASlC,GACzDA,EAAEkB,cAAe,EACjBnB,iBAAiBC,MAGrBpB,SAASuB,UAAU+B,GAAG,QAAS,cAAc,SAASlC,GAClDA,EAAEC,iBACFrB,SAASS,QAAQP,SACjBF,SAASqC,gBAIlBrB,OAAM,WACLpB,aAAaqB,UAAU,IAAIC,MAAM,sCA0FrC5B,EAAE,gBAAgBgE,GAAG,SAAS,SAASlC,GACnCA,EAAEC,qBACEkC,IAAM,IAAIC,IAAIC,KAAKC,aAAa,SAEhCC,SADS,IAAIC,gBAAgBL,IAAIM,QACfC,IAAI,MAE1BpE,KAAKsC,KAAK,CAAC,CACPC,WAAY,0BACZC,KAAM,SACS,KAAQ,CAACyB,eAExB,GAAGvB,MAAK,SAAS2B,UAEjBhE,OAASgE,SAAS,GAClB5D,qBAEDyC,MAAK,WACJhD,aAAaqB,UAAU,IAAIC,MAAM,6BAGrClB,SAASgE,WAKV/D"} \ No newline at end of file +{"version":3,"file":"copy_modal.min.js","sources":["../src/copy_modal.js"],"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 * This module provides the course copy modal from the course and\n * category management screen.\n *\n * @module core_course/copy_modal\n * @copyright 2020 onward The Moodle Users Association \n * @author Matt Porritt \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 3.9\n */\n\nimport {get_string as getString} from 'core/str';\nimport Modal from 'core/modal';\nimport * as ajax from 'core/ajax';\nimport * as Fragment from 'core/fragment';\nimport Notification from 'core/notification';\nimport * as Config from 'core/config';\n\nexport default class CopyModal {\n static init(context) {\n return new CopyModal(context);\n }\n\n constructor(context) {\n this.contextid = context;\n\n this.registerEventListeners();\n }\n\n registerEventListeners() {\n document.addEventListener('click', (e) => {\n const copyAction = e.target.closest('.action-copy');\n if (!copyAction) {\n return;\n }\n e.preventDefault(); // Stop. Hammer time.\n\n const url = new URL(copyAction.href);\n const params = new URLSearchParams(url.search);\n\n this.fetchCourseData(params.get('id'))\n .then(([course]) => this.createModal(course))\n .catch((error) => Notification.exception(error));\n });\n }\n\n fetchCourseData(courseid) {\n return ajax.call([{\n methodname: 'core_course_get_courses',\n args: {\n options: {\n ids: [courseid],\n },\n },\n }])[0];\n }\n\n submitBackupRequest(jsonformdata) {\n return ajax.call([{\n methodname: 'core_backup_submit_copy_form',\n args: {\n jsonformdata,\n },\n }])[0];\n }\n\n createModal(\n course,\n formdata = {},\n ) {\n const params = {\n jsonformdata: JSON.stringify(formdata),\n courseid: course.id,\n };\n\n // Create the Modal.\n return Modal.create({\n title: getString('copycoursetitle', 'backup', course.shortname),\n body: Fragment.loadFragment('course', 'new_base_form', this.contextid, params),\n large: true,\n show: true,\n removeOnClose: true,\n })\n .then((modal) => {\n // Explicitly handle form click events.\n modal.getRoot().on('click', '#id_submitreturn', (e) => {\n this.processModalForm(course, modal, e);\n });\n modal.getRoot().on('click', '#id_cancel', (e) => {\n e.preventDefault();\n modal.hide();\n });\n modal.getRoot().on('click', '#id_submitdisplay', (e) => {\n e.formredirect = true;\n this.processModalForm(course, modal, e);\n\n });\n\n return modal;\n });\n }\n\n processModalForm(course, modal, e) {\n e.preventDefault(); // Stop modal from closing.\n\n // Form data.\n const copyform = modal.getRoot().find('form').serialize();\n const formjson = JSON.stringify(copyform);\n\n // Handle invalid form fields for better UX.\n const invalid = modal.getRoot()[0].querySelectorAll('[aria-invalid=\"true\"], .error');\n if (invalid.length) {\n invalid[0].focus();\n return;\n }\n\n modal.hide();\n\n // Submit form via ajax.\n this.submitBackupRequest(formjson)\n .then(() => {\n if (e.formredirect == true) {\n // We are redirecting to copy progress display.\n const redirect = `${Config.wwwroot}/backup/copyprogress.php?id=${course.id}`;\n window.location.assign(redirect);\n }\n\n return;\n })\n .catch(() => {\n // Form submission failed server side, redisplay with errors.\n this.createModal(course, copyform);\n });\n }\n}\n"],"names":["CopyModal","context","constructor","contextid","registerEventListeners","document","addEventListener","e","copyAction","target","closest","preventDefault","url","URL","href","params","URLSearchParams","search","fetchCourseData","get","then","_ref","course","this","createModal","catch","error","Notification","exception","courseid","ajax","call","methodname","args","options","ids","submitBackupRequest","jsonformdata","formdata","JSON","stringify","id","Modal","create","title","shortname","body","Fragment","loadFragment","large","show","removeOnClose","modal","getRoot","on","processModalForm","hide","formredirect","copyform","find","serialize","formjson","invalid","querySelectorAll","length","focus","redirect","Config","wwwroot","window","location","assign"],"mappings":";;;;;;;;;;0SAiCqBA,sBACLC,gBACD,IAAID,UAAUC,SAGzBC,YAAYD,cACHE,UAAYF,aAEZG,yBAGTA,yBACIC,SAASC,iBAAiB,SAAUC,UAC1BC,WAAaD,EAAEE,OAAOC,QAAQ,oBAC/BF,kBAGLD,EAAEI,uBAEIC,IAAM,IAAIC,IAAIL,WAAWM,MACzBC,OAAS,IAAIC,gBAAgBJ,IAAIK,aAElCC,gBAAgBH,OAAOI,IAAI,OAC/BC,MAAKC,WAAEC,oBAAYC,KAAKC,YAAYF,WACpCG,OAAOC,OAAUC,sBAAaC,UAAUF,YAIjDR,gBAAgBW,iBACLC,KAAKC,KAAK,CAAC,CACdC,WAAY,0BACZC,KAAM,CACFC,QAAS,CACLC,IAAK,CAACN,eAGd,GAGRO,oBAAoBC,qBACTP,KAAKC,KAAK,CAAC,CACdC,WAAY,+BACZC,KAAM,CACFI,aAAAA,iBAEJ,GAGRb,YACIF,YACAgB,gEAAW,SAELvB,OAAS,CACXsB,aAAcE,KAAKC,UAAUF,UAC7BT,SAAUP,OAAOmB,WAIdC,eAAMC,OAAO,CAChBC,OAAO,mBAAU,kBAAmB,SAAUtB,OAAOuB,WACrDC,KAAMC,SAASC,aAAa,SAAU,gBAAiBzB,KAAKpB,UAAWY,QACvEkC,OAAO,EACPC,MAAM,EACNC,eAAe,IAElB/B,MAAMgC,QAEHA,MAAMC,UAAUC,GAAG,QAAS,oBAAqB/C,SACxCgD,iBAAiBjC,OAAQ8B,MAAO7C,MAEzC6C,MAAMC,UAAUC,GAAG,QAAS,cAAe/C,IACvCA,EAAEI,iBACFyC,MAAMI,UAEVJ,MAAMC,UAAUC,GAAG,QAAS,qBAAsB/C,IAC9CA,EAAEkD,cAAe,OACZF,iBAAiBjC,OAAQ8B,MAAO7C,MAIlC6C,SAIfG,iBAAiBjC,OAAQ8B,MAAO7C,GAC5BA,EAAEI,uBAGI+C,SAAWN,MAAMC,UAAUM,KAAK,QAAQC,YACxCC,SAAWtB,KAAKC,UAAUkB,UAG1BI,QAAUV,MAAMC,UAAU,GAAGU,iBAAiB,iCAChDD,QAAQE,OACRF,QAAQ,GAAGG,SAIfb,MAAMI,YAGDpB,oBAAoByB,UACxBzC,MAAK,QACoB,GAAlBb,EAAEkD,aAAsB,OAElBS,mBAAcC,OAAOC,+CAAsC9C,OAAOmB,IACxE4B,OAAOC,SAASC,OAAOL,cAK9BzC,OAAM,UAEED,YAAYF,OAAQoC"} \ No newline at end of file diff --git a/course/amd/build/downloadcontent.min.js b/course/amd/build/downloadcontent.min.js index e9138579ce0..16546171b0f 100644 --- a/course/amd/build/downloadcontent.min.js +++ b/course/amd/build/downloadcontent.min.js @@ -1,10 +1,10 @@ -define("core_course/downloadcontent",["exports","core/config","core/custom_interaction_events","core/modal_factory","jquery","core/pending","core/key_codes"],(function(_exports,_config,_custom_interaction_events,ModalFactory,_jquery,_pending,_key_codes){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}} +define("core_course/downloadcontent",["exports","core/config","core/custom_interaction_events","core/modal_save_cancel","jquery","core/pending","core/key_codes"],(function(_exports,_config,_custom_interaction_events,_modal_save_cancel,_jquery,_pending,_key_codes){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}} /** * Functions related to downloading course content. * * @module core_course/downloadcontent * @copyright 2020 Michael Hawkins * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_config=_interopRequireDefault(_config),_custom_interaction_events=_interopRequireDefault(_custom_interaction_events),ModalFactory=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(ModalFactory),_jquery=_interopRequireDefault(_jquery),_pending=_interopRequireDefault(_pending);_exports.init=()=>{const pendingPromise=new _pending.default;(0,_jquery.default)("[data-downloadcourse]").on("click keydown",(e=>{"click"!==e.type&&e.which!==_key_codes.enter&&e.which!==_key_codes.space||(e.preventDefault(),displayDownloadConfirmation(e.currentTarget))})),pendingPromise.resolve()};const displayDownloadConfirmation=downloadModalTrigger=>{ModalFactory.create({title:downloadModalTrigger.dataset.downloadTitle,type:ModalFactory.types.SAVE_CANCEL,body:"

".concat(downloadModalTrigger.dataset.downloadBody,"

"),buttons:{save:downloadModalTrigger.dataset.downloadButtonText},templateContext:{classes:"downloadcoursecontentmodal"}}).then((modal=>{modal.show();const saveButton=document.querySelector('.modal .downloadcoursecontentmodal [data-action="save"]'),cancelButton=document.querySelector('.modal .downloadcoursecontentmodal [data-action="cancel"]'),modalContainer=document.querySelector('.modal[data-region="modal-container"]');(0,_jquery.default)(saveButton).on(_custom_interaction_events.default.events.activate,(e=>downloadContent(e,downloadModalTrigger,modal))),(0,_jquery.default)(cancelButton).on(_custom_interaction_events.default.events.activate,(()=>{modal.destroy()})),modalContainer.querySelector(".downloadcoursecontentmodal")&&(0,_jquery.default)(modalContainer).on(_custom_interaction_events.default.events.activate,(()=>{modal.destroy()}))}))},downloadContent=(e,downloadModalTrigger,modal)=>{e.preventDefault();const downloadForm=document.createElement("form");downloadForm.action=downloadModalTrigger.dataset.downloadLink,downloadForm.method="POST",downloadForm.target="_blank";const downloadSesskey=document.createElement("input");downloadSesskey.name="sesskey",downloadSesskey.value=_config.default.sesskey,downloadForm.appendChild(downloadSesskey),downloadForm.style.display="none",document.body.appendChild(downloadForm),downloadForm.submit(),document.body.removeChild(downloadForm),modal.destroy()}})); + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_config=_interopRequireDefault(_config),_custom_interaction_events=_interopRequireDefault(_custom_interaction_events),_modal_save_cancel=_interopRequireDefault(_modal_save_cancel),_jquery=_interopRequireDefault(_jquery),_pending=_interopRequireDefault(_pending);_exports.init=()=>{const pendingPromise=new _pending.default;(0,_jquery.default)("[data-downloadcourse]").on("click keydown",(e=>{"click"!==e.type&&e.which!==_key_codes.enter&&e.which!==_key_codes.space||(e.preventDefault(),displayDownloadConfirmation(e.currentTarget))})),pendingPromise.resolve()};const displayDownloadConfirmation=downloadModalTrigger=>_modal_save_cancel.default.create({title:downloadModalTrigger.dataset.downloadTitle,body:"

".concat(downloadModalTrigger.dataset.downloadBody,"

"),buttons:{save:downloadModalTrigger.dataset.downloadButtonText},templateContext:{classes:"downloadcoursecontentmodal"}}).then((modal=>{modal.show();const saveButton=document.querySelector('.modal .downloadcoursecontentmodal [data-action="save"]'),cancelButton=document.querySelector('.modal .downloadcoursecontentmodal [data-action="cancel"]'),modalContainer=document.querySelector('.modal[data-region="modal-container"]');return(0,_jquery.default)(saveButton).on(_custom_interaction_events.default.events.activate,(e=>downloadContent(e,downloadModalTrigger,modal))),(0,_jquery.default)(cancelButton).on(_custom_interaction_events.default.events.activate,(()=>{modal.destroy()})),modalContainer.querySelector(".downloadcoursecontentmodal")&&(0,_jquery.default)(modalContainer).on(_custom_interaction_events.default.events.activate,(()=>{modal.destroy()})),modal})),downloadContent=(e,downloadModalTrigger,modal)=>{e.preventDefault();const downloadForm=document.createElement("form");downloadForm.action=downloadModalTrigger.dataset.downloadLink,downloadForm.method="POST",downloadForm.target="_blank";const downloadSesskey=document.createElement("input");downloadSesskey.name="sesskey",downloadSesskey.value=_config.default.sesskey,downloadForm.appendChild(downloadSesskey),downloadForm.style.display="none",document.body.appendChild(downloadForm),downloadForm.submit(),document.body.removeChild(downloadForm),modal.destroy()}})); //# sourceMappingURL=downloadcontent.min.js.map \ No newline at end of file diff --git a/course/amd/build/downloadcontent.min.js.map b/course/amd/build/downloadcontent.min.js.map index 5b7ce783b28..3695b8dfb2c 100644 --- a/course/amd/build/downloadcontent.min.js.map +++ b/course/amd/build/downloadcontent.min.js.map @@ -1 +1 @@ -{"version":3,"file":"downloadcontent.min.js","sources":["../src/downloadcontent.js"],"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 * Functions related to downloading course content.\n *\n * @module core_course/downloadcontent\n * @copyright 2020 Michael Hawkins \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Config from 'core/config';\nimport CustomEvents from 'core/custom_interaction_events';\nimport * as ModalFactory from 'core/modal_factory';\nimport jQuery from 'jquery';\nimport Pending from 'core/pending';\nimport {enter, space} from 'core/key_codes';\n\n/**\n * Set up listener to trigger the download course content modal.\n *\n * @return {void}\n */\nexport const init = () => {\n const pendingPromise = new Pending();\n\n // Add event listeners for click and enter/space keys.\n jQuery('[data-downloadcourse]').on('click keydown', (e) => {\n if (e.type === 'click' || e.which === enter || e.which === space) {\n e.preventDefault();\n displayDownloadConfirmation(e.currentTarget);\n }\n });\n\n pendingPromise.resolve();\n};\n\n/**\n * Display the download course content modal.\n *\n * @method displayDownloadConfirmation\n * @param {Object} downloadModalTrigger The DOM element that triggered the download modal.\n * @return {void}\n */\nconst displayDownloadConfirmation = (downloadModalTrigger) => {\n ModalFactory.create({\n title: downloadModalTrigger.dataset.downloadTitle,\n type: ModalFactory.types.SAVE_CANCEL,\n body: `

${downloadModalTrigger.dataset.downloadBody}

`,\n buttons: {\n save: downloadModalTrigger.dataset.downloadButtonText\n },\n templateContext: {\n classes: 'downloadcoursecontentmodal'\n }\n })\n .then(modal => {\n // Display the modal.\n modal.show();\n\n const saveButton = document.querySelector('.modal .downloadcoursecontentmodal [data-action=\"save\"]');\n const cancelButton = document.querySelector('.modal .downloadcoursecontentmodal [data-action=\"cancel\"]');\n const modalContainer = document.querySelector('.modal[data-region=\"modal-container\"]');\n\n // Create listener to trigger the download when the \"Download\" button is pressed.\n jQuery(saveButton).on(CustomEvents.events.activate, (e) => downloadContent(e, downloadModalTrigger, modal));\n\n // Create listener to destroy the modal when closing modal by cancelling.\n jQuery(cancelButton).on(CustomEvents.events.activate, () => {\n modal.destroy();\n });\n\n // Create listener to destroy the modal when closing modal by clicking outside of it.\n if (modalContainer.querySelector('.downloadcoursecontentmodal')) {\n jQuery(modalContainer).on(CustomEvents.events.activate, () => {\n modal.destroy();\n });\n }\n });\n};\n\n/**\n * Trigger downloading of course content.\n *\n * @method downloadContent\n * @param {Event} e The event triggering the download.\n * @param {Object} downloadModalTrigger The DOM element that triggered the download modal.\n * @param {Object} modal The modal object.\n * @return {void}\n */\nconst downloadContent = (e, downloadModalTrigger, modal) => {\n e.preventDefault();\n\n // Create a form to submit the file download request, so we can avoid sending sesskey over GET.\n const downloadForm = document.createElement('form');\n downloadForm.action = downloadModalTrigger.dataset.downloadLink;\n downloadForm.method = 'POST';\n // Open download in a new tab, so current course view is not disrupted.\n downloadForm.target = '_blank';\n const downloadSesskey = document.createElement('input');\n downloadSesskey.name = 'sesskey';\n downloadSesskey.value = Config.sesskey;\n downloadForm.appendChild(downloadSesskey);\n downloadForm.style.display = 'none';\n\n document.body.appendChild(downloadForm);\n downloadForm.submit();\n document.body.removeChild(downloadForm);\n\n // Destroy the modal to prevent duplicates if reopened later.\n modal.destroy();\n};\n"],"names":["pendingPromise","Pending","on","e","type","which","enter","space","preventDefault","displayDownloadConfirmation","currentTarget","resolve","downloadModalTrigger","ModalFactory","create","title","dataset","downloadTitle","types","SAVE_CANCEL","body","downloadBody","buttons","save","downloadButtonText","templateContext","classes","then","modal","show","saveButton","document","querySelector","cancelButton","modalContainer","CustomEvents","events","activate","downloadContent","destroy","downloadForm","createElement","action","downloadLink","method","target","downloadSesskey","name","value","Config","sesskey","appendChild","style","display","submit","removeChild"],"mappings":";;;;;;;g9BAmCoB,WACVA,eAAiB,IAAIC,qCAGpB,yBAAyBC,GAAG,iBAAkBC,IAClC,UAAXA,EAAEC,MAAoBD,EAAEE,QAAUC,kBAASH,EAAEE,QAAUE,mBACvDJ,EAAEK,iBACFC,4BAA4BN,EAAEO,mBAItCV,eAAeW,iBAUbF,4BAA+BG,uBACjCC,aAAaC,OAAO,CAChBC,MAAOH,qBAAqBI,QAAQC,cACpCb,KAAMS,aAAaK,MAAMC,YACzBC,kBAAYR,qBAAqBI,QAAQK,qBACzCC,QAAS,CACLC,KAAMX,qBAAqBI,QAAQQ,oBAEvCC,gBAAiB,CACbC,QAAS,gCAGhBC,MAAKC,QAEFA,MAAMC,aAEAC,WAAaC,SAASC,cAAc,2DACpCC,aAAeF,SAASC,cAAc,6DACtCE,eAAiBH,SAASC,cAAc,6DAGvCF,YAAY5B,GAAGiC,mCAAaC,OAAOC,UAAWlC,GAAMmC,gBAAgBnC,EAAGS,qBAAsBgB,6BAG7FK,cAAc/B,GAAGiC,mCAAaC,OAAOC,UAAU,KAClDT,MAAMW,aAINL,eAAeF,cAAc,oDACtBE,gBAAgBhC,GAAGiC,mCAAaC,OAAOC,UAAU,KACpDT,MAAMW,iBAehBD,gBAAkB,CAACnC,EAAGS,qBAAsBgB,SAC9CzB,EAAEK,uBAGIgC,aAAeT,SAASU,cAAc,QAC5CD,aAAaE,OAAS9B,qBAAqBI,QAAQ2B,aACnDH,aAAaI,OAAS,OAEtBJ,aAAaK,OAAS,eAChBC,gBAAkBf,SAASU,cAAc,SAC/CK,gBAAgBC,KAAO,UACvBD,gBAAgBE,MAAQC,gBAAOC,QAC/BV,aAAaW,YAAYL,iBACzBN,aAAaY,MAAMC,QAAU,OAE7BtB,SAASX,KAAK+B,YAAYX,cAC1BA,aAAac,SACbvB,SAASX,KAAKmC,YAAYf,cAG1BZ,MAAMW"} \ No newline at end of file +{"version":3,"file":"downloadcontent.min.js","sources":["../src/downloadcontent.js"],"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 * Functions related to downloading course content.\n *\n * @module core_course/downloadcontent\n * @copyright 2020 Michael Hawkins \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Config from 'core/config';\nimport CustomEvents from 'core/custom_interaction_events';\nimport SaveCancelModal from 'core/modal_save_cancel';\nimport jQuery from 'jquery';\nimport Pending from 'core/pending';\nimport {enter, space} from 'core/key_codes';\n\n/**\n * Set up listener to trigger the download course content modal.\n *\n * @return {void}\n */\nexport const init = () => {\n const pendingPromise = new Pending();\n\n // Add event listeners for click and enter/space keys.\n jQuery('[data-downloadcourse]').on('click keydown', (e) => {\n if (e.type === 'click' || e.which === enter || e.which === space) {\n e.preventDefault();\n displayDownloadConfirmation(e.currentTarget);\n }\n });\n\n pendingPromise.resolve();\n};\n\n/**\n * Display the download course content modal.\n *\n * @method displayDownloadConfirmation\n * @param {Object} downloadModalTrigger The DOM element that triggered the download modal.\n * @return {void}\n */\nconst displayDownloadConfirmation = (downloadModalTrigger) => {\n return SaveCancelModal.create({\n title: downloadModalTrigger.dataset.downloadTitle,\n body: `

${downloadModalTrigger.dataset.downloadBody}

`,\n buttons: {\n save: downloadModalTrigger.dataset.downloadButtonText\n },\n templateContext: {\n classes: 'downloadcoursecontentmodal'\n }\n })\n .then((modal) => {\n // Display the modal.\n modal.show();\n\n const saveButton = document.querySelector('.modal .downloadcoursecontentmodal [data-action=\"save\"]');\n const cancelButton = document.querySelector('.modal .downloadcoursecontentmodal [data-action=\"cancel\"]');\n const modalContainer = document.querySelector('.modal[data-region=\"modal-container\"]');\n\n // Create listener to trigger the download when the \"Download\" button is pressed.\n jQuery(saveButton).on(CustomEvents.events.activate, (e) => downloadContent(e, downloadModalTrigger, modal));\n\n // Create listener to destroy the modal when closing modal by cancelling.\n jQuery(cancelButton).on(CustomEvents.events.activate, () => {\n modal.destroy();\n });\n\n // Create listener to destroy the modal when closing modal by clicking outside of it.\n if (modalContainer.querySelector('.downloadcoursecontentmodal')) {\n jQuery(modalContainer).on(CustomEvents.events.activate, () => {\n modal.destroy();\n });\n }\n\n return modal;\n });\n};\n\n/**\n * Trigger downloading of course content.\n *\n * @method downloadContent\n * @param {Event} e The event triggering the download.\n * @param {Object} downloadModalTrigger The DOM element that triggered the download modal.\n * @param {Object} modal The modal object.\n * @return {void}\n */\nconst downloadContent = (e, downloadModalTrigger, modal) => {\n e.preventDefault();\n\n // Create a form to submit the file download request, so we can avoid sending sesskey over GET.\n const downloadForm = document.createElement('form');\n downloadForm.action = downloadModalTrigger.dataset.downloadLink;\n downloadForm.method = 'POST';\n // Open download in a new tab, so current course view is not disrupted.\n downloadForm.target = '_blank';\n const downloadSesskey = document.createElement('input');\n downloadSesskey.name = 'sesskey';\n downloadSesskey.value = Config.sesskey;\n downloadForm.appendChild(downloadSesskey);\n downloadForm.style.display = 'none';\n\n document.body.appendChild(downloadForm);\n downloadForm.submit();\n document.body.removeChild(downloadForm);\n\n // Destroy the modal to prevent duplicates if reopened later.\n modal.destroy();\n};\n"],"names":["pendingPromise","Pending","on","e","type","which","enter","space","preventDefault","displayDownloadConfirmation","currentTarget","resolve","downloadModalTrigger","SaveCancelModal","create","title","dataset","downloadTitle","body","downloadBody","buttons","save","downloadButtonText","templateContext","classes","then","modal","show","saveButton","document","querySelector","cancelButton","modalContainer","CustomEvents","events","activate","downloadContent","destroy","downloadForm","createElement","action","downloadLink","method","target","downloadSesskey","name","value","Config","sesskey","appendChild","style","display","submit","removeChild"],"mappings":";;;;;;;sWAmCoB,WACVA,eAAiB,IAAIC,qCAGpB,yBAAyBC,GAAG,iBAAkBC,IAClC,UAAXA,EAAEC,MAAoBD,EAAEE,QAAUC,kBAASH,EAAEE,QAAUE,mBACvDJ,EAAEK,iBACFC,4BAA4BN,EAAEO,mBAItCV,eAAeW,iBAUbF,4BAA+BG,sBAC1BC,2BAAgBC,OAAO,CAC1BC,MAAOH,qBAAqBI,QAAQC,cACpCC,kBAAYN,qBAAqBI,QAAQG,qBACzCC,QAAS,CACLC,KAAMT,qBAAqBI,QAAQM,oBAEvCC,gBAAiB,CACbC,QAAS,gCAGhBC,MAAMC,QAEHA,MAAMC,aAEAC,WAAaC,SAASC,cAAc,2DACpCC,aAAeF,SAASC,cAAc,6DACtCE,eAAiBH,SAASC,cAAc,mEAGvCF,YAAY1B,GAAG+B,mCAAaC,OAAOC,UAAWhC,GAAMiC,gBAAgBjC,EAAGS,qBAAsBc,6BAG7FK,cAAc7B,GAAG+B,mCAAaC,OAAOC,UAAU,KAClDT,MAAMW,aAINL,eAAeF,cAAc,oDACtBE,gBAAgB9B,GAAG+B,mCAAaC,OAAOC,UAAU,KACpDT,MAAMW,aAIPX,SAaTU,gBAAkB,CAACjC,EAAGS,qBAAsBc,SAC9CvB,EAAEK,uBAGI8B,aAAeT,SAASU,cAAc,QAC5CD,aAAaE,OAAS5B,qBAAqBI,QAAQyB,aACnDH,aAAaI,OAAS,OAEtBJ,aAAaK,OAAS,eAChBC,gBAAkBf,SAASU,cAAc,SAC/CK,gBAAgBC,KAAO,UACvBD,gBAAgBE,MAAQC,gBAAOC,QAC/BV,aAAaW,YAAYL,iBACzBN,aAAaY,MAAMC,QAAU,OAE7BtB,SAASX,KAAK+B,YAAYX,cAC1BA,aAAac,SACbvB,SAASX,KAAKmC,YAAYf,cAG1BZ,MAAMW"} \ No newline at end of file diff --git a/course/amd/src/actions.js b/course/amd/src/actions.js index 09a7df46277..deefa050593 100644 --- a/course/amd/src/actions.js +++ b/course/amd/src/actions.js @@ -31,7 +31,7 @@ define( 'core/url', 'core/yui', 'core/modal_copy_to_clipboard', - 'core/modal_factory', + 'core/modal_save_cancel', 'core/modal_events', 'core/key_codes', 'core/log', @@ -48,7 +48,7 @@ define( url, Y, ModalCopyToClipboard, - ModalFactory, + ModalSaveCancel, ModalEvents, KeyCodes, log, @@ -1015,43 +1015,53 @@ define( } // Add a handler for "Add sections" link to ask for a number of sections to add. - str.get_string('numberweeks').done(function(strNumberSections) { - var trigger = $(SELECTOR.ADDSECTIONS), - modalTitle = trigger.attr('data-add-sections'), - newSections = trigger.attr('data-new-sections'); + const trigger = $(SELECTOR.ADDSECTIONS); + const modalTitle = trigger.attr('data-add-sections'); + const newSections = trigger.attr('data-new-sections'); + str.get_string('numberweeks') + .then(function(strNumberSections) { var modalBody = $('
' + '
'); modalBody.find('label').html(strNumberSections); - ModalFactory.create({ - title: modalTitle, - type: ModalFactory.types.SAVE_CANCEL, - body: modalBody.html() - }, trigger) - .done(function(modal) { - var numSections = $(modal.getBody()).find('#add_section_numsections'), - addSections = function() { - // Check if value of the "Number of sections" is a valid positive integer and redirect - // to adding a section script. - if ('' + parseInt(numSections.val()) === numSections.val() && parseInt(numSections.val()) >= 1) { - document.location = trigger.attr('href') + '&numsections=' + parseInt(numSections.val()); + + return modalBody.html(); + }) + .then((body) => ModalSaveCancel.create({ + body, + title: modalTitle, + })) + .then(function(modal) { + var numSections = $(modal.getBody()).find('#add_section_numsections'), + addSections = function() { + // Check if value of the "Number of sections" is a valid positive integer and redirect + // to adding a section script. + if ('' + parseInt(numSections.val()) === numSections.val() && parseInt(numSections.val()) >= 1) { + document.location = trigger.attr('href') + '&numsections=' + parseInt(numSections.val()); + } + }; + modal.setSaveButtonText(modalTitle); + modal.getRoot().on(ModalEvents.shown, function() { + // When modal is shown focus and select the input and add a listener to keypress of "Enter". + numSections.focus().select().on('keydown', function(e) { + if (e.keyCode === KeyCodes.enter) { + addSections(); } - }; - modal.setSaveButtonText(modalTitle); - modal.getRoot().on(ModalEvents.shown, function() { - // When modal is shown focus and select the input and add a listener to keypress of "Enter". - numSections.focus().select().on('keydown', function(e) { - if (e.keyCode === KeyCodes.enter) { - addSections(); - } - }); - }); - modal.getRoot().on(ModalEvents.save, function(e) { - // When modal "Add" button is pressed. - e.preventDefault(); - addSections(); }); }); - }); + modal.getRoot().on(ModalEvents.save, function(e) { + // When modal "Add" button is pressed. + e.preventDefault(); + addSections(); + }); + + trigger.on('click', (e) => { + e.preventDefault(); + modal.show(); + }); + + return modal; + }) + .catch(notification.exception); }, /** diff --git a/course/amd/src/activitychooser.js b/course/amd/src/activitychooser.js index cb4daba469d..94b1725694a 100644 --- a/course/amd/src/activitychooser.js +++ b/course/amd/src/activitychooser.js @@ -26,8 +26,8 @@ import * as Repository from 'core_course/local/activitychooser/repository'; import selectors from 'core_course/local/activitychooser/selectors'; import CustomEvents from 'core/custom_interaction_events'; import * as Templates from 'core/templates'; -import * as ModalFactory from 'core/modal_factory'; import {getString} from 'core/str'; +import Modal from 'core/modal'; import Pending from 'core/pending'; // Set up some JS module wide constants that can be added to in the future. @@ -289,27 +289,21 @@ const templateDataBuilder = (data, chooserConfig) => { * Given an object we want to build a modal ready to show * * @method buildModal - * @param {Promise} bodyPromise + * @param {Promise} body * @param {String|Boolean} footer Either a footer to add or nothing * @return {Object} The modal ready to display immediately and render body in later. */ -const buildModal = (bodyPromise, footer) => { - return ModalFactory.create({ - type: ModalFactory.types.DEFAULT, - title: getString('addresourceoractivity'), - body: bodyPromise, - footer: footer.customfootertemplate, - large: true, - scrollable: false, - templateContext: { - classes: 'modchooser' - } - }) - .then(modal => { - modal.show(); - return modal; - }); -}; +const buildModal = (body, footer) => Modal.create({ + body, + title: getString('addresourceoractivity'), + footer: footer.customfootertemplate, + large: true, + scrollable: false, + templateContext: { + classes: 'modchooser' + }, + show: true, +}); /** * A small helper function to handle the case where there are no more favourites diff --git a/course/amd/src/copy_modal.js b/course/amd/src/copy_modal.js index d4daa58421a..04b7f11b64f 100644 --- a/course/amd/src/copy_modal.js +++ b/course/amd/src/copy_modal.js @@ -24,167 +24,127 @@ * @since 3.9 */ -define(['jquery', 'core/str', 'core/modal_factory', 'core/modal_events', - 'core/ajax', 'core/fragment', 'core/notification', 'core/config'], - function($, Str, ModalFactory, ModalEvents, ajax, Fragment, Notification, Config) { +import {get_string as getString} from 'core/str'; +import Modal from 'core/modal'; +import * as ajax from 'core/ajax'; +import * as Fragment from 'core/fragment'; +import Notification from 'core/notification'; +import * as Config from 'core/config'; - /** - * Module level variables. - */ - var CopyModal = {}; - var contextid; - var course; - var modalObj; - var spinner = '

' - + '' - + '

'; +export default class CopyModal { + static init(context) { + return new CopyModal(context); + } - /** - * Creates the modal for the course copy form - * - * @private - */ - function createModal() { - // Get the Title String. - Str.get_string('loading').then(function(title) { - // Create the Modal. - ModalFactory.create({ - type: ModalFactory.types.DEFAULT, - title: title, - body: spinner, - large: true - }) - .done(function(modal) { - modalObj = modal; - // Explicitly handle form click events. - modalObj.getRoot().on('click', '#id_submitreturn', processModalForm); - modalObj.getRoot().on('click', '#id_submitdisplay', function(e) { - e.formredirect = true; - processModalForm(e); + constructor(context) { + this.contextid = context; - }); - modalObj.getRoot().on('click', '#id_cancel', function(e) { - e.preventDefault(); - modalObj.setBody(spinner); - modalObj.hide(); - }); - }); - return; - }).catch(function() { - Notification.exception(new Error('Failed to load string: loading')); + this.registerEventListeners(); + } + + registerEventListeners() { + document.addEventListener('click', (e) => { + const copyAction = e.target.closest('.action-copy'); + if (!copyAction) { + return; + } + e.preventDefault(); // Stop. Hammer time. + + const url = new URL(copyAction.href); + const params = new URLSearchParams(url.search); + + this.fetchCourseData(params.get('id')) + .then(([course]) => this.createModal(course)) + .catch((error) => Notification.exception(error)); }); } - /** - * Updates the body of the modal window. - * - * @param {Object} formdata - * @private - */ - function updateModalBody(formdata) { - if (typeof formdata === "undefined") { - formdata = {}; - } + fetchCourseData(courseid) { + return ajax.call([{ + methodname: 'core_course_get_courses', + args: { + options: { + ids: [courseid], + }, + }, + }])[0]; + } - var params = { - 'jsonformdata': JSON.stringify(formdata), - 'courseid': course.id + submitBackupRequest(jsonformdata) { + return ajax.call([{ + methodname: 'core_backup_submit_copy_form', + args: { + jsonformdata, + }, + }])[0]; + } + + createModal( + course, + formdata = {}, + ) { + const params = { + jsonformdata: JSON.stringify(formdata), + courseid: course.id, }; - modalObj.setBody(spinner); - Str.get_string('copycoursetitle', 'backup', course.shortname).then(function(title) { - modalObj.setTitle(title); - modalObj.setBody(Fragment.loadFragment('course', 'new_base_form', contextid, params)); - return; - }).catch(function() { - Notification.exception(new Error('Failed to load string: copycoursetitle')); + // Create the Modal. + return Modal.create({ + title: getString('copycoursetitle', 'backup', course.shortname), + body: Fragment.loadFragment('course', 'new_base_form', this.contextid, params), + large: true, + show: true, + removeOnClose: true, + }) + .then((modal) => { + // Explicitly handle form click events. + modal.getRoot().on('click', '#id_submitreturn', (e) => { + this.processModalForm(course, modal, e); + }); + modal.getRoot().on('click', '#id_cancel', (e) => { + e.preventDefault(); + modal.hide(); + }); + modal.getRoot().on('click', '#id_submitdisplay', (e) => { + e.formredirect = true; + this.processModalForm(course, modal, e); + + }); + + return modal; }); } - /** - * Updates Moodle form with selected information. - * - * @param {Object} e - * @private - */ - function processModalForm(e) { + processModalForm(course, modal, e) { e.preventDefault(); // Stop modal from closing. // Form data. - var copyform = modalObj.getRoot().find('form').serialize(); - var formjson = JSON.stringify(copyform); + const copyform = modal.getRoot().find('form').serialize(); + const formjson = JSON.stringify(copyform); // Handle invalid form fields for better UX. - var invalid = $.merge( - modalObj.getRoot().find('[aria-invalid="true"]'), - modalObj.getRoot().find('.error') - ); - + const invalid = modal.getRoot()[0].querySelectorAll('[aria-invalid="true"], .error'); if (invalid.length) { - invalid.first().focus(); + invalid[0].focus(); return; } - // Submit form via ajax. - ajax.call([{ - methodname: 'core_backup_submit_copy_form', - args: { - jsonformdata: formjson - }, - }])[0].done(function() { - // For submission succeeded. - modalObj.setBody(spinner); - modalObj.hide(); + modal.hide(); + // Submit form via ajax. + this.submitBackupRequest(formjson) + .then(() => { if (e.formredirect == true) { // We are redirecting to copy progress display. - let redirect = Config.wwwroot + "/backup/copyprogress.php?id=" + course.id; + const redirect = `${Config.wwwroot}/backup/copyprogress.php?id=${course.id}`; window.location.assign(redirect); } - }).fail(function() { + return; + }) + .catch(() => { // Form submission failed server side, redisplay with errors. - updateModalBody(copyform); + this.createModal(course, copyform); }); } - - /** - * Initialise the class. - * - * @method - * @param {Object} context - * @public - */ - CopyModal.init = function(context) { - contextid = context; - // Setup the initial Modal. - createModal(); - - // Setup the click handlers on the copy buttons. - $('.action-copy').on('click', function(e) { - e.preventDefault(); // Stop. Hammer time. - let url = new URL(this.getAttribute('href')); - let params = new URLSearchParams(url.search); - let courseid = params.get('id'); - - ajax.call([{ // Get the course information. - methodname: 'core_course_get_courses', - args: { - 'options': {'ids': [courseid]}, - }, - }])[0].done(function(response) { - // We have the course info get the modal content. - course = response[0]; - updateModalBody(); - - }).fail(function() { - Notification.exception(new Error('Failed to load course')); - }); - - modalObj.show(); - }); - - }; - - return CopyModal; -}); +} diff --git a/course/amd/src/downloadcontent.js b/course/amd/src/downloadcontent.js index c19006e7597..d60065ce953 100644 --- a/course/amd/src/downloadcontent.js +++ b/course/amd/src/downloadcontent.js @@ -23,7 +23,7 @@ import Config from 'core/config'; import CustomEvents from 'core/custom_interaction_events'; -import * as ModalFactory from 'core/modal_factory'; +import SaveCancelModal from 'core/modal_save_cancel'; import jQuery from 'jquery'; import Pending from 'core/pending'; import {enter, space} from 'core/key_codes'; @@ -55,9 +55,8 @@ export const init = () => { * @return {void} */ const displayDownloadConfirmation = (downloadModalTrigger) => { - ModalFactory.create({ + return SaveCancelModal.create({ title: downloadModalTrigger.dataset.downloadTitle, - type: ModalFactory.types.SAVE_CANCEL, body: `

${downloadModalTrigger.dataset.downloadBody}

`, buttons: { save: downloadModalTrigger.dataset.downloadButtonText @@ -66,7 +65,7 @@ const displayDownloadConfirmation = (downloadModalTrigger) => { classes: 'downloadcoursecontentmodal' } }) - .then(modal => { + .then((modal) => { // Display the modal. modal.show(); @@ -88,6 +87,8 @@ const displayDownloadConfirmation = (downloadModalTrigger) => { modal.destroy(); }); } + + return modal; }); }; diff --git a/course/format/amd/build/local/content/actions.min.js b/course/format/amd/build/local/content/actions.min.js index 24b4e4396d1..f523a1c429f 100644 --- a/course/format/amd/build/local/content/actions.min.js +++ b/course/format/amd/build/local/content/actions.min.js @@ -1,4 +1,4 @@ -define("core_courseformat/local/content/actions",["exports","core/reactive","core/modal_factory","core/modal_events","core/templates","core/prefetch","core/str","core/normalise","core_courseformat/local/content/actions/bulkselection","core_course/events","core/pending","core_courseformat/local/courseeditor/contenttree","jquery"],(function(_exports,_reactive,_modal_factory,_modal_events,_templates,_prefetch,_str,_normalise,_bulkselection,CourseEvents,_pending,_contenttree,_jquery){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}} +define("core_courseformat/local/content/actions",["exports","core/reactive","core/modal","core/modal_save_cancel","core/modal_delete_cancel","core/modal_events","core/templates","core/prefetch","core/str","core/normalise","core_courseformat/local/content/actions/bulkselection","core_course/events","core/pending","core_courseformat/local/courseeditor/contenttree","jquery"],(function(_exports,_reactive,_modal,_modal_save_cancel,_modal_delete_cancel,_modal_events,_templates,_prefetch,_str,_normalise,_bulkselection,CourseEvents,_pending,_contenttree,_jquery){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}} /** * Course state actions dispatcher. * @@ -9,6 +9,6 @@ define("core_courseformat/local/content/actions",["exports","core/reactive","cor * @class core_courseformat/local/content/actions * @copyright 2021 Ferran Recio * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_modal_factory=_interopRequireDefault(_modal_factory),_modal_events=_interopRequireDefault(_modal_events),_templates=_interopRequireDefault(_templates),CourseEvents=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(CourseEvents),_pending=_interopRequireDefault(_pending),_contenttree=_interopRequireDefault(_contenttree),_jquery=_interopRequireDefault(_jquery),(0,_prefetch.prefetchStrings)("core",["movecoursesection","movecoursemodule","confirm","delete"]);const directMutations={sectionHide:"sectionHide",sectionShow:"sectionShow",cmHide:"cmHide",cmShow:"cmShow",cmStealth:"cmStealth",cmMoveRight:"cmMoveRight",cmMoveLeft:"cmMoveLeft",cmNoGroups:"cmNoGroups",cmSeparateGroups:"cmSeparateGroups",cmVisibleGroups:"cmVisibleGroups"};class _default extends _reactive.BaseComponent{create(){this.name="content_actions",this.selectors={ACTIONLINK:"[data-action]",SECTIONLINK:"[data-for='section']",CMLINK:"[data-for='cm']",SECTIONNODE:"[data-for='sectionnode']",MODALTOGGLER:"[data-toggle='collapse']",ADDSECTION:"[data-action='addSection']",CONTENTTREE:"#destination-selector",ACTIONMENU:".action-menu",ACTIONMENUTOGGLER:'[data-toggle="dropdown"]',OPTIONSRADIO:"[type='radio']"},this.classes={DISABLED:"text-body",ITALIC:"font-italic"}}static addActions(actions){for(const[action,mutationReference]of Object.entries(actions)){if("function"!=typeof mutationReference&&"string"!=typeof mutationReference)throw new Error("".concat(action," action must be a mutation name or a function"));directMutations[action]=mutationReference}}stateReady(state){this.addEventListener(this.element,"click",this._dispatchClick),this._checkSectionlist({state:state}),this.addEventListener(this.element,CourseEvents.sectionRefreshed,(()=>this._checkSectionlist({state:state})))}getWatchers(){return[{watch:"course.sectionlist:updated",handler:this._checkSectionlist}]}_dispatchClick(event){const target=event.target.closest(this.selectors.ACTIONLINK);if(!target)return;if(target.classList.contains(this.classes.DISABLED))return void event.preventDefault();const actionName=target.dataset.action,methodName=this._actionMethodName(actionName);if(void 0===this[methodName])return void 0!==directMutations[actionName]?"function"==typeof directMutations[actionName]?void directMutations[actionName](target,event):void this._requestMutationAction(target,event,directMutations[actionName]):void 0;this[methodName](target,event)}_actionMethodName(name){const requestName=name.charAt(0).toUpperCase()+name.slice(1);return"_request".concat(requestName)}_checkSectionlist(_ref){let{state:state}=_ref;this._setAddSectionLocked(state.course.sectionlist.length>state.course.maxsections)}_getTargetIds(target){var _target$dataset,_target$dataset2;let ids=[];null!=target&&null!==(_target$dataset=target.dataset)&&void 0!==_target$dataset&&_target$dataset.id&&ids.push(target.dataset.id);const bulkType=null==target||null===(_target$dataset2=target.dataset)||void 0===_target$dataset2?void 0:_target$dataset2.bulk;if(!bulkType)return ids;const bulk=this.reactive.get("bulk");return bulk.enabled&&bulk.selectedType===bulkType&&(ids=[...ids,...bulk.selection]),ids}async _requestMoveSection(target,event){const sectionIds=this._getTargetIds(target);if(0==sectionIds.length)return;event.preventDefault();const pendingModalReady=new _pending.default("courseformat/actions:prepareMoveSectionModal"),editTools=this._getClosestActionMenuToogler(target),data=this.reactive.getExporter().course(this.reactive.state);let titleText=null,sectionInfo=null;1==sectionIds.length?(sectionInfo=this.reactive.get("section",sectionIds[0]),data.sectionid=sectionInfo.id,data.sectiontitle=sectionInfo.title,data.information=await this.reactive.getFormatString("sectionmove_info",data.sectiontitle),titleText=this.reactive.getFormatString("sectionmove_title")):(data.information=await this.reactive.getFormatString("sectionsmove_info",sectionIds.length),titleText=this.reactive.getFormatString("sectionsmove_title"));const modalParams={title:titleText,body:_templates.default.render("core_courseformat/local/content/movesection",data)},modal=await this._modalBodyRenderedPromise(modalParams),modalBody=(0,_normalise.getFirst)(modal.getBody());sectionIds.forEach((sectionId=>{const currentElement=modalBody.querySelector("".concat(this.selectors.SECTIONLINK,"[data-id='").concat(sectionId,"']"));this._disableLink(currentElement)})),new _contenttree.default(modalBody.querySelector(this.selectors.CONTENTTREE),{SECTION:this.selectors.SECTIONNODE,TOGGLER:this.selectors.MODALTOGGLER,COLLAPSE:this.selectors.MODALTOGGLER},!0),modalBody.addEventListener("click",(event=>{const target=event.target;target.matches("a")&&"section"==target.dataset.for&&void 0!==target.dataset.id&&(target.getAttribute("aria-disabled")||(event.preventDefault(),this.reactive.dispatch("sectionMoveAfter",sectionIds,target.dataset.id),this._destroyModal(modal,editTools)))})),pendingModalReady.resolve()}async _requestMoveCm(target,event){const cmIds=this._getTargetIds(target);if(0==cmIds.length)return;event.preventDefault();const pendingModalReady=new _pending.default("courseformat/actions:prepareMoveCmModal"),editTools=this._getClosestActionMenuToogler(target),exporter=this.reactive.getExporter(),data=exporter.course(this.reactive.state);let titleText=null;if(1==cmIds.length){const cmInfo=this.reactive.get("cm",cmIds[0]);data.cmid=cmInfo.id,data.cmname=cmInfo.name,data.information=await this.reactive.getFormatString("cmmove_info",data.cmname),titleText=this.reactive.getFormatString("cmmove_title")}else data.information=await this.reactive.getFormatString("cmsmove_info",cmIds.length),titleText=this.reactive.getFormatString("cmsmove_title");const modalParams={title:titleText,body:_templates.default.render("core_courseformat/local/content/movecm",data)},modal=await this._modalBodyRenderedPromise(modalParams),modalBody=(0,_normalise.getFirst)(modal.getBody());cmIds.forEach((cmId=>{const currentElement=modalBody.querySelector("".concat(this.selectors.CMLINK,"[data-id='").concat(cmId,"']"));this._disableLink(currentElement)})),new _contenttree.default(modalBody.querySelector(this.selectors.CONTENTTREE),{SECTION:this.selectors.SECTIONNODE,TOGGLER:this.selectors.MODALTOGGLER,COLLAPSE:this.selectors.MODALTOGGLER,ENTER:this.selectors.SECTIONLINK}),cmIds.forEach((cmId=>{var _toggler$data;const sectionnode=modalBody.querySelector("".concat(this.selectors.CMLINK,"[data-id='").concat(cmId,"']")).closest(this.selectors.SECTIONNODE),toggler=(0,_jquery.default)(sectionnode).find(this.selectors.MODALTOGGLER);let collapsibleId=null!==(_toggler$data=toggler.data("target"))&&void 0!==_toggler$data?_toggler$data:toggler.attr("href");if(collapsibleId){collapsibleId=collapsibleId.replace("#","");const expandNode=modalBody.querySelector("#".concat(collapsibleId));(0,_jquery.default)(expandNode).collapse("show")}})),modalBody.addEventListener("click",(event=>{const target=event.target;if(!target.matches("a")||void 0===target.dataset.for||void 0===target.dataset.id)return;if(target.getAttribute("aria-disabled"))return;let targetSectionId,targetCmId;if(event.preventDefault(),"cm"==target.dataset.for){const dropData=exporter.cmDraggableData(this.reactive.state,target.dataset.id);targetSectionId=dropData.sectionid,targetCmId=dropData.nextcmid}else{const section=this.reactive.get("section",target.dataset.id);targetSectionId=target.dataset.id,targetCmId=null==section?void 0:section.cmlist[0]}this.reactive.dispatch("cmMove",cmIds,targetSectionId,targetCmId),this._destroyModal(modal,editTools)})),pendingModalReady.resolve()}async _requestAddSection(target,event){var _target$dataset$id;event.preventDefault(),this.reactive.dispatch("addSection",null!==(_target$dataset$id=target.dataset.id)&&void 0!==_target$dataset$id?_target$dataset$id:0)}async _requestDeleteSection(target,event){const sectionIds=this._getTargetIds(target);if(0==sectionIds.length)return;if(event.preventDefault(),!sectionIds.some((sectionId=>{var _sectionInfo$cmlist;const sectionInfo=this.reactive.get("section",sectionId);return(null!==(_sectionInfo$cmlist=sectionInfo.cmlist)&&void 0!==_sectionInfo$cmlist?_sectionInfo$cmlist:[]).length||sectionInfo.hassummary||sectionInfo.rawtitle})))return void this.reactive.dispatch("sectionDelete",sectionIds);let bodyText=null,titleText=null;if(1==sectionIds.length){titleText=this.reactive.getFormatString("sectiondelete_title");const sectionInfo=this.reactive.get("section",sectionIds[0]);bodyText=this.reactive.getFormatString("sectiondelete_info",{name:sectionInfo.title})}else titleText=this.reactive.getFormatString("sectionsdelete_title"),bodyText=this.reactive.getFormatString("sectionsdelete_info",{count:sectionIds.length});const modalParams={title:titleText,body:bodyText,type:_modal_factory.default.types.DELETE_CANCEL},modal=await this._modalBodyRenderedPromise(modalParams);modal.getRoot().on(_modal_events.default.delete,(e=>{e.preventDefault(),modal.destroy(),this.reactive.dispatch("sectionDelete",sectionIds)}))}async _requestToggleSelectionCm(target,event){(0,_bulkselection.toggleBulkSelectionAction)(this.reactive,target,event,"cm")}async _requestToggleSelectionSection(target,event){(0,_bulkselection.toggleBulkSelectionAction)(this.reactive,target,event,"section")}async _requestMutationAction(target,event,mutationName){target.dataset.id&&(event.preventDefault(),this.reactive.dispatch(mutationName,[target.dataset.id]))}async _requestCmDuplicate(target,event){var _target$dataset$secti;const cmIds=this._getTargetIds(target);if(0==cmIds.length)return;const sectionId=null!==(_target$dataset$secti=target.dataset.sectionid)&&void 0!==_target$dataset$secti?_target$dataset$secti:null;event.preventDefault(),this.reactive.dispatch("cmDuplicate",cmIds,sectionId)}async _requestCmDelete(target,event){const cmIds=this._getTargetIds(target);if(0==cmIds.length)return;event.preventDefault();let bodyText=null,titleText=null;if(1==cmIds.length){const cmInfo=this.reactive.get("cm",cmIds[0]);titleText=(0,_str.getString)("cmdelete_title","core_courseformat"),bodyText=(0,_str.getString)("cmdelete_info","core_courseformat",{type:cmInfo.modname,name:cmInfo.name})}else titleText=(0,_str.getString)("cmsdelete_title","core_courseformat"),bodyText=(0,_str.getString)("cmsdelete_info","core_courseformat",{count:cmIds.length});const modalParams={title:titleText,body:bodyText,type:_modal_factory.default.types.DELETE_CANCEL},modal=await this._modalBodyRenderedPromise(modalParams);modal.getRoot().on(_modal_events.default.delete,(e=>{e.preventDefault(),modal.destroy(),this.reactive.dispatch("cmDelete",cmIds)}))}async _requestCmAvailability(target){const cmIds=this._getTargetIds(target);if(0==cmIds.length)return;const data={allowstealth:this.reactive.getExporter().canUseStealth(this.reactive.state,cmIds)},modalParams={title:(0,_str.getString)("availability","core"),body:_templates.default.render("core_courseformat/local/content/cm/availabilitymodal",data),saveButtonText:(0,_str.getString)("apply","core"),type:_modal_factory.default.types.SAVE_CANCEL},modal=await this._modalBodyRenderedPromise(modalParams);this._setupMutationRadioButtonModal(modal,cmIds)}async _requestSectionAvailability(target){const sectionIds=this._getTargetIds(target);if(0==sectionIds.length)return;const title=1==sectionIds.length?"sectionavailability_title":"sectionsavailability_title",modalParams={title:this.reactive.getFormatString(title),body:_templates.default.render("core_courseformat/local/content/section/availabilitymodal",[]),saveButtonText:(0,_str.getString)("apply","core"),type:_modal_factory.default.types.SAVE_CANCEL},modal=await this._modalBodyRenderedPromise(modalParams);this._setupMutationRadioButtonModal(modal,sectionIds)}_setupMutationRadioButtonModal(modal,ids){modal.setButtonDisabled("save",!0);const submitFunction=radio=>{const mutation=null==radio?void 0:radio.value;return!!mutation&&(this.reactive.dispatch(mutation,ids),!0)},modalBody=(0,_normalise.getFirst)(modal.getBody());modalBody.querySelectorAll(this.selectors.OPTIONSRADIO).forEach((radio=>{radio.addEventListener("change",(()=>{modal.setButtonDisabled("save",!1)})),radio.parentNode.addEventListener("click",(()=>{radio.checked=!0,modal.setButtonDisabled("save",!1)})),radio.parentNode.addEventListener("dblclick",(dbClickEvent=>{submitFunction(radio)&&(dbClickEvent.preventDefault(),modal.destroy())}))})),modal.getRoot().on(_modal_events.default.save,(()=>{const radio=modalBody.querySelector("".concat(this.selectors.OPTIONSRADIO,":checked"));submitFunction(radio)}))}_setAddSectionLocked(locked){this.getElements(this.selectors.ADDSECTION).forEach((element=>{element.classList.toggle(this.classes.DISABLED,locked),element.classList.toggle(this.classes.ITALIC,locked),this.setElementLocked(element,locked)}))}_disableLink(element){element&&(element.style.pointerEvents="none",element.style.userSelect="none",element.classList.add(this.classes.DISABLED),element.classList.add(this.classes.ITALIC),element.setAttribute("aria-disabled",!0),element.addEventListener("click",(event=>event.preventDefault())))}_modalBodyRenderedPromise(modalParams){return new Promise(((resolve,reject)=>{_modal_factory.default.create(modalParams).then((modal=>{modal.setRemoveOnClose(!0),modal.getRoot().on(_modal_events.default.bodyRendered,(()=>{resolve(modal)})),void 0!==modalParams.saveButtonText&&modal.setSaveButtonText(modalParams.saveButtonText),void 0!==modalParams.deleteButtonText&&modal.setDeleteButtonText(modalParams.saveButtonText),modal.show()})).catch((()=>{reject("Cannot load modal content")}))}))}_destroyModal(modal,element){modal.hide();const pendingDestroy=new _pending.default("courseformat/actions:destroyModal");element&&element.focus(),setTimeout((()=>{modal.destroy(),pendingDestroy.resolve()}),500)}_getClosestActionMenuToogler(element){const actionMenu=element.closest(this.selectors.ACTIONMENU);if(actionMenu)return actionMenu.querySelector(this.selectors.ACTIONMENUTOGGLER)}}return _exports.default=_default,_exports.default})); + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_modal=_interopRequireDefault(_modal),_modal_save_cancel=_interopRequireDefault(_modal_save_cancel),_modal_delete_cancel=_interopRequireDefault(_modal_delete_cancel),_modal_events=_interopRequireDefault(_modal_events),_templates=_interopRequireDefault(_templates),CourseEvents=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(CourseEvents),_pending=_interopRequireDefault(_pending),_contenttree=_interopRequireDefault(_contenttree),_jquery=_interopRequireDefault(_jquery),(0,_prefetch.prefetchStrings)("core",["movecoursesection","movecoursemodule","confirm","delete"]);const directMutations={sectionHide:"sectionHide",sectionShow:"sectionShow",cmHide:"cmHide",cmShow:"cmShow",cmStealth:"cmStealth",cmMoveRight:"cmMoveRight",cmMoveLeft:"cmMoveLeft",cmNoGroups:"cmNoGroups",cmSeparateGroups:"cmSeparateGroups",cmVisibleGroups:"cmVisibleGroups"};class _default extends _reactive.BaseComponent{create(){this.name="content_actions",this.selectors={ACTIONLINK:"[data-action]",SECTIONLINK:"[data-for='section']",CMLINK:"[data-for='cm']",SECTIONNODE:"[data-for='sectionnode']",MODALTOGGLER:"[data-toggle='collapse']",ADDSECTION:"[data-action='addSection']",CONTENTTREE:"#destination-selector",ACTIONMENU:".action-menu",ACTIONMENUTOGGLER:'[data-toggle="dropdown"]',OPTIONSRADIO:"[type='radio']"},this.classes={DISABLED:"text-body",ITALIC:"font-italic"}}static addActions(actions){for(const[action,mutationReference]of Object.entries(actions)){if("function"!=typeof mutationReference&&"string"!=typeof mutationReference)throw new Error("".concat(action," action must be a mutation name or a function"));directMutations[action]=mutationReference}}stateReady(state){this.addEventListener(this.element,"click",this._dispatchClick),this._checkSectionlist({state:state}),this.addEventListener(this.element,CourseEvents.sectionRefreshed,(()=>this._checkSectionlist({state:state})))}getWatchers(){return[{watch:"course.sectionlist:updated",handler:this._checkSectionlist}]}_dispatchClick(event){const target=event.target.closest(this.selectors.ACTIONLINK);if(!target)return;if(target.classList.contains(this.classes.DISABLED))return void event.preventDefault();const actionName=target.dataset.action,methodName=this._actionMethodName(actionName);if(void 0===this[methodName])return void 0!==directMutations[actionName]?"function"==typeof directMutations[actionName]?void directMutations[actionName](target,event):void this._requestMutationAction(target,event,directMutations[actionName]):void 0;this[methodName](target,event)}_actionMethodName(name){const requestName=name.charAt(0).toUpperCase()+name.slice(1);return"_request".concat(requestName)}_checkSectionlist(_ref){let{state:state}=_ref;this._setAddSectionLocked(state.course.sectionlist.length>state.course.maxsections)}_getTargetIds(target){var _target$dataset,_target$dataset2;let ids=[];null!=target&&null!==(_target$dataset=target.dataset)&&void 0!==_target$dataset&&_target$dataset.id&&ids.push(target.dataset.id);const bulkType=null==target||null===(_target$dataset2=target.dataset)||void 0===_target$dataset2?void 0:_target$dataset2.bulk;if(!bulkType)return ids;const bulk=this.reactive.get("bulk");return bulk.enabled&&bulk.selectedType===bulkType&&(ids=[...ids,...bulk.selection]),ids}async _requestMoveSection(target,event){const sectionIds=this._getTargetIds(target);if(0==sectionIds.length)return;event.preventDefault();const pendingModalReady=new _pending.default("courseformat/actions:prepareMoveSectionModal"),editTools=this._getClosestActionMenuToogler(target),data=this.reactive.getExporter().course(this.reactive.state);let titleText=null,sectionInfo=null;1==sectionIds.length?(sectionInfo=this.reactive.get("section",sectionIds[0]),data.sectionid=sectionInfo.id,data.sectiontitle=sectionInfo.title,data.information=await this.reactive.getFormatString("sectionmove_info",data.sectiontitle),titleText=this.reactive.getFormatString("sectionmove_title")):(data.information=await this.reactive.getFormatString("sectionsmove_info",sectionIds.length),titleText=this.reactive.getFormatString("sectionsmove_title"));const modal=await this._modalBodyRenderedPromise(_modal.default,{title:titleText,body:_templates.default.render("core_courseformat/local/content/movesection",data)}),modalBody=(0,_normalise.getFirst)(modal.getBody());sectionIds.forEach((sectionId=>{const currentElement=modalBody.querySelector("".concat(this.selectors.SECTIONLINK,"[data-id='").concat(sectionId,"']"));this._disableLink(currentElement)})),new _contenttree.default(modalBody.querySelector(this.selectors.CONTENTTREE),{SECTION:this.selectors.SECTIONNODE,TOGGLER:this.selectors.MODALTOGGLER,COLLAPSE:this.selectors.MODALTOGGLER},!0),modalBody.addEventListener("click",(event=>{const target=event.target;target.matches("a")&&"section"==target.dataset.for&&void 0!==target.dataset.id&&(target.getAttribute("aria-disabled")||(event.preventDefault(),this.reactive.dispatch("sectionMoveAfter",sectionIds,target.dataset.id),this._destroyModal(modal,editTools)))})),pendingModalReady.resolve()}async _requestMoveCm(target,event){const cmIds=this._getTargetIds(target);if(0==cmIds.length)return;event.preventDefault();const pendingModalReady=new _pending.default("courseformat/actions:prepareMoveCmModal"),editTools=this._getClosestActionMenuToogler(target),exporter=this.reactive.getExporter(),data=exporter.course(this.reactive.state);let titleText=null;if(1==cmIds.length){const cmInfo=this.reactive.get("cm",cmIds[0]);data.cmid=cmInfo.id,data.cmname=cmInfo.name,data.information=await this.reactive.getFormatString("cmmove_info",data.cmname),titleText=this.reactive.getFormatString("cmmove_title")}else data.information=await this.reactive.getFormatString("cmsmove_info",cmIds.length),titleText=this.reactive.getFormatString("cmsmove_title");const modal=await this._modalBodyRenderedPromise(_modal.default,{title:titleText,body:_templates.default.render("core_courseformat/local/content/movecm",data)}),modalBody=(0,_normalise.getFirst)(modal.getBody());cmIds.forEach((cmId=>{const currentElement=modalBody.querySelector("".concat(this.selectors.CMLINK,"[data-id='").concat(cmId,"']"));this._disableLink(currentElement)})),new _contenttree.default(modalBody.querySelector(this.selectors.CONTENTTREE),{SECTION:this.selectors.SECTIONNODE,TOGGLER:this.selectors.MODALTOGGLER,COLLAPSE:this.selectors.MODALTOGGLER,ENTER:this.selectors.SECTIONLINK}),cmIds.forEach((cmId=>{var _toggler$data;const sectionnode=modalBody.querySelector("".concat(this.selectors.CMLINK,"[data-id='").concat(cmId,"']")).closest(this.selectors.SECTIONNODE),toggler=(0,_jquery.default)(sectionnode).find(this.selectors.MODALTOGGLER);let collapsibleId=null!==(_toggler$data=toggler.data("target"))&&void 0!==_toggler$data?_toggler$data:toggler.attr("href");if(collapsibleId){collapsibleId=collapsibleId.replace("#","");const expandNode=modalBody.querySelector("#".concat(collapsibleId));(0,_jquery.default)(expandNode).collapse("show")}})),modalBody.addEventListener("click",(event=>{const target=event.target;if(!target.matches("a")||void 0===target.dataset.for||void 0===target.dataset.id)return;if(target.getAttribute("aria-disabled"))return;let targetSectionId,targetCmId;if(event.preventDefault(),"cm"==target.dataset.for){const dropData=exporter.cmDraggableData(this.reactive.state,target.dataset.id);targetSectionId=dropData.sectionid,targetCmId=dropData.nextcmid}else{const section=this.reactive.get("section",target.dataset.id);targetSectionId=target.dataset.id,targetCmId=null==section?void 0:section.cmlist[0]}this.reactive.dispatch("cmMove",cmIds,targetSectionId,targetCmId),this._destroyModal(modal,editTools)})),pendingModalReady.resolve()}async _requestAddSection(target,event){var _target$dataset$id;event.preventDefault(),this.reactive.dispatch("addSection",null!==(_target$dataset$id=target.dataset.id)&&void 0!==_target$dataset$id?_target$dataset$id:0)}async _requestDeleteSection(target,event){const sectionIds=this._getTargetIds(target);if(0==sectionIds.length)return;if(event.preventDefault(),!sectionIds.some((sectionId=>{var _sectionInfo$cmlist;const sectionInfo=this.reactive.get("section",sectionId);return(null!==(_sectionInfo$cmlist=sectionInfo.cmlist)&&void 0!==_sectionInfo$cmlist?_sectionInfo$cmlist:[]).length||sectionInfo.hassummary||sectionInfo.rawtitle})))return void this.reactive.dispatch("sectionDelete",sectionIds);let bodyText=null,titleText=null;if(1==sectionIds.length){titleText=this.reactive.getFormatString("sectiondelete_title");const sectionInfo=this.reactive.get("section",sectionIds[0]);bodyText=this.reactive.getFormatString("sectiondelete_info",{name:sectionInfo.title})}else titleText=this.reactive.getFormatString("sectionsdelete_title"),bodyText=this.reactive.getFormatString("sectionsdelete_info",{count:sectionIds.length});const modal=await this._modalBodyRenderedPromise(_modal_delete_cancel.default,{title:titleText,body:bodyText});modal.getRoot().on(_modal_events.default.delete,(e=>{e.preventDefault(),modal.destroy(),this.reactive.dispatch("sectionDelete",sectionIds)}))}async _requestToggleSelectionCm(target,event){(0,_bulkselection.toggleBulkSelectionAction)(this.reactive,target,event,"cm")}async _requestToggleSelectionSection(target,event){(0,_bulkselection.toggleBulkSelectionAction)(this.reactive,target,event,"section")}async _requestMutationAction(target,event,mutationName){target.dataset.id&&(event.preventDefault(),this.reactive.dispatch(mutationName,[target.dataset.id]))}async _requestCmDuplicate(target,event){var _target$dataset$secti;const cmIds=this._getTargetIds(target);if(0==cmIds.length)return;const sectionId=null!==(_target$dataset$secti=target.dataset.sectionid)&&void 0!==_target$dataset$secti?_target$dataset$secti:null;event.preventDefault(),this.reactive.dispatch("cmDuplicate",cmIds,sectionId)}async _requestCmDelete(target,event){const cmIds=this._getTargetIds(target);if(0==cmIds.length)return;event.preventDefault();let bodyText=null,titleText=null;if(1==cmIds.length){const cmInfo=this.reactive.get("cm",cmIds[0]);titleText=(0,_str.getString)("cmdelete_title","core_courseformat"),bodyText=(0,_str.getString)("cmdelete_info","core_courseformat",{type:cmInfo.modname,name:cmInfo.name})}else titleText=(0,_str.getString)("cmsdelete_title","core_courseformat"),bodyText=(0,_str.getString)("cmsdelete_info","core_courseformat",{count:cmIds.length});const modal=await this._modalBodyRenderedPromise(_modal_delete_cancel.default,{title:titleText,body:bodyText});modal.getRoot().on(_modal_events.default.delete,(e=>{e.preventDefault(),modal.destroy(),this.reactive.dispatch("cmDelete",cmIds)}))}async _requestCmAvailability(target){const cmIds=this._getTargetIds(target);if(0==cmIds.length)return;const data={allowstealth:this.reactive.getExporter().canUseStealth(this.reactive.state,cmIds)},modal=await this._modalBodyRenderedPromise(_modal_save_cancel.default,{title:(0,_str.getString)("availability","core"),body:_templates.default.render("core_courseformat/local/content/cm/availabilitymodal",data),saveButtonText:(0,_str.getString)("apply","core")});this._setupMutationRadioButtonModal(modal,cmIds)}async _requestSectionAvailability(target){const sectionIds=this._getTargetIds(target);if(0==sectionIds.length)return;const title=1==sectionIds.length?"sectionavailability_title":"sectionsavailability_title",modal=await this._modalBodyRenderedPromise(_modal_save_cancel.default,{title:this.reactive.getFormatString(title),body:_templates.default.render("core_courseformat/local/content/section/availabilitymodal",[]),saveButtonText:(0,_str.getString)("apply","core")});this._setupMutationRadioButtonModal(modal,sectionIds)}_setupMutationRadioButtonModal(modal,ids){modal.setButtonDisabled("save",!0);const submitFunction=radio=>{const mutation=null==radio?void 0:radio.value;return!!mutation&&(this.reactive.dispatch(mutation,ids),!0)},modalBody=(0,_normalise.getFirst)(modal.getBody());modalBody.querySelectorAll(this.selectors.OPTIONSRADIO).forEach((radio=>{radio.addEventListener("change",(()=>{modal.setButtonDisabled("save",!1)})),radio.parentNode.addEventListener("click",(()=>{radio.checked=!0,modal.setButtonDisabled("save",!1)})),radio.parentNode.addEventListener("dblclick",(dbClickEvent=>{submitFunction(radio)&&(dbClickEvent.preventDefault(),modal.destroy())}))})),modal.getRoot().on(_modal_events.default.save,(()=>{const radio=modalBody.querySelector("".concat(this.selectors.OPTIONSRADIO,":checked"));submitFunction(radio)}))}_setAddSectionLocked(locked){this.getElements(this.selectors.ADDSECTION).forEach((element=>{element.classList.toggle(this.classes.DISABLED,locked),element.classList.toggle(this.classes.ITALIC,locked),this.setElementLocked(element,locked)}))}_disableLink(element){element&&(element.style.pointerEvents="none",element.style.userSelect="none",element.classList.add(this.classes.DISABLED),element.classList.add(this.classes.ITALIC),element.setAttribute("aria-disabled",!0),element.addEventListener("click",(event=>event.preventDefault())))}_modalBodyRenderedPromise(ModalClass,modalParams){return new Promise(((resolve,reject)=>{ModalClass.create(modalParams).then((modal=>{modal.setRemoveOnClose(!0),modal.getRoot().on(_modal_events.default.bodyRendered,(()=>{resolve(modal)})),void 0!==modalParams.saveButtonText&&modal.setSaveButtonText(modalParams.saveButtonText),void 0!==modalParams.deleteButtonText&&modal.setDeleteButtonText(modalParams.saveButtonText),modal.show()})).catch((()=>{reject("Cannot load modal content")}))}))}_destroyModal(modal,element){modal.hide();const pendingDestroy=new _pending.default("courseformat/actions:destroyModal");element&&element.focus(),setTimeout((()=>{modal.destroy(),pendingDestroy.resolve()}),500)}_getClosestActionMenuToogler(element){const actionMenu=element.closest(this.selectors.ACTIONMENU);if(actionMenu)return actionMenu.querySelector(this.selectors.ACTIONMENUTOGGLER)}}return _exports.default=_default,_exports.default})); //# sourceMappingURL=actions.min.js.map \ No newline at end of file diff --git a/course/format/amd/build/local/content/actions.min.js.map b/course/format/amd/build/local/content/actions.min.js.map index 016ef4e721c..4defcf270b1 100644 --- a/course/format/amd/build/local/content/actions.min.js.map +++ b/course/format/amd/build/local/content/actions.min.js.map @@ -1 +1 @@ -{"version":3,"file":"actions.min.js","sources":["../../../src/local/content/actions.js"],"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 * Course state actions dispatcher.\n *\n * This module captures all data-dispatch links in the course content and dispatch the proper\n * state mutation, including any confirmation and modal required.\n *\n * @module core_courseformat/local/content/actions\n * @class core_courseformat/local/content/actions\n * @copyright 2021 Ferran Recio \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {BaseComponent} from 'core/reactive';\nimport ModalFactory from 'core/modal_factory';\nimport ModalEvents from 'core/modal_events';\nimport Templates from 'core/templates';\nimport {prefetchStrings} from 'core/prefetch';\nimport {getString} from 'core/str';\nimport {getFirst} from 'core/normalise';\nimport {toggleBulkSelectionAction} from 'core_courseformat/local/content/actions/bulkselection';\nimport * as CourseEvents from 'core_course/events';\nimport Pending from 'core/pending';\nimport ContentTree from 'core_courseformat/local/courseeditor/contenttree';\n// The jQuery module is only used for interacting with Boostrap 4. It can we removed when MDL-71979 is integrated.\nimport jQuery from 'jquery';\n\n// Load global strings.\nprefetchStrings('core', ['movecoursesection', 'movecoursemodule', 'confirm', 'delete']);\n\n// Mutations are dispatched by the course content actions.\n// Formats can use this module addActions static method to add custom actions.\n// Direct mutations can be simple strings (mutation) name or functions.\nconst directMutations = {\n sectionHide: 'sectionHide',\n sectionShow: 'sectionShow',\n cmHide: 'cmHide',\n cmShow: 'cmShow',\n cmStealth: 'cmStealth',\n cmMoveRight: 'cmMoveRight',\n cmMoveLeft: 'cmMoveLeft',\n cmNoGroups: 'cmNoGroups',\n cmSeparateGroups: 'cmSeparateGroups',\n cmVisibleGroups: 'cmVisibleGroups',\n};\n\nexport default class extends BaseComponent {\n\n /**\n * Constructor hook.\n */\n create() {\n // Optional component name for debugging.\n this.name = 'content_actions';\n // Default query selectors.\n this.selectors = {\n ACTIONLINK: `[data-action]`,\n // Move modal selectors.\n SECTIONLINK: `[data-for='section']`,\n CMLINK: `[data-for='cm']`,\n SECTIONNODE: `[data-for='sectionnode']`,\n MODALTOGGLER: `[data-toggle='collapse']`,\n ADDSECTION: `[data-action='addSection']`,\n CONTENTTREE: `#destination-selector`,\n ACTIONMENU: `.action-menu`,\n ACTIONMENUTOGGLER: `[data-toggle=\"dropdown\"]`,\n // Availability modal selectors.\n OPTIONSRADIO: `[type='radio']`,\n };\n // Component css classes.\n this.classes = {\n DISABLED: `text-body`,\n ITALIC: `font-italic`,\n };\n }\n\n /**\n * Add extra actions to the module.\n *\n * @param {array} actions array of methods to execute\n */\n static addActions(actions) {\n for (const [action, mutationReference] of Object.entries(actions)) {\n if (typeof mutationReference !== 'function' && typeof mutationReference !== 'string') {\n throw new Error(`${action} action must be a mutation name or a function`);\n }\n directMutations[action] = mutationReference;\n }\n }\n\n /**\n * Initial state ready method.\n *\n * @param {Object} state the state data.\n *\n */\n stateReady(state) {\n // Delegate dispatch clicks.\n this.addEventListener(\n this.element,\n 'click',\n this._dispatchClick\n );\n // Check section limit.\n this._checkSectionlist({state});\n // Add an Event listener to recalculate limits it if a section HTML is altered.\n this.addEventListener(\n this.element,\n CourseEvents.sectionRefreshed,\n () => this._checkSectionlist({state})\n );\n }\n\n /**\n * Return the component watchers.\n *\n * @returns {Array} of watchers\n */\n getWatchers() {\n return [\n // Check section limit.\n {watch: `course.sectionlist:updated`, handler: this._checkSectionlist},\n ];\n }\n\n _dispatchClick(event) {\n const target = event.target.closest(this.selectors.ACTIONLINK);\n if (!target) {\n return;\n }\n if (target.classList.contains(this.classes.DISABLED)) {\n event.preventDefault();\n return;\n }\n\n // Invoke proper method.\n const actionName = target.dataset.action;\n const methodName = this._actionMethodName(actionName);\n\n if (this[methodName] !== undefined) {\n this[methodName](target, event);\n return;\n }\n\n // Check direct mutations or mutations handlers.\n if (directMutations[actionName] !== undefined) {\n if (typeof directMutations[actionName] === 'function') {\n directMutations[actionName](target, event);\n return;\n }\n this._requestMutationAction(target, event, directMutations[actionName]);\n return;\n }\n }\n\n _actionMethodName(name) {\n const requestName = name.charAt(0).toUpperCase() + name.slice(1);\n return `_request${requestName}`;\n }\n\n /**\n * Check the section list and disable some options if needed.\n *\n * @param {Object} detail the update details.\n * @param {Object} detail.state the state object.\n */\n _checkSectionlist({state}) {\n // Disable \"add section\" actions if the course max sections has been exceeded.\n this._setAddSectionLocked(state.course.sectionlist.length > state.course.maxsections);\n }\n\n /**\n * Return the ids represented by this element.\n *\n * Depending on the dataset attributes the action could represent a single id\n * or a bulk actions with all the current selected ids.\n *\n * @param {HTMLElement} target\n * @returns {Number[]} array of Ids\n */\n _getTargetIds(target) {\n let ids = [];\n if (target?.dataset?.id) {\n ids.push(target.dataset.id);\n }\n const bulkType = target?.dataset?.bulk;\n if (!bulkType) {\n return ids;\n }\n const bulk = this.reactive.get('bulk');\n if (bulk.enabled && bulk.selectedType === bulkType) {\n ids = [...ids, ...bulk.selection];\n }\n return ids;\n }\n\n /**\n * Handle a move section request.\n *\n * @param {Element} target the dispatch action element\n * @param {Event} event the triggered event\n */\n async _requestMoveSection(target, event) {\n // Check we have an id.\n const sectionIds = this._getTargetIds(target);\n if (sectionIds.length == 0) {\n return;\n }\n\n event.preventDefault();\n\n const pendingModalReady = new Pending(`courseformat/actions:prepareMoveSectionModal`);\n\n // The section edit menu to refocus on end.\n const editTools = this._getClosestActionMenuToogler(target);\n\n // Collect section information from the state.\n const exporter = this.reactive.getExporter();\n const data = exporter.course(this.reactive.state);\n let titleText = null;\n\n // Add the target section id and title.\n let sectionInfo = null;\n if (sectionIds.length == 1) {\n sectionInfo = this.reactive.get('section', sectionIds[0]);\n data.sectionid = sectionInfo.id;\n data.sectiontitle = sectionInfo.title;\n data.information = await this.reactive.getFormatString('sectionmove_info', data.sectiontitle);\n titleText = this.reactive.getFormatString('sectionmove_title');\n } else {\n data.information = await this.reactive.getFormatString('sectionsmove_info', sectionIds.length);\n titleText = this.reactive.getFormatString('sectionsmove_title');\n }\n\n\n // Build the modal parameters from the event data.\n const modalParams = {\n title: titleText,\n body: Templates.render('core_courseformat/local/content/movesection', data),\n };\n\n // Create the modal.\n const modal = await this._modalBodyRenderedPromise(modalParams);\n\n const modalBody = getFirst(modal.getBody());\n\n // Disable current selected section ids.\n sectionIds.forEach(sectionId => {\n const currentElement = modalBody.querySelector(`${this.selectors.SECTIONLINK}[data-id='${sectionId}']`);\n this._disableLink(currentElement);\n });\n\n // Setup keyboard navigation.\n new ContentTree(\n modalBody.querySelector(this.selectors.CONTENTTREE),\n {\n SECTION: this.selectors.SECTIONNODE,\n TOGGLER: this.selectors.MODALTOGGLER,\n COLLAPSE: this.selectors.MODALTOGGLER,\n },\n true\n );\n\n // Capture click.\n modalBody.addEventListener('click', (event) => {\n const target = event.target;\n if (!target.matches('a') || target.dataset.for != 'section' || target.dataset.id === undefined) {\n return;\n }\n if (target.getAttribute('aria-disabled')) {\n return;\n }\n event.preventDefault();\n this.reactive.dispatch('sectionMoveAfter', sectionIds, target.dataset.id);\n this._destroyModal(modal, editTools);\n });\n\n pendingModalReady.resolve();\n }\n\n /**\n * Handle a move cm request.\n *\n * @param {Element} target the dispatch action element\n * @param {Event} event the triggered event\n */\n async _requestMoveCm(target, event) {\n // Check we have an id.\n const cmIds = this._getTargetIds(target);\n if (cmIds.length == 0) {\n return;\n }\n\n event.preventDefault();\n\n const pendingModalReady = new Pending(`courseformat/actions:prepareMoveCmModal`);\n\n // The section edit menu to refocus on end.\n const editTools = this._getClosestActionMenuToogler(target);\n\n // Collect information from the state.\n const exporter = this.reactive.getExporter();\n const data = exporter.course(this.reactive.state);\n\n let titleText = null;\n if (cmIds.length == 1) {\n const cmInfo = this.reactive.get('cm', cmIds[0]);\n data.cmid = cmInfo.id;\n data.cmname = cmInfo.name;\n data.information = await this.reactive.getFormatString('cmmove_info', data.cmname);\n titleText = this.reactive.getFormatString('cmmove_title');\n } else {\n data.information = await this.reactive.getFormatString('cmsmove_info', cmIds.length);\n titleText = this.reactive.getFormatString('cmsmove_title');\n }\n\n // Build the modal parameters from the event data.\n const modalParams = {\n title: titleText,\n body: Templates.render('core_courseformat/local/content/movecm', data),\n };\n\n // Create the modal.\n const modal = await this._modalBodyRenderedPromise(modalParams);\n\n const modalBody = getFirst(modal.getBody());\n\n // Disable current selected section ids.\n cmIds.forEach(cmId => {\n const currentElement = modalBody.querySelector(`${this.selectors.CMLINK}[data-id='${cmId}']`);\n this._disableLink(currentElement);\n });\n\n // Setup keyboard navigation.\n new ContentTree(\n modalBody.querySelector(this.selectors.CONTENTTREE),\n {\n SECTION: this.selectors.SECTIONNODE,\n TOGGLER: this.selectors.MODALTOGGLER,\n COLLAPSE: this.selectors.MODALTOGGLER,\n ENTER: this.selectors.SECTIONLINK,\n }\n );\n\n // Open the cm section node if possible (Bootstrap 4 uses jQuery to interact with collapsibles).\n // All jQuery in this code can be replaced when MDL-71979 is integrated.\n cmIds.forEach(cmId => {\n const currentElement = modalBody.querySelector(`${this.selectors.CMLINK}[data-id='${cmId}']`);\n const sectionnode = currentElement.closest(this.selectors.SECTIONNODE);\n const toggler = jQuery(sectionnode).find(this.selectors.MODALTOGGLER);\n let collapsibleId = toggler.data('target') ?? toggler.attr('href');\n if (collapsibleId) {\n // We cannot be sure we have # in the id element name.\n collapsibleId = collapsibleId.replace('#', '');\n const expandNode = modalBody.querySelector(`#${collapsibleId}`);\n jQuery(expandNode).collapse('show');\n }\n });\n\n modalBody.addEventListener('click', (event) => {\n const target = event.target;\n if (!target.matches('a') || target.dataset.for === undefined || target.dataset.id === undefined) {\n return;\n }\n if (target.getAttribute('aria-disabled')) {\n return;\n }\n event.preventDefault();\n\n let targetSectionId;\n let targetCmId;\n if (target.dataset.for == 'cm') {\n const dropData = exporter.cmDraggableData(this.reactive.state, target.dataset.id);\n targetSectionId = dropData.sectionid;\n targetCmId = dropData.nextcmid;\n } else {\n const section = this.reactive.get('section', target.dataset.id);\n targetSectionId = target.dataset.id;\n targetCmId = section?.cmlist[0];\n }\n this.reactive.dispatch('cmMove', cmIds, targetSectionId, targetCmId);\n this._destroyModal(modal, editTools);\n });\n\n pendingModalReady.resolve();\n }\n\n /**\n * Handle a create section request.\n *\n * @param {Element} target the dispatch action element\n * @param {Event} event the triggered event\n */\n async _requestAddSection(target, event) {\n event.preventDefault();\n this.reactive.dispatch('addSection', target.dataset.id ?? 0);\n }\n\n /**\n * Handle a delete section request.\n *\n * @param {Element} target the dispatch action element\n * @param {Event} event the triggered event\n */\n async _requestDeleteSection(target, event) {\n const sectionIds = this._getTargetIds(target);\n if (sectionIds.length == 0) {\n return;\n }\n\n event.preventDefault();\n\n // We don't need confirmation to delete empty sections.\n let needsConfirmation = sectionIds.some(sectionId => {\n const sectionInfo = this.reactive.get('section', sectionId);\n const cmList = sectionInfo.cmlist ?? [];\n return (cmList.length || sectionInfo.hassummary || sectionInfo.rawtitle);\n });\n if (!needsConfirmation) {\n this.reactive.dispatch('sectionDelete', sectionIds);\n return;\n }\n\n let bodyText = null;\n let titleText = null;\n if (sectionIds.length == 1) {\n titleText = this.reactive.getFormatString('sectiondelete_title');\n const sectionInfo = this.reactive.get('section', sectionIds[0]);\n bodyText = this.reactive.getFormatString('sectiondelete_info', {name: sectionInfo.title});\n } else {\n titleText = this.reactive.getFormatString('sectionsdelete_title');\n bodyText = this.reactive.getFormatString('sectionsdelete_info', {count: sectionIds.length});\n }\n\n const modalParams = {\n title: titleText,\n body: bodyText,\n type: ModalFactory.types.DELETE_CANCEL,\n };\n\n const modal = await this._modalBodyRenderedPromise(modalParams);\n\n modal.getRoot().on(\n ModalEvents.delete,\n e => {\n // Stop the default save button behaviour which is to close the modal.\n e.preventDefault();\n modal.destroy();\n this.reactive.dispatch('sectionDelete', sectionIds);\n }\n );\n }\n\n /**\n * Handle a toggle cm selection.\n *\n * @param {Element} target the dispatch action element\n * @param {Event} event the triggered event\n */\n async _requestToggleSelectionCm(target, event) {\n toggleBulkSelectionAction(this.reactive, target, event, 'cm');\n }\n\n /**\n * Handle a toggle section selection.\n *\n * @param {Element} target the dispatch action element\n * @param {Event} event the triggered event\n */\n async _requestToggleSelectionSection(target, event) {\n toggleBulkSelectionAction(this.reactive, target, event, 'section');\n }\n\n /**\n * Basic mutation action helper.\n *\n * @param {Element} target the dispatch action element\n * @param {Event} event the triggered event\n * @param {string} mutationName the mutation name\n */\n async _requestMutationAction(target, event, mutationName) {\n if (!target.dataset.id) {\n return;\n }\n event.preventDefault();\n this.reactive.dispatch(mutationName, [target.dataset.id]);\n }\n\n /**\n * Handle a course module duplicate request.\n *\n * @param {Element} target the dispatch action element\n * @param {Event} event the triggered event\n */\n async _requestCmDuplicate(target, event) {\n const cmIds = this._getTargetIds(target);\n if (cmIds.length == 0) {\n return;\n }\n const sectionId = target.dataset.sectionid ?? null;\n event.preventDefault();\n this.reactive.dispatch('cmDuplicate', cmIds, sectionId);\n }\n\n /**\n * Handle a delete cm request.\n *\n * @param {Element} target the dispatch action element\n * @param {Event} event the triggered event\n */\n async _requestCmDelete(target, event) {\n const cmIds = this._getTargetIds(target);\n if (cmIds.length == 0) {\n return;\n }\n\n event.preventDefault();\n\n let bodyText = null;\n let titleText = null;\n if (cmIds.length == 1) {\n const cmInfo = this.reactive.get('cm', cmIds[0]);\n titleText = getString('cmdelete_title', 'core_courseformat');\n bodyText = getString(\n 'cmdelete_info',\n 'core_courseformat',\n {\n type: cmInfo.modname,\n name: cmInfo.name,\n }\n );\n } else {\n titleText = getString('cmsdelete_title', 'core_courseformat');\n bodyText = getString(\n 'cmsdelete_info',\n 'core_courseformat',\n {count: cmIds.length}\n );\n }\n\n const modalParams = {\n title: titleText,\n body: bodyText,\n type: ModalFactory.types.DELETE_CANCEL,\n };\n\n const modal = await this._modalBodyRenderedPromise(modalParams);\n\n modal.getRoot().on(\n ModalEvents.delete,\n e => {\n // Stop the default save button behaviour which is to close the modal.\n e.preventDefault();\n modal.destroy();\n this.reactive.dispatch('cmDelete', cmIds);\n }\n );\n }\n\n /**\n * Handle a cm availability change request.\n *\n * @param {Element} target the dispatch action element\n */\n async _requestCmAvailability(target) {\n const cmIds = this._getTargetIds(target);\n if (cmIds.length == 0) {\n return;\n }\n // Show the availability modal to decide which action to trigger.\n const exporter = this.reactive.getExporter();\n const data = {\n allowstealth: exporter.canUseStealth(this.reactive.state, cmIds),\n };\n const modalParams = {\n title: getString('availability', 'core'),\n body: Templates.render('core_courseformat/local/content/cm/availabilitymodal', data),\n saveButtonText: getString('apply', 'core'),\n type: ModalFactory.types.SAVE_CANCEL,\n };\n const modal = await this._modalBodyRenderedPromise(modalParams);\n\n this._setupMutationRadioButtonModal(modal, cmIds);\n }\n\n /**\n * Handle a section availability change request.\n *\n * @param {Element} target the dispatch action element\n */\n async _requestSectionAvailability(target) {\n const sectionIds = this._getTargetIds(target);\n if (sectionIds.length == 0) {\n return;\n }\n const title = (sectionIds.length == 1) ? 'sectionavailability_title' : 'sectionsavailability_title';\n // Show the availability modal to decide which action to trigger.\n const modalParams = {\n title: this.reactive.getFormatString(title),\n body: Templates.render('core_courseformat/local/content/section/availabilitymodal', []),\n saveButtonText: getString('apply', 'core'),\n type: ModalFactory.types.SAVE_CANCEL,\n };\n const modal = await this._modalBodyRenderedPromise(modalParams);\n\n this._setupMutationRadioButtonModal(modal, sectionIds);\n }\n\n /**\n * Add events to a mutation selector radio buttons modal.\n * @param {Modal} modal\n * @param {Number[]} ids the section or cm ids to apply the mutation\n */\n _setupMutationRadioButtonModal(modal, ids) {\n // The save button is not enabled until the user selects an option.\n modal.setButtonDisabled('save', true);\n\n const submitFunction = (radio) => {\n const mutation = radio?.value;\n if (!mutation) {\n return false;\n }\n this.reactive.dispatch(mutation, ids);\n return true;\n };\n\n const modalBody = getFirst(modal.getBody());\n const radioOptions = modalBody.querySelectorAll(this.selectors.OPTIONSRADIO);\n radioOptions.forEach(radio => {\n radio.addEventListener('change', () => {\n modal.setButtonDisabled('save', false);\n });\n radio.parentNode.addEventListener('click', () => {\n radio.checked = true;\n modal.setButtonDisabled('save', false);\n });\n radio.parentNode.addEventListener('dblclick', dbClickEvent => {\n if (submitFunction(radio)) {\n dbClickEvent.preventDefault();\n modal.destroy();\n }\n });\n });\n\n modal.getRoot().on(\n ModalEvents.save,\n () => {\n const radio = modalBody.querySelector(`${this.selectors.OPTIONSRADIO}:checked`);\n submitFunction(radio);\n }\n );\n }\n\n /**\n * Disable all add sections actions.\n *\n * @param {boolean} locked the new locked value.\n */\n _setAddSectionLocked(locked) {\n const targets = this.getElements(this.selectors.ADDSECTION);\n targets.forEach(element => {\n element.classList.toggle(this.classes.DISABLED, locked);\n element.classList.toggle(this.classes.ITALIC, locked);\n this.setElementLocked(element, locked);\n });\n }\n\n /**\n * Replace an element with a copy with a different tag name.\n *\n * @param {Element} element the original element\n */\n _disableLink(element) {\n if (element) {\n element.style.pointerEvents = 'none';\n element.style.userSelect = 'none';\n element.classList.add(this.classes.DISABLED);\n element.classList.add(this.classes.ITALIC);\n element.setAttribute('aria-disabled', true);\n element.addEventListener('click', event => event.preventDefault());\n }\n }\n\n /**\n * Render a modal and return a body ready promise.\n *\n * @param {object} modalParams the modal params\n * @return {Promise} the modal body ready promise\n */\n _modalBodyRenderedPromise(modalParams) {\n return new Promise((resolve, reject) => {\n ModalFactory.create(modalParams).then((modal) => {\n modal.setRemoveOnClose(true);\n // Handle body loading event.\n modal.getRoot().on(ModalEvents.bodyRendered, () => {\n resolve(modal);\n });\n // Configure some extra modal params.\n if (modalParams.saveButtonText !== undefined) {\n modal.setSaveButtonText(modalParams.saveButtonText);\n }\n if (modalParams.deleteButtonText !== undefined) {\n modal.setDeleteButtonText(modalParams.saveButtonText);\n }\n modal.show();\n return;\n }).catch(() => {\n reject(`Cannot load modal content`);\n });\n });\n }\n\n /**\n * Hide and later destroy a modal.\n *\n * Behat will fail if we remove the modal while some boostrap collapse is executing.\n *\n * @param {Modal} modal\n * @param {HTMLElement} element the dom element to focus on.\n */\n _destroyModal(modal, element) {\n modal.hide();\n const pendingDestroy = new Pending(`courseformat/actions:destroyModal`);\n if (element) {\n element.focus();\n }\n setTimeout(() =>{\n modal.destroy();\n pendingDestroy.resolve();\n }, 500);\n }\n\n /**\n * Get the closest actions menu toggler to an action element.\n *\n * @param {HTMLElement} element the action link element\n * @returns {HTMLElement|undefined}\n */\n _getClosestActionMenuToogler(element) {\n const actionMenu = element.closest(this.selectors.ACTIONMENU);\n if (!actionMenu) {\n return undefined;\n }\n return actionMenu.querySelector(this.selectors.ACTIONMENUTOGGLER);\n }\n}\n"],"names":["directMutations","sectionHide","sectionShow","cmHide","cmShow","cmStealth","cmMoveRight","cmMoveLeft","cmNoGroups","cmSeparateGroups","cmVisibleGroups","BaseComponent","create","name","selectors","ACTIONLINK","SECTIONLINK","CMLINK","SECTIONNODE","MODALTOGGLER","ADDSECTION","CONTENTTREE","ACTIONMENU","ACTIONMENUTOGGLER","OPTIONSRADIO","classes","DISABLED","ITALIC","actions","action","mutationReference","Object","entries","Error","stateReady","state","addEventListener","this","element","_dispatchClick","_checkSectionlist","CourseEvents","sectionRefreshed","getWatchers","watch","handler","event","target","closest","classList","contains","preventDefault","actionName","dataset","methodName","_actionMethodName","undefined","_requestMutationAction","requestName","charAt","toUpperCase","slice","_setAddSectionLocked","course","sectionlist","length","maxsections","_getTargetIds","ids","_target$dataset","id","push","bulkType","_target$dataset2","bulk","reactive","get","enabled","selectedType","selection","sectionIds","pendingModalReady","Pending","editTools","_getClosestActionMenuToogler","data","getExporter","titleText","sectionInfo","sectionid","sectiontitle","title","information","getFormatString","modalParams","body","Templates","render","modal","_modalBodyRenderedPromise","modalBody","getBody","forEach","sectionId","currentElement","querySelector","_disableLink","ContentTree","SECTION","TOGGLER","COLLAPSE","matches","for","getAttribute","dispatch","_destroyModal","resolve","cmIds","exporter","cmInfo","cmid","cmname","cmId","ENTER","sectionnode","toggler","find","collapsibleId","attr","replace","expandNode","collapse","targetSectionId","targetCmId","dropData","cmDraggableData","nextcmid","section","cmlist","some","hassummary","rawtitle","bodyText","count","type","ModalFactory","types","DELETE_CANCEL","getRoot","on","ModalEvents","delete","e","destroy","mutationName","modname","allowstealth","canUseStealth","saveButtonText","SAVE_CANCEL","_setupMutationRadioButtonModal","setButtonDisabled","submitFunction","radio","mutation","value","querySelectorAll","parentNode","checked","dbClickEvent","save","locked","getElements","toggle","setElementLocked","style","pointerEvents","userSelect","add","setAttribute","Promise","reject","then","setRemoveOnClose","bodyRendered","setSaveButtonText","deleteButtonText","setDeleteButtonText","show","catch","hide","pendingDestroy","focus","setTimeout","actionMenu"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"actions.min.js","sources":["../../../src/local/content/actions.js"],"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 * Course state actions dispatcher.\n *\n * This module captures all data-dispatch links in the course content and dispatch the proper\n * state mutation, including any confirmation and modal required.\n *\n * @module core_courseformat/local/content/actions\n * @class core_courseformat/local/content/actions\n * @copyright 2021 Ferran Recio \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {BaseComponent} from 'core/reactive';\nimport Modal from 'core/modal';\nimport ModalSaveCancel from 'core/modal_save_cancel';\nimport ModalDeleteCancel from 'core/modal_delete_cancel';\nimport ModalEvents from 'core/modal_events';\nimport Templates from 'core/templates';\nimport {prefetchStrings} from 'core/prefetch';\nimport {getString} from 'core/str';\nimport {getFirst} from 'core/normalise';\nimport {toggleBulkSelectionAction} from 'core_courseformat/local/content/actions/bulkselection';\nimport * as CourseEvents from 'core_course/events';\nimport Pending from 'core/pending';\nimport ContentTree from 'core_courseformat/local/courseeditor/contenttree';\n// The jQuery module is only used for interacting with Boostrap 4. It can we removed when MDL-71979 is integrated.\nimport jQuery from 'jquery';\n\n// Load global strings.\nprefetchStrings('core', ['movecoursesection', 'movecoursemodule', 'confirm', 'delete']);\n\n// Mutations are dispatched by the course content actions.\n// Formats can use this module addActions static method to add custom actions.\n// Direct mutations can be simple strings (mutation) name or functions.\nconst directMutations = {\n sectionHide: 'sectionHide',\n sectionShow: 'sectionShow',\n cmHide: 'cmHide',\n cmShow: 'cmShow',\n cmStealth: 'cmStealth',\n cmMoveRight: 'cmMoveRight',\n cmMoveLeft: 'cmMoveLeft',\n cmNoGroups: 'cmNoGroups',\n cmSeparateGroups: 'cmSeparateGroups',\n cmVisibleGroups: 'cmVisibleGroups',\n};\n\nexport default class extends BaseComponent {\n\n /**\n * Constructor hook.\n */\n create() {\n // Optional component name for debugging.\n this.name = 'content_actions';\n // Default query selectors.\n this.selectors = {\n ACTIONLINK: `[data-action]`,\n // Move modal selectors.\n SECTIONLINK: `[data-for='section']`,\n CMLINK: `[data-for='cm']`,\n SECTIONNODE: `[data-for='sectionnode']`,\n MODALTOGGLER: `[data-toggle='collapse']`,\n ADDSECTION: `[data-action='addSection']`,\n CONTENTTREE: `#destination-selector`,\n ACTIONMENU: `.action-menu`,\n ACTIONMENUTOGGLER: `[data-toggle=\"dropdown\"]`,\n // Availability modal selectors.\n OPTIONSRADIO: `[type='radio']`,\n };\n // Component css classes.\n this.classes = {\n DISABLED: `text-body`,\n ITALIC: `font-italic`,\n };\n }\n\n /**\n * Add extra actions to the module.\n *\n * @param {array} actions array of methods to execute\n */\n static addActions(actions) {\n for (const [action, mutationReference] of Object.entries(actions)) {\n if (typeof mutationReference !== 'function' && typeof mutationReference !== 'string') {\n throw new Error(`${action} action must be a mutation name or a function`);\n }\n directMutations[action] = mutationReference;\n }\n }\n\n /**\n * Initial state ready method.\n *\n * @param {Object} state the state data.\n *\n */\n stateReady(state) {\n // Delegate dispatch clicks.\n this.addEventListener(\n this.element,\n 'click',\n this._dispatchClick\n );\n // Check section limit.\n this._checkSectionlist({state});\n // Add an Event listener to recalculate limits it if a section HTML is altered.\n this.addEventListener(\n this.element,\n CourseEvents.sectionRefreshed,\n () => this._checkSectionlist({state})\n );\n }\n\n /**\n * Return the component watchers.\n *\n * @returns {Array} of watchers\n */\n getWatchers() {\n return [\n // Check section limit.\n {watch: `course.sectionlist:updated`, handler: this._checkSectionlist},\n ];\n }\n\n _dispatchClick(event) {\n const target = event.target.closest(this.selectors.ACTIONLINK);\n if (!target) {\n return;\n }\n if (target.classList.contains(this.classes.DISABLED)) {\n event.preventDefault();\n return;\n }\n\n // Invoke proper method.\n const actionName = target.dataset.action;\n const methodName = this._actionMethodName(actionName);\n\n if (this[methodName] !== undefined) {\n this[methodName](target, event);\n return;\n }\n\n // Check direct mutations or mutations handlers.\n if (directMutations[actionName] !== undefined) {\n if (typeof directMutations[actionName] === 'function') {\n directMutations[actionName](target, event);\n return;\n }\n this._requestMutationAction(target, event, directMutations[actionName]);\n return;\n }\n }\n\n _actionMethodName(name) {\n const requestName = name.charAt(0).toUpperCase() + name.slice(1);\n return `_request${requestName}`;\n }\n\n /**\n * Check the section list and disable some options if needed.\n *\n * @param {Object} detail the update details.\n * @param {Object} detail.state the state object.\n */\n _checkSectionlist({state}) {\n // Disable \"add section\" actions if the course max sections has been exceeded.\n this._setAddSectionLocked(state.course.sectionlist.length > state.course.maxsections);\n }\n\n /**\n * Return the ids represented by this element.\n *\n * Depending on the dataset attributes the action could represent a single id\n * or a bulk actions with all the current selected ids.\n *\n * @param {HTMLElement} target\n * @returns {Number[]} array of Ids\n */\n _getTargetIds(target) {\n let ids = [];\n if (target?.dataset?.id) {\n ids.push(target.dataset.id);\n }\n const bulkType = target?.dataset?.bulk;\n if (!bulkType) {\n return ids;\n }\n const bulk = this.reactive.get('bulk');\n if (bulk.enabled && bulk.selectedType === bulkType) {\n ids = [...ids, ...bulk.selection];\n }\n return ids;\n }\n\n /**\n * Handle a move section request.\n *\n * @param {Element} target the dispatch action element\n * @param {Event} event the triggered event\n */\n async _requestMoveSection(target, event) {\n // Check we have an id.\n const sectionIds = this._getTargetIds(target);\n if (sectionIds.length == 0) {\n return;\n }\n\n event.preventDefault();\n\n const pendingModalReady = new Pending(`courseformat/actions:prepareMoveSectionModal`);\n\n // The section edit menu to refocus on end.\n const editTools = this._getClosestActionMenuToogler(target);\n\n // Collect section information from the state.\n const exporter = this.reactive.getExporter();\n const data = exporter.course(this.reactive.state);\n let titleText = null;\n\n // Add the target section id and title.\n let sectionInfo = null;\n if (sectionIds.length == 1) {\n sectionInfo = this.reactive.get('section', sectionIds[0]);\n data.sectionid = sectionInfo.id;\n data.sectiontitle = sectionInfo.title;\n data.information = await this.reactive.getFormatString('sectionmove_info', data.sectiontitle);\n titleText = this.reactive.getFormatString('sectionmove_title');\n } else {\n data.information = await this.reactive.getFormatString('sectionsmove_info', sectionIds.length);\n titleText = this.reactive.getFormatString('sectionsmove_title');\n }\n\n\n // Create the modal.\n // Build the modal parameters from the event data.\n const modal = await this._modalBodyRenderedPromise(Modal, {\n title: titleText,\n body: Templates.render('core_courseformat/local/content/movesection', data),\n });\n\n const modalBody = getFirst(modal.getBody());\n\n // Disable current selected section ids.\n sectionIds.forEach(sectionId => {\n const currentElement = modalBody.querySelector(`${this.selectors.SECTIONLINK}[data-id='${sectionId}']`);\n this._disableLink(currentElement);\n });\n\n // Setup keyboard navigation.\n new ContentTree(\n modalBody.querySelector(this.selectors.CONTENTTREE),\n {\n SECTION: this.selectors.SECTIONNODE,\n TOGGLER: this.selectors.MODALTOGGLER,\n COLLAPSE: this.selectors.MODALTOGGLER,\n },\n true\n );\n\n // Capture click.\n modalBody.addEventListener('click', (event) => {\n const target = event.target;\n if (!target.matches('a') || target.dataset.for != 'section' || target.dataset.id === undefined) {\n return;\n }\n if (target.getAttribute('aria-disabled')) {\n return;\n }\n event.preventDefault();\n this.reactive.dispatch('sectionMoveAfter', sectionIds, target.dataset.id);\n this._destroyModal(modal, editTools);\n });\n\n pendingModalReady.resolve();\n }\n\n /**\n * Handle a move cm request.\n *\n * @param {Element} target the dispatch action element\n * @param {Event} event the triggered event\n */\n async _requestMoveCm(target, event) {\n // Check we have an id.\n const cmIds = this._getTargetIds(target);\n if (cmIds.length == 0) {\n return;\n }\n\n event.preventDefault();\n\n const pendingModalReady = new Pending(`courseformat/actions:prepareMoveCmModal`);\n\n // The section edit menu to refocus on end.\n const editTools = this._getClosestActionMenuToogler(target);\n\n // Collect information from the state.\n const exporter = this.reactive.getExporter();\n const data = exporter.course(this.reactive.state);\n\n let titleText = null;\n if (cmIds.length == 1) {\n const cmInfo = this.reactive.get('cm', cmIds[0]);\n data.cmid = cmInfo.id;\n data.cmname = cmInfo.name;\n data.information = await this.reactive.getFormatString('cmmove_info', data.cmname);\n titleText = this.reactive.getFormatString('cmmove_title');\n } else {\n data.information = await this.reactive.getFormatString('cmsmove_info', cmIds.length);\n titleText = this.reactive.getFormatString('cmsmove_title');\n }\n\n // Create the modal.\n // Build the modal parameters from the event data.\n const modal = await this._modalBodyRenderedPromise(Modal, {\n title: titleText,\n body: Templates.render('core_courseformat/local/content/movecm', data),\n });\n\n const modalBody = getFirst(modal.getBody());\n\n // Disable current selected section ids.\n cmIds.forEach(cmId => {\n const currentElement = modalBody.querySelector(`${this.selectors.CMLINK}[data-id='${cmId}']`);\n this._disableLink(currentElement);\n });\n\n // Setup keyboard navigation.\n new ContentTree(\n modalBody.querySelector(this.selectors.CONTENTTREE),\n {\n SECTION: this.selectors.SECTIONNODE,\n TOGGLER: this.selectors.MODALTOGGLER,\n COLLAPSE: this.selectors.MODALTOGGLER,\n ENTER: this.selectors.SECTIONLINK,\n }\n );\n\n // Open the cm section node if possible (Bootstrap 4 uses jQuery to interact with collapsibles).\n // All jQuery in this code can be replaced when MDL-71979 is integrated.\n cmIds.forEach(cmId => {\n const currentElement = modalBody.querySelector(`${this.selectors.CMLINK}[data-id='${cmId}']`);\n const sectionnode = currentElement.closest(this.selectors.SECTIONNODE);\n const toggler = jQuery(sectionnode).find(this.selectors.MODALTOGGLER);\n let collapsibleId = toggler.data('target') ?? toggler.attr('href');\n if (collapsibleId) {\n // We cannot be sure we have # in the id element name.\n collapsibleId = collapsibleId.replace('#', '');\n const expandNode = modalBody.querySelector(`#${collapsibleId}`);\n jQuery(expandNode).collapse('show');\n }\n });\n\n modalBody.addEventListener('click', (event) => {\n const target = event.target;\n if (!target.matches('a') || target.dataset.for === undefined || target.dataset.id === undefined) {\n return;\n }\n if (target.getAttribute('aria-disabled')) {\n return;\n }\n event.preventDefault();\n\n let targetSectionId;\n let targetCmId;\n if (target.dataset.for == 'cm') {\n const dropData = exporter.cmDraggableData(this.reactive.state, target.dataset.id);\n targetSectionId = dropData.sectionid;\n targetCmId = dropData.nextcmid;\n } else {\n const section = this.reactive.get('section', target.dataset.id);\n targetSectionId = target.dataset.id;\n targetCmId = section?.cmlist[0];\n }\n this.reactive.dispatch('cmMove', cmIds, targetSectionId, targetCmId);\n this._destroyModal(modal, editTools);\n });\n\n pendingModalReady.resolve();\n }\n\n /**\n * Handle a create section request.\n *\n * @param {Element} target the dispatch action element\n * @param {Event} event the triggered event\n */\n async _requestAddSection(target, event) {\n event.preventDefault();\n this.reactive.dispatch('addSection', target.dataset.id ?? 0);\n }\n\n /**\n * Handle a delete section request.\n *\n * @param {Element} target the dispatch action element\n * @param {Event} event the triggered event\n */\n async _requestDeleteSection(target, event) {\n const sectionIds = this._getTargetIds(target);\n if (sectionIds.length == 0) {\n return;\n }\n\n event.preventDefault();\n\n // We don't need confirmation to delete empty sections.\n let needsConfirmation = sectionIds.some(sectionId => {\n const sectionInfo = this.reactive.get('section', sectionId);\n const cmList = sectionInfo.cmlist ?? [];\n return (cmList.length || sectionInfo.hassummary || sectionInfo.rawtitle);\n });\n if (!needsConfirmation) {\n this.reactive.dispatch('sectionDelete', sectionIds);\n return;\n }\n\n let bodyText = null;\n let titleText = null;\n if (sectionIds.length == 1) {\n titleText = this.reactive.getFormatString('sectiondelete_title');\n const sectionInfo = this.reactive.get('section', sectionIds[0]);\n bodyText = this.reactive.getFormatString('sectiondelete_info', {name: sectionInfo.title});\n } else {\n titleText = this.reactive.getFormatString('sectionsdelete_title');\n bodyText = this.reactive.getFormatString('sectionsdelete_info', {count: sectionIds.length});\n }\n\n const modal = await this._modalBodyRenderedPromise(ModalDeleteCancel, {\n title: titleText,\n body: bodyText,\n });\n\n modal.getRoot().on(\n ModalEvents.delete,\n e => {\n // Stop the default save button behaviour which is to close the modal.\n e.preventDefault();\n modal.destroy();\n this.reactive.dispatch('sectionDelete', sectionIds);\n }\n );\n }\n\n /**\n * Handle a toggle cm selection.\n *\n * @param {Element} target the dispatch action element\n * @param {Event} event the triggered event\n */\n async _requestToggleSelectionCm(target, event) {\n toggleBulkSelectionAction(this.reactive, target, event, 'cm');\n }\n\n /**\n * Handle a toggle section selection.\n *\n * @param {Element} target the dispatch action element\n * @param {Event} event the triggered event\n */\n async _requestToggleSelectionSection(target, event) {\n toggleBulkSelectionAction(this.reactive, target, event, 'section');\n }\n\n /**\n * Basic mutation action helper.\n *\n * @param {Element} target the dispatch action element\n * @param {Event} event the triggered event\n * @param {string} mutationName the mutation name\n */\n async _requestMutationAction(target, event, mutationName) {\n if (!target.dataset.id) {\n return;\n }\n event.preventDefault();\n this.reactive.dispatch(mutationName, [target.dataset.id]);\n }\n\n /**\n * Handle a course module duplicate request.\n *\n * @param {Element} target the dispatch action element\n * @param {Event} event the triggered event\n */\n async _requestCmDuplicate(target, event) {\n const cmIds = this._getTargetIds(target);\n if (cmIds.length == 0) {\n return;\n }\n const sectionId = target.dataset.sectionid ?? null;\n event.preventDefault();\n this.reactive.dispatch('cmDuplicate', cmIds, sectionId);\n }\n\n /**\n * Handle a delete cm request.\n *\n * @param {Element} target the dispatch action element\n * @param {Event} event the triggered event\n */\n async _requestCmDelete(target, event) {\n const cmIds = this._getTargetIds(target);\n if (cmIds.length == 0) {\n return;\n }\n\n event.preventDefault();\n\n let bodyText = null;\n let titleText = null;\n if (cmIds.length == 1) {\n const cmInfo = this.reactive.get('cm', cmIds[0]);\n titleText = getString('cmdelete_title', 'core_courseformat');\n bodyText = getString(\n 'cmdelete_info',\n 'core_courseformat',\n {\n type: cmInfo.modname,\n name: cmInfo.name,\n }\n );\n } else {\n titleText = getString('cmsdelete_title', 'core_courseformat');\n bodyText = getString(\n 'cmsdelete_info',\n 'core_courseformat',\n {count: cmIds.length}\n );\n }\n\n const modal = await this._modalBodyRenderedPromise(ModalDeleteCancel, {\n title: titleText,\n body: bodyText,\n });\n\n modal.getRoot().on(\n ModalEvents.delete,\n e => {\n // Stop the default save button behaviour which is to close the modal.\n e.preventDefault();\n modal.destroy();\n this.reactive.dispatch('cmDelete', cmIds);\n }\n );\n }\n\n /**\n * Handle a cm availability change request.\n *\n * @param {Element} target the dispatch action element\n */\n async _requestCmAvailability(target) {\n const cmIds = this._getTargetIds(target);\n if (cmIds.length == 0) {\n return;\n }\n // Show the availability modal to decide which action to trigger.\n const exporter = this.reactive.getExporter();\n const data = {\n allowstealth: exporter.canUseStealth(this.reactive.state, cmIds),\n };\n const modal = await this._modalBodyRenderedPromise(ModalSaveCancel, {\n title: getString('availability', 'core'),\n body: Templates.render('core_courseformat/local/content/cm/availabilitymodal', data),\n saveButtonText: getString('apply', 'core'),\n });\n\n this._setupMutationRadioButtonModal(modal, cmIds);\n }\n\n /**\n * Handle a section availability change request.\n *\n * @param {Element} target the dispatch action element\n */\n async _requestSectionAvailability(target) {\n const sectionIds = this._getTargetIds(target);\n if (sectionIds.length == 0) {\n return;\n }\n const title = (sectionIds.length == 1) ? 'sectionavailability_title' : 'sectionsavailability_title';\n // Show the availability modal to decide which action to trigger.\n const modal = await this._modalBodyRenderedPromise(ModalSaveCancel, {\n title: this.reactive.getFormatString(title),\n body: Templates.render('core_courseformat/local/content/section/availabilitymodal', []),\n saveButtonText: getString('apply', 'core'),\n });\n\n this._setupMutationRadioButtonModal(modal, sectionIds);\n }\n\n /**\n * Add events to a mutation selector radio buttons modal.\n * @param {Modal} modal\n * @param {Number[]} ids the section or cm ids to apply the mutation\n */\n _setupMutationRadioButtonModal(modal, ids) {\n // The save button is not enabled until the user selects an option.\n modal.setButtonDisabled('save', true);\n\n const submitFunction = (radio) => {\n const mutation = radio?.value;\n if (!mutation) {\n return false;\n }\n this.reactive.dispatch(mutation, ids);\n return true;\n };\n\n const modalBody = getFirst(modal.getBody());\n const radioOptions = modalBody.querySelectorAll(this.selectors.OPTIONSRADIO);\n radioOptions.forEach(radio => {\n radio.addEventListener('change', () => {\n modal.setButtonDisabled('save', false);\n });\n radio.parentNode.addEventListener('click', () => {\n radio.checked = true;\n modal.setButtonDisabled('save', false);\n });\n radio.parentNode.addEventListener('dblclick', dbClickEvent => {\n if (submitFunction(radio)) {\n dbClickEvent.preventDefault();\n modal.destroy();\n }\n });\n });\n\n modal.getRoot().on(\n ModalEvents.save,\n () => {\n const radio = modalBody.querySelector(`${this.selectors.OPTIONSRADIO}:checked`);\n submitFunction(radio);\n }\n );\n }\n\n /**\n * Disable all add sections actions.\n *\n * @param {boolean} locked the new locked value.\n */\n _setAddSectionLocked(locked) {\n const targets = this.getElements(this.selectors.ADDSECTION);\n targets.forEach(element => {\n element.classList.toggle(this.classes.DISABLED, locked);\n element.classList.toggle(this.classes.ITALIC, locked);\n this.setElementLocked(element, locked);\n });\n }\n\n /**\n * Replace an element with a copy with a different tag name.\n *\n * @param {Element} element the original element\n */\n _disableLink(element) {\n if (element) {\n element.style.pointerEvents = 'none';\n element.style.userSelect = 'none';\n element.classList.add(this.classes.DISABLED);\n element.classList.add(this.classes.ITALIC);\n element.setAttribute('aria-disabled', true);\n element.addEventListener('click', event => event.preventDefault());\n }\n }\n\n /**\n * Render a modal and return a body ready promise.\n *\n * @param {Modal} ModalClass the modal class\n * @param {object} modalParams the modal params\n * @return {Promise} the modal body ready promise\n */\n _modalBodyRenderedPromise(ModalClass, modalParams) {\n return new Promise((resolve, reject) => {\n ModalClass.create(modalParams).then((modal) => {\n modal.setRemoveOnClose(true);\n // Handle body loading event.\n modal.getRoot().on(ModalEvents.bodyRendered, () => {\n resolve(modal);\n });\n // Configure some extra modal params.\n if (modalParams.saveButtonText !== undefined) {\n modal.setSaveButtonText(modalParams.saveButtonText);\n }\n if (modalParams.deleteButtonText !== undefined) {\n modal.setDeleteButtonText(modalParams.saveButtonText);\n }\n modal.show();\n return;\n }).catch(() => {\n reject(`Cannot load modal content`);\n });\n });\n }\n\n /**\n * Hide and later destroy a modal.\n *\n * Behat will fail if we remove the modal while some boostrap collapse is executing.\n *\n * @param {Modal} modal\n * @param {HTMLElement} element the dom element to focus on.\n */\n _destroyModal(modal, element) {\n modal.hide();\n const pendingDestroy = new Pending(`courseformat/actions:destroyModal`);\n if (element) {\n element.focus();\n }\n setTimeout(() =>{\n modal.destroy();\n pendingDestroy.resolve();\n }, 500);\n }\n\n /**\n * Get the closest actions menu toggler to an action element.\n *\n * @param {HTMLElement} element the action link element\n * @returns {HTMLElement|undefined}\n */\n _getClosestActionMenuToogler(element) {\n const actionMenu = element.closest(this.selectors.ACTIONMENU);\n if (!actionMenu) {\n return undefined;\n }\n return actionMenu.querySelector(this.selectors.ACTIONMENUTOGGLER);\n }\n}\n"],"names":["directMutations","sectionHide","sectionShow","cmHide","cmShow","cmStealth","cmMoveRight","cmMoveLeft","cmNoGroups","cmSeparateGroups","cmVisibleGroups","BaseComponent","create","name","selectors","ACTIONLINK","SECTIONLINK","CMLINK","SECTIONNODE","MODALTOGGLER","ADDSECTION","CONTENTTREE","ACTIONMENU","ACTIONMENUTOGGLER","OPTIONSRADIO","classes","DISABLED","ITALIC","actions","action","mutationReference","Object","entries","Error","stateReady","state","addEventListener","this","element","_dispatchClick","_checkSectionlist","CourseEvents","sectionRefreshed","getWatchers","watch","handler","event","target","closest","classList","contains","preventDefault","actionName","dataset","methodName","_actionMethodName","undefined","_requestMutationAction","requestName","charAt","toUpperCase","slice","_setAddSectionLocked","course","sectionlist","length","maxsections","_getTargetIds","ids","_target$dataset","id","push","bulkType","_target$dataset2","bulk","reactive","get","enabled","selectedType","selection","sectionIds","pendingModalReady","Pending","editTools","_getClosestActionMenuToogler","data","getExporter","titleText","sectionInfo","sectionid","sectiontitle","title","information","getFormatString","modal","_modalBodyRenderedPromise","Modal","body","Templates","render","modalBody","getBody","forEach","sectionId","currentElement","querySelector","_disableLink","ContentTree","SECTION","TOGGLER","COLLAPSE","matches","for","getAttribute","dispatch","_destroyModal","resolve","cmIds","exporter","cmInfo","cmid","cmname","cmId","ENTER","sectionnode","toggler","find","collapsibleId","attr","replace","expandNode","collapse","targetSectionId","targetCmId","dropData","cmDraggableData","nextcmid","section","cmlist","some","hassummary","rawtitle","bodyText","count","ModalDeleteCancel","getRoot","on","ModalEvents","delete","e","destroy","mutationName","type","modname","allowstealth","canUseStealth","ModalSaveCancel","saveButtonText","_setupMutationRadioButtonModal","setButtonDisabled","submitFunction","radio","mutation","value","querySelectorAll","parentNode","checked","dbClickEvent","save","locked","getElements","toggle","setElementLocked","style","pointerEvents","userSelect","add","setAttribute","ModalClass","modalParams","Promise","reject","then","setRemoveOnClose","bodyRendered","setSaveButtonText","deleteButtonText","setDeleteButtonText","show","catch","hide","pendingDestroy","focus","setTimeout","actionMenu"],"mappings":"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"} \ No newline at end of file diff --git a/course/format/amd/build/local/courseeditor/fileuploader.min.js b/course/format/amd/build/local/courseeditor/fileuploader.min.js index d21051f0bf5..cbf6ba3d164 100644 --- a/course/format/amd/build/local/courseeditor/fileuploader.min.js +++ b/course/format/amd/build/local/courseeditor/fileuploader.min.js @@ -1,3 +1,3 @@ -define("core_courseformat/local/courseeditor/fileuploader",["exports","core/config","core/modal_factory","core/modal_events","core/templates","core/normalise","core/prefetch","core/str","core_courseformat/courseeditor","core/process_monitor","core/utils"],(function(_exports,_config,_modal_factory,_modal_events,_templates,_normalise,_prefetch,_str,_courseeditor,_process_monitor,_utils){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _defineProperty(obj,key,value){return key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.uploadFilesToCourse=void 0,_config=_interopRequireDefault(_config),_modal_factory=_interopRequireDefault(_modal_factory),_modal_events=_interopRequireDefault(_modal_events),_templates=_interopRequireDefault(_templates);const UPLOADURL=_config.default.wwwroot+"/course/dndupload.php";let uploadQueue=null,handlerManagers={},courseUpdates=new Map,errors=null;(0,_prefetch.prefetchStrings)("moodle",["addresourceoractivity","upload"]),(0,_prefetch.prefetchStrings)("core_error",["dndmaxbytes","dndread","dndupload","dndunkownfile"]);class FileUploader{constructor(courseId,sectionId,sectionNum,fileInfo,handler){this.courseId=courseId,this.sectionId=sectionId,this.sectionNum=sectionNum,this.fileInfo=fileInfo,this.handler=handler}execute(process){const fileInfo=this.fileInfo,xhr=this._createXhrRequest(process),formData=this._createUploadFormData(),reader=new FileReader;reader.onload=function(){xhr.open("POST",UPLOADURL,!0),xhr.send(formData)},reader.onerror=function(){process.setError(errors.dndread)},fileInfo.size>0?reader.readAsText(fileInfo.slice(0,5)):reader.readAsText(fileInfo)}getExecutionFunction(){return this.execute.bind(this)}_createXhrRequest(process){const xhr=new XMLHttpRequest;return xhr.upload.addEventListener("progress",(event=>{if(event.lengthComputable){const percent=Math.round(100*event.loaded/event.total);process.setPercentage(percent)}}),!1),xhr.onreadystatechange=()=>{if(1==xhr.readyState&&process.setPercentage(1),4==xhr.readyState)if(200==xhr.status){var result=JSON.parse(xhr.responseText);result&&0==result.error?this._finishProcess(process):process.setError(result.error)}else process.setError(errors.dndupload)},xhr}_createUploadFormData(){const formData=new FormData;try{formData.append("repo_upload_file",this.fileInfo)}catch(error){throw Error(error.dndread)}return formData.append("sesskey",_config.default.sesskey),formData.append("course",this.courseId),formData.append("section",this.sectionNum),formData.append("module",this.handler.module),formData.append("type","Files"),formData}_finishProcess(process){!function(courseId,sectionId){let refresh=courseUpdates.get(courseId);refresh||(refresh=new Set);refresh.add(sectionId),courseUpdates.set(courseId,refresh),refreshCourseEditors()}(this.courseId,this.sectionId),process.setPercentage(100),process.finish()}}class HandlerManager{constructor(courseId){var _this$courseEditor$ge,_this$courseEditor$ge2;if(_defineProperty(this,"lastHandlers",{}),_defineProperty(this,"allHandlers",null),this.courseId=courseId,this.lastUploadId=0,this.courseEditor=(0,_courseeditor.getCourseEditor)(courseId),!this.courseEditor)throw Error("Unkown course editor");this.maxbytes=null!==(_this$courseEditor$ge=null===(_this$courseEditor$ge2=this.courseEditor.get("course"))||void 0===_this$courseEditor$ge2?void 0:_this$courseEditor$ge2.maxbytes)&&void 0!==_this$courseEditor$ge?_this$courseEditor$ge:0}async loadHandlers(){this.allHandlers=await this.courseEditor.getFileHandlersPromise()}getFileExtension(fileInfo){let extension="";const dotpos=fileInfo.name.lastIndexOf(".");return-1!=dotpos&&(extension=fileInfo.name.substring(dotpos+1,fileInfo.name.length).toLowerCase()),extension}validateFile(fileInfo){if(-1!==this.maxbytes&&fileInfo.size>this.maxbytes)throw Error(errors.dndmaxbytes)}filterHandlers(fileInfo){const extension=this.getFileExtension(fileInfo);return this.allHandlers.filter((handler=>"*"==handler.extension||handler.extension==extension))}async getFileHandler(fileInfo){const fileHandlers=this.filterHandlers(fileInfo);if(0==fileHandlers.length)throw Error(errors.dndunkownfile);let fileHandler=null;return fileHandler=1==fileHandlers.length?fileHandlers[0]:await this.askHandlerToUser(fileHandlers,fileInfo),fileHandler}async askHandlerToUser(fileHandlers,fileInfo){var _this$lastHandlers$ex;const extension=this.getFileExtension(fileInfo),modalParams={title:(0,_str.getString)("addresourceoractivity","moodle"),body:_templates.default.render("core_courseformat/fileuploader",this.getModalData(fileHandlers,fileInfo,null!==(_this$lastHandlers$ex=this.lastHandlers[extension])&&void 0!==_this$lastHandlers$ex?_this$lastHandlers$ex:null)),type:_modal_factory.default.types.SAVE_CANCEL,saveButtonText:(0,_str.getString)("upload","moodle")},modal=await this.modalBodyRenderedPromise(modalParams),selectedHandler=await this.modalUserAnswerPromise(modal,fileHandlers);return null===selectedHandler?null:(this.lastHandlers[extension]=selectedHandler.module,selectedHandler)}getModalData(fileHandlers,fileInfo,defaultModule){const data={filename:fileInfo.name,uploadid:++this.lastUploadId,handlers:[]};let hasDefault=!1;if(fileHandlers.forEach(((handler,index)=>{const isDefault=defaultModule==handler.module;data.handlers.push({...handler,selected:isDefault,labelid:"fileuploader_".concat(data.uploadid),value:index}),hasDefault=hasDefault||isDefault})),!hasDefault&&data.handlers.length>0){const lastHandler=data.handlers.pop();lastHandler.selected=!0,data.handlers.push(lastHandler)}return data}modalUserAnswerPromise(modal,fileHandlers){const modalBody=(0,_normalise.getFirst)(modal.getBody());return new Promise(((resolve,reject)=>{modal.getRoot().on(_modal_events.default.save,(event=>{const index=modalBody.querySelector("input:checked").value;event.preventDefault(),modal.destroy(),fileHandlers[index]||reject("Invalid handler selected"),resolve(fileHandlers[index])})),modal.getRoot().on(_modal_events.default.cancel,(()=>{resolve(null)}))}))}modalBodyRenderedPromise(modalParams){return new Promise(((resolve,reject)=>{_modal_factory.default.create(modalParams).then((modal=>{modal.setRemoveOnClose(!0),modal.getRoot().on(_modal_events.default.bodyRendered,(()=>{resolve(modal)})),void 0!==modalParams.saveButtonText&&modal.setSaveButtonText(modalParams.saveButtonText),modal.show()})).catch((()=>{reject("Cannot load modal content")}))}))}}const refreshCourseEditors=(0,_utils.debounce)((()=>{const refreshes=courseUpdates;courseUpdates=new Map,refreshes.forEach(((sectionIds,courseId)=>{const courseEditor=(0,_courseeditor.getCourseEditor)(courseId);courseEditor&&courseEditor.dispatch("sectionState",[...sectionIds])}))}),500);const queueFileUpload=async function(courseId,sectionId,sectionNum,fileInfo,handlerManager){let handler;uploadQueue=await _process_monitor.processMonitor.createProcessQueue();try{handlerManager.validateFile(fileInfo),handler=await handlerManager.getFileHandler(fileInfo)}catch(error){return void uploadQueue.addError(fileInfo.name,error.message)}if(!handler)return;const fileProcessor=new FileUploader(courseId,sectionId,sectionNum,fileInfo,handler);uploadQueue.addPending(fileInfo.name,fileProcessor.getExecutionFunction())};_exports.uploadFilesToCourse=async function(courseId,sectionId,sectionNum,files){const handlerManager=await async function(courseId){if(void 0!==handlerManagers[courseId])return handlerManagers[courseId];const handlerManager=new HandlerManager(courseId);return await handlerManager.loadHandlers(),handlerManagers[courseId]=handlerManager,handlerManagers[courseId]}(courseId);await async function(courseId){var _courseEditor$get$max,_courseEditor$get;if(null!==errors)return;const maxbytestext=null!==(_courseEditor$get$max=null===(_courseEditor$get=(0,_courseeditor.getCourseEditor)(courseId).get("course"))||void 0===_courseEditor$get?void 0:_courseEditor$get.maxbytestext)&&void 0!==_courseEditor$get$max?_courseEditor$get$max:"0";errors={};const allStrings=[{key:"dndmaxbytes",component:"core_error",param:{size:maxbytestext}},{key:"dndread",component:"core_error"},{key:"dndupload",component:"core_error"},{key:"dndunkownfile",component:"core_error"}];window.console.log(allStrings);const loadedStrings=await(0,_str.getStrings)(allStrings);allStrings.forEach(((_ref,index)=>{let{key:key}=_ref;errors[key]=loadedStrings[index]}))}(courseId);for(let index=0;index0?reader.readAsText(fileInfo.slice(0,5)):reader.readAsText(fileInfo)}getExecutionFunction(){return this.execute.bind(this)}_createXhrRequest(process){const xhr=new XMLHttpRequest;return xhr.upload.addEventListener("progress",(event=>{if(event.lengthComputable){const percent=Math.round(100*event.loaded/event.total);process.setPercentage(percent)}}),!1),xhr.onreadystatechange=()=>{if(1==xhr.readyState&&process.setPercentage(1),4==xhr.readyState)if(200==xhr.status){var result=JSON.parse(xhr.responseText);result&&0==result.error?this._finishProcess(process):process.setError(result.error)}else process.setError(errors.dndupload)},xhr}_createUploadFormData(){const formData=new FormData;try{formData.append("repo_upload_file",this.fileInfo)}catch(error){throw Error(error.dndread)}return formData.append("sesskey",_config.default.sesskey),formData.append("course",this.courseId),formData.append("section",this.sectionNum),formData.append("module",this.handler.module),formData.append("type","Files"),formData}_finishProcess(process){!function(courseId,sectionId){let refresh=courseUpdates.get(courseId);refresh||(refresh=new Set);refresh.add(sectionId),courseUpdates.set(courseId,refresh),refreshCourseEditors()}(this.courseId,this.sectionId),process.setPercentage(100),process.finish()}}class HandlerManager{constructor(courseId){var _this$courseEditor$ge,_this$courseEditor$ge2;if(_defineProperty(this,"lastHandlers",{}),_defineProperty(this,"allHandlers",null),this.courseId=courseId,this.lastUploadId=0,this.courseEditor=(0,_courseeditor.getCourseEditor)(courseId),!this.courseEditor)throw Error("Unkown course editor");this.maxbytes=null!==(_this$courseEditor$ge=null===(_this$courseEditor$ge2=this.courseEditor.get("course"))||void 0===_this$courseEditor$ge2?void 0:_this$courseEditor$ge2.maxbytes)&&void 0!==_this$courseEditor$ge?_this$courseEditor$ge:0}async loadHandlers(){this.allHandlers=await this.courseEditor.getFileHandlersPromise()}getFileExtension(fileInfo){let extension="";const dotpos=fileInfo.name.lastIndexOf(".");return-1!=dotpos&&(extension=fileInfo.name.substring(dotpos+1,fileInfo.name.length).toLowerCase()),extension}validateFile(fileInfo){if(-1!==this.maxbytes&&fileInfo.size>this.maxbytes)throw Error(errors.dndmaxbytes)}filterHandlers(fileInfo){const extension=this.getFileExtension(fileInfo);return this.allHandlers.filter((handler=>"*"==handler.extension||handler.extension==extension))}async getFileHandler(fileInfo){const fileHandlers=this.filterHandlers(fileInfo);if(0==fileHandlers.length)throw Error(errors.dndunkownfile);let fileHandler=null;return fileHandler=1==fileHandlers.length?fileHandlers[0]:await this.askHandlerToUser(fileHandlers,fileInfo),fileHandler}async askHandlerToUser(fileHandlers,fileInfo){var _this$lastHandlers$ex;const extension=this.getFileExtension(fileInfo),modalParams={title:(0,_str.getString)("addresourceoractivity","moodle"),body:_templates.default.render("core_courseformat/fileuploader",this.getModalData(fileHandlers,fileInfo,null!==(_this$lastHandlers$ex=this.lastHandlers[extension])&&void 0!==_this$lastHandlers$ex?_this$lastHandlers$ex:null)),saveButtonText:(0,_str.getString)("upload","moodle")},modal=await this.modalBodyRenderedPromise(modalParams),selectedHandler=await this.modalUserAnswerPromise(modal,fileHandlers);return null===selectedHandler?null:(this.lastHandlers[extension]=selectedHandler.module,selectedHandler)}getModalData(fileHandlers,fileInfo,defaultModule){const data={filename:fileInfo.name,uploadid:++this.lastUploadId,handlers:[]};let hasDefault=!1;if(fileHandlers.forEach(((handler,index)=>{const isDefault=defaultModule==handler.module;data.handlers.push({...handler,selected:isDefault,labelid:"fileuploader_".concat(data.uploadid),value:index}),hasDefault=hasDefault||isDefault})),!hasDefault&&data.handlers.length>0){const lastHandler=data.handlers.pop();lastHandler.selected=!0,data.handlers.push(lastHandler)}return data}modalUserAnswerPromise(modal,fileHandlers){const modalBody=(0,_normalise.getFirst)(modal.getBody());return new Promise(((resolve,reject)=>{modal.getRoot().on(_modal_events.default.save,(event=>{const index=modalBody.querySelector("input:checked").value;event.preventDefault(),modal.destroy(),fileHandlers[index]||reject("Invalid handler selected"),resolve(fileHandlers[index])})),modal.getRoot().on(_modal_events.default.cancel,(()=>{resolve(null)}))}))}modalBodyRenderedPromise(modalParams){return new Promise(((resolve,reject)=>{_modal_save_cancel.default.create(modalParams).then((modal=>{modal.setRemoveOnClose(!0),modal.getRoot().on(_modal_events.default.bodyRendered,(()=>{resolve(modal)})),void 0!==modalParams.saveButtonText&&modal.setSaveButtonText(modalParams.saveButtonText),modal.show()})).catch((()=>{reject("Cannot load modal content")}))}))}}const refreshCourseEditors=(0,_utils.debounce)((()=>{const refreshes=courseUpdates;courseUpdates=new Map,refreshes.forEach(((sectionIds,courseId)=>{const courseEditor=(0,_courseeditor.getCourseEditor)(courseId);courseEditor&&courseEditor.dispatch("sectionState",[...sectionIds])}))}),500);const queueFileUpload=async function(courseId,sectionId,sectionNum,fileInfo,handlerManager){let handler;uploadQueue=await _process_monitor.processMonitor.createProcessQueue();try{handlerManager.validateFile(fileInfo),handler=await handlerManager.getFileHandler(fileInfo)}catch(error){return void uploadQueue.addError(fileInfo.name,error.message)}if(!handler)return;const fileProcessor=new FileUploader(courseId,sectionId,sectionNum,fileInfo,handler);uploadQueue.addPending(fileInfo.name,fileProcessor.getExecutionFunction())};_exports.uploadFilesToCourse=async function(courseId,sectionId,sectionNum,files){const handlerManager=await async function(courseId){if(void 0!==handlerManagers[courseId])return handlerManagers[courseId];const handlerManager=new HandlerManager(courseId);return await handlerManager.loadHandlers(),handlerManagers[courseId]=handlerManager,handlerManagers[courseId]}(courseId);await async function(courseId){var _courseEditor$get$max,_courseEditor$get;if(null!==errors)return;const maxbytestext=null!==(_courseEditor$get$max=null===(_courseEditor$get=(0,_courseeditor.getCourseEditor)(courseId).get("course"))||void 0===_courseEditor$get?void 0:_courseEditor$get.maxbytestext)&&void 0!==_courseEditor$get$max?_courseEditor$get$max:"0";errors={};const allStrings=[{key:"dndmaxbytes",component:"core_error",param:{size:maxbytestext}},{key:"dndread",component:"core_error"},{key:"dndupload",component:"core_error"},{key:"dndunkownfile",component:"core_error"}];window.console.log(allStrings);const loadedStrings=await(0,_str.getStrings)(allStrings);allStrings.forEach(((_ref,index)=>{let{key:key}=_ref;errors[key]=loadedStrings[index]}))}(courseId);for(let index=0;index.\n\n/**\n * The course file uploader.\n *\n * This module is used to upload files directly into the course.\n *\n * @module core_courseformat/local/courseeditor/fileuploader\n * @copyright 2022 Ferran Recio \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n/**\n * @typedef {Object} Handler\n * @property {String} extension the handled extension or * for any\n * @property {String} message the handler message\n * @property {String} module the module name\n */\n\nimport Config from 'core/config';\nimport ModalFactory from 'core/modal_factory';\nimport ModalEvents from 'core/modal_events';\nimport Templates from 'core/templates';\nimport {getFirst} from 'core/normalise';\nimport {prefetchStrings} from 'core/prefetch';\nimport {getString, getStrings} from 'core/str';\nimport {getCourseEditor} from 'core_courseformat/courseeditor';\nimport {processMonitor} from 'core/process_monitor';\nimport {debounce} from 'core/utils';\n\n// Uploading url.\nconst UPLOADURL = Config.wwwroot + '/course/dndupload.php';\nconst DEBOUNCETIMER = 500;\nconst USERCANIGNOREFILESIZELIMITS = -1;\n\n/** @var {ProcessQueue} uploadQueue the internal uploadQueue instance. */\nlet uploadQueue = null;\n/** @var {Object} handlerManagers the courseId indexed loaded handler managers. */\nlet handlerManagers = {};\n/** @var {Map} courseUpdates the pending course sections updates. */\nlet courseUpdates = new Map();\n/** @var {Object} errors the error messages. */\nlet errors = null;\n\n// Load global strings.\nprefetchStrings('moodle', ['addresourceoractivity', 'upload']);\nprefetchStrings('core_error', ['dndmaxbytes', 'dndread', 'dndupload', 'dndunkownfile']);\n\n/**\n * Class to upload a file into the course.\n * @private\n */\nclass FileUploader {\n /**\n * Class constructor.\n *\n * @param {number} courseId the course id\n * @param {number} sectionId the section id\n * @param {number} sectionNum the section number\n * @param {File} fileInfo the file information object\n * @param {Handler} handler the file selected file handler\n */\n constructor(courseId, sectionId, sectionNum, fileInfo, handler) {\n this.courseId = courseId;\n this.sectionId = sectionId;\n this.sectionNum = sectionNum;\n this.fileInfo = fileInfo;\n this.handler = handler;\n }\n\n /**\n * Execute the file upload and update the state in the given process.\n *\n * @param {LoadingProcess} process the process to store the upload result\n */\n execute(process) {\n const fileInfo = this.fileInfo;\n const xhr = this._createXhrRequest(process);\n const formData = this._createUploadFormData();\n\n // Try reading the file to check it is not a folder, before sending it to the server.\n const reader = new FileReader();\n reader.onload = function() {\n // File was read OK - send it to the server.\n xhr.open(\"POST\", UPLOADURL, true);\n xhr.send(formData);\n };\n reader.onerror = function() {\n // Unable to read the file (it is probably a folder) - display an error message.\n process.setError(errors.dndread);\n };\n if (fileInfo.size > 0) {\n // If this is a non-empty file, try reading the first few bytes.\n // This will trigger reader.onerror() for folders and reader.onload() for ordinary, readable files.\n reader.readAsText(fileInfo.slice(0, 5));\n } else {\n // If you call slice() on a 0-byte folder, before calling readAsText, then Firefox triggers reader.onload(),\n // instead of reader.onerror().\n // So, for 0-byte files, just call readAsText on the whole file (and it will trigger load/error functions as expected).\n reader.readAsText(fileInfo);\n }\n }\n\n /**\n * Returns the bind version of execute function.\n *\n * This method is used to queue the process into a ProcessQueue instance.\n *\n * @returns {Function} the bind function to execute the process\n */\n getExecutionFunction() {\n return this.execute.bind(this);\n }\n\n /**\n * Generate a upload XHR file request.\n *\n * @param {LoadingProcess} process the current process\n * @return {XMLHttpRequest} the XHR request\n */\n _createXhrRequest(process) {\n const xhr = new XMLHttpRequest();\n // Update the progress bar as the file is uploaded.\n xhr.upload.addEventListener(\n 'progress',\n (event) => {\n if (event.lengthComputable) {\n const percent = Math.round((event.loaded * 100) / event.total);\n process.setPercentage(percent);\n }\n },\n false\n );\n // Wait for the AJAX call to complete.\n xhr.onreadystatechange = () => {\n if (xhr.readyState == 1) {\n // Add a 1% just to indicate that it is uploading.\n process.setPercentage(1);\n }\n // State 4 is DONE. Otherwise the connection is still ongoing.\n if (xhr.readyState != 4) {\n return;\n }\n if (xhr.status == 200) {\n var result = JSON.parse(xhr.responseText);\n if (result && result.error == 0) {\n // All OK.\n this._finishProcess(process);\n } else {\n process.setError(result.error);\n }\n } else {\n process.setError(errors.dndupload);\n }\n };\n return xhr;\n }\n\n /**\n * Upload a file into the course.\n *\n * @return {FormData|null} the new form data object\n */\n _createUploadFormData() {\n const formData = new FormData();\n try {\n formData.append('repo_upload_file', this.fileInfo);\n } catch (error) {\n throw Error(error.dndread);\n }\n formData.append('sesskey', Config.sesskey);\n formData.append('course', this.courseId);\n formData.append('section', this.sectionNum);\n formData.append('module', this.handler.module);\n formData.append('type', 'Files');\n return formData;\n }\n\n /**\n * Finishes the current process.\n * @param {LoadingProcess} process the process\n */\n _finishProcess(process) {\n addRefreshSection(this.courseId, this.sectionId);\n process.setPercentage(100);\n process.finish();\n }\n}\n\n/**\n * The file handler manager class.\n *\n * @private\n */\nclass HandlerManager {\n\n /** @var {Object} lastHandlers the last handlers selected per each file extension. */\n lastHandlers = {};\n\n /** @var {Handler[]|null} allHandlers all the available handlers. */\n allHandlers = null;\n\n /**\n * Class constructor.\n *\n * @param {Number} courseId\n */\n constructor(courseId) {\n this.courseId = courseId;\n this.lastUploadId = 0;\n this.courseEditor = getCourseEditor(courseId);\n if (!this.courseEditor) {\n throw Error('Unkown course editor');\n }\n this.maxbytes = this.courseEditor.get('course')?.maxbytes ?? 0;\n }\n\n /**\n * Load the course file handlers.\n */\n async loadHandlers() {\n this.allHandlers = await this.courseEditor.getFileHandlersPromise();\n }\n\n /**\n * Extract the file extension from a fileInfo.\n *\n * @param {File} fileInfo\n * @returns {String} the file extension or an empty string.\n */\n getFileExtension(fileInfo) {\n let extension = '';\n const dotpos = fileInfo.name.lastIndexOf('.');\n if (dotpos != -1) {\n extension = fileInfo.name.substring(dotpos + 1, fileInfo.name.length).toLowerCase();\n }\n return extension;\n }\n\n /**\n * Check if the file is valid.\n *\n * @param {File} fileInfo the file info\n */\n validateFile(fileInfo) {\n if (this.maxbytes !== USERCANIGNOREFILESIZELIMITS && fileInfo.size > this.maxbytes) {\n throw Error(errors.dndmaxbytes);\n }\n }\n\n /**\n * Get the file handlers of an specific file.\n *\n * @param {File} fileInfo the file indo\n * @return {Array} Array of handlers\n */\n filterHandlers(fileInfo) {\n const extension = this.getFileExtension(fileInfo);\n return this.allHandlers.filter(handler => handler.extension == '*' || handler.extension == extension);\n }\n\n /**\n * Get the Handler to upload a specific file.\n *\n * It will ask the used if more than one handler is available.\n *\n * @param {File} fileInfo the file info\n * @returns {Promise} the selected handler or null if the user cancel\n */\n async getFileHandler(fileInfo) {\n const fileHandlers = this.filterHandlers(fileInfo);\n if (fileHandlers.length == 0) {\n throw Error(errors.dndunkownfile);\n }\n let fileHandler = null;\n if (fileHandlers.length == 1) {\n fileHandler = fileHandlers[0];\n } else {\n fileHandler = await this.askHandlerToUser(fileHandlers, fileInfo);\n }\n return fileHandler;\n }\n\n /**\n * Ask the user to select a specific handler.\n *\n * @param {Handler[]} fileHandlers\n * @param {File} fileInfo the file info\n * @return {Promise} the selected handler\n */\n async askHandlerToUser(fileHandlers, fileInfo) {\n const extension = this.getFileExtension(fileInfo);\n // Build the modal parameters from the event data.\n const modalParams = {\n title: getString('addresourceoractivity', 'moodle'),\n body: Templates.render(\n 'core_courseformat/fileuploader',\n this.getModalData(\n fileHandlers,\n fileInfo,\n this.lastHandlers[extension] ?? null\n )\n ),\n type: ModalFactory.types.SAVE_CANCEL,\n saveButtonText: getString('upload', 'moodle'),\n };\n // Create the modal.\n const modal = await this.modalBodyRenderedPromise(modalParams);\n const selectedHandler = await this.modalUserAnswerPromise(modal, fileHandlers);\n // Cancel action.\n if (selectedHandler === null) {\n return null;\n }\n // Save last selected handler.\n this.lastHandlers[extension] = selectedHandler.module;\n return selectedHandler;\n }\n\n /**\n * Generated the modal template data.\n *\n * @param {Handler[]} fileHandlers\n * @param {File} fileInfo the file info\n * @param {String|null} defaultModule the default module if any\n * @return {Object} the modal template data.\n */\n getModalData(fileHandlers, fileInfo, defaultModule) {\n const data = {\n filename: fileInfo.name,\n uploadid: ++this.lastUploadId,\n handlers: [],\n };\n let hasDefault = false;\n fileHandlers.forEach((handler, index) => {\n const isDefault = (defaultModule == handler.module);\n data.handlers.push({\n ...handler,\n selected: isDefault,\n labelid: `fileuploader_${data.uploadid}`,\n value: index,\n });\n hasDefault = hasDefault || isDefault;\n });\n if (!hasDefault && data.handlers.length > 0) {\n const lastHandler = data.handlers.pop();\n lastHandler.selected = true;\n data.handlers.push(lastHandler);\n }\n return data;\n }\n\n /**\n * Get the user handler choice.\n *\n * Wait for the user answer in the modal and resolve with the selected index.\n *\n * @param {Modal} modal the modal instance\n * @param {Handler[]} fileHandlers the availabvle file handlers\n * @return {Promise} with the option selected by the user.\n */\n modalUserAnswerPromise(modal, fileHandlers) {\n const modalBody = getFirst(modal.getBody());\n return new Promise((resolve, reject) => {\n modal.getRoot().on(\n ModalEvents.save,\n event => {\n // Get the selected option.\n const index = modalBody.querySelector('input:checked').value;\n event.preventDefault();\n modal.destroy();\n if (!fileHandlers[index]) {\n reject('Invalid handler selected');\n }\n resolve(fileHandlers[index]);\n\n }\n );\n modal.getRoot().on(\n ModalEvents.cancel,\n () => {\n resolve(null);\n }\n );\n });\n }\n\n /**\n * Create a new modal and return a Promise to the body rendered.\n *\n * @param {Object} modalParams the modal params\n * @returns {Promise} the modal body rendered promise\n */\n modalBodyRenderedPromise(modalParams) {\n return new Promise((resolve, reject) => {\n ModalFactory.create(modalParams).then((modal) => {\n modal.setRemoveOnClose(true);\n // Handle body loading event.\n modal.getRoot().on(ModalEvents.bodyRendered, () => {\n resolve(modal);\n });\n // Configure some extra modal params.\n if (modalParams.saveButtonText !== undefined) {\n modal.setSaveButtonText(modalParams.saveButtonText);\n }\n modal.show();\n return;\n }).catch(() => {\n reject(`Cannot load modal content`);\n });\n });\n }\n}\n\n/**\n * Add a section to refresh.\n *\n * @param {number} courseId the course id\n * @param {number} sectionId the seciton id\n */\nfunction addRefreshSection(courseId, sectionId) {\n let refresh = courseUpdates.get(courseId);\n if (!refresh) {\n refresh = new Set();\n }\n refresh.add(sectionId);\n courseUpdates.set(courseId, refresh);\n refreshCourseEditors();\n}\n\n/**\n * Debounced processing all pending course refreshes.\n * @private\n */\nconst refreshCourseEditors = debounce(\n () => {\n const refreshes = courseUpdates;\n courseUpdates = new Map();\n refreshes.forEach((sectionIds, courseId) => {\n const courseEditor = getCourseEditor(courseId);\n if (!courseEditor) {\n return;\n }\n courseEditor.dispatch('sectionState', [...sectionIds]);\n });\n },\n DEBOUNCETIMER\n);\n\n/**\n * Load and return the course handler manager instance.\n *\n * @param {Number} courseId the course Id to load\n * @returns {Promise} promise of the the loaded handleManager\n */\nasync function loadCourseHandlerManager(courseId) {\n if (handlerManagers[courseId] !== undefined) {\n return handlerManagers[courseId];\n }\n const handlerManager = new HandlerManager(courseId);\n await handlerManager.loadHandlers();\n handlerManagers[courseId] = handlerManager;\n return handlerManagers[courseId];\n}\n\n/**\n * Load all the erros messages at once in the module \"errors\" variable.\n * @param {Number} courseId the course id\n */\nasync function loadErrorStrings(courseId) {\n if (errors !== null) {\n return;\n }\n const courseEditor = getCourseEditor(courseId);\n const maxbytestext = courseEditor.get('course')?.maxbytestext ?? '0';\n\n errors = {};\n const allStrings = [\n {key: 'dndmaxbytes', component: 'core_error', param: {size: maxbytestext}},\n {key: 'dndread', component: 'core_error'},\n {key: 'dndupload', component: 'core_error'},\n {key: 'dndunkownfile', component: 'core_error'},\n ];\n window.console.log(allStrings);\n const loadedStrings = await getStrings(allStrings);\n allStrings.forEach(({key}, index) => {\n errors[key] = loadedStrings[index];\n });\n}\n\n/**\n * Start a batch file uploading into the course.\n *\n * @private\n * @param {number} courseId the course id.\n * @param {number} sectionId the section id.\n * @param {number} sectionNum the section number.\n * @param {File} fileInfo the file information object\n * @param {HandlerManager} handlerManager the course handler manager\n */\nconst queueFileUpload = async function(courseId, sectionId, sectionNum, fileInfo, handlerManager) {\n let handler;\n uploadQueue = await processMonitor.createProcessQueue();\n try {\n handlerManager.validateFile(fileInfo);\n handler = await handlerManager.getFileHandler(fileInfo);\n } catch (error) {\n uploadQueue.addError(fileInfo.name, error.message);\n return;\n }\n // If we don't have a handler means the user cancel the upload.\n if (!handler) {\n return;\n }\n const fileProcessor = new FileUploader(courseId, sectionId, sectionNum, fileInfo, handler);\n uploadQueue.addPending(fileInfo.name, fileProcessor.getExecutionFunction());\n};\n\n/**\n * Upload a file to the course.\n *\n * This method will show any necesary modal to handle the request.\n *\n * @param {number} courseId the course id\n * @param {number} sectionId the section id\n * @param {number} sectionNum the section number\n * @param {Array} files and array of files\n */\nexport const uploadFilesToCourse = async function(courseId, sectionId, sectionNum, files) {\n // Get the course handlers.\n const handlerManager = await loadCourseHandlerManager(courseId);\n await loadErrorStrings(courseId);\n for (let index = 0; index < files.length; index++) {\n const fileInfo = files[index];\n await queueFileUpload(courseId, sectionId, sectionNum, fileInfo, handlerManager);\n }\n};\n"],"names":["UPLOADURL","Config","wwwroot","uploadQueue","handlerManagers","courseUpdates","Map","errors","FileUploader","constructor","courseId","sectionId","sectionNum","fileInfo","handler","execute","process","this","xhr","_createXhrRequest","formData","_createUploadFormData","reader","FileReader","onload","open","send","onerror","setError","dndread","size","readAsText","slice","getExecutionFunction","bind","XMLHttpRequest","upload","addEventListener","event","lengthComputable","percent","Math","round","loaded","total","setPercentage","onreadystatechange","readyState","status","result","JSON","parse","responseText","error","_finishProcess","dndupload","FormData","append","Error","sesskey","module","refresh","get","Set","add","set","refreshCourseEditors","addRefreshSection","finish","HandlerManager","lastUploadId","courseEditor","maxbytes","_this$courseEditor$ge2","allHandlers","getFileHandlersPromise","getFileExtension","extension","dotpos","name","lastIndexOf","substring","length","toLowerCase","validateFile","dndmaxbytes","filterHandlers","filter","fileHandlers","dndunkownfile","fileHandler","askHandlerToUser","modalParams","title","body","Templates","render","getModalData","lastHandlers","type","ModalFactory","types","SAVE_CANCEL","saveButtonText","modal","modalBodyRenderedPromise","selectedHandler","modalUserAnswerPromise","defaultModule","data","filename","uploadid","handlers","hasDefault","forEach","index","isDefault","push","selected","labelid","value","lastHandler","pop","modalBody","getBody","Promise","resolve","reject","getRoot","on","ModalEvents","save","querySelector","preventDefault","destroy","cancel","create","then","setRemoveOnClose","bodyRendered","undefined","setSaveButtonText","show","catch","refreshes","sectionIds","dispatch","queueFileUpload","async","handlerManager","processMonitor","createProcessQueue","getFileHandler","addError","message","fileProcessor","addPending","files","loadHandlers","loadCourseHandlerManager","maxbytestext","_courseEditor$get","allStrings","key","component","param","window","console","log","loadedStrings","loadErrorStrings"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"fileuploader.min.js","sources":["../../../src/local/courseeditor/fileuploader.js"],"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 * The course file uploader.\n *\n * This module is used to upload files directly into the course.\n *\n * @module core_courseformat/local/courseeditor/fileuploader\n * @copyright 2022 Ferran Recio \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n/**\n * @typedef {Object} Handler\n * @property {String} extension the handled extension or * for any\n * @property {String} message the handler message\n * @property {String} module the module name\n */\n\nimport Config from 'core/config';\nimport ModalSaveCancel from 'core/modal_save_cancel';\nimport ModalEvents from 'core/modal_events';\nimport Templates from 'core/templates';\nimport {getFirst} from 'core/normalise';\nimport {prefetchStrings} from 'core/prefetch';\nimport {getString, getStrings} from 'core/str';\nimport {getCourseEditor} from 'core_courseformat/courseeditor';\nimport {processMonitor} from 'core/process_monitor';\nimport {debounce} from 'core/utils';\n\n// Uploading url.\nconst UPLOADURL = Config.wwwroot + '/course/dndupload.php';\nconst DEBOUNCETIMER = 500;\nconst USERCANIGNOREFILESIZELIMITS = -1;\n\n/** @var {ProcessQueue} uploadQueue the internal uploadQueue instance. */\nlet uploadQueue = null;\n/** @var {Object} handlerManagers the courseId indexed loaded handler managers. */\nlet handlerManagers = {};\n/** @var {Map} courseUpdates the pending course sections updates. */\nlet courseUpdates = new Map();\n/** @var {Object} errors the error messages. */\nlet errors = null;\n\n// Load global strings.\nprefetchStrings('moodle', ['addresourceoractivity', 'upload']);\nprefetchStrings('core_error', ['dndmaxbytes', 'dndread', 'dndupload', 'dndunkownfile']);\n\n/**\n * Class to upload a file into the course.\n * @private\n */\nclass FileUploader {\n /**\n * Class constructor.\n *\n * @param {number} courseId the course id\n * @param {number} sectionId the section id\n * @param {number} sectionNum the section number\n * @param {File} fileInfo the file information object\n * @param {Handler} handler the file selected file handler\n */\n constructor(courseId, sectionId, sectionNum, fileInfo, handler) {\n this.courseId = courseId;\n this.sectionId = sectionId;\n this.sectionNum = sectionNum;\n this.fileInfo = fileInfo;\n this.handler = handler;\n }\n\n /**\n * Execute the file upload and update the state in the given process.\n *\n * @param {LoadingProcess} process the process to store the upload result\n */\n execute(process) {\n const fileInfo = this.fileInfo;\n const xhr = this._createXhrRequest(process);\n const formData = this._createUploadFormData();\n\n // Try reading the file to check it is not a folder, before sending it to the server.\n const reader = new FileReader();\n reader.onload = function() {\n // File was read OK - send it to the server.\n xhr.open(\"POST\", UPLOADURL, true);\n xhr.send(formData);\n };\n reader.onerror = function() {\n // Unable to read the file (it is probably a folder) - display an error message.\n process.setError(errors.dndread);\n };\n if (fileInfo.size > 0) {\n // If this is a non-empty file, try reading the first few bytes.\n // This will trigger reader.onerror() for folders and reader.onload() for ordinary, readable files.\n reader.readAsText(fileInfo.slice(0, 5));\n } else {\n // If you call slice() on a 0-byte folder, before calling readAsText, then Firefox triggers reader.onload(),\n // instead of reader.onerror().\n // So, for 0-byte files, just call readAsText on the whole file (and it will trigger load/error functions as expected).\n reader.readAsText(fileInfo);\n }\n }\n\n /**\n * Returns the bind version of execute function.\n *\n * This method is used to queue the process into a ProcessQueue instance.\n *\n * @returns {Function} the bind function to execute the process\n */\n getExecutionFunction() {\n return this.execute.bind(this);\n }\n\n /**\n * Generate a upload XHR file request.\n *\n * @param {LoadingProcess} process the current process\n * @return {XMLHttpRequest} the XHR request\n */\n _createXhrRequest(process) {\n const xhr = new XMLHttpRequest();\n // Update the progress bar as the file is uploaded.\n xhr.upload.addEventListener(\n 'progress',\n (event) => {\n if (event.lengthComputable) {\n const percent = Math.round((event.loaded * 100) / event.total);\n process.setPercentage(percent);\n }\n },\n false\n );\n // Wait for the AJAX call to complete.\n xhr.onreadystatechange = () => {\n if (xhr.readyState == 1) {\n // Add a 1% just to indicate that it is uploading.\n process.setPercentage(1);\n }\n // State 4 is DONE. Otherwise the connection is still ongoing.\n if (xhr.readyState != 4) {\n return;\n }\n if (xhr.status == 200) {\n var result = JSON.parse(xhr.responseText);\n if (result && result.error == 0) {\n // All OK.\n this._finishProcess(process);\n } else {\n process.setError(result.error);\n }\n } else {\n process.setError(errors.dndupload);\n }\n };\n return xhr;\n }\n\n /**\n * Upload a file into the course.\n *\n * @return {FormData|null} the new form data object\n */\n _createUploadFormData() {\n const formData = new FormData();\n try {\n formData.append('repo_upload_file', this.fileInfo);\n } catch (error) {\n throw Error(error.dndread);\n }\n formData.append('sesskey', Config.sesskey);\n formData.append('course', this.courseId);\n formData.append('section', this.sectionNum);\n formData.append('module', this.handler.module);\n formData.append('type', 'Files');\n return formData;\n }\n\n /**\n * Finishes the current process.\n * @param {LoadingProcess} process the process\n */\n _finishProcess(process) {\n addRefreshSection(this.courseId, this.sectionId);\n process.setPercentage(100);\n process.finish();\n }\n}\n\n/**\n * The file handler manager class.\n *\n * @private\n */\nclass HandlerManager {\n\n /** @var {Object} lastHandlers the last handlers selected per each file extension. */\n lastHandlers = {};\n\n /** @var {Handler[]|null} allHandlers all the available handlers. */\n allHandlers = null;\n\n /**\n * Class constructor.\n *\n * @param {Number} courseId\n */\n constructor(courseId) {\n this.courseId = courseId;\n this.lastUploadId = 0;\n this.courseEditor = getCourseEditor(courseId);\n if (!this.courseEditor) {\n throw Error('Unkown course editor');\n }\n this.maxbytes = this.courseEditor.get('course')?.maxbytes ?? 0;\n }\n\n /**\n * Load the course file handlers.\n */\n async loadHandlers() {\n this.allHandlers = await this.courseEditor.getFileHandlersPromise();\n }\n\n /**\n * Extract the file extension from a fileInfo.\n *\n * @param {File} fileInfo\n * @returns {String} the file extension or an empty string.\n */\n getFileExtension(fileInfo) {\n let extension = '';\n const dotpos = fileInfo.name.lastIndexOf('.');\n if (dotpos != -1) {\n extension = fileInfo.name.substring(dotpos + 1, fileInfo.name.length).toLowerCase();\n }\n return extension;\n }\n\n /**\n * Check if the file is valid.\n *\n * @param {File} fileInfo the file info\n */\n validateFile(fileInfo) {\n if (this.maxbytes !== USERCANIGNOREFILESIZELIMITS && fileInfo.size > this.maxbytes) {\n throw Error(errors.dndmaxbytes);\n }\n }\n\n /**\n * Get the file handlers of an specific file.\n *\n * @param {File} fileInfo the file indo\n * @return {Array} Array of handlers\n */\n filterHandlers(fileInfo) {\n const extension = this.getFileExtension(fileInfo);\n return this.allHandlers.filter(handler => handler.extension == '*' || handler.extension == extension);\n }\n\n /**\n * Get the Handler to upload a specific file.\n *\n * It will ask the used if more than one handler is available.\n *\n * @param {File} fileInfo the file info\n * @returns {Promise} the selected handler or null if the user cancel\n */\n async getFileHandler(fileInfo) {\n const fileHandlers = this.filterHandlers(fileInfo);\n if (fileHandlers.length == 0) {\n throw Error(errors.dndunkownfile);\n }\n let fileHandler = null;\n if (fileHandlers.length == 1) {\n fileHandler = fileHandlers[0];\n } else {\n fileHandler = await this.askHandlerToUser(fileHandlers, fileInfo);\n }\n return fileHandler;\n }\n\n /**\n * Ask the user to select a specific handler.\n *\n * @param {Handler[]} fileHandlers\n * @param {File} fileInfo the file info\n * @return {Promise} the selected handler\n */\n async askHandlerToUser(fileHandlers, fileInfo) {\n const extension = this.getFileExtension(fileInfo);\n // Build the modal parameters from the event data.\n const modalParams = {\n title: getString('addresourceoractivity', 'moodle'),\n body: Templates.render(\n 'core_courseformat/fileuploader',\n this.getModalData(\n fileHandlers,\n fileInfo,\n this.lastHandlers[extension] ?? null\n )\n ),\n saveButtonText: getString('upload', 'moodle'),\n };\n // Create the modal.\n const modal = await this.modalBodyRenderedPromise(modalParams);\n const selectedHandler = await this.modalUserAnswerPromise(modal, fileHandlers);\n // Cancel action.\n if (selectedHandler === null) {\n return null;\n }\n // Save last selected handler.\n this.lastHandlers[extension] = selectedHandler.module;\n return selectedHandler;\n }\n\n /**\n * Generated the modal template data.\n *\n * @param {Handler[]} fileHandlers\n * @param {File} fileInfo the file info\n * @param {String|null} defaultModule the default module if any\n * @return {Object} the modal template data.\n */\n getModalData(fileHandlers, fileInfo, defaultModule) {\n const data = {\n filename: fileInfo.name,\n uploadid: ++this.lastUploadId,\n handlers: [],\n };\n let hasDefault = false;\n fileHandlers.forEach((handler, index) => {\n const isDefault = (defaultModule == handler.module);\n data.handlers.push({\n ...handler,\n selected: isDefault,\n labelid: `fileuploader_${data.uploadid}`,\n value: index,\n });\n hasDefault = hasDefault || isDefault;\n });\n if (!hasDefault && data.handlers.length > 0) {\n const lastHandler = data.handlers.pop();\n lastHandler.selected = true;\n data.handlers.push(lastHandler);\n }\n return data;\n }\n\n /**\n * Get the user handler choice.\n *\n * Wait for the user answer in the modal and resolve with the selected index.\n *\n * @param {Modal} modal the modal instance\n * @param {Handler[]} fileHandlers the availabvle file handlers\n * @return {Promise} with the option selected by the user.\n */\n modalUserAnswerPromise(modal, fileHandlers) {\n const modalBody = getFirst(modal.getBody());\n return new Promise((resolve, reject) => {\n modal.getRoot().on(\n ModalEvents.save,\n event => {\n // Get the selected option.\n const index = modalBody.querySelector('input:checked').value;\n event.preventDefault();\n modal.destroy();\n if (!fileHandlers[index]) {\n reject('Invalid handler selected');\n }\n resolve(fileHandlers[index]);\n\n }\n );\n modal.getRoot().on(\n ModalEvents.cancel,\n () => {\n resolve(null);\n }\n );\n });\n }\n\n /**\n * Create a new modal and return a Promise to the body rendered.\n *\n * @param {Object} modalParams the modal params\n * @returns {Promise} the modal body rendered promise\n */\n modalBodyRenderedPromise(modalParams) {\n return new Promise((resolve, reject) => {\n ModalSaveCancel.create(modalParams).then((modal) => {\n modal.setRemoveOnClose(true);\n // Handle body loading event.\n modal.getRoot().on(ModalEvents.bodyRendered, () => {\n resolve(modal);\n });\n // Configure some extra modal params.\n if (modalParams.saveButtonText !== undefined) {\n modal.setSaveButtonText(modalParams.saveButtonText);\n }\n modal.show();\n return;\n }).catch(() => {\n reject(`Cannot load modal content`);\n });\n });\n }\n}\n\n/**\n * Add a section to refresh.\n *\n * @param {number} courseId the course id\n * @param {number} sectionId the seciton id\n */\nfunction addRefreshSection(courseId, sectionId) {\n let refresh = courseUpdates.get(courseId);\n if (!refresh) {\n refresh = new Set();\n }\n refresh.add(sectionId);\n courseUpdates.set(courseId, refresh);\n refreshCourseEditors();\n}\n\n/**\n * Debounced processing all pending course refreshes.\n * @private\n */\nconst refreshCourseEditors = debounce(\n () => {\n const refreshes = courseUpdates;\n courseUpdates = new Map();\n refreshes.forEach((sectionIds, courseId) => {\n const courseEditor = getCourseEditor(courseId);\n if (!courseEditor) {\n return;\n }\n courseEditor.dispatch('sectionState', [...sectionIds]);\n });\n },\n DEBOUNCETIMER\n);\n\n/**\n * Load and return the course handler manager instance.\n *\n * @param {Number} courseId the course Id to load\n * @returns {Promise} promise of the the loaded handleManager\n */\nasync function loadCourseHandlerManager(courseId) {\n if (handlerManagers[courseId] !== undefined) {\n return handlerManagers[courseId];\n }\n const handlerManager = new HandlerManager(courseId);\n await handlerManager.loadHandlers();\n handlerManagers[courseId] = handlerManager;\n return handlerManagers[courseId];\n}\n\n/**\n * Load all the erros messages at once in the module \"errors\" variable.\n * @param {Number} courseId the course id\n */\nasync function loadErrorStrings(courseId) {\n if (errors !== null) {\n return;\n }\n const courseEditor = getCourseEditor(courseId);\n const maxbytestext = courseEditor.get('course')?.maxbytestext ?? '0';\n\n errors = {};\n const allStrings = [\n {key: 'dndmaxbytes', component: 'core_error', param: {size: maxbytestext}},\n {key: 'dndread', component: 'core_error'},\n {key: 'dndupload', component: 'core_error'},\n {key: 'dndunkownfile', component: 'core_error'},\n ];\n window.console.log(allStrings);\n const loadedStrings = await getStrings(allStrings);\n allStrings.forEach(({key}, index) => {\n errors[key] = loadedStrings[index];\n });\n}\n\n/**\n * Start a batch file uploading into the course.\n *\n * @private\n * @param {number} courseId the course id.\n * @param {number} sectionId the section id.\n * @param {number} sectionNum the section number.\n * @param {File} fileInfo the file information object\n * @param {HandlerManager} handlerManager the course handler manager\n */\nconst queueFileUpload = async function(courseId, sectionId, sectionNum, fileInfo, handlerManager) {\n let handler;\n uploadQueue = await processMonitor.createProcessQueue();\n try {\n handlerManager.validateFile(fileInfo);\n handler = await handlerManager.getFileHandler(fileInfo);\n } catch (error) {\n uploadQueue.addError(fileInfo.name, error.message);\n return;\n }\n // If we don't have a handler means the user cancel the upload.\n if (!handler) {\n return;\n }\n const fileProcessor = new FileUploader(courseId, sectionId, sectionNum, fileInfo, handler);\n uploadQueue.addPending(fileInfo.name, fileProcessor.getExecutionFunction());\n};\n\n/**\n * Upload a file to the course.\n *\n * This method will show any necesary modal to handle the request.\n *\n * @param {number} courseId the course id\n * @param {number} sectionId the section id\n * @param {number} sectionNum the section number\n * @param {Array} files and array of files\n */\nexport const uploadFilesToCourse = async function(courseId, sectionId, sectionNum, files) {\n // Get the course handlers.\n const handlerManager = await loadCourseHandlerManager(courseId);\n await loadErrorStrings(courseId);\n for (let index = 0; index < files.length; index++) {\n const fileInfo = files[index];\n await queueFileUpload(courseId, sectionId, sectionNum, fileInfo, handlerManager);\n }\n};\n"],"names":["UPLOADURL","Config","wwwroot","uploadQueue","handlerManagers","courseUpdates","Map","errors","FileUploader","constructor","courseId","sectionId","sectionNum","fileInfo","handler","execute","process","this","xhr","_createXhrRequest","formData","_createUploadFormData","reader","FileReader","onload","open","send","onerror","setError","dndread","size","readAsText","slice","getExecutionFunction","bind","XMLHttpRequest","upload","addEventListener","event","lengthComputable","percent","Math","round","loaded","total","setPercentage","onreadystatechange","readyState","status","result","JSON","parse","responseText","error","_finishProcess","dndupload","FormData","append","Error","sesskey","module","refresh","get","Set","add","set","refreshCourseEditors","addRefreshSection","finish","HandlerManager","lastUploadId","courseEditor","maxbytes","_this$courseEditor$ge2","allHandlers","getFileHandlersPromise","getFileExtension","extension","dotpos","name","lastIndexOf","substring","length","toLowerCase","validateFile","dndmaxbytes","filterHandlers","filter","fileHandlers","dndunkownfile","fileHandler","askHandlerToUser","modalParams","title","body","Templates","render","getModalData","lastHandlers","saveButtonText","modal","modalBodyRenderedPromise","selectedHandler","modalUserAnswerPromise","defaultModule","data","filename","uploadid","handlers","hasDefault","forEach","index","isDefault","push","selected","labelid","value","lastHandler","pop","modalBody","getBody","Promise","resolve","reject","getRoot","on","ModalEvents","save","querySelector","preventDefault","destroy","cancel","create","then","setRemoveOnClose","bodyRendered","undefined","setSaveButtonText","show","catch","refreshes","sectionIds","dispatch","queueFileUpload","async","handlerManager","processMonitor","createProcessQueue","getFileHandler","addError","message","fileProcessor","addPending","files","loadHandlers","loadCourseHandlerManager","maxbytestext","_courseEditor$get","allStrings","key","component","param","window","console","log","loadedStrings","loadErrorStrings"],"mappings":"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"} \ No newline at end of file diff --git a/course/format/amd/src/local/content/actions.js b/course/format/amd/src/local/content/actions.js index 49dfb4f3135..776702b14cb 100644 --- a/course/format/amd/src/local/content/actions.js +++ b/course/format/amd/src/local/content/actions.js @@ -26,7 +26,9 @@ */ import {BaseComponent} from 'core/reactive'; -import ModalFactory from 'core/modal_factory'; +import Modal from 'core/modal'; +import ModalSaveCancel from 'core/modal_save_cancel'; +import ModalDeleteCancel from 'core/modal_delete_cancel'; import ModalEvents from 'core/modal_events'; import Templates from 'core/templates'; import {prefetchStrings} from 'core/prefetch'; @@ -247,14 +249,12 @@ export default class extends BaseComponent { } + // Create the modal. // Build the modal parameters from the event data. - const modalParams = { + const modal = await this._modalBodyRenderedPromise(Modal, { title: titleText, body: Templates.render('core_courseformat/local/content/movesection', data), - }; - - // Create the modal. - const modal = await this._modalBodyRenderedPromise(modalParams); + }); const modalBody = getFirst(modal.getBody()); @@ -328,14 +328,12 @@ export default class extends BaseComponent { titleText = this.reactive.getFormatString('cmsmove_title'); } + // Create the modal. // Build the modal parameters from the event data. - const modalParams = { + const modal = await this._modalBodyRenderedPromise(Modal, { title: titleText, body: Templates.render('core_courseformat/local/content/movecm', data), - }; - - // Create the modal. - const modal = await this._modalBodyRenderedPromise(modalParams); + }); const modalBody = getFirst(modal.getBody()); @@ -446,13 +444,10 @@ export default class extends BaseComponent { bodyText = this.reactive.getFormatString('sectionsdelete_info', {count: sectionIds.length}); } - const modalParams = { + const modal = await this._modalBodyRenderedPromise(ModalDeleteCancel, { title: titleText, body: bodyText, - type: ModalFactory.types.DELETE_CANCEL, - }; - - const modal = await this._modalBodyRenderedPromise(modalParams); + }); modal.getRoot().on( ModalEvents.delete, @@ -552,13 +547,10 @@ export default class extends BaseComponent { ); } - const modalParams = { + const modal = await this._modalBodyRenderedPromise(ModalDeleteCancel, { title: titleText, body: bodyText, - type: ModalFactory.types.DELETE_CANCEL, - }; - - const modal = await this._modalBodyRenderedPromise(modalParams); + }); modal.getRoot().on( ModalEvents.delete, @@ -586,13 +578,11 @@ export default class extends BaseComponent { const data = { allowstealth: exporter.canUseStealth(this.reactive.state, cmIds), }; - const modalParams = { + const modal = await this._modalBodyRenderedPromise(ModalSaveCancel, { title: getString('availability', 'core'), body: Templates.render('core_courseformat/local/content/cm/availabilitymodal', data), saveButtonText: getString('apply', 'core'), - type: ModalFactory.types.SAVE_CANCEL, - }; - const modal = await this._modalBodyRenderedPromise(modalParams); + }); this._setupMutationRadioButtonModal(modal, cmIds); } @@ -609,13 +599,11 @@ export default class extends BaseComponent { } const title = (sectionIds.length == 1) ? 'sectionavailability_title' : 'sectionsavailability_title'; // Show the availability modal to decide which action to trigger. - const modalParams = { + const modal = await this._modalBodyRenderedPromise(ModalSaveCancel, { title: this.reactive.getFormatString(title), body: Templates.render('core_courseformat/local/content/section/availabilitymodal', []), saveButtonText: getString('apply', 'core'), - type: ModalFactory.types.SAVE_CANCEL, - }; - const modal = await this._modalBodyRenderedPromise(modalParams); + }); this._setupMutationRadioButtonModal(modal, sectionIds); } @@ -698,12 +686,13 @@ export default class extends BaseComponent { /** * Render a modal and return a body ready promise. * + * @param {Modal} ModalClass the modal class * @param {object} modalParams the modal params * @return {Promise} the modal body ready promise */ - _modalBodyRenderedPromise(modalParams) { + _modalBodyRenderedPromise(ModalClass, modalParams) { return new Promise((resolve, reject) => { - ModalFactory.create(modalParams).then((modal) => { + ModalClass.create(modalParams).then((modal) => { modal.setRemoveOnClose(true); // Handle body loading event. modal.getRoot().on(ModalEvents.bodyRendered, () => { diff --git a/course/format/amd/src/local/courseeditor/fileuploader.js b/course/format/amd/src/local/courseeditor/fileuploader.js index 3daefb6a1aa..9103a44bf32 100644 --- a/course/format/amd/src/local/courseeditor/fileuploader.js +++ b/course/format/amd/src/local/courseeditor/fileuploader.js @@ -31,7 +31,7 @@ */ import Config from 'core/config'; -import ModalFactory from 'core/modal_factory'; +import ModalSaveCancel from 'core/modal_save_cancel'; import ModalEvents from 'core/modal_events'; import Templates from 'core/templates'; import {getFirst} from 'core/normalise'; @@ -314,7 +314,6 @@ class HandlerManager { this.lastHandlers[extension] ?? null ) ), - type: ModalFactory.types.SAVE_CANCEL, saveButtonText: getString('upload', 'moodle'), }; // Create the modal. @@ -405,7 +404,7 @@ class HandlerManager { */ modalBodyRenderedPromise(modalParams) { return new Promise((resolve, reject) => { - ModalFactory.create(modalParams).then((modal) => { + ModalSaveCancel.create(modalParams).then((modal) => { modal.setRemoveOnClose(true); // Handle body loading event. modal.getRoot().on(ModalEvents.bodyRendered, () => { diff --git a/enrol/manual/amd/build/quickenrolment.min.js b/enrol/manual/amd/build/quickenrolment.min.js index 2155e03cdcf..38659ab3100 100644 --- a/enrol/manual/amd/build/quickenrolment.min.js +++ b/enrol/manual/amd/build/quickenrolment.min.js @@ -1,10 +1,10 @@ -define("enrol_manual/quickenrolment",["exports","core_table/dynamic","core/str","core/toast","core/config","core/fragment","core/modal_events","core/modal_factory","core/notification","jquery","core/pending","core/prefetch"],(function(_exports,DynamicTable,Str,Toast,_config,_fragment,_modal_events,_modal_factory,_notification,_jquery,_pending,_prefetch){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireWildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}return newObj.default=obj,cache&&cache.set(obj,newObj),newObj} +define("enrol_manual/quickenrolment",["exports","core_table/dynamic","core/str","core/toast","core/config","core/fragment","core/modal_events","core/notification","jquery","core/pending","core/prefetch","core/modal_save_cancel"],(function(_exports,DynamicTable,Str,Toast,_config,_fragment,_modal_events,_notification,_jquery,_pending,_prefetch,_modal_save_cancel){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireWildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}return newObj.default=obj,cache&&cache.set(obj,newObj),newObj} /** * Quick enrolment AMD module. * * @module enrol_manual/quickenrolment * @copyright 2016 Damyon Wiese * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,DynamicTable=_interopRequireWildcard(DynamicTable),Str=_interopRequireWildcard(Str),Toast=_interopRequireWildcard(Toast),_config=_interopRequireDefault(_config),_fragment=_interopRequireDefault(_fragment),_modal_events=_interopRequireDefault(_modal_events),_modal_factory=_interopRequireDefault(_modal_factory),_notification=_interopRequireDefault(_notification),_jquery=_interopRequireDefault(_jquery),_pending=_interopRequireDefault(_pending),_prefetch=_interopRequireDefault(_prefetch);const Selectors_cohortSelector="#id_cohortlist",Selectors_triggerButtons=".enrolusersbutton.enrol_manual_plugin [type='submit']",Selectors_unwantedHiddenFields="input[value='_qf__force_multiselect_submission']",Selectors_buttonWrapper='[data-region="wrapper"]',getBodyForContext=contextId=>_fragment.default.loadFragment("enrol_manual","enrol_users_form",contextId,{}),registerEventListeners=contextId=>{document.addEventListener("click",(e=>{if(e.target.closest(Selectors_triggerButtons))return e.preventDefault(),void showModal((element=>{const wrapper=element.closest(Selectors_buttonWrapper);return DynamicTable.getTableFromId(wrapper.dataset.tableUniqueid)})(e.target),contextId)}))},showModal=(dynamicTable,contextId)=>{const pendingPromise=new _pending.default("enrol_manual/quickenrolment:showModal");return _modal_factory.default.create({type:_modal_factory.default.types.SAVE_CANCEL,large:!0,title:Str.get_string("enrolusers","enrol_manual"),body:getBodyForContext(contextId),buttons:{save:Str.get_string("enrolusers","enrol_manual")}}).then((modal=>(modal.getRoot().on(_modal_events.default.save,(e=>{e.preventDefault(),modal.getRoot().find("form").submit()})),modal.getRoot().on("submit","form",(e=>{e.preventDefault(),submitFormAjax(dynamicTable,modal)})),modal.getRoot().on(_modal_events.default.hidden,(()=>{modal.destroy()})),modal.show(),modal))).then((modal=>Promise.all([modal,modal.getBodyPromise()]))).then((_ref=>{let[modal,body]=_ref;return body.get(0).querySelector(Selectors_cohortSelector)?modal.setSaveButtonText(Str.get_string("enroluserscohorts","enrol_manual")).then((()=>modal)):modal})).then((modal=>(pendingPromise.resolve(),modal))).catch(_notification.default.exception)},submitFormAjax=(dynamicTable,modal)=>{const form=modal.getRoot().find("form");form.get(0).querySelectorAll(Selectors_unwantedHiddenFields).forEach((hiddenField=>hiddenField.remove())),modal.hide(),modal.destroy(),_jquery.default.ajax("".concat(_config.default.wwwroot,"/enrol/manual/ajax.php?").concat(form.serialize()),{type:"GET",processData:!1,contentType:"application/json"}).then((response=>{if(response.error)throw new Error(response.error);return response.count})).then((count=>Promise.all([Str.get_string("totalenrolledusers","enrol",count),DynamicTable.refreshTableContent(dynamicTable)]))).then((_ref2=>{let[notificationBody]=_ref2;return notificationBody})).then((notificationBody=>Toast.add(notificationBody))).catch((error=>{_notification.default.addNotification({message:error.message,type:"error"})}))};_exports.init=_ref3=>{let{contextid:contextid}=_ref3;registerEventListeners(contextid),_prefetch.default.prefetchStrings("enrol_manual",["enrolusers","enroluserscohorts"]),_prefetch.default.prefetchString("enrol","totalenrolledusers")}})); + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,DynamicTable=_interopRequireWildcard(DynamicTable),Str=_interopRequireWildcard(Str),Toast=_interopRequireWildcard(Toast),_config=_interopRequireDefault(_config),_fragment=_interopRequireDefault(_fragment),_modal_events=_interopRequireDefault(_modal_events),_notification=_interopRequireDefault(_notification),_jquery=_interopRequireDefault(_jquery),_pending=_interopRequireDefault(_pending),_prefetch=_interopRequireDefault(_prefetch),_modal_save_cancel=_interopRequireDefault(_modal_save_cancel);const Selectors_cohortSelector="#id_cohortlist",Selectors_triggerButtons=".enrolusersbutton.enrol_manual_plugin [type='submit']",Selectors_unwantedHiddenFields="input[value='_qf__force_multiselect_submission']",Selectors_buttonWrapper='[data-region="wrapper"]',getBodyForContext=contextId=>_fragment.default.loadFragment("enrol_manual","enrol_users_form",contextId,{}),registerEventListeners=contextId=>{document.addEventListener("click",(e=>{if(e.target.closest(Selectors_triggerButtons))return e.preventDefault(),void showModal((element=>{const wrapper=element.closest(Selectors_buttonWrapper);return DynamicTable.getTableFromId(wrapper.dataset.tableUniqueid)})(e.target),contextId)}))},showModal=(dynamicTable,contextId)=>{const pendingPromise=new _pending.default("enrol_manual/quickenrolment:showModal");return _modal_save_cancel.default.create({large:!0,title:Str.get_string("enrolusers","enrol_manual"),body:getBodyForContext(contextId),buttons:{save:Str.get_string("enrolusers","enrol_manual")},show:!0}).then((modal=>(modal.getRoot().on(_modal_events.default.save,(e=>{e.preventDefault(),modal.getRoot().find("form").submit()})),modal.getRoot().on("submit","form",(e=>{e.preventDefault(),submitFormAjax(dynamicTable,modal)})),modal.getRoot().on(_modal_events.default.hidden,(()=>{modal.destroy()})),modal))).then((modal=>Promise.all([modal,modal.getBodyPromise()]))).then((_ref=>{let[modal,body]=_ref;return body.get(0).querySelector(Selectors_cohortSelector)?modal.setSaveButtonText(Str.get_string("enroluserscohorts","enrol_manual")).then((()=>modal)):modal})).then((modal=>(pendingPromise.resolve(),modal))).catch(_notification.default.exception)},submitFormAjax=(dynamicTable,modal)=>{const form=modal.getRoot().find("form");form.get(0).querySelectorAll(Selectors_unwantedHiddenFields).forEach((hiddenField=>hiddenField.remove())),modal.hide(),modal.destroy(),_jquery.default.ajax("".concat(_config.default.wwwroot,"/enrol/manual/ajax.php?").concat(form.serialize()),{type:"GET",processData:!1,contentType:"application/json"}).then((response=>{if(response.error)throw new Error(response.error);return response.count})).then((count=>Promise.all([Str.get_string("totalenrolledusers","enrol",count),DynamicTable.refreshTableContent(dynamicTable)]))).then((_ref2=>{let[notificationBody]=_ref2;return notificationBody})).then((notificationBody=>Toast.add(notificationBody))).catch((error=>{_notification.default.addNotification({message:error.message,type:"error"})}))};_exports.init=_ref3=>{let{contextid:contextid}=_ref3;registerEventListeners(contextid),_prefetch.default.prefetchStrings("enrol_manual",["enrolusers","enroluserscohorts"]),_prefetch.default.prefetchString("enrol","totalenrolledusers")}})); //# sourceMappingURL=quickenrolment.min.js.map \ No newline at end of file diff --git a/enrol/manual/amd/build/quickenrolment.min.js.map b/enrol/manual/amd/build/quickenrolment.min.js.map index c903fd23853..eef35da1ac7 100644 --- a/enrol/manual/amd/build/quickenrolment.min.js.map +++ b/enrol/manual/amd/build/quickenrolment.min.js.map @@ -1 +1 @@ -{"version":3,"file":"quickenrolment.min.js","sources":["../src/quickenrolment.js"],"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 * Quick enrolment AMD module.\n *\n * @module enrol_manual/quickenrolment\n * @copyright 2016 Damyon Wiese \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport * as DynamicTable from 'core_table/dynamic';\nimport * as Str from 'core/str';\nimport * as Toast from 'core/toast';\nimport Config from 'core/config';\nimport Fragment from 'core/fragment';\nimport ModalEvents from 'core/modal_events';\nimport ModalFactory from 'core/modal_factory';\nimport Notification from 'core/notification';\nimport jQuery from 'jquery';\nimport Pending from 'core/pending';\nimport Prefetch from 'core/prefetch';\n\nconst Selectors = {\n cohortSelector: \"#id_cohortlist\",\n triggerButtons: \".enrolusersbutton.enrol_manual_plugin [type='submit']\",\n unwantedHiddenFields: \"input[value='_qf__force_multiselect_submission']\",\n buttonWrapper: '[data-region=\"wrapper\"]',\n};\n\n/**\n * Get the content of the body for the specified context.\n *\n * @param {Number} contextId\n * @returns {Promise}\n */\nconst getBodyForContext = contextId => {\n return Fragment.loadFragment('enrol_manual', 'enrol_users_form', contextId, {});\n};\n\n/**\n * Get the dynamic table for the button.\n *\n * @param {HTMLElement} element\n * @returns {HTMLElement}\n */\nconst getDynamicTableForElement = element => {\n const wrapper = element.closest(Selectors.buttonWrapper);\n\n return DynamicTable.getTableFromId(wrapper.dataset.tableUniqueid);\n};\n\n/**\n * Register the event listeners for this contextid.\n *\n * @param {Number} contextId\n */\nconst registerEventListeners = contextId => {\n document.addEventListener('click', e => {\n if (e.target.closest(Selectors.triggerButtons)) {\n e.preventDefault();\n\n showModal(getDynamicTableForElement(e.target), contextId);\n\n return;\n }\n });\n};\n\n/**\n * Display the modal for this contextId.\n *\n * @param {HTMLElement} dynamicTable The table to beb refreshed when changes are made\n * @param {Number} contextId\n * @returns {Promise}\n */\nconst showModal = (dynamicTable, contextId) => {\n const pendingPromise = new Pending('enrol_manual/quickenrolment:showModal');\n\n return ModalFactory.create({\n type: ModalFactory.types.SAVE_CANCEL,\n large: true,\n title: Str.get_string('enrolusers', 'enrol_manual'),\n body: getBodyForContext(contextId),\n buttons: {\n save: Str.get_string('enrolusers', 'enrol_manual'),\n }\n })\n .then(modal => {\n modal.getRoot().on(ModalEvents.save, e => {\n // Trigger a form submission, so that any mform elements can do final tricks before the form submission\n // is processed.\n // The actual submit even tis captured in the next handler.\n\n e.preventDefault();\n modal.getRoot().find('form').submit();\n });\n\n modal.getRoot().on('submit', 'form', e => {\n e.preventDefault();\n\n submitFormAjax(dynamicTable, modal);\n });\n\n modal.getRoot().on(ModalEvents.hidden, () => {\n modal.destroy();\n });\n\n modal.show();\n\n return modal;\n })\n .then(modal => Promise.all([modal, modal.getBodyPromise()]))\n .then(([modal, body]) => {\n if (body.get(0).querySelector(Selectors.cohortSelector)) {\n return modal.setSaveButtonText(Str.get_string('enroluserscohorts', 'enrol_manual')).then(() => modal);\n }\n\n return modal;\n })\n .then(modal => {\n pendingPromise.resolve();\n\n return modal;\n })\n .catch(Notification.exception);\n};\n\n/**\n * Submit the form via ajax.\n *\n * @param {HTMLElement} dynamicTable\n * @param {Object} modal\n */\nconst submitFormAjax = (dynamicTable, modal) => {\n // Note: We use a jQuery object here so that we can use its serialize functionality.\n const form = modal.getRoot().find('form');\n\n // Before send the data through AJAX, we need to parse and remove some unwanted hidden fields.\n // This hidden fields are added automatically by mforms and when it reaches the AJAX we get an error.\n form.get(0).querySelectorAll(Selectors.unwantedHiddenFields).forEach(hiddenField => hiddenField.remove());\n\n modal.hide();\n modal.destroy();\n\n jQuery.ajax(\n `${Config.wwwroot}/enrol/manual/ajax.php?${form.serialize()}`,\n {\n type: 'GET',\n processData: false,\n contentType: \"application/json\",\n }\n )\n .then(response => {\n if (response.error) {\n throw new Error(response.error);\n }\n\n return response.count;\n })\n .then(count => {\n return Promise.all([\n Str.get_string('totalenrolledusers', 'enrol', count),\n DynamicTable.refreshTableContent(dynamicTable),\n ]);\n })\n .then(([notificationBody]) => notificationBody)\n .then(notificationBody => Toast.add(notificationBody))\n .catch(error => {\n Notification.addNotification({\n message: error.message,\n type: 'error',\n });\n });\n};\n\n/**\n * Set up quick enrolment for the manual enrolment plugin.\n *\n * @param {Number} contextid The context id to setup for\n */\nexport const init = ({contextid}) => {\n registerEventListeners(contextid);\n\n Prefetch.prefetchStrings('enrol_manual', [\n 'enrolusers',\n 'enroluserscohorts',\n ]);\n\n Prefetch.prefetchString('enrol', 'totalenrolledusers');\n};\n"],"names":["Selectors","getBodyForContext","contextId","Fragment","loadFragment","registerEventListeners","document","addEventListener","e","target","closest","preventDefault","showModal","element","wrapper","DynamicTable","getTableFromId","dataset","tableUniqueid","getDynamicTableForElement","dynamicTable","pendingPromise","Pending","ModalFactory","create","type","types","SAVE_CANCEL","large","title","Str","get_string","body","buttons","save","then","modal","getRoot","on","ModalEvents","find","submit","submitFormAjax","hidden","destroy","show","Promise","all","getBodyPromise","_ref","get","querySelector","setSaveButtonText","resolve","catch","Notification","exception","form","querySelectorAll","forEach","hiddenField","remove","hide","ajax","Config","wwwroot","serialize","processData","contentType","response","error","Error","count","refreshTableContent","_ref2","notificationBody","Toast","add","addNotification","message","_ref3","contextid","prefetchStrings","prefetchString"],"mappings":";;;;;;;ikBAkCMA,yBACc,iBADdA,yBAEc,wDAFdA,+BAGoB,mDAHpBA,wBAIa,0BASbC,kBAAoBC,WACfC,kBAASC,aAAa,eAAgB,mBAAoBF,UAAW,IAoB1EG,uBAAyBH,YAC3BI,SAASC,iBAAiB,SAASC,OAC3BA,EAAEC,OAAOC,QAAQV,iCACjBQ,EAAEG,sBAEFC,UAhBsBC,CAAAA,gBACxBC,QAAUD,QAAQH,QAAQV,gCAEzBe,aAAaC,eAAeF,QAAQG,QAAQC,gBAajCC,CAA0BX,EAAEC,QAASP,eAcrDU,UAAY,CAACQ,aAAclB,mBACvBmB,eAAiB,IAAIC,iBAAQ,gDAE5BC,uBAAaC,OAAO,CACvBC,KAAMF,uBAAaG,MAAMC,YACzBC,OAAO,EACPC,MAAOC,IAAIC,WAAW,aAAc,gBACpCC,KAAM/B,kBAAkBC,WACxB+B,QAAS,CACLC,KAAMJ,IAAIC,WAAW,aAAc,mBAG1CI,MAAKC,QACFA,MAAMC,UAAUC,GAAGC,sBAAYL,MAAM1B,IAKjCA,EAAEG,iBACFyB,MAAMC,UAAUG,KAAK,QAAQC,YAGjCL,MAAMC,UAAUC,GAAG,SAAU,QAAQ9B,IACjCA,EAAEG,iBAEF+B,eAAetB,aAAcgB,UAGjCA,MAAMC,UAAUC,GAAGC,sBAAYI,QAAQ,KACnCP,MAAMQ,aAGVR,MAAMS,OAECT,SAEVD,MAAKC,OAASU,QAAQC,IAAI,CAACX,MAAOA,MAAMY,qBACxCb,MAAKc,WAAEb,MAAOJ,kBACPA,KAAKkB,IAAI,GAAGC,cAAcnD,0BACnBoC,MAAMgB,kBAAkBtB,IAAIC,WAAW,oBAAqB,iBAAiBI,MAAK,IAAMC,QAG5FA,SAEVD,MAAKC,QACFf,eAAegC,UAERjB,SAEVkB,MAAMC,sBAAaC,YASlBd,eAAiB,CAACtB,aAAcgB,eAE5BqB,KAAOrB,MAAMC,UAAUG,KAAK,QAIlCiB,KAAKP,IAAI,GAAGQ,iBAAiB1D,gCAAgC2D,SAAQC,aAAeA,YAAYC,WAEhGzB,MAAM0B,OACN1B,MAAMQ,0BAECmB,eACAC,gBAAOC,0CAAiCR,KAAKS,aAChD,CACIzC,KAAM,MACN0C,aAAa,EACbC,YAAa,qBAGpBjC,MAAKkC,cACEA,SAASC,YACH,IAAIC,MAAMF,SAASC,cAGtBD,SAASG,SAEnBrC,MAAKqC,OACK1B,QAAQC,IAAI,CACfjB,IAAIC,WAAW,qBAAsB,QAASyC,OAC9CzD,aAAa0D,oBAAoBrD,kBAGxCe,MAAKuC,YAAEC,+BAAsBA,oBAC7BxC,MAAKwC,kBAAoBC,MAAMC,IAAIF,oBACnCrB,OAAMgB,8BACUQ,gBAAgB,CACzBC,QAAST,MAAMS,QACftD,KAAM,4BAUEuD,YAACC,UAACA,iBAClB5E,uBAAuB4E,6BAEdC,gBAAgB,eAAgB,CACrC,aACA,wCAGKC,eAAe,QAAS"} \ No newline at end of file +{"version":3,"file":"quickenrolment.min.js","sources":["../src/quickenrolment.js"],"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 * Quick enrolment AMD module.\n *\n * @module enrol_manual/quickenrolment\n * @copyright 2016 Damyon Wiese \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport * as DynamicTable from 'core_table/dynamic';\nimport * as Str from 'core/str';\nimport * as Toast from 'core/toast';\nimport Config from 'core/config';\nimport Fragment from 'core/fragment';\nimport ModalEvents from 'core/modal_events';\nimport Notification from 'core/notification';\nimport jQuery from 'jquery';\nimport Pending from 'core/pending';\nimport Prefetch from 'core/prefetch';\nimport ModalSaveCancel from 'core/modal_save_cancel';\n\nconst Selectors = {\n cohortSelector: \"#id_cohortlist\",\n triggerButtons: \".enrolusersbutton.enrol_manual_plugin [type='submit']\",\n unwantedHiddenFields: \"input[value='_qf__force_multiselect_submission']\",\n buttonWrapper: '[data-region=\"wrapper\"]',\n};\n\n/**\n * Get the content of the body for the specified context.\n *\n * @param {Number} contextId\n * @returns {Promise}\n */\nconst getBodyForContext = contextId => {\n return Fragment.loadFragment('enrol_manual', 'enrol_users_form', contextId, {});\n};\n\n/**\n * Get the dynamic table for the button.\n *\n * @param {HTMLElement} element\n * @returns {HTMLElement}\n */\nconst getDynamicTableForElement = element => {\n const wrapper = element.closest(Selectors.buttonWrapper);\n\n return DynamicTable.getTableFromId(wrapper.dataset.tableUniqueid);\n};\n\n/**\n * Register the event listeners for this contextid.\n *\n * @param {Number} contextId\n */\nconst registerEventListeners = contextId => {\n document.addEventListener('click', e => {\n if (e.target.closest(Selectors.triggerButtons)) {\n e.preventDefault();\n\n showModal(getDynamicTableForElement(e.target), contextId);\n\n return;\n }\n });\n};\n\n/**\n * Display the modal for this contextId.\n *\n * @param {HTMLElement} dynamicTable The table to beb refreshed when changes are made\n * @param {Number} contextId\n * @returns {Promise}\n */\nconst showModal = (dynamicTable, contextId) => {\n const pendingPromise = new Pending('enrol_manual/quickenrolment:showModal');\n\n return ModalSaveCancel.create({\n large: true,\n title: Str.get_string('enrolusers', 'enrol_manual'),\n body: getBodyForContext(contextId),\n buttons: {\n save: Str.get_string('enrolusers', 'enrol_manual'),\n },\n show: true,\n })\n .then(modal => {\n modal.getRoot().on(ModalEvents.save, e => {\n // Trigger a form submission, so that any mform elements can do final tricks before the form submission\n // is processed.\n // The actual submit even tis captured in the next handler.\n\n e.preventDefault();\n modal.getRoot().find('form').submit();\n });\n\n modal.getRoot().on('submit', 'form', e => {\n e.preventDefault();\n\n submitFormAjax(dynamicTable, modal);\n });\n\n modal.getRoot().on(ModalEvents.hidden, () => {\n modal.destroy();\n });\n\n return modal;\n })\n .then(modal => Promise.all([modal, modal.getBodyPromise()]))\n .then(([modal, body]) => {\n if (body.get(0).querySelector(Selectors.cohortSelector)) {\n return modal.setSaveButtonText(Str.get_string('enroluserscohorts', 'enrol_manual')).then(() => modal);\n }\n\n return modal;\n })\n .then(modal => {\n pendingPromise.resolve();\n\n return modal;\n })\n .catch(Notification.exception);\n};\n\n/**\n * Submit the form via ajax.\n *\n * @param {HTMLElement} dynamicTable\n * @param {Object} modal\n */\nconst submitFormAjax = (dynamicTable, modal) => {\n // Note: We use a jQuery object here so that we can use its serialize functionality.\n const form = modal.getRoot().find('form');\n\n // Before send the data through AJAX, we need to parse and remove some unwanted hidden fields.\n // This hidden fields are added automatically by mforms and when it reaches the AJAX we get an error.\n form.get(0).querySelectorAll(Selectors.unwantedHiddenFields).forEach(hiddenField => hiddenField.remove());\n\n modal.hide();\n modal.destroy();\n\n jQuery.ajax(\n `${Config.wwwroot}/enrol/manual/ajax.php?${form.serialize()}`,\n {\n type: 'GET',\n processData: false,\n contentType: \"application/json\",\n }\n )\n .then(response => {\n if (response.error) {\n throw new Error(response.error);\n }\n\n return response.count;\n })\n .then(count => {\n return Promise.all([\n Str.get_string('totalenrolledusers', 'enrol', count),\n DynamicTable.refreshTableContent(dynamicTable),\n ]);\n })\n .then(([notificationBody]) => notificationBody)\n .then(notificationBody => Toast.add(notificationBody))\n .catch(error => {\n Notification.addNotification({\n message: error.message,\n type: 'error',\n });\n });\n};\n\n/**\n * Set up quick enrolment for the manual enrolment plugin.\n *\n * @param {Number} contextid The context id to setup for\n */\nexport const init = ({contextid}) => {\n registerEventListeners(contextid);\n\n Prefetch.prefetchStrings('enrol_manual', [\n 'enrolusers',\n 'enroluserscohorts',\n ]);\n\n Prefetch.prefetchString('enrol', 'totalenrolledusers');\n};\n"],"names":["Selectors","getBodyForContext","contextId","Fragment","loadFragment","registerEventListeners","document","addEventListener","e","target","closest","preventDefault","showModal","element","wrapper","DynamicTable","getTableFromId","dataset","tableUniqueid","getDynamicTableForElement","dynamicTable","pendingPromise","Pending","ModalSaveCancel","create","large","title","Str","get_string","body","buttons","save","show","then","modal","getRoot","on","ModalEvents","find","submit","submitFormAjax","hidden","destroy","Promise","all","getBodyPromise","_ref","get","querySelector","setSaveButtonText","resolve","catch","Notification","exception","form","querySelectorAll","forEach","hiddenField","remove","hide","ajax","Config","wwwroot","serialize","type","processData","contentType","response","error","Error","count","refreshTableContent","_ref2","notificationBody","Toast","add","addNotification","message","_ref3","contextid","prefetchStrings","prefetchString"],"mappings":";;;;;;;ykBAkCMA,yBACc,iBADdA,yBAEc,wDAFdA,+BAGoB,mDAHpBA,wBAIa,0BASbC,kBAAoBC,WACfC,kBAASC,aAAa,eAAgB,mBAAoBF,UAAW,IAoB1EG,uBAAyBH,YAC3BI,SAASC,iBAAiB,SAASC,OAC3BA,EAAEC,OAAOC,QAAQV,iCACjBQ,EAAEG,sBAEFC,UAhBsBC,CAAAA,gBACxBC,QAAUD,QAAQH,QAAQV,gCAEzBe,aAAaC,eAAeF,QAAQG,QAAQC,gBAajCC,CAA0BX,EAAEC,QAASP,eAcrDU,UAAY,CAACQ,aAAclB,mBACvBmB,eAAiB,IAAIC,iBAAQ,gDAE5BC,2BAAgBC,OAAO,CAC1BC,OAAO,EACPC,MAAOC,IAAIC,WAAW,aAAc,gBACpCC,KAAM5B,kBAAkBC,WACxB4B,QAAS,CACLC,KAAMJ,IAAIC,WAAW,aAAc,iBAEvCI,MAAM,IAETC,MAAKC,QACFA,MAAMC,UAAUC,GAAGC,sBAAYN,MAAMvB,IAKjCA,EAAEG,iBACFuB,MAAMC,UAAUG,KAAK,QAAQC,YAGjCL,MAAMC,UAAUC,GAAG,SAAU,QAAQ5B,IACjCA,EAAEG,iBAEF6B,eAAepB,aAAcc,UAGjCA,MAAMC,UAAUC,GAAGC,sBAAYI,QAAQ,KACnCP,MAAMQ,aAGHR,SAEVD,MAAKC,OAASS,QAAQC,IAAI,CAACV,MAAOA,MAAMW,qBACxCZ,MAAKa,WAAEZ,MAAOL,kBACPA,KAAKkB,IAAI,GAAGC,cAAchD,0BACnBkC,MAAMe,kBAAkBtB,IAAIC,WAAW,oBAAqB,iBAAiBK,MAAK,IAAMC,QAG5FA,SAEVD,MAAKC,QACFb,eAAe6B,UAERhB,SAEViB,MAAMC,sBAAaC,YASlBb,eAAiB,CAACpB,aAAcc,eAE5BoB,KAAOpB,MAAMC,UAAUG,KAAK,QAIlCgB,KAAKP,IAAI,GAAGQ,iBAAiBvD,gCAAgCwD,SAAQC,aAAeA,YAAYC,WAEhGxB,MAAMyB,OACNzB,MAAMQ,0BAECkB,eACAC,gBAAOC,0CAAiCR,KAAKS,aAChD,CACIC,KAAM,MACNC,aAAa,EACbC,YAAa,qBAGpBjC,MAAKkC,cACEA,SAASC,YACH,IAAIC,MAAMF,SAASC,cAGtBD,SAASG,SAEnBrC,MAAKqC,OACK3B,QAAQC,IAAI,CACfjB,IAAIC,WAAW,qBAAsB,QAAS0C,OAC9CvD,aAAawD,oBAAoBnD,kBAGxCa,MAAKuC,YAAEC,+BAAsBA,oBAC7BxC,MAAKwC,kBAAoBC,MAAMC,IAAIF,oBACnCtB,OAAMiB,8BACUQ,gBAAgB,CACzBC,QAAST,MAAMS,QACfb,KAAM,4BAUEc,YAACC,UAACA,iBAClB1E,uBAAuB0E,6BAEdC,gBAAgB,eAAgB,CACrC,aACA,wCAGKC,eAAe,QAAS"} \ No newline at end of file diff --git a/enrol/manual/amd/src/quickenrolment.js b/enrol/manual/amd/src/quickenrolment.js index a9191129ab9..2150fa78d8d 100644 --- a/enrol/manual/amd/src/quickenrolment.js +++ b/enrol/manual/amd/src/quickenrolment.js @@ -26,11 +26,11 @@ import * as Toast from 'core/toast'; import Config from 'core/config'; import Fragment from 'core/fragment'; import ModalEvents from 'core/modal_events'; -import ModalFactory from 'core/modal_factory'; import Notification from 'core/notification'; import jQuery from 'jquery'; import Pending from 'core/pending'; import Prefetch from 'core/prefetch'; +import ModalSaveCancel from 'core/modal_save_cancel'; const Selectors = { cohortSelector: "#id_cohortlist", @@ -88,14 +88,14 @@ const registerEventListeners = contextId => { const showModal = (dynamicTable, contextId) => { const pendingPromise = new Pending('enrol_manual/quickenrolment:showModal'); - return ModalFactory.create({ - type: ModalFactory.types.SAVE_CANCEL, + return ModalSaveCancel.create({ large: true, title: Str.get_string('enrolusers', 'enrol_manual'), body: getBodyForContext(contextId), buttons: { save: Str.get_string('enrolusers', 'enrol_manual'), - } + }, + show: true, }) .then(modal => { modal.getRoot().on(ModalEvents.save, e => { @@ -117,8 +117,6 @@ const showModal = (dynamicTable, contextId) => { modal.destroy(); }); - modal.show(); - return modal; }) .then(modal => Promise.all([modal, modal.getBodyPromise()])) diff --git a/grade/report/grader/amd/build/feedback_modal.min.js b/grade/report/grader/amd/build/feedback_modal.min.js index b6cbf5d4c86..88a0823a1fc 100644 --- a/grade/report/grader/amd/build/feedback_modal.min.js +++ b/grade/report/grader/amd/build/feedback_modal.min.js @@ -1,10 +1,10 @@ -define("gradereport_grader/feedback_modal",["exports","core/modal_factory","core/notification","core/ajax","core/templates"],(function(_exports,_modal_factory,_notification,_ajax,_templates){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}} +define("gradereport_grader/feedback_modal",["exports","core/modal","core/notification","core/ajax","core/templates"],(function(_exports,_modal,_notification,_ajax,_templates){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}} /** * Javascript module for displaying feedback in a modal window * * @module gradereport_grader/feedback_modal * @copyright 2023 Kevin Percy * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_modal_factory=_interopRequireDefault(_modal_factory),_notification=_interopRequireDefault(_notification),_ajax=_interopRequireDefault(_ajax),_templates=_interopRequireDefault(_templates);const Selectors_showFeedback='[data-action="feedback"]',fetchFeedback=(courseid,userid,itemid)=>{const request={methodname:"core_grades_get_feedback",args:{courseid:courseid,userid:userid,itemid:itemid}};return _ajax.default.call([request])[0]},registerEventListeners=()=>{document.addEventListener("click",(e=>{const showFeedbackTrigger=e.target.closest(Selectors_showFeedback);if(showFeedbackTrigger){e.preventDefault();(async(courseid,userid,itemid)=>{let feedbackData;try{feedbackData=await fetchFeedback(courseid,userid,itemid)}catch(e){return Promise.reject(e)}return _modal_factory.default.create({removeOnClose:!0,large:!0,verticallyCentered:!0}).then((modal=>{const body=_templates.default.render("core_grades/feedback_modal",{feedbacktext:feedbackData.feedbacktext,user:{picture:feedbackData.picture,fullname:feedbackData.fullname,additionalfield:feedbackData.additionalfield}});return modal.setBody(body),modal.setTitle(feedbackData.title),modal.show(),modal}))})(showFeedbackTrigger.dataset.courseid,e.target.closest("tr").dataset.uid,e.target.closest("td").dataset.itemid).catch(_notification.default.exception)}}))};_exports.init=()=>{registerEventListeners()}})); + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_modal=_interopRequireDefault(_modal),_notification=_interopRequireDefault(_notification),_ajax=_interopRequireDefault(_ajax),_templates=_interopRequireDefault(_templates);const Selectors_showFeedback='[data-action="feedback"]',fetchFeedback=(courseid,userid,itemid)=>{const request={methodname:"core_grades_get_feedback",args:{courseid:courseid,userid:userid,itemid:itemid}};return _ajax.default.call([request])[0]},registerEventListeners=()=>{document.addEventListener("click",(e=>{const showFeedbackTrigger=e.target.closest(Selectors_showFeedback);if(showFeedbackTrigger){e.preventDefault();(async(courseid,userid,itemid)=>{let feedbackData;try{feedbackData=await fetchFeedback(courseid,userid,itemid)}catch(e){return Promise.reject(e)}return _modal.default.create({removeOnClose:!0,large:!0,verticallyCentered:!0}).then((modal=>{const body=_templates.default.render("core_grades/feedback_modal",{feedbacktext:feedbackData.feedbacktext,user:{picture:feedbackData.picture,fullname:feedbackData.fullname,additionalfield:feedbackData.additionalfield}});return modal.setBody(body),modal.setTitle(feedbackData.title),modal.show(),modal}))})(showFeedbackTrigger.dataset.courseid,e.target.closest("tr").dataset.uid,e.target.closest("td").dataset.itemid).catch(_notification.default.exception)}}))};_exports.init=()=>{registerEventListeners()}})); //# sourceMappingURL=feedback_modal.min.js.map \ No newline at end of file diff --git a/grade/report/grader/amd/build/feedback_modal.min.js.map b/grade/report/grader/amd/build/feedback_modal.min.js.map index 784169cd6b7..6e6d205c05a 100644 --- a/grade/report/grader/amd/build/feedback_modal.min.js.map +++ b/grade/report/grader/amd/build/feedback_modal.min.js.map @@ -1 +1 @@ -{"version":3,"file":"feedback_modal.min.js","sources":["../src/feedback_modal.js"],"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 * Javascript module for displaying feedback in a modal window\n *\n * @module gradereport_grader/feedback_modal\n * @copyright 2023 Kevin Percy \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport ModalFactory from 'core/modal_factory';\nimport Notification from 'core/notification';\nimport ajax from 'core/ajax';\nimport Templates from 'core/templates';\n\nconst Selectors = {\n showFeedback: '[data-action=\"feedback\"]'\n};\n\n/**\n * Create the modal to display the feedback.\n *\n * @param {int} courseid\n * @param {int} userid\n * @param {int} itemid\n * @returns {Promise}\n */\nconst getModal = async(courseid, userid, itemid) => {\n let feedbackData;\n\n try {\n feedbackData = await fetchFeedback(courseid, userid, itemid);\n } catch (e) {\n return Promise.reject(e);\n }\n\n return ModalFactory.create({\n removeOnClose: true,\n large: true,\n verticallyCentered: true,\n })\n .then(modal => {\n const body = Templates.render('core_grades/feedback_modal', {\n feedbacktext: feedbackData.feedbacktext,\n user: {\n picture: feedbackData.picture,\n fullname: feedbackData.fullname,\n additionalfield: feedbackData.additionalfield,\n },\n });\n\n modal.setBody(body);\n modal.setTitle(feedbackData.title);\n modal.show();\n\n return modal;\n });\n};\n\n/**\n * Fetch the feedback data.\n *\n * @param {int} courseid\n * @param {int} userid\n * @param {int} itemid\n * @returns {Promise}\n */\nconst fetchFeedback = (courseid, userid, itemid) => {\n const request = {\n methodname: 'core_grades_get_feedback',\n args: {\n courseid: courseid,\n userid: userid,\n itemid: itemid,\n },\n };\n return ajax.call([request])[0];\n};\n\n/**\n * Register event listeners for the View Feedback links.\n */\nconst registerEventListeners = () => {\n document.addEventListener('click', e => {\n const showFeedbackTrigger = e.target.closest(Selectors.showFeedback);\n if (showFeedbackTrigger) {\n e.preventDefault();\n\n const courseid = showFeedbackTrigger.dataset.courseid;\n const userid = e.target.closest('tr').dataset.uid;\n const itemid = e.target.closest('td').dataset.itemid;\n\n getModal(courseid, userid, itemid)\n .catch(Notification.exception);\n }\n });\n};\n\n/**\n * Initialize module\n */\nexport const init = () => {\n registerEventListeners();\n};\n"],"names":["Selectors","fetchFeedback","courseid","userid","itemid","request","methodname","args","ajax","call","registerEventListeners","document","addEventListener","e","showFeedbackTrigger","target","closest","preventDefault","async","feedbackData","Promise","reject","ModalFactory","create","removeOnClose","large","verticallyCentered","then","modal","body","Templates","render","feedbacktext","user","picture","fullname","additionalfield","setBody","setTitle","title","show","getModal","dataset","uid","catch","Notification","exception"],"mappings":";;;;;;;oRA2BMA,uBACY,2BAmDZC,cAAgB,CAACC,SAAUC,OAAQC,gBAC/BC,QAAU,CACZC,WAAY,2BACZC,KAAM,CACFL,SAAUA,SACVC,OAAQA,OACRC,OAAQA,gBAGTI,cAAKC,KAAK,CAACJ,UAAU,IAM1BK,uBAAyB,KAC3BC,SAASC,iBAAiB,SAASC,UACzBC,oBAAsBD,EAAEE,OAAOC,QAAQhB,2BACzCc,oBAAqB,CACrBD,EAAEI,iBA3DGC,OAAMhB,SAAUC,OAAQC,cACjCe,iBAGAA,mBAAqBlB,cAAcC,SAAUC,OAAQC,QACvD,MAAOS,UACEO,QAAQC,OAAOR,UAGnBS,uBAAaC,OAAO,CACvBC,eAAe,EACfC,OAAO,EACPC,oBAAoB,IAEvBC,MAAKC,cACIC,KAAOC,mBAAUC,OAAO,6BAA8B,CACxDC,aAAcb,aAAaa,aAC3BC,KAAM,CACFC,QAASf,aAAae,QACtBC,SAAUhB,aAAagB,SACvBC,gBAAiBjB,aAAaiB,0BAItCR,MAAMS,QAAQR,MACdD,MAAMU,SAASnB,aAAaoB,OAC5BX,MAAMY,OAECZ,UAqCHa,CAJiB3B,oBAAoB4B,QAAQxC,SAC9BW,EAAEE,OAAOC,QAAQ,MAAM0B,QAAQC,IAC/B9B,EAAEE,OAAOC,QAAQ,MAAM0B,QAAQtC,QAGzCwC,MAAMC,sBAAaC,8BAQhB,KAChBpC"} \ No newline at end of file +{"version":3,"file":"feedback_modal.min.js","sources":["../src/feedback_modal.js"],"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 * Javascript module for displaying feedback in a modal window\n *\n * @module gradereport_grader/feedback_modal\n * @copyright 2023 Kevin Percy \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Modal from 'core/modal';\nimport Notification from 'core/notification';\nimport ajax from 'core/ajax';\nimport Templates from 'core/templates';\n\nconst Selectors = {\n showFeedback: '[data-action=\"feedback\"]'\n};\n\n/**\n * Create the modal to display the feedback.\n *\n * @param {int} courseid\n * @param {int} userid\n * @param {int} itemid\n * @returns {Promise}\n */\nconst getModal = async(courseid, userid, itemid) => {\n let feedbackData;\n\n try {\n feedbackData = await fetchFeedback(courseid, userid, itemid);\n } catch (e) {\n return Promise.reject(e);\n }\n\n return Modal.create({\n removeOnClose: true,\n large: true,\n verticallyCentered: true,\n })\n .then(modal => {\n const body = Templates.render('core_grades/feedback_modal', {\n feedbacktext: feedbackData.feedbacktext,\n user: {\n picture: feedbackData.picture,\n fullname: feedbackData.fullname,\n additionalfield: feedbackData.additionalfield,\n },\n });\n\n modal.setBody(body);\n modal.setTitle(feedbackData.title);\n modal.show();\n\n return modal;\n });\n};\n\n/**\n * Fetch the feedback data.\n *\n * @param {int} courseid\n * @param {int} userid\n * @param {int} itemid\n * @returns {Promise}\n */\nconst fetchFeedback = (courseid, userid, itemid) => {\n const request = {\n methodname: 'core_grades_get_feedback',\n args: {\n courseid: courseid,\n userid: userid,\n itemid: itemid,\n },\n };\n return ajax.call([request])[0];\n};\n\n/**\n * Register event listeners for the View Feedback links.\n */\nconst registerEventListeners = () => {\n document.addEventListener('click', e => {\n const showFeedbackTrigger = e.target.closest(Selectors.showFeedback);\n if (showFeedbackTrigger) {\n e.preventDefault();\n\n const courseid = showFeedbackTrigger.dataset.courseid;\n const userid = e.target.closest('tr').dataset.uid;\n const itemid = e.target.closest('td').dataset.itemid;\n\n getModal(courseid, userid, itemid)\n .catch(Notification.exception);\n }\n });\n};\n\n/**\n * Initialize module\n */\nexport const init = () => {\n registerEventListeners();\n};\n"],"names":["Selectors","fetchFeedback","courseid","userid","itemid","request","methodname","args","ajax","call","registerEventListeners","document","addEventListener","e","showFeedbackTrigger","target","closest","preventDefault","async","feedbackData","Promise","reject","Modal","create","removeOnClose","large","verticallyCentered","then","modal","body","Templates","render","feedbacktext","user","picture","fullname","additionalfield","setBody","setTitle","title","show","getModal","dataset","uid","catch","Notification","exception"],"mappings":";;;;;;;oQA2BMA,uBACY,2BAmDZC,cAAgB,CAACC,SAAUC,OAAQC,gBAC/BC,QAAU,CACZC,WAAY,2BACZC,KAAM,CACFL,SAAUA,SACVC,OAAQA,OACRC,OAAQA,gBAGTI,cAAKC,KAAK,CAACJ,UAAU,IAM1BK,uBAAyB,KAC3BC,SAASC,iBAAiB,SAASC,UACzBC,oBAAsBD,EAAEE,OAAOC,QAAQhB,2BACzCc,oBAAqB,CACrBD,EAAEI,iBA3DGC,OAAMhB,SAAUC,OAAQC,cACjCe,iBAGAA,mBAAqBlB,cAAcC,SAAUC,OAAQC,QACvD,MAAOS,UACEO,QAAQC,OAAOR,UAGnBS,eAAMC,OAAO,CAChBC,eAAe,EACfC,OAAO,EACPC,oBAAoB,IAEvBC,MAAKC,cACIC,KAAOC,mBAAUC,OAAO,6BAA8B,CACxDC,aAAcb,aAAaa,aAC3BC,KAAM,CACFC,QAASf,aAAae,QACtBC,SAAUhB,aAAagB,SACvBC,gBAAiBjB,aAAaiB,0BAItCR,MAAMS,QAAQR,MACdD,MAAMU,SAASnB,aAAaoB,OAC5BX,MAAMY,OAECZ,UAqCHa,CAJiB3B,oBAAoB4B,QAAQxC,SAC9BW,EAAEE,OAAOC,QAAQ,MAAM0B,QAAQC,IAC/B9B,EAAEE,OAAOC,QAAQ,MAAM0B,QAAQtC,QAGzCwC,MAAMC,sBAAaC,8BAQhB,KAChBpC"} \ No newline at end of file diff --git a/grade/report/grader/amd/src/feedback_modal.js b/grade/report/grader/amd/src/feedback_modal.js index c81154c748a..9ab99ac5f44 100644 --- a/grade/report/grader/amd/src/feedback_modal.js +++ b/grade/report/grader/amd/src/feedback_modal.js @@ -20,7 +20,7 @@ * @copyright 2023 Kevin Percy * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -import ModalFactory from 'core/modal_factory'; +import Modal from 'core/modal'; import Notification from 'core/notification'; import ajax from 'core/ajax'; import Templates from 'core/templates'; @@ -46,7 +46,7 @@ const getModal = async(courseid, userid, itemid) => { return Promise.reject(e); } - return ModalFactory.create({ + return Modal.create({ removeOnClose: true, large: true, verticallyCentered: true, diff --git a/lib/amd/build/addblockmodal.min.js b/lib/amd/build/addblockmodal.min.js index 954f67ec3d1..522e73d7945 100644 --- a/lib/amd/build/addblockmodal.min.js +++ b/lib/amd/build/addblockmodal.min.js @@ -1,4 +1,4 @@ -define("core/addblockmodal",["exports","core/modal_factory","core/templates","core/str","core/ajax"],(function(_exports,_modal_factory,_templates,_str,_ajax){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}} +define("core/addblockmodal",["exports","./modal_cancel","core/templates","core/str","core/ajax"],(function(_exports,_modal_cancel,_templates,_str,_ajax){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}} /** * Show an add block modal instead of doing it on a separate page. * @@ -6,6 +6,6 @@ define("core/addblockmodal",["exports","core/modal_factory","core/templates","co * @deprecated since Moodle 4.2 - please use core_block/add_modal instead. * @copyright 2016 Damyon Wiese * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_modal_factory=_interopRequireDefault(_modal_factory),_templates=_interopRequireDefault(_templates),_ajax=_interopRequireDefault(_ajax);const SELECTORS_ADD_BLOCK='[data-key="addblock"]';let listenerEventsRegistered=!1;const registerListenerEvents=(pageType,pageLayout,addBlockUrl,subPage)=>{document.addEventListener("click",(e=>{const addBlock=e.target.closest(SELECTORS_ADD_BLOCK);if(addBlock){e.preventDefault();let addBlockModal=null,addBlockModalUrl=null!=addBlockUrl?addBlockUrl:addBlock.dataset.url;buildAddBlockModal().then((modal=>{addBlockModal=modal;const modalBody=renderBlocks(addBlockModalUrl,pageType,pageLayout,subPage);return modal.setBody(modalBody),modal.show(),modalBody})).catch((()=>{addBlockModal.destroy()}))}}))},buildAddBlockModal=()=>_modal_factory.default.create({type:_modal_factory.default.types.CANCEL,title:(0,_str.getString)("addblock")}),renderBlocks=async(addBlockUrl,pageType,pageLayout,subPage)=>{const blocks=await getAddableBlocks(pageType,pageLayout,subPage);return _templates.default.render("core/add_block_body",{blocks:blocks,url:addBlockUrl})},getAddableBlocks=async(pageType,pageLayout,subPage)=>{const request={methodname:"core_block_fetch_addable_blocks",args:{pagecontextid:M.cfg.contextid,pagetype:pageType,pagelayout:pageLayout,subpage:subPage}};return _ajax.default.call([request])[0]};_exports.init=function(pageType,pageLayout){let addBlockUrl=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,subPage=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"";listenerEventsRegistered||(registerListenerEvents(pageType,pageLayout,addBlockUrl,subPage),listenerEventsRegistered=!0)}})); + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_modal_cancel=_interopRequireDefault(_modal_cancel),_templates=_interopRequireDefault(_templates),_ajax=_interopRequireDefault(_ajax);const SELECTORS_ADD_BLOCK='[data-key="addblock"]';let listenerEventsRegistered=!1;const registerListenerEvents=(pageType,pageLayout,addBlockUrl,subPage)=>{document.addEventListener("click",(e=>{const addBlock=e.target.closest(SELECTORS_ADD_BLOCK);if(addBlock){e.preventDefault();let addBlockModal=null,addBlockModalUrl=null!=addBlockUrl?addBlockUrl:addBlock.dataset.url;buildAddBlockModal().then((modal=>{addBlockModal=modal;const modalBody=renderBlocks(addBlockModalUrl,pageType,pageLayout,subPage);return modal.setBody(modalBody),modal.show(),modalBody})).catch((()=>{addBlockModal.destroy()}))}}))},buildAddBlockModal=()=>_modal_cancel.default.create({title:(0,_str.getString)("addblock")}),renderBlocks=async(addBlockUrl,pageType,pageLayout,subPage)=>{const blocks=await getAddableBlocks(pageType,pageLayout,subPage);return _templates.default.render("core/add_block_body",{blocks:blocks,url:addBlockUrl})},getAddableBlocks=async(pageType,pageLayout,subPage)=>{const request={methodname:"core_block_fetch_addable_blocks",args:{pagecontextid:M.cfg.contextid,pagetype:pageType,pagelayout:pageLayout,subpage:subPage}};return _ajax.default.call([request])[0]};_exports.init=function(pageType,pageLayout){let addBlockUrl=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,subPage=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"";listenerEventsRegistered||(registerListenerEvents(pageType,pageLayout,addBlockUrl,subPage),listenerEventsRegistered=!0)}})); //# sourceMappingURL=addblockmodal.min.js.map \ No newline at end of file diff --git a/lib/amd/build/addblockmodal.min.js.map b/lib/amd/build/addblockmodal.min.js.map index 3516e7f28af..fa305db3064 100644 --- a/lib/amd/build/addblockmodal.min.js.map +++ b/lib/amd/build/addblockmodal.min.js.map @@ -1 +1 @@ -{"version":3,"file":"addblockmodal.min.js","sources":["../src/addblockmodal.js"],"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 * Show an add block modal instead of doing it on a separate page.\n *\n * @module core/addblockmodal\n * @deprecated since Moodle 4.2 - please use core_block/add_modal instead.\n * @copyright 2016 Damyon Wiese \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport ModalFactory from 'core/modal_factory';\nimport Templates from 'core/templates';\nimport {getString} from 'core/str';\nimport Ajax from 'core/ajax';\n\nconst SELECTORS = {\n ADD_BLOCK: '[data-key=\"addblock\"]'\n};\n\n// Ensure we only add our listeners once.\nlet listenerEventsRegistered = false;\n\n/**\n * Register related event listeners.\n *\n * @method registerListenerEvents\n * @param {String} pageType The type of the page\n * @param {String} pageLayout The layout of the page\n * @param {String|null} addBlockUrl The add block URL\n * @param {String} subPage The subpage identifier\n */\nconst registerListenerEvents = (pageType, pageLayout, addBlockUrl, subPage) => {\n document.addEventListener('click', e => {\n\n const addBlock = e.target.closest(SELECTORS.ADD_BLOCK);\n if (addBlock) {\n e.preventDefault();\n\n let addBlockModal = null;\n let addBlockModalUrl = addBlockUrl ?? addBlock.dataset.url;\n\n buildAddBlockModal()\n .then(modal => {\n addBlockModal = modal;\n const modalBody = renderBlocks(addBlockModalUrl, pageType, pageLayout, subPage);\n modal.setBody(modalBody);\n modal.show();\n\n return modalBody;\n })\n .catch(() => {\n addBlockModal.destroy();\n });\n }\n });\n};\n\n/**\n * Method that creates the 'add block' modal.\n *\n * @method buildAddBlockModal\n * @returns {Promise} The modal promise (modal's body will be rendered later).\n */\nconst buildAddBlockModal = () => {\n return ModalFactory.create({\n type: ModalFactory.types.CANCEL,\n title: getString('addblock')\n });\n};\n\n/**\n * Method that renders the list of available blocks.\n *\n * @method renderBlocks\n * @param {String} addBlockUrl The add block URL\n * @param {String} pageType The type of the page\n * @param {String} pageLayout The layout of the page\n * @param {String} subPage The subpage identifier\n * @return {Promise}\n */\nconst renderBlocks = async(addBlockUrl, pageType, pageLayout, subPage) => {\n // Fetch all addable blocks in the given page.\n const blocks = await getAddableBlocks(pageType, pageLayout, subPage);\n\n return Templates.render('core/add_block_body', {\n blocks: blocks,\n url: addBlockUrl\n });\n};\n\n/**\n * Method that fetches all addable blocks in a given page.\n *\n * @method getAddableBlocks\n * @param {String} pageType The type of the page\n * @param {String} pageLayout The layout of the page\n * @param {String} subPage The subpage identifier\n * @return {Promise}\n */\nconst getAddableBlocks = async(pageType, pageLayout, subPage) => {\n const request = {\n methodname: 'core_block_fetch_addable_blocks',\n args: {\n pagecontextid: M.cfg.contextid,\n pagetype: pageType,\n pagelayout: pageLayout,\n subpage: subPage,\n },\n };\n\n return Ajax.call([request])[0];\n};\n\n/**\n * Set up the actions.\n *\n * @method init\n * @param {String} pageType The type of the page\n * @param {String} pageLayout The layout of the page\n * @param {String|null} addBlockUrl The add block URL\n * @param {String} subPage The subpage identifier\n */\nexport const init = (pageType, pageLayout, addBlockUrl = null, subPage = '') => {\n if (!listenerEventsRegistered) {\n registerListenerEvents(pageType, pageLayout, addBlockUrl, subPage);\n listenerEventsRegistered = true;\n }\n};\n"],"names":["SELECTORS","listenerEventsRegistered","registerListenerEvents","pageType","pageLayout","addBlockUrl","subPage","document","addEventListener","e","addBlock","target","closest","preventDefault","addBlockModal","addBlockModalUrl","dataset","url","buildAddBlockModal","then","modal","modalBody","renderBlocks","setBody","show","catch","destroy","ModalFactory","create","type","types","CANCEL","title","async","blocks","getAddableBlocks","Templates","render","request","methodname","args","pagecontextid","M","cfg","contextid","pagetype","pagelayout","subpage","Ajax","call"],"mappings":";;;;;;;;gOA6BMA,oBACS,4BAIXC,0BAA2B,QAWzBC,uBAAyB,CAACC,SAAUC,WAAYC,YAAaC,WAC/DC,SAASC,iBAAiB,SAASC,UAEzBC,SAAWD,EAAEE,OAAOC,QAAQZ,wBAC9BU,SAAU,CACVD,EAAEI,qBAEEC,cAAgB,KAChBC,iBAAmBV,MAAAA,YAAAA,YAAeK,SAASM,QAAQC,IAEvDC,qBACKC,MAAKC,QACFN,cAAgBM,YACVC,UAAYC,aAAaP,iBAAkBZ,SAAUC,WAAYE,gBACvEc,MAAMG,QAAQF,WACdD,MAAMI,OAECH,aAEVI,OAAM,KACHX,cAAcY,kBAY5BR,mBAAqB,IAChBS,uBAAaC,OAAO,CACvBC,KAAMF,uBAAaG,MAAMC,OACzBC,OAAO,kBAAU,cAcnBV,aAAeW,MAAM5B,YAAaF,SAAUC,WAAYE,iBAEpD4B,aAAeC,iBAAiBhC,SAAUC,WAAYE,gBAErD8B,mBAAUC,OAAO,sBAAuB,CAC3CH,OAAQA,OACRjB,IAAKZ,eAaP8B,iBAAmBF,MAAM9B,SAAUC,WAAYE,iBAC3CgC,QAAU,CACZC,WAAY,kCACZC,KAAM,CACFC,cAAeC,EAAEC,IAAIC,UACrBC,SAAU1C,SACV2C,WAAY1C,WACZ2C,QAASzC,iBAIV0C,cAAKC,KAAK,CAACX,UAAU,kBAYZ,SAACnC,SAAUC,gBAAYC,mEAAc,KAAMC,+DAAU,GAChEL,2BACDC,uBAAuBC,SAAUC,WAAYC,YAAaC,SAC1DL,0BAA2B"} \ No newline at end of file +{"version":3,"file":"addblockmodal.min.js","sources":["../src/addblockmodal.js"],"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 * Show an add block modal instead of doing it on a separate page.\n *\n * @module core/addblockmodal\n * @deprecated since Moodle 4.2 - please use core_block/add_modal instead.\n * @copyright 2016 Damyon Wiese \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport CancelModal from './modal_cancel';\nimport Templates from 'core/templates';\nimport {getString} from 'core/str';\nimport Ajax from 'core/ajax';\n\nconst SELECTORS = {\n ADD_BLOCK: '[data-key=\"addblock\"]'\n};\n\n// Ensure we only add our listeners once.\nlet listenerEventsRegistered = false;\n\n/**\n * Register related event listeners.\n *\n * @method registerListenerEvents\n * @param {String} pageType The type of the page\n * @param {String} pageLayout The layout of the page\n * @param {String|null} addBlockUrl The add block URL\n * @param {String} subPage The subpage identifier\n */\nconst registerListenerEvents = (pageType, pageLayout, addBlockUrl, subPage) => {\n document.addEventListener('click', e => {\n\n const addBlock = e.target.closest(SELECTORS.ADD_BLOCK);\n if (addBlock) {\n e.preventDefault();\n\n let addBlockModal = null;\n let addBlockModalUrl = addBlockUrl ?? addBlock.dataset.url;\n\n buildAddBlockModal()\n .then(modal => {\n addBlockModal = modal;\n const modalBody = renderBlocks(addBlockModalUrl, pageType, pageLayout, subPage);\n modal.setBody(modalBody);\n modal.show();\n\n return modalBody;\n })\n .catch(() => {\n addBlockModal.destroy();\n });\n }\n });\n};\n\n/**\n * Method that creates the 'add block' modal.\n *\n * @method buildAddBlockModal\n * @returns {Promise} The modal promise (modal's body will be rendered later).\n */\nconst buildAddBlockModal = () => {\n return CancelModal.create({\n title: getString('addblock')\n });\n};\n\n/**\n * Method that renders the list of available blocks.\n *\n * @method renderBlocks\n * @param {String} addBlockUrl The add block URL\n * @param {String} pageType The type of the page\n * @param {String} pageLayout The layout of the page\n * @param {String} subPage The subpage identifier\n * @return {Promise}\n */\nconst renderBlocks = async(addBlockUrl, pageType, pageLayout, subPage) => {\n // Fetch all addable blocks in the given page.\n const blocks = await getAddableBlocks(pageType, pageLayout, subPage);\n\n return Templates.render('core/add_block_body', {\n blocks: blocks,\n url: addBlockUrl\n });\n};\n\n/**\n * Method that fetches all addable blocks in a given page.\n *\n * @method getAddableBlocks\n * @param {String} pageType The type of the page\n * @param {String} pageLayout The layout of the page\n * @param {String} subPage The subpage identifier\n * @return {Promise}\n */\nconst getAddableBlocks = async(pageType, pageLayout, subPage) => {\n const request = {\n methodname: 'core_block_fetch_addable_blocks',\n args: {\n pagecontextid: M.cfg.contextid,\n pagetype: pageType,\n pagelayout: pageLayout,\n subpage: subPage,\n },\n };\n\n return Ajax.call([request])[0];\n};\n\n/**\n * Set up the actions.\n *\n * @method init\n * @param {String} pageType The type of the page\n * @param {String} pageLayout The layout of the page\n * @param {String|null} addBlockUrl The add block URL\n * @param {String} subPage The subpage identifier\n */\nexport const init = (pageType, pageLayout, addBlockUrl = null, subPage = '') => {\n if (!listenerEventsRegistered) {\n registerListenerEvents(pageType, pageLayout, addBlockUrl, subPage);\n listenerEventsRegistered = true;\n }\n};\n"],"names":["SELECTORS","listenerEventsRegistered","registerListenerEvents","pageType","pageLayout","addBlockUrl","subPage","document","addEventListener","e","addBlock","target","closest","preventDefault","addBlockModal","addBlockModalUrl","dataset","url","buildAddBlockModal","then","modal","modalBody","renderBlocks","setBody","show","catch","destroy","CancelModal","create","title","async","blocks","getAddableBlocks","Templates","render","request","methodname","args","pagecontextid","M","cfg","contextid","pagetype","pagelayout","subpage","Ajax","call"],"mappings":";;;;;;;;8NA6BMA,oBACS,4BAIXC,0BAA2B,QAWzBC,uBAAyB,CAACC,SAAUC,WAAYC,YAAaC,WAC/DC,SAASC,iBAAiB,SAASC,UAEzBC,SAAWD,EAAEE,OAAOC,QAAQZ,wBAC9BU,SAAU,CACVD,EAAEI,qBAEEC,cAAgB,KAChBC,iBAAmBV,MAAAA,YAAAA,YAAeK,SAASM,QAAQC,IAEvDC,qBACKC,MAAKC,QACFN,cAAgBM,YACVC,UAAYC,aAAaP,iBAAkBZ,SAAUC,WAAYE,gBACvEc,MAAMG,QAAQF,WACdD,MAAMI,OAECH,aAEVI,OAAM,KACHX,cAAcY,kBAY5BR,mBAAqB,IAChBS,sBAAYC,OAAO,CACtBC,OAAO,kBAAU,cAcnBP,aAAeQ,MAAMzB,YAAaF,SAAUC,WAAYE,iBAEpDyB,aAAeC,iBAAiB7B,SAAUC,WAAYE,gBAErD2B,mBAAUC,OAAO,sBAAuB,CAC3CH,OAAQA,OACRd,IAAKZ,eAaP2B,iBAAmBF,MAAM3B,SAAUC,WAAYE,iBAC3C6B,QAAU,CACZC,WAAY,kCACZC,KAAM,CACFC,cAAeC,EAAEC,IAAIC,UACrBC,SAAUvC,SACVwC,WAAYvC,WACZwC,QAAStC,iBAIVuC,cAAKC,KAAK,CAACX,UAAU,kBAYZ,SAAChC,SAAUC,gBAAYC,mEAAc,KAAMC,+DAAU,GAChEL,2BACDC,uBAAuBC,SAAUC,WAAYC,YAAaC,SAC1DL,0BAA2B"} \ No newline at end of file diff --git a/lib/amd/build/modal_copy_to_clipboard.min.js b/lib/amd/build/modal_copy_to_clipboard.min.js index 509826926bd..d9e5bf7ecfd 100644 --- a/lib/amd/build/modal_copy_to_clipboard.min.js +++ b/lib/amd/build/modal_copy_to_clipboard.min.js @@ -1,3 +1,3 @@ -define("core/modal_copy_to_clipboard",["exports","core/modal","core/modal_factory","core/copy_to_clipboard"],(function(_exports,_modal,_modal_factory,_copy_to_clipboard){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _defineProperty(obj,key,value){return key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_modal=_interopRequireDefault(_modal),_modal_factory=_interopRequireDefault(_modal_factory);class CopyToClipboardModal extends _modal.default{constructor(){super(...arguments),this.setRemoveOnClose(!0)}registerEventListeners(){super.registerEventListeners(...arguments),this.getRoot().get(0).addEventListener("click",(e=>{e.target.closest('[data-action="copytoclipboard"]')&&this.getRoot().get(0).contains(e.target)&&setTimeout(this.destroy.bind(this))}))}static async create(){let{text:text,useTextArea:useTextArea=!1}=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},title=arguments.length>1?arguments[1]:void 0;this.registerModalType();const modal=await _modal_factory.default.create({type:this.TYPE,templateContext:{text:text,useTextArea:useTextArea}});title&&modal.setTitle(title),modal.show()}}return _exports.default=CopyToClipboardModal,_defineProperty(CopyToClipboardModal,"TYPE","core/copytoclipboard"),_defineProperty(CopyToClipboardModal,"TEMPLATE","core/modal_copytoclipboard"),_exports.default})); +define("core/modal_copy_to_clipboard",["exports","core/modal","core/copy_to_clipboard"],(function(_exports,_modal,_copy_to_clipboard){var obj;function _defineProperty(obj,key,value){return key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_modal=(obj=_modal)&&obj.__esModule?obj:{default:obj};class CopyToClipboardModal extends _modal.default{constructor(){super(...arguments),this.setRemoveOnClose(!0)}registerEventListeners(){super.registerEventListeners(...arguments),this.getRoot().get(0).addEventListener("click",(e=>{e.target.closest('[data-action="copytoclipboard"]')&&this.getRoot().get(0).contains(e.target)&&setTimeout(this.destroy.bind(this))}))}static async create(){let{text:text,useTextArea:useTextArea=!1}=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},title=arguments.length>1?arguments[1]:void 0;const modalConfig={templateContext:{text:text,useTextArea:useTextArea}};return title&&(modalConfig.title=title),super.create(modalConfig)}configure(modalConfig){modalConfig.show=!0,modalConfig.removeOnClose=!0,super.configure(modalConfig)}}return _exports.default=CopyToClipboardModal,_defineProperty(CopyToClipboardModal,"TYPE","core/copytoclipboard"),_defineProperty(CopyToClipboardModal,"TEMPLATE","core/modal_copytoclipboard"),CopyToClipboardModal.registerModalType(),_exports.default})); //# sourceMappingURL=modal_copy_to_clipboard.min.js.map \ No newline at end of file diff --git a/lib/amd/build/modal_copy_to_clipboard.min.js.map b/lib/amd/build/modal_copy_to_clipboard.min.js.map index 1bc2627567a..496175e4e49 100644 --- a/lib/amd/build/modal_copy_to_clipboard.min.js.map +++ b/lib/amd/build/modal_copy_to_clipboard.min.js.map @@ -1 +1 @@ -{"version":3,"file":"modal_copy_to_clipboard.min.js","sources":["../src/modal_copy_to_clipboard.js"],"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 * Contain the logic for the copy to clipboard modal, i.e. the modal contains a\n * readonly input text field, that contains a value. Clicking on the single\n * button \"Copy to clipboard\" in the footer, puts the content of the input\n * text field into the clipboard and closes the modal.\n *\n * Usage:\n * ModalCopyToClipboard.create(string:, string:|null);\n *\n * @module core/modal_copy_to_clipboard\n * @copyright 2023 Stephan Robotta \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Modal from 'core/modal';\nimport ModalFactory from 'core/modal_factory';\nimport 'core/copy_to_clipboard';\n\nexport default class CopyToClipboardModal extends Modal {\n static TYPE = 'core/copytoclipboard';\n static TEMPLATE = 'core/modal_copytoclipboard';\n\n constructor(...config) {\n // Override the constructor to set the removeOnClose property, and show the modal.\n super(...config);\n this.setRemoveOnClose(true);\n }\n\n /**\n * Set up all the event handling for the modal.\n * This is an override of the parent method, adding an event listener to close upon the action.\n *\n * @param {array} args\n */\n registerEventListeners(...args) {\n super.registerEventListeners(...args);\n\n this.getRoot().get(0).addEventListener('click', (e) => {\n if (!e.target.closest('[data-action=\"copytoclipboard\"]')) {\n return;\n }\n\n if (!this.getRoot().get(0).contains(e.target)) {\n return;\n }\n\n // Note: We must call destroy() here, because the copy-to-clipboard action listens on the document,\n // which will be processed after this event listener has been processed.\n // By placing this in a setTimeout we move its processing to after the event loop has finished.\n setTimeout(this.destroy.bind(this));\n });\n }\n\n /**\n * Create a new instance of the Modal. Set the text that is being copied. By default, the text is put into the\n * value of an input readonly field. If useTextArea is set to true, the text is rendered in a textarea element.\n * The optional title argument is for the modal title. If not set, the generic string \"copy to clipboard\" is used.\n *\n * @param {Object} data used in the template\n * @param {string} data.text the text to copy to the clipboard\n * @param {boolean} data.useTextArea when the text to copy is displayed in a textarea, default is input\n * @param {string|null} title\n * @returns {Promise}\n */\n static async create(\n {\n text,\n useTextArea = false,\n } = {},\n title\n ) {\n this.registerModalType();\n\n const modal = await ModalFactory.create({\n type: this.TYPE,\n templateContext: {\n text: text,\n useTextArea: useTextArea,\n },\n });\n if (title) {\n modal.setTitle(title);\n }\n modal.show();\n }\n}\n"],"names":["CopyToClipboardModal","Modal","constructor","setRemoveOnClose","registerEventListeners","getRoot","get","addEventListener","e","target","closest","this","contains","setTimeout","destroy","bind","text","useTextArea","title","registerModalType","modal","ModalFactory","create","type","TYPE","templateContext","setTitle","show"],"mappings":"klBAiCqBA,6BAA6BC,eAI9CC,uCAGSC,kBAAiB,GAS1BC,+BACUA,0CAEDC,UAAUC,IAAI,GAAGC,iBAAiB,SAAUC,IACxCA,EAAEC,OAAOC,QAAQ,oCAIjBC,KAAKN,UAAUC,IAAI,GAAGM,SAASJ,EAAEC,SAOtCI,WAAWF,KAAKG,QAAQC,KAAKJ,oCAgBjCK,KACIA,KADJC,YAEIA,aAAc,0DACd,GACJC,kDAEKC,0BAECC,YAAcC,uBAAaC,OAAO,CACpCC,KAAMZ,KAAKa,KACXC,gBAAiB,CACbT,KAAMA,KACNC,YAAaA,eAGjBC,OACAE,MAAMM,SAASR,OAEnBE,MAAMO,qEAjEO3B,4BACH,wCADGA,gCAEC"} \ No newline at end of file +{"version":3,"file":"modal_copy_to_clipboard.min.js","sources":["../src/modal_copy_to_clipboard.js"],"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 * Contain the logic for the copy to clipboard modal, i.e. the modal contains a\n * readonly input text field, that contains a value. Clicking on the single\n * button \"Copy to clipboard\" in the footer, puts the content of the input\n * text field into the clipboard and closes the modal.\n *\n * Usage:\n * ModalCopyToClipboard.create(string:, string:|null);\n *\n * @module core/modal_copy_to_clipboard\n * @copyright 2023 Stephan Robotta \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Modal from 'core/modal';\nimport 'core/copy_to_clipboard';\n\nexport default class CopyToClipboardModal extends Modal {\n static TYPE = 'core/copytoclipboard';\n static TEMPLATE = 'core/modal_copytoclipboard';\n\n constructor(...config) {\n // Override the constructor to set the removeOnClose property, and show the modal.\n super(...config);\n this.setRemoveOnClose(true);\n }\n\n /**\n * Set up all the event handling for the modal.\n * This is an override of the parent method, adding an event listener to close upon the action.\n *\n * @param {array} args\n */\n registerEventListeners(...args) {\n super.registerEventListeners(...args);\n\n this.getRoot().get(0).addEventListener('click', (e) => {\n if (!e.target.closest('[data-action=\"copytoclipboard\"]')) {\n return;\n }\n\n if (!this.getRoot().get(0).contains(e.target)) {\n return;\n }\n\n // Note: We must call destroy() here, because the copy-to-clipboard action listens on the document,\n // which will be processed after this event listener has been processed.\n // By placing this in a setTimeout we move its processing to after the event loop has finished.\n setTimeout(this.destroy.bind(this));\n });\n }\n\n /**\n * Create a new instance of the Modal. Set the text that is being copied. By default, the text is put into the\n * value of an input readonly field. If useTextArea is set to true, the text is rendered in a textarea element.\n * The optional title argument is for the modal title. If not set, the generic string \"copy to clipboard\" is used.\n *\n * @param {Object} data used in the template\n * @param {string} data.text the text to copy to the clipboard\n * @param {boolean} data.useTextArea when the text to copy is displayed in a textarea, default is input\n * @param {string|null} title\n * @returns {Promise}\n */\n static async create(\n {\n text,\n useTextArea = false,\n } = {},\n title,\n ) {\n const modalConfig = {\n templateContext: {\n text,\n useTextArea,\n },\n };\n if (title) {\n modalConfig.title = title;\n }\n\n return super.create(modalConfig);\n }\n\n configure(modalConfig) {\n modalConfig.show = true;\n modalConfig.removeOnClose = true;\n\n super.configure(modalConfig);\n }\n}\n\nCopyToClipboardModal.registerModalType();\n"],"names":["CopyToClipboardModal","Modal","constructor","setRemoveOnClose","registerEventListeners","getRoot","get","addEventListener","e","target","closest","this","contains","setTimeout","destroy","bind","text","useTextArea","title","modalConfig","templateContext","super","create","configure","show","removeOnClose","registerModalType"],"mappings":"8bAgCqBA,6BAA6BC,eAI9CC,uCAGSC,kBAAiB,GAS1BC,+BACUA,0CAEDC,UAAUC,IAAI,GAAGC,iBAAiB,SAAUC,IACxCA,EAAEC,OAAOC,QAAQ,oCAIjBC,KAAKN,UAAUC,IAAI,GAAGM,SAASJ,EAAEC,SAOtCI,WAAWF,KAAKG,QAAQC,KAAKJ,oCAgBjCK,KACIA,KADJC,YAEIA,aAAc,0DACd,GACJC,mDAEMC,YAAc,CAChBC,gBAAiB,CACbJ,KAAAA,KACAC,YAAAA,qBAGJC,QACAC,YAAYD,MAAQA,OAGjBG,MAAMC,OAAOH,aAGxBI,UAAUJ,aACNA,YAAYK,MAAO,EACnBL,YAAYM,eAAgB,QAEtBF,UAAUJ,2EAtEHnB,4BACH,wCADGA,gCAEC,8BAwEtBA,qBAAqB0B"} \ No newline at end of file diff --git a/lib/amd/build/moodlenet/send_activity_modal.min.js b/lib/amd/build/moodlenet/send_activity_modal.min.js index 9a20ed8706a..148c808b957 100644 --- a/lib/amd/build/moodlenet/send_activity_modal.min.js +++ b/lib/amd/build/moodlenet/send_activity_modal.min.js @@ -1,3 +1,3 @@ -define("core/moodlenet/send_activity_modal",["exports","core/modal"],(function(_exports,_modal){var obj;function _defineProperty(obj,key,value){return key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_modal=(obj=_modal)&&obj.__esModule?obj:{default:obj};class SendActivityModal extends _modal.default{registerEventListeners(){super.registerEventListeners(),this.registerCloseOnSave(),this.registerCloseOnCancel()}}return _exports.default=SendActivityModal,_defineProperty(SendActivityModal,"TYPE","core/moodlenet/send_activity_modal"),_defineProperty(SendActivityModal,"TEMPLATE","core/moodlenet/send_activity_modal_base"),SendActivityModal.registerModalType(),_exports.default})); +define("core/moodlenet/send_activity_modal",["exports","core/modal"],(function(_exports,_modal){var obj;function _defineProperty(obj,key,value){return key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_modal=(obj=_modal)&&obj.__esModule?obj:{default:obj};class SendActivityModal extends _modal.default{registerEventListeners(){super.registerEventListeners(),this.registerCloseOnSave(),this.registerCloseOnCancel()}configure(modalConfig){modalConfig.show=!0,modalConfig.large=!0,super.configure(modalConfig)}}return _exports.default=SendActivityModal,_defineProperty(SendActivityModal,"TYPE","core/moodlenet/send_activity_modal"),_defineProperty(SendActivityModal,"TEMPLATE","core/moodlenet/send_activity_modal_base"),SendActivityModal.registerModalType(),_exports.default})); //# sourceMappingURL=send_activity_modal.min.js.map \ No newline at end of file diff --git a/lib/amd/build/moodlenet/send_activity_modal.min.js.map b/lib/amd/build/moodlenet/send_activity_modal.min.js.map index ded0340ee51..64856deb172 100644 --- a/lib/amd/build/moodlenet/send_activity_modal.min.js.map +++ b/lib/amd/build/moodlenet/send_activity_modal.min.js.map @@ -1 +1 @@ -{"version":3,"file":"send_activity_modal.min.js","sources":["../../src/moodlenet/send_activity_modal.js"],"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 * Send activity modal for MoodleNet.\n *\n * @module core/moodlenet/send_activity_modal\n * @copyright 2023 Huong Nguyen \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 4.2\n */\n\nimport Modal from 'core/modal';\n\nexport default class SendActivityModal extends Modal {\n static TYPE = 'core/moodlenet/send_activity_modal';\n static TEMPLATE = 'core/moodlenet/send_activity_modal_base';\n\n registerEventListeners() {\n // Call the parent registration.\n super.registerEventListeners();\n\n // Register to close on save/cancel.\n this.registerCloseOnSave();\n this.registerCloseOnCancel();\n }\n}\n\nSendActivityModal.registerModalType();\n"],"names":["SendActivityModal","Modal","registerEventListeners","registerCloseOnSave","registerCloseOnCancel","registerModalType"],"mappings":"wZA0BqBA,0BAA0BC,eAI3CC,+BAEUA,8BAGDC,2BACAC,mFAVQJ,yBACH,sDADGA,6BAEC,2CAYtBA,kBAAkBK"} \ No newline at end of file +{"version":3,"file":"send_activity_modal.min.js","sources":["../../src/moodlenet/send_activity_modal.js"],"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 * Send activity modal for MoodleNet.\n *\n * @module core/moodlenet/send_activity_modal\n * @copyright 2023 Huong Nguyen \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 4.2\n */\n\nimport Modal from 'core/modal';\n\nexport default class SendActivityModal extends Modal {\n static TYPE = 'core/moodlenet/send_activity_modal';\n static TEMPLATE = 'core/moodlenet/send_activity_modal_base';\n\n registerEventListeners() {\n // Call the parent registration.\n super.registerEventListeners();\n\n // Register to close on save/cancel.\n this.registerCloseOnSave();\n this.registerCloseOnCancel();\n }\n\n configure(modalConfig) {\n modalConfig.show = true;\n modalConfig.large = true;\n super.configure(modalConfig);\n }\n}\n\nSendActivityModal.registerModalType();\n"],"names":["SendActivityModal","Modal","registerEventListeners","registerCloseOnSave","registerCloseOnCancel","configure","modalConfig","show","large","registerModalType"],"mappings":"wZA0BqBA,0BAA0BC,eAI3CC,+BAEUA,8BAGDC,2BACAC,wBAGTC,UAAUC,aACNA,YAAYC,MAAO,EACnBD,YAAYE,OAAQ,QACdH,UAAUC,wEAhBHN,yBACH,sDADGA,6BAEC,2CAkBtBA,kBAAkBS"} \ No newline at end of file diff --git a/lib/amd/build/moodlenet/send_resource.min.js b/lib/amd/build/moodlenet/send_resource.min.js index 6b3438b724a..964d3e75d94 100644 --- a/lib/amd/build/moodlenet/send_resource.min.js +++ b/lib/amd/build/moodlenet/send_resource.min.js @@ -1,4 +1,4 @@ -define("core/moodlenet/send_resource",["exports","core/config","core/modal_factory","core/notification","core/str","core/prefetch","core/templates","core/moodlenet/service","core/moodlenet/send_activity_modal"],(function(_exports,_config,_modal_factory,_notification,_str,_prefetch,Templates,MoodleNetService,_send_activity_modal){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireWildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}return newObj.default=obj,cache&&cache.set(obj,newObj),newObj}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}} +define("core/moodlenet/send_resource",["exports","core/config","core/notification","core/str","core/prefetch","core/templates","core/moodlenet/service","core/moodlenet/send_activity_modal"],(function(_exports,_config,_notification,_str,_prefetch,Templates,MoodleNetService,_send_activity_modal){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireWildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}return newObj.default=obj,cache&&cache.set(obj,newObj),newObj}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}} /** * A module to handle Share operations of the MoodleNet. * @@ -6,6 +6,6 @@ define("core/moodlenet/send_resource",["exports","core/config","core/modal_facto * @copyright 2023 Huong Nguyen * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @since 4.2 - */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_config=_interopRequireDefault(_config),_modal_factory=_interopRequireDefault(_modal_factory),_prefetch=_interopRequireDefault(_prefetch),Templates=_interopRequireWildcard(Templates),MoodleNetService=_interopRequireWildcard(MoodleNetService),_send_activity_modal=_interopRequireDefault(_send_activity_modal);let currentModal,siteSupportUrl,issuerId,courseId,resourceId,shareFormat,type,listenersRegistered=!1;const responseFromMoodleNet=function(status){let resourceUrl=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";const $modal=currentModal.getModal(),modal=$modal[0];modal.querySelector(".modal-header").classList.add("no-border"),currentModal.setBody(Templates.render("core/moodlenet/send_activity_modal_done",{success:status,sitesupporturl:siteSupportUrl})),status&&(currentModal.setFooter(Templates.render("core/moodlenet/send_activity_modal_footer_view",{resourseurl:resourceUrl})),currentModal.showFooter())},handleAuthorization=issuerId=>MoodleNetService.authorizationCheck(issuerId,courseId).then((async data=>data.status?((issuerId,resourceId,shareFormat)=>{const modal=currentModal.getModal()[0];let infoPromise;modal.querySelector(".modal-header").classList.remove("no-border"),modal.querySelector(".modal-header").classList.add("no-header-text"),currentModal.setBody(Templates.render("core/moodlenet/send_activity_modal_packaging",{})),currentModal.hideFooter(),"activity"===type?infoPromise=MoodleNetService.sendActivity(issuerId,resourceId,shareFormat):"course"===type&&(infoPromise=MoodleNetService.sendCourse(issuerId,resourceId,shareFormat)),infoPromise.then((async data=>{const status=data.status,resourceUrl=data.resourceurl;return responseFromMoodleNet(status,resourceUrl)})).catch(_notification.exception)})(issuerId,resourceId,shareFormat):(window.moodleNetAuthorize=(error,errorDescription)=>{""===error?handleAuthorization(issuerId):"access_denied"!==error&&(0,_notification.alert)("Authorization error","Error: "+error+"

Error description: "+errorDescription,"Cancel")},window.open(data.loginurl,"moodlenet_auth","location=0,status=0,width=".concat(550,",height=").concat(550,",scrollbars=yes"))))).catch(_notification.exception),registerEventListeners=()=>{document.addEventListener("click",(e=>{const shareAction=e.target.closest('[data-action="sendtomoodlenet"]'),sendAction=e.target.closest('.moodlenet-action-buttons [data-action="share"]');if(shareAction){e.preventDefault(),type=shareAction.getAttribute("data-type");const shareType=shareAction.getAttribute("data-sharetype"),resourceId=_config.default.contextInstanceId;let infoPromise;"activity"===type?infoPromise=MoodleNetService.getActivityInformation(resourceId):"course"===type&&(infoPromise=MoodleNetService.getCourseInformation(resourceId)),infoPromise.then((async data=>{(async(data,shareType)=>{if(data.status)return siteSupportUrl=data.supportpageurl,issuerId=data.issuerid,_modal_factory.default.create({type:_send_activity_modal.default.TYPE,large:!0,templateContext:{activitytype:data.type,activityname:data.name,sharetype:await(0,_str.getString)("moodlenet:sharetype"+shareType,"moodle"),server:data.server}}).then((modal=>(currentModal=modal,modal.show(),modal))).catch(_notification.exception);return(0,_notification.addNotification)({message:data.warnings[0].message,type:"error"})})(data,shareType).catch(_notification.exception)})).catch(_notification.exception)}sendAction&&(e.preventDefault(),courseId=_config.default.courseId,resourceId=_config.default.contextInstanceId,shareFormat=0,handleAuthorization(issuerId))}))};_exports.init=()=>{listenersRegistered||(_prefetch.default.prefetchTemplates(["core/moodlenet/send_activity_modal_base","core/moodlenet/send_activity_modal_packaging","core/moodlenet/send_activity_modal_done","core/moodlenet/send_activity_modal_footer_view"]),registerEventListeners(),listenersRegistered=!0)}})); + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_config=_interopRequireDefault(_config),_prefetch=_interopRequireDefault(_prefetch),Templates=_interopRequireWildcard(Templates),MoodleNetService=_interopRequireWildcard(MoodleNetService),_send_activity_modal=_interopRequireDefault(_send_activity_modal);let siteSupportUrl,issuerId,courseId,resourceId,shareFormat,type,listenersRegistered=!1;const responseFromMoodleNet=function(status){let resourceUrl=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";const $modal=undefined.getModal(),modal=$modal[0];modal.querySelector(".modal-header").classList.add("no-border"),undefined.setBody(Templates.render("core/moodlenet/send_activity_modal_done",{success:status,sitesupporturl:siteSupportUrl})),status&&(undefined.setFooter(Templates.render("core/moodlenet/send_activity_modal_footer_view",{resourseurl:resourceUrl})),undefined.showFooter())},handleAuthorization=issuerId=>MoodleNetService.authorizationCheck(issuerId,courseId).then((data=>data.status?((issuerId,resourceId,shareFormat)=>{const modal=(void 0).getModal()[0];let infoPromise;modal.querySelector(".modal-header").classList.remove("no-border"),modal.querySelector(".modal-header").classList.add("no-header-text"),(void 0).setBody(Templates.render("core/moodlenet/send_activity_modal_packaging",{})),(void 0).hideFooter(),"activity"===type?infoPromise=MoodleNetService.sendActivity(issuerId,resourceId,shareFormat):"course"===type&&(infoPromise=MoodleNetService.sendCourse(issuerId,resourceId,shareFormat)),infoPromise.then((async data=>{const status=data.status,resourceUrl=data.resourceurl;return responseFromMoodleNet(status,resourceUrl)})).catch(_notification.exception)})(issuerId,resourceId,shareFormat):(window.moodleNetAuthorize=(error,errorDescription)=>{""===error?handleAuthorization(issuerId):"access_denied"!==error&&(0,_notification.alert)("Authorization error","Error: "+error+"

Error description: "+errorDescription,"Cancel")},window.open(data.loginurl,"moodlenet_auth","location=0,status=0,width=".concat(550,",height=").concat(550,",scrollbars=yes"))))).catch(_notification.exception),registerEventListeners=()=>{document.addEventListener("click",(e=>{const shareAction=e.target.closest('[data-action="sendtomoodlenet"]'),sendAction=e.target.closest('.moodlenet-action-buttons [data-action="share"]');if(shareAction){e.preventDefault(),type=shareAction.getAttribute("data-type");const shareType=shareAction.getAttribute("data-sharetype");Promise.resolve(type).then((type=>{if("activity"===type)return MoodleNetService.getActivityInformation(_config.default.contextInstanceId);if("course"===type)return MoodleNetService.getCourseInformation(_config.default.contextInstanceId);throw new Error("Unknown type ".concat(type))})).then((data=>(async(data,shareType)=>data.status?(siteSupportUrl=data.supportpageurl,issuerId=data.issuerid,_send_activity_modal.default.create({templateContext:{activitytype:data.type,activityname:data.name,sharetype:await(0,_str.getString)("moodlenet:sharetype".concat(shareType),"moodle"),server:data.server}})):(0,_notification.addNotification)({message:data.warnings[0].message,type:"error"}))(data,shareType))).catch(_notification.exception)}sendAction&&(e.preventDefault(),courseId=_config.default.courseId,resourceId=_config.default.contextInstanceId,shareFormat=0,handleAuthorization(issuerId))}))};_exports.init=()=>{listenersRegistered||(_prefetch.default.prefetchTemplates(["core/moodlenet/send_activity_modal_base","core/moodlenet/send_activity_modal_packaging","core/moodlenet/send_activity_modal_done","core/moodlenet/send_activity_modal_footer_view"]),registerEventListeners(),listenersRegistered=!0)}})); //# sourceMappingURL=send_resource.min.js.map \ No newline at end of file diff --git a/lib/amd/build/moodlenet/send_resource.min.js.map b/lib/amd/build/moodlenet/send_resource.min.js.map index f121df4885b..6d419666017 100644 --- a/lib/amd/build/moodlenet/send_resource.min.js.map +++ b/lib/amd/build/moodlenet/send_resource.min.js.map @@ -1 +1 @@ -{"version":3,"file":"send_resource.min.js","sources":["../../src/moodlenet/send_resource.js"],"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 * A module to handle Share operations of the MoodleNet.\n *\n * @module core/moodlenet/send_resource\n * @copyright 2023 Huong Nguyen \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 4.2\n */\n\nimport Config from 'core/config';\nimport ModalFactory from 'core/modal_factory';\nimport {alert as displayAlert, addNotification, exception as displayException} from 'core/notification';\nimport {getString} from 'core/str';\nimport Prefetch from \"core/prefetch\";\nimport * as Templates from 'core/templates';\nimport * as MoodleNetService from 'core/moodlenet/service';\nimport SendActivityModal from 'core/moodlenet/send_activity_modal';\n\nconst TYPE_ACTIVITY = \"activity\";\nconst TYPE_COURSE = \"course\";\n\nlet listenersRegistered = false;\nlet currentModal;\nlet siteSupportUrl;\nlet issuerId;\nlet courseId;\nlet resourceId;\nlet shareFormat;\nlet type;\n\n/**\n * Handle send to MoodleNet.\n *\n * @param {int} issuerId The OAuth 2 issuer ID.\n * @param {int} resourceId The resource ID, it can be a course or an activity.\n * @param {int} shareFormat The share format.\n */\nconst sendToMoodleNet = (issuerId, resourceId, shareFormat) => {\n const $modal = currentModal.getModal();\n const modal = $modal[0];\n modal.querySelector('.modal-header').classList.remove('no-border');\n modal.querySelector('.modal-header').classList.add('no-header-text');\n\n currentModal.setBody(Templates.render('core/moodlenet/send_activity_modal_packaging', {}));\n currentModal.hideFooter();\n\n let infoPromise;\n if (type === TYPE_ACTIVITY) {\n infoPromise = MoodleNetService.sendActivity(issuerId, resourceId, shareFormat);\n } else if (type === TYPE_COURSE) {\n infoPromise = MoodleNetService.sendCourse(issuerId, resourceId, shareFormat);\n }\n infoPromise.then(async(data) => {\n const status = data.status;\n const resourceUrl = data.resourceurl;\n return responseFromMoodleNet(status, resourceUrl);\n }).catch(displayException);\n};\n\n/**\n * Handle response from MoodleNet.\n *\n * @param {boolean} status Response status. True if successful.\n * @param {String} resourceUrl Resource URL.\n */\nconst responseFromMoodleNet = (status, resourceUrl = '') => {\n const $modal = currentModal.getModal();\n const modal = $modal[0];\n modal.querySelector('.modal-header').classList.add('no-border');\n currentModal.setBody(Templates.render('core/moodlenet/send_activity_modal_done', {\n success: status,\n sitesupporturl: siteSupportUrl,\n }));\n\n if (status) {\n currentModal.setFooter(Templates.render('core/moodlenet/send_activity_modal_footer_view', {\n resourseurl: resourceUrl,\n }));\n currentModal.showFooter();\n }\n};\n\n/**\n * Handle authorization with MoodleNet server.\n *\n * @param {int} issuerId The OAuth 2 issuer ID.\n * @return {promise}\n */\nconst handleAuthorization = (issuerId) => {\n const windowsizewidth = 550;\n const windowsizeheight = 550;\n\n // Check if the user is authorized with MoodleNet or not.\n return MoodleNetService.authorizationCheck(issuerId, courseId).then(async(data) => {\n if (!data.status) {\n // Not yet authorized.\n // Declare moodleNetAuthorize variable, so we can call it later in the callback.\n window.moodleNetAuthorize = (error, errorDescription) => {\n // This will be called by the callback after the authorization is successful.\n if (error === '') {\n handleAuthorization(issuerId);\n } else if (error !== 'access_denied') {\n displayAlert(\n 'Authorization error',\n 'Error: ' + error + '

Error description: ' + errorDescription,\n 'Cancel'\n );\n }\n };\n // Open the login url of the OAuth 2 issuer for user to login into MoodleNet and authorize.\n return window.open(data.loginurl, 'moodlenet_auth',\n `location=0,status=0,width=${windowsizewidth},height=${windowsizeheight},scrollbars=yes`);\n } else {\n // Already authorized.\n return sendToMoodleNet(issuerId, resourceId, shareFormat);\n }\n }).catch(displayException);\n};\n\n/**\n * Render the modal to send resource to MoodleNet.\n *\n * @param {obj} data The data of the resource to be shared.\n * @param {string} shareType The type of the resource to be shared.\n */\nconst renderModal = async(data, shareType) => {\n if (data.status) {\n siteSupportUrl = data.supportpageurl;\n issuerId = data.issuerid;\n const modalPromise = ModalFactory.create({\n type: SendActivityModal.TYPE,\n large: true,\n templateContext: {\n 'activitytype': data.type,\n 'activityname': data.name,\n 'sharetype': await getString('moodlenet:sharetype' + shareType, 'moodle'),\n 'server': data.server,\n }\n });\n return modalPromise.then(modal => {\n currentModal = modal;\n modal.show();\n return modal;\n }).catch(displayException);\n } else {\n return addNotification({\n message: data.warnings[0].message,\n type: 'error'\n });\n }\n};\n\n/**\n * Register events.\n */\nconst registerEventListeners = () => {\n document.addEventListener('click', e => {\n const shareAction = e.target.closest('[data-action=\"sendtomoodlenet\"]');\n const sendAction = e.target.closest('.moodlenet-action-buttons [data-action=\"share\"]');\n if (shareAction) {\n e.preventDefault();\n type = shareAction.getAttribute('data-type');\n const shareType = shareAction.getAttribute('data-sharetype');\n const resourceId = Config.contextInstanceId;\n\n let infoPromise;\n if (type === TYPE_ACTIVITY) {\n infoPromise = MoodleNetService.getActivityInformation(resourceId);\n } else if (type === TYPE_COURSE) {\n infoPromise = MoodleNetService.getCourseInformation(resourceId);\n }\n infoPromise.then(async(data) => {\n renderModal(data, shareType).catch(displayException);\n }).catch(displayException);\n }\n\n if (sendAction) {\n e.preventDefault();\n courseId = Config.courseId;\n resourceId = Config.contextInstanceId;\n shareFormat = 0;\n handleAuthorization(issuerId);\n }\n });\n};\n\n/**\n * Initialize.\n */\nexport const init = () => {\n if (!listenersRegistered) {\n Prefetch.prefetchTemplates([\n 'core/moodlenet/send_activity_modal_base',\n 'core/moodlenet/send_activity_modal_packaging',\n 'core/moodlenet/send_activity_modal_done',\n 'core/moodlenet/send_activity_modal_footer_view',\n ]);\n registerEventListeners();\n listenersRegistered = true;\n }\n};\n"],"names":["currentModal","siteSupportUrl","issuerId","courseId","resourceId","shareFormat","type","listenersRegistered","responseFromMoodleNet","status","resourceUrl","$modal","getModal","modal","querySelector","classList","add","setBody","Templates","render","success","sitesupporturl","setFooter","resourseurl","showFooter","handleAuthorization","MoodleNetService","authorizationCheck","then","async","data","infoPromise","remove","hideFooter","sendActivity","sendCourse","resourceurl","catch","displayException","sendToMoodleNet","window","moodleNetAuthorize","error","errorDescription","open","loginurl","registerEventListeners","document","addEventListener","e","shareAction","target","closest","sendAction","preventDefault","getAttribute","shareType","Config","contextInstanceId","getActivityInformation","getCourseInformation","supportpageurl","issuerid","ModalFactory","create","SendActivityModal","TYPE","large","templateContext","name","server","show","message","warnings","renderModal","prefetchTemplates"],"mappings":";;;;;;;;0YAqCIA,aACAC,eACAC,SACAC,SACAC,WACAC,YACAC,KAPAC,qBAAsB,QA4CpBC,sBAAwB,SAACC,YAAQC,mEAAc,SAC3CC,OAASX,aAAaY,WACtBC,MAAQF,OAAO,GACrBE,MAAMC,cAAc,iBAAiBC,UAAUC,IAAI,aACnDhB,aAAaiB,QAAQC,UAAUC,OAAO,0CAA2C,CAC7EC,QAASX,OACTY,eAAgBpB,kBAGhBQ,SACAT,aAAasB,UAAUJ,UAAUC,OAAO,iDAAkD,CACtFI,YAAab,eAEjBV,aAAawB,eAUfC,oBAAuBvB,UAKlBwB,iBAAiBC,mBAAmBzB,SAAUC,UAAUyB,MAAKC,MAAAA,MAC3DC,KAAKrB,OAzDM,EAACP,SAAUE,WAAYC,qBAErCQ,MADSb,aAAaY,WACP,OAOjBmB,YANJlB,MAAMC,cAAc,iBAAiBC,UAAUiB,OAAO,aACtDnB,MAAMC,cAAc,iBAAiBC,UAAUC,IAAI,kBAEnDhB,aAAaiB,QAAQC,UAAUC,OAAO,+CAAgD,KACtFnB,aAAaiC,aA1BK,aA6Bd3B,KACAyB,YAAcL,iBAAiBQ,aAAahC,SAAUE,WAAYC,aA7BtD,WA8BLC,OACPyB,YAAcL,iBAAiBS,WAAWjC,SAAUE,WAAYC,cAEpE0B,YAAYH,MAAKC,MAAAA,aACPpB,OAASqB,KAAKrB,OACdC,YAAcoB,KAAKM,mBAClB5B,sBAAsBC,OAAQC,gBACtC2B,MAAMC,0BA0DMC,CAAgBrC,SAAUE,WAAYC,cAjB7CmC,OAAOC,mBAAqB,CAACC,MAAOC,oBAElB,KAAVD,MACAjB,oBAAoBvB,UACH,kBAAVwC,+BAEH,sBACA,UAAYA,MAAQ,8BAAgCC,iBACpD,WAKLH,OAAOI,KAAKd,KAAKe,SAAU,qDArBlB,uBACC,2BA0BtBR,MAAMC,yBAuCPQ,uBAAyB,KAC3BC,SAASC,iBAAiB,SAASC,UACzBC,YAAcD,EAAEE,OAAOC,QAAQ,mCAC/BC,WAAaJ,EAAEE,OAAOC,QAAQ,sDAChCF,YAAa,CACbD,EAAEK,iBACFhD,KAAO4C,YAAYK,aAAa,mBAC1BC,UAAYN,YAAYK,aAAa,kBACrCnD,WAAaqD,gBAAOC,sBAEtB3B,YAnJM,aAoJNzB,KACAyB,YAAcL,iBAAiBiC,uBAAuBvD,YApJlD,WAqJGE,OACPyB,YAAcL,iBAAiBkC,qBAAqBxD,aAExD2B,YAAYH,MAAKC,MAAAA,OA9CTA,OAAMC,KAAM0B,gBACxB1B,KAAKrB,cACLR,eAAiB6B,KAAK+B,eACtB3D,SAAW4B,KAAKgC,SACKC,uBAAaC,OAAO,CACrC1D,KAAM2D,6BAAkBC,KACxBC,OAAO,EACPC,gBAAiB,cACGtC,KAAKxB,kBACLwB,KAAKuC,qBACF,kBAAU,sBAAwBb,UAAW,iBACtD1B,KAAKwC,UAGH1C,MAAKf,QACrBb,aAAea,MACfA,MAAM0D,OACC1D,SACRwB,MAAMC,gCAEF,iCAAgB,CACnBkC,QAAS1C,KAAK2C,SAAS,GAAGD,QAC1BlE,KAAM,WAyBFoE,CAAY5C,KAAM0B,WAAWnB,MAAMC,4BACpCD,MAAMC,yBAGTe,aACAJ,EAAEK,iBACFnD,SAAWsD,gBAAOtD,SAClBC,WAAaqD,gBAAOC,kBACpBrD,YAAc,EACdoB,oBAAoBvB,6BAQZ,KACXK,wCACQoE,kBAAkB,CACvB,0CACA,+CACA,0CACA,mDAEJ7B,yBACAvC,qBAAsB"} \ No newline at end of file +{"version":3,"file":"send_resource.min.js","sources":["../../src/moodlenet/send_resource.js"],"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 * A module to handle Share operations of the MoodleNet.\n *\n * @module core/moodlenet/send_resource\n * @copyright 2023 Huong Nguyen \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 4.2\n */\n\nimport Config from 'core/config';\nimport {alert as displayAlert, addNotification, exception as displayException} from 'core/notification';\nimport {getString} from 'core/str';\nimport Prefetch from \"core/prefetch\";\nimport * as Templates from 'core/templates';\nimport * as MoodleNetService from 'core/moodlenet/service';\nimport SendActivityModal from 'core/moodlenet/send_activity_modal';\n\nconst TYPE_ACTIVITY = \"activity\";\nconst TYPE_COURSE = \"course\";\n\nlet listenersRegistered = false;\nlet currentModal;\nlet siteSupportUrl;\nlet issuerId;\nlet courseId;\nlet resourceId;\nlet shareFormat;\nlet type;\n\n/**\n * Handle send to MoodleNet.\n *\n * @param {int} issuerId The OAuth 2 issuer ID.\n * @param {int} resourceId The resource ID, it can be a course or an activity.\n * @param {int} shareFormat The share format.\n */\nconst sendToMoodleNet = (issuerId, resourceId, shareFormat) => {\n const $modal = currentModal.getModal();\n const modal = $modal[0];\n modal.querySelector('.modal-header').classList.remove('no-border');\n modal.querySelector('.modal-header').classList.add('no-header-text');\n\n currentModal.setBody(Templates.render('core/moodlenet/send_activity_modal_packaging', {}));\n currentModal.hideFooter();\n\n let infoPromise;\n if (type === TYPE_ACTIVITY) {\n infoPromise = MoodleNetService.sendActivity(issuerId, resourceId, shareFormat);\n } else if (type === TYPE_COURSE) {\n infoPromise = MoodleNetService.sendCourse(issuerId, resourceId, shareFormat);\n }\n infoPromise.then(async(data) => {\n const status = data.status;\n const resourceUrl = data.resourceurl;\n return responseFromMoodleNet(status, resourceUrl);\n }).catch(displayException);\n};\n\n/**\n * Handle response from MoodleNet.\n *\n * @param {boolean} status Response status. True if successful.\n * @param {String} resourceUrl Resource URL.\n */\nconst responseFromMoodleNet = (status, resourceUrl = '') => {\n const $modal = currentModal.getModal();\n const modal = $modal[0];\n modal.querySelector('.modal-header').classList.add('no-border');\n currentModal.setBody(Templates.render('core/moodlenet/send_activity_modal_done', {\n success: status,\n sitesupporturl: siteSupportUrl,\n }));\n\n if (status) {\n currentModal.setFooter(Templates.render('core/moodlenet/send_activity_modal_footer_view', {\n resourseurl: resourceUrl,\n }));\n currentModal.showFooter();\n }\n};\n\n/**\n * Handle authorization with MoodleNet server.\n *\n * @param {Number} issuerId The OAuth 2 issuer ID.\n * @return {promise}\n */\nconst handleAuthorization = (issuerId) => {\n const windowsizewidth = 550;\n const windowsizeheight = 550;\n\n // Check if the user is authorized with MoodleNet or not.\n return MoodleNetService.authorizationCheck(issuerId, courseId).then((data) => {\n if (!data.status) {\n // Not yet authorized.\n // Declare moodleNetAuthorize variable, so we can call it later in the callback.\n window.moodleNetAuthorize = (error, errorDescription) => {\n // This will be called by the callback after the authorization is successful.\n if (error === '') {\n handleAuthorization(issuerId);\n } else if (error !== 'access_denied') {\n displayAlert(\n 'Authorization error',\n 'Error: ' + error + '

Error description: ' + errorDescription,\n 'Cancel'\n );\n }\n };\n // Open the login url of the OAuth 2 issuer for user to login into MoodleNet and authorize.\n return window.open(data.loginurl, 'moodlenet_auth',\n `location=0,status=0,width=${windowsizewidth},height=${windowsizeheight},scrollbars=yes`);\n } else {\n // Already authorized.\n return sendToMoodleNet(issuerId, resourceId, shareFormat);\n }\n }).catch(displayException);\n};\n\n/**\n * Render the modal to send resource to MoodleNet.\n *\n * @param {object} data The data of the resource to be shared.\n * @param {string} shareType The type of the resource to be shared.\n */\nconst renderModal = async(data, shareType) => {\n if (data.status) {\n siteSupportUrl = data.supportpageurl;\n issuerId = data.issuerid;\n return SendActivityModal.create({\n templateContext: {\n activitytype: data.type,\n activityname: data.name,\n sharetype: await getString(`moodlenet:sharetype${shareType}`, 'moodle'),\n server: data.server,\n }\n });\n } else {\n return addNotification({\n message: data.warnings[0].message,\n type: 'error'\n });\n }\n};\n\n/**\n * Register events.\n */\nconst registerEventListeners = () => {\n document.addEventListener('click', (e) => {\n const shareAction = e.target.closest('[data-action=\"sendtomoodlenet\"]');\n const sendAction = e.target.closest('.moodlenet-action-buttons [data-action=\"share\"]');\n if (shareAction) {\n e.preventDefault();\n type = shareAction.getAttribute('data-type');\n const shareType = shareAction.getAttribute('data-sharetype');\n Promise.resolve(type)\n .then((type) => {\n if (type === TYPE_ACTIVITY) {\n return MoodleNetService.getActivityInformation(Config.contextInstanceId);\n } else if (type === TYPE_COURSE) {\n return MoodleNetService.getCourseInformation(Config.contextInstanceId);\n }\n throw new Error(`Unknown type ${type}`);\n })\n .then((data) => renderModal(data, shareType))\n .catch(displayException);\n }\n\n if (sendAction) {\n e.preventDefault();\n courseId = Config.courseId;\n resourceId = Config.contextInstanceId;\n shareFormat = 0;\n handleAuthorization(issuerId);\n }\n });\n};\n\n\n/**\n * Initialize.\n */\nexport const init = () => {\n if (!listenersRegistered) {\n Prefetch.prefetchTemplates([\n 'core/moodlenet/send_activity_modal_base',\n 'core/moodlenet/send_activity_modal_packaging',\n 'core/moodlenet/send_activity_modal_done',\n 'core/moodlenet/send_activity_modal_footer_view',\n ]);\n registerEventListeners();\n listenersRegistered = true;\n }\n};\n"],"names":["siteSupportUrl","issuerId","courseId","resourceId","shareFormat","type","listenersRegistered","responseFromMoodleNet","status","resourceUrl","$modal","currentModal","getModal","modal","querySelector","classList","add","setBody","Templates","render","success","sitesupporturl","setFooter","resourseurl","showFooter","handleAuthorization","MoodleNetService","authorizationCheck","then","data","infoPromise","remove","hideFooter","sendActivity","sendCourse","async","resourceurl","catch","displayException","sendToMoodleNet","window","moodleNetAuthorize","error","errorDescription","open","loginurl","registerEventListeners","document","addEventListener","e","shareAction","target","closest","sendAction","preventDefault","getAttribute","shareType","Promise","resolve","getActivityInformation","Config","contextInstanceId","getCourseInformation","Error","supportpageurl","issuerid","SendActivityModal","create","templateContext","activitytype","activityname","name","sharetype","server","message","warnings","renderModal","prefetchTemplates"],"mappings":";;;;;;;;oVAqCIA,eACAC,SACAC,SACAC,WACAC,YACAC,KAPAC,qBAAsB,QA4CpBC,sBAAwB,SAACC,YAAQC,mEAAc,SAC3CC,OA5CNC,UA4C4BC,WACtBC,MAAQH,OAAO,GACrBG,MAAMC,cAAc,iBAAiBC,UAAUC,IAAI,aA9CnDL,UA+CaM,QAAQC,UAAUC,OAAO,0CAA2C,CAC7EC,QAASZ,OACTa,eAAgBrB,kBAGhBQ,SApDJG,UAqDiBW,UAAUJ,UAAUC,OAAO,iDAAkD,CACtFI,YAAad,eAtDrBE,UAwDiBa,eAUfC,oBAAuBxB,UAKlByB,iBAAiBC,mBAAmB1B,SAAUC,UAAU0B,MAAMC,MAC5DA,KAAKrB,OAzDM,EAACP,SAAUE,WAAYC,qBAErCS,YAjBNF,GAgB4BC,WACP,OAOjBkB,YANJjB,MAAMC,cAAc,iBAAiBC,UAAUgB,OAAO,aACtDlB,MAAMC,cAAc,iBAAiBC,UAAUC,IAAI,wBAnBnDL,GAqBaM,QAAQC,UAAUC,OAAO,+CAAgD,WArBtFR,GAsBaqB,aA1BK,aA6Bd3B,KACAyB,YAAcJ,iBAAiBO,aAAahC,SAAUE,WAAYC,aA7BtD,WA8BLC,OACPyB,YAAcJ,iBAAiBQ,WAAWjC,SAAUE,WAAYC,cAEpE0B,YAAYF,MAAKO,MAAAA,aACP3B,OAASqB,KAAKrB,OACdC,YAAcoB,KAAKO,mBAClB7B,sBAAsBC,OAAQC,gBACtC4B,MAAMC,0BA0DMC,CAAgBtC,SAAUE,WAAYC,cAjB7CoC,OAAOC,mBAAqB,CAACC,MAAOC,oBAElB,KAAVD,MACAjB,oBAAoBxB,UACH,kBAAVyC,+BAEH,sBACA,UAAYA,MAAQ,8BAAgCC,iBACpD,WAKLH,OAAOI,KAAKf,KAAKgB,SAAU,qDArBlB,uBACC,2BA0BtBR,MAAMC,yBAgCPQ,uBAAyB,KAC3BC,SAASC,iBAAiB,SAAUC,UAC1BC,YAAcD,EAAEE,OAAOC,QAAQ,mCAC/BC,WAAaJ,EAAEE,OAAOC,QAAQ,sDAChCF,YAAa,CACbD,EAAEK,iBACFjD,KAAO6C,YAAYK,aAAa,mBAC1BC,UAAYN,YAAYK,aAAa,kBAC3CE,QAAQC,QAAQrD,MACXuB,MAAMvB,UA3ID,aA4IEA,YACOqB,iBAAiBiC,uBAAuBC,gBAAOC,mBACnD,GA7IP,WA6IWxD,YACAqB,iBAAiBoC,qBAAqBF,gBAAOC,yBAElD,IAAIE,6BAAsB1D,UAEnCuB,MAAMC,MAxCHM,OAAMN,KAAM2B,YACxB3B,KAAKrB,QACLR,eAAiB6B,KAAKmC,eACtB/D,SAAW4B,KAAKoC,SACTC,6BAAkBC,OAAO,CAC5BC,gBAAiB,CACbC,aAAcxC,KAAKxB,KACnBiE,aAAczC,KAAK0C,KACnBC,gBAAiB,+CAAgChB,WAAa,UAC9DiB,OAAQ5C,KAAK4C,YAId,iCAAgB,CACnBC,QAAS7C,KAAK8C,SAAS,GAAGD,QAC1BrE,KAAM,UAyBcuE,CAAY/C,KAAM2B,aACjCnB,MAAMC,yBAGXe,aACAJ,EAAEK,iBACFpD,SAAW0D,gBAAO1D,SAClBC,WAAayD,gBAAOC,kBACpBzD,YAAc,EACdqB,oBAAoBxB,6BASZ,KACXK,wCACQuE,kBAAkB,CACvB,0CACA,+CACA,0CACA,mDAEJ/B,yBACAxC,qBAAsB"} \ No newline at end of file diff --git a/lib/amd/build/notification.min.js b/lib/amd/build/notification.min.js index afb78ff0609..bbb8e695c5b 100644 --- a/lib/amd/build/notification.min.js +++ b/lib/amd/build/notification.min.js @@ -1,3 +1,3 @@ -define("core/notification",["exports","core/pending","core/log"],(function(_exports,_pending,_log){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.saveCancelPromise=_exports.saveCancel=_exports.init=_exports.fetchNotifications=_exports.exception=_exports.deleteCancelPromise=_exports.deleteCancel=_exports.default=_exports.confirm=_exports.alert=_exports.addNotification=void 0,_pending=_interopRequireDefault(_pending),_log=_interopRequireDefault(_log);var _systemImportTransformerGlobalIdentifier="undefined"!=typeof window?window:"undefined"!=typeof self?self:"undefined"!=typeof global?global:{};function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}let currentContextId=M.cfg.contextid;const notificationTypes={success:"core/notification_success",info:"core/notification_info",warning:"core/notification_warning",error:"core/notification_error"},Selectors={notificationRegion:"#".concat("user-notifications"),fallbackRegionParents:["#region-main",'[role="main"]',"body"]},fetchNotifications=async()=>(await("function"==typeof _systemImportTransformerGlobalIdentifier.define&&_systemImportTransformerGlobalIdentifier.define.amd?new Promise((function(resolve,reject){_systemImportTransformerGlobalIdentifier.require(["core/ajax"],resolve,reject)})):"undefined"!=typeof module&&module.exports&&"undefined"!=typeof require||"undefined"!=typeof module&&module.component&&_systemImportTransformerGlobalIdentifier.require&&"component"===_systemImportTransformerGlobalIdentifier.require.loader?Promise.resolve(require("core/ajax")):Promise.resolve(_systemImportTransformerGlobalIdentifier["core/ajax"]))).call([{methodname:"core_fetch_notifications",args:{contextid:currentContextId}}])[0].then(addNotifications);_exports.fetchNotifications=fetchNotifications;const addNotifications=notifications=>{if(!notifications.length)return Promise.resolve();const pendingPromise=new _pending.default("core/notification:addNotifications");return notifications.forEach((notification=>renderNotification(notification.template,notification.variables))),pendingPromise.resolve()},addNotification=notification=>{const pendingPromise=new _pending.default("core/notification:addNotifications");let template=notificationTypes.error;return(notification={closebutton:!0,announce:!0,type:"error",...notification}).template?(template=notification.template,delete notification.template):notification.type&&(void 0!==notificationTypes[notification.type]&&(template=notificationTypes[notification.type]),delete notification.type),renderNotification(template,notification).then(pendingPromise.resolve)};_exports.addNotification=addNotification;const renderNotification=async(template,variables)=>{if(void 0===variables.message||!variables.message)return void _log.default.debug("Notification received without content. Skipping.");const pendingPromise=new _pending.default("core/notification:renderNotification"),Templates=await("function"==typeof _systemImportTransformerGlobalIdentifier.define&&_systemImportTransformerGlobalIdentifier.define.amd?new Promise((function(resolve,reject){_systemImportTransformerGlobalIdentifier.require(["core/templates"],resolve,reject)})):"undefined"!=typeof module&&module.exports&&"undefined"!=typeof require||"undefined"!=typeof module&&module.component&&_systemImportTransformerGlobalIdentifier.require&&"component"===_systemImportTransformerGlobalIdentifier.require.loader?Promise.resolve(require("core/templates")):Promise.resolve(_systemImportTransformerGlobalIdentifier["core/templates"]));Templates.renderForPromise(template,variables).then((_ref=>{let{html:html,js:js=""}=_ref;Templates.prependNodeContents(getNotificationRegion(),html,js)})).then(pendingPromise.resolve).catch(exception)},getNotificationRegion=()=>document.querySelector(Selectors.notificationRegion),alert=async(title,message,cancelText)=>{var pendingPromise=new _pending.default("core/notification:alert");const ModalFactory=await("function"==typeof _systemImportTransformerGlobalIdentifier.define&&_systemImportTransformerGlobalIdentifier.define.amd?new Promise((function(resolve,reject){_systemImportTransformerGlobalIdentifier.require(["core/modal_factory"],resolve,reject)})):"undefined"!=typeof module&&module.exports&&"undefined"!=typeof require||"undefined"!=typeof module&&module.component&&_systemImportTransformerGlobalIdentifier.require&&"component"===_systemImportTransformerGlobalIdentifier.require.loader?Promise.resolve(require("core/modal_factory")):Promise.resolve(_systemImportTransformerGlobalIdentifier["core/modal_factory"]));return ModalFactory.create({type:ModalFactory.types.ALERT,body:message,title:title,buttons:{cancel:cancelText},removeOnClose:!0}).then((function(modal){return modal.show(),pendingPromise.resolve(),modal}))};_exports.alert=alert;const confirm=(title,question,saveLabel,noLabel,saveCallback,cancelCallback)=>saveCancel(title,question,saveLabel,saveCallback,cancelCallback);_exports.confirm=confirm;const saveCancel=async function(title,question,saveLabel,saveCallback,cancelCallback){let{triggerElement:triggerElement=null}=arguments.length>5&&void 0!==arguments[5]?arguments[5]:{};const pendingPromise=new _pending.default("core/notification:confirm"),[ModalFactory,ModalEvents]=await Promise.all(["function"==typeof _systemImportTransformerGlobalIdentifier.define&&_systemImportTransformerGlobalIdentifier.define.amd?new Promise((function(resolve,reject){_systemImportTransformerGlobalIdentifier.require(["core/modal_factory"],resolve,reject)})):"undefined"!=typeof module&&module.exports&&"undefined"!=typeof require||"undefined"!=typeof module&&module.component&&_systemImportTransformerGlobalIdentifier.require&&"component"===_systemImportTransformerGlobalIdentifier.require.loader?Promise.resolve(require("core/modal_factory")):Promise.resolve(_systemImportTransformerGlobalIdentifier["core/modal_factory"]),"function"==typeof _systemImportTransformerGlobalIdentifier.define&&_systemImportTransformerGlobalIdentifier.define.amd?new Promise((function(resolve,reject){_systemImportTransformerGlobalIdentifier.require(["core/modal_events"],resolve,reject)})):"undefined"!=typeof module&&module.exports&&"undefined"!=typeof require||"undefined"!=typeof module&&module.component&&_systemImportTransformerGlobalIdentifier.require&&"component"===_systemImportTransformerGlobalIdentifier.require.loader?Promise.resolve(require("core/modal_events")):Promise.resolve(_systemImportTransformerGlobalIdentifier["core/modal_events"])]);return ModalFactory.create({type:ModalFactory.types.SAVE_CANCEL,title:title,body:question,buttons:{save:saveLabel},removeOnClose:!0}).then((function(modal){return modal.show(),modal.getRoot().on(ModalEvents.save,saveCallback),modal.getRoot().on(ModalEvents.cancel,cancelCallback),modal.getRoot().on(ModalEvents.hidden,(()=>null==triggerElement?void 0:triggerElement.focus())),pendingPromise.resolve(),modal}))};_exports.saveCancel=saveCancel;const deleteCancel=async function(title,question,deleteLabel,deleteCallback,cancelCallback){let{triggerElement:triggerElement=null}=arguments.length>5&&void 0!==arguments[5]?arguments[5]:{};const pendingPromise=new _pending.default("core/notification:confirm"),[ModalFactory,ModalEvents]=await Promise.all(["function"==typeof _systemImportTransformerGlobalIdentifier.define&&_systemImportTransformerGlobalIdentifier.define.amd?new Promise((function(resolve,reject){_systemImportTransformerGlobalIdentifier.require(["core/modal_factory"],resolve,reject)})):"undefined"!=typeof module&&module.exports&&"undefined"!=typeof require||"undefined"!=typeof module&&module.component&&_systemImportTransformerGlobalIdentifier.require&&"component"===_systemImportTransformerGlobalIdentifier.require.loader?Promise.resolve(require("core/modal_factory")):Promise.resolve(_systemImportTransformerGlobalIdentifier["core/modal_factory"]),"function"==typeof _systemImportTransformerGlobalIdentifier.define&&_systemImportTransformerGlobalIdentifier.define.amd?new Promise((function(resolve,reject){_systemImportTransformerGlobalIdentifier.require(["core/modal_events"],resolve,reject)})):"undefined"!=typeof module&&module.exports&&"undefined"!=typeof require||"undefined"!=typeof module&&module.component&&_systemImportTransformerGlobalIdentifier.require&&"component"===_systemImportTransformerGlobalIdentifier.require.loader?Promise.resolve(require("core/modal_events")):Promise.resolve(_systemImportTransformerGlobalIdentifier["core/modal_events"])]);return ModalFactory.create({type:ModalFactory.types.DELETE_CANCEL,title:title,body:question,buttons:{delete:deleteLabel},removeOnClose:!0}).then((function(modal){return modal.show(),modal.getRoot().on(ModalEvents.delete,deleteCallback),modal.getRoot().on(ModalEvents.cancel,cancelCallback),modal.getRoot().on(ModalEvents.hidden,(()=>null==triggerElement?void 0:triggerElement.focus())),pendingPromise.resolve(),modal}))};_exports.deleteCancel=deleteCancel;const saveCancelPromise=function(title,question,saveLabel){let{triggerElement:triggerElement=null}=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};return new Promise(((resolve,reject)=>{saveCancel(title,question,saveLabel,resolve,reject,{triggerElement:triggerElement})}))};_exports.saveCancelPromise=saveCancelPromise;const deleteCancelPromise=function(title,question,deleteLabel){let{triggerElement:triggerElement=null}=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};return new Promise(((resolve,reject)=>{deleteCancel(title,question,deleteLabel,resolve,reject,{triggerElement:triggerElement})}))};_exports.deleteCancelPromise=deleteCancelPromise;const exception=async ex=>{const pendingPromise=new _pending.default("core/notification:displayException");if(ex.stack||(ex.stack=""),ex.debuginfo&&(ex.stack+=ex.debuginfo+"\n"),!ex.backtrace&&ex.stacktrace&&(ex.backtrace=ex.stacktrace),ex.backtrace){ex.stack+=ex.backtrace;const ln=ex.backtrace.match(/line ([^ ]*) of/),fn=ex.backtrace.match(/ of ([^:]*): /);ln&&ln[1]&&(ex.lineNumber=ln[1]),fn&&fn[1]&&(ex.fileName=fn[1],ex.fileName.length>30&&(ex.fileName="..."+ex.fileName.substr(ex.fileName.length-27)))}void 0===ex.name&&ex.errorcode&&(ex.name=ex.errorcode);(await("function"==typeof _systemImportTransformerGlobalIdentifier.define&&_systemImportTransformerGlobalIdentifier.define.amd?new Promise((function(resolve,reject){_systemImportTransformerGlobalIdentifier.require(["core/yui"],resolve,reject)})):"undefined"!=typeof module&&module.exports&&"undefined"!=typeof require||"undefined"!=typeof module&&module.component&&_systemImportTransformerGlobalIdentifier.require&&"component"===_systemImportTransformerGlobalIdentifier.require.loader?Promise.resolve(require("core/yui")):Promise.resolve(_systemImportTransformerGlobalIdentifier["core/yui"]))).use("moodle-core-notification-exception",(function(){new M.core.exception(ex).show(),pendingPromise.resolve()}))};_exports.exception=exception;const init=(contextId,notificationList)=>{currentContextId=contextId,(()=>{if(getNotificationRegion())return!1;const newRegion=document.createElement("span");newRegion.id="user-notifications",Selectors.fallbackRegionParents.some((selector=>{const targetRegion=document.querySelector(selector);return!!targetRegion&&(targetRegion.prepend(newRegion),!0)}))})(),addNotifications(notificationList)};_exports.init=init;var _default={init:init,fetchNotifications:fetchNotifications,addNotification:addNotification,alert:alert,confirm:confirm,saveCancel:saveCancel,saveCancelPromise:saveCancelPromise,deleteCancelPromise:deleteCancelPromise,exception:exception};return _exports.default=_default,_exports.default})); +define("core/notification",["exports","core/pending","core/log"],(function(_exports,_pending,_log){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.saveCancelPromise=_exports.saveCancel=_exports.init=_exports.fetchNotifications=_exports.exception=_exports.deleteCancelPromise=_exports.deleteCancel=_exports.default=_exports.confirm=_exports.alert=_exports.addNotification=void 0,_pending=_interopRequireDefault(_pending),_log=_interopRequireDefault(_log);var _systemImportTransformerGlobalIdentifier="undefined"!=typeof window?window:"undefined"!=typeof self?self:"undefined"!=typeof global?global:{};function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}let currentContextId=M.cfg.contextid;const notificationTypes={success:"core/notification_success",info:"core/notification_info",warning:"core/notification_warning",error:"core/notification_error"},Selectors={notificationRegion:"#".concat("user-notifications"),fallbackRegionParents:["#region-main",'[role="main"]',"body"]},fetchNotifications=async()=>(await("function"==typeof _systemImportTransformerGlobalIdentifier.define&&_systemImportTransformerGlobalIdentifier.define.amd?new Promise((function(resolve,reject){_systemImportTransformerGlobalIdentifier.require(["core/ajax"],resolve,reject)})):"undefined"!=typeof module&&module.exports&&"undefined"!=typeof require||"undefined"!=typeof module&&module.component&&_systemImportTransformerGlobalIdentifier.require&&"component"===_systemImportTransformerGlobalIdentifier.require.loader?Promise.resolve(require("core/ajax")):Promise.resolve(_systemImportTransformerGlobalIdentifier["core/ajax"]))).call([{methodname:"core_fetch_notifications",args:{contextid:currentContextId}}])[0].then(addNotifications);_exports.fetchNotifications=fetchNotifications;const addNotifications=notifications=>{if(!notifications.length)return Promise.resolve();const pendingPromise=new _pending.default("core/notification:addNotifications");return notifications.forEach((notification=>renderNotification(notification.template,notification.variables))),pendingPromise.resolve()},addNotification=notification=>{const pendingPromise=new _pending.default("core/notification:addNotifications");let template=notificationTypes.error;return(notification={closebutton:!0,announce:!0,type:"error",...notification}).template?(template=notification.template,delete notification.template):notification.type&&(void 0!==notificationTypes[notification.type]&&(template=notificationTypes[notification.type]),delete notification.type),renderNotification(template,notification).then(pendingPromise.resolve)};_exports.addNotification=addNotification;const renderNotification=async(template,variables)=>{if(void 0===variables.message||!variables.message)return void _log.default.debug("Notification received without content. Skipping.");const pendingPromise=new _pending.default("core/notification:renderNotification"),Templates=await("function"==typeof _systemImportTransformerGlobalIdentifier.define&&_systemImportTransformerGlobalIdentifier.define.amd?new Promise((function(resolve,reject){_systemImportTransformerGlobalIdentifier.require(["core/templates"],resolve,reject)})):"undefined"!=typeof module&&module.exports&&"undefined"!=typeof require||"undefined"!=typeof module&&module.component&&_systemImportTransformerGlobalIdentifier.require&&"component"===_systemImportTransformerGlobalIdentifier.require.loader?Promise.resolve(require("core/templates")):Promise.resolve(_systemImportTransformerGlobalIdentifier["core/templates"]));Templates.renderForPromise(template,variables).then((_ref=>{let{html:html,js:js=""}=_ref;Templates.prependNodeContents(getNotificationRegion(),html,js)})).then(pendingPromise.resolve).catch(exception)},getNotificationRegion=()=>document.querySelector(Selectors.notificationRegion),alert=async(title,message,cancelText)=>{var pendingPromise=new _pending.default("core/notification:alert");const AlertModal=await("function"==typeof _systemImportTransformerGlobalIdentifier.define&&_systemImportTransformerGlobalIdentifier.define.amd?new Promise((function(resolve,reject){_systemImportTransformerGlobalIdentifier.require(["core/local/modal/alert"],resolve,reject)})):"undefined"!=typeof module&&module.exports&&"undefined"!=typeof require||"undefined"!=typeof module&&module.component&&_systemImportTransformerGlobalIdentifier.require&&"component"===_systemImportTransformerGlobalIdentifier.require.loader?Promise.resolve(require("core/local/modal/alert")):Promise.resolve(_systemImportTransformerGlobalIdentifier["core/local/modal/alert"])),modal=await AlertModal.create({body:message,title:title,buttons:{cancel:cancelText},removeOnClose:!0,show:!0});return pendingPromise.resolve(),modal};_exports.alert=alert;const confirm=(title,question,saveLabel,noLabel,saveCallback,cancelCallback)=>saveCancel(title,question,saveLabel,saveCallback,cancelCallback);_exports.confirm=confirm;const saveCancel=async function(title,question,saveLabel,saveCallback,cancelCallback){let{triggerElement:triggerElement=null}=arguments.length>5&&void 0!==arguments[5]?arguments[5]:{};const pendingPromise=new _pending.default("core/notification:confirm"),[SaveCancelModal,ModalEvents]=await Promise.all(["function"==typeof _systemImportTransformerGlobalIdentifier.define&&_systemImportTransformerGlobalIdentifier.define.amd?new Promise((function(resolve,reject){_systemImportTransformerGlobalIdentifier.require(["core/modal_save_cancel"],resolve,reject)})):"undefined"!=typeof module&&module.exports&&"undefined"!=typeof require||"undefined"!=typeof module&&module.component&&_systemImportTransformerGlobalIdentifier.require&&"component"===_systemImportTransformerGlobalIdentifier.require.loader?Promise.resolve(require("core/modal_save_cancel")):Promise.resolve(_systemImportTransformerGlobalIdentifier["core/modal_save_cancel"]),"function"==typeof _systemImportTransformerGlobalIdentifier.define&&_systemImportTransformerGlobalIdentifier.define.amd?new Promise((function(resolve,reject){_systemImportTransformerGlobalIdentifier.require(["core/modal_events"],resolve,reject)})):"undefined"!=typeof module&&module.exports&&"undefined"!=typeof require||"undefined"!=typeof module&&module.component&&_systemImportTransformerGlobalIdentifier.require&&"component"===_systemImportTransformerGlobalIdentifier.require.loader?Promise.resolve(require("core/modal_events")):Promise.resolve(_systemImportTransformerGlobalIdentifier["core/modal_events"])]),modal=await SaveCancelModal.create({title:title,body:question,buttons:{save:saveLabel},removeOnClose:!0,show:!0});return modal.getRoot().on(ModalEvents.save,saveCallback),modal.getRoot().on(ModalEvents.cancel,cancelCallback),modal.getRoot().on(ModalEvents.hidden,(()=>null==triggerElement?void 0:triggerElement.focus())),pendingPromise.resolve(),modal};_exports.saveCancel=saveCancel;const deleteCancel=async function(title,question,deleteLabel,deleteCallback,cancelCallback){let{triggerElement:triggerElement=null}=arguments.length>5&&void 0!==arguments[5]?arguments[5]:{};const pendingPromise=new _pending.default("core/notification:confirm"),[DeleteCancelModal,ModalEvents]=await Promise.all(["function"==typeof _systemImportTransformerGlobalIdentifier.define&&_systemImportTransformerGlobalIdentifier.define.amd?new Promise((function(resolve,reject){_systemImportTransformerGlobalIdentifier.require(["core/modal_delete_cancel"],resolve,reject)})):"undefined"!=typeof module&&module.exports&&"undefined"!=typeof require||"undefined"!=typeof module&&module.component&&_systemImportTransformerGlobalIdentifier.require&&"component"===_systemImportTransformerGlobalIdentifier.require.loader?Promise.resolve(require("core/modal_delete_cancel")):Promise.resolve(_systemImportTransformerGlobalIdentifier["core/modal_delete_cancel"]),"function"==typeof _systemImportTransformerGlobalIdentifier.define&&_systemImportTransformerGlobalIdentifier.define.amd?new Promise((function(resolve,reject){_systemImportTransformerGlobalIdentifier.require(["core/modal_events"],resolve,reject)})):"undefined"!=typeof module&&module.exports&&"undefined"!=typeof require||"undefined"!=typeof module&&module.component&&_systemImportTransformerGlobalIdentifier.require&&"component"===_systemImportTransformerGlobalIdentifier.require.loader?Promise.resolve(require("core/modal_events")):Promise.resolve(_systemImportTransformerGlobalIdentifier["core/modal_events"])]),modal=await DeleteCancelModal.create({title:title,body:question,buttons:{delete:deleteLabel},removeOnClose:!0,show:!0});return modal.getRoot().on(ModalEvents.delete,deleteCallback),modal.getRoot().on(ModalEvents.cancel,cancelCallback),modal.getRoot().on(ModalEvents.hidden,(()=>null==triggerElement?void 0:triggerElement.focus())),pendingPromise.resolve(),modal};_exports.deleteCancel=deleteCancel;const saveCancelPromise=function(title,question,saveLabel){let{triggerElement:triggerElement=null}=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};return new Promise(((resolve,reject)=>{saveCancel(title,question,saveLabel,resolve,reject,{triggerElement:triggerElement})}))};_exports.saveCancelPromise=saveCancelPromise;const deleteCancelPromise=function(title,question,deleteLabel){let{triggerElement:triggerElement=null}=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};return new Promise(((resolve,reject)=>{deleteCancel(title,question,deleteLabel,resolve,reject,{triggerElement:triggerElement})}))};_exports.deleteCancelPromise=deleteCancelPromise;const exception=async ex=>{const pendingPromise=new _pending.default("core/notification:displayException");if(ex.stack||(ex.stack=""),ex.debuginfo&&(ex.stack+=ex.debuginfo+"\n"),!ex.backtrace&&ex.stacktrace&&(ex.backtrace=ex.stacktrace),ex.backtrace){ex.stack+=ex.backtrace;const ln=ex.backtrace.match(/line ([^ ]*) of/),fn=ex.backtrace.match(/ of ([^:]*): /);ln&&ln[1]&&(ex.lineNumber=ln[1]),fn&&fn[1]&&(ex.fileName=fn[1],ex.fileName.length>30&&(ex.fileName="..."+ex.fileName.substr(ex.fileName.length-27)))}void 0===ex.name&&ex.errorcode&&(ex.name=ex.errorcode);(await("function"==typeof _systemImportTransformerGlobalIdentifier.define&&_systemImportTransformerGlobalIdentifier.define.amd?new Promise((function(resolve,reject){_systemImportTransformerGlobalIdentifier.require(["core/yui"],resolve,reject)})):"undefined"!=typeof module&&module.exports&&"undefined"!=typeof require||"undefined"!=typeof module&&module.component&&_systemImportTransformerGlobalIdentifier.require&&"component"===_systemImportTransformerGlobalIdentifier.require.loader?Promise.resolve(require("core/yui")):Promise.resolve(_systemImportTransformerGlobalIdentifier["core/yui"]))).use("moodle-core-notification-exception",(function(){new M.core.exception(ex).show(),pendingPromise.resolve()}))};_exports.exception=exception;const init=(contextId,notificationList)=>{currentContextId=contextId,(()=>{if(getNotificationRegion())return!1;const newRegion=document.createElement("span");newRegion.id="user-notifications",Selectors.fallbackRegionParents.some((selector=>{const targetRegion=document.querySelector(selector);return!!targetRegion&&(targetRegion.prepend(newRegion),!0)}))})(),addNotifications(notificationList)};_exports.init=init;var _default={init:init,fetchNotifications:fetchNotifications,addNotification:addNotification,alert:alert,confirm:confirm,saveCancel:saveCancel,saveCancelPromise:saveCancelPromise,deleteCancelPromise:deleteCancelPromise,exception:exception};return _exports.default=_default,_exports.default})); //# sourceMappingURL=notification.min.js.map \ No newline at end of file diff --git a/lib/amd/build/notification.min.js.map b/lib/amd/build/notification.min.js.map index bf5e49c6424..65aef949db3 100644 --- a/lib/amd/build/notification.min.js.map +++ b/lib/amd/build/notification.min.js.map @@ -1 +1 @@ -{"version":3,"file":"notification.min.js","sources":["../src/notification.js"],"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 * Notification manager for in-page notifications in Moodle.\n *\n * @module core/notification\n * @copyright 2015 Damyon Wiese \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 2.9\n */\nimport Pending from 'core/pending';\nimport Log from 'core/log';\n\nlet currentContextId = M.cfg.contextid;\n\nconst notificationTypes = {\n success: 'core/notification_success',\n info: 'core/notification_info',\n warning: 'core/notification_warning',\n error: 'core/notification_error',\n};\n\nconst notificationRegionId = 'user-notifications';\n\nconst Selectors = {\n notificationRegion: `#${notificationRegionId}`,\n fallbackRegionParents: [\n '#region-main',\n '[role=\"main\"]',\n 'body',\n ],\n};\n\nconst setupTargetRegion = () => {\n let targetRegion = getNotificationRegion();\n if (targetRegion) {\n return false;\n }\n\n const newRegion = document.createElement('span');\n newRegion.id = notificationRegionId;\n\n return Selectors.fallbackRegionParents.some(selector => {\n const targetRegion = document.querySelector(selector);\n\n if (targetRegion) {\n targetRegion.prepend(newRegion);\n return true;\n }\n\n return false;\n });\n};\n\n/**\n * A notification object displayed to a user.\n *\n * @typedef {Object} Notification\n * @property {string} message The body of the notification\n * @property {string} type The type of notification to add (error, warning, info, success).\n * @property {Boolean} closebutton Whether to show the close button.\n * @property {Boolean} announce Whether to announce to screen readers.\n */\n\n/**\n * Poll the server for any new notifications.\n *\n * @method\n * @returns {Promise}\n */\nexport const fetchNotifications = async() => {\n const Ajax = await import('core/ajax');\n\n return Ajax.call([{\n methodname: 'core_fetch_notifications',\n args: {\n contextid: currentContextId\n }\n }])[0]\n .then(addNotifications);\n};\n\n/**\n * Add all of the supplied notifications.\n *\n * @method\n * @param {Notification[]} notifications The list of notificaitons\n * @returns {Promise}\n */\nconst addNotifications = notifications => {\n if (!notifications.length) {\n return Promise.resolve();\n }\n\n const pendingPromise = new Pending('core/notification:addNotifications');\n notifications.forEach(notification => renderNotification(notification.template, notification.variables));\n\n return pendingPromise.resolve();\n};\n\n/**\n * Add a notification to the page.\n *\n * Note: This does not cause the notification to be added to the session.\n *\n * @method\n * @param {Notification} notification The notification to add.\n * @returns {Promise}\n */\nexport const addNotification = notification => {\n const pendingPromise = new Pending('core/notification:addNotifications');\n\n let template = notificationTypes.error;\n\n notification = {\n closebutton: true,\n announce: true,\n type: 'error',\n ...notification,\n };\n\n if (notification.template) {\n template = notification.template;\n delete notification.template;\n } else if (notification.type) {\n if (typeof notificationTypes[notification.type] !== 'undefined') {\n template = notificationTypes[notification.type];\n }\n delete notification.type;\n }\n\n return renderNotification(template, notification)\n .then(pendingPromise.resolve);\n};\n\nconst renderNotification = async(template, variables) => {\n if (typeof variables.message === 'undefined' || !variables.message) {\n Log.debug('Notification received without content. Skipping.');\n return;\n }\n\n const pendingPromise = new Pending('core/notification:renderNotification');\n const Templates = await import('core/templates');\n\n Templates.renderForPromise(template, variables)\n .then(({html, js = ''}) => {\n Templates.prependNodeContents(getNotificationRegion(), html, js);\n\n return;\n })\n .then(pendingPromise.resolve)\n .catch(exception);\n};\n\nconst getNotificationRegion = () => document.querySelector(Selectors.notificationRegion);\n\n/**\n * Alert dialogue.\n *\n * @method\n * @param {String|Promise} title\n * @param {String|Promise} message\n * @param {String|Promise} cancelText\n * @returns {Promise}\n */\nexport const alert = async(title, message, cancelText) => {\n var pendingPromise = new Pending('core/notification:alert');\n\n const ModalFactory = await import('core/modal_factory');\n\n return ModalFactory.create({\n type: ModalFactory.types.ALERT,\n body: message,\n title: title,\n buttons: {\n cancel: cancelText,\n },\n removeOnClose: true,\n })\n .then(function(modal) {\n modal.show();\n\n pendingPromise.resolve();\n return modal;\n });\n};\n\n/**\n * The confirm has now been replaced with a save and cancel dialogue.\n *\n * @method\n * @param {String|Promise} title\n * @param {String|Promise} question\n * @param {String|Promise} saveLabel\n * @param {String|Promise} noLabel\n * @param {String|Promise} saveCallback\n * @param {String|Promise} cancelCallback\n * @returns {Promise}\n */\nexport const confirm = (title, question, saveLabel, noLabel, saveCallback, cancelCallback) =>\n saveCancel(title, question, saveLabel, saveCallback, cancelCallback);\n\n/**\n * The Save and Cancel dialogue helper.\n *\n * @method\n * @param {String|Promise} title\n * @param {String|Promise} question\n * @param {String|Promise} saveLabel\n * @param {String|Promise} saveCallback\n * @param {String|Promise} cancelCallback\n * @param {Object} options\n * @param {HTMLElement} [options.triggerElement=null] The element that triggered the modal (will receive the focus after hidden)\n * @returns {Promise}\n */\nexport const saveCancel = async(title, question, saveLabel, saveCallback, cancelCallback, {\n triggerElement = null,\n} = {}) => {\n const pendingPromise = new Pending('core/notification:confirm');\n\n const [\n ModalFactory,\n ModalEvents,\n ] = await Promise.all([\n import('core/modal_factory'),\n import('core/modal_events'),\n ]);\n\n return ModalFactory.create({\n type: ModalFactory.types.SAVE_CANCEL,\n title: title,\n body: question,\n buttons: {\n // Note: The noLabel is no longer supported.\n save: saveLabel,\n },\n removeOnClose: true,\n })\n .then(function(modal) {\n modal.show();\n\n modal.getRoot().on(ModalEvents.save, saveCallback);\n modal.getRoot().on(ModalEvents.cancel, cancelCallback);\n modal.getRoot().on(ModalEvents.hidden, () => triggerElement?.focus());\n pendingPromise.resolve();\n\n return modal;\n });\n};\n\n/**\n * The Delete and Cancel dialogue helper.\n *\n * @method\n * @param {String|Promise} title\n * @param {String|Promise} question\n * @param {String|Promise} deleteLabel\n * @param {String|Promise} deleteCallback\n * @param {String|Promise} cancelCallback\n * @param {Object} options\n * @param {HTMLElement} [options.triggerElement=null] The element that triggered the modal (will receive the focus after hidden)\n * @returns {Promise}\n */\nexport const deleteCancel = async(title, question, deleteLabel, deleteCallback, cancelCallback, {\n triggerElement = null,\n} = {}) => {\n const pendingPromise = new Pending('core/notification:confirm');\n\n const [\n ModalFactory,\n ModalEvents,\n ] = await Promise.all([\n import('core/modal_factory'),\n import('core/modal_events'),\n ]);\n\n return ModalFactory.create({\n type: ModalFactory.types.DELETE_CANCEL,\n title: title,\n body: question,\n buttons: {\n 'delete': deleteLabel\n },\n removeOnClose: true,\n })\n .then(function(modal) {\n modal.show();\n\n modal.getRoot().on(ModalEvents.delete, deleteCallback);\n modal.getRoot().on(ModalEvents.cancel, cancelCallback);\n modal.getRoot().on(ModalEvents.hidden, () => triggerElement?.focus());\n pendingPromise.resolve();\n\n return modal;\n });\n};\n\n\n/**\n * Add all of the supplied notifications.\n *\n * @param {Promise|String} title The header of the modal\n * @param {Promise|String} question What do we want the user to confirm\n * @param {Promise|String} saveLabel The modal action link text\n * @param {Object} options\n * @param {HTMLElement} [options.triggerElement=null] The element that triggered the modal (will receive the focus after hidden)\n * @return {Promise}\n */\nexport const saveCancelPromise = (title, question, saveLabel, {\n triggerElement = null,\n} = {}) => new Promise((resolve, reject) => {\n saveCancel(title, question, saveLabel, resolve, reject, {triggerElement});\n});\n\n/**\n * Add all of the supplied notifications.\n *\n * @param {Promise|String} title The header of the modal\n * @param {Promise|String} question What do we want the user to confirm\n * @param {Promise|String} deleteLabel The modal action link text\n * @param {Object} options\n * @param {HTMLElement} [options.triggerElement=null] The element that triggered the modal (will receive the focus after hidden)\n * @return {Promise}\n */\nexport const deleteCancelPromise = (title, question, deleteLabel, {\n triggerElement = null,\n} = {}) => new Promise((resolve, reject) => {\n deleteCancel(title, question, deleteLabel, resolve, reject, {triggerElement});\n});\n\n/**\n * Wrap M.core.exception.\n *\n * @method\n * @param {Error} ex\n */\nexport const exception = async ex => {\n const pendingPromise = new Pending('core/notification:displayException');\n\n // Fudge some parameters.\n if (!ex.stack) {\n ex.stack = '';\n }\n\n if (ex.debuginfo) {\n ex.stack += ex.debuginfo + '\\n';\n }\n\n if (!ex.backtrace && ex.stacktrace) {\n ex.backtrace = ex.stacktrace;\n }\n\n if (ex.backtrace) {\n ex.stack += ex.backtrace;\n const ln = ex.backtrace.match(/line ([^ ]*) of/);\n const fn = ex.backtrace.match(/ of ([^:]*): /);\n if (ln && ln[1]) {\n ex.lineNumber = ln[1];\n }\n if (fn && fn[1]) {\n ex.fileName = fn[1];\n if (ex.fileName.length > 30) {\n ex.fileName = '...' + ex.fileName.substr(ex.fileName.length - 27);\n }\n }\n }\n\n if (typeof ex.name === 'undefined' && ex.errorcode) {\n ex.name = ex.errorcode;\n }\n\n const Y = await import('core/yui');\n Y.use('moodle-core-notification-exception', function() {\n var modal = new M.core.exception(ex);\n\n modal.show();\n\n pendingPromise.resolve();\n });\n};\n\n/**\n * Initialise the page for the suppled context, and displaying the supplied notifications.\n *\n * @method\n * @param {Number} contextId\n * @param {Notification[]} notificationList\n */\nexport const init = (contextId, notificationList) => {\n currentContextId = contextId;\n\n // Setup the message target region if it isn't setup already.\n setupTargetRegion();\n\n // Add provided notifications.\n addNotifications(notificationList);\n};\n\n// To maintain backwards compatability we export default here.\nexport default {\n init,\n fetchNotifications,\n addNotification,\n alert,\n confirm,\n saveCancel,\n saveCancelPromise,\n deleteCancelPromise,\n exception,\n};\n"],"names":["currentContextId","M","cfg","contextid","notificationTypes","success","info","warning","error","Selectors","notificationRegion","fallbackRegionParents","fetchNotifications","async","call","methodname","args","then","addNotifications","notifications","length","Promise","resolve","pendingPromise","Pending","forEach","notification","renderNotification","template","variables","addNotification","closebutton","announce","type","message","debug","Templates","renderForPromise","_ref","html","js","prependNodeContents","getNotificationRegion","catch","exception","document","querySelector","alert","title","cancelText","ModalFactory","create","types","ALERT","body","buttons","cancel","removeOnClose","modal","show","confirm","question","saveLabel","noLabel","saveCallback","cancelCallback","saveCancel","triggerElement","ModalEvents","all","SAVE_CANCEL","save","getRoot","on","hidden","focus","deleteCancel","deleteLabel","deleteCallback","DELETE_CANCEL","delete","saveCancelPromise","reject","deleteCancelPromise","ex","stack","debuginfo","backtrace","stacktrace","ln","match","fn","lineNumber","fileName","substr","name","errorcode","use","core","init","contextId","notificationList","newRegion","createElement","id","some","selector","targetRegion","prepend","setupTargetRegion"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"notification.min.js","sources":["../src/notification.js"],"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 * Notification manager for in-page notifications in Moodle.\n *\n * @module core/notification\n * @copyright 2015 Damyon Wiese \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 2.9\n */\nimport Pending from 'core/pending';\nimport Log from 'core/log';\n\nlet currentContextId = M.cfg.contextid;\n\nconst notificationTypes = {\n success: 'core/notification_success',\n info: 'core/notification_info',\n warning: 'core/notification_warning',\n error: 'core/notification_error',\n};\n\nconst notificationRegionId = 'user-notifications';\n\nconst Selectors = {\n notificationRegion: `#${notificationRegionId}`,\n fallbackRegionParents: [\n '#region-main',\n '[role=\"main\"]',\n 'body',\n ],\n};\n\nconst setupTargetRegion = () => {\n let targetRegion = getNotificationRegion();\n if (targetRegion) {\n return false;\n }\n\n const newRegion = document.createElement('span');\n newRegion.id = notificationRegionId;\n\n return Selectors.fallbackRegionParents.some(selector => {\n const targetRegion = document.querySelector(selector);\n\n if (targetRegion) {\n targetRegion.prepend(newRegion);\n return true;\n }\n\n return false;\n });\n};\n\n/**\n * A notification object displayed to a user.\n *\n * @typedef {Object} Notification\n * @property {string} message The body of the notification\n * @property {string} type The type of notification to add (error, warning, info, success).\n * @property {Boolean} closebutton Whether to show the close button.\n * @property {Boolean} announce Whether to announce to screen readers.\n */\n\n/**\n * Poll the server for any new notifications.\n *\n * @method\n * @returns {Promise}\n */\nexport const fetchNotifications = async() => {\n const Ajax = await import('core/ajax');\n\n return Ajax.call([{\n methodname: 'core_fetch_notifications',\n args: {\n contextid: currentContextId\n }\n }])[0]\n .then(addNotifications);\n};\n\n/**\n * Add all of the supplied notifications.\n *\n * @method\n * @param {Notification[]} notifications The list of notificaitons\n * @returns {Promise}\n */\nconst addNotifications = notifications => {\n if (!notifications.length) {\n return Promise.resolve();\n }\n\n const pendingPromise = new Pending('core/notification:addNotifications');\n notifications.forEach(notification => renderNotification(notification.template, notification.variables));\n\n return pendingPromise.resolve();\n};\n\n/**\n * Add a notification to the page.\n *\n * Note: This does not cause the notification to be added to the session.\n *\n * @method\n * @param {Notification} notification The notification to add.\n * @returns {Promise}\n */\nexport const addNotification = notification => {\n const pendingPromise = new Pending('core/notification:addNotifications');\n\n let template = notificationTypes.error;\n\n notification = {\n closebutton: true,\n announce: true,\n type: 'error',\n ...notification,\n };\n\n if (notification.template) {\n template = notification.template;\n delete notification.template;\n } else if (notification.type) {\n if (typeof notificationTypes[notification.type] !== 'undefined') {\n template = notificationTypes[notification.type];\n }\n delete notification.type;\n }\n\n return renderNotification(template, notification)\n .then(pendingPromise.resolve);\n};\n\nconst renderNotification = async(template, variables) => {\n if (typeof variables.message === 'undefined' || !variables.message) {\n Log.debug('Notification received without content. Skipping.');\n return;\n }\n\n const pendingPromise = new Pending('core/notification:renderNotification');\n const Templates = await import('core/templates');\n\n Templates.renderForPromise(template, variables)\n .then(({html, js = ''}) => {\n Templates.prependNodeContents(getNotificationRegion(), html, js);\n\n return;\n })\n .then(pendingPromise.resolve)\n .catch(exception);\n};\n\nconst getNotificationRegion = () => document.querySelector(Selectors.notificationRegion);\n\n/**\n * Alert dialogue.\n *\n * @method\n * @param {String|Promise} title\n * @param {String|Promise} message\n * @param {String|Promise} cancelText\n * @returns {Promise}\n */\nexport const alert = async(title, message, cancelText) => {\n var pendingPromise = new Pending('core/notification:alert');\n\n const AlertModal = await import('core/local/modal/alert');\n\n const modal = await AlertModal.create({\n body: message,\n title: title,\n buttons: {\n cancel: cancelText,\n },\n removeOnClose: true,\n show: true,\n });\n pendingPromise.resolve();\n return modal;\n};\n\n/**\n * The confirm has now been replaced with a save and cancel dialogue.\n *\n * @method\n * @param {String|Promise} title\n * @param {String|Promise} question\n * @param {String|Promise} saveLabel\n * @param {String|Promise} noLabel\n * @param {String|Promise} saveCallback\n * @param {String|Promise} cancelCallback\n * @returns {Promise}\n */\nexport const confirm = (title, question, saveLabel, noLabel, saveCallback, cancelCallback) =>\n saveCancel(title, question, saveLabel, saveCallback, cancelCallback);\n\n/**\n * The Save and Cancel dialogue helper.\n *\n * @method\n * @param {String|Promise} title\n * @param {String|Promise} question\n * @param {String|Promise} saveLabel\n * @param {String|Promise} saveCallback\n * @param {String|Promise} cancelCallback\n * @param {Object} options\n * @param {HTMLElement} [options.triggerElement=null] The element that triggered the modal (will receive the focus after hidden)\n * @returns {Promise}\n */\nexport const saveCancel = async(title, question, saveLabel, saveCallback, cancelCallback, {\n triggerElement = null,\n} = {}) => {\n const pendingPromise = new Pending('core/notification:confirm');\n\n const [\n SaveCancelModal,\n ModalEvents,\n ] = await Promise.all([\n import('core/modal_save_cancel'),\n import('core/modal_events'),\n ]);\n\n const modal = await SaveCancelModal.create({\n title,\n body: question,\n buttons: {\n // Note: The noLabel is no longer supported.\n save: saveLabel,\n },\n removeOnClose: true,\n show: true,\n });\n modal.getRoot().on(ModalEvents.save, saveCallback);\n modal.getRoot().on(ModalEvents.cancel, cancelCallback);\n modal.getRoot().on(ModalEvents.hidden, () => triggerElement?.focus());\n pendingPromise.resolve();\n\n return modal;\n};\n\n/**\n * The Delete and Cancel dialogue helper.\n *\n * @method\n * @param {String|Promise} title\n * @param {String|Promise} question\n * @param {String|Promise} deleteLabel\n * @param {String|Promise} deleteCallback\n * @param {String|Promise} cancelCallback\n * @param {Object} options\n * @param {HTMLElement} [options.triggerElement=null] The element that triggered the modal (will receive the focus after hidden)\n * @returns {Promise}\n */\nexport const deleteCancel = async(title, question, deleteLabel, deleteCallback, cancelCallback, {\n triggerElement = null,\n} = {}) => {\n const pendingPromise = new Pending('core/notification:confirm');\n\n const [\n DeleteCancelModal,\n ModalEvents,\n ] = await Promise.all([\n import('core/modal_delete_cancel'),\n import('core/modal_events'),\n ]);\n\n const modal = await DeleteCancelModal.create({\n title: title,\n body: question,\n buttons: {\n 'delete': deleteLabel\n },\n removeOnClose: true,\n show: true,\n });\n modal.getRoot().on(ModalEvents.delete, deleteCallback);\n modal.getRoot().on(ModalEvents.cancel, cancelCallback);\n modal.getRoot().on(ModalEvents.hidden, () => triggerElement?.focus());\n pendingPromise.resolve();\n\n return modal;\n};\n\n\n/**\n * Add all of the supplied notifications.\n *\n * @param {Promise|String} title The header of the modal\n * @param {Promise|String} question What do we want the user to confirm\n * @param {Promise|String} saveLabel The modal action link text\n * @param {Object} options\n * @param {HTMLElement} [options.triggerElement=null] The element that triggered the modal (will receive the focus after hidden)\n * @return {Promise}\n */\nexport const saveCancelPromise = (title, question, saveLabel, {\n triggerElement = null,\n} = {}) => new Promise((resolve, reject) => {\n saveCancel(title, question, saveLabel, resolve, reject, {triggerElement});\n});\n\n/**\n * Add all of the supplied notifications.\n *\n * @param {Promise|String} title The header of the modal\n * @param {Promise|String} question What do we want the user to confirm\n * @param {Promise|String} deleteLabel The modal action link text\n * @param {Object} options\n * @param {HTMLElement} [options.triggerElement=null] The element that triggered the modal (will receive the focus after hidden)\n * @return {Promise}\n */\nexport const deleteCancelPromise = (title, question, deleteLabel, {\n triggerElement = null,\n} = {}) => new Promise((resolve, reject) => {\n deleteCancel(title, question, deleteLabel, resolve, reject, {triggerElement});\n});\n\n/**\n * Wrap M.core.exception.\n *\n * @method\n * @param {Error} ex\n */\nexport const exception = async ex => {\n const pendingPromise = new Pending('core/notification:displayException');\n\n // Fudge some parameters.\n if (!ex.stack) {\n ex.stack = '';\n }\n\n if (ex.debuginfo) {\n ex.stack += ex.debuginfo + '\\n';\n }\n\n if (!ex.backtrace && ex.stacktrace) {\n ex.backtrace = ex.stacktrace;\n }\n\n if (ex.backtrace) {\n ex.stack += ex.backtrace;\n const ln = ex.backtrace.match(/line ([^ ]*) of/);\n const fn = ex.backtrace.match(/ of ([^:]*): /);\n if (ln && ln[1]) {\n ex.lineNumber = ln[1];\n }\n if (fn && fn[1]) {\n ex.fileName = fn[1];\n if (ex.fileName.length > 30) {\n ex.fileName = '...' + ex.fileName.substr(ex.fileName.length - 27);\n }\n }\n }\n\n if (typeof ex.name === 'undefined' && ex.errorcode) {\n ex.name = ex.errorcode;\n }\n\n const Y = await import('core/yui');\n Y.use('moodle-core-notification-exception', function() {\n var modal = new M.core.exception(ex);\n\n modal.show();\n\n pendingPromise.resolve();\n });\n};\n\n/**\n * Initialise the page for the suppled context, and displaying the supplied notifications.\n *\n * @method\n * @param {Number} contextId\n * @param {Notification[]} notificationList\n */\nexport const init = (contextId, notificationList) => {\n currentContextId = contextId;\n\n // Setup the message target region if it isn't setup already.\n setupTargetRegion();\n\n // Add provided notifications.\n addNotifications(notificationList);\n};\n\n// To maintain backwards compatability we export default here.\nexport default {\n init,\n fetchNotifications,\n addNotification,\n alert,\n confirm,\n saveCancel,\n saveCancelPromise,\n deleteCancelPromise,\n exception,\n};\n"],"names":["currentContextId","M","cfg","contextid","notificationTypes","success","info","warning","error","Selectors","notificationRegion","fallbackRegionParents","fetchNotifications","async","call","methodname","args","then","addNotifications","notifications","length","Promise","resolve","pendingPromise","Pending","forEach","notification","renderNotification","template","variables","addNotification","closebutton","announce","type","message","debug","Templates","renderForPromise","_ref","html","js","prependNodeContents","getNotificationRegion","catch","exception","document","querySelector","alert","title","cancelText","AlertModal","modal","create","body","buttons","cancel","removeOnClose","show","confirm","question","saveLabel","noLabel","saveCallback","cancelCallback","saveCancel","triggerElement","SaveCancelModal","ModalEvents","all","save","getRoot","on","hidden","focus","deleteCancel","deleteLabel","deleteCallback","DeleteCancelModal","delete","saveCancelPromise","reject","deleteCancelPromise","ex","stack","debuginfo","backtrace","stacktrace","ln","match","fn","lineNumber","fileName","substr","name","errorcode","use","core","init","contextId","notificationList","newRegion","createElement","id","some","selector","targetRegion","prepend","setupTargetRegion"],"mappings":"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"} \ No newline at end of file diff --git a/lib/amd/build/sortable_list.min.js b/lib/amd/build/sortable_list.min.js index 9f2ac1467c0..438887ecbee 100644 --- a/lib/amd/build/sortable_list.min.js +++ b/lib/amd/build/sortable_list.min.js @@ -43,6 +43,6 @@ * @copyright 2018 Marina Glancy * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -define("core/sortable_list",["jquery","core/log","core/autoscroll","core/str","core/modal_factory","core/modal_events","core/notification"],(function($,log,autoScroll,str,ModalFactory,ModalEvents,Notification){var defaultParameters={targetListSelector:null,moveHandlerSelector:"[data-drag-type=move]",isHorizontal:!1,autoScroll:!0},CSS_keyboardDragClass="dragdrop-keyboard-drag",CSS_isDraggedClass="sortable-list-is-dragged",CSS_currentPositionClass="sortable-list-current-position",CSS_targetListClass="sortable-list-target",CSS_overElementClass="sortable-list-over-element",registerNotPassiveListeners=function(eventname){return{setup:function(x,ns,handle){return!!ns.includes("notPassive")&&(this.addEventListener(eventname,handle,{passive:!1}),!0)}}};(function(){var options,passivesupported=!1;try{options=Object.defineProperty({},"passive",{get:function(){passivesupported=!0}}),document.addEventListener("testpassiveeventoptions",options,options),document.removeEventListener("testpassiveeventoptions",options,options)}catch(err){passivesupported=!1}return passivesupported})&&($.event.special.touchstart=registerNotPassiveListeners("touchstart"),$.event.special.touchmove=registerNotPassiveListeners("touchmove"),$.event.special.touchend=registerNotPassiveListeners("touchend"));var SortableList=function(root,config){this.info=null,this.proxy=null,this.proxyDelta=null,this.dragCounter=0,this.lastEvent=null,this.config=$.extend({},defaultParameters,config||{}),this.config.listSelector=root,this.config.targetListSelector||(this.config.targetListSelector=root),"object"==typeof this.config.listSelector?$(this.config.listSelector).on("mousedown touchstart.notPassive",$.proxy(this.dragStartHandler,this)):$("body").on("mousedown touchstart.notPassive",this.config.listSelector,$.proxy(this.dragStartHandler,this)),null!==this.config.moveHandlerSelector&&$("body").on("click keypress",this.config.moveHandlerSelector,$.proxy(this.clickHandler,this))};return SortableList.EVENTS={DRAGSTART:"sortablelist-dragstart",DRAG:"sortablelist-drag",DROP:"sortablelist-drop",DRAGEND:"sortablelist-dragend"},SortableList.prototype.resetDraggedClasses=function(){var classes=[CSS_isDraggedClass,CSS_currentPositionClass,CSS_overElementClass,CSS_targetListClass];for(var i in classes)$("."+classes[i]).removeClass(classes[i]);this.proxy&&(this.proxy.remove(),this.proxy=$())},SortableList.prototype.calculatePositionOnPage=function(evt){if(evt.originalEvent&&evt.originalEvent.touches&&void 0!==evt.originalEvent.touches[0]){var touch=evt.originalEvent.touches[0];evt.pageX=touch.pageX,evt.pageY=touch.pageY}void 0===evt.pageX?(evt.pageX=this.lastEvent.pageX,evt.pageY=this.lastEvent.pageY):this.lastEvent=evt,void 0===evt.clientX&&(evt.clientX=Math.round(evt.pageX-$(window).scrollLeft()),evt.clientY=Math.round(evt.pageY-$(window).scrollTop()))},SortableList.prototype.dragStartHandler=function(evt){if(null!==this.info){if("click"===this.info.type||"touchend"===this.info.type)return;this.moveElement(this.info.sourceList,this.info.sourceNextElement),this.finishDragging()}if("mousedown"!==evt.type||1===evt.which){this.calculatePositionOnPage(evt);var movedElement=$(evt.target).closest($(evt.currentTarget).children());if(movedElement.length&&(null===this.config.moveHandlerSelector||$(evt.target).closest(this.config.moveHandlerSelector,movedElement).length)){evt.stopPropagation(),evt.preventDefault(),this.dragCounter++,this.info={element:movedElement,sourceNextElement:movedElement.next(),sourceList:movedElement.parent(),targetNextElement:movedElement.next(),targetList:movedElement.parent(),type:evt.type,dropped:!1,startX:evt.pageX,startY:evt.pageY,startTime:(new Date).getTime()},$(this.config.targetListSelector).addClass(CSS_targetListClass);var offset=movedElement.offset();movedElement.addClass(CSS_currentPositionClass),this.proxyDelta={x:offset.left-evt.pageX,y:offset.top-evt.pageY},this.proxy=$();var thisDragCounter=this.dragCounter;setTimeout($.proxy((function(){null!==this.info&&"click"!==this.info.type&&"keypress"!==this.info.type&&this.dragCounter===thisDragCounter&&this.createProxy()}),this),500),$(window).on("mousemove touchmove.notPassive mouseup touchend.notPassive",$.proxy(this.dragHandler,this)),$(window).on("keypress",$.proxy(this.dragcancelHandler,this)),this.config.autoScroll&&autoScroll.start((function(){$(window).trigger("mousemove")})),this.executeCallback(SortableList.EVENTS.DRAGSTART)}}},SortableList.prototype.createProxy=function(){this.proxy=this.info.element.clone(),this.info.sourceList.append(this.proxy),this.proxy.removeAttr("id").removeClass(CSS_currentPositionClass).addClass(CSS_isDraggedClass).css({position:"fixed"}),this.proxy.offset({top:this.proxyDelta.y+this.lastEvent.pageY,left:this.proxyDelta.x+this.lastEvent.pageX})},SortableList.prototype.clickHandler=function(evt){if(("keypress"!==evt.type||13===evt.originalEvent.keyCode||32===evt.originalEvent.keyCode)&&null===this.info){var clickedElement=$(evt.target).closest(this.config.moveHandlerSelector),sourceList=clickedElement.closest(this.config.listSelector),movedElement=clickedElement.closest(sourceList.children());movedElement.length&&(evt.preventDefault(),evt.stopPropagation(),this.dragCounter++,this.info={element:movedElement,sourceNextElement:movedElement.next(),sourceList:sourceList,targetNextElement:movedElement.next(),targetList:sourceList,dropped:!1,type:evt.type,startTime:(new Date).getTime()},this.executeCallback(SortableList.EVENTS.DRAGSTART),this.displayMoveDialogue(clickedElement))}},SortableList.prototype.getPositionInNode=function(pageX,pageY,element){if(!element.length)return null;var rect=element[0].getBoundingClientRect(),y=pageY-(rect.top+window.scrollY),x=pageX-(rect.left+window.scrollX);return x>=-0&&x<=rect.width+0&&y>=-0&&y<=rect.height+0?{x:x,y:y,xRatio:rect.width?x/rect.width:0,yRatio:rect.height?y/rect.height:0}:null},SortableList.prototype.isListHorizontal=function(element){var isHorizontal=this.config.isHorizontal;return!0===isHorizontal||!1===isHorizontal?isHorizontal:isHorizontal(element)},SortableList.prototype.dragHandler=function(evt){evt.preventDefault(),evt.stopPropagation(),this.calculatePositionOnPage(evt),this.proxy.offset({top:-1e3,left:-1e3});var element=$(document.elementFromPoint(evt.clientX,evt.clientY)),mainElement=this.info.element[0],isNotSelf=function(){return this!==mainElement},current=element.closest("."+CSS_targetListClass+" > :not(."+CSS_isDraggedClass+")").filter(isNotSelf),currentList=element.closest("."+CSS_targetListClass),proxy=this.proxy,isNotProxy=function(){return!proxy||!proxy.length||this!==proxy[0]};if($("."+CSS_overElementClass).removeClass(CSS_overElementClass),current.addClass(CSS_overElementClass),this.proxy.offset({top:this.proxyDelta.y+evt.pageY,left:this.proxyDelta.x+evt.pageX}),currentList.length&&!currentList.children().filter(isNotProxy).length)this.moveElement(currentList,$());else if(1===current.length&&!this.info.element.find(current[0]).length){var coordinates=this.getPositionInNode(evt.pageX,evt.pageY,current);if(coordinates){var parent=current.parent(),ratio=this.isListHorizontal(parent)?coordinates.xRatio:coordinates.yRatio,subList=current.find("."+CSS_targetListClass),subListEmpty=!subList.children().filter(isNotProxy).filter(isNotSelf).length;subList.length&&subListEmpty&&ratio>.2&&ratio<.8?this.moveElement(subList,$()):ratio>.5?this.moveElement(parent,current.next().filter(isNotProxy)):this.moveElement(parent,current)}}if("mouseup"===evt.type||"touchend"===evt.type){this.info.endX=evt.pageX,this.info.endY=evt.pageY,this.info.endTime=(new Date).getTime(),this.info.dropped=!0,this.info.positionChanged=this.hasPositionChanged(this.info);var oldinfo=this.info;this.executeCallback(SortableList.EVENTS.DROP),this.finishDragging(),"touchend"===evt.type&&null!==this.config.moveHandlerSelector&&oldinfo.endTime-oldinfo.startTime<500&&!oldinfo.positionChanged&&this.clickHandler(evt)}},SortableList.prototype.hasPositionChanged=function(info){return info.sourceList[0]!==info.targetList[0]||info.sourceNextElement.length!==info.targetNextElement.length||info.sourceNextElement.length&&info.sourceNextElement[0]!==info.targetNextElement[0]},SortableList.prototype.moveElement=function(parentElement,beforeElement){var dragEl=this.info.element;beforeElement.length&&beforeElement[0]===dragEl[0]||parentElement[0]===this.info.targetList[0]&&beforeElement.length===this.info.targetNextElement.length&&beforeElement[0]===this.info.targetNextElement[0]||(beforeElement.length?parentElement[0].insertBefore(dragEl[0],beforeElement[0]):this.proxy&&this.proxy.parent().length&&this.proxy.parent()[0]===parentElement[0]?parentElement[0].insertBefore(dragEl[0],this.proxy[0]):parentElement[0].appendChild(dragEl[0]),this.info.targetList=parentElement,this.info.targetNextElement=beforeElement,this.executeCallback(SortableList.EVENTS.DRAG))},SortableList.prototype.finishDragging=function(){this.resetDraggedClasses(),this.config.autoScroll&&autoScroll.stop(),$(window).off("mousemove touchmove.notPassive mouseup touchend.notPassive",$.proxy(this.dragHandler,this)),$(window).off("keypress",$.proxy(this.dragcancelHandler,this)),this.executeCallback(SortableList.EVENTS.DRAGEND),this.info=null},SortableList.prototype.executeCallback=function(eventName){this.info.element.trigger(eventName,this.info)},SortableList.prototype.dragcancelHandler=function(evt){"keypress"===evt.type&&27===evt.originalEvent.keyCode&&(this.moveElement(this.info.sourceList,this.info.sourceNextElement),this.finishDragging())},SortableList.prototype.getElementName=function(element){return $.Deferred().resolve(element.text())},SortableList.prototype.getDestinationName=function(parentElement,afterElement){return afterElement.length?this.getElementName(afterElement).then((function(name){return str.get_string("movecontentafter","moodle",name)})):str.get_string("movecontenttothetop","moodle")},SortableList.prototype.getMoveDialogueTitle=function(element,handler){return handler.attr("title")?$.Deferred().resolve(handler.attr("title")):this.getElementName(element).then((function(name){return str.get_string("movecontent","moodle",name)}))},SortableList.prototype.getDestinationsList=function(){var addedLists=[],targets=$(this.config.targetListSelector),destinations=$("