mirror of
https://github.com/strapi/strapi.git
synced 2025-07-24 01:18:17 +00:00
Merge branch 'plugin/content-manager-dev' of github.com:strapi/strapi into plugin/content-manager-dev
This commit is contained in:
commit
4d2ec1f5b0
@ -6,6 +6,7 @@
|
||||
|
||||
import React from 'react';
|
||||
import moment from 'moment';
|
||||
import PropTypes from 'prop-types';
|
||||
import { get, isEmpty, map, mapKeys, isObject, reject, includes } from 'lodash';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import DateTime from 'react-datetime';
|
||||
@ -67,37 +68,37 @@ class Input extends React.Component { // eslint-disable-line react/prefer-statel
|
||||
validate = (value) => {
|
||||
let errors = [];
|
||||
// handle i18n
|
||||
const requiredError = { id: 'error.validation.required' };
|
||||
const requiredError = { id: `${this.props.pluginID}.error.validation.required` };
|
||||
mapKeys(this.props.validations, (validationValue, validationKey) => {
|
||||
switch (validationKey) {
|
||||
case 'max':
|
||||
if (parseInt(value, 10) > validationValue) {
|
||||
errors.push({ id: 'error.validation.max' });
|
||||
errors.push({ id: `${this.props.pluginID}.error.validation.max` });
|
||||
}
|
||||
break;
|
||||
case 'maxLength':
|
||||
if (value.length > validationValue) {
|
||||
errors.push({ id: 'error.validation.maxLength' });
|
||||
errors.push({ id: `${this.props.pluginID}.error.validation.maxLength` });
|
||||
}
|
||||
break;
|
||||
case 'min':
|
||||
if (parseInt(value, 10) < validationValue) {
|
||||
errors.push({ id: 'error.validation.min' });
|
||||
errors.push({ id: `${this.props.pluginID}.error.validation.min` });
|
||||
}
|
||||
break;
|
||||
case 'minLength':
|
||||
if (value.length < validationValue) {
|
||||
errors.push({ id: 'error.validation.minLength' });
|
||||
errors.push({ id: `${this.props.pluginID}.error.validation.minLength` });
|
||||
}
|
||||
break;
|
||||
case 'required':
|
||||
if (value.length === 0) {
|
||||
errors.push({ id: 'error.validation.required' });
|
||||
errors.push({ id: `${this.props.pluginID}.error.validation.required` });
|
||||
}
|
||||
break;
|
||||
case 'regex':
|
||||
if (!new RegExp(validationValue).test(value)) {
|
||||
errors.push({ id: 'error.validation.regex' });
|
||||
errors.push({ id: `${this.props.pluginID}.error.validation.regex` });
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -367,36 +368,37 @@ class Input extends React.Component { // eslint-disable-line react/prefer-statel
|
||||
}
|
||||
|
||||
Input.propTypes = {
|
||||
addon: React.PropTypes.oneOfType([
|
||||
React.PropTypes.bool,
|
||||
React.PropTypes.string,
|
||||
addon: PropTypes.oneOfType([
|
||||
PropTypes.bool,
|
||||
PropTypes.string,
|
||||
]),
|
||||
addRequiredInputDesign: React.PropTypes.bool,
|
||||
customBootstrapClass: React.PropTypes.string,
|
||||
deactivateErrorHighlight: React.PropTypes.bool,
|
||||
didCheckErrors: React.PropTypes.bool,
|
||||
disabled: React.PropTypes.bool,
|
||||
errors: React.PropTypes.array,
|
||||
handleBlur: React.PropTypes.oneOfType([
|
||||
React.PropTypes.func,
|
||||
React.PropTypes.bool,
|
||||
addRequiredInputDesign: PropTypes.bool,
|
||||
customBootstrapClass: PropTypes.string,
|
||||
deactivateErrorHighlight: PropTypes.bool,
|
||||
didCheckErrors: PropTypes.bool,
|
||||
disabled: PropTypes.bool,
|
||||
errors: PropTypes.array,
|
||||
handleBlur: PropTypes.oneOfType([
|
||||
PropTypes.func,
|
||||
PropTypes.bool,
|
||||
]),
|
||||
handleChange: React.PropTypes.func.isRequired,
|
||||
handleFocus: React.PropTypes.func,
|
||||
inputDescription: React.PropTypes.string,
|
||||
label: React.PropTypes.string.isRequired,
|
||||
name: React.PropTypes.string.isRequired,
|
||||
noErrorsDescription: React.PropTypes.bool,
|
||||
placeholder: React.PropTypes.string,
|
||||
selectOptions: React.PropTypes.array,
|
||||
selectOptionsFetchSucceeded: React.PropTypes.bool,
|
||||
title: React.PropTypes.string,
|
||||
type: React.PropTypes.string.isRequired,
|
||||
validations: React.PropTypes.object.isRequired,
|
||||
value: React.PropTypes.oneOfType([
|
||||
React.PropTypes.string,
|
||||
React.PropTypes.bool,
|
||||
React.PropTypes.number,
|
||||
handleChange: PropTypes.func.isRequired,
|
||||
handleFocus: PropTypes.func,
|
||||
inputDescription: PropTypes.string,
|
||||
label: PropTypes.string.isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
noErrorsDescription: PropTypes.bool,
|
||||
placeholder: PropTypes.string,
|
||||
pluginID: PropTypes.string,
|
||||
selectOptions: PropTypes.array,
|
||||
selectOptionsFetchSucceeded: PropTypes.bool,
|
||||
title: PropTypes.string,
|
||||
type: PropTypes.string.isRequired,
|
||||
validations: PropTypes.object.isRequired,
|
||||
value: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.bool,
|
||||
PropTypes.number,
|
||||
]),
|
||||
};
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
// Dependencies.
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { omit } from 'lodash';
|
||||
import { findIndex, get, omit } from 'lodash';
|
||||
|
||||
// Components.
|
||||
import Input from 'components/Input';
|
||||
@ -43,6 +43,10 @@ class EditForm extends React.Component {
|
||||
// List fields inputs
|
||||
const fields = Object.keys(displayedFields).map(attr => {
|
||||
const details = displayedFields[attr];
|
||||
const errorIndex = findIndex(this.props.formErrors, ['name', attr]);
|
||||
const errors = errorIndex !== -1 ? this.props.formErrors[errorIndex].errors : [];
|
||||
const validationsIndex = findIndex(this.props.formValidations, ['name', attr]);
|
||||
const validations = get(this.props.formValidations[validationsIndex], 'validations') || {};
|
||||
|
||||
return (
|
||||
<Input
|
||||
@ -53,7 +57,10 @@ class EditForm extends React.Component {
|
||||
value={this.props.record.get(attr) || ''}
|
||||
placeholder={details.placeholder || details.label || attr || ''}
|
||||
handleChange={this.props.handleChange}
|
||||
validations={{}}
|
||||
validations={validations}
|
||||
errors={errors}
|
||||
didCheckErrors={this.props.didCheckErrors}
|
||||
pluginID="content-manager"
|
||||
/>
|
||||
);
|
||||
});
|
||||
@ -70,6 +77,9 @@ class EditForm extends React.Component {
|
||||
|
||||
EditForm.propTypes = {
|
||||
currentModelName: PropTypes.string.isRequired,
|
||||
didCheckErrors: PropTypes.bool.isRequired,
|
||||
formErrors: PropTypes.array.isRequired,
|
||||
formValidations: PropTypes.array.isRequired,
|
||||
handleChange: PropTypes.func.isRequired,
|
||||
record: PropTypes.oneOfType([
|
||||
PropTypes.object,
|
||||
|
@ -4,7 +4,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
import { fromJS } from 'immutable';
|
||||
import { fromJS, List } from 'immutable';
|
||||
|
||||
import { LOAD_MODELS, LOADED_MODELS, UPDATE_SCHEMA } from './constants';
|
||||
|
||||
@ -12,6 +12,7 @@ const initialState = fromJS({
|
||||
loading: true,
|
||||
models: false,
|
||||
schema: false,
|
||||
formValidations: List(),
|
||||
});
|
||||
|
||||
function appReducer(state = initialState, action) {
|
||||
|
@ -3,40 +3,46 @@
|
||||
* Edit actions
|
||||
*
|
||||
*/
|
||||
import { get } from 'lodash';
|
||||
import { getValidationsFromForm } from '../../utils/formValidations';
|
||||
|
||||
import {
|
||||
SET_INITIAL_STATE,
|
||||
CANCEL_CHANGES,
|
||||
DELETE_RECORD,
|
||||
DELETE_RECORD_ERROR,
|
||||
DELETE_RECORD_SUCCESS,
|
||||
EDIT_RECORD,
|
||||
EDIT_RECORD_ERROR,
|
||||
EDIT_RECORD_SUCCESS,
|
||||
SET_CURRENT_MODEL_NAME,
|
||||
SET_IS_CREATING,
|
||||
SET_INITIAL_STATE,
|
||||
LOAD_RECORD,
|
||||
LOAD_RECORD_SUCCESS,
|
||||
SET_RECORD_ATTRIBUTE,
|
||||
EDIT_RECORD,
|
||||
EDIT_RECORD_SUCCESS,
|
||||
EDIT_RECORD_ERROR,
|
||||
DELETE_RECORD,
|
||||
DELETE_RECORD_SUCCESS,
|
||||
DELETE_RECORD_ERROR,
|
||||
TOGGLE_NULL,
|
||||
CANCEL_CHANGES,
|
||||
SET_FORM_VALIDATIONS,
|
||||
SET_FORM,
|
||||
SET_FORM_ERRORS,
|
||||
} from './constants';
|
||||
|
||||
export function setInitialState() {
|
||||
export function cancelChanges() {
|
||||
return {
|
||||
type: SET_INITIAL_STATE,
|
||||
type: CANCEL_CHANGES,
|
||||
};
|
||||
}
|
||||
|
||||
export function setCurrentModelName(currentModelName) {
|
||||
export function deleteRecord(id, modelName) {
|
||||
return {
|
||||
type: SET_CURRENT_MODEL_NAME,
|
||||
currentModelName,
|
||||
type: DELETE_RECORD,
|
||||
id,
|
||||
modelName,
|
||||
};
|
||||
}
|
||||
|
||||
export function setIsCreating() {
|
||||
export function editRecord() {
|
||||
return {
|
||||
type: SET_IS_CREATING,
|
||||
type: EDIT_RECORD,
|
||||
};
|
||||
}
|
||||
|
||||
@ -47,24 +53,17 @@ export function loadRecord(id) {
|
||||
};
|
||||
}
|
||||
|
||||
export function recordLoaded(record) {
|
||||
|
||||
export function recordDeleted(id) {
|
||||
return {
|
||||
type: LOAD_RECORD_SUCCESS,
|
||||
record,
|
||||
type: DELETE_RECORD_SUCCESS,
|
||||
id,
|
||||
};
|
||||
}
|
||||
|
||||
export function setRecordAttribute(key, value) {
|
||||
export function recordDeleteError() {
|
||||
return {
|
||||
type: SET_RECORD_ATTRIBUTE,
|
||||
key,
|
||||
value,
|
||||
};
|
||||
}
|
||||
|
||||
export function editRecord() {
|
||||
return {
|
||||
type: EDIT_RECORD,
|
||||
type: DELETE_RECORD_ERROR,
|
||||
};
|
||||
}
|
||||
|
||||
@ -80,24 +79,71 @@ export function recordEditError() {
|
||||
};
|
||||
}
|
||||
|
||||
export function deleteRecord(id, modelName) {
|
||||
export function recordLoaded(record) {
|
||||
return {
|
||||
type: DELETE_RECORD,
|
||||
id,
|
||||
modelName,
|
||||
type: LOAD_RECORD_SUCCESS,
|
||||
record,
|
||||
};
|
||||
}
|
||||
|
||||
export function recordDeleted(id) {
|
||||
export function setCurrentModelName(currentModelName) {
|
||||
return {
|
||||
type: DELETE_RECORD_SUCCESS,
|
||||
id,
|
||||
type: SET_CURRENT_MODEL_NAME,
|
||||
currentModelName,
|
||||
};
|
||||
}
|
||||
|
||||
export function recordDeleteError() {
|
||||
export function setForm(data) {
|
||||
const form = [];
|
||||
Object.keys(data).map(attr => {
|
||||
form.push([attr, '']);
|
||||
});
|
||||
|
||||
return {
|
||||
type: DELETE_RECORD_ERROR,
|
||||
type: SET_FORM,
|
||||
form,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export function setFormErrors(formErrors) {
|
||||
return {
|
||||
type: SET_FORM_ERRORS,
|
||||
formErrors,
|
||||
};
|
||||
}
|
||||
|
||||
export function setFormValidations(data) {
|
||||
const form = Object.keys(data).map(attr => {
|
||||
return { name: attr, validations: get(data[attr], ['params']) || {} }
|
||||
});
|
||||
|
||||
const formValidations = getValidationsFromForm(form, []);
|
||||
|
||||
return {
|
||||
type: SET_FORM_VALIDATIONS,
|
||||
formValidations,
|
||||
}
|
||||
}
|
||||
|
||||
export function setInitialState() {
|
||||
return {
|
||||
type: SET_INITIAL_STATE,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
export function setIsCreating() {
|
||||
return {
|
||||
type: SET_IS_CREATING,
|
||||
};
|
||||
}
|
||||
|
||||
export function setRecordAttribute(key, value) {
|
||||
return {
|
||||
type: SET_RECORD_ATTRIBUTE,
|
||||
key,
|
||||
value,
|
||||
};
|
||||
}
|
||||
|
||||
@ -106,9 +152,3 @@ export function toggleNull() {
|
||||
type: TOGGLE_NULL,
|
||||
};
|
||||
}
|
||||
|
||||
export function cancelChanges() {
|
||||
return {
|
||||
type: CANCEL_CHANGES,
|
||||
};
|
||||
}
|
||||
|
@ -7,6 +7,9 @@
|
||||
export const SET_INITIAL_STATE = 'app/Edit/SET_INITIAL_STATE';
|
||||
export const SET_CURRENT_MODEL_NAME = 'app/Edit/SET_CURRENT_MODEL_NAME';
|
||||
export const SET_IS_CREATING = 'app/Edit/SET_IS_CREATING';
|
||||
export const SET_FORM_VALIDATIONS = 'app/Edit/SET_FORM_VALIDATIONS';
|
||||
export const SET_FORM = 'app/Edit/SET_FORM';
|
||||
export const SET_FORM_ERRORS = 'app/Edit/SET_FORM_ERRORS';
|
||||
|
||||
export const LOAD_RECORD = 'app/Edit/LOAD_RECORD';
|
||||
export const LOAD_RECORD_SUCCESS = 'app/Edit/LOAD_RECORD_SUCCESS';
|
||||
|
@ -11,7 +11,7 @@ import { connect } from 'react-redux';
|
||||
import { bindActionCreators, compose } from 'redux';
|
||||
import { createStructuredSelector } from 'reselect';
|
||||
import PropTypes from 'prop-types';
|
||||
import { get, isObject } from 'lodash';
|
||||
import { map, get, isObject, isEmpty } from 'lodash';
|
||||
import { router } from 'app';
|
||||
|
||||
// Components.
|
||||
@ -26,6 +26,7 @@ import { makeSelectModels, makeSelectSchema } from 'containers/App/selectors';
|
||||
import injectReducer from 'utils/injectReducer';
|
||||
import injectSaga from 'utils/injectSaga';
|
||||
import templateObject from 'utils/templateObject';
|
||||
import { checkFormValidity } from '../../utils/formValidations';
|
||||
|
||||
// Styles.
|
||||
import styles from './styles.scss';
|
||||
@ -40,6 +41,9 @@ import {
|
||||
editRecord,
|
||||
toggleNull,
|
||||
cancelChanges,
|
||||
setFormValidations,
|
||||
setForm,
|
||||
setFormErrors,
|
||||
} from './actions';
|
||||
|
||||
// Selectors.
|
||||
@ -52,6 +56,10 @@ import {
|
||||
makeSelectDeleting,
|
||||
makeSelectIsCreating,
|
||||
makeSelectIsRelationComponentNull,
|
||||
makeSelectForm,
|
||||
makeSelectFormValidations,
|
||||
makeSelectFormErrors,
|
||||
makeSelectDidCheckErrors,
|
||||
} from './selectors';
|
||||
|
||||
import reducer from './reducer';
|
||||
@ -74,7 +82,7 @@ export class Edit extends React.Component {
|
||||
buttonBackground: 'primary',
|
||||
buttonSize: 'buttonLg',
|
||||
label: this.props.editing ? 'content-manager.containers.Edit.editing' : 'content-manager.containers.Edit.submit',
|
||||
onClick: this.props.editRecord,
|
||||
onClick: this.handleSubmit,
|
||||
disabled: this.props.editing,
|
||||
type: 'submit',
|
||||
},
|
||||
@ -94,7 +102,8 @@ export class Edit extends React.Component {
|
||||
componentDidMount() {
|
||||
this.props.setInitialState();
|
||||
this.props.setCurrentModelName(this.props.match.params.slug.toLowerCase());
|
||||
|
||||
this.props.setFormValidations(this.props.models[this.props.match.params.slug.toLowerCase()].attributes);
|
||||
this.props.setForm(this.props.models[this.props.match.params.slug.toLowerCase()].attributes);
|
||||
// Detect that the current route is the `create` route or not
|
||||
if (this.props.match.params.id === 'create') {
|
||||
this.props.setIsCreating();
|
||||
@ -118,12 +127,20 @@ export class Edit extends React.Component {
|
||||
}
|
||||
|
||||
handleSubmit = () => {
|
||||
this.props.editRecord();
|
||||
const form = this.props.form.toJS();
|
||||
map(this.props.record.toJS(), (value, key) => form[key] = value);
|
||||
const formErrors = checkFormValidity(form, this.props.formValidations.toJS());
|
||||
|
||||
if (isEmpty(formErrors)) {
|
||||
this.props.editRecord();
|
||||
} else {
|
||||
this.props.setFormErrors(formErrors);
|
||||
}
|
||||
}
|
||||
|
||||
handleSubmitOnEnterPress = (e) => {
|
||||
if (e.keyCode === 13) {
|
||||
this.props.editRecord();
|
||||
this.handleSubmit();
|
||||
}
|
||||
}
|
||||
|
||||
@ -164,6 +181,9 @@ export class Edit extends React.Component {
|
||||
handleChange={this.handleChange}
|
||||
handleSubmit={this.handleSubmit}
|
||||
editing={this.props.editing}
|
||||
formErrors={this.props.formErrors.toJS()}
|
||||
didCheckErrors={this.props.didCheckErrors}
|
||||
formValidations={this.props.formValidations.toJS()}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@ -185,17 +205,25 @@ export class Edit extends React.Component {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/* eslint-disable react/require-default-props */
|
||||
Edit.propTypes = {
|
||||
cancelChanges: PropTypes.func.isRequired,
|
||||
currentModelName: PropTypes.oneOfType([
|
||||
PropTypes.bool,
|
||||
PropTypes.string,
|
||||
]).isRequired,
|
||||
// deleteRecord: PropTypes.func.isRequired,
|
||||
// deleting: PropTypes.bool.isRequired,
|
||||
didCheckErrors: PropTypes.bool.isRequired,
|
||||
editing: PropTypes.bool.isRequired,
|
||||
editRecord: PropTypes.func.isRequired,
|
||||
form: PropTypes.object.isRequired,
|
||||
formErrors: PropTypes.oneOfType([
|
||||
PropTypes.array,
|
||||
PropTypes.object,
|
||||
]),
|
||||
formValidations: PropTypes.oneOfType([
|
||||
PropTypes.array,
|
||||
PropTypes.object,
|
||||
]),
|
||||
isCreating: PropTypes.bool.isRequired,
|
||||
isRelationComponentNull: PropTypes.bool.isRequired,
|
||||
loading: PropTypes.bool.isRequired,
|
||||
@ -219,6 +247,9 @@ Edit.propTypes = {
|
||||
PropTypes.bool,
|
||||
]).isRequired,
|
||||
setCurrentModelName: PropTypes.func.isRequired,
|
||||
setForm: PropTypes.func.isRequired,
|
||||
setFormErrors: PropTypes.func.isRequired,
|
||||
setFormValidations: PropTypes.func.isRequired,
|
||||
setInitialState: PropTypes.func.isRequired,
|
||||
setIsCreating: PropTypes.func.isRequired,
|
||||
setRecordAttribute: PropTypes.func.isRequired,
|
||||
@ -235,6 +266,10 @@ const mapStateToProps = createStructuredSelector({
|
||||
schema: makeSelectSchema(),
|
||||
models: makeSelectModels(),
|
||||
isRelationComponentNull: makeSelectIsRelationComponentNull(),
|
||||
form: makeSelectForm(),
|
||||
formValidations: makeSelectFormValidations(),
|
||||
formErrors: makeSelectFormErrors(),
|
||||
didCheckErrors: makeSelectDidCheckErrors(),
|
||||
});
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
@ -248,6 +283,9 @@ function mapDispatchToProps(dispatch) {
|
||||
editRecord,
|
||||
toggleNull,
|
||||
cancelChanges,
|
||||
setFormValidations,
|
||||
setForm,
|
||||
setFormErrors,
|
||||
},
|
||||
dispatch
|
||||
);
|
||||
|
@ -4,7 +4,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
import { fromJS, Map } from 'immutable';
|
||||
import { fromJS, Map, List } from 'immutable';
|
||||
|
||||
import {
|
||||
SET_INITIAL_STATE,
|
||||
@ -21,6 +21,9 @@ import {
|
||||
DELETE_RECORD_ERROR,
|
||||
TOGGLE_NULL,
|
||||
CANCEL_CHANGES,
|
||||
SET_FORM_VALIDATIONS,
|
||||
SET_FORM,
|
||||
SET_FORM_ERRORS,
|
||||
} from './constants';
|
||||
|
||||
const initialState = fromJS({
|
||||
@ -31,6 +34,10 @@ const initialState = fromJS({
|
||||
deleting: false,
|
||||
isCreating: false,
|
||||
isRelationComponentNull: false,
|
||||
formValidations: List(),
|
||||
formErrors: List(),
|
||||
form: Map({}),
|
||||
didCheckErrors: false,
|
||||
});
|
||||
|
||||
function editReducer(state = initialState, action) {
|
||||
@ -50,9 +57,12 @@ function editReducer(state = initialState, action) {
|
||||
.set('model', action.model)
|
||||
.set('id', action.id);
|
||||
case LOAD_RECORD_SUCCESS:
|
||||
return state.set('loading', false).set('record', fromJS(action.record));
|
||||
return state
|
||||
.set('loading', false)
|
||||
.set('record', fromJS(action.record));
|
||||
case SET_RECORD_ATTRIBUTE:
|
||||
return state.setIn(['record', action.key], fromJS(action.value));
|
||||
return state
|
||||
.setIn(['record', action.key], fromJS(action.value));
|
||||
case EDIT_RECORD:
|
||||
return state.set('editing', true);
|
||||
case EDIT_RECORD_SUCCESS:
|
||||
@ -69,6 +79,15 @@ function editReducer(state = initialState, action) {
|
||||
return state.set('isRelationComponentNull', !state.get('isRelationComponentNull'));
|
||||
case CANCEL_CHANGES:
|
||||
return state.set('record', Map({}));
|
||||
case SET_FORM_VALIDATIONS:
|
||||
return state
|
||||
.set('formValidations', List(action.formValidations));
|
||||
case SET_FORM:
|
||||
return state.set('form', Map(action.form));
|
||||
case SET_FORM_ERRORS:
|
||||
return state
|
||||
.set('formErrors', List(action.formErrors))
|
||||
.set('didCheckErrors', !state.didCheckErrors);
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
@ -36,6 +36,18 @@ const makeSelectIsCreating = () =>
|
||||
const makeSelectIsRelationComponentNull = () =>
|
||||
createSelector(selectEditDomain(), substate => substate.get('isRelationComponentNull'));
|
||||
|
||||
const makeSelectForm = () =>
|
||||
createSelector(selectEditDomain(), substate => substate.get('form'));
|
||||
|
||||
const makeSelectFormValidations = () =>
|
||||
createSelector(selectEditDomain(), substate => substate.get('formValidations'));
|
||||
|
||||
const makeSelectFormErrors = () =>
|
||||
createSelector(selectEditDomain(), substate => substate.get('formErrors'));
|
||||
|
||||
const makeSelectDidCheckErrors = () =>
|
||||
createSelector(selectEditDomain(), substate => substate.get('didCheckErrors'));
|
||||
|
||||
export default selectEditDomain;
|
||||
export {
|
||||
makeSelectRecord,
|
||||
@ -45,4 +57,8 @@ export {
|
||||
makeSelectDeleting,
|
||||
makeSelectIsCreating,
|
||||
makeSelectIsRelationComponentNull,
|
||||
makeSelectForm,
|
||||
makeSelectFormValidations,
|
||||
makeSelectFormErrors,
|
||||
makeSelectDidCheckErrors,
|
||||
};
|
||||
|
@ -87,14 +87,6 @@ export class List extends React.Component {
|
||||
|
||||
}
|
||||
|
||||
changePage = (page) => {
|
||||
router.push({
|
||||
pathname: this.props.location.pathname,
|
||||
search: `?page=${page}&limit=${this.props.limit}&sort=${this.props.sort}`,
|
||||
});
|
||||
this.props.changePage(page);
|
||||
}
|
||||
|
||||
init(props) {
|
||||
const slug = props.match.params.slug;
|
||||
// Set current model name
|
||||
@ -132,6 +124,14 @@ export class List extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
handleChangePage = (page) => {
|
||||
router.push({
|
||||
pathname: this.props.location.pathname,
|
||||
search: `?page=${page}&limit=${this.props.limit}&sort=${this.props.sort}`,
|
||||
});
|
||||
this.props.changePage(page);
|
||||
}
|
||||
|
||||
handleChangeSort = (sort) => {
|
||||
router.push({
|
||||
pathname: this.props.location.pathname,
|
||||
@ -248,7 +248,7 @@ export class List extends React.Component {
|
||||
<TableFooter
|
||||
limit={this.props.limit}
|
||||
currentPage={this.props.currentPage}
|
||||
changePage={this.changePage}
|
||||
changePage={this.handleChangePage}
|
||||
count={this.props.count}
|
||||
className="push-lg-right"
|
||||
handleChangeLimit={this.handleChangeLimit}
|
||||
|
@ -12,6 +12,19 @@
|
||||
"containers.List.pluginHeaderDescription": "Manage your {label}",
|
||||
"components.LimitSelect.itemsPerPage": "Items per page",
|
||||
"containers.List.errorFetchRecords": "Error",
|
||||
|
||||
"error.validation.required": "This value input is required.",
|
||||
"error.validation.regex": "The value not match the regex.",
|
||||
"error.validation.max": "The value is too high.",
|
||||
"error.validation.min": "The value is too low.",
|
||||
"error.validation.maxLength": "The value is too long.",
|
||||
"error.validation.minLength": "The value is too shot.",
|
||||
"error.contentTypeName.taken": "This name already exists",
|
||||
"error.attribute.taken": "This field name already exists",
|
||||
"error.attribute.key.taken": "This value already exists",
|
||||
"error.attribute.sameKeyAndName": "Can't be equals",
|
||||
"error.validation.minSupMax": "Can't be superior",
|
||||
|
||||
"pageNotFound": "Page not found",
|
||||
|
||||
"popUpWarning.button.cancel": "Cancel",
|
||||
|
@ -13,6 +13,18 @@
|
||||
"components.LimitSelect.itemsPerPage": "Éléments par page",
|
||||
"containers.List.errorFetchRecords": "Erreur",
|
||||
|
||||
"error.validation.required": "Ce champ est obligatoire.",
|
||||
"error.validation.regex": "La valeur ne correspond pas au format attendu.",
|
||||
"error.validation.max": "La valeur est trop grande.",
|
||||
"error.validation.min": "La valeur est trop basse.",
|
||||
"error.validation.maxLength": "La valeur est trop longue.",
|
||||
"error.validation.minLength": "La valeur est trop courte.",
|
||||
"error.contentTypeName.taken": "Ce nom existe déjà",
|
||||
"error.attribute.taken": "Ce champ existe déjà",
|
||||
"error.attribute.key.taken": "Cette valeur existe déjà",
|
||||
"error.attribute.sameKeyAndName": "Ne peuvent pas être égaux",
|
||||
"error.validation.minSupMax": "Ne peut pas être plus grand",
|
||||
|
||||
"popUpWarning.button.cancel": "Annuler",
|
||||
"popUpWarning.button.confirm": "Confirmer",
|
||||
"popUpWarning.title": "Confirmation requise",
|
||||
|
@ -0,0 +1,96 @@
|
||||
import { forEach, isObject, isArray, map, mapKeys, includes, reject, isEmpty, findIndex, isUndefined } from 'lodash';
|
||||
|
||||
/* eslint-disable consistent-return */
|
||||
export function getValidationsFromForm(form, formValidations) {
|
||||
map(form, (value, key) => {
|
||||
|
||||
// Check if the object
|
||||
if (isObject(value) && !isArray(value)) {
|
||||
forEach(value, (subValue) => {
|
||||
// Check if it has nestedInputs
|
||||
if (isArray(subValue) && value.type !== 'select') {
|
||||
return getValidationsFromForm(subValue, formValidations);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (isArray(value) && value.type !== 'select') {
|
||||
return getValidationsFromForm(form[key], formValidations);
|
||||
}
|
||||
|
||||
|
||||
// Push the target and the validation
|
||||
if (value.name) {
|
||||
formValidations.push({ name: value.name, validations: value.validations });
|
||||
}
|
||||
});
|
||||
|
||||
return formValidations;
|
||||
}
|
||||
|
||||
|
||||
export function checkFormValidity(formData, formValidations) {
|
||||
const errors = [];
|
||||
forEach(formData, (value, key) => {
|
||||
const validationValue = formValidations[findIndex(formValidations, ['name', key])];
|
||||
|
||||
if (!isUndefined(validationValue)) {
|
||||
const inputErrors = validate(value, validationValue.validations);
|
||||
if (!isEmpty(inputErrors)) {
|
||||
errors.push({ name: key, errors: inputErrors });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
function validate(value, validations) {
|
||||
let errors = [];
|
||||
// Handle i18n
|
||||
const requiredError = { id: 'content-manager.error.validation.required' };
|
||||
mapKeys(validations, (validationValue, validationKey) => {
|
||||
switch (validationKey) {
|
||||
case 'max':
|
||||
if (parseInt(value, 10) > validationValue) {
|
||||
errors.push({ id: 'content-manager.error.validation.max' });
|
||||
}
|
||||
break;
|
||||
case 'min':
|
||||
if (parseInt(value, 10) < validationValue) {
|
||||
errors.push({ id: 'content-manager.error.validation.min' });
|
||||
}
|
||||
break;
|
||||
case 'maxLength':
|
||||
if (value.length > validationValue) {
|
||||
errors.push({ id: 'content-manager.error.validation.maxLength' });
|
||||
}
|
||||
break;
|
||||
case 'minLength':
|
||||
if (value.length < validationValue) {
|
||||
errors.push({ id: 'content-manager.error.validation.minLength' });
|
||||
}
|
||||
break;
|
||||
case 'required':
|
||||
if (value.length === 0) {
|
||||
errors.push({ id: 'content-manager.error.validation.required' });
|
||||
}
|
||||
break;
|
||||
case 'regex':
|
||||
if (!new RegExp(validationValue).test(value)) {
|
||||
errors.push({ id: 'content-manager.error.validation.regex' });
|
||||
}
|
||||
break;
|
||||
default:
|
||||
errors = [];
|
||||
}
|
||||
});
|
||||
|
||||
if (includes(errors, requiredError)) {
|
||||
errors = reject(errors, (error) => error !== requiredError);
|
||||
}
|
||||
return errors;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user