Move StaffRolePicker into its own component
This commit is contained in:
parent
276e7d6cfc
commit
a5e5df35a5
2 changed files with 93 additions and 71 deletions
|
@ -1,31 +1,18 @@
|
||||||
import React, { useMemo } from 'react';
|
import React from 'react';
|
||||||
import { defineMessages, FormattedMessage, useIntl, MessageDescriptor } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import { setRole } from 'soapbox/actions/admin';
|
|
||||||
import snackbar from 'soapbox/actions/snackbar';
|
|
||||||
import Account from 'soapbox/components/account';
|
import Account from 'soapbox/components/account';
|
||||||
import List, { ListItem } from 'soapbox/components/list';
|
import List, { ListItem } from 'soapbox/components/list';
|
||||||
import MissingIndicator from 'soapbox/components/missing_indicator';
|
import MissingIndicator from 'soapbox/components/missing_indicator';
|
||||||
import { Button, HStack, Modal, Stack } from 'soapbox/components/ui';
|
import { Button, HStack, Modal, Stack } from 'soapbox/components/ui';
|
||||||
import { SelectDropdown } from 'soapbox/features/forms';
|
import { useAppSelector, useFeatures } from 'soapbox/hooks';
|
||||||
import { useAppDispatch, useAppSelector, useFeatures } from 'soapbox/hooks';
|
|
||||||
import { makeGetAccount } from 'soapbox/selectors';
|
import { makeGetAccount } from 'soapbox/selectors';
|
||||||
import { isLocal } from 'soapbox/utils/accounts';
|
import { isLocal } from 'soapbox/utils/accounts';
|
||||||
|
|
||||||
import type { Account as AccountEntity } from 'soapbox/types/entities';
|
import StaffRolePicker from './staff-role-picker';
|
||||||
|
|
||||||
const getAccount = makeGetAccount();
|
const getAccount = makeGetAccount();
|
||||||
|
|
||||||
const messages = defineMessages({
|
|
||||||
roleUser: { id: 'account_moderation_modal.roles.user', defaultMessage: 'User' },
|
|
||||||
roleModerator: { id: 'account_moderation_modal.roles.moderator', defaultMessage: 'Moderator' },
|
|
||||||
roleAdmin: { id: 'account_moderation_modal.roles.admin', defaultMessage: 'Admin' },
|
|
||||||
promotedToAdmin: { id: 'admin.users.actions.promote_to_admin_message', defaultMessage: '@{acct} was promoted to an admin' },
|
|
||||||
promotedToModerator: { id: 'admin.users.actions.promote_to_moderator_message', defaultMessage: '@{acct} was promoted to a moderator' },
|
|
||||||
demotedToModerator: { id: 'admin.users.actions.demote_to_moderator_message', defaultMessage: '@{acct} was demoted to a moderator' },
|
|
||||||
demotedToUser: { id: 'admin.users.actions.demote_to_user_message', defaultMessage: '@{acct} was demoted to a regular user' },
|
|
||||||
});
|
|
||||||
|
|
||||||
interface IAccountModerationModal {
|
interface IAccountModerationModal {
|
||||||
/** Action to close the modal. */
|
/** Action to close the modal. */
|
||||||
onClose: (type: string) => void,
|
onClose: (type: string) => void,
|
||||||
|
@ -33,34 +20,11 @@ interface IAccountModerationModal {
|
||||||
accountId: string,
|
accountId: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Staff role. */
|
|
||||||
type AccountRole = 'user' | 'moderator' | 'admin';
|
|
||||||
|
|
||||||
/** Get the highest staff role associated with the account. */
|
|
||||||
const getRole = (account: AccountEntity): AccountRole => {
|
|
||||||
if (account.admin) {
|
|
||||||
return 'admin';
|
|
||||||
} else if (account.moderator) {
|
|
||||||
return 'moderator';
|
|
||||||
} else {
|
|
||||||
return 'user';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Moderator actions against accounts. */
|
/** Moderator actions against accounts. */
|
||||||
const AccountModerationModal: React.FC<IAccountModerationModal> = ({ onClose, accountId }) => {
|
const AccountModerationModal: React.FC<IAccountModerationModal> = ({ onClose, accountId }) => {
|
||||||
const intl = useIntl();
|
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
|
|
||||||
const features = useFeatures();
|
const features = useFeatures();
|
||||||
const account = useAppSelector(state => getAccount(state, accountId));
|
const account = useAppSelector(state => getAccount(state, accountId));
|
||||||
|
|
||||||
const roles: Record<AccountRole, string> = useMemo(() => ({
|
|
||||||
user: intl.formatMessage(messages.roleUser),
|
|
||||||
moderator: intl.formatMessage(messages.roleModerator),
|
|
||||||
admin: intl.formatMessage(messages.roleAdmin),
|
|
||||||
}), []);
|
|
||||||
|
|
||||||
const handleClose = () => onClose('ACCOUNT_MODERATION');
|
const handleClose = () => onClose('ACCOUNT_MODERATION');
|
||||||
|
|
||||||
if (!account) {
|
if (!account) {
|
||||||
|
@ -75,32 +39,6 @@ const AccountModerationModal: React.FC<IAccountModerationModal> = ({ onClose, ac
|
||||||
window.open(`/pleroma/admin/#/users/${account.id}/`, '_blank');
|
window.open(`/pleroma/admin/#/users/${account.id}/`, '_blank');
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRoleChange: React.ChangeEventHandler<HTMLSelectElement> = (e) => {
|
|
||||||
const role = e.target.value as AccountRole;
|
|
||||||
|
|
||||||
dispatch(setRole(account.id, role))
|
|
||||||
.then(() => {
|
|
||||||
let message: MessageDescriptor | undefined;
|
|
||||||
|
|
||||||
if (role === 'admin') {
|
|
||||||
message = messages.promotedToAdmin;
|
|
||||||
} else if (role === 'moderator' && account.admin) {
|
|
||||||
message = messages.demotedToModerator;
|
|
||||||
} else if (role === 'moderator') {
|
|
||||||
message = messages.promotedToModerator;
|
|
||||||
} else if (role === 'user') {
|
|
||||||
message = messages.demotedToUser;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message) {
|
|
||||||
dispatch(snackbar.success(intl.formatMessage(message, { acct: account.acct })));
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(() => {});
|
|
||||||
};
|
|
||||||
|
|
||||||
const accountRole = getRole(account);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
title={<FormattedMessage id='account_moderation_modal.title' defaultMessage='Moderate @{acct}' values={{ acct: account.acct }} />}
|
title={<FormattedMessage id='account_moderation_modal.title' defaultMessage='Moderate @{acct}' values={{ acct: account.acct }} />}
|
||||||
|
@ -119,11 +57,9 @@ const AccountModerationModal: React.FC<IAccountModerationModal> = ({ onClose, ac
|
||||||
{isLocal(account) && (
|
{isLocal(account) && (
|
||||||
<List>
|
<List>
|
||||||
<ListItem label={<FormattedMessage id='account_moderation_modal.fields.account_role' defaultMessage='Staff level' />}>
|
<ListItem label={<FormattedMessage id='account_moderation_modal.fields.account_role' defaultMessage='Staff level' />}>
|
||||||
<SelectDropdown
|
<div className='w-auto'>
|
||||||
items={roles}
|
<StaffRolePicker account={account} />
|
||||||
defaultValue={accountRole}
|
</div>
|
||||||
onChange={handleRoleChange}
|
|
||||||
/>
|
|
||||||
</ListItem>
|
</ListItem>
|
||||||
</List>
|
</List>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
import React, { useMemo } from 'react';
|
||||||
|
import { defineMessages, MessageDescriptor, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
import { setRole } from 'soapbox/actions/admin';
|
||||||
|
import snackbar from 'soapbox/actions/snackbar';
|
||||||
|
import { SelectDropdown } from 'soapbox/features/forms';
|
||||||
|
import { useAppDispatch } from 'soapbox/hooks';
|
||||||
|
|
||||||
|
import type { Account as AccountEntity } from 'soapbox/types/entities';
|
||||||
|
|
||||||
|
/** Staff role. */
|
||||||
|
type AccountRole = 'user' | 'moderator' | 'admin';
|
||||||
|
|
||||||
|
/** Get the highest staff role associated with the account. */
|
||||||
|
const getRole = (account: AccountEntity): AccountRole => {
|
||||||
|
if (account.admin) {
|
||||||
|
return 'admin';
|
||||||
|
} else if (account.moderator) {
|
||||||
|
return 'moderator';
|
||||||
|
} else {
|
||||||
|
return 'user';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
roleUser: { id: 'account_moderation_modal.roles.user', defaultMessage: 'User' },
|
||||||
|
roleModerator: { id: 'account_moderation_modal.roles.moderator', defaultMessage: 'Moderator' },
|
||||||
|
roleAdmin: { id: 'account_moderation_modal.roles.admin', defaultMessage: 'Admin' },
|
||||||
|
promotedToAdmin: { id: 'admin.users.actions.promote_to_admin_message', defaultMessage: '@{acct} was promoted to an admin' },
|
||||||
|
promotedToModerator: { id: 'admin.users.actions.promote_to_moderator_message', defaultMessage: '@{acct} was promoted to a moderator' },
|
||||||
|
demotedToModerator: { id: 'admin.users.actions.demote_to_moderator_message', defaultMessage: '@{acct} was demoted to a moderator' },
|
||||||
|
demotedToUser: { id: 'admin.users.actions.demote_to_user_message', defaultMessage: '@{acct} was demoted to a regular user' },
|
||||||
|
});
|
||||||
|
|
||||||
|
interface IStaffRolePicker {
|
||||||
|
/** Account whose role to change. */
|
||||||
|
account: AccountEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Picker for setting the staff role of an account. */
|
||||||
|
const StaffRolePicker: React.FC<IStaffRolePicker> = ({ account }) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
|
const roles: Record<AccountRole, string> = useMemo(() => ({
|
||||||
|
user: intl.formatMessage(messages.roleUser),
|
||||||
|
moderator: intl.formatMessage(messages.roleModerator),
|
||||||
|
admin: intl.formatMessage(messages.roleAdmin),
|
||||||
|
}), []);
|
||||||
|
|
||||||
|
const handleRoleChange: React.ChangeEventHandler<HTMLSelectElement> = (e) => {
|
||||||
|
const role = e.target.value as AccountRole;
|
||||||
|
|
||||||
|
dispatch(setRole(account.id, role))
|
||||||
|
.then(() => {
|
||||||
|
let message: MessageDescriptor | undefined;
|
||||||
|
|
||||||
|
if (role === 'admin') {
|
||||||
|
message = messages.promotedToAdmin;
|
||||||
|
} else if (role === 'moderator' && account.admin) {
|
||||||
|
message = messages.demotedToModerator;
|
||||||
|
} else if (role === 'moderator') {
|
||||||
|
message = messages.promotedToModerator;
|
||||||
|
} else if (role === 'user') {
|
||||||
|
message = messages.demotedToUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message) {
|
||||||
|
dispatch(snackbar.success(intl.formatMessage(message, { acct: account.acct })));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {});
|
||||||
|
};
|
||||||
|
|
||||||
|
const accountRole = getRole(account);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SelectDropdown
|
||||||
|
items={roles}
|
||||||
|
defaultValue={accountRole}
|
||||||
|
onChange={handleRoleChange}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default StaffRolePicker;
|
Loading…
Reference in a new issue