Construire un dashboard modulaire par cartes
Ce guide montre comment assembler un tableau de bord d'administration qui agrège plusieurs domaines (métriques, comptes, indexation, etc.) sans que le dashboard connaisse les données internes de chaque module. Le principe : le dashboard compose, chaque module rend sa propre carte.
Prérequis : un back-office existant, un module de templating capable d'inclure le rendu d'un sous-contrôleur (fragments / sous-requêtes), un mécanisme de contrôle d'accès par rôle.
1. Exposer une action card par module
Sur le contrôleur d'administration de chaque module, ajoutez une action dédiée (par exemple card()), protégée par le rôle d'administration.
Cette action rend un partial dédié au module, par convention :
templates/admin/dashboard/_<module>.html.twig
La carte contient uniquement une synthèse (les quelques chiffres essentiels du module) et les actions clés. La logique de requête reste dans le contrôleur du module.
2. Composer le dashboard par sous-requêtes
Le template du tableau de bord ne fait qu'appeler le rendu de chaque carte via une sous-requête. Il n'interroge jamais un repository de domaine directement.
{{ render(controller('App\\Controller\\Admin\\MetricsController::card')) }} {{ render(controller('App\\Controller\\Admin\\AccountsController::card')) }} {{ render(controller('App\\Controller\\Admin\\IndexController::card')) }}
Le dashboard ignore ce que chaque carte contient. Ajouter un module au tableau de bord se réduit alors à une ligne ; le retirer, à supprimer cette ligne.
3. Respecter la convention de carte
Structurez chaque carte de façon homogène (ex. bloc card d'un framework CSS) :
- en-tête : titre du module ;
- corps : chiffres clés ;
- pied : boutons d'action.
Gardez le rendu côté serveur, sans logique métier dans le template.
4. Prévoir la dégradation propre
Une sous-requête qui échoue ne doit pas faire tomber la page entière. Si la donnée d'un module est indisponible (index absent, service amont injoignable…), la carte doit afficher un état dégradé explicite — bannière ou message clair — et laisser les autres cartes intactes.
Traitez ce cas dans l'action card() du module concerné (capture de l'erreur, rendu d'un partial d'état dégradé), pas dans le dashboard.
5. Rendre les cartes accessibles
Chaque carte est une surface d'interface : appliquez le même niveau d'accessibilité que le reste du back-office (contraste, structure de titres, libellés d'actions explicites, navigation clavier).
Aller plus loin : absorber la page dédiée
Quand une carte porte déjà l'essentiel d'un module, la page séparée de ce module peut souvent disparaître : son contenu devient la carte, et son ancienne route redirige vers le dashboard. Un clic en moins pour l'administrateur.
Quand ne pas appliquer ce pattern
- Un seul module : pas besoin de dashboard ni de composition ; la page du module suffit.
- Corrélation transverse : dès qu'une vue nécessite de croiser les données de plusieurs domaines (jointures inter-modules), ce n'est plus une composition de cartes autonomes. Cela relève d'un service de reporting dédié, pas de ce pattern.