From f0287d273d26990845a67a82579ae0e9c87c1c0e Mon Sep 17 00:00:00 2001 From: martmull Date: Tue, 14 Jan 2025 11:40:02 +0100 Subject: [PATCH] Add containsAny filter comparators in rest api (#9595) - add missing `containsAny` filter comparator to filter multiSelect fields - fix app break if object with same name created - fix flash when clicking on choose plan ### Before https://github.com/user-attachments/assets/71709912-63e8-40f8-bc52-3ec0a62746bb ### After https://github.com/user-attachments/assets/93ee02c2-e3d9-4bab-8b6a-62813fd40b2b --- .../src/pages/onboarding/ChooseYourPlan.tsx | 2 +- .../format-field-values.utils.spec.ts | 18 ++++++++++++++++++ .../filter-utils/format-field-values.utils.ts | 5 +++-- .../filter-utils/parse-base-filter.utils.ts | 3 ++- .../__tests__/filter-input.factory.spec.ts | 2 +- .../object-metadata/object-metadata.service.ts | 2 +- 6 files changed, 26 insertions(+), 6 deletions(-) diff --git a/packages/twenty-front/src/pages/onboarding/ChooseYourPlan.tsx b/packages/twenty-front/src/pages/onboarding/ChooseYourPlan.tsx index 493a8dfae..1d9098864 100644 --- a/packages/twenty-front/src/pages/onboarding/ChooseYourPlan.tsx +++ b/packages/twenty-front/src/pages/onboarding/ChooseYourPlan.tsx @@ -156,7 +156,7 @@ export const ChooseYourPlan = () => { handleCheckoutSession(); } - if (billingCheckoutSession.skipPlanPage || isSubmitting) { + if (billingCheckoutSession.skipPlanPage && isSubmitting) { return ; } diff --git a/packages/twenty-server/src/engine/api/rest/core/query-builder/utils/filter-utils/__tests__/format-field-values.utils.spec.ts b/packages/twenty-server/src/engine/api/rest/core/query-builder/utils/filter-utils/__tests__/format-field-values.utils.spec.ts index f8d034431..8d18d3f41 100644 --- a/packages/twenty-server/src/engine/api/rest/core/query-builder/utils/filter-utils/__tests__/format-field-values.utils.spec.ts +++ b/packages/twenty-server/src/engine/api/rest/core/query-builder/utils/filter-utils/__tests__/format-field-values.utils.spec.ts @@ -53,5 +53,23 @@ describe('formatFieldValue', () => { ).toThrow( "'filter' invalid for 'in' operator. Received '2024-12-01T14:23:23.914Z' but array value expected eg: 'field[in]:[value_1,value_2]'", ); + + expect( + formatFieldValue( + '["2023-12-01T14:23:23.914Z","2024-12-01T14:23:23.914Z"]', + undefined, + 'containsAny', + ), + ).toEqual(['2023-12-01T14:23:23.914Z', '2024-12-01T14:23:23.914Z']); + + expect( + formatFieldValue('[1,2]', FieldMetadataType.NUMBER, 'containsAny'), + ).toEqual([1, 2]); + + expect(() => + formatFieldValue('2024-12-01T14:23:23.914Z', undefined, 'containsAny'), + ).toThrow( + "'filter' invalid for 'containsAny' operator. Received '2024-12-01T14:23:23.914Z' but array value expected eg: 'field[containsAny]:[value_1,value_2]'", + ); }); }); diff --git a/packages/twenty-server/src/engine/api/rest/core/query-builder/utils/filter-utils/format-field-values.utils.ts b/packages/twenty-server/src/engine/api/rest/core/query-builder/utils/filter-utils/format-field-values.utils.ts index fb9faf671..33052ef83 100644 --- a/packages/twenty-server/src/engine/api/rest/core/query-builder/utils/filter-utils/format-field-values.utils.ts +++ b/packages/twenty-server/src/engine/api/rest/core/query-builder/utils/filter-utils/format-field-values.utils.ts @@ -3,16 +3,17 @@ import { BadRequestException } from '@nestjs/common'; import { FieldMetadataType } from 'twenty-shared'; import { FieldValue } from 'src/engine/api/rest/core/types/field-value.type'; +import { isDefined } from 'src/utils/is-defined'; export const formatFieldValue = ( value: string, fieldType?: FieldMetadataType, comparator?: string, ): FieldValue => { - if (comparator === 'in') { + if (isDefined(comparator) && ['in', 'containsAny'].includes(comparator)) { if (value[0] !== '[' || value[value.length - 1] !== ']') { throw new BadRequestException( - `'filter' invalid for 'in' operator. Received '${value}' but array value expected eg: 'field[in]:[value_1,value_2]'`, + `'filter' invalid for '${comparator}' operator. Received '${value}' but array value expected eg: 'field[${comparator}]:[value_1,value_2]'`, ); } const stringValues = value.substring(1, value.length - 1); diff --git a/packages/twenty-server/src/engine/api/rest/core/query-builder/utils/filter-utils/parse-base-filter.utils.ts b/packages/twenty-server/src/engine/api/rest/core/query-builder/utils/filter-utils/parse-base-filter.utils.ts index 5a11d1a20..0381c45bf 100644 --- a/packages/twenty-server/src/engine/api/rest/core/query-builder/utils/filter-utils/parse-base-filter.utils.ts +++ b/packages/twenty-server/src/engine/api/rest/core/query-builder/utils/filter-utils/parse-base-filter.utils.ts @@ -4,6 +4,7 @@ export enum FilterComparators { eq = 'eq', neq = 'neq', in = 'in', + containsAny = 'containsAny', is = 'is', gt = 'gt', gte = 'gte', @@ -59,7 +60,7 @@ export const parseBaseFilter = ( throw new BadRequestException( `'filter' invalid for '${baseFilter}', comparator ${comparator} not in ${Object.keys( FilterComparators, - ).join(',')}`, + ).join(', ')}`, ); } diff --git a/packages/twenty-server/src/engine/api/rest/input-factories/__tests__/filter-input.factory.spec.ts b/packages/twenty-server/src/engine/api/rest/input-factories/__tests__/filter-input.factory.spec.ts index b6366ff70..0ccf816d1 100644 --- a/packages/twenty-server/src/engine/api/rest/input-factories/__tests__/filter-input.factory.spec.ts +++ b/packages/twenty-server/src/engine/api/rest/input-factories/__tests__/filter-input.factory.spec.ts @@ -47,7 +47,7 @@ describe('FilterInputFactory', () => { }; expect(() => service.create(request, objectMetadata)).toThrow( - "'filter' invalid for 'fieldNumber[wrongComparator]:1', comparator wrongComparator not in eq,neq,in,is,gt,gte,lt,lte,startsWith,like,ilike", + "'filter' invalid for 'fieldNumber[wrongComparator]:1', comparator wrongComparator not in eq, neq, in, containsAny, is, gt, gte, lt, lte, startsWith, like, ilike", ); }); diff --git a/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.service.ts b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.service.ts index 9dff05ab7..4021a3c73 100644 --- a/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata.service.ts @@ -103,7 +103,7 @@ export class ObjectMetadataService extends TypeOrmQueryService