diff --git a/integration-tests/api/__tests__/admin/__snapshots__/colllections.js.snap b/integration-tests/api/__tests__/admin/__snapshots__/colllections.js.snap index 88caf0b69e..2c1e5d7db0 100644 --- a/integration-tests/api/__tests__/admin/__snapshots__/colllections.js.snap +++ b/integration-tests/api/__tests__/admin/__snapshots__/colllections.js.snap @@ -14,6 +14,77 @@ Object { } `; +exports[`/admin/collections /admin/collections filters collections by title 1`] = ` +Object { + "collections": Array [ + Object { + "handle": "test-collection", + "id": "test-collection", + "products": Array [ + Object { + "collection_id": "test-collection", + "created_at": Any, + "deleted_at": null, + "description": "test-product-description", + "discountable": true, + "external_id": null, + "handle": "test-product", + "height": null, + "hs_code": null, + "id": "test-product", + "is_giftcard": false, + "length": null, + "material": null, + "metadata": null, + "mid_code": null, + "origin_country": null, + "profile_id": StringMatching /\\^sp_\\*/, + "status": "draft", + "subtitle": null, + "thumbnail": null, + "title": "Test product", + "type_id": "test-type", + "updated_at": Any, + "weight": null, + "width": null, + }, + Object { + "collection_id": "test-collection", + "created_at": Any, + "deleted_at": null, + "description": "test-product-description1", + "discountable": true, + "external_id": null, + "handle": "test-product1", + "height": null, + "hs_code": null, + "id": "test-product1", + "is_giftcard": false, + "length": null, + "material": null, + "metadata": null, + "mid_code": null, + "origin_country": null, + "profile_id": StringMatching /\\^sp_\\*/, + "status": "draft", + "subtitle": null, + "thumbnail": null, + "title": "Test product1", + "type_id": "test-type", + "updated_at": Any, + "weight": null, + "width": null, + }, + ], + "title": "Test collection", + }, + ], + "count": 1, + "limit": 10, + "offset": 0, +} +`; + exports[`/admin/collections /admin/collections lists collections 1`] = ` Object { "collections": Array [ diff --git a/integration-tests/api/__tests__/admin/colllections.js b/integration-tests/api/__tests__/admin/colllections.js index 6f6b4ed22f..51b0673732 100644 --- a/integration-tests/api/__tests__/admin/colllections.js +++ b/integration-tests/api/__tests__/admin/colllections.js @@ -216,5 +216,42 @@ describe("/admin/collections", () => { count: 3, }) }) + + it("filters collections by title", async () => { + const api = useApi() + + const response = await api + .get("/admin/collections?title=Test%20collection", { + headers: { Authorization: "Bearer test_token" }, + }) + .catch((err) => console.log(err)) + + expect(response.data).toMatchSnapshot({ + collections: [ + { + id: "test-collection", + handle: "test-collection", + title: "Test collection", + products: [ + { + collection_id: "test-collection", + created_at: expect.any(String), + updated_at: expect.any(String), + profile_id: expect.stringMatching(/^sp_*/), + }, + { + collection_id: "test-collection", + created_at: expect.any(String), + updated_at: expect.any(String), + profile_id: expect.stringMatching(/^sp_*/), + }, + ], + }, + ], + count: 1, + limit: 10, + offset: 0, + }) + }) }) }) diff --git a/packages/medusa/src/api/routes/admin/collections/list-collections.ts b/packages/medusa/src/api/routes/admin/collections/list-collections.ts index e8bd0b32a2..05c47e1778 100644 --- a/packages/medusa/src/api/routes/admin/collections/list-collections.ts +++ b/packages/medusa/src/api/routes/admin/collections/list-collections.ts @@ -1,10 +1,12 @@ import { Type } from "class-transformer" -import { IsNumber, IsOptional } from "class-validator" +import { IsNumber, IsOptional, IsString, ValidateNested } from "class-validator" +import _, { identity } from "lodash" import { defaultAdminCollectionsFields, defaultAdminCollectionsRelations, } from "." import ProductCollectionService from "../../../../services/product-collection" +import { DateComparisonOperator } from "../../../../types/common" import { validator } from "../../../../utils/validator" /** * @oas [get] /collections @@ -13,8 +15,13 @@ import { validator } from "../../../../utils/validator" * description: "Retrieve a list of Product Collection." * x-authenticated: true * parameters: - * - (path) limit {string} The number of collections to return. - * - (path) offset {string} The offset of collections to return. + * - (query) limit {string} The number of collections to return. + * - (query) offset {string} The offset of collections to return. + * - (query) title {string} The title of collections to return. + * - (query) handle {string} The handle of collections to return. + * - (query) deleted_at {DateComparisonOperator} Date comparison for when resulting collections was deleted, i.e. less than, greater than etc. + * - (query) created_at {DateComparisonOperator} Date comparison for when resulting collections was created, i.e. less than, greater than etc. + * - (query) updated_at {DateComparisonOperator} Date comparison for when resulting collections was updated, i.e. less than, greater than etc. * tags: * - Collection * responses: @@ -41,8 +48,10 @@ export default async (req, res) => { take: validated.limit, } + const filterableFields = _.omit(validated, ["limit", "offset"]) + const [collections, count] = await productCollectionService.listAndCount( - {}, + _.pickBy(filterableFields, identity), listConfig ) @@ -54,7 +63,7 @@ export default async (req, res) => { }) } -export class AdminGetCollectionsParams { +export class AdminGetCollectionsPaginationParams { @IsNumber() @IsOptional() @Type(() => Number) @@ -65,3 +74,28 @@ export class AdminGetCollectionsParams { @Type(() => Number) offset = 0 } + +export class AdminGetCollectionsParams extends AdminGetCollectionsPaginationParams { + @IsOptional() + @IsString() + title?: string + + @IsOptional() + @IsString() + handle?: string + + @IsOptional() + @ValidateNested() + @Type(() => DateComparisonOperator) + created_at?: DateComparisonOperator + + @IsOptional() + @ValidateNested() + @Type(() => DateComparisonOperator) + updated_at?: DateComparisonOperator + + @ValidateNested() + @IsOptional() + @Type(() => DateComparisonOperator) + deleted_at?: DateComparisonOperator +}