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
@@ -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;