Always show a panel (#1988)
## Summary
**Fixed:** Invalid layout state where only left and right sidebars are visible (no main content area).
### Changes Made:
**1. `frontend/src/stores/useLayoutStore.ts`**
- Added `setMainPanelVisible` setter function to the type and implementation
- Added `useIsRightMainPanelVisible` derived selector hook that checks if Changes/Logs/Preview panel is visible
**2. `frontend/src/components/ui-new/containers/WorkspacesLayout.tsx`**
- Imported `useIsRightMainPanelVisible` from the layout store
- Added `setMainPanelVisible` to the destructured store values
- Replaced verbose `isChangesMode || isLogsMode || isPreviewMode` checks with the helper
- Added guard effect that ensures the left main panel (chat) is visible when the right main panel is hidden - this prevents the invalid state after page reload
The guard effect automatically opens the main panel whenever the layout would otherwise show only sidebars:
```typescript
// Ensure left main panel (chat) is visible when right main panel is hidden
// This prevents invalid state where only sidebars are visible after page reload
useEffect(() => {
if (!isMainPanelVisible && !isRightMainPanelVisible) {
setMainPanelVisible(true);
}
}, [isMainPanelVisible, isRightMainPanelVisible, setMainPanelVisible]);
```
This commit is contained in:
committed by
GitHub
parent
aad1bd092b
commit
d9fa2d1fa5
@@ -40,7 +40,10 @@ import {
|
|||||||
useExpandedAll,
|
useExpandedAll,
|
||||||
PERSIST_KEYS,
|
PERSIST_KEYS,
|
||||||
} from '@/stores/useUiPreferencesStore';
|
} from '@/stores/useUiPreferencesStore';
|
||||||
import { useLayoutStore } from '@/stores/useLayoutStore';
|
import {
|
||||||
|
useLayoutStore,
|
||||||
|
useIsRightMainPanelVisible,
|
||||||
|
} from '@/stores/useLayoutStore';
|
||||||
import { useDiffViewStore } from '@/stores/useDiffViewStore';
|
import { useDiffViewStore } from '@/stores/useDiffViewStore';
|
||||||
import { CommandBarDialog } from '@/components/ui-new/dialogs/CommandBarDialog';
|
import { CommandBarDialog } from '@/components/ui-new/dialogs/CommandBarDialog';
|
||||||
import { useCommandBarShortcut } from '@/hooks/useCommandBarShortcut';
|
import { useCommandBarShortcut } from '@/hooks/useCommandBarShortcut';
|
||||||
@@ -281,8 +284,12 @@ export function WorkspacesLayout() {
|
|||||||
setLogsMode,
|
setLogsMode,
|
||||||
resetForCreateMode,
|
resetForCreateMode,
|
||||||
setSidebarVisible,
|
setSidebarVisible,
|
||||||
|
setMainPanelVisible,
|
||||||
} = useLayoutStore();
|
} = useLayoutStore();
|
||||||
|
|
||||||
|
// Derived state: right main panel (Changes/Logs/Preview) is visible
|
||||||
|
const isRightMainPanelVisible = useIsRightMainPanelVisible();
|
||||||
|
|
||||||
// Read persisted draft for sidebar placeholder (works outside of CreateModeProvider)
|
// Read persisted draft for sidebar placeholder (works outside of CreateModeProvider)
|
||||||
const { scratch: draftScratch } = useScratch(
|
const { scratch: draftScratch } = useScratch(
|
||||||
ScratchType.DRAFT_WORKSPACE,
|
ScratchType.DRAFT_WORKSPACE,
|
||||||
@@ -435,16 +442,13 @@ export function WorkspacesLayout() {
|
|||||||
// Ref to Allotment for programmatic control
|
// Ref to Allotment for programmatic control
|
||||||
const allotmentRef = useRef<AllotmentHandle>(null);
|
const allotmentRef = useRef<AllotmentHandle>(null);
|
||||||
|
|
||||||
// Reset Allotment sizes when changes, logs, or preview panel becomes visible
|
// Reset Allotment sizes when right main panel becomes visible
|
||||||
// This re-applies preferredSize percentages based on current window size
|
// This re-applies preferredSize percentages based on current window size
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (isRightMainPanelVisible && allotmentRef.current) {
|
||||||
(isChangesMode || isLogsMode || isPreviewMode) &&
|
|
||||||
allotmentRef.current
|
|
||||||
) {
|
|
||||||
allotmentRef.current.reset();
|
allotmentRef.current.reset();
|
||||||
}
|
}
|
||||||
}, [isChangesMode, isLogsMode, isPreviewMode]);
|
}, [isRightMainPanelVisible]);
|
||||||
|
|
||||||
// Reset changes and logs mode when entering create mode
|
// Reset changes and logs mode when entering create mode
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -453,12 +457,20 @@ export function WorkspacesLayout() {
|
|||||||
}
|
}
|
||||||
}, [isCreateMode, resetForCreateMode]);
|
}, [isCreateMode, resetForCreateMode]);
|
||||||
|
|
||||||
// Show sidebar when no panel is open
|
// Show sidebar when right main panel is hidden
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isChangesMode && !isLogsMode && !isPreviewMode) {
|
if (!isRightMainPanelVisible) {
|
||||||
setSidebarVisible(true);
|
setSidebarVisible(true);
|
||||||
}
|
}
|
||||||
}, [isChangesMode, isLogsMode, isPreviewMode, setSidebarVisible]);
|
}, [isRightMainPanelVisible, setSidebarVisible]);
|
||||||
|
|
||||||
|
// Ensure left main panel (chat) is visible when right main panel is hidden
|
||||||
|
// This prevents invalid state where only sidebars are visible after page reload
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isMainPanelVisible && !isRightMainPanelVisible) {
|
||||||
|
setMainPanelVisible(true);
|
||||||
|
}
|
||||||
|
}, [isMainPanelVisible, isRightMainPanelVisible, setMainPanelVisible]);
|
||||||
|
|
||||||
// Command bar keyboard shortcut (CMD+K)
|
// Command bar keyboard shortcut (CMD+K)
|
||||||
const handleOpenCommandBar = useCallback(() => {
|
const handleOpenCommandBar = useCallback(() => {
|
||||||
@@ -748,7 +760,7 @@ export function WorkspacesLayout() {
|
|||||||
<Allotment.Pane
|
<Allotment.Pane
|
||||||
minSize={300}
|
minSize={300}
|
||||||
preferredSize={changesPanelWidth}
|
preferredSize={changesPanelWidth}
|
||||||
visible={isChangesMode || isLogsMode || isPreviewMode}
|
visible={isRightMainPanelVisible}
|
||||||
>
|
>
|
||||||
<div className="h-full overflow-hidden">
|
<div className="h-full overflow-hidden">
|
||||||
{isChangesMode && (
|
{isChangesMode && (
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ type LayoutState = {
|
|||||||
setLogsMode: (value: boolean) => void;
|
setLogsMode: (value: boolean) => void;
|
||||||
setPreviewMode: (value: boolean) => void;
|
setPreviewMode: (value: boolean) => void;
|
||||||
setSidebarVisible: (value: boolean) => void;
|
setSidebarVisible: (value: boolean) => void;
|
||||||
|
setMainPanelVisible: (value: boolean) => void;
|
||||||
|
|
||||||
// Preview actions
|
// Preview actions
|
||||||
triggerPreviewRefresh: () => void;
|
triggerPreviewRefresh: () => void;
|
||||||
@@ -168,6 +169,8 @@ export const useLayoutStore = create<LayoutState>()(
|
|||||||
|
|
||||||
setSidebarVisible: (value) => set({ isSidebarVisible: value }),
|
setSidebarVisible: (value) => set({ isSidebarVisible: value }),
|
||||||
|
|
||||||
|
setMainPanelVisible: (value) => set({ isMainPanelVisible: value }),
|
||||||
|
|
||||||
triggerPreviewRefresh: () =>
|
triggerPreviewRefresh: () =>
|
||||||
set((s) => ({ previewRefreshKey: s.previewRefreshKey + 1 })),
|
set((s) => ({ previewRefreshKey: s.previewRefreshKey + 1 })),
|
||||||
|
|
||||||
@@ -200,3 +203,7 @@ export const useIsGitPanelVisible = () =>
|
|||||||
export const useIsChangesMode = () => useLayoutStore((s) => s.isChangesMode);
|
export const useIsChangesMode = () => useLayoutStore((s) => s.isChangesMode);
|
||||||
export const useIsLogsMode = () => useLayoutStore((s) => s.isLogsMode);
|
export const useIsLogsMode = () => useLayoutStore((s) => s.isLogsMode);
|
||||||
export const useIsPreviewMode = () => useLayoutStore((s) => s.isPreviewMode);
|
export const useIsPreviewMode = () => useLayoutStore((s) => s.isPreviewMode);
|
||||||
|
|
||||||
|
// Derived selector: true when right main panel content is visible (Changes/Logs/Preview)
|
||||||
|
export const useIsRightMainPanelVisible = () =>
|
||||||
|
useLayoutStore((s) => s.isChangesMode || s.isLogsMode || s.isPreviewMode);
|
||||||
|
|||||||
Reference in New Issue
Block a user