import { useEffect, useState } from 'react' import { toast } from 'sonner' import { Button } from '@evobgp/ui/components/button' import { Checkbox } from '@evobgp/ui/components/checkbox' import { Input } from '@evobgp/ui/components/input' import { Label } from '@evobgp/ui/components/label' import { FormDrawer } from '@/components/form-drawer' import { LoadingButton } from '@/components/loading-button' import { CommunitySelect } from '@/components/modules/community-select' import { SelectField } from '@/components/select-field' import { dohProfileShortLabel, moduleDohProfileIds, } from '@/lib/modules/helpers' import { dohPolicyRu, moduleTypeRu } from '@/lib/ui-labels' import { useUpdateModuleMutation } from '@/queries/modules' import type { BgpCommunity, DohProfile, DohResolverPolicy, ModulePatch, ModuleRow, } from '@/types/api' interface ModuleEditDialogProps { open: boolean onOpenChange: (open: boolean) => void mod: ModuleRow communities: BgpCommunity[] dohProfiles: DohProfile[] } const DOH_POLICY_ITEMS: { value: DohResolverPolicy; label: string }[] = [ { value: 'primary_only', label: dohPolicyRu('primary_only') }, { value: 'failover', label: dohPolicyRu('failover') }, { value: 'union', label: dohPolicyRu('union') }, ] export function ModuleEditDialog({ open, onOpenChange, mod, communities, dohProfiles, }: ModuleEditDialogProps) { const updateMutation = useUpdateModuleMutation() const isDomains = mod.type === 'DOMAINS' const [name, setName] = useState('') const [enabled, setEnabled] = useState(true) const [priority, setPriority] = useState('0') const [refreshIntervalSec, setRefreshIntervalSec] = useState('') const [cronExpr, setCronExpr] = useState('') const [defaultCommunityId, setDefaultCommunityId] = useState(null) const [dohResolverPolicy, setDohResolverPolicy] = useState('primary_only') const [dohProfileIds, setDohProfileIds] = useState([]) useEffect(() => { if (!open) return setName(mod.name ?? '') setEnabled(mod.enabled !== false) setPriority(String(mod.priority ?? 0)) setRefreshIntervalSec( mod.refresh_interval_sec === null || mod.refresh_interval_sec === undefined ? '' : String(mod.refresh_interval_sec), ) setCronExpr(mod.cron_expr ?? '') setDefaultCommunityId(mod.default_community_id ?? null) setDohResolverPolicy(mod.doh_resolver_policy ?? 'primary_only') setDohProfileIds(moduleDohProfileIds(mod)) }, [mod, open]) function toggleDohProfile(id: string, checked: boolean) { setDohProfileIds((prev) => { if (checked) { if (prev.includes(id)) return prev return [...prev, id] } return prev.filter((x) => x !== id) }) } async function save() { const trimmedName = name.trim() if (!trimmedName) { toast.error('Укажите название модуля') return } const priorityNum = Number(priority) if (!Number.isFinite(priorityNum) || !Number.isInteger(priorityNum)) { toast.error('Приоритет должен быть целым числом') return } let refresh: number | null = null if (refreshIntervalSec.trim() !== '') { const n = Number(refreshIntervalSec) if (!Number.isFinite(n) || !Number.isInteger(n) || n < 0) { toast.error('Интервал обновления должен быть целым числом ≥ 0') return } refresh = n } const body: ModulePatch = { name: trimmedName, enabled, priority: priorityNum, refresh_interval_sec: refresh, cron_expr: cronExpr.trim() || null, default_community_id: defaultCommunityId, } if (isDomains) { body.doh_resolver_policy = dohResolverPolicy body.doh_profile_ids = dohProfileIds } try { await updateMutation.mutateAsync({ id: mod.id, body }) onOpenChange(false) } catch { // toast in mutation } } return ( void save()}> Сохранить } >
setName(e.target.value)} placeholder="Имя модуля" />

Выключенный модуль не участвует в обновлении и применении.

setEnabled(v === true)} />
setPriority(e.target.value)} />
setRefreshIntervalSec(e.target.value)} />
setCronExpr(e.target.value)} />
{isDomains ? ( <> setDohResolverPolicy(v as DohResolverPolicy)} />
{dohProfiles.length === 0 ? (

Нет профилей в справочнике

) : (
{dohProfiles.map((p) => { const checked = dohProfileIds.includes(p.id) return ( ) })}
)}
) : null}
) }