1+ import { MoreOutlined } from '@ant-design/icons' ;
12import { Handle , Position , useReactFlow } from '@xyflow/react' ;
3+ import { Dropdown , message } from "antd" ;
4+
25import classNames from 'classnames' ;
3- import React , { memo , useContext , useState } from 'react' ;
6+ import React , { memo , useCallback , useContext , useState } from 'react' ;
47import { shallow } from 'zustand/shallow' ;
58import { useStore } from '../../hooks/useStore' ;
69import { ConfigContext } from '../../models/context' ;
@@ -15,13 +18,15 @@ export default memo((props: any) => {
1518 widgets [ `${ capitalize ( type ) } Node` ] || widgets [ 'CommonNode' ] ;
1619 const [ isHovered , setIsHovered ] = useState ( false ) ;
1720 const reactflow = useReactFlow ( ) ;
18- const { addNodes, addEdges, mousePosition } = useStore (
21+ const { addNodes, addEdges, copyNode , pasteNode , mousePosition } = useStore (
1922 ( state : any ) => ( {
2023 nodes : state . nodes ,
2124 edges : state . edges ,
2225 mousePosition : state . mousePosition ,
2326 addNodes : state . addNodes ,
2427 addEdges : state . addEdges ,
28+ copyNode : state . copyNode ,
29+ pasteNode : state . pasteNode ,
2530 onEdgesChange : state . onEdgesChange ,
2631 } ) ,
2732 shallow
@@ -42,15 +47,15 @@ export default memo((props: any) => {
4247 type : 'custom' ,
4348 data : {
4449 ...data ,
45- title : `${ title } _${ uuid4 ( ) } `
50+ title : `${ title } _${ uuid4 ( ) } ` ,
4651 } ,
4752 position : { x, y } ,
4853 } ;
4954 const newEdges = {
5055 id : uuid ( ) ,
5156 source : id ,
5257 target : targetId ,
53- ...sourceHandle && { sourceHandle }
58+ ...( sourceHandle && { sourceHandle } ) ,
5459 } ;
5560 addNodes ( newNodes ) ;
5661 addEdges ( newEdges ) ;
@@ -62,6 +67,16 @@ export default memo((props: any) => {
6267 targetPosition = Position . Top ;
6368 sourcePosition = Position . Bottom ;
6469 }
70+
71+ const handleCopyNode = useCallback ( ( ) => {
72+ copyNode ( id ) ;
73+ message . success ( '复制成功' ) ;
74+ } , [ copyNode ] ) ;
75+
76+ const handlePasteNode = useCallback ( ( ) => {
77+ pasteNode ( id )
78+ } , [ pasteNode ] ) ;
79+
6580 return (
6681 < div
6782 className = { classNames ( 'xflow-node-container' , {
@@ -78,6 +93,31 @@ export default memo((props: any) => {
7893 isConnectable = { isConnectable }
7994 />
8095 ) }
96+ { selected && (
97+ < Dropdown
98+ menu = { {
99+ items : [
100+ {
101+ label : '复制' ,
102+ key : ' copy' ,
103+ onClick : handleCopyNode ,
104+ } ,
105+ {
106+ label : '粘贴' ,
107+ key : 'paste' ,
108+ onClick : handlePasteNode ,
109+ } ,
110+ ] ,
111+ } }
112+ trigger = { [ 'click' , 'contextMenu' ] }
113+ >
114+ < div className = "xflow-node-actions-container" >
115+ < MoreOutlined
116+ style = { { transform : 'rotateZ(90deg)' , fontSize : '20px' } }
117+ > </ MoreOutlined >
118+ </ div >
119+ </ Dropdown >
120+ ) }
81121 < NodeWidget
82122 id = { id }
83123 type = { type }
0 commit comments