Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
import { Box, Button, ButtonGroup, Icon, Modal } from '@rocket.chat/fuselage';
import React from 'react';
import { Box } from '@rocket.chat/fuselage';
import React, { FC } from 'react';

import { useTranslation } from '../contexts/TranslationContext';
import GenericModal from './GenericModal';
import RawText from './RawText';

const ConfirmOwnerChangeWarningModal = ({
type ConfirmOwnerChangeWarningModalProps = {
onConfirm: () => void;
onCancel: () => void;
shouldChangeOwner: Array<string>;
shouldBeRemoved: Array<string>;
contentTitle: string;
confirmLabel: string;
};

const ConfirmOwnerChangeWarningModal: FC<ConfirmOwnerChangeWarningModalProps> = ({
onConfirm,
onCancel,
contentTitle = '',
confirmLabel = '',
shouldChangeOwner,
shouldBeRemoved,
...props
}) => {
const t = useTranslation();

Expand Down Expand Up @@ -52,37 +61,26 @@ const ConfirmOwnerChangeWarningModal = ({
}

return (
<Modal {...props}>
<Modal.Header>
<Icon color='danger' name='modal-warning' size={20} />
<Modal.Title>{t('Are_you_sure')}</Modal.Title>
<Modal.Close onClick={onCancel} />
</Modal.Header>
<Modal.Content fontScale='p1'>
{contentTitle}
<GenericModal
variant='danger'
onClose={onCancel}
onCancel={onCancel}
confirmText={confirmLabel}
onConfirm={onConfirm}
>
{contentTitle}

{changeOwnerRooms && (
<Box marginBlock='x16'>
<RawText>{changeOwnerRooms}</RawText>
</Box>
)}
{removedRooms && (
<Box marginBlock='x16'>
<RawText>{removedRooms}</RawText>
</Box>
)}
</Modal.Content>
<Modal.Footer>
<ButtonGroup align='end'>
<Button ghost onClick={onCancel}>
{t('Cancel')}
</Button>
<Button primary danger onClick={onConfirm}>
{confirmLabel}
</Button>
</ButtonGroup>
</Modal.Footer>
</Modal>
{changeOwnerRooms && (
<Box marginBlock='x16'>
<RawText>{changeOwnerRooms}</RawText>
</Box>
)}
{removedRooms && (
<Box marginBlock='x16'>
<RawText>{removedRooms}</RawText>
</Box>
)}
</GenericModal>
);
};

Expand Down
67 changes: 35 additions & 32 deletions client/views/account/AccountProfilePage.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,62 +188,65 @@ const AccountProfilePage = () => {
setLoggingOut(false);
}, [logoutOtherClients, dispatchToastMessage, t]);

const handleConfirmOwnerChange = useCallback(
(passwordOrUsername, shouldChangeOwner, shouldBeRemoved) => {
const handleConfirm = async () => {
try {
await deleteOwnAccount(SHA256(passwordOrUsername), true);
dispatchToastMessage({ type: 'success', message: t('User_has_been_deleted') });
closeModal();
logout();
} catch (error) {
dispatchToastMessage({ type: 'error', message: error });
}
};

return setModal(() => (
<ConfirmOwnerChangeWarningModal
onConfirm={handleConfirm}
onCancel={closeModal}
contentTitle={t(`Delete_User_Warning_${erasureType}`)}
confirmLabel={t('Delete')}
shouldChangeOwner={shouldChangeOwner}
shouldBeRemoved={shouldBeRemoved}
/>
));
},
[closeModal, erasureType, setModal, t, deleteOwnAccount, dispatchToastMessage, logout],
);

const handleDeleteOwnAccount = useCallback(async () => {
const save = async (passwordOrUsername) => {
const handleConfirm = async (passwordOrUsername) => {
try {
await deleteOwnAccount(SHA256(passwordOrUsername));
dispatchToastMessage({ type: 'success', message: t('User_has_been_deleted') });
logout();
} catch (error) {
if (error.error === 'user-last-owner') {
const { shouldChangeOwner, shouldBeRemoved } = error.details;
return setModal(() => (
<ConfirmOwnerChangeWarningModal
onConfirm={() => {
deleteOwnAccount(SHA256(passwordOrUsername), true);
}}
onCancel={closeModal}
contentTitle={t(`Delete_User_Warning_${erasureType}`)}
confirmLabel={t('Continue')}
shouldChangeOwner={shouldChangeOwner}
shouldBeRemoved={shouldBeRemoved}
/>
));
return handleConfirmOwnerChange(passwordOrUsername, shouldChangeOwner, shouldBeRemoved);
}

dispatchToastMessage({ type: 'error', message: error });
}
};

const title = t('Are_you_sure_you_want_to_delete_your_account');
if (localPassword) {
return setModal(() => (
<ActionConfirmModal
onSave={save}
onCancel={closeModal}
title={title}
text={t('For_your_security_you_must_enter_your_current_password_to_continue')}
isPassword
/>
));
}
return setModal(() => (
<ActionConfirmModal
onSave={save}
onConfirm={handleConfirm}
onCancel={closeModal}
title={title}
text={t('If_you_are_sure_type_in_your_username')}
isPassword={localPassword}
/>
));
}, [
closeModal,
deleteOwnAccount,
dispatchToastMessage,
erasureType,
localPassword,
t,
logout,
setModal,
handleConfirmOwnerChange,
deleteOwnAccount,
logout,
t,
]);

return (
Expand Down
95 changes: 42 additions & 53 deletions client/views/account/ActionConfirmModal.tsx
Original file line number Diff line number Diff line change
@@ -1,72 +1,61 @@
import {
ButtonGroup,
Button,
Box,
Icon,
PasswordInput,
TextInput,
Modal,
FieldGroup,
Field,
} from '@rocket.chat/fuselage';
import { Box, PasswordInput, TextInput, FieldGroup, Field } from '@rocket.chat/fuselage';
import React, { useState, useCallback, FC } from 'react';

import GenericModal from '../../components/GenericModal';
import { useTranslation } from '../../contexts/TranslationContext';

type ActionConfirmModalProps = {
title: string;
text: string;
isPassword: boolean;
onSave: (input: string) => void;
onConfirm: (input: string) => void;
onCancel: () => void;
};

const ActionConfirmModal: FC<ActionConfirmModalProps> = ({
title,
text,
isPassword,
onSave,
onCancel,
...props
}) => {
const ActionConfirmModal: FC<ActionConfirmModalProps> = ({ isPassword, onConfirm, onCancel }) => {
const t = useTranslation();
const [inputText, setInputText] = useState('');
const [inputError, setInputError] = useState<string | undefined>();

const handleChange = useCallback(
(e) => {
e.target.value !== '' && setInputError(undefined);
setInputText(e.currentTarget.value);
},
[setInputText],
);

const handleChange = useCallback((e) => setInputText(e.currentTarget.value), [setInputText]);
const handleSave = useCallback(() => {
onSave(inputText);
if (inputText === '') {
setInputError(t('Invalid_field'));
return;
}
onConfirm(inputText);
onCancel();
}, [inputText, onSave, onCancel]);
}, [inputText, onConfirm, onCancel, t]);

return (
<Modal {...props}>
<Modal.Header>
<Icon color='danger' name='modal-warning' size={20} />
<Modal.Title>{title}</Modal.Title>
<Modal.Close onClick={onCancel} />
</Modal.Header>
<Modal.Content fontScale='p1'>
<Box mb='x8'>{text}</Box>
<FieldGroup w='full'>
<Field>
<Field.Row>
{isPassword && <PasswordInput value={inputText} onChange={handleChange} />}
{!isPassword && <TextInput value={inputText} onChange={handleChange} />}
</Field.Row>
</Field>
</FieldGroup>
</Modal.Content>
<Modal.Footer>
<ButtonGroup align='end'>
<Button ghost onClick={onCancel}>
{t('Cancel')}
</Button>
<Button primary danger onClick={handleSave}>
{t('Delete')}
</Button>
</ButtonGroup>
</Modal.Footer>
</Modal>
<GenericModal
onClose={onCancel}
onConfirm={handleSave}
onCancel={onCancel}
variant='danger'
title={t('Are_you_sure_you_want_to_delete_your_account')}
confirmText={t('Delete')}
>
<Box mb='x8'>
{isPassword
? t('For_your_security_you_must_enter_your_current_password_to_continue')
: t('If_you_are_sure_type_in_your_username')}
</Box>
<FieldGroup w='full'>
<Field>
<Field.Row>
{isPassword && <PasswordInput value={inputText} onChange={handleChange} />}
{!isPassword && <TextInput value={inputText} onChange={handleChange} />}
</Field.Row>
<Field.Error>{inputError}</Field.Error>
</Field>
</FieldGroup>
</GenericModal>
);
};

Expand Down
1 change: 1 addition & 0 deletions packages/rocketchat-i18n/i18n/en.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -2216,6 +2216,7 @@
"Invalid_Department": "Invalid Department",
"Invalid_email": "The email entered is invalid",
"Invalid_Export_File": "The file uploaded isn't a valid %s export file.",
"Invalid_field": "The field must not be empty",
"Invalid_Import_File_Type": "Invalid Import file type.",
"Invalid_name": "The name must not be empty",
"Invalid_notification_setting_s": "Invalid notification setting: %s",
Expand Down