feat(dashboard,medusa): Draft order list page (#6658)
**What** - (dashboard) Adds list page for Draft Order domain - (medusa) Adds the ability to filter draft orders
This commit is contained in:
1 parent
c51a67a421
commit
78e5ec459a
21 files changed
+489
-58
No files matched your search
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
"@medusajs/client-types": patch
|
||||||
|
"@medusajs/medusa": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix(medusa): Add missing query params to draft order list endpoint
|
||||||
@@ -255,7 +255,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"draftOrders": {
|
"draftOrders": {
|
||||||
"domain": "Draft Orders"
|
"domain": "Draft Orders",
|
||||||
|
"deleteWarning": "You are about to delete the draft order {{id}}. This action cannot be undone.",
|
||||||
|
"status": {
|
||||||
|
"open": "Open",
|
||||||
|
"completed": "Completed"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"discounts": {
|
"discounts": {
|
||||||
"domain": "Discounts",
|
"domain": "Discounts",
|
||||||
|
|||||||
@@ -109,11 +109,13 @@ const router = createBrowserRouter([
|
|||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
index: true,
|
index: true,
|
||||||
lazy: () => import("../../routes/draft-orders/list"),
|
lazy: () =>
|
||||||
|
import("../../routes/draft-orders/draft-order-list"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ":id",
|
path: ":id",
|
||||||
lazy: () => import("../../routes/draft-orders/details"),
|
lazy: () =>
|
||||||
|
import("../../routes/draft-orders/draft-order-detail"),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
export const DraftOrderDetails = () => {
|
|
||||||
return <div>Draft Order Details</div>;
|
|
||||||
};
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
export { DraftOrderDetails as Component } from "./details";
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export const DraftOrderDetails = () => {
|
||||||
|
return <div>Draft Order Details</div>
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export { DraftOrderDetails as Component } from "./details"
|
||||||
+69
@@ -0,0 +1,69 @@
|
|||||||
|
import { Button, Container, Heading } from "@medusajs/ui"
|
||||||
|
import { useAdminDraftOrders } from "medusa-react"
|
||||||
|
import { useTranslation } from "react-i18next"
|
||||||
|
import { Link } from "react-router-dom"
|
||||||
|
import { DataTable } from "../../../../../components/table/data-table"
|
||||||
|
import { useDataTable } from "../../../../../hooks/use-data-table"
|
||||||
|
import { useDraftOrderTableColumns } from "./use-draft-order-table-columns"
|
||||||
|
import { useDraftOrderTableFilters } from "./use-draft-order-table-filters"
|
||||||
|
import { useDraftOrderTableQuery } from "./use-draft-order-table-query"
|
||||||
|
|
||||||
|
const PAGE_SIZE = 20
|
||||||
|
|
||||||
|
export const DraftOrderListTable = () => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
|
||||||
|
const { searchParams, raw } = useDraftOrderTableQuery({
|
||||||
|
pageSize: PAGE_SIZE,
|
||||||
|
})
|
||||||
|
const { draft_orders, count, isLoading, isError, error } =
|
||||||
|
useAdminDraftOrders(
|
||||||
|
{
|
||||||
|
...searchParams,
|
||||||
|
expand: "cart,cart.customer",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keepPreviousData: true,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const columns = useDraftOrderTableColumns()
|
||||||
|
const filters = useDraftOrderTableFilters()
|
||||||
|
|
||||||
|
const { table } = useDataTable({
|
||||||
|
data: draft_orders || [],
|
||||||
|
columns,
|
||||||
|
count,
|
||||||
|
enablePagination: true,
|
||||||
|
getRowId: (row) => row.id,
|
||||||
|
pageSize: PAGE_SIZE,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (isError) {
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Container className="divide-y p-0">
|
||||||
|
<div className="flex items-center justify-between px-6 py-4">
|
||||||
|
<Heading>{t("draftOrders.domain")}</Heading>
|
||||||
|
<Button variant="secondary" size="small" asChild>
|
||||||
|
<Link to="create">{t("actions.create")}</Link>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<DataTable
|
||||||
|
table={table}
|
||||||
|
isLoading={isLoading}
|
||||||
|
columns={columns}
|
||||||
|
filters={filters}
|
||||||
|
pageSize={PAGE_SIZE}
|
||||||
|
count={count}
|
||||||
|
search
|
||||||
|
pagination
|
||||||
|
navigateTo={(row) => row.original.id}
|
||||||
|
orderBy={["status", "created_at", "updated_at"]}
|
||||||
|
queryObject={raw}
|
||||||
|
/>
|
||||||
|
</Container>
|
||||||
|
)
|
||||||
|
}
|
||||||
+59
@@ -0,0 +1,59 @@
|
|||||||
|
import { PencilSquare, Trash } from "@medusajs/icons"
|
||||||
|
import { DraftOrder } from "@medusajs/medusa"
|
||||||
|
import { usePrompt } from "@medusajs/ui"
|
||||||
|
import { useAdminDeleteDraftOrder } from "medusa-react"
|
||||||
|
import { useTranslation } from "react-i18next"
|
||||||
|
import { ActionMenu } from "../../../../../components/common/action-menu"
|
||||||
|
|
||||||
|
export const DraftOrderTableActions = ({
|
||||||
|
draftOrder,
|
||||||
|
}: {
|
||||||
|
draftOrder: DraftOrder
|
||||||
|
}) => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
const prompt = usePrompt()
|
||||||
|
|
||||||
|
const { mutateAsync } = useAdminDeleteDraftOrder(draftOrder.id)
|
||||||
|
|
||||||
|
const handleDelete = async () => {
|
||||||
|
const res = await prompt({
|
||||||
|
title: t("general.areYouSure"),
|
||||||
|
description: t("draftOrders.deleteWarning", {
|
||||||
|
id: `#${draftOrder.display_id}`,
|
||||||
|
}),
|
||||||
|
confirmText: t("actions.delete"),
|
||||||
|
cancelText: t("actions.cancel"),
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!res) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
await mutateAsync()
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ActionMenu
|
||||||
|
groups={[
|
||||||
|
{
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
label: t("actions.edit"),
|
||||||
|
to: `${draftOrder.id}/edit`,
|
||||||
|
icon: <PencilSquare />,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
label: t("actions.delete"),
|
||||||
|
onClick: handleDelete,
|
||||||
|
icon: <Trash />,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
export * from "./draft-order-list-table"
|
||||||
+81
@@ -0,0 +1,81 @@
|
|||||||
|
import { DraftOrder } from "@medusajs/medusa"
|
||||||
|
import { createColumnHelper } from "@tanstack/react-table"
|
||||||
|
import { useMemo } from "react"
|
||||||
|
import { useTranslation } from "react-i18next"
|
||||||
|
import { DateCell } from "../../../../../components/table/table-cells/common/date-cell"
|
||||||
|
import { StatusCell } from "../../../../../components/table/table-cells/common/status-cell"
|
||||||
|
import {
|
||||||
|
CustomerCell,
|
||||||
|
CustomerHeader,
|
||||||
|
} from "../../../../../components/table/table-cells/order/customer-cell"
|
||||||
|
import { DraftOrderTableActions } from "./draft-order-table-actions"
|
||||||
|
|
||||||
|
const columnHelper = createColumnHelper<DraftOrder>()
|
||||||
|
|
||||||
|
export const useDraftOrderTableColumns = () => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
|
||||||
|
return useMemo(
|
||||||
|
() => [
|
||||||
|
columnHelper.accessor("display_id", {
|
||||||
|
header: t("fields.id"),
|
||||||
|
cell: ({ getValue }) => (
|
||||||
|
<div className="flex size-full items-center overflow-hidden">
|
||||||
|
<span className="truncate">#{getValue()}</span>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
columnHelper.accessor("status", {
|
||||||
|
header: t("fields.status"),
|
||||||
|
cell: ({ getValue }) => {
|
||||||
|
const status = getValue()
|
||||||
|
|
||||||
|
const { color, label } = {
|
||||||
|
open: { color: "orange", label: t("draftOrders.status.open") },
|
||||||
|
completed: {
|
||||||
|
color: "green",
|
||||||
|
label: t("draftOrders.status.completed"),
|
||||||
|
},
|
||||||
|
}[status] as { color: "green" | "orange"; label: string }
|
||||||
|
|
||||||
|
return <StatusCell color={color}>{label}</StatusCell>
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
columnHelper.accessor("order", {
|
||||||
|
header: t("fields.order"),
|
||||||
|
cell: ({ getValue }) => {
|
||||||
|
const displayId = getValue()?.display_id
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex size-full items-center overflow-hidden">
|
||||||
|
<span className="truncate">
|
||||||
|
{displayId ? `#${displayId}` : "-"}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
columnHelper.accessor("cart.customer", {
|
||||||
|
header: () => <CustomerHeader />,
|
||||||
|
cell: ({ getValue }) => {
|
||||||
|
const customer = getValue()
|
||||||
|
|
||||||
|
return <CustomerCell customer={customer} />
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
columnHelper.accessor("created_at", {
|
||||||
|
header: t("fields.createdAt"),
|
||||||
|
cell: ({ getValue }) => {
|
||||||
|
const date = getValue()
|
||||||
|
|
||||||
|
return <DateCell date={date} />
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
columnHelper.display({
|
||||||
|
id: "actions",
|
||||||
|
cell: ({ row }) => <DraftOrderTableActions draftOrder={row.original} />,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
[t]
|
||||||
|
)
|
||||||
|
}
|
||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
import { useTranslation } from "react-i18next"
|
||||||
|
import { Filter } from "../../../../../components/table/data-table"
|
||||||
|
|
||||||
|
export const useDraftOrderTableFilters = () => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
|
||||||
|
const filters: Filter[] = [
|
||||||
|
{
|
||||||
|
type: "select",
|
||||||
|
multiple: true,
|
||||||
|
key: "status",
|
||||||
|
label: t("fields.status"),
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: t("draftOrders.status.open"),
|
||||||
|
value: "open",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t("draftOrders.status.completed"),
|
||||||
|
value: "completed",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const dateFilters: Filter[] = [
|
||||||
|
{ label: t("fields.createdAt"), key: "created_at" },
|
||||||
|
{ label: t("fields.updatedAt"), key: "updated_at" },
|
||||||
|
].map((f) => ({
|
||||||
|
key: f.key,
|
||||||
|
label: f.label,
|
||||||
|
type: "date",
|
||||||
|
}))
|
||||||
|
|
||||||
|
return [...filters, ...dateFilters]
|
||||||
|
}
|
||||||
+31
@@ -0,0 +1,31 @@
|
|||||||
|
import { AdminGetDraftOrdersParams } from "@medusajs/medusa"
|
||||||
|
import { useQueryParams } from "../../../../../hooks/use-query-params"
|
||||||
|
|
||||||
|
export const useDraftOrderTableQuery = ({
|
||||||
|
pageSize = 20,
|
||||||
|
prefix,
|
||||||
|
}: {
|
||||||
|
pageSize?: number
|
||||||
|
prefix?: string
|
||||||
|
}) => {
|
||||||
|
const raw = useQueryParams(
|
||||||
|
["offset", "q", "order", "status", "created_at", "updated_at"],
|
||||||
|
prefix
|
||||||
|
)
|
||||||
|
|
||||||
|
const { status, offset, created_at, updated_at, ...rest } = raw
|
||||||
|
|
||||||
|
const searchParams: AdminGetDraftOrdersParams = {
|
||||||
|
limit: pageSize,
|
||||||
|
offset: offset ? Number(offset) : 0,
|
||||||
|
status: status ? (status.split(",") as ["open" | "completed"]) : undefined,
|
||||||
|
created_at: created_at ? JSON.parse(created_at) : undefined,
|
||||||
|
updated_at: updated_at ? JSON.parse(updated_at) : undefined,
|
||||||
|
...rest,
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
searchParams,
|
||||||
|
raw,
|
||||||
|
}
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
import { DraftOrderListTable } from "./components/draft-order-list-table"
|
||||||
|
|
||||||
|
export const DraftOrderList = () => {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col gap-y-2">
|
||||||
|
<DraftOrderListTable />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export { DraftOrderList as Component } from "./draft-order-list"
|
||||||
@@ -1 +0,0 @@
|
|||||||
export { DraftOrderList as Component } from "./list";
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
import { Container, Heading } from "@medusajs/ui";
|
|
||||||
|
|
||||||
export const DraftOrderList = () => {
|
|
||||||
return (
|
|
||||||
<Container>
|
|
||||||
<Heading>Draft Orders</Heading>
|
|
||||||
</Container>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -16,4 +16,62 @@ export interface AdminGetDraftOrdersParams {
|
|||||||
* a term to search draft orders' display IDs and emails in the draft order's cart
|
* a term to search draft orders' display IDs and emails in the draft order's cart
|
||||||
*/
|
*/
|
||||||
q?: string
|
q?: string
|
||||||
|
/**
|
||||||
|
* Field to sort retrieved draft orders by.
|
||||||
|
*/
|
||||||
|
order?: string
|
||||||
|
/**
|
||||||
|
* A comma-separated list of fields to expand.
|
||||||
|
*/
|
||||||
|
expand?: string
|
||||||
|
/**
|
||||||
|
* A comma-separated list of fields to include in the response.
|
||||||
|
*/
|
||||||
|
fields?: string
|
||||||
|
/**
|
||||||
|
* Filter by a creation date range.
|
||||||
|
*/
|
||||||
|
created_at?: {
|
||||||
|
/**
|
||||||
|
* filter by dates less than this date
|
||||||
|
*/
|
||||||
|
lt?: string
|
||||||
|
/**
|
||||||
|
* filter by dates greater than this date
|
||||||
|
*/
|
||||||
|
gt?: string
|
||||||
|
/**
|
||||||
|
* filter by dates less than or equal to this date
|
||||||
|
*/
|
||||||
|
lte?: string
|
||||||
|
/**
|
||||||
|
* filter by dates greater than or equal to this date
|
||||||
|
*/
|
||||||
|
gte?: string
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Filter by an update date range.
|
||||||
|
*/
|
||||||
|
updated_at?: {
|
||||||
|
/**
|
||||||
|
* filter by dates less than this date
|
||||||
|
*/
|
||||||
|
lt?: string
|
||||||
|
/**
|
||||||
|
* filter by dates greater than this date
|
||||||
|
*/
|
||||||
|
gt?: string
|
||||||
|
/**
|
||||||
|
* filter by dates less than or equal to this date
|
||||||
|
*/
|
||||||
|
lte?: string
|
||||||
|
/**
|
||||||
|
* filter by dates greater than or equal to this date
|
||||||
|
*/
|
||||||
|
gte?: string
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Filter by status
|
||||||
|
*/
|
||||||
|
status?: Array<"open" | "completed">
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,23 @@
|
|||||||
import { Router } from "express"
|
import { Router } from "express"
|
||||||
import { Cart, DraftOrder, Order } from "../../../.."
|
import { Cart, DraftOrder, Order } from "../../../.."
|
||||||
import { DeleteResponse, PaginatedResponse } from "../../../../types/common"
|
import { DeleteResponse, PaginatedResponse } from "../../../../types/common"
|
||||||
import middlewares from "../../../middlewares"
|
import middlewares, { transformQuery } from "../../../middlewares"
|
||||||
|
import { AdminGetDraftOrdersParams } from "./list-draft-orders"
|
||||||
|
|
||||||
const route = Router()
|
const route = Router()
|
||||||
|
|
||||||
export default (app) => {
|
export default (app) => {
|
||||||
app.use("/draft-orders", route)
|
app.use("/draft-orders", route)
|
||||||
|
|
||||||
route.get("/", middlewares.wrap(require("./list-draft-orders").default))
|
route.get(
|
||||||
|
"/",
|
||||||
|
transformQuery(AdminGetDraftOrdersParams, {
|
||||||
|
defaultFields: defaultAdminDraftOrdersFields,
|
||||||
|
defaultRelations: defaultAdminDraftOrdersRelations,
|
||||||
|
isList: true,
|
||||||
|
}),
|
||||||
|
middlewares.wrap(require("./list-draft-orders").default)
|
||||||
|
)
|
||||||
|
|
||||||
route.get("/:id", middlewares.wrap(require("./get-draft-order").default))
|
route.get("/:id", middlewares.wrap(require("./get-draft-order").default))
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,19 @@
|
|||||||
import { IsNumber, IsOptional, IsString } from "class-validator"
|
|
||||||
import {
|
|
||||||
defaultAdminDraftOrdersFields,
|
|
||||||
defaultAdminDraftOrdersRelations,
|
|
||||||
} from "."
|
|
||||||
|
|
||||||
import { DraftOrder } from "../../../../models"
|
|
||||||
import { DraftOrderListSelector } from "../../../../types/draft-orders"
|
|
||||||
import { DraftOrderService } from "../../../../services"
|
|
||||||
import { FindConfig } from "../../../../types/common"
|
|
||||||
import { Type } from "class-transformer"
|
import { Type } from "class-transformer"
|
||||||
import { validator } from "../../../../utils/validator"
|
import {
|
||||||
|
IsArray,
|
||||||
|
IsEnum,
|
||||||
|
IsNumber,
|
||||||
|
IsOptional,
|
||||||
|
IsString,
|
||||||
|
ValidateNested,
|
||||||
|
} from "class-validator"
|
||||||
|
import { DraftOrderStatus } from "../../../../models"
|
||||||
|
import { DraftOrderService } from "../../../../services"
|
||||||
|
import {
|
||||||
|
DateComparisonOperator,
|
||||||
|
extendedFindParamsMixin,
|
||||||
|
} from "../../../../types/common"
|
||||||
|
import { DraftOrderStatusValue } from "../../../../types/draft-orders"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @oas [get] /admin/draft-orders
|
* @oas [get] /admin/draft-orders
|
||||||
@@ -21,6 +25,63 @@ import { validator } from "../../../../utils/validator"
|
|||||||
* - (query) offset=0 {number} The number of draft orders to skip when retrieving the draft orders.
|
* - (query) offset=0 {number} The number of draft orders to skip when retrieving the draft orders.
|
||||||
* - (query) limit=50 {number} Limit the number of draft orders returned.
|
* - (query) limit=50 {number} Limit the number of draft orders returned.
|
||||||
* - (query) q {string} a term to search draft orders' display IDs and emails in the draft order's cart
|
* - (query) q {string} a term to search draft orders' display IDs and emails in the draft order's cart
|
||||||
|
* - (query) order {string} Field to sort retrieved draft orders by.
|
||||||
|
* - (query) expand {string} A comma-separated list of fields to expand.
|
||||||
|
* - (query) fields {string} A comma-separated list of fields to include in the response.
|
||||||
|
* - in: query
|
||||||
|
* name: created_at
|
||||||
|
* description: Filter by a creation date range.
|
||||||
|
* schema:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* lt:
|
||||||
|
* type: string
|
||||||
|
* description: filter by dates less than this date
|
||||||
|
* format: date
|
||||||
|
* gt:
|
||||||
|
* type: string
|
||||||
|
* description: filter by dates greater than this date
|
||||||
|
* format: date
|
||||||
|
* lte:
|
||||||
|
* type: string
|
||||||
|
* description: filter by dates less than or equal to this date
|
||||||
|
* format: date
|
||||||
|
* gte:
|
||||||
|
* type: string
|
||||||
|
* description: filter by dates greater than or equal to this date
|
||||||
|
* format: date
|
||||||
|
* - in: query
|
||||||
|
* name: updated_at
|
||||||
|
* description: Filter by an update date range.
|
||||||
|
* schema:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* lt:
|
||||||
|
* type: string
|
||||||
|
* description: filter by dates less than this date
|
||||||
|
* format: date
|
||||||
|
* gt:
|
||||||
|
* type: string
|
||||||
|
* description: filter by dates greater than this date
|
||||||
|
* format: date
|
||||||
|
* lte:
|
||||||
|
* type: string
|
||||||
|
* description: filter by dates less than or equal to this date
|
||||||
|
* format: date
|
||||||
|
* gte:
|
||||||
|
* type: string
|
||||||
|
* description: filter by dates greater than or equal to this date
|
||||||
|
* format: date
|
||||||
|
* - in: query
|
||||||
|
* name: status
|
||||||
|
* style: form
|
||||||
|
* explode: false
|
||||||
|
* description: Filter by status
|
||||||
|
* schema:
|
||||||
|
* type: array
|
||||||
|
* items:
|
||||||
|
* type: string
|
||||||
|
* enum: [open, completed]
|
||||||
* x-codegen:
|
* x-codegen:
|
||||||
* method: list
|
* method: list
|
||||||
* queryParams: AdminGetDraftOrdersParams
|
* queryParams: AdminGetDraftOrdersParams
|
||||||
@@ -98,39 +159,27 @@ export default async (req, res) => {
|
|||||||
const draftOrderService: DraftOrderService =
|
const draftOrderService: DraftOrderService =
|
||||||
req.scope.resolve("draftOrderService")
|
req.scope.resolve("draftOrderService")
|
||||||
|
|
||||||
const validated = await validator(AdminGetDraftOrdersParams, req.query)
|
const { skip, take } = req.listConfig
|
||||||
|
|
||||||
const selector: DraftOrderListSelector = {}
|
|
||||||
|
|
||||||
if (validated.q) {
|
|
||||||
selector.q = validated.q
|
|
||||||
}
|
|
||||||
|
|
||||||
const listConfig: FindConfig<DraftOrder> = {
|
|
||||||
select: defaultAdminDraftOrdersFields,
|
|
||||||
relations: defaultAdminDraftOrdersRelations,
|
|
||||||
skip: validated.offset ?? 0,
|
|
||||||
take: validated.limit ?? 50,
|
|
||||||
order: { created_at: "DESC" },
|
|
||||||
}
|
|
||||||
|
|
||||||
const [draftOrders, count] = await draftOrderService.listAndCount(
|
const [draftOrders, count] = await draftOrderService.listAndCount(
|
||||||
selector,
|
req.filterableFields,
|
||||||
listConfig
|
req.listConfig
|
||||||
)
|
)
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
draft_orders: draftOrders,
|
draft_orders: draftOrders,
|
||||||
count,
|
count,
|
||||||
offset: validated.offset,
|
offset: skip,
|
||||||
limit: validated.limit,
|
limit: take,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parameters used to filter and configure the pagination of the retrieved draft orders.
|
* Parameters used to filter and configure the pagination of the retrieved draft orders.
|
||||||
*/
|
*/
|
||||||
export class AdminGetDraftOrdersParams {
|
export class AdminGetDraftOrdersParams extends extendedFindParamsMixin({
|
||||||
|
limit: 50,
|
||||||
|
}) {
|
||||||
/**
|
/**
|
||||||
* Search term to search draft orders by their display IDs and emails.
|
* Search term to search draft orders by their display IDs and emails.
|
||||||
*/
|
*/
|
||||||
@@ -139,18 +188,41 @@ export class AdminGetDraftOrdersParams {
|
|||||||
q?: string
|
q?: string
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc FindPaginationParams.limit}
|
* {@inheritDoc FindParams.expand}
|
||||||
*/
|
*/
|
||||||
@IsNumber()
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@Type(() => Number)
|
@IsString()
|
||||||
limit?: number = 50
|
expand?: string
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc FindPaginationParams.offset}
|
* {@inheritDoc FindPaginationParams.limit}
|
||||||
|
* @defaultValue 50
|
||||||
*/
|
*/
|
||||||
@IsNumber()
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@Type(() => Number)
|
@IsNumber()
|
||||||
offset?: number = 0
|
fields?: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Statuses to filter draft orders by.
|
||||||
|
*/
|
||||||
|
@IsArray()
|
||||||
|
@IsEnum(DraftOrderStatus, { each: true })
|
||||||
|
@IsOptional()
|
||||||
|
status?: DraftOrderStatusValue[]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Date filters to apply on the draft orders' `created_at` date.
|
||||||
|
*/
|
||||||
|
@IsOptional()
|
||||||
|
@ValidateNested()
|
||||||
|
@Type(() => DateComparisonOperator)
|
||||||
|
created_at?: DateComparisonOperator
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Date filters to apply on the draft orders' `updated_at` date.
|
||||||
|
*/
|
||||||
|
@IsOptional()
|
||||||
|
@ValidateNested()
|
||||||
|
@Type(() => DateComparisonOperator)
|
||||||
|
updated_at?: DateComparisonOperator
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
import { AddressPayload } from "./common"
|
import { AddressPayload } from "./common"
|
||||||
|
|
||||||
|
export type DraftOrderStatusValue = "open" | "completed"
|
||||||
|
|
||||||
export type DraftOrderListSelector = { q?: string }
|
export type DraftOrderListSelector = { q?: string }
|
||||||
|
|
||||||
export type DraftOrderCreateProps = {
|
export type DraftOrderCreateProps = {
|
||||||
|
|||||||
Reference in new issue
Block a user