first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+3
View File
@@ -0,0 +1,3 @@
define("core_reportbuilder/editor",["exports","jquery","core/inplace_editable","core/loadingicon","core/notification","core/pending","core/templates","core/str","core/toast","core_reportbuilder/local/selectors","core_reportbuilder/local/editor/columns","core_reportbuilder/local/editor/conditions","core_reportbuilder/local/editor/filters","core_reportbuilder/local/editor/sorting","core_reportbuilder/local/editor/card_view","core_reportbuilder/local/repository/reports","core_reportbuilder/local/repository/modals"],(function(_exports,_jquery,_inplace_editable,_loadingicon,_notification,_pending,_templates,_str,_toast,reportSelectors,_columns,_conditions,_filters,_sorting,_card_view,_reports,_modals){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,_jquery=_interopRequireDefault(_jquery),_notification=_interopRequireDefault(_notification),_pending=_interopRequireDefault(_pending),_templates=_interopRequireDefault(_templates),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 initialized=!1;_exports.init=()=>{(0,_columns.init)(initialized),(0,_conditions.init)(initialized),(0,_filters.init)(initialized),(0,_sorting.init)(initialized),(0,_card_view.init)(initialized),initialized||(document.addEventListener("click",(event=>{const toggleEditViewMode=event.target.closest(reportSelectors.actions.toggleEditPreview);if(toggleEditViewMode){event.preventDefault();const reportElement=event.target.closest(reportSelectors.regions.report),pendingPromise=new _pending.default("core_reportbuilder/reports:get"),toggledEditMode="1"!==toggleEditViewMode.dataset.editMode;(0,_loadingicon.addIconToContainer)(toggleEditViewMode).then((()=>(0,_reports.getReport)(reportElement.dataset.reportId,toggledEditMode))).then((response=>Promise.all([_jquery.default.parseHTML(response.javascript,null,!0).map((node=>node.innerHTML)).join("\n"),_templates.default.renderForPromise("core_reportbuilder/local/dynamictabs/editor",response)]))).then((_ref=>{let[responseJs,{html:html,js:js}]=_ref;return _templates.default.replaceNode(reportElement,html,js+responseJs)})).then((()=>pendingPromise.resolve())).catch(_notification.default.exception)}const reportEdit=event.target.closest(reportSelectors.actions.reportEdit);if(reportEdit){event.preventDefault();const reportModal=(0,_modals.createReportModal)(event.target,(0,_str.getString)("editreportdetails","core_reportbuilder"),reportEdit.dataset.reportId);reportModal.addEventListener(reportModal.events.FORM_SUBMITTED,(()=>{(0,_str.getString)("reportupdated","core_reportbuilder").then(_toast.add).then((()=>window.location.reload())).catch(_notification.default.exception)})),reportModal.show()}})),initialized=!0)}}));
//# sourceMappingURL=editor.min.js.map
File diff suppressed because one or more lines are too long
+10
View File
@@ -0,0 +1,10 @@
define("core_reportbuilder/filters",["exports","core/event_dispatcher","core/fragment","core/notification","core/pending","core/str","core/templates","core/toast","core_form/dynamicform","core_reportbuilder/local/events","core_reportbuilder/local/selectors","core_reportbuilder/local/repository/filters"],(function(_exports,_event_dispatcher,_fragment,_notification,_pending,_str,_templates,_toast,_dynamicform,reportEvents,reportSelectors,_filters){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireWildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}return newObj.default=obj,cache&&cache.set(obj,newObj),newObj}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}
/**
* Report builder filter management
*
* @module core_reportbuilder/filters
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_notification=_interopRequireDefault(_notification),_pending=_interopRequireDefault(_pending),_templates=_interopRequireDefault(_templates),_dynamicform=_interopRequireDefault(_dynamicform),reportEvents=_interopRequireWildcard(reportEvents),reportSelectors=_interopRequireWildcard(reportSelectors);const setFilterButtonCount=async(reportElement,filterCount)=>{const filterButtonLabel=reportElement.querySelector(reportSelectors.regions.filterButtonLabel);filterButtonLabel.textContent=filterCount>0?await(0,_str.getString)("filtersappliedx","core_reportbuilder",filterCount):await(0,_str.getString)("filters","moodle")};_exports.init=(reportId,contextId)=>{const reportElement=document.querySelector(reportSelectors.forReport(reportId)),filterFormContainer=reportElement.querySelector(reportSelectors.regions.filtersForm);if(filterFormContainer.dataset.initialized)return;filterFormContainer.dataset.initialized=!0;const filterForm=new _dynamicform.default(filterFormContainer,"\\core_reportbuilder\\form\\filter");filterForm.addEventListener(filterForm.events.FORM_SUBMITTED,(event=>{event.preventDefault(),(0,_event_dispatcher.dispatchEvent)(reportEvents.tableReload,{},reportElement),setFilterButtonCount(reportElement,event.detail),(0,_str.getString)("filtersapplied","core_reportbuilder").then(_toast.add).catch(_notification.default.exception)})),filterForm.addEventListener(filterForm.events.NOSUBMIT_BUTTON_PRESSED,(event=>{event.preventDefault();const pendingPromise=new _pending.default("core_reportbuilder/filters:reset"),reportParameters=reportElement.dataset.parameter;(0,_filters.resetFilters)(reportId,reportParameters).then((()=>(0,_str.getString)("filtersreset","core_reportbuilder"))).then(_toast.add).then((()=>(0,_fragment.loadFragment)("core_reportbuilder","filters_form",contextId,{reportid:reportId,parameters:reportParameters}))).then(((html,js)=>(_templates.default.replaceNodeContents(filterFormContainer,html,js),(0,_event_dispatcher.dispatchEvent)(reportEvents.tableReload,{},reportElement),setFilterButtonCount(reportElement,0),pendingPromise.resolve()))).catch(_notification.default.exception)})),document.querySelector("#region-main").style.overflowX="visible"}}));
//# sourceMappingURL=filters.min.js.map
File diff suppressed because one or more lines are too long
+3
View File
@@ -0,0 +1,3 @@
define("core_reportbuilder/local/editor/card_view",["exports","core_form/dynamicform","core/toast","core/str","core/pubsub","core/notification","core_reportbuilder/local/events","core_reportbuilder/local/selectors"],(function(_exports,_dynamicform,_toast,_str,_pubsub,_notification,reportEvents,reportSelectors){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireWildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}return newObj.default=obj,cache&&cache.set(obj,newObj),newObj}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_dynamicform=_interopRequireDefault(_dynamicform),_notification=_interopRequireDefault(_notification),reportEvents=_interopRequireWildcard(reportEvents),reportSelectors=_interopRequireWildcard(reportSelectors);let cardViewForm=null;_exports.init=initialized=>{(()=>{const cardViewFormContainer=document.querySelector(reportSelectors.regions.settingsCardView);cardViewFormContainer&&(cardViewForm=new _dynamicform.default(cardViewFormContainer,"\\core_reportbuilder\\form\\card_view"),cardViewForm.addEventListener(cardViewForm.events.FORM_SUBMITTED,(event=>{event.preventDefault(),(0,_str.getString)("cardviewsettingssaved","core_reportbuilder").then(_toast.add).catch(_notification.default.exception)})))})(),initialized||(0,_pubsub.subscribe)(reportEvents.publish.reportColumnsUpdated,(()=>{const reportElement=document.querySelector(reportSelectors.regions.report);cardViewForm.load({reportid:reportElement.dataset.reportId})}))}}));
//# sourceMappingURL=card_view.min.js.map
@@ -0,0 +1 @@
{"version":3,"file":"card_view.min.js","sources":["../../../src/local/editor/card_view.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 <http://www.gnu.org/licenses/>.\n\n/**\n * Report builder card view editor\n *\n * @module core_reportbuilder/local/editor/card_view\n * @copyright 2021 Mikel Martín <mikel@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n\"use strict\";\n\nimport DynamicForm from 'core_form/dynamicform';\nimport {add as addToast} from 'core/toast';\nimport {getString} from \"core/str\";\nimport {subscribe as subscribe} from 'core/pubsub';\nimport Notification from 'core/notification';\nimport * as reportEvents from 'core_reportbuilder/local/events';\nimport * as reportSelectors from 'core_reportbuilder/local/selectors';\n\nlet cardViewForm = null;\n\n/**\n * Initialise card view form, must be called on each init because the form container is re-created when switching editor modes\n */\nconst initCardViewForm = () => {\n const cardViewFormContainer = document.querySelector(reportSelectors.regions.settingsCardView);\n if (!cardViewFormContainer) {\n return;\n }\n cardViewForm = new DynamicForm(cardViewFormContainer, '\\\\core_reportbuilder\\\\form\\\\card_view');\n\n cardViewForm.addEventListener(cardViewForm.events.FORM_SUBMITTED, (event) => {\n event.preventDefault();\n\n getString('cardviewsettingssaved', 'core_reportbuilder')\n .then(addToast)\n .catch(Notification.exception);\n });\n};\n\n/**\n * Initialise module\n *\n * @param {Boolean} initialized Ensure we only add our listeners once\n */\nexport const init = (initialized) => {\n initCardViewForm();\n if (initialized) {\n return;\n }\n\n // Update form each time a column is added or removed to the custom report.\n subscribe(reportEvents.publish.reportColumnsUpdated, () => {\n const reportElement = document.querySelector(reportSelectors.regions.report);\n cardViewForm.load({reportid: reportElement.dataset.reportId});\n });\n};\n"],"names":["cardViewForm","initialized","cardViewFormContainer","document","querySelector","reportSelectors","regions","settingsCardView","DynamicForm","addEventListener","events","FORM_SUBMITTED","event","preventDefault","then","addToast","catch","Notification","exception","initCardViewForm","reportEvents","publish","reportColumnsUpdated","reportElement","report","load","reportid","dataset","reportId"],"mappings":"omDAiCIA,aAAe,mBA0BEC,cArBI,YACfC,sBAAwBC,SAASC,cAAcC,gBAAgBC,QAAQC,kBACxEL,wBAGLF,aAAe,IAAIQ,qBAAYN,sBAAuB,yCAEtDF,aAAaS,iBAAiBT,aAAaU,OAAOC,gBAAiBC,QAC/DA,MAAMC,oCAEI,wBAAyB,sBAC9BC,KAAKC,YACLC,MAAMC,sBAAaC,gBAU5BC,GACIlB,mCAKMmB,aAAaC,QAAQC,sBAAsB,WAC3CC,cAAgBpB,SAASC,cAAcC,gBAAgBC,QAAQkB,QACrExB,aAAayB,KAAK,CAACC,SAAUH,cAAcI,QAAQC"}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+3
View File
@@ -0,0 +1,3 @@
define("core_reportbuilder/local/events",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0;return _exports.default={tableReload:"core_reportbuilder_table_reload",publish:{reportColumnsUpdated:"core_reportbuilder_report_columns_updated"}},_exports.default}));
//# sourceMappingURL=events.min.js.map
@@ -0,0 +1 @@
{"version":3,"file":"events.min.js","sources":["../../src/local/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 <http://www.gnu.org/licenses/>.\n\n/**\n * Report builder events\n *\n * @module core_reportbuilder/local/events\n * @copyright 2021 Paul Holden <paulh@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n/**\n * Events for the Report builder subsystem\n *\n * @constant\n * @property {String} tableReload See {@link event:tableReload}\n */\nexport default {\n /**\n * Trigger table reloading\n *\n * @event tableReload\n * @type {CustomEvent}\n * @property {object} detail\n * @property {Boolean} detail.preservePagination Whether current pagination should be preserved (default false)\n * @property {String} detail.preserveTriggerElement Element selector that should be focused after table reload (default null)\n *\n * @example <caption>Triggering table reload</caption>\n * import {dispatchEvent} from 'core/event_dispatcher';\n * import * as reportEvents from 'core_reportbuilder/local/events';\n *\n * dispatchEvent(reportEvents.tableReload, {}, document.querySelector(...));\n */\n tableReload: 'core_reportbuilder_table_reload',\n publish: {\n reportColumnsUpdated: 'core_reportbuilder_report_columns_updated',\n },\n};\n"],"names":["tableReload","publish","reportColumnsUpdated"],"mappings":"iLA6Be,CAgBXA,YAAa,kCACbC,QAAS,CACLC,qBAAsB"}
@@ -0,0 +1,10 @@
define("core_reportbuilder/local/repository/audiences",["exports","core/ajax"],(function(_exports,_ajax){var obj;
/**
* Module to handle audiences AJAX requests
*
* @module core_reportbuilder/local/repository/audiences
* @copyright 2021 David Matamoros <davidmc@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.deleteAudience=void 0,_ajax=(obj=_ajax)&&obj.__esModule?obj:{default:obj};_exports.deleteAudience=(reportId,instanceId)=>{const request={methodname:"core_reportbuilder_audiences_delete",args:{reportid:reportId,instanceid:instanceId}};return _ajax.default.call([request])[0]}}));
//# sourceMappingURL=audiences.min.js.map
@@ -0,0 +1 @@
{"version":3,"file":"audiences.min.js","sources":["../../../src/local/repository/audiences.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 <http://www.gnu.org/licenses/>.\n\n/**\n * Module to handle audiences AJAX requests\n *\n * @module core_reportbuilder/local/repository/audiences\n * @copyright 2021 David Matamoros <davidmc@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Ajax from 'core/ajax';\n\n/**\n * Remove audience from given report\n *\n * @param {Number} reportId\n * @param {Number} instanceId\n * @return {Promise}\n */\nexport const deleteAudience = (reportId, instanceId) => {\n const request = {\n methodname: 'core_reportbuilder_audiences_delete',\n args: {reportid: reportId, instanceid: instanceId}\n };\n\n return Ajax.call([request])[0];\n};\n"],"names":["reportId","instanceId","request","methodname","args","reportid","instanceid","Ajax","call"],"mappings":";;;;;;;wKAgC8B,CAACA,SAAUC,oBAC/BC,QAAU,CACZC,WAAY,sCACZC,KAAM,CAACC,SAAUL,SAAUM,WAAYL,oBAGpCM,cAAKC,KAAK,CAACN,UAAU"}
+10
View File
@@ -0,0 +1,10 @@
define("core_reportbuilder/local/repository/columns",["exports","core/ajax"],(function(_exports,_ajax){var obj;
/**
* Module to handle column AJAX requests
*
* @module core_reportbuilder/local/repository/columns
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.reorderColumn=_exports.deleteColumn=_exports.addColumn=void 0,_ajax=(obj=_ajax)&&obj.__esModule?obj:{default:obj};_exports.addColumn=(reportId,uniqueIdentifier)=>{const request={methodname:"core_reportbuilder_columns_add",args:{reportid:reportId,uniqueidentifier:uniqueIdentifier}};return _ajax.default.call([request])[0]};_exports.deleteColumn=(reportId,columnId)=>{const request={methodname:"core_reportbuilder_columns_delete",args:{reportid:reportId,columnid:columnId}};return _ajax.default.call([request])[0]};_exports.reorderColumn=(reportId,columnId,position)=>{const request={methodname:"core_reportbuilder_columns_reorder",args:{reportid:reportId,columnid:columnId,position:position}};return _ajax.default.call([request])[0]}}));
//# sourceMappingURL=columns.min.js.map
@@ -0,0 +1 @@
{"version":3,"file":"columns.min.js","sources":["../../../src/local/repository/columns.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 <http://www.gnu.org/licenses/>.\n\n/**\n * Module to handle column AJAX requests\n *\n * @module core_reportbuilder/local/repository/columns\n * @copyright 2021 Paul Holden <paulh@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Ajax from 'core/ajax';\n\n/**\n * Add column to given report\n *\n * @param {Number} reportId\n * @param {String} uniqueIdentifier\n * @return {Promise}\n */\nexport const addColumn = (reportId, uniqueIdentifier) => {\n const request = {\n methodname: 'core_reportbuilder_columns_add',\n args: {reportid: reportId, uniqueidentifier: uniqueIdentifier}\n };\n\n return Ajax.call([request])[0];\n};\n\n/**\n * Remove column from given report\n *\n * @param {Number} reportId\n * @param {Number} columnId\n * @return {Promise}\n */\nexport const deleteColumn = (reportId, columnId) => {\n const request = {\n methodname: 'core_reportbuilder_columns_delete',\n args: {reportid: reportId, columnid: columnId}\n };\n\n return Ajax.call([request])[0];\n};\n\n/**\n * Re-order column within a report\n *\n * @param {Number} reportId\n * @param {Number} columnId\n * @param {Number} position\n * @return {Promise}\n */\nexport const reorderColumn = (reportId, columnId, position) => {\n const request = {\n methodname: 'core_reportbuilder_columns_reorder',\n args: {reportid: reportId, columnid: columnId, position: position}\n };\n\n return Ajax.call([request])[0];\n};\n"],"names":["reportId","uniqueIdentifier","request","methodname","args","reportid","uniqueidentifier","Ajax","call","columnId","columnid","position"],"mappings":";;;;;;;2MAgCyB,CAACA,SAAUC,0BAC1BC,QAAU,CACZC,WAAY,iCACZC,KAAM,CAACC,SAAUL,SAAUM,iBAAkBL,0BAG1CM,cAAKC,KAAK,CAACN,UAAU,0BAUJ,CAACF,SAAUS,kBAC7BP,QAAU,CACZC,WAAY,oCACZC,KAAM,CAACC,SAAUL,SAAUU,SAAUD,kBAGlCF,cAAKC,KAAK,CAACN,UAAU,2BAWH,CAACF,SAAUS,SAAUE,kBACxCT,QAAU,CACZC,WAAY,qCACZC,KAAM,CAACC,SAAUL,SAAUU,SAAUD,SAAUE,SAAUA,kBAGtDJ,cAAKC,KAAK,CAACN,UAAU"}
@@ -0,0 +1,10 @@
define("core_reportbuilder/local/repository/conditions",["exports","core/ajax"],(function(_exports,_ajax){var obj;
/**
* Module to handle condition AJAX requests
*
* @module core_reportbuilder/local/repository/conditions
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.resetConditions=_exports.reorderCondition=_exports.deleteCondition=_exports.addCondition=void 0,_ajax=(obj=_ajax)&&obj.__esModule?obj:{default:obj};_exports.resetConditions=reportId=>{const request={methodname:"core_reportbuilder_conditions_reset",args:{reportid:reportId}};return _ajax.default.call([request])[0]};_exports.addCondition=(reportId,uniqueIdentifier)=>{const request={methodname:"core_reportbuilder_conditions_add",args:{reportid:reportId,uniqueidentifier:uniqueIdentifier}};return _ajax.default.call([request])[0]};_exports.deleteCondition=(reportId,conditionId)=>{const request={methodname:"core_reportbuilder_conditions_delete",args:{reportid:reportId,conditionid:conditionId}};return _ajax.default.call([request])[0]};_exports.reorderCondition=(reportId,conditionId,position)=>{const request={methodname:"core_reportbuilder_conditions_reorder",args:{reportid:reportId,conditionid:conditionId,position:position}};return _ajax.default.call([request])[0]}}));
//# sourceMappingURL=conditions.min.js.map
@@ -0,0 +1 @@
{"version":3,"file":"conditions.min.js","sources":["../../../src/local/repository/conditions.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 <http://www.gnu.org/licenses/>.\n\n/**\n * Module to handle condition AJAX requests\n *\n * @module core_reportbuilder/local/repository/conditions\n * @copyright 2021 Paul Holden <paulh@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Ajax from 'core/ajax';\n\n/**\n * Reset all conditions for given report\n *\n * @param {Number} reportId\n * @return {Promise}\n */\nexport const resetConditions = reportId => {\n const request = {\n methodname: 'core_reportbuilder_conditions_reset',\n args: {reportid: reportId}\n };\n\n return Ajax.call([request])[0];\n};\n\n/**\n * Add condition to given report\n *\n * @param {Number} reportId\n * @param {String} uniqueIdentifier\n * @return {Promise}\n */\nexport const addCondition = (reportId, uniqueIdentifier) => {\n const request = {\n methodname: 'core_reportbuilder_conditions_add',\n args: {reportid: reportId, uniqueidentifier: uniqueIdentifier}\n };\n\n return Ajax.call([request])[0];\n};\n\n/**\n * Remove condition from given report\n *\n * @param {Number} reportId\n * @param {Number} conditionId\n * @return {Promise}\n */\nexport const deleteCondition = (reportId, conditionId) => {\n const request = {\n methodname: 'core_reportbuilder_conditions_delete',\n args: {reportid: reportId, conditionid: conditionId}\n };\n\n return Ajax.call([request])[0];\n};\n\n/**\n * Reorder a condition in a given report\n *\n * @param {Number} reportId\n * @param {Number} conditionId\n * @param {Number} position\n * @return {Promise}\n */\nexport const reorderCondition = (reportId, conditionId, position) => {\n const request = {\n methodname: 'core_reportbuilder_conditions_reorder',\n args: {reportid: reportId, conditionid: conditionId, position: position}\n };\n\n return Ajax.call([request])[0];\n};\n"],"names":["reportId","request","methodname","args","reportid","Ajax","call","uniqueIdentifier","uniqueidentifier","conditionId","conditionid","position"],"mappings":";;;;;;;mPA+B+BA,iBACrBC,QAAU,CACZC,WAAY,sCACZC,KAAM,CAACC,SAAUJ,kBAGdK,cAAKC,KAAK,CAACL,UAAU,0BAUJ,CAACD,SAAUO,0BAC7BN,QAAU,CACZC,WAAY,oCACZC,KAAM,CAACC,SAAUJ,SAAUQ,iBAAkBD,0BAG1CF,cAAKC,KAAK,CAACL,UAAU,6BAUD,CAACD,SAAUS,qBAChCR,QAAU,CACZC,WAAY,uCACZC,KAAM,CAACC,SAAUJ,SAAUU,YAAaD,qBAGrCJ,cAAKC,KAAK,CAACL,UAAU,8BAWA,CAACD,SAAUS,YAAaE,kBAC9CV,QAAU,CACZC,WAAY,wCACZC,KAAM,CAACC,SAAUJ,SAAUU,YAAaD,YAAaE,SAAUA,kBAG5DN,cAAKC,KAAK,CAACL,UAAU"}
+10
View File
@@ -0,0 +1,10 @@
define("core_reportbuilder/local/repository/filters",["exports","core/ajax"],(function(_exports,_ajax){var obj;
/**
* Module to handle filter AJAX requests
*
* @module core_reportbuilder/local/repository/filters
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.setFilters=_exports.resetFilters=_exports.reorderFilter=_exports.deleteFilter=_exports.addFilter=void 0,_ajax=(obj=_ajax)&&obj.__esModule?obj:{default:obj};_exports.resetFilters=(reportId,reportParameters)=>{const request={methodname:"core_reportbuilder_filters_reset",args:{reportid:reportId,parameters:reportParameters}};return _ajax.default.call([request])[0]};_exports.setFilters=(reportId,reportParameters,filterValues)=>{const request={methodname:"core_reportbuilder_set_filters",args:{reportid:reportId,parameters:reportParameters,values:filterValues}};return _ajax.default.call([request])[0]};_exports.addFilter=(reportId,uniqueIdentifier)=>{const request={methodname:"core_reportbuilder_filters_add",args:{reportid:reportId,uniqueidentifier:uniqueIdentifier}};return _ajax.default.call([request])[0]};_exports.deleteFilter=(reportId,filterId)=>{const request={methodname:"core_reportbuilder_filters_delete",args:{reportid:reportId,filterid:filterId}};return _ajax.default.call([request])[0]};_exports.reorderFilter=(reportId,filterId,position)=>{const request={methodname:"core_reportbuilder_filters_reorder",args:{reportid:reportId,filterid:filterId,position:position}};return _ajax.default.call([request])[0]}}));
//# sourceMappingURL=filters.min.js.map
@@ -0,0 +1 @@
{"version":3,"file":"filters.min.js","sources":["../../../src/local/repository/filters.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 <http://www.gnu.org/licenses/>.\n\n/**\n * Module to handle filter AJAX requests\n *\n * @module core_reportbuilder/local/repository/filters\n * @copyright 2021 Paul Holden <paulh@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Ajax from 'core/ajax';\n\n/**\n * Reset all filters for given report\n *\n * @method\n * @param {Number} reportId\n * @param {String} reportParameters\n * @return {Promise}\n */\nexport const resetFilters = (reportId, reportParameters) => {\n const request = {\n methodname: 'core_reportbuilder_filters_reset',\n args: {reportid: reportId, parameters: reportParameters}\n };\n\n return Ajax.call([request])[0];\n};\n\n/**\n * Set filter values for given report\n *\n * @method\n * @param {Number} reportId\n * @param {String} reportParameters\n * @param {String} filterValues\n * @return {Promise}\n */\nexport const setFilters = (reportId, reportParameters, filterValues) => {\n const request = {\n methodname: 'core_reportbuilder_set_filters',\n args: {reportid: reportId, parameters: reportParameters, values: filterValues}\n };\n\n return Ajax.call([request])[0];\n};\n\n/**\n * Add a filter to the given report\n *\n * @param {Number} reportId\n * @param {String} uniqueIdentifier\n * @return {Promise}\n */\nexport const addFilter = (reportId, uniqueIdentifier) => {\n const request = {\n methodname: 'core_reportbuilder_filters_add',\n args: {reportid: reportId, uniqueidentifier: uniqueIdentifier}\n };\n\n return Ajax.call([request])[0];\n};\n\n/**\n * Remove filter from given report\n *\n * @param {Number} reportId\n * @param {Number} filterId\n * @return {Promise}\n */\nexport const deleteFilter = (reportId, filterId) => {\n const request = {\n methodname: 'core_reportbuilder_filters_delete',\n args: {reportid: reportId, filterid: filterId}\n };\n\n return Ajax.call([request])[0];\n};\n\n/**\n * Reorder a filter in a given report\n *\n * @param {Number} reportId\n * @param {Number} filterId\n * @param {Number} position\n * @return {Promise}\n */\nexport const reorderFilter = (reportId, filterId, position) => {\n const request = {\n methodname: 'core_reportbuilder_filters_reorder',\n args: {reportid: reportId, filterid: filterId, position: position}\n };\n\n return Ajax.call([request])[0];\n};\n"],"names":["reportId","reportParameters","request","methodname","args","reportid","parameters","Ajax","call","filterValues","values","uniqueIdentifier","uniqueidentifier","filterId","filterid","position"],"mappings":";;;;;;;wPAiC4B,CAACA,SAAUC,0BAC7BC,QAAU,CACZC,WAAY,mCACZC,KAAM,CAACC,SAAUL,SAAUM,WAAYL,0BAGpCM,cAAKC,KAAK,CAACN,UAAU,wBAYN,CAACF,SAAUC,iBAAkBQ,sBAC7CP,QAAU,CACZC,WAAY,iCACZC,KAAM,CAACC,SAAUL,SAAUM,WAAYL,iBAAkBS,OAAQD,sBAG9DF,cAAKC,KAAK,CAACN,UAAU,uBAUP,CAACF,SAAUW,0BAC1BT,QAAU,CACZC,WAAY,iCACZC,KAAM,CAACC,SAAUL,SAAUY,iBAAkBD,0BAG1CJ,cAAKC,KAAK,CAACN,UAAU,0BAUJ,CAACF,SAAUa,kBAC7BX,QAAU,CACZC,WAAY,oCACZC,KAAM,CAACC,SAAUL,SAAUc,SAAUD,kBAGlCN,cAAKC,KAAK,CAACN,UAAU,2BAWH,CAACF,SAAUa,SAAUE,kBACxCb,QAAU,CACZC,WAAY,qCACZC,KAAM,CAACC,SAAUL,SAAUc,SAAUD,SAAUE,SAAUA,kBAGtDR,cAAKC,KAAK,CAACN,UAAU"}
+10
View File
@@ -0,0 +1,10 @@
define("core_reportbuilder/local/repository/modals",["exports","core_form/modalform","core/str"],(function(_exports,_modalform,_str){var obj;
/**
* Module to handle modal form requests
*
* @module core_reportbuilder/local/repository/modals
* @copyright 2021 David Matamoros <davidmc@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.createScheduleModal=_exports.createReportModal=void 0,_modalform=(obj=_modalform)&&obj.__esModule?obj:{default:obj};const createModalForm=(triggerElement,modalTitle,formClass,formArgs)=>new _modalform.default({modalConfig:{title:modalTitle},formClass:formClass,args:formArgs,saveButtonText:(0,_str.getString)("save","moodle"),returnFocus:triggerElement});_exports.createReportModal=function(triggerElement,modalTitle){let reportId=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;return createModalForm(triggerElement,modalTitle,"core_reportbuilder\\form\\report",{id:reportId})};_exports.createScheduleModal=function(triggerElement,modalTitle,reportId){let scheduleId=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0;return createModalForm(triggerElement,modalTitle,"core_reportbuilder\\form\\schedule",{reportid:reportId,id:scheduleId})}}));
//# sourceMappingURL=modals.min.js.map
@@ -0,0 +1 @@
{"version":3,"file":"modals.min.js","sources":["../../../src/local/repository/modals.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 <http://www.gnu.org/licenses/>.\n\n/**\n * Module to handle modal form requests\n *\n * @module core_reportbuilder/local/repository/modals\n * @copyright 2021 David Matamoros <davidmc@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport ModalForm from 'core_form/modalform';\nimport {getString} from 'core/str';\n\n/**\n * Return modal instance\n *\n * @param {EventTarget} triggerElement\n * @param {Promise} modalTitle\n * @param {String} formClass\n * @param {Object} formArgs\n * @return {ModalForm}\n */\nconst createModalForm = (triggerElement, modalTitle, formClass, formArgs) => {\n return new ModalForm({\n modalConfig: {\n title: modalTitle,\n },\n formClass: formClass,\n args: formArgs,\n saveButtonText: getString('save', 'moodle'),\n returnFocus: triggerElement,\n });\n};\n\n/**\n * Return report modal instance\n *\n * @param {EventTarget} triggerElement\n * @param {Promise} modalTitle\n * @param {Number} reportId\n * @return {ModalForm}\n */\nexport const createReportModal = (triggerElement, modalTitle, reportId = 0) => {\n return createModalForm(triggerElement, modalTitle, 'core_reportbuilder\\\\form\\\\report', {\n id: reportId,\n });\n};\n\n/**\n * Return schedule modal instance\n *\n * @param {EventTarget} triggerElement\n * @param {Promise} modalTitle\n * @param {Number} reportId\n * @param {Number} scheduleId\n * @return {ModalForm}\n */\nexport const createScheduleModal = (triggerElement, modalTitle, reportId, scheduleId = 0) => {\n return createModalForm(triggerElement, modalTitle, 'core_reportbuilder\\\\form\\\\schedule', {\n reportid: reportId,\n id: scheduleId,\n });\n};\n"],"names":["createModalForm","triggerElement","modalTitle","formClass","formArgs","ModalForm","modalConfig","title","args","saveButtonText","returnFocus","reportId","id","scheduleId","reportid"],"mappings":";;;;;;;gMAmCMA,gBAAkB,CAACC,eAAgBC,WAAYC,UAAWC,WACrD,IAAIC,mBAAU,CACjBC,YAAa,CACTC,MAAOL,YAEXC,UAAWA,UACXK,KAAMJ,SACNK,gBAAgB,kBAAU,OAAQ,UAClCC,YAAaT,4CAYY,SAACA,eAAgBC,gBAAYS,gEAAW,SAC9DX,gBAAgBC,eAAgBC,WAAY,mCAAoC,CACnFU,GAAID,yCAauB,SAACV,eAAgBC,WAAYS,cAAUE,kEAAa,SAC5Eb,gBAAgBC,eAAgBC,WAAY,qCAAsC,CACrFY,SAAUH,SACVC,GAAIC"}
+10
View File
@@ -0,0 +1,10 @@
define("core_reportbuilder/local/repository/reports",["exports","core/ajax"],(function(_exports,_ajax){var obj;
/**
* Module to handle report AJAX requests
*
* @module core_reportbuilder/local/repository/reports
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.getReport=_exports.deleteReport=void 0,_ajax=(obj=_ajax)&&obj.__esModule?obj:{default:obj};_exports.deleteReport=reportId=>{const request={methodname:"core_reportbuilder_reports_delete",args:{reportid:reportId}};return _ajax.default.call([request])[0]};_exports.getReport=function(reportId,editMode){let pageSize=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;const request={methodname:"core_reportbuilder_reports_get",args:{reportid:reportId,editmode:editMode,pagesize:pageSize}};return _ajax.default.call([request])[0]}}));
//# sourceMappingURL=reports.min.js.map
@@ -0,0 +1 @@
{"version":3,"file":"reports.min.js","sources":["../../../src/local/repository/reports.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 <http://www.gnu.org/licenses/>.\n\n/**\n * Module to handle report AJAX requests\n *\n * @module core_reportbuilder/local/repository/reports\n * @copyright 2021 Paul Holden <paulh@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Ajax from 'core/ajax';\n\n/**\n * Delete given report\n *\n * @param {Number} reportId\n * @return {Promise}\n */\nexport const deleteReport = reportId => {\n const request = {\n methodname: 'core_reportbuilder_reports_delete',\n args: {reportid: reportId}\n };\n\n return Ajax.call([request])[0];\n};\n\n/**\n * Get report content\n *\n * @param {Number} reportId\n * @param {Boolean} editMode\n * @param {Number} [pageSize=0]\n * @return {Promise}\n */\nexport const getReport = (reportId, editMode, pageSize = 0) => {\n const request = {\n methodname: 'core_reportbuilder_reports_get',\n args: {reportid: reportId, editmode: editMode, pagesize: pageSize}\n };\n\n return Ajax.call([request])[0];\n};\n"],"names":["reportId","request","methodname","args","reportid","Ajax","call","editMode","pageSize","editmode","pagesize"],"mappings":";;;;;;;uLA+B4BA,iBAClBC,QAAU,CACZC,WAAY,oCACZC,KAAM,CAACC,SAAUJ,kBAGdK,cAAKC,KAAK,CAACL,UAAU,uBAWP,SAACD,SAAUO,cAAUC,gEAAW,QAC/CP,QAAU,CACZC,WAAY,iCACZC,KAAM,CAACC,SAAUJ,SAAUS,SAAUF,SAAUG,SAAUF,kBAGtDH,cAAKC,KAAK,CAACL,UAAU"}
@@ -0,0 +1,10 @@
define("core_reportbuilder/local/repository/schedules",["exports","core/ajax"],(function(_exports,_ajax){var obj;
/**
* Module to handle schedule AJAX requests
*
* @module core_reportbuilder/local/repository/schedules
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.toggleSchedule=_exports.sendSchedule=_exports.deleteSchedule=void 0,_ajax=(obj=_ajax)&&obj.__esModule?obj:{default:obj};_exports.deleteSchedule=(reportId,scheduleId)=>{const request={methodname:"core_reportbuilder_schedules_delete",args:{reportid:reportId,scheduleid:scheduleId}};return _ajax.default.call([request])[0]};_exports.sendSchedule=(reportId,scheduleId)=>{const request={methodname:"core_reportbuilder_schedules_send",args:{reportid:reportId,scheduleid:scheduleId}};return _ajax.default.call([request])[0]};_exports.toggleSchedule=(reportId,scheduleId,scheduleEnabled)=>{const request={methodname:"core_reportbuilder_schedules_toggle",args:{reportid:reportId,scheduleid:scheduleId,enabled:scheduleEnabled}};return _ajax.default.call([request])[0]}}));
//# sourceMappingURL=schedules.min.js.map
@@ -0,0 +1 @@
{"version":3,"file":"schedules.min.js","sources":["../../../src/local/repository/schedules.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 <http://www.gnu.org/licenses/>.\n\n/**\n * Module to handle schedule AJAX requests\n *\n * @module core_reportbuilder/local/repository/schedules\n * @copyright 2021 Paul Holden <paulh@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Ajax from 'core/ajax';\n\n/**\n * Delete schedule\n *\n * @method\n * @param {Number} reportId\n * @param {Number} scheduleId\n * @return {Promise}\n */\nexport const deleteSchedule = (reportId, scheduleId) => {\n const request = {\n methodname: 'core_reportbuilder_schedules_delete',\n args: {reportid: reportId, scheduleid: scheduleId}\n };\n\n return Ajax.call([request])[0];\n};\n\n/**\n * Send schedule\n *\n * @method\n * @param {Number} reportId\n * @param {Number} scheduleId\n * @return {Promise}\n */\nexport const sendSchedule = (reportId, scheduleId) => {\n const request = {\n methodname: 'core_reportbuilder_schedules_send',\n args: {reportid: reportId, scheduleid: scheduleId}\n };\n\n return Ajax.call([request])[0];\n};\n\n/**\n * Toggle schedule enabled\n *\n * @method\n * @param {Number} reportId\n * @param {Number} scheduleId\n * @param {Boolean} scheduleEnabled\n * @return {Promise}\n */\nexport const toggleSchedule = (reportId, scheduleId, scheduleEnabled) => {\n const request = {\n methodname: 'core_reportbuilder_schedules_toggle',\n args: {reportid: reportId, scheduleid: scheduleId, enabled: scheduleEnabled}\n };\n\n return Ajax.call([request])[0];\n};\n"],"names":["reportId","scheduleId","request","methodname","args","reportid","scheduleid","Ajax","call","scheduleEnabled","enabled"],"mappings":";;;;;;;sNAiC8B,CAACA,SAAUC,oBAC/BC,QAAU,CACZC,WAAY,sCACZC,KAAM,CAACC,SAAUL,SAAUM,WAAYL,oBAGpCM,cAAKC,KAAK,CAACN,UAAU,0BAWJ,CAACF,SAAUC,oBAC7BC,QAAU,CACZC,WAAY,oCACZC,KAAM,CAACC,SAAUL,SAAUM,WAAYL,oBAGpCM,cAAKC,KAAK,CAACN,UAAU,4BAYF,CAACF,SAAUC,WAAYQ,yBAC3CP,QAAU,CACZC,WAAY,sCACZC,KAAM,CAACC,SAAUL,SAAUM,WAAYL,WAAYS,QAASD,yBAGzDF,cAAKC,KAAK,CAACN,UAAU"}
+10
View File
@@ -0,0 +1,10 @@
define("core_reportbuilder/local/repository/sorting",["exports","core/ajax"],(function(_exports,_ajax){var obj;
/**
* Module to handle column sorting AJAX requests
*
* @module core_reportbuilder/local/repository/sorting
* @copyright 2021 David Matamoros <davidmc@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.toggleColumnSorting=_exports.reorderColumnSorting=_exports.getColumnSorting=void 0,_ajax=(obj=_ajax)&&obj.__esModule?obj:{default:obj};_exports.getColumnSorting=reportId=>{const request={methodname:"core_reportbuilder_columns_sort_get",args:{reportid:reportId}};return _ajax.default.call([request])[0]};_exports.reorderColumnSorting=(reportId,columnId,position)=>{const request={methodname:"core_reportbuilder_columns_sort_reorder",args:{reportid:reportId,columnid:columnId,position:position}};return _ajax.default.call([request])[0]};_exports.toggleColumnSorting=(reportId,columnId,enabled,direction)=>{const request={methodname:"core_reportbuilder_columns_sort_toggle",args:{reportid:reportId,columnid:columnId,enabled:enabled,direction:direction}};return _ajax.default.call([request])[0]}}));
//# sourceMappingURL=sorting.min.js.map
@@ -0,0 +1 @@
{"version":3,"file":"sorting.min.js","sources":["../../../src/local/repository/sorting.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 <http://www.gnu.org/licenses/>.\n\n/**\n * Module to handle column sorting AJAX requests\n *\n * @module core_reportbuilder/local/repository/sorting\n * @copyright 2021 David Matamoros <davidmc@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Ajax from 'core/ajax';\n\n/**\n * Retrieve column sorting\n *\n * @param {Number} reportId\n * @return {Promise}\n */\nexport const getColumnSorting = reportId => {\n const request = {\n methodname: 'core_reportbuilder_columns_sort_get',\n args: {reportid: reportId}\n };\n\n return Ajax.call([request])[0];\n};\n\n/**\n * Re-order sort column position\n *\n * @param {Number} reportId\n * @param {Number} columnId\n * @param {Number} position\n * @return {Promise}\n */\nexport const reorderColumnSorting = (reportId, columnId, position) => {\n const request = {\n methodname: 'core_reportbuilder_columns_sort_reorder',\n args: {reportid: reportId, columnid: columnId, position: position}\n };\n\n return Ajax.call([request])[0];\n};\n\n/**\n * Enables/disabled sorting on column\n *\n * @param {Number} reportId\n * @param {Number} columnId\n * @param {Boolean} enabled\n * @param {Number} direction\n * @return {Promise}\n */\nexport const toggleColumnSorting = (reportId, columnId, enabled, direction) => {\n const request = {\n methodname: 'core_reportbuilder_columns_sort_toggle',\n args: {reportid: reportId, columnid: columnId, enabled: enabled, direction: direction}\n };\n\n return Ajax.call([request])[0];\n};\n"],"names":["reportId","request","methodname","args","reportid","Ajax","call","columnId","position","columnid","enabled","direction"],"mappings":";;;;;;;uOA+BgCA,iBACtBC,QAAU,CACZC,WAAY,sCACZC,KAAM,CAACC,SAAUJ,kBAGdK,cAAKC,KAAK,CAACL,UAAU,kCAWI,CAACD,SAAUO,SAAUC,kBAC/CP,QAAU,CACZC,WAAY,0CACZC,KAAM,CAACC,SAAUJ,SAAUS,SAAUF,SAAUC,SAAUA,kBAGtDH,cAAKC,KAAK,CAACL,UAAU,iCAYG,CAACD,SAAUO,SAAUG,QAASC,mBACvDV,QAAU,CACZC,WAAY,yCACZC,KAAM,CAACC,SAAUJ,SAAUS,SAAUF,SAAUG,QAASA,QAASC,UAAWA,mBAGzEN,cAAKC,KAAK,CAACL,UAAU"}
+11
View File
@@ -0,0 +1,11 @@
define("core_reportbuilder/local/selectors",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0;
/**
* Report builder selectors
*
* @module core_reportbuilder/local/selectors
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @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"]',sidebarItem:'[data-region="sidebar-item"]',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
File diff suppressed because one or more lines are too long
+10
View File
@@ -0,0 +1,10 @@
define("core_reportbuilder/report",["exports","core/notification","core_reportbuilder/local/events","core_reportbuilder/local/selectors","core_table/dynamic","core_table/local/dynamic/selectors"],(function(_exports,_notification,reportEvents,reportSelectors,_dynamic,tableSelectors){var obj;
/**
* Report builder report management
*
* @module core_reportbuilder/report
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireWildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}return newObj.default=obj,cache&&cache.set(obj,newObj),newObj}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_notification=(obj=_notification)&&obj.__esModule?obj:{default:obj},reportEvents=_interopRequireWildcard(reportEvents),reportSelectors=_interopRequireWildcard(reportSelectors),tableSelectors=_interopRequireWildcard(tableSelectors);const CLASSES_COLLAPSED="collapsed",CLASSES_EXPANDED="show",CLASSES_ICONUP="fa-angle-up",CLASSES_ICONDOWN="fa-angle-down";let initialized=!1;_exports.init=()=>{initialized||(document.addEventListener(reportEvents.tableReload,(async event=>{var _event$detail;const reportElement=event.target.closest(reportSelectors.regions.report);if(null===reportElement)return;const tableRoot=reportElement.querySelector(tableSelectors.main.region),pageNumber=null!==(_event$detail=event.detail)&&void 0!==_event$detail&&_event$detail.preservePagination?null:1;await(0,_dynamic.setPageNumber)(tableRoot,pageNumber,!1).then(_dynamic.refreshTableContent).then((()=>{var _event$detail2;const preserveTriggerElement=null===(_event$detail2=event.detail)||void 0===_event$detail2?void 0:_event$detail2.preserveTriggerElement;var _reportElement$queryS;preserveTriggerElement&&(null===(_reportElement$queryS=reportElement.querySelector(preserveTriggerElement))||void 0===_reportElement$queryS||_reportElement$queryS.focus())})).catch(_notification.default.exception)})),document.addEventListener("click",(event=>{const reportActionPopup=event.target.closest(reportSelectors.actions.reportActionPopup);if(null===reportActionPopup)return;event.preventDefault();const popupAction=JSON.parse(reportActionPopup.dataset.popupAction);window.openpopup(event,popupAction.jsfunctionargs)})),document.addEventListener("click",(event=>{const toggleCard=event.target.closest(reportSelectors.actions.toggleCardView);if(toggleCard){const tableCard=toggleCard.closest("tr"),toggleIcon=toggleCard.querySelector("i");event.preventDefault(),toggleCard.classList.contains(CLASSES_COLLAPSED)?(tableCard.classList.add(CLASSES_EXPANDED),toggleIcon.classList.replace(CLASSES_ICONDOWN,CLASSES_ICONUP),toggleCard.classList.remove(CLASSES_COLLAPSED),toggleCard.setAttribute("aria-expanded","true")):(tableCard.classList.remove(CLASSES_EXPANDED),toggleIcon.classList.replace(CLASSES_ICONUP,CLASSES_ICONDOWN),toggleCard.classList.add(CLASSES_COLLAPSED),toggleCard.removeAttribute("aria-expanded"))}})),initialized=!0)}}));
//# sourceMappingURL=report.min.js.map
File diff suppressed because one or more lines are too long
+3
View File
@@ -0,0 +1,3 @@
define("core_reportbuilder/reports_list",["exports","core/event_dispatcher","core/notification","core/pending","core/prefetch","core/str","core/toast","core_reportbuilder/local/events","core_reportbuilder/local/selectors","core_reportbuilder/local/repository/reports","core_reportbuilder/local/repository/modals"],(function(_exports,_event_dispatcher,_notification,_pending,_prefetch,_str,_toast,reportEvents,reportSelectors,_reports,_modals){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireWildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}return newObj.default=obj,cache&&cache.set(obj,newObj),newObj}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_notification=_interopRequireDefault(_notification),_pending=_interopRequireDefault(_pending),reportEvents=_interopRequireWildcard(reportEvents),reportSelectors=_interopRequireWildcard(reportSelectors);_exports.init=()=>{(0,_prefetch.prefetchStrings)("core_reportbuilder",["deletereport","deletereportconfirm","editreportdetails","newreport","reportdeleted","reportupdated"]),(0,_prefetch.prefetchStrings)("core",["delete"]),document.addEventListener("click",(event=>{if(event.target.closest(reportSelectors.actions.reportCreate)){event.preventDefault();const reportModal=(0,_modals.createReportModal)(event.target,(0,_str.getString)("newreport","core_reportbuilder"));reportModal.addEventListener(reportModal.events.FORM_SUBMITTED,(event=>{window.location.href=event.detail})),reportModal.show()}const reportEdit=event.target.closest(reportSelectors.actions.reportEdit);if(reportEdit){event.preventDefault();const triggerElement=reportEdit.closest(".dropdown").querySelector(".dropdown-toggle"),reportModal=(0,_modals.createReportModal)(triggerElement,(0,_str.getString)("editreportdetails","core_reportbuilder"),reportEdit.dataset.reportId);reportModal.addEventListener(reportModal.events.FORM_SUBMITTED,(()=>{const reportElement=event.target.closest(reportSelectors.regions.report);(0,_str.getString)("reportupdated","core_reportbuilder").then(_toast.add).then((()=>{(0,_event_dispatcher.dispatchEvent)(reportEvents.tableReload,{preservePagination:!0},reportElement)})).catch(_notification.default.exception)})),reportModal.show()}const reportDelete=event.target.closest(reportSelectors.actions.reportDelete);if(reportDelete){event.preventDefault();const triggerElement=reportDelete.closest(".dropdown").querySelector(".dropdown-toggle");_notification.default.saveCancelPromise((0,_str.getString)("deletereport","core_reportbuilder"),(0,_str.getString)("deletereportconfirm","core_reportbuilder",reportDelete.dataset.reportName),(0,_str.getString)("delete","core"),{triggerElement:triggerElement}).then((()=>{const pendingPromise=new _pending.default("core_reportbuilder/reports:delete"),reportElement=event.target.closest(reportSelectors.regions.report);return(0,_reports.deleteReport)(reportDelete.dataset.reportId).then((()=>(0,_toast.add)((0,_str.getString)("reportdeleted","core_reportbuilder")))).then((()=>((0,_event_dispatcher.dispatchEvent)(reportEvents.tableReload,{preservePagination:!0},reportElement),pendingPromise.resolve()))).catch(_notification.default.exception)})).catch((()=>{}))}}))}}));
//# sourceMappingURL=reports_list.min.js.map
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+10
View File
@@ -0,0 +1,10 @@
define("core_reportbuilder/sidebar",["exports","core/pending","core/utils","core_reportbuilder/local/selectors"],(function(_exports,_pending,_utils,reportSelectors){var obj;
/**
* Report builder sidebar component
*
* @module core_reportbuilder/sidebar
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/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)}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_pending=(obj=_pending)&&obj.__esModule?obj:{default:obj},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);const CLASSES_EXPANDED="show",CLASSES_COLLAPSED="collapsed",CLASSES_HIDE="d-none",sidebarCardFilter=(event,sidebarMenu)=>{const pendingPromise=new _pending.default("core_reportbuilder/sidebar:cardFilter"),sidebarCards=sidebarMenu.querySelectorAll(reportSelectors.regions.sidebarCard),sidebarItems=sidebarMenu.querySelectorAll(reportSelectors.regions.sidebarItem),searchTerm=event.target.value.toLowerCase();sidebarItems.forEach((item=>{const itemContent=item.textContent.toLowerCase();item.classList.toggle(CLASSES_HIDE,!itemContent.includes(searchTerm))})),sidebarCards.forEach((card=>{const visibleItems=card.querySelectorAll("".concat(reportSelectors.regions.sidebarItem,":not(.").concat(CLASSES_HIDE,")"));card.classList.toggle(CLASSES_HIDE,!visibleItems.length),expandCard(card)})),pendingPromise.resolve()},expandCard=card=>{let cardButton=card.querySelector('[data-toggle="collapse"]');if(cardButton.classList.contains(CLASSES_COLLAPSED)){cardButton.classList.remove(CLASSES_COLLAPSED),cardButton.setAttribute("aria-expanded","true"),card.querySelector(cardButton.dataset.target).classList.add(CLASSES_EXPANDED)}};_exports.init=selectorId=>{const sidebarMenu=document.querySelector(selectorId+reportSelectors.regions.sidebarMenu),sidebarSearch=sidebarMenu.querySelector(reportSelectors.actions.sidebarSearch),sidebarSearchDebounce=(0,_utils.debounce)(sidebarCardFilter,250);sidebarSearch.addEventListener("keyup",(event=>{const pendingPromise=new _pending.default("core_reportbuilder/sidebar:keyup");sidebarSearchDebounce(event,sidebarMenu),setTimeout((()=>{pendingPromise.resolve()}),250)}))}}));
//# sourceMappingURL=sidebar.min.js.map
File diff suppressed because one or more lines are too long
+268
View File
@@ -0,0 +1,268 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Report builder audiences
*
* @module core_reportbuilder/audience
* @copyright 2021 David Matamoros <davidmc@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
"use strict";
import 'core/inplace_editable';
import Templates from 'core/templates';
import Notification from 'core/notification';
import Pending from 'core/pending';
import {prefetchStrings} from 'core/prefetch';
import {getString} from 'core/str';
import DynamicForm from 'core_form/dynamicform';
import {add as addToast} from 'core/toast';
import {deleteAudience} from 'core_reportbuilder/local/repository/audiences';
import * as reportSelectors from 'core_reportbuilder/local/selectors';
import {loadFragment} from 'core/fragment';
import {markFormAsDirty} from 'core_form/changechecker';
let reportId = 0;
let contextId = 0;
/**
* Add audience card
*
* @param {String} className
* @param {String} title
*/
const addAudienceCard = (className, title) => {
const pendingPromise = new Pending('core_reportbuilder/audience:add');
const audiencesContainer = document.querySelector(reportSelectors.regions.audiencesContainer);
const audienceCardLength = audiencesContainer.querySelectorAll(reportSelectors.regions.audienceCard).length;
const params = {
classname: className,
reportid: reportId,
showormessage: (audienceCardLength > 0),
title: title,
};
// Load audience card fragment, render and then initialise the form within.
loadFragment('core_reportbuilder', 'audience_form', contextId, params)
.then((html, js) => {
const audienceCard = Templates.appendNodeContents(audiencesContainer, html, js)[0];
const audienceEmptyMessage = audiencesContainer.querySelector(reportSelectors.regions.audienceEmptyMessage);
const audienceForm = initAudienceCardForm(audienceCard);
// Mark as dirty new audience form created to prevent users leaving the page without saving it.
markFormAsDirty(audienceForm.getFormNode());
audienceEmptyMessage.classList.add('hidden');
return getString('audienceadded', 'core_reportbuilder', title);
})
.then(addToast)
.then(() => pendingPromise.resolve())
.catch(Notification.exception);
};
/**
* Edit audience card
*
* @param {Element} audienceCard
*/
const editAudienceCard = audienceCard => {
const pendingPromise = new Pending('core_reportbuilder/audience:edit');
// Load audience form with data for editing, then toggle visible controls in the card.
const audienceForm = initAudienceCardForm(audienceCard);
audienceForm.load({id: audienceCard.dataset.audienceId})
.then(() => {
const audienceFormContainer = audienceCard.querySelector(reportSelectors.regions.audienceFormContainer);
const audienceDescription = audienceCard.querySelector(reportSelectors.regions.audienceDescription);
const audienceEdit = audienceCard.querySelector(reportSelectors.actions.audienceEdit);
audienceFormContainer.classList.remove('hidden');
audienceDescription.classList.add('hidden');
audienceEdit.disabled = true;
return pendingPromise.resolve();
})
.catch(Notification.exception);
};
/**
* Initialise dynamic form within given audience card
*
* @param {Element} audienceCard
* @return {DynamicForm}
*/
const initAudienceCardForm = audienceCard => {
const audienceFormContainer = audienceCard.querySelector(reportSelectors.regions.audienceFormContainer);
const audienceForm = new DynamicForm(audienceFormContainer, '\\core_reportbuilder\\form\\audience');
// 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.audienceId = data.detail.instanceid;
audienceHeading.innerHTML = data.detail.heading;
audienceDescription.innerHTML = data.detail.description;
closeAudienceCardForm(audienceCard);
return getString('audiencesaved', 'core_reportbuilder')
.then(addToast);
});
// If cancelling the form, close the card or remove it if it was never created.
audienceForm.addEventListener(audienceForm.events.FORM_CANCELLED, () => {
if (audienceCard.dataset.audienceId > 0) {
closeAudienceCardForm(audienceCard);
} else {
removeAudienceCard(audienceCard);
}
});
return audienceForm;
};
/**
* Delete audience card
*
* @param {Element} audienceDelete
*/
const deleteAudienceCard = audienceDelete => {
const audienceCard = audienceDelete.closest(reportSelectors.regions.audienceCard);
const {audienceId, audienceTitle, audienceEditWarning = false} = audienceCard.dataset;
// The edit warning indicates the audience is in use in a report schedule.
const audienceDeleteConfirmation = audienceEditWarning ? 'audienceusedbyschedule' : 'deleteaudienceconfirm';
Notification.saveCancelPromise(
getString('deleteaudience', 'core_reportbuilder', audienceTitle),
getString(audienceDeleteConfirmation, 'core_reportbuilder', audienceTitle),
getString('delete', 'core'),
{triggerElement: audienceDelete}
).then(() => {
const pendingPromise = new Pending('core_reportbuilder/audience:delete');
return deleteAudience(reportId, audienceId)
.then(() => addToast(getString('audiencedeleted', 'core_reportbuilder', audienceTitle)))
.then(() => {
removeAudienceCard(audienceCard);
return pendingPromise.resolve();
})
.catch(Notification.exception);
}).catch(() => {
return;
});
};
/**
* Close audience card form
*
* @param {Element} audienceCard
*/
const closeAudienceCardForm = audienceCard => {
// Remove the [data-region="audience-form-container"] (with all the event listeners attached to it), and create it again.
const audienceFormContainer = audienceCard.querySelector(reportSelectors.regions.audienceFormContainer);
const NewAudienceFormContainer = audienceFormContainer.cloneNode(false);
audienceCard.querySelector(reportSelectors.regions.audienceForm).replaceChild(NewAudienceFormContainer, audienceFormContainer);
// Show the description container and enable the action buttons.
audienceCard.querySelector(reportSelectors.regions.audienceDescription).classList.remove('hidden');
audienceCard.querySelector(reportSelectors.actions.audienceEdit).disabled = false;
audienceCard.querySelector(reportSelectors.actions.audienceDelete).disabled = false;
};
/**
* Remove audience card
*
* @param {Element} audienceCard
*/
const removeAudienceCard = audienceCard => {
audienceCard.remove();
const audiencesContainer = document.querySelector(reportSelectors.regions.audiencesContainer);
const audienceCards = audiencesContainer.querySelectorAll(reportSelectors.regions.audienceCard);
// Show message if there are no cards remaining, ensure first card's separator is not present.
if (audienceCards.length === 0) {
const audienceEmptyMessage = document.querySelector(reportSelectors.regions.audienceEmptyMessage);
audienceEmptyMessage.classList.remove('hidden');
} else {
const audienceFirstCardSeparator = audienceCards[0].querySelector('.audience-separator');
audienceFirstCardSeparator?.remove();
}
};
let initialized = false;
/**
* Initialise audiences tab.
*
* @param {Number} id
* @param {Number} contextid
*/
export const init = (id, contextid) => {
prefetchStrings('core_reportbuilder', [
'audienceadded',
'audiencedeleted',
'audiencesaved',
'audienceusedbyschedule',
'deleteaudience',
'deleteaudienceconfirm',
]);
prefetchStrings('core', [
'delete',
]);
reportId = id;
contextId = contextid;
if (initialized) {
// We already added the event listeners (can be called multiple times by mustache template).
return;
}
document.addEventListener('click', event => {
// Add instance.
const audienceAdd = event.target.closest(reportSelectors.actions.audienceAdd);
if (audienceAdd) {
event.preventDefault();
addAudienceCard(audienceAdd.dataset.uniqueIdentifier, audienceAdd.dataset.name);
}
// Edit instance.
const audienceEdit = event.target.closest(reportSelectors.actions.audienceEdit);
if (audienceEdit) {
const audienceEditCard = audienceEdit.closest(reportSelectors.regions.audienceCard);
event.preventDefault();
editAudienceCard(audienceEditCard);
}
// Delete instance.
const audienceDelete = event.target.closest(reportSelectors.actions.audienceDelete);
if (audienceDelete) {
event.preventDefault();
deleteAudienceCard(audienceDelete);
}
});
initialized = true;
};
+103
View File
@@ -0,0 +1,103 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Report builder editor
*
* @module core_reportbuilder/editor
* @copyright 2021 David Matamoros <davidmc@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
"use strict";
import $ from 'jquery';
import 'core/inplace_editable';
import {addIconToContainer} from 'core/loadingicon';
import Notification from 'core/notification';
import Pending from 'core/pending';
import Templates from 'core/templates';
import {getString} from 'core/str';
import {add as addToast} from 'core/toast';
import * as reportSelectors from 'core_reportbuilder/local/selectors';
import {init as columnsEditorInit} from 'core_reportbuilder/local/editor/columns';
import {init as conditionsEditorInit} from 'core_reportbuilder/local/editor/conditions';
import {init as filtersEditorInit} from 'core_reportbuilder/local/editor/filters';
import {init as sortingEditorInit} from 'core_reportbuilder/local/editor/sorting';
import {init as cardviewEditorInit} from 'core_reportbuilder/local/editor/card_view';
import {getReport} from 'core_reportbuilder/local/repository/reports';
import {createReportModal} from 'core_reportbuilder/local/repository/modals';
let initialized = false;
/**
* Initialise editor and all it's modules
*/
export const init = () => {
columnsEditorInit(initialized);
conditionsEditorInit(initialized);
filtersEditorInit(initialized);
sortingEditorInit(initialized);
cardviewEditorInit(initialized);
// Ensure we only add our listeners once (can be called multiple times by mustache template).
if (initialized) {
return;
}
// Add event handlers to generic report editor elements.
document.addEventListener('click', event => {
// Toggle between edit and preview mode.
const toggleEditViewMode = event.target.closest(reportSelectors.actions.toggleEditPreview);
if (toggleEditViewMode) {
event.preventDefault();
const reportElement = event.target.closest(reportSelectors.regions.report);
const pendingPromise = new Pending('core_reportbuilder/reports:get');
const toggledEditMode = toggleEditViewMode.dataset.editMode !== "1";
addIconToContainer(toggleEditViewMode)
.then(() => getReport(reportElement.dataset.reportId, toggledEditMode))
.then(response => Promise.all([
$.parseHTML(response.javascript, null, true).map(node => node.innerHTML).join("\n"),
Templates.renderForPromise('core_reportbuilder/local/dynamictabs/editor', response),
]))
.then(([responseJs, {html, js}]) => Templates.replaceNode(reportElement, html, js + responseJs))
.then(() => pendingPromise.resolve())
.catch(Notification.exception);
}
// Edit report details modal.
const reportEdit = event.target.closest(reportSelectors.actions.reportEdit);
if (reportEdit) {
event.preventDefault();
const reportModal = createReportModal(event.target, getString('editreportdetails', 'core_reportbuilder'),
reportEdit.dataset.reportId);
reportModal.addEventListener(reportModal.events.FORM_SUBMITTED, () => {
getString('reportupdated', 'core_reportbuilder')
.then(addToast)
.then(() => {
return window.location.reload();
})
.catch(Notification.exception);
});
reportModal.show();
}
});
initialized = true;
};
+111
View File
@@ -0,0 +1,111 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Report builder filter management
*
* @module core_reportbuilder/filters
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import {dispatchEvent} from 'core/event_dispatcher';
import {loadFragment} from 'core/fragment';
import Notification from 'core/notification';
import Pending from 'core/pending';
import {getString} from 'core/str';
import Templates from 'core/templates';
import {add as addToast} from 'core/toast';
import DynamicForm from 'core_form/dynamicform';
import * as reportEvents from 'core_reportbuilder/local/events';
import * as reportSelectors from 'core_reportbuilder/local/selectors';
import {resetFilters} from 'core_reportbuilder/local/repository/filters';
/**
* Update filter button text to indicate applied filter count
*
* @param {Element} reportElement
* @param {Number} filterCount
*/
const setFilterButtonCount = async(reportElement, filterCount) => {
const filterButtonLabel = reportElement.querySelector(reportSelectors.regions.filterButtonLabel);
if (filterCount > 0) {
filterButtonLabel.textContent = await getString('filtersappliedx', 'core_reportbuilder', filterCount);
} else {
filterButtonLabel.textContent = await getString('filters', 'moodle');
}
};
/**
* Initialise module for given report
*
* @method
* @param {Number} reportId
* @param {Number} contextId
*/
export const init = (reportId, contextId) => {
const reportElement = document.querySelector(reportSelectors.forReport(reportId));
const filterFormContainer = reportElement.querySelector(reportSelectors.regions.filtersForm);
// Ensure we only add our listeners once (can be called multiple times by mustache template).
if (filterFormContainer.dataset.initialized) {
return;
}
filterFormContainer.dataset.initialized = true;
const filterForm = new DynamicForm(filterFormContainer, '\\core_reportbuilder\\form\\filter');
// Submit report filters.
filterForm.addEventListener(filterForm.events.FORM_SUBMITTED, event => {
event.preventDefault();
// After the form has been submitted, we should trigger report table reload.
dispatchEvent(reportEvents.tableReload, {}, reportElement);
setFilterButtonCount(reportElement, event.detail);
getString('filtersapplied', 'core_reportbuilder')
.then(addToast)
.catch(Notification.exception);
});
// Reset report filters.
filterForm.addEventListener(filterForm.events.NOSUBMIT_BUTTON_PRESSED, event => {
event.preventDefault();
const pendingPromise = new Pending('core_reportbuilder/filters:reset');
const reportParameters = reportElement.dataset.parameter;
resetFilters(reportId, reportParameters)
.then(() => getString('filtersreset', 'core_reportbuilder'))
.then(addToast)
.then(() => loadFragment('core_reportbuilder', 'filters_form', contextId, {
reportid: reportId,
parameters: reportParameters,
}))
.then((html, js) => {
Templates.replaceNodeContents(filterFormContainer, html, js);
dispatchEvent(reportEvents.tableReload, {}, reportElement);
setFilterButtonCount(reportElement, 0);
return pendingPromise.resolve();
})
.catch(Notification.exception);
});
// Modify "region-main" overflow for big filter forms.
document.querySelector('#region-main').style.overflowX = "visible";
};
@@ -0,0 +1,71 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Report builder card view editor
*
* @module core_reportbuilder/local/editor/card_view
* @copyright 2021 Mikel Martín <mikel@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
"use strict";
import DynamicForm from 'core_form/dynamicform';
import {add as addToast} from 'core/toast';
import {getString} from "core/str";
import {subscribe as subscribe} from 'core/pubsub';
import Notification from 'core/notification';
import * as reportEvents from 'core_reportbuilder/local/events';
import * as reportSelectors from 'core_reportbuilder/local/selectors';
let cardViewForm = null;
/**
* Initialise card view form, must be called on each init because the form container is re-created when switching editor modes
*/
const initCardViewForm = () => {
const cardViewFormContainer = document.querySelector(reportSelectors.regions.settingsCardView);
if (!cardViewFormContainer) {
return;
}
cardViewForm = new DynamicForm(cardViewFormContainer, '\\core_reportbuilder\\form\\card_view');
cardViewForm.addEventListener(cardViewForm.events.FORM_SUBMITTED, (event) => {
event.preventDefault();
getString('cardviewsettingssaved', 'core_reportbuilder')
.then(addToast)
.catch(Notification.exception);
});
};
/**
* Initialise module
*
* @param {Boolean} initialized Ensure we only add our listeners once
*/
export const init = (initialized) => {
initCardViewForm();
if (initialized) {
return;
}
// Update form each time a column is added or removed to the custom report.
subscribe(reportEvents.publish.reportColumnsUpdated, () => {
const reportElement = document.querySelector(reportSelectors.regions.report);
cardViewForm.load({reportid: reportElement.dataset.reportId});
});
};
@@ -0,0 +1,189 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Report builder columns editor
*
* @module core_reportbuilder/local/editor/columns
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
"use strict";
import $ from 'jquery';
import {dispatchEvent} from 'core/event_dispatcher';
import 'core/inplace_editable';
import {eventTypes as inplaceEditableEvents} from 'core/local/inplace_editable/events';
import Notification from 'core/notification';
import Pending from 'core/pending';
import {prefetchStrings} from 'core/prefetch';
import {publish} from 'core/pubsub';
import SortableList from 'core/sortable_list';
import {getString} from 'core/str';
import {add as addToast} from 'core/toast';
import * as reportEvents from 'core_reportbuilder/local/events';
import * as reportSelectors from 'core_reportbuilder/local/selectors';
import {addColumn, deleteColumn, reorderColumn} from 'core_reportbuilder/local/repository/columns';
import {getColumnSorting} from 'core_reportbuilder/local/repository/sorting';
/**
* Initialise module, prefetch all required strings
*
* @param {Boolean} initialized Ensure we only add our listeners once
*/
export const init = initialized => {
prefetchStrings('core_reportbuilder', [
'columnadded',
'columnaggregated',
'columndeleted',
'columnmoved',
'deletecolumn',
'deletecolumnconfirm',
]);
prefetchStrings('core', [
'delete',
]);
if (initialized) {
return;
}
document.addEventListener('click', event => {
// Add column to report.
const reportAddColumn = event.target.closest(reportSelectors.actions.reportAddColumn);
if (reportAddColumn) {
event.preventDefault();
const pendingPromise = new Pending('core_reportbuilder/columns:add');
const reportElement = reportAddColumn.closest(reportSelectors.regions.report);
addColumn(reportElement.dataset.reportId, reportAddColumn.dataset.uniqueIdentifier)
.then(data => publish(reportEvents.publish.reportColumnsUpdated, data))
.then(() => getString('columnadded', 'core_reportbuilder', reportAddColumn.dataset.name))
.then(addToast)
.then(() => {
dispatchEvent(reportEvents.tableReload, {preservePagination: true}, reportElement);
return pendingPromise.resolve();
})
.catch(Notification.exception);
}
// Remove column from report.
const reportRemoveColumn = event.target.closest(reportSelectors.actions.reportRemoveColumn);
if (reportRemoveColumn) {
event.preventDefault();
const reportElement = reportRemoveColumn.closest(reportSelectors.regions.report);
const columnHeader = reportRemoveColumn.closest(reportSelectors.regions.columnHeader);
const columnName = columnHeader.dataset.columnName;
Notification.saveCancelPromise(
getString('deletecolumn', 'core_reportbuilder', columnName),
getString('deletecolumnconfirm', 'core_reportbuilder', columnName),
getString('delete', 'core'),
{triggerElement: reportRemoveColumn}
).then(() => {
const pendingPromise = new Pending('core_reportbuilder/columns:remove');
return deleteColumn(reportElement.dataset.reportId, columnHeader.dataset.columnId)
.then(data => publish(reportEvents.publish.reportColumnsUpdated, data))
.then(() => addToast(getString('columndeleted', 'core_reportbuilder', columnName)))
.then(() => {
dispatchEvent(reportEvents.tableReload, {preservePagination: true}, reportElement);
return pendingPromise.resolve();
})
.catch(Notification.exception);
}).catch(() => {
return;
});
}
});
// Initialize sortable list to handle column moving (note JQuery dependency, see MDL-72293 for resolution).
var columnSortableList = new SortableList(`${reportSelectors.regions.reportTable} thead tr`, {isHorizontal: true});
columnSortableList.getElementName = element => Promise.resolve(element.data('columnName'));
$(document).on(SortableList.EVENTS.DRAG, `${reportSelectors.regions.report} th[data-column-id]`, (event, info) => {
const reportElement = event.target.closest(reportSelectors.regions.report);
const columnPosition = info.element.data('columnPosition');
const targetColumnPosition = info.targetNextElement.data('columnPosition');
$(reportElement).find('tbody tr').each(function() {
const cell = $(this).children(`td.c${columnPosition - 1}`)[0];
if (targetColumnPosition) {
var beforeCell = $(this).children(`td.c${targetColumnPosition - 1}`)[0];
this.insertBefore(cell, beforeCell);
} else {
this.appendChild(cell);
}
});
});
$(document).on(SortableList.EVENTS.DROP, `${reportSelectors.regions.report} th[data-column-id]`, (event, info) => {
if (info.positionChanged) {
const pendingPromise = new Pending('core_reportbuilder/columns:reorder');
const reportElement = event.target.closest(reportSelectors.regions.report);
const columnId = info.element.data('columnId');
const columnName = info.element.data('columnName');
const columnPosition = info.element.data('columnPosition');
// Select target position, if moving to the end then count number of element siblings.
let targetColumnPosition = info.targetNextElement.data('columnPosition') || info.element.siblings().length + 2;
if (targetColumnPosition > columnPosition) {
targetColumnPosition--;
}
// Re-order column, giving drop event transition time to finish.
const reorderPromise = reorderColumn(reportElement.dataset.reportId, columnId, targetColumnPosition);
Promise.all([reorderPromise, new Promise(resolve => setTimeout(resolve, 1000))])
.then(() => getString('columnmoved', 'core_reportbuilder', columnName))
.then(addToast)
.then(() => {
dispatchEvent(reportEvents.tableReload, {preservePagination: true}, reportElement);
return pendingPromise.resolve();
})
.catch(Notification.exception);
}
});
// Initialize inplace editable listeners for column aggregation.
document.addEventListener(inplaceEditableEvents.elementUpdated, event => {
const columnAggregation = event.target.closest('[data-itemtype="columnaggregation"]');
if (columnAggregation) {
const pendingPromise = new Pending('core_reportbuilder/columns:aggregate');
const reportElement = columnAggregation.closest(reportSelectors.regions.report);
const columnHeader = columnAggregation.closest(reportSelectors.regions.columnHeader);
getString('columnaggregated', 'core_reportbuilder', columnHeader.dataset.columnName)
.then(addToast)
.then(() => {
// Pass preserveTriggerElement parameter so columnAggregationLink will be focused after the report reload.
const columnAggregationLink = `[data-itemtype="columnaggregation"][data-itemid="`
+ `${columnAggregation.dataset.itemid}"] > a`;
// Now reload the table, and notify listeners that columns have been updated.
dispatchEvent(reportEvents.tableReload, {preserveTriggerElement: columnAggregationLink}, reportElement);
return getColumnSorting(reportElement.dataset.reportId);
})
.then(data => publish(reportEvents.publish.reportColumnsUpdated, data))
.then(() => pendingPromise.resolve())
.catch(Notification.exception);
}
});
};
@@ -0,0 +1,244 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Report builder conditions editor
*
* @module core_reportbuilder/local/editor/conditions
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
"use strict";
import $ from 'jquery';
import {dispatchEvent} from 'core/event_dispatcher';
import AutoComplete from 'core/form-autocomplete';
import 'core/inplace_editable';
import Notification from 'core/notification';
import Pending from 'core/pending';
import {prefetchStrings} from 'core/prefetch';
import SortableList from 'core/sortable_list';
import {getString} from 'core/str';
import Templates from 'core/templates';
import {add as addToast} from 'core/toast';
import DynamicForm from 'core_form/dynamicform';
import * as reportEvents from 'core_reportbuilder/local/events';
import * as reportSelectors from 'core_reportbuilder/local/selectors';
import {addCondition, deleteCondition, reorderCondition, resetConditions} from 'core_reportbuilder/local/repository/conditions';
/**
* Reload conditions settings region
*
* @param {Element} reportElement
* @param {Object} templateContext
* @return {Promise}
*/
const reloadSettingsConditionsRegion = (reportElement, templateContext) => {
const pendingPromise = new Pending('core_reportbuilder/conditions:reload');
const settingsConditionsRegion = reportElement.querySelector(reportSelectors.regions.settingsConditions);
return Templates.renderForPromise('core_reportbuilder/local/settings/conditions', {conditions: templateContext})
.then(({html, js}) => {
const conditionsjs = $.parseHTML(templateContext.javascript, null, true).map(node => node.innerHTML).join("\n");
Templates.replaceNode(settingsConditionsRegion, html, js + conditionsjs);
initConditionsForm();
// Re-focus the add condition element after reloading the region.
const reportAddCondition = reportElement.querySelector(reportSelectors.actions.reportAddCondition);
reportAddCondition?.focus();
return pendingPromise.resolve();
});
};
/**
* Initialise conditions form, must be called on each init because the form container is re-created when switching editor modes
*/
const initConditionsForm = () => {
const reportElement = document.querySelector(reportSelectors.regions.report);
// Enhance condition selector.
const reportAddCondition = reportElement.querySelector(reportSelectors.actions.reportAddCondition);
AutoComplete.enhanceField(reportAddCondition, false, '', getString('selectacondition', 'core_reportbuilder'))
.catch(Notification.exception);
// Handle dynamic conditions form.
const conditionFormContainer = reportElement.querySelector(reportSelectors.regions.settingsConditions);
if (!conditionFormContainer) {
return;
}
const conditionForm = new DynamicForm(conditionFormContainer, '\\core_reportbuilder\\form\\condition');
// Submit report conditions.
conditionForm.addEventListener(conditionForm.events.FORM_SUBMITTED, event => {
event.preventDefault();
getString('conditionsapplied', 'core_reportbuilder')
.then(addToast)
.catch(Notification.exception);
// After the form has been submitted, we should trigger report table reload.
dispatchEvent(reportEvents.tableReload, {}, reportElement);
});
// Reset report conditions.
conditionForm.addEventListener(conditionForm.events.NOSUBMIT_BUTTON_PRESSED, event => {
event.preventDefault();
Notification.saveCancelPromise(
getString('resetconditions', 'core_reportbuilder'),
getString('resetconditionsconfirm', 'core_reportbuilder'),
getString('resetall', 'core_reportbuilder'),
{triggerElement: event.detail}
).then(() => {
const pendingPromise = new Pending('core_reportbuilder/conditions:reset');
return resetConditions(reportElement.dataset.reportId)
.then(data => reloadSettingsConditionsRegion(reportElement, data))
.then(() => addToast(getString('conditionsreset', 'core_reportbuilder')))
.then(() => {
dispatchEvent(reportEvents.tableReload, {}, reportElement);
return pendingPromise.resolve();
})
.catch(Notification.exception);
}).catch(() => {
return;
});
});
};
/**
* Initialise module, prefetch all required strings
*
* @param {Boolean} initialized Ensure we only add our listeners once
*/
export const init = initialized => {
prefetchStrings('core_reportbuilder', [
'conditionadded',
'conditiondeleted',
'conditionmoved',
'conditionsapplied',
'conditionsreset',
'deletecondition',
'deleteconditionconfirm',
'resetall',
'resetconditions',
'resetconditionsconfirm',
'selectacondition',
]);
prefetchStrings('core', [
'delete',
]);
initConditionsForm();
if (initialized) {
return;
}
// Add condition to report.
document.addEventListener('change', event => {
const reportAddCondition = event.target.closest(reportSelectors.actions.reportAddCondition);
if (reportAddCondition) {
event.preventDefault();
// Check if dropdown is closed with no condition selected.
if (reportAddCondition.value === "" || reportAddCondition.value === "0") {
return;
}
const reportElement = reportAddCondition.closest(reportSelectors.regions.report);
const pendingPromise = new Pending('core_reportbuilder/conditions:add');
addCondition(reportElement.dataset.reportId, reportAddCondition.value)
.then(data => reloadSettingsConditionsRegion(reportElement, data))
.then(() => getString('conditionadded', 'core_reportbuilder',
reportAddCondition.options[reportAddCondition.selectedIndex].text))
.then(addToast)
.then(() => {
dispatchEvent(reportEvents.tableReload, {}, reportElement);
return pendingPromise.resolve();
})
.catch(Notification.exception);
}
});
document.addEventListener('click', event => {
// Remove condition from report.
const reportRemoveCondition = event.target.closest(reportSelectors.actions.reportRemoveCondition);
if (reportRemoveCondition) {
event.preventDefault();
const reportElement = reportRemoveCondition.closest(reportSelectors.regions.report);
const conditionContainer = reportRemoveCondition.closest(reportSelectors.regions.activeCondition);
const conditionName = conditionContainer.dataset.conditionName;
Notification.saveCancelPromise(
getString('deletecondition', 'core_reportbuilder', conditionName),
getString('deleteconditionconfirm', 'core_reportbuilder', conditionName),
getString('delete', 'core'),
{triggerElement: reportRemoveCondition}
).then(() => {
const pendingPromise = new Pending('core_reportbuilder/conditions:remove');
return deleteCondition(reportElement.dataset.reportId, conditionContainer.dataset.conditionId)
.then(data => reloadSettingsConditionsRegion(reportElement, data))
.then(() => addToast(getString('conditiondeleted', 'core_reportbuilder', conditionName)))
.then(() => {
dispatchEvent(reportEvents.tableReload, {}, reportElement);
return pendingPromise.resolve();
})
.catch(Notification.exception);
}).catch(() => {
return;
});
}
});
// Initialize sortable list to handle active conditions moving (note JQuery dependency, see MDL-72293 for resolution).
var activeConditionsSortableList = new SortableList(`${reportSelectors.regions.activeConditions}`,
{isHorizontal: false});
activeConditionsSortableList.getElementName = element => Promise.resolve(element.data('conditionName'));
$(document).on(SortableList.EVENTS.DROP, reportSelectors.regions.activeCondition, (event, info) => {
if (info.positionChanged) {
const pendingPromise = new Pending('core_reportbuilder/conditions:reorder');
const reportElement = event.target.closest(reportSelectors.regions.report);
const conditionId = info.element.data('conditionId');
const conditionPosition = info.element.data('conditionPosition');
// Select target position, if moving to the end then count number of element siblings.
let targetConditionPosition = info.targetNextElement.data('conditionPosition') || info.element.siblings().length + 2;
if (targetConditionPosition > conditionPosition) {
targetConditionPosition--;
}
// Re-order condition, giving drop event transition time to finish.
const reorderPromise = reorderCondition(reportElement.dataset.reportId, conditionId, targetConditionPosition);
Promise.all([reorderPromise, new Promise(resolve => setTimeout(resolve, 1000))])
.then(([data]) => reloadSettingsConditionsRegion(reportElement, data))
.then(() => getString('conditionmoved', 'core_reportbuilder', info.element.data('conditionName')))
.then(addToast)
.then(() => {
dispatchEvent(reportEvents.tableReload, {}, reportElement);
return pendingPromise.resolve();
})
.catch(Notification.exception);
}
});
};
@@ -0,0 +1,181 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Report builder filters editor
*
* @module core_reportbuilder/local/editor/filters
* @copyright 2021 David Matamoros <davidmc@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
"use strict";
import $ from 'jquery';
import AutoComplete from 'core/form-autocomplete';
import 'core/inplace_editable';
import Notification from 'core/notification';
import Pending from 'core/pending';
import {prefetchStrings} from 'core/prefetch';
import SortableList from 'core/sortable_list';
import {getString} from 'core/str';
import Templates from 'core/templates';
import {add as addToast} from 'core/toast';
import * as reportSelectors from 'core_reportbuilder/local/selectors';
import {addFilter, deleteFilter, reorderFilter} from 'core_reportbuilder/local/repository/filters';
/**
* Reload filters settings region
*
* @param {Element} reportElement
* @param {Object} templateContext
* @return {Promise}
*/
const reloadSettingsFiltersRegion = (reportElement, templateContext) => {
const pendingPromise = new Pending('core_reportbuilder/filters:reload');
const settingsFiltersRegion = reportElement.querySelector(reportSelectors.regions.settingsFilters);
return Templates.renderForPromise('core_reportbuilder/local/settings/filters', {filters: templateContext})
.then(({html, js}) => {
Templates.replaceNode(settingsFiltersRegion, html, js);
initFiltersForm();
// Re-focus the add filter element after reloading the region.
const reportAddFilter = reportElement.querySelector(reportSelectors.actions.reportAddFilter);
reportAddFilter?.focus();
return pendingPromise.resolve();
});
};
/**
* Initialise filters form, must be called on each init because the form container is re-created when switching editor modes
*/
const initFiltersForm = () => {
const reportElement = document.querySelector(reportSelectors.regions.report);
// Enhance filter selector.
const reportAddFilter = reportElement.querySelector(reportSelectors.actions.reportAddFilter);
AutoComplete.enhanceField(reportAddFilter, false, '', getString('selectafilter', 'core_reportbuilder'))
.catch(Notification.exception);
};
/**
* Initialise module, prefetch all required strings
*
* @param {Boolean} initialized Ensure we only add our listeners once
*/
export const init = initialized => {
prefetchStrings('core_reportbuilder', [
'deletefilter',
'deletefilterconfirm',
'filteradded',
'filterdeleted',
'filtermoved',
'selectafilter',
]);
prefetchStrings('core', [
'delete',
]);
initFiltersForm();
if (initialized) {
return;
}
// Add filter to report.
document.addEventListener('change', event => {
const reportAddFilter = event.target.closest(reportSelectors.actions.reportAddFilter);
if (reportAddFilter) {
event.preventDefault();
// Check if dropdown is closed with no filter selected.
if (reportAddFilter.value === "" || reportAddFilter.value === "0") {
return;
}
const reportElement = reportAddFilter.closest(reportSelectors.regions.report);
const pendingPromise = new Pending('core_reportbuilder/filters:add');
addFilter(reportElement.dataset.reportId, reportAddFilter.value)
.then(data => reloadSettingsFiltersRegion(reportElement, data))
.then(() => getString('filteradded', 'core_reportbuilder',
reportAddFilter.options[reportAddFilter.selectedIndex].text))
.then(addToast)
.then(() => pendingPromise.resolve())
.catch(Notification.exception);
}
});
document.addEventListener('click', event => {
// Remove filter from report.
const reportRemoveFilter = event.target.closest(reportSelectors.actions.reportRemoveFilter);
if (reportRemoveFilter) {
event.preventDefault();
const reportElement = reportRemoveFilter.closest(reportSelectors.regions.report);
const filterContainer = reportRemoveFilter.closest(reportSelectors.regions.activeFilter);
const filterName = filterContainer.dataset.filterName;
Notification.saveCancelPromise(
getString('deletefilter', 'core_reportbuilder', filterName),
getString('deletefilterconfirm', 'core_reportbuilder', filterName),
getString('delete', 'core'),
{triggerElement: reportRemoveFilter}
).then(() => {
const pendingPromise = new Pending('core_reportbuilder/filters:remove');
return deleteFilter(reportElement.dataset.reportId, filterContainer.dataset.filterId)
.then(data => reloadSettingsFiltersRegion(reportElement, data))
.then(() => addToast(getString('filterdeleted', 'core_reportbuilder', filterName)))
.then(() => pendingPromise.resolve())
.catch(Notification.exception);
}).catch(() => {
return;
});
}
});
// Initialize sortable list to handle active filters moving (note JQuery dependency, see MDL-72293 for resolution).
var activeFiltersSortableList = new SortableList(`${reportSelectors.regions.activeFilters} ul`, {isHorizontal: false});
activeFiltersSortableList.getElementName = element => Promise.resolve(element.data('filterName'));
$(document).on(SortableList.EVENTS.DROP, `${reportSelectors.regions.report} li[data-filter-id]`, (event, info) => {
if (info.positionChanged) {
const pendingPromise = new Pending('core_reportbuilder/filters:reorder');
const reportElement = event.target.closest(reportSelectors.regions.report);
const filterId = info.element.data('filterId');
const filterPosition = info.element.data('filterPosition');
// Select target position, if moving to the end then count number of element siblings.
let targetFilterPosition = info.targetNextElement.data('filterPosition') || info.element.siblings().length + 2;
if (targetFilterPosition > filterPosition) {
targetFilterPosition--;
}
// Re-order filter, giving drop event transition time to finish.
const reorderPromise = reorderFilter(reportElement.dataset.reportId, filterId, targetFilterPosition);
Promise.all([reorderPromise, new Promise(resolve => setTimeout(resolve, 1000))])
.then(([data]) => reloadSettingsFiltersRegion(reportElement, data))
.then(() => getString('filtermoved', 'core_reportbuilder', info.element.data('filterName')))
.then(addToast)
.then(() => pendingPromise.resolve())
.catch(Notification.exception);
}
});
};
@@ -0,0 +1,182 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Report builder columns sorting editor
*
* @module core_reportbuilder/local/editor/sorting
* @copyright 2021 David Matamoros <davidmc@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
"use strict";
import $ from 'jquery';
import 'core/inplace_editable';
import Notification from 'core/notification';
import Pending from 'core/pending';
import {subscribe} from 'core/pubsub';
import SortableList from 'core/sortable_list';
import {getString} from 'core/str';
import {add as addToast} from 'core/toast';
import * as reportSelectors from 'core_reportbuilder/local/selectors';
import {reorderColumnSorting, toggleColumnSorting} from 'core_reportbuilder/local/repository/sorting';
import Templates from 'core/templates';
import {dispatchEvent} from 'core/event_dispatcher';
import * as reportEvents from 'core_reportbuilder/local/events';
// These constants match PHP consts SORT_ASC, SORT_DESC.
const SORTORDER = {
ASCENDING: 4,
DESCENDING: 3,
};
/**
* Reload sorting settings region
*
* @param {Object} context
* @return {Promise}
*/
const reloadSettingsSortingRegion = context => {
const pendingPromise = new Pending('core_reportbuilder/sorting:reload');
const settingsSortingRegion = document.querySelector(reportSelectors.regions.settingsSorting);
return Templates.renderForPromise('core_reportbuilder/local/settings/sorting', {sorting: context})
.then(({html, js}) => {
Templates.replaceNode(settingsSortingRegion, html, js);
return pendingPromise.resolve();
});
};
/**
* Updates column sorting
*
* @param {Element} reportElement
* @param {Element} element
* @param {Number} sortenabled
* @param {Number} sortdirection
* @return {Promise}
*/
const updateSorting = (reportElement, element, sortenabled, sortdirection) => {
const reportId = reportElement.dataset.reportId;
const listElement = element.closest('li');
const columnId = listElement.dataset.columnSortId;
const columnName = listElement.dataset.columnSortName;
return toggleColumnSorting(reportId, columnId, sortenabled, sortdirection)
.then(reloadSettingsSortingRegion)
.then(() => getString('columnsortupdated', 'core_reportbuilder', columnName))
.then(addToast)
.then(() => {
dispatchEvent(reportEvents.tableReload, {}, reportElement);
return null;
});
};
/**
* Initialise module
*
* @param {Boolean} initialized Ensure we only add our listeners once
*/
export const init = (initialized) => {
if (initialized) {
return;
}
// Update sorting region each time report columns are updated (added or removed).
subscribe(reportEvents.publish.reportColumnsUpdated, data => reloadSettingsSortingRegion(data)
.catch(Notification.exception)
);
document.addEventListener('click', event => {
// Enable/disable sorting on columns.
const toggleSorting = event.target.closest(reportSelectors.actions.reportToggleColumnSort);
if (toggleSorting) {
event.preventDefault();
const pendingPromise = new Pending('core_reportbuilder/sorting:toggle');
const reportElement = toggleSorting.closest(reportSelectors.regions.report);
const sortdirection = parseInt(toggleSorting.closest('li').dataset.columnSortDirection);
updateSorting(reportElement, toggleSorting, toggleSorting.checked, sortdirection)
.then(() => {
// Re-focus the toggle sorting element after reloading the region.
const toggleSortingElement = document.getElementById(toggleSorting.id);
toggleSortingElement?.focus();
return pendingPromise.resolve();
})
.catch(Notification.exception);
}
// Change column sort direction.
const toggleSortDirection = event.target.closest(reportSelectors.actions.reportToggleColumnSortDirection);
if (toggleSortDirection) {
event.preventDefault();
const pendingPromise = new Pending('core_reportbuilder/sorting:direction');
const reportElement = toggleSortDirection.closest(reportSelectors.regions.report);
const listElement = toggleSortDirection.closest('li');
const toggleSorting = listElement.querySelector(reportSelectors.actions.reportToggleColumnSort);
let sortdirection = parseInt(listElement.dataset.columnSortDirection);
if (sortdirection === SORTORDER.ASCENDING) {
sortdirection = SORTORDER.DESCENDING;
} else if (sortdirection === SORTORDER.DESCENDING) {
sortdirection = SORTORDER.ASCENDING;
}
updateSorting(reportElement, toggleSortDirection, toggleSorting.checked, sortdirection)
.then(() => {
// Re-focus the toggle sort direction element after reloading the region.
const toggleSortDirectionElement = document.getElementById(toggleSortDirection.id);
toggleSortDirectionElement?.focus();
return pendingPromise.resolve();
})
.catch(Notification.exception);
}
});
// Initialize sortable list to handle column sorting moving (note JQuery dependency, see MDL-72293 for resolution).
var columnsSortingSortableList = new SortableList(`${reportSelectors.regions.settingsSorting} ul`, {isHorizontal: false});
columnsSortingSortableList.getElementName = element => Promise.resolve(element.data('columnSortName'));
$(document).on(SortableList.EVENTS.DROP, `${reportSelectors.regions.report} li[data-column-sort-id]`, (event, info) => {
if (info.positionChanged) {
const pendingPromise = new Pending('core_reportbuilder/sorting:reorder');
const reportElement = event.target.closest(reportSelectors.regions.report);
const columnId = info.element.data('columnSortId');
const columnPosition = info.element.data('columnSortPosition');
// Select target position, if moving to the end then count number of element siblings.
let targetColumnSortPosition = info.targetNextElement.data('columnSortPosition') || info.element.siblings().length + 2;
if (targetColumnSortPosition > columnPosition) {
targetColumnSortPosition--;
}
// Re-order column sorting, giving drop event transition time to finish.
const reorderPromise = reorderColumnSorting(reportElement.dataset.reportId, columnId, targetColumnSortPosition);
Promise.all([reorderPromise, new Promise(resolve => setTimeout(resolve, 1000))])
.then(([data]) => reloadSettingsSortingRegion(data))
.then(() => getString('columnsortupdated', 'core_reportbuilder', info.element.data('columnSortName')))
.then(addToast)
.then(() => {
dispatchEvent(reportEvents.tableReload, {}, reportElement);
return pendingPromise.resolve();
})
.catch(Notification.exception);
}
});
};
+50
View File
@@ -0,0 +1,50 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Report builder events
*
* @module core_reportbuilder/local/events
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Events for the Report builder subsystem
*
* @constant
* @property {String} tableReload See {@link event:tableReload}
*/
export default {
/**
* Trigger table reloading
*
* @event tableReload
* @type {CustomEvent}
* @property {object} detail
* @property {Boolean} detail.preservePagination Whether current pagination should be preserved (default false)
* @property {String} detail.preserveTriggerElement Element selector that should be focused after table reload (default null)
*
* @example <caption>Triggering table reload</caption>
* import {dispatchEvent} from 'core/event_dispatcher';
* import * as reportEvents from 'core_reportbuilder/local/events';
*
* dispatchEvent(reportEvents.tableReload, {}, document.querySelector(...));
*/
tableReload: 'core_reportbuilder_table_reload',
publish: {
reportColumnsUpdated: 'core_reportbuilder_report_columns_updated',
},
};
@@ -0,0 +1,40 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Module to handle audiences AJAX requests
*
* @module core_reportbuilder/local/repository/audiences
* @copyright 2021 David Matamoros <davidmc@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import Ajax from 'core/ajax';
/**
* Remove audience from given report
*
* @param {Number} reportId
* @param {Number} instanceId
* @return {Promise}
*/
export const deleteAudience = (reportId, instanceId) => {
const request = {
methodname: 'core_reportbuilder_audiences_delete',
args: {reportid: reportId, instanceid: instanceId}
};
return Ajax.call([request])[0];
};
@@ -0,0 +1,73 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Module to handle column AJAX requests
*
* @module core_reportbuilder/local/repository/columns
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import Ajax from 'core/ajax';
/**
* Add column to given report
*
* @param {Number} reportId
* @param {String} uniqueIdentifier
* @return {Promise}
*/
export const addColumn = (reportId, uniqueIdentifier) => {
const request = {
methodname: 'core_reportbuilder_columns_add',
args: {reportid: reportId, uniqueidentifier: uniqueIdentifier}
};
return Ajax.call([request])[0];
};
/**
* Remove column from given report
*
* @param {Number} reportId
* @param {Number} columnId
* @return {Promise}
*/
export const deleteColumn = (reportId, columnId) => {
const request = {
methodname: 'core_reportbuilder_columns_delete',
args: {reportid: reportId, columnid: columnId}
};
return Ajax.call([request])[0];
};
/**
* Re-order column within a report
*
* @param {Number} reportId
* @param {Number} columnId
* @param {Number} position
* @return {Promise}
*/
export const reorderColumn = (reportId, columnId, position) => {
const request = {
methodname: 'core_reportbuilder_columns_reorder',
args: {reportid: reportId, columnid: columnId, position: position}
};
return Ajax.call([request])[0];
};
@@ -0,0 +1,88 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Module to handle condition AJAX requests
*
* @module core_reportbuilder/local/repository/conditions
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import Ajax from 'core/ajax';
/**
* Reset all conditions for given report
*
* @param {Number} reportId
* @return {Promise}
*/
export const resetConditions = reportId => {
const request = {
methodname: 'core_reportbuilder_conditions_reset',
args: {reportid: reportId}
};
return Ajax.call([request])[0];
};
/**
* Add condition to given report
*
* @param {Number} reportId
* @param {String} uniqueIdentifier
* @return {Promise}
*/
export const addCondition = (reportId, uniqueIdentifier) => {
const request = {
methodname: 'core_reportbuilder_conditions_add',
args: {reportid: reportId, uniqueidentifier: uniqueIdentifier}
};
return Ajax.call([request])[0];
};
/**
* Remove condition from given report
*
* @param {Number} reportId
* @param {Number} conditionId
* @return {Promise}
*/
export const deleteCondition = (reportId, conditionId) => {
const request = {
methodname: 'core_reportbuilder_conditions_delete',
args: {reportid: reportId, conditionid: conditionId}
};
return Ajax.call([request])[0];
};
/**
* Reorder a condition in a given report
*
* @param {Number} reportId
* @param {Number} conditionId
* @param {Number} position
* @return {Promise}
*/
export const reorderCondition = (reportId, conditionId, position) => {
const request = {
methodname: 'core_reportbuilder_conditions_reorder',
args: {reportid: reportId, conditionid: conditionId, position: position}
};
return Ajax.call([request])[0];
};
@@ -0,0 +1,108 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Module to handle filter AJAX requests
*
* @module core_reportbuilder/local/repository/filters
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import Ajax from 'core/ajax';
/**
* Reset all filters for given report
*
* @method
* @param {Number} reportId
* @param {String} reportParameters
* @return {Promise}
*/
export const resetFilters = (reportId, reportParameters) => {
const request = {
methodname: 'core_reportbuilder_filters_reset',
args: {reportid: reportId, parameters: reportParameters}
};
return Ajax.call([request])[0];
};
/**
* Set filter values for given report
*
* @method
* @param {Number} reportId
* @param {String} reportParameters
* @param {String} filterValues
* @return {Promise}
*/
export const setFilters = (reportId, reportParameters, filterValues) => {
const request = {
methodname: 'core_reportbuilder_set_filters',
args: {reportid: reportId, parameters: reportParameters, values: filterValues}
};
return Ajax.call([request])[0];
};
/**
* Add a filter to the given report
*
* @param {Number} reportId
* @param {String} uniqueIdentifier
* @return {Promise}
*/
export const addFilter = (reportId, uniqueIdentifier) => {
const request = {
methodname: 'core_reportbuilder_filters_add',
args: {reportid: reportId, uniqueidentifier: uniqueIdentifier}
};
return Ajax.call([request])[0];
};
/**
* Remove filter from given report
*
* @param {Number} reportId
* @param {Number} filterId
* @return {Promise}
*/
export const deleteFilter = (reportId, filterId) => {
const request = {
methodname: 'core_reportbuilder_filters_delete',
args: {reportid: reportId, filterid: filterId}
};
return Ajax.call([request])[0];
};
/**
* Reorder a filter in a given report
*
* @param {Number} reportId
* @param {Number} filterId
* @param {Number} position
* @return {Promise}
*/
export const reorderFilter = (reportId, filterId, position) => {
const request = {
methodname: 'core_reportbuilder_filters_reorder',
args: {reportid: reportId, filterid: filterId, position: position}
};
return Ajax.call([request])[0];
};
@@ -0,0 +1,76 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Module to handle modal form requests
*
* @module core_reportbuilder/local/repository/modals
* @copyright 2021 David Matamoros <davidmc@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import ModalForm from 'core_form/modalform';
import {getString} from 'core/str';
/**
* Return modal instance
*
* @param {EventTarget} triggerElement
* @param {Promise} modalTitle
* @param {String} formClass
* @param {Object} formArgs
* @return {ModalForm}
*/
const createModalForm = (triggerElement, modalTitle, formClass, formArgs) => {
return new ModalForm({
modalConfig: {
title: modalTitle,
},
formClass: formClass,
args: formArgs,
saveButtonText: getString('save', 'moodle'),
returnFocus: triggerElement,
});
};
/**
* Return report modal instance
*
* @param {EventTarget} triggerElement
* @param {Promise} modalTitle
* @param {Number} reportId
* @return {ModalForm}
*/
export const createReportModal = (triggerElement, modalTitle, reportId = 0) => {
return createModalForm(triggerElement, modalTitle, 'core_reportbuilder\\form\\report', {
id: reportId,
});
};
/**
* Return schedule modal instance
*
* @param {EventTarget} triggerElement
* @param {Promise} modalTitle
* @param {Number} reportId
* @param {Number} scheduleId
* @return {ModalForm}
*/
export const createScheduleModal = (triggerElement, modalTitle, reportId, scheduleId = 0) => {
return createModalForm(triggerElement, modalTitle, 'core_reportbuilder\\form\\schedule', {
reportid: reportId,
id: scheduleId,
});
};
@@ -0,0 +1,56 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Module to handle report AJAX requests
*
* @module core_reportbuilder/local/repository/reports
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import Ajax from 'core/ajax';
/**
* Delete given report
*
* @param {Number} reportId
* @return {Promise}
*/
export const deleteReport = reportId => {
const request = {
methodname: 'core_reportbuilder_reports_delete',
args: {reportid: reportId}
};
return Ajax.call([request])[0];
};
/**
* Get report content
*
* @param {Number} reportId
* @param {Boolean} editMode
* @param {Number} [pageSize=0]
* @return {Promise}
*/
export const getReport = (reportId, editMode, pageSize = 0) => {
const request = {
methodname: 'core_reportbuilder_reports_get',
args: {reportid: reportId, editmode: editMode, pagesize: pageSize}
};
return Ajax.call([request])[0];
};
@@ -0,0 +1,76 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Module to handle schedule AJAX requests
*
* @module core_reportbuilder/local/repository/schedules
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import Ajax from 'core/ajax';
/**
* Delete schedule
*
* @method
* @param {Number} reportId
* @param {Number} scheduleId
* @return {Promise}
*/
export const deleteSchedule = (reportId, scheduleId) => {
const request = {
methodname: 'core_reportbuilder_schedules_delete',
args: {reportid: reportId, scheduleid: scheduleId}
};
return Ajax.call([request])[0];
};
/**
* Send schedule
*
* @method
* @param {Number} reportId
* @param {Number} scheduleId
* @return {Promise}
*/
export const sendSchedule = (reportId, scheduleId) => {
const request = {
methodname: 'core_reportbuilder_schedules_send',
args: {reportid: reportId, scheduleid: scheduleId}
};
return Ajax.call([request])[0];
};
/**
* Toggle schedule enabled
*
* @method
* @param {Number} reportId
* @param {Number} scheduleId
* @param {Boolean} scheduleEnabled
* @return {Promise}
*/
export const toggleSchedule = (reportId, scheduleId, scheduleEnabled) => {
const request = {
methodname: 'core_reportbuilder_schedules_toggle',
args: {reportid: reportId, scheduleid: scheduleId, enabled: scheduleEnabled}
};
return Ajax.call([request])[0];
};
@@ -0,0 +1,74 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Module to handle column sorting AJAX requests
*
* @module core_reportbuilder/local/repository/sorting
* @copyright 2021 David Matamoros <davidmc@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import Ajax from 'core/ajax';
/**
* Retrieve column sorting
*
* @param {Number} reportId
* @return {Promise}
*/
export const getColumnSorting = reportId => {
const request = {
methodname: 'core_reportbuilder_columns_sort_get',
args: {reportid: reportId}
};
return Ajax.call([request])[0];
};
/**
* Re-order sort column position
*
* @param {Number} reportId
* @param {Number} columnId
* @param {Number} position
* @return {Promise}
*/
export const reorderColumnSorting = (reportId, columnId, position) => {
const request = {
methodname: 'core_reportbuilder_columns_sort_reorder',
args: {reportid: reportId, columnid: columnId, position: position}
};
return Ajax.call([request])[0];
};
/**
* Enables/disabled sorting on column
*
* @param {Number} reportId
* @param {Number} columnId
* @param {Boolean} enabled
* @param {Number} direction
* @return {Promise}
*/
export const toggleColumnSorting = (reportId, columnId, enabled, direction) => {
const request = {
methodname: 'core_reportbuilder_columns_sort_toggle',
args: {reportid: reportId, columnid: columnId, enabled: enabled, direction: direction}
};
return Ajax.call([request])[0];
};
+95
View File
@@ -0,0 +1,95 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Report builder selectors
*
* @module core_reportbuilder/local/selectors
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Selectors for the Report builder subsystem
*
* @property {Object} regions
* @property {String} regions.systemReport System report page region
* @property {String} regions.filterButtonLabel Filters form toggle region
* @property {String} regions.filtersForm Filters form page region
*/
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"]',
sidebarItem: '[data-region="sidebar-item"]',
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"]',
},
};
/**
* Selector for given report
*
* @method forReport
* @param {Number} reportId
* @return {String}
*/
SELECTORS.forReport = reportId => `${SELECTORS.regions.report}[data-report-id="${reportId}"]`;
export default SELECTORS;
+107
View File
@@ -0,0 +1,107 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Report builder report management
*
* @module core_reportbuilder/report
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import Notification from 'core/notification';
import * as reportEvents from 'core_reportbuilder/local/events';
import * as reportSelectors from 'core_reportbuilder/local/selectors';
import {setPageNumber, refreshTableContent} from 'core_table/dynamic';
import * as tableSelectors from 'core_table/local/dynamic/selectors';
const CLASSES = {
COLLAPSED: 'collapsed',
EXPANDED: 'show',
ICONUP: 'fa-angle-up',
ICONDOWN: 'fa-angle-down'
};
let initialized = false;
/**
* Initialise module for given report
*
* @method
*/
export const init = () => {
if (initialized) {
// We already added the event listeners (can be called multiple times by mustache template).
return;
}
// Listen for the table reload event.
document.addEventListener(reportEvents.tableReload, async(event) => {
const reportElement = event.target.closest(reportSelectors.regions.report);
if (reportElement === null) {
return;
}
const tableRoot = reportElement.querySelector(tableSelectors.main.region);
const pageNumber = event.detail?.preservePagination ? null : 1;
await setPageNumber(tableRoot, pageNumber, false)
.then(refreshTableContent)
.then(() => {
// TODO: Refactor this after MDL-73130 lands.
const preserveTriggerElement = event.detail?.preserveTriggerElement;
if (preserveTriggerElement) {
reportElement.querySelector(preserveTriggerElement)?.focus();
}
return;
})
.catch(Notification.exception);
});
// Listen for trigger popup events.
document.addEventListener('click', event => {
const reportActionPopup = event.target.closest(reportSelectors.actions.reportActionPopup);
if (reportActionPopup === null) {
return;
}
event.preventDefault();
const popupAction = JSON.parse(reportActionPopup.dataset.popupAction);
window.openpopup(event, popupAction.jsfunctionargs);
});
// Listen for card view toggle events.
document.addEventListener('click', (event) => {
const toggleCard = event.target.closest(reportSelectors.actions.toggleCardView);
if (toggleCard) {
const tableCard = toggleCard.closest('tr');
const toggleIcon = toggleCard.querySelector('i');
event.preventDefault();
if (toggleCard.classList.contains(CLASSES.COLLAPSED)) {
tableCard.classList.add(CLASSES.EXPANDED);
toggleIcon.classList.replace(CLASSES.ICONDOWN, CLASSES.ICONUP);
toggleCard.classList.remove(CLASSES.COLLAPSED);
toggleCard.setAttribute('aria-expanded', "true");
} else {
tableCard.classList.remove(CLASSES.EXPANDED);
toggleIcon.classList.replace(CLASSES.ICONUP, CLASSES.ICONDOWN);
toggleCard.classList.add(CLASSES.COLLAPSED);
toggleCard.removeAttribute('aria-expanded');
}
}
});
initialized = true;
};
+119
View File
@@ -0,0 +1,119 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Report builder reports list management
*
* @module core_reportbuilder/reports_list
* @copyright 2021 David Matamoros <davidmc@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
"use strict";
import {dispatchEvent} from 'core/event_dispatcher';
import Notification from 'core/notification';
import Pending from 'core/pending';
import {prefetchStrings} from 'core/prefetch';
import {getString} from 'core/str';
import {add as addToast} from 'core/toast';
import * as reportEvents from 'core_reportbuilder/local/events';
import * as reportSelectors from 'core_reportbuilder/local/selectors';
import {deleteReport} from 'core_reportbuilder/local/repository/reports';
import {createReportModal} from 'core_reportbuilder/local/repository/modals';
/**
* Initialise module
*/
export const init = () => {
prefetchStrings('core_reportbuilder', [
'deletereport',
'deletereportconfirm',
'editreportdetails',
'newreport',
'reportdeleted',
'reportupdated',
]);
prefetchStrings('core', [
'delete',
]);
document.addEventListener('click', event => {
const reportCreate = event.target.closest(reportSelectors.actions.reportCreate);
if (reportCreate) {
event.preventDefault();
// Redirect user to editing interface for the report after submission.
const reportModal = createReportModal(event.target, getString('newreport', 'core_reportbuilder'));
reportModal.addEventListener(reportModal.events.FORM_SUBMITTED, event => {
window.location.href = event.detail;
});
reportModal.show();
}
const reportEdit = event.target.closest(reportSelectors.actions.reportEdit);
if (reportEdit) {
event.preventDefault();
// Reload current report page after submission.
// Use triggerElement to return focus to the action menu toggle.
const triggerElement = reportEdit.closest('.dropdown').querySelector('.dropdown-toggle');
const reportModal = createReportModal(triggerElement, getString('editreportdetails', 'core_reportbuilder'),
reportEdit.dataset.reportId);
reportModal.addEventListener(reportModal.events.FORM_SUBMITTED, () => {
const reportElement = event.target.closest(reportSelectors.regions.report);
getString('reportupdated', 'core_reportbuilder')
.then(addToast)
.then(() => {
dispatchEvent(reportEvents.tableReload, {preservePagination: true}, reportElement);
return;
})
.catch(Notification.exception);
});
reportModal.show();
}
const reportDelete = event.target.closest(reportSelectors.actions.reportDelete);
if (reportDelete) {
event.preventDefault();
// Use triggerElement to return focus to the action menu toggle.
const triggerElement = reportDelete.closest('.dropdown').querySelector('.dropdown-toggle');
Notification.saveCancelPromise(
getString('deletereport', 'core_reportbuilder'),
getString('deletereportconfirm', 'core_reportbuilder', reportDelete.dataset.reportName),
getString('delete', 'core'),
{triggerElement}
).then(() => {
const pendingPromise = new Pending('core_reportbuilder/reports:delete');
const reportElement = event.target.closest(reportSelectors.regions.report);
return deleteReport(reportDelete.dataset.reportId)
.then(() => addToast(getString('reportdeleted', 'core_reportbuilder')))
.then(() => {
dispatchEvent(reportEvents.tableReload, {preservePagination: true}, reportElement);
return pendingPromise.resolve();
})
.catch(Notification.exception);
}).catch(() => {
return;
});
}
});
};
+194
View File
@@ -0,0 +1,194 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Report builder audiences
*
* @module core_reportbuilder/schedules
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
"use strict";
import {dispatchEvent} from 'core/event_dispatcher';
import 'core/inplace_editable';
import Notification from 'core/notification';
import Pending from 'core/pending';
import {prefetchStrings} from 'core/prefetch';
import {getString} from 'core/str';
import {add as addToast} from 'core/toast';
import * as reportEvents from 'core_reportbuilder/local/events';
import * as reportSelectors from 'core_reportbuilder/local/selectors';
import {createScheduleModal} from 'core_reportbuilder/local/repository/modals';
import {deleteSchedule, sendSchedule, toggleSchedule} from 'core_reportbuilder/local/repository/schedules';
let initialized = false;
/**
* Initialise schedules tab
*
* @param {Number} reportId
*/
export const init = reportId => {
prefetchStrings('core_reportbuilder', [
'deleteschedule',
'deletescheduleconfirm',
'disableschedule',
'editscheduledetails',
'enableschedule',
'newschedule',
'schedulecreated',
'scheduledeleted',
'schedulesent',
'scheduleupdated',
'sendschedule',
'sendscheduleconfirm',
]);
prefetchStrings('core', [
'confirm',
'delete',
]);
if (initialized) {
// We already added the event listeners (can be called multiple times by mustache template).
return;
}
document.addEventListener('click', event => {
// Create schedule.
const scheduleCreate = event.target.closest(reportSelectors.actions.scheduleCreate);
if (scheduleCreate) {
event.preventDefault();
const scheduleModal = createScheduleModal(event.target, getString('newschedule', 'core_reportbuilder'), reportId);
scheduleModal.addEventListener(scheduleModal.events.FORM_SUBMITTED, () => {
getString('schedulecreated', 'core_reportbuilder')
.then(addToast)
.then(() => {
const reportElement = document.querySelector(reportSelectors.regions.report);
dispatchEvent(reportEvents.tableReload, {}, reportElement);
return;
})
.catch(Notification.exception);
});
scheduleModal.show();
}
// Toggle schedule.
const scheduleToggle = event.target.closest(reportSelectors.actions.scheduleToggle);
if (scheduleToggle) {
const pendingPromise = new Pending('core_reportbuilder/schedules:toggle');
const scheduleStateToggle = +!Number(scheduleToggle.dataset.state);
toggleSchedule(reportId, scheduleToggle.dataset.id, scheduleStateToggle)
.then(() => {
const tableRow = scheduleToggle.closest('tr');
tableRow.classList.toggle('text-muted');
scheduleToggle.dataset.state = scheduleStateToggle;
const stringKey = scheduleStateToggle ? 'disableschedule' : 'enableschedule';
return getString(stringKey, 'core_reportbuilder');
})
.then(toggleLabel => {
const labelContainer = scheduleToggle.parentElement.querySelector(`label[for="${scheduleToggle.id}"] > span`);
labelContainer.innerHTML = toggleLabel;
return pendingPromise.resolve();
})
.catch(Notification.exception);
}
// Edit schedule.
const scheduleEdit = event.target.closest(reportSelectors.actions.scheduleEdit);
if (scheduleEdit) {
event.preventDefault();
// Use triggerElement to return focus to the action menu toggle.
const triggerElement = scheduleEdit.closest('.dropdown').querySelector('.dropdown-toggle');
const scheduleModal = createScheduleModal(triggerElement, getString('editscheduledetails', 'core_reportbuilder'),
reportId, scheduleEdit.dataset.scheduleId);
scheduleModal.addEventListener(scheduleModal.events.FORM_SUBMITTED, () => {
getString('scheduleupdated', 'core_reportbuilder')
.then(addToast)
.then(() => {
const reportElement = scheduleEdit.closest(reportSelectors.regions.report);
dispatchEvent(reportEvents.tableReload, {}, reportElement);
return;
})
.catch(Notification.exception);
});
scheduleModal.show();
}
// Send schedule.
const scheduleSend = event.target.closest(reportSelectors.actions.scheduleSend);
if (scheduleSend) {
event.preventDefault();
// Use triggerElement to return focus to the action menu toggle.
const triggerElement = scheduleSend.closest('.dropdown').querySelector('.dropdown-toggle');
Notification.saveCancelPromise(
getString('sendschedule', 'core_reportbuilder'),
getString('sendscheduleconfirm', 'core_reportbuilder', scheduleSend.dataset.scheduleName),
getString('confirm', 'core'),
{triggerElement}
).then(() => {
const pendingPromise = new Pending('core_reportbuilder/schedules:send');
return sendSchedule(reportId, scheduleSend.dataset.scheduleId)
.then(addToast(getString('schedulesent', 'core_reportbuilder')))
.then(() => pendingPromise.resolve())
.catch(Notification.exception);
}).catch(() => {
return;
});
}
// Delete schedule.
const scheduleDelete = event.target.closest(reportSelectors.actions.scheduleDelete);
if (scheduleDelete) {
event.preventDefault();
// Use triggerElement to return focus to the action menu toggle.
const triggerElement = scheduleDelete.closest('.dropdown').querySelector('.dropdown-toggle');
Notification.saveCancelPromise(
getString('deleteschedule', 'core_reportbuilder'),
getString('deletescheduleconfirm', 'core_reportbuilder', scheduleDelete.dataset.scheduleName),
getString('delete', 'core'),
{triggerElement}
).then(() => {
const pendingPromise = new Pending('core_reportbuilder/schedules:delete');
return deleteSchedule(reportId, scheduleDelete.dataset.scheduleId)
.then(addToast(getString('scheduledeleted', 'core_reportbuilder')))
.then(() => {
const reportElement = scheduleDelete.closest(reportSelectors.regions.report);
dispatchEvent(reportEvents.tableReload, {preservePagination: true}, reportElement);
return pendingPromise.resolve();
})
.catch(Notification.exception);
}).catch(() => {
return;
});
}
});
initialized = true;
};
+101
View File
@@ -0,0 +1,101 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Report builder sidebar component
*
* @module core_reportbuilder/sidebar
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import Pending from 'core/pending';
import {debounce} from 'core/utils';
import * as reportSelectors from 'core_reportbuilder/local/selectors';
const DEBOUNCE_TIMER = 250;
const CLASSES = {
EXPANDED: 'show',
COLLAPSED: 'collapsed',
HIDE: 'd-none',
};
/**
* Initialise module
*
* @param {Event} event
* @param {Element} sidebarMenu
*/
const sidebarCardFilter = (event, sidebarMenu) => {
const pendingPromise = new Pending('core_reportbuilder/sidebar:cardFilter');
const sidebarCards = sidebarMenu.querySelectorAll(reportSelectors.regions.sidebarCard);
const sidebarItems = sidebarMenu.querySelectorAll(reportSelectors.regions.sidebarItem);
const searchTerm = event.target.value.toLowerCase();
// Toggle items according to match against search term.
sidebarItems.forEach(item => {
const itemContent = item.textContent.toLowerCase();
item.classList.toggle(CLASSES.HIDE, !itemContent.includes(searchTerm));
});
// Toggle cards according to whether they have any visible items.
sidebarCards.forEach(card => {
const visibleItems = card.querySelectorAll(`${reportSelectors.regions.sidebarItem}:not(.${CLASSES.HIDE})`);
card.classList.toggle(CLASSES.HIDE, !visibleItems.length);
expandCard(card);
});
pendingPromise.resolve();
};
/**
* Show a collapsed card.
* This function simulates the behaviour of JQuery show method on a collapsible element.
*
* @param {Element} card
*/
const expandCard = (card) => {
let cardButton = card.querySelector('[data-toggle="collapse"]');
if (cardButton.classList.contains(CLASSES.COLLAPSED)) {
cardButton.classList.remove(CLASSES.COLLAPSED);
cardButton.setAttribute('aria-expanded', "true");
let cardContent = card.querySelector(cardButton.dataset.target);
cardContent.classList.add(CLASSES.EXPANDED);
}
};
/**
* Initialise module
*
* @param {string} selectorId
*/
export const init = (selectorId) => {
const sidebarMenu = document.querySelector(selectorId + reportSelectors.regions.sidebarMenu);
const sidebarSearch = sidebarMenu.querySelector(reportSelectors.actions.sidebarSearch);
// Debounce the event listener to allow the user to finish typing.
const sidebarSearchDebounce = debounce(sidebarCardFilter, DEBOUNCE_TIMER);
sidebarSearch.addEventListener('keyup', event => {
const pendingPromise = new Pending('core_reportbuilder/sidebar:keyup');
sidebarSearchDebounce(event, sidebarMenu);
setTimeout(() => {
pendingPromise.resolve();
}, DEBOUNCE_TIMER);
});
};
+442
View File
@@ -0,0 +1,442 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_reportbuilder;
use coding_exception;
use core_reportbuilder\local\helpers\report;
use core_reportbuilder\local\models\column as column_model;
use core_reportbuilder\local\models\filter as filter_model;
use core_reportbuilder\local\report\base;
use core_reportbuilder\local\report\column;
use core_reportbuilder\local\report\filter;
/**
* Class datasource
*
* @package core_reportbuilder
* @copyright 2021 David Matamoros <davidmc@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class datasource extends base {
/** @var float[] $elementsmodified Track the time elements of specific reports have been added, updated, removed */
private static $elementsmodified = [];
/** @var array $activecolumns */
private $activecolumns;
/** @var array $activefilters */
private $activefilters;
/** @var array $activeconditions */
private $activeconditions;
/**
* Add columns from the given entity name to be available to use in a custom report
*
* Wildcard matching is supported with '*' in both $include and $exclude, e.g. ['customfield*']
*
* @param string $entityname
* @param string[] $include Include only these columns, if omitted then include all
* @param string[] $exclude Exclude these columns, if omitted then exclude none
* @throws coding_exception If both $include and $exclude are non-empty
*/
final protected function add_columns_from_entity(string $entityname, array $include = [], array $exclude = []): void {
if (!empty($include) && !empty($exclude)) {
throw new coding_exception('Cannot specify columns to include and exclude simultaneously');
}
$entity = $this->get_entity($entityname);
// Retrieve filtered columns from entity, respecting given $include/$exclude parameters.
$columns = array_filter($entity->get_columns(), function(column $column) use ($include, $exclude): bool {
if (!empty($include)) {
return $this->report_element_search($column->get_name(), $include);
}
if (!empty($exclude)) {
return !$this->report_element_search($column->get_name(), $exclude);
}
return true;
});
foreach ($columns as $column) {
$this->add_column($column);
}
}
/**
* Add default datasource columns to the report
*
* Uses column data returned by the source {@see get_default_columns} and {@see get_default_column_sorting} methods
*
* @throws coding_exception If default column sorting refers to an invalid column
*/
public function add_default_columns(): void {
$reportid = $this->get_report_persistent()->get('id');
// Retrieve default column sorting, and track index of both sorted/non-sorted columns.
$columnidentifiers = $this->get_default_columns();
$defaultcolumnsorting = $this->get_default_column_sorting();
$defaultcolumnsortinginvalid = array_diff_key($defaultcolumnsorting,
array_fill_keys($columnidentifiers, 1));
if (count($defaultcolumnsortinginvalid) > 0) {
throw new coding_exception('Invalid column name', array_key_first($defaultcolumnsortinginvalid));
}
$columnnonsortingindex = count($defaultcolumnsorting) + 1;
foreach ($columnidentifiers as $uniqueidentifier) {
$column = report::add_report_column($reportid, $uniqueidentifier);
// After adding the column, toggle sorting according to defaults provided by the datasource.
$sortorder = array_search($uniqueidentifier, array_keys($defaultcolumnsorting));
if ($sortorder !== false) {
$column->set_many([
'sortenabled' => true,
'sortdirection' => $defaultcolumnsorting[$uniqueidentifier],
'sortorder' => $sortorder + 1,
])->update();
} else if (!empty($defaultcolumnsorting)) {
$column->set('sortorder', $columnnonsortingindex++)->update();
}
}
}
/**
* Return the default columns that will be added to the report upon creation, by {@see add_default_columns}
*
* @return string[]
*/
abstract public function get_default_columns(): array;
/**
* Return the default column sorting that will be set for the report upon creation, by {@see add_default_columns}
*
* When overriding this method in child classes, column identifiers specified must refer to default columns returned from
* the {@see get_default_columns} method
*
* @return int[] array [column identifier => SORT_ASC/SORT_DESC]
*/
public function get_default_column_sorting(): array {
return [];
}
/**
* Override parent method, returning only those columns specifically added to the custom report (rather than all that are
* available)
*
* @return column[]
*/
public function get_active_columns(): array {
$reportid = $this->get_report_persistent()->get('id');
// Determine whether we already retrieved the columns since the report was last modified.
self::$elementsmodified += [$reportid => -1];
if ($this->activecolumns !== null && $this->activecolumns['builttime'] > self::$elementsmodified[$reportid]) {
return $this->activecolumns['values'];
}
$this->activecolumns = ['builttime' => microtime(true), 'values' => []];
$activecolumns = column_model::get_records(['reportid' => $reportid], 'columnorder');
foreach ($activecolumns as $index => $column) {
$instance = $this->get_column($column->get('uniqueidentifier'));
// Ensure the column is still present and available.
if ($instance !== null && $instance->get_is_available()) {
if ($instance->get_is_deprecated()) {
debugging("The column '{$instance->get_unique_identifier()}' is deprecated, please do not use it any more." .
" {$instance->get_is_deprecated_message()}", DEBUG_DEVELOPER);
}
// We should clone the report column to ensure if it's added twice to a report, each operates independently.
$this->activecolumns['values'][] = clone $instance
->set_index($index)
->set_persistent($column)
->set_aggregation($column->get('aggregation'));
}
}
return $this->activecolumns['values'];
}
/**
* Add filters from the given entity name to be available to use in a custom report
*
* Wildcard matching is supported with '*' in both $include and $exclude, e.g. ['customfield*']
*
* @param string $entityname
* @param string[] $include Include only these filters, if omitted then include all
* @param string[] $exclude Exclude these filters, if omitted then exclude none
* @throws coding_exception If both $include and $exclude are non-empty
*/
final protected function add_filters_from_entity(string $entityname, array $include = [], array $exclude = []): void {
if (!empty($include) && !empty($exclude)) {
throw new coding_exception('Cannot specify filters to include and exclude simultaneously');
}
$entity = $this->get_entity($entityname);
// Retrieve filtered filters from entity, respecting given $include/$exclude parameters.
$filters = array_filter($entity->get_filters(), function(filter $filter) use ($include, $exclude): bool {
if (!empty($include)) {
return $this->report_element_search($filter->get_name(), $include);
}
if (!empty($exclude)) {
return !$this->report_element_search($filter->get_name(), $exclude);
}
return true;
});
foreach ($filters as $filter) {
$this->add_filter($filter);
}
}
/**
* Add default datasource filters to the report
*
* This method is optional and can be called when the report is created to add the default filters defined in the
* selected datasource.
*/
public function add_default_filters(): void {
$reportid = $this->get_report_persistent()->get('id');
$filteridentifiers = $this->get_default_filters();
foreach ($filteridentifiers as $uniqueidentifier) {
report::add_report_filter($reportid, $uniqueidentifier);
}
}
/**
* Return the filters that will be added to the report once is created
*
* @return string[]
*/
abstract public function get_default_filters(): array;
/**
* Override parent method, returning only those filters specifically added to the custom report (rather than all that are
* available)
*
* @return filter[]
*/
public function get_active_filters(): array {
$reportid = $this->get_report_persistent()->get('id');
// Determine whether we already retrieved the filters since the report was last modified.
self::$elementsmodified += [$reportid => -1];
if ($this->activefilters !== null && $this->activefilters['builttime'] > self::$elementsmodified[$reportid]) {
return $this->activefilters['values'];
}
$this->activefilters = ['builttime' => microtime(true), 'values' => []];
$activefilters = filter_model::get_filter_records($reportid, 'filterorder');
foreach ($activefilters as $filter) {
$instance = $this->get_filter($filter->get('uniqueidentifier'));
// Ensure the filter is still present and available.
if ($instance !== null && $instance->get_is_available()) {
if ($instance->get_is_deprecated()) {
debugging("The filter '{$instance->get_unique_identifier()}' is deprecated, please do not use it any more." .
" {$instance->get_is_deprecated_message()}", DEBUG_DEVELOPER);
}
$this->activefilters['values'][$instance->get_unique_identifier()] =
$instance->set_persistent($filter);
}
}
return $this->activefilters['values'];
}
/**
* Add conditions from the given entity name to be available to use in a custom report
*
* Wildcard matching is supported with '*' in both $include and $exclude, e.g. ['customfield*']
*
* @param string $entityname
* @param string[] $include Include only these conditions, if omitted then include all
* @param string[] $exclude Exclude these conditions, if omitted then exclude none
* @throws coding_exception If both $include and $exclude are non-empty
*/
final protected function add_conditions_from_entity(string $entityname, array $include = [], array $exclude = []): void {
if (!empty($include) && !empty($exclude)) {
throw new coding_exception('Cannot specify conditions to include and exclude simultaneously');
}
$entity = $this->get_entity($entityname);
// Retrieve filtered conditions from entity, respecting given $include/$exclude parameters.
$conditions = array_filter($entity->get_conditions(), function(filter $condition) use ($include, $exclude): bool {
if (!empty($include)) {
return $this->report_element_search($condition->get_name(), $include);
}
if (!empty($exclude)) {
return !$this->report_element_search($condition->get_name(), $exclude);
}
return true;
});
foreach ($conditions as $condition) {
$this->add_condition($condition);
}
}
/**
* Add default datasource conditions to the report
*
* This method is optional and can be called when the report is created to add the default conditions defined in the
* selected datasource.
*/
public function add_default_conditions(): void {
$reportid = $this->get_report_persistent()->get('id');
$conditionidentifiers = $this->get_default_conditions();
foreach ($conditionidentifiers as $uniqueidentifier) {
report::add_report_condition($reportid, $uniqueidentifier);
}
// Set the default condition values if they have been set in the datasource.
$this->set_condition_values($this->get_default_condition_values());
}
/**
* Return the conditions that will be added to the report once is created
*
* @return string[]
*/
abstract public function get_default_conditions(): array;
/**
* Return the default condition values that will be added to the report once is created
*
* For any of the default conditions returned by the method {@see get_default_conditions} is
* possible to set the initial values.
*
* @return array
*/
public function get_default_condition_values(): array {
return [];
}
/**
* Override parent method, returning only those conditions specifically added to the custom report (rather than all that are
* available)
*
* @return filter[]
*/
public function get_active_conditions(): array {
$reportid = $this->get_report_persistent()->get('id');
// Determine whether we already retrieved the conditions since the report was last modified.
self::$elementsmodified += [$reportid => -1];
if ($this->activeconditions !== null && $this->activeconditions['builttime'] > self::$elementsmodified[$reportid]) {
return $this->activeconditions['values'];
}
$this->activeconditions = ['builttime' => microtime(true), 'values' => []];
$activeconditions = filter_model::get_condition_records($reportid, 'filterorder');
foreach ($activeconditions as $condition) {
$instance = $this->get_condition($condition->get('uniqueidentifier'));
// Ensure the condition is still present and available.
if ($instance !== null && $instance->get_is_available()) {
if ($instance->get_is_deprecated()) {
debugging("The condition '{$instance->get_unique_identifier()}' is deprecated, please do not use it any more." .
" {$instance->get_is_deprecated_message()}", DEBUG_DEVELOPER);
}
$this->activeconditions['values'][$instance->get_unique_identifier()] =
$instance->set_persistent($condition);
}
}
return $this->activeconditions['values'];
}
/**
* Adds all columns/filters/conditions from the given entity to the report at once
*
* @param string $entityname
* @param string[] $limitcolumns Include only these columns
* @param string[] $limitfilters Include only these filters
* @param string[] $limitconditions Include only these conditions
*/
final protected function add_all_from_entity(
string $entityname,
array $limitcolumns = [],
array $limitfilters = [],
array $limitconditions = [],
): void {
$this->add_columns_from_entity($entityname, $limitcolumns);
$this->add_filters_from_entity($entityname, $limitfilters);
$this->add_conditions_from_entity($entityname, $limitconditions);
}
/**
* Adds all columns/filters/conditions from all the entities added to the report at once
*/
final protected function add_all_from_entities(): void {
foreach ($this->get_entities() as $entity) {
$this->add_all_from_entity($entity->get_entity_name());
}
}
/**
* Indicate that report elements have been modified, e.g. columns/filters/conditions have been added, removed or updated
*
* @param int $reportid
*/
final public static function report_elements_modified(int $reportid): void {
self::$elementsmodified[$reportid] = microtime(true);
}
/**
* Search for given element within list of search items, supporting '*' wildcards
*
* @param string $element
* @param string[] $search
* @return bool
*/
private function report_element_search(string $element, array $search): bool {
foreach ($search as $item) {
// Simple matching.
if ($element === $item) {
return true;
}
// Wildcard matching.
if (strpos($item, '*') !== false) {
$pattern = '/^' . str_replace('\*', '.*', preg_quote($item)) . '$/';
return (bool) preg_match($pattern, $element);
}
}
return false;
}
}
@@ -0,0 +1,111 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_reportbuilder\event;
use coding_exception;
use core\event\base;
use core_reportbuilder\local\models\audience;
use moodle_url;
/**
* Report builder custom report audience created event class.
*
* @package core_reportbuilder
* @copyright 2021 David Matamoros <davidmc@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*
* @property-read array $other {
* Extra information about the event.
*
* - int reportid: The id of the report
* }
*/
class audience_created extends base {
/**
* Initialise the event data.
*/
protected function init() {
$this->data['objecttable'] = audience::TABLE;
$this->data['crud'] = 'c';
$this->data['edulevel'] = self::LEVEL_OTHER;
}
/**
* Creates an instance from a report audience object
*
* @param audience $audience
* @return self
*/
public static function create_from_object(audience $audience): self {
$eventparams = [
'context' => $audience->get_report()->get_context(),
'objectid' => $audience->get('id'),
'other' => [
'reportid' => $audience->get('reportid'),
]
];
$event = self::create($eventparams);
$event->add_record_snapshot($event->objecttable, $audience->to_record());
return $event;
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('audiencecreated', 'core_reportbuilder');
}
/**
* Returns non-localised description of what happened.
*
* @return string
*/
public function get_description() {
$reportid = $this->other['reportid'];
return "The user with id '$this->userid' created an audience in the custom report with id '$reportid'.";
}
/**
* Custom validations.
*
* @throws coding_exception
*/
protected function validate_data(): void {
parent::validate_data();
if (!isset($this->objectid)) {
throw new coding_exception('The \'objectid\' must be set.');
}
if (!isset($this->other['reportid'])) {
throw new coding_exception('The \'reportid\' must be set in other.');
}
}
/**
* Returns relevant URL.
*
* @return moodle_url
*/
public function get_url(): moodle_url {
return new moodle_url('/reportbuilder/edit.php', ['id' => $this->other['reportid']], 'audience');
}
}
@@ -0,0 +1,112 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_reportbuilder\event;
use coding_exception;
use core\event\base;
use core_reportbuilder\local\models\audience;
use moodle_url;
/**
* Report builder custom report audience deleted event class.
*
* @package core_reportbuilder
* @copyright 2021 David Matamoros <davidmc@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*
* @property-read array $other {
* Extra information about the event.
*
* - int reportid: The id of the report
* }
*/
class audience_deleted extends base {
/**
* Initialise the event data.
*/
protected function init() {
$this->data['objecttable'] = audience::TABLE;
$this->data['crud'] = 'd';
$this->data['edulevel'] = self::LEVEL_OTHER;
}
/**
* Creates an instance from a report audience object
*
* @param audience $audience
* @return self
*/
public static function create_from_object(audience $audience): self {
$eventparams = [
'context' => $audience->get_report()->get_context(),
'objectid' => $audience->get('id'),
'other' => [
'reportid' => $audience->get('reportid'),
]
];
$event = self::create($eventparams);
$event->add_record_snapshot($event->objecttable, $audience->to_record());
return $event;
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('audiencedeletedevent', 'core_reportbuilder');
}
/**
* Returns non-localised description of what happened.
*
* @return string
*/
public function get_description() {
$reportid = $this->other['reportid'];
return "The user with id '$this->userid' deleted the audience with id '$this->objectid' in the custom report" .
" with id '$reportid'.";
}
/**
* Custom validations.
*
* @throws coding_exception
*/
protected function validate_data(): void {
parent::validate_data();
if (!isset($this->objectid)) {
throw new coding_exception('The \'objectid\' must be set.');
}
if (!isset($this->other['reportid'])) {
throw new coding_exception('The \'reportid\' must be set in other.');
}
}
/**
* Returns relevant URL.
*
* @return moodle_url
*/
public function get_url(): moodle_url {
return new moodle_url('/reportbuilder/edit.php', ['id' => $this->other['reportid']], 'audience');
}
}
@@ -0,0 +1,112 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_reportbuilder\event;
use coding_exception;
use core\event\base;
use core_reportbuilder\local\models\audience;
use moodle_url;
/**
* Report builder custom report audience created event class.
*
* @package core_reportbuilder
* @copyright 2021 David Matamoros <davidmc@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*
* @property-read array $other {
* Extra information about the event.
*
* - int reportid: The id of the report
* }
*/
class audience_updated extends base {
/**
* Initialise the event data.
*/
protected function init() {
$this->data['objecttable'] = audience::TABLE;
$this->data['crud'] = 'u';
$this->data['edulevel'] = self::LEVEL_OTHER;
}
/**
* Creates an instance from a report audience object
*
* @param audience $audience
* @return self
*/
public static function create_from_object(audience $audience): self {
$eventparams = [
'context' => $audience->get_report()->get_context(),
'objectid' => $audience->get('id'),
'other' => [
'reportid' => $audience->get('reportid'),
]
];
$event = self::create($eventparams);
$event->add_record_snapshot($event->objecttable, $audience->to_record());
return $event;
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('audienceupdated', 'core_reportbuilder');
}
/**
* Returns non-localised description of what happened.
*
* @return string
*/
public function get_description() {
$reportid = $this->other['reportid'];
return "The user with id '$this->userid' updated the audience with id '$this->objectid' in the custom report" .
" with id '$reportid'.";
}
/**
* Custom validations.
*
* @throws coding_exception
*/
protected function validate_data(): void {
parent::validate_data();
if (!isset($this->objectid)) {
throw new coding_exception('The \'objectid\' must be set.');
}
if (!isset($this->other['reportid'])) {
throw new coding_exception('The \'reportid\' must be set in other.');
}
}
/**
* Returns relevant URL.
*
* @return moodle_url
*/
public function get_url(): moodle_url {
return new moodle_url('/reportbuilder/edit.php', ['id' => $this->other['reportid']], 'audience');
}
}
@@ -0,0 +1,109 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_reportbuilder\event;
use coding_exception;
use core\event\base;
use core_reportbuilder\local\models\report;
use moodle_url;
/**
* Report builder custom report created event class.
*
* @package core_reportbuilder
* @copyright 2021 David Matamoros <davidmc@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*
* @property-read array $other {
* Extra information about the event.
*
* - string name: The name of the report
* - string source: The report source class
* }
*/
class report_created extends base {
/**
* Initialise the event data.
*/
protected function init() {
$this->data['objecttable'] = report::TABLE;
$this->data['crud'] = 'c';
$this->data['edulevel'] = self::LEVEL_OTHER;
}
/**
* Creates an instance from a report object
*
* @param report $report
* @return self
*/
public static function create_from_object(report $report): self {
$eventparams = [
'context' => $report->get_context(),
'objectid' => $report->get('id'),
'other' => [
'name' => $report->get('name'),
'source' => $report->get('source'),
]
];
$event = self::create($eventparams);
$event->add_record_snapshot($event->objecttable, $report->to_record());
return $event;
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('reportcreated', 'core_reportbuilder');
}
/**
* Returns non-localised description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' created the custom report with id '$this->objectid'.";
}
/**
* Custom validations.
*
* @throws coding_exception
*/
protected function validate_data(): void {
parent::validate_data();
if (!isset($this->objectid)) {
throw new coding_exception('The \'objectid\' must be set.');
}
}
/**
* Returns relevant URL.
*
* @return moodle_url
*/
public function get_url(): moodle_url {
return new moodle_url('/reportbuilder/edit.php', ['id' => $this->objectid]);
}
}
@@ -0,0 +1,99 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_reportbuilder\event;
use coding_exception;
use core\event\base;
use core_reportbuilder\local\models\report;
/**
* Report builder custom report deleted event class.
*
* @package core_reportbuilder
* @copyright 2021 David Matamoros <davidmc@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*
* @property-read array $other {
* Extra information about the event.
*
* - string name: The name of the report
* - string source: The report source class
* }
*/
class report_deleted extends base {
/**
* Initialise the event data.
*/
protected function init() {
$this->data['objecttable'] = report::TABLE;
$this->data['crud'] = 'd';
$this->data['edulevel'] = self::LEVEL_OTHER;
}
/**
* Creates an instance from a report object
*
* @param report $report
* @return self
*/
public static function create_from_object(report $report): self {
$eventparams = [
'context' => $report->get_context(),
'objectid' => $report->get('id'),
'other' => [
'name' => $report->get('name'),
'source' => $report->get('source'),
]
];
$event = self::create($eventparams);
$event->add_record_snapshot($event->objecttable, $report->to_record());
return $event;
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('reportdeleted', 'core_reportbuilder');
}
/**
* Returns non-localised description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' deleted the custom report with id '$this->objectid'.";
}
/**
* Custom validations.
*
* @throws coding_exception
*/
protected function validate_data(): void {
parent::validate_data();
if (!isset($this->objectid)) {
throw new coding_exception('The \'objectid\' must be set.');
}
}
}
@@ -0,0 +1,109 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_reportbuilder\event;
use coding_exception;
use core\event\base;
use core_reportbuilder\local\models\report;
use moodle_url;
/**
* Report builder custom report updated event class.
*
* @package core_reportbuilder
* @copyright 2021 David Matamoros <davidmc@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*
* @property-read array $other {
* Extra information about the event.
*
* - string name: The name of the report
* - string source: The report source class
* }
*/
class report_updated extends base {
/**
* Initialise the event data.
*/
protected function init() {
$this->data['objecttable'] = report::TABLE;
$this->data['crud'] = 'u';
$this->data['edulevel'] = self::LEVEL_OTHER;
}
/**
* Creates an instance from a report object
*
* @param report $report
* @return self
*/
public static function create_from_object(report $report): self {
$eventparams = [
'context' => $report->get_context(),
'objectid' => $report->get('id'),
'other' => [
'name' => $report->get('name'),
'source' => $report->get('source'),
]
];
$event = self::create($eventparams);
$event->add_record_snapshot($event->objecttable, $report->to_record());
return $event;
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('reportupdated', 'core_reportbuilder');
}
/**
* Returns non-localised description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' updated the custom report with id '$this->objectid'.";
}
/**
* Custom validations.
*
* @throws coding_exception
*/
protected function validate_data(): void {
parent::validate_data();
if (!isset($this->objectid)) {
throw new coding_exception('The \'objectid\' must be set.');
}
}
/**
* Returns relevant URL.
*
* @return moodle_url
*/
public function get_url(): moodle_url {
return new moodle_url('/reportbuilder/edit.php', ['id' => $this->objectid]);
}
}
@@ -0,0 +1,109 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_reportbuilder\event;
use coding_exception;
use core\event\base;
use core_reportbuilder\local\models\report;
use moodle_url;
/**
* Report builder custom report viewed event class.
*
* @package core_reportbuilder
* @copyright 2021 David Matamoros <davidmc@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*
* @property-read array $other {
* Extra information about the event.
*
* - string name: The name of the report
* - string source: The report source class
* }
*/
class report_viewed extends base {
/**
* Initialise the event data.
*/
protected function init() {
$this->data['objecttable'] = report::TABLE;
$this->data['crud'] = 'r';
$this->data['edulevel'] = self::LEVEL_OTHER;
}
/**
* Creates an instance from a report object
*
* @param report $report
* @return self
*/
public static function create_from_object(report $report): self {
$eventparams = [
'context' => $report->get_context(),
'objectid' => $report->get('id'),
'other' => [
'name' => $report->get('name'),
'source' => $report->get('source'),
]
];
$event = self::create($eventparams);
$event->add_record_snapshot($event->objecttable, $report->to_record());
return $event;
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('reportviewed', 'core_reportbuilder');
}
/**
* Returns non-localised description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' viewed the custom report with id '$this->objectid'.";
}
/**
* Custom validations.
*
* @throws coding_exception
*/
protected function validate_data(): void {
parent::validate_data();
if (!isset($this->objectid)) {
throw new coding_exception('The \'objectid\' must be set.');
}
}
/**
* Returns relevant URL.
*
* @return moodle_url
*/
public function get_url(): moodle_url {
return new moodle_url('/reportbuilder/view.php', ['id' => $this->objectid]);
}
}
@@ -0,0 +1,111 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_reportbuilder\event;
use coding_exception;
use core\event\base;
use core_reportbuilder\local\models\schedule;
use moodle_url;
/**
* Report builder custom report schedule created event class.
*
* @package core_reportbuilder
* @copyright 2021 David Matamoros <davidmc@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*
* @property-read array $other {
* Extra information about the event.
*
* - int reportid: The id of the report
* }
*/
class schedule_created extends base {
/**
* Initialise the event data.
*/
protected function init() {
$this->data['objecttable'] = schedule::TABLE;
$this->data['crud'] = 'c';
$this->data['edulevel'] = self::LEVEL_OTHER;
}
/**
* Creates an instance from a report schedule object
*
* @param schedule $schedule
* @return self
*/
public static function create_from_object(schedule $schedule): self {
$eventparams = [
'context' => $schedule->get_report()->get_context(),
'objectid' => $schedule->get('id'),
'other' => [
'reportid' => $schedule->get('reportid'),
]
];
$event = self::create($eventparams);
$event->add_record_snapshot($event->objecttable, $schedule->to_record());
return $event;
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('schedulecreated', 'core_reportbuilder');
}
/**
* Returns non-localised description of what happened.
*
* @return string
*/
public function get_description() {
$reportid = $this->other['reportid'];
return "The user with id '$this->userid' created a schedule in the custom report with id '$reportid'.";
}
/**
* Custom validations.
*
* @throws coding_exception
*/
protected function validate_data(): void {
parent::validate_data();
if (!isset($this->objectid)) {
throw new coding_exception('The \'objectid\' must be set.');
}
if (!isset($this->other['reportid'])) {
throw new coding_exception('The \'reportid\' must be set in other.');
}
}
/**
* Returns relevant URL.
*
* @return moodle_url
*/
public function get_url(): moodle_url {
return new moodle_url('/reportbuilder/edit.php', ['id' => $this->other['reportid']], 'schedules');
}
}
@@ -0,0 +1,112 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_reportbuilder\event;
use coding_exception;
use core\event\base;
use core_reportbuilder\local\models\schedule;
use moodle_url;
/**
* Report builder custom report schedule created event class.
*
* @package core_reportbuilder
* @copyright 2021 David Matamoros <davidmc@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*
* @property-read array $other {
* Extra information about the event.
*
* - int reportid: The id of the report
* }
*/
class schedule_deleted extends base {
/**
* Initialise the event data.
*/
protected function init() {
$this->data['objecttable'] = schedule::TABLE;
$this->data['crud'] = 'd';
$this->data['edulevel'] = self::LEVEL_OTHER;
}
/**
* Creates an instance from a report schedule object
*
* @param schedule $schedule
* @return self
*/
public static function create_from_object(schedule $schedule): self {
$eventparams = [
'context' => $schedule->get_report()->get_context(),
'objectid' => $schedule->get('id'),
'other' => [
'reportid' => $schedule->get('reportid'),
]
];
$event = self::create($eventparams);
$event->add_record_snapshot($event->objecttable, $schedule->to_record());
return $event;
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('scheduledeleted', 'core_reportbuilder');
}
/**
* Returns non-localised description of what happened.
*
* @return string
*/
public function get_description() {
$reportid = $this->other['reportid'];
return "The user with id '$this->userid' deleted the schedule with id '$this->objectid' in the custom report" .
" with id '$reportid'.";
}
/**
* Custom validations.
*
* @throws coding_exception
*/
protected function validate_data(): void {
parent::validate_data();
if (!isset($this->objectid)) {
throw new coding_exception('The \'objectid\' must be set.');
}
if (!isset($this->other['reportid'])) {
throw new coding_exception('The \'reportid\' must be set in other.');
}
}
/**
* Returns relevant URL.
*
* @return moodle_url
*/
public function get_url(): moodle_url {
return new moodle_url('/reportbuilder/edit.php', ['id' => $this->other['reportid']], 'schedules');
}
}
@@ -0,0 +1,112 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_reportbuilder\event;
use coding_exception;
use core\event\base;
use core_reportbuilder\local\models\schedule;
use moodle_url;
/**
* Report builder custom report schedule updated event class.
*
* @package core_reportbuilder
* @copyright 2021 David Matamoros <davidmc@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*
* @property-read array $other {
* Extra information about the event.
*
* - int reportid: The id of the report
* }
*/
class schedule_updated extends base {
/**
* Initialise the event data.
*/
protected function init() {
$this->data['objecttable'] = schedule::TABLE;
$this->data['crud'] = 'u';
$this->data['edulevel'] = self::LEVEL_OTHER;
}
/**
* Creates an instance from a report schedule object
*
* @param schedule $schedule
* @return self
*/
public static function create_from_object(schedule $schedule): self {
$eventparams = [
'context' => $schedule->get_report()->get_context(),
'objectid' => $schedule->get('id'),
'other' => [
'reportid' => $schedule->get('reportid'),
]
];
$event = self::create($eventparams);
$event->add_record_snapshot($event->objecttable, $schedule->to_record());
return $event;
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('scheduleupdated', 'core_reportbuilder');
}
/**
* Returns non-localised description of what happened.
*
* @return string
*/
public function get_description() {
$reportid = $this->other['reportid'];
return "The user with id '$this->userid' updated the schedule with id '$this->objectid' in the custom report" .
" with id '$reportid'.";
}
/**
* Custom validations.
*
* @throws coding_exception
*/
protected function validate_data(): void {
parent::validate_data();
if (!isset($this->objectid)) {
throw new coding_exception('The \'objectid\' must be set.');
}
if (!isset($this->other['reportid'])) {
throw new coding_exception('The \'reportid\' must be set in other.');
}
}
/**
* Returns relevant URL.
*
* @return moodle_url
*/
public function get_url(): moodle_url {
return new moodle_url('/reportbuilder/edit.php', ['id' => $this->other['reportid']], 'schedules');
}
}
+90
View File
@@ -0,0 +1,90 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_reportbuilder\external\audiences;
use core_reportbuilder\local\audiences\base;
use core_external\external_api;
use core_external\external_value;
use core_external\external_function_parameters;
use core_reportbuilder\manager;
use core_reportbuilder\permission;
/**
* External method for deleting a report audience
*
* @package core_reportbuilder
* @copyright 2021 David Matamoros <davidmc@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class delete extends external_api {
/**
* Describes the parameters for get_users_courses.
*
* @return external_function_parameters
*/
public static function execute_parameters(): external_function_parameters {
return new external_function_parameters(
[
'reportid' => new external_value(PARAM_INT, 'Report id'),
'instanceid' => new external_value(PARAM_INT, 'Audience instance id'),
]
);
}
/**
* External function to delete a report audience instance.
*
* @param int $reportid
* @param int $instanceid
* @return bool
*/
public static function execute(int $reportid, int $instanceid): bool {
[
'reportid' => $reportid,
'instanceid' => $instanceid,
] = self::validate_parameters(self::execute_parameters(), [
'reportid' => $reportid,
'instanceid' => $instanceid,
]);
$report = manager::get_report_from_id($reportid);
self::validate_context($report->get_context());
permission::require_can_edit_report($report->get_report_persistent());
$baseinstance = base::instance($instanceid);
if ($baseinstance && $baseinstance->user_can_edit()) {
$persistent = $baseinstance->get_persistent();
$persistent->delete();
return true;
}
return false;
}
/**
* Describes the data returned from the external function.
*
* @return external_value
*/
public static function execute_returns(): external_value {
return new external_value(PARAM_BOOL, '', VALUE_REQUIRED);
}
}
+91
View File
@@ -0,0 +1,91 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_reportbuilder\external\columns;
use core_reportbuilder\external\custom_report_columns_sorting_exporter;
use core_external\external_api;
use core_external\external_value;
use core_external\external_single_structure;
use core_external\external_function_parameters;
use core_reportbuilder\manager;
use core_reportbuilder\permission;
use core_reportbuilder\local\helpers\report;
/**
* External method for adding report columns
*
* @package core_reportbuilder
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class add extends external_api {
/**
* External method parameters
*
* @return external_function_parameters
*/
public static function execute_parameters(): external_function_parameters {
return new external_function_parameters([
'reportid' => new external_value(PARAM_INT, 'Report ID'),
'uniqueidentifier' => new external_value(PARAM_RAW, 'Unique identifier of the column'),
]);
}
/**
* External method execution
*
* @param int $reportid
* @param string $uniqueidentifier
* @return array
*/
public static function execute(int $reportid, string $uniqueidentifier): array {
global $PAGE;
[
'reportid' => $reportid,
'uniqueidentifier' => $uniqueidentifier,
] = self::validate_parameters(self::execute_parameters(), [
'reportid' => $reportid,
'uniqueidentifier' => $uniqueidentifier,
]);
$report = manager::get_report_from_id($reportid);
self::validate_context($report->get_context());
permission::require_can_edit_report($report->get_report_persistent());
report::add_report_column($reportid, $uniqueidentifier);
$exporter = new custom_report_columns_sorting_exporter(null, [
'report' => $report,
]);
return (array) $exporter->export($PAGE->get_renderer('core'));
}
/**
* External method return value
*
* @return external_single_structure
*/
public static function execute_returns(): external_single_structure {
return custom_report_columns_sorting_exporter::get_read_structure();
}
}
+91
View File
@@ -0,0 +1,91 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_reportbuilder\external\columns;
use core_reportbuilder\external\custom_report_columns_sorting_exporter;
use core_external\external_api;
use core_external\external_value;
use core_external\external_single_structure;
use core_external\external_function_parameters;
use core_reportbuilder\manager;
use core_reportbuilder\permission;
use core_reportbuilder\local\helpers\report;
/**
* External method for deleting report columns
*
* @package core_reportbuilder
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class delete extends external_api {
/**
* External method parameters
*
* @return external_function_parameters
*/
public static function execute_parameters(): external_function_parameters {
return new external_function_parameters([
'reportid' => new external_value(PARAM_INT, 'Report ID'),
'columnid' => new external_value(PARAM_INT, 'Column ID'),
]);
}
/**
* External method execution
*
* @param int $reportid
* @param int $columnid
* @return array
*/
public static function execute(int $reportid, int $columnid): array {
global $PAGE;
[
'reportid' => $reportid,
'columnid' => $columnid,
] = self::validate_parameters(self::execute_parameters(), [
'reportid' => $reportid,
'columnid' => $columnid,
]);
$report = manager::get_report_from_id($reportid);
self::validate_context($report->get_context());
permission::require_can_edit_report($report->get_report_persistent());
report::delete_report_column($reportid, $columnid);
$exporter = new custom_report_columns_sorting_exporter(null, [
'report' => $report,
]);
return (array) $exporter->export($PAGE->get_renderer('core'));
}
/**
* External method return value
*
* @return external_single_structure
*/
public static function execute_returns(): external_single_structure {
return custom_report_columns_sorting_exporter::get_read_structure();
}
}
+85
View File
@@ -0,0 +1,85 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_reportbuilder\external\columns;
use core_external\external_api;
use core_external\external_value;
use core_external\external_function_parameters;
use core_reportbuilder\manager;
use core_reportbuilder\permission;
use core_reportbuilder\local\helpers\report;
/**
* External method for re-ordering report columns
*
* @package core_reportbuilder
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class reorder extends external_api {
/**
* External method parameters
*
* @return external_function_parameters
*/
public static function execute_parameters(): external_function_parameters {
return new external_function_parameters([
'reportid' => new external_value(PARAM_INT, 'Report ID'),
'columnid' => new external_value(PARAM_INT, 'Column ID'),
'position' => new external_value(PARAM_INT, 'New column position')
]);
}
/**
* External method execution
*
* @param int $reportid
* @param int $columnid
* @param int $position
* @return bool
*/
public static function execute(int $reportid, int $columnid, int $position): bool {
[
'reportid' => $reportid,
'columnid' => $columnid,
'position' => $position,
] = self::validate_parameters(self::execute_parameters(), [
'reportid' => $reportid,
'columnid' => $columnid,
'position' => $position,
]);
$report = manager::get_report_from_id($reportid);
self::validate_context($report->get_context());
permission::require_can_edit_report($report->get_report_persistent());
return report::reorder_report_column($reportid, $columnid, $position);
}
/**
* External method return value
*
* @return external_value
*/
public static function execute_returns(): external_value {
return new external_value(PARAM_BOOL, 'Success');
}
}
+84
View File
@@ -0,0 +1,84 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_reportbuilder\external\columns\sort;
use core_external\external_api;
use core_external\external_value;
use core_external\external_single_structure;
use core_external\external_function_parameters;
use core_reportbuilder\manager;
use core_reportbuilder\permission;
use core_reportbuilder\external\custom_report_columns_sorting_exporter;
/**
* External method for retrieving report column sorting
*
* @package core_reportbuilder
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class get extends external_api {
/**
* External method parameters
*
* @return external_function_parameters
*/
public static function execute_parameters(): external_function_parameters {
return new external_function_parameters([
'reportid' => new external_value(PARAM_INT, 'Report ID'),
]);
}
/**
* External method execution
*
* @param int $reportid
* @return array
*/
public static function execute(int $reportid): array {
global $PAGE;
[
'reportid' => $reportid,
] = self::validate_parameters(self::execute_parameters(), [
'reportid' => $reportid,
]);
$report = manager::get_report_from_id($reportid);
self::validate_context($report->get_context());
permission::require_can_edit_report($report->get_report_persistent());
$exporter = new custom_report_columns_sorting_exporter(null, [
'report' => $report,
]);
return (array) $exporter->export($PAGE->get_renderer('core'));
}
/**
* External method return value
*
* @return external_single_structure
*/
public static function execute_returns(): external_single_structure {
return custom_report_columns_sorting_exporter::get_read_structure();
}
}
+95
View File
@@ -0,0 +1,95 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_reportbuilder\external\columns\sort;
use core_external\external_api;
use core_external\external_value;
use core_external\external_single_structure;
use core_external\external_function_parameters;
use core_reportbuilder\manager;
use core_reportbuilder\permission;
use core_reportbuilder\local\helpers\report;
use core_reportbuilder\external\custom_report_columns_sorting_exporter;
/**
* External method for re-ordering report column sorting
*
* @package core_reportbuilder
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class reorder extends external_api {
/**
* External method parameters
*
* @return external_function_parameters
*/
public static function execute_parameters(): external_function_parameters {
return new external_function_parameters([
'reportid' => new external_value(PARAM_INT, 'Report ID'),
'columnid' => new external_value(PARAM_INT, 'Column ID'),
'position' => new external_value(PARAM_INT, 'New column sort position'),
]);
}
/**
* External method execution
*
* @param int $reportid
* @param int $columnid
* @param int $position
* @return array
*/
public static function execute(int $reportid, int $columnid, int $position): array {
global $PAGE;
[
'reportid' => $reportid,
'columnid' => $columnid,
'position' => $position,
] = self::validate_parameters(self::execute_parameters(), [
'reportid' => $reportid,
'columnid' => $columnid,
'position' => $position,
]);
$report = manager::get_report_from_id($reportid);
self::validate_context($report->get_context());
permission::require_can_edit_report($report->get_report_persistent());
report::reorder_report_column_sorting($reportid, $columnid, $position);
$exporter = new custom_report_columns_sorting_exporter(null, [
'report' => $report,
]);
return (array) $exporter->export($PAGE->get_renderer('core'));
}
/**
* External method return value
*
* @return external_single_structure
*/
public static function execute_returns(): external_single_structure {
return custom_report_columns_sorting_exporter::get_read_structure();
}
}
+99
View File
@@ -0,0 +1,99 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_reportbuilder\external\columns\sort;
use core_external\external_api;
use core_external\external_value;
use core_external\external_single_structure;
use core_external\external_function_parameters;
use core_reportbuilder\manager;
use core_reportbuilder\permission;
use core_reportbuilder\local\helpers\report;
use core_reportbuilder\external\custom_report_columns_sorting_exporter;
/**
* External method for toggling report column sorting
*
* @package core_reportbuilder
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class toggle extends external_api {
/**
* External method parameters
*
* @return external_function_parameters
*/
public static function execute_parameters(): external_function_parameters {
return new external_function_parameters([
'reportid' => new external_value(PARAM_INT, 'Report ID'),
'columnid' => new external_value(PARAM_INT, 'Column ID'),
'enabled' => new external_value(PARAM_BOOL, 'Sort enabled'),
'direction' => new external_value(PARAM_INT, 'Sort direction', VALUE_DEFAULT, SORT_ASC),
]);
}
/**
* External method execution
*
* @param int $reportid
* @param int $columnid
* @param bool $enabled
* @param int $direction
* @return array
*/
public static function execute(int $reportid, int $columnid, bool $enabled, int $direction = SORT_ASC): array {
global $PAGE;
[
'reportid' => $reportid,
'columnid' => $columnid,
'enabled' => $enabled,
'direction' => $direction,
] = self::validate_parameters(self::execute_parameters(), [
'reportid' => $reportid,
'columnid' => $columnid,
'enabled' => $enabled,
'direction' => $direction,
]);
$report = manager::get_report_from_id($reportid);
self::validate_context($report->get_context());
permission::require_can_edit_report($report->get_report_persistent());
report::toggle_report_column_sorting($reportid, $columnid, $enabled, $direction);
$exporter = new custom_report_columns_sorting_exporter(null, [
'report' => $report,
]);
return (array) $exporter->export($PAGE->get_renderer('core'));
}
/**
* External method return value
*
* @return external_single_structure
*/
public static function execute_returns(): external_single_structure {
return custom_report_columns_sorting_exporter::get_read_structure();
}
}
+97
View File
@@ -0,0 +1,97 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_reportbuilder\external\conditions;
use core_external\external_api;
use core_external\external_value;
use core_external\external_single_structure;
use core_external\external_function_parameters;
use core_reportbuilder\manager;
use core_reportbuilder\permission;
use core_reportbuilder\external\custom_report_conditions_exporter;
use core_reportbuilder\local\helpers\report;
/**
* External method for adding report conditions
*
* @package core_reportbuilder
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class add extends external_api {
/**
* External method parameters
*
* @return external_function_parameters
*/
public static function execute_parameters(): external_function_parameters {
return new external_function_parameters([
'reportid' => new external_value(PARAM_INT, 'Report ID'),
'uniqueidentifier' => new external_value(PARAM_RAW, 'Unique identifier of the condition'),
]);
}
/**
* External method execution
*
* @param int $reportid
* @param string $uniqueidentifier
* @return array
*/
public static function execute(int $reportid, string $uniqueidentifier): array {
global $PAGE, $OUTPUT;
[
'reportid' => $reportid,
'uniqueidentifier' => $uniqueidentifier,
] = self::validate_parameters(self::execute_parameters(), [
'reportid' => $reportid,
'uniqueidentifier' => $uniqueidentifier,
]);
$report = manager::get_report_from_id($reportid);
self::validate_context($report->get_context());
permission::require_can_edit_report($report->get_report_persistent());
report::add_report_condition($reportid, $uniqueidentifier);
// Set current URL and force bootstrap_renderer to initiate moodle page.
$PAGE->set_url('/');
$OUTPUT->header();
$PAGE->start_collecting_javascript_requirements();
$exporter = new custom_report_conditions_exporter(null, ['report' => $report]);
$export = $exporter->export($PAGE->get_renderer('core'));
$export->javascript = $PAGE->requires->get_end_code();
return (array) $export;
}
/**
* External method return value
*
* @return external_value
*/
public static function execute_returns(): external_single_structure {
return custom_report_conditions_exporter::get_read_structure();
}
}
+97
View File
@@ -0,0 +1,97 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_reportbuilder\external\conditions;
use core_external\external_api;
use core_external\external_value;
use core_external\external_single_structure;
use core_external\external_function_parameters;
use core_reportbuilder\manager;
use core_reportbuilder\permission;
use core_reportbuilder\external\custom_report_conditions_exporter;
use core_reportbuilder\local\helpers\report;
/**
* External method for deleting report conditions
*
* @package core_reportbuilder
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class delete extends external_api {
/**
* External method parameters
*
* @return external_function_parameters
*/
public static function execute_parameters(): external_function_parameters {
return new external_function_parameters([
'reportid' => new external_value(PARAM_INT, 'Report ID'),
'conditionid' => new external_value(PARAM_INT, 'Condition ID'),
]);
}
/**
* External method execution
*
* @param int $reportid
* @param int $conditionid
* @return array
*/
public static function execute(int $reportid, int $conditionid): array {
global $PAGE, $OUTPUT;
[
'reportid' => $reportid,
'conditionid' => $conditionid,
] = self::validate_parameters(self::execute_parameters(), [
'reportid' => $reportid,
'conditionid' => $conditionid,
]);
$report = manager::get_report_from_id($reportid);
self::validate_context($report->get_context());
permission::require_can_edit_report($report->get_report_persistent());
report::delete_report_condition($reportid, $conditionid);
// Set current URL and force bootstrap_renderer to initiate moodle page.
$PAGE->set_url('/');
$OUTPUT->header();
$PAGE->start_collecting_javascript_requirements();
$exporter = new custom_report_conditions_exporter(null, ['report' => $report]);
$export = $exporter->export($PAGE->get_renderer('core'));
$export->javascript = $PAGE->requires->get_end_code();
return (array) $export;
}
/**
* External method return value
*
* @return external_value
*/
public static function execute_returns(): external_single_structure {
return custom_report_conditions_exporter::get_read_structure();
}
}
+101
View File
@@ -0,0 +1,101 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_reportbuilder\external\conditions;
use core_external\external_api;
use core_external\external_value;
use core_external\external_single_structure;
use core_external\external_function_parameters;
use core_reportbuilder\manager;
use core_reportbuilder\permission;
use core_reportbuilder\external\custom_report_conditions_exporter;
use core_reportbuilder\local\helpers\report;
/**
* External method for re-ordering report conditions
*
* @package core_reportbuilder
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class reorder extends external_api {
/**
* External method parameters
*
* @return external_function_parameters
*/
public static function execute_parameters(): external_function_parameters {
return new external_function_parameters([
'reportid' => new external_value(PARAM_INT, 'Report ID'),
'conditionid' => new external_value(PARAM_INT, 'Condition ID'),
'position' => new external_value(PARAM_INT, 'New condition position')
]);
}
/**
* External method execution
*
* @param int $reportid
* @param int $conditionid
* @param int $position
* @return array
*/
public static function execute(int $reportid, int $conditionid, int $position): array {
global $PAGE, $OUTPUT;
[
'reportid' => $reportid,
'conditionid' => $conditionid,
'position' => $position,
] = self::validate_parameters(self::execute_parameters(), [
'reportid' => $reportid,
'conditionid' => $conditionid,
'position' => $position,
]);
$report = manager::get_report_from_id($reportid);
self::validate_context($report->get_context());
permission::require_can_edit_report($report->get_report_persistent());
report::reorder_report_condition($reportid, $conditionid, $position);
// Set current URL and force bootstrap_renderer to initiate moodle page.
$PAGE->set_url('/');
$OUTPUT->header();
$PAGE->start_collecting_javascript_requirements();
$exporter = new custom_report_conditions_exporter(null, ['report' => $report]);
$export = $exporter->export($PAGE->get_renderer('core'));
$export->javascript = $PAGE->requires->get_end_code();
return (array) $export;
}
/**
* External method return value
*
* @return external_value
*/
public static function execute_returns(): external_single_structure {
return custom_report_conditions_exporter::get_read_structure();
}
}
+92
View File
@@ -0,0 +1,92 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_reportbuilder\external\conditions;
use core_external\external_api;
use core_external\external_value;
use core_external\external_single_structure;
use core_external\external_function_parameters;
use core_reportbuilder\manager;
use core_reportbuilder\permission;
use core_reportbuilder\external\custom_report_conditions_exporter;
/**
* External method for resetting report conditions
*
* @package core_reportbuilder
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class reset extends external_api {
/**
* External method parameters
*
* @return external_function_parameters
*/
public static function execute_parameters(): external_function_parameters {
return new external_function_parameters([
'reportid' => new external_value(PARAM_INT, 'Report ID'),
]);
}
/**
* External method execution
*
* @param int $reportid
* @return array
*/
public static function execute(int $reportid): array {
global $PAGE, $OUTPUT;
[
'reportid' => $reportid,
] = self::validate_parameters(self::execute_parameters(), [
'reportid' => $reportid,
]);
$report = manager::get_report_from_id($reportid);
self::validate_context($report->get_context());
permission::require_can_edit_report($report->get_report_persistent());
$report->set_condition_values([]);
// Set current URL and force bootstrap_renderer to initiate moodle page.
$PAGE->set_url('/');
$OUTPUT->header();
$PAGE->start_collecting_javascript_requirements();
$exporter = new custom_report_conditions_exporter(null, ['report' => $report]);
$export = $exporter->export($PAGE->get_renderer('core'));
$export->javascript = $PAGE->requires->get_end_code();
return (array) $export;
}
/**
* External method return value
*
* @return external_value
*/
public static function execute_returns(): external_single_structure {
return custom_report_conditions_exporter::get_read_structure();
}
}
@@ -0,0 +1,85 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_reportbuilder\external;
use core_collator;
use core_component;
use renderer_base;
use core_reportbuilder\local\audiences\base;
/**
* Custom report audience cards exporter class
*
* @package core_reportbuilder
* @copyright 2022 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class custom_report_audience_cards_exporter extends custom_report_menu_cards_exporter {
/**
* Get the additional values to inject while exporting
*
* @param renderer_base $output
* @return array
*/
protected function get_other_values(renderer_base $output): array {
$menucards = [];
// Iterate over all audience types.
$audiences = core_component::get_component_classes_in_namespace(null, 'reportbuilder\\audience');
$audiencekeyindex = 0;
foreach ($audiences as $class => $path) {
if (is_subclass_of($class, base::class)) {
$audience = $class::instance();
if (!$audience->user_can_add()) {
continue;
}
// New menu card per component.
$componentname = $audience->get_component_displayname();
if (!array_key_exists($componentname, $menucards)) {
$menucards[$componentname] = [
'name' => $componentname,
'key' => 'index' . ++$audiencekeyindex,
'items' => [],
];
}
// Append menu card item per audience.
$menucards[$componentname]['items'][] = [
'name' => $audience->get_name(),
'identifier' => get_class($audience),
'title' => get_string('addaudience', 'core_reportbuilder', $audience->get_name()),
'action' => 'add-audience',
'disabled' => !$audience->is_available(),
];
}
}
// Order items in each menu card alphabetically.
array_walk($menucards, static function(array &$menucard): void {
core_collator::asort_array_of_arrays_by_key($menucard['items'], 'name');
$menucard['items'] = array_values($menucard['items']);
});
return [
'menucards' => array_values($menucards),
];
}
}
@@ -0,0 +1,88 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_reportbuilder\external;
use renderer_base;
use core\external\exporter;
use core_reportbuilder\datasource;
use core_reportbuilder\form\card_view;
/**
* Custom report card view exporter class
*
* @package core_reportbuilder
* @copyright 2021 Mikel Martín <mikel@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class custom_report_card_view_exporter extends exporter {
/**
* Return a list of objects that are related to the exporter
*
* @return array
*/
protected static function define_related(): array {
return [
'report' => datasource::class,
];
}
/**
* Return the list of additional properties for read structure and export
*
* @return array[]
*/
protected static function define_other_properties(): array {
return [
'form' => [
'type' => PARAM_RAW,
],
'helpicon' => [
'type' => PARAM_RAW,
],
];
}
/**
* Get the additional values to inject while exporting
*
* @param renderer_base $output
* @return array
*/
protected function get_other_values(renderer_base $output): array {
/** @var datasource $report */
$report = $this->related['report'];
$reportid = $report->get_report_persistent()->get('id');
$reportsettings = $report->get_settings_values();
$cardviewsettings = [
'showfirsttitle' => $reportsettings['cardview_showfirsttitle'] ?? 0,
'visiblecolumns' => $reportsettings['cardview_visiblecolumns'] ?? 1,
];
$cardviewform = new card_view(null, null, 'post', '', [], true,
array_merge(['reportid' => $reportid], $cardviewsettings));
$cardviewform->set_data_for_dynamic_submission();
return [
'form' => $cardviewform->render(),
'helpicon' => $output->help_icon('cardview', 'core_reportbuilder'),
];
}
}
@@ -0,0 +1,84 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_reportbuilder\external;
use renderer_base;
use core_reportbuilder\datasource;
/**
* Custom report column cards exporter class
*
* @package core_reportbuilder
* @copyright 2022 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class custom_report_column_cards_exporter extends custom_report_menu_cards_exporter {
/**
* Return a list of objects that are related to the exporter
*
* @return array
*/
protected static function define_related(): array {
return [
'report' => datasource::class,
];
}
/**
* Get the additional values to inject while exporting
*
* @param renderer_base $output
* @return array
*/
protected function get_other_values(renderer_base $output): array {
/** @var datasource $report */
$report = $this->related['report'];
$menucards = [];
foreach ($report->get_columns() as $column) {
if ($column->get_is_deprecated()) {
continue;
}
// New menu card per entity.
$entityname = $column->get_entity_name();
if (!array_key_exists($entityname, $menucards)) {
$menucards[$entityname] = [
'name' => (string) $report->get_entity_title($entityname),
'key' => $entityname,
'items' => [],
];
}
// Append menu card item per column.
$menucards[$entityname]['items'][] = [
'name' => $column->get_title(),
'identifier' => $column->get_unique_identifier(),
'title' => get_string('addcolumn', 'core_reportbuilder', $column->get_title()),
'action' => 'report-add-column',
];
}
return [
'menucards' => array_values($menucards),
];
}
}
@@ -0,0 +1,133 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_reportbuilder\external;
use core_collator;
use pix_icon;
use renderer_base;
use core\external\exporter;
use core_reportbuilder\datasource;
use core_reportbuilder\local\report\column;
/**
* Custom report columns sorting exporter class
*
* @package core_reportbuilder
* @copyright 2021 David Matamoros <davidmc@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class custom_report_columns_sorting_exporter extends exporter {
/**
* Return a list of objects that are related to the exporter
*
* @return array
*/
protected static function define_related(): array {
return [
'report' => datasource::class,
];
}
/**
* Return the list of additional properties for read structure and export
*
* @return array[]
*/
protected static function define_other_properties(): array {
return [
'hassortablecolumns' => [
'type' => PARAM_BOOL,
],
'sortablecolumns' => [
'type' => [
'id' => ['type' => PARAM_INT],
'title' => ['type' => PARAM_TEXT],
'heading' => ['type' => PARAM_TEXT],
'sortdirection' => ['type' => PARAM_INT],
'sortenabled' => ['type' => PARAM_BOOL],
'sortorder' => ['type' => PARAM_INT],
'sorticon' => [
'type' => [
'key' => ['type' => PARAM_RAW],
'component' => ['type' => PARAM_COMPONENT],
'title' => ['type' => PARAM_NOTAGS],
],
],
'movetitle' => ['type' => PARAM_TEXT],
'sortenabledtitle' => ['type' => PARAM_TEXT],
],
'multiple' => true,
],
'helpicon' => [
'type' => PARAM_RAW,
],
];
}
/**
* Get the additional values to inject while exporting
*
* @param renderer_base $output
* @return array
*/
protected function get_other_values(renderer_base $output): array {
/** @var datasource $report */
$report = $this->related['report'];
// Filter/retrieve all "sortable" active columns.
$sortablecolumns = array_filter($report->get_active_columns(), function(column $column): bool {
return $column->get_is_sortable();
});
$sortablecolumns = array_map(function(column $column) use ($report): array {
$persistent = $column->get_persistent();
$columntitle = $column->get_title();
$columnheading = $persistent->get_formatted_heading($report->get_context());
$columnsortascending = ($persistent->get('sortdirection') == SORT_ASC);
$sortenabledtitle = $persistent->get('sortenabled') ? 'columnsortdisable' : 'columnsortenable';
$sortdirectiontitle = $columnsortascending ? 'columnsortdirectiondesc' : 'columnsortdirectionasc';
$icon = $columnsortascending ? 't/uplong' : 't/downlong';
$sorticon = new pix_icon($icon, get_string($sortdirectiontitle, 'core_reportbuilder', $columntitle));
return [
'id' => $persistent->get('id'),
'title' => $columntitle,
'heading' => $columnheading !== '' ? $columnheading : $columntitle,
'sortdirection' => $persistent->get('sortdirection'),
'sortenabled' => $persistent->get('sortenabled'),
'sortorder' => $persistent->get('sortorder'),
'sorticon' => $sorticon->export_for_pix(),
'movetitle' => get_string('movesorting', 'core_reportbuilder', $columntitle),
'sortenabledtitle' => get_string($sortenabledtitle, 'core_reportbuilder', $columntitle),
];
}, $sortablecolumns);
core_collator::asort_array_of_arrays_by_key($sortablecolumns, 'sortorder', core_collator::SORT_NUMERIC);
return [
'hassortablecolumns' => !empty($sortablecolumns),
'sortablecolumns' => array_values($sortablecolumns),
'helpicon' => $output->help_icon('sorting', 'core_reportbuilder'),
];
}
}
@@ -0,0 +1,149 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_reportbuilder\external;
use renderer_base;
use core\external\exporter;
use core_reportbuilder\datasource;
use core_reportbuilder\form\condition;
use core_reportbuilder\local\report\filter;
/**
* Custom report conditions exporter class
*
* @package core_reportbuilder
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class custom_report_conditions_exporter extends exporter {
/**
* Return a list of objects that are related to the exporter
*
* @return array
*/
protected static function define_related(): array {
return [
'report' => datasource::class,
];
}
/**
* Return the list of additional properties for read structure and export
*
* @return array[]
*/
protected static function define_other_properties(): array {
return [
'hasavailableconditions' => [
'type' => PARAM_BOOL,
],
'availableconditions' => [
'type' => [
'optiongroup' => [
'type' => [
'text' => ['type' => PARAM_TEXT],
'values' => [
'type' => [
'value' => ['type' => PARAM_TEXT],
'visiblename' => ['type' => PARAM_TEXT],
],
'multiple' => true,
],
],
],
],
'multiple' => true,
],
'hasactiveconditions' => [
'type' => PARAM_BOOL,
],
'activeconditionsform' => [
'type' => PARAM_RAW,
],
'helpicon' => [
'type' => PARAM_RAW,
],
'javascript' => [
'type' => PARAM_RAW,
'optional' => true,
],
];
}
/**
* Get the additional values to inject while exporting
*
* @param renderer_base $output
* @return array
*/
protected function get_other_values(renderer_base $output): array {
/** @var datasource $report */
$report = $this->related['report'];
// Current condition instances contained in the report.
$conditions = $report->get_active_conditions();
$conditionidentifiers = array_map(static function(filter $condition): string {
return $condition->get_unique_identifier();
}, $conditions);
$availableconditions = [];
// Populate available conditions.
foreach ($report->get_conditions() as $condition) {
// Conditions can only be added once per report, skip if it already exists.
if (in_array($condition->get_unique_identifier(), $conditionidentifiers) || $condition->get_is_deprecated()) {
continue;
}
$entityname = $condition->get_entity_name();
if (!array_key_exists($entityname, $availableconditions)) {
$availableconditions[$entityname] = [
'optiongroup' => [
'text' => $report->get_entity_title($entityname)->out(),
'values' => [],
],
];
}
$availableconditions[$entityname]['optiongroup']['values'][] = [
'value' => $condition->get_unique_identifier(),
'visiblename' => $condition->get_header(),
];
}
// Generate conditions form if any present.
$conditionspresent = !empty($conditions);
if ($conditionspresent) {
$conditionsform = new condition(null, null, 'post', '', [], true, [
'reportid' => $report->get_report_persistent()->get('id'),
]);
$conditionsform->set_data_for_dynamic_submission();
}
return [
'hasavailableconditions' => !empty($availableconditions),
'availableconditions' => array_values($availableconditions),
'hasactiveconditions' => $conditionspresent,
'activeconditionsform' => $conditionspresent ? $conditionsform->render() : '',
'helpicon' => $output->help_icon('conditions', 'core_reportbuilder'),
];
}
}
@@ -0,0 +1,107 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_reportbuilder\external;
use renderer_base;
use core\external\exporter;
use core_reportbuilder\datasource;
use core_reportbuilder\table\custom_report_table_view;
/**
* Custom report data exporter class
*
* @package core_reportbuilder
* @copyright 2022 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class custom_report_data_exporter extends exporter {
/**
* Return a list of objects that are related to the exporter
*
* @return array
*/
protected static function define_related(): array {
return [
'report' => datasource::class,
'page' => 'int',
'perpage' => 'int',
];
}
/**
* Return the list of additional properties for read structure and export
*
* @return array[]
*/
protected static function define_other_properties(): array {
return [
'headers' => [
'type' => PARAM_RAW,
'multiple' => true,
],
'rows' => [
'type' => [
'columns' => [
'type' => PARAM_RAW,
'null' => NULL_ALLOWED,
'multiple' => true,
],
],
'multiple' => true,
],
'totalrowcount' => ['type' => PARAM_INT],
];
}
/**
* Get the additional values to inject while exporting
*
* @param renderer_base $output
* @return array
*/
protected function get_other_values(renderer_base $output): array {
global $DB;
/** @var datasource $report */
$report = $this->related['report'];
$table = custom_report_table_view::create($report->get_report_persistent()->get('id'));
$table->setup();
// Internally the current page is zero-based, but this method expects value plus one.
$table->set_page_number($this->related['page'] + 1);
$table->query_db($this->related['perpage'], false);
$tablerows = [];
foreach ($table->rawdata as $record) {
$tablerows[] = [
'columns' => array_values($table->format_row($record)),
];
}
$table->close_recordset();
return [
'headers' => $table->headers,
'rows' => $tablerows,
'totalrowcount' => $DB->count_records_sql($table->countsql, $table->countparams),
];
}
}
@@ -0,0 +1,80 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_reportbuilder\external;
use core_user;
use renderer_base;
use core\external\persistent_exporter;
use core_reportbuilder\datasource;
use core_reportbuilder\manager;
use core_reportbuilder\local\models\report;
use core_user\external\user_summary_exporter;
/**
* Custom report details exporter class
*
* @package core_reportbuilder
* @copyright 2022 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class custom_report_details_exporter extends persistent_exporter {
/** @var report The persistent object we will export. */
protected $persistent = null;
/**
* Return the name of the class we are exporting
*
* @return string
*/
protected static function define_class(): string {
return report::class;
}
/**
* Return a list of additional properties used only for display
*
* @return array
*/
protected static function define_other_properties(): array {
return [
'sourcename' => [
'type' => PARAM_RAW,
'null' => NULL_ALLOWED,
],
'modifiedby' => ['type' => user_summary_exporter::read_properties_definition()],
];
}
/**
* Get additional values to inject while exporting
*
* @param renderer_base $output
* @return array
*/
protected function get_other_values(renderer_base $output): array {
$source = $this->persistent->get('source');
$usermodified = core_user::get_user($this->persistent->get('usermodified'));
return [
'sourcename' => manager::report_source_exists($source, datasource::class) ? $source::get_name() : null,
'modifiedby' => (new user_summary_exporter($usermodified))->export($output),
];
}
}
@@ -0,0 +1,216 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_reportbuilder\external;
use renderer_base;
use core\persistent;
use core\external\persistent_exporter;
use core_reportbuilder\manager;
use core_reportbuilder\datasource;
use core_reportbuilder\form\filter as form_filter;
use core_reportbuilder\local\models\report;
use core_reportbuilder\table\custom_report_table;
use core_reportbuilder\table\custom_report_table_filterset;
use core_reportbuilder\table\custom_report_table_view;
use core_reportbuilder\table\custom_report_table_view_filterset;
use core_table\local\filter\integer_filter;
/**
* Custom report exporter class
*
* @package core_reportbuilder
* @copyright 2021 David Matamoros <davidmc@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class custom_report_exporter extends persistent_exporter {
/** @var report The persistent object we will export. */
protected $persistent = null;
/** @var bool */
protected $editmode;
/** @var string */
protected $download;
/**
* report_exporter constructor.
*
* @param persistent $persistent
* @param array $related
* @param bool $editmode
* @param string $download
*/
public function __construct(persistent $persistent, array $related = [], bool $editmode = true, string $download = '') {
parent::__construct($persistent, $related);
$this->editmode = $editmode;
$this->download = $download;
}
/**
* Return the name of the class we are exporting
*
* @return string
*/
protected static function define_class(): string {
return report::class;
}
/**
* Return a list of objects that are related to the persistent
*
* @return array
*/
protected static function define_related(): array {
return [
'pagesize' => 'int?',
];
}
/**
* Return a list of additional properties used only for display
*
* @return array
*/
protected static function define_other_properties(): array {
return [
'table' => ['type' => PARAM_RAW],
'filtersapplied' => ['type' => PARAM_INT],
'filterspresent' => ['type' => PARAM_BOOL],
'filtersform' => ['type' => PARAM_RAW],
'attributes' => [
'type' => [
'name' => ['type' => PARAM_TEXT],
'value' => ['type' => PARAM_TEXT]
],
'multiple' => true,
],
'classes' => ['type' => PARAM_TEXT],
'editmode' => ['type' => PARAM_BOOL],
'sidebarmenucards' => [
'type' => custom_report_column_cards_exporter::read_properties_definition(),
'optional' => true,
],
'conditions' => [
'type' => custom_report_conditions_exporter::read_properties_definition(),
'optional' => true,
],
'filters' => [
'type' => custom_report_filters_exporter::read_properties_definition(),
'optional' => true,
],
'sorting' => [
'type' => custom_report_columns_sorting_exporter::read_properties_definition(),
'optional' => true,
],
'cardview' => [
'type' => custom_report_card_view_exporter::read_properties_definition(),
'optional' => true,
],
'javascript' => ['type' => PARAM_RAW],
];
}
/**
* Get additional values to inject while exporting
*
* @param renderer_base $output
* @return array
*/
protected function get_other_values(renderer_base $output): array {
/** @var datasource $report */
$report = manager::get_report_from_persistent($this->persistent);
$filterspresent = false;
$filtersform = '';
$attributes = [];
if ($this->editmode) {
$table = custom_report_table::create($this->persistent->get('id'));
$table->set_filterset(new custom_report_table_filterset());
} else {
// We store the pagesize within the table filterset so that it's available between AJAX requests.
$filterset = new custom_report_table_view_filterset();
$filterset->add_filter(new integer_filter('pagesize', null, [$this->related['pagesize']]));
$table = custom_report_table_view::create($this->persistent->get('id'), $this->download);
$table->set_filterset($filterset);
// Generate filters form if report contains any filters.
$filterspresent = !empty($report->get_active_filters());
if ($filterspresent && empty($this->download)) {
$filtersform = $this->generate_filters_form()->render();
}
// Get the report classes and attributes.
$reportattributes = $report->get_attributes();
if (isset($reportattributes['class'])) {
$classes = $reportattributes['class'];
unset($reportattributes['class']);
}
$attributes = array_map(static function($key, $value): array {
return ['name' => $key, 'value' => $value];
}, array_keys($reportattributes), $reportattributes);
}
// If we are editing we need all this information for the template.
$editordata = [];
if ($this->editmode) {
$menucardsexporter = new custom_report_column_cards_exporter(null, ['report' => $report]);
$editordata['sidebarmenucards'] = (array) $menucardsexporter->export($output);
$conditionsexporter = new custom_report_conditions_exporter(null, ['report' => $report]);
$editordata['conditions'] = (array) $conditionsexporter->export($output);
$filtersexporter = new custom_report_filters_exporter(null, ['report' => $report]);
$editordata['filters'] = (array) $filtersexporter->export($output);
$sortingexporter = new custom_report_columns_sorting_exporter(null, ['report' => $report]);
$editordata['sorting'] = (array) $sortingexporter->export($output);
$cardviewexporter = new custom_report_card_view_exporter(null, ['report' => $report]);
$editordata['cardview'] = (array) $cardviewexporter->export($output);
}
return [
'table' => $output->render($table),
'filtersapplied' => $report->get_applied_filter_count(),
'filterspresent' => $filterspresent,
'filtersform' => $filtersform,
'attributes' => $attributes,
'classes' => $classes ?? '',
'editmode' => $this->editmode,
'javascript' => '',
] + $editordata;
}
/**
* Generate filters form for the report
*
* @return form_filter
*/
private function generate_filters_form(): form_filter {
$filtersform = new form_filter(null, null, 'post', '', [], true, [
'reportid' => $this->persistent->get('id'),
'parameters' => json_encode([]),
]);
$filtersform->set_data_for_dynamic_submission();
return $filtersform;
}
}
@@ -0,0 +1,163 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_reportbuilder\external;
use renderer_base;
use core\external\exporter;
use core_reportbuilder\datasource;
use core_reportbuilder\local\report\filter;
use core_reportbuilder\output\filter_heading_editable;
/**
* Custom report filters exporter class
*
* @package core_reportbuilder
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class custom_report_filters_exporter extends exporter {
/**
* Return a list of objects that are related to the exporter
*
* @return array
*/
protected static function define_related(): array {
return [
'report' => datasource::class,
];
}
/**
* Return the list of additional properties for read structure and export
*
* @return array[]
*/
protected static function define_other_properties(): array {
return [
'hasavailablefilters' => [
'type' => PARAM_BOOL,
],
'availablefilters' => [
'type' => [
'optiongroup' => [
'type' => [
'text' => ['type' => PARAM_TEXT],
'values' => [
'type' => [
'value' => ['type' => PARAM_TEXT],
'visiblename' => ['type' => PARAM_TEXT],
],
'multiple' => true,
],
],
],
],
'multiple' => true,
],
'hasactivefilters' => [
'type' => PARAM_BOOL,
],
'activefilters' => [
'type' => [
'id' => ['type' => PARAM_INT],
'heading' => ['type' => PARAM_TEXT],
'headingeditable' => ['type' => PARAM_RAW],
'sortorder' => ['type' => PARAM_INT],
'movetitle' => ['type' => PARAM_TEXT],
'entityname' => ['type' => PARAM_TEXT],
],
'multiple' => true,
],
'helpicon' => [
'type' => PARAM_RAW,
],
];
}
/**
* Get the additional values to inject while exporting
*
* @param renderer_base $output
* @return array
*/
protected function get_other_values(renderer_base $output): array {
/** @var datasource $report */
$report = $this->related['report'];
// Current filter instances contained in the report.
$filters = $report->get_active_filters();
$filteridentifiers = array_map(static function(filter $filter): string {
return $filter->get_unique_identifier();
}, $filters);
$availablefilters = $activefilters = [];
// Populate available filters.
foreach ($report->get_filters() as $filter) {
// Filters can only be added once per report, skip if it already exists.
if (in_array($filter->get_unique_identifier(), $filteridentifiers) || $filter->get_is_deprecated()) {
continue;
}
$entityname = $filter->get_entity_name();
if (!array_key_exists($entityname, $availablefilters)) {
$availablefilters[$entityname] = [
'optiongroup' => [
'text' => $report->get_entity_title($entityname)->out(),
'values' => [],
],
];
}
$availablefilters[$entityname]['optiongroup']['values'][] = [
'value' => $filter->get_unique_identifier(),
'visiblename' => $filter->get_header(),
];
}
// Populate active filters.
$filterinstances = $report->get_filter_instances();
foreach ($filterinstances as $filterinstance) {
$persistent = $filterinstance->get_filter_persistent();
$entityname = $filterinstance->get_entity_name();
$displayvalue = $filterinstance->get_header();
$editable = new filter_heading_editable(0, $persistent);
$activefilters[] = [
'id' => $persistent->get('id'),
'entityname' => $report->get_entity_title($entityname)->out(),
'heading' => $displayvalue,
'headingeditable' => $editable->render($output),
'sortorder' => $persistent->get('filterorder'),
'movetitle' => get_string('movefilter', 'core_reportbuilder', $displayvalue),
];
}
return [
'hasavailablefilters' => !empty($availablefilters),
'availablefilters' => array_values($availablefilters),
'hasactivefilters' => !empty($activefilters),
'activefilters' => $activefilters,
'helpicon' => $output->help_icon('filters', 'core_reportbuilder'),
];
}
}
@@ -0,0 +1,76 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_reportbuilder\external;
use core\external\exporter;
/**
* Custom report menu cards exporter abstract class
*
* @package core_reportbuilder
* @copyright 2021 David Matamoros <davidmc@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class custom_report_menu_cards_exporter extends exporter {
/**
* Return the list of additional properties for read structure and export
*
* @return array[]
*/
protected static function define_other_properties(): array {
return [
'menucards' => [
'type' => [
'name' => [
'type' => PARAM_TEXT,
],
'key' => [
'type' => PARAM_TEXT,
],
'items' => [
'type' => [
'name' => [
'type' => PARAM_TEXT,
],
'identifier' => [
'type' => PARAM_TEXT,
],
'title' => [
'type' => PARAM_TEXT,
],
'action' => [
'type' => PARAM_TEXT,
],
'disabled' => [
'type' => PARAM_BOOL,
'optional' => true,
'default' => false,
],
],
'optional' => true,
'multiple' => true,
],
],
'optional' => true,
'multiple' => true,
],
];
}
}
+91
View File
@@ -0,0 +1,91 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_reportbuilder\external\filters;
use core_external\external_api;
use core_external\external_value;
use core_external\external_single_structure;
use core_external\external_function_parameters;
use core_reportbuilder\manager;
use core_reportbuilder\permission;
use core_reportbuilder\external\custom_report_filters_exporter;
use core_reportbuilder\local\helpers\report;
/**
* External method for adding report filters
*
* @package core_reportbuilder
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class add extends external_api {
/**
* External method parameters
*
* @return external_function_parameters
*/
public static function execute_parameters(): external_function_parameters {
return new external_function_parameters([
'reportid' => new external_value(PARAM_INT, 'Report ID'),
'uniqueidentifier' => new external_value(PARAM_RAW, 'Unique identifier of the filter'),
]);
}
/**
* External method execution
*
* @param int $reportid
* @param string $uniqueidentifier
* @return array
*/
public static function execute(int $reportid, string $uniqueidentifier): array {
global $PAGE;
[
'reportid' => $reportid,
'uniqueidentifier' => $uniqueidentifier,
] = self::validate_parameters(self::execute_parameters(), [
'reportid' => $reportid,
'uniqueidentifier' => $uniqueidentifier,
]);
$report = manager::get_report_from_id($reportid);
self::validate_context($report->get_context());
permission::require_can_edit_report($report->get_report_persistent());
report::add_report_filter($reportid, $uniqueidentifier);
$exporter = new custom_report_filters_exporter(null, [
'report' => $report,
]);
return (array) $exporter->export($PAGE->get_renderer('core'));
}
/**
* External method return value
*
* @return external_single_structure
*/
public static function execute_returns(): external_single_structure {
return custom_report_filters_exporter::get_read_structure();
}
}
+91
View File
@@ -0,0 +1,91 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_reportbuilder\external\filters;
use core_external\external_api;
use core_external\external_value;
use core_external\external_single_structure;
use core_external\external_function_parameters;
use core_reportbuilder\manager;
use core_reportbuilder\permission;
use core_reportbuilder\external\custom_report_filters_exporter;
use core_reportbuilder\local\helpers\report;
/**
* External method for deleting report filters
*
* @package core_reportbuilder
* @copyright 2021 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class delete extends external_api {
/**
* External method parameters
*
* @return external_function_parameters
*/
public static function execute_parameters(): external_function_parameters {
return new external_function_parameters([
'reportid' => new external_value(PARAM_INT, 'Report ID'),
'filterid' => new external_value(PARAM_INT, 'Filter ID'),
]);
}
/**
* External method execution
*
* @param int $reportid
* @param int $filterid
* @return array
*/
public static function execute(int $reportid, int $filterid): array {
global $PAGE;
[
'reportid' => $reportid,
'filterid' => $filterid,
] = self::validate_parameters(self::execute_parameters(), [
'reportid' => $reportid,
'filterid' => $filterid,
]);
$report = manager::get_report_from_id($reportid);
self::validate_context($report->get_context());
permission::require_can_edit_report($report->get_report_persistent());
report::delete_report_filter($reportid, $filterid);
$exporter = new custom_report_filters_exporter(null, [
'report' => $report,
]);
return (array) $exporter->export($PAGE->get_renderer('core'));
}
/**
* External method return value
*
* @return external_single_structure
*/
public static function execute_returns(): external_single_structure {
return custom_report_filters_exporter::get_read_structure();
}
}

Some files were not shown because too many files have changed in this diff Show More