fix: reconcile Runner D UI contracts

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-08-23 21:07:06 +00:00
1 parent ebee3b3b15
commit 1016e82d90
7 files changed
+57 -32

No files matched your search

@@ -149,14 +149,12 @@ function MarkdownWorkProductRow({
metadata,
reviewDoc,
openRequestId,
onOpen,
}: {
issueId: string;
workProduct: IssueWorkProduct;
metadata: AttachmentArtifactWorkProductMetadata;
reviewDoc: IssueDocument | undefined;
openRequestId?: number;
onOpen?: () => void;
}) {
const [expanded, setExpanded] = useState(false);
const [annotationPanelOpen, setAnnotationPanelOpen] = useState(false);
@@ -195,22 +193,6 @@ function MarkdownWorkProductRow({
if (openRequestId === undefined || !expanded) return;
headerRef.current?.scrollIntoView({ behavior: "smooth", block: "center" });
}, [expanded, openRequestId]);
if (onOpen) {
return (
<button
type="button"
onClick={onOpen}
className={cn(ROW_CLASS, "w-full text-left hover:bg-accent/50")}
>
<FileText className="h-3.5 w-3.5 shrink-0 text-muted-foreground" />
<span className="min-w-0 flex-1 truncate">{documentDisplayTitle(doc)}</span>
<span className="shrink-0 text-(length:--text-micro) text-muted-foreground">
{`Rev ${doc.latestRevisionNumber ?? 1}`}
</span>
<ChevronRight className="h-3.5 w-3.5 shrink-0 text-muted-foreground" />
</button>
);
}
// Deep links land before the user clicks, so the deep-link expansion has to
// request materialization the same way a manual expand does.
useEffect(() => {
@@ -338,10 +320,12 @@ function DocumentRow({
issueId,
doc,
openRequestId,
onOpen,
}: {
issueId: string;
doc: IssueDocument;
openRequestId?: number;
onOpen?: () => void;
}) {
const [expanded, setExpanded] = useState(false);
const [annotationPanelOpen, setAnnotationPanelOpen] = useState(false);
@@ -356,6 +340,22 @@ function DocumentRow({
if (openRequestId === undefined || !expanded) return;
headerRef.current?.scrollIntoView({ behavior: "smooth", block: "center" });
}, [expanded, openRequestId]);
if (onOpen) {
return (
<button
type="button"
onClick={onOpen}
className={cn(ROW_CLASS, "w-full text-left hover:bg-accent/50")}
>
<FileText className="h-3.5 w-3.5 shrink-0 text-muted-foreground" />
<span className="min-w-0 flex-1 truncate">{documentDisplayTitle(doc)}</span>
<span className="shrink-0 text-(length:--text-micro) text-muted-foreground">
{`Rev ${doc.latestRevisionNumber ?? 1}`}
</span>
<ChevronRight className="h-3.5 w-3.5 shrink-0 text-muted-foreground" />
</button>
);
}
return (
<div className="rounded-md border border-border bg-card/50">
<div ref={headerRef} className="flex items-center hover:bg-accent/50">
@@ -31,15 +31,20 @@ const issueDocument: IssueDocument = {
const issue = { id: "issue-1", identifier: "PAP-522", workMode: "standard" } as Issue;
vi.mock("@tanstack/react-query", () => ({ useQuery: () => ({ data: [] }) }));
vi.mock("@/hooks/useIssuePlanDocument", () => ({ useIssuePlanDocument: () => ({ data: null, isLoading: false }) }));
vi.mock("@/hooks/useIssuePlanDocument", () => ({
useIssuePlanDocument: () => ({ data: { ...issueDocument, key: "plan" }, isLoading: false }),
}));
vi.mock("@/hooks/useIssueDocuments", () => ({ useIssueDocuments: () => ({ data: [issueDocument] }) }));
vi.mock("@/lib/router", () => ({ useLocation: () => ({ hash: "" }) }));
vi.mock("@/components/IssuePlanDecompositionsSection", () => ({ IssuePlanDecompositionsSection: () => null }));
vi.mock("@/components/MarkdownBody", () => ({ MarkdownBody: ({ children }: { children: string }) => <div>{children}</div> }));
vi.mock("@/components/IssueDocumentAnnotations", () => ({
DocumentAnnotationsCountChip: ({ docKey }: { docKey: string }) => <span data-testid={`annotation-count-${docKey}`} />,
IssueDocumentAnnotations: ({ doc, children }: { doc: IssueDocument; children: React.ReactNode }) => (
<div data-testid={`annotation-surface-${doc.key}`} data-document-id={doc.id}>{children}</div>
IssueDocumentAnnotations: ({ doc, children }: {
doc: Pick<IssueDocument, "key" | "latestRevisionId">;
children: React.ReactNode;
}) => (
<div data-testid={`annotation-surface-${doc.key}`} data-revision-id={doc.latestRevisionId}>{children}</div>
),
}));
@@ -59,8 +64,8 @@ describe("issue properties document annotation mounting", () => {
it("uses the issue document key on the Plan tab", async () => {
const root = createRoot(container);
await act(async () => root.render(<IssuePropertiesPlansTab issue={issue} />));
expect(container.querySelector('[data-testid="annotation-surface-qa-evidence"]')?.getAttribute("data-document-id"))
.toBe("document-1");
expect(container.querySelector('[data-testid="annotation-surface-plan"]')?.getAttribute("data-revision-id"))
.toBe("revision-1");
await act(async () => root.unmount());
});
@@ -71,8 +76,8 @@ describe("issue properties document annotation mounting", () => {
expect(container.querySelector('[data-testid="annotation-surface-qa-evidence"]')).toBeNull();
const expand = container.querySelector('button[aria-expanded="false"]') as HTMLButtonElement;
await act(async () => expand.click());
expect(container.querySelector('[data-testid="annotation-surface-qa-evidence"]')?.getAttribute("data-document-id"))
.toBe("document-1");
expect(container.querySelector('[data-testid="annotation-surface-qa-evidence"]')?.getAttribute("data-revision-id"))
.toBe("revision-1");
await act(async () => root.unmount());
});
@@ -249,7 +249,13 @@ export function TaskSidePanel({
markInteracted();
const tab = taskPanelWorkspaceFileTab(ref);
controller.openTab(tab);
viewer?.open(ref, { fromBrowse: true });
viewer?.open({
...ref,
projectId: ref.projectId ?? null,
workspaceId: ref.workspaceId ?? null,
line: ref.line ?? null,
column: ref.column ?? null,
}, { fromBrowse: true });
}
const documentByKey = useMemo(() => new Map(documents.map((document) => [document.key, document])), [documents]);