diff --git a/src/App.jsx b/src/App.jsx index 7bdebf66..a17d5aa6 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -81,10 +81,10 @@ const DnDFlow = () => { // Global variables state const [globalVariables, setGlobalVariables] = useState([]); const [events, setEvents] = useState([]); - + // Python code editor state const [pythonCode, setPythonCode] = useState("# Define your Python variables and functions here\n# Example:\n# my_variable = 42\n# def my_function(x):\n# return x * 2\n"); - + const [defaultValues, setDefaultValues] = useState({}); const [isEditingLabel, setIsEditingLabel] = useState(false); const [tempLabel, setTempLabel] = useState(''); @@ -144,34 +144,77 @@ const DnDFlow = () => { } }; + // Function to preload all documentation at startup + const preloadAllDocumentation = async () => { + const availableTypes = Object.keys(nodeTypes); + + try { + // Convert types array to a string (or could be sent as JSON array) + const response = await fetch(getApiEndpoint(`/get-all-docs`)); + + if (response.ok) { + const allDocs = await response.json(); + setNodeDocumentation(allDocs); + } else { + console.error('Failed to preload documentation'); + // Fallback: initialize empty documentation for all types + const documentationCache = {}; + availableTypes.forEach(nodeType => { + documentationCache[nodeType] = { + html: '
No documentation available for this node type.
', + text: 'No documentation available for this node type.' + }; + }); + setNodeDocumentation(documentationCache); + } + } catch (error) { + console.error('Error preloading documentation:', error); + // Fallback: initialize empty documentation for all types + const documentationCache = {}; + availableTypes.forEach(nodeType => { + documentationCache[nodeType] = { + html: 'Error loading documentation.
', + text: 'Error loading documentation.' + }; + }); + setNodeDocumentation(documentationCache); + } + }; + // Function to preload all default values at startup const preloadDefaultValues = async () => { const availableTypes = Object.keys(nodeTypes); - const promises = availableTypes.map(async (nodeType) => { - try { - const response = await fetch(getApiEndpoint(`/default-values/${nodeType}`)); - if (response.ok) { - const defaults = await response.json(); - return { nodeType, defaults }; - } - } catch (error) { - console.warn(`Failed to preload defaults for ${nodeType}:`, error); - } - return { nodeType, defaults: {} }; - }); - const results = await Promise.all(promises); - const defaultValuesCache = {}; - results.forEach(({ nodeType, defaults }) => { - defaultValuesCache[nodeType] = defaults; - }); + try { + const response = await fetch(getApiEndpoint(`/default-values-all`)); - setDefaultValues(defaultValuesCache); + if (response.ok) { + const allDefaults = await response.json(); + setDefaultValues(allDefaults); + } else { + console.error('Failed to preload default values'); + // Fallback: initialize empty defaults for all types + const defaultValuesCache = {}; + availableTypes.forEach(nodeType => { + defaultValuesCache[nodeType] = {}; + }); + setDefaultValues(defaultValuesCache); + } + } catch (error) { + console.error('Error preloading default values:', error); + // Fallback: initialize empty defaults for all types + const defaultValuesCache = {}; + availableTypes.forEach(nodeType => { + defaultValuesCache[nodeType] = {}; + }); + setDefaultValues(defaultValuesCache); + } }; - // Preload all default values when component mounts + // Preload all default values and documentation when component mounts useEffect(() => { preloadDefaultValues(); + preloadAllDocumentation(); }, []); const onDrop = useCallback( @@ -308,12 +351,12 @@ const DnDFlow = () => { } // Load the graph data - const { - nodes: loadedNodes, - edges: loadedEdges, - nodeCounter: loadedNodeCounter, - solverParams: loadedSolverParams, - globalVariables: loadedGlobalVariables, + const { + nodes: loadedNodes, + edges: loadedEdges, + nodeCounter: loadedNodeCounter, + solverParams: loadedSolverParams, + globalVariables: loadedGlobalVariables, events: loadedEvents, pythonCode: loadedPythonCode } = graphData; @@ -369,12 +412,12 @@ const DnDFlow = () => { return; } - const { - nodes: loadedNodes, - edges: loadedEdges, - nodeCounter: loadedNodeCounter, - solverParams: loadedSolverParams, - globalVariables: loadedGlobalVariables, + const { + nodes: loadedNodes, + edges: loadedEdges, + nodeCounter: loadedNodeCounter, + solverParams: loadedSolverParams, + globalVariables: loadedGlobalVariables, events: loadedEvents, pythonCode: loadedPythonCode } = graphData; @@ -752,22 +795,31 @@ const DnDFlow = () => { const selectedType = availableTypes[choiceIndex]; const newNodeId = nodeCounter.toString(); - - // Fetch default values and documentation for this node type - const defaults = await fetchDefaultValues(selectedType); - const docs = await fetchNodeDocumentation(selectedType); - - // Store default values and documentation for this node type - setDefaultValues(prev => ({ - ...prev, - [selectedType]: defaults - })); - - setNodeDocumentation(prev => ({ - ...prev, - [selectedType]: docs - })); - + + // Get default values and documentation for this node type (should be cached from preload) + let defaults = defaultValues[selectedType] || {}; + let docs = nodeDocumentation[selectedType] || { + html: 'No documentation available for this node type.
', + text: 'No documentation available for this node type.' + }; + + // Fallback: fetch if not cached (shouldn't happen normally) + if (!defaultValues[selectedType]) { + defaults = await fetchDefaultValues(selectedType); + setDefaultValues(prev => ({ + ...prev, + [selectedType]: defaults + })); + } + + if (!nodeDocumentation[selectedType]) { + docs = await fetchNodeDocumentation(selectedType); + setNodeDocumentation(prev => ({ + ...prev, + [selectedType]: docs + })); + } + // Create node data with label and initialize all expected fields as empty strings let nodeData = { label: `${selectedType} ${newNodeId}` }; @@ -933,7 +985,7 @@ const DnDFlow = () => { document.removeEventListener('keydown', handleKeyDown); }; }, [selectedEdge, selectedNode, copiedNode, duplicateNode, setCopyFeedback]); - + return (