|
|
import React from 'react';
|
|
|
import { Menu, Message } from '@arco-design/web-react';
|
|
|
import { Node } from '@xyflow/react';
|
|
|
import { isJSON } from '@/utils/common';
|
|
|
import { stepRunEvent } from '@/api/apps';
|
|
|
|
|
|
interface NodeContextMenuProps {
|
|
|
node: Node;
|
|
|
onRename?: (node: Node) => void;
|
|
|
onDelete?: (node: Node) => void;
|
|
|
onCopy?: (node: Node) => void;
|
|
|
onEdit?: (node: Node) => void;
|
|
|
onCloseMenu?: (data: React.Dispatch<React.SetStateAction<any>>) => void;
|
|
|
onCloseOpenModal?: (boolean: boolean) => void;
|
|
|
}
|
|
|
|
|
|
const NodeContextMenu: React.FC<NodeContextMenuProps> = ({
|
|
|
node,
|
|
|
onDelete,
|
|
|
onCopy,
|
|
|
onEdit,
|
|
|
onCloseMenu,
|
|
|
onCloseOpenModal
|
|
|
}) => {
|
|
|
const handleDelete = () => {
|
|
|
onDelete && onDelete(node);
|
|
|
onCloseOpenModal(false);
|
|
|
onCloseMenu(null);
|
|
|
};
|
|
|
|
|
|
const handleCopy = () => {
|
|
|
onCopy && onCopy(node);
|
|
|
onCloseOpenModal(false);
|
|
|
onCloseMenu(null);
|
|
|
};
|
|
|
|
|
|
const handleEdit = () => {
|
|
|
// 判断节点类型,如果是SUB类型则打开新标签页
|
|
|
if (node.type === 'SUB') {
|
|
|
// 创建自定义事件来通知打开新标签页
|
|
|
const customDef = isJSON((node as any).data.component.customDef) ? JSON.parse((node as any).data.component.customDef) : {};
|
|
|
if (Object.keys(customDef).length === 0) {
|
|
|
Message.warning('新导入的复合组件请保存后再进行编辑!');
|
|
|
}
|
|
|
const openTabEvent = new CustomEvent('openSubNodeTab', {
|
|
|
detail: { node }
|
|
|
});
|
|
|
document.dispatchEvent(openTabEvent);
|
|
|
}
|
|
|
else {
|
|
|
onEdit && onEdit(node);
|
|
|
onCloseOpenModal(true);
|
|
|
}
|
|
|
onCloseMenu(null);
|
|
|
};
|
|
|
|
|
|
// 单步执行事件
|
|
|
const handleStepRun = async () => {
|
|
|
try {
|
|
|
// 从节点的 component.customDef 中获取事件ID
|
|
|
let eventId = '';
|
|
|
const customDef = (node as any).data?.component?.customDef;
|
|
|
if (customDef) {
|
|
|
if (typeof customDef === 'string') {
|
|
|
const parsed = isJSON(customDef) ? JSON.parse(customDef) : {};
|
|
|
eventId = parsed.eventId || '';
|
|
|
} else {
|
|
|
eventId = customDef.eventId || '';
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (!eventId) {
|
|
|
Message.warning('该节点未配置事件,请先选择事件');
|
|
|
onCloseMenu(null);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
await stepRunEvent({ eventId });
|
|
|
Message.success('单步执行已触发');
|
|
|
} catch (error: any) {
|
|
|
Message.error(error?.message || '单步执行失败');
|
|
|
}
|
|
|
onCloseMenu(null);
|
|
|
};
|
|
|
|
|
|
// 根据节点类型和其他条件动态生成菜单项
|
|
|
const renderMenuItems = () => {
|
|
|
const menuItems = [];
|
|
|
// if (!useDefault) return;
|
|
|
|
|
|
// 对于非开始和结束节点,添加基本操作
|
|
|
if (!['start', 'end'].includes(node?.type)) {
|
|
|
if (!['AND', 'OR', 'JSON2STR', 'STR2JSON', 'IMAGE', 'RESULT', 'LOOP_START'].includes(node.data.type as string)) {
|
|
|
menuItems.push(
|
|
|
<Menu.Item key="edit" onClick={handleEdit}>
|
|
|
编辑节点
|
|
|
</Menu.Item>
|
|
|
);
|
|
|
}
|
|
|
|
|
|
menuItems.push(
|
|
|
<Menu.Item key="copy" onClick={handleCopy}>
|
|
|
复制节点
|
|
|
</Menu.Item>
|
|
|
);
|
|
|
menuItems.push(
|
|
|
<Menu.Item key="delete" onClick={handleDelete}>
|
|
|
删除节点
|
|
|
</Menu.Item>
|
|
|
);
|
|
|
|
|
|
// 单步执行 - 仅对事件接收节点显示
|
|
|
if (node.data.type === 'EVENTLISTENE') {
|
|
|
menuItems.push(
|
|
|
<Menu.Item key="step-run" onClick={handleStepRun}>
|
|
|
单步执行
|
|
|
</Menu.Item>
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 可以根据节点类型添加特定的操作
|
|
|
if (node?.type === 'special') {
|
|
|
menuItems.push(
|
|
|
<Menu.Item key="special-action">
|
|
|
特殊操作
|
|
|
</Menu.Item>
|
|
|
);
|
|
|
}
|
|
|
|
|
|
return menuItems;
|
|
|
};
|
|
|
|
|
|
return (
|
|
|
<Menu>
|
|
|
{renderMenuItems()}
|
|
|
</Menu>
|
|
|
);
|
|
|
};
|
|
|
|
|
|
export default NodeContextMenu;
|