From d1996a9899c4349982e231b5a376cddf3cbaa098 Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Tue, 9 Jun 2026 11:44:43 -0700 Subject: [PATCH] FN-6110: fix Reliability view flex sizing on mobile Keep the Reliability view filling its flex parent across mobile and desktop states. - add flex growth and min-width safeguards to the Reliability view, loading, and error containers - add desktop and mobile regression coverage for loading, populated, and error rendering states Files changed: packages/dashboard/app/components/ReliabilityView.css | 6 +++ packages/dashboard/app/components/__tests__/ReliabilityView.test.tsx | 59 ++++++++++++++++++++++ 2 files changed, 65 insertions(+) Fusion-Task-Id: FN-6110 Fusion-Task-Lineage: 5fe1e5a7-f13a-4316-8c4e-b5c85a51ce86 --- .../app/components/ReliabilityView.css | 6 ++ .../__tests__/ReliabilityView.test.tsx | 59 +++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/packages/dashboard/app/components/ReliabilityView.css b/packages/dashboard/app/components/ReliabilityView.css index 5403ac7555..6d26d81d2d 100644 --- a/packages/dashboard/app/components/ReliabilityView.css +++ b/packages/dashboard/app/components/ReliabilityView.css @@ -1,9 +1,11 @@ .reliability-view { display: flex; + flex: 1 1 auto; flex-direction: column; gap: var(--space-lg); height: 100%; min-height: 0; + min-width: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; } @@ -17,20 +19,24 @@ .reliability-loading { display: flex; + flex: 1 1 auto; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-md); + min-width: 0; padding: var(--space-2xl); color: var(--text-muted); } .reliability-error { display: flex; + flex: 1 1 auto; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-md); + min-width: 0; padding: var(--space-2xl); text-align: center; } diff --git a/packages/dashboard/app/components/__tests__/ReliabilityView.test.tsx b/packages/dashboard/app/components/__tests__/ReliabilityView.test.tsx index 8d17c0dd21..9a1b981b3b 100644 --- a/packages/dashboard/app/components/__tests__/ReliabilityView.test.tsx +++ b/packages/dashboard/app/components/__tests__/ReliabilityView.test.tsx @@ -32,6 +32,27 @@ const baseResponse = { mergeAttempts: { mean: 1.2, max: 2, histogram: { "1": 1 } }, }; +function renderInProjectContent() { + return render( +
+ +
, + ); +} + +function setViewportWidth(width: number) { + Object.defineProperty(window, "innerWidth", { configurable: true, value: width }); + window.dispatchEvent(new Event("resize")); +} + +function expectFlexFill(element: HTMLElement) { + const computed = getComputedStyle(element); + expect(computed.flexGrow).toBe("1"); + expect(computed.flexShrink).toBe("1"); + expect(computed.flexBasis).toBe("auto"); + expect(computed.minWidth).toBe("0px"); +} + describe("ReliabilityView", () => { afterEach(() => { vi.useRealTimers(); @@ -58,6 +79,44 @@ describe("ReliabilityView", () => { expect(screen.queryByRole("heading", { name: "Reliability" })).not.toBeInTheDocument(); }); + it.each([ + ["desktop", 1024], + ["mobile", 375], + ])("fills flex parent width in %s loading state", (_label, width) => { + setViewportWidth(width); + vi.spyOn(globalThis, "fetch").mockReturnValue(new Promise(() => {})); + + renderInProjectContent(); + + expectFlexFill(screen.getByTestId("reliability-loading")); + }); + + it.each([ + ["desktop", 1024], + ["mobile", 375], + ])("fills flex parent width in %s populated state", async (_label, width) => { + setViewportWidth(width); + vi.spyOn(globalThis, "fetch").mockResolvedValue({ ok: true, json: async () => baseResponse } as Response); + + const { container } = renderInProjectContent(); + + await waitFor(() => expect(container.querySelector(".reliability-view")).not.toBeNull()); + expectFlexFill(container.querySelector(".reliability-view") as HTMLElement); + }); + + it.each([ + ["desktop", 1024], + ["mobile", 375], + ])("fills flex parent width in %s error state", async (_label, width) => { + setViewportWidth(width); + vi.spyOn(globalThis, "fetch").mockRejectedValue(new Error("Network unavailable")); + + renderInProjectContent(); + + await waitFor(() => expect(screen.getByTestId("reliability-error")).toBeInTheDocument()); + expectFlexFill(screen.getByTestId("reliability-error")); + }); + it("shows data after successful load even if loading refresh is pending", async () => { vi.useFakeTimers(); const fetchSpy = vi.spyOn(globalThis, "fetch")