Remove ID field + fix relations + remove runs (#12796)

- id field should only be available for search records action
- create record action does not work for relations. Requires to send
`accountOwner: { id: string }` instead of `accountOwner: string`
- hidding `runs` for version views as we did for workflows
This commit is contained in:
Thomas Trompette
2025-06-23 18:03:11 +02:00
committed by GitHub
parent d99bff983e
commit 06fddc2ae0
4 changed files with 63 additions and 21 deletions

View File

@ -2,7 +2,9 @@ import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilte
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems'; import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
import { formatFieldMetadataItemAsFieldDefinition } from '@/object-metadata/utils/formatFieldMetadataItemAsFieldDefinition'; import { formatFieldMetadataItemAsFieldDefinition } from '@/object-metadata/utils/formatFieldMetadataItemAsFieldDefinition';
import { FormFieldInput } from '@/object-record/record-field/components/FormFieldInput'; import { FormFieldInput } from '@/object-record/record-field/components/FormFieldInput';
import { isFieldRelation } from '@/object-record/record-field/types/guards/isFieldRelation';
import { Select } from '@/ui/input/components/Select'; import { Select } from '@/ui/input/components/Select';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import { useViewOrDefaultViewFromPrefetchedViews } from '@/views/hooks/useViewOrDefaultViewFromPrefetchedViews'; import { useViewOrDefaultViewFromPrefetchedViews } from '@/views/hooks/useViewOrDefaultViewFromPrefetchedViews';
import { WorkflowCreateRecordAction } from '@/workflow/types/Workflow'; import { WorkflowCreateRecordAction } from '@/workflow/types/Workflow';
import { WorkflowStepBody } from '@/workflow/workflow-steps/components/WorkflowStepBody'; import { WorkflowStepBody } from '@/workflow/workflow-steps/components/WorkflowStepBody';
@ -10,14 +12,14 @@ import { WorkflowStepHeader } from '@/workflow/workflow-steps/components/Workflo
import { useWorkflowActionHeader } from '@/workflow/workflow-steps/workflow-actions/hooks/useWorkflowActionHeader'; import { useWorkflowActionHeader } from '@/workflow/workflow-steps/workflow-actions/hooks/useWorkflowActionHeader';
import { shouldDisplayFormField } from '@/workflow/workflow-steps/workflow-actions/utils/shouldDisplayFormField'; import { shouldDisplayFormField } from '@/workflow/workflow-steps/workflow-actions/utils/shouldDisplayFormField';
import { WorkflowVariablePicker } from '@/workflow/workflow-variables/components/WorkflowVariablePicker'; import { WorkflowVariablePicker } from '@/workflow/workflow-variables/components/WorkflowVariablePicker';
import { useTheme } from '@emotion/react';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { isDefined } from 'twenty-shared/utils'; import { isDefined } from 'twenty-shared/utils';
import { HorizontalSeparator, useIcons } from 'twenty-ui/display'; import { HorizontalSeparator, useIcons } from 'twenty-ui/display';
import { SelectOption } from 'twenty-ui/input'; import { SelectOption } from 'twenty-ui/input';
import { JsonValue } from 'type-fest'; import { JsonValue } from 'type-fest';
import { useDebouncedCallback } from 'use-debounce'; import { useDebouncedCallback } from 'use-debounce';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth'; import { RelationType } from '~/generated-metadata/graphql';
import { useTheme } from '@emotion/react';
type WorkflowEditActionCreateRecordProps = { type WorkflowEditActionCreateRecordProps = {
action: WorkflowCreateRecordAction; action: WorkflowCreateRecordAction;
@ -31,9 +33,13 @@ type WorkflowEditActionCreateRecordProps = {
}; };
}; };
type RelationManyToOneField = {
id: string;
};
type CreateRecordFormData = { type CreateRecordFormData = {
objectName: string; objectName: string;
[field: string]: unknown; [field: string]: RelationManyToOneField | JsonValue;
}; };
const sortByViewFieldPosition = ( const sortByViewFieldPosition = (
@ -77,6 +83,7 @@ export const WorkflowEditActionCreateRecord = ({
objectName: action.settings.input.objectName, objectName: action.settings.input.objectName,
...action.settings.input.objectRecord, ...action.settings.input.objectRecord,
}); });
const isFormDisabled = actionOptions.readonly; const isFormDisabled = actionOptions.readonly;
const objectNameSingular = formData.objectName; const objectNameSingular = formData.objectName;
@ -123,9 +130,27 @@ export const WorkflowEditActionCreateRecord = ({
fieldName: keyof CreateRecordFormData, fieldName: keyof CreateRecordFormData,
updatedValue: JsonValue, updatedValue: JsonValue,
) => { ) => {
const fieldDefinition = inlineFieldDefinitions?.find(
(definition) => definition.metadata.fieldName === fieldName,
);
if (!isDefined(fieldDefinition)) {
return;
}
const isFieldRelationManyToOne =
isFieldRelation(fieldDefinition) &&
fieldDefinition.metadata.relationType === RelationType.MANY_TO_ONE;
const fieldValue = isFieldRelationManyToOne
? {
id: updatedValue,
}
: updatedValue;
const newFormData: CreateRecordFormData = { const newFormData: CreateRecordFormData = {
...formData, ...formData,
[fieldName]: updatedValue, [fieldName]: fieldValue,
}; };
setFormData(newFormData); setFormData(newFormData);
@ -211,16 +236,26 @@ export const WorkflowEditActionCreateRecord = ({
<HorizontalSeparator noMargin /> <HorizontalSeparator noMargin />
{inlineFieldDefinitions?.map((field) => { {inlineFieldDefinitions?.map((fieldDefinition) => {
const currentValue = formData[field.metadata.fieldName] as JsonValue; const isFieldRelationManyToOne =
isFieldRelation(fieldDefinition) &&
fieldDefinition.metadata.relationType === RelationType.MANY_TO_ONE;
const currentValue = isFieldRelationManyToOne
? (
formData[
fieldDefinition.metadata.fieldName
] as RelationManyToOneField
)?.id
: (formData[fieldDefinition.metadata.fieldName] as JsonValue);
return ( return (
<FormFieldInput <FormFieldInput
key={field.metadata.fieldName} key={fieldDefinition.metadata.fieldName}
defaultValue={currentValue} defaultValue={currentValue}
field={field} field={fieldDefinition}
onChange={(value) => { onChange={(value) => {
handleFieldChange(field.metadata.fieldName, value); handleFieldChange(fieldDefinition.metadata.fieldName, value);
}} }}
VariablePicker={WorkflowVariablePicker} VariablePicker={WorkflowVariablePicker}
readonly={isFormDisabled} readonly={isFormDisabled}

View File

@ -7,20 +7,20 @@ import { formatFieldMetadataItemAsFieldDefinition } from '@/object-metadata/util
import { FormFieldInput } from '@/object-record/record-field/components/FormFieldInput'; import { FormFieldInput } from '@/object-record/record-field/components/FormFieldInput';
import { FormSingleRecordPicker } from '@/object-record/record-field/form-types/components/FormSingleRecordPicker'; import { FormSingleRecordPicker } from '@/object-record/record-field/form-types/components/FormSingleRecordPicker';
import { isFieldRelation } from '@/object-record/record-field/types/guards/isFieldRelation'; import { isFieldRelation } from '@/object-record/record-field/types/guards/isFieldRelation';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import { WorkflowFieldsMultiSelect } from '@/workflow/components/WorkflowEditUpdateEventFieldsMultiSelect'; import { WorkflowFieldsMultiSelect } from '@/workflow/components/WorkflowEditUpdateEventFieldsMultiSelect';
import { WorkflowStepBody } from '@/workflow/workflow-steps/components/WorkflowStepBody'; import { WorkflowStepBody } from '@/workflow/workflow-steps/components/WorkflowStepBody';
import { WorkflowStepHeader } from '@/workflow/workflow-steps/components/WorkflowStepHeader'; import { WorkflowStepHeader } from '@/workflow/workflow-steps/components/WorkflowStepHeader';
import { useWorkflowActionHeader } from '@/workflow/workflow-steps/workflow-actions/hooks/useWorkflowActionHeader'; import { useWorkflowActionHeader } from '@/workflow/workflow-steps/workflow-actions/hooks/useWorkflowActionHeader';
import { shouldDisplayFormField } from '@/workflow/workflow-steps/workflow-actions/utils/shouldDisplayFormField'; import { shouldDisplayFormField } from '@/workflow/workflow-steps/workflow-actions/utils/shouldDisplayFormField';
import { WorkflowVariablePicker } from '@/workflow/workflow-variables/components/WorkflowVariablePicker'; import { WorkflowVariablePicker } from '@/workflow/workflow-variables/components/WorkflowVariablePicker';
import { useTheme } from '@emotion/react';
import { isDefined } from 'twenty-shared/utils'; import { isDefined } from 'twenty-shared/utils';
import { HorizontalSeparator, useIcons } from 'twenty-ui/display'; import { HorizontalSeparator, useIcons } from 'twenty-ui/display';
import { SelectOption } from 'twenty-ui/input'; import { SelectOption } from 'twenty-ui/input';
import { JsonValue } from 'type-fest'; import { JsonValue } from 'type-fest';
import { useDebouncedCallback } from 'use-debounce'; import { useDebouncedCallback } from 'use-debounce';
import { RelationType } from '~/generated-metadata/graphql'; import { RelationType } from '~/generated-metadata/graphql';
import { useTheme } from '@emotion/react';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
type WorkflowEditActionUpdateRecordProps = { type WorkflowEditActionUpdateRecordProps = {
action: WorkflowUpdateRecordAction; action: WorkflowUpdateRecordAction;
@ -65,6 +65,7 @@ export const WorkflowEditActionUpdateRecord = ({
fieldsToUpdate: action.settings.input.fieldsToUpdate ?? [], fieldsToUpdate: action.settings.input.fieldsToUpdate ?? [],
...action.settings.input.objectRecord, ...action.settings.input.objectRecord,
}); });
const isFormDisabled = actionOptions.readonly; const isFormDisabled = actionOptions.readonly;
const handleFieldChange = ( const handleFieldChange = (

View File

@ -41,24 +41,30 @@ export const shouldDisplayFormField = ({
isTypeAllowedForAction = isTypeAllowedForAction =
fieldMetadataItem.type !== FieldMetadataType.RELATION || fieldMetadataItem.type !== FieldMetadataType.RELATION ||
fieldMetadataItem.settings?.['relationType'] === 'MANY_TO_ONE'; fieldMetadataItem.settings?.['relationType'] === 'MANY_TO_ONE';
break; return (
isTypeAllowedForAction &&
!fieldMetadataItem.isSystem &&
fieldMetadataItem.isActive
);
case 'UPDATE_RECORD': case 'UPDATE_RECORD':
isTypeAllowedForAction = isTypeAllowedForAction =
COMMON_DISPLAYABLE_FIELD_TYPES.includes(fieldMetadataItem.type) || COMMON_DISPLAYABLE_FIELD_TYPES.includes(fieldMetadataItem.type) ||
fieldMetadataItem.settings?.['relationType'] === 'MANY_TO_ONE'; fieldMetadataItem.settings?.['relationType'] === 'MANY_TO_ONE';
break; return (
isTypeAllowedForAction &&
!fieldMetadataItem.isSystem &&
fieldMetadataItem.isActive
);
case 'FIND_RECORDS': case 'FIND_RECORDS':
isTypeAllowedForAction = FIND_RECORDS_DISPLAYABLE_FIELD_TYPES.includes( isTypeAllowedForAction = FIND_RECORDS_DISPLAYABLE_FIELD_TYPES.includes(
fieldMetadataItem.type, fieldMetadataItem.type,
); );
break; return (
isTypeAllowedForAction &&
(!fieldMetadataItem.isSystem || isIdField) &&
fieldMetadataItem.isActive
);
default: default:
throw new Error(`Action "${actionType}" is not supported`); throw new Error(`Action "${actionType}" is not supported`);
} }
return (
isTypeAllowedForAction &&
(!fieldMetadataItem.isSystem || isIdField) &&
fieldMetadataItem.isActive
);
}; };

View File

@ -75,7 +75,7 @@ export const workflowVersionsAllView = (
field.standardId === WORKFLOW_VERSION_STANDARD_FIELD_IDS.runs, field.standardId === WORKFLOW_VERSION_STANDARD_FIELD_IDS.runs,
)?.id ?? '', )?.id ?? '',
position: 4, position: 4,
isVisible: true, isVisible: false,
size: 150, size: 150,
}, },
], ],