From 1d1cd25e0e240e49c101a89d206b62916701439d Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Thu, 23 Apr 2020 15:54:33 -0400 Subject: [PATCH 01/56] tmp commit --- ....d.ts => data_request_descriptor_types.ts} | 0 .../maps/common/descriptor_types/index.ts | 2 +- .../{descriptor_types.d.ts => sources.d.ts} | 12 +++ ....ts => style_property_descriptor_types.ts} | 0 .../maps/public/layers/fields/mvt_field.ts | 49 +++++++++++++ .../layer_wizard.tsx | 2 +- .../mvt_field_config_editor.tsx | 73 +++++++++++++++++++ .../mvt_single_layer_vector_source_editor.tsx | 28 +++++-- .../mvt_single_layer_vector_source/types.ts | 15 ++++ 9 files changed, 172 insertions(+), 9 deletions(-) rename x-pack/plugins/maps/common/descriptor_types/{data_request_descriptor_types.d.ts => data_request_descriptor_types.ts} (100%) rename x-pack/plugins/maps/common/descriptor_types/{descriptor_types.d.ts => sources.d.ts} (96%) rename x-pack/plugins/maps/common/descriptor_types/{style_property_descriptor_types.d.ts => style_property_descriptor_types.ts} (100%) create mode 100644 x-pack/plugins/maps/public/layers/fields/mvt_field.ts create mode 100644 x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx create mode 100644 x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/types.ts diff --git a/x-pack/plugins/maps/common/descriptor_types/data_request_descriptor_types.d.ts b/x-pack/plugins/maps/common/descriptor_types/data_request_descriptor_types.ts similarity index 100% rename from x-pack/plugins/maps/common/descriptor_types/data_request_descriptor_types.d.ts rename to x-pack/plugins/maps/common/descriptor_types/data_request_descriptor_types.ts diff --git a/x-pack/plugins/maps/common/descriptor_types/index.ts b/x-pack/plugins/maps/common/descriptor_types/index.ts index af0f4487f471b..b0ae065856a5d 100644 --- a/x-pack/plugins/maps/common/descriptor_types/index.ts +++ b/x-pack/plugins/maps/common/descriptor_types/index.ts @@ -5,6 +5,6 @@ */ export * from './data_request_descriptor_types'; -export * from './descriptor_types'; +export * from './sources'; export * from './map_descriptor'; export * from './style_property_descriptor_types'; diff --git a/x-pack/plugins/maps/common/descriptor_types/descriptor_types.d.ts b/x-pack/plugins/maps/common/descriptor_types/sources.d.ts similarity index 96% rename from x-pack/plugins/maps/common/descriptor_types/descriptor_types.d.ts rename to x-pack/plugins/maps/common/descriptor_types/sources.d.ts index 6980f14d0788a..8d566f1dc4aa1 100644 --- a/x-pack/plugins/maps/common/descriptor_types/descriptor_types.d.ts +++ b/x-pack/plugins/maps/common/descriptor_types/sources.d.ts @@ -94,6 +94,16 @@ export type XYZTMSSourceDescriptor = AbstractSourceDescriptor & urlTemplate: string; }; +export enum MVTFieldType { + String = 'String', + Number = 'Number', +} + +export type MVTFieldDescriptor = { + name: string; + type: MVTFieldType; +}; + export type TiledSingleLayerVectorSourceDescriptor = AbstractSourceDescriptor & { urlTemplate: string; layerName: string; @@ -104,6 +114,8 @@ export type TiledSingleLayerVectorSourceDescriptor = AbstractSourceDescriptor & // e.g. EMS basemap data from level 14 is at most detailed resolution and can be displayed at higher levels minSourceZoom: number; maxSourceZoom: number; + + fields?: MVTFieldDescriptor[]; }; export type JoinDescriptor = { diff --git a/x-pack/plugins/maps/common/descriptor_types/style_property_descriptor_types.d.ts b/x-pack/plugins/maps/common/descriptor_types/style_property_descriptor_types.ts similarity index 100% rename from x-pack/plugins/maps/common/descriptor_types/style_property_descriptor_types.d.ts rename to x-pack/plugins/maps/common/descriptor_types/style_property_descriptor_types.ts diff --git a/x-pack/plugins/maps/public/layers/fields/mvt_field.ts b/x-pack/plugins/maps/public/layers/fields/mvt_field.ts new file mode 100644 index 0000000000000..7ff982b14cbd9 --- /dev/null +++ b/x-pack/plugins/maps/public/layers/fields/mvt_field.ts @@ -0,0 +1,49 @@ +/* + * 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 { AbstractField, IField } from './field'; +import { IKibanaRegionSource } from '../sources/kibana_regionmap_source/kibana_regionmap_source'; +import { FIELD_ORIGIN } from '../../../common/constants'; +import { IVectorSource } from '../sources/vector_source'; +import { MVTFieldType } from '../../../common/descriptor_types'; + +export class MVTField extends AbstractField implements IField { + private readonly _source: IKibanaRegionSource; + private readonly _type: MVTFieldType; + constructor({ + fieldName, + type, + source, + origin, + }: { + fieldName: string; + source: IKibanaRegionSource; + origin: FIELD_ORIGIN; + type: MVTFieldType; + }) { + super({ fieldName, origin }); + this._source = source; + this._type = type; + } + + getSource(): IVectorSource { + return this._source; + } + + async getDataType(): Promise { + if (this._type === MVTFieldType.String) { + return 'string'; + } else if (this._type === MVTFieldType.Number) { + return 'number'; + } else { + throw new Error(`Unrecognized MVT field-type ${this._type}`); + } + } + + async getLabel(): Promise { + return this.getName(); + } +} diff --git a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/layer_wizard.tsx b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/layer_wizard.tsx index dfdea1489d50c..45524bda5cf3f 100644 --- a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/layer_wizard.tsx +++ b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/layer_wizard.tsx @@ -8,11 +8,11 @@ import { i18n } from '@kbn/i18n'; import React from 'react'; import { MVTSingleLayerVectorSourceEditor, - MVTSingleLayerVectorSourceConfig, } from './mvt_single_layer_vector_source_editor'; import { MVTSingleLayerVectorSource, sourceTitle } from './mvt_single_layer_vector_source'; import { LayerWizard, RenderWizardArguments } from '../../layer_wizard_registry'; import { SOURCE_TYPES } from '../../../../common/constants'; +import { MVTSingleLayerVectorSourceConfig } from './types'; export const mvtVectorSourceWizardConfig: LayerWizard = { description: i18n.translate('xpack.maps.source.mvtVectorSourceWizard', { diff --git a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx new file mode 100644 index 0000000000000..9d6e6e9cb2a7a --- /dev/null +++ b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx @@ -0,0 +1,73 @@ +/* + * 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. + */ +/* eslint-disable @typescript-eslint/consistent-type-definitions */ + +import React, { Component, Fragment } from 'react'; +import { EuiButton, EuiButtonIcon, EuiTextAlign } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { MVTFieldDescriptor, MVTFieldType } from '../../../../common/descriptor_types'; + +export interface Props { + fields: MVTFieldDescriptor[]; + onChange: (fields: MVTFieldDescriptor[]) => void; +} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +interface State {} + +export class MVTFieldConfigEditor extends Component { + state = {}; + + _removeField(index) { + const newFields = this.props.fields.slice(); + newFields.splice(index, 1); + + this.props.onChange(newFields); + } + + _addField = () => { + const newFields = this.props.fields.slice(); + newFields.push({ + type: MVTFieldType.String, + name: 'Foobar', + }); + }; + + _renderFieldConfig() { + return this.props.fields.map((mvtFieldConfig: MVTFieldDescriptor, index: number) => { + return ( +
+ {mvtFieldConfig.name} + {mvtFieldConfig.type} + { + this._removeField(index); + }} + title={i18n.translate('xpack.maps.mvtSource.trashButtonTitle', { + defaultMessage: 'Remove field', + })} + aria-label={i18n.translate('xpack.maps.mvtSource.trashButtonAriaLabel', { + defaultMessage: 'Remove field', + })} + /> +
+ ); + }); + } + + render() { + return ( + + {this._renderFieldConfig()} + + {'Add field'} + + + ); + } +} diff --git a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx index 7a4b8d43811da..03284f71e6bcb 100644 --- a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx +++ b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx @@ -11,13 +11,9 @@ import { EuiFieldText, EuiFormRow } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { MAX_ZOOM, MIN_ZOOM } from '../../../../common/constants'; import { ValidatedDualRange, Value } from '../../../../../../../src/plugins/kibana_react/public'; - -export type MVTSingleLayerVectorSourceConfig = { - urlTemplate: string; - layerName: string; - minSourceZoom: number; - maxSourceZoom: number; -}; +import { MVTSingleLayerVectorSourceConfig } from './types'; +import { MVTFieldConfigEditor } from './mvt_field_config_editor'; +import { MVTFieldDescriptor } from '../../../../common/descriptor_types'; export interface Props { onSourceConfigChange: (sourceConfig: MVTSingleLayerVectorSourceConfig) => void; @@ -28,6 +24,8 @@ interface State { layerName: string; minSourceZoom: number; maxSourceZoom: number; + fields?: MVTFieldDescriptor[]; + } export class MVTSingleLayerVectorSourceEditor extends Component { @@ -36,6 +34,7 @@ export class MVTSingleLayerVectorSourceEditor extends Component { layerName: '', minSourceZoom: MIN_ZOOM, maxSourceZoom: MAX_ZOOM, + fields: [], }; _sourceConfigChange = _.debounce(() => { @@ -45,11 +44,13 @@ export class MVTSingleLayerVectorSourceEditor extends Component { this.state.urlTemplate.indexOf('{z}') >= 0; if (canPreview && this.state.layerName) { + console.log('nf', fields); this.props.onSourceConfigChange({ urlTemplate: this.state.urlTemplate, layerName: this.state.layerName, minSourceZoom: this.state.minSourceZoom, maxSourceZoom: this.state.maxSourceZoom, + fields: this.state.fields, }); } }, 200); @@ -74,6 +75,17 @@ export class MVTSingleLayerVectorSourceEditor extends Component { ); }; + _handleFieldChange = (fields: MVTFieldDescriptor[]) => { + + this.setState( + { + fields, + }, + () => this._sourceConfigChange() + ); + + }; + _handleZoomRangeChange = (e: Value) => { const minSourceZoom = parseInt(e[0] as string, 10); const maxSourceZoom = parseInt(e[1] as string, 10); @@ -122,6 +134,8 @@ export class MVTSingleLayerVectorSourceEditor extends Component { } )} /> + + ); } diff --git a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/types.ts b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/types.ts new file mode 100644 index 0000000000000..3c1de63b96ee5 --- /dev/null +++ b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/types.ts @@ -0,0 +1,15 @@ +/* + * 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 { MVTFieldDescriptor } from '../../../../common/descriptor_types'; + +export interface MVTSingleLayerVectorSourceConfig { + urlTemplate: string; + layerName: string; + minSourceZoom: number; + maxSourceZoom: number; + fields?: MVTFieldDescriptor[]; +} From 9a3d90d823ec220120d2076ffb8527af76ce68ca Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Thu, 23 Apr 2020 16:10:25 -0400 Subject: [PATCH 02/56] rename --- .../maps/common/descriptor_types/{sources.d.ts => sources.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename x-pack/plugins/maps/common/descriptor_types/{sources.d.ts => sources.ts} (100%) diff --git a/x-pack/plugins/maps/common/descriptor_types/sources.d.ts b/x-pack/plugins/maps/common/descriptor_types/sources.ts similarity index 100% rename from x-pack/plugins/maps/common/descriptor_types/sources.d.ts rename to x-pack/plugins/maps/common/descriptor_types/sources.ts From b67f20d7cad1130ad9c389a6b45bb2c4939d7bbe Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Thu, 23 Apr 2020 16:56:03 -0400 Subject: [PATCH 03/56] more boilerpalte --- .../layer_wizard.tsx | 6 +- .../mvt_field_config_editor.tsx | 98 +++++++++++++++---- .../mvt_single_layer_vector_source.ts | 19 +++- .../mvt_single_layer_vector_source_editor.tsx | 16 ++- 4 files changed, 108 insertions(+), 31 deletions(-) diff --git a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/layer_wizard.tsx b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/layer_wizard.tsx index 45524bda5cf3f..37de854ed8478 100644 --- a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/layer_wizard.tsx +++ b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/layer_wizard.tsx @@ -6,9 +6,7 @@ import { i18n } from '@kbn/i18n'; import React from 'react'; -import { - MVTSingleLayerVectorSourceEditor, -} from './mvt_single_layer_vector_source_editor'; +import { MVTSingleLayerVectorSourceEditor } from './mvt_single_layer_vector_source_editor'; import { MVTSingleLayerVectorSource, sourceTitle } from './mvt_single_layer_vector_source'; import { LayerWizard, RenderWizardArguments } from '../../layer_wizard_registry'; import { SOURCE_TYPES } from '../../../../common/constants'; @@ -25,6 +23,7 @@ export const mvtVectorSourceWizardConfig: LayerWizard = { layerName, minSourceZoom, maxSourceZoom, + fields, }: MVTSingleLayerVectorSourceConfig) => { const sourceDescriptor = MVTSingleLayerVectorSource.createDescriptor({ urlTemplate, @@ -32,6 +31,7 @@ export const mvtVectorSourceWizardConfig: LayerWizard = { minSourceZoom, maxSourceZoom, type: SOURCE_TYPES.MVT_SINGLE_LAYER, + fields, }); const source = new MVTSingleLayerVectorSource(sourceDescriptor, inspectorAdapters); onPreviewSource(source); diff --git a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx index 9d6e6e9cb2a7a..e73d14ef63939 100644 --- a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx +++ b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx @@ -5,10 +5,39 @@ */ /* eslint-disable @typescript-eslint/consistent-type-definitions */ -import React, { Component, Fragment } from 'react'; -import { EuiButton, EuiButtonIcon, EuiTextAlign } from '@elastic/eui'; +import React, { ChangeEvent, Component, Fragment } from 'react'; +import { + EuiButton, + EuiButtonIcon, + EuiFlexGroup, + EuiFlexItem, + EuiSuperSelect, + EuiFieldText, +} from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { MVTFieldDescriptor, MVTFieldType } from '../../../../common/descriptor_types'; +import { FieldIcon } from '../../../../../../../src/plugins/kibana_react/public'; + +const FIELD_TYPE_OPTIONS = [ + { + value: MVTFieldType.String, + inputDisplay: ( + + + String + + ), + }, + { + value: MVTFieldType.Number, + inputDisplay: ( + + + Number + + ), + }, +]; export interface Props { fields: MVTFieldDescriptor[]; @@ -34,28 +63,59 @@ export class MVTFieldConfigEditor extends Component { type: MVTFieldType.String, name: 'Foobar', }); + this.props.onChange(newFields); }; + _renderFieldTypeDropDown(mvtFieldConfig: MVTFieldDescriptor, index: number) { + const onChange = (type: MVTFieldType) => { + const newFields = this.props.fields.slice(); + newFields[index].type = type; + this.props.onChange(newFields); + }; + + return ( + onChange(value)} + /> + ); + } + + _renderFieldNameInput(mvtFieldConfig: MVTFieldDescriptor, index: number) { + const onChange = (e: ChangeEvent) => { + const name = e.target.value; + const newFields = this.props.fields.slice(); + newFields[index].name = name; + this.props.onChange(newFields); + }; + return ( + + ); + } + _renderFieldConfig() { return this.props.fields.map((mvtFieldConfig: MVTFieldDescriptor, index: number) => { return ( -
- {mvtFieldConfig.name} - {mvtFieldConfig.type} - { - this._removeField(index); - }} - title={i18n.translate('xpack.maps.mvtSource.trashButtonTitle', { - defaultMessage: 'Remove field', - })} - aria-label={i18n.translate('xpack.maps.mvtSource.trashButtonAriaLabel', { - defaultMessage: 'Remove field', - })} - /> -
+ + {this._renderFieldNameInput(mvtFieldConfig, index)} + {this._renderFieldTypeDropDown(mvtFieldConfig, index)} + + { + this._removeField(index); + }} + title={i18n.translate('xpack.maps.mvtSource.trashButtonTitle', { + defaultMessage: 'Remove field', + })} + aria-label={i18n.translate('xpack.maps.mvtSource.trashButtonAriaLabel', { + defaultMessage: 'Remove field', + })} + /> + + ); }); } diff --git a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.ts b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.ts index a73cfbdc0d043..f2933d342bace 100644 --- a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.ts +++ b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.ts @@ -37,6 +37,7 @@ export class MVTSingleLayerVectorSource extends AbstractSource layerName, minSourceZoom, maxSourceZoom, + fields, }: TiledSingleLayerVectorSourceDescriptor) { return { type: SOURCE_TYPES.MVT_SINGLE_LAYER, @@ -45,6 +46,7 @@ export class MVTSingleLayerVectorSource extends AbstractSource layerName, minSourceZoom: Math.max(MIN_ZOOM, minSourceZoom), maxSourceZoom: Math.min(MAX_ZOOM, maxSourceZoom), + fields: fields ?? [], }; } @@ -54,6 +56,7 @@ export class MVTSingleLayerVectorSource extends AbstractSource sourceDescriptor: TiledSingleLayerVectorSourceDescriptor, inspectorAdapters?: object ) { + console.log('crearte source', sourceDescriptor); super(sourceDescriptor, inspectorAdapters); this._descriptor = sourceDescriptor; } @@ -63,6 +66,12 @@ export class MVTSingleLayerVectorSource extends AbstractSource } getFieldNames(): string[] { + console.log('need to implement this...'); + return []; + } + + async getFields(): Promise { + console.log('also need to implement this'); return []; } @@ -92,10 +101,6 @@ export class MVTSingleLayerVectorSource extends AbstractSource throw new Error('Does not implement getGeoJsonWithMeta'); } - async getFields(): Promise { - return []; - } - async getImmutableProperties(): Promise { return [ { label: getDataSourceLabel(), value: sourceTitle }, @@ -118,6 +123,12 @@ export class MVTSingleLayerVectorSource extends AbstractSource }), value: this._descriptor.maxSourceZoom.toString(), }, + { + label: i18n.translate('xpack.maps.source.MVTSingleLayerVectorSource.fields', { + defaultMessage: 'Fields', + }), + value: (this._descriptor.fields ?? []).join(', '), + }, ]; } diff --git a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx index 03284f71e6bcb..4891c4f8350d8 100644 --- a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx +++ b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx @@ -25,7 +25,6 @@ interface State { minSourceZoom: number; maxSourceZoom: number; fields?: MVTFieldDescriptor[]; - } export class MVTSingleLayerVectorSourceEditor extends Component { @@ -44,7 +43,7 @@ export class MVTSingleLayerVectorSourceEditor extends Component { this.state.urlTemplate.indexOf('{z}') >= 0; if (canPreview && this.state.layerName) { - console.log('nf', fields); + console.log('nf', this.state.fields); this.props.onSourceConfigChange({ urlTemplate: this.state.urlTemplate, layerName: this.state.layerName, @@ -76,14 +75,12 @@ export class MVTSingleLayerVectorSourceEditor extends Component { }; _handleFieldChange = (fields: MVTFieldDescriptor[]) => { - this.setState( { fields, }, () => this._sourceConfigChange() ); - }; _handleZoomRangeChange = (e: Value) => { @@ -115,6 +112,16 @@ export class MVTSingleLayerVectorSourceEditor extends Component { > + + + { )} /> - ); } From 1bbe0d9073d1ac9368280f3a58e2a7f1c863c664 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Thu, 23 Apr 2020 17:36:32 -0400 Subject: [PATCH 04/56] more boiler --- .../maps/common/descriptor_types/sources.ts | 2 +- .../mvt_single_layer_vector_source.ts | 45 ++++++++++++++----- .../sources/vector_source/vector_source.d.ts | 2 + .../components/color/dynamic_color_form.js | 1 + .../layers/styles/vector/vector_style.js | 3 ++ 5 files changed, 40 insertions(+), 13 deletions(-) diff --git a/x-pack/plugins/maps/common/descriptor_types/sources.ts b/x-pack/plugins/maps/common/descriptor_types/sources.ts index 8d566f1dc4aa1..7d12b609357ab 100644 --- a/x-pack/plugins/maps/common/descriptor_types/sources.ts +++ b/x-pack/plugins/maps/common/descriptor_types/sources.ts @@ -115,7 +115,7 @@ export type TiledSingleLayerVectorSourceDescriptor = AbstractSourceDescriptor & minSourceZoom: number; maxSourceZoom: number; - fields?: MVTFieldDescriptor[]; + fields: MVTFieldDescriptor[]; }; export type JoinDescriptor = { diff --git a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.ts b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.ts index f2933d342bace..79dea69fd1f70 100644 --- a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.ts +++ b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.ts @@ -9,19 +9,21 @@ import uuid from 'uuid/v4'; import { AbstractSource, ImmutableSourceProperty } from '../source'; import { TiledVectorLayer } from '../../tiled_vector_layer'; import { GeoJsonWithMeta, ITiledSingleLayerVectorSource } from '../vector_source'; -import { MAX_ZOOM, MIN_ZOOM, SOURCE_TYPES } from '../../../../common/constants'; +import { FIELD_ORIGIN, MAX_ZOOM, MIN_ZOOM, SOURCE_TYPES } from '../../../../common/constants'; import { VECTOR_SHAPE_TYPES } from '../vector_feature_types'; import { IField } from '../../fields/field'; import { registerSource } from '../source_registry'; import { getDataSourceLabel, getUrlLabel } from '../../../../common/i18n_getters'; import { MapExtent, + MVTFieldDescriptor, TiledSingleLayerVectorSourceDescriptor, VectorLayerDescriptor, VectorSourceRequestMeta, VectorSourceSyncMeta, } from '../../../../common/descriptor_types'; import { VectorLayerArguments } from '../../vector_layer'; +import { MVTField } from '../../fields/mvt_field'; export const sourceTitle = i18n.translate( 'xpack.maps.source.MVTSingleLayerVectorSource.sourceTitle', @@ -46,7 +48,7 @@ export class MVTSingleLayerVectorSource extends AbstractSource layerName, minSourceZoom: Math.max(MIN_ZOOM, minSourceZoom), maxSourceZoom: Math.min(MAX_ZOOM, maxSourceZoom), - fields: fields ?? [], + fields: fields ? fields : [], }; } @@ -56,7 +58,6 @@ export class MVTSingleLayerVectorSource extends AbstractSource sourceDescriptor: TiledSingleLayerVectorSourceDescriptor, inspectorAdapters?: object ) { - console.log('crearte source', sourceDescriptor); super(sourceDescriptor, inspectorAdapters); this._descriptor = sourceDescriptor; } @@ -66,13 +67,37 @@ export class MVTSingleLayerVectorSource extends AbstractSource } getFieldNames(): string[] { - console.log('need to implement this...'); - return []; + console.log('getfn'); + return this._descriptor.fields.map((field: MVTFieldDescriptor) => { + return field.name; + }); + } + + getFieldByName(fieldName: string): IField | null { + return this.createField({ fieldName }); + } + + createField({ fieldName }: { fieldName: string }): IField { + const field = this._descriptor.fields.find((f: MVTFieldDescriptor) => { + return f.name === fieldName; + }); + return new MVTField({ + fieldName: field.name, + type: field.type, + source: this, + origin: FIELD_ORIGIN.SOURCE, + }); } async getFields(): Promise { - console.log('also need to implement this'); - return []; + return this._descriptor.fields.map((field: MVTFieldDescriptor) => { + return new MVTField({ + fieldName: field.name, + type: field.type, + source: this, + origin: FIELD_ORIGIN.SOURCE, + }); + }); } createDefaultLayer(options?: Partial): TiledVectorLayer { @@ -127,7 +152,7 @@ export class MVTSingleLayerVectorSource extends AbstractSource label: i18n.translate('xpack.maps.source.MVTSingleLayerVectorSource.fields', { defaultMessage: 'Fields', }), - value: (this._descriptor.fields ?? []).join(', '), + value: this._descriptor.fields.map(({ name, type }) => `${name}(${type})`).join(', '), }, ]; } @@ -170,10 +195,6 @@ export class MVTSingleLayerVectorSource extends AbstractSource }; } - getFieldByName(fieldName: string): IField | null { - return null; - } - getSyncMeta(): VectorSourceSyncMeta { return null; } diff --git a/x-pack/plugins/maps/public/layers/sources/vector_source/vector_source.d.ts b/x-pack/plugins/maps/public/layers/sources/vector_source/vector_source.d.ts index 804915dd73052..b0af705dd6130 100644 --- a/x-pack/plugins/maps/public/layers/sources/vector_source/vector_source.d.ts +++ b/x-pack/plugins/maps/public/layers/sources/vector_source/vector_source.d.ts @@ -36,6 +36,7 @@ export interface IVectorSource extends ISource { getSyncMeta(): VectorSourceSyncMeta; getFieldNames(): string[]; getApplyGlobalQuery(): boolean; + createField({ fieldName }: { fieldName: string }): IField; } export class AbstractVectorSource extends AbstractSource implements IVectorSource { @@ -53,6 +54,7 @@ export class AbstractVectorSource extends AbstractSource implements IVectorSourc canFormatFeatureProperties(): boolean; getApplyGlobalQuery(): boolean; getFieldNames(): string[]; + createField({ fieldName }: { fieldName: string }): IField; } export interface ITiledSingleLayerVectorSource extends IVectorSource { diff --git a/x-pack/plugins/maps/public/layers/styles/vector/components/color/dynamic_color_form.js b/x-pack/plugins/maps/public/layers/styles/vector/components/color/dynamic_color_form.js index 460e7379920c4..cecb9b96d6c72 100644 --- a/x-pack/plugins/maps/public/layers/styles/vector/components/color/dynamic_color_form.js +++ b/x-pack/plugins/maps/public/layers/styles/vector/components/color/dynamic_color_form.js @@ -126,6 +126,7 @@ export function DynamicColorForm({ } }; + console.log('render color select'); return ( diff --git a/x-pack/plugins/maps/public/layers/styles/vector/vector_style.js b/x-pack/plugins/maps/public/layers/styles/vector/vector_style.js index 5a4edd9c93a05..625860cf31698 100644 --- a/x-pack/plugins/maps/public/layers/styles/vector/vector_style.js +++ b/x-pack/plugins/maps/public/layers/styles/vector/vector_style.js @@ -146,6 +146,7 @@ export class VectorStyle extends AbstractStyle { renderEditor({ layer, onStyleDescriptorChange }) { const rawProperties = this.getRawProperties(); const handlePropertyChange = (propertyName, settings) => { + console.log('handle property change', propertyName, settings); rawProperties[propertyName] = settings; //override single property, but preserve the rest const vectorStyleDescriptor = VectorStyle.createDescriptor(rawProperties, this.isTimeAware()); onStyleDescriptorChange(vectorStyleDescriptor); @@ -579,6 +580,7 @@ export class VectorStyle extends AbstractStyle { } _makeField(fieldDescriptor) { + console.log('mkaefield', fieldDescriptor); if (!fieldDescriptor || !fieldDescriptor.name) { return null; } @@ -624,6 +626,7 @@ export class VectorStyle extends AbstractStyle { return new StaticColorProperty(descriptor.options, styleName); } else if (descriptor.type === DynamicStyleProperty.type) { const field = this._makeField(descriptor.options.field); + console.log('mnae tcolor po', field); return new DynamicColorProperty( descriptor.options, styleName, From fcfdd6c31aeae3e53a30fc503e7835d926297066 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Thu, 23 Apr 2020 18:29:45 -0400 Subject: [PATCH 05/56] more boilerpalte --- .../maps/public/layers/fields/es_agg_field.ts | 4 ++++ x-pack/plugins/maps/public/layers/fields/field.ts | 9 +++++++++ .../plugins/maps/public/layers/fields/mvt_field.ts | 4 ++++ .../layers/sources/vector_source/vector_source.d.ts | 2 ++ .../layers/sources/vector_source/vector_source.js | 4 ++++ .../vector/components/color/color_map_select.js | 12 ++++++++---- .../vector/components/color/dynamic_color_form.js | 8 ++++++-- .../styles/vector/components/style_prop_editor.js | 1 + .../styles/vector/components/vector_style_editor.js | 5 ++++- 9 files changed, 42 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/maps/public/layers/fields/es_agg_field.ts b/x-pack/plugins/maps/public/layers/fields/es_agg_field.ts index 34f7dd4b9578f..3447d640cb910 100644 --- a/x-pack/plugins/maps/public/layers/fields/es_agg_field.ts +++ b/x-pack/plugins/maps/public/layers/fields/es_agg_field.ts @@ -116,6 +116,10 @@ export class ESAggField implements IESAggField { return !isMetricCountable(this.getAggType()); } + supportsAutoDomain(): boolean { + return true; + } + canValueBeFormatted(): boolean { // Do not use field formatters for counting metrics return ![AGG_TYPE.COUNT, AGG_TYPE.UNIQUE_COUNT].includes(this.getAggType()); diff --git a/x-pack/plugins/maps/public/layers/fields/field.ts b/x-pack/plugins/maps/public/layers/fields/field.ts index b431be4aa6cb8..72b6d2a81e09f 100644 --- a/x-pack/plugins/maps/public/layers/fields/field.ts +++ b/x-pack/plugins/maps/public/layers/fields/field.ts @@ -20,6 +20,8 @@ export interface IField { isValid(): boolean; getOrdinalFieldMetaRequest(): Promise; getCategoricalFieldMetaRequest(): Promise; + supportsFieldMeta(): boolean; + supportsAutoDomain(): boolean; } export class AbstractField implements IField { @@ -72,6 +74,13 @@ export class AbstractField implements IField { return false; } + supportsAutoDomain(): boolean { + // Determines whether MAps can determine the domain of the field-values + // if this is not the case (e.g. for non-geojson data), than styling properties that require the domain to be known + // cannot use this property. + return true; + } + async getOrdinalFieldMetaRequest(): Promise { return null; } diff --git a/x-pack/plugins/maps/public/layers/fields/mvt_field.ts b/x-pack/plugins/maps/public/layers/fields/mvt_field.ts index 7ff982b14cbd9..f61e15aee544d 100644 --- a/x-pack/plugins/maps/public/layers/fields/mvt_field.ts +++ b/x-pack/plugins/maps/public/layers/fields/mvt_field.ts @@ -46,4 +46,8 @@ export class MVTField extends AbstractField implements IField { async getLabel(): Promise { return this.getName(); } + + supportsAutoDomain() { + return false; + } } diff --git a/x-pack/plugins/maps/public/layers/sources/vector_source/vector_source.d.ts b/x-pack/plugins/maps/public/layers/sources/vector_source/vector_source.d.ts index b0af705dd6130..ab2f11433e99f 100644 --- a/x-pack/plugins/maps/public/layers/sources/vector_source/vector_source.d.ts +++ b/x-pack/plugins/maps/public/layers/sources/vector_source/vector_source.d.ts @@ -37,6 +37,7 @@ export interface IVectorSource extends ISource { getFieldNames(): string[]; getApplyGlobalQuery(): boolean; createField({ fieldName }: { fieldName: string }): IField; + supportsFieldMeta(): boolean; } export class AbstractVectorSource extends AbstractSource implements IVectorSource { @@ -55,6 +56,7 @@ export class AbstractVectorSource extends AbstractSource implements IVectorSourc getApplyGlobalQuery(): boolean; getFieldNames(): string[]; createField({ fieldName }: { fieldName: string }): IField; + supportsFieldMeta(): boolean; } export interface ITiledSingleLayerVectorSource extends IVectorSource { diff --git a/x-pack/plugins/maps/public/layers/sources/vector_source/vector_source.js b/x-pack/plugins/maps/public/layers/sources/vector_source/vector_source.js index 509584cbc415a..1d3302c93c7c8 100644 --- a/x-pack/plugins/maps/public/layers/sources/vector_source/vector_source.js +++ b/x-pack/plugins/maps/public/layers/sources/vector_source/vector_source.js @@ -159,4 +159,8 @@ export class AbstractVectorSource extends AbstractSource { getSyncMeta() { return {}; } + + supportsFieldMeta() { + return true; + } } diff --git a/x-pack/plugins/maps/public/layers/styles/vector/components/color/color_map_select.js b/x-pack/plugins/maps/public/layers/styles/vector/components/color/color_map_select.js index eadaf42ca694d..43ad0c5ab7fcc 100644 --- a/x-pack/plugins/maps/public/layers/styles/vector/components/color/color_map_select.js +++ b/x-pack/plugins/maps/public/layers/styles/vector/components/color/color_map_select.js @@ -89,7 +89,8 @@ export class ColorMapSelect extends Component { }; _renderColorStopsInput() { - if (!this.props.useCustomColorMap) { + console.log('render color stops inpiut') + if (this.props.supportsAutoDomain) { return null; } @@ -102,7 +103,8 @@ export class ColorMapSelect extends Component { swatches={this.props.swatches} /> ); - } else + } else { + console.log('render colors', this.state.customColorMap); colorStopEditor = ( ); + } return ( @@ -127,11 +130,11 @@ export class ColorMapSelect extends Component { inputDisplay: this.props.customOptionLabel, 'data-test-subj': `colorMapSelectOption_${CUSTOM_COLOR_MAP}`, }, - ...this.props.colorMapOptions, + ...(this.props.supportsAutoDomain ? this.props.colorMapOptions : []), ]; let valueOfSelected; - if (this.props.useCustomColorMap) { + if (this.props.useCustomColorMap || !this.props.supportsAutoDomain) { valueOfSelected = CUSTOM_COLOR_MAP; } else { valueOfSelected = this.props.colorMapOptions.find(option => option.value === this.props.color) @@ -148,6 +151,7 @@ export class ColorMapSelect extends Component { {toggle} { + return field.supportsAutoDomain; + }); } _handleSelectedFeatureChange = selectedFeature => { From d9ad56a7302b3ef06f3b61a183cabbd6826bae5c Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Sun, 26 Apr 2020 16:05:40 -0400 Subject: [PATCH 06/56] typing --- x-pack/plugins/maps/public/layers/fields/mvt_field.ts | 7 +++---- .../public/layers/fields/top_term_percentage_field.ts | 4 ++++ .../mvt_single_layer_vector_source/layer_wizard.tsx | 2 +- .../mvt_field_config_editor.tsx | 2 +- .../mvt_single_layer_vector_source.ts | 8 +++++++- .../mvt_single_layer_vector_source_editor.tsx | 2 -- .../vector/components/color/color_map_select.js | 2 -- .../vector/components/color/dynamic_color_form.js | 11 ++++++----- .../vector/components/symbol/icon_map_select.js | 1 + .../maps/public/layers/styles/vector/vector_style.js | 3 --- 10 files changed, 23 insertions(+), 19 deletions(-) diff --git a/x-pack/plugins/maps/public/layers/fields/mvt_field.ts b/x-pack/plugins/maps/public/layers/fields/mvt_field.ts index f61e15aee544d..9dd6a15385fbe 100644 --- a/x-pack/plugins/maps/public/layers/fields/mvt_field.ts +++ b/x-pack/plugins/maps/public/layers/fields/mvt_field.ts @@ -5,13 +5,12 @@ */ import { AbstractField, IField } from './field'; -import { IKibanaRegionSource } from '../sources/kibana_regionmap_source/kibana_regionmap_source'; import { FIELD_ORIGIN } from '../../../common/constants'; -import { IVectorSource } from '../sources/vector_source'; +import { ITiledSingleLayerVectorSource, IVectorSource } from '../sources/vector_source'; import { MVTFieldType } from '../../../common/descriptor_types'; export class MVTField extends AbstractField implements IField { - private readonly _source: IKibanaRegionSource; + private readonly _source: ITiledSingleLayerVectorSource; private readonly _type: MVTFieldType; constructor({ fieldName, @@ -20,7 +19,7 @@ export class MVTField extends AbstractField implements IField { origin, }: { fieldName: string; - source: IKibanaRegionSource; + source: ITiledSingleLayerVectorSource; origin: FIELD_ORIGIN; type: MVTFieldType; }) { diff --git a/x-pack/plugins/maps/public/layers/fields/top_term_percentage_field.ts b/x-pack/plugins/maps/public/layers/fields/top_term_percentage_field.ts index 84bade4d94490..9345dd308edfe 100644 --- a/x-pack/plugins/maps/public/layers/fields/top_term_percentage_field.ts +++ b/x-pack/plugins/maps/public/layers/fields/top_term_percentage_field.ts @@ -60,6 +60,10 @@ export class TopTermPercentageField implements IESAggField { return 0; } + supportsAutoDomain(): boolean { + return true; + } + supportsFieldMeta(): boolean { return false; } diff --git a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/layer_wizard.tsx b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/layer_wizard.tsx index 37de854ed8478..8e4f12ab66502 100644 --- a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/layer_wizard.tsx +++ b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/layer_wizard.tsx @@ -31,7 +31,7 @@ export const mvtVectorSourceWizardConfig: LayerWizard = { minSourceZoom, maxSourceZoom, type: SOURCE_TYPES.MVT_SINGLE_LAYER, - fields, + fields: fields ? fields : [], }); const source = new MVTSingleLayerVectorSource(sourceDescriptor, inspectorAdapters); onPreviewSource(source); diff --git a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx index e73d14ef63939..ab7f79b426ff7 100644 --- a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx +++ b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx @@ -50,7 +50,7 @@ interface State {} export class MVTFieldConfigEditor extends Component { state = {}; - _removeField(index) { + _removeField(index: number) { const newFields = this.props.fields.slice(); newFields.splice(index, 1); diff --git a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.ts b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.ts index 79dea69fd1f70..3f432aafaf0ed 100644 --- a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.ts +++ b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.ts @@ -67,7 +67,6 @@ export class MVTSingleLayerVectorSource extends AbstractSource } getFieldNames(): string[] { - console.log('getfn'); return this._descriptor.fields.map((field: MVTFieldDescriptor) => { return field.name; }); @@ -81,6 +80,9 @@ export class MVTSingleLayerVectorSource extends AbstractSource const field = this._descriptor.fields.find((f: MVTFieldDescriptor) => { return f.name === fieldName; }); + if (!field) { + throw new Error(`Cannot create field for fieldName ${fieldName}`); + } return new MVTField({ fieldName: field.name, type: field.type, @@ -202,6 +204,10 @@ export class MVTSingleLayerVectorSource extends AbstractSource getApplyGlobalQuery(): boolean { return false; } + + supportsFieldMeta(): boolean { + return false; + } } registerSource({ diff --git a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx index 4891c4f8350d8..d20f0ba388eaf 100644 --- a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx +++ b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx @@ -43,7 +43,6 @@ export class MVTSingleLayerVectorSourceEditor extends Component { this.state.urlTemplate.indexOf('{z}') >= 0; if (canPreview && this.state.layerName) { - console.log('nf', this.state.fields); this.props.onSourceConfigChange({ urlTemplate: this.state.urlTemplate, layerName: this.state.layerName, @@ -141,7 +140,6 @@ export class MVTSingleLayerVectorSourceEditor extends Component { } )} /> - ); } diff --git a/x-pack/plugins/maps/public/layers/styles/vector/components/color/color_map_select.js b/x-pack/plugins/maps/public/layers/styles/vector/components/color/color_map_select.js index 43ad0c5ab7fcc..bcae1c4835394 100644 --- a/x-pack/plugins/maps/public/layers/styles/vector/components/color/color_map_select.js +++ b/x-pack/plugins/maps/public/layers/styles/vector/components/color/color_map_select.js @@ -89,7 +89,6 @@ export class ColorMapSelect extends Component { }; _renderColorStopsInput() { - console.log('render color stops inpiut') if (this.props.supportsAutoDomain) { return null; } @@ -104,7 +103,6 @@ export class ColorMapSelect extends Component { /> ); } else { - console.log('render colors', this.state.customColorMap); colorStopEditor = ( diff --git a/x-pack/plugins/maps/public/layers/styles/vector/components/symbol/icon_map_select.js b/x-pack/plugins/maps/public/layers/styles/vector/components/symbol/icon_map_select.js index 08f5dfe4f4ba0..bcf694d6aece8 100644 --- a/x-pack/plugins/maps/public/layers/styles/vector/components/symbol/icon_map_select.js +++ b/x-pack/plugins/maps/public/layers/styles/vector/components/symbol/icon_map_select.js @@ -41,6 +41,7 @@ export function IconMapSelect({ ); } + console.log('render stylemap select'); return ( { - console.log('handle property change', propertyName, settings); rawProperties[propertyName] = settings; //override single property, but preserve the rest const vectorStyleDescriptor = VectorStyle.createDescriptor(rawProperties, this.isTimeAware()); onStyleDescriptorChange(vectorStyleDescriptor); @@ -580,7 +579,6 @@ export class VectorStyle extends AbstractStyle { } _makeField(fieldDescriptor) { - console.log('mkaefield', fieldDescriptor); if (!fieldDescriptor || !fieldDescriptor.name) { return null; } @@ -626,7 +624,6 @@ export class VectorStyle extends AbstractStyle { return new StaticColorProperty(descriptor.options, styleName); } else if (descriptor.type === DynamicStyleProperty.type) { const field = this._makeField(descriptor.options.field); - console.log('mnae tcolor po', field); return new DynamicColorProperty( descriptor.options, styleName, From f99e4af7f5b014b5f72360d1183d5a11e354561b Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Sun, 26 Apr 2020 16:06:51 -0400 Subject: [PATCH 07/56] fix import --- x-pack/plugins/maps/public/layers/tiled_vector_layer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/maps/public/layers/tiled_vector_layer.tsx b/x-pack/plugins/maps/public/layers/tiled_vector_layer.tsx index 06c5ef579b221..e298313d4d86b 100644 --- a/x-pack/plugins/maps/public/layers/tiled_vector_layer.tsx +++ b/x-pack/plugins/maps/public/layers/tiled_vector_layer.tsx @@ -14,7 +14,7 @@ import { ITiledSingleLayerVectorSource } from './sources/vector_source'; import { SyncContext } from '../actions/map_actions'; import { ISource } from './sources/source'; import { VectorLayerDescriptor, VectorSourceRequestMeta } from '../../common/descriptor_types'; -import { MVTSingleLayerVectorSourceConfig } from './sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor'; +import { MVTSingleLayerVectorSourceConfig } from './sources/mvt_single_layer_vector_source/types'; export class TiledVectorLayer extends VectorLayer { static type = LAYER_TYPE.TILED_VECTOR; From 05e3c89733a745331544d26baf7bd914454a0fd9 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Sun, 26 Apr 2020 17:22:08 -0400 Subject: [PATCH 08/56] boilerplate --- .../maps/common/descriptor_types/sources.ts | 1 + .../features_tooltip/feature_properties.js | 2 + .../map/mb/tooltip_control/tooltip_control.js | 13 ++- .../layer_wizard.tsx | 3 +- ....ts => mvt_single_layer_vector_source.tsx} | 18 +++- .../mvt_single_layer_vector_source/types.ts | 1 + .../update_source_editor.tsx | 82 +++++++++++++++++++ 7 files changed, 111 insertions(+), 9 deletions(-) rename x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/{mvt_single_layer_vector_source.ts => mvt_single_layer_vector_source.tsx} (89%) create mode 100644 x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/update_source_editor.tsx diff --git a/x-pack/plugins/maps/common/descriptor_types/sources.ts b/x-pack/plugins/maps/common/descriptor_types/sources.ts index 7d12b609357ab..c9c0bdaa18e0d 100644 --- a/x-pack/plugins/maps/common/descriptor_types/sources.ts +++ b/x-pack/plugins/maps/common/descriptor_types/sources.ts @@ -116,6 +116,7 @@ export type TiledSingleLayerVectorSourceDescriptor = AbstractSourceDescriptor & maxSourceZoom: number; fields: MVTFieldDescriptor[]; + tooltipProperties: string[]; }; export type JoinDescriptor = { diff --git a/x-pack/plugins/maps/public/connected_components/map/features_tooltip/feature_properties.js b/x-pack/plugins/maps/public/connected_components/map/features_tooltip/feature_properties.js index 825c1ad7e7da3..5d13b1d9483d6 100644 --- a/x-pack/plugins/maps/public/connected_components/map/features_tooltip/feature_properties.js +++ b/x-pack/plugins/maps/public/connected_components/map/features_tooltip/feature_properties.js @@ -32,6 +32,7 @@ export class FeatureProperties extends React.Component { } _loadProperties = () => { + console.log('load properties') this._fetchProperties({ nextFeatureId: this.props.featureId, nextLayerId: this.props.layerId, @@ -39,6 +40,7 @@ export class FeatureProperties extends React.Component { }; _fetchProperties = async ({ nextLayerId, nextFeatureId }) => { + console.log('fetch proeprties', nextLayerId, nextFeatureId); if (this.prevLayerId === nextLayerId && this.prevFeatureId === nextFeatureId) { // do not reload same feature properties return; diff --git a/x-pack/plugins/maps/public/connected_components/map/mb/tooltip_control/tooltip_control.js b/x-pack/plugins/maps/public/connected_components/map/mb/tooltip_control/tooltip_control.js index 329d2b7fd2985..44f8bae5c44c3 100644 --- a/x-pack/plugins/maps/public/connected_components/map/mb/tooltip_control/tooltip_control.js +++ b/x-pack/plugins/maps/public/connected_components/map/mb/tooltip_control/tooltip_control.js @@ -53,7 +53,7 @@ export class TooltipControl extends React.Component { }); } - _getIdsForFeatures(mbFeatures) { + _getIdsAndFeaturesMeta(mbFeatures) { const uniqueFeatures = []; //there may be duplicates in the results from mapbox //this is because mapbox returns the results per tile @@ -72,9 +72,13 @@ export class TooltipControl extends React.Component { } } if (!match) { + //This keeps track of first properties (assuming these will be identical for features in different tiles uniqueFeatures.push({ id: featureId, layerId: layerId, + meta: { + mbProperties: mbFeature.properties, + }, }); } } @@ -98,7 +102,7 @@ export class TooltipControl extends React.Component { const targetMbFeataure = mbFeatures[0]; const popupAnchorLocation = justifyAnchorLocation(e.lngLat, targetMbFeataure); - const features = this._getIdsForFeatures(mbFeatures); + const features = this._getIdsAndFeaturesMeta(mbFeatures); this.props.openOnClickTooltip({ features: features, location: popupAnchorLocation, @@ -127,9 +131,10 @@ export class TooltipControl extends React.Component { } const popupAnchorLocation = justifyAnchorLocation(e.lngLat, targetMbFeature); - const features = this._getIdsForFeatures(mbFeatures); + const featuresAndMeta = this._getIdsAndFeaturesMeta(mbFeatures); this.props.openOnHoverTooltip({ - features: features, + mbFeatures, + features: featuresAndMeta, location: popupAnchorLocation, }); }, 100); diff --git a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/layer_wizard.tsx b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/layer_wizard.tsx index 8e4f12ab66502..46264b08613bf 100644 --- a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/layer_wizard.tsx +++ b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/layer_wizard.tsx @@ -24,14 +24,15 @@ export const mvtVectorSourceWizardConfig: LayerWizard = { minSourceZoom, maxSourceZoom, fields, + tooltipProperties, }: MVTSingleLayerVectorSourceConfig) => { const sourceDescriptor = MVTSingleLayerVectorSource.createDescriptor({ urlTemplate, layerName, minSourceZoom, maxSourceZoom, - type: SOURCE_TYPES.MVT_SINGLE_LAYER, fields: fields ? fields : [], + tooltipProperties: tooltipProperties ? tooltipProperties : [], }); const source = new MVTSingleLayerVectorSource(sourceDescriptor, inspectorAdapters); onPreviewSource(source); diff --git a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.ts b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx similarity index 89% rename from x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.ts rename to x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx index 3f432aafaf0ed..cc124ca35de9c 100644 --- a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.ts +++ b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx @@ -6,6 +6,7 @@ import { i18n } from '@kbn/i18n'; import uuid from 'uuid/v4'; +import React from 'react'; import { AbstractSource, ImmutableSourceProperty } from '../source'; import { TiledVectorLayer } from '../../tiled_vector_layer'; import { GeoJsonWithMeta, ITiledSingleLayerVectorSource } from '../vector_source'; @@ -24,6 +25,7 @@ import { } from '../../../../common/descriptor_types'; import { VectorLayerArguments } from '../../vector_layer'; import { MVTField } from '../../fields/mvt_field'; +import { UpdateSourceEditor } from './update_source_editor'; export const sourceTitle = i18n.translate( 'xpack.maps.source.MVTSingleLayerVectorSource.sourceTitle', @@ -40,6 +42,7 @@ export class MVTSingleLayerVectorSource extends AbstractSource minSourceZoom, maxSourceZoom, fields, + tooltipProperties, }: TiledSingleLayerVectorSourceDescriptor) { return { type: SOURCE_TYPES.MVT_SINGLE_LAYER, @@ -48,22 +51,29 @@ export class MVTSingleLayerVectorSource extends AbstractSource layerName, minSourceZoom: Math.max(MIN_ZOOM, minSourceZoom), maxSourceZoom: Math.min(MAX_ZOOM, maxSourceZoom), - fields: fields ? fields : [], + fields: fields ? fields : [], // todo remove. temp for debuggin older saved objects + tooltipProperties: tooltipProperties ? tooltipProperties : [], // todo remove normalization. temp for debuggin older saved objects }; } readonly _descriptor: TiledSingleLayerVectorSourceDescriptor; + readonly _tooltipFields: MVTField[]; constructor( sourceDescriptor: TiledSingleLayerVectorSourceDescriptor, inspectorAdapters?: object ) { super(sourceDescriptor, inspectorAdapters); - this._descriptor = sourceDescriptor; + this._descriptor = MVTSingleLayerVectorSource.createDescriptor(sourceDescriptor); + this._tooltipFields = this._descriptor.tooltipProperties.map(fieldName => { + return this.createField({ fieldName }); + }); } - renderSourceSettingsEditor() { - return null; + renderSourceSettingsEditor({ onChange }) { + return ( + + ); } getFieldNames(): string[] { diff --git a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/types.ts b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/types.ts index 3c1de63b96ee5..599eaea73c9a0 100644 --- a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/types.ts +++ b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/types.ts @@ -12,4 +12,5 @@ export interface MVTSingleLayerVectorSourceConfig { minSourceZoom: number; maxSourceZoom: number; fields?: MVTFieldDescriptor[]; + tooltipProperties?: string[]; } diff --git a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/update_source_editor.tsx b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/update_source_editor.tsx new file mode 100644 index 0000000000000..c83fd7eb79f33 --- /dev/null +++ b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/update_source_editor.tsx @@ -0,0 +1,82 @@ +/* + * 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 React, { Component, Fragment } from 'react'; +import { EuiTitle, EuiPanel, EuiSpacer } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; + +// @ts-ignore +import { TooltipSelector } from '../../../components/tooltip_selector'; +import { MVTField } from '../../fields/mvt_field'; +import { MVTSingleLayerVectorSource } from './mvt_single_layer_vector_source'; + +export interface Props { + tooltipFields: MVTFields[]; + onChange: (fields: MVTFields[]) => void; + source: MVTSingleLayerVectorSource; +} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +interface State { + fields: null | MVTField[]; +} + +export class UpdateSourceEditor extends Component { + state = { + fields: null, + }; + + readonly _isMounted: boolean; + + componentDidMount() { + this._isMounted = true; + this._loadFields(); + } + + componentWillUnmount() { + this._isMounted = false; + } + + async _loadFields() { + const fields = await this.props.source.getFields(); + console.log('load fields', fields); + if (this._isMounted) { + this.setState({ fields }); + } + } + + _onTooltipPropertiesSelect = (propertyNames: string[]) => { + console.log('propertiy names', propertyNames); + this.props.onChange({ propName: 'tooltipProperties', value: propertyNames }); + }; + + render() { + return ( + + + +
+ +
+
+ + + + +
+ + +
+ ); + } +} From 0ce43bdce78c9788a7e47b16cc40f86de148365c Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Sun, 26 Apr 2020 20:00:53 -0400 Subject: [PATCH 09/56] more boiler --- .../features_tooltip/feature_properties.js | 8 ++-- .../map/features_tooltip/features_tooltip.js | 2 + .../map/mb/tooltip_control/tooltip_control.js | 6 +-- .../map/mb/tooltip_control/tooltip_popover.js | 11 +++--- .../mvt_single_layer_vector_source.tsx | 39 +++++++++++++++++-- .../update_source_editor.tsx | 6 +-- .../sources/vector_source/vector_source.d.ts | 12 +++++- .../components/symbol/icon_map_select.js | 2 - .../maps/public/layers/tiled_vector_layer.tsx | 12 ++++++ .../maps/public/layers/vector_layer.d.ts | 11 ++++++ .../maps/public/layers/vector_layer.js | 5 ++- 11 files changed, 90 insertions(+), 24 deletions(-) diff --git a/x-pack/plugins/maps/public/connected_components/map/features_tooltip/feature_properties.js b/x-pack/plugins/maps/public/connected_components/map/features_tooltip/feature_properties.js index 5d13b1d9483d6..cd904b31562f3 100644 --- a/x-pack/plugins/maps/public/connected_components/map/features_tooltip/feature_properties.js +++ b/x-pack/plugins/maps/public/connected_components/map/features_tooltip/feature_properties.js @@ -31,16 +31,15 @@ export class FeatureProperties extends React.Component { this._isMounted = false; } - _loadProperties = () => { - console.log('load properties') + _loadProperties = async () => { this._fetchProperties({ nextFeatureId: this.props.featureId, nextLayerId: this.props.layerId, + meta: this.props.meta, }); }; - _fetchProperties = async ({ nextLayerId, nextFeatureId }) => { - console.log('fetch proeprties', nextLayerId, nextFeatureId); + _fetchProperties = async ({ nextLayerId, nextFeatureId, meta }) => { if (this.prevLayerId === nextLayerId && this.prevFeatureId === nextFeatureId) { // do not reload same feature properties return; @@ -66,6 +65,7 @@ export class FeatureProperties extends React.Component { properties = await this.props.loadFeatureProperties({ layerId: nextLayerId, featureId: nextFeatureId, + meta: meta, }); } catch (error) { if (this._isMounted) { diff --git a/x-pack/plugins/maps/public/connected_components/map/features_tooltip/features_tooltip.js b/x-pack/plugins/maps/public/connected_components/map/features_tooltip/features_tooltip.js index 8a1b556d21c1f..2f5ae148b07ca 100644 --- a/x-pack/plugins/maps/public/connected_components/map/features_tooltip/features_tooltip.js +++ b/x-pack/plugins/maps/public/connected_components/map/features_tooltip/features_tooltip.js @@ -104,6 +104,7 @@ export class FeaturesTooltip extends React.Component { const currentFeatureGeometry = this.props.loadFeatureGeometry({ layerId: this.state.currentFeature.layerId, featureId: this.state.currentFeature.id, + meta: this.state.currentFeature.meta, }); const geoFields = this._filterGeoFields(currentFeatureGeometry); @@ -132,6 +133,7 @@ export class FeaturesTooltip extends React.Component { { + _loadFeatureGeometry = ({ layerId, featureId, meta }) => { const tooltipLayer = this._findLayerById(layerId); if (!tooltipLayer) { return null; } - const targetFeature = tooltipLayer.getFeatureById(featureId); + const targetFeature = tooltipLayer.getFeatureById(featureId, meta); if (!targetFeature) { return null; } @@ -70,16 +70,17 @@ export class TooltipPopover extends Component { return targetFeature.geometry; }; - _loadFeatureProperties = async ({ layerId, featureId }) => { + _loadFeatureProperties = async ({ layerId, featureId, meta }) => { const tooltipLayer = this._findLayerById(layerId); if (!tooltipLayer) { return []; } - const targetFeature = tooltipLayer.getFeatureById(featureId); + const targetFeature = tooltipLayer.getFeatureById(featureId, meta); if (!targetFeature) { return []; } + return await tooltipLayer.getPropertiesForTooltip(targetFeature.properties); }; @@ -89,7 +90,7 @@ export class TooltipPopover extends Component { return null; } - const targetFeature = tooltipLayer.getFeatureById(featureId); + const targetFeature = tooltipLayer.getFeatureById(featureId, { mbProperties: {} }); if (!targetFeature) { return null; } diff --git a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx index cc124ca35de9c..d2128bbb9e30b 100644 --- a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx +++ b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx @@ -7,6 +7,7 @@ import { i18n } from '@kbn/i18n'; import uuid from 'uuid/v4'; import React from 'react'; +import { GeoJsonProperties, Geometry } from 'geojson'; import { AbstractSource, ImmutableSourceProperty } from '../source'; import { TiledVectorLayer } from '../../tiled_vector_layer'; import { GeoJsonWithMeta, ITiledSingleLayerVectorSource } from '../vector_source'; @@ -26,6 +27,7 @@ import { import { VectorLayerArguments } from '../../vector_layer'; import { MVTField } from '../../fields/mvt_field'; import { UpdateSourceEditor } from './update_source_editor'; +import { ITooltipProperty, TooltipProperty } from '../../tooltips/tooltip_property'; export const sourceTitle = i18n.translate( 'xpack.maps.source.MVTSingleLayerVectorSource.sourceTitle', @@ -133,8 +135,7 @@ export class MVTSingleLayerVectorSource extends AbstractSource searchFilters: unknown[], registerCancelCallback: (callback: () => void) => void ): Promise { - // todo: remove this method - // This is a consequence of ITiledSingleLayerVectorSource extending IVectorSource. + // Having this method here is a consequence of ITiledSingleLayerVectorSource extending IVectorSource. throw new Error('Does not implement getGeoJsonWithMeta'); } @@ -187,7 +188,7 @@ export class MVTSingleLayerVectorSource extends AbstractSource } canFormatFeatureProperties() { - return false; + return true; } getMinZoom() { @@ -198,6 +199,18 @@ export class MVTSingleLayerVectorSource extends AbstractSource return this._descriptor.maxSourceZoom; } + getFeatureProperties( + id: string | number, + mbProperties: GeoJsonProperties + ): GeoJsonProperties | null { + // Just echo the properties back + return mbProperties; + } + getFeatureGeometry(id: string | number, mbProperties: GeoJsonProperties): Geometry | null { + // Cannot get the raw geometry for a simple tiled service + return null; + } + getBoundsForFilters(searchFilters: VectorSourceRequestMeta): MapExtent { return { maxLat: 90, @@ -218,6 +231,26 @@ export class MVTSingleLayerVectorSource extends AbstractSource supportsFieldMeta(): boolean { return false; } + + async filterAndFormatPropertiesToHtml( + properties: GeoJsonProperties, + featureId?: string | number + ): Promise { + const tooltips = []; + for (const key in properties) { + if (properties.hasOwnProperty(key)) { + const field = this._tooltipFields.find((mvtField: MVTField) => { + return mvtField.getName() === key; + }); + + if (field) { + const tooltip = new TooltipProperty(key, key, properties[key]); + tooltips.push(tooltip); + } + } + } + return tooltips; + } } registerSource({ diff --git a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/update_source_editor.tsx b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/update_source_editor.tsx index c83fd7eb79f33..e486e7881dd25 100644 --- a/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/update_source_editor.tsx +++ b/x-pack/plugins/maps/public/layers/sources/mvt_single_layer_vector_source/update_source_editor.tsx @@ -42,14 +42,12 @@ export class UpdateSourceEditor extends Component { async _loadFields() { const fields = await this.props.source.getFields(); - console.log('load fields', fields); if (this._isMounted) { this.setState({ fields }); } } _onTooltipPropertiesSelect = (propertyNames: string[]) => { - console.log('propertiy names', propertyNames); this.props.onChange({ propName: 'tooltipProperties', value: propertyNames }); }; @@ -69,9 +67,9 @@ export class UpdateSourceEditor extends Component { diff --git a/x-pack/plugins/maps/public/layers/sources/vector_source/vector_source.d.ts b/x-pack/plugins/maps/public/layers/sources/vector_source/vector_source.d.ts index ab2f11433e99f..6c6a2369cca9a 100644 --- a/x-pack/plugins/maps/public/layers/sources/vector_source/vector_source.d.ts +++ b/x-pack/plugins/maps/public/layers/sources/vector_source/vector_source.d.ts @@ -5,7 +5,7 @@ */ /* eslint-disable @typescript-eslint/consistent-type-definitions */ -import { FeatureCollection } from 'geojson'; +import { FeatureCollection, GeoJsonProperties, Geometry } from 'geojson'; import { AbstractSource, ISource } from '../source'; import { IField } from '../../fields/field'; import { @@ -15,6 +15,7 @@ import { VectorSourceSyncMeta, } from '../../../../common/descriptor_types'; import { VECTOR_SHAPE_TYPES } from '../vector_feature_types'; +import { ITooltipProperty } from '../../tooltips/tooltip_property'; export type GeoJsonFetchMeta = ESSearchSourceResponseMeta; @@ -38,6 +39,8 @@ export interface IVectorSource extends ISource { getApplyGlobalQuery(): boolean; createField({ fieldName }: { fieldName: string }): IField; supportsFieldMeta(): boolean; + canFormatFeatureProperties(): boolean; + filterAndFormatPropertiesToHtml(properties: GeoJsonProperties): Promise; } export class AbstractVectorSource extends AbstractSource implements IVectorSource { @@ -57,6 +60,7 @@ export class AbstractVectorSource extends AbstractSource implements IVectorSourc getFieldNames(): string[]; createField({ fieldName }: { fieldName: string }): IField; supportsFieldMeta(): boolean; + filterAndFormatPropertiesToHtml(properties: GeoJsonProperties): Promise; } export interface ITiledSingleLayerVectorSource extends IVectorSource { @@ -68,4 +72,10 @@ export interface ITiledSingleLayerVectorSource extends IVectorSource { }>; getMinZoom(): number; getMaxZoom(): number; + + getFeatureProperties( + id: string | number, + mbProperties: GeoJsonProperties + ): GeoJsonProperties | null; + getFeatureGeometry(id: string | number, mbProperties: GeoJsonProperties): Geometry | null; } diff --git a/x-pack/plugins/maps/public/layers/styles/vector/components/symbol/icon_map_select.js b/x-pack/plugins/maps/public/layers/styles/vector/components/symbol/icon_map_select.js index bcf694d6aece8..b88f247bb6e53 100644 --- a/x-pack/plugins/maps/public/layers/styles/vector/components/symbol/icon_map_select.js +++ b/x-pack/plugins/maps/public/layers/styles/vector/components/symbol/icon_map_select.js @@ -40,8 +40,6 @@ export function IconMapSelect({ /> ); } - - console.log('render stylemap select'); return ( ; getValidJoins(): IJoin[]; getSource(): IVectorSource; + getFeatureById( + id: string | number | undefined, + meta: { mbProperties: GeoJsonProperties } + ): Feature; + getPropertiesForTooltip(properties: GeoJsonProperties, featureId?: string | number); } export class VectorLayer extends AbstractLayer implements IVectorLayer { @@ -66,4 +72,9 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { _setMbPointsProperties(mbMap: unknown, mvtSourceLayer?: string): void; _setMbLinePolygonProperties(mbMap: unknown, mvtSourceLayer?: string): void; getSource(): IVectorSource; + getFeatureById( + id: string | number | undefined, + meta: { mbProperties: GeoJsonProperties } + ): Feature; + getPropertiesForTooltip(properties: GeoJsonProperties, featureId?: string | number); } diff --git a/x-pack/plugins/maps/public/layers/vector_layer.js b/x-pack/plugins/maps/public/layers/vector_layer.js index 17b7f8152d76d..a48f853a9c080 100644 --- a/x-pack/plugins/maps/public/layers/vector_layer.js +++ b/x-pack/plugins/maps/public/layers/vector_layer.js @@ -894,8 +894,9 @@ export class VectorLayer extends AbstractLayer { } } - async getPropertiesForTooltip(properties) { - let allTooltips = await this.getSource().filterAndFormatPropertiesToHtml(properties); + async getPropertiesForTooltip(properties, featureId) { + const vectorSource = this.getSource(); + let allTooltips = await vectorSource.filterAndFormatPropertiesToHtml(properties, featureId); this._addJoinsToSourceTooltips(allTooltips); for (let i = 0; i < this.getJoins().length; i++) { From a33b1969b90b29bda890986a3dabf00841bb442d Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Sun, 26 Apr 2020 23:09:18 -0400 Subject: [PATCH 10/56] enable custom palettes --- .../styles/vector/components/color/color_map_select.js | 2 +- .../styles/vector/components/symbol/icon_map_select.js | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/maps/public/layers/styles/vector/components/color/color_map_select.js b/x-pack/plugins/maps/public/layers/styles/vector/components/color/color_map_select.js index bcae1c4835394..51d25016ec1fc 100644 --- a/x-pack/plugins/maps/public/layers/styles/vector/components/color/color_map_select.js +++ b/x-pack/plugins/maps/public/layers/styles/vector/components/color/color_map_select.js @@ -89,7 +89,7 @@ export class ColorMapSelect extends Component { }; _renderColorStopsInput() { - if (this.props.supportsAutoDomain) { + if (this.props.supportsAutoDomain && !this.props.useCustomColorMap) { return null; } diff --git a/x-pack/plugins/maps/public/layers/styles/vector/components/symbol/icon_map_select.js b/x-pack/plugins/maps/public/layers/styles/vector/components/symbol/icon_map_select.js index b88f247bb6e53..1fe2fd99afd98 100644 --- a/x-pack/plugins/maps/public/layers/styles/vector/components/symbol/icon_map_select.js +++ b/x-pack/plugins/maps/public/layers/styles/vector/components/symbol/icon_map_select.js @@ -40,15 +40,19 @@ export function IconMapSelect({ /> ); } + + const field = styleProperty.getField(); + const defaultOptions = field.supportsAutoDomain() ? getIconPaletteOptions(isDarkMode) : []; + return ( From 99aa6ca42e436710d04502085ff7312874be86ec Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Sun, 26 Apr 2020 23:23:50 -0400 Subject: [PATCH 11/56] fix label text and orientation --- .../vector/properties/dynamic_orientation_property.js | 7 +++---- .../styles/vector/properties/dynamic_text_property.js | 6 +++++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_orientation_property.js b/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_orientation_property.js index ae4d935e2457b..bba6c49a1db95 100644 --- a/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_orientation_property.js +++ b/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_orientation_property.js @@ -11,10 +11,9 @@ import { VECTOR_STYLES } from '../../../../../common/constants'; export class DynamicOrientationProperty extends DynamicStyleProperty { syncIconRotationWithMb(symbolLayerId, mbMap) { if (this._options.field && this._options.field.name) { - const targetName = getComputedFieldName( - VECTOR_STYLES.ICON_ORIENTATION, - this._options.field.name - ); + const targetName = this._field.supportsAutoDomain() + ? getComputedFieldName(VECTOR_STYLES.ICON_ORIENTATION, this._field.getName()) + : this._field.getName(); // Using property state instead of feature-state because layout properties do not support feature-state mbMap.setLayoutProperty(symbolLayerId, 'icon-rotate', ['coalesce', ['get', targetName], 0]); } else { diff --git a/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_text_property.js b/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_text_property.js index de868f3f92650..1128280714c3e 100644 --- a/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_text_property.js +++ b/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_text_property.js @@ -9,8 +9,12 @@ import { getComputedFieldName } from '../style_util'; export class DynamicTextProperty extends DynamicStyleProperty { syncTextFieldWithMb(mbLayerId, mbMap) { + console.log('synctextfieldwithmb'); if (this._field && this._field.isValid()) { - const targetName = getComputedFieldName(this._styleName, this._options.field.name); + // Fields that don't support auto-domain, are not normalized with a field-formatter and stored into a computed-field + const targetName = this._field.supportsAutoDomain() + ? getComputedFieldName(this._styleName, this._field.getName()) + : this._field.getName(); mbMap.setLayoutProperty(mbLayerId, 'text-field', ['coalesce', ['get', targetName], '']); } else { mbMap.setLayoutProperty(mbLayerId, 'text-field', null); From c5c02d718e8731d4cc0e60e26fd53c0aa8933c5e Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Thu, 14 May 2020 18:26:12 -0400 Subject: [PATCH 12/56] fix merge errors --- ....ts => mvt_single_layer_vector_source.tsx} | 107 +++++++++++++++--- .../properties/dynamic_text_property.js | 1 - 2 files changed, 89 insertions(+), 19 deletions(-) rename x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/{mvt_single_layer_vector_source.ts => mvt_single_layer_vector_source.tsx} (59%) diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.ts b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx similarity index 59% rename from x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.ts rename to x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx index b497f10188fa6..e92a293ae9b7a 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.ts +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx @@ -6,21 +6,25 @@ import { i18n } from '@kbn/i18n'; import uuid from 'uuid/v4'; -import { AbstractSource, ImmutableSourceProperty } from '../source'; +import React from 'react'; +import { GeoJsonProperties, Geometry } from 'geojson'; +import { FIELD_ORIGIN, MAX_ZOOM, MIN_ZOOM, SOURCE_TYPES } from '../../../../common/constants'; import { GeoJsonWithMeta, ITiledSingleLayerVectorSource } from '../vector_source'; -import { MAX_ZOOM, MIN_ZOOM, SOURCE_TYPES } from '../../../../common/constants'; import { VECTOR_SHAPE_TYPES } from '../vector_feature_types'; import { IField } from '../../fields/field'; import { registerSource } from '../source_registry'; import { getDataSourceLabel, getUrlLabel } from '../../../../common/i18n_getters'; import { MapExtent, + MVTFieldDescriptor, TiledSingleLayerVectorSourceDescriptor, VectorSourceRequestMeta, VectorSourceSyncMeta, } from '../../../../common/descriptor_types'; -import { TiledSingleLayerVectorSourceDescriptor } from '../../../../common/descriptor_types'; -import { ITooltipProperty } from '../../tooltips/tooltip_property'; +import { MVTField } from '../../fields/mvt_field'; +import { UpdateSourceEditor } from './update_source_editor'; +import { ITooltipProperty, TooltipProperty } from '../../tooltips/tooltip_property'; +import { AbstractSource, ImmutableSourceProperty } from '../source'; export const sourceTitle = i18n.translate( 'xpack.maps.source.MVTSingleLayerVectorSource.sourceTitle', @@ -52,21 +56,48 @@ export class MVTSingleLayerVectorSource extends AbstractSource } readonly _descriptor: TiledSingleLayerVectorSourceDescriptor; + readonly _tooltipFields: MVTField[]; constructor( sourceDescriptor: TiledSingleLayerVectorSourceDescriptor, inspectorAdapters?: object ) { super(sourceDescriptor, inspectorAdapters); - this._descriptor = sourceDescriptor; + this._descriptor = MVTSingleLayerVectorSource.createDescriptor(sourceDescriptor); + this._tooltipFields = this._descriptor.tooltipProperties.map(fieldName => { + return this.createField({ fieldName }); + }); } - renderSourceSettingsEditor() { - return null; + renderSourceSettingsEditor({ onChange }) { + return ( + + ); } getFieldNames(): string[] { - return []; + return this._descriptor.fields.map((field: MVTFieldDescriptor) => { + return field.name; + }); + } + + getFieldByName(fieldName: string): IField | null { + return this.createField({ fieldName }); + } + + createField({ fieldName }: { fieldName: string }): IField { + const field = this._descriptor.fields.find((f: MVTFieldDescriptor) => { + return f.name === fieldName; + }); + if (!field) { + throw new Error(`Cannot create field for fieldName ${fieldName}`); + } + return new MVTField({ + fieldName: field.name, + type: field.type, + source: this, + origin: FIELD_ORIGIN.SOURCE, + }); } getGeoJsonWithMeta( @@ -74,13 +105,19 @@ export class MVTSingleLayerVectorSource extends AbstractSource searchFilters: unknown[], registerCancelCallback: (callback: () => void) => void ): Promise { - // todo: remove this method - // This is a consequence of ITiledSingleLayerVectorSource extending IVectorSource. + // Having this method here is a consequence of ITiledSingleLayerVectorSource extending IVectorSource. throw new Error('Does not implement getGeoJsonWithMeta'); } async getFields(): Promise { - return []; + return this._descriptor.fields.map((field: MVTFieldDescriptor) => { + return new MVTField({ + fieldName: field.name, + type: field.type, + source: this, + origin: FIELD_ORIGIN.SOURCE, + }); + }); } async getImmutableProperties(): Promise { @@ -105,6 +142,12 @@ export class MVTSingleLayerVectorSource extends AbstractSource }), value: this._descriptor.maxSourceZoom.toString(), }, + { + label: i18n.translate('xpack.maps.source.MVTSingleLayerVectorSource.fields', { + defaultMessage: 'Fields', + }), + value: this._descriptor.fields.map(({ name, type }) => `${name}(${type})`).join(', '), + }, ]; } @@ -126,7 +169,7 @@ export class MVTSingleLayerVectorSource extends AbstractSource } canFormatFeatureProperties() { - return false; + return true; } getMinZoom() { @@ -137,6 +180,18 @@ export class MVTSingleLayerVectorSource extends AbstractSource return this._descriptor.maxSourceZoom; } + getFeatureProperties( + id: string | number, + mbProperties: GeoJsonProperties + ): GeoJsonProperties | null { + // Just echo the properties back + return mbProperties; + } + getFeatureGeometry(id: string | number, mbProperties: GeoJsonProperties): Geometry | null { + // Cannot get the raw geometry for a simple tiled service + return null; + } + getBoundsForFilters(searchFilters: VectorSourceRequestMeta): MapExtent { return { maxLat: 90, @@ -146,10 +201,6 @@ export class MVTSingleLayerVectorSource extends AbstractSource }; } - getFieldByName(fieldName: string): IField | null { - return null; - } - getSyncMeta(): VectorSourceSyncMeta { return null; } @@ -158,8 +209,28 @@ export class MVTSingleLayerVectorSource extends AbstractSource return false; } - async filterAndFormatPropertiesToHtml(properties: unknown): Promise { - return []; + supportsFieldMeta(): boolean { + return false; + } + + async filterAndFormatPropertiesToHtml( + properties: GeoJsonProperties, + featureId?: string | number + ): Promise { + const tooltips = []; + for (const key in properties) { + if (properties.hasOwnProperty(key)) { + const field = this._tooltipFields.find((mvtField: MVTField) => { + return mvtField.getName() === key; + }); + + if (field) { + const tooltip = new TooltipProperty(key, key, properties[key]); + tooltips.push(tooltip); + } + } + } + return tooltips; } } diff --git a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_text_property.js b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_text_property.js index 1128280714c3e..cbbc55bc19b47 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_text_property.js +++ b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_text_property.js @@ -9,7 +9,6 @@ import { getComputedFieldName } from '../style_util'; export class DynamicTextProperty extends DynamicStyleProperty { syncTextFieldWithMb(mbLayerId, mbMap) { - console.log('synctextfieldwithmb'); if (this._field && this._field.isValid()) { // Fields that don't support auto-domain, are not normalized with a field-formatter and stored into a computed-field const targetName = this._field.supportsAutoDomain() From 81423bd950d71b832f7ae1611746840cf694ff05 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Tue, 9 Jun 2020 16:16:47 -0400 Subject: [PATCH 13/56] remove dupe import --- .../mvt_single_layer_vector_source.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx index 93630b401b72e..dbfd02290f369 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx @@ -24,7 +24,6 @@ import { import { MVTField } from '../../fields/mvt_field'; import { UpdateSourceEditor } from './update_source_editor'; import { ITooltipProperty, TooltipProperty } from '../../tooltips/tooltip_property'; -import { AbstractSource, ImmutableSourceProperty } from '../source'; export const sourceTitle = i18n.translate( 'xpack.maps.source.MVTSingleLayerVectorSource.sourceTitle', From 9d41d94d5ada6e543ee7ff7a442428d66f1930c9 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Wed, 10 Jun 2020 12:07:56 -0400 Subject: [PATCH 14/56] stash commit --- .../maps/public/angular/map_controller.js | 1 + .../maps/public/classes/fields/mvt_field.ts | 9 +- .../maps/public/classes/layers/layer.tsx | 2 + .../tiled_vector_layer/tiled_vector_layer.tsx | 29 ++++++- .../mvt_single_layer_source_settings.tsx | 87 +++++++++++++++++++ .../mvt_single_layer_vector_source.tsx | 8 +- .../mvt_single_layer_vector_source_editor.tsx | 62 ++++--------- .../update_source_editor.tsx | 73 +++++++++++++++- .../connected_components/layer_panel/view.js | 9 +- 9 files changed, 229 insertions(+), 51 deletions(-) create mode 100644 x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx diff --git a/x-pack/legacy/plugins/maps/public/angular/map_controller.js b/x-pack/legacy/plugins/maps/public/angular/map_controller.js index 70d5195feef42..72f74b536f4b3 100644 --- a/x-pack/legacy/plugins/maps/public/angular/map_controller.js +++ b/x-pack/legacy/plugins/maps/public/angular/map_controller.js @@ -385,6 +385,7 @@ app.controller( }); // sync store with savedMap mapState + console.log('ms', savedMap, savedMap.mapStateJSON); let savedObjectFilters = []; if (savedMap.mapStateJSON) { const mapState = JSON.parse(savedMap.mapStateJSON); diff --git a/x-pack/plugins/maps/public/classes/fields/mvt_field.ts b/x-pack/plugins/maps/public/classes/fields/mvt_field.ts index 9dd6a15385fbe..bb56379953e84 100644 --- a/x-pack/plugins/maps/public/classes/fields/mvt_field.ts +++ b/x-pack/plugins/maps/public/classes/fields/mvt_field.ts @@ -7,7 +7,7 @@ import { AbstractField, IField } from './field'; import { FIELD_ORIGIN } from '../../../common/constants'; import { ITiledSingleLayerVectorSource, IVectorSource } from '../sources/vector_source'; -import { MVTFieldType } from '../../../common/descriptor_types'; +import { MVTFieldDescriptor, MVTFieldType } from '../../../common/descriptor_types'; export class MVTField extends AbstractField implements IField { private readonly _source: ITiledSingleLayerVectorSource; @@ -28,6 +28,13 @@ export class MVTField extends AbstractField implements IField { this._type = type; } + getMVTFieldDescriptor(): MVTFieldDescriptor { + return { + type: this._type, + name: this.getName(), + }; + } + getSource(): IVectorSource { return this._source; } diff --git a/x-pack/plugins/maps/public/classes/layers/layer.tsx b/x-pack/plugins/maps/public/classes/layers/layer.tsx index 2250d5663378c..179e83c2f4dcb 100644 --- a/x-pack/plugins/maps/public/classes/layers/layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/layer.tsx @@ -331,6 +331,7 @@ export class AbstractLayer implements ILayer { _removeStaleMbSourcesAndLayers(mbMap: unknown) { if (this._requiresPrevSourceCleanup(mbMap)) { + console.log('requresprevsourcelcan'); // @ts-ignore const mbStyle = mbMap.getStyle(); // @ts-ignore @@ -346,6 +347,7 @@ export class AbstractLayer implements ILayer { // @ts-ignore if (this.ownsMbSourceId(mbSourceId)) { // @ts-ignore + console.log('remnove source', mbSourceId); mbMap.removeSource(mbSourceId); } }); diff --git a/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx index b800ff5788080..71a094f520b55 100644 --- a/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx @@ -19,6 +19,7 @@ import { VectorLayerDescriptor, VectorSourceRequestMeta, } from '../../../../common/descriptor_types'; +import { MVTSingleLayerVectorSourceConfig } from '../../sources/mvt_single_layer_vector_source/types'; export class TiledVectorLayer extends VectorLayer { static type = LAYER_TYPE.TILED_VECTOR; @@ -65,12 +66,25 @@ export class TiledVectorLayer extends VectorLayer { ); const prevDataRequest = this.getSourceDataRequest(); - const canSkip = await canSkipSourceUpdate({ + const canSkipBecauseNoChangesInState = await canSkipSourceUpdate({ source: this._source as ISource, prevDataRequest, nextMeta: searchFilters, }); - if (canSkip) { + + console.log('pdr', prevDataRequest, this._source); + let canSkipBecauseNoChangesInZoom = false; + if (prevDataRequest) { + const data: MVTSingleLayerVectorSourceConfig = prevDataRequest.getData() as MVTSingleLayerVectorSourceConfig; + canSkipBecauseNoChangesInZoom = + data.minSourceZoom === this._source.getMinZoom() && + data.maxSourceZoom === this._source.getMaxZoom(); + } + + console.log(canSkipBecauseNoChangesInZoom, canSkipBecauseNoChangesInState); + + if (canSkipBecauseNoChangesInState && canSkipBecauseNoChangesInZoom) { + console.log('can skip update'); return null; } @@ -84,14 +98,17 @@ export class TiledVectorLayer extends VectorLayer { } async syncData(syncContext: DataRequestContext) { + console.log('syncData'); await this._syncSourceStyleMeta(syncContext, this._source, this._style); await this._syncSourceFormatters(syncContext, this._source, this._style); await this._syncMVTUrlTemplate(syncContext); } _syncSourceBindingWithMb(mbMap: unknown) { + console.log('syncsourcedata'); // @ts-ignore const mbSource = mbMap.getSource(this.getId()); + console.log('mbs',mbSource); if (!mbSource) { const sourceDataRequest = this.getSourceDataRequest(); if (!sourceDataRequest) { @@ -109,6 +126,7 @@ export class TiledVectorLayer extends VectorLayer { const sourceId = this.getId(); // @ts-ignore + mbMap.addSource(sourceId, { type: 'vector', tiles: [sourceMeta.urlTemplate], @@ -131,11 +149,13 @@ export class TiledVectorLayer extends VectorLayer { } const sourceMeta: TiledSingleLayerVectorSourceDescriptor = sourceDataRequest.getData() as MVTSingleLayerVectorSourceConfig; + console.log('syncstylepore', sourceMeta.layerName); this._setMbPointsProperties(mbMap, sourceMeta.layerName); this._setMbLinePolygonProperties(mbMap, sourceMeta.layerName); } _requiresPrevSourceCleanup(mbMap: unknown): boolean { + console.log('does it require cleanup?'); // @ts-ignore const mbTileSource = mbMap.getSource(this.getId()); if (!mbTileSource) { @@ -146,19 +166,24 @@ export class TiledVectorLayer extends VectorLayer { return false; } const tiledSourceMeta: TiledSingleLayerVectorSourceDescriptor | null = dataRequest.getData() as MVTSingleLayerVectorSourceConfig; + + console.log('so is this different?', mbTileSource, tiledSourceMeta); if ( mbTileSource.tiles[0] === tiledSourceMeta.urlTemplate && mbTileSource.minzoom === tiledSourceMeta.minSourceZoom && mbTileSource.maxzoom === tiledSourceMeta.maxSourceZoom ) { + // TileURL and zoom-range captures all the state. If this does not change, no updates are required. return false; } + console.log('YES cleanuo'); return true; } syncLayerWithMB(mbMap: unknown) { + console.log('synclayewithmb'); this._removeStaleMbSourcesAndLayers(mbMap); this._syncSourceBindingWithMb(mbMap); this._syncStylePropertiesWithMb(mbMap); diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx new file mode 100644 index 0000000000000..ca4638fafab8c --- /dev/null +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx @@ -0,0 +1,87 @@ +/* + * 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. + */ +/* eslint-disable @typescript-eslint/consistent-type-definitions */ + +import React, { Fragment, Component, ChangeEvent } from 'react'; +import { EuiFieldText, EuiFormRow } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { MAX_ZOOM, MIN_ZOOM } from '../../../../common/constants'; +import { ValidatedDualRange, Value } from '../../../../../../../src/plugins/kibana_react/public'; +import { MVTFieldConfigEditor } from './mvt_field_config_editor'; +import { MVTFieldDescriptor } from '../../../../common/descriptor_types'; + +export interface Props { + handleLayerNameInputChange: (layerName: string) => void; + handleFieldChange: (fields: MVTFieldDescriptor[]) => void; + handleZoomRangeChange: ({ minSourceZoom: number, maxSourceZoom: number }) => void; + layerName: string; + fields: MVTFieldDescriptor[]; + minSourceZoom: number; + maxSourceZoom: number; +} + +export class MVTSingleLayerSourceSettings extends Component { + _handleLayerNameInputChange = (e: ChangeEvent) => { + const layerName = e.target.value; + this.props.handleLayerNameInputChange(layerName); + }; + + _handleFieldChange = (fields: MVTFieldDescriptor[]) => { + this.props.handleFieldChange(fields); + }; + + _handleZoomRangeChange = (e: Value) => { + const minSourceZoom = parseInt(e[0] as string, 10); + const maxSourceZoom = parseInt(e[1] as string, 10); + this.props.handleZoomRangeChange({ minSourceZoom, maxSourceZoom }); + }; + + render() { + return ( + + + + + + + + + + ); + } +} diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx index dbfd02290f369..58932d82a278f 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx @@ -69,6 +69,7 @@ export class MVTSingleLayerVectorSource extends AbstractSource } renderSourceSettingsEditor({ onChange }) { + console.log('render source settings editor', onChange); return ( ); @@ -119,6 +120,10 @@ export class MVTSingleLayerVectorSource extends AbstractSource }); } + getLayerName():string { + return this._descriptor.layerName; + } + async getImmutableProperties(): Promise { return [ { label: getDataSourceLabel(), value: sourceTitle }, @@ -151,10 +156,11 @@ export class MVTSingleLayerVectorSource extends AbstractSource } async getDisplayName(): Promise { - return this._descriptor.layerName; + return this.getLayerName(); } async getUrlTemplateWithMeta() { + console.log('geturltemplate withmeta'); return { urlTemplate: this._descriptor.urlTemplate, layerName: this._descriptor.layerName, diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx index 5c3d008d49ef8..111024eb8f143 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx @@ -16,6 +16,7 @@ import { MVTFieldDescriptor, TiledSingleLayerVectorSourceDescriptor, } from '../../../../common/descriptor_types'; +import { MVTSingleLayerSourceSettings } from './mvt_single_layer_source_settings'; export interface Props { onSourceConfigChange: (sourceConfig: TiledSingleLayerVectorSourceDescriptor) => void; @@ -65,8 +66,7 @@ export class MVTSingleLayerVectorSourceEditor extends Component { ); }; - _handleLayerNameInputChange = (e: ChangeEvent) => { - const layerName = e.target.value; + _handleLayerNameInputChange = (layerName: string) => { this.setState( { layerName, @@ -84,10 +84,13 @@ export class MVTSingleLayerVectorSourceEditor extends Component { ); }; - _handleZoomRangeChange = (e: Value) => { - const minSourceZoom = parseInt(e[0] as string, 10); - const maxSourceZoom = parseInt(e[1] as string, 10); - + _handleZoomRangeChange = ({ + minSourceZoom, + maxSourceZoom, + }: { + minSourceZoom: number; + maxSourceZoom: number; + }) => { if (this.state.minSourceZoom !== minSourceZoom || this.state.maxSourceZoom !== maxSourceZoom) { this.setState({ minSourceZoom, maxSourceZoom }, () => this._sourceConfigChange()); } @@ -103,44 +106,15 @@ export class MVTSingleLayerVectorSourceEditor extends Component { > - - - - - - - ); diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx index e486e7881dd25..c8909dd56d74c 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx @@ -12,6 +12,9 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { TooltipSelector } from '../../../components/tooltip_selector'; import { MVTField } from '../../fields/mvt_field'; import { MVTSingleLayerVectorSource } from './mvt_single_layer_vector_source'; +import { MVTSingleLayerVectorSourceEditor } from './mvt_single_layer_vector_source_editor'; +import { MVTSingleLayerSourceSettings } from './mvt_single_layer_source_settings'; +import { MVTFieldDescriptor } from '../../../../common/descriptor_types'; export interface Props { tooltipFields: MVTFields[]; @@ -51,14 +54,71 @@ export class UpdateSourceEditor extends Component { this.props.onChange({ propName: 'tooltipProperties', value: propertyNames }); }; - render() { + _handleLayerNameInputChange = (layerName: string) => { + console.log('ln', layerName); + this.props.onChange({ propName: 'layerName', value: layerName }); + }; + + _handleFieldChange = (fields: MVTFieldDescriptor[]) => { + console.log('f', fields); + this.props.onChange({ propName: 'fields', value: fields }); + }; + + _handleZoomRangeChange = ({ + minSourceZoom, + maxSourceZoom, + }: { + minSourceZoom: number; + maxSourceZoom: number; + }) => { + console.log('zr', minSourceZoom, maxSourceZoom); + this.props.onChange({ propName: 'minSourceZoom', value: minSourceZoom }); + this.props.onChange({ propName: 'maxSourceZoom', value: maxSourceZoom }); + }; + + _renderSourceSettingsCard() { + console.log(this.props.source); + + const fields: MVTFieldDescriptor[] = (this.state.fields || []).map((field: MVTField) => { + return field.getMVTFieldDescriptor(); + }); + + return ( + + + +
+ +
+
+ + +
+ + +
+ ); + } + + _renderTooltipSelectionCard() { return (
@@ -77,4 +137,13 @@ export class UpdateSourceEditor extends Component {
); } + + render() { + return ( + + {this._renderSourceSettingsCard()} + {this._renderTooltipSelectionCard()} + + ); + } } diff --git a/x-pack/plugins/maps/public/connected_components/layer_panel/view.js b/x-pack/plugins/maps/public/connected_components/layer_panel/view.js index f34c402a4d417..59e43651229c7 100644 --- a/x-pack/plugins/maps/public/connected_components/layer_panel/view.js +++ b/x-pack/plugins/maps/public/connected_components/layer_panel/view.js @@ -32,6 +32,7 @@ import { KibanaContextProvider } from '../../../../../../src/plugins/kibana_reac import { Storage } from '../../../../../../src/plugins/kibana_utils/public'; import { getData, getCore } from '../../kibana_services'; +import _ from 'lodash'; const localStorage = new Storage(window.localStorage); @@ -53,6 +54,10 @@ export class LayerPanel extends React.Component { this._isMounted = false; } + componentDidUpdate(prevProps, prevState, snapshot) { + this.loadImmutableSourceProperties(); + } + loadDisplayName = async () => { if (!this.props.selectedLayer) { return; @@ -71,7 +76,9 @@ export class LayerPanel extends React.Component { const immutableSourceProps = await this.props.selectedLayer.getImmutableSourceProperties(); if (this._isMounted) { - this.setState({ immutableSourceProps }); + if (!_.isEqual(this.state.immutableSourceProps, immutableSourceProps)) { + this.setState({ immutableSourceProps }); + } } }; From 6d2e8d9c09c4f9da3598d0eed566aa175a754bd7 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Thu, 18 Jun 2020 18:31:38 -0400 Subject: [PATCH 15/56] tmp commit --- .../maps/common/descriptor_types/sources.ts | 8 +- .../layers/heatmap_layer/heatmap_layer.js | 2 +- .../maps/public/classes/layers/layer.tsx | 16 +-- .../tiled_vector_layer/tiled_vector_layer.tsx | 123 ++++++++++-------- .../layers/vector_layer/vector_layer.js | 8 +- .../mvt_single_layer_vector_source.tsx | 5 +- .../update_source_editor.tsx | 5 - .../sources/vector_source/vector_source.d.ts | 1 + 8 files changed, 87 insertions(+), 81 deletions(-) diff --git a/x-pack/plugins/maps/common/descriptor_types/sources.ts b/x-pack/plugins/maps/common/descriptor_types/sources.ts index 3ddbf87e45d22..2653848004379 100644 --- a/x-pack/plugins/maps/common/descriptor_types/sources.ts +++ b/x-pack/plugins/maps/common/descriptor_types/sources.ts @@ -111,9 +111,13 @@ export type TiledSingleLayerVectorSourceDescriptor = AbstractSourceDescriptor & // These are the min/max zoom levels of the availability of the a particular layerName in the tileset at urlTemplate. // These are _not_ the visible zoom-range of the data on a map. - // Tiled data can be displayed at higher levels of zoom than that they are stored in the tileset. - // e.g. EMS basemap data from level 14 is at most detailed resolution and can be displayed at higher levels + // These are important so mapbox does not issue invalid requests based on the zoom level. + + // Tiled layer data cannot be displayed at lower levels of zoom than that they are stored in the tileset. + // e.g. building footprints at level 14 cannot be displayed at level 0. minSourceZoom: number; + // Tiled layer data can be displayed at higher levels of zoom than that they are stored in the tileset. + // e.g. EMS basemap data from level 14 is at most detailed resolution and can be displayed at higher levels maxSourceZoom: number; fields: MVTFieldDescriptor[]; diff --git a/x-pack/plugins/maps/public/classes/layers/heatmap_layer/heatmap_layer.js b/x-pack/plugins/maps/public/classes/layers/heatmap_layer/heatmap_layer.js index f6b9bd6280290..adcc86b9d1546 100644 --- a/x-pack/plugins/maps/public/classes/layers/heatmap_layer/heatmap_layer.js +++ b/x-pack/plugins/maps/public/classes/layers/heatmap_layer/heatmap_layer.js @@ -91,7 +91,7 @@ export class HeatmapLayer extends VectorLayer { resolution: this.getSource().getGridResolution(), }); mbMap.setPaintProperty(heatmapLayerId, 'heatmap-opacity', this.getAlpha()); - mbMap.setLayerZoomRange(heatmapLayerId, this._descriptor.minZoom, this._descriptor.maxZoom); + mbMap.setLayerZoomRange(heatmapLayerId, this.getMinZoom(), this.getMaxZoom()); } getLayerTypeIconName() { diff --git a/x-pack/plugins/maps/public/classes/layers/layer.tsx b/x-pack/plugins/maps/public/classes/layers/layer.tsx index 179e83c2f4dcb..d62b8340767bb 100644 --- a/x-pack/plugins/maps/public/classes/layers/layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/layer.tsx @@ -331,23 +331,21 @@ export class AbstractLayer implements ILayer { _removeStaleMbSourcesAndLayers(mbMap: unknown) { if (this._requiresPrevSourceCleanup(mbMap)) { - console.log('requresprevsourcelcan'); - // @ts-ignore + // @ts-expect-error const mbStyle = mbMap.getStyle(); - // @ts-ignore + // @ts-expect-error mbStyle.layers.forEach((mbLayer) => { - // @ts-ignore + // @ts-expect-error if (this.ownsMbLayerId(mbLayer.id)) { - // @ts-ignore + // @ts-expect-error mbMap.removeLayer(mbLayer.id); } }); - // @ts-ignore + // @ts-expect-error Object.keys(mbStyle.sources).some((mbSourceId) => { - // @ts-ignore + // @ts-expect-error if (this.ownsMbSourceId(mbSourceId)) { - // @ts-ignore - console.log('remnove source', mbSourceId); + // @ts-expect-error mbMap.removeSource(mbSourceId); } }); diff --git a/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx index 71a094f520b55..6016e810cea03 100644 --- a/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx @@ -21,6 +21,8 @@ import { } from '../../../../common/descriptor_types'; import { MVTSingleLayerVectorSourceConfig } from '../../sources/mvt_single_layer_vector_source/types'; +const DELIMITER = '~'; + export class TiledVectorLayer extends VectorLayer { static type = LAYER_TYPE.TILED_VECTOR; @@ -66,26 +68,16 @@ export class TiledVectorLayer extends VectorLayer { ); const prevDataRequest = this.getSourceDataRequest(); - const canSkipBecauseNoChangesInState = await canSkipSourceUpdate({ - source: this._source as ISource, - prevDataRequest, - nextMeta: searchFilters, - }); - - console.log('pdr', prevDataRequest, this._source); - let canSkipBecauseNoChangesInZoom = false; if (prevDataRequest) { const data: MVTSingleLayerVectorSourceConfig = prevDataRequest.getData() as MVTSingleLayerVectorSourceConfig; - canSkipBecauseNoChangesInZoom = + const canSkipBecauseNoChanges = + data.layerName === this._source.getLayerName() && data.minSourceZoom === this._source.getMinZoom() && data.maxSourceZoom === this._source.getMaxZoom(); - } - - console.log(canSkipBecauseNoChangesInZoom, canSkipBecauseNoChangesInState); - if (canSkipBecauseNoChangesInState && canSkipBecauseNoChangesInZoom) { - console.log('can skip update'); - return null; + if (canSkipBecauseNoChanges) { + return null; + } } startLoading(SOURCE_DATA_REQUEST_ID, requestToken, searchFilters); @@ -98,47 +90,55 @@ export class TiledVectorLayer extends VectorLayer { } async syncData(syncContext: DataRequestContext) { - console.log('syncData'); await this._syncSourceStyleMeta(syncContext, this._source, this._style); await this._syncSourceFormatters(syncContext, this._source, this._style); await this._syncMVTUrlTemplate(syncContext); } - _syncSourceBindingWithMb(mbMap: unknown) { - console.log('syncsourcedata'); - // @ts-ignore - const mbSource = mbMap.getSource(this.getId()); - console.log('mbs',mbSource); - if (!mbSource) { - const sourceDataRequest = this.getSourceDataRequest(); - if (!sourceDataRequest) { - // this is possible if the layer was invisible at startup. - // the actions will not perform any data=syncing as an optimization when a layer is invisible - // when turning the layer back into visible, it's possible the url has not been resovled yet. - return; - } - - const sourceMeta: TiledSingleLayerVectorSourceDescriptor | null = sourceDataRequest.getData() as MVTSingleLayerVectorSourceConfig; - if (!sourceMeta) { - return; - } + // getId() { + // return this._descriptor.id + DELIMITER + this._source.getLayerName() + DELIMITER; + // } - const sourceId = this.getId(); + _getMbSourceId(): string { + return this.getId(); + } - // @ts-ignore + _syncSourceBindingWithMb(mbMap: unknown) { + // @ts-expect-error + const mbSource = mbMap.getSource(this._getMbSourceId()); + if (mbSource) { + return; + } + const sourceDataRequest = this.getSourceDataRequest(); + if (!sourceDataRequest) { + // this is possible if the layer was invisible at startup. + // the actions will not perform any data=syncing as an optimization when a layer is invisible + // when turning the layer back into visible, it's possible the url has not been resovled yet. + return; + } - mbMap.addSource(sourceId, { - type: 'vector', - tiles: [sourceMeta.urlTemplate], - minzoom: sourceMeta.minSourceZoom, - maxzoom: sourceMeta.maxSourceZoom, - }); + const sourceMeta: TiledSingleLayerVectorSourceDescriptor | null = sourceDataRequest.getData() as MVTSingleLayerVectorSourceConfig; + if (!sourceMeta) { + return; } + + const mbSourceId = this._getMbSourceId(); + // @ts-expect-error + mbMap.addSource(mbSourceId, { + type: 'vector', + tiles: [sourceMeta.urlTemplate], + minzoom: sourceMeta.minSourceZoom, + maxzoom: sourceMeta.maxSourceZoom, + }); + } + + ownsMbSourceId(mbSourceId): boolean { + return mbSourceId === this._getMbSourceId(); } _syncStylePropertiesWithMb(mbMap: unknown) { // @ts-ignore - const mbSource = mbMap.getSource(this.getId()); + const mbSource = mbMap.getSource(this._getMbSourceId()); if (!mbSource) { return; } @@ -149,41 +149,50 @@ export class TiledVectorLayer extends VectorLayer { } const sourceMeta: TiledSingleLayerVectorSourceDescriptor = sourceDataRequest.getData() as MVTSingleLayerVectorSourceConfig; - console.log('syncstylepore', sourceMeta.layerName); this._setMbPointsProperties(mbMap, sourceMeta.layerName); this._setMbLinePolygonProperties(mbMap, sourceMeta.layerName); } _requiresPrevSourceCleanup(mbMap: unknown): boolean { - console.log('does it require cleanup?'); // @ts-ignore - const mbTileSource = mbMap.getSource(this.getId()); + const mbTileSource = mbMap.getSource(this._getMbSourceId()); if (!mbTileSource) { return false; } + const dataRequest = this.getSourceDataRequest(); if (!dataRequest) { return false; } const tiledSourceMeta: TiledSingleLayerVectorSourceDescriptor | null = dataRequest.getData() as MVTSingleLayerVectorSourceConfig; - console.log('so is this different?', mbTileSource, tiledSourceMeta); - if ( - mbTileSource.tiles[0] === tiledSourceMeta.urlTemplate && - mbTileSource.minzoom === tiledSourceMeta.minSourceZoom && - mbTileSource.maxzoom === tiledSourceMeta.maxSourceZoom - ) { - - // TileURL and zoom-range captures all the state. If this does not change, no updates are required. + if (!tiledSourceMeta) { return false; } - console.log('YES cleanuo'); - return true; + // check if layername has changed + const isSourceDifferent = + mbTileSource.tiles[0] !== tiledSourceMeta.urlTemplate || + mbTileSource.minzoom !== tiledSourceMeta.minSourceZoom || + mbTileSource.maxzoom !== tiledSourceMeta.maxSourceZoom; + + if (isSourceDifferent) { + return true; + } + + const layerIds = this.getMbLayerIds(); + // just check the first layer + for (let i = 0; i < layerIds.length; i++) { + const mbLayer = mbMap.getLayer(layerIds[i]); + if (mbLayer && mbLayer.sourceLayer !== tiledSourceMeta.layerName) { + return true; + } + } + + return false; } syncLayerWithMB(mbMap: unknown) { - console.log('synclayewithmb'); this._removeStaleMbSourcesAndLayers(mbMap); this._syncSourceBindingWithMb(mbMap); this._syncStylePropertiesWithMb(mbMap); diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.js b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.js index 7bb89a9de2dfd..355df206aa2da 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.js +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.js @@ -672,10 +672,10 @@ export class VectorLayer extends AbstractLayer { } this.syncVisibilityWithMb(mbMap, markerLayerId); - mbMap.setLayerZoomRange(markerLayerId, this._descriptor.minZoom, this._descriptor.maxZoom); + mbMap.setLayerZoomRange(markerLayerId, this.getMinZoom(), this.getMaxZoom()); if (markerLayerId !== textLayerId) { this.syncVisibilityWithMb(mbMap, textLayerId); - mbMap.setLayerZoomRange(textLayerId, this._descriptor.minZoom, this._descriptor.maxZoom); + mbMap.setLayerZoomRange(textLayerId, this.getMinZoom(), this.getMaxZoom()); } } @@ -802,14 +802,14 @@ export class VectorLayer extends AbstractLayer { }); this.syncVisibilityWithMb(mbMap, fillLayerId); - mbMap.setLayerZoomRange(fillLayerId, this._descriptor.minZoom, this._descriptor.maxZoom); + mbMap.setLayerZoomRange(fillLayerId, this.getMinZoom(), this.getMaxZoom()); const fillFilterExpr = getFillFilterExpression(hasJoins); if (fillFilterExpr !== mbMap.getFilter(fillLayerId)) { mbMap.setFilter(fillLayerId, fillFilterExpr); } this.syncVisibilityWithMb(mbMap, lineLayerId); - mbMap.setLayerZoomRange(lineLayerId, this._descriptor.minZoom, this._descriptor.maxZoom); + mbMap.setLayerZoomRange(lineLayerId, this.getMinZoom(), this.getMaxZoom()); const lineFilterExpr = getLineFilterExpression(hasJoins); if (lineFilterExpr !== mbMap.getFilter(lineLayerId)) { mbMap.setFilter(lineLayerId, lineFilterExpr); diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx index 58932d82a278f..868f65afb44e0 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx @@ -69,7 +69,7 @@ export class MVTSingleLayerVectorSource extends AbstractSource } renderSourceSettingsEditor({ onChange }) { - console.log('render source settings editor', onChange); + // console.log('render source settings editor', onChange); return ( ); @@ -120,7 +120,7 @@ export class MVTSingleLayerVectorSource extends AbstractSource }); } - getLayerName():string { + getLayerName(): string { return this._descriptor.layerName; } @@ -160,7 +160,6 @@ export class MVTSingleLayerVectorSource extends AbstractSource } async getUrlTemplateWithMeta() { - console.log('geturltemplate withmeta'); return { urlTemplate: this._descriptor.urlTemplate, layerName: this._descriptor.layerName, diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx index c8909dd56d74c..317ee95fb1a4a 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx @@ -55,12 +55,10 @@ export class UpdateSourceEditor extends Component { }; _handleLayerNameInputChange = (layerName: string) => { - console.log('ln', layerName); this.props.onChange({ propName: 'layerName', value: layerName }); }; _handleFieldChange = (fields: MVTFieldDescriptor[]) => { - console.log('f', fields); this.props.onChange({ propName: 'fields', value: fields }); }; @@ -71,14 +69,11 @@ export class UpdateSourceEditor extends Component { minSourceZoom: number; maxSourceZoom: number; }) => { - console.log('zr', minSourceZoom, maxSourceZoom); this.props.onChange({ propName: 'minSourceZoom', value: minSourceZoom }); this.props.onChange({ propName: 'maxSourceZoom', value: maxSourceZoom }); }; _renderSourceSettingsCard() { - console.log(this.props.source); - const fields: MVTFieldDescriptor[] = (this.state.fields || []).map((field: MVTField) => { return field.getMVTFieldDescriptor(); }); diff --git a/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.d.ts b/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.d.ts index 8432ee81527a1..979be5c8cee8f 100644 --- a/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.d.ts +++ b/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.d.ts @@ -88,4 +88,5 @@ export interface ITiledSingleLayerVectorSource extends IVectorSource { }>; getMinZoom(): number; getMaxZoom(): number; + getLayerName(): string; } From fd785335fc16f5d1b5cb8965b0c5bf8e7dca3219 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Tue, 23 Jun 2020 01:35:20 -0400 Subject: [PATCH 16/56] debounce settings --- .../tiled_vector_layer/tiled_vector_layer.tsx | 6 +- .../ems_file_source/update_source_editor.tsx | 2 +- .../mvt_single_layer_source_settings.tsx | 68 ++++++++++++++++--- .../mvt_single_layer_vector_source.tsx | 1 - .../mvt_single_layer_vector_source_editor.tsx | 33 ++------- .../update_source_editor.tsx | 30 ++++---- .../connected_components/layer_panel/view.js | 9 ++- 7 files changed, 88 insertions(+), 61 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx index 6016e810cea03..86909e8bd5f65 100644 --- a/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx @@ -149,12 +149,16 @@ export class TiledVectorLayer extends VectorLayer { } const sourceMeta: TiledSingleLayerVectorSourceDescriptor = sourceDataRequest.getData() as MVTSingleLayerVectorSourceConfig; + if (sourceMeta.layerName === '') { + return; + } + this._setMbPointsProperties(mbMap, sourceMeta.layerName); this._setMbLinePolygonProperties(mbMap, sourceMeta.layerName); } _requiresPrevSourceCleanup(mbMap: unknown): boolean { - // @ts-ignore + // @ts-expect-error const mbTileSource = mbMap.getSource(this._getMbSourceId()); if (!mbTileSource) { return false; diff --git a/x-pack/plugins/maps/public/classes/sources/ems_file_source/update_source_editor.tsx b/x-pack/plugins/maps/public/classes/sources/ems_file_source/update_source_editor.tsx index ac69505a9bed5..c82956f530fc0 100644 --- a/x-pack/plugins/maps/public/classes/sources/ems_file_source/update_source_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/ems_file_source/update_source_editor.tsx @@ -15,7 +15,7 @@ import { OnSourceChangeArgs } from '../../../connected_components/layer_panel/vi interface Props { layerId: string; - onChange: (args: OnSourceChangeArgs) => void; + onChange: (...args: OnSourceChangeArgs) => void; source: IEmsFileSource; tooltipFields: IField[]; } diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx index ca4638fafab8c..b8f6413fc45c3 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx @@ -8,15 +8,26 @@ import React, { Fragment, Component, ChangeEvent } from 'react'; import { EuiFieldText, EuiFormRow } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import _ from 'lodash'; import { MAX_ZOOM, MIN_ZOOM } from '../../../../common/constants'; import { ValidatedDualRange, Value } from '../../../../../../../src/plugins/kibana_react/public'; import { MVTFieldConfigEditor } from './mvt_field_config_editor'; import { MVTFieldDescriptor } from '../../../../common/descriptor_types'; +export type MVTSettings = { + layerName: string; + fields: MVTFieldDescriptor[]; + minSourceZoom: number; + maxSourceZoom: number; +}; + +export interface State { + currentSettings: MVTSettings; + prevSettings: MVTSettings; +} + export interface Props { - handleLayerNameInputChange: (layerName: string) => void; - handleFieldChange: (fields: MVTFieldDescriptor[]) => void; - handleZoomRangeChange: ({ minSourceZoom: number, maxSourceZoom: number }) => void; + handleChange: (args: State) => void; layerName: string; fields: MVTFieldDescriptor[]; minSourceZoom: number; @@ -24,19 +35,49 @@ export interface Props { } export class MVTSingleLayerSourceSettings extends Component { + state = { + currentSettings: null, + prevSettings: null, + }; + + static getDerivedStateFromProps(nextProps, prevState) { + const newSettings = { + layerName: nextProps.layerName, + fields: nextProps.fields, + minSourceZoom: nextProps.minSourceZoom, + maxSourceZoom: nextProps.maxSourceZoom, + }; + + if (_.isEqual(newSettings, prevState.prevSettings)) { + return null; + } + + return { + prevSettings: newSettings, + currentSettings: newSettings, + }; + } + + _handleChange = _.debounce(() => { + this.props.handleChange(this.state.currentSettings); + }, 200); + _handleLayerNameInputChange = (e: ChangeEvent) => { const layerName = e.target.value; - this.props.handleLayerNameInputChange(layerName); + const currentSettings = { ...this.state.currentSettings, layerName }; + this.setState({ currentSettings }, this._handleChange); }; _handleFieldChange = (fields: MVTFieldDescriptor[]) => { - this.props.handleFieldChange(fields); + const currentSettings = { ...this.state.currentSettings, fields }; + this.setState({ currentSettings }, this._handleChange); }; _handleZoomRangeChange = (e: Value) => { const minSourceZoom = parseInt(e[0] as string, 10); const maxSourceZoom = parseInt(e[1] as string, 10); - this.props.handleZoomRangeChange({ minSourceZoom, maxSourceZoom }); + const currentSettings = { ...this.state.currentSettings, minSourceZoom, maxSourceZoom }; + this.setState({ currentSettings }, this._handleChange); }; render() { @@ -50,7 +91,10 @@ export class MVTSingleLayerSourceSettings extends Component { } )} > - + { } )} > - + ); diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx index 111024eb8f143..06282e3578aeb 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx @@ -66,34 +66,13 @@ export class MVTSingleLayerVectorSourceEditor extends Component { ); }; - _handleLayerNameInputChange = (layerName: string) => { - this.setState( - { - layerName, - }, - () => this._sourceConfigChange() - ); - }; - - _handleFieldChange = (fields: MVTFieldDescriptor[]) => { - this.setState( - { - fields, - }, - () => this._sourceConfigChange() - ); - }; - - _handleZoomRangeChange = ({ - minSourceZoom, - maxSourceZoom, - }: { + _handleChange = (state: { + layerName: string; + fields: MVTFieldDescriptor[]; minSourceZoom: number; maxSourceZoom: number; }) => { - if (this.state.minSourceZoom !== minSourceZoom || this.state.maxSourceZoom !== maxSourceZoom) { - this.setState({ minSourceZoom, maxSourceZoom }, () => this._sourceConfigChange()); - } + this.setState(state, () => this._sourceConfigChange()); }; render() { @@ -108,9 +87,7 @@ export class MVTSingleLayerVectorSourceEditor extends Component { void; + onChange: (...args: OnSourceChangeArgs) => void; source: MVTSingleLayerVectorSource; } @@ -54,23 +55,18 @@ export class UpdateSourceEditor extends Component { this.props.onChange({ propName: 'tooltipProperties', value: propertyNames }); }; - _handleLayerNameInputChange = (layerName: string) => { - this.props.onChange({ propName: 'layerName', value: layerName }); - }; - - _handleFieldChange = (fields: MVTFieldDescriptor[]) => { - this.props.onChange({ propName: 'fields', value: fields }); - }; - - _handleZoomRangeChange = ({ - minSourceZoom, - maxSourceZoom, - }: { + _handleChange = (state: { + layerName: string; + fields: MVTFieldDescriptor[]; minSourceZoom: number; maxSourceZoom: number; }) => { - this.props.onChange({ propName: 'minSourceZoom', value: minSourceZoom }); - this.props.onChange({ propName: 'maxSourceZoom', value: maxSourceZoom }); + this.props.onChange( + { propName: 'layerName', value: state.layerName }, + { propName: 'fields', value: state.fields }, + { propName: 'minSourceZoom', value: state.minSourceZoom }, + { propName: 'maxSourceZoom', value: state.maxSourceZoom } + ); }; _renderSourceSettingsCard() { @@ -91,9 +87,7 @@ export class UpdateSourceEditor extends Component { { - this.props.updateSourceProp(this.props.selectedLayer.getId(), propName, value, newLayerType); + _onSourceChange = (...args) => { + for (let i = 0; i < args.length; i++) { + const { propName, value, newLayerType } = args[i]; + this.props.updateSourceProp(this.props.selectedLayer.getId(), propName, value, newLayerType); + } }; _renderFilterSection() { From 907c7b03c4cf32d985fd571d837afba5b2baf4ce Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Tue, 23 Jun 2020 01:38:26 -0400 Subject: [PATCH 17/56] return null --- .../mvt_single_layer_vector_source.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx index a64498094d8f3..4d135ecd0a610 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx @@ -81,7 +81,11 @@ export class MVTSingleLayerVectorSource extends AbstractSource } getFieldByName(fieldName: string): IField | null { - return this.createField({ fieldName }); + try { + return this.createField({ fieldName }); + } catch (e) { + return null; + } } createField({ fieldName }: { fieldName: string }): IField { From fb3a399f5324dcd2b90b94ef60ea9723841b23fb Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Tue, 23 Jun 2020 01:41:40 -0400 Subject: [PATCH 18/56] slight rearrangement --- .../mvt_single_layer_source_settings.tsx | 55 +++++++++++-------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx index b8f6413fc45c3..0ef08dd2b0f97 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx @@ -98,7 +98,38 @@ export class MVTSingleLayerSourceSettings extends Component { + + + { onChange={this._handleFieldChange} /> - ); } From a689ecbf41ca26936ab7b0bfc4efae994dc865ec Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Tue, 23 Jun 2020 01:46:43 -0400 Subject: [PATCH 19/56] tooltip guard --- .../mvt_single_layer_vector_source.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx index 4d135ecd0a610..2d31f5b4eda2a 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx @@ -63,9 +63,11 @@ export class MVTSingleLayerVectorSource extends AbstractSource ) { super(sourceDescriptor, inspectorAdapters); this._descriptor = MVTSingleLayerVectorSource.createDescriptor(sourceDescriptor); - this._tooltipFields = this._descriptor.tooltipProperties.map((fieldName) => { - return this.createField({ fieldName }); - }); + this._tooltipFields = this._descriptor.tooltipProperties + .map((fieldName) => { + return this.getFieldByName(fieldName); + }) + .filter((f) => f !== null); } renderSourceSettingsEditor({ onChange }) { From 633358d10a9a4982200e3b1127e467657d5627ca Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Tue, 23 Jun 2020 12:00:26 -0400 Subject: [PATCH 20/56] minor tweaks --- .../es_search_source/load_index_settings.js | 1 - .../mvt_field_config_editor.tsx | 6 ++-- .../mvt_single_layer_source_settings.tsx | 28 ++++++++++--------- .../mvt_single_layer_vector_source_editor.tsx | 1 + .../update_source_editor.tsx | 1 + 5 files changed, 21 insertions(+), 16 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/load_index_settings.js b/x-pack/plugins/maps/public/classes/sources/es_search_source/load_index_settings.js index d5d24da225232..d4a8a31c1b060 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/load_index_settings.js +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/load_index_settings.js @@ -50,7 +50,6 @@ async function fetchIndexSettings(indexPatternTitle) { toastDisplayed = true; toasts.addWarning(warningMsg); } - console.warn(warningMsg); return { maxResultWindow: DEFAULT_MAX_RESULT_WINDOW, maxInnerResultWindow: DEFAULT_MAX_INNER_RESULT_WINDOW, diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx index ab7f79b426ff7..ae56fe25b52d1 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx @@ -13,6 +13,7 @@ import { EuiFlexItem, EuiSuperSelect, EuiFieldText, + EuiSpacer, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { MVTFieldDescriptor, MVTFieldType } from '../../../../common/descriptor_types'; @@ -77,7 +78,7 @@ export class MVTFieldConfigEditor extends Component { onChange(value)} + onChange={(value) => onChange(value)} /> ); } @@ -97,7 +98,7 @@ export class MVTFieldConfigEditor extends Component { _renderFieldConfig() { return this.props.fields.map((mvtFieldConfig: MVTFieldDescriptor, index: number) => { return ( - + {this._renderFieldNameInput(mvtFieldConfig, index)} {this._renderFieldTypeDropDown(mvtFieldConfig, index)} @@ -124,6 +125,7 @@ export class MVTFieldConfigEditor extends Component { return ( {this._renderFieldConfig()} + {'Add field'} diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx index 0ef08dd2b0f97..d1a4560da746f 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx @@ -32,6 +32,7 @@ export interface Props { fields: MVTFieldDescriptor[]; minSourceZoom: number; maxSourceZoom: number; + includeFields: boolean; } export class MVTSingleLayerSourceSettings extends Component { @@ -81,6 +82,19 @@ export class MVTSingleLayerSourceSettings extends Component { }; render() { + const fieldEditor = this.props.includeFields ? ( + + + + ) : null; + return ( { )} /> - - - + {fieldEditor} ); } diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx index 06282e3578aeb..83fb5537665f3 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx @@ -92,6 +92,7 @@ export class MVTSingleLayerVectorSourceEditor extends Component { fields={this.state.fields} minSourceZoom={this.state.minSourceZoom} maxSourceZoom={this.state.maxSourceZoom} + includeFields={false} /> ); diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx index 9bceac62295b2..143beefa4a2fd 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx @@ -92,6 +92,7 @@ export class UpdateSourceEditor extends Component { fields={fields} minSourceZoom={this.props.source.getMinZoom()} maxSourceZoom={this.props.source.getMaxZoom()} + includeFields={true} /> From 9f737f6f2c09d6920d1eb5e3b544aee16cdc876a Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Tue, 23 Jun 2020 14:31:38 -0400 Subject: [PATCH 21/56] feedback --- x-pack/plugins/maps/common/constants.ts | 5 +++++ .../maps/common/descriptor_types/sources.ts | 14 ++++++++------ .../plugins/maps/public/classes/fields/field.ts | 8 +++++--- .../maps/public/classes/fields/mvt_field.ts | 8 ++++---- .../plugins/maps/public/classes/layers/layer.tsx | 4 ++++ .../classes/layers/tile_layer/tile_layer.js | 6 +++--- .../tiled_vector_layer/tiled_vector_layer.tsx | 16 ++-------------- .../classes/layers/vector_layer/vector_layer.js | 4 ++-- .../mvt_field_config_editor.tsx | 7 ++++--- .../mvt_single_layer_vector_source_editor.tsx | 2 -- .../update_source_editor.tsx | 1 - .../vector/properties/dynamic_text_property.js | 3 ++- 12 files changed, 39 insertions(+), 39 deletions(-) diff --git a/x-pack/plugins/maps/common/constants.ts b/x-pack/plugins/maps/common/constants.ts index be3de22fa011e..503a3e8fde796 100644 --- a/x-pack/plugins/maps/common/constants.ts +++ b/x-pack/plugins/maps/common/constants.ts @@ -220,6 +220,11 @@ export enum SCALING_TYPES { export const RGBA_0000 = 'rgba(0,0,0,0)'; +export enum MVTFieldType { + STRING = 'String', + NUMBER = 'Number', +} + export const SPATIAL_FILTERS_LAYER_ID = 'SPATIAL_FILTERS_LAYER_ID'; export enum INITIAL_LOCATION { diff --git a/x-pack/plugins/maps/common/descriptor_types/sources.ts b/x-pack/plugins/maps/common/descriptor_types/sources.ts index 2653848004379..47cfd98b48150 100644 --- a/x-pack/plugins/maps/common/descriptor_types/sources.ts +++ b/x-pack/plugins/maps/common/descriptor_types/sources.ts @@ -6,7 +6,14 @@ /* eslint-disable @typescript-eslint/consistent-type-definitions */ import { Query } from 'src/plugins/data/public'; -import { AGG_TYPE, GRID_RESOLUTION, RENDER_AS, SORT_ORDER, SCALING_TYPES } from '../constants'; +import { + AGG_TYPE, + GRID_RESOLUTION, + RENDER_AS, + SORT_ORDER, + SCALING_TYPES, + MVTFieldType, +} from '../constants'; import { StyleDescriptor, VectorStyleDescriptor } from './style_property_descriptor_types'; import { DataRequestDescriptor } from './data_request_descriptor_types'; @@ -95,11 +102,6 @@ export type XYZTMSSourceDescriptor = AbstractSourceDescriptor & urlTemplate: string; }; -export enum MVTFieldType { - String = 'String', - Number = 'Number', -} - export type MVTFieldDescriptor = { name: string; type: MVTFieldType; diff --git a/x-pack/plugins/maps/public/classes/fields/field.ts b/x-pack/plugins/maps/public/classes/fields/field.ts index e6032c3f55675..410b38e79ffe4 100644 --- a/x-pack/plugins/maps/public/classes/fields/field.ts +++ b/x-pack/plugins/maps/public/classes/fields/field.ts @@ -20,7 +20,12 @@ export interface IField { isValid(): boolean; getOrdinalFieldMetaRequest(): Promise; getCategoricalFieldMetaRequest(size: number): Promise; + + // Determines whether Maps-app can automatically determine the domain of the field-values + // if this is not the case (e.g. for .mvt tiled data), + // then styling properties that require the domain to be known cannot use this property. supportsAutoDomain(): boolean; + supportsFieldMeta(): boolean; } @@ -83,9 +88,6 @@ export class AbstractField implements IField { } supportsAutoDomain(): boolean { - // Determines whether MAps can determine the domain of the field-values - // if this is not the case (e.g. for non-geojson data), than styling properties that require the domain to be known - // cannot use this property. return true; } } diff --git a/x-pack/plugins/maps/public/classes/fields/mvt_field.ts b/x-pack/plugins/maps/public/classes/fields/mvt_field.ts index bb56379953e84..8f9856ef1da46 100644 --- a/x-pack/plugins/maps/public/classes/fields/mvt_field.ts +++ b/x-pack/plugins/maps/public/classes/fields/mvt_field.ts @@ -5,9 +5,9 @@ */ import { AbstractField, IField } from './field'; -import { FIELD_ORIGIN } from '../../../common/constants'; +import { FIELD_ORIGIN, MVTFieldType } from '../../../common/constants'; import { ITiledSingleLayerVectorSource, IVectorSource } from '../sources/vector_source'; -import { MVTFieldDescriptor, MVTFieldType } from '../../../common/descriptor_types'; +import { MVTFieldDescriptor } from '../../../common/descriptor_types'; export class MVTField extends AbstractField implements IField { private readonly _source: ITiledSingleLayerVectorSource; @@ -40,9 +40,9 @@ export class MVTField extends AbstractField implements IField { } async getDataType(): Promise { - if (this._type === MVTFieldType.String) { + if (this._type === MVTFieldType.STRING) { return 'string'; - } else if (this._type === MVTFieldType.Number) { + } else if (this._type === MVTFieldType.NUMBER) { return 'number'; } else { throw new Error(`Unrecognized MVT field-type ${this._type}`); diff --git a/x-pack/plugins/maps/public/classes/layers/layer.tsx b/x-pack/plugins/maps/public/classes/layers/layer.tsx index d62b8340767bb..90d712dc03990 100644 --- a/x-pack/plugins/maps/public/classes/layers/layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/layer.tsx @@ -325,6 +325,10 @@ export class AbstractLayer implements ILayer { return this._source.getMinZoom(); } + _getMbSourceId() { + return this.getId(); + } + _requiresPrevSourceCleanup(mbMap: unknown) { return false; } diff --git a/x-pack/plugins/maps/public/classes/layers/tile_layer/tile_layer.js b/x-pack/plugins/maps/public/classes/layers/tile_layer/tile_layer.js index 02df8acbfffad..3e2009c24a2e4 100644 --- a/x-pack/plugins/maps/public/classes/layers/tile_layer/tile_layer.js +++ b/x-pack/plugins/maps/public/classes/layers/tile_layer/tile_layer.js @@ -74,8 +74,8 @@ export class TileLayer extends AbstractLayer { return; } - const sourceId = this.getId(); - mbMap.addSource(sourceId, { + const mbSourceId = this._getMbSourceId(); + mbMap.addSource(mbSourceId, { type: 'raster', tiles: [tmsSourceData.url], tileSize: 256, @@ -85,7 +85,7 @@ export class TileLayer extends AbstractLayer { mbMap.addLayer({ id: mbLayerId, type: 'raster', - source: sourceId, + source: mbSourceId, minzoom: this._descriptor.minZoom, maxzoom: this._descriptor.maxZoom, }); diff --git a/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx index 86909e8bd5f65..c832d1fbf62a2 100644 --- a/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx @@ -10,10 +10,8 @@ import { Feature, GeoJsonProperties } from 'geojson'; import { VectorStyle } from '../../styles/vector/vector_style'; import { SOURCE_DATA_REQUEST_ID, LAYER_TYPE } from '../../../../common/constants'; import { VectorLayer, VectorLayerArguments } from '../vector_layer/vector_layer'; -import { canSkipSourceUpdate } from '../../util/can_skip_fetch'; import { ITiledSingleLayerVectorSource } from '../../sources/vector_source'; import { DataRequestContext } from '../../../actions'; -import { ISource } from '../../sources/source'; import { TiledSingleLayerVectorSourceDescriptor, VectorLayerDescriptor, @@ -21,8 +19,6 @@ import { } from '../../../../common/descriptor_types'; import { MVTSingleLayerVectorSourceConfig } from '../../sources/mvt_single_layer_vector_source/types'; -const DELIMITER = '~'; - export class TiledVectorLayer extends VectorLayer { static type = LAYER_TYPE.TILED_VECTOR; @@ -95,14 +91,6 @@ export class TiledVectorLayer extends VectorLayer { await this._syncMVTUrlTemplate(syncContext); } - // getId() { - // return this._descriptor.id + DELIMITER + this._source.getLayerName() + DELIMITER; - // } - - _getMbSourceId(): string { - return this.getId(); - } - _syncSourceBindingWithMb(mbMap: unknown) { // @ts-expect-error const mbSource = mbMap.getSource(this._getMbSourceId()); @@ -174,7 +162,6 @@ export class TiledVectorLayer extends VectorLayer { return false; } - // check if layername has changed const isSourceDifferent = mbTileSource.tiles[0] !== tiledSourceMeta.urlTemplate || mbTileSource.minzoom !== tiledSourceMeta.minSourceZoom || @@ -185,10 +172,11 @@ export class TiledVectorLayer extends VectorLayer { } const layerIds = this.getMbLayerIds(); - // just check the first layer for (let i = 0; i < layerIds.length; i++) { const mbLayer = mbMap.getLayer(layerIds[i]); if (mbLayer && mbLayer.sourceLayer !== tiledSourceMeta.layerName) { + // If the source-pointer of one of the layers is stale, they will all be stale. + // In this case, all the mb-layers need to be removed and re-added. return true; } } diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.js b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.js index 355df206aa2da..44c53149c8753 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.js +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.js @@ -822,9 +822,9 @@ export class VectorLayer extends AbstractLayer { } _syncSourceBindingWithMb(mbMap) { - const mbSource = mbMap.getSource(this.getId()); + const mbSource = mbMap.getSource(this._getMbSourceId()); if (!mbSource) { - mbMap.addSource(this.getId(), { + mbMap.addSource(this._getMbSourceId(), { type: 'geojson', data: EMPTY_FEATURE_COLLECTION, }); diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx index ae56fe25b52d1..f40340a561e1c 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx @@ -16,12 +16,13 @@ import { EuiSpacer, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { MVTFieldDescriptor, MVTFieldType } from '../../../../common/descriptor_types'; +import { MVTFieldDescriptor } from '../../../../common/descriptor_types'; import { FieldIcon } from '../../../../../../../src/plugins/kibana_react/public'; +import { MVTFieldType } from '../../../../common/constants'; const FIELD_TYPE_OPTIONS = [ { - value: MVTFieldType.String, + value: MVTFieldType.STRING, inputDisplay: ( @@ -30,7 +31,7 @@ const FIELD_TYPE_OPTIONS = [ ), }, { - value: MVTFieldType.Number, + value: MVTFieldType.NUMBER, inputDisplay: ( diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx index 83fb5537665f3..f7b1b38df170c 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx @@ -10,8 +10,6 @@ import _ from 'lodash'; import { EuiFieldText, EuiFormRow } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { MAX_ZOOM, MIN_ZOOM } from '../../../../common/constants'; -import { ValidatedDualRange, Value } from '../../../../../../../src/plugins/kibana_react/public'; -import { MVTFieldConfigEditor } from './mvt_field_config_editor'; import { MVTFieldDescriptor, TiledSingleLayerVectorSourceDescriptor, diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx index 143beefa4a2fd..20410682b494d 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx @@ -12,7 +12,6 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { TooltipSelector } from '../../../components/tooltip_selector'; import { MVTField } from '../../fields/mvt_field'; import { MVTSingleLayerVectorSource } from './mvt_single_layer_vector_source'; -import { MVTSingleLayerVectorSourceEditor } from './mvt_single_layer_vector_source_editor'; import { MVTSingleLayerSourceSettings } from './mvt_single_layer_source_settings'; import { MVTFieldDescriptor } from '../../../../common/descriptor_types'; import { OnSourceChangeArgs } from '../../../connected_components/layer_panel/view'; diff --git a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_text_property.js b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_text_property.js index cbbc55bc19b47..ffe0d73a19bb5 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_text_property.js +++ b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_text_property.js @@ -10,7 +10,8 @@ import { getComputedFieldName } from '../style_util'; export class DynamicTextProperty extends DynamicStyleProperty { syncTextFieldWithMb(mbLayerId, mbMap) { if (this._field && this._field.isValid()) { - // Fields that don't support auto-domain, are not normalized with a field-formatter and stored into a computed-field + // Fields that support auto-domain are normalized with a field-formatter and stored into a computed-field + // Otherwise, the raw value is just carried over and no computed field is created. const targetName = this._field.supportsAutoDomain() ? getComputedFieldName(this._styleName, this._field.getName()) : this._field.getName(); From 42a250bd564a29749479a4d07aa76af3be7ec586 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Tue, 23 Jun 2020 15:30:47 -0400 Subject: [PATCH 22/56] ts fixes --- .../maps/common/descriptor_types/sources.ts | 5 ++++- .../mvt_single_layer_source_settings.tsx | 2 +- .../mvt_single_layer_vector_source.tsx | 15 +++++++++------ .../mvt_single_layer_vector_source_editor.tsx | 4 ++-- .../update_source_editor.tsx | 18 ++++++------------ .../maps/public/classes/sources/source.ts | 2 +- 6 files changed, 23 insertions(+), 23 deletions(-) diff --git a/x-pack/plugins/maps/common/descriptor_types/sources.ts b/x-pack/plugins/maps/common/descriptor_types/sources.ts index 47cfd98b48150..0786c3349f02e 100644 --- a/x-pack/plugins/maps/common/descriptor_types/sources.ts +++ b/x-pack/plugins/maps/common/descriptor_types/sources.ts @@ -107,7 +107,7 @@ export type MVTFieldDescriptor = { type: MVTFieldType; }; -export type TiledSingleLayerVectorSourceDescriptor = AbstractSourceDescriptor & { +export type TiledSingleLayerVectorSourceSettings = { urlTemplate: string; layerName: string; @@ -126,6 +126,9 @@ export type TiledSingleLayerVectorSourceDescriptor = AbstractSourceDescriptor & tooltipProperties: string[]; }; +export type TiledSingleLayerVectorSourceDescriptor = AbstractSourceDescriptor & + TiledSingleLayerVectorSourceSettings; + export type JoinDescriptor = { leftField: string; right: ESTermSourceDescriptor; diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx index d1a4560da746f..3b1a96b79e1bc 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx @@ -27,7 +27,7 @@ export interface State { } export interface Props { - handleChange: (args: State) => void; + handleChange: (args: MVTSettings) => void; layerName: string; fields: MVTFieldDescriptor[]; minSourceZoom: number; diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx index 2d31f5b4eda2a..3032841829c1e 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx @@ -8,11 +8,10 @@ import { i18n } from '@kbn/i18n'; import uuid from 'uuid/v4'; import React from 'react'; import { GeoJsonProperties, Geometry } from 'geojson'; -import { AbstractSource, ImmutableSourceProperty } from '../source'; +import { AbstractSource, ImmutableSourceProperty, SourceEditorArgs } from '../source'; import { BoundsFilters, GeoJsonWithMeta, ITiledSingleLayerVectorSource } from '../vector_source'; import { FIELD_ORIGIN, MAX_ZOOM, MIN_ZOOM, SOURCE_TYPES } from '../../../../common/constants'; import { VECTOR_SHAPE_TYPES } from '../vector_feature_types'; -import { IField } from '../../fields/field'; import { registerSource } from '../source_registry'; import { getDataSourceLabel, getUrlLabel } from '../../../../common/i18n_getters'; import { @@ -70,7 +69,11 @@ export class MVTSingleLayerVectorSource extends AbstractSource .filter((f) => f !== null); } - renderSourceSettingsEditor({ onChange }) { + async supportsFitToBounds() { + return false; + } + + renderSourceSettingsEditor({ onChange }: SourceEditorArgs) { return ( ); @@ -82,7 +85,7 @@ export class MVTSingleLayerVectorSource extends AbstractSource }); } - getFieldByName(fieldName: string): IField | null { + getFieldByName(fieldName: string): MVTField | null { try { return this.createField({ fieldName }); } catch (e) { @@ -90,7 +93,7 @@ export class MVTSingleLayerVectorSource extends AbstractSource } } - createField({ fieldName }: { fieldName: string }): IField { + createField({ fieldName }: { fieldName: string }): MVTField { const field = this._descriptor.fields.find((f: MVTFieldDescriptor) => { return f.name === fieldName; }); @@ -114,7 +117,7 @@ export class MVTSingleLayerVectorSource extends AbstractSource throw new Error('Does not implement getGeoJsonWithMeta'); } - async getFields(): Promise { + async getFields(): Promise { return this._descriptor.fields.map((field: MVTFieldDescriptor) => { return new MVTField({ fieldName: field.name, diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx index f7b1b38df170c..4e04eb14f1c37 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.tsx @@ -12,12 +12,12 @@ import { i18n } from '@kbn/i18n'; import { MAX_ZOOM, MIN_ZOOM } from '../../../../common/constants'; import { MVTFieldDescriptor, - TiledSingleLayerVectorSourceDescriptor, + TiledSingleLayerVectorSourceSettings, } from '../../../../common/descriptor_types'; import { MVTSingleLayerSourceSettings } from './mvt_single_layer_source_settings'; export interface Props { - onSourceConfigChange: (sourceConfig: TiledSingleLayerVectorSourceDescriptor) => void; + onSourceConfigChange: (sourceConfig: TiledSingleLayerVectorSourceSettings) => void; } interface State { diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx index 20410682b494d..d052bd398be30 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx @@ -8,17 +8,16 @@ import React, { Component, Fragment } from 'react'; import { EuiTitle, EuiPanel, EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -// @ts-ignore import { TooltipSelector } from '../../../components/tooltip_selector'; import { MVTField } from '../../fields/mvt_field'; import { MVTSingleLayerVectorSource } from './mvt_single_layer_vector_source'; -import { MVTSingleLayerSourceSettings } from './mvt_single_layer_source_settings'; +import { MVTSettings, MVTSingleLayerSourceSettings } from './mvt_single_layer_source_settings'; import { MVTFieldDescriptor } from '../../../../common/descriptor_types'; import { OnSourceChangeArgs } from '../../../connected_components/layer_panel/view'; export interface Props { - tooltipFields: MVTFields[]; - onChange: (...args: OnSourceChangeArgs) => void; + tooltipFields: MVTField[]; + onChange: (...args: OnSourceChangeArgs[]) => void; source: MVTSingleLayerVectorSource; } @@ -32,7 +31,7 @@ export class UpdateSourceEditor extends Component { fields: null, }; - readonly _isMounted: boolean; + private _isMounted: boolean = false; componentDidMount() { this._isMounted = true; @@ -44,7 +43,7 @@ export class UpdateSourceEditor extends Component { } async _loadFields() { - const fields = await this.props.source.getFields(); + const fields: MVTField[] = (await this.props.source.getFields()) as MVTField[]; if (this._isMounted) { this.setState({ fields }); } @@ -54,12 +53,7 @@ export class UpdateSourceEditor extends Component { this.props.onChange({ propName: 'tooltipProperties', value: propertyNames }); }; - _handleChange = (state: { - layerName: string; - fields: MVTFieldDescriptor[]; - minSourceZoom: number; - maxSourceZoom: number; - }) => { + _handleChange = (state: MVTSettings) => { this.props.onChange( { propName: 'layerName', value: state.layerName }, { propName: 'fields', value: state.fields }, diff --git a/x-pack/plugins/maps/public/classes/sources/source.ts b/x-pack/plugins/maps/public/classes/sources/source.ts index a7bf6a19103f3..4ed1b2151b94c 100644 --- a/x-pack/plugins/maps/public/classes/sources/source.ts +++ b/x-pack/plugins/maps/public/classes/sources/source.ts @@ -17,7 +17,7 @@ import { MAX_ZOOM, MIN_ZOOM } from '../../../common/constants'; import { OnSourceChangeArgs } from '../../connected_components/layer_panel/view'; export type SourceEditorArgs = { - onChange: (args: OnSourceChangeArgs) => void; + onChange: (...args: OnSourceChangeArgs[]) => void; }; export type ImmutableSourceProperty = { From 9ef9277634450024d20a89a9967efb3087306db0 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Tue, 23 Jun 2020 15:43:14 -0400 Subject: [PATCH 23/56] ts fixes --- .../maps/common/descriptor_types/sources.ts | 6 ++-- .../mvt_single_layer_source_settings.tsx | 30 ++++++++++++------- .../mvt_single_layer_vector_source.tsx | 2 +- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/x-pack/plugins/maps/common/descriptor_types/sources.ts b/x-pack/plugins/maps/common/descriptor_types/sources.ts index 0786c3349f02e..80f96a8ccfe63 100644 --- a/x-pack/plugins/maps/common/descriptor_types/sources.ts +++ b/x-pack/plugins/maps/common/descriptor_types/sources.ts @@ -91,7 +91,6 @@ export type KibanaTilemapSourceDescriptor = AbstractSourceDescriptor; export type WMSSourceDescriptor = AbstractSourceDescriptor & { serviceUrl: string; - layers: string; styles: string; attributionText: string; attributionUrl: string; @@ -123,11 +122,12 @@ export type TiledSingleLayerVectorSourceSettings = { maxSourceZoom: number; fields: MVTFieldDescriptor[]; - tooltipProperties: string[]; }; export type TiledSingleLayerVectorSourceDescriptor = AbstractSourceDescriptor & - TiledSingleLayerVectorSourceSettings; + TiledSingleLayerVectorSourceSettings & { + tooltipProperties: string[]; + }; export type JoinDescriptor = { leftField: string; diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx index 3b1a96b79e1bc..3ad215858cac3 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx @@ -36,11 +36,6 @@ export interface Props { } export class MVTSingleLayerSourceSettings extends Component { - state = { - currentSettings: null, - prevSettings: null, - }; - static getDerivedStateFromProps(nextProps, prevState) { const newSettings = { layerName: nextProps.layerName, @@ -64,20 +59,33 @@ export class MVTSingleLayerSourceSettings extends Component { }, 200); _handleLayerNameInputChange = (e: ChangeEvent) => { - const layerName = e.target.value; - const currentSettings = { ...this.state.currentSettings, layerName }; + const currentSettings = { + layerName: e.target.value, + minSourceZoom: this.state.currentSettings.minSourceZoom, + maxSourceZoom: this.state.currentSettings.maxSourceZoom, + fields: this.state.currentSettings.fields, + }; + this.setState({ currentSettings }, this._handleChange); }; _handleFieldChange = (fields: MVTFieldDescriptor[]) => { - const currentSettings = { ...this.state.currentSettings, fields }; + const currentSettings = { + layerName: this.state.currentSettings.layerName, + minSourceZoom: this.state.currentSettings.minSourceZoom, + maxSourceZoom: this.state.currentSettings.maxSourceZoom, + fields, + }; this.setState({ currentSettings }, this._handleChange); }; _handleZoomRangeChange = (e: Value) => { - const minSourceZoom = parseInt(e[0] as string, 10); - const maxSourceZoom = parseInt(e[1] as string, 10); - const currentSettings = { ...this.state.currentSettings, minSourceZoom, maxSourceZoom }; + const currentSettings = { + layerName: this.state.currentSettings.layerName, + fields: this.state.currentSettings.fields, + minSourceZoom: parseInt(e[0] as string, 10), + maxSourceZoom: parseInt(e[1] as string, 10), + }; this.setState({ currentSettings }, this._handleChange); }; diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx index 3032841829c1e..7c48db171df2b 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx @@ -66,7 +66,7 @@ export class MVTSingleLayerVectorSource extends AbstractSource .map((fieldName) => { return this.getFieldByName(fieldName); }) - .filter((f) => f !== null); + .filter((f) => f !== null) as MVTField[]; } async supportsFitToBounds() { From df3ac2cfb9da2fadd19058e1fd7f2df8968f5a72 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Tue, 23 Jun 2020 15:58:16 -0400 Subject: [PATCH 24/56] more ts fixes --- .../classes/layers/vector_layer/vector_layer.d.ts | 14 +++++++++++++- .../classes/layers/vector_layer/vector_layer.js | 8 ++++---- .../ems_file_source/update_source_editor.tsx | 2 +- .../layer_wizard.tsx | 6 ++---- .../mvt_field_config_editor.tsx | 2 +- .../mvt_single_layer_source_settings.tsx | 4 ++-- 6 files changed, 23 insertions(+), 13 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.d.ts b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.d.ts index 4ed987cac70a8..6e7485dabbc0c 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.d.ts +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.d.ts @@ -18,6 +18,7 @@ import { IJoin } from '../../joins/join'; import { IVectorStyle } from '../../styles/vector/vector_style'; import { IField } from '../../fields/field'; import { DataRequestContext } from '../../../actions'; +import { ITooltipProperty } from '../../tooltips/tooltip_property'; export type VectorLayerArguments = { source: IVectorSource; @@ -36,7 +37,10 @@ export interface IVectorLayer extends ILayer { id: string | number | undefined, meta: { mbProperties: GeoJsonProperties } ): Feature; - getPropertiesForTooltip(properties: GeoJsonProperties, featureId?: string | number); + getPropertiesForTooltip( + properties: GeoJsonProperties, + featureId?: string | number + ): Promise; } export class VectorLayer extends AbstractLayer implements IVectorLayer { @@ -81,4 +85,12 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { _setMbLinePolygonProperties(mbMap: unknown, mvtSourceLayer?: string): void; getSource(): IVectorSource; getStyle(): IVectorStyle; + getFeatureById( + id: string | number | undefined, + meta: { mbProperties: GeoJsonProperties } + ): Feature; + getPropertiesForTooltip( + properties: GeoJsonProperties, + featureId?: string | number + ): Promise; } diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.js b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.js index 44c53149c8753..a4be6080b7e60 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.js +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.js @@ -892,16 +892,16 @@ export class VectorLayer extends AbstractLayer { async getPropertiesForTooltip(properties, featureId) { const vectorSource = this.getSource(); - let allTooltips = await vectorSource.filterAndFormatPropertiesToHtml(properties, featureId); - this._addJoinsToSourceTooltips(allTooltips); + let allProperties = await vectorSource.filterAndFormatPropertiesToHtml(properties, featureId); + this._addJoinsToSourceTooltips(allProperties); for (let i = 0; i < this.getJoins().length; i++) { const propsFromJoin = await this.getJoins()[i].filterAndFormatPropertiesForTooltip( properties ); - allTooltips = [...allTooltips, ...propsFromJoin]; + allProperties = [...allProperties, ...propsFromJoin]; } - return allTooltips; + return allProperties; } canShowTooltip() { diff --git a/x-pack/plugins/maps/public/classes/sources/ems_file_source/update_source_editor.tsx b/x-pack/plugins/maps/public/classes/sources/ems_file_source/update_source_editor.tsx index c82956f530fc0..7021859ee9827 100644 --- a/x-pack/plugins/maps/public/classes/sources/ems_file_source/update_source_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/ems_file_source/update_source_editor.tsx @@ -15,7 +15,7 @@ import { OnSourceChangeArgs } from '../../../connected_components/layer_panel/vi interface Props { layerId: string; - onChange: (...args: OnSourceChangeArgs) => void; + onChange: (...args: OnSourceChangeArgs[]) => void; source: IEmsFileSource; tooltipFields: IField[]; } diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/layer_wizard.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/layer_wizard.tsx index 067c7f5a47ca3..44bf96fc29883 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/layer_wizard.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/layer_wizard.tsx @@ -6,14 +6,12 @@ import { i18n } from '@kbn/i18n'; import React from 'react'; -import { - MVTSingleLayerVectorSourceEditor, - MVTSingleLayerVectorSourceConfig, -} from './mvt_single_layer_vector_source_editor'; +import { MVTSingleLayerVectorSourceEditor } from './mvt_single_layer_vector_source_editor'; import { MVTSingleLayerVectorSource, sourceTitle } from './mvt_single_layer_vector_source'; import { LayerWizard, RenderWizardArguments } from '../../layers/layer_wizard_registry'; import { TiledVectorLayer } from '../../layers/tiled_vector_layer/tiled_vector_layer'; import { LAYER_WIZARD_CATEGORY } from '../../../../common/constants'; +import { MVTSingleLayerVectorSourceConfig } from './types'; export const mvtVectorSourceWizardConfig: LayerWizard = { categories: [LAYER_WIZARD_CATEGORY.REFERENCE], diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx index f40340a561e1c..6d02870cb87aa 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx @@ -62,7 +62,7 @@ export class MVTFieldConfigEditor extends Component { _addField = () => { const newFields = this.props.fields.slice(); newFields.push({ - type: MVTFieldType.String, + type: MVTFieldType.STRING, name: 'Foobar', }); this.props.onChange(newFields); diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx index 3ad215858cac3..001f2ccff8e1a 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx @@ -36,7 +36,7 @@ export interface Props { } export class MVTSingleLayerSourceSettings extends Component { - static getDerivedStateFromProps(nextProps, prevState) { + static getDerivedStateFromProps(nextProps: Props, prevState: State) { const newSettings = { layerName: nextProps.layerName, fields: nextProps.fields, @@ -44,7 +44,7 @@ export class MVTSingleLayerSourceSettings extends Component { maxSourceZoom: nextProps.maxSourceZoom, }; - if (_.isEqual(newSettings, prevState.prevSettings)) { + if (prevState && _.isEqual(newSettings, prevState.prevSettings)) { return null; } From d0994af610f8c9ef1f999c632608c3263a4bc114 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Tue, 23 Jun 2020 16:51:52 -0400 Subject: [PATCH 25/56] ts fixes --- .../maps/public/classes/layers/layer.tsx | 5 +--- .../tiled_vector_layer/tiled_vector_layer.tsx | 23 +++++++++++-------- .../layers/vector_layer/vector_layer.d.ts | 4 ++-- .../layers/vector_layer/vector_layer.js | 2 +- .../layer_wizard.tsx | 4 ++-- .../mvt_single_layer_vector_source.tsx | 20 +++++++++------- .../sources/vector_source/vector_source.d.ts | 8 +++++++ 7 files changed, 40 insertions(+), 26 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/layers/layer.tsx b/x-pack/plugins/maps/public/classes/layers/layer.tsx index 90d712dc03990..e122d1cda3ed9 100644 --- a/x-pack/plugins/maps/public/classes/layers/layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/layer.tsx @@ -339,15 +339,12 @@ export class AbstractLayer implements ILayer { const mbStyle = mbMap.getStyle(); // @ts-expect-error mbStyle.layers.forEach((mbLayer) => { - // @ts-expect-error if (this.ownsMbLayerId(mbLayer.id)) { // @ts-expect-error mbMap.removeLayer(mbLayer.id); } }); - // @ts-expect-error Object.keys(mbStyle.sources).some((mbSourceId) => { - // @ts-expect-error if (this.ownsMbSourceId(mbSourceId)) { // @ts-expect-error mbMap.removeSource(mbSourceId); @@ -433,7 +430,7 @@ export class AbstractLayer implements ILayer { throw new Error('Should implement AbstractLayer#ownsMbLayerId'); } - ownsMbSourceId(sourceId: string): boolean { + ownsMbSourceId(mbSourceId: string): boolean { throw new Error('Should implement AbstractLayer#ownsMbSourceId'); } diff --git a/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx index c832d1fbf62a2..b7a19364d1c9d 100644 --- a/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx @@ -13,7 +13,6 @@ import { VectorLayer, VectorLayerArguments } from '../vector_layer/vector_layer' import { ITiledSingleLayerVectorSource } from '../../sources/vector_source'; import { DataRequestContext } from '../../../actions'; import { - TiledSingleLayerVectorSourceDescriptor, VectorLayerDescriptor, VectorSourceRequestMeta, } from '../../../../common/descriptor_types'; @@ -105,7 +104,7 @@ export class TiledVectorLayer extends VectorLayer { return; } - const sourceMeta: TiledSingleLayerVectorSourceDescriptor | null = sourceDataRequest.getData() as MVTSingleLayerVectorSourceConfig; + const sourceMeta: MVTSingleLayerVectorSourceConfig | null = sourceDataRequest.getData() as MVTSingleLayerVectorSourceConfig; if (!sourceMeta) { return; } @@ -120,8 +119,8 @@ export class TiledVectorLayer extends VectorLayer { }); } - ownsMbSourceId(mbSourceId): boolean { - return mbSourceId === this._getMbSourceId(); + ownsMbSourceId(mbSourceId: string): boolean { + return this._getMbSourceId() === mbSourceId; } _syncStylePropertiesWithMb(mbMap: unknown) { @@ -135,8 +134,7 @@ export class TiledVectorLayer extends VectorLayer { if (!sourceDataRequest) { return; } - const sourceMeta: TiledSingleLayerVectorSourceDescriptor = sourceDataRequest.getData() as MVTSingleLayerVectorSourceConfig; - + const sourceMeta: MVTSingleLayerVectorSourceConfig = sourceDataRequest.getData() as MVTSingleLayerVectorSourceConfig; if (sourceMeta.layerName === '') { return; } @@ -156,7 +154,7 @@ export class TiledVectorLayer extends VectorLayer { if (!dataRequest) { return false; } - const tiledSourceMeta: TiledSingleLayerVectorSourceDescriptor | null = dataRequest.getData() as MVTSingleLayerVectorSourceConfig; + const tiledSourceMeta: MVTSingleLayerVectorSourceConfig | null = dataRequest.getData() as MVTSingleLayerVectorSourceConfig; if (!tiledSourceMeta) { return false; @@ -173,6 +171,7 @@ export class TiledVectorLayer extends VectorLayer { const layerIds = this.getMbLayerIds(); for (let i = 0; i < layerIds.length; i++) { + // @ts-expect-error const mbLayer = mbMap.getLayer(layerIds[i]); if (mbLayer && mbLayer.sourceLayer !== tiledSourceMeta.layerName) { // If the source-pointer of one of the layers is stale, they will all be stale. @@ -202,10 +201,16 @@ export class TiledVectorLayer extends VectorLayer { getFeatureById( id: string | number | undefined, meta: { mbProperties: GeoJsonProperties } - ): Feature { + ): Feature | null { + const geometry = this._source.getFeatureGeometry(id, meta.mbProperties); + if (geometry === null) { + return null; + } + return { + type: 'Feature', properties: this._source.getFeatureProperties(id, meta.mbProperties), - geometry: this._source.getFeatureGeometry(id, meta.mbProperties), + geometry, id, }; } diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.d.ts b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.d.ts index 6e7485dabbc0c..74d382e0d7a80 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.d.ts +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.d.ts @@ -36,7 +36,7 @@ export interface IVectorLayer extends ILayer { getFeatureById( id: string | number | undefined, meta: { mbProperties: GeoJsonProperties } - ): Feature; + ): Feature | null; getPropertiesForTooltip( properties: GeoJsonProperties, featureId?: string | number @@ -88,7 +88,7 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { getFeatureById( id: string | number | undefined, meta: { mbProperties: GeoJsonProperties } - ): Feature; + ): Feature | null; getPropertiesForTooltip( properties: GeoJsonProperties, featureId?: string | number diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.js b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.js index a4be6080b7e60..ed69ff80d635f 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.js +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.js @@ -913,7 +913,7 @@ export class VectorLayer extends AbstractLayer { getFeatureById(id) { const featureCollection = this._getSourceFeatureCollection(); if (!featureCollection) { - return; + return null; } return featureCollection.features.find((feature) => { diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/layer_wizard.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/layer_wizard.tsx index 44bf96fc29883..6312b58c1c3c9 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/layer_wizard.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/layer_wizard.tsx @@ -11,7 +11,7 @@ import { MVTSingleLayerVectorSource, sourceTitle } from './mvt_single_layer_vect import { LayerWizard, RenderWizardArguments } from '../../layers/layer_wizard_registry'; import { TiledVectorLayer } from '../../layers/tiled_vector_layer/tiled_vector_layer'; import { LAYER_WIZARD_CATEGORY } from '../../../../common/constants'; -import { MVTSingleLayerVectorSourceConfig } from './types'; +import { TiledSingleLayerVectorSourceSettings } from '../../../../common/descriptor_types'; export const mvtVectorSourceWizardConfig: LayerWizard = { categories: [LAYER_WIZARD_CATEGORY.REFERENCE], @@ -20,7 +20,7 @@ export const mvtVectorSourceWizardConfig: LayerWizard = { }), icon: 'grid', renderWizard: ({ previewLayers, mapColors }: RenderWizardArguments) => { - const onSourceConfigChange = (sourceConfig: MVTSingleLayerVectorSourceConfig) => { + const onSourceConfigChange = (sourceConfig: TiledSingleLayerVectorSourceSettings) => { const sourceDescriptor = MVTSingleLayerVectorSource.createDescriptor(sourceConfig); const layerDescriptor = TiledVectorLayer.createDescriptor({ sourceDescriptor }, mapColors); previewLayers([layerDescriptor]); diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx index 7c48db171df2b..54464be717184 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx @@ -40,14 +40,16 @@ export class MVTSingleLayerVectorSource extends AbstractSource maxSourceZoom, fields, tooltipProperties, - }: TiledSingleLayerVectorSourceDescriptor) { + }: Partial) { return { type: SOURCE_TYPES.MVT_SINGLE_LAYER, id: uuid(), - urlTemplate, - layerName, - minSourceZoom: Math.max(MIN_ZOOM, minSourceZoom), - maxSourceZoom: Math.min(MAX_ZOOM, maxSourceZoom), + urlTemplate: urlTemplate ? urlTemplate : '', + layerName: layerName ? layerName : '', + minSourceZoom: + typeof minSourceZoom === 'number' ? Math.max(MIN_ZOOM, minSourceZoom) : MIN_ZOOM, + maxSourceZoom: + typeof maxSourceZoom === 'number' ? Math.min(MAX_ZOOM, maxSourceZoom) : MAX_ZOOM, fields: fields ? fields : [], tooltipProperties: tooltipProperties ? tooltipProperties : [], }; @@ -193,13 +195,15 @@ export class MVTSingleLayerVectorSource extends AbstractSource } getFeatureProperties( - id: string | number, + id: string | number | undefined, mbProperties: GeoJsonProperties ): GeoJsonProperties | null { - // Just echo the properties back return mbProperties; } - getFeatureGeometry(id: string | number, mbProperties: GeoJsonProperties): Geometry | null { + getFeatureGeometry( + id: string | number | undefined, + mbProperties: GeoJsonProperties + ): Geometry | null { // Cannot get the raw geometry for a simple tiled service return null; } diff --git a/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.d.ts b/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.d.ts index 979be5c8cee8f..f1063d7371e89 100644 --- a/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.d.ts +++ b/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.d.ts @@ -89,4 +89,12 @@ export interface ITiledSingleLayerVectorSource extends IVectorSource { getMinZoom(): number; getMaxZoom(): number; getLayerName(): string; + getFeatureProperties( + id: string | number | undefined, + mbProperties: GeoJsonProperties + ): GeoJsonProperties | null; + getFeatureGeometry( + id: string | number | undefined, + mbProperties: GeoJsonProperties + ): Geometry | null; } From a81a22aefaf5c2bf9462e5947a206e49a265f0e6 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Tue, 23 Jun 2020 17:04:47 -0400 Subject: [PATCH 26/56] jest test --- .../sources/mvt_single_layer_vector_source/layer_wizard.tsx | 2 +- .../map/mb/tooltip_control/tooltip_control.test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/layer_wizard.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/layer_wizard.tsx index 6312b58c1c3c9..1973570765295 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/layer_wizard.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/layer_wizard.tsx @@ -16,7 +16,7 @@ import { TiledSingleLayerVectorSourceSettings } from '../../../../common/descrip export const mvtVectorSourceWizardConfig: LayerWizard = { categories: [LAYER_WIZARD_CATEGORY.REFERENCE], description: i18n.translate('xpack.maps.source.mvtVectorSourceWizard', { - defaultMessage: 'Vector source wizard', + defaultMessage: '.mvt vector tiles', }), icon: 'grid', renderWizard: ({ previewLayers, mapColors }: RenderWizardArguments) => { diff --git a/x-pack/plugins/maps/public/connected_components/map/mb/tooltip_control/tooltip_control.test.js b/x-pack/plugins/maps/public/connected_components/map/mb/tooltip_control/tooltip_control.test.js index 31964c3395417..741088b4c428b 100644 --- a/x-pack/plugins/maps/public/connected_components/map/mb/tooltip_control/tooltip_control.test.js +++ b/x-pack/plugins/maps/public/connected_components/map/mb/tooltip_control/tooltip_control.test.js @@ -236,7 +236,7 @@ describe('TooltipControl', () => { sinon.assert.notCalled(closeOnClickTooltipStub); sinon.assert.calledWith(openOnClickTooltipStub, { - features: [{ id: 1, layerId: 'tfi3f' }], + features: [{ id: 1, layerId: 'tfi3f', meta: { mbProperties: { __kbn__feature_id__: 1 } } }], location: [100, 30], }); }); From 753fb303cbb63b27a2ea3febd54af7c6c4e8500e Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Wed, 24 Jun 2020 10:23:05 -0400 Subject: [PATCH 27/56] fix typo --- .../classes/sources/es_search_source/load_index_settings.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/load_index_settings.js b/x-pack/plugins/maps/public/classes/sources/es_search_source/load_index_settings.js index d4a8a31c1b060..45f5ec8a33a09 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/load_index_settings.js +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/load_index_settings.js @@ -50,6 +50,8 @@ async function fetchIndexSettings(indexPatternTitle) { toastDisplayed = true; toasts.addWarning(warningMsg); } + + console.warn(warningMsg); return { maxResultWindow: DEFAULT_MAX_RESULT_WINDOW, maxInnerResultWindow: DEFAULT_MAX_INNER_RESULT_WINDOW, From 9a7ba7b80b16a4204082eca0335a5da3abecf1d4 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Wed, 24 Jun 2020 10:23:29 -0400 Subject: [PATCH 28/56] spacing --- .../classes/sources/es_search_source/load_index_settings.js | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/load_index_settings.js b/x-pack/plugins/maps/public/classes/sources/es_search_source/load_index_settings.js index 45f5ec8a33a09..d5d24da225232 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/load_index_settings.js +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/load_index_settings.js @@ -50,7 +50,6 @@ async function fetchIndexSettings(indexPatternTitle) { toastDisplayed = true; toasts.addWarning(warningMsg); } - console.warn(warningMsg); return { maxResultWindow: DEFAULT_MAX_RESULT_WINDOW, From bc20cec8f0fa0d2cf4402bdc4b1c84d1fbafddad Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Wed, 24 Jun 2020 15:08:13 -0400 Subject: [PATCH 29/56] fix typing --- .../plugins/maps/common/descriptor_types/sources.ts | 1 + .../tiled_vector_layer/tiled_vector_layer.tsx | 13 +++++++++++-- .../classes/layers/vector_layer/vector_layer.js | 4 ++-- .../mvt_single_layer_vector_source.tsx | 1 + 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/maps/common/descriptor_types/sources.ts b/x-pack/plugins/maps/common/descriptor_types/sources.ts index 80f96a8ccfe63..dfbb4a8ff929d 100644 --- a/x-pack/plugins/maps/common/descriptor_types/sources.ts +++ b/x-pack/plugins/maps/common/descriptor_types/sources.ts @@ -91,6 +91,7 @@ export type KibanaTilemapSourceDescriptor = AbstractSourceDescriptor; export type WMSSourceDescriptor = AbstractSourceDescriptor & { serviceUrl: string; + layers: string; styles: string; attributionText: string; attributionUrl: string; diff --git a/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx index b7a19364d1c9d..ffea1febe2e4e 100644 --- a/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx @@ -203,13 +203,22 @@ export class TiledVectorLayer extends VectorLayer { meta: { mbProperties: GeoJsonProperties } ): Feature | null { const geometry = this._source.getFeatureGeometry(id, meta.mbProperties); + const properties = this._source.getFeatureProperties(id, meta.mbProperties); if (geometry === null) { - return null; + return { + type: 'Feature', + properties, + id, + geometry: { + type: 'Point', + coordinates: [0, 0], + }, + }; } return { type: 'Feature', - properties: this._source.getFeatureProperties(id, meta.mbProperties), + properties, geometry, id, }; diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.js b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.js index ed69ff80d635f..0a4fcfc23060c 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.js +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.js @@ -890,9 +890,9 @@ export class VectorLayer extends AbstractLayer { } } - async getPropertiesForTooltip(properties, featureId) { + async getPropertiesForTooltip(properties) { const vectorSource = this.getSource(); - let allProperties = await vectorSource.filterAndFormatPropertiesToHtml(properties, featureId); + let allProperties = await vectorSource.filterAndFormatPropertiesToHtml(properties); this._addJoinsToSourceTooltips(allProperties); for (let i = 0; i < this.getJoins().length; i++) { diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx index 54464be717184..5d96254487322 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx @@ -64,6 +64,7 @@ export class MVTSingleLayerVectorSource extends AbstractSource ) { super(sourceDescriptor, inspectorAdapters); this._descriptor = MVTSingleLayerVectorSource.createDescriptor(sourceDescriptor); + this._tooltipFields = this._descriptor.tooltipProperties .map((fieldName) => { return this.getFieldByName(fieldName); From f79904becd5c0dd708e39d716bd2e243df3d0276 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Wed, 24 Jun 2020 15:59:17 -0400 Subject: [PATCH 30/56] add unit test --- .../mvt_single_layer_vector_source.test.tsx | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.test.tsx diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.test.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.test.tsx new file mode 100644 index 0000000000000..230c086cd3935 --- /dev/null +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.test.tsx @@ -0,0 +1,25 @@ +/* + * 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 { MVTSingleLayerVectorSource } from './mvt_single_layer_vector_source'; +import { SOURCE_TYPES } from '../../../../common/constants'; +import { TiledSingleLayerVectorSourceDescriptor } from '../../../../common/descriptor_types'; + +const descriptor: TiledSingleLayerVectorSourceDescriptor = { + type: SOURCE_TYPES.MVT_SINGLE_LAYER, + urlTemplate: 'https://example.com/{x}/{y}/{z}.pbf', + layerName: 'foobar', + minSourceZoom: 4, + maxSourceZoom: 14, + fields: [], +}; +describe('xyz Tilemap Source', () => { + it('should echo configuration', async () => { + const source = new MVTSingleLayerVectorSource(descriptor); + const config = await source.getUrlTemplateWithMeta(); + expect(config.urlTemplate).toEqual(descriptor.urlTemplate); + }); +}); From 9b81fc113f7c9db4c14bf5c3082becc0b7e927d3 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Wed, 24 Jun 2020 16:16:28 -0400 Subject: [PATCH 31/56] add more tests --- .../mvt_single_layer_vector_source.test.tsx | 43 ++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.test.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.test.tsx index 230c086cd3935..8b6b9c5c5c1cf 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.test.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.test.tsx @@ -5,7 +5,7 @@ */ import { MVTSingleLayerVectorSource } from './mvt_single_layer_vector_source'; -import { SOURCE_TYPES } from '../../../../common/constants'; +import { MVTFieldType, SOURCE_TYPES } from '../../../../common/constants'; import { TiledSingleLayerVectorSourceDescriptor } from '../../../../common/descriptor_types'; const descriptor: TiledSingleLayerVectorSourceDescriptor = { @@ -15,11 +15,50 @@ const descriptor: TiledSingleLayerVectorSourceDescriptor = { minSourceZoom: 4, maxSourceZoom: 14, fields: [], + tooltipProperties: [], }; -describe('xyz Tilemap Source', () => { + +describe('getUrlTemplateWithMeta', () => { it('should echo configuration', async () => { const source = new MVTSingleLayerVectorSource(descriptor); const config = await source.getUrlTemplateWithMeta(); expect(config.urlTemplate).toEqual(descriptor.urlTemplate); + expect(config.layerName).toEqual(descriptor.layerName); + expect(config.minSourceZoom).toEqual(descriptor.minSourceZoom); + expect(config.maxSourceZoom).toEqual(descriptor.maxSourceZoom); + }); +}); + +describe('filterAndFormatPropertiesToHtml', () => { + const descriptorWithFields = { + ...descriptor, + fields: [ + { + name: 'foo', + type: MVTFieldType.STRING, + }, + { + name: 'food', + type: MVTFieldType.STRING, + }, + { + name: 'fooz', + type: MVTFieldType.NUMBER, + }, + ], + tooltipProperties: ['foo', 'fooz'], + }; + + it('should get tooltipproperties', async () => { + const source = new MVTSingleLayerVectorSource(descriptorWithFields); + const tooltipProperties = await source.filterAndFormatPropertiesToHtml({ + foo: 'bar', + fooz: 123, + }); + expect(tooltipProperties.length).toEqual(2); + expect(tooltipProperties[0].getPropertyName()).toEqual('foo'); + expect(tooltipProperties[0].getHtmlDisplayValue()).toEqual('bar'); + expect(tooltipProperties[1].getPropertyName()).toEqual('fooz'); + expect(tooltipProperties[1].getHtmlDisplayValue()).toEqual('123'); }); }); From b249ce6b2c015998b68d08b527b9498ab0a1563a Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Wed, 24 Jun 2020 16:22:51 -0400 Subject: [PATCH 32/56] add snapshot test --- .../update_source_editor.test.tsx.snap | 57 +++++++++++++++++++ .../update_source_editor.test.tsx | 35 ++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/update_source_editor.test.tsx.snap create mode 100644 x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.test.tsx diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/update_source_editor.test.tsx.snap b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/update_source_editor.test.tsx.snap new file mode 100644 index 0000000000000..13f205254dc95 --- /dev/null +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/update_source_editor.test.tsx.snap @@ -0,0 +1,57 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should render update source editor 1`] = ` + + + +
+ +
+
+ + +
+ + + +
+ +
+
+ + +
+ +
+`; diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.test.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.test.tsx new file mode 100644 index 0000000000000..00819791548c8 --- /dev/null +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.test.tsx @@ -0,0 +1,35 @@ +/* + * 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. + */ + +jest.mock('../../../kibana_services', () => ({})); + +import React from 'react'; +import { shallow } from 'enzyme'; + +import { UpdateSourceEditor } from './update_source_editor'; +import { MVTSingleLayerVectorSource } from './mvt_single_layer_vector_source'; +import { TiledSingleLayerVectorSourceDescriptor } from '../../../../common/descriptor_types'; +import { SOURCE_TYPES } from '../../../../common/constants'; + +const descriptor: TiledSingleLayerVectorSourceDescriptor = { + type: SOURCE_TYPES.MVT_SINGLE_LAYER, + urlTemplate: 'https://example.com/{x}/{y}/{z}.pbf', + layerName: 'foobar', + minSourceZoom: 4, + maxSourceZoom: 14, + fields: [], + tooltipProperties: [], +}; + +test('should render update source editor', async () => { + const source = new MVTSingleLayerVectorSource(descriptor); + + const component = shallow( + {}} /> + ); + + expect(component).toMatchSnapshot(); +}); From adc872bc989ad3677cbd7c67ef5ff6cd29d881c2 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Wed, 24 Jun 2020 16:28:09 -0400 Subject: [PATCH 33/56] add snapshot --- ...e_layer_vector_source_editor.test.tsx.snap | 28 +++++++++++++++++++ ...single_layer_vector_source_editor.test.tsx | 18 ++++++++++++ .../update_source_editor.test.tsx | 2 +- 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_single_layer_vector_source_editor.test.tsx.snap create mode 100644 x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.test.tsx diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_single_layer_vector_source_editor.test.tsx.snap b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_single_layer_vector_source_editor.test.tsx.snap new file mode 100644 index 0000000000000..525a99e030204 --- /dev/null +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_single_layer_vector_source_editor.test.tsx.snap @@ -0,0 +1,28 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should render source creation editor 1`] = ` + + + + + + +`; diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.test.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.test.tsx new file mode 100644 index 0000000000000..986756f840014 --- /dev/null +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source_editor.test.tsx @@ -0,0 +1,18 @@ +/* + * 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. + */ + +jest.mock('../../../kibana_services', () => ({})); + +import React from 'react'; +import { shallow } from 'enzyme'; + +import { MVTSingleLayerVectorSourceEditor } from './mvt_single_layer_vector_source_editor'; + +test('should render source creation editor (fields should _not_ be included)', async () => { + const component = shallow( {}} />); + + expect(component).toMatchSnapshot(); +}); diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.test.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.test.tsx index 00819791548c8..fd19379058e3b 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.test.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.test.tsx @@ -24,7 +24,7 @@ const descriptor: TiledSingleLayerVectorSourceDescriptor = { tooltipProperties: [], }; -test('should render update source editor', async () => { +test('should render update source editor (fields _should_ be included)', async () => { const source = new MVTSingleLayerVectorSource(descriptor); const component = shallow( From f9d974cb9ffb9b1744bdfce5a1f50376175e8c59 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Wed, 24 Jun 2020 16:35:32 -0400 Subject: [PATCH 34/56] add field editor snapshot test --- .../mvt_field_config_editor.test.tsx.snap | 191 ++++++++++++++++++ .../mvt_field_config_editor.test.tsx | 33 +++ 2 files changed, 224 insertions(+) create mode 100644 x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_field_config_editor.test.tsx.snap create mode 100644 x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.test.tsx diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_field_config_editor.test.tsx.snap b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_field_config_editor.test.tsx.snap new file mode 100644 index 0000000000000..a959c4897e83e --- /dev/null +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_field_config_editor.test.tsx.snap @@ -0,0 +1,191 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should render field editor 1`] = ` + + + + + + + + + + String + +
, + "value": "String", + }, + Object { + "inputDisplay": + + + Number + + , + "value": "Number", + }, + ] + } + valueOfSelected="String" + /> +
+ + + +
+ + + + + + + + + String + + , + "value": "String", + }, + Object { + "inputDisplay": + + + Number + + , + "value": "Number", + }, + ] + } + valueOfSelected="String" + /> + + + + + + + + + + + + + + String + + , + "value": "String", + }, + Object { + "inputDisplay": + + + Number + + , + "value": "Number", + }, + ] + } + valueOfSelected="Number" + /> + + + + + + + + Add field + + +`; diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.test.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.test.tsx new file mode 100644 index 0000000000000..b62db6bb95776 --- /dev/null +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.test.tsx @@ -0,0 +1,33 @@ +/* + * 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. + */ + +jest.mock('../../../kibana_services', () => ({})); + +import React from 'react'; +import { shallow } from 'enzyme'; + +import { MVTFieldConfigEditor } from './mvt_field_config_editor'; +import { MVTFieldType } from '../../../../common/constants'; + +test('should render field editor', async () => { + const fields = [ + { + name: 'foo', + type: MVTFieldType.STRING, + }, + { + name: 'food', + type: MVTFieldType.STRING, + }, + { + name: 'fooz', + type: MVTFieldType.NUMBER, + }, + ]; + const component = shallow( {}} />); + + expect(component).toMatchSnapshot(); +}); From 6e2ffb0d2108b0ed96a5b5a07000e082a1c9799e Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Thu, 25 Jun 2020 15:01:48 -0400 Subject: [PATCH 35/56] fix snapshot --- .../update_source_editor.test.tsx.snap | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/update_source_editor.test.tsx.snap b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/update_source_editor.test.tsx.snap index 13f205254dc95..df7713f3a3019 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/update_source_editor.test.tsx.snap +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/update_source_editor.test.tsx.snap @@ -1,5 +1,61 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`should render update source editor (fields _should_ be included) 1`] = ` + + + +
+ +
+
+ + +
+ + + +
+ +
+
+ + +
+ +
+`; + exports[`should render update source editor 1`] = ` From 4c92c6b61bc03676ec6d113fd5c199afdb8528a2 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Thu, 25 Jun 2020 15:09:47 -0400 Subject: [PATCH 36/56] add snapshot --- ...single_layer_source_settings.test.tsx.snap | 128 ++++++++++++++++++ .../mvt_single_layer_source_settings.test.tsx | 48 +++++++ 2 files changed, 176 insertions(+) create mode 100644 x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_single_layer_source_settings.test.tsx.snap create mode 100644 x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.test.tsx diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_single_layer_source_settings.test.tsx.snap b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_single_layer_source_settings.test.tsx.snap new file mode 100644 index 0000000000000..afe1c72a0d536 --- /dev/null +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_single_layer_source_settings.test.tsx.snap @@ -0,0 +1,128 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should render with fields 1`] = ` + + + + + + + + + + + +`; + +exports[`should render without fields 1`] = ` + + + + + + + + +`; diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.test.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.test.tsx new file mode 100644 index 0000000000000..af8f54fc3b504 --- /dev/null +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.test.tsx @@ -0,0 +1,48 @@ +/* + * 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 { MVTFieldDescriptor } from '../../../../common/descriptor_types'; + +jest.mock('../../../kibana_services', () => ({})); + +import React from 'react'; +import { shallow } from 'enzyme'; + +import { MVTSingleLayerSourceSettings } from './mvt_single_layer_source_settings'; +import { MVTFieldType } from '../../../../common/constants'; + +const defaultSettings = { + handleChange: () => {}, + layerName: 'foobar', + fields: [ + { + name: 'foo', + type: MVTFieldType.STRING, + }, + { + name: 'food', + type: MVTFieldType.STRING, + }, + { + name: 'fooz', + type: MVTFieldType.NUMBER, + }, + ], + minSourceZoom: 4, + maxSourceZoom: 14, + includeFields: true, +}; + +test('should render with fields', async () => { + const component = shallow(); + expect(component).toMatchSnapshot(); +}); + +test('should render without fields', async () => { + const settings = { ...defaultSettings, includeFields: false }; + const component = shallow(); + expect(component).toMatchSnapshot(); +}); From 508b1c63fcfd7122d4dd60e6150b6094db715146 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Thu, 25 Jun 2020 15:12:34 -0400 Subject: [PATCH 37/56] remove unused import --- .../mvt_single_layer_source_settings.test.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.test.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.test.tsx index af8f54fc3b504..22436fbe5117d 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.test.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.test.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import { MVTFieldDescriptor } from '../../../../common/descriptor_types'; - jest.mock('../../../kibana_services', () => ({})); import React from 'react'; From 9634353cf92af8cfbb621eea1889eda6a03febef Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Thu, 25 Jun 2020 15:39:40 -0400 Subject: [PATCH 38/56] test stub for mvt layer fix optional param more checks --- .../tiled_vector_layer.test.ts | 64 +++++++++++++++++++ .../tiled_vector_layer/tiled_vector_layer.tsx | 4 +- 2 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.test.ts diff --git a/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.test.ts b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.test.ts new file mode 100644 index 0000000000000..f7eb41a0f4649 --- /dev/null +++ b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.test.ts @@ -0,0 +1,64 @@ +/* + * 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. + */ +jest.mock('ui/new_platform'); +jest.mock('../../../kibana_services', () => { + return { + getUiSettings() { + return { + get() { + return false; + }, + }; + }, + }; +}); + +import { MVTSingleLayerVectorSource } from '../../sources/mvt_single_layer_vector_source'; +import { + TiledSingleLayerVectorSourceDescriptor, + VectorLayerDescriptor, +} from '../../../../common/descriptor_types'; +import { SOURCE_TYPES } from '../../../../common/constants'; +import { TiledVectorLayer } from './tiled_vector_layer'; + +function createLayer( + layerOptions: Partial = {}, + sourceOptions: Partial = {} +): TiledVectorLayer { + const sourceDescriptor: TiledSingleLayerVectorSourceDescriptor = { + type: SOURCE_TYPES.MVT_SINGLE_LAYER, + urlTemplate: 'https://example.com/{x}/{y}/{z}.pbf', + layerName: 'foobar', + minSourceZoom: 4, + maxSourceZoom: 14, + fields: [], + tooltipProperties: [], + ...sourceOptions, + }; + const mvtSource = new MVTSingleLayerVectorSource(sourceDescriptor); + + const defaultLayerOptions = { + ...layerOptions, + sourceDescriptor, + }; + const layerDescriptor = TiledVectorLayer.createDescriptor(defaultLayerOptions); + return new TiledVectorLayer({ layerDescriptor, source: mvtSource }); +} + +describe('visiblity', () => { + it('should get minzoom from source', async () => { + const layer: TiledVectorLayer = createLayer({}, {}); + expect(layer.getMinZoom()).toEqual(4); + }); + it('should get maxzoom from default', async () => { + const layer: TiledVectorLayer = createLayer({}, {}); + expect(layer.getMaxZoom()).toEqual(24); + }); + it('should get maxzoom from layer options', async () => { + const layer: TiledVectorLayer = createLayer({ maxZoom: 10 }, {}); + expect(layer.getMaxZoom()).toEqual(10); + }); +}); diff --git a/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx index ffea1febe2e4e..4a929084791ca 100644 --- a/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx @@ -23,13 +23,13 @@ export class TiledVectorLayer extends VectorLayer { static createDescriptor( descriptor: Partial, - mapColors: string[] + mapColors?: string[] ): VectorLayerDescriptor { const layerDescriptor = super.createDescriptor(descriptor, mapColors); layerDescriptor.type = TiledVectorLayer.type; if (!layerDescriptor.style) { - const styleProperties = VectorStyle.createDefaultStyleProperties(mapColors); + const styleProperties = VectorStyle.createDefaultStyleProperties(mapColors ? mapColors : []); layerDescriptor.style = VectorStyle.createDescriptor(styleProperties); } From 94efbf64f6d4fc646160b630027b61e9a290e265 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Thu, 25 Jun 2020 15:56:49 -0400 Subject: [PATCH 39/56] add snapshot test more unit tests more unit tests ts fixes --- .../tiled_vector_layer.test.tsx.snap | 8 +++++ ...er.test.ts => tiled_vector_layer.test.tsx} | 32 +++++++++++++++++++ .../tiled_vector_layer/tiled_vector_layer.tsx | 18 +++-------- 3 files changed, 44 insertions(+), 14 deletions(-) create mode 100644 x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/__snapshots__/tiled_vector_layer.test.tsx.snap rename x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/{tiled_vector_layer.test.ts => tiled_vector_layer.test.tsx} (69%) diff --git a/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/__snapshots__/tiled_vector_layer.test.tsx.snap b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/__snapshots__/tiled_vector_layer.test.tsx.snap new file mode 100644 index 0000000000000..f0ae93601ce8a --- /dev/null +++ b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/__snapshots__/tiled_vector_layer.test.tsx.snap @@ -0,0 +1,8 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`icon should use vector icon 1`] = ` +
+`; diff --git a/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.test.ts b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.test.tsx similarity index 69% rename from x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.test.ts rename to x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.test.tsx index f7eb41a0f4649..331a2e9e1733f 100644 --- a/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.test.ts +++ b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.test.tsx @@ -16,6 +16,9 @@ jest.mock('../../../kibana_services', () => { }; }); +import { shallow } from 'enzyme'; + +import { Feature } from 'geojson'; import { MVTSingleLayerVectorSource } from '../../sources/mvt_single_layer_vector_source'; import { TiledSingleLayerVectorSourceDescriptor, @@ -62,3 +65,32 @@ describe('visiblity', () => { expect(layer.getMaxZoom()).toEqual(10); }); }); + +describe('icon', () => { + it('should use vector icon', async () => { + const layer: TiledVectorLayer = createLayer({}, {}); + + const iconAndTooltipContent = layer.getCustomIconAndTooltipContent(); + const component = shallow(iconAndTooltipContent.icon); + expect(component).toMatchSnapshot(); + }); +}); + +describe('getFeatureById', () => { + it('should echo properties with dummy geometry', async () => { + const layer: TiledVectorLayer = createLayer({}, {}); + + const properties = { + foo: 'bar', + }; + const feature = layer.getFeatureById(undefined, { mbProperties: properties }) as Feature; + + expect(feature.properties).toEqual(properties); + expect(feature.geometry).toEqual({ + type: 'Point', + coordinates: [0, 0], + }); + expect(feature.id).toEqual(undefined); + expect(feature.type).toEqual('Feature'); + }); +}); diff --git a/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx index 4a929084791ca..0ef1157e1e682 100644 --- a/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx @@ -202,25 +202,15 @@ export class TiledVectorLayer extends VectorLayer { id: string | number | undefined, meta: { mbProperties: GeoJsonProperties } ): Feature | null { - const geometry = this._source.getFeatureGeometry(id, meta.mbProperties); const properties = this._source.getFeatureProperties(id, meta.mbProperties); - if (geometry === null) { - return { - type: 'Feature', - properties, - id, - geometry: { - type: 'Point', - coordinates: [0, 0], - }, - }; - } - return { type: 'Feature', properties, - geometry, id, + geometry: { + type: 'Point', + coordinates: [0, 0], + }, }; } } From 501fd8909195647afdcef72ad1d316e22dce9f0a Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Thu, 25 Jun 2020 17:52:12 -0400 Subject: [PATCH 40/56] add data syncing unit test --- .../layers/__tests__/mock_sync_context.ts | 40 +++++++++ .../tiled_vector_layer.test.tsx | 87 ++++++++++++++++++- 2 files changed, 123 insertions(+), 4 deletions(-) create mode 100644 x-pack/plugins/maps/public/classes/layers/__tests__/mock_sync_context.ts diff --git a/x-pack/plugins/maps/public/classes/layers/__tests__/mock_sync_context.ts b/x-pack/plugins/maps/public/classes/layers/__tests__/mock_sync_context.ts new file mode 100644 index 0000000000000..8c4eb49d5040d --- /dev/null +++ b/x-pack/plugins/maps/public/classes/layers/__tests__/mock_sync_context.ts @@ -0,0 +1,40 @@ +/* + * 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 sinon from 'sinon'; +import { DataRequestContext } from '../../../actions'; +import { DataMeta, MapFilters } from '../../../../common/descriptor_types'; + +export class MockSyncContext implements DataRequestContext { + dataFilters: MapFilters; + isRequestStillActive: (dataId: string, requestToken: symbol) => boolean; + onLoadError: (dataId: string, requestToken: symbol, errorMessage: string) => void; + registerCancelCallback: (requestToken: symbol, callback: () => void) => void; + startLoading: (dataId: string, requestToken: symbol, meta: DataMeta) => void; + stopLoading: (dataId: string, requestToken: symbol, data: object, meta: DataMeta) => void; + updateSourceData: (newData: unknown) => void; + + constructor({ dataFilters }: { dataFilters: Partial }) { + const mapFilters: MapFilters = { + filters: [], + timeFilters: { + from: 'now', + to: '15m', + mode: 'relative', + }, + zoom: 0, + ...dataFilters, + }; + + this.dataFilters = mapFilters; + this.isRequestStillActive = sinon.spy(); + this.onLoadError = sinon.spy(); + this.registerCancelCallback = sinon.spy(); + this.startLoading = sinon.spy(); + this.stopLoading = sinon.spy(); + this.updateSourceData = sinon.spy(); + } +} diff --git a/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.test.tsx b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.test.tsx index 331a2e9e1733f..8bb1f4c0f12e8 100644 --- a/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.test.tsx +++ b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.test.tsx @@ -3,6 +3,9 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ +import { MockSyncContext } from '../__tests__/mock_sync_context'; +import sinon from 'sinon'; + jest.mock('ui/new_platform'); jest.mock('../../../kibana_services', () => { return { @@ -21,22 +24,27 @@ import { shallow } from 'enzyme'; import { Feature } from 'geojson'; import { MVTSingleLayerVectorSource } from '../../sources/mvt_single_layer_vector_source'; import { + DataRequestDescriptor, TiledSingleLayerVectorSourceDescriptor, VectorLayerDescriptor, } from '../../../../common/descriptor_types'; import { SOURCE_TYPES } from '../../../../common/constants'; import { TiledVectorLayer } from './tiled_vector_layer'; +const defaultConfig = { + urlTemplate: 'https://example.com/{x}/{y}/{z}.pbf', + layerName: 'foobar', + minSourceZoom: 4, + maxSourceZoom: 14, +}; + function createLayer( layerOptions: Partial = {}, sourceOptions: Partial = {} ): TiledVectorLayer { const sourceDescriptor: TiledSingleLayerVectorSourceDescriptor = { type: SOURCE_TYPES.MVT_SINGLE_LAYER, - urlTemplate: 'https://example.com/{x}/{y}/{z}.pbf', - layerName: 'foobar', - minSourceZoom: 4, - maxSourceZoom: 14, + ...defaultConfig, fields: [], tooltipProperties: [], ...sourceOptions, @@ -94,3 +102,74 @@ describe('getFeatureById', () => { expect(feature.type).toEqual('Feature'); }); }); + +describe('syncData', () => { + it('Should sync with source-params', async () => { + const layer: TiledVectorLayer = createLayer({}, {}); + + const syncContext = new Mock_sync_context({ dataFilters: {} }); + + await layer.syncData(syncContext); + // @ts-expect-error + sinon.assert.calledOnce(syncContext.startLoading); + // @ts-expect-error + sinon.assert.calledOnce(syncContext.stopLoading); + + // @ts-expect-error + const call = syncContext.stopLoading.getCall(0); + expect(call.args[2]).toEqual(defaultConfig); + }); + + it('Should not resync when no changes to source params', async () => { + const layer1: TiledVectorLayer = createLayer({}, {}); + const syncContext1 = new Mock_sync_context({ dataFilters: {} }); + + await layer1.syncData(syncContext1); + + const dataRequestDescriptor: DataRequestDescriptor = { + data: { ...defaultConfig }, + dataId: 'source', + }; + const layer2: TiledVectorLayer = createLayer( + { + __dataRequests: [dataRequestDescriptor], + }, + {} + ); + const syncContext2 = new Mock_sync_context({ dataFilters: {} }); + await layer2.syncData(syncContext2); + // @ts-expect-error + sinon.assert.notCalled(syncContext2.startLoading); + // @ts-expect-error + sinon.assert.notCalled(syncContext2.stopLoading); + }); + + it('Should resync when changes to source params', async () => { + const layer1: TiledVectorLayer = createLayer({}, {}); + const syncContext1 = new Mock_sync_context({ dataFilters: {} }); + + await layer1.syncData(syncContext1); + + const dataRequestDescriptor: DataRequestDescriptor = { + data: defaultConfig, + dataId: 'source', + }; + const layer2: TiledVectorLayer = createLayer( + { + __dataRequests: [dataRequestDescriptor], + }, + { layerName: 'barfoo' } + ); + const syncContext2 = new Mock_sync_context({ dataFilters: {} }); + await layer2.syncData(syncContext2); + + // @ts-expect-error + sinon.assert.calledOnce(syncContext2.startLoading); + // @ts-expect-error + sinon.assert.calledOnce(syncContext2.stopLoading); + + // @ts-expect-error + const call = syncContext2.stopLoading.getCall(0); + expect(call.args[2]).toEqual({ ...defaultConfig, layerName: 'barfoo' }); + }); +}); From 355f7eee784f23aabf0bbbbcd228d895f502976e Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Thu, 25 Jun 2020 18:01:12 -0400 Subject: [PATCH 41/56] fix autorefactor --- .../tiled_vector_layer/tiled_vector_layer.test.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.test.tsx b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.test.tsx index 8bb1f4c0f12e8..1849dca8c9bc7 100644 --- a/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.test.tsx +++ b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.test.tsx @@ -107,7 +107,7 @@ describe('syncData', () => { it('Should sync with source-params', async () => { const layer: TiledVectorLayer = createLayer({}, {}); - const syncContext = new Mock_sync_context({ dataFilters: {} }); + const syncContext = new MockSyncContext({ dataFilters: {} }); await layer.syncData(syncContext); // @ts-expect-error @@ -122,7 +122,7 @@ describe('syncData', () => { it('Should not resync when no changes to source params', async () => { const layer1: TiledVectorLayer = createLayer({}, {}); - const syncContext1 = new Mock_sync_context({ dataFilters: {} }); + const syncContext1 = new MockSyncContext({ dataFilters: {} }); await layer1.syncData(syncContext1); @@ -136,7 +136,7 @@ describe('syncData', () => { }, {} ); - const syncContext2 = new Mock_sync_context({ dataFilters: {} }); + const syncContext2 = new MockSyncContext({ dataFilters: {} }); await layer2.syncData(syncContext2); // @ts-expect-error sinon.assert.notCalled(syncContext2.startLoading); @@ -146,7 +146,7 @@ describe('syncData', () => { it('Should resync when changes to source params', async () => { const layer1: TiledVectorLayer = createLayer({}, {}); - const syncContext1 = new Mock_sync_context({ dataFilters: {} }); + const syncContext1 = new MockSyncContext({ dataFilters: {} }); await layer1.syncData(syncContext1); @@ -160,7 +160,7 @@ describe('syncData', () => { }, { layerName: 'barfoo' } ); - const syncContext2 = new Mock_sync_context({ dataFilters: {} }); + const syncContext2 = new MockSyncContext({ dataFilters: {} }); await layer2.syncData(syncContext2); // @ts-expect-error From 229bf3b22a2c70f436807a43340ce6d6905d83c4 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Fri, 26 Jun 2020 10:51:14 -0400 Subject: [PATCH 42/56] fix merge and replace snapshots --- ...e_layer_vector_source_editor.test.tsx.snap | 2 +- .../update_source_editor.test.tsx.snap | 56 ------------------- .../mvt_single_layer_vector_source.tsx | 13 +++-- 3 files changed, 10 insertions(+), 61 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_single_layer_vector_source_editor.test.tsx.snap b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_single_layer_vector_source_editor.test.tsx.snap index 525a99e030204..932aa4d6ab128 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_single_layer_vector_source_editor.test.tsx.snap +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_single_layer_vector_source_editor.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`should render source creation editor 1`] = ` +exports[`should render source creation editor (fields should _not_ be included) 1`] = ` `; - -exports[`should render update source editor 1`] = ` - - - -
- -
-
- - -
- - - -
- -
-
- - -
- -
-`; diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx index 5d96254487322..b68ebdf5f5ee3 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx @@ -10,8 +10,13 @@ import React from 'react'; import { GeoJsonProperties, Geometry } from 'geojson'; import { AbstractSource, ImmutableSourceProperty, SourceEditorArgs } from '../source'; import { BoundsFilters, GeoJsonWithMeta, ITiledSingleLayerVectorSource } from '../vector_source'; -import { FIELD_ORIGIN, MAX_ZOOM, MIN_ZOOM, SOURCE_TYPES } from '../../../../common/constants'; -import { VECTOR_SHAPE_TYPES } from '../vector_feature_types'; +import { + FIELD_ORIGIN, + MAX_ZOOM, + MIN_ZOOM, + SOURCE_TYPES, + VECTOR_SHAPE_TYPE, +} from '../../../../common/constants'; import { registerSource } from '../source_registry'; import { getDataSourceLabel, getUrlLabel } from '../../../../common/i18n_getters'; import { @@ -179,8 +184,8 @@ export class MVTSingleLayerVectorSource extends AbstractSource }; } - async getSupportedShapeTypes(): Promise { - return [VECTOR_SHAPE_TYPES.POINT, VECTOR_SHAPE_TYPES.LINE, VECTOR_SHAPE_TYPES.POLYGON]; + async getSupportedShapeTypes(): Promise { + return [VECTOR_SHAPE_TYPE.POINT, VECTOR_SHAPE_TYPE.LINE, VECTOR_SHAPE_TYPE.POLYGON]; } canFormatFeatureProperties() { From 80cf10960cab4f396c4a1d07f7a27d5b8033e7be Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Fri, 26 Jun 2020 13:19:30 -0400 Subject: [PATCH 43/56] field editor changes --- .../mvt_field_config_editor.tsx | 89 +++++++++++++++---- .../mvt_single_layer_source_settings.tsx | 18 +++- .../update_source_editor.tsx | 10 +-- 3 files changed, 94 insertions(+), 23 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx index 6d02870cb87aa..1285e784bc3cf 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx @@ -16,6 +16,7 @@ import { EuiSpacer, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import _ from 'lodash'; import { MVTFieldDescriptor } from '../../../../common/descriptor_types'; import { FieldIcon } from '../../../../../../../src/plugins/kibana_react/public'; import { MVTFieldType } from '../../../../common/constants'; @@ -26,7 +27,11 @@ const FIELD_TYPE_OPTIONS = [ inputDisplay: ( - String + + {i18n.translate('xpack.maps.mvtSource.stringFieldLabel', { + defaultMessage: 'string', + })} + ), }, @@ -35,7 +40,11 @@ const FIELD_TYPE_OPTIONS = [ inputDisplay: ( - Number + + {i18n.translate('xpack.maps.mvtSource.numberFieldLabel', { + defaultMessage: 'number', + })} + ), }, @@ -47,32 +56,66 @@ export interface Props { } // eslint-disable-next-line @typescript-eslint/no-empty-interface -interface State {} +interface State { + previousFields: MVTFieldDescriptor[]; + currentFields: MVTFieldDescriptor[]; +} export class MVTFieldConfigEditor extends Component { - state = {}; + state = { + currentFields: [], + previousFields: [], + }; + + static getDerivedStateFromProps(nextProps: Props, prevState: State) { + if (_.isEqual(nextProps.fields, prevState.previousFields)) { + return null; + } + return { + currentFields: nextProps.fields, + previousFields: nextProps.fields, + }; + } + + _notifyChange = () => { + const invalid = this.state.currentFields.some((field) => { + return field.name === ''; + }); + + if (!invalid) { + this.props.onChange(this.state.currentFields); + } + }; + + _fieldChange(newFields) { + this.setState( + { + currentFields: newFields, + }, + this._notifyChange + ); + } _removeField(index: number) { - const newFields = this.props.fields.slice(); + const newFields = this.state.currentFields.slice(); newFields.splice(index, 1); - - this.props.onChange(newFields); + this._fieldChange(newFields); } _addField = () => { - const newFields = this.props.fields.slice(); + const newFields = this.state.currentFields.slice(); newFields.push({ type: MVTFieldType.STRING, - name: 'Foobar', + name: '', }); - this.props.onChange(newFields); + this._fieldChange(newFields); }; _renderFieldTypeDropDown(mvtFieldConfig: MVTFieldDescriptor, index: number) { const onChange = (type: MVTFieldType) => { - const newFields = this.props.fields.slice(); + const newFields = this.state.currentFields.slice(); newFields[index].type = type; - this.props.onChange(newFields); + this._fieldChange(newFields); }; return ( @@ -87,17 +130,31 @@ export class MVTFieldConfigEditor extends Component { _renderFieldNameInput(mvtFieldConfig: MVTFieldDescriptor, index: number) { const onChange = (e: ChangeEvent) => { const name = e.target.value; - const newFields = this.props.fields.slice(); + const newFields = this.state.currentFields.slice(); newFields[index].name = name; - this.props.onChange(newFields); + this._fieldChange(newFields); }; + + const isInvalid = mvtFieldConfig.name === ''; + const placeholderText = isInvalid + ? i18n.translate('xpack.maps.mvtSource.fieldPlaceholderText', { + defaultMessage: 'Field name', + }) + : ''; + return ( - + ); } _renderFieldConfig() { - return this.props.fields.map((mvtFieldConfig: MVTFieldDescriptor, index: number) => { + return this.state.currentFields.map((mvtFieldConfig: MVTFieldDescriptor, index: number) => { return ( {this._renderFieldNameInput(mvtFieldConfig, index)} diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx index 001f2ccff8e1a..964a213842dd4 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx @@ -59,6 +59,9 @@ export class MVTSingleLayerSourceSettings extends Component { }, 200); _handleLayerNameInputChange = (e: ChangeEvent) => { + if (e.target.value === this.state.currentSettings.layerName) { + return; + } const currentSettings = { layerName: e.target.value, minSourceZoom: this.state.currentSettings.minSourceZoom, @@ -70,6 +73,9 @@ export class MVTSingleLayerSourceSettings extends Component { }; _handleFieldChange = (fields: MVTFieldDescriptor[]) => { + if (_.isEqual(this.state.currentSettings.fields, fields)) { + return; + } const currentSettings = { layerName: this.state.currentSettings.layerName, minSourceZoom: this.state.currentSettings.minSourceZoom, @@ -80,11 +86,19 @@ export class MVTSingleLayerSourceSettings extends Component { }; _handleZoomRangeChange = (e: Value) => { + const minZoom = parseInt(e[0] as string, 10); + const maxZoom = parseInt(e[1] as string, 10); + if ( + this.state.currentSettings.fields.minSourceZoom === minZoom && + this.state.currentSettings.fields.maxSourceZoom === maxZoom + ) { + return; + } const currentSettings = { layerName: this.state.currentSettings.layerName, fields: this.state.currentSettings.fields, - minSourceZoom: parseInt(e[0] as string, 10), - maxSourceZoom: parseInt(e[1] as string, 10), + minSourceZoom: minZoom, + maxSourceZoom: maxZoom, }; this.setState({ currentSettings }, this._handleChange); }; diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx index d052bd398be30..790392e17ca48 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx @@ -53,12 +53,12 @@ export class UpdateSourceEditor extends Component { this.props.onChange({ propName: 'tooltipProperties', value: propertyNames }); }; - _handleChange = (state: MVTSettings) => { + _handleChange = (settings: MVTSettings) => { this.props.onChange( - { propName: 'layerName', value: state.layerName }, - { propName: 'fields', value: state.fields }, - { propName: 'minSourceZoom', value: state.minSourceZoom }, - { propName: 'maxSourceZoom', value: state.maxSourceZoom } + { propName: 'layerName', value: settings.layerName }, + { propName: 'fields', value: settings.fields }, + { propName: 'minSourceZoom', value: settings.minSourceZoom }, + { propName: 'maxSourceZoom', value: settings.maxSourceZoom } ); }; From bf9d298d61460f85ed5ff576da6cd04275e27ef2 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Fri, 26 Jun 2020 14:17:31 -0400 Subject: [PATCH 44/56] field editor changes --- .../mvt_field_config_editor.test.tsx.snap | 18 ++++++---- .../mvt_field_config_editor.tsx | 4 +-- .../mvt_single_layer_source_settings.tsx | 1 + .../mvt_single_layer_vector_source.tsx | 4 +++ .../update_source_editor.tsx | 34 ++----------------- 5 files changed, 22 insertions(+), 39 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_field_config_editor.test.tsx.snap b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_field_config_editor.test.tsx.snap index a959c4897e83e..4c0608a277b6d 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_field_config_editor.test.tsx.snap +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_field_config_editor.test.tsx.snap @@ -9,7 +9,9 @@ exports[`should render field editor 1`] = ` @@ -29,7 +31,7 @@ exports[`should render field editor 1`] = ` type="string" /> - String + string , "value": "String", @@ -40,7 +42,7 @@ exports[`should render field editor 1`] = ` type="number" /> - Number + number , "value": "Number", @@ -67,7 +69,9 @@ exports[`should render field editor 1`] = ` @@ -87,7 +91,7 @@ exports[`should render field editor 1`] = ` type="string" /> - String + string , "value": "String", @@ -98,7 +102,7 @@ exports[`should render field editor 1`] = ` type="number" /> - Number + number , "value": "Number", @@ -125,7 +129,9 @@ exports[`should render field editor 1`] = ` @@ -145,7 +151,7 @@ exports[`should render field editor 1`] = ` type="string" /> - String + string , "value": "String", @@ -156,7 +162,7 @@ exports[`should render field editor 1`] = ` type="number" /> - Number + number , "value": "Number", diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx index 1285e784bc3cf..c5573323480bf 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx @@ -77,7 +77,7 @@ export class MVTFieldConfigEditor extends Component { }; } - _notifyChange = () => { + _notifyChange = _.debounce(() => { const invalid = this.state.currentFields.some((field) => { return field.name === ''; }); @@ -85,7 +85,7 @@ export class MVTFieldConfigEditor extends Component { if (!invalid) { this.props.onChange(this.state.currentFields); } - }; + }); _fieldChange(newFields) { this.setState( diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx index 964a213842dd4..14bbe5f73b78f 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx @@ -94,6 +94,7 @@ export class MVTSingleLayerSourceSettings extends Component { ) { return; } + const currentSettings = { layerName: this.state.currentSettings.layerName, fields: this.state.currentSettings.fields, diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx index b68ebdf5f5ee3..ee59e87683bcf 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx @@ -93,6 +93,10 @@ export class MVTSingleLayerVectorSource extends AbstractSource }); } + getFieldDescriptors(): MVTFieldDescriptor[] { + return this._descriptor.fields; + } + getFieldByName(fieldName: string): MVTField | null { try { return this.createField({ fieldName }); diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx index 790392e17ca48..848fa20e07c47 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx @@ -22,33 +22,9 @@ export interface Props { } // eslint-disable-next-line @typescript-eslint/no-empty-interface -interface State { - fields: null | MVTField[]; -} +interface State {} export class UpdateSourceEditor extends Component { - state = { - fields: null, - }; - - private _isMounted: boolean = false; - - componentDidMount() { - this._isMounted = true; - this._loadFields(); - } - - componentWillUnmount() { - this._isMounted = false; - } - - async _loadFields() { - const fields: MVTField[] = (await this.props.source.getFields()) as MVTField[]; - if (this._isMounted) { - this.setState({ fields }); - } - } - _onTooltipPropertiesSelect = (propertyNames: string[]) => { this.props.onChange({ propName: 'tooltipProperties', value: propertyNames }); }; @@ -63,10 +39,6 @@ export class UpdateSourceEditor extends Component { }; _renderSourceSettingsCard() { - const fields: MVTFieldDescriptor[] = (this.state.fields || []).map((field: MVTField) => { - return field.getMVTFieldDescriptor(); - }); - return ( @@ -82,7 +54,7 @@ export class UpdateSourceEditor extends Component { { From baaa565f16f7997d8012a5e01a4b0c3b57cee5e5 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Fri, 26 Jun 2020 14:29:53 -0400 Subject: [PATCH 45/56] ts fixes --- .../mvt_field_config_editor.tsx | 10 +++++----- .../mvt_single_layer_source_settings.tsx | 4 ++-- .../mvt_single_layer_vector_source.tsx | 20 +++++++++---------- .../update_source_editor.tsx | 8 +++++--- 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx index c5573323480bf..98dff40f09885 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx @@ -62,7 +62,7 @@ interface State { } export class MVTFieldConfigEditor extends Component { - state = { + state: State = { currentFields: [], previousFields: [], }; @@ -78,7 +78,7 @@ export class MVTFieldConfigEditor extends Component { } _notifyChange = _.debounce(() => { - const invalid = this.state.currentFields.some((field) => { + const invalid = this.state.currentFields.some((field: MVTFieldDescriptor) => { return field.name === ''; }); @@ -87,7 +87,7 @@ export class MVTFieldConfigEditor extends Component { } }); - _fieldChange(newFields) { + _fieldChange(newFields: MVTFieldDescriptor[]) { this.setState( { currentFields: newFields, @@ -97,13 +97,13 @@ export class MVTFieldConfigEditor extends Component { } _removeField(index: number) { - const newFields = this.state.currentFields.slice(); + const newFields: MVTFieldDescriptor[] = this.state.currentFields.slice(); newFields.splice(index, 1); this._fieldChange(newFields); } _addField = () => { - const newFields = this.state.currentFields.slice(); + const newFields: MVTFieldDescriptor[] = this.state.currentFields.slice(); newFields.push({ type: MVTFieldType.STRING, name: '', diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx index 14bbe5f73b78f..22d7258204774 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx @@ -89,8 +89,8 @@ export class MVTSingleLayerSourceSettings extends Component { const minZoom = parseInt(e[0] as string, 10); const maxZoom = parseInt(e[1] as string, 10); if ( - this.state.currentSettings.fields.minSourceZoom === minZoom && - this.state.currentSettings.fields.maxSourceZoom === maxZoom + this.state.currentSettings.minSourceZoom === minZoom && + this.state.currentSettings.maxSourceZoom === maxZoom ) { return; } diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx index ee59e87683bcf..d933054939625 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx @@ -93,8 +93,15 @@ export class MVTSingleLayerVectorSource extends AbstractSource }); } - getFieldDescriptors(): MVTFieldDescriptor[] { - return this._descriptor.fields; + getMVTFields(): MVTField[] { + return this._descriptor.fields.map((field: MVTFieldDescriptor) => { + return new MVTField({ + fieldName: field.name, + type: field.type, + source: this, + origin: FIELD_ORIGIN.SOURCE, + }); + }); } getFieldByName(fieldName: string): MVTField | null { @@ -130,14 +137,7 @@ export class MVTSingleLayerVectorSource extends AbstractSource } async getFields(): Promise { - return this._descriptor.fields.map((field: MVTFieldDescriptor) => { - return new MVTField({ - fieldName: field.name, - type: field.type, - source: this, - origin: FIELD_ORIGIN.SOURCE, - }); - }); + return this.getMVTFields(); } getLayerName(): string { diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx index 848fa20e07c47..217c4c04b6f74 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx @@ -12,7 +12,6 @@ import { TooltipSelector } from '../../../components/tooltip_selector'; import { MVTField } from '../../fields/mvt_field'; import { MVTSingleLayerVectorSource } from './mvt_single_layer_vector_source'; import { MVTSettings, MVTSingleLayerSourceSettings } from './mvt_single_layer_source_settings'; -import { MVTFieldDescriptor } from '../../../../common/descriptor_types'; import { OnSourceChangeArgs } from '../../../connected_components/layer_panel/view'; export interface Props { @@ -39,6 +38,9 @@ export class UpdateSourceEditor extends Component { }; _renderSourceSettingsCard() { + const fieldDescriptors = this.props.source.getMVTFields().map((field: MVTField) => { + return field.getMVTFieldDescriptor(); + }); return ( @@ -54,7 +56,7 @@ export class UpdateSourceEditor extends Component { { From 9c7de48cc3bf7c0ab04012f7901a692a151d3bbe Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Fri, 26 Jun 2020 14:38:17 -0400 Subject: [PATCH 46/56] update snapshots --- .../update_source_editor.tsx | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx index 217c4c04b6f74..ce28ea6ecba89 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx @@ -13,6 +13,7 @@ import { MVTField } from '../../fields/mvt_field'; import { MVTSingleLayerVectorSource } from './mvt_single_layer_vector_source'; import { MVTSettings, MVTSingleLayerSourceSettings } from './mvt_single_layer_source_settings'; import { OnSourceChangeArgs } from '../../../connected_components/layer_panel/view'; +import { MVTFieldDescriptor } from '../../../../common/descriptor_types'; export interface Props { tooltipFields: MVTField[]; @@ -29,18 +30,28 @@ export class UpdateSourceEditor extends Component { }; _handleChange = (settings: MVTSettings) => { - this.props.onChange( - { propName: 'layerName', value: settings.layerName }, - { propName: 'fields', value: settings.fields }, - { propName: 'minSourceZoom', value: settings.minSourceZoom }, - { propName: 'maxSourceZoom', value: settings.maxSourceZoom } - ); + const changes: OnSourceChangeArgs = []; + if (settings.layerName !== this.props.layerName) { + changes.push({ propName: 'layerName', value: settings.layerName }); + } + if (settings.minSourceZoom !== this.props.minSourceZoom) { + changes.push({ propName: 'minSourceZoom', value: settings.minSourceZoom }); + } + if (settings.maxSourceZoom !== this.props.maxSourceZoom) { + changes.push({ propName: 'maxSourceZoom', value: settings.maxSourceZoom }); + } + if (!_.isEqual(settings.fields !== this.props.fields)) { + changes.push({ propName: 'fields', value: settings.fields }); + } + this.props.onChange(...changes); }; _renderSourceSettingsCard() { - const fieldDescriptors = this.props.source.getMVTFields().map((field: MVTField) => { - return field.getMVTFieldDescriptor(); - }); + const fieldDescriptors: MVTFieldDescriptor[] = this.props.source + .getMVTFields() + .map((field: MVTField) => { + return field.getMVTFieldDescriptor(); + }); return ( From d0613e983d3282ed858c4da48a2a5a25e5215958 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Fri, 26 Jun 2020 15:27:42 -0400 Subject: [PATCH 47/56] fix things --- .../mvt_field_config_editor.tsx | 15 +++- .../mvt_single_layer_source_settings.tsx | 90 ++++++++++--------- .../update_source_editor.tsx | 2 +- 3 files changed, 61 insertions(+), 46 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx index 98dff40f09885..04eccae14928c 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx @@ -71,9 +71,10 @@ export class MVTFieldConfigEditor extends Component { if (_.isEqual(nextProps.fields, prevState.previousFields)) { return null; } + const clonedFields = _.cloneDeep(nextProps.fields); return { - currentFields: nextProps.fields, - previousFields: nextProps.fields, + currentFields: clonedFields, + previousFields: clonedFields, }; } @@ -114,7 +115,10 @@ export class MVTFieldConfigEditor extends Component { _renderFieldTypeDropDown(mvtFieldConfig: MVTFieldDescriptor, index: number) { const onChange = (type: MVTFieldType) => { const newFields = this.state.currentFields.slice(); - newFields[index].type = type; + newFields[index] = { + type, + name: newFields[index].name, + }; this._fieldChange(newFields); }; @@ -131,7 +135,10 @@ export class MVTFieldConfigEditor extends Component { const onChange = (e: ChangeEvent) => { const name = e.target.value; const newFields = this.state.currentFields.slice(); - newFields[index].name = name; + newFields[index] = { + name, + type: newFields[index].type, + }; this._fieldChange(newFields); }; diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx index 22d7258204774..c6213c31463b9 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx @@ -22,8 +22,14 @@ export type MVTSettings = { }; export interface State { - currentSettings: MVTSettings; - prevSettings: MVTSettings; + currentLayerName: 'string'; + currentMinSourceZoom: number; + currentMaxSourceZoom: number; + currentFields: MVTFieldDescriptor[]; + previousLayerName: 'string'; + previousMinSourceZoom: number; + previousMaxSourceZoom: number; + previousFields: MVTFieldDescriptor[]; } export interface Props { @@ -44,64 +50,69 @@ export class MVTSingleLayerSourceSettings extends Component { maxSourceZoom: nextProps.maxSourceZoom, }; - if (prevState && _.isEqual(newSettings, prevState.prevSettings)) { + const previous = prevState + ? { + layerName: prevState.previousLayerName, + fields: prevState.previousFields, + minSourceZoom: prevState.previousMinSourceZoom, + maxSourceZoom: prevState.previousMaxSourceZoom, + } + : null; + + if (_.isEqual(previous, newSettings)) { return null; } + const clonedFields = _.cloneDeep(nextProps.fields); return { - prevSettings: newSettings, - currentSettings: newSettings, + currentLayerName: nextProps.layerName, + currentMinSourceZoom: nextProps.minSourceZoom, + currentMaxSourceZoom: nextProps.maxSourceZoom, + currentFields: clonedFields, + previousLayerName: nextProps.layerName, + previousMinSourceZoom: nextProps.minSourceZoom, + previousMaxSourceZoom: nextProps.maxSourceZoom, + previousFields: clonedFields, }; } _handleChange = _.debounce(() => { - this.props.handleChange(this.state.currentSettings); + this.props.handleChange({ + layerName: this.state.currentLayerName, + minSourceZoom: this.state.currentMinSourceZoom, + maxSourceZoom: this.state.currentMaxSourceZoom, + fields: this.state.currentFields, + }); }, 200); _handleLayerNameInputChange = (e: ChangeEvent) => { - if (e.target.value === this.state.currentSettings.layerName) { + const layerName = e.target.value; + if (layerName === this.state.currentLayerName) { return; } - const currentSettings = { - layerName: e.target.value, - minSourceZoom: this.state.currentSettings.minSourceZoom, - maxSourceZoom: this.state.currentSettings.maxSourceZoom, - fields: this.state.currentSettings.fields, - }; - - this.setState({ currentSettings }, this._handleChange); + this.setState({ currentLayerName: e.targetValue }, this._handleChange); }; _handleFieldChange = (fields: MVTFieldDescriptor[]) => { - if (_.isEqual(this.state.currentSettings.fields, fields)) { + if (_.isEqual(this.state.currentFields, fields)) { return; } - const currentSettings = { - layerName: this.state.currentSettings.layerName, - minSourceZoom: this.state.currentSettings.minSourceZoom, - maxSourceZoom: this.state.currentSettings.maxSourceZoom, - fields, - }; - this.setState({ currentSettings }, this._handleChange); + this.setState({ currentFields: fields }, this._handleChange); }; _handleZoomRangeChange = (e: Value) => { - const minZoom = parseInt(e[0] as string, 10); - const maxZoom = parseInt(e[1] as string, 10); + const minSourceZoom = parseInt(e[0] as string, 10); + const maxSourceZoom = parseInt(e[1] as string, 10); if ( - this.state.currentSettings.minSourceZoom === minZoom && - this.state.currentSettings.maxSourceZoom === maxZoom + this.state.currentMinSourceZoom === minSourceZoom && + this.state.currentMaxSourceZoom === maxSourceZoom ) { return; } - - const currentSettings = { - layerName: this.state.currentSettings.layerName, - fields: this.state.currentSettings.fields, - minSourceZoom: minZoom, - maxSourceZoom: maxZoom, - }; - this.setState({ currentSettings }, this._handleChange); + this.setState( + { currentMaxSourceZoom: minSourceZoom, currentMaxSourceZoom: maxSourceZoom }, + this._handleChange + ); }; render() { @@ -112,7 +123,7 @@ export class MVTSingleLayerSourceSettings extends Component { })} > @@ -129,7 +140,7 @@ export class MVTSingleLayerSourceSettings extends Component { )} > @@ -146,10 +157,7 @@ export class MVTSingleLayerSourceSettings extends Component { formRowDisplay="columnCompressed" min={MIN_ZOOM} max={MAX_ZOOM} - value={[ - this.state.currentSettings.minSourceZoom, - this.state.currentSettings.maxSourceZoom, - ]} + value={[this.state.currentMinSourceZoom, this.state.currentMaxSourceZoom]} showInput="inputWithPopover" showRange showLabels diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx index ce28ea6ecba89..26c31d7b09f0c 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx @@ -40,7 +40,7 @@ export class UpdateSourceEditor extends Component { if (settings.maxSourceZoom !== this.props.maxSourceZoom) { changes.push({ propName: 'maxSourceZoom', value: settings.maxSourceZoom }); } - if (!_.isEqual(settings.fields !== this.props.fields)) { + if (!_.isEqual(settings.fields, this.props.fields)) { changes.push({ propName: 'fields', value: settings.fields }); } this.props.onChange(...changes); From 574a29e507a555d11acb2d9bcb8c393c94274ca7 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Fri, 26 Jun 2020 16:13:31 -0400 Subject: [PATCH 48/56] fix names --- .../mvt_single_layer_source_settings.tsx | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx index c6213c31463b9..f244109c4ab15 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx @@ -42,6 +42,17 @@ export interface Props { } export class MVTSingleLayerSourceSettings extends Component { + state = { + currentLayerName: '', + currentMinSourceZoom: MIN_ZOOM, + currentMaxSourceZoom: MAX_ZOOM, + currentFields: [], + previousLayerName: '', + previousMinSourceZoom: MIN_ZOOM, + previousMaxSourceZoom: MAX_ZOOM, + previousFields: [], + }; + static getDerivedStateFromProps(nextProps: Props, prevState: State) { const newSettings = { layerName: nextProps.layerName, @@ -90,7 +101,7 @@ export class MVTSingleLayerSourceSettings extends Component { if (layerName === this.state.currentLayerName) { return; } - this.setState({ currentLayerName: e.targetValue }, this._handleChange); + this.setState({ currentLayerName: layerName }, this._handleChange); }; _handleFieldChange = (fields: MVTFieldDescriptor[]) => { @@ -110,7 +121,7 @@ export class MVTSingleLayerSourceSettings extends Component { return; } this.setState( - { currentMaxSourceZoom: minSourceZoom, currentMaxSourceZoom: maxSourceZoom }, + { currentMinSourceZoom: minSourceZoom, currentMaxSourceZoom: maxSourceZoom }, this._handleChange ); }; From 94024fa31235d383888be868f7417195a3e367c1 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Fri, 26 Jun 2020 17:37:43 -0400 Subject: [PATCH 49/56] fix tooltip --- .../mvt_single_layer_vector_source.test.tsx | 25 +++++++++++++++++++ .../mvt_single_layer_vector_source.tsx | 14 ++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.test.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.test.tsx index 8b6b9c5c5c1cf..4a31f940d793c 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.test.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.test.tsx @@ -29,6 +29,31 @@ describe('getUrlTemplateWithMeta', () => { }); }); +describe('canFormatFeatureProperties', () => { + it('false if no tooltips', async () => { + const source = new MVTSingleLayerVectorSource(descriptor); + expect(source.canFormatFeatureProperties()).toEqual(false); + }); + it('true if at least one matching tooltip', async () => { + const descriptorWithTooltips = { + ...descriptor, + fields: [{ name: 'foobar', type: MVTFieldType.STRING }], + tooltipProperties: ['foo', 'foobar', 'bar'], + }; + const source = new MVTSingleLayerVectorSource(descriptorWithTooltips); + expect(source.canFormatFeatureProperties()).toEqual(true); + }); + it('false if no matching tooltip', async () => { + const descriptorWithTooltips = { + ...descriptor, + fields: [{ name: 'foobar', type: MVTFieldType.STRING }], + tooltipProperties: ['foo', 'bar'], + }; + const source = new MVTSingleLayerVectorSource(descriptorWithTooltips); + expect(source.canFormatFeatureProperties()).toEqual(false); + }); +}); + describe('filterAndFormatPropertiesToHtml', () => { const descriptorWithFields = { ...descriptor, diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx index d933054939625..c936024808676 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx @@ -193,7 +193,19 @@ export class MVTSingleLayerVectorSource extends AbstractSource } canFormatFeatureProperties() { - return true; + if (!this._tooltipFields.length) { + return false; + } + + for (let i = 0; i < this._tooltipFields.length; i++) { + const tooltip: MVTField = this._tooltipFields[i]; + for (let j = 0; j < this._descriptor.fields.length; j++) { + if (tooltip.getName() === this._descriptor.fields[j].name) { + return true; + } + } + } + return false; } getMinZoom() { From 9633a736010a59a91b2389285687a227f157e76d Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Fri, 26 Jun 2020 18:12:42 -0400 Subject: [PATCH 50/56] add more error handling --- .../mvt_field_config_editor.test.tsx.snap | 392 ++++++++++++++++++ .../mvt_field_config_editor.test.tsx | 40 ++ .../mvt_field_config_editor.tsx | 10 +- 3 files changed, 441 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_field_config_editor.test.tsx.snap b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_field_config_editor.test.tsx.snap index 4c0608a277b6d..2f50f4fd59370 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_field_config_editor.test.tsx.snap +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_field_config_editor.test.tsx.snap @@ -1,5 +1,397 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`should render error for dupes 1`] = ` + + + + + + + + + + string + + , + "value": "String", + }, + Object { + "inputDisplay": + + + number + + , + "value": "Number", + }, + ] + } + valueOfSelected="String" + /> + + + + + + + + + + + + + + string + + , + "value": "String", + }, + Object { + "inputDisplay": + + + number + + , + "value": "Number", + }, + ] + } + valueOfSelected="String" + /> + + + + + + + + + + + + + + string + + , + "value": "String", + }, + Object { + "inputDisplay": + + + number + + , + "value": "Number", + }, + ] + } + valueOfSelected="Number" + /> + + + + + + + + Add field + + +`; + +exports[`should render error for empty name 1`] = ` + + + + + + + + + + string + + , + "value": "String", + }, + Object { + "inputDisplay": + + + number + + , + "value": "Number", + }, + ] + } + valueOfSelected="String" + /> + + + + + + + + + + + + + + string + + , + "value": "String", + }, + Object { + "inputDisplay": + + + number + + , + "value": "Number", + }, + ] + } + valueOfSelected="String" + /> + + + + + + + + + + + + + + string + + , + "value": "String", + }, + Object { + "inputDisplay": + + + number + + , + "value": "Number", + }, + ] + } + valueOfSelected="Number" + /> + + + + + + + + Add field + + +`; + exports[`should render field editor 1`] = ` { expect(component).toMatchSnapshot(); }); + +test('should render error for empty name', async () => { + const fields = [ + { + name: 'foo', + type: MVTFieldType.STRING, + }, + { + name: '', + type: MVTFieldType.STRING, + }, + { + name: 'fooz', + type: MVTFieldType.NUMBER, + }, + ]; + const component = shallow( {}} />); + + expect(component).toMatchSnapshot(); +}); + +test('should render error for dupes', async () => { + const fields = [ + { + name: 'foo', + type: MVTFieldType.STRING, + }, + { + name: 'bar', + type: MVTFieldType.STRING, + }, + { + name: 'foo', + type: MVTFieldType.NUMBER, + }, + ]; + const component = shallow( {}} />); + + expect(component).toMatchSnapshot(); +}); diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx index 04eccae14928c..084f349b17426 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx @@ -142,7 +142,15 @@ export class MVTFieldConfigEditor extends Component { this._fieldChange(newFields); }; - const isInvalid = mvtFieldConfig.name === ''; + const emptyName = mvtFieldConfig.name === ''; + let hasDupes = false; + for (let i = 0; i < this.state.currentFields.length; i++) { + if (i !== index && mvtFieldConfig.name === this.state.currentFields[i].name) { + hasDupes = true; + break; + } + } + const isInvalid = emptyName || hasDupes; const placeholderText = isInvalid ? i18n.translate('xpack.maps.mvtSource.fieldPlaceholderText', { defaultMessage: 'Field name', From cef7d8d9e0fdf917dd6e85d1ca7e01c2fb1c4755 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Fri, 26 Jun 2020 18:40:41 -0400 Subject: [PATCH 51/56] improve copy --- .../mvt_field_config_editor.test.tsx.snap | 33 +++++++++---------- ...single_layer_source_settings.test.tsx.snap | 5 +++ ...e_layer_vector_source_editor.test.tsx.snap | 2 ++ .../layer_wizard.tsx | 2 +- .../mvt_field_config_editor.tsx | 10 +++--- .../mvt_single_layer_source_settings.tsx | 20 +++++++++++ .../mvt_single_layer_vector_source.tsx | 2 +- .../mvt_single_layer_vector_source_editor.tsx | 15 ++++++++- 8 files changed, 64 insertions(+), 25 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_field_config_editor.test.tsx.snap b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_field_config_editor.test.tsx.snap index 2f50f4fd59370..17772da5a492d 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_field_config_editor.test.tsx.snap +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_field_config_editor.test.tsx.snap @@ -185,14 +185,13 @@ exports[`should render error for dupes 1`] = ` - - Add field - + Add + `; @@ -381,14 +380,13 @@ exports[`should render error for empty name 1`] = ` - - Add field - + Add + `; @@ -577,13 +575,12 @@ exports[`should render field editor 1`] = ` - - Add field - + Add + `; diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_single_layer_source_settings.test.tsx.snap b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_single_layer_source_settings.test.tsx.snap index afe1c72a0d536..142756ba907b7 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_single_layer_source_settings.test.tsx.snap +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_single_layer_source_settings.test.tsx.snap @@ -8,6 +8,7 @@ exports[`should render with fields 1`] = ` fullWidth={false} hasChildLabel={true} hasEmptyLabelSpace={false} + helpText="Name of the target data layer in the tile" label="Layer name" labelType="label" > @@ -22,6 +23,7 @@ exports[`should render with fields 1`] = ` fullWidth={false} hasChildLabel={true} hasEmptyLabelSpace={false} + helpText="Zoom levels where the layer is present in the tiles. This does not correspond directly to visibility. Layer data from lower levels can always be displayed at higher zoom levels (but not vice versa)." label="Available levels" labelType="label" > @@ -52,6 +54,7 @@ exports[`should render with fields 1`] = ` fullWidth={false} hasChildLabel={true} hasEmptyLabelSpace={false} + helpText="Fields which are available in the tile for the layer. These can be used for tooltips and dynamic styling." label="Fields" labelType="label" > @@ -86,6 +89,7 @@ exports[`should render without fields 1`] = ` fullWidth={false} hasChildLabel={true} hasEmptyLabelSpace={false} + helpText="Name of the target data layer in the tile" label="Layer name" labelType="label" > @@ -100,6 +104,7 @@ exports[`should render without fields 1`] = ` fullWidth={false} hasChildLabel={true} hasEmptyLabelSpace={false} + helpText="Zoom levels where the layer is present in the tiles. This does not correspond directly to visibility. Layer data from lower levels can always be displayed at higher zoom levels (but not vice versa)." label="Available levels" labelType="label" > diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_single_layer_vector_source_editor.test.tsx.snap b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_single_layer_vector_source_editor.test.tsx.snap index 932aa4d6ab128..c700acbdb51bb 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_single_layer_vector_source_editor.test.tsx.snap +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_single_layer_vector_source_editor.test.tsx.snap @@ -8,10 +8,12 @@ exports[`should render source creation editor (fields should _not_ be included) fullWidth={false} hasChildLabel={true} hasEmptyLabelSpace={false} + helpText="URL of the .mvt vector tile service. e.g. http://company.com/{z}/{x}/{y}.pbf" label="Url" labelType="label" > diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/layer_wizard.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/layer_wizard.tsx index 1973570765295..32fa329be85df 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/layer_wizard.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/layer_wizard.tsx @@ -16,7 +16,7 @@ import { TiledSingleLayerVectorSourceSettings } from '../../../../common/descrip export const mvtVectorSourceWizardConfig: LayerWizard = { categories: [LAYER_WIZARD_CATEGORY.REFERENCE], description: i18n.translate('xpack.maps.source.mvtVectorSourceWizard', { - defaultMessage: '.mvt vector tiles', + defaultMessage: 'Data service implementing the Mapbox vector tile specification', }), icon: 'grid', renderWizard: ({ previewLayers, mapColors }: RenderWizardArguments) => { diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx index 084f349b17426..a587bfd4b9f2d 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx @@ -7,10 +7,10 @@ import React, { ChangeEvent, Component, Fragment } from 'react'; import { - EuiButton, EuiButtonIcon, EuiFlexGroup, EuiFlexItem, + EuiButtonEmpty, EuiSuperSelect, EuiFieldText, EuiSpacer, @@ -199,9 +199,11 @@ export class MVTFieldConfigEditor extends Component { {this._renderFieldConfig()} - - {'Add field'} - + + {i18n.translate('xpack.maps.mvtSource.addFieldLabel', { + defaultMessage: 'Add', + })} + ); } diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx index f244109c4ab15..cf69868b54eac 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx @@ -132,6 +132,13 @@ export class MVTSingleLayerSourceSettings extends Component { label={i18n.translate('xpack.maps.source.MVTSingleLayerVectorSourceEditor.fieldsMessage', { defaultMessage: 'Fields', })} + helpText={i18n.translate( + 'xpack.maps.source.MVTSingleLayerVectorSourceEditor.fieldsHelpMessage', + { + defaultMessage: + 'Fields which are available in the tile for the layer. These can be used for tooltips and dynamic styling.', + } + )} > { defaultMessage: 'Layer name', } )} + helpText={i18n.translate( + 'xpack.maps.source.MVTSingleLayerVectorSourceEditor.layerNameHelpMessage', + { + defaultMessage: 'Name of the target data layer in the tile', + } + )} > { defaultMessage: 'Available levels', } )} + helpText={i18n.translate( + 'xpack.maps.source.MVTSingleLayerVectorSourceEditor.zoomRangeHelpMessage', + { + defaultMessage: + 'Zoom levels where the layer is present in the tiles. This does not correspond directly to visibility. Layer data from lower levels can always be displayed at higher zoom levels (but not vice versa).', + } + )} > { label={i18n.translate('xpack.maps.source.MVTSingleLayerVectorSourceEditor.urlMessage', { defaultMessage: 'Url', })} + helpText={i18n.translate( + 'xpack.maps.source.MVTSingleLayerVectorSourceEditor.urlHelpMessage', + { + defaultMessage: 'URL of the .mvt vector tile service. e.g. {url}', + values: { + url: 'http://company.com/{z}/{x}/{y}.pbf', + }, + } + )} > - + Date: Fri, 26 Jun 2020 18:50:17 -0400 Subject: [PATCH 52/56] styling changes --- .../mvt_field_config_editor.test.tsx.snap | 162 +++++++++--------- .../mvt_field_config_editor.tsx | 31 ++-- 2 files changed, 97 insertions(+), 96 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_field_config_editor.test.tsx.snap b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_field_config_editor.test.tsx.snap index 17772da5a492d..acbda925feff0 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_field_config_editor.test.tsx.snap +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_field_config_editor.test.tsx.snap @@ -17,6 +17,15 @@ exports[`should render error for dupes 1`] = ` + } compressed={false} fullWidth={false} hasDividers={false} @@ -52,15 +61,6 @@ exports[`should render error for dupes 1`] = ` valueOfSelected="String" /> - - - + } compressed={false} fullWidth={false} hasDividers={false} @@ -112,15 +121,6 @@ exports[`should render error for dupes 1`] = ` valueOfSelected="String" /> - - - + } compressed={false} fullWidth={false} hasDividers={false} @@ -172,15 +181,6 @@ exports[`should render error for dupes 1`] = ` valueOfSelected="Number" /> - - - + } compressed={false} fullWidth={false} hasDividers={false} @@ -247,15 +256,6 @@ exports[`should render error for empty name 1`] = ` valueOfSelected="String" /> - - - + } compressed={false} fullWidth={false} hasDividers={false} @@ -307,15 +316,6 @@ exports[`should render error for empty name 1`] = ` valueOfSelected="String" /> - - - + } compressed={false} fullWidth={false} hasDividers={false} @@ -367,15 +376,6 @@ exports[`should render error for empty name 1`] = ` valueOfSelected="Number" /> - - - + } compressed={false} fullWidth={false} hasDividers={false} @@ -442,15 +451,6 @@ exports[`should render field editor 1`] = ` valueOfSelected="String" /> - - - + } compressed={false} fullWidth={false} hasDividers={false} @@ -502,15 +511,6 @@ exports[`should render field editor 1`] = ` valueOfSelected="String" /> - - - + } compressed={false} fullWidth={false} hasDividers={false} @@ -562,15 +571,6 @@ exports[`should render field editor 1`] = ` valueOfSelected="Number" /> - - - { this._fieldChange(newFields); }; + const addButton = ( + { + this._removeField(index); + }} + title={i18n.translate('xpack.maps.mvtSource.trashButtonTitle', { + defaultMessage: 'Remove field', + })} + aria-label={i18n.translate('xpack.maps.mvtSource.trashButtonAriaLabel', { + defaultMessage: 'Remove field', + })} + /> + ); return ( onChange(value)} + append={addButton} /> ); } @@ -174,21 +190,6 @@ export class MVTFieldConfigEditor extends Component { {this._renderFieldNameInput(mvtFieldConfig, index)} {this._renderFieldTypeDropDown(mvtFieldConfig, index)} - - { - this._removeField(index); - }} - title={i18n.translate('xpack.maps.mvtSource.trashButtonTitle', { - defaultMessage: 'Remove field', - })} - aria-label={i18n.translate('xpack.maps.mvtSource.trashButtonAriaLabel', { - defaultMessage: 'Remove field', - })} - /> - ); }); From b0cac12c4f181edc55ff6100a2d33706508ca976 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Fri, 26 Jun 2020 19:16:32 -0400 Subject: [PATCH 53/56] style option box a little better --- .../mvt_field_config_editor.test.tsx.snap | 462 ++++++++++++------ ...single_layer_source_settings.test.tsx.snap | 56 ++- .../mvt_field_config_editor.tsx | 67 ++- .../mvt_single_layer_source_settings.test.tsx | 6 + .../mvt_single_layer_source_settings.tsx | 46 +- 5 files changed, 447 insertions(+), 190 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_field_config_editor.test.tsx.snap b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_field_config_editor.test.tsx.snap index acbda925feff0..befff16f33a1f 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_field_config_editor.test.tsx.snap +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_field_config_editor.test.tsx.snap @@ -35,25 +35,41 @@ exports[`should render error for dupes 1`] = ` options={ Array [ Object { - "inputDisplay": - - + "inputDisplay": + + + + string - - , + + , "value": "String", }, Object { - "inputDisplay": - - + "inputDisplay": + + + + number - - , + + , "value": "Number", }, ] @@ -95,25 +111,41 @@ exports[`should render error for dupes 1`] = ` options={ Array [ Object { - "inputDisplay": - - + "inputDisplay": + + + + string - - , + + , "value": "String", }, Object { - "inputDisplay": - - + "inputDisplay": + + + + number - - , + + , "value": "Number", }, ] @@ -155,25 +187,41 @@ exports[`should render error for dupes 1`] = ` options={ Array [ Object { - "inputDisplay": - - + "inputDisplay": + + + + string - - , + + , "value": "String", }, Object { - "inputDisplay": - - + "inputDisplay": + + + + number - - , + + , "value": "Number", }, ] @@ -185,13 +233,23 @@ exports[`should render error for dupes 1`] = ` - - Add - + + + Add + + + `; @@ -230,25 +288,41 @@ exports[`should render error for empty name 1`] = ` options={ Array [ Object { - "inputDisplay": - - + "inputDisplay": + + + + string - - , + + , "value": "String", }, Object { - "inputDisplay": - - + "inputDisplay": + + + + number - - , + + , "value": "Number", }, ] @@ -290,25 +364,41 @@ exports[`should render error for empty name 1`] = ` options={ Array [ Object { - "inputDisplay": - - + "inputDisplay": + + + + string - - , + + , "value": "String", }, Object { - "inputDisplay": - - + "inputDisplay": + + + + number - - , + + , "value": "Number", }, ] @@ -350,25 +440,41 @@ exports[`should render error for empty name 1`] = ` options={ Array [ Object { - "inputDisplay": - - + "inputDisplay": + + + + string - - , + + , "value": "String", }, Object { - "inputDisplay": - - + "inputDisplay": + + + + number - - , + + , "value": "Number", }, ] @@ -380,13 +486,23 @@ exports[`should render error for empty name 1`] = ` - - Add - + + + Add + + + `; @@ -425,25 +541,41 @@ exports[`should render field editor 1`] = ` options={ Array [ Object { - "inputDisplay": - - + "inputDisplay": + + + + string - - , + + , "value": "String", }, Object { - "inputDisplay": - - + "inputDisplay": + + + + number - - , + + , "value": "Number", }, ] @@ -485,25 +617,41 @@ exports[`should render field editor 1`] = ` options={ Array [ Object { - "inputDisplay": - - + "inputDisplay": + + + + string - - , + + , "value": "String", }, Object { - "inputDisplay": - - + "inputDisplay": + + + + number - - , + + , "value": "Number", }, ] @@ -545,25 +693,41 @@ exports[`should render field editor 1`] = ` options={ Array [ Object { - "inputDisplay": - - + "inputDisplay": + + + + string - - , + + , "value": "String", }, Object { - "inputDisplay": - - + "inputDisplay": + + + + number - - , + + , "value": "Number", }, ] @@ -575,12 +739,22 @@ exports[`should render field editor 1`] = ` - - Add - + + + Add + + + `; diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_single_layer_source_settings.test.tsx.snap b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_single_layer_source_settings.test.tsx.snap index 142756ba907b7..1fb81dc777c85 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_single_layer_source_settings.test.tsx.snap +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_single_layer_source_settings.test.tsx.snap @@ -1,5 +1,57 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`should not render when no layername 1`] = ` + + + + + + + + +`; + exports[`should render with fields 1`] = ` @@ -54,7 +107,7 @@ exports[`should render with fields 1`] = ` fullWidth={false} hasChildLabel={true} hasEmptyLabelSpace={false} - helpText="Fields which are available in the tile for the layer. These can be used for tooltips and dynamic styling." + helpText="Fields which are available in the \`foobar\` layer. These can be used for tooltips and dynamic styling." label="Fields" labelType="label" > @@ -94,6 +147,7 @@ exports[`should render without fields 1`] = ` labelType="label" > diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx index c8faad4819550..4d00cbeba887d 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx @@ -14,6 +14,7 @@ import { EuiSuperSelect, EuiFieldText, EuiSpacer, + EuiHighlight, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import _ from 'lodash'; @@ -21,34 +22,44 @@ import { MVTFieldDescriptor } from '../../../../common/descriptor_types'; import { FieldIcon } from '../../../../../../../src/plugins/kibana_react/public'; import { MVTFieldType } from '../../../../common/constants'; +function makeOption({ + value, + icon, + message, +}: { + value: MVTFieldType; + icon: string; + message: string; +}) { + return { + value, + inputDisplay: ( + + + + + {message} + + ), + }; +} + const FIELD_TYPE_OPTIONS = [ { value: MVTFieldType.STRING, - inputDisplay: ( - - - - {i18n.translate('xpack.maps.mvtSource.stringFieldLabel', { - defaultMessage: 'string', - })} - - - ), + icon: 'string', + message: i18n.translate('xpack.maps.mvtSource.stringFieldLabel', { + defaultMessage: 'string', + }), }, { value: MVTFieldType.NUMBER, - inputDisplay: ( - - - - {i18n.translate('xpack.maps.mvtSource.numberFieldLabel', { - defaultMessage: 'number', - })} - - - ), + icon: 'number', + message: i18n.translate('xpack.maps.mvtSource.numberFieldLabel', { + defaultMessage: 'number', + }), }, -]; +].map(makeOption); export interface Props { fields: MVTFieldDescriptor[]; @@ -200,11 +211,15 @@ export class MVTFieldConfigEditor extends Component { {this._renderFieldConfig()} - - {i18n.translate('xpack.maps.mvtSource.addFieldLabel', { - defaultMessage: 'Add', - })} - + + + + {i18n.translate('xpack.maps.mvtSource.addFieldLabel', { + defaultMessage: 'Add', + })} + + + ); } diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.test.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.test.tsx index 22436fbe5117d..04b83b23d36b3 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.test.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.test.tsx @@ -44,3 +44,9 @@ test('should render without fields', async () => { const component = shallow(); expect(component).toMatchSnapshot(); }); + +test('should not render when no layername', async () => { + const settings = { ...defaultSettings, layerName: '' }; + const component = shallow(); + expect(component).toMatchSnapshot(); +}); diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx index cf69868b54eac..af5e81302484a 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx @@ -127,25 +127,32 @@ export class MVTSingleLayerSourceSettings extends Component { }; render() { - const fieldEditor = this.props.includeFields ? ( - - - - ) : null; + const fieldEditor = + this.props.includeFields && this.state.currentLayerName !== '' ? ( + + + + ) : null; return ( @@ -166,6 +173,7 @@ export class MVTSingleLayerSourceSettings extends Component { Date: Fri, 26 Jun 2020 19:39:33 -0400 Subject: [PATCH 54/56] ts fixes --- .../mvt_field_config_editor.tsx | 1 - .../mvt_single_layer_source_settings.tsx | 4 ++-- .../update_source_editor.tsx | 22 ++++++++++--------- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx index 4d00cbeba887d..84c59b499aefe 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_field_config_editor.tsx @@ -14,7 +14,6 @@ import { EuiSuperSelect, EuiFieldText, EuiSpacer, - EuiHighlight, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import _ from 'lodash'; diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx index af5e81302484a..46a180ee59947 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_source_settings.tsx @@ -22,11 +22,11 @@ export type MVTSettings = { }; export interface State { - currentLayerName: 'string'; + currentLayerName: string; currentMinSourceZoom: number; currentMaxSourceZoom: number; currentFields: MVTFieldDescriptor[]; - previousLayerName: 'string'; + previousLayerName: string; previousMinSourceZoom: number; previousMaxSourceZoom: number; previousFields: MVTFieldDescriptor[]; diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx index 26c31d7b09f0c..8262eec47fb15 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx @@ -30,28 +30,30 @@ export class UpdateSourceEditor extends Component { }; _handleChange = (settings: MVTSettings) => { - const changes: OnSourceChangeArgs = []; - if (settings.layerName !== this.props.layerName) { + const changes: OnSourceChangeArgs[] = []; + if (settings.layerName !== this.props.source.getLayerName()) { changes.push({ propName: 'layerName', value: settings.layerName }); } - if (settings.minSourceZoom !== this.props.minSourceZoom) { + if (settings.minSourceZoom !== this.props.source.getMinZoom()) { changes.push({ propName: 'minSourceZoom', value: settings.minSourceZoom }); } - if (settings.maxSourceZoom !== this.props.maxSourceZoom) { + if (settings.maxSourceZoom !== this.props.source.getMaxZoom()) { changes.push({ propName: 'maxSourceZoom', value: settings.maxSourceZoom }); } - if (!_.isEqual(settings.fields, this.props.fields)) { + if (!_.isEqual(settings.fields, this._getFieldDescriptors())) { changes.push({ propName: 'fields', value: settings.fields }); } this.props.onChange(...changes); }; + _getFieldDescriptors(): MVTFieldDescriptor[] { + return this.props.source.getMVTFields().map((field: MVTField) => { + return field.getMVTFieldDescriptor(); + }); + } + _renderSourceSettingsCard() { - const fieldDescriptors: MVTFieldDescriptor[] = this.props.source - .getMVTFields() - .map((field: MVTField) => { - return field.getMVTFieldDescriptor(); - }); + const fieldDescriptors: MVTFieldDescriptor[] = this._getFieldDescriptors(); return ( From ef248c951094c281cf01f0c0c9bcf2c39bec1ce3 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Fri, 26 Jun 2020 20:06:11 -0400 Subject: [PATCH 55/56] fix console error --- .../classes/styles/vector/components/field_select.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/maps/public/classes/styles/vector/components/field_select.js b/x-pack/plugins/maps/public/classes/styles/vector/components/field_select.js index 51700a5e83394..dcc1f1eadbd54 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/components/field_select.js +++ b/x-pack/plugins/maps/public/classes/styles/vector/components/field_select.js @@ -81,9 +81,16 @@ export function FieldSelect({ fields, selectedFieldName, onChange, styleName, .. let selectedOption; if (selectedFieldName) { - selectedOption = fields.find((field) => { + const field = fields.find((field) => { return field.name === selectedFieldName; }); + //Do not spread in all the other unused values (e.g. type, supportsAutoDomain etc...) + if (field) { + selectedOption = { + value: field.value, + label: field.label, + }; + } } return ( From 514f4531b34386f7f7e7ff00c018d3799b6571d7 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Sat, 27 Jun 2020 01:33:14 -0400 Subject: [PATCH 56/56] tilejson poc --- x-pack/plugins/maps/common/constants.ts | 1 + .../maps/common/descriptor_types/sources.ts | 10 + .../public/classes/fields/tilejson_field.ts | 54 ++++++ .../classes/layers/load_layer_wizards.ts | 2 + .../tilejson_source/tilejon_loader_util.ts | 33 ++++ .../tilejson_source/tilejson_layer_wizard.tsx | 38 ++++ .../tilejson_source/tilejson_source.tsx | 179 ++++++++++++++++++ .../tilejson_source_editor.tsx | 86 +++++++++ .../tilejson_source_settings.tsx | 148 +++++++++++++++ .../tilejson_update_source_editor.tsx | 99 ++++++++++ 10 files changed, 650 insertions(+) create mode 100644 x-pack/plugins/maps/public/classes/fields/tilejson_field.ts create mode 100644 x-pack/plugins/maps/public/classes/sources/tilejson_source/tilejon_loader_util.ts create mode 100644 x-pack/plugins/maps/public/classes/sources/tilejson_source/tilejson_layer_wizard.tsx create mode 100644 x-pack/plugins/maps/public/classes/sources/tilejson_source/tilejson_source.tsx create mode 100644 x-pack/plugins/maps/public/classes/sources/tilejson_source/tilejson_source_editor.tsx create mode 100644 x-pack/plugins/maps/public/classes/sources/tilejson_source/tilejson_source_settings.tsx create mode 100644 x-pack/plugins/maps/public/classes/sources/tilejson_source/tilejson_update_source_editor.tsx diff --git a/x-pack/plugins/maps/common/constants.ts b/x-pack/plugins/maps/common/constants.ts index df7b8ba8a416c..a7d0d91d3d8e9 100644 --- a/x-pack/plugins/maps/common/constants.ts +++ b/x-pack/plugins/maps/common/constants.ts @@ -67,6 +67,7 @@ export enum SOURCE_TYPES { REGIONMAP_FILE = 'REGIONMAP_FILE', GEOJSON_FILE = 'GEOJSON_FILE', MVT_SINGLE_LAYER = 'MVT_SINGLE_LAYER', + TILEJSON_SINGLE_LAYER = 'TILEJSON_SINGLE_LAYER', } export enum FIELD_ORIGIN { diff --git a/x-pack/plugins/maps/common/descriptor_types/sources.ts b/x-pack/plugins/maps/common/descriptor_types/sources.ts index dfbb4a8ff929d..ef23f507594e9 100644 --- a/x-pack/plugins/maps/common/descriptor_types/sources.ts +++ b/x-pack/plugins/maps/common/descriptor_types/sources.ts @@ -130,6 +130,15 @@ export type TiledSingleLayerVectorSourceDescriptor = AbstractSourceDescriptor & tooltipProperties: string[]; }; +export type TileJsonVectorSourceSettings = { + url: string; + layerName: string; +}; +export type TileJsonVectorSourceDescriptor = AbstractSourceDescriptor & + TileJsonVectorSourceSettings & { + tooltipProperties: string[]; + }; + export type JoinDescriptor = { leftField: string; right: ESTermSourceDescriptor; @@ -149,6 +158,7 @@ export type SourceDescriptor = | EMSFileSourceDescriptor | ESPewPewSourceDescriptor | TiledSingleLayerVectorSourceDescriptor + | TileJsonVectorSourceDescriptor | EMSTMSSourceDescriptor | EMSFileSourceDescriptor; diff --git a/x-pack/plugins/maps/public/classes/fields/tilejson_field.ts b/x-pack/plugins/maps/public/classes/fields/tilejson_field.ts new file mode 100644 index 0000000000000..c14b033275d46 --- /dev/null +++ b/x-pack/plugins/maps/public/classes/fields/tilejson_field.ts @@ -0,0 +1,54 @@ +/* + * 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 { AbstractField, IField } from './field'; +import { FIELD_ORIGIN } from '../../../common/constants'; +import { IVectorSource } from '../sources/vector_source'; +import { TileJsonSource } from '../sources/tilejson_source/tilejson_source'; + +export class TileJsonField extends AbstractField implements IField { + private readonly _source: TileJsonSource; + constructor({ + fieldName, + source, + origin, + }: { + fieldName: string; + source: TileJsonSource; + origin: FIELD_ORIGIN; + }) { + super({ fieldName, origin }); + this._source = source; + } + + getSource(): IVectorSource { + return this._source; + } + + async getDataType(): Promise { + const layerConfig = await this._source.getLayerConfig(); + + const type = layerConfig.fields[this.getName()]; + + if (type === 'String') { + return 'string'; + } else if (type === 'Number') { + return 'number'; + } + + console.warn('unknwonf ield type'); + return 'string'; + + } + + async getLabel(): Promise { + return this.getName(); + } + + supportsAutoDomain() { + return false; + } +} diff --git a/x-pack/plugins/maps/public/classes/layers/load_layer_wizards.ts b/x-pack/plugins/maps/public/classes/layers/load_layer_wizards.ts index 8357971a3778f..653b19da746c9 100644 --- a/x-pack/plugins/maps/public/classes/layers/load_layer_wizards.ts +++ b/x-pack/plugins/maps/public/classes/layers/load_layer_wizards.ts @@ -27,6 +27,7 @@ import { mvtVectorSourceWizardConfig } from '../sources/mvt_single_layer_vector_ import { ObservabilityLayerWizardConfig } from './solution_layers/observability'; import { SecurityLayerWizardConfig } from './solution_layers/security'; import { getEnableVectorTiles } from '../../kibana_services'; +import {tileJsonLayerWizardConfig} from "../sources/tilejson_source/tilejson_layer_wizard"; let registered = false; export function registerLayerWizards() { @@ -62,6 +63,7 @@ export function registerLayerWizards() { // eslint-disable-next-line no-console console.warn('Vector tiles are an experimental feature and should not be used in production.'); registerLayerWizard(mvtVectorSourceWizardConfig); + registerLayerWizard(tileJsonLayerWizardConfig); } registered = true; } diff --git a/x-pack/plugins/maps/public/classes/sources/tilejson_source/tilejon_loader_util.ts b/x-pack/plugins/maps/public/classes/sources/tilejson_source/tilejon_loader_util.ts new file mode 100644 index 0000000000000..6b39f80d57b28 --- /dev/null +++ b/x-pack/plugins/maps/public/classes/sources/tilejson_source/tilejon_loader_util.ts @@ -0,0 +1,33 @@ +/* + * 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. + */ + +const tileJsonDocCache = new Map(); + +export async function loadTileJsonDocument(url: string): any { + if (tileJsonDocCache.has(url)) { + return tileJsonDocCache.get(url); + } + + let document; + try { + document = await fetch(url); + } catch (e) { + // eslint-disable-next-line no-console + console.error(e); + throw new Error(`Cannot load ${url}: ${e.message}`); + } + + let docJson; + try { + docJson = await document.json(); + } catch (e) { + console.error(e); + throw new Error(`Cannot parse contents as json: ${e.message}`); + } + + tileJsonDocCache.set(url, docJson); + return docJson; +} diff --git a/x-pack/plugins/maps/public/classes/sources/tilejson_source/tilejson_layer_wizard.tsx b/x-pack/plugins/maps/public/classes/sources/tilejson_source/tilejson_layer_wizard.tsx new file mode 100644 index 0000000000000..24cf78c8380f0 --- /dev/null +++ b/x-pack/plugins/maps/public/classes/sources/tilejson_source/tilejson_layer_wizard.tsx @@ -0,0 +1,38 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import React from 'react'; +import { LayerWizard, RenderWizardArguments } from '../../layers/layer_wizard_registry'; +import { TiledVectorLayer } from '../../layers/tiled_vector_layer/tiled_vector_layer'; +import { LAYER_WIZARD_CATEGORY } from '../../../../common/constants'; +import { TileJsonSourceEditor } from './tilejson_source_editor'; +import { + TileJsonVectorSourceDescriptor, + TileJsonVectorSourceSettings, +} from '../../../../common/descriptor_types'; +import { TileJsonSource, tilejsonSourceTitle } from './tilejson_source'; + +export const tileJsonLayerWizardConfig: LayerWizard = { + categories: [LAYER_WIZARD_CATEGORY.REFERENCE], + description: i18n.translate('xpack.maps.source.tilejsonSourceWizard', { + defaultMessage: + 'Data service implementing the TileJSON 2.0.0 specification, with vector_layers extension', + }), + icon: 'grid', + renderWizard: ({ previewLayers, mapColors }: RenderWizardArguments) => { + const onSourceConfigChange = (sourceConfig: TileJsonVectorSourceSettings) => { + const sourceDescriptor: TileJsonVectorSourceDescriptor = TileJsonSource.createDescriptor( + sourceConfig + ); + const layerDescriptor = TiledVectorLayer.createDescriptor({ sourceDescriptor }, mapColors); + previewLayers([layerDescriptor]); + }; + + return ; + }, + title: tilejsonSourceTitle, +}; diff --git a/x-pack/plugins/maps/public/classes/sources/tilejson_source/tilejson_source.tsx b/x-pack/plugins/maps/public/classes/sources/tilejson_source/tilejson_source.tsx new file mode 100644 index 0000000000000..a0e7b80a518ad --- /dev/null +++ b/x-pack/plugins/maps/public/classes/sources/tilejson_source/tilejson_source.tsx @@ -0,0 +1,179 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import uuid from 'uuid/v4'; +import React from 'react'; +import { GeoJsonProperties } from 'geojson'; +import { ImmutableSourceProperty, SourceEditorArgs } from '../source'; +import { FIELD_ORIGIN, MAX_ZOOM, MIN_ZOOM, SOURCE_TYPES } from '../../../../common/constants'; +import { registerSource } from '../source_registry'; +import { getDataSourceLabel, getUrlLabel } from '../../../../common/i18n_getters'; +import { + TiledSingleLayerVectorSourceDescriptor, + TileJsonVectorSourceDescriptor, +} from '../../../../common/descriptor_types'; +import { MVTField } from '../../fields/mvt_field'; +import { ITooltipProperty } from '../../tooltips/tooltip_property'; +import { MVTSingleLayerVectorSource } from '../mvt_single_layer_vector_source'; +import { loadTileJsonDocument } from './tilejon_loader_util'; +import { TileJsonUpdateSourceEditor } from './tilejson_update_source_editor'; +import { TileJsonField } from '../../fields/tilejson_field'; + +export const tilejsonSourceTitle = i18n.translate('xpack.maps.source.tileJsonSource.sourceTitle', { + defaultMessage: 'TileJSON Layer', +}); + +export interface TileJsonVectorLayerConfig { + id: string; + description: string; + minzoom: number; + maxzoom: number; + fields: Record; +} + +// todo: dont inherit, implement interface +export class TileJsonSource extends MVTSingleLayerVectorSource { + static createDescriptor({ + url, + layerName, + tooltipProperties, + }: Partial): TileJsonVectorSourceDescriptor { + return { + type: SOURCE_TYPES.TILEJSON_SINGLE_LAYER, + id: uuid(), + url: url ? url : '', + layerName: layerName ? layerName : '', + tooltipProperties: tooltipProperties ? tooltipProperties : [], + }; + } + + static getLayerConfigsFromTileJson(tileJsonDoc: any): TileJsonVectorLayerConfig[] { + return tileJsonDoc.vector_layers || []; + } + + readonly _descriptor: TiledSingleLayerVectorSourceDescriptor; + + constructor( + sourceDescriptor: TiledSingleLayerVectorSourceDescriptor, + inspectorAdapters?: object + ) { + super(sourceDescriptor, inspectorAdapters); + this._descriptor = TileJsonSource.createDescriptor(sourceDescriptor); + + // todo deal with tooltipProperties + } + + renderSourceSettingsEditor({ onChange }: SourceEditorArgs) { + return ; + } + + getFieldNames(): string[] { + return []; + } + + getMVTFields(): MVTField[] { + throw new Error('Cannot synchronously getMVTFieldNames'); + } + + // todo: breaks inheritance., shouldnt inherit from mvt_sinfle_layer + getFieldByName(fieldName: string): TileJsonField | null { + try { + return this.createField({ fieldName }); + } catch (e) { + return null; + } + } + + createField({ fieldName }: { fieldName: string }): TileJsonField { + return new TileJsonField({ + fieldName, + source: this, + origin: FIELD_ORIGIN.SOURCE, + }); + } + + async getFields(): Promise { + const layer = await this.getLayerConfig(); + + const fields = []; + for (const key in layer.fields) { + if (layer.fields.hasOwnProperty(key)) { + const f = new TileJsonField({ + fieldName: key, + source: this, + origin: FIELD_ORIGIN.SOURCE, + }); + fields.push(f); + } + } + + return fields; + } + + getUrl(): string { + return this._descriptor.url; + } + + async getImmutableProperties(): Promise { + return [ + { label: getDataSourceLabel(), value: tilejsonSourceTitle }, + { label: getUrlLabel(), value: this._descriptor.url }, + { + label: i18n.translate('xpack.maps.source.tilejsonSource.layerNameMessage', { + defaultMessage: 'Layer name', + }), + value: this._descriptor.layerName, + }, + ]; + } + + async getLayerConfig(): Promise { + const tileJsonDoc = await loadTileJsonDocument(this._descriptor.url); + const layers = TileJsonSource.getLayerConfigsFromTileJson(tileJsonDoc); + return layers.find((l) => l.id === this._descriptor.layerName); + } + async getUrlTemplateWithMeta() { + const layer = await this.getLayerConfig(); + // todo: EMS does not preserve licesing param + const tileJsonDoc = await loadTileJsonDocument(this._descriptor.url); + const tileUrl = tileJsonDoc.tiles[0]; + return { + urlTemplate: tileUrl, + layerName: this._descriptor.layerName, + minSourceZoom: layer.minzoom, + maxSourceZoom: layer.maxzoom, + }; + } + + getFeatureProperties( + id: string | number | undefined, + mbProperties: GeoJsonProperties + ): GeoJsonProperties | null { + return mbProperties; + } + + getMinZoom() { + return MIN_ZOOM; + } + + getMaxZoom() { + return MAX_ZOOM; + } + + async filterAndFormatPropertiesToHtml( + properties: GeoJsonProperties, + featureId?: string | number + ): Promise { + // todo + return []; + } +} + +registerSource({ + ConstructorFunction: TileJsonSource, + type: SOURCE_TYPES.TILEJSON_SINGLE_LAYER, +}); diff --git a/x-pack/plugins/maps/public/classes/sources/tilejson_source/tilejson_source_editor.tsx b/x-pack/plugins/maps/public/classes/sources/tilejson_source/tilejson_source_editor.tsx new file mode 100644 index 0000000000000..4615037237c93 --- /dev/null +++ b/x-pack/plugins/maps/public/classes/sources/tilejson_source/tilejson_source_editor.tsx @@ -0,0 +1,86 @@ +/* + * 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. + */ +/* eslint-disable @typescript-eslint/consistent-type-definitions */ + +import React, { Fragment, Component, ChangeEvent } from 'react'; +import _ from 'lodash'; +import { EuiFieldText, EuiFormRow } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { TileJsonVectorSourceSettings } from '../../../../common/descriptor_types'; +import { TileJsonSourceSettings } from './tilejson_source_settings'; + +export interface Props { + onSourceConfigChange: (sourceConfig: TileJsonVectorSourceSettings) => void; +} + +interface State { + url: string; + layerName: string; +} + +export class TileJsonSourceEditor extends Component { + state = { + url: '', + layerName: '', + }; + + _sourceConfigChange = _.debounce(() => { + if (this.state.layerName && this.state.url) { + this.props.onSourceConfigChange({ + url: this.state.url, + layerName: this.state.layerName, + }); + } + }, 200); + + _handleUrlChange = (e: ChangeEvent) => { + const url = e.target.value; + + if (this.state.url === url) { + return; + } + + this.setState( + { + url, + }, + () => this._sourceConfigChange() + ); + }; + + _handleLayerNameChange = (layerName: string) => { + if (this.state.layerName === layerName) { + return; + } + this.setState({ layerName }, () => this._sourceConfigChange()); + }; + + render() { + return ( + + + + + + + + ); + } +} diff --git a/x-pack/plugins/maps/public/classes/sources/tilejson_source/tilejson_source_settings.tsx b/x-pack/plugins/maps/public/classes/sources/tilejson_source/tilejson_source_settings.tsx new file mode 100644 index 0000000000000..558c43b2fed7f --- /dev/null +++ b/x-pack/plugins/maps/public/classes/sources/tilejson_source/tilejson_source_settings.tsx @@ -0,0 +1,148 @@ +/* + * 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. + */ +/* eslint-disable @typescript-eslint/consistent-type-definitions */ + +import React, { Fragment, Component, ChangeEvent } from 'react'; +import { EuiSelect, EuiFormRow, EuiText } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import _ from 'lodash'; +import { loadTileJsonDocument } from './tilejon_loader_util'; +import { TileJsonSource, TileJsonVectorLayerConfig } from './tilejson_source'; + +export interface State { + currentLayerName: string; + previousLayerName: string; + urlForDoc: string; + tileJsonDoc: any; +} + +export interface Props { + handleChange: (layerName: string) => void; + layerName: string; + url: string[]; +} + +export class TileJsonSourceSettings extends Component { + state = { + currentLayerName: '', + previousLayerName: '', + urlForDoc: '', + tileJsonDoc: null, + }; + + static getDerivedStateFromProps(nextProps: Props, prevState: State) { + if (_.isEqual(nextProps.layerName, prevState.previousLayerName)) { + return null; + } + + return { + currentLayerName: nextProps.layerName, + previousLayerName: nextProps.layerName, + urlForDoc: prevState.urlForDoc, + tileJsonDoc: prevState.tileJsonDoc, + }; + } + + _isMounted: boolean = false; + + componentDidMount(): void { + this._isMounted = true; + this._loadUrl(); + } + + componentWillUnmount(): void { + this._isMounted = false; + } + + componentDidUpdate(prevProps: Readonly, prevState: Readonly, snapshot?: any): void { + this._loadUrl(); + } + + async _loadUrl() { + if (!this.props.url) { + return; + } + if (this.state.urlForDoc === this.props.url) { + return; + } + const url = this.props.url; + let tileJsonDoc; + try { + tileJsonDoc = await loadTileJsonDocument(url); + } catch (e) { + console.error(e); + this.setState({ + urlForDoc: '', + tileJsonDoc: null, + }); + return; + } + if (this._isMounted && this.props.url === url) { + this.setState({ + urlForDoc: url, + tileJsonDoc, + }); + } + } + + _handleChange = _.debounce(() => { + this.props.handleChange(this.state.currentLayerName); + }, 200); + + _handleLayerNameInputChange = (e: ChangeEvent) => { + const layerName = e.target.value; + if (layerName === this.state.currentLayerName) { + return; + } + this.setState({ currentLayerName: layerName }, this._handleChange); + }; + + render() { + if (!this.state.tileJsonDoc) { + return null; + } + + const description = this.state.tileJsonDoc.description; + + const layers: TileJsonVectorLayerConfig[] = TileJsonSource.getLayerConfigsFromTileJson( + this.state.tileJsonDoc + ); + const layerOptions = layers.map((layer: TileJsonVectorLayerConfig) => { + return { + text: layer.id, + value: layer.id, + }; + }); + return ( + + + {description} + + + + + + ); + } +} diff --git a/x-pack/plugins/maps/public/classes/sources/tilejson_source/tilejson_update_source_editor.tsx b/x-pack/plugins/maps/public/classes/sources/tilejson_source/tilejson_update_source_editor.tsx new file mode 100644 index 0000000000000..40c148504a98c --- /dev/null +++ b/x-pack/plugins/maps/public/classes/sources/tilejson_source/tilejson_update_source_editor.tsx @@ -0,0 +1,99 @@ +/* + * 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 React, { Component, Fragment } from 'react'; +import { EuiTitle, EuiPanel, EuiSpacer } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; + +// import { TooltipSelector } from '../../../components/tooltip_selector'; +import { MVTField } from '../../fields/mvt_field'; +import { OnSourceChangeArgs } from '../../../connected_components/layer_panel/view'; +import { TileJsonSourceSettings } from './tilejson_source_settings'; +import { TileJsonSource } from './tilejson_source'; + +export interface Props { + tooltipFields: MVTField[]; + onChange: (...args: OnSourceChangeArgs[]) => void; + source: TileJsonSource; +} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +interface State {} + +export class TileJsonUpdateSourceEditor extends Component { + // _onTooltipPropertiesSelect = (propertyNames: string[]) => { + // this.props.onChange({ propName: 'tooltipProperties', value: propertyNames }); + // }; + + _handleChange = (layerName: string) => { + const changes: OnSourceChangeArgs[] = []; + if (layerName !== this.props.source.getLayerName()) { + changes.push({ propName: 'layerName', value: layerName }); + } + this.props.onChange(...changes); + }; + + _renderSourceSettingsCard() { + return ( + + + +
+ +
+
+ + +
+ + +
+ ); + } + + // _renderTooltipSelectionCard() { + // return ( + // + // + // + //
+ // + //
+ //
+ // + // + // + // + //
+ // + // + //
+ // ); + // } + + render() { + return ( + + {this._renderSourceSettingsCard()} + {/* {this._renderTooltipSelectionCard()}*/} + + ); + } +}