@medusajs/dashboard 2.10.4-preview-20250924060154 → 2.10.4-preview-20250924120212

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/dist/{add-campaign-promotions-BWIP24MA.mjs → add-campaign-promotions-APV4J7Z2.mjs} +4 -4
  2. package/dist/{api-key-management-detail-WGWZQCFC.mjs → api-key-management-detail-P2CXWYQG.mjs} +2 -2
  3. package/dist/{api-key-management-sales-channels-H5TVIHTV.mjs → api-key-management-sales-channels-ESGRJKDT.mjs} +1 -1
  4. package/dist/app.css +0 -3
  5. package/dist/app.js +3533 -3527
  6. package/dist/app.mjs +3 -3
  7. package/dist/{campaign-budget-edit-OXNTSPGE.mjs → campaign-budget-edit-UWGCET5Z.mjs} +1 -1
  8. package/dist/{campaign-configuration-Z5HA2DG3.mjs → campaign-configuration-WWCCFNYQ.mjs} +1 -1
  9. package/dist/{campaign-create-GRKYQY5D.mjs → campaign-create-CQ3XBHSY.mjs} +2 -2
  10. package/dist/{campaign-detail-EJD7LQCW.mjs → campaign-detail-CBO7PBOR.mjs} +4 -4
  11. package/dist/{campaign-edit-3TDW52BO.mjs → campaign-edit-R43GXNET.mjs} +1 -1
  12. package/dist/{campaign-list-IDPRC2MD.mjs → campaign-list-CDO5PRTL.mjs} +1 -1
  13. package/dist/{categories-metadata-JFNWZA5D.mjs → categories-metadata-HNABPXTE.mjs} +1 -1
  14. package/dist/{category-detail-CL3XCV7E.mjs → category-detail-JUKMFR4W.mjs} +1 -1
  15. package/dist/{category-products-UZEG63WY.mjs → category-products-CWLUKUVK.mjs} +1 -1
  16. package/dist/{chunk-U2FXUMKA.mjs → chunk-3S523T5F.mjs} +1 -1
  17. package/dist/{chunk-FUQ27NT5.mjs → chunk-5FAWKUSU.mjs} +1 -1
  18. package/dist/{chunk-OQPVQGSH.mjs → chunk-7GBCLBMX.mjs} +24 -11
  19. package/dist/{chunk-LJDVFJK7.mjs → chunk-AXXGAOQL.mjs} +1 -1
  20. package/dist/{chunk-CAZKNJTG.mjs → chunk-FGF5B6J4.mjs} +112 -112
  21. package/dist/{chunk-4CGHNQP2.mjs → chunk-G3VGLFVH.mjs} +47 -47
  22. package/dist/{chunk-YPSSUJUZ.mjs → chunk-KTBA6OOV.mjs} +7 -3
  23. package/dist/{chunk-2252SSK6.mjs → chunk-NUA3JO5E.mjs} +1 -1
  24. package/dist/{chunk-ZODJNBAV.mjs → chunk-R2G2B47Y.mjs} +1 -0
  25. package/dist/{chunk-V53HAFWH.mjs → chunk-TEMN4ESF.mjs} +1 -1
  26. package/dist/{chunk-6RWF7BPW.mjs → chunk-V6JXTITD.mjs} +1 -1
  27. package/dist/{chunk-WP5CXGGO.mjs → chunk-ZWWM2OU2.mjs} +1 -1
  28. package/dist/{collection-add-products-QTFBLLND.mjs → collection-add-products-E22XLIP7.mjs} +1 -1
  29. package/dist/{collection-detail-ZEAUSZBJ.mjs → collection-detail-LOJ6WZLT.mjs} +1 -1
  30. package/dist/{collection-list-V27JHDAD.mjs → collection-list-KKEZLFLJ.mjs} +1 -1
  31. package/dist/{collection-metadata-JAEMZMU6.mjs → collection-metadata-MEA56JQC.mjs} +1 -1
  32. package/dist/{customer-detail-YBOM6KGC.mjs → customer-detail-Z5TU254N.mjs} +1 -1
  33. package/dist/{customer-group-detail-72VFORGF.mjs → customer-group-detail-VCRUQIYD.mjs} +1 -1
  34. package/dist/{customer-group-list-UTC5ZCJZ.mjs → customer-group-list-MCQ4AUJF.mjs} +2 -2
  35. package/dist/{customers-add-customer-group-ZUCFXW2U.mjs → customers-add-customer-group-X3VHASZ6.mjs} +1 -1
  36. package/dist/{edit-rules-RY7JMYLR.mjs → edit-rules-SVG7IOSY.mjs} +2 -2
  37. package/dist/{inventory-create-F5PSTEN2.mjs → inventory-create-DR5LNYQB.mjs} +1 -1
  38. package/dist/{inventory-detail-BO5E7KXO.mjs → inventory-detail-D4MBCFS2.mjs} +2 -2
  39. package/dist/{inventory-metadata-QGPVSAUI.mjs → inventory-metadata-T22JZF4O.mjs} +1 -1
  40. package/dist/{inventory-stock-VQNXCIOA.mjs → inventory-stock-CPNDJYBD.mjs} +1 -1
  41. package/dist/{location-detail-M4CYDTSY.mjs → location-detail-SG4X4HBT.mjs} +1 -1
  42. package/dist/{location-edit-RNGPJ26L.mjs → location-edit-X6JBEWIF.mjs} +1 -1
  43. package/dist/{location-fulfillment-providers-XVEQZCUD.mjs → location-fulfillment-providers-YNKCL3FV.mjs} +1 -1
  44. package/dist/location-list-VNEYHAKV.mjs +323 -0
  45. package/dist/{location-sales-channels-NSXV65ZM.mjs → location-sales-channels-HVZHZMBY.mjs} +1 -1
  46. package/dist/{location-service-zone-shipping-option-create-I3HAEEFA.mjs → location-service-zone-shipping-option-create-PF7YJSC3.mjs} +1 -1
  47. package/dist/{login-QOENXTB7.mjs → login-23RIW4IY.mjs} +1 -1
  48. package/dist/{order-create-claim-MOBLO4YM.mjs → order-create-claim-LBA6UTTF.mjs} +1 -1
  49. package/dist/{order-create-edit-C75GUZJE.mjs → order-create-edit-7GLQP5CD.mjs} +1 -1
  50. package/dist/{order-create-exchange-RCUALEXO.mjs → order-create-exchange-IXPHBHKP.mjs} +1 -1
  51. package/dist/{order-create-fulfillment-EZTEZ4CF.mjs → order-create-fulfillment-5UJQFERR.mjs} +1 -1
  52. package/dist/{order-create-refund-4FAIESAN.mjs → order-create-refund-QZRNHK2D.mjs} +1 -1
  53. package/dist/{order-create-shipment-PTUJKVWK.mjs → order-create-shipment-TQJHHC7T.mjs} +1 -1
  54. package/dist/{order-detail-6XQLJ5TU.mjs → order-detail-NERZLT7X.mjs} +31 -23
  55. package/dist/{order-edit-billing-address-46CFUZGL.mjs → order-edit-billing-address-BMUX3GJL.mjs} +1 -1
  56. package/dist/{order-edit-email-FOK5GQW2.mjs → order-edit-email-CS4AIJZS.mjs} +1 -1
  57. package/dist/{order-edit-shipping-address-WFN2SVKM.mjs → order-edit-shipping-address-GXSNNDBC.mjs} +1 -1
  58. package/dist/{order-list-OTPVQKU6.mjs → order-list-YWPAJ7FR.mjs} +2 -2
  59. package/dist/{order-metadata-COJNFRPZ.mjs → order-metadata-KWZX64YP.mjs} +1 -1
  60. package/dist/{order-receive-return-P4OPVOPM.mjs → order-receive-return-EXZAUMCI.mjs} +1 -1
  61. package/dist/{order-request-transfer-HRPCEL5L.mjs → order-request-transfer-RLU2TK44.mjs} +1 -1
  62. package/dist/{price-list-create-FJ2FM6GL.mjs → price-list-create-RHSKBROB.mjs} +1 -1
  63. package/dist/{price-list-detail-VNZ3Q426.mjs → price-list-detail-7E2SZNKI.mjs} +1 -1
  64. package/dist/{price-list-prices-add-FMZKGOHD.mjs → price-list-prices-add-RM5FDABU.mjs} +1 -1
  65. package/dist/{product-attributes-5PLACMXK.mjs → product-attributes-K5EMRHFS.mjs} +4 -4
  66. package/dist/{product-create-6FMLIS5X.mjs → product-create-5KQFXFJF.mjs} +5 -5
  67. package/dist/{product-create-variant-KGBSFIKQ.mjs → product-create-variant-37CVX4QI.mjs} +1 -1
  68. package/dist/{product-detail-2BJJMCCO.mjs → product-detail-UM6PIKWQ.mjs} +5 -5
  69. package/dist/{product-edit-N5P7RVNS.mjs → product-edit-QSCZEH74.mjs} +4 -4
  70. package/dist/{product-export-XA5POQKT.mjs → product-export-JNLDMDUS.mjs} +1 -1
  71. package/dist/{product-import-DYTT4YDA.mjs → product-import-CA75XMEH.mjs} +1 -1
  72. package/dist/{product-list-EUQX3NBE.mjs → product-list-XA5SJLXF.mjs} +3 -3
  73. package/dist/{product-media-XJGAON6B.mjs → product-media-36YW62IO.mjs} +2 -2
  74. package/dist/{product-metadata-44VYAXZD.mjs → product-metadata-JKWIAMVB.mjs} +1 -1
  75. package/dist/{product-organization-FB6BVKKL.mjs → product-organization-YL4ZUCC4.mjs} +4 -4
  76. package/dist/{product-sales-channels-QBQDLU7Z.mjs → product-sales-channels-UX7AOJIF.mjs} +1 -1
  77. package/dist/{product-shipping-profile-UZQSV54B.mjs → product-shipping-profile-PEIUF5AK.mjs} +4 -4
  78. package/dist/{product-stock-PX5NAHH6.mjs → product-stock-4XECV73O.mjs} +1 -1
  79. package/dist/{product-tag-create-R4YSSXD6.mjs → product-tag-create-U5DAEOBS.mjs} +1 -1
  80. package/dist/{product-tag-detail-XJEGQD7U.mjs → product-tag-detail-YB44E6JT.mjs} +1 -1
  81. package/dist/{product-tag-edit-7JXF42HY.mjs → product-tag-edit-J3OPHCDJ.mjs} +1 -1
  82. package/dist/{product-tag-list-GTUMQQ6V.mjs → product-tag-list-6TGDOAMD.mjs} +1 -1
  83. package/dist/{product-tag-metadata-5QV3HMXJ.mjs → product-tag-metadata-VAHEGSFJ.mjs} +1 -1
  84. package/dist/{product-type-detail-CN74BB3Y.mjs → product-type-detail-EN3WAIVO.mjs} +1 -1
  85. package/dist/{product-type-metadata-JPFREADV.mjs → product-type-metadata-R3YLZGY5.mjs} +1 -1
  86. package/dist/{product-variant-detail-BSLEUW5J.mjs → product-variant-detail-TYV4BYNG.mjs} +1 -1
  87. package/dist/{product-variant-edit-VOW5633S.mjs → product-variant-edit-YPQDVG5C.mjs} +1 -1
  88. package/dist/{product-variant-metadata-KDSV47PE.mjs → product-variant-metadata-DII5YHIK.mjs} +1 -1
  89. package/dist/{promotion-add-campaign-JXBRCUXL.mjs → promotion-add-campaign-YREHV6TQ.mjs} +7 -20
  90. package/dist/{promotion-create-YPX2R3ZB.mjs → promotion-create-TLW6T5IO.mjs} +4 -4
  91. package/dist/{promotion-detail-VB5GZDCC.mjs → promotion-detail-BYA66IL7.mjs} +113 -64
  92. package/dist/{promotion-edit-details-I5DYHQUM.mjs → promotion-edit-details-A2UUSAZA.mjs} +1 -1
  93. package/dist/{promotion-list-NAUTWXNU.mjs → promotion-list-TOYJAQ4D.mjs} +4 -4
  94. package/dist/{refund-reason-create-CYHPXX2O.mjs → refund-reason-create-D5DJVOXP.mjs} +1 -1
  95. package/dist/{refund-reason-list-VBHGRLJJ.mjs → refund-reason-list-V7UO2NAY.mjs} +10 -5
  96. package/dist/{region-metadata-NXD563F4.mjs → region-metadata-23FQEWQ7.mjs} +1 -1
  97. package/dist/{reservation-detail-64MMXK7D.mjs → reservation-detail-USSX2THW.mjs} +1 -1
  98. package/dist/{reservation-metadata-4GZCEGM7.mjs → reservation-metadata-PKWRLWNT.mjs} +1 -1
  99. package/dist/{reset-password-ZCKXQZNQ.mjs → reset-password-EKZEJXQU.mjs} +1 -1
  100. package/dist/{sales-channel-add-products-EAWW7ADY.mjs → sales-channel-add-products-DKDV65UU.mjs} +1 -1
  101. package/dist/{sales-channel-detail-3F3HFTD2.mjs → sales-channel-detail-JKJLEM4C.mjs} +1 -1
  102. package/dist/{sales-channel-list-R4HT6A7P.mjs → sales-channel-list-FOAVTG7H.mjs} +2 -2
  103. package/dist/{sales-channel-metadata-LAHTTRLQ.mjs → sales-channel-metadata-3RXYX7U2.mjs} +1 -1
  104. package/dist/{shipping-option-type-create-IPKK5MRS.mjs → shipping-option-type-create-ZLYFQFYI.mjs} +1 -1
  105. package/dist/{shipping-option-type-detail-NEQ4RA5F.mjs → shipping-option-type-detail-OMVJZSOI.mjs} +1 -1
  106. package/dist/{shipping-option-type-edit-CC64TWSB.mjs → shipping-option-type-edit-5XHFIDEZ.mjs} +1 -1
  107. package/dist/{shipping-option-type-list-3GTGTBK7.mjs → shipping-option-type-list-SGTTVHWK.mjs} +1 -1
  108. package/dist/{shipping-profile-metadata-EPVLPEEM.mjs → shipping-profile-metadata-3TZDQ27Z.mjs} +1 -1
  109. package/dist/{store-detail-PUOKMK4K.mjs → store-detail-72GMDFY7.mjs} +1 -1
  110. package/dist/{store-metadata-JYIVRRLW.mjs → store-metadata-TXSRTL6B.mjs} +1 -1
  111. package/dist/{tax-region-create-2GDG36NQ.mjs → tax-region-create-U6XXHBMJ.mjs} +2 -2
  112. package/dist/{tax-region-detail-MQKBEBOZ.mjs → tax-region-detail-V4E63XUI.mjs} +1 -1
  113. package/dist/{tax-region-edit-2H5ACSFG.mjs → tax-region-edit-2DQPKIJG.mjs} +1 -1
  114. package/dist/{tax-region-province-detail-HNK2ZJWL.mjs → tax-region-province-detail-P6LPVSQJ.mjs} +1 -1
  115. package/dist/{tax-region-tax-override-create-XZJ3EIFJ.mjs → tax-region-tax-override-create-BPZKBPN6.mjs} +1 -1
  116. package/dist/{tax-region-tax-override-edit-QHQHFI2Y.mjs → tax-region-tax-override-edit-O7LUBRQN.mjs} +1 -1
  117. package/dist/{user-list-TPBPZ7KJ.mjs → user-list-G4H2RSDX.mjs} +1 -1
  118. package/dist/{user-metadata-F6KRFYDW.mjs → user-metadata-TM3FFLIR.mjs} +1 -1
  119. package/dist/{workflow-execution-detail-JRJZATNU.mjs → workflow-execution-detail-3IBZZVRE.mjs} +1 -1
  120. package/package.json +9 -9
  121. package/src/components/data-table/data-table.tsx +64 -46
  122. package/src/hooks/api/campaigns.tsx +1 -0
  123. package/src/i18n/translations/$schema.json +19 -2
  124. package/src/i18n/translations/en.json +7 -3
  125. package/src/routes/locations/location-edit/components/edit-location-form/edit-location-form.tsx +1 -1
  126. package/src/routes/locations/location-list/index.ts +0 -1
  127. package/src/routes/locations/location-list/location-list.tsx +52 -14
  128. package/src/routes/locations/location-list/use-location-list-table-columns.tsx +185 -0
  129. package/src/routes/locations/location-list/use-location-list-table-query.tsx +22 -0
  130. package/src/routes/orders/order-detail/components/order-activity-section/order-timeline.tsx +13 -5
  131. package/src/routes/promotions/promotion-add-campaign/components/add-campaign-promotion-form/add-campaign-promotion-form.tsx +45 -52
  132. package/src/routes/promotions/promotion-add-campaign/promotion-add-campaign.tsx +4 -21
  133. package/src/routes/refund-reasons/refund-reason-list/components/refund-reason-list-table/refund-reason-list-table.tsx +12 -4
  134. package/dist/chunk-BKJC5BGQ.mjs +0 -53
  135. package/dist/location-list-NKIOBHG4.mjs +0 -298
  136. package/src/routes/locations/location-list/components/location-list-header/index.ts +0 -1
  137. package/src/routes/locations/location-list/components/location-list-header/location-list-header.tsx +0 -21
  138. package/src/routes/locations/location-list/loader.ts +0 -36
@@ -0,0 +1,185 @@
1
+ import { HttpTypes } from "@medusajs/types"
2
+ import { PencilSquare, Trash } from "@medusajs/icons"
3
+ import {
4
+ createDataTableColumnHelper,
5
+ StatusBadge,
6
+ toast,
7
+ usePrompt,
8
+ } from "@medusajs/ui"
9
+ import { useTranslation } from "react-i18next"
10
+ import { useMemo } from "react"
11
+ import { useNavigate } from "react-router-dom"
12
+ import { FetchError } from "@medusajs/js-sdk"
13
+
14
+ import { PlaceholderCell } from "../../../components/table/table-cells/common/placeholder-cell"
15
+ import { getFormattedAddress } from "../../../lib/addresses"
16
+ import { FulfillmentSetType } from "../common/constants"
17
+ import { queryClient } from "../../../lib/query-client"
18
+ import { stockLocationsQueryKeys } from "../../../hooks/api/stock-locations"
19
+ import { ListSummary } from "../../../components/common/list-summary"
20
+ import { sdk } from "../../../lib/client"
21
+
22
+ const columnHelper = createDataTableColumnHelper<HttpTypes.AdminStockLocation>()
23
+
24
+ export const useLocationListTableColumns = () => {
25
+ const { t } = useTranslation()
26
+ const navigate = useNavigate()
27
+ const prompt = usePrompt()
28
+
29
+ const handleDelete = async (location: HttpTypes.AdminStockLocation) => {
30
+ const result = await prompt({
31
+ title: t("general.areYouSure"),
32
+ description: t("stockLocations.delete.confirmation", {
33
+ name: location.name,
34
+ }),
35
+ confirmText: t("actions.remove"),
36
+ cancelText: t("actions.cancel"),
37
+ })
38
+
39
+ if (!result) {
40
+ return
41
+ }
42
+
43
+ try {
44
+ await sdk.admin.stockLocation.delete(location.id)
45
+ queryClient.invalidateQueries({
46
+ queryKey: stockLocationsQueryKeys.lists(),
47
+ })
48
+
49
+ queryClient.invalidateQueries({
50
+ queryKey: stockLocationsQueryKeys.detail(location.id),
51
+ })
52
+
53
+ toast.success(
54
+ t("stockLocations.delete.successToast", {
55
+ name: location.name,
56
+ })
57
+ )
58
+ } catch (e) {
59
+ toast.error((e as FetchError).message)
60
+ }
61
+ }
62
+
63
+ return useMemo(
64
+ () => [
65
+ columnHelper.accessor("name", {
66
+ header: t("fields.name"),
67
+ cell: ({ getValue }) => {
68
+ const name = getValue()
69
+ if (!name) {
70
+ return <PlaceholderCell />
71
+ }
72
+
73
+ return (
74
+ <span className="text-ui-fg-subtle text-small truncate">
75
+ {name}
76
+ </span>
77
+ )
78
+ },
79
+ }),
80
+ columnHelper.accessor("address", {
81
+ header: t("fields.address"),
82
+ cell: ({ getValue, row }) => {
83
+ const address = getValue()
84
+ const location = row.original
85
+
86
+ if (!address) {
87
+ return <PlaceholderCell />
88
+ }
89
+
90
+ return (
91
+ <div className="flex flex-col">
92
+ <span className="text-ui-fg-subtle text-small truncate">
93
+ {getFormattedAddress({
94
+ address: location.address as HttpTypes.AdminOrderAddress,
95
+ }).join(", ")}
96
+ </span>
97
+ </div>
98
+ )
99
+ },
100
+ }),
101
+ columnHelper.accessor("fulfillment_sets", {
102
+ id: "shipping_fulfillment",
103
+ header: t("stockLocations.fulfillmentSets.shipping.header"),
104
+ cell: ({ getValue }) => {
105
+ const fulfillmentSets = getValue()
106
+ const shippingSet = fulfillmentSets?.find(
107
+ (f) => f.type === FulfillmentSetType.Shipping
108
+ )
109
+ const fulfillmentSetExists = !!shippingSet
110
+
111
+ return (
112
+ <StatusBadge color={fulfillmentSetExists ? "green" : "grey"}>
113
+ {t(
114
+ fulfillmentSetExists ? "statuses.enabled" : "statuses.disabled"
115
+ )}
116
+ </StatusBadge>
117
+ )
118
+ },
119
+ }),
120
+ columnHelper.accessor("fulfillment_sets", {
121
+ id: "pickup_fulfillment",
122
+ header: t("stockLocations.fulfillmentSets.pickup.header"),
123
+ cell: ({ getValue }) => {
124
+ const fulfillmentSets = getValue()
125
+ const pickupSet = fulfillmentSets?.find(
126
+ (f) => f.type === FulfillmentSetType.Pickup
127
+ )
128
+ const fulfillmentSetExists = !!pickupSet
129
+
130
+ return (
131
+ <StatusBadge color={fulfillmentSetExists ? "green" : "grey"}>
132
+ {t(
133
+ fulfillmentSetExists ? "statuses.enabled" : "statuses.disabled"
134
+ )}
135
+ </StatusBadge>
136
+ )
137
+ },
138
+ }),
139
+ columnHelper.accessor("sales_channels", {
140
+ header: t("stockLocations.salesChannels.label"),
141
+ cell: ({ getValue }) => {
142
+ const salesChannels = getValue()
143
+
144
+ if (!salesChannels?.length) {
145
+ return <PlaceholderCell />
146
+ }
147
+
148
+ return (
149
+ <div className="flex items-center">
150
+ <ListSummary
151
+ inline
152
+ n={1}
153
+ list={salesChannels.map((s) => s.name)}
154
+ />
155
+ </div>
156
+ )
157
+ },
158
+ }),
159
+ columnHelper.action({
160
+ actions: (ctx) => {
161
+ const location = ctx.row.original
162
+ return [
163
+ [
164
+ {
165
+ icon: <PencilSquare />,
166
+ label: t("actions.edit"),
167
+ onClick: () => {
168
+ navigate(`/settings/locations/${location.id}/edit`)
169
+ },
170
+ },
171
+ ],
172
+ [
173
+ {
174
+ icon: <Trash />,
175
+ label: t("actions.delete"),
176
+ onClick: () => handleDelete(location),
177
+ },
178
+ ],
179
+ ]
180
+ },
181
+ }),
182
+ ],
183
+ []
184
+ )
185
+ }
@@ -0,0 +1,22 @@
1
+ import { HttpTypes } from "@medusajs/types"
2
+ import { useQueryParams } from "../../../hooks/use-query-params"
3
+
4
+ export const useLocationListTableQuery = ({
5
+ pageSize = 20,
6
+ prefix,
7
+ }: {
8
+ pageSize?: number
9
+ prefix?: string
10
+ }) => {
11
+ const queryObject = useQueryParams(["order", "offset", "q"], prefix)
12
+
13
+ const { offset, ...rest } = queryObject
14
+
15
+ const searchParams: HttpTypes.AdminStockLocationListParams = {
16
+ limit: pageSize,
17
+ offset: offset ? Number(offset) : 0,
18
+ ...rest,
19
+ }
20
+
21
+ return searchParams
22
+ }
@@ -1,4 +1,4 @@
1
- import { Button, Text, Tooltip, clx, usePrompt } from "@medusajs/ui"
1
+ import { Button, Text, Tooltip, clx, toast, usePrompt } from "@medusajs/ui"
2
2
  import { Collapsible as RadixCollapsible } from "radix-ui"
3
3
 
4
4
  import { PropsWithChildren, ReactNode, useMemo, useState } from "react"
@@ -785,7 +785,9 @@ const ReturnBody = ({
785
785
  return
786
786
  }
787
787
 
788
- await cancelReturnRequest()
788
+ await cancelReturnRequest().catch((error) => {
789
+ toast.error(error.message)
790
+ })
789
791
  }
790
792
 
791
793
  const numberOfItems = orderReturn.items.reduce((acc, item) => {
@@ -842,7 +844,9 @@ const ClaimBody = ({
842
844
  return
843
845
  }
844
846
 
845
- await cancelClaim()
847
+ await cancelClaim().catch((error) => {
848
+ toast.error(error.message)
849
+ })
846
850
  }
847
851
 
848
852
  const outboundItems = (claim.additional_items || []).reduce(
@@ -916,7 +920,9 @@ const ExchangeBody = ({
916
920
  return
917
921
  }
918
922
 
919
- await cancelExchange()
923
+ await cancelExchange().catch((error) => {
924
+ toast.error(error.message)
925
+ })
920
926
  }
921
927
 
922
928
  const outboundItems = (exchange.additional_items || []).reduce(
@@ -1015,7 +1021,9 @@ const TransferOrderRequestBody = ({
1015
1021
  return
1016
1022
  }
1017
1023
 
1018
- await cancelTransfer()
1024
+ await cancelTransfer().catch((error) => {
1025
+ toast.error(error.message)
1026
+ })
1019
1027
  }
1020
1028
 
1021
1029
  /**
@@ -1,9 +1,9 @@
1
1
  import { zodResolver } from "@hookform/resolvers/zod"
2
2
  import { AdminCampaign, AdminPromotion } from "@medusajs/types"
3
- import { Button, RadioGroup, Select, Text, toast } from "@medusajs/ui"
3
+ import { Button, RadioGroup, toast } from "@medusajs/ui"
4
4
  import { useEffect } from "react"
5
5
  import { useForm, useWatch } from "react-hook-form"
6
- import { Trans, useTranslation } from "react-i18next"
6
+ import { useTranslation } from "react-i18next"
7
7
  import * as zod from "zod"
8
8
  import { Form } from "../../../../../components/common/form"
9
9
  import { RouteDrawer, useRouteModal } from "../../../../../components/modals"
@@ -11,11 +11,14 @@ import { KeyboundForm } from "../../../../../components/utilities/keybound-form"
11
11
  import { useUpdatePromotion } from "../../../../../hooks/api/promotions"
12
12
  import { CreateCampaignFormFields } from "../../../../campaigns/common/components/create-campaign-form-fields"
13
13
  import { CampaignDetails } from "./campaign-details"
14
+ import { sdk } from "../../../../../lib/client"
15
+ import { useComboboxData } from "../../../../../hooks/use-combobox-data"
16
+ import { Combobox } from "../../../../../components/inputs/combobox"
17
+ import { useCampaign } from "../../../../../hooks/api/campaigns"
14
18
  import { useDocumentDirection } from "../../../../../hooks/use-document-direction"
15
19
 
16
20
  type EditPromotionFormProps = {
17
21
  promotion: AdminPromotion
18
- campaigns: AdminCampaign[]
19
22
  }
20
23
 
21
24
  const EditPromotionSchema = zod.object({
@@ -25,14 +28,16 @@ const EditPromotionSchema = zod.object({
25
28
 
26
29
  export const AddCampaignPromotionFields = ({
27
30
  form,
28
- campaigns,
29
31
  withNewCampaign = true,
32
+ promotionCurrencyCode,
30
33
  }: {
31
34
  form: any
32
- campaigns: AdminCampaign[]
33
35
  withNewCampaign?: boolean
36
+ promotionCurrencyCode?: string
34
37
  }) => {
35
38
  const { t } = useTranslation()
39
+ const direction = useDocumentDirection()
40
+
36
41
  const watchCampaignId = useWatch({
37
42
  control: form.control,
38
43
  name: "campaign_id",
@@ -43,8 +48,31 @@ export const AddCampaignPromotionFields = ({
43
48
  name: "campaign_choice",
44
49
  })
45
50
 
46
- const selectedCampaign = campaigns.find((c) => c.id === watchCampaignId)
47
- const direction = useDocumentDirection()
51
+ const campaignsCombobox = useComboboxData({
52
+ queryFn: (params) =>
53
+ sdk.admin.campaign.list({
54
+ ...params,
55
+ }),
56
+ queryKey: ["campaigns"],
57
+ getOptions: (data) =>
58
+ data.campaigns.map((campaign) => ({
59
+ label: campaign.name.toUpperCase(),
60
+ value: campaign.id,
61
+ disabled:
62
+ campaign.budget?.currency_code &&
63
+ campaign.budget?.currency_code?.toLowerCase() !==
64
+ promotionCurrencyCode?.toLowerCase(), // also cannot add promotion which doesn't have currency defined to a campaign with a currency amount budget
65
+ })),
66
+ })
67
+
68
+ const { campaign: selectedCampaign } = useCampaign(
69
+ watchCampaignId as string,
70
+ undefined,
71
+ {
72
+ enabled: !!watchCampaignId,
73
+ }
74
+ )
75
+
48
76
  return (
49
77
  <div className="flex flex-col gap-y-8">
50
78
  <Form.Field
@@ -99,58 +127,24 @@ export const AddCampaignPromotionFields = ({
99
127
  <Form.Field
100
128
  control={form.control}
101
129
  name="campaign_id"
102
- render={({ field: { onChange, ref, ...field } }) => {
130
+ render={({ field: { onChange, ...field } }) => {
103
131
  return (
104
132
  <Form.Item>
105
- <Form.Label>
133
+ <Form.Label tooltip={t("campaigns.fields.campaign_id.hint")}>
106
134
  {t("promotions.form.campaign.existing.title")}
107
135
  </Form.Label>
108
136
 
109
137
  <Form.Control>
110
- <Select
138
+ <Combobox
111
139
  dir={direction}
112
- onValueChange={onChange}
140
+ options={campaignsCombobox.options}
141
+ searchValue={campaignsCombobox.searchValue}
142
+ onSearchValueChange={campaignsCombobox.onSearchValueChange}
143
+ onChange={onChange}
113
144
  {...field}
114
- >
115
- <Select.Trigger ref={ref}>
116
- <Select.Value />
117
- </Select.Trigger>
118
-
119
- <Select.Content>
120
- {!campaigns.length && (
121
- <div className="flex h-[120px] flex-col items-center justify-center gap-2 p-2">
122
- <span className="txt-small text-ui-fg-subtle font-medium">
123
- {t(
124
- "promotions.form.campaign.existing.placeholder.title"
125
- )}
126
- </span>
127
- <span className="txt-small text-ui-fg-muted">
128
- {t(
129
- "promotions.form.campaign.existing.placeholder.desc"
130
- )}
131
- </span>
132
- </div>
133
- )}
134
- {campaigns.map((c) => (
135
- <Select.Item key={c.id} value={c.id}>
136
- {c.name?.toUpperCase()}
137
- </Select.Item>
138
- ))}
139
- </Select.Content>
140
- </Select>
145
+ ></Combobox>
141
146
  </Form.Control>
142
147
 
143
- <Text
144
- size="small"
145
- leading="compact"
146
- className="text-ui-fg-subtle"
147
- >
148
- <Trans
149
- t={t}
150
- i18nKey="campaigns.fields.campaign_id.hint"
151
- components={[<br key="break" />]}
152
- />
153
- </Text>
154
148
  <Form.ErrorMessage />
155
149
  </Form.Item>
156
150
  )
@@ -162,14 +156,13 @@ export const AddCampaignPromotionFields = ({
162
156
  <CreateCampaignFormFields form={form} fieldScope="campaign." />
163
157
  )}
164
158
 
165
- <CampaignDetails campaign={selectedCampaign} />
159
+ <CampaignDetails campaign={selectedCampaign as AdminCampaign} />
166
160
  </div>
167
161
  )
168
162
  }
169
163
 
170
164
  export const AddCampaignPromotionForm = ({
171
165
  promotion,
172
- campaigns,
173
166
  }: EditPromotionFormProps) => {
174
167
  const { t } = useTranslation()
175
168
  const { handleSuccess } = useRouteModal()
@@ -227,8 +220,8 @@ export const AddCampaignPromotionForm = ({
227
220
  <RouteDrawer.Body className="size-full overflow-auto">
228
221
  <AddCampaignPromotionFields
229
222
  form={form}
230
- campaigns={campaigns}
231
223
  withNewCampaign={false}
224
+ promotionCurrencyCode={promotion.application_method?.currency_code}
232
225
  />
233
226
  </RouteDrawer.Body>
234
227
 
@@ -3,7 +3,6 @@ import { useTranslation } from "react-i18next"
3
3
  import { useParams } from "react-router-dom"
4
4
 
5
5
  import { RouteDrawer } from "../../../components/modals"
6
- import { useCampaigns } from "../../../hooks/api/campaigns"
7
6
  import { usePromotion } from "../../../hooks/api/promotions"
8
7
  import { AddCampaignPromotionForm } from "./components/add-campaign-promotion-form"
9
8
 
@@ -12,24 +11,8 @@ export const PromotionAddCampaign = () => {
12
11
  const { t } = useTranslation()
13
12
  const { promotion, isPending, isError, error } = usePromotion(id!)
14
13
 
15
- let campaignQuery = {}
16
-
17
- if (promotion?.application_method?.currency_code) {
18
- campaignQuery = {
19
- budget: {
20
- currency_code: promotion?.application_method?.currency_code,
21
- },
22
- }
23
- }
24
-
25
- const {
26
- campaigns,
27
- isPending: areCampaignsLoading,
28
- isError: isCampaignError,
29
- error: campaignError,
30
- } = useCampaigns(campaignQuery)
31
- if (isError || isCampaignError) {
32
- throw error || campaignError
14
+ if (isError) {
15
+ throw error
33
16
  }
34
17
 
35
18
  return (
@@ -38,8 +21,8 @@ export const PromotionAddCampaign = () => {
38
21
  <Heading>{t("promotions.campaign.edit.header")}</Heading>
39
22
  </RouteDrawer.Header>
40
23
 
41
- {!isPending && !areCampaignsLoading && promotion && campaigns && (
42
- <AddCampaignPromotionForm promotion={promotion} campaigns={campaigns} />
24
+ {!isPending && promotion && (
25
+ <AddCampaignPromotionForm promotion={promotion} />
43
26
  )}
44
27
  </RouteDrawer>
45
28
  )
@@ -1,12 +1,20 @@
1
1
  import { PencilSquare, Trash } from "@medusajs/icons"
2
2
  import { HttpTypes } from "@medusajs/types"
3
- import { Container, createDataTableColumnHelper, toast, usePrompt, } from "@medusajs/ui"
3
+ import {
4
+ Container,
5
+ createDataTableColumnHelper,
6
+ toast,
7
+ usePrompt,
8
+ } from "@medusajs/ui"
4
9
  import { keepPreviousData } from "@tanstack/react-query"
5
10
  import { useCallback, useMemo } from "react"
6
11
  import { useTranslation } from "react-i18next"
7
12
  import { useNavigate } from "react-router-dom"
8
13
  import { DataTable } from "../../../../../components/data-table"
9
- import { useDeleteRefundReasonLazy, useRefundReasons, } from "../../../../../hooks/api"
14
+ import {
15
+ useDeleteRefundReasonLazy,
16
+ useRefundReasons,
17
+ } from "../../../../../hooks/api"
10
18
  import { useRefundReasonTableColumns } from "../../../../../hooks/table/columns"
11
19
  import { useRefundReasonTableQuery } from "../../../../../hooks/table/query"
12
20
 
@@ -18,7 +26,7 @@ export const RefundReasonListTable = () => {
18
26
  pageSize: PAGE_SIZE,
19
27
  })
20
28
 
21
- const { refund_reasons, count, isPending, isError, error } = useRefundReasons(
29
+ const { refund_reasons, count, isLoading, isError, error } = useRefundReasons(
22
30
  searchParams,
23
31
  {
24
32
  placeholderData: keepPreviousData,
@@ -56,7 +64,7 @@ export const RefundReasonListTable = () => {
56
64
  to: "create",
57
65
  },
58
66
  ]}
59
- isLoading={isPending}
67
+ isLoading={isLoading}
60
68
  enableSearch={true}
61
69
  />
62
70
  </Container>
@@ -1,53 +0,0 @@
1
- // src/components/common/badge-list-summary/badge-list-summary.tsx
2
- import { Badge, Tooltip, clx } from "@medusajs/ui";
3
- import { useTranslation } from "react-i18next";
4
- import { jsx, jsxs } from "react/jsx-runtime";
5
- var BadgeListSummary = ({
6
- list,
7
- className,
8
- inline,
9
- rounded = false,
10
- n = 2
11
- }) => {
12
- const { t } = useTranslation();
13
- const title = t("general.plusCount", {
14
- count: list.length - n
15
- });
16
- return /* @__PURE__ */ jsxs(
17
- "div",
18
- {
19
- className: clx(
20
- "text-ui-fg-subtle txt-compact-small gap-x-2 overflow-hidden",
21
- {
22
- "inline-flex": inline,
23
- flex: !inline
24
- },
25
- className
26
- ),
27
- children: [
28
- list.slice(0, n).map((item) => {
29
- return /* @__PURE__ */ jsx(Badge, { rounded: rounded ? "full" : "base", size: "2xsmall", children: item }, item);
30
- }),
31
- list.length > n && /* @__PURE__ */ jsx("div", { className: "whitespace-nowrap", children: /* @__PURE__ */ jsx(
32
- Tooltip,
33
- {
34
- content: /* @__PURE__ */ jsx("ul", { children: list.slice(n).map((c) => /* @__PURE__ */ jsx("li", { children: c }, c)) }),
35
- children: /* @__PURE__ */ jsx(
36
- Badge,
37
- {
38
- rounded: rounded ? "full" : "base",
39
- size: "2xsmall",
40
- className: "cursor-default whitespace-nowrap",
41
- children: title
42
- }
43
- )
44
- }
45
- ) })
46
- ]
47
- }
48
- );
49
- };
50
-
51
- export {
52
- BadgeListSummary
53
- };