From 2b69c49ed1bf7f7a215ac03dc0c9c94a54d84ce1 Mon Sep 17 00:00:00 2001 From: Bruno Charest Date: Thu, 26 Mar 2026 19:53:40 -0400 Subject: [PATCH] refactor: remove hidden files indexing configuration and convert to UI-only display preference, eliminating includeHidden and hiddenWhitelist from vault config and indexing logic while adding hideHiddenFiles client-side filtering --- backend/attachment_indexer.py | 15 +- backend/indexer.py | 67 ++------- backend/main.py | 44 ++---- backend/utils.py | 40 ------ backend/vault_settings.py | 6 +- frontend/app.js | 261 +++++++++------------------------- frontend/index.html | 5 +- 7 files changed, 98 insertions(+), 340 deletions(-) diff --git a/backend/attachment_indexer.py b/backend/attachment_indexer.py index 011e912..d1587da 100644 --- a/backend/attachment_indexer.py +++ b/backend/attachment_indexer.py @@ -4,8 +4,6 @@ from pathlib import Path from typing import Dict, List, Optional, Set import threading -from backend.utils import should_include_path - logger = logging.getLogger("obsigate.attachment_indexer") # Image file extensions to index @@ -40,12 +38,12 @@ def _scan_vault_attachments(vault_name: str, vault_path: str, vault_cfg: dict = """Synchronously scan a vault directory for image attachments. Walks the vault tree and builds a filename -> absolute path mapping - for all image files. + for all image files. All files are scanned, including hidden files (starting with '.'). Args: vault_name: Display name of the vault. vault_path: Absolute filesystem path to the vault root. - vault_cfg: Optional vault configuration dict with hidden files settings. + vault_cfg: Optional vault configuration dict (unused for indexing, kept for compatibility). Returns: Dict mapping lowercase filenames to lists of absolute paths. @@ -53,10 +51,6 @@ def _scan_vault_attachments(vault_name: str, vault_path: str, vault_cfg: dict = vault_root = Path(vault_path) index: Dict[str, List[Path]] = {} - # Default config if not provided - if vault_cfg is None: - vault_cfg = {"includeHidden": False, "hiddenWhitelist": []} - if not vault_root.exists(): logger.warning(f"Vault path does not exist for attachment scan: {vault_path}") return index @@ -65,11 +59,6 @@ def _scan_vault_attachments(vault_name: str, vault_path: str, vault_cfg: dict = try: for fpath in vault_root.rglob("*"): - # Check if path should be included based on hidden files configuration - rel_parts = fpath.relative_to(vault_root).parts - if not should_include_path(rel_parts, vault_cfg): - continue - # Only process files if not fpath.is_file(): continue diff --git a/backend/indexer.py b/backend/indexer.py index e600b21..b6814ff 100644 --- a/backend/indexer.py +++ b/backend/indexer.py @@ -9,8 +9,6 @@ from typing import Dict, List, Optional, Any import frontmatter -from backend.utils import should_include_path - logger = logging.getLogger("obsigate.indexer") # Global in-memory index @@ -61,16 +59,12 @@ def load_vault_config() -> Dict[str, Dict[str, Any]]: Also reads optional configuration: - VAULT_N_ATTACHMENTS_PATH: relative path to attachments folder - VAULT_N_SCAN_ATTACHMENTS: "true"/"false" to enable/disable scanning - - VAULT_N_INCLUDE_HIDDEN: "true"/"false" to include all hidden files/folders - - VAULT_N_HIDDEN_WHITELIST: comma-separated list of hidden paths to include (e.g., ".obsidian,.github") Returns: Dict mapping vault names to configuration dicts with keys: - path: filesystem path (required) - attachmentsPath: relative attachments folder (optional) - scanAttachmentsOnStartup: boolean (default True) - - includeHidden: boolean (default False) - include all hidden files/folders - - hiddenWhitelist: list of hidden paths to include even if includeHidden is False - type: "VAULT" or "DIR" """ vaults: Dict[str, Dict[str, Any]] = {} @@ -84,16 +78,11 @@ def load_vault_config() -> Dict[str, Dict[str, Any]]: # Optional configuration attachments_path = os.environ.get(f"VAULT_{n}_ATTACHMENTS_PATH") scan_attachments = os.environ.get(f"VAULT_{n}_SCAN_ATTACHMENTS", "true").lower() == "true" - include_hidden = os.environ.get(f"VAULT_{n}_INCLUDE_HIDDEN", "false").lower() == "true" - hidden_whitelist_str = os.environ.get(f"VAULT_{n}_HIDDEN_WHITELIST", "") - hidden_whitelist = [item.strip() for item in hidden_whitelist_str.split(",") if item.strip()] vaults[name] = { "path": path, "attachmentsPath": attachments_path, "scanAttachmentsOnStartup": scan_attachments, - "includeHidden": include_hidden, - "hiddenWhitelist": hidden_whitelist, "type": "VAULT" } n += 1 @@ -105,16 +94,10 @@ def load_vault_config() -> Dict[str, Dict[str, Any]]: if not name or not path: break - include_hidden = os.environ.get(f"DIR_{n}_INCLUDE_HIDDEN", "false").lower() == "true" - hidden_whitelist_str = os.environ.get(f"DIR_{n}_HIDDEN_WHITELIST", "") - hidden_whitelist = [item.strip() for item in hidden_whitelist_str.split(",") if item.strip()] - vaults[name] = { "path": path, "attachmentsPath": None, "scanAttachmentsOnStartup": False, - "includeHidden": include_hidden, - "hiddenWhitelist": hidden_whitelist, "type": "DIR" } n += 1 @@ -219,11 +202,13 @@ def _scan_vault(vault_name: str, vault_path: str, vault_cfg: Optional[Dict[str, Walks the vault tree, reads supported files, extracts metadata (tags, title, content preview) and stores a capped content snapshot for in-memory full-text search. + + All files and directories are indexed, including hidden files (starting with '.'). Args: vault_name: Display name of the vault. vault_path: Absolute filesystem path to the vault root. - vault_cfg: Optional vault configuration dict with hidden files settings. + vault_cfg: Optional vault configuration dict (unused for indexing, kept for compatibility). Returns: Dict with keys ``files`` (list), ``tags`` (counter dict), ``path`` (str), ``paths`` (list). @@ -232,21 +217,12 @@ def _scan_vault(vault_name: str, vault_path: str, vault_cfg: Optional[Dict[str, files: List[Dict[str, Any]] = [] tag_counts: Dict[str, int] = {} paths: List[Dict[str, str]] = [] - - # Default config if not provided - if vault_cfg is None: - vault_cfg = {"includeHidden": False, "hiddenWhitelist": []} if not vault_root.exists(): logger.warning(f"Vault path does not exist: {vault_path}") return {"files": [], "tags": {}, "path": vault_path, "paths": []} for fpath in vault_root.rglob("*"): - # Check if path should be included based on hidden files configuration - rel_parts = fpath.relative_to(vault_root).parts - if not should_include_path(rel_parts, vault_cfg): - continue - rel_path_str = str(fpath.relative_to(vault_root)).replace("\\", "/") # Add all paths (files and directories) to path index @@ -329,17 +305,8 @@ async def build_index(progress_callback=None) -> None: vault_config.clear() vault_config.update(load_vault_config()) - # Merge vault_settings (from UI) with vault_config (from env vars) - from backend.vault_settings import get_all_vault_settings - saved_settings = get_all_vault_settings() - for vault_name, config in vault_config.items(): - if vault_name in saved_settings: - settings = saved_settings[vault_name] - # Override with saved settings if present - if "includeHidden" in settings: - config["includeHidden"] = settings["includeHidden"] - if "hiddenWhitelist" in settings: - config["hiddenWhitelist"] = settings["hiddenWhitelist"] + # Note: vault_settings are now only used for UI display preferences (hideHiddenFiles) + # Indexing always includes all files regardless of settings global _index_generation with _index_lock: @@ -443,22 +410,11 @@ async def reload_single_vault(vault_name: str) -> Dict[str, Any]: # Reload vault config from env vars vault_config.update(load_vault_config()) - # Merge with saved settings - from backend.vault_settings import get_vault_setting - saved_settings = get_vault_setting(vault_name) - if vault_name not in vault_config: raise ValueError(f"Vault '{vault_name}' not found in configuration") config = vault_config[vault_name] - # Override with saved settings if present - if saved_settings: - if "includeHidden" in saved_settings: - config["includeHidden"] = saved_settings["includeHidden"] - if "hiddenWhitelist" in saved_settings: - config["hiddenWhitelist"] = saved_settings["hiddenWhitelist"] - # Remove old vault data from index structures await remove_vault_from_index(vault_name) @@ -520,12 +476,14 @@ def _get_async_lock() -> asyncio.Lock: def _index_single_file_sync(vault_name: str, vault_path: str, file_path: str, vault_cfg: Optional[Dict[str, Any]] = None) -> Optional[Dict[str, Any]]: """Synchronously read and parse a single file for indexing. + + All files are indexed, including hidden files (starting with '.'). Args: vault_name: Name of the vault. vault_path: Absolute path to vault root. file_path: Absolute path to the file. - vault_cfg: Optional vault configuration dict with hidden files settings. + vault_cfg: Optional vault configuration dict (unused for indexing, kept for compatibility). Returns: File info dict or None if the file cannot be read. @@ -538,13 +496,6 @@ def _index_single_file_sync(vault_name: str, vault_path: str, file_path: str, va return None relative = fpath.relative_to(vault_root) - rel_parts = relative.parts - - # Check if path should be included based on hidden files configuration - if vault_cfg is None: - vault_cfg = {"includeHidden": False, "hiddenWhitelist": []} - if not should_include_path(rel_parts, vault_cfg): - return None ext = fpath.suffix.lower() basename_lower = fpath.name.lower() @@ -815,8 +766,6 @@ async def add_vault_to_index(vault_name: str, vault_path: str) -> Dict[str, Any] "path": vault_path, "attachmentsPath": None, "scanAttachmentsOnStartup": True, - "includeHidden": False, - "hiddenWhitelist": [], } loop = asyncio.get_event_loop() diff --git a/backend/main.py b/backend/main.py index 4fc2951..ef378bb 100644 --- a/backend/main.py +++ b/backend/main.py @@ -1414,32 +1414,28 @@ async def api_attachment_stats(vault: Optional[str] = Query(None, description="V # --------------------------------------------------------------------------- -# Vault Settings API — Hidden files configuration +# Vault Settings API — Display preferences # --------------------------------------------------------------------------- @app.get("/api/vaults/{vault_name}/settings") async def api_get_vault_settings(vault_name: str, current_user=Depends(require_auth)): - """Get settings for a specific vault including hidden files configuration. + """Get UI display settings for a specific vault. Args: vault_name: Name of the vault. Returns: - Dict with vault settings including includeHidden and hiddenWhitelist. + Dict with vault settings including hideHiddenFiles. """ if vault_name not in index: raise HTTPException(status_code=404, detail=f"Vault '{vault_name}' not found") - # Get current vault config from environment - vault_cfg = vault_config.get(vault_name, {}) - # Get persisted settings persisted = get_vault_setting(vault_name) or {} - # Merge with defaults + # Default settings settings = { - "includeHidden": vault_cfg.get("includeHidden", False), - "hiddenWhitelist": vault_cfg.get("hiddenWhitelist", []), + "hideHiddenFiles": False, } settings.update(persisted) @@ -1448,11 +1444,11 @@ async def api_get_vault_settings(vault_name: str, current_user=Depends(require_a @app.post("/api/vaults/{vault_name}/settings") async def api_update_vault_settings(vault_name: str, body: dict = Body(...), current_user=Depends(require_admin)): - """Update settings for a specific vault. + """Update UI display settings for a specific vault. Args: vault_name: Name of the vault. - body: Dict with settings to update (includeHidden, hiddenWhitelist). + body: Dict with settings to update (hideHiddenFiles). Returns: Updated settings dict. @@ -1463,18 +1459,10 @@ async def api_update_vault_settings(vault_name: str, body: dict = Body(...), cur # Validate settings settings_to_update = {} - if "includeHidden" in body: - if not isinstance(body["includeHidden"], bool): - raise HTTPException(status_code=400, detail="includeHidden must be a boolean") - settings_to_update["includeHidden"] = body["includeHidden"] - - if "hiddenWhitelist" in body: - if not isinstance(body["hiddenWhitelist"], list): - raise HTTPException(status_code=400, detail="hiddenWhitelist must be a list") - # Validate each item is a string - if not all(isinstance(item, str) for item in body["hiddenWhitelist"]): - raise HTTPException(status_code=400, detail="All hiddenWhitelist items must be strings") - settings_to_update["hiddenWhitelist"] = body["hiddenWhitelist"] + if "hideHiddenFiles" in body: + if not isinstance(body["hideHiddenFiles"], bool): + raise HTTPException(status_code=400, detail="hideHiddenFiles must be a boolean") + settings_to_update["hideHiddenFiles"] = body["hideHiddenFiles"] # Update persisted settings try: @@ -1492,10 +1480,6 @@ async def api_update_vault_settings(vault_name: str, body: dict = Body(...), cur detail=f"Failed to save settings: {str(e)}" ) - # Update in-memory vault config - if vault_name in vault_config: - vault_config[vault_name].update(settings_to_update) - logger.info(f"Updated settings for vault '{vault_name}': {settings_to_update}") return updated @@ -1503,7 +1487,7 @@ async def api_update_vault_settings(vault_name: str, body: dict = Body(...), cur @app.get("/api/vaults/settings/all") async def api_get_all_vault_settings(current_user=Depends(require_auth)): - """Get settings for all vaults. + """Get UI display settings for all vaults. Returns: Dict mapping vault names to their settings. @@ -1511,12 +1495,10 @@ async def api_get_all_vault_settings(current_user=Depends(require_auth)): all_settings = {} for vault_name in index.keys(): - vault_cfg = vault_config.get(vault_name, {}) persisted = get_vault_setting(vault_name) or {} settings = { - "includeHidden": vault_cfg.get("includeHidden", False), - "hiddenWhitelist": vault_cfg.get("hiddenWhitelist", []), + "hideHiddenFiles": False, } settings.update(persisted) all_settings[vault_name] = settings diff --git a/backend/utils.py b/backend/utils.py index ab20833..5f5d838 100644 --- a/backend/utils.py +++ b/backend/utils.py @@ -1,42 +1,2 @@ """Utility functions shared across backend modules.""" from typing import Dict, Any, Tuple - - -def should_include_path(rel_parts: Tuple[str, ...], vault_config: Dict[str, Any]) -> bool: - """Check if a path should be included based on hidden files configuration. - - Simplified logic: - - If includeHidden=True: include ALL hidden files/folders recursively - - If includeHidden=False: check whitelist - - If a whitelisted folder is in the path, include ALL sub-hidden files/folders - - Otherwise, exclude the path - - Args: - rel_parts: Tuple of path parts relative to vault root - vault_config: Vault configuration dict with includeHidden and hiddenWhitelist - - Returns: - True if the path should be included, False otherwise - """ - include_hidden = vault_config.get("includeHidden", False) - hidden_whitelist = vault_config.get("hiddenWhitelist", []) - - # Check if any part of the path starts with a dot (hidden) - hidden_parts = [part for part in rel_parts if part.startswith(".")] - - if not hidden_parts: - # No hidden parts, always include - return True - - if include_hidden: - # Include all hidden files/folders recursively - return True - - # Check if the FIRST hidden part is in the whitelist - # If yes, include all sub-hidden files/folders automatically - first_hidden = hidden_parts[0] - if first_hidden in hidden_whitelist: - return True - - # First hidden part not in whitelist, exclude - return False diff --git a/backend/vault_settings.py b/backend/vault_settings.py index 70639f8..7c1111a 100644 --- a/backend/vault_settings.py +++ b/backend/vault_settings.py @@ -1,7 +1,11 @@ """Vault-specific settings management. -Provides persistent storage for per-vault configuration like hidden files settings. +Provides persistent storage for per-vault UI display preferences. Settings are stored in /app/data/vault_settings.json + +Current settings: +- hideHiddenFiles (bool): Whether to hide files/folders starting with '.' in the UI + Note: All files are always indexed regardless of this setting. This only affects display. """ import json diff --git a/frontend/app.js b/frontend/app.js index 311dee0..1568213 100644 --- a/frontend/app.js +++ b/frontend/app.js @@ -24,6 +24,9 @@ let _iconDebounceTimer = null; let activeSidebarTab = "vaults"; let filterDebounce = null; + + // Vault settings cache for hideHiddenFiles + let vaultSettings = {}; // Advanced search state let advancedSearchOffset = 0; @@ -1866,6 +1869,39 @@ renderTagCloud(filteredTags); } + // --------------------------------------------------------------------------- + // Helper: Check if path should be displayed based on hideHiddenFiles setting + // --------------------------------------------------------------------------- + function shouldDisplayPath(path, vaultName) { + // Get hideHiddenFiles setting for this vault (default: false = show all) + const settings = vaultSettings[vaultName] || { hideHiddenFiles: false }; + + if (!settings.hideHiddenFiles) { + // Show all files + return true; + } + + // Check if any segment of the path starts with a dot (hidden) + const segments = path.split('/').filter(Boolean); + for (const segment of segments) { + if (segment.startsWith('.')) { + return false; // Hide this path + } + } + + return true; // Show this path + } + + async function loadVaultSettings() { + try { + const settings = await api("/api/vaults/settings/all"); + vaultSettings = settings; + } catch (err) { + console.error("Failed to load vault settings:", err); + vaultSettings = {}; + } + } + // --------------------------------------------------------------------------- // Sidebar — Vault tree // --------------------------------------------------------------------------- @@ -2013,6 +2049,11 @@ const fragment = document.createDocumentFragment(); data.items.forEach((item) => { + // Apply client-side filtering for hidden files + if (!shouldDisplayPath(item.path, vaultName)) { + return; // Skip this item + } + if (item.type === "directory") { const dirItem = el("div", { class: "tree-item", "data-vault": vaultName, "data-path": item.path }, [ icon("chevron-right", 14), @@ -3013,9 +3054,6 @@ // Hidden files configuration const saveHiddenBtn = document.getElementById("cfg-save-hidden-files"); if (saveHiddenBtn) saveHiddenBtn.addEventListener("click", saveHiddenFilesSettings); - - const reindexHiddenBtn = document.getElementById("cfg-reindex-hidden"); - if (reindexHiddenBtn) reindexHiddenBtn.addEventListener("click", reindexWithHiddenFiles); document.addEventListener("keydown", (e) => { if (e.key === "Escape" && modal.classList.contains("active")) { @@ -3231,32 +3269,6 @@ // --- Hidden Files Configuration --- - // Track which vaults have been modified - let modifiedVaults = new Set(); - - function updateHiddenFilesButtonStates() { - const saveBtn = document.getElementById("cfg-save-hidden-files"); - const reindexBtn = document.getElementById("cfg-reindex-hidden"); - - if (modifiedVaults.size > 0) { - if (saveBtn) { - saveBtn.textContent = `💾 Sauvegarder (${modifiedVaults.size} modifié${modifiedVaults.size > 1 ? 's' : ''})`; - saveBtn.classList.add("config-btn-highlight"); - } - if (reindexBtn) { - reindexBtn.textContent = "🔄 Sauvegarder et réindexer"; - } - } else { - if (saveBtn) { - saveBtn.textContent = "💾 Sauvegarder"; - saveBtn.classList.remove("config-btn-highlight"); - } - if (reindexBtn) { - reindexBtn.textContent = "🔄 Réindexer"; - } - } - } - async function loadHiddenFilesSettings() { const container = document.getElementById("hidden-files-vault-list"); if (!container) return; @@ -3281,7 +3293,7 @@ } allVaults.forEach(vault => { - const settings = allSettings[vault.name] || { includeHidden: false, hiddenWhitelist: [] }; + const settings = allSettings[vault.name] || { hideHiddenFiles: false }; const vaultCard = el("div", { class: "hidden-files-vault-card", "data-vault": vault.name }); @@ -3291,144 +3303,32 @@ el("span", { class: "hidden-files-vault-type" }, [document.createTextNode(vault.type || "VAULT")]) ]); - // Include all hidden toggle + // Hide hidden files toggle const toggleRow = el("div", { class: "config-row" }, [ - el("label", { class: "config-label", for: `hidden-include-${vault.name}` }, [ - document.createTextNode("Afficher tous les fichiers cachés") + el("label", { class: "config-label", for: `hide-hidden-${vault.name}` }, [ + document.createTextNode("Masquer les fichiers/dossiers cachés") ]), el("label", { class: "config-toggle" }, [ el("input", { type: "checkbox", - id: `hidden-include-${vault.name}`, + id: `hide-hidden-${vault.name}`, "data-vault": vault.name, - checked: settings.includeHidden || false + checked: settings.hideHiddenFiles || false }), el("span", { class: "config-toggle-slider" }) ]), el("span", { class: "config-hint" }, [ - document.createTextNode("Indexer tous les fichiers/dossiers commençant par un point") + document.createTextNode("Masquer les fichiers/dossiers commençant par un point dans l'interface (ils restent indexés et cherchables)") ]) ]); - // Whitelist section - const whitelistSection = el("div", { class: "hidden-files-whitelist" }); - const whitelistLabel = el("label", { class: "config-label" }, [ - document.createTextNode("Liste blanche") - ]); - const whitelistHint = el("span", { class: "config-hint", style: "display:block;margin-bottom:8px" }, [ - document.createTextNode("Dossiers cachés spécifiques à afficher (tous les sous-dossiers cachés seront inclus)") - ]); - - const whitelistItems = el("div", { class: "hidden-files-whitelist-items", id: `whitelist-items-${vault.name}` }); - - // Render existing whitelist items - (settings.hiddenWhitelist || []).forEach(item => { - const itemEl = createWhitelistItem(vault.name, item); - whitelistItems.appendChild(itemEl); - }); - - // Add new item input - const addRow = el("div", { class: "hidden-files-add-row" }, [ - el("input", { - type: "text", - class: "config-input", - id: `whitelist-input-${vault.name}`, - placeholder: ".obsidian" - }), - el("button", { - class: "config-btn-add", - type: "button", - "data-vault": vault.name - }, [document.createTextNode("➕ Ajouter")]) - ]); - - whitelistSection.appendChild(whitelistLabel); - whitelistSection.appendChild(whitelistHint); - whitelistSection.appendChild(whitelistItems); - whitelistSection.appendChild(addRow); - vaultCard.appendChild(header); vaultCard.appendChild(toggleRow); - vaultCard.appendChild(whitelistSection); container.appendChild(vaultCard); - - // Event listeners - const addBtn = addRow.querySelector("button"); - const input = addRow.querySelector("input"); - const checkbox = toggleRow.querySelector("input[type='checkbox']"); - - addBtn.addEventListener("click", () => { - addWhitelistItem(vault.name); - modifiedVaults.add(vault.name); - updateHiddenFilesButtonStates(); - }); - input.addEventListener("keypress", (e) => { - if (e.key === "Enter") { - addWhitelistItem(vault.name); - modifiedVaults.add(vault.name); - updateHiddenFilesButtonStates(); - } - }); - checkbox.addEventListener("change", () => { - modifiedVaults.add(vault.name); - updateHiddenFilesButtonStates(); - }); }); } - function createWhitelistItem(vaultName, itemValue) { - const item = el("div", { class: "hidden-files-whitelist-item" }, [ - el("span", { class: "whitelist-item-text" }, [document.createTextNode(itemValue)]), - el("button", { - class: "whitelist-item-remove", - type: "button", - title: "Supprimer", - "data-vault": vaultName, - "data-item": itemValue - }, [document.createTextNode("×")]) - ]); - - const removeBtn = item.querySelector("button"); - removeBtn.addEventListener("click", () => { - item.remove(); - modifiedVaults.add(vaultName); - updateHiddenFilesButtonStates(); - }); - - return item; - } - - function addWhitelistItem(vaultName) { - const input = document.getElementById(`whitelist-input-${vaultName}`); - const container = document.getElementById(`whitelist-items-${vaultName}`); - const includeHiddenCheckbox = document.getElementById(`hidden-include-${vaultName}`); - - if (!input || !container) return; - - const value = input.value.trim(); - if (!value) return; - - // Auto-add dot if missing - const normalizedValue = value.startsWith(".") ? value : `.${value}`; - - // Check for duplicates - const existing = Array.from(container.querySelectorAll(".whitelist-item-text")) - .map(el => el.textContent); - if (existing.includes(normalizedValue)) { - showToast("Cet élément existe déjà", "error"); - return; - } - - // Auto-uncheck "Afficher tous les fichiers cachés" when adding to whitelist - if (includeHiddenCheckbox && includeHiddenCheckbox.checked) { - includeHiddenCheckbox.checked = false; - } - - const item = createWhitelistItem(vaultName, normalizedValue); - container.appendChild(item); - input.value = ""; - } async function saveHiddenFilesSettings() { const btn = document.getElementById("cfg-save-hidden-files"); @@ -3440,15 +3340,10 @@ vaultCards.forEach(card => { const vaultName = card.dataset.vault; - const includeHidden = document.getElementById(`hidden-include-${vaultName}`)?.checked || false; - - const whitelistItems = Array.from( - document.querySelectorAll(`#whitelist-items-${vaultName} .whitelist-item-text`) - ).map(el => el.textContent); + const hideHiddenFiles = document.getElementById(`hide-hidden-${vaultName}`)?.checked || false; const settings = { - includeHidden, - hiddenWhitelist: whitelistItems + hideHiddenFiles }; promises.push( @@ -3467,9 +3362,14 @@ }); await Promise.all(promises); - modifiedVaults.clear(); - updateHiddenFilesButtonStates(); + + // Reload vault settings to update the cache + await loadVaultSettings(); + showToast("✓ Paramètres sauvegardés", "success"); + + // Refresh the UI to apply the filter + await Promise.all([loadVaults(), refreshTagsForContext()]); } catch (err) { console.error("Failed to save hidden files settings:", err); const errorMsg = err.message || "Erreur inconnue"; @@ -3479,41 +3379,6 @@ } } - async function reindexWithHiddenFiles() { - const btn = document.getElementById("cfg-reindex-hidden"); - if (btn) { btn.disabled = true; btn.textContent = "💾 Sauvegarde..."; } - - try { - // First save the settings to ensure they are persisted - await saveHiddenFilesSettings(); - - // Update button text to show reindexing phase - if (btn) { btn.textContent = "⏳ Réindexation..."; } - - // Reindex only modified vaults if any, otherwise reindex all - if (modifiedVaults.size > 0) { - const vaultsToReindex = Array.from(modifiedVaults); - for (const vaultName of vaultsToReindex) { - await api(`/api/index/reload/${encodeURIComponent(vaultName)}`); - } - showToast(`✓ Réindexation terminée (${vaultsToReindex.length} vault${vaultsToReindex.length > 1 ? 's' : ''})`, "success"); - } else { - await api("/api/index/reload"); - showToast("✓ Réindexation terminée", "success"); - } - - modifiedVaults.clear(); - updateHiddenFilesButtonStates(); - loadDiagnostics(); - await Promise.all([loadVaults(), loadTags()]); - } catch (err) { - console.error("Reindex with hidden files error:", err); - const errorMsg = err.message || "Erreur inconnue"; - showToast(`Erreur: ${errorMsg}`, "error"); - } finally { - if (btn) { btn.disabled = false; btn.textContent = "🔄 Réindexer"; } - } - } function renderConfigFilters() { const config = TagFilterService.getConfig(); @@ -3826,6 +3691,11 @@ } const container = el("div", { class: "search-results" }); data.results.forEach((r) => { + // Apply client-side filtering for hidden files + if (!shouldDisplayPath(r.path, r.vault)) { + return; // Skip this result + } + const titleDiv = el("div", { class: "search-result-title" }); if (query && query.trim()) { highlightSearchText(titleDiv, r.title, query, searchCaseSensitive); @@ -3986,6 +3856,11 @@ // Results list const container = el("div", { class: "search-results" }); data.results.forEach((r) => { + // Apply client-side filtering for hidden files + if (!shouldDisplayPath(r.path, r.vault)) { + return; // Skip this result + } + const titleDiv = el("div", { class: "search-result-title" }); if (freeText) { highlightSearchText(titleDiv, r.title, freeText, searchCaseSensitive); @@ -5544,7 +5419,7 @@ if (authOk) { try { - await Promise.all([loadVaults(), loadTags()]); + await Promise.all([loadVaultSettings(), loadVaults(), loadTags()]); // Check for popup mode query parameter const urlParams = new URLSearchParams(window.location.search); diff --git a/frontend/index.html b/frontend/index.html index 2b18f3d..94e8af8 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -551,9 +551,9 @@

🗂️ Fichiers cachés

-

Gérez l'affichage des fichiers/dossiers cachés (commençant par .) par vault.

+

Contrôlez l'affichage des fichiers/dossiers cachés (commençant par .) par vault.

- ⚠️ Important : Après avoir modifié les paramètres, cliquez sur "Sauvegarder" puis sur "Réindexer" pour appliquer les changements. + ℹ️ Note : Tous les fichiers sont toujours indexés et cherchables. Ce paramètre contrôle uniquement leur visibilité dans l'interface.

@@ -562,7 +562,6 @@
-