fix(workflow): show fields for system objects in record-updated trigger (#21826)

## Problem

On the **Record is updated** (and **upserted**) workflow trigger,
picking a record type under the **Advanced** submenu (i.e. a *system*
object) showed an empty "Fields (Optional)" list — you couldn't select
any field to watch.

## Root cause

The trigger's field picker (`WorkflowFieldsMultiSelect`) was called with
`actionType="UPDATE_RECORD"`, which runs each field through
`shouldDisplayFormField`. For `UPDATE_RECORD` that predicate requires
`(isUIEditable ?? true)` — correct for the *Update Record action* (you
can't write to a read-only field), but wrong for a *trigger*, where
you're choosing which fields to **watch for changes** and editability is
irrelevant.

System objects define their fields with `isUIEditable: false`, so every
field failed the gate and the list rendered empty.

## Fix

Add DATABASE_EVENT trigger type to separated from action type.

The `UPDATE_RECORD` / `UPSERT_RECORD` action paths are untouched.
This commit is contained in:
Thomas Trompette
2026-06-19 11:48:14 +02:00
committed by GitHub
parent 8ff494e5e8
commit ceecae30db
4 changed files with 57 additions and 4 deletions
@@ -24,7 +24,7 @@ export const WorkflowFieldsMultiSelect = ({
handleFieldsChange: (field: FieldMultiSelectValue | string) => void;
readonly: boolean;
defaultFields: string[] | undefined | null;
actionType: 'UPDATE_RECORD' | 'UPSERT_RECORD';
actionType: 'UPDATE_RECORD' | 'UPSERT_RECORD' | 'DATABASE_EVENT';
hint?: string;
}) => {
const { getIcon } = useIcons();
@@ -98,6 +98,50 @@ describe('shouldDisplayFormField', () => {
expect(result).toBe(true);
});
it('returns false for UPDATE_RECORD with non UI editable field', () => {
const field = { ...baseField, isUIEditable: false } as FieldMetadataItem;
const result = shouldDisplayFormField({
fieldMetadataItem: field,
actionType: 'UPDATE_RECORD',
});
expect(result).toBe(false);
});
it('returns true for DATABASE_EVENT with non UI editable field', () => {
const field = { ...baseField, isUIEditable: false } as FieldMetadataItem;
const result = shouldDisplayFormField({
fieldMetadataItem: field,
actionType: 'DATABASE_EVENT',
});
expect(result).toBe(true);
});
it('returns false for DATABASE_EVENT with hidden system field', () => {
const field = {
...baseField,
isSystem: true,
name: 'position',
} as FieldMetadataItem;
const result = shouldDisplayFormField({
fieldMetadataItem: field,
actionType: 'DATABASE_EVENT',
});
expect(result).toBe(false);
});
it('returns false for DATABASE_EVENT with RELATION not MANY_TO_ONE', () => {
const field = {
...baseField,
type: FieldMetadataType.RELATION,
settings: { relationType: 'ONE_TO_MANY' },
} as FieldMetadataItem;
const result = shouldDisplayFormField({
fieldMetadataItem: field,
actionType: 'DATABASE_EVENT',
});
expect(result).toBe(false);
});
it('throws error on unsupported action', () => {
expect(() =>
shouldDisplayFormField({
@@ -1,6 +1,9 @@
import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
import { isHiddenSystemField } from '@/object-metadata/utils/isHiddenSystemField';
import { type WorkflowActionType } from '@/workflow/types/Workflow';
import {
type WorkflowActionType,
type WorkflowTriggerType,
} from '@/workflow/types/Workflow';
import { CustomError } from 'twenty-shared/utils';
import { FieldMetadataType } from '~/generated-metadata/graphql';
@@ -31,7 +34,7 @@ export const shouldDisplayFormField = ({
actionType,
}: {
fieldMetadataItem: FieldMetadataItem;
actionType: WorkflowActionType;
actionType: WorkflowActionType | WorkflowTriggerType;
}) => {
if (!SUPPORTED_FORM_FIELD_TYPES.includes(fieldMetadataItem.type)) {
return false;
@@ -67,6 +70,12 @@ export const shouldDisplayFormField = ({
(!isHiddenSystemField(fieldMetadataItem) || isIdField) &&
fieldMetadataItem.isActive
);
case 'DATABASE_EVENT':
return (
!isNotSupportedRelation &&
!isHiddenSystemField(fieldMetadataItem) &&
fieldMetadataItem.isActive
);
default:
throw new CustomError(
`Action "${actionType}" is not supported`,
@@ -266,7 +266,7 @@ export const WorkflowEditTriggerDatabaseEventForm = ({
handleFieldsChange={handleFieldsChange}
readonly={triggerOptions.readonly ?? false}
defaultFields={trigger.settings.fields}
actionType="UPDATE_RECORD"
actionType="DATABASE_EVENT"
/>
)}
</WorkflowStepBody>