From df6737bb98a2747e3f4175b345c216751c8ded2a Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Thu, 18 Jun 2020 08:59:43 -0600 Subject: [PATCH 01/19] [Maps] choropleth layer wizard --- .../choropleth_layer_wizard.tsx | 26 +++++++++++ .../layers/choropleth_layer_wizard/index.ts | 7 +++ .../layer_template.tsx | 44 +++++++++++++++++++ .../classes/layers/load_layer_wizards.ts | 2 + 4 files changed, 79 insertions(+) create mode 100644 x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/choropleth_layer_wizard.tsx create mode 100644 x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/index.ts create mode 100644 x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx diff --git a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/choropleth_layer_wizard.tsx b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/choropleth_layer_wizard.tsx new file mode 100644 index 00000000000000..10357e96e85caf --- /dev/null +++ b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/choropleth_layer_wizard.tsx @@ -0,0 +1,26 @@ +/* + * 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 from 'react'; +import { i18n } from '@kbn/i18n'; +import { LAYER_WIZARD_CATEGORY } from '../../../../common/constants'; +import { LayerWizard, RenderWizardArguments } from '../layer_wizard_registry'; +import { LayerTemplate } from './layer_template'; +import { getIndexPatternService } from '../../../kibana_services'; + +export const choroplethLayerWizardConfig: LayerWizard = { + categories: [LAYER_WIZARD_CATEGORY.ELASTICSEARCH], + description: i18n.translate('xpack.maps.choropleth.desc', { + defaultMessage: 'Shaded areas to compare statistics across boundaries', + }), + icon: 'logoElasticsearch', + renderWizard: (renderWizardArguments: RenderWizardArguments) => { + return
; + }, + title: i18n.translate('xpack.maps.choropleth.title', { + defaultMessage: 'Choropleth', + }), +}; diff --git a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/index.ts b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/index.ts new file mode 100644 index 00000000000000..afabfea0c8d46a --- /dev/null +++ b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/index.ts @@ -0,0 +1,7 @@ +/* + * 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. + */ + +export { choroplethLayerWizardConfig } from './choropleth_layer_wizard'; diff --git a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx new file mode 100644 index 00000000000000..bcfc875f41ad1c --- /dev/null +++ b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx @@ -0,0 +1,44 @@ +/* + * 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 { RenderWizardArguments } from '../../layer_wizard_registry'; +import { LayerSelect, OBSERVABILITY_LAYER_TYPE } from './layer_select'; +import { getMetricOptionsForLayer, MetricSelect, OBSERVABILITY_METRIC_TYPE } from './metric_select'; +import { DisplaySelect, DISPLAY } from './display_select'; +import { createLayerDescriptor } from './create_layer_descriptor'; + +export enum BOUNDARIES_SOURCE { + ELASTICSEARCH = 'ELASTICSEARCH', + EMS = 'EMS', +} + +interface State { + leftSource: BOUNDARIES_SOURCE; + leftIndexPatternId: string | null; + leftEmsFileId: string | null; + leftKey: string | null; + rightIndexPatternId: string | null; + rightKey: string | null; +} + +export class LayerTemplate extends Component { + state = { + leftSource: BOUNDARIES_SOURCE.ELASTICSEARCH, + leftIndexPatternId: null, + leftEmsFileId: null, + leftKey: null, + rightIndexPatternId: null, + rightKey: null, + }; + + render() { + return ( +
+
+ ); + } +} 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 8357971a3778f3..37bcb3b23c0728 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 @@ -26,6 +26,7 @@ import { wmsLayerWizardConfig } from '../sources/wms_source'; import { mvtVectorSourceWizardConfig } from '../sources/mvt_single_layer_vector_source'; import { ObservabilityLayerWizardConfig } from './solution_layers/observability'; import { SecurityLayerWizardConfig } from './solution_layers/security'; +import { choroplethLayerWizardConfig } from './choropleth_layer_wizard'; import { getEnableVectorTiles } from '../../kibana_services'; let registered = false; @@ -41,6 +42,7 @@ export function registerLayerWizards() { // @ts-ignore registerLayerWizard(esDocumentsLayerWizardConfig); // @ts-ignore + registerLayerWizard(choroplethLayerWizardConfig); registerLayerWizard(clustersLayerWizardConfig); // @ts-ignore registerLayerWizard(heatmapLayerWizardConfig); From 7ec1c882136bc4076f0e4c20242e90e6167d4593 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Thu, 18 Jun 2020 09:18:47 -0600 Subject: [PATCH 02/19] add boundaries radio group --- .../choropleth_layer_wizard.tsx | 2 +- .../layer_template.tsx | 71 +++++++++++++++++-- 2 files changed, 66 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/choropleth_layer_wizard.tsx b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/choropleth_layer_wizard.tsx index 10357e96e85caf..fc20f125eb86d0 100644 --- a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/choropleth_layer_wizard.tsx +++ b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/choropleth_layer_wizard.tsx @@ -18,7 +18,7 @@ export const choroplethLayerWizardConfig: LayerWizard = { }), icon: 'logoElasticsearch', renderWizard: (renderWizardArguments: RenderWizardArguments) => { - return
; + return ; }, title: i18n.translate('xpack.maps.choropleth.title', { defaultMessage: 'Choropleth', diff --git a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx index bcfc875f41ad1c..7179dc458721fa 100644 --- a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx +++ b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx @@ -5,17 +5,30 @@ */ import React, { Component, Fragment } from 'react'; +import { i18n } from '@kbn/i18n'; +import { EuiFormRow, EuiRadioGroup } from '@elastic/eui'; import { RenderWizardArguments } from '../../layer_wizard_registry'; -import { LayerSelect, OBSERVABILITY_LAYER_TYPE } from './layer_select'; -import { getMetricOptionsForLayer, MetricSelect, OBSERVABILITY_METRIC_TYPE } from './metric_select'; -import { DisplaySelect, DISPLAY } from './display_select'; -import { createLayerDescriptor } from './create_layer_descriptor'; export enum BOUNDARIES_SOURCE { ELASTICSEARCH = 'ELASTICSEARCH', EMS = 'EMS', } +const BOUNDARIES_OPTIONS = [ + { + id: BOUNDARIES_SOURCE.ELASTICSEARCH, + label: i18n.translate('xpack.maps.choropleth.boundaries.elasticsearch', { + defaultMessage: 'Vectors from Elasticsearch', + }), + }, + { + id: BOUNDARIES_SOURCE.EMS, + label: i18n.translate('xpack.maps.choropleth.boundaries.ems', { + defaultMessage: 'Administrative boundaries from Elastic Maps Service', + }), + }, +]; + interface State { leftSource: BOUNDARIES_SOURCE; leftIndexPatternId: string | null; @@ -35,10 +48,56 @@ export class LayerTemplate extends Component { rightKey: null, }; + _onLeftSourceChange = (optionId) => { + this.setState({ leftSource: optionId }, this._previewLayer); + }; + + _isLeftConfigComplete() { + if (this.state.leftSource === BOUNDARIES_SOURCE.ELASTICSEARCH) { + return !!this.state.leftIndexPatternId && !!this.state.leftKey; + } else { + return !!this.state.leftEmsFileId; + } + } + + _isRightConfigComplete() { + return !!this.state.rightIndexPatternId && !!this.state.rightKey; + } + + _previewLayer() { + /* const layerDescriptor = createLayerDescriptor({ + layer: this.state.layer, + metric: this.state.metric, + display: this.state.display, + }); + this.props.previewLayers(layerDescriptor ? [layerDescriptor] : []);*/ + } + + _renderLeftSource() { + if (this.state.leftSource === BOUNDARIES_SOURCE) { + return null; + } + + return null; + } + render() { return ( -
-
+ <> + + + + + {this._renderLeftSource()} + ); } } From 3ded282edd26016b9d2f512e7bf846a42ef6d0e2 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Thu, 18 Jun 2020 12:00:30 -0600 Subject: [PATCH 03/19] geo_index_pattern_select --- .../layer_template.tsx | 50 +++++++-- .../ems_file_source/create_source_editor.tsx | 71 +----------- .../ems_tms_source/tile_service_select.js | 2 +- .../create_source_editor.js | 54 ++------- .../es_search_source/create_source_editor.js | 51 ++------- .../public/components/ems_file_select.tsx | 106 ++++++++++++++++++ .../ems_unavailable_message.tsx} | 2 +- .../components/geo_index_pattern_select.tsx | 104 +++++++++++++++++ .../components/no_index_pattern_callout.js | 52 --------- 9 files changed, 272 insertions(+), 220 deletions(-) create mode 100644 x-pack/plugins/maps/public/components/ems_file_select.tsx rename x-pack/plugins/maps/public/{classes/sources/ems_unavailable_message.ts => components/ems_unavailable_message.tsx} (93%) create mode 100644 x-pack/plugins/maps/public/components/geo_index_pattern_select.tsx delete mode 100644 x-pack/plugins/maps/public/components/no_index_pattern_callout.js diff --git a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx index 7179dc458721fa..23e4d723e94b32 100644 --- a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx +++ b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx @@ -8,6 +8,9 @@ import React, { Component, Fragment } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiFormRow, EuiRadioGroup } from '@elastic/eui'; import { RenderWizardArguments } from '../../layer_wizard_registry'; +import { EMSFileSelect } from '../../../components/ems_file_select'; +import { GeoIndexPatternSelect } from '../../../components/geo_index_pattern_select'; +import { getIndexPatternSelectComponent } from '../../../kibana_services'; export enum BOUNDARIES_SOURCE { ELASTICSEARCH = 'ELASTICSEARCH', @@ -18,7 +21,7 @@ const BOUNDARIES_OPTIONS = [ { id: BOUNDARIES_SOURCE.ELASTICSEARCH, label: i18n.translate('xpack.maps.choropleth.boundaries.elasticsearch', { - defaultMessage: 'Vectors from Elasticsearch', + defaultMessage: 'Points, lines, or polygons from Elasticsearch', }), }, { @@ -29,11 +32,15 @@ const BOUNDARIES_OPTIONS = [ }, ]; +const IndexPatternSelect = getIndexPatternSelectComponent(); + interface State { leftSource: BOUNDARIES_SOURCE; leftIndexPatternId: string | null; + leftGeofieldName: string | null; + leftEsJoinField: string | null; leftEmsFileId: string | null; - leftKey: string | null; + leftEmsJoinField: string | null; rightIndexPatternId: string | null; rightKey: string | null; } @@ -42,21 +49,35 @@ export class LayerTemplate extends Component { state = { leftSource: BOUNDARIES_SOURCE.ELASTICSEARCH, leftIndexPatternId: null, + leftGeofieldName: null, + leftEsJoinField: null, leftEmsFileId: null, - leftKey: null, + leftEmsJoinField: null, rightIndexPatternId: null, rightKey: null, }; - _onLeftSourceChange = (optionId) => { + _onLeftSourceChange = (optionId: string) => { this.setState({ leftSource: optionId }, this._previewLayer); }; + _onLeftIndexPatternChange = (indexPatternId: string) => { + this.setState({ leftIndexPatternId: indexPatternId }, this._previewLayer); + }; + + _onEmsFileChange = (emFileId: string) => { + this.setState({ leftEmsFileId: emFileId }, this._previewLayer); + }; + _isLeftConfigComplete() { if (this.state.leftSource === BOUNDARIES_SOURCE.ELASTICSEARCH) { - return !!this.state.leftIndexPatternId && !!this.state.leftKey; + return ( + !!this.state.leftIndexPatternId && + !!this.state.leftGeofieldName && + !!this.state.leftEsJoinField + ); } else { - return !!this.state.leftEmsFileId; + return !!this.state.leftEmsFileId && !!this.state.leftEmsFileId; } } @@ -65,6 +86,10 @@ export class LayerTemplate extends Component { } _previewLayer() { + if (!this._isLeftConfigComplete() || !this._isRightConfigComplete()) { + return; + } + /* const layerDescriptor = createLayerDescriptor({ layer: this.state.layer, metric: this.state.metric, @@ -74,11 +99,16 @@ export class LayerTemplate extends Component { } _renderLeftSource() { - if (this.state.leftSource === BOUNDARIES_SOURCE) { - return null; + if (this.state.leftSource === BOUNDARIES_SOURCE.ELASTICSEARCH) { + return ( + + ); + } else { + return ; } - - return null; } render() { diff --git a/x-pack/plugins/maps/public/classes/sources/ems_file_source/create_source_editor.tsx b/x-pack/plugins/maps/public/classes/sources/ems_file_source/create_source_editor.tsx index a78a49032503b8..e18b99cba838a3 100644 --- a/x-pack/plugins/maps/public/classes/sources/ems_file_source/create_source_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/ems_file_source/create_source_editor.tsx @@ -12,88 +12,29 @@ import { FileLayer } from '@elastic/ems-client'; import { getEmsFileLayers } from '../../../meta'; import { getEmsUnavailableMessage } from '../ems_unavailable_message'; import { EMSFileSourceDescriptor } from '../../../../common/descriptor_types'; +import { EMSFileSelect } from '../../../components/ems_file_select'; interface Props { onSourceConfigChange: (sourceConfig: Partial) => void; } interface State { - hasLoadedOptions: boolean; - emsFileOptions: Array>; - selectedOption: EuiComboBoxOptionOption | null; + emsFileId: string | null; } export class EMSFileCreateSourceEditor extends Component { private _isMounted: boolean = false; state = { - hasLoadedOptions: false, - emsFileOptions: [], - selectedOption: null, + emsFileId: null, }; - _loadFileOptions = async () => { - const fileLayers: FileLayer[] = await getEmsFileLayers(); - const options = fileLayers.map((fileLayer) => { - return { - value: fileLayer.getId(), - label: fileLayer.getDisplayName(), - }; - }); - if (this._isMounted) { - this.setState({ - hasLoadedOptions: true, - emsFileOptions: options, - }); - } - }; - - componentWillUnmount() { - this._isMounted = false; - } - - componentDidMount() { - this._isMounted = true; - this._loadFileOptions(); - } - - _onChange = (selectedOptions: Array>) => { - if (selectedOptions.length === 0) { - return; - } - - this.setState({ selectedOption: selectedOptions[0] }); - - const emsFileId = selectedOptions[0].value; + _onChange = (emsFileId: string) => { + this.setState({ emsFileId }); this.props.onSourceConfigChange({ id: emsFileId }); }; render() { - if (!this.state.hasLoadedOptions) { - // TODO display loading message - return null; - } - - return ( - - - - ); + return ; } } diff --git a/x-pack/plugins/maps/public/classes/sources/ems_tms_source/tile_service_select.js b/x-pack/plugins/maps/public/classes/sources/ems_tms_source/tile_service_select.js index 3931e441ff2548..1eff4bf3786f46 100644 --- a/x-pack/plugins/maps/public/classes/sources/ems_tms_source/tile_service_select.js +++ b/x-pack/plugins/maps/public/classes/sources/ems_tms_source/tile_service_select.js @@ -8,7 +8,7 @@ import React from 'react'; import { EuiSelect, EuiFormRow } from '@elastic/eui'; import { getEmsTmsServices } from '../../../meta'; -import { getEmsUnavailableMessage } from '../ems_unavailable_message'; +import { getEmsUnavailableMessage } from '../../../components/ems_unavailable_message'; import { i18n } from '@kbn/i18n'; export const AUTO_SELECT = 'auto_select'; diff --git a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/create_source_editor.js b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/create_source_editor.js index 24edf0251c1535..bbf9dd1777bade 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/create_source_editor.js +++ b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/create_source_editor.js @@ -8,13 +8,12 @@ import _ from 'lodash'; import React, { Fragment, Component } from 'react'; import PropTypes from 'prop-types'; -import { ES_GEO_FIELD_TYPES } from '../../../../common/constants'; import { SingleFieldSelect } from '../../../components/single_field_select'; -import { getIndexPatternService, getIndexPatternSelectComponent } from '../../../kibana_services'; -import { NoIndexPatternCallout } from '../../../components/no_index_pattern_callout'; +import { getIndexPatternService } from '../../../kibana_services'; +import { GeoIndexPatternSelect } from '../../../components/geo_index_pattern_select'; import { i18n } from '@kbn/i18n'; -import { EuiFormRow, EuiSpacer } from '@elastic/eui'; +import { EuiFormRow } from '@elastic/eui'; import { getFieldsWithGeoTileAgg, getGeoFields, @@ -37,7 +36,6 @@ export class CreateSourceEditor extends Component { indexPatternId: '', geoField: '', requestType: this.props.requestType, - noGeoIndexPatternsExist: false, }; componentWillUnmount() { @@ -129,10 +127,6 @@ export class CreateSourceEditor extends Component { this.props.onSourceConfigChange(sourceConfig); }; - _onNoIndexPatterns = () => { - this.setState({ noGeoIndexPatternsExist: true }); - }; - _renderGeoSelect() { if (!this.state.indexPattern) { return null; @@ -170,47 +164,13 @@ export class CreateSourceEditor extends Component { ); } - _renderIndexPatternSelect() { - const IndexPatternSelect = getIndexPatternSelectComponent(); - - return ( - - - - ); - } - - _renderNoIndexPatternWarning() { - if (!this.state.noGeoIndexPatternsExist) { - return null; - } - - return ( - - - - - ); - } - render() { return ( - {this._renderNoIndexPatternWarning()} - {this._renderIndexPatternSelect()} + {this._renderGeoSelect()} {this._renderRenderAsSelect()} diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/create_source_editor.js b/x-pack/plugins/maps/public/classes/sources/es_search_source/create_source_editor.js index 73abfd87e47975..cf287f5a472303 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/create_source_editor.js +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/create_source_editor.js @@ -10,10 +10,10 @@ import PropTypes from 'prop-types'; import { EuiFormRow, EuiSpacer } from '@elastic/eui'; import { SingleFieldSelect } from '../../../components/single_field_select'; -import { getIndexPatternService, getIndexPatternSelectComponent } from '../../../kibana_services'; -import { NoIndexPatternCallout } from '../../../components/no_index_pattern_callout'; +import { getIndexPatternService } from '../../../kibana_services'; +import { GeoIndexPatternSelect } from '../../../components/geo_index_pattern_select'; import { i18n } from '@kbn/i18n'; -import { ES_GEO_FIELD_TYPES, SCALING_TYPES } from '../../../../common/constants'; +import { SCALING_TYPES } from '../../../../common/constants'; import { DEFAULT_FILTER_BY_MAP_BOUNDS } from './constants'; import { ScalingForm } from './scaling_form'; import { @@ -46,7 +46,6 @@ export class CreateSourceEditor extends Component { state = { isLoadingIndexPattern: false, - noGeoIndexPatternsExist: false, ...RESET_INDEX_PATTERN_STATE, }; @@ -168,10 +167,6 @@ export class CreateSourceEditor extends Component { this.props.onSourceConfigChange(sourceConfig); }; - _onNoIndexPatterns = () => { - this.setState({ noGeoIndexPatternsExist: true }); - }; - _renderGeoSelect() { if (!this.state.indexPattern) { return; @@ -227,45 +222,13 @@ export class CreateSourceEditor extends Component { ); } - _renderNoIndexPatternWarning() { - if (!this.state.noGeoIndexPatternsExist) { - return null; - } - - return ( - - - - - ); - } - render() { - const IndexPatternSelect = getIndexPatternSelectComponent(); - return ( - {this._renderNoIndexPatternWarning()} - - - - + {this._renderGeoSelect()} diff --git a/x-pack/plugins/maps/public/components/ems_file_select.tsx b/x-pack/plugins/maps/public/components/ems_file_select.tsx new file mode 100644 index 00000000000000..c82e06d3b9fd04 --- /dev/null +++ b/x-pack/plugins/maps/public/components/ems_file_select.tsx @@ -0,0 +1,106 @@ +/* + * 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 } from 'react'; +import { EuiComboBox, EuiComboBoxOptionOption, EuiFormRow, EuiSelect } from '@elastic/eui'; + +import { i18n } from '@kbn/i18n'; +import { FileLayer } from '@elastic/ems-client'; +import { getEmsFileLayers } from '../meta'; +import { getEmsUnavailableMessage } from './ems_unavailable_message'; +import { EMSFileSourceDescriptor } from '../../common/descriptor_types'; + +interface Props { + onChange: (emsFileId: string) => void; + value: string; +} + +interface State { + hasLoadedOptions: boolean; + emsFileOptions: Array>; +} + +export class EMSFileSelect extends Component { + private _isMounted: boolean = false; + + state = { + hasLoadedOptions: false, + emsFileOptions: [], + }; + + _loadFileOptions = async () => { + const fileLayers: FileLayer[] = await getEmsFileLayers(); + const options = fileLayers.map((fileLayer) => { + return { + value: fileLayer.getId(), + label: fileLayer.getDisplayName(), + }; + }); + if (this._isMounted) { + this.setState({ + hasLoadedOptions: true, + emsFileOptions: options, + }); + } + }; + + componentWillUnmount() { + this._isMounted = false; + } + + componentDidMount() { + this._isMounted = true; + this._loadFileOptions(); + } + + _onChange = (selectedOptions: Array>) => { + if (selectedOptions.length === 0) { + return; + } + + this.props.onChange(selectedOptions[0].value); + }; + + _renderSelect() { + if (!this.state.hasLoadedOptions) { + return ; + } + + const selectedOption = this.state.emsFileOptions.find( + (option: EuiComboBoxOptionOption) => { + return option.value === this.props.value; + } + ); + + return ( + + ); + } + + render() { + return ( + + {this._renderSelect()} + + ); + } +} diff --git a/x-pack/plugins/maps/public/classes/sources/ems_unavailable_message.ts b/x-pack/plugins/maps/public/components/ems_unavailable_message.tsx similarity index 93% rename from x-pack/plugins/maps/public/classes/sources/ems_unavailable_message.ts rename to x-pack/plugins/maps/public/components/ems_unavailable_message.tsx index 748016cf889e25..dea161fafd609e 100644 --- a/x-pack/plugins/maps/public/classes/sources/ems_unavailable_message.ts +++ b/x-pack/plugins/maps/public/components/ems_unavailable_message.tsx @@ -6,7 +6,7 @@ import { i18n } from '@kbn/i18n'; // @ts-ignore -import { getIsEmsEnabled } from '../../kibana_services'; +import { getIsEmsEnabled } from '../kibana_services'; export function getEmsUnavailableMessage(): string { const isEmsEnabled = getIsEmsEnabled(); diff --git a/x-pack/plugins/maps/public/components/geo_index_pattern_select.tsx b/x-pack/plugins/maps/public/components/geo_index_pattern_select.tsx new file mode 100644 index 00000000000000..e830f4411a5d86 --- /dev/null +++ b/x-pack/plugins/maps/public/components/geo_index_pattern_select.tsx @@ -0,0 +1,104 @@ +/* + * 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 } from 'react'; +import { EuiCallOut, EuiFormRow, EuiLink, EuiSpacer } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { getIndexPatternSelectComponent, getHttp } from '../kibana_services'; +import { ES_GEO_FIELD_TYPES } from '../../common/constants'; + +interface Props { + onChange: (indexPatternId: string) => void; + value: string | null; +} + +interface State { + noGeoIndexPatternsExist: Array>; +} + +export class GeoIndexPatternSelect extends Component { + state = { + noGeoIndexPatternsExist: false, + }; + + _onNoIndexPatterns = () => { + this.setState({ noGeoIndexPatternsExist: true }); + }; + + _renderNoIndexPatternWarning() { + if (!this.state.noGeoIndexPatternsExist) { + return null; + } + + return ( + <> + +

+ + + + + +

+

+ + + + +

+
+ + + ); + } + + render() { + const IndexPatternSelect = getIndexPatternSelectComponent(); + return ( + <> + {this._renderNoIndexPatternWarning()} + + + + + + ); + } +} diff --git a/x-pack/plugins/maps/public/components/no_index_pattern_callout.js b/x-pack/plugins/maps/public/components/no_index_pattern_callout.js deleted file mode 100644 index 2daab8c6322dd3..00000000000000 --- a/x-pack/plugins/maps/public/components/no_index_pattern_callout.js +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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 { getHttp } from '../kibana_services'; -import React from 'react'; -import { EuiCallOut, EuiLink } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n/react'; - -export function NoIndexPatternCallout() { - const http = getHttp(); - return ( - -

- - - - - -

-

- - - - -

-
- ); -} From ec5818fcf2c5546e0ab4bf72fc00a49edb550d04 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Thu, 18 Jun 2020 13:55:11 -0600 Subject: [PATCH 04/19] consolidate more logic into geo_index_pattern_select --- .../layer_template.tsx | 17 ++-- .../create_source_editor.js | 77 +++------------- .../es_search_source/create_source_editor.js | 90 +++++-------------- .../components/geo_index_pattern_select.tsx | 40 ++++++++- 4 files changed, 82 insertions(+), 142 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx index 23e4d723e94b32..ec3ead247ce495 100644 --- a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx +++ b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx @@ -7,6 +7,7 @@ import React, { Component, Fragment } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiFormRow, EuiRadioGroup } from '@elastic/eui'; +import { IFieldType, IndexPattern } from 'src/plugins/data/public'; import { RenderWizardArguments } from '../../layer_wizard_registry'; import { EMSFileSelect } from '../../../components/ems_file_select'; import { GeoIndexPatternSelect } from '../../../components/geo_index_pattern_select'; @@ -36,7 +37,9 @@ const IndexPatternSelect = getIndexPatternSelectComponent(); interface State { leftSource: BOUNDARIES_SOURCE; - leftIndexPatternId: string | null; + leftIndexPattern: IndexPattern | null; + leftGeoFields: IFieldType[]; + leftTermsFields: IFieldType[]; leftGeofieldName: string | null; leftEsJoinField: string | null; leftEmsFileId: string | null; @@ -48,7 +51,9 @@ interface State { export class LayerTemplate extends Component { state = { leftSource: BOUNDARIES_SOURCE.ELASTICSEARCH, - leftIndexPatternId: null, + leftIndexPattern: null, + leftGeoFields: [], + leftTermsFields: [], leftGeofieldName: null, leftEsJoinField: null, leftEmsFileId: null, @@ -61,8 +66,8 @@ export class LayerTemplate extends Component { this.setState({ leftSource: optionId }, this._previewLayer); }; - _onLeftIndexPatternChange = (indexPatternId: string) => { - this.setState({ leftIndexPatternId: indexPatternId }, this._previewLayer); + _onLeftIndexPatternChange = (indexPattern: IndexPattern) => { + this.setState({ leftIndexPattern: indexPattern }, this._previewLayer); }; _onEmsFileChange = (emFileId: string) => { @@ -72,7 +77,7 @@ export class LayerTemplate extends Component { _isLeftConfigComplete() { if (this.state.leftSource === BOUNDARIES_SOURCE.ELASTICSEARCH) { return ( - !!this.state.leftIndexPatternId && + !!this.state.leftIndexPattern && !!this.state.leftGeofieldName && !!this.state.leftEsJoinField ); @@ -102,7 +107,7 @@ export class LayerTemplate extends Component { if (this.state.leftSource === BOUNDARIES_SOURCE.ELASTICSEARCH) { return ( ); diff --git a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/create_source_editor.js b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/create_source_editor.js index bbf9dd1777bade..72468451d0b176 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/create_source_editor.js +++ b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/create_source_editor.js @@ -4,12 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import _ from 'lodash'; import React, { Fragment, Component } from 'react'; import PropTypes from 'prop-types'; import { SingleFieldSelect } from '../../../components/single_field_select'; -import { getIndexPatternService } from '../../../kibana_services'; import { GeoIndexPatternSelect } from '../../../components/geo_index_pattern_select'; import { i18n } from '@kbn/i18n'; @@ -32,75 +30,26 @@ export class CreateSourceEditor extends Component { }; state = { - isLoadingIndexPattern: false, - indexPatternId: '', + indexPattern: null, geoField: '', requestType: this.props.requestType, }; - componentWillUnmount() { - this._isMounted = false; - } - - componentDidMount() { - this._isMounted = true; - } - - onIndexPatternSelect = (indexPatternId) => { + onIndexPatternSelect = (indexPattern) => { this.setState( { - indexPatternId, + indexPattern, }, - this.loadIndexPattern.bind(null, indexPatternId) + () => { + //make default selection + const geoFieldsWithGeoTileAgg = getFieldsWithGeoTileAgg(indexPattern.fields); + if (geoFieldsWithGeoTileAgg[0]) { + this._onGeoFieldSelect(geoFieldsWithGeoTileAgg[0].name); + } + } ); }; - loadIndexPattern = (indexPatternId) => { - this.setState( - { - isLoadingIndexPattern: true, - indexPattern: undefined, - geoField: undefined, - }, - this.debouncedLoad.bind(null, indexPatternId) - ); - }; - - debouncedLoad = _.debounce(async (indexPatternId) => { - if (!indexPatternId || indexPatternId.length === 0) { - return; - } - - let indexPattern; - try { - indexPattern = await getIndexPatternService().get(indexPatternId); - } catch (err) { - // index pattern no longer exists - return; - } - - if (!this._isMounted) { - return; - } - - // props.indexPatternId may be updated before getIndexPattern returns - // ignore response when fetched index pattern does not match active index pattern - if (indexPattern.id !== indexPatternId) { - return; - } - - this.setState({ - isLoadingIndexPattern: false, - indexPattern: indexPattern, - }); - - //make default selection - const geoFieldsWithGeoTileAgg = getFieldsWithGeoTileAgg(indexPattern.fields); - if (geoFieldsWithGeoTileAgg[0]) { - this._onGeoFieldSelect(geoFieldsWithGeoTileAgg[0].name); - } - }, 300); - _onGeoFieldSelect = (geoField) => { this.setState( { @@ -120,10 +69,10 @@ export class CreateSourceEditor extends Component { }; previewLayer = () => { - const { indexPatternId, geoField, requestType } = this.state; + const { indexPattern, geoField, requestType } = this.state; const sourceConfig = - indexPatternId && geoField ? { indexPatternId, geoField, requestType } : null; + indexPattern && geoField ? { indexPatternId: indexPattern.id, geoField, requestType } : null; this.props.onSourceConfigChange(sourceConfig); }; @@ -168,7 +117,7 @@ export class CreateSourceEditor extends Component { return ( {this._renderGeoSelect()} diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/create_source_editor.js b/x-pack/plugins/maps/public/classes/sources/es_search_source/create_source_editor.js index cf287f5a472303..54ce4a9b02ac46 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/create_source_editor.js +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/create_source_editor.js @@ -4,13 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import _ from 'lodash'; import React, { Fragment, Component } from 'react'; import PropTypes from 'prop-types'; import { EuiFormRow, EuiSpacer } from '@elastic/eui'; import { SingleFieldSelect } from '../../../components/single_field_select'; -import { getIndexPatternService } from '../../../kibana_services'; import { GeoIndexPatternSelect } from '../../../components/geo_index_pattern_select'; import { i18n } from '@kbn/i18n'; import { SCALING_TYPES } from '../../../../common/constants'; @@ -45,79 +43,33 @@ export class CreateSourceEditor extends Component { }; state = { - isLoadingIndexPattern: false, ...RESET_INDEX_PATTERN_STATE, }; - componentWillUnmount() { - this._isMounted = false; - } - - componentDidMount() { - this._isMounted = true; - } - - _onIndexPatternSelect = (indexPatternId) => { - this.setState( - { - indexPatternId, - }, - this._loadIndexPattern(indexPatternId) - ); - }; + _onIndexPatternSelect = (indexPattern) => { + const geoFields = getGeoFields(indexPattern.fields); - _loadIndexPattern = (indexPatternId) => { this.setState( { - isLoadingIndexPattern: true, ...RESET_INDEX_PATTERN_STATE, + indexPattern, + geoFields, }, - this._debouncedLoad.bind(null, indexPatternId) + () => { + if (geoFields.length) { + // make default selection, prefer aggregatable field over the first available + const firstAggregatableGeoField = geoFields.find((geoField) => { + return geoField.aggregatable; + }); + const defaultGeoFieldName = firstAggregatableGeoField + ? firstAggregatableGeoField + : geoFields[0]; + this._onGeoFieldSelect(defaultGeoFieldName.name); + } + } ); }; - _debouncedLoad = _.debounce(async (indexPatternId) => { - if (!indexPatternId || indexPatternId.length === 0) { - return; - } - - let indexPattern; - try { - indexPattern = await getIndexPatternService().get(indexPatternId); - } catch (err) { - // index pattern no longer exists - return; - } - - if (!this._isMounted) { - return; - } - - // props.indexPatternId may be updated before getIndexPattern returns - // ignore response when fetched index pattern does not match active index pattern - if (indexPattern.id !== indexPatternId) { - return; - } - - const geoFields = getGeoFields(indexPattern.fields); - this.setState({ - isLoadingIndexPattern: false, - indexPattern: indexPattern, - geoFields, - }); - - if (geoFields.length) { - // make default selection, prefer aggregatable field over the first available - const firstAggregatableGeoField = geoFields.find((geoField) => { - return geoField.aggregatable; - }); - const defaultGeoFieldName = firstAggregatableGeoField - ? firstAggregatableGeoField - : geoFields[0]; - this._onGeoFieldSelect(defaultGeoFieldName.name); - } - }, 300); - _onGeoFieldSelect = (geoFieldName) => { // Respect previous scaling type selection unless newly selected geo field does not support clustering. const scalingType = @@ -145,7 +97,7 @@ export class CreateSourceEditor extends Component { _previewLayer = () => { const { - indexPatternId, + indexPattern, geoFieldName, filterByMapBounds, scalingType, @@ -154,9 +106,9 @@ export class CreateSourceEditor extends Component { } = this.state; const sourceConfig = - indexPatternId && geoFieldName + indexPattern && geoFieldName ? { - indexPatternId, + indexPatternId: indexPattern.id, geoField: geoFieldName, filterByMapBounds, scalingType, @@ -200,7 +152,7 @@ export class CreateSourceEditor extends Component { diff --git a/x-pack/plugins/maps/public/components/geo_index_pattern_select.tsx b/x-pack/plugins/maps/public/components/geo_index_pattern_select.tsx index e830f4411a5d86..724638810c23e5 100644 --- a/x-pack/plugins/maps/public/components/geo_index_pattern_select.tsx +++ b/x-pack/plugins/maps/public/components/geo_index_pattern_select.tsx @@ -8,11 +8,16 @@ import React, { Component } from 'react'; import { EuiCallOut, EuiFormRow, EuiLink, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { getIndexPatternSelectComponent, getHttp } from '../kibana_services'; +import { IndexPattern } from 'src/plugins/data/public'; +import { + getIndexPatternSelectComponent, + getIndexPatternService, + getHttp, +} from '../kibana_services'; import { ES_GEO_FIELD_TYPES } from '../../common/constants'; interface Props { - onChange: (indexPatternId: string) => void; + onChange: (indexPattern: IndexPattern) => void; value: string | null; } @@ -21,10 +26,39 @@ interface State { } export class GeoIndexPatternSelect extends Component { + private _isMounted: boolean = false; + state = { noGeoIndexPatternsExist: false, }; + componentWillUnmount() { + this._isMounted = false; + } + + componentDidMount() { + this._isMounted = true; + } + + _onIndexPatternSelect = async (indexPatternId: string) => { + if (!indexPatternId || indexPatternId.length === 0) { + return; + } + + let indexPattern; + try { + indexPattern = await getIndexPatternService().get(indexPatternId); + } catch (err) { + return; + } + + // method may be called again before get returns + // ignore response when fetched index pattern does not match active index pattern + if (this._isMounted && indexPattern.id === indexPatternId) { + this.props.onChange(indexPattern); + } + }; + _onNoIndexPatterns = () => { this.setState({ noGeoIndexPatternsExist: true }); }; @@ -90,7 +124,7 @@ export class GeoIndexPatternSelect extends Component { Date: Thu, 18 Jun 2020 13:58:44 -0600 Subject: [PATCH 05/19] small clean-up --- .../classes/layers/choropleth_layer_wizard/layer_template.tsx | 2 +- .../sources/es_search_source/es_documents_layer_wizard.tsx | 2 +- .../plugins/maps/public/components/geo_index_pattern_select.tsx | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx index ec3ead247ce495..30c39fc17716fe 100644 --- a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx +++ b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx @@ -22,7 +22,7 @@ const BOUNDARIES_OPTIONS = [ { id: BOUNDARIES_SOURCE.ELASTICSEARCH, label: i18n.translate('xpack.maps.choropleth.boundaries.elasticsearch', { - defaultMessage: 'Points, lines, or polygons from Elasticsearch', + defaultMessage: 'Points, lines, and polygons from Elasticsearch', }), }, { diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_documents_layer_wizard.tsx b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_documents_layer_wizard.tsx index 4598b1467229d4..1ec6d2a1ff6716 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_documents_layer_wizard.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_documents_layer_wizard.tsx @@ -26,7 +26,7 @@ export function createDefaultLayerDescriptor(sourceConfig: unknown, mapColors: s export const esDocumentsLayerWizardConfig: LayerWizard = { categories: [LAYER_WIZARD_CATEGORY.ELASTICSEARCH], description: i18n.translate('xpack.maps.source.esSearchDescription', { - defaultMessage: 'Vector data from a Kibana index pattern', + defaultMessage: 'Points, lines, and polygons from Elasticsearch', }), icon: 'logoElasticsearch', renderWizard: ({ previewLayers, mapColors }: RenderWizardArguments) => { diff --git a/x-pack/plugins/maps/public/components/geo_index_pattern_select.tsx b/x-pack/plugins/maps/public/components/geo_index_pattern_select.tsx index 724638810c23e5..7cf085a035c353 100644 --- a/x-pack/plugins/maps/public/components/geo_index_pattern_select.tsx +++ b/x-pack/plugins/maps/public/components/geo_index_pattern_select.tsx @@ -130,6 +130,7 @@ export class GeoIndexPatternSelect extends Component { })} fieldTypes={ES_GEO_FIELD_TYPES} onNoIndexPatterns={this._onNoIndexPatterns} + isClearable={false} /> From 6b965f06e65e53db38cf55d5accee23af3ceba96 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Thu, 18 Jun 2020 15:34:25 -0600 Subject: [PATCH 06/19] left geo field and join field --- .../layer_template.tsx | 108 ++++++++++++++---- 1 file changed, 86 insertions(+), 22 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx index 30c39fc17716fe..03bfb305514e10 100644 --- a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx +++ b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx @@ -11,7 +11,9 @@ import { IFieldType, IndexPattern } from 'src/plugins/data/public'; import { RenderWizardArguments } from '../../layer_wizard_registry'; import { EMSFileSelect } from '../../../components/ems_file_select'; import { GeoIndexPatternSelect } from '../../../components/geo_index_pattern_select'; +import { SingleFieldSelect } from '../../../components/single_field_select'; import { getIndexPatternSelectComponent } from '../../../kibana_services'; +import { getGeoFields, getSourceFields } from '../../../index_pattern_util'; export enum BOUNDARIES_SOURCE { ELASTICSEARCH = 'ELASTICSEARCH', @@ -37,29 +39,27 @@ const IndexPatternSelect = getIndexPatternSelectComponent(); interface State { leftSource: BOUNDARIES_SOURCE; + leftEmsFileId: string | null; leftIndexPattern: IndexPattern | null; leftGeoFields: IFieldType[]; - leftTermsFields: IFieldType[]; - leftGeofieldName: string | null; - leftEsJoinField: string | null; - leftEmsFileId: string | null; - leftEmsJoinField: string | null; + leftJoinFields: IFieldType[]; + leftGeoField: string | null; + leftJoinField: string | null; rightIndexPatternId: string | null; - rightKey: string | null; + rightJoinField: string | null; } export class LayerTemplate extends Component { state = { leftSource: BOUNDARIES_SOURCE.ELASTICSEARCH, + leftEmsFileId: null, leftIndexPattern: null, leftGeoFields: [], - leftTermsFields: [], - leftGeofieldName: null, - leftEsJoinField: null, - leftEmsFileId: null, - leftEmsJoinField: null, + leftJoinFields: [], + leftGeoField: null, + leftJoinField: null, rightIndexPatternId: null, - rightKey: null, + rightJoinField: null, }; _onLeftSourceChange = (optionId: string) => { @@ -67,7 +67,29 @@ export class LayerTemplate extends Component { }; _onLeftIndexPatternChange = (indexPattern: IndexPattern) => { - this.setState({ leftIndexPattern: indexPattern }, this._previewLayer); + this.setState( + { + leftIndexPattern: indexPattern, + leftGeoFields: getGeoFields(indexPattern.fields), + leftJoinFields: getSourceFields(indexPattern.fields), + leftGeoField: null, + leftJoinField: null, + }, + () => { + // make default geo field selection + if (this.state.leftGeoFields.length) { + this._onLeftGeoFieldSelect(this.state.leftGeoFields[0].name); + } + } + ); + }; + + _onLeftGeoFieldSelect = (geoField: string) => { + this.setState({ leftGeoField: geoField }, this._previewLayer); + }; + + _onLeftJoinFieldSelect = (joinField: string) => { + this.setState({ leftJoinField: joinField }, this._previewLayer); }; _onEmsFileChange = (emFileId: string) => { @@ -77,17 +99,15 @@ export class LayerTemplate extends Component { _isLeftConfigComplete() { if (this.state.leftSource === BOUNDARIES_SOURCE.ELASTICSEARCH) { return ( - !!this.state.leftIndexPattern && - !!this.state.leftGeofieldName && - !!this.state.leftEsJoinField + !!this.state.leftIndexPattern && !!this.state.leftGeoField && !!this.state.leftJoinField ); } else { - return !!this.state.leftEmsFileId && !!this.state.leftEmsFileId; + return !!this.state.leftEmsFileId && !!this.state.leftJoinField; } } _isRightConfigComplete() { - return !!this.state.rightIndexPatternId && !!this.state.rightKey; + return !!this.state.rightIndexPatternId && !!this.state.rightJoinField; } _previewLayer() { @@ -105,11 +125,55 @@ export class LayerTemplate extends Component { _renderLeftSource() { if (this.state.leftSource === BOUNDARIES_SOURCE.ELASTICSEARCH) { + let geoFieldSelect; + if (this.state.leftGeoFields.length) { + geoFieldSelect = ( + + + + ); + } + let joinFieldSelect; + if (this.state.leftJoinFields.length) { + joinFieldSelect = ( + + + + ); + } return ( - + <> + + {geoFieldSelect} + {joinFieldSelect} + ); } else { return ; From 1339ce095a28408ce22145cc382d66e6a7d5e7f7 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Thu, 18 Jun 2020 16:21:10 -0600 Subject: [PATCH 07/19] move EuiPanel into render wizard --- .../layer_template.tsx | 61 ++++++++++++++++--- .../observability_layer_template.tsx | 7 ++- .../security/security_layer_template.tsx | 7 ++- .../upload_layer_wizard.tsx | 17 +++--- .../ems_file_source/create_source_editor.tsx | 11 ++-- .../ems_tms_source/tile_service_select.js | 38 ++++++------ .../create_source_editor.js | 8 +-- .../es_pew_pew_source/create_source_editor.js | 6 +- .../es_search_source/create_source_editor.js | 6 +- .../create_source_editor.js | 30 ++++----- .../create_source_editor.js | 34 ++++++----- .../mvt_single_layer_vector_source_editor.tsx | 8 +-- .../wms_source/wms_create_source_editor.js | 6 +- .../sources/xyz_tms_source/xyz_tms_editor.tsx | 8 +-- .../flyout_body/flyout_body.tsx | 4 +- 15 files changed, 152 insertions(+), 99 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx index 03bfb305514e10..98f46c91e71630 100644 --- a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx +++ b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx @@ -6,7 +6,8 @@ import React, { Component, Fragment } from 'react'; import { i18n } from '@kbn/i18n'; -import { EuiFormRow, EuiRadioGroup } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { EuiFormRow, EuiPanel, EuiRadioGroup, EuiSpacer, EuiTitle } from '@elastic/eui'; import { IFieldType, IndexPattern } from 'src/plugins/data/public'; import { RenderWizardArguments } from '../../layer_wizard_registry'; import { EMSFileSelect } from '../../../components/ems_file_select'; @@ -123,7 +124,7 @@ export class LayerTemplate extends Component { this.props.previewLayers(layerDescriptor ? [layerDescriptor] : []);*/ } - _renderLeftSource() { + _renderLeftSourceForm() { if (this.state.leftSource === BOUNDARIES_SOURCE.ELASTICSEARCH) { let geoFieldSelect; if (this.state.leftGeoFields.length) { @@ -180,14 +181,21 @@ export class LayerTemplate extends Component { } } - render() { + _renderLeftPanel() { return ( - <> - + + +
+ +
+
+ + + + { /> - {this._renderLeftSource()} + {this._renderLeftSourceForm()} +
+ ); + } + + _renderRightPanel() { + if (!this._isLeftConfigComplete()) { + return null; + } + + return ( + + +
+ +
+
+ + +
+ ); + } + + render() { + return ( + <> + {this._renderLeftPanel()} + + + + {this._renderRightPanel()} ); } diff --git a/x-pack/plugins/maps/public/classes/layers/solution_layers/observability/observability_layer_template.tsx b/x-pack/plugins/maps/public/classes/layers/solution_layers/observability/observability_layer_template.tsx index 3f3c556dcae1e5..3fe640a135aa61 100644 --- a/x-pack/plugins/maps/public/classes/layers/solution_layers/observability/observability_layer_template.tsx +++ b/x-pack/plugins/maps/public/classes/layers/solution_layers/observability/observability_layer_template.tsx @@ -4,7 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { Component, Fragment } from 'react'; +import React, { Component } from 'react'; +import { EuiPanel } from '@elastic/eui'; import { RenderWizardArguments } from '../../layer_wizard_registry'; import { LayerSelect, OBSERVABILITY_LAYER_TYPE } from './layer_select'; import { getMetricOptionsForLayer, MetricSelect, OBSERVABILITY_METRIC_TYPE } from './metric_select'; @@ -63,7 +64,7 @@ export class ObservabilityLayerTemplate extends Component + -
+ ); } } diff --git a/x-pack/plugins/maps/public/classes/layers/solution_layers/security/security_layer_template.tsx b/x-pack/plugins/maps/public/classes/layers/solution_layers/security/security_layer_template.tsx index eda489c88fda22..b20f57f4c276d7 100644 --- a/x-pack/plugins/maps/public/classes/layers/solution_layers/security/security_layer_template.tsx +++ b/x-pack/plugins/maps/public/classes/layers/solution_layers/security/security_layer_template.tsx @@ -4,7 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { Component, Fragment } from 'react'; +import React, { Component } from 'react'; +import { EuiPanel } from '@elastic/eui'; import { RenderWizardArguments } from '../../layer_wizard_registry'; import { IndexPatternSelect } from './index_pattern_select'; import { createSecurityLayerDescriptors } from './create_layer_descriptors'; @@ -44,12 +45,12 @@ export class SecurityLayerTemplate extends Component + -
+ ); } } diff --git a/x-pack/plugins/maps/public/classes/sources/client_file_source/upload_layer_wizard.tsx b/x-pack/plugins/maps/public/classes/sources/client_file_source/upload_layer_wizard.tsx index 0a224f75b981d6..2d0bb1ee67e864 100644 --- a/x-pack/plugins/maps/public/classes/sources/client_file_source/upload_layer_wizard.tsx +++ b/x-pack/plugins/maps/public/classes/sources/client_file_source/upload_layer_wizard.tsx @@ -7,6 +7,7 @@ import { i18n } from '@kbn/i18n'; import React from 'react'; import { IFieldType } from 'src/plugins/data/public'; +import { EuiPanel } from '@elastic/eui'; import { ES_GEO_FIELD_TYPE, DEFAULT_MAX_RESULT_WINDOW, @@ -92,13 +93,15 @@ export const uploadLayerWizardConfig: LayerWizard = { } return ( - + + + ); }, title: i18n.translate('xpack.maps.source.geojsonFileTitle', { diff --git a/x-pack/plugins/maps/public/classes/sources/ems_file_source/create_source_editor.tsx b/x-pack/plugins/maps/public/classes/sources/ems_file_source/create_source_editor.tsx index e18b99cba838a3..841c774479fcee 100644 --- a/x-pack/plugins/maps/public/classes/sources/ems_file_source/create_source_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/ems_file_source/create_source_editor.tsx @@ -5,7 +5,7 @@ */ import React, { Component } from 'react'; -import { EuiComboBox, EuiComboBoxOptionOption, EuiFormRow } from '@elastic/eui'; +import { EuiComboBox, EuiComboBoxOptionOption, EuiFormRow, EuiPanel } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FileLayer } from '@elastic/ems-client'; @@ -23,18 +23,19 @@ interface State { } export class EMSFileCreateSourceEditor extends Component { - private _isMounted: boolean = false; - state = { emsFileId: null, }; _onChange = (emsFileId: string) => { - this.setState({ emsFileId }); this.props.onSourceConfigChange({ id: emsFileId }); }; render() { - return ; + return ( + + + + ); } } diff --git a/x-pack/plugins/maps/public/classes/sources/ems_tms_source/tile_service_select.js b/x-pack/plugins/maps/public/classes/sources/ems_tms_source/tile_service_select.js index 1eff4bf3786f46..2b54e00cae7394 100644 --- a/x-pack/plugins/maps/public/classes/sources/ems_tms_source/tile_service_select.js +++ b/x-pack/plugins/maps/public/classes/sources/ems_tms_source/tile_service_select.js @@ -5,7 +5,7 @@ */ import React from 'react'; -import { EuiSelect, EuiFormRow } from '@elastic/eui'; +import { EuiSelect, EuiFormRow, EuiPanel } from '@elastic/eui'; import { getEmsTmsServices } from '../../../meta'; import { getEmsUnavailableMessage } from '../../../components/ems_unavailable_message'; @@ -71,23 +71,25 @@ export class TileServiceSelect extends React.Component { } return ( - - - + + + + + ); } } diff --git a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/create_source_editor.js b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/create_source_editor.js index 72468451d0b176..ebe312d73eccea 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/create_source_editor.js +++ b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/create_source_editor.js @@ -4,14 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { Fragment, Component } from 'react'; +import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { SingleFieldSelect } from '../../../components/single_field_select'; import { GeoIndexPatternSelect } from '../../../components/geo_index_pattern_select'; import { i18n } from '@kbn/i18n'; -import { EuiFormRow } from '@elastic/eui'; +import { EuiFormRow, EuiPanel } from '@elastic/eui'; import { getFieldsWithGeoTileAgg, getGeoFields, @@ -115,14 +115,14 @@ export class CreateSourceEditor extends Component { render() { return ( - + {this._renderGeoSelect()} {this._renderRenderAsSelect()} - + ); } } diff --git a/x-pack/plugins/maps/public/classes/sources/es_pew_pew_source/create_source_editor.js b/x-pack/plugins/maps/public/classes/sources/es_pew_pew_source/create_source_editor.js index 38a5850537200b..3fe3d536ff8098 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_pew_pew_source/create_source_editor.js +++ b/x-pack/plugins/maps/public/classes/sources/es_pew_pew_source/create_source_editor.js @@ -13,7 +13,7 @@ import { getIndexPatternService, getIndexPatternSelectComponent } from '../../.. import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { EuiFormRow, EuiCallOut } from '@elastic/eui'; +import { EuiFormRow, EuiCallOut, EuiPanel } from '@elastic/eui'; import { getFieldsWithGeoTileAgg } from '../../../index_pattern_util'; import { ES_GEO_FIELD_TYPE } from '../../../../common/constants'; @@ -200,11 +200,11 @@ export class CreateSourceEditor extends Component { } return ( - + {callout} {this._renderIndexPatternSelect()} {this._renderGeoSelects()} - + ); } } diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/create_source_editor.js b/x-pack/plugins/maps/public/classes/sources/es_search_source/create_source_editor.js index 54ce4a9b02ac46..0423d70b3f4276 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/create_source_editor.js +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/create_source_editor.js @@ -6,7 +6,7 @@ import React, { Fragment, Component } from 'react'; import PropTypes from 'prop-types'; -import { EuiFormRow, EuiSpacer } from '@elastic/eui'; +import { EuiFormRow, EuiPanel, EuiSpacer } from '@elastic/eui'; import { SingleFieldSelect } from '../../../components/single_field_select'; import { GeoIndexPatternSelect } from '../../../components/geo_index_pattern_select'; @@ -176,7 +176,7 @@ export class CreateSourceEditor extends Component { render() { return ( - + + ); } } diff --git a/x-pack/plugins/maps/public/classes/sources/kibana_regionmap_source/create_source_editor.js b/x-pack/plugins/maps/public/classes/sources/kibana_regionmap_source/create_source_editor.js index 5e28916e79f3f8..82f80e7fe484b5 100644 --- a/x-pack/plugins/maps/public/classes/sources/kibana_regionmap_source/create_source_editor.js +++ b/x-pack/plugins/maps/public/classes/sources/kibana_regionmap_source/create_source_editor.js @@ -6,7 +6,7 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { EuiSelect, EuiFormRow } from '@elastic/eui'; +import { EuiSelect, EuiFormRow, EuiPanel } from '@elastic/eui'; import { getKibanaRegionList } from '../../../meta'; import { i18n } from '@kbn/i18n'; @@ -31,19 +31,21 @@ export function CreateSourceEditor({ onSourceConfigChange }) { : null; return ( - - - + + + + + ); } diff --git a/x-pack/plugins/maps/public/classes/sources/kibana_tilemap_source/create_source_editor.js b/x-pack/plugins/maps/public/classes/sources/kibana_tilemap_source/create_source_editor.js index a0a507ff9d32d7..1cbf4c1a87de31 100644 --- a/x-pack/plugins/maps/public/classes/sources/kibana_tilemap_source/create_source_editor.js +++ b/x-pack/plugins/maps/public/classes/sources/kibana_tilemap_source/create_source_editor.js @@ -6,7 +6,7 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { EuiFieldText, EuiFormRow } from '@elastic/eui'; +import { EuiFieldText, EuiFormRow, EuiPanel } from '@elastic/eui'; import { getKibanaTileMap } from '../../../meta'; import { i18n } from '@kbn/i18n'; @@ -19,21 +19,23 @@ export function CreateSourceEditor({ onSourceConfigChange }) { } return ( - - - + + + + + ); } 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 7a4b8d43811da8..760b8c676cb37e 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 @@ -5,9 +5,9 @@ */ /* eslint-disable @typescript-eslint/consistent-type-definitions */ -import React, { Fragment, Component, ChangeEvent } from 'react'; +import React, { Component, ChangeEvent } from 'react'; import _ from 'lodash'; -import { EuiFieldText, EuiFormRow } from '@elastic/eui'; +import { EuiFieldText, EuiFormRow, EuiPanel } 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'; @@ -85,7 +85,7 @@ export class MVTSingleLayerVectorSourceEditor extends Component { render() { return ( - + { } )} /> - + ); } } diff --git a/x-pack/plugins/maps/public/classes/sources/wms_source/wms_create_source_editor.js b/x-pack/plugins/maps/public/classes/sources/wms_source/wms_create_source_editor.js index df00faf43daa38..ce9af42117683c 100644 --- a/x-pack/plugins/maps/public/classes/sources/wms_source/wms_create_source_editor.js +++ b/x-pack/plugins/maps/public/classes/sources/wms_source/wms_create_source_editor.js @@ -13,7 +13,7 @@ import { EuiComboBox, EuiFieldText, EuiFormRow, - EuiForm, + EuiPanel, EuiSpacer, } from '@elastic/eui'; import { WmsClient } from './wms_client'; @@ -289,7 +289,7 @@ export class WMSCreateSourceEditor extends Component { render() { return ( - + + ); } } diff --git a/x-pack/plugins/maps/public/classes/sources/xyz_tms_source/xyz_tms_editor.tsx b/x-pack/plugins/maps/public/classes/sources/xyz_tms_source/xyz_tms_editor.tsx index 715ff0e4c2fdd4..bf5f2c3dfe04d5 100644 --- a/x-pack/plugins/maps/public/classes/sources/xyz_tms_source/xyz_tms_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/xyz_tms_source/xyz_tms_editor.tsx @@ -5,9 +5,9 @@ */ /* eslint-disable @typescript-eslint/consistent-type-definitions */ -import React, { Fragment, Component, ChangeEvent } from 'react'; +import React, { Component, ChangeEvent } from 'react'; import _ from 'lodash'; -import { EuiFormRow, EuiFieldText } from '@elastic/eui'; +import { EuiFormRow, EuiFieldText, EuiPanel } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { AttributionDescriptor } from '../../../../common/descriptor_types'; @@ -77,7 +77,7 @@ export class XYZTMSEditor extends Component { render() { const { attributionText, attributionUrl } = this.state; return ( - + { } /> - + ); } } diff --git a/x-pack/plugins/maps/public/connected_components/add_layer_panel/flyout_body/flyout_body.tsx b/x-pack/plugins/maps/public/connected_components/add_layer_panel/flyout_body/flyout_body.tsx index b287064938ce55..b885c2c35499f6 100644 --- a/x-pack/plugins/maps/public/connected_components/add_layer_panel/flyout_body/flyout_body.tsx +++ b/x-pack/plugins/maps/public/connected_components/add_layer_panel/flyout_body/flyout_body.tsx @@ -5,7 +5,7 @@ */ import React, { Fragment } from 'react'; -import { EuiButtonEmpty, EuiPanel, EuiSpacer } from '@elastic/eui'; +import { EuiButtonEmpty, EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { LayerWizardSelect } from './layer_wizard_select'; import { LayerWizard, RenderWizardArguments } from '../../../classes/layers/layer_wizard_registry'; @@ -48,7 +48,7 @@ export const FlyoutBody = (props: Props) => { return ( {backButton} - {props.layerWizard.renderWizard(renderWizardArgs)} + {props.layerWizard.renderWizard(renderWizardArgs)} ); } From f8f16f6930ec6d8b0b56323aacf88faa21d5c86c Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 23 Jun 2020 06:55:33 -0600 Subject: [PATCH 08/19] cleanup --- .../layer_template.tsx | 98 +++++++++++++++++-- 1 file changed, 92 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx index 98f46c91e71630..8daeac10539a77 100644 --- a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx +++ b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx @@ -7,7 +7,16 @@ import React, { Component, Fragment } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { EuiFormRow, EuiPanel, EuiRadioGroup, EuiSpacer, EuiTitle } from '@elastic/eui'; +import { FileLayer } from '@elastic/ems-client'; +import { + EuiComboBox, + EuiComboBoxOptionOption, + EuiFormRow, + EuiPanel, + EuiRadioGroup, + EuiSpacer, + EuiTitle, +} from '@elastic/eui'; import { IFieldType, IndexPattern } from 'src/plugins/data/public'; import { RenderWizardArguments } from '../../layer_wizard_registry'; import { EMSFileSelect } from '../../../components/ems_file_select'; @@ -15,6 +24,7 @@ import { GeoIndexPatternSelect } from '../../../components/geo_index_pattern_sel import { SingleFieldSelect } from '../../../components/single_field_select'; import { getIndexPatternSelectComponent } from '../../../kibana_services'; import { getGeoFields, getSourceFields } from '../../../index_pattern_util'; +import { getEmsFileLayers } from '../../../meta'; export enum BOUNDARIES_SOURCE { ELASTICSEARCH = 'ELASTICSEARCH', @@ -41,6 +51,7 @@ const IndexPatternSelect = getIndexPatternSelectComponent(); interface State { leftSource: BOUNDARIES_SOURCE; leftEmsFileId: string | null; + leftEmsFields: Array>; leftIndexPattern: IndexPattern | null; leftGeoFields: IFieldType[]; leftJoinFields: IFieldType[]; @@ -51,9 +62,12 @@ interface State { } export class LayerTemplate extends Component { + private _isMounted: boolean = false; + state = { leftSource: BOUNDARIES_SOURCE.ELASTICSEARCH, leftEmsFileId: null, + leftEmsFields: [], leftIndexPattern: null, leftGeoFields: [], leftJoinFields: [], @@ -63,8 +77,41 @@ export class LayerTemplate extends Component { rightJoinField: null, }; + componentWillUnmount() { + this._isMounted = false; + } + + componentDidMount() { + this._isMounted = true; + } + + _loadEmsFileFields = async () => { + const emsFileLayers = await getEmsFileLayers(); + const emsFileLayer = emsFileLayers.find((fileLayer: FileLayer) => { + return fileLayer.getId() === this.state.leftEmsFileId; + }); + + if (!this._isMounted || !emsFileLayer) { + return; + } + + const fields = emsFileLayer.getFieldsInLanguage(); + this.setState({ + leftEmsFields: fields + .filter((field) => { + return field.type === 'id'; + }) + .map((field) => { + return { + value: field.name, + label: field.description, + }; + }), + }); + }; + _onLeftSourceChange = (optionId: string) => { - this.setState({ leftSource: optionId }, this._previewLayer); + this.setState({ leftSource: optionId, leftJoinField: null }); }; _onLeftIndexPatternChange = (indexPattern: IndexPattern) => { @@ -93,8 +140,16 @@ export class LayerTemplate extends Component { this.setState({ leftJoinField: joinField }, this._previewLayer); }; - _onEmsFileChange = (emFileId: string) => { - this.setState({ leftEmsFileId: emFileId }, this._previewLayer); + _onLeftEmsFileChange = (emFileId: string) => { + this.setState({ leftEmsFileId: emFileId, leftJoinField: null }, this._loadEmsFileFields); + }; + + _onLeftEmsFieldChange = (selectedOptions: Array>) => { + if (selectedOptions.length === 0) { + return; + } + + this.setState({ leftJoinField: selectedOptions[0].value }, this._previewLayer); }; _isLeftConfigComplete() { @@ -151,7 +206,7 @@ export class LayerTemplate extends Component { joinFieldSelect = ( { ); } else { - return ; + let emsFieldSelect; + if (this.state.leftEmsFields.length) { + let selectedOption; + if (this.state.leftJoinField) { + selectedOption = this.state.leftEmsFields.find( + (option: EuiComboBoxOptionOption) => { + return this.state.leftJoinField === option.value; + } + ); + } + emsFieldSelect = ( + + + + ); + } + return ( + <> + + {emsFieldSelect} + + ); } } From de436ccd363fea95faea1d4aae1d2f3601078ea4 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 23 Jun 2020 08:38:33 -0600 Subject: [PATCH 09/19] right panel --- .../layer_template.tsx | 96 +++++++++++++++++-- .../components/geo_index_pattern_select.tsx | 2 +- 2 files changed, 91 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx index 8daeac10539a77..65c99ae893dccd 100644 --- a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx +++ b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx @@ -22,9 +22,9 @@ import { RenderWizardArguments } from '../../layer_wizard_registry'; import { EMSFileSelect } from '../../../components/ems_file_select'; import { GeoIndexPatternSelect } from '../../../components/geo_index_pattern_select'; import { SingleFieldSelect } from '../../../components/single_field_select'; -import { getIndexPatternSelectComponent } from '../../../kibana_services'; -import { getGeoFields, getSourceFields } from '../../../index_pattern_util'; +import { getGeoFields, getSourceFields, getTermsFields } from '../../../index_pattern_util'; import { getEmsFileLayers } from '../../../meta'; +import { getIndexPatternSelectComponent, getIndexPatternService } from '../../../kibana_services'; export enum BOUNDARIES_SOURCE { ELASTICSEARCH = 'ELASTICSEARCH', @@ -46,8 +46,6 @@ const BOUNDARIES_OPTIONS = [ }, ]; -const IndexPatternSelect = getIndexPatternSelectComponent(); - interface State { leftSource: BOUNDARIES_SOURCE; leftEmsFileId: string | null; @@ -58,6 +56,7 @@ interface State { leftGeoField: string | null; leftJoinField: string | null; rightIndexPatternId: string | null; + rightTermsFields: IFieldType[]; rightJoinField: string | null; } @@ -74,6 +73,7 @@ export class LayerTemplate extends Component { leftGeoField: null, leftJoinField: null, rightIndexPatternId: null, + rightTermsFields: [], rightJoinField: null, }; @@ -85,6 +85,27 @@ export class LayerTemplate extends Component { this._isMounted = true; } + _loadRightFields = async (indexPatternId) => { + this.setState({ rightTermsFields: [] }); + + let indexPattern; + try { + indexPattern = await getIndexPatternService().get(indexPatternId); + } catch (err) { + return; + } + + // method may be called again before 'get' returns + // ignore response when fetched index pattern does not match active index pattern + if (!this._isMounted || indexPatternId !== this.state.rightIndexPatternId) { + return; + } + + this.setState({ + rightTermsFields: getTermsFields(indexPattern.fields), + }); + }; + _loadEmsFileFields = async () => { const emsFileLayers = await getEmsFileLayers(); const emsFileLayer = emsFileLayers.find((fileLayer: FileLayer) => { @@ -111,7 +132,7 @@ export class LayerTemplate extends Component { }; _onLeftSourceChange = (optionId: string) => { - this.setState({ leftSource: optionId, leftJoinField: null }); + this.setState({ leftSource: optionId, leftJoinField: null, rightJoinField: null }); }; _onLeftIndexPatternChange = (indexPattern: IndexPattern) => { @@ -122,6 +143,7 @@ export class LayerTemplate extends Component { leftJoinFields: getSourceFields(indexPattern.fields), leftGeoField: null, leftJoinField: null, + rightJoinField: null, }, () => { // make default geo field selection @@ -141,7 +163,10 @@ export class LayerTemplate extends Component { }; _onLeftEmsFileChange = (emFileId: string) => { - this.setState({ leftEmsFileId: emFileId, leftJoinField: null }, this._loadEmsFileFields); + this.setState( + { leftEmsFileId: emFileId, leftJoinField: null, rightJoinField: null }, + this._loadEmsFileFields + ); }; _onLeftEmsFieldChange = (selectedOptions: Array>) => { @@ -152,6 +177,26 @@ export class LayerTemplate extends Component { this.setState({ leftJoinField: selectedOptions[0].value }, this._previewLayer); }; + _onRightIndexPatternChange = (indexPatternId: string) => { + if (!indexPatternId) { + return; + } + + this.setState( + { + rightIndexPatternId: indexPatternId, + rightJoinField: null, + }, + () => { + this._loadRightFields(indexPatternId); + } + ); + }; + + _onRightJoinFieldSelect = (joinField: string) => { + this.setState({ rightJoinField: joinField }, this._previewLayer); + }; + _isLeftConfigComplete() { if (this.state.leftSource === BOUNDARIES_SOURCE.ELASTICSEARCH) { return ( @@ -298,6 +343,28 @@ export class LayerTemplate extends Component { if (!this._isLeftConfigComplete()) { return null; } + const IndexPatternSelect = getIndexPatternSelectComponent(); + + let joinFieldSelect; + if (this.state.rightTermsFields.length) { + joinFieldSelect = ( + + + + ); + } return ( @@ -311,6 +378,23 @@ export class LayerTemplate extends Component { + + + + + + {joinFieldSelect} ); } diff --git a/x-pack/plugins/maps/public/components/geo_index_pattern_select.tsx b/x-pack/plugins/maps/public/components/geo_index_pattern_select.tsx index 7cf085a035c353..2dbb85575f86db 100644 --- a/x-pack/plugins/maps/public/components/geo_index_pattern_select.tsx +++ b/x-pack/plugins/maps/public/components/geo_index_pattern_select.tsx @@ -52,7 +52,7 @@ export class GeoIndexPatternSelect extends Component { return; } - // method may be called again before get returns + // method may be called again before 'get' returns // ignore response when fetched index pattern does not match active index pattern if (this._isMounted && indexPattern.id === indexPatternId) { this.props.onChange(indexPattern); From f42cb7ac79489dee2e42eb8ac308fa7750e092bd Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 23 Jun 2020 09:22:09 -0600 Subject: [PATCH 10/19] createEmsChoroplethLayerDescriptor --- .../create_choropleth_layer_descriptor.ts | 111 ++++++++++++++++++ .../layer_template.tsx | 26 ++-- 2 files changed, 129 insertions(+), 8 deletions(-) create mode 100644 x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/create_choropleth_layer_descriptor.ts diff --git a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/create_choropleth_layer_descriptor.ts b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/create_choropleth_layer_descriptor.ts new file mode 100644 index 00000000000000..c7c4c702e821f6 --- /dev/null +++ b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/create_choropleth_layer_descriptor.ts @@ -0,0 +1,111 @@ +/* + * 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 uuid from 'uuid/v4'; +import { + AGG_TYPE, + COLOR_MAP_TYPE, + FIELD_ORIGIN, + SOURCE_TYPES, + STYLE_TYPE, + VECTOR_STYLES, +} from '../../../../common/constants'; +import { getJoinAggKey, getSourceAggKey } from '../../../../common/get_agg_key'; +import { + ColorDynamicOptions, + EMSFileSourceDescriptor, + ESSearchSourceDescriptor, + JoinDescriptor, +} from '../../../../common/descriptor_types'; +import { VectorStyle } from '../../styles/vector/vector_style'; +import { VectorLayer } from '../vector_layer/vector_layer'; +import { EMSFileSource } from '../../sources/ems_file_source'; +import { getDefaultDynamicProperties } from '../../styles/vector/vector_style_defaults'; + +const defaultDynamicProperties = getDefaultDynamicProperties(); + +function createChoroplethLayerDescriptor({ + sourceDescriptor, + leftField, + rightIndexPatternId, + rightIndexPatternTitle, + rightTermField, +}: { + sourceDescriptor: EMSFileSourceDescriptor | ESSearchSourceDescriptor; + leftField: string; + rightIndexPatternId: string; + rightIndexPatternTitle: string; + rightTermField: string; +}) { + const metricsDescriptor = { type: AGG_TYPE.COUNT }; + const joinId = uuid(); + const joinKey = getJoinAggKey({ + aggType: metricsDescriptor.type, + aggFieldName: metricsDescriptor.field ? metricsDescriptor.field : '', + rightSourceId: joinId, + }); + return VectorLayer.createDescriptor({ + joins: [ + { + leftField, + right: { + type: SOURCE_TYPES.ES_TERM_SOURCE, + id: joinId, + indexPatternId: rightIndexPatternId, + indexPatternTitle: rightIndexPatternTitle, + term: rightTermField, + metrics: [metricsDescriptor], + }, + }, + ], + sourceDescriptor, + style: VectorStyle.createDescriptor({ + [VECTOR_STYLES.FILL_COLOR]: { + type: STYLE_TYPE.DYNAMIC, + options: { + ...(defaultDynamicProperties[VECTOR_STYLES.FILL_COLOR]!.options as ColorDynamicOptions), + field: { + name: joinKey, + origin: FIELD_ORIGIN.JOIN, + }, + color: 'Yellow to Red', + type: COLOR_MAP_TYPE.ORDINAL, + }, + }, + [VECTOR_STYLES.LINE_COLOR]: { + type: STYLE_TYPE.STATIC, + options: { + color: '#3d3d3d', + }, + }, + }), + }); +} + +export function createEmsChoroplethLayerDescriptor({ + emsFileId, + emsField, + rightIndexPatternId, + rightIndexPatternTitle, + rightTermField, +}: { + emsFileId: string; + emsField: string; + rightIndexPatternId: string; + rightIndexPatternTitle: string; + rightTermField: string; +}) { + return createChoroplethLayerDescriptor({ + sourceDescriptor: EMSFileSource.createDescriptor({ + id: emsFileId, + tooltipProperties: [emsField], + }), + leftField: emsField, + rightIndexPatternId, + rightIndexPatternTitle, + rightTermField, + }); +} diff --git a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx index 65c99ae893dccd..70eb010a60703d 100644 --- a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx +++ b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx @@ -25,6 +25,7 @@ import { SingleFieldSelect } from '../../../components/single_field_select'; import { getGeoFields, getSourceFields, getTermsFields } from '../../../index_pattern_util'; import { getEmsFileLayers } from '../../../meta'; import { getIndexPatternSelectComponent, getIndexPatternService } from '../../../kibana_services'; +import { createEmsChoroplethLayerDescriptor } from './create_choropleth_layer_descriptor'; export enum BOUNDARIES_SOURCE { ELASTICSEARCH = 'ELASTICSEARCH', @@ -56,6 +57,7 @@ interface State { leftGeoField: string | null; leftJoinField: string | null; rightIndexPatternId: string | null; + rightIndexPatternTitle: string | null; rightTermsFields: IFieldType[]; rightJoinField: string | null; } @@ -73,6 +75,7 @@ export class LayerTemplate extends Component { leftGeoField: null, leftJoinField: null, rightIndexPatternId: null, + rightIndexPatternTitle: null, rightTermsFields: [], rightJoinField: null, }; @@ -86,7 +89,7 @@ export class LayerTemplate extends Component { } _loadRightFields = async (indexPatternId) => { - this.setState({ rightTermsFields: [] }); + this.setState({ rightTermsFields: [], rightIndexPatternTitle: null }); let indexPattern; try { @@ -103,6 +106,7 @@ export class LayerTemplate extends Component { this.setState({ rightTermsFields: getTermsFields(indexPattern.fields), + rightIndexPatternTitle: indexPattern.title, }); }; @@ -213,15 +217,21 @@ export class LayerTemplate extends Component { _previewLayer() { if (!this._isLeftConfigComplete() || !this._isRightConfigComplete()) { - return; + return []; } - /* const layerDescriptor = createLayerDescriptor({ - layer: this.state.layer, - metric: this.state.metric, - display: this.state.display, - }); - this.props.previewLayers(layerDescriptor ? [layerDescriptor] : []);*/ + const layerDescriptor = + this.state.leftSource === BOUNDARIES_SOURCE.ELASTICSEARCH + ? null + : createEmsChoroplethLayerDescriptor({ + emsFileId: this.state.leftEmsFileId, + emsField: this.state.leftJoinField, + rightIndexPatternId: this.state.rightIndexPatternId, + rightIndexPatternTitle: this.state.rightIndexPatternTitle, + rightTermField: this.state.rightJoinField, + }); + + this.props.previewLayers([layerDescriptor]); } _renderLeftSourceForm() { From 6aa28cb265e2d4c25f712c28cb79cecfd670ff53 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 23 Jun 2020 09:36:56 -0600 Subject: [PATCH 11/19] createEsChoroplethLayerDescriptor --- .../create_choropleth_layer_descriptor.ts | 45 ++++++++++++++++--- .../layer_template.tsx | 35 ++++++++++----- 2 files changed, 63 insertions(+), 17 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/create_choropleth_layer_descriptor.ts b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/create_choropleth_layer_descriptor.ts index c7c4c702e821f6..ad19cc9c8377f1 100644 --- a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/create_choropleth_layer_descriptor.ts +++ b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/create_choropleth_layer_descriptor.ts @@ -9,6 +9,7 @@ import { AGG_TYPE, COLOR_MAP_TYPE, FIELD_ORIGIN, + SCALING_TYPES, SOURCE_TYPES, STYLE_TYPE, VECTOR_STYLES, @@ -23,6 +24,7 @@ import { import { VectorStyle } from '../../styles/vector/vector_style'; import { VectorLayer } from '../vector_layer/vector_layer'; import { EMSFileSource } from '../../sources/ems_file_source'; +import { ESSearchSource } from '../../sources/es_search_source'; import { getDefaultDynamicProperties } from '../../styles/vector/vector_style_defaults'; const defaultDynamicProperties = getDefaultDynamicProperties(); @@ -86,24 +88,53 @@ function createChoroplethLayerDescriptor({ } export function createEmsChoroplethLayerDescriptor({ - emsFileId, - emsField, + leftEmsFileId, + leftEmsField, rightIndexPatternId, rightIndexPatternTitle, rightTermField, }: { - emsFileId: string; - emsField: string; + leftEmsFileId: string; + leftEmsField: string; rightIndexPatternId: string; rightIndexPatternTitle: string; rightTermField: string; }) { return createChoroplethLayerDescriptor({ sourceDescriptor: EMSFileSource.createDescriptor({ - id: emsFileId, - tooltipProperties: [emsField], + id: leftEmsFileId, + tooltipProperties: [leftEmsField], }), - leftField: emsField, + leftField: leftEmsField, + rightIndexPatternId, + rightIndexPatternTitle, + rightTermField, + }); +} + +export function createEsChoroplethLayerDescriptor({ + leftIndexPatternId, + leftGeoField, + leftJoinField, + rightIndexPatternId, + rightIndexPatternTitle, + rightTermField, +}: { + leftIndexPatternId: string; + leftGeoField: string; + leftJoinField: string; + rightIndexPatternId: string; + rightIndexPatternTitle: string; + rightTermField: string; +}) { + return createChoroplethLayerDescriptor({ + sourceDescriptor: ESSearchSource.createDescriptor({ + indexPatternId: leftIndexPatternId, + geoField: leftGeoField, + scalingType: SCALING_TYPES.LIMIT, + tooltipProperties: [leftJoinField], + }), + leftField: leftJoinField, rightIndexPatternId, rightIndexPatternTitle, rightTermField, diff --git a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx index 70eb010a60703d..091352bb52173d 100644 --- a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx +++ b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx @@ -25,7 +25,10 @@ import { SingleFieldSelect } from '../../../components/single_field_select'; import { getGeoFields, getSourceFields, getTermsFields } from '../../../index_pattern_util'; import { getEmsFileLayers } from '../../../meta'; import { getIndexPatternSelectComponent, getIndexPatternService } from '../../../kibana_services'; -import { createEmsChoroplethLayerDescriptor } from './create_choropleth_layer_descriptor'; +import { + createEmsChoroplethLayerDescriptor, + createEsChoroplethLayerDescriptor, +} from './create_choropleth_layer_descriptor'; export enum BOUNDARIES_SOURCE { ELASTICSEARCH = 'ELASTICSEARCH', @@ -136,7 +139,10 @@ export class LayerTemplate extends Component { }; _onLeftSourceChange = (optionId: string) => { - this.setState({ leftSource: optionId, leftJoinField: null, rightJoinField: null }); + this.setState( + { leftSource: optionId, leftJoinField: null, rightJoinField: null }, + this._previewLayer + ); }; _onLeftIndexPatternChange = (indexPattern: IndexPattern) => { @@ -167,10 +173,10 @@ export class LayerTemplate extends Component { }; _onLeftEmsFileChange = (emFileId: string) => { - this.setState( - { leftEmsFileId: emFileId, leftJoinField: null, rightJoinField: null }, - this._loadEmsFileFields - ); + this.setState({ leftEmsFileId: emFileId, leftJoinField: null, rightJoinField: null }, () => { + this._previewLayer(); + this._loadEmsFileFields(); + }); }; _onLeftEmsFieldChange = (selectedOptions: Array>) => { @@ -192,6 +198,7 @@ export class LayerTemplate extends Component { rightJoinField: null, }, () => { + this._previewLayer(); this._loadRightFields(indexPatternId); } ); @@ -217,15 +224,23 @@ export class LayerTemplate extends Component { _previewLayer() { if (!this._isLeftConfigComplete() || !this._isRightConfigComplete()) { - return []; + this.props.previewLayers([]); + return; } const layerDescriptor = this.state.leftSource === BOUNDARIES_SOURCE.ELASTICSEARCH - ? null + ? createEsChoroplethLayerDescriptor({ + leftIndexPatternId: this.state.leftIndexPattern.id, + leftGeoField: this.state.leftGeoField, + leftJoinField: this.state.leftJoinField, + rightIndexPatternId: this.state.rightIndexPatternId, + rightIndexPatternTitle: this.state.rightIndexPatternTitle, + rightTermField: this.state.rightJoinField, + }) : createEmsChoroplethLayerDescriptor({ - emsFileId: this.state.leftEmsFileId, - emsField: this.state.leftJoinField, + leftEmsFileId: this.state.leftEmsFileId, + leftEmsField: this.state.leftJoinField, rightIndexPatternId: this.state.rightIndexPatternId, rightIndexPatternTitle: this.state.rightIndexPatternTitle, rightTermField: this.state.rightJoinField, From 8b7afb55eab1273626a2392ec93ae0eb4d4d33cc Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 23 Jun 2020 10:02:36 -0600 Subject: [PATCH 12/19] i18n cleanup --- x-pack/plugins/translations/translations/ja-JP.json | 4 ---- x-pack/plugins/translations/translations/zh-CN.json | 4 ---- 2 files changed, 8 deletions(-) diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 0567ee675ee759..d1d4227dad8bd7 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -9177,7 +9177,6 @@ "xpack.maps.source.ems.disabledDescription": "Elastic Maps Service へのアクセスが無効になっています。システム管理者に問い合わせるか、kibana.yml で「map.includeElasticMapsService」を設定してください。", "xpack.maps.source.ems.noAccessDescription": "Kibana が Elastic Maps Service にアクセスできません。システム管理者にお問い合わせください", "xpack.maps.source.emsFile.layerLabel": "レイヤー", - "xpack.maps.source.emsFile.selectPlaceholder": "EMS ベクターシェイプを選択", "xpack.maps.source.emsFile.unableToFindIdErrorMessage": "ID {id} の EMS ベクターシェイプが見つかりません", "xpack.maps.source.emsFileDescription": "Elastic Maps Service の行政区画のベクターシェイプ", "xpack.maps.source.emsFileTitle": "ベクターシェイプ", @@ -9193,8 +9192,6 @@ "xpack.maps.source.esGeoGrid.geofieldLabel": "地理空間フィールド", "xpack.maps.source.esGeoGrid.geofieldPlaceholder": "ジオフィールドを選択", "xpack.maps.source.esGeoGrid.gridRectangleDropdownOption": "グリッド", - "xpack.maps.source.esGeoGrid.indexPatternLabel": "インデックスパターン", - "xpack.maps.source.esGeoGrid.indexPatternPlaceholder": "インデックスパターンを選択", "xpack.maps.source.esGeoGrid.pointsDropdownOption": "クラスター", "xpack.maps.source.esGeoGrid.showAsLabel": "表示形式", "xpack.maps.source.esGrid.coarseDropdownOption": "粗い", @@ -9228,7 +9225,6 @@ "xpack.maps.source.esSearch.limitScalingLabel": "結果を {maxResultWindow} に限定。", "xpack.maps.source.esSearch.loadErrorMessage": "インデックスパターン {id} が見つかりません", "xpack.maps.source.esSearch.loadTooltipPropertiesErrorMsg": "ドキュメントが見つかりません。_id: {docId}", - "xpack.maps.source.esSearch.selectIndexPatternPlaceholder": "インデックスパターンを選択", "xpack.maps.source.esSearch.selectLabel": "ジオフィールドを選択", "xpack.maps.source.esSearch.sortFieldLabel": "フィールド", "xpack.maps.source.esSearch.sortFieldSelectPlaceholder": "ソートフィールドを選択", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 86f2c44c809da9..320627f5e1f752 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -9181,7 +9181,6 @@ "xpack.maps.source.ems.disabledDescription": "已禁用对 Elastic 地图服务的访问。让您的系统管理员在 kibana.yml 中设置“map.includeElasticMapsService”。", "xpack.maps.source.ems.noAccessDescription": "Kibana 无法访问 Elastic 地图服务。请联系您的系统管理员", "xpack.maps.source.emsFile.layerLabel": "图层", - "xpack.maps.source.emsFile.selectPlaceholder": "选择 EMS 矢量形状", "xpack.maps.source.emsFile.unableToFindIdErrorMessage": "找不到 ID {id} 的 EMS 矢量形状", "xpack.maps.source.emsFileDescription": "来自 Elastic 地图服务的管理边界的矢量形状", "xpack.maps.source.emsFileTitle": "矢量形状", @@ -9197,8 +9196,6 @@ "xpack.maps.source.esGeoGrid.geofieldLabel": "地理空间字段", "xpack.maps.source.esGeoGrid.geofieldPlaceholder": "选择地理字段", "xpack.maps.source.esGeoGrid.gridRectangleDropdownOption": "网格", - "xpack.maps.source.esGeoGrid.indexPatternLabel": "索引模式", - "xpack.maps.source.esGeoGrid.indexPatternPlaceholder": "选择索引模式", "xpack.maps.source.esGeoGrid.pointsDropdownOption": "集群", "xpack.maps.source.esGeoGrid.showAsLabel": "显示为", "xpack.maps.source.esGrid.coarseDropdownOption": "粗糙", @@ -9232,7 +9229,6 @@ "xpack.maps.source.esSearch.limitScalingLabel": "将结果数限制到 {maxResultWindow}。", "xpack.maps.source.esSearch.loadErrorMessage": "找不到索引模式 {id}", "xpack.maps.source.esSearch.loadTooltipPropertiesErrorMsg": "找不到文档,_id:{docId}", - "xpack.maps.source.esSearch.selectIndexPatternPlaceholder": "选择索引模式", "xpack.maps.source.esSearch.selectLabel": "选择地理字段", "xpack.maps.source.esSearch.sortFieldLabel": "字段", "xpack.maps.source.esSearch.sortFieldSelectPlaceholder": "选择排序字段", From abcb459882a4f535b8d625b43989b80cec31b824 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 23 Jun 2020 10:52:05 -0600 Subject: [PATCH 13/19] tslint --- .../choropleth_layer_wizard.tsx | 1 - .../create_choropleth_layer_descriptor.ts | 7 +-- .../layer_template.tsx | 52 ++++++++++++------- .../ems_file_source/create_source_editor.tsx | 8 +-- .../__snapshots__/scaling_form.test.tsx.snap | 1 + .../es_search_source/scaling_form.test.tsx | 1 + .../sources/es_search_source/scaling_form.tsx | 6 ++- .../public/components/ems_file_select.tsx | 5 +- .../components/geo_index_pattern_select.tsx | 2 +- .../public/components/single_field_select.tsx | 2 +- 10 files changed, 49 insertions(+), 36 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/choropleth_layer_wizard.tsx b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/choropleth_layer_wizard.tsx index fc20f125eb86d0..6e806f4530df25 100644 --- a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/choropleth_layer_wizard.tsx +++ b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/choropleth_layer_wizard.tsx @@ -9,7 +9,6 @@ import { i18n } from '@kbn/i18n'; import { LAYER_WIZARD_CATEGORY } from '../../../../common/constants'; import { LayerWizard, RenderWizardArguments } from '../layer_wizard_registry'; import { LayerTemplate } from './layer_template'; -import { getIndexPatternService } from '../../../kibana_services'; export const choroplethLayerWizardConfig: LayerWizard = { categories: [LAYER_WIZARD_CATEGORY.ELASTICSEARCH], diff --git a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/create_choropleth_layer_descriptor.ts b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/create_choropleth_layer_descriptor.ts index ad19cc9c8377f1..bc69b0b5c59d97 100644 --- a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/create_choropleth_layer_descriptor.ts +++ b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/create_choropleth_layer_descriptor.ts @@ -14,16 +14,17 @@ import { STYLE_TYPE, VECTOR_STYLES, } from '../../../../common/constants'; -import { getJoinAggKey, getSourceAggKey } from '../../../../common/get_agg_key'; +import { getJoinAggKey } from '../../../../common/get_agg_key'; import { + AggDescriptor, ColorDynamicOptions, EMSFileSourceDescriptor, ESSearchSourceDescriptor, - JoinDescriptor, } from '../../../../common/descriptor_types'; import { VectorStyle } from '../../styles/vector/vector_style'; import { VectorLayer } from '../vector_layer/vector_layer'; import { EMSFileSource } from '../../sources/ems_file_source'; +// @ts-ignore import { ESSearchSource } from '../../sources/es_search_source'; import { getDefaultDynamicProperties } from '../../styles/vector/vector_style_defaults'; @@ -42,7 +43,7 @@ function createChoroplethLayerDescriptor({ rightIndexPatternTitle: string; rightTermField: string; }) { - const metricsDescriptor = { type: AGG_TYPE.COUNT }; + const metricsDescriptor: AggDescriptor = { type: AGG_TYPE.COUNT }; const joinId = uuid(); const joinKey = getJoinAggKey({ aggType: metricsDescriptor.type, diff --git a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx index 091352bb52173d..c10d0c57832f87 100644 --- a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx +++ b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { Component, Fragment } from 'react'; +import React, { Component } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { FileLayer } from '@elastic/ems-client'; @@ -18,7 +18,7 @@ import { EuiTitle, } from '@elastic/eui'; import { IFieldType, IndexPattern } from 'src/plugins/data/public'; -import { RenderWizardArguments } from '../../layer_wizard_registry'; +import { RenderWizardArguments } from '../layer_wizard_registry'; import { EMSFileSelect } from '../../../components/ems_file_select'; import { GeoIndexPatternSelect } from '../../../components/geo_index_pattern_select'; import { SingleFieldSelect } from '../../../components/single_field_select'; @@ -91,7 +91,7 @@ export class LayerTemplate extends Component { this._isMounted = true; } - _loadRightFields = async (indexPatternId) => { + _loadRightFields = async (indexPatternId: string) => { this.setState({ rightTermsFields: [], rightIndexPatternTitle: null }); let indexPattern; @@ -140,7 +140,7 @@ export class LayerTemplate extends Component { _onLeftSourceChange = (optionId: string) => { this.setState( - { leftSource: optionId, leftJoinField: null, rightJoinField: null }, + { leftSource: optionId as BOUNDARIES_SOURCE, leftJoinField: null, rightJoinField: null }, this._previewLayer ); }; @@ -158,17 +158,24 @@ export class LayerTemplate extends Component { () => { // make default geo field selection if (this.state.leftGeoFields.length) { + // @ts-expect-error - avoid wrong "Property 'name' does not exist on type 'never'." compile error this._onLeftGeoFieldSelect(this.state.leftGeoFields[0].name); } } ); }; - _onLeftGeoFieldSelect = (geoField: string) => { + _onLeftGeoFieldSelect = (geoField?: string) => { + if (!geoField) { + return; + } this.setState({ leftGeoField: geoField }, this._previewLayer); }; - _onLeftJoinFieldSelect = (joinField: string) => { + _onLeftJoinFieldSelect = (joinField?: string) => { + if (!joinField) { + return; + } this.setState({ leftJoinField: joinField }, this._previewLayer); }; @@ -184,7 +191,7 @@ export class LayerTemplate extends Component { return; } - this.setState({ leftJoinField: selectedOptions[0].value }, this._previewLayer); + this.setState({ leftJoinField: selectedOptions[0].value! }, this._previewLayer); }; _onRightIndexPatternChange = (indexPatternId: string) => { @@ -204,7 +211,10 @@ export class LayerTemplate extends Component { ); }; - _onRightJoinFieldSelect = (joinField: string) => { + _onRightJoinFieldSelect = (joinField?: string) => { + if (!joinField) { + return; + } this.setState({ rightJoinField: joinField }, this._previewLayer); }; @@ -231,19 +241,20 @@ export class LayerTemplate extends Component { const layerDescriptor = this.state.leftSource === BOUNDARIES_SOURCE.ELASTICSEARCH ? createEsChoroplethLayerDescriptor({ - leftIndexPatternId: this.state.leftIndexPattern.id, - leftGeoField: this.state.leftGeoField, - leftJoinField: this.state.leftJoinField, - rightIndexPatternId: this.state.rightIndexPatternId, - rightIndexPatternTitle: this.state.rightIndexPatternTitle, - rightTermField: this.state.rightJoinField, + // @ts-expect-error - avoid wrong "Property 'id' does not exist on type 'never'." compile error + leftIndexPatternId: this.state.leftIndexPattern!.id, + leftGeoField: this.state.leftGeoField!, + leftJoinField: this.state.leftJoinField!, + rightIndexPatternId: this.state.rightIndexPatternId!, + rightIndexPatternTitle: this.state.rightIndexPatternTitle!, + rightTermField: this.state.rightJoinField!, }) : createEmsChoroplethLayerDescriptor({ - leftEmsFileId: this.state.leftEmsFileId, - leftEmsField: this.state.leftJoinField, - rightIndexPatternId: this.state.rightIndexPatternId, - rightIndexPatternTitle: this.state.rightIndexPatternTitle, - rightTermField: this.state.rightJoinField, + leftEmsFileId: this.state.leftEmsFileId!, + leftEmsField: this.state.leftJoinField!, + rightIndexPatternId: this.state.rightIndexPatternId!, + rightIndexPatternTitle: this.state.rightIndexPatternTitle!, + rightTermField: this.state.rightJoinField!, }); this.props.previewLayers([layerDescriptor]); @@ -294,7 +305,8 @@ export class LayerTemplate extends Component { return ( <> {geoFieldSelect} diff --git a/x-pack/plugins/maps/public/classes/sources/ems_file_source/create_source_editor.tsx b/x-pack/plugins/maps/public/classes/sources/ems_file_source/create_source_editor.tsx index 841c774479fcee..ef15a8d7866076 100644 --- a/x-pack/plugins/maps/public/classes/sources/ems_file_source/create_source_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/ems_file_source/create_source_editor.tsx @@ -5,12 +5,7 @@ */ import React, { Component } from 'react'; -import { EuiComboBox, EuiComboBoxOptionOption, EuiFormRow, EuiPanel } from '@elastic/eui'; - -import { i18n } from '@kbn/i18n'; -import { FileLayer } from '@elastic/ems-client'; -import { getEmsFileLayers } from '../../../meta'; -import { getEmsUnavailableMessage } from '../ems_unavailable_message'; +import { EuiPanel } from '@elastic/eui'; import { EMSFileSourceDescriptor } from '../../../../common/descriptor_types'; import { EMSFileSelect } from '../../../components/ems_file_select'; @@ -28,6 +23,7 @@ export class EMSFileCreateSourceEditor extends Component { }; _onChange = (emsFileId: string) => { + this.setState({ emsFileId }); this.props.onSourceConfigChange({ id: emsFileId }); }; diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/__snapshots__/scaling_form.test.tsx.snap b/x-pack/plugins/maps/public/classes/sources/es_search_source/__snapshots__/scaling_form.test.tsx.snap index 2b04da92517561..956b9a1a663d91 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/__snapshots__/scaling_form.test.tsx.snap +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/__snapshots__/scaling_form.test.tsx.snap @@ -210,6 +210,7 @@ exports[`should render top hits form when scaling type is TOP_HITS 1`] = ` diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/scaling_form.test.tsx b/x-pack/plugins/maps/public/classes/sources/es_search_source/scaling_form.test.tsx index 3ec746223c7cf3..6e56c179b4ead2 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/scaling_form.test.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/scaling_form.test.tsx @@ -25,6 +25,7 @@ const defaultProps = { scalingType: SCALING_TYPES.LIMIT, supportsClustering: true, termFields: [], + topHitsSplitField: null, topHitsSize: 1, }; diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/scaling_form.tsx b/x-pack/plugins/maps/public/classes/sources/es_search_source/scaling_form.tsx index a998fe3569835c..816db6a98d593b 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/scaling_form.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/scaling_form.tsx @@ -40,7 +40,7 @@ interface Props { supportsClustering: boolean; clusteringDisabledReason?: string | null; termFields: IFieldType[]; - topHitsSplitField?: string; + topHitsSplitField: string | null; topHitsSize: number; } @@ -90,6 +90,9 @@ export class ScalingForm extends Component { }; _onTopHitsSplitFieldChange = (topHitsSplitField?: string) => { + if (!topHitsSplitField) { + return; + } this.props.onChange({ propName: 'topHitsSplitField', value: topHitsSplitField }); }; @@ -141,6 +144,7 @@ export class ScalingForm extends Component { value={this.props.topHitsSplitField} onChange={this._onTopHitsSplitFieldChange} fields={this.props.termFields} + isClearable={false} compressed /> diff --git a/x-pack/plugins/maps/public/components/ems_file_select.tsx b/x-pack/plugins/maps/public/components/ems_file_select.tsx index c82e06d3b9fd04..f66e813608ce19 100644 --- a/x-pack/plugins/maps/public/components/ems_file_select.tsx +++ b/x-pack/plugins/maps/public/components/ems_file_select.tsx @@ -11,11 +11,10 @@ import { i18n } from '@kbn/i18n'; import { FileLayer } from '@elastic/ems-client'; import { getEmsFileLayers } from '../meta'; import { getEmsUnavailableMessage } from './ems_unavailable_message'; -import { EMSFileSourceDescriptor } from '../../common/descriptor_types'; interface Props { onChange: (emsFileId: string) => void; - value: string; + value: string | null; } interface State { @@ -61,7 +60,7 @@ export class EMSFileSelect extends Component { return; } - this.props.onChange(selectedOptions[0].value); + this.props.onChange(selectedOptions[0].value!); }; _renderSelect() { diff --git a/x-pack/plugins/maps/public/components/geo_index_pattern_select.tsx b/x-pack/plugins/maps/public/components/geo_index_pattern_select.tsx index 2dbb85575f86db..ae23d9d97de86e 100644 --- a/x-pack/plugins/maps/public/components/geo_index_pattern_select.tsx +++ b/x-pack/plugins/maps/public/components/geo_index_pattern_select.tsx @@ -22,7 +22,7 @@ interface Props { } interface State { - noGeoIndexPatternsExist: Array>; + noGeoIndexPatternsExist: boolean; } export class GeoIndexPatternSelect extends Component { diff --git a/x-pack/plugins/maps/public/components/single_field_select.tsx b/x-pack/plugins/maps/public/components/single_field_select.tsx index eb3a28be0efc01..2895479c4fd0e7 100644 --- a/x-pack/plugins/maps/public/components/single_field_select.tsx +++ b/x-pack/plugins/maps/public/components/single_field_select.tsx @@ -49,7 +49,7 @@ type Props = Omit< > & { fields?: IFieldType[]; onChange: (fieldName?: string) => void; - value?: string; // index pattern field name + value: string | null; // index pattern field name isFieldDisabled?: (field: IFieldType) => boolean; getFieldDisabledReason?: (field: IFieldType) => string | null; }; From e85fb905258398e043ca46c5252759f0f3246348 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 23 Jun 2020 13:05:20 -0600 Subject: [PATCH 14/19] snapshot update --- .../es_search_source/__snapshots__/scaling_form.test.tsx.snap | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/__snapshots__/scaling_form.test.tsx.snap b/x-pack/plugins/maps/public/classes/sources/es_search_source/__snapshots__/scaling_form.test.tsx.snap index 956b9a1a663d91..8ebb389472f74c 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/__snapshots__/scaling_form.test.tsx.snap +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/__snapshots__/scaling_form.test.tsx.snap @@ -213,6 +213,7 @@ exports[`should render top hits form when scaling type is TOP_HITS 1`] = ` isClearable={false} onChange={[Function]} placeholder="Select entity field" + value={null} /> From aaf17fd0b7cac838c51ee219898be2338b227d6b Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Thu, 25 Jun 2020 09:17:33 -0600 Subject: [PATCH 15/19] review feedback --- .../layer_template.test.tsx.snap | 107 ++++++++++++++++++ .../create_choropleth_layer_descriptor.ts | 1 + .../layer_template.test.tsx | 42 +++++++ .../layer_template.tsx | 31 ++--- .../geo_index_pattern_select.test.tsx.snap | 104 +++++++++++++++++ .../geo_index_pattern_select.test.tsx | 42 +++++++ 6 files changed, 314 insertions(+), 13 deletions(-) create mode 100644 x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/__snapshots__/layer_template.test.tsx.snap create mode 100644 x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.test.tsx create mode 100644 x-pack/plugins/maps/public/components/__snapshots__/geo_index_pattern_select.test.tsx.snap create mode 100644 x-pack/plugins/maps/public/components/geo_index_pattern_select.test.tsx diff --git a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/__snapshots__/layer_template.test.tsx.snap b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/__snapshots__/layer_template.test.tsx.snap new file mode 100644 index 00000000000000..fca33effee7299 --- /dev/null +++ b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/__snapshots__/layer_template.test.tsx.snap @@ -0,0 +1,107 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should render EMS UI when left source is BOUNDARIES_SOURCE.EMS 1`] = ` + + + +
+ +
+
+ + + + + +
+ +
+`; + +exports[`should render elasticsearch UI when left source is BOUNDARIES_SOURCE.ELASTICSEARCH 1`] = ` + + + +
+ +
+
+ + + + + +
+ +
+`; diff --git a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/create_choropleth_layer_descriptor.ts b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/create_choropleth_layer_descriptor.ts index bc69b0b5c59d97..61fb6ef54c2073 100644 --- a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/create_choropleth_layer_descriptor.ts +++ b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/create_choropleth_layer_descriptor.ts @@ -134,6 +134,7 @@ export function createEsChoroplethLayerDescriptor({ geoField: leftGeoField, scalingType: SCALING_TYPES.LIMIT, tooltipProperties: [leftJoinField], + applyGlobalQuery: false, }), leftField: leftJoinField, rightIndexPatternId, diff --git a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.test.tsx b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.test.tsx new file mode 100644 index 00000000000000..e9d25320712036 --- /dev/null +++ b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.test.tsx @@ -0,0 +1,42 @@ +/* + * 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', () => { + const MockIndexPatternSelect = (props: unknown) => { + return
; + }; + return { + getIndexPatternSelectComponent: () => { + return MockIndexPatternSelect; + }, + }; +}); + +import React from 'react'; +import { shallow } from 'enzyme'; +import { BOUNDARIES_SOURCE, LayerTemplate } from './layer_template'; + +const renderWizardArguments = { + previewLayers: () => {}, + mapColors: [], + isIndexingTriggered: false, + onRemove: () => {}, + onIndexReady: () => {}, + importSuccessHandler: () => {}, + importErrorHandler: () => {}, +}; + +test('should render elasticsearch UI when left source is BOUNDARIES_SOURCE.ELASTICSEARCH', async () => { + const component = shallow(); + component.setState({ leftSource: BOUNDARIES_SOURCE.ELASTICSEARCH }); + expect(component).toMatchSnapshot(); +}); + +test('should render EMS UI when left source is BOUNDARIES_SOURCE.EMS', async () => { + const component = shallow(); + component.setState({ leftSource: BOUNDARIES_SOURCE.EMS }); + expect(component).toMatchSnapshot(); +}); diff --git a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx index c10d0c57832f87..e6e8c3612f9ceb 100644 --- a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx +++ b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx @@ -123,19 +123,24 @@ export class LayerTemplate extends Component { return; } - const fields = emsFileLayer.getFieldsInLanguage(); - this.setState({ - leftEmsFields: fields - .filter((field) => { - return field.type === 'id'; - }) - .map((field) => { - return { - value: field.name, - label: field.description, - }; - }), - }); + const leftEmsFields = emsFileLayer + .getFieldsInLanguage() + .filter((field) => { + return field.type === 'id'; + }) + .map((field) => { + return { + value: field.name, + label: field.description, + }; + }); + this.setState( + { + leftEmsFields, + leftJoinField: leftEmsFields.length ? leftEmsFields[0].value : null, + }, + this._previewLayer + ); }; _onLeftSourceChange = (optionId: string) => { diff --git a/x-pack/plugins/maps/public/components/__snapshots__/geo_index_pattern_select.test.tsx.snap b/x-pack/plugins/maps/public/components/__snapshots__/geo_index_pattern_select.test.tsx.snap new file mode 100644 index 00000000000000..809fe618625130 --- /dev/null +++ b/x-pack/plugins/maps/public/components/__snapshots__/geo_index_pattern_select.test.tsx.snap @@ -0,0 +1,104 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should render 1`] = ` + + + + + +`; + +exports[`should render no index pattern warning when there are no matching index patterns 1`] = ` + + +

+ + + + + +

+

+ + + + +

+
+ + + + +
+`; diff --git a/x-pack/plugins/maps/public/components/geo_index_pattern_select.test.tsx b/x-pack/plugins/maps/public/components/geo_index_pattern_select.test.tsx new file mode 100644 index 00000000000000..74d29e7d7e59a8 --- /dev/null +++ b/x-pack/plugins/maps/public/components/geo_index_pattern_select.test.tsx @@ -0,0 +1,42 @@ +/* + * 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', () => { + const MockIndexPatternSelect = (props: unknown) => { + return
; + }; + const MockHttp = { + basePath: { + prepend: (path: string) => { + return `abc/${path}`; + }, + }, + }; + return { + getIndexPatternSelectComponent: () => { + return MockIndexPatternSelect; + }, + getHttp: () => { + return MockHttp; + }, + }; +}); + +import React from 'react'; +import { shallow } from 'enzyme'; +import { GeoIndexPatternSelect } from './geo_index_pattern_select'; + +test('should render', async () => { + const component = shallow( {}} value={'indexPatternId'} />); + + expect(component).toMatchSnapshot(); +}); + +test('should render no index pattern warning when there are no matching index patterns', async () => { + const component = shallow( {}} value={'indexPatternId'} />); + component.setState({ noGeoIndexPatternsExist: true }); + expect(component).toMatchSnapshot(); +}); From ebdff3f6226220b65a20ce7b47c8f2783a29e42e Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Fri, 26 Jun 2020 07:19:53 -0600 Subject: [PATCH 16/19] review feedback --- .../layer_template.tsx | 46 ++++++++++--------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx index e6e8c3612f9ceb..b408273f0a2bd3 100644 --- a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx +++ b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx @@ -36,18 +36,18 @@ export enum BOUNDARIES_SOURCE { } const BOUNDARIES_OPTIONS = [ - { - id: BOUNDARIES_SOURCE.ELASTICSEARCH, - label: i18n.translate('xpack.maps.choropleth.boundaries.elasticsearch', { - defaultMessage: 'Points, lines, and polygons from Elasticsearch', - }), - }, { id: BOUNDARIES_SOURCE.EMS, label: i18n.translate('xpack.maps.choropleth.boundaries.ems', { defaultMessage: 'Administrative boundaries from Elastic Maps Service', }), }, + { + id: BOUNDARIES_SOURCE.ELASTICSEARCH, + label: i18n.translate('xpack.maps.choropleth.boundaries.elasticsearch', { + defaultMessage: 'Points, lines, and polygons from Elasticsearch', + }), + }, ]; interface State { @@ -58,7 +58,8 @@ interface State { leftGeoFields: IFieldType[]; leftJoinFields: IFieldType[]; leftGeoField: string | null; - leftJoinField: string | null; + leftEmsJoinField: string | null; + leftElasticsearchJoinField: string | null; rightIndexPatternId: string | null; rightIndexPatternTitle: string | null; rightTermsFields: IFieldType[]; @@ -76,7 +77,8 @@ export class LayerTemplate extends Component { leftGeoFields: [], leftJoinFields: [], leftGeoField: null, - leftJoinField: null, + leftEmsJoinField: null, + leftElasticsearchJoinField: null, rightIndexPatternId: null, rightIndexPatternTitle: null, rightTermsFields: [], @@ -137,7 +139,7 @@ export class LayerTemplate extends Component { this.setState( { leftEmsFields, - leftJoinField: leftEmsFields.length ? leftEmsFields[0].value : null, + leftEmsJoinField: leftEmsFields.length ? leftEmsFields[0].value : null, }, this._previewLayer ); @@ -145,7 +147,7 @@ export class LayerTemplate extends Component { _onLeftSourceChange = (optionId: string) => { this.setState( - { leftSource: optionId as BOUNDARIES_SOURCE, leftJoinField: null, rightJoinField: null }, + { leftSource: optionId as BOUNDARIES_SOURCE, rightJoinField: null }, this._previewLayer ); }; @@ -157,7 +159,7 @@ export class LayerTemplate extends Component { leftGeoFields: getGeoFields(indexPattern.fields), leftJoinFields: getSourceFields(indexPattern.fields), leftGeoField: null, - leftJoinField: null, + leftElasticsearchJoinField: null, rightJoinField: null, }, () => { @@ -181,11 +183,11 @@ export class LayerTemplate extends Component { if (!joinField) { return; } - this.setState({ leftJoinField: joinField }, this._previewLayer); + this.setState({ leftElasticsearchJoinField: joinField }, this._previewLayer); }; _onLeftEmsFileChange = (emFileId: string) => { - this.setState({ leftEmsFileId: emFileId, leftJoinField: null, rightJoinField: null }, () => { + this.setState({ leftEmsFileId: emFileId, leftEmsJoinField: null, rightJoinField: null }, () => { this._previewLayer(); this._loadEmsFileFields(); }); @@ -196,7 +198,7 @@ export class LayerTemplate extends Component { return; } - this.setState({ leftJoinField: selectedOptions[0].value! }, this._previewLayer); + this.setState({ leftEmsJoinField: selectedOptions[0].value! }, this._previewLayer); }; _onRightIndexPatternChange = (indexPatternId: string) => { @@ -226,10 +228,12 @@ export class LayerTemplate extends Component { _isLeftConfigComplete() { if (this.state.leftSource === BOUNDARIES_SOURCE.ELASTICSEARCH) { return ( - !!this.state.leftIndexPattern && !!this.state.leftGeoField && !!this.state.leftJoinField + !!this.state.leftIndexPattern && + !!this.state.leftGeoField && + !!this.state.leftElasticsearchJoinField ); } else { - return !!this.state.leftEmsFileId && !!this.state.leftJoinField; + return !!this.state.leftEmsFileId && !!this.state.leftEmsJoinField; } } @@ -249,14 +253,14 @@ export class LayerTemplate extends Component { // @ts-expect-error - avoid wrong "Property 'id' does not exist on type 'never'." compile error leftIndexPatternId: this.state.leftIndexPattern!.id, leftGeoField: this.state.leftGeoField!, - leftJoinField: this.state.leftJoinField!, + leftJoinField: this.state.leftElasticsearchJoinField!, rightIndexPatternId: this.state.rightIndexPatternId!, rightIndexPatternTitle: this.state.rightIndexPatternTitle!, rightTermField: this.state.rightJoinField!, }) : createEmsChoroplethLayerDescriptor({ leftEmsFileId: this.state.leftEmsFileId!, - leftEmsField: this.state.leftJoinField!, + leftEmsField: this.state.leftEmsJoinField!, rightIndexPatternId: this.state.rightIndexPatternId!, rightIndexPatternTitle: this.state.rightIndexPatternTitle!, rightTermField: this.state.rightJoinField!, @@ -299,7 +303,7 @@ export class LayerTemplate extends Component { placeholder={i18n.translate('xpack.maps.choropleth.joinFieldPlaceholder', { defaultMessage: 'Select field', })} - value={this.state.leftJoinField} + value={this.state.leftElasticsearchJoinField} onChange={this._onLeftJoinFieldSelect} fields={this.state.leftJoinFields} isClearable={false} @@ -322,10 +326,10 @@ export class LayerTemplate extends Component { let emsFieldSelect; if (this.state.leftEmsFields.length) { let selectedOption; - if (this.state.leftJoinField) { + if (this.state.leftEmsJoinField) { selectedOption = this.state.leftEmsFields.find( (option: EuiComboBoxOptionOption) => { - return this.state.leftJoinField === option.value; + return this.state.leftEmsJoinField === option.value; } ); } From 4198d11398d60535d32a45fd121e6d9abcf5c9b5 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Fri, 26 Jun 2020 07:22:39 -0600 Subject: [PATCH 17/19] update snapshot --- .../__snapshots__/layer_template.test.tsx.snap | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/__snapshots__/layer_template.test.tsx.snap b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/__snapshots__/layer_template.test.tsx.snap index fca33effee7299..3a301a951ed571 100644 --- a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/__snapshots__/layer_template.test.tsx.snap +++ b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/__snapshots__/layer_template.test.tsx.snap @@ -30,14 +30,14 @@ exports[`should render EMS UI when left source is BOUNDARIES_SOURCE.EMS 1`] = ` onChange={[Function]} options={ Array [ - Object { - "id": "ELASTICSEARCH", - "label": "Points, lines, and polygons from Elasticsearch", - }, Object { "id": "EMS", "label": "Administrative boundaries from Elastic Maps Service", }, + Object { + "id": "ELASTICSEARCH", + "label": "Points, lines, and polygons from Elasticsearch", + }, ] } /> @@ -83,14 +83,14 @@ exports[`should render elasticsearch UI when left source is BOUNDARIES_SOURCE.EL onChange={[Function]} options={ Array [ - Object { - "id": "ELASTICSEARCH", - "label": "Points, lines, and polygons from Elasticsearch", - }, Object { "id": "EMS", "label": "Administrative boundaries from Elastic Maps Service", }, + Object { + "id": "ELASTICSEARCH", + "label": "Points, lines, and polygons from Elasticsearch", + }, ] } /> From 4bcfe80aec06db042ce142078c7b9c6aacb5e014 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Fri, 26 Jun 2020 08:06:13 -0600 Subject: [PATCH 18/19] make EMS default source --- .../classes/layers/choropleth_layer_wizard/layer_template.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx index b408273f0a2bd3..72618781902d2a 100644 --- a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx +++ b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.tsx @@ -70,7 +70,7 @@ export class LayerTemplate extends Component { private _isMounted: boolean = false; state = { - leftSource: BOUNDARIES_SOURCE.ELASTICSEARCH, + leftSource: BOUNDARIES_SOURCE.EMS, leftEmsFileId: null, leftEmsFields: [], leftIndexPattern: null, From 97bc43723c4719e1f143673fa253c1d33bd422f1 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Mon, 29 Jun 2020 07:12:57 -0600 Subject: [PATCH 19/19] tslint --- .../choropleth_layer_wizard/layer_template.test.tsx | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.test.tsx b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.test.tsx index e9d25320712036..ecb86756e1ca73 100644 --- a/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.test.tsx +++ b/x-pack/plugins/maps/public/classes/layers/choropleth_layer_wizard/layer_template.test.tsx @@ -22,11 +22,12 @@ import { BOUNDARIES_SOURCE, LayerTemplate } from './layer_template'; const renderWizardArguments = { previewLayers: () => {}, mapColors: [], - isIndexingTriggered: false, - onRemove: () => {}, - onIndexReady: () => {}, - importSuccessHandler: () => {}, - importErrorHandler: () => {}, + currentStepId: null, + enableNextBtn: () => {}, + disableNextBtn: () => {}, + startStepLoading: () => {}, + stopStepLoading: () => {}, + advanceToNextStep: () => {}, }; test('should render elasticsearch UI when left source is BOUNDARIES_SOURCE.ELASTICSEARCH', async () => {