Skip to content

Commit

Permalink
[maps] clean up maps app state (#73337)
Browse files Browse the repository at this point in the history
* [maps] clean up maps app state

* remove time, query and refreshConfig from react state

* clean up

* move getInitialLayersFromUrlParam out of MapsAppView

* clean up _updateFromGlobalState to just call _onQueryChange

* inline _getAppStateFilters

* tslint cleanup and fix refresh config

* fix functional test

* fix functional tests take 2

* review feedback

* fix timing issue by not providing default query context value from props

* minor cleanup

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
  • Loading branch information
nreese and elasticmachine authored Jul 30, 2020
1 parent aa68e3b commit d8d8306
Show file tree
Hide file tree
Showing 13 changed files with 204 additions and 301 deletions.
8 changes: 5 additions & 3 deletions x-pack/plugins/maps/public/actions/map_actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ import { Filter, Query, TimeRange } from 'src/plugins/data/public';
import { MapStoreState } from '../reducers/store';
import {
getDataFilters,
getFilters,
getMapSettings,
getWaitingForMapReadyLayerListRaw,
getQuery,
getTimeFilters,
} from '../selectors/map_selectors';
import {
CLEAR_GOTO,
Expand Down Expand Up @@ -217,13 +219,13 @@ export function setQuery({

dispatch({
type: SET_QUERY,
timeFilters,
timeFilters: timeFilters ? timeFilters : getTimeFilters(getState()),
query: {
...query,
...(query ? query : getQuery(getState())),
// ensure query changes to trigger re-fetch when "Refresh" clicked
queryLastTriggeredAt: refresh ? generateQueryTimestamp() : prevTriggeredAt,
},
filters,
filters: filters ? filters : getFilters(getState()),
});

if (getMapSettings(getState()).autoFitToDataBounds) {
Expand Down
14 changes: 2 additions & 12 deletions x-pack/plugins/maps/public/embeddable/map_embeddable_factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export class MapEmbeddableFactory implements EmbeddableFactoryDefinition {
const {
addLayerWithoutDataSync,
createMapStore,
getIndexPatternService,
getIndexPatternsFromIds,
getQueryableUniqueIndexPatternIds,
} = await lazyLoadMapModules();
const store = createMapStore();
Expand All @@ -66,17 +66,7 @@ export class MapEmbeddableFactory implements EmbeddableFactoryDefinition {
);
}

const promises = queryableIndexPatternIds.map(async (indexPatternId) => {
try {
// @ts-ignore
return await getIndexPatternService().get(indexPatternId);
} catch (error) {
// Unable to load index pattern, better to not throw error so map embeddable can render
// Error will be surfaced by map embeddable since it too will be unable to locate the index pattern
return null;
}
});
const indexPatterns = await Promise.all(promises);
const indexPatterns = await getIndexPatternsFromIds(queryableIndexPatternIds);
return _.compact(indexPatterns) as IIndexPattern[];
}

Expand Down
14 changes: 10 additions & 4 deletions x-pack/plugins/maps/public/index_pattern_util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,17 @@ export function getGeoTileAggNotSupportedReason(field: IFieldType): string | nul
export async function getIndexPatternsFromIds(
indexPatternIds: string[] = []
): Promise<IndexPattern[]> {
const promises: Array<Promise<IndexPattern>> = [];
indexPatternIds.forEach((id) => {
promises.push(getIndexPatternService().get(id));
const promises: IndexPattern[] = [];
indexPatternIds.forEach(async (indexPatternId) => {
try {
// @ts-ignore
promises.push(getIndexPatternService().get(indexPatternId));
} catch (error) {
// Unable to load index pattern, better to not throw error so map can render
// Error will be surfaced by layer since it too will be unable to locate the index pattern
return null;
}
});

return await Promise.all(promises);
}

Expand Down
6 changes: 5 additions & 1 deletion x-pack/plugins/maps/public/lazy_load_bundle/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { AnyAction } from 'redux';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { IndexPatternsService } from 'src/plugins/data/public/index_patterns';
import { ReactElement } from 'react';
import { IndexPattern } from 'src/plugins/data/public';
import { Embeddable, IContainer } from '../../../../../src/plugins/embeddable/public';
import { LayerDescriptor } from '../../common/descriptor_types';
import { MapStore, MapStoreState } from '../reducers/store';
Expand Down Expand Up @@ -44,8 +45,9 @@ interface LazyLoadedMapModules {
indexPatternId: string,
indexPatternTitle: string
) => LayerDescriptor[];
registerLayerWizard(layerWizard: LayerWizard): void;
registerLayerWizard: (layerWizard: LayerWizard) => void;
registerSource(entry: SourceRegistryEntry): void;
getIndexPatternsFromIds: (indexPatternIds: string[]) => Promise<IndexPattern[]>;
}

export async function lazyLoadMapModules(): Promise<LazyLoadedMapModules> {
Expand All @@ -71,6 +73,7 @@ export async function lazyLoadMapModules(): Promise<LazyLoadedMapModules> {
createSecurityLayerDescriptors,
registerLayerWizard,
registerSource,
getIndexPatternsFromIds,
} = await import('./lazy');

resolve({
Expand All @@ -88,6 +91,7 @@ export async function lazyLoadMapModules(): Promise<LazyLoadedMapModules> {
createSecurityLayerDescriptors,
registerLayerWizard,
registerSource,
getIndexPatternsFromIds,
});
});
return loadModulesPromise;
Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/maps/public/lazy_load_bundle/lazy/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ export * from '../../routing/maps_router';
export * from '../../classes/layers/solution_layers/security';
export { registerLayerWizard } from '../../classes/layers/layer_wizard_registry';
export { registerSource } from '../../classes/sources/source_registry';
export { getIndexPatternsFromIds } from '../../index_pattern_util';
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import _ from 'lodash';
import rison from 'rison-node';
import { i18n } from '@kbn/i18n';
// Import each layer type, even those not used, to init in registry
import '../../classes/sources/wms_source';
import '../../classes/sources/ems_file_source';
Expand All @@ -16,7 +19,7 @@ import { KibanaTilemapSource } from '../../classes/sources/kibana_tilemap_source
import { TileLayer } from '../../classes/layers/tile_layer/tile_layer';
import { EMSTMSSource } from '../../classes/sources/ems_tms_source';
import { VectorTileLayer } from '../../classes/layers/vector_tile_layer/vector_tile_layer';
import { getIsEmsEnabled } from '../../kibana_services';
import { getIsEmsEnabled, getToasts } from '../../kibana_services';
import { getKibanaTileMap } from '../../meta';

export function getInitialLayers(layerListJSON, initialLayers = []) {
Expand All @@ -41,3 +44,33 @@ export function getInitialLayers(layerListJSON, initialLayers = []) {

return initialLayers;
}

export function getInitialLayersFromUrlParam() {
const locationSplit = window.location.href.split('?');
if (locationSplit.length <= 1) {
return [];
}
const mapAppParams = new URLSearchParams(locationSplit[1]);
if (!mapAppParams.has('initialLayers')) {
return [];
}

try {
let mapInitLayers = mapAppParams.get('initialLayers');
if (mapInitLayers[mapInitLayers.length - 1] === '#') {
mapInitLayers = mapInitLayers.substr(0, mapInitLayers.length - 1);
}
return rison.decode_array(mapInitLayers);
} catch (e) {
getToasts().addWarning({
title: i18n.translate('xpack.maps.initialLayers.unableToParseTitle', {
defaultMessage: `Initial layers not added to map`,
}),
text: i18n.translate('xpack.maps.initialLayers.unableToParseMessage', {
defaultMessage: `Unable to parse contents of 'initialLayers' parameter. Error: {errorMsg}`,
values: { errorMsg: e.message },
}),
});
return [];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,27 @@ import {
enableFullScreen,
openMapSettings,
removePreviewLayers,
setRefreshConfig,
setSelectedLayer,
updateFlyout,
} from '../../../actions';
import { FLYOUT_STATE } from '../../../reducers/ui';
import { getInspectorAdapters } from '../../../reducers/non_serializable_instances';
import { getFlyoutDisplay } from '../../../selectors/ui_selectors';
import { hasDirtyState } from '../../../selectors/map_selectors';
import {
getQuery,
getRefreshConfig,
getTimeFilters,
hasDirtyState,
} from '../../../selectors/map_selectors';

function mapStateToProps(state = {}) {
return {
isOpenSettingsDisabled: getFlyoutDisplay(state) !== FLYOUT_STATE.NONE,
inspectorAdapters: getInspectorAdapters(state),
isSaveDisabled: hasDirtyState(state),
query: getQuery(state),
refreshConfig: getRefreshConfig(state),
timeFilters: getTimeFilters(state),
};
}

Expand All @@ -34,7 +41,6 @@ function mapDispatchToProps(dispatch) {
dispatch(updateFlyout(FLYOUT_STATE.NONE));
dispatch(removePreviewLayers());
},
setRefreshStoreConfig: (refreshConfig) => dispatch(setRefreshConfig(refreshConfig)),
enableFullScreen: () => dispatch(enableFullScreen()),
openMapSettings: () => dispatch(openMapSettings()),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,16 @@ export function MapsTopNavMenu({
onQuerySaved,
onSavedQueryUpdated,
savedQuery,
time,
timeFilters,
refreshConfig,
setRefreshConfig,
setRefreshStoreConfig,
onRefreshConfigChange,
indexPatterns,
updateFiltersAndDispatch,
onFiltersChange,
isSaveDisabled,
closeFlyout,
enableFullScreen,
openMapSettings,
inspectorAdapters,
syncAppAndGlobalState,
setBreadcrumbs,
isOpenSettingsDisabled,
}) {
Expand Down Expand Up @@ -75,31 +73,20 @@ export function MapsTopNavMenu({
});
};

const onRefreshChange = function ({ isPaused, refreshInterval }) {
const newRefreshConfig = {
isPaused,
interval: isNaN(refreshInterval) ? refreshConfig.interval : refreshInterval,
};
setRefreshConfig(newRefreshConfig, () => {
setRefreshStoreConfig(newRefreshConfig);
syncAppAndGlobalState();
});
};

return (
<TopNavMenu
appName="maps"
config={config}
indexPatterns={indexPatterns || []}
indexPatterns={indexPatterns}
filters={filterManager.getFilters()}
query={query}
onQuerySubmit={submitQuery}
onFiltersUpdated={updateFiltersAndDispatch}
dateRangeFrom={time.from}
dateRangeTo={time.to}
onFiltersUpdated={onFiltersChange}
dateRangeFrom={timeFilters.from}
dateRangeTo={timeFilters.to}
isRefreshPaused={refreshConfig.isPaused}
refreshInterval={refreshConfig.interval}
onRefreshChange={onRefreshChange}
onRefreshChange={onRefreshConfigChange}
showSearchBar={true}
showFilterBar={true}
showDatePicker={true}
Expand Down
8 changes: 6 additions & 2 deletions x-pack/plugins/maps/public/routing/routes/maps_app/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ import { MapsAppView } from './maps_app_view';
import { getFlyoutDisplay, getIsFullScreen } from '../../../selectors/ui_selectors';
import {
getFilters,
getQuery,
getQueryableUniqueIndexPatternIds,
getRefreshConfig,
getTimeFilters,
hasUnsavedChanges,
} from '../../../selectors/map_selectors';
import {
Expand Down Expand Up @@ -38,17 +40,19 @@ function mapStateToProps(state = {}) {
hasUnsavedChanges: (savedMap, initialLayerListConfig) => {
return hasUnsavedChanges(state, savedMap, initialLayerListConfig);
},
query: getQuery(state),
timeFilters: getTimeFilters(state),
};
}

function mapDispatchToProps(dispatch) {
return {
dispatchSetQuery: (refresh, filters, query, time) => {
dispatchSetQuery: ({ refresh, filters, query, timeFilters }) => {
dispatch(
setQuery({
filters,
query,
timeFilters: time,
timeFilters,
refresh,
})
);
Expand Down
Loading

0 comments on commit d8d8306

Please sign in to comment.