фикс фикс

This commit is contained in:
dv 2026-05-27 18:08:28 +03:00
parent 5d1c409739
commit 599fe566b8
2 changed files with 77 additions and 19 deletions

View file

@ -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<string, unknown>
label: string
is_active?: boolean
}
}) =>
api
.post<SnapshotPolicy>(`/api/v1/objects/${objId}/snapshot-policies`, body)
.then((r) => r.data),
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['snapshot-policies'] })
qc.invalidateQueries({ queryKey: ['snapshot-dashboard'] })
},
})
}

View file

@ -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)
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<string, unknown> = {}
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({
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,6 +174,7 @@ export function SnapshotDashboardPage() {
<Typography.Title level={4} style={{ margin: 0 }}>
Снапшоты
</Typography.Title>
<Space>
<Input.Search
placeholder="Поиск по объекту, городу..."
allowClear
@ -167,13 +182,17 @@ export function SnapshotDashboardPage() {
value={searchText}
onChange={(e) => setSearchText(e.target.value)}
/>
<Button type="primary" icon={<PlusOutlined />} onClick={() => openCreate()}>
Добавить политику
</Button>
</Space>
</div>
{isLoading && <Typography.Text type="secondary">Загрузка...</Typography.Text>}
{!isLoading && filtered.length === 0 && (
<Typography.Text type="secondary">
Нет объектов с политиками снапшотов. Добавьте политику через страницу объекта.
Нет объектов с политиками снапшотов. Нажмите «Добавить политику» чтобы начать.
</Typography.Text>
)}
@ -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="Отмена"
>
<Form form={form} layout="vertical">
{!targetObjId && !editTarget && (
<Form.Item name="object_id" label="Объект" rules={[{ required: true, message: 'Выберите объект' }]}>
<Select
showSearch
placeholder="Выберите объект"
optionFilterProp="label"
options={(allObjects ?? []).map((o) => ({
value: o.id,
label: `${o.name}${o.city ? ` (${o.city})` : ''}`,
}))}
/>
</Form.Item>
)}
<Form.Item name="label" label="Название" rules={[{ required: true, message: 'Введите название' }]}>
<Input placeholder="CAPS config" />
</Form.Item>