1. Tab 結構規格書: 每個新頁面的 Tab 配置、區塊佈局、元件複用方式 2. 路由對照表: 26 個舊 URL → 新位置的精確映射 + redirect 實作方式 3. 元件抽取計畫: 17 個頁面抽取為 Panel 元件的步驟和目錄結構 4. API 變更規格: DashboardResponse +3 欄位 + SSE +1 事件 (不新增 API) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
4.8 KiB
4.8 KiB
Sprint 5 — 元件抽取計畫
哪些頁面需要抽取為獨立元件,以便在 Tab 容器中複用
抽取原則
- 只移動,不修改邏輯 — 確保功能零損失
- 保留原始 page.tsx 做 redirect — 舊連結不失效
- 元件接收 props 而非自行 fetch — 父層 (Tab 容器) 負責資料載入
- i18n 不變 — 繼續使用原有的
useTranslations()namespace
抽取清單
高優先 (AI 指令中心需要)
| # | 原始頁面 | 抽取為 | 放置位置 | 行數 | 用於 |
|---|---|---|---|---|---|
| 1 | /alerts/page.tsx |
AlertsPanel.tsx |
components/panels/ |
183 | AI 中心 Tab 2 左側 |
| 2 | /reports/page.tsx |
DispositionPanel.tsx |
components/panels/ |
317 | AI 中心 Tab 4 |
中優先 (其他整合頁面需要)
| # | 原始頁面 | 抽取為 | 放置位置 | 行數 | 用於 |
|---|---|---|---|---|---|
| 3 | /monitoring/page.tsx |
MonitoringPanel.tsx |
components/panels/ |
269 | 可觀測性 Tab 1 |
| 4 | /apm/page.tsx |
APMPanel.tsx |
components/panels/ |
128 | 可觀測性 Tab 2 |
| 5 | /errors/page.tsx |
ErrorsPanel.tsx |
components/panels/ |
164 | 可觀測性 Tab 3 |
| 6 | /apps/page.tsx |
AppsPanel.tsx |
components/panels/ |
103 | 可觀測性 Tab 4 |
| 7 | /services/page.tsx |
ServicesPanel.tsx |
components/panels/ |
120 | 可觀測性 Tab 5 |
| 8 | /auto-repair/page.tsx |
AutoRepairPanel.tsx |
components/panels/ |
460 | 自動化 Tab 1 |
| 9 | /neural-command/page.tsx |
NeuralCommandPanel.tsx |
components/panels/ |
209 | 自動化 Tab 2 |
| 10 | /drift/page.tsx |
DriftPanel.tsx |
components/panels/ |
324 | 自動化 Tab 3 |
| 11 | /deployments/page.tsx |
DeploymentsPanel.tsx |
components/panels/ |
113 | 營運 Tab 1 |
| 12 | /tickets/page.tsx |
TicketsPanel.tsx |
components/panels/ |
120 | 營運 Tab 2 |
| 13 | /cost/page.tsx |
CostPanel.tsx |
components/panels/ |
95 | 營運 Tab 3 |
| 14 | /action-logs/page.tsx |
ActionLogsPanel.tsx |
components/panels/ |
551 | 營運 Tab 4 |
| 15 | /billing/page.tsx |
BillingPanel.tsx |
components/panels/ |
113 | 營運 Tab 5 |
| 16 | /security/page.tsx |
SecurityPanel.tsx |
components/panels/ |
137 | 安全合規 Tab 1 |
| 17 | /compliance/page.tsx |
CompliancePanel.tsx |
components/panels/ |
124 | 安全合規 Tab 2 |
抽取步驟 (以 AlertsPanel 為例)
Step 1: 建立 Panel 元件
// apps/web/src/components/panels/AlertsPanel.tsx
'use client'
// 從原始 /alerts/page.tsx 移入完整內容
// 唯一差異: 移除 AppLayout wrapper (由 Tab 容器提供)
import { useTranslations } from 'next-intl'
// ... 原始 import 保留 ...
// 移除 export default function AlertsPage({ params })
// 改為:
export function AlertsPanel() {
const t = useTranslations('alerts')
// ... 原始邏輯完全不動 ...
return (
// 移除 <AppLayout> wrapper
// 只保留內部內容
<div className="space-y-4">
{/* 原始告警列表內容 */}
</div>
)
}
Step 2: 原始頁面改為 redirect
// apps/web/src/app/[locale]/alerts/page.tsx
import { redirect } from 'next/navigation'
export default function AlertsPage() {
redirect('/?tab=alerts')
}
Step 3: 在 Tab 容器中使用
// apps/web/src/app/[locale]/page.tsx (AI 指令中心)
import { lazy, Suspense } from 'react'
const AlertsPanel = lazy(() => import('@/components/panels/AlertsPanel').then(m => ({ default: m.AlertsPanel })))
// Tab 2 內容:
<Suspense fallback={<Skeleton />}>
<AlertsPanel />
</Suspense>
新建目錄結構
apps/web/src/components/panels/
├── index.ts # 匯出所有 Panel
├── AlertsPanel.tsx # 從 /alerts 抽取
├── DispositionPanel.tsx # 從 /reports 抽取
├── MonitoringPanel.tsx # 從 /monitoring 抽取
├── APMPanel.tsx # 從 /apm 抽取
├── ErrorsPanel.tsx # 從 /errors 抽取
├── AppsPanel.tsx # 從 /apps 抽取
├── ServicesPanel.tsx # 從 /services 抽取
├── AutoRepairPanel.tsx # 從 /auto-repair 抽取
├── NeuralCommandPanel.tsx # 從 /neural-command 抽取
├── DriftPanel.tsx # 從 /drift 抽取
├── DeploymentsPanel.tsx # 從 /deployments 抽取
├── TicketsPanel.tsx # 從 /tickets 抽取
├── CostPanel.tsx # 從 /cost 抽取
├── ActionLogsPanel.tsx # 從 /action-logs 抽取
├── BillingPanel.tsx # 從 /billing 抽取
├── SecurityPanel.tsx # 從 /security 抽取
└── CompliancePanel.tsx # 從 /compliance 抽取
共 17 個 Panel 元件