alova - add interceptor

This commit is contained in:
Proddy
2023-06-18 16:35:32 +02:00
parent b1d666d7b9
commit ce1b9f22cb
24 changed files with 200 additions and 331 deletions

View File

@@ -1,85 +1,76 @@
import { useCallback, useEffect, useState } from 'react';
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 { extractErrorMessage } from '.';
import type { AxiosPromise } from 'axios';
import { useI18nContext } from 'i18n/i18n-react';
export interface RestRequestOptions<D> {
read: () => AxiosPromise<D>;
update?: (value: D) => AxiosPromise<D>;
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 }: RestRequestOptions<D>) => {
export const useRest = <D>({ read, update }: RestRequestOptions2<D>) => {
const { LL } = useI18nContext();
const [data, setData] = useState<D>();
const [saving, setSaving] = useState<boolean>(false);
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 [dirtyFlags, setDirtyFlags] = useState<string[]>([]);
const blocker = useBlocker(dirtyFlags.length !== 0);
const loadData = useCallback(async () => {
setData(undefined);
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);
try {
const fetch_data = (await read()).data;
setData(fetch_data);
setOrigData(fetch_data);
} catch (error) {
const message = extractErrorMessage(error, LL.PROBLEM_LOADING());
toast.error(message);
setErrorMessage(message);
await readData().catch((error) => {
toast.error(error.message);
setErrorMessage(error.message);
});
};
const saveData = async () => {
if (!data) {
return;
}
}, [read, LL]);
const save = useCallback(
async (toSave: D) => {
if (!update) {
return;
setRestartNeeded(false);
setErrorMessage(undefined);
await writeData(data).catch((error) => {
if (error.message === 'Reboot required') {
setRestartNeeded(true);
} else {
toast.error(error.message);
setErrorMessage(error.message);
}
setSaving(true);
setRestartNeeded(false);
setErrorMessage(undefined);
try {
const response = await update(toSave);
setOrigData(response.data);
setData(response.data);
if (response.status === 205) {
setRestartNeeded(true); // reboot required
} else {
toast.success(LL.UPDATED_OF(LL.SETTINGS()));
}
} catch (error) {
const message = extractErrorMessage(error, LL.PROBLEM_UPDATING());
toast.error(message);
setErrorMessage(message);
} finally {
setSaving(false);
setDirtyFlags([]);
}
},
[update, LL]
);
const saveData = () => data && save(data);
useEffect(() => {
void loadData();
}, [loadData]);
});
};
return {
loadData,
saveData,
saving,
setData,
updateDataValue,
data,
origData,
dirtyFlags,