Web: Client: Data Import: add addEmail dialog
This commit is contained in:
parent
db00964816
commit
b01b9915ca
@ -10,6 +10,7 @@
|
||||
"AccountsWithoutEmails": "We found <1>{{users}} users</1> without emails. You can fill their emails or continue without this action.",
|
||||
"AccountsWithoutEmailsNextStep": "We found <1>{{users}} users</1> without emails. You can add necessary data to their accounts on the next step.",
|
||||
"AddAllowedIP": "Add allowed IP address",
|
||||
"AddEmail": "Add e-mail",
|
||||
"AddEmails": "Add emails to incomplete accounts",
|
||||
"AddEmailsDescription": "Check list of unimported users to import into {{organizationName}} {{productName}}.",
|
||||
"AddEmailsWarning": "You don't have users with emails. Please proceed to the next step to add them.",
|
||||
|
@ -0,0 +1,119 @@
|
||||
// (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 styled from "styled-components";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
import {
|
||||
ModalDialog,
|
||||
ModalDialogType,
|
||||
} from "@docspace/shared/components/modal-dialog";
|
||||
import { Button, ButtonSize } from "@docspace/shared/components/button";
|
||||
import { EmailInput } from "@docspace/shared/components/email-input";
|
||||
import { InputType } from "@docspace/shared/components/text-input";
|
||||
import { TValidate } from "@docspace/shared/components/email-input/EmailInput.types";
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
import ModalDialogContainer from "../ModalDialogContainer";
|
||||
|
||||
const DialogBodyWrapper = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
`;
|
||||
|
||||
interface EmailChangeDialogProps {
|
||||
visible: boolean;
|
||||
onClose: () => void;
|
||||
tempEmail: string;
|
||||
handleEmailChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
||||
onValidateEmail: (res: TValidate) => {
|
||||
isValid: boolean;
|
||||
errors: string[];
|
||||
};
|
||||
hasError: boolean;
|
||||
checkEmailValidity: () => void;
|
||||
handleSave: () => void;
|
||||
displayName: string;
|
||||
}
|
||||
|
||||
const EmailChangeDialog = ({
|
||||
visible,
|
||||
onClose,
|
||||
tempEmail,
|
||||
handleEmailChange,
|
||||
onValidateEmail,
|
||||
hasError,
|
||||
checkEmailValidity,
|
||||
handleSave,
|
||||
displayName,
|
||||
}: EmailChangeDialogProps) => {
|
||||
const { t } = useTranslation(["Settings", "SMTPSettings", "Common"]);
|
||||
|
||||
return (
|
||||
<ModalDialogContainer
|
||||
visible={visible}
|
||||
onClose={onClose}
|
||||
displayType={ModalDialogType.modal}
|
||||
>
|
||||
<ModalDialog.Header>{t("AddEmail")}</ModalDialog.Header>
|
||||
<ModalDialog.Body>
|
||||
<DialogBodyWrapper>
|
||||
<Text>{displayName}</Text>
|
||||
<EmailInput
|
||||
placeholder={t("SMTPSettings:EnterEmail")}
|
||||
className="import-email-input"
|
||||
value={tempEmail}
|
||||
onChange={handleEmailChange}
|
||||
type={InputType.email}
|
||||
onValidateInput={onValidateEmail}
|
||||
hasError={hasError}
|
||||
onBlur={checkEmailValidity}
|
||||
isAutoFocussed
|
||||
scale
|
||||
/>
|
||||
</DialogBodyWrapper>
|
||||
</ModalDialog.Body>
|
||||
<ModalDialog.Footer>
|
||||
<Button
|
||||
label={t("Common:SaveButton")}
|
||||
size={ButtonSize.normal}
|
||||
scale
|
||||
primary
|
||||
onClick={handleSave}
|
||||
isDisabled={hasError}
|
||||
/>
|
||||
<Button
|
||||
label={t("Common:CancelButton")}
|
||||
size={ButtonSize.normal}
|
||||
scale
|
||||
onClick={onClose}
|
||||
/>
|
||||
</ModalDialog.Footer>
|
||||
</ModalDialogContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default EmailChangeDialog;
|
@ -37,12 +37,15 @@ import { Button } from "@docspace/shared/components/button";
|
||||
import { TValidate } from "@docspace/shared/components/email-input/EmailInput.types";
|
||||
import { InputType } from "@docspace/shared/components/text-input";
|
||||
|
||||
import { isMobile } from "@docspace/shared/utils";
|
||||
|
||||
import EditSvg from "PUBLIC_DIR/images/access.edit.react.svg";
|
||||
import CrossSvg from "PUBLIC_DIR/images/cross.edit.react.svg";
|
||||
import CheckSvg from "PUBLIC_DIR/images/check.edit.react.svg";
|
||||
|
||||
import { Base } from "@docspace/shared/themes";
|
||||
|
||||
import EmailChangeDialog from "SRC_DIR/components/dialogs/EmailChangeDialog";
|
||||
import {
|
||||
AddEmailRowContentProps,
|
||||
InjectedAddEmailRowContentProps,
|
||||
@ -181,26 +184,40 @@ const UsersRowContent = (props: AddEmailRowContentProps) => {
|
||||
</Text>
|
||||
</div>
|
||||
{isEmailOpen ? (
|
||||
<EmailInputWrapper ref={emailInputRef}>
|
||||
<EmailInput
|
||||
placeholder={t("Settings:NoEmail")}
|
||||
className="import-email-input"
|
||||
value={tempEmail}
|
||||
onChange={handleEmailChange}
|
||||
type={InputType.email}
|
||||
onValidateInput={onValidateEmail}
|
||||
isMobile() ? (
|
||||
<EmailChangeDialog
|
||||
visible={isEmailOpen}
|
||||
onClose={clearEmail}
|
||||
tempEmail={tempEmail}
|
||||
handleEmailChange={handleEmailChange}
|
||||
onValidateEmail={onValidateEmail}
|
||||
hasError={hasError}
|
||||
onBlur={checkEmailValidity}
|
||||
isAutoFocussed
|
||||
checkEmailValidity={checkEmailValidity}
|
||||
handleSave={handleSaveClick}
|
||||
displayName={displayName}
|
||||
/>
|
||||
) : (
|
||||
<EmailInputWrapper ref={emailInputRef}>
|
||||
<EmailInput
|
||||
placeholder={t("SMTPSettings:EnterEmail")}
|
||||
className="import-email-input"
|
||||
value={tempEmail}
|
||||
onChange={handleEmailChange}
|
||||
type={InputType.email}
|
||||
onValidateInput={onValidateEmail}
|
||||
hasError={hasError}
|
||||
onBlur={checkEmailValidity}
|
||||
isAutoFocussed
|
||||
/>
|
||||
|
||||
<DecisionButton
|
||||
label=""
|
||||
icon={<CheckSvg />}
|
||||
onClick={handleSaveClick}
|
||||
/>
|
||||
<DecisionButton label="" icon={<CrossSvg />} onClick={clearEmail} />
|
||||
</EmailInputWrapper>
|
||||
<DecisionButton
|
||||
label=""
|
||||
icon={<CheckSvg />}
|
||||
onClick={handleSaveClick}
|
||||
/>
|
||||
<DecisionButton label="" icon={<CrossSvg />} onClick={clearEmail} />
|
||||
</EmailInputWrapper>
|
||||
)
|
||||
) : (
|
||||
<span onClick={openEmail} className="user-email" ref={emailTextRef}>
|
||||
<EditSvg />
|
||||
|
@ -31,6 +31,7 @@ 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";
|
||||
|
||||
@ -43,7 +44,6 @@ 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;
|
||||
@ -67,7 +67,7 @@ const AddEmailsStep = (props: AddEmailsStepProps) => {
|
||||
setWorkspace,
|
||||
setMigratingWorkspace,
|
||||
setMigrationPhase,
|
||||
|
||||
|
||||
cancelUploadDialogVisible,
|
||||
setCancelUploadDialogVisible,
|
||||
|
||||
@ -118,7 +118,7 @@ const AddEmailsStep = (props: AddEmailsStepProps) => {
|
||||
quota.used +
|
||||
checkedUsers.withEmail.filter((user) => !user.isDuplicate).length +
|
||||
checkedUsers.withoutEmail.length;
|
||||
|
||||
|
||||
const onCancelMigration = () => {
|
||||
cancelMigration();
|
||||
clearCheckedAccounts();
|
||||
@ -127,7 +127,7 @@ const AddEmailsStep = (props: AddEmailsStepProps) => {
|
||||
setMigratingWorkspace("");
|
||||
setMigrationPhase("");
|
||||
};
|
||||
|
||||
|
||||
const showCancelDialog = () => setCancelUploadDialogVisible(true);
|
||||
const hideCancelDialog = () => setCancelUploadDialogVisible(false);
|
||||
|
||||
@ -196,7 +196,7 @@ const AddEmailsStep = (props: AddEmailsStepProps) => {
|
||||
)}
|
||||
|
||||
{Buttons}
|
||||
|
||||
|
||||
{cancelUploadDialogVisible && (
|
||||
<CancelUploadDialog
|
||||
visible={cancelUploadDialogVisible}
|
||||
@ -211,50 +211,52 @@ const AddEmailsStep = (props: AddEmailsStepProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default inject<TStore>(({ importAccountsStore, currentQuotaStore, dialogsStore }) => {
|
||||
const {
|
||||
incrementStep,
|
||||
decrementStep,
|
||||
searchValue,
|
||||
setSearchValue,
|
||||
users,
|
||||
setResultUsers,
|
||||
areCheckedUsersEmpty,
|
||||
checkedUsers,
|
||||
withEmailUsers,
|
||||
export default inject<TStore>(
|
||||
({ importAccountsStore, currentQuotaStore, dialogsStore }) => {
|
||||
const {
|
||||
incrementStep,
|
||||
decrementStep,
|
||||
searchValue,
|
||||
setSearchValue,
|
||||
users,
|
||||
setResultUsers,
|
||||
areCheckedUsersEmpty,
|
||||
checkedUsers,
|
||||
withEmailUsers,
|
||||
|
||||
cancelMigration,
|
||||
clearCheckedAccounts,
|
||||
setStep,
|
||||
setWorkspace,
|
||||
setMigratingWorkspace,
|
||||
setMigrationPhase,
|
||||
} = importAccountsStore;
|
||||
const { quotaCharacteristics } = currentQuotaStore;
|
||||
cancelMigration,
|
||||
clearCheckedAccounts,
|
||||
setStep,
|
||||
setWorkspace,
|
||||
setMigratingWorkspace,
|
||||
setMigrationPhase,
|
||||
} = importAccountsStore;
|
||||
const { quotaCharacteristics } = currentQuotaStore;
|
||||
const { cancelUploadDialogVisible, setCancelUploadDialogVisible } =
|
||||
dialogsStore;
|
||||
|
||||
return {
|
||||
incrementStep,
|
||||
decrementStep,
|
||||
searchValue,
|
||||
setSearchValue,
|
||||
users,
|
||||
setResultUsers,
|
||||
areCheckedUsersEmpty,
|
||||
checkedUsers,
|
||||
withEmailUsers,
|
||||
return {
|
||||
incrementStep,
|
||||
decrementStep,
|
||||
searchValue,
|
||||
setSearchValue,
|
||||
users,
|
||||
setResultUsers,
|
||||
areCheckedUsersEmpty,
|
||||
checkedUsers,
|
||||
withEmailUsers,
|
||||
|
||||
cancelMigration,
|
||||
clearCheckedAccounts,
|
||||
setStep,
|
||||
setWorkspace,
|
||||
setMigratingWorkspace,
|
||||
setMigrationPhase,
|
||||
|
||||
quotaCharacteristics,
|
||||
|
||||
cancelUploadDialogVisible,
|
||||
setCancelUploadDialogVisible,
|
||||
};
|
||||
})(observer(AddEmailsStep));
|
||||
cancelMigration,
|
||||
clearCheckedAccounts,
|
||||
setStep,
|
||||
setWorkspace,
|
||||
setMigratingWorkspace,
|
||||
setMigrationPhase,
|
||||
|
||||
quotaCharacteristics,
|
||||
|
||||
cancelUploadDialogVisible,
|
||||
setCancelUploadDialogVisible,
|
||||
};
|
||||
},
|
||||
)(observer(AddEmailsStep));
|
||||
|
Loading…
Reference in New Issue
Block a user