import { useState, useEffect } from 'react'; import { SWRConfiguration } from 'swr'; import { dequal } from 'dequal'; import { StaleDataNotification } from 'component/common/StaleDataNotification/StaleDataNotification'; interface IFormatUnleashGetterOutput { data: Type; refetch: () => void; } const formatUnleashGetter = ({ unleashGetter, dataKey = '', refetchFunctionKey = '', options = {}, params = [''], }: IGetterOptions): IFormatUnleashGetterOutput => { const result = unleashGetter(...params, { refreshInterval: 5, ...options }); return { data: result[dataKey], refetch: result[refetchFunctionKey] }; }; interface IGetterOptions { dataKey: string; unleashGetter: any; options: SWRConfiguration; refetchFunctionKey: string; params: string[]; } interface ICollaborateDataOutput { staleDataNotification: JSX.Element; data: Type | null; refetch: () => void; forceRefreshCache: (data: Type) => void; } interface IStaleNotificationOptions { afterSubmitAction: () => void; } export const useCollaborateData = ( getterOptions: IGetterOptions, initialData: Type, notificationOptions: IStaleNotificationOptions, comparisonModeratorFunc: (data: Type) => any ): ICollaborateDataOutput => { const { data, refetch } = formatUnleashGetter(getterOptions); const [cache, setCache] = useState(initialData || null); const [dataModified, setDataModified] = useState(false); const forceRefreshCache = (data: Type) => { setDataModified(false); setCache(data); }; const formatDequalData = (data: Type | null) => { if (!data) return data; if ( comparisonModeratorFunc && typeof comparisonModeratorFunc === 'function' ) { return comparisonModeratorFunc(data); } return data; }; useEffect(() => { if (cache === null) { setCache(initialData); } }, [initialData]); useEffect(() => { if (!cache || !data) return; const equal = dequal(formatDequalData(cache), formatDequalData(data)); if (!equal) { setDataModified(true); } }, [data]); return { data: cache, refetch, staleDataNotification: ( forceRefreshCache(data)} show={dataModified} afterSubmitAction={notificationOptions.afterSubmitAction} /> ), forceRefreshCache, }; };