fix(ui): убрать выдуманные измерения из карты сети

This commit is contained in:
Denozordec committed 2026-10-01 01:46:29 +07:00
1 parent 329d6b82f7
commit e47e2b4029
7 files changed
+100 -37

No files matched your search

+26 -23
View File
@@ -94,7 +94,7 @@ function mapBackendRowToServer(s: BackendServerRow): Server {
os: s.os ?? "—",
enabled: s.enabled,
status: s.status ?? "unknown",
latency: s.latency != null ? Math.round(s.latency) : null,
latency: s.latency ?? null,
sessions: s.sessions ?? 0,
comment: s.comment || undefined,
lanSubnet: s.lanSubnet || undefined,
@@ -157,11 +157,13 @@ function makeApiFetch(backendUrl: string) {
}
}
function fmtMB(mb: number): string {
function fmtMB(mb: number | null): string {
if(mb==null)return "—"
if (mb >= 1024) return `${(mb / 1024).toFixed(mb >= 10240 ? 0 : 1)} ГБ`
return `${mb} МБ`
return Number(mb.toFixed(2))+" МБ"
}
function fmtUptime(sec: number): string {
function fmtUptime(sec: number | null): string {
if(sec==null)return "—"
const d = Math.floor(sec / 86400)
const h = Math.floor((sec % 86400) / 3600)
const m = Math.floor((sec % 3600) / 60)
@@ -174,7 +176,8 @@ function resBarColor(pct: number): string {
if (pct >= 70) return "bg-amber-500"
return "bg-emerald-500"
}
function resPctColor(pct: number): string {
function resPctColor(pct: number | null): string {
if(pct==null)return "text-muted-foreground"
if (pct >= 85) return "text-red-400"
if (pct >= 70) return "text-amber-400"
return "text-emerald-400"
@@ -427,7 +430,7 @@ function drawableServiceEdges(
// ─── Helpers ──────────────────────────────────────────────────────────────────
function pingColor(ms: number | null) {
if (ms == null) return "#f87171"
if (ms == null) return "var(--muted-foreground)"
if (ms < 15) return "#4ade80"
if (ms < 50) return "#fbbf24"
return "#fb923c"
@@ -1270,7 +1273,7 @@ function NetworkMapContent() {
[mapServers, mapGreTunnels, greResolvedMap],
)
const wanJhEdges = useMemo(() => buildWanJhEdges(mapServers), [mapServers])
const srvResMap = useMemo(() => buildServerResourceMap(mapServers), [mapServers])
const srvResMap = useMemo(() => buildServerResourceMap(mapServers, !useLiveData), [mapServers,useLiveData])
const homeRouters = useMemo(
() => mapServers.filter((s) => s.type === "home-router"),
[mapServers],
@@ -1522,12 +1525,12 @@ function NetworkMapContent() {
const widx = greSourceWanIndexOnMap(g.fromServer, g.tunnel, greResolvedMap)
if (widx == null) continue
const spGre = speedProbeByTunnelId.get(greEdgeKey(g))
const merged = mergeGreMetricsWithSpeedProbe(spGre, greTunnelProbe(g.tunnel))
const merged = mergeGreMetricsWithSpeedProbe(spGre, greTunnelProbe(g.tunnel,!useLiveData))
if (!merged.hasSpeedMonitor) continue
s.add(`${g.fromServer.id}\t${widx}\t${g.toServer.id}`)
}
return s
}, [greEdges, speedProbeByTunnelId, greResolvedMap])
}, [greEdges, speedProbeByTunnelId, greResolvedMap,useLiveData])
/** WAN→JH: скрываем саму линию, если тот же отрезок уже отрисован GRE (одна связь на карте). */
const suppressWanJhLineDuplicate = useMemo(() => {
@@ -1559,7 +1562,7 @@ function NetworkMapContent() {
const e = edgeByTunnel.get(tid)
if (!e) return -1
const sp = speedProbeByTunnelId.get(tid)
const m = mergeGreMetricsWithSpeedProbe(sp, greTunnelProbe(e.tunnel))
const m = mergeGreMetricsWithSpeedProbe(sp, greTunnelProbe(e.tunnel,!useLiveData))
let r = m.hasSpeedMonitor ? 1000 : 0
r += m.pingMs ?? 0
return r
@@ -1574,7 +1577,7 @@ function NetworkMapContent() {
}
}
return new Set(winners.values())
}, [greEdges, speedProbeByTunnelId])
}, [greEdges, speedProbeByTunnelId,useLiveData])
/** Несколько GRE между одной парой узлов — смещаем бейджи по дуге и по нормали, без наложения. */
const greBadgeStaggerByTunnelId = useMemo(() => {
@@ -2235,7 +2238,7 @@ function NetworkMapContent() {
fromN && toN &&
!isVisible(fromN) &&
!isVisible(toN)
const baseProbe = greTunnelProbe(e.tunnel)
const baseProbe = greTunnelProbe(e.tunnel,!useLiveData)
const spGre = speedProbeByTunnelId.get(edgeId)
const merged = mergeGreMetricsWithSpeedProbe(spGre, baseProbe)
const rttFromMonitor = spGre?.lastPingRttMs != null
@@ -2845,7 +2848,7 @@ function NetworkMapContent() {
const selectedEdgeId = greEdgeKey(edge)
const localWanName = ifaceNameForGreOuterIp(edge.fromServer, t.localAddress, greResolvedMap)
const remoteWanName = ifaceNameForGreOuterIp(edge.toServer, t.remoteAddress, greResolvedMap)
const baseProbe = greTunnelProbe(t)
const baseProbe = greTunnelProbe(t,!useLiveData)
const spGr = speedProbeByTunnelId.get(selectedEdgeId)
const merged = mergeGreMetricsWithSpeedProbe(spGr, baseProbe)
const rttMon = spGr?.lastPingRttMs != null
@@ -3369,7 +3372,7 @@ function NetworkMapContent() {
fromServer && toServer
? `${fromServer.id}|${toServer.id}|${t.id}|${t.localAddress}|${t.remoteAddress}`
: `${t.serverId}|${t.id}|${t.localAddress}|${t.remoteAddress}`
const baseProbe = greTunnelProbe(t)
const baseProbe = greTunnelProbe(t,!useLiveData)
const groupKey = peer?.id ?? (normalizeGreEndpointAddr(t.remoteAddress) || t.remoteAddress)
const isPrimary = grePrimaryByGroupKey.get(groupKey) === t.id
const spGre =
@@ -3462,8 +3465,8 @@ function NetworkMapContent() {
const res = srvResMap[selected.id]
if (!res) return null
const cpuPct = res.cpu
const ramPct = Math.round(res.ramUsed / res.ramTotal * 100)
const hddPct = Math.round(res.hddUsed / res.hddTotal * 100)
const ramPct = res.ramUsed==null||res.ramTotal==null||res.ramTotal===0?null:Math.round(res.ramUsed/res.ramTotal*100)
const hddPct = res.hddUsed==null||res.hddTotal==null||res.hddTotal===0?null:Math.round(res.hddUsed/res.hddTotal*100)
return (
<div>
<p className="text-xs font-semibold text-muted-foreground uppercase tracking-wider mb-1">
@@ -3476,7 +3479,7 @@ function NetworkMapContent() {
)}
{res.fromPoll && (
<p className="text-[9px] text-muted-foreground mb-3 leading-snug">
CPU, RAM и uptime — с последнего poll MikroTik. Диск в опросе не передаётся, шкала условная.
Последний poll: {res.measuredAt ? new Date(res.measuredAt).toLocaleString("ru-RU") : "время неизвестно"}. Неизвестные ресурсы — «—». История CPU и диск API не передаются.
</p>
)}
@@ -3485,12 +3488,12 @@ function NetworkMapContent() {
<div className="flex items-center justify-between mb-1">
<span className="text-[10px] text-muted-foreground">CPU</span>
<span className={cn("text-[10px] font-mono font-semibold", resPctColor(cpuPct))}>
{cpuPct}%
{cpuPct==null?"—":cpuPct+"%"}
</span>
</div>
<div className="flex items-center gap-2">
<MiniBar pct={cpuPct} />
<Sparkline history={res.cpuHistory} />
{cpuPct!=null&&<MiniBar pct={cpuPct} />}
{res.cpuHistory.length>1&&<Sparkline history={res.cpuHistory} />}
</div>
</div>
@@ -3502,7 +3505,7 @@ function NetworkMapContent() {
{fmtMB(res.ramUsed)} / {fmtMB(res.ramTotal)}
</span>
</div>
<MiniBar pct={ramPct} />
{ramPct!=null&&<MiniBar pct={ramPct} />}
</div>
{/* HDD (нет в GET /api/servers — всегда условная шкала) */}
@@ -3510,7 +3513,7 @@ function NetworkMapContent() {
<div className="flex items-center justify-between mb-1">
<span className="text-[10px] text-muted-foreground">
HDD
{res.fromPoll && (
{!useLiveData && (
<span className="text-[8px] font-normal text-muted-foreground/70 ml-1">(оценка)</span>
)}
</span>
@@ -3518,7 +3521,7 @@ function NetworkMapContent() {
{fmtMB(res.hddUsed)} / {fmtMB(res.hddTotal)}
</span>
</div>
<MiniBar pct={hddPct} />
{hddPct!=null&&<MiniBar pct={hddPct} />}
</div>
{/* Misc metrics */}