FN-6179: fix tablet nodes overlay stacking
Prevent the NodesView tablet overlay from letting underlying content bleed through. - make the tablet nodes management overlay fixed, fullscreen, and scrollable with the app background - add a regression test that asserts the tablet overlay media query and rule properties - add a patch changeset for the published CLI package bundle Files changed: .changeset/fn-6179-tablet-nodes-overlay.md | 5 +++++ packages/dashboard/app/components/NodesView.css | 12 ++++++++++- .../app/components/__tests__/NodesView.test.tsx | 23 ++++++++++++++++++++-- 3 files changed, 37 insertions(+), 3 deletions(-) Fusion-Task-Id: FN-6179 Fusion-Task-Lineage: 9455b38e-c32f-4865-917a-a06c1cb38840
This commit is contained in:
5
.changeset/fn-6179-tablet-nodes-overlay.md
Normal file
5
.changeset/fn-6179-tablet-nodes-overlay.md
Normal file
@@ -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.
|
||||||
@@ -717,6 +717,16 @@
|
|||||||
.nodes-view-section-title {
|
.nodes-view-section-title {
|
||||||
font-size: calc(var(--space-md) + var(--space-xs) / 4);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,9 +106,8 @@ function makeUseNodesResult(overrides: Partial<ReturnType<typeof useNodes>> = {}
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function extractMobileMediaBlocks(css: string): string {
|
function extractMediaBlocks(css: string, regex: RegExp): string {
|
||||||
const blocks: string[] = [];
|
const blocks: string[] = [];
|
||||||
const regex = /@media[^{]*\(max-width: 768px\)[^{]*\{/g;
|
|
||||||
let match: RegExpExecArray | null;
|
let match: RegExpExecArray | null;
|
||||||
|
|
||||||
while ((match = regex.exec(css)) !== null) {
|
while ((match = regex.exec(css)) !== null) {
|
||||||
@@ -130,6 +129,14 @@ function extractMobileMediaBlocks(css: string): string {
|
|||||||
return blocks.join("\n");
|
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 {
|
function extractRuleBlock(css: string, selector: string): string {
|
||||||
const escapedSelector = selector.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
const escapedSelector = selector.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||||
const matches = [...css.matchAll(new RegExp(`${escapedSelector}\\s*\\{([^}]*)\\}`, "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();
|
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", () => {
|
it("renders docker stat and passes docker data to matching node card", () => {
|
||||||
mockUseNodes.mockReturnValue(makeUseNodesResult({
|
mockUseNodes.mockReturnValue(makeUseNodesResult({
|
||||||
nodes: [makeNode({ id: "node-1", name: "Alpha", type: "remote", url: "https://alpha.node" })],
|
nodes: [makeNode({ id: "node-1", name: "Alpha", type: "remote", url: "https://alpha.node" })],
|
||||||
|
|||||||
Reference in New Issue
Block a user