fix: groups

This commit is contained in:
nate 2026-04-10 02:33:29 +04:00
parent f7a9ee624d
commit 992570341a
2 changed files with 36 additions and 3 deletions

View File

@ -52,7 +52,11 @@ h1 { font-size: 1.75rem; font-weight: 700; margin: 0 0 0.5rem; }
.group-chev { color: var(--muted); transition: transform 0.15s; flex-shrink: 0; } .group-chev { color: var(--muted); transition: transform 0.15s; flex-shrink: 0; }
.group-toggle:checked ~ .group-header .group-chev { transform: rotate(90deg); } .group-toggle:checked ~ .group-header .group-chev { transform: rotate(90deg); }
.group-name { font-size: 0.85rem; font-weight: 600; color: var(--fg); } .group-name { font-size: 0.85rem; font-weight: 600; color: var(--fg); }
.group-header-right { display: flex; align-items: center; gap: 1rem; }
.group-status { font-size: 0.75rem; font-weight: 600; } .group-status { font-size: 0.75rem; font-weight: 600; }
.group-aggregate { padding: 0 1.25rem 0.75rem; }
.group-aggregate .bars { height: 24px; }
.group-toggle:checked ~ .group-aggregate { display: none; }
.group-body { display: none; padding: 0 0.75rem 0.75rem; } .group-body { display: none; padding: 0 0.75rem 0.75rem; }
.group-toggle:checked ~ .group-body { display: block; } .group-toggle:checked ~ .group-body { display: block; }
.group-body .monitors { gap: 0.35rem; } .group-body .monitors { gap: 0.35rem; }

View File

@ -192,16 +192,45 @@
const groupStatusLabel = groupStatus === 'up' ? 'Operational' : groupStatus === 'degraded' ? 'Degraded' : groupStatus === 'down' ? 'Down' : ''; const groupStatusLabel = groupStatus === 'up' ? 'Operational' : groupStatus === 'degraded' ? 'Degraded' : groupStatus === 'down' ? 'Down' : '';
const groupStatusColor = groupStatus === 'up' ? 'var(--bar-up)' : groupStatus === 'degraded' ? 'var(--bar-partial)' : groupStatus === 'down' ? 'var(--bar-down)' : 'var(--muted)'; const groupStatusColor = groupStatus === 'up' ? 'var(--bar-up)' : groupStatus === 'degraded' ? 'var(--bar-partial)' : groupStatus === 'down' ? 'var(--bar-down)' : 'var(--muted)';
%> %>
<% if (groupName) { %> <% if (groupName) {
// Aggregate buckets across all monitors in the group (weighted average)
const aggBuckets = [];
const firstWithBuckets = list.find(m => m.buckets && m.buckets.length > 0);
if (firstWithBuckets) {
for (let bi = 0; bi < firstWithBuckets.buckets.length; bi++) {
let t = 0, u = 0, latSum = 0, latN = 0;
for (const m of list) {
if (!m.buckets || !m.buckets[bi]) continue;
t += m.buckets[bi].total;
u += m.buckets[bi].up;
if (m.buckets[bi].avg_latency != null) { latSum += m.buckets[bi].avg_latency * m.buckets[bi].total; latN += m.buckets[bi].total; }
}
aggBuckets.push({ start: firstWithBuckets.buckets[bi].start, total: t, up: u, avg_latency: latN > 0 ? Math.round(latSum / latN) : null });
}
}
const aggTotal = aggBuckets.reduce((a, b) => a + b.total, 0);
const aggUp = aggBuckets.reduce((a, b) => a + b.up, 0);
const aggPct = aggTotal > 0 ? (100 * aggUp / aggTotal) : null;
%>
<div class="group-section"> <div class="group-section">
<input type="checkbox" class="group-toggle" id="g-<%= gi %>" checked> <input type="checkbox" class="group-toggle" id="g-<%= gi %>">
<label class="group-header" for="g-<%= gi %>"> <label class="group-header" for="g-<%= gi %>">
<div class="group-header-left"> <div class="group-header-left">
<svg class="group-chev" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="9 18 15 12 9 6"/></svg> <svg class="group-chev" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="9 18 15 12 9 6"/></svg>
<span class="group-name"><%= groupName %></span> <span class="group-name"><%= groupName %></span>
</div> </div>
<div class="group-header-right">
<span class="uptime-pct <%= uptimeBand(aggPct) %>"><%= fmtUptime(aggPct) %></span>
<span class="group-status" style="color: <%= groupStatusColor %>;"><%= groupStatusLabel %></span> <span class="group-status" style="color: <%= groupStatusColor %>;"><%= groupStatusLabel %></span>
</div>
</label> </label>
<div class="group-aggregate">
<div class="bars" aria-label="Group uptime">
<% aggBuckets.forEach(function(b) { %>
<div class="bar" style="background: <%= bucketColor(b) %>;" data-start="<%= b.start %>" data-total="<%= b.total %>" data-up="<%= b.up %>"<% if (b.avg_latency != null) { %> data-latency="<%= b.avg_latency %>"<% } %>></div>
<% }); %>
</div>
</div>
<div class="group-body"> <div class="group-body">
<% } %> <% } %>
<div class="monitors"> <div class="monitors">