feat(web): add delete functionality to agent components
- Introduced delete functionality across multiple agent components, including AgentCard, AgentCardsGrid, AgentDetailSheet, and AgentDetailView, allowing users to remove agents directly from the UI. - Integrated a confirmation dialog to prevent accidental deletions, enhancing user experience and safety. - Updated relevant props and handlers to manage delete actions consistently across components. These changes improve the overall management of agents, providing users with the ability to easily delete agents while ensuring confirmation for critical actions.
This commit is contained in:
@@ -47,6 +47,7 @@ import {
|
||||
computeFleetCounts,
|
||||
fleetKpiCards,
|
||||
} from '@/components/agents/agents-fleet-kpis'
|
||||
import { ConfirmDialog } from '@/components/confirm-dialog'
|
||||
import { agentsQueryOptions } from '@/queries'
|
||||
import { apiFetch } from '@/lib/api'
|
||||
import { useCopyToClipboard } from '@/hooks/use-copy-to-clipboard'
|
||||
@@ -105,6 +106,7 @@ function AgentsPage() {
|
||||
const agentsQ = useQuery(agentsQueryOptions())
|
||||
const { copyToClipboard } = useCopyToClipboard()
|
||||
const [createOpen, setCreateOpen] = useState(false)
|
||||
const [deleteAgentId, setDeleteAgentId] = useState<string | null>(null)
|
||||
const [filters, setFilters] = useState<Filter[]>([])
|
||||
const [searchQuery, setSearchQuery] = useState('')
|
||||
const [activeTab, setActiveTab] = useState('all')
|
||||
@@ -155,6 +157,21 @@ function AgentsPage() {
|
||||
onError: (e: Error) => toast.error(e.message),
|
||||
})
|
||||
|
||||
const removeAgent = useMutation({
|
||||
mutationFn: (id: string) =>
|
||||
apiFetch(`/api/v1/agents/${id}`, { method: 'DELETE' }),
|
||||
onSuccess: (_data, id) => {
|
||||
toast.success('Агент удалён')
|
||||
setDeleteAgentId(null)
|
||||
if (detailAgentId === id) {
|
||||
setSearch({ agent: '' })
|
||||
}
|
||||
void qc.invalidateQueries({ queryKey: ['agents'] })
|
||||
void qc.invalidateQueries({ queryKey: ['dashboard'] })
|
||||
},
|
||||
onError: (e: Error) => toast.error(e.message),
|
||||
})
|
||||
|
||||
const items = agentsQ.data?.items ?? []
|
||||
const counts = useMemo(() => computeFleetCounts(items), [items])
|
||||
const pendingIds = useMemo(
|
||||
@@ -330,6 +347,15 @@ function AgentsPage() {
|
||||
[setSearch],
|
||||
)
|
||||
|
||||
const handleDeleteAgent = useCallback((id: string) => {
|
||||
setDeleteAgentId(id)
|
||||
}, [])
|
||||
|
||||
const deleteTargetName = useMemo(
|
||||
() => items.find((a) => a.id === deleteAgentId)?.name,
|
||||
[items, deleteAgentId],
|
||||
)
|
||||
|
||||
const handleClearFilters = useCallback(() => {
|
||||
setFilters([])
|
||||
setSearchQuery('')
|
||||
@@ -454,6 +480,7 @@ function AgentsPage() {
|
||||
onApprove={(id) => approve.mutate(id)}
|
||||
approvePending={approve.isPending}
|
||||
onCopyInstall={handleCopyInstall}
|
||||
onDelete={handleDeleteAgent}
|
||||
/>
|
||||
) : agentsQ.isError ? (
|
||||
<Alert variant="destructive">
|
||||
@@ -533,6 +560,7 @@ function AgentsPage() {
|
||||
agents={filteredItems}
|
||||
selectedId={detailOpen ? detailAgentId : null}
|
||||
onSelect={handleSelectAgent}
|
||||
onDelete={handleDeleteAgent}
|
||||
isLoading={agentsQ.isLoading}
|
||||
emptyTitle={
|
||||
items.length === 0
|
||||
@@ -559,6 +587,24 @@ function AgentsPage() {
|
||||
onOpenChange={(open) => {
|
||||
if (!open) setSearch({ agent: '' })
|
||||
}}
|
||||
onDelete={handleDeleteAgent}
|
||||
/>
|
||||
|
||||
<ConfirmDialog
|
||||
open={deleteAgentId !== null}
|
||||
onOpenChange={(open) => {
|
||||
if (!open) setDeleteAgentId(null)
|
||||
}}
|
||||
title="Удалить агента?"
|
||||
description={
|
||||
deleteTargetName
|
||||
? `Агент «${deleteTargetName}» будет удалён вместе с overrides, install-ссылками и статистикой. Это действие нельзя отменить.`
|
||||
: 'Агент будет удалён вместе с overrides, install-ссылками и статистикой. Это действие нельзя отменить.'
|
||||
}
|
||||
onConfirm={() => {
|
||||
if (deleteAgentId) removeAgent.mutate(deleteAgentId)
|
||||
}}
|
||||
disabled={removeAgent.isPending}
|
||||
/>
|
||||
</PageShell>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user