From 5f15002462e2a5fa14f6f86b289356c8d19c95b9 Mon Sep 17 00:00:00 2001 From: Alexis Fourmaux Date: Tue, 12 May 2026 23:24:31 +0200 Subject: [PATCH] feat: improve error management when data are missing --- server/frontend/public/assets/css/main.css | 6 ++ server/frontend/public/assets/js/chart.js | 47 ++++++++---- server/frontend/public/assets/js/main.js | 84 ++++++++++++++-------- server/frontend/public/index.html | 1 + 4 files changed, 95 insertions(+), 43 deletions(-) diff --git a/server/frontend/public/assets/css/main.css b/server/frontend/public/assets/css/main.css index 9881a42..41364b1 100644 --- a/server/frontend/public/assets/css/main.css +++ b/server/frontend/public/assets/css/main.css @@ -145,3 +145,9 @@ main { } } } + +#chart-message { + color: var(--color-text-muted); + margin-top: 8rem; + text-align: center; +} \ No newline at end of file diff --git a/server/frontend/public/assets/js/chart.js b/server/frontend/public/assets/js/chart.js index 2cb2a29..1a2e8ea 100644 --- a/server/frontend/public/assets/js/chart.js +++ b/server/frontend/public/assets/js/chart.js @@ -1,4 +1,36 @@ +const PERIOD_FORMATS = { + hour: { hour: "2-digit", minute: "2-digit", day: "2-digit", month: "short" }, + day: { day: "2-digit", month: "short" }, + week: { day: "2-digit", month: "short" }, + month: { month: "short", year: "numeric" }, +}; + +function formatPeriod(isoString, granularity) { + const date = new Date(isoString); + const opts = PERIOD_FORMATS[granularity] ?? PERIOD_FORMATS.day; + return date.toLocaleDateString("fr-FR", opts); +} + +function showMessage(message) { + document.getElementById("consumption-chart").hidden = true; + const msg = document.getElementById("chart-message"); + msg.textContent = message; + msg.hidden = false; +} + +function hideMessage() { + document.getElementById("consumption-chart").hidden = false; + document.getElementById("chart-message").hidden = true; +} + function renderChart(points, granularity) { + if (!points || points.length === 0){ + showMessage("Aucune donnée à afficher sur cette période"); + return null; + } + + hideMessage(); + const canvas = document.getElementById("consumption-chart"); const labels = points.map((p) => formatPeriod(p.period, granularity)); @@ -17,7 +49,7 @@ function renderChart(points, granularity) { data, backgroundColor: accent + 'cc', borderColor: accent, - borderWidth: '1px' + borderWidth: 1 }, ], }, @@ -43,17 +75,4 @@ function renderChart(points, granularity) { }); return chart; -} - -const PERIOD_FORMATS = { - hour: { hour: "2-digit", minute: "2-digit", day: "2-digit", month: "short" }, - day: { day: "2-digit", month: "short" }, - week: { day: "2-digit", month: "short" }, - month: { month: "short", year: "numeric" }, -}; - -function formatPeriod(isoString, granularity) { - const date = new Date(isoString); - const opts = PERIOD_FORMATS[granularity] ?? PERIOD_FORMATS.day; - return date.toLocaleDateString("fr-FR", opts); } \ No newline at end of file diff --git a/server/frontend/public/assets/js/main.js b/server/frontend/public/assets/js/main.js index 9c3aca7..6a9c8f6 100644 --- a/server/frontend/public/assets/js/main.js +++ b/server/frontend/public/assets/js/main.js @@ -1,17 +1,8 @@ let chart = null; -window.onload = init; +document.addEventListener("DOMContentLoaded", init); -async function init() { - let start = new Date(); - start.setDate(start.getDate() - 7); - const end = new Date(); +function showChartError() { - document.getElementById("date-start").valueAsDate = start; - document.getElementById("date-end").valueAsDate = end; - document.getElementById("btn-refresh").addEventListener("click", loadData); - - await loadDevices(); - await loadData(); } async function loadData() { @@ -20,18 +11,26 @@ async function loadData() { const granularity = document.getElementById("granularity").value; const device_eui = document.getElementById("device").value; - const points = await fetchConsumption({ - device_eui: device_eui, - start: start, - end: end, - granularity: granularity, - }); + if (!device_eui || !start || !end) return; - if (chart) { - chart.destroy(); + try { + const points = await fetchConsumption({ + device_eui: device_eui, + start: start, + end: end, + granularity: granularity, + }); + + if (chart) { chart.destroy(); } + + chart = renderChart(points, granularity); + updateKPIs(points); + + } catch (err) { + if (chart) { chart.destroy(); } + showMessage("Impossible de charger les données : " + err.message); + updateKPIs(null); } - chart = renderChart(points, granularity); - updateKPIs(points); } function updateKPIs(points) { @@ -40,9 +39,9 @@ function updateKPIs(points) { const countDisplay = document.getElementById("kpi-count"); if (!points || points.length === 0) { - total.textContent = "-"; - avg.textContent = "-"; - count.textContent = "-"; + totalDisplay.textContent = "-"; + avgDisplay.textContent = "-"; + countDisplay.textContent = "-"; return; } @@ -57,11 +56,38 @@ function updateKPIs(points) { async function loadDevices() { const selectDeviceElmt = document.getElementById("device"); - const devices = await fetchDevices(); + try { + const devices = await fetchDevices(); + if (!devices.length) { + selectDeviceElmt.disabled = true; + selectDeviceElmt.add(new Option("Aucun appareil disponible", "")); + return; + } - devices.forEach((device) => { - selectDeviceElmt.add(new Option(device.device_eui)) - }); + devices.forEach((device) => { + selectDeviceElmt.add(new Option(device.device_eui)); + }); - selectDeviceElmt.value = devices[0]?.device_eui ?? ""; + selectDeviceElmt.value = devices[0].device_eui; + + } catch(err) { + selectDeviceElmt.disabled = true; + selectDeviceElmt.add(new Option("Erreur de chargement", "")); + console.error("loadDevices :", err.message); + } } + +async function init() { + let start = new Date(); + start.setDate(start.getDate() - 7); + const end = new Date(); + + document.getElementById("date-start").valueAsDate = start; + document.getElementById("date-end").valueAsDate = end; + document.getElementById("btn-refresh").addEventListener("click", loadData); + + await loadDevices(); + + const device_eui = document.getElementById("device").value; + if (device_eui) await loadData(); +} \ No newline at end of file diff --git a/server/frontend/public/index.html b/server/frontend/public/index.html index 48cf597..8d6df2e 100644 --- a/server/frontend/public/index.html +++ b/server/frontend/public/index.html @@ -69,6 +69,7 @@
+