Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Maps] prevent users from overflowing URL when filtering by shape #50747

Merged
merged 8 commits into from
Nov 18, 2019
2 changes: 1 addition & 1 deletion src/legacy/ui/public/url/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@

export { KbnUrlProvider } from './url';
export { RedirectWhenMissingProvider } from './redirect_when_missing';
export { modifyUrl } from '../../../../core/public/utils';
export { modifyUrl } from '../../../../core/utils';

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

Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
EuiSelect,
EuiSpacer,
EuiTextAlign,
EuiFormErrorText,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { ES_GEO_FIELD_TYPE, ES_SPATIAL_RELATIONS } from '../../common/constants';
Expand All @@ -43,6 +44,7 @@ export class GeometryFilterForm extends Component {
intitialGeometryLabel: PropTypes.string.isRequired,
onSubmit: PropTypes.func.isRequired,
isFilterGeometryClosed: PropTypes.bool,
errorMsg: PropTypes.string,
};

static defaultProps = {
Expand Down Expand Up @@ -153,6 +155,10 @@ export class GeometryFilterForm extends Component {
value: createIndexGeoFieldName({ indexPatternTitle, geoFieldName }),
};
});
let error;
if (this.props.errorMsg) {
error = <EuiFormErrorText>{this.props.errorMsg}</EuiFormErrorText>;
}
return (
<EuiForm className={this.props.className}>
<EuiFormRow
Expand Down Expand Up @@ -191,6 +197,8 @@ export class GeometryFilterForm extends Component {

<EuiSpacer size="m" />

{error}

<EuiTextAlign textAlign="right">
<EuiButton
size="s"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,22 @@ test('should not show "within" relation when filter geometry is not closed', asy

expect(component).toMatchSnapshot();
});

test('should render error message', async () => {
const component = shallow(
<GeometryFilterForm
{...defaultProps}
geoFields={[
{
geoFieldName: 'my geo field',
geoFieldType: 'geo_point',
indexPatternTitle: 'My index',
indexPatternId: 1
}
]}
errorMsg="Simulated error"
/>
);

expect(component).toMatchSnapshot();
});
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,16 @@ import { i18n } from '@kbn/i18n';
import { createSpatialFilterWithGeometry } from '../../../elasticsearch_geo_utils';
import { GEO_JSON_TYPE } from '../../../../common/constants';
import { GeometryFilterForm } from '../../../components/geometry_filter_form';
import { UrlOverflowService } from 'ui/error_url_overflow';
nreese marked this conversation as resolved.
Show resolved Hide resolved
import rison from 'rison-node';

const urlOverflow = new UrlOverflowService();

export class FeatureGeometryFilterForm extends Component {

state = {
isLoading: false,
errorMsg: undefined,
}

componentDidMount() {
Expand Down Expand Up @@ -46,6 +51,7 @@ export class FeatureGeometryFilterForm extends Component {
}

_createFilter = async ({ geometryLabel, indexPatternId, geoFieldName, geoFieldType, relation }) => {
this.setState({ errorMsg: undefined });
const preIndexedShape = await this._loadPreIndexedShape();
if (!this._isMounted) {
// do not create filter if component is unmounted
Expand All @@ -61,6 +67,18 @@ export class FeatureGeometryFilterForm extends Component {
geoFieldType,
relation,
});

// Ensure filter will not overflow URL. Filters that contain geometry can be extremely large.
// No elasticsearch support for pre-indexed shapes and geo_point spatial queries.
if (window.location.href.length + rison.encode(filter).length > urlOverflow.failLength()) {
this.setState({
errorMsg: i18n.translate('xpack.maps.tooltip.geometryFilterForm.filterTooLargeMessage', {
defaultMessage: 'Cannot create filter. Filters are added to the URL, and this shape has too many vertices to fit in the URL.'
})
});
return;
}

this.props.addFilters([filter]);
this.props.onClose();
}
Expand Down Expand Up @@ -102,6 +120,7 @@ export class FeatureGeometryFilterForm extends Component {
isFilterGeometryClosed={this.props.geometry.type !== GEO_JSON_TYPE.LINE_STRING
&& this.props.geometry.type !== GEO_JSON_TYPE.MULTI_LINE_STRING}
isLoading={this.state.isLoading}
errorMsg={this.state.errorMsg}
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@
* you may not use this file except in compliance with the Elastic License.
*/

jest.mock('../../features_tooltip/features_tooltip', () => ({
FeaturesTooltip: () => {
return (<div>mockFeaturesTooltip</div>);
}
}));

import sinon from 'sinon';
import React from 'react';
import { mount, shallow } from 'enzyme';
Expand Down