Admin: add registration mode picker

fix/tabs-bar-issues
Alex Gleason 2020-12-29 23:25:07 -06:00
rodzic bfd01d0316
commit b571765c33
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 7211D1F99744FBB7
7 zmienionych plików z 82 dodań i 31 usunięć

Wyświetl plik

@ -37,13 +37,13 @@ export function fetchConfig() {
}; };
} }
export function updateAdminConfig(params) { export function updateConfig(configs) {
return (dispatch, getState) => { return (dispatch, getState) => {
dispatch({ type: ADMIN_CONFIG_UPDATE_REQUEST }); dispatch({ type: ADMIN_CONFIG_UPDATE_REQUEST, configs });
return api(getState) return api(getState)
.post('/api/pleroma/admin/config', params) .post('/api/pleroma/admin/config', { configs })
.then(response => { .then(({ data: { configs } }) => {
dispatch({ type: ADMIN_CONFIG_UPDATE_SUCCESS, config: response.data }); dispatch({ type: ADMIN_CONFIG_UPDATE_SUCCESS, configs });
}).catch(error => { }).catch(error => {
dispatch({ type: ADMIN_CONFIG_UPDATE_FAIL, error }); dispatch({ type: ADMIN_CONFIG_UPDATE_FAIL, error });
}); });

Wyświetl plik

@ -37,18 +37,18 @@ class AdminNav extends React.PureComponent {
<IconWithCounter icon='gavel' count={reportsCount} fixedWidth /> <IconWithCounter icon='gavel' count={reportsCount} fixedWidth />
<FormattedMessage id='admin_nav.reports' defaultMessage='Reports' /> <FormattedMessage id='admin_nav.reports' defaultMessage='Reports' />
</a> </a>
{(instance.get('approval_required') || approvalCount > 0) && ( {((instance.get('registrations') && instance.get('approval_required')) || approvalCount > 0) && (
<NavLink className='promo-panel-item' to='/admin/approval'> <NavLink className='promo-panel-item' to='/admin/approval'>
<IconWithCounter icon='user' count={approvalCount} fixedWidth /> <IconWithCounter icon='user' count={approvalCount} fixedWidth />
<FormattedMessage id='admin_nav.awaiting_approval' defaultMessage='Awaiting Approval' /> <FormattedMessage id='admin_nav.awaiting_approval' defaultMessage='Awaiting Approval' />
</NavLink> </NavLink>
)} )}
{!instance.get('registrations') && ( {/* !instance.get('registrations') && (
{/* <NavLink className='promo-panel-item' to='#'> <NavLink className='promo-panel-item' to='#'>
<Icon id='envelope' className='promo-panel-item__icon' fixedWidth /> <Icon id='envelope' className='promo-panel-item__icon' fixedWidth />
<FormattedMessage id='admin_nav.invites' defaultMessage='Invites' /> <FormattedMessage id='admin_nav.invites' defaultMessage='Invites' />
</NavLink> */} </NavLink>
)} ) */}
{/* <NavLink className='promo-panel-item' to='#'> {/* <NavLink className='promo-panel-item' to='#'>
<Icon id='group' className='promo-panel-item__icon' fixedWidth /> <Icon id='group' className='promo-panel-item__icon' fixedWidth />
<FormattedMessage id='admin_nav.registration' defaultMessage='Registration' /> <FormattedMessage id='admin_nav.registration' defaultMessage='Registration' />

Wyświetl plik

@ -8,37 +8,67 @@ import {
RadioGroup, RadioGroup,
RadioItem, RadioItem,
} from 'soapbox/features/forms'; } from 'soapbox/features/forms';
import { updateConfig } from 'soapbox/actions/admin';
const mapStateToProps = (state, props) => ({ const mapStateToProps = (state, props) => ({
instance: state.get('instance'), mode: modeFromInstance(state.get('instance')),
openReportCount: state.getIn(['admin', 'open_report_count']), openReportCount: state.getIn(['admin', 'open_report_count']),
}); });
const generateConfig = mode => {
const configMap = {
open: [{ tuple: [':registrations_open', true] }, { tuple: [':account_approval_required', false] }],
approval: [{ tuple: [':registrations_open', true] }, { tuple: [':account_approval_required', true] }],
closed: [{ tuple: [':registrations_open', false] }],
};
return [{
group: ':pleroma',
key: ':instance',
value: configMap[mode],
}];
};
const modeFromInstance = instance => {
if (instance.get('approval_required') && instance.get('registrations')) return 'approval';
return instance.get('registrations') ? 'open' : 'closed';
};
export default @connect(mapStateToProps) export default @connect(mapStateToProps)
class RegistrationModePicker extends ImmutablePureComponent { class RegistrationModePicker extends ImmutablePureComponent {
onChange = e => {
const { dispatch } = this.props;
const config = generateConfig(e.target.value);
dispatch(updateConfig(config));
}
render() { render() {
const { mode } = this.props;
return ( return (
<SimpleForm> <SimpleForm>
<FieldsGroup> <FieldsGroup>
<RadioGroup <RadioGroup
label={<FormattedMessage id='admin.dashboard.registration_mode_label' defaultMessage='Registrations' />} label={<FormattedMessage id='admin.dashboard.registration_mode_label' defaultMessage='Registrations' />}
checked
onChange={this.onChange} onChange={this.onChange}
> >
<RadioItem <RadioItem
label={<FormattedMessage id='admin.dashboard.registration_mode.open_label' defaultMessage='Open' />} label={<FormattedMessage id='admin.dashboard.registration_mode.open_label' defaultMessage='Open' />}
hint={<FormattedMessage id='admin.dashboard.registration_mode.open_hint' defaultMessage='Anyone can join.' />} hint={<FormattedMessage id='admin.dashboard.registration_mode.open_hint' defaultMessage='Anyone can join.' />}
checked={mode === 'open'}
value='open' value='open'
/> />
<RadioItem <RadioItem
label={<FormattedMessage id='admin.dashboard.registration_mode.approval_label' defaultMessage='Approval Required' />} label={<FormattedMessage id='admin.dashboard.registration_mode.approval_label' defaultMessage='Approval Required' />}
hint={<FormattedMessage id='admin.dashboard.registration_mode.approval_hint' defaultMessage='Users can sign up, but their account only gets activated when an admin approves it.' />} hint={<FormattedMessage id='admin.dashboard.registration_mode.approval_hint' defaultMessage='Users can sign up, but their account only gets activated when an admin approves it.' />}
checked={mode === 'approval'}
value='approval' value='approval'
/> />
<RadioItem <RadioItem
label={<FormattedMessage id='admin.dashboard.registration_mode.closed_label' defaultMessage='Closed' />} label={<FormattedMessage id='admin.dashboard.registration_mode.closed_label' defaultMessage='Closed' />}
hint={<FormattedMessage id='admin.dashboard.registration_mode.closed_hint' defaultMessage='Nobody can sign up. You can still invite people.' />} hint={<FormattedMessage id='admin.dashboard.registration_mode.closed_hint' defaultMessage='Nobody can sign up. You can still invite people.' />}
checked={mode === 'closed'}
value='closed' value='closed'
/> />
</RadioGroup> </RadioGroup>

Wyświetl plik

@ -67,11 +67,11 @@ class Dashboard extends ImmutablePureComponent {
</div> </div>
<RegistrationModePicker /> <RegistrationModePicker />
<div className='dashwidgets'> <div className='dashwidgets'>
<div class='dashwidget'> <div className='dashwidget'>
<h4><FormattedMessage id='admin.dashwidgets.software_header' defaultMessage='Software' /></h4> <h4><FormattedMessage id='admin.dashwidgets.software_header' defaultMessage='Software' /></h4>
<ul> <ul>
<li>Soapbox FE <span class='pull-right'>1.1.0</span></li> <li>Soapbox FE <span className='pull-right'>1.1.0</span></li>
<li>{v.software} <span class='pull-right'>{v.version}</span></li> <li>{v.software} <span className='pull-right'>{v.version}</span></li>
</ul> </ul>
</div> </div>
</div> </div>

Wyświetl plik

@ -14,7 +14,7 @@ import {
FormPropTypes, FormPropTypes,
} from 'soapbox/features/forms'; } from 'soapbox/features/forms';
import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable'; import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable';
import { updateAdminConfig } from 'soapbox/actions/admin'; import { updateConfig } from 'soapbox/actions/admin';
import Icon from 'soapbox/components/icon'; import Icon from 'soapbox/components/icon';
import { defaultConfig } from 'soapbox/actions/soapbox'; import { defaultConfig } from 'soapbox/actions/soapbox';
import { uploadMedia } from 'soapbox/actions/media'; import { uploadMedia } from 'soapbox/actions/media';
@ -82,20 +82,18 @@ class SoapboxConfig extends ImmutablePureComponent {
getParams = () => { getParams = () => {
const { soapbox } = this.state; const { soapbox } = this.state;
return { return [{
configs: [{ group: ':pleroma',
group: ':pleroma', key: ':frontend_configurations',
key: ':frontend_configurations', value: [{
value: [{ tuple: [':soapbox_fe', soapbox.toJS()],
tuple: [':soapbox_fe', soapbox.toJS()],
}],
}], }],
}; }];
} }
handleSubmit = (event) => { handleSubmit = (event) => {
const { dispatch } = this.props; const { dispatch } = this.props;
dispatch(updateAdminConfig(this.getParams())).then(() => { dispatch(updateConfig(this.getParams())).then(() => {
this.setState({ isLoading: false }); this.setState({ isLoading: false });
}).catch((error) => { }).catch((error) => {
this.setState({ isLoading: false }); this.setState({ isLoading: false });

Wyświetl plik

@ -3,7 +3,9 @@ import {
NODEINFO_FETCH_SUCCESS, NODEINFO_FETCH_SUCCESS,
} from '../actions/instance'; } from '../actions/instance';
import { PRELOAD_IMPORT } from 'soapbox/actions/preload'; import { PRELOAD_IMPORT } from 'soapbox/actions/preload';
import { Map as ImmutableMap, fromJS } from 'immutable'; import { ADMIN_CONFIG_UPDATE_SUCCESS } from 'soapbox/actions/admin';
import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable';
import { ConfigDB } from 'soapbox/utils/config_db';
const nodeinfoToInstance = nodeinfo => { const nodeinfoToInstance = nodeinfo => {
// Match Pleroma's develop branch // Match Pleroma's develop branch
@ -37,6 +39,27 @@ const preloadImport = (state, action, path) => {
return data ? initialState.mergeDeep(fromJS(data)) : state; return data ? initialState.mergeDeep(fromJS(data)) : state;
}; };
const getConfigValue = (instanceConfig, key) => {
return instanceConfig
.find(value => value.getIn(['tuple', 0]) === key)
.getIn(['tuple', 1]);
};
const importConfigs = (state, configs) => {
// FIXME: This is pretty hacked together. Need to make a cleaner map.
const config = ConfigDB.find(configs, ':pleroma', ':instance');
if (!config) return state;
const value = config.get('value', ImmutableList());
return state.withMutations(state => {
const registrationsOpen = getConfigValue(value, ':registrations_open');
const approvalRequired = getConfigValue(value, ':account_approval_required');
state.update('registrations', c => typeof registrationsOpen === 'boolean' ? registrationsOpen : c);
state.update('approval_required', c => typeof approvalRequired === 'boolean' ? approvalRequired : c);
});
};
export default function instance(state = initialState, action) { export default function instance(state = initialState, action) {
switch(action.type) { switch(action.type) {
case PRELOAD_IMPORT: case PRELOAD_IMPORT:
@ -45,6 +68,8 @@ export default function instance(state = initialState, action) {
return initialState.mergeDeep(fromJS(action.instance)); return initialState.mergeDeep(fromJS(action.instance));
case NODEINFO_FETCH_SUCCESS: case NODEINFO_FETCH_SUCCESS:
return nodeinfoToInstance(fromJS(action.nodeinfo)).mergeDeep(state); return nodeinfoToInstance(fromJS(action.nodeinfo)).mergeDeep(state);
case ADMIN_CONFIG_UPDATE_SUCCESS:
return importConfigs(state, fromJS(action.configs));
default: default:
return state; return state;
} }

Wyświetl plik

@ -4,7 +4,7 @@ import {
SOAPBOX_CONFIG_REQUEST_FAIL, SOAPBOX_CONFIG_REQUEST_FAIL,
} from '../actions/soapbox'; } from '../actions/soapbox';
import { PRELOAD_IMPORT } from 'soapbox/actions/preload'; import { PRELOAD_IMPORT } from 'soapbox/actions/preload';
import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable'; import { Map as ImmutableMap, fromJS } from 'immutable';
import { ConfigDB } from 'soapbox/utils/config_db'; import { ConfigDB } from 'soapbox/utils/config_db';
const initialState = ImmutableMap(); const initialState = ImmutableMap();
@ -13,9 +13,7 @@ const fallbackState = ImmutableMap({
brandColor: '#0482d8', // Azure brandColor: '#0482d8', // Azure
}); });
const updateFromAdmin = (state, config) => { const updateFromAdmin = (state, configs) => {
const configs = config.get('configs', ImmutableList());
try { try {
return ConfigDB.find(configs, ':pleroma', ':frontend_configurations') return ConfigDB.find(configs, ':pleroma', ':frontend_configurations')
.get('value') .get('value')
@ -47,7 +45,7 @@ export default function soapbox(state = initialState, action) {
case SOAPBOX_CONFIG_REQUEST_FAIL: case SOAPBOX_CONFIG_REQUEST_FAIL:
return fallbackState.mergeDeep(state); return fallbackState.mergeDeep(state);
case ADMIN_CONFIG_UPDATE_SUCCESS: case ADMIN_CONFIG_UPDATE_SUCCESS:
return updateFromAdmin(state, fromJS(action.config)); return updateFromAdmin(state, fromJS(action.configs));
default: default:
return state; return state;
} }