204 lines
6.0 KiB
Markdown
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.
|