From e47c786e406772f6ecd7e4a0a3759c31876f4f49 Mon Sep 17 00:00:00 2001 From: "DESKTOP-RTLN3BA\\$punk" Date: Fri, 27 Mar 2026 02:08:36 -0700 Subject: [PATCH] feat: implement session storage for tabs state management and optimize tab reset logic on search space change --- surfsense_web/atoms/tabs/tabs.atom.ts | 12 +++++++++++- .../layout/providers/LayoutDataProvider.tsx | 9 +++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/surfsense_web/atoms/tabs/tabs.atom.ts b/surfsense_web/atoms/tabs/tabs.atom.ts index da527f08d..821c8b022 100644 --- a/surfsense_web/atoms/tabs/tabs.atom.ts +++ b/surfsense_web/atoms/tabs/tabs.atom.ts @@ -1,4 +1,5 @@ import { atom } from "jotai"; +import { atomWithStorage, createJSONStorage } from "jotai/utils"; export type TabType = "chat" | "document"; @@ -32,7 +33,16 @@ const initialState: TabsState = { activeTabId: "chat-new", }; -export const tabsStateAtom = atom(initialState); +const sessionStorageAdapter = createJSONStorage( + () => (typeof window !== "undefined" ? sessionStorage : undefined) as Storage +); + +export const tabsStateAtom = atomWithStorage( + "surfsense:tabs", + initialState, + sessionStorageAdapter, + { getOnInit: true }, +); export const tabsAtom = atom((get) => get(tabsStateAtom).tabs); export const activeTabIdAtom = atom((get) => get(tabsStateAtom).activeTabId); diff --git a/surfsense_web/components/layout/providers/LayoutDataProvider.tsx b/surfsense_web/components/layout/providers/LayoutDataProvider.tsx index edc86e50e..7be8e7973 100644 --- a/surfsense_web/components/layout/providers/LayoutDataProvider.tsx +++ b/surfsense_web/components/layout/providers/LayoutDataProvider.tsx @@ -268,9 +268,14 @@ export function LayoutDataProvider({ searchSpaceId, children }: LayoutDataProvid }, [pendingNewChat, params?.chat_id, router, searchSpaceId, resetCurrentThread]); // Reset transient slide-out panels and tabs when switching search spaces. + // Use a ref to skip the initial mount — only reset when the space actually changes. + const prevSearchSpaceIdRef = useRef(searchSpaceId); useEffect(() => { - setActiveSlideoutPanel(null); - resetTabs(); + if (prevSearchSpaceIdRef.current !== searchSpaceId) { + prevSearchSpaceIdRef.current = searchSpaceId; + setActiveSlideoutPanel(null); + resetTabs(); + } }, [searchSpaceId, resetTabs]); const searchSpaces: SearchSpace[] = useMemo(() => {