Files
ObsiGate/docs/features/xlsx-ui-redesign.md
T
bruno 8da65611cb
CI / lint (push) Successful in 2m31s
CI / security (push) Failing after 1m46s
CI / test (push) Successful in 4m17s
CI / build (push) Successful in 1m40s
CI / e2e (push) Canceled after 42s
feat: dialogues themes et conflits non bloquants pour la visionneuse XLSX #154
2026-09-29 14:50:47 -04:00

8.7 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 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 (à venir)

  • Panneau repliable hébergeant Tableau de bord et Assistant IA en onglets ; la grille reste visible. Lien dashboard → grille (clic sur KPI/plage = scroll + sélection).
  • Détachement en split via PaneManager.splitRight().

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).

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)