@medusajs/dashboard 2.10.4-preview-20250924150158 → 2.10.4-preview-20250924210149

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 (167) 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 +4339 -4310
  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-H45W7DHU.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-COUIM3ID.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-J3QWFH5Q.mjs → order-create-refund-TEMK6IEQ.mjs} +10 -10
  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-E55XL2RM.mjs → product-attributes-RMPKQ5KE.mjs} +14 -13
  97. package/dist/{product-create-WUKUKVJ4.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-MJ4TK4I4.mjs → product-detail-6JW2KCQA.mjs} +14 -13
  101. package/dist/{product-edit-IS3TSDYG.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-TN3PFQPN.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-DBRFIPTN.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/dist/manage-locations-3TBIUSHP.mjs +0 -236
@@ -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
  }
@@ -1,236 +0,0 @@
1
- import "./chunk-IUCDCPJU.mjs";
2
- import {
3
- KeyboundForm
4
- } from "./chunk-6HTZNHPT.mjs";
5
- import {
6
- RouteDrawer,
7
- useRouteModal
8
- } from "./chunk-4TC5YS65.mjs";
9
- import "./chunk-OBQI23QM.mjs";
10
- import {
11
- useStockLocations
12
- } from "./chunk-32IQRUVY.mjs";
13
- import {
14
- useBatchInventoryItemLocationLevels,
15
- useInventoryItem
16
- } from "./chunk-X4X5KUGQ.mjs";
17
- import "./chunk-FXYH54JP.mjs";
18
- import "./chunk-774WSTCC.mjs";
19
- import "./chunk-DEQUVHHE.mjs";
20
- import "./chunk-RPUOO7AV.mjs";
21
-
22
- // src/routes/inventory/inventory-detail/components/manage-locations/manage-locations-drawer.tsx
23
- import { Heading } from "@medusajs/ui";
24
- import { useTranslation as useTranslation2 } from "react-i18next";
25
- import { useParams } from "react-router-dom";
26
-
27
- // src/routes/inventory/inventory-detail/components/manage-locations/components/manage-locations-form.tsx
28
- import { zodResolver } from "@hookform/resolvers/zod";
29
- import { Button, Text as Text2, toast } from "@medusajs/ui";
30
- import { useFieldArray, useForm } from "react-hook-form";
31
- import { useTranslation } from "react-i18next";
32
- import { z } from "zod";
33
- import { useEffect, useMemo } from "react";
34
-
35
- // src/routes/inventory/inventory-detail/components/manage-locations/components/location-item.tsx
36
- import { Checkbox, Text, clx } from "@medusajs/ui";
37
- import { jsx, jsxs } from "react/jsx-runtime";
38
- var LocationItem = ({
39
- selected,
40
- onSelect,
41
- location
42
- }) => {
43
- return /* @__PURE__ */ jsxs(
44
- "div",
45
- {
46
- className: clx(
47
- "flex w-full cursor-pointer gap-x-2 rounded-lg border px-2 py-2",
48
- {
49
- "border-ui-border-interactive ": selected
50
- }
51
- ),
52
- onClick: () => onSelect(!selected),
53
- children: [
54
- /* @__PURE__ */ jsx("div", { className: "h-5 w-5", children: /* @__PURE__ */ jsx(
55
- Checkbox,
56
- {
57
- onClick: (e) => {
58
- e.stopPropagation();
59
- onSelect(!selected);
60
- },
61
- checked: selected
62
- }
63
- ) }),
64
- /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-col", children: [
65
- /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", weight: "plus", children: location.name }),
66
- /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", className: "text-ui-fg-subtle", children: [
67
- location.address?.address_1,
68
- location.address?.city,
69
- location.address?.country_code
70
- ].filter((el) => !!el).join(", ") })
71
- ] })
72
- ]
73
- }
74
- );
75
- };
76
-
77
- // src/routes/inventory/inventory-detail/components/manage-locations/components/manage-locations-form.tsx
78
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
79
- var EditInventoryItemAttributesSchema = z.object({
80
- locations: z.array(
81
- z.object({
82
- id: z.string(),
83
- location_id: z.string(),
84
- selected: z.boolean()
85
- })
86
- )
87
- });
88
- var getDefaultValues = (allLocations, existingLevels) => {
89
- return {
90
- locations: allLocations.map((location) => ({
91
- ...location,
92
- location_id: location.id,
93
- selected: existingLevels.has(location.id)
94
- }))
95
- };
96
- };
97
- var ManageLocationsForm = ({
98
- item,
99
- locations
100
- }) => {
101
- const existingLocationLevels = useMemo(
102
- () => new Set(item.location_levels?.map((l) => l.location_id) ?? []),
103
- item.location_levels
104
- );
105
- const { t } = useTranslation();
106
- const { handleSuccess } = useRouteModal();
107
- const form = useForm({
108
- defaultValues: getDefaultValues(locations, existingLocationLevels),
109
- resolver: zodResolver(EditInventoryItemAttributesSchema)
110
- });
111
- const { fields: locationFields, update: updateField } = useFieldArray({
112
- control: form.control,
113
- name: "locations"
114
- });
115
- useEffect(() => {
116
- form.setValue(
117
- "locations",
118
- getDefaultValues(locations, existingLocationLevels).locations
119
- );
120
- }, [existingLocationLevels, locations]);
121
- const { mutateAsync } = useBatchInventoryItemLocationLevels(item.id);
122
- const handleSubmit = form.handleSubmit(async ({ locations: locations2 }) => {
123
- const [selectedLocations, unselectedLocations] = locations2.reduce(
124
- (acc, location) => {
125
- if (!location.selected && !existingLocationLevels.has(location.location_id) || location.selected && existingLocationLevels.has(location.location_id)) {
126
- return acc;
127
- }
128
- if (location.selected) {
129
- acc[0].push(location.location_id);
130
- } else {
131
- acc[1].push(location.location_id);
132
- }
133
- return acc;
134
- },
135
- [[], []]
136
- );
137
- if (selectedLocations.length === 0 && unselectedLocations.length === 0) {
138
- return handleSuccess();
139
- }
140
- await mutateAsync(
141
- {
142
- create: selectedLocations.map((location_id) => ({
143
- location_id
144
- })),
145
- delete: unselectedLocations
146
- },
147
- {
148
- onSuccess: () => {
149
- toast.success(t("inventory.toast.updateLocations"));
150
- handleSuccess();
151
- },
152
- onError: (e) => {
153
- toast.error(e.message);
154
- }
155
- }
156
- );
157
- });
158
- return /* @__PURE__ */ jsx2(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs2(
159
- KeyboundForm,
160
- {
161
- onSubmit: handleSubmit,
162
- className: "flex flex-1 flex-col overflow-hidden",
163
- children: [
164
- /* @__PURE__ */ jsxs2(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-4 overflow-auto", children: [
165
- /* @__PURE__ */ jsxs2("div", { className: "text-ui-fg-subtle shadow-elevation-card-rest grid grid-rows-2 divide-y rounded-lg border", children: [
166
- /* @__PURE__ */ jsxs2("div", { className: "grid grid-cols-2 divide-x", children: [
167
- /* @__PURE__ */ jsx2(Text2, { className: "px-2 py-1.5", size: "small", leading: "compact", children: t("fields.title") }),
168
- /* @__PURE__ */ jsx2(Text2, { className: "px-2 py-1.5", size: "small", leading: "compact", children: item.title ?? "-" })
169
- ] }),
170
- /* @__PURE__ */ jsxs2("div", { className: "grid grid-cols-2 divide-x", children: [
171
- /* @__PURE__ */ jsx2(Text2, { className: "px-2 py-1.5", size: "small", leading: "compact", children: t("fields.sku") }),
172
- /* @__PURE__ */ jsx2(Text2, { className: "px-2 py-1.5", size: "small", leading: "compact", children: item.sku })
173
- ] })
174
- ] }),
175
- /* @__PURE__ */ jsxs2("div", { className: "flex flex-col", children: [
176
- /* @__PURE__ */ jsx2(Text2, { size: "small", weight: "plus", leading: "compact", children: t("locations.domain") }),
177
- /* @__PURE__ */ jsxs2("div", { className: "text-ui-fg-subtle flex w-full justify-between", children: [
178
- /* @__PURE__ */ jsx2(Text2, { size: "small", leading: "compact", children: t("locations.selectLocations") }),
179
- /* @__PURE__ */ jsxs2(Text2, { size: "small", leading: "compact", children: [
180
- "(",
181
- t("general.countOfTotalSelected", {
182
- count: locationFields.filter((l) => l.selected).length,
183
- total: locations.length
184
- }),
185
- ")"
186
- ] })
187
- ] })
188
- ] }),
189
- locationFields.map((location, idx) => {
190
- return /* @__PURE__ */ jsx2(
191
- LocationItem,
192
- {
193
- selected: location.selected,
194
- location,
195
- onSelect: () => updateField(idx, {
196
- ...location,
197
- selected: !location.selected
198
- })
199
- },
200
- location.id
201
- );
202
- })
203
- ] }),
204
- /* @__PURE__ */ jsx2(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs2("div", { className: "flex items-center justify-end gap-x-2", children: [
205
- /* @__PURE__ */ jsx2(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx2(Button, { variant: "secondary", size: "small", children: t("actions.cancel") }) }),
206
- /* @__PURE__ */ jsx2(Button, { type: "submit", size: "small", isLoading: false, children: t("actions.save") })
207
- ] }) })
208
- ]
209
- }
210
- ) });
211
- };
212
-
213
- // src/routes/inventory/inventory-detail/components/manage-locations/manage-locations-drawer.tsx
214
- import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
215
- var ManageLocationsDrawer = () => {
216
- const { id } = useParams();
217
- const { t } = useTranslation2();
218
- const {
219
- inventory_item: inventoryItem,
220
- isPending: isLoading,
221
- isError,
222
- error
223
- } = useInventoryItem(id);
224
- const { stock_locations, isLoading: loadingLocations } = useStockLocations();
225
- const ready = !isLoading && !loadingLocations && inventoryItem && stock_locations;
226
- if (isError) {
227
- throw error;
228
- }
229
- return /* @__PURE__ */ jsxs3(RouteDrawer, { children: [
230
- /* @__PURE__ */ jsx3(RouteDrawer.Header, { children: /* @__PURE__ */ jsx3(Heading, { children: t("inventory.manageLocations") }) }),
231
- ready && /* @__PURE__ */ jsx3(ManageLocationsForm, { item: inventoryItem, locations: stock_locations })
232
- ] });
233
- };
234
- export {
235
- ManageLocationsDrawer as Component
236
- };