Run workflow version on multiple records (#12969)

Fixes https://github.com/twentyhq/core-team-issues/issues/776

Until we have loops implemented, we still allow the user to select
multiple records for manual trigger. A workflow run will be triggered
for each record selected.

The display of multiple runs in the side panel is not ideal. After
discussion with @Bonapara, we will load all runs into the side panel
until we have the inbox. Once we have the inbox, we will use the side
panel when only one run is triggered.


https://github.com/user-attachments/assets/b563b4f1-0705-45aa-b296-c1b41abf4815
This commit is contained in:
Thomas Trompette
2025-06-30 16:44:41 +02:00
committed by GitHub
parent 3e7f2074e5
commit 7756b472a4
2 changed files with 38 additions and 17 deletions

View File

@ -9,10 +9,11 @@ import { useActiveWorkflowVersionsWithManualTrigger } from '@/workflow/hooks/use
import { useRunWorkflowVersion } from '@/workflow/hooks/useRunWorkflowVersion';
import { msg } from '@lingui/core/macro';
import { useRecoilValue } from 'recoil';
import { WorkflowVersion } from '@/workflow/types/Workflow';
import { COMMAND_MENU_DEFAULT_ICON } from '@/workflow/workflow-trigger/constants/CommandMenuDefaultIcon';
import { useRecoilCallback } from 'recoil';
import { capitalize, isDefined } from 'twenty-shared/utils';
import { useIcons } from 'twenty-ui/display';
import { COMMAND_MENU_DEFAULT_ICON } from '@/workflow/workflow-trigger/constants/CommandMenuDefaultIcon';
export const useRunWorkflowRecordActions = ({
objectMetadataItem,
@ -26,15 +27,11 @@ export const useRunWorkflowRecordActions = ({
contextStoreTargetedRecordsRuleComponentState,
);
const selectedRecordId =
const selectedRecordIds =
contextStoreTargetedRecordsRule.mode === 'selection'
? contextStoreTargetedRecordsRule.selectedRecordIds[0]
? contextStoreTargetedRecordsRule.selectedRecordIds
: undefined;
const selectedRecord = useRecoilValue(
recordStoreFamilyState(selectedRecordId ?? ''),
);
const { records: activeWorkflowVersions } =
useActiveWorkflowVersionsWithManualTrigger({
objectMetadataItem,
@ -43,6 +40,31 @@ export const useRunWorkflowRecordActions = ({
const { runWorkflowVersion } = useRunWorkflowVersion();
const runWorkflowVersionOnSelectedRecords = useRecoilCallback(
({ snapshot }) =>
async (
selectedRecordIds: string[],
activeWorkflowVersion: WorkflowVersion,
) => {
for (const selectedRecordId of selectedRecordIds) {
const selectedRecord = snapshot
.getLoadable(recordStoreFamilyState(selectedRecordId))
.getValue();
if (!isDefined(selectedRecord)) {
continue;
}
await runWorkflowVersion({
workflowId: activeWorkflowVersion.workflowId,
workflowVersionId: activeWorkflowVersion.id,
payload: selectedRecord,
});
}
},
[runWorkflowVersion],
);
return activeWorkflowVersions
.filter((activeWorkflowVersion) =>
isDefined(activeWorkflowVersion.workflow),
@ -66,15 +88,14 @@ export const useRunWorkflowRecordActions = ({
component: (
<Action
onClick={async () => {
if (!isDefined(selectedRecord)) {
if (!isDefined(selectedRecordIds)) {
return;
}
await runWorkflowVersion({
workflowId: activeWorkflowVersion.workflowId,
workflowVersionId: activeWorkflowVersion.id,
payload: selectedRecord,
});
await runWorkflowVersionOnSelectedRecords(
selectedRecordIds,
activeWorkflowVersion,
);
}}
closeSidePanelOnCommandMenuListActionExecution={false}
/>

View File

@ -43,13 +43,13 @@ export const ActionMenuContextProviderWorkflowsEnabled = ({
contextStoreTargetedRecordsRuleComponentState,
);
const isSingleRecordSelection =
const isRecordSelection =
contextStoreTargetedRecordsRule.mode === 'selection' &&
contextStoreTargetedRecordsRule.selectedRecordIds.length === 1;
contextStoreTargetedRecordsRule.selectedRecordIds.length > 0;
const runWorkflowRecordActions = useRunWorkflowRecordActions({
objectMetadataItem,
skip: !isSingleRecordSelection,
skip: !isRecordSelection,
});
const runWorkflowRecordAgnosticActions =