fix(traffic): сохранять историю и показывать достоверную свежесть

This commit is contained in:
Denozordec committed 2026-10-12 20:23:07 +07:00
1 parent ebe62ae2ef
commit 1275dd7b9b
48 files changed
+1899 -187

No files matched your search

+3 -3
View File
@@ -1,14 +1,14 @@
import { Fragment } from "react"
/** Compact RX/TX history shared by traffic cards. Gaps remain gaps. */
export function TrafficMiniChart({ rx, tx, height = 44 }: { rx: number[]; tx: number[]; height?: number }) {
const valid = (value: number) => Number.isFinite(value) && value >= 0
export function TrafficMiniChart({ rx, tx, height = 44 }: { rx: (number|null)[]; tx: (number|null)[]; height?: number }) {
const valid = (value: number|null): value is number => value !== null && Number.isFinite(value) && value >= 0
const values = [...rx, ...tx].filter(valid)
if (!values.length) return <p className="text-xs text-muted-foreground">Нет истории трафика</p>
const width = 300
const count = Math.max(rx.length, tx.length)
const max = Math.max(...values, 1) * 1.1
const segments = (series: number[]) => {
const segments = (series: (number|null)[]) => {
const result: Array<Array<{ x: number; y: number }>> = []
let current: Array<{ x: number; y: number }> = []
series.forEach((value, index) => {
@@ -0,0 +1,18 @@
import { Alert, AlertDescription, AlertTitle } from "@/components/reui/alert"
import type { TrafficObservationMeta } from "@/lib/traffic-observations"
export function TrafficObservationStatus({ observations: o, unknown }: { observations?: TrafficObservationMeta; unknown: boolean }) {
const labels = { error: "Ошибка опроса трафика", pending: "Опрос трафика выполняется", stale: "Измерения трафика устарели",
disabled: "Опрос трафика отключён", unknown: "Скорость пока не измерена", current: "Скорость пока не измерена" }
const warning = unknown || o?.currentState && o.currentState !== "current"
return <>
{warning && <Alert variant="warning" role="status" className="mb-3">
<AlertTitle>{labels[o?.currentState ?? "unknown"]}</AlertTitle>
<AlertDescription>{o?.error || "История сохранена. Для текущей скорости нужны достоверные свежие измерения."}</AlertDescription>
</Alert>}
{o?.lastAttemptAt && <p aria-label="Попытка опроса трафика" className="text-xs text-muted-foreground mb-3">
Последняя попытка: <time dateTime={o.lastAttemptAt}>{new Date(o.lastAttemptAt).toLocaleString("ru-RU")}</time>
{o.lastSucceededAt && <> · успешный сбор: <time dateTime={o.lastSucceededAt}>{new Date(o.lastSucceededAt).toLocaleString("ru-RU")}</time></>}
</p>}
</>
}