From f95a58087b87036813782409473c86fa9cd1c08d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Fri, 6 Mar 2026 23:23:38 +0100 Subject: [PATCH] Select the respective node in the sidebar treeviews, when navigating Part-DB When you open a category page from everywhere in Part-DB, the respective node will be opened --- .../elements/sidebar_tree_controller.js | 34 +++++++++++++++++++ .../controllers/elements/tree_controller.js | 29 ---------------- 2 files changed, 34 insertions(+), 29 deletions(-) diff --git a/assets/controllers/elements/sidebar_tree_controller.js b/assets/controllers/elements/sidebar_tree_controller.js index c80de6ed..e0f012be 100644 --- a/assets/controllers/elements/sidebar_tree_controller.js +++ b/assets/controllers/elements/sidebar_tree_controller.js @@ -19,6 +19,7 @@ import {Controller} from "@hotwired/stimulus"; import {default as TreeController} from "./tree_controller"; +import {EVENT_INITIALIZED} from "@jbtronics/bs-treeview"; export default class extends TreeController { static targets = [ "tree", 'sourceText' ]; @@ -57,6 +58,39 @@ export default class extends TreeController { //Register an event listener which checks if the tree needs to be updated document.addEventListener('turbo:render', this.doUpdateIfNeeded.bind(this)); + + //Register an event listener, to check if we end up on a page we can highlight in the tree, if so then higlight it + document.addEventListener('turbo:load', this._onTurboLoad.bind(this)); + //On initial page load the tree is not available yet, so do another check after the tree is initialized + this.treeTarget.addEventListener(EVENT_INITIALIZED, (event) => { + this.selectNodeWithURL(document.location) + }); + } + + _onTurboLoad(event) { + this.selectNodeWithURL(event.detail.url); + } + + selectNodeWithURL(url) { + //Get path from url + const path = new URL(url).pathname; + + if (!this._tree) { + return; + } + + //Unselect all nodes + this._tree.unselectAll({silent: true, ignorePreventUnselect: true}); + + //Try to find a node with this path as data-path + const nodes = this._tree.findNodes(path, "href"); + if (nodes.length !== 1) { + return; //We can only work with exactly one node, if there are multiple nodes with the same path, we cannot know which one to select, so we do nothing + } + const node = nodes[0]; + + node.setSelected(true, {ignorePreventUnselect: true, silent: true}); + this._tree.revealNode(node); } doUpdateIfNeeded() diff --git a/assets/controllers/elements/tree_controller.js b/assets/controllers/elements/tree_controller.js index 28957e2a..13a7a9f9 100644 --- a/assets/controllers/elements/tree_controller.js +++ b/assets/controllers/elements/tree_controller.js @@ -113,41 +113,12 @@ export default class extends Controller { const treeView = event.detail.treeView; treeView.revealNode(treeView.getSelected()); - //Add the url watcher to all selected nodes - for (const node of treeView.getSelected()) { - this._registerURLWatcher(node); - } - //Add contextmenu event listener to the tree, which allows us to open the links in a new tab with a right click treeView.getTreeElement().addEventListener("contextmenu", this._onContextMenu.bind(this)); }); } - _registerURLWatcher(node) - { - //Register a watcher for a location change, which will unselect the node, if the location changes - const desired_url = node.href; - - //Ensure that the node is unselected, if the location changes - const unselectNode = () => { - //Parse url so we can properly compare them - const desired = new URL(node.href, window.location.origin); - - //We only compare the pathname, because the hash and parameters should not matter - if(window.location.pathname !== desired.pathname) { - //The ignore parameter is important here, otherwise the node will not be unselected - node.setSelected(false, {silent: true, ignorePreventUnselect: true}); - - //Unregister the watcher - document.removeEventListener('turbo:load', unselectNode); - } - }; - - //Register the watcher via hotwire turbo - //We must just load to have the new url in window.location - document.addEventListener('turbo:load', unselectNode); - } _onContextMenu(event) {