feat(awooop): add source flow action links
This commit is contained in:
@@ -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": {
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user