Skip to content

Commit c24a8c9

Browse files
authored
🤖 fix: workflow result chip labels (#3630)
## Summary Render workflow final-report stat chips as **key** value instead of value key, with the key emphasized as the field label. ## Background The Workflows tab's structured-output chips were displaying the value first and the key second, which made labels like outcome, target, and issue read backwards. ## Implementation - Swap the final-report stat chip ordering to key before value. - Move the bold emphasis from the value to the key. - Add a focused UI test covering both ordering and emphasis. ## Validation - `bun test src/browser/features/RightSidebar/Workflows/WorkflowTimeline.test.tsx src/browser/features/RightSidebar/Workflows/workflowDisplay.test.ts` - `make static-check` ## Risks Low. This only changes presentation for primitive structured-output stat chips in the Workflows tab final report. --- _Generated with `mux` • Model: `openai:gpt-5.5` • Thinking: `xhigh` • Cost: `$3.49`_ <!-- mux-attribution: model=openai:gpt-5.5 thinking=xhigh costs=3.49 -->
1 parent ca7d581 commit c24a8c9

2 files changed

Lines changed: 80 additions & 1 deletion

File tree

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
2+
import { cleanup, render } from "@testing-library/react";
3+
4+
import { installDom } from "../../../../../tests/ui/dom";
5+
void mock.module("@/browser/features/Tools/WorkflowToolShared", () => ({
6+
WorkflowJsonBlock: (props: { value: unknown; ariaLabel: string }) => (
7+
<pre aria-label={props.ariaLabel}>{JSON.stringify(props.value)}</pre>
8+
),
9+
}));
10+
11+
import type { WorkflowRunView } from "./projectWorkflowRun";
12+
import { WorkflowTimeline } from "./WorkflowTimeline";
13+
14+
function normalizeText(element: Element): string {
15+
return element.textContent?.replace(/\s+/g, " ").trim() ?? "";
16+
}
17+
18+
function makeCompletedView(): WorkflowRunView {
19+
const timestamp = "2026-06-25T12:00:00.000Z";
20+
return {
21+
id: "wfr_test",
22+
workflow: {
23+
name: "test-workflow",
24+
description: "Test workflow",
25+
scope: "project",
26+
executable: true,
27+
},
28+
status: "completed",
29+
argEntries: [],
30+
createdAt: timestamp,
31+
updatedAt: timestamp,
32+
phases: [],
33+
steps: [],
34+
result: {
35+
reportMarkdown: "",
36+
structuredOutput: {
37+
outcome: "converged",
38+
verifierRuns: 1,
39+
nested: { ignored: true },
40+
},
41+
},
42+
errorMessage: null,
43+
stats: {
44+
total: 0,
45+
done: 0,
46+
running: 0,
47+
failed: 0,
48+
elapsedMs: 0,
49+
},
50+
};
51+
}
52+
53+
describe("WorkflowTimeline", () => {
54+
let cleanupDom: (() => void) | null = null;
55+
56+
beforeEach(() => {
57+
cleanupDom = installDom();
58+
});
59+
60+
afterEach(() => {
61+
cleanup();
62+
cleanupDom?.();
63+
cleanupDom = null;
64+
});
65+
66+
test("renders final report stat chips as bold key before value", () => {
67+
const { container } = render(<WorkflowTimeline view={makeCompletedView()} />);
68+
69+
const statTexts = Array.from(container.querySelectorAll("span"), normalizeText);
70+
const boldTexts = Array.from(container.querySelectorAll("b"), normalizeText);
71+
72+
expect(statTexts).toContain("outcome converged");
73+
expect(statTexts).toContain("verifierRuns 1");
74+
expect(statTexts).not.toContain("converged outcome");
75+
expect(statTexts).not.toContain("1 verifierRuns");
76+
expect(boldTexts).toEqual(["outcome", "verifierRuns"]);
77+
});
78+
});

src/browser/features/RightSidebar/Workflows/WorkflowTimeline.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,12 +313,13 @@ const WorkflowFinalReport: React.FC<{ view: WorkflowRunView }> = (props) => {
313313
)}
314314
{stats.length > 0 && (
315315
<div className="flex flex-wrap gap-2">
316+
{/* Field labels lead and stay emphasized so report chips scan as key → value. */}
316317
{stats.map((stat) => (
317318
<span
318319
key={stat.key}
319320
className="border-border bg-surface-secondary text-muted rounded-md border px-2 py-0.5 text-[11px] tabular-nums"
320321
>
321-
<b className="text-content-primary font-semibold">{stat.value}</b> {stat.key}
322+
<b className="text-content-primary font-semibold">{stat.key}</b> {stat.value}
322323
</span>
323324
))}
324325
</div>

0 commit comments

Comments
 (0)