From 78f7fd6a53f1bf4dce07c4193d004c7d623157fc Mon Sep 17 00:00:00 2001 From: Bruno Charest Date: Tue, 31 Mar 2026 21:26:45 -0400 Subject: [PATCH] feat: improve dashboard navigation to files by focusing parent directory and syncing active state - Extract getParentDirectoryPath helper to get parent directory from file path - Extract syncActiveFileTreeItem helper to manage active tree item highlighting - Update dashboard file navigation to focus parent directory with expansion instead of file itself - Manually sync active state after navigation to ensure file is highlighted in tree - Refactor openFile to use new syncActiveFileTreeItem helper --- frontend/app.js | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/frontend/app.js b/frontend/app.js index ec01d1e..a39efb6 100644 --- a/frontend/app.js +++ b/frontend/app.js @@ -2410,6 +2410,26 @@ scrollTreeItemIntoView(lastTargetItem, options && options.alignToTop); } + function getParentDirectoryPath(filePath) { + if (!filePath) return ""; + const segments = filePath.split("/").filter(Boolean); + if (segments.length <= 1) return ""; + segments.pop(); + return segments.join("/"); + } + + function syncActiveFileTreeItem(vaultName, filePath) { + document.querySelectorAll(".tree-item.active").forEach((el) => el.classList.remove("active")); + if (!vaultName || !filePath) return; + const selector = `.tree-item[data-vault="${CSS.escape(vaultName)}"][data-path="${CSS.escape(filePath)}"]`; + try { + const active = document.querySelector(selector); + if (active) active.classList.add("active"); + } catch (e) { + /* selector might fail on special chars */ + } + } + async function loadDirectory(vaultName, dirPath, container) { // Only show the loading spinner if the container is currently empty const isEmpty = container.children.length === 0; @@ -2631,7 +2651,8 @@ await focusPathInSidebar(entry.vault, entry.path, { alignToTop: true, expandTarget: true }); } else { await openFile(entry.vault, entry.path); - await focusPathInSidebar(entry.vault, entry.path, { alignToTop: false }); + await focusPathInSidebar(entry.vault, getParentDirectoryPath(entry.path), { alignToTop: true, expandTarget: true }); + syncActiveFileTreeItem(entry.vault, entry.path); } closeMobileSidebar(); }); @@ -2926,14 +2947,7 @@ cachedRawSource = null; // Highlight active - document.querySelectorAll(".tree-item.active").forEach((el) => el.classList.remove("active")); - const selector = `.tree-item[data-vault="${vaultName}"][data-path="${CSS.escape(filePath)}"]`; - try { - const active = document.querySelector(selector); - if (active) active.classList.add("active"); - } catch (e) { - /* selector might fail on special chars */ - } + syncActiveFileTreeItem(vaultName, filePath); // Show loading state while fetching const area = document.getElementById("content-area");