// Global ATON import { Controller } from "@hotwired/stimulus"; import AppState from "../state.js"; import { traverseOntology } from "../ontology.js"; const html = String.raw; const domParser = new DOMParser; // TODO: hard-coded, but follows a convention... const ontologyJsonPath = location.pathname + 'ontology.json'; export default class extends Controller { static targets = ['trigger', 'layers', 'ontology']; connect() { console.log('#menu controller connected'); } /** * Open settings panel */ async toggleMenu() { ATON.UI.setSidePanelRight(); ATON.UI.showSidePanel({header: 'Menu'}); this.#buildMenuPanel(ATON.UI.elSidePanel); this.#buildLayersMenu(AppState.treeNodes, this.layersTarget); this.#buildOntologyMenu(await traverseOntology(ontologyJsonPath), this.ontologyTarget); } /** * @param {Event} event */ toggleNode(event) { /** * The node's id * @type {string} */ const id = event?.params.node; const status = event?.target?.checked; const node = AppState.normalizedNodes.find(n => n.id === id); /** * @type {HTMLElement|null} */ const eye = event.target.parentElement.querySelector('i'); if (eye) { eye.classList.toggle('bi-eye'); eye.classList.toggle('bi-eye-slash'); } if (node.children.length > 0) { this.#toggleGroup(node, status); this.#syncGroupCheckboxes(node, status, this.layersTarget); } else { ATON.getSceneNode(id).toggle(status); node.active = status; } } /** * Recursively toggle children in a nodes group * @param {Object} groupNode * @param {Boolean} status */ #toggleGroup(groupNode, status) { for (const child of groupNode.children) { if (child.model) { ATON.getSceneNode(child.id).toggle(status); child.active = status; } if (child.children.length > 0) { this.#toggleGroup(child, status); } } } #syncGroupCheckboxes(groupNode, status, container) { for (const child of groupNode.children) { const checkbox = container.querySelector( `[data-menu-node-param="${child.id}"]` ); if (checkbox) checkbox.checked = status; if (child.children.length > 0) { this.#syncGroupCheckboxes(child, status, container); } } } /** * Clone a