From a049c909e270a225300b6780f079472c47ec149d Mon Sep 17 00:00:00 2001 From: ogt Date: Fri, 10 Jul 2026 15:48:10 +0800 Subject: [PATCH] fix(iwooos): compact security cockpit --- apps/web/messages/en.json | 11 ++ apps/web/messages/zh-TW.json | 11 ++ apps/web/src/app/[locale]/iwooos/page.tsx | 225 +++++++++++++++++++--- 3 files changed, 222 insertions(+), 25 deletions(-) diff --git a/apps/web/messages/en.json b/apps/web/messages/en.json index ec263187a..76b2c4cae 100644 --- a/apps/web/messages/en.json +++ b/apps/web/messages/en.json @@ -21829,6 +21829,7 @@ "domainStatusLabel": "狀態", "p0Title": "P0 優先順序", "p0Intro": "以下是下一階段真正能降低即時風險的順序;每一項都需要脫敏證據與 owner acceptance,不能靠 UI 可見或一般批准跳過。", + "p0More": "Show remaining {count} P0 items and evidence requirements", "requiredEvidenceLabel": "需要證據", "boundaryTitle": "不可假綠燈規則", "status": { @@ -21876,6 +21877,16 @@ }, "review": { "title": "為什麼還沒有完成資安管理閉環", + "p0Queue": "Next P0 queue", + "toolRail": "External security tools", + "aiLoop": "AI automation loop", + "rootCauseDetails": "Show root causes and closure gates", + "cockpit": { + "findingCount": "Findings", + "p0Count": "P0", + "toolCount": "Tools", + "aiStageCount": "AI stages" + }, "diagnosis": { "controlPlaneRuntimeGap": "控制面已建立,runtime 防護閉環未完成", "unknown": "需要重新讀回診斷狀態" diff --git a/apps/web/messages/zh-TW.json b/apps/web/messages/zh-TW.json index cd6d47e6a..2e82ae560 100644 --- a/apps/web/messages/zh-TW.json +++ b/apps/web/messages/zh-TW.json @@ -21829,6 +21829,7 @@ "domainStatusLabel": "狀態", "p0Title": "P0 優先順序", "p0Intro": "以下是下一階段真正能降低即時風險的順序;每一項都需要脫敏證據與 owner acceptance,不能靠 UI 可見或一般批准跳過。", + "p0More": "展開其餘 {count} 個 P0 與證據要求", "requiredEvidenceLabel": "需要證據", "boundaryTitle": "不可假綠燈規則", "status": { @@ -21876,6 +21877,16 @@ }, "review": { "title": "為什麼還沒有完成資安管理閉環", + "p0Queue": "下一步 P0 queue", + "toolRail": "外部資安工具軌", + "aiLoop": "AI 自動化閉環", + "rootCauseDetails": "展開根因與 closure 條件", + "cockpit": { + "findingCount": "根因", + "p0Count": "P0", + "toolCount": "工具", + "aiStageCount": "AI 階段" + }, "diagnosis": { "controlPlaneRuntimeGap": "控制面已建立,runtime 防護閉環未完成", "unknown": "需要重新讀回診斷狀態" diff --git a/apps/web/src/app/[locale]/iwooos/page.tsx b/apps/web/src/app/[locale]/iwooos/page.tsx index dd141ba42..93668bf5c 100644 --- a/apps/web/src/app/[locale]/iwooos/page.tsx +++ b/apps/web/src/app/[locale]/iwooos/page.tsx @@ -8770,6 +8770,37 @@ function IwoooSSecurityControlCoverageBoard() { ] const domains = data?.domains ?? [] const p0Actions = data?.p0_next_actions ?? [] + const orderedP0Actions = review?.priority_work_items ?? p0Actions + const p0Preview = orderedP0Actions.slice(0, 4) + const p0Remainder = orderedP0Actions.slice(4) + const toolTracks = review?.security_tool_integration_matrix ?? [] + const aiLoopStages = review?.ai_automation_closure_loop ?? [] + const cockpitStats = review ? [ + { + key: 'findingCount', + value: String(review.root_cause_summary.length), + icon: FileWarning, + tone: 'warn' as const, + }, + { + key: 'p0Count', + value: String(review.priority_work_items.length), + icon: ListChecks, + tone: 'warn' as const, + }, + { + key: 'toolCount', + value: String(toolTracks.length), + icon: SearchCheck, + tone: 'steady' as const, + }, + { + key: 'aiStageCount', + value: String(aiLoopStages.length), + icon: Workflow, + tone: 'steady' as const, + }, + ] : [] return (
- - + + {t('review.title')}
- + {t(`review.diagnosis.${securityReviewDiagnosisKey(review.completion_diagnosis.diagnosis)}` as never)}
-
- {reviewFindings.map(finding => ( + +
+ {cockpitStats.map(item => { + const Icon = item.icon + return ( +
+
+ + {t(`review.cockpit.${item.key}` as never)} + + +
+
+ {item.value} +
+
+ ) + })} +
+ +
+
+
+ + {t('review.p0Queue')} +
+
+ {p0Preview.map(action => ( +
+ {action.priority} + {action.title} +
+ ))} +
+
+ +
+
+
+ + {t('review.toolRail')} +
+
+ {toolTracks.slice(0, 8).map(tool => ( + + {tool.tool_id} + + ))} +
+
+ +
+
+ + {t('review.aiLoop')} +
+
+ {aiLoopStages.map(stage => ( +
+ {stage.stage_id} +
+ ))} +
+
+
+
+ +
+ + {t('review.rootCauseDetails')} + +
+ {reviewFindings.map(finding => (
- {finding.severity} - {finding.title} + {finding.severity} + {finding.title}
-

+

{finding.required_closure}

- ))} -
+ ))} +
+ ) : null} @@ -8952,18 +9102,43 @@ function IwoooSSecurityControlCoverageBoard() { {t('p0Intro')}

- {p0Actions.map(action => ( -
-
- {action.priority} - {action.title} + {p0Preview.map(action => ( +
+
+ {action.priority} + {action.title} +
-

- {t('requiredEvidenceLabel')}:{action.required_evidence} -

-
- ))} + ))}
+ {p0Remainder.length > 0 ? ( +
+ + {t('p0More', { count: p0Remainder.length })} + +
+ {p0Remainder.map(action => ( +
+
+ {action.priority} + {action.title} +
+

+ {t('requiredEvidenceLabel')}:{action.required_evidence} +

+
+ ))} +
+
+ ) : null}