diff --git a/client/src/components/common/AdministrationModal/UsersPane/ActionsStep.jsx b/client/src/components/common/AdministrationModal/UsersPane/ActionsStep.jsx index b5f224a2..9fbad0ed 100644 --- a/client/src/components/common/AdministrationModal/UsersPane/ActionsStep.jsx +++ b/client/src/components/common/AdministrationModal/UsersPane/ActionsStep.jsx @@ -17,6 +17,7 @@ import SelectRoleStep from './SelectRoleStep'; import ApiKeyStep from './ApiKeyStep'; import ConfirmationStep from '../../ConfirmationStep'; import EditUserInformationStep from '../../../users/EditUserInformationStep'; +import EditUserAvatarStep from '../../../users/EditUserAvatarStep'; import EditUserUsernameStep from '../../../users/EditUserUsernameStep'; import EditUserEmailStep from '../../../users/EditUserEmailStep'; import EditUserPasswordStep from '../../../users/EditUserPasswordStep'; @@ -25,6 +26,7 @@ import styles from './ActionsStep.module.scss'; const StepTypes = { EDIT_INFORMATION: 'EDIT_INFORMATION', + EDIT_AVATAR: 'EDIT_AVATAR', EDIT_USERNAME: 'EDIT_USERNAME', EDIT_EMAIL: 'EDIT_EMAIL', EDIT_PASSWORD: 'EDIT_PASSWORD', @@ -97,6 +99,10 @@ const ActionsStep = React.memo(({ userId, onClose }) => { openStep(StepTypes.EDIT_INFORMATION); }, [openStep]); + const handleEditAvatarClick = useCallback(() => { + openStep(StepTypes.EDIT_AVATAR); + }, [openStep]); + const handleEditUsernameClick = useCallback(() => { openStep(StepTypes.EDIT_USERNAME); }, [openStep]); @@ -137,6 +143,8 @@ const ActionsStep = React.memo(({ userId, onClose }) => { switch (step.type) { case StepTypes.EDIT_INFORMATION: return ; + case StepTypes.EDIT_AVATAR: + return ; case StepTypes.EDIT_USERNAME: return ; case StepTypes.EDIT_EMAIL: @@ -219,6 +227,12 @@ const ActionsStep = React.memo(({ userId, onClose }) => { context: 'title', })} + + + {t('action.editAvatar', { + context: 'title', + })} + {!user.lockedFieldNames.includes('username') && ( diff --git a/client/src/components/users/UserSettingsModal/AccountPane/EditAvatarStep.jsx b/client/src/components/users/EditUserAvatarStep/EditUserAvatarStep.jsx similarity index 59% rename from client/src/components/users/UserSettingsModal/AccountPane/EditAvatarStep.jsx rename to client/src/components/users/EditUserAvatarStep/EditUserAvatarStep.jsx index 2b89c2c4..3f816be7 100644 --- a/client/src/components/users/UserSettingsModal/AccountPane/EditAvatarStep.jsx +++ b/client/src/components/users/EditUserAvatarStep/EditUserAvatarStep.jsx @@ -3,20 +3,22 @@ * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ -import React, { useCallback, useEffect, useRef } from 'react'; +import React, { useCallback, useEffect, useMemo, useRef } from 'react'; import PropTypes from 'prop-types'; import { useDispatch, useSelector } from 'react-redux'; import { useTranslation } from 'react-i18next'; import { Button } from 'semantic-ui-react'; -import { FilePicker, Popup } from '../../../../lib/custom-ui'; +import { FilePicker, Popup } from '../../../lib/custom-ui'; -import selectors from '../../../../selectors'; -import entryActions from '../../../../entry-actions'; +import selectors from '../../../selectors'; +import entryActions from '../../../entry-actions'; -import styles from './EditAvatarStep.module.scss'; +import styles from './EditUserAvatarStep.module.scss'; -const EditAvatarStep = React.memo(({ onClose }) => { - const defaultValue = useSelector((state) => selectors.selectCurrentUser(state).avatar); +const EditUserAvatarStep = React.memo(({ id, onBack, onClose }) => { + const selectUserById = useMemo(() => selectors.makeSelectUserById(), []); + + const avatar = useSelector((state) => selectUserById(state, id).avatar); const dispatch = useDispatch(); const [t] = useTranslation(); @@ -26,33 +28,33 @@ const EditAvatarStep = React.memo(({ onClose }) => { const handleFileSelect = useCallback( (file) => { dispatch( - entryActions.updateCurrentUserAvatar({ + entryActions.updateUserAvatar(id, { file, }), ); onClose(); }, - [onClose, dispatch], + [dispatch, id, onClose], ); const handleDeleteClick = useCallback(() => { dispatch( - entryActions.updateCurrentUser({ + entryActions.updateUser(id, { avatar: null, }), ); onClose(); - }, [onClose, dispatch]); + }, [dispatch, id, onClose]); useEffect(() => { - fieldRef.current.focus(); + fieldRef.current?.focus?.(); }, []); return ( <> - + {t('common.editAvatar', { context: 'title', })} @@ -67,7 +69,7 @@ const EditAvatarStep = React.memo(({ onClose }) => { /> - {defaultValue && ( + {avatar && (