@@ -2,8 +2,10 @@ import { MoreOutlined } from '@ant-design/icons';
22import { Handle , Position , useReactFlow } from '@xyflow/react' ;
33import { Dropdown , message } from "antd" ;
44
5+ import { ItemType } from 'antd/es/menu/interface' ;
56import 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' ;
79import { shallow } from 'zustand/shallow' ;
810import { useStore } from '../../hooks/useStore' ;
911import { ConfigContext } from '../../models/context' ;
@@ -14,8 +16,10 @@ import SourceHandle from './sourceHandle';
1416export default memo ( ( props : any ) => {
1517 const { id, type, data, layout, isConnectable, selected, onClick, status } =
1618 props ;
17- const { widgets, settingMap, globalConfig } = useContext ( ConfigContext ) ;
19+ const { widgets, settingMap, globalConfig, onMenuItemClick } =
20+ useContext ( ConfigContext ) ;
1821 const deletable = globalConfig ?. edge ?. deletable ?? true ;
22+
1923 const NodeWidget =
2024 widgets [ `${ capitalize ( type ) } Node` ] || widgets [ 'CommonNode' ] ;
2125 const [ isHovered , setIsHovered ] = useState ( false ) ;
@@ -50,7 +54,7 @@ export default memo((props: any) => {
5054 type : 'custom' ,
5155 data : {
5256 ...data ,
53- title : `${ title } _${ uuid4 ( ) } `
57+ title : `${ title } _${ uuid4 ( ) } ` ,
5458 } ,
5559 position : { x, y } ,
5660 } ;
@@ -77,14 +81,92 @@ export default memo((props: any) => {
7781 message . success ( '复制成功' ) ;
7882 } , [ copyNode ] ) ;
7983
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+ ) ;
8390
8491 const handleDeleteNode = useCallback ( ( ) => {
85- deleteNode ( id )
92+ deleteNode ( id ) ;
8693 } , [ pasteNode ] ) ;
8794
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 ] ) ;
88170
89171 // 节点状态处理
90172 const statusObj = transformNodeStatus ( globalConfig ?. nodeView ?. status || [ ] ) ;
@@ -113,29 +195,24 @@ export default memo((props: any) => {
113195 items : [
114196 {
115197 label : '复制' ,
116- key : ' copy' ,
117- onClick : handleCopyNode ,
118- } ,
119- {
120- label : '粘贴' ,
121- key : 'paste' ,
122- onClick : handlePasteNode ,
198+ key : 'copy' ,
123199 } ,
200+ ...menuItem ,
124201 {
125202 label : '删除' ,
126203 key : 'delete' ,
127204 danger : true ,
128- onClick : handleDeleteNode ,
129205 } ,
130206 ] ,
207+ onClick : itemClick ,
131208 } }
132209 trigger = { [ 'click' , 'contextMenu' ] }
133210 >
134211 < 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 >
139216 </ Dropdown >
140217 ) }
141218 < NodeWidget
0 commit comments