mirror of
https://github.com/strapi/strapi.git
synced 2025-09-18 13:02:18 +00:00
Merge branch 'master' into enhancement/database-uri
This commit is contained in:
commit
e963ee1414
@ -15,6 +15,9 @@ import InputDescription from 'components/InputDescription';
|
||||
import InputErrors from 'components/InputErrors';
|
||||
import InputAddon from 'components/InputAddon';
|
||||
|
||||
// Utils
|
||||
import validateInput from 'utils/inputsValidations';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
class InputAddonWithErrors extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||
@ -24,7 +27,7 @@ class InputAddonWithErrors extends React.Component { // eslint-disable-line reac
|
||||
const { value, errors } = this.props;
|
||||
|
||||
// Prevent the input from displaying an error when the user enters and leaves without filling it
|
||||
if (value && !isEmpty(value)) {
|
||||
if (!isEmpty(value)) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
|
||||
@ -35,6 +38,11 @@ class InputAddonWithErrors extends React.Component { // eslint-disable-line reac
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
// Show required error if the input's value is received after the compo is mounted
|
||||
if (!isEmpty(nextProps.value) && !this.state.hasInitialValue) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
|
||||
// Check if errors have been updated during validations
|
||||
if (nextProps.didCheckErrors !== this.props.didCheckErrors) {
|
||||
// Remove from the state the errors that have already been set
|
||||
@ -50,7 +58,7 @@ class InputAddonWithErrors extends React.Component { // eslint-disable-line reac
|
||||
handleBlur = ({ target }) => {
|
||||
// Prevent from displaying error if the input is initially isEmpty
|
||||
if (!isEmpty(target.value) || this.state.hasInitialValue) {
|
||||
const errors = this.validate(target.value);
|
||||
const errors = validateInput(target.value, this.props.validations);
|
||||
this.setState({ errors, hasInitialValue: true });
|
||||
}
|
||||
}
|
||||
@ -135,48 +143,6 @@ class InputAddonWithErrors extends React.Component { // eslint-disable-line reac
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
validate = (value) => {
|
||||
const requiredError = { id: 'components.Input.error.validation.required' };
|
||||
let errors = [];
|
||||
|
||||
mapKeys(this.props.validations, (validationValue, validationKey) => {
|
||||
switch (validationKey) {
|
||||
case 'maxLength': {
|
||||
if (value.length > validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.maxLength' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'minLength': {
|
||||
if (value.length < validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.minLength' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'required': {
|
||||
if (value.length === 0) {
|
||||
errors.push({ id: 'components.Input.error.validation.required' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'regex': {
|
||||
if (!new RegExp(validationValue).test(value)) {
|
||||
errors.push({ id: 'components.Input.error.validation.regex' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
errors = [];
|
||||
}
|
||||
});
|
||||
|
||||
if (includes(errors, requiredError)) {
|
||||
errors = reject(errors, (error) => error !== requiredError);
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
|
||||
InputAddonWithErrors.defaultProps = {
|
||||
|
@ -15,6 +15,9 @@ import InputDescription from 'components/InputDescription';
|
||||
import InputErrors from 'components/InputErrors';
|
||||
import InputDate from 'components/InputDate';
|
||||
|
||||
// Utils
|
||||
import validateInput from 'utils/inputsValidations';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
class InputDateWithErrors extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||
@ -24,7 +27,7 @@ class InputDateWithErrors extends React.Component { // eslint-disable-line react
|
||||
const { value, errors } = this.props;
|
||||
|
||||
// Prevent the input from displaying an error when the user enters and leaves without filling it
|
||||
if (value && !isEmpty(value)) {
|
||||
if (!isEmpty(value)) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
|
||||
@ -35,6 +38,11 @@ class InputDateWithErrors extends React.Component { // eslint-disable-line react
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
// Show required error if the input's value is received after the compo is mounted
|
||||
if (!isEmpty(nextProps.value) && !this.state.hasInitialValue) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
|
||||
// Check if errors have been updated during validations
|
||||
if (nextProps.didCheckErrors !== this.props.didCheckErrors) {
|
||||
// Remove from the state the errors that have already been set
|
||||
@ -50,7 +58,7 @@ class InputDateWithErrors extends React.Component { // eslint-disable-line react
|
||||
handleBlur = ({ target }) => {
|
||||
// Prevent from displaying error if the input is initially isEmpty
|
||||
if (!isEmpty(get(target, 'value')) || this.state.hasInitialValue) {
|
||||
const errors = this.validate(target.value);
|
||||
const errors = validateInput(target.value, this.props.validations);
|
||||
this.setState({ errors, hasInitialValue: true });
|
||||
}
|
||||
}
|
||||
@ -133,30 +141,6 @@ class InputDateWithErrors extends React.Component { // eslint-disable-line react
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
validate = (value) => {
|
||||
const requiredError = { id: 'components.Input.error.validation.required' };
|
||||
let errors = [];
|
||||
|
||||
mapKeys(this.props.validations, (validationValue, validationKey) => {
|
||||
switch (validationKey) {
|
||||
case 'required': {
|
||||
if (value.length === 0) {
|
||||
errors.push({ id: 'components.Input.error.validation.required' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
errors = [];
|
||||
}
|
||||
});
|
||||
|
||||
if (includes(errors, requiredError)) {
|
||||
errors = reject(errors, (error) => error !== requiredError);
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
|
||||
InputDateWithErrors.defaultProps = {
|
||||
|
@ -15,6 +15,9 @@ import InputDescription from 'components/InputDescription';
|
||||
import InputErrors from 'components/InputErrors';
|
||||
import InputEmail from 'components/InputEmail';
|
||||
|
||||
// Utils
|
||||
import validateInput from 'utils/inputsValidations';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
class InputEmailWithErrors extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||
@ -24,7 +27,7 @@ class InputEmailWithErrors extends React.Component { // eslint-disable-line reac
|
||||
const { value, errors } = this.props;
|
||||
|
||||
// Prevent the input from displaying an error when the user enters and leaves without filling it
|
||||
if (value && !isEmpty(value)) {
|
||||
if (!isEmpty(value)) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
|
||||
@ -35,6 +38,11 @@ class InputEmailWithErrors extends React.Component { // eslint-disable-line reac
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
// Show required error if the input's value is received after the compo is mounted
|
||||
if (!isEmpty(nextProps.value) && !this.state.hasInitialValue) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
|
||||
// Check if errors have been updated during validations
|
||||
if (nextProps.didCheckErrors !== this.props.didCheckErrors) {
|
||||
// Remove from the state the errors that have already been set
|
||||
@ -50,7 +58,7 @@ class InputEmailWithErrors extends React.Component { // eslint-disable-line reac
|
||||
handleBlur = ({ target }) => {
|
||||
// Prevent from displaying error if the input is initially isEmpty
|
||||
if (!isEmpty(target.value) || this.state.hasInitialValue) {
|
||||
const errors = this.validate(target.value);
|
||||
const errors = validateInput(target.value, this.props.validations, 'email');
|
||||
this.setState({ errors, hasInitialValue: true });
|
||||
}
|
||||
}
|
||||
@ -131,53 +139,6 @@ class InputEmailWithErrors extends React.Component { // eslint-disable-line reac
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
validate = (value) => {
|
||||
const emailRegex = new RegExp(/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/);
|
||||
const requiredError = { id: 'components.Input.error.validation.required' };
|
||||
let errors = [];
|
||||
|
||||
mapKeys(this.props.validations, (validationValue, validationKey) => {
|
||||
switch (validationKey) {
|
||||
case 'maxLength': {
|
||||
if (value.length > validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.maxLength' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'minLength': {
|
||||
if (value.length < validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.minLength' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'required': {
|
||||
if (value.length === 0) {
|
||||
errors.push({ id: 'components.Input.error.validation.required' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'regex': {
|
||||
if (!new RegExp(validationValue).test(value)) {
|
||||
errors.push({ id: 'components.Input.error.validation.regex' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
errors = [];
|
||||
}
|
||||
});
|
||||
|
||||
if (!emailRegex.test(value)) {
|
||||
errors.push({ id: 'components.Input.error.validation.email' });
|
||||
}
|
||||
|
||||
if (includes(errors, requiredError)) {
|
||||
errors = reject(errors, (error) => error !== requiredError);
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
|
||||
InputEmailWithErrors.defaultProps = {
|
||||
|
@ -9,6 +9,9 @@ import InputDescription from 'components/InputDescription';
|
||||
import InputErrors from 'components/InputErrors';
|
||||
import InputNumber from 'components/InputNumber';
|
||||
|
||||
// Utils
|
||||
import validateInput from 'utils/inputsValidations';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
class InputNumberWithErrors extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||
@ -18,7 +21,7 @@ class InputNumberWithErrors extends React.Component { // eslint-disable-line rea
|
||||
const { value, errors } = this.props;
|
||||
|
||||
// Prevent the input from displaying an error when the user enters and leaves without filling it
|
||||
if (value && !isEmpty(value)) {
|
||||
if (!isEmpty(value)) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
|
||||
@ -29,6 +32,11 @@ class InputNumberWithErrors extends React.Component { // eslint-disable-line rea
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
// Show required error if the input's value is received after the compo is mounted
|
||||
if (!isEmpty(nextProps.value) && !this.state.hasInitialValue) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
|
||||
// Check if errors have been updated during validations
|
||||
if (nextProps.didCheckErrors !== this.props.didCheckErrors) {
|
||||
// Remove from the state the errors that have already been set
|
||||
@ -44,7 +52,7 @@ class InputNumberWithErrors extends React.Component { // eslint-disable-line rea
|
||||
handleBlur = ({ target }) => {
|
||||
// Prevent from displaying error if the input is initially isEmpty
|
||||
if (!isEmpty(target.value) || this.state.hasInitialValue) {
|
||||
const errors = this.validate(target.value);
|
||||
const errors = validateInput(target.value, this.props.validations);
|
||||
this.setState({ errors, hasInitialValue: true });
|
||||
}
|
||||
}
|
||||
@ -127,48 +135,6 @@ class InputNumberWithErrors extends React.Component { // eslint-disable-line rea
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
validate = (value) => {
|
||||
const requiredError = { id: 'components.Input.error.validation.required' };
|
||||
let errors = [];
|
||||
|
||||
mapKeys(this.props.validations, (validationValue, validationKey) => {
|
||||
switch (validationKey) {
|
||||
case 'max': {
|
||||
if (parseInt(value, 10) > validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.max' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'min': {
|
||||
if (parseInt(value, 10) < validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.min' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'required': {
|
||||
if (value.length === 0) {
|
||||
errors.push({ id: 'components.Input.error.validation.required' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'regex': {
|
||||
if (!new RegExp(validationValue).test(value)) {
|
||||
errors.push({ id: 'components.Input.error.validation.regex' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
errors = [];
|
||||
}
|
||||
});
|
||||
|
||||
if (includes(errors, requiredError)) {
|
||||
errors = reject(errors, (error) => error !== requiredError);
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
|
||||
InputNumberWithErrors.defaultProps = {
|
||||
|
@ -15,6 +15,9 @@ import InputDescription from 'components/InputDescription';
|
||||
import InputErrors from 'components/InputErrors';
|
||||
import InputPassword from 'components/InputPassword';
|
||||
|
||||
// Utils
|
||||
import validateInput from 'utils/inputsValidations';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
class InputPasswordWithErrors extends React.Component {
|
||||
@ -24,7 +27,7 @@ class InputPasswordWithErrors extends React.Component {
|
||||
const { value, errors } = this.props;
|
||||
|
||||
// Prevent the input from displaying an error when the user enters and leaves without filling it
|
||||
if (value && !isEmpty(value)) {
|
||||
if (!isEmpty(value)) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
|
||||
@ -35,6 +38,11 @@ class InputPasswordWithErrors extends React.Component {
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
// Show required error if the input's value is received after the compo is mounted
|
||||
if (!isEmpty(nextProps.value) && !this.state.hasInitialValue) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
|
||||
// Check if errors have been updated during validations
|
||||
if (nextProps.didCheckErrors !== this.props.didCheckErrors) {
|
||||
// Remove from the state the errors that have already been set
|
||||
@ -50,7 +58,7 @@ class InputPasswordWithErrors extends React.Component {
|
||||
handleBlur = ({ target }) => {
|
||||
// Prevent from displaying error if the input is initially isEmpty
|
||||
if (!isEmpty(target.value) || this.state.hasInitialValue) {
|
||||
const errors = this.validate(target.value);
|
||||
const errors = validateInput(target.value, this.props.validations);
|
||||
this.setState({ errors, hasInitialValue: true });
|
||||
}
|
||||
}
|
||||
@ -120,48 +128,6 @@ class InputPasswordWithErrors extends React.Component {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
validate = (value) => {
|
||||
const requiredError = { id: 'components.Input.error.validation.required' };
|
||||
let errors = [];
|
||||
|
||||
mapKeys(this.props.validations, (validationValue, validationKey) => {
|
||||
switch (validationKey) {
|
||||
case 'maxLength': {
|
||||
if (value.length > validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.maxLength' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'minLength': {
|
||||
if (value.length < validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.minLength' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'required': {
|
||||
if (value.length === 0) {
|
||||
errors.push({ id: 'components.Input.error.validation.required' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'regex': {
|
||||
if (!new RegExp(validationValue).test(value)) {
|
||||
errors.push({ id: 'components.Input.error.validation.regex' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
errors = [];
|
||||
}
|
||||
});
|
||||
|
||||
if (includes(errors, requiredError)) {
|
||||
errors = reject(errors, (error) => error !== requiredError);
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
|
||||
InputPasswordWithErrors.defaultProps = {
|
||||
|
@ -15,6 +15,9 @@ import InputDescription from 'components/InputDescription';
|
||||
import InputErrors from 'components/InputErrors';
|
||||
import InputSearch from 'components/InputSearch';
|
||||
|
||||
// Utils
|
||||
import validateInput from 'utils/inputsValidations';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
class InputSearchWithErrors extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||
@ -24,7 +27,7 @@ class InputSearchWithErrors extends React.Component { // eslint-disable-line rea
|
||||
const { value, errors } = this.props;
|
||||
|
||||
// Prevent the input from displaying an error when the user enters and leaves without filling it
|
||||
if (value && !isEmpty(value)) {
|
||||
if (!isEmpty(value)) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
|
||||
@ -35,6 +38,11 @@ class InputSearchWithErrors extends React.Component { // eslint-disable-line rea
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
// Show required error if the input's value is received after the compo is mounted
|
||||
if (!isEmpty(nextProps.value) && !this.state.hasInitialValue) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
|
||||
// Check if errors have been updated during validations
|
||||
if (nextProps.didCheckErrors !== this.props.didCheckErrors) {
|
||||
// Remove from the state the errors that have already been set
|
||||
@ -50,7 +58,7 @@ class InputSearchWithErrors extends React.Component { // eslint-disable-line rea
|
||||
handleBlur = ({ target }) => {
|
||||
// Prevent from displaying error if the input is initially isEmpty
|
||||
if (!isEmpty(target.value) || this.state.hasInitialValue) {
|
||||
const errors = this.validate(target.value);
|
||||
const errors = validateInput(target.value, this.props.validations);
|
||||
this.setState({ errors, hasInitialValue: true });
|
||||
}
|
||||
}
|
||||
@ -131,48 +139,6 @@ class InputSearchWithErrors extends React.Component { // eslint-disable-line rea
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
validate = (value) => {
|
||||
const requiredError = { id: 'components.Input.error.validation.required' };
|
||||
let errors = [];
|
||||
|
||||
mapKeys(this.props.validations, (validationValue, validationKey) => {
|
||||
switch (validationKey) {
|
||||
case 'maxLength': {
|
||||
if (value.length > validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.maxLength' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'minLength': {
|
||||
if (value.length < validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.minLength' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'required': {
|
||||
if (value.length === 0) {
|
||||
errors.push({ id: 'components.Input.error.validation.required' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'regex': {
|
||||
if (!new RegExp(validationValue).test(value)) {
|
||||
errors.push({ id: 'components.Input.error.validation.regex' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
errors = [];
|
||||
}
|
||||
});
|
||||
|
||||
if (includes(errors, requiredError)) {
|
||||
errors = reject(errors, (error) => error !== requiredError);
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
|
||||
InputSearchWithErrors.defaultProps = {
|
||||
|
@ -9,6 +9,9 @@ import InputDescription from 'components/InputDescription';
|
||||
import InputErrors from 'components/InputErrors';
|
||||
import InputTextArea from 'components/InputTextArea';
|
||||
|
||||
// Utils
|
||||
import validateInput from 'utils/inputsValidations';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
class InputTextAreaWithErrors extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||
@ -18,7 +21,7 @@ class InputTextAreaWithErrors extends React.Component { // eslint-disable-line r
|
||||
const { value, errors } = this.props;
|
||||
|
||||
// Prevent the input from displaying an error when the user enters and leaves without filling it
|
||||
if (value && !isEmpty(value)) {
|
||||
if (!isEmpty(value)) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
|
||||
@ -29,6 +32,11 @@ class InputTextAreaWithErrors extends React.Component { // eslint-disable-line r
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
// Show required error if the input's value is received after the compo is mounted
|
||||
if (!isEmpty(nextProps.value) && !this.state.hasInitialValue) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
|
||||
// Check if errors have been updated during validations
|
||||
if (nextProps.didCheckErrors !== this.props.didCheckErrors) {
|
||||
// Remove from the state the errors that have already been set
|
||||
@ -44,7 +52,7 @@ class InputTextAreaWithErrors extends React.Component { // eslint-disable-line r
|
||||
handleBlur = ({ target }) => {
|
||||
// Prevent from displaying error if the input is initially isEmpty
|
||||
if (!isEmpty(target.value) || this.state.hasInitialValue) {
|
||||
const errors = this.validate(target.value);
|
||||
const errors = validateInput(target.value, this.props.validations);
|
||||
this.setState({ errors, hasInitialValue: true });
|
||||
}
|
||||
}
|
||||
@ -127,48 +135,6 @@ class InputTextAreaWithErrors extends React.Component { // eslint-disable-line r
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
validate = (value) => {
|
||||
const requiredError = { id: 'components.Input.error.validation.required' };
|
||||
let errors = [];
|
||||
|
||||
mapKeys(this.props.validations, (validationValue, validationKey) => {
|
||||
switch (validationKey) {
|
||||
case 'maxLength': {
|
||||
if (value.length > validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.maxLength' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'minLength': {
|
||||
if (value.length < validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.minLength' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'required': {
|
||||
if (value.length === 0) {
|
||||
errors.push({ id: 'components.Input.error.validation.required' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'regex': {
|
||||
if (!new RegExp(validationValue).test(value)) {
|
||||
errors.push({ id: 'components.Input.error.validation.regex' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
errors = [];
|
||||
}
|
||||
});
|
||||
|
||||
if (includes(errors, requiredError)) {
|
||||
errors = reject(errors, (error) => error !== requiredError);
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
|
||||
InputTextAreaWithErrors.defaultProps = {
|
||||
|
@ -9,6 +9,9 @@ import InputDescription from 'components/InputDescription';
|
||||
import InputErrors from 'components/InputErrors';
|
||||
import InputText from 'components/InputText';
|
||||
|
||||
// Utils
|
||||
import validateInput from 'utils/inputsValidations';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
class InputTextWithErrors extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||
@ -18,7 +21,7 @@ class InputTextWithErrors extends React.Component { // eslint-disable-line react
|
||||
const { value, errors } = this.props;
|
||||
|
||||
// Prevent the input from displaying an error when the user enters and leaves without filling it
|
||||
if (value && !isEmpty(value)) {
|
||||
if (!isEmpty(value)) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
|
||||
@ -29,6 +32,11 @@ class InputTextWithErrors extends React.Component { // eslint-disable-line react
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
// Show required error if the input's value is received after the compo is mounted
|
||||
if (!isEmpty(nextProps.value) && !this.state.hasInitialValue) {
|
||||
this.setState({ hasInitialValue: true });
|
||||
}
|
||||
|
||||
// Check if errors have been updated during validations
|
||||
if (nextProps.didCheckErrors !== this.props.didCheckErrors) {
|
||||
// Remove from the state the errors that have already been set
|
||||
@ -44,7 +52,7 @@ class InputTextWithErrors extends React.Component { // eslint-disable-line react
|
||||
handleBlur = ({ target }) => {
|
||||
// Prevent from displaying error if the input is initially isEmpty
|
||||
if (!isEmpty(target.value) || this.state.hasInitialValue) {
|
||||
const errors = this.validate(target.value);
|
||||
const errors = validateInput(target.value, this.props.validations);
|
||||
this.setState({ errors, hasInitialValue: true });
|
||||
}
|
||||
}
|
||||
@ -127,48 +135,6 @@ class InputTextWithErrors extends React.Component { // eslint-disable-line react
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
validate = (value) => {
|
||||
const requiredError = { id: 'components.Input.error.validation.required' };
|
||||
let errors = [];
|
||||
|
||||
mapKeys(this.props.validations, (validationValue, validationKey) => {
|
||||
switch (validationKey) {
|
||||
case 'maxLength': {
|
||||
if (value.length > validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.maxLength' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'minLength': {
|
||||
if (value.length < validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.minLength' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'required': {
|
||||
if (value.length === 0) {
|
||||
errors.push({ id: 'components.Input.error.validation.required' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'regex': {
|
||||
if (!new RegExp(validationValue).test(value)) {
|
||||
errors.push({ id: 'components.Input.error.validation.regex' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
errors = [];
|
||||
}
|
||||
});
|
||||
|
||||
if (includes(errors, requiredError)) {
|
||||
errors = reject(errors, (error) => error !== requiredError);
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
|
||||
InputTextWithErrors.defaultProps = {
|
||||
|
@ -0,0 +1,64 @@
|
||||
import { includes, mapKeys, reject } from 'lodash';
|
||||
/**
|
||||
* [validateInput description]
|
||||
* @param {String || Number} value Input's value
|
||||
* @param {Object} inputValidations
|
||||
* @param {String} [type='text'] Optionnal: the input's type only for email
|
||||
* @return {Array} Array of errors to be displayed
|
||||
*/
|
||||
const validateInput = (value, inputValidations = {}, type = 'text') => {
|
||||
let errors = [];
|
||||
|
||||
const emailRegex = new RegExp(/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/);
|
||||
// handle i18n
|
||||
const requiredError = { id: 'components.Input.error.validation.required' };
|
||||
|
||||
mapKeys(inputValidations, (validationValue, validationKey) => {
|
||||
switch (validationKey) {
|
||||
case 'max':
|
||||
if (parseInt(value, 10) > validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.max' });
|
||||
}
|
||||
break;
|
||||
case 'maxLength':
|
||||
if (value.length > validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.maxLength' });
|
||||
}
|
||||
break;
|
||||
case 'min':
|
||||
if (parseInt(value, 10) < validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.min' });
|
||||
}
|
||||
break;
|
||||
case 'minLength':
|
||||
if (value.length < validationValue) {
|
||||
errors.push({ id: 'components.Input.error.validation.minLength' });
|
||||
}
|
||||
break;
|
||||
case 'required':
|
||||
if (value.length === 0) {
|
||||
errors.push({ id: 'components.Input.error.validation.required' });
|
||||
}
|
||||
break;
|
||||
case 'regex':
|
||||
if (!new RegExp(validationValue).test(value)) {
|
||||
errors.push({ id: 'components.Input.error.validation.regex' });
|
||||
}
|
||||
break;
|
||||
default:
|
||||
errors = [];
|
||||
}
|
||||
});
|
||||
|
||||
if (type === 'email' && !emailRegex.test(value)) {
|
||||
errors.push({ id: 'components.Input.error.validation.email' });
|
||||
}
|
||||
|
||||
if (includes(errors, requiredError)) {
|
||||
errors = reject(errors, (error) => error !== requiredError);
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
export default validateInput;
|
@ -10,7 +10,7 @@ import { get, map, some } from 'lodash';
|
||||
import cn from 'classnames';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import InputCheckbox from 'components/InputCheckbox';
|
||||
import InputCheckbox from 'components/InputCheckboxPlugin';
|
||||
import styles from './styles.scss';
|
||||
|
||||
class Controller extends React.Component {
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
*
|
||||
* InputCheckbox
|
||||
* InputCheckboxPlugin
|
||||
*
|
||||
*/
|
||||
|
||||
@ -10,7 +10,7 @@ import cn from 'classnames';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
class InputCheckbox extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||
class InputCheckboxPlugin extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||
state = { showBackground: false, showCog: false };
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
@ -91,19 +91,19 @@ class InputCheckbox extends React.Component { // eslint-disable-line react/prefe
|
||||
}
|
||||
}
|
||||
|
||||
InputCheckbox.contextTypes = {
|
||||
InputCheckboxPlugin.contextTypes = {
|
||||
onChange: PropTypes.func.isRequired,
|
||||
resetShouldDisplayPoliciesHint: PropTypes.func.isRequired,
|
||||
setInputPoliciesPath: PropTypes.func.isRequired,
|
||||
setShouldDisplayPolicieshint: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
InputCheckbox.defaultProps = {
|
||||
InputCheckboxPlugin.defaultProps = {
|
||||
label: '',
|
||||
value: false,
|
||||
};
|
||||
|
||||
InputCheckbox.propTypes = {
|
||||
InputCheckboxPlugin.propTypes = {
|
||||
inputSelected: PropTypes.string.isRequired,
|
||||
isOpen: PropTypes.bool.isRequired,
|
||||
label: PropTypes.string,
|
||||
@ -112,4 +112,4 @@ InputCheckbox.propTypes = {
|
||||
value: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default InputCheckbox;
|
||||
export default InputCheckboxPlugin;
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
*
|
||||
* InputSearch
|
||||
* InputSearchContainer
|
||||
*
|
||||
*/
|
||||
|
||||
@ -10,15 +10,17 @@ import { findIndex, has, includes, isEmpty, map, toLower } from 'lodash';
|
||||
import cn from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import Label from 'components/Label';
|
||||
import InputSearchLi from 'components/InputSearchLi';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
class InputSearch extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||
class InputSearchContainer extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||
state = {
|
||||
errors: [],
|
||||
filteredUsers: this.props.values,
|
||||
isAdding: false,
|
||||
isFocused: false,
|
||||
users: this.props.values,
|
||||
value: '',
|
||||
autoFocus: false,
|
||||
@ -38,6 +40,8 @@ class InputSearch extends React.Component { // eslint-disable-line react/prefer-
|
||||
}
|
||||
}
|
||||
|
||||
handleBlur = () => this.setState({ isFocused: !this.state.isFocused });
|
||||
|
||||
handleChange = ({ target }) => {
|
||||
const filteredUsers = isEmpty(target.value) ?
|
||||
this.state.users
|
||||
@ -54,6 +58,8 @@ class InputSearch extends React.Component { // eslint-disable-line react/prefer-
|
||||
this.setState({ value: target.value, filteredUsers });
|
||||
}
|
||||
|
||||
handleFocus = () => this.setState({ isFocused: !this.state.isFocused });
|
||||
|
||||
handleClick = (item) => {
|
||||
if (this.state.isAdding) {
|
||||
const id = has(item, '_id') ? '_id' : 'id';
|
||||
@ -76,18 +82,18 @@ class InputSearch extends React.Component { // eslint-disable-line react/prefer-
|
||||
render() {
|
||||
return (
|
||||
<div className={cn(styles.inputSearch, 'col-md-6')}>
|
||||
<label htmlFor={this.props.name}>
|
||||
<FormattedMessage id={this.props.label} values={this.props.labelValues} />
|
||||
</label>
|
||||
<Label htmlFor={this.props.name} message={this.props.label} />
|
||||
<div className={cn('input-group')}>
|
||||
<span className={cn('input-group-addon', styles.addon)} />
|
||||
<span className={cn('input-group-addon', styles.addon, this.state.isFocused && styles.addonFocus,)} />
|
||||
<FormattedMessage id="users-permissions.InputSearch.placeholder">
|
||||
{(message) => (
|
||||
<input
|
||||
className={cn('form-control', !isEmpty(this.state.errors) ? 'is-invalid': '')}
|
||||
id={this.props.name}
|
||||
name={this.props.name}
|
||||
onBlur={this.handleBlur}
|
||||
onChange={this.handleChange}
|
||||
onFocus={this.handleFocus}
|
||||
value={this.state.value}
|
||||
placeholder={message}
|
||||
type="text"
|
||||
@ -96,7 +102,7 @@ class InputSearch extends React.Component { // eslint-disable-line react/prefer-
|
||||
)}
|
||||
</FormattedMessage>
|
||||
</div>
|
||||
<div className={styles.ulContainer}>
|
||||
<div className={cn(styles.ulContainer, this.state.isFocused && styles.ulFocused)}>
|
||||
<ul>
|
||||
{map(this.state.filteredUsers, (user) => (
|
||||
<InputSearchLi
|
||||
@ -113,7 +119,7 @@ class InputSearch extends React.Component { // eslint-disable-line react/prefer-
|
||||
}
|
||||
}
|
||||
|
||||
InputSearch.defaultProps = {
|
||||
InputSearchContainer.defaultProps = {
|
||||
labelValues: {
|
||||
number: 0,
|
||||
},
|
||||
@ -121,13 +127,15 @@ InputSearch.defaultProps = {
|
||||
values: [],
|
||||
};
|
||||
|
||||
InputSearch.propTypes = {
|
||||
InputSearchContainer.propTypes = {
|
||||
didDeleteUser: PropTypes.bool.isRequired,
|
||||
didFetchUsers: PropTypes.bool.isRequired,
|
||||
didGetUsers: PropTypes.bool.isRequired,
|
||||
getUser: PropTypes.func.isRequired,
|
||||
label: PropTypes.string.isRequired,
|
||||
labelValues: PropTypes.object,
|
||||
label: PropTypes.shape({
|
||||
id: PropTypes.string,
|
||||
params: PropTypes.object,
|
||||
}).isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
onClickAdd: PropTypes.func.isRequired,
|
||||
onClickDelete: PropTypes.func.isRequired,
|
||||
@ -135,4 +143,4 @@ InputSearch.propTypes = {
|
||||
values: PropTypes.array,
|
||||
};
|
||||
|
||||
export default InputSearch;
|
||||
export default InputSearchContainer;
|
@ -4,6 +4,7 @@
|
||||
margin-top: .9rem;
|
||||
background-color: rgba(16, 22, 34, 0.02);
|
||||
border: 1px solid #E3E9F3;
|
||||
border-right: 0;
|
||||
border-bottom: 0px;
|
||||
border-radius: 0.25rem;
|
||||
border-bottom-left-radius: 0!important;
|
||||
@ -46,6 +47,7 @@
|
||||
padding-left: 1rem;
|
||||
background-size: 0 !important;
|
||||
border: 1px solid #E3E9F3;
|
||||
border-left: 0;
|
||||
border-bottom: 0px;
|
||||
border-radius: 0.25rem;
|
||||
border-bottom-right-radius: 0;
|
||||
@ -72,3 +74,12 @@
|
||||
padding: 1px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.addonFocus {
|
||||
border-color: #78caff;
|
||||
border-right: 0;
|
||||
}
|
||||
|
||||
.ulFocused {
|
||||
border-color: #78caff;
|
||||
}
|
@ -11,7 +11,7 @@ import { FormattedMessage } from 'react-intl';
|
||||
import { get, isEmpty, map, takeRight, toLower, without } from 'lodash';
|
||||
|
||||
import BoundRoute from 'components/BoundRoute';
|
||||
import Input from 'components/Input';
|
||||
import Input from 'components/InputsIndex';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
@ -36,7 +36,7 @@ class Policies extends React.Component { // eslint-disable-line react/prefer-sta
|
||||
{!this.props.shouldDisplayPoliciesHint ? (
|
||||
<Input
|
||||
customBootstrapClass="col-md-12"
|
||||
label="users-permissions.Policies.InputSelect.label"
|
||||
label={{ id: 'users-permissions.Policies.InputSelect.label' }}
|
||||
name={this.props.inputSelectName}
|
||||
onChange={this.handleChange}
|
||||
selectOptions={this.props.selectOptions}
|
||||
|
@ -3,7 +3,9 @@
|
||||
"forgot-password": [
|
||||
{
|
||||
"customBootstrapClass": "col-md-12",
|
||||
"label": "users-permissions.Auth.form.forgot-password.email.label",
|
||||
"label": {
|
||||
"id": "users-permissions.Auth.form.forgot-password.email.label"
|
||||
},
|
||||
"name": "email",
|
||||
"type": "email",
|
||||
"placeholder": "users-permissions.Auth.form.forgot-password.email.placeholder"
|
||||
@ -12,20 +14,26 @@
|
||||
"login": [
|
||||
{
|
||||
"customBootstrapClass": "col-md-12",
|
||||
"label": "users-permissions.Auth.form.login.username.label",
|
||||
"label": {
|
||||
"id": "users-permissions.Auth.form.login.username.label"
|
||||
},
|
||||
"name": "identifier",
|
||||
"type": "text",
|
||||
"placeholder": "users-permissions.Auth.form.login.username.placeholder"
|
||||
},
|
||||
{
|
||||
"customBootstrapClass": "col-md-12",
|
||||
"label": "users-permissions.Auth.form.login.password.label",
|
||||
"label": {
|
||||
"id": "users-permissions.Auth.form.login.password.label"
|
||||
},
|
||||
"name": "password",
|
||||
"type": "password"
|
||||
},
|
||||
{
|
||||
"customBootstrapClass": "col-md-6",
|
||||
"label": "users-permissions.Auth.form.login.rememberMe.label",
|
||||
"label": {
|
||||
"id": "users-permissions.Auth.form.login.rememberMe.label"
|
||||
},
|
||||
"name": "rememberMe",
|
||||
"type": "checkbox"
|
||||
}
|
||||
@ -33,26 +41,34 @@
|
||||
"register": [
|
||||
{
|
||||
"customBootstrapClass": "col-md-12",
|
||||
"label": "users-permissions.Auth.form.register.username.label",
|
||||
"label": {
|
||||
"id": "users-permissions.Auth.form.register.username.label"
|
||||
},
|
||||
"name": "username",
|
||||
"type": "text",
|
||||
"placeholder": "users-permissions.Auth.form.register.username.placeholder"
|
||||
},
|
||||
{
|
||||
"customBootstrapClass": "col-md-12",
|
||||
"label": "users-permissions.Auth.form.register.password.label",
|
||||
"label": {
|
||||
"id": "users-permissions.Auth.form.register.password.label"
|
||||
},
|
||||
"name": "password",
|
||||
"type": "password"
|
||||
},
|
||||
{
|
||||
"customBootstrapClass": "col-md-12",
|
||||
"label": "users-permissions.Auth.form.register.confirmPassword.label",
|
||||
"label": {
|
||||
"id": "users-permissions.Auth.form.register.confirmPassword.label"
|
||||
},
|
||||
"name": "confirmPassword",
|
||||
"type": "password"
|
||||
},
|
||||
{
|
||||
"customBootstrapClass": "col-md-12",
|
||||
"label": "users-permissions.Auth.form.register.email.label",
|
||||
"label": {
|
||||
"id": "users-permissions.Auth.form.register.email.label"
|
||||
},
|
||||
"name": "email",
|
||||
"placeholder": "users-permissions.Auth.form.register.email.placeholder",
|
||||
"type": "email"
|
||||
@ -63,7 +79,9 @@
|
||||
"customBootstrapClass": "col-md-12",
|
||||
"name": "email",
|
||||
"type": "email",
|
||||
"label": "users-permissions.Auth.form.register-success.email.label",
|
||||
"label": {
|
||||
"id": "users-permissions.Auth.form.register-success.email.label"
|
||||
},
|
||||
"placeholder": "users-permissions.Auth.form.register-success.email.placeholder"
|
||||
}
|
||||
],
|
||||
@ -72,13 +90,17 @@
|
||||
"customBootstrapClass": "col-md-12",
|
||||
"name": "password",
|
||||
"type": "password",
|
||||
"label": "users-permissions.Auth.form.register.password.label"
|
||||
"label": {
|
||||
"id": "users-permissions.Auth.form.register.password.label"
|
||||
}
|
||||
},
|
||||
{
|
||||
"customBootstrapClass": "col-md-12",
|
||||
"name": "passwordConfirmation",
|
||||
"type": "password",
|
||||
"label": "users-permissions.Auth.form.register.confirmPassword.label"
|
||||
"label": {
|
||||
"id": "users-permissions.Auth.form.register.confirmPassword.label"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ import LogoStrapi from 'assets/images/logo_strapi.png';
|
||||
|
||||
// Design
|
||||
import Button from 'components/Button';
|
||||
import Input from 'components/Input';
|
||||
import Input from 'components/InputsIndex';
|
||||
|
||||
// Utils
|
||||
import injectSaga from 'utils/injectSaga';
|
||||
@ -173,7 +173,7 @@ export class AuthPage extends React.Component { // eslint-disable-line react/pre
|
||||
didCheckErrors={this.props.didCheckErrors}
|
||||
errors={get(this.props.formErrors, [findIndex(this.props.formErrors, ['name', input.name]), 'errors'])}
|
||||
key={get(input, 'name')}
|
||||
label={this.props.match.params.authType === 'forgot-password' && this.props.submitSuccess? 'users-permissions.Auth.form.forgot-password.email.label.success' : get(input, 'label')}
|
||||
label={this.props.match.params.authType === 'forgot-password' && this.props.submitSuccess? { id: 'users-permissions.Auth.form.forgot-password.email.label.success' } : get(input, 'label')}
|
||||
name={get(input, 'name')}
|
||||
onChange={this.props.onChangeInput}
|
||||
placeholder={get(input, 'placeholder')}
|
||||
|
@ -15,8 +15,8 @@ import cn from 'classnames';
|
||||
|
||||
// Design
|
||||
import BackHeader from 'components/BackHeader';
|
||||
import Input from 'components/Input';
|
||||
import InputSearch from 'components/InputSearch';
|
||||
import Input from 'components/InputsIndex';
|
||||
import InputSearch from 'components/InputSearchContainer';
|
||||
import PluginHeader from 'components/PluginHeader';
|
||||
import Plugins from 'components/Plugins';
|
||||
import Policies from 'components/Policies';
|
||||
@ -159,7 +159,7 @@ export class EditPage extends React.Component { // eslint-disable-line react/pre
|
||||
customBootstrapClass="col-md-12"
|
||||
errors={get(this.props.editPage, ['formErrors', findIndex(this.props.editPage.formErrors, ['name', 'name']), 'errors'])}
|
||||
didCheckErrors={this.props.editPage.didCheckErrors}
|
||||
label="users-permissions.EditPage.form.roles.label.name"
|
||||
label={{ id: 'users-permissions.EditPage.form.roles.label.name' }}
|
||||
name="name"
|
||||
onChange={this.props.onChangeInput}
|
||||
type="text"
|
||||
@ -170,7 +170,7 @@ export class EditPage extends React.Component { // eslint-disable-line react/pre
|
||||
<div className="row">
|
||||
<Input
|
||||
customBootstrapClass="col-md-12"
|
||||
label="users-permissions.EditPage.form.roles.label.description"
|
||||
label={{ id: 'users-permissions.EditPage.form.roles.label.description' }}
|
||||
name="description"
|
||||
onChange={this.props.onChangeInput}
|
||||
type="textarea"
|
||||
@ -185,8 +185,12 @@ export class EditPage extends React.Component { // eslint-disable-line react/pre
|
||||
didFetchUsers={this.props.editPage.didFetchUsers}
|
||||
didGetUsers={this.props.editPage.didGetUsers}
|
||||
getUser={this.props.getUser}
|
||||
label="users-permissions.EditPage.form.roles.label.users"
|
||||
labelValues={{ number: size(get(this.props.editPage, ['modifiedData', 'users'])) }}
|
||||
label={{
|
||||
id: 'users-permissions.EditPage.form.roles.label.users',
|
||||
params: {
|
||||
number: size(get(this.props.editPage, ['modifiedData', 'users'])),
|
||||
},
|
||||
}}
|
||||
onClickAdd={this.props.onClickAdd}
|
||||
onClickDelete={this.props.onClickDelete}
|
||||
name="users"
|
||||
|
Loading…
x
Reference in New Issue
Block a user