feat(web): S4+S5 處置統計環形圖 + 最近活動時間線 — Sprint 5R
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
- S4: DispositionMini 元件 (SVG 環形圖 + 四類列表) - S5: RecentActivity 元件 (時間線 + 色點 + JetBrains Mono) - 左欄改為 flex:6 可滾動多卡片列 - 右欄改為 flex:4 (60:40 比例) - 左欄結構: 活躍事件 → 處置統計 → 最近活動 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -28,6 +28,8 @@ import { PageTabs, type TabConfig } from '@/components/layout/page-tabs'
|
||||
import { LobsterLoading } from '@/components/shared/lobster-loading'
|
||||
import { ServiceTopology } from '@/components/topology'
|
||||
import { BarChart3, Flame, Telescope, FlaskConical, Activity, GitBranch } from 'lucide-react'
|
||||
import { DispositionMini } from '@/components/shared/disposition-mini'
|
||||
import { RecentActivity } from '@/components/shared/recent-activity'
|
||||
|
||||
const API_BASE = process.env.NEXT_PUBLIC_API_URL ?? ''
|
||||
|
||||
@@ -766,70 +768,78 @@ export default function Home({ params }: { params: { locale: string } }) {
|
||||
{/* ── 主體 2 欄 ─────────────────────────────────────────────────────── */}
|
||||
<div style={{ display: 'flex', flex: 1, overflow: 'hidden', padding: '14px 20px', gap: 20, background: '#f5f4ed' }}>
|
||||
|
||||
{/* ── Feed:活躍事件 (flex:1) ───────────────────────────────────── */}
|
||||
{/* ── 左欄 (60%): 活躍事件 + 處置統計 + 最近活動 ─────────────── */}
|
||||
<div style={{
|
||||
flex: 1,
|
||||
background: '#fff',
|
||||
border: '0.5px solid #e0ddd4',
|
||||
borderRadius: 12,
|
||||
overflow: 'hidden',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
boxShadow: '0 1px 4px rgba(0,0,0,0.05)',
|
||||
flex: 6, minWidth: 0, overflowY: 'auto',
|
||||
display: 'flex', flexDirection: 'column', gap: 14,
|
||||
paddingBottom: 40,
|
||||
}}>
|
||||
|
||||
{/* 活躍事件 */}
|
||||
<div style={{
|
||||
padding: '10px 14px',
|
||||
borderBottom: '0.5px solid #e0ddd4',
|
||||
display: 'flex', alignItems: 'center', gap: 8,
|
||||
flexShrink: 0, background: '#faf9f3',
|
||||
background: '#fff', border: '0.5px solid #e0ddd4', borderRadius: 10,
|
||||
overflow: 'hidden', boxShadow: '0 1px 3px rgba(0,0,0,0.04)', flexShrink: 0,
|
||||
}}>
|
||||
<div style={{ width: 6, height: 6, borderRadius: '50%', background: '#d97757', flexShrink: 0 }} />
|
||||
<span style={{ fontSize: 14, fontWeight: 700, color: '#141413', letterSpacing: '0.5px' }}>
|
||||
{tDashboard('activeIncidents')}
|
||||
</span>
|
||||
{(incidents?.length ?? 0) > 0 && (
|
||||
<span style={{
|
||||
fontSize: 12, background: 'rgba(217,119,87,0.1)', color: '#a04010',
|
||||
padding: '2px 8px', fontWeight: 700,
|
||||
border: '0.5px solid rgba(217,119,87,0.25)', borderRadius: 10,
|
||||
}}>
|
||||
{incidents?.length}
|
||||
<div style={{
|
||||
padding: '10px 14px', borderBottom: '0.5px solid #e0ddd4',
|
||||
display: 'flex', alignItems: 'center', gap: 8, background: '#faf9f3',
|
||||
}}>
|
||||
<div style={{ width: 6, height: 6, borderRadius: '50%', background: '#d97757', flexShrink: 0 }} />
|
||||
<span style={{ fontSize: 14, fontWeight: 700, color: '#141413', letterSpacing: '0.5px' }}>
|
||||
{tDashboard('activeIncidents')}
|
||||
</span>
|
||||
)}
|
||||
{(incidents?.length ?? 0) > 0 && (
|
||||
<span style={{
|
||||
fontSize: 12, background: 'rgba(217,119,87,0.1)', color: '#a04010',
|
||||
padding: '2px 8px', fontWeight: 700,
|
||||
border: '0.5px solid rgba(217,119,87,0.25)', borderRadius: 10,
|
||||
}}>
|
||||
{incidents?.length}
|
||||
</span>
|
||||
)}
|
||||
<span style={{ marginLeft: 'auto', fontSize: 11, color: '#4A90D9', cursor: 'pointer', fontWeight: 500 }}>查看全部告警 →</span>
|
||||
</div>
|
||||
|
||||
<div style={{ padding: '14px' }}>
|
||||
{isIncidentsLoading ? (
|
||||
<LobsterLoading size="sm" />
|
||||
) : incidentsError ? (
|
||||
<div style={{ padding: 16, fontSize: 13, color: '#cc2200' }}>{incidentsError}</div>
|
||||
) : (incidents?.length ?? 0) === 0 ? (
|
||||
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: 48, gap: 8 }}>
|
||||
<div style={{ width: 8, height: 8, borderRadius: '50%', background: '#22C55E' }} />
|
||||
<span style={{ fontSize: 13, color: '#87867f' }}>{tDashboard('stable')} · 0 {tDashboard('activeIncidents')}</span>
|
||||
</div>
|
||||
) : (
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
|
||||
{incidents?.map((incident) => (
|
||||
<IncidentCard
|
||||
key={incident.incident_id}
|
||||
incident={incident}
|
||||
decision={incident.decision}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ flex: 1, overflowY: 'auto', padding: '14px' }}>
|
||||
{isIncidentsLoading ? (
|
||||
<LobsterLoading size="sm" />
|
||||
) : incidentsError ? (
|
||||
<div style={{ padding: 16, fontSize: 13, color: '#cc2200' }}>{incidentsError}</div>
|
||||
) : (incidents?.length ?? 0) === 0 ? (
|
||||
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: 48, gap: 8 }}>
|
||||
<div style={{ width: 8, height: 8, borderRadius: '50%', background: '#22C55E' }} />
|
||||
<span style={{ fontSize: 13, color: '#87867f' }}>{tDashboard('stable')} · 0 {tDashboard('activeIncidents')}</span>
|
||||
</div>
|
||||
) : (
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
|
||||
{incidents?.map((incident) => (
|
||||
<IncidentCard
|
||||
key={incident.incident_id}
|
||||
incident={incident}
|
||||
decision={incident.decision}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{/* 處置統計迷你版 (S4) */}
|
||||
<DispositionMini />
|
||||
|
||||
{/* 最近活動 (S5) */}
|
||||
<RecentActivity />
|
||||
|
||||
</div>
|
||||
|
||||
{/* ── Right Panel:AI + Infra (width:530px) ────────────────────── */}
|
||||
{/* ── 右欄 (40%): OpenClaw + 基礎架構 + 監控工具 ─────────────── */}
|
||||
<div style={{
|
||||
width: 530,
|
||||
flexShrink: 0,
|
||||
flex: 4, minWidth: 0,
|
||||
overflowY: 'auto',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: 14,
|
||||
paddingBottom: 40,
|
||||
}}>
|
||||
|
||||
{/* WoooClaw + Reasoning Stream */}
|
||||
|
||||
Reference in New Issue
Block a user