Added initial expression work and UI errors.

This commit is contained in:
orangemug
2020-01-29 08:22:03 +00:00
parent 63ed8c1de3
commit 725b752e35
25 changed files with 360 additions and 53 deletions

View File

@@ -20,6 +20,10 @@ import { changeType, changeProperty } from '../../libs/layer'
import layout from '../../config/layout.json'
function getLayoutForType (type) {
return layout[type] ? layout[type] : layout.invalid;
}
function layoutGroups(layerType) {
const layerGroup = {
title: 'Layer',
@@ -33,7 +37,9 @@ function layoutGroups(layerType) {
title: 'JSON Editor',
type: 'jsoneditor'
}
return [layerGroup, filterGroup].concat(layout[layerType].groups).concat([editorGroup])
return [layerGroup, filterGroup]
.concat(getLayoutForType(layerType).groups)
.concat([editorGroup])
}
/** Layer editor supporting multiple types of layers. */
@@ -79,7 +85,7 @@ export default class LayerEditor extends React.Component {
static getDerivedStateFromProps(props, state) {
const additionalGroups = { ...state.editorGroups }
layout[props.layer.type].groups.forEach(group => {
getLayoutForType(props.layer.type).groups.forEach(group => {
if(!(group.title in additionalGroups)) {
additionalGroups[group.title] = true
}
@@ -118,6 +124,20 @@ export default class LayerEditor extends React.Component {
if(this.props.layer.metadata) {
comment = this.props.layer.metadata['maputnik:comment']
}
const {errors, layerIndex} = this.props;
const errorData = {};
errors.forEach(error => {
if (
error.parsed &&
error.parsed.type === "layer" &&
error.parsed.data.index == layerIndex
) {
errorData[error.parsed.data.key] = {
message: error.parsed.data.message
};
}
})
let sourceLayerIds;
if(this.props.sources.hasOwnProperty(this.props.layer.source)) {
@@ -129,13 +149,16 @@ export default class LayerEditor extends React.Component {
<LayerIdBlock
value={this.props.layer.id}
wdKey="layer-editor.layer-id"
error={errorData.id}
onChange={newId => this.props.onLayerIdChange(this.props.layer.id, newId)}
/>
<LayerTypeBlock
error={errorData.type}
value={this.props.layer.type}
onChange={newType => this.props.onLayerChanged(changeType(this.props.layer, newType))}
/>
{this.props.layer.type !== 'background' && <LayerSourceBlock
error={errorData.sources}
sourceIds={Object.keys(this.props.sources)}
value={this.props.layer.source}
onChange={v => this.changeProperty(null, 'source', v)}
@@ -143,20 +166,24 @@ export default class LayerEditor extends React.Component {
}
{['background', 'raster', 'hillshade', 'heatmap'].indexOf(this.props.layer.type) < 0 &&
<LayerSourceLayerBlock
error={errorData['source-layer']}
sourceLayerIds={sourceLayerIds}
value={this.props.layer['source-layer']}
onChange={v => this.changeProperty(null, 'source-layer', v)}
/>
}
<MinZoomBlock
error={errorData.minzoom}
value={this.props.layer.minzoom}
onChange={v => this.changeProperty(null, 'minzoom', v)}
/>
<MaxZoomBlock
error={errorData.maxzoom}
value={this.props.layer.maxzoom}
onChange={v => this.changeProperty(null, 'maxzoom', v)}
/>
<CommentBlock
error={errorData.comment}
value={comment}
onChange={v => this.changeProperty('metadata', 'maputnik:comment', v == "" ? undefined : v)}
/>
@@ -164,6 +191,7 @@ export default class LayerEditor extends React.Component {
case 'filter': return <div>
<div className="maputnik-filter-editor-wrapper">
<FilterEditor
errors={errorData}
filter={this.props.layer.filter}
properties={this.props.vectorLayers[this.props.layer['source-layer']]}
onChange={f => this.changeProperty(null, 'filter', f)}
@@ -171,6 +199,7 @@ export default class LayerEditor extends React.Component {
</div>
</div>
case 'properties': return <PropertyGroup
errors={errorData}
layer={this.props.layer}
groupFields={fields}
spec={this.props.spec}

View File

@@ -181,10 +181,19 @@ class LayerListContainer extends React.Component {
layers.forEach((layer, idxInGroup) => {
const groupIdx = findClosestCommonPrefix(this.props.layers, idx)
const layerError = this.props.errors.find(error => {
return (
error.parsed &&
error.parsed.type === "layer" &&
error.parsed.data.index == idx
);
});
const listItem = <LayerListItem
className={classnames({
'maputnik-layer-list-item-collapsed': layers.length > 1 && this.isCollapsed(groupPrefix, groupIdx) && idx !== this.props.selectedLayerIndex,
'maputnik-layer-list-item-group-last': idxInGroup == layers.length - 1 && layers.length > 1
'maputnik-layer-list-item-group-last': idxInGroup == layers.length - 1 && layers.length > 1,
'maputnik-layer-list-item--error': !!layerError
})}
index={idx}
key={layer.id}

View File

@@ -4,6 +4,7 @@ import PropTypes from 'prop-types'
import {latest} from '@mapbox/mapbox-gl-style-spec'
import InputBlock from '../inputs/InputBlock'
import SelectInput from '../inputs/SelectInput'
import StringInput from '../inputs/StringInput'
class LayerTypeBlock extends React.Component {
static propTypes = {
@@ -15,21 +16,11 @@ class LayerTypeBlock extends React.Component {
render() {
return <InputBlock label={"Type"} doc={latest.layer.type.doc}
data-wd-key={this.props.wdKey}
error={this.props.error}
>
<SelectInput
options={[
['background', 'Background'],
['fill', 'Fill'],
['line', 'Line'],
['symbol', 'Symbol'],
['raster', 'Raster'],
['circle', 'Circle'],
['fill-extrusion', 'Fill Extrusion'],
['hillshade', 'Hillshade'],
['heatmap', 'Heatmap'],
]}
onChange={this.props.onChange}
<StringInput
value={this.props.value}
disabled={true}
/>
</InputBlock>
}

View File

@@ -13,6 +13,7 @@ class MaxZoomBlock extends React.Component {
render() {
return <InputBlock label={"Max Zoom"} doc={latest.layer.maxzoom.doc}
error={this.props.error}
data-wd-key="max-zoom"
>
<NumberInput

View File

@@ -13,6 +13,7 @@ class MinZoomBlock extends React.Component {
render() {
return <InputBlock label={"Min Zoom"} doc={latest.layer.minzoom.doc}
error={this.props.error}
data-wd-key="min-zoom"
>
<NumberInput