From ef6e4599b182b1de55c733a54786431a2ac2ec92 Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Thu, 25 Jun 2026 00:51:50 -0700 Subject: [PATCH] FN-6985: pack embedded automations panes Keep the embedded Automations pane list and detail content top-packed instead of spreading vertically. - Add grid row and alignment rules so narrow embedded Automations content stays content-sized.\n- Cover populated embedded list/detail rendering and CSS contracts for mobile and wide layouts.\n- Add a patch changeset for the published Fusion package.\n\nFiles changed:\n .changeset/fn-6985-automations-spacing.md | 7 +++\n packages/dashboard/app/components/ScriptsModal.css | 14 +++++-\n .../__tests__/ScheduledTasksModal.test.tsx | 52 ++++++++++++++++++++++\n 3 files changed, 72 insertions(+), 1 deletion(-) Fusion-Task-Id: FN-6985 Fusion-Task-Lineage: ba2b117a-4dc5-4bc9-9ecb-7bc008cd79cd --- .changeset/fn-6985-automations-spacing.md | 7 +++ .../dashboard/app/components/ScriptsModal.css | 14 ++++- .../__tests__/ScheduledTasksModal.test.tsx | 52 +++++++++++++++++++ 3 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 .changeset/fn-6985-automations-spacing.md diff --git a/.changeset/fn-6985-automations-spacing.md b/.changeset/fn-6985-automations-spacing.md new file mode 100644 index 0000000000..b040367e20 --- /dev/null +++ b/.changeset/fn-6985-automations-spacing.md @@ -0,0 +1,7 @@ +--- +"@runfusion/fusion": patch +--- + +summary: Fix excessive spacing in the embedded Automations pane. +category: fix +dev: Top-pack embedded Automations grid rows and add regression coverage for the list/detail layout. diff --git a/packages/dashboard/app/components/ScriptsModal.css b/packages/dashboard/app/components/ScriptsModal.css index b74d8270ea..12873c1a77 100644 --- a/packages/dashboard/app/components/ScriptsModal.css +++ b/packages/dashboard/app/components/ScriptsModal.css @@ -1278,15 +1278,27 @@ With the header now edge-to-edge and dividerless, the first body row still needs padding-left: 0; } -/* Two-pane body: single column by default (narrow); two columns when the container is wide enough. */ +/* +FNXC:Automations 2026-06-24-23:30: +The embedded single-column Automations list/detail grid must not stretch implicit rows to fill the pane; stretch pushes the selected detail card far below the list row on tall/narrow surfaces. Keep rows content-sized and top-aligned so toolbar, list, and detail stay packed while the wide breakpoint only changes the column template. +*/ .automations-two-pane { display: grid; grid-template-columns: 1fr; + grid-auto-rows: max-content; + align-content: start; + align-items: start; gap: var(--space-lg); min-height: 0; flex: 1; } +@media (max-width: 768px) { + .automations-two-pane { + grid-template-columns: 1fr; + } +} + .automations-single-pane { min-height: 0; flex: 1; diff --git a/packages/dashboard/app/components/__tests__/ScheduledTasksModal.test.tsx b/packages/dashboard/app/components/__tests__/ScheduledTasksModal.test.tsx index 8d2952e741..a3248da83b 100644 --- a/packages/dashboard/app/components/__tests__/ScheduledTasksModal.test.tsx +++ b/packages/dashboard/app/components/__tests__/ScheduledTasksModal.test.tsx @@ -392,6 +392,58 @@ describe("ScheduledTasksModal", () => { expect(screen.queryByRole("button", { name: "Close" })).toBeNull(); }); + it("packs populated list and selected detail panes in the embedded list/detail structure", async () => { + mockFetchRoutines.mockResolvedValue([ + makeRoutine({ id: "routine-backup", name: "Database Backup", command: "fn backup --create" }), + makeRoutine({ id: "routine-disabled", name: "Disabled Import", command: "fn import", enabled: false }), + ]); + + const { container } = render( + , + ); + + await waitFor(() => { + expect(screen.getByRole("option", { name: /database backup/i })).toBeDefined(); + }); + + const twoPane = container.querySelector(".automations-two-pane"); + const listPane = container.querySelector(".automations-list-pane"); + const detailPane = container.querySelector(".automations-detail-pane"); + expect(twoPane).not.toBeNull(); + expect(listPane).not.toBeNull(); + expect(detailPane).not.toBeNull(); + expect(twoPane?.children[0]).toBe(listPane); + expect(twoPane?.children[1]).toBe(detailPane); + expect(screen.getByText("Select an automation")).toBeDefined(); + expect(screen.getByText("Disabled")).toBeDefined(); + + fireEvent.click(screen.getByRole("option", { name: /database backup/i })); + + await waitFor(() => { + expect(detailPane?.querySelector(".routine-card .routine-card-name")?.textContent).toBe("Database Backup"); + }); + expect(screen.getByText("fn backup --create")).toBeDefined(); + expect(container.querySelector(".automations-single-pane")).toBeNull(); + }); + + it("keeps embedded automation grid rows top-packed while preserving wide two-pane rules", () => { + const source = readFileSync(resolve(__dirname, "../ScriptsModal.css"), "utf8"); + const baseRule = source.match(/\.automations-two-pane\s*\{[^}]*\}/)?.[0] ?? ""; + const containerRule = source.match(/@container \(min-width: 900px\)\s*\{\s*\.automations-two-pane\s*\{[^}]*\}/)?.[0] ?? ""; + const mediaRule = source.match(/@media \(min-width: 900px\)\s*\{\s*\.automations-two-pane\s*\{[^}]*\}/)?.[0] ?? ""; + const mobileRule = source.match(/@media \(max-width: 768px\)\s*\{[\s\S]*?\.automations-two-pane\s*\{[^}]*\}/)?.[0] ?? ""; + + expect(baseRule).toContain("grid-template-columns: 1fr;"); + expect(baseRule).toContain("align-content: start;"); + expect(baseRule).toContain("align-items: start;"); + expect(baseRule).toContain("grid-auto-rows: max-content;"); + expect(containerRule).toContain("grid-template-columns: minmax(0, 18rem) minmax(0, 1fr);"); + expect(containerRule).toContain("align-items: start;"); + expect(mediaRule).toContain("grid-template-columns: minmax(0, 18rem) minmax(0, 1fr);"); + expect(mediaRule).toContain("align-items: start;"); + expect(mobileRule).toContain("grid-template-columns: 1fr;"); + }); + it("does not dismiss on Escape in embedded mode", async () => { render();