{"version":3,"file":"cm.min.js","sources":["https:\/\/moodle.tau.ac.il\/2023\/course\/format\/amd\/src\/local\/courseindex\/cm.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 .\n\n\/**\n * Course index cm component.\n *\n * This component is used to control specific course modules interactions like drag and drop.\n *\n * @module core_courseformat\/local\/courseindex\/cm\n * @class core_courseformat\/local\/courseindex\/cm\n * @copyright 2021 Ferran Recio \n * @license http:\/\/www.gnu.org\/copyleft\/gpl.html GNU GPL v3 or later\n *\/\n\nimport DndCmItem from 'core_courseformat\/local\/courseeditor\/dndcmitem';\nimport Templates from 'core\/templates';\nimport Prefetch from 'core\/prefetch';\nimport Config from 'core\/config';\n\n\/\/ Prefetch the completion icons template.\nconst completionTemplate = 'core_courseformat\/local\/courseindex\/cmcompletion';\nPrefetch.prefetchTemplate(completionTemplate);\n\nexport default class Component extends DndCmItem {\n\n \/**\n * Constructor hook.\n *\/\n create() {\n \/\/ Optional component name for debugging.\n this.name = 'courseindex_cm';\n \/\/ Default query selectors.\n this.selectors = {\n CM_NAME: `[data-for='cm_name']`,\n CM_COMPLETION: `[data-for='cm_completion']`,\n };\n \/\/ Default classes to toggle on refresh.\n this.classes = {\n CMHIDDEN: 'dimmed',\n LOCKED: 'editinprogress',\n RESTRICTIONS: 'restrictions',\n PAGEITEM: 'pageitem',\n };\n \/\/ We need our id to watch specific events.\n this.id = this.element.dataset.id;\n }\n\n \/**\n * Static method to create a component instance form the mustache template.\n *\n * @param {element|string} target the DOM main element or its ID\n * @param {object} selectors optional css selector overrides\n * @return {Component}\n *\/\n static init(target, selectors) {\n return new Component({\n element: document.getElementById(target),\n selectors,\n });\n }\n\n \/**\n * Initial state ready method.\n *\n * @param {Object} state the course state.\n *\/\n stateReady(state) {\n this.configDragDrop(this.id);\n const cm = state.cm.get(this.id);\n const course = state.course;\n \/\/ Refresh completion icon.\n this._refreshCompletion({\n state,\n element: cm,\n });\n \/\/ Check if the current url is the cm url.\n if (window.location.href == cm.url || window.location.href == `${course.baseurl}#${cm.anchor}`) {\n this.reactive.dispatch('setPageItem', 'cm', this.id);\n this.element.scrollIntoView({block: \"center\"});\n }\n \/\/ Check if this we are displaying this activity page.\n if (Config.contextid != Config.courseContextId && Config.contextInstanceId == this.id) {\n this.reactive.dispatch('setPageItem', 'cm', this.id, true);\n this.element.scrollIntoView({block: \"center\"});\n }\n \/\/ Add anchor logic if the element is not user visible.\n if (!cm.uservisible) {\n this.addEventListener(\n this.getElement(this.selectors.CM_NAME),\n 'click',\n this._activityAnchor,\n );\n }\n }\n\n \/**\n * Component watchers.\n *\n * @returns {Array} of watchers\n *\/\n getWatchers() {\n return [\n {watch: `cm[${this.id}]:deleted`, handler: this.remove},\n {watch: `cm[${this.id}]:updated`, handler: this._refreshCm},\n {watch: `cm[${this.id}].completionstate:updated`, handler: this._refreshCompletion},\n {watch: `course.pageItem:updated`, handler: this._refreshPageItem},\n ];\n }\n\n \/**\n * Update a course index cm using the state information.\n *\n * @param {object} param\n * @param {Object} param.element details the update details.\n *\/\n _refreshCm({element}) {\n \/\/ Update classes.\n this.element.classList.toggle(this.classes.CMHIDDEN, !element.visible);\n this.getElement(this.selectors.CM_NAME).innerHTML = element.name;\n this.element.classList.toggle(this.classes.DRAGGING, element.dragging ?? false);\n this.element.classList.toggle(this.classes.LOCKED, element.locked ?? false);\n this.element.classList.toggle(this.classes.RESTRICTIONS, element.hascmrestrictions ?? false);\n this.locked = element.locked;\n }\n\n \/**\n * Handle a page item update.\n *\n * @param {Object} details the update details\n * @param {Object} details.element the course state data.\n *\/\n _refreshPageItem({element}) {\n if (!element.pageItem) {\n return;\n }\n const isPageId = (element.pageItem.type == 'cm' && element.pageItem.id == this.id);\n this.element.classList.toggle(this.classes.PAGEITEM, isPageId);\n if (isPageId && !this.reactive.isEditing) {\n this.element.scrollIntoView({block: \"nearest\"});\n }\n }\n\n \/**\n * Update the activity completion icon.\n *\n * @param {Object} details the update details\n * @param {Object} details.state the state data\n * @param {Object} details.element the element data\n *\/\n async _refreshCompletion({state, element}) {\n \/\/ No completion icons are displayed in edit mode.\n if (this.reactive.isEditing || !element.istrackeduser) {\n return;\n }\n \/\/ Check if the completion value has changed.\n const completionElement = this.getElement(this.selectors.CM_COMPLETION);\n if (completionElement.dataset.value == element.completionstate) {\n return;\n }\n\n \/\/ Collect section information from the state.\n const exporter = this.reactive.getExporter();\n const data = exporter.cmCompletion(state, element);\n\n try {\n const {html, js} = await Templates.renderForPromise(completionTemplate, data);\n Templates.replaceNode(completionElement, html, js);\n } catch (error) {\n throw error;\n }\n }\n\n \/**\n * The activity anchor event.\n *\n * @param {Event} event\n *\/\n _activityAnchor(event) {\n const cm = this.reactive.get('cm', this.id);\n \/\/ If the user cannot access the element but the element is present in the page\n \/\/ the new url should be an anchor link.\n const element = document.getElementById(cm.anchor);\n if (element) {\n \/\/ Marc the element as page item once the event is handled.\n setTimeout(() => {\n this.reactive.dispatch('setPageItem', 'cm', cm.id);\n }, 50);\n return;\n }\n \/\/ If the element is not present in the page we need to go to the specific section.\n const course = this.reactive.get('course');\n const section = this.reactive.get('section', cm.sectionid);\n if (!section) {\n return;\n }\n const url = `${course.baseurl}§ion=${section.number}#${cm.anchor}`;\n event.preventDefault();\n window.location = url;\n }\n}\n"],"names":["prefetchTemplate","Component","DndCmItem","create","name","selectors","CM_NAME","CM_COMPLETION","classes","CMHIDDEN","LOCKED","RESTRICTIONS","PAGEITEM","id","this","element","dataset","target","document","getElementById","stateReady","state","configDragDrop","cm","get","course","_refreshCompletion","window","location","href","url","baseurl","anchor","reactive","dispatch","scrollIntoView","block","Config","contextid","courseContextId","contextInstanceId","uservisible","addEventListener","getElement","_activityAnchor","getWatchers","watch","handler","remove","_refreshCm","_refreshPageItem","classList","toggle","visible","innerHTML","DRAGGING","dragging","locked","hascmrestrictions","pageItem","isPageId","type","isEditing","istrackeduser","completionElement","value","completionstate","data","getExporter","cmCompletion","html","js","Templates","renderForPromise","replaceNode","error","event","setTimeout","section","sectionid","number","preventDefault"],"mappings":"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"}