From 93df9a32a49d13ebbdc53de7ec9e99e3c2c7c1da Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Fri, 4 Jun 2021 08:00:41 -0600 Subject: [PATCH] [Maps] embeddable migrations (#101070) * [Maps] embeddable migrations * review feedback Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../maps/server/embeddable_migrations.test.ts | 21 ++++ .../maps/server/embeddable_migrations.ts | 26 ++++ x-pack/plugins/maps/server/plugin.ts | 8 ++ .../plugins/maps/server/saved_objects/map.ts | 4 +- .../maps/server/saved_objects/migrations.js | 107 ----------------- .../saved_objects/saved_object_migrations.js | 112 ++++++++++++++++++ .../api_integration/apis/maps/migrations.js | 94 ++++++++++----- .../es_archives/maps/kibana/data.json | 28 +++++ 8 files changed, 259 insertions(+), 141 deletions(-) create mode 100644 x-pack/plugins/maps/server/embeddable_migrations.test.ts create mode 100644 x-pack/plugins/maps/server/embeddable_migrations.ts delete mode 100644 x-pack/plugins/maps/server/saved_objects/migrations.js create mode 100644 x-pack/plugins/maps/server/saved_objects/saved_object_migrations.js diff --git a/x-pack/plugins/maps/server/embeddable_migrations.test.ts b/x-pack/plugins/maps/server/embeddable_migrations.test.ts new file mode 100644 index 000000000000..306f716d5171 --- /dev/null +++ b/x-pack/plugins/maps/server/embeddable_migrations.test.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import semverGte from 'semver/functions/gte'; +import { embeddableMigrations } from './embeddable_migrations'; +// @ts-ignore +import { savedObjectMigrations } from './saved_objects/saved_object_migrations'; + +describe('saved object migrations and embeddable migrations', () => { + test('should have same versions registered (>7.12)', () => { + const savedObjectMigrationVersions = Object.keys(savedObjectMigrations).filter((version) => { + return semverGte(version, '7.13.0'); + }); + const embeddableMigrationVersions = Object.keys(embeddableMigrations); + expect(savedObjectMigrationVersions.sort()).toEqual(embeddableMigrationVersions.sort()); + }); +}); diff --git a/x-pack/plugins/maps/server/embeddable_migrations.ts b/x-pack/plugins/maps/server/embeddable_migrations.ts new file mode 100644 index 000000000000..4bf39dc1f999 --- /dev/null +++ b/x-pack/plugins/maps/server/embeddable_migrations.ts @@ -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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { SerializableState } from '../../../../src/plugins/kibana_utils/common'; +import { MapSavedObjectAttributes } from '../common/map_saved_object_type'; +import { moveAttribution } from '../common/migrations/move_attribution'; + +/* + * Embeddables such as Maps, Lens, and Visualize can be embedded by value or by reference on a dashboard. + * To ensure that any migrations (>7.12) are run correctly in both cases, + * the migration function must be registered as both a saved object migration and an embeddable migration + + * This is the embeddable migration registry. + */ +export const embeddableMigrations = { + '7.14.0': (state: SerializableState) => { + return { + ...state, + attributes: moveAttribution(state as { attributes: MapSavedObjectAttributes }), + } as SerializableState; + }, +}; diff --git a/x-pack/plugins/maps/server/plugin.ts b/x-pack/plugins/maps/server/plugin.ts index f0c8a051f8f7..c75329793203 100644 --- a/x-pack/plugins/maps/server/plugin.ts +++ b/x-pack/plugins/maps/server/plugin.ts @@ -37,6 +37,8 @@ import { HomeServerPluginSetup } from '../../../../src/plugins/home/server'; import { MapsEmsPluginSetup } from '../../../../src/plugins/maps_ems/server'; import { EMSSettings } from '../common/ems_settings'; import { PluginStart as DataPluginStart } from '../../../../src/plugins/data/server'; +import { EmbeddableSetup } from '../../../../src/plugins/embeddable/server'; +import { embeddableMigrations } from './embeddable_migrations'; interface SetupDeps { features: FeaturesPluginSetupContract; @@ -44,6 +46,7 @@ interface SetupDeps { home: HomeServerPluginSetup; licensing: LicensingPluginSetup; mapsEms: MapsEmsPluginSetup; + embeddable: EmbeddableSetup; } export interface StartDeps { @@ -214,6 +217,11 @@ export class MapsPlugin implements Plugin { core.savedObjects.registerType(mapSavedObjects); registerMapsUsageCollector(usageCollection, currentConfig); + plugins.embeddable.registerEmbeddableFactory({ + id: MAP_SAVED_OBJECT_TYPE, + migrations: embeddableMigrations, + }); + return { config: config$, }; diff --git a/x-pack/plugins/maps/server/saved_objects/map.ts b/x-pack/plugins/maps/server/saved_objects/map.ts index f4091db66d3d..78f70e27b2b7 100644 --- a/x-pack/plugins/maps/server/saved_objects/map.ts +++ b/x-pack/plugins/maps/server/saved_objects/map.ts @@ -8,7 +8,7 @@ import { SavedObjectsType } from 'src/core/server'; import { APP_ICON, getExistingMapPath } from '../../common/constants'; // @ts-ignore -import { migrations } from './migrations'; +import { savedObjectMigrations } from './saved_object_migrations'; export const mapSavedObjects: SavedObjectsType = { name: 'map', @@ -39,5 +39,5 @@ export const mapSavedObjects: SavedObjectsType = { }; }, }, - migrations: migrations.map, + migrations: savedObjectMigrations, }; diff --git a/x-pack/plugins/maps/server/saved_objects/migrations.js b/x-pack/plugins/maps/server/saved_objects/migrations.js deleted file mode 100644 index d10e22722970..000000000000 --- a/x-pack/plugins/maps/server/saved_objects/migrations.js +++ /dev/null @@ -1,107 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -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'; -import { addFieldMetaOptions } from '../../common/migrations/add_field_meta_options'; -import { migrateSymbolStyleDescriptor } from '../../common/migrations/migrate_symbol_style_descriptor'; -import { migrateUseTopHitsToScalingType } from '../../common/migrations/scaling_type'; -import { migrateJoinAggKey } from '../../common/migrations/join_agg_key'; -import { removeBoundsFromSavedObject } from '../../common/migrations/remove_bounds'; -import { setDefaultAutoFitToBounds } from '../../common/migrations/set_default_auto_fit_to_bounds'; -import { addTypeToTermJoin } from '../../common/migrations/add_type_to_termjoin'; -import { moveAttribution } from '../../common/migrations/move_attribution'; - -export const migrations = { - map: { - '7.2.0': (doc) => { - const { attributes, references } = extractReferences(doc); - - return { - ...doc, - attributes, - references, - }; - }, - '7.4.0': (doc) => { - const attributes = emsRasterTileToEmsVectorTile(doc); - - return { - ...doc, - attributes, - }; - }, - '7.5.0': (doc) => { - const attributes = topHitsTimeToSort(doc); - - return { - ...doc, - attributes, - }; - }, - '7.6.0': (doc) => { - const attributesPhase1 = moveApplyGlobalQueryToSources(doc); - const attributesPhase2 = addFieldMetaOptions({ attributes: attributesPhase1 }); - - return { - ...doc, - attributes: attributesPhase2, - }; - }, - '7.7.0': (doc) => { - const attributesPhase1 = migrateSymbolStyleDescriptor(doc); - const attributesPhase2 = migrateUseTopHitsToScalingType({ attributes: attributesPhase1 }); - - return { - ...doc, - attributes: attributesPhase2, - }; - }, - '7.8.0': (doc) => { - const attributes = migrateJoinAggKey(doc); - - return { - ...doc, - attributes, - }; - }, - '7.9.0': (doc) => { - const attributes = removeBoundsFromSavedObject(doc); - - return { - ...doc, - attributes, - }; - }, - '7.10.0': (doc) => { - const attributes = setDefaultAutoFitToBounds(doc); - - return { - ...doc, - attributes, - }; - }, - '7.12.0': (doc) => { - const attributes = addTypeToTermJoin(doc); - - return { - ...doc, - attributes, - }; - }, - '7.14.0': (doc) => { - const attributes = moveAttribution(doc); - - return { - ...doc, - attributes, - }; - }, - }, -}; diff --git a/x-pack/plugins/maps/server/saved_objects/saved_object_migrations.js b/x-pack/plugins/maps/server/saved_objects/saved_object_migrations.js new file mode 100644 index 000000000000..8866ebb6b3de --- /dev/null +++ b/x-pack/plugins/maps/server/saved_objects/saved_object_migrations.js @@ -0,0 +1,112 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +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'; +import { addFieldMetaOptions } from '../../common/migrations/add_field_meta_options'; +import { migrateSymbolStyleDescriptor } from '../../common/migrations/migrate_symbol_style_descriptor'; +import { migrateUseTopHitsToScalingType } from '../../common/migrations/scaling_type'; +import { migrateJoinAggKey } from '../../common/migrations/join_agg_key'; +import { removeBoundsFromSavedObject } from '../../common/migrations/remove_bounds'; +import { setDefaultAutoFitToBounds } from '../../common/migrations/set_default_auto_fit_to_bounds'; +import { addTypeToTermJoin } from '../../common/migrations/add_type_to_termjoin'; +import { moveAttribution } from '../../common/migrations/move_attribution'; + +/* + * Embeddables such as Maps, Lens, and Visualize can be embedded by value or by reference on a dashboard. + * To ensure that any migrations (>7.12) are run correctly in both cases, + * the migration function must be registered as both a saved object migration and an embeddable migration + + * This is the saved object migration registry. + */ +export const savedObjectMigrations = { + '7.2.0': (doc) => { + const { attributes, references } = extractReferences(doc); + + return { + ...doc, + attributes, + references, + }; + }, + '7.4.0': (doc) => { + const attributes = emsRasterTileToEmsVectorTile(doc); + + return { + ...doc, + attributes, + }; + }, + '7.5.0': (doc) => { + const attributes = topHitsTimeToSort(doc); + + return { + ...doc, + attributes, + }; + }, + '7.6.0': (doc) => { + const attributesPhase1 = moveApplyGlobalQueryToSources(doc); + const attributesPhase2 = addFieldMetaOptions({ attributes: attributesPhase1 }); + + return { + ...doc, + attributes: attributesPhase2, + }; + }, + '7.7.0': (doc) => { + const attributesPhase1 = migrateSymbolStyleDescriptor(doc); + const attributesPhase2 = migrateUseTopHitsToScalingType({ attributes: attributesPhase1 }); + + return { + ...doc, + attributes: attributesPhase2, + }; + }, + '7.8.0': (doc) => { + const attributes = migrateJoinAggKey(doc); + + return { + ...doc, + attributes, + }; + }, + '7.9.0': (doc) => { + const attributes = removeBoundsFromSavedObject(doc); + + return { + ...doc, + attributes, + }; + }, + '7.10.0': (doc) => { + const attributes = setDefaultAutoFitToBounds(doc); + + return { + ...doc, + attributes, + }; + }, + '7.12.0': (doc) => { + const attributes = addTypeToTermJoin(doc); + + return { + ...doc, + attributes, + }; + }, + '7.14.0': (doc) => { + const attributes = moveAttribution(doc); + + return { + ...doc, + attributes, + }; + }, +}; diff --git a/x-pack/test/api_integration/apis/maps/migrations.js b/x-pack/test/api_integration/apis/maps/migrations.js index 109579e867cb..fe6e1c70356b 100644 --- a/x-pack/test/api_integration/apis/maps/migrations.js +++ b/x-pack/test/api_integration/apis/maps/migrations.js @@ -9,41 +9,71 @@ import expect from '@kbn/expect'; export default function ({ getService }) { const supertest = getService('supertest'); + const esArchiver = getService('esArchiver'); describe('migrations', () => { - it('should apply saved object reference migration when importing map saved objects prior to 7.2.0', async () => { - const resp = await supertest - .post(`/api/saved_objects/map`) - .set('kbn-xsrf', 'kibana') - .send({ - attributes: { - title: '[Logs] Total Requests and Bytes', - layerListJSON: - '[{"id":"edh66","label":"Total Requests by Country","minZoom":0,"maxZoom":24,"alpha":0.5,"sourceDescriptor":{"type":"EMS_FILE","id":"world_countries"},"visible":true,"style":{"type":"VECTOR","properties":{"fillColor":{"type":"DYNAMIC","options":{"field":{"label":"count of kibana_sample_data_logs:geo.src","name":"__kbnjoin__count_groupby_kibana_sample_data_logs.geo.src","origin":"join"},"color":"Greys"}},"lineColor":{"type":"STATIC","options":{"color":"#FFFFFF"}},"lineWidth":{"type":"STATIC","options":{"size":1}},"iconSize":{"type":"STATIC","options":{"size":10}}}},"type":"VECTOR","joins":[{"leftField":"iso2","right":{"id":"673ff994-fc75-4c67-909b-69fcb0e1060e","indexPatternId":"90943e30-9a47-11e8-b64d-95841ca0b247","indexPatternTitle":"kibana_sample_data_logs","term":"geo.src"}}]},{"id":"gaxya","label":"Actual Requests","minZoom":9,"maxZoom":24,"alpha":1,"sourceDescriptor":{"id":"b7486535-171b-4d3b-bb2e-33c1a0a2854c","type":"ES_SEARCH","indexPatternId":"90943e30-9a47-11e8-b64d-95841ca0b247","geoField":"geo.coordinates","limit":2048,"filterByMapBounds":true,"tooltipProperties":["clientip","timestamp","host","request","response","machine.os","agent","bytes"]},"visible":true,"style":{"type":"VECTOR","properties":{"fillColor":{"type":"STATIC","options":{"color":"#2200ff"}},"lineColor":{"type":"STATIC","options":{"color":"#FFFFFF"}},"lineWidth":{"type":"STATIC","options":{"size":2}},"iconSize":{"type":"DYNAMIC","options":{"field":{"label":"bytes","name":"bytes","origin":"source"},"minSize":1,"maxSize":23}}}},"type":"VECTOR"},{"id":"tfi3f","label":"Total Requests and Bytes","minZoom":0,"maxZoom":9,"alpha":1,"sourceDescriptor":{"type":"ES_GEO_GRID","resolution":"COARSE","id":"8aaa65b5-a4e9-448b-9560-c98cb1c5ac5b","indexPatternId":"90943e30-9a47-11e8-b64d-95841ca0b247","geoField":"geo.coordinates","requestType":"point","metrics":[{"type":"count"},{"type":"sum","field":"bytes"}]},"visible":true,"style":{"type":"VECTOR","properties":{"fillColor":{"type":"DYNAMIC","options":{"field":{"label":"Count","name":"doc_count","origin":"source"},"color":"Blues"}},"lineColor":{"type":"STATIC","options":{"color":"#cccccc"}},"lineWidth":{"type":"STATIC","options":{"size":1}},"iconSize":{"type":"DYNAMIC","options":{"field":{"label":"sum of bytes","name":"sum_of_bytes","origin":"source"},"minSize":1,"maxSize":25}}}},"type":"VECTOR"}]', - }, - migrationVersion: {}, - }) - .expect(200); + describe('saved object migrations', () => { + it('should apply saved object reference migration when importing map saved objects prior to 7.2.0', async () => { + const resp = await supertest + .post(`/api/saved_objects/map`) + .set('kbn-xsrf', 'kibana') + .send({ + attributes: { + title: '[Logs] Total Requests and Bytes', + layerListJSON: + '[{"id":"edh66","label":"Total Requests by Country","minZoom":0,"maxZoom":24,"alpha":0.5,"sourceDescriptor":{"type":"EMS_FILE","id":"world_countries"},"visible":true,"style":{"type":"VECTOR","properties":{"fillColor":{"type":"DYNAMIC","options":{"field":{"label":"count of kibana_sample_data_logs:geo.src","name":"__kbnjoin__count_groupby_kibana_sample_data_logs.geo.src","origin":"join"},"color":"Greys"}},"lineColor":{"type":"STATIC","options":{"color":"#FFFFFF"}},"lineWidth":{"type":"STATIC","options":{"size":1}},"iconSize":{"type":"STATIC","options":{"size":10}}}},"type":"VECTOR","joins":[{"leftField":"iso2","right":{"id":"673ff994-fc75-4c67-909b-69fcb0e1060e","indexPatternId":"90943e30-9a47-11e8-b64d-95841ca0b247","indexPatternTitle":"kibana_sample_data_logs","term":"geo.src"}}]},{"id":"gaxya","label":"Actual Requests","minZoom":9,"maxZoom":24,"alpha":1,"sourceDescriptor":{"id":"b7486535-171b-4d3b-bb2e-33c1a0a2854c","type":"ES_SEARCH","indexPatternId":"90943e30-9a47-11e8-b64d-95841ca0b247","geoField":"geo.coordinates","limit":2048,"filterByMapBounds":true,"tooltipProperties":["clientip","timestamp","host","request","response","machine.os","agent","bytes"]},"visible":true,"style":{"type":"VECTOR","properties":{"fillColor":{"type":"STATIC","options":{"color":"#2200ff"}},"lineColor":{"type":"STATIC","options":{"color":"#FFFFFF"}},"lineWidth":{"type":"STATIC","options":{"size":2}},"iconSize":{"type":"DYNAMIC","options":{"field":{"label":"bytes","name":"bytes","origin":"source"},"minSize":1,"maxSize":23}}}},"type":"VECTOR"},{"id":"tfi3f","label":"Total Requests and Bytes","minZoom":0,"maxZoom":9,"alpha":1,"sourceDescriptor":{"type":"ES_GEO_GRID","resolution":"COARSE","id":"8aaa65b5-a4e9-448b-9560-c98cb1c5ac5b","indexPatternId":"90943e30-9a47-11e8-b64d-95841ca0b247","geoField":"geo.coordinates","requestType":"point","metrics":[{"type":"count"},{"type":"sum","field":"bytes"}]},"visible":true,"style":{"type":"VECTOR","properties":{"fillColor":{"type":"DYNAMIC","options":{"field":{"label":"Count","name":"doc_count","origin":"source"},"color":"Blues"}},"lineColor":{"type":"STATIC","options":{"color":"#cccccc"}},"lineWidth":{"type":"STATIC","options":{"size":1}},"iconSize":{"type":"DYNAMIC","options":{"field":{"label":"sum of bytes","name":"sum_of_bytes","origin":"source"},"minSize":1,"maxSize":25}}}},"type":"VECTOR"}]', + }, + migrationVersion: {}, + }) + .expect(200); - expect(resp.body.references).to.eql([ - { - id: '90943e30-9a47-11e8-b64d-95841ca0b247', - name: 'layer_0_join_0_index_pattern', - type: 'index-pattern', - }, - { - id: '90943e30-9a47-11e8-b64d-95841ca0b247', - name: 'layer_1_source_index_pattern', - type: 'index-pattern', - }, - { - id: '90943e30-9a47-11e8-b64d-95841ca0b247', - name: 'layer_2_source_index_pattern', - type: 'index-pattern', - }, - ]); - expect(resp.body.migrationVersion).to.eql({ map: '7.14.0' }); - expect(resp.body.attributes.layerListJSON.includes('indexPatternRefName')).to.be(true); + expect(resp.body.references).to.eql([ + { + id: '90943e30-9a47-11e8-b64d-95841ca0b247', + name: 'layer_0_join_0_index_pattern', + type: 'index-pattern', + }, + { + id: '90943e30-9a47-11e8-b64d-95841ca0b247', + name: 'layer_1_source_index_pattern', + type: 'index-pattern', + }, + { + id: '90943e30-9a47-11e8-b64d-95841ca0b247', + name: 'layer_2_source_index_pattern', + type: 'index-pattern', + }, + ]); + expect(resp.body.migrationVersion).to.eql({ map: '7.14.0' }); + expect(resp.body.attributes.layerListJSON.includes('indexPatternRefName')).to.be(true); + }); + }); + + describe('embeddable migrations', () => { + before(async () => { + await esArchiver.loadIfNeeded('maps/kibana'); + }); + + after(async () => { + await esArchiver.unload('maps/kibana'); + }); + + it('should apply embeddable migrations', async () => { + const resp = await supertest + .get(`/api/saved_objects/dashboard/4beb0d80-c2ef-11eb-b0cb-bd162d969e6b`) + .set('kbn-xsrf', 'kibana') + .expect(200); + + let panels; + try { + panels = JSON.parse(resp.body.attributes.panelsJSON); + } catch (error) { + throw 'Unable to parse panelsJSON from dashboard saved object'; + } + expect(panels.length).to.be(1); + expect(panels[0].type).to.be('map'); + expect(panels[0].version).to.be('7.14.0'); + }); }); }); } 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 4a879c20f19a..d0c4559d0a0a 100644 --- a/x-pack/test/functional/es_archives/maps/kibana/data.json +++ b/x-pack/test/functional/es_archives/maps/kibana/data.json @@ -1199,6 +1199,34 @@ } } +{ + "type": "doc", + "value": { + "id": "dashboard:4beb0d80-c2ef-11eb-b0cb-bd162d969e6b", + "index": ".kibana", + "source": { + "dashboard": { + "title" : "by value map", + "hits" : 0, + "description" : "", + "panelsJSON" : "[{\"version\":\"7.12.1-SNAPSHOT\",\"type\":\"map\",\"gridData\":{\"x\":0,\"y\":0,\"w\":24,\"h\":15,\"i\":\"cb82a9e3-2eb0-487f-9ade-0ffb921eb536\"},\"panelIndex\":\"cb82a9e3-2eb0-487f-9ade-0ffb921eb536\",\"embeddableConfig\":{\"attributes\":{\"title\":\"\",\"description\":\"\",\"layerListJSON\":\"[]\",\"mapStateJSON\":\"{\\\"zoom\\\":1.75,\\\"center\\\":{\\\"lon\\\":0,\\\"lat\\\":19.94277},\\\"timeFilters\\\":{\\\"from\\\":\\\"now-15m\\\",\\\"to\\\":\\\"now\\\"},\\\"refreshConfig\\\":{\\\"isPaused\\\":true,\\\"interval\\\":0},\\\"query\\\":{\\\"query\\\":\\\"\\\",\\\"language\\\":\\\"kuery\\\"},\\\"filters\\\":[],\\\"settings\\\":{\\\"autoFitToDataBounds\\\":false,\\\"backgroundColor\\\":\\\"#ffffff\\\",\\\"disableInteractive\\\":false,\\\"disableTooltipControl\\\":false,\\\"hideToolbarOverlay\\\":false,\\\"hideLayerControl\\\":false,\\\"hideViewControl\\\":false,\\\"initialLocation\\\":\\\"LAST_SAVED_LOCATION\\\",\\\"fixedLocation\\\":{\\\"lat\\\":0,\\\"lon\\\":0,\\\"zoom\\\":2},\\\"browserLocation\\\":{\\\"zoom\\\":2},\\\"maxZoom\\\":24,\\\"minZoom\\\":0,\\\"showScaleControl\\\":false,\\\"showSpatialFilters\\\":true,\\\"spatialFiltersAlpa\\\":0.3,\\\"spatialFiltersFillColor\\\":\\\"#DA8B45\\\",\\\"spatialFiltersLineColor\\\":\\\"#DA8B45\\\"}}\",\"uiStateJSON\":\"{\\\"isLayerTOCOpen\\\":true,\\\"openTOCDetails\\\":[]}\"},\"mapCenter\":{\"lat\":19.94277,\"lon\":0,\"zoom\":1.75},\"mapBuffer\":{\"minLon\":-211.13072,\"minLat\":-55.27145,\"maxLon\":211.13072,\"maxLat\":87.44135},\"isLayerTOCOpen\":true,\"openTOCDetails\":[],\"hiddenLayers\":[],\"enhancements\":{}}}]", + "optionsJSON" : "{\"hidePanelTitles\":false,\"useMargins\":true}", + "version" : 1, + "timeRestore" : false, + "kibanaSavedObjectMeta" : { + "searchSourceJSON" : "{\"query\":{\"language\":\"kuery\",\"query\":\"\"},\"filter\":[]}" + } + }, + "type" : "dashboard", + "references" : [ ], + "migrationVersion" : { + "dashboard" : "7.11.0" + }, + "updated_at" : "2021-06-01T15:37:39.198Z" + } + } +} + { "type": "doc", "value": {