@localazy/strapi-plugin 0.1.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.
Files changed (150) hide show
  1. package/.babelrc +7 -0
  2. package/.eslintrc +7 -0
  3. package/.github/workflows/.build.yml +39 -0
  4. package/.nvmrc +1 -0
  5. package/LICENSE +21 -0
  6. package/README.md +40 -0
  7. package/admin/src/.eslintrc +3 -0
  8. package/admin/src/components/Initializer/index.js +26 -0
  9. package/admin/src/components/PluginIcon/index.js +14 -0
  10. package/admin/src/i18n.js +37 -0
  11. package/admin/src/index.js +106 -0
  12. package/admin/src/modules/@common/components/Icons/Localazy/index.js +12 -0
  13. package/admin/src/modules/@common/components/SideNav/index.js +46 -0
  14. package/admin/src/modules/@common/components/TransferReport/index.js +54 -0
  15. package/admin/src/modules/@common/locale/en.js +13 -0
  16. package/admin/src/modules/@common/services/i18n-service.js +15 -0
  17. package/admin/src/modules/@common/services/project-service.js +15 -0
  18. package/admin/src/modules/@common/services/user-service.js +38 -0
  19. package/admin/src/modules/@common/utils/are-locales-compatible.js +42 -0
  20. package/admin/src/modules/@common/utils/functions/flatten-deep.js +23 -0
  21. package/admin/src/modules/@common/utils/get-default-locale.js +32 -0
  22. package/admin/src/modules/@common/utils/get-header-subtitle.js +21 -0
  23. package/admin/src/modules/@common/utils/get-header-title.js +24 -0
  24. package/admin/src/modules/@common/utils/get-nav.js +35 -0
  25. package/admin/src/modules/@common/utils/history.js +6 -0
  26. package/admin/src/modules/@common/utils/is-plugin-route.js +15 -0
  27. package/admin/src/modules/@common/utils/iso-locales-utils.js +15 -0
  28. package/admin/src/modules/@common/utils/redirect-to-plugin-route.js +22 -0
  29. package/admin/src/modules/@common/utils/sort-by-model-name.js +10 -0
  30. package/admin/src/modules/localazy-download/locale/en.js +20 -0
  31. package/admin/src/modules/localazy-download/services/localazy-download-service.js +16 -0
  32. package/admin/src/modules/localazy-upload/components/ReadDocsButton.js +21 -0
  33. package/admin/src/modules/localazy-upload/locale/en.js +18 -0
  34. package/admin/src/modules/localazy-upload/services/localazy-upload-service.js +16 -0
  35. package/admin/src/modules/login/components/LoginButton/index.js +56 -0
  36. package/admin/src/modules/login/components/LogoutButton/index.js +50 -0
  37. package/admin/src/modules/login/locale/en.js +7 -0
  38. package/admin/src/modules/login/services/localazy-login-service.js +29 -0
  39. package/admin/src/modules/plugin-settings/components/ContentTransferSetup/index.js +292 -0
  40. package/admin/src/modules/plugin-settings/components/Tree/index.js +120 -0
  41. package/admin/src/modules/plugin-settings/components/TreeItem/index.js +48 -0
  42. package/admin/src/modules/plugin-settings/functions/build-content-transfer-setup-schema.js +71 -0
  43. package/admin/src/modules/plugin-settings/functions/has-model-changed.js +85 -0
  44. package/admin/src/modules/plugin-settings/locale/en.js +19 -0
  45. package/admin/src/modules/plugin-settings/services/plugin-settings-service.js +32 -0
  46. package/admin/src/modules/plugin-settings/services/strapi-model-service.js +26 -0
  47. package/admin/src/modules/plugin-settings/utils/__tests__/get-models-tree.test.js +135 -0
  48. package/admin/src/modules/plugin-settings/utils/array-of-models-to-object.js +6 -0
  49. package/admin/src/modules/plugin-settings/utils/find-model-value-by-key.js +8 -0
  50. package/admin/src/modules/plugin-settings/utils/get-filtered-models-schemas.js +34 -0
  51. package/admin/src/modules/plugin-settings/utils/get-models-tree.js +73 -0
  52. package/admin/src/modules/settings/components/OverviewItem/index.js +44 -0
  53. package/admin/src/modules/settings/components/OverviewItemLink/index.js +34 -0
  54. package/admin/src/modules/settings/components/PrerequisitiesInfo/index.js +30 -0
  55. package/admin/src/modules/settings/locale/en.js +13 -0
  56. package/admin/src/modules/user/model/localazy-identity.js +14 -0
  57. package/admin/src/modules/user/services/localazy-user-service.js +38 -0
  58. package/admin/src/pages/App/index.js +152 -0
  59. package/admin/src/pages/Download/index.js +179 -0
  60. package/admin/src/pages/Index/index.js +8 -0
  61. package/admin/src/pages/Login/index.js +94 -0
  62. package/admin/src/pages/PluginSettings/index.js +42 -0
  63. package/admin/src/pages/Settings/index.js +120 -0
  64. package/admin/src/pages/Upload/index.js +187 -0
  65. package/admin/src/pluginId.js +5 -0
  66. package/admin/src/plugins/apolloClient.js +33 -0
  67. package/admin/src/state/localazy-identity.js +29 -0
  68. package/admin/src/tests/fixtures/all-models.js +877 -0
  69. package/admin/src/tests/fixtures/restaurant-model.js +230 -0
  70. package/admin/src/translations/en.json +4 -0
  71. package/admin/src/translations/fr.json +1 -0
  72. package/admin/src/utils/createAxiosInstance.js +52 -0
  73. package/admin/src/utils/getTrad.js +5 -0
  74. package/jest.config.js +0 -0
  75. package/package.json +60 -0
  76. package/server/bootstrap.js +5 -0
  77. package/server/config/development/index.js +15 -0
  78. package/server/config/example/index.js +15 -0
  79. package/server/config/index.js +15 -0
  80. package/server/config/production/index.js +16 -0
  81. package/server/config/schema.graphql.js +21 -0
  82. package/server/content-types/index.js +3 -0
  83. package/server/controllers/index.js +19 -0
  84. package/server/controllers/localazy-auth-controller.js +46 -0
  85. package/server/controllers/localazy-project-controller.js +21 -0
  86. package/server/controllers/localazy-transfer-controller.js +469 -0
  87. package/server/controllers/localazy-user-controller.js +24 -0
  88. package/server/controllers/my-controller.js +10 -0
  89. package/server/controllers/plugin-settings-controller.js +17 -0
  90. package/server/controllers/strapi-controller.js +16 -0
  91. package/server/db/model/content-transfer-setup.js +13 -0
  92. package/server/db/model/localazy-user.js +23 -0
  93. package/server/db/model/utils/get-strapi-store.js +9 -0
  94. package/server/destroy.js +5 -0
  95. package/server/index.js +25 -0
  96. package/server/middlewares/index.js +3 -0
  97. package/server/policies/index.js +3 -0
  98. package/server/register.js +5 -0
  99. package/server/routes/index.js +26 -0
  100. package/server/routes/localazy-auth.js +22 -0
  101. package/server/routes/localazy-project.js +14 -0
  102. package/server/routes/localazy-transfer.js +22 -0
  103. package/server/routes/localazy-user.js +30 -0
  104. package/server/routes/plugin-settings.js +22 -0
  105. package/server/routes/strapi.js +22 -0
  106. package/server/services/index.js +21 -0
  107. package/server/services/localazy-auth-service.js +38 -0
  108. package/server/services/localazy-download-service.js +54 -0
  109. package/server/services/localazy-pubapi-service.js +47 -0
  110. package/server/services/localazy-upload-service.js +95 -0
  111. package/server/services/localazy-user-service.js +29 -0
  112. package/server/services/plugin-settings-service.js +30 -0
  113. package/server/services/strapi-i18n-service.js +132 -0
  114. package/server/services/strapi-service.js +23 -0
  115. package/server/tests/fixtures/all-models-with-multimedia.js +1064 -0
  116. package/server/tests/fixtures/all-models.js +869 -0
  117. package/server/tests/fixtures/collection-flattened.js +76 -0
  118. package/server/tests/fixtures/restaurant-flattened.js +46 -0
  119. package/server/tests/fixtures/restaurant-model.js +230 -0
  120. package/server/tests/fixtures/restaurants-entries.js +152 -0
  121. package/server/tests/fixtures/restaurants-pick-paths.js +15 -0
  122. package/server/tests/fixtures/strapi-book-with-multimedia-components-cs.js +31 -0
  123. package/server/tests/fixtures/stringified-book-cs.js +3 -0
  124. package/server/tests/fixtures/stringified-book-with-multimedia-components-cs.js +3 -0
  125. package/server/tests/fixtures/stringified-restaurant-cs.js +3 -0
  126. package/server/tests/fixtures/stringified-restaurant-de.js +5 -0
  127. package/server/utils/__tests__/build-populate.test.js +85 -0
  128. package/server/utils/__tests__/flatten-object.test.js +171 -0
  129. package/server/utils/__tests__/get-models-tree.test.js +170 -0
  130. package/server/utils/__tests__/parsed-localazy-entry-to-create-entry.test.js +153 -0
  131. package/server/utils/__tests__/parsed-localazy-entry-to-update-entry.test.js +172 -0
  132. package/server/utils/__tests__/pick-entries.test.js +83 -0
  133. package/server/utils/build-populate.js +43 -0
  134. package/server/utils/delay.js +6 -0
  135. package/server/utils/flatten-object.js +52 -0
  136. package/server/utils/get-localazy-api.js +22 -0
  137. package/server/utils/get-main-keys-of-nested-array-objects.js +5 -0
  138. package/server/utils/get-models-tree.js +43 -0
  139. package/server/utils/intl-display-name.js +7 -0
  140. package/server/utils/is-generally-applicable-content-type.js +33 -0
  141. package/server/utils/is-localazy-applicable-content-type.js +36 -0
  142. package/server/utils/iso-locales-utils.js +22 -0
  143. package/server/utils/objectivise-entry.js +41 -0
  144. package/server/utils/omit-deep.js +17 -0
  145. package/server/utils/parsed-localazy-entry-to-create-entry.js +115 -0
  146. package/server/utils/parsed-localazy-entry-to-update-entry.js +31 -0
  147. package/server/utils/pick-entries.js +14 -0
  148. package/server/utils/transfer-setup-utils.js +39 -0
  149. package/strapi-admin.js +14 -0
  150. package/strapi-server.js +5 -0
package/.babelrc ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "env": {
3
+ "test": {
4
+ "plugins": ["@babel/plugin-transform-modules-commonjs"]
5
+ }
6
+ }
7
+ }
package/.eslintrc ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ // "extends": "@strapi-community",
3
+ "env": {
4
+ "jest/globals": true
5
+ },
6
+ "plugins": ["jest"]
7
+ }
@@ -0,0 +1,39 @@
1
+ name: CI
2
+ on: [push, pull_request]
3
+ jobs:
4
+ execute:
5
+ runs-on: [self-hosted, Linux, aws]
6
+ env:
7
+ INPUT_TOKEN: ""
8
+ steps:
9
+ - name: Set work folder permissions
10
+ run: pwd && sudo chown -R $USER:$USER ./
11
+ - uses: actions/checkout@v2
12
+ - name: Setup Node.js environment
13
+ uses: actions/setup-node@v1.4.4
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 }}-
27
+ - name: Install dependencies
28
+ run: npm ci
29
+ - name: Run linter
30
+ run: npm run lint
31
+ - name: Run unit tests
32
+ run: npm run test
33
+ - name: Build project
34
+ run: npm run build
35
+ - name: Publish to npm
36
+ uses: JS-DevTools/npm-publish@v1
37
+ if: github.ref == 'refs/heads/master'
38
+ with:
39
+ token: ${{ secrets.NPM_AUTH_TOKEN }}
package/.nvmrc ADDED
@@ -0,0 +1 @@
1
+ 14
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 Localazy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # The Official Strapi Plugin by Localazy
2
+
3
+ ### The Official Strapi Plugin by Localazy
4
+
5
+ Manage your multilingual content with ease. Upload your content in default language to Localazy. Let us translate your content for you, use machine translation or let your translators do it for you. Download translated content back to Strapi and feel the seamless experience of multilingual content.
6
+
7
+ ### General information
8
+
9
+ This repository contains all the code needed to run the Official Strapi Plugin by Localazy.
10
+
11
+ ### Use plugin in a clean project locally
12
+
13
+ Besides installing the plugin via `npm`, you can also use it in a project locally. Assuming you have a (clean) Strapi project set up, do:
14
+
15
+ 1. Copy the whole contents.
16
+ 2. Paste it into `./src/plugin/localazy` folder of your project (path from project root).
17
+ 3. Create `./config/plugins.js` file (path from project root).
18
+ 4. Add the following contents to `./config/plugins.js` file:
19
+
20
+ ```
21
+ module.exports = {
22
+ localazy: {
23
+ enabled: true,
24
+ resolve: "./src/plugins/localazy",
25
+ config: {
26
+ default: () => ({}),the user configuration is valid
27
+ validator: () => {},
28
+ },
29
+ },
30
+ };
31
+
32
+ ```
33
+
34
+ 5. Run the project. Plugin will be available in the admin.
35
+
36
+ ### Tests
37
+
38
+ To run tests, run `npm run test` command. To watch tests, run `npm run test:watch` command.
39
+
40
+ In case you have an access, you might also want to check the README file located in development project root for more information on tests debugging.
@@ -0,0 +1,3 @@
1
+ {
2
+ "extends": "@strapi-community/admin"
3
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ *
3
+ * Initializer
4
+ *
5
+ */
6
+
7
+ import { useEffect, useRef } from "react";
8
+ import PropTypes from "prop-types";
9
+ import pluginId from "../../pluginId";
10
+
11
+ function Initializer({ setPlugin }) {
12
+ const ref = useRef();
13
+ ref.current = setPlugin;
14
+
15
+ useEffect(() => {
16
+ ref.current(pluginId);
17
+ }, []);
18
+
19
+ return null;
20
+ }
21
+
22
+ Initializer.propTypes = {
23
+ setPlugin: PropTypes.func.isRequired,
24
+ };
25
+
26
+ export default Initializer;
@@ -0,0 +1,14 @@
1
+ /**
2
+ *
3
+ * PluginIcon
4
+ *
5
+ */
6
+
7
+ import React from "react";
8
+ import Localazy from "../../modules/@common/components/Icons/Localazy";
9
+
10
+ function PluginIcon() {
11
+ return <Localazy />;
12
+ }
13
+
14
+ export default PluginIcon;
@@ -0,0 +1,37 @@
1
+ import i18n from "i18next";
2
+ import { initReactI18next } from "react-i18next";
3
+
4
+ import en_common from "./modules/@common/locale/en";
5
+ import en_login from "./modules/login/locale/en";
6
+ import en_settings from "./modules/settings/locale/en";
7
+ import en_download from "./modules/localazy-download/locale/en";
8
+ import en_upload from "./modules/localazy-upload/locale/en";
9
+ import en_plugin_settings from "./modules/plugin-settings/locale/en";
10
+
11
+ i18n
12
+ // detect user language
13
+ // pass the i18n instance to react-i18next.
14
+ .use(initReactI18next)
15
+ // init i18next
16
+ // for all options read: https://www.i18next.com/overview/configuration-options
17
+ .init({
18
+ debug: process.env.STRAPI_ADMIN_LOCALAZY_ENV === "development",
19
+ fallbackLng: "en",
20
+ interpolation: {
21
+ escapeValue: false, // not needed for react as it escapes by default
22
+ },
23
+ resources: {
24
+ en: {
25
+ translation: {
26
+ common: en_common,
27
+ login: en_login,
28
+ settings: en_settings,
29
+ download: en_download,
30
+ upload: en_upload,
31
+ plugin_settings: en_plugin_settings,
32
+ },
33
+ },
34
+ },
35
+ });
36
+
37
+ export default i18n;
@@ -0,0 +1,106 @@
1
+ import { prefixPluginTranslations } from "@strapi/helper-plugin";
2
+ import pluginPkg from "../../package.json";
3
+ import pluginId from "./pluginId";
4
+ import Initializer from "./components/Initializer";
5
+ import PluginIcon from "./components/PluginIcon";
6
+
7
+ const name = pluginPkg.strapi.name;
8
+ const SETTINGS_SETUP = [
9
+ {
10
+ sectionId: `${pluginId}-settings`,
11
+ intlId: `localazy_settings`,
12
+ sectionDefaultLabel: "Localazy Settings",
13
+ links: [
14
+ {
15
+ linkId: `${pluginId}-settings-content-transfer-setup`,
16
+ intlId: `content_transfer_setup`,
17
+ defaultLabel: "Content Transfer Setup",
18
+ to: `/settings/${pluginId}/content-transfer-setup`,
19
+ Component: async () => {
20
+ const component = await import("./pages/PluginSettings");
21
+
22
+ return component;
23
+ },
24
+ permissions: [
25
+ // TODO: only allow access to this page if the user has the right permissions
26
+ ],
27
+ },
28
+ ],
29
+ },
30
+ ];
31
+
32
+ export default {
33
+ register(app) {
34
+ app.addMenuLink({
35
+ to: `/plugins/${pluginId}`,
36
+ icon: PluginIcon,
37
+ intlLabel: {
38
+ id: `${pluginId}.plugin.name`,
39
+ defaultMessage: name,
40
+ },
41
+ Component: async () => {
42
+ const component = await import("./pages/Index");
43
+
44
+ return component;
45
+ },
46
+ permissions: [
47
+ // Uncomment to set the permissions of the plugin here
48
+ // {
49
+ // action: '', // the action name should be plugin::plugin-name.actionType
50
+ // subject: null,
51
+ // },
52
+ ],
53
+ });
54
+ app.createSettingSection(
55
+ {
56
+ id: SETTINGS_SETUP[0].sectionId,
57
+ intlLabel: {
58
+ id: SETTINGS_SETUP[0].intlId,
59
+ defaultMessage: SETTINGS_SETUP[0].sectionDefaultLabel,
60
+ },
61
+ },
62
+ [
63
+ // links
64
+ {
65
+ id: SETTINGS_SETUP[0].links[0].linkId,
66
+ intlLabel: {
67
+ id: SETTINGS_SETUP[0].links[0].intlId,
68
+ defaultMessage: SETTINGS_SETUP[0].links[0].defaultLabel,
69
+ },
70
+ to: SETTINGS_SETUP[0].links[0].to,
71
+ Component: SETTINGS_SETUP[0].links[0].Component,
72
+ permissions: SETTINGS_SETUP[0].links[0].permissions,
73
+ },
74
+ ]
75
+ );
76
+ app.registerPlugin({
77
+ id: pluginId,
78
+ initializer: Initializer,
79
+ isReady: false,
80
+ name,
81
+ });
82
+ },
83
+
84
+ bootstrap() { },
85
+ async registerTrads({ locales }) {
86
+ const importedTrads = await Promise.all(
87
+ locales.map((locale) => {
88
+ return import(`./translations/${locale}.json`)
89
+ .then(({ default: data }) => {
90
+ return {
91
+ data: prefixPluginTranslations(data, pluginId),
92
+ locale,
93
+ };
94
+ })
95
+ .catch(() => {
96
+ return {
97
+ data: {},
98
+ locale,
99
+ };
100
+ });
101
+ })
102
+ );
103
+
104
+ return Promise.resolve(importedTrads);
105
+ },
106
+ };
@@ -0,0 +1,12 @@
1
+ import React from "react";
2
+
3
+ function Localazy() {
4
+ return (
5
+ <svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
6
+ <path d="M16.4517 2.56643L16.3247 2.87501L15.5632 4.67576H7.49071C7.18595 4.67576 6.98278 4.98434 7.1013 5.26333L9.05259 9.91314C9.12031 10.0695 9.27269 10.171 9.442 10.171H12.6211C12.9216 10.171 13.1247 10.4753 13.0147 10.7501L12.8919 11.046L12.1353 12.8468H10.9192C10.6187 12.8468 10.4113 13.1553 10.5298 13.4343L13.8229 21.2925C13.9626 21.6265 13.7171 21.9942 13.353 21.9942H11.3256C11.1224 21.9942 10.9362 21.8716 10.8557 21.6814L3.1056 3.17091C2.8728 2.61293 3.27915 2 3.88443 2H16.0538C16.3501 2 16.5533 2.29167 16.4517 2.56643Z" />
7
+ <path d="M17.2937 13.5315L21.0354 4.63345C21.2724 4.07548 20.8619 3.45832 20.2566 3.46255L17.2267 3.46255L16.4794 5.23793C16.4794 5.24638 16.4752 5.25484 16.4709 5.26329L16.4709 5.26329L16.3482 5.55074C16.2297 5.82973 16.4371 6.1383 16.7376 6.1383H16.8069C17.1074 6.1383 17.3148 6.44688 17.1963 6.72587L15.2408 11.3757C15.1773 11.5321 15.0207 11.6335 14.8514 11.6335H13.7902L12.9112 13.7217C12.7927 14.0007 13.0001 14.3093 13.3006 14.3093H16.1212C16.6334 14.3093 17.0947 14.0007 17.2937 13.5315Z" />
8
+ </svg>
9
+ );
10
+ }
11
+
12
+ export default Localazy;
@@ -0,0 +1,46 @@
1
+ /*
2
+ *
3
+ * SideNav
4
+ *
5
+ */
6
+
7
+ import React from "react";
8
+ import {
9
+ SubNav,
10
+ SubNavHeader,
11
+ SubNavSection,
12
+ SubNavSections,
13
+ SubNavLink,
14
+ } from "@strapi/design-system/SubNav";
15
+ import { useTranslation } from "react-i18next";
16
+ import { NavLink } from "react-router-dom";
17
+ import getNav from "../../utils/get-nav";
18
+
19
+ function SideNav() {
20
+ const { t } = useTranslation();
21
+
22
+ const navigation = getNav();
23
+
24
+ return (
25
+ <SubNav ariaLabel={t("common.localazy_plugin")}>
26
+ <SubNavHeader label={t("common.localazy_plugin")} />
27
+ <SubNavSections>
28
+ <SubNavSection label={t("common.navigation")}>
29
+ {navigation.map((navItem) => (
30
+ <SubNavLink
31
+ as={NavLink}
32
+ to={navItem.to}
33
+ active={navItem.active}
34
+ icon={navItem.icon || ""}
35
+ key={navItem.id}
36
+ >
37
+ {navItem.label}
38
+ </SubNavLink>
39
+ ))}
40
+ </SubNavSection>
41
+ </SubNavSections>
42
+ </SubNav>
43
+ );
44
+ }
45
+
46
+ export default SideNav;
@@ -0,0 +1,54 @@
1
+ import React, { useState, useEffect } from "react";
2
+ import PropTypes from "prop-types";
3
+ import { Alert } from "@strapi/design-system/Alert";
4
+ import { useTranslation } from "react-i18next";
5
+ import { Box } from "@strapi/design-system/Box";
6
+ import "../../../../i18n";
7
+
8
+ function TransferReport(props) {
9
+ const { t } = useTranslation();
10
+
11
+ const [reportLocal, setReportLocal] = useState(props.report);
12
+
13
+ const onCloseItem = (index) => {
14
+ const newReportLocal = reportLocal;
15
+ newReportLocal.splice(index, 1);
16
+
17
+ setReportLocal([...newReportLocal]);
18
+ };
19
+
20
+ useEffect(() => {
21
+ setReportLocal(props.report);
22
+ }, [props.report]);
23
+
24
+ if (!reportLocal) {
25
+ return null;
26
+ }
27
+
28
+ return (
29
+ reportLocal.map((item, index) => {
30
+ return (
31
+ <Box
32
+ // eslint-disable-next-line react/no-array-index-key
33
+ key={item}
34
+ marginTop={4}
35
+ marginBottom={4}
36
+ >
37
+ <Alert
38
+ key={item}
39
+ onClose={() => onCloseItem(index)}
40
+ closeLabel={t("upload.close")}
41
+ variant="default"
42
+ >
43
+ {item}
44
+ </Alert>
45
+ </Box>)
46
+ })
47
+ );
48
+ }
49
+
50
+ TransferReport.propTypes = {
51
+ report: PropTypes.array.isRequired,
52
+ };
53
+
54
+ export default TransferReport;
@@ -0,0 +1,13 @@
1
+ export default {
2
+ localazy_plugin: "Localazy",
3
+ localazy_plugin_hand: "Localazy 👋",
4
+ localazy_plugin_description: "An official Strapi plugin by Localazy.",
5
+ navigation: "Navigation",
6
+ upload_to_localazy: "Upload to Localazy",
7
+ download_to_strapi: "Download to Strapi",
8
+ settings: "Overview",
9
+ loading_content: "Loading content...",
10
+ report_will_be_available_after_an_action:
11
+ "Report will be available after performing an action...",
12
+ report: "Report",
13
+ };
@@ -0,0 +1,15 @@
1
+ /* eslint-disable no-useless-catch */
2
+ import createAxiosInstance from "../../../utils/createAxiosInstance";
3
+
4
+ const axiosInstance = createAxiosInstance("/i18n");
5
+ export default class I18nService {
6
+ static async getLocales() {
7
+ try {
8
+ const result = await axiosInstance.get(`/locales`);
9
+
10
+ return result.data;
11
+ } catch (e) {
12
+ throw e;
13
+ }
14
+ }
15
+ }
@@ -0,0 +1,15 @@
1
+ /* eslint-disable no-useless-catch */
2
+ import createAxiosInstance from "../../../utils/createAxiosInstance";
3
+
4
+ const axiosInstance = createAxiosInstance();
5
+ export default class ProjectService {
6
+ static async getConnectedProject() {
7
+ try {
8
+ const result = await axiosInstance.get(`/project`);
9
+
10
+ return result.data;
11
+ } catch (e) {
12
+ throw e;
13
+ }
14
+ }
15
+ }
@@ -0,0 +1,38 @@
1
+ /* eslint-disable no-useless-catch */
2
+ import createAxiosInstance from "../../../utils/createAxiosInstance";
3
+
4
+ const BASE_PATH = "/user";
5
+ const axiosInstance = createAxiosInstance();
6
+ export default class UserService {
7
+ static async generateKeys() {
8
+ try {
9
+ const result = await axiosInstance.get(`${BASE_PATH}/token`);
10
+
11
+ return result.data;
12
+ } catch (e) {
13
+ throw e;
14
+ }
15
+ }
16
+
17
+ static async continuousPoll(token) {
18
+ try {
19
+ const result = await axiosInstance.post(`${BASE_PATH}/token`, {
20
+ token,
21
+ });
22
+
23
+ return result.data;
24
+ } catch (e) {
25
+ throw e;
26
+ }
27
+ }
28
+
29
+ static async deleteToken() {
30
+ try {
31
+ const result = await axiosInstance.delete(`${BASE_PATH}/token`);
32
+
33
+ return result.data;
34
+ } catch (e) {
35
+ throw e;
36
+ }
37
+ }
38
+ }
@@ -0,0 +1,42 @@
1
+ import I18nService from "../services/i18n-service";
2
+ import ProjectService from "../services/project-service";
3
+ import { isoLocalazyToStrapi } from "./iso-locales-utils";
4
+
5
+ export default async (defaultLocale = null, sourceLanguage = null) => {
6
+ try {
7
+ if (!defaultLocale) {
8
+ const locales = await I18nService.getLocales();
9
+ defaultLocale = locales.find((locale) => !!locale.isDefault);
10
+ }
11
+
12
+ if (!defaultLocale) {
13
+ return false;
14
+ }
15
+
16
+ if (!sourceLanguage) {
17
+ const connectedProject = await ProjectService.getConnectedProject();
18
+
19
+ if (!connectedProject) {
20
+ return false;
21
+ }
22
+
23
+ const sourceLanguageId = connectedProject.sourceLanguage;
24
+ sourceLanguage = connectedProject.languages.find(
25
+ (language) => language.id === sourceLanguageId
26
+ );
27
+ }
28
+
29
+ if (!sourceLanguage) {
30
+ return false;
31
+ }
32
+
33
+ const defaultLocaleCode = defaultLocale.code;
34
+ const sourceLanguageStrapiCode = isoLocalazyToStrapi(sourceLanguage.code);
35
+
36
+ return defaultLocaleCode === sourceLanguageStrapiCode;
37
+ } catch (e) {
38
+ console.error(e.message);
39
+
40
+ return false;
41
+ }
42
+ };
@@ -0,0 +1,23 @@
1
+ import each from "lodash-es/each";
2
+ import isObject from "lodash-es/isObject";
3
+ import isArray from "lodash-es/isArray";
4
+
5
+ export default function flattenObject(obj, delimiter) {
6
+ const delim = delimiter || '.';
7
+ const nobj = {};
8
+
9
+ each(obj, (val, key) => {
10
+ // ensure is JSON key-value map, not array
11
+ if (isObject(val) && !isArray(val)) {
12
+ // union the returned result by concat all keys
13
+ const strip = flattenObject(val, delim);
14
+ each(strip, (v, k) => {
15
+ nobj[key + delim + k] = v;
16
+ })
17
+ } else {
18
+ nobj[key] = val;
19
+ }
20
+ });
21
+
22
+ return nobj;
23
+ }
@@ -0,0 +1,32 @@
1
+ import I18nService from "../services/i18n-service";
2
+ import ProjectService from "../services/project-service";
3
+
4
+ export async function getStrapiDefaultLocale() {
5
+ const locales = await I18nService.getLocales();
6
+ const defaultLocale = locales.find((locale) => !!locale.isDefault);
7
+
8
+ if (!defaultLocale) {
9
+ return null;
10
+ }
11
+
12
+ return defaultLocale;
13
+ }
14
+
15
+ export async function getLocalazySourceLanguage() {
16
+ const connectedProject = await ProjectService.getConnectedProject();
17
+
18
+ if (!connectedProject) {
19
+ return null;
20
+ }
21
+
22
+ const sourceLanguageId = connectedProject.sourceLanguage;
23
+ const sourceLanguage = connectedProject.languages.find(
24
+ (language) => language.id === sourceLanguageId
25
+ );
26
+
27
+ if (!sourceLanguage) {
28
+ return null;
29
+ }
30
+
31
+ return sourceLanguage;
32
+ }
@@ -0,0 +1,21 @@
1
+ import { useLocation } from "react-router-dom";
2
+ import getNav from "./get-nav";
3
+ import pluginId from "../../../pluginId";
4
+
5
+ export default (location = null) => {
6
+ if (!location) {
7
+ location = useLocation();
8
+ }
9
+ // segment after pluginId
10
+ const pluginSegment = location.pathname.split(`/${pluginId}/`)[1];
11
+
12
+ if (!pluginSegment) {
13
+ return "";
14
+ }
15
+ const navigation = getNav();
16
+ const currentNavItem = navigation.find((navItem) =>
17
+ pluginSegment.includes(navItem.id)
18
+ );
19
+
20
+ return currentNavItem?.description || "";
21
+ };
@@ -0,0 +1,24 @@
1
+ import { useLocation } from "react-router-dom";
2
+ import getNav from "./get-nav";
3
+ import pluginId from "../../../pluginId";
4
+ import i18n from "../../../i18n";
5
+
6
+ const t = i18n.t;
7
+
8
+ export default (location = null) => {
9
+ if (!location) {
10
+ location = useLocation();
11
+ }
12
+ // segment after pluginId
13
+ const pluginSegment = location.pathname.split(`/${pluginId}/`)[1];
14
+
15
+ if (!pluginSegment) {
16
+ return t("common.localazy_plugin_hand");
17
+ }
18
+ const navigation = getNav();
19
+ const currentNavItem = navigation.find((navItem) =>
20
+ pluginSegment.includes(navItem.id)
21
+ );
22
+
23
+ return currentNavItem?.label || t("common.localazy_plugin_hand");
24
+ };