PluginProbe
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services / 8.7.9
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services v8.7.9
8.7.9 8.7.8 8.7.7 8.7.6 8.7.5 8.7.4 8.7.3 8.7.2 8.7.1 8.7.0 8.6.9 8.6.8 8.6.7 8.6.6 8.6.5 8.6.4 8.6.2 8.6.1 8.6.0 8.5.9 8.5.8 8.5.7 8.5.6 8.5.5 8.5.4 All 535 releases
chatbot / addons / automator / src / components / Creator.jsx

Creator.jsx in WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services 8.7.9, at addons/automator/src/components/Creator.jsx

163 lines 4.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 "use client";
2
3 import React, { useState, useCallback, useEffect } from "react";
4 import Sidebar from "./Sidebar";
5 import Header from "./Header";
6 import { WorkflowCanvas } from "./WorkflowCanvas";
7 import NodeConfigModal from "./NodeConfigModal";
8 import LogsModal from "./LogsModal";
9
10 const Creator = ({ workflow, onBack }) => {
11 const [scale, setScale] = useState(1);
12 const [nodes, setNodes] = useState([]);
13 const [connections, setConnections] = useState([]);
14 const [workflowId, setWorkflowId] = useState(workflow ? workflow.id : null);
15 const [workflowName, setWorkflowName] = useState(workflow ? workflow.name : 'New Workflow');
16 const [selectedNodeId, setSelectedNodeId] = useState(null);
17 const [showLogs, setShowLogs] = useState(false);
18
19 // Load existing workflow data
20 useEffect(() => {
21 if (workflow && workflow.workflow_data) {
22 setNodes(workflow.workflow_data.nodes || []);
23 setConnections(workflow.workflow_data.connections || []);
24 }
25 }, [workflow]);
26
27 const handleZoomIn = () => {
28 setScale((prev) => Math.min(prev + 0.1, 2));
29 };
30
31 const handleZoomOut = () => {
32 setScale((prev) => Math.max(prev - 0.1, 0.5));
33 };
34
35 const handleAddRouter = useCallback(() => {
36 const newRouter = {
37 id: `router-${Date.now()}`,
38 type: "router",
39 title: "Router",
40 subtitle: "Branch workflow",
41 position: { x: 300, y: 200 },
42 icon: "🔀",
43 iconBg: "bg-slate-500",
44 actionNumber: nodes.length + 1,
45 };
46 setNodes((prev) => [...prev, newRouter]);
47 }, [nodes.length]);
48
49 const handleAddNode = useCallback((app) => {
50 // Determine node type based on existing nodes and app metadata
51 let nodeType = "action";
52 if (app.isTrigger) {
53 nodeType = "trigger";
54 } else if (app.id.startsWith('t')) {
55 nodeType = "action";
56 } else if (!nodes.some(n => n.type === 'trigger')) {
57 // If no trigger exists yet and this isn't explicitly a tool,
58 // check if it's the very first node.
59 nodeType = "trigger";
60 }
61
62 const newNode = {
63 id: `node-${Date.now()}`,
64 type: nodeType,
65 title: app.name,
66 subtitle: "Configure action",
67 position: { x: 300, y: 200 }, // Default position when clicking from sidebar
68 icon: app.icon,
69 iconBg: app.iconBg,
70 actionNumber: nodes.length + 1,
71 appData: app,
72 };
73
74 setNodes((prev) => [...prev, newNode]);
75 }, [nodes]);
76
77 const onSave = useCallback(async () => {
78 const flowData = {
79 nodes,
80 connections
81 };
82
83 const method = workflowId ? 'PUT' : 'POST';
84 const url = workflowId
85 ? `${window.wpbotAutomator.apiUrl}/workflows/${workflowId}`
86 : `${window.wpbotAutomator.apiUrl}/workflows`;
87
88 try {
89 const response = await fetch(url, {
90 method,
91 headers: {
92 'Content-Type': 'application/json',
93 'X-WP-Nonce': window.wpbotAutomator.nonce,
94 },
95 body: JSON.stringify({
96 name: workflowName,
97 description: 'Created via builder',
98 workflow_data: flowData,
99 status: 'active'
100 }),
101 });
102
103 const result = await response.json();
104 if (result.success) {
105 if (!workflowId && result.id) {
106 setWorkflowId(result.id);
107 }
108 alert('Workflow saved successfully!');
109 } else {
110 alert('Failed to save workflow.');
111 }
112 } catch (error) {
113 console.error('Error saving workflow:', error);
114 alert('An error occurred while saving.');
115 }
116 }, [nodes, connections, workflowId, workflowName]);
117
118 return (
119 <div className="h-screen flex flex-col overflow-hidden bg-background text-foreground">
120 <Header
121 workflowName={workflowName}
122 onNameChange={setWorkflowName}
123 onBack={onBack}
124 onSave={onSave}
125 onToggleLogs={() => setShowLogs(true)}
126 />
127 <div className="flex flex-1 overflow-hidden">
128 <Sidebar
129 onZoomIn={handleZoomIn}
130 onZoomOut={handleZoomOut}
131 onAddRouter={handleAddRouter}
132 onAddNode={handleAddNode}
133 />
134 <WorkflowCanvas
135 scale={scale}
136 setScale={setScale}
137 nodes={nodes}
138 setNodes={setNodes}
139 connections={connections}
140 setConnections={setConnections}
141 selectedNodeId={selectedNodeId}
142 onNodeClick={setSelectedNodeId}
143 />
144 <NodeConfigModal
145 isOpen={!!selectedNodeId}
146 node={nodes.find(n => n.id === selectedNodeId)}
147 onClose={() => setSelectedNodeId(null)}
148 onUpdateNode={(updatedNode) => {
149 setNodes(prev => prev.map(n => n.id === updatedNode.id ? updatedNode : n));
150 }}
151 />
152 <LogsModal
153 isOpen={showLogs}
154 onClose={() => setShowLogs(false)}
155 workflowId={workflowId}
156 />
157 </div>
158 </div>
159 );
160 };
161
162 export default Creator;
163