Skip to content

Éditeur de tableau de bord — filtres, insertion, disposition libre

Spécification technique pour Heriade Rapport. Décrit le mode édition d'un TDB : définir titre et filtres, insérer des objets de la bibliothèque (KPI, Pastilles, Graphiques, Vues), ajouter des éléments de mise en forme, et disposer/dimensionner librement chaque élément sur la page.

S'appuie sur docs/spec-bibliotheque-widgets-restitution.md (modèle BlocRestitution, mécanisme d'insertion) et docs/spec-composants-dataviz.md (composants visuels).

1. Objectif

Permettre à un utilisateur Modeleur de construire un TDB de A à Z sans développeur :

  1. Définir un titre et des filtres globaux au TDB (établissement, période, phase).
  2. Insérer des objets préparés en amont dans les bibliothèques (KPI, Pastilles, Graphiques, Vues).
  3. Ajouter des éléments de mise en forme purement visuels (trame, bordure, séparateur, zone de texte).
  4. Positionner et dimensionner chaque élément librement par glisser-déposer et poignées de redimensionnement.

2. Modèle de données étendu

TableauDeBord (extension du modèle existant)

ts
interface TableauDeBord {
  id: string
  titre: string
  filtres: {
    establishments?: string[]      // vide = tous, cf. mécanisme de restriction de filtre existant
    periode?: { annee: number, mois?: number }
    phase?: string                  // ex: 'reel', 'budget'
  }
  blocs: BlocRestitution[]
  elementsDecoration: ElementDecoration[]
}

BlocRestitution (position formalisée)

ts
interface BlocRestitution {
  id: string
  type: 'kpi' | 'pastille' | 'graphique' | 'vue'
  definitionId: string
  position: {
    x: number, y: number             // coordonnées en unités de grille (cf. section 5)
    largeur: number, hauteur: number  // dimensions en unités de grille
  }
  zIndex: number                     // ordre d'empilement, pour gérer les chevauchements avec les décorations
}

ElementDecoration (nouveau)

ts
interface ElementDecoration {
  id: string
  type: 'trame' | 'bordure' | 'separateur' | 'zone_texte'
  position: { x, y, largeur, hauteur }
  zIndex: number
  style?: {
    couleur?: string                 // référence une variable --primary-* ou une couleur sémantique, jamais une valeur libre
    epaisseur?: number                // pour bordure/séparateur
  }
  contenu?: string                    // texte libre, uniquement pour type 'zone_texte'
}

Un élément de décoration n'a aucune donnée métier — il ne référence aucune définition de bibliothèque, contrairement à un BlocRestitution.

3. Filtres du TDB — portée et articulation avec les blocs

Les filtres définis au niveau du TDB (établissement, période, phase) s'appliquent au moment du rendu, par-dessus les filtres propres à chaque définition (KPI, Pastille, Graphique, Vue) — ils ne modifient jamais la définition elle-même, seulement le contexte d'affichage sur ce TDB précis.

  • Si un bloc a déjà un filtre fixe dans sa définition (ex. une Pastille "Marge brute établissement A" avec établissement figé), le filtre du TDB ne doit pas pouvoir l'élargir en dehors de ce périmètre — seulement le restreindre davantage si le filtre TDB est plus étroit.
  • Ce comportement réutilise le mécanisme déjà en place pour la restriction de filtre par établissement (liste blanche + défaut), plutôt que d'inventer une nouvelle logique de priorité filtre TDB vs filtre bloc.
  • Si aucun filtre TDB n'est défini (valeurs vides), chaque bloc affiche son propre périmètre par défaut tel que configuré dans sa définition.

4. Panneau d'insertion

Reprend le mécanisme déjà spécifié (spec-bibliotheque-widgets-restitution.md, section 5), avec une entrée supplémentaire pour les éléments de mise en forme :

  • Insérer un KPI → sélection dans la bibliothèque KPI
  • Insérer une pastille → sélection dans la bibliothèque Pastilles
  • Insérer un graphique → sélection dans la bibliothèque Graphiques
  • Insérer une vue → sélection parmi les Vues existantes
  • Ajouter un élément de mise en forme (nouveau) → choix direct du type (trame, bordure, séparateur, zone de texte), sans passer par une bibliothèque puisque ces éléments n'ont pas de définition réutilisable — ils sont propres à ce TDB.

Chaque élément inséré apparaît sur le canevas à une position par défaut (ex. sous le dernier élément existant), prêt à être déplacé.

5. Système de disposition — grille et unités

Pour garantir un alignement cohérent entre les éléments (objectif de cohérence visuelle posé plus tôt), le canevas repose sur une grille invisible plutôt que sur un positionnement en pixels libres :

  • Le TDB est divisé en colonnes fixes (proposition : 12 colonnes, comme la plupart des systèmes de grille web), hauteur de ligne fixe (ex. 40px par unité).
  • position.x, position.largeur sont exprimés en nombre de colonnes ; position.y, position.hauteur en nombre de lignes.
  • Lors du déplacement ou redimensionnement, l'élément s'aimante à la grille (snap), évitant les décalages de quelques pixels qui cassent l'alignement visuel entre plusieurs blocs.

6. Interaction — sélection, déplacement, redimensionnement

  • Sélection : clic sur un élément → affichage d'un cadre de sélection avec poignées aux 4 coins et au milieu de chaque côté (redimensionnement), plus une barre d'actions contextuelle (dupliquer, supprimer, avancer/reculer dans l'empilement).
  • Déplacement : cliquer-glisser le corps de l'élément (pas les poignées) → déplacement libre sur la grille, aimanté aux colonnes/lignes.
  • Redimensionnement : cliquer-glisser une poignée → ajuste largeur/hauteur (poignées de coin) ou seulement l'une des deux dimensions (poignées de côté), toujours aimanté à la grille.
  • Empilement : les éléments de décoration (trame, bordure) doivent pouvoir passer derrière un bloc de données (zIndex inférieur) pour servir de fond visuel sans masquer le contenu.
  • Désélection : clic en dehors de tout élément, ou touche Échap.

7. Barre d'outils du TDB (hors canevas)

  • Champ Titre du TDB, éditable en place (pas de modale séparée).
  • Bouton Filtres ouvrant un panneau avec établissement (TreePicker existant), période, phase.
  • Bouton Insérer (section 4).
  • Bouton Aperçu pour basculer entre mode édition (grille visible, éléments sélectionnables) et mode consultation (rendu final, tel que verrait un Lecteur).

8. Cohérence avec le design system

  • Les couleurs disponibles pour ElementDecoration.style.couleur sont limitées à la palette de référence (--primary-25 à --primary-900) et aux couleurs sémantiques déjà en place (favorable/défavorable/alerte) — pas de sélecteur de couleur libre, pour éviter la dérive visuelle d'un TDB à l'autre déjà identifiée comme un risque sur les Vues.
  • Les composants insérés (HGauge, HSparkline, HWaterfall, tableau financier) conservent leur apparence telle que définie dans docs/spec-composants-dataviz.md, quel que soit le TDB où ils sont insérés — le TDB ne doit jamais permettre de recolorer ou restyler un bloc individuellement, seulement de le positionner.

9. Niveau de droits

Édition de TDB (tout ce que décrit ce document) : Modeleur, cohérent avec docs/spec-reorganisation-bandeau.md. Consultation d'un TDB déjà construit : Lecteur.

10. Phasage suggéré

  1. Étape 1 : titre + filtres du TDB, sans encore de disposition libre (blocs empilés verticalement dans l'ordre d'insertion, comme aujourd'hui probablement).
  2. Étape 2 : grille de positionnement + déplacement par glisser-déposer (sans redimensionnement), sur les blocs existants (KPI, Pastille) uniquement.
  3. Étape 3 : redimensionnement par poignées, extension aux Graphiques et Vues.
  4. Étape 4 : éléments de mise en forme (trame, bordure, séparateur, zone de texte).
  5. Étape 5 : mode aperçu (bascule édition/consultation).

11. Point de vigilance

Le risque principal est la sur-ingénierie d'un éditeur visuel complet (façon PowerPoint) alors que le besoin réel est probablement plus modeste : une disposition en grille simple couvre la grande majorité des usages de dashboard financier. Avant d'attaquer les étapes 3-4 (redimensionnement fin, décorations), vérifier avec un ou deux TDB réels existants (Serenis) si le besoin de liberté totale de mise en page est avéré, ou si une disposition pré-calibrée (lignes de blocs de tailles standard) suffirait avec beaucoup moins d'effort de développement.