Files
Front-DataSentinel/DataSentinel/src/pages/VueConso/VueConso.jsx
T
Antho 8b8121ca1c refactor(front): centralise la règle de statut et les colonnes dupliquées
Le seuil de 10 erreurs qui fait basculer un monitoring en « Critique »
était réécrit dans trois fichiers (MonitoringCard, MonitoringDetail,
VueConso), la version de VueConso ne renvoyant qu'une couleur. Faire
évoluer ce seuil imposait de corriger trois endroits sans en oublier.
Il vit maintenant dans utils/statutMonitoring.js, avec la constante
SEUIL_ATTENTION nommée.

Les colonnes du tableau de monitorings étaient également identiques
entre VueConso et ServiceMonitorings : extraites dans
utils/monitoringColumns.jsx.
2026-08-15 14:29:09 +02:00

89 lines
3.2 KiB
React

// src/pages/VueConso/VueConso.jsx
// Page Vue consolidée : graphique barres + tableau avec export CSV
import { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { Download } from 'lucide-react';
import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';
import { getDashboard, exportToCSV } from '../../services/api';
import DataTable from '../../components/common/DataTable';
import LoadingSpinner from '../../components/common/LoadingSpinner';
import ErrorMessage from '../../components/common/ErrorMessage';
import Button from '../../components/common/Button';
import { getStatutMonitoring } from '../../utils/statutMonitoring';
import { buildMonitoringColumns } from '../../utils/monitoringColumns';
import styles from './VueConso.module.css';
export default function VueConso() {
const navigate = useNavigate();
const [data, setData] = useState([]);
const [loading, setLoading] = useState(true);
const [erreur, setErreur] = useState('');
useEffect(() => {
async function loadData() {
setLoading(true);
setErreur('');
try {
const result = await getDashboard();
setData(Array.isArray(result) ? result : []);
} catch (e) {
setErreur(e.message || 'Erreur lors du chargement de la vue consolidée.');
} finally {
setLoading(false);
}
}
loadData();
}, []);
if (loading) return <LoadingSpinner message="Chargement de la vue consolidée..." />;
if (erreur) return <ErrorMessage message={erreur} />;
/* Préparation des données pour le graphique */
const chartData = data.map(item => ({
name: item.nom || item.nom_monito || item.libelle || 'Monitoring',
erreurs: item.nb_erreurs ?? item.count ?? 0,
fill: getStatutMonitoring(item.nb_erreurs ?? item.count ?? 0).color
}));
const columns = buildMonitoringColumns(navigate);
return (
<div className={styles.page}>
<div className={styles.header}>
<h1 className={styles.title}>Vue consolidée</h1>
<Button variant="secondary" onClick={() => exportToCSV(data, `vue_consolidee_${new Date().toISOString().split('T')[0]}.csv`)}>
<Download size={14} />
Exporter tout ({data.length} lignes)
</Button>
</div>
{/* Graphique */}
<div className={styles.chartContainer}>
<ResponsiveContainer width="100%" height={400}>
<BarChart data={chartData} margin={{ top: 20, right: 30, left: 20, bottom: 60 }}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="name" angle={-45} textAnchor="end" height={80} />
<YAxis />
<Tooltip
contentStyle={{
backgroundColor: 'var(--color-black)',
color: 'var(--color-white)',
border: 'none',
borderRadius: 'var(--radius)'
}}
/>
<Bar dataKey="erreurs" fill="var(--color-primary)" />
</BarChart>
</ResponsiveContainer>
</div>
{/* Tableau */}
<DataTable
columns={columns}
data={data}
pageSize={50}
emptyMessage="Aucune donnée disponible."
/>
</div>
);
}