fix(ui): показывать время получения аналитики потоков
This commit is contained in:
1 parent
7318c5286b
commit
65241c94e9
6 files changed
+70
-12
No files matched your search
@@ -2,6 +2,7 @@
|
||||
|
||||
import { useState, useMemo, useEffect, type ReactNode } from "react"
|
||||
import { Alert, AlertTitle, AlertDescription } from "@/components/reui/alert"
|
||||
import { TrafficDataTime } from "@/components/traffic/traffic-data-time"
|
||||
import { PageHeader } from "@/components/page-header"
|
||||
import { Frame, FramePanel } from "@/components/reui/frame"
|
||||
import { KpiStatGrid } from "@/components/reui-kit/kpi-stat-grid"
|
||||
@@ -796,7 +797,7 @@ export default function TrafficPage() {
|
||||
const [flowScope, setFlowScope] = useState<FlowScope>("servers")
|
||||
const [flowRetry, setFlowRetry] = useState(0)
|
||||
const flowKey = JSON.stringify([isLive, groupMode, backendUrl, range, flowScope, flowRetry])
|
||||
const [flowResult, setFlowResult] = useState<{ key: string; stats?: FlowStatsDto; exporters?: FlowEntityCard[]; clients?: FlowEntityCard[]; error?: string } | null>(null)
|
||||
const [flowResult, setFlowResult] = useState<{ key: string; receivedAt?: number; stats?: FlowStatsDto; exporters?: FlowEntityCard[]; clients?: FlowEntityCard[]; error?: string } | null>(null)
|
||||
const currentFlows = flowResult?.key === flowKey ? flowResult : null
|
||||
const liveBusy = isLive && groupMode === "flows" && !currentFlows
|
||||
const liveError = currentFlows?.error
|
||||
@@ -804,7 +805,7 @@ export default function TrafficPage() {
|
||||
const flowExporters = useMemo(() => currentFlows?.exporters ?? [], [currentFlows])
|
||||
const flowClients = useMemo(() => currentFlows?.clients ?? [], [currentFlows])
|
||||
const [analyticsRetry, setAnalyticsRetry] = useState(0)
|
||||
const [analyticsResult, setAnalyticsResult] = useState<{ key: string; data?: FlowAnalyticsDto; monthly?: FlowMonthlyDto; error?: string } | null>(null)
|
||||
const [analyticsResult, setAnalyticsResult] = useState<{ key: string; receivedAt?: number; data?: FlowAnalyticsDto; monthly?: FlowMonthlyDto; error?: string } | null>(null)
|
||||
const flowIfaceOwner = JSON.stringify([isLive, backendUrl, groupMode, flowScope, selectedId])
|
||||
const [flowIfaceSelection, setFlowIfaceSelection] = useState<{ owner: string; iface: string } | null>(null)
|
||||
const flowIface = flowIfaceSelection?.owner === flowIfaceOwner ? flowIfaceSelection.iface : "__all__"
|
||||
@@ -825,7 +826,7 @@ export default function TrafficPage() {
|
||||
iface: selectedIface,
|
||||
})
|
||||
const flowLiveEnabled = isLive && effectiveMode === "flows" && Boolean(selectedId) && range === "5m"
|
||||
const { sample: flowLiveSample, error: flowLiveError } = useFlowLive({
|
||||
const { sample: flowLiveSample, error: flowLiveError, receivedAt: flowLiveReceivedAt } = useFlowLive({
|
||||
enabled: flowLiveEnabled,
|
||||
backendUrl,
|
||||
range,
|
||||
@@ -882,7 +883,7 @@ export default function TrafficPage() {
|
||||
getFlowClients(backendUrl, range === "30d" ? "24h" : range),
|
||||
]).then(([stats, exporters, clients]) => {
|
||||
if (cancelled) return
|
||||
setFlowResult({ key: flowKey, stats, exporters: exporters.exporters, clients: clients.clients })
|
||||
setFlowResult({ key: flowKey, receivedAt: Date.now(), stats, exporters: exporters.exporters, clients: clients.clients })
|
||||
setSelectedId(prev => {
|
||||
const list = flowScope === "users" ? clients.clients : exporters.exporters
|
||||
return list.some(x => x.id === prev) ? prev : (list[0]?.id ?? "")
|
||||
@@ -907,7 +908,7 @@ export default function TrafficPage() {
|
||||
iface: flowIface, dedup: flowDedup, excludeMesh: flowExcludeMesh, excludeOverlay: flowExcludeOverlay,
|
||||
}).then(data => ({ data }))
|
||||
void request.then(result => {
|
||||
if (!cancelled) setAnalyticsResult({ key: analyticsKey, ...result })
|
||||
if (!cancelled) setAnalyticsResult({ key: analyticsKey, receivedAt: Date.now(), ...result })
|
||||
}).catch(e => {
|
||||
if (!cancelled) setAnalyticsResult({ key: analyticsKey, error: e instanceof Error ? e.message : "Не удалось загрузить аналитику" })
|
||||
})
|
||||
@@ -1193,6 +1194,7 @@ export default function TrafficPage() {
|
||||
Подключить JH
|
||||
</Button>
|
||||
</div>
|
||||
{isLive && <TrafficDataTime label="Получение списка потоков" receivedAt={currentFlows?.receivedAt} source="API" />}
|
||||
{liveBusy && <p role="status">Загрузка потоков…</p>}
|
||||
{liveError && <Alert variant="destructive" role="alert"><AlertTitle>Потоки недоступны</AlertTitle><AlertDescription>{liveError}<Button size="sm" variant="outline" onClick={() => setFlowRetry(value => value + 1)}>Повторить загрузку потоков</Button></AlertDescription></Alert>}
|
||||
{flowError && !liveError && (
|
||||
@@ -1277,6 +1279,7 @@ export default function TrafficPage() {
|
||||
<FramePanel className="flex-1 min-w-0 p-3 sm:p-5">
|
||||
{analyticsLoading && <p role="status">Загрузка аналитики…</p>}
|
||||
{currentAnalytics?.error && <Alert variant="destructive" role="alert"><AlertTitle>Аналитика недоступна</AlertTitle><AlertDescription>{currentAnalytics.error}<Button size="sm" variant="outline" onClick={() => setAnalyticsRetry(value => value + 1)}>Повторить аналитику</Button></AlertDescription></Alert>}
|
||||
{isLive && (displayedFlow || currentAnalytics?.monthly) && <TrafficDataTime label="Получение аналитики потоков" receivedAt={flowLiveSample ? flowLiveReceivedAt : currentAnalytics?.receivedAt} source={flowLiveSample ? "live-поток" : "API"} />}
|
||||
<FlowAnalyticsDetail
|
||||
card={selFlowCard}
|
||||
analytics={displayedFlow}
|
||||
|
||||
Reference in new issue
Block a user