feat(display): explain QUIC state and compact panels [CI]
This commit is contained in:
1 parent
efb50d0efe
commit
85c2043f2f
4 files changed
+101
-57
No files matched your search
@@ -141,8 +141,18 @@ function NodeCard({ node, labels, infos }: { node: HostItem; labels: string[]; i
|
||||
function LineCard({ l, range, infos }: { l: OverviewLineDto; range: OverviewRange; infos: Map<string, NodeInfoDto> }) {
|
||||
const probeInfo = infos.get(l.probe_id)
|
||||
const agentInfo = infos.get(l.agent_id)
|
||||
const rangeLabel = OVERVIEW_RANGES.find((r) => r.value === range)?.label ?? range
|
||||
const connectionIssue = !l.online
|
||||
? 'Agent 离线'
|
||||
: l.quic_health?.state === 'retry_wait'
|
||||
? 'QUIC 拨号失败'
|
||||
: !l.probe_connected
|
||||
? '测量通道未建立'
|
||||
: l.quic_health && !l.quic_health.connected
|
||||
? 'QUIC 正在连接'
|
||||
: null
|
||||
return (
|
||||
<Link to={`/line/${encodeURIComponent(l.id)}`} className="line-link line-card">
|
||||
<Link to={`/line/${encodeURIComponent(l.id)}`} className={`line-link line-card${connectionIssue ? ' disconnected' : ''}`}>
|
||||
<div className="line-top">
|
||||
<span className="line-name" title={[l.probe_name, probeInfo?.tag || probeInfo?.version].filter(Boolean).join(' · ')}>
|
||||
{probeInfo?.country ? <Flag code={probeInfo.country} /> : null}
|
||||
@@ -152,13 +162,12 @@ function LineCard({ l, range, infos }: { l: OverviewLineDto; range: OverviewRang
|
||||
{agentInfo?.country ? <Flag code={agentInfo.country} /> : null}
|
||||
<span className="name">{l.name}</span>
|
||||
</span>
|
||||
{!l.probe_connected && l.online ? (
|
||||
<span title="Agent 在线,但这个 Probe 没能和它建立测量会话(控制通道连不上或握手超时)。机器本身可能是通的、ping 也能通,这里说的是测量用的 TCP 控制通道和 QUIC Datagram 数据通道,线路或运营商对它们的处理可能和 ping 不一样。">
|
||||
<Chip tone="warn">测量通道未建立</Chip>
|
||||
</span>
|
||||
) : (
|
||||
<span className="faint line-range">{OVERVIEW_RANGES.find((r) => r.value === range)?.label ?? range}</span>
|
||||
)}
|
||||
<span
|
||||
className={connectionIssue ? 'line-range disconnected-label' : 'faint line-range'}
|
||||
title={l.quic_health?.state === 'retry_wait' ? `Probe 正在等待退避重试${l.quic_health.retry_in_ms ? `(约 ${Math.ceil(l.quic_health.retry_in_ms / 1000)} 秒)` : ''}。` : !l.probe_connected && l.online ? 'Agent 在线,但 Probe 尚未建立测量会话。' : undefined}
|
||||
>
|
||||
{connectionIssue ? `${connectionIssue} · ${rangeLabel}` : rangeLabel}
|
||||
</span>
|
||||
</div>
|
||||
<LineStrips lineId={l.id} range={range} m={l.summary.metrics} />
|
||||
</Link>
|
||||
@@ -254,7 +263,7 @@ export function Overview() {
|
||||
<IpVersionPicker value={ipVersion} onChange={(v) => { const next = new URLSearchParams(params); next.set('ip_version', v); setCarrier(''); setParams(next, { replace: true }) }} />
|
||||
{groups.length > 1 ? <Segmented<'' | CarrierKey> options={[{ value: '', label: '全部' }, ...groups.map((g) => ({ value: g.key, label: g.name }))]} value={carrier} onChange={setCarrier} /> : null}
|
||||
<span className="right row">
|
||||
<Segmented<OverviewRange> options={OVERVIEW_RANGES.map((r) => ({ value: r.value, label: `近 ${r.label}` }))} value={range} onChange={setRange} />
|
||||
<Segmented<OverviewRange> options={OVERVIEW_RANGES.map((r) => ({ value: r.value, label: r.label }))} value={range} onChange={setRange} />
|
||||
<Segmented
|
||||
options={[
|
||||
{ value: 'name' as const, label: '名称' },
|
||||
|
||||
Reference in new issue
Block a user