From c47309cadb488818ff0a6738fb3d08b3a2ebddab Mon Sep 17 00:00:00 2001 From: Richard Vsiansky Date: Tue, 14 Jan 2020 13:50:10 +0100 Subject: [PATCH 1/7] Add meta and formGroup propTypes --- packages/common/src/prop-types-templates.js | 27 +++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/packages/common/src/prop-types-templates.js b/packages/common/src/prop-types-templates.js index 9dc86f2de..a5801d28c 100644 --- a/packages/common/src/prop-types-templates.js +++ b/packages/common/src/prop-types-templates.js @@ -1,3 +1,30 @@ import PropTypes from 'prop-types'; export const optionsPropType = PropTypes.arrayOf(PropTypes.shape({ label: PropTypes.string.isRequired, value: PropTypes.any })); + +export const meta = PropTypes.shape({ + active: PropTypes.bool, + dirty: PropTypes.bool, + dirtySinceLastSubmit: PropTypes.bool, + error: PropTypes.any, + initial: PropTypes.any, + invalid: PropTypes.bool, + modified: PropTypes.bool, + pristine: PropTypes.bool, + submitError: PropTypes.any, + submitFailed: PropTypes.bool, + submitSucceeded: PropTypes.bool, + submitting: PropTypes.bool, + touched: PropTypes.bool, + valid: PropTypes.bool, + validating: PropTypes.bool, + visited: PropTypes.bool, +}); + +export const formGroup = { + isRequired: PropTypes.bool, + label: PropTypes.node, + helperText: PropTypes.node, + meta, + description: PropTypes.node, +}; From fe5c70329b79c876c21f022ef1123285145dd33c Mon Sep 17 00:00:00 2001 From: Richard Vsiansky Date: Tue, 14 Jan 2020 13:50:27 +0100 Subject: [PATCH 2/7] Add common MultipleChoiceList component --- packages/common/src/multiple-choice-list.js | 80 +++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 packages/common/src/multiple-choice-list.js diff --git a/packages/common/src/multiple-choice-list.js b/packages/common/src/multiple-choice-list.js new file mode 100644 index 000000000..ab85e9fe4 --- /dev/null +++ b/packages/common/src/multiple-choice-list.js @@ -0,0 +1,80 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { composeValidators } from '@data-driven-forms/react-form-renderer'; + +import { formGroup } from './prop-types-templates'; + +const MultipleChoiceList = ({ validate, FieldProvider, Wrapper, Checkbox, ...props }) => ( + { + const { error, touched } = meta; + const showError = touched && error; + const groupValues = rest.input.value; + return ( + + { options.map(option => + ( { + const indexValue = groupValues.indexOf(input.value); + return ( + (indexValue === -1 + ? input.onChange([ ...groupValues, input.value ]) + : input.onChange([ ...groupValues.slice(0, indexValue), ...groupValues.slice(indexValue + 1) ])) } + label={ rest.label } + /> + ); + } } + />)) } + ); + } } + /> +); + +MultipleChoiceList.propTypes = { + validate: PropTypes.func, + FieldProvider: PropTypes.oneOfType([ PropTypes.node, PropTypes.func ]), + name: PropTypes.string.isRequired, + Wrapper: PropTypes.oneOfType([ PropTypes.node, PropTypes.func ]), + Checkbox: PropTypes.oneOfType([ PropTypes.node, PropTypes.func ]), +}; + +export default MultipleChoiceList; + +export const wrapperProps = { + ...formGroup, + children: PropTypes.oneOfType([ + PropTypes.arrayOf(PropTypes.node), + PropTypes.node, + ]).isRequired, +}; From 552ab49cb73677cbcf35d021e07f08c560f768c5 Mon Sep 17 00:00:00 2001 From: Richard Vsiansky Date: Tue, 14 Jan 2020 13:53:03 +0100 Subject: [PATCH 3/7] fix(pf3): Convert PF3 multiplechoice to use common --- .../src/form-fields/multiple-choice-list.js | 90 +-- .../multiple-choice-list.test.js.snap | 572 ++++++++++-------- 2 files changed, 342 insertions(+), 320 deletions(-) diff --git a/packages/pf3-component-mapper/src/form-fields/multiple-choice-list.js b/packages/pf3-component-mapper/src/form-fields/multiple-choice-list.js index 65594582e..3d1d9f961 100644 --- a/packages/pf3-component-mapper/src/form-fields/multiple-choice-list.js +++ b/packages/pf3-component-mapper/src/form-fields/multiple-choice-list.js @@ -1,71 +1,43 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Checkbox, FormGroup, ControlLabel, FieldLevelHelp } from 'patternfly-react'; -import { composeValidators } from '@data-driven-forms/react-form-renderer'; +import MultipleChoiceListCommon, { wrapperProps } from '@data-driven-forms/common/src/multiple-choice-list'; import RequiredLabel from './required-label'; import { renderHelperText } from './form-fields'; -const MultipleChoiceList = ({ validate, FieldProvider, ...props }) => ( - - { ({ - label, - isRequired, - helperText, - meta, - options, - isDisabled, - isReadOnly, - description, - ...rest - }) => { - const { error, touched } = meta; - const showError = touched && error; - const groupValues = rest.input.value; - return ( - - - { (isRequired ? : label) } - { helperText && } - -
- { options.map(option => - ( { - const indexValue = groupValues.indexOf(input.value); - return ( - (indexValue === -1 - ? input.onChange([ ...groupValues, input.value ]) - : input.onChange([ ...groupValues.slice(0, indexValue), ...groupValues.slice(indexValue + 1) ])) } - > - { rest.label } - - ); - } } - />)) } -
- { renderHelperText(showError && meta.error, description) } -
- ); - } } -
+const FinalCheckbox = ({ label, isDisabled, ...props }) => ( + { label } ); -MultipleChoiceList.propTypes = { - validate: PropTypes.func, - FieldProvider: PropTypes.oneOfType([ PropTypes.node, PropTypes.func ]), - name: PropTypes.string.isRequired, +FinalCheckbox.propTypes = { + label: PropTypes.node, + isDisabled: PropTypes.bool, }; +const Wrapper = ({ showError, isRequired, helperText, label, meta, description, children }) => ( + + + { isRequired ? : label } + { helperText && } + +
+ { children } +
+ { renderHelperText(showError && meta.error, description) } +
+); + +Wrapper.propTypes = { + ...wrapperProps, +}; + +const MultipleChoiceList = (props) => ( + +); + export default MultipleChoiceList; diff --git a/packages/pf3-component-mapper/src/tests/__snapshots__/multiple-choice-list.test.js.snap b/packages/pf3-component-mapper/src/tests/__snapshots__/multiple-choice-list.test.js.snap index 79fd6fe71..3cd54a750 100644 --- a/packages/pf3-component-mapper/src/tests/__snapshots__/multiple-choice-list.test.js.snap +++ b/packages/pf3-component-mapper/src/tests/__snapshots__/multiple-choice-list.test.js.snap @@ -16,7 +16,10 @@ exports[` should render correctly 1`] = ` ] } > - should render correctly 1`] = ` }, ] } - validate={[Function]} > - should render correctly 1`] = ` } validate={[Function]} > - -
- - -
- - - + +
+ -
- -
- - -
- - - + +
+
+
+
+ -
- -
- - -
-
-
-
-
-
+
+ +
+ + +
+ + + + + + + `; @@ -200,7 +222,10 @@ exports[` should render in error state 1`] = ` ] } > - should render in error state 1`] = ` }, ] } - validate={[Function]} > - should render in error state 1`] = ` } validate={[Function]} > - -
- - -
- - - + +
+ -
- -
- - -
- - - + +
+
+
+
+ -
- -
- - -
-
- - - Error message - - -
-
-
-
+
+ +
+ + + + + + + Error message + + + + + + + +
`; From f4e10fa6f5b7088acf030f0ad88a034dff8f34f3 Mon Sep 17 00:00:00 2001 From: Richard Vsiansky Date: Tue, 14 Jan 2020 15:44:03 +0100 Subject: [PATCH 4/7] Convert PF4 multiple choice list to use common --- .../src/form-fields/multiple-choice-list.js | 81 +++++++------------ 1 file changed, 28 insertions(+), 53 deletions(-) diff --git a/packages/pf4-component-mapper/src/form-fields/multiple-choice-list.js b/packages/pf4-component-mapper/src/form-fields/multiple-choice-list.js index aac04189f..212c7b173 100644 --- a/packages/pf4-component-mapper/src/form-fields/multiple-choice-list.js +++ b/packages/pf4-component-mapper/src/form-fields/multiple-choice-list.js @@ -1,64 +1,39 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Checkbox, FormGroup } from '@patternfly/react-core'; -import { composeValidators } from '@data-driven-forms/react-form-renderer'; +import MultipleChoiceListCommon, { wrapperProps } from '@data-driven-forms/common/src/multiple-choice-list'; -const propTypes = { - validate: PropTypes.oneOfType([ PropTypes.array, PropTypes.func ]), - FieldProvider: PropTypes.oneOfType([ PropTypes.node, PropTypes.func ]), - name: PropTypes.string.isRequired, +const FinalCheckbox = (props) => ( + +); + +FinalCheckbox.propTypes = { + checked: PropTypes.bool, }; -const MultipleChoiceList = ({ validate, FieldProvider, ...props }) => ( - ( + + { children } + +); + +Wrapper.propTypes = { + ...wrapperProps, +}; + +const MultipleChoiceList = (props) => ( + { - const { error, touched } = meta; - const showError = touched && error; - const groupValues = rest.input.value; - return ( - - { options.map(option => - ( { - const indexValue = groupValues.indexOf(input.value); - return ( - (indexValue === -1 - ? input.onChange([ ...groupValues, input.value ]) - : input.onChange([ ...groupValues.slice(0, indexValue), ...groupValues.slice(indexValue + 1) ])) } - /> - ); - } } - />)) } - - ); - } } + Wrapper={ Wrapper } + Checkbox={ FinalCheckbox } /> ); -MultipleChoiceList.propTypes = propTypes; - export default MultipleChoiceList; From bc38f99d96af9327c1825b823887645f22d9cd78 Mon Sep 17 00:00:00 2001 From: Richard Vsiansky Date: Tue, 14 Jan 2020 15:45:32 +0100 Subject: [PATCH 5/7] Update snaps --- .../multiple-choice-list.test.js.snap | 229 ++++--- .../__snapshots__/form-fields.test.js.snap | 640 +++++++++++------- 2 files changed, 553 insertions(+), 316 deletions(-) diff --git a/packages/pf3-component-mapper/src/tests/__snapshots__/multiple-choice-list.test.js.snap b/packages/pf3-component-mapper/src/tests/__snapshots__/multiple-choice-list.test.js.snap index 3cd54a750..7b956ba9a 100644 --- a/packages/pf3-component-mapper/src/tests/__snapshots__/multiple-choice-list.test.js.snap +++ b/packages/pf3-component-mapper/src/tests/__snapshots__/multiple-choice-list.test.js.snap @@ -46,6 +46,7 @@ exports[` should render correctly 1`] = ` }, ] } + render={[Function]} validate={[Function]} > should render correctly 1`] = ` }, ] } + render={[Function]} validate={[Function]} > should render correctly 1`] = ` type="checkbox" value={0} > - -
- -
-
+ + +
+ should render correctly 1`] = ` type="checkbox" value={1} > - -
- -
-
+ + + +
@@ -252,6 +278,7 @@ exports[` should render in error state 1`] = ` }, ] } + render={[Function]} validate={[Function]} > should render in error state 1`] = ` }, ] } + render={[Function]} validate={[Function]} > should render in error state 1`] = ` type="checkbox" value={0} > - -
- -
-
+ + + +
should render in error state 1`] = ` type="checkbox" value={1} > - -
- -
-
+ + + +
diff --git a/packages/pf4-component-mapper/src/tests/__snapshots__/form-fields.test.js.snap b/packages/pf4-component-mapper/src/tests/__snapshots__/form-fields.test.js.snap index fd453d3f1..3ca7a8bfe 100644 --- a/packages/pf4-component-mapper/src/tests/__snapshots__/form-fields.test.js.snap +++ b/packages/pf4-component-mapper/src/tests/__snapshots__/form-fields.test.js.snap @@ -200,7 +200,10 @@ exports[`FormFields should render Checkbox with options correctly 1`] = ` ] } > - -
- -
+
+ - -
- + -
- + - + +
+ + +
+
+
-
-
-
- -
- + -
- + - + +
+ + +
+
+
-
-
-
- -
- + -
- + - + +
+ + +
+
+
-
+
-
-
- -
- +
+ +
+
+
@@ -1406,7 +1497,10 @@ exports[`FormFields should render disabled Checkbox with options correctly 1`] = ] } > - -
- -
+
+ - -
- + -
- + - + +
+ + +
+
+
-
-
-
- -
- + -
- + - + +
+ + +
+
+
-
-
-
- -
- + -
- + - + +
+ + +
+
+
-
+
-
-
- -
- +
+ +
+
+ From 357ec55f550c1fe383dca359bcee149d65da3ffd Mon Sep 17 00:00:00 2001 From: Richard Vsiansky Date: Tue, 14 Jan 2020 15:53:16 +0100 Subject: [PATCH 6/7] Convert MUI multiple choice list to use common --- packages/common/src/multiple-choice-list.js | 1 + .../src/form-fields/multiple-choice-list.js | 103 ++++++++---------- 2 files changed, 44 insertions(+), 60 deletions(-) diff --git a/packages/common/src/multiple-choice-list.js b/packages/common/src/multiple-choice-list.js index ab85e9fe4..4289c91ea 100644 --- a/packages/common/src/multiple-choice-list.js +++ b/packages/common/src/multiple-choice-list.js @@ -31,6 +31,7 @@ const MultipleChoiceList = ({ validate, FieldProvider, Wrapper, Checkbox, ...pro meta={ meta } description={ description } rest={ rest } + error={ error } > { options.map(option => ( ( - - { ({ - label, - isRequired, - helperText, - meta, - options, - isDisabled, - formOptions, - componentType, - ...rest - }) => { - const { error, touched } = meta; - const showError = touched && error; - const groupValues = Array.isArray(rest.input.value) ? rest.input.value : []; - return ( - - - { label } - - { options.map(option => - ( { - const indexValue = groupValues.indexOf(option.value); - return ( - { - return (indexValue === -1 - ? input.onChange([ ...groupValues, option.value ]) - : input.onChange([ ...groupValues.slice(0, indexValue), ...groupValues.slice(indexValue + 1) ]));} } - > - { option.label } - } - label={ option.label } - /> - ); - } } - />)) } - - { showError ? error : null } - - - ); - } } - +import MultipleChoiceListCommon, { wrapperProps } from '@data-driven-forms/common/src/multiple-choice-list'; + +const FinalCheckbox = (props) => ( + + { props.label } + } + label={ props.label } + /> +); + +FinalCheckbox.propTypes = { + isDisabled: PropTypes.bool, + label: PropTypes.node, +}; + +const Wrapper = ({ showError, label, error, children }) =>( + + + { label } + + { children } + + { showError ? error : null } + + +); + +Wrapper.propTypes = { + ...wrapperProps, +}; + +const MultipleChoiceList = (props) => ( + ); export default MultipleChoiceList; From 8beb3df12999a98567fb0478c149e501ca08389e Mon Sep 17 00:00:00 2001 From: Richard Vsiansky Date: Tue, 14 Jan 2020 16:55:34 +0100 Subject: [PATCH 7/7] Add tests fo MutlipleChoice list MUI --- .../src/form-fields/multiple-choice-list.js | 8 +- .../src/tests/multiple-choice-list.test.js | 85 +++++++++++++++++++ 2 files changed, 89 insertions(+), 4 deletions(-) create mode 100644 packages/mui-component-mapper/src/tests/multiple-choice-list.test.js diff --git a/packages/mui-component-mapper/src/form-fields/multiple-choice-list.js b/packages/mui-component-mapper/src/form-fields/multiple-choice-list.js index e6090d993..43ba58a19 100644 --- a/packages/mui-component-mapper/src/form-fields/multiple-choice-list.js +++ b/packages/mui-component-mapper/src/form-fields/multiple-choice-list.js @@ -11,15 +11,15 @@ import FormHelperText from '@material-ui/core/FormHelperText'; import MultipleChoiceListCommon, { wrapperProps } from '@data-driven-forms/common/src/multiple-choice-list'; -const FinalCheckbox = (props) => ( +const FinalCheckbox = ({ isDisabled, label, ...props }) => ( - { props.label } + { label } } - label={ props.label } + label={ label } /> ); diff --git a/packages/mui-component-mapper/src/tests/multiple-choice-list.test.js b/packages/mui-component-mapper/src/tests/multiple-choice-list.test.js new file mode 100644 index 000000000..c92f8ff3a --- /dev/null +++ b/packages/mui-component-mapper/src/tests/multiple-choice-list.test.js @@ -0,0 +1,85 @@ +import React from 'react'; +import { mount } from 'enzyme'; + +import Grid from '@material-ui/core/Grid'; +import Checkbox from '@material-ui/core/Checkbox'; +import FormControlLabel from '@material-ui/core/FormControlLabel'; +import FormLabel from '@material-ui/core/FormLabel'; +import FormGroup from '@material-ui/core/FormGroup'; +import FormControl from '@material-ui/core/FormControl'; +import FormHelperText from '@material-ui/core/FormHelperText'; + +import MultipleChoiceList from '../form-fields/multiple-choice-list'; +import MockFieldProvider from '../../../../__mocks__/mock-field-provider'; + +describe('', () => { + let initialProps; + let changeSpy = jest.fn(); + beforeEach(() => { + initialProps = { + FieldProvider: props => , + options: [{ + label: 'Foo', + value: 0, + }, { + label: 'Bar', + value: 1, + }], + }; + }); + + afterEach(() => { + changeSpy.mockReset(); + }); + + it('should render correctly', () => { + const wrapper = mount(); + + expect(wrapper.find(FormControl)).toHaveLength(1); + expect(wrapper.find(FormGroup)).toHaveLength(1); + expect(wrapper.find(FormLabel)).toHaveLength(1); + expect(wrapper.find(FormControlLabel)).toHaveLength(initialProps.options.length); + expect(wrapper.find(Grid)).toHaveLength(1); + expect(wrapper.find(Checkbox)).toHaveLength(initialProps.options.length); + }); + + it('should call FieldProvider on change method', () => { + const wrapper = mount(); + + wrapper.find('input').last().simulate('change', { target: { checked: true }}); + expect(changeSpy).toHaveBeenCalledWith([ 1 ]); + }); + + it('should call FieldProvider on change method and remove option value form all values', () => { + const wrapper = mount( + } + /> + ); + + wrapper.find('input').last().simulate('change', { target: { checked: true }}); + expect(changeSpy).toHaveBeenCalledWith([]); + }); + + it('should render in error state', () => { + const ERROR_MESSAGE = 'Error message'; + + const wrapper = mount( + ( + ) } + /> + ); + + expect(wrapper.find(FormHelperText).text()).toEqual(ERROR_MESSAGE); + }); +});