diff --git a/src/lang/en/br.json b/src/lang/en/br.json index 6a01cddf5f..500f49b719 100644 --- a/src/lang/en/br.json +++ b/src/lang/en/br.json @@ -9,5 +9,6 @@ "start_restore": "Start restore", "finish_restore": "Finish restore", "success_restore_item": "[ {{item}} ] Restore was successful", - "failed_restore_item": "[ {{item}} ] Restore failed" + "failed_restore_item": "[ {{item}} ] Restore failed", + "override": "Override" } diff --git a/src/pages/manage/backup-restore.tsx b/src/pages/manage/backup-restore.tsx index 2827815bd4..09bc44464a 100644 --- a/src/pages/manage/backup-restore.tsx +++ b/src/pages/manage/backup-restore.tsx @@ -1,4 +1,10 @@ -import { HStack, Button, VStack, Text } from "@hope-ui/solid" +import { + HStack, + Button, + VStack, + Text, + Switch as HopeSwitch, +} from "@hope-ui/solid" import { r, handleRespWithoutNotify, notify } from "~/utils" import { useFetch, useManageTitle, useT } from "~/hooks" import { @@ -44,6 +50,7 @@ const Log = (props: { msg: string; type: LogType }) => { } const BackupRestore = () => { + const [override, setOverride] = createSignal(false) const t = useT() useManageTitle("manage.sidemenu.backup-restore") let logRef: HTMLDivElement @@ -136,12 +143,74 @@ const BackupRestore = () => { const [addMetaLoading, addMeta] = useFetch((meta: Meta): PEmptyResp => { return r.post(`/admin/meta/create`, meta) }) + const [updateUserLoading, updateUser] = useFetch((user: User): PEmptyResp => { + return r.post(`/admin/user/update`, user) + }) + const [updateStorageLoading, updateStorage] = useFetch( + (storage: Storage): PEmptyResp => { + return r.post(`/admin/storage/update`, storage) + } + ) + const [updateMetaLoading, updateMeta] = useFetch((meta: Meta): PEmptyResp => { + return r.post(`/admin/meta/update`, meta) + }) + async function handleOvrData( + dataArray: T[], + getDataFunc: { (): PResp<{ content: T[]; total: number }> }, + addDataFunc: { + (t: T): PEmptyResp + }, + updateDataFunc: { + (t: T): PEmptyResp + }, + idFieldName: keyof T, + itemName: string + ) { + const currentData = (await getDataFunc()).data.content + for (const i in dataArray) { + const currentItem = dataArray[i] + const currentIdValue = currentItem[idFieldName] + const currentDataItem = currentData.find( + (d) => d[idFieldName] === currentIdValue + ) + const method = currentDataItem ? "update" : "add" + const handleDataFunc = method === "add" ? addDataFunc : updateDataFunc + await handleRespWithoutNotify( + await handleDataFunc(currentItem), + () => { + appendLog( + t("br.success_restore_item", { + item: t(itemName), + }) + + "-" + + `[${currentIdValue}]`, + "success" + ) + }, + (msg) => { + appendLog( + t("br.failed_restore_item", { + item: t(itemName), + }) + + "-" + + `[${currentIdValue}]` + + ":" + + msg, + "error" + ) + } + ) + } + } const restoreLoading = () => { return ( addSettingsLoading() || addUserLoading() || addStorageLoading() || - addMetaLoading() + addMetaLoading() || + updateUserLoading() || + updateStorageLoading() || + updateMetaLoading() ) } const restore = async () => { @@ -159,6 +228,9 @@ const BackupRestore = () => { const reader = new FileReader() reader.onload = async () => { const data: Data = JSON.parse(reader.result as string) + if (override()) { + await backup() + } data.settings && handleRespWithoutNotify( await addSettings( @@ -185,42 +257,69 @@ const BackupRestore = () => { ) } ) - for (const item of [ - { name: "users", fn: addUser, data: data.users, key: "username" }, - { - name: "storages", - fn: addStorage, - data: data.storages, - key: "mount_path", - }, - { name: "metas", fn: addMeta, data: data.metas, key: "path" }, - ] as const) { - for (const itemData of item.data || []) { - itemData.id = 0 - handleRespWithoutNotify( - await item.fn(itemData), - () => { - appendLog( - t("br.success_restore_item", { - item: t(`manage.sidemenu.${item.name}`), - }) + - "-" + - `[${(itemData as any)[item.key]}]`, - "success" - ) - }, - (msg) => { - appendLog( - t("br.failed_restore_item", { - item: t(`manage.sidemenu.${item.name}`), - }) + - ` [ ${(itemData as any)[item.key]} ] ` + - ":" + - msg, - "error" - ) - } - ) + if (override()) { + await handleOvrData( + data.users, + getUsers, + addUser, + updateUser, + "username", + "manage.sidemenu.users" + ) + await handleOvrData( + data.storages, + getStorages, + addStorage, + updateStorage, + "mount_path", + "manage.sidemenu.storages" + ) + await handleOvrData( + data.metas, + getMetas, + addMeta, + updateMeta, + "path", + "manage.sidemenu.metas" + ) + } else { + for (const item of [ + { name: "users", fn: addUser, data: data.users, key: "username" }, + { + name: "storages", + fn: addStorage, + data: data.storages, + key: "mount_path", + }, + { name: "metas", fn: addMeta, data: data.metas, key: "path" }, + ] as const) { + for (const itemData of item.data || []) { + itemData.id = 0 + handleRespWithoutNotify( + await item.fn(itemData), + () => { + appendLog( + t("br.success_restore_item", { + item: t(`manage.sidemenu.${item.name}`), + }) + + "-" + + `[${(itemData as any)[item.key]}]`, + "success" + ) + }, + (msg) => { + appendLog( + t("br.failed_restore_item", { + item: t(`manage.sidemenu.${item.name}`), + }) + + ` [ ${(itemData as any)[item.key]} ] ` + + ":" + + msg, + "error" + ) + } + ) + } } } appendLog(t("br.finish_restore"), "info") @@ -231,7 +330,7 @@ const BackupRestore = () => { } return ( - + + + setOverride(e.currentTarget.checked) + } + > + {t("br.override")} + { role: 0, permission: 0, disabled: false, - github_id: 0, + sso_id: "", }) const [userLoading, loadUser] = useFetch( (): PResp => r.get(`/admin/user/get?id=${id}`) @@ -147,7 +147,7 @@ const AddOrEdit = () => { loading={okLoading()} onClick={async () => { const resp = await ok() - // TODO maybe can use handleRrespWithNotifySuccess + // TODO maybe can use handleRespWithNotifySuccess handleResp(resp, () => { notify.success(t("global.save_success")) back()