import { useEffect, useState } from 'react' import { toast } from 'sonner' import { Button } from '@evobgp/ui/components/button' import { Checkbox } from '@evobgp/ui/components/checkbox' import { Field, FieldDescription, FieldLabel } from '@evobgp/ui/components/field' import { Input } from '@evobgp/ui/components/input' 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 } from '@/lib/modules/helpers' import { dohPolicyRu, moduleTypeRu } from '@/lib/ui-labels' import { useCreateModuleMutation } from '@/queries/modules' import type { BgpCommunity, DohProfile, DohResolverPolicy, ModuleCreate, ModuleRow, ModuleType, } from '@/types/api' interface ModuleCreateDialogProps { open: boolean onOpenChange: (open: boolean) => void communities: BgpCommunity[] dohProfiles: DohProfile[] onCreated?: (mod: ModuleRow) => void } /** @see https://reui.io/preview/base/form-7 */ /** @see https://reui.io/preview/base/sheet-8 */ const MODULE_TYPE_ITEMS: { value: ModuleType; label: string }[] = [ { value: 'IP_RANGES', label: moduleTypeRu('IP_RANGES') }, { value: 'AS_PREFIXES', label: moduleTypeRu('AS_PREFIXES') }, { value: 'CDN_CIDRS', label: moduleTypeRu('CDN_CIDRS') }, { value: 'DOMAINS', label: moduleTypeRu('DOMAINS') }, ] 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 ModuleCreateDialog({ open, onOpenChange, communities, dohProfiles, onCreated, }: ModuleCreateDialogProps) { const createMutation = useCreateModuleMutation() const [type, setType] = useState('IP_RANGES') 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([]) const isDomains = type === 'DOMAINS' useEffect(() => { if (!open) return setType('IP_RANGES') setName('') setEnabled(true) setPriority('0') setRefreshIntervalSec('') setCronExpr('') setDefaultCommunityId(null) setDohResolverPolicy('primary_only') setDohProfileIds([]) }, [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 | undefined if (refreshIntervalSec.trim() !== '') { const n = Number(refreshIntervalSec) if (!Number.isFinite(n) || !Number.isInteger(n) || n < 0) { toast.error('Интервал обновления должен быть целым числом ≥ 0') return } refresh = n } const body: ModuleCreate = { type, name: trimmedName, enabled, priority: priorityNum, } if (refresh !== undefined) { body.refresh_interval_sec = refresh } const cron = cronExpr.trim() if (cron) { body.cron_expr = cron } if (defaultCommunityId) { body.default_community_id = defaultCommunityId } if (isDomains) { body.doh_resolver_policy = dohResolverPolicy body.doh_profile_ids = dohProfileIds } try { const created = await createMutation.mutateAsync(body) onOpenChange(false) onCreated?.(created) } catch { // toast in mutation } } return ( void save()}> Создать } > { if (v) setType(v) }} /> Название setName(e.target.value)} placeholder="Имя модуля" />
Включён Выключенный модуль не участвует в обновлении и применении.
setEnabled(v === true)} />
Приоритет setPriority(e.target.value)} /> Интервал обновления (сек) setRefreshIntervalSec(e.target.value)} /> Cron (опционально) setCronExpr(e.target.value)} /> {isDomains ? ( <> { if (v) setDohResolverPolicy(v) }} /> DoH профили {dohProfiles.length === 0 ? (

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

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