diff --git a/dashboard/css/security.css b/dashboard/css/security.css index 40de976..5071026 100644 --- a/dashboard/css/security.css +++ b/dashboard/css/security.css @@ -226,6 +226,10 @@ color: #eee; } +.stat-item-full { + grid-column: 1 / -1; +} + .security-dialog-actions { display: flex; gap: 12px; diff --git a/dashboard/css/timeline.css b/dashboard/css/timeline.css index 973616d..3b17bcf 100644 --- a/dashboard/css/timeline.css +++ b/dashboard/css/timeline.css @@ -354,6 +354,11 @@ --event-color-bg: rgba(74, 158, 255, 0.15); } +.timeline-event[data-type="anomaly"] { + --event-color: #ff4757; + --event-color-bg: rgba(255, 71, 87, 0.15); +} + .timeline-event[data-type="anomaly_detected"] { --event-color: #ff4757; --event-color-bg: rgba(255, 71, 87, 0.15); diff --git a/dashboard/js/security-panel.js b/dashboard/js/security-panel.js index bb34cb0..b2b4598 100644 --- a/dashboard/js/security-panel.js +++ b/dashboard/js/security-panel.js @@ -110,11 +110,11 @@ } function fetchAnomalyCount() { - fetch(API.anomalyHistory + '?since=24h') + fetch(API.anomalyHistory + '?since=24h&limit=1') .then(res => res.json()) .then(data => { if (data.history && Array.isArray(data.history)) { - _anomalyCount24h = data.history.length; + _anomalyCount24h = data.total || data.history.length; if (data.history.length > 0) { _lastAnomaly = data.history[0]; } @@ -232,8 +232,9 @@ progressEl.style.width = (_learningProgress * 100) + '%'; } if (daysEl) { - const daysLeft = Math.ceil((1 - _learningProgress) * 7); - daysEl.textContent = daysLeft > 0 ? daysLeft + ' days remaining' : 'Almost ready...'; + const daysComplete = Math.floor(_learningProgress * 7); + const daysTotal = 7; + daysEl.textContent = `${daysComplete} of ${daysTotal} days complete`; } } else { banner.classList.remove('visible'); @@ -299,6 +300,12 @@ ${formatTimeAgo(_lastAnomaly.timestamp)} ` : ''} + ${_lastAnomaly && _lastAnomaly.zone_name ? ` +
+ Location + ${_lastAnomaly.zone_name} +
+ ` : ''}