1
0
Fork 0
mirror of https://github.com/plankanban/planka.git synced 2025-07-19 05:09:43 +02:00
planka/client/src/components/common/AdministrationModal/UsersPane/ActionsStep.jsx
Maksim Eltyshev 2ee1166747 feat: Version 2
Closes #627, closes #1047
2025-05-10 02:09:06 +02:00

250 lines
7.7 KiB
JavaScript

/*!
* Copyright (c) 2024 PLANKA Software GmbH
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
import React, { useCallback, useMemo } from 'react';
import PropTypes from 'prop-types';
import { useDispatch, useSelector } from 'react-redux';
import { useTranslation } from 'react-i18next';
import { Menu } from 'semantic-ui-react';
import { Popup } from '../../../../lib/custom-ui';
import selectors from '../../../../selectors';
import entryActions from '../../../../entry-actions';
import { useSteps } from '../../../../hooks';
import SelectRoleStep from './SelectRoleStep';
import ConfirmationStep from '../../ConfirmationStep';
import EditUserInformationStep from '../../../users/EditUserInformationStep';
import EditUserUsernameStep from '../../../users/EditUserUsernameStep';
import EditUserEmailStep from '../../../users/EditUserEmailStep';
import EditUserPasswordStep from '../../../users/EditUserPasswordStep';
import styles from './ActionsStep.module.scss';
const StepTypes = {
EDIT_INFORMATION: 'EDIT_INFORMATION',
EDIT_USERNAME: 'EDIT_USERNAME',
EDIT_EMAIL: 'EDIT_EMAIL',
EDIT_PASSWORD: 'EDIT_PASSWORD',
EDIT_ROLE: 'EDIT_ROLE',
ACTIVATE: 'ACTIVATE',
DEACTIVATE: 'DEACTIVATE',
DELETE: 'DELETE',
};
const ActionsStep = React.memo(({ userId, onClose }) => {
const selectUserById = useMemo(() => selectors.makeSelectUserById(), []);
const activeUsersLimit = useSelector(selectors.selectActiveUsersLimit);
const activeUsersTotal = useSelector(selectors.selectActiveUsersTotal);
const user = useSelector((state) => selectUserById(state, userId));
const dispatch = useDispatch();
const [t] = useTranslation();
const [step, openStep, handleBack] = useSteps();
const handleRoleSelect = useCallback(
(role) => {
dispatch(
entryActions.updateUser(userId, {
role,
}),
);
},
[userId, dispatch],
);
const handleActivateConfirm = useCallback(() => {
dispatch(
entryActions.updateUser(userId, {
isDeactivated: false,
}),
);
onClose();
}, [userId, onClose, dispatch]);
const handleDeactivateConfirm = useCallback(() => {
dispatch(
entryActions.updateUser(userId, {
isDeactivated: true,
}),
);
onClose();
}, [userId, onClose, dispatch]);
const handleDeleteConfirm = useCallback(() => {
dispatch(entryActions.deleteUser(userId));
}, [userId, dispatch]);
const handleEditInformationClick = useCallback(() => {
openStep(StepTypes.EDIT_INFORMATION);
}, [openStep]);
const handleEditUsernameClick = useCallback(() => {
openStep(StepTypes.EDIT_USERNAME);
}, [openStep]);
const handleEditEmailClick = useCallback(() => {
openStep(StepTypes.EDIT_EMAIL);
}, [openStep]);
const handleEditPasswordClick = useCallback(() => {
openStep(StepTypes.EDIT_PASSWORD);
}, [openStep]);
const handleEditRoleClick = useCallback(() => {
openStep(StepTypes.EDIT_ROLE);
}, [openStep]);
const handleActivateClick = useCallback(() => {
openStep(StepTypes.ACTIVATE);
}, [openStep]);
const handleDeactivateClick = useCallback(() => {
openStep(StepTypes.DEACTIVATE);
}, [openStep]);
const handleDeleteClick = useCallback(() => {
openStep(StepTypes.DELETE);
}, [openStep]);
if (step) {
switch (step.type) {
case StepTypes.EDIT_INFORMATION:
return <EditUserInformationStep id={userId} onBack={handleBack} onClose={onClose} />;
case StepTypes.EDIT_USERNAME:
return <EditUserUsernameStep id={userId} onBack={handleBack} onClose={onClose} />;
case StepTypes.EDIT_EMAIL:
return <EditUserEmailStep id={userId} onBack={handleBack} onClose={onClose} />;
case StepTypes.EDIT_PASSWORD:
return <EditUserPasswordStep id={userId} onBack={handleBack} onClose={onClose} />;
case StepTypes.EDIT_ROLE:
return (
<SelectRoleStep
withButton
defaultValue={user.role}
title="common.editRole"
buttonContent="action.save"
onSelect={handleRoleSelect}
onBack={handleBack}
onClose={onClose}
/>
);
case StepTypes.ACTIVATE:
return (
<ConfirmationStep
title="common.activateUser"
content="common.areYouSureYouWantToActivateThisUser"
buttonType="positive"
buttonContent="action.activateUser"
onConfirm={handleActivateConfirm}
onBack={handleBack}
/>
);
case StepTypes.DEACTIVATE:
return (
<ConfirmationStep
title="common.deactivateUser"
content="common.areYouSureYouWantToDeactivateThisUser"
buttonContent="action.deactivateUser"
onConfirm={handleDeactivateConfirm}
onBack={handleBack}
/>
);
case StepTypes.DELETE:
return (
<ConfirmationStep
title="common.deleteUser"
content="common.areYouSureYouWantToDeleteThisUser"
buttonContent="action.deleteUser"
typeValue={user.name}
typeContent="common.typeNameToConfirm"
onConfirm={handleDeleteConfirm}
onBack={handleBack}
/>
);
default:
}
}
return (
<>
<Popup.Header>
{t('common.userActions', {
context: 'title',
})}
</Popup.Header>
<Popup.Content>
<Menu secondary vertical className={styles.menu}>
<Menu.Item className={styles.menuItem} onClick={handleEditInformationClick}>
{t('action.editInformation', {
context: 'title',
})}
</Menu.Item>
{!user.lockedFieldNames.includes('username') && (
<Menu.Item className={styles.menuItem} onClick={handleEditUsernameClick}>
{t('action.editUsername', {
context: 'title',
})}
</Menu.Item>
)}
{!user.lockedFieldNames.includes('email') && (
<Menu.Item className={styles.menuItem} onClick={handleEditEmailClick}>
{t('action.editEmail', {
context: 'title',
})}
</Menu.Item>
)}
{!user.lockedFieldNames.includes('password') && (
<Menu.Item className={styles.menuItem} onClick={handleEditPasswordClick}>
{t('action.editPassword', {
context: 'title',
})}
</Menu.Item>
)}
{!user.lockedFieldNames.includes('role') && (
<Menu.Item className={styles.menuItem} onClick={handleEditRoleClick}>
{t('action.editRole', {
context: 'title',
})}
</Menu.Item>
)}
<Menu.Item
disabled={
user.isDeactivated &&
activeUsersLimit !== null &&
activeUsersTotal >= activeUsersLimit
}
className={styles.menuItem}
onClick={user.isDeactivated ? handleActivateClick : handleDeactivateClick}
>
{user.isDeactivated
? t('action.activateUser', {
context: 'title',
})
: t('action.deactivateUser', {
context: 'title',
})}
</Menu.Item>
{user.isDeactivated && !user.isDefaultAdmin && (
<Menu.Item className={styles.menuItem} onClick={handleDeleteClick}>
{t('action.deleteUser', {
context: 'title',
})}
</Menu.Item>
)}
</Menu>
</Popup.Content>
</>
);
});
ActionsStep.propTypes = {
userId: PropTypes.string.isRequired,
onClose: PropTypes.func.isRequired,
};
export default ActionsStep;