- 151 个 hash-style flat key (s+hex 后缀) 全部重命名为语义化 nested key
- monitor 58 个: alertChannelDialog/alertManager/alertRulesTab/chartRangeHint/
esIndexPicker/helpers/hostMonitor/logAlertSpanel/logClusterPanel/logDingAssistant/
logQueryToolbar/logRbac/lokiLabelBrowse/metricsExplorer/middlewareMonit/
mwOverviewChart/portPolicyDialog/prometheusDashb/queryHistoryPan/savedQueriesPan/
siteMonitor/snmpMonitor/snmpOverviewChart/zabbixDashboard/zabbixDatasource
- kubernetes 42 个: deploymentBundle/deploymentEditAdvanced/deploymentEditService/
deploymentView/deploymentWorkload/eventsPage/kubernetesCluster/namespaceManage/
namespaceResource/podExecTerminal/podFileBrowser/podLogsViewer/podMetricsPage/
resourceVisualEditor/workloadViewPage
- aiops 17 个: agentCliMessage/aiAnalysisResult/analyzerHelpers/assistant/predictUtils
- agent 12 个: agentAlerts/agentMonitor/hostDetailDialog
- cloud 13 个: billingRecordDialog/billingRuleDialog/platformManager
- pipeline 6 个: buildNodesManage/deployRbac/deployTargetField
- system 3 个: auditSetting
- 58 个源文件中的 147 处 t()/i18n.t() 调用更新为语义化键路径
- 3 个命名空间冲突修复 (monitor.hostMonitor/agent.agentMonitor/aiops.aiAnalysisResult
原 string 值提升为 .title 子键)
- React Hooks 警告修复 (53→43, -10):
- exhaustive-deps 4→0: useMemo/useCallback 添加 t 到 deps 数组
- preserve-manual-memoization 5→0: 变量遮蔽修复 (filter(t)→filter(tg))
- 1 个冗余 eslint-disable 指令移除 (CronJobManager)
- zh/en 7480=7480 完全对齐, 0 个 hash key 残留
- tsc -b=0, npm build✓ (17.59s), ESLint errors=0/warnings=43/any=0
- go build=0, 17/17 集成测试通过, Docker healthy
50 lines
2.4 KiB
TypeScript
50 lines
2.4 KiB
TypeScript
// deployment-edit-service/IngressListItem.tsx — 单个 Ingress 卡片(关联高亮 + 路由规则)
|
|
// 纯展示组件:接收 ing + matched 状态 + 编辑/删除回调。
|
|
import { Button } from '@/components/ui/button';
|
|
import { Badge } from '@/components/ui/badge';
|
|
import { CheckCircle, GitBranch, Pencil, Server, Trash2 } from 'lucide-react';
|
|
import i18n from '@/i18n';
|
|
import type { IngSummary } from './types';
|
|
|
|
interface Props {
|
|
ing: IngSummary;
|
|
matched: boolean;
|
|
onEdit: () => void;
|
|
onDelete: () => void;
|
|
}
|
|
|
|
export function IngressListItem({ ing, matched, onEdit, onDelete }: Props) {
|
|
return (
|
|
<div className={`rounded-lg border p-3 ${matched ? 'border-purple-700/50 bg-purple-950/20' : 'border-[var(--dg-border)] bg-[var(--dg-bg-primary)]/30'}`}>
|
|
<div className="flex items-center gap-2 flex-wrap">
|
|
{matched ? <CheckCircle className="h-4 w-4 dg-text-purple" /> : <GitBranch className="h-4 w-4 dg-text-muted" />}
|
|
<span className="text-sm font-semibold text-[var(--dg-text-primary)]">{ing.name}</span>
|
|
<Badge variant="outline" className="border-[var(--dg-border)] dg-text-secondary text-[10px]">{ing.className}</Badge>
|
|
{matched && <Badge className="bg-purple-500/20 text-purple-300 border-purple-500/30 text-[10px]"> {i18n.t('kubernetes.deploymentEditService.associated')} </Badge>}
|
|
<Button size="sm" variant="ghost" className="h-6 text-xs dg-text-green ml-auto"
|
|
onClick={onEdit}>
|
|
<Pencil className="h-3 w-3 mr-1" />编辑
|
|
</Button>
|
|
<Button size="sm" variant="ghost" className="h-6 w-6 p-0 dg-text-red hover:dg-text-red"
|
|
title={i18n.t('kubernetes.ingress.deleteIngress')} onClick={onDelete}>
|
|
<Trash2 className="h-3 w-3" />
|
|
</Button>
|
|
</div>
|
|
{/* Rules */}
|
|
<div className="mt-2 space-y-1 text-[11px]">
|
|
{ing.rules.map((r, i) => (
|
|
<div key={i} className="flex items-start gap-1.5">
|
|
<Server className="h-3 w-3 dg-text-muted mt-0.5" />
|
|
<code className="text-[var(--dg-text-secondary)]">{r.host || '*'}</code>
|
|
{r.paths.map((p, j) => (
|
|
<code key={j} className="bg-[var(--dg-bg-tertiary)]/60 px-1.5 py-0.5 rounded dg-text-secondary">
|
|
{p.path} → {p.backend.service}:{String(p.backend.port)}
|
|
</code>
|
|
))}
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|