Refactor: Unify command menu item execution (#18908)

- Makes engineComponentKey non-nullable on CommandMenuItem. Adds two new
engine component keys: TRIGGER_WORKFLOW_VERSION and
FRONT_COMPONENT_RENDERER to cover the former standalone cases.
- Unifies the previously separated engine, front component and workflow
runners into a single `CommandRunner` component with a unified
`useMountCommand` hook that handles all command types.
This commit is contained in:
Raphaël Bosi
2026-03-24 16:59:52 +01:00
committed by GitHub
parent 27c0ca975f
commit 49afe5dbc4
103 changed files with 1296 additions and 1131 deletions
@@ -1,11 +1,6 @@
import { isDefined } from 'twenty-shared/utils';
import { v4 as uuidv4 } from 'uuid';
import { type FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type';
import {
CommandMenuItemException,
CommandMenuItemExceptionCode,
} from 'src/engine/metadata-modules/command-menu-item/command-menu-item.exception';
import { type CreateCommandMenuItemInput } from 'src/engine/metadata-modules/command-menu-item/dtos/create-command-menu-item.input';
import { CommandMenuItemAvailabilityType } from 'src/engine/metadata-modules/command-menu-item/enums/command-menu-item-availability-type.enum';
import { type FlatCommandMenuItem } from 'src/engine/metadata-modules/flat-command-menu-item/types/flat-command-menu-item.type';
@@ -26,29 +21,6 @@ export const fromCreateCommandMenuItemInputToFlatCommandMenuItemToCreate = ({
AllFlatEntityMaps,
'flatObjectMetadataMaps' | 'flatFrontComponentMaps'
>): FlatCommandMenuItem => {
const hasWorkflowVersionId = isDefined(
createCommandMenuItemInput.workflowVersionId,
);
const hasFrontComponentId = isDefined(
createCommandMenuItemInput.frontComponentId,
);
const hasEngineComponentKey = isDefined(
createCommandMenuItemInput.engineComponentKey,
);
const sourceCount = [
hasWorkflowVersionId,
hasFrontComponentId,
hasEngineComponentKey,
].filter(Boolean).length;
if (sourceCount !== 1) {
throw new CommandMenuItemException(
'Exactly one of workflowVersionId, frontComponentId or engineComponentKey is required',
CommandMenuItemExceptionCode.WORKFLOW_OR_FRONT_COMPONENT_REQUIRED,
);
}
const id = uuidv4();
const now = new Date().toISOString();
@@ -71,7 +43,7 @@ export const fromCreateCommandMenuItemInputToFlatCommandMenuItemToCreate = ({
workflowVersionId: createCommandMenuItemInput.workflowVersionId ?? null,
frontComponentId: createCommandMenuItemInput.frontComponentId ?? null,
frontComponentUniversalIdentifier,
engineComponentKey: createCommandMenuItemInput.engineComponentKey ?? null,
engineComponentKey: createCommandMenuItemInput.engineComponentKey,
label: createCommandMenuItemInput.label,
icon: createCommandMenuItemInput.icon ?? null,
shortLabel: createCommandMenuItemInput.shortLabel ?? null,
@@ -7,7 +7,7 @@ export const fromFlatCommandMenuItemToCommandMenuItemDto = (
id: flatCommandMenuItem.id,
workflowVersionId: flatCommandMenuItem.workflowVersionId ?? undefined,
frontComponentId: flatCommandMenuItem.frontComponentId ?? undefined,
engineComponentKey: flatCommandMenuItem.engineComponentKey ?? undefined,
engineComponentKey: flatCommandMenuItem.engineComponentKey,
label: flatCommandMenuItem.label,
icon: flatCommandMenuItem.icon ?? undefined,
shortLabel: flatCommandMenuItem.shortLabel ?? undefined,