@@ -11,8 +11,10 @@ import {
1111 GraphElement ,
1212 GraphElementProps ,
1313 isEdge ,
14+ Layer ,
1415 observer ,
1516 Point ,
17+ TOP_LAYER ,
1618 useDndDrop ,
1719} from '@patternfly/react-topology' ;
1820import { clsx } from 'clsx' ;
@@ -23,7 +25,7 @@ import { useEntityContext } from '../../../../hooks/useEntityContext/useEntityCo
2325import { AddStepMode , IVisualizationNode } from '../../../../models' ;
2426import { LayoutType } from '../../Canvas' ;
2527import { CanvasDefaults } from '../../Canvas/canvas.defaults' ;
26- import { canDropOnEdge , NODE_DRAG_TYPE } from '../customComponentUtils' ;
28+ import { canDropOnEdge , GROUP_DRAG_TYPE , NODE_DRAG_TYPE } from '../customComponentUtils' ;
2729import { AddStepIcon } from './AddStepIcon' ;
2830
2931type DefaultEdgeProps = Parameters < typeof DefaultEdge > [ 0 ] ;
@@ -46,15 +48,23 @@ export const CustomEdge: FunctionComponent<CustomEdgeProps> = observer(({ elemen
4648 const customNodeDropTargetSpec : DropTargetSpec <
4749 GraphElement ,
4850 unknown ,
49- { droppable : boolean ; hover : boolean ; canDrop : boolean } ,
51+ {
52+ droppable : boolean ;
53+ hover : boolean ;
54+ canDrop : boolean ;
55+ dragItemType : string | undefined ;
56+ dragItem : GraphElement | undefined ;
57+ } ,
5058 GraphElementProps
5159 > = useMemo (
5260 ( ) => ( {
53- accept : [ NODE_DRAG_TYPE ] ,
61+ accept : [ NODE_DRAG_TYPE , GROUP_DRAG_TYPE ] ,
5462 canDrop : ( item , _monitor , _props ) =>
5563 canDropOnEdge ( item . getData ( ) . vizNode , element , entitiesContext . camelResource , catalogModalContext ) ,
5664 collect : ( monitor ) => ( {
5765 droppable : monitor . isDragging ( ) ,
66+ dragItemType : monitor . getItemType ( ) ,
67+ dragItem : monitor . getItem ( ) ,
5868 hover : monitor . isOver ( ) ,
5969 canDrop : monitor . canDrop ( ) ,
6070 } ) ,
@@ -63,6 +73,14 @@ export const CustomEdge: FunctionComponent<CustomEdgeProps> = observer(({ elemen
6373 ) ;
6474
6575 const [ dndDropProps , dndDropRef ] = useDndDrop ( customNodeDropTargetSpec ) ;
76+ const dragItemType = dndDropProps . dragItemType ;
77+ const dragItem = dndDropProps . dragItem ;
78+ const edgeSourceParent = element . getSource ( ) . getParent ( ) ?. getId ( ) ;
79+ const edgeTargetParent = element . getTarget ( ) . getParent ( ) ?. getId ( ) ;
80+ const refreshEdge =
81+ dragItemType === GROUP_DRAG_TYPE &&
82+ edgeSourceParent . slice ( 0 , dragItem ?. getId ( ) . length ) === dragItem ?. getId ( ) &&
83+ edgeTargetParent . slice ( 0 , dragItem ?. getId ( ) . length ) === dragItem ?. getId ( ) ;
6684
6785 /* If the edge connects to nodes in a collapsed group don't draw */
6886 const sourceParent = getClosestVisibleParent ( element . getSource ( ) ) ;
@@ -104,37 +122,70 @@ export const CustomEdge: FunctionComponent<CustomEdgeProps> = observer(({ elemen
104122 }
105123
106124 return (
107- < g className = "custom-edge" ref = { dndDropRef } >
108- < path className = "custom-edge__background" d = { edgeDRef . current } />
109- < path
110- className = { clsx ( 'custom-edge__body' , {
111- 'custom-edge__body__validDropTarget' : dndDropProps . hover && dndDropProps . canDrop ,
112- } ) }
113- d = { edgeDRef . current }
114- />
115- < ConnectorArrow
116- isTarget
117- className = { clsx ( 'custom-edge__connector' , {
118- 'custom-edge__connector__validDropTarget' : dndDropProps . hover && dndDropProps . canDrop ,
119- } ) }
120- startPoint = { startPointRef . current }
121- endPoint = { endPointRef . current }
122- />
125+ < Layer id = { refreshEdge ? TOP_LAYER : undefined } >
126+ < g className = "custom-edge" ref = { dndDropRef } >
127+ < path className = "custom-edge__background" d = { edgeDRef . current } />
128+ < path
129+ className = { clsx ( 'custom-edge__body' , {
130+ 'custom-edge__body__validDropTarget' : dndDropProps . hover && dndDropProps . canDrop ,
131+ } ) }
132+ d = { edgeDRef . current }
133+ />
134+ < ConnectorArrow
135+ isTarget
136+ className = { clsx ( 'custom-edge__connector' , {
137+ 'custom-edge__connector__validDropTarget' : dndDropProps . hover && dndDropProps . canDrop ,
138+ } ) }
139+ startPoint = { startPointRef . current }
140+ endPoint = { endPointRef . current }
141+ />
123142
124- { ! dndDropProps . droppable && shouldShowPrepend && (
125- < foreignObject x = { x } y = { y } width = { CanvasDefaults . ADD_STEP_ICON_SIZE } height = { CanvasDefaults . ADD_STEP_ICON_SIZE } >
126- < AddStepIcon
127- className = "custom-edge__add-step"
128- title = "Add step"
129- vizNode = { vizNode }
130- mode = { AddStepMode . PrependStep }
143+ { ! dndDropProps . droppable && shouldShowPrepend && (
144+ < foreignObject
145+ x = { x }
146+ y = { y }
147+ width = { CanvasDefaults . ADD_STEP_ICON_SIZE }
148+ height = { CanvasDefaults . ADD_STEP_ICON_SIZE }
131149 >
132- < Icon size = "lg" >
133- < PlusCircleIcon />
134- </ Icon >
135- </ AddStepIcon >
136- </ foreignObject >
137- ) }
138- </ g >
150+ < AddStepIcon
151+ className = "custom-edge__add-step"
152+ title = "Add step"
153+ vizNode = { vizNode }
154+ mode = { AddStepMode . PrependStep }
155+ >
156+ < Icon size = "lg" >
157+ < PlusCircleIcon />
158+ </ Icon >
159+ </ AddStepIcon >
160+ </ foreignObject >
161+ ) }
162+
163+ { dndDropProps . droppable && shouldShowPrepend && dndDropProps . hover && dndDropProps . canDrop && (
164+ < foreignObject
165+ x = {
166+ startPointRef . current . x +
167+ ( endPointRef . current . x - startPointRef . current . x - CanvasDefaults . ADD_STEP_ICON_SIZE ) / 2
168+ }
169+ y = {
170+ startPointRef . current . y +
171+ ( endPointRef . current . y - startPointRef . current . y - CanvasDefaults . ADD_STEP_ICON_SIZE ) / 2
172+ }
173+ width = { CanvasDefaults . ADD_STEP_ICON_SIZE }
174+ height = { CanvasDefaults . ADD_STEP_ICON_SIZE }
175+ >
176+ < AddStepIcon
177+ className = "add-step-icon__icon__validDropTarget"
178+ title = "Add step"
179+ vizNode = { vizNode }
180+ mode = { AddStepMode . PrependStep }
181+ >
182+ < Icon size = "lg" >
183+ < PlusCircleIcon />
184+ </ Icon >
185+ </ AddStepIcon >
186+ </ foreignObject >
187+ ) }
188+ </ g >
189+ </ Layer >
139190 ) ;
140191} ) ;
0 commit comments