CI / changes (push) Successful in 11s
CI / commitlint (push) Has been skipped
CI / openapi (push) Has been skipped
CI / web (push) Successful in 1m3s
CI / go (push) Has been skipped
CI / bird2 (push) Has been skipped
CI / release (push) Successful in 4m4s
Updated the ModuleDetailComponent to include new queries for communities and DoH profiles, improving data handling. Added a module type alert function for better user guidance and refined the UI to display module type in a more user-friendly manner. Removed unused components and streamlined the refresh functionality for better performance.
109 lines
3.2 KiB
TypeScript
109 lines
3.2 KiB
TypeScript
import { useEffect, useState } from 'react'
|
|
import { toast } from 'sonner'
|
|
|
|
import {
|
|
Dialog,
|
|
DialogContent,
|
|
DialogFooter,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
} from '@evobgp/ui/components/dialog'
|
|
import { Input } from '@evobgp/ui/components/input'
|
|
import { Label } from '@evobgp/ui/components/label'
|
|
|
|
import { LoadingButton } from '@/components/loading-button'
|
|
import { CommunitySelect } from '@/components/modules/community-select'
|
|
import { ApiError, apiMutate } from '@/lib/api-client'
|
|
import type { BgpCommunity, DomainEntry, DomainEntryCreate } from '@/types/api'
|
|
|
|
interface ModuleDomainEntryDialogProps {
|
|
open: boolean
|
|
moduleId: string
|
|
edit: DomainEntry | null
|
|
communities: BgpCommunity[]
|
|
onOpenChange: (open: boolean) => void
|
|
onSaved: () => void | Promise<void>
|
|
}
|
|
|
|
export function ModuleDomainEntryDialog({
|
|
open,
|
|
moduleId,
|
|
edit,
|
|
communities,
|
|
onOpenChange,
|
|
onSaved,
|
|
}: ModuleDomainEntryDialogProps) {
|
|
const [saving, setSaving] = useState(false)
|
|
const [form, setForm] = useState<DomainEntryCreate>({ fqdn: '', community_id: null })
|
|
|
|
useEffect(() => {
|
|
if (!open) return
|
|
setForm(
|
|
edit
|
|
? { fqdn: edit.fqdn, community_id: edit.community_id }
|
|
: { fqdn: '', community_id: null },
|
|
)
|
|
}, [open, edit])
|
|
|
|
async function save() {
|
|
if (!form.fqdn.trim()) {
|
|
toast.error('Укажите FQDN')
|
|
return
|
|
}
|
|
setSaving(true)
|
|
try {
|
|
const body = { fqdn: form.fqdn.trim(), community_id: form.community_id }
|
|
if (edit) {
|
|
await apiMutate(`/v1/modules/${moduleId}/domain-entries/${edit.id}`, 'PATCH', body)
|
|
toast.success('Домен обновлён')
|
|
} else {
|
|
await apiMutate(`/v1/modules/${moduleId}/domain-entries`, 'POST', body)
|
|
toast.success('Домен добавлен')
|
|
}
|
|
onOpenChange(false)
|
|
await onSaved()
|
|
} catch (e) {
|
|
toast.error(e instanceof ApiError ? e.message : String(e))
|
|
} finally {
|
|
setSaving(false)
|
|
}
|
|
}
|
|
|
|
return (
|
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
<DialogContent className="sm:max-w-sm">
|
|
<DialogHeader>
|
|
<DialogTitle>{edit ? 'Редактировать домен' : 'Новый домен'}</DialogTitle>
|
|
</DialogHeader>
|
|
<div className="space-y-4 py-2">
|
|
<div className="flex flex-col gap-1.5">
|
|
<Label htmlFor="dom-fqdn">FQDN</Label>
|
|
<Input
|
|
id="dom-fqdn"
|
|
placeholder="example.com"
|
|
value={form.fqdn}
|
|
onChange={(e) => setForm((s) => ({ ...s, fqdn: e.target.value }))}
|
|
/>
|
|
</div>
|
|
<CommunitySelect
|
|
id="dom-comm"
|
|
label="Community"
|
|
value={form.community_id ?? null}
|
|
onValueChange={(v) => setForm((s) => ({ ...s, community_id: v }))}
|
|
communities={communities}
|
|
nullable
|
|
/>
|
|
</div>
|
|
<DialogFooter>
|
|
<LoadingButton variant="outline" onClick={() => onOpenChange(false)}>
|
|
Отмена
|
|
</LoadingButton>
|
|
<LoadingButton loading={saving} onClick={() => void save()}>
|
|
{edit ? 'Сохранить' : 'Добавить'}
|
|
</LoadingButton>
|
|
</DialogFooter>
|
|
</DialogContent>
|
|
</Dialog>
|
|
)
|
|
}
|