Web: Client: Data Import: providers page was translated in ts

This commit is contained in:
Vladimir Khvan 2024-05-29 18:12:51 +05:00
parent ba24fc55fa
commit 87c21c3a59
7 changed files with 337 additions and 236 deletions

View File

@ -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 <DataImportLoader />;
return (
<WorkspacesContainer>
<Text className="data-import-description">
{t("DataImportDescription")}
</Text>
<Text className="data-import-subtitle">{t("UploadBackupData")}</Text>
<Box className="workspace-list">
{workspaces.map((workspace) => (
<Box
key={workspace.title}
className="workspace-item"
onClick={() => redirectToWorkspace(workspace.title)}
>
<ReactSVG src={workspace.logo} className="workspace-logo" />
<Link
type={LinkType.page}
fontWeight="600"
color="#4781D1"
isHovered
isTextOverflow
>
{t("Import")}
</Link>
</Box>
))}
</Box>
</WorkspacesContainer>
);
};
export default inject<TStore>(
({ 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));

View File

@ -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 <DataImportLoader />;
return (
<WorkspacesContainer>
<Text className="data-import-description">
{t("DataImportDescription")}
</Text>
<Text className="data-import-subtitle">{t("UploadBackupData")}</Text>
<Box className="workspace-list">
{workspaces.map((workspace) => (
<Box
key={workspace.title}
className="workspace-item"
onClick={() => redirectToWorkspace(workspace.title)}
>
<ReactSVG src={workspace.logo} className="workspace-logo" />
<Link
type="page"
fontWeight="600"
color="#4781D1"
isHovered
isTextOverflow
>
{t("Import")}
</Link>
</Box>
))}
</Box>
</WorkspacesContainer>
);
const DataImport = () => {
return <Providers />;
};
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;

View File

@ -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"];
}

View File

@ -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);
};
}

View File

@ -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`,

View File

@ -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 };