@medusajs/dashboard 3.0.0-snapshot-20251202221811 → 3.0.0-snapshot-20251208164410

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 (241) hide show
  1. package/dist/{adjust-inventory-WZOCLB5V.mjs → adjust-inventory-ZB3AVET7.mjs} +1 -1
  2. package/dist/{api-key-management-create-W7NL2IYN.mjs → api-key-management-create-U6VGZK7R.mjs} +3 -3
  3. package/dist/{api-key-management-detail-LDBEO446.mjs → api-key-management-detail-OEAWWV5O.mjs} +13 -13
  4. package/dist/{api-key-management-edit-TLVLXAVK.mjs → api-key-management-edit-TJM737A7.mjs} +3 -3
  5. package/dist/{api-key-management-list-FTLC3ELT.mjs → api-key-management-list-ZRYMMTF5.mjs} +3 -3
  6. package/dist/{api-key-management-sales-channels-NYY3NZOE.mjs → api-key-management-sales-channels-D2RAHI7W.mjs} +4 -4
  7. package/dist/app.css +3 -3
  8. package/dist/app.js +17416 -15980
  9. package/dist/app.mjs +11 -11
  10. package/dist/{campaign-create-LHL7FKQK.mjs → campaign-create-IXOWJQ4L.mjs} +3 -3
  11. package/dist/{campaign-detail-T3V6M3XE.mjs → campaign-detail-TFQCDDIN.mjs} +10 -10
  12. package/dist/{categories-metadata-V6FDXGSN.mjs → categories-metadata-7JFVYYUN.mjs} +10 -10
  13. package/dist/{category-create-ELMCLH4J.mjs → category-create-BTMZYQ5R.mjs} +5 -5
  14. package/dist/{category-detail-DNWTF4FV.mjs → category-detail-UUEMLEVJ.mjs} +14 -14
  15. package/dist/{category-edit-TYKLEYGE.mjs → category-edit-Q3KEELHO.mjs} +2 -2
  16. package/dist/{category-list-IJ3DLPYQ.mjs → category-list-Z6HS6N75.mjs} +5 -5
  17. package/dist/{category-organize-PDLC54E2.mjs → category-organize-45NPSRNG.mjs} +2 -2
  18. package/dist/{category-products-ATK63QHB.mjs → category-products-KW6X3JDW.mjs} +13 -13
  19. package/dist/{chunk-WPXYFJEP.mjs → chunk-2WLOIS3L.mjs} +1 -1
  20. package/dist/{chunk-UHIPGDJZ.mjs → chunk-35G7IXTE.mjs} +15 -15
  21. package/dist/{chunk-DODQ3KJT.mjs → chunk-3RRA56WC.mjs} +8 -3
  22. package/dist/{chunk-DKIUGYWW.mjs → chunk-3ZJ55SFA.mjs} +2 -2
  23. package/dist/{chunk-OXPE5TAY.mjs → chunk-42TMWI76.mjs} +1 -1
  24. package/dist/{chunk-OFN7DIZA.mjs → chunk-5AM254NB.mjs} +83 -3
  25. package/dist/{chunk-56TDUOXV.mjs → chunk-5N33TBBX.mjs} +1 -1
  26. package/dist/{chunk-5LGRZSEH.mjs → chunk-67RC6SEX.mjs} +1 -1
  27. package/dist/{chunk-O4RZ3Y65.mjs → chunk-7H6DB666.mjs} +1 -1
  28. package/dist/{chunk-5EGFR4EO.mjs → chunk-AGBHQZZT.mjs} +318 -236
  29. package/dist/{chunk-E3AFVPLW.mjs → chunk-BWU3ZE4W.mjs} +1 -1
  30. package/dist/{chunk-IKTS7EHT.mjs → chunk-D55WNQYO.mjs} +1 -1
  31. package/dist/{chunk-XDLBQGST.mjs → chunk-EFRTOOI5.mjs} +1 -1
  32. package/dist/{chunk-ETOJCN3Q.mjs → chunk-FJHAGJ5G.mjs} +1 -1
  33. package/dist/{chunk-K5QWNI6V.mjs → chunk-FNQ227BC.mjs} +1 -1
  34. package/dist/{chunk-A6PWH2CK.mjs → chunk-GHBURGZC.mjs} +1 -1
  35. package/dist/{chunk-4MG5LND4.mjs → chunk-HEYM67GY.mjs} +1 -1
  36. package/dist/{chunk-QHRVYT5N.mjs → chunk-HRSO6H4F.mjs} +3 -3
  37. package/dist/{chunk-REUYEF7L.mjs → chunk-MB7M5THW.mjs} +1 -1
  38. package/dist/{chunk-KLNRCI3K.mjs → chunk-MOGV3UZD.mjs} +1 -1
  39. package/dist/{chunk-3C6WQ7NH.mjs → chunk-NFEW5CVI.mjs} +37 -3
  40. package/dist/{chunk-VGXF4DOW.mjs → chunk-NKGKWMUU.mjs} +5 -5
  41. package/dist/{chunk-RLDK4LY5.mjs → chunk-NTYLG6Y3.mjs} +1 -1
  42. package/dist/{chunk-AF7A24XI.mjs → chunk-O5DGX2NZ.mjs} +1 -1
  43. package/dist/{chunk-T2ANPJ36.mjs → chunk-OMRGW7JS.mjs} +3 -3
  44. package/dist/{chunk-7V2JZU2B.mjs → chunk-P23S5LDK.mjs} +2 -2
  45. package/dist/{chunk-OAW7KLET.mjs → chunk-PPRHEG37.mjs} +2 -2
  46. package/dist/{chunk-AENRV3N7.mjs → chunk-QW4SQVMT.mjs} +109 -50
  47. package/dist/{chunk-MWBKAP7W.mjs → chunk-RNYL6AXZ.mjs} +2 -2
  48. package/dist/{chunk-KWP436SM.mjs → chunk-S3MMZPMX.mjs} +2 -2
  49. package/dist/{chunk-ND5YSIPU.mjs → chunk-SAZHCRHS.mjs} +1 -1
  50. package/dist/{chunk-M3CKVBZC.mjs → chunk-YGEJFHC3.mjs} +1 -1
  51. package/dist/chunk-ZHH3W7CN.mjs +171 -0
  52. package/dist/{collection-add-products-7WSD7YU4.mjs → collection-add-products-YSTEEHMF.mjs} +14 -14
  53. package/dist/{collection-create-I2A2X4VK.mjs → collection-create-RIGJHEX5.mjs} +2 -2
  54. package/dist/{collection-detail-NVE55BPK.mjs → collection-detail-P5JWWFHH.mjs} +14 -14
  55. package/dist/{collection-edit-RGH7NCUE.mjs → collection-edit-WX5G3FHR.mjs} +2 -2
  56. package/dist/{collection-list-SXHRKTIU.mjs → collection-list-PU6SWYVL.mjs} +24 -23
  57. package/dist/{collection-metadata-ZREV7BND.mjs → collection-metadata-R55DUZSX.mjs} +11 -11
  58. package/dist/{customer-detail-O4L55RY6.mjs → customer-detail-HVGU3DRM.mjs} +14 -14
  59. package/dist/{customer-group-detail-LSZA4ARM.mjs → customer-group-detail-QKFWIFYH.mjs} +13 -13
  60. package/dist/{customer-group-list-6JTEUJAC.mjs → customer-group-list-WLG2ZMBD.mjs} +13 -13
  61. package/dist/{customers-add-customer-group-MHJ34FDF.mjs → customers-add-customer-group-KL5UXXOR.mjs} +13 -13
  62. package/dist/{edit-inventory-item-LMDNUI6M.mjs → edit-inventory-item-O6JLGZE4.mjs} +1 -1
  63. package/dist/{edit-inventory-item-attributes-DPJIHBP3.mjs → edit-inventory-item-attributes-AUVR3GYY.mjs} +1 -1
  64. package/dist/{edit-reservation-IOOZBJ2T.mjs → edit-reservation-GQ6R6GVA.mjs} +2 -2
  65. package/dist/{edit-rules-CEE2IKS6.mjs → edit-rules-PJWEWMM7.mjs} +12 -12
  66. package/dist/en.json +49 -3
  67. package/dist/{inventory-create-H62EOWR6.mjs → inventory-create-P3WYAGQZ.mjs} +10 -10
  68. package/dist/{inventory-detail-ALOIH3H7.mjs → inventory-detail-C2NU7GTA.mjs} +10 -10
  69. package/dist/{inventory-list-RQBI7UJX.mjs → inventory-list-ADJQDNX5.mjs} +1 -1
  70. package/dist/{inventory-metadata-ICOCEY75.mjs → inventory-metadata-V2N3HOPG.mjs} +10 -10
  71. package/dist/{inventory-stock-LDEZTKU4.mjs → inventory-stock-5DCIGKBI.mjs} +10 -10
  72. package/dist/{location-detail-UNXAQQSZ.mjs → location-detail-2CJWVT5M.mjs} +15 -15
  73. package/dist/{location-fulfillment-providers-XVFFAB6I.mjs → location-fulfillment-providers-PYPUR74W.mjs} +15 -14
  74. package/dist/{location-sales-channels-UVYT52SH.mjs → location-sales-channels-JPH5BTUY.mjs} +3 -3
  75. package/dist/{location-service-zone-shipping-option-create-THNTZX5P.mjs → location-service-zone-shipping-option-create-HLZLP422.mjs} +11 -11
  76. package/dist/{location-service-zone-shipping-option-edit-TQNTCYII.mjs → location-service-zone-shipping-option-edit-OYTEZGGC.mjs} +4 -4
  77. package/dist/{login-EMANCYJH.mjs → login-AKO3BIQT.mjs} +10 -10
  78. package/dist/{manage-locations-2VDQ3ILT.mjs → manage-locations-ATCDVTSR.mjs} +1 -1
  79. package/dist/{order-allocate-items-FCJTB2IB.mjs → order-allocate-items-2H25GRTK.mjs} +3 -3
  80. package/dist/{order-create-claim-P5ADYS5P.mjs → order-create-claim-CWGDAFFU.mjs} +17 -17
  81. package/dist/{order-create-edit-CVPRRPOA.mjs → order-create-edit-KJODOQXN.mjs} +11 -11
  82. package/dist/{order-create-exchange-IHV6VKO5.mjs → order-create-exchange-TM4FQLKM.mjs} +23 -23
  83. package/dist/{order-create-fulfillment-SY6UM3NJ.mjs → order-create-fulfillment-2WJZPAWX.mjs} +14 -14
  84. package/dist/{order-create-refund-AGKPMCF6.mjs → order-create-refund-A6WKCHX7.mjs} +15 -15
  85. package/dist/{order-create-return-5UH7FN3H.mjs → order-create-return-NDKTI4E5.mjs} +5 -5
  86. package/dist/{order-create-shipment-J34CYL32.mjs → order-create-shipment-3AVEAGAY.mjs} +10 -10
  87. package/dist/{order-detail-EVDCA6UP.mjs → order-detail-7HXZEBWJ.mjs} +31 -31
  88. package/dist/{order-edit-billing-address-JH3XNOCQ.mjs → order-edit-billing-address-DPK7HTLM.mjs} +10 -10
  89. package/dist/{order-edit-email-KV2IHQRT.mjs → order-edit-email-UJ2OUKHJ.mjs} +10 -10
  90. package/dist/{order-edit-shipping-address-WMNNU53B.mjs → order-edit-shipping-address-5ZCGHHZE.mjs} +10 -10
  91. package/dist/{order-list-26YQAIRH.mjs → order-list-5C4TVJRH.mjs} +4 -4
  92. package/dist/{order-metadata-F4LZ73LR.mjs → order-metadata-UKTGLYWR.mjs} +10 -10
  93. package/dist/{order-receive-return-LSMD7POH.mjs → order-receive-return-N7VLM2GX.mjs} +11 -11
  94. package/dist/{order-request-transfer-A3EBBZ5N.mjs → order-request-transfer-5ENT7IOT.mjs} +11 -11
  95. package/dist/{price-list-configuration-2G3WFC3J.mjs → price-list-configuration-SS2VMD4N.mjs} +4 -4
  96. package/dist/{price-list-create-RLT7G7KF.mjs → price-list-create-FF4F6M2A.mjs} +17 -17
  97. package/dist/{price-list-detail-TKRELOK2.mjs → price-list-detail-HQF4ZR2U.mjs} +17 -17
  98. package/dist/{price-list-edit-6URYI6AK.mjs → price-list-edit-VRI5T4W3.mjs} +2 -2
  99. package/dist/{price-list-list-FLINOQCK.mjs → price-list-list-S2HWTXKV.mjs} +3 -3
  100. package/dist/{price-list-prices-add-UPUY72HG.mjs → price-list-prices-add-JYZAHKAQ.mjs} +13 -13
  101. package/dist/{price-list-prices-edit-ZHAQDPWX.mjs → price-list-prices-edit-TRCLLGU4.mjs} +2 -2
  102. package/dist/{product-attributes-ZR63AQWA.mjs → product-attributes-NEXVST24.mjs} +12 -12
  103. package/dist/{product-create-EQ6SN5QT.mjs → product-create-WU4YFCMM.mjs} +377 -554
  104. package/dist/{product-create-variant-7C5PKKX7.mjs → product-create-variant-RDEE4IX7.mjs} +11 -11
  105. package/dist/{product-detail-ATPFDPI2.mjs → product-detail-J4JYWH2M.mjs} +38 -54
  106. package/dist/{product-edit-XPUNYMD7.mjs → product-edit-ZF2WYHPB.mjs} +12 -12
  107. package/dist/{product-export-GFLEIKIM.mjs → product-export-QDX6343F.mjs} +23 -22
  108. package/dist/{product-image-variants-edit-TC3M4PGX.mjs → product-image-variants-edit-5L5J32SO.mjs} +10 -10
  109. package/dist/{product-import-2Z5I7RXI.mjs → product-import-6TEVSKGQ.mjs} +10 -10
  110. package/dist/{product-list-33ANLONH.mjs → product-list-BHGGJX6B.mjs} +17 -17
  111. package/dist/{product-media-WCLPCVR3.mjs → product-media-EKXMOSO4.mjs} +2 -2
  112. package/dist/{product-metadata-GQU7EVZ3.mjs → product-metadata-BCJJNWAC.mjs} +10 -10
  113. package/dist/product-option-create-3Z73MSHD.mjs +336 -0
  114. package/dist/product-option-detail-4VRUA7KT.mjs +322 -0
  115. package/dist/product-option-edit-YIKFL6OY.mjs +324 -0
  116. package/dist/product-option-list-CR7NCCMH.mjs +267 -0
  117. package/dist/product-option-metadata-7CSZUQ7M.mjs +71 -0
  118. package/dist/product-options-manage-QOMXMPGW.mjs +304 -0
  119. package/dist/{product-organization-T2TQ5EH6.mjs → product-organization-IG54OB75.mjs} +14 -14
  120. package/dist/{product-prices-MKMKBH6P.mjs → product-prices-UMEIS5AZ.mjs} +1 -1
  121. package/dist/{product-sales-channels-5YIO22UW.mjs → product-sales-channels-2SALTLTF.mjs} +3 -3
  122. package/dist/{product-shipping-profile-PL76UMVZ.mjs → product-shipping-profile-VPHZLKDT.mjs} +13 -13
  123. package/dist/{product-stock-6QHBTDUQ.mjs → product-stock-3ILUPCVN.mjs} +10 -10
  124. package/dist/{product-tag-create-B6EOKDJT.mjs → product-tag-create-OOUTLHHD.mjs} +10 -10
  125. package/dist/{product-tag-detail-TQP7ZWSR.mjs → product-tag-detail-YVKJEAKT.mjs} +28 -27
  126. package/dist/{product-tag-edit-RPLWDG5A.mjs → product-tag-edit-RV5WITSN.mjs} +10 -10
  127. package/dist/{product-tag-list-PZTGHM7M.mjs → product-tag-list-ZSPFYZIL.mjs} +26 -25
  128. package/dist/{product-tag-metadata-FKKOT5CD.mjs → product-tag-metadata-S5YL3FUL.mjs} +10 -10
  129. package/dist/{product-type-detail-DDIBFR7O.mjs → product-type-detail-EFVZRETM.mjs} +13 -13
  130. package/dist/{product-type-metadata-EXCYTTQG.mjs → product-type-metadata-TNAASDKX.mjs} +10 -10
  131. package/dist/{product-variant-detail-GCESZH4H.mjs → product-variant-detail-CLP5FJP6.mjs} +10 -10
  132. package/dist/{product-variant-edit-JHOQJN6U.mjs → product-variant-edit-REMB77V7.mjs} +11 -11
  133. package/dist/{product-variant-manage-inventory-items-B7TUBSD5.mjs → product-variant-manage-inventory-items-IGDCLZQE.mjs} +2 -2
  134. package/dist/{product-variant-media-6WWLRINP.mjs → product-variant-media-EKI4BTEV.mjs} +1 -1
  135. package/dist/{product-variant-metadata-NEZIGTEP.mjs → product-variant-metadata-5JIY5KLN.mjs} +10 -10
  136. package/dist/{promotion-add-campaign-MKDYE7MW.mjs → promotion-add-campaign-DOALJUKJ.mjs} +3 -3
  137. package/dist/{promotion-create-CUAQY2NH.mjs → promotion-create-2PTB6NQI.mjs} +18 -18
  138. package/dist/{promotion-detail-2S7FWTXF.mjs → promotion-detail-RGXCA2XS.mjs} +10 -10
  139. package/dist/{refund-reason-create-4YAO4325.mjs → refund-reason-create-AGEFXEIZ.mjs} +10 -10
  140. package/dist/{refund-reason-edit-5J2VIRIL.mjs → refund-reason-edit-DL56EKBY.mjs} +10 -10
  141. package/dist/{refund-reason-list-453DXONV.mjs → refund-reason-list-RL2ZG7IJ.mjs} +13 -13
  142. package/dist/{region-create-QLPSK6TX.mjs → region-create-UVJICJRX.mjs} +1 -1
  143. package/dist/{region-edit-JCJHA6TY.mjs → region-edit-3NVXQECN.mjs} +1 -1
  144. package/dist/{region-metadata-C7DIBM35.mjs → region-metadata-2HO3SAPM.mjs} +10 -10
  145. package/dist/{reservation-create-BW4CDTWR.mjs → reservation-create-Z7TWUE2L.mjs} +3 -3
  146. package/dist/{reservation-detail-GFNWLSI2.mjs → reservation-detail-2AOBK5EY.mjs} +10 -10
  147. package/dist/{reservation-list-RGL67CIU.mjs → reservation-list-MN22JYAW.mjs} +2 -2
  148. package/dist/{reservation-metadata-OI2G4BDW.mjs → reservation-metadata-BFPJTXK6.mjs} +10 -10
  149. package/dist/{sales-channel-add-products-63NGB37Z.mjs → sales-channel-add-products-4LNP2TUM.mjs} +13 -13
  150. package/dist/{sales-channel-create-TOBEDYFD.mjs → sales-channel-create-UFFXX5HK.mjs} +2 -2
  151. package/dist/{sales-channel-detail-LJPQAJDT.mjs → sales-channel-detail-UMYMS2JA.mjs} +13 -13
  152. package/dist/{sales-channel-edit-XUTE5GB5.mjs → sales-channel-edit-SP2HF4E3.mjs} +2 -2
  153. package/dist/{sales-channel-list-TBAN7UT6.mjs → sales-channel-list-CV4V6R7H.mjs} +11 -11
  154. package/dist/{sales-channel-metadata-SE4TGSDB.mjs → sales-channel-metadata-REOQHHUT.mjs} +10 -10
  155. package/dist/{shipping-option-type-create-MB4ENYKV.mjs → shipping-option-type-create-XAWQO66M.mjs} +10 -10
  156. package/dist/{shipping-option-type-detail-IX4JGSTK.mjs → shipping-option-type-detail-G4WLGIAA.mjs} +11 -11
  157. package/dist/{shipping-option-type-edit-B5KU5LER.mjs → shipping-option-type-edit-OI6TBKGG.mjs} +10 -10
  158. package/dist/{shipping-option-type-list-TVR5OE2C.mjs → shipping-option-type-list-6GNCKAFB.mjs} +11 -11
  159. package/dist/{shipping-profile-metadata-Z35SYLBS.mjs → shipping-profile-metadata-MANQ7ZEI.mjs} +10 -10
  160. package/dist/{store-detail-VUJSSOKZ.mjs → store-detail-N2CP3MTB.mjs} +10 -10
  161. package/dist/{store-edit-3XS6IC2Z.mjs → store-edit-Q25HCMCQ.mjs} +1 -1
  162. package/dist/{store-metadata-TYFTDOEK.mjs → store-metadata-U22TVWK2.mjs} +10 -10
  163. package/dist/{tax-region-create-ZTCTKE4C.mjs → tax-region-create-JZB7NFIG.mjs} +11 -11
  164. package/dist/{tax-region-detail-MHM4MAOS.mjs → tax-region-detail-CBZ3ZJN2.mjs} +29 -28
  165. package/dist/{tax-region-edit-SFJGFTAV.mjs → tax-region-edit-E56XVHW2.mjs} +11 -11
  166. package/dist/{tax-region-province-detail-VMOV4JPV.mjs → tax-region-province-detail-2DC2U4EN.mjs} +29 -28
  167. package/dist/{tax-region-tax-override-create-GRXLTURD.mjs → tax-region-tax-override-create-JWGWGYB4.mjs} +28 -27
  168. package/dist/{tax-region-tax-override-edit-D2YBOBEI.mjs → tax-region-tax-override-edit-7DCU55AS.mjs} +27 -26
  169. package/dist/{user-detail-N6PT3KRP.mjs → user-detail-K5UMPO2L.mjs} +1 -1
  170. package/dist/{user-metadata-D5HNZWZY.mjs → user-metadata-EX5WDGCR.mjs} +10 -10
  171. package/dist/{workflow-execution-detail-GSUDCTN3.mjs → workflow-execution-detail-GBPFVG3O.mjs} +10 -10
  172. package/package.json +9 -9
  173. package/src/components/inputs/combobox/combobox.tsx +173 -92
  174. package/src/components/layout/main-layout/main-layout.tsx +7 -4
  175. package/src/dashboard-app/routes/get-route.map.tsx +64 -12
  176. package/src/hooks/api/index.ts +1 -0
  177. package/src/hooks/api/product-options.tsx +151 -0
  178. package/src/hooks/api/products.tsx +26 -66
  179. package/src/hooks/table/columns/use-product-option-table-columns.tsx +44 -0
  180. package/src/hooks/table/filters/index.ts +1 -0
  181. package/src/hooks/table/filters/use-product-option-table-filters.tsx +33 -0
  182. package/src/hooks/table/query/use-product-option-table-query.tsx +34 -0
  183. package/src/i18n/translations/$schema.json +171 -4
  184. package/src/i18n/translations/en.json +49 -3
  185. package/src/routes/product-options/common/hooks/use-delete-product-option-action.tsx +41 -0
  186. package/src/routes/product-options/product-option-create/components/create-product-option-form/create-product-option-details.tsx +71 -0
  187. package/src/routes/product-options/product-option-create/components/create-product-option-form/create-product-option-form.tsx +192 -0
  188. package/src/routes/product-options/product-option-create/components/create-product-option-form/create-product-option-organize.tsx +77 -0
  189. package/src/routes/product-options/product-option-create/components/create-product-option-form/index.ts +1 -0
  190. package/src/routes/product-options/product-option-create/components/create-product-option-form/schema.ts +15 -0
  191. package/src/routes/product-options/product-option-create/index.ts +1 -0
  192. package/src/routes/product-options/product-option-create/product-option-create.tsx +10 -0
  193. package/src/routes/product-options/product-option-detail/breadcrumb.tsx +14 -0
  194. package/src/routes/product-options/product-option-detail/components/product-option-general-section/index.ts +1 -0
  195. package/src/routes/product-options/product-option-detail/components/product-option-general-section/product-option-general-section.tsx +81 -0
  196. package/src/routes/product-options/product-option-detail/components/product-option-product-section/index.ts +1 -0
  197. package/src/routes/product-options/product-option-detail/components/product-option-product-section/product-option-product-section.tsx +74 -0
  198. package/src/routes/product-options/product-option-detail/index.ts +3 -0
  199. package/src/routes/product-options/product-option-detail/loader.ts +17 -0
  200. package/src/routes/product-options/product-option-detail/product-option-detail.tsx +50 -0
  201. package/src/routes/product-options/product-option-edit/components/edit-product-option-form/edit-product-option-details.tsx +94 -0
  202. package/src/routes/product-options/product-option-edit/components/edit-product-option-form/edit-product-option-form.tsx +116 -0
  203. package/src/routes/product-options/product-option-edit/components/edit-product-option-form/edit-product-option-organize.tsx +77 -0
  204. package/src/routes/product-options/product-option-edit/components/edit-product-option-form/index.ts +1 -0
  205. package/src/routes/product-options/product-option-edit/components/edit-product-option-form/schema.ts +13 -0
  206. package/src/routes/product-options/product-option-edit/index.ts +1 -0
  207. package/src/routes/product-options/product-option-edit/product-option-edit.tsx +34 -0
  208. package/src/routes/product-options/product-option-list/components/product-option-list-table/index.ts +1 -0
  209. package/src/routes/product-options/product-option-list/components/product-option-list-table/product-option-list-table.tsx +140 -0
  210. package/src/routes/product-options/product-option-list/index.ts +1 -0
  211. package/src/routes/product-options/product-option-list/product-option-list.tsx +19 -0
  212. package/src/routes/product-options/product-option-metadata/index.ts +1 -0
  213. package/src/routes/product-options/product-option-metadata/product-option-metadata.tsx +27 -0
  214. package/src/routes/products/product-create/components/product-create-details-form/components/product-create-details-general-section/product-create-general-section.tsx +16 -4
  215. package/src/routes/products/product-create/components/product-create-details-form/components/product-create-details-variant-section/product-create-details-variant-section.tsx +220 -198
  216. package/src/routes/products/product-create/components/product-create-form/product-create-form.tsx +4 -7
  217. package/src/routes/products/product-create/constants.ts +2 -0
  218. package/src/routes/products/product-create/utils.ts +6 -1
  219. package/src/routes/products/product-detail/components/product-option-section/product-option-section.tsx +31 -49
  220. package/src/routes/products/product-options-manage/components/product-options-manage-form/index.ts +1 -0
  221. package/src/routes/products/product-options-manage/components/product-options-manage-form/product-options-manage-form.tsx +284 -0
  222. package/src/routes/products/product-options-manage/index.ts +1 -0
  223. package/src/routes/products/product-options-manage/product-options-manage.tsx +35 -0
  224. package/dist/product-create-option-GAEPSU6J.mjs +0 -145
  225. package/dist/product-edit-option-VIU3ZICO.mjs +0 -150
  226. package/src/routes/products/product-create-option/components/create-product-option-form/create-product-option-form.tsx +0 -122
  227. package/src/routes/products/product-create-option/components/create-product-option-form/index.ts +0 -1
  228. package/src/routes/products/product-create-option/index.ts +0 -1
  229. package/src/routes/products/product-create-option/product-create-option.tsx +0 -26
  230. package/src/routes/products/product-edit-option/components/edit-product-option-form/edit-product-option-form.tsx +0 -123
  231. package/src/routes/products/product-edit-option/components/edit-product-option-form/index.ts +0 -1
  232. package/src/routes/products/product-edit-option/index.ts +0 -1
  233. package/src/routes/products/product-edit-option/product-edit-option.tsx +0 -32
  234. package/dist/{chunk-ACJ3PPQJ.mjs → chunk-2QH2TBJ2.mjs} +3 -3
  235. package/dist/{customer-group-add-customers-QU4Q56SS.mjs → customer-group-add-customers-2Y2GVCDV.mjs} +3 -3
  236. package/dist/{customer-list-ZXCGIXJC.mjs → customer-list-TG4D4QOT.mjs} +3 -3
  237. package/dist/{location-list-OYBI7EGV.mjs → location-list-ZJMZZ6T3.mjs} +1 -1
  238. package/dist/{product-type-list-QX7QC6RI.mjs → product-type-list-7WQ5D2KV.mjs} +3 -3
  239. package/dist/{region-list-XQRIBDMF.mjs → region-list-JAQXIBYD.mjs} +3 -3
  240. package/dist/{return-reason-list-VYLLXDG4.mjs → return-reason-list-ATE2XU4H.mjs} +3 -3
  241. package/dist/{user-list-6KATHOTJ.mjs → user-list-KPI3BTOA.mjs} +3 -3
@@ -1,32 +1,30 @@
1
- import { XMarkMini } from "@medusajs/icons"
2
1
  import {
3
2
  Alert,
4
- Button,
5
3
  Checkbox,
6
4
  clx,
7
5
  Heading,
8
6
  Hint,
9
- IconButton,
10
7
  InlineTip,
11
- Input,
12
8
  Label,
13
9
  Text,
14
10
  } from "@medusajs/ui"
15
11
  import {
16
- Controller,
17
12
  FieldArrayWithId,
18
13
  useFieldArray,
19
14
  UseFormReturn,
20
15
  useWatch,
21
16
  } from "react-hook-form"
22
17
  import { useTranslation } from "react-i18next"
18
+ import { useMemo, useState } from "react"
23
19
 
24
20
  import { Form } from "../../../../../../../components/common/form"
25
21
  import { SortableList } from "../../../../../../../components/common/sortable-list"
26
22
  import { SwitchBox } from "../../../../../../../components/common/switch-box"
27
- import { ChipInput } from "../../../../../../../components/inputs/chip-input"
23
+ import { Combobox } from "../../../../../../../components/inputs/combobox"
28
24
  import { ProductCreateSchemaType } from "../../../../types"
29
25
  import { decorateVariantsWithDefaultValues } from "../../../../utils"
26
+ import { useProductOptions } from "../../../../../../../hooks/api"
27
+ import { AdminProductOption } from "@medusajs/types"
30
28
 
31
29
  type ProductCreateVariantsSectionProps = {
32
30
  form: UseFormReturn<ProductCreateSchemaType>
@@ -65,11 +63,6 @@ export const ProductCreateVariantsSection = ({
65
63
  }: ProductCreateVariantsSectionProps) => {
66
64
  const { t } = useTranslation()
67
65
 
68
- const options = useFieldArray({
69
- control: form.control,
70
- name: "options",
71
- })
72
-
73
66
  const variants = useFieldArray({
74
67
  control: form.control,
75
68
  name: "variants",
@@ -97,90 +90,173 @@ export const ProductCreateVariantsSection = ({
97
90
  const showInvalidVariantsMessage =
98
91
  form.formState.errors.variants?.root?.message === "invalid_length"
99
92
 
100
- const handleOptionValueUpdate = (index: number, value: string[]) => {
101
- const { isTouched: hasUserSelectedVariants } =
102
- form.getFieldState("variants")
103
-
104
- const newOptions = [...watchedOptions]
105
- newOptions[index].values = value
93
+ const { product_options = [], isLoading } = useProductOptions({
94
+ is_exclusive: false,
95
+ })
106
96
 
107
- const permutations = getPermutations(
108
- newOptions.filter(({ values }) => values.length)
97
+ const productOptionChoices = useMemo(() => {
98
+ return product_options.map((option) => ({
99
+ value: option.id,
100
+ label: option.title,
101
+ }))
102
+ }, [product_options])
103
+
104
+ const [selectedOptionIds, setSelectedOptionIds] = useState<string[]>([])
105
+ const [selectedOptionValues, setSelectedOptionValues] = useState<
106
+ Record<string, string[]>
107
+ >({})
108
+ const [customValues, setCustomValues] = useState<
109
+ Record<string, Array<{ id: string; value: string; rank: number }>>
110
+ >({})
111
+
112
+ const handleProductOptionSelect = (optionIds: string[]) => {
113
+ setSelectedOptionIds(optionIds)
114
+
115
+ // Initialize selected values for new options (select all by default)
116
+ const newSelectedValues: Record<string, string[]> = {}
117
+ const selectedProductOptions = product_options.filter((option) =>
118
+ optionIds.includes(option.id)
109
119
  )
110
- const oldVariants = [...watchedVariants]
111
120
 
112
- const findMatchingPermutation = (options: Record<string, string>) => {
113
- return permutations.find((permutation) =>
114
- Object.keys(options).every((key) => options[key] === permutation[key])
115
- )
116
- }
121
+ selectedProductOptions.forEach((option) => {
122
+ // If option was already selected, keep its current value selection
123
+ if (selectedOptionValues[option.id]) {
124
+ newSelectedValues[option.id] = selectedOptionValues[option.id]
125
+ } else {
126
+ // New option - select all values by default
127
+ newSelectedValues[option.id] = option.values?.map((v) => v.id) || []
128
+ }
129
+ })
117
130
 
118
- const newVariants = oldVariants.reduce((variants, variant) => {
119
- const match = findMatchingPermutation(variant.options)
131
+ setSelectedOptionValues(newSelectedValues)
132
+ updateFormWithSelectedValues(selectedProductOptions, newSelectedValues)
133
+ }
120
134
 
121
- if (match) {
122
- variants.push({
123
- ...variant,
124
- title: getVariantName(match),
125
- options: match,
126
- })
135
+ const handleValueChange = (optionId: string, valueIds: string[]) => {
136
+ // Ensure at least one value is selected
137
+ if (valueIds.length === 0) {
138
+ return
139
+ }
140
+
141
+ // Detect new custom values that aren't in the options yet
142
+ const allValues = getAllValuesForOption(optionId)
143
+ const existingValueIds = new Set(allValues.map((v) => v.id))
144
+
145
+ const validValueIds: string[] = []
146
+ const newCustomValues: string[] = []
147
+ valueIds.forEach((id) => {
148
+ if (existingValueIds.has(id)) {
149
+ validValueIds.push(id)
150
+ } else {
151
+ newCustomValues.push(id)
127
152
  }
153
+ })
128
154
 
129
- return variants
130
- }, [] as typeof oldVariants)
155
+ let updatedCustomValues = customValues
156
+ const updatedValidValueIds = [...validValueIds]
157
+ newCustomValues.forEach((newValue) => {
158
+ const tempId = `custom-${Date.now()}-${Math.random()}-${newValue}`
131
159
 
132
- const usedPermutations = new Set(
133
- newVariants.map((variant) => variant.options)
134
- )
135
- const unusedPermutations = permutations.filter(
136
- (permutation) => !usedPermutations.has(permutation)
137
- )
160
+ const existingCustom = updatedCustomValues[optionId] || []
161
+ const option = product_options.find((opt) => opt.id === optionId)
162
+ const existingValuesCount =
163
+ (option?.values?.length || 0) + existingCustom.length
164
+
165
+ const newCustomValue = {
166
+ id: tempId,
167
+ value: newValue,
168
+ rank: existingValuesCount + newCustomValues.indexOf(newValue),
169
+ }
138
170
 
139
- unusedPermutations.forEach((permutation) => {
140
- newVariants.push({
141
- title: getVariantName(permutation),
142
- options: permutation,
143
- should_create: hasUserSelectedVariants ? false : true,
144
- variant_rank: newVariants.length,
145
- // NOTE - prepare inventory array here for now so we prevent rendering issue if we append the items later
146
- inventory: [{ inventory_item_id: "", required_quantity: "" }],
147
- })
171
+ updatedCustomValues = {
172
+ ...updatedCustomValues,
173
+ [optionId]: [...(updatedCustomValues[optionId] || []), newCustomValue],
174
+ }
175
+
176
+ updatedValidValueIds.push(tempId)
148
177
  })
149
178
 
150
- form.setValue("variants", newVariants)
151
- }
179
+ if (newCustomValues.length > 0) {
180
+ setCustomValues(updatedCustomValues)
181
+ }
152
182
 
153
- const handleRemoveOption = (index: number) => {
154
- if (index === 0) {
155
- return
183
+ const updatedSelectedValues = {
184
+ ...selectedOptionValues,
185
+ [optionId]: updatedValidValueIds,
156
186
  }
157
187
 
158
- options.remove(index)
188
+ setSelectedOptionValues(updatedSelectedValues)
159
189
 
160
- const newOptions = [...watchedOptions]
161
- newOptions.splice(index, 1)
162
- const validOptionTitles = new Set(newOptions.map((option) => option.title))
190
+ const selectedProductOptions = product_options.filter((option) =>
191
+ selectedOptionIds.includes(option.id)
192
+ )
193
+ updateFormWithSelectedValues(
194
+ selectedProductOptions,
195
+ updatedSelectedValues,
196
+ newCustomValues.length > 0 ? updatedCustomValues : undefined
197
+ )
198
+ }
163
199
 
164
- const permutations = getPermutations(newOptions)
165
- const oldVariants = [...watchedVariants]
200
+ const getAllValuesForOption = (
201
+ optionId: string,
202
+ customVals?: Record<
203
+ string,
204
+ Array<{ id: string; value: string; rank: number }>
205
+ >
206
+ ) => {
207
+ const option = product_options.find((opt) => opt.id === optionId)
208
+ const existingValues = option?.values || []
209
+ const customForOption = (customVals || customValues)[optionId] || []
166
210
 
167
- const newVariants = permutations.reduce((variants, permutation) => {
168
- const variant = oldVariants.find(({ options }) =>
169
- Object.keys(options)
170
- .filter((option) => validOptionTitles.has(option))
171
- .every((key) => options[key] === permutation[key])
172
- )
211
+ return [...existingValues, ...customForOption]
212
+ }
173
213
 
174
- if (variant) {
175
- variants.push({
176
- ...variant,
177
- title: variant.title,
178
- options: permutation,
214
+ const updateFormWithSelectedValues = (
215
+ selectedProductOptions: AdminProductOption[],
216
+ valueSelections: Record<string, string[]>,
217
+ customVals?: Record<
218
+ string,
219
+ Array<{
220
+ id: string
221
+ value: string
222
+ rank: number
223
+ }>
224
+ >
225
+ ) => {
226
+ const newOptions = selectedProductOptions.map((option) => {
227
+ const selectedValueIds = valueSelections[option.id] || []
228
+ const allValues = getAllValuesForOption(option.id, customVals)
229
+
230
+ const selectedValues = allValues
231
+ .filter((v) => selectedValueIds.includes(v.id))
232
+ .sort((a, b) => {
233
+ const rankA = a.rank ?? Number.MAX_VALUE
234
+ const rankB = b.rank ?? Number.MAX_VALUE
235
+ return rankA - rankB
179
236
  })
237
+ .map((v) => v.value)
238
+
239
+ return {
240
+ id: option.id,
241
+ title: option.title,
242
+ values: selectedValues,
243
+ value_ids: selectedValueIds,
180
244
  }
245
+ })
181
246
 
182
- return variants
183
- }, [] as typeof oldVariants)
247
+ form.setValue("options", newOptions)
248
+
249
+ const permutations = getPermutations(
250
+ newOptions.filter(({ values }) => values.length)
251
+ )
252
+
253
+ const newVariants = permutations.map((permutation, index) => ({
254
+ title: getVariantName(permutation),
255
+ options: permutation,
256
+ should_create: true,
257
+ variant_rank: index,
258
+ inventory: [{ inventory_item_id: "", required_quantity: "" }],
259
+ }))
184
260
 
185
261
  form.setValue("variants", newVariants)
186
262
  }
@@ -289,138 +365,84 @@ export const ProductCreateVariantsSection = ({
289
365
  } else {
290
366
  createDefaultOptionAndVariant()
291
367
  }
368
+ setSelectedOptionIds([])
369
+ setSelectedOptionValues({})
370
+ setCustomValues({})
292
371
  }}
293
372
  />
294
373
  </div>
295
374
  {watchedAreVariantsEnabled && (
296
375
  <>
297
376
  <div className="flex flex-col gap-y-6">
298
- <Form.Field
299
- control={form.control}
300
- name="options"
301
- render={() => {
302
- return (
303
- <Form.Item>
304
- <div className="flex flex-col gap-y-6">
305
- <div className="flex items-start justify-between gap-x-4">
306
- <div className="flex flex-col">
307
- <Form.Label>
308
- {t("products.create.variants.productOptions.label")}
309
- </Form.Label>
310
- <Form.Hint>
311
- {t("products.create.variants.productOptions.hint")}
312
- </Form.Hint>
313
- </div>
314
- <Button
315
- size="small"
316
- variant="secondary"
317
- type="button"
318
- onClick={() => {
319
- options.append({
320
- title: "",
321
- values: [],
322
- })
323
- }}
324
- >
325
- {t("actions.add")}
326
- </Button>
327
- </div>
328
- {showInvalidOptionsMessage && (
329
- <Alert dismissible variant="error">
330
- {t("products.create.errors.options")}
331
- </Alert>
332
- )}
333
- <ul className="flex flex-col gap-y-4">
334
- {options.fields.map((option, index) => {
335
- const hasError =
336
- !!form.formState.errors.options?.[index]
337
- return (
338
- <li
339
- key={option.id}
340
- className={clx(
341
- "bg-ui-bg-component shadow-elevation-card-rest grid grid-cols-[1fr_28px] items-center gap-1.5 rounded-xl p-1.5",
342
- {
343
- "border-ui-border-error shadow-borders-error":
344
- hasError,
345
- }
346
- )}
347
- >
348
- <div className="grid grid-cols-[min-content,1fr] items-center gap-1.5">
349
- <div className="flex items-center px-2 py-1.5">
350
- <Label
351
- size="xsmall"
352
- weight="plus"
353
- className="text-ui-fg-subtle"
354
- htmlFor={`options.${index}.title`}
355
- >
356
- {t("fields.title")}
357
- </Label>
358
- </div>
359
- <Input
360
- className="bg-ui-bg-field-component hover:bg-ui-bg-field-component-hover"
361
- {...form.register(
362
- `options.${index}.title` as const
363
- )}
364
- placeholder={t(
365
- "products.fields.options.optionTitlePlaceholder"
366
- )}
367
- />
368
- <div className="flex items-center px-2 py-1.5">
369
- <Label
370
- size="xsmall"
371
- weight="plus"
372
- className="text-ui-fg-subtle"
373
- htmlFor={`options.${index}.values`}
374
- >
375
- {t("fields.values")}
376
- </Label>
377
- </div>
378
- <Controller
379
- control={form.control}
380
- name={`options.${index}.values` as const}
381
- render={({
382
- field: { onChange, ...field },
383
- }) => {
384
- const handleValueChange = (
385
- value: string[]
386
- ) => {
387
- handleOptionValueUpdate(index, value)
388
- onChange(value)
389
- }
390
-
391
- return (
392
- <ChipInput
393
- {...field}
394
- variant="contrast"
395
- onChange={handleValueChange}
396
- placeholder={t(
397
- "products.fields.options.variantionsPlaceholder"
398
- )}
399
- />
400
- )
401
- }}
402
- />
403
- </div>
404
- <IconButton
405
- type="button"
406
- size="small"
407
- variant="transparent"
408
- className="text-ui-fg-muted"
409
- disabled={index === 0}
410
- onClick={() => handleRemoveOption(index)}
411
- >
412
- <XMarkMini />
413
- </IconButton>
414
- </li>
415
- )
416
- })}
417
- </ul>
418
- </div>
419
- </Form.Item>
420
- )
421
- }}
377
+ <div className="flex flex-col">
378
+ <Label weight="plus">
379
+ {t("products.create.variants.productOptions.label")}
380
+ </Label>
381
+ <Hint>{t("products.create.variants.productOptions.hint")}</Hint>
382
+ </div>
383
+ {showInvalidOptionsMessage && (
384
+ <Alert dismissible variant="error">
385
+ {t("products.create.errors.options")}
386
+ </Alert>
387
+ )}
388
+ <Combobox
389
+ value={selectedOptionIds}
390
+ onChange={(value) => handleProductOptionSelect(value as string[])}
391
+ options={productOptionChoices}
392
+ placeholder={t("products.fields.options.optionTitlePlaceholder")}
393
+ disabled={isLoading}
394
+ displayMode="chips"
422
395
  />
423
396
  </div>
397
+ {selectedOptionIds.length > 0 && (
398
+ <div className="flex flex-col gap-y-4">
399
+ <div className="flex flex-col">
400
+ <Label weight="plus">{t("fields.values")}</Label>
401
+ <Hint>{t("products.create.variants.selectValuesHint")}</Hint>
402
+ </div>
403
+ <div className="flex flex-col gap-y-3">
404
+ {product_options
405
+ .filter((option) => selectedOptionIds.includes(option.id))
406
+ .map((option) => {
407
+ // Get all values (existing + custom) for this option
408
+ const allValues = getAllValuesForOption(option.id)
409
+
410
+ const valueOptions = allValues
411
+ .sort((a, b) => {
412
+ const rankA = a.rank ?? Number.MAX_VALUE
413
+ const rankB = b.rank ?? Number.MAX_VALUE
414
+ return rankA - rankB
415
+ })
416
+ .map((v) => ({
417
+ value: v.id,
418
+ label: v.value,
419
+ }))
420
+
421
+ return (
422
+ <div key={option.id} className="flex flex-col gap-y-2">
423
+ <Label size="small" weight="plus">
424
+ {option.title}
425
+ </Label>
426
+ <Combobox
427
+ value={selectedOptionValues[option.id] || []}
428
+ onChange={(value) =>
429
+ handleValueChange(option.id, value as string[])
430
+ }
431
+ onCreateOption={(_) => {
432
+ // Todo
433
+ }}
434
+ options={valueOptions}
435
+ placeholder={t(
436
+ "products.fields.options.variantionsPlaceholder"
437
+ )}
438
+ displayMode="chips"
439
+ />
440
+ </div>
441
+ )
442
+ })}
443
+ </div>
444
+ </div>
445
+ )}
424
446
  <div className="grid grid-cols-1 gap-x-4 gap-y-8">
425
447
  <div className="flex flex-col gap-y-6">
426
448
  <div className="flex flex-col">
@@ -78,13 +78,10 @@ export const ProductCreateForm = ({
78
78
  return {}
79
79
  }
80
80
 
81
- return regions.reduce(
82
- (acc, reg) => {
83
- acc[reg.id] = reg.currency_code
84
- return acc
85
- },
86
- {} as Record<string, string>
87
- )
81
+ return regions.reduce((acc, reg) => {
82
+ acc[reg.id] = reg.currency_code
83
+ return acc
84
+ }, {} as Record<string, string>)
88
85
  }, [regions])
89
86
 
90
87
  /**
@@ -47,8 +47,10 @@ export type ProductCreateVariantSchema = z.infer<
47
47
  >
48
48
 
49
49
  const ProductCreateOptionSchema = z.object({
50
+ id: z.string().optional(),
50
51
  title: z.string(),
51
52
  values: z.array(z.string()).min(1),
53
+ value_ids: z.array(z.string()).optional(),
52
54
  })
53
55
 
54
56
  export type ProductCreateOptionSchema = z.infer<
@@ -13,6 +13,8 @@ export const normalizeProductFormValues = (
13
13
  ?.filter((media) => !media.isThumbnail)
14
14
  .map((media) => ({ url: media.url }))
15
15
 
16
+ const options = values.options.filter((o) => o.title) // clean temp. values
17
+
16
18
  return {
17
19
  status: values.status,
18
20
  is_giftcard: false,
@@ -41,7 +43,10 @@ export const normalizeProductFormValues = (
41
43
  length: values.length ? parseFloat(values.length) : undefined,
42
44
  height: values.height ? parseFloat(values.height) : undefined,
43
45
  weight: values.weight ? parseFloat(values.weight) : undefined,
44
- options: values.options.filter((o) => o.title), // clean temp. values
46
+ options: options.map((option) => {
47
+ const { id, value_ids, ...rest } = option
48
+ return id ? { id, value_ids } : { ...rest, is_exclusive: true }
49
+ }),
45
50
  variants: normalizeVariants(
46
51
  values.variants.filter((variant) => variant.should_create),
47
52
  values.regionsCurrencyMap
@@ -1,38 +1,16 @@
1
- import { PencilSquare, Plus, Trash } from "@medusajs/icons"
2
- import { Badge, Container, Heading, usePrompt } from "@medusajs/ui"
1
+ import { PencilSquare } from "@medusajs/icons"
2
+ import { Badge, Container, Heading } from "@medusajs/ui"
3
3
  import { useTranslation } from "react-i18next"
4
4
  import { ActionMenu } from "../../../../../components/common/action-menu"
5
5
  import { SectionRow } from "../../../../../components/common/section"
6
- import { useDeleteProductOption } from "../../../../../hooks/api/products"
7
6
  import { HttpTypes } from "@medusajs/types"
8
7
 
9
8
  const OptionActions = ({
10
- product,
11
9
  option,
12
10
  }: {
13
- product: HttpTypes.AdminProduct
14
11
  option: HttpTypes.AdminProductOption
15
12
  }) => {
16
13
  const { t } = useTranslation()
17
- const { mutateAsync } = useDeleteProductOption(product.id, option.id)
18
- const prompt = usePrompt()
19
-
20
- const handleDelete = async () => {
21
- const res = await prompt({
22
- title: t("general.areYouSure"),
23
- description: t("products.options.deleteWarning", {
24
- title: option.title,
25
- }),
26
- confirmText: t("actions.delete"),
27
- cancelText: t("actions.cancel"),
28
- })
29
-
30
- if (!res) {
31
- return
32
- }
33
-
34
- await mutateAsync()
35
- }
36
14
 
37
15
  return (
38
16
  <ActionMenu
@@ -41,20 +19,11 @@ const OptionActions = ({
41
19
  actions: [
42
20
  {
43
21
  label: t("actions.edit"),
44
- to: `options/${option.id}/edit`,
22
+ to: `/product-options/${option.id}/edit`,
45
23
  icon: <PencilSquare />,
46
24
  },
47
25
  ],
48
26
  },
49
- {
50
- actions: [
51
- {
52
- label: t("actions.delete"),
53
- onClick: handleDelete,
54
- icon: <Trash />,
55
- },
56
- ],
57
- },
58
27
  ]}
59
28
  />
60
29
  )
@@ -78,9 +47,9 @@ export const ProductOptionSection = ({
78
47
  {
79
48
  actions: [
80
49
  {
81
- label: t("actions.create"),
82
- to: "options/create",
83
- icon: <Plus />,
50
+ label: t("actions.manage"),
51
+ to: "options/manage",
52
+ icon: <PencilSquare />,
84
53
  },
85
54
  ],
86
55
  },
@@ -93,18 +62,31 @@ export const ProductOptionSection = ({
93
62
  <SectionRow
94
63
  title={option.title}
95
64
  key={option.id}
96
- value={option.values?.map((val) => {
97
- return (
98
- <Badge
99
- key={val.value}
100
- size="2xsmall"
101
- className="flex min-w-[20px] items-center justify-center"
102
- >
103
- {val.value}
104
- </Badge>
105
- )
106
- })}
107
- actions={<OptionActions product={product} option={option} />}
65
+ value={option.values
66
+ ?.sort((a, b) => {
67
+ if (a.rank == null && b.rank == null) {
68
+ return 0
69
+ }
70
+ if (a.rank == null) {
71
+ return 1
72
+ }
73
+ if (b.rank == null) {
74
+ return -1
75
+ }
76
+ return a.rank - b.rank
77
+ })
78
+ .map((val) => {
79
+ return (
80
+ <Badge
81
+ key={val.value}
82
+ size="2xsmall"
83
+ className="flex min-w-[20px] items-center justify-center"
84
+ >
85
+ {val.value}
86
+ </Badge>
87
+ )
88
+ })}
89
+ actions={<OptionActions option={option} />}
108
90
  />
109
91
  )
110
92
  })}
@@ -0,0 +1 @@
1
+ export { ProductOptionsManageForm } from "./product-options-manage-form"