Skip to content

Commit 15bd4da

Browse files
committed
feat(v7-h38): RunResultModal severity colours (warning amber, info blue)
Closes item #50 of the UI<->API wiring list: GotchasTab already differentiated severities but RunResultModal rendered every stage in a single status colour, so an 'ok' stage with verify warnings looked identical to a clean one. - Add SEVERITY_COLORS palette (error/warning/info). - statusCellColor helper: ok+warnings>0 → amber. - Status cell carries data-severity attr (testable) + a ⚠N badge for visible signal. bd: cppmega-mlx-eerc 3/3 new vitest + 18/18 RunResultModal regression.
1 parent c3b95e9 commit 15bd4da

2 files changed

Lines changed: 76 additions & 2 deletions

File tree

vbgui/src/components/RunResultModal.tsx

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,22 @@ const COLORS = {
4444
ok: "#10b981", fail: "#dc2626", skipped: "#9ca3af", cancelled: "#f59e0b",
4545
} as const;
4646

47+
// V7-H38: severity-coloured palette used when a stage has warnings>0
48+
// and when rendering verify-style diagnostic lines (error/warn/info).
49+
const SEVERITY_COLORS = {
50+
error: "#dc2626", warning: "#d97706", info: "#2563eb",
51+
} as const;
52+
53+
/** V7-H38: status-cell colour reflects warnings — an "ok" stage with
54+
* warnings rendered in amber so the user notices verify-found issues
55+
* even though the stage technically succeeded. */
56+
function statusCellColor(
57+
status: keyof typeof COLORS, warnings: number,
58+
): string {
59+
if (status === "ok" && warnings > 0) return SEVERITY_COLORS.warning;
60+
return COLORS[status];
61+
}
62+
4763
// V3-4: keys excluded from the visible extras dl because they're
4864
// redundant with the row's status / error rendering.
4965
const EXTRAS_RESERVED = new Set<string>([
@@ -230,14 +246,35 @@ export function RunResultModal({
230246
outlineOffset: isFirstFailed ? -2 : undefined,
231247
}}>
232248
<td style={td}>
233-
<span style={{ color: COLORS[s.status],
249+
<span data-testid={`run-result-status-icon-${s.name}`}
250+
style={{ color:
251+
statusCellColor(s.status,
252+
s.warnings ?? 0),
234253
fontWeight: 700 }}>
235254
{ICONS[s.status]}
236255
</span>
237256
</td>
238257
<td style={td}>{s.name}</td>
239-
<td style={{ ...td, color: COLORS[s.status] }}>
258+
<td data-testid={`run-result-status-${s.name}`}
259+
data-severity={
260+
s.status === "ok" && (s.warnings ?? 0) > 0
261+
? "warning" : s.status}
262+
style={{ ...td,
263+
color: statusCellColor(
264+
s.status, s.warnings ?? 0) }}>
240265
{s.status}
266+
{s.status === "ok" && (s.warnings ?? 0) > 0 && (
267+
<span data-testid={
268+
`run-result-warnings-${s.name}`}
269+
style={{ marginLeft: 4, fontSize: 10,
270+
padding: "1px 4px",
271+
background:
272+
SEVERITY_COLORS.warning,
273+
color: "white",
274+
borderRadius: 3 }}>
275+
{s.warnings}
276+
</span>
277+
)}
241278
</td>
242279
<td style={{ ...td, textAlign: "right" }}>
243280
{s.elapsed_ms.toFixed(1)}

vbgui/tests/RunResultModal.test.tsx

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,20 @@ const REPORT_FAIL: RunReport = {
2424
],
2525
};
2626

27+
// V7-H38: stage with status=ok but warnings>0 — must render in amber
28+
// (severity=warning) with a ⚠N badge so the user notices even though
29+
// the stage technically succeeded.
30+
const REPORT_WARN: RunReport = {
31+
overall_status: "ok",
32+
total_elapsed_ms: 5.5,
33+
stages: [
34+
{ name: "parse", status: "ok", elapsed_ms: 0.4 },
35+
{ name: "verify_build_spec", status: "ok", elapsed_ms: 1.0,
36+
warnings: 3 },
37+
{ name: "build_model", status: "ok", elapsed_ms: 4.0 },
38+
],
39+
};
40+
2741
const REPORT_CANCELLED: RunReport = {
2842
overall_status: "cancelled",
2943
total_elapsed_ms: 20.0,
@@ -33,6 +47,29 @@ const REPORT_CANCELLED: RunReport = {
3347
],
3448
};
3549

50+
describe("V7-H38 RunResultModal severity colours", () => {
51+
it("status cell carries data-severity='warning' when stage has warnings>0",
52+
() => {
53+
render(<RunResultModal report={REPORT_WARN} onClose={() => {}} />);
54+
const cell = screen.getByTestId(
55+
"run-result-status-verify_build_spec");
56+
expect(cell.getAttribute("data-severity")).toBe("warning");
57+
expect(screen.getByTestId(
58+
"run-result-warnings-verify_build_spec").textContent).toBe("⚠3");
59+
});
60+
it("status cell carries data-severity='ok' for clean stages", () => {
61+
render(<RunResultModal report={REPORT_WARN} onClose={() => {}} />);
62+
expect(screen.getByTestId(
63+
"run-result-status-parse").getAttribute("data-severity")).toBe("ok");
64+
});
65+
it("status cell carries data-severity='fail' for failed stages", () => {
66+
render(<RunResultModal report={REPORT_FAIL} onClose={() => {}} />);
67+
expect(screen.getByTestId(
68+
"run-result-status-dry_forward").getAttribute("data-severity"))
69+
.toBe("fail");
70+
});
71+
});
72+
3673
describe("RunResultModal", () => {
3774
it("returns null when there's nothing to show", () => {
3875
const { container } = render(

0 commit comments

Comments
 (0)