class PhysicalPositionMenu { // 1) Server-side: provide the option groups getAllMenuData() { return { positionGroups: [ { group: 'Positional', options: [ { value: 'upstream', label: '⬅ Upstream' }, { value: 'atEquipment', label: '⚙️ At Equipment' }, { value: 'downstream', label: '➡ Downstream' } ] } ] }; } // 2) HTML template (pure markup) getHtmlTemplate() { return `

Physical Position vs parent


`; } // 3) HTML injector getHtmlInjectionCode(nodeName) { const tpl = this.getHtmlTemplate() .replace(/`/g,'\\`').replace(/\$/g,'\\$'); return ` // PhysicalPosition HTML injection for ${nodeName} window.EVOLV.nodes.${nodeName}.positionMenu.injectHtml = function() { const ph = document.getElementById('position-fields-placeholder'); if (ph && !ph.hasChildNodes()) { ph.innerHTML = \`${tpl}\`; } }; `; } // 4) Data-loader injector getDataInjectionCode(nodeName) { return ` // PhysicalPosition data loader for ${nodeName} window.EVOLV.nodes.${nodeName}.positionMenu.loadData = function(node) { const data = window.EVOLV.nodes.${nodeName}.menuData.position; const sel = document.getElementById('node-input-positionVsParent'); if (!sel) return; sel.innerHTML = ''; (data.positionGroups||[]).forEach(grp => { const optg = document.createElement('optgroup'); optg.label = grp.group; grp.options.forEach(o=>{ const opt = document.createElement('option'); opt.value = o.value; opt.textContent = o.label; optg.appendChild(opt); }); sel.appendChild(optg); }); // default to “atEquipment” if not set sel.value = node.positionVsParent || 'atEquipment'; }; `; } // 5) (no special events needed, but stub for symmetry) getEventInjectionCode(nodeName) { return ` // PhysicalPosition events for ${nodeName} window.EVOLV.nodes.${nodeName}.positionMenu.wireEvents = function(node) { // no dynamic behavior }; `; } // 6) Save-logic injector getSaveInjectionCode(nodeName) { return ` // PhysicalPosition Save injection for ${nodeName} window.EVOLV.nodes.${nodeName}.positionMenu.saveEditor = function(node) { const sel = document.getElementById('node-input-positionVsParent'); node.positionVsParent = sel? sel.value : 'atEquipment'; return true; }; `; } // 7) Compose everything into one client bundle getClientInitCode(nodeName) { const htmlCode = this.getHtmlInjectionCode(nodeName); const dataCode = this.getDataInjectionCode(nodeName); const eventCode = this.getEventInjectionCode(nodeName); const saveCode = this.getSaveInjectionCode(nodeName); return ` // --- PhysicalPositionMenu for ${nodeName} --- window.EVOLV.nodes.${nodeName}.positionMenu = window.EVOLV.nodes.${nodeName}.positionMenu || {}; ${htmlCode} ${dataCode} ${eventCode} ${saveCode} // hook into oneditprepare window.EVOLV.nodes.${nodeName}.positionMenu.initEditor = function(node) { this.injectHtml(); this.loadData(node); this.wireEvents(node); }; `; } } module.exports = PhysicalPositionMenu;