From 195b6945b4e76e5b69d0828610f762ff1fe100c9 Mon Sep 17 00:00:00 2001 From: attacker Date: Thu, 9 Jul 2026 20:51:11 +0800 Subject: [PATCH] =?UTF-8?q?refactor(quality):=20Q31=20=E5=89=8D=E7=AB=AF?= =?UTF-8?q?=E5=B7=A8=E5=9E=8B=E7=BB=84=E4=BB=B6=E6=8B=86=E5=88=86=20?= =?UTF-8?q?=E2=80=94=20PromDsFormDialog=20528L=E2=86=92294L=20(-44%),=20?= =?UTF-8?q?=E6=8F=90=E5=8F=96=20prometheus-ds/=206=20=E4=B8=AA=E6=96=87?= =?UTF-8?q?=E4=BB=B6=20(CollapsibleSection=2042L=20=E9=80=9A=E7=94=A8?= =?UTF-8?q?=E6=8A=98=E5=8F=A0=E5=8C=85=E8=A3=85=E5=99=A8=20DRY=203=20?= =?UTF-8?q?=E4=B8=AA=E9=87=8D=E5=A4=8D=E6=8A=98=E5=8F=A0=E6=A8=A1=E5=BC=8F?= =?UTF-8?q?=20+=20AuthSection=20107L=20=E8=AE=A4=E8=AF=81=E6=8A=98?= =?UTF-8?q?=E5=8F=A0=20+=20HeadersSection=2064L=20=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89Headers=20+=20AlertingSection=2058L=20=E5=91=8A?= =?UTF-8?q?=E8=AD=A6=E6=8A=98=E5=8F=A0=20+=20MiscSection=2047L=20=E6=9D=82?= =?UTF-8?q?=E9=A1=B9=E6=8A=98=E5=8F=A0=20+=20TestResultBanner=2032L=20?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E7=BB=93=E6=9E=9C=E6=A8=AA=E5=B9=85),=20Auth?= =?UTF-8?q?/Alerting/Misc=20=E4=B8=89=E4=B8=AA=E6=8A=98=E5=8F=A0=E5=8C=BA?= =?UTF-8?q?=E5=9D=97=E7=BB=9F=E4=B8=80=E4=BD=BF=E7=94=A8=20CollapsibleSect?= =?UTF-8?q?ion=20=E6=B6=88=E9=99=A4=20~30=20=E8=A1=8C=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E6=8A=98=E5=8F=A0=20JSX,=20updateForm=20=E6=B3=9B=E5=9E=8B?= =?UTF-8?q?=E5=8C=96=20=20=E7=B1=BB=E5=9E=8B=E5=AE=89?= =?UTF-8?q?=E5=85=A8=E6=8F=90=E5=8D=87,=20=E9=9B=B6=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E5=8F=98=E6=9B=B4,=20ESLint=20errors=3D0/warnings=3D65/any=3D0?= =?UTF-8?q?,=20tsc=20-b=3D0,=20npm=20build=E2=9C=93=20(17.65s),=20go=20bui?= =?UTF-8?q?ld=3D0,=2017/17=20=E6=B5=8B=E8=AF=95=E9=80=9A=E8=BF=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PROJECT_EVALUATION.md | 2 +- ROADMAP.md | 42 ++- .../prometheus-ds/AlertingSection.tsx | 58 ++++ .../datasource/prometheus-ds/AuthSection.tsx | 107 +++++++ .../prometheus-ds/CollapsibleSection.tsx | 42 +++ .../prometheus-ds/HeadersSection.tsx | 64 +++++ .../datasource/prometheus-ds/MiscSection.tsx | 47 ++++ .../prometheus-ds/PromDsFormDialog.tsx | 261 +----------------- .../prometheus-ds/TestResultBanner.tsx | 32 +++ 9 files changed, 405 insertions(+), 250 deletions(-) create mode 100644 frontend/src/components/monitor/datasource/prometheus-ds/AlertingSection.tsx create mode 100644 frontend/src/components/monitor/datasource/prometheus-ds/AuthSection.tsx create mode 100644 frontend/src/components/monitor/datasource/prometheus-ds/CollapsibleSection.tsx create mode 100644 frontend/src/components/monitor/datasource/prometheus-ds/HeadersSection.tsx create mode 100644 frontend/src/components/monitor/datasource/prometheus-ds/MiscSection.tsx create mode 100644 frontend/src/components/monitor/datasource/prometheus-ds/TestResultBanner.tsx diff --git a/PROJECT_EVALUATION.md b/PROJECT_EVALUATION.md index f9820bb..29b2c8a 100644 --- a/PROJECT_EVALUATION.md +++ b/PROJECT_EVALUATION.md @@ -129,7 +129,7 @@ | ~~`api.ts` 1324 行/352 方法~~ → 已拆分为 12 个域文件 (api/kubernetes.ts, deploy.ts, monitor.ts 等) | ✅ 已解决 | 前端 | ~~P0~~ done | | 前端 **1026 处** `any` 类型 | 类型安全缺失,重构风险高 | 前端全局 | ~~P0~~ **done** (any 1076→40, unused 25→6, console 93→1, tsc --noEmit=0) | | ~~K8s 双路由体系(集群域+Kuboard 域)~~ → code 路由统一为主,ID 路由标记 deprecated 向后兼容 | ✅ 已解决 | 后端 | ~~P1~~ done | -| 25 个 ≥500 行巨型组件 | 拆分困难 | 前端 | P1 → **Q6-Q27 done: 最大组件 ResourceVisualEditor 882L→282L (-68%) + AgentCLI 814L→521L (-36%) + SystemSettingsTab 754L→173L (-77%) + NamespaceResourcePage 719L→300L (-58%) + ApprovalWorkflowPage 705L→167L (-76%) + PipelineRunDetail 678L→273L (-60%) + CloudServerImport 699L→404L (-42%,any[]→具体接口) + UnifiedQueryPanel 682L→529L (-22%) + ServerManager 652L→442L (-32%) + PipelineEditor 676L→406L (-40%) + RdpDialog 642L→442L (-31%) + DeploymentEditService 627L→394L (-37%) + TraceManager 605L→331L (-45%,修复 SpanTreeNode 内联定义反模式) + GrafanaDashboard 624L→78L (-87%,DRY 合并 Zabbix/Prometheus Tab + 移除文件级 eslint-disable + 类型安全升级) + TopologyView 596L→472L (-21%) + DeploymentEditAdvanced 590L→289L (-51%) + WorkloadViewPage 572L→348L (-39%) + CloudAccountManager 572L→308L + ExcelServerImport 560L→385L + PipelineCreateDialog 559L→498L + PodLogsViewer 553L→331L (-40%) + HostMonitor 547L→224L (-59%) + KubernetesClusterDetail 547L→130L (-76%) + **AlertCenter 542L→312L (-42%,提取 4 个受控组件: AlertsToolbar + AlertsTab + ContactsTab + ContactGroupsTab,客户端搜索过滤+删除确认逻辑下沉到子组件)** + **CloudBilling 534L→295L (-45%,提取 cloud-billing/ 3 个文件: OverviewTab + RecordsTab(含 RecordsFilterToolbar) + AlertRulesTab)**,累计提取 106 个独立组件文件** | +| 25 个 ≥500 行巨型组件 | 拆分困难 | 前端 | P1 → **Q6-Q27 done: 最大组件 ResourceVisualEditor 882L→282L (-68%) + AgentCLI 814L→521L (-36%) + SystemSettingsTab 754L→173L (-77%) + NamespaceResourcePage 719L→300L (-58%) + ApprovalWorkflowPage 705L→167L (-76%) + PipelineRunDetail 678L→273L (-60%) + CloudServerImport 699L→404L (-42%,any[]→具体接口) + UnifiedQueryPanel 682L→529L (-22%) + ServerManager 652L→442L (-32%) + PipelineEditor 676L→406L (-40%) + RdpDialog 642L→442L (-31%) + DeploymentEditService 627L→394L (-37%) + TraceManager 605L→331L (-45%,修复 SpanTreeNode 内联定义反模式) + GrafanaDashboard 624L→78L (-87%,DRY 合并 Zabbix/Prometheus Tab + 移除文件级 eslint-disable + 类型安全升级) + TopologyView 596L→472L (-21%) + DeploymentEditAdvanced 590L→289L (-51%) + WorkloadViewPage 572L→348L (-39%) + CloudAccountManager 572L→308L + ExcelServerImport 560L→385L + PipelineCreateDialog 559L→498L + PodLogsViewer 553L→331L (-40%) + HostMonitor 547L→224L (-59%) + KubernetesClusterDetail 547L→130L (-76%) + **AlertCenter 542L→312L (-42%,提取 4 个受控组件: AlertsToolbar + AlertsTab + ContactsTab + ContactGroupsTab,客户端搜索过滤+删除确认逻辑下沉到子组件)** + **CloudBilling 534L→295L (-45%,提取 cloud-billing/ 3 个文件: OverviewTab + RecordsTab(含 RecordsFilterToolbar) + AlertRulesTab)** + **PromDsFormDialog 528L→294L (-44%,提取 6 个文件: CollapsibleSection 通用折叠包装器 DRY 3 个重复折叠模式 + AuthSection + HeadersSection + AlertingSection + MiscSection + TestResultBanner)**,累计提取 112 个独立组件文件** | ### 3.2 🟡 中优先级 diff --git a/ROADMAP.md b/ROADMAP.md index 9dc5dd3..825f70a 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -501,7 +501,47 @@ services/api.ts (1324L) | Q27 | 前端巨型组件拆分(HostMonitor 547L→224L (-59%),提取 host-monitor/tabs/ 8 个文件 (BasicTab + DiskTab + NetworkTab + PortMonitorTab + ProcessTable + FDUsageCard + ContextSwitchCard + ProcessTab),TABS 常量数组提取为模块级,PCT_REF_LINES 常量提升到 types.ts,端口/进程数组类型 JsonData→JsonData[] 类型安全升级) | P0 | **done** | | Q28 | 前端巨型组件拆分(KubernetesClusterDetail 547L→130L (-76%),提取 cluster-detail/ 8 个文件 (types(computeClusterMetrics/buildTrendData 纯函数) + OverviewTab + NodesTab + PodsTab + DeploymentsTab + ServicesTab + IngressesTab + EventsTab)) | P0 | **done** | | Q29 | 前端巨型组件拆分(AlertCenter 542L→312L (-42%),提取 4 个受控组件 (AlertsToolbar 89L 筛选工具栏 + AlertsTab 149L 告警列表表格+分页 + ContactsTab 87L 联系人卡片网格 + ContactGroupsTab 88L 联系组卡片网格),客户端搜索过滤逻辑移入 AlertsTab,删除确认逻辑下沉到子组件) | P0 | **done** | -| Q30 | 前端巨型组件拆分(CloudBilling 534L→295L (-45%),提取 cloud-billing/ 3 个文件 (OverviewTab 110L 概览统计:同步信息+成本告警横幅+趋势图+厂商分布 + RecordsTab 146L 成本记录表格+筛选工具栏 + AlertRulesTab 91L 预警规则卡片网格)) | P0 | **done** | +| Q30 | 前端巨型组件拆分(CloudBilling 534L→295L (-45%),提取 cloud-billing/ 3 个文件 (OverviewTab 110L 概览统计:同步信息+成本告警横幅+趋势图+厂商分布 + RecordsTab 146L 成本记录表格+RecordsFilterToolbar筛选工具栏 + AlertRulesTab 91L 预警规则卡片网格)) | P0 | **done** | +| Q31 | 前端巨型组件拆分(PromDsFormDialog 528L→294L (-44%),提取 6 个文件 (CollapsibleSection 42L 通用折叠包装器 DRY 3 个重复折叠模式 + AuthSection 107L 认证折叠 + HeadersSection 64L 自定义Headers + AlertingSection 58L 告警折叠 + MiscSection 47L 杂项折叠 + TestResultBanner 32L 测试结果横幅),3 个折叠区块全部使用共享 CollapsibleSection 消除重复 JSX)) | P0 | **done** | + +--- + +## Q31: 前端巨型组件拆分 — PromDsFormDialog [done] + +**问题**: `PromDsFormDialog.tsx`(528 行)是 Q30 拆分后项目最大的监控业务组件之一,包含 Prometheus 数据源添加/编辑弹窗的全部逻辑:表单状态管理(8 个 useState + form 对象)、初始化 effect、保存/测试连接业务逻辑、以及 8 个内联 JSX 区块(Name&Default ~23 行 / HTTP 设置 ~29 行 / Auth 折叠 ~97 行 / Custom HTTP Headers ~38 行 / Alerting 折叠 ~40 行 / 采集与查询 ~32 行 / HTTP Method ~12 行 / Misc 折叠 ~35 行 / 测试结果横幅 ~18 行)。其中 3 个折叠区块(Auth/Alerting/Misc)各自重复实现了相同的折叠 header+展开/折叠 UI 模式(按钮 + ChevronUp/Down 图标 + children 容器)。单文件过大导致维护困难。 + +**已完成 (2026-07-09)**: + +将 5 个内容区块和 1 个共享折叠包装器提取为 `prometheus-ds/` 目录下的独立文件(该目录此前已有 types.ts + helpers.ts): + +| 新文件 | 行数 | 职责 | +|--------|------|------| +| `CollapsibleSection.tsx` | 42 | 通用可折叠区块包装器(按钮 header + icon + title + ChevronUp/Down 切换 + children 容器),DRY 消除 Auth/Alerting/Misc 三处重复的折叠 UI 模式 | +| `AuthSection.tsx` | 107 | Auth 认证折叠区块(Basic auth 开关+用户名密码 / With Credentials / TLS Client Auth+CA Cert 文本域 / Skip TLS Verify / Forward OAuth Identity 提示),受控组件接收 form + updateForm + open + onToggle | +| `HeadersSection.tsx` | 64 | Custom HTTP Headers 区块(标题栏+Add header 按钮 + header/value 键值对 Input 行增删改 + 空状态提示),受控组件接收 headers + onAdd/onRemove/onUpdate | +| `AlertingSection.tsx` | 58 | Alerting 告警折叠区块(Manage alerts 开关 + Alertmanager 数据源 Select 下拉,过滤自身),受控组件接收 form + updateForm + sources + editingId + open + onToggle | +| `MiscSection.tsx` | 47 | Misc 杂项折叠区块(Disable metrics lookup 开关 + Custom query parameters Input),受控组件接收 form + updateForm + open + onToggle | +| `TestResultBanner.tsx` | 32 | 连接测试结果横幅(成功绿色 CheckCircle / 失败红色 XCircle + target_count 徽章),纯展示组件接收 result(null 时不渲染) | + +主文件 `PromDsFormDialog.tsx` 从 **528 行降至 294 行**(-44%),仅保留:8 个 useState 声明(form/headers/showAuth/showTLS/showAlerting/showMisc/testing/testResult)、初始化 useEffect、updateForm/addHeader/removeHeader/updateHeader 回调、handleSave/handleTestConnection 业务逻辑、Dialog 外壳(header + Name&Default + HTTP 设置 + 5 个子组件编排 + 采集与查询 + HTTP Method + Footer 按钮)。 + +**关键改进**: +- **DRY 折叠模式**: 原 Auth/Alerting/Misc 三个折叠区块各自重复了相同的折叠 header(button + icon + title + ChevronUp/Down + 展开 children 容器)共约 30 行重复 JSX。提取为共享 `CollapsibleSection` 组件后,三个 Section 组件只需传入 icon/title/open/onToggle + children 即可,消除全部重复。 +- **受控组件架构**: 5 个子组件全部为受控展示组件(接收 form/headers 状态 + updateForm/onToggle 回调 props),无独立状态。所有状态管理保留在主组件,拆分为纯机械操作(移动 JSX + 添加 props 透传),零逻辑变更。 +- **updateForm 泛型化**: 原 `updateForm(field, value)` 函数参数类型为 `keyof PromDsForm` + `PromDsForm[keyof PromDsForm]`(宽松联合类型)。提取到子组件时改为 `(field: K, value: PromDsForm[K])` 泛型约束,使子组件调用 `updateForm('basic_auth', v)` 时 v 自动推断为 boolean,类型安全更好。 + +**验收标准**: +- [x] PromDsFormDialog.tsx 从 528 行降至 **294 行**(-44%) +- [x] 6 个提取的文件全部 < 108 行(最大 AuthSection 107 行,最小 TestResultBanner 32 行) +- [x] `tsc -b` 零错误 +- [x] `npm run build` 零错误(✓ built in 17.65s) +- [x] ESLint errors 保持 **0**(prometheus-ds/ 目录零 errors/warnings) +- [x] ESLint warnings 保持 **65**(无新增) +- [x] 全局 ESLint any 保持 **0** +- [x] `go build` 零错误 +- [x] 17/17 集成回归测试通过(零回归) +- [x] Docker 部署 healthy,前端页面正常服务 +- [x] Prometheus 数据源弹窗功能不变(Name/Default/HTTP/Auth折叠/Custom Headers/Alerting折叠/采集与查询/HTTP Method/Misc折叠/测试连接/保存全部正常) --- diff --git a/frontend/src/components/monitor/datasource/prometheus-ds/AlertingSection.tsx b/frontend/src/components/monitor/datasource/prometheus-ds/AlertingSection.tsx new file mode 100644 index 0000000..d9836f2 --- /dev/null +++ b/frontend/src/components/monitor/datasource/prometheus-ds/AlertingSection.tsx @@ -0,0 +1,58 @@ +// Prometheus 数据源表单 — Alerting 告警设置区块 + +import { AlertTriangle } from 'lucide-react'; +import { Switch } from '@/components/ui/switch'; +import { Label } from '@/components/ui/label'; +import { + Select, SelectContent, SelectItem, SelectTrigger, SelectValue, +} from '@/components/ui/select'; +import { useTranslation } from 'react-i18next'; + +import type { PromDS, PromDsForm } from './types'; +import CollapsibleSection from './CollapsibleSection'; + +interface AlertingSectionProps { + form: PromDsForm; + updateForm: (field: K, value: PromDsForm[K]) => void; + sources: PromDS[]; + editingId: number | null; + open: boolean; + onToggle: () => void; +} + +/** Alerting 折叠区块(启用告警 + Alertmanager 数据源选择) */ +export default function AlertingSection({ + form, updateForm, sources, editingId, open, onToggle, +}: AlertingSectionProps) { + const { t } = useTranslation(['monitor', 'common']); + return ( + +
+ updateForm('enable_alerting', v)} + /> + +
+
+ + +
+
+ ); +} diff --git a/frontend/src/components/monitor/datasource/prometheus-ds/AuthSection.tsx b/frontend/src/components/monitor/datasource/prometheus-ds/AuthSection.tsx new file mode 100644 index 0000000..8e736c9 --- /dev/null +++ b/frontend/src/components/monitor/datasource/prometheus-ds/AuthSection.tsx @@ -0,0 +1,107 @@ +// Prometheus 数据源表单 — Auth 认证设置区块 + +import { Shield } from 'lucide-react'; +import { Switch } from '@/components/ui/switch'; +import { Label } from '@/components/ui/label'; +import { Input } from '@/components/ui/input'; +import { useTranslation } from 'react-i18next'; + +import type { PromDsForm } from './types'; +import CollapsibleSection from './CollapsibleSection'; + +interface AuthSectionProps { + form: PromDsForm; + updateForm: (field: K, value: PromDsForm[K]) => void; + open: boolean; + onToggle: () => void; +} + +/** Auth 认证折叠区块(Basic auth / With Credentials / TLS Client Auth / Skip TLS Verify) */ +export default function AuthSection({ form, updateForm, open, onToggle }: AuthSectionProps) { + const { t } = useTranslation(['monitor']); + return ( + +
+
+ updateForm('basic_auth', v)} + /> + +
+ {form.basic_auth && ( +
+ updateForm('basic_auth_user', e.target.value)} + className="bg-[var(--dg-bg-tertiary)] border-[var(--dg-border)] text-sm" + /> + updateForm('basic_auth_pass', e.target.value)} + className="bg-[var(--dg-bg-tertiary)] border-[var(--dg-border)] text-sm" + /> +
+ )} +
+ +
+ updateForm('with_credentials', v)} + /> + +
+ +
+
+ updateForm('tls_client_auth', v)} + /> + +
+ {form.tls_client_auth && ( +
+
+ updateForm('with_ca_cert', v)} + /> + +
+ {form.with_ca_cert && ( +