import { AlertCircle, ExternalLink } from "lucide-react"; import { ReactNode, useCallback, useEffect, useState } from "react"; import { FlowNodeData } from "@/components/flow/types"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from "@/components/ui/alert-dialog"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog"; interface NodeEditDialogProps { open: boolean; onOpenChange: (open: boolean) => void; nodeData: FlowNodeData; title: string; children: ReactNode; onSave?: () => void; error?: string | null; isDirty?: boolean; documentationUrl?: string; } export const NodeEditDialog = ({ open, onOpenChange, nodeData, title, children, onSave, error, isDirty = false, documentationUrl, }: NodeEditDialogProps) => { const [showDiscardAlert, setShowDiscardAlert] = useState(false); const handleClose = () => onOpenChange(false); const handleSave = useCallback(() => { if (onSave) { onSave(); } }, [onSave]); // Intercept dialog close attempts when dirty const handleOpenChange = useCallback((newOpen: boolean) => { // If trying to close and form is dirty, show confirmation if (!newOpen && isDirty) { setShowDiscardAlert(true); return; } onOpenChange(newOpen); }, [isDirty, onOpenChange]); // Handle confirmed discard const handleConfirmDiscard = useCallback(() => { setShowDiscardAlert(false); onOpenChange(false); }, [onOpenChange]); // Handle Cmd+S / Ctrl+S keyboard shortcut to save useEffect(() => { if (!open) return; const handleKeyDown = (e: KeyboardEvent) => { if ((e.metaKey || e.ctrlKey) && e.key === 's') { e.preventDefault(); e.stopImmediatePropagation(); handleSave(); } }; window.addEventListener('keydown', handleKeyDown, true); return () => window.removeEventListener('keydown', handleKeyDown, true); }, [open, handleSave]); return (
{title} {documentationUrl && ( Docs )}
Configure the settings for this node in your workflow. {nodeData.invalid && nodeData.validationMessage && (
{nodeData.validationMessage}
)}
{children}
{error && (
{error}
)}
{/* Discard changes confirmation dialog */} Discard changes? You have unsaved changes. Are you sure you want to discard them? Keep Editing Discard
); };