diff --git a/DataSentinel/src/pages/Dashboard/Dashboard.jsx b/DataSentinel/src/pages/Dashboard/Dashboard.jsx
index 7797dbf..79c30e2 100644
--- a/DataSentinel/src/pages/Dashboard/Dashboard.jsx
+++ b/DataSentinel/src/pages/Dashboard/Dashboard.jsx
@@ -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() {
diff --git a/DataSentinel/src/services/api.js b/DataSentinel/src/services/api.js
index 7c6f0c9..bbd1116 100644
--- a/DataSentinel/src/services/api.js
+++ b/DataSentinel/src/services/api.js
@@ -245,6 +245,18 @@ export async function getDashboard(service, categorie) {
})) : data;
}
+/* Récupère les valeurs de filtre qui ramènent au moins un monitoring (VUE_CONSO).
+ Évite de proposer un service ou une catégorie du référentiel qui n'a aucun
+ monitoring rattaché, et donc de mener l'utilisateur sur un écran vide. */
+export async function getDashboardFiltres() {
+ const data = await fetchApi('/dashboard/filtres');
+ return {
+ services: Array.isArray(data?.services) ? data.services : [],
+ categories: Array.isArray(data?.categories) ? data.categories : [],
+ combinaisons: Array.isArray(data?.combinaisons) ? data.combinaisons : [],
+ };
+}
+
/* Récupère le résumé global KPI du dashboard */
export async function getDashboardSummary() {
const data = await fetchApi('/dashboard/summary');