150 lines
3.9 KiB
TypeScript
150 lines
3.9 KiB
TypeScript
import React from "react";
|
||
import { type GridColDef } from "@mui/x-data-grid";
|
||
import {
|
||
DeleteButton,
|
||
EditButton,
|
||
List,
|
||
ShowButton,
|
||
useDataGrid,
|
||
} from "@refinedev/mui";
|
||
import { Stack } from "@mui/material";
|
||
import { CustomDataGrid } from "@components";
|
||
import { localeText } from "../../locales/ru/localeText";
|
||
import { observer } from "mobx-react-lite";
|
||
import { useMany } from "@refinedev/core";
|
||
import { DatabaseBackup } from "lucide-react";
|
||
import axios from "axios";
|
||
import { TOKEN_KEY } from "../../providers/authProvider";
|
||
import { toast } from "react-toastify";
|
||
import { useNotification } from "@refinedev/core";
|
||
|
||
export const SnapshotList = observer(() => {
|
||
const notification = useNotification();
|
||
const { dataGridProps } = useDataGrid({
|
||
resource: "snapshots",
|
||
hasPagination: false,
|
||
});
|
||
|
||
// Получаем список уникальных ParentID
|
||
const parentIds = React.useMemo(() => {
|
||
return (
|
||
dataGridProps?.rows
|
||
?.map((row: any) => row.ParentID)
|
||
.filter((id) => id !== null && id !== undefined)
|
||
.filter((value, index, self) => self.indexOf(value) === index) || []
|
||
);
|
||
}, [dataGridProps?.rows]);
|
||
|
||
// Загружаем родительские снапшоты
|
||
const { data: parentsData } = useMany({
|
||
resource: "snapshots",
|
||
ids: parentIds,
|
||
queryOptions: {
|
||
enabled: parentIds.length > 0,
|
||
},
|
||
});
|
||
|
||
// Создаем мапу ID → Name
|
||
const parentNameMap = React.useMemo(() => {
|
||
const map: Record<number, string> = {};
|
||
parentsData?.data?.forEach((parent) => {
|
||
map[parent.ID] = parent.Name;
|
||
});
|
||
return map;
|
||
}, [parentsData]);
|
||
|
||
const handleBackup = async (id: number) => {
|
||
try {
|
||
const response = await axios.post(
|
||
`${import.meta.env.VITE_KRBL_API}/snapshots/${id}/restore`,
|
||
{},
|
||
{
|
||
headers: {
|
||
Authorization: `Bearer ${localStorage.getItem(TOKEN_KEY)}`,
|
||
},
|
||
}
|
||
);
|
||
|
||
if (notification && typeof notification.open === "function") {
|
||
notification.open({
|
||
message: "Cнапшот восстановлен",
|
||
type: "success",
|
||
});
|
||
}
|
||
} catch (error) {
|
||
if (notification && typeof notification.open === "function") {
|
||
notification.open({
|
||
message: "Ошибка при восстановлении снимка",
|
||
type: "error",
|
||
});
|
||
}
|
||
}
|
||
};
|
||
|
||
const columns = React.useMemo<GridColDef[]>(
|
||
() => [
|
||
{
|
||
field: "Name",
|
||
headerName: "Название",
|
||
type: "string",
|
||
minWidth: 150,
|
||
flex: 1,
|
||
align: "left",
|
||
headerAlign: "left",
|
||
},
|
||
{
|
||
field: "ParentID",
|
||
headerName: "Родитель",
|
||
minWidth: 150,
|
||
flex: 1,
|
||
renderCell: ({ value }) => parentNameMap[value] || "—",
|
||
align: "left",
|
||
headerAlign: "left",
|
||
},
|
||
{
|
||
field: "actions",
|
||
headerName: "Действия",
|
||
minWidth: 150,
|
||
display: "flex",
|
||
align: "center",
|
||
headerAlign: "center",
|
||
sortable: false,
|
||
filterable: false,
|
||
disableColumnMenu: true,
|
||
renderCell: function render({ row }) {
|
||
return (
|
||
<>
|
||
<button
|
||
className="backup-button"
|
||
onClick={() => handleBackup(row.ID)}
|
||
>
|
||
<DatabaseBackup />
|
||
</button>
|
||
<ShowButton hideText recordItemId={row.ID} />
|
||
<DeleteButton
|
||
hideText
|
||
confirmTitle="Вы уверены?"
|
||
recordItemId={row.ID}
|
||
/>
|
||
</>
|
||
);
|
||
},
|
||
},
|
||
],
|
||
[parentNameMap]
|
||
);
|
||
|
||
return (
|
||
<List>
|
||
<Stack gap={2.5}>
|
||
<CustomDataGrid
|
||
{...dataGridProps}
|
||
columns={columns}
|
||
localeText={localeText}
|
||
getRowId={(row: any) => row.ID}
|
||
/>
|
||
</Stack>
|
||
</List>
|
||
);
|
||
});
|