2022-09-16 15:23:08 +02:00
|
|
|
import { useState, useEffect } from 'react';
|
|
|
|
import { SWRConfiguration } from 'swr';
|
|
|
|
import { dequal } from 'dequal';
|
|
|
|
import { StaleDataNotification } from 'component/common/StaleDataNotification/StaleDataNotification';
|
|
|
|
|
|
|
|
interface IFormatUnleashGetterOutput<Type> {
|
|
|
|
data: Type;
|
|
|
|
refetch: () => void;
|
|
|
|
}
|
|
|
|
|
|
|
|
const formatUnleashGetter = <Type,>({
|
|
|
|
unleashGetter,
|
|
|
|
dataKey = '',
|
|
|
|
refetchFunctionKey = '',
|
|
|
|
options = {},
|
|
|
|
params = [''],
|
|
|
|
}: IGetterOptions): IFormatUnleashGetterOutput<Type> => {
|
|
|
|
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<Type> {
|
|
|
|
staleDataNotification: JSX.Element;
|
|
|
|
data: Type | null;
|
|
|
|
refetch: () => void;
|
|
|
|
forceRefreshCache: (data: Type) => void;
|
|
|
|
}
|
|
|
|
|
|
|
|
interface IStaleNotificationOptions {
|
|
|
|
afterSubmitAction: () => void;
|
|
|
|
}
|
|
|
|
|
|
|
|
export const useCollaborateData = <Type,>(
|
|
|
|
getterOptions: IGetterOptions,
|
|
|
|
initialData: Type,
|
2022-10-06 14:39:56 +02:00
|
|
|
notificationOptions: IStaleNotificationOptions,
|
|
|
|
comparisonModeratorFunc: (data: Type) => any
|
2022-09-16 15:23:08 +02:00
|
|
|
): ICollaborateDataOutput<Type> => {
|
|
|
|
const { data, refetch } = formatUnleashGetter<Type>(getterOptions);
|
|
|
|
const [cache, setCache] = useState<Type | null>(initialData || null);
|
|
|
|
const [dataModified, setDataModified] = useState(false);
|
|
|
|
|
|
|
|
const forceRefreshCache = (data: Type) => {
|
|
|
|
setDataModified(false);
|
|
|
|
setCache(data);
|
|
|
|
};
|
|
|
|
|
2022-10-06 14:39:56 +02:00
|
|
|
const formatDequalData = (data: Type | null) => {
|
|
|
|
if (!data) return data;
|
|
|
|
if (
|
|
|
|
comparisonModeratorFunc &&
|
|
|
|
typeof comparisonModeratorFunc === 'function'
|
|
|
|
) {
|
|
|
|
return comparisonModeratorFunc(data);
|
|
|
|
}
|
|
|
|
return data;
|
|
|
|
};
|
|
|
|
|
2022-09-16 15:23:08 +02:00
|
|
|
useEffect(() => {
|
|
|
|
if (cache === null) {
|
|
|
|
setCache(initialData);
|
|
|
|
}
|
|
|
|
}, [initialData]);
|
|
|
|
|
|
|
|
useEffect(() => {
|
2022-10-06 14:39:56 +02:00
|
|
|
if (!cache || !data) return;
|
|
|
|
|
|
|
|
const equal = dequal(formatDequalData(cache), formatDequalData(data));
|
2022-09-16 15:23:08 +02:00
|
|
|
|
|
|
|
if (!equal) {
|
|
|
|
setDataModified(true);
|
|
|
|
}
|
|
|
|
}, [data]);
|
|
|
|
|
|
|
|
return {
|
|
|
|
data: cache,
|
|
|
|
refetch,
|
|
|
|
staleDataNotification: (
|
|
|
|
<StaleDataNotification
|
2022-10-06 14:39:56 +02:00
|
|
|
cache={formatDequalData(cache)}
|
|
|
|
data={formatDequalData(data)}
|
2022-09-16 15:23:08 +02:00
|
|
|
refresh={() => forceRefreshCache(data)}
|
|
|
|
show={dataModified}
|
|
|
|
afterSubmitAction={notificationOptions.afterSubmitAction}
|
|
|
|
/>
|
|
|
|
),
|
|
|
|
forceRefreshCache,
|
|
|
|
};
|
|
|
|
};
|