fix(dashboard): web clients sit right of the dashboard on the Network page

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Aaron Kimbrell
2026-09-29 18:38:17 -05:00
parent c9774173bb
commit 6a59da1748
3 changed files with 10 additions and 10 deletions

View File

@@ -13,7 +13,7 @@
(function (root) {
'use strict';
var COLUMNS = [0, 1, 2, 3]; // clients | auth, chat, worlds, others | master | dashboard, UGC
var COLUMNS = [0, 1, 2, 3, 4]; // game clients | auth, chat, worlds, others | master | dashboard, UGC | web clients
function num(v) { return typeof v === 'number' && isFinite(v) ? v : 0; }
function rates(r) { r = r || {}; return { packets_in: num(r.packets_in), packets_out: num(r.packets_out), bytes_in: num(r.bytes_in), bytes_out: num(r.bytes_out) }; }
@@ -68,7 +68,7 @@
}
var clients = node({ id: 'clients', kind: 'clients', label: 'Game clients', column: 0, order: 0 });
var web = node({ id: 'web', kind: 'web', label: 'Web clients', column: 0, order: 10 });
var web = node({ id: 'web', kind: 'web', label: 'Web clients', column: 4, order: 0 });
var hasChat = keys.some(function (k) { return servers[k].type === 'CHAT'; });
keys.forEach(function (key) {
@@ -144,7 +144,7 @@
if (shownOfKind >= limit) return;
var id = 'peer:' + peer.address;
var who = peer.character || peer.account || peer.address;
var p = node({ id: id, kind: 'peer', label: who, column: 0, order: (peer.kind === 'game' ? 0.1 : 10.1) + shownOfKind / 100 });
var p = node({ id: id, kind: 'peer', label: who, column: peer.kind === 'game' ? 0 : 4, order: 0.1 + shownOfKind / 100 });
p.peer = peer;
(peer.servers || []).forEach(function (entry) {
var target = servers[entry.server];
@@ -191,13 +191,13 @@
* Returns {width, height, nodeWidth, nodeHeight, nodes: {id: {x, y}}, paths: {edgeId: {fwd, back}}}.
*/
function layout(graph, totalWidth) {
var nodeWidth = Math.max(110, Math.min(170, Math.floor(totalWidth / 5.2))), nodeHeight = 54, rowHeight = 74, pad = 16;
var nodeWidth = Math.max(110, Math.min(170, Math.floor(totalWidth / 6.4))), nodeHeight = 54, rowHeight = 74, pad = 16;
var byColumn = COLUMNS.map(function () { return []; });
graph.nodes.forEach(function (n) { byColumn[n.column].push(n); });
var rows = Math.max.apply(null, byColumn.map(function (c) { return c.length; }).concat([1]));
var height = rows * rowHeight + pad * 2;
var usable = totalWidth - nodeWidth - pad * 2;
var xs = [0, 0.36, 0.68, 1].map(function (f) { return Math.round(pad + nodeWidth / 2 + f * usable); });
var xs = [0, 0.28, 0.54, 0.78, 1].map(function (f) { return Math.round(pad + nodeWidth / 2 + f * usable); });
var at = {};
byColumn.forEach(function (column, c) {
var step = (height - pad * 2) / Math.max(column.length, 1);

View File

@@ -735,9 +735,9 @@ How it is counted:
### Network
**Network** (`health_view`, next to Diagnostics) draws the traffic live, from the same reports: game clients and web
clients on the left, auth, chat, the worlds (one box per zone; + shows each instance) and any other server that reports
in the middle, master, the dashboard and the UGC server on the right. Servers appear as they report, so a new kind of
**Network** (`health_view`, next to Diagnostics) draws the traffic live, from the same reports: game clients on the
left, auth, chat, the worlds (one box per zone; + shows each instance) and any other server that reports in the middle,
then master, then the dashboard and the UGC server, and web clients (browsers and API users) right of the dashboard. Servers appear as they report, so a new kind of
server shows up without changes. Each link has a lane each way, as thick as its bytes per second, with dashes moving
faster with more packets, and coloured by its load against its own peak over the last 5 minutes; hover it for the
numbers. Boxes show connections, average ping, resends, busy workers and live dashboard pages. Clicking a box shows its

View File

@@ -39,7 +39,7 @@ const summary = {
const graph = G.build(summary, {});
const ids = graph.nodes.map((n) => n.id);
same(ids, ['clients', 'web', 'auth', 'chat', 'zone:1200', 'service:99:0:0', 'master', 'dashboard', 'ugc'], 'nodes in column order, one per zone');
same(ids, ['clients', 'auth', 'chat', 'zone:1200', 'service:99:0:0', 'master', 'dashboard', 'ugc', 'web'], 'nodes in column order, one per zone');
const edge = (id) => graph.edges.find((e) => e.id === id);
same(edge('clients>zone:1200').fwd, { packets: 27, bytes: 2700 }, 'players to the zone: both instances');
@@ -85,7 +85,7 @@ same(G.speed(1e6) < G.speed(1), true, 'busier moves faster');
// Layout: columns left to right, every link a path each way
const L = G.layout(graph, 1000);
same(L.nodes.clients.x < L.nodes.auth.x && L.nodes.auth.x < L.nodes.master.x && L.nodes.master.x < L.nodes.dashboard.x, true, 'columns');
same(L.nodes.clients.x < L.nodes.auth.x && L.nodes.auth.x < L.nodes.master.x && L.nodes.master.x < L.nodes.dashboard.x && L.nodes.dashboard.x < L.nodes.web.x, true, 'columns, web clients right of the dashboard');
same(graph.edges.every((e) => L.paths[e.id] && /^M/.test(L.paths[e.id].fwd) && /^M/.test(L.paths[e.id].back)), true, 'paths');
same(G.layout(graph, 1000), L, 'the same layout every time');