You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

142 lines
4.1 KiB
TypeScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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;