feat(flow):为多种节点类型添加运行状态指示器

master
钟良源 4 months ago
parent c13e0c1619
commit 28b423e208

@ -3,6 +3,8 @@ import { useStore } from '@xyflow/react';
import styles from '@/components/FlowEditor/node/style/baseOther.module.less';
import DynamicIcon from '@/components/DynamicIcon';
import NodeContentCode from '@/pages/flowEditor/components/nodeContentCode';
import NodeStatusIndicator, { NodeStatus } from '@/components/FlowEditor/NodeStatusIndicator';
import { useStore as useFlowStore } from '@xyflow/react';
const setIcon = () => {
return <DynamicIcon type="IconCode" style={{ fontSize: '16px', marginRight: '5px' }} />;
@ -15,12 +17,23 @@ const CodeNode = ({ data, id }: { data: any; id: string }) => {
const isSelected = useStore((state) =>
state.nodeLookup.get(id)?.selected || false
);
// 获取节点运行状态
const nodeStatus: NodeStatus = useFlowStore((state) =>
(state.nodeLookup.get(id)?.data?.status as NodeStatus) || 'waiting'
);
// 获取运行状态可见性
const isStatusVisible = useFlowStore((state) =>
!!state.nodeLookup.get(id)?.data?.isStatusVisible
);
return (
<div className={`${styles['node-container']} ${isSelected ? styles.selected : ''}`}>
<div className={styles['node-header']} style={{ backgroundColor: '#1890ff' }}>
{setIcon()}
{title}
<NodeStatusIndicator status={nodeStatus} isVisible={isStatusVisible} />
</div>
<NodeContentCode data={data} />
</div>

@ -1,9 +1,10 @@
import React from 'react';
import { useStore } from '@xyflow/react';
// import styles from '@/pages/flowEditor/node/style/base.module.less';
import styles from '@/components/FlowEditor/node/style/baseOther.module.less';
import DynamicIcon from '@/components/DynamicIcon';
import NodeContentImage from '@/pages/flowEditor/components/nodeContentImage';
import NodeStatusIndicator, { NodeStatus } from '@/components/FlowEditor/NodeStatusIndicator';
import { useStore as useFlowStore } from '@xyflow/react';
const setIcon = () => {
return <DynamicIcon type="IconImage" style={{ fontSize: '16px', marginRight: '5px' }} />;
@ -16,12 +17,23 @@ const ImageNode = ({ data, id }: { data: any; id: string }) => {
const isSelected = useStore((state) =>
state.nodeLookup.get(id)?.selected || false
);
// 获取节点运行状态
const nodeStatus: NodeStatus = useFlowStore((state) =>
(state.nodeLookup.get(id)?.data?.status as NodeStatus) || 'waiting'
);
// 获取运行状态可见性
const isStatusVisible = useFlowStore((state) =>
!!state.nodeLookup.get(id)?.data?.isStatusVisible
);
return (
<div className={`${styles['node-container']} ${isSelected ? styles.selected : ''}`}>
<div className={styles['node-header']} style={{ backgroundColor: '#1890ff' }}>
{setIcon()}
{title}
<NodeStatusIndicator status={nodeStatus} isVisible={isStatusVisible} />
</div>
<NodeContentImage data={data} />
</div>

@ -4,13 +4,23 @@ import StartNode from './startNode/StartNode';
import EndNode from './endNode/EndNode';
import BasicNode from './basicNode/BasicNode';
import AppNode from './appNode/AppNode';
import CodeNode from './codeNode/CodeNode';
import ImageNode from './imageNode/ImageNode';
import RestNode from './restNode/RestNode';
import SwitchNode from './switchNode/SwitchNode';
import LoopNode from './loopNode/LoopNode';
// 定义所有可用的节点类型
export const nodeTypes: NodeTypes = {
start: StartNode,
end: EndNode,
BASIC: BasicNode,
APP: AppNode
APP: AppNode,
CODE: CodeNode,
IMAGE: ImageNode,
REST: RestNode,
SWITCH: SwitchNode,
LOOP: LoopNode
};
// 节点类型映射,用于创建节点时的类型查找
@ -18,7 +28,12 @@ export const nodeTypeMap: Record<string, string> = {
'start': 'start',
'end': 'end',
'basic': 'BASIC',
'app': 'APP'
'app': 'APP',
'code': 'CODE',
'image': 'IMAGE',
'rest': 'REST',
'switch': 'SWITCH',
'loop': 'LOOP'
};
// 节点显示名称映射
@ -26,7 +41,12 @@ export const nodeTypeNameMap: Record<string, string> = {
'start': '开始节点',
'end': '结束节点',
'basic': '基础节点',
'app': '应用节点'
'app': '应用节点',
'code': '代码节点',
'image': '图片节点',
'rest': 'REST节点',
'switch': '条件节点',
'loop': '循环节点'
};
// 注册新节点类型的函数

@ -67,12 +67,12 @@ const LocalNode = ({ data, id }: { data: any; id: string }) => {
);
// 获取节点运行状态
const nodeStatus: NodeStatus = useFlowStore((state) =>
const nodeStatus: NodeStatus = useFlowStore((state) =>
(state.nodeLookup.get(id)?.data?.status as NodeStatus) || 'waiting'
);
// 获取运行状态可见性
const isStatusVisible = useFlowStore((state) =>
const isStatusVisible = useFlowStore((state) =>
!!state.nodeLookup.get(id)?.data?.isStatusVisible
);

@ -5,6 +5,8 @@ import DynamicIcon from '@/components/DynamicIcon';
import { Handle, Position } from '@xyflow/react';
import NodeContentLoop from '@/pages/flowEditor/components/nodeContentLoop';
import { defaultNodeTypes } from '@/components/FlowEditor/node/types/defaultType';
import NodeStatusIndicator, { NodeStatus } from '@/components/FlowEditor/NodeStatusIndicator';
import { useStore as useFlowStore } from '@xyflow/react';
// 循环节点组件,用于显示循环开始和循环结束节点
const LoopNode = ({ data, id }: { data: defaultNodeTypes; id: string }) => {
@ -16,6 +18,16 @@ const LoopNode = ({ data, id }: { data: defaultNodeTypes; id: string }) => {
const isSelected = useStore((state) =>
state.nodeLookup.get(id)?.selected || false
);
// 获取节点运行状态
const nodeStatus: NodeStatus = useFlowStore((state) =>
(state.nodeLookup.get(id)?.data?.status as NodeStatus) || 'waiting'
);
// 获取运行状态可见性
const isStatusVisible = useFlowStore((state) =>
!!state.nodeLookup.get(id)?.data?.isStatusVisible
);
// 设置图标
const setIcon = () => {
@ -150,6 +162,7 @@ const LoopNode = ({ data, id }: { data: defaultNodeTypes; id: string }) => {
<div className={styles['node-header']} style={{ backgroundColor: '#1890ff' }}>
{setIcon()}
{title}
<NodeStatusIndicator status={nodeStatus} isVisible={isStatusVisible} />
</div>
{/* 顶部连接点,用于标识循环开始和结束节点是一组 */}

@ -3,28 +3,41 @@ import { useStore } from '@xyflow/react';
import styles from '@/components/FlowEditor/node/style/baseOther.module.less';
import DynamicIcon from '@/components/DynamicIcon';
import NodeContentREST from '@/pages/flowEditor/components/nodeContentREST';
import NodeStatusIndicator, { NodeStatus } from '@/components/FlowEditor/NodeStatusIndicator';
import { useStore as useFlowStore } from '@xyflow/react';
const setIcon = () => {
return <DynamicIcon type="IconCloudDownload" style={{ fontSize: '16px', marginRight: '5px' }} />;
};
const CodeNode = ({ data, id }: { data: any; id: string }) => {
const RestNode = ({ data, id }: { data: any; id: string }) => {
const title = data.title || 'REST调用';
// 获取节点选中状态 - 适配React Flow v12 API
const isSelected = useStore((state) =>
state.nodeLookup.get(id)?.selected || false
);
// 获取节点运行状态
const nodeStatus: NodeStatus = useFlowStore((state) =>
(state.nodeLookup.get(id)?.data?.status as NodeStatus) || 'waiting'
);
// 获取运行状态可见性
const isStatusVisible = useFlowStore((state) =>
!!state.nodeLookup.get(id)?.data?.isStatusVisible
);
return (
<div className={`${styles['node-container']} ${isSelected ? styles.selected : ''}`}>
<div className={styles['node-header']} style={{ backgroundColor: '#1890ff' }}>
{setIcon()}
{title}
<NodeStatusIndicator status={nodeStatus} isVisible={isStatusVisible} />
</div>
<NodeContentREST data={data} />
</div>
);
};
export default CodeNode;
export default RestNode;

@ -5,6 +5,8 @@ import DynamicIcon from '@/components/DynamicIcon';
import { Handle, Position } from '@xyflow/react';
import NodeContentSwitch from '@/pages/flowEditor/components/nodeContentSwitch';
import { defaultNodeTypes } from '@/components/FlowEditor/node/types/defaultType';
import NodeStatusIndicator, { NodeStatus } from '@/components/FlowEditor/NodeStatusIndicator';
import { useStore as useFlowStore } from '@xyflow/react';
// 循环节点组件,用于显示循环开始和循环结束节点
const SwitchNode = ({ data, id }: { data: defaultNodeTypes; id: string }) => {
@ -15,6 +17,16 @@ const SwitchNode = ({ data, id }: { data: defaultNodeTypes; id: string }) => {
const isSelected = useStore((state) =>
state.nodeLookup.get(id)?.selected || false
);
// 获取节点运行状态
const nodeStatus: NodeStatus = useFlowStore((state) =>
(state.nodeLookup.get(id)?.data?.status as NodeStatus) || 'waiting'
);
// 获取运行状态可见性
const isStatusVisible = useFlowStore((state) =>
!!state.nodeLookup.get(id)?.data?.isStatusVisible
);
// 设置图标
const setIcon = () => {
@ -147,6 +159,7 @@ const SwitchNode = ({ data, id }: { data: defaultNodeTypes; id: string }) => {
<div className={styles['node-header']} style={{ backgroundColor: '#1890ff' }}>
{setIcon()}
{title}
<NodeStatusIndicator status={nodeStatus} isVisible={isStatusVisible} />
</div>
<NodeContentSwitch data={modifiedData} />

Loading…
Cancel
Save