From 3ffb35d7a83c3b10c319993deb2cf43ab01d7d2d Mon Sep 17 00:00:00 2001 From: Baptiste Devessier Date: Tue, 12 Aug 2025 17:21:52 +0200 Subject: [PATCH] Bring back edge selection & deletion (#13863) Bring back what shouldn't have been deleted. --- .../components/WorkflowDiagramCanvasBase.tsx | 24 +++++++++++++++++++ .../WorkflowDiagramCanvasEditable.tsx | 15 +++++++++++- .../getWorkflowVersionDiagram.test.ts | 4 ++-- .../utils/generateWorkflowDiagram.ts | 6 +++++ 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramCanvasBase.tsx b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramCanvasBase.tsx index 9e8b6314eee..94a2efbeeaa 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramCanvasBase.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramCanvasBase.tsx @@ -37,6 +37,7 @@ import { type FitViewOptions, type NodeChange, type NodeProps, + type OnBeforeDelete, type OnNodeDrag, } from '@xyflow/react'; import '@xyflow/react/dist/style.css'; @@ -112,6 +113,7 @@ export const WorkflowDiagramCanvasBase = ({ tagText, onInit, onConnect, + onDeleteEdge, onNodeDragStop, handlePaneContextMenu, nodesConnectable = false, @@ -145,6 +147,7 @@ export const WorkflowDiagramCanvasBase = ({ tagText: string; onInit?: () => void; onConnect?: (params: Connection) => void; + onDeleteEdge?: (edge: WorkflowDiagramEdge) => void; onNodeDragStop?: OnNodeDrag; nodesConnectable?: boolean; nodesDraggable?: boolean; @@ -411,6 +414,21 @@ export const WorkflowDiagramCanvasBase = ({ ], ); + const onBeforeDelete: OnBeforeDelete< + WorkflowDiagramNode, + WorkflowDiagramEdge + > = async (diagram) => { + if ( + diagram.nodes.length === 0 // We don't call deleteEdge when node diagram deletion is called + ) { + for (const edge of diagram.edges) { + onDeleteEdge?.(edge); + } + return diagram; + } + return false; + }; + const onPaneContextMenu = useCallback( (event: MouseEvent | React.MouseEvent) => { event.preventDefault(); @@ -456,11 +474,17 @@ export const WorkflowDiagramCanvasBase = ({ onEdgesChange={handleEdgesChange} onConnect={isWorkflowBranchEnabled ? onConnect : undefined} onNodeDragStop={isWorkflowBranchEnabled ? onNodeDragStop : undefined} + onBeforeDelete={ + isWorkflowBranchEnabled ? onBeforeDelete : async () => false + } selectNodesOnDrag={false} proOptions={{ hideAttribution: true }} multiSelectionKeyCode={null} nodesFocusable={false} nodesDraggable={isWorkflowBranchEnabled ? nodesDraggable : false} + edgesFocusable={ + isWorkflowBranchEnabled ? isDefined(onDeleteEdge) : false + } panOnDrag={workflowDiagramPanOnDrag} onPaneContextMenu={ isWorkflowBranchEnabled ? onPaneContextMenu : undefined diff --git a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramCanvasEditable.tsx b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramCanvasEditable.tsx index aaf171107ad..d006ba26b74 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramCanvasEditable.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramCanvasEditable.tsx @@ -10,9 +10,13 @@ import { WorkflowDiagramFilteringDisabledEdgeEditable } from '@/workflow/workflo import { WorkflowDiagramStepNodeEditable } from '@/workflow/workflow-diagram/components/WorkflowDiagramStepNodeEditable'; import { workflowDiagramComponentState } from '@/workflow/workflow-diagram/states/workflowDiagramComponentState'; import { workflowDiagramRightClickMenuPositionState } from '@/workflow/workflow-diagram/states/workflowDiagramRightClickMenuPositionState'; -import { type WorkflowDiagramNode } from '@/workflow/workflow-diagram/types/WorkflowDiagram'; +import { + type WorkflowDiagramEdge, + type WorkflowDiagramNode, +} from '@/workflow/workflow-diagram/types/WorkflowDiagram'; import { getWorkflowVersionStatusTagProps } from '@/workflow/workflow-diagram/utils/getWorkflowVersionStatusTagProps'; import { useCreateEdge } from '@/workflow/workflow-steps/hooks/useCreateEdge'; +import { useDeleteEdge } from '@/workflow/workflow-steps/hooks/useDeleteEdge'; import { useUpdateStep } from '@/workflow/workflow-steps/hooks/useUpdateStep'; import { useUpdateWorkflowVersionTrigger } from '@/workflow/workflow-trigger/hooks/useUpdateWorkflowVersionTrigger'; import { addEdge, type Connection, ReactFlowProvider } from '@xyflow/react'; @@ -40,6 +44,10 @@ export const WorkflowDiagramCanvasEditable = ({ workflow: workflowWithCurrentVersion, }); + const { deleteEdge } = useDeleteEdge({ + workflow: workflowWithCurrentVersion, + }); + const { updateStep } = useUpdateStep({ workflow: workflowWithCurrentVersion, }); @@ -65,6 +73,10 @@ export const WorkflowDiagramCanvasEditable = ({ createEdge(edgeConnect); }; + const onDeleteEdge = async (edge: WorkflowDiagramEdge) => { + await deleteEdge(edge); + }; + const onNodeDragStop = async ( _: React.MouseEvent, node: WorkflowDiagramNode, @@ -124,6 +136,7 @@ export const WorkflowDiagramCanvasEditable = ({ handlePaneContextMenu={handlePaneContextMenu} nodesConnectable nodesDraggable + onDeleteEdge={onDeleteEdge} /> diff --git a/packages/twenty-front/src/modules/workflow/workflow-diagram/utils/__tests__/getWorkflowVersionDiagram.test.ts b/packages/twenty-front/src/modules/workflow/workflow-diagram/utils/__tests__/getWorkflowVersionDiagram.test.ts index 76cd7093ab3..d4f7e6183cf 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-diagram/utils/__tests__/getWorkflowVersionDiagram.test.ts +++ b/packages/twenty-front/src/modules/workflow/workflow-diagram/utils/__tests__/getWorkflowVersionDiagram.test.ts @@ -159,11 +159,11 @@ describe('getWorkflowVersionDiagram', () => { "data": { "edgeType": "default", }, - "deletable": false, + "deletable": true, "id": "8f3b2121-f194-4ba4-9fbf-0", "markerEnd": "workflow-edge-arrow-rounded", "markerStart": "workflow-edge-gray-circle", - "selectable": false, + "selectable": true, "source": "trigger", "target": "step-1", "type": "empty-filter--editable", diff --git a/packages/twenty-front/src/modules/workflow/workflow-diagram/utils/generateWorkflowDiagram.ts b/packages/twenty-front/src/modules/workflow/workflow-diagram/utils/generateWorkflowDiagram.ts index e946f8755e4..f430cd41b35 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-diagram/utils/generateWorkflowDiagram.ts +++ b/packages/twenty-front/src/modules/workflow/workflow-diagram/utils/generateWorkflowDiagram.ts @@ -88,6 +88,9 @@ export const generateWorkflowDiagram = ({ id: v4(), source: TRIGGER_STEP_ID, target: stepLinkToTriggerId, + ...(defaultEdgeType.includes('editable') + ? { deletable: true, selectable: true } + : {}), }); } @@ -99,6 +102,9 @@ export const generateWorkflowDiagram = ({ id: v4(), source: step.id, target: child, + ...(defaultEdgeType.includes('editable') + ? { deletable: true, selectable: true } + : {}), }); }); }