diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index d693c84..966e440 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -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 ( +
加载中...
+实时监控和运维概览
+实时监控和运维概览 · 最后更新: {new Date().toLocaleTimeString('zh-CN')}
+{label}
+ {payload.map((entry: any, index: number) => ( +¥{Number(totalCost).toLocaleString()}
-+
+ ¥{Number(totalCost).toLocaleString()} +
+{costChange.label}
费用分布
+费用分布
月度趋势
+月度趋势
{item.hostname}
-{item.hostname}
+暂无告警事件
+所有系统运行正常
+{alert.target}
+{alert.message}
{alert.target}
-{alert.message}
+ + {alert.created_at ? new Date(alert.created_at).toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' }) : ''} +{domain.name}
-到期: {domain.expire_date?.substring(0, 10)}
-暂无证书数据
+{domain.name}
+到期: {domain.expire_date?.substring(0, 10)}
+暂无发布记录
+{server.hostname}
-{server.ip}
+{server.hostname}
+{server.ip}
CPU {Number(server.cpu_usage ?? 0).toFixed(1)}%
-内存 {Number(server.memory_usage ?? 0).toFixed(1)}%
++ CPU {Number(server.cpu_usage ?? 0).toFixed(1)}% +
++ 内存 {Number(server.memory_usage ?? 0).toFixed(1)}% +
暂无服务器
+暂无集群数据
+{title}
-+ {title} +
+{description}
} + {description && ( +{description}
+ )}+ 抱歉,该页面遇到了意外错误。您可以尝试重新加载或返回首页。 +
+
+ {this.state.error.name}: {this.state.error.message}
+
+ {this.state.errorInfo && (
+
+ {this.state.errorInfo.componentStack}
+
+ )}
+ 暂无通知
+
{notification.title}
-{notification.message}
-+
+ {notification.message} +
+{formatDistanceToNow(notification.timestamp)}