feat(dashboard): filtres services/catégories restreints aux résultats
Les select de service et catégorie utilisaient getServices()/getCategories(), soit les référentiels complets — dont certaines entrées (ex. "Business Intelligence") n'ont aucun monitoring rattaché et menaient sur un dashboard vide. Bascule vers le nouvel endpoint GET /dashboard/filtres (VUE_CONSO), avec filtrage en cascade : sélectionner un service restreint la liste des catégories proposées à celles qui ont réellement des résultats pour ce service.
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
/* Page principale du dashboard : KPI cards + grille de monitorings */
|
||||
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { useState, useEffect, useCallback, useMemo } from 'react';
|
||||
import { RefreshCw } from 'lucide-react';
|
||||
import { getDashboard, getDashboardSummary, getServices, getCategories } from '../../services/api';
|
||||
import { getDashboard, getDashboardSummary, getDashboardFiltres } from '../../services/api';
|
||||
import MonitoringCard from '../../components/common/MonitoringCard';
|
||||
import LoadingSpinner from '../../components/common/LoadingSpinner';
|
||||
import ErrorMessage from '../../components/common/ErrorMessage';
|
||||
@@ -22,19 +22,22 @@ export default function Dashboard() {
|
||||
const [summary, setSummary] = useState(null);
|
||||
const [monitorings, setMonitorings] = useState([]);
|
||||
const [services, setServices] = useState([]);
|
||||
const [categories, setCategories] = useState([]);
|
||||
const [combinaisons, setCombinaisons] = useState([]);
|
||||
const [filtreService, setFiltreService] = useState('');
|
||||
const [filtreCategorie, setFiltreCategorie] = useState('');
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [erreur, setErreur] = useState('');
|
||||
|
||||
/* Chargement initial des filtres */
|
||||
/* Chargement initial des filtres.
|
||||
On n'utilise pas les référentiels SERVICE / CATEGORIE complets : ils
|
||||
contiennent des entrées sans aucun monitoring rattaché (ex. « Business
|
||||
Intelligence »), qui mèneraient sur un dashboard vide. */
|
||||
useEffect(() => {
|
||||
async function loadFiltres() {
|
||||
try {
|
||||
const [svcs, cats] = await Promise.all([getServices(), getCategories()]);
|
||||
setServices(svcs);
|
||||
setCategories(cats);
|
||||
const filtres = await getDashboardFiltres();
|
||||
setServices(filtres.services);
|
||||
setCombinaisons(filtres.combinaisons);
|
||||
} catch {
|
||||
/* Non bloquant, les filtres restent vides */
|
||||
}
|
||||
@@ -42,6 +45,28 @@ export default function Dashboard() {
|
||||
loadFiltres();
|
||||
}, []);
|
||||
|
||||
/* Catégories proposées : restreintes au service sélectionné, le cas échéant */
|
||||
const categoriesDisponibles = useCallback(service => {
|
||||
const pertinentes = service
|
||||
? combinaisons.filter(c => c.service === service)
|
||||
: combinaisons;
|
||||
return [...new Set(pertinentes.map(c => c.categorie))].sort();
|
||||
}, [combinaisons]);
|
||||
|
||||
const categories = useMemo(
|
||||
() => categoriesDisponibles(filtreService),
|
||||
[categoriesDisponibles, filtreService],
|
||||
);
|
||||
|
||||
/* Changer de service peut rendre la catégorie sélectionnée sans résultat :
|
||||
on la remet à zéro dans le même rendu, pour ne déclencher qu'un seul appel. */
|
||||
function handleServiceChange(service) {
|
||||
setFiltreService(service);
|
||||
if (filtreCategorie && !categoriesDisponibles(service).includes(filtreCategorie)) {
|
||||
setFiltreCategorie('');
|
||||
}
|
||||
}
|
||||
|
||||
/* Chargement des données dashboard */
|
||||
const loadData = useCallback(async () => {
|
||||
setLoading(true);
|
||||
@@ -105,11 +130,11 @@ export default function Dashboard() {
|
||||
<select
|
||||
className={styles.select}
|
||||
value={filtreService}
|
||||
onChange={e => setFiltreService(e.target.value)}
|
||||
onChange={e => handleServiceChange(e.target.value)}
|
||||
>
|
||||
<option value="">Tous les services</option>
|
||||
{services.map(s => (
|
||||
<option key={s.id_service} value={s.nom_service}>{s.nom_service}</option>
|
||||
<option key={s} value={s}>{s}</option>
|
||||
))}
|
||||
</select>
|
||||
<select
|
||||
@@ -119,7 +144,7 @@ export default function Dashboard() {
|
||||
>
|
||||
<option value="">Toutes les catégories</option>
|
||||
{categories.map(c => (
|
||||
<option key={c.id_categorie} value={c.intitule_categorie}>{c.intitule_categorie}</option>
|
||||
<option key={c} value={c}>{c}</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user