diff --git a/src/common/context/LocalStorageContext.tsx b/src/common/context/LocalStorageContext.tsx deleted file mode 100644 index 5ffdf40e..00000000 --- a/src/common/context/LocalStorageContext.tsx +++ /dev/null @@ -1,91 +0,0 @@ -import * as React from 'react'; - -// TODO - duplicated from forklift-ui and made generic, candidate for reuse in lib-ui - -type LocalStorageValues = { - [key in KeyListType[number]]?: string; -}; - -const getLocalStorageValues = ( - keyList: KeyListType, -): LocalStorageValues => - keyList.reduce((values, key) => { - return { ...values, [key]: window.localStorage.getItem(key) }; - }, {}); - -interface LocalStorageContextValue { - storageValues: LocalStorageValues; - setStorageValues: (newValues: LocalStorageValues) => void; -} - -interface LocalStorageContextProviderProps { - children: React.ReactNode; - context: React.Context>; - keyList: KeyListType; -} - -const LocalStorageContextProvider = ({ - children, - context, - keyList, -}: React.PropsWithChildren>): JSX.Element | null => { - const [values, setValues] = React.useState>( - getLocalStorageValues(keyList), - ); - - const setStorageValues = (newValues: LocalStorageValues) => { - try { - Object.keys(newValues).forEach((key: KeyListType[number]) => { - if (newValues[key]) window.localStorage.setItem(key, newValues[key] as string); - }); - setValues({ ...values, ...newValues }); - } catch (error) { - console.error('Failed to update local storage', { newValues, error }); - } - }; - - React.useEffect(() => { - const updateFromStorage = () => setValues(getLocalStorageValues(keyList)); - window.addEventListener('storage', updateFromStorage); - return () => { - window.removeEventListener('storage', updateFromStorage); - }; - }, [keyList]); - - return ( - - {children} - - ); -}; - -const useLocalStorageContextKey = ( - context: React.Context>, - key: KeyListType[number], -): [string | undefined, (value: string) => void] => { - const { storageValues, setStorageValues } = React.useContext(context); - const value = storageValues[key]; - const setValue = (value: string) => - setStorageValues({ [key]: value } as LocalStorageValues); - return [value, setValue]; -}; - -export const createLocalStorageContext = ( - keyList: KeyListType, -) => { - const context = React.createContext>({ - storageValues: {}, - setStorageValues: () => { - console.error( - 'setStorageValues was called without a LocalStorageContextProvider in the tree', - ); - }, - }); - const Provider: React.FunctionComponent<{ children: React.ReactNode }> = ({ children }) => ( - - {children} - - ); - const useKey = (key: KeyListType[number]) => useLocalStorageContextKey(context, key); - return { context, Provider, useKey }; -}; diff --git a/src/common/context/createLocalStorageContext.tsx b/src/common/context/createLocalStorageContext.tsx new file mode 100644 index 00000000..0c34e46a --- /dev/null +++ b/src/common/context/createLocalStorageContext.tsx @@ -0,0 +1,70 @@ +import * as React from 'react'; + +// TODO - duplicated from forklift-ui and made generic, candidate for reuse in lib-ui + +export const createLocalStorageContext = ( + keyList: KeyListType, +) => { + type LocalStorageValues = { + [key in KeyListType[number]]?: string; + }; + + const getLocalStorageValues = (): LocalStorageValues => + keyList.reduce((values, key) => { + return { ...values, [key]: window.localStorage.getItem(key) }; + }, {}); + + interface ContextData { + storageValues: LocalStorageValues; + setStorageValues: (newValues: LocalStorageValues) => void; + } + + const context = React.createContext({ + storageValues: {}, + setStorageValues: () => { + console.error( + 'setStorageValues was called without a LocalStorageContextProvider in the tree', + ); + }, + }); + + const Provider: React.FunctionComponent<{ children: React.ReactNode }> = ({ children }) => { + const [values, setStateValues] = React.useState(getLocalStorageValues()); + + const setStorageValues = (newValues: LocalStorageValues) => { + try { + Object.keys(newValues).forEach((key: KeyListType[number]) => { + if (newValues[key]) window.localStorage.setItem(key, newValues[key] as string); + }); + setStateValues({ ...values, ...newValues }); + } catch (error) { + console.error('Failed to update local storage', { newValues, error }); + } + }; + + React.useEffect(() => { + const updateFromStorage = () => setStateValues(getLocalStorageValues()); + window.addEventListener('storage', updateFromStorage); + return () => { + window.removeEventListener('storage', updateFromStorage); + }; + }, []); + + return ( + + {children} + + ); + }; + + const useStorage = ( + key: KeyListType[number], + ): [string | undefined, (value: string) => void] => { + const { storageValues, setStorageValues } = React.useContext(context); + const value = storageValues[key]; + const setValue = (value: string) => setStorageValues({ [key]: value } as LocalStorageValues); + return [value, setValue]; + }; + + return { context, Provider, useStorage }; +}; diff --git a/src/components/ImportWizard/ImportWizardWelcomeModal.tsx b/src/components/ImportWizard/ImportWizardWelcomeModal.tsx index 967e8dcb..438296db 100644 --- a/src/components/ImportWizard/ImportWizardWelcomeModal.tsx +++ b/src/components/ImportWizard/ImportWizardWelcomeModal.tsx @@ -14,7 +14,7 @@ export const ImportWizardWelcomeModal: React.FunctionComponent { const namespace = useNamespaceContext(); - const [isDisabled, setIsDisabled] = localStorageContext.useKey( + const [isDisabled, setIsDisabled] = localStorageContext.useStorage( 'isCraneWizardWelcomeModalDisabled', ); const [isOpen, setIsOpen] = React.useState(false);