feat: 前端全面优化 — 懒加载/骨架屏/错误边界/面包屑/主题增强/Glass登录页/动画系统

- 新增: ErrorBoundary, PageTransition, Breadcrumb, SkeletonCard (4组件)
- 重构: App.tsx (React.lazy懒加载所有页面), index.css (55+主题变量/动画/工具类)
- 优化: MainLayout (CSS变量布局+Footer), Header (搜索增强+快捷键), Sidebar (折叠Tooltip+子菜单动画)
- 优化: Dashboard骨架屏+级联动画, Stats/Charts/Recent主题感知颜色
- 优化: Login.tsx Glass毛玻璃效果+密码显隐图标+光球动画
- 图表Recharts主题化(CustomTooltip/chart-grid/chart-axis)
- 减少动画偏好支持(prefers-reduced-motion)
This commit is contained in:
attacker committed 2026-06-24 02:06:07 +00:00
1 parent 3d7932c087
commit 722587ab84
14 files changed
+2026 -969

No files matched your search

+173 -165
View File
@@ -1,62 +1,93 @@
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
import { Suspense, lazy } from 'react';
import { BrowserRouter, Routes, Route, Navigate, useLocation } from 'react-router-dom';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { ThemeProvider } from '@/hooks/useTheme';
import { MainLayout } from '@/components/layout/MainLayout';
import { ConfirmProvider } from '@/components/ui/confirm-dialog';
import { Login } from '@/components/auth/Login';
import { ProtectedRoute } from '@/components/auth/ProtectedRoute';
import { Dashboard } from '@/components/dashboard/Dashboard';
import { ServerManager } from '@/components/server/ServerManager';
import { CloudAccountManager } from '@/components/cloud/CloudAccountManager';
import { DomainManager } from '@/components/cloud/DomainManager';
import { RegionManager } from '@/components/cloud/RegionManager';
import { PlatformManager } from '@/components/cloud/PlatformManager';
import { CloudBilling } from '@/components/cloud/CloudBilling';
import { KubernetesClusters } from '@/components/kubernetes/KubernetesClusters';
import ClusterOverviewPage from '@/components/kubernetes/ClusterOverviewPage';
import NodeDetailPage from '@/components/kubernetes/NodeDetailPage';
import NamespaceOverviewPage from '@/components/kubernetes/NamespaceOverviewPage';
import NamespaceResourcePage from '@/components/kubernetes/NamespaceResourcePage';
import DeploymentDetailPage from '@/components/kubernetes/DeploymentDetailPage';
import WorkloadViewPage from '@/components/kubernetes/WorkloadViewPage';
import { TopologyView } from '@/components/kubernetes/TopologyView';
import { KubernetesNodes } from '@/components/kubernetes/KubernetesNodes';
import { KubernetesWorkloads } from '@/components/kubernetes/KubernetesWorkloads';
import PodMetricsPage from '@/components/kubernetes/PodMetricsPage';
import EventsPage from '@/components/kubernetes/EventsPage';
import CapacityPage from '@/components/kubernetes/CapacityPage';
import ClusterComparePage from '@/components/kubernetes/ClusterComparePage';
import { AlertManager } from '@/components/monitor/AlertManager';
import { ApprovalFlowManager } from '@/components/approval/ApprovalFlow';
import { ScriptManager } from '@/components/automation/ScriptManager';
import { SystemManager } from '@/components/system/SystemManager';
import CredentialManager from '@/components/deploy/CredentialManager';
import { PipelineManager } from '@/components/deploy/PipelineManager';
import DeployCredentials from '@/components/deploy/DeployCredentials';
import PipelineEditor from '@/components/deploy/PipelineEditor';
import PipelineRunDetail from '@/components/deploy/PipelineRunDetail';
import DeployRBAC from '@/components/deploy/DeployRBAC';
import UserGroupsManager from '@/components/deploy/UserGroupsManager';
import { CronJobManager } from '@/components/automation/CronJobManager';
import AnsibleManager from '@/components/automation/AnsibleManager';
import AnsibleWorkflow from '@/components/automation/AnsibleWorkflow';
import { AIOpsAssistant } from '@/components/aiops/AIOpsAssistant';
import { AIAlertAnalyzer } from '@/components/aiops/AIAlertAnalyzer';
import { AIPredictiveAnalytics } from '@/components/aiops/AIPredictiveAnalytics';
import AlertCenter from '@/components/monitor/alert-center/AlertCenter';
import TraceManager from '@/components/monitor/trace/TraceManager';
import { HostMonitor } from '@/pages/HostMonitor';
import HostMonitorDashboard from '@/components/monitor/dashboard/HostMonitorDashboard';
import GrafanaDashboard from '@/components/monitor/dashboard/GrafanaDashboard';
import { MonitorCenter } from '@/pages/MonitorCenter';
import { MetricsExplorer } from '@/pages/MetricsExplorer';
import DatasourcePage from '@/components/monitor/datasource/DatasourcePage';
import { PageTransition } from '@/components/layout/PageTransition';
import { ErrorBoundary } from '@/components/layout/ErrorBoundary';
// Lazy load page components for code splitting
const Dashboard = lazy(() => import('@/components/dashboard/Dashboard').then(m => ({ default: m.Dashboard })));
const ServerManager = lazy(() => import('@/components/server/ServerManager').then(m => ({ default: m.ServerManager })));
const CloudAccountManager = lazy(() => import('@/components/cloud/CloudAccountManager').then(m => ({ default: m.CloudAccountManager })));
const DomainManager = lazy(() => import('@/components/cloud/DomainManager').then(m => ({ default: m.DomainManager })));
const RegionManager = lazy(() => import('@/components/cloud/RegionManager').then(m => ({ default: m.RegionManager })));
const PlatformManager = lazy(() => import('@/components/cloud/PlatformManager').then(m => ({ default: m.PlatformManager })));
const CloudBilling = lazy(() => import('@/components/cloud/CloudBilling').then(m => ({ default: m.CloudBilling })));
const KubernetesClusters = lazy(() => import('@/components/kubernetes/KubernetesClusters').then(m => ({ default: m.KubernetesClusters })));
const ClusterOverviewPage = lazy(() => import('@/components/kubernetes/ClusterOverviewPage').then(m => ({ default: m.default })));
const NodeDetailPage = lazy(() => import('@/components/kubernetes/NodeDetailPage').then(m => ({ default: m.default })));
const NamespaceOverviewPage = lazy(() => import('@/components/kubernetes/NamespaceOverviewPage').then(m => ({ default: m.default })));
const NamespaceResourcePage = lazy(() => import('@/components/kubernetes/NamespaceResourcePage').then(m => ({ default: m.default })));
const DeploymentDetailPage = lazy(() => import('@/components/kubernetes/DeploymentDetailPage').then(m => ({ default: m.default })));
const WorkloadViewPage = lazy(() => import('@/components/kubernetes/WorkloadViewPage').then(m => ({ default: m.default })));
const TopologyView = lazy(() => import('@/components/kubernetes/TopologyView').then(m => ({ default: m.TopologyView })));
const KubernetesNodes = lazy(() => import('@/components/kubernetes/KubernetesNodes').then(m => ({ default: m.KubernetesNodes })));
const PodMetricsPage = lazy(() => import('@/components/kubernetes/PodMetricsPage').then(m => ({ default: m.default })));
const EventsPage = lazy(() => import('@/components/kubernetes/EventsPage').then(m => ({ default: m.default })));
const CapacityPage = lazy(() => import('@/components/kubernetes/CapacityPage').then(m => ({ default: m.default })));
const AlertManager = lazy(() => import('@/components/monitor/AlertManager').then(m => ({ default: m.AlertManager })));
const ApprovalFlowManager = lazy(() => import('@/components/approval/ApprovalFlow').then(m => ({ default: m.ApprovalFlowManager })));
const ScriptManager = lazy(() => import('@/components/automation/ScriptManager').then(m => ({ default: m.ScriptManager })));
const SystemManager = lazy(() => import('@/components/system/SystemManager').then(m => ({ default: m.SystemManager })));
const CredentialManager = lazy(() => import('@/components/deploy/CredentialManager').then(m => ({ default: m.default })));
const PipelineManager = lazy(() => import('@/components/deploy/PipelineManager').then(m => ({ default: m.PipelineManager })));
const DeployCredentials = lazy(() => import('@/components/deploy/DeployCredentials').then(m => ({ default: m.default })));
const PipelineEditor = lazy(() => import('@/components/deploy/PipelineEditor').then(m => ({ default: m.default })));
const PipelineRunDetail = lazy(() => import('@/components/deploy/PipelineRunDetail').then(m => ({ default: m.default })));
const DeployRBAC = lazy(() => import('@/components/deploy/DeployRBAC').then(m => ({ default: m.default })));
const UserGroupsManager = lazy(() => import('@/components/deploy/UserGroupsManager').then(m => ({ default: m.default })));
const CronJobManager = lazy(() => import('@/components/automation/CronJobManager').then(m => ({ default: m.CronJobManager })));
const AnsibleManager = lazy(() => import('@/components/automation/AnsibleManager').then(m => ({ default: m.default })));
const AnsibleWorkflow = lazy(() => import('@/components/automation/AnsibleWorkflow').then(m => ({ default: m.default })));
const AIOpsAssistant = lazy(() => import('@/components/aiops/AIOpsAssistant').then(m => ({ default: m.AIOpsAssistant })));
const AIAlertAnalyzer = lazy(() => import('@/components/aiops/AIAlertAnalyzer').then(m => ({ default: m.AIAlertAnalyzer })));
const AIPredictiveAnalytics = lazy(() => import('@/components/aiops/AIPredictiveAnalytics').then(m => ({ default: m.AIPredictiveAnalytics })));
const AlertCenter = lazy(() => import('@/components/monitor/alert-center/AlertCenter').then(m => ({ default: m.default })));
const TraceManager = lazy(() => import('@/components/monitor/trace/TraceManager').then(m => ({ default: m.default })));
const HostMonitor = lazy(() => import('@/pages/HostMonitor').then(m => ({ default: m.HostMonitor })));
const HostMonitorDashboard = lazy(() => import('@/components/monitor/dashboard/HostMonitorDashboard').then(m => ({ default: m.default })));
const GrafanaDashboard = lazy(() => import('@/components/monitor/dashboard/GrafanaDashboard').then(m => ({ default: m.default })));
const MonitorCenter = lazy(() => import('@/pages/MonitorCenter').then(m => ({ default: m.MonitorCenter })));
const MetricsExplorer = lazy(() => import('@/pages/MetricsExplorer').then(m => ({ default: m.MetricsExplorer })));
const DatasourcePage = lazy(() => import('@/components/monitor/datasource/DatasourcePage').then(m => ({ default: m.default })));
// Page loader fallback
function PageLoader() {
return (
<div className="flex flex-col items-center justify-center h-[calc(100vh-14rem)] gap-4">
<div className="relative">
<div className="h-10 w-10 border-3 border-[var(--dg-border)] border-t-[var(--dg-blue)] rounded-full animate-spin" />
<div className="absolute inset-0 h-10 w-10 border-3 border-transparent border-t-[var(--dg-blue)] rounded-full animate-spin opacity-30" style={{ animationDirection: 'reverse', animationDuration: '1s' }} />
</div>
<p className="text-sm text-[var(--dg-text-muted)]">加载中...</p>
</div>
);
}
// Lazy page wrapper with error boundary and transition
function LazyPage({ children }: { children: React.ReactNode }) {
const location = useLocation();
return (
<ErrorBoundary>
<PageTransition key={location.pathname}>
<Suspense fallback={<PageLoader />}>
{children}
</Suspense>
</PageTransition>
</ErrorBoundary>
);
}
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 5 * 60 * 1000,
retry: 1,
refetchOnWindowFocus: false,
},
},
});
@@ -66,128 +97,105 @@ function App() {
<ThemeProvider>
<QueryClientProvider client={queryClient}>
<ConfirmProvider>
<BrowserRouter>
<Routes>
<Route path="/login" element={<Login />} />
<Route path="/" element={<ProtectedRoute><MainLayout /></ProtectedRoute>}>
<Route index element={<Dashboard />} />
<Route path="servers" element={<ServerManager />} />
<Route path="cloud-accounts" element={<CloudAccountManager />} />
<Route path="domains" element={<DomainManager />} />
<Route path="regions" element={<RegionManager />} />
<Route path="platforms" element={<PlatformManager />} />
<Route path="cloud-billing" element={<CloudBilling />} />
<BrowserRouter>
<Routes>
<Route path="/login" element={<Login />} />
<Route path="/" element={
<ProtectedRoute>
<MainLayout />
</ProtectedRoute>
}>
<Route index element={<LazyPage><Dashboard /></LazyPage>} />
<Route path="servers" element={<LazyPage><ServerManager /></LazyPage>} />
<Route path="cloud-accounts" element={<LazyPage><CloudAccountManager /></LazyPage>} />
<Route path="domains" element={<LazyPage><DomainManager /></LazyPage>} />
<Route path="regions" element={<LazyPage><RegionManager /></LazyPage>} />
<Route path="platforms" element={<LazyPage><PlatformManager /></LazyPage>} />
<Route path="cloud-billing" element={<LazyPage><CloudBilling /></LazyPage>} />
{/* ================================================================ */}
{/* Kubernetes — Kuboard-style routes */}
{/* ================================================================ */}
{/* Kubernetes 集群列表 */}
<Route path="kubernetes">
<Route index element={<KubernetesClusters />} />
{/* 🆕 M13: 多集群资源对比看板(全局,不属于特定集群) */}
<Route path="compare" element={<ClusterComparePage />} />
{/* 集群概览 (节点 + 命名空间列表) */}
<Route path=":clusterCode">
<Route index element={<ClusterOverviewPage />} />
{/* 🆕 资源用量 / 事件 / 容量分析 */}
<Route path="metrics/pods" element={<PodMetricsPage />} />
<Route path="events" element={<EventsPage />} />
<Route path="capacity" element={<CapacityPage />} />
{/* 节点详情 */}
<Route path="nodes/:nodeName" element={<NodeDetailPage />} />
{/* 架构拓扑 */}
<Route path="topology" element={<TopologyView />} />
{/* 命名空间作用域 */}
<Route path="namespace/:namespace">
{/* 命名空间概览 */}
<Route index element={<NamespaceOverviewPage />} />
{/* 🆕 Kuboard 风格双模式工作负载路由 (view/edit) */}
<Route path="workload">
<Route path=":mode/Deployment/:name" element={<DeploymentDetailPage />} />
<Route path=":mode/StatefulSet/:name" element={<WorkloadViewPage />} />
<Route path=":mode/DaemonSet/:name" element={<WorkloadViewPage />} />
{/* Kubernetes Routes */}
<Route path="kubernetes">
<Route index element={<LazyPage><KubernetesClusters /></LazyPage>} />
<Route path=":clusterCode">
<Route index element={<LazyPage><ClusterOverviewPage /></LazyPage>} />
<Route path="metrics/pods" element={<LazyPage><PodMetricsPage /></LazyPage>} />
<Route path="events" element={<LazyPage><EventsPage /></LazyPage>} />
<Route path="capacity" element={<LazyPage><CapacityPage /></LazyPage>} />
<Route path="nodes/:nodeName" element={<LazyPage><NodeDetailPage /></LazyPage>} />
<Route path="topology" element={<LazyPage><TopologyView /></LazyPage>} />
<Route path="namespace/:namespace">
<Route index element={<LazyPage><NamespaceOverviewPage /></LazyPage>} />
<Route path="workload">
<Route path=":mode/Deployment/:name" element={<LazyPage><DeploymentDetailPage /></LazyPage>} />
<Route path=":mode/StatefulSet/:name" element={<LazyPage><WorkloadViewPage /></LazyPage>} />
<Route path=":mode/DaemonSet/:name" element={<LazyPage><WorkloadViewPage /></LazyPage>} />
</Route>
<Route path="deployments" element={<LazyPage><NamespaceResourcePage /></LazyPage>} />
<Route path="deployments/:name" element={<LazyPage><DeploymentDetailPage /></LazyPage>} />
<Route path="pods" element={<LazyPage><NamespaceResourcePage /></LazyPage>} />
<Route path="services" element={<LazyPage><NamespaceResourcePage /></LazyPage>} />
<Route path="ingresses" element={<LazyPage><NamespaceResourcePage /></LazyPage>} />
<Route path="configmaps" element={<LazyPage><NamespaceResourcePage /></LazyPage>} />
<Route path="secrets" element={<LazyPage><NamespaceResourcePage /></LazyPage>} />
<Route path="hpas" element={<LazyPage><NamespaceResourcePage /></LazyPage>} />
<Route path="cronjobs" element={<LazyPage><NamespaceResourcePage /></LazyPage>} />
<Route path="pvcs" element={<LazyPage><NamespaceResourcePage /></LazyPage>} />
<Route path="statefulsets" element={<LazyPage><NamespaceResourcePage /></LazyPage>} />
<Route path="daemonsets" element={<LazyPage><NamespaceResourcePage /></LazyPage>} />
</Route>
</Route>
{/* 各类资源列表 */}
<Route path="deployments">
<Route index element={<NamespaceResourcePage />} />
{/* 兼容旧路由 /deployments/:name → 默认 view 模式 */}
<Route path=":name" element={<DeploymentDetailPage />} />
</Route>
<Route path="pods" element={<NamespaceResourcePage />} />
<Route path="services" element={<NamespaceResourcePage />} />
<Route path="ingresses" element={<NamespaceResourcePage />} />
<Route path="configmaps" element={<NamespaceResourcePage />} />
<Route path="secrets" element={<NamespaceResourcePage />} />
<Route path="hpas" element={<NamespaceResourcePage />} />
<Route path="cronjobs" element={<NamespaceResourcePage />} />
<Route path="pvcs" element={<NamespaceResourcePage />} />
<Route path="statefulsets" element={<NamespaceResourcePage />} />
<Route path="daemonsets" element={<NamespaceResourcePage />} />
</Route>
{/* Quick Access Routes (redirect to first cluster) */}
<Route path="workloads" element={<LazyPage><NamespaceResourcePage /></LazyPage>} />
<Route path="nodes" element={<LazyPage><KubernetesNodes /></LazyPage>} />
<Route path="topology" element={<LazyPage><TopologyView /></LazyPage>} />
{/* Deploy */}
<Route path="pipelines" element={<LazyPage><PipelineManager /></LazyPage>} />
<Route path="pipelines/:code" element={<LazyPage><PipelineEditor /></LazyPage>} />
<Route path="pipelines/:code/runs" element={<LazyPage><PipelineRunDetail /></LazyPage>} />
<Route path="pipelines/:code/edit" element={<LazyPage><PipelineEditor /></LazyPage>} />
<Route path="deploy/configureTools" element={<LazyPage><DeployCredentials /></LazyPage>} />
<Route path="deploy/groups" element={<LazyPage><UserGroupsManager /></LazyPage>} />
<Route path="deploy/rbac" element={<LazyPage><DeployRBAC /></LazyPage>} />
{/* Monitor */}
<Route path="metrics" element={<LazyPage><MetricsExplorer /></LazyPage>} />
<Route path="datasources" element={<LazyPage><DatasourcePage /></LazyPage>} />
<Route path="trace" element={<LazyPage><TraceManager /></LazyPage>} />
<Route path="dashboards" element={<LazyPage><GrafanaDashboard /></LazyPage>} />
<Route path="host-monitor" element={<LazyPage><HostMonitor /></LazyPage>} />
<Route path="alerts" element={<LazyPage><AlertManager /></LazyPage>} />
<Route path="alert-center" element={<LazyPage><AlertCenter /></LazyPage>} />
<Route path="monitor-center" element={<LazyPage><MonitorCenter /></LazyPage>} />
<Route path="logs" element={<LazyPage><AlertManager /></LazyPage>} />
{/* Automation */}
<Route path="approval" element={<LazyPage><ApprovalFlowManager /></LazyPage>} />
<Route path="cronjobs" element={<LazyPage><CronJobManager /></LazyPage>} />
<Route path="scripts" element={<LazyPage><ScriptManager /></LazyPage>} />
<Route path="ansible" element={<LazyPage><AnsibleWorkflow /></LazyPage>} />
<Route path="ansible/manage" element={<LazyPage><AnsibleManager /></LazyPage>} />
{/* AIOps */}
<Route path="ai-assistant" element={<LazyPage><AIOpsAssistant /></LazyPage>} />
<Route path="ai-alert-analyzer" element={<LazyPage><AIAlertAnalyzer /></LazyPage>} />
<Route path="ai-predictive" element={<LazyPage><AIPredictiveAnalytics /></LazyPage>} />
{/* System */}
<Route path="users" element={<LazyPage><SystemManager /></LazyPage>} />
<Route path="roles" element={<LazyPage><SystemManager /></LazyPage>} />
<Route path="logs-audit" element={<LazyPage><SystemManager /></LazyPage>} />
<Route path="terminal-audit" element={<LazyPage><SystemManager /></LazyPage>} />
<Route path="credentials" element={<LazyPage><CredentialManager /></LazyPage>} />
<Route path="settings" element={<LazyPage><SystemManager /></LazyPage>} />
{/* Fallback */}
<Route path="*" element={<Navigate to="/" replace />} />
</Route>
</Route>
{/* Kubernetes 资源快捷入口 (自动跳转至首个集群) */}
<Route path="workloads">
<Route path="deployments" element={<NamespaceResourcePage />} />
<Route path="statefulsets" element={<NamespaceResourcePage />} />
<Route path="daemonsets" element={<NamespaceResourcePage />} />
<Route path="pods" element={<NamespaceResourcePage />} />
<Route path="cronjobs" element={<NamespaceResourcePage />} />
<Route path="services" element={<NamespaceResourcePage />} />
<Route path="ingresses" element={<NamespaceResourcePage />} />
<Route path="configmaps" element={<NamespaceResourcePage />} />
<Route path="secrets" element={<NamespaceResourcePage />} />
<Route path="pvcs" element={<NamespaceResourcePage />} />
<Route path="hpas" element={<NamespaceResourcePage />} />
<Route path="metrics" element={<PodMetricsPage />} />
<Route path="events" element={<EventsPage />} />
<Route path="capacity" element={<CapacityPage />} />
<Route index element={<NamespaceResourcePage />} />
</Route>
{/* 资源监控(Agent 指标 + 中间件 + SNMP + 拨测) */}
<Route path="monitor-center" element={<MonitorCenter />} />
{/* 旧路由兼容:节点管理、拓扑 */}
<Route path="nodes" element={<KubernetesNodes />} />
<Route path="topology" element={<TopologyView />} />
{/* 应用发布 */}
<Route path="pipelines" element={<PipelineManager />} />
<Route path="pipelines/:code" element={<PipelineEditor />} />
<Route path="pipelines/:code/runs" element={<PipelineRunDetail />} />
<Route path="pipelines/:code/edit" element={<PipelineEditor />} />
<Route path="deploy/configureTools" element={<DeployCredentials />} />
<Route path="deploy/groups" element={<UserGroupsManager />} />
<Route path="deploy/rbac" element={<DeployRBAC />} />
{/* 监控告警 */}
<Route path="metrics" element={<MetricsExplorer />} />
<Route path="datasources" element={<DatasourcePage />} />
<Route path="trace" element={<TraceManager />} />
<Route path="dashboards" element={<GrafanaDashboard />} />
<Route path="host-monitor" element={<HostMonitor />} />
<Route path="alerts" element={<AlertManager />} />
<Route path="alert-center" element={<AlertCenter />} />
<Route path="logs" element={<AlertManager />} />
<Route path="approval" element={<ApprovalFlowManager />} />
{/* 自动化运维 */}
<Route path="cronjobs" element={<CronJobManager />} />
<Route path="scripts" element={<ScriptManager />} />
<Route path="ansible" element={<AnsibleWorkflow />} />
<Route path="ansible/manage" element={<AnsibleManager />} />
{/* AIOps智能 */}
<Route path="ai-assistant" element={<AIOpsAssistant />} />
<Route path="ai-alert-analyzer" element={<AIAlertAnalyzer />} />
<Route path="ai-predictive" element={<AIPredictiveAnalytics />} />
<Route path="users" element={<SystemManager />} />
<Route path="roles" element={<SystemManager />} />
<Route path="logs-audit" element={<SystemManager />} />
<Route path="terminal-audit" element={<SystemManager />} />
<Route path="credentials" element={<CredentialManager />} />
<Route path="settings" element={<SystemManager />} />
<Route path="*" element={<Navigate to="/" replace />} />
</Route>
</Routes>
</BrowserRouter>
</Routes>
</BrowserRouter>
</ConfirmProvider>
</QueryClientProvider>
</ThemeProvider>