feat(api, web): enhance EvoBGP community handling and UI integration
- Introduced a new function to resolve EvoBGP community IDs, allowing for better handling of legacy labels and UUIDs. - Updated `fetchEvobgpCommunity` to return both resolved community IDs and CIDRs, improving data retrieval. - Enhanced the ListsPage component to manage community IDs separately from user input, ensuring accurate configuration during list creation. - Updated documentation to reflect changes in community ID resolution and integration with the UI. This update improves the user experience by ensuring that community IDs are correctly resolved and stored, facilitating smoother interactions with the EvoBGP API.
This commit is contained in:
@@ -70,6 +70,8 @@ function ListsPage() {
|
||||
const [name, setName] = useState('')
|
||||
const [source, setSource] = useState<CreateSource>('static')
|
||||
const [extra, setExtra] = useState('')
|
||||
/** Resolved EvoBGP community UUID (Base UI Autocomplete stores label in input). */
|
||||
const [communityId, setCommunityId] = useState('')
|
||||
const [filters, setFilters] = useState<Filter[]>([])
|
||||
const [searchQuery, setSearchQuery] = useState('')
|
||||
const [activeTab, setActiveTab] = useState('all')
|
||||
@@ -90,13 +92,28 @@ function ListsPage() {
|
||||
[communitiesQ.data?.items],
|
||||
)
|
||||
|
||||
function resolveCommunityId(input: string): string {
|
||||
const q = input.trim()
|
||||
if (!q) return ''
|
||||
const hit = communityItems.find((i) => i.value === q || i.label === q)
|
||||
if (hit) return hit.value
|
||||
const raw = communitiesQ.data?.items ?? []
|
||||
const byComm = raw.find(
|
||||
(c) =>
|
||||
c.id === q ||
|
||||
c.community === q ||
|
||||
(c.title ? `${c.community} · ${c.title}` === q : false),
|
||||
)
|
||||
return byComm?.id ?? q
|
||||
}
|
||||
|
||||
const create = useMutation({
|
||||
mutationFn: async () => {
|
||||
const config: Record<string, unknown> = {}
|
||||
if (source === 'json_url') {
|
||||
config.url = extra.trim()
|
||||
} else if (source === 'evobgp_community') {
|
||||
config.community_id = extra.trim()
|
||||
config.community_id = communityId || resolveCommunityId(extra)
|
||||
}
|
||||
return apiFetch<{ id: string }>('/api/v1/lists', {
|
||||
method: 'POST',
|
||||
@@ -107,6 +124,7 @@ function ListsPage() {
|
||||
toast.success('Список создан')
|
||||
setName('')
|
||||
setExtra('')
|
||||
setCommunityId('')
|
||||
setSource('static')
|
||||
setCreateOpen(false)
|
||||
void qc.invalidateQueries({ queryKey: ['lists'] })
|
||||
@@ -157,7 +175,10 @@ function ListsPage() {
|
||||
|
||||
const canCreate =
|
||||
Boolean(name.trim()) &&
|
||||
(source === 'static' || Boolean(extra.trim()))
|
||||
(source === 'static' ||
|
||||
(source === 'json_url' && Boolean(extra.trim())) ||
|
||||
(source === 'evobgp_community' &&
|
||||
Boolean(communityId || resolveCommunityId(extra))))
|
||||
|
||||
return (
|
||||
<PageShell>
|
||||
@@ -260,7 +281,10 @@ function ListsPage() {
|
||||
items={[...CREATE_SOURCE_ITEMS]}
|
||||
value={source}
|
||||
onValueChange={(v) => {
|
||||
if (v) setSource(v as CreateSource)
|
||||
if (!v) return
|
||||
setSource(v as CreateSource)
|
||||
setExtra('')
|
||||
setCommunityId('')
|
||||
}}
|
||||
>
|
||||
<SelectTrigger className="w-full">
|
||||
@@ -298,7 +322,16 @@ function ListsPage() {
|
||||
<Autocomplete
|
||||
items={communityItems}
|
||||
value={extra}
|
||||
onValueChange={setExtra}
|
||||
onValueChange={(v) => {
|
||||
setExtra(v)
|
||||
// Base UI {value,label}: input stores label by default —
|
||||
// keep UUID separately for config.community_id.
|
||||
// Preview: https://reui.io/preview/base/components/c-autocomplete-9
|
||||
// Docs: https://reui.io/docs/components/base/autocomplete
|
||||
// Base UI: https://base-ui.com/react/components/autocomplete
|
||||
setCommunityId(resolveCommunityId(v))
|
||||
}}
|
||||
itemToStringValue={(item) => item.label}
|
||||
>
|
||||
<AutocompleteInput
|
||||
placeholder={
|
||||
|
||||
Reference in New Issue
Block a user