fix(api): сохранить неизвестные значения истории скорости
This commit is contained in:
1 parent
e5ff69e243
commit
a558412a27
13 files changed
+119
-70
No files matched your search
+20
-35
@@ -1,5 +1,7 @@
|
||||
"use client"
|
||||
|
||||
import { speedHistoryResponseSchema } from "@mmapp/contracts"
|
||||
|
||||
import probeStyles from "./probe-rows.module.css"
|
||||
|
||||
import { Suspense, useState, useMemo, useEffect, useRef, useCallback } from "react"
|
||||
@@ -698,8 +700,8 @@ interface SpeedTestRun {
|
||||
protocol: "tcp" | "udp"
|
||||
direction: "transmit" | "receive" | "both"
|
||||
durationSec: number
|
||||
txAvgMbps: number
|
||||
rxAvgMbps: number
|
||||
txAvgMbps: number | null
|
||||
rxAvgMbps: number | null
|
||||
status: "running" | "done" | "error"
|
||||
command: string
|
||||
lines: string[]
|
||||
@@ -1164,26 +1166,6 @@ function UptimePageContent({ selectedProbeId, allProbesHref }: { selectedProbeId
|
||||
const reloadSpeedData = useCallback(async (writeContext?: number) => {
|
||||
if (!liveApi || (savingRef.current && writeContext !== saveContext.current)) return
|
||||
const context = saveContext.current
|
||||
type RunRow = {
|
||||
id: string
|
||||
srcServerId: string
|
||||
dstServerId: string
|
||||
srcInterface: string
|
||||
dstInterface: string
|
||||
protocol: "tcp" | "udp"
|
||||
direction: "transmit" | "receive" | "both"
|
||||
durationSec: number
|
||||
txAvgMbps: number
|
||||
rxAvgMbps: number
|
||||
status: "done" | "error"
|
||||
error?: string | null
|
||||
srcAddress?: string | null
|
||||
dstAddress?: string | null
|
||||
srcInterfaceAddress?: string | null
|
||||
dstInterfaceAddress?: string | null
|
||||
afterBtPing?: { rttMs: number | null; lossPct: number | null; error: string | null } | null
|
||||
createdAt: string
|
||||
}
|
||||
const revision = ++speedReadRevision.current
|
||||
const current = () => revision === speedReadRevision.current && context === saveContext.current && (!savingRef.current || writeContext === context)
|
||||
const read = async (resource: "probes" | "history", task: () => Promise<void>) => {
|
||||
@@ -1201,8 +1183,9 @@ function UptimePageContent({ selectedProbeId, allProbesHref }: { selectedProbeId
|
||||
if (current()) setSpeedProbes(sp.probes)
|
||||
}),
|
||||
read("history", async () => {
|
||||
const runsRes = await apiFetch<{ runs: RunRow[] }>("/api/uptime/speed-test/runs")
|
||||
if (!Array.isArray(runsRes.runs)) throw new Error("Некорректная история тестов")
|
||||
const result = speedHistoryResponseSchema.safeParse(await apiFetch<unknown>("/api/uptime/speed-test/runs"))
|
||||
if (!result.success) throw new Error("Некорректная история тестов скорости")
|
||||
const runsRes = result.data
|
||||
const rows = (runsRes.runs ?? []).map((r) => ({
|
||||
id: r.id,
|
||||
startedAt: Date.parse(r.createdAt),
|
||||
@@ -1213,9 +1196,9 @@ function UptimePageContent({ selectedProbeId, allProbesHref }: { selectedProbeId
|
||||
protocol: r.protocol,
|
||||
direction: r.direction,
|
||||
durationSec: r.durationSec,
|
||||
txAvgMbps: Math.round(r.txAvgMbps ?? 0),
|
||||
rxAvgMbps: Math.round(r.rxAvgMbps ?? 0),
|
||||
status: (r.status === "error" ? "error" : "done") as "error" | "done",
|
||||
txAvgMbps: r.txAvgMbps === null ? null : Math.round(r.txAvgMbps),
|
||||
rxAvgMbps: r.rxAvgMbps === null ? null : Math.round(r.rxAvgMbps),
|
||||
status: r.status,
|
||||
command: "",
|
||||
lines: r.error ? [`status: error`, r.error] : [],
|
||||
afterBtPing: r.afterBtPing ?? null,
|
||||
@@ -2121,8 +2104,10 @@ function UptimePageContent({ selectedProbeId, allProbesHref }: { selectedProbeId
|
||||
{(() => {
|
||||
const doneRuns = speedRuns.filter(r => r.status === "done")
|
||||
const runningCnt = speedRuns.filter(r => r.status === "running").length
|
||||
const maxTx = doneRuns.length ? Math.max(...doneRuns.map(r => r.txAvgMbps)) : null
|
||||
const maxRx = doneRuns.length ? Math.max(...doneRuns.map(r => r.rxAvgMbps)) : null
|
||||
const txValues = doneRuns.flatMap(r => r.txAvgMbps === null ? [] : [r.txAvgMbps])
|
||||
const maxTx = txValues.length ? Math.max(...txValues) : null
|
||||
const rxValues = doneRuns.flatMap(r => r.rxAvgMbps === null ? [] : [r.rxAvgMbps])
|
||||
const maxRx = rxValues.length ? Math.max(...rxValues) : null
|
||||
return (
|
||||
<div className="px-6 py-4 border-b bg-muted/10 shrink-0">
|
||||
<KpiStatGrid
|
||||
@@ -2223,10 +2208,10 @@ function UptimePageContent({ selectedProbeId, allProbesHref }: { selectedProbeId
|
||||
(r.srcInterface ?? "") === probe.srcInterface &&
|
||||
(r.dstInterface ?? "") === probe.dstInterface,
|
||||
)
|
||||
const viewStatus = run?.status ?? (probe.lastStatus === "error" ? "error" : probe.lastRunAt ? "done" : null)
|
||||
const viewTx = run?.txAvgMbps ?? Math.round(probe.lastTxAvgMbps ?? 0)
|
||||
const viewRx = run?.rxAvgMbps ?? Math.round(probe.lastRxAvgMbps ?? 0)
|
||||
const maxVal = Math.max(viewTx, viewRx, 1)
|
||||
const viewStatus = run?.status ?? (probe.lastStatus === "error" || probe.lastStatus === "done" ? probe.lastStatus : null)
|
||||
const viewTx = run ? run.txAvgMbps : probe.lastTxAvgMbps == null ? null : Math.round(probe.lastTxAvgMbps)
|
||||
const viewRx = run ? run.rxAvgMbps : probe.lastRxAvgMbps == null ? null : Math.round(probe.lastRxAvgMbps)
|
||||
const maxVal = Math.max(viewTx ?? 0, viewRx ?? 0, 1)
|
||||
const canRun = probe.enabled && !!probe.srcServerId && !!probe.dstServerId && probe.srcServerId !== probe.dstServerId
|
||||
const viewAfterBtPing =
|
||||
run?.status === "done" && run.afterBtPing
|
||||
@@ -2314,10 +2299,10 @@ function UptimePageContent({ selectedProbeId, allProbesHref }: { selectedProbeId
|
||||
<span className="w-8 font-semibold text-muted-foreground">{r.label}</span>
|
||||
<div className="flex-1 h-1.5 rounded-full bg-muted overflow-hidden">
|
||||
<div className={cn("h-full rounded-full", r.color)}
|
||||
style={{ width: `${Math.max((r.val / maxVal) * 100, r.val > 0 ? 3 : 0)}%` }} />
|
||||
style={{ width: `${r.val === null ? 0 : Math.max((r.val / maxVal) * 100, r.val > 0 ? 3 : 0)}%` }} />
|
||||
</div>
|
||||
<span className={cn("w-24 text-right font-mono tabular-nums font-semibold", r.textColor)}>
|
||||
{r.val} Мбит/с
|
||||
{r.val === null ? "Неизвестно" : `${r.val} Мбит/с`}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
|
||||
Reference in new issue
Block a user