Filter the icon grid, and ask before removing a panel

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UytviPMJbXzD8P84nLvXcq
This commit is contained in:
2026-08-25 18:33:28 +02:00
co-authored by Claude Opus 5
parent 476dc6a1e9
commit 055f4d7d97
2 changed files with 56 additions and 10 deletions
@@ -27,6 +27,7 @@ import { Input } from "@/components/ui/input"
import { Separator } from "@/components/ui/separator"
import useAuth from "@/hooks/useAuth"
import useCustomToast from "@/hooks/useCustomToast"
import { cn } from "@/lib/utils"
import { handleError } from "@/utils"
/** As many characters as a device puts on the wall. */
@@ -207,6 +208,9 @@ function PanelRow({
// ponytail: a two-step button rather than a dialog, since this one already
// lives inside a dialog.
const [confirmUnpair, setConfirmUnpair] = useState(false)
// Removing the panel throws away more than unpairing does, so it asks the
// same way — the icon turns destructive and only the second press fires.
const [confirmRemove, setConfirmRemove] = useState(false)
const unpair = useUnpairPanel(panel.id)
const assigned = panel.dashboards ?? []
const typed = code.trim().toUpperCase()
@@ -247,6 +251,11 @@ function PanelRow({
const link = host ? `${host}/panel/${panel.id}` : ""
const remoteLink = remoteHost ? `${remoteHost}/panel` : ""
// The trash icon carries no text of its own, so the confirm step says what
// the next press does through the label a reader or a hover gets.
const removeLabel = confirmRemove
? `Confirm — remove ${panel.id}`
: `Remove ${panel.id}`
return (
<div className="grid gap-3" data-testid={`panel-${panel.id}`}>
@@ -264,13 +273,25 @@ function PanelRow({
{panel.id}
</span>
<Button
variant="ghost"
variant={confirmRemove ? "destructive" : "ghost"}
size="icon"
className="size-11 shrink-0 text-muted-foreground md:size-8"
aria-label={`Remove ${panel.id}`}
className={cn(
"size-11 shrink-0 md:size-8",
!confirmRemove && "text-muted-foreground",
)}
aria-label={removeLabel}
title={removeLabel}
data-testid={`remove-panel-${panel.id}`}
disabled={!canEdit}
onClick={onRemove}
onBlur={() => setConfirmRemove(false)}
onClick={() => {
if (!confirmRemove) {
setConfirmRemove(true)
return
}
setConfirmRemove(false)
onRemove()
}}
>
<Trash2 />
</Button>