Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
// 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);}});};