Add PermissionError handling to vault indexer and implement recursive descendant expansion in sidebar tree filter with auto-expand for matching directories

This commit is contained in:
Bruno Charest 2026-03-22 20:26:05 -04:00
parent d311a09527
commit 29e6e1c052
2 changed files with 52 additions and 3 deletions

View File

@ -218,6 +218,9 @@ def _scan_vault(vault_name: str, vault_path: str) -> Dict[str, Any]:
for tag in tags: for tag in tags:
tag_counts[tag] = tag_counts.get(tag, 0) + 1 tag_counts[tag] = tag_counts.get(tag, 0) + 1
except PermissionError as e:
logger.warning(f"Permission denied, skipping {fpath}: {e}")
continue
except Exception as e: except Exception as e:
logger.error(f"Error indexing {fpath}: {e}") logger.error(f"Error indexing {fpath}: {e}")
continue continue

View File

@ -758,23 +758,31 @@
function filterSidebarTree(query) { function filterSidebarTree(query) {
const tree = document.getElementById("vault-tree"); const tree = document.getElementById("vault-tree");
const items = tree.querySelectorAll(".tree-item"); const items = tree.querySelectorAll(".tree-item");
const containers = tree.querySelectorAll(".tree-children");
if (!query) { if (!query) {
items.forEach((item) => item.classList.remove("filtered-out")); items.forEach((item) => item.classList.remove("filtered-out"));
tree.querySelectorAll(".tree-children").forEach((c) => c.classList.remove("filtered-out")); containers.forEach((c) => {
c.classList.remove("filtered-out");
// Keep current collapsed state when clearing filter
});
return; return;
} }
// First pass: mark all as filtered out // First pass: mark all as filtered out
items.forEach((item) => item.classList.add("filtered-out")); items.forEach((item) => item.classList.add("filtered-out"));
tree.querySelectorAll(".tree-children").forEach((c) => c.classList.add("filtered-out")); containers.forEach((c) => c.classList.add("filtered-out"));
// Second pass: show matching items and their ancestors // Second pass: find matching items and mark them + ancestors + descendants
const matchingItems = new Set();
items.forEach((item) => { items.forEach((item) => {
const text = sidebarFilterCaseSensitive ? item.textContent : item.textContent.toLowerCase(); const text = sidebarFilterCaseSensitive ? item.textContent : item.textContent.toLowerCase();
const searchQuery = sidebarFilterCaseSensitive ? query : query.toLowerCase(); const searchQuery = sidebarFilterCaseSensitive ? query : query.toLowerCase();
if (text.includes(searchQuery)) { if (text.includes(searchQuery)) {
matchingItems.add(item);
item.classList.remove("filtered-out"); item.classList.remove("filtered-out");
// Show all ancestor containers // Show all ancestor containers
let parent = item.parentElement; let parent = item.parentElement;
while (parent && parent !== tree) { while (parent && parent !== tree) {
@ -784,8 +792,46 @@
} }
parent = parent.parentElement; parent = parent.parentElement;
} }
// If this is a directory (has a children container after it), show all descendants
const nextEl = item.nextElementSibling;
if (nextEl && nextEl.classList.contains("tree-children")) {
nextEl.classList.remove("filtered-out");
nextEl.classList.remove("collapsed");
// Recursively show all children in this container
showAllDescendants(nextEl);
}
} }
}); });
// Third pass: show items that are descendants of matching directories
// and ensure their containers are visible
matchingItems.forEach((item) => {
const nextEl = item.nextElementSibling;
if (nextEl && nextEl.classList.contains("tree-children")) {
const children = nextEl.querySelectorAll(".tree-item");
children.forEach((child) => child.classList.remove("filtered-out"));
}
});
}
function showAllDescendants(container) {
const items = container.querySelectorAll(".tree-item");
items.forEach((item) => {
item.classList.remove("filtered-out");
// If this item has children, also show them
const nextEl = item.nextElementSibling;
if (nextEl && nextEl.classList.contains("tree-children")) {
nextEl.classList.remove("filtered-out");
nextEl.classList.remove("collapsed");
}
});
// Also ensure all nested containers are visible
const nestedContainers = container.querySelectorAll(".tree-children");
nestedContainers.forEach((c) => {
c.classList.remove("filtered-out");
c.classList.remove("collapsed");
});
} }
function filterTagCloud(query) { function filterTagCloud(query) {