fix(historique): période par défaut du 1er janvier à aujourd'hui
La page se limitait aux 5 derniers jours par défaut, alors que l'historique disponible remonte au 1er janvier. Corrige aussi un bug de fuseau horaire : les dates par défaut étaient calculées avec toISOString(), qui bascule en UTC (un 1er janvier saisi depuis Paris, UTC+1, devenait le 31 décembre de l'année précédente) — remplacé par un formatage en heure locale. La page charge maintenant directement cette période au montage, au lieu d'attendre un clic sur "Afficher" pour afficher autre chose qu'un écran vide sous les filtres.
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
// Page Historique : filtres + graphique ligne + tableau résumé
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Area, ComposedChart } from 'recharts';
|
||||
import { Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Area, ComposedChart } from 'recharts';
|
||||
import { getMonitorings, getHistorique, getHistoriqueEvolution, getEvolutionGlobal, exportToCSV } from '../../services/api';
|
||||
import DataTable from '../../components/common/DataTable';
|
||||
import LoadingSpinner from '../../components/common/LoadingSpinner';
|
||||
@@ -10,25 +10,66 @@ import ErrorMessage from '../../components/common/ErrorMessage';
|
||||
import Button from '../../components/common/Button';
|
||||
import styles from './Historique.module.css';
|
||||
|
||||
/* Formate une date au format attendu par <input type="date"> (YYYY-MM-DD).
|
||||
On lit les composantes en heure locale plutôt que d'utiliser toISOString(),
|
||||
qui bascule en UTC : un 1er janvier saisi depuis Paris (UTC+1) y devient le
|
||||
31 décembre de l'année précédente. */
|
||||
function formatDateISO(date) {
|
||||
const mois = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const jour = String(date.getDate()).padStart(2, '0');
|
||||
return `${date.getFullYear()}-${mois}-${jour}`;
|
||||
}
|
||||
|
||||
/* Période affichée par défaut : du 1er janvier de l'année courante à aujourd'hui. */
|
||||
function periodeParDefaut() {
|
||||
const aujourdhui = new Date();
|
||||
return {
|
||||
debut: formatDateISO(new Date(aujourdhui.getFullYear(), 0, 1)),
|
||||
fin: formatDateISO(aujourdhui),
|
||||
};
|
||||
}
|
||||
|
||||
/* Récupère le tableau d'historique et la série du graphique pour les filtres
|
||||
donnés. Sans monitoring sélectionné, on prend la courbe globale.
|
||||
Fonction pure : elle ne touche à aucun état, ce qui permet de l'appeler
|
||||
aussi bien depuis le bouton « Afficher » que depuis l'effet de montage. */
|
||||
async function recupererHistorique(monitoring, debut, fin) {
|
||||
const [histResult, evolResult] = monitoring
|
||||
? await Promise.all([
|
||||
getHistorique(monitoring, debut, fin),
|
||||
getHistoriqueEvolution(monitoring, debut, fin),
|
||||
])
|
||||
: await Promise.all([
|
||||
getHistorique(undefined, debut, fin),
|
||||
getEvolutionGlobal(debut, fin),
|
||||
]);
|
||||
|
||||
return {
|
||||
hist: Array.isArray(histResult) ? histResult : [],
|
||||
evol: Array.isArray(evolResult) ? evolResult : [],
|
||||
};
|
||||
}
|
||||
|
||||
export default function Historique() {
|
||||
const [searchParams] = useSearchParams();
|
||||
|
||||
/* Figé au montage : sert à la fois de valeur initiale des filtres et de
|
||||
paramètres du premier chargement, sans dépendance instable. */
|
||||
const [valeursInitiales] = useState(() => ({
|
||||
monitoring: searchParams.get('id') || '',
|
||||
...periodeParDefaut(),
|
||||
}));
|
||||
|
||||
const [monitorings, setMonitorings] = useState([]);
|
||||
const [selectedMonitoring, setSelectedMonitoring] = useState(searchParams.get('id') || '');
|
||||
const [dateDebut, setDateDebut] = useState('');
|
||||
const [dateFin, setDateFin] = useState('');
|
||||
const [selectedMonitoring, setSelectedMonitoring] = useState(valeursInitiales.monitoring);
|
||||
const [dateDebut, setDateDebut] = useState(valeursInitiales.debut);
|
||||
const [dateFin, setDateFin] = useState(valeursInitiales.fin);
|
||||
const [historiqueData, setHistoriqueData] = useState([]);
|
||||
const [evolutionData, setEvolutionData] = useState([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
/* Un chargement est lancé dès le montage : la page démarre donc en attente. */
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [erreur, setErreur] = useState('');
|
||||
|
||||
/* Set default dates to last 5 days */
|
||||
useEffect(() => {
|
||||
const today = new Date();
|
||||
const fiveDaysAgo = new Date(today);
|
||||
fiveDaysAgo.setDate(today.getDate() - 5);
|
||||
setDateDebut(fiveDaysAgo.toISOString().split('T')[0]);
|
||||
setDateFin(today.toISOString().split('T')[0]);
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
async function loadMonitorings() {
|
||||
try {
|
||||
@@ -41,6 +82,31 @@ export default function Historique() {
|
||||
loadMonitorings();
|
||||
}, []);
|
||||
|
||||
/* Premier affichage : on charge la période par défaut, pour que la page ne
|
||||
s'ouvre pas sur un écran vide en attente d'un clic. Le drapeau `annule`
|
||||
évite d'écrire dans un composant déjà démonté si l'utilisateur quitte la
|
||||
page pendant la requête. */
|
||||
useEffect(() => {
|
||||
let annule = false;
|
||||
|
||||
async function chargerAuMontage() {
|
||||
const { monitoring, debut, fin } = valeursInitiales;
|
||||
try {
|
||||
const { hist, evol } = await recupererHistorique(monitoring, debut, fin);
|
||||
if (annule) return;
|
||||
setHistoriqueData(hist);
|
||||
setEvolutionData(evol);
|
||||
} catch (e) {
|
||||
if (!annule) setErreur(e.message || 'Erreur lors du chargement de l\'historique.');
|
||||
} finally {
|
||||
if (!annule) setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
chargerAuMontage();
|
||||
return () => { annule = true; };
|
||||
}, [valeursInitiales]);
|
||||
|
||||
async function handleAfficher() {
|
||||
if (!dateDebut || !dateFin) {
|
||||
setErreur('Veuillez sélectionner des dates.');
|
||||
@@ -50,25 +116,7 @@ export default function Historique() {
|
||||
setLoading(true);
|
||||
setErreur('');
|
||||
try {
|
||||
let hist = [];
|
||||
let evol = [];
|
||||
|
||||
if (selectedMonitoring) {
|
||||
const [histResult, evolResult] = await Promise.all([
|
||||
getHistorique(selectedMonitoring, dateDebut, dateFin),
|
||||
getHistoriqueEvolution(selectedMonitoring, dateDebut, dateFin)
|
||||
]);
|
||||
hist = Array.isArray(histResult) ? histResult : [];
|
||||
evol = Array.isArray(evolResult) ? evolResult : [];
|
||||
} else {
|
||||
const [histResult, evolResult] = await Promise.all([
|
||||
getHistorique(undefined, dateDebut, dateFin),
|
||||
getEvolutionGlobal(dateDebut, dateFin)
|
||||
]);
|
||||
hist = Array.isArray(histResult) ? histResult : [];
|
||||
evol = Array.isArray(evolResult) ? evolResult : [];
|
||||
}
|
||||
|
||||
const { hist, evol } = await recupererHistorique(selectedMonitoring, dateDebut, dateFin);
|
||||
setHistoriqueData(hist);
|
||||
setEvolutionData(evol);
|
||||
} catch (e) {
|
||||
@@ -189,9 +237,9 @@ export default function Historique() {
|
||||
emptyMessage="Aucune donnée historique."
|
||||
/>
|
||||
</>
|
||||
) : selectedMonitoring && dateDebut && dateFin && !loading ? (
|
||||
) : (
|
||||
<p className={styles.empty}>Aucune donnée trouvée pour cette période.</p>
|
||||
) : null}
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user