diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/__tests__/computeViewRecordGqlOperationFilter.test.ts b/packages/twenty-front/src/modules/object-record/record-filter/utils/__tests__/computeViewRecordGqlOperationFilter.test.ts index 5a2663d6ca..9a52e51382 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/__tests__/computeViewRecordGqlOperationFilter.test.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/utils/__tests__/computeViewRecordGqlOperationFilter.test.ts @@ -799,6 +799,60 @@ describe('should work as expected for the different field types', () => { }); }); + it('phones field type with an international calling code prefix', () => { + const personMockPhonesFieldMetadataItem = + personMockObjectMetadataItem.fields.find( + (field) => field.name === 'phones', + ); + + if (!isDefined(personMockPhonesFieldMetadataItem)) { + throw new Error('Person mock phones field metadata ID is undefined'); + } + + const phonesFilterContains: RecordFilter = { + id: 'person-phones-filter-contains-calling-code', + value: '+33 6 12', + fieldMetadataId: personMockPhonesFieldMetadataItem.id, + displayValue: '+33 6 12', + operand: ViewFilterOperand.CONTAINS, + label: 'Phones', + type: FieldMetadataType.PHONES, + }; + + const result = computeRecordGqlOperationFilter({ + filterValueDependencies: mockFilterValueDependencies, + recordFilters: [phonesFilterContains], + recordFilterGroups: [], + fieldMetadataItems: personFields, + }); + + expect(result).toEqual({ + or: [ + { + phones: { + primaryPhoneNumber: { + ilike: '%+33612%', + }, + }, + }, + { + phones: { + primaryPhoneCallingCode: { + ilike: '%+33612%', + }, + }, + }, + { + phones: { + additionalPhones: { + like: '%+33612%', + }, + }, + }, + ], + }); + }); + it('emails field type', () => { const personMockEmailFieldMetadataId = getMockFieldMetadataItemOrThrow({ objectMetadataItem: personMockObjectMetadataItem, diff --git a/packages/twenty-shared/src/utils/filter/turnRecordFilterIntoGqlOperationFilter.ts b/packages/twenty-shared/src/utils/filter/turnRecordFilterIntoGqlOperationFilter.ts index 9dca576731..812882af45 100644 --- a/packages/twenty-shared/src/utils/filter/turnRecordFilterIntoGqlOperationFilter.ts +++ b/packages/twenty-shared/src/utils/filter/turnRecordFilterIntoGqlOperationFilter.ts @@ -60,6 +60,10 @@ import { computeRelationGqlFieldJoinColumnName, } from '@/utils/fieldMetadata/compute-relation-gql-field-join-column-name'; +const PHONE_FILTER_NON_SIGNIFICANT_CHARS = /(?!^)\+|[^0-9+]/g; + +const CONTAINS_DIGIT = /[0-9]/; + type FieldSharedMorphRelation = { type: RelationType; targetObjectMetadata: { @@ -1403,9 +1407,11 @@ const buildDirectFieldGqlOperationFilter = ({ } case 'PHONES': { if (!isSubFieldFilter) { - const filterValue = recordFilter.value.replace(/[^0-9]/g, ''); + const filterValue = recordFilter.value + .trim() + .replace(PHONE_FILTER_NON_SIGNIFICANT_CHARS, ''); - if (!isNonEmptyString(filterValue)) { + if (!CONTAINS_DIGIT.test(filterValue)) { return; }