diff --git a/frontend/src/components/modals/NodeModal.tsx b/frontend/src/components/modals/NodeModal.tsx index 5ed1070..0895f77 100644 --- a/frontend/src/components/modals/NodeModal.tsx +++ b/frontend/src/components/modals/NodeModal.tsx @@ -1,4 +1,4 @@ -import { createElement, useState } from 'react' +import { createElement, useEffect, useState } from 'react' import { RotateCcw, ChevronDown } from 'lucide-react' import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog' import { Button } from '@/components/ui/button' @@ -42,14 +42,20 @@ interface NodeModalProps { const CHILD_TYPES: NodeType[] = ['vm', 'lxc'] -// NodeModal is always mounted with a key that changes on open/edit, so useState -// initial value is enough — no need for a reset effect. export function NodeModal({ open, onClose, onSubmit, initial, title = 'Add Node', proxmoxNodes = [] }: NodeModalProps) { const [form, setForm] = useState>({ ...DEFAULT_DATA, ...initial }) const [iconSearch, setIconSearch] = useState('') const [iconPickerOpen, setIconPickerOpen] = useState(false) const [labelError, setLabelError] = useState(false) + useEffect(() => { + if (!open) return + setForm({ ...DEFAULT_DATA, ...initial }) + setIconSearch('') + setIconPickerOpen(false) + setLabelError(false) + }, [open, initial]) + const set = (key: keyof NodeData, value: unknown) => setForm((f) => ({ ...f, [key]: value })) diff --git a/frontend/src/components/modals/__tests__/NodeModal.test.tsx b/frontend/src/components/modals/__tests__/NodeModal.test.tsx index ffc0c2b..ffe9b2c 100644 --- a/frontend/src/components/modals/__tests__/NodeModal.test.tsx +++ b/frontend/src/components/modals/__tests__/NodeModal.test.tsx @@ -130,6 +130,21 @@ describe('NodeModal', () => { expect(data.notes).toBe('rack A') }) + it('resets form values when reopened in Add mode', () => { + const onClose = vi.fn() + const onSubmit = vi.fn() + + const { rerender } = render() + fireEvent.change(screen.getByPlaceholderText('My Server'), { target: { value: 'Temp Node' } }) + fireEvent.change(screen.getByPlaceholderText('server.lan'), { target: { value: 'temp.local' } }) + + rerender() + rerender() + + expect((screen.getByPlaceholderText('My Server') as HTMLInputElement).value).toBe('') + expect((screen.getByPlaceholderText('server.lan') as HTMLInputElement).value).toBe('') + }) + it('submits check_target', () => { const { onSubmit } = renderModal({ initial: BASE }) fireEvent.change(screen.getByPlaceholderText('http://...'), { target: { value: 'http://192.168.1.10:8080' } })