diff --git a/packages/twenty-front/src/modules/workflow/components/WorkflowStepDetail.tsx b/packages/twenty-front/src/modules/workflow/components/WorkflowStepDetail.tsx
index fc1cd2289..1319673bf 100644
--- a/packages/twenty-front/src/modules/workflow/components/WorkflowStepDetail.tsx
+++ b/packages/twenty-front/src/modules/workflow/components/WorkflowStepDetail.tsx
@@ -1,4 +1,3 @@
-import { lazy, Suspense } from 'react';
import { WorkflowEditTriggerDatabaseEventForm } from '@/workflow/components/WorkflowEditTriggerDatabaseEventForm';
import { WorkflowEditTriggerManualForm } from '@/workflow/components/WorkflowEditTriggerManualForm';
import {
@@ -8,11 +7,14 @@ import {
} from '@/workflow/types/Workflow';
import { assertUnreachable } from '@/workflow/utils/assertUnreachable';
import { getStepDefinitionOrThrow } from '@/workflow/utils/getStepDefinitionOrThrow';
-import { isWorkflowRecordCreateAction } from '@/workflow/utils/isWorkflowRecordCreateAction';
-import { isWorkflowRecordUpdateAction } from '@/workflow/utils/isWorkflowRecordUpdateAction';
import { WorkflowEditActionFormRecordCreate } from '@/workflow/workflow-actions/components/WorkflowEditActionFormRecordCreate';
+import { WorkflowEditActionFormRecordDelete } from '@/workflow/workflow-actions/components/WorkflowEditActionFormRecordDelete';
import { WorkflowEditActionFormRecordUpdate } from '@/workflow/workflow-actions/components/WorkflowEditActionFormRecordUpdate';
import { WorkflowEditActionFormSendEmail } from '@/workflow/workflow-actions/components/WorkflowEditActionFormSendEmail';
+import { isWorkflowRecordCreateAction } from '@/workflow/workflow-actions/utils/isWorkflowRecordCreateAction';
+import { isWorkflowRecordDeleteAction } from '@/workflow/workflow-actions/utils/isWorkflowRecordDeleteAction';
+import { isWorkflowRecordUpdateAction } from '@/workflow/workflow-actions/utils/isWorkflowRecordUpdateAction';
+import { lazy, Suspense } from 'react';
import { isDefined } from 'twenty-ui';
import { RightDrawerSkeletonLoader } from '~/loading/components/RightDrawerSkeletonLoader';
@@ -124,6 +126,15 @@ export const WorkflowStepDetail = ({
);
}
+ if (isWorkflowRecordDeleteAction(stepDefinition.definition)) {
+ return (
+
+ );
+ }
+
return null;
}
}
diff --git a/packages/twenty-front/src/modules/workflow/constants/Actions.ts b/packages/twenty-front/src/modules/workflow/constants/Actions.ts
index e71d71ea2..4f5b2c2ba 100644
--- a/packages/twenty-front/src/modules/workflow/constants/Actions.ts
+++ b/packages/twenty-front/src/modules/workflow/constants/Actions.ts
@@ -30,4 +30,9 @@ export const ACTIONS: Array<{
type: 'RECORD_CRUD.UPDATE',
icon: IconAddressBook,
},
+ {
+ label: 'Delete Record',
+ type: 'RECORD_CRUD.DELETE',
+ icon: IconAddressBook,
+ },
];
diff --git a/packages/twenty-front/src/modules/workflow/utils/__tests__/isWorkflowRecordCreateAction.test.ts b/packages/twenty-front/src/modules/workflow/utils/__tests__/isWorkflowRecordCreateAction.test.ts
deleted file mode 100644
index 8a4e3721f..000000000
--- a/packages/twenty-front/src/modules/workflow/utils/__tests__/isWorkflowRecordCreateAction.test.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-import {
- WorkflowCodeAction,
- WorkflowRecordCRUDAction,
-} from '@/workflow/types/Workflow';
-import { isWorkflowRecordCreateAction } from '../isWorkflowRecordCreateAction';
-
-it('returns false when providing an action that is not Record Create', () => {
- const codeAction: WorkflowCodeAction = {
- type: 'CODE',
- id: '',
- name: '',
- settings: {
- errorHandlingOptions: {
- continueOnFailure: {
- value: false,
- },
- retryOnFailure: {
- value: false,
- },
- },
- input: {
- serverlessFunctionId: '',
- serverlessFunctionVersion: '',
- serverlessFunctionInput: {},
- },
- outputSchema: {},
- },
- valid: true,
- };
-
- expect(isWorkflowRecordCreateAction(codeAction)).toBe(false);
-});
-
-it('returns false for Record Update', () => {
- const codeAction: WorkflowRecordCRUDAction = {
- type: 'RECORD_CRUD',
- id: '',
- name: '',
- settings: {
- errorHandlingOptions: {
- continueOnFailure: { value: false },
- retryOnFailure: { value: false },
- },
- input: {
- type: 'UPDATE',
- objectName: '',
- objectRecord: {},
- objectRecordId: '',
- },
- outputSchema: {},
- },
- valid: true,
- };
-
- expect(isWorkflowRecordCreateAction(codeAction)).toBe(false);
-});
-
-it('returns true for Record Create', () => {
- const codeAction: WorkflowRecordCRUDAction = {
- type: 'RECORD_CRUD',
- id: '',
- name: '',
- settings: {
- errorHandlingOptions: {
- continueOnFailure: { value: false },
- retryOnFailure: { value: false },
- },
- input: {
- type: 'CREATE',
- objectName: '',
- objectRecord: {},
- },
- outputSchema: {},
- },
- valid: true,
- };
-
- expect(isWorkflowRecordCreateAction(codeAction)).toBe(true);
-});
diff --git a/packages/twenty-front/src/modules/workflow/workflow-actions/components/WorkflowEditActionFormRecordDelete.tsx b/packages/twenty-front/src/modules/workflow/workflow-actions/components/WorkflowEditActionFormRecordDelete.tsx
new file mode 100644
index 000000000..3ca50035f
--- /dev/null
+++ b/packages/twenty-front/src/modules/workflow/workflow-actions/components/WorkflowEditActionFormRecordDelete.tsx
@@ -0,0 +1,170 @@
+import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems';
+import { Select, SelectOption } from '@/ui/input/components/Select';
+import { WorkflowEditGenericFormBase } from '@/workflow/components/WorkflowEditGenericFormBase';
+import { WorkflowSingleRecordPicker } from '@/workflow/components/WorkflowSingleRecordPicker';
+import { WorkflowRecordDeleteAction } from '@/workflow/types/Workflow';
+import { useTheme } from '@emotion/react';
+import { useEffect, useState } from 'react';
+import {
+ HorizontalSeparator,
+ IconAddressBook,
+ isDefined,
+ useIcons,
+} from 'twenty-ui';
+
+import { JsonValue } from 'type-fest';
+import { useDebouncedCallback } from 'use-debounce';
+
+type WorkflowEditActionFormRecordDeleteProps = {
+ action: WorkflowRecordDeleteAction;
+ actionOptions:
+ | {
+ readonly: true;
+ }
+ | {
+ readonly?: false;
+ onActionUpdate: (action: WorkflowRecordDeleteAction) => void;
+ };
+};
+
+type DeleteRecordFormData = {
+ objectName: string;
+ objectRecordId: string;
+};
+
+export const WorkflowEditActionFormRecordDelete = ({
+ action,
+ actionOptions,
+}: WorkflowEditActionFormRecordDeleteProps) => {
+ const theme = useTheme();
+ const { getIcon } = useIcons();
+
+ const { activeObjectMetadataItems } = useFilteredObjectMetadataItems();
+
+ const availableMetadata: Array> =
+ activeObjectMetadataItems.map((item) => ({
+ Icon: getIcon(item.icon),
+ label: item.labelPlural,
+ value: item.nameSingular,
+ }));
+
+ const [formData, setFormData] = useState({
+ objectName: action.settings.input.objectName,
+ objectRecordId: action.settings.input.objectRecordId,
+ });
+ const isFormDisabled = actionOptions.readonly;
+
+ const handleFieldChange = (
+ fieldName: keyof DeleteRecordFormData,
+ updatedValue: JsonValue,
+ ) => {
+ const newFormData: DeleteRecordFormData = {
+ ...formData,
+ [fieldName]: updatedValue,
+ };
+
+ setFormData(newFormData);
+
+ saveAction(newFormData);
+ };
+
+ useEffect(() => {
+ setFormData({
+ objectName: action.settings.input.objectName,
+ objectRecordId: action.settings.input.objectRecordId,
+ });
+ }, [action.settings.input]);
+
+ const selectedObjectMetadataItemNameSingular = formData.objectName;
+
+ const selectedObjectMetadataItem = activeObjectMetadataItems.find(
+ (item) => item.nameSingular === selectedObjectMetadataItemNameSingular,
+ );
+ if (!isDefined(selectedObjectMetadataItem)) {
+ throw new Error('Should have found the metadata item');
+ }
+
+ const saveAction = useDebouncedCallback(
+ async (formData: DeleteRecordFormData) => {
+ if (actionOptions.readonly === true) {
+ return;
+ }
+
+ const {
+ objectName: updatedObjectName,
+ objectRecordId: updatedObjectRecordId,
+ } = formData;
+
+ actionOptions.onActionUpdate({
+ ...action,
+ settings: {
+ ...action.settings,
+ input: {
+ type: 'DELETE',
+ objectName: updatedObjectName,
+ objectRecordId: updatedObjectRecordId ?? '',
+ },
+ },
+ });
+ },
+ 1_000,
+ );
+
+ useEffect(() => {
+ return () => {
+ saveAction.flush();
+ };
+ }, [saveAction]);
+
+ const headerTitle = isDefined(action.name) ? action.name : `Delete Record`;
+
+ return (
+ {
+ if (actionOptions.readonly === true) {
+ return;
+ }
+
+ actionOptions.onActionUpdate({
+ ...action,
+ name: newName,
+ });
+ }}
+ Icon={IconAddressBook}
+ iconColor={theme.font.color.tertiary}
+ initialTitle={headerTitle}
+ headerType="Action"
+ >
+
+ );
+};
diff --git a/packages/twenty-front/src/modules/workflow/workflow-actions/components/WorkflowEditActionFormServerlessFunction.tsx b/packages/twenty-front/src/modules/workflow/workflow-actions/components/WorkflowEditActionFormServerlessFunction.tsx
index 265ae6980..a5685313e 100644
--- a/packages/twenty-front/src/modules/workflow/workflow-actions/components/WorkflowEditActionFormServerlessFunction.tsx
+++ b/packages/twenty-front/src/modules/workflow/workflow-actions/components/WorkflowEditActionFormServerlessFunction.tsx
@@ -1,11 +1,27 @@
+import { FormTextFieldInput } from '@/object-record/record-field/form-types/components/FormTextFieldInput';
+import { useGetAvailablePackages } from '@/settings/serverless-functions/hooks/useGetAvailablePackages';
+import { useServerlessFunctionUpdateFormState } from '@/settings/serverless-functions/hooks/useServerlessFunctionUpdateFormState';
+import { useUpdateOneServerlessFunction } from '@/settings/serverless-functions/hooks/useUpdateOneServerlessFunction';
+import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
+import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
import { WorkflowEditGenericFormBase } from '@/workflow/components/WorkflowEditGenericFormBase';
+import { WorkflowVariablePicker } from '@/workflow/components/WorkflowVariablePicker';
+import { useGetUpdatableWorkflowVersion } from '@/workflow/hooks/useGetUpdatableWorkflowVersion';
+import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion';
+import { workflowIdState } from '@/workflow/states/workflowIdState';
import { FunctionInput } from '@/workflow/types/FunctionInput';
import { WorkflowCodeAction } from '@/workflow/types/Workflow';
-import { mergeDefaultFunctionInputAndFunctionInput } from '@/workflow/utils/mergeDefaultFunctionInputAndFunctionInput';
+import { getDefaultFunctionInputFromInputSchema } from '@/workflow/utils/getDefaultFunctionInputFromInputSchema';
+import { getFunctionInputSchema } from '@/workflow/utils/getFunctionInputSchema';
import { setNestedValue } from '@/workflow/utils/setNestedValue';
+import { mergeDefaultFunctionInputAndFunctionInput } from '@/workflow/workflow-actions/utils/mergeDefaultFunctionInputAndFunctionInput';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
+import { Monaco } from '@monaco-editor/react';
+import { editor } from 'monaco-editor';
+import { AutoTypings } from 'monaco-editor-auto-typings';
import { Fragment, ReactNode, useEffect, useState } from 'react';
+import { useRecoilValue } from 'recoil';
import {
CodeEditor,
HorizontalSeparator,
@@ -13,23 +29,7 @@ import {
isDefined,
} from 'twenty-ui';
import { useDebouncedCallback } from 'use-debounce';
-import { useServerlessFunctionUpdateFormState } from '@/settings/serverless-functions/hooks/useServerlessFunctionUpdateFormState';
-import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
import { usePreventOverlapCallback } from '~/hooks/usePreventOverlapCallback';
-import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
-import { useUpdateOneServerlessFunction } from '@/settings/serverless-functions/hooks/useUpdateOneServerlessFunction';
-import { useGetAvailablePackages } from '@/settings/serverless-functions/hooks/useGetAvailablePackages';
-import { AutoTypings } from 'monaco-editor-auto-typings';
-import { editor } from 'monaco-editor';
-import { Monaco } from '@monaco-editor/react';
-import { WorkflowVariablePicker } from '@/workflow/components/WorkflowVariablePicker';
-import { FormTextFieldInput } from '@/object-record/record-field/form-types/components/FormTextFieldInput';
-import { getFunctionInputSchema } from '@/workflow/utils/getFunctionInputSchema';
-import { getDefaultFunctionInputFromInputSchema } from '@/workflow/utils/getDefaultFunctionInputFromInputSchema';
-import { workflowIdState } from '@/workflow/states/workflowIdState';
-import { useRecoilValue } from 'recoil';
-import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion';
-import { useGetUpdatableWorkflowVersion } from '@/workflow/hooks/useGetUpdatableWorkflowVersion';
const StyledContainer = styled.div`
display: inline-flex;
diff --git a/packages/twenty-front/src/modules/workflow/workflow-actions/utils/__tests__/isWorkflowRecordCreateAction.test.ts b/packages/twenty-front/src/modules/workflow/workflow-actions/utils/__tests__/isWorkflowRecordCreateAction.test.ts
new file mode 100644
index 000000000..980f7755f
--- /dev/null
+++ b/packages/twenty-front/src/modules/workflow/workflow-actions/utils/__tests__/isWorkflowRecordCreateAction.test.ts
@@ -0,0 +1,81 @@
+import {
+ WorkflowCodeAction,
+ WorkflowRecordCRUDAction,
+} from '@/workflow/types/Workflow';
+import { isWorkflowRecordCreateAction } from '../isWorkflowRecordCreateAction';
+
+describe('isWorkflowRecordCreateAction', () => {
+ it('returns false when providing an action that is not Record Create', () => {
+ const action: WorkflowCodeAction = {
+ type: 'CODE',
+ id: '',
+ name: '',
+ settings: {
+ errorHandlingOptions: {
+ continueOnFailure: {
+ value: false,
+ },
+ retryOnFailure: {
+ value: false,
+ },
+ },
+ input: {
+ serverlessFunctionId: '',
+ serverlessFunctionVersion: '',
+ serverlessFunctionInput: {},
+ },
+ outputSchema: {},
+ },
+ valid: true,
+ };
+
+ expect(isWorkflowRecordCreateAction(action)).toBe(false);
+ });
+
+ it('returns false for Record Update', () => {
+ const action: WorkflowRecordCRUDAction = {
+ type: 'RECORD_CRUD',
+ id: '',
+ name: '',
+ settings: {
+ errorHandlingOptions: {
+ continueOnFailure: { value: false },
+ retryOnFailure: { value: false },
+ },
+ input: {
+ type: 'UPDATE',
+ objectName: '',
+ objectRecord: {},
+ objectRecordId: '',
+ },
+ outputSchema: {},
+ },
+ valid: true,
+ };
+
+ expect(isWorkflowRecordCreateAction(action)).toBe(false);
+ });
+
+ it('returns true for Record Create', () => {
+ const action: WorkflowRecordCRUDAction = {
+ type: 'RECORD_CRUD',
+ id: '',
+ name: '',
+ settings: {
+ errorHandlingOptions: {
+ continueOnFailure: { value: false },
+ retryOnFailure: { value: false },
+ },
+ input: {
+ type: 'CREATE',
+ objectName: '',
+ objectRecord: {},
+ },
+ outputSchema: {},
+ },
+ valid: true,
+ };
+
+ expect(isWorkflowRecordCreateAction(action)).toBe(true);
+ });
+});
diff --git a/packages/twenty-front/src/modules/workflow/workflow-actions/utils/__tests__/isWorkflowRecordDeleteAction.test.ts b/packages/twenty-front/src/modules/workflow/workflow-actions/utils/__tests__/isWorkflowRecordDeleteAction.test.ts
new file mode 100644
index 000000000..0dc70f3a2
--- /dev/null
+++ b/packages/twenty-front/src/modules/workflow/workflow-actions/utils/__tests__/isWorkflowRecordDeleteAction.test.ts
@@ -0,0 +1,81 @@
+import {
+ WorkflowCodeAction,
+ WorkflowRecordCRUDAction,
+} from '@/workflow/types/Workflow';
+import { isWorkflowRecordDeleteAction } from '../isWorkflowRecordDeleteAction';
+
+describe('isWorkflowRecordDeleteAction', () => {
+ it('returns false when providing an action that is not Record Delete', () => {
+ const action: WorkflowCodeAction = {
+ type: 'CODE',
+ id: '',
+ name: '',
+ settings: {
+ errorHandlingOptions: {
+ continueOnFailure: {
+ value: false,
+ },
+ retryOnFailure: {
+ value: false,
+ },
+ },
+ input: {
+ serverlessFunctionId: '',
+ serverlessFunctionVersion: '',
+ serverlessFunctionInput: {},
+ },
+ outputSchema: {},
+ },
+ valid: true,
+ };
+
+ expect(isWorkflowRecordDeleteAction(action)).toBe(false);
+ });
+
+ it('returns false for Record Update', () => {
+ const action: WorkflowRecordCRUDAction = {
+ type: 'RECORD_CRUD',
+ id: '',
+ name: '',
+ settings: {
+ errorHandlingOptions: {
+ continueOnFailure: { value: false },
+ retryOnFailure: { value: false },
+ },
+ input: {
+ type: 'UPDATE',
+ objectName: '',
+ objectRecord: {},
+ objectRecordId: '',
+ },
+ outputSchema: {},
+ },
+ valid: true,
+ };
+
+ expect(isWorkflowRecordDeleteAction(action)).toBe(false);
+ });
+
+ it('returns true for Record Delete', () => {
+ const action: WorkflowRecordCRUDAction = {
+ type: 'RECORD_CRUD',
+ id: '',
+ name: '',
+ settings: {
+ errorHandlingOptions: {
+ continueOnFailure: { value: false },
+ retryOnFailure: { value: false },
+ },
+ input: {
+ type: 'DELETE',
+ objectName: '',
+ objectRecordId: '',
+ },
+ outputSchema: {},
+ },
+ valid: true,
+ };
+
+ expect(isWorkflowRecordDeleteAction(action)).toBe(true);
+ });
+});
diff --git a/packages/twenty-front/src/modules/workflow/workflow-actions/utils/__tests__/isWorkflowRecordUpdateAction.test.ts b/packages/twenty-front/src/modules/workflow/workflow-actions/utils/__tests__/isWorkflowRecordUpdateAction.test.ts
new file mode 100644
index 000000000..363c7c148
--- /dev/null
+++ b/packages/twenty-front/src/modules/workflow/workflow-actions/utils/__tests__/isWorkflowRecordUpdateAction.test.ts
@@ -0,0 +1,81 @@
+import {
+ WorkflowCodeAction,
+ WorkflowRecordCRUDAction,
+} from '@/workflow/types/Workflow';
+import { isWorkflowRecordUpdateAction } from '../isWorkflowRecordUpdateAction';
+
+describe('isWorkflowRecordUpdateAction', () => {
+ it('returns false when providing an action that is not Record Create', () => {
+ const action: WorkflowCodeAction = {
+ type: 'CODE',
+ id: '',
+ name: '',
+ settings: {
+ errorHandlingOptions: {
+ continueOnFailure: {
+ value: false,
+ },
+ retryOnFailure: {
+ value: false,
+ },
+ },
+ input: {
+ serverlessFunctionId: '',
+ serverlessFunctionVersion: '',
+ serverlessFunctionInput: {},
+ },
+ outputSchema: {},
+ },
+ valid: true,
+ };
+
+ expect(isWorkflowRecordUpdateAction(action)).toBe(false);
+ });
+
+ it('returns true for Record Update', () => {
+ const action: WorkflowRecordCRUDAction = {
+ type: 'RECORD_CRUD',
+ id: '',
+ name: '',
+ settings: {
+ errorHandlingOptions: {
+ continueOnFailure: { value: false },
+ retryOnFailure: { value: false },
+ },
+ input: {
+ type: 'UPDATE',
+ objectName: '',
+ objectRecord: {},
+ objectRecordId: '',
+ },
+ outputSchema: {},
+ },
+ valid: true,
+ };
+
+ expect(isWorkflowRecordUpdateAction(action)).toBe(true);
+ });
+
+ it('returns false for Record Create', () => {
+ const action: WorkflowRecordCRUDAction = {
+ type: 'RECORD_CRUD',
+ id: '',
+ name: '',
+ settings: {
+ errorHandlingOptions: {
+ continueOnFailure: { value: false },
+ retryOnFailure: { value: false },
+ },
+ input: {
+ type: 'CREATE',
+ objectName: '',
+ objectRecord: {},
+ },
+ outputSchema: {},
+ },
+ valid: true,
+ };
+
+ expect(isWorkflowRecordUpdateAction(action)).toBe(false);
+ });
+});
diff --git a/packages/twenty-front/src/modules/workflow/utils/__tests__/mergeDefaultFunctionInputAndFunctionInput.test.ts b/packages/twenty-front/src/modules/workflow/workflow-actions/utils/__tests__/mergeDefaultFunctionInputAndFunctionInput.test.ts
similarity index 81%
rename from packages/twenty-front/src/modules/workflow/utils/__tests__/mergeDefaultFunctionInputAndFunctionInput.test.ts
rename to packages/twenty-front/src/modules/workflow/workflow-actions/utils/__tests__/mergeDefaultFunctionInputAndFunctionInput.test.ts
index 9513a4fe5..3c74a8ed9 100644
--- a/packages/twenty-front/src/modules/workflow/utils/__tests__/mergeDefaultFunctionInputAndFunctionInput.test.ts
+++ b/packages/twenty-front/src/modules/workflow/workflow-actions/utils/__tests__/mergeDefaultFunctionInputAndFunctionInput.test.ts
@@ -1,4 +1,4 @@
-import { mergeDefaultFunctionInputAndFunctionInput } from '@/workflow/utils/mergeDefaultFunctionInputAndFunctionInput';
+import { mergeDefaultFunctionInputAndFunctionInput } from '../mergeDefaultFunctionInputAndFunctionInput';
describe('mergeDefaultFunctionInputAndFunctionInput', () => {
it('should merge properly', () => {
diff --git a/packages/twenty-front/src/modules/workflow/utils/isWorkflowRecordCreateAction.ts b/packages/twenty-front/src/modules/workflow/workflow-actions/utils/isWorkflowRecordCreateAction.ts
similarity index 100%
rename from packages/twenty-front/src/modules/workflow/utils/isWorkflowRecordCreateAction.ts
rename to packages/twenty-front/src/modules/workflow/workflow-actions/utils/isWorkflowRecordCreateAction.ts
diff --git a/packages/twenty-front/src/modules/workflow/workflow-actions/utils/isWorkflowRecordDeleteAction.ts b/packages/twenty-front/src/modules/workflow/workflow-actions/utils/isWorkflowRecordDeleteAction.ts
new file mode 100644
index 000000000..4112965eb
--- /dev/null
+++ b/packages/twenty-front/src/modules/workflow/workflow-actions/utils/isWorkflowRecordDeleteAction.ts
@@ -0,0 +1,12 @@
+import {
+ WorkflowAction,
+ WorkflowRecordDeleteAction,
+} from '@/workflow/types/Workflow';
+
+export const isWorkflowRecordDeleteAction = (
+ action: WorkflowAction,
+): action is WorkflowRecordDeleteAction => {
+ return (
+ action.type === 'RECORD_CRUD' && action.settings.input.type === 'DELETE'
+ );
+};
diff --git a/packages/twenty-front/src/modules/workflow/utils/isWorkflowRecordUpdateAction.ts b/packages/twenty-front/src/modules/workflow/workflow-actions/utils/isWorkflowRecordUpdateAction.ts
similarity index 100%
rename from packages/twenty-front/src/modules/workflow/utils/isWorkflowRecordUpdateAction.ts
rename to packages/twenty-front/src/modules/workflow/workflow-actions/utils/isWorkflowRecordUpdateAction.ts
diff --git a/packages/twenty-front/src/modules/workflow/utils/mergeDefaultFunctionInputAndFunctionInput.ts b/packages/twenty-front/src/modules/workflow/workflow-actions/utils/mergeDefaultFunctionInputAndFunctionInput.ts
similarity index 100%
rename from packages/twenty-front/src/modules/workflow/utils/mergeDefaultFunctionInputAndFunctionInput.ts
rename to packages/twenty-front/src/modules/workflow/workflow-actions/utils/mergeDefaultFunctionInputAndFunctionInput.ts
diff --git a/packages/twenty-server/src/modules/workflow/common/workspace-services/workflow-version-step.workspace-service.ts b/packages/twenty-server/src/modules/workflow/common/workspace-services/workflow-version-step.workspace-service.ts
index 6d3d21d82..d117580d0 100644
--- a/packages/twenty-server/src/modules/workflow/common/workspace-services/workflow-version-step.workspace-service.ts
+++ b/packages/twenty-server/src/modules/workflow/common/workspace-services/workflow-version-step.workspace-service.ts
@@ -169,6 +169,27 @@ export class WorkflowVersionStepWorkspaceService {
},
};
}
+ case `${WorkflowActionType.RECORD_CRUD}.${WorkflowRecordCRUDType.DELETE}`: {
+ const activeObjectMetadataItem =
+ await this.objectMetadataRepository.findOne({
+ where: { workspaceId, isActive: true, isSystem: false },
+ });
+
+ return {
+ id: newStepId,
+ name: 'Delete Record',
+ type: WorkflowActionType.RECORD_CRUD,
+ valid: false,
+ settings: {
+ ...BASE_STEP_DEFINITION,
+ input: {
+ type: WorkflowRecordCRUDType.DELETE,
+ objectName: activeObjectMetadataItem?.nameSingular || '',
+ objectRecordId: '',
+ },
+ },
+ };
+ }
default:
throw new WorkflowVersionStepException(
`WorkflowActionType '${type}' unknown`,