@@ -14,6 +14,7 @@ import {
1414 buildNodesFromSteps ,
1515 findStepIdxWithUUID ,
1616 getLayoutedElements ,
17+ containsAddStepPlaceholder ,
1718} from '@kaoto/services' ;
1819import { useIntegrationJsonStore , useVisualizationStore } from '@kaoto/store' ;
1920import { IStepProps , IViewData , IVizStepPropsEdge , IVizStepNode } from '@kaoto/types' ;
@@ -29,13 +30,14 @@ const Visualization = ({ toggleCatalog }: IVisualization) => {
2930 // `nodes` is an array of UI-specific objects that represent
3031 // the Integration.Steps model visually, while `edges` connect them
3132 const defaultViewport : Viewport = {
32- x : window . innerWidth / 2 ,
33- y : window . innerHeight / 2 - 160 ,
33+ x : 0 ,
34+ y : 0 ,
3435 zoom : 1.2 ,
3536 } ;
37+
3638 const [ isPanelExpanded , setIsPanelExpanded ] = useState ( false ) ;
3739 const [ , setReactFlowInstance ] = useState ( null ) ;
38- const reactFlowWrapper = useRef ( null ) ;
40+ const reactFlowWrapperRef = useRef < HTMLDivElement > ( null ) ;
3941 const [ selectedStep , setSelectedStep ] = useState < IStepProps > ( {
4042 maxBranches : 0 ,
4143 minBranches : 0 ,
@@ -50,7 +52,42 @@ const Visualization = ({ toggleCatalog }: IVisualization) => {
5052 const { nodes, setNodes, onNodesChange, edges, setEdges, onEdgesChange, deleteNode } =
5153 useVisualizationStore ( ) ;
5254
53- // initial loading of visualization steps
55+ /**
56+ * Center first node if it is the initial `add a step `
57+ * node into react flow viewport.
58+ */
59+ useEffect ( ( ) => {
60+ const isAddStepPlaceholder = containsAddStepPlaceholder ( nodes ) ;
61+
62+ if ( isAddStepPlaceholder ) {
63+ const reactFlowWrapper = reactFlowWrapperRef . current ;
64+
65+ let reactFlowWrapperRect ;
66+
67+ if ( reactFlowWrapper ) {
68+ reactFlowWrapperRect = reactFlowWrapper . getBoundingClientRect ( ) ;
69+ }
70+
71+ if (
72+ nodes [ 0 ] ?. width &&
73+ nodes [ 0 ] ?. height &&
74+ reactFlowWrapperRect ?. width &&
75+ reactFlowWrapperRect ?. height
76+ ) {
77+ const firstNodeWidth = nodes [ 0 ] . width ;
78+ const firstNodeHeight = nodes [ 0 ] . height ;
79+ const reactFlowWrapperRectWidth = reactFlowWrapperRect . width ;
80+ const reactFlowWrapperRectHeight = reactFlowWrapperRect . height ;
81+
82+ nodes [ 0 ] . position . x = ( reactFlowWrapperRectWidth / 2 - firstNodeWidth / 2 ) * 0.8 ;
83+ nodes [ 0 ] . position . y = ( reactFlowWrapperRectHeight / 2 - firstNodeHeight / 2 ) * 0.8 ;
84+ }
85+ }
86+ } ) ;
87+
88+ /**
89+ * Initial loading of visualization steps
90+ */
5491 useEffect ( ( ) => {
5592 const { stepNodes, stepEdges } = buildNodesAndEdges ( integrationJson . steps ) ;
5693
@@ -225,7 +262,7 @@ const Visualization = ({ toggleCatalog }: IVisualization) => {
225262 < div
226263 className = "reactflow-wrapper"
227264 data-testid = { 'react-flow-wrapper' }
228- ref = { reactFlowWrapper }
265+ ref = { reactFlowWrapperRef }
229266 style = { {
230267 width : window . innerWidth ,
231268 height : window . innerHeight - 153 ,
@@ -234,8 +271,8 @@ const Visualization = ({ toggleCatalog }: IVisualization) => {
234271 < ReactFlow
235272 nodes = { nodes }
236273 edges = { edges }
237- defaultViewport = { defaultViewport }
238274 edgeTypes = { edgeTypes }
275+ defaultViewport = { defaultViewport }
239276 nodeTypes = { nodeTypes }
240277 onDragOver = { onDragOver }
241278 onNodeClick = { onNodeClick }
0 commit comments