@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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@plentymarkets/shop-core",
3
3
  "configKey": "shopCore",
4
- "version": "1.14.4",
4
+ "version": "1.15.0",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "unknown"
@@ -1,19 +1,19 @@
1
1
  export const GetAllTranslationsMock = {
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!"
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
- "en": {
13
- "welcome": "Overridden welcome value",
14
- "auth": {
15
- "login": {
16
- "createAccount": "Don't have an account? Sign up now!"
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 "~/src/runtime/types";
1
+ import type { I18nInstance } from '~/src/runtime/types';
2
2
  export declare const i18nInstanceMock: I18nInstance;
@@ -1,2 +1,2 @@
1
- import type { I18nInstance } from "~/src/runtime/types";
1
+ import type { I18nInstance } from '~/src/runtime/types';
2
2
  export declare const i18nInstanceTranslatedMock: I18nInstance;
@@ -8,7 +8,7 @@ export const i18nInstanceTranslatedMock = {
8
8
  welcome: "Welcome",
9
9
  "nested.key": "Nested value",
10
10
  translated: {
11
- "welcome": "Overridden welcome value",
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
- "welcome": "\xDCberschriebener Wert f\xFCr welcome",
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"
@@ -1,4 +1,4 @@
1
- import type { LocalizationMessage } from "~/src/module";
1
+ import type { LocalizationMessage } from '~/src/module';
2
2
  /**
3
3
  * Get translation value from compiled message or string
4
4
  * @param value
@@ -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
  };
@@ -4,6 +4,11 @@ export type MultilingualKeysState = {
4
4
  [locale: string]: LocalizationMessage;
5
5
  };
6
6
  };
7
+ export type ImportKeyData = {
8
+ key: string;
9
+ locale: string;
10
+ value: string;
11
+ };
7
12
  export type CompiledMessage = {
8
13
  type?: number;
9
14
  loc?: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plentymarkets/shop-core",
3
- "version": "1.14.4",
3
+ "version": "1.15.0",
4
4
  "description": "Core module for PlentyONE Shop",
5
5
  "repository": {
6
6
  "type": "git",