Rev 1 | 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/>./*** Course index section component.** This component is used to control specific course section interactions like drag and drop.** @module core_courseformat/local/courseindex/section* @class core_courseformat/local/courseindex/section* @copyright 2021 Ferran Recio <ferran@moodle.com>* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/import SectionTitle from 'core_courseformat/local/courseindex/sectiontitle';import DndSection from 'core_courseformat/local/courseeditor/dndsection';export default class Component extends DndSection {/*** Constructor hook.*/create() {// Optional component name for debugging.this.name = 'courseindex_section';// Default query selectors.this.selectors = {SECTION_ITEM: `[data-for='section_item']`,SECTION_TITLE: `[data-for='section_title']`,CM_LAST: `[data-for="cm"]:last-child`,};// Default classes to toggle on refresh.this.classes = {SECTIONHIDDEN: 'dimmed',SECTIONCURRENT: 'current',LOCKED: 'editinprogress',RESTRICTIONS: 'restrictions',PAGEITEM: 'pageitem',OVERLAYBORDERS: 'overlay-preview-borders',};// We need our id to watch specific events.this.id = this.element.dataset.id;this.isPageItem = false;}/*** Static method to create a component instance form the mustahce template.** @param {string} target the DOM main element or its ID* @param {object} selectors optional css selector overrides* @return {Component}*/static init(target, selectors) {return new this({element: document.getElementById(target),selectors,});}/*** Initial state ready method.** @param {Object} state the initial state*/stateReady(state) {this.configState(state);const sectionItem = this.getElement(this.selectors.SECTION_ITEM);// Drag and drop is only available for components compatible course formats.if (this.reactive.isEditing && this.reactive.supportComponents) {// Init the inner dragable element passing the full section as affected region.const titleitem = new SectionTitle({...this,element: sectionItem,fullregion: this.element,});this.configDragDrop(titleitem);}// Check if the current url is the section url.const section = state.section.get(this.id);if (window.location.href == section.sectionurl.replace(/&/g, "&")) {this.reactive.dispatch('setPageItem', 'section', this.id);sectionItem.scrollIntoView();}}/*** Component watchers.** @returns {Array} of watchers*/getWatchers() {return [{watch: `section[${this.id}]:deleted`, handler: this.remove},{watch: `section[${this.id}]:updated`, handler: this._refreshSection},{watch: `course.pageItem:updated`, handler: this._refreshPageItem},];}/*** Get the last CM element of that section.** @returns {element|null}*/getLastCm() {return this.getElement(this.selectors.CM_LAST);}/*** Update a course index section using the state information.** @param {Object} param details the update details.* @param {Object} param.element the section element*/_refreshSection({element}) {// Update classes.const sectionItem = this.getElement(this.selectors.SECTION_ITEM);sectionItem.classList.toggle(this.classes.SECTIONHIDDEN, !element.visible);sectionItem.classList.toggle(this.classes.RESTRICTIONS, element.hasrestrictions ?? false);this.element.classList.toggle(this.classes.SECTIONCURRENT, element.current);this.element.classList.toggle(this.classes.DRAGGING, element.dragging ?? false);this.element.classList.toggle(this.classes.LOCKED, element.locked ?? false);this.locked = element.locked;// Update title.this.getElement(this.selectors.SECTION_TITLE).innerHTML = element.title;}/*** Handle a page item update.** @param {Object} details the update details* @param {Object} details.state the state data.* @param {Object} details.element the course state data.*/_refreshPageItem({element, state}) {if (!element.pageItem) {return;}if (element.pageItem.sectionId !== this.id && this.isPageItem || element.pageItem.type !== 'section') {this.pageItem = false;this.getElement(this.selectors.SECTION_ITEM).classList.remove(this.classes.PAGEITEM);return;}const section = state.section.get(this.id);if (section.indexcollapsed && !element.pageItem?.isStatic) {this.pageItem = (element.pageItem?.sectionId == this.id);} else {this.pageItem = (element.pageItem.type == 'section' && element.pageItem.id == this.id);}const sectionItem = this.getElement(this.selectors.SECTION_ITEM);sectionItem.classList.toggle(this.classes.PAGEITEM, this.pageItem ?? false);if (this.pageItem && !this.reactive.isEditing) {this.element.scrollIntoView({block: "nearest"});}}/*** Overridden version of the component addOverlay async method.** The course index is not compatible with overlay elements.*/async addOverlay() {this.element.classList.add(this.classes.OVERLAYBORDERS);}/*** Overridden version of the component removeOverlay.** The course index is not compatible with overlay elements.*/removeOverlay() {this.element.classList.remove(this.classes.OVERLAYBORDERS);}}