feat: node detail page shows its own configured scope, not just transported

The Transported Scopes row shows regions a repeater has relayed for
OTHERS, but not what the node's own hashRegions scope actually is --
dborup asked for that distinction to be visible too. Added an "Own
scope" row right above it, for any node (not just repeater/room --
any node can configure its own scope). Mirrors live.js's existing
null (no schema support) / empty ("unknown scope") / value
distinction for default_scope.
This commit is contained in:
dborup
2026-07-26 09:28:50 +02:00
parent 1aaa044666
commit 04cb9c955f
+1
View File
@@ -679,6 +679,7 @@
const btooltip = "Normalized betweenness centrality (0..1). How often this node sits on the shortest path between other pairs of nodes in the affinity graph. 1.0 = the most structurally critical node on the mesh. High Bridge + low Traffic share = a quiet but irreplaceable chokepoint.";
return `<tr id="row-bridge-score" data-bridge-score="${b.toFixed(4)}"><td title="${btooltip}">Bridge score <span style="color:var(--text-muted);cursor:help" aria-label="help">ⓘ</span></td><td><span style="display:inline-block;vertical-align:middle;width:80px;height:8px;background:var(--bg-secondary,#333);border-radius:4px;overflow:hidden;margin-right:6px"><span style="display:block;width:${bbarWidth}%;height:100%;background:${bcolor}"></span></span><span style="color:${bcolor};font-weight:600">${bpct}%</span> <span style="color:var(--text-muted);font-size:11px;margin-left:4px">${blabel}</span></td></tr>`;
})() : ''}
${'default_scope' in n ? `<tr id="row-own-scope"><td title="This node's own configured region scope (hashRegions) — set in its own adverts. Distinct from Transported scopes below, which are regions this node has relayed for OTHER nodes.">Own scope</td><td>${n.default_scope === null ? '<span class="text-muted">—</span>' : n.default_scope === '' ? '<span class="text-muted">unknown scope</span>' : '<span class="badge">' + escapeHtml(n.default_scope) + '</span>'}</td></tr>` : ''}
${(n.role === 'repeater' || n.role === 'room') && Array.isArray(n.transported_scopes) && n.transported_scopes.length ? `<tr id="row-transported-scopes"><td title="Distinct region scopes (transmissions.scope_name) of all non-advert packets in which this repeater appears as a path hop. Shows which regions' traffic this repeater has carried (#1751).">Transported scopes</td><td><span style="display:inline-flex;flex-wrap:wrap;gap:3px;vertical-align:middle">${n.transported_scopes.map(sc => '<span class="badge">' + escapeHtml(String(sc)) + '</span>').join('')}</span></td></tr>` : ''}
<tr><td>First Seen</td><td>${renderNodeTimestampHtml(n.first_seen)}</td></tr>
<tr><td>Total Packets</td><td>${stats.totalTransmissions || stats.totalPackets || n.advert_count || 0}${stats.totalObservations && stats.totalObservations !== (stats.totalTransmissions || stats.totalPackets) ? ' <span class="text-muted" style="font-size:0.85em">(seen ' + stats.totalObservations + '×)</span>' : ''}</td></tr>