2026-05-17 08:28:16 +00:00
|
|
|
(function () {
|
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
|
|
var pollInterval = (window._pollInterval || 15) * 1000;
|
|
|
|
|
var cliAvailable = !!window._cliAvailable;
|
|
|
|
|
|
2026-05-17 14:12:06 +00:00
|
|
|
var elDecisions = document.getElementById('stat-decisions');
|
|
|
|
|
var elAlerts24h = document.getElementById('stat-alerts-24h');
|
|
|
|
|
var elAlerts7d = document.getElementById('stat-alerts-7d');
|
|
|
|
|
var elBouncers = document.getElementById('stat-bouncers');
|
|
|
|
|
var elMachines = document.getElementById('stat-machines');
|
2026-05-17 08:28:16 +00:00
|
|
|
|
|
|
|
|
function animateTo(el, newVal) {
|
|
|
|
|
if (!el) return;
|
|
|
|
|
var current = parseInt(el.textContent, 10);
|
|
|
|
|
if (isNaN(current) || current === newVal) {
|
|
|
|
|
el.textContent = newVal;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// Brief flash transition
|
|
|
|
|
el.style.opacity = '0.4';
|
|
|
|
|
setTimeout(function () {
|
|
|
|
|
el.textContent = newVal;
|
|
|
|
|
el.style.opacity = '1';
|
|
|
|
|
}, 150);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function fetchStats() {
|
|
|
|
|
fetch('/api/v1/stats')
|
|
|
|
|
.then(function (r) {
|
|
|
|
|
if (!r.ok) throw new Error('bad response');
|
|
|
|
|
return r.json();
|
|
|
|
|
})
|
|
|
|
|
.then(function (d) {
|
|
|
|
|
animateTo(elDecisions, d.decisions);
|
2026-05-17 14:12:06 +00:00
|
|
|
animateTo(elAlerts24h, d.alerts_24h);
|
|
|
|
|
animateTo(elAlerts7d, d.alerts_7d);
|
2026-05-17 08:28:16 +00:00
|
|
|
if (cliAvailable) {
|
|
|
|
|
animateTo(elBouncers, d.bouncers);
|
|
|
|
|
animateTo(elMachines, d.machines);
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch(function () {
|
|
|
|
|
// silently fail — health badge in base.html covers connectivity state
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fetchStats();
|
|
|
|
|
setInterval(fetchStats, pollInterval);
|
|
|
|
|
})();
|