Merge branch 'admin-permission-groups' into 'develop'
Allow promotion/demotion of users to staff roles Closes #687 See merge request soapbox-pub/soapbox-fe!611
This commit is contained in:
commit
e580084e9b
6 changed files with 224 additions and 23 deletions
|
@ -53,6 +53,16 @@ export const ADMIN_USERS_UNTAG_REQUEST = 'ADMIN_USERS_UNTAG_REQUEST';
|
||||||
export const ADMIN_USERS_UNTAG_SUCCESS = 'ADMIN_USERS_UNTAG_SUCCESS';
|
export const ADMIN_USERS_UNTAG_SUCCESS = 'ADMIN_USERS_UNTAG_SUCCESS';
|
||||||
export const ADMIN_USERS_UNTAG_FAIL = 'ADMIN_USERS_UNTAG_FAIL';
|
export const ADMIN_USERS_UNTAG_FAIL = 'ADMIN_USERS_UNTAG_FAIL';
|
||||||
|
|
||||||
|
export const ADMIN_ADD_PERMISSION_GROUP_REQUEST = 'ADMIN_ADD_PERMISSION_GROUP_REQUEST';
|
||||||
|
export const ADMIN_ADD_PERMISSION_GROUP_SUCCESS = 'ADMIN_ADD_PERMISSION_GROUP_SUCCESS';
|
||||||
|
export const ADMIN_ADD_PERMISSION_GROUP_FAIL = 'ADMIN_ADD_PERMISSION_GROUP_FAIL';
|
||||||
|
|
||||||
|
export const ADMIN_REMOVE_PERMISSION_GROUP_REQUEST = 'ADMIN_REMOVE_PERMISSION_GROUP_REQUEST';
|
||||||
|
export const ADMIN_REMOVE_PERMISSION_GROUP_SUCCESS = 'ADMIN_REMOVE_PERMISSION_GROUP_SUCCESS';
|
||||||
|
export const ADMIN_REMOVE_PERMISSION_GROUP_FAIL = 'ADMIN_REMOVE_PERMISSION_GROUP_FAIL';
|
||||||
|
|
||||||
|
const nicknamesFromIds = (getState, ids) => ids.map(id => getState().getIn(['accounts', id, 'acct']));
|
||||||
|
|
||||||
export function fetchConfig() {
|
export function fetchConfig() {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
dispatch({ type: ADMIN_CONFIG_FETCH_REQUEST });
|
dispatch({ type: ADMIN_CONFIG_FETCH_REQUEST });
|
||||||
|
@ -208,7 +218,7 @@ export function fetchModerationLog(params) {
|
||||||
|
|
||||||
export function tagUsers(accountIds, tags) {
|
export function tagUsers(accountIds, tags) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
const nicknames = accountIds.map(id => getState().getIn(['accounts', id, 'acct']));
|
const nicknames = nicknamesFromIds(getState, accountIds);
|
||||||
dispatch({ type: ADMIN_USERS_TAG_REQUEST, accountIds, tags });
|
dispatch({ type: ADMIN_USERS_TAG_REQUEST, accountIds, tags });
|
||||||
return api(getState)
|
return api(getState)
|
||||||
.put('/api/v1/pleroma/admin/users/tag', { nicknames, tags })
|
.put('/api/v1/pleroma/admin/users/tag', { nicknames, tags })
|
||||||
|
@ -222,7 +232,7 @@ export function tagUsers(accountIds, tags) {
|
||||||
|
|
||||||
export function untagUsers(accountIds, tags) {
|
export function untagUsers(accountIds, tags) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
const nicknames = accountIds.map(id => getState().getIn(['accounts', id, 'acct']));
|
const nicknames = nicknamesFromIds(getState, accountIds);
|
||||||
dispatch({ type: ADMIN_USERS_UNTAG_REQUEST, accountIds, tags });
|
dispatch({ type: ADMIN_USERS_UNTAG_REQUEST, accountIds, tags });
|
||||||
return api(getState)
|
return api(getState)
|
||||||
.delete('/api/v1/pleroma/admin/users/tag', { data: { nicknames, tags } })
|
.delete('/api/v1/pleroma/admin/users/tag', { data: { nicknames, tags } })
|
||||||
|
@ -233,3 +243,70 @@ export function untagUsers(accountIds, tags) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function verifyUser(accountId) {
|
||||||
|
return (dispatch, getState) => {
|
||||||
|
return dispatch(tagUsers([accountId], ['verified']));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function unverifyUser(accountId) {
|
||||||
|
return (dispatch, getState) => {
|
||||||
|
return dispatch(untagUsers([accountId], ['verified']));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function addPermission(accountIds, permissionGroup) {
|
||||||
|
return (dispatch, getState) => {
|
||||||
|
const nicknames = nicknamesFromIds(getState, accountIds);
|
||||||
|
dispatch({ type: ADMIN_ADD_PERMISSION_GROUP_REQUEST, accountIds, permissionGroup });
|
||||||
|
return api(getState)
|
||||||
|
.post(`/api/v1/pleroma/admin/users/permission_group/${permissionGroup}`, { nicknames })
|
||||||
|
.then(({ data }) => {
|
||||||
|
dispatch({ type: ADMIN_ADD_PERMISSION_GROUP_SUCCESS, accountIds, permissionGroup, data });
|
||||||
|
}).catch(error => {
|
||||||
|
dispatch({ type: ADMIN_ADD_PERMISSION_GROUP_FAIL, error, accountIds, permissionGroup });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function removePermission(accountIds, permissionGroup) {
|
||||||
|
return (dispatch, getState) => {
|
||||||
|
const nicknames = nicknamesFromIds(getState, accountIds);
|
||||||
|
dispatch({ type: ADMIN_REMOVE_PERMISSION_GROUP_REQUEST, accountIds, permissionGroup });
|
||||||
|
return api(getState)
|
||||||
|
.delete(`/api/v1/pleroma/admin/users/permission_group/${permissionGroup}`, { data: { nicknames } })
|
||||||
|
.then(({ data }) => {
|
||||||
|
dispatch({ type: ADMIN_REMOVE_PERMISSION_GROUP_SUCCESS, accountIds, permissionGroup, data });
|
||||||
|
}).catch(error => {
|
||||||
|
dispatch({ type: ADMIN_REMOVE_PERMISSION_GROUP_FAIL, error, accountIds, permissionGroup });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function promoteToAdmin(accountId) {
|
||||||
|
return (dispatch, getState) => {
|
||||||
|
return Promise.all([
|
||||||
|
dispatch(addPermission([accountId], 'admin')),
|
||||||
|
dispatch(removePermission([accountId], 'moderator')),
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function promoteToModerator(accountId) {
|
||||||
|
return (dispatch, getState) => {
|
||||||
|
return Promise.all([
|
||||||
|
dispatch(removePermission([accountId], 'admin')),
|
||||||
|
dispatch(addPermission([accountId], 'moderator')),
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function demoteToUser(accountId) {
|
||||||
|
return (dispatch, getState) => {
|
||||||
|
return Promise.all([
|
||||||
|
dispatch(removePermission([accountId], 'admin')),
|
||||||
|
dispatch(removePermission([accountId], 'moderator')),
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -8,7 +8,13 @@ import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||||
import Icon from 'soapbox/components/icon';
|
import Icon from 'soapbox/components/icon';
|
||||||
import Button from 'soapbox/components/button';
|
import Button from 'soapbox/components/button';
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
import { isStaff } from 'soapbox/utils/accounts';
|
import {
|
||||||
|
isStaff,
|
||||||
|
isAdmin,
|
||||||
|
isModerator,
|
||||||
|
isVerified,
|
||||||
|
isLocal,
|
||||||
|
} from 'soapbox/utils/accounts';
|
||||||
import { parseVersion } from 'soapbox/utils/features';
|
import { parseVersion } from 'soapbox/utils/features';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import Avatar from 'soapbox/components/avatar';
|
import Avatar from 'soapbox/components/avatar';
|
||||||
|
@ -20,7 +26,6 @@ import { debounce } from 'lodash';
|
||||||
import StillImage from 'soapbox/components/still_image';
|
import StillImage from 'soapbox/components/still_image';
|
||||||
import ActionButton from 'soapbox/features/ui/components/action_button';
|
import ActionButton from 'soapbox/features/ui/components/action_button';
|
||||||
import SubscriptionButton from 'soapbox/features/ui/components/subscription_button';
|
import SubscriptionButton from 'soapbox/features/ui/components/subscription_button';
|
||||||
import { isVerified } from 'soapbox/utils/accounts';
|
|
||||||
import { openModal } from 'soapbox/actions/modal';
|
import { openModal } from 'soapbox/actions/modal';
|
||||||
import { List as ImmutableList, Map as ImmutableMap } from 'immutable';
|
import { List as ImmutableList, Map as ImmutableMap } from 'immutable';
|
||||||
|
|
||||||
|
@ -54,15 +59,21 @@ const messages = defineMessages({
|
||||||
deleteUser: { id: 'admin.users.actions.delete_user', defaultMessage: 'Delete @{name}' },
|
deleteUser: { id: 'admin.users.actions.delete_user', defaultMessage: 'Delete @{name}' },
|
||||||
verifyUser: { id: 'admin.users.actions.verify_user', defaultMessage: 'Verify @{name}' },
|
verifyUser: { id: 'admin.users.actions.verify_user', defaultMessage: 'Verify @{name}' },
|
||||||
unverifyUser: { id: 'admin.users.actions.unverify_user', defaultMessage: 'Unverify @{name}' },
|
unverifyUser: { id: 'admin.users.actions.unverify_user', defaultMessage: 'Unverify @{name}' },
|
||||||
|
promoteToAdmin: { id: 'admin.users.actions.promote_to_admin', defaultMessage: 'Promote @{name} to an admin' },
|
||||||
|
promoteToModerator: { id: 'admin.users.actions.promote_to_moderator', defaultMessage: 'Promote @{name} to a moderator' },
|
||||||
|
demoteToModerator: { id: 'admin.users.actions.demote_to_moderator', defaultMessage: 'Demote @{name} to a moderator' },
|
||||||
|
demoteToUser: { id: 'admin.users.actions.demote_to_user', defaultMessage: 'Demote @{name} to a regular user' },
|
||||||
subscribe: { id: 'account.subscribe', defaultMessage: 'Subscribe to notifications from @{name}' },
|
subscribe: { id: 'account.subscribe', defaultMessage: 'Subscribe to notifications from @{name}' },
|
||||||
unsubscribe: { id: 'account.unsubscribe', defaultMessage: 'Unsubscribe to notifications from @{name}' },
|
unsubscribe: { id: 'account.unsubscribe', defaultMessage: 'Unsubscribe to notifications from @{name}' },
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = state => {
|
||||||
const me = state.get('me');
|
const me = state.get('me');
|
||||||
|
const account = state.getIn(['accounts', me]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
me,
|
me,
|
||||||
isStaff: isStaff(state.getIn(['accounts', me])),
|
meAccount: account,
|
||||||
version: parseVersion(state.getIn(['instance', 'version'])),
|
version: parseVersion(state.getIn(['instance', 'version'])),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -73,17 +84,13 @@ class Header extends ImmutablePureComponent {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
account: ImmutablePropTypes.map,
|
account: ImmutablePropTypes.map,
|
||||||
|
meAccount: ImmutablePropTypes.map,
|
||||||
identity_props: ImmutablePropTypes.list,
|
identity_props: ImmutablePropTypes.list,
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
username: PropTypes.string,
|
username: PropTypes.string,
|
||||||
isStaff: PropTypes.bool.isRequired,
|
|
||||||
version: PropTypes.object,
|
version: PropTypes.object,
|
||||||
};
|
};
|
||||||
|
|
||||||
static defaultProps = {
|
|
||||||
isStaff: false,
|
|
||||||
}
|
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
isSmallScreen: (window.innerWidth <= 895),
|
isSmallScreen: (window.innerWidth <= 895),
|
||||||
}
|
}
|
||||||
|
@ -129,7 +136,7 @@ class Header extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
makeMenu() {
|
makeMenu() {
|
||||||
const { account, intl, me, isStaff, version } = this.props;
|
const { account, intl, me, meAccount, version } = this.props;
|
||||||
|
|
||||||
let menu = [];
|
let menu = [];
|
||||||
|
|
||||||
|
@ -200,9 +207,25 @@ class Header extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isStaff) {
|
if (isStaff(meAccount)) {
|
||||||
menu.push(null);
|
menu.push(null);
|
||||||
menu.push({ text: intl.formatMessage(messages.admin_account, { name: account.get('username') }), href: `/pleroma/admin/#/users/${account.get('id')}/`, newTab: true });
|
|
||||||
|
if (isAdmin(meAccount)) {
|
||||||
|
menu.push({ text: intl.formatMessage(messages.admin_account, { name: account.get('username') }), href: `/pleroma/admin/#/users/${account.get('id')}/`, newTab: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (account.get('id') !== me && isLocal(account)) {
|
||||||
|
if (isAdmin(account)) {
|
||||||
|
menu.push({ text: intl.formatMessage(messages.demoteToModerator, { name: account.get('username') }), action: this.props.onPromoteToModerator });
|
||||||
|
menu.push({ text: intl.formatMessage(messages.demoteToUser, { name: account.get('username') }), action: this.props.onDemoteToUser });
|
||||||
|
} else if (isModerator(account)) {
|
||||||
|
menu.push({ text: intl.formatMessage(messages.promoteToAdmin, { name: account.get('username') }), action: this.props.onPromoteToAdmin });
|
||||||
|
menu.push({ text: intl.formatMessage(messages.demoteToUser, { name: account.get('username') }), action: this.props.onDemoteToUser });
|
||||||
|
} else {
|
||||||
|
menu.push({ text: intl.formatMessage(messages.promoteToAdmin, { name: account.get('username') }), action: this.props.onPromoteToAdmin });
|
||||||
|
menu.push({ text: intl.formatMessage(messages.promoteToModerator, { name: account.get('username') }), action: this.props.onPromoteToModerator });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (isVerified(account)) {
|
if (isVerified(account)) {
|
||||||
menu.push({ text: intl.formatMessage(messages.unverifyUser, { name: account.get('username') }), action: this.props.onUnverifyUser });
|
menu.push({ text: intl.formatMessage(messages.unverifyUser, { name: account.get('username') }), action: this.props.onUnverifyUser });
|
||||||
|
|
|
@ -104,6 +104,18 @@ export default class Header extends ImmutablePureComponent {
|
||||||
this.props.onUnverifyUser(this.props.account);
|
this.props.onUnverifyUser(this.props.account);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handlePromoteToAdmin = () => {
|
||||||
|
this.props.onPromoteToAdmin(this.props.account);
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePromoteToModerator = () => {
|
||||||
|
this.props.onPromoteToModerator(this.props.account);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleDemoteToUser = () => {
|
||||||
|
this.props.onDemoteToUser(this.props.account);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { account, identity_proofs } = this.props;
|
const { account, identity_proofs } = this.props;
|
||||||
const moved = (account) ? account.get('moved') : false;
|
const moved = (account) ? account.get('moved') : false;
|
||||||
|
@ -132,6 +144,9 @@ export default class Header extends ImmutablePureComponent {
|
||||||
onDeleteUser={this.handleDeleteUser}
|
onDeleteUser={this.handleDeleteUser}
|
||||||
onVerifyUser={this.handleVerifyUser}
|
onVerifyUser={this.handleVerifyUser}
|
||||||
onUnverifyUser={this.handleUnverifyUser}
|
onUnverifyUser={this.handleUnverifyUser}
|
||||||
|
onPromoteToAdmin={this.handlePromoteToAdmin}
|
||||||
|
onPromoteToModerator={this.handlePromoteToModerator}
|
||||||
|
onDemoteToUser={this.handleDemoteToUser}
|
||||||
username={this.props.username}
|
username={this.props.username}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -12,7 +12,6 @@ import {
|
||||||
// unpinAccount,
|
// unpinAccount,
|
||||||
subscribeAccount,
|
subscribeAccount,
|
||||||
unsubscribeAccount,
|
unsubscribeAccount,
|
||||||
|
|
||||||
} from '../../../actions/accounts';
|
} from '../../../actions/accounts';
|
||||||
import {
|
import {
|
||||||
mentionCompose,
|
mentionCompose,
|
||||||
|
@ -27,7 +26,14 @@ import { List as ImmutableList } from 'immutable';
|
||||||
import { getSettings } from 'soapbox/actions/settings';
|
import { getSettings } from 'soapbox/actions/settings';
|
||||||
import { startChat, openChat } from 'soapbox/actions/chats';
|
import { startChat, openChat } from 'soapbox/actions/chats';
|
||||||
import { deactivateUserModal, deleteUserModal } from 'soapbox/actions/moderation';
|
import { deactivateUserModal, deleteUserModal } from 'soapbox/actions/moderation';
|
||||||
import { tagUsers, untagUsers } from 'soapbox/actions/admin';
|
import {
|
||||||
|
verifyUser,
|
||||||
|
unverifyUser,
|
||||||
|
promoteToAdmin,
|
||||||
|
promoteToModerator,
|
||||||
|
demoteToUser,
|
||||||
|
} from 'soapbox/actions/admin';
|
||||||
|
import { isAdmin } from 'soapbox/utils/accounts';
|
||||||
import snackbar from 'soapbox/actions/snackbar';
|
import snackbar from 'soapbox/actions/snackbar';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
|
@ -37,6 +43,11 @@ const messages = defineMessages({
|
||||||
blockAndReport: { id: 'confirmations.block.block_and_report', defaultMessage: 'Block & Report' },
|
blockAndReport: { id: 'confirmations.block.block_and_report', defaultMessage: 'Block & Report' },
|
||||||
userVerified: { id: 'admin.users.user_verified_message', defaultMessage: '@{acct} was verified' },
|
userVerified: { id: 'admin.users.user_verified_message', defaultMessage: '@{acct} was verified' },
|
||||||
userUnverified: { id: 'admin.users.user_unverified_message', defaultMessage: '@{acct} was unverified' },
|
userUnverified: { id: 'admin.users.user_unverified_message', defaultMessage: '@{acct} was unverified' },
|
||||||
|
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' },
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const isMobile = width => width <= 1190;
|
const isMobile = width => width <= 1190;
|
||||||
|
@ -173,16 +184,43 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
|
||||||
|
|
||||||
onVerifyUser(account) {
|
onVerifyUser(account) {
|
||||||
const message = intl.formatMessage(messages.userVerified, { acct: account.get('acct') });
|
const message = intl.formatMessage(messages.userVerified, { acct: account.get('acct') });
|
||||||
dispatch(tagUsers([account.get('id')], ['verified'])).then(() => {
|
|
||||||
dispatch(snackbar.success(message));
|
dispatch(verifyUser(account.get('id')))
|
||||||
}).catch(() => {});
|
.then(() => dispatch(snackbar.success(message)))
|
||||||
|
.catch(() => {});
|
||||||
},
|
},
|
||||||
|
|
||||||
onUnverifyUser(account) {
|
onUnverifyUser(account) {
|
||||||
const message = intl.formatMessage(messages.userUnverified, { acct: account.get('acct') });
|
const message = intl.formatMessage(messages.userUnverified, { acct: account.get('acct') });
|
||||||
dispatch(untagUsers([account.get('id')], ['verified'])).then(() => {
|
|
||||||
dispatch(snackbar.info(message));
|
dispatch(unverifyUser(account.get('id')))
|
||||||
}).catch(() => {});
|
.then(() => dispatch(snackbar.success(message)))
|
||||||
|
.catch(() => {});
|
||||||
|
},
|
||||||
|
|
||||||
|
onPromoteToAdmin(account) {
|
||||||
|
const message = intl.formatMessage(messages.promotedToAdmin, { acct: account.get('acct') });
|
||||||
|
|
||||||
|
dispatch(promoteToAdmin(account.get('id')))
|
||||||
|
.then(() => dispatch(snackbar.success(message)))
|
||||||
|
.catch(() => {});
|
||||||
|
},
|
||||||
|
|
||||||
|
onPromoteToModerator(account) {
|
||||||
|
const messageType = isAdmin(account) ? messages.demotedToModerator : messages.promotedToModerator;
|
||||||
|
const message = intl.formatMessage(messageType, { acct: account.get('acct') });
|
||||||
|
|
||||||
|
dispatch(promoteToModerator(account.get('id')))
|
||||||
|
.then(() => dispatch(snackbar.success(message)))
|
||||||
|
.catch(() => {});
|
||||||
|
},
|
||||||
|
|
||||||
|
onDemoteToUser(account) {
|
||||||
|
const message = intl.formatMessage(messages.demotedToUser, { acct: account.get('acct') });
|
||||||
|
|
||||||
|
dispatch(demoteToUser(account.get('id')))
|
||||||
|
.then(() => dispatch(snackbar.success(message)))
|
||||||
|
.catch(() => {});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,18 @@ class ProfileInfoPanel extends ImmutablePureComponent {
|
||||||
displayFqn: PropTypes.bool,
|
displayFqn: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
getStaffBadge = () => {
|
||||||
|
const { account } = this.props;
|
||||||
|
|
||||||
|
if (isAdmin(account)) {
|
||||||
|
return <Badge slug='admin' title='Admin' />;
|
||||||
|
} else if (isModerator(account)) {
|
||||||
|
return <Badge slug='moderator' title='Moderator' />;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { account, displayFqn, intl, identity_proofs, username } = this.props;
|
const { account, displayFqn, intl, identity_proofs, username } = this.props;
|
||||||
|
|
||||||
|
@ -86,8 +98,7 @@ class ProfileInfoPanel extends ImmutablePureComponent {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='profile-info-panel-content__badges'>
|
<div className='profile-info-panel-content__badges'>
|
||||||
{isAdmin(account) && <Badge slug='admin' title='Admin' />}
|
{this.getStaffBadge()}
|
||||||
{isModerator(account) && <Badge slug='moderator' title='Moderator' />}
|
|
||||||
{account.getIn(['patron', 'is_patron']) && <Badge slug='patron' title='Patron' />}
|
{account.getIn(['patron', 'is_patron']) && <Badge slug='patron' title='Patron' />}
|
||||||
{account.get('acct').includes('@') || <div className='profile-info-panel-content__badges__join-date'>
|
{account.get('acct').includes('@') || <div className='profile-info-panel-content__badges__join-date'>
|
||||||
<Icon id='calendar' />
|
<Icon id='calendar' />
|
||||||
|
|
|
@ -17,6 +17,10 @@ import {
|
||||||
ADMIN_USERS_TAG_FAIL,
|
ADMIN_USERS_TAG_FAIL,
|
||||||
ADMIN_USERS_UNTAG_REQUEST,
|
ADMIN_USERS_UNTAG_REQUEST,
|
||||||
ADMIN_USERS_UNTAG_FAIL,
|
ADMIN_USERS_UNTAG_FAIL,
|
||||||
|
ADMIN_ADD_PERMISSION_GROUP_REQUEST,
|
||||||
|
ADMIN_ADD_PERMISSION_GROUP_FAIL,
|
||||||
|
ADMIN_REMOVE_PERMISSION_GROUP_REQUEST,
|
||||||
|
ADMIN_REMOVE_PERMISSION_GROUP_FAIL,
|
||||||
} from 'soapbox/actions/admin';
|
} from 'soapbox/actions/admin';
|
||||||
import { ADMIN_USERS_DELETE_REQUEST } from 'soapbox/actions/admin';
|
import { ADMIN_USERS_DELETE_REQUEST } from 'soapbox/actions/admin';
|
||||||
|
|
||||||
|
@ -90,6 +94,33 @@ const setDeactivated = (state, nicknames) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const permissionGroupFields = {
|
||||||
|
admin: 'is_admin',
|
||||||
|
moderator: 'is_moderator',
|
||||||
|
};
|
||||||
|
|
||||||
|
const addPermission = (state, accountIds, permissionGroup) => {
|
||||||
|
const field = permissionGroupFields[permissionGroup];
|
||||||
|
if (!field) return state;
|
||||||
|
|
||||||
|
return state.withMutations(state => {
|
||||||
|
accountIds.forEach(id => {
|
||||||
|
state.setIn([id, 'pleroma', field], true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const removePermission = (state, accountIds, permissionGroup) => {
|
||||||
|
const field = permissionGroupFields[permissionGroup];
|
||||||
|
if (!field) return state;
|
||||||
|
|
||||||
|
return state.withMutations(state => {
|
||||||
|
accountIds.forEach(id => {
|
||||||
|
state.setIn([id, 'pleroma', field], false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
export default function accounts(state = initialState, action) {
|
export default function accounts(state = initialState, action) {
|
||||||
switch(action.type) {
|
switch(action.type) {
|
||||||
case ACCOUNT_IMPORT:
|
case ACCOUNT_IMPORT:
|
||||||
|
@ -111,6 +142,12 @@ export default function accounts(state = initialState, action) {
|
||||||
case ADMIN_USERS_UNTAG_REQUEST:
|
case ADMIN_USERS_UNTAG_REQUEST:
|
||||||
case ADMIN_USERS_TAG_FAIL:
|
case ADMIN_USERS_TAG_FAIL:
|
||||||
return removeTags(state, action.accountIds, action.tags);
|
return removeTags(state, action.accountIds, action.tags);
|
||||||
|
case ADMIN_ADD_PERMISSION_GROUP_REQUEST:
|
||||||
|
case ADMIN_REMOVE_PERMISSION_GROUP_FAIL:
|
||||||
|
return addPermission(state, action.accountIds, action.permissionGroup);
|
||||||
|
case ADMIN_REMOVE_PERMISSION_GROUP_REQUEST:
|
||||||
|
case ADMIN_ADD_PERMISSION_GROUP_FAIL:
|
||||||
|
return removePermission(state, action.accountIds, action.permissionGroup);
|
||||||
case ADMIN_USERS_DELETE_REQUEST:
|
case ADMIN_USERS_DELETE_REQUEST:
|
||||||
return setDeactivated(state, action.nicknames);
|
return setDeactivated(state, action.nicknames);
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in a new issue