Fix edge design on hover (#14061)
## Before https://github.com/user-attachments/assets/d44c9c20-fcf0-4f79-8ebf-8e03202c3559 ## After https://github.com/user-attachments/assets/ac7ef2ff-585e-49c1-96f9-63d6bea8de3f
This commit is contained in:
+9
-3
@@ -1,7 +1,7 @@
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { BaseEdge, type EdgeProps } from '@xyflow/react';
|
||||
import { type WorkflowDiagramEdge } from '@/workflow/workflow-diagram/types/WorkflowDiagram';
|
||||
import { useEdgeSelected } from '@/workflow/workflow-diagram/hooks/useEdgeSelected';
|
||||
import { useEdgeState } from '@/workflow/workflow-diagram/hooks/useEdgeState';
|
||||
|
||||
type WorkflowDiagramBaseEdgeProps = Pick<
|
||||
EdgeProps<WorkflowDiagramEdge>,
|
||||
@@ -19,11 +19,17 @@ export const WorkflowDiagramBaseEdge = ({
|
||||
}: WorkflowDiagramBaseEdgeProps) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const { isEdgeSelected } = useEdgeSelected();
|
||||
const { isEdgeSelected, isEdgeHovered } = useEdgeState();
|
||||
|
||||
const selected = isEdgeSelected({ source, target });
|
||||
|
||||
const stroke = selected ? theme.color.blue : theme.border.color.strong;
|
||||
const isHovered = isEdgeHovered({ source, target });
|
||||
|
||||
const stroke = selected
|
||||
? theme.color.blue
|
||||
: isHovered
|
||||
? theme.font.color.light
|
||||
: theme.border.color.strong;
|
||||
|
||||
return (
|
||||
<BaseEdge
|
||||
|
||||
+12
-6
@@ -7,7 +7,6 @@ import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state
|
||||
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
|
||||
import { WorkflowDiagramCustomMarkers } from '@/workflow/workflow-diagram/components/WorkflowDiagramCustomMarkers';
|
||||
import { WorkflowDiagramRightClickCommandMenu } from '@/workflow/workflow-diagram/components/WorkflowDiagramRightClickCommandMenu';
|
||||
import { useEdgeHovered } from '@/workflow/workflow-diagram/hooks/useEdgeHovered';
|
||||
import { useRightDrawerState } from '@/workflow/workflow-diagram/hooks/useRightDrawerState';
|
||||
import { workflowDiagramComponentState } from '@/workflow/workflow-diagram/states/workflowDiagramComponentState';
|
||||
import { workflowDiagramPanOnDragComponentState } from '@/workflow/workflow-diagram/states/workflowDiagramPanOnDragComponentState';
|
||||
@@ -55,6 +54,7 @@ import { isDefined } from 'twenty-shared/utils';
|
||||
import { Tag, type TagColor } from 'twenty-ui/components';
|
||||
import { THEME_COMMON } from 'twenty-ui/theme';
|
||||
import { FeatureFlagKey } from '~/generated/graphql';
|
||||
import { useEdgeState } from '@/workflow/workflow-diagram/hooks/useEdgeState';
|
||||
|
||||
const StyledResetReactflowStyles = styled.div`
|
||||
height: 100%;
|
||||
@@ -178,7 +178,7 @@ export const WorkflowDiagramCanvasBase = ({
|
||||
workflowDiagramWaitingNodesDimensionsComponentState,
|
||||
);
|
||||
|
||||
const { setEdgeHovered, setNoEdgeHovered } = useEdgeHovered();
|
||||
const { setEdgeHovered, clearEdgeHover } = useEdgeState();
|
||||
|
||||
const isWorkflowBranchEnabled = useIsFeatureEnabled(
|
||||
FeatureFlagKey.IS_WORKFLOW_BRANCH_ENABLED,
|
||||
@@ -444,15 +444,21 @@ export const WorkflowDiagramCanvasBase = ({
|
||||
);
|
||||
|
||||
const onEdgeMouseEnter = useCallback(
|
||||
(_: React.MouseEvent<Element, MouseEvent>, edge: WorkflowDiagramEdge) => {
|
||||
setEdgeHovered(edge.id);
|
||||
(
|
||||
_: React.MouseEvent<Element, MouseEvent>,
|
||||
hoveredEdge: WorkflowDiagramEdge,
|
||||
) => {
|
||||
setEdgeHovered({
|
||||
source: hoveredEdge.source,
|
||||
target: hoveredEdge.target,
|
||||
});
|
||||
},
|
||||
[setEdgeHovered],
|
||||
);
|
||||
|
||||
const onEdgeMouseLeave = useCallback(() => {
|
||||
setNoEdgeHovered();
|
||||
}, [setNoEdgeHovered]);
|
||||
clearEdgeHover();
|
||||
}, [clearEdgeHover]);
|
||||
|
||||
return (
|
||||
<StyledResetReactflowStyles ref={containerRef}>
|
||||
|
||||
+5
-4
@@ -1,4 +1,4 @@
|
||||
import { useEdgeSelected } from '@/workflow/workflow-diagram/hooks/useEdgeSelected';
|
||||
import { useEdgeState } from '@/workflow/workflow-diagram/hooks/useEdgeState';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import {
|
||||
type OnSelectionChangeParams,
|
||||
@@ -9,7 +9,7 @@ import { isDefined } from 'twenty-shared/utils';
|
||||
import { FeatureFlagKey } from '~/generated/graphql';
|
||||
|
||||
export const WorkflowDiagramCanvasEditableEffect = () => {
|
||||
const { setEdgeSelected, clearEdgeSelection } = useEdgeSelected();
|
||||
const { setEdgeSelected, clearEdgeSelected } = useEdgeState();
|
||||
|
||||
const isWorkflowBranchEnabled = useIsFeatureEnabled(
|
||||
FeatureFlagKey.IS_WORKFLOW_BRANCH_ENABLED,
|
||||
@@ -24,7 +24,8 @@ export const WorkflowDiagramCanvasEditableEffect = () => {
|
||||
const selectedEdge = edges?.[0];
|
||||
|
||||
if (!isDefined(selectedEdge)) {
|
||||
clearEdgeSelection();
|
||||
clearEdgeSelected();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -33,7 +34,7 @@ export const WorkflowDiagramCanvasEditableEffect = () => {
|
||||
target: selectedEdge.target,
|
||||
});
|
||||
},
|
||||
[isWorkflowBranchEnabled, setEdgeSelected, clearEdgeSelection],
|
||||
[isWorkflowBranchEnabled, setEdgeSelected, clearEdgeSelected],
|
||||
);
|
||||
|
||||
useOnSelectionChange({
|
||||
|
||||
+30
-2
@@ -1,4 +1,4 @@
|
||||
import { EDGE_BRANCH_ARROW_MARKER_ID } from '@/workflow/workflow-diagram/constants/EdgeBranchArrowMarkerId';
|
||||
import { EdgeBranchArrowMarker } from '@/workflow/workflow-diagram/constants/EdgeBranchArrowMarker';
|
||||
import { useTheme } from '@emotion/react';
|
||||
|
||||
export const WorkflowDiagramCustomMarkers = () => {
|
||||
@@ -8,7 +8,7 @@ export const WorkflowDiagramCustomMarkers = () => {
|
||||
<svg style={{ position: 'absolute', top: 0, left: 0 }}>
|
||||
<defs>
|
||||
<marker
|
||||
id={EDGE_BRANCH_ARROW_MARKER_ID}
|
||||
id={EdgeBranchArrowMarker.Default}
|
||||
markerHeight={8}
|
||||
markerWidth={10}
|
||||
refX={5}
|
||||
@@ -20,6 +20,34 @@ export const WorkflowDiagramCustomMarkers = () => {
|
||||
fill={theme.background.primary}
|
||||
/>
|
||||
</marker>
|
||||
|
||||
<marker
|
||||
id={EdgeBranchArrowMarker.Hover}
|
||||
markerHeight={8}
|
||||
markerWidth={10}
|
||||
refX={5}
|
||||
refY={4}
|
||||
>
|
||||
<path
|
||||
d="M1.7915 1.38672H8.18311C8.57541 1.38705 8.81458 1.81852 8.60693 2.15137L5.41064 7.26465C5.21481 7.57798 4.75882 7.57798 4.56299 7.26465L1.3667 2.15137C1.15906 1.81841 1.39896 1.38672 1.7915 1.38672Z"
|
||||
stroke={theme.font.color.light}
|
||||
fill={theme.background.primary}
|
||||
/>
|
||||
</marker>
|
||||
|
||||
<marker
|
||||
id={EdgeBranchArrowMarker.Selected}
|
||||
markerHeight={8}
|
||||
markerWidth={10}
|
||||
refX={5}
|
||||
refY={4}
|
||||
>
|
||||
<path
|
||||
d="M1.7915 1.38672H8.18311C8.57541 1.38705 8.81458 1.81852 8.60693 2.15137L5.41064 7.26465C5.21481 7.57798 4.75882 7.57798 4.56299 7.26465L1.3667 2.15137C1.15906 1.81841 1.39896 1.38672 1.7915 1.38672Z"
|
||||
stroke={theme.color.blue}
|
||||
fill={theme.background.primary}
|
||||
/>
|
||||
</marker>
|
||||
</defs>
|
||||
</svg>
|
||||
);
|
||||
|
||||
+5
-4
@@ -8,7 +8,6 @@ import { WorkflowDiagramEdgeButtonGroup } from '@/workflow/workflow-diagram/comp
|
||||
import { WorkflowDiagramEdgeV2Container } from '@/workflow/workflow-diagram/components/WorkflowDiagramEdgeV2Container';
|
||||
import { WorkflowDiagramEdgeV2VisibilityContainer } from '@/workflow/workflow-diagram/components/WorkflowDiagramEdgeV2VisibilityContainer';
|
||||
import { WORKFLOW_DIAGRAM_EDGE_OPTIONS_CLICK_OUTSIDE_ID } from '@/workflow/workflow-diagram/constants/WorkflowDiagramEdgeOptionsClickOutsideId';
|
||||
import { useEdgeHovered } from '@/workflow/workflow-diagram/hooks/useEdgeHovered';
|
||||
import { useOpenWorkflowEditFilterInCommandMenu } from '@/workflow/workflow-diagram/hooks/useOpenWorkflowEditFilterInCommandMenu';
|
||||
import { useStartNodeCreation } from '@/workflow/workflow-diagram/hooks/useStartNodeCreation';
|
||||
import { type WorkflowDiagramEdge } from '@/workflow/workflow-diagram/types/WorkflowDiagram';
|
||||
@@ -25,11 +24,11 @@ import { useSetRecoilState } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { IconFilter, IconPlus, IconTrash } from 'twenty-ui/display';
|
||||
import { FeatureFlagKey } from '~/generated/graphql';
|
||||
import { useEdgeState } from '@/workflow/workflow-diagram/hooks/useEdgeState';
|
||||
|
||||
type WorkflowDiagramDefaultEdgeEditableProps = EdgeProps<WorkflowDiagramEdge>;
|
||||
|
||||
export const WorkflowDiagramDefaultEdgeEditable = ({
|
||||
id,
|
||||
source,
|
||||
target,
|
||||
sourceX,
|
||||
@@ -45,7 +44,7 @@ export const WorkflowDiagramDefaultEdgeEditable = ({
|
||||
|
||||
const { isInRightDrawer } = useContext(ActionMenuContext);
|
||||
|
||||
const { isEdgeHovered } = useEdgeHovered();
|
||||
const { isEdgeHovered } = useEdgeState();
|
||||
|
||||
const [edgePath, labelX, labelY] = getBezierPath({
|
||||
sourceX,
|
||||
@@ -129,7 +128,9 @@ export const WorkflowDiagramDefaultEdgeEditable = ({
|
||||
labelY={labelY}
|
||||
>
|
||||
<WorkflowDiagramEdgeV2VisibilityContainer
|
||||
shouldDisplay={nodeCreationStarted || isEdgeHovered(id)}
|
||||
shouldDisplay={
|
||||
nodeCreationStarted || isEdgeHovered({ source, target })
|
||||
}
|
||||
>
|
||||
<WorkflowDiagramEdgeButtonGroup
|
||||
iconButtons={[
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
export enum EdgeBranchArrowMarker {
|
||||
Default = 'edge-branch-arrow-default',
|
||||
Hover = 'edge-branch-arrow-hover',
|
||||
Selected = 'edge-branch-arrow-selected',
|
||||
}
|
||||
-1
@@ -1 +0,0 @@
|
||||
export const EDGE_BRANCH_ARROW_MARKER_ID = 'workflow-edge-branch-arrow';
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
import { EDGE_BRANCH_ARROW_MARKER_ID } from '@/workflow/workflow-diagram/constants/EdgeBranchArrowMarkerId';
|
||||
import { EdgeBranchArrowMarker } from '@/workflow/workflow-diagram/constants/EdgeBranchArrowMarker';
|
||||
import {
|
||||
type WorkflowDiagramEdge,
|
||||
type WorkflowDiagramEdgeType,
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
export const WORKFLOW_VISUALIZER_EDGE_DEFAULT_CONFIGURATION = {
|
||||
type: 'empty-filter--readonly' satisfies WorkflowDiagramEdgeType,
|
||||
markerStart: undefined,
|
||||
markerEnd: EDGE_BRANCH_ARROW_MARKER_ID,
|
||||
markerEnd: EdgeBranchArrowMarker.Default,
|
||||
deletable: false,
|
||||
selectable: false,
|
||||
data: {
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
|
||||
import { workflowHoveredEdgeIdComponentState } from '@/workflow/workflow-diagram/states/workflowHoveredEdgeIdComponentState';
|
||||
|
||||
export const useEdgeHovered = () => {
|
||||
const [workflowHoveredEdgeId, setWorkflowHoveredEdgeId] =
|
||||
useRecoilComponentState(workflowHoveredEdgeIdComponentState);
|
||||
|
||||
const isEdgeHovered = (edgeId: string) => {
|
||||
return workflowHoveredEdgeId === edgeId;
|
||||
};
|
||||
|
||||
const setEdgeHovered = (edgeId: string) => {
|
||||
setWorkflowHoveredEdgeId(edgeId);
|
||||
};
|
||||
|
||||
const setNoEdgeHovered = () => {
|
||||
setWorkflowHoveredEdgeId(undefined);
|
||||
};
|
||||
|
||||
return {
|
||||
isEdgeHovered,
|
||||
setEdgeHovered,
|
||||
setNoEdgeHovered,
|
||||
};
|
||||
};
|
||||
@@ -1,47 +0,0 @@
|
||||
import { workflowSelectedEdgeComponentState } from '@/workflow/workflow-diagram/states/workflowSelectedEdgeComponentState';
|
||||
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
|
||||
import { type WorkflowDiagramHandlesSelected } from '@/workflow/workflow-diagram/types/WorkflowDiagramHandlesSelected';
|
||||
import { type WorkflowDiagramEdge } from '@/workflow/workflow-diagram/types/WorkflowDiagramEdge';
|
||||
|
||||
export const useEdgeSelected = () => {
|
||||
const [workflowSelectedEdge, setWorkflowSelectedEdge] =
|
||||
useRecoilComponentState(workflowSelectedEdgeComponentState);
|
||||
|
||||
const isEdgeSelected = ({ source, target }: WorkflowDiagramEdge) => {
|
||||
return (
|
||||
workflowSelectedEdge?.source === source &&
|
||||
workflowSelectedEdge?.target === target
|
||||
);
|
||||
};
|
||||
|
||||
const getNodeHandlesSelectedState = (
|
||||
id: string,
|
||||
): WorkflowDiagramHandlesSelected => {
|
||||
return {
|
||||
targetHandle: workflowSelectedEdge?.target === id,
|
||||
sourceHandle: workflowSelectedEdge?.source === id,
|
||||
};
|
||||
};
|
||||
|
||||
const setEdgeSelected = ({ source, target }: WorkflowDiagramEdge) => {
|
||||
if (
|
||||
workflowSelectedEdge?.source === source &&
|
||||
workflowSelectedEdge?.target === target
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
setWorkflowSelectedEdge({ source, target });
|
||||
};
|
||||
|
||||
const clearEdgeSelection = () => {
|
||||
setWorkflowSelectedEdge(undefined);
|
||||
};
|
||||
|
||||
return {
|
||||
isEdgeSelected,
|
||||
setEdgeSelected,
|
||||
clearEdgeSelection,
|
||||
getNodeHandlesSelectedState,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,132 @@
|
||||
import { workflowSelectedEdgeComponentState } from '@/workflow/workflow-diagram/states/workflowSelectedEdgeComponentState';
|
||||
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
|
||||
import { type WorkflowDiagramNodeHandles } from '@/workflow/workflow-diagram/types/WorkflowDiagramNodeHandles';
|
||||
import { type WorkflowDiagramEdge } from '@/workflow/workflow-diagram/types/WorkflowDiagramEdge';
|
||||
import { workflowHoveredEdgeComponentState } from '@/workflow/workflow-diagram/states/workflowHoveredEdgeComponentState';
|
||||
import { useReactFlow } from '@xyflow/react';
|
||||
import { EdgeBranchArrowMarker } from '@/workflow/workflow-diagram/constants/EdgeBranchArrowMarker';
|
||||
|
||||
export const useEdgeState = () => {
|
||||
const reactflow = useReactFlow();
|
||||
|
||||
const [workflowSelectedEdge, setWorkflowSelectedEdge] =
|
||||
useRecoilComponentState(workflowSelectedEdgeComponentState);
|
||||
|
||||
const [workflowHoveredEdge, setWorkflowHoveredEdge] = useRecoilComponentState(
|
||||
workflowHoveredEdgeComponentState,
|
||||
);
|
||||
|
||||
const isEdgeSelected = ({ source, target }: WorkflowDiagramEdge) => {
|
||||
return (
|
||||
workflowSelectedEdge?.source === source &&
|
||||
workflowSelectedEdge?.target === target
|
||||
);
|
||||
};
|
||||
|
||||
const isEdgeHovered = ({ source, target }: WorkflowDiagramEdge) => {
|
||||
return (
|
||||
workflowHoveredEdge?.source === source &&
|
||||
workflowHoveredEdge?.target === target
|
||||
);
|
||||
};
|
||||
|
||||
const getNodeHandlesSelectedState = (
|
||||
id: string,
|
||||
): WorkflowDiagramNodeHandles => {
|
||||
return {
|
||||
targetHandle: workflowSelectedEdge?.target === id,
|
||||
sourceHandle: workflowSelectedEdge?.source === id,
|
||||
};
|
||||
};
|
||||
|
||||
const getNodeHandlesHoveredState = (
|
||||
id: string,
|
||||
): WorkflowDiagramNodeHandles => {
|
||||
return {
|
||||
targetHandle: workflowHoveredEdge?.target === id,
|
||||
sourceHandle: workflowHoveredEdge?.source === id,
|
||||
};
|
||||
};
|
||||
|
||||
const setEdgeSelected = ({ source, target }: WorkflowDiagramEdge) => {
|
||||
if (
|
||||
workflowSelectedEdge?.source === source &&
|
||||
workflowSelectedEdge?.target === target
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
setWorkflowSelectedEdge({ source, target });
|
||||
|
||||
reactflow.setEdges((edges) =>
|
||||
edges.map((edge) => ({
|
||||
...edge,
|
||||
markerEnd:
|
||||
edge.source === source && edge.target === target
|
||||
? EdgeBranchArrowMarker.Selected
|
||||
: EdgeBranchArrowMarker.Default,
|
||||
})),
|
||||
);
|
||||
};
|
||||
|
||||
const setEdgeHovered = ({ source, target }: WorkflowDiagramEdge) => {
|
||||
if (
|
||||
workflowHoveredEdge?.source === source &&
|
||||
workflowHoveredEdge?.target === target
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
setWorkflowHoveredEdge({ source, target });
|
||||
|
||||
reactflow.setEdges((edges) =>
|
||||
edges.map((edge) =>
|
||||
edge.source === source &&
|
||||
edge.target === target &&
|
||||
edge.markerEnd !== EdgeBranchArrowMarker.Selected
|
||||
? {
|
||||
...edge,
|
||||
markerEnd: EdgeBranchArrowMarker.Hover,
|
||||
}
|
||||
: edge,
|
||||
),
|
||||
);
|
||||
};
|
||||
|
||||
const clearEdgeSelected = () => {
|
||||
setWorkflowSelectedEdge(undefined);
|
||||
|
||||
reactflow.setEdges((edges) =>
|
||||
edges.map((edge) => ({
|
||||
...edge,
|
||||
markerEnd: EdgeBranchArrowMarker.Default,
|
||||
})),
|
||||
);
|
||||
};
|
||||
|
||||
const clearEdgeHover = () => {
|
||||
setWorkflowHoveredEdge(undefined);
|
||||
|
||||
reactflow.setEdges((edges) =>
|
||||
edges.map((edge) =>
|
||||
edge.markerEnd === EdgeBranchArrowMarker.Hover
|
||||
? {
|
||||
...edge,
|
||||
markerEnd: EdgeBranchArrowMarker.Default,
|
||||
}
|
||||
: edge,
|
||||
),
|
||||
);
|
||||
};
|
||||
|
||||
return {
|
||||
isEdgeSelected,
|
||||
setEdgeSelected,
|
||||
clearEdgeSelected,
|
||||
getNodeHandlesSelectedState,
|
||||
isEdgeHovered,
|
||||
setEdgeHovered,
|
||||
clearEdgeHover,
|
||||
getNodeHandlesHoveredState,
|
||||
};
|
||||
};
|
||||
+4
-3
@@ -1,10 +1,11 @@
|
||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||
import { WorkflowVisualizerComponentInstanceContext } from '@/workflow/workflow-diagram/states/contexts/WorkflowVisualizerComponentInstanceContext';
|
||||
import type { WorkflowDiagramEdge } from '@/workflow/workflow-diagram/types/WorkflowDiagramEdge';
|
||||
|
||||
export const workflowHoveredEdgeIdComponentState = createComponentState<
|
||||
string | undefined
|
||||
export const workflowHoveredEdgeComponentState = createComponentState<
|
||||
WorkflowDiagramEdge | undefined
|
||||
>({
|
||||
key: 'workflowHoveredEdgeIdComponentState',
|
||||
key: 'workflowHoveredEdgeComponentState',
|
||||
defaultValue: undefined,
|
||||
componentInstanceContext: WorkflowVisualizerComponentInstanceContext,
|
||||
});
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
export type WorkflowDiagramHandlesSelected = {
|
||||
export type WorkflowDiagramNodeHandles = {
|
||||
targetHandle: boolean;
|
||||
sourceHandle: boolean;
|
||||
};
|
||||
+14
-14
@@ -119,7 +119,7 @@ describe('generateWorkflowRunDiagram', () => {
|
||||
},
|
||||
"deletable": false,
|
||||
"id": "8f3b2121-f194-4ba4-9fbf-0",
|
||||
"markerEnd": "workflow-edge-branch-arrow",
|
||||
"markerEnd": "edge-branch-arrow-default",
|
||||
"markerStart": undefined,
|
||||
"selectable": false,
|
||||
"source": "trigger",
|
||||
@@ -133,7 +133,7 @@ describe('generateWorkflowRunDiagram', () => {
|
||||
},
|
||||
"deletable": false,
|
||||
"id": "8f3b2121-f194-4ba4-9fbf-1",
|
||||
"markerEnd": "workflow-edge-branch-arrow",
|
||||
"markerEnd": "edge-branch-arrow-default",
|
||||
"markerStart": undefined,
|
||||
"selectable": false,
|
||||
"source": "step1",
|
||||
@@ -147,7 +147,7 @@ describe('generateWorkflowRunDiagram', () => {
|
||||
},
|
||||
"deletable": false,
|
||||
"id": "8f3b2121-f194-4ba4-9fbf-2",
|
||||
"markerEnd": "workflow-edge-branch-arrow",
|
||||
"markerEnd": "edge-branch-arrow-default",
|
||||
"markerStart": undefined,
|
||||
"selectable": false,
|
||||
"source": "step2",
|
||||
@@ -349,7 +349,7 @@ describe('generateWorkflowRunDiagram', () => {
|
||||
},
|
||||
"deletable": false,
|
||||
"id": "8f3b2121-f194-4ba4-9fbf-3",
|
||||
"markerEnd": "workflow-edge-branch-arrow",
|
||||
"markerEnd": "edge-branch-arrow-default",
|
||||
"markerStart": undefined,
|
||||
"selectable": false,
|
||||
"source": "trigger",
|
||||
@@ -363,7 +363,7 @@ describe('generateWorkflowRunDiagram', () => {
|
||||
},
|
||||
"deletable": false,
|
||||
"id": "8f3b2121-f194-4ba4-9fbf-4",
|
||||
"markerEnd": "workflow-edge-branch-arrow",
|
||||
"markerEnd": "edge-branch-arrow-default",
|
||||
"markerStart": undefined,
|
||||
"selectable": false,
|
||||
"source": "step1",
|
||||
@@ -377,7 +377,7 @@ describe('generateWorkflowRunDiagram', () => {
|
||||
},
|
||||
"deletable": false,
|
||||
"id": "8f3b2121-f194-4ba4-9fbf-5",
|
||||
"markerEnd": "workflow-edge-branch-arrow",
|
||||
"markerEnd": "edge-branch-arrow-default",
|
||||
"markerStart": undefined,
|
||||
"selectable": false,
|
||||
"source": "step2",
|
||||
@@ -579,7 +579,7 @@ describe('generateWorkflowRunDiagram', () => {
|
||||
},
|
||||
"deletable": false,
|
||||
"id": "8f3b2121-f194-4ba4-9fbf-6",
|
||||
"markerEnd": "workflow-edge-branch-arrow",
|
||||
"markerEnd": "edge-branch-arrow-default",
|
||||
"markerStart": undefined,
|
||||
"selectable": false,
|
||||
"source": "trigger",
|
||||
@@ -593,7 +593,7 @@ describe('generateWorkflowRunDiagram', () => {
|
||||
},
|
||||
"deletable": false,
|
||||
"id": "8f3b2121-f194-4ba4-9fbf-7",
|
||||
"markerEnd": "workflow-edge-branch-arrow",
|
||||
"markerEnd": "edge-branch-arrow-default",
|
||||
"markerStart": undefined,
|
||||
"selectable": false,
|
||||
"source": "step1",
|
||||
@@ -607,7 +607,7 @@ describe('generateWorkflowRunDiagram', () => {
|
||||
},
|
||||
"deletable": false,
|
||||
"id": "8f3b2121-f194-4ba4-9fbf-8",
|
||||
"markerEnd": "workflow-edge-branch-arrow",
|
||||
"markerEnd": "edge-branch-arrow-default",
|
||||
"markerStart": undefined,
|
||||
"selectable": false,
|
||||
"source": "step2",
|
||||
@@ -828,7 +828,7 @@ describe('generateWorkflowRunDiagram', () => {
|
||||
},
|
||||
"deletable": false,
|
||||
"id": "8f3b2121-f194-4ba4-9fbf-9",
|
||||
"markerEnd": "workflow-edge-branch-arrow",
|
||||
"markerEnd": "edge-branch-arrow-default",
|
||||
"markerStart": undefined,
|
||||
"selectable": false,
|
||||
"source": "trigger",
|
||||
@@ -842,7 +842,7 @@ describe('generateWorkflowRunDiagram', () => {
|
||||
},
|
||||
"deletable": false,
|
||||
"id": "8f3b2121-f194-4ba4-9fbf-10",
|
||||
"markerEnd": "workflow-edge-branch-arrow",
|
||||
"markerEnd": "edge-branch-arrow-default",
|
||||
"markerStart": undefined,
|
||||
"selectable": false,
|
||||
"source": "step1",
|
||||
@@ -856,7 +856,7 @@ describe('generateWorkflowRunDiagram', () => {
|
||||
},
|
||||
"deletable": false,
|
||||
"id": "8f3b2121-f194-4ba4-9fbf-11",
|
||||
"markerEnd": "workflow-edge-branch-arrow",
|
||||
"markerEnd": "edge-branch-arrow-default",
|
||||
"markerStart": undefined,
|
||||
"selectable": false,
|
||||
"source": "step2",
|
||||
@@ -870,7 +870,7 @@ describe('generateWorkflowRunDiagram', () => {
|
||||
},
|
||||
"deletable": false,
|
||||
"id": "8f3b2121-f194-4ba4-9fbf-12",
|
||||
"markerEnd": "workflow-edge-branch-arrow",
|
||||
"markerEnd": "edge-branch-arrow-default",
|
||||
"markerStart": undefined,
|
||||
"selectable": false,
|
||||
"source": "step3",
|
||||
@@ -1057,7 +1057,7 @@ describe('generateWorkflowRunDiagram', () => {
|
||||
},
|
||||
"deletable": false,
|
||||
"id": "8f3b2121-f194-4ba4-9fbf-13",
|
||||
"markerEnd": "workflow-edge-branch-arrow",
|
||||
"markerEnd": "edge-branch-arrow-default",
|
||||
"markerStart": undefined,
|
||||
"selectable": false,
|
||||
"source": "trigger",
|
||||
|
||||
+1
-1
@@ -157,7 +157,7 @@ describe('getWorkflowVersionDiagram', () => {
|
||||
},
|
||||
"deletable": true,
|
||||
"id": "8f3b2121-f194-4ba4-9fbf-0",
|
||||
"markerEnd": "workflow-edge-branch-arrow",
|
||||
"markerEnd": "edge-branch-arrow-default",
|
||||
"markerStart": undefined,
|
||||
"selectable": true,
|
||||
"source": "trigger",
|
||||
|
||||
+5
-4
@@ -14,7 +14,6 @@ import { WorkflowDiagramEdgeButtonGroup } from '@/workflow/workflow-diagram/comp
|
||||
import { WorkflowDiagramEdgeV2Container } from '@/workflow/workflow-diagram/components/WorkflowDiagramEdgeV2Container';
|
||||
import { WorkflowDiagramEdgeV2VisibilityContainer } from '@/workflow/workflow-diagram/components/WorkflowDiagramEdgeV2VisibilityContainer';
|
||||
import { WORKFLOW_DIAGRAM_EDGE_OPTIONS_CLICK_OUTSIDE_ID } from '@/workflow/workflow-diagram/constants/WorkflowDiagramEdgeOptionsClickOutsideId';
|
||||
import { useEdgeHovered } from '@/workflow/workflow-diagram/hooks/useEdgeHovered';
|
||||
import { useOpenWorkflowEditFilterInCommandMenu } from '@/workflow/workflow-diagram/hooks/useOpenWorkflowEditFilterInCommandMenu';
|
||||
import { useStartNodeCreation } from '@/workflow/workflow-diagram/hooks/useStartNodeCreation';
|
||||
import { workflowDiagramPanOnDragComponentState } from '@/workflow/workflow-diagram/states/workflowDiagramPanOnDragComponentState';
|
||||
@@ -48,6 +47,7 @@ import {
|
||||
import { IconButtonGroup } from 'twenty-ui/input';
|
||||
import { MenuItem } from 'twenty-ui/navigation';
|
||||
import { FeatureFlagKey } from '~/generated/graphql';
|
||||
import { useEdgeState } from '@/workflow/workflow-diagram/hooks/useEdgeState';
|
||||
|
||||
type WorkflowDiagramFilterEdgeEditableProps = EdgeProps<WorkflowDiagramEdge>;
|
||||
|
||||
@@ -80,7 +80,6 @@ const StyledConfiguredFilterContainer = styled.div`
|
||||
`;
|
||||
|
||||
export const WorkflowDiagramFilterEdgeEditable = ({
|
||||
id,
|
||||
source,
|
||||
target,
|
||||
sourceY,
|
||||
@@ -118,7 +117,7 @@ export const WorkflowDiagramFilterEdgeEditable = ({
|
||||
const { openDropdown } = useOpenDropdown();
|
||||
const { closeDropdown } = useCloseDropdown();
|
||||
|
||||
const { isEdgeHovered } = useEdgeHovered();
|
||||
const { isEdgeHovered } = useEdgeState();
|
||||
|
||||
const setWorkflowDiagramPanOnDrag = useSetRecoilComponentState(
|
||||
workflowDiagramPanOnDragComponentState,
|
||||
@@ -197,7 +196,9 @@ export const WorkflowDiagramFilterEdgeEditable = ({
|
||||
>
|
||||
<WorkflowDiagramEdgeV2VisibilityContainer shouldDisplay>
|
||||
<StyledConfiguredFilterContainer>
|
||||
{isEdgeHovered(id) || isDropdownOpen || nodeCreationStarted ? (
|
||||
{isEdgeHovered({ source, target }) ||
|
||||
isDropdownOpen ||
|
||||
nodeCreationStarted ? (
|
||||
<WorkflowDiagramEdgeButtonGroup
|
||||
iconButtons={[
|
||||
{
|
||||
|
||||
+11
-3
@@ -8,22 +8,28 @@ import { FeatureFlagKey } from '~/generated/graphql';
|
||||
|
||||
type WorkflowDiagramHandleEditableProps = HandleProps & {
|
||||
selected: boolean;
|
||||
hovered?: boolean;
|
||||
};
|
||||
|
||||
const HANDLE_SCALE_ON_HOVER = 1.5;
|
||||
|
||||
const StyledHandle = styled(Handle, {
|
||||
shouldForwardProp: (prop) =>
|
||||
prop !== 'disableHoverEffect' && prop !== 'selected',
|
||||
prop !== 'disableHoverEffect' && prop !== 'selected' && prop !== 'hovered',
|
||||
})<{
|
||||
disableHoverEffect: boolean;
|
||||
selected: boolean;
|
||||
hovered?: boolean;
|
||||
}>`
|
||||
&.react-flow__handle {
|
||||
height: ${NODE_HANDLE_HEIGHT_PX}px;
|
||||
width: ${NODE_HANDLE_WIDTH_PX}px;
|
||||
border-color: ${({ theme, selected }) =>
|
||||
selected ? theme.color.blue : theme.border.color.strong};
|
||||
border-color: ${({ theme, selected, hovered }) =>
|
||||
selected
|
||||
? theme.color.blue
|
||||
: hovered
|
||||
? theme.font.color.light
|
||||
: theme.border.color.strong};
|
||||
background: ${({ theme, selected }) =>
|
||||
selected ? theme.adaptiveColors.blue1 : theme.background.primary};
|
||||
transition:
|
||||
@@ -79,6 +85,7 @@ export const WorkflowDiagramHandleEditable = ({
|
||||
type,
|
||||
position,
|
||||
selected,
|
||||
hovered = false,
|
||||
}: WorkflowDiagramHandleEditableProps) => {
|
||||
const isWorkflowBranchEnabled = useIsFeatureEnabled(
|
||||
FeatureFlagKey.IS_WORKFLOW_BRANCH_ENABLED,
|
||||
@@ -90,6 +97,7 @@ export const WorkflowDiagramHandleEditable = ({
|
||||
position={position}
|
||||
disableHoverEffect={!isWorkflowBranchEnabled}
|
||||
selected={selected}
|
||||
hovered={hovered}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
+7
-2
@@ -1,6 +1,6 @@
|
||||
import { WorkflowDiagramCreateStepElement } from '@/workflow/workflow-diagram/components/WorkflowDiagramCreateStepElement';
|
||||
import { WORKFLOW_DIAGRAM_STEP_NODE_BASE_CLICK_OUTSIDE_ID } from '@/workflow/workflow-diagram/constants/WorkflowDiagramStepNodeClickOutsideId';
|
||||
import { useEdgeSelected } from '@/workflow/workflow-diagram/hooks/useEdgeSelected';
|
||||
import { useEdgeState } from '@/workflow/workflow-diagram/hooks/useEdgeState';
|
||||
import { useStartNodeCreation } from '@/workflow/workflow-diagram/hooks/useStartNodeCreation';
|
||||
import { type WorkflowDiagramStepNodeData } from '@/workflow/workflow-diagram/types/WorkflowDiagram';
|
||||
import { type WorkflowDiagramNodeVariant } from '@/workflow/workflow-diagram/types/WorkflowDiagramNodeVariant';
|
||||
@@ -100,10 +100,13 @@ export const WorkflowDiagramStepNodeEditableContent = ({
|
||||
|
||||
const { isNodeCreationStarted } = useStartNodeCreation();
|
||||
|
||||
const { getNodeHandlesSelectedState } = useEdgeSelected();
|
||||
const { getNodeHandlesSelectedState, getNodeHandlesHoveredState } =
|
||||
useEdgeState();
|
||||
|
||||
const handlesSelectedState = getNodeHandlesSelectedState(id);
|
||||
|
||||
const handlesHoveredState = getNodeHandlesHoveredState(id);
|
||||
|
||||
return (
|
||||
<>
|
||||
{data.nodeType !== 'trigger' && (
|
||||
@@ -111,6 +114,7 @@ export const WorkflowDiagramStepNodeEditableContent = ({
|
||||
type="target"
|
||||
position={Position.Top}
|
||||
selected={handlesSelectedState.targetHandle}
|
||||
hovered={handlesHoveredState.targetHandle}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -161,6 +165,7 @@ export const WorkflowDiagramStepNodeEditableContent = ({
|
||||
type="source"
|
||||
position={Position.Bottom}
|
||||
selected={handlesSelectedState.sourceHandle || selected}
|
||||
hovered={handlesHoveredState.sourceHandle}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user