Upsert based on ID field (#16275)

<img width="225" height="187" alt="Capture d’écran 2025-12-03 à 11 49
39"
src="https://github.com/user-attachments/assets/042daa56-71d1-4f6c-811b-c626adde4ceb"
/>


- Split CreateRecordBody in two, there are too many differences with
CreateRecord
- Add ID field to the upsert multiselect
- Provide the Record id field in upsert action so the user can edit

Fixes https://github.com/twentyhq/twenty/issues/15929
This commit is contained in:
Thomas Trompette
2025-12-03 13:54:37 +01:00
committed by GitHub
parent 9b0e8d3232
commit 21a433dd93
8 changed files with 532 additions and 317 deletions
@@ -16,6 +16,7 @@ export const WorkflowFieldsMultiSelect = ({
defaultFields,
placeholder,
hint,
actionType,
}: {
label: string;
placeholder: string;
@@ -23,6 +24,7 @@ export const WorkflowFieldsMultiSelect = ({
handleFieldsChange: (field: FieldMultiSelectValue | string) => void;
readonly: boolean;
defaultFields: string[] | undefined | null;
actionType: 'UPDATE_RECORD' | 'UPSERT_RECORD';
hint?: string;
}) => {
const { getIcon } = useIcons();
@@ -31,7 +33,7 @@ export const WorkflowFieldsMultiSelect = ({
.filter((fieldMetadataItem) =>
shouldDisplayFormField({
fieldMetadataItem,
actionType: 'UPDATE_RECORD',
actionType,
}),
)
.sort((fieldMetadataItemA, fieldMetadataItemB) =>
@@ -55,6 +57,17 @@ export const WorkflowFieldsMultiSelect = ({
label={label}
defaultValue={defaultFields}
options={inlineFieldDefinitions.map((field) => {
const isIdField = field.metadata.fieldName === 'id';
if (isIdField && actionType === 'UPSERT_RECORD') {
return {
label: 'ID',
value: field.metadata.fieldName,
Icon: getIcon('IconId'),
color: 'gray',
};
}
const isFieldRelationManyToOne =
isFieldRelation(field) &&
field.metadata.relationType === RelationType.MANY_TO_ONE;
@@ -92,6 +92,7 @@ export const Default: Story = {
handleFieldsChange: () => {},
readonly: false,
defaultFields: [],
actionType: 'UPDATE_RECORD',
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
@@ -105,6 +106,7 @@ export const WithDefaultValues: Story = {
args: {
...Default.args,
defaultFields: ['name', 'domainName'],
actionType: 'UPDATE_RECORD',
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
@@ -118,6 +120,7 @@ export const ReadOnly: Story = {
...Default.args,
readonly: true,
defaultFields: ['name', 'domainName'],
actionType: 'UPDATE_RECORD',
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);