Presupuestador_web/client/src/lib/hooks/useLoadingOvertime/useLoadingOvertime.ts
2024-06-06 13:05:54 +02:00

105 lines
2.7 KiB
TypeScript

import { useEffect, useState } from "react";
export type UseLoadingOvertimeRefineContext = Omit<
UseLoadingOvertimeCoreProps,
"isPending" | "interval"
> &
Required<Pick<UseLoadingOvertimeCoreProps, "interval">>;
export type UseLoadingOvertimeOptionsProps = {
overtimeOptions?: UseLoadingOvertimeCoreOptions;
};
export type UseLoadingOvertimeReturnType = {
overtime: {
elapsedTime?: number;
};
};
type UseLoadingOvertimeCoreOptions = Omit<
UseLoadingOvertimeCoreProps,
"isPending"
>;
type UseLoadingOvertimeCoreReturnType = {
elapsedTime?: number;
};
export type UseLoadingOvertimeCoreProps = {
/**
* The pengind state. If true, the elapsed time will be calculated.
*/
isPending: boolean;
/**
* The interval in milliseconds. If the pending time exceeds this time, the `onInterval` callback will be called.
* If not specified, the `interval` value from the `overtime` option of the `RefineProvider` will be used.
*
* @default: 1000 (1 second)
*/
interval?: number;
/**
* The callback function that will be called when the pending time exceeds the specified time.
* If not specified, the `onInterval` value from the `overtime` option of the `RefineProvider` will be used.
*
* @param elapsedInterval The elapsed time in milliseconds.
*/
onInterval?: (elapsedInterval: number) => void;
};
/**
* if you need to do something when the loading time exceeds the specified time, refine provides the `useLoadingOvertime` hook.
* It returns the elapsed time in milliseconds.
*
* @example
* const { elapsedTime } = useLoadingOvertime({
* isLoading,
* interval: 1000,
* onInterval(elapsedInterval) {
* console.log("loading overtime", elapsedInterval);
* },
* });
*/
export const useLoadingOvertime = ({
isPending,
interval = 1000,
onInterval,
}: UseLoadingOvertimeCoreProps): UseLoadingOvertimeCoreReturnType => {
const [elapsedTime, setElapsedTime] = useState<number | undefined>(undefined);
useEffect(() => {
let intervalFn: ReturnType<typeof setInterval>;
if (isPending) {
intervalFn = setInterval(() => {
// increase elapsed time
setElapsedTime((prevElapsedTime) => {
if (prevElapsedTime === undefined) {
return interval;
}
return prevElapsedTime + interval;
});
}, interval);
}
return () => {
clearInterval(intervalFn);
// reset elapsed time
setElapsedTime(undefined);
};
}, [isPending, interval]);
useEffect(() => {
// call onInterval callback
if (onInterval && elapsedTime) {
onInterval(elapsedTime);
}
}, [elapsedTime]);
return {
elapsedTime,
};
};