From fcbc121f04484b9038e2b9c1231d9daf30993760 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Mon, 21 Sep 2020 09:28:51 -0600 Subject: [PATCH 01/10] [Maps] lazy load maps_legacy bundle --- src/plugins/maps_legacy/public/index.ts | 2 + .../public/lazy_load_bundle/index.ts | 39 +++++++++++++++++++ .../public/lazy_load_bundle/lazy/index.ts | 20 ++++++++++ .../public/map/base_maps_visualization.js | 7 ++-- src/plugins/maps_legacy/public/plugin.ts | 7 +--- src/plugins/vis_type_vega/public/plugin.ts | 2 - src/plugins/vis_type_vega/public/services.ts | 3 -- .../public/vega_view/vega_map_view.js | 7 +++- .../public/vega_visualization.test.js | 10 +---- 9 files changed, 72 insertions(+), 25 deletions(-) create mode 100644 src/plugins/maps_legacy/public/lazy_load_bundle/index.ts create mode 100644 src/plugins/maps_legacy/public/lazy_load_bundle/lazy/index.ts diff --git a/src/plugins/maps_legacy/public/index.ts b/src/plugins/maps_legacy/public/index.ts index 8f14cd1b15e2c..59d4a5f55c6a3 100644 --- a/src/plugins/maps_legacy/public/index.ts +++ b/src/plugins/maps_legacy/public/index.ts @@ -68,5 +68,7 @@ export { ORIGIN } from './common/constants/origin'; export { WmsOptions } from './components/wms_options'; +export { lazyLoadMapsLegacyModules } from './lazy_load_bundle'; + export type MapsLegacyPluginSetup = ReturnType; export type MapsLegacyPluginStart = ReturnType; diff --git a/src/plugins/maps_legacy/public/lazy_load_bundle/index.ts b/src/plugins/maps_legacy/public/lazy_load_bundle/index.ts new file mode 100644 index 0000000000000..ba970b2e57404 --- /dev/null +++ b/src/plugins/maps_legacy/public/lazy_load_bundle/index.ts @@ -0,0 +1,39 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +let loadModulesPromise: Promise; + +interface LazyLoadedMapsLegacyModules { + KibanaMap: unknown; +} + +export async function lazyLoadMapsLegacyModules(): Promise { + if (typeof loadModulesPromise !== 'undefined') { + return loadModulesPromise; + } + + loadModulesPromise = new Promise(async (resolve) => { + const { KibanaMap } = await import('./lazy'); + + resolve({ + KibanaMap, + }); + }); + return loadModulesPromise; +} diff --git a/src/plugins/maps_legacy/public/lazy_load_bundle/lazy/index.ts b/src/plugins/maps_legacy/public/lazy_load_bundle/lazy/index.ts new file mode 100644 index 0000000000000..393438cc6389d --- /dev/null +++ b/src/plugins/maps_legacy/public/lazy_load_bundle/lazy/index.ts @@ -0,0 +1,20 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export { KibanaMap } from '../../map/kibana_map'; diff --git a/src/plugins/maps_legacy/public/map/base_maps_visualization.js b/src/plugins/maps_legacy/public/map/base_maps_visualization.js index 2d78fdc246e19..0065e19e8059a 100644 --- a/src/plugins/maps_legacy/public/map/base_maps_visualization.js +++ b/src/plugins/maps_legacy/public/map/base_maps_visualization.js @@ -22,11 +22,12 @@ import { i18n } from '@kbn/i18n'; import * as Rx from 'rxjs'; import { filter, first } from 'rxjs/operators'; import { getEmsTileLayerId, getUiSettings, getToasts } from '../kibana_services'; +import { lazyLoadMapsLegacyModules } from '../lazy_load_bundle'; const WMS_MINZOOM = 0; const WMS_MAXZOOM = 22; //increase this to 22. Better for WMS -export function BaseMapsVisualizationProvider(getKibanaMap, mapServiceSettings) { +export function BaseMapsVisualizationProvider(mapServiceSettings) { /** * Abstract base class for a visualization consisting of a map with a single baselayer. * @class BaseMapsVisualization @@ -95,9 +96,9 @@ export function BaseMapsVisualizationProvider(getKibanaMap, mapServiceSettings) const centerFromUIState = uiState.get('mapCenter'); options.zoom = !isNaN(zoomFromUiState) ? zoomFromUiState : this.vis.params.mapZoom; options.center = centerFromUIState ? centerFromUIState : this.vis.params.mapCenter; - const services = { toastService }; - this._kibanaMap = getKibanaMap(this._container, options, services); + const modules = await lazyLoadMapsLegacyModules(); + this._kibanaMap = new modules.KibanaMap(this._container, options); this._kibanaMap.setMinZoom(WMS_MINZOOM); //use a default this._kibanaMap.setMaxZoom(WMS_MAXZOOM); //use a default diff --git a/src/plugins/maps_legacy/public/plugin.ts b/src/plugins/maps_legacy/public/plugin.ts index 8c9f1e9cef194..ae60593f006e9 100644 --- a/src/plugins/maps_legacy/public/plugin.ts +++ b/src/plugins/maps_legacy/public/plugin.ts @@ -25,8 +25,6 @@ import { setToasts, setUiSettings, setKibanaVersion, setMapsLegacyConfig } from import { ServiceSettings } from './map/service_settings'; // @ts-ignore import { getPrecision, getZoomPrecision } from './map/precision'; -// @ts-ignore -import { KibanaMap } from './map/kibana_map'; import { MapsLegacyPluginSetup, MapsLegacyPluginStart } from './index'; import { MapsLegacyConfig } from '../config'; // @ts-ignore @@ -68,16 +66,13 @@ export class MapsLegacyPlugin implements Plugin new KibanaMap(...args); - const getBaseMapsVis = () => - new BaseMapsVisualizationProvider(getKibanaMapFactoryProvider, serviceSettings); + const getBaseMapsVis = () => new BaseMapsVisualizationProvider(serviceSettings); return { serviceSettings, getZoomPrecision, getPrecision, config, - getKibanaMapFactoryProvider, getBaseMapsVis, }; } diff --git a/src/plugins/vis_type_vega/public/plugin.ts b/src/plugins/vis_type_vega/public/plugin.ts index 4b8ff8e2cb43a..a1be76949530f 100644 --- a/src/plugins/vis_type_vega/public/plugin.ts +++ b/src/plugins/vis_type_vega/public/plugin.ts @@ -28,7 +28,6 @@ import { setSavedObjects, setInjectedVars, setUISettings, - setKibanaMapFactory, setMapsLegacyConfig, setInjectedMetadata, } from './services'; @@ -81,7 +80,6 @@ export class VegaPlugin implements Plugin, void> { emsTileLayerId: core.injectedMetadata.getInjectedVar('emsTileLayerId', true), }); setUISettings(core.uiSettings); - setKibanaMapFactory(mapsLegacy.getKibanaMapFactoryProvider); setMapsLegacyConfig(mapsLegacy.config); const visualizationDependencies: Readonly = { diff --git a/src/plugins/vis_type_vega/public/services.ts b/src/plugins/vis_type_vega/public/services.ts index dfb2c96e9f894..455fe67dbc423 100644 --- a/src/plugins/vis_type_vega/public/services.ts +++ b/src/plugins/vis_type_vega/public/services.ts @@ -33,9 +33,6 @@ export const [getData, setData] = createGetterSetter('Dat export const [getNotifications, setNotifications] = createGetterSetter( 'Notifications' ); -export const [getKibanaMapFactory, setKibanaMapFactory] = createGetterSetter( - 'KibanaMapFactory' -); export const [getUISettings, setUISettings] = createGetterSetter('UISettings'); diff --git a/src/plugins/vis_type_vega/public/vega_view/vega_map_view.js b/src/plugins/vis_type_vega/public/vega_view/vega_map_view.js index 78ae2efdbdda5..9b0ad2de7bbcd 100644 --- a/src/plugins/vis_type_vega/public/vega_view/vega_map_view.js +++ b/src/plugins/vis_type_vega/public/vega_view/vega_map_view.js @@ -21,7 +21,8 @@ import { i18n } from '@kbn/i18n'; import { vega } from '../lib/vega'; import { VegaBaseView } from './vega_base_view'; import { VegaMapLayer } from './vega_map_layer'; -import { getEmsTileLayerId, getUISettings, getKibanaMapFactory } from '../services'; +import { getEmsTileLayerId, getUISettings } from '../services'; +import { lazyLoadMapsLegacyModules } from '../../../maps_legacy/public'; export class VegaMapView extends VegaBaseView { constructor(opts) { @@ -106,7 +107,9 @@ export class VegaMapView extends VegaBaseView { // maxBounds = L.latLngBounds(L.latLng(b[1], b[0]), L.latLng(b[3], b[2])); // } - this._kibanaMap = getKibanaMapFactory()(this._$container.get(0), { + const modules = await lazyLoadMapsLegacyModules(); + + this._kibanaMap = new modules.KibanaMap(this._$container.get(0), { zoom, minZoom, maxZoom, diff --git a/src/plugins/vis_type_vega/public/vega_visualization.test.js b/src/plugins/vis_type_vega/public/vega_visualization.test.js index 1bf625af76207..53363481f8717 100644 --- a/src/plugins/vis_type_vega/public/vega_visualization.test.js +++ b/src/plugins/vis_type_vega/public/vega_visualization.test.js @@ -32,16 +32,9 @@ import { SearchAPI } from './data_model/search_api'; import { createVegaTypeDefinition } from './vega_type'; -import { - setInjectedVars, - setData, - setSavedObjects, - setNotifications, - setKibanaMapFactory, -} from './services'; +import { setInjectedVars, setData, setSavedObjects, setNotifications } from './services'; import { coreMock } from '../../../core/public/mocks'; import { dataPluginMock } from '../../data/public/mocks'; -import { KibanaMap } from '../../maps_legacy/public/map/kibana_map'; jest.mock('./default_spec', () => ({ getDefaultSpec: () => jest.requireActual('./test_utils/default.spec.json'), @@ -78,7 +71,6 @@ describe('VegaVisualizations', () => { }; beforeEach(() => { - setKibanaMapFactory((...args) => new KibanaMap(...args)); setInjectedVars({ emsTileLayerId: {}, enableExternalUrls: true, From 4d54eda6450638c130e3dff62611b65c6dcd91f6 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Mon, 21 Sep 2020 10:19:04 -0600 Subject: [PATCH 02/10] tslint --- src/plugins/maps_legacy/public/lazy_load_bundle/lazy/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/maps_legacy/public/lazy_load_bundle/lazy/index.ts b/src/plugins/maps_legacy/public/lazy_load_bundle/lazy/index.ts index 393438cc6389d..74ec9fa86e067 100644 --- a/src/plugins/maps_legacy/public/lazy_load_bundle/lazy/index.ts +++ b/src/plugins/maps_legacy/public/lazy_load_bundle/lazy/index.ts @@ -17,4 +17,5 @@ * under the License. */ +// @ts-expect-error export { KibanaMap } from '../../map/kibana_map'; From 2fddf56a2a758549372103809c91112c894882e4 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Mon, 21 Sep 2020 13:42:08 -0600 Subject: [PATCH 03/10] lazy load leaflet --- src/plugins/maps_legacy/public/index.ts | 3 -- .../public/lazy_load_bundle/index.ts | 2 ++ .../public/lazy_load_bundle/lazy/index.ts | 2 ++ .../public/map/base_maps_visualization.js | 1 + .../region_map/public/choropleth_layer.js | 20 +++++++++--- .../public/region_map_visualization.js | 6 +++- src/plugins/tile_map/public/geohash_layer.js | 31 +++++++++++++------ .../tile_map/public/markers/geohash_grid.js | 5 ++- .../tile_map/public/markers/heatmap.js | 7 ++--- .../tile_map/public/markers/scaled_circles.js | 17 +++++----- .../tile_map/public/markers/shaded_circles.js | 9 +++--- .../tile_map/public/tile_map_visualization.js | 7 ++++- .../public/vega_view/vega_map_layer.js | 6 ++-- .../public/vega_view/vega_map_view.js | 20 +++++++----- 14 files changed, 86 insertions(+), 50 deletions(-) diff --git a/src/plugins/maps_legacy/public/index.ts b/src/plugins/maps_legacy/public/index.ts index 59d4a5f55c6a3..5ff85e685d944 100644 --- a/src/plugins/maps_legacy/public/index.ts +++ b/src/plugins/maps_legacy/public/index.ts @@ -19,8 +19,6 @@ // @ts-ignore import { PluginInitializerContext } from 'kibana/public'; -// @ts-ignore -import { L } from './leaflet'; import { MapsLegacyPlugin } from './plugin'; // @ts-ignore import * as colorUtil from './map/color_util'; @@ -60,7 +58,6 @@ export { FileLayer, TmsLayer, mapTooltipProvider, - L, }; export * from './common/types'; diff --git a/src/plugins/maps_legacy/public/lazy_load_bundle/index.ts b/src/plugins/maps_legacy/public/lazy_load_bundle/index.ts index ba970b2e57404..b566a4cc11188 100644 --- a/src/plugins/maps_legacy/public/lazy_load_bundle/index.ts +++ b/src/plugins/maps_legacy/public/lazy_load_bundle/index.ts @@ -21,6 +21,7 @@ let loadModulesPromise: Promise; interface LazyLoadedMapsLegacyModules { KibanaMap: unknown; + L: unknown; } export async function lazyLoadMapsLegacyModules(): Promise { @@ -33,6 +34,7 @@ export async function lazyLoadMapsLegacyModules(): Promise { layer.on('click', () => { this.emit('select', feature.properties[this._joinField]); @@ -97,7 +107,7 @@ export default class ChoroplethLayer extends KibanaMapLayer { const tooltipContents = this._tooltipFormatter(feature); if (!location) { // eslint-disable-next-line no-undef - const leafletGeojson = L.geoJson(feature); + const leafletGeojson = this._leaflet.geoJson(feature); location = leafletGeojson.getBounds().getCenter(); } this.emit('showTooltip', { @@ -425,7 +435,7 @@ CORS configuration of the server permits requests from the Kibana application on const { min, max } = getMinMax(this._metrics); // eslint-disable-next-line no-undef - const boundsOfAllFeatures = new L.LatLngBounds(); + const boundsOfAllFeatures = new this._leaflet.LatLngBounds(); return { leafletStyleFunction: (geojsonFeature) => { const match = geojsonFeature.__kbnJoinedMetric; @@ -433,7 +443,7 @@ CORS configuration of the server permits requests from the Kibana application on return emptyStyle(); } // eslint-disable-next-line no-undef - const boundsOfFeature = L.geoJson(geojsonFeature).getBounds(); + const boundsOfFeature = this._leaflet.geoJson(geojsonFeature).getBounds(); boundsOfAllFeatures.extend(boundsOfFeature); return { diff --git a/src/plugins/region_map/public/region_map_visualization.js b/src/plugins/region_map/public/region_map_visualization.js index 43959c367558f..d91929efb9805 100644 --- a/src/plugins/region_map/public/region_map_visualization.js +++ b/src/plugins/region_map/public/region_map_visualization.js @@ -169,6 +169,9 @@ export function createRegionMapVisualization({ } _recreateChoroplethLayer(name, attribution, showAllData) { + if (!this._leaflet) { + return; + } this._kibanaMap.removeLayer(this._choroplethLayer); if (this._choroplethLayer) { @@ -189,7 +192,8 @@ export function createRegionMapVisualization({ showAllData, this._params.selectedLayer.meta, this._params.selectedLayer, - serviceSettings + serviceSettings, + this._leaflet ); } diff --git a/src/plugins/tile_map/public/geohash_layer.js b/src/plugins/tile_map/public/geohash_layer.js index ca2f49a1f31e0..ca992a0d09ec9 100644 --- a/src/plugins/tile_map/public/geohash_layer.js +++ b/src/plugins/tile_map/public/geohash_layer.js @@ -19,14 +19,14 @@ import { min, isEqual } from 'lodash'; import { i18n } from '@kbn/i18n'; -import { L, KibanaMapLayer, MapTypes } from '../../maps_legacy/public'; +import { KibanaMapLayer, MapTypes } from '../../maps_legacy/public'; import { HeatmapMarkers } from './markers/heatmap'; import { ScaledCirclesMarkers } from './markers/scaled_circles'; import { ShadedCirclesMarkers } from './markers/shaded_circles'; import { GeohashGridMarkers } from './markers/geohash_grid'; export class GeohashLayer extends KibanaMapLayer { - constructor(featureCollection, featureCollectionMetaData, options, zoom, kibanaMap) { + constructor(featureCollection, featureCollectionMetaData, options, zoom, kibanaMap, leaflet) { super(); this._featureCollection = featureCollection; @@ -35,7 +35,8 @@ export class GeohashLayer extends KibanaMapLayer { this._geohashOptions = options; this._zoom = zoom; this._kibanaMap = kibanaMap; - const geojson = L.geoJson(this._featureCollection); + this._leaflet = leaflet; + const geojson = this._leaflet.geoJson(this._featureCollection); this._bounds = geojson.getBounds(); this._createGeohashMarkers(); this._lastBounds = null; @@ -56,7 +57,8 @@ export class GeohashLayer extends KibanaMapLayer { this._featureCollectionMetaData, markerOptions, this._zoom, - this._kibanaMap + this._kibanaMap, + this._leaflet ); break; case MapTypes.ShadedCircleMarkers: @@ -65,7 +67,8 @@ export class GeohashLayer extends KibanaMapLayer { this._featureCollectionMetaData, markerOptions, this._zoom, - this._kibanaMap + this._kibanaMap, + this._leaflet ); break; case MapTypes.ShadedGeohashGrid: @@ -74,7 +77,8 @@ export class GeohashLayer extends KibanaMapLayer { this._featureCollectionMetaData, markerOptions, this._zoom, - this._kibanaMap + this._kibanaMap, + this._leaflet ); break; case MapTypes.Heatmap: @@ -95,7 +99,8 @@ export class GeohashLayer extends KibanaMapLayer { tooltipFormatter: this._geohashOptions.tooltipFormatter, }, this._zoom, - this._featureCollectionMetaData.max + this._featureCollectionMetaData.max, + this._leaflet ); break; default: @@ -126,9 +131,15 @@ export class GeohashLayer extends KibanaMapLayer { if (this._geohashOptions.fetchBounds) { const geoHashBounds = await this._geohashOptions.fetchBounds(); if (geoHashBounds) { - const northEast = L.latLng(geoHashBounds.top_left.lat, geoHashBounds.bottom_right.lon); - const southWest = L.latLng(geoHashBounds.bottom_right.lat, geoHashBounds.top_left.lon); - return L.latLngBounds(southWest, northEast); + const northEast = this._leaflet.latLng( + geoHashBounds.top_left.lat, + geoHashBounds.bottom_right.lon + ); + const southWest = this._leaflet.latLng( + geoHashBounds.bottom_right.lat, + geoHashBounds.top_left.lon + ); + return this._leaflet.latLngBounds(southWest, northEast); } } diff --git a/src/plugins/tile_map/public/markers/geohash_grid.js b/src/plugins/tile_map/public/markers/geohash_grid.js index 46e7987c601f5..d81e435a6dd5d 100644 --- a/src/plugins/tile_map/public/markers/geohash_grid.js +++ b/src/plugins/tile_map/public/markers/geohash_grid.js @@ -18,11 +18,10 @@ */ import { ScaledCirclesMarkers } from './scaled_circles'; -import { L } from '../../../maps_legacy/public'; export class GeohashGridMarkers extends ScaledCirclesMarkers { getMarkerFunction() { - return function (feature) { + return (feature) => { const geohashRect = feature.properties.geohash_meta.rectangle; // get bounds from northEast[3] and southWest[1] // corners in geohash rectangle @@ -30,7 +29,7 @@ export class GeohashGridMarkers extends ScaledCirclesMarkers { [geohashRect[3][0], geohashRect[3][1]], [geohashRect[1][0], geohashRect[1][1]], ]; - return L.rectangle(corners); + return this._leaflet.rectangle(corners); }; } } diff --git a/src/plugins/tile_map/public/markers/heatmap.js b/src/plugins/tile_map/public/markers/heatmap.js index f2d014797bce0..79bbee16548ac 100644 --- a/src/plugins/tile_map/public/markers/heatmap.js +++ b/src/plugins/tile_map/public/markers/heatmap.js @@ -20,7 +20,6 @@ import _ from 'lodash'; import d3 from 'd3'; import { EventEmitter } from 'events'; -import { L } from '../../../maps_legacy/public'; /** * Map overlay: canvas layer with leaflet.heat plugin @@ -30,17 +29,17 @@ import { L } from '../../../maps_legacy/public'; * @param params {Object} */ export class HeatmapMarkers extends EventEmitter { - constructor(featureCollection, options, zoom, max) { + constructor(featureCollection, options, zoom, max, leaflet) { super(); this._geojsonFeatureCollection = featureCollection; const points = dataToHeatArray(featureCollection, max); - this._leafletLayer = new L.HeatLayer(points, options); + this._leafletLayer = new leaflet.HeatLayer(points, options); this._tooltipFormatter = options.tooltipFormatter; this._zoom = zoom; this._disableTooltips = false; this._getLatLng = _.memoize( function (feature) { - return L.latLng(feature.geometry.coordinates[1], feature.geometry.coordinates[0]); + return leaflet.latLng(feature.geometry.coordinates[1], feature.geometry.coordinates[0]); }, function (feature) { // turn coords into a string for the memoize cache diff --git a/src/plugins/tile_map/public/markers/scaled_circles.js b/src/plugins/tile_map/public/markers/scaled_circles.js index cb111107f6fe3..4a5f1b452580b 100644 --- a/src/plugins/tile_map/public/markers/scaled_circles.js +++ b/src/plugins/tile_map/public/markers/scaled_circles.js @@ -21,7 +21,7 @@ import _ from 'lodash'; import d3 from 'd3'; import $ from 'jquery'; import { EventEmitter } from 'events'; -import { L, colorUtil } from '../../../maps_legacy/public'; +import { colorUtil } from '../../../maps_legacy/public'; import { truncatedColorMaps } from '../../../charts/public'; export class ScaledCirclesMarkers extends EventEmitter { @@ -31,14 +31,13 @@ export class ScaledCirclesMarkers extends EventEmitter { options, targetZoom, kibanaMap, - metricAgg + leaflet ) { super(); this._featureCollection = featureCollection; this._featureCollectionMetaData = featureCollectionMetaData; this._zoom = targetZoom; - this._metricAgg = metricAgg; this._valueFormatter = options.valueFormatter || @@ -55,6 +54,7 @@ export class ScaledCirclesMarkers extends EventEmitter { this._legendColors = null; this._legendQuantizer = null; + this._leaflet = leaflet; this._popups = []; @@ -72,7 +72,7 @@ export class ScaledCirclesMarkers extends EventEmitter { return kibanaMap.isInside(bucketRectBounds); }; } - this._leafletLayer = L.geoJson(null, layerOptions); + this._leafletLayer = this._leaflet.geoJson(null, layerOptions); this._leafletLayer.addData(this._featureCollection); } @@ -143,7 +143,7 @@ export class ScaledCirclesMarkers extends EventEmitter { mouseover: (e) => { const layer = e.target; // bring layer to front if not older browser - if (!L.Browser.ie && !L.Browser.opera) { + if (!this._leaflet.Browser.ie && !this._leaflet.Browser.opera) { layer.bringToFront(); } this._showTooltip(feature); @@ -170,7 +170,10 @@ export class ScaledCirclesMarkers extends EventEmitter { return; } - const latLng = L.latLng(feature.geometry.coordinates[1], feature.geometry.coordinates[0]); + const latLng = this._leaflet.latLng( + feature.geometry.coordinates[1], + feature.geometry.coordinates[0] + ); this.emit('showTooltip', { content: content, position: latLng, @@ -182,7 +185,7 @@ export class ScaledCirclesMarkers extends EventEmitter { return (feature, latlng) => { const value = feature.properties.value; const scaledRadius = this._radiusScale(value) * scaleFactor; - return L.circleMarker(latlng).setRadius(scaledRadius); + return this._leaflet.circleMarker(latlng).setRadius(scaledRadius); }; } diff --git a/src/plugins/tile_map/public/markers/shaded_circles.js b/src/plugins/tile_map/public/markers/shaded_circles.js index 745d0422856c6..3468cab7d8b75 100644 --- a/src/plugins/tile_map/public/markers/shaded_circles.js +++ b/src/plugins/tile_map/public/markers/shaded_circles.js @@ -19,7 +19,6 @@ import _ from 'lodash'; import { ScaledCirclesMarkers } from './scaled_circles'; -import { L } from '../../../maps_legacy/public'; export class ShadedCirclesMarkers extends ScaledCirclesMarkers { getMarkerFunction() { @@ -27,7 +26,7 @@ export class ShadedCirclesMarkers extends ScaledCirclesMarkers { const scaleFactor = 0.8; return (feature, latlng) => { const radius = this._geohashMinDistance(feature) * scaleFactor; - return L.circle(latlng, radius); + return this._leaflet.circle(latlng, radius); }; } @@ -49,12 +48,12 @@ export class ShadedCirclesMarkers extends ScaledCirclesMarkers { // clockwise, each value being an array of [lat, lng] // center lat and southeast lng - const east = L.latLng([centerPoint[0], geohashRect[2][1]]); + const east = this._leaflet.latLng([centerPoint[0], geohashRect[2][1]]); // southwest lat and center lng - const north = L.latLng([geohashRect[3][0], centerPoint[1]]); + const north = this._leaflet.latLng([geohashRect[3][0], centerPoint[1]]); // get latLng of geohash center point - const center = L.latLng([centerPoint[0], centerPoint[1]]); + const center = this._leaflet.latLng([centerPoint[0], centerPoint[1]]); // get smallest radius at center of geohash grid rectangle const eastRadius = Math.floor(center.distanceTo(east)); diff --git a/src/plugins/tile_map/public/tile_map_visualization.js b/src/plugins/tile_map/public/tile_map_visualization.js index 2ebb76d05c219..9b3d61caa9cc9 100644 --- a/src/plugins/tile_map/public/tile_map_visualization.js +++ b/src/plugins/tile_map/public/tile_map_visualization.js @@ -148,6 +148,10 @@ export const createTileMapVisualization = (dependencies) => { } _recreateGeohashLayer() { + if (!this._leaflet) { + return; + } + if (this._geohashLayer) { this._kibanaMap.removeLayer(this._geohashLayer); this._geohashLayer = null; @@ -158,7 +162,8 @@ export const createTileMapVisualization = (dependencies) => { this._geoJsonFeatureCollectionAndMeta.meta, geohashOptions, this._kibanaMap.getZoomLevel(), - this._kibanaMap + this._kibanaMap, + this._leaflet ); this._kibanaMap.addLayer(this._geohashLayer); } diff --git a/src/plugins/vis_type_vega/public/vega_view/vega_map_layer.js b/src/plugins/vis_type_vega/public/vega_view/vega_map_layer.js index bc1cb4e4734c7..ec4959a51d741 100644 --- a/src/plugins/vis_type_vega/public/vega_view/vega_map_layer.js +++ b/src/plugins/vis_type_vega/public/vega_view/vega_map_layer.js @@ -17,16 +17,16 @@ * under the License. */ -import { KibanaMapLayer, L } from '../../../maps_legacy/public'; +import { KibanaMapLayer } from '../../../maps_legacy/public'; export class VegaMapLayer extends KibanaMapLayer { - constructor(spec, options) { + constructor(spec, options, leaflet) { super(); // Used by super.getAttributions() this._attribution = options.attribution; delete options.attribution; - this._leafletLayer = L.vega(spec, options); + this._leafletLayer = leaflet.vega(spec, options); } getVegaView() { diff --git a/src/plugins/vis_type_vega/public/vega_view/vega_map_view.js b/src/plugins/vis_type_vega/public/vega_view/vega_map_view.js index 9b0ad2de7bbcd..d925aaeeced66 100644 --- a/src/plugins/vis_type_vega/public/vega_view/vega_map_view.js +++ b/src/plugins/vis_type_vega/public/vega_view/vega_map_view.js @@ -125,14 +125,18 @@ export class VegaMapView extends VegaBaseView { }); } - const vegaMapLayer = new VegaMapLayer(this._parser.spec, { - vega, - bindingsContainer: this._$controls.get(0), - delayRepaint: mapConfig.delayRepaint, - viewConfig: this._vegaViewConfig, - onWarning: this.onWarn.bind(this), - onError: this.onError.bind(this), - }); + const vegaMapLayer = new VegaMapLayer( + this._parser.spec, + { + vega, + bindingsContainer: this._$controls.get(0), + delayRepaint: mapConfig.delayRepaint, + viewConfig: this._vegaViewConfig, + onWarning: this.onWarn.bind(this), + onError: this.onError.bind(this), + }, + modules.L + ); this._kibanaMap.addLayer(vegaMapLayer); From a5517693fcc327d7c0c9ab5b67bc8b07af17cdb4 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 22 Sep 2020 09:06:30 -0600 Subject: [PATCH 04/10] try to get lodash out of maps_legacy bundle and work on tile_map bundle --- src/plugins/maps_legacy/public/index.ts | 3 +- .../public/lazy_load_bundle/index.ts | 2 +- .../public/map/base_maps_visualization.js | 14 +++--- .../maps_legacy/public/map/decode_geo_hash.ts | 29 ------------ .../maps_legacy/public/map/grid_dimensions.js | 4 +- .../maps_legacy/public/map/kibana_map.js | 10 ++-- .../public/map/service_settings.js | 46 +++++++++++-------- .../tile_map/public/tile_map_visualization.js | 36 +++++++++++++-- 8 files changed, 72 insertions(+), 72 deletions(-) diff --git a/src/plugins/maps_legacy/public/index.ts b/src/plugins/maps_legacy/public/index.ts index 5ff85e685d944..42b1e0a48cd7f 100644 --- a/src/plugins/maps_legacy/public/index.ts +++ b/src/plugins/maps_legacy/public/index.ts @@ -27,7 +27,7 @@ import { KibanaMapLayer } from './map/kibana_map_layer'; // @ts-ignore import { convertToGeoJson } from './map/convert_to_geojson'; // @ts-ignore -import { scaleBounds, getPrecision, geoContains } from './map/decode_geo_hash'; +import { getPrecision, geoContains } from './map/decode_geo_hash'; import { VectorLayer, FileLayerField, @@ -46,7 +46,6 @@ export function plugin(initializerContext: PluginInitializerContext) { /** @public */ export { - scaleBounds, getPrecision, geoContains, colorUtil, diff --git a/src/plugins/maps_legacy/public/lazy_load_bundle/index.ts b/src/plugins/maps_legacy/public/lazy_load_bundle/index.ts index b566a4cc11188..82840b60d7035 100644 --- a/src/plugins/maps_legacy/public/lazy_load_bundle/index.ts +++ b/src/plugins/maps_legacy/public/lazy_load_bundle/index.ts @@ -30,7 +30,7 @@ export async function lazyLoadMapsLegacyModules(): Promise { - const { KibanaMap } = await import('./lazy'); + const { KibanaMap, L } = await import('./lazy'); resolve({ KibanaMap, diff --git a/src/plugins/maps_legacy/public/map/base_maps_visualization.js b/src/plugins/maps_legacy/public/map/base_maps_visualization.js index eb4c3d18eed65..a17eff70b39c7 100644 --- a/src/plugins/maps_legacy/public/map/base_maps_visualization.js +++ b/src/plugins/maps_legacy/public/map/base_maps_visualization.js @@ -17,7 +17,6 @@ * under the License. */ -import _ from 'lodash'; import { i18n } from '@kbn/i18n'; import * as Rx from 'rxjs'; import { filter, first } from 'rxjs/operators'; @@ -197,7 +196,7 @@ export function BaseMapsVisualizationProvider(mapServiceSettings) { isDarkMode ); const showZoomMessage = serviceSettings.shouldShowZoomMessage(tmsLayer); - const options = _.cloneDeep(tmsLayer); + const options = { ...tmsLayer }; delete options.id; delete options.subdomains; this._kibanaMap.setBaseLayer({ @@ -230,12 +229,11 @@ export function BaseMapsVisualizationProvider(mapServiceSettings) { } _getMapsParams() { - return _.assign( - {}, - this.vis.type.visConfig.defaults, - { type: this.vis.type.name }, - this._params - ); + return { + ...this.vis.type.visConfig.defaults, + type: this.vis.type.name, + ...this._params, + }; } _whenBaseLayerIsLoaded() { diff --git a/src/plugins/maps_legacy/public/map/decode_geo_hash.ts b/src/plugins/maps_legacy/public/map/decode_geo_hash.ts index 8c39ada03a46b..65184a8244777 100644 --- a/src/plugins/maps_legacy/public/map/decode_geo_hash.ts +++ b/src/plugins/maps_legacy/public/map/decode_geo_hash.ts @@ -17,8 +17,6 @@ * under the License. */ -import _ from 'lodash'; - interface DecodedGeoHash { latitude: number[]; longitude: number[]; @@ -101,33 +99,6 @@ interface GeoBoundingBox { bottom_right: GeoBoundingBoxCoordinate; } -export function scaleBounds(bounds: GeoBoundingBox): GeoBoundingBox { - const scale = 0.5; // scale bounds by 50% - - const topLeft = bounds.top_left; - const bottomRight = bounds.bottom_right; - let latDiff = _.round(Math.abs(topLeft.lat - bottomRight.lat), 5); - const lonDiff = _.round(Math.abs(bottomRight.lon - topLeft.lon), 5); - // map height can be zero when vis is first created - if (latDiff === 0) latDiff = lonDiff; - - const latDelta = latDiff * scale; - let topLeftLat = _.round(topLeft.lat, 5) + latDelta; - if (topLeftLat > 90) topLeftLat = 90; - let bottomRightLat = _.round(bottomRight.lat, 5) - latDelta; - if (bottomRightLat < -90) bottomRightLat = -90; - const lonDelta = lonDiff * scale; - let topLeftLon = _.round(topLeft.lon, 5) - lonDelta; - if (topLeftLon < -180) topLeftLon = -180; - let bottomRightLon = _.round(bottomRight.lon, 5) + lonDelta; - if (bottomRightLon > 180) bottomRightLon = 180; - - return { - top_left: { lat: topLeftLat, lon: topLeftLon }, - bottom_right: { lat: bottomRightLat, lon: bottomRightLon }, - }; -} - export function geoContains(collar?: GeoBoundingBox, bounds?: GeoBoundingBox) { if (!bounds || !collar) return false; // test if bounds top_left is outside collar diff --git a/src/plugins/maps_legacy/public/map/grid_dimensions.js b/src/plugins/maps_legacy/public/map/grid_dimensions.js index d146adf2ca67f..0f84e972104ba 100644 --- a/src/plugins/maps_legacy/public/map/grid_dimensions.js +++ b/src/plugins/maps_legacy/public/map/grid_dimensions.js @@ -17,8 +17,6 @@ * under the License. */ -import _ from 'lodash'; - // geohash precision mapping of geohash grid cell dimensions (width x height, in meters) at equator. // https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-geohashgrid-aggregation.html#_cell_dimensions_at_the_equator const gridAtEquator = { @@ -37,5 +35,5 @@ const gridAtEquator = { }; export function gridDimensions(precision) { - return _.get(gridAtEquator, precision); + return gridAtEquator[precision]; } diff --git a/src/plugins/maps_legacy/public/map/kibana_map.js b/src/plugins/maps_legacy/public/map/kibana_map.js index ad5d2c089b875..3948692e55676 100644 --- a/src/plugins/maps_legacy/public/map/kibana_map.js +++ b/src/plugins/maps_legacy/public/map/kibana_map.js @@ -20,7 +20,7 @@ import { EventEmitter } from 'events'; import { createZoomWarningMsg } from './map_messages'; import $ from 'jquery'; -import _ from 'lodash'; +import { get, isEqual, escape } from 'lodash'; import { zoomToPrecision } from './zoom_to_precision'; import { i18n } from '@kbn/i18n'; import { ORIGIN } from '../common/constants/origin'; @@ -380,7 +380,7 @@ export class KibanaMap extends EventEmitter { const distanceX = latLngC.distanceTo(latLngX); // calculate distance between c and x (latitude) const distanceY = latLngC.distanceTo(latLngY); // calculate distance between c and y (longitude) - return _.min([distanceX, distanceY]); + return Math.min(distanceX, distanceY); } _getLeafletBounds(resizeOnFail) { @@ -544,7 +544,7 @@ export class KibanaMap extends EventEmitter { } setBaseLayer(settings) { - if (_.isEqual(settings, this._baseLayerSettings)) { + if (isEqual(settings, this._baseLayerSettings)) { return; } @@ -567,7 +567,7 @@ export class KibanaMap extends EventEmitter { let baseLayer; if (settings.baseLayerType === 'wms') { //This is user-input that is rendered with the Leaflet attribution control. Needs to be sanitized. - this._baseLayerSettings.options.attribution = _.escape(settings.options.attribution); + this._baseLayerSettings.options.attribution = escape(settings.options.attribution); baseLayer = this._getWMSBaseLayer(settings.options); } else if (settings.baseLayerType === 'tms') { baseLayer = this._getTMSBaseLayer(settings.options); @@ -661,7 +661,7 @@ export class KibanaMap extends EventEmitter { _updateDesaturation() { const tiles = $('img.leaflet-tile-loaded'); // Don't apply client-side styling to EMS basemaps - if (_.get(this._baseLayerSettings, 'options.origin') === ORIGIN.EMS) { + if (get(this._baseLayerSettings, 'options.origin') === ORIGIN.EMS) { tiles.addClass('filters-off'); } else { if (this._baseLayerIsDesaturated) { diff --git a/src/plugins/maps_legacy/public/map/service_settings.js b/src/plugins/maps_legacy/public/map/service_settings.js index 833304378402a..3cbefe00f7602 100644 --- a/src/plugins/maps_legacy/public/map/service_settings.js +++ b/src/plugins/maps_legacy/public/map/service_settings.js @@ -17,7 +17,6 @@ * under the License. */ -import _ from 'lodash'; import MarkdownIt from 'markdown-it'; import { EMSClient } from '@elastic/ems-client'; import { i18n } from '@kbn/i18n'; @@ -45,20 +44,6 @@ export class ServiceSettings { return fetch(...args); }, }); - this.getTMSOptions(); - } - - getTMSOptions() { - const markdownIt = new MarkdownIt({ - html: false, - linkify: true, - }); - - // TMS Options - this.tmsOptionsFromConfig = _.assign({}, this._tilemapsConfig.options, { - attribution: _.escape(markdownIt.render(this._tilemapsConfig.options.attribution || '')), - url: this._tilemapsConfig.url, - }); } shouldShowZoomMessage({ origin }) { @@ -121,8 +106,19 @@ export class ServiceSettings { async getTMSServices() { let allServices = []; if (this._hasTmsConfigured) { + const { escape } = await import('lodash'); + + const markdownIt = new MarkdownIt({ + html: false, + linkify: true, + }); + //use tilemap.* settings from yml - const tmsService = _.cloneDeep(this.tmsOptionsFromConfig); + const tmsService = { + ...this._tilemapsConfig.options, + attribution: escape(markdownIt.render(this._tilemapsConfig.options.attribution || '')), + url: this._tilemapsConfig.url, + }; tmsService.id = TMS_IN_YML_ID; tmsService.origin = ORIGIN.KIBANA_YML; allServices.push(tmsService); @@ -208,13 +204,23 @@ export class ServiceSettings { if (tmsServiceConfig.origin === ORIGIN.EMS) { return this._getAttributesForEMSTMSLayer(isDesaturated, isDarkMode); } else if (tmsServiceConfig.origin === ORIGIN.KIBANA_YML) { - const attrs = _.pick(this._tilemapsConfig, ['url', 'minzoom', 'maxzoom', 'attribution']); - return { ...attrs, ...{ origin: ORIGIN.KIBANA_YML } }; + return { + url: this._tilemapsConfig.url, + minzoom: this._tilemapsConfig.minzoom, + maxzoom: this._tilemapsConfig.maxzoom, + attribution: this._tilemapsConfig.attribution, + origin: ORIGIN.KIBANA_YML, + }; } else { //this is an older config. need to resolve this dynamically. if (tmsServiceConfig.id === TMS_IN_YML_ID) { - const attrs = _.pick(this._tilemapsConfig, ['url', 'minzoom', 'maxzoom', 'attribution']); - return { ...attrs, ...{ origin: ORIGIN.KIBANA_YML } }; + return { + url: this._tilemapsConfig.url, + minzoom: this._tilemapsConfig.minzoom, + maxzoom: this._tilemapsConfig.maxzoom, + attribution: this._tilemapsConfig.attribution, + origin: ORIGIN.KIBANA_YML, + }; } else { //assume ems return this._getAttributesForEMSTMSLayer(isDesaturated, isDarkMode); diff --git a/src/plugins/tile_map/public/tile_map_visualization.js b/src/plugins/tile_map/public/tile_map_visualization.js index 9b3d61caa9cc9..53af2b864f4cd 100644 --- a/src/plugins/tile_map/public/tile_map_visualization.js +++ b/src/plugins/tile_map/public/tile_map_visualization.js @@ -17,12 +17,38 @@ * under the License. */ -import { get } from 'lodash'; -import { GeohashLayer } from './geohash_layer'; +import { get, round } from 'lodash'; import { getFormatService, getQueryService, getKibanaLegacy } from './services'; -import { scaleBounds, geoContains, mapTooltipProvider } from '../../maps_legacy/public'; +import { geoContains, mapTooltipProvider } from '../../maps_legacy/public'; import { tooltipFormatter } from './tooltip_formatter'; +function scaleBounds(bounds) { + const scale = 0.5; // scale bounds by 50% + + const topLeft = bounds.top_left; + const bottomRight = bounds.bottom_right; + let latDiff = round(Math.abs(topLeft.lat - bottomRight.lat), 5); + const lonDiff = round(Math.abs(bottomRight.lon - topLeft.lon), 5); + // map height can be zero when vis is first created + if (latDiff === 0) latDiff = lonDiff; + + const latDelta = latDiff * scale; + let topLeftLat = round(topLeft.lat, 5) + latDelta; + if (topLeftLat > 90) topLeftLat = 90; + let bottomRightLat = round(bottomRight.lat, 5) - latDelta; + if (bottomRightLat < -90) bottomRightLat = -90; + const lonDelta = lonDiff * scale; + let topLeftLon = round(topLeft.lon, 5) - lonDelta; + if (topLeftLon < -180) topLeftLon = -180; + let bottomRightLon = round(bottomRight.lon, 5) + lonDelta; + if (bottomRightLon > 180) bottomRightLon = 180; + + return { + top_left: { lat: topLeftLat, lon: topLeftLon }, + bottom_right: { lat: bottomRightLat, lon: bottomRightLon }, + }; +} + export const createTileMapVisualization = (dependencies) => { const { getZoomPrecision, getPrecision, BaseMapsVisualization } = dependencies; @@ -147,7 +173,9 @@ export const createTileMapVisualization = (dependencies) => { this._recreateGeohashLayer(); } - _recreateGeohashLayer() { + async _recreateGeohashLayer() { + const { GeohashLayer } = await import('./geohash_layer'); + if (!this._leaflet) { return; } From 88f92fcebe1db60c0032fdfd4ee5c7922dfa04a6 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 22 Sep 2020 12:50:23 -0600 Subject: [PATCH 05/10] lazy load service settings --- .../public/get_service_settings.ts | 37 +++++++++++++++ src/plugins/maps_legacy/public/index.ts | 2 +- .../public/lazy_load_bundle/index.ts | 4 +- .../public/lazy_load_bundle/lazy/index.ts | 2 + .../public/map/base_maps_visualization.js | 20 ++++---- .../public/map/service_settings.js | 46 ++++++++----------- ...ettings.d.ts => service_settings_types.ts} | 0 src/plugins/maps_legacy/public/plugin.ts | 8 ++-- .../public/components/region_map_options.tsx | 7 +-- src/plugins/region_map/public/plugin.ts | 4 +- .../region_map/public/region_map_type.js | 7 ++- .../public/region_map_visualization.js | 9 ++-- src/plugins/tile_map/public/plugin.ts | 6 +-- src/plugins/tile_map/public/tile_map_type.js | 3 +- .../public/data_model/vega_parser.ts | 28 +++++++---- src/plugins/vis_type_vega/public/plugin.ts | 4 +- .../public/vega_request_handler.ts | 4 +- .../public/vega_visualization.js | 3 +- .../maps_legacy_licensing/public/plugin.ts | 8 ++-- 19 files changed, 123 insertions(+), 79 deletions(-) create mode 100644 src/plugins/maps_legacy/public/get_service_settings.ts rename src/plugins/maps_legacy/public/map/{service_settings.d.ts => service_settings_types.ts} (100%) diff --git a/src/plugins/maps_legacy/public/get_service_settings.ts b/src/plugins/maps_legacy/public/get_service_settings.ts new file mode 100644 index 0000000000000..bcca6dc6bc9ba --- /dev/null +++ b/src/plugins/maps_legacy/public/get_service_settings.ts @@ -0,0 +1,37 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { lazyLoadMapsLegacyModules } from './lazy_load_bundle'; +import { getMapsLegacyConfig } from './kibana_services'; +import { IServiceSettings } from './map/service_settings_types'; + +let loadPromise: Promise; + +export async function getServiceSettings(): Promise { + if (typeof loadPromise !== 'undefined') { + return loadPromise; + } + + loadPromise = new Promise(async (resolve) => { + const modules = await lazyLoadMapsLegacyModules(); + const config = getMapsLegacyConfig(); + resolve(new modules.ServiceSettings(config, config.tilemap)); + }); + return loadPromise; +} diff --git a/src/plugins/maps_legacy/public/index.ts b/src/plugins/maps_legacy/public/index.ts index 42b1e0a48cd7f..d31f23f4bc4a6 100644 --- a/src/plugins/maps_legacy/public/index.ts +++ b/src/plugins/maps_legacy/public/index.ts @@ -34,7 +34,7 @@ import { FileLayer, TmsLayer, IServiceSettings, -} from './map/service_settings'; +} from './map/service_settings_types'; // @ts-ignore import { mapTooltipProvider } from './tooltip_provider'; diff --git a/src/plugins/maps_legacy/public/lazy_load_bundle/index.ts b/src/plugins/maps_legacy/public/lazy_load_bundle/index.ts index 82840b60d7035..292949503a616 100644 --- a/src/plugins/maps_legacy/public/lazy_load_bundle/index.ts +++ b/src/plugins/maps_legacy/public/lazy_load_bundle/index.ts @@ -22,6 +22,7 @@ let loadModulesPromise: Promise; interface LazyLoadedMapsLegacyModules { KibanaMap: unknown; L: unknown; + ServiceSettings: unknown; } export async function lazyLoadMapsLegacyModules(): Promise { @@ -30,11 +31,12 @@ export async function lazyLoadMapsLegacyModules(): Promise { - const { KibanaMap, L } = await import('./lazy'); + const { KibanaMap, L, ServiceSettings } = await import('./lazy'); resolve({ KibanaMap, L, + ServiceSettings, }); }); return loadModulesPromise; diff --git a/src/plugins/maps_legacy/public/lazy_load_bundle/lazy/index.ts b/src/plugins/maps_legacy/public/lazy_load_bundle/lazy/index.ts index f17f6dce7d393..5031b29e74b9a 100644 --- a/src/plugins/maps_legacy/public/lazy_load_bundle/lazy/index.ts +++ b/src/plugins/maps_legacy/public/lazy_load_bundle/lazy/index.ts @@ -20,4 +20,6 @@ // @ts-expect-error export { KibanaMap } from '../../map/kibana_map'; // @ts-expect-error +export { ServiceSettings } from '../../map/service_settings'; +// @ts-expect-error export { L } from '../../leaflet'; diff --git a/src/plugins/maps_legacy/public/map/base_maps_visualization.js b/src/plugins/maps_legacy/public/map/base_maps_visualization.js index a17eff70b39c7..fa2457c5bd9f3 100644 --- a/src/plugins/maps_legacy/public/map/base_maps_visualization.js +++ b/src/plugins/maps_legacy/public/map/base_maps_visualization.js @@ -22,20 +22,17 @@ import * as Rx from 'rxjs'; import { filter, first } from 'rxjs/operators'; import { getEmsTileLayerId, getUiSettings, getToasts } from '../kibana_services'; import { lazyLoadMapsLegacyModules } from '../lazy_load_bundle'; +import { getServiceSettings } from '../get_service_settings'; const WMS_MINZOOM = 0; const WMS_MAXZOOM = 22; //increase this to 22. Better for WMS -export function BaseMapsVisualizationProvider(mapServiceSettings) { +export function BaseMapsVisualizationProvider() { /** * Abstract base class for a visualization consisting of a map with a single baselayer. * @class BaseMapsVisualization * @constructor */ - - const serviceSettings = mapServiceSettings; - const toastService = getToasts(); - return class BaseMapsVisualization { constructor(element, vis) { this.vis = vis; @@ -99,6 +96,7 @@ export function BaseMapsVisualizationProvider(mapServiceSettings) { const modules = await lazyLoadMapsLegacyModules(); this._leaflet = modules.L; this._kibanaMap = new modules.KibanaMap(this._container, options); + this._serviceSettings = await getServiceSettings(); this._kibanaMap.setMinZoom(WMS_MINZOOM); //use a default this._kibanaMap.setMaxZoom(WMS_MAXZOOM); //use a default @@ -132,14 +130,14 @@ export function BaseMapsVisualizationProvider(mapServiceSettings) { async _updateBaseLayer() { const emsTileLayerId = getEmsTileLayerId(); - if (!this._kibanaMap) { + if (!this._kibanaMap || !this._serviceSettings) { return; } const mapParams = this._getMapsParams(); if (!this._tmsConfigured()) { try { - const tmsServices = await serviceSettings.getTMSServices(); + const tmsServices = await this._serviceSettings.getTMSServices(); const userConfiguredTmsLayer = tmsServices[0]; const initBasemapLayer = userConfiguredTmsLayer ? userConfiguredTmsLayer @@ -148,7 +146,7 @@ export function BaseMapsVisualizationProvider(mapServiceSettings) { this._setTmsLayer(initBasemapLayer); } } catch (e) { - toastService.addWarning(e.message); + getToasts().addWarning(e.message); return; } return; @@ -175,7 +173,7 @@ export function BaseMapsVisualizationProvider(mapServiceSettings) { this._setTmsLayer(selectedTmsLayer); } } catch (tmsLoadingError) { - toastService.addWarning(tmsLoadingError.message); + getToasts().addWarning(tmsLoadingError.message); } } @@ -190,12 +188,12 @@ export function BaseMapsVisualizationProvider(mapServiceSettings) { isDesaturated = true; } const isDarkMode = getUiSettings().get('theme:darkMode'); - const meta = await serviceSettings.getAttributesForTMSLayer( + const meta = await this._serviceSettings.getAttributesForTMSLayer( tmsLayer, isDesaturated, isDarkMode ); - const showZoomMessage = serviceSettings.shouldShowZoomMessage(tmsLayer); + const showZoomMessage = this._serviceSettings.shouldShowZoomMessage(tmsLayer); const options = { ...tmsLayer }; delete options.id; delete options.subdomains; diff --git a/src/plugins/maps_legacy/public/map/service_settings.js b/src/plugins/maps_legacy/public/map/service_settings.js index 3cbefe00f7602..833304378402a 100644 --- a/src/plugins/maps_legacy/public/map/service_settings.js +++ b/src/plugins/maps_legacy/public/map/service_settings.js @@ -17,6 +17,7 @@ * under the License. */ +import _ from 'lodash'; import MarkdownIt from 'markdown-it'; import { EMSClient } from '@elastic/ems-client'; import { i18n } from '@kbn/i18n'; @@ -44,6 +45,20 @@ export class ServiceSettings { return fetch(...args); }, }); + this.getTMSOptions(); + } + + getTMSOptions() { + const markdownIt = new MarkdownIt({ + html: false, + linkify: true, + }); + + // TMS Options + this.tmsOptionsFromConfig = _.assign({}, this._tilemapsConfig.options, { + attribution: _.escape(markdownIt.render(this._tilemapsConfig.options.attribution || '')), + url: this._tilemapsConfig.url, + }); } shouldShowZoomMessage({ origin }) { @@ -106,19 +121,8 @@ export class ServiceSettings { async getTMSServices() { let allServices = []; if (this._hasTmsConfigured) { - const { escape } = await import('lodash'); - - const markdownIt = new MarkdownIt({ - html: false, - linkify: true, - }); - //use tilemap.* settings from yml - const tmsService = { - ...this._tilemapsConfig.options, - attribution: escape(markdownIt.render(this._tilemapsConfig.options.attribution || '')), - url: this._tilemapsConfig.url, - }; + const tmsService = _.cloneDeep(this.tmsOptionsFromConfig); tmsService.id = TMS_IN_YML_ID; tmsService.origin = ORIGIN.KIBANA_YML; allServices.push(tmsService); @@ -204,23 +208,13 @@ export class ServiceSettings { if (tmsServiceConfig.origin === ORIGIN.EMS) { return this._getAttributesForEMSTMSLayer(isDesaturated, isDarkMode); } else if (tmsServiceConfig.origin === ORIGIN.KIBANA_YML) { - return { - url: this._tilemapsConfig.url, - minzoom: this._tilemapsConfig.minzoom, - maxzoom: this._tilemapsConfig.maxzoom, - attribution: this._tilemapsConfig.attribution, - origin: ORIGIN.KIBANA_YML, - }; + const attrs = _.pick(this._tilemapsConfig, ['url', 'minzoom', 'maxzoom', 'attribution']); + return { ...attrs, ...{ origin: ORIGIN.KIBANA_YML } }; } else { //this is an older config. need to resolve this dynamically. if (tmsServiceConfig.id === TMS_IN_YML_ID) { - return { - url: this._tilemapsConfig.url, - minzoom: this._tilemapsConfig.minzoom, - maxzoom: this._tilemapsConfig.maxzoom, - attribution: this._tilemapsConfig.attribution, - origin: ORIGIN.KIBANA_YML, - }; + const attrs = _.pick(this._tilemapsConfig, ['url', 'minzoom', 'maxzoom', 'attribution']); + return { ...attrs, ...{ origin: ORIGIN.KIBANA_YML } }; } else { //assume ems return this._getAttributesForEMSTMSLayer(isDesaturated, isDarkMode); diff --git a/src/plugins/maps_legacy/public/map/service_settings.d.ts b/src/plugins/maps_legacy/public/map/service_settings_types.ts similarity index 100% rename from src/plugins/maps_legacy/public/map/service_settings.d.ts rename to src/plugins/maps_legacy/public/map/service_settings_types.ts diff --git a/src/plugins/maps_legacy/public/plugin.ts b/src/plugins/maps_legacy/public/plugin.ts index ae60593f006e9..17cee226cb70c 100644 --- a/src/plugins/maps_legacy/public/plugin.ts +++ b/src/plugins/maps_legacy/public/plugin.ts @@ -22,13 +22,12 @@ import { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from 'kibana/p // @ts-ignore import { setToasts, setUiSettings, setKibanaVersion, setMapsLegacyConfig } from './kibana_services'; // @ts-ignore -import { ServiceSettings } from './map/service_settings'; -// @ts-ignore import { getPrecision, getZoomPrecision } from './map/precision'; import { MapsLegacyPluginSetup, MapsLegacyPluginStart } from './index'; import { MapsLegacyConfig } from '../config'; // @ts-ignore import { BaseMapsVisualizationProvider } from './map/base_maps_visualization'; +import { getServiceSettings } from './get_service_settings'; /** * These are the interfaces with your public contracts. You should export these @@ -65,11 +64,10 @@ export class MapsLegacyPlugin implements Plugin new BaseMapsVisualizationProvider(serviceSettings); + const getBaseMapsVis = () => new BaseMapsVisualizationProvider(); return { - serviceSettings, + getServiceSettings, getZoomPrecision, getPrecision, config, diff --git a/src/plugins/region_map/public/components/region_map_options.tsx b/src/plugins/region_map/public/components/region_map_options.tsx index be3d7fe86ab3f..4d564d7347a1e 100644 --- a/src/plugins/region_map/public/components/region_map_options.tsx +++ b/src/plugins/region_map/public/components/region_map_options.tsx @@ -37,11 +37,11 @@ const mapFieldForOption = ({ description, name }: FileLayerField) => ({ }); export type RegionMapOptionsProps = { - serviceSettings: IServiceSettings; + getServiceSettings: () => Promise; } & VisOptionsProps; function RegionMapOptions(props: RegionMapOptionsProps) { - const { serviceSettings, stateParams, vis, setValue } = props; + const { getServiceSettings, stateParams, vis, setValue } = props; const { vectorLayers } = vis.type.editorConfig.collections; const vectorLayerOptions = useMemo(() => vectorLayers.map(mapLayerForOption), [vectorLayers]); const fieldOptions = useMemo( @@ -54,10 +54,11 @@ function RegionMapOptions(props: RegionMapOptionsProps) { const setEmsHotLink = useCallback( async (layer: VectorLayer) => { + const serviceSettings = await getServiceSettings(); const emsHotLink = await serviceSettings.getEMSHotLink(layer); setValue('emsHotLink', emsHotLink); }, - [setValue, serviceSettings] + [setValue, getServiceSettings] ); const setLayer = useCallback( diff --git a/src/plugins/region_map/public/plugin.ts b/src/plugins/region_map/public/plugin.ts index ec9ee94310578..c641c16a8112b 100644 --- a/src/plugins/region_map/public/plugin.ts +++ b/src/plugins/region_map/public/plugin.ts @@ -41,7 +41,7 @@ import { KibanaLegacyStart } from '../../kibana_legacy/public'; interface RegionMapVisualizationDependencies { uiSettings: IUiSettingsClient; regionmapsConfig: RegionMapsConfig; - serviceSettings: IServiceSettings; + getServiceSettings: () => Promise; BaseMapsVisualization: any; } @@ -93,7 +93,7 @@ export class RegionMapPlugin implements Plugin = { uiSettings: core.uiSettings, regionmapsConfig: config as RegionMapsConfig, - serviceSettings: mapsLegacy.serviceSettings, + getServiceSettings: mapsLegacy.getServiceSettings, BaseMapsVisualization: mapsLegacy.getBaseMapsVis(), }; diff --git a/src/plugins/region_map/public/region_map_type.js b/src/plugins/region_map/public/region_map_type.js index def95950e6151..036726f6a4a9e 100644 --- a/src/plugins/region_map/public/region_map_type.js +++ b/src/plugins/region_map/public/region_map_type.js @@ -26,7 +26,7 @@ import { Schemas } from '../../vis_default_editor/public'; import { ORIGIN } from '../../maps_legacy/public'; export function createRegionMapTypeDefinition(dependencies) { - const { uiSettings, regionmapsConfig, serviceSettings } = dependencies; + const { uiSettings, regionmapsConfig, getServiceSettings } = dependencies; const visualization = createRegionMapVisualization(dependencies); return { @@ -54,7 +54,9 @@ provided base maps, or add your own. Darker colors represent higher values.', }, visualization, editorConfig: { - optionsTemplate: (props) => , + optionsTemplate: (props) => ( + + ), collections: { colorSchemas: truncatedColorSchemas, vectorLayers: [], @@ -97,6 +99,7 @@ provided base maps, or add your own. Darker colors represent higher values.', ]), }, setup: async (vis) => { + const serviceSettings = await getServiceSettings(); const tmsLayers = await serviceSettings.getTMSServices(); vis.type.editorConfig.collections.tmsLayers = tmsLayers; if (!vis.params.wms.selectedTmsLayer && tmsLayers.length) { diff --git a/src/plugins/region_map/public/region_map_visualization.js b/src/plugins/region_map/public/region_map_visualization.js index d91929efb9805..28a7178162efb 100644 --- a/src/plugins/region_map/public/region_map_visualization.js +++ b/src/plugins/region_map/public/region_map_visualization.js @@ -27,7 +27,6 @@ import _ from 'lodash'; export function createRegionMapVisualization({ regionmapsConfig, - serviceSettings, uiSettings, BaseMapsVisualization, }) { @@ -102,7 +101,9 @@ export function createRegionMapVisualization({ fileLayerConfig.isEMS || //Hosted by EMS. Metadata needs to be resolved through EMS (fileLayerConfig.layerId && fileLayerConfig.layerId.startsWith(`${ORIGIN.EMS}.`)) //fallback for older saved objects ) { - return await serviceSettings.loadFileLayerConfig(fileLayerConfig); + return this._serviceSettings + ? await this._serviceSettings.loadFileLayerConfig(fileLayerConfig) + : null; } //Configured in the kibana.yml. Needs to be resolved through the settings. @@ -182,7 +183,7 @@ export function createRegionMapVisualization({ showAllData, this._params.selectedLayer.meta, this._params.selectedLayer, - serviceSettings + this._serviceSettings ); } else { this._choroplethLayer = new ChoroplethLayer( @@ -192,7 +193,7 @@ export function createRegionMapVisualization({ showAllData, this._params.selectedLayer.meta, this._params.selectedLayer, - serviceSettings, + this._serviceSettings, this._leaflet ); } diff --git a/src/plugins/tile_map/public/plugin.ts b/src/plugins/tile_map/public/plugin.ts index 9a164f8a303f8..bc26fa1f687d4 100644 --- a/src/plugins/tile_map/public/plugin.ts +++ b/src/plugins/tile_map/public/plugin.ts @@ -47,7 +47,7 @@ interface TileMapVisualizationDependencies { getZoomPrecision: any; getPrecision: any; BaseMapsVisualization: any; - serviceSettings: IServiceSettings; + getServiceSettings: Promise; } /** @internal */ @@ -81,13 +81,13 @@ export class TileMapPlugin implements Plugin = { getZoomPrecision, getPrecision, BaseMapsVisualization: mapsLegacy.getBaseMapsVis(), uiSettings: core.uiSettings, - serviceSettings, + getServiceSettings, }; expressions.registerFunction(() => createTileMapFn(visualizationDependencies)); diff --git a/src/plugins/tile_map/public/tile_map_type.js b/src/plugins/tile_map/public/tile_map_type.js index f76da26022a77..2b23f345f012e 100644 --- a/src/plugins/tile_map/public/tile_map_type.js +++ b/src/plugins/tile_map/public/tile_map_type.js @@ -28,7 +28,7 @@ import { truncatedColorSchemas } from '../../charts/public'; export function createTileMapTypeDefinition(dependencies) { const CoordinateMapsVisualization = createTileMapVisualization(dependencies); - const { uiSettings, serviceSettings } = dependencies; + const { uiSettings, getServiceSettings } = dependencies; return { name: 'tile_map', @@ -142,6 +142,7 @@ export function createTileMapTypeDefinition(dependencies) { let tmsLayers; try { + const serviceSettings = await getServiceSettings(); tmsLayers = await serviceSettings.getTMSServices(); } catch (e) { return vis; diff --git a/src/plugins/vis_type_vega/public/data_model/vega_parser.ts b/src/plugins/vis_type_vega/public/data_model/vega_parser.ts index b3fb2d54cb266..d835ab7be06fa 100644 --- a/src/plugins/vis_type_vega/public/data_model/vega_parser.ts +++ b/src/plugins/vis_type_vega/public/data_model/vega_parser.ts @@ -65,7 +65,7 @@ export class VegaParser { hideWarnings: boolean; error?: string; warnings: string[]; - _urlParsers: UrlParserConfig; + _urlParsers: UrlParserConfig | undefined; isVegaLite?: boolean; useHover?: boolean; _config?: VegaConfig; @@ -80,13 +80,16 @@ export class VegaParser { containerDir?: ControlsLocation | ControlsDirection; controlsDir?: ControlsLocation; searchAPI: SearchAPI; + getServiceSettings: () => Promse; + filters: Bool; + timeCache: TimeCache; constructor( spec: VegaSpec | string, searchAPI: SearchAPI, timeCache: TimeCache, filters: Bool, - serviceSettings: IServiceSettings + getServiceSettings: () => Promse ) { this.spec = spec as VegaSpec; this.hideWarnings = false; @@ -94,13 +97,9 @@ export class VegaParser { this.error = undefined; this.warnings = []; this.searchAPI = searchAPI; - - const onWarn = this._onWarning.bind(this); - this._urlParsers = { - elasticsearch: new EsQueryParser(timeCache, this.searchAPI, filters, onWarn), - emsfile: new EmsFileParser(serviceSettings), - url: new UrlParser(onWarn), - }; + this.getServiceSettings = getServiceSettings; + this.filters = filters; + this.timeCache = timeCache; } async parseAsync() { @@ -123,7 +122,7 @@ export class VegaParser { throw new Error( i18n.translate('visTypeVega.vegaParser.inputSpecDoesNotSpecifySchemaErrorMessage', { defaultMessage: `Your specification requires a {schemaParam} field with a valid URL for -Vega (see {vegaSchemaUrl}) or +Vega (see {vegaSchemaUrl}) or Vega-Lite (see {vegaLiteSchemaUrl}). The URL is an identifier only. Kibana and your browser will never access this URL.`, values: { @@ -547,6 +546,15 @@ The URL is an identifier only. Kibana and your browser will never access this UR * @private */ async _resolveDataUrls() { + if (!this._urlParsers) { + const serviceSettings = await this.getServiceSettings(); + const onWarn = this._onWarning.bind(this); + this._urlParsers = { + elasticsearch: new EsQueryParser(this.timeCache, this.searchAPI, this.filters, onWarn), + emsfile: new EmsFileParser(serviceSettings), + url: new UrlParser(onWarn), + }; + } const pending: PendingType = {}; this.searchAPI.resetSearchStats(); diff --git a/src/plugins/vis_type_vega/public/plugin.ts b/src/plugins/vis_type_vega/public/plugin.ts index a1be76949530f..ce5c5130961c6 100644 --- a/src/plugins/vis_type_vega/public/plugin.ts +++ b/src/plugins/vis_type_vega/public/plugin.ts @@ -46,7 +46,7 @@ export interface VegaVisualizationDependencies { plugins: { data: DataPublicPluginSetup; }; - serviceSettings: IServiceSettings; + getServiceSettings: () => Promise; } /** @internal */ @@ -87,7 +87,7 @@ export class VegaPlugin implements Plugin, void> { plugins: { data, }, - serviceSettings: mapsLegacy.serviceSettings, + getServiceSettings: mapsLegacy.getServiceSettings, }; inspector.registerView(getVegaInspectorView({ uiSettings: core.uiSettings })); diff --git a/src/plugins/vis_type_vega/public/vega_request_handler.ts b/src/plugins/vis_type_vega/public/vega_request_handler.ts index c09a9466df602..f48b61ed70822 100644 --- a/src/plugins/vis_type_vega/public/vega_request_handler.ts +++ b/src/plugins/vis_type_vega/public/vega_request_handler.ts @@ -40,7 +40,7 @@ interface VegaRequestHandlerContext { } export function createVegaRequestHandler( - { plugins: { data }, core: { uiSettings }, serviceSettings }: VegaVisualizationDependencies, + { plugins: { data }, core: { uiSettings }, getServiceSettings }: VegaVisualizationDependencies, context: VegaRequestHandlerContext = {} ) { let searchAPI: SearchAPI; @@ -70,7 +70,7 @@ export function createVegaRequestHandler( const esQueryConfigs = esQuery.getEsQueryConfig(uiSettings); const filtersDsl = esQuery.buildEsQuery(undefined, query, filters, esQueryConfigs); const { VegaParser } = await import('./data_model/vega_parser'); - const vp = new VegaParser(visParams.spec, searchAPI, timeCache, filtersDsl, serviceSettings); + const vp = new VegaParser(visParams.spec, searchAPI, timeCache, filtersDsl, getServiceSettings); return await vp.parseAsync(); }; diff --git a/src/plugins/vis_type_vega/public/vega_visualization.js b/src/plugins/vis_type_vega/public/vega_visualization.js index d6db0f9ea239f..2d58e9cda60cd 100644 --- a/src/plugins/vis_type_vega/public/vega_visualization.js +++ b/src/plugins/vis_type_vega/public/vega_visualization.js @@ -19,7 +19,7 @@ import { i18n } from '@kbn/i18n'; import { getNotifications, getData, getSavedObjects } from './services'; -export const createVegaVisualization = ({ serviceSettings }) => +export const createVegaVisualization = ({ getServiceSettings }) => class VegaVisualization { constructor(el, vis) { this._el = el; @@ -102,6 +102,7 @@ export const createVegaVisualization = ({ serviceSettings }) => this._vegaView = null; } + const serviceSettings = await getServiceSettings(); const { filterManager } = this.dataPlugin.query; const { timefilter } = this.dataPlugin.query.timefilter; const vegaViewParams = { diff --git a/x-pack/plugins/maps_legacy_licensing/public/plugin.ts b/x-pack/plugins/maps_legacy_licensing/public/plugin.ts index eaf527f856bc5..ed7321b2c0e74 100644 --- a/x-pack/plugins/maps_legacy_licensing/public/plugin.ts +++ b/x-pack/plugins/maps_legacy_licensing/public/plugin.ts @@ -26,12 +26,10 @@ export type MapsLegacyLicensingStart = ReturnType; export class MapsLegacyLicensing implements Plugin { public setup(core: CoreSetup, plugins: MapsLegacyLicensingSetupDependencies) { - const { - licensing, - mapsLegacy: { serviceSettings }, - } = plugins; + const { licensing, mapsLegacy } = plugins; if (licensing) { - licensing.license$.subscribe((license: ILicense) => { + licensing.license$.subscribe(async (license: ILicense) => { + const serviceSettings = await mapsLegacy.getServiceSettings(); const { uid, isActive } = license; if (isActive && license.hasAtLeast('basic')) { serviceSettings.setQueryParams({ license: uid }); From 9933bdc5c1867d4b74499d894ff6ddedd6228e9a Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 22 Sep 2020 13:43:49 -0600 Subject: [PATCH 06/10] lazy load region_map and fix vega unit tests --- .../region_map/public/choropleth_layer.js | 2 +- .../public/region_map_visualization.js | 16 +++++++-------- .../public/data_model/vega_parser.test.js | 15 ++++++++------ .../public/vega_visualization.test.js | 20 ++++++++++++++++--- 4 files changed, 35 insertions(+), 18 deletions(-) diff --git a/src/plugins/region_map/public/choropleth_layer.js b/src/plugins/region_map/public/choropleth_layer.js index 6aafef8a9b403..14a91e189e0d5 100644 --- a/src/plugins/region_map/public/choropleth_layer.js +++ b/src/plugins/region_map/public/choropleth_layer.js @@ -33,7 +33,7 @@ const EMPTY_STYLE = { fillOpacity: 0, }; -export default class ChoroplethLayer extends KibanaMapLayer { +export class ChoroplethLayer extends KibanaMapLayer { static _doInnerJoin(sortedMetrics, sortedGeojsonFeatures, joinField) { let j = 0; for (let i = 0; i < sortedGeojsonFeatures.length; i++) { diff --git a/src/plugins/region_map/public/region_map_visualization.js b/src/plugins/region_map/public/region_map_visualization.js index 28a7178162efb..e6c1434e07847 100644 --- a/src/plugins/region_map/public/region_map_visualization.js +++ b/src/plugins/region_map/public/region_map_visualization.js @@ -18,7 +18,6 @@ */ import { i18n } from '@kbn/i18n'; -import ChoroplethLayer from './choropleth_layer'; import { getFormatService, getNotifications, getKibanaLegacy } from './kibana_services'; import { truncatedColorMaps } from '../../charts/public'; import { tooltipFormatter } from './tooltip_formatter'; @@ -70,7 +69,7 @@ export function createRegionMapVisualization({ return; } - this._updateChoroplethLayerForNewMetrics( + await this._updateChoroplethLayerForNewMetrics( selectedLayer.name, selectedLayer.attribution, this._params.showAllShapes, @@ -134,7 +133,7 @@ export function createRegionMapVisualization({ return; } - this._updateChoroplethLayerForNewProperties( + await this._updateChoroplethLayerForNewProperties( selectedLayer.name, selectedLayer.attribution, this._params.showAllShapes @@ -152,24 +151,24 @@ export function createRegionMapVisualization({ ); } - _updateChoroplethLayerForNewMetrics(name, attribution, showAllData, newMetrics) { + async _updateChoroplethLayerForNewMetrics(name, attribution, showAllData, newMetrics) { if ( this._choroplethLayer && this._choroplethLayer.canReuseInstanceForNewMetrics(name, showAllData, newMetrics) ) { return; } - return this._recreateChoroplethLayer(name, attribution, showAllData); + await this._recreateChoroplethLayer(name, attribution, showAllData); } - _updateChoroplethLayerForNewProperties(name, attribution, showAllData) { + async _updateChoroplethLayerForNewProperties(name, attribution, showAllData) { if (this._choroplethLayer && this._choroplethLayer.canReuseInstance(name, showAllData)) { return; } - return this._recreateChoroplethLayer(name, attribution, showAllData); + await this._recreateChoroplethLayer(name, attribution, showAllData); } - _recreateChoroplethLayer(name, attribution, showAllData) { + async _recreateChoroplethLayer(name, attribution, showAllData) { if (!this._leaflet) { return; } @@ -186,6 +185,7 @@ export function createRegionMapVisualization({ this._serviceSettings ); } else { + const { ChoroplethLayer } = await import('./choropleth_layer'); this._choroplethLayer = new ChoroplethLayer( name, attribution, diff --git a/src/plugins/vis_type_vega/public/data_model/vega_parser.test.js b/src/plugins/vis_type_vega/public/data_model/vega_parser.test.js index 4883a8129903a..5c7656efe925b 100644 --- a/src/plugins/vis_type_vega/public/data_model/vega_parser.test.js +++ b/src/plugins/vis_type_vega/public/data_model/vega_parser.test.js @@ -162,12 +162,15 @@ describe('VegaParser._resolveEsQueries', () => { function check(spec, expected, warnCount) { return async () => { - const vp = new VegaParser(spec, searchApiStub, 0, 0, { - getFileLayers: async () => [{ name: 'file1', url: 'url1' }], - getUrlForRegionLayer: async (layer) => { - return layer.url; - }, - }); + const mockGetServiceSettings = async () => { + return { + getFileLayers: async () => [{ name: 'file1', url: 'url1' }], + getUrlForRegionLayer: async (layer) => { + return layer.url; + }, + }; + }; + const vp = new VegaParser(spec, searchApiStub, 0, 0, mockGetServiceSettings); await vp._resolveDataUrls(); expect(vp.spec).toEqual(expected); diff --git a/src/plugins/vis_type_vega/public/vega_visualization.test.js b/src/plugins/vis_type_vega/public/vega_visualization.test.js index 53363481f8717..dcf1722768075 100644 --- a/src/plugins/vis_type_vega/public/vega_visualization.test.js +++ b/src/plugins/vis_type_vega/public/vega_visualization.test.js @@ -70,6 +70,10 @@ describe('VegaVisualizations', () => { mockHeight = jest.spyOn($.prototype, 'height').mockImplementation(() => mockedHeightValue); }; + const mockGetServiceSettings = async () => { + return {}; + }; + beforeEach(() => { setInjectedVars({ emsTileLayerId: {}, @@ -84,6 +88,7 @@ describe('VegaVisualizations', () => { plugins: { data: dataPluginMock.createSetupContract(), }, + getServiceSettings: mockGetServiceSettings, }; vegaVisType = createVegaTypeDefinition(vegaVisualizationDependencies); @@ -120,7 +125,10 @@ describe('VegaVisualizations', () => { search: dataPluginStart.search, uiSettings: coreStart.uiSettings, injectedMetadata: coreStart.injectedMetadata, - }) + }), + 0, + 0, + mockGetServiceSettings ); await vegaParser.parseAsync(); await vegaVis.render(vegaParser); @@ -147,7 +155,10 @@ describe('VegaVisualizations', () => { search: dataPluginStart.search, uiSettings: coreStart.uiSettings, injectedMetadata: coreStart.injectedMetadata, - }) + }), + 0, + 0, + mockGetServiceSettings ); await vegaParser.parseAsync(); @@ -168,7 +179,10 @@ describe('VegaVisualizations', () => { search: dataPluginStart.search, uiSettings: coreStart.uiSettings, injectedMetadata: coreStart.injectedMetadata, - }) + }), + 0, + 0, + mockGetServiceSettings ); await vegaParser.parseAsync(); From d47b0cd675dce83c6822e528ff9a4c9b31862186 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 22 Sep 2020 15:19:54 -0600 Subject: [PATCH 07/10] tslint fixes --- src/plugins/maps_legacy/public/get_service_settings.ts | 2 ++ src/plugins/tile_map/public/plugin.ts | 2 +- .../vis_type_vega/public/data_model/vega_parser.ts | 8 ++++---- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/plugins/maps_legacy/public/get_service_settings.ts b/src/plugins/maps_legacy/public/get_service_settings.ts index bcca6dc6bc9ba..8d0656237976d 100644 --- a/src/plugins/maps_legacy/public/get_service_settings.ts +++ b/src/plugins/maps_legacy/public/get_service_settings.ts @@ -18,6 +18,7 @@ */ import { lazyLoadMapsLegacyModules } from './lazy_load_bundle'; +// @ts-expect-error import { getMapsLegacyConfig } from './kibana_services'; import { IServiceSettings } from './map/service_settings_types'; @@ -31,6 +32,7 @@ export async function getServiceSettings(): Promise { loadPromise = new Promise(async (resolve) => { const modules = await lazyLoadMapsLegacyModules(); const config = getMapsLegacyConfig(); + // @ts-expect-error resolve(new modules.ServiceSettings(config, config.tilemap)); }); return loadPromise; diff --git a/src/plugins/tile_map/public/plugin.ts b/src/plugins/tile_map/public/plugin.ts index bc26fa1f687d4..07add6901fb49 100644 --- a/src/plugins/tile_map/public/plugin.ts +++ b/src/plugins/tile_map/public/plugin.ts @@ -47,7 +47,7 @@ interface TileMapVisualizationDependencies { getZoomPrecision: any; getPrecision: any; BaseMapsVisualization: any; - getServiceSettings: Promise; + getServiceSettings: () => Promise; } /** @internal */ diff --git a/src/plugins/vis_type_vega/public/data_model/vega_parser.ts b/src/plugins/vis_type_vega/public/data_model/vega_parser.ts index d835ab7be06fa..ccb89207e222f 100644 --- a/src/plugins/vis_type_vega/public/data_model/vega_parser.ts +++ b/src/plugins/vis_type_vega/public/data_model/vega_parser.ts @@ -80,7 +80,7 @@ export class VegaParser { containerDir?: ControlsLocation | ControlsDirection; controlsDir?: ControlsLocation; searchAPI: SearchAPI; - getServiceSettings: () => Promse; + getServiceSettings: () => Promise; filters: Bool; timeCache: TimeCache; @@ -89,7 +89,7 @@ export class VegaParser { searchAPI: SearchAPI, timeCache: TimeCache, filters: Bool, - getServiceSettings: () => Promse + getServiceSettings: () => Promise ) { this.spec = spec as VegaSpec; this.hideWarnings = false; @@ -568,7 +568,7 @@ The URL is an identifier only. Kibana and your browser will never access this UR type = DEFAULT_PARSER; } - const parser = this._urlParsers[type]; + const parser = this._urlParsers![type]; if (parser === undefined) { throw new Error( i18n.translate('visTypeVega.vegaParser.notSupportedUrlTypeErrorMessage', { @@ -592,7 +592,7 @@ The URL is an identifier only. Kibana and your browser will never access this UR if (pendingParsers.length > 0) { // let each parser populate its data in parallel await Promise.all( - pendingParsers.map((type) => this._urlParsers[type].populateData(pending[type])) + pendingParsers.map((type) => this._urlParsers![type].populateData(pending[type])) ); } } From 37c444a70c184ce8dc0ab5f5eb8fe684b0b3e4fa Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 22 Sep 2020 16:13:39 -0600 Subject: [PATCH 08/10] remove lodash from region_map bundle --- src/plugins/region_map/public/region_map_visualization.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/region_map/public/region_map_visualization.js b/src/plugins/region_map/public/region_map_visualization.js index e6c1434e07847..6abbf43aa5736 100644 --- a/src/plugins/region_map/public/region_map_visualization.js +++ b/src/plugins/region_map/public/region_map_visualization.js @@ -22,7 +22,6 @@ import { getFormatService, getNotifications, getKibanaLegacy } from './kibana_se import { truncatedColorMaps } from '../../charts/public'; import { tooltipFormatter } from './tooltip_formatter'; import { mapTooltipProvider, ORIGIN } from '../../maps_legacy/public'; -import _ from 'lodash'; export function createRegionMapVisualization({ regionmapsConfig, @@ -96,6 +95,8 @@ export function createRegionMapVisualization({ // Do not use the selectedLayer from the visState. // These settings are stored in the URL and can be used to inject dirty display content. + const { escape } = await import('lodash'); + if ( fileLayerConfig.isEMS || //Hosted by EMS. Metadata needs to be resolved through EMS (fileLayerConfig.layerId && fileLayerConfig.layerId.startsWith(`${ORIGIN.EMS}.`)) //fallback for older saved objects @@ -113,7 +114,7 @@ export function createRegionMapVisualization({ if (configuredLayer) { return { ...configuredLayer, - attribution: _.escape(configuredLayer.attribution ? configuredLayer.attribution : ''), + attribution: escape(configuredLayer.attribution ? configuredLayer.attribution : ''), }; } From a56234ca74867f4a2d0c5eb479b89608127778da Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Wed, 23 Sep 2020 13:59:56 -0600 Subject: [PATCH 09/10] review feedback --- src/plugins/maps_legacy/public/get_leaflet.ts | 34 +++++++++++++++++++ .../public/map/base_maps_visualization.js | 12 +++---- .../public/region_map_visualization.js | 17 ++++------ .../tile_map/public/tile_map_visualization.js | 12 +++---- 4 files changed, 53 insertions(+), 22 deletions(-) create mode 100644 src/plugins/maps_legacy/public/get_leaflet.ts diff --git a/src/plugins/maps_legacy/public/get_leaflet.ts b/src/plugins/maps_legacy/public/get_leaflet.ts new file mode 100644 index 0000000000000..31ff6081be51d --- /dev/null +++ b/src/plugins/maps_legacy/public/get_leaflet.ts @@ -0,0 +1,34 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { lazyLoadMapsLegacyModules } from './lazy_load_bundle'; + +let loadPromise: Promise; + +export async function getLeaflet(): Promise { + if (typeof loadPromise !== 'undefined') { + return loadPromise; + } + + loadPromise = new Promise(async (resolve) => { + const modules = await lazyLoadMapsLegacyModules(); + resolve(new modules.L()); + }); + return loadPromise; +} diff --git a/src/plugins/maps_legacy/public/map/base_maps_visualization.js b/src/plugins/maps_legacy/public/map/base_maps_visualization.js index fa2457c5bd9f3..406dae43c9b5e 100644 --- a/src/plugins/maps_legacy/public/map/base_maps_visualization.js +++ b/src/plugins/maps_legacy/public/map/base_maps_visualization.js @@ -94,9 +94,7 @@ export function BaseMapsVisualizationProvider() { options.center = centerFromUIState ? centerFromUIState : this.vis.params.mapCenter; const modules = await lazyLoadMapsLegacyModules(); - this._leaflet = modules.L; this._kibanaMap = new modules.KibanaMap(this._container, options); - this._serviceSettings = await getServiceSettings(); this._kibanaMap.setMinZoom(WMS_MINZOOM); //use a default this._kibanaMap.setMaxZoom(WMS_MAXZOOM); //use a default @@ -130,14 +128,15 @@ export function BaseMapsVisualizationProvider() { async _updateBaseLayer() { const emsTileLayerId = getEmsTileLayerId(); - if (!this._kibanaMap || !this._serviceSettings) { + if (!this._kibanaMap) { return; } const mapParams = this._getMapsParams(); if (!this._tmsConfigured()) { try { - const tmsServices = await this._serviceSettings.getTMSServices(); + const serviceSettings = await getServiceSettings(); + const tmsServices = await serviceSettings.getTMSServices(); const userConfiguredTmsLayer = tmsServices[0]; const initBasemapLayer = userConfiguredTmsLayer ? userConfiguredTmsLayer @@ -188,12 +187,13 @@ export function BaseMapsVisualizationProvider() { isDesaturated = true; } const isDarkMode = getUiSettings().get('theme:darkMode'); - const meta = await this._serviceSettings.getAttributesForTMSLayer( + const serviceSettings = await getServiceSettings(); + const meta = await serviceSettings.getAttributesForTMSLayer( tmsLayer, isDesaturated, isDarkMode ); - const showZoomMessage = this._serviceSettings.shouldShowZoomMessage(tmsLayer); + const showZoomMessage = serviceSettings.shouldShowZoomMessage(tmsLayer); const options = { ...tmsLayer }; delete options.id; delete options.subdomains; diff --git a/src/plugins/region_map/public/region_map_visualization.js b/src/plugins/region_map/public/region_map_visualization.js index 6abbf43aa5736..9b20a35630c86 100644 --- a/src/plugins/region_map/public/region_map_visualization.js +++ b/src/plugins/region_map/public/region_map_visualization.js @@ -21,12 +21,13 @@ import { i18n } from '@kbn/i18n'; import { getFormatService, getNotifications, getKibanaLegacy } from './kibana_services'; import { truncatedColorMaps } from '../../charts/public'; import { tooltipFormatter } from './tooltip_formatter'; -import { mapTooltipProvider, ORIGIN } from '../../maps_legacy/public'; +import { mapTooltipProvider, ORIGIN, lazyLoadMapsLegacyModules } from '../../maps_legacy/public'; export function createRegionMapVisualization({ regionmapsConfig, uiSettings, BaseMapsVisualization, + getServiceSettings, }) { return class RegionMapsVisualization extends BaseMapsVisualization { constructor(container, vis) { @@ -101,9 +102,8 @@ export function createRegionMapVisualization({ fileLayerConfig.isEMS || //Hosted by EMS. Metadata needs to be resolved through EMS (fileLayerConfig.layerId && fileLayerConfig.layerId.startsWith(`${ORIGIN.EMS}.`)) //fallback for older saved objects ) { - return this._serviceSettings - ? await this._serviceSettings.loadFileLayerConfig(fileLayerConfig) - : null; + const serviceSettings = await getServiceSettings(); + return await serviceSettings.loadFileLayerConfig(fileLayerConfig); } //Configured in the kibana.yml. Needs to be resolved through the settings. @@ -170,9 +170,6 @@ export function createRegionMapVisualization({ } async _recreateChoroplethLayer(name, attribution, showAllData) { - if (!this._leaflet) { - return; - } this._kibanaMap.removeLayer(this._choroplethLayer); if (this._choroplethLayer) { @@ -183,7 +180,7 @@ export function createRegionMapVisualization({ showAllData, this._params.selectedLayer.meta, this._params.selectedLayer, - this._serviceSettings + await getServiceSettings() ); } else { const { ChoroplethLayer } = await import('./choropleth_layer'); @@ -194,8 +191,8 @@ export function createRegionMapVisualization({ showAllData, this._params.selectedLayer.meta, this._params.selectedLayer, - this._serviceSettings, - this._leaflet + await getServiceSettings(), + (await lazyLoadMapsLegacyModules()).L ); } diff --git a/src/plugins/tile_map/public/tile_map_visualization.js b/src/plugins/tile_map/public/tile_map_visualization.js index 53af2b864f4cd..b09a2f3bac48f 100644 --- a/src/plugins/tile_map/public/tile_map_visualization.js +++ b/src/plugins/tile_map/public/tile_map_visualization.js @@ -19,7 +19,11 @@ import { get, round } from 'lodash'; import { getFormatService, getQueryService, getKibanaLegacy } from './services'; -import { geoContains, mapTooltipProvider } from '../../maps_legacy/public'; +import { + geoContains, + mapTooltipProvider, + lazyLoadMapsLegacyModules, +} from '../../maps_legacy/public'; import { tooltipFormatter } from './tooltip_formatter'; function scaleBounds(bounds) { @@ -176,10 +180,6 @@ export const createTileMapVisualization = (dependencies) => { async _recreateGeohashLayer() { const { GeohashLayer } = await import('./geohash_layer'); - if (!this._leaflet) { - return; - } - if (this._geohashLayer) { this._kibanaMap.removeLayer(this._geohashLayer); this._geohashLayer = null; @@ -191,7 +191,7 @@ export const createTileMapVisualization = (dependencies) => { geohashOptions, this._kibanaMap.getZoomLevel(), this._kibanaMap, - this._leaflet + (await lazyLoadMapsLegacyModules()).L ); this._kibanaMap.addLayer(this._geohashLayer); } From 4656e0e4805132992400aea911c43030fb229920 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Wed, 23 Sep 2020 14:01:44 -0600 Subject: [PATCH 10/10] remove unused file --- src/plugins/maps_legacy/public/get_leaflet.ts | 34 ------------------- 1 file changed, 34 deletions(-) delete mode 100644 src/plugins/maps_legacy/public/get_leaflet.ts diff --git a/src/plugins/maps_legacy/public/get_leaflet.ts b/src/plugins/maps_legacy/public/get_leaflet.ts deleted file mode 100644 index 31ff6081be51d..0000000000000 --- a/src/plugins/maps_legacy/public/get_leaflet.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { lazyLoadMapsLegacyModules } from './lazy_load_bundle'; - -let loadPromise: Promise; - -export async function getLeaflet(): Promise { - if (typeof loadPromise !== 'undefined') { - return loadPromise; - } - - loadPromise = new Promise(async (resolve) => { - const modules = await lazyLoadMapsLegacyModules(); - resolve(new modules.L()); - }); - return loadPromise; -}