[]>(
() => [
{
id: 'neighbor_id',
accessorFn: (row) => row.neighbor_id || row.neighbor,
header: ({ column }) => (
),
cell: ({ row }) => (
),
meta: { headerTitle: 'ID соседа' },
},
{
accessorKey: 'remote_asn',
header: ({ column }) => ,
cell: ({ row }) => (
{row.original.remote_asn || '—'}
),
meta: { headerTitle: 'ASN' },
},
{
accessorKey: 'session_state',
header: ({ column }) => (
),
cell: ({ row }) => (
),
meta: { headerTitle: 'Состояние' },
},
{
id: 'actions',
enableSorting: false,
header: () => Действия,
cell: ({ row }) => (
),
},
],
[],
)
function getFilterFieldValue(item: PeerDiscoveryRow, field: string): unknown {
if (field === 'neighbor') {
return `${item.neighbor_id ?? ''} ${item.neighbor}`
}
return undefined
}
async function confirmApprove() {
if (!approveTarget) return
await approveMutation.mutateAsync({
id: approveTarget.id,
body: {
name: name.trim() || undefined,
bgp_speaker_id: speakerId || null,
},
})
setApproveTarget(null)
}
return (
<>
setFilterQuery(createTextFilterQuery('neighbor'))}
getFilterFieldValue={getFilterFieldValue}
columns={columns}
data={items}
getRowId={(row) => row.id}
isLoading={isLoading}
isError={isError}
error={error instanceof Error ? error : null}
onRetry={onRetry}
pinLastColumn
emptyState={{
title: 'Нет ожидающих пиров',
description:
'Включите peer discovery в параметрах BIRD и задайте CIDR-диапазоны. Новые сессии появятся здесь.',
}}
/>
{
if (!open) setApproveTarget(null)
}}
title="Одобрить пира"
description={
approveTarget
? `ID соседа ${approveTarget.neighbor_id || '—'} · ${approveTarget.neighbor} AS${approveTarget.remote_asn ?? '?'}`
: undefined
}
className="sm:max-w-sm"
footer={
<>
void confirmApprove()}
>
Одобрить
>
}
>
setName(e.target.value)}
placeholder="client-edge-1"
/>
setSpeakerId(v || null)}
placeholder="Авто"
/>
{
if (!open) setRejectTarget(null)
}}
title="Отклонить пира?"
description={
rejectTarget
? `${rejectTarget.neighbor_id || rejectTarget.neighbor} больше не будет появляться в списке.`
: undefined
}
confirmLabel="Отклонить"
destructive
confirmLoading={rejectMutation.isPending}
onConfirm={() => {
if (!rejectTarget) return
void rejectMutation.mutateAsync(rejectTarget.id).then(() => setRejectTarget(null))
}}
/>
>
)
}