Implement creating node before initial step + deleting loop edge (#14525)

https://github.com/user-attachments/assets/d4ef0fa1-89e0-4848-9a4d-93dee81254f7

## Remaining to handle in future PRs

- It would be easier for the frontend if the loop edge was stored in the
backend instead of being an edge case the frontend must handle
- Optimistic rendering when deleting loop edge
This commit is contained in:
Baptiste Devessier
2025-09-16 13:50:56 +02:00
committed by GitHub
parent e505e9cf9f
commit 60de57f469
14 changed files with 74 additions and 178 deletions
@@ -3,6 +3,7 @@ import { useGetUpdatableWorkflowVersionOrThrow } from '@/workflow/hooks/useGetUp
import { workflowLastCreatedStepIdComponentState } from '@/workflow/states/workflowLastCreatedStepIdComponentState';
import { type WorkflowStepType } from '@/workflow/types/Workflow';
import { workflowSelectedNodeComponentState } from '@/workflow/workflow-diagram/states/workflowSelectedNodeComponentState';
import { type WorkflowStepConnectionOptions } from '@/workflow/workflow-diagram/workflow-iterator/types/WorkflowStepConnectionOptions';
import { useCreateWorkflowVersionStep } from '@/workflow/workflow-steps/hooks/useCreateWorkflowVersionStep';
import { useState } from 'react';
import { isDefined } from 'twenty-shared/utils';
@@ -25,11 +26,13 @@ export const useCreateStep = () => {
parentStepId,
nextStepId,
position,
connectionOptions,
}: {
newStepType: WorkflowStepType;
parentStepId: string | undefined;
nextStepId: string | undefined;
position?: { x: number; y: number };
connectionOptions?: WorkflowStepConnectionOptions;
}) => {
if (isLoading === true) {
return;
@@ -47,6 +50,7 @@ export const useCreateStep = () => {
parentStepId,
nextStepId,
position,
parentStepConnectionOptions: connectionOptions,
})
)?.data?.createWorkflowVersionStep;
@@ -1,8 +1,14 @@
import { useGetUpdatableWorkflowVersionOrThrow } from '@/workflow/hooks/useGetUpdatableWorkflowVersionOrThrow';
import { type WorkflowDiagramEdgeDescriptor } from '@/workflow/workflow-diagram/workflow-edges/types/WorkflowDiagramEdgeDescriptor';
import { type WorkflowStepConnectionOptions } from '@/workflow/workflow-diagram/workflow-iterator/types/WorkflowStepConnectionOptions';
import { useDeleteWorkflowVersionEdge } from '@/workflow/workflow-steps/hooks/useDeleteWorkflowVersionEdge';
import { useState } from 'react';
type DeleteEdgeParams = {
source: string;
target: string;
sourceConnectionOptions?: WorkflowStepConnectionOptions;
};
export const useDeleteEdge = () => {
const [isLoading, setIsLoading] = useState(false);
@@ -14,7 +20,8 @@ export const useDeleteEdge = () => {
const deleteEdge = async ({
source,
target,
}: WorkflowDiagramEdgeDescriptor) => {
sourceConnectionOptions,
}: DeleteEdgeParams) => {
if (isLoading) {
return;
}
@@ -29,6 +36,7 @@ export const useDeleteEdge = () => {
workflowVersionId,
source,
target,
sourceConnectionOptions,
})
)?.data?.deleteWorkflowVersionEdge;
@@ -1,10 +1,12 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
import { WorkflowVisualizerComponentInstanceContext } from '@/workflow/workflow-diagram/states/contexts/WorkflowVisualizerComponentInstanceContext';
import { type WorkflowStepConnectionOptions } from '@/workflow/workflow-diagram/workflow-iterator/types/WorkflowStepConnectionOptions';
type WorkflowInsertStepIdsState = {
parentStepId: string | undefined;
nextStepId: string | undefined;
position?: { x: number; y: number };
connectionOptions?: WorkflowStepConnectionOptions;
};
export const workflowInsertStepIdsComponentState =
@@ -14,6 +16,7 @@ export const workflowInsertStepIdsComponentState =
parentStepId: undefined,
nextStepId: undefined,
position: undefined,
connectionOptions: undefined,
},
componentInstanceContext: WorkflowVisualizerComponentInstanceContext,
});