From 61e5d5bcb97ac9047d1b68a43f9da9afe693751c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tha=C3=AFs?= Date: Mon, 25 Mar 2024 16:37:41 +0100 Subject: [PATCH] fix: fix Select field preview (#4507) * fix: fix Select field preview Closes #4084 * fix: fix field preview utils tests --- .../types/guards/isFieldSelectValue.ts | 7 ++++--- .../record-field/utils/isFieldValueEmpty.ts | 17 +++++++++-------- .../selectFieldValueSchema.ts | 10 ++++++++++ .../fields/preview/hooks/useFieldPreview.ts | 2 ++ .../getFieldDefaultPreviewValue.test.ts | 6 +++--- .../getFieldPreviewValueFromRecord.test.ts | 2 +- .../utils/getFieldDefaultPreviewValue.ts | 4 +++- .../utils/getFieldPreviewValueFromRecord.ts | 2 +- 8 files changed, 33 insertions(+), 17 deletions(-) create mode 100644 packages/twenty-front/src/modules/object-record/record-field/validation-schemas/selectFieldValueSchema.ts diff --git a/packages/twenty-front/src/modules/object-record/record-field/types/guards/isFieldSelectValue.ts b/packages/twenty-front/src/modules/object-record/record-field/types/guards/isFieldSelectValue.ts index 55dbaa4a6..0c95b795b 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/types/guards/isFieldSelectValue.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/types/guards/isFieldSelectValue.ts @@ -1,7 +1,8 @@ -import { isString } from '@sniptt/guards'; - import { FieldSelectValue } from '@/object-record/record-field/types/FieldMetadata'; +import { selectFieldValueSchema } from '@/object-record/record-field/validation-schemas/selectFieldValueSchema'; export const isFieldSelectValue = ( fieldValue: unknown, -): fieldValue is FieldSelectValue => isString(fieldValue); + options?: string[], +): fieldValue is FieldSelectValue => + selectFieldValueSchema(options).safeParse(fieldValue).success; diff --git a/packages/twenty-front/src/modules/object-record/record-field/utils/isFieldValueEmpty.ts b/packages/twenty-front/src/modules/object-record/record-field/utils/isFieldValueEmpty.ts index 28a82116d..3bd94a09f 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/utils/isFieldValueEmpty.ts +++ b/packages/twenty-front/src/modules/object-record/record-field/utils/isFieldValueEmpty.ts @@ -12,7 +12,6 @@ import { isFieldLinkValue } from '@/object-record/record-field/types/guards/isFi import { isFieldNumber } from '@/object-record/record-field/types/guards/isFieldNumber'; import { isFieldRating } from '@/object-record/record-field/types/guards/isFieldRating'; import { isFieldRelation } from '@/object-record/record-field/types/guards/isFieldRelation'; -import { isFieldRelationValue } from '@/object-record/record-field/types/guards/isFieldRelationValue'; import { isFieldSelect } from '@/object-record/record-field/types/guards/isFieldSelect'; import { isFieldSelectValue } from '@/object-record/record-field/types/guards/isFieldSelectValue'; import { isFieldText } from '@/object-record/record-field/types/guards/isFieldText'; @@ -24,9 +23,11 @@ const isValueEmpty = (value: unknown) => !isDefined(value) || value === ''; export const isFieldValueEmpty = ({ fieldDefinition, fieldValue, + selectOptionValues, }: { fieldDefinition: Pick, 'type'>; fieldValue: unknown; + selectOptionValues?: string[]; }) => { if ( isFieldUuid(fieldDefinition) || @@ -35,18 +36,18 @@ export const isFieldValueEmpty = ({ isFieldNumber(fieldDefinition) || isFieldRating(fieldDefinition) || isFieldEmail(fieldDefinition) || - isFieldBoolean(fieldDefinition) + isFieldBoolean(fieldDefinition) || + isFieldRelation(fieldDefinition) //|| isFieldPhone(fieldDefinition) ) { return isValueEmpty(fieldValue); } - if (isFieldRelation(fieldDefinition)) { - return isFieldRelationValue(fieldValue) && isValueEmpty(fieldValue); - } - if (isFieldSelect(fieldDefinition)) { - return isFieldSelectValue(fieldValue) && !isDefined(fieldValue); + return ( + !isFieldSelectValue(fieldValue, selectOptionValues) || + !isDefined(fieldValue) + ); } if (isFieldCurrency(fieldDefinition)) { @@ -68,6 +69,6 @@ export const isFieldValueEmpty = ({ } throw new Error( - `Entity field type not supported in isEntityFieldEditModeEmptyFamilySelector : ${fieldDefinition.type}}`, + `Entity field type not supported in isFieldValueEmpty : ${fieldDefinition.type}}`, ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-field/validation-schemas/selectFieldValueSchema.ts b/packages/twenty-front/src/modules/object-record/record-field/validation-schemas/selectFieldValueSchema.ts new file mode 100644 index 000000000..ca79234e8 --- /dev/null +++ b/packages/twenty-front/src/modules/object-record/record-field/validation-schemas/selectFieldValueSchema.ts @@ -0,0 +1,10 @@ +import { z } from 'zod'; + +import { FieldSelectValue } from '@/object-record/record-field/types/FieldMetadata'; + +export const selectFieldValueSchema = ( + options?: string[], +): z.ZodType => + options?.length + ? z.enum(options as [string, ...string[]]).nullable() + : z.string().nullable(); diff --git a/packages/twenty-front/src/modules/settings/data-model/fields/preview/hooks/useFieldPreview.ts b/packages/twenty-front/src/modules/settings/data-model/fields/preview/hooks/useFieldPreview.ts index e5ce19c71..8f29de04e 100644 --- a/packages/twenty-front/src/modules/settings/data-model/fields/preview/hooks/useFieldPreview.ts +++ b/packages/twenty-front/src/modules/settings/data-model/fields/preview/hooks/useFieldPreview.ts @@ -55,11 +55,13 @@ export const useFieldPreview = ({ }) : null; + const selectOptionValues = selectOptions?.map((option) => option.value); const isValueFromFirstRecord = firstRecord && !isFieldValueEmpty({ fieldDefinition: { type: fieldMetadataItem.type }, fieldValue: fieldPreviewValueFromFirstRecord, + selectOptionValues, }); const { records: relationRecords } = useFindManyRecords({ diff --git a/packages/twenty-front/src/modules/settings/data-model/utils/__tests__/getFieldDefaultPreviewValue.test.ts b/packages/twenty-front/src/modules/settings/data-model/utils/__tests__/getFieldDefaultPreviewValue.test.ts index 18b9117d6..41579bfc9 100644 --- a/packages/twenty-front/src/modules/settings/data-model/utils/__tests__/getFieldDefaultPreviewValue.test.ts +++ b/packages/twenty-front/src/modules/settings/data-model/utils/__tests__/getFieldDefaultPreviewValue.test.ts @@ -37,7 +37,7 @@ describe('getFieldDefaultPreviewValue', () => { }); // Then - expect(result).toEqual(selectOptions[1]); + expect(result).toEqual(selectOptions[1].value); }); it('returns the first select option if no default option was found', () => { @@ -46,7 +46,7 @@ describe('getFieldDefaultPreviewValue', () => { const fieldMetadataItem = mockedCompanyObjectMetadataItem.fields.find( ({ name }) => name === 'industry', )!; - const selectOptions = [ + const selectOptions: SettingsObjectFieldSelectFormValues = [ { color: 'purple' as const, label: '🏭 Industry', @@ -67,7 +67,7 @@ describe('getFieldDefaultPreviewValue', () => { }); // Then - expect(result).toEqual(selectOptions[0]); + expect(result).toEqual(selectOptions[0].value); }); }); diff --git a/packages/twenty-front/src/modules/settings/data-model/utils/__tests__/getFieldPreviewValueFromRecord.test.ts b/packages/twenty-front/src/modules/settings/data-model/utils/__tests__/getFieldPreviewValueFromRecord.test.ts index 3737f2510..12e691529 100644 --- a/packages/twenty-front/src/modules/settings/data-model/utils/__tests__/getFieldPreviewValueFromRecord.test.ts +++ b/packages/twenty-front/src/modules/settings/data-model/utils/__tests__/getFieldPreviewValueFromRecord.test.ts @@ -42,7 +42,7 @@ describe('getFieldPreviewValueFromRecord', () => { }); // Then - expect(result).toEqual(selectOptions[2]); + expect(result).toEqual(selectOptions[2].value); }); it('returns undefined if the select option was not found', () => { diff --git a/packages/twenty-front/src/modules/settings/data-model/utils/getFieldDefaultPreviewValue.ts b/packages/twenty-front/src/modules/settings/data-model/utils/getFieldDefaultPreviewValue.ts index ff4938125..3994ab36e 100644 --- a/packages/twenty-front/src/modules/settings/data-model/utils/getFieldDefaultPreviewValue.ts +++ b/packages/twenty-front/src/modules/settings/data-model/utils/getFieldDefaultPreviewValue.ts @@ -26,7 +26,9 @@ export const getFieldDefaultPreviewValue = ({ fieldMetadataItem.type === FieldMetadataType.Select && isDefined(selectOptions) ) { - return selectOptions.find(({ isDefault }) => isDefault) || selectOptions[0]; + const defaultSelectOption = + selectOptions.find(({ isDefault }) => isDefault) || selectOptions[0]; + return defaultSelectOption.value; } // Relation field diff --git a/packages/twenty-front/src/modules/settings/data-model/utils/getFieldPreviewValueFromRecord.ts b/packages/twenty-front/src/modules/settings/data-model/utils/getFieldPreviewValueFromRecord.ts index 79e0a952c..9e72b8755 100644 --- a/packages/twenty-front/src/modules/settings/data-model/utils/getFieldPreviewValueFromRecord.ts +++ b/packages/twenty-front/src/modules/settings/data-model/utils/getFieldPreviewValueFromRecord.ts @@ -18,7 +18,7 @@ export const getFieldPreviewValueFromRecord = ({ if (fieldMetadataItem.type === FieldMetadataType.Select) { return selectOptions?.find( (selectOption) => selectOption.value === recordFieldValue, - ); + )?.value; } // Relation fields (to many)