mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[maps] Revert "Revert of fix EMS vector file manifest is loaded in Discover (#190073)
Re-instate https://github.com/elastic/kibana/pull/189550. PR makes one small clean-up in that getSuggestionsLazy promise will not reject when modules fail to load. https://github.com/elastic/kibana/pull/189984 confirmed that [the fix did](https://github.com/elastic/kibana/pull/189550) had a large impact on performance.
This commit is contained in:
parent
7243a5c3b5
commit
e2fdced90e
4 changed files with 119 additions and 48 deletions
|
@ -5,22 +5,50 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { EuiComboBox, EuiComboBoxOptionOption, EuiFormRow } from '@elastic/eui';
|
||||
import { EuiComboBox, EuiComboBoxOptionOption, EuiFormRow, EuiSelect } from '@elastic/eui';
|
||||
import type { FileLayer } from '@elastic/ems-client';
|
||||
import { ChoroplethChartState } from './types';
|
||||
import { EMSFileSelect } from '../../components/ems_file_select';
|
||||
import { getEmsFileLayers } from '../../util';
|
||||
|
||||
interface Props {
|
||||
emsFileLayers: FileLayer[];
|
||||
state: ChoroplethChartState;
|
||||
setState: (state: ChoroplethChartState) => void;
|
||||
}
|
||||
|
||||
export function RegionKeyEditor(props: Props) {
|
||||
const [emsFileLayers, setEmsFileLayers] = useState<FileLayer[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
let ignore = false;
|
||||
setIsLoading(true);
|
||||
getEmsFileLayers()
|
||||
.then((fileLayers) => {
|
||||
if (!ignore) {
|
||||
setEmsFileLayers(fileLayers);
|
||||
setIsLoading(false);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
if (!ignore) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(
|
||||
`Lens region map is unable to access administrative boundaries from Elastic Maps Service (EMS). To avoid unnecessary EMS requests, set 'map.includeElasticMapsService: false' in 'kibana.yml'.`
|
||||
);
|
||||
setIsLoading(false);
|
||||
}
|
||||
});
|
||||
|
||||
return () => {
|
||||
ignore = true;
|
||||
};
|
||||
}, []);
|
||||
|
||||
function onEmsLayerSelect(emsLayerId: string) {
|
||||
const emsFields = getEmsFields(props.emsFileLayers, emsLayerId);
|
||||
const emsFields = getEmsFields(emsFileLayers, emsLayerId);
|
||||
props.setState({
|
||||
...props.state,
|
||||
emsLayerId,
|
||||
|
@ -28,27 +56,30 @@ export function RegionKeyEditor(props: Props) {
|
|||
});
|
||||
}
|
||||
|
||||
function onEmsFieldSelect(selectedOptions: Array<EuiComboBoxOptionOption<string>>) {
|
||||
if (selectedOptions.length === 0) {
|
||||
return;
|
||||
const emsFieldSelect = useMemo(() => {
|
||||
const emsFields = getEmsFields(emsFileLayers, props.state.emsLayerId);
|
||||
if (emsFields.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
props.setState({
|
||||
...props.state,
|
||||
emsField: selectedOptions[0].value,
|
||||
});
|
||||
}
|
||||
const selectedOption = props.state.emsField
|
||||
? emsFields.find((option: EuiComboBoxOptionOption<string>) => {
|
||||
return props.state.emsField === option.value;
|
||||
})
|
||||
: undefined;
|
||||
|
||||
let emsFieldSelect;
|
||||
const emsFields = getEmsFields(props.emsFileLayers, props.state.emsLayerId);
|
||||
if (emsFields.length) {
|
||||
let selectedOption;
|
||||
if (props.state.emsField) {
|
||||
selectedOption = emsFields.find((option: EuiComboBoxOptionOption<string>) => {
|
||||
return props.state.emsField === option.value;
|
||||
function onEmsFieldSelect(selectedOptions: Array<EuiComboBoxOptionOption<string>>) {
|
||||
if (selectedOptions.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
props.setState({
|
||||
...props.state,
|
||||
emsField: selectedOptions[0].value,
|
||||
});
|
||||
}
|
||||
emsFieldSelect = (
|
||||
|
||||
return (
|
||||
<EuiFormRow
|
||||
label={i18n.translate('xpack.maps.choropleth.joinFieldLabel', {
|
||||
defaultMessage: 'Join field',
|
||||
|
@ -64,8 +95,11 @@ export function RegionKeyEditor(props: Props) {
|
|||
/>
|
||||
</EuiFormRow>
|
||||
);
|
||||
}
|
||||
return (
|
||||
}, [emsFileLayers, props]);
|
||||
|
||||
return isLoading ? (
|
||||
<EuiSelect isLoading />
|
||||
) : (
|
||||
<>
|
||||
<EMSFileSelect
|
||||
isColumnCompressed
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
import type { ExpressionsSetup } from '@kbn/expressions-plugin/public';
|
||||
import type { CoreSetup, CoreStart } from '@kbn/core/public';
|
||||
import type { LensPublicSetup } from '@kbn/lens-plugin/public';
|
||||
import type { FileLayer } from '@elastic/ems-client';
|
||||
import type { MapsPluginStartDependencies } from '../../plugin';
|
||||
import { getExpressionFunction } from './expression_function';
|
||||
import { getExpressionRenderer } from './expression_renderer';
|
||||
|
@ -27,22 +26,10 @@ export function setupLensChoroplethChart(
|
|||
lens.registerVisualization(async () => {
|
||||
const [coreStart, plugins]: [CoreStart, MapsPluginStartDependencies, unknown] =
|
||||
await coreSetup.getStartServices();
|
||||
const { getEmsFileLayers } = await import('../../util');
|
||||
const { getVisualization } = await import('./visualization');
|
||||
|
||||
let emsFileLayers: FileLayer[] = [];
|
||||
try {
|
||||
emsFileLayers = await getEmsFileLayers();
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(
|
||||
`Lens region map setup is unable to access administrative boundaries from Elastic Maps Service (EMS). To avoid unnecessary EMS requests, set 'map.includeElasticMapsService: false' in 'kibana.yml'. For more details please visit ${coreStart.docLinks.links.maps.connectToEms}`
|
||||
);
|
||||
}
|
||||
|
||||
return getVisualization({
|
||||
theme: coreStart.theme,
|
||||
emsFileLayers,
|
||||
paletteService: await plugins.charts.palettes.getPalettes(),
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { SuggestionRequest, VisualizationSuggestion } from '@kbn/lens-plugin/public';
|
||||
import type { FileLayer } from '@elastic/ems-client';
|
||||
import type { ChoroplethChartState } from './types';
|
||||
|
||||
let emsFileLayers: FileLayer[] | undefined;
|
||||
let getSuggestionsActual:
|
||||
| ((
|
||||
suggestionRequest: SuggestionRequest<ChoroplethChartState>,
|
||||
emsFileLayers: FileLayer[]
|
||||
) => Array<VisualizationSuggestion<ChoroplethChartState>>)
|
||||
| undefined;
|
||||
let promise: undefined | Promise<void>;
|
||||
|
||||
/**
|
||||
* Avoid loading file layers during plugin setup
|
||||
* Instead, load file layers when getSuggestions is called
|
||||
* Since getSuggestions is sync, the trade off is that
|
||||
* getSuggestions will return no suggestions until file layers load
|
||||
*/
|
||||
export function getSuggestionsLazy(
|
||||
suggestionRequest: SuggestionRequest<ChoroplethChartState>
|
||||
): Array<VisualizationSuggestion<ChoroplethChartState>> {
|
||||
if (!promise) {
|
||||
promise = new Promise((resolve) => {
|
||||
Promise.all([import('./suggestions'), import('../../util')])
|
||||
.then(async ([{ getSuggestions }, { getEmsFileLayers }]) => {
|
||||
getSuggestionsActual = getSuggestions;
|
||||
try {
|
||||
emsFileLayers = await getEmsFileLayers();
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(
|
||||
`Lens region map is unable to access administrative boundaries from Elastic Maps Service (EMS). To avoid unnecessary EMS requests, set 'map.includeElasticMapsService: false' in 'kibana.yml'.`
|
||||
);
|
||||
}
|
||||
resolve();
|
||||
})
|
||||
.catch(resolve);
|
||||
});
|
||||
return [];
|
||||
}
|
||||
|
||||
return emsFileLayers && getSuggestionsActual
|
||||
? getSuggestionsActual(suggestionRequest, emsFileLayers)
|
||||
: [];
|
||||
}
|
|
@ -7,15 +7,14 @@
|
|||
|
||||
import React from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import type { FileLayer } from '@elastic/ems-client';
|
||||
import { dynamic } from '@kbn/shared-ux-utility';
|
||||
import type { PaletteRegistry } from '@kbn/coloring';
|
||||
import { ThemeServiceStart } from '@kbn/core/public';
|
||||
import { layerTypes } from '@kbn/lens-plugin/public';
|
||||
import type { OperationMetadata, SuggestionRequest, Visualization } from '@kbn/lens-plugin/public';
|
||||
import { IconRegionMap } from '@kbn/chart-icons';
|
||||
import { getSuggestions } from './suggestions';
|
||||
import { getSuggestionsLazy } from './suggestions_lazy';
|
||||
import type { ChoroplethChartState } from './types';
|
||||
import { RegionKeyEditor } from './region_key_editor';
|
||||
|
||||
const REGION_KEY_GROUP_ID = 'region_key';
|
||||
const METRIC_GROUP_ID = 'metric';
|
||||
|
@ -27,11 +26,9 @@ const CHART_LABEL = i18n.translate('xpack.maps.lens.choropleth.label', {
|
|||
export const getVisualization = ({
|
||||
paletteService,
|
||||
theme,
|
||||
emsFileLayers,
|
||||
}: {
|
||||
paletteService: PaletteRegistry;
|
||||
theme: ThemeServiceStart;
|
||||
emsFileLayers: FileLayer[];
|
||||
}): Visualization<ChoroplethChartState> => ({
|
||||
id: 'lnsChoropleth',
|
||||
|
||||
|
@ -73,7 +70,7 @@ export const getVisualization = ({
|
|||
},
|
||||
|
||||
getSuggestions(suggestionRequest: SuggestionRequest<ChoroplethChartState>) {
|
||||
return getSuggestions(suggestionRequest, emsFileLayers);
|
||||
return getSuggestionsLazy(suggestionRequest);
|
||||
},
|
||||
|
||||
initialize(addNewLayer, state) {
|
||||
|
@ -194,13 +191,13 @@ export const getVisualization = ({
|
|||
|
||||
DimensionEditorComponent(props) {
|
||||
if (props.groupId === REGION_KEY_GROUP_ID) {
|
||||
return (
|
||||
<RegionKeyEditor
|
||||
emsFileLayers={emsFileLayers}
|
||||
state={props.state}
|
||||
setState={props.setState}
|
||||
/>
|
||||
);
|
||||
const DimensionEditor = dynamic(async () => {
|
||||
const { RegionKeyEditor } = await import('./region_key_editor');
|
||||
return {
|
||||
default: RegionKeyEditor,
|
||||
};
|
||||
});
|
||||
return <DimensionEditor state={props.state} setState={props.setState} />;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue