{"version":3,"file":"actions.min.js","sources":["https:\/\/recursosorientacion.agenciaeducacion.gob.cl\/course\/format\/amd\/src\/local\/content\/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 .\n\n\/**\n * Course state actions dispatcher.\n *\n * This module captures all data-dispatch links in the course content and dispatch the proper\n * state mutation, including any confirmation and modal required.\n *\n * @module core_courseformat\/local\/content\/actions\n * @class core_courseformat\/local\/content\/actions\n * @copyright 2021 Ferran Recio \n * @license http:\/\/www.gnu.org\/copyleft\/gpl.html GNU GPL v3 or later\n *\/\n\nimport {BaseComponent} from 'core\/reactive';\nimport ModalFactory from 'core\/modal_factory';\nimport ModalEvents from 'core\/modal_events';\nimport Templates from 'core\/templates';\nimport {prefetchStrings} from 'core\/prefetch';\nimport {get_string as getString} from 'core\/str';\nimport {getList} from 'core\/normalise';\nimport * as CourseEvents from 'core_course\/events';\nimport Pending from 'core\/pending';\nimport ContentTree from 'core_courseformat\/local\/courseeditor\/contenttree';\n\/\/ The jQuery module is only used for interacting with Boostrap 4. It can we removed when MDL-71979 is integrated.\nimport jQuery from 'jquery';\n\n\/\/ Load global strings.\nprefetchStrings('core', ['movecoursesection', 'movecoursemodule', 'confirm', 'delete']);\n\nexport default class extends BaseComponent {\n\n \/**\n * Constructor hook.\n *\/\n create() {\n \/\/ Optional component name for debugging.\n this.name = 'content_actions';\n \/\/ Default query selectors.\n this.selectors = {\n ACTIONLINK: `[data-action]`,\n \/\/ Move modal selectors.\n SECTIONLINK: `[data-for='section']`,\n CMLINK: `[data-for='cm']`,\n SECTIONNODE: `[data-for='sectionnode']`,\n MODALTOGGLER: `[data-toggle='collapse']`,\n ADDSECTION: `[data-action='addSection']`,\n CONTENTTREE: `#destination-selector`,\n ACTIONMENU: `.action-menu`,\n ACTIONMENUTOGGLER: `[data-toggle=\"dropdown\"]`,\n };\n \/\/ Component css classes.\n this.classes = {\n DISABLED: `disabled`,\n };\n }\n\n \/**\n * Initial state ready method.\n *\n * @param {Object} state the state data.\n *\n *\/\n stateReady(state) {\n \/\/ Delegate dispatch clicks.\n this.addEventListener(\n this.element,\n 'click',\n this._dispatchClick\n );\n \/\/ Check section limit.\n this._checkSectionlist({state});\n \/\/ Add an Event listener to recalculate limits it if a section HTML is altered.\n this.addEventListener(\n this.element,\n CourseEvents.sectionRefreshed,\n () => this._checkSectionlist({state})\n );\n }\n\n \/**\n * Return the component watchers.\n *\n * @returns {Array} of watchers\n *\/\n getWatchers() {\n return [\n \/\/ Check section limit.\n {watch: `course.sectionlist:updated`, handler: this._checkSectionlist},\n ];\n }\n\n _dispatchClick(event) {\n const target = event.target.closest(this.selectors.ACTIONLINK);\n if (!target) {\n return;\n }\n if (target.classList.contains(this.classes.DISABLED)) {\n event.preventDefault();\n return;\n }\n\n \/\/ Invoke proper method.\n const methodName = this._actionMethodName(target.dataset.action);\n\n if (this[methodName] !== undefined) {\n this[methodName](target, event);\n }\n }\n\n _actionMethodName(name) {\n const requestName = name.charAt(0).toUpperCase() + name.slice(1);\n return `_request${requestName}`;\n }\n\n \/**\n * Check the section list and disable some options if needed.\n *\n * @param {Object} detail the update details.\n * @param {Object} detail.state the state object.\n *\/\n _checkSectionlist({state}) {\n \/\/ Disable \"add section\" actions if the course max sections has been exceeded.\n this._setAddSectionLocked(state.course.sectionlist.length > state.course.maxsections);\n }\n\n \/**\n * Handle a move section request.\n *\n * @param {Element} target the dispatch action element\n * @param {Event} event the triggered event\n *\/\n async _requestMoveSection(target, event) {\n \/\/ Check we have an id.\n const sectionId = target.dataset.id;\n if (!sectionId) {\n return;\n }\n const sectionInfo = this.reactive.get('section', sectionId);\n\n event.preventDefault();\n\n \/\/ The section edit menu to refocus on end.\n const editTools = this._getClosestActionMenuToogler(target);\n\n \/\/ Collect section information from the state.\n const exporter = this.reactive.getExporter();\n const data = exporter.course(this.reactive.state);\n\n \/\/ Add the target section id and title.\n data.sectionid = sectionInfo.id;\n data.sectiontitle = sectionInfo.title;\n\n \/\/ Build the modal parameters from the event data.\n const modalParams = {\n title: getString('movecoursesection', 'core'),\n body: Templates.render('core_courseformat\/local\/content\/movesection', data),\n };\n\n \/\/ Create the modal.\n const modal = await this._modalBodyRenderedPromise(modalParams);\n\n const modalBody = getList(modal.getBody())[0];\n\n \/\/ Disable current element and section zero.\n const currentElement = modalBody.querySelector(`${this.selectors.SECTIONLINK}[data-id='${sectionId}']`);\n this._disableLink(currentElement);\n const generalSection = modalBody.querySelector(`${this.selectors.SECTIONLINK}[data-number='0']`);\n this._disableLink(generalSection);\n\n \/\/ Setup keyboard navigation.\n new ContentTree(\n modalBody.querySelector(this.selectors.CONTENTTREE),\n {\n SECTION: this.selectors.SECTIONNODE,\n TOGGLER: this.selectors.MODALTOGGLER,\n COLLAPSE: this.selectors.MODALTOGGLER,\n },\n true\n );\n\n \/\/ Capture click.\n modalBody.addEventListener('click', (event) => {\n const target = event.target;\n if (!target.matches('a') || target.dataset.for != 'section' || target.dataset.id === undefined) {\n return;\n }\n if (target.getAttribute('aria-disabled')) {\n return;\n }\n event.preventDefault();\n this.reactive.dispatch('sectionMove', [sectionId], target.dataset.id);\n this._destroyModal(modal, editTools);\n });\n }\n\n \/**\n * Handle a move cm request.\n *\n * @param {Element} target the dispatch action element\n * @param {Event} event the triggered event\n *\/\n async _requestMoveCm(target, event) {\n \/\/ Check we have an id.\n const cmId = target.dataset.id;\n if (!cmId) {\n return;\n }\n const cmInfo = this.reactive.get('cm', cmId);\n\n event.preventDefault();\n\n \/\/ The section edit menu to refocus on end.\n const editTools = this._getClosestActionMenuToogler(target);\n\n \/\/ Collect section information from the state.\n const exporter = this.reactive.getExporter();\n const data = exporter.course(this.reactive.state);\n\n \/\/ Add the target cm info.\n data.cmid = cmInfo.id;\n data.cmname = cmInfo.name;\n\n \/\/ Build the modal parameters from the event data.\n const modalParams = {\n title: getString('movecoursemodule', 'core'),\n body: Templates.render('core_courseformat\/local\/content\/movecm', data),\n };\n\n \/\/ Create the modal.\n const modal = await this._modalBodyRenderedPromise(modalParams);\n\n const modalBody = getList(modal.getBody())[0];\n\n \/\/ Disable current element.\n let currentElement = modalBody.querySelector(`${this.selectors.CMLINK}[data-id='${cmId}']`);\n this._disableLink(currentElement);\n\n \/\/ Setup keyboard navigation.\n new ContentTree(\n modalBody.querySelector(this.selectors.CONTENTTREE),\n {\n SECTION: this.selectors.SECTIONNODE,\n TOGGLER: this.selectors.MODALTOGGLER,\n COLLAPSE: this.selectors.MODALTOGGLER,\n ENTER: this.selectors.SECTIONLINK,\n }\n );\n\n \/\/ Open the cm section node if possible (Bootstrap 4 uses jQuery to interact with collapsibles).\n \/\/ All jQuery int this code can be replaced when MDL-71979 is integrated.\n const sectionnode = currentElement.closest(this.selectors.SECTIONNODE);\n const toggler = jQuery(sectionnode).find(this.selectors.MODALTOGGLER);\n let collapsibleId = toggler.data('target') ?? toggler.attr('href');\n if (collapsibleId) {\n \/\/ We cannot be sure we have # in the id element name.\n collapsibleId = collapsibleId.replace('#', '');\n jQuery(`#${collapsibleId}`).collapse('toggle');\n }\n\n \/\/ Capture click.\n modalBody.addEventListener('click', (event) => {\n const target = event.target;\n if (!target.matches('a') || target.dataset.for === undefined || target.dataset.id === undefined) {\n return;\n }\n if (target.getAttribute('aria-disabled')) {\n return;\n }\n event.preventDefault();\n\n \/\/ Get draggable data from cm or section to dispatch.\n let targetSectionId;\n let targetCmId;\n if (target.dataset.for == 'cm') {\n const dropData = exporter.cmDraggableData(this.reactive.state, target.dataset.id);\n targetSectionId = dropData.sectionid;\n targetCmId = dropData.nextcmid;\n } else {\n const section = this.reactive.get('section', target.dataset.id);\n targetSectionId = target.dataset.id;\n targetCmId = section?.cmlist[0];\n }\n\n this.reactive.dispatch('cmMove', [cmId], targetSectionId, targetCmId);\n this._destroyModal(modal, editTools);\n });\n }\n\n \/**\n * Handle a create section request.\n *\n * @param {Element} target the dispatch action element\n * @param {Event} event the triggered event\n *\/\n async _requestAddSection(target, event) {\n event.preventDefault();\n this.reactive.dispatch('addSection', target.dataset.id ?? 0);\n }\n\n \/**\n * Handle a delete section request.\n *\n * @param {Element} target the dispatch action element\n * @param {Event} event the triggered event\n *\/\n async _requestDeleteSection(target, event) {\n \/\/ Check we have an id.\n const sectionId = target.dataset.id;\n\n if (!sectionId) {\n return;\n }\n const sectionInfo = this.reactive.get('section', sectionId);\n\n event.preventDefault();\n\n const cmList = sectionInfo.cmlist ?? [];\n if (cmList.length || sectionInfo.hassummary || sectionInfo.rawtitle) {\n \/\/ We need confirmation if the section has something.\n const modalParams = {\n title: getString('confirm', 'core'),\n body: getString('confirmdeletesection', 'moodle', sectionInfo.title),\n saveButtonText: getString('delete', 'core'),\n type: ModalFactory.types.SAVE_CANCEL,\n };\n\n const modal = await this._modalBodyRenderedPromise(modalParams);\n\n modal.getRoot().on(\n ModalEvents.save,\n e => {\n \/\/ Stop the default save button behaviour which is to close the modal.\n e.preventDefault();\n modal.destroy();\n this.reactive.dispatch('sectionDelete', [sectionId]);\n }\n );\n return;\n } else {\n \/\/ We don't need confirmation to delete empty sections.\n this.reactive.dispatch('sectionDelete', [sectionId]);\n }\n }\n\n \/**\n * Disable all add sections actions.\n *\n * @param {boolean} locked the new locked value.\n *\/\n _setAddSectionLocked(locked) {\n const targets = this.getElements(this.selectors.ADDSECTION);\n targets.forEach(element => {\n element.classList.toggle(this.classes.DISABLED, locked);\n this.setElementLocked(element, locked);\n });\n }\n\n \/**\n * Replace an element with a copy with a different tag name.\n *\n * @param {Element} element the original element\n *\/\n _disableLink(element) {\n if (element) {\n element.style.pointerEvents = 'none';\n element.style.userSelect = 'none';\n element.classList.add(this.classes.DISABLED);\n element.setAttribute('aria-disabled', true);\n element.addEventListener('click', event => event.preventDefault());\n }\n }\n\n \/**\n * Render a modal and return a body ready promise.\n *\n * @param {object} modalParams the modal params\n * @return {Promise} the modal body ready promise\n *\/\n _modalBodyRenderedPromise(modalParams) {\n return new Promise((resolve, reject) => {\n ModalFactory.create(modalParams).then((modal) => {\n modal.setRemoveOnClose(true);\n \/\/ Handle body loading event.\n modal.getRoot().on(ModalEvents.bodyRendered, () => {\n resolve(modal);\n });\n \/\/ Configure some extra modal params.\n if (modalParams.saveButtonText !== undefined) {\n modal.setSaveButtonText(modalParams.saveButtonText);\n }\n modal.show();\n return;\n }).catch(() => {\n reject(`Cannot load modal content`);\n });\n });\n }\n\n \/**\n * Hide and later destroy a modal.\n *\n * Behat will fail if we remove the modal while some boostrap collapse is executing.\n *\n * @param {Modal} modal\n * @param {HTMLElement} element the dom element to focus on.\n *\/\n _destroyModal(modal, element) {\n modal.hide();\n const pendingDestroy = new Pending(`courseformat\/actions:destroyModal`);\n if (element) {\n element.focus();\n }\n setTimeout(() =>{\n modal.destroy();\n pendingDestroy.resolve();\n }, 500);\n }\n\n \/**\n * Get the closest actions menu toggler to an action element.\n *\n * @param {HTMLElement} element the action link element\n * @returns {HTMLElement|undefined}\n *\/\n _getClosestActionMenuToogler(element) {\n const actionMenu = element.closest(this.selectors.ACTIONMENU);\n if (!actionMenu) {\n return undefined;\n }\n return actionMenu.querySelector(this.selectors.ACTIONMENUTOGGLER);\n }\n}\n"],"names":["BaseComponent","create","name","selectors","ACTIONLINK","SECTIONLINK","CMLINK","SECTIONNODE","MODALTOGGLER","ADDSECTION","CONTENTTREE","ACTIONMENU","ACTIONMENUTOGGLER","classes","DISABLED","stateReady","state","addEventListener","this","element","_dispatchClick","_checkSectionlist","CourseEvents","sectionRefreshed","getWatchers","watch","handler","event","target","closest","classList","contains","preventDefault","methodName","_actionMethodName","dataset","action","undefined","requestName","charAt","toUpperCase","slice","_setAddSectionLocked","course","sectionlist","length","maxsections","sectionId","id","sectionInfo","reactive","get","editTools","_getClosestActionMenuToogler","data","getExporter","sectionid","sectiontitle","title","modalParams","body","Templates","render","modal","_modalBodyRenderedPromise","modalBody","getBody","currentElement","querySelector","_disableLink","generalSection","ContentTree","SECTION","TOGGLER","COLLAPSE","matches","for","getAttribute","dispatch","_destroyModal","cmId","cmInfo","exporter","cmid","cmname","ENTER","sectionnode","toggler","find","collapsibleId","attr","replace","collapse","targetSectionId","targetCmId","dropData","cmDraggableData","nextcmid","section","cmlist","hassummary","rawtitle","saveButtonText","type","ModalFactory","types","SAVE_CANCEL","getRoot","on","ModalEvents","save","e","destroy","locked","getElements","forEach","toggle","setElementLocked","style","pointerEvents","userSelect","add","setAttribute","Promise","resolve","reject","then","setRemoveOnClose","bodyRendered","setSaveButtonText","show","catch","hide","pendingDestroy","Pending","focus","setTimeout","actionMenu"],"mappings":"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\/B,yBAM5CG,SAAS4B,SAAS,gBAAiB,CAAC\/B,YASjDL,qBAAqBuE,QACD\/F,KAAKgG,YAAYhG,KAAKf,UAAUM,YACxC0G,SAAQhG,UACZA,QAAQW,UAAUsF,OAAOlG,KAAKL,QAAQC,SAAUmG,aAC3CI,iBAAiBlG,QAAS8F,WASvC5C,aAAalD,SACLA,UACAA,QAAQmG,MAAMC,cAAgB,OAC9BpG,QAAQmG,MAAME,WAAa,OAC3BrG,QAAQW,UAAU2F,IAAIvG,KAAKL,QAAQC,UACnCK,QAAQuG,aAAa,iBAAiB,GACtCvG,QAAQF,iBAAiB,SAASU,OAASA,MAAMK,oBAUzDgC,0BAA0BL,oBACf,IAAIgE,SAAQ,CAACC,QAASC,iCACZ5H,OAAO0D,aAAamE,MAAM\/D,QACnCA,MAAMgE,kBAAiB,GAEvBhE,MAAM4C,UAAUC,GAAGC,sBAAYmB,cAAc,KACzCJ,QAAQ7D,eAGuB1B,IAA\/BsB,YAAY2C,gBACZvC,MAAMkE,kBAAkBtE,YAAY2C,gBAExCvC,MAAMmE,UAEPC,OAAM,KACLN,0CAaZ9C,cAAchB,MAAO5C,SACjB4C,MAAMqE,aACAC,eAAiB,IAAIC,sDACvBnH,SACAA,QAAQoH,QAEZC,YAAW,KACPzE,MAAMiD,UACNqB,eAAeT,YAChB,KASPvE,6BAA6BlC,eACnBsH,WAAatH,QAAQU,QAAQX,KAAKf,UAAUQ,eAC7C8H,kBAGEA,WAAWrE,cAAclD,KAAKf,UAAUS"}