mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Maps] better error handling when layer configs can not be found (#29534)
* [Maps] better error handling when layer configs can not be found * remove kibana.yml changes * gis-map to map * throw exception for getStringFields and getAttributions and then handle exceptions in caller
This commit is contained in:
parent
fafa9fa9ae
commit
b1e1ab6385
14 changed files with 289 additions and 77 deletions
|
@ -101,7 +101,12 @@ export class Join extends Component {
|
|||
}
|
||||
|
||||
async _loadLeftFields() {
|
||||
const stringFields = await this.props.layer.getStringFields();
|
||||
let stringFields;
|
||||
try {
|
||||
stringFields = await this.props.layer.getStringFields();
|
||||
} catch (error) {
|
||||
stringFields = [];
|
||||
}
|
||||
if (!this._isMounted) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React, { Fragment } from 'react';
|
||||
|
||||
import {
|
||||
EuiFlexGroup,
|
||||
|
@ -15,6 +15,7 @@ import {
|
|||
EuiFieldText,
|
||||
EuiRange,
|
||||
EuiSpacer,
|
||||
EuiCallOut,
|
||||
} from '@elastic/eui';
|
||||
import { ValidatedRange } from '../../../shared/components/validated_range';
|
||||
|
||||
|
@ -43,6 +44,26 @@ export function SettingsPanel(props) {
|
|||
props.updateSourceProp(props.layerId, propName, value);
|
||||
};
|
||||
|
||||
const renderLayerErrors = () => {
|
||||
if (!props.layer.hasErrors()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<EuiCallOut
|
||||
color="warning"
|
||||
title="Unable to load layer"
|
||||
>
|
||||
<p data-test-subj="layerErrorMessage">
|
||||
{props.layer.getErrors()}
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
<EuiSpacer margin="m"/>
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
const renderZoomSliders = () => {
|
||||
return (
|
||||
<EuiFormRow
|
||||
|
@ -117,23 +138,27 @@ export function SettingsPanel(props) {
|
|||
};
|
||||
|
||||
return (
|
||||
<EuiPanel>
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem>
|
||||
<EuiTitle size="xs"><h5>Settings</h5></EuiTitle>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<Fragment>
|
||||
|
||||
<EuiSpacer margin="m"/>
|
||||
{renderLayerErrors()}
|
||||
|
||||
{renderLabel()}
|
||||
<EuiPanel>
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem>
|
||||
<EuiTitle size="xs"><h5>Settings</h5></EuiTitle>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
||||
{renderZoomSliders()}
|
||||
<EuiSpacer margin="m"/>
|
||||
|
||||
{renderAlphaSlider()}
|
||||
{renderLabel()}
|
||||
|
||||
{props.layer.renderSourceSettingsEditor({ onChange: onSourceChange })}
|
||||
{renderZoomSliders()}
|
||||
|
||||
</EuiPanel>
|
||||
{renderAlphaSlider()}
|
||||
|
||||
{props.layer.renderSourceSettingsEditor({ onChange: onSourceChange })}
|
||||
</EuiPanel>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -37,8 +37,12 @@ export class AttributionControl extends React.Component {
|
|||
|
||||
_syncMbMapWithAttribution = async () => {
|
||||
|
||||
const attributionPromises = this.props.layerList.map(layer => {
|
||||
return layer.getAttributions();
|
||||
const attributionPromises = this.props.layerList.map(async (layer) => {
|
||||
try {
|
||||
return await layer.getAttributions();
|
||||
} catch (error) {
|
||||
return [];
|
||||
}
|
||||
});
|
||||
const attributions = await Promise.all(attributionPromises);
|
||||
if (!this._isMounted) {
|
||||
|
|
|
@ -15,10 +15,8 @@ import { LayerTocActions } from '../../../../../shared/components/layer_toc_acti
|
|||
|
||||
export class TOCEntry extends React.Component {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
displayName: null };
|
||||
state = {
|
||||
displayName: null
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
@ -30,7 +28,6 @@ export class TOCEntry extends React.Component {
|
|||
this._isMounted = false;
|
||||
}
|
||||
|
||||
|
||||
async _updateDisplayName() {
|
||||
const label = await this.props.layer.getDisplayName();
|
||||
if (this._isMounted) {
|
||||
|
|
|
@ -41,11 +41,16 @@ export class LayerTOC extends React.Component {
|
|||
}
|
||||
|
||||
_renderLayers() {
|
||||
return [ ...this.props.layerList ]
|
||||
.reverse()
|
||||
return this.props.layerList
|
||||
.map((layer) => {
|
||||
return (<TOCEntry key={layer.getId()} layer={layer} displayName={layer.getDisplayName()}/>);
|
||||
});
|
||||
return (
|
||||
<TOCEntry
|
||||
key={layer.getId()}
|
||||
layer={layer}
|
||||
/>
|
||||
);
|
||||
})
|
||||
.reverse();
|
||||
}
|
||||
|
||||
render() {
|
||||
|
|
|
@ -39,11 +39,19 @@ export class EMSFileSource extends AbstractVectorSource {
|
|||
super(descriptor);
|
||||
}
|
||||
|
||||
async getGeoJsonWithMeta() {
|
||||
async _getEmsVectorFileMeta() {
|
||||
const emsFiles = await getEmsVectorFilesMeta();
|
||||
const fileSource = emsFiles.find((source => source.id === this._descriptor.id));
|
||||
const meta = emsFiles.find((source => source.id === this._descriptor.id));
|
||||
if (!meta) {
|
||||
throw new Error(`Unable to find EMS vector shapes for id: ${this._descriptor.id}`);
|
||||
}
|
||||
return meta;
|
||||
}
|
||||
|
||||
async getGeoJsonWithMeta() {
|
||||
const emsVectorFileMeta = await this._getEmsVectorFileMeta();
|
||||
const fetchUrl = `../${GIS_API_PATH}/data/ems?id=${encodeURIComponent(this._descriptor.id)}`;
|
||||
const featureCollection = await AbstractVectorSource.getGeoJson(fileSource, fetchUrl);
|
||||
const featureCollection = await AbstractVectorSource.getGeoJson(emsVectorFileMeta, fetchUrl);
|
||||
return {
|
||||
data: featureCollection,
|
||||
meta: {}
|
||||
|
@ -59,22 +67,23 @@ export class EMSFileSource extends AbstractVectorSource {
|
|||
}
|
||||
|
||||
async getDisplayName() {
|
||||
const emsFiles = await getEmsVectorFilesMeta();
|
||||
const fileSource = emsFiles.find((source => source.id === this._descriptor.id));
|
||||
return fileSource.name;
|
||||
try {
|
||||
const emsVectorFileMeta = await this._getEmsVectorFileMeta();
|
||||
return emsVectorFileMeta.name;
|
||||
} catch (error) {
|
||||
return this._descriptor.id;
|
||||
}
|
||||
}
|
||||
|
||||
async getAttributions() {
|
||||
const emsFiles = await getEmsVectorFilesMeta();
|
||||
const fileSource = emsFiles.find((source => source.id === this._descriptor.id));
|
||||
return fileSource.attributions;
|
||||
const emsVectorFileMeta = await this._getEmsVectorFileMeta();
|
||||
return emsVectorFileMeta.attributions;
|
||||
}
|
||||
|
||||
|
||||
async getStringFields() {
|
||||
const emsFiles = await getEmsVectorFilesMeta();
|
||||
const fileSource = emsFiles.find((source => source.id === this._descriptor.id));
|
||||
return fileSource.fields.map(f => {
|
||||
const emsVectorFileMeta = await this._getEmsVectorFileMeta();
|
||||
return emsVectorFileMeta.fields.map(f => {
|
||||
return { name: f.name, label: f.description };
|
||||
});
|
||||
}
|
||||
|
|
|
@ -48,15 +48,15 @@ export class EMSTMSSource extends AbstractTMSSource {
|
|||
];
|
||||
}
|
||||
|
||||
async _getTMSOptions() {
|
||||
async _getEmsTmsMeta() {
|
||||
const emsTileServices = await getEmsTMSServices();
|
||||
if(!emsTileServices) {
|
||||
return;
|
||||
}
|
||||
|
||||
return emsTileServices.find(service => {
|
||||
const meta = emsTileServices.find(service => {
|
||||
return service.id === this._descriptor.id;
|
||||
});
|
||||
if (!meta) {
|
||||
throw new Error(`Unable to find EMS tile configuration for id: ${this._descriptor.id}`);
|
||||
}
|
||||
return meta;
|
||||
}
|
||||
|
||||
_createDefaultLayerDescriptor(options) {
|
||||
|
@ -78,12 +78,12 @@ export class EMSTMSSource extends AbstractTMSSource {
|
|||
}
|
||||
|
||||
async getAttributions() {
|
||||
const service = await this._getTMSOptions();
|
||||
if (!service || !service.attributionMarkdown) {
|
||||
const emsTmsMeta = await this._getEmsTmsMeta();
|
||||
if (!emsTmsMeta.attributionMarkdown) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return service.attributionMarkdown.split('|').map((attribution) => {
|
||||
return emsTmsMeta.attributionMarkdown.split('|').map((attribution) => {
|
||||
attribution = attribution.trim();
|
||||
//this assumes attribution is plain markdown link
|
||||
const extractLink = /\[(.*)\]\((.*)\)/;
|
||||
|
@ -96,10 +96,7 @@ export class EMSTMSSource extends AbstractTMSSource {
|
|||
}
|
||||
|
||||
async getUrlTemplate() {
|
||||
const service = await this._getTMSOptions();
|
||||
if (!service || !service.url) {
|
||||
throw new Error('Cannot generate EMS TMS url template');
|
||||
}
|
||||
return service.url;
|
||||
const emsTmsMeta = await this._getEmsTmsMeta();
|
||||
return emsTmsMeta.url;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,9 +9,6 @@ import React from 'react';
|
|||
import uuid from 'uuid/v4';
|
||||
|
||||
import { AbstractESSource } from '../es_source';
|
||||
import {
|
||||
indexPatternService,
|
||||
} from '../../../../kibana_services';
|
||||
import { hitsToGeoJson } from '../../../../elasticsearch_geo_utils';
|
||||
import { CreateSourceEditor } from './create_source_editor';
|
||||
import { UpdateSourceEditor } from './update_source_editor';
|
||||
|
@ -59,10 +56,14 @@ export class ESSearchSource extends AbstractESSource {
|
|||
}
|
||||
|
||||
async getNumberFields() {
|
||||
const indexPattern = await indexPatternService.get(this._descriptor.indexPatternId);
|
||||
return indexPattern.fields.byType.number.map(field => {
|
||||
return { name: field.name, label: field.name };
|
||||
});
|
||||
try {
|
||||
const indexPattern = await this._getIndexPattern();
|
||||
return indexPattern.fields.byType.number.map(field => {
|
||||
return { name: field.name, label: field.name };
|
||||
});
|
||||
} catch (error) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
getFieldNames() {
|
||||
|
|
|
@ -108,20 +108,26 @@ export class AbstractESSource extends AbstractVectorSource {
|
|||
}
|
||||
|
||||
async isTimeAware() {
|
||||
const indexPattern = await this._getIndexPattern();
|
||||
const timeField = indexPattern.timeFieldName;
|
||||
return !!timeField;
|
||||
try {
|
||||
const indexPattern = await this._getIndexPattern();
|
||||
const timeField = indexPattern.timeFieldName;
|
||||
return !!timeField;
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async _getIndexPattern() {
|
||||
let indexPattern;
|
||||
try {
|
||||
indexPattern = await indexPatternService.get(this._descriptor.indexPatternId);
|
||||
} catch (error) {
|
||||
throw new Error(`Unable to find Index pattern ${this._descriptor.indexPatternId}`);
|
||||
if (this.indexPattern) {
|
||||
return this.indexPattern;
|
||||
}
|
||||
|
||||
try {
|
||||
this.indexPattern = await indexPatternService.get(this._descriptor.indexPatternId);
|
||||
return this.indexPattern;
|
||||
} catch (error) {
|
||||
throw new Error(`Unable to find Index pattern for id: ${this._descriptor.indexPatternId}`);
|
||||
}
|
||||
return indexPattern;
|
||||
}
|
||||
|
||||
async _getGeoField() {
|
||||
|
@ -134,8 +140,13 @@ export class AbstractESSource extends AbstractVectorSource {
|
|||
}
|
||||
|
||||
async getDisplayName() {
|
||||
const indexPattern = await this._getIndexPattern();
|
||||
return indexPattern.title;
|
||||
try {
|
||||
const indexPattern = await this._getIndexPattern();
|
||||
return indexPattern.title;
|
||||
} catch (error) {
|
||||
// Unable to load index pattern, just return id as display name
|
||||
return this._descriptor.indexPatternId;
|
||||
}
|
||||
}
|
||||
|
||||
isBoundsAware() {
|
||||
|
|
|
@ -49,20 +49,26 @@ export class KibanaRegionmapSource extends AbstractVectorSource {
|
|||
];
|
||||
}
|
||||
|
||||
async getGeoJsonWithMeta() {
|
||||
async _getVectorFileMeta() {
|
||||
const regionList = await getKibanaRegionList();
|
||||
const fileSource = regionList.find(source => source.name === this._descriptor.name);
|
||||
const featureCollection = await AbstractVectorSource.getGeoJson(fileSource, fileSource.url);
|
||||
const meta = regionList.find(source => source.name === this._descriptor.name);
|
||||
if (!meta) {
|
||||
throw new Error(`Unable to find map.regionmap configuration for ${this._descriptor.name}`);
|
||||
}
|
||||
return meta;
|
||||
}
|
||||
|
||||
async getGeoJsonWithMeta() {
|
||||
const vectorFileMeta = await this._getVectorFileMeta();
|
||||
const featureCollection = await AbstractVectorSource.getGeoJson(vectorFileMeta, vectorFileMeta.url);
|
||||
return {
|
||||
data: featureCollection
|
||||
};
|
||||
}
|
||||
|
||||
async getStringFields() {
|
||||
const regionList = await getKibanaRegionList();
|
||||
const fileSource = regionList.find((source => source.name === this._descriptor.name));
|
||||
|
||||
return fileSource.fields.map(f => {
|
||||
const vectorFileMeta = await this._getVectorFileMeta();
|
||||
return vectorFileMeta.fields.map(f => {
|
||||
return { name: f.name, label: f.description };
|
||||
});
|
||||
}
|
||||
|
|
|
@ -35,5 +35,6 @@ export default function ({ loadTestFile, getService }) {
|
|||
loadTestFile(require.resolve('./es_search_source'));
|
||||
loadTestFile(require.resolve('./es_geo_grid_source'));
|
||||
loadTestFile(require.resolve('./joins'));
|
||||
loadTestFile(require.resolve('./layer_errors'));
|
||||
});
|
||||
}
|
||||
|
|
100
x-pack/test/functional/apps/maps/layer_errors.js
Normal file
100
x-pack/test/functional/apps/maps/layer_errors.js
Normal file
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import expect from 'expect.js';
|
||||
|
||||
export default function ({ getPageObjects }) {
|
||||
|
||||
const PageObjects = getPageObjects(['gis', 'header']);
|
||||
|
||||
describe('layer errors', () => {
|
||||
|
||||
before(async () => {
|
||||
await PageObjects.gis.loadSavedMap('layer with errors');
|
||||
});
|
||||
|
||||
describe('ESSearchSource with missing index pattern id', async () => {
|
||||
const MISSING_INDEX_ID = 'idThatDoesNotExitForESSearchSource';
|
||||
const LAYER_NAME = MISSING_INDEX_ID;
|
||||
|
||||
|
||||
it('should diplay error message in layer panel', async () => {
|
||||
const errorMsg = await PageObjects.gis.getLayerErrorText(LAYER_NAME);
|
||||
expect(errorMsg).to.equal(`Unable to find Index pattern for id: ${MISSING_INDEX_ID}`);
|
||||
});
|
||||
|
||||
it('should allow deletion of layer', async () => {
|
||||
await PageObjects.gis.removeLayer(LAYER_NAME);
|
||||
const exists = await PageObjects.gis.doesLayerExist(LAYER_NAME);
|
||||
expect(exists).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('ESGeoGridSource with missing index pattern id', async () => {
|
||||
const MISSING_INDEX_ID = 'idThatDoesNotExitForESGeoGridSource';
|
||||
const LAYER_NAME = MISSING_INDEX_ID;
|
||||
|
||||
it('should diplay error message in layer panel', async () => {
|
||||
const errorMsg = await PageObjects.gis.getLayerErrorText(LAYER_NAME);
|
||||
expect(errorMsg).to.equal(`Unable to find Index pattern for id: ${MISSING_INDEX_ID}`);
|
||||
});
|
||||
|
||||
it('should allow deletion of layer', async () => {
|
||||
await PageObjects.gis.removeLayer(LAYER_NAME);
|
||||
const exists = await PageObjects.gis.doesLayerExist(LAYER_NAME);
|
||||
expect(exists).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('EMSFileSource with missing EMS id', async () => {
|
||||
const MISSING_EMS_ID = 'idThatDoesNotExitForEMSFileSource';
|
||||
const LAYER_NAME = 'EMS_vector_shapes';
|
||||
|
||||
it('should diplay error message in layer panel', async () => {
|
||||
const errorMsg = await PageObjects.gis.getLayerErrorText(LAYER_NAME);
|
||||
expect(errorMsg).to.equal(`Unable to find EMS vector shapes for id: ${MISSING_EMS_ID}`);
|
||||
});
|
||||
|
||||
it('should allow deletion of layer', async () => {
|
||||
await PageObjects.gis.removeLayer(LAYER_NAME);
|
||||
const exists = await PageObjects.gis.doesLayerExist(LAYER_NAME);
|
||||
expect(exists).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('EMSTMSSource with missing EMS id', async () => {
|
||||
const MISSING_EMS_ID = 'idThatDoesNotExitForEMSTile';
|
||||
const LAYER_NAME = 'EMS_tiles';
|
||||
|
||||
it('should diplay error message in layer panel', async () => {
|
||||
const errorMsg = await PageObjects.gis.getLayerErrorText(LAYER_NAME);
|
||||
expect(errorMsg).to.equal(`Unable to find EMS tile configuration for id: ${MISSING_EMS_ID}`);
|
||||
});
|
||||
|
||||
it('should allow deletion of layer', async () => {
|
||||
await PageObjects.gis.removeLayer(LAYER_NAME);
|
||||
const exists = await PageObjects.gis.doesLayerExist(LAYER_NAME);
|
||||
expect(exists).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('KibanaRegionmapSource with missing region map configuration', async () => {
|
||||
const MISSING_REGION_NAME = 'nameThatDoesNotExitForKibanaRegionmapSource';
|
||||
const LAYER_NAME = 'Custom_vector_shapes';
|
||||
|
||||
it('should diplay error message in layer panel', async () => {
|
||||
const errorMsg = await PageObjects.gis.getLayerErrorText(LAYER_NAME);
|
||||
expect(errorMsg).to.equal(`Unable to find map.regionmap configuration for ${MISSING_REGION_NAME}`);
|
||||
});
|
||||
|
||||
it('should allow deletion of layer', async () => {
|
||||
await PageObjects.gis.removeLayer(LAYER_NAME);
|
||||
const exists = await PageObjects.gis.doesLayerExist(LAYER_NAME);
|
||||
expect(exists).to.be(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
|
@ -332,3 +332,48 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
"type": "doc",
|
||||
"value": {
|
||||
"index": ".kibana",
|
||||
"id": "map:745c98b0-23e1-11e9-a048-6fef5a3e0d1e",
|
||||
"source": {
|
||||
"type": "map",
|
||||
"map": {
|
||||
"title" : "layer with errors",
|
||||
"description" : "",
|
||||
"mapStateJSON" : "{\"zoom\":0.71,\"center\":{\"lon\":0.10268,\"lat\":0},\"timeFilters\":{\"from\":\"now-7d\",\"to\":\"now\"},\"refreshConfig\":{\"isPaused\":true,\"interval\":0},\"query\":{\"query\":\"\",\"language\":\"kuery\"}}",
|
||||
"layerListJSON" : "[{\"sourceDescriptor\":{\"type\":\"KIBANA_TILEMAP\",\"url\":\"https://a.tile.openstreetmap.org/{z}/{x}/{y}.png\"},\"id\":\"ap0ys\",\"label\":\"Custom TMS\",\"minZoom\":0,\"maxZoom\":24,\"alpha\":1,\"visible\":true,\"temporary\":false,\"style\":{\"type\":\"TILE\",\"properties\":{},\"previousStyle\":null},\"type\":\"TILE\",\"isInErrorState\":true,\"errorMessage\":\"Tiles from \\\"https://a.tile.openstreetmap.org/{z}/{x}/{y}.png\\\" could not be loaded\"},{\"sourceDescriptor\":{\"type\":\"REGIONMAP_FILE\",\"name\":\"nameThatDoesNotExitForKibanaRegionmapSource\"},\"temporary\":false,\"id\":\"0sabv\",\"label\":\"Custom_vector_shapes\",\"minZoom\":0,\"maxZoom\":24,\"alpha\":0.75,\"visible\":true,\"style\":{\"type\":\"VECTOR\",\"properties\":{\"fillColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#3cb44b\"}},\"lineColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#FFFFFF\"}},\"lineWidth\":{\"type\":\"STATIC\",\"options\":{\"size\":1}},\"iconSize\":{\"type\":\"STATIC\",\"options\":{\"size\":10}}},\"previousStyle\":null},\"type\":\"VECTOR\",\"isInErrorState\":true,\"errorMessage\":\"Cannot read property 'url' of undefined\"},{\"sourceDescriptor\":{\"type\":\"EMS_TMS\",\"id\":\"idThatDoesNotExitForEMSTile\"},\"temporary\":false,\"id\":\"plw9l\",\"label\":\"EMS_tiles\",\"minZoom\":0,\"maxZoom\":24,\"alpha\":1,\"visible\":true,\"style\":{\"type\":\"TILE\",\"properties\":{},\"previousStyle\":null},\"type\":\"TILE\"},{\"sourceDescriptor\":{\"type\":\"EMS_FILE\",\"id\":\"idThatDoesNotExitForEMSFileSource\"},\"temporary\":false,\"id\":\"2gro0\",\"label\":\"EMS_vector_shapes\",\"minZoom\":0,\"maxZoom\":24,\"alpha\":0.75,\"visible\":true,\"style\":{\"type\":\"VECTOR\",\"properties\":{\"fillColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#e6194b\"}},\"lineColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#FFFFFF\"}},\"lineWidth\":{\"type\":\"STATIC\",\"options\":{\"size\":1}},\"iconSize\":{\"type\":\"STATIC\",\"options\":{\"size\":10}}},\"previousStyle\":null},\"type\":\"VECTOR\"},{\"sourceDescriptor\":{\"type\":\"ES_GEO_GRID\",\"id\":\"f67fe707-95dd-46d6-89b8-82617b251b61\",\"indexPatternId\":\"idThatDoesNotExitForESGeoGridSource\",\"geoField\":\"geo.coordinates\",\"requestType\":\"grid\",\"resolution\":\"COARSE\"},\"temporary\":false,\"id\":\"pl5qd\",\"label\":\"\",\"minZoom\":0,\"maxZoom\":24,\"alpha\":0.75,\"visible\":true,\"style\":{\"type\":\"VECTOR\",\"properties\":{\"fillColor\":{\"type\":\"DYNAMIC\",\"options\":{\"field\":{\"label\":\"Count\",\"name\":\"doc_count\",\"origin\":\"source\"},\"color\":\"Blues\"}},\"lineColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#FFFFFF\"}},\"lineWidth\":{\"type\":\"STATIC\",\"options\":{\"size\":1}},\"iconSize\":{\"type\":\"DYNAMIC\",\"options\":{\"field\":{\"label\":\"Count\",\"name\":\"doc_count\",\"origin\":\"source\"},\"minSize\":4,\"maxSize\":32}}},\"previousStyle\":null},\"type\":\"VECTOR\"},{\"sourceDescriptor\":{\"id\":\"a07072bb-3a92-4320-bd37-250ef6d04db7\",\"type\":\"ES_SEARCH\",\"indexPatternId\":\"idThatDoesNotExitForESSearchSource\",\"geoField\":\"geo.coordinates\",\"limit\":2048,\"filterByMapBounds\":true,\"tooltipProperties\":[]},\"temporary\":false,\"id\":\"9bw8h\",\"label\":\"\",\"minZoom\":0,\"maxZoom\":24,\"alpha\":0.75,\"visible\":true,\"style\":{\"type\":\"VECTOR\",\"properties\":{\"fillColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#e6194b\"}},\"lineColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#FFFFFF\"}},\"lineWidth\":{\"type\":\"STATIC\",\"options\":{\"size\":1}},\"iconSize\":{\"type\":\"STATIC\",\"options\":{\"size\":10}}},\"previousStyle\":null},\"type\":\"VECTOR\"}]",
|
||||
"uiStateJSON" : "{}",
|
||||
"bounds" : {
|
||||
"type" : "polygon",
|
||||
"coordinates" : [
|
||||
[
|
||||
[
|
||||
-180,
|
||||
85.05113
|
||||
],
|
||||
[
|
||||
-180,
|
||||
-85.05113
|
||||
],
|
||||
[
|
||||
180,
|
||||
-85.05113
|
||||
],
|
||||
[
|
||||
180,
|
||||
85.05113
|
||||
],
|
||||
[
|
||||
-180,
|
||||
85.05113
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,6 +143,12 @@ export function GisPageProvider({ getService, getPageObjects }) {
|
|||
await testSubjects.click(`mapRemoveLayerButton`);
|
||||
}
|
||||
|
||||
async getLayerErrorText(layerName) {
|
||||
log.debug(`Remove layer ${layerName}`);
|
||||
await this.openLayerPanel(layerName);
|
||||
return await testSubjects.getVisibleText(`layerErrorMessage`);
|
||||
}
|
||||
|
||||
async openInspectorView(viewId) {
|
||||
await inspector.open();
|
||||
log.debug(`Open Inspector view ${viewId}`);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue