diff --git a/.changeset/fn-8427-planning-mobile-session-list-nav.md b/.changeset/fn-8427-planning-mobile-session-list-nav.md new file mode 100644 index 0000000000..ef8ae951b6 --- /dev/null +++ b/.changeset/fn-8427-planning-mobile-session-list-nav.md @@ -0,0 +1,7 @@ +--- +"@runfusion/fusion": patch +--- + +summary: Restore mobile navigation back to the Planning session list without a stuck Running plan screen. +category: fix +dev: Hide RunningPlanPane in list mode; ensure Back/Sessions on non-list mobile Planning surfaces. diff --git a/MOBILE.md b/MOBILE.md index 09c7db75c6..ffbd16f1dc 100644 --- a/MOBILE.md +++ b/MOBILE.md @@ -101,7 +101,7 @@ gesture delivery enabled across `cap sync` regenerations. ### Planning Mode -Planning Mode opens directly into the composer pane on mobile when no planning sessions exist, avoiding an empty-sidebar dead end. Desktop keeps its three-pane interview (answered history, current question, and running plan) when there is room. Mobile, phone-class short landscape, and tablet use a progressive interview: **Question** is the default full-width surface, while labeled **Running plan** and **Answered questions** controls switch to those surfaces without stacking three panes. **Sessions** and the mobile back control always return to the saved-session list; **Validate plan** remains on the Running plan surface. Once sessions are saved, mobile shows the session list as usual and the user can navigate between list and detail panes. +Planning Mode opens directly into the composer pane on mobile when no planning sessions exist, avoiding an empty-sidebar dead end. Desktop keeps its three-pane interview (answered history, current question, and running plan) when there is room. Mobile, phone-class short landscape, and tablet use a progressive interview: **Question** is the default full-width surface, while labeled **Running plan** and **Answered questions** controls switch to those surfaces without stacking three panes. **Sessions** and the mobile back control always return to the saved-session list; this is a full-pane, scrollable list with **New session** as its footer and no Running plan stacked beneath it. The same escape is available from interview, summary, breakdown, and a new-session composer when saved sessions exist; **Validate plan** remains on the Running plan surface. ### Chat and Quick Chat mobile scroll/readability behavior diff --git a/docs/dashboard-guide.md b/docs/dashboard-guide.md index 1b5a9eacac..ff44b17954 100644 --- a/docs/dashboard-guide.md +++ b/docs/dashboard-guide.md @@ -529,7 +529,7 @@ When an active Planning AI generation appears stuck, Planning Mode automatically Use **New session** to restart planning with a different idea. -Planning Mode keeps the running plan visible beside answered-question history and the current question on desktop; you can rename a session and keep asking high-impact, context-aware questions until you choose **Validate plan**. On tablet, mobile, and phone-class short landscape, the interview switches between labeled **Question**, **Running plan**, and **Answered questions** surfaces so the current question stays usable instead of competing with three columns. **Sessions** (and mobile Back) return to the saved-session list, while **Validate plan** remains available on the Running plan surface. The running title, description, and deliverables are available throughout the interview—including while the next question is generating or a recoverable error is shown. The AI never ends an interview on its own. Selection questions provide alternatives with pros and cons plus an **Other** free-text choice, whose wording follows your input language and whose answer steers the next question. You may edit an earlier answer by question ID without losing later answers; Planning re-derives the running plan and appends a fresh next question. +Planning Mode keeps the running plan visible beside answered-question history and the current question on desktop; you can rename a session and keep asking high-impact, context-aware questions until you choose **Validate plan**. On tablet, mobile, and phone-class short landscape, the interview switches between labeled **Question**, **Running plan**, and **Answered questions** surfaces so the current question stays usable instead of competing with three columns. **Sessions** (and mobile Back) return to a full-pane, scrollable saved-session list with **New session** pinned as its footer; the Running plan is not stacked under that list. This escape remains available from interview, summary, breakdown, and a new-session composer whenever saved sessions exist, while **Validate plan** remains available on the Running plan surface. The running title, description, and deliverables are available throughout the interview—including while the next question is generating or a recoverable error is shown. The AI never ends an interview on its own. Selection questions provide alternatives with pros and cons plus an **Other** free-text choice, whose wording follows your input language and whose answer steers the next question. You may edit an earlier answer by question ID without losing later answers; Planning re-derives the running plan and appends a fresh next question. Choose **Validate plan** when the running plan is ready for task creation. Validation is durable and is required before **Create task**, **Create tasks**, or **Start breakdown**; those actions reject unvalidated sessions. diff --git a/packages/dashboard/app/components/PlanningModeModal.css b/packages/dashboard/app/components/PlanningModeModal.css index c92198d6ce..f4451ea142 100644 --- a/packages/dashboard/app/components/PlanningModeModal.css +++ b/packages/dashboard/app/components/PlanningModeModal.css @@ -469,6 +469,7 @@ The New session button must look EXACTLY like Missions' primary sidebar create b cursor: pointer; padding: var(--space-xs); border-radius: var(--radius-sm); + flex-shrink: 0; transition: background var(--transition-fast), box-shadow var(--transition-fast); } @@ -620,13 +621,24 @@ The New session button must look EXACTLY like Missions' primary sidebar create b .planning-modal-body--show-detail .planning-sidebar { display: none; } - .planning-modal-body--show-list .planning-detail { + /* + FNXC:PlanningModeMobile 2026-07-20-10:30: + FN-8427 gives session-list mode exclusive ownership of the compact body. JS unmounts + RunningPlanPane; this selector is a layout backstop for future render paths so session + rows stay scrollable above the New session footer instead of sharing height with a plan. + */ + .planning-modal-body--show-list .planning-detail, + .planning-modal-body--show-list .planning-running-plan, + .planning-modal-body--show-list .planning-compact-pane-switcher { display: none; } - /* Show back button on mobile whenever it's rendered (the React component - only renders it when `mobileShowDetail` is true). */ + /* The rendered Back control needs a full touch target and must not be squeezed out of the title row. */ .planning-mobile-back { display: inline-flex; + min-width: calc(var(--space-md) * 2.25); + min-height: calc(var(--space-md) * 2.25); + align-items: center; + justify-content: center; } /* Always keep action buttons visible on mobile (no hover) */ .planning-sidebar-item-delete, @@ -1535,6 +1547,44 @@ Tablet embedded Planning keeps the desktop two-pane shell, so the summary footer display: none; } + /* FNXC:PlanningModeMobile 2026-07-20-10:30: tablet uses the same compact list destination as phone and short shells, so summary/compose detail cannot remain beside saved session rows. */ + .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-list .planning-detail, + .planning-modal-body--show-list .planning-running-plan, + .planning-modal-body--show-list .planning-compact-pane-switcher { + display: none; + } + + .planning-mobile-back { + display: inline-flex; + min-width: calc(var(--space-md) * 2.25); + min-height: calc(var(--space-md) * 2.25); + align-items: center; + justify-content: center; + } + .planning-summary-actions { flex-wrap: wrap; align-items: flex-start; diff --git a/packages/dashboard/app/components/PlanningModeModal.tsx b/packages/dashboard/app/components/PlanningModeModal.tsx index cf3d1769b9..38de00e88e 100644 --- a/packages/dashboard/app/components/PlanningModeModal.tsx +++ b/packages/dashboard/app/components/PlanningModeModal.tsx @@ -521,6 +521,16 @@ export function PlanningModeModal({ isOpen, onClose, onTaskCreated, onTasksCreat temporary while a keyboard is open, rather than a global viewport-mode change. */ const isCompactInterview = viewportMode !== "desktop" || isShortViewport(); + /* + FNXC:PlanningModeMobile 2026-07-20-10:30: + FN-8427 makes the saved-session list a real compact destination. Both Back and Sessions + enter this one mode, which must unmount the active interview plan so it cannot consume + flex height beneath session rows. Desktop preserves its three-pane interview until its + explicit Sessions toggle requests the same list destination. + */ + const isSessionListMode = showSessionList || (isCompactInterview && !mobileShowDetail); + // FNXC:PlanningModeMobile 2026-07-20-10:30: Empty mobile state opens the composer because no saved destination exists; once sessions exist, every compact detail surface gets this single Back-to-list escape. + const canReturnToSessionList = isCompactInterview && mobileShowDetail && planningSessions.length > 0; const [compactInterviewPane, setCompactInterviewPane] = useState<"question" | "plan" | "history">("question"); const { addToast } = useToast(); const { pushNav } = useNavigationHistoryContext(); @@ -1192,6 +1202,7 @@ export function PlanningModeModal({ isOpen, onClose, onTaskCreated, onTasksCreat liveGenerationSessionIdRef.current = sessionId; setSelectedSessionId(sessionId); setShowSessionList(false); + setMobileShowDetail(true); connectToPlanningStream(sessionId); setResponseHistory([]); @@ -2215,7 +2226,7 @@ export function PlanningModeModal({ isOpen, onClose, onTaskCreated, onTasksCreat */}