Files
EMS-ESP32/interface/src/utils/useRest.ts
2023-07-03 12:38:31 +02:00

86 lines
2.1 KiB
TypeScript

import { useRequest, type Method } from 'alova';
import { useState } from 'react';
import { unstable_useBlocker as useBlocker } from 'react-router-dom';
import { toast } from 'react-toastify';
import { useI18nContext } from 'i18n/i18n-react';
export interface RestRequestOptions2<D> {
read: () => Method<any, any, any, any, any, any, any>;
update: (value: D) => Method<any, any, any, any, any, any, any>;
}
export const useRest = <D>({ read, update }: RestRequestOptions2<D>) => {
const { LL } = useI18nContext();
const [errorMessage, setErrorMessage] = useState<string>();
const [restartNeeded, setRestartNeeded] = useState<boolean>(false);
const [origData, setOrigData] = useState<D>();
const [dirtyFlags, setDirtyFlags] = useState<string[]>([]);
const blocker = useBlocker(dirtyFlags.length !== 0);
const { data: data, send: readData, update: updateData, onComplete: onReadComplete } = useRequest(read());
const {
loading: saving,
send: writeData,
onSuccess: onWriteSuccess
} = useRequest((newData: D) => update(newData), { immediate: false });
const updateDataValue = (new_data: D) => {
updateData({ data: new_data });
};
onWriteSuccess(() => {
toast.success(LL.UPDATED_OF(LL.SETTINGS()));
setDirtyFlags([]);
});
onReadComplete((event) => {
setOrigData(event.data);
});
const loadData = async () => {
setDirtyFlags([]);
setErrorMessage(undefined);
await readData().catch((error) => {
toast.error(error.message);
setErrorMessage(error.message);
});
};
const saveData = async () => {
if (!data) {
return;
}
setRestartNeeded(false);
setErrorMessage(undefined);
setDirtyFlags([]);
setOrigData(data);
await writeData(data).catch((error) => {
if (error.message === 'Reboot required') {
setRestartNeeded(true);
} else {
toast.error(error.message);
setErrorMessage(error.message);
}
});
};
return {
loadData,
saveData,
saving,
updateDataValue,
data,
origData,
dirtyFlags,
setDirtyFlags,
setOrigData,
blocker,
errorMessage,
restartNeeded
} as const;
};