fix: stabilize admin dashboard navigation

This commit is contained in:
linkong
2026-03-31 18:09:52 +08:00
parent e903723877
commit 6f01dfb590
8 changed files with 51 additions and 18 deletions

View File

@@ -19,15 +19,15 @@ function App() {
return (
<Routes>
<Route path="/" element={<Dashboard />} />
<Route path="/admin" element={<Dashboard />} />
<Route path="/" element={<Navigate to="/earth" replace />} />
<Route path="/earth" element={<Earth />} />
<Route path="/users" element={<Users />} />
<Route path="/datasources" element={<DataSources />} />
<Route path="/data" element={<DataList />} />
<Route path="/bgp" element={<BGP />} />
<Route path="/settings" element={<Settings />} />
<Route path="*" element={<Navigate to="/" replace />} />
<Route path="*" element={<Navigate to="/admin" replace />} />
</Routes>
)
}

View File

@@ -10,7 +10,7 @@ import {
MenuUnfoldOutlined,
MenuFoldOutlined,
} from '@ant-design/icons'
import { Link, useLocation } from 'react-router-dom'
import { useLocation, useNavigate } from 'react-router-dom'
import { useAuthStore } from '../../stores/auth'
import packageJson from '../../../package.json'
@@ -23,18 +23,19 @@ interface AppLayoutProps {
function AppLayout({ children }: AppLayoutProps) {
const location = useLocation()
const navigate = useNavigate()
const { user, logout } = useAuthStore()
const [collapsed, setCollapsed] = useState(false)
const showBanner = true
const appVersion = `v${packageJson.version}`
const menuItems = [
{ key: '/', icon: <DashboardOutlined />, label: <Link to="/"></Link> },
{ key: '/datasources', icon: <DatabaseOutlined />, label: <Link to="/datasources"></Link> },
{ key: '/data', icon: <BarChartOutlined />, label: <Link to="/data"></Link> },
{ key: '/bgp', icon: <DeploymentUnitOutlined />, label: <Link to="/bgp">BGP观测</Link> },
{ key: '/users', icon: <UserOutlined />, label: <Link to="/users"></Link> },
{ key: '/settings', icon: <SettingOutlined />, label: <Link to="/settings"></Link> },
{ key: '/admin', icon: <DashboardOutlined />, label: '仪表盘' },
{ key: '/datasources', icon: <DatabaseOutlined />, label: '数据源' },
{ key: '/data', icon: <BarChartOutlined />, label: '采集数据' },
{ key: '/bgp', icon: <DeploymentUnitOutlined />, label: 'BGP观测' },
{ key: '/users', icon: <UserOutlined />, label: '用户管理' },
{ key: '/settings', icon: <SettingOutlined />, label: '系统配置' },
]
return (
@@ -68,6 +69,11 @@ function AppLayout({ children }: AppLayoutProps) {
mode="inline"
selectedKeys={[location.pathname]}
items={menuItems}
onClick={({ key }) => {
if (key !== location.pathname) {
navigate(key)
}
}}
/>
</div>

View File

@@ -90,6 +90,8 @@ const RESTART_GUIDE_LINES: Record<RestartAction, string[]> = {
],
}
let cachedDashboardStats: Stats | null = null
function getRestartConfirmMessage(action: RestartAction): string {
if (action === 'restart-database') {
return '将重启 PostgreSQL 和 Redis页面通常保持在线但相关请求可能短暂波动。'
@@ -102,8 +104,8 @@ function getRestartConfirmMessage(action: RestartAction): string {
function Dashboard() {
const { token, clearAuth, user } = useAuthStore()
const [stats, setStats] = useState<Stats | null>(null)
const [loading, setLoading] = useState(true)
const [stats, setStats] = useState<Stats | null>(cachedDashboardStats)
const [loading, setLoading] = useState(cachedDashboardStats === null)
const [wsConnected, setWsConnected] = useState(false)
const [error, setError] = useState<string | null>(null)
const [restartModalOpen, setRestartModalOpen] = useState(false)
@@ -122,7 +124,9 @@ function Dashboard() {
const fetchStats = async () => {
try {
setLoading(true)
if (!cachedDashboardStats) {
setLoading(true)
}
const res = await fetch('/api/v1/dashboard/stats', {
headers: { Authorization: `Bearer ${token}` },
})
@@ -132,6 +136,7 @@ function Dashboard() {
return
}
const data = await res.json()
cachedDashboardStats = data
setStats(data)
setError(null)
} catch (err) {
@@ -164,7 +169,9 @@ function Dashboard() {
try {
const msg = JSON.parse(event.data)
if (msg.type === 'data_frame' && msg.channel === 'dashboard') {
setStats(msg.payload?.stats as Stats)
const nextStats = msg.payload?.stats as Stats
cachedDashboardStats = nextStats
setStats(nextStats)
}
} catch (e) {
console.error('Parse WS message error:', e)