diff --git a/.changeset/fn-7348-mobile-planning-new-session.md b/.changeset/fn-7348-mobile-planning-new-session.md new file mode 100644 index 0000000000..d6fa849a69 --- /dev/null +++ b/.changeset/fn-7348-mobile-planning-new-session.md @@ -0,0 +1,7 @@ +--- +"@runfusion/fusion": patch +--- + +summary: Keep the mobile Planning Mode New session button pinned at the bottom. +category: fix +dev: Bounds the mobile Planning sessions list so only saved sessions scroll above the footer CTA. diff --git a/packages/dashboard/app/components/PlanningModeModal.css b/packages/dashboard/app/components/PlanningModeModal.css index 9a1213a03e..7f86b2161a 100644 --- a/packages/dashboard/app/components/PlanningModeModal.css +++ b/packages/dashboard/app/components/PlanningModeModal.css @@ -497,6 +497,29 @@ The New session button must look EXACTLY like Missions' primary sidebar create b border-right: none; border-bottom: 1px solid var(--border); } + /* + FNXC:PlanningMode 2026-06-30-00:00: + Mobile list view must keep the New session CTA reachable like Missions' bottom sidebar action. Bound the sidebar to the Planning pane and let only the session list scroll above the fixed footer; detail view still hides the sidebar through the existing show-detail rule. + */ + .planning-modal-body--show-list { + flex: 1; + min-height: 0; + overflow: hidden; + } + .planning-modal-body--show-list .planning-sidebar { + flex: 1 1 auto; + height: 100%; + min-height: 0; + max-height: 100%; + } + .planning-modal-body--show-list .planning-sidebar-list { + flex: 1 1 auto; + min-height: 0; + overflow-y: auto; + } + .planning-modal-body--show-list .planning-sidebar-footer { + flex-shrink: 0; + } .planning-modal-body--show-detail .planning-sidebar { display: none; } diff --git a/packages/dashboard/app/components/__tests__/PlanningModeModal.css.test.ts b/packages/dashboard/app/components/__tests__/PlanningModeModal.css.test.ts index c78b77f632..8d8f0cd2c5 100644 --- a/packages/dashboard/app/components/__tests__/PlanningModeModal.css.test.ts +++ b/packages/dashboard/app/components/__tests__/PlanningModeModal.css.test.ts @@ -6,6 +6,7 @@ import { getMediaBlocks } from "./PlanningModeModal.test-helpers"; const PLANNING_CSS_PATH = resolve(__dirname, "..", "PlanningModeModal.css"); const TABLET_SUMMARY_ACTIONS_QUERY = "@media (min-width: 769px) and (max-width: 1024px)"; const MOBILE_ACTIONS_QUERY = "@media (max-width: 768px)"; +const MOBILE_PLANNING_SHELL_QUERY = "@media (max-width: 768px), (max-height: 480px)"; function loadPlanningCss(): string { return readFileSync(PLANNING_CSS_PATH, "utf-8"); @@ -67,4 +68,32 @@ describe("PlanningModeModal CSS responsive action contract", () => { expect(embeddedRule).toMatch(/height\s*:\s*100%\s*;/); expect(embeddedRule).toMatch(/max-height\s*:\s*100%\s*;/); }); + + it("keeps the mobile sessions list scrolling above the bottom-pinned New session footer", () => { + const css = loadPlanningCss(); + const mobileShellCss = getMediaBlocks(css, MOBILE_PLANNING_SHELL_QUERY).join("\n"); + + const showListRule = findRule(mobileShellCss, ".planning-modal-body--show-list"); + expect(showListRule).toBeTruthy(); + expect(showListRule).toMatch(/flex\s*:\s*1\s*;/); + expect(showListRule).toMatch(/min-height\s*:\s*0\s*;/); + expect(showListRule).toMatch(/overflow\s*:\s*hidden\s*;/); + + const sidebarRule = findRule(mobileShellCss, ".planning-modal-body--show-list .planning-sidebar"); + expect(sidebarRule).toBeTruthy(); + expect(sidebarRule).toMatch(/flex\s*:\s*1 1 auto\s*;/); + expect(sidebarRule).toMatch(/height\s*:\s*100%\s*;/); + expect(sidebarRule).toMatch(/min-height\s*:\s*0\s*;/); + expect(sidebarRule).toMatch(/max-height\s*:\s*100%\s*;/); + + const sidebarListRule = findRule(mobileShellCss, ".planning-modal-body--show-list .planning-sidebar-list"); + expect(sidebarListRule).toBeTruthy(); + expect(sidebarListRule).toMatch(/flex\s*:\s*1 1 auto\s*;/); + expect(sidebarListRule).toMatch(/min-height\s*:\s*0\s*;/); + expect(sidebarListRule).toMatch(/overflow-y\s*:\s*auto\s*;/); + + const footerRule = findRule(mobileShellCss, ".planning-modal-body--show-list .planning-sidebar-footer"); + expect(footerRule).toBeTruthy(); + expect(footerRule).toMatch(/flex-shrink\s*:\s*0\s*;/); + }); });