feat(widget-list): add min max configuration (#4394)
This commit is contained in:
@ -15,7 +15,7 @@ import {
|
||||
getErrorMessageForTypedFieldAndValue,
|
||||
} from './typedListHelpers';
|
||||
import { ListItemTopBar, ObjectWidgetTopBar, colors, lengths } from 'netlify-cms-ui-default';
|
||||
import { stringTemplate } from 'netlify-cms-lib-widgets';
|
||||
import { stringTemplate, validations } from 'netlify-cms-lib-widgets';
|
||||
|
||||
function valueToString(value) {
|
||||
return value ? value.join(',').replace(/,([^\s]|$)/g, ', $1') : '';
|
||||
@ -261,6 +261,28 @@ export default class ListControl extends React.Component {
|
||||
} else {
|
||||
this.props.validate();
|
||||
}
|
||||
this.props.onValidateObject(this.props.forID, this.validateSize());
|
||||
};
|
||||
|
||||
validateSize = () => {
|
||||
const { field, value, t } = this.props;
|
||||
const min = field.get('min');
|
||||
const max = field.get('max');
|
||||
const required = field.get('required', true);
|
||||
|
||||
if (!required && !value?.size) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const error = validations.validateMinMax(
|
||||
t,
|
||||
field.get('label', field.get('name')),
|
||||
value,
|
||||
min,
|
||||
max,
|
||||
);
|
||||
|
||||
return error ? [error] : [];
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { render, fireEvent } from '@testing-library/react';
|
||||
import { fireEvent, render } from '@testing-library/react';
|
||||
import { fromJS } from 'immutable';
|
||||
import ListControl from '../ListControl';
|
||||
|
||||
@ -53,6 +53,7 @@ describe('ListControl', () => {
|
||||
path: 'posts/index.md',
|
||||
}),
|
||||
forID: 'forID',
|
||||
t: key => key,
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
@ -629,4 +630,158 @@ describe('ListControl', () => {
|
||||
mock.mockRestore();
|
||||
}
|
||||
});
|
||||
|
||||
it('should give validation error if below min elements', () => {
|
||||
const field = fromJS({
|
||||
name: 'list',
|
||||
label: 'List',
|
||||
collapsed: false,
|
||||
minimize_collapsed: true,
|
||||
required: true,
|
||||
min: 2,
|
||||
max: 3,
|
||||
fields: [{ label: 'String', name: 'string', widget: 'string' }],
|
||||
});
|
||||
const listControl = new ListControl({
|
||||
...props,
|
||||
field,
|
||||
value: fromJS([{ string: 'item 1' }]),
|
||||
});
|
||||
|
||||
listControl.validate();
|
||||
expect(props.onValidateObject).toHaveBeenCalledWith('forID', [
|
||||
{
|
||||
message: 'editor.editorControlPane.widget.rangeCount',
|
||||
type: 'RANGE',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should give min validation error if below min elements', () => {
|
||||
const field = fromJS({
|
||||
name: 'list',
|
||||
label: 'List',
|
||||
collapsed: false,
|
||||
minimize_collapsed: true,
|
||||
required: true,
|
||||
min: 2,
|
||||
fields: [{ label: 'String', name: 'string', widget: 'string' }],
|
||||
});
|
||||
const listControl = new ListControl({
|
||||
...props,
|
||||
field,
|
||||
value: fromJS([{ string: 'item 1' }]),
|
||||
});
|
||||
|
||||
listControl.validate();
|
||||
expect(props.onValidateObject).toHaveBeenCalledWith('forID', [
|
||||
{
|
||||
message: 'editor.editorControlPane.widget.rangeMin',
|
||||
type: 'RANGE',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should give validation error if above max elements', () => {
|
||||
const field = fromJS({
|
||||
name: 'list',
|
||||
label: 'List',
|
||||
collapsed: false,
|
||||
minimize_collapsed: true,
|
||||
required: true,
|
||||
min: 2,
|
||||
max: 3,
|
||||
fields: [{ label: 'String', name: 'string', widget: 'string' }],
|
||||
});
|
||||
const listControl = new ListControl({
|
||||
...props,
|
||||
field,
|
||||
value: fromJS([
|
||||
{ string: 'item 1' },
|
||||
{ string: 'item 2' },
|
||||
{ string: 'item 3' },
|
||||
{ string: 'item 4' },
|
||||
]),
|
||||
});
|
||||
|
||||
listControl.validate();
|
||||
expect(props.onValidateObject).toHaveBeenCalledWith('forID', [
|
||||
{
|
||||
message: 'editor.editorControlPane.widget.rangeCount',
|
||||
type: 'RANGE',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should give max validation error if above max elements', () => {
|
||||
const field = fromJS({
|
||||
name: 'list',
|
||||
label: 'List',
|
||||
collapsed: false,
|
||||
minimize_collapsed: true,
|
||||
required: true,
|
||||
max: 3,
|
||||
fields: [{ label: 'String', name: 'string', widget: 'string' }],
|
||||
});
|
||||
const listControl = new ListControl({
|
||||
...props,
|
||||
field,
|
||||
value: fromJS([
|
||||
{ string: 'item 1' },
|
||||
{ string: 'item 2' },
|
||||
{ string: 'item 3' },
|
||||
{ string: 'item 4' },
|
||||
]),
|
||||
});
|
||||
|
||||
listControl.validate();
|
||||
expect(props.onValidateObject).toHaveBeenCalledWith('forID', [
|
||||
{
|
||||
message: 'editor.editorControlPane.widget.rangeMax',
|
||||
type: 'RANGE',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should give no validation error if between min and max elements', () => {
|
||||
const field = fromJS({
|
||||
name: 'list',
|
||||
label: 'List',
|
||||
collapsed: false,
|
||||
minimize_collapsed: true,
|
||||
required: true,
|
||||
min: 2,
|
||||
max: 3,
|
||||
fields: [{ label: 'String', name: 'string', widget: 'string' }],
|
||||
});
|
||||
const listControl = new ListControl({
|
||||
...props,
|
||||
field,
|
||||
value: fromJS([{ string: 'item 1' }, { string: 'item 2' }, { string: 'item 3' }]),
|
||||
});
|
||||
|
||||
listControl.validate();
|
||||
expect(props.onValidateObject).toHaveBeenCalledWith('forID', []);
|
||||
});
|
||||
|
||||
it('should give no validation error if no elements and optional', () => {
|
||||
const field = fromJS({
|
||||
name: 'list',
|
||||
label: 'List',
|
||||
collapsed: false,
|
||||
minimize_collapsed: true,
|
||||
required: false,
|
||||
min: 2,
|
||||
max: 3,
|
||||
fields: [{ label: 'String', name: 'string', widget: 'string' }],
|
||||
});
|
||||
const listControl = new ListControl({
|
||||
...props,
|
||||
field,
|
||||
value: fromJS([]),
|
||||
});
|
||||
|
||||
listControl.validate();
|
||||
expect(props.onValidateObject).toHaveBeenCalledWith('forID', []);
|
||||
});
|
||||
});
|
||||
|
@ -6,5 +6,7 @@ export default {
|
||||
minimize_collapsed: { type: 'boolean' },
|
||||
label_singular: { type: 'string' },
|
||||
i18n: { type: 'boolean' },
|
||||
min: { type: 'number' },
|
||||
max: { type: 'number' },
|
||||
},
|
||||
};
|
||||
|
Reference in New Issue
Block a user