mirror of
https://github.com/maputnik/editor.git
synced 2025-12-27 00:20:00 +00:00
Added initial expression work and UI errors.
This commit is contained in:
@@ -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}
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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>
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user