import React , { Component } from 'react' ; import { i18n } from '@kbn/i18n' ; import { Filter } from '@kbn/es-query' ; import { ActionExecutionContext , Action } from 'src/plugins/ui_actions/public' ; import { Geometry , Polygon } from 'geojson' ; import rison , { RisonObject } from 'rison-node' ; import { URL_MAX_LENGTH } from '../../../../../../../../src/core/public' ; import { ACTION_GLOBAL_APPLY_FILTER } from '../../../../../../../../src/plugins/data/public' ; import { createSpatialFilterWithGeometry , PreIndexedShape , } from '../../../../../common/elasticsearch_util' ; import { ES_SPATIAL_RELATIONS , GEO_JSON_TYPE } from '../../../../../common/constants' ; import { GeometryFilterForm } from '../../../../components/draw_forms/geometry_filter_form/geometry_filter_form' ; const META_OVERHEAD = 100 ; interface Props { onClose : ( ) => void ; geometry : Geometry ; addFilters : ( filters : Filter [ ] , actionId : string ) => Promise < void > ; getFilterActions ? : ( ) => Promise < Action [ ] > ; getActionContext ? : ( ) => ActionExecutionContext ; loadPreIndexedShape : ( ) => Promise < PreIndexedShape | null > ; geoFieldNames : string [ ] ; } interface State { isLoading : boolean ; errorMsg : string | undefined ; } export class FeatureGeometryFilterForm extends Component < Props , State > { private _isMounted = false ; state : State = { isLoading : false , errorMsg : undefined , } ; componentDidMount ( ) { this . _isMounted = true ; } componentWillUnmount ( ) { this . _isMounted = false ; } _loadPreIndexedShape = async ( ) => { this . setState ( { isLoading : true , } ) ; let preIndexedShape ; try { preIndexedShape = await this . props . loadPreIndexedShape ( ) ; } catch ( err ) { } if ( this . _isMounted ) { this . setState ( { isLoading : false } ) ; } return preIndexedShape ; } ; _createFilter = async ( { geometryLabel , relation , } ) => { this . setState ( { errorMsg : undefined } ) ; const preIndexedShape = await this . _loadPreIndexedShape ( ) ; if ( ! this . _isMounted ) { return ; } const filter = createSpatialFilterWithGeometry ( { preIndexedShape , geometry : this . props . geometry as Polygon , geometryLabel , geoFieldNames : this . props . geoFieldNames , relation , } ) ; if ( window . location . href . length + rison . encode ( filter as unknown as RisonObject ) . length + META_OVERHEAD > URL_MAX_LENGTH ) { 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 ] , ACTION_GLOBAL_APPLY_FILTER ) ; this . props . onClose ( ) ; } ; render ( ) { return ( < GeometryFilterForm buttonLabel = { i18n . translate ( 'xpack.maps.tooltip.geometryFilterForm.createFilterButtonLabel' , { defaultMessage : 'Create filter' , } ) } getFilterActions = { this . props . getFilterActions } getActionContext = { this . props . getActionContext } intitialGeometryLabel = { this . props . geometry . type . toLowerCase ( ) } onSubmit = { this . _createFilter } 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 } / > ) ; } }