Add stat cards, lt-frame alert queue, and timeline for resolved alerts
Lint / Python (flake8) (push) Successful in 54s
Lint / JS (eslint) (push) Successful in 7s
Security / Python Security (bandit) (push) Failing after 40s
Test / Python Tests (pytest) (push) Successful in 50s
Lint / Notify on failure (push) Has been skipped
Lint / Deploy (push) Successful in 3s
Lint / Python (flake8) (push) Successful in 54s
Lint / JS (eslint) (push) Successful in 7s
Security / Python Security (bandit) (push) Failing after 40s
Test / Python Tests (pytest) (push) Successful in 50s
Lint / Notify on failure (push) Has been skipped
Lint / Deploy (push) Successful in 3s
- Four lt-stat-card widgets (Critical, Warning, Hosts, Resolved 24h) below the status bar; Critical card pulses red when count > 0 - Clicking Critical or Warning card filters the events table by severity - Events table wrapped in lt-frame with ASCII corner ornaments and lt-section-header; filter bar moved to lt-toolbar with lt-search icon - Recently Resolved table replaced with lt-timeline component - updateStatusBar() and updateHostGrid() keep stat card values live Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -89,6 +89,14 @@ function updateStatusBar(summary, lastCheck, daemonOk) {
|
||||
alertBadge.style.display = total ? '' : 'none';
|
||||
}
|
||||
|
||||
// Update stat cards
|
||||
const scCrit = document.getElementById('stat-critical-val');
|
||||
const scWarn = document.getElementById('stat-warning-val');
|
||||
if (scCrit) scCrit.textContent = critCount;
|
||||
if (scWarn) scWarn.textContent = warnCount;
|
||||
const statCritCard = document.getElementById('stat-critical');
|
||||
if (statCritCard) statCritCard.classList.toggle('lt-stat-card--alert', critCount > 0);
|
||||
|
||||
// Stale data banner: warn if last_check is older than 15 minutes
|
||||
let staleBanner = document.getElementById('stale-banner');
|
||||
if (lastCheck) {
|
||||
@@ -112,6 +120,9 @@ function updateStatusBar(summary, lastCheck, daemonOk) {
|
||||
}
|
||||
|
||||
function updateHostGrid(hosts) {
|
||||
const scHosts = document.getElementById('stat-hosts-val');
|
||||
if (scHosts) scHosts.textContent = Object.keys(hosts).length;
|
||||
|
||||
for (const [name, host] of Object.entries(hosts)) {
|
||||
const card = document.querySelector(`.host-card[data-host="${CSS.escape(name)}"]`);
|
||||
if (!card) continue;
|
||||
|
||||
@@ -995,6 +995,17 @@
|
||||
.diag-pulse-link a { color: var(--cyan); }
|
||||
.diag-pulse-link a:hover { text-shadow: var(--glow-cyan); }
|
||||
|
||||
/* ── Stat card alert variant (pulsing border when critical > 0) ─── */
|
||||
.lt-stat-card--alert {
|
||||
border-color: var(--red) !important;
|
||||
box-shadow: 0 0 8px rgba(255,45,85,.25) !important;
|
||||
animation: topo-pulse-down 2s ease-in-out infinite;
|
||||
}
|
||||
.lt-stat-card--alert::before { background: var(--red); box-shadow: var(--glow-red); }
|
||||
|
||||
/* ── lt-frame inside g-section: no extra bottom margin ────────────── */
|
||||
.g-section > .lt-frame { margin-bottom: 0; }
|
||||
|
||||
/* ── Responsive ───────────────────────────────────────────────────── */
|
||||
@media (max-width: 768px) {
|
||||
.host-grid { grid-template-columns: 1fr; }
|
||||
|
||||
Reference in New Issue
Block a user