AutorÃa | 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/>./*** Schema selector javascript controls.** This module controls:* - The select all feature.* - Disabling activities checkboxes when the section is not selected.** @module core_backup/schema_backup_form* @copyright 2024 Ferran Recio <ferran@moodle.com>* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/import Notification from 'core/notification';import * as Templates from 'core/templates';const Selectors = {action: '[data-mdl-action]',checkboxes: '#id_coursesettings input[type="checkbox"]',firstSection: 'fieldset#id_coursesettings .fcontainer .grouped_settings.section_level',modCheckboxes: (modName) => `setting_activity_${modName}_`,};const Suffixes = {userData: '_userdata',userInfo: '_userinfo',included: '_included',};/*** Adds select all/none links to the top of the backup/restore/import schema page.*/export default class BackupFormController {/*** Static module init method.* @param {Array<string>} modNames - The names of the modules.* @returns {BackupFormController}*/static init(modNames) {return new BackupFormController(modNames);}/*** Creates a new instance of the SchemaBackupForm class.* @param {Array<string>} modNames - The names of the modules.*/constructor(modNames) {this.modNames = modNames;this.scanFormUserData();this.addSelectorsToPage();}/*** Detect the user data attribute from the form.** @private*/scanFormUserData() {this.withuserdata = false;this.userDataSuffix = Suffixes.userData;const checkboxes = document.querySelectorAll(Selectors.checkboxes);if (!checkboxes) {return;}// Depending on the form, user data inclusion is called userinfo or userdata.for (const checkbox of checkboxes) {const name = checkbox.name;if (name.endsWith(Suffixes.userData)) {this.withuserdata = true;break;} else if (name.endsWith(Suffixes.userInfo)) {this.withuserdata = true;this.userDataSuffix = Suffixes.userInfo;break;}}}/*** Initializes all related events.** @private* @param {HTMLElement} element - The element to attach the events to.*/initEvents(element) {element.addEventListener('click', (event) => {const action = event.target.closest(Selectors.action);if (!action) {return;}event.preventDefault();const suffix = (action.dataset?.mdlType == 'userdata') ? this.userDataSuffix : Suffixes.included;this.changeSelection(action.dataset.mdlAction == 'selectall',suffix,action.dataset?.mdlMod ?? null);});}/*** Changes the selection according to the params.** @private* @param {boolean} checked - The checked state for the checkboxes.* @param {string} suffix - The checkboxes suffix* @param {string} [modName] - The module name.*/changeSelection(checked, suffix, modName) {const prefix = modName ? Selectors.modCheckboxes(modName) : null;let formId;const checkboxes = document.querySelectorAll(Selectors.checkboxes);for (const checkbox of checkboxes) {formId = formId ?? checkbox.closest('form').getAttribute('id');if (prefix && !checkbox.name.startsWith(prefix)) {continue;}if (checkbox.name.endsWith(suffix)) {checkbox.checked = checked;}}// At this point, we really need to persuade the form we are part of to// update all of its disabledIf rules. However, as far as I can see,// given the way that lib/form/form.js is written, that is impossible.if (formId && M.form) {M.form.updateFormState(formId);}}/*** Generates the full selectors element to add to the page.** @private* @returns {HTMLElement} The selectors element.*/generateSelectorsElement() {const links = document.createElement('div');links.id = 'backup_selectors';this.initEvents(links);this.renderSelectorsTemplate(links);return links;}/*** Load the select all template.** @private* @param {HTMLElement} element the container*/renderSelectorsTemplate(element) {const data = {modules: this.getModulesTemplateData(),withuserdata: (this.withuserdata) ? true : undefined,};Templates.renderForPromise('core_backup/formselectall',data).then(({html, js}) => {return Templates.replaceNodeContents(element, html, js);}).catch(Notification.exception);}/*** Generate the modules template data.** @private* @returns {Array} of modules data.*/getModulesTemplateData() {const modules = [];for (const modName in this.modNames) {if (!this.modNames.hasOwnProperty(modName)) {continue;}modules.push({modname: modName,heading: this.modNames[modName],});}return modules;}/*** Adds select all/none functionality to the backup form.** @private*/addSelectorsToPage() {const firstSection = document.querySelector(Selectors.firstSection);if (!firstSection) {// This is not a relevant page.return;}if (!firstSection.querySelector(Selectors.checkboxes)) {// No checkboxes.return;}// Add global select all/none options.const selector = this.generateSelectorsElement();firstSection.parentNode.insertBefore(selector, firstSection);}}