fix: detail page updates all stats, status bar, pings table in realtime via SSE
This commit is contained in:
parent
93c3a1e84a
commit
f00c78116b
|
|
@ -265,10 +265,67 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// SSE: on ping for this monitor, fetch fresh chart
|
// Running totals for incremental stat updates
|
||||||
|
let _total = <%= pings.length %>, _up = <%= upPings.length %>;
|
||||||
|
let _latSum = <%= latencies.reduce((a,b)=>a+b,0) %>, _latCount = <%= latencies.length %>;
|
||||||
|
|
||||||
|
// SSE: update everything on ping
|
||||||
let _fetchingChart = false;
|
let _fetchingChart = false;
|
||||||
watchAccount(async (ping) => {
|
watchAccount(async (ping) => {
|
||||||
if (ping.monitor_id !== monitorId || _fetchingChart) return;
|
if (ping.monitor_id !== monitorId) return;
|
||||||
|
|
||||||
|
// Accumulate
|
||||||
|
_total++;
|
||||||
|
if (ping.up) _up++;
|
||||||
|
if (ping.latency_ms != null) { _latSum += ping.latency_ms; _latCount++; }
|
||||||
|
|
||||||
|
// Status
|
||||||
|
document.getElementById('stat-status').innerHTML = ping.up
|
||||||
|
? '<span class="text-green-400">Up</span>'
|
||||||
|
: '<span class="text-red-400">Down</span>';
|
||||||
|
document.getElementById('status-dot').innerHTML = ping.up
|
||||||
|
? '<span class="inline-block w-2.5 h-2.5 rounded-full bg-green-400 mr-2"></span>'
|
||||||
|
: '<span class="inline-block w-2.5 h-2.5 rounded-full bg-red-400 mr-2"></span>';
|
||||||
|
|
||||||
|
// Avg latency
|
||||||
|
if (_latCount > 0)
|
||||||
|
document.getElementById('stat-latency').textContent = Math.round(_latSum / _latCount) + 'ms';
|
||||||
|
|
||||||
|
// Uptime
|
||||||
|
if (_total > 0)
|
||||||
|
document.getElementById('stat-uptime').textContent = Math.round((_up / _total) * 100) + '%';
|
||||||
|
|
||||||
|
// Last ping
|
||||||
|
document.getElementById('stat-last').innerHTML = timeAgo(ping.checked_at);
|
||||||
|
|
||||||
|
// Status bar — prepend segment, cap at 60
|
||||||
|
const bar = document.getElementById('status-bar');
|
||||||
|
if (bar) {
|
||||||
|
const seg = document.createElement('div');
|
||||||
|
seg.className = `flex-1 ${ping.up ? 'bg-green-500/70' : 'bg-red-500/70'}`;
|
||||||
|
seg.title = `${new Date(ping.checked_at).toLocaleString()} — ${ping.up ? 'Up' : 'Down'}${ping.latency_ms ? ' ' + ping.latency_ms + 'ms' : ''}`;
|
||||||
|
bar.prepend(seg);
|
||||||
|
while (bar.children.length > 60) bar.removeChild(bar.lastChild);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pings table — prepend row, cap at 100
|
||||||
|
const tbody = document.getElementById('pings-table');
|
||||||
|
if (tbody) {
|
||||||
|
const tr = document.createElement('tr');
|
||||||
|
tr.className = 'hover:bg-gray-800/50';
|
||||||
|
tr.innerHTML = `
|
||||||
|
<td class="px-4 py-2">${ping.up ? '<span class="text-green-400">Up</span>' : '<span class="text-red-400">Down</span>'}</td>
|
||||||
|
<td class="px-4 py-2 text-gray-300">${ping.status_code ?? '—'}</td>
|
||||||
|
<td class="px-4 py-2 text-gray-300">${ping.latency_ms != null ? ping.latency_ms + 'ms' : '—'}</td>
|
||||||
|
<td class="px-4 py-2 text-gray-500">${timeAgo(ping.checked_at)}</td>
|
||||||
|
<td class="px-4 py-2 text-red-400/70 text-xs truncate max-w-[200px]">${ping.error ? escapeHtml(ping.error) : ''}</td>
|
||||||
|
`;
|
||||||
|
tbody.prepend(tr);
|
||||||
|
while (tbody.children.length > 100) tbody.removeChild(tbody.lastChild);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chart
|
||||||
|
if (_fetchingChart) return;
|
||||||
_fetchingChart = true;
|
_fetchingChart = true;
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/dashboard/monitors/${monitorId}/chart`, { credentials: 'same-origin' });
|
const res = await fetch(`/dashboard/monitors/${monitorId}/chart`, { credentials: 'same-origin' });
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue