feat: customer group customers client endpoints (#1221)

* feat: add `listCustomers` (by group) to `medusa-js`

* feat: add `useAdminCustomerGroupCustomers` hook

* fix: remove log

* fix: import/export

* fix: change query keys

* wip: sublist query keys

* fix: revert query factory changes

* fix: add query as a param when building the "detail" key

* fix: revert keys logic, use special case

* fix: query path, change batch keys

* change admin customer groups cache key generation

* spread query params

Co-authored-by: fPolic <frane@medusajs.com>
This commit is contained in:
Frane Polić
2022-03-23 20:07:13 +01:00
committed by GitHub
parent 932f4b29a8
commit b7f699654b
7 changed files with 102 additions and 10 deletions

View File

@@ -8,6 +8,8 @@ import {
AdminPostCustomerGroupsGroupCustomersBatchReq,
AdminDeleteCustomerGroupsGroupCustomerBatchReq,
AdminGetCustomerGroupsGroupParams,
AdminCustomersListRes,
AdminGetCustomersParams,
} from "@medusajs/medusa"
import qs from "qs"
@@ -131,6 +133,28 @@ class AdminCustomerGroupsResource extends BaseResource {
const path = `/admin/customer-groups/${id}/customers/batch`
return this.client.request("DELETE", path, payload, {}, customHeaders)
}
/**
* List and count customers that belong to provided customer groups.
*
* @param id - customer group id
* @param query - params for filtering customers
* @param customHeaders
*/
listCustomers(
id: string,
query?: AdminGetCustomersParams,
customHeaders: Record<string, any> = {}
): ResponsePromise<AdminCustomersListRes> {
let path = `/admin/customer-groups/${id}/customers`
if (query) {
const queryString = qs.stringify(query)
path += `?${queryString}`
}
return this.client.request("GET", path, {}, {}, customHeaders)
}
}
export default AdminCustomerGroupsResource

View File

@@ -551,6 +551,15 @@ export const adminHandlers = [
)
}),
rest.get("/admin/customer-groups/:id/customers", (req, res, ctx) => {
return res(
ctx.status(200),
ctx.json({
customers: fixtures.list("customer"),
})
)
}),
rest.get("/admin/discounts/", (req, res, ctx) => {
return res(
ctx.status(200),

View File

@@ -112,7 +112,10 @@ export const useAdminAddCustomersToCustomerGroup = (
client.admin.customerGroups.addCustomers(id, payload),
buildOptions(
queryClient,
[adminCustomerGroupKeys.lists(), adminCustomerGroupKeys.detail(id)],
[
adminCustomerGroupKeys.lists(),
adminCustomerGroupKeys.detailCustomer(id),
],
options
)
)
@@ -140,7 +143,10 @@ export const useAdminRemoveCustomersFromCustomerGroup = (
client.admin.customerGroups.removeCustomers(id, payload),
buildOptions(
queryClient,
[adminCustomerGroupKeys.lists(), adminCustomerGroupKeys.detail(id)],
[
adminCustomerGroupKeys.lists(),
adminCustomerGroupKeys.detailCustomer(id),
],
options
)
)

View File

@@ -1,8 +1,10 @@
import {
AdminCustomerGroupsListRes,
AdminCustomerGroupsRes,
AdminCustomersListRes,
AdminGetCustomerGroupsGroupParams,
AdminGetCustomerGroupsParams,
AdminGetCustomersParams,
} from "@medusajs/medusa"
import { Response } from "@medusajs/medusa-js"
import { useQuery } from "react-query"
@@ -13,9 +15,12 @@ import { queryKeysFactory } from "../../utils"
const ADMIN_CUSTOMER_GROUPS_QUERY_KEY = `admin_customer_groups` as const
export const adminCustomerGroupKeys = queryKeysFactory(
ADMIN_CUSTOMER_GROUPS_QUERY_KEY
)
export const adminCustomerGroupKeys = {
...queryKeysFactory(ADMIN_CUSTOMER_GROUPS_QUERY_KEY),
detailCustomer(id: string, query?: AdminGetCustomersParams) {
return [...this.detail(id), "customers", { ...(query || {}) }]
},
}
type CustomerGroupQueryKeys = typeof adminCustomerGroupKeys
@@ -66,3 +71,28 @@ export const useAdminCustomerGroups = (
)
return { ...data, ...rest } as const
}
/**
* Hook retrieves a list of customers that belong to provided groups.
*
* @param id - customer group id
* @param query - pagination/filtering params
* @param options
*/
export const useAdminCustomerGroupCustomers = (
id: string,
query?: AdminGetCustomersParams,
options?: UseQueryOptionsWrapper<
Response<AdminCustomersListRes>,
Error,
ReturnType<CustomerGroupQueryKeys["detailCustomer"]>
>
) => {
const { client } = useMedusa()
const { data, ...rest } = useQuery(
adminCustomerGroupKeys.detailCustomer(id, query),
() => client.admin.customerGroups.listCustomers(id, query),
options
)
return { ...data, ...rest } as const
}

View File

@@ -1,9 +1,11 @@
import { adminCustomerKeys } from "./queries"
import { useMutation, UseMutationOptions, useQueryClient } from "react-query"
import { AdminCustomersRes, AdminPostCustomersReq } from "@medusajs/medusa"
import { Response } from "@medusajs/medusa-js"
import { useMutation, UseMutationOptions, useQueryClient } from "react-query"
import { useMedusa } from "../../../contexts/medusa"
import { useMedusa } from "../../../contexts"
import { buildOptions } from "../../utils/buildOptions"
import { adminCustomerKeys } from "./queries"
export const useAdminCreateCustomer = (
options?: UseMutationOptions<

View File

@@ -7,7 +7,7 @@ import { Response } from "@medusajs/medusa-js"
import { useQuery } from "react-query"
import { useMedusa } from "../../../contexts"
import { UseQueryOptionsWrapper } from "../../../types"
import { queryKeysFactory } from "../../utils/index"
import { queryKeysFactory } from "../../utils"
const ADMIN_CUSTOMERS_QUERY_KEY = `admin_customers` as const

View File

@@ -1,6 +1,10 @@
import { renderHook } from "@testing-library/react-hooks"
import { useAdminCustomerGroup, useAdminCustomerGroups } from "../../../../src"
import {
useAdminCustomerGroup,
useAdminCustomerGroupCustomers,
useAdminCustomerGroups,
} from "../../../../src"
import { fixtures } from "../../../../mocks/data"
import { createWrapper } from "../../../utils"
@@ -31,4 +35,21 @@ describe("useAdminCustomerGroup hook", () => {
expect(result.current.response.status).toEqual(200)
expect(result.current.customer_groups).toEqual(groups)
})
test("returns a list of customers that belong to a group", async () => {
const groups = fixtures.list("customer_group")
const customers = fixtures.list("customer")
const { result, waitFor } = renderHook(
() => useAdminCustomerGroupCustomers(groups[0].id),
{
wrapper: createWrapper(),
}
)
await waitFor(() => result.current.isSuccess)
expect(result.current.response.status).toEqual(200)
expect(result.current.customers).toEqual(customers)
})
})