feat: Live Dashboard redesign — 6 columns, hover details, last-alert column
Replaces the 11-column table with severity-sorted record rows: host, combined status chip, latency, alert chips, time-in-state, and the most recent alert message. Per-family address/state/latency/last-change move to a hover card on the status chip and permanently to a new Connectivity table in the Host Overview info section (host info API now includes connections). Last-alert is seeded from /api/0/alerts and kept fresh from the event stream; the event log below uses the same row idiom with its filters intact. WS reconnect state shows in the toolbar instead of a modal. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NfPpSpccTWBfZg1FTveyaU
This commit is contained in:
@@ -258,12 +258,25 @@ def _build_host_info(host, threshold_checker=None) -> dict:
|
||||
key=lambda x: x["metric"],
|
||||
)
|
||||
|
||||
connections = [
|
||||
{
|
||||
"family": getattr(conn, "afam", family),
|
||||
"addr": getattr(conn, "addr", ""),
|
||||
"state": getattr(conn, "state", ""),
|
||||
"rtt": (getattr(conn, "rtts", None) or [None])[0],
|
||||
"statetime": getattr(conn, "statetime", None),
|
||||
"lastbeat": getattr(conn, "lastbeat", None),
|
||||
}
|
||||
for family, conn in sorted(host.connections.items())
|
||||
]
|
||||
|
||||
return {
|
||||
"owner": getattr(host, "owner", None),
|
||||
"managers": list(getattr(host, "managers", [])),
|
||||
"hbc_version": hbc_version,
|
||||
"hbc_type": hbc_type,
|
||||
"last_packet": last_packet,
|
||||
"connections": connections,
|
||||
"thresholds": thresholds,
|
||||
}
|
||||
|
||||
|
||||
+459
-670
File diff suppressed because it is too large
Load Diff
@@ -444,6 +444,30 @@
|
||||
<span class="info-label">Last Packet</span><span class="info-value">${lastPkt}</span>
|
||||
</div>`;
|
||||
|
||||
if (data.connections && data.connections.length) {
|
||||
html += `<div class="info-thresholds-title">Connectivity</div>
|
||||
<table class="data-table"><thead><tr>
|
||||
<th>Family</th><th>Address</th><th>State</th>
|
||||
<th class="num">RTT</th><th>Last Change</th><th>Last Packet</th>
|
||||
</tr></thead><tbody>`;
|
||||
for (const c of data.connections) {
|
||||
const st = escHtml(c.state || '—');
|
||||
const stCls = c.state === 'up' ? 'status-up' : (c.state ? 'status-down' : '');
|
||||
const rtt = (c.state === 'up' && c.rtt) ? Math.round(c.rtt) + ' ms' : '—';
|
||||
const chg = c.statetime ? new Date(c.statetime * 1000).toLocaleString() : '—';
|
||||
const seen = c.lastbeat ? new Date(c.lastbeat * 1000).toLocaleString() : '—';
|
||||
html += `<tr>
|
||||
<td class="key">${escHtml(c.family)}</td>
|
||||
<td>${escHtml(c.addr || '—')}</td>
|
||||
<td><span class="${stCls}">${st}</span></td>
|
||||
<td class="num">${rtt}</td>
|
||||
<td>${chg}</td>
|
||||
<td>${seen}</td>
|
||||
</tr>`;
|
||||
}
|
||||
html += `</tbody></table>`;
|
||||
}
|
||||
|
||||
if (data.thresholds === null) {
|
||||
html += `<div class="info-note">Threshold alerting not configured.</div>`;
|
||||
} else if (data.thresholds.length === 0) {
|
||||
|
||||
Reference in New Issue
Block a user