fix(ui): проверять данные VXLAN и гонки загрузки

This commit is contained in:
Denozordec committed 2026-09-30 09:47:51 +07:00
1 parent e163a9ed9d
commit 14be83a869
6 files changed
+103 -13

No files matched your search

+12 -8
View File
@@ -19,6 +19,7 @@ import {
} from "lucide-react"
import { CodeExportSheet } from "@/components/reui-kit/code-export-sheet"
import { useDataSource } from "@/lib/data-source"
import { vxlanResponseSchema, vxlanServersSchema } from "@/lib/vxlan-response"
import { requestJson } from "@/shared/api/http-client"
import { cn } from "@/lib/utils"
import { ServerRailLayout, ServerRailMobileButton } from "@/components/server-rail-layout"
@@ -153,19 +154,22 @@ function VxlanPageContent({ selectedServerId, selectedTunnelId, allTunnelsHref,
setLiveError(null)
try {
const [tunnelsRes, serversRes] = await Promise.all([
requestJson<VxlanApiResponse>(backendUrl, "/api/vxlan"),
requestJson<BackendServer[]>(backendUrl, "/api/servers"),
requestJson<unknown>(backendUrl, "/api/vxlan"),
requestJson<unknown>(backendUrl, "/api/servers"),
])
if (epoch !== loadEpoch.current) return
if (!Array.isArray(tunnelsRes?.tunnels) || !Array.isArray(serversRes)) throw new Error("Некорректный ответ загрузки VXLAN")
const nextFailures = tunnelsRes.failures ?? []
if (!Array.isArray(nextFailures) || nextFailures.some(f => !f || typeof f.serverId !== "string" || typeof f.error !== "string")) throw new Error("Некорректный ответ загрузки VXLAN")
const parsedTunnels = vxlanResponseSchema.safeParse(tunnelsRes)
const parsedServers = vxlanServersSchema.safeParse(serversRes)
if (!parsedTunnels.success || !parsedServers.success) throw new Error("Некорректный ответ загрузки VXLAN")
const nextTunnels = parsedTunnels.data.tunnels
const nextServers = parsedServers.data
const nextFailures = parsedTunnels.data.failures
const failedIds = new Set(nextFailures.map(f => f.serverId))
const enabledIds = new Set(serversRes.filter(s => s.enabled).map(s => String(s.id)))
setLiveTunnels(previous => [...tunnelsRes.tunnels.filter(t => !failedIds.has(t.serverId)), ...previous.filter(t => failedIds.has(t.serverId) && enabledIds.has(t.serverId))])
const enabledIds = new Set(nextServers.filter(s => s.enabled).map(s => String(s.id)))
setLiveTunnels(previous => [...nextTunnels.filter(t => !failedIds.has(t.serverId)), ...previous.filter(t => failedIds.has(t.serverId) && enabledIds.has(t.serverId))])
setFailures(nextFailures)
setHasLoaded(true)
setLiveServers(serversRes.filter((s) => s.enabled).map(mapBackendServer))
setLiveServers(nextServers.filter((s) => s.enabled).map(mapBackendServer))
} catch (e) {
if (epoch !== loadEpoch.current) return
setLiveError(e instanceof Error ? e.message : "Ошибка загрузки")