[Maps] move map embeddable display properties to map settings (#86395)

* [Maps] move map embeddable display properties to map settings

* update uptime EmbeddedMap

* tslint

* more cleanup

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Nathan Reese 2021-01-11 16:18:01 -07:00 committed by GitHub
parent 1e7c3f88ec
commit ddf1b67559
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 36 additions and 303 deletions

View file

@ -38,11 +38,6 @@ export const SET_OPEN_TOOLTIPS = 'SET_OPEN_TOOLTIPS';
export const UPDATE_DRAW_STATE = 'UPDATE_DRAW_STATE';
export const SET_SCROLL_ZOOM = 'SET_SCROLL_ZOOM';
export const SET_MAP_INIT_ERROR = 'SET_MAP_INIT_ERROR';
export const SET_INTERACTIVE = 'SET_INTERACTIVE';
export const DISABLE_TOOLTIP_CONTROL = 'DISABLE_TOOLTIP_CONTROL';
export const HIDE_TOOLBAR_OVERLAY = 'HIDE_TOOLBAR_OVERLAY';
export const HIDE_LAYER_CONTROL = 'HIDE_LAYER_CONTROL';
export const HIDE_VIEW_CONTROL = 'HIDE_VIEW_CONTROL';
export const SET_WAITING_FOR_READY_HIDDEN_LAYERS = 'SET_WAITING_FOR_READY_HIDDEN_LAYERS';
export const SET_MAP_SETTINGS = 'SET_MAP_SETTINGS';
export const ROLLBACK_MAP_SETTINGS = 'ROLLBACK_MAP_SETTINGS';

View file

@ -24,16 +24,11 @@ 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,
@ -73,7 +68,7 @@ export function setMapInitError(errorMessage: string) {
};
}
export function setMapSettings(settings: MapSettings) {
export function setMapSettings(settings: Partial<MapSettings>) {
return {
type: SET_MAP_SETTINGS,
settings,
@ -316,22 +311,3 @@ export function updateDrawState(drawState: DrawState | null) {
});
};
}
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

@ -16,7 +16,6 @@ import {
getMapInitError,
getMapSettings,
getQueryableUniqueIndexPatternIds,
isToolbarOverlayHidden,
} from '../../selectors/map_selectors';
import { MapStoreState } from '../../reducers/store';
import { getCoreChrome } from '../../kibana_services';
@ -29,8 +28,7 @@ function mapStateToProps(state: MapStoreState) {
refreshConfig: getRefreshConfig(state),
mapInitError: getMapInitError(state),
indexPatternIds: getQueryableUniqueIndexPatternIds(state),
hideToolbarOverlay: isToolbarOverlayHidden(state),
backgroundColor: getMapSettings(state).backgroundColor,
settings: getMapSettings(state),
};
}

View file

@ -25,6 +25,7 @@ import { getIndexPatternsFromIds } from '../../index_pattern_util';
import { ES_GEO_FIELD_TYPE, RawValue } from '../../../common/constants';
import { indexPatterns as indexPatternsUtils } from '../../../../../../src/plugins/data/public';
import { FLYOUT_STATE } from '../../reducers/ui';
import { MapSettings } from '../../reducers/map';
import { MapSettingsPanel } from '../map_settings_panel';
import { registerLayerWizards } from '../../classes/layers/load_layer_wizards';
import { RenderToolTipContent } from '../../classes/tooltips/tooltip_property';
@ -36,7 +37,6 @@ const RENDER_COMPLETE_EVENT = 'renderComplete';
interface Props {
addFilters: ((filters: Filter[]) => Promise<void>) | null;
backgroundColor: string;
getFilterActions?: () => Promise<Action[]>;
getActionContext?: () => ActionExecutionContext;
onSingleValueTrigger?: (actionId: string, key: string, value: RawValue) => void;
@ -44,7 +44,6 @@ interface Props {
cancelAllInFlightRequests: () => void;
exitFullScreen: () => void;
flyoutDisplay: FLYOUT_STATE;
hideToolbarOverlay: boolean;
isFullScreen: boolean;
indexPatternIds: string[];
mapInitError: string | null | undefined;
@ -53,6 +52,7 @@ interface Props {
triggerRefreshTimer: () => void;
title?: string;
description?: string;
settings: MapSettings;
}
interface State {
@ -245,7 +245,7 @@ export class MapContainer extends Component<Props, State> {
>
<EuiFlexItem
className="mapMapWrapper"
style={{ backgroundColor: this.props.backgroundColor }}
style={{ backgroundColor: this.props.settings.backgroundColor }}
>
<MBMap
addFilters={addFilters}
@ -255,7 +255,7 @@ export class MapContainer extends Component<Props, State> {
geoFields={this.state.geoFields}
renderTooltipContent={renderTooltipContent}
/>
{!this.props.hideToolbarOverlay && (
{!this.props.settings.hideToolbarOverlay && (
<ToolbarOverlay
addFilters={addFilters}
geoFields={this.state.geoFields}

View file

@ -23,9 +23,6 @@ import {
getMapReady,
getGoto,
getScrollZoom,
isInteractiveDisabled,
isTooltipControlDisabled,
isViewControlHidden,
getSpatialFiltersLayer,
getMapSettings,
} from '../../selectors/map_selectors';
@ -41,9 +38,6 @@ function mapStateToProps(state: MapStoreState) {
goto: getGoto(state),
inspectorAdapters: getInspectorAdapters(state),
scrollZoom: getScrollZoom(state),
disableInteractive: isInteractiveDisabled(state),
disableTooltipControl: isTooltipControlDisabled(state),
hideViewControl: isViewControlHidden(state),
};
}

View file

@ -56,9 +56,6 @@ interface Props {
goto?: Goto | null;
inspectorAdapters: Adapters;
scrollZoom: boolean;
disableInteractive: boolean;
disableTooltipControl: boolean;
hideViewControl: boolean;
extentChanged: (mapExtentState: MapExtentState) => void;
onMapReady: (mapExtentState: MapExtentState) => void;
onMapDestroyed: () => void;
@ -181,7 +178,7 @@ export class MBMap extends Component<Props, State> {
style: mbStyle,
scrollZoom: this.props.scrollZoom,
preserveDrawingBuffer: getPreserveDrawingBuffer(),
interactive: !this.props.disableInteractive,
interactive: !this.props.settings.disableInteractive,
maxZoom: this.props.settings.maxZoom,
minZoom: this.props.settings.minZoom,
};
@ -197,7 +194,7 @@ export class MBMap extends Component<Props, State> {
const mbMap = new mapboxgl.Map(options);
mbMap.dragRotate.disable();
mbMap.touchZoomRotate.disableRotation();
if (!this.props.disableInteractive) {
if (!this.props.settings.disableInteractive) {
mbMap.addControl(new mapboxgl.NavigationControl({ showCompass: false }), 'top-left');
}
@ -260,7 +257,7 @@ export class MBMap extends Component<Props, State> {
}, 100)
);
// Attach event only if view control is visible, which shows lat/lon
if (!this.props.hideViewControl) {
if (!this.props.settings.hideViewControl) {
const throttledSetMouseCoordinates = _.throttle((e: MapMouseEvent) => {
this.props.setMouseCoordinates({
lat: e.lngLat.lat,
@ -386,7 +383,7 @@ export class MBMap extends Component<Props, State> {
let tooltipControl;
if (this.state.mbMap) {
drawControl = <DrawControl mbMap={this.state.mbMap} addFilters={this.props.addFilters} />;
tooltipControl = !this.props.disableTooltipControl ? (
tooltipControl = !this.props.settings.disableTooltipControl ? (
<TooltipControl
mbMap={this.state.mbMap}
addFilters={this.props.addFilters}

View file

@ -7,12 +7,11 @@
import { connect } from 'react-redux';
import { WidgetOverlay } from './widget_overlay';
import { isLayerControlHidden, isViewControlHidden } from '../../selectors/map_selectors';
import { getMapSettings } from '../../selectors/map_selectors';
function mapStateToProps(state = {}) {
return {
hideLayerControl: isLayerControlHidden(state),
hideViewControl: isViewControlHidden(state),
settings: getMapSettings(state),
};
}

View file

@ -10,7 +10,7 @@ import { LayerControl } from './layer_control';
import { ViewControl } from './view_control';
import { AttributionControl } from './attribution_control';
export function WidgetOverlay({ hideLayerControl, hideViewControl }) {
export function WidgetOverlay({ settings }) {
return (
<EuiFlexGroup
className="mapWidgetOverlay"
@ -20,9 +20,9 @@ export function WidgetOverlay({ hideLayerControl, hideViewControl }) {
gutterSize="s"
>
<EuiFlexItem className="mapWidgetOverlay__layerWrapper">
{!hideLayerControl && <LayerControl />}
{!settings.hideLayerControl && <LayerControl />}
</EuiFlexItem>
<EuiFlexItem grow={false}>{!hideViewControl && <ViewControl />}</EuiFlexItem>
<EuiFlexItem grow={false}>{!settings.hideViewControl && <ViewControl />}</EuiFlexItem>
<EuiFlexItem grow={false}>
<AttributionControl />
</EuiFlexItem>

View file

@ -1,143 +0,0 @@
### Map specific `input` parameters
- **hideFilterActions:** (Boolean) Set to true to hide all filtering controls.
- **isLayerTOCOpen:** (Boolean) Set to false to render map with legend in collapsed state.
- **openTOCDetails:** (Array of Strings) Array of layer ids. Add layer id to show layer details on initial render.
- **mapCenter:** ({lat, lon, zoom }) Provide mapCenter to customize initial map location.
- **disableInteractive:** (Boolean) Will disable map interactions, panning, zooming in the map.
- **disableTooltipControl:** (Boolean) Will disable tooltip which shows relevant information on hover, like Continent name etc
- **hideToolbarOverlay:** (Boolean) Will disable toolbar, which can be used to navigate to coordinate by entering lat/long and zoom values.
- **hideLayerControl:** (Boolean) Will hide useful layer control, which can be used to hide/show a layer to get a refined view of the map.
- **hideViewControl:** (Boolean) Will hide view control at bottom right of the map, which shows lat/lon values based on mouse hover in the map, this is useful to get coordinate value from a particular point in map.
- **hiddenLayers:** (Array of Strings) Array of layer ids that should be hidden. Any other layers will be set to visible regardless of their value in the layerList used to initialize the embeddable
### Creating a Map embeddable from saved object
```
const factory = new MapEmbeddableFactory();
const input = {
hideFilterActions: true,
isLayerTOCOpen: false,
openTOCDetails: ['tfi3f', 'edh66'],
mapCenter: { lat: 0.0, lon: 0.0, zoom: 7 }
}
const mapEmbeddable = await factory.createFromSavedObject(
'de71f4f0-1902-11e9-919b-ffe5949a18d2',
input,
parent
);
```
### Creating a Map embeddable from state
```
const factory = new MapEmbeddableFactory();
const input = {
hideFilterActions: true,
isLayerTOCOpen: false,
openTOCDetails: ['tfi3f', 'edh66'],
mapCenter: { lat: 0.0, lon: 0.0, zoom: 7 }
}
const mapEmbeddable = await factory.create(input, parent);
// where layerList is same as saved object layerListJSON property (unstringified))
mapEmbeddable.setLayerList([]);
```
#### Customize tooltip
```
/**
* Render custom tooltip content
*
* @param {function} addFilters
* @param {function} closeTooltip
* @param {Array} features - Vector features at tooltip location.
* @param {boolean} isLocked
* @param {function} getLayerName - Get layer name. Call with (layerId). Returns Promise.
* @param {function} loadFeatureProperties - Loads feature properties. Call with ({ layerId, featureId }). Returns Promise.
* @param {function} loadFeatureGeometry - Loads feature geometry. Call with ({ layerId, featureId }). Returns geojson geometry object { type, coordinates }.
*
* @return {Component} A React Component.
*/
const renderTooltipContent = ({ addFilters, closeTooltip, features, isLocked, loadFeatureProperties}) => {
return <div>Custom tooltip content</div>;
}
const mapEmbeddable = await factory.create(input, parent)
mapEmbeddable.setLayerList(layerList);
mapEmbeddable.setRenderTooltipContent(renderTooltipContent);
```
#### Event handlers
```
const eventHandlers = {
onDataLoad: (layerId: string, dataId: string) => {
// take action on data load
},
onDataLoadEnd: (layerId: string, dataId: string, resultMeta: object) => {
// take action on data load end
},
onDataLoadError: (layerId: string, dataId: string, errorMessage: string) => {
// take action on data load error
},
}
const mapEmbeddable = await factory.create(input, parent);
mapEmbeddable.setLayerList(layerList);
mapEmbeddable.setRenderTooltipContent(renderTooltipContent);
mapEmbeddable.setEventHandlers(eventHandlers);
```
#### Passing in geospatial data
You can pass geospatial data into the Map embeddable by configuring the layerList parameter with a layer with `GEOJSON_FILE` source.
Geojson sources will not update unless you modify `__featureCollection` property by calling the `setLayerList` method.
```
const factory = new MapEmbeddableFactory();
const input = {
hideFilterActions: true,
isLayerTOCOpen: false,
openTOCDetails: ['tfi3f', 'edh66'],
mapCenter: { lat: 0.0, lon: 0.0, zoom: 7 }
}
const mapEmbeddable = await factory.create(input, parent);
mapEmbeddable.setLayerList([
{
'id': 'gaxya',
'label': 'My geospatial data',
'minZoom': 0,
'maxZoom': 24,
'alpha': 1,
'sourceDescriptor': {
'id': 'b7486',
'type': 'GEOJSON_FILE',
'__featureCollection': {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[35, 35], [45, 45], [45, 35], [35, 35]
]
]
},
"properties": {
"name": "null island",
"another_prop": "something else interesting"
}
}
]
}
},
'visible': true,
'style': {
'type': 'VECTOR',
'properties': {}
},
'type': 'VECTOR'
}
]);
```

View file

@ -31,11 +31,6 @@ import {
setQuery,
setRefreshConfig,
disableScrollZoom,
disableInteractive,
disableTooltipControl,
hideToolbarOverlay,
hideLayerControl,
hideViewControl,
setReadOnly,
} from '../actions';
import { getIsLayerTOCOpen, getOpenTOCDetails } from '../selectors/ui_selectors';
@ -129,25 +124,6 @@ export class MapEmbeddable
store.dispatch(setReadOnly(true));
store.dispatch(disableScrollZoom());
if (_.has(this.input, 'disableInteractive') && this.input.disableInteractive) {
store.dispatch(disableInteractive());
}
if (_.has(this.input, 'disableTooltipControl') && this.input.disableTooltipControl) {
store.dispatch(disableTooltipControl());
}
if (_.has(this.input, 'hideToolbarOverlay') && this.input.hideToolbarOverlay) {
store.dispatch(hideToolbarOverlay());
}
if (_.has(this.input, 'hideLayerControl') && this.input.hideLayerControl) {
store.dispatch(hideLayerControl());
}
if (_.has(this.input, 'hideViewControl') && this.input.hideViewControl) {
store.dispatch(hideViewControl());
}
this._dispatchSetQuery({
query: this.input.query,
timeRange: this.input.timeRange,

View file

@ -13,6 +13,7 @@ import {
import { RefreshInterval, Query, Filter, TimeRange } from '../../../../../src/plugins/data/common';
import { MapCenterAndZoom } from '../../common/descriptor_types';
import { MapSavedObjectAttributes } from '../../common/map_saved_object_type';
import { MapSettings } from '../reducers/map';
export interface MapEmbeddableConfig {
editable: boolean;
@ -22,12 +23,8 @@ interface MapEmbeddableState {
refreshConfig?: RefreshInterval;
isLayerTOCOpen?: boolean;
openTOCDetails?: string[];
disableTooltipControl?: boolean;
disableInteractive?: boolean;
hideToolbarOverlay?: boolean;
hideLayerControl?: boolean;
hideViewControl?: boolean;
mapCenter?: MapCenterAndZoom;
mapSettings?: Partial<MapSettings>;
hiddenLayers?: string[];
hideFilterActions?: boolean;
filters?: Filter[];

View file

@ -12,6 +12,11 @@ export function getDefaultMapSettings(): MapSettings {
return {
autoFitToDataBounds: false,
backgroundColor: euiThemeVars.euiColorEmptyShade,
disableInteractive: false,
disableTooltipControl: false,
hideToolbarOverlay: false,
hideLayerControl: false,
hideViewControl: false,
initialLocation: INITIAL_LOCATION.LAST_SAVED_LOCATION,
fixedLocation: { lat: 0, lon: 0, zoom: 2 },
browserLocation: { zoom: 2 },

View file

@ -34,16 +34,16 @@ export type MapContext = {
refreshConfig?: MapRefreshConfig;
refreshTimerLastTriggeredAt?: string;
drawState?: DrawState;
disableInteractive: boolean;
disableTooltipControl: boolean;
hideToolbarOverlay: boolean;
hideLayerControl: boolean;
hideViewControl: boolean;
};
export type MapSettings = {
autoFitToDataBounds: boolean;
backgroundColor: string;
disableInteractive: boolean;
disableTooltipControl: boolean;
hideToolbarOverlay: boolean;
hideLayerControl: boolean;
hideViewControl: boolean;
initialLocation: INITIAL_LOCATION;
fixedLocation: {
lat: number;

View file

@ -39,11 +39,6 @@ import {
SET_SCROLL_ZOOM,
SET_MAP_INIT_ERROR,
UPDATE_DRAW_STATE,
SET_INTERACTIVE,
DISABLE_TOOLTIP_CONTROL,
HIDE_TOOLBAR_OVERLAY,
HIDE_LAYER_CONTROL,
HIDE_VIEW_CONTROL,
SET_WAITING_FOR_READY_HIDDEN_LAYERS,
SET_MAP_SETTINGS,
ROLLBACK_MAP_SETTINGS,
@ -118,11 +113,6 @@ export const DEFAULT_MAP_STATE = {
refreshConfig: null,
refreshTimerLastTriggeredAt: null,
drawState: null,
disableInteractive: false,
disableTooltipControl: false,
hideToolbarOverlay: false,
hideLayerControl: false,
hideViewControl: false,
},
selectedLayerId: null,
layerList: [],
@ -355,46 +345,6 @@ export function map(state = DEFAULT_MAP_STATE, action) {
...state,
mapInitError: action.errorMessage,
};
case SET_INTERACTIVE:
return {
...state,
mapState: {
...state.mapState,
disableInteractive: action.disableInteractive,
},
};
case DISABLE_TOOLTIP_CONTROL:
return {
...state,
mapState: {
...state.mapState,
disableTooltipControl: action.disableTooltipControl,
},
};
case HIDE_TOOLBAR_OVERLAY:
return {
...state,
mapState: {
...state.mapState,
hideToolbarOverlay: action.hideToolbarOverlay,
},
};
case HIDE_LAYER_CONTROL:
return {
...state,
mapState: {
...state.mapState,
hideLayerControl: action.hideLayerControl,
},
};
case HIDE_VIEW_CONTROL:
return {
...state,
mapState: {
...state.mapState,
hideViewControl: action.hideViewControl,
},
};
case SET_WAITING_FOR_READY_HIDDEN_LAYERS:
return {
...state,

View file

@ -102,7 +102,9 @@ export class SavedMap {
}
}
if (this._attributes?.mapStateJSON) {
if (this._mapEmbeddableInput && this._mapEmbeddableInput.mapSettings !== undefined) {
this._store.dispatch(setMapSettings(this._mapEmbeddableInput.mapSettings));
} else if (this._attributes?.mapStateJSON) {
const mapState = JSON.parse(this._attributes.mapStateJSON);
if (mapState.settings) {
this._store.dispatch(setMapSettings(mapState.settings));

View file

@ -150,21 +150,6 @@ export const getWaitingForMapReadyLayerListRaw = ({ map }: MapStoreState): Layer
export const getScrollZoom = ({ map }: MapStoreState): boolean => map.mapState.scrollZoom;
export const isInteractiveDisabled = ({ map }: MapStoreState): boolean =>
map.mapState.disableInteractive;
export const isTooltipControlDisabled = ({ map }: MapStoreState): boolean =>
map.mapState.disableTooltipControl;
export const isToolbarOverlayHidden = ({ map }: MapStoreState): boolean =>
map.mapState.hideToolbarOverlay;
export const isLayerControlHidden = ({ map }: MapStoreState): boolean =>
map.mapState.hideLayerControl;
export const isViewControlHidden = ({ map }: MapStoreState): boolean =>
map.mapState.hideViewControl;
export const getMapExtent = ({ map }: MapStoreState): MapExtent | undefined => map.mapState.extent;
export const getMapBuffer = ({ map }: MapStoreState): MapExtent | undefined => map.mapState.buffer;

View file

@ -83,10 +83,12 @@ export const EmbeddedMap = React.memo(({ upPoints, downPoints }: EmbeddedMapProp
lat: 20,
zoom: 0,
},
disableInteractive: true,
hideToolbarOverlay: true,
hideLayerControl: true,
hideViewControl: true,
mapSettings: {
disableInteractive: true,
hideToolbarOverlay: true,
hideLayerControl: true,
hideViewControl: true,
},
};
const renderTooltipContent = ({