@medusajs/dashboard 3.0.0-snapshot-20251216145629 → 3.0.0-snapshot-20260102125810
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/add-locales-2OZXZCT5.mjs +81 -0
- package/dist/{adjust-inventory-26YXAXQL.mjs → adjust-inventory-47KGDWME.mjs} +2 -2
- package/dist/{api-key-management-create-EMP32G2D.mjs → api-key-management-create-EFPPZPZ7.mjs} +4 -4
- package/dist/{api-key-management-detail-6RCDH73M.mjs → api-key-management-detail-4IFED7SF.mjs} +15 -15
- package/dist/{api-key-management-edit-IBM3ZXHK.mjs → api-key-management-edit-QGVBNLUL.mjs} +4 -4
- package/dist/{api-key-management-list-KC5GOWAU.mjs → api-key-management-list-ROIJIIPQ.mjs} +4 -4
- package/dist/{api-key-management-sales-channels-LUB5G6RC.mjs → api-key-management-sales-channels-7P5L45AT.mjs} +6 -6
- package/dist/app.css +26 -3
- package/dist/app.js +18504 -16698
- package/dist/app.mjs +13 -13
- package/dist/{campaign-create-FJOECKGT.mjs → campaign-create-EZGZ4SBQ.mjs} +3 -3
- package/dist/{campaign-detail-5Q4BYCPX.mjs → campaign-detail-NFKLFPY4.mjs} +12 -12
- package/dist/{categories-metadata-J7M3XWI7.mjs → categories-metadata-G7BACZ26.mjs} +12 -12
- package/dist/{category-create-KHJZSC7G.mjs → category-create-7MV25HYX.mjs} +6 -6
- package/dist/{category-detail-S5IPXMHX.mjs → category-detail-XJQQ7UU4.mjs} +14 -14
- package/dist/{category-edit-CTA2EPDG.mjs → category-edit-LV7EARAB.mjs} +3 -3
- package/dist/{category-list-QBYJ4T3R.mjs → category-list-NIVLV5S3.mjs} +6 -6
- package/dist/{category-organize-SXP33XET.mjs → category-organize-SCRGWKDG.mjs} +3 -3
- package/dist/{category-products-KPW6BA5J.mjs → category-products-FXFSMCR6.mjs} +13 -13
- package/dist/{chunk-OXPE5TAY.mjs → chunk-24C2YVFU.mjs} +1 -1
- package/dist/{chunk-4JQR6QNW.mjs → chunk-333HK6Y6.mjs} +2 -2
- package/dist/{chunk-DODQ3KJT.mjs → chunk-3RRA56WC.mjs} +8 -3
- package/dist/{chunk-5LGRZSEH.mjs → chunk-3YPZ3R4U.mjs} +1 -1
- package/dist/{chunk-2DULKOPN.mjs → chunk-5ISRTMYH.mjs} +1 -1
- package/dist/{chunk-PHLCT2HA.mjs → chunk-5ZPKY5XP.mjs} +1 -1
- package/dist/{chunk-U6G4M5LP.mjs → chunk-6EXKKRZY.mjs} +1 -1
- package/dist/{chunk-GRZSG4EP.mjs → chunk-74WPAWMW.mjs} +127 -226
- package/dist/chunk-7AXHHXCX.mjs +4 -0
- package/dist/{chunk-UULAOAFM.mjs → chunk-BJ44US4R.mjs} +358 -242
- package/dist/{chunk-BMS2QLJY.mjs → chunk-BMJ5RYIO.mjs} +1 -1
- package/dist/{chunk-Y2YVTIJI.mjs → chunk-CW5PQUJ6.mjs} +1 -1
- package/dist/{chunk-IAV7IKJ6.mjs → chunk-DN5BRKVN.mjs} +1 -1
- package/dist/{chunk-RS7DWLEP.mjs → chunk-DQUXK4WW.mjs} +1 -1
- package/dist/{chunk-2XTBDCGE.mjs → chunk-DWH2OQFK.mjs} +1 -1
- package/dist/{chunk-CCQD65EY.mjs → chunk-FKNW5MLZ.mjs} +360 -288
- package/dist/{chunk-HTCYX4VD.mjs → chunk-G35UUG2P.mjs} +1 -1
- package/dist/{chunk-QKALAT7P.mjs → chunk-GGONMC2N.mjs} +1 -1
- package/dist/{chunk-FYWHE3W5.mjs → chunk-GJN5SXGZ.mjs} +1 -1
- package/dist/{chunk-CVHJAKLQ.mjs → chunk-HDO2UCKF.mjs} +1 -1
- package/dist/{chunk-3C6WQ7NH.mjs → chunk-IWNNQ6HA.mjs} +37 -3
- package/dist/{chunk-OL24RDYM.mjs → chunk-KHJL6MUQ.mjs} +8 -8
- package/dist/{chunk-6P4Q4AAP.mjs → chunk-KPI4WFJU.mjs} +3 -3
- package/dist/{chunk-AHZLMCZF.mjs → chunk-KSDXSKJ7.mjs} +1 -1
- package/dist/{chunk-BZKI5J2M.mjs → chunk-L7A2JIQY.mjs} +3 -3
- package/dist/{chunk-XY7A7GZJ.mjs → chunk-LEAMWI5H.mjs} +1 -1
- package/dist/{chunk-A4XYK3MY.mjs → chunk-LG5B2BVB.mjs} +2 -2
- package/dist/{chunk-23GTCEOV.mjs → chunk-ML7BA2NY.mjs} +1 -1
- package/dist/{chunk-OFN7DIZA.mjs → chunk-OYHFHBNL.mjs} +94 -7
- package/dist/{chunk-OSHH5GAS.mjs → chunk-Q34TRFIW.mjs} +1 -13
- package/dist/{chunk-UJ2TMPV4.mjs → chunk-QBIQEVTU.mjs} +0 -12
- package/dist/{chunk-YYOPBKME.mjs → chunk-QHRAWZGA.mjs} +3 -3
- package/dist/{chunk-A2WBKOXJ.mjs → chunk-SO2DE6MM.mjs} +2 -2
- package/dist/chunk-T6DDBLGY.mjs +13 -0
- package/dist/{chunk-EHU67PIM.mjs → chunk-TOCMU7UV.mjs} +7 -3
- package/dist/{chunk-YIOBBZUB.mjs → chunk-U7KANQ5A.mjs} +2 -2
- package/dist/{chunk-Z6BFNHEO.mjs → chunk-UCYUWNJL.mjs} +109 -62
- package/dist/{chunk-WYATCUOM.mjs → chunk-V2RGYIAG.mjs} +10 -10
- package/dist/{chunk-UWY5ZV66.mjs → chunk-VQ73B7ZZ.mjs} +1 -13
- package/dist/chunk-XD72PXRS.mjs +329 -0
- package/dist/{store-add-locales-VJ4RJ7UI.mjs → chunk-YFXI6CWD.mjs} +2 -67
- package/dist/{chunk-AWRCV3ME.mjs → chunk-YM4XGCHB.mjs} +1 -1
- package/dist/{chunk-ZMG5B4FG.mjs → chunk-ZGV5NOTE.mjs} +1 -1
- package/dist/{collection-add-products-FU2BS3D3.mjs → collection-add-products-YDMBU2JY.mjs} +13 -13
- package/dist/{collection-create-GWKWVT7B.mjs → collection-create-RXHEXU6T.mjs} +3 -3
- package/dist/{collection-detail-VJE7XHLV.mjs → collection-detail-75XPGVOX.mjs} +13 -13
- package/dist/{collection-edit-EZIO2BR5.mjs → collection-edit-CGF47VIN.mjs} +3 -3
- package/dist/{collection-list-IGA6SCNF.mjs → collection-list-75N5NYXQ.mjs} +18 -17
- package/dist/{collection-metadata-QK7MI3D2.mjs → collection-metadata-TGGC6HM2.mjs} +12 -12
- package/dist/{customer-detail-MOV2T3LF.mjs → customer-detail-KDLZ23B3.mjs} +17 -16
- package/dist/{customer-group-detail-6T7OXGQD.mjs → customer-group-detail-ZIAVMOYS.mjs} +12 -12
- package/dist/{customer-group-list-AJEAF5D2.mjs → customer-group-list-BDDC5VVZ.mjs} +15 -15
- package/dist/{customers-add-customer-group-QVTVSQYM.mjs → customers-add-customer-group-B3ASQGP6.mjs} +12 -12
- package/dist/{edit-inventory-item-H7DAZWIT.mjs → edit-inventory-item-OKAXQRJ5.mjs} +2 -2
- package/dist/{edit-inventory-item-attributes-7HTXXPGZ.mjs → edit-inventory-item-attributes-FVWDV6O5.mjs} +2 -2
- package/dist/{edit-reservation-OVTRZHJR.mjs → edit-reservation-3PU6YSNJ.mjs} +3 -3
- package/dist/{edit-rules-SMVRTCUP.mjs → edit-rules-LOJ3P4YB.mjs} +14 -14
- package/dist/en.json +73 -5
- package/dist/{inventory-create-ANYUM4P5.mjs → inventory-create-C2WWS7QR.mjs} +13 -13
- package/dist/{inventory-detail-ZPSEMYI2.mjs → inventory-detail-AKOZ4T3Z.mjs} +12 -12
- package/dist/{inventory-list-RXJPSVZE.mjs → inventory-list-DRFJIU2O.mjs} +2 -2
- package/dist/{inventory-metadata-FNEJ3RAT.mjs → inventory-metadata-N6CJZEWD.mjs} +12 -12
- package/dist/{inventory-stock-FD4ZM4BB.mjs → inventory-stock-IJ2N7LKC.mjs} +14 -14
- package/dist/{location-detail-N3GUZSY7.mjs → location-detail-PL4Y43RS.mjs} +16 -16
- package/dist/{location-fulfillment-providers-7ZUJAGNY.mjs → location-fulfillment-providers-2PLOVSXC.mjs} +17 -16
- package/dist/{location-sales-channels-P3QJTFDT.mjs → location-sales-channels-SZARSLWT.mjs} +5 -5
- package/dist/{location-service-zone-shipping-option-create-ZJ4GIBTJ.mjs → location-service-zone-shipping-option-create-CUNSAP24.mjs} +15 -15
- package/dist/{location-service-zone-shipping-option-edit-4CGPQ3VT.mjs → location-service-zone-shipping-option-edit-OJ462SVM.mjs} +1 -1
- package/dist/{location-service-zone-shipping-option-pricing-CR4BVYG3.mjs → location-service-zone-shipping-option-pricing-5HN2Z5RB.mjs} +2 -2
- package/dist/login-VBUNWZHI.mjs +301 -0
- package/dist/{manage-locations-7HH6R4UP.mjs → manage-locations-JPCSBA5D.mjs} +2 -2
- package/dist/{order-allocate-items-HZGGYJ42.mjs → order-allocate-items-6QHQASQJ.mjs} +4 -4
- package/dist/{order-create-claim-SCDJGM46.mjs → order-create-claim-ECVSH5GC.mjs} +22 -22
- package/dist/{order-create-edit-JIE3HDHP.mjs → order-create-edit-EVIOJIXE.mjs} +14 -13
- package/dist/{order-create-exchange-LQU4YN7F.mjs → order-create-exchange-ZVYYOGI3.mjs} +22 -22
- package/dist/{order-create-fulfillment-OWUVTZXW.mjs → order-create-fulfillment-FDIFEV6X.mjs} +16 -16
- package/dist/{order-create-refund-Q6HQY42R.mjs → order-create-refund-TNPGKR5P.mjs} +17 -17
- package/dist/{order-create-return-52GHGW5Z.mjs → order-create-return-NR6XQLDD.mjs} +9 -9
- package/dist/{order-create-shipment-WAGGEPRW.mjs → order-create-shipment-UP3WGRWB.mjs} +12 -12
- package/dist/{order-detail-PVPGEWGY.mjs → order-detail-F6D5DV74.mjs} +28 -28
- package/dist/{order-edit-billing-address-UM76J4KX.mjs → order-edit-billing-address-D4AJ6Z5Q.mjs} +44 -12
- package/dist/{order-edit-email-CL3KNOCM.mjs → order-edit-email-MXYA5BII.mjs} +12 -12
- package/dist/{order-edit-shipping-address-PIESTGVL.mjs → order-edit-shipping-address-GKW2ZPGR.mjs} +42 -12
- package/dist/{order-export-LE363ZLB.mjs → order-export-KQUI2TK7.mjs} +14 -14
- package/dist/{order-list-GRLQWN4L.mjs → order-list-7A5UKGXR.mjs} +11 -11
- package/dist/{order-metadata-FHBB7MTG.mjs → order-metadata-2IXELA7C.mjs} +12 -12
- package/dist/{order-receive-return-PRVKP6J2.mjs → order-receive-return-XXHOXGDC.mjs} +13 -13
- package/dist/{order-request-transfer-XSAGRUMT.mjs → order-request-transfer-2ENR64VR.mjs} +13 -13
- package/dist/{price-list-configuration-6S3MLNXQ.mjs → price-list-configuration-BZ3ZH5FY.mjs} +3 -3
- package/dist/{price-list-create-MFRUQADC.mjs → price-list-create-GFGNP6OS.mjs} +16 -16
- package/dist/{price-list-detail-Q5VG5VGW.mjs → price-list-detail-SNNOR5N7.mjs} +17 -17
- package/dist/{price-list-edit-53UW35L3.mjs → price-list-edit-YW5BXBF2.mjs} +3 -3
- package/dist/{price-list-list-DG5YEZ44.mjs → price-list-list-OF562HME.mjs} +4 -4
- package/dist/{price-list-prices-add-SDU5YZAT.mjs → price-list-prices-add-F7A2EV7L.mjs} +15 -15
- package/dist/{price-list-prices-edit-5USQR4D4.mjs → price-list-prices-edit-PQ26MOJE.mjs} +5 -5
- package/dist/{product-attributes-K4FGFORS.mjs → product-attributes-JTPGHUXZ.mjs} +13 -13
- package/dist/{product-create-7YTRHZQQ.mjs → product-create-VFLLQWVX.mjs} +485 -561
- package/dist/{product-create-variant-ERKHTEJZ.mjs → product-create-variant-PLZ5Q2R6.mjs} +14 -14
- package/dist/{product-detail-32ZXNWOP.mjs → product-detail-ISHFZV7X.mjs} +45 -66
- package/dist/{product-edit-FBAKONMR.mjs → product-edit-6EDDNIM6.mjs} +13 -13
- package/dist/{product-export-5AD7NELI.mjs → product-export-UMMROQ7T.mjs} +18 -17
- package/dist/{product-image-variants-edit-M6QF2RLE.mjs → product-image-variants-edit-VRG3AJID.mjs} +12 -12
- package/dist/{product-import-V3KQN4TV.mjs → product-import-EPS4KDID.mjs} +12 -12
- package/dist/{product-list-EUWZIFTM.mjs → product-list-37O7VB2L.mjs} +20 -20
- package/dist/{product-media-3VJ7KENL.mjs → product-media-IV5NUSLW.mjs} +3 -3
- package/dist/{product-metadata-GL2MVPDI.mjs → product-metadata-KTVRI7B3.mjs} +12 -12
- package/dist/product-option-create-JUGLFR2K.mjs +336 -0
- package/dist/product-option-detail-VVK3YBCE.mjs +331 -0
- package/dist/product-option-edit-7FQSKI2R.mjs +325 -0
- package/dist/product-option-list-YHGRI7OJ.mjs +268 -0
- package/dist/product-option-metadata-P2DHDGYR.mjs +73 -0
- package/dist/product-options-manage-4SZDF5H5.mjs +325 -0
- package/dist/{product-organization-IUSVX22S.mjs → product-organization-OEUSIWNQ.mjs} +15 -15
- package/dist/{product-prices-4C36AG4R.mjs → product-prices-GUO3KM2U.mjs} +3 -3
- package/dist/{product-sales-channels-PPXUG4KT.mjs → product-sales-channels-BOZD3AC3.mjs} +5 -5
- package/dist/{product-shipping-profile-ETQFZ7DC.mjs → product-shipping-profile-FNFRDY47.mjs} +3 -3
- package/dist/{product-stock-VEGE6SUZ.mjs → product-stock-2DNYG73L.mjs} +14 -14
- package/dist/{product-tag-create-PQMDDKWH.mjs → product-tag-create-CW7GUCZW.mjs} +12 -12
- package/dist/{product-tag-detail-I3MBZX7U.mjs → product-tag-detail-IB5VIZ3K.mjs} +26 -25
- package/dist/{product-tag-edit-K3BBQLJR.mjs → product-tag-edit-ZSXD3DOC.mjs} +12 -12
- package/dist/{product-tag-list-JUWSOMB7.mjs → product-tag-list-MJO5PURP.mjs} +24 -23
- package/dist/{product-tag-metadata-MJH5LH7E.mjs → product-tag-metadata-DAKCXWZF.mjs} +12 -12
- package/dist/{product-type-create-DRFXTL5O.mjs → product-type-create-NRLNMABQ.mjs} +2 -2
- package/dist/{product-type-detail-RKHT5NBL.mjs → product-type-detail-J2IMAZW6.mjs} +14 -14
- package/dist/{product-type-edit-SRHCZDK7.mjs → product-type-edit-BHTPMMVI.mjs} +2 -2
- package/dist/{product-type-list-QQKAHBJ3.mjs → product-type-list-MQ2PW2IE.mjs} +3 -3
- package/dist/{product-type-metadata-CDJDFFGQ.mjs → product-type-metadata-BCZMUG3K.mjs} +12 -12
- package/dist/{product-variant-detail-XAYG5CKE.mjs → product-variant-detail-4L6DHT3K.mjs} +12 -12
- package/dist/{product-variant-edit-DEZEY2H2.mjs → product-variant-edit-PZU4P65H.mjs} +13 -13
- package/dist/{product-variant-manage-inventory-items-Y2VEOHP7.mjs → product-variant-manage-inventory-items-E3GPBPEZ.mjs} +3 -3
- package/dist/{product-variant-media-2WLVNGI4.mjs → product-variant-media-BSNCO642.mjs} +2 -2
- package/dist/{product-variant-metadata-VTZDNWUT.mjs → product-variant-metadata-FHGGZGPV.mjs} +12 -12
- package/dist/{promotion-add-campaign-DO67QK6M.mjs → promotion-add-campaign-NQSIFI33.mjs} +3 -3
- package/dist/{promotion-create-HWFNUQXG.mjs → promotion-create-GBZWJVAI.mjs} +24 -21
- package/dist/{promotion-detail-QC36KXB3.mjs → promotion-detail-W2OGUESO.mjs} +12 -12
- package/dist/{refund-reason-create-YHCDEHGQ.mjs → refund-reason-create-DLVRT5OU.mjs} +12 -12
- package/dist/{refund-reason-edit-CZ5QZ2SZ.mjs → refund-reason-edit-XCSU7RMH.mjs} +12 -12
- package/dist/{refund-reason-list-OJYYEYJE.mjs → refund-reason-list-G6UNVGPG.mjs} +18 -18
- package/dist/{region-create-NA7Y2LN4.mjs → region-create-2CRTF7HJ.mjs} +1 -1
- package/dist/{region-edit-WAU347DP.mjs → region-edit-IB3PJE7V.mjs} +1 -1
- package/dist/{region-metadata-H6XXUQ4S.mjs → region-metadata-WBEUKOI6.mjs} +12 -12
- package/dist/{reservation-create-ZCIYM6JI.mjs → reservation-create-ERFJUBME.mjs} +4 -4
- package/dist/{reservation-detail-LZAQL4XA.mjs → reservation-detail-Y6UZRZXY.mjs} +12 -12
- package/dist/{reservation-list-B47DXTA7.mjs → reservation-list-LEDZB7KL.mjs} +3 -3
- package/dist/{reservation-metadata-5HZSDDOK.mjs → reservation-metadata-7KH4EXMN.mjs} +12 -12
- package/dist/{return-reason-list-SCBGTOEI.mjs → return-reason-list-UUQAL464.mjs} +6 -6
- package/dist/{sales-channel-add-products-F7YV4MO5.mjs → sales-channel-add-products-GSPG7OTK.mjs} +14 -14
- package/dist/{sales-channel-create-MI7HHZYE.mjs → sales-channel-create-MM237EBQ.mjs} +3 -3
- package/dist/{sales-channel-detail-MXIPZCGA.mjs → sales-channel-detail-65ZFV2OI.mjs} +14 -14
- package/dist/{sales-channel-edit-VSHOIR37.mjs → sales-channel-edit-AC2J4N3M.mjs} +3 -3
- package/dist/{sales-channel-list-RLGL7FM3.mjs → sales-channel-list-LXLW7X3U.mjs} +14 -14
- package/dist/{sales-channel-metadata-M364R4RJ.mjs → sales-channel-metadata-QUAL2RH6.mjs} +13 -13
- package/dist/{shipping-option-type-create-C5WUWON7.mjs → shipping-option-type-create-EU75JC2Q.mjs} +12 -12
- package/dist/{shipping-option-type-detail-PENS2K73.mjs → shipping-option-type-detail-5GYEWATD.mjs} +13 -13
- package/dist/{shipping-option-type-edit-CIU5EHRP.mjs → shipping-option-type-edit-YR4JXT5M.mjs} +12 -12
- package/dist/{shipping-option-type-list-DIOX7VG7.mjs → shipping-option-type-list-BLC4Z5QW.mjs} +13 -13
- package/dist/{shipping-profile-metadata-75G2NNMA.mjs → shipping-profile-metadata-64YRWPDA.mjs} +12 -12
- package/dist/store-add-locales-TSMLNFZP.mjs +81 -0
- package/dist/{store-detail-JSNPOB2F.mjs → store-detail-3SS53LZR.mjs} +13 -13
- package/dist/{store-edit-5ZS562ZO.mjs → store-edit-SMEWFETF.mjs} +1 -1
- package/dist/{store-metadata-CYXTVJUE.mjs → store-metadata-IJGVDDA6.mjs} +12 -12
- package/dist/{tax-region-create-DWGL4EUT.mjs → tax-region-create-XLYIS5XX.mjs} +13 -13
- package/dist/{tax-region-detail-2AE2EFI3.mjs → tax-region-detail-66FKEGFB.mjs} +29 -28
- package/dist/{tax-region-edit-EEVEEU2Q.mjs → tax-region-edit-GBR4EDW7.mjs} +13 -13
- package/dist/{tax-region-province-detail-4ERSEQFF.mjs → tax-region-province-detail-OBA7Q7MQ.mjs} +29 -28
- package/dist/{tax-region-tax-override-create-PHCGEF7V.mjs → tax-region-tax-override-create-34WYD2QZ.mjs} +28 -27
- package/dist/{tax-region-tax-override-edit-SMRPSILC.mjs → tax-region-tax-override-edit-6WJVOGWA.mjs} +27 -26
- package/dist/translation-list-J65VNNAX.mjs +527 -0
- package/dist/{translations-edit-KECSHYZY.mjs → translations-edit-6P3KC4MO.mjs} +280 -304
- package/dist/{user-detail-BJUXLZZQ.mjs → user-detail-VMOJFHIJ.mjs} +2 -2
- package/dist/{user-metadata-2WPJOEJA.mjs → user-metadata-UOPVFX2L.mjs} +12 -12
- package/dist/{workflow-execution-detail-H2AKEZJX.mjs → workflow-execution-detail-WAQ7IG4T.mjs} +12 -12
- package/package.json +9 -9
- package/src/components/data-grid/components/data-grid-cell-container.tsx +7 -10
- package/src/components/data-grid/components/data-grid-multiline-cell.tsx +103 -0
- package/src/components/data-grid/components/data-grid-readonly-cell.tsx +1 -4
- package/src/components/data-grid/components/data-grid-root.tsx +68 -51
- package/src/components/data-grid/components/data-grid-text-cell.tsx +6 -76
- package/src/components/data-grid/components/index.ts +1 -0
- package/src/components/data-grid/data-grid.tsx +2 -0
- package/src/components/data-grid/hooks/use-data-grid-cell.tsx +12 -0
- package/src/components/data-grid/hooks/use-data-grid-form-handlers.tsx +1 -0
- package/src/components/data-grid/hooks/use-data-grid-keydown-event.tsx +65 -7
- package/src/components/data-grid/types.ts +1 -0
- package/src/components/inputs/combobox/combobox.tsx +185 -95
- package/src/components/layout/main-layout/main-layout.tsx +7 -4
- package/src/components/table/table-cells/order/country-cell/country-cell.tsx +5 -1
- package/src/dashboard-app/routes/get-route.map.tsx +68 -12
- package/src/hooks/api/cloud.tsx +41 -0
- package/src/hooks/api/index.ts +3 -1
- package/src/hooks/api/product-options.tsx +151 -0
- package/src/hooks/api/products.tsx +26 -66
- package/src/hooks/api/translations.tsx +103 -191
- package/src/hooks/table/columns/use-order-table-columns.tsx +5 -3
- package/src/hooks/table/columns/use-product-option-table-columns.tsx +44 -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 +257 -10
- package/src/i18n/translations/en.json +73 -5
- package/src/i18n/translations/es.json +9 -1
- package/src/routes/customers/customer-detail/components/customer-order-section/customer-order-section.tsx +1 -1
- package/src/routes/login/components/cloud-auth-login.tsx +114 -0
- package/src/routes/login/login.tsx +9 -1
- package/src/routes/orders/order-create-edit/components/order-edit-create-form/order-edit-item.tsx +1 -0
- package/src/routes/orders/order-edit-billing-address/components/edit-order-billing-address-form/edit-order-billing-address-form.tsx +34 -0
- package/src/routes/orders/order-edit-shipping-address/components/edit-order-shipping-address-form/edit-order-shipping-address-form.tsx +32 -0
- 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 +84 -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 +82 -0
- package/src/routes/product-options/product-option-detail/index.ts +3 -0
- package/src/routes/product-options/product-option-detail/loader.ts +18 -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 +140 -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-general-section/product-create-general-section.tsx +16 -4
- package/src/routes/products/product-create/components/product-create-details-form/components/product-create-details-variant-section/product-create-details-variant-section.tsx +327 -194
- package/src/routes/products/product-create/components/product-create-form/product-create-form.tsx +4 -7
- package/src/routes/products/product-create/constants.ts +2 -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 +33 -51
- 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 +296 -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/src/routes/promotions/promotion-create/components/create-promotion-form/create-promotion-form.tsx +6 -0
- package/src/routes/translations/add-locales/add-locales.tsx +29 -0
- package/src/routes/translations/add-locales/index.tsx +1 -0
- package/src/routes/translations/translation-list/components/active-locales-section/active-locales-section.tsx +42 -17
- package/src/routes/translations/translation-list/components/translation-list-section/translation-list-section.tsx +5 -1
- package/src/routes/translations/translation-list/components/translations-completion-section/translations-completion-section.tsx +182 -121
- package/src/routes/translations/translations-edit/components/translations-edit-form/translations-edit-form.tsx +330 -361
- package/src/routes/translations/translations-edit/translations-edit.tsx +8 -13
- package/dist/chunk-HGRIOEAR.mjs +0 -32
- package/dist/chunk-XDJ7OMBR.mjs +0 -160
- package/dist/login-VNOLI5YG.mjs +0 -201
- package/dist/product-create-option-7AOXAA4S.mjs +0 -151
- package/dist/product-edit-option-LWJT3CYJ.mjs +0 -156
- package/dist/translation-list-UF7FLXOW.mjs +0 -441
- 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 -30
- 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 -35
- package/dist/{chunk-FBYTX6K7.mjs → chunk-ORWRXJJT.mjs} +4 -4
- package/dist/{location-list-KVBA6J47.mjs → location-list-3WP65J3E.mjs} +1 -1
- package/dist/{user-list-YTZQNYSO.mjs → user-list-3EAKK4XC.mjs} +3 -3
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { zodResolver } from "@hookform/resolvers/zod"
|
|
2
2
|
import { AdminStoreLocale, HttpTypes } from "@medusajs/types"
|
|
3
|
-
import { Button, Prompt, Select, toast } from "@medusajs/ui"
|
|
3
|
+
import { Button, Prompt, Select, toast, Text } from "@medusajs/ui"
|
|
4
4
|
import { ColumnDef } from "@tanstack/react-table"
|
|
5
5
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react"
|
|
6
6
|
import { useForm } from "react-hook-form"
|
|
@@ -18,38 +18,17 @@ import {
|
|
|
18
18
|
import { KeyboundForm } from "../../../../../components/utilities/keybound-form"
|
|
19
19
|
import { useBatchTranslations } from "../../../../../hooks/api/translations"
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
* Schema for a single locale translation.
|
|
23
|
-
*/
|
|
24
|
-
const LocaleTranslationSchema = z.object({
|
|
21
|
+
const EntityTranslationsSchema = z.object({
|
|
25
22
|
id: z.string().nullish(),
|
|
26
|
-
locale_code: z.string(),
|
|
27
23
|
fields: z.record(z.string().optional()),
|
|
28
24
|
})
|
|
29
|
-
export type LocaleTranslationSchema = z.infer<typeof LocaleTranslationSchema>
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Schema for an entity's translations (parent row in DataGrid).
|
|
33
|
-
* Contains all locale translations for that entity.
|
|
34
|
-
*/
|
|
35
|
-
const EntityTranslationsSchema = z.object({
|
|
36
|
-
locales: z.record(LocaleTranslationSchema),
|
|
37
|
-
})
|
|
38
25
|
export type EntityTranslationsSchema = z.infer<typeof EntityTranslationsSchema>
|
|
39
26
|
|
|
40
|
-
/**
|
|
41
|
-
* Form schema
|
|
42
|
-
* Maps each reference_id to their corresponding translations for each locale
|
|
43
|
-
*/
|
|
44
27
|
export const TranslationsFormSchema = z.object({
|
|
45
28
|
entities: z.record(EntityTranslationsSchema),
|
|
46
29
|
})
|
|
47
30
|
export type TranslationsFormSchema = z.infer<typeof TranslationsFormSchema>
|
|
48
31
|
|
|
49
|
-
/**
|
|
50
|
-
* Row types for the DataGrid.
|
|
51
|
-
* Parent rows are entities, subrows are translatable fields.
|
|
52
|
-
*/
|
|
53
32
|
export type TranslationRow = EntityRow | FieldRow
|
|
54
33
|
|
|
55
34
|
export type EntityRow = {
|
|
@@ -72,150 +51,94 @@ export function isFieldRow(row: TranslationRow): row is FieldRow {
|
|
|
72
51
|
return row._type === "field"
|
|
73
52
|
}
|
|
74
53
|
|
|
75
|
-
|
|
54
|
+
type LocaleSnapshot = {
|
|
55
|
+
localeCode: string
|
|
56
|
+
entities: Record<string, EntityTranslationsSchema>
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function buildLocaleSnapshot(
|
|
76
60
|
translations: HttpTypes.AdminTranslation[],
|
|
77
61
|
references: { id: string; [key: string]: string }[],
|
|
78
|
-
|
|
62
|
+
localeCode: string,
|
|
79
63
|
translatableFields: string[]
|
|
80
|
-
):
|
|
81
|
-
const
|
|
64
|
+
): LocaleSnapshot {
|
|
65
|
+
const referenceTranslations = new Map<string, HttpTypes.AdminTranslation>()
|
|
82
66
|
for (const t of translations) {
|
|
83
|
-
|
|
67
|
+
if (t.locale_code === localeCode) {
|
|
68
|
+
referenceTranslations.set(t.reference_id, t)
|
|
69
|
+
}
|
|
84
70
|
}
|
|
85
71
|
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
for (const locale of availableLocales) {
|
|
92
|
-
const key = `${reference.id}:${locale.locale_code}`
|
|
93
|
-
const existing = existingMap.get(key)
|
|
94
|
-
|
|
95
|
-
const fields: Record<string, string> = {}
|
|
96
|
-
for (const fieldName of translatableFields) {
|
|
97
|
-
const fieldValue = (existing?.translations?.[fieldName] as string) ?? ""
|
|
98
|
-
fields[fieldName] = fieldValue
|
|
99
|
-
}
|
|
72
|
+
const entities: Record<string, EntityTranslationsSchema> = {}
|
|
73
|
+
for (const ref of references) {
|
|
74
|
+
const existing = referenceTranslations.get(ref.id)
|
|
75
|
+
const fields: Record<string, string> = {}
|
|
100
76
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
locale_code: locale.locale_code,
|
|
104
|
-
fields,
|
|
105
|
-
}
|
|
77
|
+
for (const fieldName of translatableFields) {
|
|
78
|
+
fields[fieldName] = (existing?.translations?.[fieldName] as string) ?? ""
|
|
106
79
|
}
|
|
107
80
|
|
|
108
|
-
|
|
81
|
+
entities[ref.id] = {
|
|
82
|
+
id: existing?.id ?? null,
|
|
83
|
+
fields,
|
|
84
|
+
}
|
|
109
85
|
}
|
|
110
86
|
|
|
111
|
-
return {
|
|
112
|
-
entities: entitiesTranslationState,
|
|
113
|
-
}
|
|
87
|
+
return { localeCode, entities }
|
|
114
88
|
}
|
|
115
89
|
|
|
116
|
-
function
|
|
117
|
-
|
|
90
|
+
function extendSnapshot(
|
|
91
|
+
snapshot: LocaleSnapshot,
|
|
92
|
+
translations: HttpTypes.AdminTranslation[],
|
|
93
|
+
newReferences: { id: string; [key: string]: string }[],
|
|
118
94
|
translatableFields: string[]
|
|
119
|
-
):
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
_type: "field" as const,
|
|
125
|
-
reference_id: reference.id,
|
|
126
|
-
field_name: fieldName,
|
|
127
|
-
})),
|
|
128
|
-
}))
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
function transformToBatchPayload(
|
|
132
|
-
currentState: TranslationsFormSchema,
|
|
133
|
-
initialState: TranslationsFormSchema,
|
|
134
|
-
entityType: string
|
|
135
|
-
): Required<HttpTypes.AdminBatchTranslations> {
|
|
136
|
-
const payload: Required<HttpTypes.AdminBatchTranslations> = {
|
|
137
|
-
create: [],
|
|
138
|
-
update: [],
|
|
139
|
-
delete: [],
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
for (const [entityId, entityData] of Object.entries(currentState.entities)) {
|
|
143
|
-
for (const [localeCode, localeTranslations] of Object.entries(
|
|
144
|
-
entityData.locales
|
|
145
|
-
)) {
|
|
146
|
-
const initial = initialState.entities[entityId]?.locales[localeCode]
|
|
147
|
-
const hasContent = Object.values(localeTranslations.fields).some(
|
|
148
|
-
(v) => v !== undefined && v.trim() !== ""
|
|
149
|
-
)
|
|
150
|
-
const hadContent =
|
|
151
|
-
initial &&
|
|
152
|
-
Object.values(initial.fields).some(
|
|
153
|
-
(v) => v !== undefined && v.trim() !== ""
|
|
154
|
-
)
|
|
155
|
-
|
|
156
|
-
if (!localeTranslations.id && hasContent) {
|
|
157
|
-
payload.create.push({
|
|
158
|
-
reference_id: entityId,
|
|
159
|
-
reference: entityType,
|
|
160
|
-
locale_code: localeTranslations.locale_code,
|
|
161
|
-
translations: localeTranslations.fields,
|
|
162
|
-
})
|
|
163
|
-
} else if (localeTranslations.id && hasContent) {
|
|
164
|
-
// UPDATE: Has ID and has content - check if changed
|
|
165
|
-
const hasChanged =
|
|
166
|
-
!initial ||
|
|
167
|
-
JSON.stringify(localeTranslations.fields) !==
|
|
168
|
-
JSON.stringify(initial.fields)
|
|
169
|
-
|
|
170
|
-
if (hasChanged) {
|
|
171
|
-
payload.update.push({
|
|
172
|
-
id: localeTranslations.id,
|
|
173
|
-
translations: localeTranslations.fields,
|
|
174
|
-
})
|
|
175
|
-
}
|
|
176
|
-
} else if (localeTranslations.id && !hasContent && hadContent) {
|
|
177
|
-
payload.delete.push(localeTranslations.id)
|
|
178
|
-
}
|
|
95
|
+
): LocaleSnapshot {
|
|
96
|
+
const referenceTranslations = new Map<string, HttpTypes.AdminTranslation>()
|
|
97
|
+
for (const t of translations) {
|
|
98
|
+
if (t.locale_code === snapshot.localeCode) {
|
|
99
|
+
referenceTranslations.set(t.reference_id, t)
|
|
179
100
|
}
|
|
180
101
|
}
|
|
181
102
|
|
|
182
|
-
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
function hasLocaleChanges(
|
|
186
|
-
currentState: TranslationsFormSchema,
|
|
187
|
-
initialState: TranslationsFormSchema,
|
|
188
|
-
localeCode: string
|
|
189
|
-
): boolean {
|
|
190
|
-
for (const [entityId, entityData] of Object.entries(currentState.entities)) {
|
|
191
|
-
const currentLocale = entityData.locales[localeCode]
|
|
192
|
-
const initialLocale = initialState.entities[entityId]?.locales[localeCode]
|
|
103
|
+
const extendedEntities = { ...snapshot.entities }
|
|
193
104
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
105
|
+
for (const ref of newReferences) {
|
|
106
|
+
if (!extendedEntities[ref.id]) {
|
|
107
|
+
const existing = referenceTranslations.get(ref.id)
|
|
108
|
+
const fields: Record<string, string> = {}
|
|
197
109
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
const currentValue = fieldValue ?? ""
|
|
110
|
+
for (const fieldName of translatableFields) {
|
|
111
|
+
fields[fieldName] =
|
|
112
|
+
(existing?.translations?.[fieldName] as string) ?? ""
|
|
113
|
+
}
|
|
203
114
|
|
|
204
|
-
|
|
205
|
-
|
|
115
|
+
extendedEntities[ref.id] = {
|
|
116
|
+
id: existing?.id ?? null,
|
|
117
|
+
fields,
|
|
206
118
|
}
|
|
207
119
|
}
|
|
208
120
|
}
|
|
209
121
|
|
|
210
|
-
return
|
|
122
|
+
return { ...snapshot, entities: extendedEntities }
|
|
211
123
|
}
|
|
212
124
|
|
|
213
|
-
function
|
|
125
|
+
function snapshotToFormValues(
|
|
126
|
+
snapshot: LocaleSnapshot
|
|
127
|
+
): TranslationsFormSchema {
|
|
128
|
+
return { entities: snapshot.entities }
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
type ChangeDetectionResult = {
|
|
132
|
+
hasChanges: boolean
|
|
133
|
+
payload: Required<HttpTypes.AdminBatchTranslations>
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function computeChanges(
|
|
214
137
|
currentState: TranslationsFormSchema,
|
|
215
|
-
|
|
138
|
+
snapshot: LocaleSnapshot,
|
|
216
139
|
entityType: string,
|
|
217
140
|
localeCode: string
|
|
218
|
-
):
|
|
141
|
+
): ChangeDetectionResult {
|
|
219
142
|
const payload: Required<HttpTypes.AdminBatchTranslations> = {
|
|
220
143
|
create: [],
|
|
221
144
|
update: [],
|
|
@@ -223,44 +146,43 @@ function transformSingleLocaleToBatchPayload(
|
|
|
223
146
|
}
|
|
224
147
|
|
|
225
148
|
for (const [entityId, entityData] of Object.entries(currentState.entities)) {
|
|
226
|
-
const
|
|
227
|
-
if (!
|
|
149
|
+
const baseline = snapshot.entities[entityId]
|
|
150
|
+
if (!baseline) {
|
|
151
|
+
continue
|
|
152
|
+
}
|
|
228
153
|
|
|
229
|
-
const
|
|
230
|
-
const hasContent = Object.values(localeTranslations.fields).some(
|
|
154
|
+
const hasContent = Object.values(entityData.fields).some(
|
|
231
155
|
(v) => v !== undefined && v.trim() !== ""
|
|
232
156
|
)
|
|
233
|
-
const hadContent =
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
)
|
|
157
|
+
const hadContent = Object.values(baseline.fields).some(
|
|
158
|
+
(v) => v !== undefined && v.trim() !== ""
|
|
159
|
+
)
|
|
160
|
+
const hasChanged =
|
|
161
|
+
JSON.stringify(entityData.fields) !== JSON.stringify(baseline.fields)
|
|
238
162
|
|
|
239
|
-
if (!
|
|
163
|
+
if (!entityData.id && hasContent) {
|
|
240
164
|
payload.create.push({
|
|
241
165
|
reference_id: entityId,
|
|
242
166
|
reference: entityType,
|
|
243
|
-
locale_code:
|
|
244
|
-
translations:
|
|
167
|
+
locale_code: localeCode,
|
|
168
|
+
translations: entityData.fields,
|
|
245
169
|
})
|
|
246
|
-
} else if (
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
payload.update.push({
|
|
254
|
-
id: localeTranslations.id,
|
|
255
|
-
translations: localeTranslations.fields,
|
|
256
|
-
})
|
|
257
|
-
}
|
|
258
|
-
} else if (localeTranslations.id && !hasContent && hadContent) {
|
|
259
|
-
payload.delete.push(localeTranslations.id)
|
|
170
|
+
} else if (entityData.id && hasContent && hasChanged) {
|
|
171
|
+
payload.update.push({
|
|
172
|
+
id: entityData.id,
|
|
173
|
+
translations: entityData.fields,
|
|
174
|
+
})
|
|
175
|
+
} else if (entityData.id && !hasContent && hadContent) {
|
|
176
|
+
payload.delete.push(entityData.id)
|
|
260
177
|
}
|
|
261
178
|
}
|
|
262
179
|
|
|
263
|
-
|
|
180
|
+
const hasChanges =
|
|
181
|
+
payload.create.length > 0 ||
|
|
182
|
+
payload.update.length > 0 ||
|
|
183
|
+
payload.delete.length > 0
|
|
184
|
+
|
|
185
|
+
return { hasChanges, payload }
|
|
264
186
|
}
|
|
265
187
|
|
|
266
188
|
const columnHelper = createDataGridHelper<
|
|
@@ -268,29 +190,42 @@ const columnHelper = createDataGridHelper<
|
|
|
268
190
|
TranslationsFormSchema
|
|
269
191
|
>()
|
|
270
192
|
|
|
271
|
-
const FIELD_COLUMN_WIDTH =
|
|
193
|
+
const FIELD_COLUMN_WIDTH = 350
|
|
194
|
+
|
|
195
|
+
function buildTranslationRows(
|
|
196
|
+
references: { id: string; [key: string]: string }[],
|
|
197
|
+
translatableFields: string[]
|
|
198
|
+
): TranslationRow[] {
|
|
199
|
+
return references.map((reference) => ({
|
|
200
|
+
_type: "entity" as const,
|
|
201
|
+
reference_id: reference.id,
|
|
202
|
+
subRows: translatableFields.map((fieldName) => ({
|
|
203
|
+
_type: "field" as const,
|
|
204
|
+
reference_id: reference.id,
|
|
205
|
+
field_name: fieldName,
|
|
206
|
+
})),
|
|
207
|
+
}))
|
|
208
|
+
}
|
|
272
209
|
|
|
273
210
|
function useTranslationsGridColumns({
|
|
274
211
|
entities,
|
|
275
|
-
translatableFields,
|
|
276
212
|
availableLocales,
|
|
277
213
|
selectedLocale,
|
|
278
214
|
dynamicColumnWidth,
|
|
279
215
|
}: {
|
|
280
216
|
entities: { id: string; [key: string]: string }[]
|
|
281
|
-
translatableFields: string[]
|
|
282
217
|
availableLocales: AdminStoreLocale[]
|
|
283
218
|
selectedLocale: string
|
|
284
219
|
dynamicColumnWidth: number
|
|
285
220
|
}) {
|
|
286
221
|
const { t } = useTranslation()
|
|
287
222
|
|
|
288
|
-
|
|
223
|
+
return useMemo(() => {
|
|
289
224
|
const selectedLocaleData = availableLocales.find(
|
|
290
225
|
(l) => l.locale_code === selectedLocale
|
|
291
226
|
)
|
|
292
227
|
|
|
293
|
-
const
|
|
228
|
+
const columns: ColumnDef<TranslationRow>[] = [
|
|
294
229
|
columnHelper.column({
|
|
295
230
|
id: "field",
|
|
296
231
|
name: "field",
|
|
@@ -300,19 +235,21 @@ function useTranslationsGridColumns({
|
|
|
300
235
|
const row = context.row.original
|
|
301
236
|
|
|
302
237
|
if (isEntityRow(row)) {
|
|
303
|
-
return
|
|
304
|
-
<DataGrid.ReadonlyCell context={context}></DataGrid.ReadonlyCell>
|
|
305
|
-
)
|
|
238
|
+
return <DataGrid.ReadonlyCell context={context} />
|
|
306
239
|
}
|
|
307
240
|
|
|
308
241
|
return (
|
|
309
242
|
<DataGrid.ReadonlyCell context={context} color="normal">
|
|
310
243
|
<div className="flex h-full w-full items-center gap-x-2 overflow-hidden">
|
|
311
|
-
<
|
|
244
|
+
<Text
|
|
245
|
+
className="text-ui-fg-subtle truncate"
|
|
246
|
+
weight="plus"
|
|
247
|
+
size="small"
|
|
248
|
+
>
|
|
312
249
|
{t(`fields.${row.field_name}`, {
|
|
313
250
|
defaultValue: row.field_name,
|
|
314
251
|
})}
|
|
315
|
-
</
|
|
252
|
+
</Text>
|
|
316
253
|
</div>
|
|
317
254
|
</DataGrid.ReadonlyCell>
|
|
318
255
|
)
|
|
@@ -323,27 +260,29 @@ function useTranslationsGridColumns({
|
|
|
323
260
|
id: "original",
|
|
324
261
|
name: "original",
|
|
325
262
|
size: dynamicColumnWidth,
|
|
326
|
-
header:
|
|
263
|
+
header: () => (
|
|
264
|
+
<Text className="text-ui-fg-base" weight="plus" size="small">
|
|
265
|
+
{t("general.original")}
|
|
266
|
+
</Text>
|
|
267
|
+
),
|
|
327
268
|
disableHiding: true,
|
|
328
269
|
cell: (context) => {
|
|
329
270
|
const row = context.row.original
|
|
330
271
|
|
|
331
272
|
if (isEntityRow(row)) {
|
|
332
|
-
return
|
|
333
|
-
<DataGrid.ReadonlyCell context={context}></DataGrid.ReadonlyCell>
|
|
334
|
-
)
|
|
273
|
+
return <DataGrid.ReadonlyCell context={context} />
|
|
335
274
|
}
|
|
336
275
|
|
|
337
|
-
const entity = entities.find(
|
|
338
|
-
(entity) => entity.id === row.reference_id
|
|
339
|
-
)
|
|
276
|
+
const entity = entities.find((e) => e.id === row.reference_id)
|
|
340
277
|
if (!entity) {
|
|
341
278
|
return null
|
|
342
279
|
}
|
|
343
280
|
|
|
344
281
|
return (
|
|
345
|
-
<DataGrid.ReadonlyCell context={context} isMultiLine>
|
|
346
|
-
|
|
282
|
+
<DataGrid.ReadonlyCell color="normal" context={context} isMultiLine>
|
|
283
|
+
<Text className="text-ui-fg-subtle" weight="plus" size="small">
|
|
284
|
+
{entity[row.field_name]}
|
|
285
|
+
</Text>
|
|
347
286
|
</DataGrid.ReadonlyCell>
|
|
348
287
|
)
|
|
349
288
|
},
|
|
@@ -351,12 +290,16 @@ function useTranslationsGridColumns({
|
|
|
351
290
|
]
|
|
352
291
|
|
|
353
292
|
if (selectedLocaleData) {
|
|
354
|
-
|
|
293
|
+
columns.push(
|
|
355
294
|
columnHelper.column({
|
|
356
295
|
id: selectedLocaleData.locale_code,
|
|
357
296
|
name: selectedLocaleData.locale.name,
|
|
358
297
|
size: dynamicColumnWidth,
|
|
359
|
-
header: () =>
|
|
298
|
+
header: () => (
|
|
299
|
+
<Text className="text-ui-fg-base" weight="plus" size="small">
|
|
300
|
+
{selectedLocaleData.locale.name}
|
|
301
|
+
</Text>
|
|
302
|
+
),
|
|
360
303
|
cell: (context) => {
|
|
361
304
|
const row = context.row.original
|
|
362
305
|
|
|
@@ -364,7 +307,7 @@ function useTranslationsGridColumns({
|
|
|
364
307
|
return <DataGrid.ReadonlyCell context={context} isMultiLine />
|
|
365
308
|
}
|
|
366
309
|
|
|
367
|
-
return <DataGrid.
|
|
310
|
+
return <DataGrid.MultilineCell context={context} />
|
|
368
311
|
},
|
|
369
312
|
field: (context) => {
|
|
370
313
|
const row = context.row.original
|
|
@@ -373,24 +316,15 @@ function useTranslationsGridColumns({
|
|
|
373
316
|
return null
|
|
374
317
|
}
|
|
375
318
|
|
|
376
|
-
return `entities.${row.reference_id}.
|
|
319
|
+
return `entities.${row.reference_id}.fields.${row.field_name}`
|
|
377
320
|
},
|
|
378
|
-
type: "text",
|
|
321
|
+
type: "multiline-text",
|
|
379
322
|
})
|
|
380
323
|
)
|
|
381
324
|
}
|
|
382
325
|
|
|
383
|
-
return
|
|
384
|
-
}, [
|
|
385
|
-
t,
|
|
386
|
-
translatableFields,
|
|
387
|
-
availableLocales,
|
|
388
|
-
selectedLocale,
|
|
389
|
-
entities,
|
|
390
|
-
dynamicColumnWidth,
|
|
391
|
-
])
|
|
392
|
-
|
|
393
|
-
return columns
|
|
326
|
+
return columns
|
|
327
|
+
}, [t, availableLocales, selectedLocale, entities, dynamicColumnWidth])
|
|
394
328
|
}
|
|
395
329
|
|
|
396
330
|
type TranslationsEditFormProps = {
|
|
@@ -445,74 +379,105 @@ export const TranslationsEditForm = ({
|
|
|
445
379
|
const [selectedLocale, setSelectedLocale] = useState<string>(
|
|
446
380
|
availableLocales[0]?.locale_code ?? ""
|
|
447
381
|
)
|
|
448
|
-
|
|
449
382
|
const [showUnsavedPrompt, setShowUnsavedPrompt] = useState(false)
|
|
450
383
|
const [pendingLocale, setPendingLocale] = useState<string | null>(null)
|
|
384
|
+
const [isSwitchingLocale, setIsSwitchingLocale] = useState(false)
|
|
451
385
|
|
|
452
|
-
const
|
|
453
|
-
|
|
454
|
-
() => referenceCount * (translatableFields.length + 1),
|
|
455
|
-
[referenceCount, translatableFields]
|
|
456
|
-
)
|
|
457
|
-
|
|
458
|
-
const initialState = useRef(
|
|
459
|
-
initTranslationsFormState(
|
|
386
|
+
const snapshotRef = useRef<LocaleSnapshot>(
|
|
387
|
+
buildLocaleSnapshot(
|
|
460
388
|
translations,
|
|
461
|
-
|
|
462
|
-
|
|
389
|
+
references,
|
|
390
|
+
selectedLocale,
|
|
463
391
|
translatableFields
|
|
464
392
|
)
|
|
465
393
|
)
|
|
466
394
|
|
|
395
|
+
const knownEntityIdsRef = useRef<Set<string>>(
|
|
396
|
+
new Set(references.map((r) => r.id))
|
|
397
|
+
)
|
|
398
|
+
|
|
399
|
+
const latestPropsRef = useRef({ translations, references })
|
|
400
|
+
useEffect(() => {
|
|
401
|
+
latestPropsRef.current = { translations, references }
|
|
402
|
+
}, [translations, references])
|
|
403
|
+
|
|
467
404
|
const form = useForm<TranslationsFormSchema>({
|
|
468
405
|
resolver: zodResolver(TranslationsFormSchema),
|
|
469
|
-
defaultValues:
|
|
406
|
+
defaultValues: snapshotToFormValues(snapshotRef.current),
|
|
470
407
|
})
|
|
471
408
|
|
|
472
|
-
|
|
473
|
-
() =>
|
|
474
|
-
|
|
475
|
-
|
|
409
|
+
useEffect(() => {
|
|
410
|
+
const currentIds = new Set(references.map((r) => r.id))
|
|
411
|
+
const newReferences = references.filter(
|
|
412
|
+
(r) => !knownEntityIdsRef.current.has(r.id)
|
|
413
|
+
)
|
|
476
414
|
|
|
477
|
-
|
|
415
|
+
if (newReferences.length === 0) {
|
|
416
|
+
return
|
|
417
|
+
}
|
|
478
418
|
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
419
|
+
knownEntityIdsRef.current = currentIds
|
|
420
|
+
snapshotRef.current = extendSnapshot(
|
|
421
|
+
snapshotRef.current,
|
|
422
|
+
translations,
|
|
423
|
+
newReferences,
|
|
424
|
+
translatableFields
|
|
425
|
+
)
|
|
484
426
|
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
selectedLocale
|
|
490
|
-
)
|
|
427
|
+
const currentValues = form.getValues()
|
|
428
|
+
const newFormValues: TranslationsFormSchema = {
|
|
429
|
+
entities: { ...currentValues.entities },
|
|
430
|
+
}
|
|
491
431
|
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
} else {
|
|
496
|
-
setSelectedLocale(newLocale)
|
|
432
|
+
for (const ref of newReferences) {
|
|
433
|
+
if (!newFormValues.entities[ref.id]) {
|
|
434
|
+
newFormValues.entities[ref.id] = snapshotRef.current.entities[ref.id]
|
|
497
435
|
}
|
|
498
|
-
}
|
|
499
|
-
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
form.reset(newFormValues, {
|
|
439
|
+
keepDirty: true,
|
|
440
|
+
keepDirtyValues: true,
|
|
441
|
+
})
|
|
442
|
+
}, [references, translations, translatableFields, form])
|
|
443
|
+
|
|
444
|
+
const rows = useMemo(
|
|
445
|
+
() => buildTranslationRows(references, translatableFields),
|
|
446
|
+
[references, translatableFields]
|
|
447
|
+
)
|
|
448
|
+
|
|
449
|
+
const totalRowCount = useMemo(
|
|
450
|
+
() => referenceCount * (translatableFields.length + 1),
|
|
451
|
+
[referenceCount, translatableFields]
|
|
452
|
+
)
|
|
453
|
+
|
|
454
|
+
const selectedLocaleDisplay = useMemo(
|
|
455
|
+
() =>
|
|
456
|
+
availableLocales.find((l) => l.locale_code === selectedLocale)?.locale
|
|
457
|
+
.name,
|
|
458
|
+
[availableLocales, selectedLocale]
|
|
500
459
|
)
|
|
501
460
|
|
|
461
|
+
const columns = useTranslationsGridColumns({
|
|
462
|
+
entities: references,
|
|
463
|
+
availableLocales,
|
|
464
|
+
selectedLocale,
|
|
465
|
+
dynamicColumnWidth,
|
|
466
|
+
})
|
|
467
|
+
|
|
468
|
+
const { mutateAsync, isPending, invalidateQueries } =
|
|
469
|
+
useBatchTranslations(entityType)
|
|
470
|
+
|
|
502
471
|
const saveCurrentLocale = useCallback(async () => {
|
|
503
472
|
const currentValues = form.getValues()
|
|
504
|
-
const payload =
|
|
473
|
+
const { hasChanges, payload } = computeChanges(
|
|
505
474
|
currentValues,
|
|
506
|
-
|
|
475
|
+
snapshotRef.current,
|
|
507
476
|
entityType,
|
|
508
477
|
selectedLocale
|
|
509
478
|
)
|
|
510
479
|
|
|
511
|
-
if (
|
|
512
|
-
payload.create.length === 0 &&
|
|
513
|
-
payload.update.length === 0 &&
|
|
514
|
-
payload.delete.length === 0
|
|
515
|
-
) {
|
|
480
|
+
if (!hasChanges) {
|
|
516
481
|
return true
|
|
517
482
|
}
|
|
518
483
|
|
|
@@ -524,11 +489,13 @@ export const TranslationsEditForm = ({
|
|
|
524
489
|
|
|
525
490
|
for (let i = 0; i < batchCount; i++) {
|
|
526
491
|
let currentBatchAvailable = BATCH_SIZE
|
|
492
|
+
|
|
527
493
|
const currentBatch: HttpTypes.AdminBatchTranslations = {
|
|
528
494
|
create: [],
|
|
529
495
|
update: [],
|
|
530
496
|
delete: [],
|
|
531
497
|
}
|
|
498
|
+
|
|
532
499
|
if (payload.create.length > 0) {
|
|
533
500
|
currentBatch.create = payload.create.splice(0, currentBatchAvailable)
|
|
534
501
|
currentBatchAvailable -= currentBatch.create.length
|
|
@@ -539,22 +506,36 @@ export const TranslationsEditForm = ({
|
|
|
539
506
|
}
|
|
540
507
|
if (payload.delete.length > 0) {
|
|
541
508
|
currentBatch.delete = payload.delete.splice(0, currentBatchAvailable)
|
|
542
|
-
currentBatchAvailable -= currentBatch.delete.length
|
|
543
509
|
}
|
|
544
510
|
|
|
545
|
-
await mutateAsync(currentBatch
|
|
511
|
+
const response = await mutateAsync(currentBatch, {
|
|
512
|
+
onError: (error) => {
|
|
513
|
+
toast.error(error.message)
|
|
514
|
+
},
|
|
515
|
+
})
|
|
516
|
+
|
|
517
|
+
if (response.created) {
|
|
518
|
+
for (const created of response.created) {
|
|
519
|
+
form.setValue(`entities.${created.reference_id}.id`, created.id, {
|
|
520
|
+
shouldDirty: false,
|
|
521
|
+
})
|
|
522
|
+
if (snapshotRef.current.entities[created.reference_id]) {
|
|
523
|
+
snapshotRef.current.entities[created.reference_id].id = created.id
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
}
|
|
546
527
|
}
|
|
547
528
|
|
|
548
|
-
const
|
|
549
|
-
for (const entityId of Object.keys(
|
|
550
|
-
if (
|
|
551
|
-
|
|
552
|
-
...
|
|
529
|
+
const savedValues = form.getValues()
|
|
530
|
+
for (const entityId of Object.keys(savedValues.entities)) {
|
|
531
|
+
if (snapshotRef.current.entities[entityId]) {
|
|
532
|
+
snapshotRef.current.entities[entityId] = {
|
|
533
|
+
...savedValues.entities[entityId],
|
|
553
534
|
}
|
|
554
535
|
}
|
|
555
536
|
}
|
|
556
|
-
|
|
557
|
-
form.reset(
|
|
537
|
+
|
|
538
|
+
form.reset(savedValues)
|
|
558
539
|
|
|
559
540
|
return true
|
|
560
541
|
} catch (error) {
|
|
@@ -565,19 +546,70 @@ export const TranslationsEditForm = ({
|
|
|
565
546
|
}
|
|
566
547
|
}, [form, entityType, selectedLocale, mutateAsync])
|
|
567
548
|
|
|
549
|
+
const switchToLocale = useCallback(
|
|
550
|
+
async (newLocale: string) => {
|
|
551
|
+
setIsSwitchingLocale(true)
|
|
552
|
+
|
|
553
|
+
try {
|
|
554
|
+
await invalidateQueries()
|
|
555
|
+
|
|
556
|
+
await new Promise((resolve) => requestAnimationFrame(resolve))
|
|
557
|
+
|
|
558
|
+
const { translations, references } = latestPropsRef.current
|
|
559
|
+
|
|
560
|
+
const newSnapshot = buildLocaleSnapshot(
|
|
561
|
+
translations,
|
|
562
|
+
references,
|
|
563
|
+
newLocale,
|
|
564
|
+
translatableFields
|
|
565
|
+
)
|
|
566
|
+
|
|
567
|
+
snapshotRef.current = newSnapshot
|
|
568
|
+
knownEntityIdsRef.current = new Set(references.map((r) => r.id))
|
|
569
|
+
|
|
570
|
+
form.reset(snapshotToFormValues(newSnapshot))
|
|
571
|
+
|
|
572
|
+
setSelectedLocale(newLocale)
|
|
573
|
+
} finally {
|
|
574
|
+
setIsSwitchingLocale(false)
|
|
575
|
+
}
|
|
576
|
+
},
|
|
577
|
+
[translatableFields, form, invalidateQueries]
|
|
578
|
+
)
|
|
579
|
+
|
|
580
|
+
const handleLocaleChange = useCallback(
|
|
581
|
+
(newLocale: string) => {
|
|
582
|
+
if (newLocale === selectedLocale) {
|
|
583
|
+
return
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
const currentValues = form.getValues()
|
|
587
|
+
const { hasChanges } = computeChanges(
|
|
588
|
+
currentValues,
|
|
589
|
+
snapshotRef.current,
|
|
590
|
+
entityType,
|
|
591
|
+
selectedLocale
|
|
592
|
+
)
|
|
593
|
+
|
|
594
|
+
if (hasChanges) {
|
|
595
|
+
setPendingLocale(newLocale)
|
|
596
|
+
setShowUnsavedPrompt(true)
|
|
597
|
+
} else {
|
|
598
|
+
switchToLocale(newLocale)
|
|
599
|
+
}
|
|
600
|
+
},
|
|
601
|
+
[selectedLocale, form, entityType, switchToLocale]
|
|
602
|
+
)
|
|
603
|
+
|
|
568
604
|
const handleSaveAndSwitch = useCallback(async () => {
|
|
569
605
|
const success = await saveCurrentLocale()
|
|
570
606
|
if (success && pendingLocale) {
|
|
571
|
-
toast.success(
|
|
572
|
-
|
|
573
|
-
defaultValue: "Changes saved successfully",
|
|
574
|
-
})
|
|
575
|
-
)
|
|
576
|
-
setSelectedLocale(pendingLocale)
|
|
607
|
+
toast.success(t("translations.edit.successToast"))
|
|
608
|
+
await switchToLocale(pendingLocale)
|
|
577
609
|
}
|
|
578
610
|
setShowUnsavedPrompt(false)
|
|
579
611
|
setPendingLocale(null)
|
|
580
|
-
}, [saveCurrentLocale, pendingLocale, t])
|
|
612
|
+
}, [saveCurrentLocale, pendingLocale, t, switchToLocale])
|
|
581
613
|
|
|
582
614
|
const handleCancelSwitch = useCallback(() => {
|
|
583
615
|
setShowUnsavedPrompt(false)
|
|
@@ -597,108 +629,23 @@ export const TranslationsEditForm = ({
|
|
|
597
629
|
[saveCurrentLocale, t, handleSuccess]
|
|
598
630
|
)
|
|
599
631
|
|
|
600
|
-
const
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
initialState.current,
|
|
604
|
-
entityType
|
|
605
|
-
)
|
|
632
|
+
const handleClose = useCallback(() => {
|
|
633
|
+
invalidateQueries()
|
|
634
|
+
}, [invalidateQueries])
|
|
606
635
|
|
|
607
|
-
|
|
608
|
-
payload.create.length === 0 &&
|
|
609
|
-
payload.update.length === 0 &&
|
|
610
|
-
payload.delete.length === 0
|
|
611
|
-
) {
|
|
612
|
-
return
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
const BATCH_SIZE = 150
|
|
616
|
-
const totalItems =
|
|
617
|
-
payload.create.length + payload.update.length + payload.delete.length
|
|
618
|
-
const batchCount = Math.ceil(totalItems / BATCH_SIZE)
|
|
619
|
-
|
|
620
|
-
for (let i = 0; i < batchCount; i++) {
|
|
621
|
-
let currentBatchAvailable = BATCH_SIZE
|
|
622
|
-
const currentBatch: HttpTypes.AdminBatchTranslations = {
|
|
623
|
-
create: [],
|
|
624
|
-
update: [],
|
|
625
|
-
delete: [],
|
|
626
|
-
}
|
|
627
|
-
if (payload.create.length > 0) {
|
|
628
|
-
currentBatch.create = payload.create.splice(0, currentBatchAvailable)
|
|
629
|
-
currentBatchAvailable -= currentBatch.create.length
|
|
630
|
-
}
|
|
631
|
-
if (payload.update.length > 0) {
|
|
632
|
-
currentBatch.update = payload.update.splice(0, currentBatchAvailable)
|
|
633
|
-
currentBatchAvailable -= currentBatch.update.length
|
|
634
|
-
}
|
|
635
|
-
if (payload.delete.length > 0) {
|
|
636
|
-
currentBatch.delete = payload.delete.splice(0, currentBatchAvailable)
|
|
637
|
-
currentBatchAvailable -= currentBatch.delete.length
|
|
638
|
-
}
|
|
639
|
-
|
|
640
|
-
await mutateAsync(currentBatch, {
|
|
641
|
-
onSuccess: () => {
|
|
642
|
-
if (i === batchCount - 1) {
|
|
643
|
-
toast.success(
|
|
644
|
-
t("translations.edit.successToast", {
|
|
645
|
-
defaultValue: "Translations updated successfully",
|
|
646
|
-
})
|
|
647
|
-
)
|
|
648
|
-
handleSuccess()
|
|
649
|
-
}
|
|
650
|
-
},
|
|
651
|
-
onError: (error) => {
|
|
652
|
-
toast.error(error.message)
|
|
653
|
-
},
|
|
654
|
-
})
|
|
655
|
-
}
|
|
656
|
-
})
|
|
657
|
-
|
|
658
|
-
const columns = useTranslationsGridColumns({
|
|
659
|
-
entities,
|
|
660
|
-
translatableFields,
|
|
661
|
-
availableLocales,
|
|
662
|
-
selectedLocale,
|
|
663
|
-
dynamicColumnWidth,
|
|
664
|
-
})
|
|
665
|
-
|
|
666
|
-
const selectedLocaleDisplay = availableLocales.find(
|
|
667
|
-
(l) => l.locale_code === selectedLocale
|
|
668
|
-
)?.locale.name
|
|
636
|
+
const isLoading = isPending || isSwitchingLocale
|
|
669
637
|
|
|
670
638
|
return (
|
|
671
|
-
<RouteFocusModal.Form form={form}>
|
|
639
|
+
<RouteFocusModal.Form form={form} onClose={handleClose}>
|
|
672
640
|
<KeyboundForm
|
|
673
|
-
onSubmit={
|
|
641
|
+
onSubmit={() => handleSave(true)}
|
|
674
642
|
className="flex h-full flex-col overflow-hidden"
|
|
675
643
|
>
|
|
676
|
-
<RouteFocusModal.Header
|
|
677
|
-
<div className="-my-2 flex w-full items-center justify-between border-l px-4">
|
|
678
|
-
<Select
|
|
679
|
-
value={selectedLocale}
|
|
680
|
-
onValueChange={handleLocaleChange}
|
|
681
|
-
size="small"
|
|
682
|
-
>
|
|
683
|
-
<Select.Trigger className="bg-ui-bg-base w-[200px]">
|
|
684
|
-
<Select.Value>{selectedLocaleDisplay}</Select.Value>
|
|
685
|
-
</Select.Trigger>
|
|
686
|
-
<Select.Content>
|
|
687
|
-
{availableLocales.map((locale) => (
|
|
688
|
-
<Select.Item
|
|
689
|
-
key={locale.locale_code}
|
|
690
|
-
value={locale.locale_code}
|
|
691
|
-
>
|
|
692
|
-
{locale.locale.name}
|
|
693
|
-
</Select.Item>
|
|
694
|
-
))}
|
|
695
|
-
</Select.Content>
|
|
696
|
-
</Select>
|
|
697
|
-
</div>
|
|
698
|
-
</RouteFocusModal.Header>
|
|
644
|
+
<RouteFocusModal.Header />
|
|
699
645
|
<RouteFocusModal.Body className="size-full overflow-hidden">
|
|
700
646
|
<div ref={containerRef} className="size-full">
|
|
701
647
|
<DataGrid
|
|
648
|
+
showColumnsDropdown={false}
|
|
702
649
|
columns={columns}
|
|
703
650
|
data={rows}
|
|
704
651
|
getSubRows={(row) => {
|
|
@@ -708,17 +655,44 @@ export const TranslationsEditForm = ({
|
|
|
708
655
|
}}
|
|
709
656
|
state={form}
|
|
710
657
|
onEditingChange={(editing) => setCloseOnEscape(!editing)}
|
|
711
|
-
totalRowCount={
|
|
658
|
+
totalRowCount={totalRowCount}
|
|
712
659
|
onFetchMore={fetchNextPage}
|
|
713
660
|
isFetchingMore={isFetchingNextPage}
|
|
714
661
|
hasNextPage={hasNextPage}
|
|
662
|
+
headerContent={
|
|
663
|
+
<Select
|
|
664
|
+
disabled={isLoading}
|
|
665
|
+
value={selectedLocale}
|
|
666
|
+
onValueChange={handleLocaleChange}
|
|
667
|
+
size="small"
|
|
668
|
+
>
|
|
669
|
+
<Select.Trigger className="bg-ui-bg-base w-[200px]">
|
|
670
|
+
<Select.Value>{selectedLocaleDisplay}</Select.Value>
|
|
671
|
+
</Select.Trigger>
|
|
672
|
+
<Select.Content>
|
|
673
|
+
{availableLocales.map((locale) => (
|
|
674
|
+
<Select.Item
|
|
675
|
+
key={locale.locale_code}
|
|
676
|
+
value={locale.locale_code}
|
|
677
|
+
>
|
|
678
|
+
{locale.locale.name}
|
|
679
|
+
</Select.Item>
|
|
680
|
+
))}
|
|
681
|
+
</Select.Content>
|
|
682
|
+
</Select>
|
|
683
|
+
}
|
|
715
684
|
/>
|
|
716
685
|
</div>
|
|
717
686
|
</RouteFocusModal.Body>
|
|
718
687
|
<RouteFocusModal.Footer>
|
|
719
688
|
<div className="flex items-center justify-end gap-x-2">
|
|
720
689
|
<RouteFocusModal.Close asChild>
|
|
721
|
-
<Button
|
|
690
|
+
<Button
|
|
691
|
+
type="button"
|
|
692
|
+
size="small"
|
|
693
|
+
variant="secondary"
|
|
694
|
+
isLoading={isLoading}
|
|
695
|
+
>
|
|
722
696
|
{t("actions.cancel")}
|
|
723
697
|
</Button>
|
|
724
698
|
</RouteFocusModal.Close>
|
|
@@ -727,16 +701,11 @@ export const TranslationsEditForm = ({
|
|
|
727
701
|
type="button"
|
|
728
702
|
variant="secondary"
|
|
729
703
|
onClick={() => handleSave(false)}
|
|
730
|
-
isLoading={
|
|
704
|
+
isLoading={isLoading}
|
|
731
705
|
>
|
|
732
706
|
{t("actions.saveChanges")}
|
|
733
707
|
</Button>
|
|
734
|
-
<Button
|
|
735
|
-
size="small"
|
|
736
|
-
type="button"
|
|
737
|
-
onClick={() => handleSave(true)}
|
|
738
|
-
isLoading={isPending}
|
|
739
|
-
>
|
|
708
|
+
<Button size="small" type="submit" isLoading={isLoading}>
|
|
740
709
|
{t("actions.saveAndClose")}
|
|
741
710
|
</Button>
|
|
742
711
|
</div>
|
|
@@ -766,7 +735,7 @@ export const TranslationsEditForm = ({
|
|
|
766
735
|
size="small"
|
|
767
736
|
onClick={handleSaveAndSwitch}
|
|
768
737
|
type="button"
|
|
769
|
-
isLoading={
|
|
738
|
+
isLoading={isLoading}
|
|
770
739
|
>
|
|
771
740
|
{t("actions.saveChanges")}
|
|
772
741
|
</Button>
|