parent
4786aafddc
commit
cd36924bf4
|
|
@ -1,6 +1,10 @@
|
||||||
import { EdgeLabelRenderer, getBezierPath } from 'reactflow'
|
import { EdgeLabelRenderer, getBezierPath } from 'reactflow'
|
||||||
import { memo } from 'react'
|
import { memo, useState, useContext } from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
import { useDispatch } from 'react-redux'
|
||||||
|
import { SET_DIRTY } from '@/store/actions'
|
||||||
|
import { flowContext } from '@/store/context/ReactFlowContext'
|
||||||
|
import { IconX } from '@tabler/icons-react'
|
||||||
|
|
||||||
function EdgeLabel({ transform, isHumanInput, label, color }) {
|
function EdgeLabel({ transform, isHumanInput, label, color }) {
|
||||||
return (
|
return (
|
||||||
|
|
@ -30,11 +34,23 @@ EdgeLabel.propTypes = {
|
||||||
color: PropTypes.string
|
color: PropTypes.string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const foreignObjectSize = 40
|
||||||
|
|
||||||
const AgentFlowEdge = ({ id, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, data, markerEnd, selected }) => {
|
const AgentFlowEdge = ({ id, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, data, markerEnd, selected }) => {
|
||||||
|
const [isHovered, setIsHovered] = useState(false)
|
||||||
|
const { deleteEdge } = useContext(flowContext)
|
||||||
|
const dispatch = useDispatch()
|
||||||
|
|
||||||
|
const onEdgeClick = (evt, id) => {
|
||||||
|
evt.stopPropagation()
|
||||||
|
deleteEdge(id)
|
||||||
|
dispatch({ type: SET_DIRTY })
|
||||||
|
}
|
||||||
|
|
||||||
const xEqual = sourceX === targetX
|
const xEqual = sourceX === targetX
|
||||||
const yEqual = sourceY === targetY
|
const yEqual = sourceY === targetY
|
||||||
|
|
||||||
const [edgePath] = getBezierPath({
|
const [edgePath, edgeCenterX, edgeCenterY] = getBezierPath({
|
||||||
// we need this little hack in order to display the gradient for a straight line
|
// we need this little hack in order to display the gradient for a straight line
|
||||||
sourceX: xEqual ? sourceX + 0.0001 : sourceX,
|
sourceX: xEqual ? sourceX + 0.0001 : sourceX,
|
||||||
sourceY: yEqual ? sourceY + 0.0001 : sourceY,
|
sourceY: yEqual ? sourceY + 0.0001 : sourceY,
|
||||||
|
|
@ -63,6 +79,8 @@ const AgentFlowEdge = ({ id, sourceX, sourceY, targetX, targetY, sourcePosition,
|
||||||
cursor: 'pointer'
|
cursor: 'pointer'
|
||||||
}}
|
}}
|
||||||
d={edgePath}
|
d={edgePath}
|
||||||
|
onMouseEnter={() => setIsHovered(true)}
|
||||||
|
onMouseLeave={() => setIsHovered(false)}
|
||||||
/>
|
/>
|
||||||
<path
|
<path
|
||||||
id={id}
|
id={id}
|
||||||
|
|
@ -77,6 +95,8 @@ const AgentFlowEdge = ({ id, sourceX, sourceY, targetX, targetY, sourcePosition,
|
||||||
}}
|
}}
|
||||||
d={edgePath}
|
d={edgePath}
|
||||||
markerEnd={markerEnd}
|
markerEnd={markerEnd}
|
||||||
|
onMouseEnter={() => setIsHovered(true)}
|
||||||
|
onMouseLeave={() => setIsHovered(false)}
|
||||||
/>
|
/>
|
||||||
{data?.edgeLabel && (
|
{data?.edgeLabel && (
|
||||||
<EdgeLabelRenderer>
|
<EdgeLabelRenderer>
|
||||||
|
|
@ -88,6 +108,70 @@ const AgentFlowEdge = ({ id, sourceX, sourceY, targetX, targetY, sourcePosition,
|
||||||
/>
|
/>
|
||||||
</EdgeLabelRenderer>
|
</EdgeLabelRenderer>
|
||||||
)}
|
)}
|
||||||
|
{isHovered && (
|
||||||
|
<foreignObject
|
||||||
|
width={foreignObjectSize}
|
||||||
|
height={foreignObjectSize}
|
||||||
|
x={edgeCenterX - foreignObjectSize / 2}
|
||||||
|
y={edgeCenterY - foreignObjectSize / 2}
|
||||||
|
className='edgebutton-foreignobject'
|
||||||
|
requiredExtensions='http://www.w3.org/1999/xhtml'
|
||||||
|
onMouseEnter={() => setIsHovered(true)}
|
||||||
|
onMouseLeave={() => setIsHovered(false)}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
pointerEvents: 'all'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
className='edgebutton'
|
||||||
|
onClick={(event) => onEdgeClick(event, id)}
|
||||||
|
style={{
|
||||||
|
width: '12px',
|
||||||
|
height: '12px',
|
||||||
|
background: `linear-gradient(to right, ${data?.sourceColor || '#ae53ba'}, ${
|
||||||
|
data?.targetColor || '#2a8af6'
|
||||||
|
})`,
|
||||||
|
border: 'none',
|
||||||
|
borderRadius: '50%',
|
||||||
|
cursor: 'pointer',
|
||||||
|
fontSize: '10px',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
color: 'white',
|
||||||
|
boxShadow: '0 0 4px rgba(0,0,0,0.3)',
|
||||||
|
transition: 'all 0.2s ease-in-out',
|
||||||
|
padding: '2px'
|
||||||
|
}}
|
||||||
|
onMouseOver={(e) => {
|
||||||
|
e.currentTarget.style.transform = 'scale(1.2)'
|
||||||
|
e.currentTarget.style.boxShadow = '0 0 8px rgba(0,0,0,0.4)'
|
||||||
|
}}
|
||||||
|
onFocus={(e) => {
|
||||||
|
e.currentTarget.style.transform = 'scale(1.2)'
|
||||||
|
e.currentTarget.style.boxShadow = '0 0 8px rgba(0,0,0,0.4)'
|
||||||
|
}}
|
||||||
|
onMouseOut={(e) => {
|
||||||
|
e.currentTarget.style.transform = 'scale(1)'
|
||||||
|
e.currentTarget.style.boxShadow = '0 0 4px rgba(0,0,0,0.3)'
|
||||||
|
}}
|
||||||
|
onBlur={(e) => {
|
||||||
|
e.currentTarget.style.transform = 'scale(1)'
|
||||||
|
e.currentTarget.style.boxShadow = '0 0 4px rgba(0,0,0,0.3)'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<IconX stroke={2} size='12' color='white' />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</foreignObject>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue