Files
ObsiGate/docs/features/xlsx-ui-redesign.md
T
bruno e94af0369b
CI / lint (push) Successful in 2m30s
CI / security (push) Failing after 1m46s
CI / build (push) Canceled after 0s
CI / e2e (push) Canceled after 0s
CI / test (push) Canceled after 1h32m51s
feat: inspecteur droit pour le tableau de bord XLSX #154
2026-09-29 14:56:08 -04:00

9.2 KiB
Raw Blame History

#154 — Refonte UI/UX de la visionneuse & éditeur XLSX (ruban, grille, inspecteur)

Item de roadmap : #154 — Refonte UI/UX tableur Origine : #152 / #153 (visionneuse XLSX fonctionnelle mais peu conviviale) Statut : 🔵 en cours — Lots 1, 2 & 3 livrés le 2026-09-29 Effort estimé : 6-9 jours (Lot 1 ✅ · Lot 2 ✅ · Lot 3 ✅ · Lot 4) Règle de maintenance : la Roadmap porte les cases à cocher (suivi), cette fiche porte l'analyse, l'architecture cible et le plan par lots. Ne pas dupliquer le détail.


1. Objectif

Rendre la vue tableur d'ObsiGate intuitive, moderne et hautement utilisable en s'inspirant des standards du marché (Excel, Google Sheets, Airtable), sans renier les contraintes du dépôt : thème sombre, vanilla JS, zéro framework, zéro build npm (AGENTS.md). La refonte est organique : on améliore la coquille existante (frontend/js/viewer.js::renderXlsxViewer, frontend/style.css), on ne réécrit pas la grille ni le backend.

2. Audit UX — les 3 problèmes majeurs

# Problème Constat Résolution
P1 Aucune hiérarchie ni regroupement des commandes Rangée plate de boutons de poids identique (viewer.js toolbar historique) ; « Tableau de bord » prependé au runtime ; barre de formule réduite à un input. Barre de commandes groupée (Formules · Insertion · Vue · Fichier), bouton Enregistrer primaire, état dirty.
P2 Grille sans affordances : en-têtes = cellules Contraste faible entre th et td, pas de zébrage, pas de survol lisible, cellule active peu marquée. Tokens de grille + en-têtes plus clairs/interactifs, zébrage, survol, cellule active en bordure accent.
P3 États avancés traités comme du contenu Dashboard inline qui pousse la grille, troncature/lecture seule/formules non recalculées sans emplacement dédié, confirm()/prompt() natifs. Couche UI dédiée : bandeaux d'état + inspecteur droit (Lot 3) + dialogues thémés (Lot 2).

3. Architecture cible de l'écran

┌──────────────────────────────────────────────────────────────────────────┐
│ BARRE APP (globale, existante)                                            │
├─────────────┬────────────────────────────────────────────────────────────┤
│             │ A. RUBAN — groupes Formules · Insertion · Vue · Fichier     │
│  EXPLORATEUR│ B. BARRE DE FORMULE — [ A1 ] fx [ … ]                       │
│  DE FICHIERS│ C. BANDEAUX D'ÉTAT — lecture seule · formules non recalculées│
│  (sidebar)  ├──────────────────────────────────────────────┬─────────────┤
│             │ D. GRILLE (en-têtes clairs, zébrage, survol)  │ E. INSPECTEUR│
│             │                                               │ (dashboard + │
│             │                                               │  IA, repliable)│
│             ├───────────────────────────────────────────────┤             │
│             │ F. ONGLETS FEUILLES + « + » · 500/522           │             │
└─────────────┴───────────────────────────────────────────────┴─────────────┘
  • A. Ruban : groupes d'actions avec séparateurs ; actions de style désactivées (styles lus, pas écrits). Bouton Enregistrer en accent, désactivé si rien de dirty.
  • B. Barre de formule : zone nom + champ + badge de session f(x).
  • C. Bandeaux d'état : empilables, non bloquants ; portent lecture seule et « formules non recalculées ».
  • D. Grille : rendue côté serveur (backend/xlsx_reader.py), habillée et câblée par le front.
  • E. Inspecteur : à venir (Lot 3) — Tableau de bord + Assistant IA dans un panneau droit repliable (réutilise PaneManager pour le détachement), au lieu du dashboard inline actuel.
  • F. Onglets feuilles : permanents (même à une seule feuille) + bouton « + ».

4. Plan par lots (incréments livrables)

Lot 1 — Coquille : ruban groupé, onglets permanents, badges d'état ✅ (2026-09-29)

  • A1.1 Barre de commandes groupée (.xlsx-cmdbar, .xlsx-cmd-group, .xlsx-cmd-sep, .xlsx-save-primary), IDs existants conservés (compatibilité tests JSDOM/E2E).
  • A1.2 Onglets de feuilles toujours rendus (non-CSV) + bouton + .xlsx-tab-add → sheet_add (même pipeline putStructure).
  • A1.3 Badges d'état : .xlsx-status-pill lecture seule (.xls/.ods) et formules non recalculées (non-CSV).
  • A1.4 Tokens de grille (--grid-bg, --grid-header-bg, --grid-header-text, --grid-border, --grid-zebra) déclinés dark/light + affordances (en-têtes clairs, zébrage, survol, cellule active solide, cellule dirty prioritaire au survol).

Lot 2 — Dialogues thémés & feedback ✅ (2026-09-29)

  • A2.1 Helpers génériques showConfirm() / showPrompt() (frontend/js/ui.js), promise-based, réutilisant les classes .obsigate-modal-* (fini window.confirm() / window.prompt()).
  • A2.2 La visionneuse XLSX utilise ces dialogues pour les actions de structure (ajouter / renommer / dupliquer / supprimer feuille, insérer / supprimer ligne et colonne) et pour la confirmation de perte (409 xlsx_lossy_content).
  • A2.3 Conflit de sauvegarde (409 conflict) : bandeau non bloquant .xlsx-banner-conflict avec bouton Réessayer — les modifications sont conservées.
  • A2.4 Indicateur dirty sur le bouton Enregistrer et sur l'onglet de la feuille concernée.

Lot 3 — Inspecteur droit ✅ (2026-09-29)

  • A3.1 Le Tableau de bord quitte le flux de la grille pour un panneau droit repliable (.xlsx-inspector) : la grille reste visible à côté (.xlsx-body = .xlsx-main + inspecteur).
  • A3.2 En-tête d'inspecteur : titre, bouton Assistant IA (ouvre le panneau latéral global existant) et bouton de fermeture.
  • A3.3 Responsive : sous 900 px, l'inspecteur passe sous la grille.

Lot 4 — Découpage & finitions (à venir)

  • Extraction de renderXlsxViewer en modules (frontend/js/xlsx/*.js) : toolbar, formula-bar, grid, sheet-tabs, inspector, cell-editor, api.
  • Undo/redo local (pile de commandes), défilement paresseux via IntersectionObserver, accessibilité ARIA (role="grid", roving tabindex).
  • Lien dashboard → grille (clic sur KPI/plage = scroll + sélection), inspecteur redimensionnable, détachement en split via PaneManager.splitRight().

5. Recommandations techniques (contrainte « zéro build »)

Option Data Grid Build Licence Verdict
AG Grid Community npm + bundler MIT ❌ viole « zéro build », réécrit le DOM, casse les tests
Handsontable npm + bundler commerciale ❌ licence non libre
TanStack Table headless (importable esm.sh) MIT ⚠ possible sans build, mais headless → gain limité
Grille maison sur <table> aucun — ✅ recommandé (conserve DOM, CSP, i18n, tests)
  • Performance : ne pas ré-écrire tout le DOM ; réutiliser le pipeline appendWindow ; content-visibility:auto; contain:strict sur les lignes ; garder la pagination serveur (500 × 40 = 20 000 cellules/feuille) plutôt qu'une virtualisation client complexe.
  • CSP : main.py autorise déjà esm.sh — une lib headless reste possible en Lot 4 si un vrai besoin de modèle de colonnes apparaît.

6. Critères d'acceptation (par lot)

  • Lot 1 : une feuille unique affiche son onglet + « + » ; « + » ajoute une feuille via PUT …/xlsx/structure et re-rend ; .xls/.ods montrent le badge « lecture seule » (pas de « + », pas de structure, pas de dashboard) ; un .xlsx montre le badge « formules non recalculées », un .csv non ; les tests JSDOM/E2E existants restent verts + nouveaux tests.
  • Lots suivants : définis à leur ouverture.

7. Historique

Date Événement
2026-09-29 Audit UX (3 problèmes) + architecture cible + plan par lots ; Lot 1 livré (ruban groupé, onglets permanents + « + », badges d'état, tokens de grille)
2026-09-29 Lot 2 livré : dialogues thémés (showConfirm/showPrompt) pour la structure et la confirmation de perte, bandeau de conflit 409 non bloquant avec réessai, indicateur dirty (bouton + onglet)
2026-09-29 Lot 3 livré : le Tableau de bord passe dans un inspecteur droit repliable (grille toujours visible), en-tête d'inspecteur avec entrée Assistant IA et fermeture, responsive < 900 px