import { useState, useEffect, useCallback, useMemo } from 'react'; import { useParams, useNavigate, Link } from 'react-router-dom'; import { Card, CardContent } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from '@/components/ui/table'; import { Cpu, HardDrive, RefreshCw, ChevronRight, Activity } from 'lucide-react'; import { kubernetesApi } from '@/services/api'; export default function PodMetricsPage() { const { clusterCode } = useParams<{ clusterCode: string }>(); const navigate = useNavigate(); const [loading, setLoading] = useState(false); const [metrics, setMetrics] = useState([]); const [clusters, setClusters] = useState([]); const [namespaces, setNamespaces] = useState([]); const [selectedNs, setSelectedNs] = useState('all'); const [activeCluster, setActiveCluster] = useState(clusterCode || ''); useEffect(() => { kubernetesApi.getClusters().then((res: any) => { const list = res?.list || []; setClusters(list); if (!activeCluster && list.length > 0) { const code = list[0].code || String(list[0].id); setActiveCluster(code); navigate(`/kubernetes/${code}/metrics/pods`, { replace: true }); } }).catch(() => {}); }, []); useEffect(() => { if (!activeCluster) return; kubernetesApi.getNamespaces(activeCluster).then((res: any) => { setNamespaces(Array.isArray(res) ? res : (res?.list || res?.data || [])); }).catch(() => {}); }, [activeCluster]); const loadMetrics = useCallback(async () => { if (!activeCluster) return; setLoading(true); try { const ns = selectedNs === 'all' ? undefined : selectedNs; const res: any = await kubernetesApi.getPodMetrics(activeCluster, ns); setMetrics(Array.isArray(res) ? res : (res?.list || [])); } catch { setMetrics([]); } finally { setLoading(false); } }, [activeCluster, selectedNs]); useEffect(() => { loadMetrics(); }, [loadMetrics]); // Flatten for table const rows = useMemo(() => metrics.flatMap((pm: any) => (pm.containers || []).map((c: any) => ({ pod: pm.name, namespace: pm.namespace, container: c.name, cpu: c.cpu || '0m', memory: c.memory || '0Mi', })) ), [metrics]); const totalCPU = useMemo(() => rows.reduce((s, r) => s + (parseInt(r.cpu) || 0), 0), [rows]); const totalMem = useMemo(() => { let sum = 0; rows.forEach(r => { const v = r.memory; if (v.endsWith('Mi')) sum += parseInt(v); else if (v.endsWith('Ki')) sum += parseInt(v) / 1024; else if (v.endsWith('Gi')) sum += parseInt(v) * 1024; }); return sum; }, [rows]); return (
集群 {activeCluster && <>{activeCluster}} Pod 资源用量

Pod 资源用量

{/* Summary cards */}

Pod 数

{metrics.length}

总 CPU

{totalCPU}m

总内存

{totalMem.toFixed(0)}Mi

Pod 命名空间 容器 CPU Memory {rows.length === 0 ? ( 暂无数据{loading ? ⏳ : ''} ) : rows.map((r, i) => ( {r.pod} {r.namespace} {r.container} {r.cpu} {r.memory} ))}
); }