feat(client): Add ability for admins to edit user avatars (#1604)
This commit is contained in:
+24
-16
@@ -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 (
|
||||
<>
|
||||
<Popup.Header>
|
||||
<Popup.Header onBack={onBack}>
|
||||
{t('common.editAvatar', {
|
||||
context: 'title',
|
||||
})}
|
||||
@@ -67,7 +69,7 @@ const EditAvatarStep = React.memo(({ onClose }) => {
|
||||
/>
|
||||
</FilePicker>
|
||||
</div>
|
||||
{defaultValue && (
|
||||
{avatar && (
|
||||
<Button negative content={t('action.deleteAvatar')} onClick={handleDeleteClick} />
|
||||
)}
|
||||
</Popup.Content>
|
||||
@@ -75,8 +77,14 @@ const EditAvatarStep = React.memo(({ onClose }) => {
|
||||
);
|
||||
});
|
||||
|
||||
EditAvatarStep.propTypes = {
|
||||
EditUserAvatarStep.propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
onBack: PropTypes.func,
|
||||
onClose: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default EditAvatarStep;
|
||||
EditUserAvatarStep.defaultProps = {
|
||||
onBack: undefined,
|
||||
};
|
||||
|
||||
export default EditUserAvatarStep;
|
||||
+2
-2
@@ -3,6 +3,6 @@
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
import AccountPane from './AccountPane';
|
||||
import EditUserAvatarStep from './EditUserAvatarStep';
|
||||
|
||||
export default AccountPane;
|
||||
export default EditUserAvatarStep;
|
||||
+13
-13
@@ -8,16 +8,16 @@ import { useDispatch, useSelector } from 'react-redux';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Button, Divider, Dropdown, Header, Tab } from 'semantic-ui-react';
|
||||
|
||||
import selectors from '../../../../selectors';
|
||||
import entryActions from '../../../../entry-actions';
|
||||
import { usePopupInClosableContext } from '../../../../hooks';
|
||||
import locales from '../../../../locales';
|
||||
import EditAvatarStep from './EditAvatarStep';
|
||||
import EditUserInformation from '../../EditUserInformation';
|
||||
import EditUserUsernameStep from '../../EditUserUsernameStep';
|
||||
import EditUserEmailStep from '../../EditUserEmailStep';
|
||||
import EditUserPasswordStep from '../../EditUserPasswordStep';
|
||||
import UserAvatar from '../../UserAvatar';
|
||||
import selectors from '../../../selectors';
|
||||
import entryActions from '../../../entry-actions';
|
||||
import { usePopupInClosableContext } from '../../../hooks';
|
||||
import locales from '../../../locales';
|
||||
import EditUserInformation from '../EditUserInformation';
|
||||
import EditUserAvatarStep from '../EditUserAvatarStep';
|
||||
import EditUserUsernameStep from '../EditUserUsernameStep';
|
||||
import EditUserEmailStep from '../EditUserEmailStep';
|
||||
import EditUserPasswordStep from '../EditUserPasswordStep';
|
||||
import UserAvatar from '../UserAvatar';
|
||||
|
||||
import styles from './AccountPane.module.scss';
|
||||
|
||||
@@ -34,7 +34,7 @@ const AccountPane = React.memo(() => {
|
||||
[dispatch],
|
||||
);
|
||||
|
||||
const EditAvatarPopup = usePopupInClosableContext(EditAvatarStep);
|
||||
const EditUserAvatarPopup = usePopupInClosableContext(EditUserAvatarStep);
|
||||
const EditUserUsernamePopup = usePopupInClosableContext(EditUserUsernameStep);
|
||||
const EditUserEmailPopup = usePopupInClosableContext(EditUserEmailStep);
|
||||
const EditUserPasswordPopup = usePopupInClosableContext(EditUserPasswordStep);
|
||||
@@ -45,9 +45,9 @@ const AccountPane = React.memo(() => {
|
||||
|
||||
return (
|
||||
<Tab.Pane attached={false} className={styles.wrapper}>
|
||||
<EditAvatarPopup>
|
||||
<EditUserAvatarPopup id={user.id}>
|
||||
<UserAvatar id={user.id} size="massive" isDisabled={user.isAvatarUpdating} />
|
||||
</EditAvatarPopup>
|
||||
</EditUserAvatarPopup>
|
||||
<br />
|
||||
<br />
|
||||
<EditUserInformation id={user.id} />
|
||||
Reference in New Issue
Block a user