fix: stabilize admin dashboard navigation
This commit is contained in:
4
frontend/package-lock.json
generated
4
frontend/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "planet-frontend",
|
||||
"version": "0.22.3",
|
||||
"version": "0.22.4",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "planet-frontend",
|
||||
"version": "0.22.3",
|
||||
"version": "0.22.4",
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^5.2.6",
|
||||
"antd": "^5.12.5",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "planet-frontend",
|
||||
"version": "0.22.3",
|
||||
"version": "0.22.4",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^5.2.6",
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user