// collecte.js — page "Collecte" : historique des exécutions de tâches de // collecte (cron quotidien + backfill historique), détail des erreurs par // exécution, et acquittement manuel. let currentRuns = []; async function loadRuns() { const res = await fetch("/api/collection-runs"); if (!res.ok) throw new Error(`API collection-runs: HTTP ${res.status}`); return res.json(); } function runTypeLabel(type) { return type === "backfill" ? "Historique (backfill)" : "Journalière"; } function formatDateTime(iso) { if (!iso) return "—"; return new Intl.DateTimeFormat("fr-FR", { dateStyle: "medium", timeStyle: "short" }).format(new Date(iso)); } function formatDuration(startIso, endIso) { if (!startIso || !endIso) return "—"; const seconds = Math.max(0, Math.round((new Date(endIso) - new Date(startIso)) / 1000)); if (seconds < 60) return `${seconds} s`; return `${Math.floor(seconds / 60)} min ${seconds % 60} s`; } function statusBadge(run) { if (run.tenants_error === 0) { return `OK`; } if (run.acknowledged_at) { return `Erreurs (acquittées)`; } return `Erreurs`; } function renderRunsTable() { const wrap = document.getElementById("runs-table-wrap"); if (currentRuns.length === 0) { wrap.innerHTML = `
collect.py ou backfill_historical.py.| Type | Démarrée | Durée | OK | Erreurs | Statut |
|---|
Acquittée le ${formatDateTime(run.acknowledged_at)}
` : ``; bodyEl.innerHTML = `${ackBlock}${list}`; const btn = document.getElementById("ack-button"); if (btn) { btn.addEventListener("click", () => acknowledgeRun(run.id)); } } async function acknowledgeRun(runId) { const btn = document.getElementById("ack-button"); if (btn) btn.disabled = true; try { const res = await fetch(`/api/collection-runs/${runId}/acknowledge`, { method: "POST" }); if (!res.ok) throw new Error(`HTTP ${res.status}`); closeRunDrawer(); await init(); refreshCollecteAlert(); } catch (e) { document.getElementById("drawer-body").innerHTML = ``; } } function closeRunDrawer() { document.getElementById("run-drawer").classList.remove("open"); document.getElementById("run-drawer").setAttribute("aria-hidden", "true"); document.getElementById("drawer-backdrop").classList.remove("open"); } function setupDrawer() { document.getElementById("drawer-close").addEventListener("click", closeRunDrawer); document.getElementById("drawer-backdrop").addEventListener("click", closeRunDrawer); document.addEventListener("keydown", (e) => { if (e.key === "Escape") closeRunDrawer(); }); } async function init() { try { const data = await loadRuns(); currentRuns = data.runs; renderRunsTable(); } catch (e) { document.getElementById("error-banner").innerHTML = ` `; document.getElementById("runs-table-wrap").innerHTML = ""; } } init(); setupDrawer();