feat(display): add compact QUIC and host health views

This commit is contained in:
justme committed 2026-10-10 03:00:23 +08:00
1 parent b964dc2bbc
commit b25b111134
14 files changed
+921 -251

No files matched your search

+1 -1
View File
@@ -257,7 +257,7 @@ export function AgentDetail() {
<dt>控制端口</dt>
<dd className="mono">{a.probe_tcp_port}/tcp</dd>
<dt>数据端口</dt>
<dd className="mono">{a.probe_udp_ports.map((p) => `${p}/udp`).join(', ') || '—'}</dd>
<dd className="mono">{a.probe_quic_ports.map((p) => `${p}/udp (QUIC)`).join(', ') || '—'}</dd>
<dt>版本</dt>
<dd>{a.agent_version ?? '—'}</dd>
<dt>展示页可见</dt>
+12 -2
View File
@@ -17,8 +17,10 @@ import { OwnerPicker } from './OwnerPicker'
*/
function LinkMatrix() {
const matrix = useQuery(() => api.get<LinkMatrixDto>('/api/admin/links'), [], 8000)
const probeState = useQuery(() => api.get<Page<ProbeDto>>('/api/admin/probes'), [], 8000)
const { busy, run } = useAction()
const items = matrix.data?.items ?? []
const onlineByProbe = new Map((probeState.data?.items ?? []).map((probe) => [probe.id, probe.online]))
const probes = [...new Map(items.map((i) => [i.probe_id, i.probe_name])).entries()]
const agents = [...new Map(items.map((i) => [i.agent_id, i.agent_name])).entries()]
const cell = (probeId: string, agentId: string) => items.find((i) => i.probe_id === probeId && i.agent_id === agentId)
@@ -58,12 +60,20 @@ function LinkMatrix() {
{agents.map(([agentId]) => {
const link = cell(probeId, agentId)
if (!link) return <td key={agentId} />
const probeOnline = onlineByProbe.get(probeId)
const tone = link.connected ? 'ok' : link.linked ? 'warn' : ''
const text = link.connected ? '已连接' : link.linked ? '待连接' : '不连'
const text = link.connected ? '已连接' : !link.linked ? '不连' : probeOnline === false ? 'Probe 离线' : '待连接'
const statusHint = link.connected
? 'Probe 已和 Agent 建立测量会话'
: !link.linked
? '这条线路已关闭'
: probeOnline === false
? 'Probe 当前没有连接到面板;Probe 上线后才会尝试连接 Agent'
: '线路已启用,等待 Probe 与 Agent 建立测量会话'
return (
<td key={agentId}>
<span className="row" style={{ gap: 6 }}>
<button type="button" className="btn small" disabled={busy} title={link.linked ? '点一下:手动关闭' : '点一下:手动开启'} onClick={() => set(link, !link.linked)}>
<button type="button" className="btn small" disabled={busy} title={`${statusHint}。点一下${link.linked ? '手动关闭' : '手动开启'}线路`} onClick={() => set(link, !link.linked)}>
<Chip tone={tone}>{text}</Chip>
</button>
{link.override !== null && link.override !== undefined ? (