feat(awooop): add source flow action links
All checks were successful
Code Review / ai-code-review (push) Successful in 11s
CD Pipeline / tests (push) Successful in 3m59s
CD Pipeline / build-and-deploy (push) Successful in 4m42s
CD Pipeline / post-deploy-checks (push) Successful in 2m36s

This commit is contained in:
Your Name
2026-05-21 15:08:09 +08:00
parent 0fc66370c7
commit d94f427a09
3 changed files with 99 additions and 0 deletions

View File

@@ -1731,6 +1731,16 @@
"workDetail": "Whether recurrence groups still have open work",
"decision": "Source Match Decision",
"decisionDetail": "Whether source review / apply has a decision record"
},
"actions": {
"workItems": "Handle Work Items",
"workItemsDetail": "{count} open groups need handling or confirmation",
"runs": "Inspect Run Linkage",
"runsDetail": "Unlinked events: {unlinked}",
"approvals": "Check Human Gates",
"approvalsDetail": "{count} manual gates need human judgment",
"sourceReviews": "Review Source Matches",
"sourceReviewsDetail": "{count} source reviews need a decision"
}
},
"quality": {

View File

@@ -1732,6 +1732,16 @@
"workDetail": "recurrence group 是否仍有待處理項",
"decision": "來源配對決策",
"decisionDetail": "source review / apply 是否已有決策紀錄"
},
"actions": {
"workItems": "處理工作項",
"workItemsDetail": "{count} 個 open group 需要處理或確認",
"runs": "查看 Run 連結",
"runsDetail": "未連結事件:{unlinked}",
"approvals": "檢查人工閘門",
"approvalsDetail": "{count} 個 manual gate 需要人工判斷",
"sourceReviews": "審核來源配對",
"sourceReviewsDetail": "{count} 個 source review 待決策"
}
},
"quality": {

View File

@@ -367,6 +367,50 @@ function ProgressRow({
);
}
function SourceFlowActionLink({
href,
label,
value,
detail,
icon: Icon,
tone,
}: {
href: string;
label: string;
value: string | number;
detail: string;
icon: typeof ArrowRight;
tone: "good" | "warn" | "neutral";
}) {
return (
<Link
href={href as never}
className="group flex min-h-[92px] items-start justify-between gap-3 border border-[#e0ddd4] bg-white px-4 py-3 hover:border-[#d97757] hover:bg-[#faf9f3]"
>
<div className="min-w-0">
<p className="text-xs font-semibold text-[#77736a]">{label}</p>
<p className="mt-2 font-mono text-2xl font-semibold leading-none text-[#141413]">
{value}
</p>
<p className="mt-2 text-xs leading-5 text-[#5f5b52]">{detail}</p>
</div>
<span
className={cn(
"flex h-8 w-8 shrink-0 items-center justify-center border",
tone === "good" && "border-[#9bc7a4] bg-[#f0faf2] text-[#17602a]",
tone === "warn" && "border-[#d9b36f] bg-[#fff7e8] text-[#8a5a08]",
tone === "neutral" && "border-[#d8d3c7] bg-[#faf9f3] text-[#5f5b52]"
)}
>
<Icon
className="h-4 w-4 transition-transform group-hover:translate-x-0.5"
aria-hidden="true"
/>
</span>
</Link>
);
}
function SourceFlowOverviewPanel({
summary,
error,
@@ -484,6 +528,41 @@ function SourceFlowOverviewPanel({
tone={sourceReview === 0 ? "good" : "neutral"}
/>
</div>
<div className="grid gap-3 md:grid-cols-2 xl:grid-cols-4">
<SourceFlowActionLink
href="/awooop/work-items?project_id=awoooi"
label={t("actions.workItems")}
value={openWork}
detail={t("actions.workItemsDetail", { count: openWork })}
icon={ArrowRight}
tone={openWork === 0 ? "good" : "warn"}
/>
<SourceFlowActionLink
href="/awooop/runs?project_id=awoooi"
label={t("actions.runs")}
value={`${linkedRuns}/${sourceTotal}`}
detail={t("actions.runsDetail", { unlinked: unlinkedEvents })}
icon={Activity}
tone={unlinkedEvents === 0 ? "good" : "warn"}
/>
<SourceFlowActionLink
href="/awooop/approvals"
label={t("actions.approvals")}
value={manualGates}
detail={t("actions.approvalsDetail", { count: manualGates })}
icon={ShieldCheck}
tone={manualGates === 0 ? "good" : "warn"}
/>
<SourceFlowActionLink
href="/awooop/work-items?project_id=awoooi"
label={t("actions.sourceReviews")}
value={sourceReview}
detail={t("actions.sourceReviewsDetail", { count: sourceReview })}
icon={SearchCheck}
tone={sourceReview === 0 ? "good" : "neutral"}
/>
</div>
</div>
)}
</section>