From a896ea64730b0f1ed8a770336ee83f9dbf7c483c Mon Sep 17 00:00:00 2001 From: Paul Holden Date: Mon, 28 Mar 2022 18:49:12 +0100 Subject: [PATCH] MDL-74342 reportbuilder: allow audiences to be immediately renamed. Return rendered editable component in response to form submission so that the audience card can be updated straight away. --- reportbuilder/amd/build/audience.min.js | 2 +- reportbuilder/amd/build/audience.min.js.map | 2 +- reportbuilder/amd/build/local/selectors.min.js | 2 +- reportbuilder/amd/build/local/selectors.min.js.map | 2 +- reportbuilder/amd/src/audience.js | 4 ++++ reportbuilder/amd/src/local/selectors.js | 1 + reportbuilder/classes/form/audience.php | 14 ++++++++++++-- .../templates/local/audience/form.mustache | 2 +- reportbuilder/tests/behat/audience.feature | 9 +++++++++ 9 files changed, 31 insertions(+), 7 deletions(-) diff --git a/reportbuilder/amd/build/audience.min.js b/reportbuilder/amd/build/audience.min.js index bfe7fe3bb99..43393195f35 100644 --- a/reportbuilder/amd/build/audience.min.js +++ b/reportbuilder/amd/build/audience.min.js @@ -1,3 +1,3 @@ -define("core_reportbuilder/audience",["exports","core/templates","core/notification","core/pending","core/prefetch","core/str","core_form/dynamicform","core/toast","core_reportbuilder/local/repository/audiences","core_reportbuilder/local/selectors","core/fragment","core_form/changechecker"],(function(_exports,_templates,_notification,_pending,_prefetch,_str,_dynamicform,_toast,_audiences,reportSelectors,_fragment,_changechecker){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_templates=_interopRequireDefault(_templates),_notification=_interopRequireDefault(_notification),_pending=_interopRequireDefault(_pending),_dynamicform=_interopRequireDefault(_dynamicform),reportSelectors=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(reportSelectors);let reportId=0,contextId=0;const initAudienceCardForm=audienceCard=>{const audienceFormContainer=audienceCard.querySelector(reportSelectors.regions.audienceFormContainer),audienceForm=new _dynamicform.default(audienceFormContainer,"\\core_reportbuilder\\form\\audience");return audienceForm.addEventListener(audienceForm.events.FORM_SUBMITTED,(data=>{const audienceDescription=audienceCard.querySelector(reportSelectors.regions.audienceDescription);return audienceCard.dataset.instanceid=data.detail.instanceid,audienceDescription.innerHTML=data.detail.description,closeAudienceCardForm(audienceCard),(0,_str.get_string)("audiencesaved","core_reportbuilder").then(_toast.add)})),audienceForm.addEventListener(audienceForm.events.FORM_CANCELLED,(()=>{audienceCard.dataset.instanceid>0?closeAudienceCardForm(audienceCard):removeAudienceCard(audienceCard)})),audienceForm},closeAudienceCardForm=audienceCard=>{const audienceFormContainer=audienceCard.querySelector(reportSelectors.regions.audienceFormContainer),NewAudienceFormContainer=audienceFormContainer.cloneNode(!1);audienceCard.querySelector(reportSelectors.regions.audienceForm).replaceChild(NewAudienceFormContainer,audienceFormContainer),audienceCard.querySelector(reportSelectors.regions.audienceDescription).classList.remove("hidden"),audienceCard.querySelector(reportSelectors.actions.audienceEdit).disabled=!1,audienceCard.querySelector(reportSelectors.actions.audienceDelete).disabled=!1},removeAudienceCard=audienceCard=>{audienceCard.remove();const audienceCards=document.querySelector(reportSelectors.regions.audiencesContainer).querySelectorAll(reportSelectors.regions.audienceCard);if(0===audienceCards.length){document.querySelector(reportSelectors.regions.audienceEmptyMessage).classList.remove("hidden")}else{const audienceFirstCardSeparator=audienceCards[0].querySelector(".audience-separator");null==audienceFirstCardSeparator||audienceFirstCardSeparator.remove()}};let initialized=!1;_exports.init=(id,contextid)=>{(0,_prefetch.prefetchStrings)("core_reportbuilder",["audienceadded","audiencedeleted","audiencesaved","deleteaudience","deleteaudienceconfirm"]),(0,_prefetch.prefetchStrings)("core",["delete"]),reportId=id,contextId=contextid,initialized||(document.addEventListener("click",(event=>{const audienceAdd=event.target.closest(reportSelectors.actions.audienceAdd);audienceAdd&&(event.preventDefault(),((className,title)=>{const pendingPromise=new _pending.default("core_reportbuilder/audience:add"),audiencesContainer=document.querySelector(reportSelectors.regions.audiencesContainer),audienceCardLength=audiencesContainer.querySelectorAll(reportSelectors.regions.audienceCard).length,params={classname:className,reportid:reportId,showormessage:audienceCardLength>0,title:title};(0,_fragment.loadFragment)("core_reportbuilder","audience_form",contextId,params).then(((html,js)=>{const audienceCard=_templates.default.appendNodeContents(audiencesContainer,html,js)[0],audienceEmptyMessage=audiencesContainer.querySelector(reportSelectors.regions.audienceEmptyMessage),audienceForm=initAudienceCardForm(audienceCard);return(0,_changechecker.markFormAsDirty)(audienceForm.getFormNode()),audienceEmptyMessage.classList.add("hidden"),(0,_str.get_string)("audienceadded","core_reportbuilder",title)})).then(_toast.add).then((()=>pendingPromise.resolve())).catch(_notification.default.exception)})(audienceAdd.dataset.uniqueIdentifier,audienceAdd.dataset.name));const audienceEdit=event.target.closest(reportSelectors.actions.audienceEdit);if(audienceEdit){const audienceEditCard=audienceEdit.closest(reportSelectors.regions.audienceCard);event.preventDefault(),(audienceCard=>{const pendingPromise=new _pending.default("core_reportbuilder/audience:edit"),audienceForm=initAudienceCardForm(audienceCard),audienceFormData={reportid:reportId,id:audienceCard.dataset.instanceid,classname:audienceCard.dataset.classname};audienceForm.load(audienceFormData).then((()=>{const audienceFormContainer=audienceCard.querySelector(reportSelectors.regions.audienceFormContainer),audienceDescription=audienceCard.querySelector(reportSelectors.regions.audienceDescription),audienceEdit=audienceCard.querySelector(reportSelectors.actions.audienceEdit);return audienceFormContainer.classList.remove("hidden"),audienceDescription.classList.add("hidden"),audienceEdit.disabled=!0,pendingPromise.resolve()})).catch(_notification.default.exception)})(audienceEditCard)}const audienceDelete=event.target.closest(reportSelectors.actions.audienceDelete);audienceDelete&&(event.preventDefault(),(audienceDelete=>{const audienceCard=audienceDelete.closest(reportSelectors.regions.audienceCard),audienceTitle=audienceCard.dataset.title;_notification.default.saveCancelPromise((0,_str.get_string)("deleteaudience","core_reportbuilder",audienceTitle),(0,_str.get_string)("deleteaudienceconfirm","core_reportbuilder",audienceTitle),(0,_str.get_string)("delete","core"),{triggerElement:audienceDelete}).then((()=>{const pendingPromise=new _pending.default("core_reportbuilder/audience:delete");return(0,_audiences.deleteAudience)(reportId,audienceCard.dataset.instanceid).then((()=>(0,_toast.add)((0,_str.get_string)("audiencedeleted","core_reportbuilder",audienceTitle)))).then((()=>(removeAudienceCard(audienceCard),pendingPromise.resolve()))).catch(_notification.default.exception)})).catch((()=>{}))})(audienceDelete))})),initialized=!0)}})); +define("core_reportbuilder/audience",["exports","core/inplace_editable","core/templates","core/notification","core/pending","core/prefetch","core/str","core_form/dynamicform","core/toast","core_reportbuilder/local/repository/audiences","core_reportbuilder/local/selectors","core/fragment","core_form/changechecker"],(function(_exports,_inplace_editable,_templates,_notification,_pending,_prefetch,_str,_dynamicform,_toast,_audiences,reportSelectors,_fragment,_changechecker){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_templates=_interopRequireDefault(_templates),_notification=_interopRequireDefault(_notification),_pending=_interopRequireDefault(_pending),_dynamicform=_interopRequireDefault(_dynamicform),reportSelectors=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(reportSelectors);let reportId=0,contextId=0;const initAudienceCardForm=audienceCard=>{const audienceFormContainer=audienceCard.querySelector(reportSelectors.regions.audienceFormContainer),audienceForm=new _dynamicform.default(audienceFormContainer,"\\core_reportbuilder\\form\\audience");return audienceForm.addEventListener(audienceForm.events.FORM_SUBMITTED,(data=>{const audienceHeading=audienceCard.querySelector(reportSelectors.regions.audienceHeading),audienceDescription=audienceCard.querySelector(reportSelectors.regions.audienceDescription);return audienceCard.dataset.instanceid=data.detail.instanceid,audienceHeading.innerHTML=data.detail.heading,audienceDescription.innerHTML=data.detail.description,closeAudienceCardForm(audienceCard),(0,_str.get_string)("audiencesaved","core_reportbuilder").then(_toast.add)})),audienceForm.addEventListener(audienceForm.events.FORM_CANCELLED,(()=>{audienceCard.dataset.instanceid>0?closeAudienceCardForm(audienceCard):removeAudienceCard(audienceCard)})),audienceForm},closeAudienceCardForm=audienceCard=>{const audienceFormContainer=audienceCard.querySelector(reportSelectors.regions.audienceFormContainer),NewAudienceFormContainer=audienceFormContainer.cloneNode(!1);audienceCard.querySelector(reportSelectors.regions.audienceForm).replaceChild(NewAudienceFormContainer,audienceFormContainer),audienceCard.querySelector(reportSelectors.regions.audienceDescription).classList.remove("hidden"),audienceCard.querySelector(reportSelectors.actions.audienceEdit).disabled=!1,audienceCard.querySelector(reportSelectors.actions.audienceDelete).disabled=!1},removeAudienceCard=audienceCard=>{audienceCard.remove();const audienceCards=document.querySelector(reportSelectors.regions.audiencesContainer).querySelectorAll(reportSelectors.regions.audienceCard);if(0===audienceCards.length){document.querySelector(reportSelectors.regions.audienceEmptyMessage).classList.remove("hidden")}else{const audienceFirstCardSeparator=audienceCards[0].querySelector(".audience-separator");null==audienceFirstCardSeparator||audienceFirstCardSeparator.remove()}};let initialized=!1;_exports.init=(id,contextid)=>{(0,_prefetch.prefetchStrings)("core_reportbuilder",["audienceadded","audiencedeleted","audiencesaved","deleteaudience","deleteaudienceconfirm"]),(0,_prefetch.prefetchStrings)("core",["delete"]),reportId=id,contextId=contextid,initialized||(document.addEventListener("click",(event=>{const audienceAdd=event.target.closest(reportSelectors.actions.audienceAdd);audienceAdd&&(event.preventDefault(),((className,title)=>{const pendingPromise=new _pending.default("core_reportbuilder/audience:add"),audiencesContainer=document.querySelector(reportSelectors.regions.audiencesContainer),audienceCardLength=audiencesContainer.querySelectorAll(reportSelectors.regions.audienceCard).length,params={classname:className,reportid:reportId,showormessage:audienceCardLength>0,title:title};(0,_fragment.loadFragment)("core_reportbuilder","audience_form",contextId,params).then(((html,js)=>{const audienceCard=_templates.default.appendNodeContents(audiencesContainer,html,js)[0],audienceEmptyMessage=audiencesContainer.querySelector(reportSelectors.regions.audienceEmptyMessage),audienceForm=initAudienceCardForm(audienceCard);return(0,_changechecker.markFormAsDirty)(audienceForm.getFormNode()),audienceEmptyMessage.classList.add("hidden"),(0,_str.get_string)("audienceadded","core_reportbuilder",title)})).then(_toast.add).then((()=>pendingPromise.resolve())).catch(_notification.default.exception)})(audienceAdd.dataset.uniqueIdentifier,audienceAdd.dataset.name));const audienceEdit=event.target.closest(reportSelectors.actions.audienceEdit);if(audienceEdit){const audienceEditCard=audienceEdit.closest(reportSelectors.regions.audienceCard);event.preventDefault(),(audienceCard=>{const pendingPromise=new _pending.default("core_reportbuilder/audience:edit"),audienceForm=initAudienceCardForm(audienceCard),audienceFormData={reportid:reportId,id:audienceCard.dataset.instanceid,classname:audienceCard.dataset.classname};audienceForm.load(audienceFormData).then((()=>{const audienceFormContainer=audienceCard.querySelector(reportSelectors.regions.audienceFormContainer),audienceDescription=audienceCard.querySelector(reportSelectors.regions.audienceDescription),audienceEdit=audienceCard.querySelector(reportSelectors.actions.audienceEdit);return audienceFormContainer.classList.remove("hidden"),audienceDescription.classList.add("hidden"),audienceEdit.disabled=!0,pendingPromise.resolve()})).catch(_notification.default.exception)})(audienceEditCard)}const audienceDelete=event.target.closest(reportSelectors.actions.audienceDelete);audienceDelete&&(event.preventDefault(),(audienceDelete=>{const audienceCard=audienceDelete.closest(reportSelectors.regions.audienceCard),audienceTitle=audienceCard.dataset.title;_notification.default.saveCancelPromise((0,_str.get_string)("deleteaudience","core_reportbuilder",audienceTitle),(0,_str.get_string)("deleteaudienceconfirm","core_reportbuilder",audienceTitle),(0,_str.get_string)("delete","core"),{triggerElement:audienceDelete}).then((()=>{const pendingPromise=new _pending.default("core_reportbuilder/audience:delete");return(0,_audiences.deleteAudience)(reportId,audienceCard.dataset.instanceid).then((()=>(0,_toast.add)((0,_str.get_string)("audiencedeleted","core_reportbuilder",audienceTitle)))).then((()=>(removeAudienceCard(audienceCard),pendingPromise.resolve()))).catch(_notification.default.exception)})).catch((()=>{}))})(audienceDelete))})),initialized=!0)}})); //# sourceMappingURL=audience.min.js.map \ No newline at end of file diff --git a/reportbuilder/amd/build/audience.min.js.map b/reportbuilder/amd/build/audience.min.js.map index 4b787fe64f8..982d858b4fe 100644 --- a/reportbuilder/amd/build/audience.min.js.map +++ b/reportbuilder/amd/build/audience.min.js.map @@ -1 +1 @@ -{"version":3,"file":"audience.min.js","sources":["../src/audience.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 * Report builder audiences\n *\n * @module core_reportbuilder/audience\n * @copyright 2021 David Matamoros \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n\"use strict\";\n\nimport Templates from 'core/templates';\nimport Notification from 'core/notification';\nimport Pending from 'core/pending';\nimport {prefetchStrings} from 'core/prefetch';\nimport {get_string as getString} from 'core/str';\nimport DynamicForm from 'core_form/dynamicform';\nimport {add as addToast} from 'core/toast';\nimport {deleteAudience} from 'core_reportbuilder/local/repository/audiences';\nimport * as reportSelectors from 'core_reportbuilder/local/selectors';\nimport {loadFragment} from 'core/fragment';\nimport {markFormAsDirty} from 'core_form/changechecker';\n\nlet reportId = 0;\nlet contextId = 0;\n\n/**\n * Add audience card\n *\n * @param {String} className\n * @param {String} title\n */\nconst addAudienceCard = (className, title) => {\n const pendingPromise = new Pending('core_reportbuilder/audience:add');\n\n const audiencesContainer = document.querySelector(reportSelectors.regions.audiencesContainer);\n const audienceCardLength = audiencesContainer.querySelectorAll(reportSelectors.regions.audienceCard).length;\n\n const params = {\n classname: className,\n reportid: reportId,\n showormessage: (audienceCardLength > 0),\n title: title,\n };\n\n // Load audience card fragment, render and then initialise the form within.\n loadFragment('core_reportbuilder', 'audience_form', contextId, params)\n .then((html, js) => {\n const audienceCard = Templates.appendNodeContents(audiencesContainer, html, js)[0];\n const audienceEmptyMessage = audiencesContainer.querySelector(reportSelectors.regions.audienceEmptyMessage);\n\n const audienceForm = initAudienceCardForm(audienceCard);\n // Mark as dirty new audience form created to prevent users leaving the page without saving it.\n markFormAsDirty(audienceForm.getFormNode());\n audienceEmptyMessage.classList.add('hidden');\n\n return getString('audienceadded', 'core_reportbuilder', title);\n })\n .then(addToast)\n .then(() => pendingPromise.resolve())\n .catch(Notification.exception);\n};\n\n/**\n * Edit audience card\n *\n * @param {Element} audienceCard\n */\nconst editAudienceCard = audienceCard => {\n const pendingPromise = new Pending('core_reportbuilder/audience:edit');\n\n const audienceForm = initAudienceCardForm(audienceCard);\n const audienceFormData = {\n reportid: reportId,\n id: audienceCard.dataset.instanceid,\n classname: audienceCard.dataset.classname\n };\n\n // Load audience form with data for editing, then toggle visible controls in the card.\n audienceForm.load(audienceFormData)\n .then(() => {\n const audienceFormContainer = audienceCard.querySelector(reportSelectors.regions.audienceFormContainer);\n const audienceDescription = audienceCard.querySelector(reportSelectors.regions.audienceDescription);\n const audienceEdit = audienceCard.querySelector(reportSelectors.actions.audienceEdit);\n\n audienceFormContainer.classList.remove('hidden');\n audienceDescription.classList.add('hidden');\n audienceEdit.disabled = true;\n\n return pendingPromise.resolve();\n })\n .catch(Notification.exception);\n};\n\n/**\n * Initialise dynamic form within given audience card\n *\n * @param {Element} audienceCard\n * @return {DynamicForm}\n */\nconst initAudienceCardForm = audienceCard => {\n const audienceFormContainer = audienceCard.querySelector(reportSelectors.regions.audienceFormContainer);\n const audienceForm = new DynamicForm(audienceFormContainer, '\\\\core_reportbuilder\\\\form\\\\audience');\n\n // After submitting the form, update the card instance and description properties.\n audienceForm.addEventListener(audienceForm.events.FORM_SUBMITTED, data => {\n const audienceDescription = audienceCard.querySelector(reportSelectors.regions.audienceDescription);\n\n audienceCard.dataset.instanceid = data.detail.instanceid;\n audienceDescription.innerHTML = data.detail.description;\n\n closeAudienceCardForm(audienceCard);\n\n return getString('audiencesaved', 'core_reportbuilder')\n .then(addToast);\n });\n\n // If cancelling the form, close the card or remove it if it was never created.\n audienceForm.addEventListener(audienceForm.events.FORM_CANCELLED, () => {\n if (audienceCard.dataset.instanceid > 0) {\n closeAudienceCardForm(audienceCard);\n } else {\n removeAudienceCard(audienceCard);\n }\n });\n\n return audienceForm;\n};\n\n/**\n * Delete audience card\n *\n * @param {Element} audienceDelete\n */\nconst deleteAudienceCard = audienceDelete => {\n const audienceCard = audienceDelete.closest(reportSelectors.regions.audienceCard);\n const audienceTitle = audienceCard.dataset.title;\n\n Notification.saveCancelPromise(\n getString('deleteaudience', 'core_reportbuilder', audienceTitle),\n getString('deleteaudienceconfirm', 'core_reportbuilder', audienceTitle),\n getString('delete', 'core'),\n {triggerElement: audienceDelete}\n ).then(() => {\n const pendingPromise = new Pending('core_reportbuilder/audience:delete');\n\n return deleteAudience(reportId, audienceCard.dataset.instanceid)\n .then(() => addToast(getString('audiencedeleted', 'core_reportbuilder', audienceTitle)))\n .then(() => {\n removeAudienceCard(audienceCard);\n return pendingPromise.resolve();\n })\n .catch(Notification.exception);\n }).catch(() => {\n return;\n });\n};\n\n/**\n * Close audience card form\n *\n * @param {Element} audienceCard\n */\nconst closeAudienceCardForm = audienceCard => {\n // Remove the [data-region=\"audience-form-container\"] (with all the event listeners attached to it), and create it again.\n const audienceFormContainer = audienceCard.querySelector(reportSelectors.regions.audienceFormContainer);\n const NewAudienceFormContainer = audienceFormContainer.cloneNode(false);\n audienceCard.querySelector(reportSelectors.regions.audienceForm).replaceChild(NewAudienceFormContainer, audienceFormContainer);\n // Show the description container and enable the action buttons.\n audienceCard.querySelector(reportSelectors.regions.audienceDescription).classList.remove('hidden');\n audienceCard.querySelector(reportSelectors.actions.audienceEdit).disabled = false;\n audienceCard.querySelector(reportSelectors.actions.audienceDelete).disabled = false;\n};\n\n/**\n * Remove audience card\n *\n * @param {Element} audienceCard\n */\nconst removeAudienceCard = audienceCard => {\n audienceCard.remove();\n\n const audiencesContainer = document.querySelector(reportSelectors.regions.audiencesContainer);\n const audienceCards = audiencesContainer.querySelectorAll(reportSelectors.regions.audienceCard);\n\n // Show message if there are no cards remaining, ensure first card's separator is not present.\n if (audienceCards.length === 0) {\n const audienceEmptyMessage = document.querySelector(reportSelectors.regions.audienceEmptyMessage);\n audienceEmptyMessage.classList.remove('hidden');\n } else {\n const audienceFirstCardSeparator = audienceCards[0].querySelector('.audience-separator');\n audienceFirstCardSeparator?.remove();\n }\n};\n\nlet initialized = false;\n\n/**\n * Initialise audiences tab.\n *\n * @param {Number} id\n * @param {Number} contextid\n */\nexport const init = (id, contextid) => {\n prefetchStrings('core_reportbuilder', [\n 'audienceadded',\n 'audiencedeleted',\n 'audiencesaved',\n 'deleteaudience',\n 'deleteaudienceconfirm',\n ]);\n\n prefetchStrings('core', [\n 'delete',\n ]);\n\n reportId = id;\n contextId = contextid;\n\n if (initialized) {\n // We already added the event listeners (can be called multiple times by mustache template).\n return;\n }\n\n document.addEventListener('click', event => {\n\n // Add instance.\n const audienceAdd = event.target.closest(reportSelectors.actions.audienceAdd);\n if (audienceAdd) {\n event.preventDefault();\n addAudienceCard(audienceAdd.dataset.uniqueIdentifier, audienceAdd.dataset.name);\n }\n\n // Edit instance.\n const audienceEdit = event.target.closest(reportSelectors.actions.audienceEdit);\n if (audienceEdit) {\n const audienceEditCard = audienceEdit.closest(reportSelectors.regions.audienceCard);\n\n event.preventDefault();\n editAudienceCard(audienceEditCard);\n }\n\n // Delete instance.\n const audienceDelete = event.target.closest(reportSelectors.actions.audienceDelete);\n if (audienceDelete) {\n event.preventDefault();\n deleteAudienceCard(audienceDelete);\n }\n });\n\n initialized = true;\n};\n"],"names":["reportId","contextId","initAudienceCardForm","audienceCard","audienceFormContainer","querySelector","reportSelectors","regions","audienceForm","DynamicForm","addEventListener","events","FORM_SUBMITTED","data","audienceDescription","dataset","instanceid","detail","innerHTML","description","closeAudienceCardForm","then","addToast","FORM_CANCELLED","removeAudienceCard","NewAudienceFormContainer","cloneNode","replaceChild","classList","remove","actions","audienceEdit","disabled","audienceDelete","audienceCards","document","audiencesContainer","querySelectorAll","length","audienceEmptyMessage","audienceFirstCardSeparator","initialized","id","contextid","event","audienceAdd","target","closest","preventDefault","className","title","pendingPromise","Pending","audienceCardLength","params","classname","reportid","showormessage","html","js","Templates","appendNodeContents","getFormNode","add","resolve","catch","Notification","exception","addAudienceCard","uniqueIdentifier","name","audienceEditCard","audienceFormData","load","editAudienceCard","audienceTitle","saveCancelPromise","triggerElement","deleteAudienceCard"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"audience.min.js","sources":["../src/audience.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 * Report builder audiences\n *\n * @module core_reportbuilder/audience\n * @copyright 2021 David Matamoros \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n\"use strict\";\n\nimport 'core/inplace_editable';\nimport Templates from 'core/templates';\nimport Notification from 'core/notification';\nimport Pending from 'core/pending';\nimport {prefetchStrings} from 'core/prefetch';\nimport {get_string as getString} from 'core/str';\nimport DynamicForm from 'core_form/dynamicform';\nimport {add as addToast} from 'core/toast';\nimport {deleteAudience} from 'core_reportbuilder/local/repository/audiences';\nimport * as reportSelectors from 'core_reportbuilder/local/selectors';\nimport {loadFragment} from 'core/fragment';\nimport {markFormAsDirty} from 'core_form/changechecker';\n\nlet reportId = 0;\nlet contextId = 0;\n\n/**\n * Add audience card\n *\n * @param {String} className\n * @param {String} title\n */\nconst addAudienceCard = (className, title) => {\n const pendingPromise = new Pending('core_reportbuilder/audience:add');\n\n const audiencesContainer = document.querySelector(reportSelectors.regions.audiencesContainer);\n const audienceCardLength = audiencesContainer.querySelectorAll(reportSelectors.regions.audienceCard).length;\n\n const params = {\n classname: className,\n reportid: reportId,\n showormessage: (audienceCardLength > 0),\n title: title,\n };\n\n // Load audience card fragment, render and then initialise the form within.\n loadFragment('core_reportbuilder', 'audience_form', contextId, params)\n .then((html, js) => {\n const audienceCard = Templates.appendNodeContents(audiencesContainer, html, js)[0];\n const audienceEmptyMessage = audiencesContainer.querySelector(reportSelectors.regions.audienceEmptyMessage);\n\n const audienceForm = initAudienceCardForm(audienceCard);\n // Mark as dirty new audience form created to prevent users leaving the page without saving it.\n markFormAsDirty(audienceForm.getFormNode());\n audienceEmptyMessage.classList.add('hidden');\n\n return getString('audienceadded', 'core_reportbuilder', title);\n })\n .then(addToast)\n .then(() => pendingPromise.resolve())\n .catch(Notification.exception);\n};\n\n/**\n * Edit audience card\n *\n * @param {Element} audienceCard\n */\nconst editAudienceCard = audienceCard => {\n const pendingPromise = new Pending('core_reportbuilder/audience:edit');\n\n const audienceForm = initAudienceCardForm(audienceCard);\n const audienceFormData = {\n reportid: reportId,\n id: audienceCard.dataset.instanceid,\n classname: audienceCard.dataset.classname\n };\n\n // Load audience form with data for editing, then toggle visible controls in the card.\n audienceForm.load(audienceFormData)\n .then(() => {\n const audienceFormContainer = audienceCard.querySelector(reportSelectors.regions.audienceFormContainer);\n const audienceDescription = audienceCard.querySelector(reportSelectors.regions.audienceDescription);\n const audienceEdit = audienceCard.querySelector(reportSelectors.actions.audienceEdit);\n\n audienceFormContainer.classList.remove('hidden');\n audienceDescription.classList.add('hidden');\n audienceEdit.disabled = true;\n\n return pendingPromise.resolve();\n })\n .catch(Notification.exception);\n};\n\n/**\n * Initialise dynamic form within given audience card\n *\n * @param {Element} audienceCard\n * @return {DynamicForm}\n */\nconst initAudienceCardForm = audienceCard => {\n const audienceFormContainer = audienceCard.querySelector(reportSelectors.regions.audienceFormContainer);\n const audienceForm = new DynamicForm(audienceFormContainer, '\\\\core_reportbuilder\\\\form\\\\audience');\n\n // After submitting the form, update the card instance and description properties.\n audienceForm.addEventListener(audienceForm.events.FORM_SUBMITTED, data => {\n const audienceHeading = audienceCard.querySelector(reportSelectors.regions.audienceHeading);\n const audienceDescription = audienceCard.querySelector(reportSelectors.regions.audienceDescription);\n\n audienceCard.dataset.instanceid = data.detail.instanceid;\n\n audienceHeading.innerHTML = data.detail.heading;\n audienceDescription.innerHTML = data.detail.description;\n\n closeAudienceCardForm(audienceCard);\n\n return getString('audiencesaved', 'core_reportbuilder')\n .then(addToast);\n });\n\n // If cancelling the form, close the card or remove it if it was never created.\n audienceForm.addEventListener(audienceForm.events.FORM_CANCELLED, () => {\n if (audienceCard.dataset.instanceid > 0) {\n closeAudienceCardForm(audienceCard);\n } else {\n removeAudienceCard(audienceCard);\n }\n });\n\n return audienceForm;\n};\n\n/**\n * Delete audience card\n *\n * @param {Element} audienceDelete\n */\nconst deleteAudienceCard = audienceDelete => {\n const audienceCard = audienceDelete.closest(reportSelectors.regions.audienceCard);\n const audienceTitle = audienceCard.dataset.title;\n\n Notification.saveCancelPromise(\n getString('deleteaudience', 'core_reportbuilder', audienceTitle),\n getString('deleteaudienceconfirm', 'core_reportbuilder', audienceTitle),\n getString('delete', 'core'),\n {triggerElement: audienceDelete}\n ).then(() => {\n const pendingPromise = new Pending('core_reportbuilder/audience:delete');\n\n return deleteAudience(reportId, audienceCard.dataset.instanceid)\n .then(() => addToast(getString('audiencedeleted', 'core_reportbuilder', audienceTitle)))\n .then(() => {\n removeAudienceCard(audienceCard);\n return pendingPromise.resolve();\n })\n .catch(Notification.exception);\n }).catch(() => {\n return;\n });\n};\n\n/**\n * Close audience card form\n *\n * @param {Element} audienceCard\n */\nconst closeAudienceCardForm = audienceCard => {\n // Remove the [data-region=\"audience-form-container\"] (with all the event listeners attached to it), and create it again.\n const audienceFormContainer = audienceCard.querySelector(reportSelectors.regions.audienceFormContainer);\n const NewAudienceFormContainer = audienceFormContainer.cloneNode(false);\n audienceCard.querySelector(reportSelectors.regions.audienceForm).replaceChild(NewAudienceFormContainer, audienceFormContainer);\n // Show the description container and enable the action buttons.\n audienceCard.querySelector(reportSelectors.regions.audienceDescription).classList.remove('hidden');\n audienceCard.querySelector(reportSelectors.actions.audienceEdit).disabled = false;\n audienceCard.querySelector(reportSelectors.actions.audienceDelete).disabled = false;\n};\n\n/**\n * Remove audience card\n *\n * @param {Element} audienceCard\n */\nconst removeAudienceCard = audienceCard => {\n audienceCard.remove();\n\n const audiencesContainer = document.querySelector(reportSelectors.regions.audiencesContainer);\n const audienceCards = audiencesContainer.querySelectorAll(reportSelectors.regions.audienceCard);\n\n // Show message if there are no cards remaining, ensure first card's separator is not present.\n if (audienceCards.length === 0) {\n const audienceEmptyMessage = document.querySelector(reportSelectors.regions.audienceEmptyMessage);\n audienceEmptyMessage.classList.remove('hidden');\n } else {\n const audienceFirstCardSeparator = audienceCards[0].querySelector('.audience-separator');\n audienceFirstCardSeparator?.remove();\n }\n};\n\nlet initialized = false;\n\n/**\n * Initialise audiences tab.\n *\n * @param {Number} id\n * @param {Number} contextid\n */\nexport const init = (id, contextid) => {\n prefetchStrings('core_reportbuilder', [\n 'audienceadded',\n 'audiencedeleted',\n 'audiencesaved',\n 'deleteaudience',\n 'deleteaudienceconfirm',\n ]);\n\n prefetchStrings('core', [\n 'delete',\n ]);\n\n reportId = id;\n contextId = contextid;\n\n if (initialized) {\n // We already added the event listeners (can be called multiple times by mustache template).\n return;\n }\n\n document.addEventListener('click', event => {\n\n // Add instance.\n const audienceAdd = event.target.closest(reportSelectors.actions.audienceAdd);\n if (audienceAdd) {\n event.preventDefault();\n addAudienceCard(audienceAdd.dataset.uniqueIdentifier, audienceAdd.dataset.name);\n }\n\n // Edit instance.\n const audienceEdit = event.target.closest(reportSelectors.actions.audienceEdit);\n if (audienceEdit) {\n const audienceEditCard = audienceEdit.closest(reportSelectors.regions.audienceCard);\n\n event.preventDefault();\n editAudienceCard(audienceEditCard);\n }\n\n // Delete instance.\n const audienceDelete = event.target.closest(reportSelectors.actions.audienceDelete);\n if (audienceDelete) {\n event.preventDefault();\n deleteAudienceCard(audienceDelete);\n }\n });\n\n initialized = true;\n};\n"],"names":["reportId","contextId","initAudienceCardForm","audienceCard","audienceFormContainer","querySelector","reportSelectors","regions","audienceForm","DynamicForm","addEventListener","events","FORM_SUBMITTED","data","audienceHeading","audienceDescription","dataset","instanceid","detail","innerHTML","heading","description","closeAudienceCardForm","then","addToast","FORM_CANCELLED","removeAudienceCard","NewAudienceFormContainer","cloneNode","replaceChild","classList","remove","actions","audienceEdit","disabled","audienceDelete","audienceCards","document","audiencesContainer","querySelectorAll","length","audienceEmptyMessage","audienceFirstCardSeparator","initialized","id","contextid","event","audienceAdd","target","closest","preventDefault","className","title","pendingPromise","Pending","audienceCardLength","params","classname","reportid","showormessage","html","js","Templates","appendNodeContents","getFormNode","add","resolve","catch","Notification","exception","addAudienceCard","uniqueIdentifier","name","audienceEditCard","audienceFormData","load","editAudienceCard","audienceTitle","saveCancelPromise","triggerElement","deleteAudienceCard"],"mappings":"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"} \ No newline at end of file diff --git a/reportbuilder/amd/build/local/selectors.min.js b/reportbuilder/amd/build/local/selectors.min.js index ed8c55bea59..6963addaa54 100644 --- a/reportbuilder/amd/build/local/selectors.min.js +++ b/reportbuilder/amd/build/local/selectors.min.js @@ -6,6 +6,6 @@ define("core_reportbuilder/local/selectors",["exports"],(function(_exports){Obje * @copyright 2021 Paul Holden * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -const SELECTORS={regions:{report:'[data-region="core_reportbuilder/report"]',reportTable:'[data-region="reportbuilder-table"]',columnHeader:'[data-region="column-header"]',filterButtonLabel:'[data-region="filter-button-label"]',filtersForm:'[data-region="filters-form"]',sidebarMenu:'[data-region="sidebar-menu"]',sidebarCard:'[data-region="sidebar-card"]',settingsConditions:'[data-region="settings-conditions"]',activeConditions:'[data-region="active-conditions"]',activeCondition:'[data-region="active-condition"]',settingsFilters:'[data-region="settings-filters"]',activeFilters:'[data-region="active-filters"]',activeFilter:'[data-region="active-filter"]',settingsSorting:'[data-region="settings-sorting"]',audiencesContainer:'[data-region="audiences"]',audienceFormContainer:'[data-region="audience-form-container"]',audienceCard:'[data-region="audience-card"]',audienceForm:'[data-region="audience-form"]',audienceEmptyMessage:"[data-region=no-instances-message]",audienceDescription:"[data-region=audience-description]",audienceNotSavedLabel:"[data-region=audience-not-saved]",settingsCardView:'[data-region="settings-cardview"]'},actions:{reportActionPopup:'[data-action="report-action-popup"]',reportCreate:'[data-action="report-create"]',reportEdit:'[data-action="report-edit"]',reportDelete:'[data-action="report-delete"]',reportAddColumn:'[data-action="report-add-column"]',reportRemoveColumn:'[data-action="report-remove-column"]',reportAddCondition:'[data-action="report-add-condition"]',reportRemoveCondition:'[data-action="report-remove-condition"]',reportAddFilter:'[data-action="report-add-filter"]',reportRemoveFilter:'[data-action="report-remove-filter"]',reportToggleColumnSort:'[data-action="report-toggle-column-sorting"]',reportToggleColumnSortDirection:'[data-action="report-toggle-sort-direction"]',sidebarSearch:'[data-action="sidebar-search"]',toggleEditPreview:'[data-action="toggle-edit-preview"]',audienceAdd:'[data-action="add-audience"]',audienceEdit:'[data-action="edit-audience"]',audienceDelete:'[data-action="delete-audience"]',toggleCardView:'[data-action="toggle-card"]',scheduleCreate:'[data-action="schedule-create"]',scheduleToggle:'[data-action="schedule-toggle"]',scheduleEdit:'[data-action="schedule-edit"]',scheduleSend:'[data-action="schedule-send"]',scheduleDelete:'[data-action="schedule-delete"]'},forReport:reportId=>"".concat(SELECTORS.regions.report,'[data-report-id="').concat(reportId,'"]')};var _default=SELECTORS;return _exports.default=_default,_exports.default})); +const SELECTORS={regions:{report:'[data-region="core_reportbuilder/report"]',reportTable:'[data-region="reportbuilder-table"]',columnHeader:'[data-region="column-header"]',filterButtonLabel:'[data-region="filter-button-label"]',filtersForm:'[data-region="filters-form"]',sidebarMenu:'[data-region="sidebar-menu"]',sidebarCard:'[data-region="sidebar-card"]',settingsConditions:'[data-region="settings-conditions"]',activeConditions:'[data-region="active-conditions"]',activeCondition:'[data-region="active-condition"]',settingsFilters:'[data-region="settings-filters"]',activeFilters:'[data-region="active-filters"]',activeFilter:'[data-region="active-filter"]',settingsSorting:'[data-region="settings-sorting"]',audiencesContainer:'[data-region="audiences"]',audienceFormContainer:'[data-region="audience-form-container"]',audienceCard:'[data-region="audience-card"]',audienceHeading:'[data-region="audience-heading"]',audienceForm:'[data-region="audience-form"]',audienceEmptyMessage:"[data-region=no-instances-message]",audienceDescription:"[data-region=audience-description]",audienceNotSavedLabel:"[data-region=audience-not-saved]",settingsCardView:'[data-region="settings-cardview"]'},actions:{reportActionPopup:'[data-action="report-action-popup"]',reportCreate:'[data-action="report-create"]',reportEdit:'[data-action="report-edit"]',reportDelete:'[data-action="report-delete"]',reportAddColumn:'[data-action="report-add-column"]',reportRemoveColumn:'[data-action="report-remove-column"]',reportAddCondition:'[data-action="report-add-condition"]',reportRemoveCondition:'[data-action="report-remove-condition"]',reportAddFilter:'[data-action="report-add-filter"]',reportRemoveFilter:'[data-action="report-remove-filter"]',reportToggleColumnSort:'[data-action="report-toggle-column-sorting"]',reportToggleColumnSortDirection:'[data-action="report-toggle-sort-direction"]',sidebarSearch:'[data-action="sidebar-search"]',toggleEditPreview:'[data-action="toggle-edit-preview"]',audienceAdd:'[data-action="add-audience"]',audienceEdit:'[data-action="edit-audience"]',audienceDelete:'[data-action="delete-audience"]',toggleCardView:'[data-action="toggle-card"]',scheduleCreate:'[data-action="schedule-create"]',scheduleToggle:'[data-action="schedule-toggle"]',scheduleEdit:'[data-action="schedule-edit"]',scheduleSend:'[data-action="schedule-send"]',scheduleDelete:'[data-action="schedule-delete"]'},forReport:reportId=>"".concat(SELECTORS.regions.report,'[data-report-id="').concat(reportId,'"]')};var _default=SELECTORS;return _exports.default=_default,_exports.default})); //# sourceMappingURL=selectors.min.js.map \ No newline at end of file diff --git a/reportbuilder/amd/build/local/selectors.min.js.map b/reportbuilder/amd/build/local/selectors.min.js.map index ebc266eb9ec..0e4ec7427e6 100644 --- a/reportbuilder/amd/build/local/selectors.min.js.map +++ b/reportbuilder/amd/build/local/selectors.min.js.map @@ -1 +1 @@ -{"version":3,"file":"selectors.min.js","sources":["../../src/local/selectors.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 * Report builder selectors\n *\n * @module core_reportbuilder/local/selectors\n * @copyright 2021 Paul Holden \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n/**\n * Selectors for the Report builder subsystem\n *\n * @property {Object} regions\n * @property {String} regions.systemReport System report page region\n * @property {String} regions.filterButtonLabel Filters form toggle region\n * @property {String} regions.filtersForm Filters form page region\n */\nconst SELECTORS = {\n regions: {\n report: '[data-region=\"core_reportbuilder/report\"]',\n reportTable: '[data-region=\"reportbuilder-table\"]',\n columnHeader: '[data-region=\"column-header\"]',\n filterButtonLabel: '[data-region=\"filter-button-label\"]',\n filtersForm: '[data-region=\"filters-form\"]',\n sidebarMenu: '[data-region=\"sidebar-menu\"]',\n sidebarCard: '[data-region=\"sidebar-card\"]',\n settingsConditions: '[data-region=\"settings-conditions\"]',\n activeConditions: '[data-region=\"active-conditions\"]',\n activeCondition: '[data-region=\"active-condition\"]',\n settingsFilters: '[data-region=\"settings-filters\"]',\n activeFilters: '[data-region=\"active-filters\"]',\n activeFilter: '[data-region=\"active-filter\"]',\n settingsSorting: '[data-region=\"settings-sorting\"]',\n audiencesContainer: '[data-region=\"audiences\"]',\n audienceFormContainer: '[data-region=\"audience-form-container\"]',\n audienceCard: '[data-region=\"audience-card\"]',\n audienceForm: '[data-region=\"audience-form\"]',\n audienceEmptyMessage: '[data-region=no-instances-message]',\n audienceDescription: '[data-region=audience-description]',\n audienceNotSavedLabel: '[data-region=audience-not-saved]',\n settingsCardView: '[data-region=\"settings-cardview\"]',\n },\n actions: {\n reportActionPopup: '[data-action=\"report-action-popup\"]',\n reportCreate: '[data-action=\"report-create\"]',\n reportEdit: '[data-action=\"report-edit\"]',\n reportDelete: '[data-action=\"report-delete\"]',\n reportAddColumn: '[data-action=\"report-add-column\"]',\n reportRemoveColumn: '[data-action=\"report-remove-column\"]',\n reportAddCondition: '[data-action=\"report-add-condition\"]',\n reportRemoveCondition: '[data-action=\"report-remove-condition\"]',\n reportAddFilter: '[data-action=\"report-add-filter\"]',\n reportRemoveFilter: '[data-action=\"report-remove-filter\"]',\n reportToggleColumnSort: '[data-action=\"report-toggle-column-sorting\"]',\n reportToggleColumnSortDirection: '[data-action=\"report-toggle-sort-direction\"]',\n sidebarSearch: '[data-action=\"sidebar-search\"]',\n toggleEditPreview: '[data-action=\"toggle-edit-preview\"]',\n audienceAdd: '[data-action=\"add-audience\"]',\n audienceEdit: '[data-action=\"edit-audience\"]',\n audienceDelete: '[data-action=\"delete-audience\"]',\n toggleCardView: '[data-action=\"toggle-card\"]',\n scheduleCreate: '[data-action=\"schedule-create\"]',\n scheduleToggle: '[data-action=\"schedule-toggle\"]',\n scheduleEdit: '[data-action=\"schedule-edit\"]',\n scheduleSend: '[data-action=\"schedule-send\"]',\n scheduleDelete: '[data-action=\"schedule-delete\"]',\n },\n};\n\n/**\n * Selector for given report\n *\n * @method forReport\n * @param {Number} reportId\n * @return {String}\n */\nSELECTORS.forReport = reportId => `${SELECTORS.regions.report}[data-report-id=\"${reportId}\"]`;\n\nexport default SELECTORS;\n"],"names":["SELECTORS","regions","report","reportTable","columnHeader","filterButtonLabel","filtersForm","sidebarMenu","sidebarCard","settingsConditions","activeConditions","activeCondition","settingsFilters","activeFilters","activeFilter","settingsSorting","audiencesContainer","audienceFormContainer","audienceCard","audienceForm","audienceEmptyMessage","audienceDescription","audienceNotSavedLabel","settingsCardView","actions","reportActionPopup","reportCreate","reportEdit","reportDelete","reportAddColumn","reportRemoveColumn","reportAddCondition","reportRemoveCondition","reportAddFilter","reportRemoveFilter","reportToggleColumnSort","reportToggleColumnSortDirection","sidebarSearch","toggleEditPreview","audienceAdd","audienceEdit","audienceDelete","toggleCardView","scheduleCreate","scheduleToggle","scheduleEdit","scheduleSend","scheduleDelete","reportId"],"mappings":";;;;;;;;MA+BMA,UAAY,CACdC,QAAS,CACLC,OAAQ,4CACRC,YAAa,sCACbC,aAAc,gCACdC,kBAAmB,sCACnBC,YAAa,+BACbC,YAAa,+BACbC,YAAa,+BACbC,mBAAoB,sCACpBC,iBAAkB,oCAClBC,gBAAiB,mCACjBC,gBAAiB,mCACjBC,cAAe,iCACfC,aAAc,gCACdC,gBAAiB,mCACjBC,mBAAoB,4BACpBC,sBAAuB,0CACvBC,aAAc,gCACdC,aAAc,gCACdC,qBAAsB,qCACtBC,oBAAqB,qCACrBC,sBAAuB,mCACvBC,iBAAkB,qCAEtBC,QAAS,CACLC,kBAAmB,sCACnBC,aAAc,gCACdC,WAAY,8BACZC,aAAc,gCACdC,gBAAiB,oCACjBC,mBAAoB,uCACpBC,mBAAoB,uCACpBC,sBAAuB,0CACvBC,gBAAiB,oCACjBC,mBAAoB,uCACpBC,uBAAwB,+CACxBC,gCAAiC,+CACjCC,cAAe,iCACfC,kBAAmB,sCACnBC,YAAa,+BACbC,aAAc,gCACdC,eAAgB,kCAChBC,eAAgB,8BAChBC,eAAgB,kCAChBC,eAAgB,kCAChBC,aAAc,gCACdC,aAAc,gCACdC,eAAgB,mCAWxB/C,UAAsBgD,oBAAehD,UAAUC,QAAQC,mCAA0B8C,6BAElEhD"} \ No newline at end of file +{"version":3,"file":"selectors.min.js","sources":["../../src/local/selectors.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 * Report builder selectors\n *\n * @module core_reportbuilder/local/selectors\n * @copyright 2021 Paul Holden \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n/**\n * Selectors for the Report builder subsystem\n *\n * @property {Object} regions\n * @property {String} regions.systemReport System report page region\n * @property {String} regions.filterButtonLabel Filters form toggle region\n * @property {String} regions.filtersForm Filters form page region\n */\nconst SELECTORS = {\n regions: {\n report: '[data-region=\"core_reportbuilder/report\"]',\n reportTable: '[data-region=\"reportbuilder-table\"]',\n columnHeader: '[data-region=\"column-header\"]',\n filterButtonLabel: '[data-region=\"filter-button-label\"]',\n filtersForm: '[data-region=\"filters-form\"]',\n sidebarMenu: '[data-region=\"sidebar-menu\"]',\n sidebarCard: '[data-region=\"sidebar-card\"]',\n settingsConditions: '[data-region=\"settings-conditions\"]',\n activeConditions: '[data-region=\"active-conditions\"]',\n activeCondition: '[data-region=\"active-condition\"]',\n settingsFilters: '[data-region=\"settings-filters\"]',\n activeFilters: '[data-region=\"active-filters\"]',\n activeFilter: '[data-region=\"active-filter\"]',\n settingsSorting: '[data-region=\"settings-sorting\"]',\n audiencesContainer: '[data-region=\"audiences\"]',\n audienceFormContainer: '[data-region=\"audience-form-container\"]',\n audienceCard: '[data-region=\"audience-card\"]',\n audienceHeading: '[data-region=\"audience-heading\"]',\n audienceForm: '[data-region=\"audience-form\"]',\n audienceEmptyMessage: '[data-region=no-instances-message]',\n audienceDescription: '[data-region=audience-description]',\n audienceNotSavedLabel: '[data-region=audience-not-saved]',\n settingsCardView: '[data-region=\"settings-cardview\"]',\n },\n actions: {\n reportActionPopup: '[data-action=\"report-action-popup\"]',\n reportCreate: '[data-action=\"report-create\"]',\n reportEdit: '[data-action=\"report-edit\"]',\n reportDelete: '[data-action=\"report-delete\"]',\n reportAddColumn: '[data-action=\"report-add-column\"]',\n reportRemoveColumn: '[data-action=\"report-remove-column\"]',\n reportAddCondition: '[data-action=\"report-add-condition\"]',\n reportRemoveCondition: '[data-action=\"report-remove-condition\"]',\n reportAddFilter: '[data-action=\"report-add-filter\"]',\n reportRemoveFilter: '[data-action=\"report-remove-filter\"]',\n reportToggleColumnSort: '[data-action=\"report-toggle-column-sorting\"]',\n reportToggleColumnSortDirection: '[data-action=\"report-toggle-sort-direction\"]',\n sidebarSearch: '[data-action=\"sidebar-search\"]',\n toggleEditPreview: '[data-action=\"toggle-edit-preview\"]',\n audienceAdd: '[data-action=\"add-audience\"]',\n audienceEdit: '[data-action=\"edit-audience\"]',\n audienceDelete: '[data-action=\"delete-audience\"]',\n toggleCardView: '[data-action=\"toggle-card\"]',\n scheduleCreate: '[data-action=\"schedule-create\"]',\n scheduleToggle: '[data-action=\"schedule-toggle\"]',\n scheduleEdit: '[data-action=\"schedule-edit\"]',\n scheduleSend: '[data-action=\"schedule-send\"]',\n scheduleDelete: '[data-action=\"schedule-delete\"]',\n },\n};\n\n/**\n * Selector for given report\n *\n * @method forReport\n * @param {Number} reportId\n * @return {String}\n */\nSELECTORS.forReport = reportId => `${SELECTORS.regions.report}[data-report-id=\"${reportId}\"]`;\n\nexport default SELECTORS;\n"],"names":["SELECTORS","regions","report","reportTable","columnHeader","filterButtonLabel","filtersForm","sidebarMenu","sidebarCard","settingsConditions","activeConditions","activeCondition","settingsFilters","activeFilters","activeFilter","settingsSorting","audiencesContainer","audienceFormContainer","audienceCard","audienceHeading","audienceForm","audienceEmptyMessage","audienceDescription","audienceNotSavedLabel","settingsCardView","actions","reportActionPopup","reportCreate","reportEdit","reportDelete","reportAddColumn","reportRemoveColumn","reportAddCondition","reportRemoveCondition","reportAddFilter","reportRemoveFilter","reportToggleColumnSort","reportToggleColumnSortDirection","sidebarSearch","toggleEditPreview","audienceAdd","audienceEdit","audienceDelete","toggleCardView","scheduleCreate","scheduleToggle","scheduleEdit","scheduleSend","scheduleDelete","reportId"],"mappings":";;;;;;;;MA+BMA,UAAY,CACdC,QAAS,CACLC,OAAQ,4CACRC,YAAa,sCACbC,aAAc,gCACdC,kBAAmB,sCACnBC,YAAa,+BACbC,YAAa,+BACbC,YAAa,+BACbC,mBAAoB,sCACpBC,iBAAkB,oCAClBC,gBAAiB,mCACjBC,gBAAiB,mCACjBC,cAAe,iCACfC,aAAc,gCACdC,gBAAiB,mCACjBC,mBAAoB,4BACpBC,sBAAuB,0CACvBC,aAAc,gCACdC,gBAAiB,mCACjBC,aAAc,gCACdC,qBAAsB,qCACtBC,oBAAqB,qCACrBC,sBAAuB,mCACvBC,iBAAkB,qCAEtBC,QAAS,CACLC,kBAAmB,sCACnBC,aAAc,gCACdC,WAAY,8BACZC,aAAc,gCACdC,gBAAiB,oCACjBC,mBAAoB,uCACpBC,mBAAoB,uCACpBC,sBAAuB,0CACvBC,gBAAiB,oCACjBC,mBAAoB,uCACpBC,uBAAwB,+CACxBC,gCAAiC,+CACjCC,cAAe,iCACfC,kBAAmB,sCACnBC,YAAa,+BACbC,aAAc,gCACdC,eAAgB,kCAChBC,eAAgB,8BAChBC,eAAgB,kCAChBC,eAAgB,kCAChBC,aAAc,gCACdC,aAAc,gCACdC,eAAgB,mCAWxBhD,UAAsBiD,oBAAejD,UAAUC,QAAQC,mCAA0B+C,6BAElEjD"} \ No newline at end of file diff --git a/reportbuilder/amd/src/audience.js b/reportbuilder/amd/src/audience.js index 041e76a3511..411e2088684 100644 --- a/reportbuilder/amd/src/audience.js +++ b/reportbuilder/amd/src/audience.js @@ -23,6 +23,7 @@ "use strict"; +import 'core/inplace_editable'; import Templates from 'core/templates'; import Notification from 'core/notification'; import Pending from 'core/pending'; @@ -118,9 +119,12 @@ const initAudienceCardForm = audienceCard => { // After submitting the form, update the card instance and description properties. audienceForm.addEventListener(audienceForm.events.FORM_SUBMITTED, data => { + const audienceHeading = audienceCard.querySelector(reportSelectors.regions.audienceHeading); const audienceDescription = audienceCard.querySelector(reportSelectors.regions.audienceDescription); audienceCard.dataset.instanceid = data.detail.instanceid; + + audienceHeading.innerHTML = data.detail.heading; audienceDescription.innerHTML = data.detail.description; closeAudienceCardForm(audienceCard); diff --git a/reportbuilder/amd/src/local/selectors.js b/reportbuilder/amd/src/local/selectors.js index 61d64401ac5..0c7d01c0377 100644 --- a/reportbuilder/amd/src/local/selectors.js +++ b/reportbuilder/amd/src/local/selectors.js @@ -48,6 +48,7 @@ const SELECTORS = { audiencesContainer: '[data-region="audiences"]', audienceFormContainer: '[data-region="audience-form-container"]', audienceCard: '[data-region="audience-card"]', + audienceHeading: '[data-region="audience-heading"]', audienceForm: '[data-region="audience-form"]', audienceEmptyMessage: '[data-region=no-instances-message]', audienceDescription: '[data-region=audience-description]', diff --git a/reportbuilder/classes/form/audience.php b/reportbuilder/classes/form/audience.php index 038abae5bdb..7c2489bdf73 100644 --- a/reportbuilder/classes/form/audience.php +++ b/reportbuilder/classes/form/audience.php @@ -22,9 +22,9 @@ use context; use context_system; use core_form\dynamic_form; use core_reportbuilder\local\audiences\base; +use core_reportbuilder\output\audience_heading_editable; use core_reportbuilder\manager; use core_reportbuilder\permission; -use core_reportbuilder\report_access_exception; use moodle_exception; use moodle_url; use stdClass; @@ -116,6 +116,8 @@ class audience extends dynamic_form { * Process the form submission, used if form was submitted via AJAX */ public function process_dynamic_submission() { + global $PAGE; + $formdata = $this->get_data(); $audience = $this->get_audience(); @@ -131,7 +133,15 @@ class audience extends dynamic_form { // Editing audience. $audience->update_configdata($configdata, true); } - return ['instanceid' => $audience->get_persistent()->get('id'), 'description' => $audience->get_description()]; + + $persistent = $audience->get_persistent(); + $editable = new audience_heading_editable(0, $persistent); + + return [ + 'instanceid' => $persistent->get('id'), + 'heading' => $editable->render($PAGE->get_renderer('core')), + 'description' => $audience->get_description(), + ]; } /** diff --git a/reportbuilder/templates/local/audience/form.mustache b/reportbuilder/templates/local/audience/form.mustache index 152e0d772f7..ee6f5339d8f 100644 --- a/reportbuilder/templates/local/audience/form.mustache +++ b/reportbuilder/templates/local/audience/form.mustache @@ -41,7 +41,7 @@
-

+

{{{headingeditable}}}

diff --git a/reportbuilder/tests/behat/audience.feature b/reportbuilder/tests/behat/audience.feature index 1426c5a6320..3a38a54a505 100644 --- a/reportbuilder/tests/behat/audience.feature +++ b/reportbuilder/tests/behat/audience.feature @@ -91,6 +91,15 @@ Feature: Configure access to reports based on intended audience # This audience type should be disabled because there are no cohorts available. And "Add audience 'Member of cohort'" "link" should not exist + Scenario: Rename report audience + Given I am on the "My report" "reportbuilder > Editor" page logged in as "admin" + And I click on the "Audience" dynamic tab + And I click on "Add audience 'All users'" "link" + And I press "Save changes" + When I set the field "Rename audience 'All users'" to "All my lovely users" + And I reload the page + Then I should see "All my lovely users" in the "[data-region='audience-card']" "css_element" + Scenario: Delete report audience Given I am on the "My report" "reportbuilder > Editor" page logged in as "admin" And I click on the "Audience" dynamic tab