diff --git a/apps/web/src/components/network/network-speakers-card.tsx b/apps/web/src/components/network/network-speakers-card.tsx index 4bca06f..ac02e39 100644 --- a/apps/web/src/components/network/network-speakers-card.tsx +++ b/apps/web/src/components/network/network-speakers-card.tsx @@ -1,8 +1,10 @@ import { useMemo, useState } from 'react' -import { Plus, SearchIcon, TagIcon } from 'lucide-react' +import type { ColumnDef } from '@tanstack/react-table' +import { Plus, SearchIcon, TagIcon, Trash2 } from 'lucide-react' import { Button } from '@evobgp/ui/components/button' +import { ConfirmDialog } from '@/components/confirm-dialog' import { SpeakerFormDialog } from '@/components/network/speaker-form-dialog' import { getSpeakerFilterFieldValue, @@ -15,6 +17,7 @@ import { type FilterFieldConfig, } from '@/components/reui/filters' import { ResourcePage, renderSingleSelectedLabel } from '@/components/reui-kit' +import { useDeleteSpeakerMutation } from '@/queries/network' import type { SpeakerRow } from '@/types/api' /** @@ -22,6 +25,10 @@ import type { SpeakerRow } from '@/types/api' * @see https://reui.io/preview/base/data-grid-filtering-2 */ +function speakerDeleteLabel(s: SpeakerRow): string { + return s.agent_domain ?? s.endpoint ?? s.id +} + const SPEAKER_TABS = [ { id: 'all', label: 'Все' }, { id: 'online', label: 'Online' }, @@ -75,7 +82,9 @@ export function NetworkSpeakersCard({ error, onRetry, }: NetworkSpeakersCardProps) { + const deleteMutation = useDeleteSpeakerMutation() const [dialogOpen, setDialogOpen] = useState(false) + const [deleteTarget, setDeleteTarget] = useState(null) const [filters, setFilters] = useState(createDefaultSpeakerFilters) const addButton = useMemo( @@ -88,6 +97,33 @@ export function NetworkSpeakersCard({ [], ) + const columns = useMemo[]>( + () => [ + ...speakerColumns, + { + id: 'actions', + enableSorting: false, + header: () => Действия, + cell: ({ row }) => ( +
+ +
+ ), + }, + ], + [], + ) + return ( <> setFilters(createDefaultSpeakerFilters())} getFilterFieldValue={getSpeakerFilterFieldValue} - columns={speakerColumns} + columns={columns} data={items} getRowId={(row) => row.id} isLoading={isLoading} @@ -116,6 +152,27 @@ export function NetworkSpeakersCard({ /> + + { + if (!open) setDeleteTarget(null) + }} + title="Удалить спикера?" + description={ + deleteTarget + ? `${speakerDeleteLabel(deleteTarget)} будет удалён. Привязки пиров к этому спикеру сбросятся.` + : undefined + } + confirmLabel="Удалить" + confirmLoadingLabel="Удаление…" + destructive + confirmLoading={deleteMutation.isPending} + onConfirm={() => { + if (!deleteTarget) return + void deleteMutation.mutateAsync(deleteTarget.id).then(() => setDeleteTarget(null)) + }} + /> ) }