Enable upload providers configuration

This commit is contained in:
cyril lopez 2018-02-28 17:11:44 +01:00
parent 696cf002d5
commit e1e7f68f4b
7 changed files with 148 additions and 14 deletions

View File

@ -15,9 +15,7 @@ import Input from 'components/InputsIndex';
import styles from './styles.scss'; import styles from './styles.scss';
class EditForm extends React.Component { class EditForm extends React.Component {
getSelectedProviderIndex = () => findIndex(this.props.settings.providers, ['provider', get(this.props.modifiedData, 'provider')]); getProviderForm = () => get(this.props.settings, ['providers', this.props.selectedProviderIndex, 'auth'], {});
getProviderForm = () => get(this.props.settings, ['providers', this.getSelectedProviderIndex(), 'auth'], {});
generateSelectOptions = () => ( generateSelectOptions = () => (
Object.keys(get(this.props.settings, 'providers', {})).reduce((acc, current) => { Object.keys(get(this.props.settings, 'providers', {})).reduce((acc, current) => {
@ -47,12 +45,12 @@ class EditForm extends React.Component {
/> />
</div> </div>
{!isEmpty(this.getProviderForm()) && ( {!isEmpty(this.getProviderForm()) && (
<div className={styles.subFormWrapper}> <div className={styles.subFormWrapper}>
<div className="row"> <div className="row">
{map(this.getProviderForm(), (value, key) => ( {map(this.getProviderForm(), (value, key) => (
<Input <Input
didCheckErrors={this.props.didCheckErrors}
errors={get(this.props.formErrors, [findIndex(this.props.formErrors, ['name', key]), 'errors'])}
key={key} key={key}
label={{ id: value.label }} label={{ id: value.label }}
name={key} name={key}
@ -97,9 +95,13 @@ EditForm.defaultProps = {
providers: [], providers: [],
}, },
}; };
EditForm.propTypes = { EditForm.propTypes = {
didCheckErrors: PropTypes.bool.isRequired,
formErrors: PropTypes.array.isRequired,
modifiedData: PropTypes.object.isRequired, modifiedData: PropTypes.object.isRequired,
onChange: PropTypes.func.isRequired, onChange: PropTypes.func.isRequired,
selectedProviderIndex: PropTypes.number.isRequired,
settings: PropTypes.object, settings: PropTypes.object,
}; };

View File

@ -10,6 +10,10 @@ import {
GET_SETTINGS_SUCCEEDED, GET_SETTINGS_SUCCEEDED,
ON_CANCEL, ON_CANCEL,
ON_CHANGE, ON_CHANGE,
SET_ERRORS,
SUBMIT,
SUBMIT_ERROR,
SUBMIT_SUCCEEDED,
} from './constants'; } from './constants';
export function getSettings(env) { export function getSettings(env) {
@ -43,3 +47,30 @@ export function onChange({ target }) {
value, value,
}; };
} }
export function setErrors(errors) {
return {
type: SET_ERRORS,
errors,
};
}
export function submit() {
return {
type: SUBMIT,
};
}
export function submitError(errors) {
return {
type: SUBMIT_ERROR,
errors,
};
}
export function submitSucceeded(data) {
return {
type: SUBMIT_SUCCEEDED,
data,
};
}

View File

@ -8,3 +8,7 @@ export const GET_SETTINGS = 'Upload/ConfigPage/GET_SETTINGS';
export const GET_SETTINGS_SUCCEEDED = 'Upload/ConfigPage/GET_SETTINGS_SUCCEEDED'; export const GET_SETTINGS_SUCCEEDED = 'Upload/ConfigPage/GET_SETTINGS_SUCCEEDED';
export const ON_CANCEL = 'Upload/ConfigPage/ON_CANCEL'; export const ON_CANCEL = 'Upload/ConfigPage/ON_CANCEL';
export const ON_CHANGE = 'Upload/ConfigPage/ON_CHANGE'; export const ON_CHANGE = 'Upload/ConfigPage/ON_CHANGE';
export const SET_ERRORS = 'Upload/ConfigPage/SET_ERRORS';
export const SUBMIT = 'Upload/ConfigPage/SUBMIT';
export const SUBMIT_ERROR = 'Upload/ConfigPage/SUBMIT_ERROR';
export const SUBMIT_SUCCEEDED = 'Upload/ConfigPage/SUBMIT_SUCCEEDED';

View File

@ -8,7 +8,7 @@ import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { bindActionCreators, compose } from 'redux'; import { bindActionCreators, compose } from 'redux';
// import { get, findIndex } from 'lodash'; import { findIndex, get, isEmpty } from 'lodash';
// You can find these components in either // You can find these components in either
// ./node_modules/strapi-helper-plugin/lib/src // ./node_modules/strapi-helper-plugin/lib/src
@ -30,6 +30,8 @@ import {
getSettings, getSettings,
onCancel, onCancel,
onChange, onChange,
setErrors,
submit,
} from './actions'; } from './actions';
import reducer from './reducer'; import reducer from './reducer';
@ -48,6 +50,8 @@ class ConfigPage extends React.Component {
} }
} }
getSelectedProviderIndex = () => findIndex(this.props.settings.providers, ['provider', get(this.props.modifiedData, 'provider')]);
/** /**
* Get Settings depending on the props * Get Settings depending on the props
* @param {Object} props * @param {Object} props
@ -68,6 +72,25 @@ class ConfigPage extends React.Component {
return headerNavLinks; return headerNavLinks;
} }
handleSubmit = (e) => {
e.preventDefault();
const formErrors = Object.keys(get(this.props.settings, ['providers', this.getSelectedProviderIndex(), 'auth'], {})).reduce((acc, current) => {
if (isEmpty(get(this.props.modifiedData, current, ''))) {
acc.push({
name: current,
errors: [{ id: 'components.Input.error.validation.required' }],
});
}
return acc;
}, []);
if (!isEmpty(formErrors)) {
return this.props.setErrors(formErrors);
}
return this.props.submit();
}
pluginHeaderActions = [ pluginHeaderActions = [
{ {
kind: 'secondary', kind: 'secondary',
@ -78,17 +101,15 @@ class ConfigPage extends React.Component {
{ {
kind: 'primary', kind: 'primary',
label: 'app.components.Button.save', label: 'app.components.Button.save',
onClick: () => console.log('will save'), onClick: this.handleSubmit,
type: 'button', type: 'submit',
}, },
]; ];
render() { render() {
console.log('modifiedData', this.props.modifiedData);
console.log('settings', this.props.settings);
return ( return (
<div> <div>
<form onSubmit={(e) => e.preventDefault()}> <form onSubmit={this.handleSubmit}>
<ContainerFluid> <ContainerFluid>
<PluginHeader <PluginHeader
actions={this.pluginHeaderActions} actions={this.pluginHeaderActions}
@ -97,8 +118,11 @@ class ConfigPage extends React.Component {
/> />
<HeaderNav links={this.generateLinks()} /> <HeaderNav links={this.generateLinks()} />
<EditForm <EditForm
didCheckErrors={this.props.didCheckErrors}
formErrors={this.props.formErrors}
modifiedData={this.props.modifiedData} modifiedData={this.props.modifiedData}
onChange={this.props.onChange} onChange={this.props.onChange}
selectedProviderIndex={this.getSelectedProviderIndex()}
settings={this.props.settings} settings={this.props.settings}
/> />
</ContainerFluid> </ContainerFluid>
@ -113,18 +137,23 @@ ConfigPage.contextTypes = {
}; };
ConfigPage.defaultProps = { ConfigPage.defaultProps = {
formErrors: [],
settings: { settings: {
providers: [], providers: [],
}, },
}; };
ConfigPage.propTypes = { ConfigPage.propTypes = {
didCheckErrors: PropTypes.bool.isRequired,
formErrors: PropTypes.array,
getSettings: PropTypes.func.isRequired, getSettings: PropTypes.func.isRequired,
match: PropTypes.object.isRequired, match: PropTypes.object.isRequired,
modifiedData: PropTypes.object.isRequired, modifiedData: PropTypes.object.isRequired,
onCancel: PropTypes.func.isRequired, onCancel: PropTypes.func.isRequired,
onChange: PropTypes.func.isRequired, onChange: PropTypes.func.isRequired,
setErrors: PropTypes.func.isRequired,
settings: PropTypes.object, settings: PropTypes.object,
submit: PropTypes.func.isRequired,
}; };
function mapDispatchToProps(dispatch) { function mapDispatchToProps(dispatch) {
@ -133,6 +162,8 @@ function mapDispatchToProps(dispatch) {
getSettings, getSettings,
onCancel, onCancel,
onChange, onChange,
setErrors,
submit,
}, },
dispatch, dispatch,
); );

View File

@ -4,17 +4,22 @@
* *
*/ */
import { fromJS, Map } from 'immutable'; import { fromJS, List, Map } from 'immutable';
import { import {
GET_SETTINGS, GET_SETTINGS,
GET_SETTINGS_SUCCEEDED, GET_SETTINGS_SUCCEEDED,
ON_CANCEL, ON_CANCEL,
ON_CHANGE, ON_CHANGE,
SET_ERRORS,
SUBMIT_ERROR,
SUBMIT_SUCCEEDED,
} from './constants'; } from './constants';
const initialState = fromJS({ const initialState = fromJS({
didCheckErrors: false,
env: '', env: '',
formErrors: List([]),
initialData: Map({}), initialData: Map({}),
modifiedData: Map({}), modifiedData: Map({}),
settings: {}, settings: {},
@ -26,14 +31,30 @@ function configPageReducer(state = initialState, action) {
return state.update('env', () => action.env); return state.update('env', () => action.env);
case GET_SETTINGS_SUCCEEDED: case GET_SETTINGS_SUCCEEDED:
return state return state
.update('didCheckErrors', (v) => v = !v)
.update('formErrors', () => List([]))
.update('initialData', () => Map(action.initialData)) .update('initialData', () => Map(action.initialData))
.update('modifiedData', () => Map(action.initialData)) .update('modifiedData', () => Map(action.initialData))
.update('settings', () => action.settings); .update('settings', () => action.settings);
case ON_CANCEL: case ON_CANCEL:
return state.update('modifiedData', () => state.get('initialData')); return state
.update('didCheckErrors', (v) => v = !v)
.update('formErrors', () => List([]))
.update('modifiedData', () => state.get('initialData'));
case ON_CHANGE: case ON_CHANGE:
return state return state
.updateIn(action.keys, () => action.value); .updateIn(action.keys, () => action.value);
case SET_ERRORS:
case SUBMIT_ERROR:
return state
.update('didCheckErrors', (v) => v = !v)
.update('formErrors', () => List(action.errors));
case SUBMIT_SUCCEEDED:
return state
.update('didCheckErrors', (v) => v = !v)
.update('formErrors', () => List([]))
.update('initialData', () => Map(action.data))
.update('modifiedData', () => Map(action.data));
default: default:
return state; return state;
} }

View File

@ -1,13 +1,19 @@
// import { LOCATION_CHANGE } from 'react-router-redux'; // import { LOCATION_CHANGE } from 'react-router-redux';
import { call, fork, put, takeLatest } from 'redux-saga/effects'; import { call, fork, put, select, takeLatest } from 'redux-saga/effects';
import request from 'utils/request'; import request from 'utils/request';
import { import {
getSettingsSucceeded, getSettingsSucceeded,
submitSucceeded,
} from './actions'; } from './actions';
import { import {
GET_SETTINGS, GET_SETTINGS,
SUBMIT,
} from './constants'; } from './constants';
import {
makeSelectEnv,
makeSelectModifiedData,
} from './selectors';
export function* settingsGet(action) { export function* settingsGet(action) {
try { try {
@ -19,8 +25,33 @@ export function* settingsGet(action) {
} }
} }
export function* submit() {
try {
const env = yield select(makeSelectEnv());
let body = yield select(makeSelectModifiedData());
if (body.provider === 'local') {
body = {
enabled: body.enabled,
provider: 'local',
sizeLimit: body.sizeLimit,
};
}
const requestURL = `/upload/settings/${env}`;
yield call(request, requestURL, { method: 'PUT', body });
// Update reducer with optimisticResponse
yield put(submitSucceeded(body));
} catch(err) {
console.log('err', err);
strapi.notification.error('notification.error');
// TODO handle error PUT
}
}
function* defaultSaga() { function* defaultSaga() {
yield fork(takeLatest, GET_SETTINGS, settingsGet); yield fork(takeLatest, GET_SETTINGS, settingsGet);
yield fork(takeLatest, SUBMIT, submit);
} }
export default defaultSaga; export default defaultSaga;

View File

@ -14,4 +14,18 @@ const selectConfigPage = () => createSelector(
(substate) => substate.toJS(), (substate) => substate.toJS(),
); );
const makeSelectEnv = () => createSelector(
selectConfigPageDomain(),
(substate) => substate.get('env'),
);
const makeSelectModifiedData = () => createSelector(
selectConfigPageDomain(),
(substate) => substate.get('modifiedData').toJS(),
);
export default selectConfigPage; export default selectConfigPage;
export {
makeSelectEnv,
makeSelectModifiedData,
};