feat: combine status blips by run id
This commit is contained in:
parent
eae2b3869d
commit
6f0499d34b
|
|
@ -9,7 +9,19 @@
|
||||||
const latencies = pings.filter(p => p.latency_ms != null).map(p => p.latency_ms);
|
const latencies = pings.filter(p => p.latency_ms != null).map(p => p.latency_ms);
|
||||||
const avgLatency = latencies.length ? Math.round(latencies.reduce((a, b) => a + b, 0) / latencies.length) : null;
|
const avgLatency = latencies.length ? Math.round(latencies.reduce((a, b) => a + b, 0) / latencies.length) : null;
|
||||||
const uptime = pings.length ? Math.round((upPings.length / pings.length) * 100) : null;
|
const uptime = pings.length ? Math.round((upPings.length / pings.length) * 100) : null;
|
||||||
const barPings = pings.slice(0, 60).reverse();
|
// Group pings by run_id for status bar
|
||||||
|
const barRuns = [];
|
||||||
|
const runMap = {};
|
||||||
|
for (const p of pings.slice(0, 120).reverse()) {
|
||||||
|
const rid = p.run_id || p.checked_at;
|
||||||
|
if (!runMap[rid]) {
|
||||||
|
runMap[rid] = { run_id: rid, up: 0, down: 0, checked_at: p.checked_at, latency_ms: p.latency_ms };
|
||||||
|
barRuns.push(runMap[rid]);
|
||||||
|
}
|
||||||
|
if (p.up) runMap[rid].up++; else runMap[rid].down++;
|
||||||
|
}
|
||||||
|
// Keep last 60 runs
|
||||||
|
const barPings = barRuns.slice(-60);
|
||||||
const chartPings = pings.slice().reverse();
|
const chartPings = pings.slice().reverse();
|
||||||
%>
|
%>
|
||||||
|
|
||||||
|
|
@ -80,8 +92,11 @@
|
||||||
<h3 class="text-sm text-gray-400 mb-3">Status History</h3>
|
<h3 class="text-sm text-gray-400 mb-3">Status History</h3>
|
||||||
<div id="status-bar" class="flex gap-0.5 h-8 rounded-lg overflow-hidden">
|
<div id="status-bar" class="flex gap-0.5 h-8 rounded-lg overflow-hidden">
|
||||||
<% if (barPings.length > 0) { %>
|
<% if (barPings.length > 0) { %>
|
||||||
<% barPings.forEach(function(c) { %>
|
<% barPings.forEach(function(c) {
|
||||||
<div class="flex-1 rounded-sm <%= c.up ? 'bg-green-500/70' : 'bg-red-500/70' %>" title="<%= new Date(c.checked_at).toLocaleString() %> — <%= c.up ? 'Up' : 'Down' %> <%= c.latency_ms ? c.latency_ms + 'ms' : '' %>"></div>
|
const color = c.down === 0 ? 'bg-green-500/70' : (c.up === 0 ? 'bg-red-500/70' : 'bg-orange-400/70');
|
||||||
|
const label = c.down === 0 ? 'Up' : (c.up === 0 ? 'Down' : 'Partial');
|
||||||
|
%>
|
||||||
|
<div class="flex-1 rounded-sm <%= color %>" data-run="<%= c.run_id %>" data-up="<%= c.up %>" data-down="<%= c.down %>" title="<%= new Date(c.checked_at).toLocaleString() %> — <%= label %>"></div>
|
||||||
<% }) %>
|
<% }) %>
|
||||||
<% } else { %>
|
<% } else { %>
|
||||||
<div class="flex-1 bg-gray-800/50 text-center text-xs text-gray-600 leading-8 rounded-lg">No data</div>
|
<div class="flex-1 bg-gray-800/50 text-center text-xs text-gray-600 leading-8 rounded-lg">No data</div>
|
||||||
|
|
@ -479,14 +494,31 @@
|
||||||
// Last ping
|
// Last ping
|
||||||
document.getElementById('stat-last').innerHTML = timeAgo(ping.checked_at);
|
document.getElementById('stat-last').innerHTML = timeAgo(ping.checked_at);
|
||||||
|
|
||||||
// Status bar — prepend segment, cap at 60
|
// Status bar — group by run_id, cap at 60
|
||||||
const bar = document.getElementById('status-bar');
|
const bar = document.getElementById('status-bar');
|
||||||
if (bar) {
|
if (bar) {
|
||||||
const seg = document.createElement('div');
|
const rid = ping.run_id || ping.checked_at;
|
||||||
seg.className = `flex-1 rounded-sm ${ping.up ? 'bg-green-500/70' : 'bg-red-500/70'}`;
|
let existing = bar.querySelector(`[data-run="${rid}"]`);
|
||||||
seg.title = `${new Date(ping.checked_at).toLocaleString()} — ${ping.up ? 'Up' : 'Down'}${ping.latency_ms ? ' ' + ping.latency_ms + 'ms' : ''}`;
|
if (existing) {
|
||||||
bar.prepend(seg);
|
// Update existing run segment
|
||||||
while (bar.children.length > 60) bar.removeChild(bar.lastChild);
|
const up = parseInt(existing.dataset.up || '0') + (ping.up ? 1 : 0);
|
||||||
|
const down = parseInt(existing.dataset.down || '0') + (ping.up ? 0 : 1);
|
||||||
|
existing.dataset.up = up;
|
||||||
|
existing.dataset.down = down;
|
||||||
|
const color = down === 0 ? 'bg-green-500/70' : (up === 0 ? 'bg-red-500/70' : 'bg-orange-400/70');
|
||||||
|
const label = down === 0 ? 'Up' : (up === 0 ? 'Down' : 'Partial');
|
||||||
|
existing.className = `flex-1 rounded-sm ${color}`;
|
||||||
|
existing.title = `${new Date(ping.checked_at).toLocaleString()} — ${label}`;
|
||||||
|
} else {
|
||||||
|
const seg = document.createElement('div');
|
||||||
|
seg.className = `flex-1 rounded-sm ${ping.up ? 'bg-green-500/70' : 'bg-red-500/70'}`;
|
||||||
|
seg.dataset.run = rid;
|
||||||
|
seg.dataset.up = ping.up ? '1' : '0';
|
||||||
|
seg.dataset.down = ping.up ? '0' : '1';
|
||||||
|
seg.title = `${new Date(ping.checked_at).toLocaleString()} — ${ping.up ? 'Up' : 'Down'}`;
|
||||||
|
bar.appendChild(seg);
|
||||||
|
while (bar.children.length > 60) bar.removeChild(bar.firstChild);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pings table — prepend row, cap at 100
|
// Pings table — prepend row, cap at 100
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue