|
|
|
|
@ -24,6 +24,7 @@ import ActionBar from './components/actionBar';
|
|
|
|
|
import { useAlignmentGuidelines } from '@/hooks/useAlignmentGuidelines';
|
|
|
|
|
import { useHistory } from './components/historyContext';
|
|
|
|
|
import { NodeTypes } from '@xyflow/react';
|
|
|
|
|
import { useSelector } from 'react-redux';
|
|
|
|
|
|
|
|
|
|
const edgeTypes = {
|
|
|
|
|
custom: CustomEdge
|
|
|
|
|
@ -137,6 +138,12 @@ const FlowEditorMain: React.FC<FlowEditorMainProps> = (props) => {
|
|
|
|
|
const { getGuidelines, clearGuidelines, AlignmentGuides } = useAlignmentGuidelines();
|
|
|
|
|
const { undo, redo, canUndo, canRedo } = useHistory();
|
|
|
|
|
const reactFlowId = useMemo(() => new Date().getTime().toString(), []);
|
|
|
|
|
|
|
|
|
|
// 从Redux store中获取当前应用的运行状态
|
|
|
|
|
const { appRuntimeData, currentAppData } = useSelector((state: any) => state.ideContainer);
|
|
|
|
|
const currentAppIsRunning = currentAppData?.id && appRuntimeData[currentAppData.id]
|
|
|
|
|
? appRuntimeData[currentAppData.id].isRunning
|
|
|
|
|
: false;
|
|
|
|
|
|
|
|
|
|
// 监听键盘事件实现快捷键
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
@ -178,17 +185,17 @@ const FlowEditorMain: React.FC<FlowEditorMainProps> = (props) => {
|
|
|
|
|
onContextMenu={(e) => e.preventDefault()}>
|
|
|
|
|
<ReactFlow
|
|
|
|
|
id={reactFlowId}
|
|
|
|
|
nodes={nodes.map(node => ({ ...node, draggable: !isRunning }))} // 运行时禁用节点拖拽
|
|
|
|
|
nodes={nodes.map(node => ({ ...node, draggable: !currentAppIsRunning }))} // 运行时禁用节点拖拽
|
|
|
|
|
edges={edges}
|
|
|
|
|
nodeTypes={nodeTypes}
|
|
|
|
|
edgeTypes={edgeTypes}
|
|
|
|
|
snapToGrid={true}
|
|
|
|
|
snapGrid={[2, 2]}
|
|
|
|
|
nodesConnectable={!isRunning} // 运行时禁用节点连接
|
|
|
|
|
nodesDraggable={!isRunning} // 运行时禁用节点拖拽
|
|
|
|
|
elementsSelectable={!isRunning} // 运行时禁用元素选择
|
|
|
|
|
connectOnClick={!isRunning} // 运行时禁用点击连接
|
|
|
|
|
disableKeyboardA11y={isRunning} // 运行时禁用键盘交互
|
|
|
|
|
nodesConnectable={!currentAppIsRunning} // 运行时禁用节点连接
|
|
|
|
|
nodesDraggable={!currentAppIsRunning} // 运行时禁用节点拖拽
|
|
|
|
|
elementsSelectable={!currentAppIsRunning} // 运行时禁用元素选择
|
|
|
|
|
connectOnClick={!currentAppIsRunning} // 运行时禁用点击连接
|
|
|
|
|
disableKeyboardA11y={currentAppIsRunning} // 运行时禁用键盘交互
|
|
|
|
|
onBeforeDelete={async ({ nodes }) => {
|
|
|
|
|
// 检查是否有开始或结束节点
|
|
|
|
|
const hasStartOrEndNode = nodes.some(node => node.type === 'start' || node.type === 'end');
|
|
|
|
|
@ -203,7 +210,7 @@ const FlowEditorMain: React.FC<FlowEditorMainProps> = (props) => {
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// 允许删除操作继续进行
|
|
|
|
|
return !isRunning; // 运行时禁止删除节点
|
|
|
|
|
return !currentAppIsRunning; // 运行时禁止删除节点
|
|
|
|
|
}}
|
|
|
|
|
onNodesDelete={(deleted) => {
|
|
|
|
|
// 检查是否有循环节点
|
|
|
|
|
@ -262,21 +269,21 @@ const FlowEditorMain: React.FC<FlowEditorMainProps> = (props) => {
|
|
|
|
|
|
|
|
|
|
setIsEditModalOpen(false);
|
|
|
|
|
}}
|
|
|
|
|
onNodesChange={!isRunning ? onNodesChange : undefined} // 运行时禁用节点变更
|
|
|
|
|
onEdgesChange={!isRunning ? onEdgesChange : undefined} // 运行时禁用边变更
|
|
|
|
|
onConnect={!isRunning ? onConnect : undefined} // 运行时禁用连接
|
|
|
|
|
onReconnect={!isRunning ? onReconnect : undefined} // 运行时禁用重新连接
|
|
|
|
|
onDragOver={!isRunning ? onDragOver : undefined} // 运行时禁用拖拽
|
|
|
|
|
onDrop={!isRunning ? onDrop : undefined} // 运行时禁用放置
|
|
|
|
|
onNodeDrag={!isRunning ? onNodeDrag : undefined} // 运行时禁用节点拖拽
|
|
|
|
|
onNodesChange={!currentAppIsRunning ? onNodesChange : undefined} // 运行时禁用节点变更
|
|
|
|
|
onEdgesChange={!currentAppIsRunning ? onEdgesChange : undefined} // 运行时禁用边变更
|
|
|
|
|
onConnect={!currentAppIsRunning ? onConnect : undefined} // 运行时禁用连接
|
|
|
|
|
onReconnect={!currentAppIsRunning ? onReconnect : undefined} // 运行时禁用重新连接
|
|
|
|
|
onDragOver={!currentAppIsRunning ? onDragOver : undefined} // 运行时禁用拖拽
|
|
|
|
|
onDrop={!currentAppIsRunning ? onDrop : undefined} // 运行时禁用放置
|
|
|
|
|
onNodeDrag={!currentAppIsRunning ? onNodeDrag : undefined} // 运行时禁用节点拖拽
|
|
|
|
|
connectionLineType={ConnectionLineType.SmoothStep}
|
|
|
|
|
connectionLineComponent={CustomConnectionLine}
|
|
|
|
|
onNodeDragStop={!isRunning ? onNodeDragStop : undefined} // 运行时禁用节点拖拽停止
|
|
|
|
|
onNodeContextMenu={!isRunning ? onNodeContextMenu : undefined} // 运行时禁用节点上下文菜单
|
|
|
|
|
onNodeDoubleClick={!isRunning ? onNodeDoubleClick : undefined} // 运行时禁用节点双击
|
|
|
|
|
onEdgeContextMenu={!isRunning ? onEdgeContextMenu : undefined} // 运行时禁用边上下文菜单
|
|
|
|
|
onPaneClick={!isRunning ? onPaneClick : undefined} // 运行时禁用面板点击
|
|
|
|
|
onPaneContextMenu={!isRunning ? onPaneContextMenu : undefined} // 运行时禁用面板上下文菜单
|
|
|
|
|
onNodeDragStop={!currentAppIsRunning ? onNodeDragStop : undefined} // 运行时禁用节点拖拽停止
|
|
|
|
|
onNodeContextMenu={!currentAppIsRunning ? onNodeContextMenu : undefined} // 运行时禁用节点上下文菜单
|
|
|
|
|
onNodeDoubleClick={!currentAppIsRunning ? onNodeDoubleClick : undefined} // 运行时禁用节点双击
|
|
|
|
|
onEdgeContextMenu={!currentAppIsRunning ? onEdgeContextMenu : undefined} // 运行时禁用边上下文菜单
|
|
|
|
|
onPaneClick={!currentAppIsRunning ? onPaneClick : undefined} // 运行时禁用面板点击
|
|
|
|
|
onPaneContextMenu={!currentAppIsRunning ? onPaneContextMenu : undefined} // 运行时禁用面板上下文菜单
|
|
|
|
|
onEdgeMouseEnter={(_event, edge) => {
|
|
|
|
|
setEdges((eds) => eds.map(e => {
|
|
|
|
|
if (e.id === edge.id) {
|
|
|
|
|
@ -294,8 +301,8 @@ const FlowEditorMain: React.FC<FlowEditorMainProps> = (props) => {
|
|
|
|
|
}));
|
|
|
|
|
}}
|
|
|
|
|
fitView
|
|
|
|
|
selectionOnDrag={!isRunning} // 运行时禁用拖拽选择
|
|
|
|
|
selectionMode={!isRunning ? SelectionMode.Partial : undefined} // 运行时禁用选择模式
|
|
|
|
|
selectionOnDrag={!currentAppIsRunning} // 运行时禁用拖拽选择
|
|
|
|
|
selectionMode={!currentAppIsRunning ? SelectionMode.Partial : undefined} // 运行时禁用选择模式
|
|
|
|
|
>
|
|
|
|
|
<Background />
|
|
|
|
|
<Panel position="top-left">
|
|
|
|
|
@ -307,14 +314,14 @@ const FlowEditorMain: React.FC<FlowEditorMainProps> = (props) => {
|
|
|
|
|
canUndo={canUndo}
|
|
|
|
|
canRedo={canRedo}
|
|
|
|
|
onRun={handleRun}
|
|
|
|
|
isRunning={isRunning}
|
|
|
|
|
isRunning={currentAppIsRunning}
|
|
|
|
|
></ActionBar>
|
|
|
|
|
</Panel>
|
|
|
|
|
<AlignmentGuides />
|
|
|
|
|
</ReactFlow>
|
|
|
|
|
|
|
|
|
|
{/*节点右键上下文*/}
|
|
|
|
|
{!isRunning && menu && menu.type === 'node' && (
|
|
|
|
|
{!currentAppIsRunning && menu && menu.type === 'node' && (
|
|
|
|
|
<div
|
|
|
|
|
style={{
|
|
|
|
|
position: 'absolute',
|
|
|
|
|
@ -335,7 +342,7 @@ const FlowEditorMain: React.FC<FlowEditorMainProps> = (props) => {
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{/*边右键上下文*/}
|
|
|
|
|
{!isRunning && menu && menu.type === 'edge' && (
|
|
|
|
|
{!currentAppIsRunning && menu && menu.type === 'edge' && (
|
|
|
|
|
<div
|
|
|
|
|
style={{
|
|
|
|
|
position: 'absolute',
|
|
|
|
|
@ -358,7 +365,7 @@ const FlowEditorMain: React.FC<FlowEditorMainProps> = (props) => {
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{/*画布右键上下文*/}
|
|
|
|
|
{!isRunning && menu && menu.type === 'pane' && (
|
|
|
|
|
{!currentAppIsRunning && menu && menu.type === 'pane' && (
|
|
|
|
|
<div
|
|
|
|
|
style={{
|
|
|
|
|
position: 'absolute',
|
|
|
|
|
@ -382,14 +389,14 @@ const FlowEditorMain: React.FC<FlowEditorMainProps> = (props) => {
|
|
|
|
|
<NodeEditModal
|
|
|
|
|
popupContainer={reactFlowWrapper}
|
|
|
|
|
node={editingNode}
|
|
|
|
|
isOpen={isEditModalOpen && !isRunning}
|
|
|
|
|
isOpen={isEditModalOpen && !currentAppIsRunning}
|
|
|
|
|
isDelete={isDelete}
|
|
|
|
|
onSave={saveNodeEdit}
|
|
|
|
|
onClose={closeEditModal}
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
{/*统一的添加节点菜单*/}
|
|
|
|
|
{!isRunning && (edgeForNodeAdd || positionForNodeAdd) && (
|
|
|
|
|
{!currentAppIsRunning && (edgeForNodeAdd || positionForNodeAdd) && (
|
|
|
|
|
<div
|
|
|
|
|
style={{
|
|
|
|
|
position: 'absolute',
|
|
|
|
|
|