feat: UI improvements — event ages, error badges, PoE bars, mismatch detection
- events table: add Last Seen column; show relative times ("3h ago") with
absolute timestamp on hover; update updateEventsTable() in app.js to match
- links.html: add error/drop/flap alert badges to interface and port card headers
- links.html: PoE power bar (draw/max ratio with colour-coded fill) and poe_mode
- links.html: stale data warning banner when link_stats are >2 minutes old
- links.html: improved error handler shows HTTP status instead of generic message
- links.html: fix collapse state persisted to localStorage (was sessionStorage,
lost on browser restart); fix collapseAll/expandAll to also persist state
- inspector.html: duplex mismatch and speed mismatch warnings in path debug panel
- inspector.html: carrier changes added to server column of path debug
- style.css: new classes — .link-alert-badge, .poe-bar-*, .path-mismatch-alert,
.error-state; fix .stale-banner to use CSS variables
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -326,8 +326,25 @@ function buildPathDebug(swName, swPort, serverName, ifaceName, svrData) {
|
||||
const swErrTx = (swPort.tx_errs_rate > 0.001) ? 'val-crit' : 'val-good';
|
||||
const swErrRx = (swPort.rx_errs_rate > 0.001) ? 'val-crit' : 'val-good';
|
||||
|
||||
// Detect duplex mismatch (switch full_duplex vs server duplex string)
|
||||
const swFull = swPort.full_duplex;
|
||||
const svrFull = (svrData.duplex || '').toLowerCase().includes('full');
|
||||
const duplexMismatch = swPort.up && svrData.duplex &&
|
||||
((swFull && !svrFull) || (!swFull && svrFull));
|
||||
const duplexWarnHtml = duplexMismatch
|
||||
? `<div class="path-mismatch-alert">⚠ DUPLEX MISMATCH — Switch: ${swFull ? 'Full' : 'Half'} · Server: ${escHtml(svrData.duplex)}</div>`
|
||||
: '';
|
||||
|
||||
// Detect speed mismatch
|
||||
const swSpd = swPort.speed_mbps, svrSpd = svrData.speed_mbps;
|
||||
const speedMismatch = swSpd && svrSpd && swSpd > 0 && svrSpd > 0 && swSpd !== svrSpd;
|
||||
const speedWarnHtml = speedMismatch
|
||||
? `<div class="path-mismatch-alert">⚠ SPEED MISMATCH — Switch: ${fmtSpeed(swSpd)} · Server: ${fmtSpeed(svrSpd)}</div>`
|
||||
: '';
|
||||
|
||||
return `
|
||||
<div class="panel-section-title">Path Debug <span class="path-conn-type">${escHtml(connType)}</span></div>
|
||||
${duplexWarnHtml}${speedWarnHtml}
|
||||
<div class="path-debug-cols">
|
||||
<div class="path-col">
|
||||
<div class="path-col-header">Switch</div>
|
||||
@@ -347,6 +364,7 @@ function buildPathDebug(swName, swPort, serverName, ifaceName, svrData) {
|
||||
<div class="path-row"><span>RX</span><span>${fmtRate(svrData.rx_bytes_rate)}</span></div>
|
||||
<div class="path-row"><span>TX Err</span><span class="${svrErrTx}">${fmtErrors(svrData.tx_errs_rate)}</span></div>
|
||||
<div class="path-row"><span>RX Err</span><span class="${svrErrRx}">${fmtErrors(svrData.rx_errs_rate)}</span></div>
|
||||
${svrData.carrier_changes != null ? `<div class="path-row"><span>Carrier Chg</span><span class="${(svrData.carrier_changes||0)>10?'val-crit':(svrData.carrier_changes||0)>2?'val-warn':'val-good'}">${svrData.carrier_changes}</span></div>` : ''}
|
||||
${sfpDomHtml}
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
Reference in New Issue
Block a user