Files
KLALB-dashboard/src/hooks/use-routing-table.ts
T
SerinaNya 89474b9e91 feat(dashboard)!: add routing table and split endpoint settings
- Add #/routing-table with one-second polling and route filters
- Separate auto-connect targets from local external endpoints
- Remove the obsolete interfaces navigation module

BREAKING CHANGE: #/interfaces is removed.
2026-08-27 23:19:39 +08:00

48 lines
1.6 KiB
TypeScript

import { useCallback, useEffect, useRef, useState } from 'react'
import type { RoutingTableItem } from '@/types/api'
const POLL_INTERVAL_MS = 1000
interface UseRoutingTableResult {
routingTable: RoutingTableItem[]
isLoading: boolean
error: string | null
refresh: () => void
}
export function useRoutingTable(): UseRoutingTableResult {
const [routingTable, setRoutingTable] = useState<RoutingTableItem[]>([])
const [isLoading, setIsLoading] = useState(true)
const [error, setError] = useState<string | null>(null)
const mountedRef = useRef(true)
const fetchRoutingTable = useCallback(async () => {
try {
const response = await fetch('/api/routing-table')
if (!response.ok) throw new Error(`路由接口异常 (${response.status})`)
const payload: unknown = await response.json()
if (!Array.isArray(payload)) throw new Error('路由接口返回格式异常')
if (!mountedRef.current) return
setRoutingTable(payload as RoutingTableItem[])
setError(null)
} catch (err: unknown) {
if (mountedRef.current) setError(err instanceof Error ? err.message : String(err))
} finally {
if (mountedRef.current) setIsLoading(false)
}
}, [])
useEffect(() => {
mountedRef.current = true
void fetchRoutingTable()
const timer = window.setInterval(() => void fetchRoutingTable(), POLL_INTERVAL_MS)
return () => {
mountedRef.current = false
window.clearInterval(timer)
}
}, [fetchRoutingTable])
const refresh = useCallback(() => void fetchRoutingTable(), [fetchRoutingTable])
return { routingTable, isLoading, error, refresh }
}