Moderators: conditional display of features

merge-requests/609/head
Alex Gleason 3 years ago
parent 0fbc3f3d99
commit 96af79ad90
No known key found for this signature in database
GPG Key ID: 7211D1F99744FBB7

@ -12,7 +12,7 @@ import IconButton from './icon_button';
import Icon from './icon'; import Icon from './icon';
import DisplayName from './display_name'; import DisplayName from './display_name';
import { closeSidebar } from '../actions/sidebar'; import { closeSidebar } from '../actions/sidebar';
import { isStaff } from '../utils/accounts'; import { isStaff, isAdmin } from '../utils/accounts';
import { makeGetAccount, makeGetOtherAccounts } from '../selectors'; import { makeGetAccount, makeGetOtherAccounts } from '../selectors';
import { logOut, switchAccount } from 'soapbox/actions/auth'; import { logOut, switchAccount } from 'soapbox/actions/auth';
import ThemeToggle from '../features/ui/components/theme_toggle_container'; import ThemeToggle from '../features/ui/components/theme_toggle_container';
@ -58,7 +58,6 @@ const makeMapStateToProps = () => {
sidebarOpen: state.get('sidebar').sidebarOpen, sidebarOpen: state.get('sidebar').sidebarOpen,
donateUrl: state.getIn(['patron', 'instance', 'url']), donateUrl: state.getIn(['patron', 'instance', 'url']),
hasCrypto: typeof soapbox.getIn(['cryptoAddresses', 0, 'ticker']) === 'string', hasCrypto: typeof soapbox.getIn(['cryptoAddresses', 0, 'ticker']) === 'string',
isStaff: isStaff(state.getIn(['accounts', me])),
otherAccounts: getOtherAccounts(state), otherAccounts: getOtherAccounts(state),
}; };
}; };
@ -92,13 +91,8 @@ class SidebarMenu extends ImmutablePureComponent {
otherAccounts: ImmutablePropTypes.list, otherAccounts: ImmutablePropTypes.list,
sidebarOpen: PropTypes.bool, sidebarOpen: PropTypes.bool,
onClose: PropTypes.func.isRequired, onClose: PropTypes.func.isRequired,
isStaff: PropTypes.bool.isRequired,
}; };
static defaultProps = {
isStaff: false,
}
state = { state = {
switcher: false, switcher: false,
} }
@ -153,7 +147,7 @@ class SidebarMenu extends ImmutablePureComponent {
} }
render() { render() {
const { sidebarOpen, intl, account, onClickLogOut, donateUrl, isStaff, otherAccounts, hasCrypto } = this.props; const { sidebarOpen, intl, account, onClickLogOut, donateUrl, otherAccounts, hasCrypto } = this.props;
const { switcher } = this.state; const { switcher } = this.state;
if (!account) return null; if (!account) return null;
const acct = account.get('acct'); const acct = account.get('acct');
@ -245,14 +239,14 @@ class SidebarMenu extends ImmutablePureComponent {
<Icon id='filter' /> <Icon id='filter' />
<span className='sidebar-menu-item__title'>{intl.formatMessage(messages.filters)}</span> <span className='sidebar-menu-item__title'>{intl.formatMessage(messages.filters)}</span>
</NavLink> </NavLink>
{ isStaff && <a className='sidebar-menu-item' href='/pleroma/admin' target='_blank' onClick={this.handleClose}> {isStaff(account) && <a className='sidebar-menu-item' href='/pleroma/admin' target='_blank' onClick={this.handleClose}>
<Icon id='shield' /> <Icon id='shield' />
<span className='sidebar-menu-item__title'>{intl.formatMessage(messages.admin_settings)}</span> <span className='sidebar-menu-item__title'>{intl.formatMessage(messages.admin_settings)}</span>
</a> } </a>}
{ isStaff && <NavLink className='sidebar-menu-item' to='/soapbox/config' onClick={this.handleClose}> {isAdmin(account) && <NavLink className='sidebar-menu-item' to='/soapbox/config' onClick={this.handleClose}>
<Icon id='cog' /> <Icon id='cog' />
<span className='sidebar-menu-item__title'>{intl.formatMessage(messages.soapbox_config)}</span> <span className='sidebar-menu-item__title'>{intl.formatMessage(messages.soapbox_config)}</span>
</NavLink> } </NavLink>}
<NavLink className='sidebar-menu-item' to='/settings/preferences' onClick={this.handleClose}> <NavLink className='sidebar-menu-item' to='/settings/preferences' onClick={this.handleClose}>
<Icon id='cog' /> <Icon id='cog' />
<span className='sidebar-menu-item__title'>{intl.formatMessage(messages.preferences)}</span> <span className='sidebar-menu-item__title'>{intl.formatMessage(messages.preferences)}</span>

@ -10,6 +10,7 @@ import { parseVersion } from 'soapbox/utils/features';
import sourceCode from 'soapbox/utils/code'; import sourceCode from 'soapbox/utils/code';
import { getSubscribersCsv, getUnsubscribersCsv, getCombinedCsv } from 'soapbox/actions/email_list'; import { getSubscribersCsv, getUnsubscribersCsv, getCombinedCsv } from 'soapbox/actions/email_list';
import { getFeatures } from 'soapbox/utils/features'; import { getFeatures } from 'soapbox/utils/features';
import { isAdmin } from 'soapbox/utils/accounts';
// https://stackoverflow.com/a/53230807 // https://stackoverflow.com/a/53230807
const download = (response, filename) => { const download = (response, filename) => {
@ -26,10 +27,15 @@ const messages = defineMessages({
heading: { id: 'column.admin.dashboard', defaultMessage: 'Dashboard' }, heading: { id: 'column.admin.dashboard', defaultMessage: 'Dashboard' },
}); });
const mapStateToProps = (state, props) => ({ const mapStateToProps = (state, props) => {
const me = state.get('me');
return {
instance: state.get('instance'), instance: state.get('instance'),
supportsEmailList: getFeatures(state.get('instance')).emailList, supportsEmailList: getFeatures(state.get('instance')).emailList,
}); account: state.getIn(['accounts', me]),
};
};
export default @connect(mapStateToProps) export default @connect(mapStateToProps)
@injectIntl @injectIntl
@ -39,6 +45,7 @@ class Dashboard extends ImmutablePureComponent {
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
instance: ImmutablePropTypes.map.isRequired, instance: ImmutablePropTypes.map.isRequired,
supportsEmailList: PropTypes.bool, supportsEmailList: PropTypes.bool,
account: ImmutablePropTypes.map,
}; };
handleSubscribersClick = e => { handleSubscribersClick = e => {
@ -63,12 +70,14 @@ class Dashboard extends ImmutablePureComponent {
} }
render() { render() {
const { intl, instance, supportsEmailList } = this.props; const { intl, instance, supportsEmailList, account } = this.props;
const v = parseVersion(instance.get('version')); const v = parseVersion(instance.get('version'));
const userCount = instance.getIn(['stats', 'user_count']); const userCount = instance.getIn(['stats', 'user_count']);
const mau = instance.getIn(['pleroma', 'stats', 'mau']); const mau = instance.getIn(['pleroma', 'stats', 'mau']);
const retention = (userCount && mau) ? Math.round(mau / userCount * 100) : null; const retention = (userCount && mau) ? Math.round(mau / userCount * 100) : null;
if (!account) return null;
return ( return (
<Column icon='tachometer' heading={intl.formatMessage(messages.heading)} backBtnSlim> <Column icon='tachometer' heading={intl.formatMessage(messages.heading)} backBtnSlim>
<div className='dashcounters'> <div className='dashcounters'>
@ -123,7 +132,7 @@ class Dashboard extends ImmutablePureComponent {
</div> </div>
</div> </div>
</div> </div>
<RegistrationModePicker /> {isAdmin(account) && <RegistrationModePicker />}
<div className='dashwidgets'> <div className='dashwidgets'>
<div className='dashwidget'> <div className='dashwidget'>
<h4><FormattedMessage id='admin.dashwidgets.software_header' defaultMessage='Software' /></h4> <h4><FormattedMessage id='admin.dashwidgets.software_header' defaultMessage='Software' /></h4>
@ -132,7 +141,7 @@ class Dashboard extends ImmutablePureComponent {
<li>{v.software} <span className='pull-right'>{v.version}</span></li> <li>{v.software} <span className='pull-right'>{v.version}</span></li>
</ul> </ul>
</div> </div>
{supportsEmailList && <div className='dashwidget'> {supportsEmailList && isAdmin(account) && <div className='dashwidget'>
<h4><FormattedMessage id='admin.dashwidgets.email_list_header' defaultMessage='Email list' /></h4> <h4><FormattedMessage id='admin.dashwidgets.email_list_header' defaultMessage='Email list' /></h4>
<ul> <ul>
<li><a href='#' onClick={this.handleSubscribersClick} target='_blank'>subscribers.csv</a></li> <li><a href='#' onClick={this.handleSubscribersClick} target='_blank'>subscribers.csv</a></li>

@ -6,7 +6,7 @@ import { Link } from 'react-router-dom';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { openModal } from '../../../actions/modal'; import { openModal } from '../../../actions/modal';
import { logOut } from 'soapbox/actions/auth'; import { logOut } from 'soapbox/actions/auth';
import { isStaff } from 'soapbox/utils/accounts'; import { isStaff, isAdmin } from 'soapbox/utils/accounts';
import sourceCode from 'soapbox/utils/code'; import sourceCode from 'soapbox/utils/code';
const mapStateToProps = state => { const mapStateToProps = state => {
@ -35,10 +35,8 @@ const LinkFooter = ({ onOpenHotkeys, account, onClickLogOut }) => (
<li><Link to='/filters'><FormattedMessage id='navigation_bar.filters' defaultMessage='Filters' /></Link></li> <li><Link to='/filters'><FormattedMessage id='navigation_bar.filters' defaultMessage='Filters' /></Link></li>
<li><Link to='/domain_blocks'><FormattedMessage id='navigation_bar.domain_blocks' defaultMessage='Domain blocks' /></Link></li> <li><Link to='/domain_blocks'><FormattedMessage id='navigation_bar.domain_blocks' defaultMessage='Domain blocks' /></Link></li>
<li><Link to='/follow_requests'><FormattedMessage id='navigation_bar.follow_requests' defaultMessage='Follow requests' /></Link></li> <li><Link to='/follow_requests'><FormattedMessage id='navigation_bar.follow_requests' defaultMessage='Follow requests' /></Link></li>
{isStaff(account) && <> {isStaff(account) && <li><a href='/pleroma/admin'><FormattedMessage id='navigation_bar.admin_settings' defaultMessage='AdminFE' /></a></li>}
<li><a href='/pleroma/admin'><FormattedMessage id='navigation_bar.admin_settings' defaultMessage='AdminFE' /></a></li> {isAdmin(account) && <li><Link to='/soapbox/config'><FormattedMessage id='navigation_bar.soapbox_config' defaultMessage='Soapbox config' /></Link></li>}
<li><Link to='/soapbox/config'><FormattedMessage id='navigation_bar.soapbox_config' defaultMessage='Soapbox config' /></Link></li>
</>}
<li><Link to='/settings/import'><FormattedMessage id='navigation_bar.import_data' defaultMessage='Import data' /></Link></li> <li><Link to='/settings/import'><FormattedMessage id='navigation_bar.import_data' defaultMessage='Import data' /></Link></li>
<li><a href='#' onClick={onOpenHotkeys}><FormattedMessage id='navigation_bar.keyboard_shortcuts' defaultMessage='Hotkeys' /></a></li> <li><a href='#' onClick={onOpenHotkeys}><FormattedMessage id='navigation_bar.keyboard_shortcuts' defaultMessage='Hotkeys' /></a></li>
</>} </>}

@ -38,7 +38,7 @@ import SidebarMenu from '../../components/sidebar_menu';
import { connectUserStream } from '../../actions/streaming'; import { connectUserStream } from '../../actions/streaming';
import { Redirect } from 'react-router-dom'; import { Redirect } from 'react-router-dom';
import Icon from 'soapbox/components/icon'; import Icon from 'soapbox/components/icon';
import { isStaff } from 'soapbox/utils/accounts'; import { isStaff, isAdmin } from 'soapbox/utils/accounts';
import ProfileHoverCard from 'soapbox/components/profile_hover_card'; import ProfileHoverCard from 'soapbox/components/profile_hover_card';
import { getAccessToken } from 'soapbox/utils/auth'; import { getAccessToken } from 'soapbox/utils/auth';
@ -429,6 +429,9 @@ class UI extends React.PureComponent {
if (isStaff(account)) { if (isStaff(account)) {
this.props.dispatch(fetchReports({ state: 'open' })); this.props.dispatch(fetchReports({ state: 'open' }));
this.props.dispatch(fetchUsers({ page: 1, filters: 'local,need_approval' })); this.props.dispatch(fetchUsers({ page: 1, filters: 'local,need_approval' }));
}
if (isAdmin(account)) {
this.props.dispatch(fetchConfig()); this.props.dispatch(fetchConfig());
} }

Loading…
Cancel
Save