@plentymarkets/shop-core 1.14.4 → 1.15.0
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/module.json +1 -1
- package/dist/runtime/composables/localization/helpers/__tests__/mocks/getAllTranslationsMock.js +12 -12
- package/dist/runtime/composables/localization/helpers/__tests__/mocks/i18nInstanceMock.d.ts +1 -1
- package/dist/runtime/composables/localization/helpers/__tests__/mocks/i18nInstanceTranslatedMock.d.ts +1 -1
- package/dist/runtime/composables/localization/helpers/__tests__/mocks/i18nInstanceTranslatedMock.js +2 -2
- package/dist/runtime/composables/localization/helpers/extractKeysWithValuesHelper.d.ts +1 -1
- package/dist/runtime/composables/localization/helpers/importExportHelper.d.ts +5 -0
- package/dist/runtime/composables/localization/helpers/importExportHelper.js +65 -0
- package/dist/runtime/composables/localization/useEditorLocalizationKeys.d.ts +2 -0
- package/dist/runtime/composables/localization/useEditorLocalizationKeys.js +30 -1
- package/dist/runtime/types/localization.d.ts +5 -0
- package/package.json +1 -1
package/dist/module.json
CHANGED
package/dist/runtime/composables/localization/helpers/__tests__/mocks/getAllTranslationsMock.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
export const GetAllTranslationsMock = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
events: [],
|
|
3
|
+
data: {
|
|
4
|
+
de: {
|
|
5
|
+
welcome: "Willkommen vom Backend",
|
|
6
|
+
auth: {
|
|
7
|
+
login: {
|
|
8
|
+
createAccount: "Sie haben noch kein Konto? Erstellen Sie jetzt Ihr Konto!"
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
11
|
},
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
en: {
|
|
13
|
+
welcome: "Overridden welcome value",
|
|
14
|
+
auth: {
|
|
15
|
+
login: {
|
|
16
|
+
createAccount: "Don't have an account? Sign up now!"
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { I18nInstance } from
|
|
1
|
+
import type { I18nInstance } from '~/src/runtime/types';
|
|
2
2
|
export declare const i18nInstanceMock: I18nInstance;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { I18nInstance } from
|
|
1
|
+
import type { I18nInstance } from '~/src/runtime/types';
|
|
2
2
|
export declare const i18nInstanceTranslatedMock: I18nInstance;
|
package/dist/runtime/composables/localization/helpers/__tests__/mocks/i18nInstanceTranslatedMock.js
CHANGED
|
@@ -8,7 +8,7 @@ export const i18nInstanceTranslatedMock = {
|
|
|
8
8
|
welcome: "Welcome",
|
|
9
9
|
"nested.key": "Nested value",
|
|
10
10
|
translated: {
|
|
11
|
-
|
|
11
|
+
welcome: "Overridden welcome value",
|
|
12
12
|
"another.override": "Another override",
|
|
13
13
|
"nested.translated.key": "Nested translated value"
|
|
14
14
|
}
|
|
@@ -19,7 +19,7 @@ export const i18nInstanceTranslatedMock = {
|
|
|
19
19
|
welcome: "Willkommen",
|
|
20
20
|
"nested.key": "Verschachtelter Wert",
|
|
21
21
|
translated: {
|
|
22
|
-
|
|
22
|
+
welcome: "\xDCberschriebener Wert f\xFCr welcome",
|
|
23
23
|
"another.override": "Weitere \xDCberschreibung",
|
|
24
24
|
"nested.translated.key": "Verschachtelter \xFCbersetzter Wert",
|
|
25
25
|
"key.thatdoesnotexist": "Dieser Schl\xFCssel existiert nur in der \xDCbersetzung"
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { MultilingualKeysState, ImportKeyData } from '../../../types/index.js';
|
|
2
|
+
export declare const parseCSVLine: (line: string) => string[];
|
|
3
|
+
export declare const escapeCSVField: (field: string) => string;
|
|
4
|
+
export declare const generateExportCSV: (selectedLocales: string[], keys: MultilingualKeysState[]) => string;
|
|
5
|
+
export declare const parseImportCSV: (csvContent: string, selectedLocales: string[]) => ImportKeyData[] | null;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export const parseCSVLine = (line) => {
|
|
2
|
+
const result = [];
|
|
3
|
+
let current = "";
|
|
4
|
+
let i = 0;
|
|
5
|
+
while (i < line.length) {
|
|
6
|
+
const char = line[i];
|
|
7
|
+
if (char === "\\" && i + 1 < line.length) {
|
|
8
|
+
current += line[i + 1];
|
|
9
|
+
i += 2;
|
|
10
|
+
} else if (char === ";") {
|
|
11
|
+
result.push(current);
|
|
12
|
+
current = "";
|
|
13
|
+
i++;
|
|
14
|
+
} else {
|
|
15
|
+
current += char;
|
|
16
|
+
i++;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
result.push(current);
|
|
20
|
+
return result;
|
|
21
|
+
};
|
|
22
|
+
export const escapeCSVField = (field) => {
|
|
23
|
+
return field.replace(/\\/g, "\\\\").replace(/;/g, "\\;");
|
|
24
|
+
};
|
|
25
|
+
export const generateExportCSV = (selectedLocales, keys) => {
|
|
26
|
+
if (keys.length === 0 || selectedLocales.length === 0) {
|
|
27
|
+
return "";
|
|
28
|
+
}
|
|
29
|
+
const headers = ["key", ...selectedLocales];
|
|
30
|
+
const rows = [];
|
|
31
|
+
keys.forEach((key) => {
|
|
32
|
+
const row = [key.key];
|
|
33
|
+
selectedLocales.forEach((lang) => {
|
|
34
|
+
const translation = key.translations[lang]?.input ?? "";
|
|
35
|
+
row.push(escapeCSVField(translation));
|
|
36
|
+
});
|
|
37
|
+
rows.push(row);
|
|
38
|
+
});
|
|
39
|
+
return [headers, ...rows].map((row) => row.join(";")).join("\n");
|
|
40
|
+
};
|
|
41
|
+
export const parseImportCSV = (csvContent, selectedLocales) => {
|
|
42
|
+
const data = [];
|
|
43
|
+
const lines = csvContent.split(/\r?\n/);
|
|
44
|
+
const headerRow = parseCSVLine(lines[0] ?? "");
|
|
45
|
+
const locales = headerRow.slice(1);
|
|
46
|
+
for (let i = 1; i < lines.length; i++) {
|
|
47
|
+
const line = lines[i];
|
|
48
|
+
const row = parseCSVLine(line);
|
|
49
|
+
const key = row[0];
|
|
50
|
+
if (!key) {
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
for (let j = 1; j < row.length; j++) {
|
|
54
|
+
if (j - 1 >= locales.length) {
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
const locale = locales[j - 1];
|
|
58
|
+
const value = row[j];
|
|
59
|
+
if (locale && value && selectedLocales.includes(locale)) {
|
|
60
|
+
data.push({ key, locale, value });
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return data;
|
|
65
|
+
};
|
|
@@ -13,6 +13,8 @@ export declare const useEditorLocalizationKeys: () => {
|
|
|
13
13
|
getCategoryFromKey: (key: string) => string;
|
|
14
14
|
getKeyFromFullKey: (key: string) => string;
|
|
15
15
|
saveLocalizations: () => Promise<void>;
|
|
16
|
+
exportFile: (fileName?: string) => void;
|
|
17
|
+
importFile: (data: string) => void;
|
|
16
18
|
keys: import("vue").Ref<MultilingualKeysState[], MultilingualKeysState[]>;
|
|
17
19
|
keysMap: import("vue").Ref<Map<string, MultilingualKeysState>, Map<string, MultilingualKeysState>>;
|
|
18
20
|
filteredKeys: import("vue").Ref<MultilingualKeysState[] | null, MultilingualKeysState[] | null>;
|
|
@@ -4,6 +4,7 @@ import { loadDefaultKeys, loadTranslatedKeys, loadKeysFromBackend } from "./help
|
|
|
4
4
|
import { useSdk, useNotification, useEditorLocalizationLocales } from "#imports";
|
|
5
5
|
import { allLanguages } from "./useEditorLocalizationLocales.js";
|
|
6
6
|
import { unflattenTranslations } from "./helpers/transformationHelper.js";
|
|
7
|
+
import { generateExportCSV, parseImportCSV } from "./helpers/importExportHelper.js";
|
|
7
8
|
const containsSearchTerm = (text, searchQuery) => {
|
|
8
9
|
return text.toLowerCase().indexOf(searchQuery) !== -1;
|
|
9
10
|
};
|
|
@@ -229,6 +230,32 @@ export const useEditorLocalizationKeys = () => {
|
|
|
229
230
|
state.value.loading = false;
|
|
230
231
|
}
|
|
231
232
|
};
|
|
233
|
+
const exportFile = (fileName = "export.csv") => {
|
|
234
|
+
const exportKeys = state.value.filteredKeys ?? state.value.keys;
|
|
235
|
+
const { selectedLocales } = useEditorLocalizationLocales();
|
|
236
|
+
const csvText = generateExportCSV(selectedLocales.value, exportKeys);
|
|
237
|
+
if (csvText.length === 0) return;
|
|
238
|
+
const blob = new Blob([csvText], { type: "text/csv;charset=utf-8;" });
|
|
239
|
+
const url = URL.createObjectURL(blob);
|
|
240
|
+
const link = document.createElement("a");
|
|
241
|
+
link.href = url;
|
|
242
|
+
link.download = fileName;
|
|
243
|
+
link.click();
|
|
244
|
+
URL.revokeObjectURL(url);
|
|
245
|
+
};
|
|
246
|
+
const importFile = (data) => {
|
|
247
|
+
const { selectedLocales } = useEditorLocalizationLocales();
|
|
248
|
+
const parsedData = parseImportCSV(data, selectedLocales.value);
|
|
249
|
+
if (!parsedData || parsedData.length === 0) return;
|
|
250
|
+
parsedData.forEach((importedKey) => {
|
|
251
|
+
const keyState = state.value.keys.find((k) => k.key === importedKey.key);
|
|
252
|
+
if (!keyState) return;
|
|
253
|
+
if (keyState.translations[importedKey.locale] !== void 0) {
|
|
254
|
+
keyState.translations[importedKey.locale].input = importedKey.value;
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
state.value.hasChanges = checkHasUnsavedChanges();
|
|
258
|
+
};
|
|
232
259
|
return {
|
|
233
260
|
...toRefs(state.value),
|
|
234
261
|
updateTranslationInput,
|
|
@@ -239,6 +266,8 @@ export const useEditorLocalizationKeys = () => {
|
|
|
239
266
|
getTranslatedCount,
|
|
240
267
|
getCategoryFromKey,
|
|
241
268
|
getKeyFromFullKey,
|
|
242
|
-
saveLocalizations
|
|
269
|
+
saveLocalizations,
|
|
270
|
+
exportFile,
|
|
271
|
+
importFile
|
|
243
272
|
};
|
|
244
273
|
};
|