|
|
|
|
@ -1,6 +1,9 @@
|
|
|
|
|
import React from 'react';
|
|
|
|
|
import React, { useState, useEffect, useRef } from 'react';
|
|
|
|
|
import { BaseEdge, EdgeLabelRenderer, EdgeProps, getSmoothStepPath, useReactFlow } from '@xyflow/react';
|
|
|
|
|
import EdgeAddNodeButton from '@/pages/flowEditor/components/edgeAddNodeButton';
|
|
|
|
|
import { getTopicList } from '@/api/event';
|
|
|
|
|
import { useSelector } from 'react-redux';
|
|
|
|
|
import { Message } from '@arco-design/web-react';
|
|
|
|
|
|
|
|
|
|
type DataDisplayEdgeData = {
|
|
|
|
|
label?: string;
|
|
|
|
|
@ -23,6 +26,10 @@ const DataDisplayEdge: React.FC<EdgeProps> = ({
|
|
|
|
|
selected,
|
|
|
|
|
data
|
|
|
|
|
}) => {
|
|
|
|
|
const [options, setOptions] = useState([]);
|
|
|
|
|
const [isOpen, setIsOpen] = useState(false);
|
|
|
|
|
const [selectedValue, setSelectedValue] = useState('');
|
|
|
|
|
const dropdownRef = useRef<HTMLDivElement>(null);
|
|
|
|
|
const [edgePath, labelX, labelY] = getSmoothStepPath({
|
|
|
|
|
sourceX,
|
|
|
|
|
sourceY,
|
|
|
|
|
@ -32,6 +39,7 @@ const DataDisplayEdge: React.FC<EdgeProps> = ({
|
|
|
|
|
targetPosition,
|
|
|
|
|
borderRadius: 8 // 设置圆角半径
|
|
|
|
|
});
|
|
|
|
|
const { info } = useSelector((state: any) => state.ideContainer);
|
|
|
|
|
|
|
|
|
|
// 从数据中获取悬停状态
|
|
|
|
|
const hovered = data?.hovered || false;
|
|
|
|
|
@ -61,8 +69,35 @@ const DataDisplayEdge: React.FC<EdgeProps> = ({
|
|
|
|
|
}));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleDataClick = (e) => {
|
|
|
|
|
console.log('click:', e);
|
|
|
|
|
const getEventList = async () => {
|
|
|
|
|
const res: any = await getTopicList(info.id);
|
|
|
|
|
if (res.code === 200) {
|
|
|
|
|
setOptions(res.data.map(v => {
|
|
|
|
|
return { label: v.eventName, value: v.topic };
|
|
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
getEventList();
|
|
|
|
|
}, [displayData]);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
const handleClickOutside = (event: MouseEvent) => {
|
|
|
|
|
if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
|
|
|
|
|
setIsOpen(false);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
document.addEventListener('mousedown', handleClickOutside);
|
|
|
|
|
return () => {
|
|
|
|
|
document.removeEventListener('mousedown', handleClickOutside);
|
|
|
|
|
};
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
const handleSelect = (option) => {
|
|
|
|
|
setSelectedValue(option.label);
|
|
|
|
|
setIsOpen(false);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
@ -89,29 +124,60 @@ const DataDisplayEdge: React.FC<EdgeProps> = ({
|
|
|
|
|
{/* 数据展示框 */}
|
|
|
|
|
{displayData && Object.keys(displayData).length > 0 && (
|
|
|
|
|
<div
|
|
|
|
|
onClick={(e) => handleDataClick(e)}
|
|
|
|
|
ref={dropdownRef}
|
|
|
|
|
style={{
|
|
|
|
|
background: '#ffffff',
|
|
|
|
|
border: '1px solid #ddd',
|
|
|
|
|
width: 150,
|
|
|
|
|
border: isOpen ? '1px solid #1890ff' : '1px solid #d9d9d9',
|
|
|
|
|
borderRadius: 4,
|
|
|
|
|
padding: 4,
|
|
|
|
|
boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
|
|
|
|
|
minWidth: 100,
|
|
|
|
|
marginBottom: 4,
|
|
|
|
|
fontSize: 12,
|
|
|
|
|
textAlign: 'center'
|
|
|
|
|
backgroundColor: '#fff',
|
|
|
|
|
position: 'relative'
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{displayData.name && (
|
|
|
|
|
<div style={{ fontWeight: 'bold', marginBottom: 2 }}>
|
|
|
|
|
{displayData.name}
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
{displayData.value !== undefined && (
|
|
|
|
|
<div>
|
|
|
|
|
{typeof displayData.value === 'object'
|
|
|
|
|
? JSON.stringify(displayData.value)
|
|
|
|
|
: String(displayData.value)}
|
|
|
|
|
<div
|
|
|
|
|
onClick={() => setIsOpen(!isOpen)}
|
|
|
|
|
style={{
|
|
|
|
|
padding: '4px 11px',
|
|
|
|
|
cursor: 'pointer',
|
|
|
|
|
display: 'flex',
|
|
|
|
|
justifyContent: 'space-between',
|
|
|
|
|
alignItems: 'center'
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<span>{selectedValue || displayData.name}</span>
|
|
|
|
|
<span>{isOpen ? '▲' : '▼'}</span>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{isOpen && (
|
|
|
|
|
<div
|
|
|
|
|
style={{
|
|
|
|
|
position: 'absolute',
|
|
|
|
|
top: '105%',
|
|
|
|
|
left: 0,
|
|
|
|
|
right: 0,
|
|
|
|
|
border: '1px solid #d9d9d9',
|
|
|
|
|
borderTop: 'none',
|
|
|
|
|
borderRadius: '0 0 4px 4px',
|
|
|
|
|
backgroundColor: '#fff',
|
|
|
|
|
zIndex: 1000,
|
|
|
|
|
maxHeight: 200,
|
|
|
|
|
overflowY: 'auto'
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{options.map((option: { value: string; label: string }) => (
|
|
|
|
|
<div
|
|
|
|
|
key={option.value}
|
|
|
|
|
onClick={() => handleSelect(option)}
|
|
|
|
|
style={{
|
|
|
|
|
padding: '5px 12px',
|
|
|
|
|
cursor: 'pointer',
|
|
|
|
|
borderBottom: '1px solid #f0f0f0'
|
|
|
|
|
}}
|
|
|
|
|
onMouseEnter={(e) => e.currentTarget.style.backgroundColor = '#f5f5f5'}
|
|
|
|
|
onMouseLeave={(e) => e.currentTarget.style.backgroundColor = '#fff'}
|
|
|
|
|
>
|
|
|
|
|
{option.label}
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
|