Просмотр исходного кода

fix(core): Fix sorting by localeString custom fields

Fixes #1581
Michael Bromley 3 лет назад
Родитель
Сommit
e0960018da

+ 25 - 0
packages/core/e2e/custom-fields.e2e-spec.ts

@@ -767,6 +767,19 @@ describe('Custom fields', () => {
             expect(products.totalItems).toBe(1);
         });
 
+        // https://github.com/vendure-ecommerce/vendure/issues/1581
+        it('can sort by localeString custom fields', async () => {
+            const { products } = await adminClient.query(gql`
+                query {
+                    products(options: { sort: { localeStringWithDefault: ASC } }) {
+                        totalItems
+                    }
+                }
+            `);
+
+            expect(products.totalItems).toBe(1);
+        });
+
         it('can filter by custom fields', async () => {
             const { products } = await adminClient.query(gql`
                 query {
@@ -779,6 +792,18 @@ describe('Custom fields', () => {
             expect(products.totalItems).toBe(1);
         });
 
+        it('can filter by localeString custom fields', async () => {
+            const { products } = await adminClient.query(gql`
+                query {
+                    products(options: { filter: { localeStringWithDefault: { contains: "hola" } } }) {
+                        totalItems
+                    }
+                }
+            `);
+
+            expect(products.totalItems).toBe(1);
+        });
+
         it('can filter by custom list fields', async () => {
             const { products: result1 } = await adminClient.query(gql`
                 query {

+ 3 - 0
packages/core/src/service/helpers/list-query-builder/list-query-builder.ts

@@ -19,6 +19,7 @@ import { RequestContext } from '../../../api/common/request-context';
 import { UserInputError } from '../../../common/error/errors';
 import { FilterParameter, ListQueryOptions, SortParameter } from '../../../common/types/common-types';
 import { ConfigService } from '../../../config/config.service';
+import { CustomFields } from '../../../config/index';
 import { Logger } from '../../../config/logger/vendure-logger';
 import { TransactionalConnection } from '../../../connection/transactional-connection';
 import { VendureEntity } from '../../../entity/base/base.entity';
@@ -216,12 +217,14 @@ export class ListQueryBuilder implements OnApplicationBootstrap {
         if (customPropertyMap) {
             this.normalizeCustomPropertyMap(customPropertyMap, options, qb);
         }
+        const customFieldsForType = this.configService.customFields[entity.name as keyof CustomFields];
         const sort = parseSortParams(
             rawConnection,
             entity,
             Object.assign({}, options.sort, extendedOptions.orderBy),
             customPropertyMap,
             entityAlias,
+            customFieldsForType,
         );
         const filter = parseFilterParams(
             rawConnection,

+ 12 - 3
packages/core/src/service/helpers/list-query-builder/parse-sort-params.spec.ts

@@ -4,6 +4,7 @@ import { ColumnMetadata } from 'typeorm/metadata/ColumnMetadata';
 import { RelationMetadata } from 'typeorm/metadata/RelationMetadata';
 
 import { SortParameter } from '../../../common/types/common-types';
+import { CustomFieldConfig } from '../../../config/index';
 import { ProductTranslation } from '../../../entity/product/product-translation.entity';
 import { Product } from '../../../entity/product/product.entity';
 import { I18nError } from '../../../i18n/i18n-error';
@@ -98,10 +99,18 @@ describe('parseSortParams()', () => {
         const sortParams: SortParameter<Product & { shortName: any }> = {
             shortName: 'ASC',
         };
-
-        const result = parseSortParams(connection as any, Product, sortParams);
+        const productCustomFields: CustomFieldConfig[] = [{ name: 'shortName', type: 'localeString' }];
+
+        const result = parseSortParams(
+            connection as any,
+            Product,
+            sortParams,
+            {},
+            undefined,
+            productCustomFields,
+        );
         expect(result).toEqual({
-            'product_translations.shortName': 'ASC',
+            'product_translations.customFields.shortName': 'ASC',
         });
     });
 

+ 10 - 1
packages/core/src/service/helpers/list-query-builder/parse-sort-params.ts

@@ -5,6 +5,7 @@ import { ColumnMetadata } from 'typeorm/metadata/ColumnMetadata';
 
 import { UserInputError } from '../../../common/error/errors';
 import { NullOptionals, SortParameter } from '../../../common/types/common-types';
+import { CustomFieldConfig } from '../../../config/index';
 import { VendureEntity } from '../../../entity/base/base.entity';
 
 import { escapeCalculatedColumnExpression, getColumnMetadata } from './connection-utils';
@@ -23,6 +24,7 @@ export function parseSortParams<T extends VendureEntity>(
     sortParams?: NullOptionals<SortParameter<T>> | null,
     customPropertyMap?: { [name: string]: string },
     entityAlias?: string,
+    customFields?: CustomFieldConfig[],
 ): OrderByCondition {
     if (!sortParams || Object.keys(sortParams).length === 0) {
         return {};
@@ -38,7 +40,14 @@ export function parseSortParams<T extends VendureEntity>(
             output[`${alias}.${matchingColumn.propertyPath}`] = order as any;
         } else if (translationColumns.find(c => c.propertyName === key)) {
             const translationsAlias = connection.namingStrategy.eagerJoinRelationAlias(alias, 'translations');
-            output[`${translationsAlias}.${key}`] = order as any;
+            const pathParts = [translationsAlias];
+            const isLocaleStringCustomField =
+                customFields?.find(f => f.name === key)?.type === 'localeString';
+            if (isLocaleStringCustomField) {
+                pathParts.push('customFields');
+            }
+            pathParts.push(key);
+            output[pathParts.join('.')] = order as any;
         } else if (calculatedColumnDef) {
             const instruction = calculatedColumnDef.listQuery;
             if (instruction && instruction.expression) {