From 5b6543b167ea931ae7137eb7ec7682c17463d74b Mon Sep 17 00:00:00 2001 From: hsiegeln <37154749+hsiegeln@users.noreply.github.com> Date: Sun, 12 Apr 2026 16:43:05 +0200 Subject: [PATCH] fix: use ConfirmDialog for dismiss, move warning to top of page Replace window.confirm with design system ConfirmDialog for the dismiss action. Move the "No agents connected" section to the top of the Runtime page using Alert component with warning variant. Co-Authored-By: Claude Opus 4.6 (1M context) --- ui/src/pages/AgentHealth/AgentHealth.tsx | 81 ++++++++++++------------ 1 file changed, 42 insertions(+), 39 deletions(-) diff --git a/ui/src/pages/AgentHealth/AgentHealth.tsx b/ui/src/pages/AgentHealth/AgentHealth.tsx index ed13241a..eaa81582 100644 --- a/ui/src/pages/AgentHealth/AgentHealth.tsx +++ b/ui/src/pages/AgentHealth/AgentHealth.tsx @@ -5,6 +5,7 @@ import { StatCard, StatusDot, Badge, MonoText, GroupCard, DataTable, EventFeed, LogViewer, ButtonGroup, SectionHeader, Toggle, Select, Button, useToast, + Alert, ConfirmDialog, } from '@cameleer/design-system'; import type { Column, FeedEvent, LogEntry, ButtonGroupItem } from '@cameleer/design-system'; import styles from './AgentHealth.module.css'; @@ -111,6 +112,7 @@ export default function AgentHealth() { const dismissApp = useDismissApp(); const catalogEntry = catalogApps?.find((a) => a.slug === appId); + const [confirmDismissOpen, setConfirmDismissOpen] = useState(false); const [configEditing, setConfigEditing] = useState(false); const [configDraft, setConfigDraft] = useState>({}); @@ -292,6 +294,46 @@ export default function AgentHealth() { return (
+ {/* No agents warning + dismiss — shown when app-scoped, no agents, admin */} + {appId && agentList.length === 0 && isAdmin && ( + <> + + + {catalogEntry?.managed ? 'Managed app' : 'Discovered app'} — {(catalogEntry?.exchangeCount ?? 0).toLocaleString()} exchanges recorded. + {' '}You can dismiss this application to remove it and all associated data. + +
+ +
+
+ setConfirmDismissOpen(false)} + onConfirm={() => { + setConfirmDismissOpen(false); + dismissApp.mutate(appId, { + onSuccess: () => { + toast({ title: 'Application dismissed', description: `${appId} and all associated data have been deleted`, variant: 'success' }); + navigate('/runtime'); + }, + onError: (err) => { + toast({ title: 'Dismiss failed', description: err.message, variant: 'error', duration: 86_400_000 }); + }, + }); + }} + title="Dismiss Application" + message={`This will permanently delete "${appId}" and all associated data (${(catalogEntry?.exchangeCount ?? 0).toLocaleString()} exchanges, logs, diagrams).`} + confirmText="This action cannot be undone." + confirmLabel="Dismiss" + variant="danger" + loading={dismissApp.isPending} + /> + + )} + {/* Stat strip */}
)} - {/* Dismiss application card — shown when app-scoped, no agents, admin */} - {appId && agentList.length === 0 && isAdmin && ( -
-
-
- No agents connected - {catalogEntry && ( - - {catalogEntry.managed ? 'Managed app' : 'Discovered app'} — {catalogEntry.exchangeCount.toLocaleString()} exchanges recorded - - )} -
- -
-
- )} {/* Group cards grid */}