diff --git a/client/app/components/dynamic-form/DynamicForm.jsx b/client/app/components/dynamic-form/DynamicForm.jsx index b0ab61b1b0..b41b5630f9 100644 --- a/client/app/components/dynamic-form/DynamicForm.jsx +++ b/client/app/components/dynamic-form/DynamicForm.jsx @@ -7,21 +7,37 @@ import Checkbox from 'antd/lib/checkbox'; import Button from 'antd/lib/button'; import Upload from 'antd/lib/upload'; import Icon from 'antd/lib/icon'; -import { includes, isFunction } from 'lodash'; +import { includes, isFunction, isPlainObject, isArray } from 'lodash'; import Select from 'antd/lib/select'; import notification from '@/services/notification'; import { Field, Action, AntdForm } from '../proptypes'; import helper from './dynamicFormHelper'; +const { TextArea } = Input; + const fieldRules = ({ type, required, minLength }) => { const requiredRule = required; const minLengthRule = minLength && includes(['text', 'email', 'password'], type); const emailTypeRule = type === 'email'; + const jsonRule = type === 'json'; return [ requiredRule && { required, message: 'This field is required.' }, minLengthRule && { min: minLength, message: 'This field is too short.' }, emailTypeRule && { type: 'email', message: 'This field must be a valid email.' }, + jsonRule && { + type: 'object', + transform(x) { + if (x.trim()) { + try { + JSON.parse(x); + } catch { + return ''; + } + } + }, + message: 'This field must be a JSON string.', + }, ].filter(rule => rule); }; @@ -74,13 +90,22 @@ class DynamicForm extends React.Component { })); }; + parseValues = (values) => { + this.props.fields.forEach((field) => { + if (field.type === 'json' && field.name in values) { + values[field.name] = JSON.parse(values[field.name]); + } + }); + return values; + }; + handleSubmit = (e) => { this.setState({ isSubmitting: true }); e.preventDefault(); this.props.form.validateFieldsAndScroll((err, values) => { if (!err) { this.props.onSubmit( - values, + this.parseValues(values), (msg) => { const { setFieldsValue, getFieldsValue } = this.props.form; this.setState({ isSubmitting: false }); @@ -155,8 +180,13 @@ class DynamicForm extends React.Component { renderField(field, props) { const { getFieldDecorator } = this.props.form; - const { name, type, initialValue } = field; + const { name, type } = field; const fieldLabel = field.title || helper.toHuman(name); + let initialValue = field.initialValue; + + if (isPlainObject(initialValue) || isArray(initialValue)) { + initialValue = JSON.stringify(field.initialValue); + } const options = { rules: fieldRules(field), @@ -174,6 +204,8 @@ class DynamicForm extends React.Component { return field.content; } else if (type === 'number') { return getFieldDecorator(name, options)(); + } else if (type === 'json') { + return getFieldDecorator(name, options)(