Keep leading + when filtering phones by calling code (#23546)
Fixes #23528 Filtering a PHONES field with `CONTAINS` / `DOES_NOT_CONTAIN` stripped every non-digit character from the filter value, so `+33` became `33` and the generated `ilike`/`like` predicates could not distinguish an international calling code from any number containing those digits. `turnRecordFilterIntoGqlOperationFilter` now preserves a leading `+` while still removing other formatting characters (spaces, dashes, parentheses). `+33 6 12` becomes `+33612`; values without a `+` are unchanged. Added a regression test in `computeViewRecordGqlOperationFilter.test.ts` for a `+`-prefixed value. Lint and typecheck pass on `twenty-shared` and `twenty-front`; the filter test suites pass in both packages. --------- Co-authored-by: Thomas Trompette <tom@twenty.com>
This commit is contained in:
+54
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user