From 2f40a83b47527de2adffc6c55f2d0db8f8b592c0 Mon Sep 17 00:00:00 2001 From: moklick Date: Thu, 5 Nov 2020 17:28:21 +0100 Subject: [PATCH] refactor(drag-edge): cleanup drag edge handlers --- src/components/Edges/wrapEdge.tsx | 58 ++++++++++++++++++---------- src/components/Handle/BaseHandle.tsx | 2 +- src/container/EdgeRenderer/index.tsx | 31 ++------------- src/types/index.ts | 7 ++-- src/utils/graph.ts | 13 +------ 5 files changed, 47 insertions(+), 64 deletions(-) diff --git a/src/components/Edges/wrapEdge.tsx b/src/components/Edges/wrapEdge.tsx index 0c6537cd..5b4e90be 100644 --- a/src/components/Edges/wrapEdge.tsx +++ b/src/components/Edges/wrapEdge.tsx @@ -2,7 +2,8 @@ import React, { memo, ComponentType, useCallback } from 'react'; import cc from 'classcat'; import { useStoreActions } from '../../store/hooks'; -import { Edge, EdgeProps, WrapEdgeProps } from '../../types'; +import { Edge, EdgeProps, WrapEdgeProps, Connection } from '../../types'; +import { onMouseDown } from '../../components/Handle/BaseHandle'; export default (EdgeComponent: ComponentType) => { const EdgeWrapper = ({ @@ -32,9 +33,13 @@ export default (EdgeComponent: ComponentType) => { elementsSelectable, markerEndId, isHidden, - onEitherEndOfEdgePress, + sourceHandleId, + targetHandleId, + onEdgeUpdate, }: WrapEdgeProps) => { const addSelectedElements = useStoreActions((actions) => actions.addSelectedElements); + const setConnectionNodeId = useStoreActions((actions) => actions.setConnectionNodeId); + const setPosition = useStoreActions((actions) => actions.setConnectionPosition); const inactive = !elementsSelectable && !onClick; const edgeClasses = cc([ @@ -63,35 +68,46 @@ export default (EdgeComponent: ComponentType) => { [elementsSelectable, id, source, target, type, data, onClick] ); - const handleEdgeUpdaterMouseDown = useCallback( - (event: React.MouseEvent, isEdgeHeader?: boolean): void => { - if (elementsSelectable) { - addSelectedElements({ id, source, target }); - } + const handleEdgeUpdater = useCallback( + (event: React.MouseEvent, isSourceHandle: boolean) => { + const nodeId = isSourceHandle ? target : source; + const handleId = isSourceHandle ? targetHandleId : sourceHandleId; - const edgeElement: Edge = { id, source, target, type }; + const onConnect = (connection: Connection) => { + if (onEdgeUpdate) { + const edgeElement: Edge = { + id, + source, + target, + sourceHandle: sourceHandleId, + targetHandle: targetHandleId, + type, + }; - if (typeof data !== 'undefined') { - edgeElement.data = data; - } + onEdgeUpdate(edgeElement, connection); + } + }; - onEitherEndOfEdgePress(event, edgeElement, isEdgeHeader); + const isValidConnection = () => true; + const isTarget = isSourceHandle; + + onMouseDown(event, handleId, nodeId, setConnectionNodeId, setPosition, onConnect, isTarget, isValidConnection); }, - [elementsSelectable, id, source, target, type, data, onEitherEndOfEdgePress] + [id, source, target, type, sourceHandleId, targetHandleId, setConnectionNodeId, setPosition] ); - const handleEdgeTargetMouseDown = useCallback( + const onEdgeUpdaterSourceMouseDown = useCallback( (event: React.MouseEvent): void => { - handleEdgeUpdaterMouseDown(event, true); + handleEdgeUpdater(event, true); }, - [handleEdgeUpdaterMouseDown] + [id, source, sourceHandleId, handleEdgeUpdater] ); - const handleEdgeSourceMouseDown = useCallback( + const onEdgeUpdaterTargetMouseDown = useCallback( (event: React.MouseEvent): void => { - handleEdgeUpdaterMouseDown(event); + handleEdgeUpdater(event, false); }, - [handleEdgeUpdaterMouseDown] + [id, target, targetHandleId, handleEdgeUpdater] ); if (isHidden) { @@ -100,7 +116,7 @@ export default (EdgeComponent: ComponentType) => { return ( - + ) => { targetPosition={targetPosition} markerEndId={markerEndId} /> - + void + elementsSelectable: boolean ) { const sourceId = edge.source; const sourceHandleId = edge.sourceHandle || null; @@ -192,22 +188,6 @@ function renderEdge( const isSelected = selectedElements ? selectedElements.some((elm) => isEdge(elm) && elm.id === edge.id) : false; - const onConnect = (connection: Connection) => { - const { onEdgeUpdate } = props; - if (onEdgeUpdate) { - onEdgeUpdate(edge, connection); - } - }; - - const handleEitherEndOfEdgePress = (event: React.MouseEvent, edge: Edge, isEdgeHeader = false) => { - const { source, target } = edge; - const nodeId = isEdgeHeader ? source : target; - const isValidConnection = () => true; - const isTarget = !isEdgeHeader; - - onMouseDown(event, null, nodeId, setConnectionNodeId, setPosition, onConnect, isTarget, isValidConnection); - }; - return ( ); } @@ -257,8 +236,6 @@ const EdgeRenderer = (props: EdgeRendererProps) => { const elementsSelectable = useStoreState((state) => state.elementsSelectable); const width = useStoreState((state) => state.width); const height = useStoreState((state) => state.height); - const setConnectionNodeId = useStoreActions((actions) => actions.setConnectionNodeId); - const setPosition = useStoreActions((actions) => actions.setConnectionPosition); const { connectionLineType, arrowHeadColor, connectionLineStyle, connectionLineComponent } = props; @@ -273,9 +250,7 @@ const EdgeRenderer = (props: EdgeRendererProps) => { - {edges.map((edge: Edge) => - renderEdge(edge, props, nodes, selectedElements, elementsSelectable, setConnectionNodeId, setPosition) - )} + {edges.map((edge: Edge) => renderEdge(edge, props, nodes, selectedElements, elementsSelectable))} {renderConnectionLine && ( void; + onEdgeUpdate?: OnEdgeUpdateFunc; } export interface EdgeProps { @@ -322,4 +323,4 @@ export type FlowTransform = { export type TranslateExtent = [[number, number], [number, number]]; -export type OnEdgeUpdateFunc = (oldEdge: Edge, newConnection: Connection) => void; \ No newline at end of file +export type OnEdgeUpdateFunc = (oldEdge: Edge, newConnection: Connection) => void; diff --git a/src/utils/graph.ts b/src/utils/graph.ts index e0fb57d4..93815b2e 100644 --- a/src/utils/graph.ts +++ b/src/utils/graph.ts @@ -82,16 +82,8 @@ export const updateEdge = (oldEdge: Edge, newConnection: Connection, elements: E throw new Error("Can't create new edge. An edge needs a source and a target."); } - // make sure that there is node with the target and one with the source id - [newConnection.source, newConnection.target].forEach((id) => { - const nodeId = id.includes('__') ? id.split('__')[0] : id; + const foundEdge = elements.find((e) => isEdge(e) && e.id === oldEdge.id) as Edge; - if (!elements.find((e) => isNode(e) && e.id === nodeId)) { - throw new Error(`Can't create edge. Node with id=${nodeId} does not exist.`); - } - }); - - const foundEdge = elements.find(e => isEdge(e) && e.id === oldEdge.id) as Edge; if (!foundEdge) { throw new Error(`The old edge with id=${oldEdge.id} does not exist.`); } @@ -104,10 +96,9 @@ export const updateEdge = (oldEdge: Edge, newConnection: Connection, elements: E target: newConnection.target, } as Edge; - return elements.filter(e => e.id !== oldEdge.id).concat(edge); + return elements.filter((e) => e.id !== oldEdge.id).concat(edge); }; - export const pointToRendererPoint = ( { x, y }: XYPosition, [tx, ty, tScale]: Transform,