131 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			131 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /* eslint-env browser */
 | |
| /* eslint-disable no-alert, no-console */
 | |
| 
 | |
| /**
 | |
|  * @file simplemobnav.js (previously simplemobnavnew.js)
 | |
|  * @description Modern, class-based implementation for a simple mobile navigation component.
 | |
|  * @version 2.1
 | |
|  * @author support@ndda.fr
 | |
|  */
 | |
| 
 | |
| // Establish the global namespace
 | |
| window.apx = window.apx || {};
 | |
| 
 | |
| /**
 | |
|  * @class SimpleMobNav
 | |
|  * Manages a mobile navigation menu, dynamically rendering links based on user profiles.
 | |
|  */
 | |
| class SimpleMobNav {
 | |
|     constructor() {
 | |
|         if (typeof apx.main === 'undefined') {
 | |
|             throw new Error("SimpleMobNav requires a global 'apx.main' (ApxManager) instance.");
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     loadwco(id, ctx) {
 | |
|         console.log(`[simplemobnav] loadwco triggered for id: ${id} with context:`, ctx);
 | |
|         const componentRoot = document.getElementById(id);
 | |
|         if (!componentRoot) {
 | |
|             console.error(`SimpleMobNav: Element with id "${id}" not found.`);
 | |
|             return;
 | |
|         }
 | |
| 
 | |
|         const tpldataname = `${apx.main.data.pagename}_${id}_simplemobnav`;
 | |
|         if (!this._validateTplData(tpldataname)) return;
 | |
| 
 | |
|         const tplData = apx.main.data.tpldata[tpldataname];
 | |
|         let currentLink = ctx.link;
 | |
| 
 | |
|         if (componentRoot.innerHTML.trim() === "") {
 | |
|             currentLink = this._getInitialLink(tplData);
 | |
|             tplData.contentscreen = currentLink;
 | |
|             componentRoot.innerHTML = Mustache.render(apx.main.data.tpl.simplemobnavmain, tplData);
 | |
|         } else {
 | |
|             componentRoot.querySelectorAll('[wco-name]').forEach(el => {
 | |
|                 el.setAttribute('wco-link', currentLink);
 | |
|             });
 | |
|         }
 | |
| 
 | |
|         this._renderNavLinks(id, currentLink, tplData);
 | |
|         
 | |
|         const loadingIndicator = document.getElementById("loading");
 | |
|         if (loadingIndicator) {
 | |
|             loadingIndicator.classList.add("hidden");
 | |
|         }
 | |
|         console.log(`SimpleMobNav: Screen "${currentLink}" loaded.`);
 | |
|     }
 | |
| 
 | |
|     action(id, link, action, wconame) {
 | |
|         if (action === "navigation") {
 | |
|             document.getElementById(id)?.setAttribute("wco-link", link);
 | |
|             return;
 | |
|         }
 | |
| 
 | |
|         const wco = window.apx[wconame];
 | |
|         if (!wco) {
 | |
|             console.warn(`Action target WCO "${wconame}" does not exist.`);
 | |
|             return;
 | |
|         }
 | |
|         if (typeof wco[action] !== 'function') {
 | |
|             console.warn(`Action "${action}" does not exist on WCO "${wconame}".`);
 | |
|             return;
 | |
|         }
 | |
|         wco[action]();
 | |
|     }
 | |
| 
 | |
|     reload() {
 | |
|         location.reload();
 | |
|     }
 | |
| 
 | |
|     _renderNavLinks(id, currentLink, tplData) {
 | |
|         const componentRoot = document.getElementById(id);
 | |
|         const navlinkContainer = componentRoot?.querySelector('.navlink');
 | |
|         if (!navlinkContainer) return;
 | |
| 
 | |
|         const currentScreenConfig = tplData.links.find(m => m.link === currentLink);
 | |
|         if (!currentScreenConfig) return;
 | |
| 
 | |
|         const visibleLinks = tplData.links
 | |
|             .filter(m => 
 | |
|                 currentScreenConfig.next.includes(m.link) &&
 | |
|                 m.allowedprofil.some(p => apx.main.data.headers.xprofils.includes(p))
 | |
|             )
 | |
|             .map(m => ({
 | |
|                 ...m,
 | |
|                 classnavbutton: m.classnavbutton || tplData.classnavbutton,
 | |
|                 classnavlist: m.classnavlist || tplData.classnavlist,
 | |
|             }));
 | |
|         
 | |
|         const navTemplate = apx.main.data.tpl[`simplemobnav${tplData.navtpl}`];
 | |
|         navlinkContainer.innerHTML = Mustache.render(navTemplate, { id, links: visibleLinks });
 | |
|     }
 | |
| 
 | |
|     _getInitialLink(tplData) {
 | |
|         for (const menu of tplData.profilmenu) {
 | |
|             if (apx.main.data.headers.xprofils.includes(menu.mainprofil)) {
 | |
|                 return menu.link;
 | |
|             }
 | |
|         }
 | |
|         return null;
 | |
|     }
 | |
| 
 | |
|     _validateTplData(tpldataname) {
 | |
|         const tplData = apx.main.data.tpldata[tpldataname];
 | |
|         if (!tplData) {
 | |
|             console.error(`Template data "${tpldataname}" not found in apx.main.data.tpldata.`);
 | |
|             return false;
 | |
|         }
 | |
| 
 | |
|         const mandatoryProps = ["contentwconame", "contentid", "profilmenu", "links"];
 | |
|         const missingProps = mandatoryProps.filter(p => !tplData[p]);
 | |
| 
 | |
|         if (missingProps.length > 0) {
 | |
|             console.error(`Missing properties in ${tpldataname}: ${missingProps.join(', ')}`);
 | |
|             return false;
 | |
|         }
 | |
|         return true;
 | |
|     }
 | |
| }
 | |
| 
 | |
| // Attach an instance to the global namespace
 | |
| apx.simplemobnav = new SimpleMobNav(); |