feat(medusa,dashboard): Tax settings pages and fixes to list tax rates endpoint (#6606)

**What**
- Adds pages for managing tax settings and tax rates for regions.
- Fixes `list` tax rates endpoint, which was missing pagination, search, order, and filters.

**Note**
The fix to the tax rate list endpoint is very rough, as I have had to reimplement most of the logic from our transformQuery middleware. This is because this endpoints does not follow normal convention for fields and expand and uses string arrays instead of strings separated by commas. Our middleware does not support this, and changing the endpoint to align with other endpoints on the expand and fields params would be a breaking change. Since this is very temporary until 2.0 I think it's okay for the time being.

CLOSES CORE-1654
This commit is contained in:
Kasper Fabricius Kristensen
2024-03-09 14:19:29 +01:00
committed by GitHub
parent 7109969874
commit c2d56ca12b
88 changed files with 3659 additions and 489 deletions

View File

@@ -0,0 +1,107 @@
import { ShippingOption } from "@medusajs/medusa"
import { PricedShippingOption } from "@medusajs/medusa/dist/types/pricing"
import { createColumnHelper } from "@tanstack/react-table"
import { useMemo } from "react"
import {
AdminOnlyCell,
AdminOnlyHeader,
} from "../../../components/table/table-cells/shipping-option/admin-only-cell"
import {
IsReturnCell,
IsReturnHeader,
} from "../../../components/table/table-cells/shipping-option/is-return-cell"
import {
PriceTypeCell,
PriceTypeHeader,
} from "../../../components/table/table-cells/shipping-option/price-type-cell"
import {
ShippingOptionCell,
ShippingOptionHeader,
} from "../../../components/table/table-cells/shipping-option/shipping-option-cell"
import {
ShippingPriceCell,
ShippingPriceHeader,
} from "../../../components/table/table-cells/shipping-option/shipping-price-cell/shipping-price-cell"
import {
SubtotalRequirementCell,
SubtotalRequirementHeader,
} from "../../../components/table/table-cells/shipping-option/subtotal-requirement-cell"
const columnHelper = createColumnHelper<PricedShippingOption>()
export const useShippingOptionTableColumns = () => {
return useMemo(
() => [
columnHelper.accessor("name", {
header: () => <ShippingOptionHeader />,
cell: ({ getValue }) => <ShippingOptionCell name={getValue()} />,
}),
columnHelper.accessor("is_return", {
header: () => <IsReturnHeader />,
cell: (cell) => {
const value = cell.getValue()
return <IsReturnCell isReturn={value} />
},
}),
columnHelper.accessor("price_type", {
header: () => <PriceTypeHeader />,
cell: ({ getValue }) => {
const type = getValue()
return <PriceTypeCell priceType={type} />
},
}),
columnHelper.accessor("price_incl_tax", {
header: () => <ShippingPriceHeader />,
cell: ({ getValue, row }) => {
const isCalculated = row.original.price_type === "calculated"
const amount = getValue()
const currencyCode = row.original.region!.currency_code
return (
<ShippingPriceCell
isCalculated={isCalculated}
currencyCode={currencyCode}
price={amount}
/>
)
},
}),
columnHelper.display({
id: "min_amount",
header: () => <SubtotalRequirementHeader type="min" />,
cell: ({ row }) => {
return (
<SubtotalRequirementCell
type="min"
shippingOption={row.original as unknown as ShippingOption}
/>
)
},
}),
columnHelper.display({
id: "max_amount",
header: () => <SubtotalRequirementHeader type="max" />,
cell: ({ row }) => {
return (
<SubtotalRequirementCell
type="max"
shippingOption={row.original as unknown as ShippingOption}
/>
)
},
}),
columnHelper.accessor("admin_only", {
header: () => <AdminOnlyHeader />,
cell: (cell) => {
const value = cell.getValue() || false
return <AdminOnlyCell adminOnly={value} />
},
}),
],
[]
)
}

View File

@@ -0,0 +1,39 @@
import { useTranslation } from "react-i18next"
import { Filter } from "../../../components/table/data-table"
export const useShippingOptionTableFilters = () => {
const { t } = useTranslation()
const isReturnFilter: Filter = {
key: "is_return",
label: t("fields.type"),
type: "select",
options: [
{ label: t("regions.return"), value: "true" },
{ label: t("regions.outbound"), value: "false" },
],
}
const isAdminFilter: Filter = {
key: "admin_only",
label: t("fields.availability"),
type: "select",
options: [
{ label: t("general.admin"), value: "true" },
{ label: t("general.store"), value: "false" },
],
}
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",
}))
const filters = [isReturnFilter, isAdminFilter, ...dateFilters]
return filters
}

View File

@@ -0,0 +1,48 @@
import { AdminGetShippingOptionsParams } from "@medusajs/medusa"
import { useQueryParams } from "../../use-query-params"
type UseShippingOptionTableQueryProps = {
regionId: string
isReturn?: boolean
pageSize?: number
prefix?: string
}
export const useShippingOptionTableQuery = ({
regionId,
pageSize = 10,
prefix,
}: UseShippingOptionTableQueryProps) => {
const queryObject = useQueryParams(
[
"offset",
"q",
"order",
"admin_only",
"is_return",
"created_at",
"updated_at",
],
prefix
)
const { offset, order, q, admin_only, is_return, created_at, updated_at } =
queryObject
const searchParams: AdminGetShippingOptionsParams = {
limit: pageSize,
offset: offset ? Number(offset) : 0,
region_id: regionId,
is_return: is_return ? is_return === "true" : undefined,
admin_only: admin_only ? admin_only === "true" : undefined,
q,
order,
created_at: created_at ? JSON.parse(created_at) : undefined,
updated_at: updated_at ? JSON.parse(updated_at) : undefined,
}
return {
searchParams,
raw: queryObject,
}
}