diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/components/Providers.tsx b/packages/client/src/pages/PortalSettings/categories/data-import/components/Providers.tsx
new file mode 100644
index 0000000000..38ddf481ae
--- /dev/null
+++ b/packages/client/src/pages/PortalSettings/categories/data-import/components/Providers.tsx
@@ -0,0 +1,185 @@
+// (c) Copyright Ascensio System SIA 2009-2024
+//
+// This program is a free software product.
+// You can redistribute it and/or modify it under the terms
+// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
+// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
+// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
+// any third-party rights.
+//
+// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
+// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
+//
+// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
+//
+// The interactive user interfaces in modified source and object code versions of the Program must
+// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
+//
+// Pursuant to Section 7(b) of the License you must retain the original Product logo when
+// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
+// trademark law for use of our trademarks.
+//
+// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
+// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
+// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
+
+import { useEffect, useMemo } from "react";
+import { inject, observer } from "mobx-react";
+import { useNavigate } from "react-router-dom";
+import { useTranslation } from "react-i18next";
+import { ReactSVG } from "react-svg";
+
+import { Link } from "@docspace/shared/components/link";
+import { Box } from "@docspace/shared/components/box";
+import { Text } from "@docspace/shared/components/text";
+
+import GoogleWorkspaceSvgUrl from "PUBLIC_DIR/images/workspace.google.react.svg?url";
+import NextcloudWorkspaceSvgUrl from "PUBLIC_DIR/images/workspace.nextcloud.react.svg?url";
+import OnlyofficeWorkspaceSvgUrl from "PUBLIC_DIR/images/workspace.onlyoffice.react.svg?url";
+import GoogleWorkspaceDarkSvgUrl from "PUBLIC_DIR/images/dark.workspace.google.react.svg?url";
+import NextcloudWorkspaceDarkSvgUrl from "PUBLIC_DIR/images/dark.workspace.nextcloud.react.svg?url";
+import OnlyofficeWorkspaceDarkSvgUrl from "PUBLIC_DIR/images/dark.workspace.onlyoffice.react.svg?url";
+import { TWorkspaceService } from "@docspace/shared/api/settings/types";
+import { LinkType } from "@docspace/shared/components/link/Link.enums";
+import DataImportLoader from "../sub-components/DataImportLoader";
+import { WorkspacesContainer } from "../StyledDataImport";
+import { ProvidersProps } from "../types";
+
+const Providers = ({
+ theme,
+ services,
+ setServices,
+ getMigrationList,
+ getMigrationStatus,
+ setDocumentTitle,
+ isMigrationInit,
+ setIsMigrationInit,
+}: ProvidersProps) => {
+ const navigate = useNavigate();
+ const { t } = useTranslation(["Settings"]);
+
+ const workspacesMap = {
+ GoogleWorkspace: "google",
+ Nextcloud: "nextcloud",
+ Workspace: "onlyoffice",
+ };
+
+ const workspaces = useMemo(() => {
+ const logos = {
+ GoogleWorkspace: theme.isBase
+ ? GoogleWorkspaceSvgUrl
+ : GoogleWorkspaceDarkSvgUrl,
+ Nextcloud: theme.isBase
+ ? NextcloudWorkspaceSvgUrl
+ : NextcloudWorkspaceDarkSvgUrl,
+ Workspace: theme.isBase
+ ? OnlyofficeWorkspaceSvgUrl
+ : OnlyofficeWorkspaceDarkSvgUrl,
+ };
+
+ return services.map((service) => ({
+ title: service,
+ logo: logos[service],
+ }));
+ }, [theme.isBase, services]);
+
+ const handleMigrationCheck = async () => {
+ const migrationStatus = await getMigrationStatus();
+
+ if (
+ migrationStatus &&
+ migrationStatus.parseResult?.failedArchives &&
+ migrationStatus.parseResult.failedArchives.length === 0 &&
+ !migrationStatus.error
+ ) {
+ const migratorName = migrationStatus.parseResult.migratorName;
+
+ navigate(`${workspacesMap[migratorName]}?service=${migratorName}`);
+
+ return;
+ }
+
+ const migrationList = await getMigrationList();
+ setIsMigrationInit(true);
+ setServices(migrationList);
+ };
+
+ useEffect(() => {
+ setDocumentTitle(t("DataImport"));
+ handleMigrationCheck();
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, []);
+
+ const redirectToWorkspace = (title: TWorkspaceService) => {
+ switch (title) {
+ case "GoogleWorkspace":
+ navigate(`google?service=${title}`);
+ break;
+ case "Nextcloud":
+ navigate(`nextcloud?service=${title}`);
+ break;
+ case "Workspace":
+ navigate(`onlyoffice?service=${title}`);
+ break;
+ default:
+ break;
+ }
+ };
+
+ if (!isMigrationInit) return ;
+ return (
+
+
+ {t("DataImportDescription")}
+
+ {t("UploadBackupData")}
+
+
+ {workspaces.map((workspace) => (
+ redirectToWorkspace(workspace.title)}
+ >
+
+
+ {t("Import")}
+
+
+ ))}
+
+
+ );
+};
+export default inject(
+ ({ authStore, settingsStore, importAccountsStore }) => {
+ const {
+ services,
+ setServices,
+ getMigrationList,
+ getMigrationStatus,
+ isMigrationInit,
+ setIsMigrationInit,
+ } = importAccountsStore;
+
+ const { setDocumentTitle } = authStore;
+
+ return {
+ services,
+ setServices,
+ getMigrationList,
+ getMigrationStatus,
+ theme: settingsStore.theme,
+ setDocumentTitle,
+ isMigrationInit,
+ setIsMigrationInit,
+ };
+ },
+)(observer(Providers));
diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/index.js b/packages/client/src/pages/PortalSettings/categories/data-import/index.js
index e139e7b95f..3e1cfd98b8 100644
--- a/packages/client/src/pages/PortalSettings/categories/data-import/index.js
+++ b/packages/client/src/pages/PortalSettings/categories/data-import/index.js
@@ -24,161 +24,10 @@
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
-import { useEffect, useMemo } from "react";
-import { inject, observer } from "mobx-react";
-import { useNavigate } from "react-router-dom";
-import { withTranslation } from "react-i18next";
-import { ReactSVG } from "react-svg";
+import Providers from "./components/Providers";
-import { Link } from "@docspace/shared/components/link";
-import { Box } from "@docspace/shared/components/box";
-import { Text } from "@docspace/shared/components/text";
-import { WorkspacesContainer } from "./StyledDataImport";
-
-import GoogleWorkspaceSvgUrl from "PUBLIC_DIR/images/workspace.google.react.svg?url";
-import NextcloudWorkspaceSvgUrl from "PUBLIC_DIR/images/workspace.nextcloud.react.svg?url";
-import OnlyofficeWorkspaceSvgUrl from "PUBLIC_DIR/images/workspace.onlyoffice.react.svg?url";
-import GoogleWorkspaceDarkSvgUrl from "PUBLIC_DIR/images/dark.workspace.google.react.svg?url";
-import NextcloudWorkspaceDarkSvgUrl from "PUBLIC_DIR/images/dark.workspace.nextcloud.react.svg?url";
-import OnlyofficeWorkspaceDarkSvgUrl from "PUBLIC_DIR/images/dark.workspace.onlyoffice.react.svg?url";
-import DataImportLoader from "./sub-components/DataImportLoader";
-
-const DataImport = ({
- t,
- theme,
- services,
- setServices,
- getMigrationList,
- getMigrationStatus,
- setDocumentTitle,
- isMigrationInit,
- setIsMigrationInit,
-}) => {
- const navigate = useNavigate();
-
- const google = theme.isBase
- ? GoogleWorkspaceSvgUrl
- : GoogleWorkspaceDarkSvgUrl;
-
- const nextcloud = theme.isBase
- ? NextcloudWorkspaceSvgUrl
- : NextcloudWorkspaceDarkSvgUrl;
-
- const onlyoffice = theme.isBase
- ? OnlyofficeWorkspaceSvgUrl
- : OnlyofficeWorkspaceDarkSvgUrl;
-
- const logos = {
- GoogleWorkspace: google,
- Nextcloud: nextcloud,
- Workspace: onlyoffice,
- };
-
- const workspaces = useMemo(() => {
- return services.map((service) => ({
- title: service,
- logo: logos[service],
- }));
- }, [theme.isBase, services]);
-
- const handleMigrationCheck = async () => {
- const migrationStatus = await getMigrationStatus();
-
- if (
- migrationStatus &&
- migrationStatus.parseResult?.failedArchives &&
- migrationStatus.parseResult.failedArchives.length === 0 &&
- !migrationStatus.error
- ) {
- const workspacesEnum = {
- GoogleWorkspace: "google",
- Nextcloud: "nextcloud",
- Workspace: "onlyoffice",
- };
- const migratorName = migrationStatus.parseResult.migratorName;
-
- navigate(`${workspacesEnum[migratorName]}?service=${migratorName}`);
-
- return;
- }
-
- const migrationList = await getMigrationList();
- setIsMigrationInit(true);
- setServices(migrationList);
- };
-
- useEffect(() => {
- setDocumentTitle(t("DataImport"));
- handleMigrationCheck();
- }, []);
-
- const redirectToWorkspace = (title) => {
- switch (title) {
- case "GoogleWorkspace":
- navigate(`google?service=${title}`);
- break;
- case "Nextcloud":
- navigate(`nextcloud?service=${title}`);
- break;
- case "Workspace":
- navigate(`onlyoffice?service=${title}`);
- break;
- default:
- break;
- }
- };
-
- if (!isMigrationInit) return ;
- return (
-
-
- {t("DataImportDescription")}
-
- {t("UploadBackupData")}
-
-
- {workspaces.map((workspace) => (
- redirectToWorkspace(workspace.title)}
- >
-
-
- {t("Import")}
-
-
- ))}
-
-
- );
+const DataImport = () => {
+ return ;
};
-export default inject(({ authStore, settingsStore, importAccountsStore }) => {
- const {
- services,
- setServices,
- getMigrationList,
- getMigrationStatus,
- isMigrationInit,
- setIsMigrationInit,
- } = importAccountsStore;
- const { setDocumentTitle } = authStore;
-
- return {
- services,
- setServices,
- getMigrationList,
- getMigrationStatus,
- theme: settingsStore.theme,
- setDocumentTitle,
- isMigrationInit,
- setIsMigrationInit,
- };
-})(withTranslation(["Settings"])(observer(DataImport)));
+export default DataImport;
diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/sub-components/DataImportLoader.js b/packages/client/src/pages/PortalSettings/categories/data-import/sub-components/DataImportLoader.tsx
similarity index 100%
rename from packages/client/src/pages/PortalSettings/categories/data-import/sub-components/DataImportLoader.js
rename to packages/client/src/pages/PortalSettings/categories/data-import/sub-components/DataImportLoader.tsx
diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/types/index.ts b/packages/client/src/pages/PortalSettings/categories/data-import/types/index.ts
new file mode 100644
index 0000000000..7b2cf455e8
--- /dev/null
+++ b/packages/client/src/pages/PortalSettings/categories/data-import/types/index.ts
@@ -0,0 +1,36 @@
+// (c) Copyright Ascensio System SIA 2009-2024
+//
+// This program is a free software product.
+// You can redistribute it and/or modify it under the terms
+// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
+// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
+// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
+// any third-party rights.
+//
+// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
+// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
+//
+// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
+//
+// The interactive user interfaces in modified source and object code versions of the Program must
+// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
+//
+// Pursuant to Section 7(b) of the License you must retain the original Product logo when
+// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
+// trademark law for use of our trademarks.
+//
+// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
+// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
+// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
+
+export interface ProvidersProps {
+ theme: TStore["settingsStore"]["theme"];
+ services: TStore["importAccountsStore"]["services"];
+ setServices: TStore["importAccountsStore"]["setServices"];
+ getMigrationList: TStore["importAccountsStore"]["getMigrationList"];
+ getMigrationStatus: TStore["importAccountsStore"]["getMigrationStatus"];
+ setDocumentTitle: TStore["authStore"]["setDocumentTitle"];
+ isMigrationInit: TStore["importAccountsStore"]["isMigrationInit"];
+ setIsMigrationInit: TStore["importAccountsStore"]["setIsMigrationInit"];
+}
diff --git a/packages/client/src/store/ImportAccountsStore.ts b/packages/client/src/store/ImportAccountsStore.ts
index 43ce7a04f0..3b6ced71fa 100644
--- a/packages/client/src/store/ImportAccountsStore.ts
+++ b/packages/client/src/store/ImportAccountsStore.ts
@@ -30,7 +30,7 @@ import { combineUrl } from "@docspace/shared/utils/combineUrl";
import { makeAutoObservable, runInAction } from "mobx";
import {
migrationList,
- migrationName,
+ initMigration,
migrationStatus,
migrationCancel,
migrationFinish,
@@ -38,64 +38,30 @@ import {
migrateFile,
migrationClear,
} from "@docspace/shared/api/settings";
-
-type TUser = {
- key: string;
- email: string;
- displayName: string;
- firstName: string;
- userType: string;
- migratingFiles: {
- foldersCount: number;
- filesCount: number;
- bytesTotal: number;
- };
- shouldImport: boolean;
-};
+import {
+ TWorkspaceService,
+ TSendWelcomeEmailData,
+ TMigrationUser,
+ TMigrationStatusResult,
+} from "@docspace/shared/api/settings/types";
type TUsers = {
- new: TUser[];
- existing: TUser[];
- withoutEmail: TUser[];
- result: TUser[];
+ new: TMigrationUser[];
+ existing: TMigrationUser[];
+ withoutEmail: TMigrationUser[];
+ result: TMigrationUser[];
};
type TCheckedUsers = {
- withEmail: TUser[];
- withoutEmail: TUser[];
- result: TUser[];
-};
-
-type TGroup = {
- groupName: string;
- userUidList: string[];
- shouldImport: boolean;
-};
-
-type TResponseData = {
- migratorName: string;
- operation: string;
- failedArchives: string[];
- users: TUser[];
- withoutEmailUsers: TUser[];
- existUsers: TUser[];
- groups: TGroup[];
- importPersonalFiles: boolean;
- importSharedFiles: boolean;
- importSharedFolders: boolean;
- importCommonFiles: boolean;
- importProjectFiles: boolean;
- importGroups: boolean;
- successedUsers: number;
- failedUsers: number;
- files: string[];
- errors: string[];
+ withEmail: TMigrationUser[];
+ withoutEmail: TMigrationUser[];
+ result: TMigrationUser[];
};
type CheckedAccountTypes = "withEmail" | "withoutEmail" | "result";
class ImportAccountsStore {
- services: string[] = [];
+ services: TWorkspaceService[] = [];
users: TUsers = {
new: [],
@@ -186,7 +152,7 @@ class ImportAccountsStore {
});
};
- setUsers = (data: TResponseData) => {
+ setUsers = (data: TMigrationStatusResult) => {
runInAction(() => {
this.users = {
new: data.users,
@@ -227,7 +193,10 @@ class ImportAccountsStore {
};
};
- toggleAccount = (account: TUser, checkedAccountType: CheckedAccountTypes) => {
+ toggleAccount = (
+ account: TMigrationUser,
+ checkedAccountType: CheckedAccountTypes,
+ ) => {
this.checkedUsers = this.checkedUsers[checkedAccountType].some(
(user) => user.key === account.key,
)
@@ -248,7 +217,7 @@ class ImportAccountsStore {
toggleAllAccounts = (
isChecked: boolean,
- accounts: TUser[],
+ accounts: TMigrationUser[],
checkedAccountType: CheckedAccountTypes,
) => {
this.checkedUsers = isChecked
@@ -305,10 +274,6 @@ class ImportAccountsStore {
};
};
- // get numberOfCheckedAccounts() {
- // return this.checkedAccounts.length;
- // }
-
multipleFileUploading = async (
files: File[],
setProgress: (progress: number) => void,
@@ -418,7 +383,7 @@ class ImportAccountsStore {
this.importOptions = { ...this.importOptions, ...value };
};
- setServices = (services: string[]) => {
+ setServices = (services: TWorkspaceService[]) => {
this.services = services;
};
@@ -428,11 +393,11 @@ class ImportAccountsStore {
};
// eslint-disable-next-line class-methods-use-this
- initMigrationName = (name: string) => {
- return migrationName(name);
+ initMigrationName = (name: TWorkspaceService) => {
+ return initMigration(name);
};
- proceedFileMigration = (migratorName: string) => {
+ proceedFileMigration = (migratorName: TWorkspaceService) => {
const users = this.finalUsers.map((item) =>
Object.assign(item, { shouldImport: true }),
);
@@ -461,19 +426,16 @@ class ImportAccountsStore {
// eslint-disable-next-line class-methods-use-this
getMigrationLog = () => {
- return migrationLog()
- .then((response) => {
- if (!response || !response.data) return null;
- return response.data;
- })
- .catch((error) => {
- console.log("Request Failed:", { error });
- return Promise.reject(error);
- });
+ try {
+ return migrationLog();
+ } catch (error) {
+ console.log("Request Failed:", { error });
+ return Promise.reject(error);
+ }
};
// eslint-disable-next-line class-methods-use-this
- sendWelcomeLetter = (data: { isSendWelcomeEmail: boolean }) => {
+ sendWelcomeLetter = (data: TSendWelcomeEmailData) => {
return migrationFinish(data);
};
}
diff --git a/packages/shared/api/settings/index.ts b/packages/shared/api/settings/index.ts
index efc69c4224..be89755e97 100644
--- a/packages/shared/api/settings/index.ts
+++ b/packages/shared/api/settings/index.ts
@@ -46,6 +46,10 @@ import {
TThirdPartyProvider,
TPaymentSettings,
TGetSsoSettings,
+ TWorkspaceService,
+ TWorkspaceStatusResponse,
+ TMigrationData,
+ TSendWelcomeEmailData,
} from "./types";
export async function getSettings(withPassword = false, headers = null) {
@@ -1087,28 +1091,30 @@ export function getSendingTestMailStatus() {
});
}
-export function migrationList() {
- return request({
+export async function migrationList() {
+ const res = (await request({
method: "get",
url: `/migration/list`,
- });
+ })) as TWorkspaceService[];
+ return res;
}
-export function migrationName(name) {
+export function initMigration(name: TWorkspaceService) {
return request({
method: "post",
url: `/migration/init/${name}`,
});
}
-export function migrationStatus() {
- return request({
+export async function migrationStatus() {
+ const res = (await request({
method: "get",
url: `/migration/status`,
- });
+ })) as TWorkspaceStatusResponse;
+ return res;
}
-export function migrateFile(data) {
+export function migrateFile(data: TMigrationData) {
return request({
method: "post",
url: `/migration/migrate`,
@@ -1130,11 +1136,13 @@ export function migrationClear() {
});
}
-export function migrationLog() {
- return axios.get("/api/2.0/migration/logs");
+export async function migrationLog() {
+ const response = await axios.get("/api/2.0/migration/logs");
+ if (!response || !response.data) return null;
+ return response.data as string;
}
-export function migrationFinish(data) {
+export function migrationFinish(data: TSendWelcomeEmailData) {
return request({
method: "post",
url: `/migration/finish`,
diff --git a/packages/shared/api/settings/types.ts b/packages/shared/api/settings/types.ts
index ddc65ff68d..1971def085 100644
--- a/packages/shared/api/settings/types.ts
+++ b/packages/shared/api/settings/types.ts
@@ -239,3 +239,64 @@ export type TPaymentSettings = {
};
max: number;
};
+
+export type TWorkspaceService = "Workspace" | "GoogleWorkspace" | "Nextcloud";
+
+export type TMigrationGroup = {
+ groupName: string;
+ userUidList: string[];
+ shouldImport: boolean;
+};
+
+export type TImportOptions = {
+ importGroups: boolean;
+ importPersonalFiles: boolean;
+ importSharedFiles: boolean;
+ importSharedFolders: boolean;
+ importCommonFiles: boolean;
+ importProjectFiles: boolean;
+};
+
+export type TMigrationUser = {
+ key: string;
+ email: string;
+ displayName: string;
+ firstName: string;
+ userType: string;
+ migratingFiles: {
+ foldersCount: number;
+ filesCount: number;
+ bytesTotal: number;
+ };
+ shouldImport: boolean;
+};
+
+export type TMigrationStatusResult = {
+ migratorName: TWorkspaceService;
+ operation: string;
+ failedArchives: string[];
+ users: TMigrationUser[];
+ withoutEmailUsers: TMigrationUser[];
+ existUsers: TMigrationUser[];
+ groups: TMigrationGroup[];
+ successedUsers: number;
+ failedUsers: number;
+ files: string[];
+ errors: string[];
+} & TImportOptions;
+
+export type TWorkspaceStatusResponse =
+ | {
+ error: string;
+ isCompleted: boolean;
+ progress: number;
+ parseResult: TMigrationStatusResult;
+ }
+ | undefined;
+
+export type TMigrationData = {
+ users: TMigrationUser[];
+ migratorName: TWorkspaceService;
+} & TImportOptions;
+
+export type TSendWelcomeEmailData = { isSendWelcomeEmail: boolean };