From 9a14b84e58a7db2b38edaf9ce59dcb4416736c30 Mon Sep 17 00:00:00 2001 From: Sebastian Rindom Date: Mon, 4 Jul 2022 16:52:55 +0200 Subject: [PATCH] fix: introduce listAndCount for gift cards to enable pagination (#1754) **What** Proper `listAndCount` implementation for gift cards. --- .../admin/gift-cards/list-gift-cards.ts | 5 +- packages/medusa/src/repositories/gift-card.ts | 64 +++++++++++++++---- packages/medusa/src/services/gift-card.ts | 36 ++++++++++- 3 files changed, 87 insertions(+), 18 deletions(-) diff --git a/packages/medusa/src/api/routes/admin/gift-cards/list-gift-cards.ts b/packages/medusa/src/api/routes/admin/gift-cards/list-gift-cards.ts index 8530be5a4f..9aa990cd56 100644 --- a/packages/medusa/src/api/routes/admin/gift-cards/list-gift-cards.ts +++ b/packages/medusa/src/api/routes/admin/gift-cards/list-gift-cards.ts @@ -1,7 +1,6 @@ import { Type } from "class-transformer" import { IsInt, IsOptional, IsString } from "class-validator" import { pickBy } from "lodash" -import { defaultAdminGiftCardFields, defaultAdminGiftCardRelations } from "." import { GiftCardService } from "../../../../services" import { validator } from "../../../../utils/validator" @@ -30,14 +29,14 @@ export default async (req, res) => { const giftCardService: GiftCardService = req.scope.resolve("giftCardService") - const giftCards = await giftCardService.list( + const [giftCards, count] = await giftCardService.listAndCount( pickBy(req.filterableFields, (val) => typeof val !== "undefined"), req.listConfig ) res.status(200).json({ gift_cards: giftCards, - count: giftCards.length, + count, offset: validated.offset, limit: validated.limit, }) diff --git a/packages/medusa/src/repositories/gift-card.ts b/packages/medusa/src/repositories/gift-card.ts index 9953a43dec..48e2a6cafb 100644 --- a/packages/medusa/src/repositories/gift-card.ts +++ b/packages/medusa/src/repositories/gift-card.ts @@ -15,12 +15,18 @@ export class GiftCardRepository extends Repository { idsOrOptionsWithoutRelations: | Omit, "relations"> | string[] = {} - ): Promise { - let entities + ): Promise<[GiftCard[], number]> { + let entities: GiftCard[] = [] + let count = 0 if (Array.isArray(idsOrOptionsWithoutRelations)) { entities = await this.findByIds(idsOrOptionsWithoutRelations) + count = idsOrOptionsWithoutRelations.length } else { - entities = await this.find(idsOrOptionsWithoutRelations) + const [results, resultCount] = await this.findAndCount( + idsOrOptionsWithoutRelations + ) + entities = results + count = resultCount } const entitiesIds = entities.map(({ id }) => id) @@ -45,15 +51,19 @@ export class GiftCardRepository extends Repository { const entitiesAndRelations = entitiesIdsWithRelations.concat(entities) const entitiesAndRelationsById = groupBy(entitiesAndRelations, "id") - return Object.values(entitiesAndRelationsById).map((v) => merge({}, ...v)) + return [ + Object.values(entitiesAndRelationsById).map((v) => merge({}, ...v)), + count, + ] } protected async queryGiftCards( q: string, where: Partial>>, - rels: (keyof GiftCard | string)[] - ): Promise { - const raw = await this.createQueryBuilder("gift_card") + rels: (keyof GiftCard | string)[], + shouldCount = false + ): Promise<[GiftCard[], number]> { + const qb = this.createQueryBuilder("gift_card") .leftJoinAndSelect("gift_card.order", "order") .select(["gift_card.id"]) .where(where) @@ -64,12 +74,39 @@ export class GiftCardRepository extends Repository { .orWhere(`display_id::varchar(255) ILIKE :dId`, { dId: `${q}` }) }) ) - .getMany() - return this.findWithRelations( + let raw: GiftCard[] = [] + let count = 0 + if (shouldCount) { + const [results, resultCount] = await qb.getManyAndCount() + raw = results + count = resultCount + } else { + raw = await qb.getMany() + } + + const [results] = await this.findWithRelations( rels, raw.map((i) => i.id) ) + + return [results, count] + } + + public async listGiftCardsAndCount( + inputQuery: ExtendedFindConfig>, + rels: (keyof GiftCard | string)[] = [], + q?: string + ): Promise<[GiftCard[], number]> { + const query = { ...inputQuery } + + if (q) { + const where = query.where + delete where.id + + return await this.queryGiftCards(q, where, rels, true) + } + return await this.findWithRelations(rels, query) } public async listGiftCards( @@ -81,9 +118,12 @@ export class GiftCardRepository extends Repository { const where = query.where delete where.id - return await this.queryGiftCards(q, where, rels) + const [result] = await this.queryGiftCards(q, where, rels) + return result } - return this.findWithRelations(rels, query) + + const [results] = await this.findWithRelations(rels, query) + return results } public async findOneWithRelations( @@ -93,7 +133,7 @@ export class GiftCardRepository extends Repository { // Limit 1 optionsWithoutRelations.take = 1 - const result = await this.findWithRelations( + const [result] = await this.findWithRelations( relations, optionsWithoutRelations ) diff --git a/packages/medusa/src/services/gift-card.ts b/packages/medusa/src/services/gift-card.ts index 542bf7deb9..70fd249b0e 100644 --- a/packages/medusa/src/services/gift-card.ts +++ b/packages/medusa/src/services/gift-card.ts @@ -1,6 +1,6 @@ import { MedusaError } from "medusa-core-utils" import randomize from "randomatic" -import { Brackets, EntityManager, FindOneOptions } from "typeorm" +import { EntityManager } from "typeorm" import { EventBusService } from "." import { TransactionBaseService } from "../interfaces" import { GiftCard } from "../models" @@ -76,6 +76,36 @@ class GiftCardService extends TransactionBaseService { return code } + /** + * @param selector - the query object for find + * @param config - the configuration used to find the objects. contains relations, skip, and take. + * @return the result of the find operation + */ + async listAndCount( + selector: QuerySelector = {}, + config: FindConfig = { relations: [], skip: 0, take: 10 } + ): Promise<[GiftCard[], number]> { + return await this.atomicPhase_(async (manager) => { + const giftCardRepo = manager.getCustomRepository(this.giftCardRepository_) + + let q: string | undefined + if (typeof selector.q !== "undefined") { + q = selector.q + delete selector.q + } + + const query: ExtendedFindConfig< + GiftCard, + QuerySelector + > = buildQuery, GiftCard>(selector, config) + + const rels = query.relations + delete query.relations + + return await giftCardRepo.listGiftCardsAndCount(query, rels, q) + }) + } + /** * @param selector - the query object for find * @param config - the configuration used to find the objects. contains relations, skip, and take. @@ -88,8 +118,8 @@ class GiftCardService extends TransactionBaseService { return await this.atomicPhase_(async (manager) => { const giftCardRepo = manager.getCustomRepository(this.giftCardRepository_) - let q - if ("q" in selector) { + let q: string | undefined + if (typeof selector.q !== "undefined") { q = selector.q delete selector.q }