Browse Source

fix(core): Fix list query sorting by non-default language with filters

Michael Bromley 5 years ago
parent
commit
1e31828cf6

+ 60 - 0
packages/core/e2e/list-query-builder.e2e-spec.ts

@@ -633,6 +633,66 @@ describe('ListQueryBuilder', () => {
             expect(testEntities.items.map((x: any) => x.label)).toEqual(['B', 'A', 'E', 'D', 'C']);
         });
     });
+
+    describe('multiple clauses', () => {
+        it('sort by translated field en & filter', async () => {
+            const { testEntities } = await adminClient.query(GET_LIST, {
+                options: {
+                    sort: {
+                        name: SortOrder.ASC,
+                    },
+                    filter: {
+                        order: {
+                            gte: 1,
+                        },
+                    },
+                },
+            });
+            expect(testEntities.items.map((x: any) => x.name)).toEqual(['bike', 'cake', 'dog', 'egg']);
+        });
+
+        it('sort by translated field de & filter', async () => {
+            const { testEntities } = await adminClient.query(
+                GET_LIST,
+                {
+                    options: {
+                        sort: {
+                            name: SortOrder.ASC,
+                        },
+                        filter: {
+                            order: {
+                                gte: 1,
+                            },
+                        },
+                    },
+                },
+                { languageCode: LanguageCode.de },
+            );
+            expect(testEntities.items.map((x: any) => x.name)).toEqual(['egg', 'fahrrad', 'hund', 'kuchen']);
+        });
+
+        it('sort by translated field de & filter & pagination', async () => {
+            const { testEntities } = await adminClient.query(
+                GET_LIST,
+                {
+                    options: {
+                        sort: {
+                            name: SortOrder.ASC,
+                        },
+                        filter: {
+                            order: {
+                                gte: 1,
+                            },
+                        },
+                        take: 2,
+                        skip: 1,
+                    },
+                },
+                { languageCode: LanguageCode.de },
+            );
+            expect(testEntities.items.map((x: any) => x.name)).toEqual(['fahrrad', 'hund']);
+        });
+    });
 });
 
 const GET_LIST = gql`

+ 31 - 27
packages/core/src/service/helpers/list-query-builder/list-query-builder.ts

@@ -154,34 +154,38 @@ export class ListQueryBuilder implements OnApplicationBootstrap {
                 'translations',
             );
 
-            qb.andWhere(`${translationsAlias}.languageCode = :languageCode`, { languageCode });
-
-            if (languageCode !== this.configService.defaultLanguageCode) {
-                // If the current languageCode is not the default, then we create a more
-                // complex WHERE clause to allow us to use the non-default translations and
-                // fall back to the default language if no translation exists.
-                qb.orWhere(
-                    new Brackets(qb1 => {
-                        const translationEntity = translationColumns[0].entityMetadata.target;
-                        const subQb1 = this.connection.rawConnection
-                            .createQueryBuilder(translationEntity, 'translation')
-                            .where(`translation.base = ${alias}.id`)
-                            .andWhere('translation.languageCode = :defaultLanguageCode');
-                        const subQb2 = this.connection.rawConnection
-                            .createQueryBuilder(translationEntity, 'translation')
-                            .where(`translation.base = ${alias}.id`)
-                            .andWhere('translation.languageCode = :nonDefaultLanguageCode');
-
-                        qb1.where(`EXISTS (${subQb1.getQuery()})`).andWhere(
-                            `NOT EXISTS (${subQb2.getQuery()})`,
+            qb.andWhere(
+                new Brackets(qb1 => {
+                    qb1.where(`${translationsAlias}.languageCode = :languageCode`, { languageCode });
+
+                    if (languageCode !== this.configService.defaultLanguageCode) {
+                        // If the current languageCode is not the default, then we create a more
+                        // complex WHERE clause to allow us to use the non-default translations and
+                        // fall back to the default language if no translation exists.
+                        qb1.orWhere(
+                            new Brackets(qb2 => {
+                                const translationEntity = translationColumns[0].entityMetadata.target;
+                                const subQb1 = this.connection.rawConnection
+                                    .createQueryBuilder(translationEntity, 'translation')
+                                    .where(`translation.base = ${alias}.id`)
+                                    .andWhere('translation.languageCode = :defaultLanguageCode');
+                                const subQb2 = this.connection.rawConnection
+                                    .createQueryBuilder(translationEntity, 'translation')
+                                    .where(`translation.base = ${alias}.id`)
+                                    .andWhere('translation.languageCode = :nonDefaultLanguageCode');
+
+                                qb2.where(`EXISTS (${subQb1.getQuery()})`).andWhere(
+                                    `NOT EXISTS (${subQb2.getQuery()})`,
+                                );
+                            }),
                         );
-                    }),
-                );
-                qb.setParameters({
-                    nonDefaultLanguageCode: languageCode,
-                    defaultLanguageCode: this.configService.defaultLanguageCode,
-                });
-            }
+                        qb.setParameters({
+                            nonDefaultLanguageCode: languageCode,
+                            defaultLanguageCode: this.configService.defaultLanguageCode,
+                        });
+                    }
+                }),
+            );
         }
     }