feat(medusa): Add proper pagination (#4517)

* update method for listing regions

* add changeset

* fix unit tests

* listAndCount swaps

* add count calculation to list-returns

* swap integration test

* notes pagination

* pagination props for notifications

* listAndCount store regions

* fix nit

* fix note unit test

* update list-regions store unit test

* cleanup integration test

* rename introduced tests

---------

Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com>
This commit is contained in:
Philip Korsholm
2023-07-14 16:14:51 +02:00
committed by GitHub
co-authored by Oliver Windall Juhl
parent 55db914151
commit 5b91a3503a
21 changed files with 401 additions and 192 deletions
@@ -69,7 +69,7 @@ export default async (req, res) => {
}
const noteService: NoteService = req.scope.resolve("noteService")
const notes = await noteService.list(selector, {
const [notes, count] = await noteService.listAndCount(selector, {
take: validated.limit,
skip: validated.offset,
relations: ["author"],
@@ -77,7 +77,7 @@ export default async (req, res) => {
res.status(200).json({
notes,
count: notes.length,
count,
offset: validated.offset,
limit: validated.limit,
})
@@ -1,5 +1,6 @@
import { Router } from "express"
import { Notification } from "./../../../../"
import { PaginatedResponse } from "@medusajs/types"
import { Router } from "express"
import middlewares from "../../../middlewares"
const route = Router()
@@ -50,8 +51,17 @@ export const defaultAdminNotificationsFields = [
* type: array
* items:
* $ref: "#/components/schemas/Notification"
* count:
* type: integer
* description: The total number of notifications
* offset:
* type: integer
* description: The number of notifications skipped before these notifications
* limit:
* type: integer
* description: The number of notifications per page
*/
export type AdminNotificationsListRes = {
export type AdminNotificationsListRes = PaginatedResponse & {
notifications: Notification[]
}
@@ -3,9 +3,9 @@ import {
defaultAdminNotificationsFields,
defaultAdminNotificationsRelations,
} from "./"
import { Notification } from "../../../../models"
import { FindConfig } from "../../../../types/common"
import { FindConfig } from "../../../../types/common"
import { Notification } from "../../../../models"
import { NotificationService } from "../../../../services"
import { Type } from "class-transformer"
import { pick } from "lodash"
@@ -135,7 +135,10 @@ export default async (req, res) => {
order: { created_at: "DESC" },
} as FindConfig<Notification>
const notifications = await notificationService.list(selector, listConfig)
const [notifications, count] = await notificationService.listAndCount(
selector,
listConfig
)
const resultFields = [
...(listConfig.select ?? []),
@@ -143,7 +146,7 @@ export default async (req, res) => {
]
const data = notifications.map((o) => pick(o, resultFields))
res.json({ notifications: data })
res.json({ notifications: data, count, limit, offset })
}
export class AdminGetNotificationsParams {
@@ -1,11 +1,11 @@
import { IsNumber, IsOptional } from "class-validator"
import { ReturnService } from "../../../../services"
import { Type } from "class-transformer"
import { validator } from "../../../../utils/validator"
import { FindConfig } from "../../../../types/common"
import { Return } from "../../../../models"
import { ReturnService } from "../../../../services"
import { Type } from "class-transformer"
import { defaultRelationsList } from "."
import { validator } from "../../../../utils/validator"
/**
* @oas [get] /admin/returns
@@ -73,11 +73,13 @@ export default async (req, res) => {
order: { created_at: "DESC" },
} as FindConfig<Return>
const returns = await returnService.list(selector, { ...listConfig })
const [returns, count] = await returnService.listAndCount(selector, {
...listConfig,
})
res.json({
returns,
count: returns.length,
count,
offset: validated.offset,
limit: validated.limit,
})
@@ -1,6 +1,6 @@
import { IdMap } from "medusa-test-utils"
import { request } from "../../../../../helpers/test-request"
import { SwapServiceMock } from "../../../../../services/__mocks__/swap"
import { request } from "../../../../../helpers/test-request"
const defaultListOptions = {
take: 50,
@@ -27,8 +27,8 @@ describe("GET /admin/swaps/", () => {
})
it("calls swapService list with default pagination and sorting options", () => {
expect(SwapServiceMock.list).toHaveBeenCalledTimes(1)
expect(SwapServiceMock.list).toHaveBeenCalledWith(
expect(SwapServiceMock.listAndCount).toHaveBeenCalledTimes(1)
expect(SwapServiceMock.listAndCount).toHaveBeenCalledWith(
{},
{
...defaultListOptions,
@@ -1,10 +1,10 @@
import { Type } from "class-transformer"
import { IsInt, IsOptional } from "class-validator"
import { SwapService } from "../../../../services"
import { validator } from "../../../../utils/validator"
import { FindConfig } from "../../../../types/common"
import { Swap } from "../../../../models"
import { SwapService } from "../../../../services"
import { Type } from "class-transformer"
import { validator } from "../../../../utils/validator"
/**
* @oas [get] /admin/swaps
@@ -72,9 +72,11 @@ export default async (req, res) => {
order: { created_at: "DESC" },
}
const swaps = await swapService.list(selector, { ...listConfig })
const [swaps, count] = await swapService.listAndCount(selector, {
...listConfig,
})
res.json({ swaps, count: swaps.length, offset, limit })
res.json({ swaps, count, offset, limit })
}
export class AdminGetSwapsParams {
@@ -1,6 +1,6 @@
import { IdMap } from "medusa-test-utils"
import { request } from "../../../../../helpers/test-request"
import { RegionServiceMock } from "../../../../../services/__mocks__/region"
import { request } from "../../../../../helpers/test-request"
describe("List regions", () => {
describe("list regions", () => {
@@ -14,8 +14,8 @@ describe("List regions", () => {
})
it("calls list from region service", () => {
expect(RegionServiceMock.list).toHaveBeenCalledTimes(1)
expect(RegionServiceMock.list).toHaveBeenCalledWith(
expect(RegionServiceMock.listAndCount).toHaveBeenCalledTimes(1)
expect(RegionServiceMock.listAndCount).toHaveBeenCalledWith(
{},
{
relations: [
@@ -1,6 +1,7 @@
import { PaginatedResponse } from "@medusajs/types"
import { Region } from "./../../../../"
import { Router } from "express"
import middlewares from "../../../middlewares"
import { Region } from "./../../../../"
const route = Router()
@@ -38,8 +39,17 @@ export const defaultRelations = [
* type: array
* items:
* $ref: "#/components/schemas/Region"
* count:
* type: integer
* description: The total number of items available
* offset:
* type: integer
* description: The number of items skipped before these items
* limit:
* type: integer
* description: The number of items per page
*/
export type StoreRegionsListRes = {
export type StoreRegionsListRes = PaginatedResponse & {
regions: Region[]
}
@@ -3,9 +3,9 @@ import { IsInt, IsOptional, ValidateNested } from "class-validator"
import { DateComparisonOperator } from "../../../../types/common"
import RegionService from "../../../../services/region"
import { Type } from "class-transformer"
import { defaultRelations } from "."
import { omit } from "lodash"
import { validator } from "../../../../utils/validator"
import { defaultRelations } from "."
/**
* @oas [get] /store/regions
@@ -110,9 +110,12 @@ export default async (req, res) => {
take: limit,
}
const regions = await regionService.list(filterableFields, listConfig)
const [regions, count] = await regionService.listAndCount(
filterableFields,
listConfig
)
res.json({ regions })
res.json({ regions, count, limit, offset })
}
export class StoreGetRegionsParams {