AutorÃa | Ultima modificación | Ver Log |
{"version":3,"file":"bulkedittools.min.js","sources":["../../../src/local/content/bulkedittools.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 * The bulk editor tools bar.\n *\n * @module core_courseformat/local/content/bulkedittools\n * @class core_courseformat/local/content/bulkedittools\n * @copyright 2023 Ferran Recio <ferran
@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {BaseComponent} from 'core/reactive';\nimport {disableStickyFooter, enableStickyFooter} from 'core/sticky-footer';\nimport {getCurrentCourseEditor} from 'core_courseformat/courseeditor';\nimport {getString} from 'core/str';\nimport Pending from 'core/pending';\nimport {prefetchStrings} from 'core/prefetch';\nimport {\n selectAllBulk,\n switchBulkSelection,\n checkAllBulkSelected\n} from 'core_courseformat/local/content/actions/bulkselection';\nimport Notification from 'core/notification';\n\n// Load global strings.\nprefetchStrings(\n 'core_courseformat',\n ['bulkselection']\n);\n\nexport default class Component extends BaseComponent {\n\n /**\n * Constructor hook.\n */\n create() {\n // Optional component name for debugging.\n this.name = 'bulk_editor_tools';\n // Default query selectors.\n this.selectors = {\n ACTIONS: `[data-for=\"bulkacti
on\"]`,\n ACTIONTOOL: `[data-for=\"bulkactions\"] li`,\n CANCEL: `[data-for=\"bulkcancel\"]`,\n COUNT: `[data-for='bulkcount']`,\n SELECTABLE: `[data-bulkcheckbox][data-is-selectable]`,\n SELECTALL: `[data-for=\"selectall\"]`,\n BULKBTN: `[data-for=\"enableBulk\"]`,\n };\n // Most classes will be loaded later by DndCmItem.\n this.classes = {\n HIDE: 'd-none',\n DISABLED: 'disabled',\n };\n }\n\n /**\n * Static method to create a component instance from the mustache template.\n *\n * @param {string} target optional altentative DOM main element CSS selector\n * @param {object} selectors optional css selector overrides\n * @return {Component}\n */\n static init(target, selectors) {\n return new this({\n element: document.querySelector(target),\n reactive: getCurrentCourseEditor(),\n selectors\n });\n }\n\n /**\n
* Initial state ready method.\n */\n stateReady() {\n const cancelBtn = this.getElement(this.selectors.CANCEL);\n if (cancelBtn) {\n this.addEventListener(cancelBtn, 'click', this._cancelBulk);\n }\n const selectAll = this.getElement(this.selectors.SELECTALL);\n if (selectAll) {\n this.addEventListener(selectAll, 'click', this._selectAllClick);\n }\n }\n\n /**\n * Component watchers.\n *\n * @returns {Array} of watchers\n */\n getWatchers() {\n return [\n {watch: `bulk.enabled:updated`, handler: this._refreshEnabled},\n {watch: `bulk:updated`, handler: this._refreshTools},\n ];\n }\n\n /**\n * Hide and show the bulk edit tools.\n *\n * @param {object} param\n * @param {Object} param.element details the update details (state.bulk in this case).\n */\n _refreshEnabled({element}) {\n this._updatePageTitle(element.enabled).catch(Notification.e
xception);\n\n if (element.enabled) {\n enableStickyFooter();\n } else {\n disableStickyFooter();\n }\n }\n\n /**\n * Refresh the tools depending on the current selection.\n *\n * @param {object} param the state watcher information\n * @param {Object} param.state the full state data.\n * @param {Object} param.element the affected element (bulk in this case).\n */\n _refreshTools(param) {\n this._refreshSelectCount(param);\n this._refreshSelectAll(param);\n this._refreshActions(param);\n }\n\n /**\n * Refresh the selection count.\n *\n * @param {object} param\n * @param {Object} param.element the affected element (bulk in this case).\n */\n async _refreshSelectCount({element: bulk}) {\n const stringName = (bulk.selection.length > 1) ? 'bulkselection_plural' : 'bulkselection';\n const selectedCount = await getString(stringName, 'core_courseformat', bulk.selection.length);\
n const selectedElement = this.getElement(this.selectors.COUNT);\n if (selectedElement) {\n selectedElement.innerHTML = selectedCount;\n }\n }\n\n /**\n * Refresh the select all element.\n *\n * @param {object} param\n * @param {Object} param.element the affected element (bulk in this case).\n */\n _refreshSelectAll({element: bulk}) {\n const selectall = this.getElement(this.selectors.SELECTALL);\n if (!selectall) {\n return;\n }\n selectall.disabled = (bulk.selectedType === '');\n // The changechecker module can prevent the checkbox form changing it's value.\n // To avoid that we leave the sniffer to act before changing the value.\n const pending = new Pending(`courseformat/bulktools:refreshSelectAll`);\n setTimeout(\n () => {\n selectall.checked = checkAllBulkSelected(this.reactive);\n pending.resolve();\n },\n 100\n
);\n }\n\n /**\n * Refresh the visible action buttons depending on the selection type.\n *\n * @param {object} param\n * @param {Object} param.element the affected element (bulk in this case).\n */\n _refreshActions({element: bulk}) {\n // By default, we show the cm options.\n const displayType = (bulk.selectedType == 'section') ? 'section' : 'cm';\n const enabled = (bulk.selectedType !== '');\n this.getElements(this.selectors.ACTIONS).forEach(action => {\n action.classList.toggle(this.classes.DISABLED, !enabled);\n action.tabIndex = (enabled) ? 0 : -1;\n\n const actionTool = action.closest(this.selectors.ACTIONTOOL);\n const isHidden = (action.dataset.bulk != displayType);\n actionTool?.classList.toggle(this.classes.HIDE, isHidden);\n });\n }\n\n /**\n * Cancel bulk handler.\n */\n _cancelBulk() {\n const pending = new Pending(`courseformat/content:bulktoggle_o
ff`);\n this.reactive.dispatch('bulkEnable', false);\n // Wait for a while and focus on enable bulk button.\n setTimeout(() => {\n document.querySelector(this.selectors.BULKBTN)?.focus();\n pending.resolve();\n }, 150);\n }\n\n /**\n * Handle special select all cases.\n * @param {Event} event\n */\n _selectAllClick(event) {\n event.preventDefault();\n if (event.altKey) {\n switchBulkSelection(this.reactive);\n return;\n }\n if (checkAllBulkSelected(this.reactive)) {\n this._handleUnselectAll();\n return;\n }\n selectAllBulk(this.reactive, true);\n }\n\n /**\n * Process unselect all elements.\n */\n _handleUnselectAll() {\n const pending = new Pending(`courseformat/content:bulktUnselectAll`);\n selectAllBulk(this.reactive, false);\n // Wait for a while and focus on the first checkbox.\n setTimeout(() => {\n
document.querySelector(this.selectors.SELECTABLE)?.focus();\n pending.resolve();\n }, 150);\n }\n\n /**\n * Updates the <title> attribute of the page whenever bulk editing is toggled.\n *\n * This helps users, especially screen reader users, to understand the current state of the course homepage.\n *\n * @param {Boolean} enabled True when bulk editing is turned on. False, otherwise.\n * @returns {Promise<void>}\n * @private\n */\n async _updatePageTitle(enabled) {\n const enableBulk = document.querySelector(this.selectors.BULKBTN);\n let params, bulkEditTitle, editingTitle;\n if (enableBulk.dataset.sectiontitle) {\n // Section editing mode.\n params = {\n course: enableBulk.dataset.coursename,\n sectionname: enableBulk.dataset.sectionname,\n sectiontitle: enableBulk.dataset.sectiontitle,\n };\n bulkEditTitle = await getString('courses
ectiontitlebulkediting', 'moodle', params);\n editingTitle = await getString('coursesectiontitleediting', 'moodle', params);\n } else {\n // Whole course editing mode.\n params = {\n course: enableBulk.dataset.coursename\n };\n bulkEditTitle = await getString('coursetitlebulkediting', 'moodle', params);\n editingTitle = await getString('coursetitleediting', 'moodle', params);\n }\n const pageTitle = document.title;\n if (enabled) {\n // Use bulk editing string for the page title.\n // At this point, the current page title should be the normal editing title.\n // So replace the normal editing title with the bulk editing title.\n document.title = pageTitle.replace(editingTitle, bulkEditTitle);\n } else {\n // Use the normal editing string for the page title.\n // At this point, the current page title should be the bulk editing titl
e.\n // So replace the bulk editing title with the normal editing title.\n document.title = pageTitle.replace(bulkEditTitle, editingTitle);\n }\n }\n}\n"],"names":["Component","BaseComponent","create","name","selectors","ACTIONS","ACTIONTOOL","CANCEL","COUNT","SELECTABLE","SELECTALL","BULKBTN","classes","HIDE","DISABLED","target","this","element","document","querySelector","reactive","stateReady","cancelBtn","getElement","addEventListener","_cancelBulk","selectAll","_selectAllClick","getWatchers","watch","handler","_refreshEnabled","_refreshTools","_updatePageTitle","enabled","catch","Notification","exception","param","_refreshSelectCount","_refreshSelectAll","_refreshActions","bulk","stringName","selection","length","selectedCount","selectedElement","innerHTML","selectall","disabled","selectedType","pending","Pending","setTimeout","checked","resolve","displayType","getElements","forEach","action","classList","toggle","tabIndex","actionTool","closest","isHidden","dataset","dis
patch","focus","event","preventDefault","altKey","_handleUnselectAll","enableBulk","params","bulkEditTitle","editingTitle","sectiontitle","course","coursename","sectionname","pageTitle","title","replace"],"mappings":"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"}