From 59255bf75b38e28bc3262b53d2ff0f3237a7601e Mon Sep 17 00:00:00 2001 From: Vladimir Khvan Date: Tue, 2 Jul 2024 15:21:58 +0500 Subject: [PATCH] Web: Client: Data Import: add cancel migration button --- .../client/public/locales/en/Settings.json | 1 + .../data-import/StyledDataImport.ts | 8 - .../components/AddEmailsStep/index.tsx | 63 +++++++- .../components/SelectUsersStep/index.tsx | 112 ++++++++++---- .../components/SelectUsersTypeStep/index.tsx | 62 +++++++- .../sub-components/MigrationButtons.tsx | 138 ++++++++++++++++++ .../categories/data-import/types/index.ts | 32 ++++ 7 files changed, 370 insertions(+), 46 deletions(-) create mode 100644 packages/client/src/pages/PortalSettings/categories/data-import/sub-components/MigrationButtons.tsx diff --git a/packages/client/public/locales/en/Settings.json b/packages/client/public/locales/en/Settings.json index cfa531055e..4d5b014fa4 100644 --- a/packages/client/public/locales/en/Settings.json +++ b/packages/client/public/locales/en/Settings.json @@ -65,6 +65,7 @@ "ButtonsColor": "Buttons", "ByApp": "By authenticator app", "BySms": "By sms", + "CancelImport": "Cancel import", "ChangeLogoButton": "Change Logo", "Characters": "{{length}} characters", "CheckPeriod": "Check period (sec)", diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/StyledDataImport.ts b/packages/client/src/pages/PortalSettings/categories/data-import/StyledDataImport.ts index e08bbb31f1..2ca64010d5 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/StyledDataImport.ts +++ b/packages/client/src/pages/PortalSettings/categories/data-import/StyledDataImport.ts @@ -117,14 +117,6 @@ export const Wrapper = styled.div` margin: 12px 0 16px; } - .save-cancel-buttons { - margin-bottom: 16px; - - @media ${mobile} { - margin-bottom: 0; - } - } - .mt-8 { margin-top: 8px; } diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/components/AddEmailsStep/index.tsx b/packages/client/src/pages/PortalSettings/categories/data-import/components/AddEmailsStep/index.tsx index 88ac6bb26b..2f0071a142 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/components/AddEmailsStep/index.tsx +++ b/packages/client/src/pages/PortalSettings/categories/data-import/components/AddEmailsStep/index.tsx @@ -27,7 +27,6 @@ import { useState, useEffect } from "react"; import { inject, observer } from "mobx-react"; -import { SaveCancelButtons } from "@docspace/shared/components/save-cancel-buttons"; import { SearchInput } from "@docspace/shared/components/search-input"; import { Text } from "@docspace/shared/components/text"; @@ -43,6 +42,8 @@ import { NoEmailUsersBlock } from "../../sub-components/NoEmailUsersBlock"; import { parseQuota } from "../../utils"; import { AddEmailsStepProps, InjectedAddEmailsStepProps } from "../../types"; +import { MigrationButtons } from "../../sub-components/MigrationButtons"; +import { CancelUploadDialog } from "SRC_DIR/components/dialogs"; const PAGE_SIZE = 25; const REFRESH_TIMEOUT = 100; @@ -60,6 +61,15 @@ const AddEmailsStep = (props: AddEmailsStepProps) => { areCheckedUsersEmpty, checkedUsers, withEmailUsers, + cancelMigration, + clearCheckedAccounts, + setStep, + setWorkspace, + setMigratingWorkspace, + setMigrationPhase, + + cancelUploadDialogVisible, + setCancelUploadDialogVisible, quotaCharacteristics, } = props as InjectedAddEmailsStepProps; @@ -108,9 +118,21 @@ const AddEmailsStep = (props: AddEmailsStepProps) => { quota.used + checkedUsers.withEmail.filter((user) => !user.isDuplicate).length + checkedUsers.withoutEmail.length; + + const onCancelMigration = () => { + cancelMigration(); + clearCheckedAccounts(); + setStep(1); + setWorkspace(""); + setMigratingWorkspace(""); + setMigrationPhase(""); + }; + + const showCancelDialog = () => setCancelUploadDialogVisible(true); + const hideCancelDialog = () => setCancelUploadDialogVisible(false); const Buttons = ( - { saveButtonDisabled={ areCheckedUsersEmpty || (quota.max ? totalUsedUsers > quota.max : false) } + migrationCancelLabel={t("Settings:CancelImport")} + onMigrationCancelClick={showCancelDialog} /> ); @@ -172,11 +196,22 @@ const AddEmailsStep = (props: AddEmailsStepProps) => { )} {Buttons} + + {cancelUploadDialogVisible && ( + + )} ); }; -export default inject(({ importAccountsStore, currentQuotaStore }) => { +export default inject(({ importAccountsStore, currentQuotaStore, dialogsStore }) => { const { incrementStep, decrementStep, @@ -187,8 +222,17 @@ export default inject(({ importAccountsStore, currentQuotaStore }) => { areCheckedUsersEmpty, checkedUsers, withEmailUsers, + + cancelMigration, + clearCheckedAccounts, + setStep, + setWorkspace, + setMigratingWorkspace, + setMigrationPhase, } = importAccountsStore; const { quotaCharacteristics } = currentQuotaStore; + const { cancelUploadDialogVisible, setCancelUploadDialogVisible } = + dialogsStore; return { incrementStep, @@ -199,7 +243,18 @@ export default inject(({ importAccountsStore, currentQuotaStore }) => { setResultUsers, areCheckedUsersEmpty, checkedUsers, - quotaCharacteristics, withEmailUsers, + + cancelMigration, + clearCheckedAccounts, + setStep, + setWorkspace, + setMigratingWorkspace, + setMigrationPhase, + + quotaCharacteristics, + + cancelUploadDialogVisible, + setCancelUploadDialogVisible, }; })(observer(AddEmailsStep)); diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/components/SelectUsersStep/index.tsx b/packages/client/src/pages/PortalSettings/categories/data-import/components/SelectUsersStep/index.tsx index 24f3a90e99..22e86277bc 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/components/SelectUsersStep/index.tsx +++ b/packages/client/src/pages/PortalSettings/categories/data-import/components/SelectUsersStep/index.tsx @@ -27,11 +27,11 @@ import { useEffect, useState } from "react"; import { inject, observer } from "mobx-react"; -import { SaveCancelButtons } from "@docspace/shared/components/save-cancel-buttons"; import { SearchInput } from "@docspace/shared/components/search-input"; import { Text } from "@docspace/shared/components/text"; import { InputSize } from "@docspace/shared/components/text-input"; +import { CancelUploadDialog } from "SRC_DIR/components/dialogs"; import AccountsTable from "./AccountsTable"; import AccountsPaging from "../../sub-components/AccountsPaging"; @@ -44,6 +44,7 @@ import { SelectUsersStepProps, InjectedSelectUsersStepProps, } from "../../types"; +import { MigrationButtons } from "../../sub-components/MigrationButtons"; const REFRESH_TIMEOUT = 100; const PAGE_SIZE = 25; @@ -63,6 +64,15 @@ const SelectUsersStep = (props: SelectUsersStepProps) => { users, areCheckedUsersEmpty, setResultUsers, + cancelMigration, + clearCheckedAccounts, + setStep, + setWorkspace, + setMigratingWorkspace, + setMigrationPhase, + + cancelUploadDialogVisible, + setCancelUploadDialogVisible, quotaCharacteristics, } = props as InjectedSelectUsersStepProps; @@ -117,8 +127,20 @@ const SelectUsersStep = (props: SelectUsersStepProps) => { } : incrementStep; + const onCancelMigration = () => { + cancelMigration(); + clearCheckedAccounts(); + setStep(1); + setWorkspace(""); + setMigratingWorkspace(""); + setMigrationPhase(""); + }; + + const showCancelDialog = () => setCancelUploadDialogVisible(true); + const hideCancelDialog = () => setCancelUploadDialogVisible(false); + const Buttons = ( - { (areCheckedUsersEmpty || (quota.max ? totalUsedUsers > quota.max : false)) } + migrationCancelLabel={t("Settings:CancelImport")} + onMigrationCancelClick={showCancelDialog} /> ); @@ -178,38 +202,66 @@ const SelectUsersStep = (props: SelectUsersStepProps) => { )} {filteredAccounts.length > 0 && Buttons} + + {cancelUploadDialogVisible && ( + + )} ); }; -export default inject(({ importAccountsStore, currentQuotaStore }) => { - const { - incrementStep, - decrementStep, - users, - withEmailUsers, - searchValue, - setSearchValue, - cancelMigration, - checkedUsers, - areCheckedUsersEmpty, - setResultUsers, - } = importAccountsStore; +export default inject( + ({ importAccountsStore, currentQuotaStore, dialogsStore }) => { + const { + incrementStep, + decrementStep, + users, + withEmailUsers, + searchValue, + setSearchValue, + cancelMigration, + checkedUsers, + areCheckedUsersEmpty, + setResultUsers, + clearCheckedAccounts, + setStep, + setWorkspace, + setMigratingWorkspace, + setMigrationPhase, + } = importAccountsStore; + const { cancelUploadDialogVisible, setCancelUploadDialogVisible } = + dialogsStore; - const { quotaCharacteristics } = currentQuotaStore; + const { quotaCharacteristics } = currentQuotaStore; - return { - incrementStep, - decrementStep, - users, - withEmailUsers, - searchValue, - setSearchValue, - cancelMigration, - checkedUsers, - areCheckedUsersEmpty, - setResultUsers, + return { + incrementStep, + decrementStep, + users, + withEmailUsers, + searchValue, + setSearchValue, + cancelMigration, + checkedUsers, + areCheckedUsersEmpty, + setResultUsers, + clearCheckedAccounts, + setStep, + setWorkspace, + setMigratingWorkspace, + setMigrationPhase, - quotaCharacteristics, - }; -})(observer(SelectUsersStep)); + quotaCharacteristics, + + cancelUploadDialogVisible, + setCancelUploadDialogVisible, + }; + }, +)(observer(SelectUsersStep)); diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/components/SelectUsersTypeStep/index.tsx b/packages/client/src/pages/PortalSettings/categories/data-import/components/SelectUsersTypeStep/index.tsx index f56fde3aa3..510352cb8c 100644 --- a/packages/client/src/pages/PortalSettings/categories/data-import/components/SelectUsersTypeStep/index.tsx +++ b/packages/client/src/pages/PortalSettings/categories/data-import/components/SelectUsersTypeStep/index.tsx @@ -27,7 +27,6 @@ import { useState, useEffect } from "react"; import { inject, observer } from "mobx-react"; -import { SaveCancelButtons } from "@docspace/shared/components/save-cancel-buttons"; import { SearchInput } from "@docspace/shared/components/search-input"; import { InputSize } from "@docspace/shared/components/text-input"; import AccountsTable from "./AccountsTable"; @@ -35,6 +34,8 @@ import AccountsPaging from "../../sub-components/AccountsPaging"; import { Wrapper } from "../../StyledDataImport"; import { InjectedTypeSelectProps, TypeSelectProps } from "../../types"; +import { MigrationButtons } from "../../sub-components/MigrationButtons"; +import { CancelUploadDialog } from "SRC_DIR/components/dialogs"; const PAGE_SIZE = 25; const REFRESH_TIMEOUT = 100; @@ -49,6 +50,15 @@ const SelectUsersTypeStep = (props: TypeSelectProps) => { searchValue, setSearchValue, filteredUsers, + cancelMigration, + clearCheckedAccounts, + setStep, + setWorkspace, + setMigratingWorkspace, + setMigrationPhase, + + cancelUploadDialogVisible, + setCancelUploadDialogVisible, } = props as InjectedTypeSelectProps; const [boundaries, setBoundaries] = useState([0, PAGE_SIZE]); @@ -76,13 +86,25 @@ const SelectUsersTypeStep = (props: TypeSelectProps) => { data.email?.toLowerCase().startsWith(searchValue.toLowerCase()), ); + const onCancelMigration = () => { + cancelMigration(); + clearCheckedAccounts(); + setStep(1); + setWorkspace(""); + setMigratingWorkspace(""); + setMigrationPhase(""); + }; + + const showCancelDialog = () => setCancelUploadDialogVisible(true); + const hideCancelDialog = () => setCancelUploadDialogVisible(false); + useEffect(() => { setDataPortion(filteredUsers.slice(...boundaries)); }, [users]); return ( - { saveButtonLabel={t("Settings:NextStep")} cancelButtonLabel={t("Common:Back")} displaySettings + migrationCancelLabel={t("Settings:CancelImport")} + onMigrationCancelClick={showCancelDialog} /> {filteredUsers.length > 0 && ( @@ -117,7 +141,7 @@ const SelectUsersTypeStep = (props: TypeSelectProps) => { )} {filteredAccounts.length > 0 && ( - { saveButtonLabel={t("Settings:NextStep")} cancelButtonLabel={t("Common:Back")} displaySettings + migrationCancelLabel={t("Settings:CancelImport")} + onMigrationCancelClick={showCancelDialog} /> )} )} + + {cancelUploadDialogVisible && ( + + )} ); }; -export default inject(({ importAccountsStore }) => { +export default inject(({ importAccountsStore, dialogsStore }) => { const { users, incrementStep, @@ -141,7 +178,15 @@ export default inject(({ importAccountsStore }) => { searchValue, setSearchValue, filteredUsers, + cancelMigration, + clearCheckedAccounts, + setStep, + setWorkspace, + setMigratingWorkspace, + setMigrationPhase, } = importAccountsStore; + const { cancelUploadDialogVisible, setCancelUploadDialogVisible } = + dialogsStore; return { users, @@ -150,5 +195,14 @@ export default inject(({ importAccountsStore }) => { searchValue, setSearchValue, filteredUsers, + cancelMigration, + clearCheckedAccounts, + setStep, + setWorkspace, + setMigratingWorkspace, + setMigrationPhase, + + cancelUploadDialogVisible, + setCancelUploadDialogVisible, }; })(observer(SelectUsersTypeStep)); diff --git a/packages/client/src/pages/PortalSettings/categories/data-import/sub-components/MigrationButtons.tsx b/packages/client/src/pages/PortalSettings/categories/data-import/sub-components/MigrationButtons.tsx new file mode 100644 index 0000000000..fc27bcc9f7 --- /dev/null +++ b/packages/client/src/pages/PortalSettings/categories/data-import/sub-components/MigrationButtons.tsx @@ -0,0 +1,138 @@ +// (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 { SaveCancelButtons } from "@docspace/shared/components/save-cancel-buttons"; +import { mobile } from "@docspace/shared/utils/device"; + +import styled from "styled-components"; +import { MigrationButtonsProps } from "../types"; + +const MigrationButtonsWrapper = styled.div` + display: flex; + align-items: center; + gap: 12px; + + margin-bottom: 16px; + + @media ${mobile} { + margin-bottom: 0; + + width: 100%; + + position: fixed; + inset-inline: 0px; + bottom: 0px; + + padding-top: 18px; + + background: white; + + flex-direction: column-reverse; + align-items: flex-start; + gap: 0; + } + + .migration-buttons { + width: fit-content; + font-family: Open Sans; + font-size: 13px; + font-weight: 600; + line-height: 15px; + text-align: left; + + @media ${mobile} { + width: 100%; + position: relative; + padding: 0; + } + } +`; + +const CancelMigrationButton = styled.span` + font-family: Open Sans; + font-size: 13px; + font-weight: 600; + line-height: 15px; + + cursor: pointer; + + text-decoration-line: underline; + text-decoration-style: dashed; + padding: 0 16px; +`; + +export const MigrationButtons = ({ + id, + className, + reminderText, + saveButtonLabel = "Save", + cancelButtonLabel = "Cancel", + onCancelClick, + onSaveClick, + showReminder, + displaySettings, + disableRestoreToDefault, + hasScroll, + isSaving, + cancelEnable, + tabIndex, + hideBorder, + additionalClassSaveButton, + additionalClassCancelButton, + saveButtonDisabled, + getTopComponent, + migrationCancelLabel, + onMigrationCancelClick, +}: MigrationButtonsProps) => { + return ( + + + + {migrationCancelLabel} + + + ); +}; 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 44f76585b7..a3457f7ffc 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 @@ -33,6 +33,7 @@ import { import { TPaymentFeature } from "@docspace/shared/api/portal/types"; import { TOption } from "@docspace/shared/components/combobox"; +import { SaveCancelButtonProps } from "@docspace/shared/components/save-cancel-buttons/SaveCancelButton.types"; export type TFunciton = ReturnType["t"]; @@ -136,6 +137,14 @@ export interface InjectedSelectUsersStepProps extends SelectUsersStepProps { users: TStore["importAccountsStore"]["users"]; areCheckedUsersEmpty: TStore["importAccountsStore"]["areCheckedUsersEmpty"]; setResultUsers: TStore["importAccountsStore"]["setResultUsers"]; + clearCheckedAccounts: TStore["importAccountsStore"]["clearCheckedAccounts"]; + setStep: TStore["importAccountsStore"]["setStep"]; + setWorkspace: TStore["importAccountsStore"]["setWorkspace"]; + setMigratingWorkspace: TStore["importAccountsStore"]["setMigratingWorkspace"]; + setMigrationPhase: TStore["importAccountsStore"]["setMigrationPhase"]; + + cancelUploadDialogVisible: TStore["dialogsStore"]["cancelUploadDialogVisible"]; + setCancelUploadDialogVisible: TStore["dialogsStore"]["setCancelUploadDialogVisible"]; quotaCharacteristics: TStore["currentQuotaStore"]["quotaCharacteristics"]; } @@ -254,6 +263,15 @@ export interface InjectedAddEmailsStepProps extends AddEmailsStepProps { areCheckedUsersEmpty: TStore["importAccountsStore"]["areCheckedUsersEmpty"]; checkedUsers: TStore["importAccountsStore"]["checkedUsers"]; withEmailUsers: TStore["importAccountsStore"]["withEmailUsers"]; + cancelMigration: TStore["importAccountsStore"]["cancelMigration"]; + clearCheckedAccounts: TStore["importAccountsStore"]["clearCheckedAccounts"]; + setStep: TStore["importAccountsStore"]["setStep"]; + setWorkspace: TStore["importAccountsStore"]["setWorkspace"]; + setMigratingWorkspace: TStore["importAccountsStore"]["setMigratingWorkspace"]; + setMigrationPhase: TStore["importAccountsStore"]["setMigrationPhase"]; + + cancelUploadDialogVisible: TStore["dialogsStore"]["cancelUploadDialogVisible"]; + setCancelUploadDialogVisible: TStore["dialogsStore"]["setCancelUploadDialogVisible"]; quotaCharacteristics: TStore["currentQuotaStore"]["quotaCharacteristics"]; } @@ -303,6 +321,15 @@ export interface InjectedTypeSelectProps extends TypeSelectProps { searchValue: TStore["importAccountsStore"]["searchValue"]; setSearchValue: TStore["importAccountsStore"]["setSearchValue"]; filteredUsers: TStore["importAccountsStore"]["filteredUsers"]; + cancelMigration: TStore["importAccountsStore"]["cancelMigration"]; + clearCheckedAccounts: TStore["importAccountsStore"]["clearCheckedAccounts"]; + setStep: TStore["importAccountsStore"]["setStep"]; + setWorkspace: TStore["importAccountsStore"]["setWorkspace"]; + setMigratingWorkspace: TStore["importAccountsStore"]["setMigratingWorkspace"]; + setMigrationPhase: TStore["importAccountsStore"]["setMigrationPhase"]; + + cancelUploadDialogVisible: TStore["dialogsStore"]["cancelUploadDialogVisible"]; + setCancelUploadDialogVisible: TStore["dialogsStore"]["setCancelUploadDialogVisible"]; } export interface InjectedTypeSelectTableProps extends AccountsTableProps { @@ -470,3 +497,8 @@ export interface InjectedImportCompleteStepProps setMigratingWorkspace: TStore["importAccountsStore"]["setMigratingWorkspace"]; setMigrationPhase: TStore["importAccountsStore"]["setMigrationPhase"]; } + +export interface MigrationButtonsProps extends SaveCancelButtonProps { + migrationCancelLabel: string; + onMigrationCancelClick: () => void; +}