From 66a5505965907a0c5e0da0623dbe4130c8dd7f2f Mon Sep 17 00:00:00 2001 From: Bruno Charest Date: Thu, 1 Oct 2026 10:29:38 -0400 Subject: [PATCH] fix: correction raccourci palette + filtrage ext/vault/tag dans palette fichiers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Correction du raccourci clavier inversé dans l'aide : Ctrl+Shift+Space → Palette de fichiers (navigation rapide) Ctrl+Alt+Space → Palette de commandes - Ajout du support des filtres ext:xxx, vault:nom, tag:monTag dans la palette de fichiers - parseQuery étendu pour gérer les opérateurs de filtrage - Filtrage client-side par extension et tag dans searchFiles et searchBrowseGlobal - Backend : suggest_titles retourne les tags pour chaque suggestion - Schema TitleSuggestion : ajout du champ tags - Placeholders mis à jour pour indiquer les nouveaux filtres disponibles Fixes : raccourci inversé, filtrage par extension/vault/tag dans palette fichiers --- CHANGELOG.md | 6 +++++- README.fr.md | 6 +++--- README.md | 6 +++--- VERSION | 2 +- backend/schemas.py | 1 + backend/search.py | 12 +++++++++--- desktop/Cargo.lock | 2 +- desktop/Cargo.toml | 2 +- desktop/tauri.conf.json | 2 +- docs/ROADMAP.md | 2 +- frontend/index.html | 7 +++---- frontend/js/palette.js | 43 ++++++++++++++++++++++++++++++++++------- package.json | 2 +- 13 files changed, 66 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c7ebf9..c58d6a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ Format basé sur [Keep a Changelog](https://keepachangelog.com/fr/1.1.0/), et [Semantic Versioning](https://semver.org/spec/v2.0.0.html). > **En cours de développement** : les changements à venir sont listés dans la section -> [Unreleased](#unreleased). La dernière version livrée est **2.45.0**. +> [Unreleased](#unreleased). La dernière version livrée est **2.45.1**. --- @@ -14,6 +14,10 @@ et [Semantic Versioning](https://semver.org/spec/v2.0.0.html). --- +## [2.45.1] — 2026-10-01 + +--- + ## [2.45.0] — 2026-09-30 ### Ajouté diff --git a/README.fr.md b/README.fr.md index efe4152..9e68b34 100644 --- a/README.fr.md +++ b/README.fr.md @@ -4,7 +4,7 @@ **Porte d'entrée web ultra-léger pour vos vaults Obsidian** — Accédez, naviguez et recherchez dans toutes vos notes Obsidian depuis n'importe quel appareil via une interface web moderne et responsive. -[![Version](https://img.shields.io/badge/Version-2.45.0-blue.svg)]() +[![Version](https://img.shields.io/badge/Version-2.45.1-blue.svg)]() [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Docker](https://img.shields.io/badge/Docker-Ready-blue.svg)](https://www.docker.com/) [![Python](https://img.shields.io/badge/Python-3.11+-green.svg)](https://www.python.org/) @@ -976,8 +976,8 @@ Ce projet est sous licence **MIT** — voir le fichier [LICENSE](LICENSE) pour l ## 📝 Changelog -Consultez le [CHANGELOG.md](./CHANGELOG.md) pour l'historique complet de toutes les versions (v1.0.0 → v2.45.0). +Consultez le [CHANGELOG.md](./CHANGELOG.md) pour l'historique complet de toutes les versions (v1.0.0 → v2.45.1). --- -*Projet : ObsiGate | Version : 2.45.0 | Dernière mise à jour : Septembre 2026* +*Projet : ObsiGate | Version : 2.45.1 | Dernière mise à jour : Septembre 2026* diff --git a/README.md b/README.md index 8eacc1c..ab0025b 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ **Ultra-light web gateway for your Obsidian vaults** — Access, browse, and search all your Obsidian notes from any device via a modern, responsive web interface. -[![Version](https://img.shields.io/badge/Version-2.45.0-blue.svg)]() +[![Version](https://img.shields.io/badge/Version-2.45.1-blue.svg)]() [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Docker](https://img.shields.io/badge/Docker-Ready-blue.svg)](https://www.docker.com/) [![Python](https://img.shields.io/badge/Python-3.11+-green.svg)](https://www.python.org/) @@ -1151,8 +1151,8 @@ This project is licensed under the **MIT License** - see the [LICENSE](LICENSE) ## 📝 Changelog -See [CHANGELOG.md](./CHANGELOG.md) for the complete version history (v1.0.0 → v2.45.0). +See [CHANGELOG.md](./CHANGELOG.md) for the complete version history (v1.0.0 → v2.45.1). --- -*Project: ObsiGate | Version: 2.45.0 | Last updated: September 2026* +*Project: ObsiGate | Version: 2.45.1 | Last updated: September 2026* diff --git a/VERSION b/VERSION index e599014..4a858ed 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.45.0 +2.45.1 diff --git a/backend/schemas.py b/backend/schemas.py index 298418c..ef9de88 100644 --- a/backend/schemas.py +++ b/backend/schemas.py @@ -666,6 +666,7 @@ class TitleSuggestion(BaseModel): vault: str = Field(description="Vault name") path: str = Field(description="Relative file path") title: str = Field(description="File title") + tags: list[str] = Field(default_factory=list, description="File tags") class SuggestResponse(BaseModel): diff --git a/backend/search.py b/backend/search.py index b3c23f0..587c56f 100644 --- a/backend/search.py +++ b/backend/search.py @@ -373,6 +373,7 @@ class InvertedIndex: self.doc_vault: dict[str, str] = {} self.vault_docs: dict[str, set] = defaultdict(set) self.tag_docs: dict[str, set] = defaultdict(set) + self.doc_tags: dict[str, set] = defaultdict(set) self._sorted_tokens: SortedList = SortedList() self._ready: bool = False # True after initial build @@ -403,6 +404,7 @@ class InvertedIndex: self.doc_vault = {} self.vault_docs = defaultdict(set) self.tag_docs = defaultdict(set) + self.doc_tags = defaultdict(set) for vault_name, vault_data in _indexer.index.items(): for file_info in vault_data.get("files", []): @@ -417,6 +419,7 @@ class InvertedIndex: # --- Per-document tag index --- for tag in file_info.get("tags", []): self.tag_docs[tag.lower()].add(doc_key) + self.doc_tags[file_info['path']].add(tag.lower()) # --- Title tokens --- title_tokens = tokenize(file_info.get("title", "")) @@ -1538,7 +1541,7 @@ def suggest_titles( prefix: str, vault_filter: str = "all", limit: int = SUGGEST_LIMIT, -) -> list[dict[str, str]]: +) -> list[dict[str, Any]]: """Suggest file titles matching a prefix (accent-insensitive). Args: @@ -1547,7 +1550,7 @@ def suggest_titles( limit: Maximum suggestions. Returns: - List of ``{"vault", "path", "title"}`` dicts. + List of ``{"vault", "path", "title", "tags"}`` dicts. """ if not prefix or len(prefix) < MIN_PREFIX_LENGTH: return [] @@ -1565,7 +1568,10 @@ def suggest_titles( key = f"{entry['vault']}::{entry['path']}" if key not in seen: seen.add(key) - results.append(entry) + # Add tags from the index + entry_with_tags: dict[str, Any] = dict(entry) + entry_with_tags["tags"] = list(inv.doc_tags.get(entry["path"], set())) + results.append(entry_with_tags) if len(results) >= limit: return results diff --git a/desktop/Cargo.lock b/desktop/Cargo.lock index 30b5cf2..a074b4a 100644 --- a/desktop/Cargo.lock +++ b/desktop/Cargo.lock @@ -2626,7 +2626,7 @@ dependencies = [ [[package]] name = "obsigate-desktop" -version = "2.45.0" +version = "2.45.1" dependencies = [ "chrono", "env_logger", diff --git a/desktop/Cargo.toml b/desktop/Cargo.toml index 4e6ea9d..cf448a7 100644 --- a/desktop/Cargo.toml +++ b/desktop/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "obsigate-desktop" -version = "2.45.0" +version = "2.45.1" description = "ObsiGate Desktop — Porte d'entrée native pour vos vaults Obsidian" authors = ["Bruno Charest"] edition = "2021" diff --git a/desktop/tauri.conf.json b/desktop/tauri.conf.json index f16e9f1..718d249 100644 --- a/desktop/tauri.conf.json +++ b/desktop/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://raw.githubusercontent.com/nicedoc/obsigate/main/desktop/tauri.conf.schema.json", "productName": "ObsiGate", - "version": "2.45.0", + "version": "2.45.1", "identifier": "com.obsigate.desktop", "build": { "frontendDist": "../frontend", diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 7dcea86..9f541e7 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -1,6 +1,6 @@ # ObsiGate — Roadmap -> **Version :** 2.45.0 | **Dernière mise à jour :** 2026-09-30 +> **Version :** 2.45.1 | **Dernière mise à jour :** 2026-10-01 > **Ce fichier ne contient que le travail à venir** (🔵 En cours + ⚪ Backlog) et un index compact > vers les fonctionnalités livrées. > - **Méthode de livraison à appliquer pour toute tâche : [DELIVERY_WORKFLOW.md](./DELIVERY_WORKFLOW.md)** diff --git a/frontend/index.html b/frontend/index.html index 95730a8..61dd913 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -1196,16 +1196,15 @@ >Ctrl+Shift+Space Palette de commandesPalette de fichiers (nav. + rapide)
Ctrl+Alt+Space - Palette de fichiers (nav. - rapide)Palette de commandes
diff --git a/frontend/js/palette.js b/frontend/js/palette.js index 11614b4..9db2de9 100644 --- a/frontend/js/palette.js +++ b/frontend/js/palette.js @@ -14,17 +14,26 @@ function getCurrentFile() { return null; } -// ── Query parser: +word = required, -word = exclude, word = required ── +// ── Query parser: +word = required, -word = exclude, word = required, ext:xxx, vault:xxx, tag:xxx ── function parseQuery(raw) { const positive = []; const negative = []; + const filters = { ext: null, vault: null, tag: null }; const parts = (raw || '').split(/\s+/).filter(Boolean); for (const p of parts) { - if (p.startsWith('-') && p.length > 1) negative.push(p.slice(1).toLowerCase()); + const lower = p.toLowerCase(); + if (lower.startsWith('ext:')) { + filters.ext = lower.slice(4).trim().replace(/^\./, '').toLowerCase(); + } else if (lower.startsWith('vault:')) { + filters.vault = lower.slice(6).trim(); + } else if (lower.startsWith('tag:') || (lower.startsWith('#') && p.length > 1)) { + const tag = lower.startsWith('tag:') ? lower.slice(4) : lower.slice(1); + if (tag) filters.tag = tag.trim(); + } else if (p.startsWith('-') && p.length > 1) negative.push(p.slice(1).toLowerCase()); else if (p.startsWith('+')) positive.push(p.slice(1).toLowerCase()); else positive.push(p.toLowerCase()); } - return { positive, negative }; + return { positive, negative, filters }; } // ── DOM / state ── @@ -407,8 +416,8 @@ function createDOM() { _overlay.className = 'command-palette-overlay'; _overlay.tabIndex = -1; _overlay.innerHTML = `
-
Ctrl+Shift+Espace
- +
Ctrl+Shift+Espace
+
`; _input = _overlay.querySelector('.cp-input'); @@ -488,11 +497,14 @@ async function searchFiles(rawQ) { return; } - const { positive, negative } = parseQuery(rawQ); + const { positive, negative, filters } = parseQuery(rawQ); try { const q = positive.join(' '); - const d = await api(`/api/suggest?q=${encodeURIComponent(q)}&vault=all`); + let vaultFilter = 'all'; + if (filters.vault) vaultFilter = filters.vault; + + const d = await api(`/api/suggest?q=${encodeURIComponent(q)}&vault=${encodeURIComponent(vaultFilter)}`); let sug = d.suggestions || []; // Client-side negative filter @@ -506,6 +518,23 @@ async function searchFiles(rawQ) { }); } + // Filter by extension if specified + if (filters.ext) { + sug = sug.filter(s => { + const name = s.path.split('/').pop() || ''; + const ext = name.includes('.') ? name.split('.').pop().toLowerCase() : ''; + return ext === filters.ext; + }); + } + + // Filter by tag if specified + if (filters.tag) { + sug = sug.filter(s => { + const tags = s.tags || []; + return tags.some(t => t.toLowerCase() === filters.tag.toLowerCase()); + }); + } + if (sug.length === 0) { _items = [{ type:'_browse', label:'📂 Parcourir les répertoires...', sublabel:'Aucun résultat — naviguer manuellement', act:()=>startBrowse('open-file') }]; } else { diff --git a/package.json b/package.json index 9cd3929..e1f4121 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "obsigate", - "version": "2.45.0", + "version": "2.45.1", "description": "**Porte d'entrée web ultra-léger pour vos vaults Obsidian** — Accédez, naviguez et recherchez dans toutes vos notes Obsidian depuis n'importe quel appareil via une interface web moderne et responsive.", "main": "patch.js", "directories": {