Files
ObsiGate/docs/features/split-view.md
T
bruno ce23ab38f7
CI / lint (push) Successful in 57s
CI / security (push) Successful in 40s
CI / test (push) Successful in 1m13s
CI / build (push) Successful in 34s
CI / e2e (push) Successful in 10m33s
docs: restructurer le suivi et unifier la methode de livraison
- ROADMAP: ne garde que le travail a venir + index compact du complete (995 -> ~155 lignes); detail deplace vers docs/features/ et docs/archive/

- docs/features/: fiches detaillees #74, #75, #76, #77, #78, #79

- docs/archive/COMPLETED_v1-v2.md: detail des items courts livres

- CHANGELOG: alignement sur les tags (2.0.0 date, 2.2.0/2.2.1 ajoutes, Unreleased = travail #79 post-2.2.1)

- AGENTS.md + docs/DELIVERY_WORKFLOW.md: methode de livraison unique (Definition of Done) referencee par ROADMAP, CONTRIBUTING, ISSUES_TODOLIST
2026-09-11 14:07:56 -04:00

7.2 KiB

#75 — Éditeur multi-panneaux (Split View)

Statut : ✅ Terminé — 100% implémenté + 37 tests E2E (16 split-view.spec.js + 21 split-view-matrix.spec.js, 2026-09-08) Effort : 5-7 jours (réalisé) | Impact : 🟡 Références : Roadmap · Changelog — 2.1.0

  • Fichiers clés : frontend/js/pane-manager.js (1082 loc), frontend/js/viewer.js (modifié), frontend/js/ui.js (modifié), frontend/js/dashboard.js (modifié), frontend/js/palette.js (modifié), frontend/style.css (modifié), tests/test_pane_manager.py (22 tests)

  • Description : Système de panneaux divisés permettant d'afficher plusieurs documents côte à côte ou superposés, à la manière d'un éditeur de code (VS Code). Drag & drop des onglets entre les panneaux, drag-to-split, menu contextuel, raccourcis clavier, palette de commandes.

  • Architecture :

    • PaneManager — orchestre la grille de panneaux (1-4), crée/détruit les instances PaneTabManager
    • PaneTabManager (factory createPaneTabManager(paneId)) — chaque panneau a son instance indépendante avec ses propres onglets, cache, état
    • Singleton TabManager — délègue automatiquement vers le PaneTabManager actif quand en mode split ; gère les onglets en single-pane
    • Migration automatique — les onglets migrent singleton→PaneTabManager au premier split, et inversement au collapse
    • getContentArea() — helper global dans viewer.js, priorise window._activePaneContentArea (set par PaneTabManager)
  • Implémenté :

A. PaneManager — Gestionnaire de panneaux

  • A1. Module PaneManager + factory createPaneTabManager — état indépendant par panneau
  • A2. Création dynamique du DOM — .pane-grid avec .pane-container, IDs suffixés -N
  • A3. Redimensionnement — drag handles, double-clic reset 50/50, contrainte 20-80%, localStorage
  • A4. Indépendance des panneaux — chaque panneau a ses propres onglets, scroll, cache, source view

B. Refactoring du TabManager

  • B1. Découplage du DOM — init(tabBar, tabList, contentArea) par paramètre
  • B2. Factory createPaneTabManager(paneId) — instances indépendantes
  • B3. Compatibilité ascendante — pane 0 réutilise les IDs existants, panes 1+ suffixés -N
  • B4. Synchronisation state global — setActivePane() met à jour currentVault/currentPath

C. Actions de division

  • C1. Menu contextuel — « Diviser à droite », « Diviser en bas », « Fermer le panneau »
  • C1b. Sous-menu « Déplacer vers... » — flyout hover listant les autres panneaux
  • C2. Raccourcis clavier — Ctrl+Alt+\ (split R), Ctrl+Alt+Shift+\ (split D), Ctrl+Alt+W (close pane), Ctrl+Shift+Alt+W (close others), Ctrl+Alt+←/→/↑/↓ (navigate)
  • C3. Boutons dans la barre d'onglets — ⊞→ et ⊞↓ visibles au survol
  • C4. Fermeture panneau — retour single-pane si dernier, focus voisin, onglets perdus (pas déplacés)

D. Drag & Drop

  • D1. Drag cross-pane — text/plain JSON {paneId, tabId, index}, indicateurs visuels
  • D2. Drag depuis l'arborescence — format tree:{vault,path}, drop sur panneau spécifique
  • D3. Drag-to-split — zone droite 28% → split right, zone basse 28% → split down, overlay bleu

E. Rendu et performance

  • E1. Rendu indépendant — window._activePaneContentArea override pour renderFile()
  • E2. Cache de contenu — chaque PaneTabManager a son propre _tabCache, pas de refetch
  • E3. Rendu paresseux — contenu masqué via display:none sur panneaux inactifs
  • E4. Verrouillage éditeur — même fichier déjà ouvert ailleurs → focus le panneau existant

F. CSS & Design

  • F1-F5. Grid layout, resize handles avec hover accent, barre onglets par panneau, variables CSS (dark/light), responsive <768px

G. Persistance et restauration

  • G1. localStorage obsigate-panes — layout, panes[{id, width, activeTab, tabs[]}]
  • G2. Restauration au chargement — reconstruction grille + onglets + activation
  • G3. Reset dans la palette de commandes — « 🔄 Réinitialiser les panneaux »

H. Compatibilité

  • H1. Palette de commandes — « Diviser à droite », « Diviser en bas », « Fermer le panneau », « Panneau suivant/précédent » (catégorie Panneaux)
  • H2. Pop-out inchangé
  • H3. Mermaid scoped au content-area
  • H4. AI Editor en modale (inchangé)
  • H5. Ctrl+S par panneau

I. Tests

  • I1. 22 tests statiques (structure, CSS, brace balance, régression backend)
  • I4. 307 tests de régression passent
  • I2. Tests d'intégration frontend (JSDOM) — tests/frontend/pane-manager.test.mjs (9 tests)
  • I3. Tests E2E Playwright (#58) — 2026-09 : split-view.spec.js (16) + split-view-matrix.spec.js (21) = 37 tests verts en local + CI

Reste à faire

  • C1b. Sous-menu « Déplacer vers... » dans le menu contextuel des onglets
  • D2. Drag & drop depuis l'arborescence vers un panneau spécifique
  • E3. Rendu paresseux (mémoire) — contenu masqué via display:none sur panneaux inactifs
  • E4. Verrouillage éditeur multi-panneau — même fichier ouvert dans 2 panneaux → focus le panneau existant
  • G3. Bouton reset dans la palette de commandes (🔄 Réinitialiser les panneaux)
  • I2. Tests d'intégration frontend (JSDOM) — tests/frontend/pane-manager.test.mjs (9 tests, 100% verts)
  • I3. Tests E2E Playwright — matrice complète ouverture/fermeture couverte (voir split-view-matrix.spec.js)

Matrice de couverture ouverture/fermeture (validée 2026-09-08, 37/37 verts)

Cas Surface testée Spec
Ouverture fichier → onglet clic arbre, double-clic preview vs persistant split-view
Split droit raccourci Ctrl+Alt+\ · bouton ⊞→ · menu contextuel · palette · drag-to-split bord droit les 5
Split bas raccourci Ctrl+Alt+Shift+\ · bouton ⊞↓ · menu contextuel · drag-to-split bord bas les 4
Déplacer onglet drag cross-pane · flyout « Déplacer vers... » · drag depuis arbre vers panneau les 3
Navigation Ctrl+Alt+←/→ (horizontal) · Ctrl+Alt+↑/↓ (vertical) · palette suivant/précédent les 3
Fermeture onglet bouton X · double-clic · clic molette · Ctrl+W (single) les 4
Fermeture menu ctx Fermer · Fermer les autres · Fermer à droite · Fermer tout → dashboard les 4
Fermeture panneau Ctrl+Alt+W (clavier) · menu « Fermer le panneau » · Ctrl+Shift+Alt+W (autres) · auto-collapse panneau vidé (C4) · fermeture pane 0 → voisin survit · onglets du panneau fermé perdus (documenté) les 5
Persistance layout restauré au reload · reset palette vide localStorage les 2
Edge plafond 4 panneaux (PANE_MAX) · pas de doublon à la réouverture (E4) les 2

Non couvert par E2E (hors périmètre ouverture/fermeture) : poignée de redimensionnement drag/dblclick-reset (A3) — logique vérifiée par les 22 tests statiques + JSDOM.