@@ -2,8 +2,10 @@ import { MoreOutlined } from '@ant-design/icons';
2
2
import { Handle , Position , useReactFlow } from '@xyflow/react' ;
3
3
import { Dropdown , message } from "antd" ;
4
4
5
+ import { ItemType } from 'antd/es/menu/interface' ;
5
6
import classNames from 'classnames' ;
6
- import React , { memo , useCallback , useContext , useState } from 'react' ;
7
+ import { isFunction } from 'lodash' ;
8
+ import React , { memo , useCallback , useContext , useMemo , useState } from 'react' ;
7
9
import { shallow } from 'zustand/shallow' ;
8
10
import { useStore } from '../../hooks/useStore' ;
9
11
import { ConfigContext } from '../../models/context' ;
@@ -14,8 +16,10 @@ import SourceHandle from './sourceHandle';
14
16
export default memo ( ( props : any ) => {
15
17
const { id, type, data, layout, isConnectable, selected, onClick, status } =
16
18
props ;
17
- const { widgets, settingMap, globalConfig } = useContext ( ConfigContext ) ;
19
+ const { widgets, settingMap, globalConfig, onMenuItemClick } =
20
+ useContext ( ConfigContext ) ;
18
21
const deletable = globalConfig ?. edge ?. deletable ?? true ;
22
+
19
23
const NodeWidget =
20
24
widgets [ `${ capitalize ( type ) } Node` ] || widgets [ 'CommonNode' ] ;
21
25
const [ isHovered , setIsHovered ] = useState ( false ) ;
@@ -50,7 +54,7 @@ export default memo((props: any) => {
50
54
type : 'custom' ,
51
55
data : {
52
56
...data ,
53
- title : `${ title } _${ uuid4 ( ) } `
57
+ title : `${ title } _${ uuid4 ( ) } ` ,
54
58
} ,
55
59
position : { x, y } ,
56
60
} ;
@@ -77,14 +81,92 @@ export default memo((props: any) => {
77
81
message . success ( '复制成功' ) ;
78
82
} , [ copyNode ] ) ;
79
83
80
- const handlePasteNode = useCallback ( ( ) => {
81
- pasteNode ( id )
82
- } , [ pasteNode ] ) ;
84
+ const handlePasteNode = useCallback (
85
+ ( data ?: { sourceHandle : string } ) => {
86
+ pasteNode ( id , data ) ;
87
+ } ,
88
+ [ pasteNode ]
89
+ ) ;
83
90
84
91
const handleDeleteNode = useCallback ( ( ) => {
85
- deleteNode ( id )
92
+ deleteNode ( id ) ;
86
93
} , [ pasteNode ] ) ;
87
94
95
+ const itemClick = e => {
96
+ if ( ! e . key ) {
97
+ return ;
98
+ }
99
+ const sourceHandle = e . item . props ?. sourcehandle ;
100
+ if ( isFunction ( onMenuItemClick ) ) {
101
+ const data : Record < string , string > = {
102
+ key : e . key ,
103
+ nodeId : id ,
104
+ } ;
105
+ if ( type === 'Switch' && e . key . startsWith ( 'paste-' ) && sourceHandle ) {
106
+ data [ 'sourceHandle' ] = sourceHandle ;
107
+ }
108
+ onMenuItemClick ( data ) ;
109
+ } else {
110
+ if ( e . key === 'copy' ) {
111
+ handleCopyNode ( ) ;
112
+ } else if ( e . key === 'paste' ) {
113
+ handlePasteNode ( ) ;
114
+ } else if ( e . key === 'delete' ) {
115
+ handleDeleteNode ( ) ;
116
+ } else if ( e . key . startsWith ( 'paste-' ) ) {
117
+ if ( sourceHandle ) {
118
+ handlePasteNode ( {
119
+ sourceHandle,
120
+ } ) ;
121
+ } else {
122
+ handlePasteNode ( ) ;
123
+ }
124
+ }
125
+ }
126
+ } ;
127
+
128
+ const menuItem : ItemType [ ] = useMemo ( ( ) => {
129
+ if ( type === 'Switch' ) {
130
+ let list = [ ] ;
131
+ if ( Array . isArray ( data . list ) ) {
132
+ const len = data . list . length ;
133
+ list = data . list . map ( ( r , i ) => {
134
+ if ( i === 0 ) {
135
+ return {
136
+ label : `粘贴到第${ i + 1 } 个出口` ,
137
+ key : 'paste-' + i ,
138
+ index : i ,
139
+ id : id ,
140
+ } ;
141
+ } else {
142
+ return {
143
+ label : `粘贴到第${ i + 1 } 个出口` ,
144
+ key : 'paste-' + i ,
145
+ id : id ,
146
+ index : i ,
147
+ sourcehandle : r . _conditionId ,
148
+ } ;
149
+ }
150
+ } ) ;
151
+ }
152
+ return [
153
+ ...list ,
154
+ {
155
+ label : `粘贴到第${ list . length + 1 } 个出口` ,
156
+ key : 'paste-' + ( list . length + 1 ) ,
157
+ id : id ,
158
+ index : list . length + 1 ,
159
+ sourcehandle : 'condition_else' ,
160
+ } ,
161
+ ] ;
162
+ }
163
+ return [
164
+ {
165
+ label : '粘贴' ,
166
+ key : 'paste' ,
167
+ } ,
168
+ ] ;
169
+ } , [ type ] ) ;
88
170
89
171
// 节点状态处理
90
172
const statusObj = transformNodeStatus ( globalConfig ?. nodeView ?. status || [ ] ) ;
@@ -113,29 +195,24 @@ export default memo((props: any) => {
113
195
items : [
114
196
{
115
197
label : '复制' ,
116
- key : ' copy' ,
117
- onClick : handleCopyNode ,
118
- } ,
119
- {
120
- label : '粘贴' ,
121
- key : 'paste' ,
122
- onClick : handlePasteNode ,
198
+ key : 'copy' ,
123
199
} ,
200
+ ...menuItem ,
124
201
{
125
202
label : '删除' ,
126
203
key : 'delete' ,
127
204
danger : true ,
128
- onClick : handleDeleteNode ,
129
205
} ,
130
206
] ,
207
+ onClick : itemClick ,
131
208
} }
132
209
trigger = { [ 'click' , 'contextMenu' ] }
133
210
>
134
211
< div className = "xflow-node-actions-container" >
135
- < MoreOutlined
136
- style = { { transform : 'rotateZ(90deg)' , fontSize : '20px' } }
137
- > </ MoreOutlined >
138
- </ div >
212
+ < MoreOutlined
213
+ style = { { transform : 'rotateZ(90deg)' , fontSize : '20px' } }
214
+ > </ MoreOutlined >
215
+ </ div >
139
216
</ Dropdown >
140
217
) }
141
218
< NodeWidget
0 commit comments