Added JSON error to expression editor

This commit is contained in:
orangemug 2020-02-25 09:20:14 +00:00
parent 97a61afc24
commit 1b3d8b5b79
5 changed files with 75 additions and 31 deletions

View file

@ -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 <InputBlock
error={error}
error={foundErrors}
fieldSpec={this.props.fieldSpec}
label={labelFromFieldName(this.props.fieldName)}
action={deleteStopBtn}
@ -86,6 +112,8 @@ export default class ExpressionProperty extends React.Component {
className="maputnik-expression-editor"
onFocus={this.props.onFocus}
onBlur={this.props.onBlur}
onJSONInvalid={this.onJSONInvalid}
onJSONValid={this.onJSONValid}
layer={value}
lineNumbers={false}
maxHeight={200}

View file

@ -1,6 +1,13 @@
import capitalize from 'lodash.capitalize'
export default function labelFromFieldName(fieldName) {
let label = fieldName.split('-').slice(1).join(' ')
return capitalize(label)
let label;
const parts = fieldName.split('-');
if (parts.length > 1) {
label = fieldName.split('-').slice(1).join(' ');
}
else {
label = fieldName;
}
return capitalize(label);
}

View file

@ -239,7 +239,7 @@ export default class CombiningFilterEditor extends React.Component {
<InputBlock
key="top"
fieldSpec={fieldSpec}
label={"Compound filter"}
label={"Filter"}
action={actions}
>
<SelectInput
@ -273,14 +273,6 @@ export default class CombiningFilterEditor extends React.Component {
else {
let {filter} = this.props;
const errorMessage = Object.entries(errors)
.filter(([k, v]) => k.match(/filter(\[\d+\])?/))
.map(([k, v]) => {
return v.message;
})
.join("\n")
const error = errorMessage ? {message: errorMessage} : null;
return (
<>
<ExpressionProperty
@ -288,10 +280,10 @@ export default class CombiningFilterEditor extends React.Component {
this.setState({displaySimpleFilter: true});
this.props.onChange(defaultFilter);
}}
fieldName="filter-compound-filter"
fieldName="filter"
fieldSpec={fieldSpec}
value={filter}
error={error}
errors={errors}
onChange={this.props.onChange}
/>
{this.state.valueIsSimpleFilter &&

View file

@ -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 <div style={this.props.style}
data-wd-key={this.props["data-wd-key"]}
className={classnames({
@ -71,9 +73,11 @@ class InputBlock extends React.Component {
<div className="maputnik-input-block-content">
{this.props.children}
</div>
{this.props.error &&
{errors.length > 0 &&
<div className="maputnik-inline-error">
{this.props.error.message}
{[].concat(this.props.error).map(error => {
return <div>{error.message}</div>
})}
</div>
}
{this.props.fieldSpec &&

View file

@ -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();
}
}