web: unify Agent management and add a draggable link board

Replace Probe pages with directed Agent links, shared deployment controls and unified display data. Add node dragging, canvas pan and zoom, saved layouts, and per-direction link controls.
This commit is contained in:
justme committed 2026-10-21 11:55:50 +08:00
1 parent 016dbc2bbf
commit 15f0023614
32 files changed
+937 -1093

No files matched your search

+9 -9
View File
@@ -213,8 +213,8 @@ export function Line() {
<section className="hero line-header-surface">
<div className="line-title-row">
<h1>
{line.data?.name ?? '线路'}
{line.data ? <span className="muted line-peer-name"> → {line.data.probe_name}</span> : null}
{line.data?.dialer_name ?? '线路'}
{line.data ? <span className="muted line-peer-name"> → {line.data.name}</span> : null}
</h1>
<div className="row line-version-switch">
{IP_VERSIONS.map((v) => {
@@ -231,15 +231,15 @@ export function Line() {
</div>
{line.data ? (
<div className="row wrap line-route-meta">
<Dot tone={line.data.online && line.data.probe_connected ? 'ok' : line.data.online ? 'warn' : 'bad'} />
<span className="line-route-status">{line.data.online ? (line.data.probe_connected ? '在线' : '测量未连接') : '离线'}</span>
<Dot tone={line.data.online && line.data.dialer_connected ? 'ok' : line.data.online ? 'warn' : 'bad'} />
<span className="line-route-status">{line.data.online ? (line.data.dialer_connected ? '在线' : '测量未连接') : '离线'}</span>
<span className="row" style={{ gap: 6 }}>
<span className="faint">Agent</span>
<span className="faint">目标 Agent</span>
<NodeTag info={infos.get(line.data.agent_id)} />
</span>
<span className="row" style={{ gap: 6 }}>
<span className="faint">Probe</span>
<NodeTag info={infos.get(line.data.probe_id)} />
<span className="faint">来源 Agent</span>
<NodeTag info={infos.get(line.data.dialer_id)} />
</span>
{line.data.labels.map((x) => (
<Chip key={x}>{x}</Chip>
@@ -324,7 +324,7 @@ export function Line() {
<div className="line-jitter-pair"><span>↑ <b>{fmtMs(m['jitter.up.p95'])}</b></span><span>↓ <b>{fmtMs(m['jitter.down.p95'])}</b></span></div>
</div>
</div>
<div className="line-session-bar" title="会话计数从 Probe 本次启动开始;传输疑似丢包率不等同于 Datagram 应用丢包率,连接迁移成功率暂不采集。">
<div className="line-session-bar" title="会话计数从 来源 Agent 本次启动开始;传输疑似丢包率不等同于 Datagram 应用丢包率,连接迁移成功率暂不采集。">
<strong className="line-session-title">QUIC 会话与传输</strong>
{line.data?.quic_health ? (() => {
const h = line.data.quic_health!
@@ -338,7 +338,7 @@ export function Line() {
<span>路径 MTU <b>{fmtNum(h.path_mtu)} B</b></span>
</div>
</>
})() : <span className="line-session-empty">Probe 尚未上报会话数据</span>}
})() : <span className="line-session-empty">来源 Agent 尚未上报会话数据</span>}
</div>
</> : null}
{metricGroup !== 'quic' ? <div className="tiles">