diff --git a/.changeset/fn-6179-tablet-nodes-overlay.md b/.changeset/fn-6179-tablet-nodes-overlay.md new file mode 100644 index 0000000000..4709b37a1c --- /dev/null +++ b/.changeset/fn-6179-tablet-nodes-overlay.md @@ -0,0 +1,5 @@ +--- +"@runfusion/fusion": patch +--- + +Fix the Nodes view tablet overlay so node cards and topology content no longer bleed through node detail modals. diff --git a/packages/dashboard/app/components/NodesView.css b/packages/dashboard/app/components/NodesView.css index 4af3cc0d18..bfd30ee997 100644 --- a/packages/dashboard/app/components/NodesView.css +++ b/packages/dashboard/app/components/NodesView.css @@ -717,6 +717,16 @@ .nodes-view-section-title { font-size: calc(var(--space-md) + var(--space-xs) / 4); } - - +} + +/* ── Nodes View Tablet Overlay ───────────────────────────────────────── */ +@media (min-width: 769px) and (max-width: 1024px) { + .nodes-management-overlay { + position: fixed; + inset: 0; + z-index: 50; + background: var(--bg); + overflow-y: auto; + -webkit-overflow-scrolling: touch; + } } diff --git a/packages/dashboard/app/components/__tests__/NodesView.test.tsx b/packages/dashboard/app/components/__tests__/NodesView.test.tsx index 98edc470fd..fc7d36030a 100644 --- a/packages/dashboard/app/components/__tests__/NodesView.test.tsx +++ b/packages/dashboard/app/components/__tests__/NodesView.test.tsx @@ -106,9 +106,8 @@ function makeUseNodesResult(overrides: Partial> = {} }; } -function extractMobileMediaBlocks(css: string): string { +function extractMediaBlocks(css: string, regex: RegExp): string { const blocks: string[] = []; - const regex = /@media[^{]*\(max-width: 768px\)[^{]*\{/g; let match: RegExpExecArray | null; while ((match = regex.exec(css)) !== null) { @@ -130,6 +129,14 @@ function extractMobileMediaBlocks(css: string): string { return blocks.join("\n"); } +function extractMobileMediaBlocks(css: string): string { + return extractMediaBlocks(css, /@media[^{]*\(max-width: 768px\)[^{]*\{/g); +} + +function extractTabletMediaBlocks(css: string): string { + return extractMediaBlocks(css, /@media[^{]*\(min-width: 769px\)[^{]*\(max-width: 1024px\)[^{]*\{/g); +} + function extractRuleBlock(css: string, selector: string): string { const escapedSelector = selector.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); const matches = [...css.matchAll(new RegExp(`${escapedSelector}\\s*\\{([^}]*)\\}`, "g"))]; @@ -202,6 +209,18 @@ describe("NodesView", () => { expect(screen.getByRole("button", { name: "Close nodes view" })).toBeInTheDocument(); }); + it("defines nodes overlay as a fixed fullscreen tablet panel", () => { + const tabletCss = extractTabletMediaBlocks(loadAllAppCss()); + const overlayRule = extractRuleBlock(tabletCss, ".nodes-management-overlay"); + + expect(overlayRule).toContain("position: fixed;"); + expect(overlayRule).toContain("inset: 0;"); + expect(overlayRule).toContain("z-index: 50;"); + expect(overlayRule).toContain("background: var(--bg);"); + expect(overlayRule).toContain("overflow-y: auto;"); + expect(overlayRule).toContain("-webkit-overflow-scrolling: touch;"); + }); + it("renders docker stat and passes docker data to matching node card", () => { mockUseNodes.mockReturnValue(makeUseNodesResult({ nodes: [makeNode({ id: "node-1", name: "Alpha", type: "remote", url: "https://alpha.node" })],