diff --git a/amd/build/management.min.js b/amd/build/management.min.js index 0ecd1fb..6f3228f 100644 --- a/amd/build/management.min.js +++ b/amd/build/management.min.js @@ -6,6 +6,6 @@ define("tiny_elements/management",["exports","tiny_elements/previewmodal","core_ * @copyright 2024 ISB Bayern * @author Tobias Garske * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.wipe=_exports.init=_exports.duplicateItem=_exports.deleteItem=void 0,_modalform=_interopRequireDefault(_modalform),_notification=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(_notification),_log=_interopRequireDefault(_log);_exports.init=async params=>{document.getElementById("elements_import").addEventListener("click",(async e=>{importModal(e)})),document.getElementsByClassName("add").forEach((element=>{element.addEventListener("click",(async e=>{showModal(e,element.dataset.id,element.dataset.table)}))})),document.getElementsByClassName("edit").forEach((element=>{element.addEventListener("click",(async e=>{showModal(e,element.dataset.id,element.dataset.table)}))})),document.getElementsByClassName("delete").forEach((element=>{element.addEventListener("click",(async e=>{deleteModal(e,element.dataset.id,element.dataset.title,element.dataset.table)}))})),document.getElementsByClassName("preview-button").forEach((element=>{element.addEventListener("click",(async e=>{previewModal(e)}))})),document.getElementsByClassName("compcat").forEach((element=>{element.addEventListener("click",(async e=>{showItems(e,element.dataset.compcat)}))})),document.getElementsByClassName("editlicenses").forEach((element=>{element.addEventListener("click",(async e=>{editlicensesModal(e,element.dataset.id)}))})),document.querySelectorAll(".buttonicons").forEach((element=>{element.addEventListener("click",(async e=>{compflavorModal(e)}))})),document.getElementById("elements_displaynames_button").addEventListener("click",(async e=>{displaynamesModal(e)})),document.getElementById("elements_displaynames_flavor_button").addEventListener("click",(async e=>{displaynamesFlavorModal(e)})),document.getElementById("elements_displaynames_variant_button").addEventListener("click",(async e=>{displaynamesVariantModal(e)})),document.getElementsByClassName("duplicate").forEach((element=>{element.addEventListener("click",(async()=>{duplicateItem(element.dataset.id,element.dataset.table).always((()=>reload()))}))}));let wipebutton=document.getElementById("elements_wipe");if(wipebutton&&wipebutton.addEventListener("click",(async e=>{wipeModal(e)})),document.querySelectorAll(".flavor .card-body > .clickingextended, .component .card-body > .clickingextended, .variant .card-body > .clickingextended").forEach((element=>{element.addEventListener("click",(async e=>{e.target.closest(".item").querySelector("a.edit").click()}))})),params.compcatactive){let compcat=document.querySelector('.compcat[data-compcat="'+params.compcatactive+'"]');compcat&&(showItems(!1,params.compcatactive),compcat.classList.add("active"))}};const showModal=async(event,id,table)=>{let title;event.preventDefault(),title=0==id?(0,_str.get_string)("additem","tiny_elements"):(0,_str.get_string)("edititem","tiny_elements");const modalForm=new _modalform.default({formClass:"tiny_elements\\form\\management_"+table+"_form",args:{id:id,compcat:getActiveCompcatId(),categoryname:getActiveCompcatName()},modalConfig:{title:title},returnFocus:event.target});modalForm.addEventListener(modalForm.events.FORM_SUBMITTED,(()=>reload())),await modalForm.show()},previewModal=async event=>{event.preventDefault();let preview=event.target.closest(".preview-button");const modal=await _previewmodal.PreviewModal.create({templateContext:{component:preview.dataset.component,flavors:preview.dataset.flavors.trim().split(" "),config:M.cfg}});await modal.show()},importModal=async event=>{event.preventDefault();let title=(0,_str.get_string)("import","tiny_elements");const modalForm=new _modalform.default({formClass:"tiny_elements\\form\\management_import_form",args:{},modalConfig:{title:title}});modalForm.addEventListener(modalForm.events.FORM_SUBMITTED,importModalSubmitted),await modalForm.show()},importModalSubmitted=async event=>{event.detail.update?location.reload():(event.stopPropagation(),(0,_templates.render)("tiny_elements/management_import_form_result",event.detail).then((async html=>(await _notification.default.alert((0,_str.get_string)("import_simulation","tiny_elements"),html,(0,_str.get_string)("close","tiny_elements")),!0))).catch((error=>{(0,_notification.exception)(error)})))},compflavorModal=async event=>{var _target$dataset$compo,_target$dataset$flavo;event.preventDefault();let title=(0,_str.get_string)("manage","tiny_elements");const target=event.target.closest(".buttonicons"),component=null!==(_target$dataset$compo=target.dataset.component)&&void 0!==_target$dataset$compo?_target$dataset$compo:"",flavor=null!==(_target$dataset$flavo=target.dataset.flavor)&&void 0!==_target$dataset$flavo?_target$dataset$flavo:"",modalForm=new _modalform.default({formClass:"tiny_elements\\form\\management_comp_flavor_form",args:{component:component,flavor:flavor},modalConfig:{title:title}});await modalForm.show()},editlicensesModal=async(event,id)=>{event.preventDefault();let title=(0,_str.get_string)("editlicenses","tiny_elements");const modalForm=new _modalform.default({formClass:"tiny_elements\\form\\management_editlicense_form",args:{id:id},modalConfig:{title:title}});await modalForm.show()},displaynamesModal=async event=>{event.preventDefault();let title=(0,_str.get_string)("manage","tiny_elements");const modalForm=new _modalform.default({formClass:"tiny_elements\\form\\management_displaynames_form",args:{},modalConfig:{title:title}});modalForm.addEventListener(modalForm.events.FORM_SUBMITTED,(()=>location.reload())),await modalForm.show()},displaynamesFlavorModal=async event=>{event.preventDefault();let title=(0,_str.get_string)("manage","tiny_elements");const modalForm=new _modalform.default({formClass:"tiny_elements\\form\\management_displaynames_flavors_form",args:{},modalConfig:{title:title}});modalForm.addEventListener(modalForm.events.FORM_SUBMITTED,(()=>location.reload())),await modalForm.show()},displaynamesVariantModal=async event=>{event.preventDefault();let title=(0,_str.get_string)("manage","tiny_elements");const modalForm=new _modalform.default({formClass:"tiny_elements\\form\\management_displaynames_variants_form",args:{},modalConfig:{title:title}});modalForm.addEventListener(modalForm.events.FORM_SUBMITTED,(()=>location.reload())),await modalForm.show()},deleteModal=(event,id,title,table)=>{event.preventDefault(),(0,_notification.deleteCancelPromise)((0,_str.get_string)("delete","tiny_elements",title),(0,_str.get_string)("deletewarning","tiny_elements")).then((async()=>{if(0!==id)try{if(await deleteItem(id,table)){const link=document.querySelector('[data-table="'+table+'"][data-id="'+id+'"]');if(link){link.closest(".item").remove()}}}catch(error){(0,_notification.exception)(error)}})).catch((err=>{err.message&&_log.default.error(err.message)}))},wipeModal=event=>{event.preventDefault(),(0,_notification.deleteCancelPromise)((0,_str.get_string)("wipe","tiny_elements"),(0,_str.get_string)("wipewarning","tiny_elements")).then((async()=>{try{await wipe(),reload()}catch(error){(0,_notification.exception)(error)}})).catch((err=>{err.message&&_log.default.error(err.message)}))},deleteItem=(id,table)=>(0,_ajax.call)([{methodname:"tiny_elements_delete_item",args:{id:id,table:table}}])[0];_exports.deleteItem=deleteItem;const wipe=()=>(0,_ajax.call)([{methodname:"tiny_elements_wipe",args:{contextid:1}}])[0];_exports.wipe=wipe;const showItems=(event,compcat)=>{document.querySelectorAll(".flavor, .component, .variant").forEach((element=>{element.classList.add("hidden")}));let itemsShow=document.querySelectorAll('[data-categoryname="'+compcat+'"]'),usedFlavors=[];itemsShow.forEach((element=>{if(element.classList.remove("hidden"),void 0!==element.dataset.flavors){let flavors=element.dataset.flavors.split(" ");for(let value of flavors)usedFlavors.includes(value)||0==value.length||usedFlavors.push(value)}}));let flavorstring=usedFlavors.map((item=>".".concat(item))).join(", ");if(flavorstring.length){document.querySelectorAll(flavorstring).forEach((element=>{element.classList.remove("hidden")}))}if(document.getElementsByClassName("addcontainer").forEach((element=>{element.classList.remove("hidden")})),event){document.getElementsByClassName("compcat").forEach((element=>{element.classList.remove("active")})),event.target.closest(".compcat").classList.add("active")}if("found-items"==compcat){let found=document.querySelector('.compcat[data-compcat="found-items"]');if(found.dataset.loneflavors.length){document.querySelectorAll(found.dataset.loneflavors).forEach((element=>{element.classList.remove("hidden")}))}if(found.dataset.lonevariants.length){document.querySelectorAll(found.dataset.lonevariants).forEach((element=>{element.classList.remove("hidden")}))}if(found.dataset.lonecomponents.length){document.querySelectorAll(found.dataset.lonecomponents).forEach((element=>{element.classList.remove("hidden")}))}}},reload=()=>{const currentUrl=new URL(window.location.href);currentUrl.searchParams.set("compcat",getActiveCompcatName()),window.location.href=currentUrl.toString(),window.location.reload()},getActiveCompcatName=()=>{var _compcat$dataset$comp;const compcat=document.querySelector(".compcat.active");return compcat&&null!==(_compcat$dataset$comp=compcat.dataset.compcat)&&void 0!==_compcat$dataset$comp?_compcat$dataset$comp:""},getActiveCompcatId=()=>{var _compcat$dataset$id;const compcat=document.querySelector(".compcat.active");return compcat&&null!==(_compcat$dataset$id=compcat.dataset.id)&&void 0!==_compcat$dataset$id?_compcat$dataset$id:0},duplicateItem=(id,table)=>(0,_ajax.call)([{methodname:"tiny_elements_duplicate_item",args:{id:id,table:table}}])[0];_exports.duplicateItem=duplicateItem})); + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.wipe=_exports.init=_exports.duplicateItem=_exports.deleteItem=void 0,_modalform=_interopRequireDefault(_modalform),_notification=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(_notification),_log=_interopRequireDefault(_log);_exports.init=async params=>{document.getElementById("elements_import").addEventListener("click",(async e=>{importModal(e)})),document.getElementsByClassName("add").forEach((element=>{element.addEventListener("click",(async e=>{showModal(e,element.dataset.id,element.dataset.table)}))})),document.getElementsByClassName("edit").forEach((element=>{element.addEventListener("click",(async e=>{showModal(e,element.dataset.id,element.dataset.table)}))})),document.getElementsByClassName("delete").forEach((element=>{element.addEventListener("click",(async e=>{deleteModal(e,element.dataset.id,element.dataset.title,element.dataset.table)}))})),document.getElementsByClassName("preview-button").forEach((element=>{element.addEventListener("click",(async e=>{previewModal(e)}))})),document.getElementsByClassName("compcat").forEach((element=>{element.addEventListener("click",(async e=>{showItems(e,element.dataset.compcat)}))})),document.getElementsByClassName("editlicenses").forEach((element=>{element.addEventListener("click",(async e=>{editlicensesModal(e,element.dataset.id)}))})),document.querySelectorAll(".buttonicons").forEach((element=>{element.addEventListener("click",(async e=>{compflavorModal(e)}))})),document.getElementById("elements_displaynames_button").addEventListener("click",(async e=>{displaynamesModal(e)})),document.getElementById("elements_displaynames_flavor_button").addEventListener("click",(async e=>{displaynamesFlavorModal(e)})),document.getElementById("elements_displaynames_variant_button").addEventListener("click",(async e=>{displaynamesVariantModal(e)})),document.getElementsByClassName("duplicate").forEach((element=>{element.addEventListener("click",(async()=>{duplicateItem(element.dataset.id,element.dataset.table).always((()=>reload()))}))}));let wipebutton=document.getElementById("elements_wipe");if(wipebutton&&wipebutton.addEventListener("click",(async e=>{wipeModal(e)})),document.querySelectorAll(".flavor .card-body > .clickingextended, .component .card-body > .clickingextended, .variant .card-body > .clickingextended").forEach((element=>{element.addEventListener("click",(async e=>{e.target.closest(".item").querySelector("a.edit").click()}))})),params.compcatactive){let compcat=document.querySelector('.compcat[data-compcat="'+params.compcatactive+'"]');compcat&&(showItems(!1,params.compcatactive),compcat.classList.add("active"))}};const showModal=async(event,id,table)=>{let title;event.preventDefault(),title=0==id?(0,_str.get_string)("additem","tiny_elements"):(0,_str.get_string)("edititem","tiny_elements");const modalForm=new _modalform.default({formClass:"tiny_elements\\form\\management_"+table+"_form",args:{id:id,compcat:getActiveCompcatId(),categoryname:getActiveCompcatName()},modalConfig:{title:title},returnFocus:event.target});modalForm.addEventListener(modalForm.events.FORM_SUBMITTED,(()=>reload())),await modalForm.show()},previewModal=async event=>{event.preventDefault();let preview=event.target.closest(".preview-button");const modal=await _previewmodal.PreviewModal.create({templateContext:{component:preview.dataset.component,flavors:preview.dataset.flavors.trim().split(" "),config:M.cfg}});await modal.show()},importModal=async event=>{event.preventDefault();let title=(0,_str.get_string)("import","tiny_elements");const modalForm=new _modalform.default({formClass:"tiny_elements\\form\\management_import_form",args:{},modalConfig:{title:title}});modalForm.addEventListener(modalForm.events.FORM_SUBMITTED,importModalSubmitted),await modalForm.show()},importModalSubmitted=async event=>{event.detail.update?location.reload():(event.stopPropagation(),(0,_templates.render)("tiny_elements/management_import_form_result",event.detail).then((async html=>(await _notification.default.alert((0,_str.get_string)("import_simulation","tiny_elements"),html,(0,_str.get_string)("close","tiny_elements")),!0))).catch((error=>{(0,_notification.exception)(error)})))},compflavorModal=async event=>{var _target$dataset$compo,_target$dataset$flavo;event.preventDefault();let title=(0,_str.get_string)("manage","tiny_elements");const target=event.target.closest(".buttonicons"),component=null!==(_target$dataset$compo=target.dataset.component)&&void 0!==_target$dataset$compo?_target$dataset$compo:"",flavor=null!==(_target$dataset$flavo=target.dataset.flavor)&&void 0!==_target$dataset$flavo?_target$dataset$flavo:"",modalForm=new _modalform.default({formClass:"tiny_elements\\form\\management_comp_flavor_form",args:{component:component,flavor:flavor},modalConfig:{title:title}});await modalForm.show()},editlicensesModal=async(event,id)=>{event.preventDefault();let title=(0,_str.get_string)("editlicenses","tiny_elements");const modalForm=new _modalform.default({formClass:"tiny_elements\\form\\management_editlicense_form",args:{id:id},modalConfig:{title:title}});await modalForm.show()},displaynamesModal=async event=>{event.preventDefault();let title=(0,_str.get_string)("manage","tiny_elements");const modalForm=new _modalform.default({formClass:"tiny_elements\\form\\management_displaynames_form",args:{},modalConfig:{title:title}});modalForm.addEventListener(modalForm.events.FORM_SUBMITTED,(()=>location.reload())),await modalForm.show()},displaynamesFlavorModal=async event=>{event.preventDefault();let title=(0,_str.get_string)("manage","tiny_elements");const modalForm=new _modalform.default({formClass:"tiny_elements\\form\\management_displaynames_flavors_form",args:{},modalConfig:{title:title}});modalForm.addEventListener(modalForm.events.FORM_SUBMITTED,(()=>location.reload())),await modalForm.show()},displaynamesVariantModal=async event=>{event.preventDefault();let title=(0,_str.get_string)("manage","tiny_elements");const modalForm=new _modalform.default({formClass:"tiny_elements\\form\\management_displaynames_variants_form",args:{},modalConfig:{title:title}});modalForm.addEventListener(modalForm.events.FORM_SUBMITTED,(()=>location.reload())),await modalForm.show()},deleteModal=(event,id,title,table)=>{event.preventDefault(),(0,_notification.deleteCancelPromise)((0,_str.get_string)("delete","tiny_elements",title),(0,_str.get_string)("deletewarning","tiny_elements")).then((async()=>{if(0!==id)try{if(await deleteItem(id,table)){const link=document.querySelector('[data-table="'+table+'"][data-id="'+id+'"]');if(link){link.closest(".item").remove()}}}catch(error){(0,_notification.exception)(error)}})).catch((err=>{err.message&&_log.default.error(err.message)}))},wipeModal=event=>{event.preventDefault(),(0,_notification.deleteCancelPromise)((0,_str.get_string)("wipe","tiny_elements"),(0,_str.get_string)("wipewarning","tiny_elements")).then((async()=>{try{return await wipe(),void reload()}catch(error){return void(0,_notification.exception)(error)}})).catch((err=>{err.message&&_log.default.error(err.message)}))},deleteItem=(id,table)=>(0,_ajax.call)([{methodname:"tiny_elements_delete_item",args:{id:id,table:table}}])[0];_exports.deleteItem=deleteItem;const wipe=()=>(0,_ajax.call)([{methodname:"tiny_elements_wipe",args:{contextid:1}}])[0];_exports.wipe=wipe;const showItems=(event,compcat)=>{document.querySelectorAll(".flavor, .component, .variant").forEach((element=>{element.classList.add("hidden")}));let itemsShow=document.querySelectorAll('[data-categoryname="'+compcat+'"]'),usedFlavors=[];itemsShow.forEach((element=>{if(element.classList.remove("hidden"),void 0!==element.dataset.flavors){let flavors=element.dataset.flavors.split(" ");for(let value of flavors)usedFlavors.includes(value)||0==value.length||usedFlavors.push(value)}}));let flavorstring=usedFlavors.map((item=>".".concat(item))).join(", ");if(flavorstring.length){document.querySelectorAll(flavorstring).forEach((element=>{element.classList.remove("hidden")}))}if(document.getElementsByClassName("addcontainer").forEach((element=>{element.classList.remove("hidden")})),event){document.getElementsByClassName("compcat").forEach((element=>{element.classList.remove("active")})),event.target.closest(".compcat").classList.add("active")}if("found-items"==compcat){let found=document.querySelector('.compcat[data-compcat="found-items"]');if(found.dataset.loneflavors.length){document.querySelectorAll(found.dataset.loneflavors).forEach((element=>{element.classList.remove("hidden")}))}if(found.dataset.lonevariants.length){document.querySelectorAll(found.dataset.lonevariants).forEach((element=>{element.classList.remove("hidden")}))}if(found.dataset.lonecomponents.length){document.querySelectorAll(found.dataset.lonecomponents).forEach((element=>{element.classList.remove("hidden")}))}}},reload=()=>{const currentUrl=new URL(window.location.href);currentUrl.searchParams.set("compcat",getActiveCompcatName()),window.location.href=currentUrl.toString(),window.location.reload()},getActiveCompcatName=()=>{var _compcat$dataset$comp;const compcat=document.querySelector(".compcat.active");return compcat&&null!==(_compcat$dataset$comp=compcat.dataset.compcat)&&void 0!==_compcat$dataset$comp?_compcat$dataset$comp:""},getActiveCompcatId=()=>{var _compcat$dataset$id;const compcat=document.querySelector(".compcat.active");return compcat&&null!==(_compcat$dataset$id=compcat.dataset.id)&&void 0!==_compcat$dataset$id?_compcat$dataset$id:0},duplicateItem=(id,table)=>(0,_ajax.call)([{methodname:"tiny_elements_duplicate_item",args:{id:id,table:table}}])[0];_exports.duplicateItem=duplicateItem})); //# sourceMappingURL=management.min.js.map \ No newline at end of file diff --git a/amd/build/management.min.js.map b/amd/build/management.min.js.map index 5db611b..4180dd3 100644 --- a/amd/build/management.min.js.map +++ b/amd/build/management.min.js.map @@ -1 +1 @@ -{"version":3,"file":"management.min.js","sources":["../src/management.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 * Management functions for tiny_elements admin backend.\n *\n * @module tiny_elements/management\n * @copyright 2024 ISB Bayern\n * @author Tobias Garske\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {PreviewModal} from 'tiny_elements/previewmodal';\nimport ModalForm from 'core_form/modalform';\nimport Notification from 'core/notification';\nimport {get_string as getString} from 'core/str';\nimport {exception as displayException, deleteCancelPromise} from 'core/notification';\nimport {call as fetchMany} from 'core/ajax';\nimport {render as renderTemplate} from 'core/templates';\nimport Log from 'core/log';\n\nexport const init = async(params) => {\n\n // Add listener to import xml files.\n let importxml = document.getElementById('elements_import');\n importxml.addEventListener('click', async(e) => {\n importModal(e);\n });\n\n // Add listener for adding a new item.\n let additem = document.getElementsByClassName('add');\n additem.forEach(element => {\n element.addEventListener('click', async(e) => {\n showModal(e, element.dataset.id, element.dataset.table);\n });\n });\n\n // Add listener to edit items.\n let edititems = document.getElementsByClassName('edit');\n edititems.forEach(element => {\n element.addEventListener('click', async(e) => {\n showModal(e, element.dataset.id, element.dataset.table);\n });\n });\n\n // Add listener to delete items.\n let deleteitems = document.getElementsByClassName('delete');\n deleteitems.forEach(element => {\n element.addEventListener('click', async(e) => {\n deleteModal(e, element.dataset.id, element.dataset.title, element.dataset.table);\n });\n });\n\n // Add listener to preview items.\n let previewitems = document.getElementsByClassName('preview-button');\n previewitems.forEach(element => {\n element.addEventListener('click', async(e) => {\n previewModal(e);\n });\n });\n\n // Add listener to select compcat to show corresponding items.\n let compcats = document.getElementsByClassName('compcat');\n compcats.forEach(element => {\n element.addEventListener('click', async(e) => {\n showItems(e, element.dataset.compcat);\n });\n });\n\n // Add listener to edit licenses icon.\n let editlicenses = document.getElementsByClassName('editlicenses');\n editlicenses.forEach(element => {\n element.addEventListener('click', async(e) => {\n editlicensesModal(e, element.dataset.id);\n });\n });\n\n // Add listener to manage component flavor relation.\n let buttonicons = document.querySelectorAll('.buttonicons');\n buttonicons.forEach(element => {\n element.addEventListener('click', async(e) => {\n compflavorModal(e);\n });\n });\n\n let displaynamesbutton = document.getElementById('elements_displaynames_button');\n displaynamesbutton.addEventListener('click', async(e) => {\n displaynamesModal(e);\n });\n\n let displaynamesflavorbutton = document.getElementById('elements_displaynames_flavor_button');\n displaynamesflavorbutton.addEventListener('click', async(e) => {\n displaynamesFlavorModal(e);\n });\n\n let displaynamesvariantbutton = document.getElementById('elements_displaynames_variant_button');\n displaynamesvariantbutton.addEventListener('click', async(e) => {\n displaynamesVariantModal(e);\n });\n\n // Add listener to duplicate items.\n let duplicateitems = document.getElementsByClassName('duplicate');\n duplicateitems.forEach(element => {\n element.addEventListener('click', async() => {\n duplicateItem(element.dataset.id, element.dataset.table).always(() => reload());\n });\n });\n\n // Add listener to wipe all items.\n let wipebutton = document.getElementById('elements_wipe');\n if (wipebutton) {\n wipebutton.addEventListener('click', async(e) => {\n wipeModal(e);\n });\n }\n\n // Add image and text to item setting click area.\n let enlargeItems = document.querySelectorAll(\n '.flavor .card-body > .clickingextended, .component .card-body > .clickingextended, .variant .card-body > .clickingextended'\n );\n enlargeItems.forEach(element => {\n element.addEventListener('click', async(e) => {\n let item = e.target.closest('.item');\n item.querySelector('a.edit').click();\n });\n });\n\n // After submitting a new item, reset active compcat.\n if (params.compcatactive) {\n let compcat = document.querySelector('.compcat[data-compcat=\"' + params.compcatactive + '\"]');\n if (compcat) {\n showItems(false, params.compcatactive);\n compcat.classList.add('active');\n }\n }\n};\n\n/**\n * Show dynamic form to add/edit a source.\n * @param {*} event\n * @param {*} id\n * @param {*} table\n */\nconst showModal = async(event, id, table) => {\n event.preventDefault();\n let title;\n if (id == 0) {\n title = getString('additem', 'tiny_elements');\n } else {\n title = getString('edititem', 'tiny_elements');\n }\n\n const modalForm = new ModalForm({\n // Set formclass, depending on component.\n formClass: \"tiny_elements\\\\form\\\\management_\" + table + \"_form\",\n args: {\n id: id,\n compcat: getActiveCompcatId(),\n categoryname: getActiveCompcatName(),\n },\n modalConfig: {title: title},\n returnFocus: event.target,\n });\n // Conditional reload page after submit.\n modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, () => reload());\n\n await modalForm.show();\n};\n\n/**\n * Show modal to preview css version.\n * @param {*} event\n */\nconst previewModal = async(event) => {\n event.preventDefault();\n let preview = event.target.closest(\".preview-button\");\n const modal = await PreviewModal.create({\n templateContext: {\n component: preview.dataset.component,\n flavors: preview.dataset.flavors.trim().split(\" \"),\n config: M.cfg,\n },\n });\n await modal.show();\n};\n\n/**\n * Show dynamic form to import xml backups.\n * @param {*} event\n */\nconst importModal = async(event) => {\n event.preventDefault();\n let title = getString('import', 'tiny_elements');\n\n const modalForm = new ModalForm({\n // Load import form.\n formClass: \"tiny_elements\\\\form\\\\management_import_form\",\n args: {},\n modalConfig: {title: title},\n });\n modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, importModalSubmitted);\n\n await modalForm.show();\n};\n\n/**\n * Process import form submit.\n * @param {*} event\n */\nconst importModalSubmitted = async(event) => {\n // Reload page after submit.\n if (event.detail.update) {\n location.reload();\n } else {\n event.stopPropagation();\n renderTemplate('tiny_elements/management_import_form_result', event.detail).then(async(html) => {\n await Notification.alert(\n getString('import_simulation', 'tiny_elements'),\n html,\n getString('close', 'tiny_elements')\n );\n return true;\n }).catch((error) => {\n displayException(error);\n });\n }\n};\n\n/**\n * Load modal to edit icon urls.\n * @param {*} event\n */\nconst compflavorModal = async(event) => {\n event.preventDefault();\n let title = getString('manage', 'tiny_elements');\n const target = event.target.closest('.buttonicons');\n const component = target.dataset.component ?? '';\n const flavor = target.dataset.flavor ?? '';\n const modalForm = new ModalForm({\n // Load import form.\n formClass: \"tiny_elements\\\\form\\\\management_comp_flavor_form\",\n args: {\n component: component,\n flavor: flavor,\n },\n modalConfig: {title: title},\n });\n\n await modalForm.show();\n};\n\n/**\n * Load modal to edit licenses of icons.\n * @param {*} event\n * @param {*} id\n */\nconst editlicensesModal = async(event, id) => {\n event.preventDefault();\n let title = getString('editlicenses', 'tiny_elements');\n const modalForm = new ModalForm({\n formClass: \"tiny_elements\\\\form\\\\management_editlicense_form\",\n args: {\n id: id,\n },\n modalConfig: {title: title},\n });\n await modalForm.show();\n};\n\n/**\n * Load modal to edit displaynames.\n * @param {*} event\n * @returns {void}\n */\nconst displaynamesModal = async(event) => {\n event.preventDefault();\n let title = getString('manage', 'tiny_elements');\n\n const modalForm = new ModalForm({\n // Load displaynames bulk edit form.\n formClass: \"tiny_elements\\\\form\\\\management_displaynames_form\",\n args: {},\n modalConfig: {title: title},\n });\n\n // Reload page after submit.\n modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, () => location.reload());\n\n await modalForm.show();\n};\n\n/**\n * Load modal to edit displaynames.\n * @param {*} event\n * @returns {void}\n */\nconst displaynamesFlavorModal = async(event) => {\n event.preventDefault();\n let title = getString('manage', 'tiny_elements');\n\n const modalForm = new ModalForm({\n // Load displaynames bulk edit form.\n formClass: \"tiny_elements\\\\form\\\\management_displaynames_flavors_form\",\n args: {},\n modalConfig: {title: title},\n });\n\n // Reload page after submit.\n modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, () => location.reload());\n\n await modalForm.show();\n};\n\n/**\n * Load modal to edit displaynames.\n * @param {*} event\n * @returns {void}\n */\nconst displaynamesVariantModal = async(event) => {\n event.preventDefault();\n let title = getString('manage', 'tiny_elements');\n\n const modalForm = new ModalForm({\n // Load displaynames bulk edit form.\n formClass: \"tiny_elements\\\\form\\\\management_displaynames_variants_form\",\n args: {},\n modalConfig: {title: title},\n });\n\n // Reload page after submit.\n modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, () => location.reload());\n\n await modalForm.show();\n};\n\n/**\n * Show dynamic form to delete a source.\n * @param {*} event\n * @param {*} id\n * @param {*} title\n * @param {*} table\n */\nconst deleteModal = (event, id, title, table) => {\n event.preventDefault();\n\n deleteCancelPromise(\n getString('delete', 'tiny_elements', title),\n getString('deletewarning', 'tiny_elements'),\n ).then(async() => {\n if (id !== 0) {\n try {\n const deleted = await deleteItem(id, table);\n if (deleted) {\n const link = document.querySelector('[data-table=\"' + table + '\"][data-id=\"' + id + '\"]');\n if (link) {\n const card = link.closest(\".item\");\n card.remove();\n }\n }\n } catch (error) {\n displayException(error);\n }\n }\n return;\n }).catch((err) => {\n if (err.message) {\n Log.error(err.message);\n }\n return;\n });\n};\n\n/**\n * Show a modal to confirm wiping all items.\n * @param {*} event\n */\nconst wipeModal = (event) => {\n event.preventDefault();\n\n deleteCancelPromise(\n getString('wipe', 'tiny_elements'),\n getString('wipewarning', 'tiny_elements')\n ).then(async() => {\n try {\n await wipe();\n reload();\n } catch (error) {\n displayException(error);\n }\n }).catch((err) => {\n if (err.message) {\n Log.error(err.message);\n }\n return;\n });\n};\n\n/**\n * Delete elements items.\n * @param {*} id\n * @param {*} table\n * @returns {mixed}\n */\nexport const deleteItem = (\n id,\n table,\n) => fetchMany(\n [{\n methodname: 'tiny_elements_delete_item',\n args: {\n id,\n table,\n }\n }])[0];\n\n/**\n * Wipe all elements items.\n * @returns {mixed}\n */\nexport const wipe = () => fetchMany(\n [{\n methodname: 'tiny_elements_wipe',\n args: {\n \"contextid\": 1,\n }\n }])[0];\n\n/**\n * Show items after clicking a compcat.\n * @param {*} event\n * @param {*} compcat\n */\nconst showItems = (event, compcat) => {\n // But first hide all items.\n let itemsHide = document.querySelectorAll('.flavor, .component, .variant');\n itemsHide.forEach(element => {\n element.classList.add('hidden');\n });\n\n // Show component and variants with compcat name and read the flavors.\n let itemsShow = document.querySelectorAll('[data-categoryname=\"' + compcat + '\"]');\n let usedFlavors = [];\n itemsShow.forEach(element => {\n element.classList.remove('hidden');\n // Get all flavors to show if on compcat element.\n if (typeof element.dataset.flavors !== 'undefined') {\n let flavors = element.dataset.flavors.split(' ');\n for (let value of flavors) {\n if (!usedFlavors.includes(value) && value.length != 0) {\n usedFlavors.push(value);\n }\n }\n }\n });\n\n // Show the flavors.\n let flavorstring = usedFlavors.map(item => `.${item}`).join(', ');\n if (flavorstring.length) {\n let flavorsShow = document.querySelectorAll(flavorstring);\n flavorsShow.forEach(element => {\n element.classList.remove('hidden');\n });\n }\n\n // Show add buttons.\n let addsShow = document.getElementsByClassName('addcontainer');\n addsShow.forEach(element => {\n element.classList.remove('hidden');\n });\n\n // Unmark all and mark clicked compcat.\n if (event) {\n let items = document.getElementsByClassName('compcat');\n items.forEach(element => {\n element.classList.remove('active');\n });\n let item = event.target.closest('.compcat');\n item.classList.add('active');\n }\n\n // Special case, unassigned items, show all items without connection to compcat.\n if (compcat == 'found-items') {\n let found = document.querySelector('.compcat[data-compcat=\"found-items\"]');\n if (found.dataset.loneflavors.length) {\n let flavorsShow = document.querySelectorAll(found.dataset.loneflavors);\n flavorsShow.forEach(element => {\n element.classList.remove('hidden');\n });\n }\n if (found.dataset.lonevariants.length) {\n let variantsShow = document.querySelectorAll(found.dataset.lonevariants);\n variantsShow.forEach(element => {\n element.classList.remove('hidden');\n });\n }\n if (found.dataset.lonecomponents.length) {\n let componentsShow = document.querySelectorAll(found.dataset.lonecomponents);\n componentsShow.forEach(element => {\n element.classList.remove('hidden');\n });\n }\n }\n};\n\n/**\n * Reload page with active compcat.\n */\nconst reload = () => {\n // Reload page with active compcat.\n const currentUrl = new URL(window.location.href);\n currentUrl.searchParams.set('compcat', getActiveCompcatName());\n window.location.href = currentUrl.toString();\n window.location.reload();\n};\n\n/**\n * Get the current active compcat.\n * @returns string Name of active compcat.\n */\nconst getActiveCompcatName = () => {\n const compcat = document.querySelector('.compcat.active');\n if (!compcat) {\n return '';\n }\n return compcat.dataset.compcat ?? '';\n};\n\n/**\n * Get the current active compcat.\n * @returns int Id of active compcat.\n */\nconst getActiveCompcatId = () => {\n const compcat = document.querySelector('.compcat.active');\n if (!compcat) {\n return 0;\n }\n return compcat.dataset.id ?? 0;\n};\n\n/**\n * Duplicate elements items.\n * @param {*} id\n * @param {*} table\n * @returns {mixed}\n */\nexport const duplicateItem = (id, table) => fetchMany(\n [{\n methodname: 'tiny_elements_duplicate_item',\n args: {\n id,\n table,\n }\n }])[0];\n"],"names":["async","document","getElementById","addEventListener","importModal","e","getElementsByClassName","forEach","element","showModal","dataset","id","table","deleteModal","title","previewModal","showItems","compcat","editlicensesModal","querySelectorAll","compflavorModal","displaynamesModal","displaynamesFlavorModal","displaynamesVariantModal","duplicateItem","always","reload","wipebutton","wipeModal","target","closest","querySelector","click","params","compcatactive","classList","add","event","preventDefault","modalForm","ModalForm","formClass","args","getActiveCompcatId","categoryname","getActiveCompcatName","modalConfig","returnFocus","events","FORM_SUBMITTED","show","preview","modal","PreviewModal","create","templateContext","component","flavors","trim","split","config","M","cfg","importModalSubmitted","detail","update","location","stopPropagation","then","Notification","alert","html","catch","error","flavor","deleteItem","link","remove","err","message","wipe","methodname","itemsShow","usedFlavors","value","includes","length","push","flavorstring","map","item","join","found","loneflavors","lonevariants","lonecomponents","currentUrl","URL","window","href","searchParams","set","toString"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"management.min.js","sources":["../src/management.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 * Management functions for tiny_elements admin backend.\n *\n * @module tiny_elements/management\n * @copyright 2024 ISB Bayern\n * @author Tobias Garske\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {PreviewModal} from 'tiny_elements/previewmodal';\nimport ModalForm from 'core_form/modalform';\nimport Notification from 'core/notification';\nimport {get_string as getString} from 'core/str';\nimport {exception as displayException, deleteCancelPromise} from 'core/notification';\nimport {call as fetchMany} from 'core/ajax';\nimport {render as renderTemplate} from 'core/templates';\nimport Log from 'core/log';\n\nexport const init = async(params) => {\n\n // Add listener to import xml files.\n let importxml = document.getElementById('elements_import');\n importxml.addEventListener('click', async(e) => {\n importModal(e);\n });\n\n // Add listener for adding a new item.\n let additem = document.getElementsByClassName('add');\n additem.forEach(element => {\n element.addEventListener('click', async(e) => {\n showModal(e, element.dataset.id, element.dataset.table);\n });\n });\n\n // Add listener to edit items.\n let edititems = document.getElementsByClassName('edit');\n edititems.forEach(element => {\n element.addEventListener('click', async(e) => {\n showModal(e, element.dataset.id, element.dataset.table);\n });\n });\n\n // Add listener to delete items.\n let deleteitems = document.getElementsByClassName('delete');\n deleteitems.forEach(element => {\n element.addEventListener('click', async(e) => {\n deleteModal(e, element.dataset.id, element.dataset.title, element.dataset.table);\n });\n });\n\n // Add listener to preview items.\n let previewitems = document.getElementsByClassName('preview-button');\n previewitems.forEach(element => {\n element.addEventListener('click', async(e) => {\n previewModal(e);\n });\n });\n\n // Add listener to select compcat to show corresponding items.\n let compcats = document.getElementsByClassName('compcat');\n compcats.forEach(element => {\n element.addEventListener('click', async(e) => {\n showItems(e, element.dataset.compcat);\n });\n });\n\n // Add listener to edit licenses icon.\n let editlicenses = document.getElementsByClassName('editlicenses');\n editlicenses.forEach(element => {\n element.addEventListener('click', async(e) => {\n editlicensesModal(e, element.dataset.id);\n });\n });\n\n // Add listener to manage component flavor relation.\n let buttonicons = document.querySelectorAll('.buttonicons');\n buttonicons.forEach(element => {\n element.addEventListener('click', async(e) => {\n compflavorModal(e);\n });\n });\n\n let displaynamesbutton = document.getElementById('elements_displaynames_button');\n displaynamesbutton.addEventListener('click', async(e) => {\n displaynamesModal(e);\n });\n\n let displaynamesflavorbutton = document.getElementById('elements_displaynames_flavor_button');\n displaynamesflavorbutton.addEventListener('click', async(e) => {\n displaynamesFlavorModal(e);\n });\n\n let displaynamesvariantbutton = document.getElementById('elements_displaynames_variant_button');\n displaynamesvariantbutton.addEventListener('click', async(e) => {\n displaynamesVariantModal(e);\n });\n\n // Add listener to duplicate items.\n let duplicateitems = document.getElementsByClassName('duplicate');\n duplicateitems.forEach(element => {\n element.addEventListener('click', async() => {\n duplicateItem(element.dataset.id, element.dataset.table).always(() => reload());\n });\n });\n\n // Add listener to wipe all items.\n let wipebutton = document.getElementById('elements_wipe');\n if (wipebutton) {\n wipebutton.addEventListener('click', async(e) => {\n wipeModal(e);\n });\n }\n\n // Add image and text to item setting click area.\n let enlargeItems = document.querySelectorAll(\n '.flavor .card-body > .clickingextended, .component .card-body > .clickingextended, .variant .card-body > .clickingextended'\n );\n enlargeItems.forEach(element => {\n element.addEventListener('click', async(e) => {\n let item = e.target.closest('.item');\n item.querySelector('a.edit').click();\n });\n });\n\n // After submitting a new item, reset active compcat.\n if (params.compcatactive) {\n let compcat = document.querySelector('.compcat[data-compcat=\"' + params.compcatactive + '\"]');\n if (compcat) {\n showItems(false, params.compcatactive);\n compcat.classList.add('active');\n }\n }\n};\n\n/**\n * Show dynamic form to add/edit a source.\n * @param {*} event\n * @param {*} id\n * @param {*} table\n */\nconst showModal = async(event, id, table) => {\n event.preventDefault();\n let title;\n if (id == 0) {\n title = getString('additem', 'tiny_elements');\n } else {\n title = getString('edititem', 'tiny_elements');\n }\n\n const modalForm = new ModalForm({\n // Set formclass, depending on component.\n formClass: \"tiny_elements\\\\form\\\\management_\" + table + \"_form\",\n args: {\n id: id,\n compcat: getActiveCompcatId(),\n categoryname: getActiveCompcatName(),\n },\n modalConfig: {title: title},\n returnFocus: event.target,\n });\n // Conditional reload page after submit.\n modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, () => reload());\n\n await modalForm.show();\n};\n\n/**\n * Show modal to preview css version.\n * @param {*} event\n */\nconst previewModal = async(event) => {\n event.preventDefault();\n let preview = event.target.closest(\".preview-button\");\n const modal = await PreviewModal.create({\n templateContext: {\n component: preview.dataset.component,\n flavors: preview.dataset.flavors.trim().split(\" \"),\n config: M.cfg,\n },\n });\n await modal.show();\n};\n\n/**\n * Show dynamic form to import xml backups.\n * @param {*} event\n */\nconst importModal = async(event) => {\n event.preventDefault();\n let title = getString('import', 'tiny_elements');\n\n const modalForm = new ModalForm({\n // Load import form.\n formClass: \"tiny_elements\\\\form\\\\management_import_form\",\n args: {},\n modalConfig: {title: title},\n });\n modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, importModalSubmitted);\n\n await modalForm.show();\n};\n\n/**\n * Process import form submit.\n * @param {*} event\n */\nconst importModalSubmitted = async(event) => {\n // Reload page after submit.\n if (event.detail.update) {\n location.reload();\n } else {\n event.stopPropagation();\n renderTemplate('tiny_elements/management_import_form_result', event.detail).then(async(html) => {\n await Notification.alert(\n getString('import_simulation', 'tiny_elements'),\n html,\n getString('close', 'tiny_elements')\n );\n return true;\n }).catch((error) => {\n displayException(error);\n });\n }\n};\n\n/**\n * Load modal to edit icon urls.\n * @param {*} event\n */\nconst compflavorModal = async(event) => {\n event.preventDefault();\n let title = getString('manage', 'tiny_elements');\n const target = event.target.closest('.buttonicons');\n const component = target.dataset.component ?? '';\n const flavor = target.dataset.flavor ?? '';\n const modalForm = new ModalForm({\n // Load import form.\n formClass: \"tiny_elements\\\\form\\\\management_comp_flavor_form\",\n args: {\n component: component,\n flavor: flavor,\n },\n modalConfig: {title: title},\n });\n\n await modalForm.show();\n};\n\n/**\n * Load modal to edit licenses of icons.\n * @param {*} event\n * @param {*} id\n */\nconst editlicensesModal = async(event, id) => {\n event.preventDefault();\n let title = getString('editlicenses', 'tiny_elements');\n const modalForm = new ModalForm({\n formClass: \"tiny_elements\\\\form\\\\management_editlicense_form\",\n args: {\n id: id,\n },\n modalConfig: {title: title},\n });\n await modalForm.show();\n};\n\n/**\n * Load modal to edit displaynames.\n * @param {*} event\n * @returns {void}\n */\nconst displaynamesModal = async(event) => {\n event.preventDefault();\n let title = getString('manage', 'tiny_elements');\n\n const modalForm = new ModalForm({\n // Load displaynames bulk edit form.\n formClass: \"tiny_elements\\\\form\\\\management_displaynames_form\",\n args: {},\n modalConfig: {title: title},\n });\n\n // Reload page after submit.\n modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, () => location.reload());\n\n await modalForm.show();\n};\n\n/**\n * Load modal to edit displaynames.\n * @param {*} event\n * @returns {void}\n */\nconst displaynamesFlavorModal = async(event) => {\n event.preventDefault();\n let title = getString('manage', 'tiny_elements');\n\n const modalForm = new ModalForm({\n // Load displaynames bulk edit form.\n formClass: \"tiny_elements\\\\form\\\\management_displaynames_flavors_form\",\n args: {},\n modalConfig: {title: title},\n });\n\n // Reload page after submit.\n modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, () => location.reload());\n\n await modalForm.show();\n};\n\n/**\n * Load modal to edit displaynames.\n * @param {*} event\n * @returns {void}\n */\nconst displaynamesVariantModal = async(event) => {\n event.preventDefault();\n let title = getString('manage', 'tiny_elements');\n\n const modalForm = new ModalForm({\n // Load displaynames bulk edit form.\n formClass: \"tiny_elements\\\\form\\\\management_displaynames_variants_form\",\n args: {},\n modalConfig: {title: title},\n });\n\n // Reload page after submit.\n modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, () => location.reload());\n\n await modalForm.show();\n};\n\n/**\n * Show dynamic form to delete a source.\n * @param {*} event\n * @param {*} id\n * @param {*} title\n * @param {*} table\n */\nconst deleteModal = (event, id, title, table) => {\n event.preventDefault();\n\n deleteCancelPromise(\n getString('delete', 'tiny_elements', title),\n getString('deletewarning', 'tiny_elements'),\n ).then(async() => {\n if (id !== 0) {\n try {\n const deleted = await deleteItem(id, table);\n if (deleted) {\n const link = document.querySelector('[data-table=\"' + table + '\"][data-id=\"' + id + '\"]');\n if (link) {\n const card = link.closest(\".item\");\n card.remove();\n }\n }\n } catch (error) {\n displayException(error);\n }\n }\n return;\n }).catch((err) => {\n if (err.message) {\n Log.error(err.message);\n }\n return;\n });\n};\n\n/**\n * Show a modal to confirm wiping all items.\n * @param {*} event\n */\nconst wipeModal = (event) => {\n event.preventDefault();\n\n deleteCancelPromise(\n getString('wipe', 'tiny_elements'),\n getString('wipewarning', 'tiny_elements')\n ).then(async() => {\n try {\n await wipe();\n reload();\n return;\n } catch (error) {\n displayException(error);\n return;\n }\n }).catch((err) => {\n if (err.message) {\n Log.error(err.message);\n }\n return;\n });\n};\n\n/**\n * Delete elements items.\n * @param {*} id\n * @param {*} table\n * @returns {mixed}\n */\nexport const deleteItem = (\n id,\n table,\n) => fetchMany(\n [{\n methodname: 'tiny_elements_delete_item',\n args: {\n id,\n table,\n }\n }])[0];\n\n/**\n * Wipe all elements items.\n * @returns {mixed}\n */\nexport const wipe = () => fetchMany(\n [{\n methodname: 'tiny_elements_wipe',\n args: {\n \"contextid\": 1,\n }\n }])[0];\n\n/**\n * Show items after clicking a compcat.\n * @param {*} event\n * @param {*} compcat\n */\nconst showItems = (event, compcat) => {\n // But first hide all items.\n let itemsHide = document.querySelectorAll('.flavor, .component, .variant');\n itemsHide.forEach(element => {\n element.classList.add('hidden');\n });\n\n // Show component and variants with compcat name and read the flavors.\n let itemsShow = document.querySelectorAll('[data-categoryname=\"' + compcat + '\"]');\n let usedFlavors = [];\n itemsShow.forEach(element => {\n element.classList.remove('hidden');\n // Get all flavors to show if on compcat element.\n if (typeof element.dataset.flavors !== 'undefined') {\n let flavors = element.dataset.flavors.split(' ');\n for (let value of flavors) {\n if (!usedFlavors.includes(value) && value.length != 0) {\n usedFlavors.push(value);\n }\n }\n }\n });\n\n // Show the flavors.\n let flavorstring = usedFlavors.map(item => `.${item}`).join(', ');\n if (flavorstring.length) {\n let flavorsShow = document.querySelectorAll(flavorstring);\n flavorsShow.forEach(element => {\n element.classList.remove('hidden');\n });\n }\n\n // Show add buttons.\n let addsShow = document.getElementsByClassName('addcontainer');\n addsShow.forEach(element => {\n element.classList.remove('hidden');\n });\n\n // Unmark all and mark clicked compcat.\n if (event) {\n let items = document.getElementsByClassName('compcat');\n items.forEach(element => {\n element.classList.remove('active');\n });\n let item = event.target.closest('.compcat');\n item.classList.add('active');\n }\n\n // Special case, unassigned items, show all items without connection to compcat.\n if (compcat == 'found-items') {\n let found = document.querySelector('.compcat[data-compcat=\"found-items\"]');\n if (found.dataset.loneflavors.length) {\n let flavorsShow = document.querySelectorAll(found.dataset.loneflavors);\n flavorsShow.forEach(element => {\n element.classList.remove('hidden');\n });\n }\n if (found.dataset.lonevariants.length) {\n let variantsShow = document.querySelectorAll(found.dataset.lonevariants);\n variantsShow.forEach(element => {\n element.classList.remove('hidden');\n });\n }\n if (found.dataset.lonecomponents.length) {\n let componentsShow = document.querySelectorAll(found.dataset.lonecomponents);\n componentsShow.forEach(element => {\n element.classList.remove('hidden');\n });\n }\n }\n};\n\n/**\n * Reload page with active compcat.\n */\nconst reload = () => {\n // Reload page with active compcat.\n const currentUrl = new URL(window.location.href);\n currentUrl.searchParams.set('compcat', getActiveCompcatName());\n window.location.href = currentUrl.toString();\n window.location.reload();\n};\n\n/**\n * Get the current active compcat.\n * @returns string Name of active compcat.\n */\nconst getActiveCompcatName = () => {\n const compcat = document.querySelector('.compcat.active');\n if (!compcat) {\n return '';\n }\n return compcat.dataset.compcat ?? '';\n};\n\n/**\n * Get the current active compcat.\n * @returns int Id of active compcat.\n */\nconst getActiveCompcatId = () => {\n const compcat = document.querySelector('.compcat.active');\n if (!compcat) {\n return 0;\n }\n return compcat.dataset.id ?? 0;\n};\n\n/**\n * Duplicate elements items.\n * @param {*} id\n * @param {*} table\n * @returns {mixed}\n */\nexport const duplicateItem = (id, table) => fetchMany(\n [{\n methodname: 'tiny_elements_duplicate_item',\n args: {\n id,\n table,\n }\n }])[0];\n"],"names":["async","document","getElementById","addEventListener","importModal","e","getElementsByClassName","forEach","element","showModal","dataset","id","table","deleteModal","title","previewModal","showItems","compcat","editlicensesModal","querySelectorAll","compflavorModal","displaynamesModal","displaynamesFlavorModal","displaynamesVariantModal","duplicateItem","always","reload","wipebutton","wipeModal","target","closest","querySelector","click","params","compcatactive","classList","add","event","preventDefault","modalForm","ModalForm","formClass","args","getActiveCompcatId","categoryname","getActiveCompcatName","modalConfig","returnFocus","events","FORM_SUBMITTED","show","preview","modal","PreviewModal","create","templateContext","component","flavors","trim","split","config","M","cfg","importModalSubmitted","detail","update","location","stopPropagation","then","Notification","alert","html","catch","error","flavor","deleteItem","link","remove","err","message","wipe","methodname","itemsShow","usedFlavors","value","includes","length","push","flavorstring","map","item","join","found","loneflavors","lonevariants","lonecomponents","currentUrl","URL","window","href","searchParams","set","toString"],"mappings":"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"} \ No newline at end of file diff --git a/amd/build/previewall.min.js b/amd/build/previewall.min.js new file mode 100644 index 0000000..3df11bd --- /dev/null +++ b/amd/build/previewall.min.js @@ -0,0 +1,3 @@ +define("tiny_elements/previewall",["exports","core/toast","core/str"],(function(_exports,_toast,_str){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0;_exports.init=async()=>{document.getElementById("elements_to_clipboard").addEventListener("click",(()=>{const allelements=document.getElementById("elements_output");navigator.clipboard.writeText(allelements.value).then((()=>{(0,_toast.add)((0,_str.get_string)("copysuccess","tiny_elements"),{type:"info"})})).catch((()=>{(0,_toast.add)((0,_str.get_string)("copyfail","tiny_elements"),{type:"warning"})}))}))}})); + +//# sourceMappingURL=previewall.min.js.map \ No newline at end of file diff --git a/amd/build/previewall.min.js.map b/amd/build/previewall.min.js.map new file mode 100644 index 0000000..db22623 --- /dev/null +++ b/amd/build/previewall.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"previewall.min.js","sources":["../src/previewall.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 * Elements preview all.\n *\n * @module tiny_elements/previewall\n * @copyright 2025 Tobias Garske\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {add as addToast} from 'core/toast';\nimport {get_string as getString} from \"core/str\";\n\nexport const init = async() => {\n // Add listener to copy all elements as string.\n document.getElementById(\"elements_to_clipboard\").addEventListener(\"click\", () => {\n const allelements = document.getElementById(\"elements_output\");\n navigator.clipboard.writeText(allelements.value)\n .then(() => {\n addToast(getString('copysuccess', 'tiny_elements'), {\n type: 'info',\n });\n return;\n })\n .catch(() => {\n addToast(getString('copyfail', 'tiny_elements'), {\n type: 'warning',\n });\n return;\n });\n });\n};\n"],"names":["async","document","getElementById","addEventListener","allelements","navigator","clipboard","writeText","value","then","type","catch"],"mappings":"iMA0BoBA,UAEhBC,SAASC,eAAe,yBAAyBC,iBAAiB,SAAS,WACjEC,YAAcH,SAASC,eAAe,mBAC5CG,UAAUC,UAAUC,UAAUH,YAAYI,OACzCC,MAAK,qBACO,mBAAU,cAAe,iBAAkB,CAChDC,KAAM,YAIbC,OAAM,qBACM,mBAAU,WAAY,iBAAkB,CAC7CD,KAAM"} \ No newline at end of file diff --git a/amd/src/management.js b/amd/src/management.js index 6ed63d0..a5ce911 100644 --- a/amd/src/management.js +++ b/amd/src/management.js @@ -396,8 +396,10 @@ const wipeModal = (event) => { try { await wipe(); reload(); + return; } catch (error) { displayException(error); + return; } }).catch((err) => { if (err.message) { diff --git a/amd/src/previewall.js b/amd/src/previewall.js new file mode 100644 index 0000000..dedc851 --- /dev/null +++ b/amd/src/previewall.js @@ -0,0 +1,45 @@ +// 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 . + +/** + * Elements preview all. + * + * @module tiny_elements/previewall + * @copyright 2025 Tobias Garske + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +import {add as addToast} from 'core/toast'; +import {get_string as getString} from "core/str"; + +export const init = async() => { + // Add listener to copy all elements as string. + document.getElementById("elements_to_clipboard").addEventListener("click", () => { + const allelements = document.getElementById("elements_output"); + navigator.clipboard.writeText(allelements.value) + .then(() => { + addToast(getString('copysuccess', 'tiny_elements'), { + type: 'info', + }); + return; + }) + .catch(() => { + addToast(getString('copyfail', 'tiny_elements'), { + type: 'warning', + }); + return; + }); + }); +}; diff --git a/classes/exporter.php b/classes/exporter.php index f5bd451..481ce8d 100644 --- a/classes/exporter.php +++ b/classes/exporter.php @@ -212,7 +212,7 @@ public function export_flavors_and_variants( $params ); $this->write_elements($xmlwriter, constants::TABLES['compflavor'], $compflavors); - $flavornames = array_unique(array_column($compflavors, 'flavor')); + $flavornames = array_unique(array_column($compflavors, 'flavorname')); $sql = ' = name'; if (!empty($categoryname)) { diff --git a/classes/external/wipe.php b/classes/external/wipe.php index 12fc7cc..18c6b87 100644 --- a/classes/external/wipe.php +++ b/classes/external/wipe.php @@ -45,6 +45,7 @@ public static function execute_parameters(): external_function_parameters { /** * Implementation of web service tiny_elements_wipe + * @param int $contextid * @return array */ public static function execute(int $contextid): array { diff --git a/classes/form/management_editlicense_form.php b/classes/form/management_editlicense_form.php index bf20eb9..0f74793 100644 --- a/classes/form/management_editlicense_form.php +++ b/classes/form/management_editlicense_form.php @@ -108,6 +108,7 @@ public function definition(): void { $mform->removeElement('adddummy'); $mform->setAttributes(['data-formtype' => 'tiny_elements_editlicense']); + $mform->disable_form_change_checker(); } /** diff --git a/lang/de/tiny_elements.php b/lang/de/tiny_elements.php index 32f5f42..cf779a1 100644 --- a/lang/de/tiny_elements.php +++ b/lang/de/tiny_elements.php @@ -47,7 +47,10 @@ $string['componentname_help'] = 'Name der Komponente zur internen Verwendung (auch als Klassenname in CSS)'; $string['components'] = 'Komponenten'; $string['content'] = 'Inhalt'; +$string['copyasstring'] = 'Alle Elemente als String in den Zwischenspeicher laden'; +$string['copyfail'] = 'Fehler beim Kopieren aufgetreten'; $string['copyof'] = 'Kopie von {$a}'; +$string['copysuccess'] = 'Elemente in den Zwischenspeicher kopiert'; $string['css'] = 'CSS'; $string['delete'] = 'Element "{$a}" löschen'; $string['deletewarning'] = 'Sind Sie sicher, dass Sie dieses Element löschen möchten?'; @@ -94,6 +97,8 @@ $string['js'] = 'JS'; $string['linktomanagerdesc'] = 'Gehen Sie zu Verwaltung, um Änderungen vorzunehmen.'; $string['linktomanagername'] = 'Link zur Verwaltung'; +$string['linktopreviewall'] = 'Link zur Vorschau'; +$string['linktopreviewall_desc'] = 'Gehen Sie zu Vorschau, um alle Elements anzusehen und als String zu exportieren.'; $string['manage'] = 'Verwalten'; $string['management'] = 'Verwaltung'; $string['menuitem_elements'] = 'Kurselemente'; diff --git a/lang/en/tiny_elements.php b/lang/en/tiny_elements.php index 17790ea..3744797 100644 --- a/lang/en/tiny_elements.php +++ b/lang/en/tiny_elements.php @@ -45,7 +45,10 @@ $string['componentname_help'] = 'Name of the component use for internal use (also as a class name in CSS)'; $string['components'] = 'Components'; $string['content'] = 'Content'; +$string['copyasstring'] = 'Save all elements to clipboard'; +$string['copyfail'] = 'Error copying elements'; $string['copyof'] = 'Copy of {$a}'; +$string['copysuccess'] = 'Elements copied to clipboard'; $string['css'] = 'CSS'; $string['delete'] = 'Delete item "{$a}"'; $string['deletewarning'] = 'Are you sure you want to delete this item.'; @@ -91,6 +94,9 @@ $string['js'] = 'JS'; $string['linktomanagerdesc'] = 'Go to management page to edit categories, components, flavors and variants.'; $string['linktomanagername'] = 'Link to management'; +$string['linktopreviewall'] = 'Link to preview'; +$string['linktopreviewall_desc'] = 'Go to preview to watch all elements and export as string.'; + $string['manage'] = 'Manage'; $string['management'] = 'Management'; $string['menuitem_elements'] = 'Course elements'; diff --git a/preview.php b/preview.php index 30edf63..2218b5e 100644 --- a/preview.php +++ b/preview.php @@ -53,10 +53,6 @@ $componentdata->code = tiny_elements\local\utils::replace_pluginfile_urls($componentdata->code, true); -if (empty($flavordata)) { - echo str_replace('{{FLAVOR}}', '', $componentdata->code); -} else { - echo str_replace('{{FLAVOR}}', $flavordata->name, $componentdata->code); -} +echo $componentdata->code; echo $OUTPUT->footer(); diff --git a/previewall.php b/previewall.php new file mode 100644 index 0000000..f59d376 --- /dev/null +++ b/previewall.php @@ -0,0 +1,96 @@ +. + +/** + * Creates a preview for all elements components in all flavors and variants. + * + * @package tiny_elements + * @copyright 2024 Tobias Garske, ISB Bayern + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +require('../../../../../config.php'); + +require_login(); + +$url = new moodle_url('/lib/editor/tiny/plugins/elements/previewall.php', []); +$PAGE->set_url($url); +$PAGE->set_context(context_system::instance()); +$PAGE->set_heading($SITE->fullname); + +echo $OUTPUT->header(); + +// Iterate over every category. +$categorydata = $DB->get_records('tiny_elements_compcat'); +$outputbuffer = ''; +foreach ($categorydata as $category) { + $outputbuffer .= '

' . $category->name . '

'; + $category = $category->name; + $componentdata = $DB->get_records('tiny_elements_component', ['categoryname' => $category]); + // Iterate over every component. + foreach ($componentdata as $component) { + $outputbuffer .= '

' . $component->name . '

'; + // Select corresponding flavors and variants. + $sql = "SELECT * FROM {tiny_elements_flavor} fla + JOIN {tiny_elements_comp_flavor} comfla ON comfla.flavorname = fla.name + WHERE fla.categoryname = :categoryname AND comfla.componentname = :componentname"; + $allflavors = $DB->get_records_sql($sql, ['categoryname' => $component->categoryname, 'componentname' => $component->name]); + $sql = "SELECT * FROM {tiny_elements_variant} var + JOIN {tiny_elements_comp_variant} covar ON var.name = covar.variant + WHERE covar.componentname = :componentname"; + $allvariants = $DB->get_records_sql($sql, ['componentname' => $component->name]); + // Add default "variant". + array_unshift($allvariants, (object) ['name' => '']); + foreach ($allflavors as $flavordata) { + foreach ($allvariants as $variantdata) { + $tmpcomponent = clone $component; + $variant = ''; + if (strlen($variantdata->name) > 0) { + $variant = 'elements-' . $variantdata->name . '-variant'; + } + $varianthtml = ''; + // Build elements by replacing placeholders. + $tmpcomponent->code = str_replace('{{CATEGORY}}', 'elements-' . $category, $tmpcomponent->code); + $tmpcomponent->code = str_replace('{{COMPONENT}}', 'elements-' . $tmpcomponent->name, $tmpcomponent->code); + $tmpcomponent->code = str_replace( + '{{FLAVOR}}', + 'elements-' . $flavordata->name . '-flavor', + $tmpcomponent->code + ); + $tmpcomponent->code = str_replace('{{VARIANTS}}', $variant, $tmpcomponent->code); + $tmpcomponent->code = str_replace('{{VARIANTSHTML}}', $varianthtml, $tmpcomponent->code); + $tmpcomponent->code = str_replace( + '{{PLACEHOLDER}}', + $flavordata->name . ' ' . $variantdata->name, + $tmpcomponent->code + ); + // Output element. + $tmpcomponent->code = tiny_elements\local\utils::replace_pluginfile_urls($tmpcomponent->code, true); + $outputbuffer .= $tmpcomponent->code; + } + } + } +} + +// Create button to copy elements to clipboard. +echo ""; +echo ""; +$PAGE->requires->js_call_amd('tiny_elements/previewall', 'init'); + +echo $outputbuffer; + +echo $OUTPUT->footer(); diff --git a/settings.php b/settings.php index 5f0fdd0..f018aae 100644 --- a/settings.php +++ b/settings.php @@ -51,4 +51,15 @@ (new moodle_url('/lib/editor/tiny/plugins/elements/management.php'))->out() ) )); + + // Add text with link to previewpage as setting. + $settings->add(new admin_setting_description( + 'tiny_elements/previewall', + get_string('linktopreviewall', 'tiny_elements'), + get_string( + 'linktopreviewall_desc', + 'tiny_elements', + (new moodle_url('/lib/editor/tiny/plugins/elements/previewall.php'))->out() + ) + )); } diff --git a/templates/management.mustache b/templates/management.mustache index 15e61de..65ae139 100644 --- a/templates/management.mustache +++ b/templates/management.mustache @@ -76,7 +76,7 @@

{{#str}} compcat, tiny_elements {{/str}}

{{#compcats}} -
@@ -154,11 +154,11 @@
-
+
- +

{{#str}} components, tiny_elements {{/str}}

@@ -207,7 +207,7 @@
-
+
@@ -215,7 +215,7 @@

{{#str}} variants, tiny_elements {{/str}}

{{#variant}} -
@@ -246,9 +246,8 @@
-
+
-
diff --git a/templates/management_preview.mustache b/templates/management_preview.mustache index d8a05c2..bc4c36a 100644 --- a/templates/management_preview.mustache +++ b/templates/management_preview.mustache @@ -38,4 +38,4 @@ {{/flavors}} {{/body}} -{{/ core/modal }} \ No newline at end of file +{{/ core/modal }}