feat(FN-4462): complete Step 2 — render retry-exhausted badge text
Fusion-Task-Id: FN-4462 Fusion-Task-Lineage: 15fc09f5-1363-429e-b131-9c9fdabee532
This commit is contained in:
@@ -27,7 +27,7 @@ import { getEndToEndDurationMs, getTimedDurationMs, getWorkflowRuntimeMs, parseT
|
||||
import type { ToastType } from "../hooks/useToast";
|
||||
import { useConfirm } from "../hooks/useConfirm";
|
||||
import { extractDependencyDeleteConflict } from "../utils/taskDelete";
|
||||
import type { BlockerFanoutEntry } from "../hooks/useBlockerFanout";
|
||||
import { MAX_AUTO_MERGE_RETRIES, type BlockerFanoutEntry } from "../hooks/useBlockerFanout";
|
||||
import { useRetryWarning } from "../context/RetryWarningContext";
|
||||
|
||||
// ── Mission title caching ───────────────────────────────────────────────────
|
||||
@@ -768,7 +768,12 @@ function TaskCardComponent({
|
||||
const stalledReview = getStalledReviewSignal(task);
|
||||
const showStalledReview = Boolean(stalledReview && task.column === "in-review" && !isPaused);
|
||||
const hasInReviewStall = shouldShowInReviewStallBadge(task);
|
||||
const stallCopy = task.inReviewStall ? getInReviewStallCopy(task.inReviewStall) : undefined;
|
||||
const stallCopy = task.inReviewStall
|
||||
? getInReviewStallCopy(task.inReviewStall, {
|
||||
mergeRetries: task.mergeRetries,
|
||||
maxAutoMergeRetries: MAX_AUTO_MERGE_RETRIES,
|
||||
})
|
||||
: undefined;
|
||||
const hasStalePausedReview = shouldShowStalePausedReviewBadge(task);
|
||||
const stalePausedReviewCopy = task.stalePausedReview ? getStalePausedReviewCopy(task.stalePausedReview) : undefined;
|
||||
const hasTaskAgeStaleness = shouldShowTaskAgeStalenessBadge(task);
|
||||
@@ -1477,7 +1482,7 @@ function TaskCardComponent({
|
||||
title={`${stallCopy.headline} — ${stallCopy.description}`}
|
||||
data-stall-code={stallCopy.code}
|
||||
>
|
||||
{stallCopy.badgeLabel}
|
||||
{stallCopy.badgeLabel}{stallCopy.counter ? ` ${stallCopy.counter}` : ""}
|
||||
</span>
|
||||
)}
|
||||
{hasStalePausedReview && stalePausedReviewCopy && (
|
||||
|
||||
@@ -456,12 +456,13 @@ describe("TaskCard", () => {
|
||||
expect(screen.queryByText(/Re-enqueued for merge/)).toBeNull();
|
||||
});
|
||||
|
||||
it("renders in-review stall badge with code and tooltip", () => {
|
||||
it("renders retry-exhausted in-review stall badge with counter, code, and tooltip", () => {
|
||||
render(
|
||||
<TaskCard
|
||||
task={makeTask({
|
||||
column: "in-review",
|
||||
status: "merging",
|
||||
mergeRetries: 3,
|
||||
inReviewStall: {
|
||||
code: "merge-retries-exhausted",
|
||||
reason: "Auto-merge retries exhausted",
|
||||
@@ -473,11 +474,33 @@ describe("TaskCard", () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
const badge = screen.getByText("Stall");
|
||||
const badge = screen.getByText("Retries exhausted 3/3");
|
||||
expect(badge.getAttribute("data-stall-code")).toBe("merge-retries-exhausted");
|
||||
expect(badge.getAttribute("title")).toContain("Auto-merge retries exhausted");
|
||||
});
|
||||
|
||||
it("renders merge-blocker in-review stall badge without retry counter", () => {
|
||||
render(
|
||||
<TaskCard
|
||||
task={makeTask({
|
||||
column: "in-review",
|
||||
status: "merging",
|
||||
mergeRetries: 3,
|
||||
inReviewStall: {
|
||||
code: "merge-blocker",
|
||||
reason: "Merge blocked by pre-merge check",
|
||||
observedAt: "2026-05-13T00:00:00.000Z",
|
||||
},
|
||||
})}
|
||||
onOpenDetail={noop}
|
||||
addToast={noop}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.getByText("Merge blocked")).toBeDefined();
|
||||
expect(screen.queryByText(/\/3/)).toBeNull();
|
||||
});
|
||||
|
||||
it.each([
|
||||
{
|
||||
label: "paused in-review task",
|
||||
@@ -510,7 +533,7 @@ describe("TaskCard", () => {
|
||||
},
|
||||
])("hides in-review stall badge for $label", ({ task }) => {
|
||||
render(<TaskCard task={task} onOpenDetail={noop} addToast={noop} />);
|
||||
expect(screen.queryByText("Stall")).toBeNull();
|
||||
expect(screen.queryByText("Retries exhausted")).toBeNull();
|
||||
});
|
||||
|
||||
it("renders stale paused review badge for paused in-review signal", () => {
|
||||
|
||||
Reference in New Issue
Block a user