From dd3eb10a89739fc509d1c6206d65a67b94b1757f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Ezr?= Date: Fri, 26 Mar 2021 01:21:46 +0100 Subject: [PATCH] Refs #30784 - MemoryAllocation use react helper In 8a9922fd we've removed `byte_size_f` last usage. This is moving the byte_size_f to render the React component, to seamlessly integrate into the form without breaking any plugins that were possibly still using it. Adds posibility for InputFactory components to set validation states. --- app/helpers/form_helper.rb | 7 +- .../form/libvirt/_base.html.erb | 8 +- .../form/ovirt/_base.html.erb | 7 +- .../javascripts/compute_resource/ovirt.js | 42 ++--- .../MemoryAllocationInput.js | 159 +++++++----------- .../MemoryAllocationInput.stories.js | 12 +- .../__tests__/MemoryAllocationInput.test.js | 20 ++- .../memoryAllocationInput.scss | 15 -- .../components/common/forms/Form.stories.js | 4 + .../common/forms/FormField.fixtures.js | 10 +- .../components/common/forms/FormField.js | 35 +++- .../components/common/forms/InputFactory.js | 26 ++- .../__snapshots__/FormField.test.js.snap | 21 +++ .../__snapshots__/InputFactory.test.js.snap | 10 +- 14 files changed, 185 insertions(+), 191 deletions(-) delete mode 100644 webpack/assets/javascripts/react_app/components/MemoryAllocationInput/memoryAllocationInput.scss diff --git a/app/helpers/form_helper.rb b/app/helpers/form_helper.rb index 0b658a051c7..6941f52f84f 100644 --- a/app/helpers/form_helper.rb +++ b/app/helpers/form_helper.rb @@ -232,12 +232,7 @@ def autocomplete_f(f, attr, options = {}) end def byte_size_f(f, attr, options = {}) - options[:class] = options[:class].to_s + ' byte_spinner' unless options[:disabled] - options[:label_help] = _("When specifying custom value, add 'MB' or 'GB' at the end. Field is not case sensitive and MB is default if unspecified.") - options[:help_block] ||= soft_limit_warning_block - options[:help_block] += f.hidden_field(attr, :class => "real-hidden-value", :id => nil) - - text_f(f, attr, options) + react_form_input('memory', f, attr, options) end def counter_f(f, attr, options = {}) diff --git a/app/views/compute_resources_vms/form/libvirt/_base.html.erb b/app/views/compute_resources_vms/form/libvirt/_base.html.erb index 3bf83ba5f8f..e9872a7be64 100644 --- a/app/views/compute_resources_vms/form/libvirt/_base.html.erb +++ b/app/views/compute_resources_vms/form/libvirt/_base.html.erb @@ -10,13 +10,7 @@ name: "#{f.object_name}[cpus]"}) %> <%= select_f f, :cpu_mode, Foreman::Model::Libvirt::CPU_MODES, :to_s, :to_s, { }, :label => _("CPU mode"), :label_size => "col-md-2" %> -<%= react_component('MemoryAllocationInput', - {label: 'Memory', - disabled: !new_vm, - recommendedMaxValue: compute_resource.max_memory.to_i / 1.megabyte, - defaultValue: f.object.memory.present? ? f.object.memory.to_i / 1.megabytes : 1024, - id: "#{f.object_name.gsub(/[\[\]]/, '[' => '_', ']' => '_')}memory", - name: "#{f.object_name}[memory]"}) %> +<%= byte_size_f(f, :memory, disabled: !new_vm, label: _('Memory'), recommended_max_value: compute_resource.max_memory.to_i) %> <% checked = params[:host] && params[:host][:compute_attributes] && params[:host][:compute_attributes][:start] || '1' %> <%= checkbox_f f, :start, { :checked => (checked == '1'), :help_inline => _("Power ON this machine"), :label => _('Start'), :label_size => "col-md-2"} if new_vm && controller_name != "compute_attributes" %> diff --git a/app/views/compute_resources_vms/form/ovirt/_base.html.erb b/app/views/compute_resources_vms/form/ovirt/_base.html.erb index af81b5ac488..c2609ba0aeb 100644 --- a/app/views/compute_resources_vms/form/ovirt/_base.html.erb +++ b/app/views/compute_resources_vms/form/ovirt/_base.html.erb @@ -52,12 +52,7 @@ disable_mem = !new_vm || (new_vm && instance_type && instance_type.memory.presen name: "#{f.object_name}[sockets]"}) %>
- <%= react_component('MemoryAllocationInput', - {label: 'Memory', - disabled: disable_mem, - defaultValue: f.object.memory.present? ? f.object.memory.to_i / 1.megabytes : 1024, - id: "#{f.object_name.gsub(/[\[\]]/, '[' => '_', ']' => '_')}memory", - name: "#{f.object_name}[memory]"}) %> +<%= byte_size_f(f, :memory, label: _('Memory'), disabled: disable_mem) %>
<% checked = params[:host] && params[:host][:compute_attributes] && params[:host][:compute_attributes][:start] || '1' %> diff --git a/webpack/assets/javascripts/compute_resource/ovirt.js b/webpack/assets/javascripts/compute_resource/ovirt.js index cec5f2450b4..a2fa4a8db0e 100644 --- a/webpack/assets/javascripts/compute_resource/ovirt.js +++ b/webpack/assets/javascripts/compute_resource/ovirt.js @@ -14,8 +14,6 @@ import $ from 'jquery'; import { showSpinner } from '../foreman_tools'; import { testConnection } from '../foreman_compute_resource'; -const megabyte = 1024 * 1024; - export function templateSelected(item) { const template = $(item).val(); @@ -34,17 +32,8 @@ export function templateSelected(item) { // As Instance Type values will take precence over templates values, // we don't update memory/cores values if instance type is already selected if (!$('#host_compute_attributes_instance_type').val()) { - const memoryInputElement = document - .getElementById('memory-input') - .getElementsByTagName('foreman-react-component')[0]; - memoryInputElement.setAttribute( - 'data-props', - JSON.stringify({ - ...memoryInputElement.reactProps, - defaultValue: result.memory / megabyte, - }) - ); updateCoresAndSockets(result); + setMemoryInputProps({ value: result.memory }); $('[id$=_ha]').prop('checked', result.ha); } $('#network_interfaces') @@ -85,27 +74,12 @@ export function instanceTypeSelected(item) { url, data: `instance_type_id=${instanceType}`, success(result) { - const memoryInputElement = document - .getElementById('memory-input') - .getElementsByTagName('foreman-react-component')[0]; if (result.name != null) { - memoryInputElement.setAttribute( - 'data-props', - JSON.stringify({ - ...memoryInputElement.reactProps, - defaultValue: result.memory / megabyte, - }) - ); + setMemoryInputProps({ value: result.memory }); updateCoresAndSockets(result); $('[id$=_ha]').prop('checked', result.ha); } - memoryInputElement.setAttribute( - 'data-props', - JSON.stringify({ - ...memoryInputElement.reactProps, - disabled: result.name != null, - }) - ); + setMemoryInputProps({ disabled: result.name != null }); disableCoresAndSockets(result); ['_ha'].forEach(name => $(`[id$=${name}]`).prop('readOnly', result.name != null) @@ -168,6 +142,16 @@ function addVolume({ .hide(); } +function setMemoryInputProps(props) { + const memoryInputElement = document + .getElementById('memory-input') + .getElementsByTagName('foreman-react-component')[0]; + memoryInputElement.reactProps = { + ...memoryInputElement.reactProps, + ...props, + }; +} + function updateCoresAndSockets(result) { const coresInputElement = document .getElementById('cores-input') diff --git a/webpack/assets/javascripts/react_app/components/MemoryAllocationInput/MemoryAllocationInput.js b/webpack/assets/javascripts/react_app/components/MemoryAllocationInput/MemoryAllocationInput.js index 7d4c2378a87..9cf46396e0c 100644 --- a/webpack/assets/javascripts/react_app/components/MemoryAllocationInput/MemoryAllocationInput.js +++ b/webpack/assets/javascripts/react_app/components/MemoryAllocationInput/MemoryAllocationInput.js @@ -1,16 +1,13 @@ +import RCInputNumber from 'rc-input-number'; import React, { useEffect, useState } from 'react'; import PropTypes from 'prop-types'; -import { WarningTriangleIcon, ErrorCircleOIcon } from '@patternfly/react-icons'; -import { HelpBlock, Grid, Col, Row } from 'patternfly-react'; -import { translate as __ } from '../../common/I18n'; +import { sprintf, translate as __ } from '../../common/I18n'; import { MB_FORMAT, MEGABYTES } from './constants'; -import './memoryAllocationInput.scss'; +import '../common/forms/NumericInput.scss'; import { noop } from '../../common/helpers'; -import NumericInput from '../common/forms/NumericInput'; const MemoryAllocationInput = ({ - defaultValue, - label, + value, onChange, maxValue, minValue, @@ -18,104 +15,67 @@ const MemoryAllocationInput = ({ name, id, disabled, + setError, + setWarning, }) => { - const [validationState, setValidationState] = useState(undefined); - const [value, setValue] = useState(defaultValue); + const [valueMB, setValueMB] = useState(value / MEGABYTES); useEffect(() => { - setValue(defaultValue); - }, [defaultValue]); - - useEffect(() => { - if (value > maxValue && maxValue !== undefined) { - setValidationState('error'); - } else if ( - value > recommendedMaxValue && - recommendedMaxValue !== undefined - ) { - setValidationState('warning'); + const valueBytes = valueMB * MEGABYTES; + if (maxValue && valueBytes > maxValue) { + setWarning(null); + setError( + sprintf( + __('Specified value is higher than maximum value %s'), + `${maxValue / MEGABYTES} ${MB_FORMAT}` + ) + ); + } else if (recommendedMaxValue && valueBytes > recommendedMaxValue) { + setError(null); + setWarning( + sprintf( + __('Specified value is higher than recommended maximum %s'), + `${recommendedMaxValue / MEGABYTES} ${MB_FORMAT}` + ) + ); } else { - setValidationState(undefined); + setWarning(null); } - }, [recommendedMaxValue, maxValue, value]); - - const handleValueIncrease = () => { - setValue(value * 2); - }; - - const handleValueDecrease = () => { - setValue(value / 2); - }; - - const handleTypedValue = v => { - setValue(v); - }; + }, [valueMB, recommendedMaxValue, maxValue, setError, setWarning]); const handleChange = v => { - if (v === value + 1) { - handleValueIncrease(); - } else if (v === value - 1) { - handleValueDecrease(); - } else { - handleTypedValue(v); - } - onChange(value); - }; - - const format = v => `${v} ${MB_FORMAT}`; - - const helpBlock = () => { - if (validationState === 'warning') { - return ( - - - {__('Specified value is higher than recommended maximum')} - - ); - } else if (validationState === 'error') { - return ( - - - {__('Specified value is higher than maximum value')} - - ); + if (v === valueMB + 1) { + v = valueMB * 2; + } else if (v === valueMB - 1) { + v = Math.floor(valueMB / 2); } - return undefined; + setValueMB(v); + onChange(v * MEGABYTES); }; - const parser = str => str.replace(/\D/g, ''); return ( - - - - - - - - - - - {validationState !== undefined && helpBlock()} - - - + <> + `${v} ${MB_FORMAT}`} + parser={str => str.replace(/\D/g, '')} + onChange={handleChange} + disabled={disabled} + min={minValue && minValue / MEGABYTES} + step={1} + precision={0} + name="" + prefixCls="foreman-numeric-input" + /> + + ); }; MemoryAllocationInput.propTypes = { - /** Set the label of the memory allocation input */ - label: PropTypes.string, /** Set the default value of the memory allocation input */ - defaultValue: PropTypes.number, + value: PropTypes.number, /** Set the recommended max value of the numeric input */ recommendedMaxValue: PropTypes.number, /** Set the max value of the numeric input */ @@ -124,24 +84,29 @@ MemoryAllocationInput.propTypes = { minValue: PropTypes.number, /** Set the onChange function of the numeric input */ onChange: PropTypes.func, - /** Set the name of the numeric input */ - name: NumericInput.propTypes.name, + /** Set the name of the input holding the value in bytes */ + name: PropTypes.string, /** Set the id of the numeric input */ - id: NumericInput.propTypes.id, + id: PropTypes.string, /** Set whether the numeric input will be disabled or not */ - disabled: NumericInput.propTypes.disabled, + disabled: PropTypes.bool, + /** Component passes the validation error to this function */ + setError: PropTypes.func, + /** Component passes the validation warning to this function */ + setWarning: PropTypes.func, }; MemoryAllocationInput.defaultProps = { - label: __('Memory'), - defaultValue: 1, + value: 2048 * MEGABYTES, onChange: noop, - recommendedMaxValue: undefined, - maxValue: undefined, + recommendedMaxValue: null, + maxValue: null, minValue: 1, name: '', id: '', disabled: false, + setError: noop, + setWarning: noop, }; export default MemoryAllocationInput; diff --git a/webpack/assets/javascripts/react_app/components/MemoryAllocationInput/MemoryAllocationInput.stories.js b/webpack/assets/javascripts/react_app/components/MemoryAllocationInput/MemoryAllocationInput.stories.js index da29ceea96f..aba553e1585 100644 --- a/webpack/assets/javascripts/react_app/components/MemoryAllocationInput/MemoryAllocationInput.stories.js +++ b/webpack/assets/javascripts/react_app/components/MemoryAllocationInput/MemoryAllocationInput.stories.js @@ -1,6 +1,7 @@ import React from 'react'; -import { number, text } from '@storybook/addon-knobs'; +import { number } from '@storybook/addon-knobs'; import { action } from '@storybook/addon-actions'; +import { MEGABYTES } from './constants'; import MemoryAllocationInput from './MemoryAllocationInput'; export default { @@ -13,10 +14,9 @@ export default { export const UseMemoryAllocationInput = () => ( -); \ No newline at end of file +); diff --git a/webpack/assets/javascripts/react_app/components/MemoryAllocationInput/__tests__/MemoryAllocationInput.test.js b/webpack/assets/javascripts/react_app/components/MemoryAllocationInput/__tests__/MemoryAllocationInput.test.js index 69f064e310b..556e25a393b 100644 --- a/webpack/assets/javascripts/react_app/components/MemoryAllocationInput/__tests__/MemoryAllocationInput.test.js +++ b/webpack/assets/javascripts/react_app/components/MemoryAllocationInput/__tests__/MemoryAllocationInput.test.js @@ -1,29 +1,31 @@ import React from 'react'; import { mount } from '@theforeman/test'; import { Provider } from 'react-redux'; +import { MEGABYTES } from '../constants'; import MemoryAllocationInput from '../'; -import Store from "../../../redux"; describe('MemoryAllocationInput', () => { it('warning alert', async () => { + const setWarning = jest.fn(); const component = mount( - - - + ); expect(component.find('.foreman-numeric-input-input').prop('value')).toEqual('11264 MB'); - expect(component.find('.warning-icon').exists()).toBeTruthy(); + expect(setWarning.mock.calls.length).toBe(1); }); it('error alert', async () => { + const setError = jest.fn(); const component = mount( - - - + ); expect(component.find('.foreman-numeric-input-input').prop('value')).toEqual('21504 MB'); - expect(component.find('.error-icon').exists()).toBeTruthy(); + expect(setError.mock.calls.length).toBe(1); }); }); diff --git a/webpack/assets/javascripts/react_app/components/MemoryAllocationInput/memoryAllocationInput.scss b/webpack/assets/javascripts/react_app/components/MemoryAllocationInput/memoryAllocationInput.scss deleted file mode 100644 index 9f244bc3e35..00000000000 --- a/webpack/assets/javascripts/react_app/components/MemoryAllocationInput/memoryAllocationInput.scss +++ /dev/null @@ -1,15 +0,0 @@ -@import '../../common/colors.scss'; - -.container { - max-width: none !important; -} - -.warning-icon { - margin-right: 3px; - color: $pf-gold-400; -} - -.error-icon { - margin-right: 3px; - color: $pf-red-100; -} diff --git a/webpack/assets/javascripts/react_app/components/common/forms/Form.stories.js b/webpack/assets/javascripts/react_app/components/common/forms/Form.stories.js index 01ab06f902a..a1fcb4fc9f2 100644 --- a/webpack/assets/javascripts/react_app/components/common/forms/Form.stories.js +++ b/webpack/assets/javascripts/react_app/components/common/forms/Form.stories.js @@ -16,6 +16,7 @@ import { selectProps, dateTimeWithErrorProps, ownComponentFieldProps, + memoryProps, } from './FormField.fixtures'; const StoryForm = () => ( @@ -74,6 +75,9 @@ export const formField = () => ( + + + ); diff --git a/webpack/assets/javascripts/react_app/components/common/forms/FormField.fixtures.js b/webpack/assets/javascripts/react_app/components/common/forms/FormField.fixtures.js index b5b0a5b716e..d6fcff4b7ba 100644 --- a/webpack/assets/javascripts/react_app/components/common/forms/FormField.fixtures.js +++ b/webpack/assets/javascripts/react_app/components/common/forms/FormField.fixtures.js @@ -17,7 +17,7 @@ export const dateTimeWithErrorProps = { export const selectProps = { type: 'select', - id: 'date-time', + id: 'select-field', label: 'Grouped select', name: 'group[groupedSelect]', options: [ @@ -47,3 +47,11 @@ export const formAutocompleteDataProps = { name: 'Filter[search]', id: 'form-search', }; + +export const memoryProps = { + type: 'memory', + label: 'Memory', + id: 'memory-field', + maxValue: 48000*1024*1024, + recommendedMaxValue: 2048*1024*1024, +}; diff --git a/webpack/assets/javascripts/react_app/components/common/forms/FormField.js b/webpack/assets/javascripts/react_app/components/common/forms/FormField.js index 550e2d24027..57ccd855663 100644 --- a/webpack/assets/javascripts/react_app/components/common/forms/FormField.js +++ b/webpack/assets/javascripts/react_app/components/common/forms/FormField.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState } from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import { @@ -8,27 +8,35 @@ import { HelpBlock, FieldLevelHelp, } from 'patternfly-react'; +import { WarningTriangleIcon, ErrorCircleOIcon } from '@patternfly/react-icons'; import InputFactory from './InputFactory'; import { noop } from '../../../common/helpers'; -const InlineMessage = ({ error, helpInline }) => { - if (!error && !helpInline) { +const InlineMessage = ({ error, warning, helpInline }) => { + if (!error && !warning && !helpInline) { return null; } return ( - {error || helpInline} + {error && } + {!error && warning && } + {error || warning || helpInline} ); }; InlineMessage.propTypes = { error: PropTypes.string, + warning: PropTypes.string, helpInline: PropTypes.string, }; InlineMessage.defaultProps = { error: null, + warning: null, helpInline: null, }; @@ -51,6 +59,9 @@ const FormField = ({ inputProps, ...otherProps }) => { + const [innerError, setError] = useState(error); + const [innerWarning, setWarning] = useState(null); + const controlProps = { value, name, @@ -58,15 +69,21 @@ const FormField = ({ required, className, onChange, + setError, + setWarning, ...otherProps, ...inputProps, }; + let validationState = null; + if (innerWarning) validationState = 'warning'; + if (innerError) validationState = 'error'; + return ( {label} @@ -82,7 +99,11 @@ const FormField = ({ {children || } - + ); }; diff --git a/webpack/assets/javascripts/react_app/components/common/forms/InputFactory.js b/webpack/assets/javascripts/react_app/components/common/forms/InputFactory.js index c9886a37f9f..9caf1270943 100644 --- a/webpack/assets/javascripts/react_app/components/common/forms/InputFactory.js +++ b/webpack/assets/javascripts/react_app/components/common/forms/InputFactory.js @@ -7,6 +7,7 @@ import AutoComplete from '../../AutoComplete'; import DateTimePicker from '../DateTimePicker/DateTimePicker'; import DatePicker from '../DateTimePicker/DatePicker'; import OrderableSelect from './OrderableSelect'; +import MemoryAllocationInput from '../../MemoryAllocationInput/MemoryAllocationInput'; import TimePicker from '../DateTimePicker/TimePicker'; import Select from './Select'; @@ -17,6 +18,7 @@ const inputComponents = { dateTime: DateTimePicker, orderableSelect: OrderableSelect, time: TimePicker, + memory: MemoryAllocationInput, }; export const registerInputComponent = (name, Component) => { @@ -25,13 +27,19 @@ export const registerInputComponent = (name, Component) => { export const getComponentClass = name => inputComponents[name] || 'input'; -const InputFactory = ({ type, ...controlProps }) => ( - -); +const InputFactory = ({ type, setError, setWarning, ...controlProps }) => { + const componentClass = getComponentClass(type); + let validations = {}; + if (componentClass !== 'input') validations = { setError, setWarning }; + return ( + + ); +}; InputFactory.propTypes = { type: PropTypes.string, @@ -46,6 +54,8 @@ InputFactory.propTypes = { required: PropTypes.bool, className: PropTypes.string, onChange: PropTypes.func, + setError: PropTypes.func, + setWarning: PropTypes.func, }; InputFactory.defaultProps = { @@ -56,6 +66,8 @@ InputFactory.defaultProps = { required: false, disabled: false, onChange: noop, + setError: noop, + setWarning: noop, }; export default InputFactory; diff --git a/webpack/assets/javascripts/react_app/components/common/forms/__tests__/__snapshots__/FormField.test.js.snap b/webpack/assets/javascripts/react_app/components/common/forms/__tests__/__snapshots__/FormField.test.js.snap index 0d95e97c5d2..401c18901cf 100644 --- a/webpack/assets/javascripts/react_app/components/common/forms/__tests__/__snapshots__/FormField.test.js.snap +++ b/webpack/assets/javascripts/react_app/components/common/forms/__tests__/__snapshots__/FormField.test.js.snap @@ -33,12 +33,15 @@ exports[`FormField rendering renders AutoComplete 1`] = ` } onChange={[Function]} required={false} + setError={[Function]} + setWarning={[Function]} type="autocomplete" /> `; @@ -66,12 +69,15 @@ exports[`FormField rendering renders Date input 1`] = ` name="a" onChange={[Function]} required={false} + setError={[Function]} + setWarning={[Function]} type="date" /> `; @@ -101,6 +107,8 @@ exports[`FormField rendering renders DateTime complex options and error 1`] = ` name="group[datetime]" onChange={[Function]} required={false} + setError={[Function]} + setWarning={[Function]} type="dateTime" value={1991-01-01T01:12:01.000Z} /> @@ -108,6 +116,7 @@ exports[`FormField rendering renders DateTime complex options and error 1`] = ` `; @@ -135,12 +144,15 @@ exports[`FormField rendering renders DateTime input 1`] = ` name="a" onChange={[Function]} required={false} + setError={[Function]} + setWarning={[Function]} type="dateTime" /> `; @@ -168,12 +180,15 @@ exports[`FormField rendering renders Time input 1`] = ` name="a" onChange={[Function]} required={false} + setError={[Function]} + setWarning={[Function]} type="time" /> `; @@ -213,12 +228,15 @@ exports[`FormField rendering renders text complex options and help 1`] = ` name="group[textfield]" onChange={[Function]} required={false} + setError={[Function]} + setWarning={[Function]} type="text" /> `; @@ -246,12 +264,15 @@ exports[`FormField rendering renders text input 1`] = ` name="a" onChange={[Function]} required={false} + setError={[Function]} + setWarning={[Function]} type="text" /> `; diff --git a/webpack/assets/javascripts/react_app/components/common/forms/__tests__/__snapshots__/InputFactory.test.js.snap b/webpack/assets/javascripts/react_app/components/common/forms/__tests__/__snapshots__/InputFactory.test.js.snap index f246574df76..18435ee6caf 100644 --- a/webpack/assets/javascripts/react_app/components/common/forms/__tests__/__snapshots__/InputFactory.test.js.snap +++ b/webpack/assets/javascripts/react_app/components/common/forms/__tests__/__snapshots__/InputFactory.test.js.snap @@ -22,6 +22,8 @@ exports[`InputFactory rendering renders AutoComplete 1`] = ` onChange={[Function]} required={false} searchQuery="" + setError={[Function]} + setWarning={[Function]} type="autocomplete" url="bookmarks/auto_complete" useKeyShortcuts={false} @@ -37,6 +39,8 @@ exports[`InputFactory rendering renders DateTime input 1`] = ` name="a" onChange={[Function]} required={false} + setError={[Function]} + setWarning={[Function]} type="dateTime" /> `; @@ -47,7 +51,7 @@ exports[`InputFactory rendering renders Select 1`] = ` className="" componentClass={[Function]} disabled={false} - id="date-time" + id="select-field" label="Grouped select" name="group[groupedSelect]" onChange={[Function]} @@ -79,6 +83,8 @@ exports[`InputFactory rendering renders Select 1`] = ` ] } required={false} + setError={[Function]} + setWarning={[Function]} type="select" /> `; @@ -94,6 +100,8 @@ exports[`InputFactory rendering renders custom registered component 1`] = ` name="group[ownfield]" onChange={[Function]} required={false} + setError={[Function]} + setWarning={[Function]} type="ownInput" /> `;