diff --git a/amd/build/automation.min.js.map b/amd/build/automation.min.js.map
index 87a54e8..7094e8f 100644
--- a/amd/build/automation.min.js.map
+++ b/amd/build/automation.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"automation.min.js","sources":["../src/automation.js"],"sourcesContent":["define(\"mod_pulse/automation\", ['jquery', 'core/modal_factory', 'core/templates', 'core/str', \"core/notification\"],\r\n function($, Modal, Template, Str, notification) {\r\n\r\n const moveOutMoreMenu = (navMenu) => {\r\n\r\n if (navMenu === null) {\r\n return;\r\n }\r\n\r\n var menu = navMenu.querySelector('a.automation-templates');\r\n\r\n if (menu === null) {\r\n return;\r\n }\r\n\r\n menu = menu.parentNode;\r\n menu.dataset.forceintomoremenu = false;\r\n menu.querySelector('a').classList.remove('dropdown-item');\r\n menu.querySelector('a').classList.add('nav-link');\r\n menu.parentNode.removeChild(menu);\r\n\r\n // Insert the stored menus before the more menu.\r\n navMenu.insertBefore(menu, navMenu.children[1]);\r\n window.dispatchEvent(new Event('resize')); // Dispatch the resize event to create more menu.\r\n };\r\n\r\n const returnToFailedTab = () => {\r\n\r\n if (document.forms['pulse-automation-template'] === null) {\r\n return false;\r\n }\r\n\r\n document.forms['pulse-automation-template'].onsubmit = (e) => {\r\n var form = e.target;\r\n var invalidElement = form.querySelector('.is-invalid');\r\n if (invalidElement === null) {\r\n return true;\r\n }\r\n\r\n var tabid = invalidElement.parentNode.parentNode.parentNode.id;\r\n var hrefSelector = '[href=\"#' + tabid + '\"]';\r\n\r\n document.querySelector(hrefSelector).click();\r\n\r\n return true;\r\n };\r\n\r\n return true;\r\n };\r\n\r\n // No need.\r\n const updateAutoCompletionPositions = function() {\r\n var group = \"checkboxgroupautomation\";\r\n\r\n if (document.querySelectorAll('input[type=checkbox].' + group)\r\n === null || document.querySelectorAll('[data-fieldtype=\"autocomplete\"]') === null) {\r\n return true;\r\n }\r\n\r\n document.querySelectorAll('[data-fieldtype=\"autocomplete\"]').forEach((element) => {\r\n\r\n if (element === null) {\r\n return true;\r\n }\r\n\r\n var observer = new MutationObserver(function(mutations) {\r\n mutations.forEach((mutation) => {\r\n var target = mutation.target;\r\n var overrideElement = target.querySelector('.custom-switch');\r\n if (overrideElement === null) {\r\n return;\r\n }\r\n overrideElement.parentNode.append(overrideElement);\r\n observer.disconnect();\r\n });\r\n });\r\n observer.observe(element, {attributes: true, childList: true, subtree: true});\r\n return true;\r\n });\r\n\r\n return true;\r\n };\r\n\r\n const moveOverRidePosition = function() {\r\n\r\n var group = \"checkboxgroupautomation\";\r\n\r\n if (document.querySelectorAll('input[type=checkbox].' + group) === null) {\r\n return true;\r\n }\r\n\r\n document.querySelectorAll('input[type=checkbox].' + group).forEach((overElement) => {\r\n var id = overElement.id;\r\n id = id.replace('id_override_', '');\r\n var element = document.querySelector('div#fitem_id_' + id);\r\n if (element === null) {\r\n element = document.querySelector('div#fgroup_id_' + id);\r\n if (element === null) {\r\n return true;\r\n }\r\n }\r\n var parent = overElement.parentNode;\r\n parent.innerHTML += '';\r\n var nodeToMove = document.createElement('div');\r\n nodeToMove.classList.add('custom-control', 'custom-switch');\r\n nodeToMove.append(parent);\r\n element.querySelector(\".felement\").append(nodeToMove);\r\n return true;\r\n });\r\n // Move the override button for autocompletion fields after the autocomplete nodes are created.\r\n updateAutoCompletionPositions();\r\n\r\n return true;\r\n };\r\n\r\n /**\r\n * Create a modal to display the list of instances which is overriden the template setting.\r\n *\r\n * @returns {void}\r\n */\r\n const overrideModal = function() {\r\n\r\n // Add the template reference as prefix of the instance reference.\r\n var templateReference = document.querySelector('#pulse-template-reference');\r\n var instanceReference = document.querySelector('#fitem_id_insreference .felement');\r\n if (templateReference && instanceReference) {\r\n templateReference.classList.remove('hide');\r\n instanceReference.prepend(templateReference);\r\n }\r\n\r\n const trigger = document.querySelectorAll('[data-target=\"overridemodal\"]');\r\n\r\n if (trigger === null) {\r\n return;\r\n }\r\n\r\n trigger.forEach((elem) => {\r\n\r\n elem.nextSibling.querySelector('.felement').append(elem);\r\n\r\n elem.addEventListener('click', function(e) {\r\n e.preventDefault();\r\n var element = e.target;\r\n var data = element.dataset;\r\n var instance = document.querySelector('[name=overinstance_' + data.element + ']');\r\n if (instance !== null) {\r\n var overrides = JSON.parse(instance.value);\r\n overrides.map((value) => {\r\n var path = '/mod/pulse/automation/instances/edit.php?instanceid=';\r\n value.url = M.cfg.wwwroot + path + value.id + '&sesskey=' + M.cfg.sesskey;\r\n return value;\r\n });\r\n Modal.create({\r\n title: Str.get_string('instanceoverrides', 'pulse'),\r\n body: Template.render('mod_pulse/overrides', {instances: overrides})\r\n }).then((modal) => {\r\n modal.show();\r\n return true;\r\n }).catch(notification.exception);\r\n }\r\n });\r\n });\r\n };\r\n\r\n const enableTitleOnSubmit = function() {\r\n if (document.forms['pulse-automation-template'] === null) {\r\n return;\r\n }\r\n document.forms['pulse-automation-template'].onsubmit =\r\n () => document.querySelector('[name=\"title\"]').removeAttribute(\"disabled\");\r\n };\r\n\r\n return {\r\n\r\n init: function() {\r\n returnToFailedTab();\r\n overrideModal();\r\n moveOverRidePosition();\r\n enableTitleOnSubmit();\r\n },\r\n\r\n instanceMenuLink: function() {\r\n var primaryNav = document.querySelector('.secondary-navigation ul.more-nav');\r\n moveOutMoreMenu(primaryNav);\r\n },\r\n\r\n };\r\n});\r\n"],"names":["define","$","Modal","Template","Str","notification","moveOverRidePosition","group","document","querySelectorAll","forEach","overElement","id","replace","element","querySelector","parent","parentNode","innerHTML","nodeToMove","createElement","classList","add","append","observer","MutationObserver","mutations","mutation","overrideElement","target","disconnect","observe","attributes","childList","subtree","init","forms","onsubmit","e","invalidElement","hrefSelector","click","templateReference","instanceReference","remove","prepend","trigger","elem","nextSibling","addEventListener","preventDefault","data","dataset","instance","overrides","JSON","parse","value","map","url","M","cfg","wwwroot","sesskey","create","title","get_string","body","render","instances","then","modal","show","catch","exception","overrideModal","removeAttribute","instanceMenuLink","navMenu","menu","forceintomoremenu","removeChild","insertBefore","children","window","dispatchEvent","Event","moveOutMoreMenu"],"mappings":"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"}
\ No newline at end of file
+{"version":3,"file":"automation.min.js","sources":["../src/automation.js"],"sourcesContent":["define(\"mod_pulse/automation\", ['jquery', 'core/modal_factory', 'core/templates', 'core/str', \"core/notification\"],\n function($, Modal, Template, Str, notification) {\n\n const moveOutMoreMenu = (navMenu) => {\n\n if (navMenu === null) {\n return;\n }\n\n var menu = navMenu.querySelector('a.automation-templates');\n\n if (menu === null) {\n return;\n }\n\n menu = menu.parentNode;\n menu.dataset.forceintomoremenu = false;\n menu.querySelector('a').classList.remove('dropdown-item');\n menu.querySelector('a').classList.add('nav-link');\n menu.parentNode.removeChild(menu);\n\n // Insert the stored menus before the more menu.\n navMenu.insertBefore(menu, navMenu.children[1]);\n window.dispatchEvent(new Event('resize')); // Dispatch the resize event to create more menu.\n };\n\n const returnToFailedTab = () => {\n\n if (document.forms['pulse-automation-template'] === null) {\n return false;\n }\n\n document.forms['pulse-automation-template'].onsubmit = (e) => {\n var form = e.target;\n var invalidElement = form.querySelector('.is-invalid');\n if (invalidElement === null) {\n return true;\n }\n\n var tabid = invalidElement.parentNode.parentNode.parentNode.id;\n var hrefSelector = '[href=\"#' + tabid + '\"]';\n\n document.querySelector(hrefSelector).click();\n\n return true;\n };\n\n return true;\n };\n\n // No need.\n const updateAutoCompletionPositions = function() {\n var group = \"checkboxgroupautomation\";\n\n if (document.querySelectorAll('input[type=checkbox].' + group)\n === null || document.querySelectorAll('[data-fieldtype=\"autocomplete\"]') === null) {\n return true;\n }\n\n document.querySelectorAll('[data-fieldtype=\"autocomplete\"]').forEach((element) => {\n\n if (element === null) {\n return true;\n }\n\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach((mutation) => {\n var target = mutation.target;\n var overrideElement = target.querySelector('.custom-switch');\n if (overrideElement === null) {\n return;\n }\n overrideElement.parentNode.append(overrideElement);\n observer.disconnect();\n });\n });\n observer.observe(element, {attributes: true, childList: true, subtree: true});\n return true;\n });\n\n return true;\n };\n\n const moveOverRidePosition = function() {\n\n var group = \"checkboxgroupautomation\";\n\n if (document.querySelectorAll('input[type=checkbox].' + group) === null) {\n return true;\n }\n\n document.querySelectorAll('input[type=checkbox].' + group).forEach((overElement) => {\n var id = overElement.id;\n id = id.replace('id_override_', '');\n var element = document.querySelector('div#fitem_id_' + id);\n if (element === null) {\n element = document.querySelector('div#fgroup_id_' + id);\n if (element === null) {\n return true;\n }\n }\n var parent = overElement.parentNode;\n parent.innerHTML += '';\n var nodeToMove = document.createElement('div');\n nodeToMove.classList.add('custom-control', 'custom-switch');\n nodeToMove.append(parent);\n element.querySelector(\".felement\").append(nodeToMove);\n return true;\n });\n // Move the override button for autocompletion fields after the autocomplete nodes are created.\n updateAutoCompletionPositions();\n\n return true;\n };\n\n /**\n * Create a modal to display the list of instances which is overriden the template setting.\n *\n * @returns {void}\n */\n const overrideModal = function() {\n\n // Add the template reference as prefix of the instance reference.\n var templateReference = document.querySelector('#pulse-template-reference');\n var instanceReference = document.querySelector('#fitem_id_insreference .felement');\n if (templateReference && instanceReference) {\n templateReference.classList.remove('hide');\n instanceReference.prepend(templateReference);\n }\n\n const trigger = document.querySelectorAll('[data-target=\"overridemodal\"]');\n\n if (trigger === null) {\n return;\n }\n\n trigger.forEach((elem) => {\n\n elem.nextSibling.querySelector('.felement').append(elem);\n\n elem.addEventListener('click', function(e) {\n e.preventDefault();\n var element = e.target;\n var data = element.dataset;\n var instance = document.querySelector('[name=overinstance_' + data.element + ']');\n if (instance !== null) {\n var overrides = JSON.parse(instance.value);\n overrides.map((value) => {\n var path = '/mod/pulse/automation/instances/edit.php?instanceid=';\n value.url = M.cfg.wwwroot + path + value.id + '&sesskey=' + M.cfg.sesskey;\n return value;\n });\n Modal.create({\n title: Str.get_string('instanceoverrides', 'pulse'),\n body: Template.render('mod_pulse/overrides', {instances: overrides})\n }).then((modal) => {\n modal.show();\n return true;\n }).catch(notification.exception);\n }\n });\n });\n };\n\n const enableTitleOnSubmit = function() {\n if (document.forms['pulse-automation-template'] === null) {\n return;\n }\n document.forms['pulse-automation-template'].onsubmit =\n () => document.querySelector('[name=\"title\"]').removeAttribute(\"disabled\");\n };\n\n return {\n\n init: function() {\n returnToFailedTab();\n overrideModal();\n moveOverRidePosition();\n enableTitleOnSubmit();\n },\n\n instanceMenuLink: function() {\n var primaryNav = document.querySelector('.secondary-navigation ul.more-nav');\n moveOutMoreMenu(primaryNav);\n },\n\n };\n});\n"],"names":["define","$","Modal","Template","Str","notification","moveOverRidePosition","group","document","querySelectorAll","forEach","overElement","id","replace","element","querySelector","parent","parentNode","innerHTML","nodeToMove","createElement","classList","add","append","observer","MutationObserver","mutations","mutation","overrideElement","target","disconnect","observe","attributes","childList","subtree","init","forms","onsubmit","e","invalidElement","hrefSelector","click","templateReference","instanceReference","remove","prepend","trigger","elem","nextSibling","addEventListener","preventDefault","data","dataset","instance","overrides","JSON","parse","value","map","url","M","cfg","wwwroot","sesskey","create","title","get_string","body","render","instances","then","modal","show","catch","exception","overrideModal","removeAttribute","instanceMenuLink","navMenu","menu","forceintomoremenu","removeChild","insertBefore","children","window","dispatchEvent","Event","moveOutMoreMenu"],"mappings":"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"}
\ No newline at end of file
diff --git a/amd/build/bulkaction.min.js.map b/amd/build/bulkaction.min.js.map
index 8eb662c..2e1b8c3 100644
--- a/amd/build/bulkaction.min.js.map
+++ b/amd/build/bulkaction.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"bulkaction.min.js","sources":["../src/bulkaction.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 * Contain the bulk action for the instance management.\r\n *\r\n * @module mod_pulse/bulkaction\r\n * @copyright 2023, 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(\"mod_pulse/bulkaction\", [\"jquery\", \"core/fragment\", \"core/modal_factory\",\r\n\"core/modal_events\", \"core/notification\", \"core/str\", \"core/ajax\", \"core/templates\"],\r\n (function($, Fragment, ModalFactory, ModalEvents, notification, String, Ajax, Templates) {\r\n\r\n /**\r\n * Instance management page selectors.\r\n */\r\n const Selectors = {\r\n table: '#manage-instance-table',\r\n selectAll: '#manage-instance-tab .selectall-pulse-bulkaction',\r\n deselectAll: '#manage-instance-tab .deselectall-pulse-bulkaction',\r\n selectwithoutinsbtn: '#manage-instance-tab #selectwithoutins-btn',\r\n CheckBoxes: \"input[name='bc[]']\",\r\n DeleteBtn: '#manage-instance-tab #bulkdelete-btn',\r\n AddBtn: '#manage-instance-tab #bulkadd-btn',\r\n EnableBtn: '#manage-instance-tab #bulkenable-btn',\r\n DisableBtn: '#manage-instance-tab #bulkdisable-btn',\r\n CheckedBoxes: \"input[name='bc[]']:checked\",\r\n checkboxgroups: '#manage-instance-tab .bulkaction-group',\r\n tabUL: '#automation-tabs',\r\n tabPane: '#pulsetemplates-tab-content .tab-pane',\r\n tabContent: '#pulsetemplates-tab-content',\r\n manageInstanceTab: '#manage-instance-tab',\r\n templateForm: '.mform#pulse-automation-template',\r\n activeNav: '#automation-tabs .nav-link.active',\r\n };\r\n\r\n /**\r\n * Init the bulk select actions in the instance management tab.\r\n */\r\n function bulkaction() {\r\n const select = document.querySelector(Selectors.selectAll);\r\n const deselect = document.querySelector(Selectors.deselectAll);\r\n const tableRoot = () => document.querySelector(Selectors.table);\r\n const checkboxelm = () => tableRoot().querySelectorAll(Selectors.CheckBoxes);\r\n const selectwithoutins = document.querySelector(Selectors.selectwithoutinsbtn);\r\n const checkboxgroup = document.querySelector(Selectors.checkboxgroups);\r\n\r\n // Whent click the select all button on the instance management tab.\r\n select.addEventListener('click', () => {\r\n checkboxelm().forEach(checkbox => {\r\n checkbox.checked = true;\r\n checkboxgroup.classList.remove('hide');\r\n });\r\n });\r\n\r\n // Whent click the de-select all button on the instance management tab.\r\n deselect.addEventListener('click', () => {\r\n checkboxelm().forEach(checkbox => {\r\n checkbox.checked = false;\r\n checkboxgroup.classList.add('hide');\r\n });\r\n });\r\n\r\n // Whent click the select all without instances button on the instance management tab.\r\n selectwithoutins.addEventListener('click', () => {\r\n checkboxelm().forEach(checkbox => {\r\n if (checkbox.classList.contains(\"emptyinstance\")) {\r\n checkbox.checked = true;\r\n checkboxgroup.classList.remove('hide');\r\n }\r\n });\r\n });\r\n\r\n // Add event listener to checkboxes.\r\n document.addEventListener('change', function(e) {\r\n\r\n if (e.target.matches(Selectors.CheckBoxes)) {\r\n // Check if at least one checkbox is checked.\r\n var atLeastOneChecked = Array.from(checkboxelm()).some(function(checkbox) {\r\n return checkbox.checked;\r\n });\r\n\r\n // Toggle visibility of bulk edit action based on checkbox status.\r\n if (atLeastOneChecked) {\r\n checkboxgroup.classList.remove('hide');\r\n } else {\r\n checkboxgroup.classList.add('hide');\r\n }\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Return the selected check boxes coursed ids for the instance management.\r\n *\r\n * @returns array $courseids course Ids\r\n */\r\n function getcourseids() {\r\n var courseids = [];\r\n var checkedboxes = document.querySelectorAll(Selectors.CheckedBoxes);\r\n checkedboxes.forEach(checkedbox => {\r\n courseids.push(checkedbox.value);\r\n });\r\n return courseids;\r\n }\r\n\r\n /**\r\n * Manage the automation instances confirmation and bulk action in modal.\r\n *\r\n * @param {int} params\r\n */\r\n function manageInstances(params) {\r\n const deletebtn = document.querySelector(Selectors.DeleteBtn);\r\n const addbtn = document.querySelector(Selectors.AddBtn);\r\n const disableBtn = document.querySelector(Selectors.DisableBtn);\r\n const enableBtn = document.querySelector(Selectors.EnableBtn);\r\n\r\n // Click the delete instance bulk action button.\r\n deletebtn.addEventListener('click', function() {\r\n var courseids = getcourseids();\r\n getInstanceModal(courseids, params, 'delete');\r\n });\r\n\r\n // Click the add instance bulk action button.\r\n addbtn.addEventListener('click', function() {\r\n var courseids = getcourseids();\r\n getInstanceModal(courseids, params, 'add');\r\n });\r\n\r\n // Click the disable instance bulk action button.\r\n disableBtn.addEventListener('click', function() {\r\n var courseids = getcourseids();\r\n getInstanceModal(courseids, params, 'disable');\r\n });\r\n\r\n // Click the enable instance bulk action button.\r\n enableBtn.addEventListener('click', function() {\r\n var courseids = getcourseids();\r\n getInstanceModal(courseids, params, 'enable');\r\n });\r\n\r\n // Show/hide the instance manage tab of template.\r\n // Moved the tab outside the form, default tab handlers not works. Used custom method to show hide.\r\n document.querySelector(Selectors.tabUL).addEventListener('click', function(e) {\r\n templateInstanceFilter(e);\r\n });\r\n\r\n const templateInstanceFilter = (e) => {\r\n\r\n document.querySelectorAll(Selectors.tabPane).forEach((e) => {\r\n e.classList.remove('active');\r\n e.classList.remove('show');\r\n });\r\n // Remove the active.\r\n var href = (e === null || !e.target.matches('#automation-tabs .nav-link')) ? activeTabHref() :\r\n e.target.getAttribute('href');\r\n\r\n document.querySelector(Selectors.tabContent + ' ' + href).classList.add('active');\r\n document.querySelector(Selectors.tabContent + ' ' + href).classList.add('show');\r\n\r\n // Hide the form.\r\n if (href == Selectors.manageInstanceTab) {\r\n document.querySelector(Selectors.templateForm).style.display = 'none';\r\n } else {\r\n document.querySelector(Selectors.templateForm).style.display = 'block';\r\n }\r\n };\r\n\r\n // Find the active ul.\r\n const activeTabHref = () => {\r\n return !document.querySelector(Selectors.activeNav)\r\n || document.querySelector(Selectors.activeNav).getAttribute('href');\r\n };\r\n\r\n templateInstanceFilter(null);\r\n }\r\n\r\n /**\r\n * Get the instance management confirmation modal.\r\n *\r\n * @param {array} courseids Course Ids\r\n * @param {int} params Templated ID\r\n * @param {string} action Bulk action name\r\n */\r\n function getInstanceModal(courseids, params, action) {\r\n var args = {templateid: params, courseids: courseids, action: action};\r\n ModalFactory.create({\r\n type: ModalFactory.types.SAVE_CANCEL,\r\n title: String.get_string('confirmation', 'pulse'),\r\n body: String.get_string('confirm' + action + 'instance', 'pulse'),\r\n large: false\r\n })\r\n .then(function(modal) {\r\n\r\n modal.setButtonText('save', String.get_string('yes'));\r\n\r\n modal.getRoot().on(ModalEvents.save, e => {\r\n e.preventDefault();\r\n submitformdata(args);\r\n loadInstancetable(args);\r\n modal.getRoot().find('form').submit();\r\n modal.hide();\r\n });\r\n\r\n modal.getRoot().on(ModalEvents.hidden, function() {\r\n modal.destroy();\r\n });\r\n modal.show();\r\n return modal;\r\n }).catch(notification.exception);\r\n }\r\n\r\n /**\r\n * Submit and recieve the message form the modal confirmation on the instance management.\r\n *\r\n * @param {string} params\r\n */\r\n function submitformdata(params) {\r\n Ajax.call([{\r\n methodname: 'mod_pulse_manage_instances',\r\n args: params,\r\n done: function(response) {\r\n window.location.reload();\r\n if (response.message) {\r\n notification.addNotification({\r\n message: response.message,\r\n type: \"success\"\r\n });\r\n }\r\n }\r\n }]);\r\n }\r\n\r\n /**\r\n * Load the current manage instance table to replace the table root.\r\n *\r\n * @param {string} params\r\n */\r\n function loadInstancetable(params) {\r\n var table = document.querySelector(Selectors.table);\r\n Fragment.loadFragment('mod_pulse', 'get_manageinstance_table', 1, params).done((html, js) => {\r\n Templates.replaceNode(table, html, js);\r\n });\r\n }\r\n\r\n return {\r\n init: function(params) {\r\n bulkaction();\r\n manageInstances(params);\r\n },\r\n };\r\n\r\n }));\r\n"],"names":["define","$","Fragment","ModalFactory","ModalEvents","notification","String","Ajax","Templates","Selectors","bulkaction","select","document","querySelector","deselect","checkboxelm","querySelectorAll","selectwithoutins","checkboxgroup","addEventListener","forEach","checkbox","checked","classList","remove","add","contains","e","target","matches","Array","from","some","getcourseids","courseids","checkedbox","push","value","getInstanceModal","params","action","args","templateid","create","type","types","SAVE_CANCEL","title","get_string","body","large","then","modal","setButtonText","getRoot","on","save","preventDefault","call","methodname","done","response","window","location","reload","message","addNotification","submitformdata","table","loadFragment","html","js","replaceNode","loadInstancetable","find","submit","hide","hidden","destroy","show","catch","exception","init","deletebtn","addbtn","disableBtn","enableBtn","templateInstanceFilter","href","getAttribute","activeTabHref","style","display","manageInstances"],"mappings":"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"}
\ No newline at end of file
+{"version":3,"file":"bulkaction.min.js","sources":["../src/bulkaction.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Contain the bulk action for the instance management.\n *\n * @module mod_pulse/bulkaction\n * @copyright 2023, bdecent gmbh bdecent.de\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine(\"mod_pulse/bulkaction\", [\"jquery\", \"core/fragment\", \"core/modal_factory\",\n\"core/modal_events\", \"core/notification\", \"core/str\", \"core/ajax\", \"core/templates\"],\n (function($, Fragment, ModalFactory, ModalEvents, notification, String, Ajax, Templates) {\n\n /**\n * Instance management page selectors.\n */\n const Selectors = {\n table: '#manage-instance-table',\n selectAll: '#manage-instance-tab .selectall-pulse-bulkaction',\n deselectAll: '#manage-instance-tab .deselectall-pulse-bulkaction',\n selectwithoutinsbtn: '#manage-instance-tab #selectwithoutins-btn',\n CheckBoxes: \"input[name='bc[]']\",\n DeleteBtn: '#manage-instance-tab #bulkdelete-btn',\n AddBtn: '#manage-instance-tab #bulkadd-btn',\n EnableBtn: '#manage-instance-tab #bulkenable-btn',\n DisableBtn: '#manage-instance-tab #bulkdisable-btn',\n CheckedBoxes: \"input[name='bc[]']:checked\",\n checkboxgroups: '#manage-instance-tab .bulkaction-group',\n tabUL: '#automation-tabs',\n tabPane: '#pulsetemplates-tab-content .tab-pane',\n tabContent: '#pulsetemplates-tab-content',\n manageInstanceTab: '#manage-instance-tab',\n templateForm: '.mform#pulse-automation-template',\n activeNav: '#automation-tabs .nav-link.active',\n };\n\n /**\n * Init the bulk select actions in the instance management tab.\n */\n function bulkaction() {\n const select = document.querySelector(Selectors.selectAll);\n const deselect = document.querySelector(Selectors.deselectAll);\n const tableRoot = () => document.querySelector(Selectors.table);\n const checkboxelm = () => tableRoot().querySelectorAll(Selectors.CheckBoxes);\n const selectwithoutins = document.querySelector(Selectors.selectwithoutinsbtn);\n const checkboxgroup = document.querySelector(Selectors.checkboxgroups);\n\n // Whent click the select all button on the instance management tab.\n select.addEventListener('click', () => {\n checkboxelm().forEach(checkbox => {\n checkbox.checked = true;\n checkboxgroup.classList.remove('hide');\n });\n });\n\n // Whent click the de-select all button on the instance management tab.\n deselect.addEventListener('click', () => {\n checkboxelm().forEach(checkbox => {\n checkbox.checked = false;\n checkboxgroup.classList.add('hide');\n });\n });\n\n // Whent click the select all without instances button on the instance management tab.\n selectwithoutins.addEventListener('click', () => {\n checkboxelm().forEach(checkbox => {\n if (checkbox.classList.contains(\"emptyinstance\")) {\n checkbox.checked = true;\n checkboxgroup.classList.remove('hide');\n }\n });\n });\n\n // Add event listener to checkboxes.\n document.addEventListener('change', function(e) {\n\n if (e.target.matches(Selectors.CheckBoxes)) {\n // Check if at least one checkbox is checked.\n var atLeastOneChecked = Array.from(checkboxelm()).some(function(checkbox) {\n return checkbox.checked;\n });\n\n // Toggle visibility of bulk edit action based on checkbox status.\n if (atLeastOneChecked) {\n checkboxgroup.classList.remove('hide');\n } else {\n checkboxgroup.classList.add('hide');\n }\n }\n });\n }\n\n /**\n * Return the selected check boxes coursed ids for the instance management.\n *\n * @returns array $courseids course Ids\n */\n function getcourseids() {\n var courseids = [];\n var checkedboxes = document.querySelectorAll(Selectors.CheckedBoxes);\n checkedboxes.forEach(checkedbox => {\n courseids.push(checkedbox.value);\n });\n return courseids;\n }\n\n /**\n * Manage the automation instances confirmation and bulk action in modal.\n *\n * @param {int} params\n */\n function manageInstances(params) {\n const deletebtn = document.querySelector(Selectors.DeleteBtn);\n const addbtn = document.querySelector(Selectors.AddBtn);\n const disableBtn = document.querySelector(Selectors.DisableBtn);\n const enableBtn = document.querySelector(Selectors.EnableBtn);\n\n // Click the delete instance bulk action button.\n deletebtn.addEventListener('click', function() {\n var courseids = getcourseids();\n getInstanceModal(courseids, params, 'delete');\n });\n\n // Click the add instance bulk action button.\n addbtn.addEventListener('click', function() {\n var courseids = getcourseids();\n getInstanceModal(courseids, params, 'add');\n });\n\n // Click the disable instance bulk action button.\n disableBtn.addEventListener('click', function() {\n var courseids = getcourseids();\n getInstanceModal(courseids, params, 'disable');\n });\n\n // Click the enable instance bulk action button.\n enableBtn.addEventListener('click', function() {\n var courseids = getcourseids();\n getInstanceModal(courseids, params, 'enable');\n });\n\n // Show/hide the instance manage tab of template.\n // Moved the tab outside the form, default tab handlers not works. Used custom method to show hide.\n document.querySelector(Selectors.tabUL).addEventListener('click', function(e) {\n templateInstanceFilter(e);\n });\n\n const templateInstanceFilter = (e) => {\n\n document.querySelectorAll(Selectors.tabPane).forEach((e) => {\n e.classList.remove('active');\n e.classList.remove('show');\n });\n // Remove the active.\n var href = (e === null || !e.target.matches('#automation-tabs .nav-link')) ? activeTabHref() :\n e.target.getAttribute('href');\n\n document.querySelector(Selectors.tabContent + ' ' + href).classList.add('active');\n document.querySelector(Selectors.tabContent + ' ' + href).classList.add('show');\n\n // Hide the form.\n if (href == Selectors.manageInstanceTab) {\n document.querySelector(Selectors.templateForm).style.display = 'none';\n } else {\n document.querySelector(Selectors.templateForm).style.display = 'block';\n }\n };\n\n // Find the active ul.\n const activeTabHref = () => {\n return !document.querySelector(Selectors.activeNav)\n || document.querySelector(Selectors.activeNav).getAttribute('href');\n };\n\n templateInstanceFilter(null);\n }\n\n /**\n * Get the instance management confirmation modal.\n *\n * @param {array} courseids Course Ids\n * @param {int} params Templated ID\n * @param {string} action Bulk action name\n */\n function getInstanceModal(courseids, params, action) {\n var args = {templateid: params, courseids: courseids, action: action};\n ModalFactory.create({\n type: ModalFactory.types.SAVE_CANCEL,\n title: String.get_string('confirmation', 'pulse'),\n body: String.get_string('confirm' + action + 'instance', 'pulse'),\n large: false\n })\n .then(function(modal) {\n\n modal.setButtonText('save', String.get_string('yes'));\n\n modal.getRoot().on(ModalEvents.save, e => {\n e.preventDefault();\n submitformdata(args);\n loadInstancetable(args);\n modal.getRoot().find('form').submit();\n modal.hide();\n });\n\n modal.getRoot().on(ModalEvents.hidden, function() {\n modal.destroy();\n });\n modal.show();\n return modal;\n }).catch(notification.exception);\n }\n\n /**\n * Submit and recieve the message form the modal confirmation on the instance management.\n *\n * @param {string} params\n */\n function submitformdata(params) {\n Ajax.call([{\n methodname: 'mod_pulse_manage_instances',\n args: params,\n done: function(response) {\n window.location.reload();\n if (response.message) {\n notification.addNotification({\n message: response.message,\n type: \"success\"\n });\n }\n }\n }]);\n }\n\n /**\n * Load the current manage instance table to replace the table root.\n *\n * @param {string} params\n */\n function loadInstancetable(params) {\n var table = document.querySelector(Selectors.table);\n Fragment.loadFragment('mod_pulse', 'get_manageinstance_table', 1, params).done((html, js) => {\n Templates.replaceNode(table, html, js);\n });\n }\n\n return {\n init: function(params) {\n bulkaction();\n manageInstances(params);\n },\n };\n\n }));\n"],"names":["define","$","Fragment","ModalFactory","ModalEvents","notification","String","Ajax","Templates","Selectors","bulkaction","select","document","querySelector","deselect","checkboxelm","querySelectorAll","selectwithoutins","checkboxgroup","addEventListener","forEach","checkbox","checked","classList","remove","add","contains","e","target","matches","Array","from","some","getcourseids","courseids","checkedbox","push","value","getInstanceModal","params","action","args","templateid","create","type","types","SAVE_CANCEL","title","get_string","body","large","then","modal","setButtonText","getRoot","on","save","preventDefault","call","methodname","done","response","window","location","reload","message","addNotification","submitformdata","table","loadFragment","html","js","replaceNode","loadInstancetable","find","submit","hide","hidden","destroy","show","catch","exception","init","deletebtn","addbtn","disableBtn","enableBtn","templateInstanceFilter","href","getAttribute","activeTabHref","style","display","manageInstances"],"mappings":"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"}
\ No newline at end of file
diff --git a/amd/build/completion.min.js.map b/amd/build/completion.min.js.map
index 57f658f..8d97437 100644
--- a/amd/build/completion.min.js.map
+++ b/amd/build/completion.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"completion.min.js","sources":["../src/completion.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 * Module javascript to place the placeholders.\r\n * Modified version of IOMAD Email template emailvars.\r\n *\r\n * @module mod_pulse/completion\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/fragment'], function(Fragment) {\r\n\r\n return {\r\n\r\n /**\r\n * Update completion buttons for each activity based on user role.\r\n * This will load the template using fragment.\r\n */\r\n updatecompletionbuttons: function() {\r\n var instances = document.getElementsByClassName('modtype_pulse');\r\n var modules = []; var moduleid;\r\n for (var i = 0; i < instances.length; i++) {\r\n var instance = instances[i];\r\n var id = instance.getAttribute('id');\r\n moduleid = parseInt(id.replace('module-', ''));\r\n modules.push(moduleid);\r\n }\r\n var params = {modules: JSON.stringify(modules)};\r\n if (modules.length > 0) {\r\n let completionbuttons = Fragment.loadFragment('mod_pulse', 'completionbuttons', 1, params);\r\n var approvebtn, element, referenceNode, completioncontent;\r\n completionbuttons.then((data) => {\r\n data = JSON.parse(data);\r\n for (var k in data) {\r\n approvebtn = data[k];\r\n element = document.getElementById('module-' + k);\r\n referenceNode = element.getElementsByClassName('contentwithoutlink')[0];\r\n completioncontent = document.createElement('div');\r\n completioncontent.innerHTML = approvebtn;\r\n completioncontent.classList.add('pulse-completion-btn');\r\n referenceNode.parentNode.insertBefore(completioncontent, referenceNode.nextSibling);\r\n }\r\n return true;\r\n }).fail();\r\n }\r\n },\r\n\r\n /**\r\n * If the page is course view page then call the completion buttons to insert.\r\n */\r\n init: function() {\r\n if (document.body.classList.contains('path-course-view')) {\r\n this.updatecompletionbuttons();\r\n }\r\n },\r\n\r\n };\r\n});\r\n"],"names":["define","Fragment","updatecompletionbuttons","moduleid","instances","document","getElementsByClassName","modules","i","length","id","getAttribute","parseInt","replace","push","params","JSON","stringify","approvebtn","element","referenceNode","completioncontent","loadFragment","then","data","k","parse","getElementById","createElement","innerHTML","classList","add","parentNode","insertBefore","nextSibling","fail","init","body","contains"],"mappings":";;;;;;;;;AAyBAA,8BAAO,CAAC,kBAAkB,SAASC,gBAExB,CAMHC,wBAAyB,mBAECC,SADlBC,UAAYC,SAASC,uBAAuB,iBAC5CC,QAAU,GACLC,EAAI,EAAGA,EAAIJ,UAAUK,OAAQD,IAAK,KAEnCE,GADWN,UAAUI,GACPG,aAAa,MAC/BR,SAAWS,SAASF,GAAGG,QAAQ,UAAW,KAC1CN,QAAQO,KAAKX,cAEbY,OAAS,CAACR,QAASS,KAAKC,UAAUV,aAClCA,QAAQE,OAAS,EAAG,KAEhBS,WAAYC,QAASC,cAAeC,kBADhBpB,SAASqB,aAAa,YAAa,oBAAqB,EAAGP,QAEjEQ,MAAMC,WAEf,IAAIC,KADTD,KAAOR,KAAKU,MAAMF,MAEdN,WAAaM,KAAKC,GAClBN,QAAUd,SAASsB,eAAe,UAAYF,GAC9CL,cAAgBD,QAAQb,uBAAuB,sBAAsB,IACrEe,kBAAoBhB,SAASuB,cAAc,QACzBC,UAAYX,WAC9BG,kBAAkBS,UAAUC,IAAI,wBAChCX,cAAcY,WAAWC,aAAaZ,kBAAmBD,cAAcc,oBAEpE,KACRC,SAOXC,KAAM,WACE/B,SAASgC,KAAKP,UAAUQ,SAAS,0BAC5BpC"}
\ No newline at end of file
+{"version":3,"file":"completion.min.js","sources":["../src/completion.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/completion\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/fragment'], function(Fragment) {\n\n return {\n\n /**\n * Update completion buttons for each activity based on user role.\n * This will load the template using fragment.\n */\n updatecompletionbuttons: function() {\n var instances = document.getElementsByClassName('modtype_pulse');\n var modules = []; var moduleid;\n for (var i = 0; i < instances.length; i++) {\n var instance = instances[i];\n var id = instance.getAttribute('id');\n moduleid = parseInt(id.replace('module-', ''));\n modules.push(moduleid);\n }\n var params = {modules: JSON.stringify(modules)};\n if (modules.length > 0) {\n let completionbuttons = Fragment.loadFragment('mod_pulse', 'completionbuttons', 1, params);\n var approvebtn, element, referenceNode, completioncontent;\n completionbuttons.then((data) => {\n data = JSON.parse(data);\n for (var k in data) {\n approvebtn = data[k];\n element = document.getElementById('module-' + k);\n referenceNode = element.getElementsByClassName('contentwithoutlink')[0];\n completioncontent = document.createElement('div');\n completioncontent.innerHTML = approvebtn;\n completioncontent.classList.add('pulse-completion-btn');\n referenceNode.parentNode.insertBefore(completioncontent, referenceNode.nextSibling);\n }\n return true;\n }).fail();\n }\n },\n\n /**\n * If the page is course view page then call the completion buttons to insert.\n */\n init: function() {\n if (document.body.classList.contains('path-course-view')) {\n this.updatecompletionbuttons();\n }\n },\n\n };\n});\n"],"names":["define","Fragment","updatecompletionbuttons","moduleid","instances","document","getElementsByClassName","modules","i","length","id","getAttribute","parseInt","replace","push","params","JSON","stringify","approvebtn","element","referenceNode","completioncontent","loadFragment","then","data","k","parse","getElementById","createElement","innerHTML","classList","add","parentNode","insertBefore","nextSibling","fail","init","body","contains"],"mappings":";;;;;;;;;AAyBAA,8BAAO,CAAC,kBAAkB,SAASC,gBAExB,CAMHC,wBAAyB,mBAECC,SADlBC,UAAYC,SAASC,uBAAuB,iBAC5CC,QAAU,GACLC,EAAI,EAAGA,EAAIJ,UAAUK,OAAQD,IAAK,KAEnCE,GADWN,UAAUI,GACPG,aAAa,MAC/BR,SAAWS,SAASF,GAAGG,QAAQ,UAAW,KAC1CN,QAAQO,KAAKX,cAEbY,OAAS,CAACR,QAASS,KAAKC,UAAUV,aAClCA,QAAQE,OAAS,EAAG,KAEhBS,WAAYC,QAASC,cAAeC,kBADhBpB,SAASqB,aAAa,YAAa,oBAAqB,EAAGP,QAEjEQ,MAAMC,WAEf,IAAIC,KADTD,KAAOR,KAAKU,MAAMF,MAEdN,WAAaM,KAAKC,GAClBN,QAAUd,SAASsB,eAAe,UAAYF,GAC9CL,cAAgBD,QAAQb,uBAAuB,sBAAsB,IACrEe,kBAAoBhB,SAASuB,cAAc,QACzBC,UAAYX,WAC9BG,kBAAkBS,UAAUC,IAAI,wBAChCX,cAAcY,WAAWC,aAAaZ,kBAAmBD,cAAcc,oBAEpE,KACRC,SAOXC,KAAM,WACE/B,SAASgC,KAAKP,UAAUQ,SAAS,0BAC5BpC"}
\ No newline at end of file
diff --git a/amd/build/events.min.js.map b/amd/build/events.min.js.map
index 50926ee..8582bd6 100644
--- a/amd/build/events.min.js.map
+++ b/amd/build/events.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"events.min.js","sources":["../src/events.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 * Contain the events the data privacy tool can fire.\r\n *\r\n * @module mod_pulse/events\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([], function() {\r\n return {\r\n save: 'mod_pulse-preset:save',\r\n customize: 'mod_pulse-preset:customize',\r\n };\r\n});\r\n"],"names":["define","save","customize"],"mappings":";;;;;;;;AAwBAA,0BAAO,IAAI,iBACA,CACHC,KAAM,wBACNC,UAAW"}
\ No newline at end of file
+{"version":3,"file":"events.min.js","sources":["../src/events.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Contain the events the data privacy tool can fire.\n *\n * @module mod_pulse/events\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([], function() {\n return {\n save: 'mod_pulse-preset:save',\n customize: 'mod_pulse-preset:customize',\n };\n});\n"],"names":["define","save","customize"],"mappings":";;;;;;;;AAwBAA,0BAAO,IAAI,iBACA,CACHC,KAAM,wBACNC,UAAW"}
\ No newline at end of file
diff --git a/amd/build/modal_preset.min.js.map b/amd/build/modal_preset.min.js.map
index 4422f36..4003855 100644
--- a/amd/build/modal_preset.min.js.map
+++ b/amd/build/modal_preset.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"modal_preset.min.js","sources":["../src/modal_preset.js"],"sourcesContent":["define(['jquery', 'core/notification', 'core/custom_interaction_events', 'core/modal', 'core/modal_registry', 'mod_pulse/events'],\r\n function($, Notification, CustomEvents, Modal, ModalRegistry, PresetEvents) {\r\n\r\n var registered = false;\r\n var SELECTORS = {\r\n SAVE_BUTTON: '[data-action=\"save\"]',\r\n CUSTOMIZE_BUTTON: '[data-action=\"customize\"]',\r\n CANCEL_BUTTON: '[data-action=\"cancel\"]',\r\n };\r\n\r\n /**\r\n * Constructor for the Modal.\r\n *\r\n * @param {object} root The root jQuery element for the modal\r\n */\r\n var ModalPreset = function(root) {\r\n Modal.call(this, root);\r\n\r\n if (!this.getFooter().find(SELECTORS.SAVE_BUTTON).length) {\r\n Notification.exception({message: 'No \"Apply and save\" button found'});\r\n }\r\n\r\n if (!this.getFooter().find(SELECTORS.CUSTOMIZE_BUTTON).length) {\r\n Notification.exception({message: 'No \"Apply and customize\" button found'});\r\n }\r\n\r\n if (!this.getFooter().find(SELECTORS.CANCEL_BUTTON).length) {\r\n Notification.exception({message: 'No cancel button found'});\r\n }\r\n };\r\n\r\n ModalPreset.TYPE = 'PresetModal';\r\n ModalPreset.prototype = Object.create(Modal.prototype);\r\n ModalPreset.prototype.constructor = ModalPreset;\r\n ModalPreset.prototype.formData = '';\r\n\r\n /**\r\n * Set up all of the event handling for the modal.\r\n *\r\n * @method registerEventListeners\r\n */\r\n ModalPreset.prototype.registerEventListeners = function() {\r\n // Apply parent event listeners.\r\n Modal.prototype.registerEventListeners.call(this);\r\n\r\n this.getModal().on(CustomEvents.events.activate, SELECTORS.SAVE_BUTTON, function(event, data) {\r\n // Load the backupfile.\r\n document.querySelectorAll('.preset-config-params form.mform').forEach(form => {\r\n form.importmethod.value = 'save';\r\n form.addEventListener('submit', function(e) {\r\n e.preventDefault();\r\n });\r\n });\r\n\r\n if (document.querySelectorAll('.preset-config-params [data-fieldtype=\"submit\"] input').length != 0) {\r\n document.querySelectorAll('.preset-config-params [data-fieldtype=\"submit\"] input')[0].click();\r\n }\r\n\r\n var approveEvent = $.Event(PresetEvents.save);\r\n this.getRoot().trigger(approveEvent, this);\r\n\r\n if (!approveEvent.isDefaultPrevented()) {\r\n this.destroy();\r\n data.originalEvent.preventDefault();\r\n }\r\n event.preventDefault();\r\n }.bind(this));\r\n\r\n\r\n this.getModal().on(CustomEvents.events.activate, SELECTORS.CUSTOMIZE_BUTTON, function(event, data) {\r\n // Add your logic for when the login button is clicked. This could include the form validation,\r\n document.querySelectorAll('.preset-config-params form.mform').forEach(form => {\r\n form.importmethod.value = 'customize';\r\n });\r\n\r\n var customizeEvent = $.Event(PresetEvents.customize);\r\n this.getRoot().trigger(customizeEvent, this);\r\n\r\n if (!customizeEvent.isDefaultPrevented()) {\r\n data.originalEvent.preventDefault();\r\n }\r\n event.preventDefault();\r\n\r\n }.bind(this));\r\n\r\n this.getModal().on(CustomEvents.events.activate, SELECTORS.CANCEL_BUTTON, function() {\r\n this.destroy();\r\n }.bind(this));\r\n };\r\n\r\n // Automatically register with the modal registry the first time this module is imported so that you can create modals\r\n // of this type using the modal factory.\r\n if (!registered) {\r\n ModalRegistry.register(ModalPreset.TYPE, ModalPreset, 'mod_pulse/modal_preset');\r\n registered = true;\r\n }\r\n\r\n return ModalPreset;\r\n });\r\n"],"names":["define","$","Notification","CustomEvents","Modal","ModalRegistry","PresetEvents","registered","SELECTORS","ModalPreset","root","call","this","getFooter","find","length","exception","message","TYPE","prototype","Object","create","constructor","formData","registerEventListeners","getModal","on","events","activate","event","data","document","querySelectorAll","forEach","form","importmethod","value","addEventListener","e","preventDefault","click","approveEvent","Event","save","getRoot","trigger","isDefaultPrevented","destroy","originalEvent","bind","customizeEvent","customize","register"],"mappings":"AAAAA,gCAAO,CAAC,SAAU,oBAAqB,iCAAkC,aAAc,sBAAuB,qBAC1G,SAASC,EAAGC,aAAcC,aAAcC,MAAOC,cAAeC,kBAEtDC,YAAa,EACbC,sBACa,uBADbA,2BAEkB,4BAFlBA,wBAGe,yBAQfC,YAAc,SAASC,MACvBN,MAAMO,KAAKC,KAAMF,MAEZE,KAAKC,YAAYC,KAAKN,uBAAuBO,QAC9Cb,aAAac,UAAU,CAACC,QAAS,qCAGhCL,KAAKC,YAAYC,KAAKN,4BAA4BO,QACnDb,aAAac,UAAU,CAACC,QAAS,0CAGhCL,KAAKC,YAAYC,KAAKN,yBAAyBO,QAChDb,aAAac,UAAU,CAACC,QAAS,mCAIzCR,YAAYS,KAAO,eACnBT,YAAYU,UAAYC,OAAOC,OAAOjB,MAAMe,YACtBG,YAAcb,YACpCA,YAAYU,UAAUI,SAAW,GAOjCd,YAAYU,UAAUK,uBAAyB,WAE3CpB,MAAMe,UAAUK,uBAAuBb,KAAKC,WAEvCa,WAAWC,GAAGvB,aAAawB,OAAOC,SAAUpB,sBAAuB,SAASqB,MAAOC,MAEpFC,SAASC,iBAAiB,oCAAoCC,SAAQC,OAClEA,KAAKC,aAAaC,MAAQ,OAC1BF,KAAKG,iBAAiB,UAAU,SAASC,GACrCA,EAAEC,uBAIuF,GAA7FR,SAASC,iBAAiB,yDAAyDjB,QACnFgB,SAASC,iBAAiB,yDAAyD,GAAGQ,YAGtFC,aAAexC,EAAEyC,MAAMpC,aAAaqC,WACnCC,UAAUC,QAAQJ,aAAc7B,MAEhC6B,aAAaK,4BACTC,UACLjB,KAAKkB,cAAcT,kBAEvBV,MAAMU,kBACRU,KAAKrC,YAGFa,WAAWC,GAAGvB,aAAawB,OAAOC,SAAUpB,2BAA4B,SAASqB,MAAOC,MAEzFC,SAASC,iBAAiB,oCAAoCC,SAAQC,OAClEA,KAAKC,aAAaC,MAAQ,mBAG1Bc,eAAiBjD,EAAEyC,MAAMpC,aAAa6C,gBACrCP,UAAUC,QAAQK,eAAgBtC,MAElCsC,eAAeJ,sBAChBhB,KAAKkB,cAAcT,iBAEvBV,MAAMU,kBAERU,KAAKrC,YAEFa,WAAWC,GAAGvB,aAAawB,OAAOC,SAAUpB,wBAAyB,gBACjEuC,WACPE,KAAKrC,QAKNL,aACDF,cAAc+C,SAAS3C,YAAYS,KAAMT,YAAa,0BACtDF,YAAa,GAGVE"}
\ No newline at end of file
+{"version":3,"file":"modal_preset.min.js","sources":["../src/modal_preset.js"],"sourcesContent":["define(['jquery', 'core/notification', 'core/custom_interaction_events', 'core/modal', 'core/modal_registry', 'mod_pulse/events'],\n function($, Notification, CustomEvents, Modal, ModalRegistry, PresetEvents) {\n\n var registered = false;\n var SELECTORS = {\n SAVE_BUTTON: '[data-action=\"save\"]',\n CUSTOMIZE_BUTTON: '[data-action=\"customize\"]',\n CANCEL_BUTTON: '[data-action=\"cancel\"]',\n };\n\n /**\n * Constructor for the Modal.\n *\n * @param {object} root The root jQuery element for the modal\n */\n var ModalPreset = function(root) {\n Modal.call(this, root);\n\n if (!this.getFooter().find(SELECTORS.SAVE_BUTTON).length) {\n Notification.exception({message: 'No \"Apply and save\" button found'});\n }\n\n if (!this.getFooter().find(SELECTORS.CUSTOMIZE_BUTTON).length) {\n Notification.exception({message: 'No \"Apply and customize\" button found'});\n }\n\n if (!this.getFooter().find(SELECTORS.CANCEL_BUTTON).length) {\n Notification.exception({message: 'No cancel button found'});\n }\n };\n\n ModalPreset.TYPE = 'PresetModal';\n ModalPreset.prototype = Object.create(Modal.prototype);\n ModalPreset.prototype.constructor = ModalPreset;\n ModalPreset.prototype.formData = '';\n\n /**\n * Set up all of the event handling for the modal.\n *\n * @method registerEventListeners\n */\n ModalPreset.prototype.registerEventListeners = function() {\n // Apply parent event listeners.\n Modal.prototype.registerEventListeners.call(this);\n\n this.getModal().on(CustomEvents.events.activate, SELECTORS.SAVE_BUTTON, function(event, data) {\n // Load the backupfile.\n document.querySelectorAll('.preset-config-params form.mform').forEach(form => {\n form.importmethod.value = 'save';\n form.addEventListener('submit', function(e) {\n e.preventDefault();\n });\n });\n\n if (document.querySelectorAll('.preset-config-params [data-fieldtype=\"submit\"] input').length != 0) {\n document.querySelectorAll('.preset-config-params [data-fieldtype=\"submit\"] input')[0].click();\n }\n\n var approveEvent = $.Event(PresetEvents.save);\n this.getRoot().trigger(approveEvent, this);\n\n if (!approveEvent.isDefaultPrevented()) {\n this.destroy();\n data.originalEvent.preventDefault();\n }\n event.preventDefault();\n }.bind(this));\n\n\n this.getModal().on(CustomEvents.events.activate, SELECTORS.CUSTOMIZE_BUTTON, function(event, data) {\n // Add your logic for when the login button is clicked. This could include the form validation,\n document.querySelectorAll('.preset-config-params form.mform').forEach(form => {\n form.importmethod.value = 'customize';\n });\n\n var customizeEvent = $.Event(PresetEvents.customize);\n this.getRoot().trigger(customizeEvent, this);\n\n if (!customizeEvent.isDefaultPrevented()) {\n data.originalEvent.preventDefault();\n }\n event.preventDefault();\n\n }.bind(this));\n\n this.getModal().on(CustomEvents.events.activate, SELECTORS.CANCEL_BUTTON, function() {\n this.destroy();\n }.bind(this));\n };\n\n // Automatically register with the modal registry the first time this module is imported so that you can create modals\n // of this type using the modal factory.\n if (!registered) {\n ModalRegistry.register(ModalPreset.TYPE, ModalPreset, 'mod_pulse/modal_preset');\n registered = true;\n }\n\n return ModalPreset;\n });\n"],"names":["define","$","Notification","CustomEvents","Modal","ModalRegistry","PresetEvents","registered","SELECTORS","ModalPreset","root","call","this","getFooter","find","length","exception","message","TYPE","prototype","Object","create","constructor","formData","registerEventListeners","getModal","on","events","activate","event","data","document","querySelectorAll","forEach","form","importmethod","value","addEventListener","e","preventDefault","click","approveEvent","Event","save","getRoot","trigger","isDefaultPrevented","destroy","originalEvent","bind","customizeEvent","customize","register"],"mappings":"AAAAA,gCAAO,CAAC,SAAU,oBAAqB,iCAAkC,aAAc,sBAAuB,qBAC1G,SAASC,EAAGC,aAAcC,aAAcC,MAAOC,cAAeC,kBAEtDC,YAAa,EACbC,sBACa,uBADbA,2BAEkB,4BAFlBA,wBAGe,yBAQfC,YAAc,SAASC,MACvBN,MAAMO,KAAKC,KAAMF,MAEZE,KAAKC,YAAYC,KAAKN,uBAAuBO,QAC9Cb,aAAac,UAAU,CAACC,QAAS,qCAGhCL,KAAKC,YAAYC,KAAKN,4BAA4BO,QACnDb,aAAac,UAAU,CAACC,QAAS,0CAGhCL,KAAKC,YAAYC,KAAKN,yBAAyBO,QAChDb,aAAac,UAAU,CAACC,QAAS,mCAIzCR,YAAYS,KAAO,eACnBT,YAAYU,UAAYC,OAAOC,OAAOjB,MAAMe,YACtBG,YAAcb,YACpCA,YAAYU,UAAUI,SAAW,GAOjCd,YAAYU,UAAUK,uBAAyB,WAE3CpB,MAAMe,UAAUK,uBAAuBb,KAAKC,WAEvCa,WAAWC,GAAGvB,aAAawB,OAAOC,SAAUpB,sBAAuB,SAASqB,MAAOC,MAEpFC,SAASC,iBAAiB,oCAAoCC,SAAQC,OAClEA,KAAKC,aAAaC,MAAQ,OAC1BF,KAAKG,iBAAiB,UAAU,SAASC,GACrCA,EAAEC,uBAIuF,GAA7FR,SAASC,iBAAiB,yDAAyDjB,QACnFgB,SAASC,iBAAiB,yDAAyD,GAAGQ,YAGtFC,aAAexC,EAAEyC,MAAMpC,aAAaqC,WACnCC,UAAUC,QAAQJ,aAAc7B,MAEhC6B,aAAaK,4BACTC,UACLjB,KAAKkB,cAAcT,kBAEvBV,MAAMU,kBACRU,KAAKrC,YAGFa,WAAWC,GAAGvB,aAAawB,OAAOC,SAAUpB,2BAA4B,SAASqB,MAAOC,MAEzFC,SAASC,iBAAiB,oCAAoCC,SAAQC,OAClEA,KAAKC,aAAaC,MAAQ,mBAG1Bc,eAAiBjD,EAAEyC,MAAMpC,aAAa6C,gBACrCP,UAAUC,QAAQK,eAAgBtC,MAElCsC,eAAeJ,sBAChBhB,KAAKkB,cAAcT,iBAEvBV,MAAMU,kBAERU,KAAKrC,YAEFa,WAAWC,GAAGvB,aAAawB,OAAOC,SAAUpB,wBAAyB,gBACjEuC,WACPE,KAAKrC,QAKNL,aACDF,cAAc+C,SAAS3C,YAAYS,KAAMT,YAAa,0BACtDF,YAAa,GAGVE"}
\ No newline at end of file
diff --git a/amd/build/vars.min.js.map b/amd/build/vars.min.js.map
index 3362e07..f0c6f89 100644
--- a/amd/build/vars.min.js.map
+++ b/amd/build/vars.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"vars.min.js","sources":["../src/vars.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 * vars javascript to place the placeholders.\r\n * Modified version of IOMAD Email template emailvars.\r\n *\r\n * @module mod_pulse/vars\r\n * @copyright 2023, 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(\"mod_pulse/vars\", [\"jquery\", 'core/str'], (function($, Str) {\r\n\r\n /**\r\n * Toggle the placeholder container hide/show.\r\n */\r\n const initPlaceholderToggle = function() {\r\n\r\n var selector = \".mod-pulse-emailvars-toggle\";\r\n\r\n var emailvars = document.querySelectorAll(selector);\r\n\r\n if (emailvars === undefined || emailvars === null) {\r\n return;\r\n }\r\n\r\n emailvars.forEach((editor) => {\r\n editor.querySelector('.email-vars-button').addEventListener('click', (e) => {\r\n e.preventDefault();\r\n\r\n var target = e.target.closest('a');\r\n var btnurl = target.getAttribute('href'); // Get the clicked placeholder element vars content selector.\r\n var toggleIcon = target.querySelector('i');\r\n var varsContent = document.querySelector(btnurl); // Email vars content body.\r\n\r\n varsContent.classList.toggle('show');\r\n\r\n // Change the toggle icon direction.\r\n toggleIcon.classList.toggle('fa-angle-double-up');\r\n toggleIcon.classList.toggle('fa-angle-double-down');\r\n });\r\n });\r\n };\r\n\r\n /**\r\n * Email vars placeholders show more / show less.\r\n */\r\n const initVarsExpand = function() {\r\n var selector = '.mod-pulse-emailvars-toggle .pulse-email-placeholders li .button-show-more';\r\n\r\n var placeholders = document.querySelectorAll(selector);\r\n\r\n if (placeholders === undefined || placeholders === null) {\r\n return;\r\n }\r\n\r\n placeholders.forEach((showmorebtn) => {\r\n showmorebtn.addEventListener('click', (e) => {\r\n e.preventDefault();\r\n var target = e.target.closest('a');\r\n var placeholderurl = target.getAttribute('href'); // Get the clicked show more element placeholder content selector.\r\n var placeholderContent = document.querySelector(placeholderurl); // Placeholder content body.\r\n placeholderContent.classList.toggle('less');\r\n\r\n if (target.innerHTML == 'Show more') {\r\n var showless = Str.get_string('showless', 'mod_pulse');\r\n showless.done(function(localizedShowlessString) {\r\n target.innerHTML = localizedShowlessString;\r\n });\r\n } else {\r\n var showmore = Str.get_string('showmore', 'mod_pulse');\r\n showmore.done(function(localizedShowmoreString) {\r\n target.innerHTML = localizedShowmoreString;\r\n });\r\n }\r\n });\r\n });\r\n };\r\n\r\n return {\r\n\r\n init: function() {\r\n initPlaceholderToggle();\r\n initVarsExpand();\r\n },\r\n };\r\n\r\n}));\r\n"],"names":["define","$","Str","init","emailvars","placeholders","document","querySelectorAll","forEach","editor","querySelector","addEventListener","e","preventDefault","target","closest","btnurl","getAttribute","toggleIcon","classList","toggle","showmorebtn","placeholderurl","innerHTML","get_string","done","localizedShowlessString","localizedShowmoreString"],"mappings":";;;;;;;;AAwBAA,wBAAyB,CAAC,SAAU,aAAc,SAASC,EAAGC,WAoEnD,CAEHC,KAAM,WAjEoB,IAItBC,UA8BAC,aA5BAD,OAFAA,UAAYE,SAASC,iBAFV,iCAQfH,UAAUI,SAASC,SACfA,OAAOC,cAAc,sBAAsBC,iBAAiB,SAAUC,IAClEA,EAAEC,qBAEEC,OAASF,EAAEE,OAAOC,QAAQ,KAC1BC,OAASF,OAAOG,aAAa,QAC7BC,WAAaJ,OAAOJ,cAAc,KACpBJ,SAASI,cAAcM,QAE7BG,UAAUC,OAAO,QAG7BF,WAAWC,UAAUC,OAAO,sBAC5BF,WAAWC,UAAUC,OAAO,8BAahCf,OAFAA,aAAeC,SAASC,iBAFb,gFAQfF,aAAaG,SAASa,cAClBA,YAAYV,iBAAiB,SAAUC,IACnCA,EAAEC,qBACEC,OAASF,EAAEE,OAAOC,QAAQ,KAC1BO,eAAiBR,OAAOG,aAAa,QAChBX,SAASI,cAAcY,gBAC7BH,UAAUC,OAAO,QAEZ,aAApBN,OAAOS,UACQrB,IAAIsB,WAAW,WAAY,aACjCC,MAAK,SAASC,yBACnBZ,OAAOS,UAAYG,2BAGRxB,IAAIsB,WAAW,WAAY,aACjCC,MAAK,SAASE,yBACnBb,OAAOS,UAAYI"}
\ No newline at end of file
+{"version":3,"file":"vars.min.js","sources":["../src/vars.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 * vars javascript to place the placeholders.\n * Modified version of IOMAD Email template emailvars.\n *\n * @module mod_pulse/vars\n * @copyright 2023, bdecent gmbh bdecent.de\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine(\"mod_pulse/vars\", [\"jquery\", 'core/str'], (function($, Str) {\n\n /**\n * Toggle the placeholder container hide/show.\n */\n const initPlaceholderToggle = function() {\n\n var selector = \".mod-pulse-emailvars-toggle\";\n\n var emailvars = document.querySelectorAll(selector);\n\n if (emailvars === undefined || emailvars === null) {\n return;\n }\n\n emailvars.forEach((editor) => {\n editor.querySelector('.email-vars-button').addEventListener('click', (e) => {\n e.preventDefault();\n\n var target = e.target.closest('a');\n var btnurl = target.getAttribute('href'); // Get the clicked placeholder element vars content selector.\n var toggleIcon = target.querySelector('i');\n var varsContent = document.querySelector(btnurl); // Email vars content body.\n\n varsContent.classList.toggle('show');\n\n // Change the toggle icon direction.\n toggleIcon.classList.toggle('fa-angle-double-up');\n toggleIcon.classList.toggle('fa-angle-double-down');\n });\n });\n };\n\n /**\n * Email vars placeholders show more / show less.\n */\n const initVarsExpand = function() {\n var selector = '.mod-pulse-emailvars-toggle .pulse-email-placeholders li .button-show-more';\n\n var placeholders = document.querySelectorAll(selector);\n\n if (placeholders === undefined || placeholders === null) {\n return;\n }\n\n placeholders.forEach((showmorebtn) => {\n showmorebtn.addEventListener('click', (e) => {\n e.preventDefault();\n var target = e.target.closest('a');\n var placeholderurl = target.getAttribute('href'); // Get the clicked show more element placeholder content selector.\n var placeholderContent = document.querySelector(placeholderurl); // Placeholder content body.\n placeholderContent.classList.toggle('less');\n\n if (target.innerHTML == 'Show more') {\n var showless = Str.get_string('showless', 'mod_pulse');\n showless.done(function(localizedShowlessString) {\n target.innerHTML = localizedShowlessString;\n });\n } else {\n var showmore = Str.get_string('showmore', 'mod_pulse');\n showmore.done(function(localizedShowmoreString) {\n target.innerHTML = localizedShowmoreString;\n });\n }\n });\n });\n };\n\n return {\n\n init: function() {\n initPlaceholderToggle();\n initVarsExpand();\n },\n };\n\n}));\n"],"names":["define","$","Str","init","emailvars","placeholders","document","querySelectorAll","forEach","editor","querySelector","addEventListener","e","preventDefault","target","closest","btnurl","getAttribute","toggleIcon","classList","toggle","showmorebtn","placeholderurl","innerHTML","get_string","done","localizedShowlessString","localizedShowmoreString"],"mappings":";;;;;;;;AAwBAA,wBAAyB,CAAC,SAAU,aAAc,SAASC,EAAGC,WAoEnD,CAEHC,KAAM,WAjEoB,IAItBC,UA8BAC,aA5BAD,OAFAA,UAAYE,SAASC,iBAFV,iCAQfH,UAAUI,SAASC,SACfA,OAAOC,cAAc,sBAAsBC,iBAAiB,SAAUC,IAClEA,EAAEC,qBAEEC,OAASF,EAAEE,OAAOC,QAAQ,KAC1BC,OAASF,OAAOG,aAAa,QAC7BC,WAAaJ,OAAOJ,cAAc,KACpBJ,SAASI,cAAcM,QAE7BG,UAAUC,OAAO,QAG7BF,WAAWC,UAAUC,OAAO,sBAC5BF,WAAWC,UAAUC,OAAO,8BAahCf,OAFAA,aAAeC,SAASC,iBAFb,gFAQfF,aAAaG,SAASa,cAClBA,YAAYV,iBAAiB,SAAUC,IACnCA,EAAEC,qBACEC,OAASF,EAAEE,OAAOC,QAAQ,KAC1BO,eAAiBR,OAAOG,aAAa,QAChBX,SAASI,cAAcY,gBAC7BH,UAAUC,OAAO,QAEZ,aAApBN,OAAOS,UACQrB,IAAIsB,WAAW,WAAY,aACjCC,MAAK,SAASC,yBACnBZ,OAAOS,UAAYG,2BAGRxB,IAAIsB,WAAW,WAAY,aACjCC,MAAK,SAASE,yBACnBb,OAAOS,UAAYI"}
\ No newline at end of file
diff --git a/tests/behat/behat_pulse.php b/tests/behat/behat_pulse.php
index 5e571e3..aed1d0a 100644
--- a/tests/behat/behat_pulse.php
+++ b/tests/behat/behat_pulse.php
@@ -229,15 +229,19 @@ public function switch_to_open_window() {
* Switches to a pulse new window.
*
* @Given /^I click on pulse "([^"]*)" editor$/
+ *
+ * @param string $editor
* @throws DriverException If there aren't exactly 2 windows open.
*/
public function i_click_on_pulse_editor($editor) {
global $CFG;
if ($CFG->branch == "403") {
- $this->execute('behat_general::i_click_on_in_the', ['#'.$editor . '_ifr', 'css_element', '#fitem_'.$editor, 'css_element']);
+ $this->execute('behat_general::i_click_on_in_the',
+ ['#'.$editor . '_ifr', 'css_element', '#fitem_'.$editor, 'css_element']);
} else {
- $this->execute('behat_general::i_click_on_in_the', ['#'.$editor . 'editable', 'css_element', '#fitem_'.$editor, 'css_element']);
+ $this->execute('behat_general::i_click_on_in_the',
+ ['#'.$editor . 'editable', 'css_element', '#fitem_'.$editor, 'css_element']);
}
}
}