From df39831f9a0181c509fd21ca251d35bb9d718552 Mon Sep 17 00:00:00 2001 From: "raja.lmsace@gmail.com" Date: Tue, 9 Apr 2024 21:08:46 +0530 Subject: [PATCH] Moodle plugin CI improved --- .../amd/build/chaptersource.min.js.map | 2 +- actions/notification/classes/actionform.php | 2 +- actions/notification/classes/schedule.php | 2 +- actions/notification/db/install.xml | 4 +- actions/notification/db/upgrade.php | 16 + actions/notification/lib.php | 1 + amd/build/module.min.js | 2 +- amd/build/module.min.js.map | 2 +- amd/build/preset.min.js.map | 2 +- amd/src/module.js | 8 +- amd/src/preset.js | 4 +- classes/helper.php | 2 +- classes/preset.php | 5 +- conditions/enrolment/db/events.php | 1 + conditions/events/classes/conditionform.php | 30 +- conditions/events/db/events.php | 1 - lib/vars.php | 8 +- templates/vars.mustache | 2 +- tests/behat/behat_pulse.php | 12 + tests/behat/pulse_activity_completion.feature | 52 +- tests/behat/pulse_appearance.feature | 38 +- tests/behat/pulse_automation_instance.feature | 83 ++- ...lse_automation_instance_management.feature | 583 +++++++++++++++++- tests/behat/pulse_automation_template.feature | 96 +-- tests/behat/pulse_preset.feature | 16 +- tests/behat/pulse_visibility.feature | 18 +- 26 files changed, 818 insertions(+), 174 deletions(-) diff --git a/actions/notification/amd/build/chaptersource.min.js.map b/actions/notification/amd/build/chaptersource.min.js.map index fe8f460..1b95448 100644 --- a/actions/notification/amd/build/chaptersource.min.js.map +++ b/actions/notification/amd/build/chaptersource.min.js.map @@ -1 +1 @@ -{"version":3,"file":"chaptersource.min.js","sources":["../src/chaptersource.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\r\n//\r\n// Moodle is free software: you can redistribute it and/or modify\r\n// it under the terms of the GNU General Public License as published by\r\n// the Free Software Foundation, either version 3 of the License, or\r\n// (at your option) any later version.\r\n//\r\n// Moodle is distributed in the hope that it will be useful,\r\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n// GNU General Public License for more details.\r\n//\r\n// You should have received a copy of the GNU General Public License\r\n// along with Moodle. If not, see .\r\n\r\n/**\r\n * Frameworks datasource.\r\n *\r\n * This module is compatible with core/form-autocomplete.\r\n *\r\n * @module tool_lp/frameworks_datasource\r\n * @copyright 2016 Frédéric Massart - FMCorz.net\r\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\r\n */\r\n\r\ndefine(['jquery', 'core/ajax', 'core/notification', 'core/modal_factory', 'core/fragment', 'core/str', 'core/modal_events'],\r\n function ($, Ajax, Notification, ModalFactory, Fragment, Str, ModalEvents) {\r\n\r\n const previewModalBody = function (contextID, userid = null) {\r\n\r\n var params;\r\n if (window.tinyMCE !== undefined && window.tinyMCE.get('id_pulsenotification_headercontent_editor')) {\r\n // EditorPlugin = window.tinyMCE;\r\n params = {\r\n contentheader: window.tinyMCE.get('id_pulsenotification_headercontent_editor').getContent(),\r\n contentstatic: window.tinyMCE.get('id_pulsenotification_staticcontent_editor').getContent(),\r\n contentfooter: window.tinyMCE.get('id_pulsenotification_footercontent_editor').getContent(),\r\n userid: userid\r\n };\r\n } else {\r\n // EditorPlugin = document;\r\n params = {\r\n contentheader: document.querySelector('#id_pulsenotification_headercontent_editoreditable').innerHTML,\r\n contentstatic: document.querySelector('#id_pulsenotification_staticcontent_editoreditable').innerHTML,\r\n contentfooter: document.querySelector('#id_pulsenotification_footercontent_editoreditable').innerHTML,\r\n userid: userid\r\n };\r\n }\r\n\r\n var dynamicparams = {};\r\n\r\n if (document.querySelector('[name=pulsenotification_dynamiccontent]') !== null) {\r\n dynamicparams = {\r\n contentdynamic: document.querySelector('[name=pulsenotification_dynamiccontent]').value,\r\n contenttype: document.querySelector('[name=pulsenotification_contenttype]').value,\r\n chapterid: document.querySelector('[name=pulsenotification_chapterid]').value,\r\n contentlength: document.querySelector('[name=pulsenotification_contentlength]').value,\r\n };\r\n }\r\n // Get the form data.\r\n var formData;\r\n var form = document.forms['pulse-automation-template'];\r\n var formdata = new FormData(form);\r\n formdata = new URLSearchParams(formdata).toString();\r\n formData = {\r\n formdata: formdata\r\n };\r\n\r\n var finalParams = { ...params, ...dynamicparams, ...formData };\r\n\r\n return Fragment.loadFragment('pulseaction_notification', 'preview_content', contextID, finalParams);\r\n };\r\n\r\n const previewModal = function (contextID) {\r\n\r\n ModalFactory.create({\r\n title: Str.get_string('preview', 'pulseaction_notification'),\r\n body: previewModalBody(contextID),\r\n large: true,\r\n }).then((modal) => {\r\n modal.show();\r\n\r\n modal.getRoot().on(ModalEvents.bodyRendered, function () {\r\n modal.getRoot().get(0).querySelector('[name=userselector]').addEventListener('change', (e) => {\r\n e.preventDefault();\r\n var target = e.target;\r\n modal.setBody(previewModalBody(contextID, target.value));\r\n });\r\n });\r\n\r\n return;\r\n }).catch();\r\n };\r\n\r\n const notificationModal = function (contextID, instance, userid) {\r\n\r\n var params = {\r\n instanceid: instance,\r\n userid: userid\r\n };\r\n\r\n ModalFactory.create({\r\n title: Str.get_string('preview', 'pulseaction_notification'),\r\n body: Fragment.loadFragment('pulseaction_notification', 'preview_instance_content', contextID, params),\r\n large: true,\r\n }).then((modal) => {\r\n modal.show();\r\n return;\r\n }).catch();\r\n };\r\n\r\n return {\r\n\r\n processResults: function (selector, modules) {\r\n return modules;\r\n },\r\n\r\n transport: function (selector, query, success, failure) {\r\n\r\n var mod = document.querySelector(\"#id_pulsenotification_dynamiccontent\");\r\n\r\n var promise = Ajax.call([{\r\n methodname: 'pulseaction_notification_get_chapters',\r\n args: { mod: mod.value }\r\n }]);\r\n\r\n promise[0].then(function (result) {\r\n success(result);\r\n return;\r\n }).fail(failure);\r\n },\r\n\r\n updateChapter: function (ctxID, contentMods) {\r\n\r\n const SELECTORS = {\r\n chaperType: \"#id_pulsenotification_contenttype\",\r\n mod: \"#id_pulsenotification_dynamiccontent\"\r\n };\r\n\r\n // Disable the content type option for modules other than book and page.\r\n if (contentMods !== null) {\r\n var type = document.querySelector(SELECTORS.chaperType);\r\n document.querySelector(SELECTORS.mod).addEventListener(\"change\", (e) => {\r\n var target = e.currentTarget;\r\n var selected = target.value;\r\n if (contentMods.includes(selected.toString())) {\r\n Array.prototype.find.call(type.options, function (cmid) {\r\n if (cmid.value == '2') {\r\n cmid.disabled = false;\r\n }\r\n });\r\n } else {\r\n Array.prototype.find.call(type.options, function (cmid) {\r\n if (cmid.value == '2') {\r\n cmid.disabled = true;\r\n }\r\n });\r\n }\r\n });\r\n }\r\n\r\n document.querySelector(SELECTORS.chaperType).addEventListener(\"change\", () => resetChapter());\r\n document.querySelector(SELECTORS.mod).addEventListener(\"change\", () => resetChapter());\r\n var chapter = document.querySelector(\"#id_pulsenotification_chapterid\");\r\n\r\n /**\r\n *\r\n */\r\n function resetChapter() {\r\n chapter.innerHTML = '';\r\n chapter.value = '';\r\n var event = new Event('change');\r\n chapter.dispatchEvent(event);\r\n }\r\n },\r\n\r\n previewNotification: function (contextid) {\r\n\r\n var btn = document.querySelector('[name=\"pulsenotification_preview\"]');\r\n\r\n if (btn === null) {\r\n return;\r\n }\r\n\r\n btn.addEventListener('click', function () {\r\n previewModal(contextid);\r\n });\r\n },\r\n\r\n reportModal: function (contextID) {\r\n // View content.\r\n /* var btn = document.querySelectorAll('[data-target=\"view-content\"]');\r\n\r\n if (btn === null) {\r\n return;\r\n }\r\n\r\n btn.forEach((element) => {\r\n element.addEventListener('click', function(e) {\r\n\r\n var target = e.target.closest('a');\r\n\r\n var instance = target.dataset.instanceid;\r\n var userid = target.dataset.userid;\r\n\r\n notificationModal(contextID, instance, userid); // Notification modal.\r\n });\r\n });\r\n */\r\n\r\n document.addEventListener('click', function (e) {\r\n\r\n if (e.target.closest('[data-target=\"view-content\"]') !== null) {\r\n\r\n var target = e.target.closest('a');\r\n\r\n var instance = target.dataset.instanceid;\r\n var userid = target.dataset.userid;\r\n\r\n notificationModal(contextID, instance, userid); // Notification modal.\r\n }\r\n\r\n })\r\n }\r\n };\r\n\r\n });\r\n"],"names":["define","$","Ajax","Notification","ModalFactory","Fragment","Str","ModalEvents","previewModalBody","contextID","userid","params","undefined","window","tinyMCE","get","contentheader","getContent","contentstatic","contentfooter","document","querySelector","innerHTML","formData","dynamicparams","contentdynamic","value","contenttype","chapterid","contentlength","form","forms","formdata","FormData","URLSearchParams","toString","finalParams","loadFragment","processResults","selector","modules","transport","query","success","failure","mod","call","methodname","args","then","result","fail","updateChapter","ctxID","contentMods","SELECTORS","type","addEventListener","e","selected","currentTarget","includes","Array","prototype","find","options","cmid","disabled","resetChapter","chapter","event","Event","dispatchEvent","previewNotification","contextid","btn","create","title","get_string","body","large","modal","show","getRoot","on","bodyRendered","preventDefault","target","setBody","catch","reportModal","closest","instance","dataset","instanceid","notificationModal"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"chaptersource.min.js","sources":["../src/chaptersource.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 * Frameworks datasource.\n *\n * This module is compatible with core/form-autocomplete.\n *\n * @module tool_lp/frameworks_datasource\n * @copyright 2016 Frédéric Massart - FMCorz.net\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine(['jquery', 'core/ajax', 'core/notification', 'core/modal_factory', 'core/fragment', 'core/str', 'core/modal_events'],\n function ($, Ajax, Notification, ModalFactory, Fragment, Str, ModalEvents) {\n\n const previewModalBody = function (contextID, userid = null) {\n\n var params;\n if (window.tinyMCE !== undefined && window.tinyMCE.get('id_pulsenotification_headercontent_editor')) {\n // EditorPlugin = window.tinyMCE;\n params = {\n contentheader: window.tinyMCE.get('id_pulsenotification_headercontent_editor').getContent(),\n contentstatic: window.tinyMCE.get('id_pulsenotification_staticcontent_editor').getContent(),\n contentfooter: window.tinyMCE.get('id_pulsenotification_footercontent_editor').getContent(),\n userid: userid\n };\n } else {\n // EditorPlugin = document;\n params = {\n contentheader: document.querySelector('#id_pulsenotification_headercontent_editoreditable').innerHTML,\n contentstatic: document.querySelector('#id_pulsenotification_staticcontent_editoreditable').innerHTML,\n contentfooter: document.querySelector('#id_pulsenotification_footercontent_editoreditable').innerHTML,\n userid: userid\n };\n }\n\n var dynamicparams = {};\n\n if (document.querySelector('[name=pulsenotification_dynamiccontent]') !== null) {\n dynamicparams = {\n contentdynamic: document.querySelector('[name=pulsenotification_dynamiccontent]').value,\n contenttype: document.querySelector('[name=pulsenotification_contenttype]').value,\n chapterid: document.querySelector('[name=pulsenotification_chapterid]').value,\n contentlength: document.querySelector('[name=pulsenotification_contentlength]').value,\n };\n }\n // Get the form data.\n var formData;\n var form = document.forms['pulse-automation-template'];\n var formdata = new FormData(form);\n formdata = new URLSearchParams(formdata).toString();\n formData = {\n formdata: formdata\n };\n\n var finalParams = { ...params, ...dynamicparams, ...formData };\n\n return Fragment.loadFragment('pulseaction_notification', 'preview_content', contextID, finalParams);\n };\n\n const previewModal = function (contextID) {\n\n ModalFactory.create({\n title: Str.get_string('preview', 'pulseaction_notification'),\n body: previewModalBody(contextID),\n large: true,\n }).then((modal) => {\n modal.show();\n\n modal.getRoot().on(ModalEvents.bodyRendered, function () {\n modal.getRoot().get(0).querySelector('[name=userselector]').addEventListener('change', (e) => {\n e.preventDefault();\n var target = e.target;\n modal.setBody(previewModalBody(contextID, target.value));\n });\n });\n\n return;\n }).catch();\n };\n\n const notificationModal = function (contextID, instance, userid) {\n\n var params = {\n instanceid: instance,\n userid: userid\n };\n\n ModalFactory.create({\n title: Str.get_string('preview', 'pulseaction_notification'),\n body: Fragment.loadFragment('pulseaction_notification', 'preview_instance_content', contextID, params),\n large: true,\n }).then((modal) => {\n modal.show();\n return;\n }).catch();\n };\n\n return {\n\n processResults: function (selector, modules) {\n return modules;\n },\n\n transport: function (selector, query, success, failure) {\n\n var mod = document.querySelector(\"#id_pulsenotification_dynamiccontent\");\n\n var promise = Ajax.call([{\n methodname: 'pulseaction_notification_get_chapters',\n args: { mod: mod.value }\n }]);\n\n promise[0].then(function (result) {\n success(result);\n return;\n }).fail(failure);\n },\n\n updateChapter: function (ctxID, contentMods) {\n\n const SELECTORS = {\n chaperType: \"#id_pulsenotification_contenttype\",\n mod: \"#id_pulsenotification_dynamiccontent\"\n };\n\n // Disable the content type option for modules other than book and page.\n if (contentMods !== null) {\n var type = document.querySelector(SELECTORS.chaperType);\n document.querySelector(SELECTORS.mod).addEventListener(\"change\", (e) => {\n var target = e.currentTarget;\n var selected = target.value;\n if (contentMods.includes(selected.toString())) {\n Array.prototype.find.call(type.options, function (cmid) {\n if (cmid.value == '2') {\n cmid.disabled = false;\n }\n });\n } else {\n Array.prototype.find.call(type.options, function (cmid) {\n if (cmid.value == '2') {\n cmid.disabled = true;\n }\n });\n }\n });\n }\n\n document.querySelector(SELECTORS.chaperType).addEventListener(\"change\", () => resetChapter());\n document.querySelector(SELECTORS.mod).addEventListener(\"change\", () => resetChapter());\n var chapter = document.querySelector(\"#id_pulsenotification_chapterid\");\n\n /**\n *\n */\n function resetChapter() {\n chapter.innerHTML = '';\n chapter.value = '';\n var event = new Event('change');\n chapter.dispatchEvent(event);\n }\n },\n\n previewNotification: function (contextid) {\n\n var btn = document.querySelector('[name=\"pulsenotification_preview\"]');\n\n if (btn === null) {\n return;\n }\n\n btn.addEventListener('click', function () {\n previewModal(contextid);\n });\n },\n\n reportModal: function (contextID) {\n // View content.\n /* var btn = document.querySelectorAll('[data-target=\"view-content\"]');\n\n if (btn === null) {\n return;\n }\n\n btn.forEach((element) => {\n element.addEventListener('click', function(e) {\n\n var target = e.target.closest('a');\n\n var instance = target.dataset.instanceid;\n var userid = target.dataset.userid;\n\n notificationModal(contextID, instance, userid); // Notification modal.\n });\n });\n */\n\n document.addEventListener('click', function (e) {\n\n if (e.target.closest('[data-target=\"view-content\"]') !== null) {\n\n var target = e.target.closest('a');\n\n var instance = target.dataset.instanceid;\n var userid = target.dataset.userid;\n\n notificationModal(contextID, instance, userid); // Notification modal.\n }\n\n })\n }\n };\n\n });\n"],"names":["define","$","Ajax","Notification","ModalFactory","Fragment","Str","ModalEvents","previewModalBody","contextID","userid","params","undefined","window","tinyMCE","get","contentheader","getContent","contentstatic","contentfooter","document","querySelector","innerHTML","formData","dynamicparams","contentdynamic","value","contenttype","chapterid","contentlength","form","forms","formdata","FormData","URLSearchParams","toString","finalParams","loadFragment","processResults","selector","modules","transport","query","success","failure","mod","call","methodname","args","then","result","fail","updateChapter","ctxID","contentMods","SELECTORS","type","addEventListener","e","selected","currentTarget","includes","Array","prototype","find","options","cmid","disabled","resetChapter","chapter","event","Event","dispatchEvent","previewNotification","contextid","btn","create","title","get_string","body","large","modal","show","getRoot","on","bodyRendered","preventDefault","target","setBody","catch","reportModal","closest","instance","dataset","instanceid","notificationModal"],"mappings":"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"} \ No newline at end of file diff --git a/actions/notification/classes/actionform.php b/actions/notification/classes/actionform.php index 787e508..d09c57d 100644 --- a/actions/notification/classes/actionform.php +++ b/actions/notification/classes/actionform.php @@ -805,7 +805,7 @@ public function get_email_placeholders() { * @return array */ public function assignment_data_fields() { - return [ 'Assignment_Extensions']; + return ['Assignment_Extensions']; } /** diff --git a/actions/notification/classes/schedule.php b/actions/notification/classes/schedule.php index 1d0feed..1df27ed 100644 --- a/actions/notification/classes/schedule.php +++ b/actions/notification/classes/schedule.php @@ -319,7 +319,7 @@ protected function get_scheduled_records($userid=null) { WHERE ns.status = :status AND ai.status <> 0 AND active_enrols.activeenrolment <> 0 AND c.visible = 1 - AND c.startdate <= :startdate AND (c.enddate = 0 OR c.enddate >= :enddate) + AND c.startdate <= :startdate AND (c.enddate = 0 OR c.enddate >= :enddate) AND ue.deleted = 0 AND ue.suspended = 0 AND ns.suppressreached = 0 AND ns.scheduletime <= :current_timestamp $userwhere ORDER BY ns.timecreated ASC"; diff --git a/actions/notification/db/install.xml b/actions/notification/db/install.xml index 8a87d2f..b509983 100644 --- a/actions/notification/db/install.xml +++ b/actions/notification/db/install.xml @@ -25,7 +25,7 @@ - + @@ -58,7 +58,7 @@ - + diff --git a/actions/notification/db/upgrade.php b/actions/notification/db/upgrade.php index b1a94b7..38e9682 100644 --- a/actions/notification/db/upgrade.php +++ b/actions/notification/db/upgrade.php @@ -51,5 +51,21 @@ function xmldb_pulseaction_notification_upgrade($oldversion) { $dbman->change_field_precision($temptable, $timemodified); } + // Update the type of dynamic content. + $instable = new xmldb_table('pulseaction_notification'); + $dynamiccontent = new xmldb_field('dynamiccontent', XMLDB_TYPE_INTEGER, '11', null, null, null, null); + // Verify field exists. + if ($dbman->field_exists($instable, $dynamiccontent)) { + // Change the field. + $dbman->change_field_precision($instable, $dynamiccontent); + } + + // Update the templates table dynamiccontent. + $temptable = new xmldb_table('pulseaction_notification_ins'); + if ($dbman->field_exists($temptable, $dynamiccontent)) { + // Change the field. + $dbman->change_field_precision($temptable, $dynamiccontent); + } + return true; } diff --git a/actions/notification/lib.php b/actions/notification/lib.php index d80711e..b0f4597 100644 --- a/actions/notification/lib.php +++ b/actions/notification/lib.php @@ -181,6 +181,7 @@ function pulseaction_notification_output_fragment_preview_content($args) { $selector = html_writer::select($list, 'userselector', $user->id); $data = ['message' => $messagehtml, 'usersselector' => $selector]; + return $OUTPUT->render_from_template('pulseaction_notification/preview', ['data' => $data]); } } diff --git a/amd/build/module.min.js b/amd/build/module.min.js index b401d11..cf8a1a8 100644 --- a/amd/build/module.min.js +++ b/amd/build/module.min.js @@ -7,6 +7,6 @@ * @copyright 2021, bdecent gmbh bdecent.de * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -define("mod_pulse/module",["core_editor/events"],(function(){return{init:function(branch){for(var module=this,templatevars=document.getElementsByClassName("fitem_id_templatevars_editor"),l=0;l{elem.addEventListener("click",(function(e){var target=e.currentTarget;if(branch<="402")var EditorInput=target.querySelector('[id*="_editoreditable"]');else EditorInput=target.querySelector('textarea[id*="_content_editor"]');module.insertCaretActive(EditorInput)}))}));var headertargetNode=document.querySelector("#id_s_mod_pulse_notificationheader");if(null!==headertargetNode){new MutationObserver((function(){if("none"==headertargetNode.style.display){var headeriframe=document.querySelector("#admin-notificationheader iframe").contentDocument;null!==headeriframe&&headeriframe.addEventListener("click",(function(e){var headercontentBody=e.target.querySelector("body");null!==headercontentBody&&headercontentBody.classList.add("insertatcaretactive");var footerBody=document.querySelector("#admin-notificationfooter iframe").contentDocument.querySelector("body");footerBody.classList.contains("insertatcaretactive")&&footerBody.classList.remove("insertatcaretactive")}))}})).observe(headertargetNode,{attributes:!0,childList:!0})}var footertargetNode=document.querySelector("#id_s_mod_pulse_notificationfooter");if(null!==footertargetNode){new MutationObserver((function(){if("none"==footertargetNode.style.display){var footeriframe=document.querySelector("#admin-notificationfooter iframe").contentDocument;null!==footeriframe&&footeriframe.addEventListener("click",(function(e){var footercontentBody=e.target.querySelector("body");null!==footercontentBody&&footercontentBody.classList.add("insertatcaretactive");var headerBody=document.querySelector("#admin-notificationheader iframe").contentDocument.querySelector("body");headerBody.classList.contains("insertatcaretactive")&&headerBody.classList.remove("insertatcaretactive")}))}})).observe(footertargetNode,{attributes:!0,childList:!0})}var targetNode=document.querySelector("textarea[id$=_editor]");if(null!==targetNode){new MutationObserver((function(){"none"==targetNode.style.display&&setTimeout(initIframeListeners,100)})).observe(targetNode,{attributes:!0,childList:!0})}const initIframeListeners=()=>{let iframes=document.querySelectorAll('[data-fieldtype="editor"] iframe');return!(null===iframes||!iframes.length)&&(iframes.forEach((iframe=>{iframe.contentDocument.addEventListener("click",(function(e){var currentFrame=e.target;iframes.forEach((frame=>{var frameElem=frame.contentDocument.querySelector(".insertatcaretactive");null!==frameElem&&frameElem.classList.remove("insertatcaretactive")}));var contentBody=currentFrame.querySelector("body");null!==contentBody&&contentBody.classList.add("insertatcaretactive")}))})),!0)};for(var clickforword=document.getElementsByClassName("clickforword"),i=0;i{const span=document.createElement("span");span.classList="badge badge-info pulse-completion-roles",node.after(span),span.appendChild(node)}))}},insertCaretActive:function(EditorInput){if(null!==EditorInput){for(var caret=document.getElementsByClassName("insertatcaretactive"),j=0;j3===node.nodeType&&node.textContent.trim().length>1))},isSelectionInsideDiv:div=>{const selection=window.getSelection();if(0===selection.rangeCount)return!1;const startNode=selection.getRangeAt(0).startContainer,endNode=selection.getRangeAt(0).endContainer;return div.contains(startNode)&&div.contains(endNode)},insertAtCaret:function(myValue){for(var sel,range,caretelements=document.getElementsByClassName("insertatcaretactive"),n=0;n{elem.addEventListener("click",(function(e){var target=e.currentTarget,EditorInput=branch<="402"?target.querySelector('[id*="_editoreditable"]'):target.querySelector('textarea[id*="_content_editor"]');module.insertCaretActive(EditorInput)}))}));var headertargetNode=document.querySelector("#id_s_mod_pulse_notificationheader");if(null!==headertargetNode){new MutationObserver((function(){if("none"==headertargetNode.style.display){var headeriframe=document.querySelector("#admin-notificationheader iframe").contentDocument;null!==headeriframe&&headeriframe.addEventListener("click",(function(e){var headercontentBody=e.target.querySelector("body");null!==headercontentBody&&headercontentBody.classList.add("insertatcaretactive");var footerBody=document.querySelector("#admin-notificationfooter iframe").contentDocument.querySelector("body");footerBody.classList.contains("insertatcaretactive")&&footerBody.classList.remove("insertatcaretactive")}))}})).observe(headertargetNode,{attributes:!0,childList:!0})}var footertargetNode=document.querySelector("#id_s_mod_pulse_notificationfooter");if(null!==footertargetNode){new MutationObserver((function(){if("none"==footertargetNode.style.display){var footeriframe=document.querySelector("#admin-notificationfooter iframe").contentDocument;null!==footeriframe&&footeriframe.addEventListener("click",(function(e){var footercontentBody=e.target.querySelector("body");null!==footercontentBody&&footercontentBody.classList.add("insertatcaretactive");var headerBody=document.querySelector("#admin-notificationheader iframe").contentDocument.querySelector("body");headerBody.classList.contains("insertatcaretactive")&&headerBody.classList.remove("insertatcaretactive")}))}})).observe(footertargetNode,{attributes:!0,childList:!0})}var targetNode=document.querySelector("textarea[id$=_editor]");if(null!==targetNode){new MutationObserver((function(){"none"==targetNode.style.display&&setTimeout(initIframeListeners,100)})).observe(targetNode,{attributes:!0,childList:!0})}const initIframeListeners=()=>{let iframes=document.querySelectorAll('[data-fieldtype="editor"] iframe');return!(null===iframes||!iframes.length)&&(iframes.forEach((iframe=>{iframe.contentDocument.addEventListener("click",(function(e){var currentFrame=e.target;iframes.forEach((frame=>{var frameElem=frame.contentDocument.querySelector(".insertatcaretactive");null!==frameElem&&frameElem.classList.remove("insertatcaretactive")}));var contentBody=currentFrame.querySelector("body");null!==contentBody&&contentBody.classList.add("insertatcaretactive")}))})),!0)};for(var clickforword=document.getElementsByClassName("clickforword"),i=0;i{const span=document.createElement("span");span.classList="badge badge-info pulse-completion-roles",node.after(span),span.appendChild(node)}))}},insertCaretActive:function(EditorInput){if(null!==EditorInput){for(var caret=document.getElementsByClassName("insertatcaretactive"),j=0;j3===node.nodeType&&node.textContent.trim().length>1))},isSelectionInsideDiv:div=>{const selection=window.getSelection();if(0===selection.rangeCount)return!1;const startNode=selection.getRangeAt(0).startContainer,endNode=selection.getRangeAt(0).endContainer;return div.contains(startNode)&&div.contains(endNode)},insertAtCaret:function(myValue){for(var sel,range,caretelements=document.getElementsByClassName("insertatcaretactive"),n=0;n.\r\n\r\n/**\r\n * Module javascript to place the placeholders.\r\n * Modified version of IOMAD Email template emailvars.\r\n *\r\n * @module mod_pulse/module\r\n * @category Classes - autoloading\r\n * @copyright 2021, bdecent gmbh bdecent.de\r\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\r\n */\r\n\r\ndefine(['core_editor/events'], function() {\r\n\r\n return {\r\n /**\r\n * Setup the classes to editors works with placeholders.\r\n *\r\n * @param {integer} branch\r\n */\r\n init: function(branch) {\r\n var module = this;\r\n\r\n var templatevars = document.getElementsByClassName(\"fitem_id_templatevars_editor\");\r\n for (var l = 0; l < templatevars.length; l++) {\r\n templatevars[l].addEventListener('click', function() {\r\n var EditorInput = document.getElementById('id_pulse_content_editoreditable');\r\n if (EditorInput !== null) {\r\n module.insertCaretActive(EditorInput);\r\n }\r\n });\r\n }\r\n\r\n var notificationheader = document.getElementById('admin-notificationheader');\r\n if (notificationheader !== null) {\r\n notificationheader.addEventListener('click', function() {\r\n var EditorInput = document.getElementById('id_s_mod_pulse_notificationheader_ifr');\r\n module.insertCaretActive(EditorInput);\r\n });\r\n }\r\n\r\n var notificationfooter = document.getElementById('admin-notificationfooter');\r\n if (notificationfooter !== null) {\r\n notificationfooter.addEventListener('click', function() {\r\n var EditorInput = document.getElementById('id_s_mod_pulse_notificationfooter_ifr');\r\n module.insertCaretActive(EditorInput);\r\n });\r\n }\r\n\r\n\r\n templatevars = document.getElementsByClassName(\"fitem_id_templatevars_editor\");\r\n if (templatevars) {\r\n templatevars.forEach((elem) => {\r\n elem.addEventListener('click', function(e) {\r\n var target = e.currentTarget;\r\n if (branch <= \"402\") {\r\n var EditorInput = target.querySelector('[id*=\"_editoreditable\"]');\r\n } else {\r\n var EditorInput = target.querySelector('textarea[id*=\"_content_editor\"]');\r\n }\r\n module.insertCaretActive(EditorInput);\r\n });\r\n });\r\n }\r\n\r\n\r\n var headertargetNode = document.querySelector('#id_s_mod_pulse_notificationheader');\r\n if (headertargetNode !== null) {\r\n let observer = new MutationObserver(function() {\r\n if (headertargetNode.style.display == 'none') {\r\n var headeriframe = document.querySelector('#admin-notificationheader iframe').contentDocument;\r\n if (headeriframe !== null) {\r\n headeriframe.addEventListener('click', function(e) {\r\n var currentFrame = e.target;\r\n var headercontentBody = currentFrame.querySelector('body');\r\n if (headercontentBody !== null) {\r\n headercontentBody.classList.add(\"insertatcaretactive\");\r\n }\r\n\r\n var footer = document.querySelector('#admin-notificationfooter iframe').contentDocument;\r\n var footerBody = footer.querySelector('body');\r\n if (footerBody.classList.contains('insertatcaretactive')) {\r\n footerBody.classList.remove(\"insertatcaretactive\");\r\n }\r\n\r\n });\r\n }\r\n }\r\n });\r\n observer.observe(headertargetNode, {attributes: true, childList: true});\r\n }\r\n\r\n var footertargetNode = document.querySelector('#id_s_mod_pulse_notificationfooter');\r\n if (footertargetNode !== null) {\r\n let observer = new MutationObserver(function() {\r\n if (footertargetNode.style.display == 'none') {\r\n var footeriframe = document.querySelector('#admin-notificationfooter iframe').contentDocument;\r\n if (footeriframe !== null) {\r\n footeriframe.addEventListener('click', function(e) {\r\n var currentFrame = e.target;\r\n var footercontentBody = currentFrame.querySelector('body');\r\n if (footercontentBody !== null) {\r\n footercontentBody.classList.add(\"insertatcaretactive\");\r\n }\r\n\r\n var header = document.querySelector('#admin-notificationheader iframe').contentDocument;\r\n var headerBody = header.querySelector('body');\r\n if (headerBody.classList.contains('insertatcaretactive')) {\r\n headerBody.classList.remove(\"insertatcaretactive\");\r\n }\r\n\r\n });\r\n }\r\n }\r\n });\r\n observer.observe(footertargetNode, {attributes: true, childList: true});\r\n }\r\n\r\n var targetNode = document.querySelector('textarea[id$=_editor]');\r\n\r\n if (targetNode !== null) {\r\n let observer = new MutationObserver(function() {\r\n if (targetNode.style.display == 'none') {\r\n setTimeout(initIframeListeners, 100);\r\n }\r\n });\r\n observer.observe(targetNode, {attributes: true, childList: true});\r\n }\r\n\r\n const initIframeListeners = () => {\r\n\r\n let iframes = document.querySelectorAll('[data-fieldtype=\"editor\"] iframe');\r\n if (iframes === null || !iframes.length) {\r\n return false;\r\n }\r\n iframes.forEach((iframe) => {\r\n iframe.contentDocument.addEventListener('click', function(e) {\r\n var currentFrame = e.target;\r\n iframes.forEach((frame) => {\r\n var frameElem = frame.contentDocument.querySelector(\".insertatcaretactive\");\r\n if (frameElem !== null) {\r\n frameElem.classList.remove(\"insertatcaretactive\");\r\n }\r\n });\r\n\r\n var contentBody = currentFrame.querySelector('body');\r\n if (contentBody !== null) {\r\n contentBody.classList.add(\"insertatcaretactive\");\r\n }\r\n });\r\n });\r\n\r\n return true;\r\n };\r\n\r\n\r\n var clickforword = document.getElementsByClassName('clickforword');\r\n for (var i = 0; i < clickforword.length; i++) {\r\n clickforword[i].addEventListener('click', function(e) {\r\n e.preventDefault(); // To prevent the default behaviour of a tag.\r\n\r\n var content = \"{\" + this.getAttribute('data-text') + \"}\";\r\n let iframes = document.querySelectorAll('[data-fieldtype=\"editor\"] iframe');\r\n\r\n // Copy the placeholder field.\r\n navigator.clipboard.writeText(content);\r\n\r\n if (iframes === null || !iframes.length) {\r\n if (branch <= '402') {\r\n module.insertAtCaret(content);\r\n return true;\r\n } else {\r\n // Header notification editor.\r\n var headerNode = document.querySelector('#admin-notificationheader iframe').contentDocument;\r\n if (headerNode !== null) {\r\n var headercontentBody = headerNode.querySelector(\"body\");\r\n if (headercontentBody.classList.contains(\"insertatcaretactive\")) {\r\n headercontentBody.classList.add(\"insertatcaretactive\");\r\n const id = headercontentBody.dataset.id;\r\n var headereditor = window.tinyMCE.get(id);\r\n headereditor.selection.setContent(content);\r\n return true;\r\n }\r\n }\r\n // Footer notification editor.\r\n var footerNode = document.querySelector('#admin-notificationfooter iframe').contentDocument;\r\n if (footerNode !== null) {\r\n var footercontentBody = footerNode.querySelector(\"body\");\r\n if (footercontentBody.classList.contains(\"insertatcaretactive\")) {\r\n footercontentBody.classList.add(\"insertatcaretactive\");\r\n const id = footercontentBody.dataset.id;\r\n var footereditor = window.tinyMCE.get(id);\r\n footereditor.selection.setContent(content);\r\n return true;\r\n }\r\n }\r\n }\r\n }\r\n\r\n var tinyEditor;\r\n iframes.forEach(function(frame) {\r\n var frameElem = frame.contentDocument.querySelector(\".insertatcaretactive\");\r\n if (frameElem !== null) {\r\n var contentBody = frame.contentDocument.querySelector('body');\r\n if (contentBody !== null) {\r\n contentBody.classList.add(\"insertatcaretactive\");\r\n const id = contentBody.dataset.id;\r\n var editor = window.tinyMCE.get(id);\r\n tinyEditor = editor;\r\n }\r\n }\r\n });\r\n\r\n if (tinyEditor) {\r\n tinyEditor.selection.setContent(content);\r\n } else {\r\n module.insertAtCaret(content);\r\n }\r\n\r\n return true;\r\n });\r\n }\r\n\r\n // Make selected roles as badges in module edit form page.\r\n if (document.getElementById('page-mod-pulse-mod') !== null && document.getElementById('page-mod-pulse-mod')\r\n .querySelector(\"#fgroup_id_completionrequireapproval [data-fieldtype='autocomplete']\") !== null) {\r\n const textNodes = this.getAllTextNodes(\r\n document.getElementById('page-mod-pulse-mod')\r\n .querySelector(\"#fgroup_id_completionrequireapproval [data-fieldtype='autocomplete']\")\r\n );\r\n textNodes.forEach(node => {\r\n const span = document.createElement('span');\r\n span.classList = 'badge badge-info pulse-completion-roles';\r\n node.after(span);\r\n span.appendChild(node);\r\n });\r\n }\r\n },\r\n\r\n insertCaretActive: function(EditorInput) {\r\n if (EditorInput === null) {\r\n return;\r\n }\r\n var caret = document.getElementsByClassName(\"insertatcaretactive\");\r\n for (var j = 0; j < caret.length; j++) {\r\n caret[j].classList.remove(\"insertatcaretactive\");\r\n }\r\n EditorInput.classList.add(\"insertatcaretactive\");\r\n },\r\n\r\n /**\r\n * Filter text from node.\r\n * @param {string} element\r\n * @returns {array} list of childNodes.\r\n */\r\n getAllTextNodes: function(element) {\r\n return Array.from(element.childNodes)\r\n .filter(node => node.nodeType === 3 && node.textContent.trim().length > 1);\r\n },\r\n\r\n /**\r\n * Find the selection is inside the editor\r\n *\r\n * @param {string} div\r\n * @returns {bool}\r\n */\r\n isSelectionInsideDiv: (div) => {\r\n const selection = window.getSelection();\r\n if (selection.rangeCount === 0) {\r\n return false;\r\n }\r\n\r\n // Get the start and end nodes of the selection.\r\n const startNode = selection.getRangeAt(0).startContainer;\r\n const endNode = selection.getRangeAt(0).endContainer;\r\n\r\n // Check if the start and end nodes are both descendants of the editor div.\r\n return div.contains(startNode) && div.contains(endNode);\r\n },\r\n\r\n /**\r\n * Insert the placeholder in selected caret place.\r\n * @param {string} myValue\r\n */\r\n insertAtCaret: function(myValue) {\r\n var caretelements = document.getElementsByClassName(\"insertatcaretactive\");\r\n var sel, range;\r\n for (var n = 0; n < caretelements.length; n++) {\r\n var thiselem = caretelements[n];\r\n\r\n if (typeof thiselem.value === 'undefined' && window.getSelection && this.isSelectionInsideDiv(thiselem)) {\r\n sel = window.getSelection();\r\n if (sel.getRangeAt && sel.rangeCount) {\r\n range = sel.getRangeAt(0);\r\n range.deleteContents();\r\n range.insertNode(document.createTextNode(myValue));\r\n\r\n for (let position = 0; position != (myValue.length + 1); position++) {\r\n sel.modify(\"move\", \"right\", \"character\");\r\n }\r\n }\r\n } else if (typeof thiselem.value === 'undefined' && document.selection && document.selection.createRange) {\r\n range = document.selection.createRange();\r\n range.text = myValue;\r\n }\r\n\r\n if (typeof thiselem.value !== 'undefined') {\r\n if (document.selection) {\r\n // For browsers like Internet Explorer.\r\n thiselem.focus();\r\n sel = document.selection.createRange();\r\n sel.text = myValue;\r\n thiselem.focus();\r\n } else if (thiselem.selectionStart || thiselem.selectionStart == '0') {\r\n // For browsers like Firefox and Webkit based.\r\n var startPos = thiselem.selectionStart;\r\n var endPos = thiselem.selectionEnd;\r\n thiselem.value = thiselem.value.substring(0, startPos)\r\n + myValue + thiselem.value.substring(endPos, thiselem.value.length);\r\n thiselem.focus();\r\n thiselem.selectionStart = startPos + myValue.length;\r\n thiselem.selectionEnd = startPos + myValue.length;\r\n thiselem.focus();\r\n } else {\r\n thiselem.value += myValue;\r\n thiselem.focus();\r\n }\r\n }\r\n }\r\n },\r\n };\r\n});\r\n"],"names":["define","init","branch","module","this","templatevars","document","getElementsByClassName","l","length","addEventListener","EditorInput","getElementById","insertCaretActive","notificationheader","notificationfooter","forEach","elem","e","target","currentTarget","querySelector","headertargetNode","MutationObserver","style","display","headeriframe","contentDocument","headercontentBody","classList","add","footerBody","contains","remove","observe","attributes","childList","footertargetNode","footeriframe","footercontentBody","headerBody","targetNode","setTimeout","initIframeListeners","iframes","querySelectorAll","iframe","currentFrame","frame","frameElem","contentBody","clickforword","i","preventDefault","content","getAttribute","navigator","clipboard","writeText","insertAtCaret","headerNode","id","dataset","window","tinyMCE","get","selection","setContent","footerNode","tinyEditor","editor","getAllTextNodes","node","span","createElement","after","appendChild","caret","j","element","Array","from","childNodes","filter","nodeType","textContent","trim","isSelectionInsideDiv","div","getSelection","rangeCount","startNode","getRangeAt","startContainer","endNode","endContainer","myValue","sel","range","caretelements","n","thiselem","value","deleteContents","insertNode","createTextNode","position","modify","createRange","text","focus","selectionStart","startPos","endPos","selectionEnd","substring"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"module.min.js","sources":["../src/module.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 javascript to place the placeholders.\n * Modified version of IOMAD Email template emailvars.\n *\n * @module mod_pulse/module\n * @category Classes - autoloading\n * @copyright 2021, bdecent gmbh bdecent.de\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine(['core_editor/events'], function() {\n\n return {\n /**\n * Setup the classes to editors works with placeholders.\n *\n * @param {integer} branch\n */\n init: function(branch) {\n var module = this;\n\n var templatevars = document.getElementsByClassName(\"fitem_id_templatevars_editor\");\n for (var l = 0; l < templatevars.length; l++) {\n templatevars[l].addEventListener('click', function() {\n var EditorInput = document.getElementById('id_pulse_content_editoreditable');\n if (EditorInput !== null) {\n module.insertCaretActive(EditorInput);\n }\n });\n }\n\n var notificationheader = document.getElementById('admin-notificationheader');\n if (notificationheader !== null) {\n notificationheader.addEventListener('click', function() {\n var EditorInput = document.getElementById('id_s_mod_pulse_notificationheader_ifr');\n module.insertCaretActive(EditorInput);\n });\n }\n\n var notificationfooter = document.getElementById('admin-notificationfooter');\n if (notificationfooter !== null) {\n notificationfooter.addEventListener('click', function() {\n var EditorInput = document.getElementById('id_s_mod_pulse_notificationfooter_ifr');\n module.insertCaretActive(EditorInput);\n });\n }\n\n\n templatevars = document.getElementsByClassName(\"fitem_id_templatevars_editor\");\n if (templatevars) {\n templatevars.forEach((elem) => {\n elem.addEventListener('click', function(e) {\n var target = e.currentTarget;\n var EditorInput = (branch <= \"402\")\n ? target.querySelector('[id*=\"_editoreditable\"]')\n : target.querySelector('textarea[id*=\"_content_editor\"]');\n module.insertCaretActive(EditorInput);\n });\n });\n }\n\n\n var headertargetNode = document.querySelector('#id_s_mod_pulse_notificationheader');\n if (headertargetNode !== null) {\n let observer = new MutationObserver(function() {\n if (headertargetNode.style.display == 'none') {\n var headeriframe = document.querySelector('#admin-notificationheader iframe').contentDocument;\n if (headeriframe !== null) {\n headeriframe.addEventListener('click', function(e) {\n var currentFrame = e.target;\n var headercontentBody = currentFrame.querySelector('body');\n if (headercontentBody !== null) {\n headercontentBody.classList.add(\"insertatcaretactive\");\n }\n\n var footer = document.querySelector('#admin-notificationfooter iframe').contentDocument;\n var footerBody = footer.querySelector('body');\n if (footerBody.classList.contains('insertatcaretactive')) {\n footerBody.classList.remove(\"insertatcaretactive\");\n }\n\n });\n }\n }\n });\n observer.observe(headertargetNode, {attributes: true, childList: true});\n }\n\n var footertargetNode = document.querySelector('#id_s_mod_pulse_notificationfooter');\n if (footertargetNode !== null) {\n let observer = new MutationObserver(function() {\n if (footertargetNode.style.display == 'none') {\n var footeriframe = document.querySelector('#admin-notificationfooter iframe').contentDocument;\n if (footeriframe !== null) {\n footeriframe.addEventListener('click', function(e) {\n var currentFrame = e.target;\n var footercontentBody = currentFrame.querySelector('body');\n if (footercontentBody !== null) {\n footercontentBody.classList.add(\"insertatcaretactive\");\n }\n\n var header = document.querySelector('#admin-notificationheader iframe').contentDocument;\n var headerBody = header.querySelector('body');\n if (headerBody.classList.contains('insertatcaretactive')) {\n headerBody.classList.remove(\"insertatcaretactive\");\n }\n\n });\n }\n }\n });\n observer.observe(footertargetNode, {attributes: true, childList: true});\n }\n\n var targetNode = document.querySelector('textarea[id$=_editor]');\n\n if (targetNode !== null) {\n let observer = new MutationObserver(function() {\n if (targetNode.style.display == 'none') {\n setTimeout(initIframeListeners, 100);\n }\n });\n observer.observe(targetNode, {attributes: true, childList: true});\n }\n\n const initIframeListeners = () => {\n\n let iframes = document.querySelectorAll('[data-fieldtype=\"editor\"] iframe');\n if (iframes === null || !iframes.length) {\n return false;\n }\n iframes.forEach((iframe) => {\n iframe.contentDocument.addEventListener('click', function(e) {\n var currentFrame = e.target;\n iframes.forEach((frame) => {\n var frameElem = frame.contentDocument.querySelector(\".insertatcaretactive\");\n if (frameElem !== null) {\n frameElem.classList.remove(\"insertatcaretactive\");\n }\n });\n\n var contentBody = currentFrame.querySelector('body');\n if (contentBody !== null) {\n contentBody.classList.add(\"insertatcaretactive\");\n }\n });\n });\n\n return true;\n };\n\n\n var clickforword = document.getElementsByClassName('clickforword');\n for (var i = 0; i < clickforword.length; i++) {\n clickforword[i].addEventListener('click', function(e) {\n e.preventDefault(); // To prevent the default behaviour of a tag.\n\n var content = \"{\" + this.getAttribute('data-text') + \"}\";\n let iframes = document.querySelectorAll('[data-fieldtype=\"editor\"] iframe');\n\n // Copy the placeholder field.\n navigator.clipboard.writeText(content);\n\n if (iframes === null || !iframes.length) {\n if (branch <= '402') {\n module.insertAtCaret(content);\n return true;\n } else {\n // Header notification editor.\n var headerNode = document.querySelector('#admin-notificationheader iframe').contentDocument;\n if (headerNode !== null) {\n var headercontentBody = headerNode.querySelector(\"body\");\n if (headercontentBody.classList.contains(\"insertatcaretactive\")) {\n headercontentBody.classList.add(\"insertatcaretactive\");\n const id = headercontentBody.dataset.id;\n var headereditor = window.tinyMCE.get(id);\n headereditor.selection.setContent(content);\n return true;\n }\n }\n // Footer notification editor.\n var footerNode = document.querySelector('#admin-notificationfooter iframe').contentDocument;\n if (footerNode !== null) {\n var footercontentBody = footerNode.querySelector(\"body\");\n if (footercontentBody.classList.contains(\"insertatcaretactive\")) {\n footercontentBody.classList.add(\"insertatcaretactive\");\n const id = footercontentBody.dataset.id;\n var footereditor = window.tinyMCE.get(id);\n footereditor.selection.setContent(content);\n return true;\n }\n }\n }\n }\n\n var tinyEditor;\n iframes.forEach(function(frame) {\n var frameElem = frame.contentDocument.querySelector(\".insertatcaretactive\");\n if (frameElem !== null) {\n var contentBody = frame.contentDocument.querySelector('body');\n if (contentBody !== null) {\n contentBody.classList.add(\"insertatcaretactive\");\n const id = contentBody.dataset.id;\n var editor = window.tinyMCE.get(id);\n tinyEditor = editor;\n }\n }\n });\n\n if (tinyEditor) {\n tinyEditor.selection.setContent(content);\n } else {\n module.insertAtCaret(content);\n }\n\n return true;\n });\n }\n\n // Make selected roles as badges in module edit form page.\n if (document.getElementById('page-mod-pulse-mod') !== null && document.getElementById('page-mod-pulse-mod')\n .querySelector(\"#fgroup_id_completionrequireapproval [data-fieldtype='autocomplete']\") !== null) {\n const textNodes = this.getAllTextNodes(\n document.getElementById('page-mod-pulse-mod')\n .querySelector(\"#fgroup_id_completionrequireapproval [data-fieldtype='autocomplete']\")\n );\n textNodes.forEach(node => {\n const span = document.createElement('span');\n span.classList = 'badge badge-info pulse-completion-roles';\n node.after(span);\n span.appendChild(node);\n });\n }\n },\n\n insertCaretActive: function(EditorInput) {\n if (EditorInput === null) {\n return;\n }\n var caret = document.getElementsByClassName(\"insertatcaretactive\");\n for (var j = 0; j < caret.length; j++) {\n caret[j].classList.remove(\"insertatcaretactive\");\n }\n EditorInput.classList.add(\"insertatcaretactive\");\n },\n\n /**\n * Filter text from node.\n * @param {string} element\n * @returns {array} list of childNodes.\n */\n getAllTextNodes: function(element) {\n return Array.from(element.childNodes)\n .filter(node => node.nodeType === 3 && node.textContent.trim().length > 1);\n },\n\n /**\n * Find the selection is inside the editor\n *\n * @param {string} div\n * @returns {bool}\n */\n isSelectionInsideDiv: (div) => {\n const selection = window.getSelection();\n if (selection.rangeCount === 0) {\n return false;\n }\n\n // Get the start and end nodes of the selection.\n const startNode = selection.getRangeAt(0).startContainer;\n const endNode = selection.getRangeAt(0).endContainer;\n\n // Check if the start and end nodes are both descendants of the editor div.\n return div.contains(startNode) && div.contains(endNode);\n },\n\n /**\n * Insert the placeholder in selected caret place.\n * @param {string} myValue\n */\n insertAtCaret: function(myValue) {\n var caretelements = document.getElementsByClassName(\"insertatcaretactive\");\n var sel, range;\n for (var n = 0; n < caretelements.length; n++) {\n var thiselem = caretelements[n];\n\n if (typeof thiselem.value === 'undefined' && window.getSelection && this.isSelectionInsideDiv(thiselem)) {\n sel = window.getSelection();\n if (sel.getRangeAt && sel.rangeCount) {\n range = sel.getRangeAt(0);\n range.deleteContents();\n range.insertNode(document.createTextNode(myValue));\n\n for (let position = 0; position != (myValue.length + 1); position++) {\n sel.modify(\"move\", \"right\", \"character\");\n }\n }\n } else if (typeof thiselem.value === 'undefined' && document.selection && document.selection.createRange) {\n range = document.selection.createRange();\n range.text = myValue;\n }\n\n if (typeof thiselem.value !== 'undefined') {\n if (document.selection) {\n // For browsers like Internet Explorer.\n thiselem.focus();\n sel = document.selection.createRange();\n sel.text = myValue;\n thiselem.focus();\n } else if (thiselem.selectionStart || thiselem.selectionStart == '0') {\n // For browsers like Firefox and Webkit based.\n var startPos = thiselem.selectionStart;\n var endPos = thiselem.selectionEnd;\n thiselem.value = thiselem.value.substring(0, startPos)\n + myValue + thiselem.value.substring(endPos, thiselem.value.length);\n thiselem.focus();\n thiselem.selectionStart = startPos + myValue.length;\n thiselem.selectionEnd = startPos + myValue.length;\n thiselem.focus();\n } else {\n thiselem.value += myValue;\n thiselem.focus();\n }\n }\n }\n },\n };\n});\n"],"names":["define","init","branch","module","this","templatevars","document","getElementsByClassName","l","length","addEventListener","EditorInput","getElementById","insertCaretActive","notificationheader","notificationfooter","forEach","elem","e","target","currentTarget","querySelector","headertargetNode","MutationObserver","style","display","headeriframe","contentDocument","headercontentBody","classList","add","footerBody","contains","remove","observe","attributes","childList","footertargetNode","footeriframe","footercontentBody","headerBody","targetNode","setTimeout","initIframeListeners","iframes","querySelectorAll","iframe","currentFrame","frame","frameElem","contentBody","clickforword","i","preventDefault","content","getAttribute","navigator","clipboard","writeText","insertAtCaret","headerNode","id","dataset","window","tinyMCE","get","selection","setContent","footerNode","tinyEditor","editor","getAllTextNodes","node","span","createElement","after","appendChild","caret","j","element","Array","from","childNodes","filter","nodeType","textContent","trim","isSelectionInsideDiv","div","getSelection","rangeCount","startNode","getRangeAt","startContainer","endNode","endContainer","myValue","sel","range","caretelements","n","thiselem","value","deleteContents","insertNode","createTextNode","position","modify","createRange","text","focus","selectionStart","startPos","endPos","selectionEnd","substring"],"mappings":"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"} \ No newline at end of file diff --git a/amd/build/preset.min.js.map b/amd/build/preset.min.js.map index 3f21b33..a636070 100644 --- a/amd/build/preset.min.js.map +++ b/amd/build/preset.min.js.map @@ -1 +1 @@ -{"version":3,"file":"preset.min.js","sources":["../src/preset.js"],"sourcesContent":["define(['jquery', 'core/modal_factory', 'mod_pulse/modal_preset', 'mod_pulse/events', 'core/str', 'core/fragment', 'core/ajax',\r\n 'core/templates', 'core/loadingicon', 'core/notification', 'core/modal_events', 'mod_pulse/presetmodal'],\r\n function($, Modal, ModalPreset, PresetEvents, Str, Fragment, AJAX, Templates, Loadingicon,\r\n Notification, ModalEvents, PresetModal) {\r\n\r\n var SELECTOR = {\r\n presetAvailability: '.preset-config-params .availability-field'\r\n };\r\n\r\n /**\r\n * Preset module declaration. Setup the global values.\r\n * @param {int} contextId\r\n * @param {int} courseid\r\n * @param {int} section\r\n */\r\n var Preset = function(contextId, courseid, section) {\r\n this.contextId = contextId;\r\n this.courseid = courseid;\r\n this.section = section;\r\n this.loadPresetsList();\r\n };\r\n\r\n Preset.prototype.listElement = {'selector': 'pulse-presets-data', \"loaded\": \"data-listloaded\"};\r\n\r\n Preset.prototype.contextId = 0;\r\n\r\n Preset.prototype.courseid = 0;\r\n\r\n Preset.prototype.section = 0;\r\n\r\n Preset.prototype.pageparams = [];\r\n\r\n Preset.prototype.loadIconElement = '.modal-footer #loader-icon';\r\n\r\n Preset.prototype.actionbuttons = '.modal-footer button';\r\n\r\n /**\r\n * Setup the presets modal event listeners.\r\n */\r\n Preset.prototype.setupmodal = function() {\r\n\r\n var THIS = this;\r\n\r\n var triggerelement = document.querySelectorAll('.pulse-usepreset');\r\n // Modal attachment point.\r\n var attachmentPoint = document.createElement('div');\r\n attachmentPoint.classList.add('modal-preset');\r\n triggerelement.forEach((element) => element.addEventListener('click', () => {\r\n var presetid = element.getAttribute('data-presetid');\r\n var presettitle = element.getAttribute('data-presettitle');\r\n var params = {'presetid': presetid, 'courseid': THIS.courseid, 'section': THIS.section};\r\n\r\n document.body.prepend(attachmentPoint);\r\n\r\n var modalFn;\r\n if (typeof PresetModal.registerModalType == 'undefined') {\r\n modalFn = Modal.create({\r\n type: ModalPreset.TYPE,\r\n title: Str.get_string('presetmodaltitle', 'pulse', {'title': presettitle}),\r\n body: Fragment.loadFragment('mod_pulse', 'get_preset_preview', THIS.contextId, params),\r\n large: true,\r\n });\r\n } else {\r\n modalFn = PresetModal.create({\r\n title: Str.get_string('presetmodaltitle', 'pulse', {'title': presettitle}),\r\n body: Fragment.loadFragment('mod_pulse', 'get_preset_preview', THIS.contextId, params),\r\n large: true,\r\n });\r\n }\r\n\r\n modalFn.then(modal => {\r\n // Make the modal attachment point to overcome the restriction access condition.\r\n modal.attachmentPoint = attachmentPoint;\r\n modal.show();\r\n modal.getRoot().on(ModalEvents.bodyRendered, function() {\r\n THIS.reinitAvailability(SELECTOR.presetAvailability);\r\n THIS.fieldChangedEvent();\r\n });\r\n // Destroy the modal on hidden to reload the editors.\r\n modal.getRoot().on(ModalEvents.hidden, function() {\r\n modal.getRoot().get(0).querySelectorAll('form textarea').forEach(target => {\r\n if (tinyMCE != 'undefined') {\r\n tinyMCE.EditorManager.get(target.id).remove();\r\n }\r\n });\r\n modal.destroy.bind(modal);\r\n // THIS.reinitAvailability();\r\n });\r\n\r\n // Apply and customize method.\r\n modal.getRoot().on(PresetEvents.customize, () => {\r\n var modform = document.querySelector('#mod-pulse-form');\r\n var modformdata = new FormData(modform);\r\n modal.getRoot().get(0).querySelectorAll('form').forEach(form => {\r\n var formdata = new FormData(form);\r\n formdata = new URLSearchParams(formdata).toString();\r\n var pageparams = new URLSearchParams(modformdata).toString();\r\n params = {formdata: formdata, pageparams: pageparams};\r\n\r\n Loadingicon.addIconToContainer(this.loadIconElement);\r\n THIS.disableButtons();\r\n THIS.applyCustomize(params, THIS.contextId, modal);\r\n });\r\n });\r\n // Apply and save method.\r\n modal.getRoot().on(PresetEvents.save, (e) => {\r\n e.preventDefault();\r\n Loadingicon.addIconToContainer(this.loadIconElement);\r\n THIS.disableButtons();\r\n var formdata = {};\r\n modal.getRoot().get(0).querySelectorAll('form').forEach(form => {\r\n formdata = new FormData(form);\r\n this.restorePreset(formdata, THIS.contextId);\r\n });\r\n });\r\n return true;\r\n }).catch(Notification.exception);\r\n }));\r\n };\r\n\r\n\r\n Preset.prototype.fieldChangedEvent = () => {\r\n var confParam = document.getElementById(\"preset-configurable-params\");\r\n var reminders = ['first', 'second', 'recurring'];\r\n var methods = ['fixed', 'relative'];\r\n var fieldName, changeinput, id, changeName, split;\r\n confParam.querySelectorAll('input, select, textarea').forEach(field => {\r\n field.addEventListener('change', (event) => {\r\n fieldName = event.target.getAttribute('name');\r\n if (confParam.querySelector('input[name=\"' + fieldName + '_changed\"]') !== null) {\r\n confParam.querySelector('input[name=\"' + fieldName + '_changed\"]').value = true;\r\n }\r\n });\r\n });\r\n\r\n reminders.forEach(reminder => {\r\n confParam.querySelectorAll('[name=\"' + reminder + '_schedule\"').forEach(schedule => {\r\n schedule.addEventListener('change', (e) => {\r\n changeName = e.target.getAttribute('name');\r\n changeinput = 'input[name=\"' + changeName + '_arr_changed\"]';\r\n confParam.querySelector(changeinput).value = true;\r\n });\r\n });\r\n methods.forEach(method => {\r\n id = reminder + \"_\" + method + \"date\";\r\n confParam.querySelectorAll('[name*=\"' + id + '\"]').forEach(opt => {\r\n opt.addEventListener('change', (e) => {\r\n split = e.target.getAttribute('name').split('[');\r\n changeName = (split.hasOwnProperty(1)) ? split[0] : split;\r\n changeinput = 'input[name=\"' + changeName + '_changed\"]';\r\n confParam.querySelector(changeinput).value = true;\r\n });\r\n });\r\n });\r\n });\r\n };\r\n\r\n /**\r\n * Reinitialize the availability javascript.\r\n * @param {string} selector\r\n */\r\n Preset.prototype.reinitAvailability = function(selector = '.availability-field') {\r\n if (typeof M.core_availability.form !== \"undefined\" &&\r\n document.getElementById('id_availabilityconditionsjson') !== null) {\r\n this.resetRestrictPlugins();\r\n document.querySelectorAll(selector).forEach((field) => field.parentNode.removeChild(field));\r\n M.core_availability.form.init();\r\n }\r\n };\r\n\r\n Preset.prototype.resetRestrictPlugins = function() {\r\n if (typeof M.core_availability.form !== \"undefined\" &&\r\n document.getElementById('id_availabilityconditionsjson') !== null) {\r\n M.core_availability.form.restrictByGroup = null;\r\n var availabilityPlugins = (typeof M.core_availability.form.plugins !== 'undefined')\r\n ? M.core_availability.form.plugins : {};\r\n var plugin = '';\r\n for (var i in availabilityPlugins) {\r\n plugin = \"availability_\" + i;\r\n if (M.hasOwnProperty(plugin)) {\r\n M[plugin].form.addedEvents = false;\r\n }\r\n }\r\n }\r\n };\r\n\r\n /**\r\n * Apply and customize triggered using fragment. Response will replaced with current mod form.\r\n * @param {string} params\r\n * @param {int} contextID\r\n * @param {object} modal\r\n */\r\n Preset.prototype.applyCustomize = function(params, contextID, modal) {\r\n Fragment.loadFragment('mod_pulse', 'apply_preset', contextID, params).done((html, js) => {\r\n modal.destroy();\r\n // Reset the availability to work for upcoming response html.\r\n this.resetRestrictPlugins();\r\n this.handleFormSubmissionResponse(html, js);\r\n });\r\n };\r\n\r\n /**\r\n * Disable the modal save and customize buttons to prevent reinit.\r\n */\r\n Preset.prototype.disableButtons = function() {\r\n var buttons = document.querySelectorAll(this.actionbuttons);\r\n for (let $i in buttons) {\r\n buttons[$i].disabled = true;\r\n }\r\n };\r\n\r\n /**\r\n * Handle the loaded fragment output of customize method pulse mod.\r\n * @param {html} data\r\n * @param {string} js\r\n */\r\n Preset.prototype.handleFormSubmissionResponse = (data, js) => {\r\n var newform = document.createElement('div');\r\n newform.innerHTML = data;\r\n Templates.replaceNode('[action=\"modedit.php\"]', data, js);\r\n\r\n };\r\n\r\n /**\r\n * Initiate the apply and save method to create the pulse module with custom daa.\r\n * @param {FormData} formdata\r\n * @param {int} contextid\r\n */\r\n Preset.prototype.restorePreset = (formdata, contextid) => {\r\n var formdatastr = new URLSearchParams(formdata).toString();\r\n var promises = AJAX.call([{\r\n methodname: 'mod_pulse_apply_presets',\r\n args: {contextid: contextid, formdata: formdatastr}\r\n }]);\r\n\r\n promises[0].done((response) => {\r\n response = JSON.parse(response);\r\n if (typeof response.url != 'undefined') {\r\n window.location.href = response.url;\r\n }\r\n });\r\n };\r\n\r\n /**\r\n * Load list of available presets.\r\n */\r\n Preset.prototype.loadPresetsList = function() {\r\n var listParent = document.getElementById(this.listElement.selector);\r\n\r\n if (listParent !== null) {\r\n if (listParent.getAttribute(this.listElement.loaded) == 'false') {\r\n Fragment.loadFragment('mod_pulse', 'get_presetslist', this.contextId, {'courseid': this.courseid})\r\n .done((html, js) => {\r\n Templates.replaceNodeContents(listParent, html, js);\r\n listParent.setAttribute(this.listElement.loaded, 'true');\r\n this.setupmodal();\r\n });\r\n }\r\n }\r\n };\r\n\r\n return {\r\n init: (contextId, courseid, section) => {\r\n new Preset(contextId, courseid, section);\r\n }\r\n };\r\n });\r\n"],"names":["define","$","Modal","ModalPreset","PresetEvents","Str","Fragment","AJAX","Templates","Loadingicon","Notification","ModalEvents","PresetModal","SELECTOR","Preset","contextId","courseid","section","loadPresetsList","prototype","listElement","pageparams","loadIconElement","actionbuttons","setupmodal","THIS","this","triggerelement","document","querySelectorAll","attachmentPoint","createElement","classList","add","forEach","element","addEventListener","presetid","getAttribute","presettitle","params","body","prepend","registerModalType","create","type","TYPE","title","get_string","loadFragment","large","then","modal","show","getRoot","on","bodyRendered","reinitAvailability","fieldChangedEvent","hidden","get","target","tinyMCE","EditorManager","id","remove","destroy","bind","customize","modform","querySelector","modformdata","FormData","form","formdata","URLSearchParams","toString","addIconToContainer","disableButtons","applyCustomize","save","e","preventDefault","restorePreset","catch","exception","fieldName","changeinput","changeName","split","confParam","getElementById","methods","field","event","value","reminder","schedule","method","opt","hasOwnProperty","selector","M","core_availability","resetRestrictPlugins","parentNode","removeChild","init","restrictByGroup","availabilityPlugins","plugins","plugin","i","addedEvents","contextID","done","html","js","handleFormSubmissionResponse","buttons","$i","disabled","data","innerHTML","replaceNode","contextid","formdatastr","call","methodname","args","response","JSON","parse","url","window","location","href","listParent","loaded","replaceNodeContents","setAttribute"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"preset.min.js","sources":["../src/preset.js"],"sourcesContent":["define(['jquery', 'core/modal_factory', 'mod_pulse/modal_preset', 'mod_pulse/events', 'core/str', 'core/fragment', 'core/ajax',\n 'core/templates', 'core/loadingicon', 'core/notification', 'core/modal_events', 'mod_pulse/presetmodal'],\n function($, Modal, ModalPreset, PresetEvents, Str, Fragment, AJAX, Templates, Loadingicon,\n Notification, ModalEvents, PresetModal) {\n\n var SELECTOR = {\n presetAvailability: '.preset-config-params .availability-field'\n };\n\n /**\n * Preset module declaration. Setup the global values.\n * @param {int} contextId\n * @param {int} courseid\n * @param {int} section\n */\n var Preset = function(contextId, courseid, section) {\n this.contextId = contextId;\n this.courseid = courseid;\n this.section = section;\n this.loadPresetsList();\n };\n\n Preset.prototype.listElement = {'selector': 'pulse-presets-data', \"loaded\": \"data-listloaded\"};\n\n Preset.prototype.contextId = 0;\n\n Preset.prototype.courseid = 0;\n\n Preset.prototype.section = 0;\n\n Preset.prototype.pageparams = [];\n\n Preset.prototype.loadIconElement = '.modal-footer #loader-icon';\n\n Preset.prototype.actionbuttons = '.modal-footer button';\n\n /**\n * Setup the presets modal event listeners.\n */\n Preset.prototype.setupmodal = function() {\n\n var THIS = this;\n\n var triggerelement = document.querySelectorAll('.pulse-usepreset');\n // Modal attachment point.\n var attachmentPoint = document.createElement('div');\n attachmentPoint.classList.add('modal-preset');\n triggerelement.forEach((element) => element.addEventListener('click', () => {\n var presetid = element.getAttribute('data-presetid');\n var presettitle = element.getAttribute('data-presettitle');\n var params = {'presetid': presetid, 'courseid': THIS.courseid, 'section': THIS.section};\n\n document.body.prepend(attachmentPoint);\n\n var modalFn;\n if (typeof PresetModal.registerModalType == 'undefined') {\n modalFn = Modal.create({\n type: ModalPreset.TYPE,\n title: Str.get_string('presetmodaltitle', 'pulse', {'title': presettitle}),\n body: Fragment.loadFragment('mod_pulse', 'get_preset_preview', THIS.contextId, params),\n large: true,\n });\n } else {\n modalFn = PresetModal.create({\n title: Str.get_string('presetmodaltitle', 'pulse', {'title': presettitle}),\n body: Fragment.loadFragment('mod_pulse', 'get_preset_preview', THIS.contextId, params),\n large: true,\n });\n }\n\n modalFn.then(modal => {\n // Make the modal attachment point to overcome the restriction access condition.\n modal.attachmentPoint = attachmentPoint;\n modal.show();\n modal.getRoot().on(ModalEvents.bodyRendered, function() {\n THIS.reinitAvailability(SELECTOR.presetAvailability);\n THIS.fieldChangedEvent();\n });\n // Destroy the modal on hidden to reload the editors.\n modal.getRoot().on(ModalEvents.hidden, function() {\n modal.getRoot().get(0).querySelectorAll('form textarea').forEach(target => {\n if (tinyMCE != 'undefined') { // eslint-disable-line\n tinyMCE.EditorManager.get(target.id).remove(); // eslint-disable-line\n }\n });\n modal.destroy.bind(modal);\n // THIS.reinitAvailability();\n });\n\n // Apply and customize method.\n modal.getRoot().on(PresetEvents.customize, () => {\n var modform = document.querySelector('#mod-pulse-form');\n var modformdata = new FormData(modform);\n modal.getRoot().get(0).querySelectorAll('form').forEach(form => {\n var formdata = new FormData(form);\n formdata = new URLSearchParams(formdata).toString();\n var pageparams = new URLSearchParams(modformdata).toString();\n params = {formdata: formdata, pageparams: pageparams};\n\n Loadingicon.addIconToContainer(this.loadIconElement);\n THIS.disableButtons();\n THIS.applyCustomize(params, THIS.contextId, modal);\n });\n });\n // Apply and save method.\n modal.getRoot().on(PresetEvents.save, (e) => {\n e.preventDefault();\n Loadingicon.addIconToContainer(this.loadIconElement);\n THIS.disableButtons();\n var formdata = {};\n modal.getRoot().get(0).querySelectorAll('form').forEach(form => {\n formdata = new FormData(form);\n this.restorePreset(formdata, THIS.contextId);\n });\n });\n return true;\n }).catch(Notification.exception);\n }));\n };\n\n\n Preset.prototype.fieldChangedEvent = () => {\n var confParam = document.getElementById(\"preset-configurable-params\");\n var reminders = ['first', 'second', 'recurring'];\n var methods = ['fixed', 'relative'];\n var fieldName, changeinput, id, changeName, split;\n confParam.querySelectorAll('input, select, textarea').forEach(field => {\n field.addEventListener('change', (event) => {\n fieldName = event.target.getAttribute('name');\n if (confParam.querySelector('input[name=\"' + fieldName + '_changed\"]') !== null) {\n confParam.querySelector('input[name=\"' + fieldName + '_changed\"]').value = true;\n }\n });\n });\n\n reminders.forEach(reminder => {\n confParam.querySelectorAll('[name=\"' + reminder + '_schedule\"').forEach(schedule => {\n schedule.addEventListener('change', (e) => {\n changeName = e.target.getAttribute('name');\n changeinput = 'input[name=\"' + changeName + '_arr_changed\"]';\n confParam.querySelector(changeinput).value = true;\n });\n });\n methods.forEach(method => {\n id = reminder + \"_\" + method + \"date\";\n confParam.querySelectorAll('[name*=\"' + id + '\"]').forEach(opt => {\n opt.addEventListener('change', (e) => {\n split = e.target.getAttribute('name').split('[');\n changeName = (split.hasOwnProperty(1)) ? split[0] : split;\n changeinput = 'input[name=\"' + changeName + '_changed\"]';\n confParam.querySelector(changeinput).value = true;\n });\n });\n });\n });\n };\n\n /**\n * Reinitialize the availability javascript.\n * @param {string} selector\n */\n Preset.prototype.reinitAvailability = function(selector = '.availability-field') {\n if (typeof M.core_availability.form !== \"undefined\" &&\n document.getElementById('id_availabilityconditionsjson') !== null) {\n this.resetRestrictPlugins();\n document.querySelectorAll(selector).forEach((field) => field.parentNode.removeChild(field));\n M.core_availability.form.init();\n }\n };\n\n Preset.prototype.resetRestrictPlugins = function() {\n if (typeof M.core_availability.form !== \"undefined\" &&\n document.getElementById('id_availabilityconditionsjson') !== null) {\n M.core_availability.form.restrictByGroup = null;\n var availabilityPlugins = (typeof M.core_availability.form.plugins !== 'undefined')\n ? M.core_availability.form.plugins : {};\n var plugin = '';\n for (var i in availabilityPlugins) {\n plugin = \"availability_\" + i;\n if (M.hasOwnProperty(plugin)) {\n M[plugin].form.addedEvents = false;\n }\n }\n }\n };\n\n /**\n * Apply and customize triggered using fragment. Response will replaced with current mod form.\n * @param {string} params\n * @param {int} contextID\n * @param {object} modal\n */\n Preset.prototype.applyCustomize = function(params, contextID, modal) {\n Fragment.loadFragment('mod_pulse', 'apply_preset', contextID, params).done((html, js) => {\n modal.destroy();\n // Reset the availability to work for upcoming response html.\n this.resetRestrictPlugins();\n this.handleFormSubmissionResponse(html, js);\n });\n };\n\n /**\n * Disable the modal save and customize buttons to prevent reinit.\n */\n Preset.prototype.disableButtons = function() {\n var buttons = document.querySelectorAll(this.actionbuttons);\n for (let $i in buttons) {\n buttons[$i].disabled = true;\n }\n };\n\n /**\n * Handle the loaded fragment output of customize method pulse mod.\n * @param {html} data\n * @param {string} js\n */\n Preset.prototype.handleFormSubmissionResponse = (data, js) => {\n var newform = document.createElement('div');\n newform.innerHTML = data;\n Templates.replaceNode('[action=\"modedit.php\"]', data, js);\n\n };\n\n /**\n * Initiate the apply and save method to create the pulse module with custom daa.\n * @param {FormData} formdata\n * @param {int} contextid\n */\n Preset.prototype.restorePreset = (formdata, contextid) => {\n var formdatastr = new URLSearchParams(formdata).toString();\n var promises = AJAX.call([{\n methodname: 'mod_pulse_apply_presets',\n args: {contextid: contextid, formdata: formdatastr}\n }]);\n\n promises[0].done((response) => {\n response = JSON.parse(response);\n if (typeof response.url != 'undefined') {\n window.location.href = response.url;\n }\n });\n };\n\n /**\n * Load list of available presets.\n */\n Preset.prototype.loadPresetsList = function() {\n var listParent = document.getElementById(this.listElement.selector);\n\n if (listParent !== null) {\n if (listParent.getAttribute(this.listElement.loaded) == 'false') {\n Fragment.loadFragment('mod_pulse', 'get_presetslist', this.contextId, {'courseid': this.courseid})\n .done((html, js) => {\n Templates.replaceNodeContents(listParent, html, js);\n listParent.setAttribute(this.listElement.loaded, 'true');\n this.setupmodal();\n });\n }\n }\n };\n\n return {\n init: (contextId, courseid, section) => {\n new Preset(contextId, courseid, section);\n }\n };\n });\n"],"names":["define","$","Modal","ModalPreset","PresetEvents","Str","Fragment","AJAX","Templates","Loadingicon","Notification","ModalEvents","PresetModal","SELECTOR","Preset","contextId","courseid","section","loadPresetsList","prototype","listElement","pageparams","loadIconElement","actionbuttons","setupmodal","THIS","this","triggerelement","document","querySelectorAll","attachmentPoint","createElement","classList","add","forEach","element","addEventListener","presetid","getAttribute","presettitle","params","body","prepend","registerModalType","create","type","TYPE","title","get_string","loadFragment","large","then","modal","show","getRoot","on","bodyRendered","reinitAvailability","fieldChangedEvent","hidden","get","target","tinyMCE","EditorManager","id","remove","destroy","bind","customize","modform","querySelector","modformdata","FormData","form","formdata","URLSearchParams","toString","addIconToContainer","disableButtons","applyCustomize","save","e","preventDefault","restorePreset","catch","exception","fieldName","changeinput","changeName","split","confParam","getElementById","methods","field","event","value","reminder","schedule","method","opt","hasOwnProperty","selector","M","core_availability","resetRestrictPlugins","parentNode","removeChild","init","restrictByGroup","availabilityPlugins","plugins","plugin","i","addedEvents","contextID","done","html","js","handleFormSubmissionResponse","buttons","$i","disabled","data","innerHTML","replaceNode","contextid","formdatastr","call","methodname","args","response","JSON","parse","url","window","location","href","listParent","loaded","replaceNodeContents","setAttribute"],"mappings":"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"} \ No newline at end of file diff --git a/amd/src/module.js b/amd/src/module.js index dcde636..865575d 100644 --- a/amd/src/module.js +++ b/amd/src/module.js @@ -66,11 +66,9 @@ define(['core_editor/events'], function() { templatevars.forEach((elem) => { elem.addEventListener('click', function(e) { var target = e.currentTarget; - if (branch <= "402") { - var EditorInput = target.querySelector('[id*="_editoreditable"]'); - } else { - var EditorInput = target.querySelector('textarea[id*="_content_editor"]'); - } + var EditorInput = (branch <= "402") + ? target.querySelector('[id*="_editoreditable"]') + : target.querySelector('textarea[id*="_content_editor"]'); module.insertCaretActive(EditorInput); }); }); diff --git a/amd/src/preset.js b/amd/src/preset.js index 14f080c..8ab37c5 100644 --- a/amd/src/preset.js +++ b/amd/src/preset.js @@ -79,8 +79,8 @@ define(['jquery', 'core/modal_factory', 'mod_pulse/modal_preset', 'mod_pulse/eve // Destroy the modal on hidden to reload the editors. modal.getRoot().on(ModalEvents.hidden, function() { modal.getRoot().get(0).querySelectorAll('form textarea').forEach(target => { - if (tinyMCE != 'undefined') { - tinyMCE.EditorManager.get(target.id).remove(); + if (tinyMCE != 'undefined') { // eslint-disable-line + tinyMCE.EditorManager.get(target.id).remove(); // eslint-disable-line } }); modal.destroy.bind(modal); diff --git a/classes/helper.php b/classes/helper.php index f2c42a5..9fa7f70 100644 --- a/classes/helper.php +++ b/classes/helper.php @@ -86,7 +86,7 @@ public static function update_emailvars($templatetext, $subject, $course, $user, $course->courseurl = $courseurl; $sender = $sender ? $sender : core_user::get_support_user(); // Support user. - $amethods = pulse_email_vars::vars(); // List of available placeholders. + $amethods = pulse_email_vars::vars('all'); // List of available placeholders. // Get formatted name of the category. $course->category = is_number($course->category) ? core_course_category::get($course->category)->get_formatted_name() : $course->category; diff --git a/classes/preset.php b/classes/preset.php index 74ba6e3..2c434c2 100644 --- a/classes/preset.php +++ b/classes/preset.php @@ -665,7 +665,8 @@ public function import_presets($backuptempdir, $configdata) { $formdata['course'] = $this->courseid; $formdata = array_filter($formdata, function($value) { if (!is_array($value)) { - return (trim($value) !== '') ? true : false; + $value = $value != '' ? trim($value) : $value; + return ($value !== '') ? true : false; } return true; }); @@ -738,7 +739,7 @@ public function prepare_modform($data) { $this->modformdata = array_replace_recursive($this->modformdata, $data); // Replace the config data. $this->modformdata = array_map(function($value) { - return (!is_array($value)) ? trim($value) : $value; + return (!is_array($value) && $value != null) ? trim($value) : $value; }, $this->modformdata); $COURSE = $this->course; diff --git a/conditions/enrolment/db/events.php b/conditions/enrolment/db/events.php index 661abda..43eed32 100644 --- a/conditions/enrolment/db/events.php +++ b/conditions/enrolment/db/events.php @@ -38,3 +38,4 @@ 'callback' => '\pulsecondition_enrolment\conditionform::user_enrolled', ], ]; + diff --git a/conditions/events/classes/conditionform.php b/conditions/events/classes/conditionform.php index 748e8ba..0f8e693 100644 --- a/conditions/events/classes/conditionform.php +++ b/conditions/events/classes/conditionform.php @@ -283,16 +283,27 @@ public static function get_events() { global $DB; $list = []; + $events = []; // Events added for observe. + $eventscoditiondata = $DB->get_records('pulse_condition_overrides', ['triggercondition' => 'events']); foreach ($eventscoditiondata as $data) { $additional = json_decode($data->additional); - if (!isset($additional->event) || $additional->event != '') { + if (!isset($additional->event) || $additional->event == '') { + continue; + } + + // Verify the event is already observed in the pulse event condition, to prevent multiple observe of single event. + if (in_array($additional->event, $events)) { continue; } + $list[] = [ 'eventname' => $additional->event, 'callback' => '\pulsecondition_events\conditionform::pulse_event_condition_trigger', ]; + + // Prevent multiple event observer for one event. + $events[] = $additional->event; } return $list ?? []; } @@ -470,4 +481,21 @@ public function backup_define_structure(&$instances) { $eventsfields->set_source_table('pulsecondition_events', ['instanceid' => \backup::VAR_PARENTID]); } + /** + * After save the condition form, clear the observers from cache and recreated the list. + * + * @param int $instanceid + * @param object $data + * @return void + */ + public function process_instance_save($instanceid, $data) { + parent::process_instance_save($instanceid, $data); + + // Remove the event observers and recreate. + $cache = \cache::make('core', 'observers'); + $cache->delete('all'); + // Build the observers again. + $list = \core\event\manager::get_all_observers(); + purge_other_caches(); + } } diff --git a/conditions/events/db/events.php b/conditions/events/db/events.php index c84559d..cb81e17 100644 --- a/conditions/events/db/events.php +++ b/conditions/events/db/events.php @@ -28,5 +28,4 @@ defined('MOODLE_INTERNAL') || die(); - $observers = \pulsecondition_events\conditionform::get_events(); diff --git a/lib/vars.php b/lib/vars.php index cbf93b3..e95ad76 100644 --- a/lib/vars.php +++ b/lib/vars.php @@ -199,7 +199,7 @@ public function __construct($user, $course, $sender, $pulse, $condition=null) { $this->assignment = $pluginbase->get_assignment_extension($this->course->id, $this->user->id); } - if (pulsehelper::pulse_has_pro()) { + if (pulsehelper::pulse_has_pro() && $this->pulse) { $this->reaction = $this->reaction_data(); } @@ -297,7 +297,9 @@ public static function vars($automation=false) { // Session data fields. $result += ['Mod_session' => self::session_fields()]; - } else { + } + + if (!$automation || $automation == 'all') { $result += \mod_pulse\extendpro::pulse_extend_reaction_placholder(); } @@ -577,7 +579,7 @@ public static function module_meta_fields() { $fields = array_keys($records); array_walk($fields, function(&$value) { - $value = $value; + $value = "Mod_metadata".$value; }); } diff --git a/templates/vars.mustache b/templates/vars.mustache index 0332a78..680c99c 100644 --- a/templates/vars.mustache +++ b/templates/vars.mustache @@ -74,7 +74,7 @@ {{/emailvars}}
-
{{#str}} vardocstr, pulse {{/str}}{{#str}} documentation, pulse {{/str}}
+
{{#str}} vardocstr, pulse {{/str}}{{#str}} documentation, pulse {{/str}}
diff --git a/tests/behat/behat_pulse.php b/tests/behat/behat_pulse.php index 8cac0a4..fb1e99d 100644 --- a/tests/behat/behat_pulse.php +++ b/tests/behat/behat_pulse.php @@ -212,4 +212,16 @@ public function i_set_the_activity_completion_tracking() { ['Completion tracking', 'Show activity as complete when conditions are met']); } } + + + /** + * Switches to a pulse new window. + * + * @Given /^I switch to a pulse open window$/ + * @throws DriverException If there aren't exactly 2 windows open. + */ + public function switch_to_open_window() { + $names = $this->getSession()->getWindowNames(); + $this->getSession()->switchToWindow(end($names)); + } } diff --git a/tests/behat/pulse_activity_completion.feature b/tests/behat/pulse_activity_completion.feature index 95a3a73..f054452 100644 --- a/tests/behat/pulse_activity_completion.feature +++ b/tests/behat/pulse_activity_completion.feature @@ -6,23 +6,23 @@ Feature: View activity completion information in the pulse activity Background: Given the following "users" exist: - | username | firstname | lastname | email | - | student1 | Student | User 1 | student1@test.com | - | teacher1 | Teacher | User 1 | teacher1@test.com | + | username | firstname | lastname | email | + | student1 | Student | User 1 | student1@test.com | + | teacher1 | Teacher | User 1 | teacher1@test.com | And the following "courses" exist: | fullname | shortname | category | enablecompletion | showcompletionconditions | | Course 1 | C1 | 0 | 1 | 1 | And the following "course enrolments" exist: - | user | course | role | - | student1 | C1 | student | - | teacher1 | C1 | editingteacher | + | user | course | role | + | student1 | C1 | student | + | teacher1 | C1 | editingteacher | And the following "activity" exists: - | activity | pulse | - | course | C1 | - | idnumber | pulse1 | - | name | Test pulse 1 | - | intro | Test pulse 1 | - | pulse | 0 | + | activity | pulse | + | course | C1 | + | idnumber | pulse1 | + | name | Test pulse 1 | + | intro | Test pulse 1 | + | pulse | 0 | And I log in as "teacher1" And I am on "Course 1" course homepage with editing mode on And I click on "Edit" "link" in the ".modtype_pulse" "css_element" @@ -32,16 +32,16 @@ Feature: View activity completion information in the pulse activity And I press "Save and return to course" @javascript - Scenario: View automatic completion items + Scenario: Pulse view automatic completion items Given I am on "Course 1" course homepage with editing mode on And I click on "Edit" "link" in the ".modtype_pulse" "css_element" And I click on ".menu-action-text" "css_element" in the ".modtype_pulse" "css_element" - And I set the following fields to these values: - | Completion tracking | Show activity as complete when conditions are met | + And I expand all fieldsets + And I wait "10" seconds + And I set the activity completion tracking And I click on "Completion when available" "checkbox" And I press "Save and return to course" # Teacher view. - # And "Test pulse 1" should have the "" or "auto" completion condition And "Test pulse 1" should have the "Restrictions must be met" completion condition type "auto" And I log out # Student view. @@ -55,14 +55,14 @@ Feature: View activity completion information in the pulse activity Given I am on "Course 1" course homepage with editing mode on And I click on "Edit" "link" in the ".modtype_pulse" "css_element" And I click on ".menu-action-text" "css_element" in the ".modtype_pulse" "css_element" - And I set the following fields to these values: - | Completion tracking | Show activity as complete when conditions are met | + And I expand all fieldsets + And I set the activity completion tracking And I click on "Mark as complete by student to complete this activity" "checkbox" And I press "Save and return to course" # Teacher view. # confirm the activity completion enabled. And "Test pulse 1" should have the "Mark complete" completion condition type "auto" - And I should not see "Mark complete" in the ".modtype_pulse .contentwithoutlink" "css_element" + And I should not see "Mark complete" in the ".modtype_pulse .activity-altcontent" "css_element" And I log out # Student view. When I log in as "student1" @@ -71,30 +71,36 @@ Feature: View activity completion information in the pulse activity And I should see "Mark complete" in the ".pulse-completion-btn" "css_element" When I click on "Mark complete" "link" And I should see "Marked as completed" in the ".notifications" "css_element" - Then I should see "Self marked complete on" completion condition of "Test pulse 1" is displayed as "done" + And "Test pulse 1" should have the "Self marked complete on" completion condition type "done" @javascript Scenario: Use manual completion Required by approval complete. Given I am on "Course 1" course homepage with editing mode on And I click on "Edit" "link" in the ".modtype_pulse" "css_element" And I click on ".menu-action-text" "css_element" in the ".modtype_pulse" "css_element" - And I set the following fields to these values: - | Completion tracking | Show activity as complete when conditions are met | + And I expand all fieldsets + And I set the activity completion tracking And I click on "Require approval by one of the following roles" "checkbox" And I click on ".form-autocomplete-downarrow" "css_element" in the "#fgroup_id_completionrequireapproval" "css_element" And I click on "Teacher" "list_item" in the "#fgroup_id_completionrequireapproval [class='form-autocomplete-suggestions']" "css_element" And I press "Save and return to course" + And I log out + # Teacher view. + And I log in as "teacher1" + And I am on "Course 1" course homepage And "Test pulse 1" should have the "Approval required" completion condition type "auto" And I should see "Approve users" in the ".pulse-completion-btn" "css_element" + And I click on "Test pulse 1" "text" in the ".activity-altcontent" "css_element" And I click on "Approve users" "link" in the ".pulse-completion-btn" "css_element" And I should see "Student User 1" in the "participants" "table" When I click on "Approve" "link" in the "Student User 1" "table_row" And I should see "Approval successful" in the ".notifications" "css_element" And I should see "Approved" in the "Student User 1" "table_row" And I log out + # Student view When I log in as "student1" And I am on "Course 1" course homepage And I should see "Test pulse 1" - Then I should see "Approved on" completion condition of "Test pulse 1" is displayed as "done" + And "Test pulse 1" should have the "Approved on" completion condition type "done" diff --git a/tests/behat/pulse_appearance.feature b/tests/behat/pulse_appearance.feature index 2a85877..750de7a 100644 --- a/tests/behat/pulse_appearance.feature +++ b/tests/behat/pulse_appearance.feature @@ -6,23 +6,23 @@ Feature: Pulse appearance display modes Background: Create pulse instance. Given the following "course" exist: - | fullname| shortname | category | - | Test | C1 | 0 | + | fullname | shortname | category | + | Test | C1 | 0 | And the following "users" exist: - | username | firstname | lastname | email | - | student1 | student | User 1 | student1@test.com | - | teacher1 | Teacher | User 1 | teacher1@test.com | + | username | firstname | lastname | email | + | student1 | student | User 1 | student1@test.com | + | teacher1 | Teacher | User 1 | teacher1@test.com | And the following "course enrolments" exist: - | user | course | role | - | teacher1 | C1 | editingteacher | - | student1 | C1 | student | + | user | course | role | + | teacher1 | C1 | editingteacher | + | student1 | C1 | student | And the following "activity" exists: - | activity | pulse | - | course | C1 | - | idnumber | 00001 | - | name | pulse box mode | - | intro | pulse box mode | - | section | 1 | + | activity | pulse | + | course | C1 | + | idnumber | 00001 | + | name | pulse box mode | + | intro | pulse box mode | + | section | 1 | @javascript Scenario: Change the display mode to box. @@ -30,11 +30,11 @@ Feature: Pulse appearance display modes And I am on "Test" course homepage with editing mode on And I click on "Edit" "link" in the ".modtype_pulse" "css_element" And I click on ".menu-action-text" "css_element" in the ".modtype_pulse" "css_element" - And I follow "Expand all" + And I expand all fieldsets And I set the following fields to these values: - | Display mode | Box | - | Box Type | Success | - | Box Icon | fa-clone | + | Display mode | Box | + | Box Type | Success | + | Box Icon | fa-clone | And I set the field "Send Pulse notification" to "0" And I press "Save and return to course" Then ".pulse-box" "css_element" should exist in the ".modtype_pulse" "css_element" @@ -54,7 +54,7 @@ Feature: Pulse appearance display modes And I am on "Test" course homepage with editing mode on And I click on "Edit" "link" in the ".modtype_pulse" "css_element" And I click on ".menu-action-text" "css_element" in the ".modtype_pulse" "css_element" - And I follow "Expand all" + And I expand all fieldsets And I set the following fields to these values: | CSS class | pulse-appearance-custom-class | And I set the field "Send Pulse notification" to "0" diff --git a/tests/behat/pulse_automation_instance.feature b/tests/behat/pulse_automation_instance.feature index 97fa5ca..c9914e0 100644 --- a/tests/behat/pulse_automation_instance.feature +++ b/tests/behat/pulse_automation_instance.feature @@ -10,27 +10,27 @@ Feature: Pulse automation instances | Cat 2 | 0 | CAT2 | | Cat 3 | CAT1 | CAT3 | And the following "course" exist: - | fullname | shortname | category | - | Course 1 | C1 | 0 | - | Course 2 | C2 | CAT1 | - | Course 3 | C3 | CAT2 | - | Course 4 | C4 | CAT3 | + | fullname | shortname | category | + | Course 1 | C1 | 0 | + | Course 2 | C2 | CAT1 | + | Course 3 | C3 | CAT2 | + | Course 4 | C4 | CAT3 | And the following "users" exist: - | username | firstname | lastname | email | - | student1 | student | User 1 | student1@test.com | - | teacher1 | Teacher | User 1 | teacher1@test.com | + | username | firstname | lastname | email | + | student1 | student | User 1 | student1@test.com | + | teacher1 | Teacher | User 1 | teacher1@test.com | And the following "course enrolments" exist: - | user | course | role | + | user | course | role | | teacher1 | C1 | editingteacher | - | student1 | C1 | student | + | student1 | C1 | student | @javascript Scenario: Create the automation template instance. Given I log in as "admin" Then I create automation template with the following fields to these values: - | Title | WELCOME MESSAGE | - | Reference | Welcomemessage | - | Visibility| Show | + | Title | WELCOME MESSAGE | + | Reference | Welcomemessage | + | Visibility | Show | And I should see "WELCOME MESSAGE" in the "#pulse_automation_template" "css_element" And I am on "Course 1" course homepage And I follow "Automation" @@ -38,9 +38,9 @@ Feature: Pulse automation instances And I click on "WELCOME MESSAGE" item in the autocomplete list Then I click on "Add automation instance" "button" And I set the following fields to these values: - | override[title] | 1 | - | Title | WELCOME MESSAGE Instance | - | insreference | Welcomemessageinstance | + | override[title] | 1 | + | Title | WELCOME MESSAGE Instance | + | insreference | Welcomemessageinstance | And I press "Save changes" Then I should see "Template inserted successfully" And I should see "WELCOME MESSAGE" in the "#pulse_automation_template" "css_element" @@ -50,9 +50,9 @@ Feature: Pulse automation instances Scenario: Edit the automation template instance. Given I log in as "admin" Then I create automation template with the following fields to these values: - | Title | WELCOME MESSAGE | - | Reference | Welcomemessage | - | Visibility| Show | + | Title | WELCOME MESSAGE | + | Reference | Welcomemessage | + | Visibility | Show | And I should see "WELCOME MESSAGE" in the "#pulse_automation_template" "css_element" And I am on "Course 1" course homepage And I follow "Automation" @@ -60,7 +60,7 @@ Feature: Pulse automation instances And I click on "WELCOME MESSAGE" item in the autocomplete list Then I click on "Add automation instance" "button" And I set the following fields to these values: - | insreference | Welcomemessage | + | insreference | Welcomemessage | And I press "Save changes" Then I should see "Template inserted successfully" And I should see "WELCOME MESSAGE" in the "#pulse_automation_template" "css_element" @@ -69,9 +69,9 @@ Feature: Pulse automation instances Then I click on ".action-edit" "css_element" in the "WELCOME MESSAGE" "table_row" Then I should see "Edit instance" And I set the following fields to these values: - | override[title] | 1 | - | Title | DEMO MESSAGE | - | insreference | demomessageinstance | + | override[title] | 1 | + | Title | DEMO MESSAGE | + | insreference | demomessageinstance | Then I press "Save changes" And I should see "DEMO MESSAGE" in the "#pulse_automation_template" "css_element" And I should not see "WELCOME MESSAGE" in the "#pulse_automation_template" "css_element" @@ -82,9 +82,9 @@ Feature: Pulse automation instances Scenario: Dupilcate the automation template instance. Given I log in as "admin" Then I create automation template with the following fields to these values: - | Title | WELCOME MESSAGE | - | Reference | Welcomemessage | - | Visibility | Show | + | Title | WELCOME MESSAGE | + | Reference | Welcomemessage | + | Visibility | Show | And I am on "Course 1" course homepage And I follow "Automation" When I open the autocomplete suggestions list @@ -105,24 +105,23 @@ Feature: Pulse automation instances Scenario: Delete the automation template instance. Given I log in as "admin" Then I create automation template with the following fields to these values: - | Title | WELCOME MESSAGE | - | Reference | Welcomemessage | - | Visibility | Show | + | Title | WELCOME MESSAGE | + | Reference | Welcomemessage | + | Visibility | Show | And I am on "Course 1" course homepage And I follow "Automation" When I open the autocomplete suggestions list And I click on "WELCOME MESSAGE" item in the autocomplete list Then I click on "Add automation instance" "button" And I set the following fields to these values: - | insreference | Welcomemessage | + | insreference | Welcomemessage | And I press "Save changes" And I should see "WELCOME MESSAGE" in the "#pulse_automation_template" "css_element" Then I click on "#pulse_automation_template .action-delete" "css_element" - #Then I should see "Confirmation" in the ".confirmation-dialogue" "css_element" - And I click on "Cancel" "button" in the ".confirmation-dialogue" "css_element" + And I click on "Cancel" "button" in the "Confirmation" "dialogue" And I should see "WELCOME MESSAGE" in the "#pulse_automation_template" "css_element" Then I click on "#pulse_automation_template .action-delete" "css_element" - And I click on "Yes" "button" in the ".confirmation-dialogue" "css_element" + And I click on "Yes" "button" in the "Confirmation" "dialogue" Then I should see "Nothing to display" And "#pulse_automation_template" "css_element" should not exist @@ -130,11 +129,11 @@ Feature: Pulse automation instances Scenario: Check the multiple automation template instance Given I log in as "admin" Then I create automation template with the following fields to these values: - | Title | WELCOME MESSAGE | - | Reference | Welcomemessage | + | Title | WELCOME MESSAGE | + | Reference | Welcomemessage | Then I create automation template with the following fields to these values: - | Title | Notification | - | Reference | notification | + | Title | Notification | + | Reference | notification | And I am on "Course 1" course homepage And I follow "Automation" When I open the autocomplete suggestions list @@ -145,7 +144,7 @@ Feature: Pulse automation instances Then I click on "Add automation instance" "button" Then the field "Title" matches value "WELCOME MESSAGE" And I set the following fields to these values: - | insreference | Welcomemessageinstance | + | insreference | Welcomemessageinstance | And I press "Save changes" And I should see "WELCOME MESSAGE" in the "#pulse_automation_template tbody tr:nth-child(1)" "css_element" When I open the autocomplete suggestions list @@ -153,7 +152,7 @@ Feature: Pulse automation instances Then I click on "Add automation instance" "button" Then the field "Title" matches value "Notification" And I set the following fields to these values: - | insreference | notificationinstance | + | insreference | notificationinstance | And I press "Save changes" And I should see "Notification" in the "#pulse_automation_template tbody tr:nth-child(2)" "css_element" When I open the autocomplete suggestions list @@ -161,8 +160,8 @@ Feature: Pulse automation instances Then I click on "Add automation instance" "button" Then the field "Title" matches value "WELCOME MESSAGE" And I set the following fields to these values: - | override[title] | 1 | - | insreference | Welcomemessageinstance2 | - | Title | WELCOME CONTENT | + | override[title] | 1 | + | insreference | Welcomemessageinstance2 | + | Title | WELCOME CONTENT | And I press "Save changes" And I should see "WELCOME CONTENT" diff --git a/tests/behat/pulse_automation_instance_management.feature b/tests/behat/pulse_automation_instance_management.feature index ceaefb8..a395ce2 100644 --- a/tests/behat/pulse_automation_instance_management.feature +++ b/tests/behat/pulse_automation_instance_management.feature @@ -81,6 +81,147 @@ Feature: Pulse automation instances management And I should see "1" in the "Course 4" "table_row" And I log out + @javascript + Scenario: Add instances in the Instance Management + Given I log in as "admin" + And I navigate to "Plugins > Activity modules > Automation templates" in site administration + And I click on ".action-edit" "css_element" in the "Template1" "table_row" + And I click on "Instance Management" "link" + And I click on "Select all" "link" in the "#manage-instance-tab" "css_element" + And I click on "#bulkdelete-btn" "css_element" in the ".bulkaction-group" "css_element" + And I click on "Yes" "button" in the "Confirmation" "dialogue" + + And I should see "0" in the "Course 1" "table_row" + And I click on ".action-add-instance" "css_element" in the "Course 1" "table_row" + And I click on "Automation templates" "link" in the ".breadcrumb" "css_element" + And I should see "1(0)" in the "temp1" "table_row" + And I click on ".action-edit" "css_element" in the "Template1" "table_row" + And I click on "Instance Management" "link" + And I should see "1" in the "Course 1" "table_row" + + And I set the field with xpath "//tr[contains(normalize-space(.), 'Course 1')]//input[@type='checkbox']" to "bc[]" + And I click on "#bulkadd-btn" "css_element" in the ".bulkaction-group" "css_element" + And I click on "Yes" "button" in the "Confirmation" "dialogue" + And I click on "Automation templates" "link" in the ".breadcrumb" "css_element" + And I should see "2(0)" in the "temp1" "table_row" + And I click on ".action-edit" "css_element" in the "Template1" "table_row" + And I click on "Instance Management" "link" + And I should see "2" in the "Course 1" "table_row" + + And I click on ".action-add-instance" "css_element" in the "Course 2" "table_row" + And I click on "Automation templates" "link" in the ".breadcrumb" "css_element" + And I should see "3(0)" in the "temp1" "table_row" + And I click on ".action-edit" "css_element" in the "Template1" "table_row" + And I click on "Instance Management" "link" + And I should see "1" in the "Course 2" "table_row" + + And I click on "Select all without instances" "link" in the "#manage-instance-tab" "css_element" + And I click on "#bulkadd-btn" "css_element" in the ".bulkaction-group" "css_element" + And I click on "Yes" "button" in the "Confirmation" "dialogue" + And I click on "Automation templates" "link" in the ".breadcrumb" "css_element" + And I should see "5(0)" in the "temp1" "table_row" + And I click on ".action-edit" "css_element" in the "Template1" "table_row" + And I click on "Instance Management" "link" + And I should see "1" in the "Course 3" "table_row" + And I should see "1" in the "Course 4" "table_row" + + And I click on ".fa-calendar" "css_element" in the "Course 1" "table_row" + And I switch to a second window + Then I should see "Template1" in the "temp1C1" "table_row" + + @javascript + Scenario: Modify the instances with bulk action group + Given I log in as "admin" + And I navigate to "Plugins > Activity modules > Automation templates" in site administration + And I click on ".action-edit" "css_element" in the "Template1" "table_row" + And I click on "Instance Management" "link" + And I should see "1" in the "Course 1" "table_row" + + # Delete the instances for the Course + And I click on ".action-delete" "css_element" in the "Course 2" "table_row" + And I click on "Yes" "button" in the "Confirmation" "dialogue" + And I click on "Automation templates" "link" in the ".breadcrumb" "css_element" + And I should see "3(0)" in the "temp1" "table_row" + And I click on ".action-edit" "css_element" in the "Template1" "table_row" + And I click on "Instance Management" "link" + And I should see "0" in the "Course 2" "table_row" + + # Bulk delete the instances for the course + And I set the field with xpath "//tr[contains(normalize-space(.), 'Course 1')]//input[@type='checkbox']" to "bc[]" + And I click on "#bulkdelete-btn" "css_element" in the ".bulkaction-group" "css_element" + And I click on "Yes" "button" in the "Confirmation" "dialogue" + And I click on "Automation templates" "link" in the ".breadcrumb" "css_element" + And I should see "2(0)" in the "temp1" "table_row" + And I click on ".action-edit" "css_element" in the "Template1" "table_row" + And I click on "Instance Management" "link" + And I should see "0" in the "Course 1" "table_row" + + # Enable / Disable the instances with bulk option + And I set the field with xpath "//tr[contains(normalize-space(.), 'Course 3')]//input[@type='checkbox']" to "bc[]" + And I set the field with xpath "//tr[contains(normalize-space(.), 'Course 4')]//input[@type='checkbox']" to "bc[]" + And I click on "#bulkdisable-btn" "css_element" in the ".bulkaction-group" "css_element" + And I click on "Yes" "button" in the "Confirmation" "dialogue" + And ".pulse-manage-instance-status-switch .custom-control-input:checked" "css_element" should not exist in the "Course 3" "table_row" + And ".pulse-manage-instance-status-switch .custom-control-input:checked" "css_element" should not exist in the "Course 4" "table_row" + And I set the field with xpath "//tr[contains(normalize-space(.), 'Course 1')]//input[@type='checkbox']" to "bc[]" + And I set the field with xpath "//tr[contains(normalize-space(.), 'Course 2')]//input[@type='checkbox']" to "bc[]" + And I click on "#bulkadd-btn" "css_element" in the ".bulkaction-group" "css_element" + And I click on "Yes" "button" in the "Confirmation" "dialogue" + And I should see "1" in the "Course 1" "table_row" + And I should see "1" in the "Course 2" "table_row" + And I click on "Select all" "link" in the "#manage-instance-tab" "css_element" + And I click on "#bulkenable-btn" "css_element" in the ".bulkaction-group" "css_element" + And I click on "Yes" "button" in the "Confirmation" "dialogue" + And ".pulse-manage-instance-status-switch .custom-control-input:checked" "css_element" should exist in the "Course 1" "table_row" + And ".pulse-manage-instance-status-switch .custom-control-input:checked" "css_element" should exist in the "Course 3" "table_row" + + And I click on "Automation templates" "link" in the ".breadcrumb" "css_element" + And I click on ".action-edit" "css_element" in the "Notification1" "table_row" + And I click on "Instance Management" "link" + And I should see "1" in the "Course 1" "table_row" + And I click on "Select all" "link" in the "#manage-instance-tab" "css_element" + And I click on "#bulkadd-btn" "css_element" in the ".bulkaction-group" "css_element" + And I click on "Yes" "button" in the "Confirmation" "dialogue" + And I click on "Automation templates" "link" in the ".breadcrumb" "css_element" + + And I should see "5(0)" in the "notification1" "table_row" + And I click on ".action-edit" "css_element" in the "Notification1" "table_row" + And I click on "Instance Management" "link" + And I should see "2" in the "Course 1" "table_row" + + And I click on ".action-edit" "css_element" in the "Course 1" "table_row" + And I switch to a second window + And I should see "Template1" in the "temp1C1" "table_row" + And I should see "Notification1" in the "notification1C1" "table_row" + And I close all opened windows + And I click on ".action-report" "css_element" in the "Course 1" "table_row" + And I switch to a second window + Then "Template1" "table_row" should not exist + And I should see "Notification1" in the "notification1C1" "table_row" + And I close all opened windows + + # Filter the available course categories + And I click on "#tool-details-tab" "css_element" + And I wait "2" seconds + And I set the following fields to these values: + | Available in course categories | Category 1, Cat 1 | + And I press "Save changes" + And I click on ".action-edit" "css_element" in the "Notification1" "table_row" + And I click on "Instance Management" "link" + And I should see "Course 1" in the "Category 1" "table_row" + And I should see "Course 2" in the "Cat 1" "table_row" + And "Course 3" "table_row" should not exist + And I click on "#tool-details-tab" "css_element" + And I click on "span.badge" "css_element" in the "#fitem_id_categories .form-autocomplete-selection" "css_element" + And I wait "1" seconds + And I click on "span.badge" "css_element" in the "#fitem_id_categories .form-autocomplete-selection" "css_element" + And I press "Save changes" + And I click on ".action-edit" "css_element" in the "Notification1" "table_row" + And I click on "Instance Management" "link" + And I should see "Course 1" in the "Category 1" "table_row" + And I should see "Course 3" in the "Cat 2" "table_row" + And I wait "5" seconds + @javascript Scenario: Instance mixed status check Given I log in as "admin" @@ -104,4 +245,444 @@ Feature: Pulse automation instances management And I click on "Instance Management" "link" And I should see "Mixed" in the "Course 1" "table_row" And I should see "3" in the "Course 1" "table_row" - And I wait "15" seconds + + @javascript + Scenario: Utilizing the filter option in instance management + Given I log in as "admin" + And I navigate to "Plugins > Activity modules > Automation templates" in site administration + And I click on ".action-edit" "css_element" in the "Template1" "table_row" + And I click on "Instance Management" "link" + And I should see "1" in the "Course 1" "table_row" + + # Filtering "Category" + And I click on "#pulse-manageinstance-filter" "css_element" in the "#manage-instance-tab" "css_element" + And I set the following fields to these values: + | Category | Category 1 | + And I click on "Filter" "button" in the "#fitem_id_submitbutton" "css_element" + And I should see "Course 1" in the "Category 1" "table_row" + And "Cat 1" "table_row" should not exist + And I click on "#pulse-manageinstance-filter" "css_element" in the "#manage-instance-tab" "css_element" + And I set the following fields to these values: + | Category | All | + And I click on "Filter" "button" in the "#fitem_id_submitbutton" "css_element" + And I should see "Course 1" in the "Category 1" "table_row" + And I should see "Course 2" in the "Cat 1" "table_row" + And I wait "5" seconds + + # Filtering "Course" + And I click on "#pulse-manageinstance-filter" "css_element" in the "#manage-instance-tab" "css_element" + And I set the following fields to these values: + | Course name | Course 1 | + And I click on "Filter" "button" in the "#fitem_id_submitbutton" "css_element" + And I should see "Course 1" in the "Category 1" "table_row" + And "Cat 2" "table_row" should not exist + And I click on "#pulse-manageinstance-filter" "css_element" in the "#manage-instance-tab" "css_element" + And I set the following fields to these values: + | Course name | All | + And I click on "Filter" "button" in the "#fitem_id_submitbutton" "css_element" + And I should see "Course 1" in the "Category 1" "table_row" + And I should see "Course 2" in the "Cat 1" "table_row" + + # Filtering "Number of instances" + And I click on ".action-add-instance" "css_element" in the "Course 1" "table_row" + And I click on "Instance Management" "link" + And I should see "2" in the "Course 1" "table_row" + And I click on "#pulse-manageinstance-filter" "css_element" in the "#manage-instance-tab" "css_element" + And I set the following fields to these values: + | Number of instance | 2 | + And I click on "Filter" "button" in the "#fitem_id_submitbutton" "css_element" + And I should see "2" in the "Category 1" "table_row" + And "Cat 1" "table_row" should not exist + And I click on "#pulse-manageinstance-filter" "css_element" in the "#manage-instance-tab" "css_element" + And I set the following fields to these values: + | Number of instance | | + And I click on "Filter" "button" in the "#fitem_id_submitbutton" "css_element" + And I should see "2" in the "Category 1" "table_row" + And I should see "1" in the "Cat 1" "table_row" + + # Filtering "Number of overrides" + @javascript + Scenario: Utilizing the number of overrides filter option in instance management + Given I log in as "admin" + And I navigate to "Plugins > Activity modules > Automation templates" in site administration + And I click on ".action-edit" "css_element" in the "Template1" "table_row" + And I click on "Instance Management" "link" + And I should see "1" in the "Course 1" "table_row" + + # Number of override: 1 + And I click on ".action-report" "css_element" in the "Category 1" "table_row" + And I switch to a second window + And I should see "Template1" in the "temp1C1" "table_row" + And I click on ".action-edit" "css_element" in the "Template1" "table_row" + And I click on ".checkboxgroupautomation" "css_element" in the "#fitem_id_title" "css_element" + And I set the following fields to these values: + | Title | Template01 | + | Reference | C2 | + And I wait "2" seconds + And I press "Save changes" + And I should see "Template01" in the "temp1C2" "table_row" + And I navigate to "Plugins > Activity modules > Automation templates" in site administration + And I click on ".action-edit" "css_element" in the "Template1" "table_row" + And I click on "Instance Management" "link" + + And I click on "#pulse-manageinstance-filter" "css_element" in the "#manage-instance-tab" "css_element" + And I set the following fields to these values: + | Number of overrides | 1 | + And I click on "Filter" "button" in the "#fitem_id_submitbutton" "css_element" + And I should see "Course 1" in the "Category 1" "table_row" + And "Cat 1" "table_row" should not exist + + And I click on "#pulse-manageinstance-filter" "css_element" in the "#manage-instance-tab" "css_element" + And I set the following fields to these values: + | Number of overrides | 0 | + And I click on "Filter" "button" in the "#fitem_id_submitbutton" "css_element" + And I should see "Course 2" in the "Cat 1" "table_row" + And I should see "Course 3" in the "Cat 2" "table_row" + And I should see "Course 4" in the "Cat 3" "table_row" + And "Category 1" "table_row" should not exist + + And I click on "#pulse-manageinstance-filter" "css_element" in the "#manage-instance-tab" "css_element" + And I set the following fields to these values: + | Number of overrides | | + And I click on "Filter" "button" in the "#fitem_id_submitbutton" "css_element" + And I should see "Course 1" in the "Category 1" "table_row" + And I should see "Course 2" in the "Cat 1" "table_row" + + And I click on ".action-edit" "css_element" in the "Course 2" "table_row" + And I switch to a pulse open window + And I should see "Template1" in the "temp1C2" "table_row" + And I click on ".action-edit" "css_element" in the "Template1" "table_row" + And I click on ".checkboxgroupautomation" "css_element" in the "#fitem_id_title" "css_element" + And I set the following fields to these values: + | Title | Template02 | + And I press "Save changes" + And I should see "Template02" in the "temp1C2" "table_row" + And I navigate to "Plugins > Activity modules > Automation templates" in site administration + And I click on ".action-edit" "css_element" in the "Template1" "table_row" + And I click on "Instance Management" "link" + + And I click on "#pulse-manageinstance-filter" "css_element" in the "#manage-instance-tab" "css_element" + And I set the following fields to these values: + | Number of overrides | 1 | + And I click on "Filter" "button" in the "#fitem_id_submitbutton" "css_element" + And I should see "Course 1" in the "Category 1" "table_row" + And I should see "Course 2" in the "Cat 1" "table_row" + And "Cat 2" "table_row" should not exist + + # Number of override: 2 + And I click on ".action-edit" "css_element" in the "Course 1" "table_row" + And I switch to a pulse open window + And I click on ".action-edit" "css_element" in the "Template01" "table_row" + And I click on ".checkboxgroupautomation" "css_element" in the "#fitem_id_notes" "css_element" + And I set the following fields to these values: + | Internal notes | Demo Template01 | + And I press "Save changes" + And I navigate to "Plugins > Activity modules > Automation templates" in site administration + And I click on ".action-edit" "css_element" in the "Template1" "table_row" + And I click on "Instance Management" "link" + + And I click on "#pulse-manageinstance-filter" "css_element" in the "#manage-instance-tab" "css_element" + And I set the following fields to these values: + | Number of overrides | 2 | + And I click on "Filter" "button" in the "#fitem_id_submitbutton" "css_element" + And I should see "Course 1" in the "Category 1" "table_row" + And "Cat 1" "table_row" should not exist + + And I click on ".action-edit" "css_element" in the "Course 1" "table_row" + And I switch to a pulse open window + And I click on ".action-edit" "css_element" in the "Template01" "table_row" + And I click on ".checkboxgroupautomation" "css_element" in the "#fitem_id_notes" "css_element" + And I press "Save changes" + And I navigate to "Plugins > Activity modules > Automation templates" in site administration + And I click on ".action-edit" "css_element" in the "Template1" "table_row" + And I click on "Instance Management" "link" + + And I click on "#pulse-manageinstance-filter" "css_element" in the "#manage-instance-tab" "css_element" + And I set the following fields to these values: + | Number of overrides | 2 | + And I click on "Filter" "button" in the "#fitem_id_submitbutton" "css_element" + And I should see "Nothing to display" in the "#manage-instance-table" "css_element" + + And I click on "#pulse-manageinstance-filter" "css_element" in the "#manage-instance-tab" "css_element" + And I set the following fields to these values: + | Number of overrides | 1 | + And I click on "Filter" "button" in the "#fitem_id_submitbutton" "css_element" + And I should see "Course 1" in the "Category 1" "table_row" + And I wait "2" seconds + + @javascript + Scenario: Delete action for the template + Given I log in as "admin" + And I navigate to "Plugins > Activity modules > Automation templates" in site administration + And I click on ".action-edit" "css_element" in the "Notification1" "table_row" + And I click on "Instance Management" "link" + And I click on ".action-edit" "css_element" in the "Course 1" "table_row" + And I switch to a second window + And I should see "Notification1" in the "notification1C1" "table_row" + And I should see "Template1" in the "temp1C1" "table_row" + And I click on ".form-autocomplete-downarrow" "css_element" in the "#fitem_id_templateid .align-items-start" "css_element" + And "Template1" "text" in the "#fitem_id_templateid .form-autocomplete-suggestions" "css_element" should be visible + And "Notification1" "text" in the "#fitem_id_templateid .form-autocomplete-suggestions" "css_element" should be visible + And I close all opened windows + And I click on "Automation templates" "link" in the ".breadcrumb" "css_element" + And I click on ".action-delete" "css_element" in the "notification1" "table_row" + And I click on "Yes" "button" in the "Confirmation" "dialogue" + And "Notification1" "table_row" should not exist + And I click on ".action-edit" "css_element" in the "Template1" "table_row" + And I click on "Instance Management" "link" + And I should see "1" in the "Course 1" "table_row" + And I click on ".action-edit" "css_element" in the "Course 1" "table_row" + And I switch to a second window + And I should see "Template1" in the "temp1C1" "table_row" + And "notification1C1" "table_row" should not exist + And I click on ".form-autocomplete-downarrow" "css_element" in the "#fitem_id_templateid .align-items-start" "css_element" + And "Template1" "text" in the "#fitem_id_templateid .form-autocomplete-suggestions" "css_element" should be visible + And "Notification1" "text" in the "#fitem_id_templateid .form-autocomplete-suggestions" "css_element" should not be visible + And I wait "2" seconds + + @javascript + Scenario: Additional column added for the report source + Given I log in as "student1" + And I am on "Course 1" course homepage + And I am on the "Assign1" "assign activity" page + And I press "Mark as done" + And I log out + + And I log in as "admin" + And I navigate to course "Course 1" automation instances + And I should see "Template1" in the "temp1C1" "table_row" + And I click on ".action-edit" "css_element" in the "Template1" "table_row" + And I click on "#id_override_title" "css_element" in the "#fitem_id_title" "css_element" + And I set the field "Title" to "Template01" + And I click on "Condition" "link" in the "#automation-tabs" "css_element" + And I click on "#id_override_triggeroperator" "css_element" in the "#fitem_id_triggeroperator" "css_element" + And I set the field "Trigger operator" to "Any" + And I click on "#id_override_condition_activity_status" "css_element" in the "#fitem_id_condition_activity_status" "css_element" + And I set the field "Activity completion" to "All" + And I wait "2" seconds + And I set the field "Select activities" to "Assign1" + And I click on "Notification" "link" in the "#automation-tabs" "css_element" + And I click on "#id_override_pulsenotification_recipients" "css_element" in the "#fitem_id_pulsenotification_recipients" "css_element" + And I set the field "Recipients" to "Student" + And I click on "#id_override_pulsenotification_cc" "css_element" in the "#fitem_id_pulsenotification_cc" "css_element" + And I set the field "Cc" to "Teacher" + And I press "Save changes" + + And I wait "3" seconds + And I click on ".action-report" "css_element" in the "Template01" "table_row" + And I switch to a second window + And I should see "student User 1" in the "Course 1" "table_row" + And I log out + + And I log in as "admin" + And I navigate to "Reports > Report builder > Custom reports" in site administration + And I click on "New report" "button" + And I set the following fields in the "New report" "dialogue" to these values: + | Name | My report | + | Report source | Notification | + | Include default setup | 0 | + And I click on "Save" "button" in the "New report" "dialogue" + And I wait until the page is ready + Then I should see "My report" + And I click on "Template title" "link" in the ".reportbuilder-sidebar-menu-cards .card-body" "css_element" + And I should see "Template1" in the ".reportbuilder-table tbody tr td" "css_element" + And I click on "Template reference" "link" in the ".reportbuilder-sidebar-menu-cards .card-body" "css_element" + And I should see "temp1" in the "Template1" "table_row" + And I click on "Instance title" "link" in the ".reportbuilder-sidebar-menu-cards .card-body" "css_element" + And I wait "2" seconds + And I should see "Template01" in the "temp1" "table_row" + And I click on "Instance reference" "link" in the ".reportbuilder-sidebar-menu-cards .card-body" "css_element" + And I wait "2" seconds + And I should see "C1" in the "temp1" "table_row" + + @javascript + Scenario: A instance override capabiltiy check + Given I log in as "admin" + And I navigate to "Plugins > Activity modules > Automation templates" in site administration + And I click on ".action-edit" "css_element" in the "Template1" "table_row" + And I click on "Instance Management" "link" + And I should see "1" in the "Course 1" "table_row" + And I log out + + # Allow the instance override + And I log in as "teacher1" + And I navigate to course "Course 1" automation instances + And I click on ".action-edit" "css_element" in the "Notification1" "table_row" + And I click on ".checkboxgroupautomation" "css_element" in the "#fitem_id_title" "css_element" + And I set the following fields to these values: + | Title | Template01 | + And I wait "2" seconds + And I press "Save changes" + And I wait "10" seconds + And I should see "Template01" in the "notification1C1" "table_row" + And I close all opened windows + And I log out + + # Allow the instance override + And I log in as "admin" + And I navigate to "Users > Permissions > Define roles" in site administration + And I click on ".fa-cog" "css_element" in the "teacher" "table_row" + And I set the field "mod/pulse:overridetemplateinstance" to "0" + And I press "Save changes" + And I log out + + And I log in as "teacher1" + And I navigate to course "Course 1" automation instances + And I click on ".action-edit" "css_element" in the "Template01" "table_row" + And ".form-control[disabled='disabled']" "css_element" should exist in the "#fitem_id_title" "css_element" + And I press "Save changes" + And I should see "Notification1" in the "notification1C1" "table_row" + And I close all opened windows + + @javascript + Scenario: Placeholder for extending assignment submission deadlines + Given I log in as "admin" + And I am on "Course 1" course homepage + And I am on the "Assign1" "assign activity" page + And I click on "Settings" "link" in the ".secondary-navigation" "css_element" + And I set the following fields to these values: + | Due date | ##1 March 2024## | + And I press "Save and display" + + And I am on the "Assign2" "assign activity" page + And I click on "Settings" "link" in the ".secondary-navigation" "css_element" + And I set the following fields to these values: + | Due date | ##31 March 2024## | + And I press "Save and display" + + And I am on the "Assign3" "assign activity" page + And I click on "Settings" "link" in the ".secondary-navigation" "css_element" + And I set the following fields to these values: + | Due date | ##1 April 2024## | + And I press "Save and display" + + And I navigate to course "Course 1" automation instances + And I click on ".action-edit" "css_element" in the "Template1" "table_row" + And I click on "Notification" "link" in the "#automation-tabs" "css_element" + And I click on "#id_override_pulsenotification_headercontent_editor" "css_element" in the "#fitem_id_pulsenotification_headercontent_editor" "css_element" + And I wait "2" seconds + And I click on ".fa-angle-double-down" "css_element" in the "#header-email-vars-button" "css_element" + And I click on "Show more" "link" in the ".User_field-placeholders" "css_element" + And I click on "Show less" "link" in the ".User_field-placeholders" "css_element" + And I click on "#id_pulsenotification_headercontent_editor_ifr" "css_element" in the "#fitem_id_pulsenotification_headercontent_editor" "css_element" + And I click on "Extensions" "link" in the ".Assignment_field-placeholders .placeholders" "css_element" + And I click on "Preview" "button" in the "#fitem_id_pulsenotification_preview" "css_element" + And I should see "No extensions have been granted for upcoming assignments." in the "Preview" "dialogue" + And I click on ".close" "css_element" in the "Preview" "dialogue" + And I press "Save changes" + And I log out + + And I log in as "student1" + And I am on "Course 1" course homepage + And I am on the "Assign1" "assign activity" page + And I should see "The due date for this assignment has now passed" in the "Time remaining" "table_row" + And I am on the "Assign3" "assign activity" page + And I should see "The due date for this assignment has now passed" in the "Time remaining" "table_row" + And I log out + + # Due date extension in assign1 activity + And I log in as "admin" + And I am on "Course 1" course homepage + And I am on the "Assign1" "assign activity" page + And I click on "View all submissions" "link" in the ".tertiary-navigation" "css_element" + And I click on "Edit" "link" in the "student User 1" "table_row" + And I choose "Grant extension" in the open action menu + And I set the following fields to these values: + | Extension due date | ##1 July 2024## | + And I press "Save changes" + And I should see "Extension granted until: Monday, 1 July 2024, 12:00 AM" in the "student User 1" "table_row" + + # Due date extension in assign3 activity + And I am on the "Assign3" "assign activity" page + And I click on "View all submissions" "link" in the ".tertiary-navigation" "css_element" + And I click on "Edit" "link" in the "student User 1" "table_row" + And I choose "Grant extension" in the open action menu + And I set the following fields to these values: + | Extension due date | ##2 August 2024 14:27## | + And I press "Save changes" + And I should see "Extension granted until: Friday, 2 August 2024, 2:27 PM" in the "student User 1" "table_row" + + And I navigate to course "Course 1" automation instances + And I click on ".action-edit" "css_element" in the "Template1" "table_row" + And I click on "Notification" "link" in the "#automation-tabs" "css_element" + And I click on "Preview" "button" in the "#fitem_id_pulsenotification_preview" "css_element" + And I wait "10" seconds + And I should see "Assign1: Monday, 1 July 2024, 12:00 AM(Previously: Friday, 1 March 2024, 12:00 AM)" in the "Preview" "dialogue" + And I should see "Assign3: Friday, 2 August 2024, 2:27 PM(Previously: Monday, 1 April 2024, 12:00 AM)" in the "Preview" "dialogue" + And I click on ".close" "css_element" in the "Preview" "dialogue" + And I press "Save changes" + And I log out + + And I log in as "student1" + And I am on "Course 1" course homepage + And I am on the "Assign1" "assign activity" page + And I should see "Monday, 1 July 2024, 12:00 AM" in the "Extension due date" "table_row" + And I press "Mark as done" + + And I am on the "Assign3" "assign activity" page + And I should see "Friday, 2 August 2024, 2:27 PM" in the "Extension due date" "table_row" + And I press "Mark as done" + And I log out + + And I log in as "admin" + And I navigate to course "Course 1" automation instances + And I click on ".action-edit" "css_element" in the "Template1" "table_row" + And I click on "Notification" "link" in the "#automation-tabs" "css_element" + And I click on "Preview" "button" in the "#fitem_id_pulsenotification_preview" "css_element" + And I should see "No extensions have been granted for upcoming assignments." in the "Preview" "dialogue" + And I click on ".close" "css_element" in the "Preview" "dialogue" + And I press "Save changes" + + @javascript + Scenario: Notification of events condition for extending assignment submission deadlines + Given I log in as "admin" + And I am on "Course 1" course homepage + And I am on the "Assign1" "assign activity" page + And I click on "Settings" "link" in the ".secondary-navigation" "css_element" + And I set the following fields to these values: + | Due date | ##1 March 2024## | + And I press "Save and display" + And I log out + + And I log in as "student1" + And I am on "Course 1" course homepage + And I am on the "Assign1" "assign activity" page + And I should see "The due date for this assignment has now passed" in the "Time remaining" "table_row" + And I log out + + And I log in as "admin" + And I navigate to course "Course 1" automation instances + And I should see "Template1" in the "temp1C1" "table_row" + And I click on ".action-edit" "css_element" in the "Template1" "table_row" + And I click on "Condition" "link" in the "#automation-tabs" "css_element" + And I click on "#id_override_triggeroperator" "css_element" in the "#fitem_id_triggeroperator" "css_element" + And I set the field "Trigger operator" to "Any" + And I click on "#id_override_condition_events_status" "css_element" in the "#fitem_id_condition_events_status" "css_element" + And I set the field "Events completion" to "All" + And I open the autocomplete suggestions list in the "Event" "fieldset" + And I click on "An extension has been granted. \mod_assign\event\extension_granted" item in the autocomplete list + And I set the field "User" to "1" + And I set the field "Event module" to "Assign1" + And I click on "Notification" "link" in the "#automation-tabs" "css_element" + And I click on "#id_override_pulsenotification_recipients" "css_element" in the "#fitem_id_pulsenotification_recipients" "css_element" + And I set the field "Recipients" to "Student" + And I click on "#id_override_pulsenotification_cc" "css_element" in the "#fitem_id_pulsenotification_cc" "css_element" + And I set the field "Cc" to "Teacher" + And I press "Save changes" + + And I am on "Course 1" course homepage + And I am on the "Assign1" "assign activity" page + And I click on "View all submissions" "link" in the ".tertiary-navigation" "css_element" + And I click on "Edit" "link" in the "student User 1" "table_row" + And I choose "Grant extension" in the open action menu + And I set the following fields to these values: + | Extension due date | ##1 July 2024## | + And I press "Save changes" + And I should see "Extension granted until: Monday, 1 July 2024, 12:00 AM" in the "student User 1" "table_row" + And I navigate to course "Course 1" automation instances + And I trigger cron + And I navigate to course "Course 1" automation instances + And I should see "Template1" in the "temp1C1" "table_row" + And I click on ".action-report" "css_element" in the "temp1C1" "table_row" + And I switch to a second window + And I should see "sent" in the "Template1" "table_row" diff --git a/tests/behat/pulse_automation_template.feature b/tests/behat/pulse_automation_template.feature index 59cb070..10236b0 100644 --- a/tests/behat/pulse_automation_template.feature +++ b/tests/behat/pulse_automation_template.feature @@ -9,18 +9,18 @@ Feature: Pulse automation templates | Cat 1 | 0 | CAT1 | | Cat 2 | 0 | CAT2 | And the following "course" exist: - | fullname | shortname | category | - | Course 1 | C1 | 0 | - | Course 2 | C2 | CAT1 | - | Course 3 | C3 | CAT2 | + | fullname | shortname | category | + | Course 1 | C1 | 0 | + | Course 2 | C2 | CAT1 | + | Course 3 | C3 | CAT2 | And the following "users" exist: - | username | firstname | lastname | email | - | student1 | student | User 1 | student1@test.com | - | teacher1 | Teacher | User 1 | teacher1@test.com | + | username | firstname | lastname | email | + | student1 | student | User 1 | student1@test.com | + | teacher1 | Teacher | User 1 | teacher1@test.com | And the following "course enrolments" exist: - | user | course | role | + | user | course | role | | teacher1 | C1 | editingteacher | - | student1 | C1 | student | + | student1 | C1 | student | @javascript Scenario: Check the automation template. @@ -30,10 +30,10 @@ Feature: Pulse automation templates And I should see "Create new template" Then I click on "Create new template" "button" And I set the following fields to these values: - | Title | WELCOME MESSAGE | - | Reference | Welcomemessage | - | Visibility| Show | - | Status | Enabled | + | Title | WELCOME MESSAGE | + | Reference | Welcomemessage | + | Visibility | Show | + | Status | Enabled | Then I press "Save changes" Then I should see "Template inserted successfully" Then I should see "Automation templates" @@ -42,8 +42,8 @@ Feature: Pulse automation templates And I should see "Welcomemessage" in the "#pulse_automation_template .template-reference" "css_element" And "#pulse_automation_template .menu-item-actions .action-edit" "css_element" should exist Then I create automation template with the following fields to these values: - | Title | Triggers | - | Reference | Conditiontriggers | + | Title | Triggers | + | Reference | Conditiontriggers | Then I should see "Template inserted successfully" And I should see "WELCOME MESSAGE" in the "#pulse_automation_template tbody tr:nth-child(1)" "css_element" And I should see "Welcomemessage" in the "#pulse_automation_template tbody tr:nth-child(1) .template-reference" "css_element" @@ -63,8 +63,8 @@ Feature: Pulse automation templates Then I click on ".action-edit" "css_element" in the "WELCOME MESSAGE" "table_row" Then I should see "Edit template" And I set the following fields to these values: - | Title | Triggers | - | Reference | Conditiontriggers | + | Title | Triggers | + | Reference | Conditiontriggers | Then I press "Save changes" Then I should see "Template updated successfully" And I should see "Triggers" in the "#pulse_automation_template tbody tr:nth-child(1)" "css_element" @@ -74,9 +74,9 @@ Feature: Pulse automation templates Scenario: Check Visibility of automation template Given I log in as "admin" Then I create automation template with the following fields to these values: - | Title | WELCOME MESSAGE | - | Reference | Welcomemessage | - | Visibility| Show | + | Title | WELCOME MESSAGE | + | Reference | Welcomemessage | + | Visibility | Show | And I should see "WELCOME MESSAGE" in the "#pulse_automation_template" "css_element" And I am on "Course 1" course homepage Then I should see "Automation" @@ -105,10 +105,10 @@ Feature: Pulse automation templates Scenario: Check Status of automation template Given I log in as "admin" Then I create automation template with the following fields to these values: - | Title | WELCOME MESSAGE | - | Reference | Welcomemessage | - | Visibility| Show | - | Status | Enable | + | Title | WELCOME MESSAGE | + | Reference | Welcomemessage | + | Visibility | Show | + | Status | Enable | And I should see "WELCOME MESSAGE" in the "#pulse_automation_template" "css_element" And I am on "Course 1" course homepage Then I should see "Automation" @@ -137,9 +137,9 @@ Feature: Pulse automation templates Scenario: Check Available in course categories for automation template Given I log in as "admin" Then I create automation template with the following fields to these values: - | Title | WELCOME MESSAGE | - | Reference | Welcomemessage | - | Available in course categories | Category 1 | + | Title | WELCOME MESSAGE | + | Reference | Welcomemessage | + | Available in course categories | Category 1 | And I am on "Course 1" course homepage Then I should see "Automation" And I follow "Automation" @@ -187,12 +187,12 @@ Feature: Pulse automation templates Scenario: Check condition for automation template Given I log in as "admin" Then I create automation template with the following fields to these values: - | Title | WELCOME MESSAGE | - | Reference | Welcomemessage | - | Available in course categories | Category 1 | + | Title | WELCOME MESSAGE | + | Reference | Welcomemessage | + | Available in course categories | Category 1 | Then I create "Welcomemessage" template with the set the condition: - | Triggers | Activity completion, Member in cohorts | - | Trigger operator | All | + | Triggers | Activity completion, Member in cohorts | + | Trigger operator | All | And I am on "Course 1" course homepage And I follow "Automation" When I open the autocomplete suggestions list @@ -211,20 +211,20 @@ Feature: Pulse automation templates Given I log in as "admin" And I navigate to "Plugins > Activity modules > Pulse > Automation templates" in site administration Then I create automation template with the following fields to these values: - | Title | WELCOME MESSAGE | - | Reference | Welcomemessage | - | Available in course categories | Category 1 | + | Title | WELCOME MESSAGE | + | Reference | Welcomemessage | + | Available in course categories | Category 1 | Then I create "Welcomemessage" template with the set the condition: - | Triggers | Activity completion, Member in cohorts | - | Trigger operator | All | + | Triggers | Activity completion, Member in cohorts | + | Trigger operator | All | Then I create "Welcomemessage" template with the set the notification: - | Sender | Group teacher | - | Interval | Once | - | Cc | Teacher | - | Bcc | Manager | - | Subject | Demo MESSAGE | - | Header content | Lorem Ipsum is therefore always free from repetition, injected humour| - | Static content | There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form | + | Sender | Group teacher | + | Interval | Once | + | Cc | Teacher | + | Bcc | Manager | + | Subject | Demo MESSAGE | + | Header content | Lorem Ipsum is therefore always free from repetition, injected humour | + | Static content | There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form | Then I should see "Template updated successfully" And I am on "Course 1" course homepage And I follow "Automation" @@ -252,25 +252,25 @@ Feature: Pulse automation templates And I click on "WELCOME MESSAGE" item in the autocomplete list Then I click on "Add automation instance" "button" And I set the following fields to these values: - | insreference | Welcomemessageinstance | + | insreference | Welcomemessageinstance | And I press "Save changes" When I open the autocomplete suggestions list And I click on "WELCOME MESSAGE" item in the autocomplete list Then I click on "Add automation instance" "button" And I set the following fields to these values: - | insreference | Welcomemessageinstance2 | + | insreference | Welcomemessageinstance2 | And I press "Save changes" When I open the autocomplete suggestions list And I click on "WELCOME MESSAGE" item in the autocomplete list Then I click on "Add automation instance" "button" And I set the following fields to these values: - | insreference | Welcomemessageinstance3 | + | insreference | Welcomemessageinstance3 | And I press "Save changes" When I open the autocomplete suggestions list And I click on "Notification" item in the autocomplete list Then I click on "Add automation instance" "button" And I set the following fields to these values: - | insreference | notificationinstance | + | insreference | notificationinstance | And I press "Save changes" And I navigate to "Plugins > Activity modules > Pulse > Automation templates" in site administration And I should see "3(0)" in the "WELCOME MESSAGE" "table_row" diff --git a/tests/behat/pulse_preset.feature b/tests/behat/pulse_preset.feature index b9fcbea..fba3cbe 100644 --- a/tests/behat/pulse_preset.feature +++ b/tests/behat/pulse_preset.feature @@ -7,16 +7,16 @@ Feature: Preset create pulse with custom params. Background: Insert demo presets. Given the following "courses" exist: - | fullname| shortname | category | - | Test | C1 | 0 | + | fullname | shortname | category | + | Test | C1 | 0 | And the following "users" exist: - | username | firstname | lastname | email | - | student1 | student | User 1 | student1@test.com | - | teacher | Teacher | User 1 | teacher1@test.com | + | username | firstname | lastname | email | + | student1 | student | User 1 | student1@test.com | + | teacher | Teacher | User 1 | teacher1@test.com | And the following "course enrolments" exist: - | user | course | role | - | teacher | C1 | editingteacher | - | student1 | C1 | student | + | user | course | role | + | teacher | C1 | editingteacher | + | student1 | C1 | student | Given I log in as "admin" And I create demo presets And I log out diff --git a/tests/behat/pulse_visibility.feature b/tests/behat/pulse_visibility.feature index 0df7cf2..a8f833b 100644 --- a/tests/behat/pulse_visibility.feature +++ b/tests/behat/pulse_visibility.feature @@ -8,20 +8,20 @@ Feature: Check pulse activity works @javascript Scenario: Pulse activity should shown the Content text. Given the following "courses" exist: - | fullname| shortname | category | - | Test | C1 | 0 | + | fullname | shortname | category | + | Test | C1 | 0 | And the following "users" exist: - | username | firstname | lastname | email | - | student1 | student | User 1 | student1@test.com | - | teacher1 | Teacher | User 1 | teacher1@test.com | + | username | firstname | lastname | email | + | student1 | student | User 1 | student1@test.com | + | teacher1 | Teacher | User 1 | teacher1@test.com | And the following "course enrolments" exist: - | user | course | role | - | teacher1 | C1 | editingteacher | - | student1 | C1 | student | + | user | course | role | + | teacher1 | C1 | editingteacher | + | student1 | C1 | student | Given I log in as "teacher1" And I am on "Test" course homepage with editing mode on When I add a "pulse" to section "1" and I fill the form with: - | Title | Test pulse | + | Title | Test pulse | | Content | Test pulse content | Then "Test pulse content" activity should be visible And I turn editing mode off