Skip to content

Commit

Permalink
[Maps] allow simultaneous opening of multiple tooltips (#57226)
Browse files Browse the repository at this point in the history
* split TooltipPopover from TooltipContent

* display multiple tooltips

* hack to fix spacing

* hover tooltip

* fix jest tests for new props

* update snapshots

* simplify jest tests

* avoid opening up multiple tooltips in same location

* remove duplicated code

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
  • Loading branch information
nreese and elasticmachine committed Feb 13, 2020
1 parent 05bf3ee commit 6b62f5a
Show file tree
Hide file tree
Showing 11 changed files with 733 additions and 514 deletions.
121 changes: 88 additions & 33 deletions x-pack/legacy/plugins/maps/public/actions/map_actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
* you may not use this file except in compliance with the Elastic License.
*/

import _ from 'lodash';
import turf from 'turf';
import turfBooleanContains from '@turf/boolean-contains';
import uuid from 'uuid/v4';
import {
getLayerList,
getLayerListRaw,
Expand All @@ -14,7 +16,7 @@ import {
getMapReady,
getWaitingForMapReadyLayerListRaw,
getTransientLayerId,
getTooltipState,
getOpenTooltips,
getQuery,
} from '../selectors/map_selectors';
import { FLYOUT_STATE } from '../reducers/ui';
Expand Down Expand Up @@ -63,7 +65,7 @@ export const CLEAR_GOTO = 'CLEAR_GOTO';
export const TRACK_CURRENT_LAYER_STATE = 'TRACK_CURRENT_LAYER_STATE';
export const ROLLBACK_TO_TRACKED_LAYER_STATE = 'ROLLBACK_TO_TRACKED_LAYER_STATE';
export const REMOVE_TRACKED_LAYER_STATE = 'REMOVE_TRACKED_LAYER_STATE';
export const SET_TOOLTIP_STATE = 'SET_TOOLTIP_STATE';
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';
Expand Down Expand Up @@ -221,34 +223,36 @@ function setLayerDataLoadErrorStatus(layerId, errorMessage) {

export function cleanTooltipStateForLayer(layerId, layerFeatures = []) {
return (dispatch, getState) => {
const tooltipState = getTooltipState(getState());

if (!tooltipState) {
return;
}

const nextTooltipFeatures = tooltipState.features.filter(tooltipFeature => {
if (tooltipFeature.layerId !== layerId) {
// feature from another layer, keep it
return true;
}

// Keep feature if it is still in layer
return layerFeatures.some(layerFeature => {
return layerFeature.properties[FEATURE_ID_PROPERTY_NAME] === tooltipFeature.id;
let featuresRemoved = false;
const openTooltips = getOpenTooltips(getState())
.map(tooltipState => {
const nextFeatures = tooltipState.features.filter(tooltipFeature => {
if (tooltipFeature.layerId !== layerId) {
// feature from another layer, keep it
return true;
}

// Keep feature if it is still in layer
return layerFeatures.some(layerFeature => {
return layerFeature.properties[FEATURE_ID_PROPERTY_NAME] === tooltipFeature.id;
});
});

if (tooltipState.features.length !== nextFeatures.length) {
featuresRemoved = true;
}

return { ...tooltipState, features: nextFeatures };
})
.filter(tooltipState => {
return tooltipState.features.length > 0;
});
});

if (tooltipState.features.length === nextTooltipFeatures.length) {
// no features got removed, nothing to update
return;
}

if (nextTooltipFeatures.length === 0) {
// all features removed from tooltip, close tooltip
dispatch(setTooltipState(null));
} else {
dispatch(setTooltipState({ ...tooltipState, features: nextTooltipFeatures }));
if (featuresRemoved) {
dispatch({
type: SET_OPEN_TOOLTIPS,
openTooltips,
});
}
};
}
Expand Down Expand Up @@ -412,10 +416,61 @@ export function mapExtentChanged(newMapConstants) {
};
}

export function setTooltipState(tooltipState) {
export function closeOnClickTooltip(tooltipId) {
return (dispatch, getState) => {
dispatch({
type: SET_OPEN_TOOLTIPS,
openTooltips: getOpenTooltips(getState()).filter(({ id }) => {
return tooltipId !== id;
}),
});
};
}

export function openOnClickTooltip(tooltipState) {
return (dispatch, getState) => {
const openTooltips = getOpenTooltips(getState()).filter(({ features, location, isLocked }) => {
return (
isLocked &&
!_.isEqual(location, tooltipState.location) &&
!_.isEqual(features, tooltipState.features)
);
});

openTooltips.push({
...tooltipState,
isLocked: true,
id: uuid(),
});

dispatch({
type: SET_OPEN_TOOLTIPS,
openTooltips,
});
};
}

export function closeOnHoverTooltip() {
return (dispatch, getState) => {
if (getOpenTooltips(getState()).length) {
dispatch({
type: SET_OPEN_TOOLTIPS,
openTooltips: [],
});
}
};
}

export function openOnHoverTooltip(tooltipState) {
return {
type: 'SET_TOOLTIP_STATE',
tooltipState: tooltipState,
type: SET_OPEN_TOOLTIPS,
openTooltips: [
{
...tooltipState,
isLocked: false,
id: uuid(),
},
],
};
}

Expand Down Expand Up @@ -826,9 +881,9 @@ export function setJoinsForLayer(layer, joins) {
}

export function updateDrawState(drawState) {
return async dispatch => {
return dispatch => {
if (drawState !== null) {
await dispatch(setTooltipState(null)); //tooltips just get in the way
dispatch({ type: SET_OPEN_TOOLTIPS, openTooltips: [] }); // tooltips just get in the way
}
dispatch({
type: UPDATE_DRAW_STATE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import {
setMapInitError,
} from '../../../actions/map_actions';
import {
getTooltipState,
getLayerList,
getMapReady,
getGoto,
Expand All @@ -33,7 +32,6 @@ function mapStateToProps(state = {}) {
layerList: getLayerList(state),
goto: getGoto(state),
inspectorAdapters: getInspectorAdapters(state),
tooltipState: getTooltipState(state),
scrollZoom: getScrollZoom(state),
disableInteractive: isInteractiveDisabled(state),
disableTooltipControl: isTooltipControlDisabled(state),
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 6b62f5a

Please sign in to comment.