fix(ui): учитывать неизвестный статус устройств VPN

This commit is contained in:
Denozordec committed 2026-09-30 15:41:45 +07:00
1 parent 6f00596e33
commit 6ea3cdad0e
6 files changed
+56 -16

No files matched your search

+11 -7
View File
@@ -140,12 +140,14 @@ interface BackendServer {
country: string
type?: Server["type"]
enabled: boolean
status?: Server["status"]
status?: Server["status"] | null
latency?: number | null
asn?: string
}
function mapBackendServer(s: BackendServer): Server {
type InventoryServer = Server & { monitoringUnknown?: boolean }
function mapBackendServer(s: BackendServer): InventoryServer {
return {
id: String(s.id),
name: s.name || s.host,
@@ -157,7 +159,8 @@ function mapBackendServer(s: BackendServer): Server {
asn: s.asn ?? "",
type: s.type ?? "exit-node",
enabled: s.enabled,
status: s.status ?? "online",
status: s.status ?? "offline",
monitoringUnknown: s.status == null,
latency: s.latency ?? null,
sessions: 0,
}
@@ -167,7 +170,7 @@ const ipsecInventorySchema = z.array(z.object({
id: z.number().int().positive(), name: z.string(), host: z.string(), enabled: z.boolean(),
country: z.string().optional().default("UN"),
type: z.enum(["jump-host", "exit-node", "home-router"]).optional(),
status: z.enum(["online", "offline", "degraded"]).optional(),
status: z.enum(["online", "offline", "degraded"]).nullable().optional(),
latency: z.number().nullable().optional(), asn: z.string().optional(),
})).refine(rows => new Set(rows.map(row => row.id)).size === rows.length)
@@ -177,7 +180,7 @@ function IpsecPage() {
const [summaries, setSummaries] = useState<IpsecServerSummaryDto[]>([])
const [clients, setClients] = useState<IpsecClientDto[]>([])
const [liveServers, setLiveServers] = useState<Server[]>([])
const [liveServers, setLiveServers] = useState<InventoryServer[]>([])
const [failures, setFailures] = useState<IpsecFailure[]>([])
const [loading, setLoading] = useState(false)
const [dataError, setDataError] = useState<string | null>(null)
@@ -397,13 +400,14 @@ function IpsecPage() {
host: s.host,
site: s.site,
country: s.country,
status: s.status,
status: isLive && (s as InventoryServer).monitoringUnknown ? undefined : s.status,
type: s.type,
count: counts.get(s.id) ?? 0,
meta: isLive && (s as InventoryServer).monitoringUnknown ? `${counts.get(s.id) ?? 0} · Статус неизвестен` : undefined,
enabled: s.enabled,
title: [s.name, s.host, s.asn].filter(Boolean).join(" · "),
}))
}, [displayServers, displayClients])
}, [displayServers, displayClients, isLive])
const handleInit = async (form: IpsecInitFormState) => {
beginOperation(form.serverId)
+10 -7
View File
@@ -36,7 +36,7 @@ interface BackendServer {
country: string
asn?: string
enabled: boolean
status?: Server["status"]
status?: Server["status"] | null
latency?: number | null
}
@@ -45,7 +45,9 @@ interface VxlanApiResponse {
tunnels: VxlanTunnel[]
}
function mapBackendServer(s: BackendServer): Server {
type InventoryServer = Server & { monitoringUnknown?: boolean }
function mapBackendServer(s: BackendServer): InventoryServer {
return {
id: String(s.id),
name: s.name || s.host,
@@ -57,7 +59,8 @@ function mapBackendServer(s: BackendServer): Server {
asn: s.asn ?? "",
type: s.type ?? "exit-node",
enabled: s.enabled,
status: s.status ?? "online",
status: s.status ?? "offline",
monitoringUnknown: s.status == null,
latency: s.latency ?? null,
sessions: 0,
}
@@ -112,7 +115,7 @@ function VxlanPageContent({ selectedServerId, selectedTunnelId, allTunnelsHref,
const [responseReceipt, setResponseReceipt] = useState<string | null>(null)
const [liveTunnels, setLiveTunnels] = useState<VxlanTunnel[]>([])
const [liveServers, setLiveServers] = useState<Server[]>([])
const [liveServers, setLiveServers] = useState<InventoryServer[]>([])
const [loading, setLoading] = useState(true)
const [failures, setFailures] = useState<NonNullable<VxlanApiResponse["failures"]>>([])
const [hasLoaded, setHasLoaded] = useState(false)
@@ -193,12 +196,12 @@ function VxlanPageContent({ selectedServerId, selectedTunnelId, allTunnelsHref,
host: s.host,
site: s.site,
country: s.country,
status: s.status,
status: isLive && (s as InventoryServer).monitoringUnknown ? undefined : s.status,
type: s.type,
enabled: s.enabled,
meta: String(displayTunnels.filter((t) => t.serverId === s.id).length),
meta: `${displayTunnels.filter((t) => t.serverId === s.id).length}${isLive && (s as InventoryServer).monitoringUnknown ? " · Статус неизвестен" : ""}`,
}))
), [displayServers, displayTunnels])
), [displayServers, displayTunnels, isLive])
const filtered = useMemo(() => {
if (!search) return scopedTunnels