From efc37e4a670046dfa49f463e76499693039f78a5 Mon Sep 17 00:00:00 2001 From: sulemanof Date: Fri, 23 Aug 2019 16:27:29 +0300 Subject: [PATCH 1/3] Fix loading default vector layer --- .../public/components/region_map_options.tsx | 36 ++++++++++++++----- .../public/components/wms_options.tsx | 19 ++++++++-- .../public/vis/editors/default/sidebar.html | 1 + .../public/vis/editors/default/vis_options.js | 5 ++- .../vis/editors/default/vis_options_props.tsx | 1 + .../kibana_react/public/util/use_mount.ts | 24 +++++++++++++ 6 files changed, 73 insertions(+), 13 deletions(-) create mode 100644 src/plugins/kibana_react/public/util/use_mount.ts diff --git a/src/legacy/core_plugins/region_map/public/components/region_map_options.tsx b/src/legacy/core_plugins/region_map/public/components/region_map_options.tsx index b295646e35b05..31051cd8b52bc 100644 --- a/src/legacy/core_plugins/region_map/public/components/region_map_options.tsx +++ b/src/legacy/core_plugins/region_map/public/components/region_map_options.tsx @@ -17,7 +17,7 @@ * under the License. */ -import React, { useEffect, useState, useCallback, useMemo } from 'react'; +import React, { useState, useCallback, useMemo } from 'react'; import { EuiIcon, EuiLink, EuiPanel, EuiSpacer, EuiText, EuiTitle } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; @@ -34,6 +34,10 @@ import { mapToLayerWithId } from '../util'; import { RegionMapVisParams } from '../types'; import { RegionMapsConfig } from '../plugin'; +// TODO: Below import is temporary, use `react-use` lib instead. +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { useMount } from '../../../../../plugins/kibana_react/public/util/use_mount'; + const mapLayerForOption = ({ layerId, name }: VectorLayer) => ({ text: name, value: layerId, @@ -50,18 +54,24 @@ export type RegionMapOptionsProps = { } & VisOptionsProps; function RegionMapOptions(props: RegionMapOptionsProps) { - const { includeElasticMapsService, serviceSettings, stateParams, vis, setValue } = props; + const { + includeElasticMapsService, + serviceSettings, + stateParams, + vis, + setValue, + forceUpdateVis, + } = props; const [vectorLayers, setVectorLayers] = useState( vis.type.editorConfig.collections.vectorLayers ); const [vectorLayerOptions, setVectorLayerOptions] = useState(vectorLayers.map(mapLayerForOption)); - const currentLayerId = stateParams.selectedLayer && stateParams.selectedLayer.layerId; const fieldOptions = useMemo( () => ((stateParams.selectedLayer && stateParams.selectedLayer.fields) || []).map( mapFieldForOption ), - [currentLayerId] + [stateParams.selectedLayer] ); const setEmsHotLink = useCallback( @@ -69,7 +79,7 @@ function RegionMapOptions(props: RegionMapOptionsProps) { const emsHotLink = await serviceSettings.getEMSHotLink(layer); setValue('emsHotLink', emsHotLink); }, - [setValue] + [setValue, serviceSettings] ); const setLayer = useCallback( @@ -82,7 +92,7 @@ function RegionMapOptions(props: RegionMapOptionsProps) { setEmsHotLink(newLayer); } }, - [vectorLayers, setValue] + [vectorLayers, setEmsHotLink, setValue] ); const setField = useCallback( @@ -91,10 +101,10 @@ function RegionMapOptions(props: RegionMapOptionsProps) { setValue(paramName, stateParams.selectedLayer.fields.find(f => f.name === value)); } }, - [currentLayerId, setValue] + [setValue, stateParams.selectedLayer] ); - useEffect(() => { + const onMount = () => { async function setDefaultValues() { try { const layers = await serviceSettings.getFileLayers(); @@ -127,6 +137,12 @@ function RegionMapOptions(props: RegionMapOptionsProps) { if (newLayer.isEMS) { setEmsHotLink(newLayer); } + + // apply default changes directly to visualization + // without it, these values will be reset after visualization loading + // caused by vis state watcher at line 138 in src/legacy/ui/public/vis/editors/default/default.js + // the approach could be revised after removing angular + forceUpdateVis(); } } catch (error) { toastNotifications.addWarning(error.message); @@ -136,7 +152,9 @@ function RegionMapOptions(props: RegionMapOptionsProps) { if (includeElasticMapsService) { setDefaultValues(); } - }, []); + }; + + useMount(onMount); return ( <> diff --git a/src/legacy/core_plugins/tile_map/public/components/wms_options.tsx b/src/legacy/core_plugins/tile_map/public/components/wms_options.tsx index 7beedc548b6b8..5ca9e2d25da5c 100644 --- a/src/legacy/core_plugins/tile_map/public/components/wms_options.tsx +++ b/src/legacy/core_plugins/tile_map/public/components/wms_options.tsx @@ -17,7 +17,7 @@ * under the License. */ -import React, { useEffect, useState } from 'react'; +import React, { useState } from 'react'; import { EuiPanel, EuiSpacer, EuiTitle } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; @@ -31,9 +31,14 @@ import { WmsInternalOptions } from './wms_internal_options'; import { TileMapOptionsProps } from './tile_map_options'; import { TileMapVisParams } from '../types'; +// TODO: Below import is temporary, use `react-use` lib instead. +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { useMount } from '../../../../../plugins/kibana_react/public/util/use_mount'; + const mapLayerForOption = ({ id }: TmsLayer) => ({ text: id, value: id }); function WmsOptions({ + forceUpdateVis, serviceSettings, stateParams, setValue, @@ -62,7 +67,7 @@ function WmsOptions({ } }; - useEffect(() => { + const onMount = () => { serviceSettings .getTMSServices() .then(services => { @@ -76,10 +81,18 @@ function WmsOptions({ if (!wms.selectedTmsLayer && newBaseLayers.length) { setWmsOption('selectedTmsLayer', newBaseLayers[0]); + + // apply default changes directly to visualization + // without it, these values will be reset after visualization loading + // caused by vis state watcher at line 138 in src/legacy/ui/public/vis/editors/default/default.js + // the approach could be revised after removing angular + forceUpdateVis(); } }) .catch((error: Error) => toastNotifications.addWarning(error.message)); - }, []); + }; + + useMount(onMount); return ( diff --git a/src/legacy/ui/public/vis/editors/default/sidebar.html b/src/legacy/ui/public/vis/editors/default/sidebar.html index 7d775b50a3860..e89b92ac284b0 100644 --- a/src/legacy/ui/public/vis/editors/default/sidebar.html +++ b/src/legacy/ui/public/vis/editors/default/sidebar.html @@ -183,6 +183,7 @@ visualize-editor="visualizeEditor" editor="tab.editor" on-agg-params-change="onAggParamsChange" + force-update-vis="stageEditableVis" > diff --git a/src/legacy/ui/public/vis/editors/default/vis_options.js b/src/legacy/ui/public/vis/editors/default/vis_options.js index 6ebff6a4c5fb7..58a4a5a016be4 100644 --- a/src/legacy/ui/public/vis/editors/default/vis_options.js +++ b/src/legacy/ui/public/vis/editors/default/vis_options.js @@ -38,6 +38,7 @@ uiModules ['setValue', { watchDepth: 'reference' }], ['setValidity', { watchDepth: 'reference' }], ['setTouched', { watchDepth: 'reference' }], + ['forceUpdateVis', { watchDepth: 'reference' }], 'hasHistogramAgg', ])) .directive('visEditorVisOptions', function ($compile) { @@ -53,6 +54,7 @@ uiModules editorState: '=', onAggParamsChange: '=', hasHistogramAgg: '=', + forceUpdateVis: '=', }, link: function ($scope, $el, attrs, ngModelCtrl) { $scope.setValue = (paramName, value) => @@ -81,7 +83,8 @@ uiModules ui-state="uiState" set-value="setValue" set-validity="setValidity" - set-touched="setTouched"> + set-touched="setTouched" + force-update-vis="forceUpdateVis"> `; const $editor = $compile(comp)($scope); $el.append($editor); diff --git a/src/legacy/ui/public/vis/editors/default/vis_options_props.tsx b/src/legacy/ui/public/vis/editors/default/vis_options_props.tsx index d850e34029cb4..f61d53c9a429b 100644 --- a/src/legacy/ui/public/vis/editors/default/vis_options_props.tsx +++ b/src/legacy/ui/public/vis/editors/default/vis_options_props.tsx @@ -30,4 +30,5 @@ export interface VisOptionsProps { setValue(paramName: T, value: VisParamType[T]): void; setValidity(isValid: boolean): void; setTouched(isTouched: boolean): void; + forceUpdateVis(): void; } diff --git a/src/plugins/kibana_react/public/util/use_mount.ts b/src/plugins/kibana_react/public/util/use_mount.ts new file mode 100644 index 0000000000000..e4ff25fbbfb8d --- /dev/null +++ b/src/plugins/kibana_react/public/util/use_mount.ts @@ -0,0 +1,24 @@ +/* + * 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 { useEffect } from 'react'; + +export function useMount(fn: () => void): void { + useEffect(fn, []); +} From 62a5b930339b38e0cb30167820aa1f7406237d81 Mon Sep 17 00:00:00 2001 From: maryia-lapata Date: Wed, 4 Sep 2019 16:25:09 +0300 Subject: [PATCH 2/3] Move layers loading to vis initialization --- .../public/components/region_map_options.tsx | 84 ++----------------- .../region_map/public/region_map_type.js | 26 +++--- .../public/shim/legacy_dependencies_plugin.ts | 63 ++++++++++++-- .../public/components/tile_map_options.tsx | 5 +- .../public/components/wms_options.tsx | 49 +---------- .../public/shim/legacy_dependencies_plugin.ts | 19 +++-- .../tile_map/public/tile_map_type.js | 12 ++- .../public/vis/editors/default/sidebar.html | 1 - .../public/vis/editors/default/vis_options.js | 5 +- .../vis/editors/default/vis_options_props.tsx | 1 - .../kibana_react/public/util/use_mount.ts | 24 ------ 11 files changed, 104 insertions(+), 185 deletions(-) delete mode 100644 src/plugins/kibana_react/public/util/use_mount.ts diff --git a/src/legacy/core_plugins/region_map/public/components/region_map_options.tsx b/src/legacy/core_plugins/region_map/public/components/region_map_options.tsx index 3fe8de7c2d160..f4a838dc58340 100644 --- a/src/legacy/core_plugins/region_map/public/components/region_map_options.tsx +++ b/src/legacy/core_plugins/region_map/public/components/region_map_options.tsx @@ -17,12 +17,11 @@ * under the License. */ -import React, { useState, useCallback, useMemo } from 'react'; +import React, { useCallback, useMemo } from 'react'; import { EuiIcon, EuiLink, EuiPanel, EuiSpacer, EuiText, EuiTitle } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { toastNotifications } from 'ui/notify'; import { FileLayerField, VectorLayer, ServiceSettings } from 'ui/vis/map/service_settings'; import { VisOptionsProps } from 'ui/vis/editors/default'; import { @@ -30,15 +29,8 @@ import { SelectOption, SwitchOption, } from '../../../kbn_vislib_vis_types/public/components'; -import { ORIGIN } from '../../../tile_map/common/origin'; import { WmsOptions } from '../../../tile_map/public/components/wms_options'; -import { mapToLayerWithId } from '../util'; import { RegionMapVisParams } from '../types'; -import { RegionMapsConfig } from '../plugin'; - -// TODO: Below import is temporary, use `react-use` lib instead. -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { useMount } from '../../../../../plugins/kibana_react/public/util/use_mount'; const mapLayerForOption = ({ layerId, name }: VectorLayer) => ({ text: name, @@ -52,22 +44,14 @@ const mapFieldForOption = ({ description, name }: FileLayerField) => ({ export type RegionMapOptionsProps = { serviceSettings: ServiceSettings; - includeElasticMapsService: RegionMapsConfig['includeElasticMapsService']; } & VisOptionsProps; function RegionMapOptions(props: RegionMapOptionsProps) { - const { - includeElasticMapsService, - serviceSettings, - stateParams, - vis, - setValue, - forceUpdateVis, - } = props; - const [vectorLayers, setVectorLayers] = useState( - vis.type.editorConfig.collections.vectorLayers + const { serviceSettings, stateParams, vis, setValue } = props; + const vectorLayerOptions = useMemo( + () => vis.type.editorConfig.collections.vectorLayers.map(mapLayerForOption), + [vis.type.editorConfig.collections.vectorLayers] ); - const [vectorLayerOptions, setVectorLayerOptions] = useState(vectorLayers.map(mapLayerForOption)); const fieldOptions = useMemo( () => ((stateParams.selectedLayer && stateParams.selectedLayer.fields) || []).map( @@ -86,7 +70,9 @@ function RegionMapOptions(props: RegionMapOptionsProps) { const setLayer = useCallback( async (paramName: 'selectedLayer', value: VectorLayer['layerId']) => { - const newLayer = vectorLayers.find(({ layerId }: VectorLayer) => layerId === value); + const newLayer = vis.type.editorConfig.collections.vectorLayers.find( + ({ layerId }: VectorLayer) => layerId === value + ); if (newLayer) { setValue(paramName, newLayer); @@ -94,7 +80,7 @@ function RegionMapOptions(props: RegionMapOptionsProps) { setEmsHotLink(newLayer); } }, - [vectorLayers, setEmsHotLink, setValue] + [vis.type.editorConfig.collections.vectorLayers, setEmsHotLink, setValue] ); const setField = useCallback( @@ -106,58 +92,6 @@ function RegionMapOptions(props: RegionMapOptionsProps) { [setValue, stateParams.selectedLayer] ); - const onMount = () => { - async function setDefaultValues() { - try { - const layers = await serviceSettings.getFileLayers(); - const newLayers = layers - .map(mapToLayerWithId.bind(null, ORIGIN.EMS)) - .filter( - layer => !vectorLayers.some(vectorLayer => vectorLayer.layerId === layer.layerId) - ); - - // backfill v1 manifest for now - newLayers.forEach(layer => { - if (layer.format === 'geojson') { - layer.format = { - type: 'geojson', - }; - } - }); - - const newVectorLayers = [...vectorLayers, ...newLayers]; - - setVectorLayers(newVectorLayers); - setVectorLayerOptions(newVectorLayers.map(mapLayerForOption)); - - const [newLayer] = newVectorLayers; - - if (newLayer && !stateParams.selectedLayer) { - setValue('selectedLayer', newLayer); - setValue('selectedJoinField', newLayer.fields[0]); - - if (newLayer.isEMS) { - setEmsHotLink(newLayer); - } - - // apply default changes directly to visualization - // without it, these values will be reset after visualization loading - // caused by vis state watcher at line 138 in src/legacy/ui/public/vis/editors/default/default.js - // the approach could be revised after removing angular - forceUpdateVis(); - } - } catch (error) { - toastNotifications.addWarning(error.message); - } - } - - if (includeElasticMapsService) { - setDefaultValues(); - } - }; - - useMount(onMount); - return ( <> diff --git a/src/legacy/core_plugins/region_map/public/region_map_type.js b/src/legacy/core_plugins/region_map/public/region_map_type.js index 10aaeb1060bc0..ac95da374715f 100644 --- a/src/legacy/core_plugins/region_map/public/region_map_type.js +++ b/src/legacy/core_plugins/region_map/public/region_map_type.js @@ -20,22 +20,19 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { Schemas } from 'ui/vis/editors/default/schemas'; import { colorSchemas } from 'ui/vislib/components/color/truncated_colormaps'; -import { mapToLayerWithId } from './util'; import { createRegionMapVisualization } from './region_map_visualization'; import { Status } from 'ui/vis/update_status'; import { RegionMapOptions } from './components/region_map_options'; import { visFactory } from '../../visualizations/public'; -// TODO: reference to TILE_MAP plugin should be removed -import { ORIGIN } from '../../tile_map/common/origin'; - export function createRegionMapTypeDefinition(dependencies) { - const { uiSettings, regionmapsConfig, serviceSettings } = dependencies; + const { uiSettings, serviceSettings, visConfig, collections } = dependencies; const visualization = createRegionMapVisualization(dependencies); - const vectorLayers = regionmapsConfig.layers.map(mapToLayerWithId.bind(null, ORIGIN.KIBANA_YML)); - const selectedLayer = vectorLayers[0]; - const selectedJoinField = selectedLayer ? selectedLayer.fields[0] : null; + const wms = uiSettings.get('visualization:tileMap:WMSdefaults'); + if (!wms.selectedTmsLayer && collections.tmsLayers.length) { + wms.selectedTmsLayer = collections.tmsLayers[0]; + } return visFactory.createBaseVisualization({ name: 'region_map', @@ -48,11 +45,11 @@ provided base maps, or add your own. Darker colors represent higher values.' }), legendPosition: 'bottomright', addTooltip: true, colorSchema: 'Yellow to Red', - emsHotLink: '', - selectedLayer, - selectedJoinField, + emsHotLink: visConfig.emsHotLink, + selectedLayer: visConfig.selectedLayer, + selectedJoinField: visConfig.selectedJoinField, isDisplayWarning: true, - wms: uiSettings.get('visualization:tileMap:WMSdefaults'), + wms, mapZoom: 2, mapCenter: [0, 0], outlineWeight: 1, @@ -66,12 +63,11 @@ provided base maps, or add your own. Darker colors represent higher values.' }), (), collections: { colorSchemas, - vectorLayers, - tmsLayers: [] + vectorLayers: collections.vectorLayers, + tmsLayers: collections.tmsLayers, }, schemas: new Schemas([ { diff --git a/src/legacy/core_plugins/region_map/public/shim/legacy_dependencies_plugin.ts b/src/legacy/core_plugins/region_map/public/shim/legacy_dependencies_plugin.ts index c47fc40fbacd7..ae3b3425bde39 100644 --- a/src/legacy/core_plugins/region_map/public/shim/legacy_dependencies_plugin.ts +++ b/src/legacy/core_plugins/region_map/public/shim/legacy_dependencies_plugin.ts @@ -20,12 +20,17 @@ import chrome from 'ui/chrome'; import { CoreStart, Plugin } from 'kibana/public'; import 'ui/vis/map/service_settings'; +import { VectorLayer, ServiceSettings, TmsLayer } from 'ui/vis/map/service_settings'; import { RegionMapsConfig } from '../plugin'; +import { mapToLayerWithId } from '../util'; +// TODO: reference to TILE_MAP plugin should be removed +import { ORIGIN } from '../../../tile_map/common/origin'; + /** @internal */ export interface LegacyDependenciesPluginSetup { $injector: any; - serviceSettings: any; + serviceSettings: ServiceSettings; regionmapsConfig: RegionMapsConfig; } @@ -35,15 +40,61 @@ export class LegacyDependenciesPlugin public async setup() { const $injector = await chrome.dangerouslyGetActiveInjector(); + // Settings for EMSClient. + // EMSClient, which currently lives in the tile_map vis, + // will probably end up being exposed from the future vis_type_maps plugin, + // which would register both the tile_map and the region_map vis plugins. + const serviceSettings: ServiceSettings = $injector.get('serviceSettings'); + + let vectorLayers = this.regionmapsConfig.layers.map( + mapToLayerWithId.bind(null, ORIGIN.KIBANA_YML) + ); + let selectedLayer = vectorLayers[0]; + let selectedJoinField = selectedLayer ? selectedLayer.fields[0] : null; + let emsHotLink = ''; + + if (this.regionmapsConfig.includeElasticMapsService) { + const layers = await serviceSettings.getFileLayers(); + const newLayers = layers + .map(mapToLayerWithId.bind(null, ORIGIN.EMS)) + .filter( + (layer: VectorLayer) => + !vectorLayers.some(vectorLayer => vectorLayer.layerId === layer.layerId) + ); + + // backfill v1 manifest for now + newLayers.forEach((layer: VectorLayer) => { + if (layer.format === 'geojson') { + layer.format = { + type: 'geojson', + }; + } + }); + + vectorLayers = [...vectorLayers, ...newLayers]; + [selectedLayer] = vectorLayers; + selectedJoinField = selectedLayer ? selectedLayer.fields[0] : null; + + if (selectedLayer.isEMS) { + emsHotLink = await serviceSettings.getEMSHotLink(selectedLayer); + } + } + + const tmsLayers: TmsLayer[] = await serviceSettings.getTMSServices(); return { $injector, regionmapsConfig: this.regionmapsConfig, - // Settings for EMSClient. - // EMSClient, which currently lives in the tile_map vis, - // will probably end up being exposed from the future vis_type_maps plugin, - // which would register both the tile_map and the region_map vis plugins. - serviceSettings: $injector.get('serviceSettings'), + serviceSettings, + visConfig: { + emsHotLink, + selectedLayer, + selectedJoinField, + }, + collections: { + vectorLayers, + tmsLayers, + }, } as LegacyDependenciesPluginSetup; } diff --git a/src/legacy/core_plugins/tile_map/public/components/tile_map_options.tsx b/src/legacy/core_plugins/tile_map/public/components/tile_map_options.tsx index d0cff4013b0e7..f19a129fb764a 100644 --- a/src/legacy/core_plugins/tile_map/public/components/tile_map_options.tsx +++ b/src/legacy/core_plugins/tile_map/public/components/tile_map_options.tsx @@ -21,7 +21,6 @@ import React, { useEffect } from 'react'; import { EuiPanel, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { ServiceSettings } from 'ui/vis/map/service_settings'; import { VisOptionsProps } from 'ui/vis/editors/default'; import { BasicOptions, @@ -32,9 +31,7 @@ import { import { WmsOptions } from './wms_options'; import { TileMapVisParams } from '../types'; -export type TileMapOptionsProps = { serviceSettings: ServiceSettings } & VisOptionsProps< - TileMapVisParams ->; +export type TileMapOptionsProps = VisOptionsProps; function TileMapOptions(props: TileMapOptionsProps) { const { stateParams, setValue, vis } = props; diff --git a/src/legacy/core_plugins/tile_map/public/components/wms_options.tsx b/src/legacy/core_plugins/tile_map/public/components/wms_options.tsx index a3f3e95f3c7f3..ef6b2eaea1e52 100644 --- a/src/legacy/core_plugins/tile_map/public/components/wms_options.tsx +++ b/src/legacy/core_plugins/tile_map/public/components/wms_options.tsx @@ -17,12 +17,11 @@ * under the License. */ -import React, { useState } from 'react'; +import React, { useMemo } from 'react'; import { EuiPanel, EuiSpacer, EuiTitle } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { toastNotifications } from 'ui/notify'; import { TmsLayer } from 'ui/vis/map/service_settings'; import { SelectOption, SwitchOption } from '../../../kbn_vislib_vis_types/public/components'; import { RegionMapOptionsProps } from '../../../region_map/public/components/region_map_options'; @@ -30,25 +29,12 @@ import { WmsInternalOptions } from './wms_internal_options'; import { TileMapOptionsProps } from './tile_map_options'; import { TileMapVisParams } from '../types'; -// TODO: Below import is temporary, use `react-use` lib instead. -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { useMount } from '../../../../../plugins/kibana_react/public/util/use_mount'; - const mapLayerForOption = ({ id }: TmsLayer) => ({ text: id, value: id }); -function WmsOptions({ - forceUpdateVis, - serviceSettings, - stateParams, - setValue, - vis, -}: TileMapOptionsProps | RegionMapOptionsProps) { +function WmsOptions({ stateParams, setValue, vis }: TileMapOptionsProps | RegionMapOptionsProps) { const { wms } = stateParams; const { tmsLayers } = vis.type.editorConfig.collections; - const [tmsLayerOptions, setTmsLayersOptions] = useState>( - tmsLayers.map(mapLayerForOption) - ); - const [layers, setLayers] = useState([]); + const tmsLayerOptions = useMemo(() => tmsLayers.map(mapLayerForOption), [tmsLayers]); const setWmsOption = ( paramName: T, @@ -60,39 +46,12 @@ function WmsOptions({ }); const selectTmsLayer = (id: string) => { - const layer = layers.find(l => l.id === id); + const layer = tmsLayers.find((l: TmsLayer) => l.id === id); if (layer) { setWmsOption('selectedTmsLayer', layer); } }; - const onMount = () => { - serviceSettings - .getTMSServices() - .then(services => { - const newBaseLayers: TmsLayer[] = [ - ...tmsLayers, - ...services.filter(service => !tmsLayers.some(({ id }: TmsLayer) => service.id === id)), - ]; - - setLayers(newBaseLayers); - setTmsLayersOptions(newBaseLayers.map(mapLayerForOption)); - - if (!wms.selectedTmsLayer && newBaseLayers.length) { - setWmsOption('selectedTmsLayer', newBaseLayers[0]); - - // apply default changes directly to visualization - // without it, these values will be reset after visualization loading - // caused by vis state watcher at line 138 in src/legacy/ui/public/vis/editors/default/default.js - // the approach could be revised after removing angular - forceUpdateVis(); - } - }) - .catch((error: Error) => toastNotifications.addWarning(error.message)); - }; - - useMount(onMount); - return ( diff --git a/src/legacy/core_plugins/tile_map/public/shim/legacy_dependencies_plugin.ts b/src/legacy/core_plugins/tile_map/public/shim/legacy_dependencies_plugin.ts index 063b12bf0a2db..264e5a027a43b 100644 --- a/src/legacy/core_plugins/tile_map/public/shim/legacy_dependencies_plugin.ts +++ b/src/legacy/core_plugins/tile_map/public/shim/legacy_dependencies_plugin.ts @@ -19,11 +19,12 @@ import chrome from 'ui/chrome'; import 'ui/vis/map/service_settings'; +import { ServiceSettings, TmsLayer } from 'ui/vis/map/service_settings'; import { CoreStart, Plugin } from 'kibana/public'; /** @internal */ export interface LegacyDependenciesPluginSetup { - serviceSettings: any; + serviceSettings: ServiceSettings; $injector: any; } @@ -31,14 +32,20 @@ export class LegacyDependenciesPlugin implements Plugin, void> { public async setup() { const $injector = await chrome.dangerouslyGetActiveInjector(); + // Settings for EMSClient. + // EMSClient, which currently lives in the tile_map vis, + // will probably end up being exposed from the future vis_type_maps plugin, + // which would register both the tile_map and the region_map vis plugins. + const serviceSettings: ServiceSettings = $injector.get('serviceSettings'); + + const tmsLayers: TmsLayer[] = await serviceSettings.getTMSServices(); return { $injector, - // Settings for EMSClient. - // EMSClient, which currently lives in the tile_map vis, - // will probably end up being exposed from the future vis_type_maps plugin, - // which would register both the tile_map and the region_map vis plugins. - serviceSettings: $injector.get('serviceSettings'), + serviceSettings, + collections: { + tmsLayers, + }, } as LegacyDependenciesPluginSetup; } diff --git a/src/legacy/core_plugins/tile_map/public/tile_map_type.js b/src/legacy/core_plugins/tile_map/public/tile_map_type.js index 05dbe0fa9f9df..676ad7aaf857f 100644 --- a/src/legacy/core_plugins/tile_map/public/tile_map_type.js +++ b/src/legacy/core_plugins/tile_map/public/tile_map_type.js @@ -32,7 +32,11 @@ import { TileMapOptions } from './components/tile_map_options'; export function createTileMapTypeDefinition(dependencies) { const CoordinateMapsVisualization = createTileMapVisualization(dependencies); - const { uiSettings, serviceSettings } = dependencies; + const { uiSettings, collections } = dependencies; + const wms = uiSettings.get('visualization:tileMap:WMSdefaults'); + if (!wms.selectedTmsLayer && collections.tmsLayers.length) { + wms.selectedTmsLayer = collections.tmsLayers[0]; + } return visFactory.createBaseVisualization({ name: 'tile_map', @@ -54,7 +58,7 @@ export function createTileMapTypeDefinition(dependencies) { legendPosition: 'bottomright', mapZoom: 2, mapCenter: [0, 0], - wms: uiSettings.get('visualization:tileMap:WMSdefaults'), + wms, }, }, requiresUpdateStatus: [Status.AGGS, Status.PARAMS, Status.RESIZE, Status.UI_STATE], @@ -111,9 +115,9 @@ export function createTileMapTypeDefinition(dependencies) { }), }, ], - tmsLayers: [], + tmsLayers: collections.tmsLayers, }, - optionsTemplate: (props) => , + optionsTemplate: (props) => , schemas: new Schemas([ { group: 'metrics', diff --git a/src/legacy/ui/public/vis/editors/default/sidebar.html b/src/legacy/ui/public/vis/editors/default/sidebar.html index e89b92ac284b0..7d775b50a3860 100644 --- a/src/legacy/ui/public/vis/editors/default/sidebar.html +++ b/src/legacy/ui/public/vis/editors/default/sidebar.html @@ -183,7 +183,6 @@ visualize-editor="visualizeEditor" editor="tab.editor" on-agg-params-change="onAggParamsChange" - force-update-vis="stageEditableVis" > diff --git a/src/legacy/ui/public/vis/editors/default/vis_options.js b/src/legacy/ui/public/vis/editors/default/vis_options.js index 58a4a5a016be4..6ebff6a4c5fb7 100644 --- a/src/legacy/ui/public/vis/editors/default/vis_options.js +++ b/src/legacy/ui/public/vis/editors/default/vis_options.js @@ -38,7 +38,6 @@ uiModules ['setValue', { watchDepth: 'reference' }], ['setValidity', { watchDepth: 'reference' }], ['setTouched', { watchDepth: 'reference' }], - ['forceUpdateVis', { watchDepth: 'reference' }], 'hasHistogramAgg', ])) .directive('visEditorVisOptions', function ($compile) { @@ -54,7 +53,6 @@ uiModules editorState: '=', onAggParamsChange: '=', hasHistogramAgg: '=', - forceUpdateVis: '=', }, link: function ($scope, $el, attrs, ngModelCtrl) { $scope.setValue = (paramName, value) => @@ -83,8 +81,7 @@ uiModules ui-state="uiState" set-value="setValue" set-validity="setValidity" - set-touched="setTouched" - force-update-vis="forceUpdateVis"> + set-touched="setTouched"> `; const $editor = $compile(comp)($scope); $el.append($editor); diff --git a/src/legacy/ui/public/vis/editors/default/vis_options_props.tsx b/src/legacy/ui/public/vis/editors/default/vis_options_props.tsx index f61d53c9a429b..d850e34029cb4 100644 --- a/src/legacy/ui/public/vis/editors/default/vis_options_props.tsx +++ b/src/legacy/ui/public/vis/editors/default/vis_options_props.tsx @@ -30,5 +30,4 @@ export interface VisOptionsProps { setValue(paramName: T, value: VisParamType[T]): void; setValidity(isValid: boolean): void; setTouched(isTouched: boolean): void; - forceUpdateVis(): void; } diff --git a/src/plugins/kibana_react/public/util/use_mount.ts b/src/plugins/kibana_react/public/util/use_mount.ts deleted file mode 100644 index e4ff25fbbfb8d..0000000000000 --- a/src/plugins/kibana_react/public/util/use_mount.ts +++ /dev/null @@ -1,24 +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 { useEffect } from 'react'; - -export function useMount(fn: () => void): void { - useEffect(fn, []); -} From f49d5692da6a4f078364c2799b97c2a08366998b Mon Sep 17 00:00:00 2001 From: maryia-lapata Date: Mon, 9 Sep 2019 13:44:27 +0300 Subject: [PATCH 3/3] Move layers loading to editor initialization --- .../kibana/public/visualize/editor/editor.js | 14 ++++ .../public/components/region_map_options.tsx | 12 ++-- .../region_map/public/region_map_type.js | 69 ++++++++++++++++--- .../public/shim/legacy_dependencies_plugin.ts | 63 ++--------------- .../public/shim/legacy_dependencies_plugin.ts | 19 ++--- .../tile_map/public/tile_map_type.js | 26 +++++-- 6 files changed, 107 insertions(+), 96 deletions(-) diff --git a/src/legacy/core_plugins/kibana/public/visualize/editor/editor.js b/src/legacy/core_plugins/kibana/public/visualize/editor/editor.js index 620e93282b29b..dd7b7b978baf4 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/editor/editor.js +++ b/src/legacy/core_plugins/kibana/public/visualize/editor/editor.js @@ -79,6 +79,13 @@ uiRoutes } return savedVisualizations.get($route.current.params) + .then(savedVis => { + if (savedVis.vis.type.setup) { + return savedVis.vis.type.setup(savedVis) + .catch(() => savedVis); + } + return savedVis; + }) .catch(redirectWhenMissing({ '*': '/visualize' })); @@ -98,6 +105,13 @@ uiRoutes savedVis.id); return savedVis; }) + .then(savedVis => { + if (savedVis.vis.type.setup) { + return savedVis.vis.type.setup(savedVis) + .catch(() => savedVis); + } + return savedVis; + }) .catch(redirectWhenMissing({ 'visualization': '/visualize', 'search': '/management/kibana/objects/savedVisualizations/' + $route.current.params.id, diff --git a/src/legacy/core_plugins/region_map/public/components/region_map_options.tsx b/src/legacy/core_plugins/region_map/public/components/region_map_options.tsx index f4a838dc58340..56742eaec5203 100644 --- a/src/legacy/core_plugins/region_map/public/components/region_map_options.tsx +++ b/src/legacy/core_plugins/region_map/public/components/region_map_options.tsx @@ -48,10 +48,8 @@ export type RegionMapOptionsProps = { function RegionMapOptions(props: RegionMapOptionsProps) { const { serviceSettings, stateParams, vis, setValue } = props; - const vectorLayerOptions = useMemo( - () => vis.type.editorConfig.collections.vectorLayers.map(mapLayerForOption), - [vis.type.editorConfig.collections.vectorLayers] - ); + const { vectorLayers } = vis.type.editorConfig.collections; + const vectorLayerOptions = useMemo(() => vectorLayers.map(mapLayerForOption), [vectorLayers]); const fieldOptions = useMemo( () => ((stateParams.selectedLayer && stateParams.selectedLayer.fields) || []).map( @@ -70,9 +68,7 @@ function RegionMapOptions(props: RegionMapOptionsProps) { const setLayer = useCallback( async (paramName: 'selectedLayer', value: VectorLayer['layerId']) => { - const newLayer = vis.type.editorConfig.collections.vectorLayers.find( - ({ layerId }: VectorLayer) => layerId === value - ); + const newLayer = vectorLayers.find(({ layerId }: VectorLayer) => layerId === value); if (newLayer) { setValue(paramName, newLayer); @@ -80,7 +76,7 @@ function RegionMapOptions(props: RegionMapOptionsProps) { setEmsHotLink(newLayer); } }, - [vis.type.editorConfig.collections.vectorLayers, setEmsHotLink, setValue] + [vectorLayers, setEmsHotLink, setValue] ); const setField = useCallback( diff --git a/src/legacy/core_plugins/region_map/public/region_map_type.js b/src/legacy/core_plugins/region_map/public/region_map_type.js index 735dbfc0ea4b5..b25cc36372257 100644 --- a/src/legacy/core_plugins/region_map/public/region_map_type.js +++ b/src/legacy/core_plugins/region_map/public/region_map_type.js @@ -20,19 +20,19 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { Schemas } from 'ui/vis/editors/default/schemas'; import { colorSchemas } from 'ui/vislib/components/color/truncated_colormaps'; +import { mapToLayerWithId } from './util'; import { createRegionMapVisualization } from './region_map_visualization'; import { Status } from 'ui/vis/update_status'; import { RegionMapOptions } from './components/region_map_options'; import { visFactory } from '../../visualizations/public/np_ready/public'; +// TODO: reference to TILE_MAP plugin should be removed +import { ORIGIN } from '../../tile_map/common/origin'; + export function createRegionMapTypeDefinition(dependencies) { - const { uiSettings, serviceSettings, visConfig, collections } = dependencies; + const { uiSettings, regionmapsConfig, serviceSettings } = dependencies; const visualization = createRegionMapVisualization(dependencies); - const wms = uiSettings.get('visualization:tileMap:WMSdefaults'); - if (!wms.selectedTmsLayer && collections.tmsLayers.length) { - wms.selectedTmsLayer = collections.tmsLayers[0]; - } return visFactory.createBaseVisualization({ name: 'region_map', @@ -48,11 +48,9 @@ provided base maps, or add your own. Darker colors represent higher values.', legendPosition: 'bottomright', addTooltip: true, colorSchema: 'Yellow to Red', - emsHotLink: visConfig.emsHotLink, - selectedLayer: visConfig.selectedLayer, - selectedJoinField: visConfig.selectedJoinField, + emsHotLink: '', isDisplayWarning: true, - wms, + wms: uiSettings.get('visualization:tileMap:WMSdefaults'), mapZoom: 2, mapCenter: [0, 0], outlineWeight: 1, @@ -69,8 +67,8 @@ provided base maps, or add your own. Darker colors represent higher values.', />), collections: { colorSchemas, - vectorLayers: collections.vectorLayers, - tmsLayers: collections.tmsLayers, + vectorLayers: [], + tmsLayers: [], }, schemas: new Schemas([ { @@ -108,5 +106,54 @@ provided base maps, or add your own. Darker colors represent higher values.', }, ]), }, + setup: async (savedVis) => { + const vis = savedVis.vis; + + const tmsLayers = await serviceSettings.getTMSServices(); + vis.type.editorConfig.collections.tmsLayers = tmsLayers; + if (!vis.params.wms.selectedTmsLayer && tmsLayers.length) { + vis.params.wms.selectedTmsLayer = tmsLayers[0]; + } + + const vectorLayers = regionmapsConfig.layers.map( + mapToLayerWithId.bind(null, ORIGIN.KIBANA_YML) + ); + let selectedLayer = vectorLayers[0]; + let selectedJoinField = selectedLayer ? selectedLayer.fields[0] : null; + if (regionmapsConfig.includeElasticMapsService) { + const layers = await serviceSettings.getFileLayers(); + const newLayers = layers + .map(mapToLayerWithId.bind(null, ORIGIN.EMS)) + .filter( + (layer) => + !vectorLayers.some(vectorLayer => vectorLayer.layerId === layer.layerId) + ); + + // backfill v1 manifest for now + newLayers.forEach((layer) => { + if (layer.format === 'geojson') { + layer.format = { + type: 'geojson', + }; + } + }); + + vis.type.editorConfig.collections.vectorLayers = [...vectorLayers, ...newLayers]; + + [selectedLayer] = vis.type.editorConfig.collections.vectorLayers; + selectedJoinField = selectedLayer ? selectedLayer.fields[0] : null; + + if (selectedLayer && !vis.params.selectedLayer && selectedLayer.isEMS) { + vis.params.emsHotLink = await serviceSettings.getEMSHotLink(selectedLayer); + } + } + + if (!vis.params.selectedLayer) { + vis.params.selectedLayer = selectedLayer; + vis.params.selectedJoinField = selectedJoinField; + } + + return savedVis; + }, }); } diff --git a/src/legacy/core_plugins/region_map/public/shim/legacy_dependencies_plugin.ts b/src/legacy/core_plugins/region_map/public/shim/legacy_dependencies_plugin.ts index ae3b3425bde39..c47fc40fbacd7 100644 --- a/src/legacy/core_plugins/region_map/public/shim/legacy_dependencies_plugin.ts +++ b/src/legacy/core_plugins/region_map/public/shim/legacy_dependencies_plugin.ts @@ -20,17 +20,12 @@ import chrome from 'ui/chrome'; import { CoreStart, Plugin } from 'kibana/public'; import 'ui/vis/map/service_settings'; -import { VectorLayer, ServiceSettings, TmsLayer } from 'ui/vis/map/service_settings'; import { RegionMapsConfig } from '../plugin'; -import { mapToLayerWithId } from '../util'; -// TODO: reference to TILE_MAP plugin should be removed -import { ORIGIN } from '../../../tile_map/common/origin'; - /** @internal */ export interface LegacyDependenciesPluginSetup { $injector: any; - serviceSettings: ServiceSettings; + serviceSettings: any; regionmapsConfig: RegionMapsConfig; } @@ -40,61 +35,15 @@ export class LegacyDependenciesPlugin public async setup() { const $injector = await chrome.dangerouslyGetActiveInjector(); - // Settings for EMSClient. - // EMSClient, which currently lives in the tile_map vis, - // will probably end up being exposed from the future vis_type_maps plugin, - // which would register both the tile_map and the region_map vis plugins. - const serviceSettings: ServiceSettings = $injector.get('serviceSettings'); - - let vectorLayers = this.regionmapsConfig.layers.map( - mapToLayerWithId.bind(null, ORIGIN.KIBANA_YML) - ); - let selectedLayer = vectorLayers[0]; - let selectedJoinField = selectedLayer ? selectedLayer.fields[0] : null; - let emsHotLink = ''; - - if (this.regionmapsConfig.includeElasticMapsService) { - const layers = await serviceSettings.getFileLayers(); - const newLayers = layers - .map(mapToLayerWithId.bind(null, ORIGIN.EMS)) - .filter( - (layer: VectorLayer) => - !vectorLayers.some(vectorLayer => vectorLayer.layerId === layer.layerId) - ); - - // backfill v1 manifest for now - newLayers.forEach((layer: VectorLayer) => { - if (layer.format === 'geojson') { - layer.format = { - type: 'geojson', - }; - } - }); - - vectorLayers = [...vectorLayers, ...newLayers]; - [selectedLayer] = vectorLayers; - selectedJoinField = selectedLayer ? selectedLayer.fields[0] : null; - - if (selectedLayer.isEMS) { - emsHotLink = await serviceSettings.getEMSHotLink(selectedLayer); - } - } - - const tmsLayers: TmsLayer[] = await serviceSettings.getTMSServices(); return { $injector, regionmapsConfig: this.regionmapsConfig, - serviceSettings, - visConfig: { - emsHotLink, - selectedLayer, - selectedJoinField, - }, - collections: { - vectorLayers, - tmsLayers, - }, + // Settings for EMSClient. + // EMSClient, which currently lives in the tile_map vis, + // will probably end up being exposed from the future vis_type_maps plugin, + // which would register both the tile_map and the region_map vis plugins. + serviceSettings: $injector.get('serviceSettings'), } as LegacyDependenciesPluginSetup; } diff --git a/src/legacy/core_plugins/tile_map/public/shim/legacy_dependencies_plugin.ts b/src/legacy/core_plugins/tile_map/public/shim/legacy_dependencies_plugin.ts index 264e5a027a43b..063b12bf0a2db 100644 --- a/src/legacy/core_plugins/tile_map/public/shim/legacy_dependencies_plugin.ts +++ b/src/legacy/core_plugins/tile_map/public/shim/legacy_dependencies_plugin.ts @@ -19,12 +19,11 @@ import chrome from 'ui/chrome'; import 'ui/vis/map/service_settings'; -import { ServiceSettings, TmsLayer } from 'ui/vis/map/service_settings'; import { CoreStart, Plugin } from 'kibana/public'; /** @internal */ export interface LegacyDependenciesPluginSetup { - serviceSettings: ServiceSettings; + serviceSettings: any; $injector: any; } @@ -32,20 +31,14 @@ export class LegacyDependenciesPlugin implements Plugin, void> { public async setup() { const $injector = await chrome.dangerouslyGetActiveInjector(); - // Settings for EMSClient. - // EMSClient, which currently lives in the tile_map vis, - // will probably end up being exposed from the future vis_type_maps plugin, - // which would register both the tile_map and the region_map vis plugins. - const serviceSettings: ServiceSettings = $injector.get('serviceSettings'); - - const tmsLayers: TmsLayer[] = await serviceSettings.getTMSServices(); return { $injector, - serviceSettings, - collections: { - tmsLayers, - }, + // Settings for EMSClient. + // EMSClient, which currently lives in the tile_map vis, + // will probably end up being exposed from the future vis_type_maps plugin, + // which would register both the tile_map and the region_map vis plugins. + serviceSettings: $injector.get('serviceSettings'), } as LegacyDependenciesPluginSetup; } diff --git a/src/legacy/core_plugins/tile_map/public/tile_map_type.js b/src/legacy/core_plugins/tile_map/public/tile_map_type.js index fb82dc08e7de2..2b5bb0c576fd1 100644 --- a/src/legacy/core_plugins/tile_map/public/tile_map_type.js +++ b/src/legacy/core_plugins/tile_map/public/tile_map_type.js @@ -33,11 +33,7 @@ import { MapTypes } from './map_types'; export function createTileMapTypeDefinition(dependencies) { const CoordinateMapsVisualization = createTileMapVisualization(dependencies); - const { uiSettings, collections } = dependencies; - const wms = uiSettings.get('visualization:tileMap:WMSdefaults'); - if (!wms.selectedTmsLayer && collections.tmsLayers.length) { - wms.selectedTmsLayer = collections.tmsLayers[0]; - } + const { uiSettings, serviceSettings } = dependencies; return visFactory.createBaseVisualization({ name: 'tile_map', @@ -59,7 +55,7 @@ export function createTileMapTypeDefinition(dependencies) { legendPosition: 'bottomright', mapZoom: 2, mapCenter: [0, 0], - wms, + wms: uiSettings.get('visualization:tileMap:WMSdefaults'), }, }, requiresUpdateStatus: [Status.AGGS, Status.PARAMS, Status.RESIZE, Status.UI_STATE], @@ -121,7 +117,7 @@ export function createTileMapTypeDefinition(dependencies) { }), }, ], - tmsLayers: collections.tmsLayers, + tmsLayers: [], }, optionsTemplate: (props) => , schemas: new Schemas([ @@ -148,5 +144,21 @@ export function createTileMapTypeDefinition(dependencies) { }, ]), }, + setup: async (savedVis) => { + const vis = savedVis.vis; + let tmsLayers; + + try { + tmsLayers = await serviceSettings.getTMSServices(); + } catch (e) { + return savedVis; + } + + vis.type.editorConfig.collections.tmsLayers = tmsLayers; + if (!vis.params.wms.selectedTmsLayer && tmsLayers.length) { + vis.params.wms.selectedTmsLayer = tmsLayers[0]; + } + return savedVis; + }, }); }