Support referencing updatedFields array in databaseEvent triggers (#17240)

Closes https://github.com/twentyhq/core-team-issues/issues/1838

DatabaseEventTriggers can now define a field-level granularity on which
updates they should react to.
After a discussion with the team, we have decided to rely on field names
and not UID, just as we do for objects. The rationale is that we want to
keep a pleasant devX and consider it's not on twenty to ensure
continuity of api usage around an object if their name is updated: for
instance if a user has based their webhook on the name of an object, if
they decide to update it, they have to take care of updating their
webhook.
This commit is contained in:
Marie
2026-01-19 16:33:49 +01:00
committed by GitHub
parent f381516d30
commit 1a38152451
9 changed files with 451 additions and 32 deletions
@@ -1,7 +1,9 @@
import { t } from '@lingui/core/macro';
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
import { Select } from '@/ui/input/components/Select';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import styled from '@emotion/styled';
import { t } from '@lingui/core/macro';
import { isDefined } from 'twenty-shared/utils';
import { IconButton, type SelectOption } from 'twenty-ui/input';
import {
IconBox,
IconNorthStar,
@@ -9,12 +11,10 @@ import {
IconTrash,
useIcons,
} from 'twenty-ui/display';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import styled from '@emotion/styled';
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
import { IconButton, type SelectOption } from 'twenty-ui/input';
const OBJECT_DROPDOWN_WIDTH = 340;
const ACTION_DROPDOWN_WIDTH = 140;
const OBJECT_DROPDOWN_WIDTH = 240;
const ACTION_DROPDOWN_WIDTH = 240;
const OBJECT_MOBILE_WIDTH = 150;
const ACTION_MOBILE_WIDTH = 140;
@@ -40,7 +40,7 @@ export const SettingsDatabaseEventsForm = ({
removeOperation,
disabled = false,
}: {
events: { object: string | null; action: string }[];
events: { object: string | null; action: string; updatedFields?: string[] }[];
updateOperation?: (
index: number,
field: 'object' | 'action',
@@ -64,12 +64,23 @@ export const SettingsDatabaseEventsForm = ({
})),
];
const actionOptions: SelectOption<string>[] = [
{ label: t`All`, value: '*', Icon: IconNorthStar },
{ label: t`Created`, value: 'created', Icon: IconPlus },
{ label: t`Updated`, value: 'updated', Icon: IconBox },
{ label: t`Deleted`, value: 'deleted', Icon: IconTrash },
];
const getActionOptions = (
updatedFields?: string[],
): SelectOption<string>[] => {
const hasSpecificFields =
isDefined(updatedFields) && updatedFields.length > 0;
return [
{ label: t`All`, value: '*', Icon: IconNorthStar },
{ label: t`Created`, value: 'created', Icon: IconPlus },
{
label: hasSpecificFields ? t`Updated (on specific fields)` : t`Updated`,
value: 'updated',
Icon: IconBox,
},
{ label: t`Deleted`, value: 'deleted', Icon: IconTrash },
];
};
return (
<>
@@ -89,7 +100,7 @@ export const SettingsDatabaseEventsForm = ({
<Select
dropdownId={`operation-webhook-type-select-${index}`}
value={operation.action}
options={actionOptions}
options={getActionOptions(operation.updatedFields)}
onChange={(newValue) =>
updateOperation?.(index, 'action', newValue)
}