feat: add group system
This commit is contained in:
@@ -44,7 +44,19 @@ h1 { font-size: 1.75rem; font-weight: 700; margin: 0 0 0.5rem; }
|
||||
.overall { padding: 1rem 1.25rem; border-radius: 10px; font-weight: 600; font-size: 1rem; margin: 1.5rem 0 2rem; display: flex; align-items: center; gap: 0.75rem; border: 1px solid; }
|
||||
.overall .dot { width: 12px; height: 12px; border-radius: 50%; flex-shrink: 0; animation: pulse-dot 2s ease-in-out infinite; }
|
||||
@keyframes pulse-dot { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }
|
||||
.group-title { font-size: 0.85rem; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: 0.05em; margin: 2rem 0 0.75rem; }
|
||||
.group-section { margin: 1.5rem 0; background: var(--card); border: 1px solid var(--border); border-radius: 10px; overflow: hidden; }
|
||||
.group-toggle { display: none; }
|
||||
.group-header { display: flex; align-items: center; justify-content: space-between; padding: 0.75rem 1.25rem; cursor: pointer; }
|
||||
.group-header:hover { background: rgba(255,255,255,0.02); }
|
||||
.group-header-left { display: flex; align-items: center; gap: 0.5rem; }
|
||||
.group-chev { color: var(--muted); transition: transform 0.15s; flex-shrink: 0; }
|
||||
.group-toggle:checked ~ .group-header .group-chev { transform: rotate(90deg); }
|
||||
.group-name { font-size: 0.85rem; font-weight: 600; color: var(--fg); }
|
||||
.group-status { font-size: 0.75rem; font-weight: 600; }
|
||||
.group-body { display: none; padding: 0 0.75rem 0.75rem; }
|
||||
.group-toggle:checked ~ .group-body { display: block; }
|
||||
.group-body .monitors { gap: 0.35rem; }
|
||||
.group-body .monitor { border-radius: 8px; }
|
||||
.monitors { display: flex; flex-direction: column; gap: 0.5rem; }
|
||||
/* All monitors share one structure: a clickable header row + a collapsible
|
||||
detail panel. display_mode just controls whether `expanded-state` is set
|
||||
|
||||
@@ -181,12 +181,29 @@
|
||||
return d.toLocaleString(undefined, { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' });
|
||||
}
|
||||
%>
|
||||
<% groupOrder.forEach(function(gid) {
|
||||
<% groupOrder.forEach(function(gid, gi) {
|
||||
const list = grouped[gid];
|
||||
if (!list || list.length === 0) return;
|
||||
const groupName = gid ? (groups.find(g => g.id === gid)?.name || '') : '';
|
||||
// Aggregate status for the group header
|
||||
const activeInGroup = list.filter(m => m.current_state !== 'paused');
|
||||
const downInGroup = activeInGroup.filter(m => m.current_state === 'down').length;
|
||||
const groupStatus = activeInGroup.length === 0 ? 'unknown' : downInGroup === activeInGroup.length ? 'down' : downInGroup > 0 ? 'degraded' : 'up';
|
||||
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)';
|
||||
%>
|
||||
<% if (groupName) { %><div class="group-title"><%= groupName %></div><% } %>
|
||||
<% if (groupName) { %>
|
||||
<div class="group-section">
|
||||
<input type="checkbox" class="group-toggle" id="g-<%= gi %>" checked>
|
||||
<label class="group-header" for="g-<%= gi %>">
|
||||
<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>
|
||||
<span class="group-name"><%= groupName %></span>
|
||||
</div>
|
||||
<span class="group-status" style="color: <%= groupStatusColor %>;"><%= groupStatusLabel %></span>
|
||||
</label>
|
||||
<div class="group-body">
|
||||
<% } %>
|
||||
<div class="monitors">
|
||||
<% list.forEach(function(m) {
|
||||
const buckets = m.buckets || [];
|
||||
@@ -233,6 +250,10 @@
|
||||
</div>
|
||||
<% }); %>
|
||||
</div>
|
||||
<% if (groupName) { %>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
<% }); %>
|
||||
|
||||
<% if (incidents.recent.length > 0) { %>
|
||||
|
||||
Reference in New Issue
Block a user