[Maps] convert redux actions to TS (#67218)

* [Maps] convert redux actions to TS

* move ts-ignore comment to right location

* eslint
This commit is contained in:
Nathan Reese 2020-05-26 08:52:56 -06:00 committed by GitHub
parent db6709bd54
commit 18e1075979
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 837 additions and 888 deletions

View file

@ -72,7 +72,7 @@ export function cancelAllInFlightRequests() {
};
}
export function updateStyleMeta(layerId: string) {
export function updateStyleMeta(layerId: string | null) {
return async (dispatch: Dispatch, getState: () => MapStoreState) => {
const layer = getLayerById(layerId, getState());
if (!layer) {
@ -143,7 +143,7 @@ export function syncDataForLayer(layer: ILayer) {
};
}
export function syncDataForLayerId(layerId: string) {
export function syncDataForLayerId(layerId: string | null) {
return async (dispatch: Dispatch, getState: () => MapStoreState) => {
const layer = getLayerById(layerId, getState());
if (layer) {

View file

@ -8,6 +8,7 @@ export * from './ui_actions';
export * from './map_actions';
export * from './map_action_constants';
export * from './layer_actions';
export { cancelAllInFlightRequests, DataRequestContext } from './data_request_actions';
export {
closeOnClickTooltip,

View file

@ -0,0 +1,429 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { Dispatch } from 'redux';
import { Query } from 'src/plugins/data/public';
import { MapStoreState } from '../reducers/store';
import {
getLayerById,
getLayerListRaw,
getSelectedLayerId,
getMapReady,
getTransientLayerId,
} from '../selectors/map_selectors';
import { FLYOUT_STATE } from '../reducers/ui';
import { cancelRequest } from '../reducers/non_serializable_instances';
import { updateFlyout } from './ui_actions';
import {
ADD_LAYER,
ADD_WAITING_FOR_MAP_READY_LAYER,
CLEAR_WAITING_FOR_MAP_READY_LAYER_LIST,
REMOVE_LAYER,
REMOVE_TRACKED_LAYER_STATE,
ROLLBACK_TO_TRACKED_LAYER_STATE,
SET_JOINS,
SET_LAYER_VISIBILITY,
SET_SELECTED_LAYER,
SET_TRANSIENT_LAYER,
SET_WAITING_FOR_READY_HIDDEN_LAYERS,
TRACK_CURRENT_LAYER_STATE,
UPDATE_LAYER_ORDER,
UPDATE_LAYER_PROP,
UPDATE_LAYER_STYLE,
UPDATE_SOURCE_PROP,
} from './map_action_constants';
import {
clearDataRequests,
syncDataForLayerId,
syncDataForLayer,
updateStyleMeta,
} from './data_request_actions';
import { cleanTooltipStateForLayer } from './tooltip_actions';
import { JoinDescriptor, LayerDescriptor, StyleDescriptor } from '../../common/descriptor_types';
import { ILayer } from '../classes/layers/layer';
import { IVectorLayer } from '../classes/layers/vector_layer/vector_layer';
import { LAYER_TYPE } from '../../common/constants';
export function trackCurrentLayerState(layerId: string) {
return {
type: TRACK_CURRENT_LAYER_STATE,
layerId,
};
}
export function rollbackToTrackedLayerStateForSelectedLayer() {
return async (dispatch: Dispatch, getState: () => MapStoreState) => {
const layerId = getSelectedLayerId(getState());
await dispatch({
type: ROLLBACK_TO_TRACKED_LAYER_STATE,
layerId,
});
// Ensure updateStyleMeta is triggered
// syncDataForLayer may not trigger endDataLoad if no re-fetch is required
dispatch<any>(updateStyleMeta(layerId));
dispatch<any>(syncDataForLayerId(layerId));
};
}
export function removeTrackedLayerStateForSelectedLayer() {
return (dispatch: Dispatch, getState: () => MapStoreState) => {
const layerId = getSelectedLayerId(getState());
dispatch({
type: REMOVE_TRACKED_LAYER_STATE,
layerId,
});
};
}
export function replaceLayerList(newLayerList: LayerDescriptor[]) {
return (dispatch: Dispatch, getState: () => MapStoreState) => {
const isMapReady = getMapReady(getState());
if (!isMapReady) {
dispatch({
type: CLEAR_WAITING_FOR_MAP_READY_LAYER_LIST,
});
} else {
getLayerListRaw(getState()).forEach(({ id }) => {
dispatch<any>(removeLayerFromLayerList(id));
});
}
newLayerList.forEach((layerDescriptor) => {
dispatch<any>(addLayer(layerDescriptor));
});
};
}
export function cloneLayer(layerId: string) {
return async (dispatch: Dispatch, getState: () => MapStoreState) => {
const layer = getLayerById(layerId, getState());
if (!layer) {
return;
}
const clonedDescriptor = await layer.cloneDescriptor();
dispatch<any>(addLayer(clonedDescriptor));
};
}
export function addLayer(layerDescriptor: LayerDescriptor) {
return (dispatch: Dispatch, getState: () => MapStoreState) => {
const isMapReady = getMapReady(getState());
if (!isMapReady) {
dispatch({
type: ADD_WAITING_FOR_MAP_READY_LAYER,
layer: layerDescriptor,
});
return;
}
dispatch({
type: ADD_LAYER,
layer: layerDescriptor,
});
dispatch<any>(syncDataForLayerId(layerDescriptor.id));
};
}
// Do not use when rendering a map. Method exists to enable selectors for getLayerList when
// rendering is not needed.
export function addLayerWithoutDataSync(layerDescriptor: LayerDescriptor) {
return {
type: ADD_LAYER,
layer: layerDescriptor,
};
}
export function setLayerVisibility(layerId: string, makeVisible: boolean) {
return async (dispatch: Dispatch, getState: () => MapStoreState) => {
// if the current-state is invisible, we also want to sync data
// e.g. if a layer was invisible at start-up, it won't have any data loaded
const layer = getLayerById(layerId, getState());
// If the layer visibility is already what we want it to be, do nothing
if (!layer || layer.isVisible() === makeVisible) {
return;
}
if (!makeVisible) {
dispatch<any>(cleanTooltipStateForLayer(layerId));
}
await dispatch({
type: SET_LAYER_VISIBILITY,
layerId,
visibility: makeVisible,
});
if (makeVisible) {
dispatch<any>(syncDataForLayer(layer));
}
};
}
export function toggleLayerVisible(layerId: string) {
return async (dispatch: Dispatch, getState: () => MapStoreState) => {
const layer = getLayerById(layerId, getState());
if (!layer) {
return;
}
const makeVisible = !layer.isVisible();
dispatch<any>(setLayerVisibility(layerId, makeVisible));
};
}
export function setSelectedLayer(layerId: string | null) {
return async (dispatch: Dispatch, getState: () => MapStoreState) => {
const oldSelectedLayer = getSelectedLayerId(getState());
if (oldSelectedLayer) {
await dispatch<any>(rollbackToTrackedLayerStateForSelectedLayer());
}
if (layerId) {
dispatch(trackCurrentLayerState(layerId));
}
dispatch({
type: SET_SELECTED_LAYER,
selectedLayerId: layerId,
});
};
}
export function removeTransientLayer() {
return async (dispatch: Dispatch, getState: () => MapStoreState) => {
const transientLayerId = getTransientLayerId(getState());
if (transientLayerId) {
await dispatch<any>(removeLayerFromLayerList(transientLayerId));
await dispatch<any>(setTransientLayer(null));
}
};
}
export function setTransientLayer(layerId: string | null) {
return {
type: SET_TRANSIENT_LAYER,
transientLayerId: layerId,
};
}
export function clearTransientLayerStateAndCloseFlyout() {
return async (dispatch: Dispatch) => {
await dispatch(updateFlyout(FLYOUT_STATE.NONE));
await dispatch<any>(setSelectedLayer(null));
await dispatch<any>(removeTransientLayer());
};
}
export function updateLayerOrder(newLayerOrder: number[]) {
return {
type: UPDATE_LAYER_ORDER,
newLayerOrder,
};
}
export function updateSourceProp(
layerId: string,
propName: string,
value: unknown,
newLayerType?: LAYER_TYPE
) {
return async (dispatch: Dispatch) => {
dispatch({
type: UPDATE_SOURCE_PROP,
layerId,
propName,
value,
});
if (newLayerType) {
dispatch<any>(updateLayerType(layerId, newLayerType));
}
await dispatch<any>(clearMissingStyleProperties(layerId));
dispatch<any>(syncDataForLayerId(layerId));
};
}
function updateLayerType(layerId: string, newLayerType: string) {
return (dispatch: Dispatch, getState: () => MapStoreState) => {
const layer = getLayerById(layerId, getState());
if (!layer || layer.getType() === newLayerType) {
return;
}
dispatch<any>(clearDataRequests(layer));
dispatch({
type: UPDATE_LAYER_PROP,
id: layerId,
propName: 'type',
newValue: newLayerType,
});
};
}
export function updateLayerLabel(id: string, newLabel: string) {
return {
type: UPDATE_LAYER_PROP,
id,
propName: 'label',
newValue: newLabel,
};
}
export function updateLayerMinZoom(id: string, minZoom: number) {
return {
type: UPDATE_LAYER_PROP,
id,
propName: 'minZoom',
newValue: minZoom,
};
}
export function updateLayerMaxZoom(id: string, maxZoom: number) {
return {
type: UPDATE_LAYER_PROP,
id,
propName: 'maxZoom',
newValue: maxZoom,
};
}
export function updateLayerAlpha(id: string, alpha: number) {
return {
type: UPDATE_LAYER_PROP,
id,
propName: 'alpha',
newValue: alpha,
};
}
export function setLayerQuery(id: string, query: Query) {
return (dispatch: Dispatch) => {
dispatch({
type: UPDATE_LAYER_PROP,
id,
propName: 'query',
newValue: query,
});
dispatch<any>(syncDataForLayerId(id));
};
}
export function removeSelectedLayer() {
return (dispatch: Dispatch, getState: () => MapStoreState) => {
const state = getState();
const layerId = getSelectedLayerId(state);
dispatch<any>(removeLayer(layerId));
};
}
export function removeLayer(layerId: string | null) {
return async (dispatch: Dispatch, getState: () => MapStoreState) => {
const state = getState();
const selectedLayerId = getSelectedLayerId(state);
if (layerId === selectedLayerId) {
dispatch(updateFlyout(FLYOUT_STATE.NONE));
await dispatch<any>(setSelectedLayer(null));
}
dispatch<any>(removeLayerFromLayerList(layerId));
};
}
function removeLayerFromLayerList(layerId: string | null) {
return (dispatch: Dispatch, getState: () => MapStoreState) => {
const layerGettingRemoved = getLayerById(layerId, getState());
if (!layerGettingRemoved) {
return;
}
layerGettingRemoved.getInFlightRequestTokens().forEach((requestToken) => {
dispatch(cancelRequest(requestToken));
});
dispatch<any>(cleanTooltipStateForLayer(layerId!));
layerGettingRemoved.destroy();
dispatch({
type: REMOVE_LAYER,
id: layerId,
});
};
}
export function clearMissingStyleProperties(layerId: string) {
return async (dispatch: Dispatch, getState: () => MapStoreState) => {
const targetLayer = getLayerById(layerId, getState());
if (!targetLayer || !('getFields' in targetLayer)) {
return;
}
const style = targetLayer!.getCurrentStyle();
if (!style) {
return;
}
const nextFields = await (targetLayer as IVectorLayer).getFields(); // take into account all fields, since labels can be driven by any field (source or join)
const { hasChanges, nextStyleDescriptor } = style.getDescriptorWithMissingStylePropsRemoved(
nextFields
);
if (hasChanges && nextStyleDescriptor) {
dispatch<any>(updateLayerStyle(layerId, nextStyleDescriptor));
}
};
}
export function updateLayerStyle(layerId: string, styleDescriptor: StyleDescriptor) {
return (dispatch: Dispatch) => {
dispatch({
type: UPDATE_LAYER_STYLE,
layerId,
style: {
...styleDescriptor,
},
});
// Ensure updateStyleMeta is triggered
// syncDataForLayer may not trigger endDataLoad if no re-fetch is required
dispatch<any>(updateStyleMeta(layerId));
// Style update may require re-fetch, for example ES search may need to retrieve field used for dynamic styling
dispatch<any>(syncDataForLayerId(layerId));
};
}
export function updateLayerStyleForSelectedLayer(styleDescriptor: StyleDescriptor) {
return (dispatch: Dispatch, getState: () => MapStoreState) => {
const selectedLayerId = getSelectedLayerId(getState());
if (!selectedLayerId) {
return;
}
dispatch<any>(updateLayerStyle(selectedLayerId, styleDescriptor));
};
}
export function setJoinsForLayer(layer: ILayer, joins: JoinDescriptor[]) {
return async (dispatch: Dispatch) => {
await dispatch({
type: SET_JOINS,
layer,
joins,
});
await dispatch<any>(clearMissingStyleProperties(layer.getId()));
dispatch<any>(syncDataForLayerId(layer.getId()));
};
}
export function setHiddenLayers(hiddenLayerIds: string[]) {
return (dispatch: Dispatch, getState: () => MapStoreState) => {
const isMapReady = getMapReady(getState());
if (!isMapReady) {
dispatch({ type: SET_WAITING_FOR_READY_HIDDEN_LAYERS, hiddenLayerIds });
} else {
getLayerListRaw(getState()).forEach((layer) =>
dispatch<any>(setLayerVisibility(layer.id, !hiddenLayerIds.includes(layer.id)))
);
}
};
}

View file

@ -1,89 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
/* eslint-disable @typescript-eslint/consistent-type-definitions */
import { Filter, Query, TimeRange } from 'src/plugins/data/public';
import { AnyAction } from 'redux';
import { LAYER_TYPE } from '../../common/constants';
import {
DataMeta,
LayerDescriptor,
MapFilters,
MapCenterAndZoom,
MapRefreshConfig,
MapExtent,
} from '../../common/descriptor_types';
import { MapSettings } from '../reducers/map';
export function updateSourceProp(
layerId: string,
propName: string,
value: unknown,
newLayerType?: LAYER_TYPE
): void;
export function setGotoWithCenter(config: MapCenterAndZoom): AnyAction;
export function setGotoWithBounds(config: MapExtent): AnyAction;
export function fitToDataBounds(): AnyAction;
export function replaceLayerList(layerList: unknown[]): AnyAction;
export type QueryGroup = {
filters: Filter[];
query?: Query;
timeFilters?: TimeRange;
refresh?: boolean;
};
export function setQuery(query: QueryGroup): AnyAction;
export function setRefreshConfig(config: MapRefreshConfig): AnyAction;
export function disableScrollZoom(): AnyAction;
export function disableInteractive(): AnyAction;
export function disableTooltipControl(): AnyAction;
export function hideToolbarOverlay(): AnyAction;
export function hideLayerControl(): AnyAction;
export function hideViewControl(): AnyAction;
export function setHiddenLayers(hiddenLayerIds: string[]): AnyAction;
export function addLayerWithoutDataSync(layerDescriptor: unknown): AnyAction;
export function setMapSettings(settings: MapSettings): AnyAction;
export function rollbackMapSettings(): AnyAction;
export function trackMapSettings(): AnyAction;
export function updateMapSetting(
settingKey: string,
settingValue: string | boolean | number | object
): AnyAction;
export function cloneLayer(layerId: string): AnyAction;
export function fitToLayerExtent(layerId: string): AnyAction;
export function removeLayer(layerId: string): AnyAction;
export function toggleLayerVisible(layerId: string): AnyAction;
export function clearTransientLayerStateAndCloseFlyout(): AnyAction;
export function setTransientLayer(layerId: string | null): AnyAction;
export function removeTransientLayer(): AnyAction;
export function addLayer(layerDescriptor: LayerDescriptor): AnyAction;
export function setSelectedLayer(layerId: string | null): AnyAction;

View file

@ -1,730 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import turf from 'turf';
import turfBooleanContains from '@turf/boolean-contains';
import {
getLayerById,
getLayerListRaw,
getDataFilters,
getSelectedLayerId,
getMapReady,
getWaitingForMapReadyLayerListRaw,
getTransientLayerId,
getQuery,
getFittableLayers,
} from '../selectors/map_selectors';
import { FLYOUT_STATE } from '../reducers/ui';
import { cancelRequest } from '../reducers/non_serializable_instances';
import { updateFlyout } from './ui_actions';
import {
ADD_LAYER,
ADD_WAITING_FOR_MAP_READY_LAYER,
CLEAR_GOTO,
CLEAR_MOUSE_COORDINATES,
CLEAR_WAITING_FOR_MAP_READY_LAYER_LIST,
DISABLE_TOOLTIP_CONTROL,
HIDE_LAYER_CONTROL,
HIDE_TOOLBAR_OVERLAY,
HIDE_VIEW_CONTROL,
MAP_DESTROYED,
MAP_EXTENT_CHANGED,
MAP_READY,
REMOVE_LAYER,
REMOVE_TRACKED_LAYER_STATE,
ROLLBACK_MAP_SETTINGS,
ROLLBACK_TO_TRACKED_LAYER_STATE,
SET_GOTO,
SET_INTERACTIVE,
SET_JOINS,
SET_LAYER_VISIBILITY,
SET_MAP_INIT_ERROR,
SET_MAP_SETTINGS,
SET_MOUSE_COORDINATES,
SET_OPEN_TOOLTIPS,
SET_QUERY,
SET_REFRESH_CONFIG,
SET_SCROLL_ZOOM,
SET_SELECTED_LAYER,
SET_TRANSIENT_LAYER,
SET_WAITING_FOR_READY_HIDDEN_LAYERS,
TRACK_CURRENT_LAYER_STATE,
TRACK_MAP_SETTINGS,
TRIGGER_REFRESH_TIMER,
UPDATE_DRAW_STATE,
UPDATE_LAYER_ORDER,
UPDATE_LAYER_PROP,
UPDATE_LAYER_STYLE,
UPDATE_MAP_SETTING,
UPDATE_SOURCE_PROP,
} from './map_action_constants';
import {
clearDataRequests,
syncDataForAllLayers,
syncDataForLayerId,
syncDataForLayer,
updateStyleMeta,
} from './data_request_actions';
import { cleanTooltipStateForLayer } from './tooltip_actions';
export function setMapInitError(errorMessage) {
return {
type: SET_MAP_INIT_ERROR,
errorMessage,
};
}
export function setMapSettings(settings) {
return {
type: SET_MAP_SETTINGS,
settings,
};
}
export function rollbackMapSettings() {
return { type: ROLLBACK_MAP_SETTINGS };
}
export function trackMapSettings() {
return { type: TRACK_MAP_SETTINGS };
}
export function updateMapSetting(settingKey, settingValue) {
return {
type: UPDATE_MAP_SETTING,
settingKey,
settingValue,
};
}
export function trackCurrentLayerState(layerId) {
return {
type: TRACK_CURRENT_LAYER_STATE,
layerId: layerId,
};
}
export function rollbackToTrackedLayerStateForSelectedLayer() {
return async (dispatch, getState) => {
const layerId = getSelectedLayerId(getState());
await dispatch({
type: ROLLBACK_TO_TRACKED_LAYER_STATE,
layerId: layerId,
});
// Ensure updateStyleMeta is triggered
// syncDataForLayer may not trigger endDataLoad if no re-fetch is required
dispatch(updateStyleMeta(layerId));
dispatch(syncDataForLayerId(layerId));
};
}
export function removeTrackedLayerStateForSelectedLayer() {
return (dispatch, getState) => {
const layerId = getSelectedLayerId(getState());
dispatch({
type: REMOVE_TRACKED_LAYER_STATE,
layerId: layerId,
});
};
}
export function replaceLayerList(newLayerList) {
return (dispatch, getState) => {
const isMapReady = getMapReady(getState());
if (!isMapReady) {
dispatch({
type: CLEAR_WAITING_FOR_MAP_READY_LAYER_LIST,
});
} else {
getLayerListRaw(getState()).forEach(({ id }) => {
dispatch(removeLayerFromLayerList(id));
});
}
newLayerList.forEach((layerDescriptor) => {
dispatch(addLayer(layerDescriptor));
});
};
}
export function cloneLayer(layerId) {
return async (dispatch, getState) => {
const layer = getLayerById(layerId, getState());
if (!layer) {
return;
}
const clonedDescriptor = await layer.cloneDescriptor();
dispatch(addLayer(clonedDescriptor));
};
}
export function addLayer(layerDescriptor) {
return (dispatch, getState) => {
const isMapReady = getMapReady(getState());
if (!isMapReady) {
dispatch({
type: ADD_WAITING_FOR_MAP_READY_LAYER,
layer: layerDescriptor,
});
return;
}
dispatch({
type: ADD_LAYER,
layer: layerDescriptor,
});
dispatch(syncDataForLayerId(layerDescriptor.id));
};
}
// Do not use when rendering a map. Method exists to enable selectors for getLayerList when
// rendering is not needed.
export function addLayerWithoutDataSync(layerDescriptor) {
return {
type: ADD_LAYER,
layer: layerDescriptor,
};
}
export function setLayerVisibility(layerId, makeVisible) {
return async (dispatch, getState) => {
//if the current-state is invisible, we also want to sync data
//e.g. if a layer was invisible at start-up, it won't have any data loaded
const layer = getLayerById(layerId, getState());
// If the layer visibility is already what we want it to be, do nothing
if (!layer || layer.isVisible() === makeVisible) {
return;
}
if (!makeVisible) {
dispatch(cleanTooltipStateForLayer(layerId));
}
await dispatch({
type: SET_LAYER_VISIBILITY,
layerId,
visibility: makeVisible,
});
if (makeVisible) {
dispatch(syncDataForLayer(layer));
}
};
}
export function toggleLayerVisible(layerId) {
return async (dispatch, getState) => {
const layer = getLayerById(layerId, getState());
if (!layer) {
return;
}
const makeVisible = !layer.isVisible();
dispatch(setLayerVisibility(layerId, makeVisible));
};
}
export function setSelectedLayer(layerId) {
return async (dispatch, getState) => {
const oldSelectedLayer = getSelectedLayerId(getState());
if (oldSelectedLayer) {
await dispatch(rollbackToTrackedLayerStateForSelectedLayer());
}
if (layerId) {
dispatch(trackCurrentLayerState(layerId));
}
dispatch({
type: SET_SELECTED_LAYER,
selectedLayerId: layerId,
});
};
}
export function removeTransientLayer() {
return async (dispatch, getState) => {
const transientLayerId = getTransientLayerId(getState());
if (transientLayerId) {
await dispatch(removeLayerFromLayerList(transientLayerId));
await dispatch(setTransientLayer(null));
}
};
}
export function setTransientLayer(layerId) {
return {
type: SET_TRANSIENT_LAYER,
transientLayerId: layerId,
};
}
export function clearTransientLayerStateAndCloseFlyout() {
return async (dispatch) => {
await dispatch(updateFlyout(FLYOUT_STATE.NONE));
await dispatch(setSelectedLayer(null));
await dispatch(removeTransientLayer());
};
}
export function updateLayerOrder(newLayerOrder) {
return {
type: UPDATE_LAYER_ORDER,
newLayerOrder,
};
}
export function mapReady() {
return (dispatch, getState) => {
dispatch({
type: MAP_READY,
});
getWaitingForMapReadyLayerListRaw(getState()).forEach((layerDescriptor) => {
dispatch(addLayer(layerDescriptor));
});
dispatch({
type: CLEAR_WAITING_FOR_MAP_READY_LAYER_LIST,
});
};
}
export function mapDestroyed() {
return {
type: MAP_DESTROYED,
};
}
export function mapExtentChanged(newMapConstants) {
return async (dispatch, getState) => {
const state = getState();
const dataFilters = getDataFilters(state);
const { extent, zoom: newZoom } = newMapConstants;
const { buffer, zoom: currentZoom } = dataFilters;
if (extent) {
let doesBufferContainExtent = false;
if (buffer) {
const bufferGeometry = turf.bboxPolygon([
buffer.minLon,
buffer.minLat,
buffer.maxLon,
buffer.maxLat,
]);
const extentGeometry = turf.bboxPolygon([
extent.minLon,
extent.minLat,
extent.maxLon,
extent.maxLat,
]);
doesBufferContainExtent = turfBooleanContains(bufferGeometry, extentGeometry);
}
if (!doesBufferContainExtent || currentZoom !== newZoom) {
const scaleFactor = 0.5; // TODO put scale factor in store and fetch with selector
const width = extent.maxLon - extent.minLon;
const height = extent.maxLat - extent.minLat;
dataFilters.buffer = {
minLon: extent.minLon - width * scaleFactor,
minLat: extent.minLat - height * scaleFactor,
maxLon: extent.maxLon + width * scaleFactor,
maxLat: extent.maxLat + height * scaleFactor,
};
}
}
dispatch({
type: MAP_EXTENT_CHANGED,
mapState: {
...dataFilters,
...newMapConstants,
},
});
await dispatch(syncDataForAllLayers());
};
}
export function setMouseCoordinates({ lat, lon }) {
let safeLon = lon;
if (lon > 180) {
const overlapWestOfDateLine = lon - 180;
safeLon = -180 + overlapWestOfDateLine;
} else if (lon < -180) {
const overlapEastOfDateLine = Math.abs(lon) - 180;
safeLon = 180 - overlapEastOfDateLine;
}
return {
type: SET_MOUSE_COORDINATES,
lat,
lon: safeLon,
};
}
export function clearMouseCoordinates() {
return { type: CLEAR_MOUSE_COORDINATES };
}
export function disableScrollZoom() {
return { type: SET_SCROLL_ZOOM, scrollZoom: false };
}
export function fitToLayerExtent(layerId) {
return async function (dispatch, getState) {
const targetLayer = getLayerById(layerId, getState());
if (targetLayer) {
const dataFilters = getDataFilters(getState());
const bounds = await targetLayer.getBounds(dataFilters);
if (bounds) {
await dispatch(setGotoWithBounds(bounds));
}
}
};
}
export function fitToDataBounds() {
return async function (dispatch, getState) {
const layerList = getFittableLayers(getState());
if (!layerList.length) {
return;
}
const dataFilters = getDataFilters(getState());
const boundsPromises = layerList.map(async (layer) => {
return layer.getBounds(dataFilters);
});
const bounds = await Promise.all(boundsPromises);
const corners = [];
for (let i = 0; i < bounds.length; i++) {
const b = bounds[i];
//filter out undefined bounds (uses Infinity due to turf responses)
if (
b === null ||
b.minLon === Infinity ||
b.maxLon === Infinity ||
b.minLat === -Infinity ||
b.maxLat === -Infinity
) {
continue;
}
corners.push([b.minLon, b.minLat]);
corners.push([b.maxLon, b.maxLat]);
}
if (!corners.length) {
return;
}
const turfUnionBbox = turf.bbox(turf.multiPoint(corners));
const dataBounds = {
minLon: turfUnionBbox[0],
minLat: turfUnionBbox[1],
maxLon: turfUnionBbox[2],
maxLat: turfUnionBbox[3],
};
dispatch(setGotoWithBounds(dataBounds));
};
}
export function setGotoWithBounds(bounds) {
return {
type: SET_GOTO,
bounds: bounds,
};
}
export function setGotoWithCenter({ lat, lon, zoom }) {
return {
type: SET_GOTO,
center: { lat, lon, zoom },
};
}
export function clearGoto() {
return { type: CLEAR_GOTO };
}
export function updateSourceProp(layerId, propName, value, newLayerType) {
return async (dispatch) => {
dispatch({
type: UPDATE_SOURCE_PROP,
layerId,
propName,
value,
});
if (newLayerType) {
dispatch(updateLayerType(layerId, newLayerType));
}
await dispatch(clearMissingStyleProperties(layerId));
dispatch(syncDataForLayerId(layerId));
};
}
function updateLayerType(layerId, newLayerType) {
return (dispatch, getState) => {
const layer = getLayerById(layerId, getState());
if (!layer || layer.getType() === newLayerType) {
return;
}
dispatch(clearDataRequests(layer));
dispatch({
type: UPDATE_LAYER_PROP,
id: layerId,
propName: 'type',
newValue: newLayerType,
});
};
}
export function updateLayerLabel(id, newLabel) {
return {
type: UPDATE_LAYER_PROP,
id,
propName: 'label',
newValue: newLabel,
};
}
export function updateLayerMinZoom(id, minZoom) {
return {
type: UPDATE_LAYER_PROP,
id,
propName: 'minZoom',
newValue: minZoom,
};
}
export function updateLayerMaxZoom(id, maxZoom) {
return {
type: UPDATE_LAYER_PROP,
id,
propName: 'maxZoom',
newValue: maxZoom,
};
}
export function updateLayerAlpha(id, alpha) {
return {
type: UPDATE_LAYER_PROP,
id,
propName: 'alpha',
newValue: alpha,
};
}
export function setLayerQuery(id, query) {
return (dispatch) => {
dispatch({
type: UPDATE_LAYER_PROP,
id,
propName: 'query',
newValue: query,
});
dispatch(syncDataForLayerId(id));
};
}
export function removeSelectedLayer() {
return (dispatch, getState) => {
const state = getState();
const layerId = getSelectedLayerId(state);
dispatch(removeLayer(layerId));
};
}
export function removeLayer(layerId) {
return async (dispatch, getState) => {
const state = getState();
const selectedLayerId = getSelectedLayerId(state);
if (layerId === selectedLayerId) {
dispatch(updateFlyout(FLYOUT_STATE.NONE));
await dispatch(setSelectedLayer(null));
}
dispatch(removeLayerFromLayerList(layerId));
};
}
function removeLayerFromLayerList(layerId) {
return (dispatch, getState) => {
const layerGettingRemoved = getLayerById(layerId, getState());
if (!layerGettingRemoved) {
return;
}
layerGettingRemoved.getInFlightRequestTokens().forEach((requestToken) => {
dispatch(cancelRequest(requestToken));
});
dispatch(cleanTooltipStateForLayer(layerId));
layerGettingRemoved.destroy();
dispatch({
type: REMOVE_LAYER,
id: layerId,
});
};
}
export function setQuery({ query, timeFilters, filters = [], refresh = false }) {
function generateQueryTimestamp() {
return new Date().toISOString();
}
return async (dispatch, getState) => {
const prevQuery = getQuery(getState());
const prevTriggeredAt =
prevQuery && prevQuery.queryLastTriggeredAt
? prevQuery.queryLastTriggeredAt
: generateQueryTimestamp();
dispatch({
type: SET_QUERY,
timeFilters,
query: {
...query,
// ensure query changes to trigger re-fetch when "Refresh" clicked
queryLastTriggeredAt: refresh ? generateQueryTimestamp() : prevTriggeredAt,
},
filters,
});
await dispatch(syncDataForAllLayers());
};
}
export function setRefreshConfig({ isPaused, interval }) {
return {
type: SET_REFRESH_CONFIG,
isPaused,
interval,
};
}
export function triggerRefreshTimer() {
return async (dispatch) => {
dispatch({
type: TRIGGER_REFRESH_TIMER,
});
await dispatch(syncDataForAllLayers());
};
}
export function clearMissingStyleProperties(layerId) {
return async (dispatch, getState) => {
const targetLayer = getLayerById(layerId, getState());
if (!targetLayer) {
return;
}
const style = targetLayer.getCurrentStyle();
if (!style) {
return;
}
const nextFields = await targetLayer.getFields(); //take into account all fields, since labels can be driven by any field (source or join)
const { hasChanges, nextStyleDescriptor } = style.getDescriptorWithMissingStylePropsRemoved(
nextFields
);
if (hasChanges) {
dispatch(updateLayerStyle(layerId, nextStyleDescriptor));
}
};
}
export function updateLayerStyle(layerId, styleDescriptor) {
return (dispatch) => {
dispatch({
type: UPDATE_LAYER_STYLE,
layerId,
style: {
...styleDescriptor,
},
});
// Ensure updateStyleMeta is triggered
// syncDataForLayer may not trigger endDataLoad if no re-fetch is required
dispatch(updateStyleMeta(layerId));
// Style update may require re-fetch, for example ES search may need to retrieve field used for dynamic styling
dispatch(syncDataForLayerId(layerId));
};
}
export function updateLayerStyleForSelectedLayer(styleDescriptor) {
return (dispatch, getState) => {
const selectedLayerId = getSelectedLayerId(getState());
if (!selectedLayerId) {
return;
}
dispatch(updateLayerStyle(selectedLayerId, styleDescriptor));
};
}
export function setJoinsForLayer(layer, joins) {
return async (dispatch) => {
await dispatch({
type: SET_JOINS,
layer,
joins,
});
await dispatch(clearMissingStyleProperties(layer.getId()));
dispatch(syncDataForLayerId(layer.getId()));
};
}
export function updateDrawState(drawState) {
return (dispatch) => {
if (drawState !== null) {
dispatch({ type: SET_OPEN_TOOLTIPS, openTooltips: [] }); // tooltips just get in the way
}
dispatch({
type: UPDATE_DRAW_STATE,
drawState: drawState,
});
};
}
export function disableInteractive() {
return { type: SET_INTERACTIVE, disableInteractive: true };
}
export function disableTooltipControl() {
return { type: DISABLE_TOOLTIP_CONTROL, disableTooltipControl: true };
}
export function hideToolbarOverlay() {
return { type: HIDE_TOOLBAR_OVERLAY, hideToolbarOverlay: true };
}
export function hideLayerControl() {
return { type: HIDE_LAYER_CONTROL, hideLayerControl: true };
}
export function hideViewControl() {
return { type: HIDE_VIEW_CONTROL, hideViewControl: true };
}
export function setHiddenLayers(hiddenLayerIds) {
return (dispatch, getState) => {
const isMapReady = getMapReady(getState());
if (!isMapReady) {
dispatch({ type: SET_WAITING_FOR_READY_HIDDEN_LAYERS, hiddenLayerIds });
} else {
getLayerListRaw(getState()).forEach((layer) =>
dispatch(setLayerVisibility(layer.id, !hiddenLayerIds.includes(layer.id)))
);
}
};
}

View file

@ -0,0 +1,352 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
/* eslint-disable @typescript-eslint/consistent-type-definitions */
import { Dispatch } from 'redux';
// @ts-ignore
import turf from 'turf';
import turfBooleanContains from '@turf/boolean-contains';
import { Filter, Query, TimeRange } from 'src/plugins/data/public';
import { MapStoreState } from '../reducers/store';
import {
getLayerById,
getDataFilters,
getWaitingForMapReadyLayerListRaw,
getQuery,
getFittableLayers,
} from '../selectors/map_selectors';
import {
CLEAR_GOTO,
CLEAR_MOUSE_COORDINATES,
CLEAR_WAITING_FOR_MAP_READY_LAYER_LIST,
DISABLE_TOOLTIP_CONTROL,
HIDE_LAYER_CONTROL,
HIDE_TOOLBAR_OVERLAY,
HIDE_VIEW_CONTROL,
MAP_DESTROYED,
MAP_EXTENT_CHANGED,
MAP_READY,
ROLLBACK_MAP_SETTINGS,
SET_GOTO,
SET_INTERACTIVE,
SET_MAP_INIT_ERROR,
SET_MAP_SETTINGS,
SET_MOUSE_COORDINATES,
SET_OPEN_TOOLTIPS,
SET_QUERY,
SET_REFRESH_CONFIG,
SET_SCROLL_ZOOM,
TRACK_MAP_SETTINGS,
TRIGGER_REFRESH_TIMER,
UPDATE_DRAW_STATE,
UPDATE_MAP_SETTING,
} from './map_action_constants';
import { syncDataForAllLayers } from './data_request_actions';
import { addLayer } from './layer_actions';
import { MapSettings } from '../reducers/map';
import {
DrawState,
MapCenterAndZoom,
MapExtent,
MapRefreshConfig,
} from '../../common/descriptor_types';
export function setMapInitError(errorMessage: string) {
return {
type: SET_MAP_INIT_ERROR,
errorMessage,
};
}
export function setMapSettings(settings: MapSettings) {
return {
type: SET_MAP_SETTINGS,
settings,
};
}
export function rollbackMapSettings() {
return { type: ROLLBACK_MAP_SETTINGS };
}
export function trackMapSettings() {
return { type: TRACK_MAP_SETTINGS };
}
export function updateMapSetting(
settingKey: string,
settingValue: string | boolean | number | object
) {
return {
type: UPDATE_MAP_SETTING,
settingKey,
settingValue,
};
}
export function mapReady() {
return (dispatch: Dispatch, getState: () => MapStoreState) => {
dispatch({
type: MAP_READY,
});
getWaitingForMapReadyLayerListRaw(getState()).forEach((layerDescriptor) => {
dispatch<any>(addLayer(layerDescriptor));
});
dispatch({
type: CLEAR_WAITING_FOR_MAP_READY_LAYER_LIST,
});
};
}
export function mapDestroyed() {
return {
type: MAP_DESTROYED,
};
}
export function mapExtentChanged(newMapConstants: { zoom: number; extent: MapExtent }) {
return async (dispatch: Dispatch, getState: () => MapStoreState) => {
const state = getState();
const dataFilters = getDataFilters(state);
const { extent, zoom: newZoom } = newMapConstants;
const { buffer, zoom: currentZoom } = dataFilters;
if (extent) {
let doesBufferContainExtent = false;
if (buffer) {
const bufferGeometry = turf.bboxPolygon([
buffer.minLon,
buffer.minLat,
buffer.maxLon,
buffer.maxLat,
]);
const extentGeometry = turf.bboxPolygon([
extent.minLon,
extent.minLat,
extent.maxLon,
extent.maxLat,
]);
doesBufferContainExtent = turfBooleanContains(bufferGeometry, extentGeometry);
}
if (!doesBufferContainExtent || currentZoom !== newZoom) {
const scaleFactor = 0.5; // TODO put scale factor in store and fetch with selector
const width = extent.maxLon - extent.minLon;
const height = extent.maxLat - extent.minLat;
dataFilters.buffer = {
minLon: extent.minLon - width * scaleFactor,
minLat: extent.minLat - height * scaleFactor,
maxLon: extent.maxLon + width * scaleFactor,
maxLat: extent.maxLat + height * scaleFactor,
};
}
}
dispatch({
type: MAP_EXTENT_CHANGED,
mapState: {
...dataFilters,
...newMapConstants,
},
});
await dispatch<any>(syncDataForAllLayers());
};
}
export function setMouseCoordinates({ lat, lon }: { lat: number; lon: number }) {
let safeLon = lon;
if (lon > 180) {
const overlapWestOfDateLine = lon - 180;
safeLon = -180 + overlapWestOfDateLine;
} else if (lon < -180) {
const overlapEastOfDateLine = Math.abs(lon) - 180;
safeLon = 180 - overlapEastOfDateLine;
}
return {
type: SET_MOUSE_COORDINATES,
lat,
lon: safeLon,
};
}
export function clearMouseCoordinates() {
return { type: CLEAR_MOUSE_COORDINATES };
}
export function disableScrollZoom() {
return { type: SET_SCROLL_ZOOM, scrollZoom: false };
}
export function fitToLayerExtent(layerId: string) {
return async (dispatch: Dispatch, getState: () => MapStoreState) => {
const targetLayer = getLayerById(layerId, getState());
if (targetLayer) {
const dataFilters = getDataFilters(getState());
const bounds = await targetLayer.getBounds(dataFilters);
if (bounds) {
await dispatch(setGotoWithBounds(bounds));
}
}
};
}
export function fitToDataBounds() {
return async (dispatch: Dispatch, getState: () => MapStoreState) => {
const layerList = getFittableLayers(getState());
if (!layerList.length) {
return;
}
const dataFilters = getDataFilters(getState());
const boundsPromises = layerList.map(async (layer) => {
return layer.getBounds(dataFilters);
});
const bounds = await Promise.all(boundsPromises);
const corners = [];
for (let i = 0; i < bounds.length; i++) {
const b = bounds[i];
// filter out undefined bounds (uses Infinity due to turf responses)
if (
b === null ||
b.minLon === Infinity ||
b.maxLon === Infinity ||
b.minLat === -Infinity ||
b.maxLat === -Infinity
) {
continue;
}
corners.push([b.minLon, b.minLat]);
corners.push([b.maxLon, b.maxLat]);
}
if (!corners.length) {
return;
}
const turfUnionBbox = turf.bbox(turf.multiPoint(corners));
const dataBounds = {
minLon: turfUnionBbox[0],
minLat: turfUnionBbox[1],
maxLon: turfUnionBbox[2],
maxLat: turfUnionBbox[3],
};
dispatch(setGotoWithBounds(dataBounds));
};
}
export function setGotoWithBounds(bounds: MapExtent) {
return {
type: SET_GOTO,
bounds,
};
}
export function setGotoWithCenter({ lat, lon, zoom }: MapCenterAndZoom) {
return {
type: SET_GOTO,
center: { lat, lon, zoom },
};
}
export function clearGoto() {
return { type: CLEAR_GOTO };
}
function generateQueryTimestamp() {
return new Date().toISOString();
}
export function setQuery({
query,
timeFilters,
filters = [],
refresh = false,
}: {
filters: Filter[];
query?: Query;
timeFilters?: TimeRange;
refresh?: boolean;
}) {
return async (dispatch: Dispatch, getState: () => MapStoreState) => {
const prevQuery = getQuery(getState());
const prevTriggeredAt =
prevQuery && prevQuery.queryLastTriggeredAt
? prevQuery.queryLastTriggeredAt
: generateQueryTimestamp();
dispatch({
type: SET_QUERY,
timeFilters,
query: {
...query,
// ensure query changes to trigger re-fetch when "Refresh" clicked
queryLastTriggeredAt: refresh ? generateQueryTimestamp() : prevTriggeredAt,
},
filters,
});
await dispatch<any>(syncDataForAllLayers());
};
}
export function setRefreshConfig({ isPaused, interval }: MapRefreshConfig) {
return {
type: SET_REFRESH_CONFIG,
isPaused,
interval,
};
}
export function triggerRefreshTimer() {
return async (dispatch: Dispatch) => {
dispatch({
type: TRIGGER_REFRESH_TIMER,
});
await dispatch<any>(syncDataForAllLayers());
};
}
export function updateDrawState(drawState: DrawState) {
return (dispatch: Dispatch) => {
if (drawState !== null) {
dispatch({ type: SET_OPEN_TOOLTIPS, openTooltips: [] }); // tooltips just get in the way
}
dispatch({
type: UPDATE_DRAW_STATE,
drawState,
});
};
}
export function disableInteractive() {
return { type: SET_INTERACTIVE, disableInteractive: true };
}
export function disableTooltipControl() {
return { type: DISABLE_TOOLTIP_CONTROL, disableTooltipControl: true };
}
export function hideToolbarOverlay() {
return { type: HIDE_TOOLBAR_OVERLAY, hideToolbarOverlay: true };
}
export function hideLayerControl() {
return { type: HIDE_LAYER_CONTROL, hideLayerControl: true };
}
export function hideViewControl() {
return { type: HIDE_VIEW_CONTROL, hideViewControl: true };
}

View file

@ -72,7 +72,7 @@ export function openOnHoverTooltip(tooltipState: TooltipState) {
};
}
export function cleanTooltipStateForLayer(layerId: string, layerFeatures: Feature[] = []) {
export function cleanTooltipStateForLayer(layerId: string | null, layerFeatures: Feature[] = []) {
return (dispatch: Dispatch, getState: () => MapStoreState) => {
let featuresRemoved = false;
const openTooltips = getOpenTooltips(getState())

View file

@ -1,29 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { AnyAction } from 'redux';
import { INDEXING_STAGE, FLYOUT_STATE } from '../reducers/ui';
export const UPDATE_FLYOUT: string;
export const CLOSE_SET_VIEW: string;
export const OPEN_SET_VIEW: string;
export const SET_IS_LAYER_TOC_OPEN: string;
export const SET_FULL_SCREEN: string;
export const SET_READ_ONLY: string;
export const SET_OPEN_TOC_DETAILS: string;
export const SHOW_TOC_DETAILS: string;
export const HIDE_TOC_DETAILS: string;
export const UPDATE_INDEXING_STAGE: string;
export function updateFlyout(display: FLYOUT_STATE): AnyAction;
export function setOpenTOCDetails(layerIds?: string[]): AnyAction;
export function setIsLayerTOCOpen(open: boolean): AnyAction;
export function setReadOnly(readOnly: boolean): AnyAction;
export function updateIndexingStage(state: INDEXING_STAGE | null): AnyAction;

View file

@ -4,9 +4,12 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { Dispatch } from 'redux';
import { MapStoreState } from '../reducers/store';
import { getFlyoutDisplay } from '../selectors/ui_selectors';
import { FLYOUT_STATE } from '../reducers/ui';
import { setSelectedLayer, trackMapSettings } from './map_actions';
import { FLYOUT_STATE, INDEXING_STAGE } from '../reducers/ui';
import { trackMapSettings } from './map_actions';
import { setSelectedLayer } from './layer_actions';
export const UPDATE_FLYOUT = 'UPDATE_FLYOUT';
export const CLOSE_SET_VIEW = 'CLOSE_SET_VIEW';
@ -26,19 +29,19 @@ export function exitFullScreen() {
};
}
export function updateFlyout(display) {
export function updateFlyout(display: FLYOUT_STATE) {
return {
type: UPDATE_FLYOUT,
display,
};
}
export function openMapSettings() {
return (dispatch, getState) => {
return (dispatch: Dispatch, getState: () => MapStoreState) => {
const flyoutDisplay = getFlyoutDisplay(getState());
if (flyoutDisplay === FLYOUT_STATE.MAP_SETTINGS_PANEL) {
return;
}
dispatch(setSelectedLayer(null));
dispatch<any>(setSelectedLayer(null));
dispatch(trackMapSettings());
dispatch(updateFlyout(FLYOUT_STATE.MAP_SETTINGS_PANEL));
};
@ -53,7 +56,7 @@ export function openSetView() {
type: OPEN_SET_VIEW,
};
}
export function setIsLayerTOCOpen(isLayerTOCOpen) {
export function setIsLayerTOCOpen(isLayerTOCOpen: boolean) {
return {
type: SET_IS_LAYER_TOC_OPEN,
isLayerTOCOpen,
@ -65,35 +68,35 @@ export function enableFullScreen() {
isFullScreen: true,
};
}
export function setReadOnly(isReadOnly) {
export function setReadOnly(isReadOnly: boolean) {
return {
type: SET_READ_ONLY,
isReadOnly,
};
}
export function setOpenTOCDetails(layerIds) {
export function setOpenTOCDetails(layerIds?: string[]) {
return {
type: SET_OPEN_TOC_DETAILS,
layerIds,
};
}
export function showTOCDetails(layerId) {
export function showTOCDetails(layerId: string) {
return {
type: SHOW_TOC_DETAILS,
layerId,
};
}
export function hideTOCDetails(layerId) {
export function hideTOCDetails(layerId: string) {
return {
type: HIDE_TOC_DETAILS,
layerId,
};
}
export function updateIndexingStage(stage) {
export function updateIndexingStage(stage: INDEXING_STAGE | null) {
return {
type: UPDATE_INDEXING_STAGE,
stage,

View file

@ -4,4 +4,9 @@
* you may not use this file except in compliance with the Elastic License.
*/
export function getInitialLayers(layerListJSON?: string, initialLayers?: unknown[]): unknown[];
import { LayerDescriptor } from '../../common/descriptor_types';
export function getInitialLayers(
layerListJSON?: string,
initialLayers?: LayerDescriptor[]
): LayerDescriptor[];

View file

@ -79,6 +79,7 @@ export interface ILayer {
}): ReactElement<any> | null;
getInFlightRequestTokens(): symbol[];
getPrevRequestToken(dataId: string): symbol | undefined;
destroy: () => void;
}
export type Footnote = {
icon: ReactElement<any>;

View file

@ -22,7 +22,7 @@ function mapStateToProps(state: MapStoreState) {
function mapDispatchToProps(dispatch: Dispatch<AnyAction>) {
return {
closeFlyout: () => dispatch(clearTransientLayerStateAndCloseFlyout()),
closeFlyout: () => dispatch<any>(clearTransientLayerStateAndCloseFlyout()),
};
}

View file

@ -33,15 +33,15 @@ function mapStateToProps(state: MapStoreState) {
function mapDispatchToProps(dispatch: Dispatch<AnyAction>) {
return {
previewLayer: async (layerDescriptor: LayerDescriptor) => {
await dispatch(setSelectedLayer(null));
await dispatch(removeTransientLayer());
dispatch(addLayer(layerDescriptor));
dispatch(setSelectedLayer(layerDescriptor.id));
await dispatch<any>(setSelectedLayer(null));
await dispatch<any>(removeTransientLayer());
dispatch<any>(addLayer(layerDescriptor));
dispatch<any>(setSelectedLayer(layerDescriptor.id));
dispatch(setTransientLayer(layerDescriptor.id));
},
removeTransientLayer: () => {
dispatch(setSelectedLayer(null));
dispatch(removeTransientLayer());
dispatch<any>(setSelectedLayer(null));
dispatch<any>(removeTransientLayer());
},
selectLayerAndAdd: () => {
dispatch(setTransientLayer(null));

View file

@ -20,7 +20,7 @@ function mapStateToProps(state: MapStoreState) {
function mapDispatchToProps(dispatch: Dispatch<AnyAction>) {
return {
fitToBounds: () => {
dispatch(fitToDataBounds());
dispatch<any>(fitToDataBounds());
},
};
}

View file

@ -28,16 +28,16 @@ function mapStateToProps(state: MapStoreState) {
function mapDispatchToProps(dispatch: Dispatch<AnyAction>) {
return {
cloneLayer: (layerId: string) => {
dispatch(cloneLayer(layerId));
dispatch<any>(cloneLayer(layerId));
},
fitToBounds: (layerId: string) => {
dispatch(fitToLayerExtent(layerId));
dispatch<any>(fitToLayerExtent(layerId));
},
removeLayer: (layerId: string) => {
dispatch(removeLayer(layerId));
dispatch<any>(removeLayer(layerId));
},
toggleVisible: (layerId: string) => {
dispatch(toggleLayerVisible(layerId));
dispatch<any>(toggleLayerVisible(layerId));
},
};
}

View file

@ -55,6 +55,7 @@ import { getMapCenter, getMapZoom, getHiddenLayerIds } from '../selectors/map_se
import { MAP_SAVED_OBJECT_TYPE } from '../../common/constants';
import { RenderToolTipContent } from '../classes/tooltips/tooltip_property';
import { getUiActions, getCoreI18n } from '../kibana_services';
import { LayerDescriptor } from '../../common/descriptor_types';
import { MapEmbeddableInput, MapEmbeddableConfig } from './types';
export { MapEmbeddableInput, MapEmbeddableConfig };
@ -69,7 +70,7 @@ export class MapEmbeddable extends Embeddable<MapEmbeddableInput, MapEmbeddableO
private _renderTooltipContent?: RenderToolTipContent;
private _eventHandlers?: EventHandlers;
private _layerList: unknown[];
private _layerList: LayerDescriptor[];
private _store: MapStore;
private _subscription: Subscription;
private _prevTimeRange?: TimeRange;
@ -147,7 +148,7 @@ export class MapEmbeddable extends Embeddable<MapEmbeddableInput, MapEmbeddableO
this._prevTimeRange = timeRange;
this._prevQuery = query;
this._prevFilters = filters;
this._store.dispatch(
this._store.dispatch<any>(
setQuery({
filters: filters.filter((filter) => !filter.meta.disabled),
query,
@ -218,9 +219,9 @@ export class MapEmbeddable extends Embeddable<MapEmbeddableInput, MapEmbeddableO
);
}
this._store.dispatch(replaceLayerList(this._layerList));
this._store.dispatch<any>(replaceLayerList(this._layerList));
if (this.input.hiddenLayers) {
this._store.dispatch(setHiddenLayers(this.input.hiddenLayers));
this._store.dispatch<any>(setHiddenLayers(this.input.hiddenLayers));
}
this._dispatchSetQuery(this.input);
this._dispatchSetRefreshConfig(this.input);
@ -248,9 +249,9 @@ export class MapEmbeddable extends Embeddable<MapEmbeddableInput, MapEmbeddableO
});
}
async setLayerList(layerList: unknown[]) {
async setLayerList(layerList: LayerDescriptor[]) {
this._layerList = layerList;
return await this._store.dispatch(replaceLayerList(this._layerList));
return await this._store.dispatch<any>(replaceLayerList(this._layerList));
}
addFilters = (filters: Filter[]) => {

View file

@ -15,6 +15,7 @@ import {
} from '../../../../../src/plugins/embeddable/public';
import '../index.scss';
import { createMapPath, MAP_SAVED_OBJECT_TYPE, APP_ICON } from '../../common/constants';
import { LayerDescriptor } from '../../common/descriptor_types';
import { MapStore, MapStoreState } from '../reducers/store';
import { MapEmbeddableConfig, MapEmbeddableInput } from './types';
import { MapEmbeddableOutput } from './map_embeddable';
@ -38,9 +39,12 @@ let getIndexPatternService: () => {
let getHttp: () => any;
let getMapsCapabilities: () => any;
let createMapStore: () => MapStore;
let addLayerWithoutDataSync: (layerDescriptor: unknown) => AnyAction;
let addLayerWithoutDataSync: (layerDescriptor: LayerDescriptor) => AnyAction;
let getQueryableUniqueIndexPatternIds: (state: MapStoreState) => string[];
let getInitialLayers: (layerListJSON?: string, initialLayers?: unknown[]) => unknown[];
let getInitialLayers: (
layerListJSON?: string,
initialLayers?: LayerDescriptor[]
) => LayerDescriptor[];
let mergeInputWithSavedMap: any;
async function waitForMapDependencies(): Promise<boolean> {
@ -94,12 +98,12 @@ export class MapEmbeddableFactory implements EmbeddableFactoryDefinition {
});
}
async _getIndexPatterns(layerList: unknown[]): Promise<IIndexPattern[]> {
async _getIndexPatterns(layerList: LayerDescriptor[]): Promise<IIndexPattern[]> {
// Need to extract layerList from store to get queryable index pattern ids
const store = createMapStore();
let queryableIndexPatternIds: string[];
try {
layerList.forEach((layerDescriptor: unknown) => {
layerList.forEach((layerDescriptor: LayerDescriptor) => {
store.dispatch(addLayerWithoutDataSync(layerDescriptor));
});
queryableIndexPatternIds = getQueryableUniqueIndexPatternIds(store.getState());

View file

@ -9,14 +9,14 @@ import { MapSettings } from '../reducers/map';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { EmbeddableInput } from '../../../../../src/plugins/embeddable/public/lib/embeddables';
import { Filter, Query, RefreshInterval, TimeRange } from '../../../../../src/plugins/data/common';
import { MapCenterAndZoom } from '../../common/descriptor_types';
import { LayerDescriptor, MapCenterAndZoom } from '../../common/descriptor_types';
export interface MapEmbeddableConfig {
editUrl?: string;
indexPatterns: IIndexPattern[];
editable: boolean;
title?: string;
layerList: unknown[];
layerList: LayerDescriptor[];
settings?: MapSettings;
}

View file

@ -300,7 +300,7 @@ export const getLayerList = createSelector(
}
);
export function getLayerById(layerId: string, state: MapStoreState): ILayer | undefined {
export function getLayerById(layerId: string | null, state: MapStoreState): ILayer | undefined {
return getLayerList(state).find((layer) => {
return layerId === layer.getId();
});

View file

@ -109,6 +109,7 @@ export const createEmbeddable = async (
if (!isErrorEmbeddable(embeddableObject)) {
embeddableObject.setRenderTooltipContent(renderTooltipContent);
// @ts-ignore
await embeddableObject.setLayerList(getLayerList(indexPatterns));
}