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

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 (168) hide show
  1. package/dist/{add-campaign-promotions-APV4J7Z2.mjs → add-campaign-promotions-3BB3BLFD.mjs} +3 -3
  2. package/dist/{adjust-inventory-WBEBMJN7.mjs → adjust-inventory-OIJTAKHP.mjs} +1 -1
  3. package/dist/{api-key-management-create-VXPZX2Q5.mjs → api-key-management-create-XDQHUNWK.mjs} +3 -3
  4. package/dist/{api-key-management-detail-P2CXWYQG.mjs → api-key-management-detail-MM673US3.mjs} +10 -10
  5. package/dist/{api-key-management-edit-7CGMSHAY.mjs → api-key-management-edit-2SUSKI7T.mjs} +3 -3
  6. package/dist/{api-key-management-list-QAMBWB7T.mjs → api-key-management-list-C2WM4PHC.mjs} +3 -3
  7. package/dist/{api-key-management-sales-channels-ESGRJKDT.mjs → api-key-management-sales-channels-MVHVMPF6.mjs} +3 -3
  8. package/dist/app.js +4371 -4313
  9. package/dist/app.mjs +13 -12
  10. package/dist/{campaign-detail-CBO7PBOR.mjs → campaign-detail-G2VM7CRL.mjs} +13 -13
  11. package/dist/{categories-metadata-HNABPXTE.mjs → categories-metadata-M4PAATNV.mjs} +10 -10
  12. package/dist/{category-create-DJHTY4QX.mjs → category-create-GMFWRFT7.mjs} +2 -2
  13. package/dist/{category-detail-JUKMFR4W.mjs → category-detail-MTLPW4MR.mjs} +12 -12
  14. package/dist/{category-edit-JQQX7IZZ.mjs → category-edit-HCHER73V.mjs} +2 -2
  15. package/dist/{category-list-FOCNQKPH.mjs → category-list-IXW2NWWJ.mjs} +3 -3
  16. package/dist/{category-organize-BW3YOPUS.mjs → category-organize-LRQKM4LA.mjs} +2 -2
  17. package/dist/{category-products-CWLUKUVK.mjs → category-products-DGWKONYE.mjs} +11 -11
  18. package/dist/{chunk-2HKRIUW4.mjs → chunk-2PGNKUXS.mjs} +1 -1
  19. package/dist/{chunk-X4X5KUGQ.mjs → chunk-4QUHWHBD.mjs} +3 -0
  20. package/dist/{chunk-RFP4O5GO.mjs → chunk-A4GWVZB4.mjs} +2 -2
  21. package/dist/{chunk-2YP2ZNKR.mjs → chunk-AN5IILM2.mjs} +1 -1
  22. package/dist/{chunk-FGF5B6J4.mjs → chunk-DBN6UH2G.mjs} +477 -586
  23. package/dist/{chunk-KTBA6OOV.mjs → chunk-DKOCYXB5.mjs} +1 -0
  24. package/dist/{chunk-ZCZL3STK.mjs → chunk-EA5GGT2Q.mjs} +1 -1
  25. package/dist/{chunk-BSBCIU6C.mjs → chunk-EILZIUOP.mjs} +1 -1
  26. package/dist/{chunk-BFNH5UWD.mjs → chunk-EYTETK3W.mjs} +1 -1
  27. package/dist/{chunk-3S523T5F.mjs → chunk-G43AJZ7B.mjs} +1 -1
  28. package/dist/{chunk-CU5EFQSB.mjs → chunk-HOERC634.mjs} +1 -1
  29. package/dist/{chunk-YPDTZXV6.mjs → chunk-I2QEZTVU.mjs} +2 -2
  30. package/dist/{chunk-NUA3JO5E.mjs → chunk-IP2QPPWC.mjs} +1 -1
  31. package/dist/{chunk-YI4CZGTU.mjs → chunk-ITJEYJNB.mjs} +1 -1
  32. package/dist/{chunk-BM5ZIV5V.mjs → chunk-IXMPYDY2.mjs} +1 -1
  33. package/dist/{chunk-IYDBZI47.mjs → chunk-K2HM7KXJ.mjs} +1 -1
  34. package/dist/{chunk-OHSRRFGN.mjs → chunk-LKVQ5YC6.mjs} +1 -1
  35. package/dist/{chunk-QGCKTVQX.mjs → chunk-LMRZMI7O.mjs} +1 -1
  36. package/dist/{chunk-5M5ZVAWU.mjs → chunk-MSOFJHH3.mjs} +2 -2
  37. package/dist/{chunk-ZWWM2OU2.mjs → chunk-NFQXNOP7.mjs} +1 -1
  38. package/dist/{chunk-NCR5UWRI.mjs → chunk-NY6I2FYO.mjs} +1 -1
  39. package/dist/{chunk-HUX22ZHT.mjs → chunk-RF75BZNF.mjs} +3 -3
  40. package/dist/{chunk-4RG7UJCT.mjs → chunk-RGP3IXX4.mjs} +1 -1
  41. package/dist/{chunk-TOS3CYMH.mjs → chunk-SQFZWNYA.mjs} +1 -1
  42. package/dist/{chunk-KSRI5LOF.mjs → chunk-U25RCIX2.mjs} +2 -2
  43. package/dist/{chunk-TEMN4ESF.mjs → chunk-U4R5MBF2.mjs} +1 -1
  44. package/dist/chunk-VLOA5XAC.mjs +113 -0
  45. package/dist/{chunk-4Q4LIFFO.mjs → chunk-XP3BY6G6.mjs} +1 -1
  46. package/dist/{chunk-6IZUCU7K.mjs → chunk-YSFTQA6Y.mjs} +2 -2
  47. package/dist/{chunk-RMEITCLS.mjs → chunk-ZSDEVTFT.mjs} +1 -1
  48. package/dist/{collection-add-products-E22XLIP7.mjs → collection-add-products-KEB3ESAK.mjs} +11 -11
  49. package/dist/{collection-create-75ZI5NDG.mjs → collection-create-PTOF33H2.mjs} +2 -2
  50. package/dist/{collection-detail-LOJ6WZLT.mjs → collection-detail-V24IDEZQ.mjs} +11 -11
  51. package/dist/{collection-edit-RD6BDDDI.mjs → collection-edit-WM57WXJ2.mjs} +2 -2
  52. package/dist/{collection-list-KKEZLFLJ.mjs → collection-list-GD2IJYOP.mjs} +12 -12
  53. package/dist/{collection-metadata-MEA56JQC.mjs → collection-metadata-Z2JMXTHW.mjs} +10 -10
  54. package/dist/{customer-detail-Z5TU254N.mjs → customer-detail-E7LPLLML.mjs} +11 -11
  55. package/dist/{customer-group-detail-VCRUQIYD.mjs → customer-group-detail-5ZWHOJOD.mjs} +10 -10
  56. package/dist/{customer-group-list-MCQ4AUJF.mjs → customer-group-list-N22GDJVL.mjs} +10 -10
  57. package/dist/{customers-add-customer-group-X3VHASZ6.mjs → customers-add-customer-group-LFEUVS5G.mjs} +10 -10
  58. package/dist/{edit-inventory-item-ZPE4MMC4.mjs → edit-inventory-item-UV2Z7SYL.mjs} +1 -1
  59. package/dist/{edit-inventory-item-attributes-BMPRVCPN.mjs → edit-inventory-item-attributes-BRC3KBYT.mjs} +1 -1
  60. package/dist/{edit-reservation-QQTYP22N.mjs → edit-reservation-NYGQBFBO.mjs} +2 -2
  61. package/dist/{edit-rules-SVG7IOSY.mjs → edit-rules-BCGRJ4FJ.mjs} +10 -10
  62. package/dist/{inventory-create-DR5LNYQB.mjs → inventory-create-OPYAZF3M.mjs} +10 -10
  63. package/dist/{inventory-detail-D4MBCFS2.mjs → inventory-detail-PAVP7J2W.mjs} +16 -10
  64. package/dist/{inventory-list-HUYCKI2I.mjs → inventory-list-J5VZGQ2M.mjs} +1 -1
  65. package/dist/{inventory-metadata-T22JZF4O.mjs → inventory-metadata-PMQLZCHW.mjs} +10 -10
  66. package/dist/{inventory-stock-CPNDJYBD.mjs → inventory-stock-7QXMAX45.mjs} +10 -10
  67. package/dist/{location-detail-SG4X4HBT.mjs → location-detail-IXHZ7DZS.mjs} +10 -10
  68. package/dist/{location-fulfillment-providers-YNKCL3FV.mjs → location-fulfillment-providers-3KPC4HQT.mjs} +12 -12
  69. package/dist/{location-sales-channels-HVZHZMBY.mjs → location-sales-channels-66ZE3ZMI.mjs} +2 -2
  70. package/dist/{location-service-zone-shipping-option-create-PF7YJSC3.mjs → location-service-zone-shipping-option-create-PVQ66CXW.mjs} +10 -10
  71. package/dist/{login-23RIW4IY.mjs → login-DVYOEF5F.mjs} +10 -10
  72. package/dist/manage-locations-RPHTPGRE.mjs +247 -0
  73. package/dist/{order-allocate-items-NO5SVLS6.mjs → order-allocate-items-2RYXQRVK.mjs} +3 -3
  74. package/dist/{order-create-claim-LBA6UTTF.mjs → order-create-claim-FK4LIPAE.mjs} +12 -12
  75. package/dist/{order-create-edit-7GLQP5CD.mjs → order-create-edit-VGIWYKBB.mjs} +11 -11
  76. package/dist/{order-create-exchange-IXPHBHKP.mjs → order-create-exchange-BMRCMN5G.mjs} +12 -12
  77. package/dist/{order-create-fulfillment-5UJQFERR.mjs → order-create-fulfillment-NLGPRK4J.mjs} +10 -10
  78. package/dist/{order-create-refund-QZRNHK2D.mjs → order-create-refund-TEMK6IEQ.mjs} +45 -14
  79. package/dist/{order-create-return-AV4BEJDN.mjs → order-create-return-6FHAU3OZ.mjs} +4 -4
  80. package/dist/{order-create-shipment-TQJHHC7T.mjs → order-create-shipment-WCEZXWM6.mjs} +10 -10
  81. package/dist/{order-detail-NERZLT7X.mjs → order-detail-BYAGOF5M.mjs} +14 -14
  82. package/dist/{order-edit-billing-address-BMUX3GJL.mjs → order-edit-billing-address-MWF3L6GK.mjs} +10 -10
  83. package/dist/{order-edit-email-CS4AIJZS.mjs → order-edit-email-UDJOGYPP.mjs} +10 -10
  84. package/dist/{order-edit-shipping-address-GXSNNDBC.mjs → order-edit-shipping-address-O46U65WM.mjs} +10 -10
  85. package/dist/{order-list-YWPAJ7FR.mjs → order-list-VDUUHTSU.mjs} +4 -4
  86. package/dist/{order-metadata-KWZX64YP.mjs → order-metadata-SHCFZWCA.mjs} +10 -10
  87. package/dist/{order-receive-return-EXZAUMCI.mjs → order-receive-return-MC4DIRK3.mjs} +11 -11
  88. package/dist/{order-request-transfer-RLU2TK44.mjs → order-request-transfer-MELQKMC4.mjs} +10 -10
  89. package/dist/{price-list-configuration-HF3DARKG.mjs → price-list-configuration-VACKCKJF.mjs} +2 -2
  90. package/dist/{price-list-create-RHSKBROB.mjs → price-list-create-TZUDGP2J.mjs} +11 -11
  91. package/dist/{price-list-detail-7E2SZNKI.mjs → price-list-detail-DX74DH6G.mjs} +12 -12
  92. package/dist/{price-list-edit-COHKW6UK.mjs → price-list-edit-G73ZIU2Y.mjs} +2 -2
  93. package/dist/{price-list-list-55WD2WAY.mjs → price-list-list-QYZSJNF5.mjs} +3 -3
  94. package/dist/{price-list-prices-add-RM5FDABU.mjs → price-list-prices-add-IHMS7HIH.mjs} +11 -11
  95. package/dist/{price-list-prices-edit-SUZNOKK2.mjs → price-list-prices-edit-R53ITSDD.mjs} +2 -2
  96. package/dist/{product-attributes-K5EMRHFS.mjs → product-attributes-RMPKQ5KE.mjs} +14 -13
  97. package/dist/{product-create-5KQFXFJF.mjs → product-create-XZHAADGZ.mjs} +15 -14
  98. package/dist/{product-create-option-3JR35UZ5.mjs → product-create-option-OW2LMVST.mjs} +1 -1
  99. package/dist/{product-create-variant-37CVX4QI.mjs → product-create-variant-NKU6J7NG.mjs} +10 -10
  100. package/dist/{product-detail-UM6PIKWQ.mjs → product-detail-6JW2KCQA.mjs} +14 -13
  101. package/dist/{product-edit-QSCZEH74.mjs → product-edit-FGQ3YETD.mjs} +14 -13
  102. package/dist/{product-edit-option-VNDGZ37A.mjs → product-edit-option-OM56DLU6.mjs} +1 -1
  103. package/dist/{product-export-JNLDMDUS.mjs → product-export-W6KP2RGO.mjs} +12 -12
  104. package/dist/{product-import-CA75XMEH.mjs → product-import-P76MITMC.mjs} +10 -10
  105. package/dist/{product-list-XA5SJLXF.mjs → product-list-7H64APWI.mjs} +11 -11
  106. package/dist/{product-media-36YW62IO.mjs → product-media-TRKQTA4G.mjs} +3 -3
  107. package/dist/{product-metadata-JKWIAMVB.mjs → product-metadata-2G6DWHWG.mjs} +10 -10
  108. package/dist/{product-organization-YL4ZUCC4.mjs → product-organization-GXXT6SZY.mjs} +15 -14
  109. package/dist/{product-prices-4ZV5EXX5.mjs → product-prices-XLY5TUSJ.mjs} +1 -1
  110. package/dist/{product-sales-channels-UX7AOJIF.mjs → product-sales-channels-KSIHPDJG.mjs} +2 -2
  111. package/dist/{product-shipping-profile-PEIUF5AK.mjs → product-shipping-profile-GFSIYLGC.mjs} +14 -13
  112. package/dist/{product-stock-4XECV73O.mjs → product-stock-GAWLELSE.mjs} +10 -10
  113. package/dist/{product-tag-create-U5DAEOBS.mjs → product-tag-create-FVU5JRL3.mjs} +10 -10
  114. package/dist/{product-tag-detail-YB44E6JT.mjs → product-tag-detail-VMVPWMZK.mjs} +13 -13
  115. package/dist/{product-tag-edit-J3OPHCDJ.mjs → product-tag-edit-OWI3OFVF.mjs} +10 -10
  116. package/dist/{product-tag-list-6TGDOAMD.mjs → product-tag-list-YPIZII2D.mjs} +13 -13
  117. package/dist/{product-tag-metadata-VAHEGSFJ.mjs → product-tag-metadata-B4YBSHOH.mjs} +10 -10
  118. package/dist/{product-type-detail-EN3WAIVO.mjs → product-type-detail-243HFRBD.mjs} +11 -11
  119. package/dist/{product-type-metadata-R3YLZGY5.mjs → product-type-metadata-4YE4UEOF.mjs} +10 -10
  120. package/dist/{product-variant-detail-TYV4BYNG.mjs → product-variant-detail-LJE3IFNE.mjs} +10 -10
  121. package/dist/{product-variant-edit-YPQDVG5C.mjs → product-variant-edit-IGJIWVQQ.mjs} +10 -10
  122. package/dist/{product-variant-manage-inventory-items-LGRRKHT2.mjs → product-variant-manage-inventory-items-2M2KTPNK.mjs} +1 -1
  123. package/dist/{product-variant-metadata-DII5YHIK.mjs → product-variant-metadata-F6BGFMMS.mjs} +10 -10
  124. package/dist/{promotion-create-TLW6T5IO.mjs → promotion-create-YGHBTAFC.mjs} +10 -10
  125. package/dist/{promotion-detail-BYA66IL7.mjs → promotion-detail-BIC23HFR.mjs} +12 -12
  126. package/dist/{promotion-list-TOYJAQ4D.mjs → promotion-list-WDHOSD55.mjs} +3 -3
  127. package/dist/{refund-reason-create-D5DJVOXP.mjs → refund-reason-create-YCWLRRBW.mjs} +10 -10
  128. package/dist/{refund-reason-list-V7UO2NAY.mjs → refund-reason-list-7GANH7KL.mjs} +10 -10
  129. package/dist/{region-create-4C42KVB4.mjs → region-create-AFZTSM3N.mjs} +4 -4
  130. package/dist/{region-edit-CLE5VVRP.mjs → region-edit-DSYIUI7W.mjs} +4 -4
  131. package/dist/{region-metadata-23FQEWQ7.mjs → region-metadata-L5K6YENH.mjs} +10 -10
  132. package/dist/{reservation-create-CBWJLYHP.mjs → reservation-create-FV7QXGL3.mjs} +2 -2
  133. package/dist/{reservation-detail-USSX2THW.mjs → reservation-detail-USDAVGWH.mjs} +10 -10
  134. package/dist/{reservation-list-YNG7YKG2.mjs → reservation-list-NOWJUMXV.mjs} +2 -2
  135. package/dist/{reservation-metadata-PKWRLWNT.mjs → reservation-metadata-47C6RWYS.mjs} +10 -10
  136. package/dist/{reset-password-EKZEJXQU.mjs → reset-password-LCVV4NOA.mjs} +1 -1
  137. package/dist/{sales-channel-add-products-DKDV65UU.mjs → sales-channel-add-products-NGPN4IRB.mjs} +11 -11
  138. package/dist/{sales-channel-create-VW2UPYSI.mjs → sales-channel-create-NODWGJDD.mjs} +2 -2
  139. package/dist/{sales-channel-detail-JKJLEM4C.mjs → sales-channel-detail-IWWRX2Y3.mjs} +11 -11
  140. package/dist/{sales-channel-edit-OA6QPIHW.mjs → sales-channel-edit-ALIRERVH.mjs} +2 -2
  141. package/dist/{sales-channel-list-FOAVTG7H.mjs → sales-channel-list-LCPDOQK3.mjs} +10 -10
  142. package/dist/{sales-channel-metadata-3RXYX7U2.mjs → sales-channel-metadata-VZ4TINYG.mjs} +10 -10
  143. package/dist/{shipping-option-type-create-ZLYFQFYI.mjs → shipping-option-type-create-NOMFII5B.mjs} +10 -10
  144. package/dist/{shipping-option-type-detail-OMVJZSOI.mjs → shipping-option-type-detail-6XIJRVZ5.mjs} +11 -11
  145. package/dist/{shipping-option-type-edit-5XHFIDEZ.mjs → shipping-option-type-edit-PEDYL6JQ.mjs} +10 -10
  146. package/dist/{shipping-option-type-list-SGTTVHWK.mjs → shipping-option-type-list-GI5GBLIS.mjs} +11 -11
  147. package/dist/{shipping-profile-metadata-3TZDQ27Z.mjs → shipping-profile-metadata-ZOR7MQFF.mjs} +10 -10
  148. package/dist/{store-detail-72GMDFY7.mjs → store-detail-MZAKRCTC.mjs} +10 -10
  149. package/dist/{store-metadata-TXSRTL6B.mjs → store-metadata-GO4TXB3W.mjs} +10 -10
  150. package/dist/{tax-region-create-U6XXHBMJ.mjs → tax-region-create-KDCNQGPC.mjs} +11 -11
  151. package/dist/{tax-region-detail-V4E63XUI.mjs → tax-region-detail-O6U6ZVDB.mjs} +11 -11
  152. package/dist/{tax-region-edit-2DQPKIJG.mjs → tax-region-edit-T4B5DM55.mjs} +10 -10
  153. package/dist/{tax-region-province-detail-P6LPVSQJ.mjs → tax-region-province-detail-XH45ZAOJ.mjs} +11 -11
  154. package/dist/{tax-region-tax-override-create-BPZKBPN6.mjs → tax-region-tax-override-create-MSL7HEM6.mjs} +13 -13
  155. package/dist/{tax-region-tax-override-edit-O7LUBRQN.mjs → tax-region-tax-override-edit-AO6CYS62.mjs} +13 -13
  156. package/dist/{user-detail-ZIWKV6QD.mjs → user-detail-ZFW3YF3M.mjs} +1 -1
  157. package/dist/{user-metadata-TM3FFLIR.mjs → user-metadata-2CR2AK3U.mjs} +10 -10
  158. package/dist/{workflow-execution-detail-3IBZZVRE.mjs → workflow-execution-detail-ZD7OVL4W.mjs} +10 -10
  159. package/package.json +9 -9
  160. package/src/hooks/api/inventory.tsx +3 -0
  161. package/src/i18n/translations/$schema.json +4 -0
  162. package/src/i18n/translations/en.json +1 -0
  163. package/src/routes/inventory/inventory-detail/components/location-levels-table/use-location-list-table-columns.tsx +7 -0
  164. package/src/routes/inventory/inventory-detail/components/manage-locations/components/location-item.tsx +2 -2
  165. package/src/routes/inventory/inventory-detail/components/manage-locations/components/location-search-input.tsx +34 -0
  166. package/src/routes/inventory/inventory-detail/components/manage-locations/components/manage-locations-form.tsx +127 -140
  167. package/src/routes/orders/order-create-refund/components/create-refund-form/create-refund-form.tsx +39 -1
  168. package/dist/manage-locations-3TBIUSHP.mjs +0 -236
@@ -241,6 +241,9 @@ export const useBatchInventoryItemLocationLevels = (
241
241
  queryClient.invalidateQueries({
242
242
  queryKey: inventoryItemLevelsQueryKeys.detail(inventoryItemId),
243
243
  })
244
+ queryClient.invalidateQueries({
245
+ queryKey: inventoryItemLevelsQueryKeys.list({ inventoryItemId }),
246
+ })
244
247
  options?.onSuccess?.(data, variables, context)
245
248
  },
246
249
  ...options,
@@ -3111,6 +3111,9 @@
3111
3111
  "quantityAcrossLocations": {
3112
3112
  "type": "string"
3113
3113
  },
3114
+ "levelDeleted": {
3115
+ "type": "string"
3116
+ },
3114
3117
  "create": {
3115
3118
  "type": "object",
3116
3119
  "properties": {
@@ -3327,6 +3330,7 @@
3327
3330
  "deleteWarning",
3328
3331
  "editItemDetails",
3329
3332
  "quantityAcrossLocations",
3333
+ "levelDeleted",
3330
3334
  "create",
3331
3335
  "reservation",
3332
3336
  "adjustInventory",
@@ -832,6 +832,7 @@
832
832
  "deleteWarning": "You are about to delete an inventory item. This action cannot be undone.",
833
833
  "editItemDetails": "Edit item details",
834
834
  "quantityAcrossLocations": "{{quantity}} across {{locations}} locations",
835
+ "levelDeleted": "Inventory level deleted successfully.",
835
836
  "create": {
836
837
  "title": "Create Inventory Item",
837
838
  "details": "Details",
@@ -49,9 +49,16 @@ export const useLocationListTableColumns = () => {
49
49
  level.location_id
50
50
  )
51
51
 
52
+ toast.success(t("inventory.levelDeleted"))
53
+
52
54
  queryClient.invalidateQueries({
53
55
  queryKey: inventoryItemsQueryKeys.lists(),
54
56
  })
57
+ queryClient.invalidateQueries({
58
+ queryKey: inventoryItemLevelsQueryKeys.list({
59
+ inventoryItemId: level.inventory_item_id,
60
+ }),
61
+ })
55
62
  queryClient.invalidateQueries({
56
63
  queryKey: inventoryItemsQueryKeys.detail(level.inventory_item_id),
57
64
  })
@@ -1,11 +1,11 @@
1
1
  import { Checkbox, Text, clx } from "@medusajs/ui"
2
2
 
3
- import { StockLocationDTO } from "@medusajs/types"
3
+ import { HttpTypes } from "@medusajs/types"
4
4
 
5
5
  type LocationItemProps = {
6
6
  selected: boolean
7
7
  onSelect: (selected: boolean) => void
8
- location: StockLocationDTO
8
+ location: HttpTypes.AdminStockLocation
9
9
  }
10
10
 
11
11
  export const LocationItem = ({
@@ -0,0 +1,34 @@
1
+ import { Input } from "@medusajs/ui"
2
+ import { useTranslation } from "react-i18next"
3
+ import { useState, useEffect } from "react"
4
+
5
+ type LocationSearchInputProps = {
6
+ onSearchChange: (search: string) => void
7
+ placeholder?: string
8
+ }
9
+
10
+ export const LocationSearchInput = ({
11
+ onSearchChange,
12
+ placeholder,
13
+ }: LocationSearchInputProps) => {
14
+ const { t } = useTranslation()
15
+ const [searchValue, setSearchValue] = useState("")
16
+
17
+ useEffect(() => {
18
+ const timer = setTimeout(() => {
19
+ onSearchChange(searchValue)
20
+ }, 300)
21
+
22
+ return () => clearTimeout(timer)
23
+ }, [searchValue, onSearchChange])
24
+
25
+ return (
26
+ <Input
27
+ type="text"
28
+ placeholder={placeholder || t("general.search")}
29
+ value={searchValue}
30
+ onChange={(e) => setSearchValue(e.target.value)}
31
+ className="w-full"
32
+ />
33
+ )
34
+ }
@@ -1,111 +1,75 @@
1
- import * as zod from "zod"
2
-
3
- import { zodResolver } from "@hookform/resolvers/zod"
4
- import { AdminInventoryItem, AdminStockLocation } from "@medusajs/types"
1
+ import {
2
+ AdminInventoryItem,
3
+ AdminStockLocation,
4
+ HttpTypes,
5
+ } from "@medusajs/types"
5
6
  import { Button, Text, toast } from "@medusajs/ui"
6
- import { useFieldArray, useForm } from "react-hook-form"
7
7
  import { useTranslation } from "react-i18next"
8
- import { z } from "zod"
9
8
  import { RouteDrawer, useRouteModal } from "../../../../../../components/modals"
10
9
  import { useBatchInventoryItemLocationLevels } from "../../../../../../hooks/api/inventory"
10
+ import { sdk } from "../../../../../../lib/client"
11
11
 
12
- import { useEffect, useMemo } from "react"
13
- import { KeyboundForm } from "../../../../../../components/utilities/keybound-form"
12
+ import { useMemo, useState } from "react"
14
13
  import { LocationItem } from "./location-item"
14
+ import { LocationSearchInput } from "./location-search-input"
15
+ import { InfiniteList } from "../../../../../../components/common/infinite-list/infinite-list"
16
+ import { useStockLocations } from "../../../../../../hooks/api/stock-locations"
15
17
 
16
18
  type EditInventoryItemAttributeFormProps = {
17
19
  item: AdminInventoryItem
18
20
  locations: AdminStockLocation[]
19
21
  }
20
22
 
21
- const EditInventoryItemAttributesSchema = z.object({
22
- locations: z.array(
23
- z.object({
24
- id: z.string(),
25
- location_id: z.string(),
26
- selected: z.boolean(),
27
- })
28
- ),
29
- })
30
-
31
- const getDefaultValues = (
32
- allLocations: AdminStockLocation[],
33
- existingLevels: Set<string>
34
- ) => {
35
- return {
36
- locations: allLocations.map((location) => ({
37
- ...location,
38
- location_id: location.id,
39
- selected: existingLevels.has(location.id),
40
- })),
41
- }
42
- }
43
-
44
23
  export const ManageLocationsForm = ({
45
24
  item,
46
- locations,
47
25
  }: EditInventoryItemAttributeFormProps) => {
48
26
  const existingLocationLevels = useMemo(
49
27
  () => new Set(item.location_levels?.map((l) => l.location_id) ?? []),
50
- item.location_levels
28
+ [item.location_levels]
51
29
  )
52
30
 
53
31
  const { t } = useTranslation()
54
32
  const { handleSuccess } = useRouteModal()
33
+ const [searchQuery, setSearchQuery] = useState("")
34
+ const [selectedLocationIds, setSelectedLocationIds] = useState<Set<string>>(
35
+ existingLocationLevels
36
+ )
55
37
 
56
- const form = useForm<zod.infer<typeof EditInventoryItemAttributesSchema>>({
57
- defaultValues: getDefaultValues(locations, existingLocationLevels),
58
- resolver: zodResolver(EditInventoryItemAttributesSchema),
59
- })
60
-
61
- const { fields: locationFields, update: updateField } = useFieldArray({
62
- control: form.control,
63
- name: "locations",
64
- })
38
+ const { count } = useStockLocations({ limit: 1, fields: "id" })
65
39
 
66
- useEffect(() => {
67
- form.setValue(
68
- "locations",
69
- getDefaultValues(locations, existingLocationLevels).locations
70
- )
71
- }, [existingLocationLevels, locations])
40
+ const handleLocationSelect = (locationId: string, selected: boolean) => {
41
+ setSelectedLocationIds((prev) => {
42
+ const newSet = new Set(prev)
43
+ if (selected) {
44
+ newSet.add(locationId)
45
+ } else {
46
+ newSet.delete(locationId)
47
+ }
48
+ return newSet
49
+ })
50
+ }
72
51
 
73
52
  const { mutateAsync } = useBatchInventoryItemLocationLevels(item.id)
74
53
 
75
- const handleSubmit = form.handleSubmit(async ({ locations }) => {
76
- // Changes in selected locations
77
- const [selectedLocations, unselectedLocations] = locations.reduce(
78
- (acc, location) => {
79
- // If the location is not changed do nothing
80
- if (
81
- (!location.selected &&
82
- !existingLocationLevels.has(location.location_id)) ||
83
- (location.selected &&
84
- existingLocationLevels.has(location.location_id))
85
- ) {
86
- return acc
87
- }
54
+ const handleSubmit = async () => {
55
+ const toCreate = Array.from(selectedLocationIds).filter(
56
+ (id) => !existingLocationLevels.has(id)
57
+ )
88
58
 
89
- if (location.selected) {
90
- acc[0].push(location.location_id)
91
- } else {
92
- acc[1].push(location.location_id)
93
- }
94
- return acc
95
- },
96
- [[], []] as [string[], string[]]
59
+ const toDeleteLocations = Array.from(existingLocationLevels).filter(
60
+ (id) => !selectedLocationIds.has(id)
97
61
  )
98
62
 
99
- if (selectedLocations.length === 0 && unselectedLocations.length === 0) {
100
- return handleSuccess()
101
- }
63
+ const toDelete = toDeleteLocations
64
+ .map((id) => item.location_levels?.find((l) => l.location_id === id)?.id)
65
+ .filter(Boolean) as unknown as string[]
102
66
 
103
67
  await mutateAsync(
104
68
  {
105
- create: selectedLocations.map((location_id) => ({
69
+ create: toCreate.map((location_id) => ({
106
70
  location_id,
107
71
  })),
108
- delete: unselectedLocations,
72
+ delete: toDelete,
109
73
  },
110
74
  {
111
75
  onSuccess: () => {
@@ -117,80 +81,103 @@ export const ManageLocationsForm = ({
117
81
  },
118
82
  }
119
83
  )
120
- })
84
+ }
121
85
 
122
86
  return (
123
- <RouteDrawer.Form form={form}>
124
- <KeyboundForm
125
- onSubmit={handleSubmit}
126
- className="flex flex-1 flex-col overflow-hidden"
127
- >
128
- <RouteDrawer.Body className="flex flex-1 flex-col gap-y-4 overflow-auto">
129
- <div className="text-ui-fg-subtle shadow-elevation-card-rest grid grid-rows-2 divide-y rounded-lg border">
130
- <div className="grid grid-cols-2 divide-x">
131
- <Text className="px-2 py-1.5" size="small" leading="compact">
132
- {t("fields.title")}
133
- </Text>
134
- <Text className="px-2 py-1.5" size="small" leading="compact">
135
- {item.title ?? "-"}
136
- </Text>
137
- </div>
138
- <div className="grid grid-cols-2 divide-x">
139
- <Text className="px-2 py-1.5" size="small" leading="compact">
140
- {t("fields.sku")}
141
- </Text>
142
- <Text className="px-2 py-1.5" size="small" leading="compact">
143
- {item.sku}
144
- </Text>
145
- </div>
87
+ <div className="flex flex-1 flex-col overflow-hidden">
88
+ <RouteDrawer.Body className="flex flex-1 flex-col gap-y-4 overflow-auto">
89
+ <div className="text-ui-fg-subtle shadow-elevation-card-rest grid grid-rows-2 divide-y rounded-lg border">
90
+ <div className="grid grid-cols-2 divide-x">
91
+ <Text className="px-2 py-1.5" size="small" leading="compact">
92
+ {t("fields.title")}
93
+ </Text>
94
+ <Text className="px-2 py-1.5" size="small" leading="compact">
95
+ {item.title ?? "-"}
96
+ </Text>
146
97
  </div>
147
- <div className="flex flex-col">
148
- <Text size="small" weight="plus" leading="compact">
149
- {t("locations.domain")}
98
+ <div className="grid grid-cols-2 divide-x">
99
+ <Text className="px-2 py-1.5" size="small" leading="compact">
100
+ {t("fields.sku")}
101
+ </Text>
102
+ <Text className="px-2 py-1.5" size="small" leading="compact">
103
+ {item.sku}
150
104
  </Text>
151
- <div className="text-ui-fg-subtle flex w-full justify-between">
152
- <Text size="small" leading="compact">
153
- {t("locations.selectLocations")}
154
- </Text>
155
- <Text size="small" leading="compact">
156
- {"("}
157
- {t("general.countOfTotalSelected", {
158
- count: locationFields.filter((l) => l.selected).length,
159
- total: locations.length,
160
- })}
161
- {")"}
162
- </Text>
163
- </div>
164
105
  </div>
165
- {locationFields.map((location, idx) => {
166
- return (
106
+ </div>
107
+ <div className="flex flex-col">
108
+ <Text size="small" weight="plus" leading="compact">
109
+ {t("locations.domain")}
110
+ </Text>
111
+ <div className="text-ui-fg-subtle flex w-full justify-between">
112
+ <Text size="small" leading="compact">
113
+ {t("locations.selectLocations")}
114
+ </Text>
115
+ <Text size="small" leading="compact">
116
+ {"("}
117
+ {t("general.countOfTotalSelected", {
118
+ count: selectedLocationIds.size,
119
+ total: count,
120
+ })}
121
+ {")"}
122
+ </Text>
123
+ </div>
124
+ </div>
125
+
126
+ <LocationSearchInput
127
+ onSearchChange={setSearchQuery}
128
+ placeholder={t("general.search")}
129
+ />
130
+
131
+ <div className="min-h-0 flex-1">
132
+ <InfiniteList<
133
+ HttpTypes.AdminStockLocationListResponse,
134
+ HttpTypes.AdminStockLocation,
135
+ HttpTypes.AdminStockLocationListParams
136
+ >
137
+ queryKey={["stock-locations", searchQuery]}
138
+ queryFn={async (params) => {
139
+ const response = await sdk.admin.stockLocation.list({
140
+ limit: params.limit,
141
+ offset: params.offset,
142
+ ...(searchQuery && { q: searchQuery }),
143
+ })
144
+ return response
145
+ }}
146
+ responseKey="stock_locations"
147
+ renderItem={(location) => (
167
148
  <LocationItem
168
- selected={location.selected}
169
- location={location as any}
170
- onSelect={() =>
171
- updateField(idx, {
172
- ...location,
173
- selected: !location.selected,
174
- })
149
+ selected={selectedLocationIds.has(location.id)}
150
+ location={location}
151
+ onSelect={(selected) =>
152
+ handleLocationSelect(location.id, selected)
175
153
  }
176
- key={location.id}
177
154
  />
178
- )
179
- })}
180
- </RouteDrawer.Body>
181
- <RouteDrawer.Footer>
182
- <div className="flex items-center justify-end gap-x-2">
183
- <RouteDrawer.Close asChild>
184
- <Button variant="secondary" size="small">
185
- {t("actions.cancel")}
186
- </Button>
187
- </RouteDrawer.Close>
188
- <Button type="submit" size="small" isLoading={false}>
189
- {t("actions.save")}
155
+ )}
156
+ renderEmpty={() => (
157
+ <div className="flex items-center justify-center py-8">
158
+ <Text size="small" className="text-ui-fg-subtle">
159
+ {searchQuery
160
+ ? t("locations.noLocationsFound")
161
+ : t("locations.noLocationsFound")}
162
+ </Text>
163
+ </div>
164
+ )}
165
+ pageSize={20}
166
+ />
167
+ </div>
168
+ </RouteDrawer.Body>
169
+ <RouteDrawer.Footer>
170
+ <div className="flex items-center justify-end gap-x-2">
171
+ <RouteDrawer.Close asChild>
172
+ <Button variant="secondary" size="small">
173
+ {t("actions.cancel")}
190
174
  </Button>
191
- </div>
192
- </RouteDrawer.Footer>
193
- </KeyboundForm>
194
- </RouteDrawer.Form>
175
+ </RouteDrawer.Close>
176
+ <Button onClick={handleSubmit} size="small" isLoading={false}>
177
+ {t("actions.save")}
178
+ </Button>
179
+ </div>
180
+ </RouteDrawer.Footer>
181
+ </div>
195
182
  )
196
183
  }
@@ -17,7 +17,7 @@ import * as zod from "zod"
17
17
  import { Form } from "../../../../../components/common/form"
18
18
  import { RouteDrawer, useRouteModal } from "../../../../../components/modals"
19
19
  import { KeyboundForm } from "../../../../../components/utilities/keybound-form"
20
- import { useRefundPayment } from "../../../../../hooks/api"
20
+ import { useRefundPayment, useRefundReasons } from "../../../../../hooks/api"
21
21
  import { currencies } from "../../../../../lib/data/currencies"
22
22
  import { formatCurrency } from "../../../../../lib/format-currency"
23
23
  import { formatProvider } from "../../../../../lib/format-provider"
@@ -35,11 +35,13 @@ const CreateRefundSchema = zod.object({
35
35
  float: zod.number().or(zod.null()),
36
36
  }),
37
37
  note: zod.string().optional(),
38
+ refund_reason_id: zod.string().optional(),
38
39
  })
39
40
 
40
41
  export const CreateRefundForm = ({ order }: CreateRefundFormProps) => {
41
42
  const { t } = useTranslation()
42
43
  const { handleSuccess } = useRouteModal()
44
+ const { refund_reasons } = useRefundReasons()
43
45
 
44
46
  const [searchParams] = useSearchParams()
45
47
  const [paymentId, setPaymentId] = useState<string | undefined>(
@@ -62,6 +64,7 @@ export const CreateRefundForm = ({ order }: CreateRefundFormProps) => {
62
64
  float: paymentAmount,
63
65
  },
64
66
  note: "",
67
+ refund_reason_id: "",
65
68
  },
66
69
  resolver: zodResolver(CreateRefundSchema),
67
70
  })
@@ -90,6 +93,7 @@ export const CreateRefundForm = ({ order }: CreateRefundFormProps) => {
90
93
  {
91
94
  amount: data.amount.float!,
92
95
  note: data.note,
96
+ refund_reason_id: data.refund_reason_id,
93
97
  },
94
98
  {
95
99
  onSuccess: () => {
@@ -208,6 +212,40 @@ export const CreateRefundForm = ({ order }: CreateRefundFormProps) => {
208
212
  }}
209
213
  />
210
214
 
215
+ <Form.Field
216
+ control={form.control}
217
+ name="refund_reason_id"
218
+ render={({ field }) => {
219
+ return (
220
+ <Form.Item>
221
+ <Form.Label>{t("fields.refundReason")}</Form.Label>
222
+
223
+ <Form.Control>
224
+ <Select
225
+ dir={direction}
226
+ value={field.value}
227
+ onValueChange={field.onChange}
228
+ >
229
+ <Select.Trigger>
230
+ <Select.Value />
231
+ </Select.Trigger>
232
+
233
+ <Select.Content>
234
+ {refund_reasons?.map((reason) => (
235
+ <Select.Item key={reason.id} value={reason.id}>
236
+ {reason.label}
237
+ </Select.Item>
238
+ ))}
239
+ </Select.Content>
240
+ </Select>
241
+ </Form.Control>
242
+
243
+ <Form.ErrorMessage />
244
+ </Form.Item>
245
+ )
246
+ }}
247
+ />
248
+
211
249
  <Form.Field
212
250
  control={form.control}
213
251
  name={`note`}