- 拆分 DeploymentView / DeploymentDetail 至子目录(<700 行红线) - AlertCenter 接入 useAlerts / useAgentAlertRules / useAlertMutations - 新增 utils/permission.ts,usePermission 复用纯函数 - useAlerts 增强分页统计与 Agent 规则 hooks
90 lines
4.6 KiB
TypeScript
90 lines
4.6 KiB
TypeScript
// deployment-view/ServicesTab.tsx — 访问方式 Tab // Logan.Li
|
||
import { Badge } from '@/components/ui/badge';
|
||
import {
|
||
Table, TableBody, TableCell, TableHead, TableHeader, TableRow,
|
||
} from '@/components/ui/table';
|
||
import { Network, ExternalLink, Loader2 } from 'lucide-react';
|
||
import type { SvcItem, IngItem } from './types';
|
||
|
||
export function ServicesTab({ services, ingresses, loading }: { services: SvcItem[]; ingresses: IngItem[]; loading: string; namespace: string }) {
|
||
if (loading === 'services') {
|
||
return <div className="flex items-center justify-center py-12"><Loader2 className="h-6 w-6 animate-spin text-[var(--dg-text-muted)]" /></div>;
|
||
}
|
||
return (
|
||
<div className="space-y-6">
|
||
{/* Services */}
|
||
<div>
|
||
<h3 className="text-sm font-semibold text-[var(--dg-text-primary)] mb-3 flex items-center gap-2">
|
||
<Network className="h-4 w-4 text-[var(--dg-blue)]" />关联 Service
|
||
</h3>
|
||
{services.length === 0 ? (
|
||
<p className="text-sm text-[var(--dg-text-muted)] py-4">暂无匹配的 Service(Deployment 选择器未关联任何 Service)</p>
|
||
) : (
|
||
<div className="overflow-x-auto">
|
||
<Table>
|
||
<TableHeader>
|
||
<TableRow className="border-[var(--dg-border)]">
|
||
<TableHead className="text-[var(--dg-text-muted)]">名称</TableHead>
|
||
<TableHead className="text-[var(--dg-text-muted)]">类型</TableHead>
|
||
<TableHead className="text-[var(--dg-text-muted)]">ClusterIP</TableHead>
|
||
<TableHead className="text-[var(--dg-text-muted)]">端口</TableHead>
|
||
<TableHead className="text-[var(--dg-text-muted)]">Selector</TableHead>
|
||
</TableRow>
|
||
</TableHeader>
|
||
<TableBody>
|
||
{services.map(svc => (
|
||
<TableRow key={svc.name} className="border-[var(--dg-border)]">
|
||
<TableCell className="font-medium text-[var(--dg-text-primary)]">{svc.name}</TableCell>
|
||
<TableCell><Badge variant="outline" className="text-xs">{svc.type}</Badge></TableCell>
|
||
<TableCell className="font-mono text-sm text-[var(--dg-text-muted)]">{svc.clusterIP}</TableCell>
|
||
<TableCell className="text-sm text-[var(--dg-text-muted)]">{svc.ports.join(', ')}</TableCell>
|
||
<TableCell className="text-xs text-[var(--dg-text-muted)]">
|
||
{Object.entries(svc.selector).map(([k, v]) => (
|
||
<code key={k} className="mr-1 bg-[var(--dg-bg-tertiary)] px-1 rounded">{k}={v}</code>
|
||
))}
|
||
</TableCell>
|
||
</TableRow>
|
||
))}
|
||
</TableBody>
|
||
</Table>
|
||
</div>
|
||
)}
|
||
</div>
|
||
|
||
{/* Ingresses */}
|
||
<div>
|
||
<h3 className="text-sm font-semibold text-[var(--dg-text-primary)] mb-3 flex items-center gap-2">
|
||
<ExternalLink className="h-4 w-4 text-[var(--dg-purple)]" />关联 Ingress
|
||
</h3>
|
||
{ingresses.length === 0 ? (
|
||
<p className="text-sm text-[var(--dg-text-muted)] py-4">暂无匹配的 Ingress</p>
|
||
) : (
|
||
<div className="overflow-x-auto">
|
||
<Table>
|
||
<TableHeader>
|
||
<TableRow className="border-[var(--dg-border)]">
|
||
<TableHead className="text-[var(--dg-text-muted)]">名称</TableHead>
|
||
<TableHead className="text-[var(--dg-text-muted)]">Class</TableHead>
|
||
<TableHead className="text-[var(--dg-text-muted)]">Host</TableHead>
|
||
<TableHead className="text-[var(--dg-text-muted)]">路径</TableHead>
|
||
</TableRow>
|
||
</TableHeader>
|
||
<TableBody>
|
||
{ingresses.map(ing => (
|
||
<TableRow key={ing.name} className="border-[var(--dg-border)]">
|
||
<TableCell className="font-medium text-[var(--dg-text-primary)]">{ing.name}</TableCell>
|
||
<TableCell className="text-sm text-[var(--dg-text-muted)]">{ing.className}</TableCell>
|
||
<TableCell className="text-sm text-[var(--dg-text-muted)]">{ing.hosts.join(', ')}</TableCell>
|
||
<TableCell className="text-xs text-[var(--dg-text-muted)]">
|
||
{ing.rules.flatMap((r: any) => (r.http?.paths || r.paths || []).map((p: any) => p.path || '/')).join(', ')}
|
||
</TableCell>
|
||
</TableRow>
|
||
))}
|
||
</TableBody>
|
||
</Table>
|
||
</div>
|
||
)}
|
||
</div>
|
||
</div>
|
||
);
|
||
} |