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 index 38ddf481ae..f393aaa9dc 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/components/Providers.tsx +++ b/packages/client/src/pages/PortalSettings/categories/data-import/components/Providers.tsx @@ -24,9 +24,8 @@ // 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 { useState, useEffect, useMemo, useCallback } from "react"; import { inject, observer } from "mobx-react"; -import { useNavigate } from "react-router-dom"; import { useTranslation } from "react-i18next"; import { ReactSVG } from "react-svg"; @@ -40,31 +39,20 @@ import OnlyofficeWorkspaceSvgUrl from "PUBLIC_DIR/images/workspace.onlyoffice.re 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"; +import { ProvidersProps, InjectedProvidersProps } from "../types"; + +const Providers = (props: ProvidersProps) => { + const { theme, services, setServices, getMigrationList, setWorkspace } = + props as InjectedProvidersProps; + + const [areProvidersReady, setAreProvidersReady] = useState(false); -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 @@ -84,50 +72,17 @@ const Providers = ({ })); }, [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 handleMigrationCheck = useCallback(async () => { const migrationList = await getMigrationList(); - setIsMigrationInit(true); + setAreProvidersReady(true); setServices(migrationList); - }; + }, [getMigrationList, setServices]); useEffect(() => { - setDocumentTitle(t("DataImport")); handleMigrationCheck(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + }, [handleMigrationCheck]); - 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 ; + if (!areProvidersReady) return ; return ( @@ -140,7 +95,7 @@ const Providers = ({ redirectToWorkspace(workspace.title)} + onClick={() => setWorkspace(workspace.title)} > ); }; -export default inject( - ({ authStore, settingsStore, importAccountsStore }) => { - const { - services, - setServices, - getMigrationList, - getMigrationStatus, - isMigrationInit, - setIsMigrationInit, - } = importAccountsStore; +export default inject(({ settingsStore, importAccountsStore }) => { + const { + services, + setServices, + getMigrationList, + isMigrationInit, + setIsMigrationInit, + setWorkspace, + } = importAccountsStore; - const { setDocumentTitle } = authStore; - - return { - services, - setServices, - getMigrationList, - getMigrationStatus, - theme: settingsStore.theme, - setDocumentTitle, - isMigrationInit, - setIsMigrationInit, - }; - }, -)(observer(Providers)); + return { + services, + setServices, + getMigrationList, + theme: settingsStore.theme, + isMigrationInit, + setIsMigrationInit, + setWorkspace, + }; +})(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 deleted file mode 100644 index 3e1cfd98b8..0000000000 --- a/packages/client/src/pages/PortalSettings/categories/data-import/index.js +++ /dev/null @@ -1,33 +0,0 @@ -// (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 Providers from "./components/Providers"; - -const DataImport = () => { - return ; -}; - -export default DataImport; diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/index.tsx b/packages/client/src/pages/PortalSettings/categories/data-import/index.tsx new file mode 100644 index 0000000000..080ff8e55c --- /dev/null +++ b/packages/client/src/pages/PortalSettings/categories/data-import/index.tsx @@ -0,0 +1,139 @@ +// (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, useCallback } from "react"; +import { inject, observer } from "mobx-react"; +import { useTranslation } from "react-i18next"; +import useViewEffect from "SRC_DIR/Hooks/useViewEffect"; + +import { toastr } from "@docspace/shared/components/toast"; + +import { DataImportProps, InjectedDataImportProps } from "./types"; + +import Providers from "./components/Providers"; + +const DataImport = (props: DataImportProps) => { + const { + setDocumentTitle, + viewAs, + setViewAs, + currentDeviceType, + + getMigrationStatus, + isMigrationInit, + setUsers, + workspace, + setWorkspace, + setFiles, + setIsMigrationInit, + } = props as InjectedDataImportProps; + + const { t } = useTranslation(["Settings"]); + + useViewEffect({ + view: viewAs, + setView: setViewAs, + currentDeviceType, + }); + + useEffect(() => { + setDocumentTitle(t("DataImport")); + }, [setDocumentTitle, t]); + + const updateStatus = useCallback(async () => { + const response = await getMigrationStatus(); + + if (!response) return; + + const { parseResult, isCompleted } = response; + + if (parseResult.operation === "parse" && isCompleted) { + setUsers(parseResult); + setWorkspace(parseResult.migratorName); + setFiles(parseResult.files); + setIsMigrationInit(true); + } + }, [ + getMigrationStatus, + setIsMigrationInit, + setFiles, + setUsers, + setWorkspace, + ]); + + useEffect(() => { + try { + if (!isMigrationInit) { + updateStatus(); + } + } catch (error) { + toastr.error(error as string); + } + }, [isMigrationInit, updateStatus]); + + return workspace === "Nextcloud" ? ( +
next
+ ) : workspace === "GoogleWorkspace" ? ( +
google
+ ) : workspace === "Workspace" ? ( +
onlyoffice
+ ) : ( + + ); +}; + +export default inject( + ({ authStore, settingsStore, setup, importAccountsStore }) => { + const { + getMigrationStatus, + isMigrationInit, + setUsers, + workspace, + setWorkspace, + setFiles, + setIsMigrationInit, + } = importAccountsStore; + + const { setDocumentTitle } = authStore; + const { viewAs, setViewAs } = setup; + const { currentDeviceType } = settingsStore; + + return { + setDocumentTitle, + viewAs, + setViewAs, + currentDeviceType, + + getMigrationStatus, + isMigrationInit, + setUsers, + workspace, + setWorkspace, + setFiles, + setIsMigrationInit, + }; + }, +)(observer(DataImport)); 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 index 7b2cf455e8..dff1393d03 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/types/index.ts +++ b/packages/client/src/pages/PortalSettings/categories/data-import/types/index.ts @@ -24,7 +24,9 @@ // 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 { +export interface ProvidersProps {} + +export interface InjectedProvidersProps extends ProvidersProps { theme: TStore["settingsStore"]["theme"]; services: TStore["importAccountsStore"]["services"]; setServices: TStore["importAccountsStore"]["setServices"]; @@ -33,4 +35,34 @@ export interface ProvidersProps { setDocumentTitle: TStore["authStore"]["setDocumentTitle"]; isMigrationInit: TStore["importAccountsStore"]["isMigrationInit"]; setIsMigrationInit: TStore["importAccountsStore"]["setIsMigrationInit"]; + setWorkspace: TStore["importAccountsStore"]["setWorkspace"]; +} + +export interface SelectFileStepProps { + incrementStep: () => void; + cancelUploadDialogVisible: TStore["dialogsStore"]["cancelUploadDialogVisible"]; + setCancelUploadDialogVisible: TStore["dialogsStore"]["setCancelUploadDialogVisible"]; + initMigrationName: TStore["importAccountsStore"]["initMigrationName"]; + singleFileUploading: TStore["importAccountsStore"]["singleFileUploading"]; + getMigrationStatus: TStore["importAccountsStore"]["getMigrationStatus"]; + setUsers: TStore["importAccountsStore"]["setUsers"]; + isFileLoading: TStore["importAccountsStore"]["isFileLoading"]; + setIsFileLoading: TStore["importAccountsStore"]["setIsFileLoading"]; + cancelMigration: TStore["importAccountsStore"]["cancelMigration"]; +} + +export interface DataImportProps {} + +export interface InjectedDataImportProps { + setDocumentTitle: TStore["authStore"]["setDocumentTitle"]; + getMigrationStatus: TStore["importAccountsStore"]["getMigrationStatus"]; + viewAs: TStore["setup"]["viewAs"]; + setViewAs: TStore["setup"]["setViewAs"]; + currentDeviceType: TStore["settingsStore"]["currentDeviceType"]; + isMigrationInit: TStore["importAccountsStore"]["isMigrationInit"]; + setUsers: TStore["importAccountsStore"]["setUsers"]; + workspace: TStore["importAccountsStore"]["workspace"]; + setWorkspace: TStore["importAccountsStore"]["setWorkspace"]; + setFiles: TStore["importAccountsStore"]["setFiles"]; + setIsMigrationInit: TStore["importAccountsStore"]["setIsMigrationInit"]; } diff --git a/packages/client/src/routes/portalSettings.js b/packages/client/src/routes/portalSettings.js index 5e8acc34dc..4b9dabb6c4 100644 --- a/packages/client/src/routes/portalSettings.js +++ b/packages/client/src/routes/portalSettings.js @@ -233,7 +233,7 @@ const DeveloperTools = loadable(() => const DataImport = loadable(() => componentLoader( - () => import("../pages/PortalSettings/categories/data-import/index.js"), + () => import("../pages/PortalSettings/categories/data-import/index.tsx"), ), ); const GoogleDataImport = loadable(() => diff --git a/packages/client/src/store/ImportAccountsStore.ts b/packages/client/src/store/ImportAccountsStore.ts index 3b6ced71fa..bc32b13ebf 100644 --- a/packages/client/src/store/ImportAccountsStore.ts +++ b/packages/client/src/store/ImportAccountsStore.ts @@ -90,6 +90,12 @@ class ImportAccountsStore { searchValue = ""; + step = 1; + + workspace: TWorkspaceService | "" = ""; + + files: string[] = []; + importOptions = { importGroups: true, importPersonalFiles: true, @@ -131,6 +137,18 @@ class ImportAccountsStore { ); } + setStep = (step: number) => { + this.step = step; + }; + + setWorkspace = (workspace: TWorkspaceService | "") => { + this.workspace = workspace; + }; + + setFiles = (files: string[]) => { + this.files = files; + }; + setResultUsers = () => { const checkedIds = this.checkedUsers.withoutEmail.map( (checkedUser) => checkedUser.key, diff --git a/packages/shared/api/settings/types.ts b/packages/shared/api/settings/types.ts index 1971def085..1c7bb551a0 100644 --- a/packages/shared/api/settings/types.ts +++ b/packages/shared/api/settings/types.ts @@ -241,6 +241,7 @@ export type TPaymentSettings = { }; export type TWorkspaceService = "Workspace" | "GoogleWorkspace" | "Nextcloud"; +export type MigrationOperation = "parse" | "migration"; export type TMigrationGroup = { groupName: string; @@ -273,7 +274,7 @@ export type TMigrationUser = { export type TMigrationStatusResult = { migratorName: TWorkspaceService; - operation: string; + operation: MigrationOperation; failedArchives: string[]; users: TMigrationUser[]; withoutEmailUsers: TMigrationUser[];