diff --git a/packages/twenty-front/src/modules/command-menu/pages/workflow/step/edit/components/CommandMenuWorkflowEditStep.tsx b/packages/twenty-front/src/modules/command-menu/pages/workflow/step/edit/components/CommandMenuWorkflowEditStep.tsx
index 27e8892734..3c6b671df1 100644
--- a/packages/twenty-front/src/modules/command-menu/pages/workflow/step/edit/components/CommandMenuWorkflowEditStep.tsx
+++ b/packages/twenty-front/src/modules/command-menu/pages/workflow/step/edit/components/CommandMenuWorkflowEditStep.tsx
@@ -25,7 +25,7 @@ export const CommandMenuWorkflowEditStep = () => {
-
+
);
diff --git a/packages/twenty-front/src/modules/command-menu/pages/workflow/step/edit/components/CommandMenuWorkflowEditStepContent.tsx b/packages/twenty-front/src/modules/command-menu/pages/workflow/step/edit/components/CommandMenuWorkflowEditStepContent.tsx
index ef7fbbbc1a..7590731958 100644
--- a/packages/twenty-front/src/modules/command-menu/pages/workflow/step/edit/components/CommandMenuWorkflowEditStepContent.tsx
+++ b/packages/twenty-front/src/modules/command-menu/pages/workflow/step/edit/components/CommandMenuWorkflowEditStepContent.tsx
@@ -1,6 +1,5 @@
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useFlowOrThrow } from '@/workflow/hooks/useFlowOrThrow';
-import { type WorkflowWithCurrentVersion } from '@/workflow/types/Workflow';
import { workflowSelectedNodeComponentState } from '@/workflow/workflow-diagram/states/workflowSelectedNodeComponentState';
import { WorkflowStepDetail } from '@/workflow/workflow-steps/components/WorkflowStepDetail';
import { useUpdateStep } from '@/workflow/workflow-steps/hooks/useUpdateStep';
@@ -14,20 +13,14 @@ const StyledContainer = styled.div`
height: 100%;
`;
-export const CommandMenuWorkflowEditStepContent = ({
- workflow,
-}: {
- workflow: WorkflowWithCurrentVersion;
-}) => {
+export const CommandMenuWorkflowEditStepContent = () => {
const flow = useFlowOrThrow();
const workflowSelectedNode = useRecoilComponentValue(
workflowSelectedNodeComponentState,
);
- const { updateTrigger } = useUpdateWorkflowVersionTrigger({ workflow });
- const { updateStep } = useUpdateStep({
- workflow,
- });
+ const { updateTrigger } = useUpdateWorkflowVersionTrigger();
+ const { updateStep } = useUpdateStep();
if (!isDefined(workflowSelectedNode)) {
return null;
diff --git a/packages/twenty-front/src/modules/command-menu/pages/workflow/trigger-type/components/CommandMenuWorkflowSelectTriggerTypeContent.tsx b/packages/twenty-front/src/modules/command-menu/pages/workflow/trigger-type/components/CommandMenuWorkflowSelectTriggerTypeContent.tsx
index b55084b4ac..7c405bfb59 100644
--- a/packages/twenty-front/src/modules/command-menu/pages/workflow/trigger-type/components/CommandMenuWorkflowSelectTriggerTypeContent.tsx
+++ b/packages/twenty-front/src/modules/command-menu/pages/workflow/trigger-type/components/CommandMenuWorkflowSelectTriggerTypeContent.tsx
@@ -24,7 +24,7 @@ export const CommandMenuWorkflowSelectTriggerTypeContent = ({
workflow: WorkflowWithCurrentVersion;
}) => {
const { getIcon } = useIcons();
- const { updateTrigger } = useUpdateWorkflowVersionTrigger({ workflow });
+ const { updateTrigger } = useUpdateWorkflowVersionTrigger();
const { activeNonSystemObjectMetadataItems } =
useFilteredObjectMetadataItems();
diff --git a/packages/twenty-front/src/modules/object-record/record-show/components/CardComponents.tsx b/packages/twenty-front/src/modules/object-record/record-show/components/CardComponents.tsx
index 6a407fca56..956f658a07 100644
--- a/packages/twenty-front/src/modules/object-record/record-show/components/CardComponents.tsx
+++ b/packages/twenty-front/src/modules/object-record/record-show/components/CardComponents.tsx
@@ -158,7 +158,7 @@ export const CardComponents: Record = {
>
}>
-
+
);
diff --git a/packages/twenty-front/src/modules/serverless-functions/components/ServerlessFunctionExecutionResult.tsx b/packages/twenty-front/src/modules/serverless-functions/components/ServerlessFunctionExecutionResult.tsx
index 40c3ddb3ab..65182f635d 100644
--- a/packages/twenty-front/src/modules/serverless-functions/components/ServerlessFunctionExecutionResult.tsx
+++ b/packages/twenty-front/src/modules/serverless-functions/components/ServerlessFunctionExecutionResult.tsx
@@ -2,7 +2,7 @@ import {
type ExecutionStatus,
WorkflowStepExecutionResult,
} from '@/workflow/components/WorkflowStepExecutionResult';
-import { type ServerlessFunctionTestData } from '@/workflow/states/serverlessFunctionTestDataFamilyState';
+import { type ServerlessFunctionTestData } from '@/workflow/workflow-steps/workflow-actions/code-action/states/serverlessFunctionTestDataFamilyState';
import { ServerlessFunctionExecutionStatus } from '~/generated-metadata/graphql';
export const ServerlessFunctionExecutionResult = ({
diff --git a/packages/twenty-front/src/modules/serverless-functions/hooks/useTestServerlessFunction.ts b/packages/twenty-front/src/modules/serverless-functions/hooks/useTestServerlessFunction.ts
index 585f619666..04c208aa1b 100644
--- a/packages/twenty-front/src/modules/serverless-functions/hooks/useTestServerlessFunction.ts
+++ b/packages/twenty-front/src/modules/serverless-functions/hooks/useTestServerlessFunction.ts
@@ -1,9 +1,9 @@
import { useExecuteOneServerlessFunction } from '@/settings/serverless-functions/hooks/useExecuteOneServerlessFunction';
-import { serverlessFunctionTestDataFamilyState } from '@/workflow/states/serverlessFunctionTestDataFamilyState';
+import { serverlessFunctionTestDataFamilyState } from '@/workflow/workflow-steps/workflow-actions/code-action/states/serverlessFunctionTestDataFamilyState';
import { useState } from 'react';
import { useRecoilState } from 'recoil';
-import { sleep } from '~/utils/sleep';
import { isDefined } from 'twenty-shared/utils';
+import { sleep } from '~/utils/sleep';
export const useTestServerlessFunction = ({
serverlessFunctionId,
diff --git a/packages/twenty-front/src/modules/settings/serverless-functions/components/tabs/SettingsServerlessFunctionTestTab.tsx b/packages/twenty-front/src/modules/settings/serverless-functions/components/tabs/SettingsServerlessFunctionTestTab.tsx
index e32f219051..b40aa951da 100644
--- a/packages/twenty-front/src/modules/settings/serverless-functions/components/tabs/SettingsServerlessFunctionTestTab.tsx
+++ b/packages/twenty-front/src/modules/settings/serverless-functions/components/tabs/SettingsServerlessFunctionTestTab.tsx
@@ -1,5 +1,5 @@
import { ServerlessFunctionExecutionResult } from '@/serverless-functions/components/ServerlessFunctionExecutionResult';
-import { serverlessFunctionTestDataFamilyState } from '@/workflow/states/serverlessFunctionTestDataFamilyState';
+import { serverlessFunctionTestDataFamilyState } from '@/workflow/workflow-steps/workflow-actions/code-action/states/serverlessFunctionTestDataFamilyState';
import styled from '@emotion/styled';
import { useRecoilState } from 'recoil';
import { H2Title, IconPlayerPlay } from 'twenty-ui/display';
diff --git a/packages/twenty-front/src/modules/settings/serverless-functions/hooks/useServerlessFunctionUpdateFormState.ts b/packages/twenty-front/src/modules/settings/serverless-functions/hooks/useServerlessFunctionUpdateFormState.ts
index 09bd194356..f77bcc2b7f 100644
--- a/packages/twenty-front/src/modules/settings/serverless-functions/hooks/useServerlessFunctionUpdateFormState.ts
+++ b/packages/twenty-front/src/modules/settings/serverless-functions/hooks/useServerlessFunctionUpdateFormState.ts
@@ -2,7 +2,7 @@ import { INDEX_FILE_PATH } from '@/serverless-functions/constants/IndexFilePath'
import { getFunctionInputFromSourceCode } from '@/serverless-functions/utils/getFunctionInputFromSourceCode';
import { useGetOneServerlessFunction } from '@/settings/serverless-functions/hooks/useGetOneServerlessFunction';
import { useGetOneServerlessFunctionSourceCode } from '@/settings/serverless-functions/hooks/useGetOneServerlessFunctionSourceCode';
-import { serverlessFunctionTestDataFamilyState } from '@/workflow/states/serverlessFunctionTestDataFamilyState';
+import { serverlessFunctionTestDataFamilyState } from '@/workflow/workflow-steps/workflow-actions/code-action/states/serverlessFunctionTestDataFamilyState';
import { type Dispatch, type SetStateAction, useState } from 'react';
import { useRecoilState } from 'recoil';
import { type FindOneServerlessFunctionSourceCodeQuery } from '~/generated-metadata/graphql';
diff --git a/packages/twenty-front/src/modules/workflow/hooks/__tests__/useGetUpdatableWorkflowVersion.test.ts b/packages/twenty-front/src/modules/workflow/hooks/__tests__/useGetUpdatableWorkflowVersion.test.ts
index 036444ae22..92c93f2ae9 100644
--- a/packages/twenty-front/src/modules/workflow/hooks/__tests__/useGetUpdatableWorkflowVersion.test.ts
+++ b/packages/twenty-front/src/modules/workflow/hooks/__tests__/useGetUpdatableWorkflowVersion.test.ts
@@ -1,8 +1,16 @@
-import { renderHook } from '@testing-library/react';
-import { useGetUpdatableWorkflowVersion } from '@/workflow/hooks/useGetUpdatableWorkflowVersion';
+import { useGetUpdatableWorkflowVersionOrThrow } from '@/workflow/hooks/useGetUpdatableWorkflowVersionOrThrow';
import { type WorkflowWithCurrentVersion } from '@/workflow/types/Workflow';
+import { renderHook } from '@testing-library/react';
const mockCreateDraftFromWorkflowVersion = jest.fn().mockResolvedValue('457');
+const mockWorkflowId = '123';
+const mockWorkflow = {
+ id: mockWorkflowId,
+ currentVersion: {
+ id: '456',
+ status: 'DRAFT',
+ },
+} as WorkflowWithCurrentVersion;
jest.mock('@/workflow/hooks/useCreateDraftFromWorkflowVersion', () => ({
useCreateDraftFromWorkflowVersion: () => ({
@@ -10,43 +18,75 @@ jest.mock('@/workflow/hooks/useCreateDraftFromWorkflowVersion', () => ({
}),
}));
-describe('useGetUpdatableWorkflowVersion', () => {
- const mockWorkflow = (status: 'ACTIVE' | 'DRAFT') =>
- ({
- id: '123',
- __typename: 'Workflow',
- statuses: [],
- lastPublishedVersionId: '1',
- name: 'toto',
- versions: [],
- currentVersion: {
- id: '456',
- name: 'toto',
- createdAt: '2024-07-03T20:03:35.064Z',
- updatedAt: '2024-07-03T20:03:35.064Z',
- workflowId: '123',
- __typename: 'WorkflowVersion',
- status,
- steps: [],
- trigger: null,
- },
- }) as WorkflowWithCurrentVersion;
+jest.mock(
+ '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue',
+ () => ({
+ useRecoilComponentValue: jest.fn(() => mockWorkflowId),
+ }),
+);
- it('should not create workflow version if draft version exists', async () => {
- const { result } = renderHook(() => useGetUpdatableWorkflowVersion());
- const workflowVersionId = await result.current.getUpdatableWorkflowVersion(
- mockWorkflow('DRAFT'),
+jest.mock('@/workflow/hooks/useWorkflowWithCurrentVersion', () => ({
+ useWorkflowWithCurrentVersion: jest.fn((workflowId) =>
+ workflowId === mockWorkflowId ? mockWorkflow : undefined,
+ ),
+}));
+
+describe('useGetUpdatableWorkflowVersionOrThrow', () => {
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
+
+ it('should return draft version id when current version is draft', async () => {
+ const { result } = renderHook(() =>
+ useGetUpdatableWorkflowVersionOrThrow(),
);
+ const workflowVersionId =
+ await result.current.getUpdatableWorkflowVersion();
+
expect(mockCreateDraftFromWorkflowVersion).not.toHaveBeenCalled();
expect(workflowVersionId).toEqual('456');
});
- it('should create workflow version if no draft version exists', async () => {
- const { result } = renderHook(() => useGetUpdatableWorkflowVersion());
- const workflowVersionId = await result.current.getUpdatableWorkflowVersion(
- mockWorkflow('ACTIVE'),
+ it('should create draft from active version when current version is active', async () => {
+ // Mock the workflow to have an active version
+ const mockActiveWorkflow = {
+ ...mockWorkflow,
+ currentVersion: {
+ ...mockWorkflow.currentVersion,
+ status: 'ACTIVE',
+ },
+ } as WorkflowWithCurrentVersion;
+
+ const {
+ useWorkflowWithCurrentVersion,
+ } = require('@/workflow/hooks/useWorkflowWithCurrentVersion');
+ useWorkflowWithCurrentVersion.mockReturnValue(mockActiveWorkflow);
+
+ const { result } = renderHook(() =>
+ useGetUpdatableWorkflowVersionOrThrow(),
);
- expect(mockCreateDraftFromWorkflowVersion).toHaveBeenCalled();
+ const workflowVersionId =
+ await result.current.getUpdatableWorkflowVersion();
+
+ expect(mockCreateDraftFromWorkflowVersion).toHaveBeenCalledWith({
+ workflowId: mockWorkflowId,
+ workflowVersionIdToCopy: '456',
+ });
expect(workflowVersionId).toEqual('457');
});
+
+ it('should throw an error when workflow is not found', async () => {
+ const {
+ useWorkflowWithCurrentVersion,
+ } = require('@/workflow/hooks/useWorkflowWithCurrentVersion');
+ useWorkflowWithCurrentVersion.mockReturnValue(undefined);
+
+ const { result } = renderHook(() =>
+ useGetUpdatableWorkflowVersionOrThrow(),
+ );
+
+ await expect(result.current.getUpdatableWorkflowVersion()).rejects.toThrow(
+ 'Failed to get updatable workflow version',
+ );
+ });
});
diff --git a/packages/twenty-front/src/modules/workflow/hooks/useGetUpdatableWorkflowVersion.ts b/packages/twenty-front/src/modules/workflow/hooks/useGetUpdatableWorkflowVersion.ts
deleted file mode 100644
index 327cdd043f..0000000000
--- a/packages/twenty-front/src/modules/workflow/hooks/useGetUpdatableWorkflowVersion.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { type WorkflowWithCurrentVersion } from '@/workflow/types/Workflow';
-import { useCreateDraftFromWorkflowVersion } from '@/workflow/hooks/useCreateDraftFromWorkflowVersion';
-
-export const useGetUpdatableWorkflowVersion = () => {
- const { createDraftFromWorkflowVersion } =
- useCreateDraftFromWorkflowVersion();
- const getUpdatableWorkflowVersion = async (
- workflow: WorkflowWithCurrentVersion,
- ) => {
- if (workflow.currentVersion.status === 'DRAFT') {
- return workflow.currentVersion.id;
- }
- return await createDraftFromWorkflowVersion({
- workflowId: workflow.id,
- workflowVersionIdToCopy: workflow.currentVersion.id,
- });
- };
-
- return { getUpdatableWorkflowVersion };
-};
diff --git a/packages/twenty-front/src/modules/workflow/hooks/useGetUpdatableWorkflowVersionOrThrow.ts b/packages/twenty-front/src/modules/workflow/hooks/useGetUpdatableWorkflowVersionOrThrow.ts
new file mode 100644
index 0000000000..7e1eac57bf
--- /dev/null
+++ b/packages/twenty-front/src/modules/workflow/hooks/useGetUpdatableWorkflowVersionOrThrow.ts
@@ -0,0 +1,37 @@
+import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
+import { useCreateDraftFromWorkflowVersion } from '@/workflow/hooks/useCreateDraftFromWorkflowVersion';
+import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion';
+import { workflowVisualizerWorkflowIdComponentState } from '@/workflow/states/workflowVisualizerWorkflowIdComponentState';
+import { isDefined } from 'twenty-shared/utils';
+
+export const useGetUpdatableWorkflowVersionOrThrow = () => {
+ const { createDraftFromWorkflowVersion } =
+ useCreateDraftFromWorkflowVersion();
+ const workflowVisualizerWorkflowId = useRecoilComponentValue(
+ workflowVisualizerWorkflowIdComponentState,
+ );
+ const workflow = useWorkflowWithCurrentVersion(workflowVisualizerWorkflowId);
+
+ const getUpdatableWorkflowVersion = async (): Promise => {
+ if (!isDefined(workflowVisualizerWorkflowId) || !isDefined(workflow)) {
+ throw new Error('Failed to get updatable workflow version');
+ }
+
+ if (workflow.currentVersion.status === 'DRAFT') {
+ return workflow.currentVersion.id;
+ }
+
+ const draftVersionId = await createDraftFromWorkflowVersion({
+ workflowId: workflowVisualizerWorkflowId,
+ workflowVersionIdToCopy: workflow.currentVersion.id,
+ });
+
+ if (!isDefined(draftVersionId)) {
+ throw new Error('Failed to create draft version');
+ }
+
+ return draftVersionId;
+ };
+
+ return { getUpdatableWorkflowVersion };
+};
diff --git a/packages/twenty-front/src/modules/workflow/utils/__tests__/assertWorkflowWithCurrentVersionIsDefined.test.ts b/packages/twenty-front/src/modules/workflow/utils/__tests__/assertWorkflowWithCurrentVersionIsDefined.test.ts
deleted file mode 100644
index af417e2801..0000000000
--- a/packages/twenty-front/src/modules/workflow/utils/__tests__/assertWorkflowWithCurrentVersionIsDefined.test.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { type WorkflowWithCurrentVersion } from '@/workflow/types/Workflow';
-import { assertWorkflowWithCurrentVersionIsDefined } from '../assertWorkflowWithCurrentVersionIsDefined';
-
-it('throws when provided workflow is undefined', () => {
- expect(() => {
- assertWorkflowWithCurrentVersionIsDefined(undefined);
- }).toThrow();
-});
-
-it("throws when provided workflow's current version is undefined", () => {
- expect(() => {
- assertWorkflowWithCurrentVersionIsDefined(
- {} as unknown as WorkflowWithCurrentVersion,
- );
- }).toThrow();
-});
diff --git a/packages/twenty-front/src/modules/workflow/utils/assertWorkflowWithCurrentVersionIsDefined.ts b/packages/twenty-front/src/modules/workflow/utils/assertWorkflowWithCurrentVersionIsDefined.ts
deleted file mode 100644
index 4e3350815c..0000000000
--- a/packages/twenty-front/src/modules/workflow/utils/assertWorkflowWithCurrentVersionIsDefined.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import {
- type Workflow,
- type WorkflowVersion,
- type WorkflowWithCurrentVersion,
-} from '@/workflow/types/Workflow';
-import { isDefined } from 'twenty-shared/utils';
-
-// eslint-disable-next-line prefer-arrow/prefer-arrow-functions
-export function assertWorkflowWithCurrentVersionIsDefined(
- workflow: WorkflowWithCurrentVersion | undefined,
-): asserts workflow is Workflow & { currentVersion: WorkflowVersion } {
- if (!isDefined(workflow) || !isDefined(workflow.currentVersion)) {
- throw new Error('Expected workflow and its current version to be defined');
- }
-}
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 d006ba26b7..a7651b61c2 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
@@ -1,5 +1,7 @@
+import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
-import { type WorkflowWithCurrentVersion } from '@/workflow/types/Workflow';
+import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion';
+import { workflowVisualizerWorkflowIdComponentState } from '@/workflow/states/workflowVisualizerWorkflowIdComponentState';
import { WorkflowDiagramBlankEdge } from '@/workflow/workflow-diagram/components/WorkflowDiagramBlankEdge';
import { WorkflowDiagramCanvasBase } from '@/workflow/workflow-diagram/components/WorkflowDiagramCanvasBase';
import { WorkflowDiagramCanvasEditableEffect } from '@/workflow/workflow-diagram/components/WorkflowDiagramCanvasEditableEffect';
@@ -23,14 +25,14 @@ import { addEdge, type Connection, ReactFlowProvider } from '@xyflow/react';
import React from 'react';
import { isDefined } from 'twenty-shared/utils';
-export const WorkflowDiagramCanvasEditable = ({
- workflowWithCurrentVersion,
-}: {
- workflowWithCurrentVersion: WorkflowWithCurrentVersion;
-}) => {
- const tagProps = getWorkflowVersionStatusTagProps({
- workflowVersionStatus: workflowWithCurrentVersion.currentVersion.status,
- });
+export const WorkflowDiagramCanvasEditable = () => {
+ const workflowVisualizerWorkflowId = useRecoilComponentValue(
+ workflowVisualizerWorkflowIdComponentState,
+ );
+
+ const workflowWithCurrentVersion = useWorkflowWithCurrentVersion(
+ workflowVisualizerWorkflowId,
+ );
const setWorkflowDiagram = useSetRecoilComponentState(
workflowDiagramComponentState,
@@ -40,21 +42,13 @@ export const WorkflowDiagramCanvasEditable = ({
workflowDiagramRightClickMenuPositionState,
);
- const { createEdge } = useCreateEdge({
- workflow: workflowWithCurrentVersion,
- });
+ const { createEdge } = useCreateEdge();
- const { deleteEdge } = useDeleteEdge({
- workflow: workflowWithCurrentVersion,
- });
+ const { deleteEdge } = useDeleteEdge();
- const { updateStep } = useUpdateStep({
- workflow: workflowWithCurrentVersion,
- });
+ const { updateStep } = useUpdateStep();
- const { updateTrigger } = useUpdateWorkflowVersionTrigger({
- workflow: workflowWithCurrentVersion,
- });
+ const { updateTrigger } = useUpdateWorkflowVersionTrigger();
const onConnect = (edgeConnect: Connection) => {
setWorkflowDiagram((diagram) => {
@@ -107,6 +101,14 @@ export const WorkflowDiagramCanvasEditable = ({
}
};
+ if (!isDefined(workflowWithCurrentVersion)) {
+ return null;
+ }
+
+ const tagProps = getWorkflowVersionStatusTagProps({
+ workflowVersionStatus: workflowWithCurrentVersion.currentVersion.status,
+ });
+
const handlePaneContextMenu = ({ x, y }: { x: number; y: number }) => {
setWorkflowDiagramRightClickMenuPosition({
x,
diff --git a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramDefaultEdgeEditable.tsx b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramDefaultEdgeEditable.tsx
index efbf80695b..cd1fa29ae0 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramDefaultEdgeEditable.tsx
+++ b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramDefaultEdgeEditable.tsx
@@ -61,7 +61,7 @@ export const WorkflowDiagramDefaultEdgeEditable = ({
const { createStep } = useCreateStep({ workflow });
- const { deleteEdge } = useDeleteEdge({ workflow });
+ const { deleteEdge } = useDeleteEdge();
const { startNodeCreation, isNodeCreationStarted } = useStartNodeCreation();
diff --git a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramEffect.tsx b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramEffect.tsx
index e3e50e2f4b..b1dfbddea0 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramEffect.tsx
+++ b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramEffect.tsx
@@ -1,13 +1,13 @@
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
+import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
import { useStepsOutputSchema } from '@/workflow/hooks/useStepsOutputSchema';
+import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion';
import { flowComponentState } from '@/workflow/states/flowComponentState';
import { workflowLastCreatedStepIdComponentState } from '@/workflow/states/workflowLastCreatedStepIdComponentState';
-import {
- type WorkflowVersion,
- type WorkflowWithCurrentVersion,
-} from '@/workflow/types/Workflow';
+import { workflowVisualizerWorkflowIdComponentState } from '@/workflow/states/workflowVisualizerWorkflowIdComponentState';
+import { type WorkflowVersion } from '@/workflow/types/Workflow';
import { workflowDiagramComponentState } from '@/workflow/workflow-diagram/states/workflowDiagramComponentState';
import { getWorkflowVersionDiagram } from '@/workflow/workflow-diagram/utils/getWorkflowVersionDiagram';
@@ -18,11 +18,15 @@ import { useRecoilCallback } from 'recoil';
import { isDefined } from 'twenty-shared/utils';
import { FeatureFlagKey } from '~/generated/graphql';
-export const WorkflowDiagramEffect = ({
- workflowWithCurrentVersion,
-}: {
- workflowWithCurrentVersion: WorkflowWithCurrentVersion | undefined;
-}) => {
+export const WorkflowDiagramEffect = () => {
+ const workflowVisualizerWorkflowId = useRecoilComponentValue(
+ workflowVisualizerWorkflowIdComponentState,
+ );
+
+ const workflowWithCurrentVersion = useWorkflowWithCurrentVersion(
+ workflowVisualizerWorkflowId,
+ );
+
const workflowDiagramState = useRecoilComponentCallbackState(
workflowDiagramComponentState,
);
diff --git a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramFilterEdgeEditable.tsx b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramFilterEdgeEditable.tsx
index 3ee717c3ca..558731e9ef 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramFilterEdgeEditable.tsx
+++ b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramFilterEdgeEditable.tsx
@@ -9,8 +9,6 @@ import { useOpenDropdown } from '@/ui/layout/dropdown/hooks/useOpenDropdown';
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
-import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion';
-import { workflowVisualizerWorkflowIdComponentState } from '@/workflow/states/workflowVisualizerWorkflowIdComponentState';
import { WorkflowDiagramBaseEdge } from '@/workflow/workflow-diagram/components/WorkflowDiagramBaseEdge';
import { WorkflowDiagramEdgeButtonGroup } from '@/workflow/workflow-diagram/components/WorkflowDiagramEdgeButtonGroup';
import { WorkflowDiagramEdgeV2Container } from '@/workflow/workflow-diagram/components/WorkflowDiagramEdgeV2Container';
@@ -107,15 +105,10 @@ export const WorkflowDiagramFilterEdgeEditable = ({
targetY,
});
- const workflowVisualizerWorkflowId = useRecoilComponentValue(
- workflowVisualizerWorkflowIdComponentState,
- );
- const workflow = useWorkflowWithCurrentVersion(workflowVisualizerWorkflowId);
-
const { isInRightDrawer } = useContext(ActionMenuContext);
- const { deleteStep } = useDeleteStep({ workflow });
- const { deleteEdge } = useDeleteEdge({ workflow });
+ const { deleteStep } = useDeleteStep();
+ const { deleteEdge } = useDeleteEdge();
const { startNodeCreation, isNodeCreationStarted } = useStartNodeCreation();
const setCommandMenuNavigationStack = useSetRecoilState(
diff --git a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramRightClickCommandMenu.tsx b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramRightClickCommandMenu.tsx
index 0f9880920c..0c1e729a9d 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramRightClickCommandMenu.tsx
+++ b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramRightClickCommandMenu.tsx
@@ -1,6 +1,4 @@
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
-import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion';
-import { workflowVisualizerWorkflowIdComponentState } from '@/workflow/states/workflowVisualizerWorkflowIdComponentState';
import { useCloseRightClickMenu } from '@/workflow/workflow-diagram/hooks/useCloseRightClickMenu';
import { useStartNodeCreation } from '@/workflow/workflow-diagram/hooks/useStartNodeCreation';
import { useWorkflowDiagramScreenToFlowPosition } from '@/workflow/workflow-diagram/hooks/useWorkflowDiagramScreenToFlowPosition';
@@ -43,17 +41,7 @@ export const WorkflowDiagramRightClickCommandMenu = () => {
workflowDiagramRightClickMenuPositionState,
);
- const workflowVisualizerWorkflowId = useRecoilComponentValue(
- workflowVisualizerWorkflowIdComponentState,
- );
-
- const workflowWithCurrentVersion = useWorkflowWithCurrentVersion(
- workflowVisualizerWorkflowId,
- );
-
- const { tidyUpWorkflowVersion } = useTidyUpWorkflowVersion({
- workflow: workflowWithCurrentVersion,
- });
+ const { tidyUpWorkflowVersion } = useTidyUpWorkflowVersion();
const handleReorderWorkflowDiagram = async () => {
await tidyUpWorkflowVersion();
diff --git a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramStepNodeEditable.tsx b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramStepNodeEditable.tsx
index 7455dea9e9..1559eca3a5 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramStepNodeEditable.tsx
+++ b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramStepNodeEditable.tsx
@@ -3,9 +3,7 @@ import { useWorkflowCommandMenu } from '@/command-menu/hooks/useWorkflowCommandM
import { commandMenuNavigationStackState } from '@/command-menu/states/commandMenuNavigationStackState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
-import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion';
import { workflowVisualizerWorkflowIdComponentState } from '@/workflow/states/workflowVisualizerWorkflowIdComponentState';
-import { assertWorkflowWithCurrentVersionIsDefined } from '@/workflow/utils/assertWorkflowWithCurrentVersionIsDefined';
import { WorkflowDiagramStepNodeEditableContent } from '@/workflow/workflow-diagram/components/WorkflowDiagramStepNodeEditableContent';
import { workflowSelectedNodeComponentState } from '@/workflow/workflow-diagram/states/workflowSelectedNodeComponentState';
import { type WorkflowDiagramStepNodeData } from '@/workflow/workflow-diagram/types/WorkflowDiagram';
@@ -31,14 +29,7 @@ export const WorkflowDiagramStepNodeEditable = ({
workflowVisualizerWorkflowIdComponentState,
);
- const workflowWithCurrentVersion = useWorkflowWithCurrentVersion(
- workflowVisualizerWorkflowId,
- );
- assertWorkflowWithCurrentVersionIsDefined(workflowWithCurrentVersion);
-
- const { deleteStep } = useDeleteStep({
- workflow: workflowWithCurrentVersion,
- });
+ const { deleteStep } = useDeleteStep();
const setWorkflowSelectedNode = useSetRecoilComponentState(
workflowSelectedNodeComponentState,
diff --git a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowVisualizer.tsx b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowVisualizer.tsx
index 16b1418b62..531ec6f69b 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowVisualizer.tsx
+++ b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowVisualizer.tsx
@@ -1,24 +1,11 @@
-import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion';
import { WorkflowDiagramCanvasEditable } from '@/workflow/workflow-diagram/components/WorkflowDiagramCanvasEditable';
import { WorkflowDiagramEffect } from '@/workflow/workflow-diagram/components/WorkflowDiagramEffect';
-import '@xyflow/react/dist/style.css';
-import { isDefined } from 'twenty-shared/utils';
-
-export const WorkflowVisualizer = ({ workflowId }: { workflowId: string }) => {
- const workflowWithCurrentVersion = useWorkflowWithCurrentVersion(workflowId);
-
- if (!isDefined(workflowWithCurrentVersion)) {
- return null;
- }
+export const WorkflowVisualizer = () => {
return (
<>
-
-
+
+
>
);
};
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/__tests__/useCreateStep.test.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/__tests__/useCreateStep.test.tsx
index 622849b79e..234064845e 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/__tests__/useCreateStep.test.tsx
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/__tests__/useCreateStep.test.tsx
@@ -4,7 +4,7 @@ import { RecoilRoot } from 'recoil';
import { WorkflowVisualizerComponentInstanceContext } from '../../../workflow-diagram/states/contexts/WorkflowVisualizerComponentInstanceContext';
import { useCreateStep } from '../useCreateStep';
-const mockCreateDraftFromWorkflowVersion = jest.fn().mockResolvedValue('457');
+const mockGetUpdatableWorkflowVersion = jest.fn();
const mockCreateWorkflowVersionStep = jest.fn().mockResolvedValue({
data: {
createWorkflowVersionStep: { createdStep: { id: '1', type: 'CODE' } },
@@ -20,9 +20,9 @@ jest.mock(
}),
);
-jest.mock('@/workflow/hooks/useCreateDraftFromWorkflowVersion', () => ({
- useCreateDraftFromWorkflowVersion: () => ({
- createDraftFromWorkflowVersion: mockCreateDraftFromWorkflowVersion,
+jest.mock('@/workflow/hooks/useGetUpdatableWorkflowVersionOrThrow', () => ({
+ useGetUpdatableWorkflowVersionOrThrow: () => ({
+ getUpdatableWorkflowVersion: mockGetUpdatableWorkflowVersion,
}),
}));
@@ -55,7 +55,14 @@ describe('useCreateStep', () => {
versions: [],
};
- it('should create step in draft version', async () => {
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
+
+ it('should create step in workflow version', async () => {
+ const mockWorkflowVersionId = 'version-123';
+ mockGetUpdatableWorkflowVersion.mockResolvedValue(mockWorkflowVersionId);
+
const { result } = renderHook(
() =>
useCreateStep({
@@ -74,6 +81,13 @@ describe('useCreateStep', () => {
});
});
- expect(mockCreateWorkflowVersionStep).toHaveBeenCalled();
+ expect(mockGetUpdatableWorkflowVersion).toHaveBeenCalled();
+ expect(mockCreateWorkflowVersionStep).toHaveBeenCalledWith({
+ workflowVersionId: mockWorkflowVersionId,
+ stepType: 'CODE',
+ parentStepId: 'parent-step-id',
+ nextStepId: undefined,
+ position: undefined,
+ });
});
});
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/__tests__/useDeleteStep.test.ts b/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/__tests__/useDeleteStep.test.ts
index 994b70b023..3fb8f43f1f 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/__tests__/useDeleteStep.test.ts
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/__tests__/useDeleteStep.test.ts
@@ -1,17 +1,10 @@
-import { type WorkflowWithCurrentVersion } from '@/workflow/types/Workflow';
import { useDeleteStep } from '@/workflow/workflow-steps/hooks/useDeleteStep';
import { renderHook } from '@testing-library/react';
-import { RecoilRoot } from 'recoil';
const mockDeleteWorkflowVersionStep = jest.fn();
-const updateOneRecordMock = jest.fn();
-const mockCreateDraftFromWorkflowVersion = jest.fn().mockResolvedValue('457');
-
-jest.mock('@/object-record/hooks/useUpdateOneRecord', () => ({
- useUpdateOneRecord: () => ({
- updateOneRecord: updateOneRecordMock,
- }),
-}));
+const mockGetUpdatableWorkflowVersion = jest.fn();
+const mockDeleteStepsOutputSchema = jest.fn();
+const mockCloseCommandMenu = jest.fn();
jest.mock('@/workflow/hooks/useDeleteWorkflowVersionStep', () => ({
useDeleteWorkflowVersionStep: () => ({
@@ -19,34 +12,51 @@ jest.mock('@/workflow/hooks/useDeleteWorkflowVersionStep', () => ({
}),
}));
-jest.mock('@/workflow/hooks/useCreateDraftFromWorkflowVersion', () => ({
- useCreateDraftFromWorkflowVersion: () => ({
- createDraftFromWorkflowVersion: mockCreateDraftFromWorkflowVersion,
+jest.mock('@/workflow/hooks/useGetUpdatableWorkflowVersionOrThrow', () => ({
+ useGetUpdatableWorkflowVersionOrThrow: () => ({
+ getUpdatableWorkflowVersion: mockGetUpdatableWorkflowVersion,
+ }),
+}));
+
+jest.mock('@/workflow/hooks/useStepsOutputSchema', () => ({
+ useStepsOutputSchema: () => ({
+ deleteStepsOutputSchema: mockDeleteStepsOutputSchema,
+ }),
+}));
+
+jest.mock('@/command-menu/hooks/useCommandMenu', () => ({
+ useCommandMenu: () => ({
+ closeCommandMenu: mockCloseCommandMenu,
}),
}));
describe('useDeleteStep', () => {
- const mockWorkflow = {
- id: '123',
- currentVersion: {
- id: '456',
- status: 'DRAFT',
- steps: [],
- trigger: { type: 'manual' },
- },
- versions: [],
- };
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
- it('should delete step in draft version', async () => {
- const { result } = renderHook(
- () =>
- useDeleteStep({
- workflow: mockWorkflow as unknown as WorkflowWithCurrentVersion,
- }),
- { wrapper: RecoilRoot },
- );
- await result.current.deleteStep('1');
+ it('should delete step and clean up dependencies', async () => {
+ const mockWorkflowVersionId = 'version-123';
+ const mockStepId = 'step-1';
+ const mockDeletedStepIds = ['step-1', 'step-2'];
- expect(mockDeleteWorkflowVersionStep).toHaveBeenCalled();
+ mockGetUpdatableWorkflowVersion.mockResolvedValue(mockWorkflowVersionId);
+ mockDeleteWorkflowVersionStep.mockResolvedValue({
+ deletedStepIds: mockDeletedStepIds,
+ });
+
+ const { result } = renderHook(() => useDeleteStep());
+ await result.current.deleteStep(mockStepId);
+
+ expect(mockGetUpdatableWorkflowVersion).toHaveBeenCalled();
+ expect(mockDeleteWorkflowVersionStep).toHaveBeenCalledWith({
+ workflowVersionId: mockWorkflowVersionId,
+ stepId: mockStepId,
+ });
+ expect(mockCloseCommandMenu).toHaveBeenCalled();
+ expect(mockDeleteStepsOutputSchema).toHaveBeenCalledWith({
+ stepIds: mockDeletedStepIds,
+ workflowVersionId: mockWorkflowVersionId,
+ });
});
});
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/__tests__/useUpdateStep.test.ts b/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/__tests__/useUpdateStep.test.ts
index 98fcfb4120..ac68bf0f12 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/__tests__/useUpdateStep.test.ts
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/__tests__/useUpdateStep.test.ts
@@ -1,15 +1,8 @@
-import { type WorkflowWithCurrentVersion } from '@/workflow/types/Workflow';
import { useUpdateStep } from '@/workflow/workflow-steps/hooks/useUpdateStep';
import { renderHook } from '@testing-library/react';
const mockUpdateWorkflowVersionStep = jest.fn();
-const mockCreateDraftFromWorkflowVersion = jest.fn().mockResolvedValue('457');
-
-jest.mock('recoil', () => ({
- useRecoilValue: () => 'parent-step-id',
- useSetRecoilState: () => jest.fn(),
- atom: (params: any) => params,
-}));
+const mockGetUpdatableWorkflowVersion = jest.fn();
jest.mock(
'@/workflow/workflow-steps/hooks/useUpdateWorkflowVersionStep',
@@ -20,35 +13,24 @@ jest.mock(
}),
);
-jest.mock('@/workflow/hooks/useCreateDraftFromWorkflowVersion', () => ({
- useCreateDraftFromWorkflowVersion: () => ({
- createDraftFromWorkflowVersion: mockCreateDraftFromWorkflowVersion,
+jest.mock('@/workflow/hooks/useGetUpdatableWorkflowVersionOrThrow', () => ({
+ useGetUpdatableWorkflowVersionOrThrow: () => ({
+ getUpdatableWorkflowVersion: mockGetUpdatableWorkflowVersion,
}),
}));
describe('useUpdateStep', () => {
- const mockWorkflow = {
- id: '123',
- currentVersion: {
- id: '456',
- status: 'DRAFT',
- steps: [],
- trigger: { type: 'manual' },
- },
- versions: [],
- };
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
- it('should update step in draft version', async () => {
- const { result } = renderHook(() =>
- useUpdateStep({
- workflow: mockWorkflow as unknown as WorkflowWithCurrentVersion,
- }),
- );
- await result.current.updateStep({
+ it('should update step in workflow version', async () => {
+ const mockWorkflowVersionId = 'version-123';
+ const mockStep = {
id: '1',
name: 'name',
valid: true,
- type: 'CODE',
+ type: 'CODE' as const,
settings: {
input: {
serverlessFunctionId: 'id',
@@ -65,8 +47,17 @@ describe('useUpdateStep', () => {
},
},
},
- });
+ };
- expect(mockUpdateWorkflowVersionStep).toHaveBeenCalled();
+ mockGetUpdatableWorkflowVersion.mockResolvedValue(mockWorkflowVersionId);
+
+ const { result } = renderHook(() => useUpdateStep());
+ await result.current.updateStep(mockStep);
+
+ expect(mockGetUpdatableWorkflowVersion).toHaveBeenCalled();
+ expect(mockUpdateWorkflowVersionStep).toHaveBeenCalledWith({
+ workflowVersionId: mockWorkflowVersionId,
+ step: mockStep,
+ });
});
});
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/useCreateEdge.ts b/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/useCreateEdge.ts
index 2e4ff77e67..d7f44ab018 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/useCreateEdge.ts
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/useCreateEdge.ts
@@ -1,20 +1,15 @@
-import { useGetUpdatableWorkflowVersion } from '@/workflow/hooks/useGetUpdatableWorkflowVersion';
-import { type WorkflowWithCurrentVersion } from '@/workflow/types/Workflow';
+import { useGetUpdatableWorkflowVersionOrThrow } from '@/workflow/hooks/useGetUpdatableWorkflowVersionOrThrow';
+import { type WorkflowDiagramEdge } from '@/workflow/workflow-diagram/types/WorkflowDiagramEdge';
import { useCreateWorkflowVersionEdge } from '@/workflow/workflow-steps/hooks/useCreateWorkflowVersionEdge';
import { useState } from 'react';
-import { isDefined } from 'twenty-shared/utils';
-import { type WorkflowDiagramEdge } from '@/workflow/workflow-diagram/types/WorkflowDiagramEdge';
-export const useCreateEdge = ({
- workflow,
-}: {
- workflow: WorkflowWithCurrentVersion;
-}) => {
+export const useCreateEdge = () => {
const [isLoading, setIsLoading] = useState(false);
const { createWorkflowVersionEdge } = useCreateWorkflowVersionEdge();
- const { getUpdatableWorkflowVersion } = useGetUpdatableWorkflowVersion();
+ const { getUpdatableWorkflowVersion } =
+ useGetUpdatableWorkflowVersionOrThrow();
const createEdge = async ({ source, target }: WorkflowDiagramEdge) => {
if (isLoading) {
@@ -24,11 +19,7 @@ export const useCreateEdge = ({
setIsLoading(true);
try {
- const workflowVersionId = await getUpdatableWorkflowVersion(workflow);
-
- if (!isDefined(workflowVersionId)) {
- throw new Error('Cannot find a workflow version to update');
- }
+ const workflowVersionId = await getUpdatableWorkflowVersion();
const createdEdge = (
await createWorkflowVersionEdge({
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/useCreateStep.ts b/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/useCreateStep.ts
index c49bd68426..0cccd36021 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/useCreateStep.ts
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/useCreateStep.ts
@@ -1,5 +1,5 @@
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
-import { useGetUpdatableWorkflowVersion } from '@/workflow/hooks/useGetUpdatableWorkflowVersion';
+import { useGetUpdatableWorkflowVersionOrThrow } from '@/workflow/hooks/useGetUpdatableWorkflowVersionOrThrow';
import { workflowLastCreatedStepIdComponentState } from '@/workflow/states/workflowLastCreatedStepIdComponentState';
import {
type WorkflowStepType,
@@ -24,7 +24,8 @@ export const useCreateStep = ({
workflowLastCreatedStepIdComponentState,
);
- const { getUpdatableWorkflowVersion } = useGetUpdatableWorkflowVersion();
+ const { getUpdatableWorkflowVersion } =
+ useGetUpdatableWorkflowVersionOrThrow();
if (!isDefined(workflow)) {
return {
@@ -50,11 +51,7 @@ export const useCreateStep = ({
setIsLoading(true);
try {
- const workflowVersionId = await getUpdatableWorkflowVersion(workflow);
-
- if (!isDefined(workflowVersionId)) {
- throw new Error("Couldn't get updatable workflow version");
- }
+ const workflowVersionId = await getUpdatableWorkflowVersion();
const workflowVersionStepChanges = (
await createWorkflowVersionStep({
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/useDeleteEdge.ts b/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/useDeleteEdge.ts
index aa4bfd6045..58cdf986a6 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/useDeleteEdge.ts
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/useDeleteEdge.ts
@@ -1,25 +1,17 @@
-import { useGetUpdatableWorkflowVersion } from '@/workflow/hooks/useGetUpdatableWorkflowVersion';
-import { type WorkflowWithCurrentVersion } from '@/workflow/types/Workflow';
-import { assertWorkflowWithCurrentVersionIsDefined } from '@/workflow/utils/assertWorkflowWithCurrentVersionIsDefined';
+import { useGetUpdatableWorkflowVersionOrThrow } from '@/workflow/hooks/useGetUpdatableWorkflowVersionOrThrow';
import { type WorkflowDiagramEdge } from '@/workflow/workflow-diagram/types/WorkflowDiagramEdge';
import { useDeleteWorkflowVersionEdge } from '@/workflow/workflow-steps/hooks/useDeleteWorkflowVersionEdge';
import { useState } from 'react';
-import { isDefined } from 'twenty-shared/utils';
-export const useDeleteEdge = ({
- workflow,
-}: {
- workflow: WorkflowWithCurrentVersion | undefined;
-}) => {
+export const useDeleteEdge = () => {
const [isLoading, setIsLoading] = useState(false);
const { deleteWorkflowVersionEdge } = useDeleteWorkflowVersionEdge();
- const { getUpdatableWorkflowVersion } = useGetUpdatableWorkflowVersion();
+ const { getUpdatableWorkflowVersion } =
+ useGetUpdatableWorkflowVersionOrThrow();
const deleteEdge = async ({ source, target }: WorkflowDiagramEdge) => {
- assertWorkflowWithCurrentVersionIsDefined(workflow);
-
if (isLoading) {
return;
}
@@ -27,11 +19,7 @@ export const useDeleteEdge = ({
setIsLoading(true);
try {
- const workflowVersionId = await getUpdatableWorkflowVersion(workflow);
-
- if (!isDefined(workflowVersionId)) {
- throw new Error('Cannot find a workflow version to update');
- }
+ const workflowVersionId = await getUpdatableWorkflowVersion();
const deletedEdge = (
await deleteWorkflowVersionEdge({
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/useDeleteStep.ts b/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/useDeleteStep.ts
index dcb72cc87b..5c9e3d0f61 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/useDeleteStep.ts
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/useDeleteStep.ts
@@ -1,30 +1,18 @@
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
import { useDeleteWorkflowVersionStep } from '@/workflow/hooks/useDeleteWorkflowVersionStep';
-import { useGetUpdatableWorkflowVersion } from '@/workflow/hooks/useGetUpdatableWorkflowVersion';
+import { useGetUpdatableWorkflowVersionOrThrow } from '@/workflow/hooks/useGetUpdatableWorkflowVersionOrThrow';
import { useStepsOutputSchema } from '@/workflow/hooks/useStepsOutputSchema';
-import { type WorkflowWithCurrentVersion } from '@/workflow/types/Workflow';
-import { assertWorkflowWithCurrentVersionIsDefined } from '@/workflow/utils/assertWorkflowWithCurrentVersionIsDefined';
-import { isDefined } from 'twenty-shared/utils';
-export const useDeleteStep = ({
- workflow,
-}: {
- workflow: WorkflowWithCurrentVersion | undefined;
-}) => {
+export const useDeleteStep = () => {
const { deleteWorkflowVersionStep } = useDeleteWorkflowVersionStep();
const { deleteStepsOutputSchema } = useStepsOutputSchema();
- const { getUpdatableWorkflowVersion } = useGetUpdatableWorkflowVersion();
+ const { getUpdatableWorkflowVersion } =
+ useGetUpdatableWorkflowVersionOrThrow();
const { closeCommandMenu } = useCommandMenu();
const deleteStep = async (stepId: string) => {
- assertWorkflowWithCurrentVersionIsDefined(workflow);
-
- const workflowVersionId = await getUpdatableWorkflowVersion(workflow);
-
- if (!isDefined(workflowVersionId)) {
- throw new Error('Could not find workflow version');
- }
+ const workflowVersionId = await getUpdatableWorkflowVersion();
const workflowVersionStepChanges = await deleteWorkflowVersionStep({
workflowVersionId,
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/useUpdateStep.ts b/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/useUpdateStep.ts
index 94d65d2f99..486947af70 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/useUpdateStep.ts
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/useUpdateStep.ts
@@ -1,29 +1,14 @@
-import { useGetUpdatableWorkflowVersion } from '@/workflow/hooks/useGetUpdatableWorkflowVersion';
-import {
- type WorkflowStep,
- type WorkflowWithCurrentVersion,
-} from '@/workflow/types/Workflow';
+import { useGetUpdatableWorkflowVersionOrThrow } from '@/workflow/hooks/useGetUpdatableWorkflowVersionOrThrow';
+import { type WorkflowStep } from '@/workflow/types/Workflow';
import { useUpdateWorkflowVersionStep } from '@/workflow/workflow-steps/hooks/useUpdateWorkflowVersionStep';
-import { isDefined } from 'twenty-shared/utils';
-export const useUpdateStep = ({
- workflow,
-}: {
- workflow: WorkflowWithCurrentVersion;
-}) => {
- const { getUpdatableWorkflowVersion } = useGetUpdatableWorkflowVersion();
+export const useUpdateStep = () => {
+ const { getUpdatableWorkflowVersion } =
+ useGetUpdatableWorkflowVersionOrThrow();
const { updateWorkflowVersionStep } = useUpdateWorkflowVersionStep();
const updateStep = async (updatedStep: T) => {
- if (!isDefined(workflow.currentVersion)) {
- throw new Error('Could not find current workflow version');
- }
-
- const workflowVersionId = await getUpdatableWorkflowVersion(workflow);
-
- if (!isDefined(workflowVersionId)) {
- throw new Error('Workflow version not found');
- }
+ const workflowVersionId = await getUpdatableWorkflowVersion();
await updateWorkflowVersionStep({
workflowVersionId,
diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionServerlessFunction.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionServerlessFunction.tsx
index 4be8bc14ff..2a5c56c656 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionServerlessFunction.tsx
+++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionServerlessFunction.tsx
@@ -8,7 +8,7 @@ import {
Breadcrumb,
type BreadcrumbProps,
} from '@/ui/navigation/bread-crumb/components/Breadcrumb';
-import { useGetUpdatableWorkflowVersion } from '@/workflow/hooks/useGetUpdatableWorkflowVersion';
+import { useGetUpdatableWorkflowVersionOrThrow } from '@/workflow/hooks/useGetUpdatableWorkflowVersionOrThrow';
import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion';
import { workflowVisualizerWorkflowIdComponentState } from '@/workflow/states/workflowVisualizerWorkflowIdComponentState';
import { type WorkflowCodeAction } from '@/workflow/types/Workflow';
@@ -30,11 +30,11 @@ import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTab
import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
-import { serverlessFunctionTestDataFamilyState } from '@/workflow/states/serverlessFunctionTestDataFamilyState';
import { WorkflowStepBody } from '@/workflow/workflow-steps/components/WorkflowStepBody';
import { WorkflowEditActionServerlessFunctionFields } from '@/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionServerlessFunctionFields';
import { WorkflowServerlessFunctionCodeEditor } from '@/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowServerlessFunctionCodeEditor';
import { WORKFLOW_SERVERLESS_FUNCTION_TAB_LIST_COMPONENT_ID } from '@/workflow/workflow-steps/workflow-actions/code-action/constants/WorkflowServerlessFunctionTabListComponentId';
+import { serverlessFunctionTestDataFamilyState } from '@/workflow/workflow-steps/workflow-actions/code-action/states/serverlessFunctionTestDataFamilyState';
import { WorkflowServerlessFunctionTabId } from '@/workflow/workflow-steps/workflow-actions/code-action/types/WorkflowServerlessFunctionTabId';
import { getWrongExportedFunctionMarkers } from '@/workflow/workflow-steps/workflow-actions/code-action/utils/getWrongExportedFunctionMarkers';
import { useActionHeaderTypeOrThrow } from '@/workflow/workflow-steps/workflow-actions/hooks/useActionHeaderTypeOrThrow';
@@ -140,7 +140,8 @@ export const WorkflowEditActionServerlessFunction = ({
);
const { updateOneServerlessFunction } =
useUpdateOneServerlessFunction(serverlessFunctionId);
- const { getUpdatableWorkflowVersion } = useGetUpdatableWorkflowVersion();
+ const { getUpdatableWorkflowVersion } =
+ useGetUpdatableWorkflowVersionOrThrow();
const workflowVisualizerWorkflowId = useRecoilComponentValue(
workflowVisualizerWorkflowIdComponentState,
@@ -323,7 +324,7 @@ export const WorkflowEditActionServerlessFunction = ({
if (actionOptions.readonly === true || !isDefined(workflow)) {
return;
}
- await getUpdatableWorkflowVersion(workflow);
+ await getUpdatableWorkflowVersion();
await onCodeChange(value);
};
diff --git a/packages/twenty-front/src/modules/workflow/states/serverlessFunctionTestDataFamilyState.ts b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/code-action/states/serverlessFunctionTestDataFamilyState.ts
similarity index 100%
rename from packages/twenty-front/src/modules/workflow/states/serverlessFunctionTestDataFamilyState.ts
rename to packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/code-action/states/serverlessFunctionTestDataFamilyState.ts
diff --git a/packages/twenty-front/src/modules/workflow/workflow-trigger/hooks/__tests__/useUpdateWorkflowVersionTrigger.test.ts b/packages/twenty-front/src/modules/workflow/workflow-trigger/hooks/__tests__/useUpdateWorkflowVersionTrigger.test.ts
index 1b68d46a7a..17474e8c28 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-trigger/hooks/__tests__/useUpdateWorkflowVersionTrigger.test.ts
+++ b/packages/twenty-front/src/modules/workflow/workflow-trigger/hooks/__tests__/useUpdateWorkflowVersionTrigger.test.ts
@@ -1,9 +1,6 @@
-import { act, renderHook } from '@testing-library/react';
+import { type WorkflowTrigger } from '@/workflow/types/Workflow';
import { useUpdateWorkflowVersionTrigger } from '@/workflow/workflow-trigger/hooks/useUpdateWorkflowVersionTrigger';
-import {
- type WorkflowTrigger,
- type WorkflowWithCurrentVersion,
-} from '@/workflow/types/Workflow';
+import { act, renderHook } from '@testing-library/react';
const mockUpdateOneRecord = jest.fn();
const mockGetUpdatableWorkflowVersion = jest.fn();
@@ -15,8 +12,8 @@ jest.mock('@/object-record/hooks/useUpdateOneRecord', () => ({
})),
}));
-jest.mock('@/workflow/hooks/useGetUpdatableWorkflowVersion', () => ({
- useGetUpdatableWorkflowVersion: jest.fn(() => ({
+jest.mock('@/workflow/hooks/useGetUpdatableWorkflowVersionOrThrow', () => ({
+ useGetUpdatableWorkflowVersionOrThrow: jest.fn(() => ({
getUpdatableWorkflowVersion: mockGetUpdatableWorkflowVersion,
})),
}));
@@ -28,11 +25,6 @@ jest.mock('@/workflow/hooks/useComputeStepOutputSchema', () => ({
}));
describe('useUpdateWorkflowVersionTrigger', () => {
- const mockWorkflow = {
- id: 'workflow-id',
- currentVersion: { id: 'version-id' },
- } as WorkflowWithCurrentVersion;
-
const trigger: WorkflowTrigger = {
name: 'Company created',
type: 'DATABASE_EVENT',
@@ -53,15 +45,13 @@ describe('useUpdateWorkflowVersionTrigger', () => {
data: { computeStepOutputSchema: { field1: 'string' } },
});
- const { result } = renderHook(() =>
- useUpdateWorkflowVersionTrigger({ workflow: mockWorkflow }),
- );
+ const { result } = renderHook(() => useUpdateWorkflowVersionTrigger());
await act(async () => {
await result.current.updateTrigger(trigger);
});
- expect(mockGetUpdatableWorkflowVersion).toHaveBeenCalledWith(mockWorkflow);
+ expect(mockGetUpdatableWorkflowVersion).toHaveBeenCalled();
expect(mockComputeStepOutputSchema).toHaveBeenCalledWith({ step: trigger });
expect(mockUpdateOneRecord).toHaveBeenCalledWith({
idToUpdate: 'version-id',
@@ -77,9 +67,7 @@ describe('useUpdateWorkflowVersionTrigger', () => {
it('skips output schema computation when disabled', async () => {
mockGetUpdatableWorkflowVersion.mockResolvedValue('version-id');
- const { result } = renderHook(() =>
- useUpdateWorkflowVersionTrigger({ workflow: mockWorkflow }),
- );
+ const { result } = renderHook(() => useUpdateWorkflowVersionTrigger());
await act(async () => {
await result.current.updateTrigger(trigger, {
diff --git a/packages/twenty-front/src/modules/workflow/workflow-trigger/hooks/useUpdateWorkflowVersionTrigger.ts b/packages/twenty-front/src/modules/workflow/workflow-trigger/hooks/useUpdateWorkflowVersionTrigger.ts
index 9fdf691222..684b063f1c 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-trigger/hooks/useUpdateWorkflowVersionTrigger.ts
+++ b/packages/twenty-front/src/modules/workflow/workflow-trigger/hooks/useUpdateWorkflowVersionTrigger.ts
@@ -1,25 +1,20 @@
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
import { useComputeStepOutputSchema } from '@/workflow/hooks/useComputeStepOutputSchema';
-import { useGetUpdatableWorkflowVersion } from '@/workflow/hooks/useGetUpdatableWorkflowVersion';
+import { useGetUpdatableWorkflowVersionOrThrow } from '@/workflow/hooks/useGetUpdatableWorkflowVersionOrThrow';
import {
type WorkflowTrigger,
type WorkflowVersion,
- type WorkflowWithCurrentVersion,
} from '@/workflow/types/Workflow';
-import { isDefined } from 'twenty-shared/utils';
-export const useUpdateWorkflowVersionTrigger = ({
- workflow,
-}: {
- workflow: WorkflowWithCurrentVersion;
-}) => {
+export const useUpdateWorkflowVersionTrigger = () => {
const { updateOneRecord: updateOneWorkflowVersion } =
useUpdateOneRecord({
objectNameSingular: CoreObjectNameSingular.WorkflowVersion,
});
- const { getUpdatableWorkflowVersion } = useGetUpdatableWorkflowVersion();
+ const { getUpdatableWorkflowVersion } =
+ useGetUpdatableWorkflowVersionOrThrow();
const { computeStepOutputSchema } = useComputeStepOutputSchema();
@@ -27,11 +22,7 @@ export const useUpdateWorkflowVersionTrigger = ({
updatedTrigger: WorkflowTrigger,
options: { computeOutputSchema: boolean } = { computeOutputSchema: true },
) => {
- if (!isDefined(workflow.currentVersion)) {
- throw new Error('Cannot find current workflow version');
- }
-
- const workflowVersionId = await getUpdatableWorkflowVersion(workflow);
+ const workflowVersionId = await getUpdatableWorkflowVersion();
if (options.computeOutputSchema) {
const outputSchema = (
@@ -46,10 +37,6 @@ export const useUpdateWorkflowVersionTrigger = ({
};
}
- if (!isDefined(workflowVersionId)) {
- throw new Error('Workflow version not found');
- }
-
await updateOneWorkflowVersion({
idToUpdate: workflowVersionId,
updateOneRecordInput: {
diff --git a/packages/twenty-front/src/modules/workflow/workflow-version/hooks/useTidyUpWorkflowVersion.ts b/packages/twenty-front/src/modules/workflow/workflow-version/hooks/useTidyUpWorkflowVersion.ts
index f4afd83687..8bd2d8570c 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-version/hooks/useTidyUpWorkflowVersion.ts
+++ b/packages/twenty-front/src/modules/workflow/workflow-version/hooks/useTidyUpWorkflowVersion.ts
@@ -1,8 +1,5 @@
-import { useGetUpdatableWorkflowVersion } from '@/workflow/hooks/useGetUpdatableWorkflowVersion';
-import {
- type WorkflowVersion,
- type WorkflowWithCurrentVersion,
-} from '@/workflow/types/Workflow';
+import { useGetUpdatableWorkflowVersionOrThrow } from '@/workflow/hooks/useGetUpdatableWorkflowVersionOrThrow';
+import { type WorkflowVersion } from '@/workflow/types/Workflow';
import { useMutation } from '@apollo/client';
import { isDefined } from 'twenty-shared/utils';
import {
@@ -23,11 +20,7 @@ import { workflowDiagramComponentState } from '@/workflow/workflow-diagram/state
import { getOrganizedDiagram } from '@/workflow/workflow-diagram/utils/getOrganizedDiagram';
import { UPDATE_WORKFLOW_VERSION_POSITIONS } from '@/workflow/workflow-version/graphql/mutations/updateWorkflowVersionPositions';
-export const useTidyUpWorkflowVersion = ({
- workflow,
-}: {
- workflow?: WorkflowWithCurrentVersion;
-}) => {
+export const useTidyUpWorkflowVersion = () => {
const [workflowDiagram, setWorkflowDiagram] = useRecoilComponentState(
workflowDiagramComponentState,
);
@@ -49,20 +42,13 @@ export const useTidyUpWorkflowVersion = ({
UpdateWorkflowVersionPositionsMutationVariables
>(UPDATE_WORKFLOW_VERSION_POSITIONS, { client: apolloCoreClient });
- const { getUpdatableWorkflowVersion } = useGetUpdatableWorkflowVersion();
+ const { getUpdatableWorkflowVersion } =
+ useGetUpdatableWorkflowVersionOrThrow();
const updateWorkflowVersionPosition = async (
positions: { id: string; position: { x: number; y: number } }[],
) => {
- if (!isDefined(workflow)) {
- throw new Error('Cannot find a workflow to update');
- }
-
- const workflowVersionId = await getUpdatableWorkflowVersion(workflow);
-
- if (!isDefined(workflowVersionId)) {
- throw new Error('Cannot find a workflow version to update');
- }
+ const workflowVersionId = await getUpdatableWorkflowVersion();
await mutate({ variables: { input: { workflowVersionId, positions } } });
@@ -115,7 +101,7 @@ export const useTidyUpWorkflowVersion = ({
};
const tidyUpWorkflowVersion = async () => {
- if (!isDefined(workflowDiagram) || !isDefined(workflow?.currentVersion)) {
+ if (!isDefined(workflowDiagram)) {
return;
}