From f47438a5a5e39e5a82b1c86b62797e5fdb0f5165 Mon Sep 17 00:00:00 2001 From: Jason Staack Date: Sun, 22 Mar 2026 08:21:51 -0500 Subject: [PATCH] feat(ui): add delete button to fleet table rows Trash icon appears on row hover. Confirms before deleting. Both virtual and non-virtual row renderers have group/row class for the hover-to-show pattern. Co-Authored-By: Claude Opus 4.6 (1M context) --- frontend/src/components/fleet/FleetTable.tsx | 30 ++++++++++++++++++-- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/fleet/FleetTable.tsx b/frontend/src/components/fleet/FleetTable.tsx index 5937fcb..17394c6 100644 --- a/frontend/src/components/fleet/FleetTable.tsx +++ b/frontend/src/components/fleet/FleetTable.tsx @@ -2,7 +2,7 @@ import { useRef, useState, useCallback } from 'react' import { Link, useNavigate } from '@tanstack/react-router' import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query' import { useVirtualizer } from '@tanstack/react-virtual' -import { ChevronUp, ChevronDown, ChevronsUpDown, Monitor, MapPin, Router, Network } from 'lucide-react' +import { ChevronUp, ChevronDown, ChevronsUpDown, Monitor, MapPin, Router, Network, Trash2 } from 'lucide-react' import { devicesApi, sitesApi, type DeviceResponse } from '@/lib/api' import { Badge } from '@/components/ui/badge' import { useShortcut } from '@/hooks/useShortcut' @@ -165,6 +165,20 @@ export function FleetTable({ }, }) + const deleteMutation = useMutation({ + mutationFn: (deviceId: string) => devicesApi.delete(tenantId, deviceId), + onSuccess: () => { + void queryClient.invalidateQueries({ queryKey: ['devices'] }) + }, + }) + + function handleDeleteDevice(e: React.MouseEvent, deviceId: string, hostname: string) { + e.stopPropagation() + if (confirm(`Delete ${hostname}? This cannot be undone.`)) { + deleteMutation.mutate(deviceId) + } + } + const { data, isLoading, isFetching } = useQuery({ queryKey: ['devices', tenantId, { search, status, deviceType, sortBy, sortDir, page, pageSize }], queryFn: () => @@ -322,6 +336,15 @@ export function FleetTable({ ))} + + + ) } @@ -348,6 +371,7 @@ export function FleetTable({ Tags + Actions ) @@ -417,7 +441,7 @@ export function FleetTable({ data-index={virtualRow.index} ref={virtualizer.measureElement} className={cn( - 'border-b border-border/50 hover:bg-elevated/30 transition-[background-color] duration-[50ms]', + 'border-b border-border/50 hover:bg-elevated/30 transition-[background-color] duration-[50ms] group/row', selectedIndex === virtualRow.index && 'bg-elevated/50', )} style={{ @@ -475,7 +499,7 @@ export function FleetTable({ key={device.id} data-testid={`device-row-${device.hostname}`} className={cn( - 'border-b border-border/50 hover:bg-elevated/30 transition-[background-color] duration-[50ms]', + 'border-b border-border/50 hover:bg-elevated/30 transition-[background-color] duration-[50ms] group/row', selectedIndex === idx && 'bg-elevated/50', )} >