|
|
|
|
@ -1,9 +1,18 @@
|
|
|
|
|
import React, { useState, useEffect } from 'react';
|
|
|
|
|
import { Node } from '@xyflow/react';
|
|
|
|
|
import { Modal, Button } from '@arco-design/web-react';
|
|
|
|
|
import { Modal, Input, Form, Select } from '@arco-design/web-react';
|
|
|
|
|
|
|
|
|
|
interface NodeData {
|
|
|
|
|
type?: string;
|
|
|
|
|
title?: string;
|
|
|
|
|
parameters?: any;
|
|
|
|
|
component?: any;
|
|
|
|
|
|
|
|
|
|
[key: string]: any;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface NodeEditModalProps {
|
|
|
|
|
node: Node | any;
|
|
|
|
|
node: Node<NodeData>;
|
|
|
|
|
isOpen: boolean;
|
|
|
|
|
onSave: (data: any) => void;
|
|
|
|
|
onClose: () => void;
|
|
|
|
|
@ -15,12 +24,12 @@ const NodeEditModal: React.FC<NodeEditModalProps> = ({
|
|
|
|
|
onSave,
|
|
|
|
|
onClose
|
|
|
|
|
}) => {
|
|
|
|
|
const [title, setTitle] = useState('');
|
|
|
|
|
const [visible, setVisible] = React.useState(false);
|
|
|
|
|
const [nodeData, setNodeData] = useState<NodeData>({});
|
|
|
|
|
const [visible, setVisible] = useState(false);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (node) {
|
|
|
|
|
setTitle(node.data?.title || '');
|
|
|
|
|
setNodeData(node.data || {});
|
|
|
|
|
}
|
|
|
|
|
}, [node]);
|
|
|
|
|
|
|
|
|
|
@ -32,7 +41,7 @@ const NodeEditModal: React.FC<NodeEditModalProps> = ({
|
|
|
|
|
|
|
|
|
|
const handleSave = () => {
|
|
|
|
|
setVisible(false);
|
|
|
|
|
onSave({ title });
|
|
|
|
|
onSave(nodeData);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleClose = () => {
|
|
|
|
|
@ -40,66 +49,59 @@ const NodeEditModal: React.FC<NodeEditModalProps> = ({
|
|
|
|
|
onClose();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 更新节点数据的通用函数
|
|
|
|
|
const updateNodeData = (key: string, value: any) => {
|
|
|
|
|
setNodeData(prev => ({
|
|
|
|
|
...prev,
|
|
|
|
|
[key]: value
|
|
|
|
|
}));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 根据节点类型渲染不同的内容
|
|
|
|
|
const renderContent = () => {
|
|
|
|
|
const nodeType = node?.type || 'basic';
|
|
|
|
|
|
|
|
|
|
switch (nodeType) {
|
|
|
|
|
case 'start':
|
|
|
|
|
return (
|
|
|
|
|
<div>
|
|
|
|
|
<h4>开始节点设置</h4>
|
|
|
|
|
<div>
|
|
|
|
|
<label>节点标题:</label>
|
|
|
|
|
<input
|
|
|
|
|
type="text"
|
|
|
|
|
value={title}
|
|
|
|
|
onChange={(e) => setTitle(e.target.value)}
|
|
|
|
|
style={{ width: '100%', padding: '8px', margin: '10px 0' }}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
case 'end':
|
|
|
|
|
return (
|
|
|
|
|
<div>
|
|
|
|
|
<h4>结束节点设置</h4>
|
|
|
|
|
<div>
|
|
|
|
|
<label>节点标题:</label>
|
|
|
|
|
<input
|
|
|
|
|
type="text"
|
|
|
|
|
value={title}
|
|
|
|
|
onChange={(e) => setTitle(e.target.value)}
|
|
|
|
|
style={{ width: '100%', padding: '8px', margin: '10px 0' }}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
case 'basic':
|
|
|
|
|
default:
|
|
|
|
|
return (
|
|
|
|
|
<div>
|
|
|
|
|
<h4>基础节点设置</h4>
|
|
|
|
|
<div>
|
|
|
|
|
<label>节点标题:</label>
|
|
|
|
|
<input
|
|
|
|
|
type="text"
|
|
|
|
|
value={title}
|
|
|
|
|
onChange={(e) => setTitle(e.target.value)}
|
|
|
|
|
style={{ width: '100%', padding: '8px', margin: '10px 0' }}
|
|
|
|
|
<Form layout="vertical">
|
|
|
|
|
<Form.Item label="节点标题">
|
|
|
|
|
<Input
|
|
|
|
|
value={nodeData.title || ''}
|
|
|
|
|
onChange={(value) => updateNodeData('title', value)}
|
|
|
|
|
/>
|
|
|
|
|
</Form.Item>
|
|
|
|
|
<Form.Item label="描述">
|
|
|
|
|
<Input.TextArea
|
|
|
|
|
value={nodeData.description || ''}
|
|
|
|
|
onChange={(value) => updateNodeData('description', value)}
|
|
|
|
|
/>
|
|
|
|
|
</Form.Item>
|
|
|
|
|
<Form.Item label="节点类型">
|
|
|
|
|
<Select
|
|
|
|
|
value={nodeData.category || ''}
|
|
|
|
|
onChange={(value) => updateNodeData('category', value)}
|
|
|
|
|
options={[
|
|
|
|
|
{ label: '数据处理', value: 'data' },
|
|
|
|
|
{ label: '逻辑判断', value: 'logic' },
|
|
|
|
|
{ label: '外部接口', value: 'api' }
|
|
|
|
|
]}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</Form.Item>
|
|
|
|
|
</Form>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Modal
|
|
|
|
|
title={'节点标题:' + title}
|
|
|
|
|
title={`编辑节点: ${nodeData.title || node?.type || '未知类型'}`}
|
|
|
|
|
visible={visible}
|
|
|
|
|
onOk={() => handleSave()}
|
|
|
|
|
onCancel={() => handleClose()}
|
|
|
|
|
onOk={handleSave}
|
|
|
|
|
onCancel={handleClose}
|
|
|
|
|
autoFocus={false}
|
|
|
|
|
focusLock={true}
|
|
|
|
|
>
|
|
|
|
|
|