feat(web): 顯示修復候選資產沉澱板
All checks were successful
CD Pipeline / tests (push) Successful in 1m55s
Code Review / ai-code-review (push) Successful in 16s
CD Pipeline / build-and-deploy (push) Successful in 5m47s
CD Pipeline / post-deploy-checks (push) Successful in 3m5s

This commit is contained in:
Your Name
2026-06-18 12:05:20 +08:00
parent a1bce80842
commit abe795461a
3 changed files with 162 additions and 2 deletions

View File

@@ -1040,6 +1040,27 @@ const REPAIR_CANDIDATE_DRAFT_REQUIRED_FIELDS = [
"rollback_command",
"verifier_plan",
"owner_review",
"script_or_ansible_ref",
"schedule_or_monitoring_rule_ref",
"km_update_plan",
"automation_asset_record",
] as const;
const REPAIR_CANDIDATE_AUTOMATION_ASSETS = [
"km",
"playbook",
"script",
"schedule",
"verifier",
] as const;
const REPAIR_CANDIDATE_WRITEBACKS = [
"incident_timeline_stage_update",
"execution_or_manual_handoff_result",
"verifier_result",
"km_update_draft",
"playbook_trust_update",
"automation_asset_inventory_record",
] as const;
const REPAIR_CANDIDATE_DRAFT_BLOCKED_OPERATIONS = [
@@ -2911,6 +2932,31 @@ function RepairCandidateDraftPanel({
</div>
))}
</div>
<div className="mt-4 border border-[#e0ddd4] bg-[#faf9f3] p-3">
<div className="flex items-center gap-2">
<Database className="h-4 w-4 text-brand-accent" aria-hidden="true" />
<h4 className="text-sm font-semibold text-[#141413]">{t("assetsTitle")}</h4>
</div>
<div className="mt-3 grid gap-2 md:grid-cols-5">
{REPAIR_CANDIDATE_AUTOMATION_ASSETS.map((asset) => (
<div key={asset} className="min-w-0 border border-[#e0ddd4] bg-white px-3 py-2">
<p className="font-mono text-[11px] font-semibold uppercase text-[#77736a]">
{t(`assets.${asset}.type` as never)}
</p>
<p className="mt-1 text-xs font-semibold text-[#141413]">
{t(`assets.${asset}.owner` as never)}
</p>
<p className="mt-1 text-[11px] leading-5 text-[#5f5b52]">
{t(`assets.${asset}.visibility` as never)}
</p>
<span className="mt-2 inline-flex border border-[#d9b36f] bg-[#fff7e8] px-2 py-0.5 font-mono text-[10px] font-semibold text-[#8a5a08]">
{t(`assets.${asset}.status` as never)}
</span>
</div>
))}
</div>
</div>
</div>
<div className="min-w-0 bg-white p-4">
@@ -2928,6 +2974,28 @@ function RepairCandidateDraftPanel({
</div>
))}
</div>
<div className="mt-4 border border-[#e0ddd4] bg-white p-3">
<div className="flex items-center gap-2">
<FileText className="h-4 w-4 text-brand-accent" aria-hidden="true" />
<h4 className="text-sm font-semibold text-[#141413]">{t("writebackTitle")}</h4>
</div>
<div className="mt-3 grid gap-2">
{REPAIR_CANDIDATE_WRITEBACKS.map((writeback) => (
<div key={writeback} className="flex min-w-0 items-start gap-2 border border-[#e0ddd4] bg-[#faf9f3] px-3 py-2">
<CheckCircle2 className="mt-0.5 h-3.5 w-3.5 shrink-0 text-[#17602a]" aria-hidden="true" />
<div className="min-w-0">
<p className="break-all font-mono text-xs font-semibold text-[#141413]">
{writeback}
</p>
<p className="mt-1 text-[11px] leading-5 text-[#5f5b52]">
{t(`writebacks.${writeback}` as never)}
</p>
</div>
</div>
))}
</div>
</div>
</div>
</div>