feat(admin-shared,dashboard,js-sdk,types): refund reasons in dashboard (#13575)

CLOSES CORE-1209

This PR just adds the stuff necessary to support refund reasons in the dashboard. It adds the option in the settings tab and allows viewing, creating, editing and deleting refund reasons. I hate to open such a big PR but most of it is copy pasted from the return reasons. Major difference is only the fact that refund reasons don't have a `value` field
This commit is contained in:
William Bouchard
2025-09-23 11:51:40 -04:00
committed by GitHub
parent 543c9f7d0f
commit 5e827ec95d
39 changed files with 1190 additions and 131 deletions
@@ -1,29 +1,124 @@
import { HttpTypes } from "@medusajs/types"
import { QueryKey, useQuery, UseQueryOptions } from "@tanstack/react-query"
import { sdk } from "../../lib/client"
import { queryKeysFactory } from "../../lib/query-key-factory"
import { FetchError } from "@medusajs/js-sdk"
import {
useMutation,
UseMutationOptions,
useQuery,
UseQueryOptions,
} from "@tanstack/react-query"
const REFUND_REASON_QUERY_KEY = "refund-reason" as const
export const refundReasonQueryKeys = queryKeysFactory(REFUND_REASON_QUERY_KEY)
import { FetchError } from "@medusajs/js-sdk"
import { sdk } from "../../lib/client"
import { queryClient } from "../../lib/query-client"
import { queryKeysFactory } from "../../lib/query-key-factory"
const REFUND_REASONS_QUERY_KEY = "refund_reasons" as const
export const refundReasonsQueryKeys = queryKeysFactory(REFUND_REASONS_QUERY_KEY)
export const useRefundReasons = (
query?: HttpTypes.RefundReasonFilters,
query?: HttpTypes.AdminRefundReasonListParams,
options?: Omit<
UseQueryOptions<
HttpTypes.RefundReasonsResponse,
HttpTypes.AdminRefundReasonListResponse,
FetchError,
HttpTypes.RefundReasonsResponse,
QueryKey
HttpTypes.AdminRefundReasonListResponse
>,
"queryKey" | "queryFn"
"queryFn" | "queryKey"
>
) => {
const { data, ...rest } = useQuery({
queryFn: () => sdk.admin.refundReason.list(query),
queryKey: [],
queryKey: refundReasonsQueryKeys.list(query),
...options,
})
return { ...data, ...rest }
}
export const useRefundReason = (
id: string,
query?: HttpTypes.AdminRefundReasonParams,
options?: Omit<
UseQueryOptions<
HttpTypes.AdminRefundReasonResponse,
FetchError,
HttpTypes.AdminRefundReasonResponse
>,
"queryFn" | "queryKey"
>
) => {
const { data, ...rest } = useQuery({
queryFn: () => sdk.admin.refundReason.retrieve(id, query),
queryKey: refundReasonsQueryKeys.detail(id),
...options,
})
return { ...data, ...rest }
}
export const useCreateRefundReason = (
query?: HttpTypes.AdminRefundReasonParams,
options?: UseMutationOptions<
HttpTypes.RefundReasonResponse,
FetchError,
HttpTypes.AdminCreateRefundReason
>
) => {
return useMutation({
mutationFn: async (data) => sdk.admin.refundReason.create(data, query),
onSuccess: (data, variables, context) => {
queryClient.invalidateQueries({
queryKey: refundReasonsQueryKeys.lists(),
})
options?.onSuccess?.(data, variables, context)
},
...options,
})
}
export const useUpdateRefundReason = (
id: string,
options?: UseMutationOptions<
HttpTypes.AdminRefundReasonResponse,
FetchError,
HttpTypes.AdminUpdateRefundReason
>
) => {
return useMutation({
mutationFn: async (data) => sdk.admin.refundReason.update(id, data),
onSuccess: (data, variables, context) => {
queryClient.invalidateQueries({
queryKey: refundReasonsQueryKeys.lists(),
})
queryClient.invalidateQueries({
queryKey: refundReasonsQueryKeys.detail(data.refund_reason.id),
})
options?.onSuccess?.(data, variables, context)
},
...options,
})
}
export const useDeleteRefundReasonLazy = (
options?: UseMutationOptions<
HttpTypes.AdminRefundReasonDeleteResponse,
FetchError,
string
>
) => {
return useMutation({
mutationFn: (id: string) => sdk.admin.refundReason.delete(id),
onSuccess: (data, variables, context) => {
queryClient.invalidateQueries({
queryKey: refundReasonsQueryKeys.lists(),
})
queryClient.invalidateQueries({
queryKey: refundReasonsQueryKeys.details(),
})
options?.onSuccess?.(data, variables, context)
},
...options,
})
}
@@ -6,6 +6,7 @@ export * from "./use-order-table-columns"
export * from "./use-product-table-columns"
export * from "./use-product-tag-table-columns"
export * from "./use-product-type-table-columns"
export * from "./use-refund-reason-table-columns"
export * from "./use-region-table-columns"
export * from "./use-return-reason-table-columns"
export * from "./use-tax-rates-table-columns"
@@ -0,0 +1,32 @@
import { HttpTypes } from "@medusajs/types"
import { useMemo } from "react"
import { useTranslation } from "react-i18next"
import { createDataTableColumnHelper } from "@medusajs/ui"
import { DescriptionCell } from "../../../components/table/table-cells/sales-channel/description-cell"
const columnHelper = createDataTableColumnHelper<HttpTypes.AdminRefundReason>()
export const useRefundReasonTableColumns = () => {
const { t } = useTranslation()
return useMemo(
() => [
columnHelper.accessor("label", {
header: () => t("fields.label"),
enableSorting: true,
sortLabel: t("fields.label"),
sortAscLabel: t("filters.sorting.alphabeticallyAsc"),
sortDescLabel: t("filters.sorting.alphabeticallyDesc"),
}),
columnHelper.accessor("description", {
header: () => t("fields.description"),
cell: ({ getValue }) => <DescriptionCell description={getValue()} />,
enableSorting: true,
sortLabel: t("fields.description"),
sortAscLabel: t("filters.sorting.alphabeticallyAsc"),
sortDescLabel: t("filters.sorting.alphabeticallyDesc"),
}),
],
[t]
)
}
@@ -6,6 +6,7 @@ export * from "./use-order-table-query"
export * from "./use-product-table-query"
export * from "./use-product-tag-table-query"
export * from "./use-product-type-table-query"
export * from "./use-refund-reason-table-query"
export * from "./use-region-table-query"
export * from "./use-return-reason-table-query"
export * from "./use-shipping-option-table-query"
@@ -0,0 +1,32 @@
import { HttpTypes } from "@medusajs/types"
import { useQueryParams } from "../../use-query-params"
type UseRefundReasonTableQueryProps = {
prefix?: string
pageSize?: number
}
export const useRefundReasonTableQuery = ({
prefix,
pageSize = 20,
}: UseRefundReasonTableQueryProps) => {
const queryObject = useQueryParams(
["offset", "q", "order", "created_at", "updated_at"],
prefix
)
const { offset, q, order, created_at, updated_at } = queryObject
const searchParams: HttpTypes.AdminRefundReasonListParams = {
limit: pageSize,
offset: offset ? Number(offset) : 0,
order,
created_at: created_at ? JSON.parse(created_at) : undefined,
updated_at: updated_at ? JSON.parse(updated_at) : undefined,
q,
}
return {
searchParams,
raw: queryObject,
}
}