diff --git a/src/components/fields/_ExpressionProperty.jsx b/src/components/fields/_ExpressionProperty.jsx index f9214eff..b50fbb52 100644 --- a/src/components/fields/_ExpressionProperty.jsx +++ b/src/components/fields/_ExpressionProperty.jsx @@ -34,10 +34,26 @@ export default class ExpressionProperty extends React.Component { constructor (props) { super(); + this.state = { + jsonError: false, + }; + } + + onJSONInvalid = (err) => { + this.setState({ + jsonError: true, + }) + } + + onJSONValid = () => { + this.setState({ + jsonError: false, + }) } render() { const {errors, fieldName, fieldType, value, canUndo} = this.props; + const {jsonError} = this.state; const undoDisabled = canUndo ? !canUndo() : true; const deleteStopBtn = ( @@ -62,21 +78,31 @@ export default class ExpressionProperty extends React.Component { ); - const fieldError = errors[fieldType+"."+fieldName]; - const errorKeyStart = `${fieldType}.${fieldName}[`; - const foundErrors = Object.entries(errors).filter(([key, error]) => { - return key.startsWith(errorKeyStart); - }); - let message = foundErrors.map(([key, error]) => { - return error.message; - }).join(""); - if (fieldError) { - message = fieldError.message + message; + const fieldKey = fieldType === undefined ? fieldName : `${fieldType}.${fieldName}`; + + const fieldError = errors[fieldKey]; + const errorKeyStart = `${fieldKey}[`; + const foundErrors = []; + + if (jsonError) { + foundErrors.push({message: "Invalid JSON"}); + } + else { + Object.entries(errors) + .filter(([key, error]) => { + return key.startsWith(errorKeyStart); + }) + .forEach(([key, error]) => { + return foundErrors.push(error); + }) + + if (fieldError) { + foundErrors.push(fieldError); + } } - const error = message ? {message} : undefined; return 1) { + label = fieldName.split('-').slice(1).join(' '); + } + else { + label = fieldName; + } + return capitalize(label); } diff --git a/src/components/filter/FilterEditor.jsx b/src/components/filter/FilterEditor.jsx index 9b05fe8b..57094766 100644 --- a/src/components/filter/FilterEditor.jsx +++ b/src/components/filter/FilterEditor.jsx @@ -239,7 +239,7 @@ export default class CombiningFilterEditor extends React.Component { k.match(/filter(\[\d+\])?/)) - .map(([k, v]) => { - return v.message; - }) - .join("\n") - const error = errorMessage ? {message: errorMessage} : null; - return ( <> {this.state.valueIsSimpleFilter && diff --git a/src/components/inputs/InputBlock.jsx b/src/components/inputs/InputBlock.jsx index 378d3450..6925fbad 100644 --- a/src/components/inputs/InputBlock.jsx +++ b/src/components/inputs/InputBlock.jsx @@ -19,7 +19,7 @@ class InputBlock extends React.Component { onChange: PropTypes.func, fieldSpec: PropTypes.object, wideMode: PropTypes.bool, - error: PropTypes.object, + error: PropTypes.array, } constructor (props) { @@ -41,6 +41,8 @@ class InputBlock extends React.Component { } render() { + const errors = [].concat(this.props.error || []); + return
{this.props.children}
- {this.props.error && + {errors.length > 0 &&
- {this.props.error.message} + {[].concat(this.props.error).map(error => { + return
{error.message}
+ })}
} {this.props.fieldSpec && diff --git a/src/components/layers/JSONEditor.jsx b/src/components/layers/JSONEditor.jsx index 0e2ae5bd..80ce055e 100644 --- a/src/components/layers/JSONEditor.jsx +++ b/src/components/layers/JSONEditor.jsx @@ -30,6 +30,8 @@ class JSONEditor extends React.Component { className: PropTypes.string, onFocus: PropTypes.func, onBlur: PropTypes.func, + onJSONValid: PropTypes.func, + onJSONInvalid: PropTypes.func, } static defaultProps = { @@ -41,6 +43,8 @@ class JSONEditor extends React.Component { }, onFocus: () => {}, onBlur: () => {}, + onJSONInvalid: () => {}, + onJSONValid: () => {}, } constructor(props) { @@ -114,11 +118,20 @@ class JSONEditor extends React.Component { const newCode = this._doc.getValue(); if (this.state.prevValue !== newCode) { + let parsedLayer, err; try { - const parsedLayer = JSON.parse(newCode) + parsedLayer = JSON.parse(newCode); + } catch(_err) { + err = _err; + console.warn(_err) + } + + if (err) { + this.props.onJSONInvalid(); + } + else { this.props.onChange(parsedLayer) - } catch(err) { - console.warn(err) + this.props.onJSONValid(); } }