diff --git a/docs/maps/search.asciidoc b/docs/maps/search.asciidoc index de72c32f153d1..97b10e389963e 100644 --- a/docs/maps/search.asciidoc +++ b/docs/maps/search.asciidoc @@ -14,7 +14,7 @@ You can create a layer that requests data from {es} from the following: ** Grid aggregation source -** <>. The search context is applied to both the terms join and the vector source when the vector source is provided by Elasticsearch documents. +** <> * <> with Grid aggregation source @@ -87,8 +87,11 @@ The most common cause for empty layers are searches for a field that exists in o [[maps-disable-search-for-layer]] ==== Disable search for layer -To prevent the global search bar from applying search context to a layer, clear the *Apply global filter to layer* checkbox in Layer settings. -Disabling the search context applies to the layer source and all <> configured for the layer. +You can prevent the search bar from applying search context to a layer by configuring the following: + +* In *Source settings*, clear the *Apply global filter to source* checkbox to turn off the global search context for the layer source. + +* In *Term joins*, clear the *Apply global filter to join* checkbox to turn off the global search context for the <>. [float] [[maps-add-index-search]] diff --git a/x-pack/legacy/plugins/maps/common/constants.js b/x-pack/legacy/plugins/maps/common/constants.js index 942d0a21123c2..ade645d76cad9 100644 --- a/x-pack/legacy/plugins/maps/common/constants.js +++ b/x-pack/legacy/plugins/maps/common/constants.js @@ -59,6 +59,9 @@ export const SOURCE_DATA_ID_ORIGIN = 'source'; export const GEOJSON_FILE = 'GEOJSON_FILE'; +export const MIN_ZOOM = 0; +export const MAX_ZOOM = 24; + export const DECIMAL_DEGREES_PRECISION = 5; // meters precision export const ZOOM_PRECISION = 2; export const ES_SIZE_LIMIT = 10000; diff --git a/x-pack/legacy/plugins/maps/common/migrations/move_apply_global_query.js b/x-pack/legacy/plugins/maps/common/migrations/move_apply_global_query.js new file mode 100644 index 0000000000000..89619893d757c --- /dev/null +++ b/x-pack/legacy/plugins/maps/common/migrations/move_apply_global_query.js @@ -0,0 +1,51 @@ +/* + * 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 _ from 'lodash'; +import { + ES_GEO_GRID, + ES_PEW_PEW, + ES_SEARCH, +} from '../constants'; + +function isEsSource(layerDescriptor) { + const sourceType = _.get(layerDescriptor, 'sourceDescriptor.type'); + return [ES_GEO_GRID, ES_PEW_PEW, ES_SEARCH].includes(sourceType); +} + +// Migration to move applyGlobalQuery from layer to sources. +// Moving to source to provide user the granularity needed to apply global filter per source. +export function moveApplyGlobalQueryToSources({ attributes }) { + if (!attributes.layerListJSON) { + return attributes; + } + + const layerList = JSON.parse(attributes.layerListJSON); + layerList.forEach((layerDescriptor) => { + + const applyGlobalQuery = _.get(layerDescriptor, 'applyGlobalQuery', true); + delete layerDescriptor.applyGlobalQuery; + + if (isEsSource(layerDescriptor)) { + layerDescriptor.sourceDescriptor.applyGlobalQuery = applyGlobalQuery; + } + + if (_.has(layerDescriptor, 'joins')) { + layerDescriptor.joins.forEach(joinDescriptor => { + if (_.has(joinDescriptor, 'right')) { + // joinDescriptor.right is ES_TERM_SOURCE source descriptor + joinDescriptor.right.applyGlobalQuery = applyGlobalQuery; + } + }); + } + + }); + + return { + ...attributes, + layerListJSON: JSON.stringify(layerList), + }; +} diff --git a/x-pack/legacy/plugins/maps/common/migrations/move_apply_global_query.test.js b/x-pack/legacy/plugins/maps/common/migrations/move_apply_global_query.test.js new file mode 100644 index 0000000000000..5a66012cc625d --- /dev/null +++ b/x-pack/legacy/plugins/maps/common/migrations/move_apply_global_query.test.js @@ -0,0 +1,109 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +/* eslint max-len: 0 */ + +import { moveApplyGlobalQueryToSources } from './move_apply_global_query'; + +describe('moveApplyGlobalQueryToSources', () => { + + test('Should handle missing layerListJSON attribute', () => { + const attributes = { + title: 'my map', + }; + expect(moveApplyGlobalQueryToSources({ attributes })).toEqual({ + title: 'my map', + }); + }); + + test('Should ignore layers without ES sources', () => { + const layerListJSON = JSON.stringify([ + { + type: 'TILE', + sourceDescriptor: { + type: 'EMS_TMS' + } + } + ]); + const attributes = { + title: 'my map', + layerListJSON + }; + expect(moveApplyGlobalQueryToSources({ attributes })).toEqual({ + title: 'my map', + layerListJSON, + }); + }); + + test('Should move applyGlobalQuery from layer to source', () => { + const layerListJSON = JSON.stringify([ + { + type: 'HEATMAP', + applyGlobalQuery: false, + sourceDescriptor: { + type: 'ES_GEO_GRID' + } + } + ]); + const attributes = { + title: 'my map', + layerListJSON + }; + expect(moveApplyGlobalQueryToSources({ attributes })).toEqual({ + title: 'my map', + layerListJSON: '[{\"type\":\"HEATMAP\",\"sourceDescriptor\":{\"type\":\"ES_GEO_GRID\",\"applyGlobalQuery\":false}}]', + }); + }); + + test('Should move applyGlobalQuery from layer to join', () => { + const layerListJSON = JSON.stringify([ + { + type: 'VECTOR', + applyGlobalQuery: false, + sourceDescriptor: { + type: 'EMS_FILE' + }, + joins: [ + { + right: {} + } + ] + } + ]); + const attributes = { + title: 'my map', + layerListJSON + }; + expect(moveApplyGlobalQueryToSources({ attributes })).toEqual({ + title: 'my map', + layerListJSON: '[{\"type\":\"VECTOR\",\"sourceDescriptor\":{\"type\":\"EMS_FILE\"},\"joins\":[{\"right\":{\"applyGlobalQuery\":false}}]}]', + }); + }); + + test('Should set applyGlobalQuery to true sources when no value is provided in layer', () => { + const layerListJSON = JSON.stringify([ + { + type: 'VECTOR', + sourceDescriptor: { + type: 'ES_GEO_GRID' + }, + joins: [ + { + right: {} + } + ] + } + ]); + const attributes = { + title: 'my map', + layerListJSON + }; + expect(moveApplyGlobalQueryToSources({ attributes })).toEqual({ + title: 'my map', + layerListJSON: '[{\"type\":\"VECTOR\",\"sourceDescriptor\":{\"type\":\"ES_GEO_GRID\",\"applyGlobalQuery\":true},\"joins\":[{\"right\":{\"applyGlobalQuery\":true}}]}]', + }); + }); +}); diff --git a/x-pack/legacy/plugins/maps/migrations.js b/x-pack/legacy/plugins/maps/migrations.js index cdec1f25ce247..39dc58f259961 100644 --- a/x-pack/legacy/plugins/maps/migrations.js +++ b/x-pack/legacy/plugins/maps/migrations.js @@ -7,6 +7,7 @@ import { extractReferences } from './common/migrations/references'; import { emsRasterTileToEmsVectorTile } from './common/migrations/ems_raster_tile_to_ems_vector_tile'; import { topHitsTimeToSort } from './common/migrations/top_hits_time_to_sort'; +import { moveApplyGlobalQueryToSources } from './common/migrations/move_apply_global_query'; export const migrations = { 'map': { @@ -30,6 +31,14 @@ export const migrations = { '7.5.0': (doc) => { const attributes = topHitsTimeToSort(doc); + return { + ...doc, + attributes, + }; + }, + '7.6.0': (doc) => { + const attributes = moveApplyGlobalQueryToSources(doc); + return { ...doc, attributes, diff --git a/x-pack/legacy/plugins/maps/public/actions/map_actions.js b/x-pack/legacy/plugins/maps/public/actions/map_actions.js index 33771a355ddd5..0dbbbf18426a5 100644 --- a/x-pack/legacy/plugins/maps/public/actions/map_actions.js +++ b/x-pack/legacy/plugins/maps/public/actions/map_actions.js @@ -634,19 +634,6 @@ export function setLayerQuery(id, query) { }; } -export function setLayerApplyGlobalQuery(id, applyGlobalQuery) { - return (dispatch) => { - dispatch({ - type: UPDATE_LAYER_PROP, - id, - propName: 'applyGlobalQuery', - newValue: applyGlobalQuery, - }); - - dispatch(syncDataForLayer(id)); - }; -} - export function removeSelectedLayer() { return (dispatch, getState) => { const state = getState(); diff --git a/x-pack/legacy/plugins/maps/public/angular/get_initial_layers.test.js b/x-pack/legacy/plugins/maps/public/angular/get_initial_layers.test.js index 5dc08751347e4..d362fac7570ce 100644 --- a/x-pack/legacy/plugins/maps/public/angular/get_initial_layers.test.js +++ b/x-pack/legacy/plugins/maps/public/angular/get_initial_layers.test.js @@ -45,7 +45,6 @@ describe('kibana.yml configured with map.tilemap.url', () => { alpha: 1, __dataRequests: [], id: layers[0].id, - applyGlobalQuery: true, label: null, maxZoom: 24, minZoom: 0, @@ -87,7 +86,6 @@ describe('EMS is enabled', () => { alpha: 1, __dataRequests: [], id: layers[0].id, - applyGlobalQuery: true, label: null, maxZoom: 24, minZoom: 0, diff --git a/x-pack/legacy/plugins/maps/public/components/global_filter_checkbox.js b/x-pack/legacy/plugins/maps/public/components/global_filter_checkbox.js new file mode 100644 index 0000000000000..e841fa573c9a5 --- /dev/null +++ b/x-pack/legacy/plugins/maps/public/components/global_filter_checkbox.js @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { EuiFormRow, EuiSwitch } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +const label = i18n.translate('xpack.maps.layerPanel.applyGlobalQueryCheckboxLabel', { + defaultMessage: `Apply global filter to source`, +}); + +export function GlobalFilterCheckbox({ applyGlobalQuery, customLabel, setApplyGlobalQuery }) { + const onApplyGlobalQueryChange = event => { + setApplyGlobalQuery(event.target.checked); + }; + + return ( + + + + ); +} diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/filter_editor/filter_editor.js b/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/filter_editor/filter_editor.js index f736f87dc46e1..20520ad3ff8f1 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/filter_editor/filter_editor.js +++ b/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/filter_editor/filter_editor.js @@ -43,7 +43,8 @@ export class FilterEditor extends Component { } _loadIndexPatterns = async () => { - const indexPatternIds = this.props.layer.getIndexPatternIds(); + // Filter only effects source so only load source indices. + const indexPatternIds = this.props.layer.getSource().getIndexPatternIds(); const indexPatterns = []; const getIndexPatternPromises = indexPatternIds.map(async indexPatternId => { try { diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/join.js b/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/join.js index 44987e0d241e3..2b7c614f182fd 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/join.js +++ b/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/join.js @@ -15,6 +15,7 @@ import { i18n } from '@kbn/i18n'; import { JoinExpression } from './join_expression'; import { MetricsExpression } from './metrics_expression'; import { WhereExpression } from './where_expression'; +import { GlobalFilterCheckbox } from '../../../../components/global_filter_checkbox'; import { indexPatternService, @@ -168,6 +169,16 @@ export class Join extends Component { }); } + _onApplyGlobalQueryChange = applyGlobalQuery => { + this.props.onChange({ + leftField: this.props.join.leftField, + right: { + ...this.props.join.right, + applyGlobalQuery, + }, + }); + } + render() { const { join, @@ -184,6 +195,7 @@ export class Join extends Component { const isJoinConfigComplete = join.leftField && right.indexPatternId && right.term; let metricsExpression; + let globalFilterCheckbox; if (isJoinConfigComplete) { metricsExpression = ( @@ -194,6 +206,15 @@ export class Join extends Component { /> ); + globalFilterCheckbox = ( + + ); } let whereExpression; @@ -234,6 +255,8 @@ export class Join extends Component { {whereExpression} + {globalFilterCheckbox} + dispatch(updateLayerMinZoom(id, minZoom)), updateMaxZoom: (id, maxZoom) => dispatch(updateLayerMaxZoom(id, maxZoom)), updateAlpha: (id, alpha) => dispatch(updateLayerAlpha(id, alpha)), - setLayerApplyGlobalQuery: (layerId, applyGlobalQuery) => { - dispatch(setLayerApplyGlobalQuery(layerId, applyGlobalQuery)); - } }; } diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/layer_settings/layer_settings.js b/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/layer_settings/layer_settings.js index 5be842f949871..7b89bba29352a 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/layer_settings/layer_settings.js +++ b/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/layer_settings/layer_settings.js @@ -12,17 +12,13 @@ import { EuiFormRow, EuiFieldText, EuiSpacer, - EuiSwitch, - EuiToolTip, } from '@elastic/eui'; import { ValidatedRange } from '../../../components/validated_range'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { ValidatedDualRange } from 'ui/validated_range'; - -const MIN_ZOOM = 0; -const MAX_ZOOM = 24; +import { MAX_ZOOM, MIN_ZOOM } from '../../../../common/constants'; export function LayerSettings(props) { const onLabelChange = event => { @@ -37,14 +33,9 @@ export function LayerSettings(props) { const onAlphaChange = alpha => { const alphaDecimal = alpha / 100; - props.updateAlpha(props.layerId, alphaDecimal); }; - const onApplyGlobalQueryChange = event => { - props.setLayerApplyGlobalQuery(props.layerId, event.target.checked); - }; - const renderZoomSliders = () => { return ( { - const layerSupportsGlobalQuery = props.layer.getIndexPatternIds().length; - - const applyGlobalQueryCheckbox = ( - - - - ); - - if (layerSupportsGlobalQuery) { - return applyGlobalQueryCheckbox; - } - - return ( - - {applyGlobalQueryCheckbox} - - ); - }; - return ( @@ -164,7 +116,6 @@ export function LayerSettings(props) { {renderLabel()} {renderZoomSliders()} {renderAlphaSlider()} - {renderApplyGlobalQueryCheckbox()} diff --git a/x-pack/legacy/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/set_view_control.js b/x-pack/legacy/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/set_view_control.js index 05ec23d10795a..9c983447bfbf6 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/set_view_control.js +++ b/x-pack/legacy/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/set_view_control.js @@ -18,6 +18,7 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; +import { MAX_ZOOM, MIN_ZOOM } from '../../../../common/constants'; function getViewString(lat, lon, zoom) { return `${lat},${lon},${zoom}`; @@ -117,8 +118,8 @@ export class SetViewControl extends Component { const { isInvalid: isZoomInvalid, component: zoomFormRow } = this._renderNumberFormRow({ value: this.state.zoom, - min: 0, - max: 24, + min: MIN_ZOOM, + max: MAX_ZOOM, onChange: this._onZoomChange, label: i18n.translate('xpack.maps.setViewControl.zoomLabel', { defaultMessage: 'Zoom', diff --git a/x-pack/legacy/plugins/maps/public/layers/joins/inner_join.js b/x-pack/legacy/plugins/maps/public/layers/joins/inner_join.js index 9c9aa912f3a39..c1ca1a90c15e6 100644 --- a/x-pack/legacy/plugins/maps/public/layers/joins/inner_join.js +++ b/x-pack/legacy/plugins/maps/public/layers/joins/inner_join.js @@ -90,6 +90,10 @@ export class InnerJoin { return this._rightSource.getIndexPatternIds(); } + getQueryableIndexPatternIds() { + return this._rightSource.getQueryableIndexPatternIds(); + } + getWhereQuery() { return this._rightSource.getWhereQuery(); } diff --git a/x-pack/legacy/plugins/maps/public/layers/layer.js b/x-pack/legacy/plugins/maps/public/layers/layer.js index 6515ab608c2ea..3cde1b4bc0a41 100644 --- a/x-pack/legacy/plugins/maps/public/layers/layer.js +++ b/x-pack/legacy/plugins/maps/public/layers/layer.js @@ -10,8 +10,10 @@ import turf from 'turf'; import turfBooleanContains from '@turf/boolean-contains'; import { DataRequest } from './util/data_request'; import { + MAX_ZOOM, MB_SOURCE_ID_LAYER_ID_PREFIX_DELIMITER, - SOURCE_DATA_ID_ORIGIN + MIN_ZOOM, + SOURCE_DATA_ID_ORIGIN, } from '../../common/constants'; import uuid from 'uuid/v4'; import { copyPersistentState } from '../reducers/util'; @@ -44,11 +46,10 @@ export class AbstractLayer { layerDescriptor.__dataRequests = _.get(options, '__dataRequests', []); layerDescriptor.id = _.get(options, 'id', uuid()); layerDescriptor.label = options.label && options.label.length > 0 ? options.label : null; - layerDescriptor.minZoom = _.get(options, 'minZoom', 0); - layerDescriptor.maxZoom = _.get(options, 'maxZoom', 24); + layerDescriptor.minZoom = _.get(options, 'minZoom', MIN_ZOOM); + layerDescriptor.maxZoom = _.get(options, 'maxZoom', MAX_ZOOM); layerDescriptor.alpha = _.get(options, 'alpha', 0.75); layerDescriptor.visible = _.get(options, 'visible', true); - layerDescriptor.applyGlobalQuery = _.get(options, 'applyGlobalQuery', true); layerDescriptor.style = _.get(options, 'style', {}); return layerDescriptor; @@ -231,10 +232,6 @@ export class AbstractLayer { return this._descriptor.query; } - getApplyGlobalQuery() { - return this._descriptor.applyGlobalQuery; - } - getZoomConfig() { return { minZoom: this._descriptor.minZoom, @@ -383,14 +380,10 @@ export class AbstractLayer { } getIndexPatternIds() { - return []; + return []; } getQueryableIndexPatternIds() { - if (this.getApplyGlobalQuery()) { - return this.getIndexPatternIds(); - } - return []; } diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/client_file_source/constants.js b/x-pack/legacy/plugins/maps/public/layers/sources/client_file_source/constants.js deleted file mode 100644 index 779ac2861e9f4..0000000000000 --- a/x-pack/legacy/plugins/maps/public/layers/sources/client_file_source/constants.js +++ /dev/null @@ -1,7 +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. - */ - -export const DEFAULT_APPLY_GLOBAL_QUERY = false; diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/client_file_source/geojson_file_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/client_file_source/geojson_file_source.js index 59cfc7b486bdd..6c298352cc03a 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/client_file_source/geojson_file_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/client_file_source/geojson_file_source.js @@ -15,9 +15,6 @@ import { ClientFileCreateSourceEditor } from './create_client_file_source_editor import { ESSearchSource } from '../es_search_source'; import uuid from 'uuid/v4'; import _ from 'lodash'; -import { - DEFAULT_APPLY_GLOBAL_QUERY -} from './constants'; import { i18n } from '@kbn/i18n'; export class GeojsonFileSource extends AbstractVectorSource { @@ -31,9 +28,6 @@ export class GeojsonFileSource extends AbstractVectorSource { }); static icon = 'importAction'; static isIndexingSource = true; - static layerDefaults = { - applyGlobalQuery: DEFAULT_APPLY_GLOBAL_QUERY - } static createDescriptor(geoJson, name) { // Wrap feature as feature collection if needed @@ -96,7 +90,7 @@ export class GeojsonFileSource extends AbstractVectorSource { geoField, filterByMapBounds }, inspectorAdapters); - addAndViewSource(source, this.layerDefaults); + addAndViewSource(source); importSuccessHandler(indexResponses); } }; diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/es_geo_grid_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/es_geo_grid_source.js index a8b52e586da28..53a77dc0c00a8 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/es_geo_grid_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/es_geo_grid_source.js @@ -85,6 +85,7 @@ export class ESGeoGridSource extends AbstractESAggSource { metrics={this._descriptor.metrics} renderAs={this._descriptor.requestType} resolution={this._descriptor.resolution} + applyGlobalQuery={this._descriptor.applyGlobalQuery} /> ); } diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/update_source_editor.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/update_source_editor.js index 9ea5093724ed9..1b446e1f2159a 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/update_source_editor.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/update_source_editor.js @@ -14,6 +14,7 @@ import { ResolutionEditor } from './resolution_editor'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiSpacer, EuiTitle } from '@elastic/eui'; +import { GlobalFilterCheckbox } from '../../../components/global_filter_checkbox'; export class UpdateSourceEditor extends Component { state = { @@ -62,6 +63,10 @@ export class UpdateSourceEditor extends Component { this.props.onChange({ propName: 'resolution', value: e }); }; + _onApplyGlobalQueryChange = applyGlobalQuery => { + this.props.onChange({ propName: 'applyGlobalQuery', value: applyGlobalQuery }); + }; + _renderMetricsEditor() { const metricsFilter = this.props.renderAs === RENDER_AS.HEATMAP @@ -95,7 +100,13 @@ export class UpdateSourceEditor extends Component { + {this._renderMetricsEditor()} + + ); } diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_pew_pew_source/es_pew_pew_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_pew_pew_source/es_pew_pew_source.js index 6cc6ab196f7d8..0e224578c5754 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_pew_pew_source/es_pew_pew_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_pew_pew_source/es_pew_pew_source.js @@ -68,6 +68,7 @@ export class ESPewPewSource extends AbstractESAggSource { indexPatternId={this._descriptor.indexPatternId} onChange={onChange} metrics={this._descriptor.metrics} + applyGlobalQuery={this._descriptor.applyGlobalQuery} /> ); } diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_pew_pew_source/update_source_editor.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_pew_pew_source/update_source_editor.js index 5f73ae61a2864..2df7dfc3e0764 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_pew_pew_source/update_source_editor.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_pew_pew_source/update_source_editor.js @@ -11,6 +11,7 @@ import { indexPatternService } from '../../../kibana_services'; import { i18n } from '@kbn/i18n'; import { EuiTitle, EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; +import { GlobalFilterCheckbox } from '../../../components/global_filter_checkbox'; export class UpdateSourceEditor extends Component { state = { @@ -55,6 +56,10 @@ export class UpdateSourceEditor extends Component { this.props.onChange({ propName: 'metrics', value: metrics }); }; + _onApplyGlobalQueryChange = applyGlobalQuery => { + this.props.onChange({ propName: 'applyGlobalQuery', value: applyGlobalQuery }); + }; + render() { return ( <> @@ -70,6 +75,10 @@ export class UpdateSourceEditor extends Component { metrics={this.props.metrics} onChange={this._onMetricsChange} /> + ); } diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/__snapshots__/update_source_editor.test.js.snap b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/__snapshots__/update_source_editor.test.js.snap index c0e443758ada6..eb9bba76e4405 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/__snapshots__/update_source_editor.test.js.snap +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/__snapshots__/update_source_editor.test.js.snap @@ -96,6 +96,9 @@ exports[`should enable sort order select when sort field provided 1`] = ` onChange={[Function]} /> + `; @@ -234,6 +237,9 @@ exports[`should render top hits form when useTopHits is true 1`] = ` onChange={[Function]} /> + `; @@ -332,5 +338,8 @@ exports[`should render update source editor 1`] = ` onChange={[Function]} /> + `; diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js index d9c48424bb77d..d3f6f3aeaf30f 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js @@ -55,6 +55,7 @@ export class ESSearchSource extends AbstractESSource { constructor(descriptor, inspectorAdapters) { super({ + ...descriptor, id: descriptor.id, type: ESSearchSource.type, indexPatternId: descriptor.indexPatternId, @@ -81,6 +82,7 @@ export class ESSearchSource extends AbstractESSource { useTopHits={this._descriptor.useTopHits} topHitsSplitField={this._descriptor.topHitsSplitField} topHitsSize={this._descriptor.topHitsSize} + applyGlobalQuery={this._descriptor.applyGlobalQuery} /> ); } diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/update_source_editor.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/update_source_editor.js index 3678af4d54940..760e087f2e6f6 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/update_source_editor.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/update_source_editor.js @@ -15,6 +15,7 @@ import { } from '@elastic/eui'; import { SingleFieldSelect } from '../../../components/single_field_select'; import { TooltipSelector } from '../../../components/tooltip_selector'; +import { GlobalFilterCheckbox } from '../../../components/global_filter_checkbox'; import { indexPatternService } from '../../../kibana_services'; import { i18n } from '@kbn/i18n'; @@ -106,6 +107,10 @@ export class UpdateSourceEditor extends Component { this.props.onChange({ propName: 'topHitsSize', value: size }); }; + _onApplyGlobalQueryChange = applyGlobalQuery => { + this.props.onChange({ propName: 'applyGlobalQuery', value: applyGlobalQuery }); + }; + renderTopHitsForm() { if (!this.props.useTopHits) { return null; @@ -236,6 +241,11 @@ export class UpdateSourceEditor extends Component { /> + + ); } diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_source.js index cc53ee27af471..010b9360d6501 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_source.js @@ -24,6 +24,13 @@ export class AbstractESSource extends AbstractVectorSource { static icon = 'logoElasticsearch'; + constructor(descriptor, inspectorAdapters) { + super({ + ...descriptor, + applyGlobalQuery: _.get(descriptor, 'applyGlobalQuery', true), + }, inspectorAdapters); + } + isFieldAware() { return true; } @@ -40,6 +47,13 @@ export class AbstractESSource extends AbstractVectorSource { return [this._descriptor.indexPatternId]; } + getQueryableIndexPatternIds() { + if (this.getApplyGlobalQuery()) { + return [this._descriptor.indexPatternId]; + } + return []; + } + supportsElasticsearchFilters() { return true; } @@ -55,7 +69,6 @@ export class AbstractESSource extends AbstractVectorSource { return clonedDescriptor; } - async _runEsQuery(requestName, searchSource, registerCancelCallback, requestDescription) { const abortController = new AbortController(); registerCancelCallback(() => abortController.abort()); diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/source.js b/x-pack/legacy/plugins/maps/public/layers/sources/source.js index 3bee49cff6d18..78e57f79bbe56 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/source.js @@ -95,8 +95,16 @@ export class AbstractSource { return null; } + getApplyGlobalQuery() { + return !!this._descriptor.applyGlobalQuery; + } + getIndexPatternIds() { - return []; + return []; + } + + getQueryableIndexPatternIds() { + return []; } getGeoGridPrecision() { diff --git a/x-pack/legacy/plugins/maps/public/layers/vector_layer.js b/x-pack/legacy/plugins/maps/public/layers/vector_layer.js index b2f45cb6206c6..925ff963e05d4 100644 --- a/x-pack/legacy/plugins/maps/public/layers/vector_layer.js +++ b/x-pack/legacy/plugins/maps/public/layers/vector_layer.js @@ -292,6 +292,14 @@ export class VectorLayer extends AbstractLayer { return indexPatternIds; } + getQueryableIndexPatternIds() { + const indexPatternIds = this._source.getQueryableIndexPatternIds(); + this.getValidJoins().forEach(join => { + indexPatternIds.push(...join.getQueryableIndexPatternIds()); + }); + return indexPatternIds; + } + _findDataRequestForSource(sourceDataId) { return this._dataRequests.find(dataRequest => dataRequest.getDataId() === sourceDataId); } @@ -389,7 +397,7 @@ export class VectorLayer extends AbstractLayer { ...dataFilters, fieldNames: joinSource.getFieldNames(), sourceQuery: joinSource.getWhereQuery(), - applyGlobalQuery: this.getApplyGlobalQuery(), + applyGlobalQuery: joinSource.getApplyGlobalQuery(), }; const canSkip = await this._canSkipSourceUpdate(joinSource, sourceDataId, searchFilters); if (canSkip) { @@ -452,7 +460,7 @@ export class VectorLayer extends AbstractLayer { fieldNames: _.uniq(fieldNames).sort(), geogridPrecision: this._source.getGeoGridPrecision(dataFilters.zoom), sourceQuery: this.getQuery(), - applyGlobalQuery: this.getApplyGlobalQuery(), + applyGlobalQuery: this._source.getApplyGlobalQuery(), sourceMeta: this._source.getSyncMeta(), }; } diff --git a/x-pack/legacy/plugins/siem/public/components/embeddables/__mocks__/mock.ts b/x-pack/legacy/plugins/siem/public/components/embeddables/__mocks__/mock.ts index 1019bfd172846..d7da585966758 100644 --- a/x-pack/legacy/plugins/siem/public/components/embeddables/__mocks__/mock.ts +++ b/x-pack/legacy/plugins/siem/public/components/embeddables/__mocks__/mock.ts @@ -14,6 +14,7 @@ export const mockSourceLayer = { sourceDescriptor: { id: 'uuid.v4()', type: 'ES_SEARCH', + applyGlobalQuery: true, geoField: 'source.geo.location', filterByMapBounds: false, tooltipProperties: [ @@ -56,7 +57,6 @@ export const mockSourceLayer = { maxZoom: 24, alpha: 1, visible: true, - applyGlobalQuery: true, type: 'VECTOR', query: { query: '', language: 'kuery' }, joins: [], @@ -66,6 +66,7 @@ export const mockDestinationLayer = { sourceDescriptor: { id: 'uuid.v4()', type: 'ES_SEARCH', + applyGlobalQuery: true, geoField: 'destination.geo.location', filterByMapBounds: true, tooltipProperties: [ @@ -108,7 +109,6 @@ export const mockDestinationLayer = { maxZoom: 24, alpha: 1, visible: true, - applyGlobalQuery: true, type: 'VECTOR', query: { query: '', language: 'kuery' }, }; @@ -116,6 +116,7 @@ export const mockDestinationLayer = { export const mockLineLayer = { sourceDescriptor: { type: 'ES_PEW_PEW', + applyGlobalQuery: true, id: 'uuid.v4()', indexPatternId: '8c7323ac-97ad-4b53-ac0a-40f8f691a918', sourceGeoField: 'source.geo.location', @@ -164,7 +165,6 @@ export const mockLineLayer = { maxZoom: 24, alpha: 0.5, visible: true, - applyGlobalQuery: true, type: 'VECTOR', query: { query: '', language: 'kuery' }, }; @@ -178,7 +178,6 @@ export const mockLayerList = [ maxZoom: 24, alpha: 1, visible: true, - applyGlobalQuery: true, style: null, type: 'VECTOR_TILE', }, @@ -196,7 +195,6 @@ export const mockLayerListDouble = [ maxZoom: 24, alpha: 1, visible: true, - applyGlobalQuery: true, style: null, type: 'VECTOR_TILE', }, diff --git a/x-pack/legacy/plugins/siem/public/components/embeddables/map_config.ts b/x-pack/legacy/plugins/siem/public/components/embeddables/map_config.ts index e1d3a4aa62938..fd17e6eaeac64 100644 --- a/x-pack/legacy/plugins/siem/public/components/embeddables/map_config.ts +++ b/x-pack/legacy/plugins/siem/public/components/embeddables/map_config.ts @@ -50,7 +50,6 @@ export const getLayerList = (indexPatternIds: IndexPatternMapping[]) => { maxZoom: 24, alpha: 1, visible: true, - applyGlobalQuery: true, style: null, type: 'VECTOR_TILE', }, @@ -76,6 +75,7 @@ export const getSourceLayer = (indexPatternTitle: string, indexPatternId: string sourceDescriptor: { id: uuid.v4(), type: 'ES_SEARCH', + applyGlobalQuery: true, geoField: 'source.geo.location', filterByMapBounds: false, tooltipProperties: Object.keys(sourceFieldMappings), @@ -112,7 +112,6 @@ export const getSourceLayer = (indexPatternTitle: string, indexPatternId: string maxZoom: 24, alpha: 1, visible: true, - applyGlobalQuery: true, type: 'VECTOR', query: { query: '', language: 'kuery' }, joins: [], @@ -129,6 +128,7 @@ export const getDestinationLayer = (indexPatternTitle: string, indexPatternId: s sourceDescriptor: { id: uuid.v4(), type: 'ES_SEARCH', + applyGlobalQuery: true, geoField: 'destination.geo.location', filterByMapBounds: true, tooltipProperties: Object.keys(destinationFieldMappings), @@ -165,7 +165,6 @@ export const getDestinationLayer = (indexPatternTitle: string, indexPatternId: s maxZoom: 24, alpha: 1, visible: true, - applyGlobalQuery: true, type: 'VECTOR', query: { query: '', language: 'kuery' }, }); @@ -180,6 +179,7 @@ export const getDestinationLayer = (indexPatternTitle: string, indexPatternId: s export const getLineLayer = (indexPatternTitle: string, indexPatternId: string) => ({ sourceDescriptor: { type: 'ES_PEW_PEW', + applyGlobalQuery: true, id: uuid.v4(), indexPatternId, sourceGeoField: 'source.geo.location', @@ -228,7 +228,6 @@ export const getLineLayer = (indexPatternTitle: string, indexPatternId: string) maxZoom: 24, alpha: 0.5, visible: true, - applyGlobalQuery: true, type: 'VECTOR', query: { query: '', language: 'kuery' }, }); diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 2154adf87e29b..11777cfd5175f 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -6445,7 +6445,6 @@ "xpack.maps.layerControl.tocEntry.hideDetailsButtonTitle": "レイヤー詳細を非表示", "xpack.maps.layerControl.tocEntry.showDetailsButtonAriaLabel": "レイヤー詳細を表示", "xpack.maps.layerControl.tocEntry.showDetailsButtonTitle": "レイヤー詳細を表示", - "xpack.maps.layerPanel.applyGlobalQueryCheckbox.disableTooltip": "レイヤーはフィルタリングをサポートしていません。", "xpack.maps.layerPanel.applyGlobalQueryCheckboxLabel": "レイヤーにグローバルフィルターを適用", "xpack.maps.layerPanel.filterEditor.addFilterButtonLabel": "フィルターを追加します", "xpack.maps.layerPanel.filterEditor.editFilterButtonLabel": "フィルターを編集", @@ -6701,7 +6700,6 @@ "xpack.maps.tooltip.toolsControl.cancelDrawButtonLabel": "キャンセル", "xpack.maps.xyztmssource.attributionLink": "属性テキストにはリンクが必要です", "xpack.maps.xyztmssource.attributionText": "属性 URL にはテキストが必要です", - "xpack.maps.layerPanel.settingsPanel.layerGlobalFilterLabel": "グローバルフィルター", "xpack.maps.layerPanel.settingsPanel.percentageLabel": "%", "xpack.maps.layerPanel.settingsPanel.visibleZoom": "ズームレベル", "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 c758239423883..a29dc7ad599ab 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -6447,7 +6447,6 @@ "xpack.maps.layerControl.tocEntry.hideDetailsButtonTitle": "隐藏图层详情", "xpack.maps.layerControl.tocEntry.showDetailsButtonAriaLabel": "显示图层详情", "xpack.maps.layerControl.tocEntry.showDetailsButtonTitle": "显示图层详情", - "xpack.maps.layerPanel.applyGlobalQueryCheckbox.disableTooltip": "图层不支持筛选", "xpack.maps.layerPanel.applyGlobalQueryCheckboxLabel": "将全局筛选应用到图层", "xpack.maps.layerPanel.filterEditor.addFilterButtonLabel": "添加筛选", "xpack.maps.layerPanel.filterEditor.editFilterButtonLabel": "编辑筛选", @@ -6703,7 +6702,6 @@ "xpack.maps.tooltip.toolsControl.cancelDrawButtonLabel": "取消", "xpack.maps.xyztmssource.attributionLink": "属性文本必须附带链接", "xpack.maps.xyztmssource.attributionText": "属性 url 必须附带文本", - "xpack.maps.layerPanel.settingsPanel.layerGlobalFilterLabel": "全局筛选", "xpack.maps.layerPanel.settingsPanel.percentageLabel": "%", "xpack.maps.layerPanel.settingsPanel.visibleZoom": "缩放级别", "xpack.maps.source.esSearch.sortFieldSelectPlaceholder": "选择排序字段", diff --git a/x-pack/test/api_integration/apis/maps/migrations.js b/x-pack/test/api_integration/apis/maps/migrations.js index e4ef5e5784249..fdf4ec228f634 100644 --- a/x-pack/test/api_integration/apis/maps/migrations.js +++ b/x-pack/test/api_integration/apis/maps/migrations.js @@ -42,7 +42,7 @@ export default function ({ getService }) { type: 'index-pattern' } ]); - expect(resp.body.migrationVersion).to.eql({ map: '7.5.0' }); + expect(resp.body.migrationVersion).to.eql({ map: '7.6.0' }); expect(resp.body.attributes.layerListJSON.includes('indexPatternRefName')).to.be(true); }); }); diff --git a/x-pack/test/functional/apps/maps/embeddable/dashboard.js b/x-pack/test/functional/apps/maps/embeddable/dashboard.js index f458c38093e4f..0bc764b0d76bd 100644 --- a/x-pack/test/functional/apps/maps/embeddable/dashboard.js +++ b/x-pack/test/functional/apps/maps/embeddable/dashboard.js @@ -40,7 +40,7 @@ export default function ({ getPageObjects, getService }) { it('should pass index patterns to container', async () => { const indexPatterns = await filterBar.getIndexPatterns(); - expect(indexPatterns).to.equal('geo_shapes*,meta_for_geo_shapes*,logstash-*'); + expect(indexPatterns).to.equal('meta_for_geo_shapes*,logstash-*'); }); it('should populate inspector with requests for map embeddable', async () => { diff --git a/x-pack/test/functional/apps/maps/joins.js b/x-pack/test/functional/apps/maps/joins.js index 41c777ad67c77..1634bea47a69f 100644 --- a/x-pack/test/functional/apps/maps/joins.js +++ b/x-pack/test/functional/apps/maps/joins.js @@ -111,14 +111,15 @@ export default function ({ getPageObjects, getService }) { describe('query bar', () => { before(async () => { - await PageObjects.maps.setAndSubmitQuery('prop1 < 10 or _index : "geo_shapes*"'); + await PageObjects.maps.setAndSubmitQuery('prop1 < 10'); }); - afterEach(async () => { + after(async () => { await inspector.close(); + await PageObjects.maps.setAndSubmitQuery(''); }); - it('should apply query to join request', async () => { + it('should not apply query to source and apply query to join', async () => { await PageObjects.maps.openInspectorRequest('meta_for_geo_shapes*.shape_name'); const requestStats = await inspector.getTableData(); const totalHits = PageObjects.maps.getInspectorStatRowHit(requestStats, 'Hits (total)'); @@ -128,20 +129,6 @@ export default function ({ getPageObjects, getService }) { const indexPatternName = PageObjects.maps.getInspectorStatRowHit(requestStats, 'Index pattern'); expect(indexPatternName).to.equal('meta_for_geo_shapes*'); }); - - it('should not apply query to join request when apply global query is disabled', async () => { - await PageObjects.maps.openLayerPanel('geo_shapes*'); - await PageObjects.maps.disableApplyGlobalQuery(); - - await PageObjects.maps.openInspectorRequest('meta_for_geo_shapes*.shape_name'); - const requestStats = await inspector.getTableData(); - const totalHits = PageObjects.maps.getInspectorStatRowHit(requestStats, 'Hits (total)'); - expect(totalHits).to.equal('6'); - const hits = PageObjects.maps.getInspectorStatRowHit(requestStats, 'Hits'); - expect(hits).to.equal('0'); // aggregation requests do not return any documents - const indexPatternName = PageObjects.maps.getInspectorStatRowHit(requestStats, 'Index pattern'); - expect(indexPatternName).to.equal('meta_for_geo_shapes*'); - }); }); describe('where clause', () => { diff --git a/x-pack/test/functional/es_archives/maps/kibana/data.json b/x-pack/test/functional/es_archives/maps/kibana/data.json index 52a454eeeb743..1291e3dd10cff 100644 --- a/x-pack/test/functional/es_archives/maps/kibana/data.json +++ b/x-pack/test/functional/es_archives/maps/kibana/data.json @@ -411,7 +411,7 @@ "type": "envelope" }, "description": "", - "layerListJSON": "[{\"id\":\"0hmz5\",\"label\":\"EMS base layer (road_map)\",\"sourceDescriptor\":{\"type\":\"EMS_TMS\",\"id\":\"road_map\"},\"visible\":true,\"temporary\":false,\"style\":{\"type\":\"TILE\",\"properties\":{}},\"type\":\"TILE\",\"minZoom\":0,\"maxZoom\":24},{\"id\":\"n1t6f\",\"label\":null,\"minZoom\":0,\"maxZoom\":24,\"sourceDescriptor\":{\"id\":\"62eca1fc-fe42-11e8-8eb2-f2801f1b9fd1\",\"type\":\"ES_SEARCH\",\"geoField\":\"geometry\",\"limit\":2048,\"filterByMapBounds\":false,\"showTooltip\":true,\"tooltipProperties\":[\"name\"],\"indexPatternRefName\":\"layer_1_source_index_pattern\"},\"visible\":true,\"temporary\":false,\"style\":{\"type\":\"VECTOR\",\"properties\":{\"fillColor\":{\"type\":\"DYNAMIC\",\"options\":{\"field\":{\"label\":\"max(prop1) group by meta_for_geo_shapes*.shape_name\",\"name\":\"__kbnjoin__max_of_prop1_groupby_meta_for_geo_shapes*.shape_name\",\"origin\":\"join\"},\"color\":\"Blues\"}},\"iconSize\":{\"type\":\"STATIC\",\"options\":{\"size\":10}}},\"temporary\":true,\"previousStyle\":null},\"type\":\"VECTOR\",\"joins\":[{\"leftField\":\"name\",\"right\":{\"id\":\"855ccb86-fe42-11e8-8eb2-f2801f1b9fd1\",\"indexPatternTitle\":\"meta_for_geo_shapes*\",\"term\":\"shape_name\",\"metrics\":[{\"type\":\"max\",\"field\":\"prop1\"}],\"indexPatternRefName\":\"layer_1_join_0_index_pattern\"}}]}]", + "layerListJSON" : "[{\"id\":\"0hmz5\",\"label\":\"EMS base layer (road_map)\",\"sourceDescriptor\":{\"type\":\"EMS_TMS\",\"id\":\"road_map\"},\"visible\":true,\"temporary\":false,\"style\":{\"type\":\"TILE\",\"properties\":{}},\"type\":\"VECTOR_TILE\",\"minZoom\":0,\"maxZoom\":24},{\"id\":\"n1t6f\",\"label\":null,\"minZoom\":0,\"maxZoom\":24,\"sourceDescriptor\":{\"id\":\"62eca1fc-fe42-11e8-8eb2-f2801f1b9fd1\",\"type\":\"ES_SEARCH\",\"geoField\":\"geometry\",\"limit\":2048,\"filterByMapBounds\":false,\"showTooltip\":true,\"tooltipProperties\":[\"name\"],\"applyGlobalQuery\":false,\"indexPatternRefName\":\"layer_1_source_index_pattern\"},\"visible\":true,\"temporary\":false,\"style\":{\"type\":\"VECTOR\",\"properties\":{\"fillColor\":{\"type\":\"DYNAMIC\",\"options\":{\"field\":{\"label\":\"max(prop1) group by meta_for_geo_shapes*.shape_name\",\"name\":\"__kbnjoin__max_of_prop1_groupby_meta_for_geo_shapes*.shape_name\",\"origin\":\"join\"},\"color\":\"Blues\"}},\"iconSize\":{\"type\":\"STATIC\",\"options\":{\"size\":10}}},\"temporary\":true,\"previousStyle\":null},\"type\":\"VECTOR\",\"joins\":[{\"leftField\":\"name\",\"right\":{\"id\":\"855ccb86-fe42-11e8-8eb2-f2801f1b9fd1\",\"indexPatternTitle\":\"meta_for_geo_shapes*\",\"term\":\"shape_name\",\"metrics\":[{\"type\":\"max\",\"field\":\"prop1\"}],\"applyGlobalQuery\":true,\"indexPatternRefName\":\"layer_1_join_0_index_pattern\"}}]}]", "mapStateJSON": "{\"zoom\":3.02,\"center\":{\"lon\":77.33426,\"lat\":-0.04647},\"timeFilters\":{\"from\":\"now-17m\",\"to\":\"now\",\"mode\":\"quick\"},\"refreshConfig\":{\"isPaused\":true,\"interval\":1000}}", "title": "join example", "uiStateJSON": "{\"isLayerTOCOpen\":true,\"openTOCDetails\":[\"n1t6f\"]}" @@ -430,7 +430,7 @@ } ], "migrationVersion" : { - "map" : "7.2.0" + "map" : "7.6.0" } } }