diff --git a/e2e/nodes.spec.ts b/e2e/nodes.spec.ts index 80a1cfe6..4839b617 100644 --- a/e2e/nodes.spec.ts +++ b/e2e/nodes.spec.ts @@ -46,8 +46,8 @@ test.describe('Node management', () => { await page.locator('#node-api-url').fill('http://localhost:6379'); // api_token is required to enable the submit button; use a dummy value since we're testing URL validation await page.locator('#node-api-token').fill('dummy-token'); - // Use .last() to target the dialog submit button, not the trigger - await page.getByRole('button', { name: /add node/i }).last().click(); + // Scope to the dialog so we target the submit button, not the trigger + await page.getByRole('dialog').getByRole('button', { name: /add node/i }).click(); await expect(page.getByText(/loopback|localhost/i)).toBeVisible({ timeout: 5_000 }); }); @@ -59,7 +59,7 @@ test.describe('Node management', () => { await page.locator('#node-api-url').fill('not-a-url-at-all'); // api_token is required to enable the submit button; use a dummy value since we're testing URL validation await page.locator('#node-api-token').fill('dummy-token'); - await page.getByRole('button', { name: /add node/i }).last().click(); + await page.getByRole('dialog').getByRole('button', { name: /add node/i }).click(); await expect(page.getByText(/valid url|invalid url/i)).toBeVisible({ timeout: 5_000 }); }); diff --git a/frontend/src/components/NodeManager.tsx b/frontend/src/components/NodeManager.tsx index e3fd9577..d2344501 100644 --- a/frontend/src/components/NodeManager.tsx +++ b/frontend/src/components/NodeManager.tsx @@ -4,8 +4,7 @@ import type { Node, NodeMode } from '@/context/NodeContext'; import { apiFetch } from '@/lib/api'; import { copyToClipboard } from '@/lib/clipboard'; import { toast } from '@/components/ui/toast-store'; -import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogTrigger } from './ui/dialog'; -import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from './ui/alert-dialog'; +import { Modal, ModalHeader, ModalBody, ModalFooter, ConfirmModal } from './ui/modal'; import { Button } from './ui/button'; import { Input } from './ui/input'; import { Label } from './ui/label'; @@ -232,11 +231,12 @@ export function NodeManager() { throw new Error(err.error || 'Failed to delete node'); } toast.success(`Node "${deletingNode.name}" deleted`); - setDeleteOpen(false); - setDeletingNode(null); await refreshNodes(); } catch (error) { toast.error((error as Error).message || 'Failed to delete node'); + } finally { + setDeleteOpen(false); + setDeletingNode(null); } }; @@ -422,28 +422,40 @@ export function NodeManager() {
+ Removes {deletingNode?.name} from this console. The remote instance and its containers are not affected. +
+