diff --git a/ui/src/pages/IssueDetail.test.tsx b/ui/src/pages/IssueDetail.test.tsx
index 3b52e52addd..7fbd28e217e 100644
--- a/ui/src/pages/IssueDetail.test.tsx
+++ b/ui/src/pages/IssueDetail.test.tsx
@@ -524,9 +524,9 @@ function createPausePreview(): IssueTreeControlPreview {
generatedAt: new Date("2026-04-21T00:00:00.000Z"),
releasePolicy: { strategy: "manual" },
totals: {
- totalIssues: 2,
+ totalIssues: 3,
affectedIssues: 2,
- skippedIssues: 0,
+ skippedIssues: 1,
activeRuns: 1,
queuedRuns: 0,
affectedAgents: 0,
@@ -563,8 +563,39 @@ function createPausePreview(): IssueTreeControlPreview {
skipped: false,
skipReason: null,
},
+ {
+ id: "child-2",
+ identifier: "PAP-3",
+ title: "Completed child",
+ status: "done",
+ parentId: "issue-1",
+ depth: 1,
+ assigneeAgentId: null,
+ assigneeUserId: null,
+ activeRun: null,
+ activeHoldIds: [],
+ action: "pause",
+ skipped: true,
+ skipReason: "terminal_status",
+ },
+ ],
+ skippedIssues: [
+ {
+ id: "child-2",
+ identifier: "PAP-3",
+ title: "Completed child",
+ status: "done",
+ parentId: "issue-1",
+ depth: 1,
+ assigneeAgentId: null,
+ assigneeUserId: null,
+ activeRun: null,
+ activeHoldIds: [],
+ action: "pause",
+ skipped: true,
+ skipReason: "terminal_status",
+ },
],
- skippedIssues: [],
activeRuns: [],
affectedAgents: [],
warnings: [],
@@ -953,6 +984,8 @@ describe("IssueDetail", () => {
expect(container.textContent).not.toContain("Status breakdown");
expect(container.textContent).not.toContain("Active runs cancelled");
expect(container.textContent).toContain("Paused child");
+ expect(container.textContent).toContain("Completed child");
+ expect(container.textContent).toContain("Complete");
const pauseApplyButton = Array.from(container.querySelectorAll("button"))
.find((button) => button.textContent?.trim() === "Pause and stop work");
diff --git a/ui/src/pages/IssueDetail.tsx b/ui/src/pages/IssueDetail.tsx
index f37b06a6618..a6e1830034c 100644
--- a/ui/src/pages/IssueDetail.tsx
+++ b/ui/src/pages/IssueDetail.tsx
@@ -2564,6 +2564,16 @@ export function IssueDetail() {
() => (treeControlPreview?.issues ?? []).filter((candidate) => !candidate.skipped),
[treeControlPreview],
);
+ const treePreviewDisplayIssues = useMemo(
+ () => {
+ const previewIssues = treeControlPreview?.issues ?? [];
+ if (treeControlMode !== "pause") {
+ return previewIssues.filter((candidate) => !candidate.skipped);
+ }
+ return previewIssues.filter((candidate) => !candidate.skipped || candidate.skipReason === "terminal_status");
+ },
+ [treeControlMode, treeControlPreview],
+ );
const activePauseHold = treeControlState?.activePauseHold ?? null;
const activeRootPauseHoldsForDisplay = useMemo(
() => activePauseHold?.isRoot === true ? activeRootPauseHolds : [],
@@ -2656,7 +2666,7 @@ export function IssueDetail() {
: treeControlMode === "restore"
? `Restore ${previewAffectedIssueCount} issues`
: "Resume subtree";
- const treePreviewAffectedIssueRows = treePreviewAffectedIssues.map((candidate) => ({
+ const treePreviewAffectedIssueRows = treePreviewDisplayIssues.map((candidate) => ({
candidate,
issue: {
...issue,
@@ -3527,13 +3537,19 @@ export function IssueDetail() {
{candidate.identifier ?? candidate.id.slice(0, 8)}
{candidate.title}
+ {candidate.skipped && candidate.skipReason === "terminal_status" ? (
+ Complete
+ ) : null}
))}