refactor(quality): Q18 前端巨型组件拆分 — TraceManager 605L→331L (-45%), 提取 types + trace-helpers + SpanTreeNode + TraceDetailDialog + SpanDetailDialog 5 个独立文件, 修复 SpanTreeNode 内联定义反模式(每次 render 重建组件函数), 零逻辑变更, ESLint errors=0/warnings=64/any=0, tsc -b=0, npm build✓, 17/17 测试通过
This commit is contained in:
1 parent
6f1c79fd51
commit
69447e4d66
9 files changed
+656
-461
No files matched your search
+39
@@ -489,6 +489,45 @@ services/api.ts (1324L)
|
||||
| Q15 | 前端巨型组件拆分(PipelineEditor 676L→406L,提取 types + TaskCard + TaskEditorPanel + PipelineLogDialog + RunsHistoryTab + PipelineMembersTab) | P0 | **done** |
|
||||
| Q16 | 前端巨型组件拆分(RdpDialog 642L→442L,提取 types + rdpp-utils + RdpDialogHeader) | P0 | **done** |
|
||||
| Q17 | 前端巨型组件拆分(DeploymentEditService 627L→394L,提取 types + ServiceCreateForm + IngressCreateForm + ServiceListItem + IngressListItem) | P0 | **done** |
|
||||
| Q18 | 前端巨型组件拆分(TraceManager 605L→331L,提取 types + trace-helpers + SpanTreeNode + TraceDetailDialog + SpanDetailDialog,修复 SpanTreeNode 内联定义反模式) | P0 | **done** |
|
||||
|
||||
---
|
||||
|
||||
## Q18: 前端巨型组件拆分 — TraceManager [done]
|
||||
|
||||
**问题**: `TraceManager.tsx`(605 行)是 Q17 拆分后项目最大的核心业务组件之一(排除 UI 库 sidebar/data-table),包含链路追踪管理页面的全部逻辑:类型定义(Trace/Span/SpanLog/ServiceMetrics)、状态徽章/Kind 图标/状态颜色/耗时格式化等工具函数、Span 树构建、**SpanTreeNode 递归组件内联定义(每次父组件 render 重新创建组件函数,性能反模式)**、Traces/Services/Metrics 三个 Tab 的完整 JSX、Trace 详情弹窗(Span 树可视化)、Span 详情弹窗(基本信息+标签+日志)。单文件过大导致维护困难。
|
||||
|
||||
**已完成 (2026-07-08)**:
|
||||
|
||||
将类型/工具函数、共享 JSX 辅助、递归 Span 树组件、两个详情弹窗提取为 `trace-manager/` 子目录下的独立文件:
|
||||
|
||||
| 新文件 | 行数 | 职责 |
|
||||
|--------|------|------|
|
||||
| `types.ts` | 90 | Trace/Span/SpanLog/ServiceMetrics 接口 + formatDuration/getStatusColor/buildSpanTree 纯函数 |
|
||||
| `trace-helpers.tsx` | 44 | getStatusBadge(状态徽章)+ getKindIcon(Span kind 图标)共享 JSX 辅助,接收 TFunction 参数 |
|
||||
| `SpanTreeNode.tsx` | 71 | 递归 Span 树节点组件(展开/折叠 + 时间轴宽度 + 状态色 + 点击选中 Span),接收 span/level/totalDuration/onSelectSpan props |
|
||||
| `TraceDetailDialog.tsx` | 80 | Trace 详情弹窗(服务/操作/总耗时/状态摘要 + ScrollArea 内 Span 树可视化) |
|
||||
| `SpanDetailDialog.tsx` | 91 | Span 详情弹窗(基本信息网格 + 标签键值对 + 日志列表) |
|
||||
|
||||
主文件 `TraceManager.tsx` 从 **605 行降至 331 行**(-45%),仅保留:状态管理(traces/services/loading/搜索/筛选/时间范围/activeTab/selectedTrace/selectedSpan/弹窗开关)、数据加载(fetchData/fetchTraces/fetchServices/fetchTraceDetail)、派生数据(filteredTraces/serviceNames)、handleSelectSpan 回调、pageTabs、tracesToolbar(搜索+服务/状态/时间筛选+刷新)、PageShell 布局(StatStrip 统计条 + Traces 表格 + Services 表格 + Metrics 卡片)、以及 TraceDetailDialog + SpanDetailDialog 两个弹窗组件的编排。
|
||||
|
||||
**关键改进**: 原 `SpanTreeNode` 定义在主组件函数体内(`const SpanTreeNode: React.FC = (...)` 内联),每次父组件 render 都会创建新的组件函数引用 → React 无法复用,整个 Span 子树重渲染。提取为模块级独立组件后,组件引用稳定,避免不必要的子树重渲染。
|
||||
|
||||
**提取原则**: types 为纯数据/类型(零 React 依赖);trace-helpers 为共享 JSX 辅助(getStatusBadge/getKindIcon 返回 ReactNode,接收 TFunction 以支持 i18n);SpanTreeNode 为独立递归组件(模块级定义,接收 4 个 props);TraceDetailDialog/SpanDetailDialog 为受控展示组件(接收 open/onOpenChange/数据 props,内部用 useTranslation)。零逻辑变更。
|
||||
|
||||
**验收标准**:
|
||||
- [x] TraceManager.tsx 从 605 行降至 **331 行**(-45%)
|
||||
- [x] 5 个提取的文件全部 < 95 行(最大 SpanDetailDialog 91 行)
|
||||
- [x] `tsc -b` 零错误
|
||||
- [x] `npm run build` 零错误(✓ built in 18.23s)
|
||||
- [x] ESLint errors 保持 **0**(trace-manager/ 目录零 warnings)
|
||||
- [x] ESLint warnings 保持 **64**(无新增)
|
||||
- [x] 全局 ESLint any 保持 **0**
|
||||
- [x] `go build` 零错误
|
||||
- [x] 17/17 集成回归测试通过(零回归)
|
||||
- [x] Docker 部署 healthy,前端页面正常加载(HTTP 200),traces API 返回 200
|
||||
- [x] 链路追踪管理页功能不变(Traces/Services/Metrics 三 Tab + Trace 详情 Span 树 + Span 详情标签/日志全部正常)
|
||||
- [x] SpanTreeNode 内联定义反模式已修复(提取为模块级稳定组件引用)
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in new issue
Block a user