@@ -15,50 +15,21 @@ import ReactFlow, {
15
15
import 'reactflow/dist/style.css' ;
16
16
import CustomNode , { CustomNodeData } from './CustomNode' ;
17
17
import './flow.css' ;
18
- import AutoGPTServerAPI , { Block , BlockIOSchema , Graph , NodeExecutionResult , ObjectSchema } from '@/lib/autogpt-server-api' ;
19
- import { Button } from './ui/button' ;
20
- import { Input } from './ui/input' ;
21
- import { ChevronRight , ChevronLeft } from "lucide-react" ;
18
+ import AutoGPTServerAPI , { Block , BlockIOSchema , Graph , NodeExecutionResult } from '@/lib/autogpt-server-api' ;
19
+ import { Play , Undo2 , Redo2 } from "lucide-react" ;
22
20
import { deepEquals , getTypeColor , removeEmptyStringsAndNulls , setNestedProperty } from '@/lib/utils' ;
23
- import { beautifyString } from '@/lib/utils' ;
24
21
import { history } from './history' ;
25
22
import { CustomEdge , CustomEdgeData } from './CustomEdge' ;
26
23
import ConnectionLine from './ConnectionLine' ;
27
24
import Ajv from 'ajv' ;
25
+ import { Control , ControlPanel } from "@/components/edit/control/ControlPanel" ;
26
+ import { SaveControl } from "@/components/edit/control/SaveControl" ;
27
+ import { BlocksControl } from "@/components/edit/control/BlocksControl" ;
28
28
29
29
// This is for the history, this is the minimum distance a block must move before it is logged
30
30
// It helps to prevent spamming the history with small movements especially when pressing on a input in a block
31
31
const MINIMUM_MOVE_BEFORE_LOG = 50 ;
32
32
33
- const Sidebar : React . FC < { isOpen : boolean , availableNodes : Block [ ] , addNode : ( id : string , name : string ) => void } > =
34
- ( { isOpen, availableNodes, addNode } ) => {
35
- const [ searchQuery , setSearchQuery ] = useState ( '' ) ;
36
-
37
- if ( ! isOpen ) return null ;
38
-
39
- const filteredNodes = availableNodes . filter ( node =>
40
- node . name . toLowerCase ( ) . includes ( searchQuery . toLowerCase ( ) )
41
- ) ;
42
-
43
- return (
44
- < div className = { `sidebar dark-theme ${ isOpen ? 'open' : '' } ` } >
45
- < h3 > Nodes</ h3 >
46
- < Input
47
- type = "text"
48
- placeholder = "Search nodes..."
49
- value = { searchQuery }
50
- onChange = { ( e ) => setSearchQuery ( e . target . value ) }
51
- />
52
- { filteredNodes . map ( ( node ) => (
53
- < div key = { node . id } className = "sidebarNodeRowStyle dark-theme" >
54
- < span > { beautifyString ( node . name ) . replace ( / B l o c k $ / , '' ) } </ span >
55
- < Button onClick = { ( ) => addNode ( node . id , node . name ) } > Add</ Button >
56
- </ div >
57
- ) ) }
58
- </ div >
59
- ) ;
60
- } ;
61
-
62
33
const ajv = new Ajv ( { strict : false , allErrors : true } ) ;
63
34
64
35
const FlowEditor : React . FC < {
@@ -70,7 +41,6 @@ const FlowEditor: React.FC<{
70
41
const [ edges , setEdges , onEdgesChange ] = useEdgesState < CustomEdgeData > ( [ ] ) ;
71
42
const [ nodeId , setNodeId ] = useState < number > ( 1 ) ;
72
43
const [ availableNodes , setAvailableNodes ] = useState < Block [ ] > ( [ ] ) ;
73
- const [ isSidebarOpen , setIsSidebarOpen ] = useState ( true ) ;
74
44
const [ savedAgent , setSavedAgent ] = useState < Graph | null > ( null ) ;
75
45
const [ agentDescription , setAgentDescription ] = useState < string > ( '' ) ;
76
46
const [ agentName , setAgentName ] = useState < string > ( '' ) ;
@@ -665,8 +635,6 @@ const FlowEditor: React.FC<{
665
635
) ;
666
636
} ;
667
637
668
- const toggleSidebar = ( ) => setIsSidebarOpen ( ! isSidebarOpen ) ;
669
-
670
638
const handleKeyDown = useCallback ( ( event : KeyboardEvent ) => {
671
639
if ( isAnyModalOpen ) return ; // Prevent copy/paste if any modal is open
672
640
@@ -735,23 +703,26 @@ const FlowEditor: React.FC<{
735
703
clearNodesStatusAndOutput ( ) ;
736
704
} , [ clearNodesStatusAndOutput ] ) ;
737
705
706
+ const editorControls : Control [ ] = [
707
+ {
708
+ label : 'Undo' ,
709
+ icon : < Undo2 /> ,
710
+ onClick : handleUndo ,
711
+ } ,
712
+ {
713
+ label : 'Redo' ,
714
+ icon : < Redo2 /> ,
715
+ onClick : handleRedo ,
716
+ } ,
717
+ {
718
+ label : 'Run' ,
719
+ icon : < Play /> ,
720
+ onClick : runAgent ,
721
+ }
722
+ ] ;
723
+
738
724
return (
739
725
< div className = { className } >
740
- < Button
741
- variant = "outline"
742
- size = "icon"
743
- onClick = { toggleSidebar }
744
- style = { {
745
- position : 'fixed' ,
746
- left : isSidebarOpen ? '350px' : '10px' ,
747
- zIndex : 10000 ,
748
- backgroundColor : 'black' ,
749
- color : 'white' ,
750
- } }
751
- >
752
- { isSidebarOpen ? < ChevronLeft className = "h-4 w-4" /> : < ChevronRight className = "h-4 w-4" /> }
753
- </ Button >
754
- < Sidebar isOpen = { isSidebarOpen } availableNodes = { availableNodes } addNode = { addNode } />
755
726
< ReactFlow
756
727
nodes = { nodes . map ( node => ( { ...node , data : { ...node . data , setIsAnyModalOpen } } ) ) }
757
728
edges = { edges . map ( edge => ( { ...edge , data : { ...edge . data , clearNodesStatusAndOutput } } ) ) }
@@ -767,34 +738,16 @@ const FlowEditor: React.FC<{
767
738
onNodeDragStart = { onNodesChangeStart }
768
739
onNodeDragStop = { onNodesChangeEnd }
769
740
>
770
- < div style = { { position : 'absolute' , right : 10 , zIndex : 4 } } >
771
- < Input
772
- type = "text"
773
- placeholder = "Agent Name"
774
- value = { agentName }
775
- onChange = { ( e ) => setAgentName ( e . target . value ) }
776
- />
777
- < Input
778
- type = "text"
779
- placeholder = "Agent Description"
780
- value = { agentDescription }
781
- onChange = { ( e ) => setAgentDescription ( e . target . value ) }
782
- />
783
- < div style = { { display : 'flex' , flexDirection : 'column' , gap : '10px' } } > { /* Added gap for spacing */ }
784
- < Button onClick = { ( ) => saveAgent ( savedAgent ?. is_template ) } >
785
- Save { savedAgent ?. is_template ? "Template" : "Agent" }
786
- </ Button >
787
- { ! savedAgent ?. is_template &&
788
- < Button onClick = { runAgent } > Save & Run Agent </ Button >
789
- }
790
- { ! savedAgent &&
791
- < Button onClick = { ( ) => saveAgent ( true ) } > Save as Template</ Button >
792
- }
793
- < div >
794
- < Button onClick = { handleUndo } disabled = { ! history . canUndo ( ) } style = { { marginRight : '10px' } } > Undo</ Button >
795
- < Button onClick = { handleRedo } disabled = { ! history . canRedo ( ) } > Redo</ Button >
796
- </ div >
797
- </ div >
741
+ < div className = { "flex flex-row absolute z-10 gap-2" } >
742
+ < ControlPanel controls = { editorControls } >
743
+ < BlocksControl blocks = { availableNodes } addBlock = { addNode } />
744
+ < SaveControl
745
+ agentMeta = { savedAgent }
746
+ onSave = { saveAgent }
747
+ onDescriptionChange = { setAgentDescription }
748
+ onNameChange = { setAgentName }
749
+ />
750
+ </ ControlPanel >
798
751
</ div >
799
752
</ ReactFlow >
800
753
</ div >
0 commit comments