diff --git a/output/forms.eslint.txt b/output/forms.eslint.txt index ac385b6ada..9d583d0c9e 100755 --- a/output/forms.eslint.txt +++ b/output/forms.eslint.txt @@ -7,114 +7,110 @@ Scoping to packages that match 'react-talend-forms' The react/require-extension rule is deprecated. Please use the import/extensions rule from eslint-plugin-import instead. /home/travis/build/Talend/ui/packages/forms/src/fields/ArrayField.js - 19:28 error 'TitleField' is missing in props validation react/prop-types - 19:40 error 'idSchema' is missing in props validation react/prop-types - 19:50 error 'title' is missing in props validation react/prop-types - 19:57 error 'required' is missing in props validation react/prop-types - 28:34 error 'DescriptionField' is missing in props validation react/prop-types - 28:52 error 'idSchema' is missing in props validation react/prop-types - 28:62 error 'description' is missing in props validation react/prop-types - 38:10 error 'type' is missing in props validation react/prop-types - 38:28 error 'icon' is missing in props validation react/prop-types - 38:34 error 'className' is missing in props validation react/prop-types - 50:19 error 'index' is missing in props validation react/prop-types - 50:43 error 'className' is missing in props validation react/prop-types - 52:26 error 'hasToolbar' is missing in props validation react/prop-types - 53:12 error 'children' is missing in props validation react/prop-types - 56:11 error 'hasToolbar' is missing in props validation react/prop-types - 60:14 error 'hasMoveUp' is missing in props validation react/prop-types - 60:33 error 'hasMoveDown' is missing in props validation react/prop-types - 65:25 error 'disabled' is missing in props validation react/prop-types - 65:43 error 'readonly' is missing in props validation react/prop-types - 65:62 error 'hasMoveUp' is missing in props validation react/prop-types - 66:24 error 'onReorderClick' is missing in props validation react/prop-types - 66:45 error 'index' is missing in props validation react/prop-types - 66:58 error 'index' is missing in props validation react/prop-types - 70:14 error 'hasMoveUp' is missing in props validation react/prop-types - 70:33 error 'hasMoveDown' is missing in props validation react/prop-types - 75:25 error 'disabled' is missing in props validation react/prop-types - 75:43 error 'readonly' is missing in props validation react/prop-types - 75:62 error 'hasMoveDown' is missing in props validation react/prop-types - 76:24 error 'onReorderClick' is missing in props validation react/prop-types - 76:45 error 'index' is missing in props validation react/prop-types - 76:58 error 'index' is missing in props validation react/prop-types - 80:14 error 'hasRemove' is missing in props validation react/prop-types - 85:25 error 'disabled' is missing in props validation react/prop-types - 85:43 error 'readonly' is missing in props validation react/prop-types - 86:24 error 'onDropIndexClick' is missing in props validation react/prop-types - 86:47 error 'index' is missing in props validation react/prop-types - 99:30 error 'className' is missing in props validation react/prop-types - 102:37 error 'idSchema' is missing in props validation react/prop-types - 102:46 error 'idSchema.$id' is missing in props validation react/prop-types - 103:23 error 'TitleField' is missing in props validation react/prop-types - 104:21 error 'idSchema' is missing in props validation react/prop-types - 105:18 error 'title' is missing in props validation react/prop-types - 106:21 error 'required' is missing in props validation react/prop-types - 109:11 error 'schema' is missing in props validation react/prop-types - 109:18 error 'schema.description' is missing in props validation react/prop-types - 110:72 error 'idSchema' is missing in props validation react/prop-types - 110:81 error 'idSchema.$id' is missing in props validation react/prop-types - 111:13 error 'schema' is missing in props validation react/prop-types - 111:20 error 'schema.description' is missing in props validation react/prop-types - 117:35 error 'idSchema' is missing in props validation react/prop-types - 117:44 error 'idSchema.$id' is missing in props validation react/prop-types - 119:12 error 'items' is missing in props validation react/prop-types - 119:27 error 'items' is missing in props validation react/prop-types - 119:33 error 'items.map' is missing in props validation react/prop-types - 122:11 error 'canAdd' is missing in props validation react/prop-types - 123:20 error 'onAddClick' is missing in props validation react/prop-types - 124:21 error 'disabled' is missing in props validation react/prop-types - 124:39 error 'readonly' is missing in props validation react/prop-types - 132:30 error 'className' is missing in props validation react/prop-types - 135:37 error 'idSchema' is missing in props validation react/prop-types - 135:46 error 'idSchema.$id' is missing in props validation react/prop-types - 136:23 error 'TitleField' is missing in props validation react/prop-types - 137:21 error 'idSchema' is missing in props validation react/prop-types - 138:18 error 'title' is missing in props validation react/prop-types - 139:21 error 'required' is missing in props validation react/prop-types - 142:11 error 'schema' is missing in props validation react/prop-types - 142:18 error 'schema.description' is missing in props validation react/prop-types - 144:44 error 'idSchema' is missing in props validation react/prop-types - 144:53 error 'idSchema.$id' is missing in props validation react/prop-types - 145:30 error 'DescriptionField' is missing in props validation react/prop-types - 146:22 error 'idSchema' is missing in props validation react/prop-types - 147:25 error 'schema' is missing in props validation react/prop-types - 147:32 error 'schema.description' is missing in props validation react/prop-types - 153:35 error 'idSchema' is missing in props validation react/prop-types - 153:44 error 'idSchema.$id' is missing in props validation react/prop-types - 155:12 error 'items' is missing in props validation react/prop-types - 155:27 error 'items' is missing in props validation react/prop-types - 155:33 error 'items.map' is missing in props validation react/prop-types - 155:42 error A function with a name starting with an uppercase letter should only be used as a constructor new-cap - 158:11 error 'canAdd' is missing in props validation react/prop-types - 159:20 error 'onAddClick' is missing in props validation react/prop-types - 160:21 error 'disabled' is missing in props validation react/prop-types - 160:39 error 'readonly' is missing in props validation react/prop-types - 213:2 error onAddClick should be placed before getStateFromProps react/sort-comp - 258:32 error Arrow function used ambiguously with a conditional expression no-confusing-arrow - 266:2 error render should be placed after renderArrayFieldItem react/sort-comp - 286:7 error 'name' is missing in props validation react/prop-types - 385:39 error 'name' is missing in props validation react/prop-types - 414:7 error 'name' is missing in props validation react/prop-types - 451:26 error Do not nest ternary expressions no-nested-ternary - 542:22 error 'onClick' is missing in props validation react/prop-types - 542:31 error 'disabled' is missing in props validation react/prop-types + 18:28 error 'TitleField' is missing in props validation react/prop-types + 18:40 error 'idSchema' is missing in props validation react/prop-types + 18:50 error 'title' is missing in props validation react/prop-types + 18:57 error 'required' is missing in props validation react/prop-types + 27:34 error 'DescriptionField' is missing in props validation react/prop-types + 27:52 error 'idSchema' is missing in props validation react/prop-types + 27:62 error 'description' is missing in props validation react/prop-types + 37:10 error 'type' is missing in props validation react/prop-types + 37:28 error 'icon' is missing in props validation react/prop-types + 37:34 error 'className' is missing in props validation react/prop-types + 49:19 error 'index' is missing in props validation react/prop-types + 49:43 error 'className' is missing in props validation react/prop-types + 51:26 error 'hasToolbar' is missing in props validation react/prop-types + 52:12 error 'children' is missing in props validation react/prop-types + 55:11 error 'hasToolbar' is missing in props validation react/prop-types + 59:14 error 'hasMoveUp' is missing in props validation react/prop-types + 59:33 error 'hasMoveDown' is missing in props validation react/prop-types + 64:25 error 'disabled' is missing in props validation react/prop-types + 64:43 error 'readonly' is missing in props validation react/prop-types + 64:62 error 'hasMoveUp' is missing in props validation react/prop-types + 65:24 error 'onReorderClick' is missing in props validation react/prop-types + 65:45 error 'index' is missing in props validation react/prop-types + 65:58 error 'index' is missing in props validation react/prop-types + 69:14 error 'hasMoveUp' is missing in props validation react/prop-types + 69:33 error 'hasMoveDown' is missing in props validation react/prop-types + 74:25 error 'disabled' is missing in props validation react/prop-types + 74:43 error 'readonly' is missing in props validation react/prop-types + 74:62 error 'hasMoveDown' is missing in props validation react/prop-types + 75:24 error 'onReorderClick' is missing in props validation react/prop-types + 75:45 error 'index' is missing in props validation react/prop-types + 75:58 error 'index' is missing in props validation react/prop-types + 79:14 error 'hasRemove' is missing in props validation react/prop-types + 84:25 error 'disabled' is missing in props validation react/prop-types + 84:43 error 'readonly' is missing in props validation react/prop-types + 85:24 error 'onDropIndexClick' is missing in props validation react/prop-types + 85:47 error 'index' is missing in props validation react/prop-types + 98:30 error 'className' is missing in props validation react/prop-types + 101:37 error 'idSchema' is missing in props validation react/prop-types + 101:46 error 'idSchema.$id' is missing in props validation react/prop-types + 102:23 error 'TitleField' is missing in props validation react/prop-types + 103:21 error 'idSchema' is missing in props validation react/prop-types + 104:18 error 'title' is missing in props validation react/prop-types + 105:21 error 'required' is missing in props validation react/prop-types + 108:11 error 'schema' is missing in props validation react/prop-types + 108:18 error 'schema.description' is missing in props validation react/prop-types + 109:72 error 'idSchema' is missing in props validation react/prop-types + 109:81 error 'idSchema.$id' is missing in props validation react/prop-types + 110:13 error 'schema' is missing in props validation react/prop-types + 110:20 error 'schema.description' is missing in props validation react/prop-types + 116:35 error 'idSchema' is missing in props validation react/prop-types + 116:44 error 'idSchema.$id' is missing in props validation react/prop-types + 118:12 error 'items' is missing in props validation react/prop-types + 118:27 error 'items' is missing in props validation react/prop-types + 118:33 error 'items.map' is missing in props validation react/prop-types + 121:11 error 'canAdd' is missing in props validation react/prop-types + 122:20 error 'onAddClick' is missing in props validation react/prop-types + 123:21 error 'disabled' is missing in props validation react/prop-types + 123:39 error 'readonly' is missing in props validation react/prop-types + 131:30 error 'className' is missing in props validation react/prop-types + 134:37 error 'idSchema' is missing in props validation react/prop-types + 134:46 error 'idSchema.$id' is missing in props validation react/prop-types + 135:23 error 'TitleField' is missing in props validation react/prop-types + 136:21 error 'idSchema' is missing in props validation react/prop-types + 137:18 error 'title' is missing in props validation react/prop-types + 138:21 error 'required' is missing in props validation react/prop-types + 141:11 error 'schema' is missing in props validation react/prop-types + 141:18 error 'schema.description' is missing in props validation react/prop-types + 143:44 error 'idSchema' is missing in props validation react/prop-types + 143:53 error 'idSchema.$id' is missing in props validation react/prop-types + 144:30 error 'DescriptionField' is missing in props validation react/prop-types + 145:22 error 'idSchema' is missing in props validation react/prop-types + 146:25 error 'schema' is missing in props validation react/prop-types + 146:32 error 'schema.description' is missing in props validation react/prop-types + 152:35 error 'idSchema' is missing in props validation react/prop-types + 152:44 error 'idSchema.$id' is missing in props validation react/prop-types + 154:12 error 'items' is missing in props validation react/prop-types + 154:27 error 'items' is missing in props validation react/prop-types + 154:33 error 'items.map' is missing in props validation react/prop-types + 154:42 error A function with a name starting with an uppercase letter should only be used as a constructor new-cap + 157:11 error 'canAdd' is missing in props validation react/prop-types + 158:20 error 'onAddClick' is missing in props validation react/prop-types + 159:21 error 'disabled' is missing in props validation react/prop-types + 159:39 error 'readonly' is missing in props validation react/prop-types + 181:2 error itemTitle should be placed after onSelectChange react/sort-comp + 204:32 error Unexpected block statement surrounding arrow body arrow-body-style + 216:40 error Unexpected block statement surrounding arrow body arrow-body-style + 234:32 error Unexpected block statement surrounding arrow body arrow-body-style + 250:2 error render should be placed after renderArrayFieldItem react/sort-comp + 271:4 error 'name' is missing in props validation react/prop-types + 277:4 error 'formContext' is missing in props validation react/prop-types + 370:39 error 'name' is missing in props validation react/prop-types + 400:4 error 'name' is missing in props validation react/prop-types + 437:26 error Do not nest ternary expressions no-nested-ternary + 528:22 error 'onClick' is missing in props validation react/prop-types + 528:31 error 'disabled' is missing in props validation react/prop-types /home/travis/build/Talend/ui/packages/forms/src/fields/BooleanField.js 25:3 error 'name' is missing in props validation react/prop-types -/home/travis/build/Talend/ui/packages/forms/src/fields/ObjectField.js - 82:2 error onPropertyChange should be placed before getStateFromProps react/sort-comp - 91:4 error 'name' is missing in props validation react/prop-types - 97:4 error 'onBlur' is missing in props validation react/prop-types - 153:29 error 'name' is already declared in the upper scope no-shadow - /home/travis/build/Talend/ui/packages/forms/src/fields/StringField.js 14:3 error 'name' is missing in props validation react/prop-types - 71:21 error Missing trailing comma comma-dangle 77:16 error 'formContext' PropType is defined but prop is never used react/no-unused-prop-types -✖ 100 problems (100 errors, 0 warnings) +✖ 98 problems (98 errors, 0 warnings) Errored while running command 'npm' with arguments 'run lint:es' in 'react-talend-forms' Errored while running ExecCommand.execute diff --git a/packages/forms/src/fields/ArrayField.js b/packages/forms/src/fields/ArrayField.js index e0a5a4e421..796220608c 100644 --- a/packages/forms/src/fields/ArrayField.js +++ b/packages/forms/src/fields/ArrayField.js @@ -1,24 +1,23 @@ import React, { Component, PropTypes } from 'react'; import { - getWidget, - getDefaultFormState, - getUiOptions, - isMultiSelect, - isFilesArray, - isFixedItems, - allowAdditionalItems, - optionsList, - retrieveSchema, - toIdSchema, - shouldRender, - getDefaultRegistry, - setState, + getWidget, + getDefaultFormState, + getUiOptions, + isMultiSelect, + isFilesArray, + isFixedItems, + allowAdditionalItems, + optionsList, + retrieveSchema, + toIdSchema, + shouldRender, + getDefaultRegistry, } from 'react-jsonschema-form/lib/utils'; function ArrayFieldTitle({ TitleField, idSchema, title, required }) { if (!title) { - // See #312: Ensure compatibility with old versions of React. + // See #312: Ensure compatibility with old versions of React. return
; } const id = `${idSchema.$id}__title`; @@ -27,7 +26,7 @@ function ArrayFieldTitle({ TitleField, idSchema, title, required }) { function ArrayFieldDescription({ DescriptionField, idSchema, description }) { if (!description) { - // See #312: Ensure compatibility with old versions of React. + // See #312: Ensure compatibility with old versions of React. return
; } const id = `${idSchema.$id}__description`; @@ -166,6 +165,7 @@ function DefaultNormalArrayFieldTemplate(props) { class ArrayField extends Component { static defaultProps = { uiSchema: {}, + formData: [], idSchema: {}, registry: getDefaultRegistry(), required: false, @@ -174,23 +174,6 @@ class ArrayField extends Component { autofocus: false, }; - constructor(props) { - super(props); - this.state = this.getStateFromProps(props); - } - - componentWillReceiveProps(nextProps) { - this.setState(this.getStateFromProps(nextProps)); - } - - getStateFromProps(props) { - const formData = Array.isArray(props.formData) ? props.formData : null; - const { definitions } = this.props.registry; - return { - items: getDefaultFormState(props.schema, formData, definitions) || [], - }; - } - shouldComponentUpdate(nextProps, nextState) { return shouldRender(this, nextProps, nextState); } @@ -204,63 +187,64 @@ class ArrayField extends Component { return itemsSchema.type === 'string' && itemsSchema.minLength > 0; } - asyncSetState(state, options = { validate: false }) { - setState(this, state, () => { - this.props.onChange(this.state.items, options); - }); - } - onAddClick = (event) => { event.preventDefault(); - const { items } = this.state; - const { schema, registry } = this.props; + const { schema, registry, formData } = this.props; const { definitions } = registry; let itemSchema = schema.items; if (isFixedItems(schema) && allowAdditionalItems(schema)) { itemSchema = schema.additionalItems; } - this.asyncSetState({ - items: items.concat([ - getDefaultFormState(itemSchema, undefined, definitions), - ]), - }); + this.props.onChange([ + ...formData, + getDefaultFormState(itemSchema, undefined, definitions), + ], { validate: false }); }; - onDropIndexClick = (index) => (event) => { - if (event) { - event.preventDefault(); - } - this.asyncSetState({ - items: this.state.items.filter((_, i) => i !== index), - }, { validate: true }); // refs #195 + onDropIndexClick = (index) => { + return (event) => { + if (event) { + event.preventDefault(); + } + this.props.onChange( + this.props.formData.filter((_, i) => i !== index), + { validate: true } // refs #195 + ); + }; }; - onReorderClick = (index, newIndex) => (event) => { - if (event) { - event.preventDefault(); - event.target.blur(); - } - const { items } = this.state; - this.asyncSetState({ - items: items.map((item, i) => { + onReorderClick = (index, newIndex) => { + return (event) => { + if (event) { + event.preventDefault(); + event.target.blur(); + } + const { formData, onChange } = this.props; + onChange(formData.map((item, i) => { if (i === newIndex) { - return items[index]; + return formData[index]; } else if (i === index) { - return items[newIndex]; + return formData[newIndex]; } return item; - }), - }, { validate: true }); + }), { validate: true }); + }; }; - onChangeForIndex = (index) => (value) => { - this.asyncSetState({ - items: this.state.items.map((item, i) => index === i ? value : item), - }); + onChangeForIndex = (index) => { + return (value) => { + const { formData, onChange } = this.props; + onChange(formData.map((item, i) => { + // We need to treat undefined items as nulls to have validation. + // See https://github.com/tdegrunt/jsonschema/issues/206 + const jsonValue = typeof value === 'undefined' ? null : value; + return index === i ? jsonValue : item; + }), { validate: false }); + }; }; onSelectChange = (value) => { - this.asyncSetState({ items: value }); + this.props.onChange(value, { validate: false }); }; render() { @@ -279,28 +263,27 @@ class ArrayField extends Component { renderNormalArray() { const { - schema, - uiSchema, - errorSchema, - idSchema, - name, - required, - disabled, - readonly, - autofocus, - registry, - onBlur, - onChange, + schema, + uiSchema, formData, - } = this.props; + errorSchema, + idSchema, + name, + required, + disabled, + readonly, + autofocus, + registry, + formContext, + onChange, + onBlur, + } = this.props; const title = (schema.title === undefined) ? name : schema.title; - const { items = [] } = this.state; const { ArrayFieldTemplate, definitions, fields, widgets } = registry; const { TitleField, DescriptionField } = fields; const itemsSchema = retrieveSchema(schema.items, definitions); const { widget, addable = true, ...options } = getUiOptions(uiSchema); - // widget if (typeof widget === 'string') { if (widget === 'hidden') { return null; @@ -323,18 +306,18 @@ class ArrayField extends Component { const arrayProps = { canAdd: addable, - items: items.map((item, index) => { + items: formData.map((item, index) => { const itemErrorSchema = errorSchema ? errorSchema[index] : undefined; const itemIdPrefix = `${idSchema.$id}_${index}`; const itemIdSchema = toIdSchema(itemsSchema, itemIdPrefix, definitions); return this.renderArrayFieldItem({ index, canMoveUp: index > 0, - canMoveDown: index < items.length - 1, + canMoveDown: index < formData.length - 1, itemSchema: itemsSchema, itemIdSchema, itemErrorSchema, - itemData: items[index], + itemData: formData[index], itemUiSchema: uiSchema.items, autofocus: autofocus && index === 0, onBlur, @@ -350,17 +333,18 @@ class ArrayField extends Component { schema, title, TitleField, + formContext, }; - // Check if a custom render function was passed in + // Check if a custom render function was passed in const renderFunction = ArrayFieldTemplate || DefaultNormalArrayFieldTemplate; return renderFunction(arrayProps); } renderMultiSelect() { const { schema, idSchema, uiSchema, disabled, readonly, autofocus, onBlur } = this.props; - const { items } = this.state; - const { widgets, definitions } = this.props.registry; + const items = this.props.formData; + const { widgets, definitions, formContext } = this.props.registry; const itemsSchema = retrieveSchema(schema.items, definitions); const enumOptions = optionsList(itemsSchema); const { widget = 'select', ...options } = { ...getUiOptions(uiSchema), enumOptions }; @@ -376,6 +360,7 @@ class ArrayField extends Component { value={items} disabled={disabled} readonly={readonly} + formContext={formContext} autofocus={autofocus} /> ); @@ -384,8 +369,8 @@ class ArrayField extends Component { renderFiles() { const { schema, uiSchema, idSchema, name, disabled, readonly, autofocus, onBlur } = this.props; const title = schema.title || name; - const { items } = this.state; - const { widgets } = this.props.registry; + const items = this.props.formData; + const { widgets, formContext } = this.props.registry; const { widget = 'files', ...options } = getUiOptions(uiSchema); const Widget = getWidget(schema, widget, widgets); return ( @@ -400,6 +385,7 @@ class ArrayField extends Component { value={items} disabled={disabled} readonly={readonly} + formContext={formContext} autofocus={autofocus} /> ); @@ -407,36 +393,36 @@ class ArrayField extends Component { renderFixedArray() { const { - schema, - uiSchema, - errorSchema, - idSchema, - name, - required, - disabled, - readonly, - autofocus, - registry, - onBlur, - } = this.props; + schema, + uiSchema, + errorSchema, + idSchema, + name, + required, + disabled, + readonly, + autofocus, + registry, + onBlur, + } = this.props; const title = schema.title || name; - let { items } = this.state; + let items = this.props.formData; const { ArrayFieldTemplate, definitions, fields } = registry; const { TitleField } = fields; const itemSchemas = schema.items.map(item => - retrieveSchema(item, definitions)); + retrieveSchema(item, definitions)); const additionalSchema = allowAdditionalItems(schema) ? - retrieveSchema(schema.additionalItems, definitions) : null; + retrieveSchema(schema.additionalItems, definitions) : null; const { addable = true } = getUiOptions(uiSchema); const canAdd = addable && additionalSchema; if (!items || items.length < itemSchemas.length) { - // to make sure at least all fixed items are generated + // to make sure at least all fixed items are generated items = items || []; items = items.concat(new Array(itemSchemas.length - items.length)); } - // These are the props passed into the render function + // These are the props passed into the render function const arrayProps = { canAdd, className: 'field field-array field-array-fixed-items', @@ -449,9 +435,9 @@ class ArrayField extends Component { const itemIdPrefix = `${idSchema.$id}_${index}`; const itemIdSchema = toIdSchema(itemSchema, itemIdPrefix, definitions); const itemUiSchema = additional ? - uiSchema.additionalItems || {} : - Array.isArray(uiSchema.items) ? - uiSchema.items[index] : uiSchema.items || {}; + uiSchema.additionalItems || {} : + Array.isArray(uiSchema.items) ? + uiSchema.items[index] : uiSchema.items || {}; const itemErrorSchema = errorSchema ? errorSchema[index] : undefined; return this.renderArrayFieldItem({ @@ -476,24 +462,24 @@ class ArrayField extends Component { TitleField, }; - // Check if a custom template template was passed in + // Check if a custom template template was passed in const renderFunction = ArrayFieldTemplate || DefaultFixedArrayFieldTemplate; return renderFunction(arrayProps); } renderArrayFieldItem({ - index, - canRemove = true, - canMoveUp = true, - canMoveDown = true, - itemSchema, - itemData, - itemUiSchema, - itemIdSchema, - itemErrorSchema, - autofocus, - onBlur, - }) { + index, + canRemove = true, + canMoveUp = true, + canMoveDown = true, + itemSchema, + itemData, + itemUiSchema, + itemIdSchema, + itemErrorSchema, + autofocus, + onBlur, + }) { const { SchemaField } = this.props.registry.fields; const { disabled, readonly, uiSchema } = this.props; const { orderable, removable } = { @@ -524,7 +510,7 @@ class ArrayField extends Component { readonly={this.props.readonly} autofocus={autofocus} /> - ), + ), className: 'array-item', disabled, hasToolbar: has.toolbar, diff --git a/packages/forms/src/fields/ObjectField.js b/packages/forms/src/fields/ObjectField.js index 553c2ea5d8..d0e53007f8 100644 --- a/packages/forms/src/fields/ObjectField.js +++ b/packages/forms/src/fields/ObjectField.js @@ -1,98 +1,54 @@ import React, { Component, PropTypes } from 'react'; import { - deepEquals, - getDefaultFormState, orderProperties, retrieveSchema, shouldRender, - getDefaultRegistry, - setState, getUiOptions, getWidget, + getDefaultRegistry, } from 'react-jsonschema-form/lib/utils'; -function objectKeysHaveChanged(formData, state) { - // for performance, first check for lengths - const newKeys = Object.keys(formData); - const oldKeys = Object.keys(state); - if (newKeys.length < oldKeys.length) { - return true; - } - // deep check on sorted keys - if (!deepEquals(newKeys.sort(), oldKeys.sort())) { - return true; - } - return false; -} - class ObjectField extends Component { static defaultProps = { uiSchema: {}, + formData: {}, errorSchema: {}, idSchema: {}, registry: getDefaultRegistry(), required: false, disabled: false, readonly: false, - } - - constructor(props) { - super(props); - this.state = this.getStateFromProps(props); - } - - componentWillReceiveProps(nextProps) { - const state = this.getStateFromProps(nextProps); - const { formData } = nextProps; - if (formData && objectKeysHaveChanged(formData, this.state)) { - // We *need* to replace state entirely here has we have received formData - // holding different keys (so with some removed). - this.state = state; - this.forceUpdate(); - } else { - this.setState(state); - } - } - - getStateFromProps(props) { - const { schema, formData, registry } = props; - return getDefaultFormState(schema, formData, registry.definitions) || {}; - } + }; shouldComponentUpdate(nextProps, nextState) { return shouldRender(this, nextProps, nextState); } + onPropertyChange = (id, name) => (value, options) => { + const newFormData = { ...this.props.formData, [name]: value }; + if (this.props.registry.formContext.handleSchemaChange) { + this.props.registry.formContext.handleSchemaChange(newFormData, id, name, value, options); + } + this.props.onChange(newFormData, options); + }; + isRequired(name) { const schema = this.props.schema; return Array.isArray(schema.required) && schema.required.indexOf(name) !== -1; } - asyncSetState(state, options = { validate: false }, id, name, value) { - setState(this, state, () => { - if (this.props.registry.formContext.handleSchemaChange) { - this.props.registry.formContext.handleSchemaChange(this.state, id, name, value, options); - } - this.props.onChange(this.state, options); - }); - } - - onPropertyChange = (id, name) => (value, options) => { - this.asyncSetState({ [name]: value }, options, id, name, value); - }; - render() { const { uiSchema, + formData, errorSchema, idSchema, name, required, disabled, readonly, - formData, onChange, onBlur, } = this.props; @@ -100,7 +56,7 @@ class ObjectField extends Component { const { SchemaField, TitleField, DescriptionField } = fields; const schema = retrieveSchema(this.props.schema, definitions); const { widget, ...options } = getUiOptions(uiSchema); - // widget + if (typeof widget === 'string') { if (widget === 'hidden') { return null; @@ -119,6 +75,7 @@ class ObjectField extends Component { definitions={definitions} />); } + const title = (schema.title === undefined) ? name : schema.title; let orderedProperties; try { @@ -150,38 +107,40 @@ class ObjectField extends Component { formContext={formContext} /> : null} { - orderedProperties.map((name, index) => ( + orderedProperties.map((propName, index) => ( - )) - } + )) + } ); } } if (process.env.NODE_ENV !== 'production') { ObjectField.propTypes = { - schema: PropTypes.object.isRequired, - uiSchema: PropTypes.object, - errorSchema: PropTypes.object, - idSchema: PropTypes.object, + schema: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types + uiSchema: PropTypes.object, // eslint-disable-line react/forbid-prop-types + errorSchema: PropTypes.object, // eslint-disable-line react/forbid-prop-types + idSchema: PropTypes.object, // eslint-disable-line react/forbid-prop-types + formData: PropTypes.object, // eslint-disable-line react/forbid-prop-types onChange: PropTypes.func.isRequired, - formData: PropTypes.object, + onBlur: PropTypes.func, required: PropTypes.bool, disabled: PropTypes.bool, + name: PropTypes.string, readonly: PropTypes.bool, registry: PropTypes.shape({ widgets: PropTypes.objectOf(PropTypes.oneOfType([ diff --git a/packages/forms/src/fields/StringField.js b/packages/forms/src/fields/StringField.js index 25efa45846..9524c22740 100644 --- a/packages/forms/src/fields/StringField.js +++ b/packages/forms/src/fields/StringField.js @@ -68,7 +68,7 @@ if (process.env.NODE_ENV !== 'production') { registry: PropTypes.shape({ widgets: PropTypes.objectOf(PropTypes.oneOfType([ PropTypes.func, - PropTypes.object + PropTypes.object, ])).isRequired, fields: PropTypes.objectOf(PropTypes.func).isRequired, definitions: PropTypes.object.isRequired, diff --git a/packages/forms/src/widgets/ColumnsWidget/ColumnsWidget.js b/packages/forms/src/widgets/ColumnsWidget/ColumnsWidget.js index 8f5767c404..fe1415268b 100644 --- a/packages/forms/src/widgets/ColumnsWidget/ColumnsWidget.js +++ b/packages/forms/src/widgets/ColumnsWidget/ColumnsWidget.js @@ -26,7 +26,7 @@ Column.propTypes = { function onColumnChange(key, onChange, formData) { return function handleChange(change) { - onChange(Object.assign(formData, { [key]: change })); + onChange(Object.assign({}, formData, { [key]: change })); }; }