feat(FN-4462): complete Step 4 — mirror stall badge copy in detail modal

Fusion-Task-Id: FN-4462
Fusion-Task-Lineage: 15fc09f5-1363-429e-b131-9c9fdabee532
This commit is contained in:
Fusion
2026-05-14 22:52:39 -07:00
committed by gsxdsm
parent 16ab408919
commit 04c857918f
2 changed files with 30 additions and 3 deletions

View File

@@ -42,7 +42,7 @@ import { subscribeSse } from "../sse-bus";
import { usePluginUiSlots } from "../hooks/usePluginUiSlots"; import { usePluginUiSlots } from "../hooks/usePluginUiSlots";
import { appendTokenQuery } from "../auth"; import { appendTokenQuery } from "../auth";
import { extractDependencyDeleteConflict } from "../utils/taskDelete"; import { extractDependencyDeleteConflict } from "../utils/taskDelete";
import { computeBlockerFanoutMap } from "../hooks/useBlockerFanout"; import { MAX_AUTO_MERGE_RETRIES, computeBlockerFanoutMap } from "../hooks/useBlockerFanout";
import { resolveEffectiveGithubRepoDefault } from "./githubTracking"; import { resolveEffectiveGithubRepoDefault } from "./githubTracking";
import { linkifyFilePaths, linkifyReactChildren } from "../utils/filePathLinkify"; import { linkifyFilePaths, linkifyReactChildren } from "../utils/filePathLinkify";
import { getInReviewStallCopy, shouldShowInReviewStallBadge } from "../utils/inReviewStallCopy"; import { getInReviewStallCopy, shouldShowInReviewStallBadge } from "../utils/inReviewStallCopy";
@@ -3176,7 +3176,10 @@ export function TaskDetailContent({
{task.column === "in-review" && ( {task.column === "in-review" && (
<> <>
{shouldShowInReviewStallBadge(workingTask) && workingTask.inReviewStall && (() => { {shouldShowInReviewStallBadge(workingTask) && workingTask.inReviewStall && (() => {
const copy = getInReviewStallCopy(workingTask.inReviewStall); const copy = getInReviewStallCopy(workingTask.inReviewStall, {
mergeRetries: workingTask.mergeRetries,
maxAutoMergeRetries: MAX_AUTO_MERGE_RETRIES,
});
const logMatch = findInReviewStallLogEntry(workingTask, workingTask.inReviewStall.code); const logMatch = findInReviewStallLogEntry(workingTask, workingTask.inReviewStall.code);
return ( return (
<div <div
@@ -3185,7 +3188,7 @@ export function TaskDetailContent({
> >
<div className="detail-in-review-stall-header"> <div className="detail-in-review-stall-header">
<span className="card-status-badge card-status-badge--in-review in-review-stall"> <span className="card-status-badge card-status-badge--in-review in-review-stall">
{copy.badgeLabel} {copy.badgeLabel}{copy.counter ? ` ${copy.counter}` : ""}
</span> </span>
<span className="detail-in-review-stall-headline">{copy.headline}</span> <span className="detail-in-review-stall-headline">{copy.headline}</span>
</div> </div>

View File

@@ -123,6 +123,30 @@ describe("TaskDetailModal in-review stall diagnostics", () => {
expect(highlighted?.textContent).toContain("In-review stall surfaced [merge-blocker]"); expect(highlighted?.textContent).toContain("In-review stall surfaced [merge-blocker]");
}); });
it("renders retry-exhausted badge label with counter", () => {
render(
<TaskDetailModal
task={makeTask({
column: "in-review",
mergeRetries: 3,
inReviewStall: {
code: "merge-retries-exhausted",
reason: "Auto-merge retries exhausted",
observedAt: "2026-05-13T00:00:00.000Z",
},
})}
onClose={noop}
onMoveTask={noopMove}
onDeleteTask={noopDelete}
onMergeTask={noopMerge}
onOpenDetail={noopOpenDetail}
addToast={noop}
/>,
);
expect(screen.getByText("Retries exhausted 3/3")).toBeInTheDocument();
});
it("shows no-log copy when no matching stall entry exists", () => { it("shows no-log copy when no matching stall entry exists", () => {
render( render(
<TaskDetailModal <TaskDetailModal