@localazy/strapi-plugin 0.1.6 → 0.1.9
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/.github/workflows/.build.yml +2 -13
- package/admin/src/modules/@common/components/PluginPageLoader/index.js +22 -0
- package/admin/src/modules/@common/services/product-analytics-service.js +67 -0
- package/admin/src/modules/@common/utils/__tests__/iso-locales-utils.test.js +102 -0
- package/admin/src/modules/@common/utils/format-number.js +1 -0
- package/admin/src/modules/@common/utils/iso-locales-utils.js +45 -2
- package/admin/src/modules/plugin-settings/components/ContentTransferSetup/index.js +33 -22
- package/admin/src/modules/plugin-settings/components/ContentTransferSetupEmpty/index.js +86 -0
- package/admin/src/modules/plugin-settings/components/Tree/index.js +10 -1
- package/admin/src/modules/plugin-settings/locale/en.js +7 -0
- package/admin/src/modules/plugin-settings/services/plugin-settings-service.js +23 -0
- package/admin/src/pages/App/index.js +4 -2
- package/admin/src/pages/Download/index.js +16 -1
- package/admin/src/pages/Login/index.js +8 -1
- package/admin/src/pages/Settings/index.js +17 -3
- package/admin/src/pages/Upload/index.js +17 -1
- package/admin/src/plugins/analytics-service.js +14 -0
- package/admin/src/utils/createPluginConnectorAxiosInstance.js +45 -0
- package/package.json +4 -4
- package/server/config/development/index.js +2 -2
- package/server/config/index.js +10 -5
- package/server/config/local/index.js +15 -0
- package/server/controllers/localazy-transfer-controller.js +3 -1
- package/server/controllers/plugin-settings-controller.js +14 -0
- package/server/db/model/plugin-settings.js +13 -0
- package/server/routes/plugin-settings.js +16 -0
- package/server/services/plugin-settings-service.js +28 -7
- package/server/services/strapi-i18n-service.js +3 -3
- package/server/utils/__tests__/iso-locales-utils.test.js +104 -0
- package/server/utils/intl-display-name.js +2 -5
- package/server/utils/iso-locales-utils.js +40 -2
|
@@ -10,20 +10,9 @@ jobs:
|
|
|
10
10
|
run: pwd && sudo chown -R $USER:$USER ./
|
|
11
11
|
- uses: actions/checkout@v2
|
|
12
12
|
- name: Setup Node.js environment
|
|
13
|
-
uses: actions/setup-node@
|
|
13
|
+
uses: actions/setup-node@v3
|
|
14
14
|
with:
|
|
15
|
-
node-version: 14.x
|
|
16
|
-
- name: Cache node modules
|
|
17
|
-
uses: actions/cache@v1
|
|
18
|
-
env:
|
|
19
|
-
cache-name: cache-node-modules
|
|
20
|
-
with:
|
|
21
|
-
path: ~/.npm # npm cache files are stored in `~/.npm` on Linux/macOS
|
|
22
|
-
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
|
|
23
|
-
restore-keys: |
|
|
24
|
-
${{ runner.os }}-build-${{ env.cache-name }}-
|
|
25
|
-
${{ runner.os }}-build-
|
|
26
|
-
${{ runner.os }}-
|
|
15
|
+
node-version: 14.x
|
|
27
16
|
- name: Install dependencies
|
|
28
17
|
run: npm ci
|
|
29
18
|
- name: Run unit tests
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Flex } from '@strapi/design-system/Flex';
|
|
3
|
+
import { Loader } from "@strapi/design-system/Loader";
|
|
4
|
+
import { useTranslation } from "react-i18next";
|
|
5
|
+
|
|
6
|
+
import "../../../../i18n";
|
|
7
|
+
|
|
8
|
+
function PluginPageLoader() {
|
|
9
|
+
const { t } = useTranslation();
|
|
10
|
+
|
|
11
|
+
return (
|
|
12
|
+
<Flex
|
|
13
|
+
marginTop={10}
|
|
14
|
+
alignItems="center"
|
|
15
|
+
justifyContent="center"
|
|
16
|
+
>
|
|
17
|
+
<Loader>{t("common.loading_content")}</Loader>
|
|
18
|
+
</Flex>
|
|
19
|
+
)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default PluginPageLoader;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import AnalyticsService from "../../../plugins/analytics-service";
|
|
2
|
+
|
|
3
|
+
export default class ProductAnalyticsService {
|
|
4
|
+
static async trackAppConnected(userId, project, params = {}) {
|
|
5
|
+
try {
|
|
6
|
+
const data = this.buildData(userId, "Strapi Connected", project, params);
|
|
7
|
+
await AnalyticsService.trackEvent(data.event, {
|
|
8
|
+
...data.data,
|
|
9
|
+
userId,
|
|
10
|
+
category: "Project",
|
|
11
|
+
});
|
|
12
|
+
} catch (e) {
|
|
13
|
+
console.warn(e);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
static async trackAppDisconnected(userId, project, params = {}) {
|
|
18
|
+
try {
|
|
19
|
+
const data = this.buildData(userId, "Strapi Disconnected", project, params);
|
|
20
|
+
await AnalyticsService.trackEvent(data.event, {
|
|
21
|
+
...data.data,
|
|
22
|
+
userId,
|
|
23
|
+
category: "Project",
|
|
24
|
+
});
|
|
25
|
+
} catch (e) {
|
|
26
|
+
console.warn(e);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
static async trackUploadToLocalazy(userId, project, params = {}) {
|
|
31
|
+
try {
|
|
32
|
+
const data = this.buildData(userId, "Strapi Upload", project, params);
|
|
33
|
+
await AnalyticsService.trackEvent(data.event, {
|
|
34
|
+
...data.data,
|
|
35
|
+
userId,
|
|
36
|
+
category: "Project",
|
|
37
|
+
});
|
|
38
|
+
} catch (e) {
|
|
39
|
+
console.warn(e);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
static async trackDownloadToStrapi(userId, project, params = {}) {
|
|
44
|
+
try {
|
|
45
|
+
const data = this.buildData(userId, "Strapi Download", project, params);
|
|
46
|
+
await AnalyticsService.trackEvent(data.event, {
|
|
47
|
+
...data.data,
|
|
48
|
+
userId,
|
|
49
|
+
category: "Project",
|
|
50
|
+
});
|
|
51
|
+
} catch (e) {
|
|
52
|
+
console.warn(e);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
static buildData(userId, event, project, params) {
|
|
57
|
+
return {
|
|
58
|
+
event,
|
|
59
|
+
data: {
|
|
60
|
+
"User Id": userId,
|
|
61
|
+
"Project Id": project.id,
|
|
62
|
+
"Project Name": project.name,
|
|
63
|
+
...params,
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
const { isoStrapiToLocalazy, isoLocalazyToStrapi } = require("../iso-locales-utils");
|
|
2
|
+
|
|
3
|
+
describe("iso-locales-utils.js", () => {
|
|
4
|
+
describe("transform Strapi ISO to Localazy ISO", () => {
|
|
5
|
+
it("should transform codes containing lang only", () => {
|
|
6
|
+
// setup
|
|
7
|
+
const input = ["en", "fr", "de", "es", "it", "ja", "ko", "pt", "ru", "zh"];
|
|
8
|
+
|
|
9
|
+
// execute
|
|
10
|
+
const output = input.map((item) => isoStrapiToLocalazy(item));
|
|
11
|
+
|
|
12
|
+
// verify
|
|
13
|
+
const expected = input;
|
|
14
|
+
expect(output).toEqual(expected);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it("should transform codes containing lang-region", () => {
|
|
18
|
+
// setup
|
|
19
|
+
const input = ["en-US", "fr-CA", "de-DE", "es-ES", "it-IT", "ja-JP", "ko-KR", "pt-BR", "ru-RU", "zh-CN"];
|
|
20
|
+
|
|
21
|
+
// execute
|
|
22
|
+
const output = input.map((item) => isoStrapiToLocalazy(item));
|
|
23
|
+
|
|
24
|
+
// verify
|
|
25
|
+
const expected = ["en_US", "fr_CA", "de_DE", "es_ES", "it_IT", "ja_JP", "ko_KR", "pt_BR", "ru_RU", "zh_CN"];
|
|
26
|
+
expect(output).toEqual(expected);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("should transform codes containing lang-script", () => {
|
|
30
|
+
// setup
|
|
31
|
+
const input = ["en-Latn", "fr-Latn", "de-Latn", "es-Latn", "it-Latn", "ja-Latn", "ko-Latn", "pt-Latn", "ru-Latn", "zh-Latn"];
|
|
32
|
+
|
|
33
|
+
// execute
|
|
34
|
+
const output = input.map((item) => isoStrapiToLocalazy(item));
|
|
35
|
+
|
|
36
|
+
// verify
|
|
37
|
+
const expected = ["en#Latn", "fr#Latn", "de#Latn", "es#Latn", "it#Latn", "ja#Latn", "ko#Latn", "pt#Latn", "ru#Latn", "zh#Latn"];
|
|
38
|
+
expect(output).toEqual(expected);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("should transform codes containing lang-script-region", () => {
|
|
42
|
+
// setup
|
|
43
|
+
const input = ["en-Latn-US", "fr-Latn-CA", "de-Latn-DE", "es-Latn-ES", "it-Latn-IT", "ja-Latn-JP", "ko-Latn-KR", "pt-Latn-BR", "ru-Latn-RU", "zh-Hant-CN"];
|
|
44
|
+
|
|
45
|
+
// execute
|
|
46
|
+
const output = input.map((item) => isoStrapiToLocalazy(item));
|
|
47
|
+
|
|
48
|
+
// verify
|
|
49
|
+
const expected = ["en_US#Latn", "fr_CA#Latn", "de_DE#Latn", "es_ES#Latn", "it_IT#Latn", "ja_JP#Latn", "ko_KR#Latn", "pt_BR#Latn", "ru_RU#Latn", "zh_CN#Hant"];
|
|
50
|
+
expect(output).toEqual(expected);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
describe("transform Strapi ISO to Localazy ISO", () => {
|
|
55
|
+
it("should transform codes containing lang only", () => {
|
|
56
|
+
// setup
|
|
57
|
+
const input = ["en", "fr", "de", "es", "it", "ja", "ko", "pt", "ru", "zh"];
|
|
58
|
+
|
|
59
|
+
// execute
|
|
60
|
+
const output = input.map((item) => isoLocalazyToStrapi(item));
|
|
61
|
+
|
|
62
|
+
// verify
|
|
63
|
+
const expected = input;
|
|
64
|
+
expect(output).toEqual(expected);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it("should transform codes containing lang-region", () => {
|
|
68
|
+
// setup
|
|
69
|
+
const input = ["en_US", "fr_CA", "de_DE", "es_ES", "it_IT", "ja_JP", "ko_KR", "pt_BR", "ru_RU", "zh_CN"];
|
|
70
|
+
|
|
71
|
+
// execute
|
|
72
|
+
const output = input.map((item) => isoLocalazyToStrapi(item));
|
|
73
|
+
|
|
74
|
+
// verify
|
|
75
|
+
const expected = ["en-US", "fr-CA", "de-DE", "es-ES", "it-IT", "ja-JP", "ko-KR", "pt-BR", "ru-RU", "zh-CN"];
|
|
76
|
+
expect(output).toEqual(expected);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it("should transform codes containing lang-script", () => {
|
|
80
|
+
// setup
|
|
81
|
+
const input = ["en#Latn", "fr#Latn", "de#Latn", "es#Latn", "it#Latn", "ja#Latn", "ko#Latn", "pt#Latn", "ru#Latn", "zh#Latn"];
|
|
82
|
+
|
|
83
|
+
// execute
|
|
84
|
+
const output = input.map((item) => isoLocalazyToStrapi(item));
|
|
85
|
+
|
|
86
|
+
// verify
|
|
87
|
+
const expected = ["en-Latn", "fr-Latn", "de-Latn", "es-Latn", "it-Latn", "ja-Latn", "ko-Latn", "pt-Latn", "ru-Latn", "zh-Latn"];
|
|
88
|
+
expect(output).toEqual(expected);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it("should transform codes containing lang-script-region", () => {
|
|
92
|
+
// setup
|
|
93
|
+
const input = ["en_US#Latn", "fr_CA#Latn", "de_DE#Latn", "es_ES#Latn", "it_IT#Latn", "ja_JP#Latn", "ko_KR#Latn", "pt_BR#Latn", "ru_RU#Latn", "zh_CN#Hant"];
|
|
94
|
+
|
|
95
|
+
// execute
|
|
96
|
+
const output = input.map((item) => isoLocalazyToStrapi(item));
|
|
97
|
+
// verify
|
|
98
|
+
const expected = ["en-Latn-US", "fr-Latn-CA", "de-Latn-DE", "es-Latn-ES", "it-Latn-IT", "ja-Latn-JP", "ko-Latn-KR", "pt-Latn-BR", "ru-Latn-RU", "zh-Hant-CN"];
|
|
99
|
+
expect(output).toEqual(expected);
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default (value, options = undefined) => new Intl.NumberFormat("en-GB", options).format(value);
|
|
@@ -3,7 +3,31 @@ export const isoStrapiToLocalazy = (isoStrapi) => {
|
|
|
3
3
|
return null;
|
|
4
4
|
}
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
const split = isoStrapi.split("-");
|
|
7
|
+
const language = split[0];
|
|
8
|
+
|
|
9
|
+
const hasRegionAndScript = split.length === 3;
|
|
10
|
+
|
|
11
|
+
if (hasRegionAndScript) {
|
|
12
|
+
const script = split[1];
|
|
13
|
+
const region = split[2];
|
|
14
|
+
|
|
15
|
+
return `${language}_${region}#${script}`;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const hasPossiblyRegion = split.length === 2;
|
|
19
|
+
|
|
20
|
+
if (hasPossiblyRegion) {
|
|
21
|
+
const regionOrScript = split[1];
|
|
22
|
+
|
|
23
|
+
// is it script - the way Strapi resolves that
|
|
24
|
+
const isItRegion = regionOrScript.toUpperCase() === regionOrScript;
|
|
25
|
+
|
|
26
|
+
// it is region; otherwise it is script
|
|
27
|
+
return isItRegion ? `${language}_${regionOrScript}` : `${language}#${regionOrScript}`;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return isoStrapi.replace("-", "_");
|
|
7
31
|
};
|
|
8
32
|
|
|
9
33
|
export const isoLocalazyToStrapi = (isoLocalazy) => {
|
|
@@ -11,5 +35,24 @@ export const isoLocalazyToStrapi = (isoLocalazy) => {
|
|
|
11
35
|
return null;
|
|
12
36
|
}
|
|
13
37
|
|
|
14
|
-
|
|
38
|
+
const scriptIndex = isoLocalazy.indexOf("#");
|
|
39
|
+
const hasScript = scriptIndex > -1;
|
|
40
|
+
|
|
41
|
+
if (hasScript) {
|
|
42
|
+
const script = isoLocalazy.substring(scriptIndex + 1);
|
|
43
|
+
const isoLocalazyWithoutScript = isoLocalazy.substring(0, scriptIndex);
|
|
44
|
+
const split = isoLocalazyWithoutScript.split("_");
|
|
45
|
+
const language = split[0];
|
|
46
|
+
const region = split[1];
|
|
47
|
+
|
|
48
|
+
if (!region) {
|
|
49
|
+
return `${language}-${script}`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const isoStrapi = `${language}-${script}-${region.toUpperCase()}`;
|
|
53
|
+
|
|
54
|
+
return isoStrapi;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return isoLocalazy.replace("_", "-");
|
|
15
58
|
};
|
|
@@ -21,6 +21,7 @@ import hasModelChanged from "../../functions/has-model-changed";
|
|
|
21
21
|
import buildContentTransferSetupSchema from "../../functions/build-content-transfer-setup-schema";
|
|
22
22
|
import { getLocalazyIdentity } from "../../../../state/localazy-identity";
|
|
23
23
|
import Tree from "../Tree";
|
|
24
|
+
import ContentTransferSetupEmpty from "../ContentTransferSetupEmpty";
|
|
24
25
|
|
|
25
26
|
import "../../../../i18n";
|
|
26
27
|
|
|
@@ -28,7 +29,6 @@ function ContentTransferSetup() {
|
|
|
28
29
|
/**
|
|
29
30
|
* Translation function
|
|
30
31
|
*/
|
|
31
|
-
// eslint-disable-next-line no-unused-vars
|
|
32
32
|
const { t } = useTranslation();
|
|
33
33
|
|
|
34
34
|
/**
|
|
@@ -250,6 +250,10 @@ function ContentTransferSetup() {
|
|
|
250
250
|
shadow="tableShadow"
|
|
251
251
|
hasRadius
|
|
252
252
|
>
|
|
253
|
+
{!formModel.length && (
|
|
254
|
+
// empty state
|
|
255
|
+
<ContentTransferSetupEmpty />
|
|
256
|
+
)}
|
|
253
257
|
{formModel.map((tree, index) => {
|
|
254
258
|
return (
|
|
255
259
|
<Box
|
|
@@ -257,30 +261,37 @@ function ContentTransferSetup() {
|
|
|
257
261
|
key={`box_tree_${index}`}
|
|
258
262
|
marginBottom={3}
|
|
259
263
|
>
|
|
260
|
-
<Tree
|
|
264
|
+
<Tree
|
|
265
|
+
onTreeItemClick={onTreeItemClick}
|
|
266
|
+
objects={tree}
|
|
267
|
+
initiallyExpanded={index === 0} />
|
|
261
268
|
</Box>
|
|
262
269
|
);
|
|
263
270
|
})}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
271
|
+
{!!formModel.length && (
|
|
272
|
+
<Box>
|
|
273
|
+
<Box
|
|
274
|
+
paddingTop={6}
|
|
275
|
+
paddingBottom={6}
|
|
276
|
+
>
|
|
277
|
+
<Divider />
|
|
278
|
+
</Box>
|
|
279
|
+
<Typography variant="omega">{t("plugin_settings.you_can_upload_download")}</Typography>
|
|
280
|
+
<Typography variant="omega" fontWeight="semiBold">{t("plugin_settings.only_text_based_content")}</Typography>
|
|
281
|
+
<br />
|
|
282
|
+
<br />
|
|
283
|
+
<Typography variant="omega">{t("plugin_settings.learn_more_in_docs_message_a")}</Typography>
|
|
284
|
+
<Typography
|
|
285
|
+
onClick={onReadDocumentationClick}
|
|
286
|
+
variant="omega"
|
|
287
|
+
fontWeight="semiBold"
|
|
288
|
+
textColor="primary600"
|
|
289
|
+
style={{ cursor: "pointer" }}
|
|
290
|
+
>
|
|
291
|
+
{t("plugin_settings.learn_more_in_docs_message_b")}
|
|
292
|
+
</Typography>
|
|
293
|
+
</Box>
|
|
294
|
+
)}
|
|
284
295
|
</Box>
|
|
285
296
|
)
|
|
286
297
|
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { useTranslation, Trans } from "react-i18next";
|
|
3
|
+
import styled from 'styled-components';
|
|
4
|
+
import { Typography, Flex } from "@strapi/design-system";
|
|
5
|
+
import Dot from '@strapi/icons/Dot';
|
|
6
|
+
|
|
7
|
+
const CustomBullet = styled(Dot)`
|
|
8
|
+
width: ${12 / 16}rem;
|
|
9
|
+
height: ${4 / 16}rem;
|
|
10
|
+
margin-right: ${4 / 16}rem;
|
|
11
|
+
* {
|
|
12
|
+
fill: ${({ theme, $active }) => ($active ? theme.colors.primary600 : theme.colors.neutral600)};
|
|
13
|
+
}
|
|
14
|
+
`;
|
|
15
|
+
|
|
16
|
+
function ContentTransferSetupEmpty() {
|
|
17
|
+
const { t } = useTranslation();
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<div>
|
|
21
|
+
<Typography
|
|
22
|
+
textColor="neutral600"
|
|
23
|
+
variant="beta"
|
|
24
|
+
>
|
|
25
|
+
{t("plugin_settings.there_is_nothing_to_transfer")}
|
|
26
|
+
</Typography>
|
|
27
|
+
<br />
|
|
28
|
+
<br />
|
|
29
|
+
<Typography
|
|
30
|
+
textColor="neutral600"
|
|
31
|
+
variant="omega"
|
|
32
|
+
>
|
|
33
|
+
{t("plugin_settings.please_check_that_you_have_entered_a_valid_collection")}
|
|
34
|
+
</Typography>
|
|
35
|
+
<br />
|
|
36
|
+
<Flex marginTop={1} alignItems="center">
|
|
37
|
+
<CustomBullet />
|
|
38
|
+
<Typography
|
|
39
|
+
textColor="neutral600"
|
|
40
|
+
variant="omega"
|
|
41
|
+
>
|
|
42
|
+
<Trans i18nKey="plugin_settings.step_1" components={{ 1: <Typography variant="omega" fontWeight="semiBold" /> }} />
|
|
43
|
+
</Typography>
|
|
44
|
+
</Flex>
|
|
45
|
+
<Flex marginTop={1} alignItems="center">
|
|
46
|
+
<CustomBullet />
|
|
47
|
+
|
|
48
|
+
<Typography
|
|
49
|
+
textColor="neutral600"
|
|
50
|
+
variant="omega"
|
|
51
|
+
>
|
|
52
|
+
<Trans i18nKey="plugin_settings.step_2" components={{ 1: <Typography variant="omega" fontWeight="semiBold" /> }} />
|
|
53
|
+
</Typography>
|
|
54
|
+
</Flex>
|
|
55
|
+
<Flex marginTop={1} alignItems="center">
|
|
56
|
+
<CustomBullet />
|
|
57
|
+
<Typography
|
|
58
|
+
textColor="neutral600"
|
|
59
|
+
variant="omega"
|
|
60
|
+
>
|
|
61
|
+
<Trans i18nKey="plugin_settings.step_3" components={{ 1: <Typography variant="omega" fontWeight="semiBold" /> }} />
|
|
62
|
+
</Typography>
|
|
63
|
+
</Flex>
|
|
64
|
+
<Flex marginTop={1} alignItems="center">
|
|
65
|
+
<CustomBullet />
|
|
66
|
+
<Typography
|
|
67
|
+
textColor="neutral600"
|
|
68
|
+
variant="omega"
|
|
69
|
+
>
|
|
70
|
+
<Trans i18nKey="plugin_settings.step_4" components={{ 1: <Typography variant="omega" fontWeight="semiBold" /> }} />
|
|
71
|
+
</Typography>
|
|
72
|
+
</Flex>
|
|
73
|
+
<Flex marginTop={1} alignItems="center">
|
|
74
|
+
<CustomBullet />
|
|
75
|
+
<Typography
|
|
76
|
+
textColor="neutral600"
|
|
77
|
+
variant="omega"
|
|
78
|
+
>
|
|
79
|
+
<Trans i18nKey="plugin_settings.step_5" components={{ 1: <Typography variant="omega" fontWeight="semiBold" /> }} />
|
|
80
|
+
</Typography>
|
|
81
|
+
</Flex>
|
|
82
|
+
</div >
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export default ContentTransferSetupEmpty;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState } from "react";
|
|
1
|
+
import React, { useState, useEffect } from "react";
|
|
2
2
|
import PropTypes from "prop-types";
|
|
3
3
|
import { Box } from "@strapi/design-system/Box";
|
|
4
4
|
import { Switch } from '@strapi/design-system/Switch';
|
|
@@ -13,6 +13,10 @@ function Tree(props) {
|
|
|
13
13
|
props.onTreeItemClick(key, currentValue);
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
setIsExpanded(props.initiallyExpanded);
|
|
18
|
+
}, [props.initiallyExpanded]);
|
|
19
|
+
|
|
16
20
|
const createTree = (name, branch, path = "") => {
|
|
17
21
|
const isBranchObject = typeof branch === "object" && branch !== null;
|
|
18
22
|
|
|
@@ -115,6 +119,11 @@ function Tree(props) {
|
|
|
115
119
|
Tree.propTypes = {
|
|
116
120
|
objects: PropTypes.object.isRequired,
|
|
117
121
|
onTreeItemClick: PropTypes.func.isRequired,
|
|
122
|
+
initiallyExpanded: PropTypes.bool,
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
Tree.defaultProps = {
|
|
126
|
+
initiallyExpanded: false,
|
|
118
127
|
};
|
|
119
128
|
|
|
120
129
|
export default Tree;
|
|
@@ -16,4 +16,11 @@ export default {
|
|
|
16
16
|
only_text_based_content: "only text based content.",
|
|
17
17
|
learn_more_in_docs_message_a: "If you want to learn more about how to setup your Content Transfer settings read the ",
|
|
18
18
|
learn_more_in_docs_message_b: "Localazy documentation.",
|
|
19
|
+
there_is_nothing_to_transfer: "There is nothing to transfer.",
|
|
20
|
+
please_check_that_you_have_entered_a_valid_collection: "To finish the content transfer setup, you must enable localization for at least one Content-Type.",
|
|
21
|
+
step_1: "Go to the <1>Content-Type Builder</1>",
|
|
22
|
+
step_2: "Click on <1>Edit</1> and select the <1>Advanced Settings</1> tab",
|
|
23
|
+
step_3: "Check <1>Enable localization for this Content-Type</1>",
|
|
24
|
+
step_4: "Repeat for all Content-Types you want to translate",
|
|
25
|
+
step_5: "Return to this screen and finish the transfer setup",
|
|
19
26
|
};
|
|
@@ -29,4 +29,27 @@ export default class PluginSettingsService {
|
|
|
29
29
|
throw e;
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
|
+
|
|
33
|
+
static async getPluginSettings() {
|
|
34
|
+
try {
|
|
35
|
+
const result = await axiosInstance.get(`${BASE_PATH}/plugin-settings`);
|
|
36
|
+
|
|
37
|
+
return result.data;
|
|
38
|
+
} catch (e) {
|
|
39
|
+
throw e;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
static async updatePluginSettings(data) {
|
|
44
|
+
try {
|
|
45
|
+
const result = await axiosInstance.put(
|
|
46
|
+
`${BASE_PATH}/plugin-settings`,
|
|
47
|
+
data
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
return result.data;
|
|
51
|
+
} catch (e) {
|
|
52
|
+
throw e;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
32
55
|
}
|
|
@@ -12,8 +12,8 @@ import { ThemeProvider } from "@strapi/design-system/ThemeProvider";
|
|
|
12
12
|
import { lightTheme } from "@strapi/design-system/themes";
|
|
13
13
|
import { Box } from "@strapi/design-system/Box";
|
|
14
14
|
import { Layout } from "@strapi/design-system/Layout";
|
|
15
|
-
import { Loader } from "@strapi/design-system/Loader";
|
|
16
15
|
import { useTranslation } from "react-i18next";
|
|
16
|
+
import Loader from "../../modules/@common/components/PluginPageLoader";
|
|
17
17
|
import pluginId from "../../pluginId";
|
|
18
18
|
import Download from "../Download";
|
|
19
19
|
import Settings from "../Settings";
|
|
@@ -32,6 +32,7 @@ import {
|
|
|
32
32
|
getLocalazyIdentity,
|
|
33
33
|
} from "../../state/localazy-identity";
|
|
34
34
|
import history from "../../modules/@common/utils/history";
|
|
35
|
+
import PluginSettingsService from "../../modules/plugin-settings/services/plugin-settings-service";
|
|
35
36
|
|
|
36
37
|
import "../../i18n";
|
|
37
38
|
|
|
@@ -89,7 +90,8 @@ function App() {
|
|
|
89
90
|
if (!hasLocalazyIdentity()) {
|
|
90
91
|
redirectToPluginRoute(PLUGIN_ROUTES.LOGIN);
|
|
91
92
|
} else {
|
|
92
|
-
|
|
93
|
+
const lastRoute = (await PluginSettingsService.getPluginSettings()).defaultRoute || PLUGIN_ROUTES.UPLOAD;
|
|
94
|
+
redirectToPluginRoute(lastRoute);
|
|
93
95
|
}
|
|
94
96
|
}
|
|
95
97
|
}
|
|
@@ -5,11 +5,11 @@ import { Button } from "@strapi/design-system/Button";
|
|
|
5
5
|
import DownloadIcon from "@strapi/icons/Download";
|
|
6
6
|
import { Box } from "@strapi/design-system/Box";
|
|
7
7
|
import { Alert } from "@strapi/design-system/Alert";
|
|
8
|
-
import { Loader } from "@strapi/design-system/Loader";
|
|
9
8
|
import { useTranslation } from "react-i18next";
|
|
10
9
|
import { Flex } from '@strapi/design-system/Flex';
|
|
11
10
|
import { Divider } from '@strapi/design-system/Divider';
|
|
12
11
|
import { Typography } from "@strapi/design-system/Typography";
|
|
12
|
+
import Loader from "../../modules/@common/components/PluginPageLoader";
|
|
13
13
|
import LocalazyDownloadService from "../../modules/localazy-download/services/localazy-download-service";
|
|
14
14
|
import areLocalesCompatible from "../../modules/@common/utils/are-locales-compatible";
|
|
15
15
|
import hasModelChanged from "../../modules/plugin-settings/functions/has-model-changed";
|
|
@@ -17,6 +17,9 @@ import TransferReport from "../../modules/@common/components/TransferReport";
|
|
|
17
17
|
import ReadDocsButton from "../../modules/localazy-upload/components/ReadDocsButton";
|
|
18
18
|
import "../../i18n";
|
|
19
19
|
import { getLocalazyIdentity } from "../../state/localazy-identity";
|
|
20
|
+
import ProductAnalyticsService from "../../modules/@common/services/product-analytics-service";
|
|
21
|
+
import PluginSettingsService from "../../modules/plugin-settings/services/plugin-settings-service";
|
|
22
|
+
import { PLUGIN_ROUTES } from "../../modules/@common/utils/redirect-to-plugin-route";
|
|
20
23
|
|
|
21
24
|
function Download(props) {
|
|
22
25
|
const { t } = useTranslation();
|
|
@@ -44,6 +47,16 @@ function Download(props) {
|
|
|
44
47
|
setIsDownloading(true);
|
|
45
48
|
const result = await LocalazyDownloadService.download();
|
|
46
49
|
setDownloadResult(result);
|
|
50
|
+
|
|
51
|
+
// track download
|
|
52
|
+
ProductAnalyticsService.trackDownloadToStrapi(
|
|
53
|
+
localazyIdentity.user.id,
|
|
54
|
+
localazyIdentity.project,
|
|
55
|
+
{
|
|
56
|
+
"Target Languages Codes": "all",
|
|
57
|
+
}
|
|
58
|
+
);
|
|
59
|
+
|
|
47
60
|
setIsDownloading(false);
|
|
48
61
|
setshowDownloadFinishedModal(true);
|
|
49
62
|
};
|
|
@@ -58,6 +71,8 @@ function Download(props) {
|
|
|
58
71
|
setModelChanged(await hasModelChanged());
|
|
59
72
|
setLocalesIncompatible(!(await areLocalesCompatible()));
|
|
60
73
|
|
|
74
|
+
PluginSettingsService.updatePluginSettings({ defaultRoute: PLUGIN_ROUTES.DOWNLOAD });
|
|
75
|
+
|
|
61
76
|
setIsLoading(false);
|
|
62
77
|
}
|
|
63
78
|
initComponent();
|
|
@@ -6,19 +6,20 @@
|
|
|
6
6
|
|
|
7
7
|
import React from "react";
|
|
8
8
|
import PropTypes from "prop-types";
|
|
9
|
-
import { Loader } from "@strapi/design-system/Loader";
|
|
10
9
|
import { Link } from "@strapi/design-system/Link";
|
|
11
10
|
import { useHistory } from "react-router-dom";
|
|
12
11
|
import { useTranslation } from "react-i18next";
|
|
13
12
|
import { HeaderLayout } from "@strapi/design-system/Layout";
|
|
14
13
|
import { Box } from "@strapi/design-system/Box";
|
|
15
14
|
import { Typography } from "@strapi/design-system/Typography";
|
|
15
|
+
import Loader from "../../modules/@common/components/PluginPageLoader";
|
|
16
16
|
import { setLocalazyIdentity } from "../../state/localazy-identity";
|
|
17
17
|
import LocalazyUserService from "../../modules/user/services/localazy-user-service";
|
|
18
18
|
import LoginButton from "../../modules/login/components/LoginButton";
|
|
19
19
|
import redirectToPluginRoute, {
|
|
20
20
|
PLUGIN_ROUTES,
|
|
21
21
|
} from "../../modules/@common/utils/redirect-to-plugin-route";
|
|
22
|
+
import ProductAnalyticsService from "../../modules/@common/services/product-analytics-service";
|
|
22
23
|
|
|
23
24
|
import "../../i18n";
|
|
24
25
|
|
|
@@ -40,6 +41,12 @@ function Login(props) {
|
|
|
40
41
|
setLocalazyIdentity(result);
|
|
41
42
|
|
|
42
43
|
if (result.accessToken) {
|
|
44
|
+
// track user login
|
|
45
|
+
ProductAnalyticsService.trackAppConnected(
|
|
46
|
+
result.user.id,
|
|
47
|
+
result.project,
|
|
48
|
+
);
|
|
49
|
+
|
|
43
50
|
redirectToPluginRoute(PLUGIN_ROUTES.DOWNLOAD, history);
|
|
44
51
|
}
|
|
45
52
|
};
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import React, { useEffect, useState } from "react";
|
|
2
2
|
import PropTypes from "prop-types";
|
|
3
|
-
import { Loader } from "@strapi/design-system/Loader";
|
|
4
3
|
import { HeaderLayout } from "@strapi/design-system/Layout";
|
|
5
4
|
import { Box } from "@strapi/design-system/Box";
|
|
6
5
|
import { useHistory } from "react-router-dom";
|
|
7
6
|
import { useTranslation } from "react-i18next";
|
|
8
7
|
import { Grid } from '@strapi/design-system/Grid';
|
|
9
8
|
import { Divider } from '@strapi/design-system/Divider';
|
|
9
|
+
import Loader from "../../modules/@common/components/PluginPageLoader";
|
|
10
10
|
import LogoutButton from "../../modules/login/components/LogoutButton";
|
|
11
11
|
import redirectToPluginRoute, {
|
|
12
12
|
PLUGIN_ROUTES,
|
|
@@ -16,6 +16,9 @@ import OverviewItem from "../../modules/settings/components/OverviewItem";
|
|
|
16
16
|
import OverviewItemLink from "../../modules/settings/components/OverviewItemLink";
|
|
17
17
|
import PrerequisitiesInfo from "../../modules/settings/components/PrerequisitiesInfo";
|
|
18
18
|
import ProjectService from "../../modules/@common/services/project-service";
|
|
19
|
+
import ProductAnalyticsService from "../../modules/@common/services/product-analytics-service";
|
|
20
|
+
import formatNumber from "../../modules/@common/utils/format-number";
|
|
21
|
+
import PluginSettingsService from "../../modules/plugin-settings/services/plugin-settings-service";
|
|
19
22
|
|
|
20
23
|
import "../../i18n";
|
|
21
24
|
|
|
@@ -35,6 +38,9 @@ function Settings(props) {
|
|
|
35
38
|
setIsLoading(true);
|
|
36
39
|
const project = await ProjectService.getConnectedProject();
|
|
37
40
|
setConnectedProject(project);
|
|
41
|
+
|
|
42
|
+
PluginSettingsService.updatePluginSettings({ defaultRoute: PLUGIN_ROUTES.SETTINGS });
|
|
43
|
+
|
|
38
44
|
setIsLoading(false);
|
|
39
45
|
}
|
|
40
46
|
|
|
@@ -45,6 +51,12 @@ function Settings(props) {
|
|
|
45
51
|
* On logout action
|
|
46
52
|
*/
|
|
47
53
|
const onLoggedOut = () => {
|
|
54
|
+
// track user logout
|
|
55
|
+
ProductAnalyticsService.trackAppDisconnected(
|
|
56
|
+
localazyIdentity.user.id,
|
|
57
|
+
localazyIdentity.project,
|
|
58
|
+
);
|
|
59
|
+
|
|
48
60
|
redirectToPluginRoute(PLUGIN_ROUTES.LOGIN, history);
|
|
49
61
|
};
|
|
50
62
|
|
|
@@ -56,7 +68,9 @@ function Settings(props) {
|
|
|
56
68
|
primaryAction={<LogoutButton onResultFetched={onLoggedOut} />}
|
|
57
69
|
as="h2"
|
|
58
70
|
/>
|
|
59
|
-
{(props.isLoading || isLoading) && (
|
|
71
|
+
{(props.isLoading || isLoading) && (
|
|
72
|
+
<Loader>{t("common.loading_content")}</Loader>
|
|
73
|
+
)}
|
|
60
74
|
{!(props.isLoading || isLoading) && (
|
|
61
75
|
<Box paddingRight={10} paddingLeft={10}>
|
|
62
76
|
<Box
|
|
@@ -86,7 +100,7 @@ function Settings(props) {
|
|
|
86
100
|
<OverviewItem
|
|
87
101
|
label={t("settings.remaining_organization_keys")}
|
|
88
102
|
value={
|
|
89
|
-
connectedProject.organization.availableKeys - connectedProject.organization.usedKeys
|
|
103
|
+
formatNumber(connectedProject.organization.availableKeys - connectedProject.organization.usedKeys)
|
|
90
104
|
}
|
|
91
105
|
/>
|
|
92
106
|
<OverviewItemLink
|
|
@@ -9,7 +9,7 @@ import { Button } from "@strapi/design-system/Button";
|
|
|
9
9
|
import UploadIcon from "@strapi/icons/Upload";
|
|
10
10
|
import { Box } from "@strapi/design-system/Box";
|
|
11
11
|
import { Alert } from "@strapi/design-system/Alert";
|
|
12
|
-
import
|
|
12
|
+
import Loader from "../../modules/@common/components/PluginPageLoader";
|
|
13
13
|
import LocalazyUploadService from "../../modules/localazy-upload/services/localazy-upload-service";
|
|
14
14
|
import areLocalesCompatible from "../../modules/@common/utils/are-locales-compatible";
|
|
15
15
|
import { getStrapiDefaultLocale, getLocalazySourceLanguage } from "../../modules/@common/utils/get-default-locale";
|
|
@@ -21,6 +21,9 @@ import ReadDocsButton from "../../modules/localazy-upload/components/ReadDocsBut
|
|
|
21
21
|
import redirectToPluginRoute, {
|
|
22
22
|
PLUGIN_ROUTES,
|
|
23
23
|
} from "../../modules/@common/utils/redirect-to-plugin-route";
|
|
24
|
+
import { getLocalazyIdentity } from "../../state/localazy-identity";
|
|
25
|
+
import ProductAnalyticsService from "../../modules/@common/services/product-analytics-service";
|
|
26
|
+
import PluginSettingsService from "../../modules/plugin-settings/services/plugin-settings-service";
|
|
24
27
|
|
|
25
28
|
import "../../i18n";
|
|
26
29
|
|
|
@@ -38,6 +41,7 @@ function Upload(props) {
|
|
|
38
41
|
const [isUploading, setIsUploading] = useState(false);
|
|
39
42
|
const [strapiDefaultLocale, setStrapiDefaultLocale] = useState(null);
|
|
40
43
|
const [localazySourceLanguage, setLocalazySourceLanguage] = useState(null);
|
|
44
|
+
const [localazyIdentity] = getLocalazyIdentity();
|
|
41
45
|
|
|
42
46
|
const onChangeSettingsClick = () => {
|
|
43
47
|
redirectToPluginRoute(PLUGIN_ROUTES.CONTENT_TRANSFER_SETUP);
|
|
@@ -49,6 +53,16 @@ function Upload(props) {
|
|
|
49
53
|
setIsUploading(true);
|
|
50
54
|
const result = await LocalazyUploadService.upload();
|
|
51
55
|
setUploadResult(result);
|
|
56
|
+
|
|
57
|
+
// track upload
|
|
58
|
+
ProductAnalyticsService.trackUploadToLocalazy(
|
|
59
|
+
localazyIdentity.user.id,
|
|
60
|
+
localazyIdentity.project,
|
|
61
|
+
{
|
|
62
|
+
"Source Language Code": localazySourceLanguage.code,
|
|
63
|
+
}
|
|
64
|
+
);
|
|
65
|
+
|
|
52
66
|
setIsUploading(false);
|
|
53
67
|
setShowUploadFinishedModal(true);
|
|
54
68
|
};
|
|
@@ -66,6 +80,8 @@ function Upload(props) {
|
|
|
66
80
|
setModelChanged(await hasModelChanged());
|
|
67
81
|
setLocalesIncompatible(!(await areLocalesCompatible(strapiDefaultLocale, localazySourceLanguage)));
|
|
68
82
|
|
|
83
|
+
PluginSettingsService.updatePluginSettings({ defaultRoute: PLUGIN_ROUTES.UPLOAD });
|
|
84
|
+
|
|
69
85
|
setIsLoading(false);
|
|
70
86
|
}
|
|
71
87
|
initComponent();
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import createPluginConnectorAxiosInstance from "../utils/createPluginConnectorAxiosInstance";
|
|
2
|
+
|
|
3
|
+
const ANALYTICS_PATH = "/analytics";
|
|
4
|
+
const axiosInstance = createPluginConnectorAxiosInstance();
|
|
5
|
+
export default class AnalyticsService {
|
|
6
|
+
static async trackEvent(event, data) {
|
|
7
|
+
const result = await axiosInstance.post(`${ANALYTICS_PATH}/track`, {
|
|
8
|
+
event,
|
|
9
|
+
...data,
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
return result.data;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* axios with plugin connector config.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import axios from "axios";
|
|
6
|
+
import { config } from "../../../server";
|
|
7
|
+
|
|
8
|
+
const BASE_PLUGIN_PATH = config.default.LOCALAZY_PLUGIN_CONNECTOR_API_URL;
|
|
9
|
+
|
|
10
|
+
const createPluginConnectorAxiosInstance = (baseUrl = null) => {
|
|
11
|
+
if (baseUrl === null) {
|
|
12
|
+
baseUrl = `${BASE_PLUGIN_PATH}`;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const instance = axios.create({
|
|
16
|
+
baseURL: baseUrl,
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
instance.interceptors.request.use(
|
|
20
|
+
async (config) => {
|
|
21
|
+
config.headers = {
|
|
22
|
+
Accept: "application/json",
|
|
23
|
+
"Content-Type": "application/json",
|
|
24
|
+
// Strapi plugin id in terms of plugin connector
|
|
25
|
+
"X-Localazy-Plugin-Id": 1,
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
return config;
|
|
29
|
+
},
|
|
30
|
+
(error) => {
|
|
31
|
+
Promise.reject(error);
|
|
32
|
+
}
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
instance.interceptors.response.use(
|
|
36
|
+
(response) => response,
|
|
37
|
+
(error) => {
|
|
38
|
+
throw error;
|
|
39
|
+
}
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
return instance;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export default createPluginConnectorAxiosInstance;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@localazy/strapi-plugin",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"description": "The official Strapi Plugin by Localazy.",
|
|
5
5
|
"strapi": {
|
|
6
6
|
"name": "localazy",
|
|
@@ -28,8 +28,6 @@
|
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@localazy/ts-api": "^1.0.6",
|
|
31
|
-
"@strapi/design-system": "^1.0.0",
|
|
32
|
-
"@strapi/icons": "^1.0.0",
|
|
33
31
|
"deep-keys": "^0.5.0",
|
|
34
32
|
"i18next": "^21.6.13",
|
|
35
33
|
"isomorphic-fetch": "^3.0.0",
|
|
@@ -41,7 +39,9 @@
|
|
|
41
39
|
"styled-components": "^5.3.3"
|
|
42
40
|
},
|
|
43
41
|
"peerDependencies": {
|
|
44
|
-
"@strapi/strapi": "^4.0.0"
|
|
42
|
+
"@strapi/strapi": "^4.0.0",
|
|
43
|
+
"@strapi/design-system": "^1.0.0",
|
|
44
|
+
"@strapi/icons": "^1.0.0"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@babel/plugin-transform-modules-commonjs": "^7.17.7",
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
module.exports = {
|
|
4
4
|
LOCALAZY_OAUTH_URL: "https://testing.localazy.com/oauth/authorize",
|
|
5
|
-
LOCALAZY_OAUTH_APP_CLIENT_ID: "
|
|
6
|
-
LOCALAZY_PLUGIN_CONNECTOR_API_URL: "
|
|
5
|
+
LOCALAZY_OAUTH_APP_CLIENT_ID: "18503917571895066466",
|
|
6
|
+
LOCALAZY_PLUGIN_CONNECTOR_API_URL: "https://testing.localazy.com/plugin-connector",
|
|
7
7
|
LOCALAZY_PUBLIC_API_URL: "https://testing.localazy.com/pubapi",
|
|
8
8
|
LOCALAZY_PLUGIN_ID: "1",
|
|
9
9
|
LOCALAZY_DEFAULT_FILE_NAME: "strapi.json",
|
package/server/config/index.js
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
// depending on the STRAPI_ADMIN_LOCALAZY_ENV, use the correct config
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
let config = require("./production/index");
|
|
5
|
+
|
|
6
|
+
if (process.env.STRAPI_ADMIN_LOCALAZY_ENV === "local") {
|
|
7
|
+
config = require("./local/index");
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if (process.env.STRAPI_ADMIN_LOCALAZY_ENV === "development") {
|
|
11
|
+
config = require("./development/index");
|
|
12
|
+
}
|
|
8
13
|
|
|
9
14
|
module.exports = {
|
|
10
15
|
default: {
|
|
11
16
|
// Default plugin configuration, merged with the user configuration
|
|
12
17
|
...(config || {}),
|
|
13
18
|
},
|
|
14
|
-
validator() {},
|
|
19
|
+
validator() { },
|
|
15
20
|
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
LOCALAZY_OAUTH_URL: "https://testing.localazy.com/oauth/authorize",
|
|
5
|
+
LOCALAZY_OAUTH_APP_CLIENT_ID: "18503917571895066465",
|
|
6
|
+
LOCALAZY_PLUGIN_CONNECTOR_API_URL: "http://localhost:3000",
|
|
7
|
+
LOCALAZY_PUBLIC_API_URL: "https://testing.localazy.com/pubapi",
|
|
8
|
+
LOCALAZY_PLUGIN_ID: "1",
|
|
9
|
+
LOCALAZY_DEFAULT_FILE_NAME: "strapi.json",
|
|
10
|
+
LOCALAZY_DEFAULT_FILE_PATH: "",
|
|
11
|
+
LOCALAZY_DEFAULT_FILE_EXTENSION: "json",
|
|
12
|
+
LOCALAZY_DEFAULT_LOCALE: "en",
|
|
13
|
+
LOCALAZY_API_USER_JWT_COOKIE_NAME: "LOCALAZY-API-USER-JWT",
|
|
14
|
+
LOCALAZY_API_USER_COOKIE_EXPIRATION: 7,
|
|
15
|
+
};
|
|
@@ -25,7 +25,9 @@ module.exports = {
|
|
|
25
25
|
const messageReport = [];
|
|
26
26
|
|
|
27
27
|
// Strapi Service
|
|
28
|
-
const StrapiService = strapi
|
|
28
|
+
const StrapiService = strapi
|
|
29
|
+
.plugin("localazy")
|
|
30
|
+
.service("strapiService");
|
|
29
31
|
|
|
30
32
|
// Strapi i18n Service
|
|
31
33
|
const StrapiI18nService = strapi
|
|
@@ -14,4 +14,18 @@ module.exports = {
|
|
|
14
14
|
.service("pluginSettingsService")
|
|
15
15
|
.updateContentTransferSetup(ctx.request.body);
|
|
16
16
|
},
|
|
17
|
+
|
|
18
|
+
async getPluginSettings(ctx) {
|
|
19
|
+
ctx.body = await strapi
|
|
20
|
+
.plugin("localazy")
|
|
21
|
+
.service("pluginSettingsService")
|
|
22
|
+
.getPluginSettings();
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
async updatePluginSettings(ctx) {
|
|
26
|
+
ctx.body = await strapi
|
|
27
|
+
.plugin("localazy")
|
|
28
|
+
.service("pluginSettingsService")
|
|
29
|
+
.updatePluginSettings(ctx.request.body);
|
|
30
|
+
}
|
|
17
31
|
};
|
|
@@ -19,4 +19,20 @@ module.exports = [
|
|
|
19
19
|
policies: [],
|
|
20
20
|
},
|
|
21
21
|
},
|
|
22
|
+
{
|
|
23
|
+
method: "GET",
|
|
24
|
+
path: `${ROUTE_PREFIX}/plugin-settings`,
|
|
25
|
+
handler: "pluginSettingsController.getPluginSettings",
|
|
26
|
+
config: {
|
|
27
|
+
policies: [],
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
method: "PUT",
|
|
32
|
+
path: `${ROUTE_PREFIX}/plugin-settings`,
|
|
33
|
+
handler: "pluginSettingsController.updatePluginSettings",
|
|
34
|
+
config: {
|
|
35
|
+
policies: [],
|
|
36
|
+
},
|
|
37
|
+
}
|
|
22
38
|
];
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
const contentTransferSetupModel = require("../db/model/content-transfer-setup");
|
|
4
|
+
|
|
5
|
+
const pluginSettingsModel = require("../db/model/plugin-settings");
|
|
6
|
+
// {
|
|
7
|
+
// KEY,
|
|
8
|
+
// emptyPluginSettings,
|
|
9
|
+
// } = require("../db/model/plugin-settings");
|
|
7
10
|
const getStrapiStore = require("../db/model/utils/get-strapi-store");
|
|
8
11
|
|
|
9
12
|
module.exports = ({ strapi }) => ({
|
|
10
13
|
async getContentTransferSetup() {
|
|
11
14
|
const pluginStore = getStrapiStore(strapi);
|
|
12
|
-
const setup = await pluginStore.get({ key: KEY });
|
|
15
|
+
const setup = await pluginStore.get({ key: contentTransferSetupModel.KEY });
|
|
13
16
|
|
|
14
|
-
return setup || emptyContentTransferSetup;
|
|
17
|
+
return setup || contentTransferSetupModel.emptyContentTransferSetup;
|
|
15
18
|
},
|
|
16
19
|
|
|
17
20
|
async updateContentTransferSetup(setup) {
|
|
@@ -21,10 +24,28 @@ module.exports = ({ strapi }) => ({
|
|
|
21
24
|
};
|
|
22
25
|
const pluginStore = getStrapiStore(strapi);
|
|
23
26
|
await pluginStore.set({
|
|
24
|
-
key: KEY,
|
|
27
|
+
key: contentTransferSetupModel.KEY,
|
|
25
28
|
value: newSetup,
|
|
26
29
|
});
|
|
27
30
|
|
|
28
31
|
return newSetup;
|
|
29
32
|
},
|
|
33
|
+
|
|
34
|
+
async getPluginSettings() {
|
|
35
|
+
const pluginStore = getStrapiStore(strapi);
|
|
36
|
+
const settings = await pluginStore.get({ key: pluginSettingsModel.KEY });
|
|
37
|
+
|
|
38
|
+
return settings || pluginSettingsModel.emptyPluginSettings;
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
async updatePluginSettings(settings) {
|
|
42
|
+
const newSettings = settings;
|
|
43
|
+
const pluginStore = getStrapiStore(strapi);
|
|
44
|
+
await pluginStore.set({
|
|
45
|
+
key: pluginSettingsModel.KEY,
|
|
46
|
+
value: newSettings,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
return newSettings;
|
|
50
|
+
},
|
|
30
51
|
});
|
|
@@ -13,17 +13,18 @@ module.exports = ({ strapi }) => ({
|
|
|
13
13
|
async createStrapiLocale(ctx, isoLocalazy) {
|
|
14
14
|
try {
|
|
15
15
|
const isoStrapi = isoLocalazyToStrapi(isoLocalazy);
|
|
16
|
-
|
|
16
|
+
let localeName = intlDisplayName(isoStrapi);
|
|
17
17
|
|
|
18
18
|
if (!localeName || !isoStrapi) {
|
|
19
19
|
throw new Error("Invalid locale");
|
|
20
20
|
}
|
|
21
|
+
localeName = `${localeName} (${isoStrapi})`;
|
|
21
22
|
|
|
22
23
|
const newLocaleCtx = { ...ctx };
|
|
23
24
|
newLocaleCtx.request.body = {
|
|
24
25
|
isDefault: false,
|
|
25
26
|
code: isoStrapi,
|
|
26
|
-
name: localeName,
|
|
27
|
+
name: localeName.substring(0, 50), // limit name to 50 characters (given by Strapi)
|
|
27
28
|
};
|
|
28
29
|
|
|
29
30
|
await strapi
|
|
@@ -39,7 +40,6 @@ module.exports = ({ strapi }) => ({
|
|
|
39
40
|
parseLocalazyKey(key) {
|
|
40
41
|
const split = key.split(/\.|\[|\]/);
|
|
41
42
|
const filteredSplit = split.filter((item) => item !== "");
|
|
42
|
-
// return split;
|
|
43
43
|
|
|
44
44
|
return {
|
|
45
45
|
uid: `${filteredSplit[0]}.${filteredSplit[1]}`,
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const { isoStrapiToLocalazy, isoLocalazyToStrapi } = require("../iso-locales-utils.js");
|
|
4
|
+
|
|
5
|
+
describe("iso-locales-utils.js", () => {
|
|
6
|
+
describe("transform Strapi ISO to Localazy ISO", () => {
|
|
7
|
+
it("should transform codes containing lang only", () => {
|
|
8
|
+
// setup
|
|
9
|
+
const input = ["en", "fr", "de", "es", "it", "ja", "ko", "pt", "ru", "zh"];
|
|
10
|
+
|
|
11
|
+
// execute
|
|
12
|
+
const output = input.map((item) => isoStrapiToLocalazy(item));
|
|
13
|
+
|
|
14
|
+
// verify
|
|
15
|
+
const expected = input;
|
|
16
|
+
expect(output).toEqual(expected);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it("should transform codes containing lang-region", () => {
|
|
20
|
+
// setup
|
|
21
|
+
const input = ["en-US", "fr-CA", "de-DE", "es-ES", "it-IT", "ja-JP", "ko-KR", "pt-BR", "ru-RU", "zh-CN"];
|
|
22
|
+
|
|
23
|
+
// execute
|
|
24
|
+
const output = input.map((item) => isoStrapiToLocalazy(item));
|
|
25
|
+
|
|
26
|
+
// verify
|
|
27
|
+
const expected = ["en_US", "fr_CA", "de_DE", "es_ES", "it_IT", "ja_JP", "ko_KR", "pt_BR", "ru_RU", "zh_CN"];
|
|
28
|
+
expect(output).toEqual(expected);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("should transform codes containing lang-script", () => {
|
|
32
|
+
// setup
|
|
33
|
+
const input = ["en-Latn", "fr-Latn", "de-Latn", "es-Latn", "it-Latn", "ja-Latn", "ko-Latn", "pt-Latn", "ru-Latn", "zh-Latn"];
|
|
34
|
+
|
|
35
|
+
// execute
|
|
36
|
+
const output = input.map((item) => isoStrapiToLocalazy(item));
|
|
37
|
+
|
|
38
|
+
// verify
|
|
39
|
+
const expected = ["en#Latn", "fr#Latn", "de#Latn", "es#Latn", "it#Latn", "ja#Latn", "ko#Latn", "pt#Latn", "ru#Latn", "zh#Latn"];
|
|
40
|
+
expect(output).toEqual(expected);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it("should transform codes containing lang-script-region", () => {
|
|
44
|
+
// setup
|
|
45
|
+
const input = ["en-Latn-US", "fr-Latn-CA", "de-Latn-DE", "es-Latn-ES", "it-Latn-IT", "ja-Latn-JP", "ko-Latn-KR", "pt-Latn-BR", "ru-Latn-RU", "zh-Hant-CN"];
|
|
46
|
+
|
|
47
|
+
// execute
|
|
48
|
+
const output = input.map((item) => isoStrapiToLocalazy(item));
|
|
49
|
+
|
|
50
|
+
// verify
|
|
51
|
+
const expected = ["en_US#Latn", "fr_CA#Latn", "de_DE#Latn", "es_ES#Latn", "it_IT#Latn", "ja_JP#Latn", "ko_KR#Latn", "pt_BR#Latn", "ru_RU#Latn", "zh_CN#Hant"];
|
|
52
|
+
expect(output).toEqual(expected);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
describe("transform Strapi ISO to Localazy ISO", () => {
|
|
57
|
+
it("should transform codes containing lang only", () => {
|
|
58
|
+
// setup
|
|
59
|
+
const input = ["en", "fr", "de", "es", "it", "ja", "ko", "pt", "ru", "zh"];
|
|
60
|
+
|
|
61
|
+
// execute
|
|
62
|
+
const output = input.map((item) => isoLocalazyToStrapi(item));
|
|
63
|
+
|
|
64
|
+
// verify
|
|
65
|
+
const expected = input;
|
|
66
|
+
expect(output).toEqual(expected);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it("should transform codes containing lang-region", () => {
|
|
70
|
+
// setup
|
|
71
|
+
const input = ["en_US", "fr_CA", "de_DE", "es_ES", "it_IT", "ja_JP", "ko_KR", "pt_BR", "ru_RU", "zh_CN"];
|
|
72
|
+
|
|
73
|
+
// execute
|
|
74
|
+
const output = input.map((item) => isoLocalazyToStrapi(item));
|
|
75
|
+
|
|
76
|
+
// verify
|
|
77
|
+
const expected = ["en-US", "fr-CA", "de-DE", "es-ES", "it-IT", "ja-JP", "ko-KR", "pt-BR", "ru-RU", "zh-CN"];
|
|
78
|
+
expect(output).toEqual(expected);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it("should transform codes containing lang-script", () => {
|
|
82
|
+
// setup
|
|
83
|
+
const input = ["en#Latn", "fr#Latn", "de#Latn", "es#Latn", "it#Latn", "ja#Latn", "ko#Latn", "pt#Latn", "ru#Latn", "zh#Latn"];
|
|
84
|
+
|
|
85
|
+
// execute
|
|
86
|
+
const output = input.map((item) => isoLocalazyToStrapi(item));
|
|
87
|
+
|
|
88
|
+
// verify
|
|
89
|
+
const expected = ["en-Latn", "fr-Latn", "de-Latn", "es-Latn", "it-Latn", "ja-Latn", "ko-Latn", "pt-Latn", "ru-Latn", "zh-Latn"];
|
|
90
|
+
expect(output).toEqual(expected);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it("should transform codes containing lang-script-region", () => {
|
|
94
|
+
// setup
|
|
95
|
+
const input = ["en_US#Latn", "fr_CA#Latn", "de_DE#Latn", "es_ES#Latn", "it_IT#Latn", "ja_JP#Latn", "ko_KR#Latn", "pt_BR#Latn", "ru_RU#Latn", "zh_CN#Hant"];
|
|
96
|
+
|
|
97
|
+
// execute
|
|
98
|
+
const output = input.map((item) => isoLocalazyToStrapi(item));
|
|
99
|
+
// verify
|
|
100
|
+
const expected = ["en-Latn-US", "fr-Latn-CA", "de-Latn-DE", "es-Latn-ES", "it-Latn-IT", "ja-Latn-JP", "ko-Latn-KR", "pt-Latn-BR", "ru-Latn-RU", "zh-Hant-CN"];
|
|
101
|
+
expect(output).toEqual(expected);
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
});
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
module.exports = (isoCode) => {
|
|
4
|
-
const isoDashed = isoStrapiToLocalazy(isoCode);
|
|
1
|
+
module.exports = (isoStrapi) => {
|
|
5
2
|
let languageNames = new Intl.DisplayNames(["en"], { type: "language" });
|
|
6
|
-
return languageNames.of(
|
|
3
|
+
return languageNames.of(isoStrapi);
|
|
7
4
|
};
|
|
@@ -5,7 +5,28 @@ const isoStrapiToLocalazy = (isoStrapi) => {
|
|
|
5
5
|
return null;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
const split = isoStrapi.split("-");
|
|
9
|
+
const language = split[0];
|
|
10
|
+
|
|
11
|
+
const hasRegionAndScript = split.length === 3;
|
|
12
|
+
if (hasRegionAndScript) {
|
|
13
|
+
const script = split[1];
|
|
14
|
+
const region = split[2];
|
|
15
|
+
return `${language}_${region}#${script}`;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const hasPossiblyRegion = split.length === 2;
|
|
19
|
+
if (hasPossiblyRegion) {
|
|
20
|
+
const regionOrScript = split[1];
|
|
21
|
+
|
|
22
|
+
// is it script - the way Strapi resolves that
|
|
23
|
+
const isItRegion = regionOrScript.toUpperCase() === regionOrScript;
|
|
24
|
+
|
|
25
|
+
// it is region; otherwise it is script
|
|
26
|
+
return isItRegion ? `${language}_${regionOrScript}` : `${language}#${regionOrScript}`;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return isoStrapi.replace("-", "_");
|
|
9
30
|
};
|
|
10
31
|
|
|
11
32
|
const isoLocalazyToStrapi = (isoLocalazy) => {
|
|
@@ -13,7 +34,24 @@ const isoLocalazyToStrapi = (isoLocalazy) => {
|
|
|
13
34
|
return null;
|
|
14
35
|
}
|
|
15
36
|
|
|
16
|
-
|
|
37
|
+
const scriptIndex = isoLocalazy.indexOf("#");
|
|
38
|
+
const hasScript = scriptIndex > -1;
|
|
39
|
+
if (hasScript) {
|
|
40
|
+
const script = isoLocalazy.substring(scriptIndex + 1);
|
|
41
|
+
const isoLocalazyWithoutScript = isoLocalazy.substring(0, scriptIndex);
|
|
42
|
+
const split = isoLocalazyWithoutScript.split("_");
|
|
43
|
+
const language = split[0];
|
|
44
|
+
const region = split[1];
|
|
45
|
+
|
|
46
|
+
if (!region) {
|
|
47
|
+
return `${language}-${script}`;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const isoStrapi = `${language}-${script}-${region.toUpperCase()}`;
|
|
51
|
+
return isoStrapi;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return isoLocalazy.replace("_", "-");
|
|
17
55
|
};
|
|
18
56
|
|
|
19
57
|
module.exports = {
|