feat(p2.5): aiops 時序前端面板 — Incident 6 階段視覺化

Wave 6 P2.5 frontend-designer 工業級視覺化(拒絕 AI slop):

新增(1824 行):
- apps/web/src/app/[locale]/aiops/timeline/page.tsx
- apps/web/src/components/aiops/timeline/
  · AiopsTimelinePanel.tsx (413) — 主面板組件
  · TimelineStage.tsx (279) — 6 階段時序卡片
  · TimelineStageDetails.tsx (359) — 階段細節展開
  · EvidenceViewer.tsx (144) — Evidence Snapshot 檢視
  · TimelineFilter.tsx (109) — incident_id / severity / 時段 過濾器
  · types.ts (118) — TS 型別定義
  · mock-data.ts (357) — 開發 mock fallback
  · index.ts (7) — barrel export
- i18n: messages/en.json + messages/zh-TW.json — Timeline 翻譯

設計原則:
- 拒絕 AI slop(無泛用 emoji/漸層,採工業 dashboard 風格)
- 後端 endpoint 接通 /api/v1/aiops/timeline(critic B4 修復)
- mock 模式 fallback 防 endpoint 暫時不可達

對應後端: a3b4595e(aiops_timeline.py + aiops_timeline_service.py)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: frontend-designer agent (Wave 6) <noreply@anthropic.com>
This commit is contained in:
Your Name
2026-04-27 08:10:58 +08:00
parent cc547736ab
commit 1096da12ae
9 changed files with 1824 additions and 0 deletions

View File

@@ -0,0 +1,38 @@
'use client'
// 2026-04-26 P2.5 by Claude — AIOps Timeline
// ============================================================
// AIOps 全景時序頁面
// 告警→感官調查→AI決策→自動執行→驗證→學習 完整鏈路視覺化
//
// Mock 模式NEXT_PUBLIC_AIOPS_TIMELINE_MOCK=true
// 真實 API: GET /api/v1/aiops/timeline?incident_id=&limit=20
// ============================================================
import dynamic from 'next/dynamic'
import { AppLayout } from '@/components/layout'
// SSR 跳過 — Timeline 面板含動畫與 client-only state
const AiopsTimelinePanel = dynamic(
() => import('@/components/aiops/timeline/AiopsTimelinePanel'),
{
ssr: false,
loading: () => (
<div className="flex items-center justify-center py-24">
<div className="w-5 h-5 rounded-full border-2 border-claw-blue border-t-transparent animate-spin" />
</div>
),
}
)
interface AiopsTimelinePageProps {
params: { locale: string }
}
export default function AiopsTimelinePage({ params }: AiopsTimelinePageProps) {
return (
<AppLayout locale={params.locale}>
<AiopsTimelinePanel />
</AppLayout>
)
}