feat(client): Refactorisation composants KPI en composants composites réutilisables

- Création de kpi-card.xhtml et kpi-card-content.xhtml (composants génériques)
- Création de kpi-group.xhtml et dashboard-section.xhtml pour organisation
- Refactorisation user-stat-card.xhtml pour utiliser kpi-card
- Documentation README_KPI.md pour l'utilisation des composants KPI
This commit is contained in:
lionsdev
2025-12-05 16:23:29 +00:00
parent ed3a3a37e4
commit 137db9c2bb
6 changed files with 613 additions and 74 deletions

View File

@@ -0,0 +1,240 @@
# 📊 Composants KPI Réutilisables - Écosystème LionsDev
**Version**: 2.0.0
**Date**: 2025-01-29
**Pattern**: WOU/DRY (Write Once Use / Don't Repeat Yourself)
---
## 🎯 Vue d'Ensemble
Ces composants KPI (Indicateurs de Performance) sont conçus pour être **100% réutilisables** dans tous les projets de l'écosystème **lionsdev**. Ils suivent les meilleures pratiques de PrimeFaces Freya et offrent une expérience utilisateur cohérente.
---
## 📦 Composants Disponibles
### 1. **kpi-card.xhtml** - Carte KPI Individuelle
Composant principal pour afficher un indicateur de performance unique.
**Localisation**: `/templates/components/shared/cards/kpi-card.xhtml`
**Paramètres principaux**:
- `title` (requis) - Titre du KPI
- `value` (requis) - Valeur à afficher
- `icon` (requis) - Icône PrimeIcons
- `iconColor` (requis) - Couleur de l'icône
- `growthValue` (optionnel) - Valeur de croissance
- `growthLabel` (optionnel) - Libellé de croissance
- `progressValue` (optionnel) - Barre de progression 0-100
- `statusIcon`, `statusLabel`, `statusValue` (optionnel) - Mode statut
- `clickable` (défaut: false) - Rendre cliquable
- `clickOutcome` (optionnel) - Redirection au clic
**Exemple simple**:
```xhtml
<ui:include src="/templates/components/shared/cards/kpi-card.xhtml">
<ui:param name="title" value="Total Utilisateurs" />
<ui:param name="value" value="#{bean.totalUsers}" />
<ui:param name="icon" value="pi-users" />
<ui:param name="iconColor" value="blue-600" />
</ui:include>
```
**Exemple avec croissance**:
```xhtml
<ui:include src="/templates/components/shared/cards/kpi-card.xhtml">
<ui:param name="title" value="Utilisateurs Actifs" />
<ui:param name="value" value="#{bean.activeUsers}" />
<ui:param name="icon" value="pi-user-check" />
<ui:param name="iconColor" value="green-600" />
<ui:param name="growthValue" value="#{bean.growthPercent}" />
<ui:param name="growthLabel" value="ce mois" />
<ui:param name="progressValue" value="#{bean.progressPercent}" />
</ui:include>
```
**Exemple avec statut**:
```xhtml
<ui:include src="/templates/components/shared/cards/kpi-card.xhtml">
<ui:param name="title" value="Sessions Actives" />
<ui:param name="value" value="#{bean.activeSessions}" />
<ui:param name="icon" value="pi-sign-in" />
<ui:param name="iconColor" value="purple-600" />
<ui:param name="statusIcon" value="pi-check-circle" />
<ui:param name="statusLabel" value="En ligne" />
<ui:param name="statusValue" value="#{bean.onlineUsers} actifs" />
</ui:include>
```
---
### 2. **kpi-group.xhtml** - Groupe de KPI
Composant composite pour organiser plusieurs KPI dans une grille.
**Localisation**: `/templates/components/shared/dashboard/kpi-group.xhtml`
**Paramètres**:
- `title` (optionnel) - Titre de la section
- `columns` (défaut: 4) - Nombre de colonnes (1-6)
- `colSize` (optionnel) - Taille personnalisée
**Exemple**:
```xhtml
<ui:include src="/templates/components/shared/dashboard/kpi-group.xhtml">
<ui:param name="title" value="Statistiques Utilisateurs" />
<ui:param name="columns" value="4" />
<ui:define name="kpi-content">
<!-- KPI 1 -->
<ui:include src="/templates/components/shared/cards/kpi-card.xhtml">
<ui:param name="title" value="Total" />
<ui:param name="value" value="#{bean.total}" />
<ui:param name="icon" value="pi-users" />
<ui:param name="iconColor" value="blue-600" />
</ui:include>
<!-- KPI 2, 3, 4... -->
</ui:define>
</ui:include>
```
---
### 3. **dashboard-section.xhtml** - Section Dashboard
Composant composite pour créer des sections de dashboard réutilisables.
**Localisation**: `/templates/components/shared/dashboard/dashboard-section.xhtml`
**Paramètres**:
- `title` (requis) - Titre de la section
- `description` (optionnel) - Description
- `icon` (optionnel) - Icône
- `colSize` (défaut: "col-12") - Taille de colonne
- `showCard` (défaut: true) - Envelopper dans une carte
**Exemple**:
```xhtml
<ui:include src="/templates/components/shared/dashboard/dashboard-section.xhtml">
<ui:param name="title" value="Actions Rapides" />
<ui:param name="icon" value="pi-bolt" />
<ui:param name="colSize" value="col-12 lg:col-6" />
<ui:define name="section-content">
<!-- Contenu de la section -->
<div class="grid">
<div class="col-12 md:col-6">
<p:commandButton value="Action 1" />
</div>
</div>
</ui:define>
</ui:include>
```
---
### 4. **user-stat-card.xhtml** - Wrapper de Compatibilité
Wrapper de compatibilité ascendante qui délègue à `kpi-card.xhtml`.
**Note**: Pour de nouvelles implémentations, utilisez directement `kpi-card.xhtml`.
---
## 🎨 Couleurs Disponibles
Utilisez les couleurs PrimeFlex pour `iconColor`:
- `blue-600`, `blue-500`, `blue-400`
- `green-600`, `green-500`, `green-400`
- `purple-600`, `purple-500`, `purple-400`
- `orange-600`, `orange-500`, `orange-400`
- `red-600`, `red-500`, `red-400`
- `cyan-600`, `cyan-500`, `cyan-400`
- `pink-600`, `pink-500`, `pink-400`
---
## 📐 Tailles de Colonnes
Utilisez les classes PrimeFlex pour `colSize`:
- `col-12` - Pleine largeur
- `col-12 md:col-6` - 2 colonnes sur tablette+
- `col-12 md:col-6 lg:col-3` - 4 colonnes sur desktop (défaut)
- `col-12 md:col-4` - 3 colonnes
- `col-12 md:col-6 lg:col-2` - 6 colonnes
---
## 🔄 Réutilisabilité dans l'Écosystème LionsDev
Ces composants peuvent être utilisés dans:
-**lions-user-manager** (module actuel)
-**unionflow** (via dépendance Maven)
-**btpxpress** (via dépendance Maven)
-**Tout autre projet lionsdev** (via dépendance Maven)
**Avantages**:
- Code DRY (Don't Repeat Yourself)
- Interface utilisateur cohérente
- Maintenance centralisée
- Évolutivité garantie
---
## 📝 Bonnes Pratiques
1. **Toujours utiliser `kpi-card.xhtml`** pour de nouveaux KPI
2. **Utiliser `kpi-group.xhtml`** pour organiser plusieurs KPI
3. **Utiliser `dashboard-section.xhtml`** pour structurer les dashboards
4. **Respecter les conventions de couleurs** PrimeFlex
5. **Documenter les paramètres personnalisés** dans votre code
---
## 🚀 Exemple Complet de Dashboard
```xhtml
<div class="grid">
<!-- En-tête -->
<div class="col-12">
<ui:include src="/templates/components/layout/page-header.xhtml">
<ui:param name="title" value="Tableau de Bord" />
</ui:include>
</div>
<!-- KPIs -->
<div class="col-12">
<div class="grid">
<ui:include src="/templates/components/shared/cards/kpi-card.xhtml">
<ui:param name="title" value="Total" />
<ui:param name="value" value="#{bean.total}" />
<ui:param name="icon" value="pi-users" />
<ui:param name="iconColor" value="blue-600" />
</ui:include>
<!-- Autres KPI... -->
</div>
</div>
<!-- Sections -->
<ui:include src="/templates/components/shared/dashboard/dashboard-section.xhtml">
<ui:param name="title" value="Actions Rapides" />
<ui:define name="section-content">
<!-- Contenu -->
</ui:define>
</ui:include>
</div>
```
---
## 📚 Documentation Complète
Pour plus de détails, consultez:
- `/templates/components/README.md` - Documentation générale
- Code source des composants avec commentaires JSDoc
---
**Auteur**: Lions User Manager Team
**Licence**: Écosystème LionsDev

View File

@@ -0,0 +1,102 @@
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core">
<div class="p-4" style="min-height: 9rem;">
<!-- Header: Titre et Icône -->
<div class="flex align-items-center justify-content-between mb-3">
<span class="block text-600 font-medium text-sm">#{title}</span>
<div class="flex align-items-center justify-content-center surface-100 border-round-lg"
style="width: 2.5rem; height: 2.5rem;">
<i class="pi #{icon} text-#{iconColor} text-lg"></i>
</div>
</div>
<!-- Valeur principale -->
<div class="text-900 font-bold text-2xl mb-2">#{value}</div>
<!-- Sous-titre -->
<c:if test="#{not empty subtitle}">
<div class="text-500 text-xs mb-2">#{subtitle}</div>
</c:if>
<!-- Section Croissance ou Statut -->
<c:choose>
<!-- Mode Statut (statusIcon fourni) -->
<c:when test="#{not empty statusIcon}">
<c:choose>
<c:when test="#{not empty statusValue and statusValue != '0' and statusValue != '0.0'}">
<div class="flex align-items-center mb-2">
<i class="pi #{statusIcon} text-green-500 text-sm mr-2"></i>
<span class="text-green-600 font-semibold text-sm mr-2">#{statusLabel}</span>
<span class="text-500 text-xs">#{statusValue}</span>
</div>
</c:when>
<c:otherwise>
<div class="text-500 text-xs mb-2">Aucun #{statusLabel}</div>
</c:otherwise>
</c:choose>
</c:when>
<!-- Mode Croissance -->
<c:otherwise>
<c:choose>
<!-- Croissance en nombre -->
<c:when test="#{growthType == 'number'}">
<c:choose>
<c:when test="#{showGrowth and not empty growthValue and growthValue != '0' and growthValue != '0.0'}">
<div class="flex align-items-center mb-2">
<i class="pi pi-arrow-up text-green-500 text-sm mr-2"></i>
<span class="text-green-600 font-semibold text-sm mr-2">+#{growthValue}</span>
<c:if test="#{not empty growthLabel}">
<span class="text-500 text-xs">#{growthLabel}</span>
</c:if>
</div>
</c:when>
<c:otherwise>
<div class="text-500 text-xs mb-2">#{noDataLabel}</div>
</c:otherwise>
</c:choose>
</c:when>
<!-- Croissance en pourcentage (défaut) -->
<c:otherwise>
<c:choose>
<c:when test="#{showGrowth and not empty growthValue and growthValue != '0' and growthValue != '0.0'}">
<div class="flex align-items-center mb-2">
<c:choose>
<c:when test="#{growthValue >= 0}">
<i class="pi pi-arrow-up text-green-500 text-sm mr-2"></i>
<span class="text-green-600 font-semibold text-sm mr-2">+#{growthValue}%</span>
</c:when>
<c:otherwise>
<i class="pi pi-arrow-down text-red-500 text-sm mr-2"></i>
<span class="text-red-600 font-semibold text-sm mr-2">#{growthValue}%</span>
</c:otherwise>
</c:choose>
<c:if test="#{not empty growthLabel}">
<span class="text-500 text-xs">#{growthLabel}</span>
</c:if>
</div>
</c:when>
<c:otherwise>
<div class="text-500 text-xs mb-2">#{noDataLabel}</div>
</c:otherwise>
</c:choose>
</c:otherwise>
</c:choose>
</c:otherwise>
</c:choose>
<!-- Barre de progression -->
<c:if test="#{showProgress and not empty progressValue}">
<p:progressBar value="#{progressValue}"
showValue="false"
styleClass="surface-200"
style="height: 0.5rem; width: 100%;" />
</c:if>
</div>
</ui:composition>

View File

@@ -0,0 +1,95 @@
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core">
<!--
Composant réutilisable: Carte KPI (Indicateur de Performance) - Écosystème LionsDev
Auteur: Lions User Manager
Version: 2.1.0
Description: Carte KPI générique et réutilisable pour tous les projets de l'écosystème lionsdev
-->
<c:set var="colSize" value="#{empty colSize ? 'col-12 md:col-6 lg:col-3' : colSize}" />
<c:set var="clickable" value="#{empty clickable ? false : clickable}" />
<c:set var="growthType" value="#{empty growthType ? 'percentage' : growthType}" />
<c:set var="showGrowth" value="#{empty showGrowth ? (not empty growthValue) : showGrowth}" />
<c:set var="showProgress" value="#{empty showProgress ? (not empty progressValue) : showProgress}" />
<c:set var="noDataLabel" value="#{empty noDataLabel ? 'Données non disponibles' : noDataLabel}" />
<div class="#{colSize}">
<c:choose>
<c:when test="#{clickable and not empty clickOutcome}">
<p:commandLink styleClass="card-link w-full #{styleClass}" outcome="#{clickOutcome}">
<div class="card surface-0 hover:surface-100 border-round-lg transition-all transition-duration-200">
<ui:include src="/templates/components/shared/cards/kpi-card-content.xhtml">
<ui:param name="title" value="#{title}" />
<ui:param name="value" value="#{value}" />
<ui:param name="icon" value="#{icon}" />
<ui:param name="iconColor" value="#{iconColor}" />
<ui:param name="subtitle" value="#{subtitle}" />
<ui:param name="growthValue" value="#{growthValue}" />
<ui:param name="growthLabel" value="#{growthLabel}" />
<ui:param name="growthType" value="#{growthType}" />
<ui:param name="showGrowth" value="#{showGrowth}" />
<ui:param name="noDataLabel" value="#{noDataLabel}" />
<ui:param name="progressValue" value="#{progressValue}" />
<ui:param name="showProgress" value="#{showProgress}" />
<ui:param name="statusIcon" value="#{statusIcon}" />
<ui:param name="statusLabel" value="#{statusLabel}" />
<ui:param name="statusValue" value="#{statusValue}" />
</ui:include>
</div>
</p:commandLink>
</c:when>
<c:when test="#{clickable and not empty clickAction}">
<p:commandLink styleClass="card-link w-full #{styleClass}" action="#{clickAction}">
<div class="card surface-0 hover:surface-100 border-round-lg transition-all transition-duration-200">
<ui:include src="/templates/components/shared/cards/kpi-card-content.xhtml">
<ui:param name="title" value="#{title}" />
<ui:param name="value" value="#{value}" />
<ui:param name="icon" value="#{icon}" />
<ui:param name="iconColor" value="#{iconColor}" />
<ui:param name="subtitle" value="#{subtitle}" />
<ui:param name="growthValue" value="#{growthValue}" />
<ui:param name="growthLabel" value="#{growthLabel}" />
<ui:param name="growthType" value="#{growthType}" />
<ui:param name="showGrowth" value="#{showGrowth}" />
<ui:param name="noDataLabel" value="#{noDataLabel}" />
<ui:param name="progressValue" value="#{progressValue}" />
<ui:param name="showProgress" value="#{showProgress}" />
<ui:param name="statusIcon" value="#{statusIcon}" />
<ui:param name="statusLabel" value="#{statusLabel}" />
<ui:param name="statusValue" value="#{statusValue}" />
</ui:include>
</div>
</p:commandLink>
</c:when>
<c:otherwise>
<div class="card surface-0 border-round-lg #{styleClass}">
<ui:include src="/templates/components/shared/cards/kpi-card-content.xhtml">
<ui:param name="title" value="#{title}" />
<ui:param name="value" value="#{value}" />
<ui:param name="icon" value="#{icon}" />
<ui:param name="iconColor" value="#{iconColor}" />
<ui:param name="subtitle" value="#{subtitle}" />
<ui:param name="growthValue" value="#{growthValue}" />
<ui:param name="growthLabel" value="#{growthLabel}" />
<ui:param name="growthType" value="#{growthType}" />
<ui:param name="showGrowth" value="#{showGrowth}" />
<ui:param name="noDataLabel" value="#{noDataLabel}" />
<ui:param name="progressValue" value="#{progressValue}" />
<ui:param name="showProgress" value="#{showProgress}" />
<ui:param name="statusIcon" value="#{statusIcon}" />
<ui:param name="statusLabel" value="#{statusLabel}" />
<ui:param name="statusValue" value="#{statusValue}" />
</ui:include>
</div>
</c:otherwise>
</c:choose>
</div>
</ui:composition>

View File

@@ -7,10 +7,10 @@
<!-- <!--
Composant réutilisable: Carte Statistique Utilisateur (WOU/DRY Pattern) Composant réutilisable: Carte Statistique Utilisateur (WOU/DRY Pattern)
Version 2.0.0 - Utilise maintenant kpi-card.xhtml en interne
Auteur: Lions User Manager Auteur: Lions User Manager
Version: 1.0.0 Description: Wrapper autour de kpi-card.xhtml pour compatibilité ascendante
Description: Carte affichant une statistique utilisateur avec icône et valeur
Paramètres: Paramètres:
- title: String (requis) - Titre de la carte - title: String (requis) - Titre de la carte
@@ -18,12 +18,15 @@
- icon: String (requis) - Classe d'icône PrimeIcons - icon: String (requis) - Classe d'icône PrimeIcons
- iconColor: String (requis) - Couleur de l'icône - iconColor: String (requis) - Couleur de l'icône
- subtitle: String (optionnel) - Sous-titre - subtitle: String (optionnel) - Sous-titre
- trend: Number (optionnel) - Tendance (pourcentage) - trend: Number (optionnel) - Tendance (pourcentage) - Mappé vers growthValue
- trendLabel: String (optionnel) - Libellé de la tendance - trendLabel: String (optionnel) - Libellé de la tendance - Mappé vers growthLabel
- colSize: String (défaut: "col-12 md:col-6 lg:col-3") - Taille de colonne - colSize: String (défaut: "col-12 md:col-6 lg:col-3") - Taille de colonne
- clickable: Boolean (défaut: false) - Rendre la carte cliquable - clickable: Boolean (défaut: false) - Rendre la carte cliquable
- clickOutcome: String (optionnel) - Page de redirection au clic - clickOutcome: String (optionnel) - Page de redirection au clic
Note: Ce composant est un wrapper de compatibilité. Pour de nouvelles implémentations,
utilisez directement kpi-card.xhtml qui offre plus de fonctionnalités.
Exemples d'utilisation: Exemples d'utilisation:
1. Carte simple: 1. Carte simple:
@@ -45,76 +48,20 @@
</ui:include> </ui:include>
--> -->
<c:set var="colSize" value="#{empty colSize ? 'col-12 md:col-6 lg:col-3' : colSize}" /> <!-- Déléguer à kpi-card.xhtml -->
<c:set var="clickable" value="#{empty clickable ? false : clickable}" /> <ui:include src="/templates/components/shared/cards/kpi-card.xhtml">
<ui:param name="title" value="#{title}" />
<div class="field #{colSize}"> <ui:param name="value" value="#{value}" />
<c:choose> <ui:param name="icon" value="#{icon}" />
<c:when test="#{clickable}"> <ui:param name="iconColor" value="#{iconColor}" />
<p:commandLink <ui:param name="subtitle" value="#{subtitle}" />
styleClass="card-link" <ui:param name="growthValue" value="#{trend}" />
outcome="#{not empty clickOutcome ? clickOutcome : null}"> <ui:param name="growthLabel" value="#{trendLabel}" />
<div class="card surface-0 hover:surface-100 border-round-lg transition-all transition-duration-200 p-4"> <ui:param name="growthType" value="percentage" />
<div class="flex align-items-center justify-content-between mb-3"> <ui:param name="colSize" value="#{colSize}" />
<span class="block text-600 font-medium text-sm">#{title}</span> <ui:param name="clickable" value="#{clickable}" />
<div class="flex align-items-center justify-content-center surface-100 border-round-lg" <ui:param name="clickOutcome" value="#{clickOutcome}" />
style="width: 2.5rem; height: 2.5rem;"> </ui:include>
<i class="pi #{icon} text-#{iconColor} text-lg"></i>
</div>
</div>
<div class="text-900 font-bold text-2xl mb-2">#{value}</div>
<c:if test="#{not empty subtitle}">
<div class="text-500 text-xs mb-2">#{subtitle}</div>
</c:if>
<c:if test="#{not empty trend}">
<div class="flex align-items-center">
<i class="pi pi-arrow-#{trend >= 0 ? 'up' : 'down'} text-#{trend >= 0 ? 'green' : 'red'}-500 text-sm mr-2"></i>
<span class="text-#{trend >= 0 ? 'green' : 'red'}-600 font-semibold text-sm mr-2">
#{trend >= 0 ? '+' : ''}#{trend}%
</span>
<c:if test="#{not empty trendLabel}">
<span class="text-500 text-xs">#{trendLabel}</span>
</c:if>
</div>
</c:if>
</div>
</p:commandLink>
</c:when>
<c:otherwise>
<div class="card surface-0 border-round-lg p-4">
<div class="flex align-items-center justify-content-between mb-3">
<span class="block text-600 font-medium text-sm">#{title}</span>
<div class="flex align-items-center justify-content-center surface-100 border-round-lg"
style="width: 2.5rem; height: 2.5rem;">
<i class="pi #{icon} text-#{iconColor} text-lg"></i>
</div>
</div>
<div class="text-900 font-bold text-2xl mb-2">#{value}</div>
<c:if test="#{not empty subtitle}">
<div class="text-500 text-xs mb-2">#{subtitle}</div>
</c:if>
<c:if test="#{not empty trend}">
<div class="flex align-items-center">
<i class="pi pi-arrow-#{trend >= 0 ? 'up' : 'down'} text-#{trend >= 0 ? 'green' : 'red'}-500 text-sm mr-2"></i>
<span class="text-#{trend >= 0 ? 'green' : 'red'}-600 font-semibold text-sm mr-2">
#{trend >= 0 ? '+' : ''}#{trend}%
</span>
<c:if test="#{not empty trendLabel}">
<span class="text-500 text-xs">#{trendLabel}</span>
</c:if>
</div>
</c:if>
</div>
</c:otherwise>
</c:choose>
</div>
</ui:composition> </ui:composition>

View File

@@ -0,0 +1,77 @@
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core">
<!--
Composant réutilisable: Section Dashboard - Écosystème LionsDev
Auteur: Lions User Manager
Version: 1.0.0
Description: Composant composite pour créer des sections de dashboard réutilisables
Paramètres:
- title: String (requis) - Titre de la section
- description: String (optionnel) - Description de la section
- icon: String (optionnel) - Icône PrimeIcons
- colSize: String (défaut: "col-12") - Taille de colonne
- showCard: Boolean (défaut: true) - Envelopper dans une carte
- styleClass: String (optionnel) - Classes CSS supplémentaires
Exemple:
ui:include src="/templates/components/shared/dashboard/dashboard-section.xhtml"
ui:param name="title" value="Actions Rapides"
ui:param name="icon" value="pi-bolt"
ui:param name="colSize" value="col-12 lg:col-6"
ui:define name="section-content"
Contenu de la section
ui:define
ui:include
-->
<c:set var="colSize" value="#{empty colSize ? 'col-12' : colSize}" />
<c:set var="showCard" value="#{empty showCard ? true : showCard}" />
<div class="#{colSize}">
<c:choose>
<c:when test="#{showCard}">
<div class="card #{styleClass}">
<c:if test="#{not empty title}">
<div class="flex align-items-center mb-3">
<c:if test="#{not empty icon}">
<i class="pi #{icon} mr-2 text-primary"></i>
</c:if>
<h5 class="font-semibold mb-0">#{title}</h5>
</div>
</c:if>
<c:if test="#{not empty description}">
<p class="text-600 text-sm mb-3">#{description}</p>
</c:if>
<ui:insert name="section-content">
<!-- Contenu de la section -->
</ui:insert>
</div>
</c:when>
<c:otherwise>
<c:if test="#{not empty title}">
<div class="flex align-items-center mb-3">
<c:if test="#{not empty icon}">
<i class="pi #{icon} mr-2 text-primary"></i>
</c:if>
<h5 class="font-semibold mb-0">#{title}</h5>
</div>
</c:if>
<c:if test="#{not empty description}">
<p class="text-600 text-sm mb-3">#{description}</p>
</c:if>
<ui:insert name="section-content">
<!-- Contenu de la section -->
</ui:insert>
</c:otherwise>
</c:choose>
</div>
</ui:composition>

View File

@@ -0,0 +1,78 @@
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core">
<!--
Composant réutilisable: Groupe de KPI (Composite) - Écosystème LionsDev
Auteur: Lions User Manager
Version: 1.0.0
Description: Composant composite pour afficher un groupe de KPI dans une grille
Paramètres:
- title: String (optionnel) - Titre de la section
- columns: Integer (défaut: 4) - Nombre de colonnes (1-12)
- colSize: String (optionnel) - Taille de colonne personnalisée (ex: "col-12 md:col-6 lg:col-3")
- showTitle: Boolean (défaut: true si title fourni) - Afficher le titre
- styleClass: String (optionnel) - Classes CSS supplémentaires
Utilisation:
Ce composant doit être utilisé avec des ui:param pour passer les KPI individuels.
Chaque KPI doit être inclus avec kpi-card.xhtml.
Exemple:
<ui:include src="/templates/components/shared/dashboard/kpi-group.xhtml">
<ui:param name="title" value="Statistiques Utilisateurs" />
<ui:param name="columns" value="4" />
<ui:define name="kpi-content">
<ui:include src="/templates/components/shared/cards/kpi-card.xhtml">
<ui:param name="title" value="Total" />
<ui:param name="value" value="#{bean.total}" />
<ui:param name="icon" value="pi-users" />
<ui:param name="iconColor" value="blue-600" />
</ui:include>
<!-- Autres KPI... -->
</ui:define>
</ui:include>
-->
<c:set var="columns" value="#{empty columns ? 4 : columns}" />
<c:set var="showTitle" value="#{empty showTitle ? (not empty title) : showTitle}" />
<c:choose>
<c:when test="#{columns == 1}">
<c:set var="colSize" value="col-12" />
</c:when>
<c:when test="#{columns == 2}">
<c:set var="colSize" value="col-12 md:col-6" />
</c:when>
<c:when test="#{columns == 3}">
<c:set var="colSize" value="col-12 md:col-6 lg:col-4" />
</c:when>
<c:when test="#{columns == 4}">
<c:set var="colSize" value="col-12 md:col-6 lg:col-3" />
</c:when>
<c:when test="#{columns == 6}">
<c:set var="colSize" value="col-12 md:col-6 lg:col-2" />
</c:when>
<c:otherwise>
<c:set var="colSize" value="#{empty colSize ? 'col-12 md:col-6 lg:col-3' : colSize}" />
</c:otherwise>
</c:choose>
<div class="mb-4 #{styleClass}">
<c:if test="#{showTitle}">
<h5 class="font-semibold mb-3">#{title}</h5>
</c:if>
<div class="grid">
<ui:insert name="kpi-content">
<!-- Les KPI seront insérés ici -->
</ui:insert>
</div>
</div>
</ui:composition>