Fix UI when loading invalid style with duplicate layer ids.

Also fix for throwing error when 2 layers exist with empty strings as ids.
This commit is contained in:
orangemug
2020-03-28 10:58:47 +00:00
parent f70d078ec6
commit 74b47e7e74
6 changed files with 82 additions and 38 deletions
+41 -23
View File
@@ -36,6 +36,7 @@ import tokens from '../config/tokens.json'
import isEqual from 'lodash.isequal'
import Debug from '../libs/debug'
import queryUtil from '../libs/query-util'
import {formatLayerId} from './util/format';
import MapboxGl from 'mapbox-gl'
@@ -325,6 +326,30 @@ export default class App extends React.Component {
};
const errors = validate(newStyle, latest) || [];
// The validate function doesn't give us errors for duplicate error with
// empty string for layer.id, manually deal with that here.
const layerErrors = [];
if (newStyle && newStyle.layers) {
const foundLayers = new Map();
newStyle.layers.forEach((layer, index) => {
if (layer.id === "" && foundLayers.has(layer.id)) {
const message = `Duplicate layer: ${formatLayerId(layer.id)}`;
layerErrors.push({
message,
parsed: {
type: "layer",
data: {
index,
message,
}
}
});
}
foundLayers.set(layer.id, true);
});
}
const mappedErrors = errors.map(error => {
const layerMatch = error.message.match(/layers\[(\d+)\]\.(?:(\S+)\.)?(\S+): (.*)/);
if (layerMatch) {
@@ -347,7 +372,7 @@ export default class App extends React.Component {
message: error.message,
};
}
})
}).concat(layerErrors);
let dirtyMapStyle = undefined;
if (errors.length > 0) {
@@ -437,56 +462,50 @@ export default class App extends React.Component {
this.onStyleChanged(changedStyle)
}
onLayerDestroy = (layerId) => {
onLayerDestroy = (index) => {
let layers = this.state.mapStyle.layers;
const remainingLayers = layers.slice(0);
const idx = style.indexOfLayer(remainingLayers, layerId)
remainingLayers.splice(idx, 1);
remainingLayers.splice(index, 1);
this.onLayersChange(remainingLayers);
}
onLayerCopy = (layerId) => {
onLayerCopy = (index) => {
let layers = this.state.mapStyle.layers;
const changedLayers = layers.slice(0)
const idx = style.indexOfLayer(changedLayers, layerId)
const clonedLayer = cloneDeep(changedLayers[idx])
const clonedLayer = cloneDeep(changedLayers[index])
clonedLayer.id = clonedLayer.id + "-copy"
changedLayers.splice(idx, 0, clonedLayer)
changedLayers.splice(index, 0, clonedLayer)
this.onLayersChange(changedLayers)
}
onLayerVisibilityToggle = (layerId) => {
onLayerVisibilityToggle = (index) => {
let layers = this.state.mapStyle.layers;
const changedLayers = layers.slice(0)
const idx = style.indexOfLayer(changedLayers, layerId)
const layer = { ...changedLayers[idx] }
const layer = { ...changedLayers[index] }
const changedLayout = 'layout' in layer ? {...layer.layout} : {}
changedLayout.visibility = changedLayout.visibility === 'none' ? 'visible' : 'none'
layer.layout = changedLayout
changedLayers[idx] = layer
changedLayers[index] = layer
this.onLayersChange(changedLayers)
}
onLayerIdChange = (oldId, newId) => {
onLayerIdChange = (index, oldId, newId) => {
const changedLayers = this.state.mapStyle.layers.slice(0)
const idx = style.indexOfLayer(changedLayers, oldId)
changedLayers[idx] = {
...changedLayers[idx],
changedLayers[index] = {
...changedLayers[index],
id: newId
}
this.onLayersChange(changedLayers)
}
onLayerChanged = (layer) => {
onLayerChanged = (index, layer) => {
const changedLayers = this.state.mapStyle.layers.slice(0)
const idx = style.indexOfLayer(changedLayers, layer.id)
changedLayers[idx] = layer
changedLayers[index] = layer
this.onLayersChange(changedLayers)
}
@@ -645,9 +664,8 @@ export default class App extends React.Component {
</div>
}
onLayerSelect = (layerId) => {
const idx = style.indexOfLayer(this.state.mapStyle.layers, layerId)
this.setState({ selectedLayerIndex: idx })
onLayerSelect = (index) => {
this.setState({ selectedLayerIndex: index })
}
setModal(modalName, value) {