feat(network): add delete functionality for speakers in network speakers card
Implemented a delete feature for speakers within the NetworkSpeakersCard component. This includes a confirmation dialog for deletion and integration with the delete speaker mutation. Updated the table columns to include an action button for deleting speakers, enhancing the user experience for managing network speakers.
This commit is contained in:
@@ -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<SpeakerRow | null>(null)
|
||||
const [filters, setFilters] = useState<Filter[]>(createDefaultSpeakerFilters)
|
||||
|
||||
const addButton = useMemo(
|
||||
@@ -88,6 +97,33 @@ export function NetworkSpeakersCard({
|
||||
[],
|
||||
)
|
||||
|
||||
const columns = useMemo<ColumnDef<SpeakerRow, unknown>[]>(
|
||||
() => [
|
||||
...speakerColumns,
|
||||
{
|
||||
id: 'actions',
|
||||
enableSorting: false,
|
||||
header: () => <span className="sr-only">Действия</span>,
|
||||
cell: ({ row }) => (
|
||||
<div className="flex items-center justify-end">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon-sm"
|
||||
type="button"
|
||||
className="text-destructive"
|
||||
aria-label="Удалить спикера"
|
||||
title="Удалить"
|
||||
onClick={() => setDeleteTarget(row.original)}
|
||||
>
|
||||
<Trash2 className="size-3.5" />
|
||||
</Button>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
],
|
||||
[],
|
||||
)
|
||||
|
||||
return (
|
||||
<>
|
||||
<ResourcePage
|
||||
@@ -100,7 +136,7 @@ export function NetworkSpeakersCard({
|
||||
onFiltersChange={setFilters}
|
||||
onClearFilters={() => setFilters(createDefaultSpeakerFilters())}
|
||||
getFilterFieldValue={getSpeakerFilterFieldValue}
|
||||
columns={speakerColumns}
|
||||
columns={columns}
|
||||
data={items}
|
||||
getRowId={(row) => row.id}
|
||||
isLoading={isLoading}
|
||||
@@ -116,6 +152,27 @@ export function NetworkSpeakersCard({
|
||||
/>
|
||||
|
||||
<SpeakerFormDialog open={dialogOpen} onOpenChange={setDialogOpen} />
|
||||
|
||||
<ConfirmDialog
|
||||
open={deleteTarget !== null}
|
||||
onOpenChange={(open) => {
|
||||
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))
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user