@medusajs/dashboard 3.0.0-snapshot-20251104011621 → 3.0.0-snapshot-20251106181920
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.
- package/dist/{adjust-inventory-7EWRE2HD.mjs → adjust-inventory-MEJEPP4Y.mjs} +1 -1
- package/dist/{api-key-management-create-SPLD3JMO.mjs → api-key-management-create-4OZWVOSF.mjs} +3 -3
- package/dist/{api-key-management-detail-MFQTHUN6.mjs → api-key-management-detail-K3A3T6ET.mjs} +13 -13
- package/dist/{api-key-management-edit-2VPL7PHB.mjs → api-key-management-edit-FYLVVQOA.mjs} +3 -3
- package/dist/{api-key-management-list-22GXXJUC.mjs → api-key-management-list-6YG52LWY.mjs} +3 -3
- package/dist/{api-key-management-sales-channels-MV6FMA4C.mjs → api-key-management-sales-channels-S5IFH7LP.mjs} +4 -4
- package/dist/app.css +3 -3
- package/dist/app.js +16852 -15621
- package/dist/app.mjs +12 -12
- package/dist/{campaign-create-GD2D45NX.mjs → campaign-create-NEKUWDGF.mjs} +2 -2
- package/dist/{campaign-detail-IKHUALTL.mjs → campaign-detail-2H2W4W5B.mjs} +10 -10
- package/dist/{categories-metadata-2HM7G27P.mjs → categories-metadata-ZEYU33GV.mjs} +10 -10
- package/dist/{category-create-BC2VUVKO.mjs → category-create-N7PP3GWU.mjs} +5 -5
- package/dist/{category-detail-D4PYJJGJ.mjs → category-detail-DKY37LPO.mjs} +14 -14
- package/dist/{category-edit-U5Y5KJ2Y.mjs → category-edit-IFDQP7EZ.mjs} +2 -2
- package/dist/{category-list-MLLB5U6K.mjs → category-list-2M4BCRAL.mjs} +5 -5
- package/dist/{category-organize-4NXFDN2I.mjs → category-organize-76I7PO24.mjs} +2 -2
- package/dist/{category-products-K5INZSSV.mjs → category-products-VVRGW25X.mjs} +13 -13
- package/dist/{chunk-XXROCJ7D.mjs → chunk-227DWSFF.mjs} +15 -15
- package/dist/{chunk-IKXQEHLS.mjs → chunk-3G33PZVQ.mjs} +1 -1
- package/dist/{chunk-ULQ3V4CC.mjs → chunk-3MPO56OL.mjs} +2 -2
- package/dist/{chunk-MQALAB34.mjs → chunk-7PWZ5GMG.mjs} +1 -1
- package/dist/{chunk-PYIPIUAY.mjs → chunk-ET6EGRW3.mjs} +332 -241
- package/dist/{chunk-6IXLTZ2H.mjs → chunk-FA5QNPXE.mjs} +2 -2
- package/dist/{chunk-IXZVR3HG.mjs → chunk-GBKLLUUX.mjs} +1 -1
- package/dist/{chunk-ALKTJGWS.mjs → chunk-GI6XX5VU.mjs} +2 -2
- package/dist/{chunk-4BGVSXZZ.mjs → chunk-GVPJPLE2.mjs} +15 -48
- package/dist/{chunk-6XWHQ6ON.mjs → chunk-GVVAVAXG.mjs} +1 -1
- package/dist/{chunk-3DO2JGVG.mjs → chunk-HGFZAXHD.mjs} +1 -1
- package/dist/{chunk-3C6WQ7NH.mjs → chunk-IBSMG7AF.mjs} +37 -3
- package/dist/{chunk-EQKJ5FSL.mjs → chunk-JAXWGF4M.mjs} +1 -1
- package/dist/{chunk-LEKWKUIS.mjs → chunk-JC75WAC7.mjs} +3 -3
- package/dist/{chunk-ZUUKLYH4.mjs → chunk-JDA2MYND.mjs} +1 -1
- package/dist/{chunk-LOAL44PP.mjs → chunk-JDEH6Z4M.mjs} +1 -1
- package/dist/{chunk-2O43G3RH.mjs → chunk-LYTIMAIZ.mjs} +1 -1
- package/dist/{chunk-OGAZYXOV.mjs → chunk-NGR5XU3K.mjs} +1 -1
- package/dist/{chunk-3JJBLFYN.mjs → chunk-OI4W5AEL.mjs} +6 -2
- package/dist/{chunk-XYHXWLTJ.mjs → chunk-P5RVJWPK.mjs} +1 -1
- package/dist/{chunk-WTK7SR6S.mjs → chunk-SBFWPL42.mjs} +2 -2
- package/dist/{chunk-NDXL7ZT5.mjs → chunk-TNMXAPPT.mjs} +1 -1
- package/dist/{chunk-TUCPFNIY.mjs → chunk-UTVAHVAY.mjs} +5 -5
- package/dist/{chunk-KXRW6JRE.mjs → chunk-WOFUOGLO.mjs} +123 -33
- package/dist/{chunk-N4N4KGET.mjs → chunk-WWQZD7WM.mjs} +1 -1
- package/dist/{chunk-R2QF6AQX.mjs → chunk-Y6ZQFV7H.mjs} +1 -1
- package/dist/{chunk-VLOA5XAC.mjs → chunk-YCDDT44O.mjs} +8 -4
- package/dist/{chunk-YL4UEHO3.mjs → chunk-YSQG2JDM.mjs} +1 -1
- package/dist/chunk-ZHH3W7CN.mjs +171 -0
- package/dist/{collection-add-products-TWIDVZMU.mjs → collection-add-products-QCSFXELK.mjs} +14 -14
- package/dist/{collection-create-CUZFWEOB.mjs → collection-create-45RYGDW7.mjs} +2 -2
- package/dist/{collection-detail-B33WPVIW.mjs → collection-detail-OLC6DMBZ.mjs} +14 -14
- package/dist/{collection-edit-22I7EEJG.mjs → collection-edit-YBPBHLLZ.mjs} +2 -2
- package/dist/{collection-list-DAW7WOX5.mjs → collection-list-6UJNE2QB.mjs} +24 -23
- package/dist/{collection-metadata-ZUFYY4OU.mjs → collection-metadata-QG55V5ZM.mjs} +11 -11
- package/dist/{customer-detail-ATJGSJTH.mjs → customer-detail-XOCZDUJL.mjs} +14 -14
- package/dist/{customer-group-detail-OVZIWNPP.mjs → customer-group-detail-EWSDTVTQ.mjs} +13 -13
- package/dist/{customer-group-list-SADXXHAE.mjs → customer-group-list-NFXAELFY.mjs} +13 -13
- package/dist/{customers-add-customer-group-XNPZ47LK.mjs → customers-add-customer-group-EYZMFVBS.mjs} +13 -13
- package/dist/{edit-inventory-item-5RPZHCM7.mjs → edit-inventory-item-TFJL5H5X.mjs} +1 -1
- package/dist/{edit-inventory-item-attributes-R73ZTBYG.mjs → edit-inventory-item-attributes-O3K7OB56.mjs} +1 -1
- package/dist/{edit-reservation-WMLAFMYU.mjs → edit-reservation-Z5TFZERY.mjs} +2 -2
- package/dist/{edit-rules-KV43O773.mjs → edit-rules-IE77WUXD.mjs} +10 -10
- package/dist/en.json +51 -4
- package/dist/{inventory-create-NW5WSPBV.mjs → inventory-create-HQ5XLKOJ.mjs} +10 -10
- package/dist/{inventory-detail-I2CNJC6Y.mjs → inventory-detail-DAINM7WP.mjs} +10 -10
- package/dist/{inventory-list-I7IXI4KC.mjs → inventory-list-5ROSUTXF.mjs} +1 -1
- package/dist/{inventory-metadata-7XR4ON7G.mjs → inventory-metadata-HUL56OD2.mjs} +10 -10
- package/dist/{inventory-stock-VTIDGTOY.mjs → inventory-stock-5VIUWKTQ.mjs} +10 -10
- package/dist/{location-detail-WZM4EXFM.mjs → location-detail-QMLCFID5.mjs} +15 -15
- package/dist/{location-fulfillment-providers-F7MMM5KC.mjs → location-fulfillment-providers-NAFFMP3P.mjs} +15 -14
- package/dist/{location-sales-channels-J3V26P3Q.mjs → location-sales-channels-D37LXTKQ.mjs} +3 -3
- package/dist/{location-service-zone-shipping-option-create-F3EQW67U.mjs → location-service-zone-shipping-option-create-VM4TEJHY.mjs} +10 -10
- package/dist/{login-VZALGB6R.mjs → login-MTGOV7KC.mjs} +10 -10
- package/dist/{manage-locations-ZRCDYW5V.mjs → manage-locations-OHDFBORX.mjs} +2 -2
- package/dist/{order-allocate-items-MZ7Y4FU4.mjs → order-allocate-items-NU65ZXHE.mjs} +3 -3
- package/dist/{order-create-claim-VFFKHCI6.mjs → order-create-claim-LTE2E75R.mjs} +16 -16
- package/dist/{order-create-edit-7TFUOMST.mjs → order-create-edit-TPU3CKUU.mjs} +11 -11
- package/dist/{order-create-exchange-CXQ5ZM3Q.mjs → order-create-exchange-FVSBZI7P.mjs} +22 -22
- package/dist/{order-create-fulfillment-VTICR6OE.mjs → order-create-fulfillment-NFGPDCBV.mjs} +13 -13
- package/dist/{order-create-refund-RWDVIXPV.mjs → order-create-refund-DC7C3R4Y.mjs} +15 -15
- package/dist/{order-create-return-AYWH3WMR.mjs → order-create-return-RLXYVZLO.mjs} +4 -4
- package/dist/{order-create-shipment-2KNYEHSU.mjs → order-create-shipment-RDYWCG3A.mjs} +10 -10
- package/dist/{order-detail-IFXJNVTV.mjs → order-detail-VVOZ6E2R.mjs} +31 -31
- package/dist/{order-edit-billing-address-T6BIIRAX.mjs → order-edit-billing-address-LV7453CS.mjs} +10 -10
- package/dist/{order-edit-email-SLUOGWRO.mjs → order-edit-email-4U5C6UKX.mjs} +10 -10
- package/dist/{order-edit-shipping-address-YUES5K5Q.mjs → order-edit-shipping-address-6IQC2CVP.mjs} +10 -10
- package/dist/{order-list-4N3OV2PU.mjs → order-list-INSYF52F.mjs} +5 -5
- package/dist/{order-metadata-HS33MC6S.mjs → order-metadata-EEV4IWOM.mjs} +10 -10
- package/dist/{order-receive-return-E6BGSZVL.mjs → order-receive-return-IWHR3EBF.mjs} +11 -11
- package/dist/{order-request-transfer-7IIDQ37I.mjs → order-request-transfer-65R4A7HS.mjs} +10 -10
- package/dist/{price-list-configuration-4XY4JW4I.mjs → price-list-configuration-L5XYCVP2.mjs} +4 -4
- package/dist/{price-list-create-VFQVCUWV.mjs → price-list-create-5GIMBRG2.mjs} +17 -17
- package/dist/{price-list-detail-32UKOWNW.mjs → price-list-detail-7AL2EBRL.mjs} +17 -17
- package/dist/{price-list-edit-GXDLVOU4.mjs → price-list-edit-DHG5STG4.mjs} +2 -2
- package/dist/{price-list-list-TKXSU27S.mjs → price-list-list-QQKZEFSU.mjs} +3 -3
- package/dist/{price-list-prices-add-AY75YZ7D.mjs → price-list-prices-add-2OO4QEZB.mjs} +13 -13
- package/dist/{price-list-prices-edit-J7HCNDTO.mjs → price-list-prices-edit-2FB25KWU.mjs} +2 -2
- package/dist/{product-attributes-3GCAY7KW.mjs → product-attributes-CCQ6WAOD.mjs} +13 -13
- package/dist/{product-create-4TD7FQC7.mjs → product-create-AIRCVZAE.mjs} +343 -549
- package/dist/{product-create-variant-ZWY57BX7.mjs → product-create-variant-7BD5KQHQ.mjs} +10 -10
- package/dist/{product-detail-J7T7MNUY.mjs → product-detail-IYMXYAPH.mjs} +27 -54
- package/dist/{product-edit-MJ7VAIVY.mjs → product-edit-PDGQHCQ2.mjs} +13 -13
- package/dist/{product-export-X64NQWTS.mjs → product-export-5EINLQDF.mjs} +23 -22
- package/dist/{product-image-variants-edit-J6A5G4AC.mjs → product-image-variants-edit-DDSEBG5H.mjs} +10 -10
- package/dist/{product-import-HDNC36SM.mjs → product-import-IQJWHNYN.mjs} +16 -16
- package/dist/{product-list-E7HS4SBG.mjs → product-list-PUQEGU75.mjs} +17 -17
- package/dist/{product-media-Z3NNTB7H.mjs → product-media-Q5XFYZRS.mjs} +2 -2
- package/dist/{product-metadata-LMDEXR3V.mjs → product-metadata-WCKNOZXX.mjs} +10 -10
- package/dist/product-option-create-MWFWB2SU.mjs +336 -0
- package/dist/product-option-detail-UKKEZPG7.mjs +323 -0
- package/dist/product-option-edit-NHAF7B4P.mjs +324 -0
- package/dist/product-option-list-C6ZR2WIX.mjs +266 -0
- package/dist/product-option-metadata-OWSGHNDC.mjs +71 -0
- package/dist/product-options-manage-N73G5IXY.mjs +206 -0
- package/dist/{product-organization-263TICCI.mjs → product-organization-HHME5F2C.mjs} +14 -14
- package/dist/{product-prices-MCZYVPQW.mjs → product-prices-GVEPABHQ.mjs} +1 -1
- package/dist/{product-sales-channels-RHZQXWAY.mjs → product-sales-channels-ZC5ONPG7.mjs} +3 -3
- package/dist/{product-shipping-profile-GVTR3MHD.mjs → product-shipping-profile-KXSBDGRD.mjs} +13 -13
- package/dist/{product-stock-O2BH5R45.mjs → product-stock-LXRLD7FA.mjs} +10 -10
- package/dist/{product-tag-create-GOJTE5XA.mjs → product-tag-create-RAJEWM5O.mjs} +10 -10
- package/dist/{product-tag-detail-CK5F4DU3.mjs → product-tag-detail-EOW2GMOL.mjs} +28 -27
- package/dist/{product-tag-edit-IT4GHLSO.mjs → product-tag-edit-ZOO56XMF.mjs} +10 -10
- package/dist/{product-tag-list-VNROS2W3.mjs → product-tag-list-B2UX2OHB.mjs} +26 -25
- package/dist/{product-tag-metadata-QV2BOGP2.mjs → product-tag-metadata-OZB7SVDN.mjs} +10 -10
- package/dist/{product-type-detail-7K5RLART.mjs → product-type-detail-4YZUC6ZS.mjs} +13 -13
- package/dist/{product-type-metadata-5TDBJGNQ.mjs → product-type-metadata-6QT47ZSR.mjs} +10 -10
- package/dist/{product-variant-detail-3SO2MX22.mjs → product-variant-detail-HOOYZSS2.mjs} +10 -10
- package/dist/{product-variant-edit-DW27AYBX.mjs → product-variant-edit-J2MTJA75.mjs} +10 -10
- package/dist/{product-variant-manage-inventory-items-T5OB3YX3.mjs → product-variant-manage-inventory-items-P4QUORRH.mjs} +1 -1
- package/dist/{product-variant-media-PHRCKUDK.mjs → product-variant-media-U5RG7AOW.mjs} +1 -1
- package/dist/{product-variant-metadata-4KJE6B2R.mjs → product-variant-metadata-ZRSZO2D4.mjs} +10 -10
- package/dist/{promotion-create-F27AOTVZ.mjs → promotion-create-2E4EF4SP.mjs} +15 -15
- package/dist/{promotion-detail-ZDINJASC.mjs → promotion-detail-P2BHIQDG.mjs} +10 -10
- package/dist/{refund-reason-create-5ATQ2IPU.mjs → refund-reason-create-I3BIJFJH.mjs} +10 -10
- package/dist/{refund-reason-edit-F7AMOTG3.mjs → refund-reason-edit-2BEZASQH.mjs} +10 -10
- package/dist/{refund-reason-list-SFTHVSPC.mjs → refund-reason-list-NIJHHOXJ.mjs} +13 -13
- package/dist/{region-metadata-CRAHVHOC.mjs → region-metadata-RLZSQNGW.mjs} +10 -10
- package/dist/{reservation-create-YZMZ6HSS.mjs → reservation-create-4R2XEEZU.mjs} +2 -2
- package/dist/{reservation-detail-6MCBQZAE.mjs → reservation-detail-7OYGNK4L.mjs} +10 -10
- package/dist/{reservation-list-IEUC3KXK.mjs → reservation-list-VY44QEH6.mjs} +2 -2
- package/dist/{reservation-metadata-IQNJPNAX.mjs → reservation-metadata-VJIAGIMF.mjs} +10 -10
- package/dist/{sales-channel-add-products-7RKUDBXN.mjs → sales-channel-add-products-KAUMNKMD.mjs} +13 -13
- package/dist/{sales-channel-create-7ISLGNGC.mjs → sales-channel-create-I6ME6QBM.mjs} +2 -2
- package/dist/{sales-channel-detail-TKVVIAS5.mjs → sales-channel-detail-5SXDKP6P.mjs} +13 -13
- package/dist/{sales-channel-edit-2PEHGAWF.mjs → sales-channel-edit-O7GM2B6O.mjs} +2 -2
- package/dist/{sales-channel-list-SI7JVBOI.mjs → sales-channel-list-JKZ6TIY7.mjs} +11 -11
- package/dist/{sales-channel-metadata-ZOCPAIGM.mjs → sales-channel-metadata-33P5SKDI.mjs} +10 -10
- package/dist/{shipping-option-type-create-YR2QV2OG.mjs → shipping-option-type-create-KVYNWD2Q.mjs} +10 -10
- package/dist/{shipping-option-type-detail-TYHGCV2X.mjs → shipping-option-type-detail-YX3HMXNI.mjs} +11 -11
- package/dist/{shipping-option-type-edit-6KL3MHVT.mjs → shipping-option-type-edit-ODXQMHYJ.mjs} +10 -10
- package/dist/{shipping-option-type-list-YPCCUVFZ.mjs → shipping-option-type-list-XCQNWDDA.mjs} +11 -11
- package/dist/{shipping-profile-metadata-A33XKBQN.mjs → shipping-profile-metadata-K34DAKGY.mjs} +10 -10
- package/dist/{store-detail-3ZV7FCPV.mjs → store-detail-3Z3BK2BH.mjs} +10 -10
- package/dist/{store-metadata-LMRFCZ3J.mjs → store-metadata-FESGAO7E.mjs} +10 -10
- package/dist/{tax-region-create-5Y6EA7XE.mjs → tax-region-create-EVFVC6HN.mjs} +10 -10
- package/dist/{tax-region-detail-TTYUBJ3V.mjs → tax-region-detail-ULHK52CD.mjs} +29 -28
- package/dist/{tax-region-edit-IKEWHRUK.mjs → tax-region-edit-CXEPD2F2.mjs} +10 -10
- package/dist/{tax-region-province-detail-YCY56CRL.mjs → tax-region-province-detail-VUY4PDGN.mjs} +29 -28
- package/dist/{tax-region-tax-override-create-R3PNDP43.mjs → tax-region-tax-override-create-WWZZVAG5.mjs} +28 -27
- package/dist/{tax-region-tax-override-edit-QLD7MIQY.mjs → tax-region-tax-override-edit-HVZRD44G.mjs} +27 -26
- package/dist/{user-detail-DFZPKHG2.mjs → user-detail-YTVBPRH5.mjs} +1 -1
- package/dist/{user-metadata-BQKW4WAU.mjs → user-metadata-33W3JSHN.mjs} +10 -10
- package/dist/{workflow-execution-detail-D5QUZFTV.mjs → workflow-execution-detail-SHEXD5OL.mjs} +10 -10
- package/package.json +9 -9
- package/src/components/common/infinite-list/infinite-list.tsx +9 -4
- package/src/components/layout/main-layout/main-layout.tsx +7 -4
- package/src/dashboard-app/dashboard-app.tsx +10 -2
- package/src/dashboard-app/routes/get-route.map.tsx +64 -12
- package/src/dashboard-app/routes/utils.ts +14 -6
- package/src/hooks/api/index.ts +1 -0
- package/src/hooks/api/product-options.tsx +151 -0
- package/src/hooks/api/products.tsx +23 -63
- package/src/hooks/table/columns/use-product-option-table-columns.tsx +43 -0
- package/src/hooks/table/filters/index.ts +1 -0
- package/src/hooks/table/filters/use-product-option-table-filters.tsx +33 -0
- package/src/hooks/table/query/use-product-option-table-query.tsx +34 -0
- package/src/i18n/translations/$schema.json +176 -5
- package/src/i18n/translations/en.json +51 -4
- package/src/routes/product-options/common/hooks/use-delete-product-option-action.tsx +41 -0
- package/src/routes/product-options/product-option-create/components/create-product-option-form/create-product-option-details.tsx +71 -0
- package/src/routes/product-options/product-option-create/components/create-product-option-form/create-product-option-form.tsx +192 -0
- package/src/routes/product-options/product-option-create/components/create-product-option-form/create-product-option-organize.tsx +77 -0
- package/src/routes/product-options/product-option-create/components/create-product-option-form/index.ts +1 -0
- package/src/routes/product-options/product-option-create/components/create-product-option-form/schema.ts +15 -0
- package/src/routes/product-options/product-option-create/index.ts +1 -0
- package/src/routes/product-options/product-option-create/product-option-create.tsx +10 -0
- package/src/routes/product-options/product-option-detail/breadcrumb.tsx +14 -0
- package/src/routes/product-options/product-option-detail/components/product-option-general-section/index.ts +1 -0
- package/src/routes/product-options/product-option-detail/components/product-option-general-section/product-option-general-section.tsx +81 -0
- package/src/routes/product-options/product-option-detail/components/product-option-product-section/index.ts +1 -0
- package/src/routes/product-options/product-option-detail/components/product-option-product-section/product-option-product-section.tsx +74 -0
- package/src/routes/product-options/product-option-detail/index.ts +3 -0
- package/src/routes/product-options/product-option-detail/loader.ts +17 -0
- package/src/routes/product-options/product-option-detail/product-option-detail.tsx +50 -0
- package/src/routes/product-options/product-option-edit/components/edit-product-option-form/edit-product-option-details.tsx +94 -0
- package/src/routes/product-options/product-option-edit/components/edit-product-option-form/edit-product-option-form.tsx +116 -0
- package/src/routes/product-options/product-option-edit/components/edit-product-option-form/edit-product-option-organize.tsx +77 -0
- package/src/routes/product-options/product-option-edit/components/edit-product-option-form/index.ts +1 -0
- package/src/routes/product-options/product-option-edit/components/edit-product-option-form/schema.ts +13 -0
- package/src/routes/product-options/product-option-edit/index.ts +1 -0
- package/src/routes/product-options/product-option-edit/product-option-edit.tsx +34 -0
- package/src/routes/product-options/product-option-list/components/product-option-list-table/index.ts +1 -0
- package/src/routes/product-options/product-option-list/components/product-option-list-table/product-option-list-table.tsx +131 -0
- package/src/routes/product-options/product-option-list/index.ts +1 -0
- package/src/routes/product-options/product-option-list/product-option-list.tsx +19 -0
- package/src/routes/product-options/product-option-metadata/index.ts +1 -0
- package/src/routes/product-options/product-option-metadata/product-option-metadata.tsx +27 -0
- package/src/routes/products/product-create/components/product-create-details-form/components/product-create-details-variant-section/product-create-details-variant-section.tsx +214 -198
- package/src/routes/products/product-create/components/product-create-form/product-create-form.tsx +4 -7
- package/src/routes/products/product-create/constants.ts +1 -0
- package/src/routes/products/product-create/utils.ts +6 -1
- package/src/routes/products/product-detail/components/product-option-section/product-option-section.tsx +7 -38
- package/src/routes/products/product-import/helpers/import-template.ts +6 -6
- package/src/routes/products/product-options-manage/components/product-options-manage-form/index.ts +1 -0
- package/src/routes/products/product-options-manage/components/product-options-manage-form/product-options-manage-form.tsx +147 -0
- package/src/routes/products/product-options-manage/index.ts +1 -0
- package/src/routes/products/product-options-manage/product-options-manage.tsx +35 -0
- package/dist/product-create-option-D2636LJL.mjs +0 -145
- package/dist/product-edit-option-DYAFZIT2.mjs +0 -150
- package/src/routes/products/product-create-option/components/create-product-option-form/create-product-option-form.tsx +0 -122
- package/src/routes/products/product-create-option/components/create-product-option-form/index.ts +0 -1
- package/src/routes/products/product-create-option/index.ts +0 -1
- package/src/routes/products/product-create-option/product-create-option.tsx +0 -26
- package/src/routes/products/product-edit-option/components/edit-product-option-form/edit-product-option-form.tsx +0 -123
- package/src/routes/products/product-edit-option/components/edit-product-option-form/index.ts +0 -1
- package/src/routes/products/product-edit-option/index.ts +0 -1
- package/src/routes/products/product-edit-option/product-edit-option.tsx +0 -32
- package/dist/{chunk-ELPHCFRW.mjs → chunk-MK4E5XQX.mjs} +3 -3
- package/dist/{chunk-VWXNC2B5.mjs → chunk-SMDWWXCD.mjs} +3 -3
- package/dist/{customer-group-add-customers-57THRZ6D.mjs → customer-group-add-customers-TQAH4IPM.mjs} +3 -3
- package/dist/{customer-list-TE7VNBX6.mjs → customer-list-TXAB4URJ.mjs} +3 -3
- package/dist/{location-list-W6EHBBE5.mjs → location-list-MVIK73QC.mjs} +1 -1
- package/dist/{location-service-zone-shipping-option-edit-27MYKN7R.mjs → location-service-zone-shipping-option-edit-WN4MTZSB.mjs} +3 -3
- package/dist/{product-type-list-2ZQ2NE3R.mjs → product-type-list-J2WDYTZK.mjs} +3 -3
- package/dist/{region-list-W55C3CTH.mjs → region-list-KE5HCKOR.mjs} +3 -3
- package/dist/{return-reason-list-CBOVMQZF.mjs → return-reason-list-6UKR2BLW.mjs} +3 -3
- package/dist/{user-list-6EVTLPJE.mjs → user-list-73SJSKYT.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 {
|
|
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,172 @@ export const ProductCreateVariantsSection = ({
|
|
|
97
90
|
const showInvalidVariantsMessage =
|
|
98
91
|
form.formState.errors.variants?.root?.message === "invalid_length"
|
|
99
92
|
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const newOptions = [...watchedOptions]
|
|
105
|
-
newOptions[index].values = value
|
|
93
|
+
const { product_options = [], isLoading } = useProductOptions({
|
|
94
|
+
is_exclusive: false,
|
|
95
|
+
})
|
|
106
96
|
|
|
107
|
-
|
|
108
|
-
|
|
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
|
-
|
|
113
|
-
|
|
114
|
-
|
|
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
|
-
|
|
119
|
-
|
|
131
|
+
setSelectedOptionValues(newSelectedValues)
|
|
132
|
+
updateFormWithSelectedValues(selectedProductOptions, newSelectedValues)
|
|
133
|
+
}
|
|
120
134
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
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
|
-
|
|
130
|
-
|
|
155
|
+
let updatedCustomValues = customValues
|
|
156
|
+
const updatedValidValueIds = [...validValueIds]
|
|
157
|
+
newCustomValues.forEach((newValue) => {
|
|
158
|
+
const tempId = `custom-${Date.now()}-${Math.random()}-${newValue}`
|
|
131
159
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
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
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
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
|
-
|
|
151
|
-
|
|
179
|
+
if (newCustomValues.length > 0) {
|
|
180
|
+
setCustomValues(updatedCustomValues)
|
|
181
|
+
}
|
|
152
182
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
183
|
+
const updatedSelectedValues = {
|
|
184
|
+
...selectedOptionValues,
|
|
185
|
+
[optionId]: updatedValidValueIds,
|
|
156
186
|
}
|
|
157
187
|
|
|
158
|
-
|
|
188
|
+
setSelectedOptionValues(updatedSelectedValues)
|
|
159
189
|
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
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
|
-
|
|
165
|
-
|
|
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
|
-
|
|
168
|
-
|
|
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
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
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,
|
|
180
243
|
}
|
|
244
|
+
})
|
|
181
245
|
|
|
182
|
-
|
|
183
|
-
|
|
246
|
+
form.setValue("options", newOptions)
|
|
247
|
+
|
|
248
|
+
const permutations = getPermutations(
|
|
249
|
+
newOptions.filter(({ values }) => values.length)
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
const newVariants = permutations.map((permutation, index) => ({
|
|
253
|
+
title: getVariantName(permutation),
|
|
254
|
+
options: permutation,
|
|
255
|
+
should_create: true,
|
|
256
|
+
variant_rank: index,
|
|
257
|
+
inventory: [{ inventory_item_id: "", required_quantity: "" }],
|
|
258
|
+
}))
|
|
184
259
|
|
|
185
260
|
form.setValue("variants", newVariants)
|
|
186
261
|
}
|
|
@@ -295,132 +370,73 @@ export const ProductCreateVariantsSection = ({
|
|
|
295
370
|
{watchedAreVariantsEnabled && (
|
|
296
371
|
<>
|
|
297
372
|
<div className="flex flex-col gap-y-6">
|
|
298
|
-
<
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
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
|
-
}}
|
|
373
|
+
<div className="flex flex-col">
|
|
374
|
+
<Label weight="plus">
|
|
375
|
+
{t("products.create.variants.productOptions.label")}
|
|
376
|
+
</Label>
|
|
377
|
+
<Hint>{t("products.create.variants.productOptions.hint")}</Hint>
|
|
378
|
+
</div>
|
|
379
|
+
{showInvalidOptionsMessage && (
|
|
380
|
+
<Alert dismissible variant="error">
|
|
381
|
+
{t("products.create.errors.options")}
|
|
382
|
+
</Alert>
|
|
383
|
+
)}
|
|
384
|
+
<Combobox
|
|
385
|
+
value={selectedOptionIds}
|
|
386
|
+
onChange={(value) => handleProductOptionSelect(value as string[])}
|
|
387
|
+
options={productOptionChoices}
|
|
388
|
+
placeholder={t("products.fields.options.optionTitlePlaceholder")}
|
|
389
|
+
disabled={isLoading}
|
|
422
390
|
/>
|
|
423
391
|
</div>
|
|
392
|
+
{selectedOptionIds.length > 0 && (
|
|
393
|
+
<div className="flex flex-col gap-y-4">
|
|
394
|
+
<div className="flex flex-col">
|
|
395
|
+
<Label weight="plus">{t("fields.values")}</Label>
|
|
396
|
+
<Hint>{t("products.create.variants.selectValuesHint")}</Hint>
|
|
397
|
+
</div>
|
|
398
|
+
<div className="flex flex-col gap-y-3">
|
|
399
|
+
{product_options
|
|
400
|
+
.filter((option) => selectedOptionIds.includes(option.id))
|
|
401
|
+
.map((option) => {
|
|
402
|
+
// Get all values (existing + custom) for this option
|
|
403
|
+
const allValues = getAllValuesForOption(option.id)
|
|
404
|
+
|
|
405
|
+
const valueOptions = allValues
|
|
406
|
+
.sort((a, b) => {
|
|
407
|
+
const rankA = a.rank ?? Number.MAX_VALUE
|
|
408
|
+
const rankB = b.rank ?? Number.MAX_VALUE
|
|
409
|
+
return rankA - rankB
|
|
410
|
+
})
|
|
411
|
+
.map((v) => ({
|
|
412
|
+
value: v.id,
|
|
413
|
+
label: v.value,
|
|
414
|
+
}))
|
|
415
|
+
|
|
416
|
+
return (
|
|
417
|
+
<div key={option.id} className="flex flex-col gap-y-2">
|
|
418
|
+
<Label size="small" weight="plus">
|
|
419
|
+
{option.title}
|
|
420
|
+
</Label>
|
|
421
|
+
<Combobox
|
|
422
|
+
value={selectedOptionValues[option.id] || []}
|
|
423
|
+
onChange={(value) =>
|
|
424
|
+
handleValueChange(option.id, value as string[])
|
|
425
|
+
}
|
|
426
|
+
onCreateOption={(_) => {
|
|
427
|
+
// Nothing
|
|
428
|
+
}}
|
|
429
|
+
options={valueOptions}
|
|
430
|
+
placeholder={t(
|
|
431
|
+
"products.fields.options.variantionsPlaceholder"
|
|
432
|
+
)}
|
|
433
|
+
/>
|
|
434
|
+
</div>
|
|
435
|
+
)
|
|
436
|
+
})}
|
|
437
|
+
</div>
|
|
438
|
+
</div>
|
|
439
|
+
)}
|
|
424
440
|
<div className="grid grid-cols-1 gap-x-4 gap-y-8">
|
|
425
441
|
<div className="flex flex-col gap-y-6">
|
|
426
442
|
<div className="flex flex-col">
|
package/src/routes/products/product-create/components/product-create-form/product-create-form.tsx
CHANGED
|
@@ -78,13 +78,10 @@ export const ProductCreateForm = ({
|
|
|
78
78
|
return {}
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
return regions.reduce(
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
/**
|
|
@@ -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:
|
|
46
|
+
options: options.map((option) => {
|
|
47
|
+
const { id, ...rest } = option
|
|
48
|
+
return id ? { id } : rest
|
|
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
|
|
2
|
-
import { Badge, Container, Heading
|
|
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:
|
|
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.
|
|
82
|
-
to: "options/
|
|
83
|
-
icon: <
|
|
50
|
+
label: t("actions.manage"),
|
|
51
|
+
to: "options/manage",
|
|
52
|
+
icon: <PencilSquare />,
|
|
84
53
|
},
|
|
85
54
|
],
|
|
86
55
|
},
|
|
@@ -104,7 +73,7 @@ export const ProductOptionSection = ({
|
|
|
104
73
|
</Badge>
|
|
105
74
|
)
|
|
106
75
|
})}
|
|
107
|
-
actions={<OptionActions
|
|
76
|
+
actions={<OptionActions option={option} />}
|
|
108
77
|
/>
|
|
109
78
|
)
|
|
110
79
|
})}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
const ProductImportCSV =
|
|
2
2
|
"data:text/csv;charset=utf-8," +
|
|
3
|
-
`Product Id,Product Handle,Product Title,Product Subtitle,Product Description,Product Status,Product Thumbnail,Product Weight,Product Length,Product Width,Product Height,Product HS Code,Product Origin Country,Product MID Code,Product Material,Product Collection Id,Product Type Id,Product Tag 1,Product Discountable,Product External Id,Variant Id,Variant Title,Variant SKU,Variant Barcode,Variant Allow Backorder,Variant Manage Inventory,Variant Weight,Variant Length,Variant Width,Variant Height,Variant HS Code,Variant Origin Country,Variant MID Code,Variant Material,Variant Price EUR,Variant Price USD,Variant Option 1 Name,Variant Option 1 Value,Product Image 1 Url,Product Image 2 Url
|
|
4
|
-
,coffee-mug-v3,Medusa Coffee Mug,,Every programmer's best friend.,published,https://medusa-public-images.s3.eu-west-1.amazonaws.com/coffee-mug.png,400
|
|
5
|
-
,sweatpants-v2,Medusa Sweatpants,,"Reimagine the feeling of classic sweatpants. With our cotton sweatpants, everyday essentials no longer have to be ordinary.",published,https://medusa-public-images.s3.eu-west-1.amazonaws.com/sweatpants-gray-front.png,400
|
|
6
|
-
,sweatpants-v2,Medusa Sweatpants,,"Reimagine the feeling of classic sweatpants. With our cotton sweatpants, everyday essentials no longer have to be ordinary.",published,https://medusa-public-images.s3.eu-west-1.amazonaws.com/sweatpants-gray-front.png,400
|
|
7
|
-
,sweatpants-v2,Medusa Sweatpants,,"Reimagine the feeling of classic sweatpants. With our cotton sweatpants, everyday essentials no longer have to be ordinary.",published,https://medusa-public-images.s3.eu-west-1.amazonaws.com/sweatpants-gray-front.png,400
|
|
8
|
-
,sweatpants-v2,Medusa Sweatpants,,"Reimagine the feeling of classic sweatpants. With our cotton sweatpants, everyday essentials no longer have to be ordinary.",published,https://medusa-public-images.s3.eu-west-1.amazonaws.com/sweatpants-gray-front.png,400
|
|
3
|
+
`Product Id,Product Handle,Product Title,Product Subtitle,Product Description,Product Status,Product Thumbnail,Product Weight,Product Length,Product Width,Product Height,Product HS Code,Product Origin Country,Product MID Code,Product Material,Shipping Profile Id,Product Sales Channel 1,Product Collection Id,Product Type Id,Product Tag 1,Product Discountable,Product External Id,Variant Id,Variant Title,Variant SKU,Variant Barcode,Variant Allow Backorder,Variant Manage Inventory,Variant Weight,Variant Length,Variant Width,Variant Height,Variant HS Code,Variant Origin Country,Variant MID Code,Variant Material,Variant Price EUR,Variant Price USD,Variant Option 1 Name,Variant Option 1 Value,Product Image 1 Url,Product Image 2 Url
|
|
4
|
+
,coffee-mug-v3,Medusa Coffee Mug,,Every programmer's best friend.,published,https://medusa-public-images.s3.eu-west-1.amazonaws.com/coffee-mug.png,400,,,,,,,,,,,,,TRUE,,,One Size,,,FALSE,TRUE,,,,,,,,,10,12,Size,One Size,https://medusa-public-images.s3.eu-west-1.amazonaws.com/coffee-mug.png,
|
|
5
|
+
,sweatpants-v2,Medusa Sweatpants,,"Reimagine the feeling of classic sweatpants. With our cotton sweatpants, everyday essentials no longer have to be ordinary.",published,https://medusa-public-images.s3.eu-west-1.amazonaws.com/sweatpants-gray-front.png,400,,,,,,,,,,,,,TRUE,,,S,,,FALSE,TRUE,,,,,,,,,29.5,33.5,Size,S,https://medusa-public-images.s3.eu-west-1.amazonaws.com/sweatpants-gray-front.png,https://medusa-public-images.s3.eu-west-1.amazonaws.com/sweatpants-gray-back.png
|
|
6
|
+
,sweatpants-v2,Medusa Sweatpants,,"Reimagine the feeling of classic sweatpants. With our cotton sweatpants, everyday essentials no longer have to be ordinary.",published,https://medusa-public-images.s3.eu-west-1.amazonaws.com/sweatpants-gray-front.png,400,,,,,,,,,,,,,TRUE,,,M,,,FALSE,TRUE,,,,,,,,,29.5,33.5,Size,M,https://medusa-public-images.s3.eu-west-1.amazonaws.com/sweatpants-gray-front.png,https://medusa-public-images.s3.eu-west-1.amazonaws.com/sweatpants-gray-back.png
|
|
7
|
+
,sweatpants-v2,Medusa Sweatpants,,"Reimagine the feeling of classic sweatpants. With our cotton sweatpants, everyday essentials no longer have to be ordinary.",published,https://medusa-public-images.s3.eu-west-1.amazonaws.com/sweatpants-gray-front.png,400,,,,,,,,,,,,,TRUE,,,L,,,FALSE,TRUE,,,,,,,,,29.5,33.5,Size,L,https://medusa-public-images.s3.eu-west-1.amazonaws.com/sweatpants-gray-front.png,https://medusa-public-images.s3.eu-west-1.amazonaws.com/sweatpants-gray-back.png
|
|
8
|
+
,sweatpants-v2,Medusa Sweatpants,,"Reimagine the feeling of classic sweatpants. With our cotton sweatpants, everyday essentials no longer have to be ordinary.",published,https://medusa-public-images.s3.eu-west-1.amazonaws.com/sweatpants-gray-front.png,400,,,,,,,,,,,,,TRUE,,,XL,,,FALSE,TRUE,,,,,,,,,29.5,33.5,Size,XL,https://medusa-public-images.s3.eu-west-1.amazonaws.com/sweatpants-gray-front.png,https://medusa-public-images.s3.eu-west-1.amazonaws.com/sweatpants-gray-back.png`
|
|
9
9
|
|
|
10
10
|
export const getProductImportCsvTemplate = () => {
|
|
11
11
|
return encodeURI(ProductImportCSV)
|
package/src/routes/products/product-options-manage/components/product-options-manage-form/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ProductOptionsManageForm } from "./product-options-manage-form"
|