/* 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();