From 49a104ee93c285a3fb35acabb90918be8f966358 Mon Sep 17 00:00:00 2001 From: jile1997 <1154416769@qq.com> Date: Thu, 30 Oct 2025 09:58:50 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=83=A8=E5=88=86=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/x-flow/src/XFlow.tsx | 2 + .../src/components/CustomNode/index.tsx | 51 ++++++++++++------- .../components/CustomNode/sourceHandle.tsx | 11 +++- .../src/components/NodesPopover/index.tsx | 12 +++-- .../ParallelBuildInNodeWidget.tsx | 1 + .../node-switch/SwitchBuildInNodeWidget.tsx | 2 + packages/x-flow/src/types.ts | 3 +- packages/x-flow/src/withProvider.tsx | 2 + 8 files changed, 59 insertions(+), 25 deletions(-) diff --git a/packages/x-flow/src/XFlow.tsx b/packages/x-flow/src/XFlow.tsx index b35f14e75..d36f4354f 100644 --- a/packages/x-flow/src/XFlow.tsx +++ b/packages/x-flow/src/XFlow.tsx @@ -176,6 +176,8 @@ const XFlow: FC = memo(props => { isAddingNode: false, }); } + } else if (e.key === 'Escape'){ + setOpenPanel(false) } }); diff --git a/packages/x-flow/src/components/CustomNode/index.tsx b/packages/x-flow/src/components/CustomNode/index.tsx index bb83abf8a..9b3651145 100644 --- a/packages/x-flow/src/components/CustomNode/index.tsx +++ b/packages/x-flow/src/components/CustomNode/index.tsx @@ -277,6 +277,30 @@ export default memo((props: any) => { }; }, [menuItem, isEnd]); + const renderHandleMemo = useCallback(()=>{ + if(renderHandle){ + return renderHandle( + SourceHandle, + { + position:sourcePosition, + isConnectable:connectable, + selected:selected, + isHovered:isHovered, + handleAddNode:handleAddNode + }, + { + id, + type, + data, + layout, + isConnectable, + readOnly + } + ) + } + return null + },[renderHandle,SourceHandle,sourcePosition,connectable,selected,isHovered,handleAddNode,id,type,data,layout,isConnectable,readOnly]) + return (
{ > {!settingMap?.[type]?.targetHandleHidden && !isNote && ( { + if(handleProps.isValidConnection){ + return handleProps.isValidConnection(edge,'target',type) + } + return true + }} type="target" position={targetPosition} isConnectable={connectable} @@ -333,24 +362,7 @@ export default memo((props: any) => {
{ onClick(data) }}> - {renderHandle( - SourceHandle, - { - position:sourcePosition, - isConnectable:connectable, - selected:selected, - isHovered:isHovered, - handleAddNode:handleAddNode - }, - { - id, - type, - data, - layout, - isConnectable, - readOnly - } - )} + {renderHandleMemo()}
: @@ -363,6 +375,7 @@ export default memo((props: any) => { isHovered={isHovered} handleAddNode={handleAddNode} isConnected={isSourceHandleConnected} + nodeType={type} // isConnectableStart={isConnectableStart} // isConnectableEnd={isConnectableEnd} /> diff --git a/packages/x-flow/src/components/CustomNode/sourceHandle.tsx b/packages/x-flow/src/components/CustomNode/sourceHandle.tsx index b2cc2b9c2..d31755a63 100644 --- a/packages/x-flow/src/components/CustomNode/sourceHandle.tsx +++ b/packages/x-flow/src/components/CustomNode/sourceHandle.tsx @@ -2,7 +2,7 @@ import { PlusOutlined } from '@ant-design/icons'; import { Handle } from '@xyflow/react'; import { Tooltip } from 'antd'; import classNames from 'classnames'; -import React, { ComponentProps, memo, useContext, useMemo, useRef, useState } from 'react'; +import React, { ComponentProps, memo, useContext, useEffect, useMemo, useRef, useState } from 'react'; import NodeSelectPopover from '../NodesPopover'; import { ConfigContext } from '../../models/context'; import './index.less'; @@ -18,6 +18,7 @@ export default memo((props:Partial & Record ) => { handleAddNode, switchTitle, isConnected, // 是否有连接的节点 + nodeType, ...rest } = props; const [isShowTooltip, setIsShowTooltip] = useState(false); @@ -40,7 +41,12 @@ export default memo((props:Partial & Record ) => { return ( { + if(handleProps.isValidConnection){ + return handleProps.isValidConnection(edge,'source',nodeType) + } + return true + }} type="source" position={position} isConnectable={isConnectable} @@ -72,6 +78,7 @@ export default memo((props:Partial & Record ) => { addNode={handleAddNode} ref={popoverRef} onNodeSelectPopoverChange={val => setOpenNodeSelectPopover(val)} + nodeType={nodeType} > { - const { addNode, children, onNodeSelectPopoverChange } = props; + const { addNode, children, onNodeSelectPopoverChange,nodeType } = props; const { setIsAddingNode } = useStore(s => ({ setIsAddingNode: s.setIsAddingNode, })); @@ -25,7 +25,13 @@ export default forwardRef((props: any, popoverRef) => { const closeRef: any = useRef(null); const [open, setOpen] = useState(false); - const { settings, nodeSelector, antdVersion ,readOnly ,clickAddNode,settingMap }: any = useContext(ConfigContext); + const { settings, nodeSelector, antdVersion ,readOnly ,clickAddNode,settingMap,filterSettings }: any = useContext(ConfigContext); + const items = useMemo(()=>{ + if(typeof filterSettings === 'function'){ + return filterSettings(settings,nodeType) + } + return settings + },[settings,nodeType]) const { showSearch, popoverProps = { placement: 'top' } } = nodeSelector || {}; @@ -97,7 +103,7 @@ export default forwardRef((props: any, popoverRef) => { content={ diff --git a/packages/x-flow/src/nodes/node-parallel/ParallelBuildInNodeWidget.tsx b/packages/x-flow/src/nodes/node-parallel/ParallelBuildInNodeWidget.tsx index 544f5d1f4..140ea7ac8 100644 --- a/packages/x-flow/src/nodes/node-parallel/ParallelBuildInNodeWidget.tsx +++ b/packages/x-flow/src/nodes/node-parallel/ParallelBuildInNodeWidget.tsx @@ -69,6 +69,7 @@ export default memo((props: any) => { (edges || [])?.filter(flow => flow?.sourceHandle === item?._id) ?.length > 0 } + nodeType={'Parallel'} />
); diff --git a/packages/x-flow/src/nodes/node-switch/SwitchBuildInNodeWidget.tsx b/packages/x-flow/src/nodes/node-switch/SwitchBuildInNodeWidget.tsx index 69f5f1401..8d5eee6a8 100644 --- a/packages/x-flow/src/nodes/node-switch/SwitchBuildInNodeWidget.tsx +++ b/packages/x-flow/src/nodes/node-switch/SwitchBuildInNodeWidget.tsx @@ -56,6 +56,7 @@ export default memo((props: any) => { (edges || [])?.filter(flow => flow?.sourceHandle === item?._id) ?.length > 0 } + nodeType={'switch'} /> ); @@ -140,6 +141,7 @@ export default memo((props: any) => { flow?.sourceHandle === 'id_else' && flow?.source === id )?.length > 0 } + nodeType={'Switch'} /> diff --git a/packages/x-flow/src/types.ts b/packages/x-flow/src/types.ts index 116bdf824..542870237 100644 --- a/packages/x-flow/src/types.ts +++ b/packages/x-flow/src/types.ts @@ -139,7 +139,7 @@ export interface TControl{ export interface THandle{ // isConnectableStart?:boolean // isConnectableEnd?:boolean - isValidConnection?:HandleProps['isValidConnection'] + isValidConnection?:(edges:Parameters[0],edgeType:'source'|'target',nodeType:string)=>boolean } export interface FlowProps { initialValues?: { @@ -167,6 +167,7 @@ export interface FlowProps { * 节点配置 */ settings?: (TNodeGroup | TNodeItem)[]; + filterSettings?:(settings:(TNodeGroup | TNodeItem)[],nodeType:string)=>(TNodeGroup | TNodeItem)[] nodeSelector?: TNodeSelector; iconFontUrl?: string; globalConfig?: { diff --git a/packages/x-flow/src/withProvider.tsx b/packages/x-flow/src/withProvider.tsx index 6dedc1859..e18de895f 100644 --- a/packages/x-flow/src/withProvider.tsx +++ b/packages/x-flow/src/withProvider.tsx @@ -35,6 +35,7 @@ export default function withProvider( clickAddNode, onTesting, openColorfulMode, + filterSettings, ...restProps } = props; const settingMap = useMemo(() => { @@ -65,6 +66,7 @@ export default function withProvider( clickAddNode, onTesting, openColorfulMode, + filterSettings, widgets: { ...defaultWidgets, ...widgets,