From 599fe566b813610568d30a60ab8088921e5666e7 Mon Sep 17 00:00:00 2001 From: dv Date: Wed, 27 May 2026 18:08:28 +0300 Subject: [PATCH] =?UTF-8?q?=D1=84=D0=B8=D0=BA=D1=81=20=D1=84=D0=B8=D0=BA?= =?UTF-8?q?=D1=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/api/snapshotPolicies.ts | 26 +++++++++ frontend/src/pages/SnapshotDashboard.tsx | 70 +++++++++++++++++------- 2 files changed, 77 insertions(+), 19 deletions(-) diff --git a/frontend/src/api/snapshotPolicies.ts b/frontend/src/api/snapshotPolicies.ts index 842f28e..56e500b 100644 --- a/frontend/src/api/snapshotPolicies.ts +++ b/frontend/src/api/snapshotPolicies.ts @@ -123,3 +123,29 @@ export const useCollectPolicy = (objId: number) => { }, }) } + +export const useCreateSnapshotPolicyDynamic = () => { + const qc = useQueryClient() + return useMutation({ + mutationFn: ({ + objId, + body, + }: { + objId: number + body: { + category: string + action_type: string + params?: Record + label: string + is_active?: boolean + } + }) => + api + .post(`/api/v1/objects/${objId}/snapshot-policies`, body) + .then((r) => r.data), + onSuccess: () => { + qc.invalidateQueries({ queryKey: ['snapshot-policies'] }) + qc.invalidateQueries({ queryKey: ['snapshot-dashboard'] }) + }, + }) +} diff --git a/frontend/src/pages/SnapshotDashboard.tsx b/frontend/src/pages/SnapshotDashboard.tsx index 23059fd..013777a 100644 --- a/frontend/src/pages/SnapshotDashboard.tsx +++ b/frontend/src/pages/SnapshotDashboard.tsx @@ -26,13 +26,14 @@ import 'dayjs/locale/ru' import { useMemo, useState } from 'react' import { useSnapshotDashboard, - useCreateSnapshotPolicy, + useCreateSnapshotPolicyDynamic, useUpdateSnapshotPolicy, useDeleteSnapshotPolicy, useCollectPolicy, type ObjectSnapshotSummary, type PolicySnapshotStatus, } from '../api/snapshotPolicies' +import { useObjects } from '../api/objects' dayjs.extend(relativeTime) dayjs.locale('ru') @@ -57,6 +58,7 @@ const ACTION_OPTIONS = [ ] interface PolicyFormValues { + object_id?: number label: string category: string action_type: string @@ -65,6 +67,7 @@ interface PolicyFormValues { export function SnapshotDashboardPage() { const { data: dashboard, isLoading } = useSnapshotDashboard() + const { data: allObjects } = useObjects() const [searchText, setSearchText] = useState('') const [modalOpen, setModalOpen] = useState(false) const [editTarget, setEditTarget] = useState<{ objId: number; policy: PolicySnapshotStatus } | null>(null) @@ -98,10 +101,14 @@ export function SnapshotDashboardPage() { return sorted }, [filtered]) - const openCreate = (objId: number) => { + const openCreate = (objId?: number) => { form.resetFields() setEditTarget(null) - setTargetObjId(objId) + if (objId) { + setTargetObjId(objId) + } else { + setTargetObjId(null) + } setModalOpen(true) } @@ -120,7 +127,11 @@ export function SnapshotDashboardPage() { const handleSubmit = async () => { const values = await form.validateFields() - const objId = targetObjId! + const objId = targetObjId ?? values.object_id + if (!objId) { + message.error('Выберите объект') + return + } const params: Record = {} if (values.action_type === 'get_file' && values.path) { params.path = values.path @@ -137,11 +148,14 @@ export function SnapshotDashboardPage() { }) message.success('Политика обновлена') } else { - await createPolicyMutation.mutateAsync({ - label: values.label, - category: values.category, - action_type: values.action_type, - params, + await createPolicyFor.mutateAsync({ + objId, + body: { + label: values.label, + category: values.category, + action_type: values.action_type, + params, + }, }) message.success('Политика создана') } @@ -151,7 +165,7 @@ export function SnapshotDashboardPage() { } } - const createPolicyMutation = useCreateSnapshotPolicy(targetObjId ?? 0) + const createPolicyFor = useCreateSnapshotPolicyDynamic() const updatePolicyMutation = useUpdateSnapshotPolicy(targetObjId ?? 0) return ( @@ -160,20 +174,25 @@ export function SnapshotDashboardPage() { Снапшоты - setSearchText(e.target.value)} - /> + + setSearchText(e.target.value)} + /> + + {isLoading && Загрузка...} {!isLoading && filtered.length === 0 && ( - Нет объектов с политиками снапшотов. Добавьте политику через страницу объекта. + Нет объектов с политиками снапшотов. Нажмите «Добавить политику» чтобы начать. )} @@ -203,11 +222,24 @@ export function SnapshotDashboardPage() { open={modalOpen} onCancel={() => setModalOpen(false)} onOk={handleSubmit} - confirmLoading={createPolicyMutation.isPending || updatePolicyMutation.isPending} + confirmLoading={createPolicyFor.isPending || updatePolicyMutation.isPending} okText="Сохранить" cancelText="Отмена" >
+ {!targetObjId && !editTarget && ( + +