fix(web): 首頁全面 QA 修復 — hosts 數據 + incident 標題 + i18n + 字體
Some checks failed
E2E Health Check / e2e-health (push) Successful in 17s
CD Pipeline / build-and-deploy (push) Has been cancelled

- HostGrid 接 useHosts() SSE 數據(不再傳空陣列)
- IncidentCard 標題從 description?? '--' 改為 decision.action ?? services + 異常
- 6 處硬編碼中文改 i18n (活躍事件/載入中/系統穩定/OpenClaw認知引擎/基礎架構)
- fontFamily: Inter/monospace → var(--font-body) 全部替換
- 新增 dashboard.openclawEngine / infrastructure i18n keys

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
OG T
2026-04-02 13:33:48 +08:00
parent 1628f659e3
commit 1f174e1268
4 changed files with 34 additions and 20 deletions

View File

@@ -138,7 +138,9 @@
"autoRemediationRate": "Auto Remediation",
"mttrAvg": "MTTR Avg",
"stable": "Stable",
"normal": "Normal"
"normal": "Normal",
"openclawEngine": "OPENCLAW COGNITIVE ENGINE",
"infrastructure": "INFRASTRUCTURE"
},
"openclaw": {
"name": "OpenClaw",
@@ -304,8 +306,10 @@
"waitingCommander": ">_ Awaiting commander approval (Tier {tier})",
"suggestedAction": "> Suggested action:",
"authorize": "Authorize",
"reject": "Reject"
}
"reject": "Reject",
"anomaly": "anomaly"
},
"anomaly": "anomaly"
},
"status": {
"idle": "Idle",

View File

@@ -139,7 +139,9 @@
"autoRemediationRate": "自動處置率",
"mttrAvg": "MTTR 均值",
"stable": "穩定",
"normal": "正常"
"normal": "正常",
"openclawEngine": "OPENCLAW 認知引擎",
"infrastructure": "基礎架構"
},
"openclaw": {
"name": "OpenClaw",
@@ -305,8 +307,10 @@
"waitingCommander": ">_ 等待統帥親核 (Tier {tier})",
"suggestedAction": "> 建議行動:",
"authorize": "授權",
"reject": "拒絕"
}
"reject": "拒絕",
"anomaly": "異常"
},
"anomaly": "異常"
},
"status": {
"idle": "待命",

View File

@@ -11,6 +11,7 @@
import { useTranslations } from 'next-intl'
import { useGlobalPulseMetrics } from '@/hooks/useGlobalPulseMetrics'
import { useIncidents } from '@/hooks/useIncidents'
import { useHosts } from '@/stores/dashboard.store'
import { IncidentCard } from '@/components/incident'
import { OpenClawPanel } from '@/components/ai/openclaw-panel'
import { HostGrid } from '@/components/infra/host-grid'
@@ -24,8 +25,10 @@ export default function Home({ params }: { params: { locale: string } }) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const t = useTranslations()
const tDashboard = useTranslations('dashboard')
const tCommon = useTranslations('common')
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const locale = params.locale
const hosts = useHosts()
// 統帥鐵律: 使用真實數據 Hook禁止假數據
const { metrics: pulseMetrics } = useGlobalPulseMetrics({
@@ -71,7 +74,7 @@ export default function Home({ params }: { params: { locale: string } }) {
flexDirection: 'column',
height: 'calc(100vh - 64px)',
background: '#f5f4ed',
fontFamily: 'Inter, system-ui, sans-serif',
fontFamily: 'var(--font-body), monospace',
overflow: 'hidden',
margin: '-24px',
}}>
@@ -105,7 +108,7 @@ export default function Home({ params }: { params: { locale: string } }) {
<span style={{ fontSize: 12, color: '#b0ad9f', letterSpacing: '2px', textTransform: 'uppercase' }}>
{m.label}
</span>
<span style={{ fontSize: 20, fontWeight: 700, color: '#141413', lineHeight: 1.1, fontFamily: 'monospace' }}>
<span style={{ fontSize: 20, fontWeight: 700, color: '#141413', lineHeight: 1.1, fontFamily: 'var(--font-body), monospace' }}>
{String(m.value)}
</span>
{m.sub && <span style={{ fontSize: 12, color: '#87867f' }}>{m.sub}</span>}
@@ -134,8 +137,8 @@ export default function Home({ params }: { params: { locale: string } }) {
flexShrink: 0,
background: '#faf9f3',
}}>
<span style={{ fontSize: 13, fontWeight: 700, color: '#141413', letterSpacing: '1px', textTransform: 'uppercase', fontFamily: 'monospace' }}>
<span style={{ fontSize: 13, fontWeight: 700, color: '#141413', letterSpacing: '1px', textTransform: 'uppercase' }}>
{tDashboard('activeIncidents')}
</span>
{(incidents?.length ?? 0) > 0 && (
<span style={{
@@ -152,14 +155,14 @@ export default function Home({ params }: { params: { locale: string } }) {
<div style={{ flex: 1, overflowY: 'auto', padding: '8px 10px' }}>
{isIncidentsLoading ? (
<div style={{ display: 'flex', justifyContent: 'center', padding: 32 }}>
<span style={{ fontSize: 13, color: '#b0ad9f' }}>...</span>
<span style={{ fontSize: 13, color: '#b0ad9f' }}>{tCommon('loading')}</span>
</div>
) : 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' }}> · 0 </span>
<span style={{ fontSize: 13, color: '#87867f' }}>{tDashboard('stable')} · 0 {tDashboard('activeIncidents')}</span>
</div>
) : (
incidents?.map((incident) => (
@@ -189,9 +192,9 @@ export default function Home({ params }: { params: { locale: string } }) {
borderBottom: '0.5px solid #e0ddd4',
fontSize: 13, fontWeight: 700, color: '#141413',
letterSpacing: '1px', textTransform: 'uppercase',
fontFamily: 'monospace', background: '#faf9f3',
fontFamily: 'var(--font-body), monospace', background: '#faf9f3',
}}>
OpenClaw
{tDashboard('openclawEngine')}
</div>
<OpenClawPanel
status={
@@ -207,11 +210,11 @@ export default function Home({ params }: { params: { locale: string } }) {
borderBottom: '0.5px solid #e0ddd4',
fontSize: 13, fontWeight: 700, color: '#141413',
letterSpacing: '1px', textTransform: 'uppercase',
fontFamily: 'monospace', background: '#faf9f3',
fontFamily: 'var(--font-body), monospace', background: '#faf9f3',
}}>
{tDashboard('infrastructure')}
</div>
<HostGrid hosts={[]} />
<HostGrid hosts={hosts} />
</div>
</div>

View File

@@ -278,13 +278,16 @@ export function IncidentCard({ incident, decision, onApprovalChange }: IncidentC
</span>
</div>
{/* 事件標題 */}
{/* 事件標題 — 從 decision action 或 affected_services 組合 */}
<div style={{ padding: '2px 10px 4px', fontSize: 14, fontWeight: 600, color: '#141413', lineHeight: 1.4 }}>
{(incident as IncidentResponse & { description?: string }).description ?? '--'}
{incident.decision?.proposal_data?.action
?? (incident.affected_services?.length
? `${incident.affected_services.join(', ')} ${t('anomaly')}`
: incident.incident_id)}
</div>
{/* INC-ID */}
<div style={{ padding: '0 10px 4px', fontSize: 12, color: '#b0ad9f', fontFamily: 'monospace' }}>
<div style={{ padding: '0 10px 4px', fontSize: 12, color: '#b0ad9f', fontFamily: 'var(--font-body), monospace' }}>
{incident.incident_id}
</div>