Skip to content

Commit 37d82db

Browse files
authored
[Maps] prevent users from overflowing URL when filtering by shape (#50747)
* [Maps] prevent users from overflowing URL when filtering by shape * small fix * fix jest test * update warning message * update overflow error message
1 parent 6729d51 commit 37d82db

File tree

7 files changed

+135
-1
lines changed

7 files changed

+135
-1
lines changed

src/legacy/ui/public/url/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,4 @@
1919

2020
export { KbnUrlProvider } from './url';
2121
export { RedirectWhenMissingProvider } from './redirect_when_missing';
22-
export { modifyUrl } from '../../../../core/public/utils';
22+
export { modifyUrl } from '../../../../core/utils';

x-pack/legacy/plugins/maps/public/components/__snapshots__/geometry_filter_form.test.js.snap

Lines changed: 82 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

x-pack/legacy/plugins/maps/public/components/geometry_filter_form.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
EuiSelect,
1818
EuiSpacer,
1919
EuiTextAlign,
20+
EuiFormErrorText,
2021
} from '@elastic/eui';
2122
import { i18n } from '@kbn/i18n';
2223
import { ES_GEO_FIELD_TYPE, ES_SPATIAL_RELATIONS } from '../../common/constants';
@@ -43,6 +44,7 @@ export class GeometryFilterForm extends Component {
4344
intitialGeometryLabel: PropTypes.string.isRequired,
4445
onSubmit: PropTypes.func.isRequired,
4546
isFilterGeometryClosed: PropTypes.bool,
47+
errorMsg: PropTypes.string,
4648
};
4749

4850
static defaultProps = {
@@ -153,6 +155,10 @@ export class GeometryFilterForm extends Component {
153155
value: createIndexGeoFieldName({ indexPatternTitle, geoFieldName }),
154156
};
155157
});
158+
let error;
159+
if (this.props.errorMsg) {
160+
error = <EuiFormErrorText>{this.props.errorMsg}</EuiFormErrorText>;
161+
}
156162
return (
157163
<EuiForm className={this.props.className}>
158164
<EuiFormRow
@@ -191,6 +197,8 @@ export class GeometryFilterForm extends Component {
191197

192198
<EuiSpacer size="m" />
193199

200+
{error}
201+
194202
<EuiTextAlign textAlign="right">
195203
<EuiButton
196204
size="s"

x-pack/legacy/plugins/maps/public/components/geometry_filter_form.test.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,22 @@ test('should not show "within" relation when filter geometry is not closed', asy
6969

7070
expect(component).toMatchSnapshot();
7171
});
72+
73+
test('should render error message', async () => {
74+
const component = shallow(
75+
<GeometryFilterForm
76+
{...defaultProps}
77+
geoFields={[
78+
{
79+
geoFieldName: 'my geo field',
80+
geoFieldType: 'geo_point',
81+
indexPatternTitle: 'My index',
82+
indexPatternId: 1
83+
}
84+
]}
85+
errorMsg="Simulated error"
86+
/>
87+
);
88+
89+
expect(component).toMatchSnapshot();
90+
});

x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/feature_geometry_filter_form.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,16 @@ import { i18n } from '@kbn/i18n';
1111
import { createSpatialFilterWithGeometry } from '../../../elasticsearch_geo_utils';
1212
import { GEO_JSON_TYPE } from '../../../../common/constants';
1313
import { GeometryFilterForm } from '../../../components/geometry_filter_form';
14+
import { UrlOverflowService } from 'ui/error_url_overflow';
15+
import rison from 'rison-node';
16+
17+
const urlOverflow = new UrlOverflowService();
1418

1519
export class FeatureGeometryFilterForm extends Component {
1620

1721
state = {
1822
isLoading: false,
23+
errorMsg: undefined,
1924
}
2025

2126
componentDidMount() {
@@ -46,6 +51,7 @@ export class FeatureGeometryFilterForm extends Component {
4651
}
4752

4853
_createFilter = async ({ geometryLabel, indexPatternId, geoFieldName, geoFieldType, relation }) => {
54+
this.setState({ errorMsg: undefined });
4955
const preIndexedShape = await this._loadPreIndexedShape();
5056
if (!this._isMounted) {
5157
// do not create filter if component is unmounted
@@ -61,6 +67,18 @@ export class FeatureGeometryFilterForm extends Component {
6167
geoFieldType,
6268
relation,
6369
});
70+
71+
// Ensure filter will not overflow URL. Filters that contain geometry can be extremely large.
72+
// No elasticsearch support for pre-indexed shapes and geo_point spatial queries.
73+
if (window.location.href.length + rison.encode(filter).length > urlOverflow.failLength()) {
74+
this.setState({
75+
errorMsg: i18n.translate('xpack.maps.tooltip.geometryFilterForm.filterTooLargeMessage', {
76+
defaultMessage: 'Cannot create filter. Filters are added to the URL, and this shape has too many vertices to fit in the URL.'
77+
})
78+
});
79+
return;
80+
}
81+
6482
this.props.addFilters([filter]);
6583
this.props.onClose();
6684
}
@@ -102,6 +120,7 @@ export class FeatureGeometryFilterForm extends Component {
102120
isFilterGeometryClosed={this.props.geometry.type !== GEO_JSON_TYPE.LINE_STRING
103121
&& this.props.geometry.type !== GEO_JSON_TYPE.MULTI_LINE_STRING}
104122
isLoading={this.state.isLoading}
123+
errorMsg={this.state.errorMsg}
105124
/>
106125
);
107126
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44
* you may not use this file except in compliance with the Elastic License.
55
*/
66

7+
jest.mock('../../features_tooltip/features_tooltip', () => ({
8+
FeaturesTooltip: () => {
9+
return (<div>mockFeaturesTooltip</div>);
10+
}
11+
}));
12+
713
import sinon from 'sinon';
814
import React from 'react';
915
import { mount, shallow } from 'enzyme';

0 commit comments

Comments
 (0)