Files
ObsiGate/docs/features/navigation-tab-158.md
T
bruno 2add24a9c1
CI / lint (push) Canceled after 0s
CI / test (push) Canceled after 0s
CI / security (push) Canceled after 0s
CI / build (push) Canceled after 0s
CI / e2e (push) Canceled after 0s
feat: onglet Accueil, menus contextuels de navigation et racine vault #158
- clic sur le titre: la page d'accueil s'ouvre dans un onglet Accueil (icone Maison) epingle en tete de barre, reactivable d'un clic (onglet propre au panneau actif en split)
- page de navigation: menus contextuels des repertoires et des fichiers identiques a ceux de la sidebar, clic sur la racine d'un vault qui ouvre la vue, icone dossier a la couleur de l'arbre de navigation
- BUG-101: bloc « Keyboard shortcuts for tabs » duplique dans ui.js (un seul Ctrl+W fermait deux onglets)
- BUG-102: le menu contextuel se refermait 10 ms apres son ouverture (scroll de reflow des icones lucide)
2026-10-02 14:05:01 -04:00

4.4 KiB

#158 — Navigation : vue répertoire en onglet, filtres & tris, retour Home complet

Statut : livré le 2026-10-02 · ID : #158 (correctif associé : BUG-100) Fichiers : frontend/js/vaulthome.js, frontend/js/ui.js, frontend/js/sidebar.js, frontend/js/navfacets.js (nouveau), frontend/js/viewer.js, frontend/js/legacy.js, backend/services/vaults.py, backend/schemas.py, frontend/style.css, frontend/locales/{fr,en}.json

Problème

La vue « chemin + Récents + fichiers du répertoire » (vault home) ne s'affichait qu'en mode focus vault, disparaissait dès qu'un fichier était ouvert (aucun onglet), ne listait pas les sous-répertoires, n'avait ni filtre ni tri, et le clic sur le titre ne rendait pas la vraie page d'accueil.

Conception

Un onglet de navigation par vault. TabManager.openNav(vault, dir) (frontend/js/ui.js) crée/rétarget l'onglet nav::<vault> (icône dossier) ; TabManager.activate() branche sur cache.nav et rend showVaultHome(vault, dir) au lieu de fetcher un fichier. Les onglets de fichiers ne sont jamais fermés. Le dashboard appelle TabManager.deactivate() : aucun onglet ne reste « actif », donc un clic suivant ré-éffectue réellement l'onglet (avant : early-return et vue figée).

Points d'entrée des clics (frontend/js/sidebar.js) : clic répertoire dans l'arbre (2 sites, mode focus et mode All), clic sur la racine d'un vault (2 sites, expansion + navigation), changement de contexte vault (sélecteur), facettes/filtres et fil d'Ariane de la vue (vaulthome.js route tout par openNav, plus aucune délégation sur l'arbre).

Menus contextuels : les répertoires et les fichiers de la vue appellent le même ContextMenuManager.show() que la sidebar, avec stopPropagation() — le handler global de ContextMenuManager referme le menu sur tout clic droit hors .tree-item.

Onglet Accueil (ui.js::openHome + pane-manager.js::openHome) : le clic sur le titre crée (ou remonte en position 0) l'onglet home — icône Maison, libellé i18n common.home — et l'active ; activate() rend la page d'accueil via showWelcome() et deactivate() conserve l'onglet Accueil actif (il est la page d'accueil). En mode split, l'onglet vit dans le panneau actif (délégation getActiveTabManager(), libellé transmis par l'appelant pour ne pas d'importer t dans pane-manager.js, qui déclare déjà des variables locales t).

Contenu de la vue (vaulthome.js) : fil d'Ariane · barre Pertinence / Date + Sauver · panneau de facettes · Répertoires cliquables (GET /api/browse) · Récents (racine) · fichiers (GET /api/vault/{v}/files?recursive=false). Les facettes réutilisent les classes de la page de recherche (search-facets, search-sort, search-save-btn) — même visuel, même repli obsigate_facets_collapsed, filtrage local (pas de nouvelle requête).

Facettes (frontend/js/navfacets.js, pur, sans DOM) : buildNavFacets, filterNavFiles, sortNavFiles. Le listing embarque les tags indexés : GET /api/vault/{v}/files renvoie tags (_indexed_tags() dans backend/services/vaults.py, lookup vault::path dans l'index inversé, [] si non indexé).

Décisions / limites connues

  • Un seul onglet de navigation par vault : cliquer un autre répertoire re-cible le même onglet (pas d'empilement d'onglets). En mode split, la vue s'affiche dans la zone principale.
  • « Pertinence » = tri alphabétique (ponytail: commenté) : un listing de répertoire n'a aucun signal de pertinence tant que la vue n'a pas sa propre requête — voir navfacets.js::sortNavFiles.
  • Facettes calculées sur la liste courante (répertoire non récursif, 200 fichiers max) : les sous-répertoires non listés n'apportent aucune compte.

Tests

  • tests/test_nav_files.py (3) : tags exposés + survivent au response_model, tags en sous-répertoire, miss d'index → [].
  • tests/frontend/navfacets.test.mjs (10) : comptages, filtres tag/ext (insensible au point), combinaison ET, tris, non-mutation.
  • tests/frontend/unit.test.mjs : navfacets.js ajouté à la liste des modules purs.
  • tests/e2e/nav-tab.spec.js (4) : racine vault → page de navigation, icône + menus contextuels identiques à la sidebar, onglet Accueil en tête de barre (avec #quick-help).
  • Vérification manuelle Playwright (jetable) : 22/22 puis 16/16 checks sur les lots A1-A3 et A4-A6.