diff --git a/gradle/changelog/secondary_navigation_status.yaml b/gradle/changelog/secondary_navigation_status.yaml new file mode 100644 index 0000000000..d6a68411fd --- /dev/null +++ b/gradle/changelog/secondary_navigation_status.yaml @@ -0,0 +1,2 @@ +- type: changed + description: Save collapse status of secondary navigation diff --git a/scm-ui/ui-api/src/localStorage.tsx b/scm-ui/ui-api/src/localStorage.tsx index d4dc8d1361..e2e7c6fa4e 100644 --- a/scm-ui/ui-api/src/localStorage.tsx +++ b/scm-ui/ui-api/src/localStorage.tsx @@ -22,11 +22,12 @@ * SOFTWARE. */ -import React, { createContext, FC, useCallback, useContext, useMemo, useState } from "react"; +import React, { createContext, FC, useCallback, useContext, useEffect, useMemo, useState } from "react"; type LocalStorage = { - getItem: (key: string, initialValue: T) => T; + getItem: (key: string, fallback: T) => T; setItem: (key: string, value: T) => void; + preload: (key: string, initialValue: T) => void; }; const LocalStorageContext = createContext(null as unknown as LocalStorage); @@ -50,9 +51,14 @@ export const LocalStorageProvider: FC = ({ children }) => { }, []); const getItem = useCallback( - (key: string, initialValue: T): T => { - let initialLoadResult: T | undefined; + (key: string, fallback: T): T => (key in localStorageCache ? (localStorageCache[key] as T) : fallback), + [localStorageCache] + ); + + const preload = useCallback( + (key: string, initialValue: T) => { if (!(key in localStorageCache)) { + let initialLoadResult: T | undefined; try { const item = localStorage.getItem(key); initialLoadResult = item ? JSON.parse(item) : initialValue; @@ -63,13 +69,12 @@ export const LocalStorageProvider: FC = ({ children }) => { } setItem(key, initialLoadResult); } - return initialLoadResult ?? (localStorageCache[key] as T); }, [localStorageCache, setItem] ); return ( - ({ getItem, setItem }), [getItem, setItem])}> + ({ getItem, setItem, preload }), [getItem, preload, setItem])}> {children} ); @@ -85,7 +90,7 @@ export function useLocalStorage( key: string, initialValue: T ): [value: T, setValue: (value: T | ((previousConfig: T) => T)) => void] { - const { getItem, setItem } = useContext(LocalStorageContext); + const { getItem, setItem, preload } = useContext(LocalStorageContext); const value = useMemo(() => getItem(key, initialValue), [getItem, initialValue, key]); const setValue = useCallback( (newValue: T | ((previousConfig: T) => T)) => @@ -95,5 +100,6 @@ export function useLocalStorage( // eslint-disable-next-line react-hooks/exhaustive-deps [key, setItem, value] ); + useEffect(() => preload(key, initialValue), [initialValue, key, preload]); return useMemo(() => [value, setValue], [setValue, value]); } diff --git a/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap b/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap index 64255ef8bd..661171f18a 100644 --- a/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap +++ b/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap @@ -72218,7 +72218,7 @@ exports[`Storyshots Secondary Navigation Active when match 1`] = ` className="column is-3" >