diff --git a/packages/graphiql-react/src/editor/__tests__/tabs.spec.ts b/packages/graphiql-react/src/editor/__tests__/tabs.spec.ts index 3c9dcfab193..a5fc7c3d452 100644 --- a/packages/graphiql-react/src/editor/__tests__/tabs.spec.ts +++ b/packages/graphiql-react/src/editor/__tests__/tabs.spec.ts @@ -154,8 +154,9 @@ describe('clearHeadersFromTabs', () => { it('preserves tab state except for headers', () => { const storage = createMockStorage(); const stateWithoutHeaders = { - hash: 123, - response: { + operationName: 'test', + query: 'query test {\n test {\n id\n }\n}', + test: { a: 'test', }, }; diff --git a/packages/graphiql-react/src/editor/context.tsx b/packages/graphiql-react/src/editor/context.tsx index 30219d474e4..ce867659396 100644 --- a/packages/graphiql-react/src/editor/context.tsx +++ b/packages/graphiql-react/src/editor/context.tsx @@ -25,6 +25,8 @@ import { useStoreTabs, useSynchronizeActiveTabValues, clearHeadersFromTabs, + serializeTabState, + STORAGE_KEY as STORAGE_KEY_TABS, } from './tabs'; import { CodeMirrorEditor } from './types'; import { STORAGE_KEY as STORAGE_KEY_VARIABLES } from './variable-editor'; @@ -274,25 +276,13 @@ export function EditorContextProvider(props: EditorContextProviderProps) { const [shouldPersistHeaders, setShouldPersistHeadersInternal] = useState( () => { const propValue = Boolean(props.shouldPersistHeaders); - return userControlledShouldPersistHeaders - ? storage?.get(PERSIST_HEADERS_STORAGE_KEY) === 'true' || propValue + const isStored = storage?.get(PERSIST_HEADERS_STORAGE_KEY) !== null; + return userControlledShouldPersistHeaders && isStored + ? storage?.get(PERSIST_HEADERS_STORAGE_KEY) === 'true' : propValue; }, ); - const setShouldPersistHeaders = useCallback( - (persist: boolean) => { - // clean up when setting to false - if (!persist) { - storage?.set(STORAGE_KEY_HEADERS, ''); - clearHeadersFromTabs(storage); - } - setShouldPersistHeadersInternal(persist); - storage?.set(PERSIST_HEADERS_STORAGE_KEY, persist.toString()); - }, - [storage], - ); - useSynchronizeValue(headerEditor, props.headers); useSynchronizeValue(queryEditor, props.query); useSynchronizeValue(responseEditor, props.response); @@ -337,6 +327,22 @@ export function EditorContextProvider(props: EditorContextProviderProps) { const [tabState, setTabState] = useState(initialState.tabState); + const setShouldPersistHeaders = useCallback( + (persist: boolean) => { + if (persist) { + storage?.set(STORAGE_KEY_HEADERS, headerEditor?.getValue() ?? ''); + const serializedTabs = serializeTabState(tabState, true); + storage?.set(STORAGE_KEY_TABS, serializedTabs); + } else { + storage?.set(STORAGE_KEY_HEADERS, ''); + clearHeadersFromTabs(storage); + } + setShouldPersistHeadersInternal(persist); + storage?.set(PERSIST_HEADERS_STORAGE_KEY, persist.toString()); + }, + [storage, tabState, headerEditor], + ); + const synchronizeActiveTabValues = useSynchronizeActiveTabValues({ queryEditor, variableEditor, diff --git a/packages/graphiql-react/src/editor/tabs.ts b/packages/graphiql-react/src/editor/tabs.ts index d47e766e19f..d12c7e8e177 100644 --- a/packages/graphiql-react/src/editor/tabs.ts +++ b/packages/graphiql-react/src/editor/tabs.ts @@ -210,6 +210,19 @@ export function useSynchronizeActiveTabValues({ ); } +export function serializeTabState( + tabState: TabsState, + shouldPersistHeaders = false, +) { + return JSON.stringify(tabState, (key, value) => + key === 'hash' || + key === 'response' || + (!shouldPersistHeaders && key === 'headers') + ? null + : value, + ); +} + export function useStoreTabs({ storage, shouldPersistHeaders, @@ -226,15 +239,7 @@ export function useStoreTabs({ ); return useCallback( (currentState: TabsState) => { - store( - JSON.stringify(currentState, (key, value) => - key === 'hash' || - key === 'response' || - (!shouldPersistHeaders && key === 'headers') - ? null - : value, - ), - ); + store(serializeTabState(currentState, shouldPersistHeaders)); }, [shouldPersistHeaders, store], );