Proyectos de Subversion Moodle

Rev

Autoría | Ultima modificación | Ver Log |

{"version":3,"file":"bulk_actions.min.js","sources":["../../src/bulkactions/bulk_actions.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\nimport Templates from 'core/templates';\nimport {get_string as getString} from 'core/str';\nimport {disableStickyFooter, enableStickyFooter} from 'core/sticky-footer';\n\n/**\n * Base class for defining a bulk actions area within a page.\n *\n * @module     core/bulkactions/bulk_actions\n * @copyright  2023 Mihail Geshoski <mihail@moodle.com>\n * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n/** @constant {Object} The object containing the relevant selectors. */\nconst Selectors = {\n    stickyFooterContainer: '#sticky-footer',\n    selectedItemsCountContainer: '[data-type=\"bulkactions\"] [data-for=\"bulkcount\"]',\n    cancelBulkActionModeElement: '[data-type=\"bulkactions\"] [data-action=\"bulkcancel\"]',\n    bulkModeContainer: '[data-type=\"bulkactions\"]',\n    bulkActionsContainer: '[data-type=\"bulkactions\"] [data-for=\"bulktools\"]'\n};\n\nexport default class BulkActions {\n\n    /** @property {string|null} initialStickyFooterContent The initial content of the sticky footer. */\n    initialStickyFooterContent = null;\n\n    /** @property {Array} selectedItems The array of selected item elements. */\n    selectedItems = [];\n\n    /** @property {boolean} isBulkActionsModeEnabled Whether the bulk actions mode is enabled. */\n    isBulkActionsModeEnabled = false;\n\n    /**\n     * The class constructor.\n     *\n     * @returns {void}\n     */\n    constructor() {\n        if (!this.getStickyFooterContainer()) {\n            throw new Error('Sticky footer not found.');\n        }\n        // Store any pre-existing content in the sticky footer. When bulk actions mode is enabled, this content will be\n        // replaced with the bulk actions content and restored when bulk actions mode is disabled.\n        this.initialStickyFooterContent = this.getStickyFooterContainer().innerHTML;\n        // Register and handle the item select change event.\n        this.registerItemSelectChangeEvent(async() => {\n            this.selectedItems = this.getSelectedItems();\n            if (this.selectedItems.length > 0) { // At least one item is selected.\n                // If the bulk actions mode is already enabled only update the selected items count.\n                if (this.isBulkActionsModeEnabled) {\n                    await this.updateBulkItemSelection();\n                } else { // Otherwise, enable the bulk action mode.\n                    await this.enableBulkActionsMode();\n                }\n            } else { // No items are selected, disable the bulk action mode.\n                this.disableBulkActionsMode();\n            }\n        });\n    }\n\n    /**\n     * Returns the array of the relevant bulk action objects.\n     *\n     * @method getBulkActions\n     * @returns {Array}\n     */\n    getBulkActions() {\n        throw new Error(`getBulkActions() must be implemented in ${this.constructor.name}`);\n    }\n\n    /**\n     * Returns the array of selected items.\n     *\n     * @method getSelectedItems\n     * @returns {Array}\n     */\n    getSelectedItems() {\n        throw new Error(`getSelectedItems() must be implemented in ${this.constructor.name}`);\n    }\n\n    /**\n     * Adds the listener for the item select change event.\n     * The event handler function that is passed as a parameter should be called right after the event is triggered.\n     *\n     * @method registerItemSelectChangeEvent\n     * @param {function} eventHandler The event handler function.\n     * @returns {void}\n     */\n    registerItemSelectChangeEvent(eventHandler) {\n        throw new Error(`registerItemSelectChangeEvent(${eventHandler}) must be implemented in ${this.constructor.name}`);\n    }\n\n    /**\n     * Returns the sticky footer container.\n     *\n     * @method getStickyFooterContainer\n     * @returns {HTMLElement}\n     */\n    getStickyFooterContainer() {\n        return document.querySelector(Selectors.stickyFooterContainer);\n    }\n\n    /**\n     * Enables the bulk action mode.\n     *\n     * @method enableBulkActionsMode\n     * @returns {Promise}\n     */\n    async enableBulkActionsMode() {\n        // Make sure that the sticky footer is enabled.\n        enableStickyFooter();\n        // Render the bulk actions content in the sticky footer container.\n        this.getStickyFooterContainer().innerHTML = await this.renderBulkActions();\n        const bulkModeContainer = this.getStickyFooterContainer().querySelector(Selectors.bulkModeContainer);\n        const bulkActionsContainer = bulkModeContainer.querySelector(Selectors.bulkActionsContainer);\n        this.getBulkActions().forEach((bulkAction) => {\n            // Register the listener events for each available bulk action.\n            bulkAction.registerListenerEvents(bulkActionsContainer);\n            // Set the selected items for each available bulk action.\n            bulkAction.setSelectedItems(this.selectedItems);\n        });\n        // Register the click listener event for the cancel bulk mode button.\n        bulkModeContainer.addEventListener('click', (e) => {\n            if (e.target.closest(Selectors.cancelBulkActionModeElement)) {\n                // Uncheck all selected items.\n                this.selectedItems.forEach((item) => {\n                    item.checked = false;\n                });\n                // Disable the bulk action mode.\n                this.disableBulkActionsMode();\n            }\n        });\n        this.isBulkActionsModeEnabled = true;\n    }\n\n    /**\n     * Disables the bulk action mode.\n     *\n     * @method disableBulkActionsMode\n     * @returns {void}\n     */\n    disableBulkActionsMode() {\n        // If there was any previous (initial) content in the sticky footer, restore it.\n        if (this.initialStickyFooterContent.length > 0) {\n            this.getStickyFooterContainer().innerHTML = this.initialStickyFooterContent;\n        } else { // No previous content to restore, disable the sticky footer.\n            disableStickyFooter();\n        }\n        this.isBulkActionsModeEnabled = false;\n    }\n\n    /**\n     * Renders the bulk actions content.\n     *\n     * @method renderBulkActions\n     * @returns {Promise}\n     */\n    async renderBulkActions() {\n        let data = {\n            'bulkselectioncount': this.selectedItems.length,\n            'actions': []\n        };\n        // Render the bulk actions trigger element for each available bulk action.\n        await Promise.all(this.getBulkActions().map(async(bulkAction) => {\n            data.actions.push({'actiontrigger': await bulkAction.renderBulkActionTrigger()});\n        }));\n\n        return Templates.render('core/bulkactions/bulk_actions', data);\n    }\n\n    /**\n     * Updates the selected items count in the bulk actions content.\n     *\n     * @method updateBulkItemSelection\n     * @returns {void}\n     */\n    async updateBulkItemSelection() {\n        const bulkSelection = await getString('bulkselection', 'core', this.selectedItems.length);\n        document.querySelector(Selectors.selectedItemsCountContainer).innerHTML = bulkSelection;\n    }\n}\n"],"names":["Selectors","constructor","this","getStickyFooterContainer","Error","initialStickyFooterContent","innerHTML","registerItemSelectChangeEvent","async","selectedItems","getSelectedItems","length","isBulkActionsModeEnabled","updateBulkItemSelection","enableBulkActionsMode","disableBulkActionsMode","getBulkActions","name","eventHandler","document","querySelector","renderBulkActions","bulkModeContainer","bulkActionsContainer","forEach","bulkAction","registerListenerEvents","setSelectedItems","addEventListener","e","target","closest","item","checked","data","Promise","all","map","actions","push","renderBulkActionTrigger","Templates","render","bulkSelection"],"mappings":";;;;;;;yJA4BMA,gCACqB,iBADrBA,sCAE2B,mDAF3BA,sCAG2B,uDAH3BA,4BAIiB,4BAJjBA,+BAKoB,iFAmBtBC,mEAb6B,2CAGb,qDAGW,IAQlBC,KAAKC,iCACA,IAAIC,MAAM,iCAIfC,2BAA6BH,KAAKC,2BAA2BG,eAE7DC,+BAA8BC,eAC1BC,cAAgBP,KAAKQ,mBACtBR,KAAKO,cAAcE,OAAS,EAExBT,KAAKU,+BACCV,KAAKW,gCAELX,KAAKY,6BAGVC,4BAWjBC,uBACU,IAAIZ,wDAAiDF,KAAKD,YAAYgB,OAShFP,yBACU,IAAIN,0DAAmDF,KAAKD,YAAYgB,OAWlFV,8BAA8BW,oBACpB,IAAId,8CAAuCc,iDAAwChB,KAAKD,YAAYgB,OAS9Gd,kCACWgB,SAASC,cAAcpB,2GAazBG,2BAA2BG,gBAAkBJ,KAAKmB,0BACjDC,kBAAoBpB,KAAKC,2BAA2BiB,cAAcpB,6BAClEuB,qBAAuBD,kBAAkBF,cAAcpB,qCACxDgB,iBAAiBQ,SAASC,aAE3BA,WAAWC,uBAAuBH,sBAElCE,WAAWE,iBAAiBzB,KAAKO,kBAGrCa,kBAAkBM,iBAAiB,SAAUC,IACrCA,EAAEC,OAAOC,QAAQ/B,8CAEZS,cAAce,SAASQ,OACxBA,KAAKC,SAAU,UAGdlB,kCAGRH,0BAA2B,EASpCG,yBAEQb,KAAKG,2BAA2BM,OAAS,OACpCR,2BAA2BG,UAAYJ,KAAKG,wEAIhDO,0BAA2B,gCAU5BsB,KAAO,oBACehC,KAAKO,cAAcE,eAC9B,iBAGTwB,QAAQC,IAAIlC,KAAKc,iBAAiBqB,KAAI7B,MAAAA,aACxC0B,KAAKI,QAAQC,KAAK,qBAAwBd,WAAWe,gCAGlDC,mBAAUC,OAAO,gCAAiCR,4CAUnDS,oBAAsB,mBAAU,gBAAiB,OAAQzC,KAAKO,cAAcE,QAClFQ,SAASC,cAAcpB,uCAAuCM,UAAYqC"}