From 039d7cb0cbbf0d6907dc65becc4f200c852a2034 Mon Sep 17 00:00:00 2001 From: andrei Date: Tue, 1 Jul 2025 18:44:18 +0500 Subject: [PATCH] =?UTF-8?q?feat:=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=20=D0=B2=D0=BA=D0=BB=D0=B0=D0=B4=D0=BA=D0=B0?= =?UTF-8?q?=20=D1=83=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F?= =?UTF-8?q?=20=D1=80=D0=B5=D0=B7=D0=B5=D1=80=D0=B2=D0=BD=D1=8B=D0=BC=D0=B8?= =?UTF-8?q?=20=D0=BA=D0=BE=D0=BF=D0=B8=D1=8F=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BackupManageTab/useBackupManageTab.js | 116 ++++++++++++++++++ web-app/src/Redux/store.js | 4 + 2 files changed, 120 insertions(+) diff --git a/web-app/src/Components/Pages/AdminPage/Components/BackupManageTab/useBackupManageTab.js b/web-app/src/Components/Pages/AdminPage/Components/BackupManageTab/useBackupManageTab.js index e69de29..2ac08fd 100644 --- a/web-app/src/Components/Pages/AdminPage/Components/BackupManageTab/useBackupManageTab.js +++ b/web-app/src/Components/Pages/AdminPage/Components/BackupManageTab/useBackupManageTab.js @@ -0,0 +1,116 @@ +import { + useCreateBackupMutation, + useDeleteBackupMutation, + useGetBackupsQuery +} from "../../../../../Api/backupsApi.js"; +import {useDispatch} from "react-redux"; +import {notification} from "antd"; +import {baseQueryWithAuth} from "../../../../../Api/baseQuery.js"; +import {useState} from "react"; + + +const useBackupManageTab = () => { + const dispatch = useDispatch(); + const {data: backups, isLoading: isLoadingBackups, isError: isErrorBackups} = useGetBackupsQuery(undefined, { + pollingInterval: 60000, + }); + const [createBackup, {isLoading: isCreatingBackup}] = useCreateBackupMutation(); + const [deleteBackup, {isLoading: isDeletingBackup}] = useDeleteBackupMutation(); + + const [isDownloadingBackup, setDownloadingFiles] = useState(false); + + const createBackupHandler = async () => { + try { + await createBackup().unwrap(); + notification.success({ + message: "Успех", + description: "Резервная копия успешно создана", + placement: "topRight", + }); + } catch (e) { + notification.error({ + message: "Ошибка", + description: e?.data?.detail || "Не удалось создать резервную копию", + placement: "topRight", + }); + } + }; + + const downloadBackupHandler = async (backupId, fileName) => { + try { + setDownloadingFiles(true); + const {url, ...options} = await baseQueryWithAuth( + { + url: `/backups/${backupId}/`, + method: 'GET', + credentials: 'include', + }, + {}, + {} + ); + + const response = await fetch(url, { + ...options, + method: 'GET', + credentials: 'include', + }); + + if (!response.ok) { + notification.error({ + message: "Ошибка при скачивании файла", + description: "Не удалось загрузить файл.", + placement: "topRight", + }); + } + + const blob = await response.blob(); + const downloadUrl = window.URL.createObjectURL(blob); + const link = document.createElement("a"); + link.href = downloadUrl; + link.setAttribute("download", fileName || "file"); + document.body.appendChild(link); + link.click(); + link.remove(); + window.URL.revokeObjectURL(downloadUrl); + setDownloadingFiles(false); + } catch (e) { + console.log(e) + notification.error({ + message: "Ошибка", + description: e?.data?.detail || "Не удалось загрузить резервную копию", + placement: "topRight", + }); + } + }; + + const deleteBackupHandler = async (backupId) => { + try { + await deleteBackup(backupId).unwrap(); + notification.success({ + message: "Успех", + description: "Резервная копия успешно удалена", + placement: "topRight", + }); + } catch (e) { + notification.error({ + message: "Ошибка", + description: e?.data?.detail || "Не удалось удалить резервную копию", + placement: "topRight", + }); + } + }; + + return { + backups, + isLoadingBackups, + isErrorBackups, + isCreatingBackup, + isDownloadingBackup, + isDeletingBackup, + createBackupHandler, + downloadBackupHandler, + deleteBackupHandler, + } +}; + +export default useBackupManageTab; \ No newline at end of file diff --git a/web-app/src/Redux/store.js b/web-app/src/Redux/store.js index d29ef97..0f9e2db 100644 --- a/web-app/src/Redux/store.js +++ b/web-app/src/Redux/store.js @@ -21,6 +21,7 @@ import {rolesApi} from "../Api/rolesApi.js"; import adminReducer from "./Slices/adminSlice.js"; import {registerApi} from "../Api/registerApi.js"; import {appointmentFilesApi} from "../Api/appointmentFilesApi.js"; +import {backupsApi} from "../Api/backupsApi.js"; export const store = configureStore({ reducer: { @@ -60,6 +61,8 @@ export const store = configureStore({ [registerApi.reducerPath]: registerApi.reducer, [appointmentFilesApi.reducerPath]: appointmentFilesApi.reducer, + + [backupsApi.reducerPath]: backupsApi.reducer }, middleware: (getDefaultMiddleware) => ( getDefaultMiddleware().concat( @@ -77,6 +80,7 @@ export const store = configureStore({ rolesApi.middleware, registerApi.middleware, appointmentFilesApi.middleware, + backupsApi.middleware, ) ), });