diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowEditActionFindRecords.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowEditActionFindRecords.tsx index 3e1a644da1..882307d490 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowEditActionFindRecords.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/find-records-action/components/WorkflowEditActionFindRecords.tsx @@ -66,6 +66,7 @@ type FindRecordsFormData = { filter?: FindRecordsActionFilter; orderBy?: FindRecordsActionOrderBy; limit?: number; + offset?: number; }; export type FindRecordsActionFilter = { @@ -100,11 +101,13 @@ export const WorkflowEditActionFindRecords = ({ action.settings.input.limit > QUERY_MAX_RECORDS ? QUERY_MAX_RECORDS : (action.settings.input.limit ?? 1), + offset: Math.max(0, Math.floor(action.settings.input.offset ?? 0)), filter: action.settings.input.filter as FindRecordsActionFilter, orderBy: action.settings.input.orderBy as FindRecordsActionOrderBy, })); const [limitError, setLimitError] = useState(undefined); + const [offsetError, setOffsetError] = useState(undefined); const isFormDisabled = actionOptions.readonly ?? false; const instanceId = `workflow-edit-action-record-find-records-${action.id}-${formData.objectNameSingular}`; @@ -140,6 +143,7 @@ export const WorkflowEditActionFindRecords = ({ const { objectNameSingular: updatedObjectName, limit: updatedLimit, + offset: updatedOffset, filter: updatedFilter, orderBy: updatedOrderBy, } = formData; @@ -151,6 +155,7 @@ export const WorkflowEditActionFindRecords = ({ input: { objectName: updatedObjectName, limit: updatedLimit ?? 1, + offset: Math.max(0, Math.floor(updatedOffset ?? 0)), filter: updatedFilter, orderBy: updatedOrderBy as Record | undefined, }, @@ -174,6 +179,7 @@ export const WorkflowEditActionFindRecords = ({ const newFormData: FindRecordsFormData = { objectNameSingular: value, limit: 1, + offset: 0, }; setFormData(newFormData); @@ -335,6 +341,38 @@ export const WorkflowEditActionFindRecords = ({ saveAction(newFormData); }} /> + + { + if (isFormDisabled === true || !isNumber(offset)) { + return; + } + + const normalizedOffset = Math.floor(offset); + + if (normalizedOffset < 0) { + setOffsetError(t`Offset cannot be negative.`); + return; + } + + setOffsetError(undefined); + + const newFormData: FindRecordsFormData = { + ...formData, + offset: normalizedOffset, + }; + + setFormData(newFormData); + + saveAction(newFormData); + }} + /> {!actionOptions.readonly && } diff --git a/packages/twenty-server/src/engine/core-modules/record-crud/types/record-crud-input.type.ts b/packages/twenty-server/src/engine/core-modules/record-crud/types/record-crud-input.type.ts index 0705867349..91ba7af519 100644 --- a/packages/twenty-server/src/engine/core-modules/record-crud/types/record-crud-input.type.ts +++ b/packages/twenty-server/src/engine/core-modules/record-crud/types/record-crud-input.type.ts @@ -38,6 +38,7 @@ export type FindRecordsInput = { gqlOperationOrderBy?: Partial; }; limit?: number; + offset?: number; }; export type UpsertRecordInput = { diff --git a/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-version-step/workflow-version-step-operations.workspace-service.ts b/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-version-step/workflow-version-step-operations.workspace-service.ts index a862f5369d..fd1767b4cb 100644 --- a/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-version-step/workflow-version-step-operations.workspace-service.ts +++ b/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-version-step/workflow-version-step-operations.workspace-service.ts @@ -434,6 +434,7 @@ export class WorkflowVersionStepOperationsWorkspaceService { input: { objectName: activeObjectMetadataItem?.nameSingular || '', limit: 1, + offset: 0, }, }, }, diff --git a/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/record-crud/find-records.workflow-action.ts b/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/record-crud/find-records.workflow-action.ts index fcb4d22a2e..04bf853525 100644 --- a/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/record-crud/find-records.workflow-action.ts +++ b/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/record-crud/find-records.workflow-action.ts @@ -95,6 +95,7 @@ export class FindRecordsWorkflowAction implements WorkflowAction { filter: gqlOperationFilter, orderBy: workflowActionInput.orderBy?.gqlOperationOrderBy, limit: workflowActionInput.limit, + offset: workflowActionInput.offset, authContext: executionContext.authContext, rolePermissionConfig: executionContext.rolePermissionConfig, shouldBuildEffectiveSelectFields: false, diff --git a/packages/twenty-shared/src/workflow/schemas/find-records-action-settings-schema.ts b/packages/twenty-shared/src/workflow/schemas/find-records-action-settings-schema.ts index 30d55235bd..0dd390e5bb 100644 --- a/packages/twenty-shared/src/workflow/schemas/find-records-action-settings-schema.ts +++ b/packages/twenty-shared/src/workflow/schemas/find-records-action-settings-schema.ts @@ -6,6 +6,7 @@ export const workflowFindRecordsActionSettingsSchema = input: z.object({ objectName: z.string(), limit: z.number().optional(), + offset: z.number().int().nonnegative().optional(), filter: z .object({ recordFilterGroups: z.array(z.any()).optional(),