From 6b4cacc4847a892e739a665596a567ce00b466d8 Mon Sep 17 00:00:00 2001 From: Dotta Date: Fri, 24 Apr 2026 21:02:45 -0500 Subject: [PATCH] Move checklist numbers beside issue IDs Co-Authored-By: Paperclip --- ui/src/components/IssueColumns.tsx | 7 +++++++ ui/src/components/IssueRow.test.tsx | 25 +++++++++++++++++++++++++ ui/src/components/IssueRow.tsx | 14 ++++++-------- ui/src/components/IssuesList.test.tsx | 2 ++ ui/src/components/IssuesList.tsx | 1 + 5 files changed, 41 insertions(+), 8 deletions(-) diff --git a/ui/src/components/IssueColumns.tsx b/ui/src/components/IssueColumns.tsx index 54813689395..d0ef0d6a39f 100644 --- a/ui/src/components/IssueColumns.tsx +++ b/ui/src/components/IssueColumns.tsx @@ -139,12 +139,14 @@ export function InboxIssueMetaLeading({ showStatus = true, showIdentifier = true, statusSlot, + checklistStepNumber = null, }: { issue: Issue; isLive: boolean; showStatus?: boolean; showIdentifier?: boolean; statusSlot?: ReactNode; + checklistStepNumber?: number | string | null; }) { return ( <> @@ -153,6 +155,11 @@ export function InboxIssueMetaLeading({ {statusSlot ?? } ) : null} + {checklistStepNumber !== null ? ( + + ) : null} {showIdentifier ? ( {issue.identifier ?? issue.id.slice(0, 8)} diff --git a/ui/src/components/IssueRow.test.tsx b/ui/src/components/IssueRow.test.tsx index 60a201acddd..944712e64c9 100644 --- a/ui/src/components/IssueRow.test.tsx +++ b/ui/src/components/IssueRow.test.tsx @@ -202,6 +202,31 @@ describe("IssueRow", () => { }); }); + it("renders checklist step numbers beside the issue identifier", () => { + const root = createRoot(container); + + act(() => { + root.render( + , + ); + }); + + const link = container.querySelector("[data-inbox-issue-link]") as HTMLAnchorElement | null; + const metaRow = Array.from(link?.querySelectorAll("span.flex.items-center.gap-2") ?? []) + .find((element) => element.textContent?.includes("PAP-42")); + + expect(metaRow).not.toBeUndefined(); + expect(metaRow?.textContent?.replace(/\s+/g, "")).toContain("2.1.PAP-42"); + + act(() => { + root.unmount(); + }); + }); + it("renders without error when titleSuffix is omitted", () => { const root = createRoot(container); diff --git a/ui/src/components/IssueRow.tsx b/ui/src/components/IssueRow.tsx index 5dc015813f8..d6969d23323 100644 --- a/ui/src/components/IssueRow.tsx +++ b/ui/src/components/IssueRow.tsx @@ -64,6 +64,11 @@ export function IssueRow({ const selectedStatusClass = selected ? "!text-muted-foreground !border-muted-foreground" : undefined; const detailState = withIssueDetailHeaderSeed(issueLinkState, issue); const hasChecklistStep = checklistStepNumber !== null; + const checklistStep = hasChecklistStep ? ( + + ) : null; return ( - {hasChecklistStep ? ( - - ) : null} {mobileLeading ?? } @@ -111,6 +108,7 @@ export function IssueRow({ + {checklistStep} {identifier} diff --git a/ui/src/components/IssuesList.test.tsx b/ui/src/components/IssuesList.test.tsx index 5d5daa86c51..0d6d335896a 100644 --- a/ui/src/components/IssuesList.test.tsx +++ b/ui/src/components/IssuesList.test.tsx @@ -494,6 +494,8 @@ describe("IssuesList", () => { const rows = Array.from(container.querySelectorAll('[data-testid="issue-row"]')); expect(rows).toHaveLength(3); expect(rows.map((row) => row.getAttribute("data-step"))).toEqual(["1", "2", "3"]); + expect(container.textContent?.replace(/\s+/g, "")).toContain("1.PAP-1"); + expect(container.textContent?.replace(/\s+/g, "")).toContain("2.PAP-3"); expect(rows.filter((row) => row.getAttribute("data-current-step") === "true")).toHaveLength(1); expect(rows.find((row) => row.textContent?.includes("Active blocker"))?.getAttribute("data-current-step")).toBe("true"); expect(rows.find((row) => row.textContent?.includes("Done first"))?.getAttribute("data-title-class")).toContain("text-muted-foreground"); diff --git a/ui/src/components/IssuesList.tsx b/ui/src/components/IssuesList.tsx index dde72802620..5822ea334ad 100644 --- a/ui/src/components/IssuesList.tsx +++ b/ui/src/components/IssuesList.tsx @@ -1412,6 +1412,7 @@ export function IssuesList({ isLive={liveIssueIds?.has(issue.id) === true} showStatus={visibleIssueColumnSet.has("status") && availableIssueColumnSet.has("status")} showIdentifier={visibleIssueColumnSet.has("id") && availableIssueColumnSet.has("id")} + checklistStepNumber={checklistStepNumber} statusSlot={( { e.preventDefault(); e.stopPropagation(); }}> onUpdateIssue(issue.id, { status: s })} />