@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.
- package/.babelrc +7 -0
- package/.eslintrc +7 -0
- package/.github/workflows/.build.yml +39 -0
- package/.nvmrc +1 -0
- package/LICENSE +21 -0
- package/README.md +40 -0
- package/admin/src/.eslintrc +3 -0
- package/admin/src/components/Initializer/index.js +26 -0
- package/admin/src/components/PluginIcon/index.js +14 -0
- package/admin/src/i18n.js +37 -0
- package/admin/src/index.js +106 -0
- package/admin/src/modules/@common/components/Icons/Localazy/index.js +12 -0
- package/admin/src/modules/@common/components/SideNav/index.js +46 -0
- package/admin/src/modules/@common/components/TransferReport/index.js +54 -0
- package/admin/src/modules/@common/locale/en.js +13 -0
- package/admin/src/modules/@common/services/i18n-service.js +15 -0
- package/admin/src/modules/@common/services/project-service.js +15 -0
- package/admin/src/modules/@common/services/user-service.js +38 -0
- package/admin/src/modules/@common/utils/are-locales-compatible.js +42 -0
- package/admin/src/modules/@common/utils/functions/flatten-deep.js +23 -0
- package/admin/src/modules/@common/utils/get-default-locale.js +32 -0
- package/admin/src/modules/@common/utils/get-header-subtitle.js +21 -0
- package/admin/src/modules/@common/utils/get-header-title.js +24 -0
- package/admin/src/modules/@common/utils/get-nav.js +35 -0
- package/admin/src/modules/@common/utils/history.js +6 -0
- package/admin/src/modules/@common/utils/is-plugin-route.js +15 -0
- package/admin/src/modules/@common/utils/iso-locales-utils.js +15 -0
- package/admin/src/modules/@common/utils/redirect-to-plugin-route.js +22 -0
- package/admin/src/modules/@common/utils/sort-by-model-name.js +10 -0
- package/admin/src/modules/localazy-download/locale/en.js +20 -0
- package/admin/src/modules/localazy-download/services/localazy-download-service.js +16 -0
- package/admin/src/modules/localazy-upload/components/ReadDocsButton.js +21 -0
- package/admin/src/modules/localazy-upload/locale/en.js +18 -0
- package/admin/src/modules/localazy-upload/services/localazy-upload-service.js +16 -0
- package/admin/src/modules/login/components/LoginButton/index.js +56 -0
- package/admin/src/modules/login/components/LogoutButton/index.js +50 -0
- package/admin/src/modules/login/locale/en.js +7 -0
- package/admin/src/modules/login/services/localazy-login-service.js +29 -0
- package/admin/src/modules/plugin-settings/components/ContentTransferSetup/index.js +292 -0
- package/admin/src/modules/plugin-settings/components/Tree/index.js +120 -0
- package/admin/src/modules/plugin-settings/components/TreeItem/index.js +48 -0
- package/admin/src/modules/plugin-settings/functions/build-content-transfer-setup-schema.js +71 -0
- package/admin/src/modules/plugin-settings/functions/has-model-changed.js +85 -0
- package/admin/src/modules/plugin-settings/locale/en.js +19 -0
- package/admin/src/modules/plugin-settings/services/plugin-settings-service.js +32 -0
- package/admin/src/modules/plugin-settings/services/strapi-model-service.js +26 -0
- package/admin/src/modules/plugin-settings/utils/__tests__/get-models-tree.test.js +135 -0
- package/admin/src/modules/plugin-settings/utils/array-of-models-to-object.js +6 -0
- package/admin/src/modules/plugin-settings/utils/find-model-value-by-key.js +8 -0
- package/admin/src/modules/plugin-settings/utils/get-filtered-models-schemas.js +34 -0
- package/admin/src/modules/plugin-settings/utils/get-models-tree.js +73 -0
- package/admin/src/modules/settings/components/OverviewItem/index.js +44 -0
- package/admin/src/modules/settings/components/OverviewItemLink/index.js +34 -0
- package/admin/src/modules/settings/components/PrerequisitiesInfo/index.js +30 -0
- package/admin/src/modules/settings/locale/en.js +13 -0
- package/admin/src/modules/user/model/localazy-identity.js +14 -0
- package/admin/src/modules/user/services/localazy-user-service.js +38 -0
- package/admin/src/pages/App/index.js +152 -0
- package/admin/src/pages/Download/index.js +179 -0
- package/admin/src/pages/Index/index.js +8 -0
- package/admin/src/pages/Login/index.js +94 -0
- package/admin/src/pages/PluginSettings/index.js +42 -0
- package/admin/src/pages/Settings/index.js +120 -0
- package/admin/src/pages/Upload/index.js +187 -0
- package/admin/src/pluginId.js +5 -0
- package/admin/src/plugins/apolloClient.js +33 -0
- package/admin/src/state/localazy-identity.js +29 -0
- package/admin/src/tests/fixtures/all-models.js +877 -0
- package/admin/src/tests/fixtures/restaurant-model.js +230 -0
- package/admin/src/translations/en.json +4 -0
- package/admin/src/translations/fr.json +1 -0
- package/admin/src/utils/createAxiosInstance.js +52 -0
- package/admin/src/utils/getTrad.js +5 -0
- package/jest.config.js +0 -0
- package/package.json +60 -0
- package/server/bootstrap.js +5 -0
- package/server/config/development/index.js +15 -0
- package/server/config/example/index.js +15 -0
- package/server/config/index.js +15 -0
- package/server/config/production/index.js +16 -0
- package/server/config/schema.graphql.js +21 -0
- package/server/content-types/index.js +3 -0
- package/server/controllers/index.js +19 -0
- package/server/controllers/localazy-auth-controller.js +46 -0
- package/server/controllers/localazy-project-controller.js +21 -0
- package/server/controllers/localazy-transfer-controller.js +469 -0
- package/server/controllers/localazy-user-controller.js +24 -0
- package/server/controllers/my-controller.js +10 -0
- package/server/controllers/plugin-settings-controller.js +17 -0
- package/server/controllers/strapi-controller.js +16 -0
- package/server/db/model/content-transfer-setup.js +13 -0
- package/server/db/model/localazy-user.js +23 -0
- package/server/db/model/utils/get-strapi-store.js +9 -0
- package/server/destroy.js +5 -0
- package/server/index.js +25 -0
- package/server/middlewares/index.js +3 -0
- package/server/policies/index.js +3 -0
- package/server/register.js +5 -0
- package/server/routes/index.js +26 -0
- package/server/routes/localazy-auth.js +22 -0
- package/server/routes/localazy-project.js +14 -0
- package/server/routes/localazy-transfer.js +22 -0
- package/server/routes/localazy-user.js +30 -0
- package/server/routes/plugin-settings.js +22 -0
- package/server/routes/strapi.js +22 -0
- package/server/services/index.js +21 -0
- package/server/services/localazy-auth-service.js +38 -0
- package/server/services/localazy-download-service.js +54 -0
- package/server/services/localazy-pubapi-service.js +47 -0
- package/server/services/localazy-upload-service.js +95 -0
- package/server/services/localazy-user-service.js +29 -0
- package/server/services/plugin-settings-service.js +30 -0
- package/server/services/strapi-i18n-service.js +132 -0
- package/server/services/strapi-service.js +23 -0
- package/server/tests/fixtures/all-models-with-multimedia.js +1064 -0
- package/server/tests/fixtures/all-models.js +869 -0
- package/server/tests/fixtures/collection-flattened.js +76 -0
- package/server/tests/fixtures/restaurant-flattened.js +46 -0
- package/server/tests/fixtures/restaurant-model.js +230 -0
- package/server/tests/fixtures/restaurants-entries.js +152 -0
- package/server/tests/fixtures/restaurants-pick-paths.js +15 -0
- package/server/tests/fixtures/strapi-book-with-multimedia-components-cs.js +31 -0
- package/server/tests/fixtures/stringified-book-cs.js +3 -0
- package/server/tests/fixtures/stringified-book-with-multimedia-components-cs.js +3 -0
- package/server/tests/fixtures/stringified-restaurant-cs.js +3 -0
- package/server/tests/fixtures/stringified-restaurant-de.js +5 -0
- package/server/utils/__tests__/build-populate.test.js +85 -0
- package/server/utils/__tests__/flatten-object.test.js +171 -0
- package/server/utils/__tests__/get-models-tree.test.js +170 -0
- package/server/utils/__tests__/parsed-localazy-entry-to-create-entry.test.js +153 -0
- package/server/utils/__tests__/parsed-localazy-entry-to-update-entry.test.js +172 -0
- package/server/utils/__tests__/pick-entries.test.js +83 -0
- package/server/utils/build-populate.js +43 -0
- package/server/utils/delay.js +6 -0
- package/server/utils/flatten-object.js +52 -0
- package/server/utils/get-localazy-api.js +22 -0
- package/server/utils/get-main-keys-of-nested-array-objects.js +5 -0
- package/server/utils/get-models-tree.js +43 -0
- package/server/utils/intl-display-name.js +7 -0
- package/server/utils/is-generally-applicable-content-type.js +33 -0
- package/server/utils/is-localazy-applicable-content-type.js +36 -0
- package/server/utils/iso-locales-utils.js +22 -0
- package/server/utils/objectivise-entry.js +41 -0
- package/server/utils/omit-deep.js +17 -0
- package/server/utils/parsed-localazy-entry-to-create-entry.js +115 -0
- package/server/utils/parsed-localazy-entry-to-update-entry.js +31 -0
- package/server/utils/pick-entries.js +14 -0
- package/server/utils/transfer-setup-utils.js +39 -0
- package/strapi-admin.js +14 -0
- package/strapi-server.js +5 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/*
|
|
2
|
+
*
|
|
3
|
+
* OverviewItem
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import React from "react";
|
|
8
|
+
import { GridItem } from '@strapi/design-system/Grid';
|
|
9
|
+
import { Box } from "@strapi/design-system/Box";
|
|
10
|
+
import { Typography } from "@strapi/design-system/Typography";
|
|
11
|
+
import PropTypes from "prop-types";
|
|
12
|
+
|
|
13
|
+
function OverviewItem(props) {
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<GridItem padding={1} col={6} s={12}>
|
|
17
|
+
<Box>
|
|
18
|
+
<Typography
|
|
19
|
+
variant="sigma"
|
|
20
|
+
textColor="neutral600"
|
|
21
|
+
textTransform="uppercase"
|
|
22
|
+
>
|
|
23
|
+
{props.label}
|
|
24
|
+
</Typography>
|
|
25
|
+
</Box>
|
|
26
|
+
<Box>
|
|
27
|
+
<Typography
|
|
28
|
+
variant="omega"
|
|
29
|
+
textColor="neutral800"
|
|
30
|
+
fontWeight="semiBold"
|
|
31
|
+
>
|
|
32
|
+
{props.value}
|
|
33
|
+
</Typography>
|
|
34
|
+
</Box>
|
|
35
|
+
</GridItem>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
OverviewItem.propTypes = {
|
|
40
|
+
label: PropTypes.string.isRequired,
|
|
41
|
+
value: PropTypes.string.isRequired,
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export default OverviewItem;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/*
|
|
2
|
+
*
|
|
3
|
+
* OpenProjectInLocalalazy
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import React from "react";
|
|
8
|
+
import { GridItem } from '@strapi/design-system/Grid';
|
|
9
|
+
import { Typography } from "@strapi/design-system/Typography";
|
|
10
|
+
import { Link } from "@strapi/design-system/Link";
|
|
11
|
+
import PropTypes from "prop-types";
|
|
12
|
+
|
|
13
|
+
function OverviewItemLink(props) {
|
|
14
|
+
return (
|
|
15
|
+
<GridItem padding={1} col={6} s={12}>
|
|
16
|
+
<Link href={props.to} isExternal>
|
|
17
|
+
<Typography
|
|
18
|
+
variant="sigma"
|
|
19
|
+
textColor="primary600"
|
|
20
|
+
textTransform="uppercase"
|
|
21
|
+
>
|
|
22
|
+
{props.label}
|
|
23
|
+
</Typography>
|
|
24
|
+
</Link>
|
|
25
|
+
</GridItem>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
OverviewItemLink.propTypes = {
|
|
30
|
+
label: PropTypes.string.isRequired,
|
|
31
|
+
to: PropTypes.string.isRequired,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export default OverviewItemLink;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Box } from "@strapi/design-system/Box";
|
|
3
|
+
import { useTranslation } from "react-i18next";
|
|
4
|
+
import { Typography } from "@strapi/design-system/Typography";
|
|
5
|
+
|
|
6
|
+
import "../../../../i18n";
|
|
7
|
+
|
|
8
|
+
function PrerequisitiesInfo() {
|
|
9
|
+
const { t } = useTranslation();
|
|
10
|
+
|
|
11
|
+
return (
|
|
12
|
+
<Box>
|
|
13
|
+
<Typography variant="omega" fontWeight="semiBold">
|
|
14
|
+
{t("settings.internationalization_plugin")}
|
|
15
|
+
</Typography>
|
|
16
|
+
<Typography variant="omega">
|
|
17
|
+
{t("settings.has_to_be_installed")}
|
|
18
|
+
</Typography>
|
|
19
|
+
<br />
|
|
20
|
+
<Typography variant="omega">
|
|
21
|
+
{t("settings.transfer_setup_message_a")}
|
|
22
|
+
</Typography>
|
|
23
|
+
<Typography variant="omega" fontWeight="semiBold">
|
|
24
|
+
{t("settings.transfer_setup_message_b")}
|
|
25
|
+
</Typography>
|
|
26
|
+
</Box>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export default PrerequisitiesInfo;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
description: "Overview of the connected Localazy account and project.",
|
|
3
|
+
localazy_account_details: "Localazy Account Details",
|
|
4
|
+
connected_user: "Connected User",
|
|
5
|
+
connected_project: "Connected Project",
|
|
6
|
+
connected_organization: "Connected Organization",
|
|
7
|
+
remaining_organization_keys: "Remaining Organization Keys",
|
|
8
|
+
open_project_in_localazy: "Open project in Localazy",
|
|
9
|
+
internationalization_plugin: "Internationalization Plugin ",
|
|
10
|
+
has_to_be_installed: "has to be installed.",
|
|
11
|
+
transfer_setup_message_a: "Select which parts of your project you want to upload in ",
|
|
12
|
+
transfer_setup_message_b: "Settings > Localazy Settings > Content Transfer Setup."
|
|
13
|
+
}
|
|
@@ -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
|
+
|
|
7
|
+
export default class LocalazyUserService {
|
|
8
|
+
static async getIdentity() {
|
|
9
|
+
try {
|
|
10
|
+
const result = await axiosInstance.get(`${BASE_PATH}`);
|
|
11
|
+
|
|
12
|
+
return result.data;
|
|
13
|
+
} catch (e) {
|
|
14
|
+
throw e;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
static async updateIdentity(localazyIdentity) {
|
|
19
|
+
try {
|
|
20
|
+
// store in DB plugin settings
|
|
21
|
+
const result = await axiosInstance.put(`${BASE_PATH}`, localazyIdentity);
|
|
22
|
+
|
|
23
|
+
return result.data;
|
|
24
|
+
} catch (e) {
|
|
25
|
+
throw e;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
static async deleteIdentity() {
|
|
30
|
+
try {
|
|
31
|
+
const result = await axiosInstance.delete(`${BASE_PATH}`);
|
|
32
|
+
|
|
33
|
+
return result.data;
|
|
34
|
+
} catch (e) {
|
|
35
|
+
throw e;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* This component is the skeleton around the actual pages, and should only
|
|
4
|
+
* contain code that should be seen on all pages. (e.g. navigation bar)
|
|
5
|
+
*
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import React, { useEffect, useState } from "react";
|
|
9
|
+
import { Switch, Router, Route, useLocation } from "react-router-dom";
|
|
10
|
+
import { NotFound } from "@strapi/helper-plugin";
|
|
11
|
+
import { ThemeProvider } from "@strapi/design-system/ThemeProvider";
|
|
12
|
+
import { lightTheme } from "@strapi/design-system/themes";
|
|
13
|
+
import { Box } from "@strapi/design-system/Box";
|
|
14
|
+
import { Layout } from "@strapi/design-system/Layout";
|
|
15
|
+
import { Loader } from "@strapi/design-system/Loader";
|
|
16
|
+
import { useTranslation } from "react-i18next";
|
|
17
|
+
import pluginId from "../../pluginId";
|
|
18
|
+
import Download from "../Download";
|
|
19
|
+
import Settings from "../Settings";
|
|
20
|
+
import Upload from "../Upload";
|
|
21
|
+
import Login from "../Login";
|
|
22
|
+
import SideNav from "../../modules/@common/components/SideNav";
|
|
23
|
+
import isPluginRoute from "../../modules/@common/utils/is-plugin-route";
|
|
24
|
+
import redirectToPluginRoute, {
|
|
25
|
+
PLUGIN_ROUTES,
|
|
26
|
+
} from "../../modules/@common/utils/redirect-to-plugin-route";
|
|
27
|
+
import getHeaderTitle from "../../modules/@common/utils/get-header-title";
|
|
28
|
+
import getHeaderSubtitle from "../../modules/@common/utils/get-header-subtitle";
|
|
29
|
+
import LocalazyUserService from "../../modules/user/services/localazy-user-service";
|
|
30
|
+
import {
|
|
31
|
+
setLocalazyIdentity,
|
|
32
|
+
getLocalazyIdentity,
|
|
33
|
+
} from "../../state/localazy-identity";
|
|
34
|
+
import history from "../../modules/@common/utils/history";
|
|
35
|
+
|
|
36
|
+
import "../../i18n";
|
|
37
|
+
|
|
38
|
+
function App() {
|
|
39
|
+
const location = useLocation();
|
|
40
|
+
const { t } = useTranslation();
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* is processing app loading
|
|
44
|
+
*/
|
|
45
|
+
const [isLoadingApp, setIsLoadingApp] = useState(true);
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* is user logged in
|
|
49
|
+
*/
|
|
50
|
+
const [isLoggedIn, setIsLoggedIn] = useState(false);
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* side navigation component apperance and title
|
|
54
|
+
*/
|
|
55
|
+
const [renderSideNav, setRenderSideNav] = useState(false);
|
|
56
|
+
const [headerTitle, setHeaderTitle] = useState(getHeaderTitle(location));
|
|
57
|
+
const [headerSubtitle, setHeaderSubtitle] = useState(getHeaderSubtitle(location));
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* localazy identity / access token
|
|
61
|
+
*/
|
|
62
|
+
const [localazyIdentity] = getLocalazyIdentity();
|
|
63
|
+
const hasLocalazyIdentity = () => !!localazyIdentity.accessToken;
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
const unlisten = history.listen((location) => {
|
|
69
|
+
setHeaderTitle(getHeaderTitle(location));
|
|
70
|
+
setHeaderSubtitle(getHeaderSubtitle(location));
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
return unlisten;
|
|
74
|
+
}, []);
|
|
75
|
+
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
async function fetchData() {
|
|
78
|
+
setIsLoadingApp(true);
|
|
79
|
+
|
|
80
|
+
const identity = await LocalazyUserService.getIdentity();
|
|
81
|
+
setLocalazyIdentity(identity);
|
|
82
|
+
setIsLoggedIn(hasLocalazyIdentity());
|
|
83
|
+
setRenderSideNav(hasLocalazyIdentity());
|
|
84
|
+
|
|
85
|
+
setIsLoadingApp(false);
|
|
86
|
+
|
|
87
|
+
// is root route
|
|
88
|
+
if (isPluginRoute(location)) {
|
|
89
|
+
if (!hasLocalazyIdentity()) {
|
|
90
|
+
redirectToPluginRoute(PLUGIN_ROUTES.LOGIN);
|
|
91
|
+
} else {
|
|
92
|
+
redirectToPluginRoute(PLUGIN_ROUTES.DOWNLOAD);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
fetchData();
|
|
97
|
+
|
|
98
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
99
|
+
}, [localazyIdentity.accessToken]);
|
|
100
|
+
|
|
101
|
+
return (
|
|
102
|
+
<Router history={history}>
|
|
103
|
+
<ThemeProvider theme={lightTheme}>
|
|
104
|
+
<Box background="neutral100">
|
|
105
|
+
<Layout sideNav={renderSideNav && <SideNav />}>
|
|
106
|
+
{isLoadingApp && <Loader>{t("common.loading_content")}</Loader>}
|
|
107
|
+
{!isLoadingApp && (
|
|
108
|
+
<>
|
|
109
|
+
{!isLoggedIn && (
|
|
110
|
+
<Switch>
|
|
111
|
+
<Route path={`/admin/plugins/${pluginId}/login`} exact>
|
|
112
|
+
<Login
|
|
113
|
+
title={headerTitle}
|
|
114
|
+
subtitle={headerSubtitle}
|
|
115
|
+
/>
|
|
116
|
+
</Route>
|
|
117
|
+
</Switch>
|
|
118
|
+
)}
|
|
119
|
+
|
|
120
|
+
{isLoggedIn && (
|
|
121
|
+
<Switch>
|
|
122
|
+
<Route path={`/admin/plugins/${pluginId}/download`} exact>
|
|
123
|
+
<Download
|
|
124
|
+
title={headerTitle}
|
|
125
|
+
subtitle={headerSubtitle}
|
|
126
|
+
/>
|
|
127
|
+
</Route>
|
|
128
|
+
<Route path={`/admin/plugins/${pluginId}/upload`} exact>
|
|
129
|
+
<Upload
|
|
130
|
+
title={headerTitle}
|
|
131
|
+
subtitle={headerSubtitle}
|
|
132
|
+
/>
|
|
133
|
+
</Route>
|
|
134
|
+
<Route path={`/admin/plugins/${pluginId}/settings`} exact>
|
|
135
|
+
<Settings
|
|
136
|
+
title={headerTitle}
|
|
137
|
+
subtitle={headerSubtitle}
|
|
138
|
+
/>
|
|
139
|
+
</Route>
|
|
140
|
+
<Route component={NotFound} />
|
|
141
|
+
</Switch>
|
|
142
|
+
)}
|
|
143
|
+
</>
|
|
144
|
+
)}
|
|
145
|
+
</Layout>
|
|
146
|
+
</Box>
|
|
147
|
+
</ThemeProvider>
|
|
148
|
+
</Router>
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export default App;
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import React, { useState, useEffect } from "react";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
import { HeaderLayout } from "@strapi/design-system/Layout";
|
|
4
|
+
import { Button } from "@strapi/design-system/Button";
|
|
5
|
+
import DownloadIcon from "@strapi/icons/Download";
|
|
6
|
+
import { Box } from "@strapi/design-system/Box";
|
|
7
|
+
import { Alert } from "@strapi/design-system/Alert";
|
|
8
|
+
import { Loader } from "@strapi/design-system/Loader";
|
|
9
|
+
import { useTranslation } from "react-i18next";
|
|
10
|
+
import { Flex } from '@strapi/design-system/Flex';
|
|
11
|
+
import { Divider } from '@strapi/design-system/Divider';
|
|
12
|
+
import { Typography } from "@strapi/design-system/Typography";
|
|
13
|
+
import LocalazyDownloadService from "../../modules/localazy-download/services/localazy-download-service";
|
|
14
|
+
import areLocalesCompatible from "../../modules/@common/utils/are-locales-compatible";
|
|
15
|
+
import hasModelChanged from "../../modules/plugin-settings/functions/has-model-changed";
|
|
16
|
+
import TransferReport from "../../modules/@common/components/TransferReport";
|
|
17
|
+
import ReadDocsButton from "../../modules/localazy-upload/components/ReadDocsButton";
|
|
18
|
+
import "../../i18n";
|
|
19
|
+
import { getLocalazyIdentity } from "../../state/localazy-identity";
|
|
20
|
+
|
|
21
|
+
function Download(props) {
|
|
22
|
+
const { t } = useTranslation();
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Component state
|
|
26
|
+
*/
|
|
27
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
28
|
+
const [modelChanged, setModelChanged] = useState(false);
|
|
29
|
+
const [localesIncompatible, setLocalesIncompatible] = useState(false);
|
|
30
|
+
const [showDownloadFinishedModal, setshowDownloadFinishedModal] =
|
|
31
|
+
useState(false);
|
|
32
|
+
const [downloadResult, setDownloadResult] = useState({});
|
|
33
|
+
const [isDownloading, setIsDownloading] = useState(false);
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* localazy identity / access token
|
|
37
|
+
*/
|
|
38
|
+
const [localazyIdentity] = getLocalazyIdentity();
|
|
39
|
+
const onTranslateInLocalazyClick = () => {
|
|
40
|
+
window.open(localazyIdentity.project.url, "_blank");
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const onDownloadClick = async () => {
|
|
44
|
+
setIsDownloading(true);
|
|
45
|
+
const result = await LocalazyDownloadService.download();
|
|
46
|
+
setDownloadResult(result);
|
|
47
|
+
setIsDownloading(false);
|
|
48
|
+
setshowDownloadFinishedModal(true);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
async function initComponent() {
|
|
53
|
+
setIsLoading(true);
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Handle alerts onload apperance
|
|
57
|
+
*/
|
|
58
|
+
setModelChanged(await hasModelChanged());
|
|
59
|
+
setLocalesIncompatible(!(await areLocalesCompatible()));
|
|
60
|
+
|
|
61
|
+
setIsLoading(false);
|
|
62
|
+
}
|
|
63
|
+
initComponent();
|
|
64
|
+
}, []);
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
<>
|
|
68
|
+
<HeaderLayout
|
|
69
|
+
title={props.title}
|
|
70
|
+
subtitle={props.subtitle}
|
|
71
|
+
primaryAction={
|
|
72
|
+
<Button
|
|
73
|
+
startIcon={<DownloadIcon />}
|
|
74
|
+
disabled={isLoading || modelChanged || localesIncompatible}
|
|
75
|
+
loading={isDownloading}
|
|
76
|
+
onClick={onDownloadClick}
|
|
77
|
+
>
|
|
78
|
+
{t("download.download_to_strapi")}
|
|
79
|
+
</Button>
|
|
80
|
+
}
|
|
81
|
+
as="h2"
|
|
82
|
+
/>
|
|
83
|
+
{isLoading && <Loader>{t("common.loading_content")}</Loader>}
|
|
84
|
+
{!isLoading && (
|
|
85
|
+
<Box paddingRight={10} paddingLeft={10}>
|
|
86
|
+
<Box
|
|
87
|
+
background="neutral0"
|
|
88
|
+
paddingTop={6}
|
|
89
|
+
paddingRight={7}
|
|
90
|
+
paddingBottom={6}
|
|
91
|
+
paddingLeft={7}
|
|
92
|
+
hasRadius
|
|
93
|
+
shadow="tableShadow"
|
|
94
|
+
>
|
|
95
|
+
<Typography variant="omega">
|
|
96
|
+
{t("download.download_note_a")}
|
|
97
|
+
</Typography>
|
|
98
|
+
<Typography variant="omega" fontWeight="semiBold">
|
|
99
|
+
{t("download.download_note_b")}
|
|
100
|
+
</Typography>
|
|
101
|
+
<br />
|
|
102
|
+
<br />
|
|
103
|
+
<Typography variant="omega">
|
|
104
|
+
{t("download.make_sure_note_a")}
|
|
105
|
+
</Typography>
|
|
106
|
+
<Typography variant="omega" fontWeight="semiBold">
|
|
107
|
+
{t("download.make_sure_note_b")}
|
|
108
|
+
</Typography>
|
|
109
|
+
<Typography variant="omega">
|
|
110
|
+
{t("download.make_sure_note_c")}
|
|
111
|
+
</Typography>
|
|
112
|
+
<Box
|
|
113
|
+
paddingTop={4}
|
|
114
|
+
paddingBottom={4}
|
|
115
|
+
>
|
|
116
|
+
<Divider />
|
|
117
|
+
</Box>
|
|
118
|
+
<Box marginTop={4}>
|
|
119
|
+
<Flex gap="2">
|
|
120
|
+
<Button variant="secondary" onClick={onTranslateInLocalazyClick}>
|
|
121
|
+
{t("download.translate_in_localazy")}
|
|
122
|
+
</Button>
|
|
123
|
+
<ReadDocsButton />
|
|
124
|
+
</Flex>
|
|
125
|
+
</Box>
|
|
126
|
+
</Box>
|
|
127
|
+
{showDownloadFinishedModal && (
|
|
128
|
+
<Box marginTop={4} marginBottom={4}>
|
|
129
|
+
<Alert
|
|
130
|
+
onClose={() => setshowDownloadFinishedModal(false)}
|
|
131
|
+
closeLabel={t("download.close")}
|
|
132
|
+
title={t("download.download_result")}
|
|
133
|
+
variant={downloadResult.success ? "success" : "danger"}
|
|
134
|
+
>
|
|
135
|
+
{downloadResult.success
|
|
136
|
+
? t("download.download_success")
|
|
137
|
+
: t("download.download_failed")}
|
|
138
|
+
</Alert>
|
|
139
|
+
</Box>
|
|
140
|
+
)}
|
|
141
|
+
{localesIncompatible && (
|
|
142
|
+
<Box marginTop={4} marginBottom={4}>
|
|
143
|
+
<Alert
|
|
144
|
+
onClose={() => setLocalesIncompatible(false)}
|
|
145
|
+
closeLabel={t("download.close")}
|
|
146
|
+
title={t("download.languages_incompatible")}
|
|
147
|
+
variant="danger"
|
|
148
|
+
>
|
|
149
|
+
{t("download.languages_incompatible_message")}
|
|
150
|
+
</Alert>
|
|
151
|
+
</Box>
|
|
152
|
+
)}
|
|
153
|
+
{modelChanged && (
|
|
154
|
+
<Box marginTop={4} marginBottom={4}>
|
|
155
|
+
<Alert
|
|
156
|
+
onClose={() => setModelChanged(false)}
|
|
157
|
+
closeLabel={t("download.close")}
|
|
158
|
+
title={t("download.content_types_model_changed")}
|
|
159
|
+
variant="default"
|
|
160
|
+
>
|
|
161
|
+
{t("download.please_update_your_content")}
|
|
162
|
+
</Alert>
|
|
163
|
+
</Box>
|
|
164
|
+
)}
|
|
165
|
+
{downloadResult.report && downloadResult.report.length > 0 && (
|
|
166
|
+
<TransferReport report={downloadResult.report} />
|
|
167
|
+
)}
|
|
168
|
+
</Box>
|
|
169
|
+
)}
|
|
170
|
+
</>
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
Download.propTypes = {
|
|
175
|
+
title: PropTypes.string.isRequired,
|
|
176
|
+
subtitle: PropTypes.string.isRequired,
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
export default Download;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/*
|
|
2
|
+
*
|
|
3
|
+
* Login
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import React from "react";
|
|
8
|
+
import PropTypes from "prop-types";
|
|
9
|
+
import { Loader } from "@strapi/design-system/Loader";
|
|
10
|
+
import { Link } from "@strapi/design-system/Link";
|
|
11
|
+
import { useHistory } from "react-router-dom";
|
|
12
|
+
import { useTranslation } from "react-i18next";
|
|
13
|
+
import { HeaderLayout } from "@strapi/design-system/Layout";
|
|
14
|
+
import { Box } from "@strapi/design-system/Box";
|
|
15
|
+
import { Typography } from "@strapi/design-system/Typography";
|
|
16
|
+
import { setLocalazyIdentity } from "../../state/localazy-identity";
|
|
17
|
+
import LocalazyUserService from "../../modules/user/services/localazy-user-service";
|
|
18
|
+
import LoginButton from "../../modules/login/components/LoginButton";
|
|
19
|
+
import redirectToPluginRoute, {
|
|
20
|
+
PLUGIN_ROUTES,
|
|
21
|
+
} from "../../modules/@common/utils/redirect-to-plugin-route";
|
|
22
|
+
|
|
23
|
+
import "../../i18n";
|
|
24
|
+
|
|
25
|
+
function Login(props) {
|
|
26
|
+
const history = useHistory();
|
|
27
|
+
const { t } = useTranslation();
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Localazy Strapi documentation link
|
|
31
|
+
*/
|
|
32
|
+
const localazyStrapiDocsLink = "https://localazy.com/docs/strapi";
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Handle fetched identity on login
|
|
36
|
+
* @param result fetched identity
|
|
37
|
+
*/
|
|
38
|
+
const onLoginResultFetched = async (result) => {
|
|
39
|
+
await LocalazyUserService.updateIdentity(result);
|
|
40
|
+
setLocalazyIdentity(result);
|
|
41
|
+
|
|
42
|
+
if (result.accessToken) {
|
|
43
|
+
redirectToPluginRoute(PLUGIN_ROUTES.DOWNLOAD, history);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<>
|
|
49
|
+
<HeaderLayout
|
|
50
|
+
title={props.title}
|
|
51
|
+
subtitle={props.subtitle}
|
|
52
|
+
as="h2"
|
|
53
|
+
/>
|
|
54
|
+
{props.isLoading && (<Loader>{t("common.loading_content")}</Loader>)}
|
|
55
|
+
{!props.isLoading && (
|
|
56
|
+
<Box paddingLeft={10}>
|
|
57
|
+
<Box>
|
|
58
|
+
<Typography variant="epsilon" textColor="neutral600">
|
|
59
|
+
{t("common.localazy_plugin_description")}
|
|
60
|
+
<br />
|
|
61
|
+
{t("login.login_and_start_translating_your_project")}
|
|
62
|
+
<br />
|
|
63
|
+
<br />
|
|
64
|
+
{t("login.you_have_to_own_account_for_the_plugin_to_work_properly")}
|
|
65
|
+
</Typography>
|
|
66
|
+
</Box>
|
|
67
|
+
<Box paddingTop={6}>
|
|
68
|
+
<LoginButton onResultFetched={onLoginResultFetched} />
|
|
69
|
+
</Box>
|
|
70
|
+
<Box paddingTop={6}>
|
|
71
|
+
<Link href={localazyStrapiDocsLink} isExternal>
|
|
72
|
+
<Typography variant="sigma" textColor="primary600">
|
|
73
|
+
{t("login.read_the_documentation")}
|
|
74
|
+
</Typography>
|
|
75
|
+
</Link>
|
|
76
|
+
</Box>
|
|
77
|
+
</Box>
|
|
78
|
+
)
|
|
79
|
+
}
|
|
80
|
+
</>
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
Login.propTypes = {
|
|
85
|
+
title: PropTypes.string.isRequired,
|
|
86
|
+
subtitle: PropTypes.string.isRequired,
|
|
87
|
+
isLoading: PropTypes.bool,
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
Login.defaultProps = {
|
|
91
|
+
isLoading: false,
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
export default Login;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React, { useEffect, useState } from "react";
|
|
2
|
+
import { Box } from "@strapi/design-system/Box";
|
|
3
|
+
import { Switch, Route } from "react-router-dom";
|
|
4
|
+
import { ThemeProvider } from "@strapi/design-system/ThemeProvider";
|
|
5
|
+
import { lightTheme } from "@strapi/design-system/themes";
|
|
6
|
+
import pluginId from "../../pluginId";
|
|
7
|
+
import ContentTransferSetup from "../../modules/plugin-settings/components/ContentTransferSetup";
|
|
8
|
+
import LocalazyUserService from "../../modules/user/services/localazy-user-service";
|
|
9
|
+
import { setLocalazyIdentity } from "../../state/localazy-identity";
|
|
10
|
+
|
|
11
|
+
function PluginSettings() {
|
|
12
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
13
|
+
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
async function fetchData() {
|
|
16
|
+
setIsLoading(true);
|
|
17
|
+
|
|
18
|
+
const identity = await LocalazyUserService.getIdentity();
|
|
19
|
+
setLocalazyIdentity(identity);
|
|
20
|
+
|
|
21
|
+
setIsLoading(false);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
fetchData();
|
|
25
|
+
}, []);
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
!isLoading && (
|
|
29
|
+
<ThemeProvider theme={lightTheme}>
|
|
30
|
+
<Box padding={8}>
|
|
31
|
+
<Switch>
|
|
32
|
+
<Route path={`/settings/${pluginId}/content-transfer-setup`} exact>
|
|
33
|
+
<ContentTransferSetup />
|
|
34
|
+
</Route>
|
|
35
|
+
</Switch>
|
|
36
|
+
</Box>
|
|
37
|
+
</ThemeProvider>
|
|
38
|
+
)
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export default PluginSettings;
|