FlowForge/frontend/integration-guide.md

204 lines
6.0 KiB
Markdown

# FlowForge Frontend Integration Guide
This guide provides instructions for integrating the new components we've created into the existing WorkflowEditor.js file.
## Step 1: Import New Components
Add these imports at the top of your `WorkflowEditor.js` file:
```javascript
import Modal from '../components/common/Modal';
import WorkflowEditorTabs from '../components/workflow/WorkflowEditorTabs';
import WorkflowEditorActions from '../components/workflow/WorkflowEditorActions';
import NodeTester from '../components/workflow/NodeTester';
import ExecutionResults from '../components/execution/ExecutionResults';
```
## Step 2: Add New State Variables
Add these state variables inside your WorkflowEditor component:
```javascript
const [showNodeTester, setShowNodeTester] = useState(false);
const [showExecutionResults, setShowExecutionResults] = useState(false);
const [latestExecutionId, setLatestExecutionId] = useState(null);
const [currentVersion, setCurrentVersion] = useState(1);
const [showTabs, setShowTabs] = useState(true);
```
## Step 3: Add New Methods
Add these methods inside your WorkflowEditor component:
```javascript
// Duplicate a node
const handleDuplicateNode = (node) => {
const newNode = {
...node,
id: `${node.id}-copy-${Date.now()}`,
position: {
x: node.position.x + 50,
y: node.position.y + 50
}
};
setNodes((nds) => nds.concat(newNode));
};
// Delete a node
const handleDeleteNode = (node) => {
setNodes((nds) => nds.filter((n) => n.id !== node.id));
setEdges((eds) => eds.filter((e) => e.source !== node.id && e.target !== node.id));
setSelectedNode(null);
};
// Handle workflow execution
const handleExecuteWorkflow = (executionId) => {
setLatestExecutionId(executionId);
};
// Handle version restoration
const handleRestoreVersion = async (version) => {
try {
setIsLoading(true);
const response = await api.get(`/api/workflows/${id}/versions/${version}`);
const workflowData = response.data.workflow;
// Update workflow data
setWorkflow({
...workflow,
name: workflowData.name,
description: workflowData.description
});
// Convert backend nodes/connections to React Flow format
const flowNodes = workflowData.nodes.map(node => ({
id: node.id,
type: 'customNode',
position: { x: node.position_x, y: node.position_y },
data: {
label: node.name,
nodeType: node.type,
config: node.config || {}
}
}));
const flowEdges = workflowData.connections.map(conn => ({
id: conn.id,
source: conn.source_node_id,
target: conn.target_node_id,
sourceHandle: conn.source_handle,
targetHandle: conn.target_handle
}));
setNodes(flowNodes);
setEdges(flowEdges);
setCurrentVersion(version);
toast.success(`Restored workflow to version ${version}`);
} catch (error) {
console.error('Error restoring version:', error);
toast.error('Failed to restore workflow version');
} finally {
setIsLoading(false);
}
};
```
## Step 4: Update the Return Statement
Replace the existing buttons in the workflow header with the WorkflowEditorActions component:
```jsx
<div className="flex space-x-2">
<button
onClick={handleSave}
disabled={isSaving}
className="px-4 py-2 bg-primary-600 text-white rounded-md hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2 disabled:opacity-50"
>
{isSaving ? 'Saving...' : 'Save'}
</button>
<WorkflowEditorActions
workflowId={id}
selectedNode={selectedNode}
onDuplicateNode={handleDuplicateNode}
onDeleteNode={handleDeleteNode}
onExecuteWorkflow={handleExecuteWorkflow}
/>
</div>
```
## Step 5: Add the Tabs Component
Add the WorkflowEditorTabs component at the bottom of your component, just before the closing div of the main container:
```jsx
{/* Workflow Tabs */}
{id && id !== 'new' && showTabs && (
<div className="border-t border-gray-200">
<WorkflowEditorTabs
workflowId={id}
nodes={nodes}
currentVersion={currentVersion}
onRestoreVersion={handleRestoreVersion}
/>
</div>
)}
```
## Step 6: Add Toggle Button for Tabs
Add a button to toggle the tabs visibility in the workflow header:
```jsx
<button
onClick={() => setShowTabs(!showTabs)}
className="ml-2 inline-flex items-center p-1 border border-gray-300 rounded text-gray-500 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500"
>
{showTabs ? (
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
<path fillRule="evenodd" d="M5 10a1 1 0 011-1h8a1 1 0 110 2H6a1 1 0 01-1-1z" clipRule="evenodd" />
</svg>
) : (
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
<path fillRule="evenodd" d="M10 5a1 1 0 011 1v3h3a1 1 0 110 2h-3v3a1 1 0 11-2 0v-3H6a1 1 0 110-2h3V6a1 1 0 011-1z" clipRule="evenodd" />
</svg>
)}
</button>
```
## Step 7: Fetch Current Version on Load
Update the fetchData method to get the current version:
```javascript
// If editing existing workflow, fetch it
if (id && id !== 'new') {
const workflowResponse = await api.get(`/api/workflows/${id}`);
const workflowData = workflowResponse.data.workflow;
setWorkflow({
id: workflowData.id,
name: workflowData.name,
description: workflowData.description
});
// Set current version
setCurrentVersion(workflowData.version || 1);
// Rest of the existing code...
}
```
## Testing Your Integration
After making these changes, you should be able to:
1. Test individual nodes with the NodeTester component
2. View execution history in the tabs
3. Schedule workflows with the CronScheduler component
4. Manage workflow versions with the VersionHistory component
5. View and copy webhook URLs with the WebhookManager component
If you encounter any issues, check the browser console for errors and verify that all the components are properly imported and integrated.