import { Context, createContext, ReactNode, useCallback, useContext, useMemo, useState, } from 'react'; import { useLocalStorage } from '@/portainer/hooks/useLocalStorage'; interface TableSettingsContextInterface { settings: T; setTableSettings(partialSettings: Partial): void; setTableSettings(mutation: (settings: T) => T): void; } const TableSettingsContext = createContext > | null>(null); TableSettingsContext.displayName = 'TableSettingsContext'; export function useTableSettings() { const Context = getContextType(); const context = useContext(Context); if (context === null) { throw new Error('must be nested under TableSettingsProvider'); } return context; } interface ProviderProps { children: ReactNode; defaults?: T; storageKey: string; } export function TableSettingsProvider({ children, defaults, storageKey, }: ProviderProps) { const Context = getContextType(); const [storage, setStorage] = useLocalStorage( keyBuilder(storageKey), defaults as T ); const [settings, setTableSettings] = useState(storage); const handleChange = useCallback( (mutation: Partial | ((settings: T) => T)): void => { setTableSettings((settings) => { const newTableSettings = mutation instanceof Function ? mutation(settings) : { ...settings, ...mutation }; setStorage(newTableSettings); return newTableSettings; }); }, [setStorage] ); const contextValue = useMemo( () => ({ settings, setTableSettings: handleChange, }), [settings, handleChange] ); return {children}; function keyBuilder(key: string) { return `datatable_TableSettings_${key}`; } } function getContextType() { return TableSettingsContext as unknown as Context< TableSettingsContextInterface >; }