import { Button, DialogTitle, useAiCompletion } from "../../ui"; import { Dialog, DialogContent, DialogHeader } from "../../ui"; import { EditorCodeNodeInstance, EditorNodeInstance, EditorVisualNode, } from "@flyde/core"; import { ErrorBoundary } from "react-error-boundary"; import React, { useCallback, useMemo, useEffect } from "react"; import { loadConfigEditorComponent } from "./loadConfigEditorComponent"; import { usePorts } from "../../flow-editor/ports"; import { InstanceIcon } from "../instance-view/InstanceIcon"; import { HotkeyIndication } from "../../ui"; import { Loader } from "../../lib/loader"; export interface InstanceConfigEditorProps { ins: EditorCodeNodeInstance; editorNode: EditorVisualNode; onCancel: () => void; onSubmit: (value: any) => Promise; onFork: (ins: EditorNodeInstance) => void; // onSwitchToSiblingMacro: (newMacro: MacroNodeDefinition) => void; } export const InstanceConfigEditor: React.FC = ( props ) => { const { ins, onCancel, onFork } = props; const [isLoading, setIsLoading] = React.useState(false); const _onFork = useCallback(() => { onCancel(); onFork(ins); }, [onCancel, onFork, ins]); const [instanceConfig, setInstanceConfig] = React.useState( ins.config ?? {} ); const [hasUnsavedChanges, setHasUnsavedChanges] = React.useState(false); const [showUnsavedChangesDialog, setShowUnsavedChangesDialog] = React.useState(false); const handleMacroDataChange = useCallback((newData: any) => { setInstanceConfig(newData); setHasUnsavedChanges(true); }, []); const handleSubmit = useCallback(() => { if (isLoading) return; setIsLoading(true); props.onSubmit(instanceConfig) .then(() => { setHasUnsavedChanges(false); setIsLoading(false); }) .catch((error) => { console.error("Failed to save config:", error); setIsLoading(false); }); }, [props, instanceConfig, isLoading]); const handleCancel = useCallback(() => { if (isLoading) return; if (!hasUnsavedChanges) { onCancel(); return; } setShowUnsavedChangesDialog(true); }, [hasUnsavedChanges, onCancel, isLoading]); const handleCloseUnsavedChangesDialog = useCallback(() => { if (isLoading) return; setShowUnsavedChangesDialog(false); }, [isLoading]); const handleDiscardChanges = useCallback(() => { if (isLoading) return; setShowUnsavedChangesDialog(false); onCancel(); }, [onCancel, isLoading]); const EditorComp = useMemo(() => { return loadConfigEditorComponent(ins); }, [ins.node]); // Add keyboard shortcut handler useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') { e.preventDefault(); handleSubmit(); } }; window.addEventListener('keydown', handleKeyDown); return () => window.removeEventListener('keydown', handleKeyDown); }, [handleSubmit, hasUnsavedChanges]); const ports = usePorts(); const aiCompletion = useAiCompletion(); const { node } = ins; return ( <> {node.displayName ?? node.id}
{node.description && (
{node.description}
)}
Error loading config editor
} >
Need more customization?{" "} {" "}this node
{/* Unsaved Changes Dialog */} Unsaved Changes

You have unsaved changes. Are you sure you want to exit without saving?

); };