feat(frontend): persist drawer open/close state on page refresh (#10935)

Co-authored-by: sp.wack <83104063+amanape@users.noreply.github.com>
This commit is contained in:
Hiep Le
2025-09-11 22:58:00 +07:00
committed by GitHub
parent 921fec0019
commit e21475a88e
3 changed files with 26 additions and 9 deletions

View File

@@ -57,18 +57,13 @@ export function ConversationMain() {
<PanelGroup
direction="horizontal"
className="grow h-full min-h-0 min-w-0"
autoSaveId="react-resizable-panels:layout"
>
<Panel
defaultSize={50}
minSize={30}
maxSize={80}
className="overflow-hidden bg-base"
>
<Panel minSize={30} maxSize={80} className="overflow-hidden bg-base">
<ChatInterfaceWrapper isRightPanelShown={isRightPanelShown} />
</Panel>
<PanelResizeHandle className="cursor-ew-resize" />
<Panel
defaultSize={50}
minSize={20}
maxSize={70}
className="flex flex-col overflow-hidden"

View File

@@ -1,6 +1,7 @@
import { useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import { useTranslation } from "react-i18next";
import { useLocalStorage } from "@uidotdev/usehooks";
import JupyterIcon from "#/icons/jupyter.svg?react";
import TerminalIcon from "#/icons/terminal.svg?react";
import GlobeIcon from "#/icons/globe.svg?react";
@@ -15,6 +16,7 @@ import { VSCodeTooltipContent } from "./vscode-tooltip-content";
import {
setHasRightPanelToggled,
setSelectedTab,
setIsRightPanelShown,
type ConversationTab,
} from "#/state/conversation-slice";
import { RootState } from "#/store";
@@ -28,10 +30,30 @@ export function ConversationTabs() {
(state: RootState) => state.conversation,
);
// Persist selectedTab and isRightPanelShown in localStorage
const [persistedSelectedTab, setPersistedSelectedTab] =
useLocalStorage<ConversationTab | null>(
"conversation-selected-tab",
"editor",
);
const [persistedIsRightPanelShown, setPersistedIsRightPanelShown] =
useLocalStorage<boolean>("conversation-right-panel-shown", true);
const onTabChange = (value: ConversationTab | null) => {
dispatch(setSelectedTab(value));
// Persist the selected tab to localStorage
setPersistedSelectedTab(value);
};
// Initialize Redux state from localStorage on component mount
useEffect(() => {
// Initialize selectedTab from localStorage if available
dispatch(setSelectedTab(persistedSelectedTab));
dispatch(setIsRightPanelShown(persistedIsRightPanelShown));
dispatch(setHasRightPanelToggled(persistedIsRightPanelShown));
}, []);
useEffect(() => {
const handlePanelVisibilityChange = () => {
if (isRightPanelShown) {
@@ -51,11 +73,13 @@ export function ConversationTabs() {
if (selectedTab === tab && isRightPanelShown) {
// If clicking the same active tab, close the drawer
dispatch(setHasRightPanelToggled(false));
setPersistedIsRightPanelShown(false);
} else {
// If clicking a different tab or drawer is closed, open drawer and select tab
onTabChange(tab);
if (!isRightPanelShown) {
dispatch(setHasRightPanelToggled(true));
setPersistedIsRightPanelShown(true);
}
}
};

View File

@@ -117,8 +117,6 @@ export const conversationSlice = createSlice({
},
// Reset conversation state (useful for cleanup)
resetConversationState: (state) => {
state.selectedTab = "editor";
state.isRightPanelShown = true;
state.shouldHideSuggestions = false;
},
setHasRightPanelToggled: (state, action) => {