66 addEdge ,
77 NodeChange ,
88 EdgeChange ,
9+ Node as ReactFlowNode ,
10+ Edge as ReactFlowEdge ,
911} from "@xyflow/react" ;
1012import "@xyflow/react/dist/style.css" ;
1113import { useState , useCallback , useEffect } from "react" ;
@@ -19,24 +21,23 @@ import {
1921} from "@/lib/types" ;
2022import { useMenuActions } from "@/lib/hooks/use-menu-actions" ;
2123import AppNode from "./nodes/app-node" ;
22- import { v4 } from "uuid" ;
23-
24- const initialNodes = [
25- {
26- id : "n1" ,
27- position : { x : 200 , y : 0 } ,
28- data : {
29- label : "Node 1" ,
30- config : {
31- viewId : v4 ( ) ,
32- app : "https://cdn.pulse-editor.com/extension/spin_wheel/0.0.1/" ,
33- } ,
34- } ,
35- type : "appNode" ,
36- } ,
37- { id : "n2" , position : { x : 0 , y : 100 } , data : { label : "Node 2" } } ,
38- ] ;
39- const initialEdges = [ { id : "n1-n2" , source : "n1" , target : "n2" } ] ;
24+
25+ // const initialNodes = [
26+ // {
27+ // id: "n1",
28+ // position: { x: 200, y: 0 },
29+ // data: {
30+ // label: "Node 1",
31+ // config: {
32+ // viewId: v4(),
33+ // app: "https://cdn.pulse-editor.com/extension/spin_wheel/0.0.1/",
34+ // },
35+ // },
36+ // type: "appNode",
37+ // },
38+ // { id: "n2", position: { x: 0, y: 100 }, data: { label: "Node 2" } },
39+ // ];
40+ // const initialEdges = [{ id: "n1-n2", source: "n1", target: "n2" }];
4041
4142const appInfo : AppInfoModalContent = {
4243 name : "Pulse Editor" ,
@@ -64,22 +65,13 @@ export default function CanvasView({
6465 openViewInFullScreen : ( config : AppViewConfig ) => void ;
6566} ) {
6667 const { openAppInfoModal } = useAppInfo ( ) ;
67- const [ nodes , setNodes ] = useState ( initialNodes ) ;
68- const [ edges , setEdges ] = useState ( initialEdges ) ;
69-
70- const onNodesChange = useCallback (
71- (
72- changes : NodeChange < {
73- id : string ;
74- position : { x : number ; y : number } ;
75- data : { label : string } ;
76- } > [ ] ,
77- ) => {
78- console . log ( "Node changes:" , changes ) ;
79- setNodes ( ( nodesSnapshot ) => applyNodeChanges ( changes , nodesSnapshot ) ) ;
80- } ,
81- [ ] ,
82- ) ;
68+ const [ nodes , setNodes ] = useState < ReactFlowNode [ ] > ( [ ] ) ;
69+ const [ edges , setEdges ] = useState < ReactFlowEdge [ ] > ( [ ] ) ;
70+
71+ const onNodesChange = useCallback ( ( changes : NodeChange < ReactFlowNode > [ ] ) => {
72+ console . log ( "Node changes:" , changes ) ;
73+ setNodes ( ( nodesSnapshot ) => applyNodeChanges ( changes , nodesSnapshot ) ) ;
74+ } , [ ] ) ;
8375 const onEdgesChange = useCallback (
8476 ( changes : EdgeChange < { id : string ; source : string ; target : string } > [ ] ) =>
8577 setEdges ( ( edgesSnapshot ) => applyEdgeChanges ( changes , edgesSnapshot ) ) ,
@@ -91,19 +83,6 @@ export default function CanvasView({
9183 [ ] ,
9284 ) ;
9385
94- async function exportWorkflow ( ) {
95- const workflow = { nodes, edges } ;
96- const blob = new Blob ( [ JSON . stringify ( workflow , null , 2 ) ] , {
97- type : "application/json" ,
98- } ) ;
99- const url = URL . createObjectURL ( blob ) ;
100- const a = document . createElement ( "a" ) ;
101- a . href = url ;
102- a . download = "workflow.json" ;
103- a . click ( ) ;
104- URL . revokeObjectURL ( url ) ;
105- }
106-
10786 const createAppNode = useCallback (
10887 ( props : any ) => {
10988 return < AppNode { ...props } openViewInFullScreen = { openViewInFullScreen } /> ;
@@ -112,6 +91,7 @@ export default function CanvasView({
11291 ) ;
11392
11493 const { registerMenuAction, unregisterMenuAction } = useMenuActions ( ) ;
94+
11595 // Register menu actions
11696 useEffect ( ( ) => {
11797 console . log ( "CanvasView rendered: registering menu actions" ) ;
@@ -172,8 +152,46 @@ export default function CanvasView({
172152 } ;
173153 } , [ ] ) ;
174154
155+ useEffect ( ( ) => {
156+ if ( config ) {
157+ const appConfigs : ReactFlowNode [ ] =
158+ config . nodes ?. map ( ( appConfig ) => ( {
159+ id : appConfig . viewId ,
160+ position : {
161+ x : 0 ,
162+ y : 0 ,
163+ } ,
164+ data : {
165+ label : appConfig . app ,
166+ config : appConfig ,
167+ } ,
168+ type : "appNode" ,
169+ height : appConfig . recommendedHeight ?? 360 ,
170+ width : appConfig . recommendedWidth ?? 640 ,
171+ } ) ) ?? [ ] ;
172+
173+ setNodes ( appConfigs ) ;
174+ }
175+ } , [ config ] ) ;
176+
177+ async function exportWorkflow ( ) {
178+ const workflow = { nodes, edges } ;
179+ const blob = new Blob ( [ JSON . stringify ( workflow , null , 2 ) ] , {
180+ type : "application/json" ,
181+ } ) ;
182+ const url = URL . createObjectURL ( blob ) ;
183+ const a = document . createElement ( "a" ) ;
184+ a . href = url ;
185+ a . download = "workflow.json" ;
186+ a . click ( ) ;
187+ URL . revokeObjectURL ( url ) ;
188+ }
189+
175190 return (
176- < div className = "bg-default text-default-foreground relative h-full w-full" >
191+ < div
192+ className = "bg-default text-default-foreground relative h-full w-full"
193+ id = { `canvas-${ config ?. viewId } ` }
194+ >
177195 < ReactFlow
178196 nodes = { nodes }
179197 edges = { edges }
0 commit comments