@medusajs/dashboard 2.12.3-snapshot-20251216185234 → 2.12.3
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-GGNZCABB.mjs +81 -0
- package/dist/{api-key-management-detail-6RCDH73M.mjs → api-key-management-detail-FRUN2KFK.mjs} +1 -1
- package/dist/app.css +19 -0
- package/dist/app.js +795 -680
- package/dist/app.mjs +2 -2
- package/dist/{campaign-detail-5Q4BYCPX.mjs → campaign-detail-HM3GQJLQ.mjs} +1 -1
- package/dist/{categories-metadata-J7M3XWI7.mjs → categories-metadata-WKL3MGD7.mjs} +1 -1
- package/dist/{category-detail-S5IPXMHX.mjs → category-detail-UTWWDKFP.mjs} +2 -2
- package/dist/{category-products-KPW6BA5J.mjs → category-products-XXBTCXFF.mjs} +2 -2
- package/dist/{chunk-OL24RDYM.mjs → chunk-5F427YCP.mjs} +2 -2
- package/dist/{chunk-MJDHVDOW.mjs → chunk-5ISRTMYH.mjs} +1 -1
- package/dist/{chunk-ST4P6BQN.mjs → chunk-DQUXK4WW.mjs} +1 -1
- package/dist/{chunk-YYOPBKME.mjs → chunk-DTCIBQO2.mjs} +1 -1
- package/dist/{chunk-LZFWCKOF.mjs → chunk-FKNW5MLZ.mjs} +21 -4
- package/dist/{chunk-GRZSG4EP.mjs → chunk-GLBHPDR4.mjs} +21 -16
- package/dist/{chunk-WYATCUOM.mjs → chunk-HNJ65IND.mjs} +1 -1
- package/dist/{store-add-locales-VJ4RJ7UI.mjs → chunk-IKTGFXWR.mjs} +2 -67
- package/dist/{chunk-DBXWB3RF.mjs → chunk-KSDXSKJ7.mjs} +1 -1
- package/dist/{chunk-OL6MEUKW.mjs → chunk-LWYKUORZ.mjs} +108 -105
- package/dist/{chunk-PHLCT2HA.mjs → chunk-OK6NZN2A.mjs} +1 -1
- package/dist/{chunk-ZMG5B4FG.mjs → chunk-SG2JZPTG.mjs} +1 -1
- package/dist/{chunk-CVHJAKLQ.mjs → chunk-UMCJYHAD.mjs} +1 -1
- package/dist/{collection-add-products-FU2BS3D3.mjs → collection-add-products-42F7H77E.mjs} +2 -2
- package/dist/{collection-detail-VJE7XHLV.mjs → collection-detail-PXIS3G64.mjs} +2 -2
- package/dist/{collection-list-IGA6SCNF.mjs → collection-list-O74CGY24.mjs} +2 -2
- package/dist/{collection-metadata-QK7MI3D2.mjs → collection-metadata-U6FMA4IC.mjs} +1 -1
- package/dist/{customer-detail-MOV2T3LF.mjs → customer-detail-OMTFJ6CE.mjs} +1 -1
- package/dist/{customer-group-detail-6T7OXGQD.mjs → customer-group-detail-ADK3M5LG.mjs} +1 -1
- package/dist/{customer-group-list-AJEAF5D2.mjs → customer-group-list-7ZRQ2HWU.mjs} +1 -1
- package/dist/{customers-add-customer-group-QVTVSQYM.mjs → customers-add-customer-group-5U27WHJB.mjs} +1 -1
- package/dist/{edit-rules-SMVRTCUP.mjs → edit-rules-BM2ERGVJ.mjs} +1 -1
- package/dist/en.json +1 -2
- package/dist/{inventory-create-BK52VALF.mjs → inventory-create-7MA7B5N2.mjs} +2 -2
- package/dist/{inventory-detail-ZPSEMYI2.mjs → inventory-detail-B4PRHZK3.mjs} +1 -1
- package/dist/{inventory-metadata-FNEJ3RAT.mjs → inventory-metadata-C7MJ3GY5.mjs} +1 -1
- package/dist/{inventory-stock-6WYWLWJ7.mjs → inventory-stock-WVTYPJTX.mjs} +3 -3
- package/dist/{location-detail-N3GUZSY7.mjs → location-detail-KO6EBDK5.mjs} +1 -1
- package/dist/{location-fulfillment-providers-7ZUJAGNY.mjs → location-fulfillment-providers-IORBE3E3.mjs} +2 -2
- package/dist/{location-service-zone-shipping-option-create-CNRWYZQC.mjs → location-service-zone-shipping-option-create-2R3ZFLVK.mjs} +3 -3
- package/dist/{location-service-zone-shipping-option-pricing-OGWI7VPT.mjs → location-service-zone-shipping-option-pricing-5HN2Z5RB.mjs} +2 -2
- package/dist/{login-VNOLI5YG.mjs → login-XKB6OR7I.mjs} +1 -1
- package/dist/{order-create-claim-SCDJGM46.mjs → order-create-claim-NKCOGF4A.mjs} +1 -1
- package/dist/{order-create-edit-2WALBPXS.mjs → order-create-edit-UNQYXGLL.mjs} +1 -1
- package/dist/{order-create-exchange-LQU4YN7F.mjs → order-create-exchange-WI7OA2WO.mjs} +1 -1
- package/dist/{order-create-fulfillment-OWUVTZXW.mjs → order-create-fulfillment-2LJTEWDY.mjs} +1 -1
- package/dist/{order-create-refund-Q6HQY42R.mjs → order-create-refund-7K6UJXGP.mjs} +1 -1
- package/dist/{order-create-shipment-WAGGEPRW.mjs → order-create-shipment-ZTDLLUBY.mjs} +1 -1
- package/dist/{order-detail-PVPGEWGY.mjs → order-detail-JTRUMRLO.mjs} +1 -1
- package/dist/{order-edit-billing-address-UM76J4KX.mjs → order-edit-billing-address-YHYNVLOE.mjs} +1 -1
- package/dist/{order-edit-email-CL3KNOCM.mjs → order-edit-email-TCQPEVZY.mjs} +1 -1
- package/dist/{order-edit-shipping-address-PIESTGVL.mjs → order-edit-shipping-address-CFSYQLKD.mjs} +1 -1
- package/dist/{order-export-LE363ZLB.mjs → order-export-G4SBNEJ7.mjs} +1 -1
- package/dist/{order-metadata-FHBB7MTG.mjs → order-metadata-KGPB37VL.mjs} +1 -1
- package/dist/{order-receive-return-PRVKP6J2.mjs → order-receive-return-JER24SEV.mjs} +1 -1
- package/dist/{order-request-transfer-XSAGRUMT.mjs → order-request-transfer-3FBUYZNT.mjs} +1 -1
- package/dist/{price-list-create-K5JEZT57.mjs → price-list-create-CXZCFFTP.mjs} +4 -4
- package/dist/{price-list-detail-Q5VG5VGW.mjs → price-list-detail-XOMU6U5J.mjs} +2 -2
- package/dist/{price-list-prices-add-2MQ226U4.mjs → price-list-prices-add-SDX5CQME.mjs} +4 -4
- package/dist/{price-list-prices-edit-OJZLV7OS.mjs → price-list-prices-edit-EKB6NI5D.mjs} +2 -2
- package/dist/{product-attributes-YF4TZOIO.mjs → product-attributes-STD47BGC.mjs} +2 -2
- package/dist/{product-create-KJML2332.mjs → product-create-LVGWVQAT.mjs} +3 -3
- package/dist/{product-create-variant-5EBCLM54.mjs → product-create-variant-OTJKT6WI.mjs} +2 -2
- package/dist/{product-detail-QG72542C.mjs → product-detail-OYVHJH3D.mjs} +2 -2
- package/dist/{product-edit-DZZR775Q.mjs → product-edit-3SIUUIW4.mjs} +2 -2
- package/dist/{product-export-5AD7NELI.mjs → product-export-57UUAGXF.mjs} +2 -2
- package/dist/{product-image-variants-edit-M6QF2RLE.mjs → product-image-variants-edit-2BW5BJON.mjs} +1 -1
- package/dist/{product-import-V3KQN4TV.mjs → product-import-6EM4VUXP.mjs} +1 -1
- package/dist/{product-list-EUWZIFTM.mjs → product-list-5V5GEH5K.mjs} +2 -2
- package/dist/{product-metadata-GL2MVPDI.mjs → product-metadata-JZLHBLZQ.mjs} +1 -1
- package/dist/{product-organization-O7RHELMQ.mjs → product-organization-3PQ45C4B.mjs} +2 -2
- package/dist/{product-prices-YWV6MSM6.mjs → product-prices-5ZL2RP7A.mjs} +1 -1
- package/dist/{product-stock-AKEFMK5O.mjs → product-stock-SJJABF6I.mjs} +3 -3
- package/dist/{product-tag-create-PQMDDKWH.mjs → product-tag-create-XXO4AQEC.mjs} +1 -1
- package/dist/{product-tag-detail-I3MBZX7U.mjs → product-tag-detail-BSK64HXL.mjs} +3 -3
- package/dist/{product-tag-edit-K3BBQLJR.mjs → product-tag-edit-ENCGDT7E.mjs} +1 -1
- package/dist/{product-tag-list-JUWSOMB7.mjs → product-tag-list-SLQGCNDZ.mjs} +3 -3
- package/dist/{product-tag-metadata-MJH5LH7E.mjs → product-tag-metadata-EPXHMU2K.mjs} +1 -1
- package/dist/{product-type-detail-RKHT5NBL.mjs → product-type-detail-4CRRU7YK.mjs} +2 -2
- package/dist/{product-type-metadata-CDJDFFGQ.mjs → product-type-metadata-73OKOGPP.mjs} +1 -1
- package/dist/{product-variant-detail-XAYG5CKE.mjs → product-variant-detail-RPHLG4HU.mjs} +1 -1
- package/dist/{product-variant-edit-DEZEY2H2.mjs → product-variant-edit-JF7NN64Y.mjs} +1 -1
- package/dist/{product-variant-metadata-VTZDNWUT.mjs → product-variant-metadata-HU2CXGPO.mjs} +1 -1
- package/dist/{promotion-create-HWFNUQXG.mjs → promotion-create-BHA3FQG2.mjs} +1 -1
- package/dist/{promotion-detail-QC36KXB3.mjs → promotion-detail-F3QSR52W.mjs} +1 -1
- package/dist/{refund-reason-create-YHCDEHGQ.mjs → refund-reason-create-ZA5TKW2Z.mjs} +1 -1
- package/dist/{refund-reason-edit-CZ5QZ2SZ.mjs → refund-reason-edit-N2CRCLKZ.mjs} +1 -1
- package/dist/{refund-reason-list-OJYYEYJE.mjs → refund-reason-list-SE4TMGMT.mjs} +1 -1
- package/dist/{region-metadata-H6XXUQ4S.mjs → region-metadata-O5NZBWXP.mjs} +1 -1
- package/dist/{reservation-detail-LZAQL4XA.mjs → reservation-detail-UFK6XIXE.mjs} +1 -1
- package/dist/{reservation-metadata-5HZSDDOK.mjs → reservation-metadata-AEJEKGLV.mjs} +1 -1
- package/dist/{sales-channel-add-products-F7YV4MO5.mjs → sales-channel-add-products-2LMB7EF5.mjs} +2 -2
- package/dist/{sales-channel-detail-MXIPZCGA.mjs → sales-channel-detail-EUQ4STQI.mjs} +2 -2
- package/dist/{sales-channel-list-RLGL7FM3.mjs → sales-channel-list-JXKGHX4G.mjs} +1 -1
- package/dist/{sales-channel-metadata-M364R4RJ.mjs → sales-channel-metadata-AJMQ5SQ2.mjs} +1 -1
- package/dist/{shipping-option-type-create-C5WUWON7.mjs → shipping-option-type-create-YVVIA2XC.mjs} +1 -1
- package/dist/{shipping-option-type-detail-PENS2K73.mjs → shipping-option-type-detail-ZZW36XLK.mjs} +2 -2
- package/dist/{shipping-option-type-edit-CIU5EHRP.mjs → shipping-option-type-edit-O6F74T3A.mjs} +1 -1
- package/dist/{shipping-option-type-list-DIOX7VG7.mjs → shipping-option-type-list-SPTE7MT6.mjs} +2 -2
- package/dist/{shipping-profile-metadata-75G2NNMA.mjs → shipping-profile-metadata-7WFE55VG.mjs} +1 -1
- package/dist/store-add-locales-GWCGIXHU.mjs +81 -0
- package/dist/{store-detail-JSNPOB2F.mjs → store-detail-YLJLBBZE.mjs} +1 -1
- package/dist/{store-metadata-CYXTVJUE.mjs → store-metadata-BZ57I2E6.mjs} +1 -1
- package/dist/{tax-region-create-DWGL4EUT.mjs → tax-region-create-FGTV7VJL.mjs} +1 -1
- package/dist/{tax-region-detail-2AE2EFI3.mjs → tax-region-detail-PPIMD7OX.mjs} +5 -5
- package/dist/{tax-region-edit-EEVEEU2Q.mjs → tax-region-edit-ELZKA7YH.mjs} +1 -1
- package/dist/{tax-region-province-detail-4ERSEQFF.mjs → tax-region-province-detail-FV2NDT3E.mjs} +5 -5
- package/dist/{tax-region-tax-override-create-PHCGEF7V.mjs → tax-region-tax-override-create-N572MQPZ.mjs} +3 -3
- package/dist/{tax-region-tax-override-edit-SMRPSILC.mjs → tax-region-tax-override-edit-5DCSJW6D.mjs} +4 -4
- package/dist/{translation-list-UF7FLXOW.mjs → translation-list-FK7XYLHX.mjs} +227 -141
- package/dist/{translations-edit-USQJNMAY.mjs → translations-edit-VRXZI5KW.mjs} +224 -253
- package/dist/{user-metadata-2WPJOEJA.mjs → user-metadata-GRJZZ524.mjs} +1 -1
- package/dist/{workflow-execution-detail-H2AKEZJX.mjs → workflow-execution-detail-HXTFWGKG.mjs} +1 -1
- package/package.json +9 -9
- package/src/components/data-grid/hooks/use-data-grid-cell.tsx +1 -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 +22 -4
- package/src/dashboard-app/routes/get-route.map.tsx +4 -0
- package/src/hooks/api/translations.tsx +26 -17
- package/src/i18n/translations/en.json +1 -2
- package/src/i18n/translations/es.json +1 -1
- 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 +285 -330
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DataGrid,
|
|
3
3
|
createDataGridHelper
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-FKNW5MLZ.mjs";
|
|
5
5
|
import "./chunk-DK4WIVY6.mjs";
|
|
6
6
|
import "./chunk-IUCDCPJU.mjs";
|
|
7
7
|
import {
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
useBatchTranslations,
|
|
24
24
|
useReferenceTranslations,
|
|
25
25
|
useTranslationSettings
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-GLBHPDR4.mjs";
|
|
27
27
|
import "./chunk-I4OBEAOJ.mjs";
|
|
28
28
|
import "./chunk-HI6URQ7H.mjs";
|
|
29
29
|
import "./chunk-6CLQKVAU.mjs";
|
|
@@ -69,169 +69,125 @@ import { useForm } from "react-hook-form";
|
|
|
69
69
|
import { useTranslation } from "react-i18next";
|
|
70
70
|
import { z } from "zod";
|
|
71
71
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
72
|
-
var
|
|
72
|
+
var EntityTranslationsSchema = z.object({
|
|
73
73
|
id: z.string().nullish(),
|
|
74
|
-
locale_code: z.string(),
|
|
75
74
|
fields: z.record(z.string().optional())
|
|
76
75
|
});
|
|
77
|
-
var EntityTranslationsSchema = z.object({
|
|
78
|
-
locales: z.record(LocaleTranslationSchema)
|
|
79
|
-
});
|
|
80
76
|
var TranslationsFormSchema = z.object({
|
|
81
77
|
entities: z.record(EntityTranslationsSchema)
|
|
82
78
|
});
|
|
83
79
|
function isEntityRow(row) {
|
|
84
80
|
return row._type === "entity";
|
|
85
81
|
}
|
|
86
|
-
function
|
|
87
|
-
const
|
|
82
|
+
function buildLocaleSnapshot(translations, references, localeCode, translatableFields) {
|
|
83
|
+
const referenceTranslations = /* @__PURE__ */ new Map();
|
|
84
|
+
for (const t of translations) {
|
|
85
|
+
if (t.locale_code === localeCode) {
|
|
86
|
+
referenceTranslations.set(t.reference_id, t);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const entities = {};
|
|
90
|
+
for (const ref of references) {
|
|
91
|
+
const existing = referenceTranslations.get(ref.id);
|
|
92
|
+
const fields = {};
|
|
93
|
+
for (const fieldName of translatableFields) {
|
|
94
|
+
fields[fieldName] = existing?.translations?.[fieldName] ?? "";
|
|
95
|
+
}
|
|
96
|
+
entities[ref.id] = {
|
|
97
|
+
id: existing?.id ?? null,
|
|
98
|
+
fields
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
return { localeCode, entities };
|
|
102
|
+
}
|
|
103
|
+
function extendSnapshot(snapshot, translations, newReferences, translatableFields) {
|
|
104
|
+
const referenceTranslations = /* @__PURE__ */ new Map();
|
|
88
105
|
for (const t of translations) {
|
|
89
|
-
|
|
106
|
+
if (t.locale_code === snapshot.localeCode) {
|
|
107
|
+
referenceTranslations.set(t.reference_id, t);
|
|
108
|
+
}
|
|
90
109
|
}
|
|
91
|
-
const
|
|
92
|
-
for (const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
const key = `${reference.id}:${locale.locale_code}`;
|
|
96
|
-
const existing = existingMap.get(key);
|
|
110
|
+
const extendedEntities = { ...snapshot.entities };
|
|
111
|
+
for (const ref of newReferences) {
|
|
112
|
+
if (!extendedEntities[ref.id]) {
|
|
113
|
+
const existing = referenceTranslations.get(ref.id);
|
|
97
114
|
const fields = {};
|
|
98
115
|
for (const fieldName of translatableFields) {
|
|
99
|
-
|
|
100
|
-
fields[fieldName] = fieldValue;
|
|
116
|
+
fields[fieldName] = existing?.translations?.[fieldName] ?? "";
|
|
101
117
|
}
|
|
102
|
-
|
|
118
|
+
extendedEntities[ref.id] = {
|
|
103
119
|
id: existing?.id ?? null,
|
|
104
|
-
locale_code: locale.locale_code,
|
|
105
120
|
fields
|
|
106
121
|
};
|
|
107
122
|
}
|
|
108
|
-
entitiesTranslationState[reference.id] = { locales };
|
|
109
123
|
}
|
|
110
|
-
return {
|
|
111
|
-
entities: entitiesTranslationState
|
|
112
|
-
};
|
|
124
|
+
return { ...snapshot, entities: extendedEntities };
|
|
113
125
|
}
|
|
114
|
-
function
|
|
115
|
-
return
|
|
116
|
-
_type: "entity",
|
|
117
|
-
reference_id: reference.id,
|
|
118
|
-
subRows: translatableFields.map((fieldName) => ({
|
|
119
|
-
_type: "field",
|
|
120
|
-
reference_id: reference.id,
|
|
121
|
-
field_name: fieldName
|
|
122
|
-
}))
|
|
123
|
-
}));
|
|
126
|
+
function snapshotToFormValues(snapshot) {
|
|
127
|
+
return { entities: snapshot.entities };
|
|
124
128
|
}
|
|
125
|
-
function
|
|
129
|
+
function computeChanges(currentState, snapshot, entityType, localeCode) {
|
|
126
130
|
const payload = {
|
|
127
131
|
create: [],
|
|
128
132
|
update: [],
|
|
129
133
|
delete: []
|
|
130
134
|
};
|
|
131
135
|
for (const [entityId, entityData] of Object.entries(currentState.entities)) {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
)) {
|
|
135
|
-
const initial = initialState.entities[entityId]?.locales[localeCode];
|
|
136
|
-
const hasContent = Object.values(localeTranslations.fields).some(
|
|
137
|
-
(v) => v !== void 0 && v.trim() !== ""
|
|
138
|
-
);
|
|
139
|
-
const hadContent = initial && Object.values(initial.fields).some(
|
|
140
|
-
(v) => v !== void 0 && v.trim() !== ""
|
|
141
|
-
);
|
|
142
|
-
if (!localeTranslations.id && hasContent) {
|
|
143
|
-
payload.create.push({
|
|
144
|
-
reference_id: entityId,
|
|
145
|
-
reference: entityType,
|
|
146
|
-
locale_code: localeTranslations.locale_code,
|
|
147
|
-
translations: localeTranslations.fields
|
|
148
|
-
});
|
|
149
|
-
} else if (localeTranslations.id && hasContent) {
|
|
150
|
-
const hasChanged = !initial || JSON.stringify(localeTranslations.fields) !== JSON.stringify(initial.fields);
|
|
151
|
-
if (hasChanged) {
|
|
152
|
-
payload.update.push({
|
|
153
|
-
id: localeTranslations.id,
|
|
154
|
-
translations: localeTranslations.fields
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
|
-
} else if (localeTranslations.id && !hasContent && hadContent) {
|
|
158
|
-
payload.delete.push(localeTranslations.id);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
return payload;
|
|
163
|
-
}
|
|
164
|
-
function hasLocaleChanges(currentState, initialState, localeCode) {
|
|
165
|
-
for (const [entityId, entityData] of Object.entries(currentState.entities)) {
|
|
166
|
-
const currentLocale = entityData.locales[localeCode];
|
|
167
|
-
const initialLocale = initialState.entities[entityId]?.locales[localeCode];
|
|
168
|
-
if (!currentLocale || !initialLocale) {
|
|
136
|
+
const baseline = snapshot.entities[entityId];
|
|
137
|
+
if (!baseline) {
|
|
169
138
|
continue;
|
|
170
139
|
}
|
|
171
|
-
|
|
172
|
-
currentLocale.fields
|
|
173
|
-
)) {
|
|
174
|
-
const initialValue = initialLocale.fields[fieldName] ?? "";
|
|
175
|
-
const currentValue = fieldValue ?? "";
|
|
176
|
-
if (currentValue !== initialValue) {
|
|
177
|
-
return true;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
return false;
|
|
182
|
-
}
|
|
183
|
-
function transformSingleLocaleToBatchPayload(currentState, initialState, entityType, localeCode) {
|
|
184
|
-
const payload = {
|
|
185
|
-
create: [],
|
|
186
|
-
update: [],
|
|
187
|
-
delete: []
|
|
188
|
-
};
|
|
189
|
-
for (const [entityId, entityData] of Object.entries(currentState.entities)) {
|
|
190
|
-
const localeTranslations = entityData.locales[localeCode];
|
|
191
|
-
if (!localeTranslations) continue;
|
|
192
|
-
const initial = initialState.entities[entityId]?.locales[localeCode];
|
|
193
|
-
const hasContent = Object.values(localeTranslations.fields).some(
|
|
140
|
+
const hasContent = Object.values(entityData.fields).some(
|
|
194
141
|
(v) => v !== void 0 && v.trim() !== ""
|
|
195
142
|
);
|
|
196
|
-
const hadContent =
|
|
143
|
+
const hadContent = Object.values(baseline.fields).some(
|
|
197
144
|
(v) => v !== void 0 && v.trim() !== ""
|
|
198
145
|
);
|
|
199
|
-
|
|
146
|
+
const hasChanged = JSON.stringify(entityData.fields) !== JSON.stringify(baseline.fields);
|
|
147
|
+
if (!entityData.id && hasContent) {
|
|
200
148
|
payload.create.push({
|
|
201
149
|
reference_id: entityId,
|
|
202
150
|
reference: entityType,
|
|
203
|
-
locale_code:
|
|
204
|
-
translations:
|
|
151
|
+
locale_code: localeCode,
|
|
152
|
+
translations: entityData.fields
|
|
205
153
|
});
|
|
206
|
-
} else if (
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
}
|
|
214
|
-
} else if (localeTranslations.id && !hasContent && hadContent) {
|
|
215
|
-
payload.delete.push(localeTranslations.id);
|
|
154
|
+
} else if (entityData.id && hasContent && hasChanged) {
|
|
155
|
+
payload.update.push({
|
|
156
|
+
id: entityData.id,
|
|
157
|
+
translations: entityData.fields
|
|
158
|
+
});
|
|
159
|
+
} else if (entityData.id && !hasContent && hadContent) {
|
|
160
|
+
payload.delete.push(entityData.id);
|
|
216
161
|
}
|
|
217
162
|
}
|
|
218
|
-
|
|
163
|
+
const hasChanges = payload.create.length > 0 || payload.update.length > 0 || payload.delete.length > 0;
|
|
164
|
+
return { hasChanges, payload };
|
|
219
165
|
}
|
|
220
166
|
var columnHelper = createDataGridHelper();
|
|
221
|
-
var FIELD_COLUMN_WIDTH =
|
|
167
|
+
var FIELD_COLUMN_WIDTH = 350;
|
|
168
|
+
function buildTranslationRows(references, translatableFields) {
|
|
169
|
+
return references.map((reference) => ({
|
|
170
|
+
_type: "entity",
|
|
171
|
+
reference_id: reference.id,
|
|
172
|
+
subRows: translatableFields.map((fieldName) => ({
|
|
173
|
+
_type: "field",
|
|
174
|
+
reference_id: reference.id,
|
|
175
|
+
field_name: fieldName
|
|
176
|
+
}))
|
|
177
|
+
}));
|
|
178
|
+
}
|
|
222
179
|
function useTranslationsGridColumns({
|
|
223
180
|
entities,
|
|
224
|
-
translatableFields,
|
|
225
181
|
availableLocales,
|
|
226
182
|
selectedLocale,
|
|
227
183
|
dynamicColumnWidth
|
|
228
184
|
}) {
|
|
229
185
|
const { t } = useTranslation();
|
|
230
|
-
|
|
186
|
+
return useMemo(() => {
|
|
231
187
|
const selectedLocaleData = availableLocales.find(
|
|
232
188
|
(l) => l.locale_code === selectedLocale
|
|
233
189
|
);
|
|
234
|
-
const
|
|
190
|
+
const columns = [
|
|
235
191
|
columnHelper.column({
|
|
236
192
|
id: "field",
|
|
237
193
|
name: "field",
|
|
@@ -267,9 +223,7 @@ function useTranslationsGridColumns({
|
|
|
267
223
|
if (isEntityRow(row)) {
|
|
268
224
|
return /* @__PURE__ */ jsx(DataGrid.ReadonlyCell, { context });
|
|
269
225
|
}
|
|
270
|
-
const entity = entities.find(
|
|
271
|
-
(entity2) => entity2.id === row.reference_id
|
|
272
|
-
);
|
|
226
|
+
const entity = entities.find((e) => e.id === row.reference_id);
|
|
273
227
|
if (!entity) {
|
|
274
228
|
return null;
|
|
275
229
|
}
|
|
@@ -278,7 +232,7 @@ function useTranslationsGridColumns({
|
|
|
278
232
|
})
|
|
279
233
|
];
|
|
280
234
|
if (selectedLocaleData) {
|
|
281
|
-
|
|
235
|
+
columns.push(
|
|
282
236
|
columnHelper.column({
|
|
283
237
|
id: selectedLocaleData.locale_code,
|
|
284
238
|
name: selectedLocaleData.locale.name,
|
|
@@ -296,22 +250,14 @@ function useTranslationsGridColumns({
|
|
|
296
250
|
if (isEntityRow(row)) {
|
|
297
251
|
return null;
|
|
298
252
|
}
|
|
299
|
-
return `entities.${row.reference_id}.
|
|
253
|
+
return `entities.${row.reference_id}.fields.${row.field_name}`;
|
|
300
254
|
},
|
|
301
255
|
type: "multiline-text"
|
|
302
256
|
})
|
|
303
257
|
);
|
|
304
258
|
}
|
|
305
|
-
return
|
|
306
|
-
}, [
|
|
307
|
-
t,
|
|
308
|
-
translatableFields,
|
|
309
|
-
availableLocales,
|
|
310
|
-
selectedLocale,
|
|
311
|
-
entities,
|
|
312
|
-
dynamicColumnWidth
|
|
313
|
-
]);
|
|
314
|
-
return columns;
|
|
259
|
+
return columns;
|
|
260
|
+
}, [t, availableLocales, selectedLocale, entities, dynamicColumnWidth]);
|
|
315
261
|
}
|
|
316
262
|
var TranslationsEditForm = ({
|
|
317
263
|
translations,
|
|
@@ -349,57 +295,83 @@ var TranslationsEditForm = ({
|
|
|
349
295
|
);
|
|
350
296
|
const [showUnsavedPrompt, setShowUnsavedPrompt] = useState(false);
|
|
351
297
|
const [pendingLocale, setPendingLocale] = useState(null);
|
|
352
|
-
const
|
|
353
|
-
const
|
|
354
|
-
(
|
|
355
|
-
[referenceCount, translatableFields]
|
|
356
|
-
);
|
|
357
|
-
const initialState = useRef(
|
|
358
|
-
initTranslationsFormState(
|
|
298
|
+
const [isSwitchingLocale, setIsSwitchingLocale] = useState(false);
|
|
299
|
+
const snapshotRef = useRef(
|
|
300
|
+
buildLocaleSnapshot(
|
|
359
301
|
translations,
|
|
360
|
-
|
|
361
|
-
|
|
302
|
+
references,
|
|
303
|
+
selectedLocale,
|
|
362
304
|
translatableFields
|
|
363
305
|
)
|
|
364
306
|
);
|
|
307
|
+
const knownEntityIdsRef = useRef(
|
|
308
|
+
new Set(references.map((r) => r.id))
|
|
309
|
+
);
|
|
310
|
+
const latestPropsRef = useRef({ translations, references });
|
|
311
|
+
useEffect(() => {
|
|
312
|
+
latestPropsRef.current = { translations, references };
|
|
313
|
+
}, [translations, references]);
|
|
365
314
|
const form = useForm({
|
|
366
315
|
resolver: zodResolver(TranslationsFormSchema),
|
|
367
|
-
defaultValues:
|
|
316
|
+
defaultValues: snapshotToFormValues(snapshotRef.current)
|
|
368
317
|
});
|
|
318
|
+
useEffect(() => {
|
|
319
|
+
const currentIds = new Set(references.map((r) => r.id));
|
|
320
|
+
const newReferences = references.filter(
|
|
321
|
+
(r) => !knownEntityIdsRef.current.has(r.id)
|
|
322
|
+
);
|
|
323
|
+
if (newReferences.length === 0) {
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
knownEntityIdsRef.current = currentIds;
|
|
327
|
+
snapshotRef.current = extendSnapshot(
|
|
328
|
+
snapshotRef.current,
|
|
329
|
+
translations,
|
|
330
|
+
newReferences,
|
|
331
|
+
translatableFields
|
|
332
|
+
);
|
|
333
|
+
const currentValues = form.getValues();
|
|
334
|
+
const newFormValues = {
|
|
335
|
+
entities: { ...currentValues.entities }
|
|
336
|
+
};
|
|
337
|
+
for (const ref of newReferences) {
|
|
338
|
+
if (!newFormValues.entities[ref.id]) {
|
|
339
|
+
newFormValues.entities[ref.id] = snapshotRef.current.entities[ref.id];
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
form.reset(newFormValues, {
|
|
343
|
+
keepDirty: true,
|
|
344
|
+
keepDirtyValues: true
|
|
345
|
+
});
|
|
346
|
+
}, [references, translations, translatableFields, form]);
|
|
369
347
|
const rows = useMemo(
|
|
370
|
-
() => buildTranslationRows(
|
|
371
|
-
[
|
|
348
|
+
() => buildTranslationRows(references, translatableFields),
|
|
349
|
+
[references, translatableFields]
|
|
372
350
|
);
|
|
373
|
-
const
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
const hasChanges = hasLocaleChanges(
|
|
381
|
-
currentValues,
|
|
382
|
-
initialState.current,
|
|
383
|
-
selectedLocale
|
|
384
|
-
);
|
|
385
|
-
if (hasChanges) {
|
|
386
|
-
setPendingLocale(newLocale);
|
|
387
|
-
setShowUnsavedPrompt(true);
|
|
388
|
-
} else {
|
|
389
|
-
setSelectedLocale(newLocale);
|
|
390
|
-
}
|
|
391
|
-
},
|
|
392
|
-
[selectedLocale, form]
|
|
351
|
+
const totalRowCount = useMemo(
|
|
352
|
+
() => referenceCount * (translatableFields.length + 1),
|
|
353
|
+
[referenceCount, translatableFields]
|
|
354
|
+
);
|
|
355
|
+
const selectedLocaleDisplay = useMemo(
|
|
356
|
+
() => availableLocales.find((l) => l.locale_code === selectedLocale)?.locale.name,
|
|
357
|
+
[availableLocales, selectedLocale]
|
|
393
358
|
);
|
|
359
|
+
const columns = useTranslationsGridColumns({
|
|
360
|
+
entities: references,
|
|
361
|
+
availableLocales,
|
|
362
|
+
selectedLocale,
|
|
363
|
+
dynamicColumnWidth
|
|
364
|
+
});
|
|
365
|
+
const { mutateAsync, isPending, invalidateQueries } = useBatchTranslations(entityType);
|
|
394
366
|
const saveCurrentLocale = useCallback(async () => {
|
|
395
367
|
const currentValues = form.getValues();
|
|
396
|
-
const payload =
|
|
368
|
+
const { hasChanges, payload } = computeChanges(
|
|
397
369
|
currentValues,
|
|
398
|
-
|
|
370
|
+
snapshotRef.current,
|
|
399
371
|
entityType,
|
|
400
372
|
selectedLocale
|
|
401
373
|
);
|
|
402
|
-
if (
|
|
374
|
+
if (!hasChanges) {
|
|
403
375
|
return true;
|
|
404
376
|
}
|
|
405
377
|
try {
|
|
@@ -423,20 +395,32 @@ var TranslationsEditForm = ({
|
|
|
423
395
|
}
|
|
424
396
|
if (payload.delete.length > 0) {
|
|
425
397
|
currentBatch.delete = payload.delete.splice(0, currentBatchAvailable);
|
|
426
|
-
currentBatchAvailable -= currentBatch.delete.length;
|
|
427
398
|
}
|
|
428
|
-
await mutateAsync(currentBatch
|
|
399
|
+
const response = await mutateAsync(currentBatch, {
|
|
400
|
+
onError: (error) => {
|
|
401
|
+
toast.error(error.message);
|
|
402
|
+
}
|
|
403
|
+
});
|
|
404
|
+
if (response.created) {
|
|
405
|
+
for (const created of response.created) {
|
|
406
|
+
form.setValue(`entities.${created.reference_id}.id`, created.id, {
|
|
407
|
+
shouldDirty: false
|
|
408
|
+
});
|
|
409
|
+
if (snapshotRef.current.entities[created.reference_id]) {
|
|
410
|
+
snapshotRef.current.entities[created.reference_id].id = created.id;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
429
414
|
}
|
|
430
|
-
const
|
|
431
|
-
for (const entityId of Object.keys(
|
|
432
|
-
if (
|
|
433
|
-
|
|
434
|
-
...
|
|
415
|
+
const savedValues = form.getValues();
|
|
416
|
+
for (const entityId of Object.keys(savedValues.entities)) {
|
|
417
|
+
if (snapshotRef.current.entities[entityId]) {
|
|
418
|
+
snapshotRef.current.entities[entityId] = {
|
|
419
|
+
...savedValues.entities[entityId]
|
|
435
420
|
};
|
|
436
421
|
}
|
|
437
422
|
}
|
|
438
|
-
|
|
439
|
-
form.reset(currentValues);
|
|
423
|
+
form.reset(savedValues);
|
|
440
424
|
return true;
|
|
441
425
|
} catch (error) {
|
|
442
426
|
toast.error(
|
|
@@ -445,19 +429,59 @@ var TranslationsEditForm = ({
|
|
|
445
429
|
return false;
|
|
446
430
|
}
|
|
447
431
|
}, [form, entityType, selectedLocale, mutateAsync]);
|
|
432
|
+
const switchToLocale = useCallback(
|
|
433
|
+
async (newLocale) => {
|
|
434
|
+
setIsSwitchingLocale(true);
|
|
435
|
+
try {
|
|
436
|
+
await invalidateQueries();
|
|
437
|
+
await new Promise((resolve) => requestAnimationFrame(resolve));
|
|
438
|
+
const { translations: translations2, references: references2 } = latestPropsRef.current;
|
|
439
|
+
const newSnapshot = buildLocaleSnapshot(
|
|
440
|
+
translations2,
|
|
441
|
+
references2,
|
|
442
|
+
newLocale,
|
|
443
|
+
translatableFields
|
|
444
|
+
);
|
|
445
|
+
snapshotRef.current = newSnapshot;
|
|
446
|
+
knownEntityIdsRef.current = new Set(references2.map((r) => r.id));
|
|
447
|
+
form.reset(snapshotToFormValues(newSnapshot));
|
|
448
|
+
setSelectedLocale(newLocale);
|
|
449
|
+
} finally {
|
|
450
|
+
setIsSwitchingLocale(false);
|
|
451
|
+
}
|
|
452
|
+
},
|
|
453
|
+
[translatableFields, form, invalidateQueries]
|
|
454
|
+
);
|
|
455
|
+
const handleLocaleChange = useCallback(
|
|
456
|
+
(newLocale) => {
|
|
457
|
+
if (newLocale === selectedLocale) {
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
const currentValues = form.getValues();
|
|
461
|
+
const { hasChanges } = computeChanges(
|
|
462
|
+
currentValues,
|
|
463
|
+
snapshotRef.current,
|
|
464
|
+
entityType,
|
|
465
|
+
selectedLocale
|
|
466
|
+
);
|
|
467
|
+
if (hasChanges) {
|
|
468
|
+
setPendingLocale(newLocale);
|
|
469
|
+
setShowUnsavedPrompt(true);
|
|
470
|
+
} else {
|
|
471
|
+
switchToLocale(newLocale);
|
|
472
|
+
}
|
|
473
|
+
},
|
|
474
|
+
[selectedLocale, form, entityType, switchToLocale]
|
|
475
|
+
);
|
|
448
476
|
const handleSaveAndSwitch = useCallback(async () => {
|
|
449
477
|
const success = await saveCurrentLocale();
|
|
450
478
|
if (success && pendingLocale) {
|
|
451
|
-
toast.success(
|
|
452
|
-
|
|
453
|
-
defaultValue: "Changes saved successfully"
|
|
454
|
-
})
|
|
455
|
-
);
|
|
456
|
-
setSelectedLocale(pendingLocale);
|
|
479
|
+
toast.success(t("translations.edit.successToast"));
|
|
480
|
+
await switchToLocale(pendingLocale);
|
|
457
481
|
}
|
|
458
482
|
setShowUnsavedPrompt(false);
|
|
459
483
|
setPendingLocale(null);
|
|
460
|
-
}, [saveCurrentLocale, pendingLocale, t]);
|
|
484
|
+
}, [saveCurrentLocale, pendingLocale, t, switchToLocale]);
|
|
461
485
|
const handleCancelSwitch = useCallback(() => {
|
|
462
486
|
setShowUnsavedPrompt(false);
|
|
463
487
|
setPendingLocale(null);
|
|
@@ -474,69 +498,15 @@ var TranslationsEditForm = ({
|
|
|
474
498
|
},
|
|
475
499
|
[saveCurrentLocale, t, handleSuccess]
|
|
476
500
|
);
|
|
477
|
-
const
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
);
|
|
483
|
-
if (payload.create.length === 0 && payload.update.length === 0 && payload.delete.length === 0) {
|
|
484
|
-
return;
|
|
485
|
-
}
|
|
486
|
-
const BATCH_SIZE = 150;
|
|
487
|
-
const totalItems = payload.create.length + payload.update.length + payload.delete.length;
|
|
488
|
-
const batchCount = Math.ceil(totalItems / BATCH_SIZE);
|
|
489
|
-
for (let i = 0; i < batchCount; i++) {
|
|
490
|
-
let currentBatchAvailable = BATCH_SIZE;
|
|
491
|
-
const currentBatch = {
|
|
492
|
-
create: [],
|
|
493
|
-
update: [],
|
|
494
|
-
delete: []
|
|
495
|
-
};
|
|
496
|
-
if (payload.create.length > 0) {
|
|
497
|
-
currentBatch.create = payload.create.splice(0, currentBatchAvailable);
|
|
498
|
-
currentBatchAvailable -= currentBatch.create.length;
|
|
499
|
-
}
|
|
500
|
-
if (payload.update.length > 0) {
|
|
501
|
-
currentBatch.update = payload.update.splice(0, currentBatchAvailable);
|
|
502
|
-
currentBatchAvailable -= currentBatch.update.length;
|
|
503
|
-
}
|
|
504
|
-
if (payload.delete.length > 0) {
|
|
505
|
-
currentBatch.delete = payload.delete.splice(0, currentBatchAvailable);
|
|
506
|
-
currentBatchAvailable -= currentBatch.delete.length;
|
|
507
|
-
}
|
|
508
|
-
await mutateAsync(currentBatch, {
|
|
509
|
-
onSuccess: () => {
|
|
510
|
-
if (i === batchCount - 1) {
|
|
511
|
-
toast.success(
|
|
512
|
-
t("translations.edit.successToast", {
|
|
513
|
-
defaultValue: "Translations updated successfully"
|
|
514
|
-
})
|
|
515
|
-
);
|
|
516
|
-
handleSuccess();
|
|
517
|
-
}
|
|
518
|
-
},
|
|
519
|
-
onError: (error) => {
|
|
520
|
-
toast.error(error.message);
|
|
521
|
-
}
|
|
522
|
-
});
|
|
523
|
-
}
|
|
524
|
-
});
|
|
525
|
-
const columns = useTranslationsGridColumns({
|
|
526
|
-
entities,
|
|
527
|
-
translatableFields,
|
|
528
|
-
availableLocales,
|
|
529
|
-
selectedLocale,
|
|
530
|
-
dynamicColumnWidth
|
|
531
|
-
});
|
|
532
|
-
const selectedLocaleDisplay = availableLocales.find(
|
|
533
|
-
(l) => l.locale_code === selectedLocale
|
|
534
|
-
)?.locale.name;
|
|
535
|
-
return /* @__PURE__ */ jsxs(RouteFocusModal.Form, { form, children: [
|
|
501
|
+
const handleClose = useCallback(() => {
|
|
502
|
+
invalidateQueries();
|
|
503
|
+
}, [invalidateQueries]);
|
|
504
|
+
const isLoading = isPending || isSwitchingLocale;
|
|
505
|
+
return /* @__PURE__ */ jsxs(RouteFocusModal.Form, { form, onClose: handleClose, children: [
|
|
536
506
|
/* @__PURE__ */ jsxs(
|
|
537
507
|
KeyboundForm,
|
|
538
508
|
{
|
|
539
|
-
onSubmit:
|
|
509
|
+
onSubmit: () => handleSave(true),
|
|
540
510
|
className: "flex h-full flex-col overflow-hidden",
|
|
541
511
|
children: [
|
|
542
512
|
/* @__PURE__ */ jsx(RouteFocusModal.Header, {}),
|
|
@@ -553,13 +523,14 @@ var TranslationsEditForm = ({
|
|
|
553
523
|
},
|
|
554
524
|
state: form,
|
|
555
525
|
onEditingChange: (editing) => setCloseOnEscape(!editing),
|
|
556
|
-
totalRowCount
|
|
526
|
+
totalRowCount,
|
|
557
527
|
onFetchMore: fetchNextPage,
|
|
558
528
|
isFetchingMore: isFetchingNextPage,
|
|
559
529
|
hasNextPage,
|
|
560
530
|
headerContent: /* @__PURE__ */ jsxs(
|
|
561
531
|
Select,
|
|
562
532
|
{
|
|
533
|
+
disabled: isLoading,
|
|
563
534
|
value: selectedLocale,
|
|
564
535
|
onValueChange: handleLocaleChange,
|
|
565
536
|
size: "small",
|
|
@@ -579,28 +550,28 @@ var TranslationsEditForm = ({
|
|
|
579
550
|
}
|
|
580
551
|
) }) }),
|
|
581
552
|
/* @__PURE__ */ jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
|
|
582
|
-
/* @__PURE__ */ jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
583
|
-
/* @__PURE__ */ jsx(
|
|
553
|
+
/* @__PURE__ */ jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
584
554
|
Button,
|
|
585
555
|
{
|
|
586
|
-
size: "small",
|
|
587
556
|
type: "button",
|
|
557
|
+
size: "small",
|
|
588
558
|
variant: "secondary",
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
children: t("actions.saveChanges")
|
|
559
|
+
isLoading,
|
|
560
|
+
children: t("actions.cancel")
|
|
592
561
|
}
|
|
593
|
-
),
|
|
562
|
+
) }),
|
|
594
563
|
/* @__PURE__ */ jsx(
|
|
595
564
|
Button,
|
|
596
565
|
{
|
|
597
566
|
size: "small",
|
|
598
567
|
type: "button",
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
568
|
+
variant: "secondary",
|
|
569
|
+
onClick: () => handleSave(false),
|
|
570
|
+
isLoading,
|
|
571
|
+
children: t("actions.saveChanges")
|
|
602
572
|
}
|
|
603
|
-
)
|
|
573
|
+
),
|
|
574
|
+
/* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading, children: t("actions.saveAndClose") })
|
|
604
575
|
] }) })
|
|
605
576
|
]
|
|
606
577
|
}
|
|
@@ -627,7 +598,7 @@ var TranslationsEditForm = ({
|
|
|
627
598
|
size: "small",
|
|
628
599
|
onClick: handleSaveAndSwitch,
|
|
629
600
|
type: "button",
|
|
630
|
-
isLoading
|
|
601
|
+
isLoading,
|
|
631
602
|
children: t("actions.saveChanges")
|
|
632
603
|
}
|
|
633
604
|
)
|
|
@@ -12,7 +12,7 @@ import "./chunk-LPEUYMRK.mjs";
|
|
|
12
12
|
import "./chunk-OC7BQLYI.mjs";
|
|
13
13
|
import "./chunk-S4DMV3ZT.mjs";
|
|
14
14
|
import "./chunk-OBQI23QM.mjs";
|
|
15
|
-
import "./chunk-
|
|
15
|
+
import "./chunk-GLBHPDR4.mjs";
|
|
16
16
|
import "./chunk-I4OBEAOJ.mjs";
|
|
17
17
|
import "./chunk-HI6URQ7H.mjs";
|
|
18
18
|
import "./chunk-6CLQKVAU.mjs";
|