mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Maps] Show minusInCircle icon when layer has no data (#36457)
* [Maps] Show minusInCircle icon when layer has no data * rename getTooltipContent so its less ambigiuos * Update x-pack/plugins/maps/public/shared/layers/layer.js Co-Authored-By: gchaps <33642766+gchaps@users.noreply.github.com> * review feedback
This commit is contained in:
parent
ef8d7ea905
commit
2791becd27
9 changed files with 150 additions and 557 deletions
|
@ -6,6 +6,7 @@ exports[`LayerTocActions is rendered 1`] = `
|
|||
anchorPosition="leftUp"
|
||||
button={
|
||||
<EuiToolTip
|
||||
content="simulated tooltip content at zoom: 0"
|
||||
delay="regular"
|
||||
position="top"
|
||||
title="layer 1"
|
||||
|
@ -23,9 +24,9 @@ exports[`LayerTocActions is rendered 1`] = `
|
|||
<span
|
||||
className="mapTocEntry__layerNameIcon"
|
||||
>
|
||||
<div>
|
||||
icon mock
|
||||
</div>
|
||||
<span>
|
||||
mockIcon
|
||||
</span>
|
||||
</span>
|
||||
layer 1
|
||||
</EuiButtonEmpty>
|
||||
|
@ -101,6 +102,7 @@ exports[`LayerTocActions should disable fit to data when supportsFitToBounds is
|
|||
anchorPosition="leftUp"
|
||||
button={
|
||||
<EuiToolTip
|
||||
content="simulated tooltip content at zoom: 0"
|
||||
delay="regular"
|
||||
position="top"
|
||||
title="layer 1"
|
||||
|
@ -118,9 +120,9 @@ exports[`LayerTocActions should disable fit to data when supportsFitToBounds is
|
|||
<span
|
||||
className="mapTocEntry__layerNameIcon"
|
||||
>
|
||||
<div>
|
||||
icon mock
|
||||
</div>
|
||||
<span>
|
||||
mockIcon
|
||||
</span>
|
||||
</span>
|
||||
layer 1
|
||||
</EuiButtonEmpty>
|
||||
|
@ -190,107 +192,13 @@ exports[`LayerTocActions should disable fit to data when supportsFitToBounds is
|
|||
</EuiPopover>
|
||||
`;
|
||||
|
||||
exports[`LayerTocActions should display spinner when layer is loading 1`] = `
|
||||
<EuiPopover
|
||||
anchorClassName="mapLayTocActions__popoverAnchor"
|
||||
anchorPosition="leftUp"
|
||||
button={
|
||||
<EuiToolTip
|
||||
delay="regular"
|
||||
position="top"
|
||||
title="layer 1"
|
||||
>
|
||||
<EuiButtonEmpty
|
||||
className="mapTocEntry__layerName eui-textLeft"
|
||||
color="text"
|
||||
data-test-subj="layerTocActionsPanelToggleButtonlayer1"
|
||||
flush="left"
|
||||
iconSide="left"
|
||||
onClick={[Function]}
|
||||
size="xs"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
className="mapTocEntry__layerNameIcon"
|
||||
>
|
||||
<EuiLoadingSpinner
|
||||
size="m"
|
||||
/>
|
||||
</span>
|
||||
layer 1
|
||||
</EuiButtonEmpty>
|
||||
</EuiToolTip>
|
||||
}
|
||||
className="mapLayTocActions"
|
||||
closePopover={[Function]}
|
||||
hasArrow={true}
|
||||
id="contextMenu"
|
||||
isOpen={false}
|
||||
ownFocus={false}
|
||||
panelPaddingSize="none"
|
||||
withTitle={true}
|
||||
>
|
||||
<EuiContextMenu
|
||||
data-test-subj="layerTocActionsPanellayer1"
|
||||
initialPanelId={0}
|
||||
panels={
|
||||
Array [
|
||||
Object {
|
||||
"id": 0,
|
||||
"items": Array [
|
||||
Object {
|
||||
"data-test-subj": "fitToBoundsButton",
|
||||
"disabled": false,
|
||||
"icon": <EuiIcon
|
||||
size="m"
|
||||
type="search"
|
||||
/>,
|
||||
"name": "Fit to data",
|
||||
"onClick": [Function],
|
||||
"toolTipContent": null,
|
||||
},
|
||||
Object {
|
||||
"data-test-subj": "layerVisibilityToggleButton",
|
||||
"icon": <EuiIcon
|
||||
size="m"
|
||||
type="eye"
|
||||
/>,
|
||||
"name": "Hide layer",
|
||||
"onClick": [Function],
|
||||
},
|
||||
Object {
|
||||
"data-test-subj": "editLayerButton",
|
||||
"icon": <EuiIcon
|
||||
size="m"
|
||||
type="pencil"
|
||||
/>,
|
||||
"name": "Edit layer",
|
||||
"onClick": [Function],
|
||||
},
|
||||
Object {
|
||||
"data-test-subj": "cloneLayerButton",
|
||||
"icon": <EuiIcon
|
||||
size="m"
|
||||
type="copy"
|
||||
/>,
|
||||
"name": "Clone layer",
|
||||
"onClick": [Function],
|
||||
},
|
||||
],
|
||||
"title": "Layer actions",
|
||||
},
|
||||
]
|
||||
}
|
||||
/>
|
||||
</EuiPopover>
|
||||
`;
|
||||
|
||||
exports[`LayerTocActions should not show edit actions in read only mode 1`] = `
|
||||
<EuiPopover
|
||||
anchorClassName="mapLayTocActions__popoverAnchor"
|
||||
anchorPosition="leftUp"
|
||||
button={
|
||||
<EuiToolTip
|
||||
content="simulated tooltip content at zoom: 0"
|
||||
delay="regular"
|
||||
position="top"
|
||||
title="layer 1"
|
||||
|
@ -308,9 +216,9 @@ exports[`LayerTocActions should not show edit actions in read only mode 1`] = `
|
|||
<span
|
||||
className="mapTocEntry__layerNameIcon"
|
||||
>
|
||||
<div>
|
||||
icon mock
|
||||
</div>
|
||||
<span>
|
||||
mockIcon
|
||||
</span>
|
||||
</span>
|
||||
layer 1
|
||||
</EuiButtonEmpty>
|
||||
|
@ -361,296 +269,3 @@ exports[`LayerTocActions should not show edit actions in read only mode 1`] = `
|
|||
/>
|
||||
</EuiPopover>
|
||||
`;
|
||||
|
||||
exports[`LayerTocActions should show visible toggle when layer is not visible 1`] = `
|
||||
<EuiPopover
|
||||
anchorClassName="mapLayTocActions__popoverAnchor"
|
||||
anchorPosition="leftUp"
|
||||
button={
|
||||
<EuiToolTip
|
||||
content="Layer is hidden."
|
||||
delay="regular"
|
||||
position="top"
|
||||
title="layer 1"
|
||||
>
|
||||
<EuiButtonEmpty
|
||||
className="mapTocEntry__layerName eui-textLeft"
|
||||
color="text"
|
||||
data-test-subj="layerTocActionsPanelToggleButtonlayer1"
|
||||
flush="left"
|
||||
iconSide="left"
|
||||
onClick={[Function]}
|
||||
size="xs"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
className="mapTocEntry__layerNameIcon"
|
||||
>
|
||||
<EuiIcon
|
||||
size="m"
|
||||
type="eyeClosed"
|
||||
/>
|
||||
</span>
|
||||
layer 1
|
||||
</EuiButtonEmpty>
|
||||
</EuiToolTip>
|
||||
}
|
||||
className="mapLayTocActions"
|
||||
closePopover={[Function]}
|
||||
hasArrow={true}
|
||||
id="contextMenu"
|
||||
isOpen={false}
|
||||
ownFocus={false}
|
||||
panelPaddingSize="none"
|
||||
withTitle={true}
|
||||
>
|
||||
<EuiContextMenu
|
||||
data-test-subj="layerTocActionsPanellayer1"
|
||||
initialPanelId={0}
|
||||
panels={
|
||||
Array [
|
||||
Object {
|
||||
"id": 0,
|
||||
"items": Array [
|
||||
Object {
|
||||
"data-test-subj": "fitToBoundsButton",
|
||||
"disabled": false,
|
||||
"icon": <EuiIcon
|
||||
size="m"
|
||||
type="search"
|
||||
/>,
|
||||
"name": "Fit to data",
|
||||
"onClick": [Function],
|
||||
"toolTipContent": null,
|
||||
},
|
||||
Object {
|
||||
"data-test-subj": "layerVisibilityToggleButton",
|
||||
"icon": <EuiIcon
|
||||
size="m"
|
||||
type="eyeClosed"
|
||||
/>,
|
||||
"name": "Show layer",
|
||||
"onClick": [Function],
|
||||
},
|
||||
Object {
|
||||
"data-test-subj": "editLayerButton",
|
||||
"icon": <EuiIcon
|
||||
size="m"
|
||||
type="pencil"
|
||||
/>,
|
||||
"name": "Edit layer",
|
||||
"onClick": [Function],
|
||||
},
|
||||
Object {
|
||||
"data-test-subj": "cloneLayerButton",
|
||||
"icon": <EuiIcon
|
||||
size="m"
|
||||
type="copy"
|
||||
/>,
|
||||
"name": "Clone layer",
|
||||
"onClick": [Function],
|
||||
},
|
||||
],
|
||||
"title": "Layer actions",
|
||||
},
|
||||
]
|
||||
}
|
||||
/>
|
||||
</EuiPopover>
|
||||
`;
|
||||
|
||||
exports[`LayerTocActions should show warning when layer has errors 1`] = `
|
||||
<EuiPopover
|
||||
anchorClassName="mapLayTocActions__popoverAnchor"
|
||||
anchorPosition="leftUp"
|
||||
button={
|
||||
<EuiToolTip
|
||||
content="simulated layer error"
|
||||
delay="regular"
|
||||
position="top"
|
||||
title="layer 1"
|
||||
>
|
||||
<EuiButtonEmpty
|
||||
className="mapTocEntry__layerName eui-textLeft"
|
||||
color="text"
|
||||
data-test-subj="layerTocActionsPanelToggleButtonlayer1"
|
||||
flush="left"
|
||||
iconSide="left"
|
||||
onClick={[Function]}
|
||||
size="xs"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
className="mapTocEntry__layerNameIcon"
|
||||
>
|
||||
<EuiIcon
|
||||
aria-label="Load warning"
|
||||
color="warning"
|
||||
size="m"
|
||||
type="alert"
|
||||
/>
|
||||
</span>
|
||||
layer 1
|
||||
</EuiButtonEmpty>
|
||||
</EuiToolTip>
|
||||
}
|
||||
className="mapLayTocActions"
|
||||
closePopover={[Function]}
|
||||
hasArrow={true}
|
||||
id="contextMenu"
|
||||
isOpen={false}
|
||||
ownFocus={false}
|
||||
panelPaddingSize="none"
|
||||
withTitle={true}
|
||||
>
|
||||
<EuiContextMenu
|
||||
data-test-subj="layerTocActionsPanellayer1"
|
||||
initialPanelId={0}
|
||||
panels={
|
||||
Array [
|
||||
Object {
|
||||
"id": 0,
|
||||
"items": Array [
|
||||
Object {
|
||||
"data-test-subj": "fitToBoundsButton",
|
||||
"disabled": false,
|
||||
"icon": <EuiIcon
|
||||
size="m"
|
||||
type="search"
|
||||
/>,
|
||||
"name": "Fit to data",
|
||||
"onClick": [Function],
|
||||
"toolTipContent": null,
|
||||
},
|
||||
Object {
|
||||
"data-test-subj": "layerVisibilityToggleButton",
|
||||
"icon": <EuiIcon
|
||||
size="m"
|
||||
type="eye"
|
||||
/>,
|
||||
"name": "Hide layer",
|
||||
"onClick": [Function],
|
||||
},
|
||||
Object {
|
||||
"data-test-subj": "editLayerButton",
|
||||
"icon": <EuiIcon
|
||||
size="m"
|
||||
type="pencil"
|
||||
/>,
|
||||
"name": "Edit layer",
|
||||
"onClick": [Function],
|
||||
},
|
||||
Object {
|
||||
"data-test-subj": "cloneLayerButton",
|
||||
"icon": <EuiIcon
|
||||
size="m"
|
||||
type="copy"
|
||||
/>,
|
||||
"name": "Clone layer",
|
||||
"onClick": [Function],
|
||||
},
|
||||
],
|
||||
"title": "Layer actions",
|
||||
},
|
||||
]
|
||||
}
|
||||
/>
|
||||
</EuiPopover>
|
||||
`;
|
||||
|
||||
exports[`LayerTocActions should show when layer is not visible because zoom settings are outside of the current zoom level 1`] = `
|
||||
<EuiPopover
|
||||
anchorClassName="mapLayTocActions__popoverAnchor"
|
||||
anchorPosition="leftUp"
|
||||
button={
|
||||
<EuiToolTip
|
||||
content="Layer is visible between zoom levels 2 to 3."
|
||||
delay="regular"
|
||||
position="top"
|
||||
title="layer 1"
|
||||
>
|
||||
<EuiButtonEmpty
|
||||
className="mapTocEntry__layerName eui-textLeft"
|
||||
color="text"
|
||||
data-test-subj="layerTocActionsPanelToggleButtonlayer1"
|
||||
flush="left"
|
||||
iconSide="left"
|
||||
onClick={[Function]}
|
||||
size="xs"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
className="mapTocEntry__layerNameIcon"
|
||||
>
|
||||
<EuiIcon
|
||||
size="m"
|
||||
type="expand"
|
||||
/>
|
||||
</span>
|
||||
layer 1
|
||||
</EuiButtonEmpty>
|
||||
</EuiToolTip>
|
||||
}
|
||||
className="mapLayTocActions"
|
||||
closePopover={[Function]}
|
||||
hasArrow={true}
|
||||
id="contextMenu"
|
||||
isOpen={false}
|
||||
ownFocus={false}
|
||||
panelPaddingSize="none"
|
||||
withTitle={true}
|
||||
>
|
||||
<EuiContextMenu
|
||||
data-test-subj="layerTocActionsPanellayer1"
|
||||
initialPanelId={0}
|
||||
panels={
|
||||
Array [
|
||||
Object {
|
||||
"id": 0,
|
||||
"items": Array [
|
||||
Object {
|
||||
"data-test-subj": "fitToBoundsButton",
|
||||
"disabled": false,
|
||||
"icon": <EuiIcon
|
||||
size="m"
|
||||
type="search"
|
||||
/>,
|
||||
"name": "Fit to data",
|
||||
"onClick": [Function],
|
||||
"toolTipContent": null,
|
||||
},
|
||||
Object {
|
||||
"data-test-subj": "layerVisibilityToggleButton",
|
||||
"icon": <EuiIcon
|
||||
size="m"
|
||||
type="eye"
|
||||
/>,
|
||||
"name": "Hide layer",
|
||||
"onClick": [Function],
|
||||
},
|
||||
Object {
|
||||
"data-test-subj": "editLayerButton",
|
||||
"icon": <EuiIcon
|
||||
size="m"
|
||||
type="pencil"
|
||||
/>,
|
||||
"name": "Edit layer",
|
||||
"onClick": [Function],
|
||||
},
|
||||
Object {
|
||||
"data-test-subj": "cloneLayerButton",
|
||||
"icon": <EuiIcon
|
||||
size="m"
|
||||
type="copy"
|
||||
/>,
|
||||
"name": "Clone layer",
|
||||
"onClick": [Function],
|
||||
},
|
||||
],
|
||||
"title": "Layer actions",
|
||||
},
|
||||
]
|
||||
}
|
||||
/>
|
||||
</EuiPopover>
|
||||
`;
|
||||
|
|
|
@ -11,7 +11,6 @@ import {
|
|||
EuiPopover,
|
||||
EuiContextMenu,
|
||||
EuiIcon,
|
||||
EuiLoadingSpinner,
|
||||
EuiToolTip,
|
||||
} from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
@ -52,7 +51,7 @@ export class LayerTocActions extends Component {
|
|||
};
|
||||
|
||||
_renderPopoverToggleButton() {
|
||||
const { icon, tooltipContent } = this._getIconAndTooltipContent();
|
||||
const { icon, tooltipContent } = this.props.layer.getIconAndTooltipContent(this.props.zoom);
|
||||
return (
|
||||
<EuiToolTip
|
||||
position="top"
|
||||
|
@ -74,55 +73,6 @@ export class LayerTocActions extends Component {
|
|||
);
|
||||
}
|
||||
|
||||
_getIconAndTooltipContent() {
|
||||
const { zoom, layer } = this.props;
|
||||
|
||||
let icon;
|
||||
let tooltipContent;
|
||||
if (layer.hasErrors()) {
|
||||
icon = (
|
||||
<EuiIcon
|
||||
aria-label={i18n.translate('xpack.maps.layerTocActions.loadWarningAriaLabel', { defaultMessage: 'Load warning' })}
|
||||
size="m"
|
||||
type="alert"
|
||||
color="warning"
|
||||
/>
|
||||
);
|
||||
tooltipContent = layer.getErrors();
|
||||
} else if (layer.isLayerLoading()) {
|
||||
icon = (<EuiLoadingSpinner size="m"/>);
|
||||
} else if (!layer.isVisible()) {
|
||||
icon = (
|
||||
<EuiIcon
|
||||
size="m"
|
||||
type="eyeClosed"
|
||||
/>
|
||||
);
|
||||
tooltipContent = i18n.translate('xpack.maps.layerTocActions.layerHiddenTooltip', {
|
||||
defaultMessage: `Layer is hidden.`
|
||||
});
|
||||
} else if (!layer.showAtZoomLevel(zoom)) {
|
||||
const { minZoom, maxZoom } = layer.getZoomConfig();
|
||||
icon = (
|
||||
<EuiIcon
|
||||
size="m"
|
||||
type="expand"
|
||||
/>
|
||||
);
|
||||
tooltipContent = i18n.translate('xpack.maps.layerTocActions.zoomFeedbackTooltip', {
|
||||
defaultMessage: `Layer is visible between zoom levels {minZoom} to {maxZoom}.`,
|
||||
values: { minZoom, maxZoom }
|
||||
});
|
||||
} else {
|
||||
icon = layer.getIcon();
|
||||
}
|
||||
|
||||
return {
|
||||
icon,
|
||||
tooltipContent
|
||||
};
|
||||
}
|
||||
|
||||
_getActionsPanel() {
|
||||
const actionItems = [
|
||||
{
|
||||
|
|
|
@ -10,19 +10,15 @@ import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
|||
import { LayerTocActions } from './layer_toc_actions';
|
||||
|
||||
let supportsFitToBounds;
|
||||
let isLayerLoading;
|
||||
let isVisible;
|
||||
let hasErrors;
|
||||
let showAtZoomLevel;
|
||||
const layerMock = {
|
||||
supportsFitToBounds: () => { return supportsFitToBounds; },
|
||||
isVisible: () => { return isVisible; },
|
||||
hasErrors: () => { return hasErrors; },
|
||||
getErrors: () => { return 'simulated layer error'; },
|
||||
isLayerLoading: () => { return isLayerLoading; },
|
||||
showAtZoomLevel: () => { return showAtZoomLevel; },
|
||||
getZoomConfig: () => { return { minZoom: 2, maxZoom: 3 }; },
|
||||
getIcon: () => { return (<div>icon mock</div>); },
|
||||
isVisible: () => { return true; },
|
||||
getIconAndTooltipContent: (zoom) => {
|
||||
return {
|
||||
icon: (<span>mockIcon</span>),
|
||||
tooltipContent: `simulated tooltip content at zoom: ${zoom}`
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const defaultProps = {
|
||||
|
@ -35,10 +31,6 @@ const defaultProps = {
|
|||
describe('LayerTocActions', () => {
|
||||
beforeEach(() => {
|
||||
supportsFitToBounds = true;
|
||||
isLayerLoading = false;
|
||||
isVisible = true;
|
||||
hasErrors = false;
|
||||
showAtZoomLevel = true;
|
||||
});
|
||||
|
||||
test('is rendered', async () => {
|
||||
|
@ -90,72 +82,4 @@ describe('LayerTocActions', () => {
|
|||
expect(component)
|
||||
.toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should display spinner when layer is loading', async () => {
|
||||
isLayerLoading = true;
|
||||
const component = shallowWithIntl(
|
||||
<LayerTocActions
|
||||
{...defaultProps}
|
||||
/>
|
||||
);
|
||||
|
||||
// Ensure all promises resolve
|
||||
await new Promise(resolve => process.nextTick(resolve));
|
||||
// Ensure the state changes are reflected
|
||||
component.update();
|
||||
|
||||
expect(component)
|
||||
.toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should show warning when layer has errors', async () => {
|
||||
hasErrors = true;
|
||||
const component = shallowWithIntl(
|
||||
<LayerTocActions
|
||||
{...defaultProps}
|
||||
/>
|
||||
);
|
||||
|
||||
// Ensure all promises resolve
|
||||
await new Promise(resolve => process.nextTick(resolve));
|
||||
// Ensure the state changes are reflected
|
||||
component.update();
|
||||
|
||||
expect(component)
|
||||
.toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should show visible toggle when layer is not visible', async () => {
|
||||
isVisible = false;
|
||||
const component = shallowWithIntl(
|
||||
<LayerTocActions
|
||||
{...defaultProps}
|
||||
/>
|
||||
);
|
||||
|
||||
// Ensure all promises resolve
|
||||
await new Promise(resolve => process.nextTick(resolve));
|
||||
// Ensure the state changes are reflected
|
||||
component.update();
|
||||
|
||||
expect(component)
|
||||
.toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should show when layer is not visible because zoom settings are outside of the current zoom level', async () => {
|
||||
showAtZoomLevel = false;
|
||||
const component = shallowWithIntl(
|
||||
<LayerTocActions
|
||||
{...defaultProps}
|
||||
/>
|
||||
);
|
||||
|
||||
// Ensure all promises resolve
|
||||
await new Promise(resolve => process.nextTick(resolve));
|
||||
// Ensure the state changes are reflected
|
||||
component.update();
|
||||
|
||||
expect(component)
|
||||
.toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -11,6 +11,7 @@ import { EuiIcon } from '@elastic/eui';
|
|||
import { HeatmapStyle } from './styles/heatmap_style';
|
||||
import { SOURCE_DATA_ID_ORIGIN } from '../../../common/constants';
|
||||
import { isRefreshOnlyQuery } from './util/is_refresh_only_query';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
const SCALED_PROPERTY_NAME = '__kbn_heatmap_weight__';//unique name to store scaled value for weighting
|
||||
|
||||
|
@ -188,12 +189,25 @@ export class HeatmapLayer extends AbstractLayer {
|
|||
return 'heatmap';
|
||||
}
|
||||
|
||||
getIcon() {
|
||||
return (
|
||||
<EuiIcon
|
||||
type={this.getLayerTypeIconName()}
|
||||
/>
|
||||
);
|
||||
getCustomIconAndTooltipContent() {
|
||||
const sourceDataRequest = this.getSourceDataRequest();
|
||||
const featureCollection = sourceDataRequest ? sourceDataRequest.getData() : null;
|
||||
if (!featureCollection || featureCollection.features.length === 0) {
|
||||
return {
|
||||
icon: (
|
||||
<EuiIcon
|
||||
size="m"
|
||||
color="subdued"
|
||||
type="minusInCircle"
|
||||
/>
|
||||
),
|
||||
tooltipContent: i18n.translate('xpack.maps.heatmapLayer.noResultsFoundTooltip', {
|
||||
defaultMessage: `No results found.`
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
return super.getCustomIconAndTooltipContent();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,12 +4,15 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import _ from 'lodash';
|
||||
import React from 'react';
|
||||
import { EuiIcon, EuiLoadingSpinner } from '@elastic/eui';
|
||||
import turf from 'turf';
|
||||
import turfBooleanContains from '@turf/boolean-contains';
|
||||
import { DataRequest } from './util/data_request';
|
||||
import { SOURCE_DATA_ID_ORIGIN } from '../../../common/constants';
|
||||
import uuid from 'uuid/v4';
|
||||
import { copyPersistentState } from '../../store/util';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
const SOURCE_UPDATE_REQUIRED = true;
|
||||
const NO_SOURCE_UPDATE_REQUIRED = false;
|
||||
|
@ -101,8 +104,66 @@ export class AbstractLayer {
|
|||
return this._descriptor.label ? this._descriptor.label : '';
|
||||
}
|
||||
|
||||
getIcon() {
|
||||
console.warn('Icon not available for this layer type');
|
||||
getCustomIconAndTooltipContent() {
|
||||
return {
|
||||
icon: (
|
||||
<EuiIcon
|
||||
size="m"
|
||||
type={this.getLayerTypeIconName()}
|
||||
/>
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
getIconAndTooltipContent(zoomLevel) {
|
||||
let icon;
|
||||
let tooltipContent = null;
|
||||
if (this.hasErrors()) {
|
||||
icon = (
|
||||
<EuiIcon
|
||||
aria-label={i18n.translate('xpack.maps.layer.loadWarningAriaLabel', { defaultMessage: 'Load warning' })}
|
||||
size="m"
|
||||
type="alert"
|
||||
color="warning"
|
||||
/>
|
||||
);
|
||||
tooltipContent = this.getErrors();
|
||||
} else if (this.isLayerLoading()) {
|
||||
icon = (<EuiLoadingSpinner size="m"/>);
|
||||
} else if (!this.isVisible()) {
|
||||
icon = (
|
||||
<EuiIcon
|
||||
size="m"
|
||||
type="eyeClosed"
|
||||
/>
|
||||
);
|
||||
tooltipContent = i18n.translate('xpack.maps.layer.layerHiddenTooltip', {
|
||||
defaultMessage: `Layer is hidden.`
|
||||
});
|
||||
} else if (!this.showAtZoomLevel(zoomLevel)) {
|
||||
const { minZoom, maxZoom } = this.getZoomConfig();
|
||||
icon = (
|
||||
<EuiIcon
|
||||
size="m"
|
||||
type="expand"
|
||||
/>
|
||||
);
|
||||
tooltipContent = i18n.translate('xpack.maps.layer.zoomFeedbackTooltip', {
|
||||
defaultMessage: `Layer is visible between zoom levels {minZoom} and {maxZoom}.`,
|
||||
values: { minZoom, maxZoom }
|
||||
});
|
||||
} else {
|
||||
const customIconAndTooltipContent = this.getCustomIconAndTooltipContent();
|
||||
if (customIconAndTooltipContent) {
|
||||
icon = customIconAndTooltipContent.icon;
|
||||
tooltipContent = customIconAndTooltipContent.tooltipContent;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
icon,
|
||||
tooltipContent
|
||||
};
|
||||
}
|
||||
|
||||
hasLegendDetails() {
|
||||
|
@ -126,12 +187,7 @@ export class AbstractLayer {
|
|||
}
|
||||
|
||||
showAtZoomLevel(zoom) {
|
||||
|
||||
if (zoom >= this._descriptor.minZoom && zoom <= this._descriptor.maxZoom) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return zoom >= this._descriptor.minZoom && zoom <= this._descriptor.maxZoom;
|
||||
}
|
||||
|
||||
getMinZoom() {
|
||||
|
|
|
@ -196,4 +196,21 @@ export class ESSearchSource extends AbstractESSource {
|
|||
return { name: field.name, label: field.name };
|
||||
});
|
||||
}
|
||||
|
||||
getSourceTooltipContent(sourceDataRequest) {
|
||||
const featureCollection = sourceDataRequest ? sourceDataRequest.getData() : null;
|
||||
const meta = sourceDataRequest ? sourceDataRequest.getMeta() : {};
|
||||
|
||||
if (meta.areResultsTrimmed) {
|
||||
return i18n.translate('xpack.maps.esSearch.resultsTrimmedMsg', {
|
||||
defaultMessage: `Results limited to first {count} matching documents.`,
|
||||
values: { count: featureCollection.features.length }
|
||||
});
|
||||
}
|
||||
|
||||
return i18n.translate('xpack.maps.esSearch.featureCountMsg', {
|
||||
defaultMessage: `Found {count} documents.`,
|
||||
values: { count: featureCollection.features.length }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -114,4 +114,8 @@ export class AbstractVectorSource extends AbstractSource {
|
|||
isJoinable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
getSourceTooltipContent(/* sourceDataRequest */) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
|
||||
import { AbstractLayer } from './layer';
|
||||
import _ from 'lodash';
|
||||
import React from 'react';
|
||||
import { EuiIcon } from '@elastic/eui';
|
||||
import { TileStyle } from '../layers/styles/tile_style';
|
||||
import { SOURCE_DATA_ID_ORIGIN } from '../../../common/constants';
|
||||
|
||||
|
@ -105,15 +103,7 @@ export class TileLayer extends AbstractLayer {
|
|||
return 'grid';
|
||||
}
|
||||
|
||||
getIcon() {
|
||||
return (
|
||||
<EuiIcon
|
||||
type={this.getLayerTypeIconName()}
|
||||
/>
|
||||
);
|
||||
}
|
||||
isLayerLoading() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
import turf from 'turf';
|
||||
import React from 'react';
|
||||
import { AbstractLayer } from './layer';
|
||||
import { VectorStyle } from './styles/vector_style';
|
||||
import { LeftInnerJoin } from './joins/left_inner_join';
|
||||
|
@ -12,6 +13,8 @@ import { FEATURE_ID_PROPERTY_NAME, SOURCE_DATA_ID_ORIGIN } from '../../../common
|
|||
import _ from 'lodash';
|
||||
import { JoinTooltipProperty } from './tooltips/join_tooltip_property';
|
||||
import { isRefreshOnlyQuery } from './util/is_refresh_only_query';
|
||||
import { EuiIcon } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
const EMPTY_FEATURE_COLLECTION = {
|
||||
type: 'FeatureCollection',
|
||||
|
@ -78,8 +81,28 @@ export class VectorLayer extends AbstractLayer {
|
|||
});
|
||||
}
|
||||
|
||||
getIcon() {
|
||||
return this._style.getIcon();
|
||||
getCustomIconAndTooltipContent() {
|
||||
const sourceDataRequest = this.getSourceDataRequest();
|
||||
const featureCollection = sourceDataRequest ? sourceDataRequest.getData() : null;
|
||||
if (!featureCollection || featureCollection.features.length === 0) {
|
||||
return {
|
||||
icon: (
|
||||
<EuiIcon
|
||||
size="m"
|
||||
color="subdued"
|
||||
type="minusInCircle"
|
||||
/>
|
||||
),
|
||||
tooltipContent: i18n.translate('xpack.maps.vectorLayer.noResultsFoundTooltip', {
|
||||
defaultMessage: `No results found.`
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
icon: this._style.getIcon(),
|
||||
tooltipContent: this._source.getSourceTooltipContent(sourceDataRequest)
|
||||
};
|
||||
}
|
||||
|
||||
getLayerTypeIconName() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue