From 5f8aa18131610de3ef7d2cac8d28c07fe7a0f032 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Fri, 26 Mar 2021 15:50:56 -0600 Subject: [PATCH 001/103] Placeholder feature edit control in place --- .../feature_edit_control.test.tsx.snap | 242 +++++++++++++++ .../feature_edit_control/_index.scss | 3 + .../feature_edit_control.test.tsx | 36 +++ .../feature_edit_control.tsx | 281 ++++++++++++++++++ .../feature_edit_control/index.ts | 38 +++ .../toolbar_overlay/toolbar_overlay.js | 20 ++ 6 files changed, 620 insertions(+) create mode 100644 x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/__snapshots__/feature_edit_control.test.tsx.snap create mode 100644 x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/_index.scss create mode 100644 x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.test.tsx create mode 100644 x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.tsx create mode 100644 x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/index.ts diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/__snapshots__/feature_edit_control.test.tsx.snap b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/__snapshots__/feature_edit_control.test.tsx.snap new file mode 100644 index 00000000000000..076f4690143d92 --- /dev/null +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/__snapshots__/feature_edit_control.test.tsx.snap @@ -0,0 +1,242 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Should render cancel button when drawing 1`] = ` + + + + } + closePopover={[Function]} + display="inlineBlock" + hasArrow={true} + id="FeatureEditControlPopover" + isOpen={false} + ownFocus={false} + panelPaddingSize="none" + > + , + "id": 1, + "title": "Draw shape", + }, + Object { + "content": , + "id": 2, + "title": "Draw bounds", + }, + Object { + "content": , + "id": 3, + "title": "Draw distance", + }, + ] + } + size="m" + /> + + + + + + + + +`; + +exports[`renders 1`] = ` + + } + closePopover={[Function]} + display="inlineBlock" + hasArrow={true} + id="FeatureEditControlPopover" + isOpen={false} + ownFocus={false} + panelPaddingSize="none" +> + , + "id": 1, + "title": "Draw shape", + }, + Object { + "content": , + "id": 2, + "title": "Draw bounds", + }, + Object { + "content": , + "id": 3, + "title": "Draw distance", + }, + ] + } + size="m" + /> + +`; diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/_index.scss b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/_index.scss new file mode 100644 index 00000000000000..de86299d559e86 --- /dev/null +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/_index.scss @@ -0,0 +1,3 @@ +.mapDrawControl__geometryFilterForm { + padding: $euiSizeS; +} diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.test.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.test.tsx new file mode 100644 index 00000000000000..afcf0de5c8baf7 --- /dev/null +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.test.tsx @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { shallow } from 'enzyme'; +import { FeatureEditControl } from './feature_edit_control'; + +const defaultProps = { + initiateDraw: () => {}, + cancelDraw: () => {}, + geoFields: [ + { + geoFieldName: 'location', + geoFieldType: 'geo_point', + indexPatternTitle: 'my_index', + indexPatternId: '1', + }, + ], + isDrawingFilter: false, +}; + +test('renders', async () => { + const component = shallow(); + + expect(component).toMatchSnapshot(); +}); + +test('Should render cancel button when drawing', async () => { + const component = shallow(); + + expect(component).toMatchSnapshot(); +}); diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.tsx new file mode 100644 index 00000000000000..9318774fe616bc --- /dev/null +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.tsx @@ -0,0 +1,281 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { Component } from 'react'; +import { + EuiButtonIcon, + EuiPopover, + EuiContextMenu, + EuiFlexGroup, + EuiFlexItem, + EuiButton, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { ActionExecutionContext, Action } from 'src/plugins/ui_actions/public'; +import { DRAW_TYPE, ES_GEO_FIELD_TYPE, ES_SPATIAL_RELATIONS } from '../../../../common/constants'; +// @ts-expect-error +import { GeometryFilterForm } from '../../../components/geometry_filter_form'; +import { DistanceFilterForm } from '../../../components/distance_filter_form'; +import { GeoFieldWithIndex } from '../../../components/geo_field_with_index'; +import { DrawState } from '../../../../common/descriptor_types'; + +const DRAW_SHAPE_LABEL = i18n.translate('xpack.maps.toolbarOverlay.drawShapeLabel', { + defaultMessage: 'Draw shape to filter data', +}); + +const DRAW_BOUNDS_LABEL = i18n.translate('xpack.maps.toolbarOverlay.drawBoundsLabel', { + defaultMessage: 'Draw bounds to filter data', +}); + +const DRAW_DISTANCE_LABEL = i18n.translate('xpack.maps.toolbarOverlay.drawDistanceLabel', { + defaultMessage: 'Draw distance to filter data', +}); + +const DRAW_SHAPE_LABEL_SHORT = i18n.translate('xpack.maps.toolbarOverlay.drawShapeLabelShort', { + defaultMessage: 'Draw shape', +}); + +const DRAW_BOUNDS_LABEL_SHORT = i18n.translate('xpack.maps.toolbarOverlay.drawBoundsLabelShort', { + defaultMessage: 'Draw bounds', +}); + +const DRAW_DISTANCE_LABEL_SHORT = i18n.translate( + 'xpack.maps.toolbarOverlay.drawDistanceLabelShort', + { + defaultMessage: 'Draw distance', + } +); + +export interface Props { + cancelDraw: () => void; + geoFields: GeoFieldWithIndex[]; + initiateDraw: (drawState: DrawState) => void; + isDrawingFilter: boolean; + getFilterActions?: () => Promise; + getActionContext?: () => ActionExecutionContext; +} + +interface State { + isPopoverOpen: boolean; +} + +export class FeatureEditControl extends Component { + state: State = { + isPopoverOpen: false, + }; + + _togglePopover = () => { + this.setState((prevState) => ({ + isPopoverOpen: !prevState.isPopoverOpen, + })); + }; + + _closePopover = () => { + this.setState({ isPopoverOpen: false }); + }; + + _initiateShapeDraw = (options: { + actionId: string; + geometryLabel: string; + indexPatternId: string; + geoFieldName: string; + geoFieldType: ES_GEO_FIELD_TYPE; + relation: ES_SPATIAL_RELATIONS; + }) => { + this.props.initiateDraw({ + drawType: DRAW_TYPE.POLYGON, + ...options, + }); + this._closePopover(); + }; + + _initiateBoundsDraw = (options: { + actionId: string; + geometryLabel: string; + indexPatternId: string; + geoFieldName: string; + geoFieldType: ES_GEO_FIELD_TYPE; + relation: ES_SPATIAL_RELATIONS; + }) => { + this.props.initiateDraw({ + drawType: DRAW_TYPE.BOUNDS, + ...options, + }); + this._closePopover(); + }; + + _initiateDistanceDraw = (options: { + actionId: string; + filterLabel: string; + indexPatternId: string; + geoFieldName: string; + }) => { + this.props.initiateDraw({ + drawType: DRAW_TYPE.DISTANCE, + ...options, + }); + this._closePopover(); + }; + + _getDrawPanels() { + const tools = [ + { + name: DRAW_SHAPE_LABEL, + panel: 1, + }, + { + name: DRAW_BOUNDS_LABEL, + panel: 2, + }, + ]; + + const hasGeoPoints = this.props.geoFields.some(({ geoFieldType }) => { + return geoFieldType === ES_GEO_FIELD_TYPE.GEO_POINT; + }); + if (hasGeoPoints) { + tools.push({ + name: DRAW_DISTANCE_LABEL, + panel: 3, + }); + } + + return [ + { + id: 0, + title: i18n.translate('xpack.maps.toolbarOverlay.tools.toolbarTitle', { + defaultMessage: 'Tools', + }), + items: tools, + }, + { + id: 1, + title: DRAW_SHAPE_LABEL_SHORT, + content: ( + + ), + }, + { + id: 2, + title: DRAW_BOUNDS_LABEL_SHORT, + content: ( + + ), + }, + { + id: 3, + title: DRAW_DISTANCE_LABEL_SHORT, + content: ( + { + return geoFieldType === ES_GEO_FIELD_TYPE.GEO_POINT; + })} + getFilterActions={this.props.getFilterActions} + getActionContext={this.props.getActionContext} + onSubmit={this._initiateDistanceDraw} + /> + ), + }, + ]; + } + + _renderToolsButton() { + return ( + + ); + } + + _renderFeatureEditButton() { + return ( + + ); + } + + render() { + const featureEditControlPopoverButton = ( + + + + ); + + if (!this.props.isDrawingFilter) { + return featureEditControlPopoverButton; + } + + return ( + + {featureEditControlPopoverButton} + + + + + + + ); + } +} diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/index.ts new file mode 100644 index 00000000000000..da0a33c652c2a6 --- /dev/null +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/index.ts @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { AnyAction } from 'redux'; +import { ThunkDispatch } from 'redux-thunk'; +import { connect } from 'react-redux'; +import { FeatureEditControl } from './feature_edit_control'; +import { isDrawingFilter } from '../../../selectors/map_selectors'; +import { updateDrawState } from '../../../actions'; +import { MapStoreState } from '../../../reducers/store'; +import { DrawState } from '../../../../common/descriptor_types'; + +function mapStateToProps(state: MapStoreState) { + return { + isDrawingFilter: isDrawingFilter(state), + }; +} + +function mapDispatchToProps(dispatch: ThunkDispatch) { + return { + initiateDraw: (drawState: DrawState) => { + dispatch(updateDrawState(drawState)); + }, + cancelDraw: () => { + dispatch(updateDrawState(null)); + }, + }; +} + +const connectedFeatureEditControl = connect( + mapStateToProps, + mapDispatchToProps +)(FeatureEditControl); +export { connectedFeatureEditControl as FeatureEditControl }; diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.js b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.js index ceca3f5b7fdc11..832212478c3d12 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.js +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.js @@ -9,6 +9,7 @@ import React from 'react'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { SetViewControl } from './set_view_control'; import { ToolsControl } from './tools_control'; +import { FeatureEditControl } from './feature_edit_control'; import { FitToData } from './fit_to_data'; export class ToolbarOverlay extends React.Component { @@ -29,6 +30,23 @@ export class ToolbarOverlay extends React.Component { ); } + _renderFeatureEditControl() { + const { addFilters, geoFields, getFilterActions, getActionContext } = this.props; + if (!addFilters || !geoFields.length) { + return null; + } + + return ( + + + + ); + } + render() { return ( {this._renderToolsControl()} + + {this._renderFeatureEditControl()} ); } From a80038a388c6d7e42b1c7c9c684371f8c9b508f5 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 31 Mar 2021 11:42:15 -0600 Subject: [PATCH 002/103] Placeholder menu added --- x-pack/plugins/maps/common/constants.ts | 1 + .../source_descriptor_types.ts | 9 + .../sources/new_vector_layer_source/index.ts | 8 + .../new_vector_layer.test.ts | 106 +++++++++ .../new_vector_layer_source.ts | 137 +++++++++++ .../draw_feature_control.tsx | 49 ++++ .../draw_feature_control/index.ts | 32 +++ .../connected_components/mb_map/index.ts | 1 + .../connected_components/mb_map/mb_map.tsx | 16 +- .../feature_edit_control.tsx | 215 +++--------------- .../toolbar_overlay/toolbar_overlay.js | 5 +- 11 files changed, 387 insertions(+), 192 deletions(-) create mode 100644 x-pack/plugins/maps/public/classes/sources/new_vector_layer_source/index.ts create mode 100644 x-pack/plugins/maps/public/classes/sources/new_vector_layer_source/new_vector_layer.test.ts create mode 100644 x-pack/plugins/maps/public/classes/sources/new_vector_layer_source/new_vector_layer_source.ts create mode 100644 x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx create mode 100644 x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts diff --git a/x-pack/plugins/maps/common/constants.ts b/x-pack/plugins/maps/common/constants.ts index ecdf94a076809c..c4c7a60c56fe65 100644 --- a/x-pack/plugins/maps/common/constants.ts +++ b/x-pack/plugins/maps/common/constants.ts @@ -89,6 +89,7 @@ export enum SOURCE_TYPES { GEOJSON_FILE = 'GEOJSON_FILE', MVT_SINGLE_LAYER = 'MVT_SINGLE_LAYER', TABLE_SOURCE = 'TABLE_SOURCE', + NEW_VECTOR_LAYER = 'NEW_VECTOR_LAYER', } export enum FIELD_ORIGIN { diff --git a/x-pack/plugins/maps/common/descriptor_types/source_descriptor_types.ts b/x-pack/plugins/maps/common/descriptor_types/source_descriptor_types.ts index 7b757aa9cf10b1..145501d16683c7 100644 --- a/x-pack/plugins/maps/common/descriptor_types/source_descriptor_types.ts +++ b/x-pack/plugins/maps/common/descriptor_types/source_descriptor_types.ts @@ -188,4 +188,13 @@ export type TableSourceDescriptor = { term: string; }; +export type NewVectorLayerSourceDescriptor = { + __fields?: InlineFieldDescriptor[]; + __featureCollection: FeatureCollection; + areResultsTrimmed: boolean; + tooltipContent: string | null; + name: string; + type: string; +}; + export type TermJoinSourceDescriptor = ESTermSourceDescriptor | TableSourceDescriptor; diff --git a/x-pack/plugins/maps/public/classes/sources/new_vector_layer_source/index.ts b/x-pack/plugins/maps/public/classes/sources/new_vector_layer_source/index.ts new file mode 100644 index 00000000000000..48fbbe0c4cc525 --- /dev/null +++ b/x-pack/plugins/maps/public/classes/sources/new_vector_layer_source/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { NewVectorLayerSource } from './new_vector_layer_source'; diff --git a/x-pack/plugins/maps/public/classes/sources/new_vector_layer_source/new_vector_layer.test.ts b/x-pack/plugins/maps/public/classes/sources/new_vector_layer_source/new_vector_layer.test.ts new file mode 100644 index 00000000000000..47519747ae28a8 --- /dev/null +++ b/x-pack/plugins/maps/public/classes/sources/new_vector_layer_source/new_vector_layer.test.ts @@ -0,0 +1,106 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { GeoJsonFileSource } from './new_vector_layer_source'; +import { BoundsFilters } from '../vector_source'; +import { FIELD_ORIGIN } from '../../../../common/constants'; + +describe('GeoJsonFileSource', () => { + describe('getName', () => { + it('should get default display name', async () => { + const geojsonFileSource = new GeoJsonFileSource({}); + expect(await geojsonFileSource.getDisplayName()).toBe('Features'); + }); + }); + describe('getBounds', () => { + it('should get null bounds', async () => { + const geojsonFileSource = new GeoJsonFileSource({}); + expect( + await geojsonFileSource.getBoundsForFilters(({} as unknown) as BoundsFilters, () => {}) + ).toEqual(null); + }); + + it('should get bounds from feature collection', async () => { + const geojsonFileSource = new GeoJsonFileSource({ + __featureCollection: { + type: 'FeatureCollection', + features: [ + { + type: 'Feature', + geometry: { + type: 'Point', + coordinates: [0, 1], + }, + properties: {}, + }, + { + type: 'Feature', + geometry: { + type: 'Point', + coordinates: [2, 3], + }, + properties: {}, + }, + ], + }, + }); + + expect(geojsonFileSource.isBoundsAware()).toBe(true); + expect( + await geojsonFileSource.getBoundsForFilters(({} as unknown) as BoundsFilters, () => {}) + ).toEqual({ + maxLat: 3, + maxLon: 2, + minLat: 1, + minLon: 0, + }); + }); + }); + + describe('getFields', () => { + it('should get fields from config', async () => { + const geojsonFileSource = new GeoJsonFileSource({ + __fields: [ + { + type: 'string', + name: 'foo', + }, + { + type: 'number', + name: 'bar', + }, + ], + }); + + const fields = await geojsonFileSource.getFields(); + + const actualFields = fields.map(async (field) => { + return { + dataType: await field.getDataType(), + origin: field.getOrigin(), + name: field.getName(), + source: field.getSource(), + }; + }); + + expect(await Promise.all(actualFields)).toEqual([ + { + dataType: 'string', + origin: FIELD_ORIGIN.SOURCE, + source: geojsonFileSource, + name: 'foo', + }, + { + dataType: 'number', + origin: FIELD_ORIGIN.SOURCE, + source: geojsonFileSource, + name: 'bar', + }, + ]); + }); + }); +}); diff --git a/x-pack/plugins/maps/public/classes/sources/new_vector_layer_source/new_vector_layer_source.ts b/x-pack/plugins/maps/public/classes/sources/new_vector_layer_source/new_vector_layer_source.ts new file mode 100644 index 00000000000000..7154b2993965bd --- /dev/null +++ b/x-pack/plugins/maps/public/classes/sources/new_vector_layer_source/new_vector_layer_source.ts @@ -0,0 +1,137 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Feature, FeatureCollection } from 'geojson'; +import { AbstractVectorSource, BoundsFilters, GeoJsonWithMeta } from '../vector_source'; +import { EMPTY_FEATURE_COLLECTION, FIELD_ORIGIN, SOURCE_TYPES } from '../../../../common/constants'; +import { + InlineFieldDescriptor, + NewVectorLayerSourceDescriptor, + MapExtent, +} from '../../../../common/descriptor_types'; +import { registerSource } from '../source_registry'; +import { IField } from '../../fields/field'; +import { getFeatureCollectionBounds } from '../../util/get_feature_collection_bounds'; +import { Adapters } from '../../../../../../../src/plugins/inspector/common/adapters'; +import { InlineField } from '../../fields/inline_field'; + +function getFeatureCollection( + geoJson: Feature | FeatureCollection | null | undefined +): FeatureCollection { + if (!geoJson) { + return EMPTY_FEATURE_COLLECTION; + } + + if (geoJson.type === 'FeatureCollection') { + return geoJson; + } + + if (geoJson.type === 'Feature') { + return { + type: 'FeatureCollection', + features: [geoJson], + }; + } + + return EMPTY_FEATURE_COLLECTION; +} + +export class NewVectorLayerSource extends AbstractVectorSource { + static createDescriptor( + descriptor: Partial + ): NewVectorLayerSourceDescriptor { + return { + type: SOURCE_TYPES.GEOJSON_FILE, + __featureCollection: getFeatureCollection(descriptor.__featureCollection), + __fields: descriptor.__fields || [], + areResultsTrimmed: + descriptor.areResultsTrimmed !== undefined ? descriptor.areResultsTrimmed : false, + tooltipContent: descriptor.tooltipContent ? descriptor.tooltipContent : null, + name: descriptor.name || 'Features', + }; + } + + constructor(descriptor: Partial, inspectorAdapters?: Adapters) { + const normalizedDescriptor = GeoJsonFileSource.createDescriptor(descriptor); + super(normalizedDescriptor, inspectorAdapters); + } + + _getFields(): InlineFieldDescriptor[] { + const fields = (this._descriptor as NewVectorLayerSourceDescriptor).__fields; + return fields ? fields : []; + } + + createField({ fieldName }: { fieldName: string }): IField { + const fields = this._getFields(); + const descriptor: InlineFieldDescriptor | undefined = fields.find((field) => { + return field.name === fieldName; + }); + + if (!descriptor) { + throw new Error( + `Cannot find corresponding field ${fieldName} in __fields array ${JSON.stringify( + this._getFields() + )} ` + ); + } + return new InlineField({ + fieldName: descriptor.name, + source: this, + origin: FIELD_ORIGIN.SOURCE, + dataType: descriptor.type, + }); + } + + async getFields(): Promise { + const fields = this._getFields(); + return fields.map((field: InlineFieldDescriptor) => { + return new InlineField({ + fieldName: field.name, + source: this, + origin: FIELD_ORIGIN.SOURCE, + dataType: field.type, + }); + }); + } + + isBoundsAware(): boolean { + return true; + } + + async getBoundsForFilters( + boundsFilters: BoundsFilters, + registerCancelCallback: (callback: () => void) => void + ): Promise { + const featureCollection = (this._descriptor as NewVectorLayerSourceDescriptor).__featureCollection; + return getFeatureCollectionBounds(featureCollection, false); + } + + async getGeoJsonWithMeta(): Promise { + return { + data: (this._descriptor as NewVectorLayerSourceDescriptor).__featureCollection, + meta: {}, + }; + } + + async getDisplayName() { + return (this._descriptor as NewVectorLayerSourceDescriptor).name; + } + + canFormatFeatureProperties() { + return true; + } + + getSourceTooltipContent() { + console.log('getSourceTooltipContent not implemented for new vector layer source'); + return undefined; + } +} + +registerSource({ + ConstructorFunction: NewVectorLayerSource, + type: SOURCE_TYPES.NEW_VECTOR_LAYER, +}); diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx new file mode 100644 index 00000000000000..e5c069385bdc03 --- /dev/null +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { Component } from 'react'; +import { Map as MbMap } from 'mapbox-gl'; +import { i18n } from '@kbn/i18n'; +import { Feature } from 'geojson'; +import { DrawState } from '../../../../../common/descriptor_types'; +import { getToasts } from '../../../../kibana_services'; +import { DrawControl } from '../draw_control'; + +export interface Props { + disableDrawState: () => void; + drawState?: DrawState; + mbMap: MbMap; +} + +export class DrawFeatureControl extends Component { + _onDraw = async (e: { features: Feature[] }) => { + try { + console.log(e); + } catch (error) { + getToasts().addWarning( + i18n.translate('xpack.maps.drawFeatureControl.unableToCreatFilter', { + defaultMessage: `Unable to create feature, error: '{errorMsg}'.`, + values: { + errorMsg: error.message, + }, + }) + ); + } finally { + this.props.disableDrawState(); + } + }; + + render() { + return ( + + ); + } +} diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts new file mode 100644 index 00000000000000..f1274978c18b2a --- /dev/null +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { AnyAction } from 'redux'; +import { ThunkDispatch } from 'redux-thunk'; +import { connect } from 'react-redux'; +import { DrawFeatureControl } from './draw_feature_control'; +import { updateDrawState } from '../../../../actions'; +import { getDrawState, isDrawingFilter } from '../../../../selectors/map_selectors'; +import { MapStoreState } from '../../../../reducers/store'; + +function mapStateToProps(state: MapStoreState) { + return { + isDrawingFilter: isDrawingFilter(state), + drawState: getDrawState(state), + }; +} + +function mapDispatchToProps(dispatch: ThunkDispatch) { + return { + disableDrawState() { + dispatch(updateDrawState(null)); + }, + }; +} + +const connected = connect(mapStateToProps, mapDispatchToProps)(DrawFeatureControl); +export { connected as DrawFeatureControl }; diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/index.ts b/x-pack/plugins/maps/public/connected_components/mb_map/index.ts index 2c92f67bd74101..32efb54b71c44c 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/index.ts +++ b/x-pack/plugins/maps/public/connected_components/mb_map/index.ts @@ -42,6 +42,7 @@ function mapStateToProps(state: MapStoreState) { inspectorAdapters: getInspectorAdapters(state), scrollZoom: getScrollZoom(state), isFullScreen: getIsFullScreen(state), + editModeActive: true, }; } diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/mb_map.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/mb_map.tsx index 5e4c3c9b1981fa..7fbf33330c8924 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/mb_map.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/mb_map.tsx @@ -42,6 +42,7 @@ import { GeoFieldWithIndex } from '../../components/geo_field_with_index'; import { RenderToolTipContent } from '../../classes/tooltips/tooltip_property'; import { MapExtentState } from '../../actions'; import { TileStatusTracker } from './tile_status_tracker'; +import { DrawFeatureControl } from './draw_control/draw_feature_control'; // @ts-expect-error import mbRtlPlugin from '!!file-loader!@mapbox/mapbox-gl-rtl-text/mapbox-gl-rtl-text.min.js'; // @ts-expect-error @@ -58,6 +59,7 @@ export interface Props { goto?: Goto | null; inspectorAdapters: Adapters; isFullScreen: boolean; + editModeActive: boolean; scrollZoom: boolean; extentChanged: (mapExtentState: MapExtentState) => void; onMapReady: (mapExtentState: MapExtentState) => void; @@ -413,12 +415,17 @@ export class MBMap extends Component { }; render() { - let drawControl; + let drawFilterControl; + let drawFeatureControl; let tooltipControl; let scaleControl; if (this.state.mbMap) { - drawControl = this.props.addFilters ? ( - + drawFilterControl = + !this.props.editModeActive && this.props.addFilters ? ( + + ) : null; + drawFeatureControl = this.props.editModeActive ? ( + ) : null; tooltipControl = !this.props.settings.disableTooltipControl ? ( { ref={this._setContainerRef} data-test-subj="mapContainer" > - {drawControl} + {drawFilterControl} + {drawFeatureControl} {scaleControl} {tooltipControl} diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.tsx index 9318774fe616bc..18229efd230822 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.tsx @@ -9,10 +9,11 @@ import React, { Component } from 'react'; import { EuiButtonIcon, EuiPopover, - EuiContextMenu, + EuiContextMenuPanel, EuiFlexGroup, EuiFlexItem, EuiButton, + EuiContextMenuItem, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; @@ -20,36 +21,20 @@ import { ActionExecutionContext, Action } from 'src/plugins/ui_actions/public'; import { DRAW_TYPE, ES_GEO_FIELD_TYPE, ES_SPATIAL_RELATIONS } from '../../../../common/constants'; // @ts-expect-error import { GeometryFilterForm } from '../../../components/geometry_filter_form'; -import { DistanceFilterForm } from '../../../components/distance_filter_form'; import { GeoFieldWithIndex } from '../../../components/geo_field_with_index'; import { DrawState } from '../../../../common/descriptor_types'; -const DRAW_SHAPE_LABEL = i18n.translate('xpack.maps.toolbarOverlay.drawShapeLabel', { - defaultMessage: 'Draw shape to filter data', -}); - -const DRAW_BOUNDS_LABEL = i18n.translate('xpack.maps.toolbarOverlay.drawBoundsLabel', { - defaultMessage: 'Draw bounds to filter data', -}); - -const DRAW_DISTANCE_LABEL = i18n.translate('xpack.maps.toolbarOverlay.drawDistanceLabel', { - defaultMessage: 'Draw distance to filter data', -}); - -const DRAW_SHAPE_LABEL_SHORT = i18n.translate('xpack.maps.toolbarOverlay.drawShapeLabelShort', { +const DRAW_SHAPE = i18n.translate('xpack.maps.toolbarOverlay.drawShapeLabelShort', { defaultMessage: 'Draw shape', }); -const DRAW_BOUNDS_LABEL_SHORT = i18n.translate('xpack.maps.toolbarOverlay.drawBoundsLabelShort', { +const DRAW_BOUNDS = i18n.translate('xpack.maps.toolbarOverlay.drawBoundsLabelShort', { defaultMessage: 'Draw bounds', }); -const DRAW_DISTANCE_LABEL_SHORT = i18n.translate( - 'xpack.maps.toolbarOverlay.drawDistanceLabelShort', - { - defaultMessage: 'Draw distance', - } -); +const DRAW_DISTANCE = i18n.translate('xpack.maps.toolbarOverlay.drawDistanceLabel', { + defaultMessage: 'Draw distance', +}); export interface Props { cancelDraw: () => void; @@ -79,155 +64,6 @@ export class FeatureEditControl extends Component { this.setState({ isPopoverOpen: false }); }; - _initiateShapeDraw = (options: { - actionId: string; - geometryLabel: string; - indexPatternId: string; - geoFieldName: string; - geoFieldType: ES_GEO_FIELD_TYPE; - relation: ES_SPATIAL_RELATIONS; - }) => { - this.props.initiateDraw({ - drawType: DRAW_TYPE.POLYGON, - ...options, - }); - this._closePopover(); - }; - - _initiateBoundsDraw = (options: { - actionId: string; - geometryLabel: string; - indexPatternId: string; - geoFieldName: string; - geoFieldType: ES_GEO_FIELD_TYPE; - relation: ES_SPATIAL_RELATIONS; - }) => { - this.props.initiateDraw({ - drawType: DRAW_TYPE.BOUNDS, - ...options, - }); - this._closePopover(); - }; - - _initiateDistanceDraw = (options: { - actionId: string; - filterLabel: string; - indexPatternId: string; - geoFieldName: string; - }) => { - this.props.initiateDraw({ - drawType: DRAW_TYPE.DISTANCE, - ...options, - }); - this._closePopover(); - }; - - _getDrawPanels() { - const tools = [ - { - name: DRAW_SHAPE_LABEL, - panel: 1, - }, - { - name: DRAW_BOUNDS_LABEL, - panel: 2, - }, - ]; - - const hasGeoPoints = this.props.geoFields.some(({ geoFieldType }) => { - return geoFieldType === ES_GEO_FIELD_TYPE.GEO_POINT; - }); - if (hasGeoPoints) { - tools.push({ - name: DRAW_DISTANCE_LABEL, - panel: 3, - }); - } - - return [ - { - id: 0, - title: i18n.translate('xpack.maps.toolbarOverlay.tools.toolbarTitle', { - defaultMessage: 'Tools', - }), - items: tools, - }, - { - id: 1, - title: DRAW_SHAPE_LABEL_SHORT, - content: ( - - ), - }, - { - id: 2, - title: DRAW_BOUNDS_LABEL_SHORT, - content: ( - - ), - }, - { - id: 3, - title: DRAW_DISTANCE_LABEL_SHORT, - content: ( - { - return geoFieldType === ES_GEO_FIELD_TYPE.GEO_POINT; - })} - getFilterActions={this.props.getFilterActions} - getActionContext={this.props.getActionContext} - onSubmit={this._initiateDistanceDraw} - /> - ), - }, - ]; - } - - _renderToolsButton() { - return ( - - ); - } - _renderFeatureEditButton() { return ( { panelPaddingSize="none" anchorPosition="leftUp" > - + console.log('Polygon!')}> + Polygon + , + console.log('Rectangle')}> + Rectangle + , + console.log('Polyline')}> + Polyline + , + console.log('Point')}> + Point + , + ]} + /> ); - if (!this.props.isDrawingFilter) { - return featureEditControlPopoverButton; - } - return ( {featureEditControlPopoverButton} - - - - - + {/**/} + {/* */} + {/* */} + {/* */} + {/**/} ); } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.js b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.js index 832212478c3d12..074cb19ad5dfd5 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.js +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.js @@ -31,10 +31,7 @@ export class ToolbarOverlay extends React.Component { } _renderFeatureEditControl() { - const { addFilters, geoFields, getFilterActions, getActionContext } = this.props; - if (!addFilters || !geoFields.length) { - return null; - } + const { geoFields, getFilterActions, getActionContext } = this.props; return ( From 26ec7bf2e10cedd63adf0eddec1442b65d97b7e5 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Thu, 1 Apr 2021 15:06:59 -0600 Subject: [PATCH 003/103] Redux integrated --- x-pack/plugins/maps/common/constants.ts | 1 + .../public/actions/map_action_constants.ts | 1 + .../maps/public/actions/map_actions.ts | 13 ++++++++- .../feature_edit_control.tsx | 27 +++++++------------ .../feature_edit_control/index.ts | 10 +++---- .../plugins/maps/public/reducers/map/map.ts | 10 +++++++ .../plugins/maps/public/reducers/map/types.ts | 3 ++- 7 files changed, 41 insertions(+), 24 deletions(-) diff --git a/x-pack/plugins/maps/common/constants.ts b/x-pack/plugins/maps/common/constants.ts index c4c7a60c56fe65..a21d664a80fab8 100644 --- a/x-pack/plugins/maps/common/constants.ts +++ b/x-pack/plugins/maps/common/constants.ts @@ -156,6 +156,7 @@ export enum DRAW_TYPE { BOUNDS = 'BOUNDS', DISTANCE = 'DISTANCE', POLYGON = 'POLYGON', + POINT = 'POINT', } export const AGG_DELIMITER = '_of_'; diff --git a/x-pack/plugins/maps/public/actions/map_action_constants.ts b/x-pack/plugins/maps/public/actions/map_action_constants.ts index b9951af71154d2..77ae985908ba96 100644 --- a/x-pack/plugins/maps/public/actions/map_action_constants.ts +++ b/x-pack/plugins/maps/public/actions/map_action_constants.ts @@ -37,6 +37,7 @@ 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_OPEN_TOOLTIPS = 'SET_OPEN_TOOLTIPS'; export const UPDATE_DRAW_STATE = 'UPDATE_DRAW_STATE'; +export const UPDATE_DRAW_FEATURE_STATE = 'UPDATE_DRAW_FEATURE_STATE'; export const SET_SCROLL_ZOOM = 'SET_SCROLL_ZOOM'; export const SET_MAP_INIT_ERROR = 'SET_MAP_INIT_ERROR'; export const SET_WAITING_FOR_READY_HIDDEN_LAYERS = 'SET_WAITING_FOR_READY_HIDDEN_LAYERS'; diff --git a/x-pack/plugins/maps/public/actions/map_actions.ts b/x-pack/plugins/maps/public/actions/map_actions.ts index 9682306852ba92..14fc259b95f220 100644 --- a/x-pack/plugins/maps/public/actions/map_actions.ts +++ b/x-pack/plugins/maps/public/actions/map_actions.ts @@ -10,8 +10,8 @@ import { AnyAction, Dispatch } from 'redux'; import { ThunkDispatch } from 'redux-thunk'; import turfBboxPolygon from '@turf/bbox-polygon'; import turfBooleanContains from '@turf/boolean-contains'; - import { Filter, Query, TimeRange } from 'src/plugins/data/public'; +import { DRAW_TYPE } from '../../common/constants'; import { MapStoreState } from '../reducers/store'; import { getDataFilters, @@ -43,6 +43,7 @@ import { TRACK_MAP_SETTINGS, TRIGGER_REFRESH_TIMER, UPDATE_DRAW_STATE, + UPDATE_DRAW_FEATURE_STATE, UPDATE_MAP_SETTING, } from './map_action_constants'; import { autoFitToBounds, syncDataForAllLayers } from './data_request_actions'; @@ -323,3 +324,13 @@ export function updateDrawState(drawState: DrawState | null) { }); }; } + +export function updateDrawFeatureState(drawFeatureState: DRAW_TYPE) { + return (dispatch: Dispatch) => { + dispatch({ type: SET_OPEN_TOOLTIPS, openTooltips: [] }); + dispatch({ + type: UPDATE_DRAW_FEATURE_STATE, + drawFeatureState, + }); + }; +} diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.tsx index 18229efd230822..4857fbcc53d256 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.tsx @@ -8,21 +8,17 @@ import React, { Component } from 'react'; import { EuiButtonIcon, - EuiPopover, + EuiContextMenuItem, EuiContextMenuPanel, EuiFlexGroup, EuiFlexItem, - EuiButton, - EuiContextMenuItem, + EuiPopover, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n/react'; -import { ActionExecutionContext, Action } from 'src/plugins/ui_actions/public'; -import { DRAW_TYPE, ES_GEO_FIELD_TYPE, ES_SPATIAL_RELATIONS } from '../../../../common/constants'; +import { DRAW_TYPE } from '../../../../common/constants'; // @ts-expect-error import { GeometryFilterForm } from '../../../components/geometry_filter_form'; import { GeoFieldWithIndex } from '../../../components/geo_field_with_index'; -import { DrawState } from '../../../../common/descriptor_types'; const DRAW_SHAPE = i18n.translate('xpack.maps.toolbarOverlay.drawShapeLabelShort', { defaultMessage: 'Draw shape', @@ -39,10 +35,7 @@ const DRAW_DISTANCE = i18n.translate('xpack.maps.toolbarOverlay.drawDistanceLabe export interface Props { cancelDraw: () => void; geoFields: GeoFieldWithIndex[]; - initiateDraw: (drawState: DrawState) => void; - isDrawingFilter: boolean; - getFilterActions?: () => Promise; - getActionContext?: () => ActionExecutionContext; + initiateDraw: (drawFeatureState: DRAW_TYPE) => void; } interface State { @@ -94,16 +87,16 @@ export class FeatureEditControl extends Component { > console.log('Polygon!')}> + this.props.initiateDraw(DRAW_TYPE.POLYGON)}> Polygon , - console.log('Rectangle')}> + this.props.initiateDraw(DRAW_TYPE.BOUNDS)}> Rectangle , - console.log('Polyline')}> + this.props.initiateDraw(DRAW_TYPE.DISTANCE)}> Polyline , - console.log('Point')}> + this.props.initiateDraw(DRAW_TYPE.POINT)}> Point , ]} @@ -114,14 +107,14 @@ export class FeatureEditControl extends Component { return ( {featureEditControlPopoverButton} - {/**/} + {/* */} {/* */} {/* */} {/* */} - {/**/} + {/* */} ); } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/index.ts index da0a33c652c2a6..904421a0012171 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/index.ts @@ -10,9 +10,9 @@ import { ThunkDispatch } from 'redux-thunk'; import { connect } from 'react-redux'; import { FeatureEditControl } from './feature_edit_control'; import { isDrawingFilter } from '../../../selectors/map_selectors'; -import { updateDrawState } from '../../../actions'; +import { updateDrawFeatureState } from '../../../actions'; import { MapStoreState } from '../../../reducers/store'; -import { DrawState } from '../../../../common/descriptor_types'; +import { DRAW_TYPE } from '../../../../common'; function mapStateToProps(state: MapStoreState) { return { @@ -22,11 +22,11 @@ function mapStateToProps(state: MapStoreState) { function mapDispatchToProps(dispatch: ThunkDispatch) { return { - initiateDraw: (drawState: DrawState) => { - dispatch(updateDrawState(drawState)); + initiateDraw: (drawFeatureState: DRAW_TYPE) => { + dispatch(updateDrawFeatureState(drawFeatureState)); }, cancelDraw: () => { - dispatch(updateDrawState(null)); + dispatch(updateDrawFeatureState(null)); }, }; } diff --git a/x-pack/plugins/maps/public/reducers/map/map.ts b/x-pack/plugins/maps/public/reducers/map/map.ts index 9573f1ac80c6b5..e611cb079ffe46 100644 --- a/x-pack/plugins/maps/public/reducers/map/map.ts +++ b/x-pack/plugins/maps/public/reducers/map/map.ts @@ -45,6 +45,7 @@ import { ROLLBACK_MAP_SETTINGS, TRACK_MAP_SETTINGS, UPDATE_MAP_SETTING, + UPDATE_DRAW_FEATURE_STATE, } from '../../actions'; import { getDefaultMapSettings } from './default_map_settings'; @@ -76,6 +77,7 @@ export const DEFAULT_MAP_STATE: MapState = { refreshConfig: undefined, refreshTimerLastTriggeredAt: undefined, drawState: undefined, + drawFeatureState: undefined, }, selectedLayerId: null, layerList: [], @@ -94,6 +96,14 @@ export function map(state: MapState = DEFAULT_MAP_STATE, action: any) { drawState: action.drawState, }, }; + case UPDATE_DRAW_FEATURE_STATE: + return { + ...state, + mapState: { + ...state.mapState, + drawFeatureState: action.drawFeatureState, + }, + }; case REMOVE_TRACKED_LAYER_STATE: return removeTrackedLayerState(state, action.layerId); case TRACK_CURRENT_LAYER_STATE: diff --git a/x-pack/plugins/maps/public/reducers/map/types.ts b/x-pack/plugins/maps/public/reducers/map/types.ts index 6b10b4a66fb611..2531f7ee344cd5 100644 --- a/x-pack/plugins/maps/public/reducers/map/types.ts +++ b/x-pack/plugins/maps/public/reducers/map/types.ts @@ -17,7 +17,7 @@ import { MapRefreshConfig, TooltipState, } from '../../../common/descriptor_types'; -import { INITIAL_LOCATION } from '../../../common/constants'; +import { DRAW_TYPE, INITIAL_LOCATION } from '../../../common/constants'; import { Filter, TimeRange } from '../../../../../../src/plugins/data/public'; export type MapContext = { @@ -36,6 +36,7 @@ export type MapContext = { refreshConfig?: MapRefreshConfig; refreshTimerLastTriggeredAt?: string; drawState?: DrawState; + drawFeatureState?: DRAW_TYPE; searchSessionId?: string; searchSessionMapBuffer?: MapExtent; }; From 8ca809aeb24c109ca7946937878fd19f5cc7da1f Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Thu, 1 Apr 2021 15:36:09 -0600 Subject: [PATCH 004/103] Single shape drawing --- .../draw_feature_control/draw_feature_control.tsx | 6 +++--- .../mb_map/draw_control/draw_feature_control/index.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx index e5c069385bdc03..49e4f3009775f7 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx @@ -9,13 +9,13 @@ import React, { Component } from 'react'; import { Map as MbMap } from 'mapbox-gl'; import { i18n } from '@kbn/i18n'; import { Feature } from 'geojson'; -import { DrawState } from '../../../../../common/descriptor_types'; import { getToasts } from '../../../../kibana_services'; import { DrawControl } from '../draw_control'; +import { DRAW_TYPE } from "../../../../../common"; export interface Props { disableDrawState: () => void; - drawState?: DrawState; + drawType: DRAW_TYPE; mbMap: MbMap; } @@ -40,7 +40,7 @@ export class DrawFeatureControl extends Component { render() { return ( diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts index f1274978c18b2a..615d0d8dcf6c98 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts @@ -16,7 +16,7 @@ import { MapStoreState } from '../../../../reducers/store'; function mapStateToProps(state: MapStoreState) { return { isDrawingFilter: isDrawingFilter(state), - drawState: getDrawState(state), + drawType: state.map.mapState.drawFeatureState, }; } From b8eea96d4bc6901d2a55dec0955f4767a4525032 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Fri, 2 Apr 2021 11:11:57 -0600 Subject: [PATCH 005/103] Keep draw mode active --- x-pack/plugins/maps/public/actions/map_actions.ts | 6 ++++-- .../mb_map/draw_control/draw_control.tsx | 3 ++- .../draw_feature_control/draw_feature_control.tsx | 3 ++- .../mb_map/draw_control/draw_feature_control/index.ts | 6 ++---- .../draw_filter_control/draw_filter_control.tsx | 1 + 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/maps/public/actions/map_actions.ts b/x-pack/plugins/maps/public/actions/map_actions.ts index 14fc259b95f220..33f8806db28a5b 100644 --- a/x-pack/plugins/maps/public/actions/map_actions.ts +++ b/x-pack/plugins/maps/public/actions/map_actions.ts @@ -325,9 +325,11 @@ export function updateDrawState(drawState: DrawState | null) { }; } -export function updateDrawFeatureState(drawFeatureState: DRAW_TYPE) { +export function updateDrawFeatureState(drawFeatureState: DRAW_TYPE | null) { return (dispatch: Dispatch) => { - dispatch({ type: SET_OPEN_TOOLTIPS, openTooltips: [] }); + if (drawFeatureState !== null) { + dispatch({ type: SET_OPEN_TOOLTIPS, openTooltips: [] }); + } dispatch({ type: UPDATE_DRAW_FEATURE_STATE, drawFeatureState, diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx index a1bea4a8e93dcd..545389a3e96fc5 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx @@ -28,6 +28,7 @@ export interface Props { drawType?: DRAW_TYPE; onDraw: (event: { features: Feature[] }) => void; mbMap: MbMap; + drawActive: boolean; } export class DrawControl extends Component { @@ -58,7 +59,7 @@ export class DrawControl extends Component { return; } - if (this.props.drawType) { + if (this.props.drawActive) { this._updateDrawControl(); } else { this._removeDrawControl(); diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx index 49e4f3009775f7..339dd3dc4ef1de 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx @@ -11,7 +11,7 @@ import { i18n } from '@kbn/i18n'; import { Feature } from 'geojson'; import { getToasts } from '../../../../kibana_services'; import { DrawControl } from '../draw_control'; -import { DRAW_TYPE } from "../../../../../common"; +import { DRAW_TYPE } from '../../../../../common'; export interface Props { disableDrawState: () => void; @@ -43,6 +43,7 @@ export class DrawFeatureControl extends Component { drawType={this.props.drawType} onDraw={this._onDraw} mbMap={this.props.mbMap} + drawActive={true} /> ); } diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts index 615d0d8dcf6c98..5b4c579f1dbf74 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts @@ -9,13 +9,11 @@ import { AnyAction } from 'redux'; import { ThunkDispatch } from 'redux-thunk'; import { connect } from 'react-redux'; import { DrawFeatureControl } from './draw_feature_control'; -import { updateDrawState } from '../../../../actions'; -import { getDrawState, isDrawingFilter } from '../../../../selectors/map_selectors'; +import { updateDrawFeatureState } from '../../../../actions'; import { MapStoreState } from '../../../../reducers/store'; function mapStateToProps(state: MapStoreState) { return { - isDrawingFilter: isDrawingFilter(state), drawType: state.map.mapState.drawFeatureState, }; } @@ -23,7 +21,7 @@ function mapStateToProps(state: MapStoreState) { function mapDispatchToProps(dispatch: ThunkDispatch) { return { disableDrawState() { - dispatch(updateDrawState(null)); + dispatch(updateDrawFeatureState(null)); }, }; } diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_filter_control/draw_filter_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_filter_control/draw_filter_control.tsx index c0cbd3566ca8fd..9e13f7afb6cc3d 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_filter_control/draw_filter_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_filter_control/draw_filter_control.tsx @@ -120,6 +120,7 @@ export class DrawFilterControl extends Component { } onDraw={this._onDraw} mbMap={this.props.mbMap} + drawActive={!!(this.props.drawState && this.props.drawState.drawType)} /> ); } From b4f3af0c9052f39aebb34578b1720028187378f0 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Mon, 5 Apr 2021 07:23:05 -0600 Subject: [PATCH 006/103] Trigger editing through add layer wizard --- .../public/actions/map_action_constants.ts | 1 + .../maps/public/actions/map_actions.ts | 8 +++++ .../classes/layers/load_layer_wizards.ts | 2 ++ .../layers/new_vector_layer_wizard/config.tsx | 27 ++++++++++++++++ .../layers/new_vector_layer_wizard/index.ts | 27 ++++++++++++++++ .../layers/new_vector_layer_wizard/wizard.tsx | 32 +++++++++++++++++++ .../new_vector_layer_source.ts | 9 +++--- .../connected_components/mb_map/index.ts | 2 +- .../plugins/maps/public/reducers/map/map.ts | 10 ++++++ .../plugins/maps/public/reducers/map/types.ts | 1 + 10 files changed, 114 insertions(+), 5 deletions(-) create mode 100644 x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/config.tsx create mode 100644 x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/index.ts create mode 100644 x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx diff --git a/x-pack/plugins/maps/public/actions/map_action_constants.ts b/x-pack/plugins/maps/public/actions/map_action_constants.ts index 77ae985908ba96..31e0f8a534bd4e 100644 --- a/x-pack/plugins/maps/public/actions/map_action_constants.ts +++ b/x-pack/plugins/maps/public/actions/map_action_constants.ts @@ -37,6 +37,7 @@ 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_OPEN_TOOLTIPS = 'SET_OPEN_TOOLTIPS'; export const UPDATE_DRAW_STATE = 'UPDATE_DRAW_STATE'; +export const UPDATE_EDIT_MODE = 'UPDATE_EDIT_MODE'; export const UPDATE_DRAW_FEATURE_STATE = 'UPDATE_DRAW_FEATURE_STATE'; export const SET_SCROLL_ZOOM = 'SET_SCROLL_ZOOM'; export const SET_MAP_INIT_ERROR = 'SET_MAP_INIT_ERROR'; diff --git a/x-pack/plugins/maps/public/actions/map_actions.ts b/x-pack/plugins/maps/public/actions/map_actions.ts index 33f8806db28a5b..332342daaa6dce 100644 --- a/x-pack/plugins/maps/public/actions/map_actions.ts +++ b/x-pack/plugins/maps/public/actions/map_actions.ts @@ -44,6 +44,7 @@ import { TRIGGER_REFRESH_TIMER, UPDATE_DRAW_STATE, UPDATE_DRAW_FEATURE_STATE, + UPDATE_EDIT_MODE, UPDATE_MAP_SETTING, } from './map_action_constants'; import { autoFitToBounds, syncDataForAllLayers } from './data_request_actions'; @@ -336,3 +337,10 @@ export function updateDrawFeatureState(drawFeatureState: DRAW_TYPE | null) { }); }; } + +export function updateEditMode(isActive: boolean) { + return { + type: UPDATE_EDIT_MODE, + isActive, + }; +} diff --git a/x-pack/plugins/maps/public/classes/layers/load_layer_wizards.ts b/x-pack/plugins/maps/public/classes/layers/load_layer_wizards.ts index 804352f5bede72..574d86f0082e8c 100644 --- a/x-pack/plugins/maps/public/classes/layers/load_layer_wizards.ts +++ b/x-pack/plugins/maps/public/classes/layers/load_layer_wizards.ts @@ -30,6 +30,7 @@ import { mvtVectorSourceWizardConfig } from '../sources/mvt_single_layer_vector_ import { ObservabilityLayerWizardConfig } from './solution_layers/observability'; import { SecurityLayerWizardConfig } from './solution_layers/security'; import { choroplethLayerWizardConfig } from './choropleth_layer_wizard'; +import { newVectorLayerWizardConfig } from './new_vector_layer_wizard/config'; let registered = false; export function registerLayerWizards() { @@ -39,6 +40,7 @@ export function registerLayerWizards() { // Registration order determines display order registerLayerWizard(uploadLayerWizardConfig); + registerLayerWizard(newVectorLayerWizardConfig); registerLayerWizard(esDocumentsLayerWizardConfig); // @ts-ignore registerLayerWizard(choroplethLayerWizardConfig); diff --git a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/config.tsx b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/config.tsx new file mode 100644 index 00000000000000..da4d762fffa655 --- /dev/null +++ b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/config.tsx @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; +import React from 'react'; +import { LayerWizard, RenderWizardArguments } from '../../layers/layer_wizard_registry'; +import { NewVectorLayerEditor } from './index'; +import { DocumentsLayerIcon } from '../../layers/icons/documents_layer_icon'; + +export const newVectorLayerWizardConfig: LayerWizard = { + categories: [], + description: i18n.translate('xpack.maps.newVectorLayerWizard.description', { + defaultMessage: 'Draw points & shapes and save in Elasticsearch', + }), + icon: DocumentsLayerIcon, + prerequisiteSteps: [], + renderWizard: (renderWizardArguments: RenderWizardArguments) => { + return ; + }, + title: i18n.translate('xpack.maps.newVectorLayerWizard.title', { + defaultMessage: 'Draw new vector layer', + }), +}; diff --git a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/index.ts b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/index.ts new file mode 100644 index 00000000000000..e4829bdeb0484b --- /dev/null +++ b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/index.ts @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ThunkDispatch } from 'redux-thunk'; +import { AnyAction } from 'redux'; +import { connect } from 'react-redux'; +import { MapStoreState } from '../../../reducers/store'; +import { NewVectorLayerEditor } from './wizard'; +import { updateEditMode } from '../../../actions'; + +function mapStateToProps(state: MapStoreState) { + return {}; +} + +function mapDispatchToProps(dispatch: ThunkDispatch) { + return { + setEditModeActive: () => dispatch(updateEditMode(true)), + setEditModeInActive: () => dispatch(updateEditMode(false)), + }; +} + +const connected = connect(mapStateToProps, mapDispatchToProps)(NewVectorLayerEditor); +export { connected as NewVectorLayerEditor }; diff --git a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx new file mode 100644 index 00000000000000..4c402c21440381 --- /dev/null +++ b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { Component } from 'react'; +import { EuiPanel } from '@elastic/eui'; + +interface Props { + setEditModeActive: () => void; + setEditModeInActive: () => void; +} + +export class NewVectorLayerEditor extends Component { + componentDidMount() { + this.props.setEditModeActive(); + } + + componentWillUnmount() { + this.props.setEditModeInActive(); + } + + render() { + return ( + +
Draw shapes
+
+ ); + } +} diff --git a/x-pack/plugins/maps/public/classes/sources/new_vector_layer_source/new_vector_layer_source.ts b/x-pack/plugins/maps/public/classes/sources/new_vector_layer_source/new_vector_layer_source.ts index 7154b2993965bd..99e7adaccaf039 100644 --- a/x-pack/plugins/maps/public/classes/sources/new_vector_layer_source/new_vector_layer_source.ts +++ b/x-pack/plugins/maps/public/classes/sources/new_vector_layer_source/new_vector_layer_source.ts @@ -56,7 +56,7 @@ export class NewVectorLayerSource extends AbstractVectorSource { } constructor(descriptor: Partial, inspectorAdapters?: Adapters) { - const normalizedDescriptor = GeoJsonFileSource.createDescriptor(descriptor); + const normalizedDescriptor = NewVectorLayerSource.createDescriptor(descriptor); super(normalizedDescriptor, inspectorAdapters); } @@ -78,7 +78,7 @@ export class NewVectorLayerSource extends AbstractVectorSource { )} ` ); } - return new InlineField({ + return new InlineField({ fieldName: descriptor.name, source: this, origin: FIELD_ORIGIN.SOURCE, @@ -89,7 +89,7 @@ export class NewVectorLayerSource extends AbstractVectorSource { async getFields(): Promise { const fields = this._getFields(); return fields.map((field: InlineFieldDescriptor) => { - return new InlineField({ + return new InlineField({ fieldName: field.name, source: this, origin: FIELD_ORIGIN.SOURCE, @@ -106,7 +106,8 @@ export class NewVectorLayerSource extends AbstractVectorSource { boundsFilters: BoundsFilters, registerCancelCallback: (callback: () => void) => void ): Promise { - const featureCollection = (this._descriptor as NewVectorLayerSourceDescriptor).__featureCollection; + const featureCollection = (this._descriptor as NewVectorLayerSourceDescriptor) + .__featureCollection; return getFeatureCollectionBounds(featureCollection, false); } diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/index.ts b/x-pack/plugins/maps/public/connected_components/mb_map/index.ts index 32efb54b71c44c..4a1b822f98066f 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/index.ts +++ b/x-pack/plugins/maps/public/connected_components/mb_map/index.ts @@ -42,7 +42,7 @@ function mapStateToProps(state: MapStoreState) { inspectorAdapters: getInspectorAdapters(state), scrollZoom: getScrollZoom(state), isFullScreen: getIsFullScreen(state), - editModeActive: true, + editModeActive: state.map.mapState.editModeActive, }; } diff --git a/x-pack/plugins/maps/public/reducers/map/map.ts b/x-pack/plugins/maps/public/reducers/map/map.ts index e611cb079ffe46..238b10f9244d6c 100644 --- a/x-pack/plugins/maps/public/reducers/map/map.ts +++ b/x-pack/plugins/maps/public/reducers/map/map.ts @@ -46,6 +46,7 @@ import { TRACK_MAP_SETTINGS, UPDATE_MAP_SETTING, UPDATE_DRAW_FEATURE_STATE, + UPDATE_EDIT_MODE, } from '../../actions'; import { getDefaultMapSettings } from './default_map_settings'; @@ -78,6 +79,7 @@ export const DEFAULT_MAP_STATE: MapState = { refreshTimerLastTriggeredAt: undefined, drawState: undefined, drawFeatureState: undefined, + editModeActive: undefined, }, selectedLayerId: null, layerList: [], @@ -104,6 +106,14 @@ export function map(state: MapState = DEFAULT_MAP_STATE, action: any) { drawFeatureState: action.drawFeatureState, }, }; + case UPDATE_EDIT_MODE: + return { + ...state, + mapState: { + ...state.mapState, + editModeActive: action.isActive, + }, + }; case REMOVE_TRACKED_LAYER_STATE: return removeTrackedLayerState(state, action.layerId); case TRACK_CURRENT_LAYER_STATE: diff --git a/x-pack/plugins/maps/public/reducers/map/types.ts b/x-pack/plugins/maps/public/reducers/map/types.ts index 2531f7ee344cd5..7e20f3b6602466 100644 --- a/x-pack/plugins/maps/public/reducers/map/types.ts +++ b/x-pack/plugins/maps/public/reducers/map/types.ts @@ -37,6 +37,7 @@ export type MapContext = { refreshTimerLastTriggeredAt?: string; drawState?: DrawState; drawFeatureState?: DRAW_TYPE; + editModeActive?: boolean; searchSessionId?: string; searchSessionMapBuffer?: MapExtent; }; From 001c87f7c28285a15dbc3babcb3521966dcd4ea2 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Mon, 5 Apr 2021 09:31:57 -0600 Subject: [PATCH 007/103] Add index checking utils --- .../utils/http_service.js | 52 ++++++ .../utils/indexing_service.js | 41 +++++ .../layers/new_vector_layer_wizard/wizard.tsx | 157 +++++++++++++++++- 3 files changed, 245 insertions(+), 5 deletions(-) create mode 100644 x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/utils/http_service.js create mode 100644 x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/utils/indexing_service.js diff --git a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/utils/http_service.js b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/utils/http_service.js new file mode 100644 index 00000000000000..3fe736f7e67024 --- /dev/null +++ b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/utils/http_service.js @@ -0,0 +1,52 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; +import { getHttp } from '../../../../kibana_services'; + +export async function http(options) { + if (!(options && options.url)) { + throw i18n.translate('xpack.layers.newVectorLayerWizard.httpService.noUrl', { + defaultMessage: 'No URL provided', + }); + } + const url = options.url || ''; + const headers = { + 'Content-Type': 'application/json', + ...options.headers, + }; + + const allHeaders = options.headers === undefined ? headers : { ...options.headers, ...headers }; + const body = options.data === undefined ? null : JSON.stringify(options.data); + + const payload = { + method: options.method || 'GET', + headers: allHeaders, + credentials: 'same-origin', + query: options.query, + }; + + if (body !== null) { + payload.body = body; + } + return await doFetch(url, payload); +} + +async function doFetch(url, payload) { + try { + return await getHttp().fetch(url, payload); + } catch (err) { + return { + failures: [ + i18n.translate('xpack.layers.newVectorLayerWizard.httpService.fetchError', { + defaultMessage: 'Error performing fetch: {error}', + values: { error: err.message }, + }), + ], + }; + } +} diff --git a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/utils/indexing_service.js b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/utils/indexing_service.js new file mode 100644 index 00000000000000..a508aaa5ab01ef --- /dev/null +++ b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/utils/indexing_service.js @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { http as httpService } from './http_service'; +import { getSavedObjectsClient } from '../../../../kibana_services'; + +export const getExistingIndexNames = async () => { + const indexes = await httpService({ + url: `/api/index_management/indices`, + method: 'GET', + }); + return indexes ? indexes.map(({ name }) => name) : []; +}; + +export const getExistingIndexPatternNames = async () => { + const indexPatterns = await getSavedObjectsClient() + .find({ + type: 'index-pattern', + fields: ['id', 'title', 'type', 'fields'], + perPage: 10000, + }) + .then(({ savedObjects }) => savedObjects.map((savedObject) => savedObject.get('title'))); + return indexPatterns ? indexPatterns.map(({ name }) => name) : []; +}; + +export function checkIndexPatternValid(name) { + const byteLength = encodeURI(name).split(/%(?:u[0-9A-F]{2})?[0-9A-F]{2}|./).length - 1; + const reg = new RegExp('[\\\\/*?"<>|\\s,#]+'); + const indexPatternInvalid = + byteLength > 255 || // name can't be greater than 255 bytes + name !== name.toLowerCase() || // name should be lowercase + name === '.' || + name === '..' || // name can't be . or .. + name.match(/^[-_+]/) !== null || // name can't start with these chars + name.match(reg) !== null; // name can't contain these chars + return !indexPatternInvalid; +} diff --git a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx index 4c402c21440381..cb3449a416a7f3 100644 --- a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx +++ b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx @@ -5,27 +5,174 @@ * 2.0. */ -import React, { Component } from 'react'; -import { EuiPanel } from '@elastic/eui'; +import React, { ChangeEvent, Component } from 'react'; +import { EuiCallOut, EuiFieldText, EuiFormRow, EuiPanel, EuiSpacer } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { + getExistingIndexNames, + getExistingIndexPatternNames, + checkIndexPatternValid, + // @ts-expect-error +} from './utils/indexing_service'; interface Props { setEditModeActive: () => void; setEditModeInActive: () => void; } -export class NewVectorLayerEditor extends Component { - componentDidMount() { +interface State { + indexName: string; + indexValid: boolean; + indexError: string; + indexNames: string[]; +} + +export class NewVectorLayerEditor extends Component { + state = { + indexName: '', + indexValid: false, + indexError: '', + indexNames: [], + }; + + private _isMounted = false; + + async componentDidMount() { this.props.setEditModeActive(); + this._isMounted = true; + this._loadIndexNames(); } componentWillUnmount() { this.props.setEditModeInActive(); + this._isMounted = false; } + _loadIndexNames = async () => { + const indexNameList = await getExistingIndexNames(); + const indexPatternList = await getExistingIndexPatternNames(); + if (this._isMounted) { + this.setState({ + indexNames: [...indexNameList, ...indexPatternList], + }); + } + }; + + _onIndexNameChange = (indexName: string) => { + let error: string | undefined; + if (this.state.indexNames.includes(indexName)) { + error = i18n.translate( + 'xpack.layers.newVectorLayerWizard.indexSettings.indexNameAlreadyExistsErrorMessage', + { + defaultMessage: 'Index name already exists.', + } + ); + } else if (!checkIndexPatternValid(indexName)) { + error = i18n.translate( + 'xpack.layers.newVectorLayerWizard.indexSettings.indexNameContainsIllegalCharactersErrorMessage', + { + defaultMessage: 'Index name contains illegal characters.', + } + ); + } + }; + + _onIndexNameChangeEvent = (event: ChangeEvent) => { + this.setState({ indexName: event.target.value }); + this._onIndexNameChange(event.target.value); + }; + render() { return ( -
Draw shapes
+ <> + + + + + +
    +
  • + {i18n.translate( + 'xpack.layers.newVectorLayerWizard.indexSettings.guidelines.mustBeNewIndex', + { + defaultMessage: 'Must be a new index', + } + )} +
  • +
  • + {i18n.translate( + 'xpack.layers.newVectorLayerWizard.indexSettings.guidelines.lowercaseOnly', + { + defaultMessage: 'Lowercase only', + } + )} +
  • +
  • + {i18n.translate( + 'xpack.layers.newVectorLayerWizard.indexSettings.guidelines.cannotInclude', + { + defaultMessage: + 'Cannot include \\\\, /, *, ?, ", <, >, |, \ + " " (space character), , (comma), #', + } + )} +
  • +
  • + {i18n.translate( + 'xpack.layers.newVectorLayerWizard.indexSettings.guidelines.cannotStartWith', + { + defaultMessage: 'Cannot start with -, _, +', + } + )} +
  • +
  • + {i18n.translate( + 'xpack.layers.newVectorLayerWizard.indexSettings.guidelines.cannotBe', + { + defaultMessage: 'Cannot be . or ..', + } + )} +
  • +
  • + {i18n.translate( + 'xpack.layers.newVectorLayerWizard.indexSettings.guidelines.length', + { + defaultMessage: + 'Cannot be longer than 255 bytes (note it is bytes, \ + so multi-byte characters will count towards the 255 \ + limit faster)', + } + )} +
  • +
+
+
); } From 95f8f14ae5666461793f89e5118903025f6d70ef Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Mon, 5 Apr 2021 10:19:38 -0600 Subject: [PATCH 008/103] Connect error checking --- .../layers/new_vector_layer_wizard/wizard.tsx | 39 ++++++++++--------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx index cb3449a416a7f3..74665d8826a8a9 100644 --- a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx +++ b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx @@ -22,7 +22,6 @@ interface Props { interface State { indexName: string; - indexValid: boolean; indexError: string; indexNames: string[]; } @@ -30,7 +29,6 @@ interface State { export class NewVectorLayerEditor extends Component { state = { indexName: '', - indexValid: false, indexError: '', indexNames: [], }; @@ -59,21 +57,26 @@ export class NewVectorLayerEditor extends Component { }; _onIndexNameChange = (indexName: string) => { - let error: string | undefined; if (this.state.indexNames.includes(indexName)) { - error = i18n.translate( - 'xpack.layers.newVectorLayerWizard.indexSettings.indexNameAlreadyExistsErrorMessage', - { - defaultMessage: 'Index name already exists.', - } - ); + this.setState({ + indexError: i18n.translate( + 'xpack.layers.newVectorLayerWizard.indexSettings.indexNameAlreadyExistsErrorMessage', + { + defaultMessage: 'Index name already exists.', + } + ), + }); } else if (!checkIndexPatternValid(indexName)) { - error = i18n.translate( - 'xpack.layers.newVectorLayerWizard.indexSettings.indexNameContainsIllegalCharactersErrorMessage', - { - defaultMessage: 'Index name contains illegal characters.', - } - ); + this.setState({ + indexError: i18n.translate( + 'xpack.layers.newVectorLayerWizard.indexSettings.indexNameContainsIllegalCharactersErrorMessage', + { + defaultMessage: 'Index name contains illegal characters.', + } + ), + }); + } else { + this.setState({ indexError: '' }); } }; @@ -93,14 +96,14 @@ export class NewVectorLayerEditor extends Component { defaultMessage: 'Index name', } )} - isInvalid={this.state.indexValid} - error={this.state.indexValid ? [this.state.indexError] : []} + isInvalid={!!this.state.indexError} + error={!!this.state.indexError ? [this.state.indexError] : []} > Date: Mon, 5 Apr 2021 15:14:32 -0600 Subject: [PATCH 009/103] Conditionally show edit toolbar --- .../layers/new_vector_layer_wizard/wizard.tsx | 37 ++++- .../toolbar_overlay/_index.scss | 1 + .../feature_edit_control.tsx | 127 +++++++++--------- .../toolbar_overlay/index.ts | 13 +- .../toolbar_overlay/toolbar_overlay.tsx | 13 +- 5 files changed, 114 insertions(+), 77 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx index 74665d8826a8a9..54a1713a686ba3 100644 --- a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx +++ b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx @@ -5,8 +5,17 @@ * 2.0. */ -import React, { ChangeEvent, Component } from 'react'; -import { EuiCallOut, EuiFieldText, EuiFormRow, EuiPanel, EuiSpacer } from '@elastic/eui'; +import React, { ChangeEvent, Component, Fragment } from 'react'; +import { + EuiButton, + EuiCallOut, + EuiEmptyPrompt, + EuiFieldText, + EuiFormRow, + EuiLoadingSpinner, + EuiPanel, + EuiSpacer, +} from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { getExistingIndexNames, @@ -89,6 +98,24 @@ export class NewVectorLayerEditor extends Component { return ( <> + + {i18n.translate('xpack.layers.newVectorLayerWizard.drawVectorShapes', { + defaultMessage: 'Draw vector shapes', + })} + + } + body={ + +

+ {i18n.translate('xpack.layers.newVectorLayerWizard.vectorEditorDescription', { + defaultMessage: `Using the editor on the left side of the map, draw and edit the points and shapes to be indexed and added to the map.`, + })} +

+
+ } + /> { { defaultMessage: 'Cannot include \\\\, /, *, ?, ", <, >, |, \ - " " (space character), , (comma), #', + " " (space character), , (comma), #', } )} @@ -168,8 +195,8 @@ export class NewVectorLayerEditor extends Component { { defaultMessage: 'Cannot be longer than 255 bytes (note it is bytes, \ - so multi-byte characters will count towards the 255 \ - limit faster)', + so multi-byte characters will count towards the 255 \ + limit faster)', } )} diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/_index.scss b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/_index.scss index e92e89b1703709..7bd002a2c970aa 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/_index.scss +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/_index.scss @@ -10,6 +10,7 @@ .mapToolbarOverlay__button { @include size($euiSizeXL); // sass-lint:disable-block no-important + color: $euiTextColor !important; background-color: $euiColorEmptyShade !important; pointer-events: all; position: relative; diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.tsx index 4857fbcc53d256..ed9bc89c60658e 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.tsx @@ -6,35 +6,14 @@ */ import React, { Component } from 'react'; -import { - EuiButtonIcon, - EuiContextMenuItem, - EuiContextMenuPanel, - EuiFlexGroup, - EuiFlexItem, - EuiPopover, -} from '@elastic/eui'; +import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { DRAW_TYPE } from '../../../../common/constants'; // @ts-expect-error import { GeometryFilterForm } from '../../../components/geometry_filter_form'; -import { GeoFieldWithIndex } from '../../../components/geo_field_with_index'; - -const DRAW_SHAPE = i18n.translate('xpack.maps.toolbarOverlay.drawShapeLabelShort', { - defaultMessage: 'Draw shape', -}); - -const DRAW_BOUNDS = i18n.translate('xpack.maps.toolbarOverlay.drawBoundsLabelShort', { - defaultMessage: 'Draw bounds', -}); - -const DRAW_DISTANCE = i18n.translate('xpack.maps.toolbarOverlay.drawDistanceLabel', { - defaultMessage: 'Draw distance', -}); export interface Props { cancelDraw: () => void; - geoFields: GeoFieldWithIndex[]; initiateDraw: (drawFeatureState: DRAW_TYPE) => void; } @@ -65,7 +44,6 @@ export class FeatureEditControl extends Component { iconType="pencil" onClick={this._togglePopover} aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureEditTitle', { - // This feature only "adds" at the moment. Messaging can be changed when further capabilities added defaultMessage: 'Add feature', })} title={i18n.translate('xpack.maps.toolbarOverlay.featureEditTitle', { @@ -76,46 +54,71 @@ export class FeatureEditControl extends Component { } render() { - const featureEditControlPopoverButton = ( - - this.props.initiateDraw(DRAW_TYPE.POLYGON)}> - Polygon -
, - this.props.initiateDraw(DRAW_TYPE.BOUNDS)}> - Rectangle - , - this.props.initiateDraw(DRAW_TYPE.DISTANCE)}> - Polyline - , - this.props.initiateDraw(DRAW_TYPE.POINT)}> - Point - , - ]} - /> - - ); - return ( - - {featureEditControlPopoverButton} - {/* */} - {/* */} - {/* */} - {/* */} - {/* */} - + + + + { + console.log('line'); + }} + iconType="minus" + aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.drawLineLabel', { + defaultMessage: 'Draw line', + })} + title={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.drawLineTitle', { + defaultMessage: 'Draw line', + })} + /> + + + { + console.log('Polygon'); + }} + iconType="home" + aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.drawPolygonLabel', { + defaultMessage: 'Draw polygon', + })} + title={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.drawLineTitle', { + defaultMessage: 'Draw polygon', + })} + /> + + + { + console.log('Bounding box'); + }} + iconType="stop" + aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.drawBBoxLabel', { + defaultMessage: 'Draw bounding box', + })} + title={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.drawBBoxTitle', { + defaultMessage: 'Draw bounding box', + })} + /> + + + { + console.log('Point'); + }} + iconType="visMapCoordinate" + aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.drawPointLabel', { + defaultMessage: 'Draw point', + })} + title={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.drawPointTitle', { + defaultMessage: 'Draw point', + })} + /> + + + ); } } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts index d1008edfd572d9..cad0a3908441ae 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts @@ -5,4 +5,15 @@ * 2.0. */ -export { ToolbarOverlay } from './toolbar_overlay'; +import { connect } from 'react-redux'; +import { ToolbarOverlay } from './toolbar_overlay'; +import { MapStoreState } from '../../reducers/store'; + +function mapStateToProps(state: MapStoreState) { + return { + editModeActive: state.map.mapState.editModeActive, + }; +} + +const connected = connect(mapStateToProps, null)(ToolbarOverlay); +export { connected as ToolbarOverlay }; diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx index 734ff678351479..7461f9724295fa 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx @@ -20,6 +20,7 @@ export interface Props { geoFields: GeoFieldWithIndex[]; getFilterActions?: () => Promise; getActionContext?: () => ActionExecutionContext; + editModeActive: boolean; } export function ToolbarOverlay(props: Props) { @@ -41,17 +42,11 @@ export function ToolbarOverlay(props: Props) { } function renderFeatureEditControl() { - const { geoFields, getFilterActions, getActionContext } = props; - - return ( + return props.editModeActive ? ( - + - ); + ) : null; } return ( From 92e17aa9a2f9feede6cae1b517629e2691d1c54f Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Mon, 5 Apr 2021 15:56:56 -0600 Subject: [PATCH 010/103] Connect missing shapes. Some clean up --- x-pack/plugins/maps/common/constants.ts | 1 + .../mb_map/draw_control/draw_control.tsx | 21 ++- .../draw_feature_control/index.ts | 4 + .../feature_edit_control.tsx | 165 +++++++----------- 4 files changed, 80 insertions(+), 111 deletions(-) diff --git a/x-pack/plugins/maps/common/constants.ts b/x-pack/plugins/maps/common/constants.ts index e3dcacd090e09e..33f2a52c6331d9 100644 --- a/x-pack/plugins/maps/common/constants.ts +++ b/x-pack/plugins/maps/common/constants.ts @@ -157,6 +157,7 @@ export enum DRAW_TYPE { DISTANCE = 'DISTANCE', POLYGON = 'POLYGON', POINT = 'POINT', + LINE = 'LINE', } export const AGG_DELIMITER = '_of_'; diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx index 545389a3e96fc5..f30a62bb0ed74a 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx @@ -6,19 +6,22 @@ */ import _ from 'lodash'; -import React, { Component } from 'react'; +import React, {Component} from 'react'; // @ts-expect-error import MapboxDraw from '@mapbox/mapbox-gl-draw'; // @ts-expect-error import DrawRectangle from 'mapbox-gl-draw-rectangle-mode'; -import { Map as MbMap } from 'mapbox-gl'; -import { Feature } from 'geojson'; -import { DRAW_TYPE } from '../../../../common/constants'; -import { DrawCircle } from './draw_circle'; -import { DrawTooltip } from './draw_tooltip'; +import {Map as MbMap} from 'mapbox-gl'; +import {Feature} from 'geojson'; +import {DRAW_TYPE} from '../../../../common/constants'; +import {DrawCircle} from './draw_circle'; +import {DrawTooltip} from './draw_tooltip'; const DRAW_RECTANGLE = 'draw_rectangle'; const DRAW_CIRCLE = 'draw_circle'; +const DRAW_POLYGON = 'draw_polygon'; +const DRAW_LINE = 'draw_line_string'; +const DRAW_POINT = 'draw_point'; const mbDrawModes = MapboxDraw.modes; mbDrawModes[DRAW_RECTANGLE] = DrawRectangle; @@ -94,6 +97,12 @@ export class DrawControl extends Component { this._mbDrawControl.changeMode(DRAW_RECTANGLE); } else if (drawMode !== DRAW_CIRCLE && this.props.drawType === DRAW_TYPE.DISTANCE) { this._mbDrawControl.changeMode(DRAW_CIRCLE); + } else if (drawMode !== DRAW_LINE && this.props.drawType === DRAW_TYPE.LINE) { + this._mbDrawControl.changeMode(DRAW_LINE); + } else if (drawMode !== DRAW_POLYGON && this.props.drawType === DRAW_TYPE.POLYGON) { + this._mbDrawControl.changeMode(DRAW_POLYGON); + } else if (drawMode !== DRAW_POINT && this.props.drawType === DRAW_TYPE.POINT) { + this._mbDrawControl.changeMode(DRAW_POINT); } else if ( drawMode !== this._mbDrawControl.modes.DRAW_POLYGON && this.props.drawType === DRAW_TYPE.POLYGON diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts index 5b4c579f1dbf74..dbfcc4e0188efa 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts @@ -11,6 +11,7 @@ import { connect } from 'react-redux'; import { DrawFeatureControl } from './draw_feature_control'; import { updateDrawFeatureState } from '../../../../actions'; import { MapStoreState } from '../../../../reducers/store'; +import { DRAW_TYPE } from '../../../../../common'; function mapStateToProps(state: MapStoreState) { return { @@ -20,6 +21,9 @@ function mapStateToProps(state: MapStoreState) { function mapDispatchToProps(dispatch: ThunkDispatch) { return { + initiateDraw: (drawFeatureState: DRAW_TYPE) => { + dispatch(updateDrawFeatureState(drawFeatureState)); + }, disableDrawState() { dispatch(updateDrawFeatureState(null)); }, diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.tsx index ed9bc89c60658e..aaaedd5104b0d6 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { Component } from 'react'; +import React from 'react'; import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { DRAW_TYPE } from '../../../../common/constants'; @@ -17,108 +17,63 @@ export interface Props { initiateDraw: (drawFeatureState: DRAW_TYPE) => void; } -interface State { - isPopoverOpen: boolean; -} - -export class FeatureEditControl extends Component { - state: State = { - isPopoverOpen: false, - }; - - _togglePopover = () => { - this.setState((prevState) => ({ - isPopoverOpen: !prevState.isPopoverOpen, - })); - }; - - _closePopover = () => { - this.setState({ isPopoverOpen: false }); - }; - - _renderFeatureEditButton() { - return ( - - ); - } - - render() { - return ( - - - - { - console.log('line'); - }} - iconType="minus" - aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.drawLineLabel', { - defaultMessage: 'Draw line', - })} - title={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.drawLineTitle', { - defaultMessage: 'Draw line', - })} - /> - - - { - console.log('Polygon'); - }} - iconType="home" - aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.drawPolygonLabel', { - defaultMessage: 'Draw polygon', - })} - title={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.drawLineTitle', { - defaultMessage: 'Draw polygon', - })} - /> - - - { - console.log('Bounding box'); - }} - iconType="stop" - aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.drawBBoxLabel', { - defaultMessage: 'Draw bounding box', - })} - title={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.drawBBoxTitle', { - defaultMessage: 'Draw bounding box', - })} - /> - - - { - console.log('Point'); - }} - iconType="visMapCoordinate" - aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.drawPointLabel', { - defaultMessage: 'Draw point', - })} - title={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.drawPointTitle', { - defaultMessage: 'Draw point', - })} - /> - - - - ); - } +export function FeatureEditControl(props: Props) { + return ( + + + + props.initiateDraw(DRAW_TYPE.LINE)} + iconType="minus" + aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.drawLineLabel', { + defaultMessage: 'Draw line', + })} + title={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.drawLineTitle', { + defaultMessage: 'Draw line', + })} + /> + + + props.initiateDraw(DRAW_TYPE.POLYGON)} + iconType="home" + aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.drawPolygonLabel', { + defaultMessage: 'Draw polygon', + })} + title={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.drawLineTitle', { + defaultMessage: 'Draw polygon', + })} + /> + + + props.initiateDraw(DRAW_TYPE.BOUNDS)} + iconType="stop" + aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.drawBBoxLabel', { + defaultMessage: 'Draw bounding box', + })} + title={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.drawBBoxTitle', { + defaultMessage: 'Draw bounding box', + })} + /> + + + props.initiateDraw(DRAW_TYPE.POINT)} + iconType="visMapCoordinate" + aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.drawPointLabel', { + defaultMessage: 'Draw point', + })} + title={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.drawPointTitle', { + defaultMessage: 'Draw point', + })} + /> + + + + ); } From 143b24ae69a2da5590923cf1f6b5650c5de36436 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Mon, 5 Apr 2021 17:19:53 -0600 Subject: [PATCH 011/103] Track features and index name in store --- .../public/actions/map_action_constants.ts | 2 ++ .../maps/public/actions/map_actions.ts | 17 ++++++++++++++++ .../layers/new_vector_layer_wizard/index.ts | 7 +++++-- .../layers/new_vector_layer_wizard/wizard.tsx | 4 ++-- .../draw_feature_control.tsx | 4 +++- .../draw_feature_control/index.ts | 8 ++++---- .../feature_edit_control.tsx | 2 +- .../plugins/maps/public/reducers/map/map.ts | 20 +++++++++++++++++++ .../plugins/maps/public/reducers/map/types.ts | 3 +++ 9 files changed, 57 insertions(+), 10 deletions(-) diff --git a/x-pack/plugins/maps/public/actions/map_action_constants.ts b/x-pack/plugins/maps/public/actions/map_action_constants.ts index 31e0f8a534bd4e..f7fc35f5af351a 100644 --- a/x-pack/plugins/maps/public/actions/map_action_constants.ts +++ b/x-pack/plugins/maps/public/actions/map_action_constants.ts @@ -46,3 +46,5 @@ export const SET_MAP_SETTINGS = 'SET_MAP_SETTINGS'; export const ROLLBACK_MAP_SETTINGS = 'ROLLBACK_MAP_SETTINGS'; export const TRACK_MAP_SETTINGS = 'TRACK_MAP_SETTINGS'; export const UPDATE_MAP_SETTING = 'UPDATE_MAP_SETTING'; +export const ADD_FEATURES_TO_INDEX_QUEUE = 'ADD_FEATURES_TO_INDEX_QUEUE'; +export const SET_VECTOR_LAYER_INDEX_NAME = 'SET_VECTOR_LAYER_INDEX_NAME'; diff --git a/x-pack/plugins/maps/public/actions/map_actions.ts b/x-pack/plugins/maps/public/actions/map_actions.ts index 332342daaa6dce..fc6e268528f599 100644 --- a/x-pack/plugins/maps/public/actions/map_actions.ts +++ b/x-pack/plugins/maps/public/actions/map_actions.ts @@ -6,6 +6,7 @@ */ import _ from 'lodash'; +import { Feature } from 'geojson'; import { AnyAction, Dispatch } from 'redux'; import { ThunkDispatch } from 'redux-thunk'; import turfBboxPolygon from '@turf/bbox-polygon'; @@ -46,6 +47,8 @@ import { UPDATE_DRAW_FEATURE_STATE, UPDATE_EDIT_MODE, UPDATE_MAP_SETTING, + ADD_FEATURES_TO_INDEX_QUEUE, + SET_VECTOR_LAYER_INDEX_NAME, } from './map_action_constants'; import { autoFitToBounds, syncDataForAllLayers } from './data_request_actions'; import { addLayer, addLayerWithoutDataSync } from './layer_actions'; @@ -344,3 +347,17 @@ export function updateEditMode(isActive: boolean) { isActive, }; } + +export function addFeaturesToIndexQueue(features: Feature[]) { + return { + type: ADD_FEATURES_TO_INDEX_QUEUE, + features, + }; +} + +export function setVectorLayerIndexName(indexName: string) { + return { + type: SET_VECTOR_LAYER_INDEX_NAME, + indexName, + }; +} diff --git a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/index.ts b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/index.ts index e4829bdeb0484b..0f4760349406ca 100644 --- a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/index.ts +++ b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/index.ts @@ -10,16 +10,19 @@ import { AnyAction } from 'redux'; import { connect } from 'react-redux'; import { MapStoreState } from '../../../reducers/store'; import { NewVectorLayerEditor } from './wizard'; -import { updateEditMode } from '../../../actions'; +import { setVectorLayerIndexName, updateEditMode } from '../../../actions'; function mapStateToProps(state: MapStoreState) { - return {}; + return { + indexName: state.map.mapState.vectorLayerIndexName, + }; } function mapDispatchToProps(dispatch: ThunkDispatch) { return { setEditModeActive: () => dispatch(updateEditMode(true)), setEditModeInActive: () => dispatch(updateEditMode(false)), + setIndexName: (indexName: string) => dispatch(setVectorLayerIndexName(indexName)), }; } diff --git a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx index 54a1713a686ba3..ed20d4b4c5831f 100644 --- a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx +++ b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx @@ -7,12 +7,10 @@ import React, { ChangeEvent, Component, Fragment } from 'react'; import { - EuiButton, EuiCallOut, EuiEmptyPrompt, EuiFieldText, EuiFormRow, - EuiLoadingSpinner, EuiPanel, EuiSpacer, } from '@elastic/eui'; @@ -27,6 +25,7 @@ import { interface Props { setEditModeActive: () => void; setEditModeInActive: () => void; + setIndexName: (indexName: string) => void; } interface State { @@ -86,6 +85,7 @@ export class NewVectorLayerEditor extends Component { }); } else { this.setState({ indexError: '' }); + this.props.setIndexName(indexName); } }; diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx index 339dd3dc4ef1de..6e0bb65709f287 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx @@ -7,14 +7,15 @@ import React, { Component } from 'react'; import { Map as MbMap } from 'mapbox-gl'; -import { i18n } from '@kbn/i18n'; import { Feature } from 'geojson'; +import { i18n } from '@kbn/i18n'; import { getToasts } from '../../../../kibana_services'; import { DrawControl } from '../draw_control'; import { DRAW_TYPE } from '../../../../../common'; export interface Props { disableDrawState: () => void; + addFeaturesToIndexQueue: (features: Feature[]) => void; drawType: DRAW_TYPE; mbMap: MbMap; } @@ -23,6 +24,7 @@ export class DrawFeatureControl extends Component { _onDraw = async (e: { features: Feature[] }) => { try { console.log(e); + this.props.addFeaturesToIndexQueue(e.features); } catch (error) { getToasts().addWarning( i18n.translate('xpack.maps.drawFeatureControl.unableToCreatFilter', { diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts index dbfcc4e0188efa..9069090b2b700e 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts @@ -8,10 +8,10 @@ import { AnyAction } from 'redux'; import { ThunkDispatch } from 'redux-thunk'; import { connect } from 'react-redux'; +import { Feature } from 'geojson'; import { DrawFeatureControl } from './draw_feature_control'; -import { updateDrawFeatureState } from '../../../../actions'; +import { addFeaturesToIndexQueue, updateDrawFeatureState } from '../../../../actions'; import { MapStoreState } from '../../../../reducers/store'; -import { DRAW_TYPE } from '../../../../../common'; function mapStateToProps(state: MapStoreState) { return { @@ -21,8 +21,8 @@ function mapStateToProps(state: MapStoreState) { function mapDispatchToProps(dispatch: ThunkDispatch) { return { - initiateDraw: (drawFeatureState: DRAW_TYPE) => { - dispatch(updateDrawFeatureState(drawFeatureState)); + addFeaturesToIndexQueue(features: Feature[]) { + dispatch(addFeaturesToIndexQueue(features)); }, disableDrawState() { dispatch(updateDrawFeatureState(null)); diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.tsx index aaaedd5104b0d6..684eb92b4b9399 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.tsx @@ -64,7 +64,7 @@ export function FeatureEditControl(props: Props) { props.initiateDraw(DRAW_TYPE.POINT)} - iconType="visMapCoordinate" + iconType="dot" aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.drawPointLabel', { defaultMessage: 'Draw point', })} diff --git a/x-pack/plugins/maps/public/reducers/map/map.ts b/x-pack/plugins/maps/public/reducers/map/map.ts index 238b10f9244d6c..e2d62b262ac209 100644 --- a/x-pack/plugins/maps/public/reducers/map/map.ts +++ b/x-pack/plugins/maps/public/reducers/map/map.ts @@ -47,6 +47,8 @@ import { UPDATE_MAP_SETTING, UPDATE_DRAW_FEATURE_STATE, UPDATE_EDIT_MODE, + ADD_FEATURES_TO_INDEX_QUEUE, + SET_VECTOR_LAYER_INDEX_NAME, } from '../../actions'; import { getDefaultMapSettings } from './default_map_settings'; @@ -77,9 +79,11 @@ export const DEFAULT_MAP_STATE: MapState = { filters: [], refreshConfig: undefined, refreshTimerLastTriggeredAt: undefined, + vectorLayerIndexName: '', drawState: undefined, drawFeatureState: undefined, editModeActive: undefined, + featuresToIndexQueue: [], }, selectedLayerId: null, layerList: [], @@ -114,6 +118,22 @@ export function map(state: MapState = DEFAULT_MAP_STATE, action: any) { editModeActive: action.isActive, }, }; + case ADD_FEATURES_TO_INDEX_QUEUE: + return { + ...state, + mapState: { + ...state.mapState, + featuresToIndexQueue: [...state.mapState.featuresToIndexQueue, ...action.features], + }, + }; + case SET_VECTOR_LAYER_INDEX_NAME: + return { + ...state, + mapState: { + ...state.mapState, + vectorLayerIndexName: action.indexName, + }, + }; case REMOVE_TRACKED_LAYER_STATE: return removeTrackedLayerState(state, action.layerId); case TRACK_CURRENT_LAYER_STATE: diff --git a/x-pack/plugins/maps/public/reducers/map/types.ts b/x-pack/plugins/maps/public/reducers/map/types.ts index 7e20f3b6602466..8ea7d9d253bcca 100644 --- a/x-pack/plugins/maps/public/reducers/map/types.ts +++ b/x-pack/plugins/maps/public/reducers/map/types.ts @@ -7,6 +7,7 @@ /* eslint-disable @typescript-eslint/consistent-type-definitions */ +import { Feature } from 'geojson'; import { DrawState, Goto, @@ -35,8 +36,10 @@ export type MapContext = { filters: Filter[]; refreshConfig?: MapRefreshConfig; refreshTimerLastTriggeredAt?: string; + vectorLayerIndexName: string; drawState?: DrawState; drawFeatureState?: DRAW_TYPE; + featuresToIndexQueue: Feature[]; editModeActive?: boolean; searchSessionId?: string; searchSessionMapBuffer?: MapExtent; From e1295395343cfcde835a6aea36224f5e23e9e801 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Mon, 5 Apr 2021 18:20:50 -0600 Subject: [PATCH 012/103] Connect add layer button enablement --- .../layers/new_vector_layer_wizard/config.tsx | 2 +- .../layers/new_vector_layer_wizard/index.ts | 1 + .../layers/new_vector_layer_wizard/wizard.tsx | 18 ++++++++++++++++-- .../add_layer_panel/index.ts | 1 + .../add_layer_panel/view.tsx | 3 ++- 5 files changed, 21 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/config.tsx b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/config.tsx index da4d762fffa655..8b5f7f98d42d92 100644 --- a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/config.tsx +++ b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/config.tsx @@ -19,7 +19,7 @@ export const newVectorLayerWizardConfig: LayerWizard = { icon: DocumentsLayerIcon, prerequisiteSteps: [], renderWizard: (renderWizardArguments: RenderWizardArguments) => { - return ; + return ; }, title: i18n.translate('xpack.maps.newVectorLayerWizard.title', { defaultMessage: 'Draw new vector layer', diff --git a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/index.ts b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/index.ts index 0f4760349406ca..2ff942d3c61ea4 100644 --- a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/index.ts +++ b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/index.ts @@ -15,6 +15,7 @@ import { setVectorLayerIndexName, updateEditMode } from '../../../actions'; function mapStateToProps(state: MapStoreState) { return { indexName: state.map.mapState.vectorLayerIndexName, + featuresAreQueued: !!state.map.mapState.featuresToIndexQueue.length, }; } diff --git a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx index ed20d4b4c5831f..13478a77f77898 100644 --- a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx +++ b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx @@ -21,8 +21,11 @@ import { checkIndexPatternValid, // @ts-expect-error } from './utils/indexing_service'; +import { RenderWizardArguments } from '../layer_wizard_registry'; -interface Props { +interface NewVectorLayerProps extends RenderWizardArguments { + indexName: string; + featuresAreQueued: boolean; setEditModeActive: () => void; setEditModeInActive: () => void; setIndexName: (indexName: string) => void; @@ -34,7 +37,7 @@ interface State { indexNames: string[]; } -export class NewVectorLayerEditor extends Component { +export class NewVectorLayerEditor extends Component { state = { indexName: '', indexError: '', @@ -49,6 +52,15 @@ export class NewVectorLayerEditor extends Component { this._loadIndexNames(); } + componentDidUpdate() { + const { indexName, featuresAreQueued, enableNextBtn, disableNextBtn } = this.props; + if (indexName && featuresAreQueued) { + enableNextBtn(); + } else { + disableNextBtn(); + } + } + componentWillUnmount() { this.props.setEditModeInActive(); this._isMounted = false; @@ -74,6 +86,7 @@ export class NewVectorLayerEditor extends Component { } ), }); + this.props.setIndexName(''); } else if (!checkIndexPatternValid(indexName)) { this.setState({ indexError: i18n.translate( @@ -83,6 +96,7 @@ export class NewVectorLayerEditor extends Component { } ), }); + this.props.setIndexName(''); } else { this.setState({ indexError: '' }); this.props.setIndexName(indexName); diff --git a/x-pack/plugins/maps/public/connected_components/add_layer_panel/index.ts b/x-pack/plugins/maps/public/connected_components/add_layer_panel/index.ts index f91abc3856e05c..b3f3c747f20745 100644 --- a/x-pack/plugins/maps/public/connected_components/add_layer_panel/index.ts +++ b/x-pack/plugins/maps/public/connected_components/add_layer_panel/index.ts @@ -25,6 +25,7 @@ function mapStateToProps(state: MapStoreState) { return { hasPreviewLayers: hasPreviewLayers(state), isLoadingPreviewLayers: isLoadingPreviewLayers(state), + isDrawingLayer: state.map.mapState.editModeActive, }; } diff --git a/x-pack/plugins/maps/public/connected_components/add_layer_panel/view.tsx b/x-pack/plugins/maps/public/connected_components/add_layer_panel/view.tsx index 35672d7369404a..e89f4a6443fdd4 100644 --- a/x-pack/plugins/maps/public/connected_components/add_layer_panel/view.tsx +++ b/x-pack/plugins/maps/public/connected_components/add_layer_panel/view.tsx @@ -33,6 +33,7 @@ export interface Props { hasPreviewLayers: boolean; isLoadingPreviewLayers: boolean; promotePreviewLayers: () => void; + isDrawingLayer: boolean; } interface State { @@ -127,7 +128,7 @@ export class AddLayerPanel extends Component { let isDisabled = !this.state.isNextStepBtnEnabled; let isLoading = this.state.isStepLoading; - if (this.state.currentStep.id === ADD_LAYER_STEP_ID) { + if (this.state.currentStep.id === ADD_LAYER_STEP_ID && !this.props.isDrawingLayer) { isDisabled = !this.props.hasPreviewLayers; isLoading = this.props.isLoadingPreviewLayers; } else { From 9c5ca169b075b0a5d72c69f09acd23d46b2229b9 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Tue, 6 Apr 2021 10:11:37 -0600 Subject: [PATCH 013/103] Connect persistence utils --- .../maps/public/actions/layer_actions.ts | 28 +++++++++++++++++ .../public/actions/map_action_constants.ts | 1 + .../utils/indexing_service.js | 31 +++++++++++++++++++ .../add_layer_panel/index.ts | 2 ++ .../add_layer_panel/view.tsx | 6 +++- .../plugins/maps/public/reducers/map/map.ts | 9 ++++++ 6 files changed, 76 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/maps/public/actions/layer_actions.ts b/x-pack/plugins/maps/public/actions/layer_actions.ts index fe62e9fe9da51b..356edc5f76d00c 100644 --- a/x-pack/plugins/maps/public/actions/layer_actions.ts +++ b/x-pack/plugins/maps/public/actions/layer_actions.ts @@ -37,6 +37,7 @@ import { UPDATE_LAYER_PROP, UPDATE_LAYER_STYLE, UPDATE_SOURCE_PROP, + INDEX_DRAWN_LAYERS, } from './map_action_constants'; import { clearDataRequests, syncDataForLayerId, updateStyleMeta } from './data_request_actions'; import { cleanTooltipStateForLayer } from './tooltip_actions'; @@ -48,6 +49,8 @@ import { IVectorStyle } from '../classes/styles/vector/vector_style'; import { notifyLicensedFeatureUsage } from '../licensed_features'; import { IESAggField } from '../classes/fields/agg'; import { IField } from '../classes/fields/field'; +// @ts-ignore +import { createNewIndexAndPattern, addFeatureToIndex } from '../classes/layers/new_vector_layer_wizard/utils/indexing_service'; export function trackCurrentLayerState(layerId: string) { return { @@ -548,3 +551,28 @@ export function setAreTilesLoaded(layerId: string, areTilesLoaded: boolean) { newValue: areTilesLoaded, }; } + +export function indexDrawnLayers() { + return async ( + dispatch: ThunkDispatch, + getState: () => MapStoreState + ) => { + const state = getState(); + const features = state.map.mapState.featuresToIndexQueue; + const indexName = state.map.mapState.vectorLayerIndexName; + await createNewIndexAndPattern(indexName); + Promise.all( + features.map(async (feature) => { + const geometry = { + coordinates: feature.geometry.coordinates, + type: feature.geometry.type.toLowerCase(), + }; + await addFeatureToIndex(indexName, geometry); + }) + ); + + return { + type: INDEX_DRAWN_LAYERS, + }; + }; +} diff --git a/x-pack/plugins/maps/public/actions/map_action_constants.ts b/x-pack/plugins/maps/public/actions/map_action_constants.ts index f7fc35f5af351a..e43ef1786f2474 100644 --- a/x-pack/plugins/maps/public/actions/map_action_constants.ts +++ b/x-pack/plugins/maps/public/actions/map_action_constants.ts @@ -48,3 +48,4 @@ export const TRACK_MAP_SETTINGS = 'TRACK_MAP_SETTINGS'; export const UPDATE_MAP_SETTING = 'UPDATE_MAP_SETTING'; export const ADD_FEATURES_TO_INDEX_QUEUE = 'ADD_FEATURES_TO_INDEX_QUEUE'; export const SET_VECTOR_LAYER_INDEX_NAME = 'SET_VECTOR_LAYER_INDEX_NAME'; +export const INDEX_DRAWN_LAYERS = 'INDEX_DRAWN_LAYERS'; diff --git a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/utils/indexing_service.js b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/utils/indexing_service.js index a508aaa5ab01ef..29e593fd977b66 100644 --- a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/utils/indexing_service.js +++ b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/utils/indexing_service.js @@ -16,6 +16,37 @@ export const getExistingIndexNames = async () => { return indexes ? indexes.map(({ name }) => name) : []; }; +export const createNewIndexAndPattern = async (indexName) => { + return await httpService({ + url: `/api/maps/docSource`, + method: 'POST', + data: { + index: indexName, + // Initially set to static mappings + mappings: { + properties: { + coordinates: { + type: 'geo_shape', + }, + }, + }, + }, + }); +}; + +export const addFeatureToIndex = async (indexName, geometry) => { + return await httpService({ + url: `/api/maps/feature`, + method: 'POST', + data: { + index: indexName, + data: { + coordinates: geometry, + }, + }, + }); +}; + export const getExistingIndexPatternNames = async () => { const indexPatterns = await getSavedObjectsClient() .find({ diff --git a/x-pack/plugins/maps/public/connected_components/add_layer_panel/index.ts b/x-pack/plugins/maps/public/connected_components/add_layer_panel/index.ts index b3f3c747f20745..1bb90642f50289 100644 --- a/x-pack/plugins/maps/public/connected_components/add_layer_panel/index.ts +++ b/x-pack/plugins/maps/public/connected_components/add_layer_panel/index.ts @@ -16,6 +16,7 @@ import { removePreviewLayers, setFirstPreviewLayerToSelectedLayer, updateFlyout, + indexDrawnLayers, } from '../../actions'; import { MapStoreState } from '../../reducers/store'; import { LayerDescriptor } from '../../../common/descriptor_types'; @@ -43,6 +44,7 @@ function mapDispatchToProps(dispatch: ThunkDispatch dispatch(indexDrawnLayers()), }; } diff --git a/x-pack/plugins/maps/public/connected_components/add_layer_panel/view.tsx b/x-pack/plugins/maps/public/connected_components/add_layer_panel/view.tsx index e89f4a6443fdd4..653fa4b6297bc4 100644 --- a/x-pack/plugins/maps/public/connected_components/add_layer_panel/view.tsx +++ b/x-pack/plugins/maps/public/connected_components/add_layer_panel/view.tsx @@ -34,6 +34,7 @@ export interface Props { isLoadingPreviewLayers: boolean; promotePreviewLayers: () => void; isDrawingLayer: boolean; + indexDrawnLayers: () => void; } interface State { @@ -89,7 +90,10 @@ export class AddLayerPanel extends Component { return; } - if (this.state.layerSteps.length - 1 === this.state.currentStepIndex) { + if (this.props.isDrawingLayer) { + // Write to index + this.props.indexDrawnLayers(); + } else if (this.state.layerSteps.length - 1 === this.state.currentStepIndex) { // last step this.props.promotePreviewLayers(); } else { diff --git a/x-pack/plugins/maps/public/reducers/map/map.ts b/x-pack/plugins/maps/public/reducers/map/map.ts index e2d62b262ac209..3f4c2e67f8220b 100644 --- a/x-pack/plugins/maps/public/reducers/map/map.ts +++ b/x-pack/plugins/maps/public/reducers/map/map.ts @@ -49,6 +49,7 @@ import { UPDATE_EDIT_MODE, ADD_FEATURES_TO_INDEX_QUEUE, SET_VECTOR_LAYER_INDEX_NAME, + INDEX_DRAWN_LAYERS, } from '../../actions'; import { getDefaultMapSettings } from './default_map_settings'; @@ -134,6 +135,14 @@ export function map(state: MapState = DEFAULT_MAP_STATE, action: any) { vectorLayerIndexName: action.indexName, }, }; + case INDEX_DRAWN_LAYERS: + return { + ...state, + mapState: { + ...state.mapState, + featuresToIndexQueue: [], + }, + }; case REMOVE_TRACKED_LAYER_STATE: return removeTrackedLayerState(state, action.layerId); case TRACK_CURRENT_LAYER_STATE: From 423e3aae54624264302107b70bf405c2dc095621 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Tue, 6 Apr 2021 11:09:29 -0600 Subject: [PATCH 014/103] Dispatch clearing action --- x-pack/plugins/maps/public/actions/layer_actions.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/maps/public/actions/layer_actions.ts b/x-pack/plugins/maps/public/actions/layer_actions.ts index 356edc5f76d00c..da3d4924a01742 100644 --- a/x-pack/plugins/maps/public/actions/layer_actions.ts +++ b/x-pack/plugins/maps/public/actions/layer_actions.ts @@ -571,8 +571,8 @@ export function indexDrawnLayers() { }) ); - return { + dispatch({ type: INDEX_DRAWN_LAYERS, - }; + }); }; } From f238ccbdc34a07b7fee44423fb38eebf6f8d637c Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Tue, 6 Apr 2021 17:47:32 -0600 Subject: [PATCH 015/103] Full roundtrip w/ settings showing. Moved async calls to component --- x-pack/plugins/maps/common/types.ts | 1 + .../maps/public/actions/layer_actions.ts | 28 +++------- .../layers/new_vector_layer_wizard/config.tsx | 16 +++++- .../layers/new_vector_layer_wizard/index.ts | 21 +++++++- .../layers/new_vector_layer_wizard/wizard.tsx | 52 +++++++++++++++++-- .../add_layer_panel/index.ts | 3 -- .../add_layer_panel/view.tsx | 7 +-- .../server/data_indexing/create_doc_source.ts | 3 +- 8 files changed, 92 insertions(+), 39 deletions(-) diff --git a/x-pack/plugins/maps/common/types.ts b/x-pack/plugins/maps/common/types.ts index 6f2bd72c808967..6ca3de3dac377c 100644 --- a/x-pack/plugins/maps/common/types.ts +++ b/x-pack/plugins/maps/common/types.ts @@ -6,6 +6,7 @@ */ export interface CreateDocSourceResp { + indexPatternId?: string; success: boolean; error?: Error; } diff --git a/x-pack/plugins/maps/public/actions/layer_actions.ts b/x-pack/plugins/maps/public/actions/layer_actions.ts index da3d4924a01742..78e3b5483f3b7c 100644 --- a/x-pack/plugins/maps/public/actions/layer_actions.ts +++ b/x-pack/plugins/maps/public/actions/layer_actions.ts @@ -50,7 +50,10 @@ import { notifyLicensedFeatureUsage } from '../licensed_features'; import { IESAggField } from '../classes/fields/agg'; import { IField } from '../classes/fields/field'; // @ts-ignore -import { createNewIndexAndPattern, addFeatureToIndex } from '../classes/layers/new_vector_layer_wizard/utils/indexing_service'; +import { + createNewIndexAndPattern, + addFeatureToIndex, +} from '../classes/layers/new_vector_layer_wizard/utils/indexing_service'; export function trackCurrentLayerState(layerId: string) { return { @@ -553,26 +556,7 @@ export function setAreTilesLoaded(layerId: string, areTilesLoaded: boolean) { } export function indexDrawnLayers() { - return async ( - dispatch: ThunkDispatch, - getState: () => MapStoreState - ) => { - const state = getState(); - const features = state.map.mapState.featuresToIndexQueue; - const indexName = state.map.mapState.vectorLayerIndexName; - await createNewIndexAndPattern(indexName); - Promise.all( - features.map(async (feature) => { - const geometry = { - coordinates: feature.geometry.coordinates, - type: feature.geometry.type.toLowerCase(), - }; - await addFeatureToIndex(indexName, geometry); - }) - ); - - dispatch({ - type: INDEX_DRAWN_LAYERS, - }); + return { + type: INDEX_DRAWN_LAYERS, }; } diff --git a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/config.tsx b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/config.tsx index 8b5f7f98d42d92..6612be3a287796 100644 --- a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/config.tsx +++ b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/config.tsx @@ -10,6 +10,7 @@ import React from 'react'; import { LayerWizard, RenderWizardArguments } from '../../layers/layer_wizard_registry'; import { NewVectorLayerEditor } from './index'; import { DocumentsLayerIcon } from '../../layers/icons/documents_layer_icon'; +import { CREATE_DRAWN_FEATURES_INDEX_STEP_ID, ADD_DRAWN_FEATURES_TO_INDEX_STEP_ID } from './wizard'; export const newVectorLayerWizardConfig: LayerWizard = { categories: [], @@ -17,7 +18,20 @@ export const newVectorLayerWizardConfig: LayerWizard = { defaultMessage: 'Draw points & shapes and save in Elasticsearch', }), icon: DocumentsLayerIcon, - prerequisiteSteps: [], + prerequisiteSteps: [ + { + id: CREATE_DRAWN_FEATURES_INDEX_STEP_ID, + label: i18n.translate('xpack.maps.newVectorLayerWizard.indexFeatures', { + defaultMessage: 'Index features', + }), + }, + { + id: ADD_DRAWN_FEATURES_TO_INDEX_STEP_ID, + label: i18n.translate('xpack.maps.newVectorLayerWizard.indexingFeatures', { + defaultMessage: 'Indexing features', + }), + }, + ], renderWizard: (renderWizardArguments: RenderWizardArguments) => { return ; }, diff --git a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/index.ts b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/index.ts index 2ff942d3c61ea4..9afd0d83533bec 100644 --- a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/index.ts +++ b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/index.ts @@ -10,12 +10,21 @@ import { AnyAction } from 'redux'; import { connect } from 'react-redux'; import { MapStoreState } from '../../../reducers/store'; import { NewVectorLayerEditor } from './wizard'; -import { setVectorLayerIndexName, updateEditMode } from '../../../actions'; +import { + addLayer, + indexDrawnLayers, + setSelectedLayer, + setVectorLayerIndexName, + updateEditMode, + updateFlyout, +} from '../../../actions'; +import { FLYOUT_STATE } from '../../../reducers/ui'; +import { LayerDescriptor } from '../../../../common/descriptor_types'; function mapStateToProps(state: MapStoreState) { return { indexName: state.map.mapState.vectorLayerIndexName, - featuresAreQueued: !!state.map.mapState.featuresToIndexQueue.length, + featuresQueued: state.map.mapState.featuresToIndexQueue, }; } @@ -24,6 +33,14 @@ function mapDispatchToProps(dispatch: ThunkDispatch dispatch(updateEditMode(true)), setEditModeInActive: () => dispatch(updateEditMode(false)), setIndexName: (indexName: string) => dispatch(setVectorLayerIndexName(indexName)), + indexDrawnLayers: () => { + dispatch(indexDrawnLayers()); + }, + addNewLayer: async (layerDescriptor: LayerDescriptor) => { + dispatch(addLayer(layerDescriptor)); + await dispatch(setSelectedLayer(layerDescriptor.id)); + dispatch(updateFlyout(FLYOUT_STATE.LAYER_PANEL)); + }, }; } diff --git a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx index 13478a77f77898..855a06f8a2fc7f 100644 --- a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx +++ b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx @@ -15,26 +15,39 @@ import { EuiSpacer, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { Feature } from 'geojson'; import { getExistingIndexNames, getExistingIndexPatternNames, checkIndexPatternValid, + createNewIndexAndPattern, + addFeatureToIndex, // @ts-expect-error } from './utils/indexing_service'; import { RenderWizardArguments } from '../layer_wizard_registry'; +import { VectorLayer } from '../vector_layer'; +import { ESSearchSource } from '../../sources/es_search_source'; +import { LayerDescriptor } from '../../../../common/descriptor_types'; + +export const CREATE_DRAWN_FEATURES_INDEX_STEP_ID = 'CREATE_DRAWN_FEATURES_INDEX_STEP_ID'; +export const ADD_DRAWN_FEATURES_TO_INDEX_STEP_ID = 'ADD_DRAWN_FEATURES_TO_INDEX_STEP_ID'; interface NewVectorLayerProps extends RenderWizardArguments { indexName: string; - featuresAreQueued: boolean; + featuresQueued: Feature[]; setEditModeActive: () => void; setEditModeInActive: () => void; setIndexName: (indexName: string) => void; + indexDrawnLayers: () => void; + addNewLayer: (layerDescriptor: LayerDescriptor) => void; } interface State { indexName: string; indexError: string; indexNames: string[]; + indexingTriggered: boolean; + indexPatternId: string; } export class NewVectorLayerEditor extends Component { @@ -42,6 +55,8 @@ export class NewVectorLayerEditor extends Component indexName: '', indexError: '', indexNames: [], + indexingTriggered: false, + indexPatternId: '', }; private _isMounted = false; @@ -52,13 +67,17 @@ export class NewVectorLayerEditor extends Component this._loadIndexNames(); } - componentDidUpdate() { - const { indexName, featuresAreQueued, enableNextBtn, disableNextBtn } = this.props; - if (indexName && featuresAreQueued) { + async componentDidUpdate() { + const { indexName, featuresQueued, enableNextBtn, disableNextBtn, currentStepId } = this.props; + if (indexName && featuresQueued.length) { enableNextBtn(); } else { disableNextBtn(); } + if (!this.state.indexingTriggered && currentStepId === ADD_DRAWN_FEATURES_TO_INDEX_STEP_ID) { + await this._addFeaturesToNewIndex(); + this.props.indexDrawnLayers(); + } } componentWillUnmount() { @@ -66,6 +85,31 @@ export class NewVectorLayerEditor extends Component this._isMounted = false; } + _addFeaturesToNewIndex = async () => { + const { indexPatternId } = await createNewIndexAndPattern(this.props.indexName); + this.props.advanceToNextStep(); + await Promise.all( + this.props.featuresQueued.map(async (feature) => { + const geometry = { + coordinates: feature.geometry.coordinates, + type: feature.geometry.type.toLowerCase(), + }; + await addFeatureToIndex(this.props.indexName, geometry); + }) + ); + const sourceDescriptor = ESSearchSource.createDescriptor({ + indexPatternId, + geoField: 'coordinates', + filterByMapBounds: false, + }); + this.props.advanceToNextStep(); + const layerDescriptor = VectorLayer.createDescriptor( + { sourceDescriptor }, + this.props.mapColors + ); + await this.props.addNewLayer(layerDescriptor); + }; + _loadIndexNames = async () => { const indexNameList = await getExistingIndexNames(); const indexPatternList = await getExistingIndexPatternNames(); diff --git a/x-pack/plugins/maps/public/connected_components/add_layer_panel/index.ts b/x-pack/plugins/maps/public/connected_components/add_layer_panel/index.ts index 1bb90642f50289..f91abc3856e05c 100644 --- a/x-pack/plugins/maps/public/connected_components/add_layer_panel/index.ts +++ b/x-pack/plugins/maps/public/connected_components/add_layer_panel/index.ts @@ -16,7 +16,6 @@ import { removePreviewLayers, setFirstPreviewLayerToSelectedLayer, updateFlyout, - indexDrawnLayers, } from '../../actions'; import { MapStoreState } from '../../reducers/store'; import { LayerDescriptor } from '../../../common/descriptor_types'; @@ -26,7 +25,6 @@ function mapStateToProps(state: MapStoreState) { return { hasPreviewLayers: hasPreviewLayers(state), isLoadingPreviewLayers: isLoadingPreviewLayers(state), - isDrawingLayer: state.map.mapState.editModeActive, }; } @@ -44,7 +42,6 @@ function mapDispatchToProps(dispatch: ThunkDispatch dispatch(indexDrawnLayers()), }; } diff --git a/x-pack/plugins/maps/public/connected_components/add_layer_panel/view.tsx b/x-pack/plugins/maps/public/connected_components/add_layer_panel/view.tsx index 653fa4b6297bc4..7f3c7f3d3f8c5a 100644 --- a/x-pack/plugins/maps/public/connected_components/add_layer_panel/view.tsx +++ b/x-pack/plugins/maps/public/connected_components/add_layer_panel/view.tsx @@ -33,8 +33,6 @@ export interface Props { hasPreviewLayers: boolean; isLoadingPreviewLayers: boolean; promotePreviewLayers: () => void; - isDrawingLayer: boolean; - indexDrawnLayers: () => void; } interface State { @@ -90,10 +88,7 @@ export class AddLayerPanel extends Component { return; } - if (this.props.isDrawingLayer) { - // Write to index - this.props.indexDrawnLayers(); - } else if (this.state.layerSteps.length - 1 === this.state.currentStepIndex) { + if (this.state.layerSteps.length - 1 === this.state.currentStepIndex) { // last step this.props.promotePreviewLayers(); } else { diff --git a/x-pack/plugins/maps/server/data_indexing/create_doc_source.ts b/x-pack/plugins/maps/server/data_indexing/create_doc_source.ts index 2b8984aa1534a1..22c3da61244afa 100644 --- a/x-pack/plugins/maps/server/data_indexing/create_doc_source.ts +++ b/x-pack/plugins/maps/server/data_indexing/create_doc_source.ts @@ -29,9 +29,10 @@ export async function createDocSource( ): Promise { try { await createIndex(index, mappings, asCurrentUser); - await indexPatternsService.createAndSave({ title: index }, true); + const { id: indexPatternId } = await indexPatternsService.createAndSave({ title: index }, true); return { + indexPatternId, success: true, }; } catch (error) { From d450fd19a14e1f3b55a60720908a708870a19077 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 7 Apr 2021 10:26:46 -0600 Subject: [PATCH 016/103] Adjust addLayer call for async --- .../maps/public/classes/layers/new_vector_layer_wizard/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/index.ts b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/index.ts index 9afd0d83533bec..ec98f6bd2056f9 100644 --- a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/index.ts +++ b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/index.ts @@ -37,7 +37,7 @@ function mapDispatchToProps(dispatch: ThunkDispatch { - dispatch(addLayer(layerDescriptor)); + await dispatch(addLayer(layerDescriptor)); await dispatch(setSelectedLayer(layerDescriptor.id)); dispatch(updateFlyout(FLYOUT_STATE.LAYER_PANEL)); }, From b12ad85fd343f891ee4b95190c80d191b30ceca7 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 7 Apr 2021 13:52:29 -0600 Subject: [PATCH 017/103] Add edit controls --- x-pack/plugins/maps/common/constants.ts | 3 + .../mb_map/draw_control/draw_control.tsx | 23 ++++++-- .../feature_edit_control.test.tsx.snap | 0 .../_index.scss | 0 .../feature_draw_control.tsx} | 22 +++---- .../feature_draw_control/index.ts | 38 ++++++++++++ .../feature_edit_control.tsx | 59 +++++++++++++++++++ .../feature_edit_control/index.ts | 9 +-- .../feature_edit_control.test.tsx | 36 ----------- .../toolbar_overlay/toolbar_overlay.tsx | 18 ++++-- 10 files changed, 145 insertions(+), 63 deletions(-) rename x-pack/plugins/maps/public/connected_components/toolbar_overlay/{feature_edit_control => feature_draw_controls}/__snapshots__/feature_edit_control.test.tsx.snap (100%) rename x-pack/plugins/maps/public/connected_components/toolbar_overlay/{feature_edit_control => feature_draw_controls}/_index.scss (100%) rename x-pack/plugins/maps/public/connected_components/toolbar_overlay/{feature_edit_control/feature_edit_control.tsx => feature_draw_controls/feature_draw_control/feature_draw_control.tsx} (86%) create mode 100644 x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/index.ts create mode 100644 x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/feature_edit_control.tsx rename x-pack/plugins/maps/public/connected_components/toolbar_overlay/{ => feature_draw_controls}/feature_edit_control/index.ts (77%) delete mode 100644 x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.test.tsx diff --git a/x-pack/plugins/maps/common/constants.ts b/x-pack/plugins/maps/common/constants.ts index 33f2a52c6331d9..77dafa99a7087e 100644 --- a/x-pack/plugins/maps/common/constants.ts +++ b/x-pack/plugins/maps/common/constants.ts @@ -158,6 +158,9 @@ export enum DRAW_TYPE { POLYGON = 'POLYGON', POINT = 'POINT', LINE = 'LINE', + DIRECT_SELECT = 'DIRECT_SELECT', + SIMPLE_SELECT = 'SIMPLE_SELECT', + TRASH = 'TRASH', } export const AGG_DELIMITER = '_of_'; diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx index f30a62bb0ed74a..614cd5c95c1798 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx @@ -6,17 +6,18 @@ */ import _ from 'lodash'; -import React, {Component} from 'react'; +import React, { Component } from 'react'; // @ts-expect-error import MapboxDraw from '@mapbox/mapbox-gl-draw'; // @ts-expect-error import DrawRectangle from 'mapbox-gl-draw-rectangle-mode'; -import {Map as MbMap} from 'mapbox-gl'; -import {Feature} from 'geojson'; -import {DRAW_TYPE} from '../../../../common/constants'; -import {DrawCircle} from './draw_circle'; -import {DrawTooltip} from './draw_tooltip'; +import { Map as MbMap } from 'mapbox-gl'; +import { Feature } from 'geojson'; +import { DRAW_TYPE } from '../../../../common/constants'; +import { DrawCircle } from './draw_circle'; +import { DrawTooltip } from './draw_tooltip'; +const SIMPLE_SELECT = 'simple_select'; const DRAW_RECTANGLE = 'draw_rectangle'; const DRAW_CIRCLE = 'draw_circle'; const DRAW_POLYGON = 'draw_polygon'; @@ -76,10 +77,17 @@ export class DrawControl extends Component { this.props.mbMap.getCanvas().style.cursor = ''; this.props.mbMap.off('draw.create', this.props.onDraw); + this.props.mbMap.off('draw.selectionchange', this._handleFeatureSelected); this.props.mbMap.removeControl(this._mbDrawControl); this._mbDrawControlAdded = false; } + _handleFeatureSelected = () => { + if (this.props.drawType === DRAW_TYPE.TRASH) { + this._mbDrawControl.trash(); + } + }; + _updateDrawControl() { if (!this.props.drawType) { return; @@ -90,6 +98,7 @@ export class DrawControl extends Component { this._mbDrawControlAdded = true; this.props.mbMap.getCanvas().style.cursor = 'crosshair'; this.props.mbMap.on('draw.create', this.props.onDraw); + this.props.mbMap.on('draw.selectionchange', this._handleFeatureSelected); } const drawMode = this._mbDrawControl.getMode(); @@ -103,6 +112,8 @@ export class DrawControl extends Component { this._mbDrawControl.changeMode(DRAW_POLYGON); } else if (drawMode !== DRAW_POINT && this.props.drawType === DRAW_TYPE.POINT) { this._mbDrawControl.changeMode(DRAW_POINT); + } else if (drawMode !== SIMPLE_SELECT && this.props.drawType === DRAW_TYPE.SIMPLE_SELECT) { + this._mbDrawControl.changeMode(SIMPLE_SELECT); } else if ( drawMode !== this._mbDrawControl.modes.DRAW_POLYGON && this.props.drawType === DRAW_TYPE.POLYGON diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/__snapshots__/feature_edit_control.test.tsx.snap b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/__snapshots__/feature_edit_control.test.tsx.snap similarity index 100% rename from x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/__snapshots__/feature_edit_control.test.tsx.snap rename to x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/__snapshots__/feature_edit_control.test.tsx.snap diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/_index.scss b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/_index.scss similarity index 100% rename from x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/_index.scss rename to x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/_index.scss diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx similarity index 86% rename from x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.tsx rename to x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx index 684eb92b4b9399..1916a1529cba22 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx @@ -8,16 +8,16 @@ import React from 'react'; import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { DRAW_TYPE } from '../../../../common/constants'; +import { DRAW_TYPE } from '../../../../../common/constants'; // @ts-expect-error -import { GeometryFilterForm } from '../../../components/geometry_filter_form'; +import { GeometryFilterForm } from '../../../../components/geometry_filter_form'; export interface Props { cancelDraw: () => void; initiateDraw: (drawFeatureState: DRAW_TYPE) => void; } -export function FeatureEditControl(props: Props) { +export function FeatureDrawControl(props: Props) { return ( @@ -26,10 +26,10 @@ export function FeatureEditControl(props: Props) { className="mapToolbarOverlay__button" onClick={() => props.initiateDraw(DRAW_TYPE.LINE)} iconType="minus" - aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.drawLineLabel', { + aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawLineLabel', { defaultMessage: 'Draw line', })} - title={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.drawLineTitle', { + title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawLineTitle', { defaultMessage: 'Draw line', })} /> @@ -39,10 +39,10 @@ export function FeatureEditControl(props: Props) { className="mapToolbarOverlay__button" onClick={() => props.initiateDraw(DRAW_TYPE.POLYGON)} iconType="home" - aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.drawPolygonLabel', { + aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawPolygonLabel', { defaultMessage: 'Draw polygon', })} - title={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.drawLineTitle', { + title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawLineTitle', { defaultMessage: 'Draw polygon', })} /> @@ -52,10 +52,10 @@ export function FeatureEditControl(props: Props) { className="mapToolbarOverlay__button" onClick={() => props.initiateDraw(DRAW_TYPE.BOUNDS)} iconType="stop" - aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.drawBBoxLabel', { + aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawBBoxLabel', { defaultMessage: 'Draw bounding box', })} - title={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.drawBBoxTitle', { + title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawBBoxTitle', { defaultMessage: 'Draw bounding box', })} /> @@ -65,10 +65,10 @@ export function FeatureEditControl(props: Props) { className="mapToolbarOverlay__button" onClick={() => props.initiateDraw(DRAW_TYPE.POINT)} iconType="dot" - aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.drawPointLabel', { + aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawPointLabel', { defaultMessage: 'Draw point', })} - title={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.drawPointTitle', { + title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawPointTitle', { defaultMessage: 'Draw point', })} /> diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/index.ts new file mode 100644 index 00000000000000..ed6c0703bdcc4b --- /dev/null +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/index.ts @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { AnyAction } from 'redux'; +import { ThunkDispatch } from 'redux-thunk'; +import { connect } from 'react-redux'; +import { FeatureDrawControl } from './feature_draw_control'; +import { isDrawingFilter } from '../../../../selectors/map_selectors'; +import { updateDrawFeatureState } from '../../../../actions'; +import { MapStoreState } from '../../../../reducers/store'; +import { DRAW_TYPE } from '../../../../../common'; + +function mapStateToProps(state: MapStoreState) { + return { + isDrawingFilter: isDrawingFilter(state), + }; +} + +function mapDispatchToProps(dispatch: ThunkDispatch) { + return { + initiateDraw: (drawFeatureState: DRAW_TYPE) => { + dispatch(updateDrawFeatureState(drawFeatureState)); + }, + cancelDraw: () => { + dispatch(updateDrawFeatureState(null)); + }, + }; +} + +const connectedFeatureEditControl = connect( + mapStateToProps, + mapDispatchToProps +)(FeatureDrawControl); +export { connectedFeatureEditControl as FeatureDrawControl }; diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/feature_edit_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/feature_edit_control.tsx new file mode 100644 index 00000000000000..deec404d245540 --- /dev/null +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/feature_edit_control.tsx @@ -0,0 +1,59 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { DRAW_TYPE } from '../../../../../common/constants'; +// @ts-expect-error +import { GeometryFilterForm } from '../../../../components/geometry_filter_form'; + +export interface Props { + isDrawingFilter: boolean; + drawType: string; + cancelDraw: () => void; + initiateDraw: (drawFeatureState: DRAW_TYPE) => void; +} + +export function FeatureEditControl(props: Props) { + return ( + + + + props.initiateDraw(DRAW_TYPE.SIMPLE_SELECT)} + iconType="documentEdit" + aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.editFeaturesLabel', { + defaultMessage: 'Edit features', + })} + title={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.editFeaturesTitle', { + defaultMessage: 'Edit features', + })} + aria-pressed={props.drawType === DRAW_TYPE.SIMPLE_SELECT} + isSelected={props.drawType === DRAW_TYPE.SIMPLE_SELECT} + /> + + + props.initiateDraw(DRAW_TYPE.TRASH)} + iconType="trash" + aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.deleteLabel', { + defaultMessage: 'Remove feature', + })} + title={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.deleteTitle', { + defaultMessage: 'Remove feature', + })} + aria-pressed={props.drawType === DRAW_TYPE.TRASH} + isSelected={props.drawType === DRAW_TYPE.TRASH} + /> + + + + ); +} diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/index.ts similarity index 77% rename from x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/index.ts rename to x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/index.ts index 904421a0012171..ca6c7c5bfacde3 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/index.ts @@ -9,14 +9,15 @@ import { AnyAction } from 'redux'; import { ThunkDispatch } from 'redux-thunk'; import { connect } from 'react-redux'; import { FeatureEditControl } from './feature_edit_control'; -import { isDrawingFilter } from '../../../selectors/map_selectors'; -import { updateDrawFeatureState } from '../../../actions'; -import { MapStoreState } from '../../../reducers/store'; -import { DRAW_TYPE } from '../../../../common'; +import { isDrawingFilter } from '../../../../selectors/map_selectors'; +import { updateDrawFeatureState } from '../../../../actions'; +import { MapStoreState } from '../../../../reducers/store'; +import { DRAW_TYPE } from '../../../../../common'; function mapStateToProps(state: MapStoreState) { return { isDrawingFilter: isDrawingFilter(state), + drawType: state.map.mapState.drawFeatureState, }; } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.test.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.test.tsx deleted file mode 100644 index afcf0de5c8baf7..00000000000000 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_edit_control/feature_edit_control.test.tsx +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { shallow } from 'enzyme'; -import { FeatureEditControl } from './feature_edit_control'; - -const defaultProps = { - initiateDraw: () => {}, - cancelDraw: () => {}, - geoFields: [ - { - geoFieldName: 'location', - geoFieldType: 'geo_point', - indexPatternTitle: 'my_index', - indexPatternId: '1', - }, - ], - isDrawingFilter: false, -}; - -test('renders', async () => { - const component = shallow(); - - expect(component).toMatchSnapshot(); -}); - -test('Should render cancel button when drawing', async () => { - const component = shallow(); - - expect(component).toMatchSnapshot(); -}); diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx index 7461f9724295fa..149eea8c0f207e 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx @@ -11,7 +11,8 @@ import { Filter } from 'src/plugins/data/public'; import { ActionExecutionContext, Action } from 'src/plugins/ui_actions/public'; import { SetViewControl } from './set_view_control'; import { ToolsControl } from './tools_control'; -import { FeatureEditControl } from './feature_edit_control'; +import { FeatureDrawControl } from './feature_draw_controls/feature_draw_control'; +import { FeatureEditControl } from './feature_draw_controls/feature_edit_control'; import { FitToData } from './fit_to_data'; import { GeoFieldWithIndex } from '../../components/geo_field_with_index'; @@ -41,11 +42,16 @@ export function ToolbarOverlay(props: Props) { ); } - function renderFeatureEditControl() { + function renderFeatureDrawAndEditControls() { return props.editModeActive ? ( - - - + <> + + + + + + + ) : null; } @@ -67,7 +73,7 @@ export function ToolbarOverlay(props: Props) { {renderToolsControl()} - {renderFeatureEditControl()} + {renderFeatureDrawAndEditControls()} ); } From 576b3d3b03c53cd55b131104ea74ddfa23e94732 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 7 Apr 2021 15:56:11 -0600 Subject: [PATCH 018/103] Fix deleting functionality to update store --- .../public/actions/map_action_constants.ts | 1 + .../plugins/maps/public/actions/map_actions.ts | 8 ++++++++ .../mb_map/draw_control/draw_control.tsx | 18 ++++++++++-------- .../draw_feature_control.tsx | 11 +++++++++++ .../draw_control/draw_feature_control/index.ts | 9 ++++++++- x-pack/plugins/maps/public/reducers/map/map.ts | 10 ++++++++++ 6 files changed, 48 insertions(+), 9 deletions(-) diff --git a/x-pack/plugins/maps/public/actions/map_action_constants.ts b/x-pack/plugins/maps/public/actions/map_action_constants.ts index e43ef1786f2474..dc8f0a18422880 100644 --- a/x-pack/plugins/maps/public/actions/map_action_constants.ts +++ b/x-pack/plugins/maps/public/actions/map_action_constants.ts @@ -47,5 +47,6 @@ export const ROLLBACK_MAP_SETTINGS = 'ROLLBACK_MAP_SETTINGS'; export const TRACK_MAP_SETTINGS = 'TRACK_MAP_SETTINGS'; export const UPDATE_MAP_SETTING = 'UPDATE_MAP_SETTING'; export const ADD_FEATURES_TO_INDEX_QUEUE = 'ADD_FEATURES_TO_INDEX_QUEUE'; +export const REMOVE_FEATURES_FROM_INDEX_QUEUE = 'REMOVE_FEATURES_FROM_INDEX_QUEUE'; export const SET_VECTOR_LAYER_INDEX_NAME = 'SET_VECTOR_LAYER_INDEX_NAME'; export const INDEX_DRAWN_LAYERS = 'INDEX_DRAWN_LAYERS'; diff --git a/x-pack/plugins/maps/public/actions/map_actions.ts b/x-pack/plugins/maps/public/actions/map_actions.ts index fc6e268528f599..5a761a95c4f1aa 100644 --- a/x-pack/plugins/maps/public/actions/map_actions.ts +++ b/x-pack/plugins/maps/public/actions/map_actions.ts @@ -49,6 +49,7 @@ import { UPDATE_MAP_SETTING, ADD_FEATURES_TO_INDEX_QUEUE, SET_VECTOR_LAYER_INDEX_NAME, + REMOVE_FEATURES_FROM_INDEX_QUEUE, } from './map_action_constants'; import { autoFitToBounds, syncDataForAllLayers } from './data_request_actions'; import { addLayer, addLayerWithoutDataSync } from './layer_actions'; @@ -355,6 +356,13 @@ export function addFeaturesToIndexQueue(features: Feature[]) { }; } +export function removeFeaturesFromIndexQueue(featureIds: string[]) { + return { + type: REMOVE_FEATURES_FROM_INDEX_QUEUE, + featureIds, + }; +} + export function setVectorLayerIndexName(indexName: string) { return { type: SET_VECTOR_LAYER_INDEX_NAME, diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx index 614cd5c95c1798..6a02029159667f 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx @@ -31,6 +31,7 @@ mbDrawModes[DRAW_CIRCLE] = DrawCircle; export interface Props { drawType?: DRAW_TYPE; onDraw: (event: { features: Feature[] }) => void; + onFeaturesSelected?: (drawControl: MapboxDraw) => (event: { features: Feature[] }) => void; mbMap: MbMap; drawActive: boolean; } @@ -77,17 +78,13 @@ export class DrawControl extends Component { this.props.mbMap.getCanvas().style.cursor = ''; this.props.mbMap.off('draw.create', this.props.onDraw); - this.props.mbMap.off('draw.selectionchange', this._handleFeatureSelected); + if (this.props.onFeaturesSelected) { + this.props.mbMap.off('draw.selectionchange', this.props.onFeaturesSelected); + } this.props.mbMap.removeControl(this._mbDrawControl); this._mbDrawControlAdded = false; } - _handleFeatureSelected = () => { - if (this.props.drawType === DRAW_TYPE.TRASH) { - this._mbDrawControl.trash(); - } - }; - _updateDrawControl() { if (!this.props.drawType) { return; @@ -98,7 +95,12 @@ export class DrawControl extends Component { this._mbDrawControlAdded = true; this.props.mbMap.getCanvas().style.cursor = 'crosshair'; this.props.mbMap.on('draw.create', this.props.onDraw); - this.props.mbMap.on('draw.selectionchange', this._handleFeatureSelected); + if (this.props.onFeaturesSelected) { + this.props.mbMap.on( + 'draw.selectionchange', + this.props.onFeaturesSelected(this._mbDrawControl) + ); + } } const drawMode = this._mbDrawControl.getMode(); diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx index 6e0bb65709f287..cc4bd2ae4e48e3 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx @@ -7,6 +7,8 @@ import React, { Component } from 'react'; import { Map as MbMap } from 'mapbox-gl'; +// @ts-expect-error +import MapboxDraw from '@mapbox/mapbox-gl-draw'; import { Feature } from 'geojson'; import { i18n } from '@kbn/i18n'; import { getToasts } from '../../../../kibana_services'; @@ -16,11 +18,19 @@ import { DRAW_TYPE } from '../../../../../common'; export interface Props { disableDrawState: () => void; addFeaturesToIndexQueue: (features: Feature[]) => void; + removeFeatures: (featureIds: string[]) => void; drawType: DRAW_TYPE; mbMap: MbMap; } export class DrawFeatureControl extends Component { + _onFeaturesSelected = (mbDrawControl: MapboxDraw) => (e: { features: Feature[] }) => { + if (this.props.drawType === DRAW_TYPE.TRASH) { + this.props.removeFeatures(e.features.map(({ id }: {id: string}) => id)); + mbDrawControl.trash(); + } + }; + _onDraw = async (e: { features: Feature[] }) => { try { console.log(e); @@ -44,6 +54,7 @@ export class DrawFeatureControl extends Component { diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts index 9069090b2b700e..c2a01b05c5bbd6 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts @@ -10,7 +10,11 @@ import { ThunkDispatch } from 'redux-thunk'; import { connect } from 'react-redux'; import { Feature } from 'geojson'; import { DrawFeatureControl } from './draw_feature_control'; -import { addFeaturesToIndexQueue, updateDrawFeatureState } from '../../../../actions'; +import { + addFeaturesToIndexQueue, + removeFeaturesFromIndexQueue, + updateDrawFeatureState, +} from '../../../../actions'; import { MapStoreState } from '../../../../reducers/store'; function mapStateToProps(state: MapStoreState) { @@ -27,6 +31,9 @@ function mapDispatchToProps(dispatch: ThunkDispatch !action.featureIds.includes(id)) + return { + ...state, + mapState: { + ...state.mapState, + featuresToIndexQueue: newFeatureArr, + }, + }; case SET_VECTOR_LAYER_INDEX_NAME: return { ...state, From cd211f9f9355d191cc406e7362c940ff6661e621 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 7 Apr 2021 20:59:15 -0600 Subject: [PATCH 019/103] Add toggle color to buttons. Fall back to edit between drawings --- x-pack/plugins/maps/common/constants.ts | 1 - .../mb_map/draw_control/draw_control.tsx | 20 ++++++++++++++++- .../draw_feature_control.tsx | 4 ++-- .../draw_filter_control.tsx | 2 +- .../mb_map/draw_control/index.ts | 19 +++++++++++++++- .../connected_components/mb_map/mb_map.tsx | 2 +- .../toolbar_overlay/_index.scss | 15 +++++++++++++ .../feature_draw_control.tsx | 22 +++++++++++++++---- .../feature_draw_control/index.ts | 1 + .../feature_edit_control.tsx | 14 +++++++----- 10 files changed, 83 insertions(+), 17 deletions(-) diff --git a/x-pack/plugins/maps/common/constants.ts b/x-pack/plugins/maps/common/constants.ts index 77dafa99a7087e..e842384d26a28e 100644 --- a/x-pack/plugins/maps/common/constants.ts +++ b/x-pack/plugins/maps/common/constants.ts @@ -158,7 +158,6 @@ export enum DRAW_TYPE { POLYGON = 'POLYGON', POINT = 'POINT', LINE = 'LINE', - DIRECT_SELECT = 'DIRECT_SELECT', SIMPLE_SELECT = 'SIMPLE_SELECT', TRASH = 'TRASH', } diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx index 6a02029159667f..5eafd4b5b48faa 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx @@ -24,6 +24,15 @@ const DRAW_POLYGON = 'draw_polygon'; const DRAW_LINE = 'draw_line_string'; const DRAW_POINT = 'draw_point'; +const mbModeEquivalencies = new Map([ + ['simple_select', 'SIMPLE_SELECT'], + ['draw_rectangle', 'BOUNDS'], + ['draw_circle', 'DISTANCE'], + ['draw_polygon', 'POLYGON'], + ['draw_line_string', 'LINE'], + ['draw_point', 'POINT'], +]); + const mbDrawModes = MapboxDraw.modes; mbDrawModes[DRAW_RECTANGLE] = DrawRectangle; mbDrawModes[DRAW_CIRCLE] = DrawCircle; @@ -34,9 +43,10 @@ export interface Props { onFeaturesSelected?: (drawControl: MapboxDraw) => (event: { features: Feature[] }) => void; mbMap: MbMap; drawActive: boolean; + updateDrawFeatureState: (drawFeatureState: DRAW_TYPE) => void; } -export class DrawControl extends Component { +export class DrawControl extends Component { private _isMounted = false; private _mbDrawControlAdded = false; private _mbDrawControl = new MapboxDraw({ @@ -71,12 +81,19 @@ export class DrawControl extends Component { } }, 0); + _onModeChange = ({ mode }: { mode: string }) => { + if (mbModeEquivalencies.has(mode)) { + this.props.updateDrawFeatureState(mbModeEquivalencies.get(mode) as DRAW_TYPE); + } + }; + _removeDrawControl() { if (!this._mbDrawControlAdded) { return; } this.props.mbMap.getCanvas().style.cursor = ''; + this.props.mbMap.off('draw.modechange', this._onModeChange); this.props.mbMap.off('draw.create', this.props.onDraw); if (this.props.onFeaturesSelected) { this.props.mbMap.off('draw.selectionchange', this.props.onFeaturesSelected); @@ -94,6 +111,7 @@ export class DrawControl extends Component { this.props.mbMap.addControl(this._mbDrawControl); this._mbDrawControlAdded = true; this.props.mbMap.getCanvas().style.cursor = 'crosshair'; + this.props.mbMap.on('draw.modechange', this._onModeChange); this.props.mbMap.on('draw.create', this.props.onDraw); if (this.props.onFeaturesSelected) { this.props.mbMap.on( diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx index cc4bd2ae4e48e3..305c3596245194 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx @@ -12,7 +12,7 @@ import MapboxDraw from '@mapbox/mapbox-gl-draw'; import { Feature } from 'geojson'; import { i18n } from '@kbn/i18n'; import { getToasts } from '../../../../kibana_services'; -import { DrawControl } from '../draw_control'; +import { DrawControl } from '../'; import { DRAW_TYPE } from '../../../../../common'; export interface Props { @@ -26,7 +26,7 @@ export interface Props { export class DrawFeatureControl extends Component { _onFeaturesSelected = (mbDrawControl: MapboxDraw) => (e: { features: Feature[] }) => { if (this.props.drawType === DRAW_TYPE.TRASH) { - this.props.removeFeatures(e.features.map(({ id }: {id: string}) => id)); + this.props.removeFeatures(e.features.map(({ id }: { id: string }) => id)); mbDrawControl.trash(); } }; diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_filter_control/draw_filter_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_filter_control/draw_filter_control.tsx index 9e13f7afb6cc3d..ea394c7c0a8e24 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_filter_control/draw_filter_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_filter_control/draw_filter_control.tsx @@ -24,7 +24,7 @@ import { roundCoordinates, } from '../../../../../common/elasticsearch_util'; import { getToasts } from '../../../../kibana_services'; -import { DrawControl } from '../draw_control'; +import { DrawControl } from '../'; import { DrawCircleProperties } from '../draw_circle'; export interface Props { diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/index.ts b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/index.ts index 63f91a03a5d012..5e97d0257bd46f 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/index.ts @@ -5,4 +5,21 @@ * 2.0. */ -export { DrawFilterControl } from './draw_filter_control'; +import { ThunkDispatch } from 'redux-thunk'; +import { AnyAction } from 'redux'; +import { connect } from 'react-redux'; +import { updateDrawFeatureState } from '../../../actions'; +import { MapStoreState } from '../../../reducers/store'; +import { DrawControl } from './draw_control'; +import { DRAW_TYPE } from '../../../../common'; + +function mapDispatchToProps(dispatch: ThunkDispatch) { + return { + updateDrawFeatureState(drawFeatureState: DRAW_TYPE) { + dispatch(updateDrawFeatureState(drawFeatureState)); + }, + }; +} + +const connected = connect(null, mapDispatchToProps)(DrawControl); +export { connected as DrawControl }; diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/mb_map.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/mb_map.tsx index b7c2a4fb772a69..f6d8fabba17ab4 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/mb_map.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/mb_map.tsx @@ -17,7 +17,7 @@ import sprites2 from '@elastic/maki/dist/sprite@2.png'; import { Adapters } from 'src/plugins/inspector/public'; import { Filter } from 'src/plugins/data/public'; import { ActionExecutionContext, Action } from 'src/plugins/ui_actions/public'; -import { DrawFilterControl } from './draw_control'; +import { DrawFilterControl } from './draw_control/draw_filter_control'; import { ScaleControl } from './scale_control'; // @ts-expect-error import { TooltipControl } from './tooltip_control'; diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/_index.scss b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/_index.scss index 7bd002a2c970aa..17e629977465f8 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/_index.scss +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/_index.scss @@ -21,3 +21,18 @@ @include euiBottomShadowLarge; } } + +.mapToolbarOverlay__button__selected { + @include size($euiSizeXL); + // sass-lint:disable-block no-important + color: $euiTextColor !important; + background-color: $euiColorLightShade !important; + pointer-events: all; + position: relative; + + &:enabled, + &:enabled:hover, + &:enabled:focus { + @include euiBottomShadowLarge; + } +} diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx index 1916a1529cba22..be6e09c264c6d8 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx @@ -14,16 +14,22 @@ import { GeometryFilterForm } from '../../../../components/geometry_filter_form' export interface Props { cancelDraw: () => void; + drawType: string; initiateDraw: (drawFeatureState: DRAW_TYPE) => void; } export function FeatureDrawControl(props: Props) { + const drawLineSelected = props.drawType === DRAW_TYPE.LINE; + const drawPolygonSelected = props.drawType === DRAW_TYPE.POLYGON; + const drawBBoxSelected = props.drawType === DRAW_TYPE.BOUNDS; + const drawPointSelected = props.drawType === DRAW_TYPE.POINT; + return ( props.initiateDraw(DRAW_TYPE.LINE)} iconType="minus" aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawLineLabel', { @@ -32,11 +38,13 @@ export function FeatureDrawControl(props: Props) { title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawLineTitle', { defaultMessage: 'Draw line', })} + aria-pressed={drawLineSelected} + isSelected={drawLineSelected} /> props.initiateDraw(DRAW_TYPE.POLYGON)} iconType="home" aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawPolygonLabel', { @@ -45,11 +53,13 @@ export function FeatureDrawControl(props: Props) { title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawLineTitle', { defaultMessage: 'Draw polygon', })} + aria-pressed={drawPolygonSelected} + isSelected={drawPolygonSelected} /> props.initiateDraw(DRAW_TYPE.BOUNDS)} iconType="stop" aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawBBoxLabel', { @@ -58,11 +68,13 @@ export function FeatureDrawControl(props: Props) { title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawBBoxTitle', { defaultMessage: 'Draw bounding box', })} + aria-pressed={drawBBoxSelected} + isSelected={drawBBoxSelected} /> props.initiateDraw(DRAW_TYPE.POINT)} iconType="dot" aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawPointLabel', { @@ -71,6 +83,8 @@ export function FeatureDrawControl(props: Props) { title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawPointTitle', { defaultMessage: 'Draw point', })} + aria-pressed={drawPointSelected} + isSelected={drawPointSelected} /> diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/index.ts index ed6c0703bdcc4b..013aa2d79153c6 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/index.ts @@ -17,6 +17,7 @@ import { DRAW_TYPE } from '../../../../../common'; function mapStateToProps(state: MapStoreState) { return { isDrawingFilter: isDrawingFilter(state), + drawType: state.map.mapState.drawFeatureState, }; } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/feature_edit_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/feature_edit_control.tsx index deec404d245540..ea2866a84b4206 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/feature_edit_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/feature_edit_control.tsx @@ -20,12 +20,14 @@ export interface Props { } export function FeatureEditControl(props: Props) { + const editFeaturesSelected = props.drawType === DRAW_TYPE.SIMPLE_SELECT; + const deleteFeaturesSelected = props.drawType === DRAW_TYPE.TRASH; return ( props.initiateDraw(DRAW_TYPE.SIMPLE_SELECT)} iconType="documentEdit" aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.editFeaturesLabel', { @@ -34,13 +36,13 @@ export function FeatureEditControl(props: Props) { title={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.editFeaturesTitle', { defaultMessage: 'Edit features', })} - aria-pressed={props.drawType === DRAW_TYPE.SIMPLE_SELECT} - isSelected={props.drawType === DRAW_TYPE.SIMPLE_SELECT} + aria-pressed={editFeaturesSelected} + isSelected={editFeaturesSelected} /> props.initiateDraw(DRAW_TYPE.TRASH)} iconType="trash" aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.deleteLabel', { @@ -49,8 +51,8 @@ export function FeatureEditControl(props: Props) { title={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.deleteTitle', { defaultMessage: 'Remove feature', })} - aria-pressed={props.drawType === DRAW_TYPE.TRASH} - isSelected={props.drawType === DRAW_TYPE.TRASH} + aria-pressed={deleteFeaturesSelected} + isSelected={deleteFeaturesSelected} /> From 4f79738102ee8537f945f4277c4e6f8edd8493c3 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 7 Apr 2021 21:41:13 -0600 Subject: [PATCH 020/103] Deselect features still selected when entering trash mode --- .../mb_map/draw_control/draw_control.tsx | 8 ++++++++ .../feature_edit_control/feature_edit_control.tsx | 1 + 2 files changed, 9 insertions(+) diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx index 5eafd4b5b48faa..a80662571ce68e 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx @@ -121,6 +121,14 @@ export class DrawControl extends Component { } } + if (this.props.drawType === DRAW_TYPE.TRASH) { + // There is no way to deselect shapes other than changing modes, + // this deselects shapes to avoid leaving shapes in an unwanted + // edit mode + this._mbDrawControl.changeMode('simple_select'); + return; + } + const drawMode = this._mbDrawControl.getMode(); if (drawMode !== DRAW_RECTANGLE && this.props.drawType === DRAW_TYPE.BOUNDS) { this._mbDrawControl.changeMode(DRAW_RECTANGLE); diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/feature_edit_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/feature_edit_control.tsx index ea2866a84b4206..7744ba309945cf 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/feature_edit_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/feature_edit_control.tsx @@ -22,6 +22,7 @@ export interface Props { export function FeatureEditControl(props: Props) { const editFeaturesSelected = props.drawType === DRAW_TYPE.SIMPLE_SELECT; const deleteFeaturesSelected = props.drawType === DRAW_TYPE.TRASH; + return ( From ceae6d25909a1b9fc238c35651560bd649893c9d Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 7 Apr 2021 22:02:14 -0600 Subject: [PATCH 021/103] Add geometry check to filter out invalid geometries --- .../mb_map/draw_control/draw_control.tsx | 4 ++-- .../draw_feature_control/draw_feature_control.tsx | 14 ++++++++++++-- .../draw_filter_control/draw_filter_control.tsx | 2 +- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx index a80662571ce68e..20a10753e64e3a 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx @@ -39,7 +39,7 @@ mbDrawModes[DRAW_CIRCLE] = DrawCircle; export interface Props { drawType?: DRAW_TYPE; - onDraw: (event: { features: Feature[] }) => void; + onDraw: (drawControl: MapboxDraw) => (event: { features: Feature[] }) => void; onFeaturesSelected?: (drawControl: MapboxDraw) => (event: { features: Feature[] }) => void; mbMap: MbMap; drawActive: boolean; @@ -112,7 +112,7 @@ export class DrawControl extends Component { this._mbDrawControlAdded = true; this.props.mbMap.getCanvas().style.cursor = 'crosshair'; this.props.mbMap.on('draw.modechange', this._onModeChange); - this.props.mbMap.on('draw.create', this.props.onDraw); + this.props.mbMap.on('draw.create', this.props.onDraw(this._mbDrawControl)); if (this.props.onFeaturesSelected) { this.props.mbMap.on( 'draw.selectionchange', diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx index 305c3596245194..c04dec50e92048 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx @@ -11,10 +11,14 @@ import { Map as MbMap } from 'mapbox-gl'; import MapboxDraw from '@mapbox/mapbox-gl-draw'; import { Feature } from 'geojson'; import { i18n } from '@kbn/i18n'; +// @ts-expect-error +import * as jsts from 'jsts'; import { getToasts } from '../../../../kibana_services'; import { DrawControl } from '../'; import { DRAW_TYPE } from '../../../../../common'; +const geoJSONReader = new jsts.io.GeoJSONReader(); + export interface Props { disableDrawState: () => void; addFeaturesToIndexQueue: (features: Feature[]) => void; @@ -31,9 +35,15 @@ export class DrawFeatureControl extends Component { } }; - _onDraw = async (e: { features: Feature[] }) => { + _onDraw = (mbDrawControl: MapboxDraw) => async (e: { features: Feature[] }) => { try { - console.log(e); + e.features.forEach((feature: Feature) => { + const { geometry } = geoJSONReader.read(feature); + if (!geometry.isSimple() || !geometry.isValid()) { + mbDrawControl.delete(feature.id); + throw new Error('Invalid geometry detected'); + } + }); this.props.addFeaturesToIndexQueue(e.features); } catch (error) { getToasts().addWarning( diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_filter_control/draw_filter_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_filter_control/draw_filter_control.tsx index ea394c7c0a8e24..2e255bb26e9901 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_filter_control/draw_filter_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_filter_control/draw_filter_control.tsx @@ -36,7 +36,7 @@ export interface Props { } export class DrawFilterControl extends Component { - _onDraw = async (e: { features: Feature[] }) => { + _onDraw = () => async (e: { features: Feature[] }) => { if ( !e.features.length || !this.props.drawState || From bee0fd5e03c133f79f483a1dca7c7935afc1ab6a Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 7 Apr 2021 22:20:15 -0600 Subject: [PATCH 022/103] Clear out old drawing data on cancel. Update action names --- x-pack/plugins/maps/public/actions/layer_actions.ts | 6 +++--- .../maps/public/actions/map_action_constants.ts | 2 +- .../classes/layers/new_vector_layer_wizard/index.ts | 11 +++++++---- .../classes/layers/new_vector_layer_wizard/wizard.tsx | 4 ++-- .../draw_feature_control/draw_feature_control.tsx | 2 +- x-pack/plugins/maps/public/reducers/map/map.ts | 9 ++++++--- 6 files changed, 20 insertions(+), 14 deletions(-) diff --git a/x-pack/plugins/maps/public/actions/layer_actions.ts b/x-pack/plugins/maps/public/actions/layer_actions.ts index 78e3b5483f3b7c..646197713432d3 100644 --- a/x-pack/plugins/maps/public/actions/layer_actions.ts +++ b/x-pack/plugins/maps/public/actions/layer_actions.ts @@ -37,7 +37,7 @@ import { UPDATE_LAYER_PROP, UPDATE_LAYER_STYLE, UPDATE_SOURCE_PROP, - INDEX_DRAWN_LAYERS, + CLEAR_DRAWING_DATA, } from './map_action_constants'; import { clearDataRequests, syncDataForLayerId, updateStyleMeta } from './data_request_actions'; import { cleanTooltipStateForLayer } from './tooltip_actions'; @@ -555,8 +555,8 @@ export function setAreTilesLoaded(layerId: string, areTilesLoaded: boolean) { }; } -export function indexDrawnLayers() { +export function clearDrawingData() { return { - type: INDEX_DRAWN_LAYERS, + type: CLEAR_DRAWING_DATA, }; } diff --git a/x-pack/plugins/maps/public/actions/map_action_constants.ts b/x-pack/plugins/maps/public/actions/map_action_constants.ts index dc8f0a18422880..e40ada35cd442a 100644 --- a/x-pack/plugins/maps/public/actions/map_action_constants.ts +++ b/x-pack/plugins/maps/public/actions/map_action_constants.ts @@ -49,4 +49,4 @@ export const UPDATE_MAP_SETTING = 'UPDATE_MAP_SETTING'; export const ADD_FEATURES_TO_INDEX_QUEUE = 'ADD_FEATURES_TO_INDEX_QUEUE'; export const REMOVE_FEATURES_FROM_INDEX_QUEUE = 'REMOVE_FEATURES_FROM_INDEX_QUEUE'; export const SET_VECTOR_LAYER_INDEX_NAME = 'SET_VECTOR_LAYER_INDEX_NAME'; -export const INDEX_DRAWN_LAYERS = 'INDEX_DRAWN_LAYERS'; +export const CLEAR_DRAWING_DATA = 'CLEAR_DRAWING_DATA'; diff --git a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/index.ts b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/index.ts index ec98f6bd2056f9..efe1686ad5a43b 100644 --- a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/index.ts +++ b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/index.ts @@ -12,7 +12,7 @@ import { MapStoreState } from '../../../reducers/store'; import { NewVectorLayerEditor } from './wizard'; import { addLayer, - indexDrawnLayers, + clearDrawingData, setSelectedLayer, setVectorLayerIndexName, updateEditMode, @@ -31,10 +31,13 @@ function mapStateToProps(state: MapStoreState) { function mapDispatchToProps(dispatch: ThunkDispatch) { return { setEditModeActive: () => dispatch(updateEditMode(true)), - setEditModeInActive: () => dispatch(updateEditMode(false)), + setEditModeInActive: () => { + dispatch(updateEditMode(false)) + dispatch(clearDrawingData()); + }, setIndexName: (indexName: string) => dispatch(setVectorLayerIndexName(indexName)), - indexDrawnLayers: () => { - dispatch(indexDrawnLayers()); + clearDrawingData: () => { + dispatch(clearDrawingData()); }, addNewLayer: async (layerDescriptor: LayerDescriptor) => { await dispatch(addLayer(layerDescriptor)); diff --git a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx index 855a06f8a2fc7f..006c2fa2e14b57 100644 --- a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx +++ b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx @@ -38,7 +38,7 @@ interface NewVectorLayerProps extends RenderWizardArguments { setEditModeActive: () => void; setEditModeInActive: () => void; setIndexName: (indexName: string) => void; - indexDrawnLayers: () => void; + clearDrawingData: () => void; addNewLayer: (layerDescriptor: LayerDescriptor) => void; } @@ -76,7 +76,7 @@ export class NewVectorLayerEditor extends Component } if (!this.state.indexingTriggered && currentStepId === ADD_DRAWN_FEATURES_TO_INDEX_STEP_ID) { await this._addFeaturesToNewIndex(); - this.props.indexDrawnLayers(); + this.props.clearDrawingData(); } } diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx index c04dec50e92048..84500e0e1e8148 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx @@ -47,7 +47,7 @@ export class DrawFeatureControl extends Component { this.props.addFeaturesToIndexQueue(e.features); } catch (error) { getToasts().addWarning( - i18n.translate('xpack.maps.drawFeatureControl.unableToCreatFilter', { + i18n.translate('xpack.maps.drawFeatureControl.unableToCreateFeature', { defaultMessage: `Unable to create feature, error: '{errorMsg}'.`, values: { errorMsg: error.message, diff --git a/x-pack/plugins/maps/public/reducers/map/map.ts b/x-pack/plugins/maps/public/reducers/map/map.ts index 1a95b637201e11..61ff56c8a6e89e 100644 --- a/x-pack/plugins/maps/public/reducers/map/map.ts +++ b/x-pack/plugins/maps/public/reducers/map/map.ts @@ -49,7 +49,7 @@ import { UPDATE_EDIT_MODE, ADD_FEATURES_TO_INDEX_QUEUE, SET_VECTOR_LAYER_INDEX_NAME, - INDEX_DRAWN_LAYERS, + CLEAR_DRAWING_DATA, REMOVE_FEATURES_FROM_INDEX_QUEUE, } from '../../actions'; @@ -84,7 +84,7 @@ export const DEFAULT_MAP_STATE: MapState = { vectorLayerIndexName: '', drawState: undefined, drawFeatureState: undefined, - editModeActive: undefined, + editModeActive: false, featuresToIndexQueue: [], }, selectedLayerId: null, @@ -145,11 +145,14 @@ export function map(state: MapState = DEFAULT_MAP_STATE, action: any) { vectorLayerIndexName: action.indexName, }, }; - case INDEX_DRAWN_LAYERS: + case CLEAR_DRAWING_DATA: return { ...state, mapState: { ...state.mapState, + drawState: undefined, + drawFeatureState: undefined, + editModeActive: false, featuresToIndexQueue: [], }, }; From 37258594b3dcf5181fc72007bf5e8f29b5d735b6 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Thu, 8 Apr 2021 07:20:55 -0600 Subject: [PATCH 023/103] Add circle drawing button --- .../feature_draw_control.tsx | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx index be6e09c264c6d8..c5f3899e4c8982 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx @@ -21,6 +21,7 @@ export interface Props { export function FeatureDrawControl(props: Props) { const drawLineSelected = props.drawType === DRAW_TYPE.LINE; const drawPolygonSelected = props.drawType === DRAW_TYPE.POLYGON; + const drawCircleSelected = props.drawType === DRAW_TYPE.DISTANCE; const drawBBoxSelected = props.drawType === DRAW_TYPE.BOUNDS; const drawPointSelected = props.drawType === DRAW_TYPE.POINT; @@ -46,7 +47,7 @@ export function FeatureDrawControl(props: Props) { props.initiateDraw(DRAW_TYPE.POLYGON)} - iconType="home" + iconType="node" aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawPolygonLabel', { defaultMessage: 'Draw polygon', })} @@ -57,6 +58,21 @@ export function FeatureDrawControl(props: Props) { isSelected={drawPolygonSelected} />
+ + props.initiateDraw(DRAW_TYPE.DISTANCE)} + iconType="plusInCircle" + aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawCircleLabel', { + defaultMessage: 'Draw circle', + })} + title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawCircleTitle', { + defaultMessage: 'Draw circle', + })} + aria-pressed={drawCircleSelected} + isSelected={drawCircleSelected} + /> + Date: Mon, 12 Apr 2021 12:18:08 -0600 Subject: [PATCH 024/103] Add tools show on map with cancel. Not completely connected to add layer code --- .../index_geometry_select_popover_form.js | 69 ++++++++++++++ .../toolbar_overlay/edit_control/_index.scss | 3 + .../edit_control/edit_control.tsx | 92 +++++++++++++++++++ .../toolbar_overlay/edit_control/index.ts | 23 +++++ .../toolbar_overlay/index.ts | 4 + .../toolbar_overlay/toolbar_overlay.tsx | 17 ++++ 6 files changed, 208 insertions(+) create mode 100644 x-pack/plugins/maps/public/components/index_geometry_select_popover_form.js create mode 100644 x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/_index.scss create mode 100644 x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/edit_control.tsx create mode 100644 x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/index.ts diff --git a/x-pack/plugins/maps/public/components/index_geometry_select_popover_form.js b/x-pack/plugins/maps/public/components/index_geometry_select_popover_form.js new file mode 100644 index 00000000000000..281a0fc17e651c --- /dev/null +++ b/x-pack/plugins/maps/public/components/index_geometry_select_popover_form.js @@ -0,0 +1,69 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { EuiForm, EuiButton, EuiSpacer, EuiTextAlign, EuiFormErrorText } from '@elastic/eui'; +import { MultiIndexGeoFieldSelect } from './multi_index_geo_field_select'; +import { i18n } from '@kbn/i18n'; + +export class IndexGeometrySelectPopoverForm extends Component { + static propTypes = { + geoFields: PropTypes.array.isRequired, + onSubmit: PropTypes.func.isRequired, + }; + + state = { + selectedField: this.props.geoFields.length ? this.props.geoFields[0] : undefined, + }; + + _onGeoFieldChange = (selectedField) => { + this.setState({ selectedField }); + }; + + _onSubmit = () => { + this.props.onSubmit({ + indexPatternId: this.state.selectedField.indexPatternId, + geoFieldName: this.state.selectedField.geoFieldName, + geoFieldType: this.state.selectedField.geoFieldType, + }); + }; + + render() { + let error; + if (this.props.errorMsg) { + error = {this.props.errorMsg}; + } + return ( + + + + + + {error} + + + + {i18n.translate('xpack.maps.indexGeometrySelectPopoverForm.buttonTitle', { + defaultMessage: 'Launch edit tool', + })} + + + + ); + } +} diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/_index.scss b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/_index.scss new file mode 100644 index 00000000000000..de86299d559e86 --- /dev/null +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/_index.scss @@ -0,0 +1,3 @@ +.mapDrawControl__geometryFilterForm { + padding: $euiSizeS; +} diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/edit_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/edit_control.tsx new file mode 100644 index 00000000000000..e1bcece2603900 --- /dev/null +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/edit_control.tsx @@ -0,0 +1,92 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { Component } from 'react'; +import { EuiButtonIcon, EuiPopover, EuiFlexItem, EuiFlexGroup, EuiButton } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; +// @ts-expect-error +import { GeometryFilterForm } from '../../../components/geometry_filter_form'; +import { GeoFieldWithIndex } from '../../../components/geo_field_with_index'; +// @ts-expect-error +import { IndexGeometrySelectPopoverForm } from '../../../components/index_geometry_select_popover_form'; + +export interface Props { + geoFields: GeoFieldWithIndex[]; + setEditModeActive: () => void; + setEditModeInActive: () => void; +} + +interface State { + isPopoverOpen: boolean; +} + +export class EditControl extends Component { + state: State = { + isPopoverOpen: false, + }; + + _togglePopover = () => { + this.setState((prevState) => ({ + isPopoverOpen: !prevState.isPopoverOpen, + })); + }; + + _closePopover = () => { + this.setState({ isPopoverOpen: false }); + }; + + _renderEditButton() { + return ( + + ); + } + + render() { + const editPopoverButton = ( + + + + ); + + return ( + + {editPopoverButton} + + + + + + + ); + } +} diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/index.ts new file mode 100644 index 00000000000000..bce398d2e59317 --- /dev/null +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/index.ts @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { AnyAction } from 'redux'; +import { ThunkDispatch } from 'redux-thunk'; +import { connect } from 'react-redux'; +import { EditControl } from './edit_control'; +import { updateEditMode } from '../../../actions'; +import { MapStoreState } from '../../../reducers/store'; + +function mapDispatchToProps(dispatch: ThunkDispatch) { + return { + setEditModeActive: () => dispatch(updateEditMode(true)), + setEditModeInActive: () => dispatch(updateEditMode(false)), + }; +} + +const connectedEditControl = connect(null, mapDispatchToProps)(EditControl); +export { connectedEditControl as EditControl }; diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts index cad0a3908441ae..584c47b83b96bb 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts @@ -8,10 +8,14 @@ import { connect } from 'react-redux'; import { ToolbarOverlay } from './toolbar_overlay'; import { MapStoreState } from '../../reducers/store'; +import { getFlyoutDisplay } from '../../selectors/ui_selectors'; +import { FLYOUT_STATE } from '../../reducers/ui'; function mapStateToProps(state: MapStoreState) { return { editModeActive: state.map.mapState.editModeActive, + addDrawLayerInProgress: + getFlyoutDisplay(state) !== FLYOUT_STATE.NONE && state.map.mapState.editModeActive, }; } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx index 149eea8c0f207e..f24d80ee3aed33 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx @@ -15,12 +15,14 @@ import { FeatureDrawControl } from './feature_draw_controls/feature_draw_control import { FeatureEditControl } from './feature_draw_controls/feature_edit_control'; import { FitToData } from './fit_to_data'; import { GeoFieldWithIndex } from '../../components/geo_field_with_index'; +import { EditControl } from './edit_control'; export interface Props { addFilters?: ((filters: Filter[], actionId: string) => Promise) | null; geoFields: GeoFieldWithIndex[]; getFilterActions?: () => Promise; getActionContext?: () => ActionExecutionContext; + addDrawLayerInProgress: boolean; editModeActive: boolean; } @@ -42,6 +44,19 @@ export function ToolbarOverlay(props: Props) { ); } + function renderEditControl() { + const { geoFields } = props; + if (!geoFields.length || props.addDrawLayerInProgress) { + return null; + } + + return ( + + + + ); + } + function renderFeatureDrawAndEditControls() { return props.editModeActive ? ( <> @@ -73,6 +88,8 @@ export function ToolbarOverlay(props: Props) { {renderToolsControl()} + {renderEditControl()} + {renderFeatureDrawAndEditControls()} ); From 87cdb31bb39d56d5826b243839e9e9bf4961dce2 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Thu, 15 Apr 2021 15:41:06 -0600 Subject: [PATCH 025/103] Pull out unneeded pieces. Add in common utils --- .../source_descriptor_types.ts | 9 - .../classes/layers/load_layer_wizards.ts | 2 - .../layers/new_vector_layer_wizard/config.tsx | 41 --- .../layers/new_vector_layer_wizard/index.ts | 51 ---- .../{http_service.js => http_service.ts} | 23 +- ...ndexing_service.js => indexing_service.ts} | 13 +- .../layers/new_vector_layer_wizard/wizard.tsx | 267 ------------------ .../sources/new_vector_layer_source/index.ts | 8 - .../new_vector_layer.test.ts | 106 ------- .../new_vector_layer_source.ts | 138 --------- .../add_layer_panel/view.tsx | 2 +- 11 files changed, 25 insertions(+), 635 deletions(-) delete mode 100644 x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/config.tsx delete mode 100644 x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/index.ts rename x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/utils/{http_service.js => http_service.ts} (67%) rename x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/utils/{indexing_service.js => indexing_service.ts} (81%) delete mode 100644 x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx delete mode 100644 x-pack/plugins/maps/public/classes/sources/new_vector_layer_source/index.ts delete mode 100644 x-pack/plugins/maps/public/classes/sources/new_vector_layer_source/new_vector_layer.test.ts delete mode 100644 x-pack/plugins/maps/public/classes/sources/new_vector_layer_source/new_vector_layer_source.ts diff --git a/x-pack/plugins/maps/common/descriptor_types/source_descriptor_types.ts b/x-pack/plugins/maps/common/descriptor_types/source_descriptor_types.ts index e16f61aa531444..9c4ef3fde6d164 100644 --- a/x-pack/plugins/maps/common/descriptor_types/source_descriptor_types.ts +++ b/x-pack/plugins/maps/common/descriptor_types/source_descriptor_types.ts @@ -188,13 +188,4 @@ export type TableSourceDescriptor = { term: string; }; -export type NewVectorLayerSourceDescriptor = { - __fields?: InlineFieldDescriptor[]; - __featureCollection: FeatureCollection; - areResultsTrimmed: boolean; - tooltipContent: string | null; - name: string; - type: string; -}; - export type TermJoinSourceDescriptor = ESTermSourceDescriptor | TableSourceDescriptor; diff --git a/x-pack/plugins/maps/public/classes/layers/load_layer_wizards.ts b/x-pack/plugins/maps/public/classes/layers/load_layer_wizards.ts index 574d86f0082e8c..804352f5bede72 100644 --- a/x-pack/plugins/maps/public/classes/layers/load_layer_wizards.ts +++ b/x-pack/plugins/maps/public/classes/layers/load_layer_wizards.ts @@ -30,7 +30,6 @@ import { mvtVectorSourceWizardConfig } from '../sources/mvt_single_layer_vector_ import { ObservabilityLayerWizardConfig } from './solution_layers/observability'; import { SecurityLayerWizardConfig } from './solution_layers/security'; import { choroplethLayerWizardConfig } from './choropleth_layer_wizard'; -import { newVectorLayerWizardConfig } from './new_vector_layer_wizard/config'; let registered = false; export function registerLayerWizards() { @@ -40,7 +39,6 @@ export function registerLayerWizards() { // Registration order determines display order registerLayerWizard(uploadLayerWizardConfig); - registerLayerWizard(newVectorLayerWizardConfig); registerLayerWizard(esDocumentsLayerWizardConfig); // @ts-ignore registerLayerWizard(choroplethLayerWizardConfig); diff --git a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/config.tsx b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/config.tsx deleted file mode 100644 index 6612be3a287796..00000000000000 --- a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/config.tsx +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; -import React from 'react'; -import { LayerWizard, RenderWizardArguments } from '../../layers/layer_wizard_registry'; -import { NewVectorLayerEditor } from './index'; -import { DocumentsLayerIcon } from '../../layers/icons/documents_layer_icon'; -import { CREATE_DRAWN_FEATURES_INDEX_STEP_ID, ADD_DRAWN_FEATURES_TO_INDEX_STEP_ID } from './wizard'; - -export const newVectorLayerWizardConfig: LayerWizard = { - categories: [], - description: i18n.translate('xpack.maps.newVectorLayerWizard.description', { - defaultMessage: 'Draw points & shapes and save in Elasticsearch', - }), - icon: DocumentsLayerIcon, - prerequisiteSteps: [ - { - id: CREATE_DRAWN_FEATURES_INDEX_STEP_ID, - label: i18n.translate('xpack.maps.newVectorLayerWizard.indexFeatures', { - defaultMessage: 'Index features', - }), - }, - { - id: ADD_DRAWN_FEATURES_TO_INDEX_STEP_ID, - label: i18n.translate('xpack.maps.newVectorLayerWizard.indexingFeatures', { - defaultMessage: 'Indexing features', - }), - }, - ], - renderWizard: (renderWizardArguments: RenderWizardArguments) => { - return ; - }, - title: i18n.translate('xpack.maps.newVectorLayerWizard.title', { - defaultMessage: 'Draw new vector layer', - }), -}; diff --git a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/index.ts b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/index.ts deleted file mode 100644 index efe1686ad5a43b..00000000000000 --- a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/index.ts +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { ThunkDispatch } from 'redux-thunk'; -import { AnyAction } from 'redux'; -import { connect } from 'react-redux'; -import { MapStoreState } from '../../../reducers/store'; -import { NewVectorLayerEditor } from './wizard'; -import { - addLayer, - clearDrawingData, - setSelectedLayer, - setVectorLayerIndexName, - updateEditMode, - updateFlyout, -} from '../../../actions'; -import { FLYOUT_STATE } from '../../../reducers/ui'; -import { LayerDescriptor } from '../../../../common/descriptor_types'; - -function mapStateToProps(state: MapStoreState) { - return { - indexName: state.map.mapState.vectorLayerIndexName, - featuresQueued: state.map.mapState.featuresToIndexQueue, - }; -} - -function mapDispatchToProps(dispatch: ThunkDispatch) { - return { - setEditModeActive: () => dispatch(updateEditMode(true)), - setEditModeInActive: () => { - dispatch(updateEditMode(false)) - dispatch(clearDrawingData()); - }, - setIndexName: (indexName: string) => dispatch(setVectorLayerIndexName(indexName)), - clearDrawingData: () => { - dispatch(clearDrawingData()); - }, - addNewLayer: async (layerDescriptor: LayerDescriptor) => { - await dispatch(addLayer(layerDescriptor)); - await dispatch(setSelectedLayer(layerDescriptor.id)); - dispatch(updateFlyout(FLYOUT_STATE.LAYER_PANEL)); - }, - }; -} - -const connected = connect(mapStateToProps, mapDispatchToProps)(NewVectorLayerEditor); -export { connected as NewVectorLayerEditor }; diff --git a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/utils/http_service.js b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/utils/http_service.ts similarity index 67% rename from x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/utils/http_service.js rename to x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/utils/http_service.ts index 3fe736f7e67024..5db916acc951b3 100644 --- a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/utils/http_service.js +++ b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/utils/http_service.ts @@ -6,15 +6,26 @@ */ import { i18n } from '@kbn/i18n'; +import { HttpFetchOptions } from 'kibana/public'; import { getHttp } from '../../../../kibana_services'; -export async function http(options) { +export interface HttpOptions { + url: string; + method: string; + headers?: { + [key: string]: any; + }; + data?: unknown; + query?: any; +} + +export async function http(options: HttpOptions) { if (!(options && options.url)) { - throw i18n.translate('xpack.layers.newVectorLayerWizard.httpService.noUrl', { + throw i18n.translate('xpack.maps.layers.newVectorLayerWizard.httpService.noUrl', { defaultMessage: 'No URL provided', }); } - const url = options.url || ''; + const url: string = options.url || ''; const headers = { 'Content-Type': 'application/json', ...options.headers, @@ -23,7 +34,7 @@ export async function http(options) { const allHeaders = options.headers === undefined ? headers : { ...options.headers, ...headers }; const body = options.data === undefined ? null : JSON.stringify(options.data); - const payload = { + const payload: HttpFetchOptions = { method: options.method || 'GET', headers: allHeaders, credentials: 'same-origin', @@ -36,13 +47,13 @@ export async function http(options) { return await doFetch(url, payload); } -async function doFetch(url, payload) { +async function doFetch(url: string, payload: HttpFetchOptions) { try { return await getHttp().fetch(url, payload); } catch (err) { return { failures: [ - i18n.translate('xpack.layers.newVectorLayerWizard.httpService.fetchError', { + i18n.translate('xpack.maps.layers.newVectorLayerWizard.httpService.fetchError', { defaultMessage: 'Error performing fetch: {error}', values: { error: err.message }, }), diff --git a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/utils/indexing_service.js b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/utils/indexing_service.ts similarity index 81% rename from x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/utils/indexing_service.js rename to x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/utils/indexing_service.ts index 29e593fd977b66..2720524894a730 100644 --- a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/utils/indexing_service.js +++ b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/utils/indexing_service.ts @@ -7,18 +7,19 @@ import { http as httpService } from './http_service'; import { getSavedObjectsClient } from '../../../../kibana_services'; +import { INDEX_FEATURE_PATH, INDEX_SOURCE_API_PATH } from '../../../../../common'; export const getExistingIndexNames = async () => { const indexes = await httpService({ url: `/api/index_management/indices`, method: 'GET', }); - return indexes ? indexes.map(({ name }) => name) : []; + return indexes ? indexes.map(({ name }: { name: string }) => name) : []; }; -export const createNewIndexAndPattern = async (indexName) => { +export const createNewIndexAndPattern = async (indexName: string) => { return await httpService({ - url: `/api/maps/docSource`, + url: `/${INDEX_SOURCE_API_PATH}`, method: 'POST', data: { index: indexName, @@ -34,9 +35,9 @@ export const createNewIndexAndPattern = async (indexName) => { }); }; -export const addFeatureToIndex = async (indexName, geometry) => { +export const addFeatureToIndex = async (indexName: string, geometry: unknown) => { return await httpService({ - url: `/api/maps/feature`, + url: `/${INDEX_FEATURE_PATH}`, method: 'POST', data: { index: indexName, @@ -58,7 +59,7 @@ export const getExistingIndexPatternNames = async () => { return indexPatterns ? indexPatterns.map(({ name }) => name) : []; }; -export function checkIndexPatternValid(name) { +export function checkIndexPatternValid(name: string) { const byteLength = encodeURI(name).split(/%(?:u[0-9A-F]{2})?[0-9A-F]{2}|./).length - 1; const reg = new RegExp('[\\\\/*?"<>|\\s,#]+'); const indexPatternInvalid = diff --git a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx deleted file mode 100644 index 006c2fa2e14b57..00000000000000 --- a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { ChangeEvent, Component, Fragment } from 'react'; -import { - EuiCallOut, - EuiEmptyPrompt, - EuiFieldText, - EuiFormRow, - EuiPanel, - EuiSpacer, -} from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import { Feature } from 'geojson'; -import { - getExistingIndexNames, - getExistingIndexPatternNames, - checkIndexPatternValid, - createNewIndexAndPattern, - addFeatureToIndex, - // @ts-expect-error -} from './utils/indexing_service'; -import { RenderWizardArguments } from '../layer_wizard_registry'; -import { VectorLayer } from '../vector_layer'; -import { ESSearchSource } from '../../sources/es_search_source'; -import { LayerDescriptor } from '../../../../common/descriptor_types'; - -export const CREATE_DRAWN_FEATURES_INDEX_STEP_ID = 'CREATE_DRAWN_FEATURES_INDEX_STEP_ID'; -export const ADD_DRAWN_FEATURES_TO_INDEX_STEP_ID = 'ADD_DRAWN_FEATURES_TO_INDEX_STEP_ID'; - -interface NewVectorLayerProps extends RenderWizardArguments { - indexName: string; - featuresQueued: Feature[]; - setEditModeActive: () => void; - setEditModeInActive: () => void; - setIndexName: (indexName: string) => void; - clearDrawingData: () => void; - addNewLayer: (layerDescriptor: LayerDescriptor) => void; -} - -interface State { - indexName: string; - indexError: string; - indexNames: string[]; - indexingTriggered: boolean; - indexPatternId: string; -} - -export class NewVectorLayerEditor extends Component { - state = { - indexName: '', - indexError: '', - indexNames: [], - indexingTriggered: false, - indexPatternId: '', - }; - - private _isMounted = false; - - async componentDidMount() { - this.props.setEditModeActive(); - this._isMounted = true; - this._loadIndexNames(); - } - - async componentDidUpdate() { - const { indexName, featuresQueued, enableNextBtn, disableNextBtn, currentStepId } = this.props; - if (indexName && featuresQueued.length) { - enableNextBtn(); - } else { - disableNextBtn(); - } - if (!this.state.indexingTriggered && currentStepId === ADD_DRAWN_FEATURES_TO_INDEX_STEP_ID) { - await this._addFeaturesToNewIndex(); - this.props.clearDrawingData(); - } - } - - componentWillUnmount() { - this.props.setEditModeInActive(); - this._isMounted = false; - } - - _addFeaturesToNewIndex = async () => { - const { indexPatternId } = await createNewIndexAndPattern(this.props.indexName); - this.props.advanceToNextStep(); - await Promise.all( - this.props.featuresQueued.map(async (feature) => { - const geometry = { - coordinates: feature.geometry.coordinates, - type: feature.geometry.type.toLowerCase(), - }; - await addFeatureToIndex(this.props.indexName, geometry); - }) - ); - const sourceDescriptor = ESSearchSource.createDescriptor({ - indexPatternId, - geoField: 'coordinates', - filterByMapBounds: false, - }); - this.props.advanceToNextStep(); - const layerDescriptor = VectorLayer.createDescriptor( - { sourceDescriptor }, - this.props.mapColors - ); - await this.props.addNewLayer(layerDescriptor); - }; - - _loadIndexNames = async () => { - const indexNameList = await getExistingIndexNames(); - const indexPatternList = await getExistingIndexPatternNames(); - if (this._isMounted) { - this.setState({ - indexNames: [...indexNameList, ...indexPatternList], - }); - } - }; - - _onIndexNameChange = (indexName: string) => { - if (this.state.indexNames.includes(indexName)) { - this.setState({ - indexError: i18n.translate( - 'xpack.layers.newVectorLayerWizard.indexSettings.indexNameAlreadyExistsErrorMessage', - { - defaultMessage: 'Index name already exists.', - } - ), - }); - this.props.setIndexName(''); - } else if (!checkIndexPatternValid(indexName)) { - this.setState({ - indexError: i18n.translate( - 'xpack.layers.newVectorLayerWizard.indexSettings.indexNameContainsIllegalCharactersErrorMessage', - { - defaultMessage: 'Index name contains illegal characters.', - } - ), - }); - this.props.setIndexName(''); - } else { - this.setState({ indexError: '' }); - this.props.setIndexName(indexName); - } - }; - - _onIndexNameChangeEvent = (event: ChangeEvent) => { - this.setState({ indexName: event.target.value }); - this._onIndexNameChange(event.target.value); - }; - - render() { - return ( - - <> - - {i18n.translate('xpack.layers.newVectorLayerWizard.drawVectorShapes', { - defaultMessage: 'Draw vector shapes', - })} - - } - body={ - -

- {i18n.translate('xpack.layers.newVectorLayerWizard.vectorEditorDescription', { - defaultMessage: `Using the editor on the left side of the map, draw and edit the points and shapes to be indexed and added to the map.`, - })} -

-
- } - /> - - - - - -
    -
  • - {i18n.translate( - 'xpack.layers.newVectorLayerWizard.indexSettings.guidelines.mustBeNewIndex', - { - defaultMessage: 'Must be a new index', - } - )} -
  • -
  • - {i18n.translate( - 'xpack.layers.newVectorLayerWizard.indexSettings.guidelines.lowercaseOnly', - { - defaultMessage: 'Lowercase only', - } - )} -
  • -
  • - {i18n.translate( - 'xpack.layers.newVectorLayerWizard.indexSettings.guidelines.cannotInclude', - { - defaultMessage: - 'Cannot include \\\\, /, *, ?, ", <, >, |, \ - " " (space character), , (comma), #', - } - )} -
  • -
  • - {i18n.translate( - 'xpack.layers.newVectorLayerWizard.indexSettings.guidelines.cannotStartWith', - { - defaultMessage: 'Cannot start with -, _, +', - } - )} -
  • -
  • - {i18n.translate( - 'xpack.layers.newVectorLayerWizard.indexSettings.guidelines.cannotBe', - { - defaultMessage: 'Cannot be . or ..', - } - )} -
  • -
  • - {i18n.translate( - 'xpack.layers.newVectorLayerWizard.indexSettings.guidelines.length', - { - defaultMessage: - 'Cannot be longer than 255 bytes (note it is bytes, \ - so multi-byte characters will count towards the 255 \ - limit faster)', - } - )} -
  • -
-
- -
- ); - } -} diff --git a/x-pack/plugins/maps/public/classes/sources/new_vector_layer_source/index.ts b/x-pack/plugins/maps/public/classes/sources/new_vector_layer_source/index.ts deleted file mode 100644 index 48fbbe0c4cc525..00000000000000 --- a/x-pack/plugins/maps/public/classes/sources/new_vector_layer_source/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export { NewVectorLayerSource } from './new_vector_layer_source'; diff --git a/x-pack/plugins/maps/public/classes/sources/new_vector_layer_source/new_vector_layer.test.ts b/x-pack/plugins/maps/public/classes/sources/new_vector_layer_source/new_vector_layer.test.ts deleted file mode 100644 index 47519747ae28a8..00000000000000 --- a/x-pack/plugins/maps/public/classes/sources/new_vector_layer_source/new_vector_layer.test.ts +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { GeoJsonFileSource } from './new_vector_layer_source'; -import { BoundsFilters } from '../vector_source'; -import { FIELD_ORIGIN } from '../../../../common/constants'; - -describe('GeoJsonFileSource', () => { - describe('getName', () => { - it('should get default display name', async () => { - const geojsonFileSource = new GeoJsonFileSource({}); - expect(await geojsonFileSource.getDisplayName()).toBe('Features'); - }); - }); - describe('getBounds', () => { - it('should get null bounds', async () => { - const geojsonFileSource = new GeoJsonFileSource({}); - expect( - await geojsonFileSource.getBoundsForFilters(({} as unknown) as BoundsFilters, () => {}) - ).toEqual(null); - }); - - it('should get bounds from feature collection', async () => { - const geojsonFileSource = new GeoJsonFileSource({ - __featureCollection: { - type: 'FeatureCollection', - features: [ - { - type: 'Feature', - geometry: { - type: 'Point', - coordinates: [0, 1], - }, - properties: {}, - }, - { - type: 'Feature', - geometry: { - type: 'Point', - coordinates: [2, 3], - }, - properties: {}, - }, - ], - }, - }); - - expect(geojsonFileSource.isBoundsAware()).toBe(true); - expect( - await geojsonFileSource.getBoundsForFilters(({} as unknown) as BoundsFilters, () => {}) - ).toEqual({ - maxLat: 3, - maxLon: 2, - minLat: 1, - minLon: 0, - }); - }); - }); - - describe('getFields', () => { - it('should get fields from config', async () => { - const geojsonFileSource = new GeoJsonFileSource({ - __fields: [ - { - type: 'string', - name: 'foo', - }, - { - type: 'number', - name: 'bar', - }, - ], - }); - - const fields = await geojsonFileSource.getFields(); - - const actualFields = fields.map(async (field) => { - return { - dataType: await field.getDataType(), - origin: field.getOrigin(), - name: field.getName(), - source: field.getSource(), - }; - }); - - expect(await Promise.all(actualFields)).toEqual([ - { - dataType: 'string', - origin: FIELD_ORIGIN.SOURCE, - source: geojsonFileSource, - name: 'foo', - }, - { - dataType: 'number', - origin: FIELD_ORIGIN.SOURCE, - source: geojsonFileSource, - name: 'bar', - }, - ]); - }); - }); -}); diff --git a/x-pack/plugins/maps/public/classes/sources/new_vector_layer_source/new_vector_layer_source.ts b/x-pack/plugins/maps/public/classes/sources/new_vector_layer_source/new_vector_layer_source.ts deleted file mode 100644 index 99e7adaccaf039..00000000000000 --- a/x-pack/plugins/maps/public/classes/sources/new_vector_layer_source/new_vector_layer_source.ts +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { Feature, FeatureCollection } from 'geojson'; -import { AbstractVectorSource, BoundsFilters, GeoJsonWithMeta } from '../vector_source'; -import { EMPTY_FEATURE_COLLECTION, FIELD_ORIGIN, SOURCE_TYPES } from '../../../../common/constants'; -import { - InlineFieldDescriptor, - NewVectorLayerSourceDescriptor, - MapExtent, -} from '../../../../common/descriptor_types'; -import { registerSource } from '../source_registry'; -import { IField } from '../../fields/field'; -import { getFeatureCollectionBounds } from '../../util/get_feature_collection_bounds'; -import { Adapters } from '../../../../../../../src/plugins/inspector/common/adapters'; -import { InlineField } from '../../fields/inline_field'; - -function getFeatureCollection( - geoJson: Feature | FeatureCollection | null | undefined -): FeatureCollection { - if (!geoJson) { - return EMPTY_FEATURE_COLLECTION; - } - - if (geoJson.type === 'FeatureCollection') { - return geoJson; - } - - if (geoJson.type === 'Feature') { - return { - type: 'FeatureCollection', - features: [geoJson], - }; - } - - return EMPTY_FEATURE_COLLECTION; -} - -export class NewVectorLayerSource extends AbstractVectorSource { - static createDescriptor( - descriptor: Partial - ): NewVectorLayerSourceDescriptor { - return { - type: SOURCE_TYPES.GEOJSON_FILE, - __featureCollection: getFeatureCollection(descriptor.__featureCollection), - __fields: descriptor.__fields || [], - areResultsTrimmed: - descriptor.areResultsTrimmed !== undefined ? descriptor.areResultsTrimmed : false, - tooltipContent: descriptor.tooltipContent ? descriptor.tooltipContent : null, - name: descriptor.name || 'Features', - }; - } - - constructor(descriptor: Partial, inspectorAdapters?: Adapters) { - const normalizedDescriptor = NewVectorLayerSource.createDescriptor(descriptor); - super(normalizedDescriptor, inspectorAdapters); - } - - _getFields(): InlineFieldDescriptor[] { - const fields = (this._descriptor as NewVectorLayerSourceDescriptor).__fields; - return fields ? fields : []; - } - - createField({ fieldName }: { fieldName: string }): IField { - const fields = this._getFields(); - const descriptor: InlineFieldDescriptor | undefined = fields.find((field) => { - return field.name === fieldName; - }); - - if (!descriptor) { - throw new Error( - `Cannot find corresponding field ${fieldName} in __fields array ${JSON.stringify( - this._getFields() - )} ` - ); - } - return new InlineField({ - fieldName: descriptor.name, - source: this, - origin: FIELD_ORIGIN.SOURCE, - dataType: descriptor.type, - }); - } - - async getFields(): Promise { - const fields = this._getFields(); - return fields.map((field: InlineFieldDescriptor) => { - return new InlineField({ - fieldName: field.name, - source: this, - origin: FIELD_ORIGIN.SOURCE, - dataType: field.type, - }); - }); - } - - isBoundsAware(): boolean { - return true; - } - - async getBoundsForFilters( - boundsFilters: BoundsFilters, - registerCancelCallback: (callback: () => void) => void - ): Promise { - const featureCollection = (this._descriptor as NewVectorLayerSourceDescriptor) - .__featureCollection; - return getFeatureCollectionBounds(featureCollection, false); - } - - async getGeoJsonWithMeta(): Promise { - return { - data: (this._descriptor as NewVectorLayerSourceDescriptor).__featureCollection, - meta: {}, - }; - } - - async getDisplayName() { - return (this._descriptor as NewVectorLayerSourceDescriptor).name; - } - - canFormatFeatureProperties() { - return true; - } - - getSourceTooltipContent() { - console.log('getSourceTooltipContent not implemented for new vector layer source'); - return undefined; - } -} - -registerSource({ - ConstructorFunction: NewVectorLayerSource, - type: SOURCE_TYPES.NEW_VECTOR_LAYER, -}); diff --git a/x-pack/plugins/maps/public/connected_components/add_layer_panel/view.tsx b/x-pack/plugins/maps/public/connected_components/add_layer_panel/view.tsx index 7f3c7f3d3f8c5a..35672d7369404a 100644 --- a/x-pack/plugins/maps/public/connected_components/add_layer_panel/view.tsx +++ b/x-pack/plugins/maps/public/connected_components/add_layer_panel/view.tsx @@ -127,7 +127,7 @@ export class AddLayerPanel extends Component { let isDisabled = !this.state.isNextStepBtnEnabled; let isLoading = this.state.isStepLoading; - if (this.state.currentStep.id === ADD_LAYER_STEP_ID && !this.props.isDrawingLayer) { + if (this.state.currentStep.id === ADD_LAYER_STEP_ID) { isDisabled = !this.props.hasPreviewLayers; isLoading = this.props.isLoadingPreviewLayers; } else { From 5cf1aa99fd762100c9c7ed0eba6e108d2dd56e81 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Tue, 20 Apr 2021 16:18:36 -0600 Subject: [PATCH 026/103] Draw tool switch logic --- x-pack/plugins/maps/common/constants.ts | 7 +++++- .../plugins/maps/public/actions/ui_actions.ts | 9 +++++++ .../maps/public/classes/sources/source.ts | 7 +++++- .../connected_components/mb_map/index.ts | 20 ++++++++------- .../edit_control/edit_control.tsx | 8 +++--- .../toolbar_overlay/edit_control/index.ts | 7 +++--- .../toolbar_overlay/index.ts | 7 ++++-- .../toolbar_overlay/toolbar_overlay.tsx | 2 +- .../toolbar_overlay/tools_control/index.ts | 5 +++- .../tools_control/tools_control.tsx | 25 ++++++++++++++++--- .../plugins/maps/public/reducers/map/types.ts | 2 +- x-pack/plugins/maps/public/reducers/ui.ts | 6 +++++ .../maps/public/selectors/map_selectors.ts | 9 ++++++- .../maps/public/selectors/ui_selectors.ts | 2 ++ 14 files changed, 88 insertions(+), 28 deletions(-) diff --git a/x-pack/plugins/maps/common/constants.ts b/x-pack/plugins/maps/common/constants.ts index e842384d26a28e..37ae247814a7a8 100644 --- a/x-pack/plugins/maps/common/constants.ts +++ b/x-pack/plugins/maps/common/constants.ts @@ -89,7 +89,6 @@ export enum SOURCE_TYPES { GEOJSON_FILE = 'GEOJSON_FILE', MVT_SINGLE_LAYER = 'MVT_SINGLE_LAYER', TABLE_SOURCE = 'TABLE_SOURCE', - NEW_VECTOR_LAYER = 'NEW_VECTOR_LAYER', } export enum FIELD_ORIGIN { @@ -152,6 +151,12 @@ export const EMPTY_FEATURE_COLLECTION: FeatureCollection = { features: [], }; +export enum DRAW_MODE { + DRAW_FEATURES = 'DRAW_FEATURES', + DRAW_FILTERS = 'DRAW_FILTERS', + NONE = 'NONE', +} + export enum DRAW_TYPE { BOUNDS = 'BOUNDS', DISTANCE = 'DISTANCE', diff --git a/x-pack/plugins/maps/public/actions/ui_actions.ts b/x-pack/plugins/maps/public/actions/ui_actions.ts index f9c0e324aa5d8b..ee6e68abea0023 100644 --- a/x-pack/plugins/maps/public/actions/ui_actions.ts +++ b/x-pack/plugins/maps/public/actions/ui_actions.ts @@ -12,6 +12,7 @@ import { getFlyoutDisplay } from '../selectors/ui_selectors'; import { FLYOUT_STATE } from '../reducers/ui'; import { trackMapSettings } from './map_actions'; import { setSelectedLayer } from './layer_actions'; +import { DRAW_MODE } from '../../common'; export const UPDATE_FLYOUT = 'UPDATE_FLYOUT'; export const SET_IS_LAYER_TOC_OPEN = 'SET_IS_LAYER_TOC_OPEN'; @@ -20,6 +21,7 @@ export const SET_READ_ONLY = 'SET_READ_ONLY'; export const SET_OPEN_TOC_DETAILS = 'SET_OPEN_TOC_DETAILS'; export const SHOW_TOC_DETAILS = 'SHOW_TOC_DETAILS'; export const HIDE_TOC_DETAILS = 'HIDE_TOC_DETAILS'; +export const SET_DRAW_MODE = 'SET_DRAW_MODE'; export function exitFullScreen() { return { @@ -87,3 +89,10 @@ export function hideTOCDetails(layerId: string) { layerId, }; } + +export function setDrawMode(drawMode: DRAW_MODE) { + return { + type: SET_DRAW_MODE, + drawMode, + }; +} diff --git a/x-pack/plugins/maps/public/classes/sources/source.ts b/x-pack/plugins/maps/public/classes/sources/source.ts index 25e3595d6dffa1..1baeef5ed2be09 100644 --- a/x-pack/plugins/maps/public/classes/sources/source.ts +++ b/x-pack/plugins/maps/public/classes/sources/source.ts @@ -14,7 +14,7 @@ import { GeoJsonProperties } from 'geojson'; import { copyPersistentState } from '../../reducers/copy_persistent_state'; import { IField } from '../fields/field'; -import { FieldFormatter, MAX_ZOOM, MIN_ZOOM } from '../../../common/constants'; +import { FieldFormatter, MAX_ZOOM, MIN_ZOOM, SOURCE_TYPES } from '../../../common/constants'; import { AbstractSourceDescriptor } from '../../../common/descriptor_types'; import { OnSourceChangeArgs } from '../../connected_components/layer_panel/view'; import { LICENSED_FEATURES } from '../../licensed_features'; @@ -55,6 +55,7 @@ export interface ISource { getJoinsDisabledReason(): string | null; cloneDescriptor(): AbstractSourceDescriptor; getFieldNames(): string[]; + getType(): SOURCE_TYPES; getApplyGlobalQuery(): boolean; getApplyGlobalTime(): boolean; getIndexPatternIds(): string[]; @@ -127,6 +128,10 @@ export class AbstractSource implements ISource { return []; } + getType(): SOURCE_TYPES { + return this._descriptor.type as SOURCE_TYPES; + } + renderSourceSettingsEditor(sourceEditorArgs: SourceEditorArgs): ReactElement | null { return null; } diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/index.ts b/x-pack/plugins/maps/public/connected_components/mb_map/index.ts index 4a1b822f98066f..06c3071eec8ac0 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/index.ts +++ b/x-pack/plugins/maps/public/connected_components/mb_map/index.ts @@ -10,27 +10,29 @@ import { ThunkDispatch } from 'redux-thunk'; import { connect } from 'react-redux'; import { MBMap } from './mb_map'; import { - mapExtentChanged, - mapReady, - mapDestroyed, - setMouseCoordinates, - clearMouseCoordinates, clearGoto, - setMapInitError, + clearMouseCoordinates, + mapDestroyed, + mapExtentChanged, MapExtentState, + mapReady, setAreTilesLoaded, + setMapInitError, + setMouseCoordinates, } from '../../actions'; import { + getGoto, getLayerList, getMapReady, - getGoto, + getMapSettings, getScrollZoom, getSpatialFiltersLayer, - getMapSettings, + getLayersBySourceType, } from '../../selectors/map_selectors'; import { getIsFullScreen } from '../../selectors/ui_selectors'; import { getInspectorAdapters } from '../../reducers/non_serializable_instances'; import { MapStoreState } from '../../reducers/store'; +import { SOURCE_TYPES } from '../../../common'; function mapStateToProps(state: MapStoreState) { return { @@ -42,7 +44,7 @@ function mapStateToProps(state: MapStoreState) { inspectorAdapters: getInspectorAdapters(state), scrollZoom: getScrollZoom(state), isFullScreen: getIsFullScreen(state), - editModeActive: state.map.mapState.editModeActive, + editModeActive: !!getLayersBySourceType(SOURCE_TYPES.ES_SEARCH, state).length, }; } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/edit_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/edit_control.tsx index e1bcece2603900..735b866c3308c6 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/edit_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/edit_control.tsx @@ -17,8 +17,8 @@ import { IndexGeometrySelectPopoverForm } from '../../../components/index_geomet export interface Props { geoFields: GeoFieldWithIndex[]; - setEditModeActive: () => void; - setEditModeInActive: () => void; + activateDrawFeatureMode: () => void; + deactivateDrawMode: () => void; } interface State { @@ -70,7 +70,7 @@ export class EditControl extends Component { ); @@ -79,7 +79,7 @@ export class EditControl extends Component { {editPopoverButton} - + ) { return { - setEditModeActive: () => dispatch(updateEditMode(true)), - setEditModeInActive: () => dispatch(updateEditMode(false)), + activateDrawFeatureMode: () => dispatch(setDrawMode(DRAW_MODE.DRAW_FILTERS)), + deactivateDrawMode: () => dispatch(setDrawMode(DRAW_MODE.NONE)), }; } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts index 584c47b83b96bb..d0cd31268bd9c4 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts @@ -8,14 +8,17 @@ import { connect } from 'react-redux'; import { ToolbarOverlay } from './toolbar_overlay'; import { MapStoreState } from '../../reducers/store'; -import { getFlyoutDisplay } from '../../selectors/ui_selectors'; +import { getDrawMode, getFlyoutDisplay } from '../../selectors/ui_selectors'; import { FLYOUT_STATE } from '../../reducers/ui'; +import { getLayersBySourceType } from '../../selectors/map_selectors'; +import { SOURCE_TYPES } from '../../../common'; function mapStateToProps(state: MapStoreState) { return { - editModeActive: state.map.mapState.editModeActive, + showEditButton: !!getLayersBySourceType(SOURCE_TYPES.ES_SEARCH, state).length, addDrawLayerInProgress: getFlyoutDisplay(state) !== FLYOUT_STATE.NONE && state.map.mapState.editModeActive, + drawMode: getDrawMode(state), }; } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx index f24d80ee3aed33..0bfb724affbad0 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx @@ -58,7 +58,7 @@ export function ToolbarOverlay(props: Props) { } function renderFeatureDrawAndEditControls() { - return props.editModeActive ? ( + return props.showEditButton ? ( <> diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts index 5270f23754b566..d5de47cb9b01da 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts @@ -10,9 +10,10 @@ import { ThunkDispatch } from 'redux-thunk'; import { connect } from 'react-redux'; import { ToolsControl } from './tools_control'; import { isDrawingFilter } from '../../../selectors/map_selectors'; -import { updateDrawState } from '../../../actions'; +import { setDrawMode, updateDrawState } from '../../../actions'; import { MapStoreState } from '../../../reducers/store'; import { DrawState } from '../../../../common/descriptor_types'; +import { DRAW_MODE } from '../../../../common'; function mapStateToProps(state: MapStoreState) { return { @@ -28,6 +29,8 @@ function mapDispatchToProps(dispatch: ThunkDispatch { dispatch(updateDrawState(null)); }, + activateDrawFilterMode: () => dispatch(setDrawMode(DRAW_MODE.DRAW_FILTERS)), + deactivateDrawMode: () => dispatch(setDrawMode(DRAW_MODE.NONE)), }; } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx index 6779fe945137e8..3141d0a3e598f5 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx @@ -18,12 +18,18 @@ import { import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { ActionExecutionContext, Action } from 'src/plugins/ui_actions/public'; -import { DRAW_TYPE, ES_GEO_FIELD_TYPE, ES_SPATIAL_RELATIONS } from '../../../../common/constants'; +import { + DRAW_MODE, + DRAW_TYPE, + ES_GEO_FIELD_TYPE, + ES_SPATIAL_RELATIONS, +} from '../../../../common/constants'; // @ts-expect-error import { GeometryFilterForm } from '../../../components/geometry_filter_form'; import { DistanceFilterForm } from '../../../components/distance_filter_form'; import { GeoFieldWithIndex } from '../../../components/geo_field_with_index'; import { DrawState } from '../../../../common/descriptor_types'; +import { setDrawMode } from '../../../actions'; const DRAW_SHAPE_LABEL = i18n.translate('xpack.maps.toolbarOverlay.drawShapeLabel', { defaultMessage: 'Draw shape to filter data', @@ -59,6 +65,8 @@ export interface Props { isDrawingFilter: boolean; getFilterActions?: () => Promise; getActionContext?: () => ActionExecutionContext; + activateDrawFilterMode: () => void; + deactivateDrawMode: () => void; } interface State { @@ -71,13 +79,21 @@ export class ToolsControl extends Component { }; _togglePopover = () => { - this.setState((prevState) => ({ - isPopoverOpen: !prevState.isPopoverOpen, - })); + this.setState( + (prevState) => ({ + isPopoverOpen: !prevState.isPopoverOpen, + }), + () => { + if (this.state.isPopoverOpen) { + this.props.activateDrawFilterMode(); + } + } + ); }; _closePopover = () => { this.setState({ isPopoverOpen: false }); + this.props.deactivateDrawMode(); }; _initiateShapeDraw = (options: { @@ -88,6 +104,7 @@ export class ToolsControl extends Component { geoFieldType: ES_GEO_FIELD_TYPE; relation: ES_SPATIAL_RELATIONS; }) => { + this.props.activateDrawFilterMode(); this.props.initiateDraw({ drawType: DRAW_TYPE.POLYGON, ...options, diff --git a/x-pack/plugins/maps/public/reducers/map/types.ts b/x-pack/plugins/maps/public/reducers/map/types.ts index 8ea7d9d253bcca..938b3344308195 100644 --- a/x-pack/plugins/maps/public/reducers/map/types.ts +++ b/x-pack/plugins/maps/public/reducers/map/types.ts @@ -40,7 +40,7 @@ export type MapContext = { drawState?: DrawState; drawFeatureState?: DRAW_TYPE; featuresToIndexQueue: Feature[]; - editModeActive?: boolean; + editModeActive: boolean; searchSessionId?: string; searchSessionMapBuffer?: MapExtent; }; diff --git a/x-pack/plugins/maps/public/reducers/ui.ts b/x-pack/plugins/maps/public/reducers/ui.ts index 676ac6ce12efeb..1c6415f65a2ab2 100644 --- a/x-pack/plugins/maps/public/reducers/ui.ts +++ b/x-pack/plugins/maps/public/reducers/ui.ts @@ -17,7 +17,9 @@ import { SET_OPEN_TOC_DETAILS, SHOW_TOC_DETAILS, HIDE_TOC_DETAILS, + SET_DRAW_MODE, } from '../actions'; +import { DRAW_MODE } from '../../common'; export enum FLYOUT_STATE { NONE = 'NONE', @@ -28,6 +30,7 @@ export enum FLYOUT_STATE { export type MapUiState = { flyoutDisplay: FLYOUT_STATE; + drawMode: DRAW_MODE; isFullScreen: boolean; isReadOnly: boolean; isLayerTOCOpen: boolean; @@ -38,6 +41,7 @@ export const DEFAULT_IS_LAYER_TOC_OPEN = true; export const DEFAULT_MAP_UI_STATE = { flyoutDisplay: FLYOUT_STATE.NONE, + drawMode: DRAW_MODE.NONE, isFullScreen: false, isReadOnly: !getMapsCapabilities().save, isLayerTOCOpen: DEFAULT_IS_LAYER_TOC_OPEN, @@ -51,6 +55,8 @@ export function ui(state: MapUiState = DEFAULT_MAP_UI_STATE, action: any) { switch (action.type) { case UPDATE_FLYOUT: return { ...state, flyoutDisplay: action.display }; + case SET_DRAW_MODE: + return { ...state, drawMode: action.drawMode }; case SET_IS_LAYER_TOC_OPEN: return { ...state, isLayerTOCOpen: action.isLayerTOCOpen }; case SET_FULL_SCREEN: diff --git a/x-pack/plugins/maps/public/selectors/map_selectors.ts b/x-pack/plugins/maps/public/selectors/map_selectors.ts index a818cdd2d00f92..f60848f18c2f94 100644 --- a/x-pack/plugins/maps/public/selectors/map_selectors.ts +++ b/x-pack/plugins/maps/public/selectors/map_selectors.ts @@ -28,9 +28,10 @@ import { getSourceByType } from '../classes/sources/source_registry'; import { GeoJsonFileSource } from '../classes/sources/geojson_file_source'; import { SOURCE_DATA_REQUEST_ID, + SOURCE_TYPES, + SPATIAL_FILTERS_LAYER_ID, STYLE_TYPE, VECTOR_STYLES, - SPATIAL_FILTERS_LAYER_ID, } from '../../common/constants'; // @ts-ignore import { extractFeaturesFromFilters } from '../../common/elasticsearch_util'; @@ -199,6 +200,8 @@ export const isDrawingFilter = ({ map }: MapStoreState): boolean => { return !!map.mapState.drawState; }; +export const getEditModeActive = ({ map }: MapStoreState): boolean => map.mapState.editModeActive; + export const getRefreshConfig = ({ map }: MapStoreState): MapRefreshConfig => { if (map.mapState.refreshConfig) { return map.mapState.refreshConfig; @@ -328,6 +331,10 @@ export function getLayerById(layerId: string | null, state: MapStoreState): ILay }); } +export function getLayersBySourceType(sourceType: SOURCE_TYPES, state: MapStoreState): ILayer[] { + return getLayerList(state).filter((layer) => layer.getSource().getType() === sourceType); +} + export const getHiddenLayerIds = createSelector(getLayerListRaw, (layers) => layers.filter((layer) => !layer.visible).map((layer) => layer.id) ); diff --git a/x-pack/plugins/maps/public/selectors/ui_selectors.ts b/x-pack/plugins/maps/public/selectors/ui_selectors.ts index e5c83bd0f8f4ab..bdab7c93053006 100644 --- a/x-pack/plugins/maps/public/selectors/ui_selectors.ts +++ b/x-pack/plugins/maps/public/selectors/ui_selectors.ts @@ -8,8 +8,10 @@ import { MapStoreState } from '../reducers/store'; import { FLYOUT_STATE } from '../reducers/ui'; +import { DRAW_MODE } from '../../common'; export const getFlyoutDisplay = ({ ui }: MapStoreState): FLYOUT_STATE => ui.flyoutDisplay; +export const getDrawMode = ({ ui }: MapStoreState): DRAW_MODE => ui.drawMode; export const getIsLayerTOCOpen = ({ ui }: MapStoreState): boolean => ui.isLayerTOCOpen; export const getOpenTOCDetails = ({ ui }: MapStoreState): string[] => ui.openTOCDetails; export const getIsFullScreen = ({ ui }: MapStoreState): boolean => ui.isFullScreen; From 81ba1e74bcd506b0d8fe4219ab02304ad3811e0b Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Tue, 20 Apr 2021 17:48:46 -0600 Subject: [PATCH 027/103] Set map draw control selectively when filters or drawing active --- .../maps/public/connected_components/mb_map/index.ts | 8 +++++--- .../maps/public/connected_components/mb_map/mb_map.tsx | 6 ++++-- .../toolbar_overlay/edit_control/index.ts | 2 +- .../public/connected_components/toolbar_overlay/index.ts | 4 ++-- .../toolbar_overlay/toolbar_overlay.tsx | 9 +++++---- 5 files changed, 17 insertions(+), 12 deletions(-) diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/index.ts b/x-pack/plugins/maps/public/connected_components/mb_map/index.ts index 06c3071eec8ac0..7fda00a8c56605 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/index.ts +++ b/x-pack/plugins/maps/public/connected_components/mb_map/index.ts @@ -23,16 +23,16 @@ import { import { getGoto, getLayerList, + getLayersBySourceType, getMapReady, getMapSettings, getScrollZoom, getSpatialFiltersLayer, - getLayersBySourceType, } from '../../selectors/map_selectors'; -import { getIsFullScreen } from '../../selectors/ui_selectors'; +import { getDrawMode, getIsFullScreen } from '../../selectors/ui_selectors'; import { getInspectorAdapters } from '../../reducers/non_serializable_instances'; import { MapStoreState } from '../../reducers/store'; -import { SOURCE_TYPES } from '../../../common'; +import { DRAW_MODE, SOURCE_TYPES } from '../../../common'; function mapStateToProps(state: MapStoreState) { return { @@ -45,6 +45,8 @@ function mapStateToProps(state: MapStoreState) { scrollZoom: getScrollZoom(state), isFullScreen: getIsFullScreen(state), editModeActive: !!getLayersBySourceType(SOURCE_TYPES.ES_SEARCH, state).length, + featureModeActive: getDrawMode(state) === DRAW_MODE.DRAW_FEATURES, + filterModeActive: getDrawMode(state) === DRAW_MODE.DRAW_FILTERS, }; } diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/mb_map.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/mb_map.tsx index f6d8fabba17ab4..a1a0f304cfca9c 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/mb_map.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/mb_map.tsx @@ -75,6 +75,8 @@ export interface Props { geoFields: GeoFieldWithIndex[]; renderTooltipContent?: RenderToolTipContent; setAreTilesLoaded: (layerId: string, areTilesLoaded: boolean) => void; + featureModeActive: boolean; + filterModeActive: boolean; } interface State { @@ -421,10 +423,10 @@ export class MBMap extends Component { let scaleControl; if (this.state.mbMap) { drawFilterControl = - !this.props.editModeActive && this.props.addFilters ? ( + this.props.addFilters && this.props.filterModeActive ? ( ) : null; - drawFeatureControl = this.props.editModeActive ? ( + drawFeatureControl = this.props.featureModeActive ? ( ) : null; tooltipControl = !this.props.settings.disableTooltipControl ? ( diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/index.ts index b1bc3299335959..b589b4b5651ba0 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/index.ts @@ -15,7 +15,7 @@ import { setDrawMode } from '../../../actions'; function mapDispatchToProps(dispatch: ThunkDispatch) { return { - activateDrawFeatureMode: () => dispatch(setDrawMode(DRAW_MODE.DRAW_FILTERS)), + activateDrawFeatureMode: () => dispatch(setDrawMode(DRAW_MODE.DRAW_FEATURES)), deactivateDrawMode: () => dispatch(setDrawMode(DRAW_MODE.NONE)), }; } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts index d0cd31268bd9c4..6fdf186f838e0c 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts @@ -11,14 +11,14 @@ import { MapStoreState } from '../../reducers/store'; import { getDrawMode, getFlyoutDisplay } from '../../selectors/ui_selectors'; import { FLYOUT_STATE } from '../../reducers/ui'; import { getLayersBySourceType } from '../../selectors/map_selectors'; -import { SOURCE_TYPES } from '../../../common'; +import { DRAW_MODE, SOURCE_TYPES } from '../../../common'; function mapStateToProps(state: MapStoreState) { return { showEditButton: !!getLayersBySourceType(SOURCE_TYPES.ES_SEARCH, state).length, addDrawLayerInProgress: getFlyoutDisplay(state) !== FLYOUT_STATE.NONE && state.map.mapState.editModeActive, - drawMode: getDrawMode(state), + featureModeActive: getDrawMode(state) === DRAW_MODE.DRAW_FEATURES, }; } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx index 0bfb724affbad0..656e2590d73813 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx @@ -23,7 +23,8 @@ export interface Props { getFilterActions?: () => Promise; getActionContext?: () => ActionExecutionContext; addDrawLayerInProgress: boolean; - editModeActive: boolean; + showEditButton: boolean; + featureModeActive: boolean; } export function ToolbarOverlay(props: Props) { @@ -44,7 +45,7 @@ export function ToolbarOverlay(props: Props) { ); } - function renderEditControl() { + function renderEditLayerControl() { const { geoFields } = props; if (!geoFields.length || props.addDrawLayerInProgress) { return null; @@ -58,7 +59,7 @@ export function ToolbarOverlay(props: Props) { } function renderFeatureDrawAndEditControls() { - return props.showEditButton ? ( + return props.featureModeActive ? ( <> @@ -88,7 +89,7 @@ export function ToolbarOverlay(props: Props) { {renderToolsControl()} - {renderEditControl()} + {renderEditLayerControl()} {renderFeatureDrawAndEditControls()} From 1f3a19b3c6ab1cfa80a4d3244473c017cb4c77ab Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 21 Apr 2021 11:03:24 -0600 Subject: [PATCH 028/103] Update draw tools appearance to be in line with other tools --- .../toolbar_overlay/_toolbar_overlay.scss | 31 ++-- .../edit_control/edit_control.tsx | 36 +++-- .../feature_draw_control.tsx | 145 ++++++++++-------- .../feature_edit_control.tsx | 61 +++++--- 4 files changed, 161 insertions(+), 112 deletions(-) diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/_toolbar_overlay.scss b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/_toolbar_overlay.scss index 49898b776dbf88..5b81c62be5d680 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/_toolbar_overlay.scss +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/_toolbar_overlay.scss @@ -21,6 +21,10 @@ } } + .euiButtonIcon { + color: $euiTextColor !important; + } + &:hover { transform: translateY(-1px); } @@ -39,27 +43,24 @@ } .mapToolbarOverlay__button__selected { - @include size($euiSizeXL); + position: relative; + transition: transform $euiAnimSpeedNormal ease-in-out, background $euiAnimSpeedNormal ease-in-out; // sass-lint:disable-block no-important color: $euiTextColor !important; background-color: $euiColorLightShade !important; - pointer-events: all; - position: relative; - &:enabled, - &:enabled:hover, - &:enabled:focus { - @include euiBottomShadowLarge; - } -} + @include kbnThemeStyle($theme: 'v7') { + // Overrides the .euiPanel default border + // sass-lint:disable-block no-important + border: none !important; -.mapToolbarOverlay__buttonGroup { - @include mapToolbarButtonGroupBorderRadius; - display: flex; - flex-direction: column; + // Overrides the .euiPanel--hasShadow + &.euiPanel.euiPanel--hasShadow { + @include euiBottomShadowLarge; + } + } .euiButtonIcon { - border-radius: 0; + color: $euiTextColor !important; } } - diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/edit_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/edit_control.tsx index 735b866c3308c6..65eefc66c23e0e 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/edit_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/edit_control.tsx @@ -6,7 +6,14 @@ */ import React, { Component } from 'react'; -import { EuiButtonIcon, EuiPopover, EuiFlexItem, EuiFlexGroup, EuiButton } from '@elastic/eui'; +import { + EuiButtonIcon, + EuiPopover, + EuiFlexItem, + EuiFlexGroup, + EuiButton, + EuiPanel, +} from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; // @ts-expect-error @@ -42,18 +49,21 @@ export class EditControl extends Component { _renderEditButton() { return ( - + + + ); } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx index c5f3899e4c8982..ec8a3498712b17 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx @@ -29,79 +29,104 @@ export function FeatureDrawControl(props: Props) { - props.initiateDraw(DRAW_TYPE.LINE)} - iconType="minus" - aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawLineLabel', { - defaultMessage: 'Draw line', - })} - title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawLineTitle', { - defaultMessage: 'Draw line', - })} - aria-pressed={drawLineSelected} - isSelected={drawLineSelected} - /> + > + props.initiateDraw(DRAW_TYPE.LINE)} + iconType="minus" + aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawLineLabel', { + defaultMessage: 'Draw line', + })} + title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawLineTitle', { + defaultMessage: 'Draw line', + })} + aria-pressed={drawLineSelected} + isSelected={drawLineSelected} + /> +
- props.initiateDraw(DRAW_TYPE.POLYGON)} - iconType="node" - aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawPolygonLabel', { - defaultMessage: 'Draw polygon', - })} - title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawLineTitle', { - defaultMessage: 'Draw polygon', - })} - aria-pressed={drawPolygonSelected} - isSelected={drawPolygonSelected} - /> + > + props.initiateDraw(DRAW_TYPE.POLYGON)} + iconType="node" + aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawPolygonLabel', { + defaultMessage: 'Draw polygon', + })} + title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawLineTitle', { + defaultMessage: 'Draw polygon', + })} + aria-pressed={drawPolygonSelected} + isSelected={drawPolygonSelected} + /> + - props.initiateDraw(DRAW_TYPE.DISTANCE)} - iconType="plusInCircle" - aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawCircleLabel', { - defaultMessage: 'Draw circle', - })} - title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawCircleTitle', { - defaultMessage: 'Draw circle', - })} - aria-pressed={drawCircleSelected} - isSelected={drawCircleSelected} - /> + > + props.initiateDraw(DRAW_TYPE.DISTANCE)} + iconType="plusInCircle" + aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawCircleLabel', { + defaultMessage: 'Draw circle', + })} + title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawCircleTitle', { + defaultMessage: 'Draw circle', + })} + aria-pressed={drawCircleSelected} + isSelected={drawCircleSelected} + /> + - props.initiateDraw(DRAW_TYPE.BOUNDS)} - iconType="stop" - aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawBBoxLabel', { - defaultMessage: 'Draw bounding box', - })} - title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawBBoxTitle', { - defaultMessage: 'Draw bounding box', - })} - aria-pressed={drawBBoxSelected} - isSelected={drawBBoxSelected} - /> + > + props.initiateDraw(DRAW_TYPE.BOUNDS)} + iconType="stop" + aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawBBoxLabel', { + defaultMessage: 'Draw bounding box', + })} + title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawBBoxTitle', { + defaultMessage: 'Draw bounding box', + })} + aria-pressed={drawBBoxSelected} + isSelected={drawBBoxSelected} + /> + - props.initiateDraw(DRAW_TYPE.POINT)} - iconType="dot" - aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawPointLabel', { - defaultMessage: 'Draw point', - })} - title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawPointTitle', { - defaultMessage: 'Draw point', - })} - aria-pressed={drawPointSelected} - isSelected={drawPointSelected} - /> + > + props.initiateDraw(DRAW_TYPE.POINT)} + iconType="dot" + aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawPointLabel', { + defaultMessage: 'Draw point', + })} + title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawPointTitle', { + defaultMessage: 'Draw point', + })} + aria-pressed={drawPointSelected} + isSelected={drawPointSelected} + /> + diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/feature_edit_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/feature_edit_control.tsx index 7744ba309945cf..e32904345d9c8e 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/feature_edit_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/feature_edit_control.tsx @@ -27,34 +27,47 @@ export function FeatureEditControl(props: Props) { - props.initiateDraw(DRAW_TYPE.SIMPLE_SELECT)} - iconType="documentEdit" - aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.editFeaturesLabel', { - defaultMessage: 'Edit features', - })} - title={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.editFeaturesTitle', { - defaultMessage: 'Edit features', - })} - aria-pressed={editFeaturesSelected} - isSelected={editFeaturesSelected} - /> + > + props.initiateDraw(DRAW_TYPE.SIMPLE_SELECT)} + iconType="documentEdit" + aria-label={i18n.translate( + 'xpack.maps.toolbarOverlay.featureEdit.editFeaturesLabel', + { + defaultMessage: 'Edit features', + } + )} + title={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.editFeaturesTitle', { + defaultMessage: 'Edit features', + })} + aria-pressed={editFeaturesSelected} + isSelected={editFeaturesSelected} + /> + - props.initiateDraw(DRAW_TYPE.TRASH)} - iconType="trash" - aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.deleteLabel', { - defaultMessage: 'Remove feature', - })} - title={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.deleteTitle', { - defaultMessage: 'Remove feature', - })} - aria-pressed={deleteFeaturesSelected} - isSelected={deleteFeaturesSelected} - /> + > + props.initiateDraw(DRAW_TYPE.TRASH)} + iconType="trash" + aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.deleteLabel', { + defaultMessage: 'Remove feature', + })} + title={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.deleteTitle', { + defaultMessage: 'Remove feature', + })} + aria-pressed={deleteFeaturesSelected} + isSelected={deleteFeaturesSelected} + /> + From 216258ecbf62c4b4b93c3f7e6803ef3376030494 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 21 Apr 2021 11:20:38 -0600 Subject: [PATCH 029/103] Fix popover and cancel button appear/disappear behaviors --- .../edit_control/edit_control.tsx | 25 +++++++++++++------ .../toolbar_overlay/edit_control/index.ts | 9 ++++++- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/edit_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/edit_control.tsx index 65eefc66c23e0e..591d888af5c15d 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/edit_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/edit_control.tsx @@ -26,6 +26,7 @@ export interface Props { geoFields: GeoFieldWithIndex[]; activateDrawFeatureMode: () => void; deactivateDrawMode: () => void; + featureModeActive: boolean; } interface State { @@ -47,6 +48,12 @@ export class EditControl extends Component { this.setState({ isPopoverOpen: false }); }; + componentDidUpdate() { + if (this.props.featureModeActive && this.state.isPopoverOpen) { + this._closePopover(); + } + } + _renderEditButton() { return ( @@ -88,14 +95,16 @@ export class EditControl extends Component { return ( {editPopoverButton} - - - - - + {this.props.featureModeActive ? ( + + + + + + ) : null} ); } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/index.ts index b589b4b5651ba0..54d72b6688b8dd 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/index.ts @@ -12,6 +12,13 @@ import { EditControl } from './edit_control'; import { MapStoreState } from '../../../reducers/store'; import { DRAW_MODE } from '../../../../common'; import { setDrawMode } from '../../../actions'; +import { getDrawMode } from '../../../selectors/ui_selectors'; + +function mapStateToProps(state: MapStoreState) { + return { + featureModeActive: getDrawMode(state) === DRAW_MODE.DRAW_FEATURES, + }; +} function mapDispatchToProps(dispatch: ThunkDispatch) { return { @@ -20,5 +27,5 @@ function mapDispatchToProps(dispatch: ThunkDispatch Date: Wed, 21 Apr 2021 14:54:21 -0600 Subject: [PATCH 030/103] Only allow adding points for geo_point indexes and shapes for geo_shape --- x-pack/plugins/maps/common/constants.ts | 3 +- .../connected_components/mb_map/index.ts | 3 +- .../edit_control/edit_control.tsx | 11 +- .../toolbar_overlay/edit_control/index.ts | 6 +- .../feature_draw_control.tsx | 177 ++++++++++-------- .../toolbar_overlay/index.ts | 3 +- .../toolbar_overlay/toolbar_overlay.tsx | 7 +- 7 files changed, 120 insertions(+), 90 deletions(-) diff --git a/x-pack/plugins/maps/common/constants.ts b/x-pack/plugins/maps/common/constants.ts index 37ae247814a7a8..c0fe199ef35204 100644 --- a/x-pack/plugins/maps/common/constants.ts +++ b/x-pack/plugins/maps/common/constants.ts @@ -152,7 +152,8 @@ export const EMPTY_FEATURE_COLLECTION: FeatureCollection = { }; export enum DRAW_MODE { - DRAW_FEATURES = 'DRAW_FEATURES', + DRAW_SHAPES = 'DRAW_SHAPES', + DRAW_POINTS = 'DRAW_POINTS', DRAW_FILTERS = 'DRAW_FILTERS', NONE = 'NONE', } diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/index.ts b/x-pack/plugins/maps/public/connected_components/mb_map/index.ts index 7fda00a8c56605..341fcf91573162 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/index.ts +++ b/x-pack/plugins/maps/public/connected_components/mb_map/index.ts @@ -45,7 +45,8 @@ function mapStateToProps(state: MapStoreState) { scrollZoom: getScrollZoom(state), isFullScreen: getIsFullScreen(state), editModeActive: !!getLayersBySourceType(SOURCE_TYPES.ES_SEARCH, state).length, - featureModeActive: getDrawMode(state) === DRAW_MODE.DRAW_FEATURES, + featureModeActive: + getDrawMode(state) === DRAW_MODE.DRAW_SHAPES || getDrawMode(state) === DRAW_MODE.DRAW_POINTS, filterModeActive: getDrawMode(state) === DRAW_MODE.DRAW_FILTERS, }; } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/edit_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/edit_control.tsx index 591d888af5c15d..1835b6859ce636 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/edit_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/edit_control.tsx @@ -24,7 +24,8 @@ import { IndexGeometrySelectPopoverForm } from '../../../components/index_geomet export interface Props { geoFields: GeoFieldWithIndex[]; - activateDrawFeatureMode: () => void; + activateDrawPointsMode: () => void; + activateDrawShapesMode: () => void; deactivateDrawMode: () => void; featureModeActive: boolean; } @@ -87,7 +88,13 @@ export class EditControl extends Component { { + if (geoFieldType === 'geo_point') { + this.props.activateDrawPointsMode(); + } else { + this.props.activateDrawShapesMode(); + } + }} /> ); diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/index.ts index 54d72b6688b8dd..660581a5dbd725 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/index.ts @@ -16,13 +16,15 @@ import { getDrawMode } from '../../../selectors/ui_selectors'; function mapStateToProps(state: MapStoreState) { return { - featureModeActive: getDrawMode(state) === DRAW_MODE.DRAW_FEATURES, + featureModeActive: + getDrawMode(state) === DRAW_MODE.DRAW_POINTS || getDrawMode(state) === DRAW_MODE.DRAW_SHAPES, }; } function mapDispatchToProps(dispatch: ThunkDispatch) { return { - activateDrawFeatureMode: () => dispatch(setDrawMode(DRAW_MODE.DRAW_FEATURES)), + activateDrawPointsMode: () => dispatch(setDrawMode(DRAW_MODE.DRAW_POINTS)), + activateDrawShapesMode: () => dispatch(setDrawMode(DRAW_MODE.DRAW_SHAPES)), deactivateDrawMode: () => dispatch(setDrawMode(DRAW_MODE.NONE)), }; } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx index ec8a3498712b17..ebb778a413ebee 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx @@ -16,6 +16,7 @@ export interface Props { cancelDraw: () => void; drawType: string; initiateDraw: (drawFeatureState: DRAW_TYPE) => void; + pointsOnly?: boolean; } export function FeatureDrawControl(props: Props) { @@ -28,86 +29,102 @@ export function FeatureDrawControl(props: Props) { return ( - - - props.initiateDraw(DRAW_TYPE.LINE)} - iconType="minus" - aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawLineLabel', { - defaultMessage: 'Draw line', - })} - title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawLineTitle', { - defaultMessage: 'Draw line', - })} - aria-pressed={drawLineSelected} - isSelected={drawLineSelected} - /> - - - - - props.initiateDraw(DRAW_TYPE.POLYGON)} - iconType="node" - aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawPolygonLabel', { - defaultMessage: 'Draw polygon', - })} - title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawLineTitle', { - defaultMessage: 'Draw polygon', - })} - aria-pressed={drawPolygonSelected} - isSelected={drawPolygonSelected} - /> - - - - - props.initiateDraw(DRAW_TYPE.DISTANCE)} - iconType="plusInCircle" - aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawCircleLabel', { - defaultMessage: 'Draw circle', - })} - title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawCircleTitle', { - defaultMessage: 'Draw circle', - })} - aria-pressed={drawCircleSelected} - isSelected={drawCircleSelected} - /> - - - - - props.initiateDraw(DRAW_TYPE.BOUNDS)} - iconType="stop" - aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawBBoxLabel', { - defaultMessage: 'Draw bounding box', - })} - title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawBBoxTitle', { - defaultMessage: 'Draw bounding box', - })} - aria-pressed={drawBBoxSelected} - isSelected={drawBBoxSelected} - /> - - + {props.pointsOnly ? null : ( + <> + + + props.initiateDraw(DRAW_TYPE.LINE)} + iconType="minus" + aria-label={i18n.translate( + 'xpack.maps.toolbarOverlay.featureDraw.drawLineLabel', + { + defaultMessage: 'Draw line', + } + )} + title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawLineTitle', { + defaultMessage: 'Draw line', + })} + aria-pressed={drawLineSelected} + isSelected={drawLineSelected} + /> + + + + + props.initiateDraw(DRAW_TYPE.POLYGON)} + iconType="node" + aria-label={i18n.translate( + 'xpack.maps.toolbarOverlay.featureDraw.drawPolygonLabel', + { + defaultMessage: 'Draw polygon', + } + )} + title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawLineTitle', { + defaultMessage: 'Draw polygon', + })} + aria-pressed={drawPolygonSelected} + isSelected={drawPolygonSelected} + /> + + + + + props.initiateDraw(DRAW_TYPE.DISTANCE)} + iconType="plusInCircle" + aria-label={i18n.translate( + 'xpack.maps.toolbarOverlay.featureDraw.drawCircleLabel', + { + defaultMessage: 'Draw circle', + } + )} + title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawCircleTitle', { + defaultMessage: 'Draw circle', + })} + aria-pressed={drawCircleSelected} + isSelected={drawCircleSelected} + /> + + + + + props.initiateDraw(DRAW_TYPE.BOUNDS)} + iconType="stop" + aria-label={i18n.translate( + 'xpack.maps.toolbarOverlay.featureDraw.drawBBoxLabel', + { + defaultMessage: 'Draw bounding box', + } + )} + title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawBBoxTitle', { + defaultMessage: 'Draw bounding box', + })} + aria-pressed={drawBBoxSelected} + isSelected={drawBBoxSelected} + /> + + + + )} ActionExecutionContext; addDrawLayerInProgress: boolean; showEditButton: boolean; - featureModeActive: boolean; + shapeDrawModeActive: boolean; + pointDrawModeActive: boolean; } export function ToolbarOverlay(props: Props) { @@ -59,10 +60,10 @@ export function ToolbarOverlay(props: Props) { } function renderFeatureDrawAndEditControls() { - return props.featureModeActive ? ( + return props.shapeDrawModeActive || props.pointDrawModeActive ? ( <> - + From d683bd49356de2aad95fe3f89f28c18ef17be2ff Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 5 May 2021 13:39:24 -0600 Subject: [PATCH 031/103] Init shape drawing from filter menu --- .../toolbar_overlay/tools_control/index.ts | 2 + .../tools_control/tools_control.tsx | 39 +++++++++++++++++-- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts index d5de47cb9b01da..1ab6fde917122f 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts @@ -30,6 +30,8 @@ function mapDispatchToProps(dispatch: ThunkDispatch dispatch(setDrawMode(DRAW_MODE.DRAW_FILTERS)), + activateDrawPointsMode: () => dispatch(setDrawMode(DRAW_MODE.DRAW_POINTS)), + activateDrawShapesMode: () => dispatch(setDrawMode(DRAW_MODE.DRAW_SHAPES)), deactivateDrawMode: () => dispatch(setDrawMode(DRAW_MODE.NONE)), }; } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx index 3141d0a3e598f5..078a8fbff99f39 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx @@ -19,7 +19,6 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { ActionExecutionContext, Action } from 'src/plugins/ui_actions/public'; import { - DRAW_MODE, DRAW_TYPE, ES_GEO_FIELD_TYPE, ES_SPATIAL_RELATIONS, @@ -28,8 +27,9 @@ import { import { GeometryFilterForm } from '../../../components/geometry_filter_form'; import { DistanceFilterForm } from '../../../components/distance_filter_form'; import { GeoFieldWithIndex } from '../../../components/geo_field_with_index'; +// @ts-expect-error +import { IndexGeometrySelectPopoverForm } from '../../../components/index_geometry_select_popover_form'; import { DrawState } from '../../../../common/descriptor_types'; -import { setDrawMode } from '../../../actions'; const DRAW_SHAPE_LABEL = i18n.translate('xpack.maps.toolbarOverlay.drawShapeLabel', { defaultMessage: 'Draw shape to filter data', @@ -43,6 +43,10 @@ const DRAW_DISTANCE_LABEL = i18n.translate('xpack.maps.toolbarOverlay.drawDistan defaultMessage: 'Draw distance to filter data', }); +const ADD_FEATURES_LABEL = i18n.translate('xpack.maps.toolbarOverlay.editFeaturesLabel', { + defaultMessage: 'Add features to index', +}); + const DRAW_SHAPE_LABEL_SHORT = i18n.translate('xpack.maps.toolbarOverlay.drawShapeLabelShort', { defaultMessage: 'Draw shape', }); @@ -58,6 +62,13 @@ const DRAW_DISTANCE_LABEL_SHORT = i18n.translate( } ); +const ADD_FEATURES_LABEL_SHORT = i18n.translate( + 'xpack.maps.toolbarOverlay.editFeaturesLabelShort', + { + defaultMessage: 'Add features', + } +); + export interface Props { cancelDraw: () => void; geoFields: GeoFieldWithIndex[]; @@ -66,6 +77,8 @@ export interface Props { getFilterActions?: () => Promise; getActionContext?: () => ActionExecutionContext; activateDrawFilterMode: () => void; + activateDrawPointsMode: () => void; + activateDrawShapesMode: () => void; deactivateDrawMode: () => void; } @@ -93,7 +106,6 @@ export class ToolsControl extends Component { _closePopover = () => { this.setState({ isPopoverOpen: false }); - this.props.deactivateDrawMode(); }; _initiateShapeDraw = (options: { @@ -154,6 +166,10 @@ export class ToolsControl extends Component { name: DRAW_DISTANCE_LABEL, panel: 3, }, + { + name: ADD_FEATURES_LABEL, + panel: 4, + }, ]; return [ @@ -218,6 +234,23 @@ export class ToolsControl extends Component { /> ), }, + { + id: 4, + title: ADD_FEATURES_LABEL_SHORT, + content: ( + { + if (geoFieldType === 'geo_point') { + this.props.activateDrawPointsMode(); + } else { + this.props.activateDrawShapesMode(); + } + }} + /> + ), + }, ]; } From f97e74f6eb0e1d9ae88497f5d57a53497a9f4dc8 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 5 May 2021 16:28:17 -0600 Subject: [PATCH 032/103] Delete edit controls. Connect cancel button and remaining logic to new draw tools flow --- .../toolbar_overlay/edit_control/_index.scss | 3 - .../edit_control/edit_control.tsx | 118 ------------------ .../toolbar_overlay/edit_control/index.ts | 33 ----- .../toolbar_overlay/toolbar_overlay.tsx | 16 --- .../toolbar_overlay/tools_control/index.ts | 4 + .../tools_control/tools_control.tsx | 12 +- 6 files changed, 9 insertions(+), 177 deletions(-) delete mode 100644 x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/_index.scss delete mode 100644 x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/edit_control.tsx delete mode 100644 x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/index.ts diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/_index.scss b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/_index.scss deleted file mode 100644 index de86299d559e86..00000000000000 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/_index.scss +++ /dev/null @@ -1,3 +0,0 @@ -.mapDrawControl__geometryFilterForm { - padding: $euiSizeS; -} diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/edit_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/edit_control.tsx deleted file mode 100644 index 1835b6859ce636..00000000000000 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/edit_control.tsx +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { Component } from 'react'; -import { - EuiButtonIcon, - EuiPopover, - EuiFlexItem, - EuiFlexGroup, - EuiButton, - EuiPanel, -} from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n/react'; -// @ts-expect-error -import { GeometryFilterForm } from '../../../components/geometry_filter_form'; -import { GeoFieldWithIndex } from '../../../components/geo_field_with_index'; -// @ts-expect-error -import { IndexGeometrySelectPopoverForm } from '../../../components/index_geometry_select_popover_form'; - -export interface Props { - geoFields: GeoFieldWithIndex[]; - activateDrawPointsMode: () => void; - activateDrawShapesMode: () => void; - deactivateDrawMode: () => void; - featureModeActive: boolean; -} - -interface State { - isPopoverOpen: boolean; -} - -export class EditControl extends Component { - state: State = { - isPopoverOpen: false, - }; - - _togglePopover = () => { - this.setState((prevState) => ({ - isPopoverOpen: !prevState.isPopoverOpen, - })); - }; - - _closePopover = () => { - this.setState({ isPopoverOpen: false }); - }; - - componentDidUpdate() { - if (this.props.featureModeActive && this.state.isPopoverOpen) { - this._closePopover(); - } - } - - _renderEditButton() { - return ( - - - - ); - } - - render() { - const editPopoverButton = ( - - { - if (geoFieldType === 'geo_point') { - this.props.activateDrawPointsMode(); - } else { - this.props.activateDrawShapesMode(); - } - }} - /> - - ); - - return ( - - {editPopoverButton} - {this.props.featureModeActive ? ( - - - - - - ) : null} - - ); - } -} diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/index.ts deleted file mode 100644 index 660581a5dbd725..00000000000000 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/edit_control/index.ts +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { AnyAction } from 'redux'; -import { ThunkDispatch } from 'redux-thunk'; -import { connect } from 'react-redux'; -import { EditControl } from './edit_control'; -import { MapStoreState } from '../../../reducers/store'; -import { DRAW_MODE } from '../../../../common'; -import { setDrawMode } from '../../../actions'; -import { getDrawMode } from '../../../selectors/ui_selectors'; - -function mapStateToProps(state: MapStoreState) { - return { - featureModeActive: - getDrawMode(state) === DRAW_MODE.DRAW_POINTS || getDrawMode(state) === DRAW_MODE.DRAW_SHAPES, - }; -} - -function mapDispatchToProps(dispatch: ThunkDispatch) { - return { - activateDrawPointsMode: () => dispatch(setDrawMode(DRAW_MODE.DRAW_POINTS)), - activateDrawShapesMode: () => dispatch(setDrawMode(DRAW_MODE.DRAW_SHAPES)), - deactivateDrawMode: () => dispatch(setDrawMode(DRAW_MODE.NONE)), - }; -} - -const connectedEditControl = connect(mapStateToProps, mapDispatchToProps)(EditControl); -export { connectedEditControl as EditControl }; diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx index 98363d15a56a60..5fc407b8f385c2 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx @@ -15,7 +15,6 @@ import { FeatureDrawControl } from './feature_draw_controls/feature_draw_control import { FeatureEditControl } from './feature_draw_controls/feature_edit_control'; import { FitToData } from './fit_to_data'; import { GeoFieldWithIndex } from '../../components/geo_field_with_index'; -import { EditControl } from './edit_control'; export interface Props { addFilters?: ((filters: Filter[], actionId: string) => Promise) | null; @@ -46,19 +45,6 @@ export function ToolbarOverlay(props: Props) { ); } - function renderEditLayerControl() { - const { geoFields } = props; - if (!geoFields.length || props.addDrawLayerInProgress) { - return null; - } - - return ( - - - - ); - } - function renderFeatureDrawAndEditControls() { return props.shapeDrawModeActive || props.pointDrawModeActive ? ( <> @@ -90,8 +76,6 @@ export function ToolbarOverlay(props: Props) { {renderToolsControl()} - {renderEditLayerControl()} - {renderFeatureDrawAndEditControls()} ); diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts index 1ab6fde917122f..7bf9f20b8f0025 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts @@ -14,10 +14,13 @@ import { setDrawMode, updateDrawState } from '../../../actions'; import { MapStoreState } from '../../../reducers/store'; import { DrawState } from '../../../../common/descriptor_types'; import { DRAW_MODE } from '../../../../common'; +import { getDrawMode } from '../../../selectors/ui_selectors'; function mapStateToProps(state: MapStoreState) { return { isDrawingFilter: isDrawingFilter(state), + featureModeActive: + getDrawMode(state) === DRAW_MODE.DRAW_POINTS || getDrawMode(state) === DRAW_MODE.DRAW_SHAPES, }; } @@ -28,6 +31,7 @@ function mapDispatchToProps(dispatch: ThunkDispatch { dispatch(updateDrawState(null)); + dispatch(setDrawMode(DRAW_MODE.NONE)); }, activateDrawFilterMode: () => dispatch(setDrawMode(DRAW_MODE.DRAW_FILTERS)), activateDrawPointsMode: () => dispatch(setDrawMode(DRAW_MODE.DRAW_POINTS)), diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx index 078a8fbff99f39..12b697dde67249 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx @@ -18,11 +18,7 @@ import { import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { ActionExecutionContext, Action } from 'src/plugins/ui_actions/public'; -import { - DRAW_TYPE, - ES_GEO_FIELD_TYPE, - ES_SPATIAL_RELATIONS, -} from '../../../../common/constants'; +import { DRAW_TYPE, ES_GEO_FIELD_TYPE, ES_SPATIAL_RELATIONS } from '../../../../common/constants'; // @ts-expect-error import { GeometryFilterForm } from '../../../components/geometry_filter_form'; import { DistanceFilterForm } from '../../../components/distance_filter_form'; @@ -74,6 +70,7 @@ export interface Props { geoFields: GeoFieldWithIndex[]; initiateDraw: (drawState: DrawState) => void; isDrawingFilter: boolean; + featureModeActive: boolean; getFilterActions?: () => Promise; getActionContext?: () => ActionExecutionContext; activateDrawFilterMode: () => void; @@ -242,6 +239,7 @@ export class ToolsControl extends Component { className="mapDrawControl__geometryFilterForm" geoFields={this.props.geoFields} onSubmit={({ geoFieldType }: { geoFieldType: string }) => { + this._closePopover(); if (geoFieldType === 'geo_point') { this.props.activateDrawPointsMode(); } else { @@ -260,7 +258,7 @@ export class ToolsControl extends Component { { ); - if (!this.props.isDrawingFilter) { + if (!(this.props.isDrawingFilter || this.props.featureModeActive)) { return toolsPopoverButton; } From 8086701af6ac88d3666f72ecfe4f66db4231ae39 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 5 May 2021 17:17:48 -0600 Subject: [PATCH 033/103] Add back deactivation on popover close for filter layers --- .../toolbar_overlay/tools_control/tools_control.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx index 12b697dde67249..c88e019f79d0f6 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx @@ -103,6 +103,9 @@ export class ToolsControl extends Component { _closePopover = () => { this.setState({ isPopoverOpen: false }); + if (this.props.isDrawingFilter) { + this.props.deactivateDrawMode(); + } }; _initiateShapeDraw = (options: { From debdb62b6f1772c065d713ca2ab0663d7035e73a Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Thu, 6 May 2021 15:00:24 -0600 Subject: [PATCH 034/103] Convert geom filter form to ts. Activate filter mode on filter forms load --- .../maps/public/components/_index.scss | 2 +- .../{ => draw_forms}/distance_filter_form.tsx | 20 +++-- .../_geometry_filter.scss | 0 .../geometry_filter_form.test.js | 0 .../geometry_filter_form.tsx} | 89 ++++++++++++------- .../index_geometry_select_popover_form.js | 2 +- .../feature_geometry_filter_form.tsx | 2 +- .../feature_draw_control.tsx | 14 +-- .../feature_draw_control/index.ts | 2 +- .../feature_edit_control.tsx | 2 +- .../toolbar_overlay/tools_control/index.ts | 9 +- .../tools_control/tools_control.tsx | 64 ++++++------- 12 files changed, 122 insertions(+), 84 deletions(-) rename x-pack/plugins/maps/public/components/{ => draw_forms}/distance_filter_form.tsx (85%) rename x-pack/plugins/maps/public/components/{ => draw_forms/geometry_filter_form}/_geometry_filter.scss (100%) rename x-pack/plugins/maps/public/components/{ => draw_forms/geometry_filter_form}/geometry_filter_form.test.js (100%) rename x-pack/plugins/maps/public/components/{geometry_filter_form.js => draw_forms/geometry_filter_form/geometry_filter_form.tsx} (62%) rename x-pack/plugins/maps/public/components/{ => draw_forms}/index_geometry_select_popover_form.js (96%) diff --git a/x-pack/plugins/maps/public/components/_index.scss b/x-pack/plugins/maps/public/components/_index.scss index 726573ce4307d5..60cf2f0d59c54b 100644 --- a/x-pack/plugins/maps/public/components/_index.scss +++ b/x-pack/plugins/maps/public/components/_index.scss @@ -1,4 +1,4 @@ @import 'action_select'; @import 'metrics_editor/metric_editors'; -@import './geometry_filter'; +@import 'draw_forms/geometry_filter_form/geometry_filter'; @import 'tooltip_selector/tooltip_selector'; diff --git a/x-pack/plugins/maps/public/components/distance_filter_form.tsx b/x-pack/plugins/maps/public/components/draw_forms/distance_filter_form.tsx similarity index 85% rename from x-pack/plugins/maps/public/components/distance_filter_form.tsx rename to x-pack/plugins/maps/public/components/draw_forms/distance_filter_form.tsx index 14ae6b11b85c8b..e2b2100e07df83 100644 --- a/x-pack/plugins/maps/public/components/distance_filter_form.tsx +++ b/x-pack/plugins/maps/public/components/draw_forms/distance_filter_form.tsx @@ -16,12 +16,12 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { ActionExecutionContext, Action } from 'src/plugins/ui_actions/public'; -import { MultiIndexGeoFieldSelect } from './multi_index_geo_field_select'; -import { GeoFieldWithIndex } from './geo_field_with_index'; -import { ActionSelect } from './action_select'; -import { ACTION_GLOBAL_APPLY_FILTER } from '../../../../../src/plugins/data/public'; +import { MultiIndexGeoFieldSelect } from '../multi_index_geo_field_select'; +import { GeoFieldWithIndex } from '../geo_field_with_index'; +import { ActionSelect } from '../action_select'; +import { ACTION_GLOBAL_APPLY_FILTER } from '../../../../../../src/plugins/data/public'; -interface Props { +export interface Props { className?: string; buttonLabel: string; geoFields: GeoFieldWithIndex[]; @@ -38,6 +38,8 @@ interface Props { indexPatternId: string; geoFieldName: string; }) => void; + activateDrawFilterMode: () => void; + deactivateDrawMode: () => void; } interface State { @@ -53,6 +55,14 @@ export class DistanceFilterForm extends Component { filterLabel: '', }; + componentDidMount() { + // this.props.activateDrawFilterMode(); + } + + componentWillUnmount() { + this.props.deactivateDrawMode(); + } + _onGeoFieldChange = (selectedField: GeoFieldWithIndex | undefined) => { this.setState({ selectedField }); }; diff --git a/x-pack/plugins/maps/public/components/_geometry_filter.scss b/x-pack/plugins/maps/public/components/draw_forms/geometry_filter_form/_geometry_filter.scss similarity index 100% rename from x-pack/plugins/maps/public/components/_geometry_filter.scss rename to x-pack/plugins/maps/public/components/draw_forms/geometry_filter_form/_geometry_filter.scss diff --git a/x-pack/plugins/maps/public/components/geometry_filter_form.test.js b/x-pack/plugins/maps/public/components/draw_forms/geometry_filter_form/geometry_filter_form.test.js similarity index 100% rename from x-pack/plugins/maps/public/components/geometry_filter_form.test.js rename to x-pack/plugins/maps/public/components/draw_forms/geometry_filter_form/geometry_filter_form.test.js diff --git a/x-pack/plugins/maps/public/components/geometry_filter_form.js b/x-pack/plugins/maps/public/components/draw_forms/geometry_filter_form/geometry_filter_form.tsx similarity index 62% rename from x-pack/plugins/maps/public/components/geometry_filter_form.js rename to x-pack/plugins/maps/public/components/draw_forms/geometry_filter_form/geometry_filter_form.tsx index 624d3b60fe14b8..36d1f6520cdc1a 100644 --- a/x-pack/plugins/maps/public/components/geometry_filter_form.js +++ b/x-pack/plugins/maps/public/components/draw_forms/geometry_filter_form/geometry_filter_form.tsx @@ -5,8 +5,7 @@ * 2.0. */ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; +import React, { ChangeEvent, Component } from 'react'; import { EuiForm, EuiFormRow, @@ -18,52 +17,76 @@ import { EuiFormErrorText, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { ES_GEO_FIELD_TYPE, ES_SPATIAL_RELATIONS } from '../../common/constants'; -import { getEsSpatialRelationLabel } from '../../common/i18n_getters'; -import { MultiIndexGeoFieldSelect } from './multi_index_geo_field_select'; -import { ActionSelect } from './action_select'; -import { ACTION_GLOBAL_APPLY_FILTER } from '../../../../../src/plugins/data/public'; - -export class GeometryFilterForm extends Component { - static propTypes = { - buttonLabel: PropTypes.string.isRequired, - geoFields: PropTypes.array.isRequired, - getFilterActions: PropTypes.func, - getActionContext: PropTypes.func, - intitialGeometryLabel: PropTypes.string.isRequired, - onSubmit: PropTypes.func.isRequired, - isFilterGeometryClosed: PropTypes.bool, - errorMsg: PropTypes.string, - }; +import { ES_GEO_FIELD_TYPE, ES_SPATIAL_RELATIONS } from '../../../../common/constants'; +import { getEsSpatialRelationLabel } from '../../../../common/i18n_getters'; +import { MultiIndexGeoFieldSelect } from '../../multi_index_geo_field_select'; +import { ActionSelect } from '../../action_select'; +import { ACTION_GLOBAL_APPLY_FILTER } from '../../../../../../../src/plugins/data/public'; +import { GeoFieldWithIndex } from '../../geo_field_with_index'; +import { Action, ActionExecutionContext } from '../../../../../../../src/plugins/ui_actions/public'; + +export interface Props { + buttonLabel: string; + geoFields: GeoFieldWithIndex[]; + getFilterActions?: () => Promise; + getActionContext?: () => ActionExecutionContext; + intitialGeometryLabel: string; + onSubmit: (options: { + actionId: string; + geometryLabel?: string; + indexPatternId?: string; + geoFieldName?: string; + geoFieldType?: ES_GEO_FIELD_TYPE; + relation?: ES_SPATIAL_RELATIONS; + }) => void; + isFilterGeometryClosed?: boolean; + errorMsg?: string; + className: string; + isLoading?: boolean; + activateDrawFilterMode: () => void; + deactivateDrawMode: () => void; +} - static defaultProps = { - isFilterGeometryClosed: true, - }; +interface State { + actionId: string; + selectedField: GeoFieldWithIndex | undefined; + geometryLabel: string; + relation: ES_SPATIAL_RELATIONS; +} - state = { +export class GeometryFilterForm extends Component { + state: State = { actionId: ACTION_GLOBAL_APPLY_FILTER, selectedField: this.props.geoFields.length ? this.props.geoFields[0] : undefined, geometryLabel: this.props.intitialGeometryLabel, relation: ES_SPATIAL_RELATIONS.INTERSECTS, }; - _onGeoFieldChange = (selectedField) => { + componentDidMount() { + this.props.activateDrawFilterMode(); + } + + componentWillUnmount() { + this.props.deactivateDrawMode(); + } + + _onGeoFieldChange = (selectedField: GeoFieldWithIndex | undefined) => { this.setState({ selectedField }); }; - _onGeometryLabelChange = (e) => { + _onGeometryLabelChange = (e: ChangeEvent) => { this.setState({ geometryLabel: e.target.value, }); }; - _onRelationChange = (e) => { + _onRelationChange = (e: ChangeEvent) => { this.setState({ relation: e.target.value, }); }; - _onActionIdChange = (value) => { + _onActionIdChange = (value: string) => { this.setState({ actionId: value }); }; @@ -71,8 +94,10 @@ export class GeometryFilterForm extends Component { this.props.onSubmit({ actionId: this.state.actionId, geometryLabel: this.state.geometryLabel, - indexPatternId: this.state.selectedField.indexPatternId, - geoFieldName: this.state.selectedField.geoFieldName, + indexPatternId: this.state.selectedField + ? this.state.selectedField.indexPatternId + : undefined, + geoFieldName: this.state.selectedField ? this.state.selectedField.geoFieldName : undefined, relation: this.state.relation, }); }; @@ -82,9 +107,13 @@ export class GeometryFilterForm extends Component { if (!this.state.selectedField) { return null; } + let _isFilterGeometryClosed = true; + if (this.props.isFilterGeometryClosed !== undefined) { + _isFilterGeometryClosed = this.props.isFilterGeometryClosed; + } const spatialRelations = - this.props.isFilterGeometryClosed && + _isFilterGeometryClosed && this.state.selectedField.geoFieldType !== ES_GEO_FIELD_TYPE.GEO_POINT ? Object.values(ES_SPATIAL_RELATIONS) : Object.values(ES_SPATIAL_RELATIONS).filter((relation) => { diff --git a/x-pack/plugins/maps/public/components/index_geometry_select_popover_form.js b/x-pack/plugins/maps/public/components/draw_forms/index_geometry_select_popover_form.js similarity index 96% rename from x-pack/plugins/maps/public/components/index_geometry_select_popover_form.js rename to x-pack/plugins/maps/public/components/draw_forms/index_geometry_select_popover_form.js index 281a0fc17e651c..0e6a403f8f02f4 100644 --- a/x-pack/plugins/maps/public/components/index_geometry_select_popover_form.js +++ b/x-pack/plugins/maps/public/components/draw_forms/index_geometry_select_popover_form.js @@ -8,7 +8,7 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { EuiForm, EuiButton, EuiSpacer, EuiTextAlign, EuiFormErrorText } from '@elastic/eui'; -import { MultiIndexGeoFieldSelect } from './multi_index_geo_field_select'; +import { MultiIndexGeoFieldSelect } from '../multi_index_geo_field_select'; import { i18n } from '@kbn/i18n'; export class IndexGeometrySelectPopoverForm extends Component { diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/features_tooltip/feature_geometry_filter_form.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/features_tooltip/feature_geometry_filter_form.tsx index 61732d1c268c2b..d00ec3a7af2494 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/features_tooltip/feature_geometry_filter_form.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/features_tooltip/feature_geometry_filter_form.tsx @@ -20,7 +20,7 @@ import { } from '../../../../common/elasticsearch_util'; import { ES_SPATIAL_RELATIONS, GEO_JSON_TYPE } from '../../../../common/constants'; // @ts-expect-error -import { GeometryFilterForm } from '../../../components/geometry_filter_form'; +import { GeometryFilterForm } from '../../../components/draw_forms/geometry_filter_form/geometry_filter_form'; import { GeoFieldWithIndex } from '../../../components/geo_field_with_index'; // over estimated and imprecise value to ensure filter has additional room for any meta keys added when filter is mapped. diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx index ebb778a413ebee..f56d78d4222423 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx @@ -10,12 +10,12 @@ import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui import { i18n } from '@kbn/i18n'; import { DRAW_TYPE } from '../../../../../common/constants'; // @ts-expect-error -import { GeometryFilterForm } from '../../../../components/geometry_filter_form'; +import { GeometryFilterForm } from '../../../../components/draw_forms/geometry_filter_form/geometry_filter_form'; export interface Props { cancelDraw: () => void; drawType: string; - initiateDraw: (drawFeatureState: DRAW_TYPE) => void; + updateCompletedShape: (drawFeatureState: DRAW_TYPE) => void; pointsOnly?: boolean; } @@ -38,7 +38,7 @@ export function FeatureDrawControl(props: Props) { > props.initiateDraw(DRAW_TYPE.LINE)} + onClick={() => props.updateCompletedShape(DRAW_TYPE.LINE)} iconType="minus" aria-label={i18n.translate( 'xpack.maps.toolbarOverlay.featureDraw.drawLineLabel', @@ -61,7 +61,7 @@ export function FeatureDrawControl(props: Props) { > props.initiateDraw(DRAW_TYPE.POLYGON)} + onClick={() => props.updateCompletedShape(DRAW_TYPE.POLYGON)} iconType="node" aria-label={i18n.translate( 'xpack.maps.toolbarOverlay.featureDraw.drawPolygonLabel', @@ -84,7 +84,7 @@ export function FeatureDrawControl(props: Props) { > props.initiateDraw(DRAW_TYPE.DISTANCE)} + onClick={() => props.updateCompletedShape(DRAW_TYPE.DISTANCE)} iconType="plusInCircle" aria-label={i18n.translate( 'xpack.maps.toolbarOverlay.featureDraw.drawCircleLabel', @@ -107,7 +107,7 @@ export function FeatureDrawControl(props: Props) { > props.initiateDraw(DRAW_TYPE.BOUNDS)} + onClick={() => props.updateCompletedShape(DRAW_TYPE.BOUNDS)} iconType="stop" aria-label={i18n.translate( 'xpack.maps.toolbarOverlay.featureDraw.drawBBoxLabel', @@ -132,7 +132,7 @@ export function FeatureDrawControl(props: Props) { > props.initiateDraw(DRAW_TYPE.POINT)} + onClick={() => props.updateCompletedShape(DRAW_TYPE.POINT)} iconType="dot" aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawPointLabel', { defaultMessage: 'Draw point', diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/index.ts index 013aa2d79153c6..f7e2673442b013 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/index.ts @@ -23,7 +23,7 @@ function mapStateToProps(state: MapStoreState) { function mapDispatchToProps(dispatch: ThunkDispatch) { return { - initiateDraw: (drawFeatureState: DRAW_TYPE) => { + updateCompletedShape: (drawFeatureState: DRAW_TYPE) => { dispatch(updateDrawFeatureState(drawFeatureState)); }, cancelDraw: () => { diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/feature_edit_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/feature_edit_control.tsx index e32904345d9c8e..13fd0a0d917757 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/feature_edit_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/feature_edit_control.tsx @@ -10,7 +10,7 @@ import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui import { i18n } from '@kbn/i18n'; import { DRAW_TYPE } from '../../../../../common/constants'; // @ts-expect-error -import { GeometryFilterForm } from '../../../../components/geometry_filter_form'; +import { GeometryFilterForm } from '../../../../components/draw_forms/geometry_filter_form/geometry_filter_form'; export interface Props { isDrawingFilter: boolean; diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts index 7bf9f20b8f0025..2b4078db0145fb 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts @@ -9,7 +9,6 @@ import { AnyAction } from 'redux'; import { ThunkDispatch } from 'redux-thunk'; import { connect } from 'react-redux'; import { ToolsControl } from './tools_control'; -import { isDrawingFilter } from '../../../selectors/map_selectors'; import { setDrawMode, updateDrawState } from '../../../actions'; import { MapStoreState } from '../../../reducers/store'; import { DrawState } from '../../../../common/descriptor_types'; @@ -17,16 +16,16 @@ import { DRAW_MODE } from '../../../../common'; import { getDrawMode } from '../../../selectors/ui_selectors'; function mapStateToProps(state: MapStoreState) { + const drawMode = getDrawMode(state); return { - isDrawingFilter: isDrawingFilter(state), - featureModeActive: - getDrawMode(state) === DRAW_MODE.DRAW_POINTS || getDrawMode(state) === DRAW_MODE.DRAW_SHAPES, + filterModeActive: drawMode === DRAW_MODE.DRAW_FILTERS, + featureModeActive: drawMode === DRAW_MODE.DRAW_POINTS || drawMode === DRAW_MODE.DRAW_SHAPES, }; } function mapDispatchToProps(dispatch: ThunkDispatch) { return { - initiateDraw: (drawState: DrawState) => { + updateCompletedShape: (drawState: DrawState) => { dispatch(updateDrawState(drawState)); }, cancelDraw: () => { diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx index c88e019f79d0f6..aec98d8446e7b4 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx @@ -19,12 +19,11 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { ActionExecutionContext, Action } from 'src/plugins/ui_actions/public'; import { DRAW_TYPE, ES_GEO_FIELD_TYPE, ES_SPATIAL_RELATIONS } from '../../../../common/constants'; -// @ts-expect-error -import { GeometryFilterForm } from '../../../components/geometry_filter_form'; -import { DistanceFilterForm } from '../../../components/distance_filter_form'; +import { GeometryFilterForm } from '../../../components/draw_forms/geometry_filter_form/geometry_filter_form'; +import { DistanceFilterForm } from '../../../components/draw_forms/distance_filter_form'; import { GeoFieldWithIndex } from '../../../components/geo_field_with_index'; // @ts-expect-error -import { IndexGeometrySelectPopoverForm } from '../../../components/index_geometry_select_popover_form'; +import { IndexGeometrySelectPopoverForm } from '../../../components/draw_forms/index_geometry_select_popover_form'; import { DrawState } from '../../../../common/descriptor_types'; const DRAW_SHAPE_LABEL = i18n.translate('xpack.maps.toolbarOverlay.drawShapeLabel', { @@ -68,8 +67,8 @@ const ADD_FEATURES_LABEL_SHORT = i18n.translate( export interface Props { cancelDraw: () => void; geoFields: GeoFieldWithIndex[]; - initiateDraw: (drawState: DrawState) => void; - isDrawingFilter: boolean; + updateCompletedShape: (drawState: DrawState) => void; + filterModeActive: boolean; featureModeActive: boolean; getFilterActions?: () => Promise; getActionContext?: () => ActionExecutionContext; @@ -89,35 +88,27 @@ export class ToolsControl extends Component { }; _togglePopover = () => { - this.setState( - (prevState) => ({ - isPopoverOpen: !prevState.isPopoverOpen, - }), - () => { - if (this.state.isPopoverOpen) { - this.props.activateDrawFilterMode(); - } - } - ); + this.setState((prevState) => ({ + isPopoverOpen: !prevState.isPopoverOpen, + })); }; _closePopover = () => { this.setState({ isPopoverOpen: false }); - if (this.props.isDrawingFilter) { + if (this.props.filterModeActive) { this.props.deactivateDrawMode(); } }; _initiateShapeDraw = (options: { actionId: string; - geometryLabel: string; - indexPatternId: string; - geoFieldName: string; - geoFieldType: ES_GEO_FIELD_TYPE; - relation: ES_SPATIAL_RELATIONS; + geometryLabel?: string; + indexPatternId?: string; + geoFieldName?: string; + geoFieldType?: ES_GEO_FIELD_TYPE; + relation?: ES_SPATIAL_RELATIONS; }) => { - this.props.activateDrawFilterMode(); - this.props.initiateDraw({ + this.props.updateCompletedShape({ drawType: DRAW_TYPE.POLYGON, ...options, }); @@ -126,13 +117,13 @@ export class ToolsControl extends Component { _initiateBoundsDraw = (options: { actionId: string; - geometryLabel: string; - indexPatternId: string; - geoFieldName: string; - geoFieldType: ES_GEO_FIELD_TYPE; - relation: ES_SPATIAL_RELATIONS; + geometryLabel?: string; + indexPatternId?: string; + geoFieldName?: string; + geoFieldType?: ES_GEO_FIELD_TYPE; + relation?: ES_SPATIAL_RELATIONS; }) => { - this.props.initiateDraw({ + this.props.updateCompletedShape({ drawType: DRAW_TYPE.BOUNDS, ...options, }); @@ -145,7 +136,7 @@ export class ToolsControl extends Component { indexPatternId: string; geoFieldName: string; }) => { - this.props.initiateDraw({ + this.props.updateCompletedShape({ drawType: DRAW_TYPE.DISTANCE, ...options, }); @@ -197,6 +188,8 @@ export class ToolsControl extends Component { } )} onSubmit={this._initiateShapeDraw} + activateDrawFilterMode={this.props.activateDrawFilterMode} + deactivateDrawMode={this.props.deactivateDrawMode} /> ), }, @@ -217,6 +210,8 @@ export class ToolsControl extends Component { } )} onSubmit={this._initiateBoundsDraw} + activateDrawFilterMode={this.props.activateDrawFilterMode} + deactivateDrawMode={this.props.deactivateDrawMode} /> ), }, @@ -231,6 +226,8 @@ export class ToolsControl extends Component { getFilterActions={this.props.getFilterActions} getActionContext={this.props.getActionContext} onSubmit={this._initiateDistanceDraw} + activateDrawFilterMode={this.props.activateDrawFilterMode} + deactivateDrawMode={this.props.deactivateDrawMode} /> ), }, @@ -288,7 +285,10 @@ export class ToolsControl extends Component { ); - if (!(this.props.isDrawingFilter || this.props.featureModeActive)) { + if ( + !(this.props.filterModeActive || this.props.featureModeActive) || + this.state.isPopoverOpen + ) { return toolsPopoverButton; } From 3f441862f6dd75ebcdbf854efd1430a0d07107d4 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Mon, 10 May 2021 11:10:44 -0600 Subject: [PATCH 035/103] Combine handling of draw state and draw mode for filters and feature drawing --- .../common/descriptor_types/map_descriptor.ts | 2 +- .../draw_forms/distance_filter_form.tsx | 10 ----- .../geometry_filter_form.tsx | 10 ----- .../mb_map/draw_control/draw_control.tsx | 3 +- .../draw_filter_control.tsx | 6 +-- .../draw_control/draw_filter_control/index.ts | 9 ++-- .../mb_map/draw_control/draw_tooltip.tsx | 6 +++ .../toolbar_overlay/tools_control/index.ts | 18 +++++--- .../tools_control/tools_control.tsx | 43 ++++++++++--------- 9 files changed, 52 insertions(+), 55 deletions(-) diff --git a/x-pack/plugins/maps/common/descriptor_types/map_descriptor.ts b/x-pack/plugins/maps/common/descriptor_types/map_descriptor.ts index acb0d9329e0652..4accdf01dd5408 100644 --- a/x-pack/plugins/maps/common/descriptor_types/map_descriptor.ts +++ b/x-pack/plugins/maps/common/descriptor_types/map_descriptor.ts @@ -56,7 +56,7 @@ export type TooltipState = { export type DrawState = { actionId: string; - drawType: DRAW_TYPE; + drawType?: DRAW_TYPE; filterLabel?: string; // point radius filter alias geoFieldName?: string; geoFieldType?: ES_GEO_FIELD_TYPE; diff --git a/x-pack/plugins/maps/public/components/draw_forms/distance_filter_form.tsx b/x-pack/plugins/maps/public/components/draw_forms/distance_filter_form.tsx index e2b2100e07df83..4db86ffbc9203a 100644 --- a/x-pack/plugins/maps/public/components/draw_forms/distance_filter_form.tsx +++ b/x-pack/plugins/maps/public/components/draw_forms/distance_filter_form.tsx @@ -38,8 +38,6 @@ export interface Props { indexPatternId: string; geoFieldName: string; }) => void; - activateDrawFilterMode: () => void; - deactivateDrawMode: () => void; } interface State { @@ -55,14 +53,6 @@ export class DistanceFilterForm extends Component { filterLabel: '', }; - componentDidMount() { - // this.props.activateDrawFilterMode(); - } - - componentWillUnmount() { - this.props.deactivateDrawMode(); - } - _onGeoFieldChange = (selectedField: GeoFieldWithIndex | undefined) => { this.setState({ selectedField }); }; diff --git a/x-pack/plugins/maps/public/components/draw_forms/geometry_filter_form/geometry_filter_form.tsx b/x-pack/plugins/maps/public/components/draw_forms/geometry_filter_form/geometry_filter_form.tsx index 36d1f6520cdc1a..b790124aabdffe 100644 --- a/x-pack/plugins/maps/public/components/draw_forms/geometry_filter_form/geometry_filter_form.tsx +++ b/x-pack/plugins/maps/public/components/draw_forms/geometry_filter_form/geometry_filter_form.tsx @@ -43,8 +43,6 @@ export interface Props { errorMsg?: string; className: string; isLoading?: boolean; - activateDrawFilterMode: () => void; - deactivateDrawMode: () => void; } interface State { @@ -62,14 +60,6 @@ export class GeometryFilterForm extends Component { relation: ES_SPATIAL_RELATIONS.INTERSECTS, }; - componentDidMount() { - this.props.activateDrawFilterMode(); - } - - componentWillUnmount() { - this.props.deactivateDrawMode(); - } - _onGeoFieldChange = (selectedField: GeoFieldWithIndex | undefined) => { this.setState({ selectedField }); }; diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx index 20a10753e64e3a..2c728118c5f913 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx @@ -54,12 +54,13 @@ export class DrawControl extends Component { modes: mbDrawModes, }); - componentDidUpdate() { + componentWillReceiveProps() { this._syncDrawControl(); } componentDidMount() { this._isMounted = true; + this._syncDrawControl(); } componentWillUnmount() { diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_filter_control/draw_filter_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_filter_control/draw_filter_control.tsx index 4ffb72989ebc16..bba9dba1d49391 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_filter_control/draw_filter_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_filter_control/draw_filter_control.tsx @@ -27,7 +27,7 @@ export interface Props { addFilters: (filters: Filter[], actionId: string) => Promise; disableDrawState: () => void; drawState?: DrawState; - isDrawingFilter: boolean; + filterModeActive: boolean; mbMap: MbMap; } @@ -107,13 +107,13 @@ export class DrawFilterControl extends Component { return ( ); } diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_filter_control/index.ts b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_filter_control/index.ts index 17f4d919fb7e0d..d1d2030023f175 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_filter_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_filter_control/index.ts @@ -9,14 +9,16 @@ import { AnyAction } from 'redux'; import { ThunkDispatch } from 'redux-thunk'; import { connect } from 'react-redux'; import { DrawFilterControl } from './draw_filter_control'; -import { updateDrawState } from '../../../../actions'; -import { getDrawState, isDrawingFilter } from '../../../../selectors/map_selectors'; +import { setDrawMode, updateDrawState } from '../../../../actions'; +import { getDrawState } from '../../../../selectors/map_selectors'; import { MapStoreState } from '../../../../reducers/store'; +import { getDrawMode } from '../../../../selectors/ui_selectors'; +import { DRAW_MODE } from '../../../../../common'; function mapStateToProps(state: MapStoreState) { return { - isDrawingFilter: isDrawingFilter(state), drawState: getDrawState(state), + filterModeActive: getDrawMode(state) === DRAW_MODE.DRAW_FILTERS, }; } @@ -24,6 +26,7 @@ function mapDispatchToProps(dispatch: ThunkDispatch { private readonly _popoverRef: RefObject = React.createRef(); + private _isMounted = false; state: State = { x: undefined, @@ -35,6 +36,7 @@ export class DrawTooltip extends Component { }; componentDidMount() { + this._isMounted = true; this.props.mbMap.on('mousemove', this._updateTooltipLocation); this.props.mbMap.on('mouseout', this._hideTooltip); } @@ -46,6 +48,7 @@ export class DrawTooltip extends Component { } componentWillUnmount() { + this._isMounted = false; this.props.mbMap.off('mousemove', this._updateTooltipLocation); this.props.mbMap.off('mouseout', this._hideTooltip); this._updateTooltipLocation.cancel(); @@ -106,6 +109,9 @@ export class DrawTooltip extends Component { _updateTooltipLocation = _.throttle(({ lngLat }) => { const mouseLocation = this.props.mbMap.project(lngLat); + if (!this._isMounted) { + return; + } this.setState({ isOpen: true, x: mouseLocation.x, diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts index 2b4078db0145fb..bf02301676709e 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts @@ -25,16 +25,22 @@ function mapStateToProps(state: MapStoreState) { function mapDispatchToProps(dispatch: ThunkDispatch) { return { - updateCompletedShape: (drawState: DrawState) => { - dispatch(updateDrawState(drawState)); - }, cancelDraw: () => { dispatch(updateDrawState(null)); dispatch(setDrawMode(DRAW_MODE.NONE)); }, - activateDrawFilterMode: () => dispatch(setDrawMode(DRAW_MODE.DRAW_FILTERS)), - activateDrawPointsMode: () => dispatch(setDrawMode(DRAW_MODE.DRAW_POINTS)), - activateDrawShapesMode: () => dispatch(setDrawMode(DRAW_MODE.DRAW_SHAPES)), + activateDrawFilterMode: (drawState: DrawState) => { + dispatch(setDrawMode(DRAW_MODE.DRAW_FILTERS)); + dispatch(updateDrawState(drawState)); + }, + activateDrawPointsMode: (drawState: DrawState) => { + dispatch(setDrawMode(DRAW_MODE.DRAW_POINTS)); + dispatch(updateDrawState(drawState)); + }, + activateDrawShapesMode: (drawState: DrawState) => { + dispatch(setDrawMode(DRAW_MODE.DRAW_SHAPES)); + dispatch(updateDrawState(drawState)); + }, deactivateDrawMode: () => dispatch(setDrawMode(DRAW_MODE.NONE)), }; } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx index aec98d8446e7b4..6bee926aa206d0 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx @@ -67,14 +67,13 @@ const ADD_FEATURES_LABEL_SHORT = i18n.translate( export interface Props { cancelDraw: () => void; geoFields: GeoFieldWithIndex[]; - updateCompletedShape: (drawState: DrawState) => void; filterModeActive: boolean; featureModeActive: boolean; getFilterActions?: () => Promise; getActionContext?: () => ActionExecutionContext; - activateDrawFilterMode: () => void; - activateDrawPointsMode: () => void; - activateDrawShapesMode: () => void; + activateDrawFilterMode: (drawState: DrawState) => void; + activateDrawPointsMode: (drawState: DrawState) => void; + activateDrawShapesMode: (drawState: DrawState) => void; deactivateDrawMode: () => void; } @@ -108,7 +107,7 @@ export class ToolsControl extends Component { geoFieldType?: ES_GEO_FIELD_TYPE; relation?: ES_SPATIAL_RELATIONS; }) => { - this.props.updateCompletedShape({ + this.props.activateDrawFilterMode({ drawType: DRAW_TYPE.POLYGON, ...options, }); @@ -123,7 +122,7 @@ export class ToolsControl extends Component { geoFieldType?: ES_GEO_FIELD_TYPE; relation?: ES_SPATIAL_RELATIONS; }) => { - this.props.updateCompletedShape({ + this.props.activateDrawFilterMode({ drawType: DRAW_TYPE.BOUNDS, ...options, }); @@ -136,13 +135,28 @@ export class ToolsControl extends Component { indexPatternId: string; geoFieldName: string; }) => { - this.props.updateCompletedShape({ + this.props.activateDrawFilterMode({ drawType: DRAW_TYPE.DISTANCE, ...options, }); this._closePopover(); }; + _initiateFeatureEdit = (options: { + actionId: string; + filterLabel: string; + indexPatternId: string; + geoFieldName: string; + geoFieldType?: ES_GEO_FIELD_TYPE; + }) => { + this._closePopover(); + if (options.geoFieldType === 'geo_point') { + this.props.activateDrawPointsMode(options); + } else { + this.props.activateDrawShapesMode(options); + } + }; + _getDrawPanels() { const tools = [ { @@ -188,8 +202,6 @@ export class ToolsControl extends Component { } )} onSubmit={this._initiateShapeDraw} - activateDrawFilterMode={this.props.activateDrawFilterMode} - deactivateDrawMode={this.props.deactivateDrawMode} /> ), }, @@ -210,8 +222,6 @@ export class ToolsControl extends Component { } )} onSubmit={this._initiateBoundsDraw} - activateDrawFilterMode={this.props.activateDrawFilterMode} - deactivateDrawMode={this.props.deactivateDrawMode} /> ), }, @@ -226,8 +236,6 @@ export class ToolsControl extends Component { getFilterActions={this.props.getFilterActions} getActionContext={this.props.getActionContext} onSubmit={this._initiateDistanceDraw} - activateDrawFilterMode={this.props.activateDrawFilterMode} - deactivateDrawMode={this.props.deactivateDrawMode} /> ), }, @@ -238,14 +246,7 @@ export class ToolsControl extends Component { { - this._closePopover(); - if (geoFieldType === 'geo_point') { - this.props.activateDrawPointsMode(); - } else { - this.props.activateDrawShapesMode(); - } - }} + onSubmit={this._initiateFeatureEdit} /> ), }, From 7fdd380cc3bc929629998c40a8b925ac5ac3c3b2 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Mon, 10 May 2021 11:49:58 -0600 Subject: [PATCH 036/103] Add popover title placeholder --- .../connected_components/mb_map/draw_control/draw_tooltip.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_tooltip.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_tooltip.tsx index e68dcb60774bb2..dc40fb34fea605 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_tooltip.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_tooltip.tsx @@ -7,7 +7,7 @@ import _ from 'lodash'; import React, { Component, RefObject } from 'react'; -import { EuiPopover, EuiText } from '@elastic/eui'; +import { EuiPopover, EuiPopoverTitle, EuiText } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { Map as MbMap } from 'mapbox-gl'; import { DRAW_TYPE } from '../../../../common/constants'; @@ -84,6 +84,7 @@ export class DrawTooltip extends Component { return ( { transform: `translate(${this.state.x - 13}px, ${this.state.y - 13}px)`, }} > + Hello, I’m a popover title {instructions} From 00ab78324ac0eb038ce142eca449357d1858e6e5 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Mon, 10 May 2021 14:27:52 -0600 Subject: [PATCH 037/103] Organize filter vs. feature modes. Replace old filter check logic --- .../public/actions/map_action_constants.ts | 2 +- .../maps/public/actions/map_actions.ts | 21 ++++++++----------- .../mb_map/draw_control/draw_control.tsx | 4 ++-- .../draw_feature_control/index.ts | 6 +++--- .../mb_map/draw_control/index.ts | 6 +++--- .../mb_map/tooltip_control/index.js | 5 +++-- .../mb_map/tooltip_control/tooltip_control.js | 4 ++-- .../tooltip_control/tooltip_control.test.js | 2 -- .../tooltip_control/tooltip_popover.test.js | 1 - .../feature_draw_control.tsx | 2 +- .../feature_draw_control/index.ts | 16 +++++++------- .../feature_edit_control.tsx | 4 ++-- .../feature_edit_control/index.ts | 16 +++++++------- .../tools_control/tools_control.test.tsx | 3 +-- .../plugins/maps/public/reducers/map/map.ts | 14 +++++++------ .../plugins/maps/public/reducers/map/types.ts | 2 +- .../maps/public/selectors/map_selectors.ts | 4 ---- 17 files changed, 52 insertions(+), 60 deletions(-) diff --git a/x-pack/plugins/maps/public/actions/map_action_constants.ts b/x-pack/plugins/maps/public/actions/map_action_constants.ts index f1250f88cc377d..8c63ee498c51f4 100644 --- a/x-pack/plugins/maps/public/actions/map_action_constants.ts +++ b/x-pack/plugins/maps/public/actions/map_action_constants.ts @@ -39,7 +39,7 @@ export const REMOVE_TRACKED_LAYER_STATE = 'REMOVE_TRACKED_LAYER_STATE'; export const SET_OPEN_TOOLTIPS = 'SET_OPEN_TOOLTIPS'; export const UPDATE_DRAW_STATE = 'UPDATE_DRAW_STATE'; export const UPDATE_EDIT_MODE = 'UPDATE_EDIT_MODE'; -export const UPDATE_DRAW_FEATURE_STATE = 'UPDATE_DRAW_FEATURE_STATE'; +export const SET_SHAPE_TO_DRAW = 'SET_SHAPE_TO_DRAW'; export const SET_SCROLL_ZOOM = 'SET_SCROLL_ZOOM'; export const SET_MAP_INIT_ERROR = 'SET_MAP_INIT_ERROR'; export const SET_WAITING_FOR_READY_HIDDEN_LAYERS = 'SET_WAITING_FOR_READY_HIDDEN_LAYERS'; diff --git a/x-pack/plugins/maps/public/actions/map_actions.ts b/x-pack/plugins/maps/public/actions/map_actions.ts index 5a761a95c4f1aa..ba26d76cc5fa2c 100644 --- a/x-pack/plugins/maps/public/actions/map_actions.ts +++ b/x-pack/plugins/maps/public/actions/map_actions.ts @@ -44,7 +44,7 @@ import { TRACK_MAP_SETTINGS, TRIGGER_REFRESH_TIMER, UPDATE_DRAW_STATE, - UPDATE_DRAW_FEATURE_STATE, + SET_SHAPE_TO_DRAW, UPDATE_EDIT_MODE, UPDATE_MAP_SETTING, ADD_FEATURES_TO_INDEX_QUEUE, @@ -318,26 +318,23 @@ export function triggerRefreshTimer() { }; } -export function updateDrawState(drawState: DrawState | null) { +export function setShapeToDraw(shapeToDraw: DRAW_TYPE | null) { return (dispatch: Dispatch) => { - if (drawState !== null) { - dispatch({ type: SET_OPEN_TOOLTIPS, openTooltips: [] }); // tooltips just get in the way - } dispatch({ - type: UPDATE_DRAW_STATE, - drawState, + type: SET_SHAPE_TO_DRAW, + shapeToDraw, }); }; } -export function updateDrawFeatureState(drawFeatureState: DRAW_TYPE | null) { +export function updateDrawState(drawState: DrawState | null) { return (dispatch: Dispatch) => { - if (drawFeatureState !== null) { - dispatch({ type: SET_OPEN_TOOLTIPS, openTooltips: [] }); + if (drawState !== null) { + dispatch({ type: SET_OPEN_TOOLTIPS, openTooltips: [] }); // tooltips just get in the way } dispatch({ - type: UPDATE_DRAW_FEATURE_STATE, - drawFeatureState, + type: UPDATE_DRAW_STATE, + drawState, }); }; } diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx index 2c728118c5f913..4cd2c5623d6e2a 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx @@ -43,7 +43,7 @@ export interface Props { onFeaturesSelected?: (drawControl: MapboxDraw) => (event: { features: Feature[] }) => void; mbMap: MbMap; drawActive: boolean; - updateDrawFeatureState: (drawFeatureState: DRAW_TYPE) => void; + setShapeToDraw: (shapeToDraw: DRAW_TYPE) => void; } export class DrawControl extends Component { @@ -84,7 +84,7 @@ export class DrawControl extends Component { _onModeChange = ({ mode }: { mode: string }) => { if (mbModeEquivalencies.has(mode)) { - this.props.updateDrawFeatureState(mbModeEquivalencies.get(mode) as DRAW_TYPE); + this.props.setShapeToDraw(mbModeEquivalencies.get(mode) as DRAW_TYPE); } }; diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts index c2a01b05c5bbd6..152cbae1dc0a68 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts @@ -13,13 +13,13 @@ import { DrawFeatureControl } from './draw_feature_control'; import { addFeaturesToIndexQueue, removeFeaturesFromIndexQueue, - updateDrawFeatureState, + setShapeToDraw, } from '../../../../actions'; import { MapStoreState } from '../../../../reducers/store'; function mapStateToProps(state: MapStoreState) { return { - drawType: state.map.mapState.drawFeatureState, + drawType: state.map.mapState.shapeToDraw, }; } @@ -29,7 +29,7 @@ function mapDispatchToProps(dispatch: ThunkDispatch) { return { - updateDrawFeatureState(drawFeatureState: DRAW_TYPE) { - dispatch(updateDrawFeatureState(drawFeatureState)); + setShapeToDraw(shapeToDraw: DRAW_TYPE) { + dispatch(setShapeToDraw(shapeToDraw)); }, }; } diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/index.js b/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/index.js index 7c404058395949..ffd8495ee27c6b 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/index.js +++ b/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/index.js @@ -17,14 +17,15 @@ import { getLayerList, getOpenTooltips, getHasLockedTooltips, - isDrawingFilter, } from '../../../selectors/map_selectors'; +import { getDrawMode } from '../../../selectors/ui_selectors'; +import { DRAW_MODE } from '../../../../common'; function mapStateToProps(state = {}) { return { layerList: getLayerList(state), hasLockedTooltips: getHasLockedTooltips(state), - isDrawingFilter: isDrawingFilter(state), + filterModeActive: getDrawMode(state) === DRAW_MODE.DRAW_FILTERS, openTooltips: getOpenTooltips(state), }; } diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.js b/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.js index 85c4fb2bca7949..01ce627cdf2b7d 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.js +++ b/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.js @@ -93,7 +93,7 @@ export class TooltipControl extends React.Component { } _lockTooltip = (e) => { - if (this.props.isDrawingFilter) { + if (this.props.filterModeActive) { // ignore click events when in draw mode return; } @@ -117,7 +117,7 @@ export class TooltipControl extends React.Component { }; _updateHoverTooltipState = _.debounce((e) => { - if (this.props.isDrawingFilter || this.props.hasLockedTooltips) { + if (this.props.filterModeActive || this.props.hasLockedTooltips) { // ignore hover events when in draw mode or when there are locked tooltips return; } diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.test.js b/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.test.js index 5d7b078ed96746..89ae6a4f13607d 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.test.js +++ b/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.test.js @@ -54,7 +54,6 @@ const defaultProps = { closeOnHoverTooltip: () => {}, openOnHoverTooltip: () => {}, layerList: [mockLayer], - isDrawingFilter: false, addFilters: () => {}, geoFields: [{}], openTooltips: [], @@ -185,7 +184,6 @@ describe('TooltipControl', () => { {...defaultProps} closeOnClickTooltip={closeOnClickTooltipStub} openOnClickTooltip={openOnClickTooltipStub} - isDrawingFilter={true} /> ); diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_popover.test.js b/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_popover.test.js index cb90d1f50bcd58..7017dbe091b631 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_popover.test.js +++ b/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_popover.test.js @@ -60,7 +60,6 @@ const defaultProps = { mbMap: mockMBMap, closeTooltip: () => {}, layerList: [], - isDrawingFilter: false, addFilters: () => {}, geoFields: [{}], location: [-120, 30], diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx index f56d78d4222423..feb3700d0c1d63 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx @@ -15,7 +15,7 @@ import { GeometryFilterForm } from '../../../../components/draw_forms/geometry_f export interface Props { cancelDraw: () => void; drawType: string; - updateCompletedShape: (drawFeatureState: DRAW_TYPE) => void; + updateCompletedShape: (shapeToDraw: DRAW_TYPE) => void; pointsOnly?: boolean; } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/index.ts index f7e2673442b013..5dd919dde126c3 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/index.ts @@ -9,25 +9,25 @@ import { AnyAction } from 'redux'; import { ThunkDispatch } from 'redux-thunk'; import { connect } from 'react-redux'; import { FeatureDrawControl } from './feature_draw_control'; -import { isDrawingFilter } from '../../../../selectors/map_selectors'; -import { updateDrawFeatureState } from '../../../../actions'; +import { setShapeToDraw } from '../../../../actions'; import { MapStoreState } from '../../../../reducers/store'; -import { DRAW_TYPE } from '../../../../../common'; +import { DRAW_MODE, DRAW_TYPE } from '../../../../../common'; +import { getDrawMode } from '../../../../selectors/ui_selectors'; function mapStateToProps(state: MapStoreState) { return { - isDrawingFilter: isDrawingFilter(state), - drawType: state.map.mapState.drawFeatureState, + filterModeActive: getDrawMode(state) === DRAW_MODE.DRAW_FILTERS, + drawType: state.map.mapState.shapeToDraw, }; } function mapDispatchToProps(dispatch: ThunkDispatch) { return { - updateCompletedShape: (drawFeatureState: DRAW_TYPE) => { - dispatch(updateDrawFeatureState(drawFeatureState)); + updateCompletedShape: (shapeToDraw: DRAW_TYPE) => { + dispatch(setShapeToDraw(shapeToDraw)); }, cancelDraw: () => { - dispatch(updateDrawFeatureState(null)); + dispatch(setShapeToDraw(null)); }, }; } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/feature_edit_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/feature_edit_control.tsx index 13fd0a0d917757..9eb1977dc312a5 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/feature_edit_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/feature_edit_control.tsx @@ -13,10 +13,10 @@ import { DRAW_TYPE } from '../../../../../common/constants'; import { GeometryFilterForm } from '../../../../components/draw_forms/geometry_filter_form/geometry_filter_form'; export interface Props { - isDrawingFilter: boolean; + filterModeActive: boolean; drawType: string; cancelDraw: () => void; - initiateDraw: (drawFeatureState: DRAW_TYPE) => void; + initiateDraw: (shapeToDraw: DRAW_TYPE) => void; } export function FeatureEditControl(props: Props) { diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/index.ts index ca6c7c5bfacde3..9b46bd517df858 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/index.ts @@ -9,25 +9,25 @@ import { AnyAction } from 'redux'; import { ThunkDispatch } from 'redux-thunk'; import { connect } from 'react-redux'; import { FeatureEditControl } from './feature_edit_control'; -import { isDrawingFilter } from '../../../../selectors/map_selectors'; -import { updateDrawFeatureState } from '../../../../actions'; +import { setShapeToDraw } from '../../../../actions'; import { MapStoreState } from '../../../../reducers/store'; -import { DRAW_TYPE } from '../../../../../common'; +import { DRAW_MODE, DRAW_TYPE } from '../../../../../common'; +import { getDrawMode } from '../../../../selectors/ui_selectors'; function mapStateToProps(state: MapStoreState) { return { - isDrawingFilter: isDrawingFilter(state), - drawType: state.map.mapState.drawFeatureState, + filterModeActive: getDrawMode(state) === DRAW_MODE.DRAW_FILTERS, + drawType: state.map.mapState.shapeToDraw, }; } function mapDispatchToProps(dispatch: ThunkDispatch) { return { - initiateDraw: (drawFeatureState: DRAW_TYPE) => { - dispatch(updateDrawFeatureState(drawFeatureState)); + initiateDraw: (shapeToDraw: DRAW_TYPE) => { + dispatch(setShapeToDraw(shapeToDraw)); }, cancelDraw: () => { - dispatch(updateDrawFeatureState(null)); + dispatch(setShapeToDraw(null)); }, }; } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.test.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.test.tsx index 868f700d3c7717..f9e0203c67add8 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.test.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.test.tsx @@ -20,7 +20,6 @@ const defaultProps = { indexPatternId: '1', }, ], - isDrawingFilter: false, }; test('renders', async () => { @@ -30,7 +29,7 @@ test('renders', async () => { }); test('Should render cancel button when drawing', async () => { - const component = shallow(); + const component = shallow(); expect(component).toMatchSnapshot(); }); diff --git a/x-pack/plugins/maps/public/reducers/map/map.ts b/x-pack/plugins/maps/public/reducers/map/map.ts index 21b955bf1f2c3e..40208bb61cd8be 100644 --- a/x-pack/plugins/maps/public/reducers/map/map.ts +++ b/x-pack/plugins/maps/public/reducers/map/map.ts @@ -46,7 +46,7 @@ import { ROLLBACK_MAP_SETTINGS, TRACK_MAP_SETTINGS, UPDATE_MAP_SETTING, - UPDATE_DRAW_FEATURE_STATE, + SET_SHAPE_TO_DRAW, UPDATE_EDIT_MODE, ADD_FEATURES_TO_INDEX_QUEUE, SET_VECTOR_LAYER_INDEX_NAME, @@ -85,7 +85,7 @@ export const DEFAULT_MAP_STATE: MapState = { refreshTimerLastTriggeredAt: undefined, vectorLayerIndexName: '', drawState: undefined, - drawFeatureState: undefined, + shapeToDraw: undefined, editModeActive: false, featuresToIndexQueue: [], }, @@ -106,12 +106,12 @@ export function map(state: MapState = DEFAULT_MAP_STATE, action: any) { drawState: action.drawState, }, }; - case UPDATE_DRAW_FEATURE_STATE: + case SET_SHAPE_TO_DRAW: return { ...state, mapState: { ...state.mapState, - drawFeatureState: action.drawFeatureState, + shapeToDraw: action.shapeToDraw, }, }; case UPDATE_EDIT_MODE: @@ -131,7 +131,9 @@ export function map(state: MapState = DEFAULT_MAP_STATE, action: any) { }, }; case REMOVE_FEATURES_FROM_INDEX_QUEUE: - const newFeatureArr = state.mapState.featuresToIndexQueue.filter(({ id }: { id: string }) => !action.featureIds.includes(id)) + const newFeatureArr = state.mapState.featuresToIndexQueue.filter( + ({ id }: { id: string }) => !action.featureIds.includes(id) + ); return { ...state, mapState: { @@ -153,7 +155,7 @@ export function map(state: MapState = DEFAULT_MAP_STATE, action: any) { mapState: { ...state.mapState, drawState: undefined, - drawFeatureState: undefined, + shapeToDraw: undefined, editModeActive: false, featuresToIndexQueue: [], }, diff --git a/x-pack/plugins/maps/public/reducers/map/types.ts b/x-pack/plugins/maps/public/reducers/map/types.ts index 938b3344308195..c2fba10773ad50 100644 --- a/x-pack/plugins/maps/public/reducers/map/types.ts +++ b/x-pack/plugins/maps/public/reducers/map/types.ts @@ -38,7 +38,7 @@ export type MapContext = { refreshTimerLastTriggeredAt?: string; vectorLayerIndexName: string; drawState?: DrawState; - drawFeatureState?: DRAW_TYPE; + shapeToDraw?: DRAW_TYPE; featuresToIndexQueue: Feature[]; editModeActive: boolean; searchSessionId?: string; diff --git a/x-pack/plugins/maps/public/selectors/map_selectors.ts b/x-pack/plugins/maps/public/selectors/map_selectors.ts index f60848f18c2f94..4847ef0c1df59a 100644 --- a/x-pack/plugins/maps/public/selectors/map_selectors.ts +++ b/x-pack/plugins/maps/public/selectors/map_selectors.ts @@ -196,10 +196,6 @@ export const isUsingSearch = (state: MapStoreState): boolean => { export const getDrawState = ({ map }: MapStoreState): DrawState | undefined => map.mapState.drawState; -export const isDrawingFilter = ({ map }: MapStoreState): boolean => { - return !!map.mapState.drawState; -}; - export const getEditModeActive = ({ map }: MapStoreState): boolean => map.mapState.editModeActive; export const getRefreshConfig = ({ map }: MapStoreState): MapRefreshConfig => { From d79d4f660fa1ef0080f4bc577e307a94b530d9e0 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Mon, 10 May 2021 14:41:07 -0600 Subject: [PATCH 038/103] Create selector for shape being drawn --- .../mb_map/draw_control/draw_feature_control/index.ts | 3 ++- .../feature_draw_controls/feature_draw_control/index.ts | 3 ++- .../feature_draw_controls/feature_edit_control/index.ts | 3 ++- x-pack/plugins/maps/public/reducers/map/map.ts | 1 + x-pack/plugins/maps/public/selectors/map_selectors.ts | 4 ++++ 5 files changed, 11 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts index 152cbae1dc0a68..64467a0fe27c97 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts @@ -16,10 +16,11 @@ import { setShapeToDraw, } from '../../../../actions'; import { MapStoreState } from '../../../../reducers/store'; +import { getShapeToDraw } from '../../../../selectors/map_selectors'; function mapStateToProps(state: MapStoreState) { return { - drawType: state.map.mapState.shapeToDraw, + drawType: getShapeToDraw(state), }; } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/index.ts index 5dd919dde126c3..726baeb20d7424 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/index.ts @@ -13,11 +13,12 @@ import { setShapeToDraw } from '../../../../actions'; import { MapStoreState } from '../../../../reducers/store'; import { DRAW_MODE, DRAW_TYPE } from '../../../../../common'; import { getDrawMode } from '../../../../selectors/ui_selectors'; +import { getShapeToDraw } from '../../../../selectors/map_selectors'; function mapStateToProps(state: MapStoreState) { return { filterModeActive: getDrawMode(state) === DRAW_MODE.DRAW_FILTERS, - drawType: state.map.mapState.shapeToDraw, + drawType: getShapeToDraw(state), }; } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/index.ts index 9b46bd517df858..4b09b70a012cef 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/index.ts @@ -13,11 +13,12 @@ import { setShapeToDraw } from '../../../../actions'; import { MapStoreState } from '../../../../reducers/store'; import { DRAW_MODE, DRAW_TYPE } from '../../../../../common'; import { getDrawMode } from '../../../../selectors/ui_selectors'; +import { getShapeToDraw } from '../../../../selectors/map_selectors'; function mapStateToProps(state: MapStoreState) { return { filterModeActive: getDrawMode(state) === DRAW_MODE.DRAW_FILTERS, - drawType: state.map.mapState.shapeToDraw, + drawType: getShapeToDraw(state), }; } diff --git a/x-pack/plugins/maps/public/reducers/map/map.ts b/x-pack/plugins/maps/public/reducers/map/map.ts index 40208bb61cd8be..600c25093bf859 100644 --- a/x-pack/plugins/maps/public/reducers/map/map.ts +++ b/x-pack/plugins/maps/public/reducers/map/map.ts @@ -66,6 +66,7 @@ import { } from './layer_utils'; import { startDataRequest, stopDataRequest, updateSourceDataRequest } from './data_request_utils'; import { MapState } from './types'; +import { DRAW_TYPE } from '../../../common'; export const DEFAULT_MAP_STATE: MapState = { ready: false, diff --git a/x-pack/plugins/maps/public/selectors/map_selectors.ts b/x-pack/plugins/maps/public/selectors/map_selectors.ts index 4847ef0c1df59a..cb6714a12e29b2 100644 --- a/x-pack/plugins/maps/public/selectors/map_selectors.ts +++ b/x-pack/plugins/maps/public/selectors/map_selectors.ts @@ -27,6 +27,7 @@ import { InnerJoin } from '../classes/joins/inner_join'; import { getSourceByType } from '../classes/sources/source_registry'; import { GeoJsonFileSource } from '../classes/sources/geojson_file_source'; import { + DRAW_TYPE, SOURCE_DATA_REQUEST_ID, SOURCE_TYPES, SPATIAL_FILTERS_LAYER_ID, @@ -198,6 +199,9 @@ export const getDrawState = ({ map }: MapStoreState): DrawState | undefined => export const getEditModeActive = ({ map }: MapStoreState): boolean => map.mapState.editModeActive; +export const getShapeToDraw = ({ map }: MapStoreState): DRAW_TYPE | undefined => + map.mapState.shapeToDraw; + export const getRefreshConfig = ({ map }: MapStoreState): MapRefreshConfig => { if (map.mapState.refreshConfig) { return map.mapState.refreshConfig; From 9d85c81d301f8a43fa1b839d3025ec5fa041e531 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Mon, 10 May 2021 14:48:53 -0600 Subject: [PATCH 039/103] Clean up --- .../maps/public/actions/map_action_constants.ts | 1 - x-pack/plugins/maps/public/actions/map_actions.ts | 8 -------- .../maps/public/connected_components/mb_map/index.ts | 4 +--- .../public/connected_components/mb_map/mb_map.tsx | 1 - .../connected_components/toolbar_overlay/index.ts | 5 +---- .../toolbar_overlay/toolbar_overlay.tsx | 1 - x-pack/plugins/maps/public/reducers/map/map.ts | 12 ------------ x-pack/plugins/maps/public/reducers/map/types.ts | 1 - .../plugins/maps/public/selectors/map_selectors.ts | 2 -- 9 files changed, 2 insertions(+), 33 deletions(-) diff --git a/x-pack/plugins/maps/public/actions/map_action_constants.ts b/x-pack/plugins/maps/public/actions/map_action_constants.ts index 8c63ee498c51f4..144ddb204ccd4c 100644 --- a/x-pack/plugins/maps/public/actions/map_action_constants.ts +++ b/x-pack/plugins/maps/public/actions/map_action_constants.ts @@ -38,7 +38,6 @@ 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_OPEN_TOOLTIPS = 'SET_OPEN_TOOLTIPS'; export const UPDATE_DRAW_STATE = 'UPDATE_DRAW_STATE'; -export const UPDATE_EDIT_MODE = 'UPDATE_EDIT_MODE'; export const SET_SHAPE_TO_DRAW = 'SET_SHAPE_TO_DRAW'; export const SET_SCROLL_ZOOM = 'SET_SCROLL_ZOOM'; export const SET_MAP_INIT_ERROR = 'SET_MAP_INIT_ERROR'; diff --git a/x-pack/plugins/maps/public/actions/map_actions.ts b/x-pack/plugins/maps/public/actions/map_actions.ts index ba26d76cc5fa2c..55a849005d5497 100644 --- a/x-pack/plugins/maps/public/actions/map_actions.ts +++ b/x-pack/plugins/maps/public/actions/map_actions.ts @@ -45,7 +45,6 @@ import { TRIGGER_REFRESH_TIMER, UPDATE_DRAW_STATE, SET_SHAPE_TO_DRAW, - UPDATE_EDIT_MODE, UPDATE_MAP_SETTING, ADD_FEATURES_TO_INDEX_QUEUE, SET_VECTOR_LAYER_INDEX_NAME, @@ -339,13 +338,6 @@ export function updateDrawState(drawState: DrawState | null) { }; } -export function updateEditMode(isActive: boolean) { - return { - type: UPDATE_EDIT_MODE, - isActive, - }; -} - export function addFeaturesToIndexQueue(features: Feature[]) { return { type: ADD_FEATURES_TO_INDEX_QUEUE, diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/index.ts b/x-pack/plugins/maps/public/connected_components/mb_map/index.ts index 341fcf91573162..4f94cbc7b74588 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/index.ts +++ b/x-pack/plugins/maps/public/connected_components/mb_map/index.ts @@ -23,7 +23,6 @@ import { import { getGoto, getLayerList, - getLayersBySourceType, getMapReady, getMapSettings, getScrollZoom, @@ -32,7 +31,7 @@ import { import { getDrawMode, getIsFullScreen } from '../../selectors/ui_selectors'; import { getInspectorAdapters } from '../../reducers/non_serializable_instances'; import { MapStoreState } from '../../reducers/store'; -import { DRAW_MODE, SOURCE_TYPES } from '../../../common'; +import { DRAW_MODE } from '../../../common'; function mapStateToProps(state: MapStoreState) { return { @@ -44,7 +43,6 @@ function mapStateToProps(state: MapStoreState) { inspectorAdapters: getInspectorAdapters(state), scrollZoom: getScrollZoom(state), isFullScreen: getIsFullScreen(state), - editModeActive: !!getLayersBySourceType(SOURCE_TYPES.ES_SEARCH, state).length, featureModeActive: getDrawMode(state) === DRAW_MODE.DRAW_SHAPES || getDrawMode(state) === DRAW_MODE.DRAW_POINTS, filterModeActive: getDrawMode(state) === DRAW_MODE.DRAW_FILTERS, diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/mb_map.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/mb_map.tsx index 84d46bef8ec3a5..1d6a81275d331b 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/mb_map.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/mb_map.tsx @@ -63,7 +63,6 @@ export interface Props { goto?: Goto | null; inspectorAdapters: Adapters; isFullScreen: boolean; - editModeActive: boolean; scrollZoom: boolean; extentChanged: (mapExtentState: MapExtentState) => void; onMapReady: (mapExtentState: MapExtentState) => void; diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts index 0d3e6d6720a7fb..d9c84290f0d5d0 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts @@ -8,16 +8,13 @@ import { connect } from 'react-redux'; import { ToolbarOverlay } from './toolbar_overlay'; import { MapStoreState } from '../../reducers/store'; -import { getDrawMode, getFlyoutDisplay } from '../../selectors/ui_selectors'; -import { FLYOUT_STATE } from '../../reducers/ui'; +import { getDrawMode } from '../../selectors/ui_selectors'; import { getLayersBySourceType } from '../../selectors/map_selectors'; import { DRAW_MODE, SOURCE_TYPES } from '../../../common'; function mapStateToProps(state: MapStoreState) { return { showEditButton: !!getLayersBySourceType(SOURCE_TYPES.ES_SEARCH, state).length, - addDrawLayerInProgress: - getFlyoutDisplay(state) !== FLYOUT_STATE.NONE && state.map.mapState.editModeActive, shapeDrawModeActive: getDrawMode(state) === DRAW_MODE.DRAW_SHAPES, pointDrawModeActive: getDrawMode(state) === DRAW_MODE.DRAW_POINTS, }; diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx index 5fc407b8f385c2..1ac15efb3ceaac 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx @@ -21,7 +21,6 @@ export interface Props { geoFields: GeoFieldWithIndex[]; getFilterActions?: () => Promise; getActionContext?: () => ActionExecutionContext; - addDrawLayerInProgress: boolean; showEditButton: boolean; shapeDrawModeActive: boolean; pointDrawModeActive: boolean; diff --git a/x-pack/plugins/maps/public/reducers/map/map.ts b/x-pack/plugins/maps/public/reducers/map/map.ts index 600c25093bf859..00ddd2ca7ff2d1 100644 --- a/x-pack/plugins/maps/public/reducers/map/map.ts +++ b/x-pack/plugins/maps/public/reducers/map/map.ts @@ -47,7 +47,6 @@ import { TRACK_MAP_SETTINGS, UPDATE_MAP_SETTING, SET_SHAPE_TO_DRAW, - UPDATE_EDIT_MODE, ADD_FEATURES_TO_INDEX_QUEUE, SET_VECTOR_LAYER_INDEX_NAME, CLEAR_DRAWING_DATA, @@ -66,7 +65,6 @@ import { } from './layer_utils'; import { startDataRequest, stopDataRequest, updateSourceDataRequest } from './data_request_utils'; import { MapState } from './types'; -import { DRAW_TYPE } from '../../../common'; export const DEFAULT_MAP_STATE: MapState = { ready: false, @@ -87,7 +85,6 @@ export const DEFAULT_MAP_STATE: MapState = { vectorLayerIndexName: '', drawState: undefined, shapeToDraw: undefined, - editModeActive: false, featuresToIndexQueue: [], }, selectedLayerId: null, @@ -115,14 +112,6 @@ export function map(state: MapState = DEFAULT_MAP_STATE, action: any) { shapeToDraw: action.shapeToDraw, }, }; - case UPDATE_EDIT_MODE: - return { - ...state, - mapState: { - ...state.mapState, - editModeActive: action.isActive, - }, - }; case ADD_FEATURES_TO_INDEX_QUEUE: return { ...state, @@ -157,7 +146,6 @@ export function map(state: MapState = DEFAULT_MAP_STATE, action: any) { ...state.mapState, drawState: undefined, shapeToDraw: undefined, - editModeActive: false, featuresToIndexQueue: [], }, }; diff --git a/x-pack/plugins/maps/public/reducers/map/types.ts b/x-pack/plugins/maps/public/reducers/map/types.ts index c2fba10773ad50..d279bd517a9ec7 100644 --- a/x-pack/plugins/maps/public/reducers/map/types.ts +++ b/x-pack/plugins/maps/public/reducers/map/types.ts @@ -40,7 +40,6 @@ export type MapContext = { drawState?: DrawState; shapeToDraw?: DRAW_TYPE; featuresToIndexQueue: Feature[]; - editModeActive: boolean; searchSessionId?: string; searchSessionMapBuffer?: MapExtent; }; diff --git a/x-pack/plugins/maps/public/selectors/map_selectors.ts b/x-pack/plugins/maps/public/selectors/map_selectors.ts index cb6714a12e29b2..94ae297f3074e3 100644 --- a/x-pack/plugins/maps/public/selectors/map_selectors.ts +++ b/x-pack/plugins/maps/public/selectors/map_selectors.ts @@ -197,8 +197,6 @@ export const isUsingSearch = (state: MapStoreState): boolean => { export const getDrawState = ({ map }: MapStoreState): DrawState | undefined => map.mapState.drawState; -export const getEditModeActive = ({ map }: MapStoreState): boolean => map.mapState.editModeActive; - export const getShapeToDraw = ({ map }: MapStoreState): DRAW_TYPE | undefined => map.mapState.shapeToDraw; From 90c8d3d6f11bf312dbaed950922f19383ee7ff39 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Mon, 10 May 2021 15:52:34 -0600 Subject: [PATCH 040/103] Show index pattern id (for now) and geo field in tooltip. Fill in missing tooltip messages --- .../mb_map/draw_control/draw_control.tsx | 20 ++++--- .../mb_map/draw_control/draw_tooltip.tsx | 53 ++++++++++++------- .../mb_map/draw_control/index.ts | 11 +++- 3 files changed, 57 insertions(+), 27 deletions(-) diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx index 4cd2c5623d6e2a..449d9f59731fdf 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx @@ -44,6 +44,8 @@ export interface Props { mbMap: MbMap; drawActive: boolean; setShapeToDraw: (shapeToDraw: DRAW_TYPE) => void; + indexPatternId: string | undefined; + geoField: string | undefined; } export class DrawControl extends Component { @@ -135,19 +137,14 @@ export class DrawControl extends Component { this._mbDrawControl.changeMode(DRAW_RECTANGLE); } else if (drawMode !== DRAW_CIRCLE && this.props.drawType === DRAW_TYPE.DISTANCE) { this._mbDrawControl.changeMode(DRAW_CIRCLE); - } else if (drawMode !== DRAW_LINE && this.props.drawType === DRAW_TYPE.LINE) { - this._mbDrawControl.changeMode(DRAW_LINE); } else if (drawMode !== DRAW_POLYGON && this.props.drawType === DRAW_TYPE.POLYGON) { this._mbDrawControl.changeMode(DRAW_POLYGON); + } else if (drawMode !== DRAW_LINE && this.props.drawType === DRAW_TYPE.LINE) { + this._mbDrawControl.changeMode(DRAW_LINE); } else if (drawMode !== DRAW_POINT && this.props.drawType === DRAW_TYPE.POINT) { this._mbDrawControl.changeMode(DRAW_POINT); } else if (drawMode !== SIMPLE_SELECT && this.props.drawType === DRAW_TYPE.SIMPLE_SELECT) { this._mbDrawControl.changeMode(SIMPLE_SELECT); - } else if ( - drawMode !== this._mbDrawControl.modes.DRAW_POLYGON && - this.props.drawType === DRAW_TYPE.POLYGON - ) { - this._mbDrawControl.changeMode(this._mbDrawControl.modes.DRAW_POLYGON); } } @@ -156,6 +153,13 @@ export class DrawControl extends Component { return null; } - return ; + return ( + + ); } } diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_tooltip.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_tooltip.tsx index dc40fb34fea605..f4e7c6e60e103b 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_tooltip.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_tooltip.tsx @@ -17,6 +17,8 @@ const noop = () => {}; interface Props { mbMap: MbMap; drawType: DRAW_TYPE; + indexPatternId: string | undefined; + geoField: string | undefined; } interface State { @@ -54,6 +56,23 @@ export class DrawTooltip extends Component { this._updateTooltipLocation.cancel(); } + _hideTooltip = () => { + this._updateTooltipLocation.cancel(); + this.setState({ isOpen: false }); + }; + + _updateTooltipLocation = _.throttle(({ lngLat }) => { + const mouseLocation = this.props.mbMap.project(lngLat); + if (!this._isMounted) { + return; + } + this.setState({ + isOpen: true, + x: mouseLocation.x, + y: mouseLocation.y, + }); + }, 100); + render() { if (this.state.x === undefined || this.state.y === undefined) { return null; @@ -73,6 +92,14 @@ export class DrawTooltip extends Component { instructions = i18n.translate('xpack.maps.drawTooltip.polygonInstructions', { defaultMessage: 'Click to start shape. Click to add vertex. Double click to finish.', }); + } else if (this.props.drawType === DRAW_TYPE.LINE) { + instructions = i18n.translate('xpack.maps.drawTooltip.polygonInstructions', { + defaultMessage: 'Click to start line. Click to add vertex. Double click to finish.', + }); + } else if (this.props.drawType === DRAW_TYPE.POINT) { + instructions = i18n.translate('xpack.maps.drawTooltip.polygonInstructions', { + defaultMessage: 'Click to create point.', + }); } else { // unknown draw type, tooltip not needed return null; @@ -82,6 +109,13 @@ export class DrawTooltip extends Component {
); + const title = + this.props.indexPatternId && this.props.geoField ? ( + + {`${this.props.indexPatternId}: ${this.props.geoField}`} + + ) : undefined; + return ( { transform: `translate(${this.state.x - 13}px, ${this.state.y - 13}px)`, }} > - Hello, I’m a popover title + {title ? title : null} {instructions} ); } - - _hideTooltip = () => { - this._updateTooltipLocation.cancel(); - this.setState({ isOpen: false }); - }; - - _updateTooltipLocation = _.throttle(({ lngLat }) => { - const mouseLocation = this.props.mbMap.project(lngLat); - if (!this._isMounted) { - return; - } - this.setState({ - isOpen: true, - x: mouseLocation.x, - y: mouseLocation.y, - }); - }, 100); } diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/index.ts b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/index.ts index e0686a0202f94e..da029774e5d481 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/index.ts @@ -12,6 +12,15 @@ import { setShapeToDraw } from '../../../actions'; import { MapStoreState } from '../../../reducers/store'; import { DrawControl } from './draw_control'; import { DRAW_TYPE } from '../../../../common'; +import { getDrawState } from '../../../selectors/map_selectors'; + +function mapStateToProps(state: MapStoreState) { + const drawState = getDrawState(state); + return { + indexPatternId: drawState ? drawState.indexPatternId : undefined, + geoField: drawState ? drawState.geoFieldName : undefined, + }; +} function mapDispatchToProps(dispatch: ThunkDispatch) { return { @@ -21,5 +30,5 @@ function mapDispatchToProps(dispatch: ThunkDispatch Date: Tue, 11 May 2021 09:25:07 -0600 Subject: [PATCH 041/103] Add pieces for feature persistence w/ placeholder content --- x-pack/plugins/maps/common/constants.ts | 1 + .../public/actions/map_action_constants.ts | 1 - .../maps/public/actions/map_actions.ts | 16 ++-- .../utils/http_service.ts | 63 ---------------- .../utils/indexing_service.ts | 73 ------------------- .../draw_feature_control.tsx | 11 ++- .../draw_feature_control/index.ts | 7 +- .../plugins/maps/public/reducers/map/map.ts | 9 --- x-pack/plugins/maps/public/util.ts | 30 +++++++- 9 files changed, 48 insertions(+), 163 deletions(-) delete mode 100644 x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/utils/http_service.ts delete mode 100644 x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/utils/indexing_service.ts diff --git a/x-pack/plugins/maps/common/constants.ts b/x-pack/plugins/maps/common/constants.ts index 8e4632b2812ef6..516eedb2669e5c 100644 --- a/x-pack/plugins/maps/common/constants.ts +++ b/x-pack/plugins/maps/common/constants.ts @@ -42,6 +42,7 @@ export const INDEX_SETTINGS_API_PATH = `${GIS_API_PATH}/indexSettings`; export const FONTS_API_PATH = `${GIS_API_PATH}/fonts`; export const INDEX_SOURCE_API_PATH = `${GIS_API_PATH}/docSource`; export const API_ROOT_PATH = `/${GIS_API_PATH}`; +export const INDEX_FEATURE_PATH = `/${GIS_API_PATH}/feature`; export const MVT_GETTILE_API_PATH = 'mvt/getTile'; export const MVT_GETGRIDTILE_API_PATH = 'mvt/getGridTile'; diff --git a/x-pack/plugins/maps/public/actions/map_action_constants.ts b/x-pack/plugins/maps/public/actions/map_action_constants.ts index 144ddb204ccd4c..900a64ff65f6af 100644 --- a/x-pack/plugins/maps/public/actions/map_action_constants.ts +++ b/x-pack/plugins/maps/public/actions/map_action_constants.ts @@ -46,7 +46,6 @@ export const SET_MAP_SETTINGS = 'SET_MAP_SETTINGS'; export const ROLLBACK_MAP_SETTINGS = 'ROLLBACK_MAP_SETTINGS'; export const TRACK_MAP_SETTINGS = 'TRACK_MAP_SETTINGS'; export const UPDATE_MAP_SETTING = 'UPDATE_MAP_SETTING'; -export const ADD_FEATURES_TO_INDEX_QUEUE = 'ADD_FEATURES_TO_INDEX_QUEUE'; export const REMOVE_FEATURES_FROM_INDEX_QUEUE = 'REMOVE_FEATURES_FROM_INDEX_QUEUE'; export const SET_VECTOR_LAYER_INDEX_NAME = 'SET_VECTOR_LAYER_INDEX_NAME'; export const CLEAR_DRAWING_DATA = 'CLEAR_DRAWING_DATA'; diff --git a/x-pack/plugins/maps/public/actions/map_actions.ts b/x-pack/plugins/maps/public/actions/map_actions.ts index 55a849005d5497..563cc9f8e1cf2a 100644 --- a/x-pack/plugins/maps/public/actions/map_actions.ts +++ b/x-pack/plugins/maps/public/actions/map_actions.ts @@ -6,7 +6,6 @@ */ import _ from 'lodash'; -import { Feature } from 'geojson'; import { AnyAction, Dispatch } from 'redux'; import { ThunkDispatch } from 'redux-thunk'; import turfBboxPolygon from '@turf/bbox-polygon'; @@ -46,7 +45,6 @@ import { UPDATE_DRAW_STATE, SET_SHAPE_TO_DRAW, UPDATE_MAP_SETTING, - ADD_FEATURES_TO_INDEX_QUEUE, SET_VECTOR_LAYER_INDEX_NAME, REMOVE_FEATURES_FROM_INDEX_QUEUE, } from './map_action_constants'; @@ -63,6 +61,7 @@ import { import { INITIAL_LOCATION } from '../../common/constants'; import { scaleBounds } from '../../common/elasticsearch_util'; import { cleanTooltipStateForLayer } from './tooltip_actions'; +import { addFeatureToIndex } from '../util'; export interface MapExtentState { zoom: number; @@ -338,13 +337,6 @@ export function updateDrawState(drawState: DrawState | null) { }; } -export function addFeaturesToIndexQueue(features: Feature[]) { - return { - type: ADD_FEATURES_TO_INDEX_QUEUE, - features, - }; -} - export function removeFeaturesFromIndexQueue(featureIds: string[]) { return { type: REMOVE_FEATURES_FROM_INDEX_QUEUE, @@ -358,3 +350,9 @@ export function setVectorLayerIndexName(indexName: string) { indexName, }; } + +export function addNewFeatureToIndex(indexName: string, geometry: unknown, path: string) { + return async () => { + await addFeatureToIndex(indexName, geometry, path); + }; +} diff --git a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/utils/http_service.ts b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/utils/http_service.ts deleted file mode 100644 index 5db916acc951b3..00000000000000 --- a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/utils/http_service.ts +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; -import { HttpFetchOptions } from 'kibana/public'; -import { getHttp } from '../../../../kibana_services'; - -export interface HttpOptions { - url: string; - method: string; - headers?: { - [key: string]: any; - }; - data?: unknown; - query?: any; -} - -export async function http(options: HttpOptions) { - if (!(options && options.url)) { - throw i18n.translate('xpack.maps.layers.newVectorLayerWizard.httpService.noUrl', { - defaultMessage: 'No URL provided', - }); - } - const url: string = options.url || ''; - const headers = { - 'Content-Type': 'application/json', - ...options.headers, - }; - - const allHeaders = options.headers === undefined ? headers : { ...options.headers, ...headers }; - const body = options.data === undefined ? null : JSON.stringify(options.data); - - const payload: HttpFetchOptions = { - method: options.method || 'GET', - headers: allHeaders, - credentials: 'same-origin', - query: options.query, - }; - - if (body !== null) { - payload.body = body; - } - return await doFetch(url, payload); -} - -async function doFetch(url: string, payload: HttpFetchOptions) { - try { - return await getHttp().fetch(url, payload); - } catch (err) { - return { - failures: [ - i18n.translate('xpack.maps.layers.newVectorLayerWizard.httpService.fetchError', { - defaultMessage: 'Error performing fetch: {error}', - values: { error: err.message }, - }), - ], - }; - } -} diff --git a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/utils/indexing_service.ts b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/utils/indexing_service.ts deleted file mode 100644 index 2720524894a730..00000000000000 --- a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/utils/indexing_service.ts +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { http as httpService } from './http_service'; -import { getSavedObjectsClient } from '../../../../kibana_services'; -import { INDEX_FEATURE_PATH, INDEX_SOURCE_API_PATH } from '../../../../../common'; - -export const getExistingIndexNames = async () => { - const indexes = await httpService({ - url: `/api/index_management/indices`, - method: 'GET', - }); - return indexes ? indexes.map(({ name }: { name: string }) => name) : []; -}; - -export const createNewIndexAndPattern = async (indexName: string) => { - return await httpService({ - url: `/${INDEX_SOURCE_API_PATH}`, - method: 'POST', - data: { - index: indexName, - // Initially set to static mappings - mappings: { - properties: { - coordinates: { - type: 'geo_shape', - }, - }, - }, - }, - }); -}; - -export const addFeatureToIndex = async (indexName: string, geometry: unknown) => { - return await httpService({ - url: `/${INDEX_FEATURE_PATH}`, - method: 'POST', - data: { - index: indexName, - data: { - coordinates: geometry, - }, - }, - }); -}; - -export const getExistingIndexPatternNames = async () => { - const indexPatterns = await getSavedObjectsClient() - .find({ - type: 'index-pattern', - fields: ['id', 'title', 'type', 'fields'], - perPage: 10000, - }) - .then(({ savedObjects }) => savedObjects.map((savedObject) => savedObject.get('title'))); - return indexPatterns ? indexPatterns.map(({ name }) => name) : []; -}; - -export function checkIndexPatternValid(name: string) { - const byteLength = encodeURI(name).split(/%(?:u[0-9A-F]{2})?[0-9A-F]{2}|./).length - 1; - const reg = new RegExp('[\\\\/*?"<>|\\s,#]+'); - const indexPatternInvalid = - byteLength > 255 || // name can't be greater than 255 bytes - name !== name.toLowerCase() || // name should be lowercase - name === '.' || - name === '..' || // name can't be . or .. - name.match(/^[-_+]/) !== null || // name can't start with these chars - name.match(reg) !== null; // name can't contain these chars - return !indexPatternInvalid; -} diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx index 84500e0e1e8148..b76bfe80db0cbd 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx @@ -20,8 +20,8 @@ import { DRAW_TYPE } from '../../../../../common'; const geoJSONReader = new jsts.io.GeoJSONReader(); export interface Props { + addNewFeature: (indexName: string, geometry: unknown, mappings: unknown) => void; disableDrawState: () => void; - addFeaturesToIndexQueue: (features: Feature[]) => void; removeFeatures: (featureIds: string[]) => void; drawType: DRAW_TYPE; mbMap: MbMap; @@ -30,7 +30,12 @@ export interface Props { export class DrawFeatureControl extends Component { _onFeaturesSelected = (mbDrawControl: MapboxDraw) => (e: { features: Feature[] }) => { if (this.props.drawType === DRAW_TYPE.TRASH) { - this.props.removeFeatures(e.features.map(({ id }: { id: string }) => id)); + const featureIds = e.features + .map((feature: Feature) => { + return feature.id ? `${feature.id}` : ''; + }) + .filter((id) => id); + this.props.removeFeatures(featureIds); mbDrawControl.trash(); } }; @@ -43,8 +48,8 @@ export class DrawFeatureControl extends Component { mbDrawControl.delete(feature.id); throw new Error('Invalid geometry detected'); } + this.props.addNewFeature('someIndex', geometry, 'somePath'); }); - this.props.addFeaturesToIndexQueue(e.features); } catch (error) { getToasts().addWarning( i18n.translate('xpack.maps.drawFeatureControl.unableToCreateFeature', { diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts index 64467a0fe27c97..c342b5d08b07bc 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts @@ -8,10 +8,9 @@ import { AnyAction } from 'redux'; import { ThunkDispatch } from 'redux-thunk'; import { connect } from 'react-redux'; -import { Feature } from 'geojson'; import { DrawFeatureControl } from './draw_feature_control'; import { - addFeaturesToIndexQueue, + addNewFeatureToIndex, removeFeaturesFromIndexQueue, setShapeToDraw, } from '../../../../actions'; @@ -26,8 +25,8 @@ function mapStateToProps(state: MapStoreState) { function mapDispatchToProps(dispatch: ThunkDispatch) { return { - addFeaturesToIndexQueue(features: Feature[]) { - dispatch(addFeaturesToIndexQueue(features)); + addNewFeatureToIndex(indexName: string, geometry: unknown, path: string) { + dispatch(addNewFeatureToIndex(indexName, geometry, path)); }, disableDrawState() { dispatch(setShapeToDraw(null)); diff --git a/x-pack/plugins/maps/public/reducers/map/map.ts b/x-pack/plugins/maps/public/reducers/map/map.ts index 00ddd2ca7ff2d1..20b40a1ad7f529 100644 --- a/x-pack/plugins/maps/public/reducers/map/map.ts +++ b/x-pack/plugins/maps/public/reducers/map/map.ts @@ -47,7 +47,6 @@ import { TRACK_MAP_SETTINGS, UPDATE_MAP_SETTING, SET_SHAPE_TO_DRAW, - ADD_FEATURES_TO_INDEX_QUEUE, SET_VECTOR_LAYER_INDEX_NAME, CLEAR_DRAWING_DATA, REMOVE_FEATURES_FROM_INDEX_QUEUE, @@ -112,14 +111,6 @@ export function map(state: MapState = DEFAULT_MAP_STATE, action: any) { shapeToDraw: action.shapeToDraw, }, }; - case ADD_FEATURES_TO_INDEX_QUEUE: - return { - ...state, - mapState: { - ...state.mapState, - featuresToIndexQueue: [...state.mapState.featuresToIndexQueue, ...action.features], - }, - }; case REMOVE_FEATURES_FROM_INDEX_QUEUE: const newFeatureArr = state.mapState.featuresToIndexQueue.filter( ({ id }: { id: string }) => !action.featureIds.includes(id) diff --git a/x-pack/plugins/maps/public/util.ts b/x-pack/plugins/maps/public/util.ts index 7cae3d4d5e9361..c49a9ffffb398b 100644 --- a/x-pack/plugins/maps/public/util.ts +++ b/x-pack/plugins/maps/public/util.ts @@ -11,8 +11,9 @@ import { FeatureCollection } from 'geojson'; import * as topojson from 'topojson-client'; import { GeometryCollection } from 'topojson-specification'; import _ from 'lodash'; - import fetch from 'node-fetch'; +import { INDEX_FEATURE_PATH } from '../common'; + import { GIS_API_PATH, EMS_FILES_CATALOGUE_PATH, @@ -156,3 +157,30 @@ export async function fetchGeoJson( }) ); } + +export const addFeatureToIndex = async (indexName: string, geometry: unknown, path: string) => { + const data = convertDotNotationStringToObj(path, geometry); + return await getHttp().fetch({ + path: `/${INDEX_FEATURE_PATH}`, + method: 'POST', + body: convertObjectToBlob({ + index: indexName, + data, + }), + }); +}; + +const convertDotNotationStringToObj = ( + dotNotationStr: string, + value: unknown +): Record => { + const container: Record = {}; + dotNotationStr.split('.').map((k, i, values) => { + container[k] = i === values.length - 1 ? value : {}; + }); + return container; +}; + +const convertObjectToBlob = (obj: unknown) => { + return new Blob([JSON.stringify(obj)], { type: 'application/json' }); +}; From 6508d71940ba917b165ec3a52a3320f48c3d8568 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Tue, 11 May 2021 09:53:50 -0600 Subject: [PATCH 042/103] Writing to index connected --- .../common/descriptor_types/map_descriptor.ts | 1 + .../index_geometry_select_popover_form.js | 1 + .../draw_feature_control.tsx | 28 +++++++++++++++++-- .../draw_feature_control/index.ts | 3 +- .../tools_control/tools_control.tsx | 1 + x-pack/plugins/maps/public/util.ts | 2 +- 6 files changed, 31 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/maps/common/descriptor_types/map_descriptor.ts b/x-pack/plugins/maps/common/descriptor_types/map_descriptor.ts index 4accdf01dd5408..92e81589617481 100644 --- a/x-pack/plugins/maps/common/descriptor_types/map_descriptor.ts +++ b/x-pack/plugins/maps/common/descriptor_types/map_descriptor.ts @@ -62,5 +62,6 @@ export type DrawState = { geoFieldType?: ES_GEO_FIELD_TYPE; geometryLabel?: string; indexPatternId?: string; + indexPatternTitle?: string; relation?: ES_SPATIAL_RELATIONS; }; diff --git a/x-pack/plugins/maps/public/components/draw_forms/index_geometry_select_popover_form.js b/x-pack/plugins/maps/public/components/draw_forms/index_geometry_select_popover_form.js index 0e6a403f8f02f4..780f690f548d85 100644 --- a/x-pack/plugins/maps/public/components/draw_forms/index_geometry_select_popover_form.js +++ b/x-pack/plugins/maps/public/components/draw_forms/index_geometry_select_popover_form.js @@ -30,6 +30,7 @@ export class IndexGeometrySelectPopoverForm extends Component { indexPatternId: this.state.selectedField.indexPatternId, geoFieldName: this.state.selectedField.geoFieldName, geoFieldType: this.state.selectedField.geoFieldType, + indexPatternTitle: this.state.selectedField.indexPatternTitle, }); }; diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx index b76bfe80db0cbd..54c819099c5645 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx @@ -16,14 +16,16 @@ import * as jsts from 'jsts'; import { getToasts } from '../../../../kibana_services'; import { DrawControl } from '../'; import { DRAW_TYPE } from '../../../../../common'; +import { DrawState } from '../../../../../common/descriptor_types'; const geoJSONReader = new jsts.io.GeoJSONReader(); export interface Props { - addNewFeature: (indexName: string, geometry: unknown, mappings: unknown) => void; + addNewFeatureToIndex: (indexName: string, geometry: unknown, path: string) => void; disableDrawState: () => void; removeFeatures: (featureIds: string[]) => void; drawType: DRAW_TYPE; + drawState: DrawState; mbMap: MbMap; } @@ -46,9 +48,29 @@ export class DrawFeatureControl extends Component { const { geometry } = geoJSONReader.read(feature); if (!geometry.isSimple() || !geometry.isValid()) { mbDrawControl.delete(feature.id); - throw new Error('Invalid geometry detected'); + throw new Error( + i18n.translate('xpack.maps.drawFeatureControl.invalidGeometry', { + defaultMessage: `Invalid geometry detected`, + }) + ); } - this.props.addNewFeature('someIndex', geometry, 'somePath'); + const geoField = this.props.drawState.geoFieldName; + const indexPattern = this.props.drawState.indexPatternTitle; + if (!geoField) { + throw new Error( + i18n.translate('xpack.maps.drawFeatureControl.missingGeofield', { + defaultMessage: `No geo field designated for feature update`, + }) + ); + } + if (!indexPattern) { + throw new Error( + i18n.translate('xpack.maps.drawFeatureControl.missingIndexPattern', { + defaultMessage: `No index pattern designated for feature update`, + }) + ); + } + this.props.addNewFeatureToIndex(indexPattern, feature.geometry, geoField); }); } catch (error) { getToasts().addWarning( diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts index c342b5d08b07bc..bbdb9119d6a8a9 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts @@ -15,11 +15,12 @@ import { setShapeToDraw, } from '../../../../actions'; import { MapStoreState } from '../../../../reducers/store'; -import { getShapeToDraw } from '../../../../selectors/map_selectors'; +import { getDrawState, getShapeToDraw } from '../../../../selectors/map_selectors'; function mapStateToProps(state: MapStoreState) { return { drawType: getShapeToDraw(state), + drawState: getDrawState(state), }; } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx index 6bee926aa206d0..fc5b83014f6729 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx @@ -146,6 +146,7 @@ export class ToolsControl extends Component { actionId: string; filterLabel: string; indexPatternId: string; + indexPatternTitle: string; geoFieldName: string; geoFieldType?: ES_GEO_FIELD_TYPE; }) => { diff --git a/x-pack/plugins/maps/public/util.ts b/x-pack/plugins/maps/public/util.ts index c49a9ffffb398b..a2dfbac2cd4fd8 100644 --- a/x-pack/plugins/maps/public/util.ts +++ b/x-pack/plugins/maps/public/util.ts @@ -161,7 +161,7 @@ export async function fetchGeoJson( export const addFeatureToIndex = async (indexName: string, geometry: unknown, path: string) => { const data = convertDotNotationStringToObj(path, geometry); return await getHttp().fetch({ - path: `/${INDEX_FEATURE_PATH}`, + path: `${INDEX_FEATURE_PATH}`, method: 'POST', body: convertObjectToBlob({ index: indexName, From aea42da050f922faa7af776ba0400bd7056a44f1 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Tue, 11 May 2021 10:26:08 -0600 Subject: [PATCH 043/103] Delete shapes when done. Add sync layers call --- x-pack/plugins/maps/public/actions/map_actions.ts | 3 ++- .../draw_control/draw_feature_control/draw_feature_control.tsx | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/maps/public/actions/map_actions.ts b/x-pack/plugins/maps/public/actions/map_actions.ts index 563cc9f8e1cf2a..c3ebc299708433 100644 --- a/x-pack/plugins/maps/public/actions/map_actions.ts +++ b/x-pack/plugins/maps/public/actions/map_actions.ts @@ -352,7 +352,8 @@ export function setVectorLayerIndexName(indexName: string) { } export function addNewFeatureToIndex(indexName: string, geometry: unknown, path: string) { - return async () => { + return async (dispatch: ThunkDispatch) => { await addFeatureToIndex(indexName, geometry, path); + await dispatch(syncDataForAllLayers()); }; } diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx index 54c819099c5645..bbb30e9d890bca 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx @@ -83,6 +83,7 @@ export class DrawFeatureControl extends Component { ); } finally { this.props.disableDrawState(); + mbDrawControl.deleteAll(); } }; From c7acf679065cf31103c3e6290e8dce608ce0ffea Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Tue, 11 May 2021 16:43:34 -0600 Subject: [PATCH 044/103] Fix issue with point geometries. Add force refresh flag so features are re-feteched on add --- .../maps/public/actions/data_request_actions.ts | 10 ++++++---- .../plugins/maps/public/actions/map_actions.ts | 2 +- .../public/classes/layers/vector_layer/utils.tsx | 16 ++++++++++------ .../classes/layers/vector_layer/vector_layer.tsx | 12 +++++++++--- .../draw_feature_control.tsx | 9 +++++++-- .../draw_control/draw_feature_control/index.ts | 2 ++ 6 files changed, 35 insertions(+), 16 deletions(-) diff --git a/x-pack/plugins/maps/public/actions/data_request_actions.ts b/x-pack/plugins/maps/public/actions/data_request_actions.ts index 6b57da132e895e..9e5226eb69deb9 100644 --- a/x-pack/plugins/maps/public/actions/data_request_actions.ts +++ b/x-pack/plugins/maps/public/actions/data_request_actions.ts @@ -138,13 +138,15 @@ function getDataRequestContext( }; } -export function syncDataForAllLayers() { +export function syncDataForAllLayers( + { forceRefresh }: { forceRefresh: boolean } = { forceRefresh: false } +) { return async ( dispatch: ThunkDispatch, getState: () => MapStoreState ) => { const syncPromises = getLayerList(getState()).map((layer) => { - return dispatch(syncDataForLayer(layer)); + return dispatch(syncDataForLayer(layer, forceRefresh)); }); await Promise.all(syncPromises); }; @@ -166,13 +168,13 @@ function syncDataForAllJoinLayers() { }; } -export function syncDataForLayer(layer: ILayer) { +export function syncDataForLayer(layer: ILayer, forceRefresh: boolean) { return async (dispatch: Dispatch, getState: () => MapStoreState) => { const dataRequestContext = getDataRequestContext(dispatch, getState, layer.getId()); if (!layer.isVisible() || !layer.showAtZoomLevel(dataRequestContext.dataFilters.zoom)) { return; } - await layer.syncData(dataRequestContext); + await layer.syncData(dataRequestContext, forceRefresh); }; } diff --git a/x-pack/plugins/maps/public/actions/map_actions.ts b/x-pack/plugins/maps/public/actions/map_actions.ts index c3ebc299708433..744491a67ef127 100644 --- a/x-pack/plugins/maps/public/actions/map_actions.ts +++ b/x-pack/plugins/maps/public/actions/map_actions.ts @@ -354,6 +354,6 @@ export function setVectorLayerIndexName(indexName: string) { export function addNewFeatureToIndex(indexName: string, geometry: unknown, path: string) { return async (dispatch: ThunkDispatch) => { await addFeatureToIndex(indexName, geometry, path); - await dispatch(syncDataForAllLayers()); + await dispatch(syncDataForAllLayers({ forceRefresh: true })); }; } diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/utils.tsx b/x-pack/plugins/maps/public/classes/layers/vector_layer/utils.tsx index e49339b6250b48..5cc0a67fb4b4d9 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/utils.tsx +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/utils.tsx @@ -52,6 +52,7 @@ export async function syncVectorSource({ requestMeta, syncContext, source, + forceRefresh, }: { layerId: string; layerName: string; @@ -59,6 +60,7 @@ export async function syncVectorSource({ requestMeta: VectorSourceRequestMeta; syncContext: DataRequestContext; source: IVectorSource; + forceRefresh: boolean; }): Promise<{ refreshed: boolean; featureCollection: FeatureCollection }> { const { startLoading, @@ -69,12 +71,14 @@ export async function syncVectorSource({ } = syncContext; const dataRequestId = SOURCE_DATA_REQUEST_ID; const requestToken = Symbol(`${layerId}-${dataRequestId}`); - const canSkipFetch = await canSkipSourceUpdate({ - source, - prevDataRequest, - nextMeta: requestMeta, - extentAware: source.isFilterByMapBounds(), - }); + const canSkipFetch = !forceRefresh + ? await canSkipSourceUpdate({ + source, + prevDataRequest, + nextMeta: requestMeta, + extentAware: source.isFilterByMapBounds(), + }) + : !forceRefresh; if (canSkipFetch) { return { refreshed: false, diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx index 104d0b56578d12..9d733d8714b016 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx @@ -634,8 +634,8 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { } } - async syncData(syncContext: DataRequestContext) { - await this._syncData(syncContext, this.getSource(), this.getCurrentStyle()); + async syncData(syncContext: DataRequestContext, forceRefresh: boolean) { + await this._syncData(syncContext, this.getSource(), this.getCurrentStyle(), forceRefresh); } // TLDR: Do not call getSource or getCurrentStyle in syncData flow. Use 'source' and 'style' arguments instead. @@ -648,7 +648,12 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { // Given 1 above, which source/style to use can not be stored in Layer instance state. // Given 2 above, which source/style to use can not be pulled from data request state. // Therefore, source and style are provided as arugments and must be used instead of calling getSource or getCurrentStyle. - async _syncData(syncContext: DataRequestContext, source: IVectorSource, style: IVectorStyle) { + async _syncData( + syncContext: DataRequestContext, + source: IVectorSource, + style: IVectorStyle, + forceRefresh: boolean + ) { if (this.isLoadingBounds()) { return; } @@ -663,6 +668,7 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { requestMeta: this._getSearchFilters(syncContext.dataFilters, source, style), syncContext, source, + forceRefresh, }); if ( !sourceResult.featureCollection || diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx index bbb30e9d890bca..3379b08a22d490 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx @@ -15,7 +15,7 @@ import { i18n } from '@kbn/i18n'; import * as jsts from 'jsts'; import { getToasts } from '../../../../kibana_services'; import { DrawControl } from '../'; -import { DRAW_TYPE } from '../../../../../common'; +import { DRAW_MODE, DRAW_TYPE } from '../../../../../common'; import { DrawState } from '../../../../../common/descriptor_types'; const geoJSONReader = new jsts.io.GeoJSONReader(); @@ -26,6 +26,7 @@ export interface Props { removeFeatures: (featureIds: string[]) => void; drawType: DRAW_TYPE; drawState: DrawState; + drawMode: DRAW_MODE; mbMap: MbMap; } @@ -70,7 +71,11 @@ export class DrawFeatureControl extends Component { }) ); } - this.props.addNewFeatureToIndex(indexPattern, feature.geometry, geoField); + const featureGeom = + this.props.drawMode === DRAW_MODE.DRAW_POINTS + ? feature.geometry.coordinates + : feature.geometry; + this.props.addNewFeatureToIndex(indexPattern, featureGeom, geoField); }); } catch (error) { getToasts().addWarning( diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts index bbdb9119d6a8a9..108eb6586bf528 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts @@ -16,11 +16,13 @@ import { } from '../../../../actions'; import { MapStoreState } from '../../../../reducers/store'; import { getDrawState, getShapeToDraw } from '../../../../selectors/map_selectors'; +import { getDrawMode } from '../../../../selectors/ui_selectors'; function mapStateToProps(state: MapStoreState) { return { drawType: getShapeToDraw(state), drawState: getDrawState(state), + drawMode: getDrawMode(state), }; } From d89c810b31f5ae6cb2643426bc887d5fd9146f82 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 12 May 2021 09:02:27 -0600 Subject: [PATCH 045/103] Check draw tool exists before delete --- .../draw_feature_control/draw_feature_control.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx index 3379b08a22d490..79e4adf3450ec3 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx @@ -88,7 +88,9 @@ export class DrawFeatureControl extends Component { ); } finally { this.props.disableDrawState(); - mbDrawControl.deleteAll(); + if (mbDrawControl) { + mbDrawControl.deleteAll(); + } } }; From 849ba8eb885302ab3a6f39d6c0a68231c9680caa Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 12 May 2021 09:03:06 -0600 Subject: [PATCH 046/103] Add refresh to index call to prevent shapes from not getting drawn after created --- x-pack/plugins/maps/server/data_indexing/index_data.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/maps/server/data_indexing/index_data.ts b/x-pack/plugins/maps/server/data_indexing/index_data.ts index b87cd53a3dfd21..9a05b81d4269d0 100644 --- a/x-pack/plugins/maps/server/data_indexing/index_data.ts +++ b/x-pack/plugins/maps/server/data_indexing/index_data.ts @@ -26,7 +26,7 @@ export async function writeDataToIndex( }) ); } - const settings: WriteSettings = { index, body: data }; + const settings: WriteSettings = { index, body: data, refresh: true }; const { body: resp } = await asCurrentUser.index(settings); if (resp.result === 'Error') { throw resp; From ad72af1af07ad4bb854459fb36cc9bc11e64e492 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 12 May 2021 09:55:16 -0600 Subject: [PATCH 047/103] Remove unused feature edit controls. Fix typing on geometry --- .../maps/public/actions/map_actions.ts | 7 +- .../draw_feature_control.tsx | 15 ++-- .../draw_feature_control/index.ts | 3 +- .../feature_edit_control.tsx | 75 ------------------- .../feature_edit_control/index.ts | 40 ---------- .../toolbar_overlay/toolbar_overlay.tsx | 8 +- x-pack/plugins/maps/public/util.ts | 8 +- 7 files changed, 25 insertions(+), 131 deletions(-) delete mode 100644 x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/feature_edit_control.tsx delete mode 100644 x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/index.ts diff --git a/x-pack/plugins/maps/public/actions/map_actions.ts b/x-pack/plugins/maps/public/actions/map_actions.ts index 744491a67ef127..5718f09b4f77f4 100644 --- a/x-pack/plugins/maps/public/actions/map_actions.ts +++ b/x-pack/plugins/maps/public/actions/map_actions.ts @@ -11,6 +11,7 @@ import { ThunkDispatch } from 'redux-thunk'; import turfBboxPolygon from '@turf/bbox-polygon'; import turfBooleanContains from '@turf/boolean-contains'; import { Filter, Query, TimeRange } from 'src/plugins/data/public'; +import { Geometry, Position } from 'geojson'; import { DRAW_TYPE } from '../../common/constants'; import { MapStoreState } from '../reducers/store'; import { @@ -351,7 +352,11 @@ export function setVectorLayerIndexName(indexName: string) { }; } -export function addNewFeatureToIndex(indexName: string, geometry: unknown, path: string) { +export function addNewFeatureToIndex( + indexName: string, + geometry: Geometry | Position[], + path: string +) { return async (dispatch: ThunkDispatch) => { await addFeatureToIndex(indexName, geometry, path); await dispatch(syncDataForAllLayers({ forceRefresh: true })); diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx index 79e4adf3450ec3..d1865b33649f3f 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx @@ -9,7 +9,7 @@ import React, { Component } from 'react'; import { Map as MbMap } from 'mapbox-gl'; // @ts-expect-error import MapboxDraw from '@mapbox/mapbox-gl-draw'; -import { Feature } from 'geojson'; +import { Feature, Geometry, Position } from 'geojson'; import { i18n } from '@kbn/i18n'; // @ts-expect-error import * as jsts from 'jsts'; @@ -71,11 +71,14 @@ export class DrawFeatureControl extends Component { }) ); } - const featureGeom = - this.props.drawMode === DRAW_MODE.DRAW_POINTS - ? feature.geometry.coordinates - : feature.geometry; - this.props.addNewFeatureToIndex(indexPattern, featureGeom, geoField); + if ('coordinates' in feature.geometry) { + // @ts-ignore /* Single position array only used if point geometry */ + const featureGeom: Geometry | Position[] = + this.props.drawMode === DRAW_MODE.DRAW_POINTS + ? feature.geometry.coordinates + : feature.geometry; + this.props.addNewFeatureToIndex(indexPattern, featureGeom, geoField); + } }); } catch (error) { getToasts().addWarning( diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts index 108eb6586bf528..eace53dbef2684 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts @@ -8,6 +8,7 @@ import { AnyAction } from 'redux'; import { ThunkDispatch } from 'redux-thunk'; import { connect } from 'react-redux'; +import { Geometry, Position } from 'geojson'; import { DrawFeatureControl } from './draw_feature_control'; import { addNewFeatureToIndex, @@ -28,7 +29,7 @@ function mapStateToProps(state: MapStoreState) { function mapDispatchToProps(dispatch: ThunkDispatch) { return { - addNewFeatureToIndex(indexName: string, geometry: unknown, path: string) { + addNewFeatureToIndex(indexName: string, geometry: Geometry | Position[], path: string) { dispatch(addNewFeatureToIndex(indexName, geometry, path)); }, disableDrawState() { diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/feature_edit_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/feature_edit_control.tsx deleted file mode 100644 index 9eb1977dc312a5..00000000000000 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/feature_edit_control.tsx +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import { DRAW_TYPE } from '../../../../../common/constants'; -// @ts-expect-error -import { GeometryFilterForm } from '../../../../components/draw_forms/geometry_filter_form/geometry_filter_form'; - -export interface Props { - filterModeActive: boolean; - drawType: string; - cancelDraw: () => void; - initiateDraw: (shapeToDraw: DRAW_TYPE) => void; -} - -export function FeatureEditControl(props: Props) { - const editFeaturesSelected = props.drawType === DRAW_TYPE.SIMPLE_SELECT; - const deleteFeaturesSelected = props.drawType === DRAW_TYPE.TRASH; - - return ( - - - - - props.initiateDraw(DRAW_TYPE.SIMPLE_SELECT)} - iconType="documentEdit" - aria-label={i18n.translate( - 'xpack.maps.toolbarOverlay.featureEdit.editFeaturesLabel', - { - defaultMessage: 'Edit features', - } - )} - title={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.editFeaturesTitle', { - defaultMessage: 'Edit features', - })} - aria-pressed={editFeaturesSelected} - isSelected={editFeaturesSelected} - /> - - - - - props.initiateDraw(DRAW_TYPE.TRASH)} - iconType="trash" - aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.deleteLabel', { - defaultMessage: 'Remove feature', - })} - title={i18n.translate('xpack.maps.toolbarOverlay.featureEdit.deleteTitle', { - defaultMessage: 'Remove feature', - })} - aria-pressed={deleteFeaturesSelected} - isSelected={deleteFeaturesSelected} - /> - - - - - ); -} diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/index.ts deleted file mode 100644 index 4b09b70a012cef..00000000000000 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_control/index.ts +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { AnyAction } from 'redux'; -import { ThunkDispatch } from 'redux-thunk'; -import { connect } from 'react-redux'; -import { FeatureEditControl } from './feature_edit_control'; -import { setShapeToDraw } from '../../../../actions'; -import { MapStoreState } from '../../../../reducers/store'; -import { DRAW_MODE, DRAW_TYPE } from '../../../../../common'; -import { getDrawMode } from '../../../../selectors/ui_selectors'; -import { getShapeToDraw } from '../../../../selectors/map_selectors'; - -function mapStateToProps(state: MapStoreState) { - return { - filterModeActive: getDrawMode(state) === DRAW_MODE.DRAW_FILTERS, - drawType: getShapeToDraw(state), - }; -} - -function mapDispatchToProps(dispatch: ThunkDispatch) { - return { - initiateDraw: (shapeToDraw: DRAW_TYPE) => { - dispatch(setShapeToDraw(shapeToDraw)); - }, - cancelDraw: () => { - dispatch(setShapeToDraw(null)); - }, - }; -} - -const connectedFeatureEditControl = connect( - mapStateToProps, - mapDispatchToProps -)(FeatureEditControl); -export { connectedFeatureEditControl as FeatureEditControl }; diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx index 1ac15efb3ceaac..0d0eec151b6b2c 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx @@ -12,7 +12,6 @@ import { ActionExecutionContext, Action } from 'src/plugins/ui_actions/public'; import { SetViewControl } from './set_view_control'; import { ToolsControl } from './tools_control'; import { FeatureDrawControl } from './feature_draw_controls/feature_draw_control'; -import { FeatureEditControl } from './feature_draw_controls/feature_edit_control'; import { FitToData } from './fit_to_data'; import { GeoFieldWithIndex } from '../../components/geo_field_with_index'; @@ -44,15 +43,12 @@ export function ToolbarOverlay(props: Props) { ); } - function renderFeatureDrawAndEditControls() { + function renderFeatureDrawControl() { return props.shapeDrawModeActive || props.pointDrawModeActive ? ( <> - - - ) : null; } @@ -75,7 +71,7 @@ export function ToolbarOverlay(props: Props) { {renderToolsControl()} - {renderFeatureDrawAndEditControls()} + {renderFeatureDrawControl()} ); } diff --git a/x-pack/plugins/maps/public/util.ts b/x-pack/plugins/maps/public/util.ts index a2dfbac2cd4fd8..58553da31d7e6c 100644 --- a/x-pack/plugins/maps/public/util.ts +++ b/x-pack/plugins/maps/public/util.ts @@ -7,7 +7,7 @@ import { i18n } from '@kbn/i18n'; import { EMSClient, FileLayer, TMSService } from '@elastic/ems-client'; -import { FeatureCollection } from 'geojson'; +import { FeatureCollection, Geometry, Position } from 'geojson'; import * as topojson from 'topojson-client'; import { GeometryCollection } from 'topojson-specification'; import _ from 'lodash'; @@ -158,7 +158,11 @@ export async function fetchGeoJson( ); } -export const addFeatureToIndex = async (indexName: string, geometry: unknown, path: string) => { +export const addFeatureToIndex = async ( + indexName: string, + geometry: Geometry | Position[], + path: string +) => { const data = convertDotNotationStringToObj(path, geometry); return await getHttp().fetch({ path: `${INDEX_FEATURE_PATH}`, From f5c65558ff8b94d61a79fcbd62a25411812fc57f Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 12 May 2021 14:22:03 -0600 Subject: [PATCH 048/103] Add route to find matching indexes for a pattern. Not connected and using test code from client --- x-pack/plugins/maps/common/constants.ts | 1 + x-pack/plugins/maps/common/types.ts | 5 +++ .../maps/public/actions/map_actions.ts | 4 ++- x-pack/plugins/maps/public/util.ts | 9 ++++- .../get_indexes_matching_pattern.ts | 33 +++++++++++++++++++ .../server/data_indexing/indexing_routes.ts | 30 +++++++++++++++++ 6 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 x-pack/plugins/maps/server/data_indexing/get_indexes_matching_pattern.ts diff --git a/x-pack/plugins/maps/common/constants.ts b/x-pack/plugins/maps/common/constants.ts index 516eedb2669e5c..3b05f2111ff329 100644 --- a/x-pack/plugins/maps/common/constants.ts +++ b/x-pack/plugins/maps/common/constants.ts @@ -43,6 +43,7 @@ export const FONTS_API_PATH = `${GIS_API_PATH}/fonts`; export const INDEX_SOURCE_API_PATH = `${GIS_API_PATH}/docSource`; export const API_ROOT_PATH = `/${GIS_API_PATH}`; export const INDEX_FEATURE_PATH = `/${GIS_API_PATH}/feature`; +export const GET_MATCHING_INDEXES_PATH = `/${GIS_API_PATH}/getMatchingIndexes`; export const MVT_GETTILE_API_PATH = 'mvt/getTile'; export const MVT_GETGRIDTILE_API_PATH = 'mvt/getGridTile'; diff --git a/x-pack/plugins/maps/common/types.ts b/x-pack/plugins/maps/common/types.ts index 6ca3de3dac377c..4feb2346e37b8a 100644 --- a/x-pack/plugins/maps/common/types.ts +++ b/x-pack/plugins/maps/common/types.ts @@ -11,6 +11,11 @@ export interface CreateDocSourceResp { error?: Error; } +export interface MatchingIndexesResp { + matchingIndexes?: string[]; + success: boolean; +} + export interface IndexSourceMappings { _meta?: { created_by: string; diff --git a/x-pack/plugins/maps/public/actions/map_actions.ts b/x-pack/plugins/maps/public/actions/map_actions.ts index 5718f09b4f77f4..2d0fd2bcc75e6b 100644 --- a/x-pack/plugins/maps/public/actions/map_actions.ts +++ b/x-pack/plugins/maps/public/actions/map_actions.ts @@ -62,7 +62,7 @@ import { import { INITIAL_LOCATION } from '../../common/constants'; import { scaleBounds } from '../../common/elasticsearch_util'; import { cleanTooltipStateForLayer } from './tooltip_actions'; -import { addFeatureToIndex } from '../util'; +import { addFeatureToIndex, getMatchingIndexes } from '../util'; export interface MapExtentState { zoom: number; @@ -358,6 +358,8 @@ export function addNewFeatureToIndex( path: string ) { return async (dispatch: ThunkDispatch) => { + const matchingIndexes = await getMatchingIndexes('t*'); + console.log(matchingIndexes); await addFeatureToIndex(indexName, geometry, path); await dispatch(syncDataForAllLayers({ forceRefresh: true })); }; diff --git a/x-pack/plugins/maps/public/util.ts b/x-pack/plugins/maps/public/util.ts index 58553da31d7e6c..9a96f105007246 100644 --- a/x-pack/plugins/maps/public/util.ts +++ b/x-pack/plugins/maps/public/util.ts @@ -12,7 +12,7 @@ import * as topojson from 'topojson-client'; import { GeometryCollection } from 'topojson-specification'; import _ from 'lodash'; import fetch from 'node-fetch'; -import { INDEX_FEATURE_PATH } from '../common'; +import { GET_MATCHING_INDEXES_PATH, INDEX_FEATURE_PATH } from '../common'; import { GIS_API_PATH, @@ -188,3 +188,10 @@ const convertDotNotationStringToObj = ( const convertObjectToBlob = (obj: unknown) => { return new Blob([JSON.stringify(obj)], { type: 'application/json' }); }; + +export const getMatchingIndexes = async (indexPattern: string) => { + return await getHttp().fetch({ + path: `${GET_MATCHING_INDEXES_PATH}/${indexPattern}`, + method: 'GET', + }); +}; diff --git a/x-pack/plugins/maps/server/data_indexing/get_indexes_matching_pattern.ts b/x-pack/plugins/maps/server/data_indexing/get_indexes_matching_pattern.ts new file mode 100644 index 00000000000000..dc575ca0abcf2d --- /dev/null +++ b/x-pack/plugins/maps/server/data_indexing/get_indexes_matching_pattern.ts @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { IScopedClusterClient } from 'kibana/server'; +import { CatIndicesRecord } from '@elastic/elasticsearch/api/types'; +import { MatchingIndexesResp } from '../../common'; + +export async function getMatchingIndexes( + indexPattern: string, + { asCurrentUser }: IScopedClusterClient +): Promise { + try { + const { body: indexResults } = await asCurrentUser.cat.indices({ + index: indexPattern, + format: 'JSON', + }); + const matchingIndexes = indexResults + .map((indexRecord: CatIndicesRecord) => indexRecord.index) + .filter((indexName) => !!indexName); + return { + success: true, + matchingIndexes: matchingIndexes as string[], + }; + } catch (error) { + return { + success: false, + }; + } +} diff --git a/x-pack/plugins/maps/server/data_indexing/indexing_routes.ts b/x-pack/plugins/maps/server/data_indexing/indexing_routes.ts index e6e6471ff9af61..5472b36e126caf 100644 --- a/x-pack/plugins/maps/server/data_indexing/indexing_routes.ts +++ b/x-pack/plugins/maps/server/data_indexing/indexing_routes.ts @@ -13,10 +13,12 @@ import { INDEX_SOURCE_API_PATH, GIS_API_PATH, MAX_DRAWING_SIZE_BYTES, + GET_MATCHING_INDEXES_PATH, } from '../../common/constants'; import { createDocSource } from './create_doc_source'; import { writeDataToIndex } from './index_data'; import { PluginStart as DataPluginStart } from '../../../../../src/plugins/data/server'; +import { getMatchingIndexes } from './get_indexes_matching_pattern'; export function initIndexingRoutes({ router, @@ -101,4 +103,32 @@ export function initIndexingRoutes({ } } ); + + router.get( + { + path: `${GET_MATCHING_INDEXES_PATH}/{indexPattern}`, + validate: { + params: schema.object({ + indexPattern: schema.string(), + }), + }, + }, + async (context, request, response) => { + const result = await getMatchingIndexes( + request.params.indexPattern, + context.core.elasticsearch.client + ); + if (result.success) { + return response.ok({ body: result }); + } else { + if (result.error) { + logger.error(result.error); + } + return response.custom({ + body: result?.error?.message, + statusCode: 500, + }); + } + } + ); } From 6ddef3a96978316c894c4d25768d80281836397d Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Mon, 17 May 2021 16:32:59 -0600 Subject: [PATCH 049/103] Revise feature editing to be initiated from layer toc (index persistence not connected) --- .../common/descriptor_types/map_descriptor.ts | 5 ++ .../public/actions/map_action_constants.ts | 1 + .../maps/public/actions/map_actions.ts | 14 ++++ .../index_geometry_select_popover_form.js | 70 ------------------- .../layer_toc/toc_entry/action_labels.ts | 13 +++- .../layer_toc/toc_entry/toc_entry.tsx | 12 ++-- .../toc_entry_actions_popover.test.tsx.snap | 6 +- .../toc_entry_actions_popover/index.ts | 12 +++- .../toc_entry_actions_popover.tsx | 28 ++++++-- .../feature_draw_control.tsx | 12 ++-- .../feature_draw_control/index.ts | 2 +- .../tools_control/tools_control.tsx | 26 ------- .../plugins/maps/public/reducers/map/map.ts | 19 ++++- .../plugins/maps/public/reducers/map/types.ts | 3 +- .../maps/public/selectors/map_selectors.ts | 2 +- .../test/functional/page_objects/gis_page.ts | 2 +- 16 files changed, 99 insertions(+), 128 deletions(-) delete mode 100644 x-pack/plugins/maps/public/components/draw_forms/index_geometry_select_popover_form.js diff --git a/x-pack/plugins/maps/common/descriptor_types/map_descriptor.ts b/x-pack/plugins/maps/common/descriptor_types/map_descriptor.ts index 018115dd4de379..aa9829a5b0bac7 100644 --- a/x-pack/plugins/maps/common/descriptor_types/map_descriptor.ts +++ b/x-pack/plugins/maps/common/descriptor_types/map_descriptor.ts @@ -77,3 +77,8 @@ export type DrawState = { indexPatternTitle?: string; relation?: ES_SPATIAL_RELATIONS; }; + +export type EditState = { + layerId: string; + drawType?: DRAW_TYPE; +}; diff --git a/x-pack/plugins/maps/public/actions/map_action_constants.ts b/x-pack/plugins/maps/public/actions/map_action_constants.ts index 900a64ff65f6af..21ade2c7ccc9a9 100644 --- a/x-pack/plugins/maps/public/actions/map_action_constants.ts +++ b/x-pack/plugins/maps/public/actions/map_action_constants.ts @@ -38,6 +38,7 @@ 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_OPEN_TOOLTIPS = 'SET_OPEN_TOOLTIPS'; export const UPDATE_DRAW_STATE = 'UPDATE_DRAW_STATE'; +export const UPDATE_EDIT_LAYER = 'UPDATE_EDIT_LAYER'; export const SET_SHAPE_TO_DRAW = 'SET_SHAPE_TO_DRAW'; export const SET_SCROLL_ZOOM = 'SET_SCROLL_ZOOM'; export const SET_MAP_INIT_ERROR = 'SET_MAP_INIT_ERROR'; diff --git a/x-pack/plugins/maps/public/actions/map_actions.ts b/x-pack/plugins/maps/public/actions/map_actions.ts index 2d0fd2bcc75e6b..501f79e3acea55 100644 --- a/x-pack/plugins/maps/public/actions/map_actions.ts +++ b/x-pack/plugins/maps/public/actions/map_actions.ts @@ -48,12 +48,14 @@ import { UPDATE_MAP_SETTING, SET_VECTOR_LAYER_INDEX_NAME, REMOVE_FEATURES_FROM_INDEX_QUEUE, + UPDATE_EDIT_LAYER, } from './map_action_constants'; import { autoFitToBounds, syncDataForAllLayers } from './data_request_actions'; import { addLayer, addLayerWithoutDataSync } from './layer_actions'; import { MapSettings } from '../reducers/map'; import { DrawState, + EditState, MapCenter, MapCenterAndZoom, MapExtent, @@ -338,6 +340,18 @@ export function updateDrawState(drawState: DrawState | null) { }; } +export function updateEditLayer(layerId: string | null) { + return (dispatch: Dispatch) => { + if (layerId !== null) { + dispatch({ type: SET_OPEN_TOOLTIPS, openTooltips: [] }); // tooltips just get in the way + } + dispatch({ + type: UPDATE_EDIT_LAYER, + layerId, + }); + }; +} + export function removeFeaturesFromIndexQueue(featureIds: string[]) { return { type: REMOVE_FEATURES_FROM_INDEX_QUEUE, diff --git a/x-pack/plugins/maps/public/components/draw_forms/index_geometry_select_popover_form.js b/x-pack/plugins/maps/public/components/draw_forms/index_geometry_select_popover_form.js deleted file mode 100644 index 780f690f548d85..00000000000000 --- a/x-pack/plugins/maps/public/components/draw_forms/index_geometry_select_popover_form.js +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; -import { EuiForm, EuiButton, EuiSpacer, EuiTextAlign, EuiFormErrorText } from '@elastic/eui'; -import { MultiIndexGeoFieldSelect } from '../multi_index_geo_field_select'; -import { i18n } from '@kbn/i18n'; - -export class IndexGeometrySelectPopoverForm extends Component { - static propTypes = { - geoFields: PropTypes.array.isRequired, - onSubmit: PropTypes.func.isRequired, - }; - - state = { - selectedField: this.props.geoFields.length ? this.props.geoFields[0] : undefined, - }; - - _onGeoFieldChange = (selectedField) => { - this.setState({ selectedField }); - }; - - _onSubmit = () => { - this.props.onSubmit({ - indexPatternId: this.state.selectedField.indexPatternId, - geoFieldName: this.state.selectedField.geoFieldName, - geoFieldType: this.state.selectedField.geoFieldType, - indexPatternTitle: this.state.selectedField.indexPatternTitle, - }); - }; - - render() { - let error; - if (this.props.errorMsg) { - error = {this.props.errorMsg}; - } - return ( - - - - - - {error} - - - - {i18n.translate('xpack.maps.indexGeometrySelectPopoverForm.buttonTitle', { - defaultMessage: 'Launch edit tool', - })} - - - - ); - } -} diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/action_labels.ts b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/action_labels.ts index 74d4b205bfdf2a..f514f213958cbe 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/action_labels.ts +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/action_labels.ts @@ -21,10 +21,17 @@ export function getVisibilityToggleLabel(isVisible: boolean) { }); } -export const EDIT_LAYER_LABEL = i18n.translate( - 'xpack.maps.layerControl.layerTocActions.editButtonLabel', +export const LAYER_SETTINGS_LABEL = i18n.translate( + 'xpack.maps.layerControl.layerTocActions.layerSettingsButtonLabel', { - defaultMessage: 'Edit layer', + defaultMessage: 'Layer settings', + } +); + +export const EDIT_FEATURES_LABEL = i18n.translate( + 'xpack.maps.layerControl.layerTocActions.editFeaturesButtonLabel', + { + defaultMessage: 'Edit features', } ); diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.tsx index 553d7b94006f4a..41388c91539972 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.tsx +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.tsx @@ -15,7 +15,7 @@ import { TOCEntryActionsPopover } from './toc_entry_actions_popover'; import { getVisibilityToggleIcon, getVisibilityToggleLabel, - EDIT_LAYER_LABEL, + LAYER_SETTINGS_LABEL, FIT_TO_DATA_LABEL, } from './action_labels'; import { ILayer } from '../../../../../classes/layers/layer'; @@ -196,11 +196,11 @@ export class TOCEntry extends Component { if (!this.props.isReadOnly) { quickActions.push( ); @@ -277,7 +277,7 @@ export class TOCEntry extends Component { layer={layer} displayName={this.state.displayName} escapedDisplayName={escapeLayerName(this.state.displayName)} - editLayer={this._openLayerPanelWithCheck} + layerSettings={this._openLayerPanelWithCheck} isEditButtonDisabled={this.props.isEditButtonDisabled} supportsFitToBounds={this.state.supportsFitToBounds} /> diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/__snapshots__/toc_entry_actions_popover.test.tsx.snap b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/__snapshots__/toc_entry_actions_popover.test.tsx.snap index 7e5b43e89f5a41..adf33a85164359 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/__snapshots__/toc_entry_actions_popover.test.tsx.snap +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/__snapshots__/toc_entry_actions_popover.test.tsx.snap @@ -74,7 +74,7 @@ exports[`TOCEntryActionsPopover is rendered 1`] = ` "toolTipContent": null, }, Object { - "data-test-subj": "editLayerButton", + "data-test-subj": "layerSettingsButton", "disabled": false, "icon": { dispatch(toggleLayerVisible(layerId)); }, + enableLayerEditing: (layerId: string) => { + dispatch(updateEditLayer(layerId)); + // TODO: Determine points vs. shapes + dispatch(setDrawMode(DRAW_MODE.DRAW_SHAPES)); + }, }; } diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx index 3cd719f0b9447f..7a1f3d50ec6bf4 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx @@ -14,14 +14,16 @@ import { TOCEntryButton } from '../toc_entry_button'; import { getVisibilityToggleIcon, getVisibilityToggleLabel, - EDIT_LAYER_LABEL, + LAYER_SETTINGS_LABEL, FIT_TO_DATA_LABEL, + EDIT_FEATURES_LABEL, } from '../action_labels'; export interface Props { cloneLayer: (layerId: string) => void; + enableLayerEditing: (layerId: string) => void; displayName: string; - editLayer: () => void; + layerSettings: () => void; escapedDisplayName: string; fitToBounds: (layerId: string) => void; isEditButtonDisabled: boolean; @@ -96,16 +98,30 @@ export class TOCEntryActionsPopover extends Component { }, ]; + // TODO: Make conditional + actionItems.push({ + // TODO: Determine + disabled: false, + name: EDIT_FEATURES_LABEL, + icon: , + 'data-test-subj': 'editLayerButton', + toolTipContent: null, + onClick: () => { + this._closePopover(); + this.props.enableLayerEditing(this.props.layer.getId()); + }, + }); + if (!this.props.isReadOnly) { actionItems.push({ disabled: this.props.isEditButtonDisabled, - name: EDIT_LAYER_LABEL, - icon: , - 'data-test-subj': 'editLayerButton', + name: LAYER_SETTINGS_LABEL, + icon: , + 'data-test-subj': 'layerSettingsButton', toolTipContent: null, onClick: () => { this._closePopover(); - this.props.editLayer(); + this.props.layerSettings(); }, }); actionItems.push({ diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx index feb3700d0c1d63..773a7abdadb115 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx @@ -15,7 +15,7 @@ import { GeometryFilterForm } from '../../../../components/draw_forms/geometry_f export interface Props { cancelDraw: () => void; drawType: string; - updateCompletedShape: (shapeToDraw: DRAW_TYPE) => void; + setDrawShape: (shapeToDraw: DRAW_TYPE) => void; pointsOnly?: boolean; } @@ -38,7 +38,7 @@ export function FeatureDrawControl(props: Props) { > props.updateCompletedShape(DRAW_TYPE.LINE)} + onClick={() => props.setDrawShape(DRAW_TYPE.LINE)} iconType="minus" aria-label={i18n.translate( 'xpack.maps.toolbarOverlay.featureDraw.drawLineLabel', @@ -61,7 +61,7 @@ export function FeatureDrawControl(props: Props) { > props.updateCompletedShape(DRAW_TYPE.POLYGON)} + onClick={() => props.setDrawShape(DRAW_TYPE.POLYGON)} iconType="node" aria-label={i18n.translate( 'xpack.maps.toolbarOverlay.featureDraw.drawPolygonLabel', @@ -84,7 +84,7 @@ export function FeatureDrawControl(props: Props) { > props.updateCompletedShape(DRAW_TYPE.DISTANCE)} + onClick={() => props.setDrawShape(DRAW_TYPE.DISTANCE)} iconType="plusInCircle" aria-label={i18n.translate( 'xpack.maps.toolbarOverlay.featureDraw.drawCircleLabel', @@ -107,7 +107,7 @@ export function FeatureDrawControl(props: Props) { > props.updateCompletedShape(DRAW_TYPE.BOUNDS)} + onClick={() => props.setDrawShape(DRAW_TYPE.BOUNDS)} iconType="stop" aria-label={i18n.translate( 'xpack.maps.toolbarOverlay.featureDraw.drawBBoxLabel', @@ -132,7 +132,7 @@ export function FeatureDrawControl(props: Props) { > props.updateCompletedShape(DRAW_TYPE.POINT)} + onClick={() => props.setDrawShape(DRAW_TYPE.POINT)} iconType="dot" aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawPointLabel', { defaultMessage: 'Draw point', diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/index.ts index 726baeb20d7424..0761a88b6087ee 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/index.ts @@ -24,7 +24,7 @@ function mapStateToProps(state: MapStoreState) { function mapDispatchToProps(dispatch: ThunkDispatch) { return { - updateCompletedShape: (shapeToDraw: DRAW_TYPE) => { + setDrawShape: (shapeToDraw: DRAW_TYPE) => { dispatch(setShapeToDraw(shapeToDraw)); }, cancelDraw: () => { diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx index fc5b83014f6729..1f8df72a94584b 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx @@ -38,10 +38,6 @@ const DRAW_DISTANCE_LABEL = i18n.translate('xpack.maps.toolbarOverlay.drawDistan defaultMessage: 'Draw distance to filter data', }); -const ADD_FEATURES_LABEL = i18n.translate('xpack.maps.toolbarOverlay.editFeaturesLabel', { - defaultMessage: 'Add features to index', -}); - const DRAW_SHAPE_LABEL_SHORT = i18n.translate('xpack.maps.toolbarOverlay.drawShapeLabelShort', { defaultMessage: 'Draw shape', }); @@ -57,13 +53,6 @@ const DRAW_DISTANCE_LABEL_SHORT = i18n.translate( } ); -const ADD_FEATURES_LABEL_SHORT = i18n.translate( - 'xpack.maps.toolbarOverlay.editFeaturesLabelShort', - { - defaultMessage: 'Add features', - } -); - export interface Props { cancelDraw: () => void; geoFields: GeoFieldWithIndex[]; @@ -172,10 +161,6 @@ export class ToolsControl extends Component { name: DRAW_DISTANCE_LABEL, panel: 3, }, - { - name: ADD_FEATURES_LABEL, - panel: 4, - }, ]; return [ @@ -240,17 +225,6 @@ export class ToolsControl extends Component { /> ), }, - { - id: 4, - title: ADD_FEATURES_LABEL_SHORT, - content: ( - - ), - }, ]; } diff --git a/x-pack/plugins/maps/public/reducers/map/map.ts b/x-pack/plugins/maps/public/reducers/map/map.ts index 20b40a1ad7f529..8c64ad464d8eb9 100644 --- a/x-pack/plugins/maps/public/reducers/map/map.ts +++ b/x-pack/plugins/maps/public/reducers/map/map.ts @@ -50,6 +50,7 @@ import { SET_VECTOR_LAYER_INDEX_NAME, CLEAR_DRAWING_DATA, REMOVE_FEATURES_FROM_INDEX_QUEUE, + UPDATE_EDIT_LAYER, } from '../../actions'; import { getDefaultMapSettings } from './default_map_settings'; @@ -83,7 +84,7 @@ export const DEFAULT_MAP_STATE: MapState = { refreshTimerLastTriggeredAt: undefined, vectorLayerIndexName: '', drawState: undefined, - shapeToDraw: undefined, + editState: undefined, featuresToIndexQueue: [], }, selectedLayerId: null, @@ -103,12 +104,26 @@ export function map(state: MapState = DEFAULT_MAP_STATE, action: any) { drawState: action.drawState, }, }; + case UPDATE_EDIT_LAYER: + return { + ...state, + mapState: { + ...state.mapState, + editState: { + ...state.mapState.editState, + editLayer: action.editLayer, + }, + }, + }; case SET_SHAPE_TO_DRAW: return { ...state, mapState: { ...state.mapState, - shapeToDraw: action.shapeToDraw, + editState: { + ...state.mapState.editState, + drawType: action.shapeToDraw, + }, }, }; case REMOVE_FEATURES_FROM_INDEX_QUEUE: diff --git a/x-pack/plugins/maps/public/reducers/map/types.ts b/x-pack/plugins/maps/public/reducers/map/types.ts index d279bd517a9ec7..b85bb085d72289 100644 --- a/x-pack/plugins/maps/public/reducers/map/types.ts +++ b/x-pack/plugins/maps/public/reducers/map/types.ts @@ -10,6 +10,7 @@ import { Feature } from 'geojson'; import { DrawState, + EditState, Goto, LayerDescriptor, MapCenter, @@ -38,7 +39,7 @@ export type MapContext = { refreshTimerLastTriggeredAt?: string; vectorLayerIndexName: string; drawState?: DrawState; - shapeToDraw?: DRAW_TYPE; + editState?: EditState; featuresToIndexQueue: Feature[]; searchSessionId?: string; searchSessionMapBuffer?: MapExtent; diff --git a/x-pack/plugins/maps/public/selectors/map_selectors.ts b/x-pack/plugins/maps/public/selectors/map_selectors.ts index 94ae297f3074e3..af654c95940c9d 100644 --- a/x-pack/plugins/maps/public/selectors/map_selectors.ts +++ b/x-pack/plugins/maps/public/selectors/map_selectors.ts @@ -198,7 +198,7 @@ export const getDrawState = ({ map }: MapStoreState): DrawState | undefined => map.mapState.drawState; export const getShapeToDraw = ({ map }: MapStoreState): DRAW_TYPE | undefined => - map.mapState.shapeToDraw; + map.mapState.editState ? map.mapState.editState.drawType : undefined; export const getRefreshConfig = ({ map }: MapStoreState): MapRefreshConfig => { if (map.mapState.refreshConfig) { diff --git a/x-pack/test/functional/page_objects/gis_page.ts b/x-pack/test/functional/page_objects/gis_page.ts index 4a898967419b6f..bd03cc4008fed2 100644 --- a/x-pack/test/functional/page_objects/gis_page.ts +++ b/x-pack/test/functional/page_objects/gis_page.ts @@ -311,7 +311,7 @@ export function GisPageProvider({ getService, getPageObjects }: FtrProviderConte async openLayerPanel(layerName: string) { log.debug(`Open layer panel, layer: ${layerName}`); await this.openLayerTocActionsPanel(layerName); - await testSubjects.click('editLayerButton'); + await testSubjects.click('layerSettingsButton'); } async closeLayerPanel() { From 0efb85783585ee333faea9bb71e48ab15efaad8a Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Mon, 17 May 2021 17:29:41 -0600 Subject: [PATCH 050/103] Indexing connected --- .../common/descriptor_types/map_descriptor.ts | 2 +- .../maps/public/actions/map_actions.ts | 28 +++++++++++++------ .../draw_feature_control.tsx | 20 ++----------- .../draw_feature_control/index.ts | 4 +-- .../plugins/maps/public/reducers/map/map.ts | 2 +- .../maps/public/selectors/map_selectors.ts | 3 ++ 6 files changed, 29 insertions(+), 30 deletions(-) diff --git a/x-pack/plugins/maps/common/descriptor_types/map_descriptor.ts b/x-pack/plugins/maps/common/descriptor_types/map_descriptor.ts index aa9829a5b0bac7..1d1d15e9fed19f 100644 --- a/x-pack/plugins/maps/common/descriptor_types/map_descriptor.ts +++ b/x-pack/plugins/maps/common/descriptor_types/map_descriptor.ts @@ -79,6 +79,6 @@ export type DrawState = { }; export type EditState = { - layerId: string; + layerId?: string; drawType?: DRAW_TYPE; }; diff --git a/x-pack/plugins/maps/public/actions/map_actions.ts b/x-pack/plugins/maps/public/actions/map_actions.ts index 501f79e3acea55..af18b59a0d6a0a 100644 --- a/x-pack/plugins/maps/public/actions/map_actions.ts +++ b/x-pack/plugins/maps/public/actions/map_actions.ts @@ -24,6 +24,8 @@ import { getLayerList, getSearchSessionId, getSearchSessionMapBuffer, + getLayerById, + getEditingLayer, } from '../selectors/map_selectors'; import { CLEAR_GOTO, @@ -65,6 +67,7 @@ import { INITIAL_LOCATION } from '../../common/constants'; import { scaleBounds } from '../../common/elasticsearch_util'; import { cleanTooltipStateForLayer } from './tooltip_actions'; import { addFeatureToIndex, getMatchingIndexes } from '../util'; +import { AbstractESSource } from '../classes/sources/es_source'; export interface MapExtentState { zoom: number; @@ -366,15 +369,24 @@ export function setVectorLayerIndexName(indexName: string) { }; } -export function addNewFeatureToIndex( - indexName: string, - geometry: Geometry | Position[], - path: string -) { - return async (dispatch: ThunkDispatch) => { - const matchingIndexes = await getMatchingIndexes('t*'); +export function addNewFeatureToIndex(geometry: Geometry | Position[]) { + return async ( + dispatch: ThunkDispatch, + getState: () => MapStoreState + ) => { + const layerId = getEditingLayer(getState()); + if (!layerId) { + return; + } + const layer = getLayerById(layerId, getState()); + if (!layer) { + return; + } + const layerSource = (await layer.getSource()) as AbstractESSource; + const indexPattern = await layerSource.getIndexPattern(); + const matchingIndexes = await getMatchingIndexes('n*'); console.log(matchingIndexes); - await addFeatureToIndex(indexName, geometry, path); + await addFeatureToIndex(indexPattern.title, geometry, layerSource.getGeoFieldName()); await dispatch(syncDataForAllLayers({ forceRefresh: true })); }; } diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx index d1865b33649f3f..c021c9c3fd24ee 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx @@ -21,7 +21,7 @@ import { DrawState } from '../../../../../common/descriptor_types'; const geoJSONReader = new jsts.io.GeoJSONReader(); export interface Props { - addNewFeatureToIndex: (indexName: string, geometry: unknown, path: string) => void; + addNewFeatureToIndex: (geometry: Geometry | Position[]) => void; disableDrawState: () => void; removeFeatures: (featureIds: string[]) => void; drawType: DRAW_TYPE; @@ -55,29 +55,13 @@ export class DrawFeatureControl extends Component { }) ); } - const geoField = this.props.drawState.geoFieldName; - const indexPattern = this.props.drawState.indexPatternTitle; - if (!geoField) { - throw new Error( - i18n.translate('xpack.maps.drawFeatureControl.missingGeofield', { - defaultMessage: `No geo field designated for feature update`, - }) - ); - } - if (!indexPattern) { - throw new Error( - i18n.translate('xpack.maps.drawFeatureControl.missingIndexPattern', { - defaultMessage: `No index pattern designated for feature update`, - }) - ); - } if ('coordinates' in feature.geometry) { // @ts-ignore /* Single position array only used if point geometry */ const featureGeom: Geometry | Position[] = this.props.drawMode === DRAW_MODE.DRAW_POINTS ? feature.geometry.coordinates : feature.geometry; - this.props.addNewFeatureToIndex(indexPattern, featureGeom, geoField); + this.props.addNewFeatureToIndex(featureGeom); } }); } catch (error) { diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts index eace53dbef2684..b0d1ed830fdbf0 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts @@ -29,8 +29,8 @@ function mapStateToProps(state: MapStoreState) { function mapDispatchToProps(dispatch: ThunkDispatch) { return { - addNewFeatureToIndex(indexName: string, geometry: Geometry | Position[], path: string) { - dispatch(addNewFeatureToIndex(indexName, geometry, path)); + addNewFeatureToIndex(geometry: Geometry | Position[], path: string) { + dispatch(addNewFeatureToIndex(geometry)); }, disableDrawState() { dispatch(setShapeToDraw(null)); diff --git a/x-pack/plugins/maps/public/reducers/map/map.ts b/x-pack/plugins/maps/public/reducers/map/map.ts index 8c64ad464d8eb9..355733db31a64a 100644 --- a/x-pack/plugins/maps/public/reducers/map/map.ts +++ b/x-pack/plugins/maps/public/reducers/map/map.ts @@ -111,7 +111,7 @@ export function map(state: MapState = DEFAULT_MAP_STATE, action: any) { ...state.mapState, editState: { ...state.mapState.editState, - editLayer: action.editLayer, + layerId: action.layerId, }, }, }; diff --git a/x-pack/plugins/maps/public/selectors/map_selectors.ts b/x-pack/plugins/maps/public/selectors/map_selectors.ts index af654c95940c9d..d0061705941c50 100644 --- a/x-pack/plugins/maps/public/selectors/map_selectors.ts +++ b/x-pack/plugins/maps/public/selectors/map_selectors.ts @@ -200,6 +200,9 @@ export const getDrawState = ({ map }: MapStoreState): DrawState | undefined => export const getShapeToDraw = ({ map }: MapStoreState): DRAW_TYPE | undefined => map.mapState.editState ? map.mapState.editState.drawType : undefined; +export const getEditingLayer = ({ map }: MapStoreState): string | undefined => + map.mapState.editState ? map.mapState.editState.layerId : undefined; + export const getRefreshConfig = ({ map }: MapStoreState): MapRefreshConfig => { if (map.mapState.refreshConfig) { return map.mapState.refreshConfig; From a8b21d364d5d3c661b407fb7945649db6633383d Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Tue, 18 May 2021 08:03:51 -0600 Subject: [PATCH 051/103] Detangle filters and feature drawing. Add drawing exit button --- .../toolbar_overlay/index.ts | 13 +++++++- .../toolbar_overlay/toolbar_overlay.tsx | 30 +++++++++++++++++-- .../toolbar_overlay/tools_control/index.ts | 1 - .../tools_control/tools_control.tsx | 8 ++--- 4 files changed, 41 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts index d9c84290f0d5d0..8ae1641c8fe629 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts @@ -6,11 +6,14 @@ */ import { connect } from 'react-redux'; +import { ThunkDispatch } from 'redux-thunk'; +import { AnyAction } from 'redux'; import { ToolbarOverlay } from './toolbar_overlay'; import { MapStoreState } from '../../reducers/store'; import { getDrawMode } from '../../selectors/ui_selectors'; import { getLayersBySourceType } from '../../selectors/map_selectors'; import { DRAW_MODE, SOURCE_TYPES } from '../../../common'; +import { setDrawMode } from '../../actions'; function mapStateToProps(state: MapStoreState) { return { @@ -20,5 +23,13 @@ function mapStateToProps(state: MapStoreState) { }; } -const connected = connect(mapStateToProps, null)(ToolbarOverlay); +function mapDispatchToProps(dispatch: ThunkDispatch) { + return { + cancelEditing: () => { + dispatch(setDrawMode(DRAW_MODE.NONE)); + }, + }; +} + +const connected = connect(mapStateToProps, mapDispatchToProps)(ToolbarOverlay); export { connected as ToolbarOverlay }; diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx index 0d0eec151b6b2c..b256bd2f41cd72 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx @@ -6,7 +6,8 @@ */ import React from 'react'; -import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; import { Filter } from 'src/plugins/data/public'; import { ActionExecutionContext, Action } from 'src/plugins/ui_actions/public'; import { SetViewControl } from './set_view_control'; @@ -23,12 +24,20 @@ export interface Props { showEditButton: boolean; shapeDrawModeActive: boolean; pointDrawModeActive: boolean; + cancelEditing: () => void; } export function ToolbarOverlay(props: Props) { function renderToolsControl() { - const { addFilters, geoFields, getFilterActions, getActionContext } = props; - if (!addFilters || !geoFields.length) { + const { + addFilters, + geoFields, + getFilterActions, + getActionContext, + shapeDrawModeActive, + pointDrawModeActive, + } = props; + if (!addFilters || !geoFields.length || shapeDrawModeActive || pointDrawModeActive) { return null; } @@ -49,6 +58,21 @@ export function ToolbarOverlay(props: Props) { + + + + + ) : null; } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts index bf02301676709e..24a87d715fffd0 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts @@ -19,7 +19,6 @@ function mapStateToProps(state: MapStoreState) { const drawMode = getDrawMode(state); return { filterModeActive: drawMode === DRAW_MODE.DRAW_FILTERS, - featureModeActive: drawMode === DRAW_MODE.DRAW_POINTS || drawMode === DRAW_MODE.DRAW_SHAPES, }; } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx index 1f8df72a94584b..d11c6e9a681656 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx @@ -57,7 +57,6 @@ export interface Props { cancelDraw: () => void; geoFields: GeoFieldWithIndex[]; filterModeActive: boolean; - featureModeActive: boolean; getFilterActions?: () => Promise; getActionContext?: () => ActionExecutionContext; activateDrawFilterMode: (drawState: DrawState) => void; @@ -234,7 +233,7 @@ export class ToolsControl extends Component { { ); - if ( - !(this.props.filterModeActive || this.props.featureModeActive) || - this.state.isPopoverOpen - ) { + if (!this.props.filterModeActive || this.state.isPopoverOpen) { return toolsPopoverButton; } From 6c31b48dc7da1998c13b93e4f16b44788dc05b7a Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Tue, 18 May 2021 08:57:35 -0600 Subject: [PATCH 052/103] Show current layer in edit mode in TOC --- .../layer_control/layer_toc/toc_entry/_toc_entry.scss | 5 +++++ .../layer_control/layer_toc/toc_entry/index.ts | 7 +++++++ .../layer_control/layer_toc/toc_entry/toc_entry.tsx | 2 ++ 3 files changed, 14 insertions(+) diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/_toc_entry.scss b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/_toc_entry.scss index 53e5d2e0bb6b64..bd0df7d2129cd0 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/_toc_entry.scss +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/_toc_entry.scss @@ -30,6 +30,11 @@ } } +.mapTocEntry-isInEditingMode { + background-color: $euiColorLightShade !important; + border: 2px dashed $euiColorAccent !important; +} + .mapTocEntry-isDragging { @include euiBottomShadowMedium; } diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/index.ts b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/index.ts index eaebc9099ada12..272d8e21d138db 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/index.ts +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/index.ts @@ -15,11 +15,13 @@ import { getMapZoom, hasDirtyState, getSelectedLayer, + getEditingLayer, } from '../../../../../selectors/map_selectors'; import { getIsReadOnly, getOpenTOCDetails, getFlyoutDisplay, + getDrawMode, } from '../../../../../selectors/ui_selectors'; import { fitToLayerExtent, @@ -29,6 +31,7 @@ import { showTOCDetails, toggleLayerVisible, } from '../../../../../actions'; +import { DRAW_MODE } from '../../../../../../common'; function mapStateToProps(state: MapStoreState, ownProps: OwnProps): ReduxStateProps { const flyoutDisplay = getFlyoutDisplay(state); @@ -40,6 +43,10 @@ function mapStateToProps(state: MapStoreState, ownProps: OwnProps): ReduxStatePr isLegendDetailsOpen: getOpenTOCDetails(state).includes(ownProps.layer.getId()), isEditButtonDisabled: flyoutDisplay !== FLYOUT_STATE.NONE && flyoutDisplay !== FLYOUT_STATE.LAYER_PANEL, + layerIsInEditMode: + (getDrawMode(state) === DRAW_MODE.DRAW_SHAPES || + getDrawMode(state) === DRAW_MODE.DRAW_POINTS) && + getEditingLayer(state) === ownProps.layer.getId(), }; } diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.tsx index 41388c91539972..0e356ad6b5b231 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.tsx +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.tsx @@ -31,6 +31,7 @@ export interface ReduxStateProps { hasDirtyStateSelector: boolean; isLegendDetailsOpen: boolean; isEditButtonDisabled: boolean; + layerIsInEditMode: boolean; } export interface ReduxDispatchProps { @@ -314,6 +315,7 @@ export class TOCEntry extends Component { 'mapTocEntry-isSelected': this.props.layer.isPreviewLayer() || (this.props.selectedLayer && this.props.selectedLayer.getId() === this.props.layer.getId()), + 'mapTocEntry-isInEditingMode': this.props.layerIsInEditMode, }); return ( From ce1d62e9b2d562c89a1504be7e08418193ba6b72 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Tue, 18 May 2021 14:06:06 -0600 Subject: [PATCH 053/103] Edit styling adjustments. Add source editable check function. Misc. --- .../maps/public/actions/map_actions.ts | 2 -- .../classes/sources/es_source/es_source.ts | 13 +++++++++ .../maps/public/classes/sources/source.ts | 7 ++++- .../mb_map/draw_control/draw_tooltip.tsx | 10 +------ .../layer_toc/toc_entry/_toc_entry.scss | 2 +- .../toolbar_overlay/_toolbar_overlay.scss | 6 +++++ .../feature_draw_control.tsx | 20 +++++++++++++- .../feature_draw_control/index.ts | 6 ++--- .../toolbar_overlay/index.ts | 13 +-------- .../toolbar_overlay/toolbar_overlay.tsx | 27 +++---------------- 10 files changed, 54 insertions(+), 52 deletions(-) diff --git a/x-pack/plugins/maps/public/actions/map_actions.ts b/x-pack/plugins/maps/public/actions/map_actions.ts index af18b59a0d6a0a..3d32b0731afc6f 100644 --- a/x-pack/plugins/maps/public/actions/map_actions.ts +++ b/x-pack/plugins/maps/public/actions/map_actions.ts @@ -384,8 +384,6 @@ export function addNewFeatureToIndex(geometry: Geometry | Position[]) { } const layerSource = (await layer.getSource()) as AbstractESSource; const indexPattern = await layerSource.getIndexPattern(); - const matchingIndexes = await getMatchingIndexes('n*'); - console.log(matchingIndexes); await addFeatureToIndex(indexPattern.title, geometry, layerSource.getGeoFieldName()); await dispatch(syncDataForAllLayers({ forceRefresh: true })); }; diff --git a/x-pack/plugins/maps/public/classes/sources/es_source/es_source.ts b/x-pack/plugins/maps/public/classes/sources/es_source/es_source.ts index 8e31ad78551970..0c9a3ae583845d 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_source/es_source.ts +++ b/x-pack/plugins/maps/public/classes/sources/es_source/es_source.ts @@ -36,6 +36,7 @@ import { IField } from '../../fields/field'; import { FieldFormatter } from '../../../../common/constants'; import { Adapters } from '../../../../../../../src/plugins/inspector/common/adapters'; import { isValidStringConfig } from '../../util/valid_string_config'; +import { getMatchingIndexes } from '../../../util'; export function isSearchSourceAbortError(error: Error) { return error.name === 'AbortError'; @@ -68,6 +69,7 @@ export interface IESSource extends IVectorSource { export class AbstractESSource extends AbstractVectorSource implements IESSource { indexPattern?: IndexPattern; + _isEditable: boolean | undefined; readonly _descriptor: AbstractESSourceDescriptor; @@ -120,6 +122,17 @@ export class AbstractESSource extends AbstractVectorSource implements IESSource return true; } + async isEditable(): Promise { + if (this._isEditable === undefined) { + if (!this.indexPattern) { + return false; + } + const matchingIndexes = await getMatchingIndexes(this.indexPattern.title); + this._isEditable = matchingIndexes.length <= 1; + } + return this._isEditable; + } + getIndexPatternIds(): string[] { return [this.getIndexPatternId()]; } diff --git a/x-pack/plugins/maps/public/classes/sources/source.ts b/x-pack/plugins/maps/public/classes/sources/source.ts index 486d5688c1a62c..667a4df7a041aa 100644 --- a/x-pack/plugins/maps/public/classes/sources/source.ts +++ b/x-pack/plugins/maps/public/classes/sources/source.ts @@ -12,7 +12,7 @@ import { Adapters } from 'src/plugins/inspector/public'; import { GeoJsonProperties } from 'geojson'; import { copyPersistentState } from '../../reducers/copy_persistent_state'; import { IField } from '../fields/field'; -import { FieldFormatter, MAX_ZOOM, MIN_ZOOM } from '../../../common/constants'; +import { FieldFormatter, MAX_ZOOM, MIN_ZOOM, SOURCE_TYPES } from '../../../common/constants'; import { AbstractSourceDescriptor, Attribution } from '../../../common/descriptor_types'; import { OnSourceChangeArgs } from '../../connected_components/layer_panel/view'; import { LICENSED_FEATURES } from '../../licensed_features'; @@ -34,6 +34,7 @@ export interface ISource { getDisplayName(): Promise; getInspectorAdapters(): Adapters | undefined; isFieldAware(): boolean; + isEditable(): Promise; isFilterByMapBounds(): boolean; isGeoGridPrecisionAware(): boolean; isQueryAware(): boolean; @@ -105,6 +106,10 @@ export class AbstractSource implements ISource { return false; } + async isEditable(): Promise { + return false; + } + isRefreshTimerAware(): boolean { return false; } diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_tooltip.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_tooltip.tsx index f4e7c6e60e103b..64705a7e95974c 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_tooltip.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_tooltip.tsx @@ -7,7 +7,7 @@ import _ from 'lodash'; import React, { Component, RefObject } from 'react'; -import { EuiPopover, EuiPopoverTitle, EuiText } from '@elastic/eui'; +import { EuiPopover, EuiText } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { Map as MbMap } from 'mapbox-gl'; import { DRAW_TYPE } from '../../../../common/constants'; @@ -109,13 +109,6 @@ export class DrawTooltip extends Component {
); - const title = - this.props.indexPatternId && this.props.geoField ? ( - - {`${this.props.indexPatternId}: ${this.props.geoField}`} - - ) : undefined; - return ( { transform: `translate(${this.state.x - 13}px, ${this.state.y - 13}px)`, }} > - {title ? title : null} {instructions} diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/_toc_entry.scss b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/_toc_entry.scss index bd0df7d2129cd0..951e33376bf5ba 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/_toc_entry.scss +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/_toc_entry.scss @@ -32,7 +32,7 @@ .mapTocEntry-isInEditingMode { background-color: $euiColorLightShade !important; - border: 2px dashed $euiColorAccent !important; + border: 2px dashed $euiColorDangerText !important; } .mapTocEntry-isDragging { diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/_toolbar_overlay.scss b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/_toolbar_overlay.scss index 5b81c62be5d680..fe011fe5f66d70 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/_toolbar_overlay.scss +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/_toolbar_overlay.scss @@ -42,6 +42,12 @@ } } +.mapToolbarOverlay__button__exit { + .euiButtonIcon { + color: $euiColorDangerText !important; + } +} + .mapToolbarOverlay__button__selected { position: relative; transition: transform $euiAnimSpeedNormal ease-in-out, background $euiAnimSpeedNormal ease-in-out; diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx index 773a7abdadb115..ce89ccea55ffe5 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx @@ -13,10 +13,10 @@ import { DRAW_TYPE } from '../../../../../common/constants'; import { GeometryFilterForm } from '../../../../components/draw_forms/geometry_filter_form/geometry_filter_form'; export interface Props { - cancelDraw: () => void; drawType: string; setDrawShape: (shapeToDraw: DRAW_TYPE) => void; pointsOnly?: boolean; + cancelEditing: () => void; } export function FeatureDrawControl(props: Props) { @@ -145,6 +145,24 @@ export function FeatureDrawControl(props: Props) { /> + + + + + ); diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/index.ts index 0761a88b6087ee..06805dfd4d526a 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/index.ts @@ -9,7 +9,7 @@ import { AnyAction } from 'redux'; import { ThunkDispatch } from 'redux-thunk'; import { connect } from 'react-redux'; import { FeatureDrawControl } from './feature_draw_control'; -import { setShapeToDraw } from '../../../../actions'; +import { setDrawMode, setShapeToDraw } from '../../../../actions'; import { MapStoreState } from '../../../../reducers/store'; import { DRAW_MODE, DRAW_TYPE } from '../../../../../common'; import { getDrawMode } from '../../../../selectors/ui_selectors'; @@ -27,8 +27,8 @@ function mapDispatchToProps(dispatch: ThunkDispatch { dispatch(setShapeToDraw(shapeToDraw)); }, - cancelDraw: () => { - dispatch(setShapeToDraw(null)); + cancelEditing: () => { + dispatch(setDrawMode(DRAW_MODE.NONE)); }, }; } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts index 8ae1641c8fe629..24177b77d10209 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts @@ -6,14 +6,11 @@ */ import { connect } from 'react-redux'; -import { ThunkDispatch } from 'redux-thunk'; -import { AnyAction } from 'redux'; import { ToolbarOverlay } from './toolbar_overlay'; import { MapStoreState } from '../../reducers/store'; import { getDrawMode } from '../../selectors/ui_selectors'; import { getLayersBySourceType } from '../../selectors/map_selectors'; import { DRAW_MODE, SOURCE_TYPES } from '../../../common'; -import { setDrawMode } from '../../actions'; function mapStateToProps(state: MapStoreState) { return { @@ -23,13 +20,5 @@ function mapStateToProps(state: MapStoreState) { }; } -function mapDispatchToProps(dispatch: ThunkDispatch) { - return { - cancelEditing: () => { - dispatch(setDrawMode(DRAW_MODE.NONE)); - }, - }; -} - -const connected = connect(mapStateToProps, mapDispatchToProps)(ToolbarOverlay); +const connected = connect(mapStateToProps)(ToolbarOverlay); export { connected as ToolbarOverlay }; diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx index b256bd2f41cd72..5d90ce2d49e91f 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx @@ -6,8 +6,7 @@ */ import React from 'react'; -import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; +import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { Filter } from 'src/plugins/data/public'; import { ActionExecutionContext, Action } from 'src/plugins/ui_actions/public'; import { SetViewControl } from './set_view_control'; @@ -24,7 +23,6 @@ export interface Props { showEditButton: boolean; shapeDrawModeActive: boolean; pointDrawModeActive: boolean; - cancelEditing: () => void; } export function ToolbarOverlay(props: Props) { @@ -54,26 +52,9 @@ export function ToolbarOverlay(props: Props) { function renderFeatureDrawControl() { return props.shapeDrawModeActive || props.pointDrawModeActive ? ( - <> - - - - - - - - - + + + ) : null; } From 4fe3b94dc98744fd2100bfc76e09fe6acb789e17 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Tue, 18 May 2021 15:53:59 -0600 Subject: [PATCH 054/103] Add checks for editability --- .../maps/public/classes/layers/layer.tsx | 5 ++ .../layers/vector_layer/vector_layer.tsx | 16 ++++++ .../classes/sources/es_source/es_source.ts | 6 +-- .../toc_entry_actions_popover.tsx | 49 +++++++++++++------ .../feature_draw_control.tsx | 2 +- 5 files changed, 60 insertions(+), 18 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/layers/layer.tsx b/x-pack/plugins/maps/public/classes/layers/layer.tsx index 4167ed47752195..106c7adc8ecddb 100644 --- a/x-pack/plugins/maps/public/classes/layers/layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/layer.tsx @@ -72,6 +72,7 @@ export interface ILayer { isLayerLoading(): boolean; isLoadingBounds(): boolean; isFilteredByGlobalTime(): Promise; + isEditable(): Promise; hasErrors(): boolean; getErrors(): string; getMbLayerIds(): string[]; @@ -236,6 +237,10 @@ export class AbstractLayer implements ILayer { return !!this._descriptor.__isPreviewLayer; } + async isEditable(): Promise { + return false; + } + supportsElasticsearchFilters(): boolean { return this.getSource().isESSource(); } diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx index 9f1254b2ff448a..29269c7464c4b7 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx @@ -89,6 +89,7 @@ export interface IVectorLayer extends ILayer { getPropertiesForTooltip(properties: GeoJsonProperties): Promise; hasJoins(): boolean; canShowTooltip(): boolean; + isEditable(): Promise; } export class VectorLayer extends AbstractLayer implements IVectorLayer { @@ -170,6 +171,21 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { }); } + async isEditable(): Promise { + if (!(await this.getSource().isEditable())) { + return false; + } + if ( + (await this.isFilteredByGlobalTime()) || + this.isPreviewLayer() || + !this.isVisible() || + this.hasJoins() + ) { + return false; + } + return true; + } + hasJoins() { return this.getValidJoins().length > 0; } diff --git a/x-pack/plugins/maps/public/classes/sources/es_source/es_source.ts b/x-pack/plugins/maps/public/classes/sources/es_source/es_source.ts index 0c9a3ae583845d..c7b4ae7d52225f 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_source/es_source.ts +++ b/x-pack/plugins/maps/public/classes/sources/es_source/es_source.ts @@ -125,10 +125,10 @@ export class AbstractESSource extends AbstractVectorSource implements IESSource async isEditable(): Promise { if (this._isEditable === undefined) { if (!this.indexPattern) { - return false; + await this.getIndexPattern(); } - const matchingIndexes = await getMatchingIndexes(this.indexPattern.title); - this._isEditable = matchingIndexes.length <= 1; + const { matchingIndexes } = await getMatchingIndexes(this.indexPattern!.title); + this._isEditable = matchingIndexes.length === 1; } return this._isEditable; } diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx index 7a1f3d50ec6bf4..a29ffcd61a529c 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx @@ -36,10 +36,32 @@ export interface Props { interface State { isPopoverOpen: boolean; + isLayerEditable: boolean; } export class TOCEntryActionsPopover extends Component { - state: State = { isPopoverOpen: false }; + state: State = { isPopoverOpen: false, isLayerEditable: false }; + private _isMounted = false; + + componentDidMount() { + this._isMounted = true; + } + + componentWillUnmount() { + this._isMounted = false; + } + + componentDidUpdate() { + this._checkLayerEditable(); + } + + async _checkLayerEditable() { + const isLayerEditable = await this.props.layer.isEditable(); + if (!this._isMounted || isLayerEditable === this.state.isLayerEditable) { + return; + } + this.setState({ isLayerEditable }); + } _togglePopover = () => { this.setState((prevState) => ({ @@ -98,19 +120,18 @@ export class TOCEntryActionsPopover extends Component { }, ]; - // TODO: Make conditional - actionItems.push({ - // TODO: Determine - disabled: false, - name: EDIT_FEATURES_LABEL, - icon: , - 'data-test-subj': 'editLayerButton', - toolTipContent: null, - onClick: () => { - this._closePopover(); - this.props.enableLayerEditing(this.props.layer.getId()); - }, - }); + if (this.state.isLayerEditable) { + actionItems.push({ + name: EDIT_FEATURES_LABEL, + icon: , + 'data-test-subj': 'editLayerButton', + toolTipContent: null, + onClick: () => { + this._closePopover(); + this.props.enableLayerEditing(this.props.layer.getId()); + }, + }); + } if (!this.props.isReadOnly) { actionItems.push({ diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx index ce89ccea55ffe5..9182b3867bb7c3 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx @@ -145,7 +145,7 @@ export function FeatureDrawControl(props: Props) { /> - + Date: Thu, 20 May 2021 11:08:38 -0600 Subject: [PATCH 055/103] Adjust conditions for showing feature editing --- .../blended_vector_layer.ts | 4 +++ .../tiled_vector_layer/tiled_vector_layer.tsx | 4 +++ .../layers/vector_layer/vector_layer.tsx | 4 +-- .../sources/es_agg_source/es_agg_source.ts | 4 +++ .../toc_entry_actions_popover.tsx | 27 +++++++++---------- 5 files changed, 26 insertions(+), 17 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/layers/blended_vector_layer/blended_vector_layer.ts b/x-pack/plugins/maps/public/classes/layers/blended_vector_layer/blended_vector_layer.ts index 6dd454137be7de..da9bd3774196ff 100644 --- a/x-pack/plugins/maps/public/classes/layers/blended_vector_layer/blended_vector_layer.ts +++ b/x-pack/plugins/maps/public/classes/layers/blended_vector_layer/blended_vector_layer.ts @@ -259,6 +259,10 @@ export class BlendedVectorLayer extends VectorLayer implements IVectorLayer { return false; } + async isEditable(): Promise { + return false; + } + async cloneDescriptor(): Promise { const clonedDescriptor = await super.cloneDescriptor(); diff --git a/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx index d452096250576d..6f7bf2dd0a3195 100644 --- a/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx @@ -247,4 +247,8 @@ export class TiledVectorLayer extends VectorLayer { getFeatureById(id: string | number): Feature | null { return null; } + + async isEditable(): Promise { + return false; + } } diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx index 29269c7464c4b7..4c88a52d93dd3d 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx @@ -172,10 +172,8 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { } async isEditable(): Promise { - if (!(await this.getSource().isEditable())) { - return false; - } if ( + !(await this.getSource().isEditable()) || (await this.isFilteredByGlobalTime()) || this.isPreviewLayer() || !this.isVisible() || diff --git a/x-pack/plugins/maps/public/classes/sources/es_agg_source/es_agg_source.ts b/x-pack/plugins/maps/public/classes/sources/es_agg_source/es_agg_source.ts index 78bc2592182d8a..fdc23906c2b9eb 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_agg_source/es_agg_source.ts +++ b/x-pack/plugins/maps/public/classes/sources/es_agg_source/es_agg_source.ts @@ -152,4 +152,8 @@ export abstract class AbstractESAggSource extends AbstractESSource implements IE return await Promise.all(promises); } + + async isEditable(): Promise { + return false; + } } diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx index a29ffcd61a529c..03740f0365b524 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx @@ -57,7 +57,7 @@ export class TOCEntryActionsPopover extends Component { async _checkLayerEditable() { const isLayerEditable = await this.props.layer.isEditable(); - if (!this._isMounted || isLayerEditable === this.state.isLayerEditable) { + if (!this._isMounted || !isLayerEditable || isLayerEditable === this.state.isLayerEditable) { return; } this.setState({ isLayerEditable }); @@ -120,20 +120,19 @@ export class TOCEntryActionsPopover extends Component { }, ]; - if (this.state.isLayerEditable) { - actionItems.push({ - name: EDIT_FEATURES_LABEL, - icon: , - 'data-test-subj': 'editLayerButton', - toolTipContent: null, - onClick: () => { - this._closePopover(); - this.props.enableLayerEditing(this.props.layer.getId()); - }, - }); - } - if (!this.props.isReadOnly) { + if (this.state.isLayerEditable) { + actionItems.push({ + name: EDIT_FEATURES_LABEL, + icon: , + 'data-test-subj': 'editLayerButton', + toolTipContent: null, + onClick: () => { + this._closePopover(); + this.props.enableLayerEditing(this.props.layer.getId()); + }, + }); + } actionItems.push({ disabled: this.props.isEditButtonDisabled, name: LAYER_SETTINGS_LABEL, From 70b2d9727f4cfd7ccda6a081e0b74cf0e4cfb491 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Thu, 20 May 2021 17:00:47 -0600 Subject: [PATCH 056/103] Connect shape/point modes. Fix issue with on draw callback not getting removed --- .../mb_map/draw_control/draw_control.tsx | 10 ++++++++-- .../draw_feature_control/draw_feature_control.tsx | 5 +++-- .../toc_entry/toc_entry_actions_popover/index.ts | 7 +++++-- .../toc_entry_actions_popover.tsx | 13 ++++++++++--- 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx index 449d9f59731fdf..f8a33d3f70077b 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx @@ -55,6 +55,7 @@ export class DrawControl extends Component { displayControlsDefault: false, modes: mbDrawModes, }); + private _drawFunction: ((event: { features: Feature[] }) => void) | null = null; componentWillReceiveProps() { this._syncDrawControl(); @@ -62,6 +63,7 @@ export class DrawControl extends Component { componentDidMount() { this._isMounted = true; + this._drawFunction = this.props.onDraw(this._mbDrawControl); this._syncDrawControl(); } @@ -97,7 +99,9 @@ export class DrawControl extends Component { this.props.mbMap.getCanvas().style.cursor = ''; this.props.mbMap.off('draw.modechange', this._onModeChange); - this.props.mbMap.off('draw.create', this.props.onDraw); + if (this._drawFunction !== null) { + this.props.mbMap.off('draw.create', this._drawFunction); + } if (this.props.onFeaturesSelected) { this.props.mbMap.off('draw.selectionchange', this.props.onFeaturesSelected); } @@ -115,7 +119,9 @@ export class DrawControl extends Component { this._mbDrawControlAdded = true; this.props.mbMap.getCanvas().style.cursor = 'crosshair'; this.props.mbMap.on('draw.modechange', this._onModeChange); - this.props.mbMap.on('draw.create', this.props.onDraw(this._mbDrawControl)); + if (this._drawFunction !== null) { + this.props.mbMap.on('draw.create', this._drawFunction); + } if (this.props.onFeaturesSelected) { this.props.mbMap.on( 'draw.selectionchange', diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx index c021c9c3fd24ee..fb8dd6796f44ff 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx @@ -48,7 +48,6 @@ export class DrawFeatureControl extends Component { e.features.forEach((feature: Feature) => { const { geometry } = geoJSONReader.read(feature); if (!geometry.isSimple() || !geometry.isValid()) { - mbDrawControl.delete(feature.id); throw new Error( i18n.translate('xpack.maps.drawFeatureControl.invalidGeometry', { defaultMessage: `Invalid geometry detected`, @@ -75,8 +74,10 @@ export class DrawFeatureControl extends Component { ); } finally { this.props.disableDrawState(); - if (mbDrawControl) { + try { mbDrawControl.deleteAll(); + } catch (_e) { + // Fail silently. Always works, but sometimes produces an upstream error in the draw tool } } }; diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/index.ts b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/index.ts index 9f83fcce97f09e..55d15f7ed24108 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/index.ts +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/index.ts @@ -41,11 +41,14 @@ function mapDispatchToProps(dispatch: ThunkDispatch { dispatch(toggleLayerVisible(layerId)); }, - enableLayerEditing: (layerId: string) => { + enableShapeEditing: (layerId: string) => { dispatch(updateEditLayer(layerId)); - // TODO: Determine points vs. shapes dispatch(setDrawMode(DRAW_MODE.DRAW_SHAPES)); }, + enablePointEditing: (layerId: string) => { + dispatch(updateEditLayer(layerId)); + dispatch(setDrawMode(DRAW_MODE.DRAW_POINTS)); + }, }; } diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx index 03740f0365b524..6e46e2da348454 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx @@ -18,10 +18,12 @@ import { FIT_TO_DATA_LABEL, EDIT_FEATURES_LABEL, } from '../action_labels'; +import { ESSearchSource } from '../../../../../../classes/sources/es_search_source'; export interface Props { cloneLayer: (layerId: string) => void; - enableLayerEditing: (layerId: string) => void; + enableShapeEditing: (layerId: string) => void; + enablePointEditing: (layerId: string) => void; displayName: string; layerSettings: () => void; escapedDisplayName: string; @@ -127,9 +129,14 @@ export class TOCEntryActionsPopover extends Component { icon: , 'data-test-subj': 'editLayerButton', toolTipContent: null, - onClick: () => { + onClick: async () => { this._closePopover(); - this.props.enableLayerEditing(this.props.layer.getId()); + const supportedShapeTypes = await (this.props.layer.getSource() as ESSearchSource).getSupportedShapeTypes(); + if (supportedShapeTypes.length === 1) { + this.props.enablePointEditing(this.props.layer.getId()); + } else { + this.props.enableShapeEditing(this.props.layer.getId()); + } }, }); } From 96b3c9d8de842df1bdcd9dc57fd8d26c93e07a08 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Tue, 1 Jun 2021 08:47:19 -0600 Subject: [PATCH 057/103] Clean up --- .../plugins/maps/public/actions/map_actions.ts | 7 +++---- .../toolbar_overlay/tools_control/index.ts | 8 -------- .../tools_control/tools_control.tsx | 18 ------------------ 3 files changed, 3 insertions(+), 30 deletions(-) diff --git a/x-pack/plugins/maps/public/actions/map_actions.ts b/x-pack/plugins/maps/public/actions/map_actions.ts index 3d32b0731afc6f..6e79ea34a4ec1d 100644 --- a/x-pack/plugins/maps/public/actions/map_actions.ts +++ b/x-pack/plugins/maps/public/actions/map_actions.ts @@ -57,7 +57,6 @@ import { addLayer, addLayerWithoutDataSync } from './layer_actions'; import { MapSettings } from '../reducers/map'; import { DrawState, - EditState, MapCenter, MapCenterAndZoom, MapExtent, @@ -66,8 +65,8 @@ import { import { INITIAL_LOCATION } from '../../common/constants'; import { scaleBounds } from '../../common/elasticsearch_util'; import { cleanTooltipStateForLayer } from './tooltip_actions'; -import { addFeatureToIndex, getMatchingIndexes } from '../util'; -import { AbstractESSource } from '../classes/sources/es_source'; +import { addFeatureToIndex } from '../util'; +import { ESSearchSource } from '../classes/sources/es_search_source'; export interface MapExtentState { zoom: number; @@ -382,7 +381,7 @@ export function addNewFeatureToIndex(geometry: Geometry | Position[]) { if (!layer) { return; } - const layerSource = (await layer.getSource()) as AbstractESSource; + const layerSource = (await layer.getSource()) as ESSearchSource; const indexPattern = await layerSource.getIndexPattern(); await addFeatureToIndex(indexPattern.title, geometry, layerSource.getGeoFieldName()); await dispatch(syncDataForAllLayers({ forceRefresh: true })); diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts index 24a87d715fffd0..8e78e3439531b6 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts @@ -32,14 +32,6 @@ function mapDispatchToProps(dispatch: ThunkDispatch { - dispatch(setDrawMode(DRAW_MODE.DRAW_POINTS)); - dispatch(updateDrawState(drawState)); - }, - activateDrawShapesMode: (drawState: DrawState) => { - dispatch(setDrawMode(DRAW_MODE.DRAW_SHAPES)); - dispatch(updateDrawState(drawState)); - }, deactivateDrawMode: () => dispatch(setDrawMode(DRAW_MODE.NONE)), }; } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx index d11c6e9a681656..e01e1092fa96e8 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx @@ -60,8 +60,6 @@ export interface Props { getFilterActions?: () => Promise; getActionContext?: () => ActionExecutionContext; activateDrawFilterMode: (drawState: DrawState) => void; - activateDrawPointsMode: (drawState: DrawState) => void; - activateDrawShapesMode: (drawState: DrawState) => void; deactivateDrawMode: () => void; } @@ -130,22 +128,6 @@ export class ToolsControl extends Component { this._closePopover(); }; - _initiateFeatureEdit = (options: { - actionId: string; - filterLabel: string; - indexPatternId: string; - indexPatternTitle: string; - geoFieldName: string; - geoFieldType?: ES_GEO_FIELD_TYPE; - }) => { - this._closePopover(); - if (options.geoFieldType === 'geo_point') { - this.props.activateDrawPointsMode(options); - } else { - this.props.activateDrawShapesMode(options); - } - }; - _getDrawPanels() { const tools = [ { From aa3edcab2933af772b9c1de4e5d391229137f4a2 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Tue, 1 Jun 2021 11:05:29 -0600 Subject: [PATCH 058/103] Add back logic to activate feature draw control. Update logic to be similar to other overlay logic --- .../toolbar_overlay/toolbar_overlay.tsx | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx index a00aeb9b62b36f..cc882d070117cf 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx @@ -11,6 +11,7 @@ import { Filter } from 'src/plugins/data/public'; import { ActionExecutionContext, Action } from 'src/plugins/ui_actions/public'; import { SetViewControl } from './set_view_control'; import { ToolsControl } from './tools_control'; +import { FeatureDrawControl } from './feature_draw_controls/feature_draw_control'; import { FitToData } from './fit_to_data'; import { TimesliderToggleButton } from './timeslider_toggle_button'; import { GeoFieldWithIndex } from '../../components/geo_field_with_index'; @@ -51,6 +52,13 @@ export function ToolbarOverlay(props: Props) { ) : null; + const featureDrawControl = + props.shapeDrawModeActive || props.pointDrawModeActive ? ( + + + + ) : null; + return ( ); From a22f058bc70c793caea171f7c39e557d53d1ab19 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Tue, 1 Jun 2021 14:57:01 -0600 Subject: [PATCH 059/103] Editable check fixes and updates --- .../tiled_vector_layer/tiled_vector_layer.tsx | 4 --- .../sources/es_agg_source/es_agg_source.ts | 4 --- .../es_search_source/es_search_source.tsx | 27 ++++++++++++++++--- .../classes/sources/es_source/es_source.ts | 13 --------- .../sources/vector_source/vector_source.tsx | 1 + .../toc_entry_actions_popover.tsx | 2 +- 6 files changed, 25 insertions(+), 26 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx index d154be8b29f2af..6dba935ccc87d9 100644 --- a/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx @@ -247,8 +247,4 @@ export class TiledVectorLayer extends VectorLayer { getFeatureById(id: string | number): Feature | null { return null; } - - async isEditable(): Promise { - return false; - } } diff --git a/x-pack/plugins/maps/public/classes/sources/es_agg_source/es_agg_source.ts b/x-pack/plugins/maps/public/classes/sources/es_agg_source/es_agg_source.ts index fdc23906c2b9eb..78bc2592182d8a 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_agg_source/es_agg_source.ts +++ b/x-pack/plugins/maps/public/classes/sources/es_agg_source/es_agg_source.ts @@ -152,8 +152,4 @@ export abstract class AbstractESAggSource extends AbstractESSource implements IE return await Promise.all(promises); } - - async isEditable(): Promise { - return false; - } } diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx index 8a6e97bf2a1af5..3f5e99ebed9c2c 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx @@ -13,7 +13,7 @@ import { i18n } from '@kbn/i18n'; import { IFieldType, IndexPattern } from 'src/plugins/data/public'; import { GeoJsonProperties } from 'geojson'; import { AbstractESSource } from '../es_source'; -import { getHttp, getSearchService } from '../../../kibana_services'; +import { getFileUpload, getHttp, getSearchService } from '../../../kibana_services'; import { addFieldToDSL, getField, @@ -23,7 +23,6 @@ import { } from '../../../../common/elasticsearch_util'; // @ts-expect-error import { UpdateSourceEditor } from './update_source_editor'; - import { DEFAULT_MAX_BUCKETS_LIMIT, ES_GEO_FIELD_TYPE, @@ -39,10 +38,8 @@ import { import { getDataSourceLabel } from '../../../../common/i18n_getters'; import { getSourceFields } from '../../../index_pattern_util'; import { loadIndexSettings } from './load_index_settings'; - import { DEFAULT_FILTER_BY_MAP_BOUNDS } from './constants'; import { ESDocField } from '../../fields/es_doc_field'; - import { registerSource } from '../source_registry'; import { ESSearchSourceDescriptor, @@ -61,6 +58,7 @@ import { isValidStringConfig } from '../../util/valid_string_config'; import { TopHitsUpdateSourceEditor } from './top_hits'; import { getDocValueAndSourceFields, ScriptField } from './get_docvalue_source_fields'; import { ITiledSingleLayerMvtParams } from '../tiled_single_layer_vector_source/tiled_single_layer_vector_source'; +import { getMatchingIndexes } from '../../../util'; export const sourceTitle = i18n.translate('xpack.maps.source.esSearchTitle', { defaultMessage: 'Documents', @@ -69,6 +67,7 @@ export const sourceTitle = i18n.translate('xpack.maps.source.esSearchTitle', { export class ESSearchSource extends AbstractESSource implements ITiledSingleLayerVectorSource { readonly _descriptor: ESSearchSourceDescriptor; protected readonly _tooltipFields: ESDocField[]; + protected _isEditable: boolean | undefined; static createDescriptor(descriptor: Partial): ESSearchSourceDescriptor { const normalizedDescriptor = AbstractESSource.createDescriptor(descriptor); @@ -392,6 +391,26 @@ export class ESSearchSource extends AbstractESSource implements ITiledSingleLaye return !!(scalingType === SCALING_TYPES.TOP_HITS && topHitsSplitField); } + async isEditable(): Promise { + if (this._isEditable === undefined) { + if (!this.indexPattern) { + await this.getIndexPattern(); + } + + const { matchingIndexes } = await getMatchingIndexes(this.indexPattern!.title); + this._isEditable = + // For now we only support 1:1 index-pattern:index matches + matchingIndexes.length === 1 && + // Permissions required for index modification are identical to file upload + (await getFileUpload().hasImportPermission({ + checkCreateIndexPattern: true, + checkHasManagePipeline: false, + indexName: this.indexPattern!.title, + })); + } + return this._isEditable; + } + _hasSort(): boolean { const { sortField, sortOrder } = this._descriptor; return !!sortField && !!sortOrder; diff --git a/x-pack/plugins/maps/public/classes/sources/es_source/es_source.ts b/x-pack/plugins/maps/public/classes/sources/es_source/es_source.ts index 664998ba4627c7..23bcd9baed8c0b 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_source/es_source.ts +++ b/x-pack/plugins/maps/public/classes/sources/es_source/es_source.ts @@ -36,7 +36,6 @@ import { IField } from '../../fields/field'; import { FieldFormatter } from '../../../../common/constants'; import { Adapters } from '../../../../../../../src/plugins/inspector/common/adapters'; import { isValidStringConfig } from '../../util/valid_string_config'; -import { getMatchingIndexes } from '../../../util'; export function isSearchSourceAbortError(error: Error) { return error.name === 'AbortError'; @@ -69,7 +68,6 @@ export interface IESSource extends IVectorSource { export class AbstractESSource extends AbstractVectorSource implements IESSource { indexPattern?: IndexPattern; - _isEditable: boolean | undefined; readonly _descriptor: AbstractESSourceDescriptor; @@ -122,17 +120,6 @@ export class AbstractESSource extends AbstractVectorSource implements IESSource return true; } - async isEditable(): Promise { - if (this._isEditable === undefined) { - if (!this.indexPattern) { - await this.getIndexPattern(); - } - const { matchingIndexes } = await getMatchingIndexes(this.indexPattern!.title); - this._isEditable = matchingIndexes.length === 1; - } - return this._isEditable; - } - getIndexPatternIds(): string[] { return [this.getIndexPatternId()]; } diff --git a/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.tsx b/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.tsx index eabc5c4314d628..3782118bfde403 100644 --- a/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.tsx @@ -66,6 +66,7 @@ export interface IVectorSource extends ISource { getSupportedShapeTypes(): Promise; isBoundsAware(): boolean; getSourceTooltipContent(sourceDataRequest?: DataRequest): SourceTooltipConfig; + isEditable(): Promise; } export class AbstractVectorSource extends AbstractSource implements IVectorSource { diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx index 6e46e2da348454..f27db415b040c3 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx @@ -59,7 +59,7 @@ export class TOCEntryActionsPopover extends Component { async _checkLayerEditable() { const isLayerEditable = await this.props.layer.isEditable(); - if (!this._isMounted || !isLayerEditable || isLayerEditable === this.state.isLayerEditable) { + if (!this._isMounted || isLayerEditable === this.state.isLayerEditable) { return; } this.setState({ isLayerEditable }); From dd6def59477bdc07b9f2421ef11e918025105425 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Tue, 1 Jun 2021 15:20:13 -0600 Subject: [PATCH 060/103] Add forceRefresh flag to data request context --- .../public/actions/data_request_actions.ts | 22 ++++++++++++------- .../maps/public/actions/map_actions.ts | 4 ++-- .../classes/layers/vector_layer/utils.tsx | 6 ++--- .../layers/vector_layer/vector_layer.tsx | 8 +------ 4 files changed, 19 insertions(+), 21 deletions(-) diff --git a/x-pack/plugins/maps/public/actions/data_request_actions.ts b/x-pack/plugins/maps/public/actions/data_request_actions.ts index 9e5226eb69deb9..b9e696eaa915df 100644 --- a/x-pack/plugins/maps/public/actions/data_request_actions.ts +++ b/x-pack/plugins/maps/public/actions/data_request_actions.ts @@ -61,6 +61,7 @@ export type DataRequestContext = { isRequestStillActive(dataId: string, requestToken: symbol): boolean; registerCancelCallback(requestToken: symbol, callback: () => void): void; dataFilters: MapFilters; + forceRefresh: boolean; }; export function clearDataRequests(layer: ILayer) { @@ -113,7 +114,8 @@ export function updateStyleMeta(layerId: string | null) { function getDataRequestContext( dispatch: ThunkDispatch, getState: () => MapStoreState, - layerId: string + layerId: string, + forceRefresh: boolean = true ): DataRequestContext { return { dataFilters: getDataFilters(getState()), @@ -135,18 +137,17 @@ function getDataRequestContext( }, registerCancelCallback: (requestToken: symbol, callback: () => void) => dispatch(registerCancelCallback(requestToken, callback)), + forceRefresh, }; } -export function syncDataForAllLayers( - { forceRefresh }: { forceRefresh: boolean } = { forceRefresh: false } -) { +export function syncDataForAllLayers() { return async ( dispatch: ThunkDispatch, getState: () => MapStoreState ) => { const syncPromises = getLayerList(getState()).map((layer) => { - return dispatch(syncDataForLayer(layer, forceRefresh)); + return dispatch(syncDataForLayer(layer)); }); await Promise.all(syncPromises); }; @@ -168,13 +169,18 @@ function syncDataForAllJoinLayers() { }; } -export function syncDataForLayer(layer: ILayer, forceRefresh: boolean) { +export function syncDataForLayer(layer: ILayer, forceRefresh: boolean = false) { return async (dispatch: Dispatch, getState: () => MapStoreState) => { - const dataRequestContext = getDataRequestContext(dispatch, getState, layer.getId()); + const dataRequestContext = getDataRequestContext( + dispatch, + getState, + layer.getId(), + forceRefresh + ); if (!layer.isVisible() || !layer.showAtZoomLevel(dataRequestContext.dataFilters.zoom)) { return; } - await layer.syncData(dataRequestContext, forceRefresh); + await layer.syncData(dataRequestContext); }; } diff --git a/x-pack/plugins/maps/public/actions/map_actions.ts b/x-pack/plugins/maps/public/actions/map_actions.ts index edbb59ffdaaa6c..a6715bcd809558 100644 --- a/x-pack/plugins/maps/public/actions/map_actions.ts +++ b/x-pack/plugins/maps/public/actions/map_actions.ts @@ -53,7 +53,7 @@ import { REMOVE_FEATURES_FROM_INDEX_QUEUE, UPDATE_EDIT_LAYER, } from './map_action_constants'; -import { autoFitToBounds, syncDataForAllLayers } from './data_request_actions'; +import { autoFitToBounds, syncDataForAllLayers, syncDataForLayer } from './data_request_actions'; import { addLayer, addLayerWithoutDataSync } from './layer_actions'; import { MapSettings } from '../reducers/map'; import { @@ -405,6 +405,6 @@ export function addNewFeatureToIndex(geometry: Geometry | Position[]) { const layerSource = (await layer.getSource()) as ESSearchSource; const indexPattern = await layerSource.getIndexPattern(); await addFeatureToIndex(indexPattern.title, geometry, layerSource.getGeoFieldName()); - await dispatch(syncDataForAllLayers({ forceRefresh: true })); + await dispatch(syncDataForLayer(layer, true)); }; } diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/utils.tsx b/x-pack/plugins/maps/public/classes/layers/vector_layer/utils.tsx index 7c33ddc28fdbed..a330a7ff3ae3e1 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/utils.tsx +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/utils.tsx @@ -52,7 +52,6 @@ export async function syncVectorSource({ requestMeta, syncContext, source, - forceRefresh, }: { layerId: string; layerName: string; @@ -60,7 +59,6 @@ export async function syncVectorSource({ requestMeta: VectorSourceRequestMeta; syncContext: DataRequestContext; source: IVectorSource; - forceRefresh: boolean; }): Promise<{ refreshed: boolean; featureCollection: FeatureCollection }> { const { startLoading, @@ -71,14 +69,14 @@ export async function syncVectorSource({ } = syncContext; const dataRequestId = SOURCE_DATA_REQUEST_ID; const requestToken = Symbol(`${layerId}-${dataRequestId}`); - const canSkipFetch = !forceRefresh + const canSkipFetch = !syncContext.forceRefresh ? await canSkipSourceUpdate({ source, prevDataRequest, nextMeta: requestMeta, extentAware: source.isFilterByMapBounds(), }) - : !forceRefresh; + : !syncContext.forceRefresh; if (canSkipFetch) { return { refreshed: false, diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx index 0878101f8f75f0..5d6eafadb6e0b3 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx @@ -668,12 +668,7 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { // Given 1 above, which source/style to use can not be stored in Layer instance state. // Given 2 above, which source/style to use can not be pulled from data request state. // Therefore, source and style are provided as arugments and must be used instead of calling getSource or getCurrentStyle. - async _syncData( - syncContext: DataRequestContext, - source: IVectorSource, - style: IVectorStyle, - forceRefresh: boolean - ) { + async _syncData(syncContext: DataRequestContext, source: IVectorSource, style: IVectorStyle) { if (this.isLoadingBounds()) { return; } @@ -688,7 +683,6 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { requestMeta: this._getSearchFilters(syncContext.dataFilters, source, style), syncContext, source, - forceRefresh, }); if ( !sourceResult.featureCollection || From fd0a187b6324a413f051327262be78ec4953db1f Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Tue, 1 Jun 2021 16:27:41 -0600 Subject: [PATCH 061/103] Review feedback. Add addFeature methods to vector layer and es search source. Clean up --- .../public/actions/map_action_constants.ts | 2 -- .../maps/public/actions/map_actions.ts | 25 +++---------------- .../layers/vector_layer/vector_layer.tsx | 12 ++++++--- .../es_search_source/es_search_source.tsx | 10 +++++--- .../sources/vector_source/vector_source.tsx | 7 +++++- .../mb_map/draw_control/draw_control.tsx | 10 -------- .../draw_feature_control.tsx | 14 ----------- .../draw_feature_control/index.ts | 9 +------ .../plugins/maps/public/reducers/map/map.ts | 20 --------------- .../plugins/maps/public/reducers/map/types.ts | 3 +-- 10 files changed, 27 insertions(+), 85 deletions(-) diff --git a/x-pack/plugins/maps/public/actions/map_action_constants.ts b/x-pack/plugins/maps/public/actions/map_action_constants.ts index 21ade2c7ccc9a9..d488f6032f4e64 100644 --- a/x-pack/plugins/maps/public/actions/map_action_constants.ts +++ b/x-pack/plugins/maps/public/actions/map_action_constants.ts @@ -47,6 +47,4 @@ export const SET_MAP_SETTINGS = 'SET_MAP_SETTINGS'; export const ROLLBACK_MAP_SETTINGS = 'ROLLBACK_MAP_SETTINGS'; export const TRACK_MAP_SETTINGS = 'TRACK_MAP_SETTINGS'; export const UPDATE_MAP_SETTING = 'UPDATE_MAP_SETTING'; -export const REMOVE_FEATURES_FROM_INDEX_QUEUE = 'REMOVE_FEATURES_FROM_INDEX_QUEUE'; -export const SET_VECTOR_LAYER_INDEX_NAME = 'SET_VECTOR_LAYER_INDEX_NAME'; export const CLEAR_DRAWING_DATA = 'CLEAR_DRAWING_DATA'; diff --git a/x-pack/plugins/maps/public/actions/map_actions.ts b/x-pack/plugins/maps/public/actions/map_actions.ts index a6715bcd809558..4191a73c9939df 100644 --- a/x-pack/plugins/maps/public/actions/map_actions.ts +++ b/x-pack/plugins/maps/public/actions/map_actions.ts @@ -49,8 +49,6 @@ import { UPDATE_DRAW_STATE, SET_SHAPE_TO_DRAW, UPDATE_MAP_SETTING, - SET_VECTOR_LAYER_INDEX_NAME, - REMOVE_FEATURES_FROM_INDEX_QUEUE, UPDATE_EDIT_LAYER, } from './map_action_constants'; import { autoFitToBounds, syncDataForAllLayers, syncDataForLayer } from './data_request_actions'; @@ -67,8 +65,7 @@ import { import { INITIAL_LOCATION } from '../../common/constants'; import { scaleBounds } from '../../common/elasticsearch_util'; import { cleanTooltipStateForLayer } from './tooltip_actions'; -import { addFeatureToIndex } from '../util'; -import { ESSearchSource } from '../classes/sources/es_search_source'; +import { VectorLayer } from '../classes/layers/vector_layer'; export interface MapExtentState { zoom: number; @@ -375,20 +372,6 @@ export function updateEditLayer(layerId: string | null) { }; } -export function removeFeaturesFromIndexQueue(featureIds: string[]) { - return { - type: REMOVE_FEATURES_FROM_INDEX_QUEUE, - featureIds, - }; -} - -export function setVectorLayerIndexName(indexName: string) { - return { - type: SET_VECTOR_LAYER_INDEX_NAME, - indexName, - }; -} - export function addNewFeatureToIndex(geometry: Geometry | Position[]) { return async ( dispatch: ThunkDispatch, @@ -399,12 +382,10 @@ export function addNewFeatureToIndex(geometry: Geometry | Position[]) { return; } const layer = getLayerById(layerId, getState()); - if (!layer) { + if (!layer || !(layer instanceof VectorLayer)) { return; } - const layerSource = (await layer.getSource()) as ESSearchSource; - const indexPattern = await layerSource.getIndexPattern(); - await addFeatureToIndex(indexPattern.title, geometry, layerSource.getGeoFieldName()); + await layer.addFeature(geometry); await dispatch(syncDataForLayer(layer, true)); }; } diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx index 5d6eafadb6e0b3..e491e588275831 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx @@ -11,7 +11,7 @@ import type { AnyLayer as MbLayer, GeoJSONSource as MbGeoJSONSource, } from '@kbn/mapbox-gl'; -import { Feature, FeatureCollection, GeoJsonProperties } from 'geojson'; +import { Feature, FeatureCollection, GeoJsonProperties, Geometry, Position } from 'geojson'; import _ from 'lodash'; import { EuiIcon } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; @@ -95,6 +95,7 @@ export interface IVectorLayer extends ILayer { canShowTooltip(): boolean; isEditable(): Promise; getLeftJoinFields(): Promise; + addFeature(geometry: Geometry | Position[]): Promise; } export class VectorLayer extends AbstractLayer implements IVectorLayer { @@ -654,8 +655,8 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { } } - async syncData(syncContext: DataRequestContext, forceRefresh: boolean) { - await this._syncData(syncContext, this.getSource(), this.getCurrentStyle(), forceRefresh); + async syncData(syncContext: DataRequestContext) { + await this._syncData(syncContext, this.getSource(), this.getCurrentStyle()); } // TLDR: Do not call getSource or getCurrentStyle in syncData flow. Use 'source' and 'style' arguments instead. @@ -1071,4 +1072,9 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { async getLicensedFeatures() { return await this._source.getLicensedFeatures(); } + + async addFeature(geometry: Geometry | Position[]) { + const layerSource = await this.getSource(); + await layerSource.addFeature(geometry); + } } diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx index 3f5e99ebed9c2c..1eb527322819f1 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx @@ -8,10 +8,9 @@ import _ from 'lodash'; import React, { ReactElement } from 'react'; import rison from 'rison-node'; - import { i18n } from '@kbn/i18n'; import { IFieldType, IndexPattern } from 'src/plugins/data/public'; -import { GeoJsonProperties } from 'geojson'; +import { GeoJsonProperties, Geometry, Position } from 'geojson'; import { AbstractESSource } from '../es_source'; import { getFileUpload, getHttp, getSearchService } from '../../../kibana_services'; import { @@ -58,7 +57,7 @@ import { isValidStringConfig } from '../../util/valid_string_config'; import { TopHitsUpdateSourceEditor } from './top_hits'; import { getDocValueAndSourceFields, ScriptField } from './get_docvalue_source_fields'; import { ITiledSingleLayerMvtParams } from '../tiled_single_layer_vector_source/tiled_single_layer_vector_source'; -import { getMatchingIndexes } from '../../../util'; +import { addFeatureToIndex, getMatchingIndexes } from '../../../util'; export const sourceTitle = i18n.translate('xpack.maps.source.esSearchTitle', { defaultMessage: 'Documents', @@ -690,6 +689,11 @@ export class ESSearchSource extends AbstractESSource implements ITiledSingleLaye return MVT_SOURCE_LAYER_NAME; } + async addFeature(geometry: Geometry | Position[]) { + const indexPattern = await this.getIndexPattern(); + await addFeatureToIndex(indexPattern.title, geometry, this.getGeoFieldName()); + } + async getUrlTemplateWithMeta( searchFilters: VectorSourceRequestMeta ): Promise { diff --git a/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.tsx b/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.tsx index 3782118bfde403..c7d9e644b90f00 100644 --- a/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { FeatureCollection, GeoJsonProperties } from 'geojson'; +import { FeatureCollection, GeoJsonProperties, Geometry, Position } from 'geojson'; import { Filter, TimeRange } from 'src/plugins/data/public'; import { VECTOR_SHAPE_TYPE } from '../../../../common/constants'; import { TooltipProperty, ITooltipProperty } from '../../tooltips/tooltip_property'; @@ -67,6 +67,7 @@ export interface IVectorSource extends ISource { isBoundsAware(): boolean; getSourceTooltipContent(sourceDataRequest?: DataRequest): SourceTooltipConfig; isEditable(): Promise; + addFeature(geometry: Geometry | Position[]): Promise; } export class AbstractVectorSource extends AbstractSource implements IVectorSource { @@ -154,4 +155,8 @@ export class AbstractVectorSource extends AbstractSource implements IVectorSourc getSyncMeta(): VectorSourceSyncMeta | null { return null; } + + async addFeature(geometry: Geometry | Position[]) { + throw new Error('Should implement VectorSource#addFeature'); + } } diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx index 84f863310aa5d8..49a279d7aa7cc8 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx @@ -40,7 +40,6 @@ mbDrawModes[DRAW_CIRCLE] = DrawCircle; export interface Props { drawType?: DRAW_TYPE; onDraw: (drawControl: MapboxDraw) => (event: { features: Feature[] }) => void; - onFeaturesSelected?: (drawControl: MapboxDraw) => (event: { features: Feature[] }) => void; mbMap: MbMap; drawActive: boolean; setShapeToDraw: (shapeToDraw: DRAW_TYPE) => void; @@ -102,9 +101,6 @@ export class DrawControl extends Component { if (this._drawFunction !== null) { this.props.mbMap.off('draw.create', this._drawFunction); } - if (this.props.onFeaturesSelected) { - this.props.mbMap.off('draw.selectionchange', this.props.onFeaturesSelected); - } this.props.mbMap.removeControl(this._mbDrawControl); this._mbDrawControlAdded = false; } @@ -122,12 +118,6 @@ export class DrawControl extends Component { if (this._drawFunction !== null) { this.props.mbMap.on('draw.create', this._drawFunction); } - if (this.props.onFeaturesSelected) { - this.props.mbMap.on( - 'draw.selectionchange', - this.props.onFeaturesSelected(this._mbDrawControl) - ); - } } if (this.props.drawType === DRAW_TYPE.TRASH) { diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx index fb8dd6796f44ff..e5a9f32631b2cf 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx @@ -23,7 +23,6 @@ const geoJSONReader = new jsts.io.GeoJSONReader(); export interface Props { addNewFeatureToIndex: (geometry: Geometry | Position[]) => void; disableDrawState: () => void; - removeFeatures: (featureIds: string[]) => void; drawType: DRAW_TYPE; drawState: DrawState; drawMode: DRAW_MODE; @@ -31,18 +30,6 @@ export interface Props { } export class DrawFeatureControl extends Component { - _onFeaturesSelected = (mbDrawControl: MapboxDraw) => (e: { features: Feature[] }) => { - if (this.props.drawType === DRAW_TYPE.TRASH) { - const featureIds = e.features - .map((feature: Feature) => { - return feature.id ? `${feature.id}` : ''; - }) - .filter((id) => id); - this.props.removeFeatures(featureIds); - mbDrawControl.trash(); - } - }; - _onDraw = (mbDrawControl: MapboxDraw) => async (e: { features: Feature[] }) => { try { e.features.forEach((feature: Feature) => { @@ -87,7 +74,6 @@ export class DrawFeatureControl extends Component { diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts index b0d1ed830fdbf0..8ead6734d1b675 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts @@ -10,11 +10,7 @@ import { ThunkDispatch } from 'redux-thunk'; import { connect } from 'react-redux'; import { Geometry, Position } from 'geojson'; import { DrawFeatureControl } from './draw_feature_control'; -import { - addNewFeatureToIndex, - removeFeaturesFromIndexQueue, - setShapeToDraw, -} from '../../../../actions'; +import { addNewFeatureToIndex, setShapeToDraw } from '../../../../actions'; import { MapStoreState } from '../../../../reducers/store'; import { getDrawState, getShapeToDraw } from '../../../../selectors/map_selectors'; import { getDrawMode } from '../../../../selectors/ui_selectors'; @@ -35,9 +31,6 @@ function mapDispatchToProps(dispatch: ThunkDispatch !action.featureIds.includes(id) - ); - return { - ...state, - mapState: { - ...state.mapState, - featuresToIndexQueue: newFeatureArr, - }, - }; - case SET_VECTOR_LAYER_INDEX_NAME: - return { - ...state, - mapState: { - ...state.mapState, - vectorLayerIndexName: action.indexName, - }, - }; case CLEAR_DRAWING_DATA: return { ...state, diff --git a/x-pack/plugins/maps/public/reducers/map/types.ts b/x-pack/plugins/maps/public/reducers/map/types.ts index e68008d27d6746..02f2161db4ca8b 100644 --- a/x-pack/plugins/maps/public/reducers/map/types.ts +++ b/x-pack/plugins/maps/public/reducers/map/types.ts @@ -20,7 +20,7 @@ import { Timeslice, TooltipState, } from '../../../common/descriptor_types'; -import { DRAW_TYPE, INITIAL_LOCATION } from '../../../common/constants'; +import { INITIAL_LOCATION } from '../../../common/constants'; import { Filter, TimeRange } from '../../../../../../src/plugins/data/public'; export type MapContext = { @@ -39,7 +39,6 @@ export type MapContext = { filters: Filter[]; refreshConfig?: MapRefreshConfig; refreshTimerLastTriggeredAt?: string; - vectorLayerIndexName: string; drawState?: DrawState; editState?: EditState; featuresToIndexQueue: Feature[]; From 2e9a9311b289eda3477595c2b480de83769976ee Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 2 Jun 2021 11:42:26 -0600 Subject: [PATCH 062/103] Differentiate between edit capability and enablement --- .../blended_vector_layer.ts | 8 ++++---- .../maps/public/classes/layers/layer.tsx | 5 +++++ .../layers/vector_layer/vector_layer.tsx | 8 ++++++-- .../toc_entry_actions_popover.tsx | 20 +++++++++++++++---- 4 files changed, 31 insertions(+), 10 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/layers/blended_vector_layer/blended_vector_layer.ts b/x-pack/plugins/maps/public/classes/layers/blended_vector_layer/blended_vector_layer.ts index da9bd3774196ff..212ec23a1ecf9b 100644 --- a/x-pack/plugins/maps/public/classes/layers/blended_vector_layer/blended_vector_layer.ts +++ b/x-pack/plugins/maps/public/classes/layers/blended_vector_layer/blended_vector_layer.ts @@ -259,10 +259,6 @@ export class BlendedVectorLayer extends VectorLayer implements IVectorLayer { return false; } - async isEditable(): Promise { - return false; - } - async cloneDescriptor(): Promise { const clonedDescriptor = await super.cloneDescriptor(); @@ -295,6 +291,10 @@ export class BlendedVectorLayer extends VectorLayer implements IVectorLayer { return this._documentStyle; } + async getEditModeEnabled(): Promise { + return false; + } + async syncData(syncContext: DataRequestContext) { const dataRequestId = ACTIVE_COUNT_DATA_ID; const requestToken = Symbol(`layer-active-count:${this.getId()}`); diff --git a/x-pack/plugins/maps/public/classes/layers/layer.tsx b/x-pack/plugins/maps/public/classes/layers/layer.tsx index b15b86be77cf86..adc0ba25df7536 100644 --- a/x-pack/plugins/maps/public/classes/layers/layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/layer.tsx @@ -74,6 +74,7 @@ export interface ILayer { isLoadingBounds(): boolean; isFilteredByGlobalTime(): Promise; isEditable(): Promise; + getEditModeEnabled(): Promise; hasErrors(): boolean; getErrors(): string; getMbLayerIds(): string[]; @@ -246,6 +247,10 @@ export class AbstractLayer implements ILayer { return false; } + async getEditModeEnabled(): Promise { + return false; + } + supportsElasticsearchFilters(): boolean { return this.getSource().isESSource(); } diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx index e491e588275831..484bf709feebdd 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx @@ -93,6 +93,7 @@ export interface IVectorLayer extends ILayer { getPropertiesForTooltip(properties: GeoJsonProperties): Promise; hasJoins(): boolean; canShowTooltip(): boolean; + getEditModeEnabled(): Promise; isEditable(): Promise; getLeftJoinFields(): Promise; addFeature(geometry: Geometry | Position[]): Promise; @@ -177,9 +178,8 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { }); } - async isEditable(): Promise { + async getEditModeEnabled(): Promise { if ( - !(await this.getSource().isEditable()) || (await this.isFilteredByGlobalTime()) || this.isPreviewLayer() || !this.isVisible() || @@ -190,6 +190,10 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { return true; } + async isEditable(): Promise { + return await this.getSource().isEditable(); + } + hasJoins() { return this.getValidJoins().length > 0; } diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx index f27db415b040c3..aa5cdfb84c2742 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx @@ -39,10 +39,11 @@ export interface Props { interface State { isPopoverOpen: boolean; isLayerEditable: boolean; + editModeEnabled: boolean; } export class TOCEntryActionsPopover extends Component { - state: State = { isPopoverOpen: false, isLayerEditable: false }; + state: State = { isPopoverOpen: false, isLayerEditable: false, editModeEnabled: false }; private _isMounted = false; componentDidMount() { @@ -59,10 +60,15 @@ export class TOCEntryActionsPopover extends Component { async _checkLayerEditable() { const isLayerEditable = await this.props.layer.isEditable(); - if (!this._isMounted || isLayerEditable === this.state.isLayerEditable) { + const editModeEnabled = await this.props.layer.getEditModeEnabled(); + if ( + !this._isMounted || + (isLayerEditable === this.state.isLayerEditable && + editModeEnabled === this.state.editModeEnabled) + ) { return; } - this.setState({ isLayerEditable }); + this.setState({ isLayerEditable, editModeEnabled }); } _togglePopover = () => { @@ -128,7 +134,13 @@ export class TOCEntryActionsPopover extends Component { name: EDIT_FEATURES_LABEL, icon: , 'data-test-subj': 'editLayerButton', - toolTipContent: null, + toolTipContent: this.state.editModeEnabled + ? null + : i18n.translate('xpack.maps.layerTocActions.editLayerTooltip', { + defaultMessage: + 'Only fully added document layers without clustering, joins or time filtering enabled can be modified', + }), + disabled: !this.state.editModeEnabled, onClick: async () => { this._closePopover(); const supportedShapeTypes = await (this.props.layer.getSource() as ESSearchSource).getSupportedShapeTypes(); From 8e78142467e363ddcd762f330c774802c6a9b0d6 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 2 Jun 2021 12:01:29 -0600 Subject: [PATCH 063/103] Allow edits on blended layers if clustering not enabled --- .../classes/layers/blended_vector_layer/blended_vector_layer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/maps/public/classes/layers/blended_vector_layer/blended_vector_layer.ts b/x-pack/plugins/maps/public/classes/layers/blended_vector_layer/blended_vector_layer.ts index 212ec23a1ecf9b..12b064660815f3 100644 --- a/x-pack/plugins/maps/public/classes/layers/blended_vector_layer/blended_vector_layer.ts +++ b/x-pack/plugins/maps/public/classes/layers/blended_vector_layer/blended_vector_layer.ts @@ -292,7 +292,7 @@ export class BlendedVectorLayer extends VectorLayer implements IVectorLayer { } async getEditModeEnabled(): Promise { - return false; + return this._isClustered ? false : super.getEditModeEnabled(); } async syncData(syncContext: DataRequestContext) { From 7bb8f27bdd8a6e0a1c4fb984b67533079e85b7f6 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 2 Jun 2021 17:01:46 -0600 Subject: [PATCH 064/103] Type fixes --- x-pack/plugins/maps/common/types.ts | 1 + .../maps/public/actions/layer_actions.ts | 12 --------- .../public/actions/map_action_constants.ts | 1 - .../layers/__fixtures__/mock_sync_context.ts | 2 ++ .../mvt_single_layer_vector_source.tsx | 6 ++++- .../geometry_filter_form.tsx | 2 +- .../draw_feature_control.tsx | 16 +++++++++--- .../draw_feature_control/index.ts | 20 ++++++++++---- .../feature_geometry_filter_form.tsx | 11 ++++---- .../tooltip_control/tooltip_control.test.tsx | 1 + .../layer_toc/toc_entry/toc_entry.test.tsx | 1 + .../toc_entry_actions_popover.test.tsx | 3 +++ .../feature_edit_tools.tsx} | 16 +++++++++--- .../index.ts | 26 +++++++++++++------ .../toolbar_overlay/toolbar_overlay.test.tsx | 12 ++++++++- .../toolbar_overlay/toolbar_overlay.tsx | 4 +-- .../tools_control/tools_control.test.tsx | 3 +++ .../plugins/maps/public/reducers/map/map.ts | 14 ---------- .../plugins/maps/public/reducers/map/types.ts | 2 -- 19 files changed, 92 insertions(+), 61 deletions(-) rename x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/{feature_draw_control/feature_draw_control.tsx => feature_edit_tools/feature_edit_tools.tsx} (96%) rename x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/{feature_draw_control => feature_edit_tools}/index.ts (65%) diff --git a/x-pack/plugins/maps/common/types.ts b/x-pack/plugins/maps/common/types.ts index 4feb2346e37b8a..5b202fd7811e5b 100644 --- a/x-pack/plugins/maps/common/types.ts +++ b/x-pack/plugins/maps/common/types.ts @@ -14,6 +14,7 @@ export interface CreateDocSourceResp { export interface MatchingIndexesResp { matchingIndexes?: string[]; success: boolean; + error?: Error; } export interface IndexSourceMappings { diff --git a/x-pack/plugins/maps/public/actions/layer_actions.ts b/x-pack/plugins/maps/public/actions/layer_actions.ts index c8b882f02fa35d..90ec515b3ef402 100644 --- a/x-pack/plugins/maps/public/actions/layer_actions.ts +++ b/x-pack/plugins/maps/public/actions/layer_actions.ts @@ -38,7 +38,6 @@ import { UPDATE_LAYER_PROP, UPDATE_LAYER_STYLE, UPDATE_SOURCE_PROP, - CLEAR_DRAWING_DATA, } from './map_action_constants'; import { clearDataRequests, syncDataForLayerId, updateStyleMeta } from './data_request_actions'; import { cleanTooltipStateForLayer } from './tooltip_actions'; @@ -55,11 +54,6 @@ import { IVectorStyle } from '../classes/styles/vector/vector_style'; import { notifyLicensedFeatureUsage } from '../licensed_features'; import { IESAggField } from '../classes/fields/agg'; import { IField } from '../classes/fields/field'; -// @ts-ignore -import { - createNewIndexAndPattern, - addFeatureToIndex, -} from '../classes/layers/new_vector_layer_wizard/utils/indexing_service'; export function trackCurrentLayerState(layerId: string) { return { @@ -586,9 +580,3 @@ export function setAreTilesLoaded(layerId: string, areTilesLoaded: boolean) { newValue: areTilesLoaded, }; } - -export function clearDrawingData() { - return { - type: CLEAR_DRAWING_DATA, - }; -} diff --git a/x-pack/plugins/maps/public/actions/map_action_constants.ts b/x-pack/plugins/maps/public/actions/map_action_constants.ts index d488f6032f4e64..7b4a575622c55a 100644 --- a/x-pack/plugins/maps/public/actions/map_action_constants.ts +++ b/x-pack/plugins/maps/public/actions/map_action_constants.ts @@ -47,4 +47,3 @@ export const SET_MAP_SETTINGS = 'SET_MAP_SETTINGS'; export const ROLLBACK_MAP_SETTINGS = 'ROLLBACK_MAP_SETTINGS'; export const TRACK_MAP_SETTINGS = 'TRACK_MAP_SETTINGS'; export const UPDATE_MAP_SETTING = 'UPDATE_MAP_SETTING'; -export const CLEAR_DRAWING_DATA = 'CLEAR_DRAWING_DATA'; diff --git a/x-pack/plugins/maps/public/classes/layers/__fixtures__/mock_sync_context.ts b/x-pack/plugins/maps/public/classes/layers/__fixtures__/mock_sync_context.ts index 6881264d03d53c..3ffa99f6afe49b 100644 --- a/x-pack/plugins/maps/public/classes/layers/__fixtures__/mock_sync_context.ts +++ b/x-pack/plugins/maps/public/classes/layers/__fixtures__/mock_sync_context.ts @@ -17,6 +17,7 @@ export class MockSyncContext implements DataRequestContext { startLoading: (dataId: string, requestToken: symbol, meta: DataMeta) => void; stopLoading: (dataId: string, requestToken: symbol, data: object, meta: DataMeta) => void; updateSourceData: (newData: unknown) => void; + forceRefresh: boolean; constructor({ dataFilters }: { dataFilters: Partial }) { const mapFilters: MapFilters = { @@ -37,5 +38,6 @@ export class MockSyncContext implements DataRequestContext { this.startLoading = sinon.spy(); this.stopLoading = sinon.spy(); this.updateSourceData = sinon.spy(); + this.forceRefresh = false; } } diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx index 692e1fd18efafd..fbfd982c313d89 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx @@ -8,7 +8,7 @@ import { i18n } from '@kbn/i18n'; import uuid from 'uuid/v4'; import React from 'react'; -import { GeoJsonProperties } from 'geojson'; +import { GeoJsonProperties, Geometry, Position } from 'geojson'; import { AbstractSource, ImmutableSourceProperty, SourceEditorArgs } from '../source'; import { BoundsFilters, GeoJsonWithMeta } from '../vector_source'; import { ITiledSingleLayerVectorSource } from '../tiled_single_layer_vector_source'; @@ -98,6 +98,10 @@ export class MVTSingleLayerVectorSource }); } + addFeature(geometry: Geometry | Position[]): Promise { + throw new Error('Does not implement addFeature'); + } + getMVTFields(): MVTField[] { return this._descriptor.fields.map((field: MVTFieldDescriptor) => { return new MVTField({ diff --git a/x-pack/plugins/maps/public/components/draw_forms/geometry_filter_form/geometry_filter_form.tsx b/x-pack/plugins/maps/public/components/draw_forms/geometry_filter_form/geometry_filter_form.tsx index b790124aabdffe..c752b7e5834b50 100644 --- a/x-pack/plugins/maps/public/components/draw_forms/geometry_filter_form/geometry_filter_form.tsx +++ b/x-pack/plugins/maps/public/components/draw_forms/geometry_filter_form/geometry_filter_form.tsx @@ -41,7 +41,7 @@ export interface Props { }) => void; isFilterGeometryClosed?: boolean; errorMsg?: string; - className: string; + className?: string; isLoading?: boolean; } diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx index e5a9f32631b2cf..36b7a781f9095e 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx @@ -20,15 +20,23 @@ import { DrawState } from '../../../../../common/descriptor_types'; const geoJSONReader = new jsts.io.GeoJSONReader(); -export interface Props { +export interface ReduxStateProps { + drawType?: DRAW_TYPE; + drawState?: DrawState; + drawMode: DRAW_MODE; +} + +export interface ReduxDispatchProps { addNewFeatureToIndex: (geometry: Geometry | Position[]) => void; disableDrawState: () => void; - drawType: DRAW_TYPE; - drawState: DrawState; - drawMode: DRAW_MODE; +} + +export interface OwnProps { mbMap: MbMap; } +type Props = ReduxStateProps & ReduxDispatchProps & OwnProps; + export class DrawFeatureControl extends Component { _onDraw = (mbDrawControl: MapboxDraw) => async (e: { features: Feature[] }) => { try { diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts index 8ead6734d1b675..d6e668c6acc543 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts @@ -9,13 +9,18 @@ import { AnyAction } from 'redux'; import { ThunkDispatch } from 'redux-thunk'; import { connect } from 'react-redux'; import { Geometry, Position } from 'geojson'; -import { DrawFeatureControl } from './draw_feature_control'; +import { + DrawFeatureControl, + ReduxDispatchProps, + ReduxStateProps, + OwnProps, +} from './draw_feature_control'; import { addNewFeatureToIndex, setShapeToDraw } from '../../../../actions'; import { MapStoreState } from '../../../../reducers/store'; import { getDrawState, getShapeToDraw } from '../../../../selectors/map_selectors'; import { getDrawMode } from '../../../../selectors/ui_selectors'; -function mapStateToProps(state: MapStoreState) { +function mapStateToProps(state: MapStoreState): ReduxStateProps { return { drawType: getShapeToDraw(state), drawState: getDrawState(state), @@ -23,9 +28,11 @@ function mapStateToProps(state: MapStoreState) { }; } -function mapDispatchToProps(dispatch: ThunkDispatch) { +function mapDispatchToProps( + dispatch: ThunkDispatch +): ReduxDispatchProps { return { - addNewFeatureToIndex(geometry: Geometry | Position[], path: string) { + addNewFeatureToIndex(geometry: Geometry | Position[]) { dispatch(addNewFeatureToIndex(geometry)); }, disableDrawState() { @@ -34,5 +41,8 @@ function mapDispatchToProps(dispatch: ThunkDispatch( + mapStateToProps, + mapDispatchToProps +)(DrawFeatureControl); export { connected as DrawFeatureControl }; diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/features_tooltip/feature_geometry_filter_form.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/features_tooltip/feature_geometry_filter_form.tsx index 300379aa2c9fdc..b72df0b8b60d97 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/features_tooltip/feature_geometry_filter_form.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/features_tooltip/feature_geometry_filter_form.tsx @@ -80,15 +80,14 @@ export class FeatureGeometryFilterForm extends Component { geoFieldName, relation, }: { - geometryLabel: string; - indexPatternId: string; - geoFieldName: string; - relation: ES_SPATIAL_RELATIONS; + geometryLabel?: string; + indexPatternId?: string; + geoFieldName?: string; + relation?: ES_SPATIAL_RELATIONS; }) => { this.setState({ errorMsg: undefined }); const preIndexedShape = await this._loadPreIndexedShape(); - if (!this._isMounted) { - // do not create filter if component is unmounted + if (!this._isMounted || !(geometryLabel && indexPatternId && geoFieldName && relation)) { return; } diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.test.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.test.tsx index c3d85e6b2d20f5..7e8426f78a6f56 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.test.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.test.tsx @@ -80,6 +80,7 @@ const defaultProps = { geoFields: [], openTooltips: [], hasLockedTooltips: false, + filterModeActive: false, }; const hoverTooltipState = { diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.test.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.test.tsx index 4d80f762b6a829..e6a42fb5c93932 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.test.tsx +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.test.tsx @@ -62,6 +62,7 @@ const defaultProps = { isEditButtonDisabled: false, hideTOCDetails: () => {}, showTOCDetails: () => {}, + layerIsInEditMode: false, }; describe('TOCEntry', () => { diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.test.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.test.tsx index dd85d6dd1eb6ec..5a234c0241e987 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.test.tsx +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.test.tsx @@ -46,6 +46,9 @@ const defaultProps = { removeLayer: () => {}, toggleVisible: () => {}, supportsFitToBounds: true, + enableShapeEditing: () => {}, + enablePointEditing: () => {}, + layerSettings: () => {}, }; describe('TOCEntryActionsPopover', () => { diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/feature_edit_tools.tsx similarity index 96% rename from x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx rename to x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/feature_edit_tools.tsx index 9182b3867bb7c3..48728ffd832399 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/feature_draw_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/feature_edit_tools.tsx @@ -12,14 +12,22 @@ import { DRAW_TYPE } from '../../../../../common/constants'; // @ts-expect-error import { GeometryFilterForm } from '../../../../components/draw_forms/geometry_filter_form/geometry_filter_form'; -export interface Props { - drawType: string; +export interface ReduxStateProps { + drawType?: string; +} + +export interface ReduxDispatchProps { setDrawShape: (shapeToDraw: DRAW_TYPE) => void; - pointsOnly?: boolean; cancelEditing: () => void; } -export function FeatureDrawControl(props: Props) { +export interface OwnProps { + pointsOnly?: boolean; +} + +type Props = ReduxStateProps & ReduxDispatchProps & OwnProps; + +export function FeatureEditTools(props: Props) { const drawLineSelected = props.drawType === DRAW_TYPE.LINE; const drawPolygonSelected = props.drawType === DRAW_TYPE.POLYGON; const drawCircleSelected = props.drawType === DRAW_TYPE.DISTANCE; diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/index.ts similarity index 65% rename from x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/index.ts rename to x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/index.ts index 06805dfd4d526a..46bd3184b6deda 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_draw_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/index.ts @@ -8,21 +8,26 @@ import { AnyAction } from 'redux'; import { ThunkDispatch } from 'redux-thunk'; import { connect } from 'react-redux'; -import { FeatureDrawControl } from './feature_draw_control'; +import { + FeatureEditTools, + ReduxDispatchProps, + ReduxStateProps, + OwnProps, +} from './feature_edit_tools'; import { setDrawMode, setShapeToDraw } from '../../../../actions'; import { MapStoreState } from '../../../../reducers/store'; import { DRAW_MODE, DRAW_TYPE } from '../../../../../common'; -import { getDrawMode } from '../../../../selectors/ui_selectors'; import { getShapeToDraw } from '../../../../selectors/map_selectors'; -function mapStateToProps(state: MapStoreState) { +function mapStateToProps(state: MapStoreState): ReduxStateProps { return { - filterModeActive: getDrawMode(state) === DRAW_MODE.DRAW_FILTERS, drawType: getShapeToDraw(state), }; } -function mapDispatchToProps(dispatch: ThunkDispatch) { +function mapDispatchToProps( + dispatch: ThunkDispatch +): ReduxDispatchProps { return { setDrawShape: (shapeToDraw: DRAW_TYPE) => { dispatch(setShapeToDraw(shapeToDraw)); @@ -33,8 +38,13 @@ function mapDispatchToProps(dispatch: ThunkDispatch( mapStateToProps, mapDispatchToProps -)(FeatureDrawControl); -export { connectedFeatureEditControl as FeatureDrawControl }; +)(FeatureEditTools); +export { connectedFeatureEditControl as FeatureEditTools }; diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.test.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.test.tsx index 28b5ab9c78f401..aab2e939e6cc2c 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.test.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.test.tsx @@ -21,7 +21,14 @@ import { ToolbarOverlay } from './toolbar_overlay'; test('Should only show set view control', async () => { const component = shallow( - + ); expect(component).toMatchSnapshot(); }); @@ -39,6 +46,9 @@ test('Should show all controls', async () => { geoFields={[geoFieldWithIndex]} showFitToBoundsButton={true} showTimesliderButton={true} + showEditButton={false} + shapeDrawModeActive={false} + pointDrawModeActive={false} /> ); expect(component).toMatchSnapshot(); diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx index cc882d070117cf..ebfc4e0f3716f5 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx @@ -11,7 +11,7 @@ import { Filter } from 'src/plugins/data/public'; import { ActionExecutionContext, Action } from 'src/plugins/ui_actions/public'; import { SetViewControl } from './set_view_control'; import { ToolsControl } from './tools_control'; -import { FeatureDrawControl } from './feature_draw_controls/feature_draw_control'; +import { FeatureEditTools } from './feature_draw_controls/feature_edit_tools'; import { FitToData } from './fit_to_data'; import { TimesliderToggleButton } from './timeslider_toggle_button'; import { GeoFieldWithIndex } from '../../components/geo_field_with_index'; @@ -55,7 +55,7 @@ export function ToolbarOverlay(props: Props) { const featureDrawControl = props.shapeDrawModeActive || props.pointDrawModeActive ? ( - + ) : null; diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.test.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.test.tsx index f9e0203c67add8..36533002501872 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.test.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.test.tsx @@ -20,6 +20,9 @@ const defaultProps = { indexPatternId: '1', }, ], + filterModeActive: false, + activateDrawFilterMode: () => {}, + deactivateDrawMode: () => {}, }; test('renders', async () => { diff --git a/x-pack/plugins/maps/public/reducers/map/map.ts b/x-pack/plugins/maps/public/reducers/map/map.ts index bcf00bbab72dc1..2056bd10c04e9e 100644 --- a/x-pack/plugins/maps/public/reducers/map/map.ts +++ b/x-pack/plugins/maps/public/reducers/map/map.ts @@ -47,9 +47,6 @@ import { TRACK_MAP_SETTINGS, UPDATE_MAP_SETTING, SET_SHAPE_TO_DRAW, - SET_VECTOR_LAYER_INDEX_NAME, - CLEAR_DRAWING_DATA, - REMOVE_FEATURES_FROM_INDEX_QUEUE, UPDATE_EDIT_LAYER, } from '../../actions'; @@ -85,7 +82,6 @@ export const DEFAULT_MAP_STATE: MapState = { refreshTimerLastTriggeredAt: undefined, drawState: undefined, editState: undefined, - featuresToIndexQueue: [], }, selectedLayerId: null, layerList: [], @@ -126,16 +122,6 @@ export function map(state: MapState = DEFAULT_MAP_STATE, action: any) { }, }, }; - case CLEAR_DRAWING_DATA: - return { - ...state, - mapState: { - ...state.mapState, - drawState: undefined, - shapeToDraw: undefined, - featuresToIndexQueue: [], - }, - }; case REMOVE_TRACKED_LAYER_STATE: return removeTrackedLayerState(state, action.layerId); case TRACK_CURRENT_LAYER_STATE: diff --git a/x-pack/plugins/maps/public/reducers/map/types.ts b/x-pack/plugins/maps/public/reducers/map/types.ts index 02f2161db4ca8b..1b2f50708dc875 100644 --- a/x-pack/plugins/maps/public/reducers/map/types.ts +++ b/x-pack/plugins/maps/public/reducers/map/types.ts @@ -7,7 +7,6 @@ /* eslint-disable @typescript-eslint/consistent-type-definitions */ -import { Feature } from 'geojson'; import { DrawState, EditState, @@ -41,7 +40,6 @@ export type MapContext = { refreshTimerLastTriggeredAt?: string; drawState?: DrawState; editState?: EditState; - featuresToIndexQueue: Feature[]; searchSessionId?: string; searchSessionMapBuffer?: MapExtent; }; From 69ffe2dc9b12a82b78f56f03258b5e404a3ee677 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 2 Jun 2021 18:27:20 -0600 Subject: [PATCH 065/103] i18n fixes --- .../connected_components/mb_map/draw_control/draw_tooltip.tsx | 4 ++-- .../feature_edit_tools/feature_edit_tools.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_tooltip.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_tooltip.tsx index 6cab30e6833fd7..0ba547af292bcb 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_tooltip.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_tooltip.tsx @@ -91,11 +91,11 @@ export class DrawTooltip extends Component { defaultMessage: 'Click to start shape. Click to add vertex. Double click to finish.', }); } else if (this.props.drawType === DRAW_TYPE.LINE) { - instructions = i18n.translate('xpack.maps.drawTooltip.polygonInstructions', { + instructions = i18n.translate('xpack.maps.drawTooltip.lineInstructions', { defaultMessage: 'Click to start line. Click to add vertex. Double click to finish.', }); } else if (this.props.drawType === DRAW_TYPE.POINT) { - instructions = i18n.translate('xpack.maps.drawTooltip.polygonInstructions', { + instructions = i18n.translate('xpack.maps.drawTooltip.pointInstructions', { defaultMessage: 'Click to create point.', }); } else { diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/feature_edit_tools.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/feature_edit_tools.tsx index 48728ffd832399..57299db8d96e81 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/feature_edit_tools.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/feature_edit_tools.tsx @@ -77,7 +77,7 @@ export function FeatureEditTools(props: Props) { defaultMessage: 'Draw polygon', } )} - title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawLineTitle', { + title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawPolygonTitle', { defaultMessage: 'Draw polygon', })} aria-pressed={drawPolygonSelected} From 1760b385440f3ef274d9d70a5e1510068c1edb25 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 2 Jun 2021 19:31:04 -0600 Subject: [PATCH 066/103] i18n translations --- x-pack/plugins/translations/translations/ja-JP.json | 1 - x-pack/plugins/translations/translations/zh-CN.json | 1 - 2 files changed, 2 deletions(-) diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index d1e6835b486b23..cae71459d0399e 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -13359,7 +13359,6 @@ "xpack.maps.layerControl.addLayerButtonLabel": "レイヤーを追加", "xpack.maps.layerControl.closeLayerTOCButtonAriaLabel": "レイヤーパネルを畳む", "xpack.maps.layerControl.layersTitle": "レイヤー", - "xpack.maps.layerControl.layerTocActions.editButtonLabel": "レイヤーを編集", "xpack.maps.layerControl.openLayerTOCButtonAriaLabel": "レイヤーパネルを拡張", "xpack.maps.layerControl.tocEntry.grabButtonAriaLabel": "レイヤーの並べ替え", "xpack.maps.layerControl.tocEntry.grabButtonTitle": "レイヤーの並べ替え", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 97f3ebdb733968..abd469fa647c5d 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -13535,7 +13535,6 @@ "xpack.maps.layerControl.addLayerButtonLabel": "添加图层", "xpack.maps.layerControl.closeLayerTOCButtonAriaLabel": "折叠图层面板", "xpack.maps.layerControl.layersTitle": "图层", - "xpack.maps.layerControl.layerTocActions.editButtonLabel": "编辑图层", "xpack.maps.layerControl.openLayerTOCButtonAriaLabel": "展开图层面板", "xpack.maps.layerControl.tocEntry.grabButtonAriaLabel": "重新排序图层", "xpack.maps.layerControl.tocEntry.grabButtonTitle": "重新排序图层", From 836ed627427030fb98cd4300495ecd1dec976031 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 2 Jun 2021 19:34:33 -0600 Subject: [PATCH 067/103] Fix import path --- .../features_tooltip/feature_geometry_filter_form.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/features_tooltip/feature_geometry_filter_form.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/features_tooltip/feature_geometry_filter_form.tsx index 5f26715c86004e..a4b72986d34db6 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/features_tooltip/feature_geometry_filter_form.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/features_tooltip/feature_geometry_filter_form.tsx @@ -20,7 +20,7 @@ import { } from '../../../../../common/elasticsearch_util'; import { ES_SPATIAL_RELATIONS, GEO_JSON_TYPE } from '../../../../../common/constants'; // @ts-expect-error -import { GeometryFilterForm } from '../../../../components/geometry_filter_form'; +import { GeometryFilterForm } from '../../../../components/draw_forms/geometry_filter_form/geometry_filter_form'; // over estimated and imprecise value to ensure filter has additional room for any meta keys added when filter is mapped. const META_OVERHEAD = 100; From 33e8a13b121ac637c21eddcb2d1463dce6a911b0 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Thu, 3 Jun 2021 08:25:12 -0600 Subject: [PATCH 068/103] eslint --- x-pack/plugins/maps/public/classes/sources/source.ts | 8 +++++++- .../toolbar_overlay/tools_control/tools_control.tsx | 5 +---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/sources/source.ts b/x-pack/plugins/maps/public/classes/sources/source.ts index 891d69622c8f02..bb44f845fc8f9c 100644 --- a/x-pack/plugins/maps/public/classes/sources/source.ts +++ b/x-pack/plugins/maps/public/classes/sources/source.ts @@ -12,7 +12,13 @@ import { Adapters } from 'src/plugins/inspector/public'; import { GeoJsonProperties } from 'geojson'; import { copyPersistentState } from '../../reducers/copy_persistent_state'; import { IField } from '../fields/field'; -import { FieldFormatter, LAYER_TYPE, MAX_ZOOM, MIN_ZOOM, SOURCE_TYPES } from '../../../common/constants'; +import { + FieldFormatter, + LAYER_TYPE, + MAX_ZOOM, + MIN_ZOOM, + SOURCE_TYPES, +} from '../../../common/constants'; import { AbstractSourceDescriptor, Attribution } from '../../../common/descriptor_types'; import { LICENSED_FEATURES } from '../../licensed_features'; import { PreIndexedShape } from '../../../common/elasticsearch_util'; diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx index 01e4da8e9ac4f7..125bab28174402 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx @@ -114,10 +114,7 @@ export class ToolsControl extends Component { this._closePopover(); }; - _initiateDistanceDraw = (options: { - actionId: string; - filterLabel: string; - }) => { + _initiateDistanceDraw = (options: { actionId: string; filterLabel: string }) => { this.props.activateDrawFilterMode({ drawType: DRAW_TYPE.DISTANCE, ...options, From d2e1c47dbbc03aab1fbc30e10b607c1db083b7c6 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Thu, 3 Jun 2021 09:04:53 -0600 Subject: [PATCH 069/103] Type fixes --- .../geometry_filter_form.tsx | 43 +++++++++++-------- .../feature_geometry_filter_form.tsx | 1 - .../toolbar_overlay/toolbar_overlay.test.tsx | 4 +- .../tools_control/tools_control.tsx | 1 - 4 files changed, 28 insertions(+), 21 deletions(-) diff --git a/x-pack/plugins/maps/public/components/draw_forms/geometry_filter_form/geometry_filter_form.tsx b/x-pack/plugins/maps/public/components/draw_forms/geometry_filter_form/geometry_filter_form.tsx index a4624addacf354..47dd75ca99419d 100644 --- a/x-pack/plugins/maps/public/components/draw_forms/geometry_filter_form/geometry_filter_form.tsx +++ b/x-pack/plugins/maps/public/components/draw_forms/geometry_filter_form/geometry_filter_form.tsx @@ -5,8 +5,7 @@ * 2.0. */ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; +import React, { ChangeEvent, Component } from 'react'; import { EuiForm, EuiFormRow, @@ -22,19 +21,29 @@ import { ES_SPATIAL_RELATIONS } from '../../../../common/constants'; import { getEsSpatialRelationLabel } from '../../../../common/i18n_getters'; import { ActionSelect } from '../../action_select'; import { ACTION_GLOBAL_APPLY_FILTER } from '../../../../../../../src/plugins/data/public'; +import { Action, ActionExecutionContext } from '../../../../../../../src/plugins/ui_actions/public'; + +interface Props { + buttonLabel: string; + getFilterActions?: () => Promise; + getActionContext?: () => ActionExecutionContext; + intitialGeometryLabel: string; + onSubmit: ({ + actionId, + geometryLabel, + relation, + }: { + actionId: string; + geometryLabel: string; + relation: ES_SPATIAL_RELATIONS; + }) => void; + isFilterGeometryClosed?: boolean; + errorMsg?: string; + className?: string; + isLoading?: boolean; +} -export class GeometryFilterForm extends Component { - static propTypes = { - buttonLabel: PropTypes.string.isRequired, - getFilterActions: PropTypes.func, - getActionContext: PropTypes.func, - intitialGeometryLabel: PropTypes.string.isRequired, - onSubmit: PropTypes.func.isRequired, - isFilterGeometryClosed: PropTypes.bool, - errorMsg: PropTypes.string, - className: PropTypes.string, - }; - +export class GeometryFilterForm extends Component { static defaultProps = { isFilterGeometryClosed: true, }; @@ -45,19 +54,19 @@ export class GeometryFilterForm extends Component { relation: ES_SPATIAL_RELATIONS.INTERSECTS, }; - _onGeometryLabelChange = (e) => { + _onGeometryLabelChange = (e: ChangeEvent) => { this.setState({ geometryLabel: e.target.value, }); }; - _onRelationChange = (e) => { + _onRelationChange = (e: ChangeEvent) => { this.setState({ relation: e.target.value, }); }; - _onActionIdChange = (value) => { + _onActionIdChange = (value: string) => { this.setState({ actionId: value }); }; diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/features_tooltip/feature_geometry_filter_form.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/features_tooltip/feature_geometry_filter_form.tsx index a4b72986d34db6..d5ed944f7e7c8c 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/features_tooltip/feature_geometry_filter_form.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/features_tooltip/feature_geometry_filter_form.tsx @@ -19,7 +19,6 @@ import { PreIndexedShape, } from '../../../../../common/elasticsearch_util'; import { ES_SPATIAL_RELATIONS, GEO_JSON_TYPE } from '../../../../../common/constants'; -// @ts-expect-error import { GeometryFilterForm } from '../../../../components/draw_forms/geometry_filter_form/geometry_filter_form'; // over estimated and imprecise value to ensure filter has additional room for any meta keys added when filter is mapped. diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.test.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.test.tsx index 522ec239833119..4faa214b75a834 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.test.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.test.tsx @@ -22,7 +22,7 @@ import { ToolbarOverlay } from './toolbar_overlay'; test('Should only show set view control', async () => { const component = shallow( { test('Should show all controls', async () => { const component = shallow( {}} showFitToBoundsButton={true} diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx index 125bab28174402..cf535fc8fb97d3 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx @@ -55,7 +55,6 @@ const DRAW_DISTANCE_LABEL_SHORT = i18n.translate( export interface Props { cancelDraw: () => void; filterModeActive: boolean; - initiateDraw: (drawState: DrawState) => void; getFilterActions?: () => Promise; getActionContext?: () => ActionExecutionContext; activateDrawFilterMode: (drawState: DrawState) => void; From a57a65f38d95ee32eca721435e1f6e01f82ebaa1 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Thu, 3 Jun 2021 09:07:23 -0600 Subject: [PATCH 070/103] Update snapshot --- .../geometry_filter_form.test.js.snap | 144 ++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 x-pack/plugins/maps/public/components/draw_forms/geometry_filter_form/__snapshots__/geometry_filter_form.test.js.snap diff --git a/x-pack/plugins/maps/public/components/draw_forms/geometry_filter_form/__snapshots__/geometry_filter_form.test.js.snap b/x-pack/plugins/maps/public/components/draw_forms/geometry_filter_form/__snapshots__/geometry_filter_form.test.js.snap new file mode 100644 index 00000000000000..80238bf3a4d17f --- /dev/null +++ b/x-pack/plugins/maps/public/components/draw_forms/geometry_filter_form/__snapshots__/geometry_filter_form.test.js.snap @@ -0,0 +1,144 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`render 1`] = ` + + + + + + + + + + + + Create filter + + + +`; + +exports[`should render error message 1`] = ` + + + + + + + + + + + Simulated error + + + + Create filter + + + +`; From 44ac82bafc4f144b1fdeef416897f32eb800e09d Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Thu, 3 Jun 2021 09:12:09 -0600 Subject: [PATCH 071/103] Clean up snapshots --- .../geometry_filter_form.test.js.snap | 144 ----------- .../feature_edit_control.test.tsx.snap | 242 ------------------ 2 files changed, 386 deletions(-) delete mode 100644 x-pack/plugins/maps/public/components/__snapshots__/geometry_filter_form.test.js.snap delete mode 100644 x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/__snapshots__/feature_edit_control.test.tsx.snap diff --git a/x-pack/plugins/maps/public/components/__snapshots__/geometry_filter_form.test.js.snap b/x-pack/plugins/maps/public/components/__snapshots__/geometry_filter_form.test.js.snap deleted file mode 100644 index 80238bf3a4d17f..00000000000000 --- a/x-pack/plugins/maps/public/components/__snapshots__/geometry_filter_form.test.js.snap +++ /dev/null @@ -1,144 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`render 1`] = ` - - - - - - - - - - - - Create filter - - - -`; - -exports[`should render error message 1`] = ` - - - - - - - - - - - Simulated error - - - - Create filter - - - -`; diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/__snapshots__/feature_edit_control.test.tsx.snap b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/__snapshots__/feature_edit_control.test.tsx.snap deleted file mode 100644 index 076f4690143d92..00000000000000 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/__snapshots__/feature_edit_control.test.tsx.snap +++ /dev/null @@ -1,242 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Should render cancel button when drawing 1`] = ` - - - - } - closePopover={[Function]} - display="inlineBlock" - hasArrow={true} - id="FeatureEditControlPopover" - isOpen={false} - ownFocus={false} - panelPaddingSize="none" - > - , - "id": 1, - "title": "Draw shape", - }, - Object { - "content": , - "id": 2, - "title": "Draw bounds", - }, - Object { - "content": , - "id": 3, - "title": "Draw distance", - }, - ] - } - size="m" - /> - - - - - - - - -`; - -exports[`renders 1`] = ` - - } - closePopover={[Function]} - display="inlineBlock" - hasArrow={true} - id="FeatureEditControlPopover" - isOpen={false} - ownFocus={false} - panelPaddingSize="none" -> - , - "id": 1, - "title": "Draw shape", - }, - Object { - "content": , - "id": 2, - "title": "Draw bounds", - }, - Object { - "content": , - "id": 3, - "title": "Draw distance", - }, - ] - } - size="m" - /> - -`; From 91769265f8fee6091276a301b7adbbc47f0ddc2c Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Thu, 3 Jun 2021 17:18:57 -0600 Subject: [PATCH 072/103] Lots of clean up --- x-pack/plugins/maps/common/constants.ts | 3 +- .../common/descriptor_types/map_descriptor.ts | 8 ++--- .../public/actions/data_request_actions.ts | 2 +- .../public/actions/map_action_constants.ts | 4 +-- .../maps/public/actions/map_actions.ts | 28 +++++++-------- .../classes/layers/vector_layer/utils.tsx | 10 +++--- .../maps/public/classes/sources/source.ts | 13 +------ .../draw_forms/distance_filter_form.tsx | 4 +-- .../mb_map/draw_control/draw_control.tsx | 34 +++++++------------ .../draw_feature_control.tsx | 10 +++--- .../draw_feature_control/index.ts | 9 +++-- .../draw_filter_control.tsx | 10 +++--- .../mb_map/draw_control/draw_tooltip.tsx | 14 ++++---- .../mb_map/draw_control/index.ts | 8 ++--- .../layer_toc/toc_entry/index.ts | 2 +- .../layer_toc/toc_entry/toc_entry.test.tsx | 2 +- .../layer_toc/toc_entry/toc_entry.tsx | 4 +-- .../feature_edit_tools/feature_edit_tools.tsx | 26 +++++++------- .../feature_edit_tools/index.ts | 10 +++--- .../toolbar_overlay/index.ts | 5 ++- .../toolbar_overlay/toolbar_overlay.test.tsx | 2 -- .../toolbar_overlay/toolbar_overlay.tsx | 1 - .../toolbar_overlay/tools_control/index.ts | 2 +- .../tools_control/tools_control.tsx | 20 +++++------ .../plugins/maps/public/reducers/map/map.ts | 10 +++--- .../maps/public/selectors/map_selectors.ts | 11 ++---- x-pack/plugins/maps/public/util.ts | 6 +--- 27 files changed, 110 insertions(+), 148 deletions(-) diff --git a/x-pack/plugins/maps/common/constants.ts b/x-pack/plugins/maps/common/constants.ts index 3b05f2111ff329..16dfe5567898d7 100644 --- a/x-pack/plugins/maps/common/constants.ts +++ b/x-pack/plugins/maps/common/constants.ts @@ -162,14 +162,13 @@ export enum DRAW_MODE { NONE = 'NONE', } -export enum DRAW_TYPE { +export enum DRAW_SHAPE { BOUNDS = 'BOUNDS', DISTANCE = 'DISTANCE', POLYGON = 'POLYGON', POINT = 'POINT', LINE = 'LINE', SIMPLE_SELECT = 'SIMPLE_SELECT', - TRASH = 'TRASH', } export const AGG_DELIMITER = '_of_'; diff --git a/x-pack/plugins/maps/common/descriptor_types/map_descriptor.ts b/x-pack/plugins/maps/common/descriptor_types/map_descriptor.ts index dc57d88dd11fc4..cb2da42e771c61 100644 --- a/x-pack/plugins/maps/common/descriptor_types/map_descriptor.ts +++ b/x-pack/plugins/maps/common/descriptor_types/map_descriptor.ts @@ -11,7 +11,7 @@ import { ReactNode } from 'react'; import { GeoJsonProperties } from 'geojson'; import { Geometry } from 'geojson'; import { Query } from '../../../../../src/plugins/data/common'; -import { DRAW_TYPE, ES_SPATIAL_RELATIONS } from '../constants'; +import { DRAW_SHAPE, ES_SPATIAL_RELATIONS } from '../constants'; export type MapExtent = { minLon: number; @@ -68,15 +68,13 @@ export type TooltipState = { export type DrawState = { actionId: string; - drawType?: DRAW_TYPE; + drawShape?: DRAW_SHAPE; filterLabel?: string; // point radius filter alias geometryLabel?: string; - indexPatternId?: string; - indexPatternTitle?: string; relation?: ES_SPATIAL_RELATIONS; }; export type EditState = { layerId?: string; - drawType?: DRAW_TYPE; + drawShape?: DRAW_SHAPE; }; diff --git a/x-pack/plugins/maps/public/actions/data_request_actions.ts b/x-pack/plugins/maps/public/actions/data_request_actions.ts index b9e696eaa915df..970303fe05edbe 100644 --- a/x-pack/plugins/maps/public/actions/data_request_actions.ts +++ b/x-pack/plugins/maps/public/actions/data_request_actions.ts @@ -115,7 +115,7 @@ function getDataRequestContext( dispatch: ThunkDispatch, getState: () => MapStoreState, layerId: string, - forceRefresh: boolean = true + forceRefresh: boolean = false, ): DataRequestContext { return { dataFilters: getDataFilters(getState()), diff --git a/x-pack/plugins/maps/public/actions/map_action_constants.ts b/x-pack/plugins/maps/public/actions/map_action_constants.ts index 7b4a575622c55a..b67da9950b9df7 100644 --- a/x-pack/plugins/maps/public/actions/map_action_constants.ts +++ b/x-pack/plugins/maps/public/actions/map_action_constants.ts @@ -38,8 +38,8 @@ 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_OPEN_TOOLTIPS = 'SET_OPEN_TOOLTIPS'; export const UPDATE_DRAW_STATE = 'UPDATE_DRAW_STATE'; -export const UPDATE_EDIT_LAYER = 'UPDATE_EDIT_LAYER'; -export const SET_SHAPE_TO_DRAW = 'SET_SHAPE_TO_DRAW'; +export const UPDATE_EDIT_STATE_LAYER = 'UPDATE_EDIT_STATE_LAYER'; +export const UPDATE_EDIT_STATE_SHAPE = 'UPDATE_EDIT_STATE_SHAPE'; export const SET_SCROLL_ZOOM = 'SET_SCROLL_ZOOM'; export const SET_MAP_INIT_ERROR = 'SET_MAP_INIT_ERROR'; export const SET_WAITING_FOR_READY_HIDDEN_LAYERS = 'SET_WAITING_FOR_READY_HIDDEN_LAYERS'; diff --git a/x-pack/plugins/maps/public/actions/map_actions.ts b/x-pack/plugins/maps/public/actions/map_actions.ts index 4191a73c9939df..d275dadd353e5d 100644 --- a/x-pack/plugins/maps/public/actions/map_actions.ts +++ b/x-pack/plugins/maps/public/actions/map_actions.ts @@ -12,7 +12,7 @@ import turfBboxPolygon from '@turf/bbox-polygon'; import turfBooleanContains from '@turf/boolean-contains'; import { Filter, Query, TimeRange } from 'src/plugins/data/public'; import { Geometry, Position } from 'geojson'; -import { DRAW_TYPE } from '../../common/constants'; +import { DRAW_SHAPE } from '../../common/constants'; import { MapStoreState } from '../reducers/store'; import { getDataFilters, @@ -47,9 +47,9 @@ import { TRACK_MAP_SETTINGS, TRIGGER_REFRESH_TIMER, UPDATE_DRAW_STATE, - SET_SHAPE_TO_DRAW, + UPDATE_EDIT_STATE_SHAPE, UPDATE_MAP_SETTING, - UPDATE_EDIT_LAYER, + UPDATE_EDIT_STATE_LAYER, } from './map_action_constants'; import { autoFitToBounds, syncDataForAllLayers, syncDataForLayer } from './data_request_actions'; import { addLayer, addLayerWithoutDataSync } from './layer_actions'; @@ -339,15 +339,6 @@ export function triggerRefreshTimer() { }; } -export function setShapeToDraw(shapeToDraw: DRAW_TYPE | null) { - return (dispatch: Dispatch) => { - dispatch({ - type: SET_SHAPE_TO_DRAW, - shapeToDraw, - }); - }; -} - export function updateDrawState(drawState: DrawState | null) { return (dispatch: Dispatch) => { if (drawState !== null) { @@ -360,13 +351,22 @@ export function updateDrawState(drawState: DrawState | null) { }; } +export function updateEditShape(shapeToDraw: DRAW_SHAPE | null) { + return (dispatch: Dispatch) => { + dispatch({ + type: UPDATE_EDIT_STATE_SHAPE, + shapeToDraw, + }); + }; +} + export function updateEditLayer(layerId: string | null) { return (dispatch: Dispatch) => { if (layerId !== null) { - dispatch({ type: SET_OPEN_TOOLTIPS, openTooltips: [] }); // tooltips just get in the way + dispatch({ type: SET_OPEN_TOOLTIPS, openTooltips: [] }); } dispatch({ - type: UPDATE_EDIT_LAYER, + type: UPDATE_EDIT_STATE_LAYER, layerId, }); }; diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/utils.tsx b/x-pack/plugins/maps/public/classes/layers/vector_layer/utils.tsx index a330a7ff3ae3e1..8d5c4f83409079 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/utils.tsx +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/utils.tsx @@ -69,15 +69,15 @@ export async function syncVectorSource({ } = syncContext; const dataRequestId = SOURCE_DATA_REQUEST_ID; const requestToken = Symbol(`${layerId}-${dataRequestId}`); - const canSkipFetch = !syncContext.forceRefresh - ? await canSkipSourceUpdate({ + const doRefresh = syncContext.forceRefresh + ? syncContext.forceRefresh + : !(await canSkipSourceUpdate({ source, prevDataRequest, nextMeta: requestMeta, extentAware: source.isFilterByMapBounds(), - }) - : !syncContext.forceRefresh; - if (canSkipFetch) { + })); + if (!doRefresh) { return { refreshed: false, featureCollection: prevDataRequest diff --git a/x-pack/plugins/maps/public/classes/sources/source.ts b/x-pack/plugins/maps/public/classes/sources/source.ts index bb44f845fc8f9c..3e34e30d2c5a19 100644 --- a/x-pack/plugins/maps/public/classes/sources/source.ts +++ b/x-pack/plugins/maps/public/classes/sources/source.ts @@ -12,13 +12,7 @@ import { Adapters } from 'src/plugins/inspector/public'; import { GeoJsonProperties } from 'geojson'; import { copyPersistentState } from '../../reducers/copy_persistent_state'; import { IField } from '../fields/field'; -import { - FieldFormatter, - LAYER_TYPE, - MAX_ZOOM, - MIN_ZOOM, - SOURCE_TYPES, -} from '../../../common/constants'; +import { FieldFormatter, LAYER_TYPE, MAX_ZOOM, MIN_ZOOM } from '../../../common/constants'; import { AbstractSourceDescriptor, Attribution } from '../../../common/descriptor_types'; import { LICENSED_FEATURES } from '../../licensed_features'; import { PreIndexedShape } from '../../../common/elasticsearch_util'; @@ -60,7 +54,6 @@ export interface ISource { getJoinsDisabledReason(): string | null; cloneDescriptor(): AbstractSourceDescriptor; getFieldNames(): string[]; - getType(): SOURCE_TYPES; getApplyGlobalQuery(): boolean; getApplyGlobalTime(): boolean; getIndexPatternIds(): string[]; @@ -137,10 +130,6 @@ export class AbstractSource implements ISource { return []; } - getType(): SOURCE_TYPES { - return this._descriptor.type as SOURCE_TYPES; - } - renderSourceSettingsEditor(sourceEditorArgs: SourceEditorArgs): ReactElement | null { return null; } diff --git a/x-pack/plugins/maps/public/components/draw_forms/distance_filter_form.tsx b/x-pack/plugins/maps/public/components/draw_forms/distance_filter_form.tsx index b322cac767cebc..ed2b79d911ca56 100644 --- a/x-pack/plugins/maps/public/components/draw_forms/distance_filter_form.tsx +++ b/x-pack/plugins/maps/public/components/draw_forms/distance_filter_form.tsx @@ -16,10 +16,10 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { ActionExecutionContext, Action } from 'src/plugins/ui_actions/public'; -import { ACTION_GLOBAL_APPLY_FILTER } from '../../../../../../src/plugins/data/public'; import { ActionSelect } from '../action_select'; +import { ACTION_GLOBAL_APPLY_FILTER } from '../../../../../../src/plugins/data/public'; -export interface Props { +interface Props { className?: string; buttonLabel: string; getFilterActions?: () => Promise; diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx index 0a1922455e379e..5d35094a21c0a8 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx @@ -13,7 +13,7 @@ import MapboxDraw from '@mapbox/mapbox-gl-draw'; import DrawRectangle from 'mapbox-gl-draw-rectangle-mode'; import type { Map as MbMap } from '@kbn/mapbox-gl'; import { Feature } from 'geojson'; -import { DRAW_TYPE } from '../../../../common/constants'; +import { DRAW_SHAPE } from '../../../../common/constants'; import { DrawCircle } from './draw_circle'; import { DrawTooltip } from './draw_tooltip'; @@ -38,11 +38,11 @@ mbDrawModes[DRAW_RECTANGLE] = DrawRectangle; mbDrawModes[DRAW_CIRCLE] = DrawCircle; export interface Props { - drawType?: DRAW_TYPE; + drawShape?: DRAW_SHAPE; onDraw: (drawControl: MapboxDraw) => (event: { features: Feature[] }) => void; mbMap: MbMap; drawActive: boolean; - setShapeToDraw: (shapeToDraw: DRAW_TYPE) => void; + updateEditShape: (shapeToDraw: DRAW_SHAPE) => void; } export class DrawControl extends Component { @@ -85,7 +85,7 @@ export class DrawControl extends Component { _onModeChange = ({ mode }: { mode: string }) => { if (mbModeEquivalencies.has(mode)) { - this.props.setShapeToDraw(mbModeEquivalencies.get(mode) as DRAW_TYPE); + this.props.updateEditShape(mbModeEquivalencies.get(mode) as DRAW_SHAPE); } }; @@ -104,7 +104,7 @@ export class DrawControl extends Component { } _updateDrawControl() { - if (!this.props.drawType) { + if (!this.props.drawShape) { return; } @@ -118,35 +118,27 @@ export class DrawControl extends Component { } } - if (this.props.drawType === DRAW_TYPE.TRASH) { - // There is no way to deselect shapes other than changing modes, - // this deselects shapes to avoid leaving shapes in an unwanted - // edit mode - this._mbDrawControl.changeMode('simple_select'); - return; - } - const drawMode = this._mbDrawControl.getMode(); - if (drawMode !== DRAW_RECTANGLE && this.props.drawType === DRAW_TYPE.BOUNDS) { + if (drawMode !== DRAW_RECTANGLE && this.props.drawShape === DRAW_SHAPE.BOUNDS) { this._mbDrawControl.changeMode(DRAW_RECTANGLE); - } else if (drawMode !== DRAW_CIRCLE && this.props.drawType === DRAW_TYPE.DISTANCE) { + } else if (drawMode !== DRAW_CIRCLE && this.props.drawShape === DRAW_SHAPE.DISTANCE) { this._mbDrawControl.changeMode(DRAW_CIRCLE); - } else if (drawMode !== DRAW_POLYGON && this.props.drawType === DRAW_TYPE.POLYGON) { + } else if (drawMode !== DRAW_POLYGON && this.props.drawShape === DRAW_SHAPE.POLYGON) { this._mbDrawControl.changeMode(DRAW_POLYGON); - } else if (drawMode !== DRAW_LINE && this.props.drawType === DRAW_TYPE.LINE) { + } else if (drawMode !== DRAW_LINE && this.props.drawShape === DRAW_SHAPE.LINE) { this._mbDrawControl.changeMode(DRAW_LINE); - } else if (drawMode !== DRAW_POINT && this.props.drawType === DRAW_TYPE.POINT) { + } else if (drawMode !== DRAW_POINT && this.props.drawShape === DRAW_SHAPE.POINT) { this._mbDrawControl.changeMode(DRAW_POINT); - } else if (drawMode !== SIMPLE_SELECT && this.props.drawType === DRAW_TYPE.SIMPLE_SELECT) { + } else if (drawMode !== SIMPLE_SELECT && this.props.drawShape === DRAW_SHAPE.SIMPLE_SELECT) { this._mbDrawControl.changeMode(SIMPLE_SELECT); } } render() { - if (!this.props.drawType) { + if (!this.props.drawShape) { return null; } - return ; + return ; } } diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx index 36b7a781f9095e..f415a3566d2a68 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx @@ -15,14 +15,12 @@ import { i18n } from '@kbn/i18n'; import * as jsts from 'jsts'; import { getToasts } from '../../../../kibana_services'; import { DrawControl } from '../'; -import { DRAW_MODE, DRAW_TYPE } from '../../../../../common'; -import { DrawState } from '../../../../../common/descriptor_types'; +import { DRAW_MODE, DRAW_SHAPE } from '../../../../../common'; const geoJSONReader = new jsts.io.GeoJSONReader(); export interface ReduxStateProps { - drawType?: DRAW_TYPE; - drawState?: DrawState; + drawShape?: DRAW_SHAPE; drawMode: DRAW_MODE; } @@ -72,7 +70,7 @@ export class DrawFeatureControl extends Component { try { mbDrawControl.deleteAll(); } catch (_e) { - // Fail silently. Always works, but sometimes produces an upstream error in the draw tool + // Fail silently. Always works, but sometimes produces an upstream error in the mb draw lib } } }; @@ -80,7 +78,7 @@ export class DrawFeatureControl extends Component { render() { return ( { } let filter: Filter | undefined; - if (this.props.drawState.drawType === DRAW_TYPE.DISTANCE) { + if (this.props.drawState.drawShape === DRAW_SHAPE.DISTANCE) { const circle = e.features[0] as Feature & { properties: DrawCircleProperties }; const distanceKm = _.round( circle.properties.radiusKm, @@ -70,7 +70,7 @@ export class DrawFilterControl extends Component { filter = createSpatialFilterWithGeometry({ geometry: - this.props.drawState.drawType === DRAW_TYPE.BOUNDS + this.props.drawState.drawShape === DRAW_SHAPE.BOUNDS ? getBoundingBoxGeometry(geometry) : geometry, geoFieldNames: this.props.geoFieldNames, @@ -100,9 +100,9 @@ export class DrawFilterControl extends Component { render() { return ( {}; interface Props { mbMap: MbMap; - drawType: DRAW_TYPE; + drawShape: DRAW_SHAPE; } interface State { @@ -77,24 +77,24 @@ export class DrawTooltip extends Component { } let instructions; - if (this.props.drawType === DRAW_TYPE.BOUNDS) { + if (this.props.drawShape === DRAW_SHAPE.BOUNDS) { instructions = i18n.translate('xpack.maps.drawTooltip.boundsInstructions', { defaultMessage: 'Click to start rectangle. Move mouse to adjust rectangle size. Click again to finish.', }); - } else if (this.props.drawType === DRAW_TYPE.DISTANCE) { + } else if (this.props.drawShape === DRAW_SHAPE.DISTANCE) { instructions = i18n.translate('xpack.maps.drawTooltip.distanceInstructions', { defaultMessage: 'Click to set point. Move mouse to adjust distance. Click to finish.', }); - } else if (this.props.drawType === DRAW_TYPE.POLYGON) { + } else if (this.props.drawShape === DRAW_SHAPE.POLYGON) { instructions = i18n.translate('xpack.maps.drawTooltip.polygonInstructions', { defaultMessage: 'Click to start shape. Click to add vertex. Double click to finish.', }); - } else if (this.props.drawType === DRAW_TYPE.LINE) { + } else if (this.props.drawShape === DRAW_SHAPE.LINE) { instructions = i18n.translate('xpack.maps.drawTooltip.lineInstructions', { defaultMessage: 'Click to start line. Click to add vertex. Double click to finish.', }); - } else if (this.props.drawType === DRAW_TYPE.POINT) { + } else if (this.props.drawShape === DRAW_SHAPE.POINT) { instructions = i18n.translate('xpack.maps.drawTooltip.pointInstructions', { defaultMessage: 'Click to create point.', }); diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/index.ts b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/index.ts index e0686a0202f94e..847b0f2e429e2e 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/index.ts @@ -8,15 +8,15 @@ import { ThunkDispatch } from 'redux-thunk'; import { AnyAction } from 'redux'; import { connect } from 'react-redux'; -import { setShapeToDraw } from '../../../actions'; +import { updateEditShape } from '../../../actions'; import { MapStoreState } from '../../../reducers/store'; import { DrawControl } from './draw_control'; -import { DRAW_TYPE } from '../../../../common'; +import { DRAW_SHAPE } from '../../../../common'; function mapDispatchToProps(dispatch: ThunkDispatch) { return { - setShapeToDraw(shapeToDraw: DRAW_TYPE) { - dispatch(setShapeToDraw(shapeToDraw)); + updateEditShape(shapeToDraw: DRAW_SHAPE) { + dispatch(updateEditShape(shapeToDraw)); }, }; } diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/index.ts b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/index.ts index 272d8e21d138db..662234dd36b59c 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/index.ts +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/index.ts @@ -43,7 +43,7 @@ function mapStateToProps(state: MapStoreState, ownProps: OwnProps): ReduxStatePr isLegendDetailsOpen: getOpenTOCDetails(state).includes(ownProps.layer.getId()), isEditButtonDisabled: flyoutDisplay !== FLYOUT_STATE.NONE && flyoutDisplay !== FLYOUT_STATE.LAYER_PANEL, - layerIsInEditMode: + editModeActiveForLayer: (getDrawMode(state) === DRAW_MODE.DRAW_SHAPES || getDrawMode(state) === DRAW_MODE.DRAW_POINTS) && getEditingLayer(state) === ownProps.layer.getId(), diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.test.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.test.tsx index e6a42fb5c93932..e6439f80411d15 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.test.tsx +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.test.tsx @@ -62,7 +62,7 @@ const defaultProps = { isEditButtonDisabled: false, hideTOCDetails: () => {}, showTOCDetails: () => {}, - layerIsInEditMode: false, + editModeActiveForLayer: false, }; describe('TOCEntry', () => { diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.tsx index 0e356ad6b5b231..62333a56b4db75 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.tsx +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.tsx @@ -31,7 +31,7 @@ export interface ReduxStateProps { hasDirtyStateSelector: boolean; isLegendDetailsOpen: boolean; isEditButtonDisabled: boolean; - layerIsInEditMode: boolean; + editModeActiveForLayer: boolean; } export interface ReduxDispatchProps { @@ -315,7 +315,7 @@ export class TOCEntry extends Component { 'mapTocEntry-isSelected': this.props.layer.isPreviewLayer() || (this.props.selectedLayer && this.props.selectedLayer.getId() === this.props.layer.getId()), - 'mapTocEntry-isInEditingMode': this.props.layerIsInEditMode, + 'mapTocEntry-isInEditingMode': this.props.editModeActiveForLayer, }); return ( diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/feature_edit_tools.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/feature_edit_tools.tsx index 57299db8d96e81..73776e6f168dbc 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/feature_edit_tools.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/feature_edit_tools.tsx @@ -8,16 +8,16 @@ import React from 'react'; import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { DRAW_TYPE } from '../../../../../common/constants'; +import { DRAW_SHAPE } from '../../../../../common/constants'; // @ts-expect-error import { GeometryFilterForm } from '../../../../components/draw_forms/geometry_filter_form/geometry_filter_form'; export interface ReduxStateProps { - drawType?: string; + drawShape?: string; } export interface ReduxDispatchProps { - setDrawShape: (shapeToDraw: DRAW_TYPE) => void; + setDrawShape: (shapeToDraw: DRAW_SHAPE) => void; cancelEditing: () => void; } @@ -28,11 +28,11 @@ export interface OwnProps { type Props = ReduxStateProps & ReduxDispatchProps & OwnProps; export function FeatureEditTools(props: Props) { - const drawLineSelected = props.drawType === DRAW_TYPE.LINE; - const drawPolygonSelected = props.drawType === DRAW_TYPE.POLYGON; - const drawCircleSelected = props.drawType === DRAW_TYPE.DISTANCE; - const drawBBoxSelected = props.drawType === DRAW_TYPE.BOUNDS; - const drawPointSelected = props.drawType === DRAW_TYPE.POINT; + const drawLineSelected = props.drawShape === DRAW_SHAPE.LINE; + const drawPolygonSelected = props.drawShape === DRAW_SHAPE.POLYGON; + const drawCircleSelected = props.drawShape === DRAW_SHAPE.DISTANCE; + const drawBBoxSelected = props.drawShape === DRAW_SHAPE.BOUNDS; + const drawPointSelected = props.drawShape === DRAW_SHAPE.POINT; return ( @@ -46,7 +46,7 @@ export function FeatureEditTools(props: Props) { > props.setDrawShape(DRAW_TYPE.LINE)} + onClick={() => props.setDrawShape(DRAW_SHAPE.LINE)} iconType="minus" aria-label={i18n.translate( 'xpack.maps.toolbarOverlay.featureDraw.drawLineLabel', @@ -69,7 +69,7 @@ export function FeatureEditTools(props: Props) { > props.setDrawShape(DRAW_TYPE.POLYGON)} + onClick={() => props.setDrawShape(DRAW_SHAPE.POLYGON)} iconType="node" aria-label={i18n.translate( 'xpack.maps.toolbarOverlay.featureDraw.drawPolygonLabel', @@ -92,7 +92,7 @@ export function FeatureEditTools(props: Props) { > props.setDrawShape(DRAW_TYPE.DISTANCE)} + onClick={() => props.setDrawShape(DRAW_SHAPE.DISTANCE)} iconType="plusInCircle" aria-label={i18n.translate( 'xpack.maps.toolbarOverlay.featureDraw.drawCircleLabel', @@ -115,7 +115,7 @@ export function FeatureEditTools(props: Props) { > props.setDrawShape(DRAW_TYPE.BOUNDS)} + onClick={() => props.setDrawShape(DRAW_SHAPE.BOUNDS)} iconType="stop" aria-label={i18n.translate( 'xpack.maps.toolbarOverlay.featureDraw.drawBBoxLabel', @@ -140,7 +140,7 @@ export function FeatureEditTools(props: Props) { > props.setDrawShape(DRAW_TYPE.POINT)} + onClick={() => props.setDrawShape(DRAW_SHAPE.POINT)} iconType="dot" aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawPointLabel', { defaultMessage: 'Draw point', diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/index.ts index 46bd3184b6deda..07988fe3f83cde 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/index.ts @@ -14,14 +14,14 @@ import { ReduxStateProps, OwnProps, } from './feature_edit_tools'; -import { setDrawMode, setShapeToDraw } from '../../../../actions'; +import { setDrawMode, updateEditShape } from '../../../../actions'; import { MapStoreState } from '../../../../reducers/store'; -import { DRAW_MODE, DRAW_TYPE } from '../../../../../common'; +import { DRAW_MODE, DRAW_SHAPE } from '../../../../../common'; import { getShapeToDraw } from '../../../../selectors/map_selectors'; function mapStateToProps(state: MapStoreState): ReduxStateProps { return { - drawType: getShapeToDraw(state), + drawShape: getShapeToDraw(state), }; } @@ -29,8 +29,8 @@ function mapDispatchToProps( dispatch: ThunkDispatch ): ReduxDispatchProps { return { - setDrawShape: (shapeToDraw: DRAW_TYPE) => { - dispatch(setShapeToDraw(shapeToDraw)); + setDrawShape: (shapeToDraw: DRAW_SHAPE) => { + dispatch(updateEditShape(shapeToDraw)); }, cancelEditing: () => { dispatch(setDrawMode(DRAW_MODE.NONE)); diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts index 38f999c1742c12..d98d24a313ec5e 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts @@ -9,13 +9,12 @@ import { connect } from 'react-redux'; import { ToolbarOverlay } from './toolbar_overlay'; import { MapStoreState } from '../../reducers/store'; import { getDrawMode } from '../../selectors/ui_selectors'; -import { getGeoFieldNames, getLayersBySourceType } from '../../selectors/map_selectors'; -import { DRAW_MODE, SOURCE_TYPES } from '../../../common'; +import { getGeoFieldNames } from '../../selectors/map_selectors'; +import { DRAW_MODE } from '../../../common'; function mapStateToProps(state: MapStoreState) { return { showToolsControl: getGeoFieldNames(state).length !== 0, - showEditButton: !!getLayersBySourceType(SOURCE_TYPES.ES_SEARCH, state).length, shapeDrawModeActive: getDrawMode(state) === DRAW_MODE.DRAW_SHAPES, pointDrawModeActive: getDrawMode(state) === DRAW_MODE.DRAW_POINTS, }; diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.test.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.test.tsx index 4faa214b75a834..240f620102cd23 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.test.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.test.tsx @@ -23,7 +23,6 @@ test('Should only show set view control', async () => { const component = shallow( { const component = shallow( {}} showFitToBoundsButton={true} showTimesliderButton={true} diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx index e9491848b5d8a8..23cf6039a1d880 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx @@ -20,7 +20,6 @@ export interface Props { showToolsControl: boolean; getFilterActions?: () => Promise; getActionContext?: () => ActionExecutionContext; - showEditButton: boolean; shapeDrawModeActive: boolean; pointDrawModeActive: boolean; showFitToBoundsButton: boolean; diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts index 8e78e3439531b6..49ce77661b1c8e 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts @@ -28,7 +28,7 @@ function mapDispatchToProps(dispatch: ThunkDispatch { + initiateDraw: (drawState: DrawState) => { dispatch(setDrawMode(DRAW_MODE.DRAW_FILTERS)); dispatch(updateDrawState(drawState)); }, diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx index cf535fc8fb97d3..2d986c8a13c7a3 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx @@ -18,7 +18,7 @@ import { import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { ActionExecutionContext, Action } from 'src/plugins/ui_actions/public'; -import { DRAW_TYPE, ES_GEO_FIELD_TYPE, ES_SPATIAL_RELATIONS } from '../../../../common/constants'; +import { DRAW_SHAPE, ES_GEO_FIELD_TYPE, ES_SPATIAL_RELATIONS } from '../../../../common/constants'; import { GeometryFilterForm } from '../../../components/draw_forms/geometry_filter_form/geometry_filter_form'; import { DistanceFilterForm } from '../../../components/draw_forms/distance_filter_form'; // @ts-expect-error @@ -57,7 +57,7 @@ export interface Props { filterModeActive: boolean; getFilterActions?: () => Promise; getActionContext?: () => ActionExecutionContext; - activateDrawFilterMode: (drawState: DrawState) => void; + initiateDraw: (drawState: DrawState) => void; deactivateDrawMode: () => void; } @@ -91,8 +91,8 @@ export class ToolsControl extends Component { geoFieldType?: ES_GEO_FIELD_TYPE; relation?: ES_SPATIAL_RELATIONS; }) => { - this.props.activateDrawFilterMode({ - drawType: DRAW_TYPE.POLYGON, + this.props.initiateDraw({ + drawShape: DRAW_SHAPE.POLYGON, ...options, }); this._closePopover(); @@ -106,16 +106,16 @@ export class ToolsControl extends Component { geoFieldType?: ES_GEO_FIELD_TYPE; relation?: ES_SPATIAL_RELATIONS; }) => { - this.props.activateDrawFilterMode({ - drawType: DRAW_TYPE.BOUNDS, + this.props.initiateDraw({ + drawShape: DRAW_SHAPE.BOUNDS, ...options, }); this._closePopover(); }; _initiateDistanceDraw = (options: { actionId: string; filterLabel: string }) => { - this.props.activateDrawFilterMode({ - drawType: DRAW_TYPE.DISTANCE, + this.props.initiateDraw({ + drawShape: DRAW_SHAPE.DISTANCE, ...options, }); this._closePopover(); @@ -205,7 +205,7 @@ export class ToolsControl extends Component { { ); - if (!this.props.filterModeActive || this.state.isPopoverOpen) { + if (!this.props.filterModeActive) { return toolsPopoverButton; } diff --git a/x-pack/plugins/maps/public/reducers/map/map.ts b/x-pack/plugins/maps/public/reducers/map/map.ts index 2056bd10c04e9e..70796f21cccff2 100644 --- a/x-pack/plugins/maps/public/reducers/map/map.ts +++ b/x-pack/plugins/maps/public/reducers/map/map.ts @@ -46,8 +46,8 @@ import { ROLLBACK_MAP_SETTINGS, TRACK_MAP_SETTINGS, UPDATE_MAP_SETTING, - SET_SHAPE_TO_DRAW, - UPDATE_EDIT_LAYER, + UPDATE_EDIT_STATE_SHAPE, + UPDATE_EDIT_STATE_LAYER, } from '../../actions'; import { getDefaultMapSettings } from './default_map_settings'; @@ -100,7 +100,7 @@ export function map(state: MapState = DEFAULT_MAP_STATE, action: any) { drawState: action.drawState, }, }; - case UPDATE_EDIT_LAYER: + case UPDATE_EDIT_STATE_LAYER: return { ...state, mapState: { @@ -111,14 +111,14 @@ export function map(state: MapState = DEFAULT_MAP_STATE, action: any) { }, }, }; - case SET_SHAPE_TO_DRAW: + case UPDATE_EDIT_STATE_SHAPE: return { ...state, mapState: { ...state.mapState, editState: { ...state.mapState.editState, - drawType: action.shapeToDraw, + drawShape: action.shapeToDraw, }, }, }; diff --git a/x-pack/plugins/maps/public/selectors/map_selectors.ts b/x-pack/plugins/maps/public/selectors/map_selectors.ts index 93fe2cbb65cf52..d2d35bc6ae1158 100644 --- a/x-pack/plugins/maps/public/selectors/map_selectors.ts +++ b/x-pack/plugins/maps/public/selectors/map_selectors.ts @@ -27,9 +27,8 @@ import { InnerJoin } from '../classes/joins/inner_join'; import { getSourceByType } from '../classes/sources/source_registry'; import { GeoJsonFileSource } from '../classes/sources/geojson_file_source'; import { - DRAW_TYPE, + DRAW_SHAPE, SOURCE_DATA_REQUEST_ID, - SOURCE_TYPES, SPATIAL_FILTERS_LAYER_ID, STYLE_TYPE, VECTOR_STYLES, @@ -199,8 +198,8 @@ export const isUsingSearch = (state: MapStoreState): boolean => { export const getDrawState = ({ map }: MapStoreState): DrawState | undefined => map.mapState.drawState; -export const getShapeToDraw = ({ map }: MapStoreState): DRAW_TYPE | undefined => - map.mapState.editState ? map.mapState.editState.drawType : undefined; +export const getShapeToDraw = ({ map }: MapStoreState): DRAW_SHAPE | undefined => + map.mapState.editState ? map.mapState.editState.drawShape : undefined; export const getEditingLayer = ({ map }: MapStoreState): string | undefined => map.mapState.editState ? map.mapState.editState.layerId : undefined; @@ -337,10 +336,6 @@ export function getLayerById(layerId: string | null, state: MapStoreState): ILay }); } -export function getLayersBySourceType(sourceType: SOURCE_TYPES, state: MapStoreState): ILayer[] { - return getLayerList(state).filter((layer) => layer.getSource().getType() === sourceType); -} - export const getHiddenLayerIds = createSelector(getLayerListRaw, (layers) => layers.filter((layer) => !layer.visible).map((layer) => layer.id) ); diff --git a/x-pack/plugins/maps/public/util.ts b/x-pack/plugins/maps/public/util.ts index 9a96f105007246..e56c0841ee381d 100644 --- a/x-pack/plugins/maps/public/util.ts +++ b/x-pack/plugins/maps/public/util.ts @@ -167,7 +167,7 @@ export const addFeatureToIndex = async ( return await getHttp().fetch({ path: `${INDEX_FEATURE_PATH}`, method: 'POST', - body: convertObjectToBlob({ + body: JSON.stringify({ index: indexName, data, }), @@ -185,10 +185,6 @@ const convertDotNotationStringToObj = ( return container; }; -const convertObjectToBlob = (obj: unknown) => { - return new Blob([JSON.stringify(obj)], { type: 'application/json' }); -}; - export const getMatchingIndexes = async (indexPattern: string) => { return await getHttp().fetch({ path: `${GET_MATCHING_INDEXES_PATH}/${indexPattern}`, From 80554f586c8539b1533c730436d80652d829f637 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Fri, 4 Jun 2021 09:09:21 -0600 Subject: [PATCH 073/103] Snapshot updates, eslint fix --- .../public/actions/data_request_actions.ts | 2 +- .../__snapshots__/toc_entry.test.tsx.snap | 42 ++--- .../toc_entry_actions_popover.test.tsx.snap | 12 +- .../toolbar_overlay.test.tsx.snap | 3 - .../__snapshots__/tools_control.test.tsx.snap | 171 ++++++++---------- 5 files changed, 104 insertions(+), 126 deletions(-) diff --git a/x-pack/plugins/maps/public/actions/data_request_actions.ts b/x-pack/plugins/maps/public/actions/data_request_actions.ts index 970303fe05edbe..ee86891bde8545 100644 --- a/x-pack/plugins/maps/public/actions/data_request_actions.ts +++ b/x-pack/plugins/maps/public/actions/data_request_actions.ts @@ -115,7 +115,7 @@ function getDataRequestContext( dispatch: ThunkDispatch, getState: () => MapStoreState, layerId: string, - forceRefresh: boolean = false, + forceRefresh: boolean = false ): DataRequestContext { return { dataFilters: getDataFilters(getState()), diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/__snapshots__/toc_entry.test.tsx.snap b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/__snapshots__/toc_entry.test.tsx.snap index 3abc6801122fb8..05158452ad8612 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/__snapshots__/toc_entry.test.tsx.snap +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/__snapshots__/toc_entry.test.tsx.snap @@ -11,7 +11,6 @@ exports[`TOCEntry is rendered 1`] = ` >
, - "name": "Edit layer", + "name": "Layer settings", "onClick": [Function], "toolTipContent": null, }, @@ -194,9 +194,9 @@ exports[`TOCEntryActionsPopover should disable fit to data when supportsFitToBou "disabled": false, "icon": , - "name": "Edit layer", + "name": "Layer settings", "onClick": [Function], "toolTipContent": null, }, @@ -310,9 +310,9 @@ exports[`TOCEntryActionsPopover should have "show layer" action when layer is no "disabled": false, "icon": , - "name": "Edit layer", + "name": "Layer settings", "onClick": [Function], "toolTipContent": null, }, diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/__snapshots__/toolbar_overlay.test.tsx.snap b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/__snapshots__/toolbar_overlay.test.tsx.snap index 245cf6e5b2a482..69df0539944e9f 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/__snapshots__/toolbar_overlay.test.tsx.snap +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/__snapshots__/toolbar_overlay.test.tsx.snap @@ -28,9 +28,6 @@ exports[`Should show all controls 1`] = ` - - - diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/__snapshots__/tools_control.test.tsx.snap b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/__snapshots__/tools_control.test.tsx.snap index aa5c6aa42c77de..38e32697660063 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/__snapshots__/tools_control.test.tsx.snap +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/__snapshots__/tools_control.test.tsx.snap @@ -1,108 +1,89 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Should render cancel button when drawing 1`] = ` - - - - - - } - closePopover={[Function]} - display="inlineBlock" - hasArrow={true} - id="toolsControlPopover" - isOpen={false} - ownFocus={true} - panelPaddingSize="none" + - + + } + closePopover={[Function]} + display="inlineBlock" + hasArrow={true} + id="toolsControlPopover" + isOpen={false} + ownFocus={true} + panelPaddingSize="none" +> + , - "id": 1, - "title": "Draw shape", + "name": "Draw shape to filter data", + "panel": 1, }, Object { - "content": , - "id": 2, - "title": "Draw bounds", + "name": "Draw bounds to filter data", + "panel": 2, }, Object { - "content": , - "id": 3, - "title": "Draw distance", + "name": "Draw distance to filter data", + "panel": 3, }, - ] - } - size="m" - /> - - - - - - - - + ], + "title": "Tools", + }, + Object { + "content": , + "id": 1, + "title": "Draw shape", + }, + Object { + "content": , + "id": 2, + "title": "Draw bounds", + }, + Object { + "content": , + "id": 3, + "title": "Draw distance", + }, + ] + } + size="m" + /> + `; exports[`renders 1`] = ` From af8c47a8d41c873ea1fb3c230d748d0a062efe3d Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Fri, 4 Jun 2021 10:07:46 -0600 Subject: [PATCH 074/103] Prevent tooltips from popping up while drawing over other layers --- .../maps/public/actions/tooltip_actions.ts | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/maps/public/actions/tooltip_actions.ts b/x-pack/plugins/maps/public/actions/tooltip_actions.ts index c1b5f8190a73a8..1f578cdf92dd6c 100644 --- a/x-pack/plugins/maps/public/actions/tooltip_actions.ts +++ b/x-pack/plugins/maps/public/actions/tooltip_actions.ts @@ -10,9 +10,10 @@ import { Dispatch } from 'redux'; import { Feature } from 'geojson'; import { getOpenTooltips } from '../selectors/map_selectors'; import { SET_OPEN_TOOLTIPS } from './map_action_constants'; -import { FEATURE_ID_PROPERTY_NAME } from '../../common/constants'; +import { DRAW_MODE, FEATURE_ID_PROPERTY_NAME } from '../../common/constants'; import { TooltipState } from '../../common/descriptor_types'; import { MapStoreState } from '../reducers/store'; +import { getDrawMode } from '../selectors/ui_selectors'; export function closeOnClickTooltip(tooltipId: string) { return (dispatch: Dispatch, getState: () => MapStoreState) => { @@ -27,6 +28,12 @@ export function closeOnClickTooltip(tooltipId: string) { export function openOnClickTooltip(tooltipState: TooltipState) { return (dispatch: Dispatch, getState: () => MapStoreState) => { + if ( + getDrawMode(getState()) === DRAW_MODE.DRAW_SHAPES || + getDrawMode(getState()) === DRAW_MODE.DRAW_POINTS + ) { + return; + } const openTooltips = getOpenTooltips(getState()).filter(({ features, location, isLocked }) => { return ( isLocked && @@ -56,9 +63,17 @@ export function closeOnHoverTooltip() { } export function openOnHoverTooltip(tooltipState: TooltipState) { - return { - type: SET_OPEN_TOOLTIPS, - openTooltips: [tooltipState], + return (dispatch: Dispatch, getState: () => MapStoreState) => { + if ( + getDrawMode(getState()) === DRAW_MODE.DRAW_SHAPES || + getDrawMode(getState()) === DRAW_MODE.DRAW_POINTS + ) { + return; + } + dispatch({ + type: SET_OPEN_TOOLTIPS, + openTooltips: [tooltipState], + }); }; } From 420f6b8b5fe81ee8480915dd8357a4fb9549bb13 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Fri, 4 Jun 2021 10:20:02 -0600 Subject: [PATCH 075/103] Use new svg icons for toolbar --- .../feature_edit_tools/feature_edit_tools.tsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/feature_edit_tools.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/feature_edit_tools.tsx index 73776e6f168dbc..578dee5c93d169 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/feature_edit_tools.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/feature_edit_tools.tsx @@ -11,6 +11,9 @@ import { i18n } from '@kbn/i18n'; import { DRAW_SHAPE } from '../../../../../common/constants'; // @ts-expect-error import { GeometryFilterForm } from '../../../../components/draw_forms/geometry_filter_form/geometry_filter_form'; +import { VectorCircleIcon } from '../../icons/vector_circle_icon'; +import { VectorLineIcon } from '../../icons/vector_line_icon'; +import { VectorSquareIcon } from '../../icons/vector_square_icon'; export interface ReduxStateProps { drawShape?: string; @@ -47,7 +50,7 @@ export function FeatureEditTools(props: Props) { props.setDrawShape(DRAW_SHAPE.LINE)} - iconType="minus" + iconType={VectorLineIcon} aria-label={i18n.translate( 'xpack.maps.toolbarOverlay.featureDraw.drawLineLabel', { @@ -93,7 +96,7 @@ export function FeatureEditTools(props: Props) { props.setDrawShape(DRAW_SHAPE.DISTANCE)} - iconType="plusInCircle" + iconType={VectorCircleIcon} aria-label={i18n.translate( 'xpack.maps.toolbarOverlay.featureDraw.drawCircleLabel', { @@ -116,7 +119,7 @@ export function FeatureEditTools(props: Props) { props.setDrawShape(DRAW_SHAPE.BOUNDS)} - iconType="stop" + iconType={VectorSquareIcon} aria-label={i18n.translate( 'xpack.maps.toolbarOverlay.featureDraw.drawBBoxLabel', { From 6e36f3f9b8843fb409061469fdf9389392aa5281 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Fri, 4 Jun 2021 11:05:22 -0600 Subject: [PATCH 076/103] Put edit features behind feature flag --- .../toc_entry_actions_popover/toc_entry_actions_popover.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx index aa5cdfb84c2742..0dbc555b67cc25 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx @@ -19,6 +19,7 @@ import { EDIT_FEATURES_LABEL, } from '../action_labels'; import { ESSearchSource } from '../../../../../../classes/sources/es_search_source'; +import { getMapAppConfig } from '../../../../../../kibana_services'; export interface Props { cloneLayer: (layerId: string) => void; @@ -129,7 +130,7 @@ export class TOCEntryActionsPopover extends Component { ]; if (!this.props.isReadOnly) { - if (this.state.isLayerEditable) { + if (getMapAppConfig().enableDrawingFeature && this.state.isLayerEditable) { actionItems.push({ name: EDIT_FEATURES_LABEL, icon: , From 4b81f4dec5e958545fb7e6eddf641ce72513555a Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Fri, 4 Jun 2021 11:05:52 -0600 Subject: [PATCH 077/103] Disable filters when feature editing active --- .../public/connected_components/toolbar_overlay/index.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts index d98d24a313ec5e..cab28dee9851b9 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts @@ -13,10 +13,13 @@ import { getGeoFieldNames } from '../../selectors/map_selectors'; import { DRAW_MODE } from '../../../common'; function mapStateToProps(state: MapStoreState) { + const shapeDrawModeActive = getDrawMode(state) === DRAW_MODE.DRAW_SHAPES; + const pointDrawModeActive = getDrawMode(state) === DRAW_MODE.DRAW_POINTS; return { - showToolsControl: getGeoFieldNames(state).length !== 0, - shapeDrawModeActive: getDrawMode(state) === DRAW_MODE.DRAW_SHAPES, - pointDrawModeActive: getDrawMode(state) === DRAW_MODE.DRAW_POINTS, + showToolsControl: + getGeoFieldNames(state).length !== 0 && !(shapeDrawModeActive || pointDrawModeActive), + shapeDrawModeActive, + pointDrawModeActive, }; } From 4c1e1af69d6680bdc67dffef1ad605293dcde006 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Fri, 4 Jun 2021 11:35:11 -0600 Subject: [PATCH 078/103] Disable draw mode on add layer flyout opened --- .../right_side_controls/layer_control/index.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/index.ts b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/index.ts index 5f293dba05d9dd..4b8005cc5054df 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/index.ts @@ -11,7 +11,7 @@ import { connect } from 'react-redux'; import { LayerControl } from './layer_control'; import { FLYOUT_STATE } from '../../../reducers/ui'; -import { setSelectedLayer, updateFlyout, setIsLayerTOCOpen } from '../../../actions'; +import { setSelectedLayer, updateFlyout, setIsLayerTOCOpen, setDrawMode } from '../../../actions'; import { getIsReadOnly, getIsLayerTOCOpen, @@ -19,6 +19,7 @@ import { } from '../../../selectors/ui_selectors'; import { getLayerList } from '../../../selectors/map_selectors'; import { MapStoreState } from '../../../reducers/store'; +import { DRAW_MODE } from '../../../../common'; function mapStateToProps(state: MapStoreState) { return { @@ -34,6 +35,7 @@ function mapDispatchToProps(dispatch: ThunkDispatch { await dispatch(setSelectedLayer(null)); dispatch(updateFlyout(FLYOUT_STATE.ADD_LAYER_WIZARD)); + dispatch(setDrawMode(DRAW_MODE.NONE)); }, closeLayerTOC: () => { dispatch(setIsLayerTOCOpen(false)); From fdc22e7c77cc1ad494e3ebbaef6597370fc820e8 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Fri, 4 Jun 2021 11:51:00 -0600 Subject: [PATCH 079/103] Do config check at the layer level instead of in TOC --- .../classes/layers/vector_layer/vector_layer.tsx | 1 + .../sources/es_search_source/es_search_source.tsx | 11 ++++++++++- .../toc_entry_actions_popover.tsx | 3 +-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx index 484bf709feebdd..fdda2deb854694 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx @@ -180,6 +180,7 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { async getEditModeEnabled(): Promise { if ( + !(await this.isEditable()) || (await this.isFilteredByGlobalTime()) || this.isPreviewLayer() || !this.isVisible() || diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx index 1eb527322819f1..6883978dbc5629 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx @@ -12,7 +12,12 @@ import { i18n } from '@kbn/i18n'; import { IFieldType, IndexPattern } from 'src/plugins/data/public'; import { GeoJsonProperties, Geometry, Position } from 'geojson'; import { AbstractESSource } from '../es_source'; -import { getFileUpload, getHttp, getSearchService } from '../../../kibana_services'; +import { + getFileUpload, + getHttp, + getMapAppConfig, + getSearchService, +} from '../../../kibana_services'; import { addFieldToDSL, getField, @@ -391,6 +396,10 @@ export class ESSearchSource extends AbstractESSource implements ITiledSingleLaye } async isEditable(): Promise { + if (!getMapAppConfig().enableDrawingFeature) { + this._isEditable = false; + return this._isEditable; + } if (this._isEditable === undefined) { if (!this.indexPattern) { await this.getIndexPattern(); diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx index 0dbc555b67cc25..aa5cdfb84c2742 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx @@ -19,7 +19,6 @@ import { EDIT_FEATURES_LABEL, } from '../action_labels'; import { ESSearchSource } from '../../../../../../classes/sources/es_search_source'; -import { getMapAppConfig } from '../../../../../../kibana_services'; export interface Props { cloneLayer: (layerId: string) => void; @@ -130,7 +129,7 @@ export class TOCEntryActionsPopover extends Component { ]; if (!this.props.isReadOnly) { - if (getMapAppConfig().enableDrawingFeature && this.state.isLayerEditable) { + if (this.state.isLayerEditable) { actionItems.push({ name: EDIT_FEATURES_LABEL, icon: , From 8c3a2283ef72c850b84bebc1d518c6bbf327f998 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Tue, 8 Jun 2021 06:51:12 -0600 Subject: [PATCH 080/103] Review feedback --- .../maps/public/actions/map_actions.ts | 5 +++-- .../maps/public/actions/tooltip_actions.ts | 14 +------------- .../classes/layers/vector_layer/utils.tsx | 2 +- .../es_search_source/es_search_source.tsx | 19 +++---------------- .../draw_feature_control/index.ts | 5 +++-- .../mb_map/tooltip_control/index.ts | 2 ++ .../tooltip_control/tooltip_control.tsx | 5 +++-- .../layer_toc/toc_entry/index.ts | 5 +++-- .../feature_edit_tools/index.ts | 5 +++-- .../maps/public/selectors/map_selectors.ts | 9 +++------ 10 files changed, 25 insertions(+), 46 deletions(-) diff --git a/x-pack/plugins/maps/public/actions/map_actions.ts b/x-pack/plugins/maps/public/actions/map_actions.ts index 30a73f9117de67..c3ea9711f8c88f 100644 --- a/x-pack/plugins/maps/public/actions/map_actions.ts +++ b/x-pack/plugins/maps/public/actions/map_actions.ts @@ -26,7 +26,7 @@ import { getSearchSessionId, getSearchSessionMapBuffer, getLayerById, - getEditingLayer, + getEditState, } from '../selectors/map_selectors'; import { CLEAR_GOTO, @@ -349,7 +349,8 @@ export function addNewFeatureToIndex(geometry: Geometry | Position[]) { dispatch: ThunkDispatch, getState: () => MapStoreState ) => { - const layerId = getEditingLayer(getState()); + const editState = getEditState(getState()); + const layerId = editState ? editState.layerId : undefined; if (!layerId) { return; } diff --git a/x-pack/plugins/maps/public/actions/tooltip_actions.ts b/x-pack/plugins/maps/public/actions/tooltip_actions.ts index 1f578cdf92dd6c..0145a36bb5bdd7 100644 --- a/x-pack/plugins/maps/public/actions/tooltip_actions.ts +++ b/x-pack/plugins/maps/public/actions/tooltip_actions.ts @@ -28,12 +28,6 @@ export function closeOnClickTooltip(tooltipId: string) { export function openOnClickTooltip(tooltipState: TooltipState) { return (dispatch: Dispatch, getState: () => MapStoreState) => { - if ( - getDrawMode(getState()) === DRAW_MODE.DRAW_SHAPES || - getDrawMode(getState()) === DRAW_MODE.DRAW_POINTS - ) { - return; - } const openTooltips = getOpenTooltips(getState()).filter(({ features, location, isLocked }) => { return ( isLocked && @@ -63,13 +57,7 @@ export function closeOnHoverTooltip() { } export function openOnHoverTooltip(tooltipState: TooltipState) { - return (dispatch: Dispatch, getState: () => MapStoreState) => { - if ( - getDrawMode(getState()) === DRAW_MODE.DRAW_SHAPES || - getDrawMode(getState()) === DRAW_MODE.DRAW_POINTS - ) { - return; - } + return (dispatch: Dispatch) => { dispatch({ type: SET_OPEN_TOOLTIPS, openTooltips: [tooltipState], diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/utils.tsx b/x-pack/plugins/maps/public/classes/layers/vector_layer/utils.tsx index 8d5c4f83409079..a4e0b9beffbcc7 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/utils.tsx +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/utils.tsx @@ -70,7 +70,7 @@ export async function syncVectorSource({ const dataRequestId = SOURCE_DATA_REQUEST_ID; const requestToken = Symbol(`${layerId}-${dataRequestId}`); const doRefresh = syncContext.forceRefresh - ? syncContext.forceRefresh + ? true : !(await canSkipSourceUpdate({ source, prevDataRequest, diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx index 6883978dbc5629..b3f413fa93e121 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx @@ -12,12 +12,7 @@ import { i18n } from '@kbn/i18n'; import { IFieldType, IndexPattern } from 'src/plugins/data/public'; import { GeoJsonProperties, Geometry, Position } from 'geojson'; import { AbstractESSource } from '../es_source'; -import { - getFileUpload, - getHttp, - getMapAppConfig, - getSearchService, -} from '../../../kibana_services'; +import { getHttp, getMapAppConfig, getSearchService } from '../../../kibana_services'; import { addFieldToDSL, getField, @@ -401,20 +396,12 @@ export class ESSearchSource extends AbstractESSource implements ITiledSingleLaye return this._isEditable; } if (this._isEditable === undefined) { - if (!this.indexPattern) { - await this.getIndexPattern(); - } + await this.getIndexPattern(); const { matchingIndexes } = await getMatchingIndexes(this.indexPattern!.title); this._isEditable = // For now we only support 1:1 index-pattern:index matches - matchingIndexes.length === 1 && - // Permissions required for index modification are identical to file upload - (await getFileUpload().hasImportPermission({ - checkCreateIndexPattern: true, - checkHasManagePipeline: false, - indexName: this.indexPattern!.title, - })); + matchingIndexes.length === 1; } return this._isEditable; } diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts index 118b8afa7b1e24..9034e40913e772 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/index.ts @@ -17,12 +17,13 @@ import { } from './draw_feature_control'; import { addNewFeatureToIndex, updateEditShape } from '../../../../actions'; import { MapStoreState } from '../../../../reducers/store'; -import { getShapeToDraw } from '../../../../selectors/map_selectors'; +import { getEditState } from '../../../../selectors/map_selectors'; import { getDrawMode } from '../../../../selectors/ui_selectors'; function mapStateToProps(state: MapStoreState): ReduxStateProps { + const editState = getEditState(state); return { - drawShape: getShapeToDraw(state), + drawShape: editState ? editState.drawShape : undefined, drawMode: getDrawMode(state), }; } diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/index.ts b/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/index.ts index 30605a0f53e15a..009a512023309e 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/index.ts @@ -31,6 +31,8 @@ function mapStateToProps(state: MapStoreState) { layerList: getLayerList(state), hasLockedTooltips: getHasLockedTooltips(state), filterModeActive: getDrawMode(state) === DRAW_MODE.DRAW_FILTERS, + drawModeActive: + getDrawMode(state) === DRAW_MODE.DRAW_SHAPES || getDrawMode(state) === DRAW_MODE.DRAW_POINTS, openTooltips: getOpenTooltips(state), geoFieldNames: getGeoFieldNames(state), }; diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.tsx index 7ce7c45cf404e8..35675014557344 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.tsx @@ -71,6 +71,7 @@ export interface Props { geoFieldNames: string[]; hasLockedTooltips: boolean; filterModeActive: boolean; + drawModeActive: boolean; layerList: ILayer[]; mbMap: MbMap; openOnClickTooltip: (tooltipState: TooltipState) => void; @@ -244,7 +245,7 @@ export class TooltipControl extends Component { } _lockTooltip = (e: MapMouseEvent) => { - if (this.props.filterModeActive) { + if (this.props.filterModeActive || this.props.drawModeActive) { // ignore click events when in draw mode return; } @@ -275,7 +276,7 @@ export class TooltipControl extends Component { }; _updateHoverTooltipState = _.debounce((e: MapMouseEvent) => { - if (this.props.filterModeActive || this.props.hasLockedTooltips) { + if (this.props.filterModeActive || this.props.hasLockedTooltips || this.props.drawModeActive) { // ignore hover events when in draw mode or when there are locked tooltips return; } diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/index.ts b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/index.ts index 662234dd36b59c..5ee779fe1f86d8 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/index.ts +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/index.ts @@ -15,7 +15,7 @@ import { getMapZoom, hasDirtyState, getSelectedLayer, - getEditingLayer, + getEditState, } from '../../../../../selectors/map_selectors'; import { getIsReadOnly, @@ -46,7 +46,8 @@ function mapStateToProps(state: MapStoreState, ownProps: OwnProps): ReduxStatePr editModeActiveForLayer: (getDrawMode(state) === DRAW_MODE.DRAW_SHAPES || getDrawMode(state) === DRAW_MODE.DRAW_POINTS) && - getEditingLayer(state) === ownProps.layer.getId(), + !!getEditState(state) && + getEditState(state)!.layerId === ownProps.layer.getId(), }; } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/index.ts index 07988fe3f83cde..2e103eb2c8c095 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/index.ts @@ -17,11 +17,12 @@ import { import { setDrawMode, updateEditShape } from '../../../../actions'; import { MapStoreState } from '../../../../reducers/store'; import { DRAW_MODE, DRAW_SHAPE } from '../../../../../common'; -import { getShapeToDraw } from '../../../../selectors/map_selectors'; +import { getEditState } from '../../../../selectors/map_selectors'; function mapStateToProps(state: MapStoreState): ReduxStateProps { + const editState = getEditState(state); return { - drawShape: getShapeToDraw(state), + drawShape: editState ? editState.drawShape : undefined, }; } diff --git a/x-pack/plugins/maps/public/selectors/map_selectors.ts b/x-pack/plugins/maps/public/selectors/map_selectors.ts index 06efd4517fd2f5..a2eb06f20cb263 100644 --- a/x-pack/plugins/maps/public/selectors/map_selectors.ts +++ b/x-pack/plugins/maps/public/selectors/map_selectors.ts @@ -27,7 +27,6 @@ import { InnerJoin } from '../classes/joins/inner_join'; import { getSourceByType } from '../classes/sources/source_registry'; import { GeoJsonFileSource } from '../classes/sources/geojson_file_source'; import { - DRAW_SHAPE, SOURCE_DATA_REQUEST_ID, SPATIAL_FILTERS_LAYER_ID, STYLE_TYPE, @@ -40,6 +39,7 @@ import { AbstractSourceDescriptor, DataRequestDescriptor, DrawState, + EditState, Goto, HeatmapLayerDescriptor, LayerDescriptor, @@ -197,11 +197,8 @@ export const isUsingSearch = (state: MapStoreState): boolean => { export const getDrawState = ({ map }: MapStoreState): DrawState | undefined => map.mapState.drawState; -export const getShapeToDraw = ({ map }: MapStoreState): DRAW_SHAPE | undefined => - map.mapState.editState ? map.mapState.editState.drawShape : undefined; - -export const getEditingLayer = ({ map }: MapStoreState): string | undefined => - map.mapState.editState ? map.mapState.editState.layerId : undefined; +export const getEditState = ({ map }: MapStoreState): EditState | undefined => + map.mapState.editState; export const getRefreshTimerLastTriggeredAt = ({ map }: MapStoreState): string | undefined => map.mapState.refreshTimerLastTriggeredAt; From 902fe04894766a8c67b0e241839158ee0b310f31 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Tue, 8 Jun 2021 08:25:11 -0600 Subject: [PATCH 081/103] Review feedback. Draw mode handling improvements --- x-pack/plugins/maps/public/actions/map_actions.ts | 7 ++++++- x-pack/plugins/maps/public/actions/ui_actions.ts | 15 ++++++++++++--- x-pack/plugins/maps/public/reducers/map/map.ts | 6 ++---- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/maps/public/actions/map_actions.ts b/x-pack/plugins/maps/public/actions/map_actions.ts index c3ea9711f8c88f..48c46846043555 100644 --- a/x-pack/plugins/maps/public/actions/map_actions.ts +++ b/x-pack/plugins/maps/public/actions/map_actions.ts @@ -12,7 +12,7 @@ import turfBboxPolygon from '@turf/bbox-polygon'; import turfBooleanContains from '@turf/boolean-contains'; import { Filter, Query, TimeRange } from 'src/plugins/data/public'; import { Geometry, Position } from 'geojson'; -import { DRAW_SHAPE } from '../../common/constants'; +import { DRAW_MODE, DRAW_SHAPE } from '../../common/constants'; import { MapStoreState } from '../reducers/store'; import { getDataFilters, @@ -63,6 +63,7 @@ import { INITIAL_LOCATION } from '../../common/constants'; import { scaleBounds } from '../../common/elasticsearch_util'; import { cleanTooltipStateForLayer } from './tooltip_actions'; import { VectorLayer } from '../classes/layers/vector_layer'; +import { SET_DRAW_MODE } from './ui_actions'; export interface MapExtentState { zoom: number; @@ -337,6 +338,10 @@ export function updateEditLayer(layerId: string | null) { if (layerId !== null) { dispatch({ type: SET_OPEN_TOOLTIPS, openTooltips: [] }); } + dispatch({ + type: SET_DRAW_MODE, + drawMode: DRAW_MODE.NONE, + }); dispatch({ type: UPDATE_EDIT_STATE_LAYER, layerId, diff --git a/x-pack/plugins/maps/public/actions/ui_actions.ts b/x-pack/plugins/maps/public/actions/ui_actions.ts index 25f5cb8c45f5f2..e4bbc161618dac 100644 --- a/x-pack/plugins/maps/public/actions/ui_actions.ts +++ b/x-pack/plugins/maps/public/actions/ui_actions.ts @@ -13,6 +13,7 @@ import { FLYOUT_STATE } from '../reducers/ui'; import { setQuery, trackMapSettings } from './map_actions'; import { setSelectedLayer } from './layer_actions'; import { DRAW_MODE } from '../../common'; +import { UPDATE_EDIT_STATE_LAYER } from './map_action_constants'; export const UPDATE_FLYOUT = 'UPDATE_FLYOUT'; export const SET_IS_LAYER_TOC_OPEN = 'SET_IS_LAYER_TOC_OPEN'; @@ -92,9 +93,17 @@ export function hideTOCDetails(layerId: string) { } export function setDrawMode(drawMode: DRAW_MODE) { - return { - type: SET_DRAW_MODE, - drawMode, + return (dispatch: ThunkDispatch) => { + if (drawMode === DRAW_MODE.NONE) { + dispatch({ + type: UPDATE_EDIT_STATE_LAYER, + layerId: null, + }); + } + dispatch({ + type: SET_DRAW_MODE, + drawMode, + }); }; } diff --git a/x-pack/plugins/maps/public/reducers/map/map.ts b/x-pack/plugins/maps/public/reducers/map/map.ts index b460c3076c9367..181406de250be6 100644 --- a/x-pack/plugins/maps/public/reducers/map/map.ts +++ b/x-pack/plugins/maps/public/reducers/map/map.ts @@ -98,14 +98,12 @@ export function map(state: MapState = DEFAULT_MAP_STATE, action: any) { }, }; case UPDATE_EDIT_STATE_LAYER: + const editState = action.layerId ? { layerId: action.layerId } : undefined; return { ...state, mapState: { ...state.mapState, - editState: { - ...state.mapState.editState, - layerId: action.layerId, - }, + editState, }, }; case UPDATE_EDIT_STATE_SHAPE: From 7e73334a71182ee8db196e7dc63b1bb3a387e6f8 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Tue, 8 Jun 2021 09:19:28 -0600 Subject: [PATCH 082/103] Review feedback. Move editable checks down a level from top level layer and source --- x-pack/plugins/maps/public/actions/tooltip_actions.ts | 3 +-- x-pack/plugins/maps/public/classes/layers/layer.tsx | 10 ---------- .../mvt_single_layer_vector_source.tsx | 4 ++++ x-pack/plugins/maps/public/classes/sources/source.ts | 5 ----- .../classes/sources/vector_source/vector_source.tsx | 4 ++++ .../mb_map/tooltip_control/tooltip_control.test.tsx | 1 + .../toc_entry_actions_popover.tsx | 5 ++++- 7 files changed, 14 insertions(+), 18 deletions(-) diff --git a/x-pack/plugins/maps/public/actions/tooltip_actions.ts b/x-pack/plugins/maps/public/actions/tooltip_actions.ts index 0145a36bb5bdd7..8e40e1cf2e504f 100644 --- a/x-pack/plugins/maps/public/actions/tooltip_actions.ts +++ b/x-pack/plugins/maps/public/actions/tooltip_actions.ts @@ -10,10 +10,9 @@ import { Dispatch } from 'redux'; import { Feature } from 'geojson'; import { getOpenTooltips } from '../selectors/map_selectors'; import { SET_OPEN_TOOLTIPS } from './map_action_constants'; -import { DRAW_MODE, FEATURE_ID_PROPERTY_NAME } from '../../common/constants'; +import { FEATURE_ID_PROPERTY_NAME } from '../../common/constants'; import { TooltipState } from '../../common/descriptor_types'; import { MapStoreState } from '../reducers/store'; -import { getDrawMode } from '../selectors/ui_selectors'; export function closeOnClickTooltip(tooltipId: string) { return (dispatch: Dispatch, getState: () => MapStoreState) => { diff --git a/x-pack/plugins/maps/public/classes/layers/layer.tsx b/x-pack/plugins/maps/public/classes/layers/layer.tsx index adc0ba25df7536..be113ab4cc2c9a 100644 --- a/x-pack/plugins/maps/public/classes/layers/layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/layer.tsx @@ -73,8 +73,6 @@ export interface ILayer { isLayerLoading(): boolean; isLoadingBounds(): boolean; isFilteredByGlobalTime(): Promise; - isEditable(): Promise; - getEditModeEnabled(): Promise; hasErrors(): boolean; getErrors(): string; getMbLayerIds(): string[]; @@ -243,14 +241,6 @@ export class AbstractLayer implements ILayer { return !!this._descriptor.__isPreviewLayer; } - async isEditable(): Promise { - return false; - } - - async getEditModeEnabled(): Promise { - return false; - } - supportsElasticsearchFilters(): boolean { return this.getSource().isESSource(); } diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx index fbfd982c313d89..99554fef69fd61 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx @@ -227,6 +227,10 @@ export class MVTSingleLayerVectorSource } return tooltips; } + + async isEditable(): Promise { + return false; + } } registerSource({ diff --git a/x-pack/plugins/maps/public/classes/sources/source.ts b/x-pack/plugins/maps/public/classes/sources/source.ts index 3e34e30d2c5a19..7a8fca337fd2e1 100644 --- a/x-pack/plugins/maps/public/classes/sources/source.ts +++ b/x-pack/plugins/maps/public/classes/sources/source.ts @@ -39,7 +39,6 @@ export interface ISource { getDisplayName(): Promise; getInspectorAdapters(): Adapters | undefined; isFieldAware(): boolean; - isEditable(): Promise; isFilterByMapBounds(): boolean; isGeoGridPrecisionAware(): boolean; isQueryAware(): boolean; @@ -110,10 +109,6 @@ export class AbstractSource implements ISource { return false; } - async isEditable(): Promise { - return false; - } - isRefreshTimerAware(): boolean { return false; } diff --git a/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.tsx b/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.tsx index c7d9e644b90f00..9521af85df0afd 100644 --- a/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.tsx @@ -159,4 +159,8 @@ export class AbstractVectorSource extends AbstractSource implements IVectorSourc async addFeature(geometry: Geometry | Position[]) { throw new Error('Should implement VectorSource#addFeature'); } + + async isEditable(): Promise { + return false; + } } diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.test.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.test.tsx index f1c112cdcec2eb..94ce1e75458004 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.test.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.test.tsx @@ -81,6 +81,7 @@ const defaultProps = { openTooltips: [], hasLockedTooltips: false, filterModeActive: false, + drawModeActive: false, }; const hoverTooltipState = { diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx index aa5cdfb84c2742..6e0746b2dc8437 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx @@ -6,7 +6,6 @@ */ import React, { Component } from 'react'; - import { EuiPopover, EuiContextMenu, EuiIcon } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { ILayer } from '../../../../../../classes/layers/layer'; @@ -19,6 +18,7 @@ import { EDIT_FEATURES_LABEL, } from '../action_labels'; import { ESSearchSource } from '../../../../../../classes/sources/es_search_source'; +import { VectorLayer } from '../../../../../../classes/layers/vector_layer'; export interface Props { cloneLayer: (layerId: string) => void; @@ -59,6 +59,9 @@ export class TOCEntryActionsPopover extends Component { } async _checkLayerEditable() { + if (!(this.props.layer instanceof VectorLayer)) { + return; + } const isLayerEditable = await this.props.layer.isEditable(); const editModeEnabled = await this.props.layer.getEditModeEnabled(); if ( From 52958816a4da43cef6cd1435f474be3364c1d8c2 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Tue, 8 Jun 2021 15:36:00 -0600 Subject: [PATCH 083/103] Update editable flag to be DataRequest --- x-pack/plugins/maps/common/constants.ts | 1 + .../public/actions/data_request_actions.ts | 2 +- .../layers/vector_layer/vector_layer.tsx | 35 ++++++++++++++++--- .../es_search_source/es_search_source.tsx | 19 ++++------ .../mvt_single_layer_vector_source.tsx | 2 +- .../sources/vector_source/vector_source.tsx | 4 +-- 6 files changed, 41 insertions(+), 22 deletions(-) diff --git a/x-pack/plugins/maps/common/constants.ts b/x-pack/plugins/maps/common/constants.ts index 16dfe5567898d7..c49dd4fb619b50 100644 --- a/x-pack/plugins/maps/common/constants.ts +++ b/x-pack/plugins/maps/common/constants.ts @@ -107,6 +107,7 @@ export const SOURCE_DATA_REQUEST_ID = 'source'; export const SOURCE_META_DATA_REQUEST_ID = `${SOURCE_DATA_REQUEST_ID}_${META_DATA_REQUEST_ID_SUFFIX}`; export const SOURCE_FORMATTERS_DATA_REQUEST_ID = `${SOURCE_DATA_REQUEST_ID}_${FORMATTERS_DATA_REQUEST_ID_SUFFIX}`; export const SOURCE_BOUNDS_DATA_REQUEST_ID = `${SOURCE_DATA_REQUEST_ID}_bounds`; +export const IS_EDITABLE_REQUEST_ID = 'isEditable'; export const MIN_ZOOM = 0; export const MAX_ZOOM = 24; diff --git a/x-pack/plugins/maps/public/actions/data_request_actions.ts b/x-pack/plugins/maps/public/actions/data_request_actions.ts index ee86891bde8545..beb8f60138c62d 100644 --- a/x-pack/plugins/maps/public/actions/data_request_actions.ts +++ b/x-pack/plugins/maps/public/actions/data_request_actions.ts @@ -54,7 +54,7 @@ import { IVectorStyle } from '../classes/styles/vector/vector_style'; const FIT_TO_BOUNDS_SCALE_FACTOR = 0.1; export type DataRequestContext = { - startLoading(dataId: string, requestToken: symbol, requestMeta: DataMeta): void; + startLoading(dataId: string, requestToken: symbol, requestMeta?: DataMeta): void; stopLoading(dataId: string, requestToken: symbol, data: object, resultsMeta?: DataMeta): void; onLoadError(dataId: string, requestToken: symbol, errorMessage: string): void; updateSourceData(newData: unknown): void; diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx index fdda2deb854694..67748369e053c9 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx @@ -28,6 +28,7 @@ import { FIELD_ORIGIN, KBN_TOO_MANY_FEATURES_IMAGE_ID, FieldFormatter, + IS_EDITABLE_REQUEST_ID, } from '../../../../common/constants'; import { JoinTooltipProperty } from '../../tooltips/join_tooltip_property'; import { DataRequestAbortError } from '../../util/data_request'; @@ -43,7 +44,6 @@ import { getLineFilterExpression, getPointFilterExpression, } from '../../util/mb_filter_expressions'; - import { DynamicStylePropertyOptions, MapFilters, @@ -76,6 +76,10 @@ interface JoinState { propertiesMap?: PropertiesMap; } +interface EditableData { + isEditable: boolean; +} + export interface VectorLayerArguments { source: IVectorSource; joins?: InnerJoin[]; @@ -94,14 +98,13 @@ export interface IVectorLayer extends ILayer { hasJoins(): boolean; canShowTooltip(): boolean; getEditModeEnabled(): Promise; - isEditable(): Promise; + isEditable(): boolean; getLeftJoinFields(): Promise; addFeature(geometry: Geometry | Position[]): Promise; } export class VectorLayer extends AbstractLayer implements IVectorLayer { static type = LAYER_TYPE.VECTOR; - protected readonly _style: IVectorStyle; private readonly _joins: InnerJoin[]; @@ -191,8 +194,9 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { return true; } - async isEditable(): Promise { - return await this.getSource().isEditable(); + isEditable(): boolean { + const isEditable = this.getDataRequest(IS_EDITABLE_REQUEST_ID); + return isEditable ? (isEditable.getData() as EditableData).isEditable : false; } hasJoins() { @@ -690,6 +694,7 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { syncContext, source, }); + await this._syncIsEditable({ syncContext }); if ( !sourceResult.featureCollection || !sourceResult.featureCollection.features.length || @@ -707,6 +712,26 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { } } + async _syncIsEditable({ syncContext }: { syncContext: DataRequestContext }) { + const { startLoading, stopLoading, onLoadError } = syncContext; + const dataRequestId = IS_EDITABLE_REQUEST_ID; + const requestToken = Symbol(`layer-${this.getId()}-${dataRequestId}`); + const prevDataRequest = this.getDataRequest(dataRequestId); + if (prevDataRequest) { + return; + } + try { + startLoading(dataRequestId, requestToken); + const isEditable = await this.getSource().loadIsEditable(); + stopLoading(dataRequestId, requestToken, { isEditable }); + } catch (error) { + if (!(error instanceof DataRequestAbortError)) { + onLoadError(dataRequestId, requestToken, error.message); + } + throw error; + } + } + _getSourceFeatureCollection() { const sourceDataRequest = this.getSourceDataRequest(); return sourceDataRequest ? (sourceDataRequest.getData() as FeatureCollection) : null; diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx index b3f413fa93e121..3c2c2688cb97cc 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx @@ -66,7 +66,6 @@ export const sourceTitle = i18n.translate('xpack.maps.source.esSearchTitle', { export class ESSearchSource extends AbstractESSource implements ITiledSingleLayerVectorSource { readonly _descriptor: ESSearchSourceDescriptor; protected readonly _tooltipFields: ESDocField[]; - protected _isEditable: boolean | undefined; static createDescriptor(descriptor: Partial): ESSearchSourceDescriptor { const normalizedDescriptor = AbstractESSource.createDescriptor(descriptor); @@ -390,20 +389,14 @@ export class ESSearchSource extends AbstractESSource implements ITiledSingleLaye return !!(scalingType === SCALING_TYPES.TOP_HITS && topHitsSplitField); } - async isEditable(): Promise { + async loadIsEditable(): Promise { if (!getMapAppConfig().enableDrawingFeature) { - this._isEditable = false; - return this._isEditable; - } - if (this._isEditable === undefined) { - await this.getIndexPattern(); - - const { matchingIndexes } = await getMatchingIndexes(this.indexPattern!.title); - this._isEditable = - // For now we only support 1:1 index-pattern:index matches - matchingIndexes.length === 1; + return false; } - return this._isEditable; + await this.getIndexPattern(); + const { matchingIndexes } = await getMatchingIndexes(this.indexPattern!.title); + // For now we only support 1:1 index-pattern:index matches + return matchingIndexes.length === 1; } _hasSort(): boolean { diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx index 99554fef69fd61..2311774691acbd 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx @@ -228,7 +228,7 @@ export class MVTSingleLayerVectorSource return tooltips; } - async isEditable(): Promise { + async loadIsEditable(): Promise { return false; } } diff --git a/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.tsx b/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.tsx index 9521af85df0afd..84aad44c4fdbbf 100644 --- a/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.tsx @@ -66,7 +66,7 @@ export interface IVectorSource extends ISource { getSupportedShapeTypes(): Promise; isBoundsAware(): boolean; getSourceTooltipContent(sourceDataRequest?: DataRequest): SourceTooltipConfig; - isEditable(): Promise; + loadIsEditable(): Promise; addFeature(geometry: Geometry | Position[]): Promise; } @@ -160,7 +160,7 @@ export class AbstractVectorSource extends AbstractSource implements IVectorSourc throw new Error('Should implement VectorSource#addFeature'); } - async isEditable(): Promise { + async loadIsEditable(): Promise { return false; } } From cfec1364c1e326089739a39d1f517e7e39b293fb Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 9 Jun 2021 10:30:55 -0600 Subject: [PATCH 084/103] Review feedback. Clean up endpoint. Clean up & update editable checks --- .../data_request_descriptor_types.ts | 1 + .../common/descriptor_types/map_descriptor.ts | 2 +- .../blended_vector_layer.ts | 4 ---- .../layers/vector_layer/vector_layer.tsx | 17 +++-------------- .../layer_control/layer_toc/toc_entry/index.ts | 8 +------- .../toc_entry_actions_popover.tsx | 16 +++++++++++++++- .../maps/public/selectors/map_selectors.ts | 6 +++++- .../get_indexes_matching_pattern.ts | 4 ++-- .../server/data_indexing/indexing_routes.ts | 12 +----------- 9 files changed, 29 insertions(+), 41 deletions(-) diff --git a/x-pack/plugins/maps/common/descriptor_types/data_request_descriptor_types.ts b/x-pack/plugins/maps/common/descriptor_types/data_request_descriptor_types.ts index e65e19d7def482..cda812700804e0 100644 --- a/x-pack/plugins/maps/common/descriptor_types/data_request_descriptor_types.ts +++ b/x-pack/plugins/maps/common/descriptor_types/data_request_descriptor_types.ts @@ -29,6 +29,7 @@ export type MapFilters = { timeFilters: TimeRange; timeslice?: Timeslice; zoom: number; + isReadOnly: boolean; }; type ESSearchSourceSyncMeta = { diff --git a/x-pack/plugins/maps/common/descriptor_types/map_descriptor.ts b/x-pack/plugins/maps/common/descriptor_types/map_descriptor.ts index 86dd2ba2ad3abd..20d811fab62f79 100644 --- a/x-pack/plugins/maps/common/descriptor_types/map_descriptor.ts +++ b/x-pack/plugins/maps/common/descriptor_types/map_descriptor.ts @@ -70,6 +70,6 @@ export type DrawState = { }; export type EditState = { - layerId?: string; + layerId: string; drawShape?: DRAW_SHAPE; }; diff --git a/x-pack/plugins/maps/public/classes/layers/blended_vector_layer/blended_vector_layer.ts b/x-pack/plugins/maps/public/classes/layers/blended_vector_layer/blended_vector_layer.ts index 12b064660815f3..6dd454137be7de 100644 --- a/x-pack/plugins/maps/public/classes/layers/blended_vector_layer/blended_vector_layer.ts +++ b/x-pack/plugins/maps/public/classes/layers/blended_vector_layer/blended_vector_layer.ts @@ -291,10 +291,6 @@ export class BlendedVectorLayer extends VectorLayer implements IVectorLayer { return this._documentStyle; } - async getEditModeEnabled(): Promise { - return this._isClustered ? false : super.getEditModeEnabled(); - } - async syncData(syncContext: DataRequestContext) { const dataRequestId = ACTIVE_COUNT_DATA_ID; const requestToken = Symbol(`layer-active-count:${this.getId()}`); diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx index 67748369e053c9..96f99c9141d844 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx @@ -97,7 +97,6 @@ export interface IVectorLayer extends ILayer { getPropertiesForTooltip(properties: GeoJsonProperties): Promise; hasJoins(): boolean; canShowTooltip(): boolean; - getEditModeEnabled(): Promise; isEditable(): boolean; getLeftJoinFields(): Promise; addFeature(geometry: Geometry | Position[]): Promise; @@ -181,19 +180,6 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { }); } - async getEditModeEnabled(): Promise { - if ( - !(await this.isEditable()) || - (await this.isFilteredByGlobalTime()) || - this.isPreviewLayer() || - !this.isVisible() || - this.hasJoins() - ) { - return false; - } - return true; - } - isEditable(): boolean { const isEditable = this.getDataRequest(IS_EDITABLE_REQUEST_ID); return isEditable ? (isEditable.getData() as EditableData).isEditable : false; @@ -713,6 +699,9 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { } async _syncIsEditable({ syncContext }: { syncContext: DataRequestContext }) { + if (syncContext.dataFilters.isReadOnly) { + return; + } const { startLoading, stopLoading, onLoadError } = syncContext; const dataRequestId = IS_EDITABLE_REQUEST_ID; const requestToken = Symbol(`layer-${this.getId()}-${dataRequestId}`); diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/index.ts b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/index.ts index 5ee779fe1f86d8..e9c386ce5f8bdf 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/index.ts +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/index.ts @@ -21,7 +21,6 @@ import { getIsReadOnly, getOpenTOCDetails, getFlyoutDisplay, - getDrawMode, } from '../../../../../selectors/ui_selectors'; import { fitToLayerExtent, @@ -31,7 +30,6 @@ import { showTOCDetails, toggleLayerVisible, } from '../../../../../actions'; -import { DRAW_MODE } from '../../../../../../common'; function mapStateToProps(state: MapStoreState, ownProps: OwnProps): ReduxStateProps { const flyoutDisplay = getFlyoutDisplay(state); @@ -43,11 +41,7 @@ function mapStateToProps(state: MapStoreState, ownProps: OwnProps): ReduxStatePr isLegendDetailsOpen: getOpenTOCDetails(state).includes(ownProps.layer.getId()), isEditButtonDisabled: flyoutDisplay !== FLYOUT_STATE.NONE && flyoutDisplay !== FLYOUT_STATE.LAYER_PANEL, - editModeActiveForLayer: - (getDrawMode(state) === DRAW_MODE.DRAW_SHAPES || - getDrawMode(state) === DRAW_MODE.DRAW_POINTS) && - !!getEditState(state) && - getEditState(state)!.layerId === ownProps.layer.getId(), + editModeActiveForLayer: getEditState(state)?.layerId === ownProps.layer.getId(), }; } diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx index 6e0746b2dc8437..6a7a42a0d8df20 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx @@ -63,7 +63,7 @@ export class TOCEntryActionsPopover extends Component { return; } const isLayerEditable = await this.props.layer.isEditable(); - const editModeEnabled = await this.props.layer.getEditModeEnabled(); + const editModeEnabled = await this._getEditModeEnabled(); if ( !this._isMounted || (isLayerEditable === this.state.isLayerEditable && @@ -74,6 +74,20 @@ export class TOCEntryActionsPopover extends Component { this.setState({ isLayerEditable, editModeEnabled }); } + async _getEditModeEnabled(): Promise { + const vectorLayer = this.props.layer as VectorLayer; + if ( + !(await vectorLayer.isEditable()) || + (await vectorLayer.isFilteredByGlobalTime()) || + vectorLayer.isPreviewLayer() || + !vectorLayer.isVisible() || + vectorLayer.hasJoins() + ) { + return false; + } + return true; + } + _togglePopover = () => { this.setState((prevState) => ({ isPopoverOpen: !prevState.isPopoverOpen, diff --git a/x-pack/plugins/maps/public/selectors/map_selectors.ts b/x-pack/plugins/maps/public/selectors/map_selectors.ts index a2eb06f20cb263..609b830f2f5129 100644 --- a/x-pack/plugins/maps/public/selectors/map_selectors.ts +++ b/x-pack/plugins/maps/public/selectors/map_selectors.ts @@ -56,6 +56,7 @@ import { ITMSSource } from '../classes/sources/tms_source'; import { IVectorSource } from '../classes/sources/vector_source'; import { ESGeoGridSource } from '../classes/sources/es_geo_grid_source'; import { ILayer } from '../classes/layers/layer'; +import { getIsReadOnly } from './ui_selectors'; export function createLayerInstance( layerDescriptor: LayerDescriptor, @@ -229,6 +230,7 @@ export const getDataFilters = createSelector( getFilters, getSearchSessionId, getSearchSessionMapBuffer, + getIsReadOnly, ( mapExtent, mapBuffer, @@ -239,7 +241,8 @@ export const getDataFilters = createSelector( query, filters, searchSessionId, - searchSessionMapBuffer + searchSessionMapBuffer, + isReadOnly ) => { return { extent: mapExtent, @@ -251,6 +254,7 @@ export const getDataFilters = createSelector( query, filters, searchSessionId, + isReadOnly, }; } ); diff --git a/x-pack/plugins/maps/server/data_indexing/get_indexes_matching_pattern.ts b/x-pack/plugins/maps/server/data_indexing/get_indexes_matching_pattern.ts index dc575ca0abcf2d..c8b55ffe2e0875 100644 --- a/x-pack/plugins/maps/server/data_indexing/get_indexes_matching_pattern.ts +++ b/x-pack/plugins/maps/server/data_indexing/get_indexes_matching_pattern.ts @@ -6,7 +6,6 @@ */ import { IScopedClusterClient } from 'kibana/server'; -import { CatIndicesRecord } from '@elastic/elasticsearch/api/types'; import { MatchingIndexesResp } from '../../common'; export async function getMatchingIndexes( @@ -19,7 +18,7 @@ export async function getMatchingIndexes( format: 'JSON', }); const matchingIndexes = indexResults - .map((indexRecord: CatIndicesRecord) => indexRecord.index) + .map((indexRecord) => indexRecord.index) .filter((indexName) => !!indexName); return { success: true, @@ -28,6 +27,7 @@ export async function getMatchingIndexes( } catch (error) { return { success: false, + error, }; } } diff --git a/x-pack/plugins/maps/server/data_indexing/indexing_routes.ts b/x-pack/plugins/maps/server/data_indexing/indexing_routes.ts index f5bf63180aede8..b137978025f869 100644 --- a/x-pack/plugins/maps/server/data_indexing/indexing_routes.ts +++ b/x-pack/plugins/maps/server/data_indexing/indexing_routes.ts @@ -118,17 +118,7 @@ export function initIndexingRoutes({ request.params.indexPattern, context.core.elasticsearch.client ); - if (result.success) { - return response.ok({ body: result }); - } else { - if (result.error) { - logger.error(result.error); - } - return response.custom({ - body: result?.error?.message, - statusCode: 500, - }); - } + return response.ok({ body: result }); } ); } From 0bd9cfbb6ac7fe441a3ecedbba7a585579636915 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 9 Jun 2021 10:44:25 -0600 Subject: [PATCH 085/103] Type fixes --- .../classes/layers/__fixtures__/mock_sync_context.ts | 1 + .../sources/es_geo_grid_source/es_geo_grid_source.test.ts | 1 + .../sources/es_search_source/es_search_source.test.ts | 1 + x-pack/plugins/maps/public/selectors/map_selectors.test.ts | 7 +++++-- 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/layers/__fixtures__/mock_sync_context.ts b/x-pack/plugins/maps/public/classes/layers/__fixtures__/mock_sync_context.ts index 3ffa99f6afe49b..dd1367605376d7 100644 --- a/x-pack/plugins/maps/public/classes/layers/__fixtures__/mock_sync_context.ts +++ b/x-pack/plugins/maps/public/classes/layers/__fixtures__/mock_sync_context.ts @@ -28,6 +28,7 @@ export class MockSyncContext implements DataRequestContext { mode: 'relative', }, zoom: 0, + isReadOnly: false, ...dataFilters, }; diff --git a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.test.ts b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.test.ts index ad413419a289b1..96a9cc6c33f4ce 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.test.ts +++ b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.test.ts @@ -144,6 +144,7 @@ describe('ESGeoGridSource', () => { }; const vectorSourceRequestMeta: VectorSourceRequestMeta = { + isReadOnly: false, geogridPrecision: 4, filters: [], timeFilters: { diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.test.ts b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.test.ts index 014dfe7da929ba..cbd02ad06c9a53 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.test.ts +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.test.ts @@ -90,6 +90,7 @@ describe('ESSearchSource', () => { }); const searchFilters: VectorSourceRequestMeta = { + isReadOnly: false, filters: [], zoom: 0, fieldNames: ['tooltipField', 'styleField'], diff --git a/x-pack/plugins/maps/public/selectors/map_selectors.test.ts b/x-pack/plugins/maps/public/selectors/map_selectors.test.ts index cf739957a39937..a1b8ad97acb9ff 100644 --- a/x-pack/plugins/maps/public/selectors/map_selectors.test.ts +++ b/x-pack/plugins/maps/public/selectors/map_selectors.test.ts @@ -68,6 +68,7 @@ describe('getDataFilters', () => { minLat: -0.25, minLon: -0.25, }; + const isReadOnly = false; test('should set buffer as searchSessionMapBuffer when using searchSessionId', () => { const dataFilters = getDataFilters.resultFunc( @@ -80,7 +81,8 @@ describe('getDataFilters', () => { query, filters, searchSessionId, - searchSessionMapBuffer + searchSessionMapBuffer, + isReadOnly ); expect(dataFilters.buffer).toEqual(searchSessionMapBuffer); }); @@ -96,7 +98,8 @@ describe('getDataFilters', () => { query, filters, searchSessionId, - undefined + undefined, + isReadOnly ); expect(dataFilters.buffer).toEqual(mapBuffer); }); From a4fe3476bb54a2d0d4b32b3b3d31d64a0af56581 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 9 Jun 2021 14:51:43 -0600 Subject: [PATCH 086/103] Add functional tests for index pattern matching endpoint --- .../apis/maps/get_indexes_matching_pattern.js | 35 +++++++++++++++++++ .../test/api_integration/apis/maps/index.js | 1 + 2 files changed, 36 insertions(+) create mode 100644 x-pack/test/api_integration/apis/maps/get_indexes_matching_pattern.js diff --git a/x-pack/test/api_integration/apis/maps/get_indexes_matching_pattern.js b/x-pack/test/api_integration/apis/maps/get_indexes_matching_pattern.js new file mode 100644 index 00000000000000..b272575f52964f --- /dev/null +++ b/x-pack/test/api_integration/apis/maps/get_indexes_matching_pattern.js @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; + +export default function ({ getService }) { + const supertest = getService('supertest'); + + describe('get matching index patterns', () => { + it('should return an array containing indexes matching pattern', async () => { + const resp = await supertest + .get(`/api/maps/getMatchingIndexes/geo_shapes`) + .set('kbn-xsrf', 'kibana') + .send() + .expect(200); + + expect(resp.body.success).to.be(true); + expect(resp.body.matchingIndexes.length).to.be.greaterThan(0); + }); + + it('should return an empty array when no indexes match pattern', async () => { + const resp = await supertest + .get(`/api/maps/getMatchingIndexes/notAnIndex`) + .set('kbn-xsrf', 'kibana') + .send() + .expect(200); + + expect(resp.body.success).to.be(false); + }); + }); +} diff --git a/x-pack/test/api_integration/apis/maps/index.js b/x-pack/test/api_integration/apis/maps/index.js index dc39d7ce36931a..14a42e06dbb9a0 100644 --- a/x-pack/test/api_integration/apis/maps/index.js +++ b/x-pack/test/api_integration/apis/maps/index.js @@ -15,6 +15,7 @@ export default function ({ loadTestFile, getService }) { }); describe('', () => { + loadTestFile(require.resolve('./get_indexes_matching_pattern')); loadTestFile(require.resolve('./create_doc_source')); loadTestFile(require.resolve('./index_data')); loadTestFile(require.resolve('./fonts_api')); From bd6c2f974df16bde556882b8bc3cc42838c21312 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 9 Jun 2021 15:29:32 -0600 Subject: [PATCH 087/103] Remove unneeded function --- x-pack/plugins/maps/public/util.ts | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/x-pack/plugins/maps/public/util.ts b/x-pack/plugins/maps/public/util.ts index e56c0841ee381d..ea0328ba91b27c 100644 --- a/x-pack/plugins/maps/public/util.ts +++ b/x-pack/plugins/maps/public/util.ts @@ -11,6 +11,7 @@ import { FeatureCollection, Geometry, Position } from 'geojson'; import * as topojson from 'topojson-client'; import { GeometryCollection } from 'topojson-specification'; import _ from 'lodash'; +import { set } from '@elastic/safer-lodash-set'; import fetch from 'node-fetch'; import { GET_MATCHING_INDEXES_PATH, INDEX_FEATURE_PATH } from '../common'; @@ -163,7 +164,7 @@ export const addFeatureToIndex = async ( geometry: Geometry | Position[], path: string ) => { - const data = convertDotNotationStringToObj(path, geometry); + const data = set({}, path, geometry); return await getHttp().fetch({ path: `${INDEX_FEATURE_PATH}`, method: 'POST', @@ -174,17 +175,6 @@ export const addFeatureToIndex = async ( }); }; -const convertDotNotationStringToObj = ( - dotNotationStr: string, - value: unknown -): Record => { - const container: Record = {}; - dotNotationStr.split('.').map((k, i, values) => { - container[k] = i === values.length - 1 ? value : {}; - }); - return container; -}; - export const getMatchingIndexes = async (indexPattern: string) => { return await getHttp().fetch({ path: `${GET_MATCHING_INDEXES_PATH}/${indexPattern}`, From 5c15ccffda2ababcf69c791e7f68f21dfd147222 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 9 Jun 2021 17:04:28 -0600 Subject: [PATCH 088/103] Update functional test --- x-pack/test/functional/page_objects/gis_page.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/test/functional/page_objects/gis_page.ts b/x-pack/test/functional/page_objects/gis_page.ts index c2c92b2370381a..002dc575e956bd 100644 --- a/x-pack/test/functional/page_objects/gis_page.ts +++ b/x-pack/test/functional/page_objects/gis_page.ts @@ -312,7 +312,7 @@ export class GisPageObject extends FtrService { async openLayerPanel(layerName: string) { this.log.debug(`Open layer panel, layer: ${layerName}`); await this.openLayerTocActionsPanel(layerName); - await this.testSubjects.click('editLayerButton'); + await this.testSubjects.click('layerSettingsButton'); } async closeLayerPanel() { From a80006214496a1715ab0db892bb5b7f2393f6af7 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 9 Jun 2021 17:40:02 -0600 Subject: [PATCH 089/103] Disable draw mode when adjusting layer settings --- .../plugins/maps/public/actions/layer_actions.ts | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/maps/public/actions/layer_actions.ts b/x-pack/plugins/maps/public/actions/layer_actions.ts index 90ec515b3ef402..8bd79474e7f71d 100644 --- a/x-pack/plugins/maps/public/actions/layer_actions.ts +++ b/x-pack/plugins/maps/public/actions/layer_actions.ts @@ -10,17 +10,17 @@ import { ThunkDispatch } from 'redux-thunk'; import { Query } from 'src/plugins/data/public'; import { MapStoreState } from '../reducers/store'; import { + createLayerInstance, getLayerById, getLayerList, getLayerListRaw, - getSelectedLayerId, - getMapReady, getMapColors, - createLayerInstance, + getMapReady, + getSelectedLayerId, } from '../selectors/map_selectors'; import { FLYOUT_STATE } from '../reducers/ui'; import { cancelRequest } from '../reducers/non_serializable_instances'; -import { updateFlyout } from './ui_actions'; +import { setDrawMode, updateFlyout } from './ui_actions'; import { ADD_LAYER, ADD_WAITING_FOR_MAP_READY_LAYER, @@ -49,11 +49,12 @@ import { } from '../../common/descriptor_types'; import { ILayer } from '../classes/layers/layer'; import { IVectorLayer } from '../classes/layers/vector_layer'; -import { LAYER_STYLE_TYPE, LAYER_TYPE } from '../../common/constants'; +import { DRAW_MODE, LAYER_STYLE_TYPE, LAYER_TYPE } from '../../common/constants'; import { IVectorStyle } from '../classes/styles/vector/vector_style'; import { notifyLicensedFeatureUsage } from '../licensed_features'; import { IESAggField } from '../classes/fields/agg'; import { IField } from '../classes/fields/field'; +import { getDrawMode } from '../selectors/ui_selectors'; export function trackCurrentLayerState(layerId: string) { return { @@ -255,6 +256,9 @@ export function setSelectedLayer(layerId: string | null) { if (layerId) { dispatch(trackCurrentLayerState(layerId)); } + if (getDrawMode(getState()) !== DRAW_MODE.NONE) { + dispatch(setDrawMode(DRAW_MODE.NONE)); + } dispatch({ type: SET_SELECTED_LAYER, selectedLayerId: layerId, From a198ecc215ff81f1bc83271c89fcae3aec08857f Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 9 Jun 2021 17:40:53 -0600 Subject: [PATCH 090/103] Prevent occasional error on startup where dataRequest > getData returns nothing --- .../maps/public/classes/layers/vector_layer/vector_layer.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx index 96f99c9141d844..56f387a29a30d8 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx @@ -182,7 +182,10 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { isEditable(): boolean { const isEditable = this.getDataRequest(IS_EDITABLE_REQUEST_ID); - return isEditable ? (isEditable.getData() as EditableData).isEditable : false; + if (!(isEditable && isEditable.getData())) { + return false; + } + return (isEditable.getData() as EditableData).isEditable; } hasJoins() { From f1dabb0f6120168b93db233b895b47f1ffd38316 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Thu, 10 Jun 2021 11:44:54 -0600 Subject: [PATCH 091/103] Review feedback. Clean up, optimizations --- .../maps/public/actions/tooltip_actions.ts | 8 ++--- .../classes/layers/vector_layer/utils.tsx | 10 +++--- .../layers/vector_layer/vector_layer.tsx | 18 +++------- .../es_search_source/create_source_editor.js | 2 +- .../es_search_source/es_search_source.test.ts | 2 +- .../es_search_source/es_search_source.tsx | 14 +++++--- .../top_hits/top_hits_form.tsx | 2 +- .../es_search_source/update_source_editor.js | 2 +- .../es_search_source/util/feature_edit.ts | 34 +++++++++++++++++++ .../get_docvalue_source_fields.test.ts | 4 +-- .../{ => util}/get_docvalue_source_fields.ts | 4 +-- .../{ => util}/load_index_settings.ts | 6 ++-- .../{ => util}/scaling_form.test.tsx | 2 +- .../{ => util}/scaling_form.tsx | 14 +++++--- x-pack/plugins/maps/public/util.ts | 28 +-------------- .../apis/maps/get_indexes_matching_pattern.js | 2 +- 16 files changed, 80 insertions(+), 72 deletions(-) create mode 100644 x-pack/plugins/maps/public/classes/sources/es_search_source/util/feature_edit.ts rename x-pack/plugins/maps/public/classes/sources/es_search_source/{ => util}/get_docvalue_source_fields.test.ts (84%) rename x-pack/plugins/maps/public/classes/sources/es_search_source/{ => util}/get_docvalue_source_fields.ts (89%) rename x-pack/plugins/maps/public/classes/sources/es_search_source/{ => util}/load_index_settings.ts (87%) rename x-pack/plugins/maps/public/classes/sources/es_search_source/{ => util}/scaling_form.test.tsx (95%) rename x-pack/plugins/maps/public/classes/sources/es_search_source/{ => util}/scaling_form.tsx (89%) diff --git a/x-pack/plugins/maps/public/actions/tooltip_actions.ts b/x-pack/plugins/maps/public/actions/tooltip_actions.ts index 8e40e1cf2e504f..c1b5f8190a73a8 100644 --- a/x-pack/plugins/maps/public/actions/tooltip_actions.ts +++ b/x-pack/plugins/maps/public/actions/tooltip_actions.ts @@ -56,11 +56,9 @@ export function closeOnHoverTooltip() { } export function openOnHoverTooltip(tooltipState: TooltipState) { - return (dispatch: Dispatch) => { - dispatch({ - type: SET_OPEN_TOOLTIPS, - openTooltips: [tooltipState], - }); + return { + type: SET_OPEN_TOOLTIPS, + openTooltips: [tooltipState], }; } diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/utils.tsx b/x-pack/plugins/maps/public/classes/layers/vector_layer/utils.tsx index a4e0b9beffbcc7..d305bb920b2ad0 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/utils.tsx +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/utils.tsx @@ -69,15 +69,15 @@ export async function syncVectorSource({ } = syncContext; const dataRequestId = SOURCE_DATA_REQUEST_ID; const requestToken = Symbol(`${layerId}-${dataRequestId}`); - const doRefresh = syncContext.forceRefresh - ? true - : !(await canSkipSourceUpdate({ + const canSkipFetch = syncContext.forceRefresh + ? false + : await canSkipSourceUpdate({ source, prevDataRequest, nextMeta: requestMeta, extentAware: source.isFilterByMapBounds(), - })); - if (!doRefresh) { + }); + if (canSkipFetch) { return { refreshed: false, featureCollection: prevDataRequest diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx index 56f387a29a30d8..c0a6061d98dd48 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx @@ -76,10 +76,6 @@ interface JoinState { propertiesMap?: PropertiesMap; } -interface EditableData { - isEditable: boolean; -} - export interface VectorLayerArguments { source: IVectorSource; joins?: InnerJoin[]; @@ -181,11 +177,9 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { } isEditable(): boolean { - const isEditable = this.getDataRequest(IS_EDITABLE_REQUEST_ID); - if (!(isEditable && isEditable.getData())) { - return false; - } - return (isEditable.getData() as EditableData).isEditable; + const dataRequest = this.getDataRequest(IS_EDITABLE_REQUEST_ID); + const data = dataRequest?.getData() as { isEditable: boolean } | undefined; + return data ? data.isEditable : false; } hasJoins() { @@ -717,9 +711,7 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { const isEditable = await this.getSource().loadIsEditable(); stopLoading(dataRequestId, requestToken, { isEditable }); } catch (error) { - if (!(error instanceof DataRequestAbortError)) { - onLoadError(dataRequestId, requestToken, error.message); - } + onLoadError(dataRequestId, requestToken, error.message); throw error; } } @@ -1096,7 +1088,7 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { } async addFeature(geometry: Geometry | Position[]) { - const layerSource = await this.getSource(); + const layerSource = this.getSource(); await layerSource.addFeature(geometry); } } diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/create_source_editor.js b/x-pack/plugins/maps/public/classes/sources/es_search_source/create_source_editor.js index 59264dad3f874e..2137706bec4a8c 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/create_source_editor.js +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/create_source_editor.js @@ -14,7 +14,7 @@ import { GeoIndexPatternSelect } from '../../../components/geo_index_pattern_sel import { i18n } from '@kbn/i18n'; import { SCALING_TYPES } from '../../../../common/constants'; import { DEFAULT_FILTER_BY_MAP_BOUNDS } from './constants'; -import { ScalingForm } from './scaling_form'; +import { ScalingForm } from './util/scaling_form'; import { getGeoFields, getGeoTileAggNotSupportedReason, diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.test.ts b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.test.ts index cbd02ad06c9a53..c1d01cbec2ab8b 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.test.ts +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.test.ts @@ -13,7 +13,7 @@ jest.mock('./load_index_settings'); import { getIndexPatternService, getSearchService, getHttp } from '../../../kibana_services'; import { SearchSource } from 'src/plugins/data/public'; -import { loadIndexSettings } from './load_index_settings'; +import { loadIndexSettings } from './util/load_index_settings'; import { ESSearchSource } from './es_search_source'; import { VectorSourceRequestMeta } from '../../../../common/descriptor_types'; diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx index 3c2c2688cb97cc..a3f8ce8e51edea 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx @@ -36,7 +36,7 @@ import { } from '../../../../common/constants'; import { getDataSourceLabel } from '../../../../common/i18n_getters'; import { getSourceFields } from '../../../index_pattern_util'; -import { loadIndexSettings } from './load_index_settings'; +import { loadIndexSettings } from './util/load_index_settings'; import { DEFAULT_FILTER_BY_MAP_BOUNDS } from './constants'; import { ESDocField } from '../../fields/es_doc_field'; import { registerSource } from '../source_registry'; @@ -55,9 +55,9 @@ import { DataRequest } from '../../util/data_request'; import { SortDirection, SortDirectionNumeric } from '../../../../../../../src/plugins/data/common'; import { isValidStringConfig } from '../../util/valid_string_config'; import { TopHitsUpdateSourceEditor } from './top_hits'; -import { getDocValueAndSourceFields, ScriptField } from './get_docvalue_source_fields'; +import { getDocValueAndSourceFields, ScriptField } from './util/get_docvalue_source_fields'; import { ITiledSingleLayerMvtParams } from '../tiled_single_layer_vector_source/tiled_single_layer_vector_source'; -import { addFeatureToIndex, getMatchingIndexes } from '../../../util'; +import { addFeatureToIndex, getMatchingIndexes } from './util/feature_edit'; export const sourceTitle = i18n.translate('xpack.maps.source.esSearchTitle', { defaultMessage: 'Documents', @@ -394,7 +394,13 @@ export class ESSearchSource extends AbstractESSource implements ITiledSingleLaye return false; } await this.getIndexPattern(); - const { matchingIndexes } = await getMatchingIndexes(this.indexPattern!.title); + if (!(this.indexPattern && this.indexPattern.title)) { + return false; + } + const { matchingIndexes } = await getMatchingIndexes(this.indexPattern.title); + if (!matchingIndexes) { + return false; + } // For now we only support 1:1 index-pattern:index matches return matchingIndexes.length === 1; } diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/top_hits/top_hits_form.tsx b/x-pack/plugins/maps/public/classes/sources/es_search_source/top_hits/top_hits_form.tsx index 83831f84e77f98..79d6039076f81c 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/top_hits/top_hits_form.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/top_hits/top_hits_form.tsx @@ -13,7 +13,7 @@ import { getIndexPatternService } from '../../../../kibana_services'; // @ts-expect-error import { ValidatedRange } from '../../../../components/validated_range'; import { DEFAULT_MAX_INNER_RESULT_WINDOW } from '../../../../../common/constants'; -import { loadIndexSettings } from '../load_index_settings'; +import { loadIndexSettings } from '../util/load_index_settings'; import { OnSourceChangeArgs } from '../../source'; import { IFieldType, SortDirection } from '../../../../../../../../src/plugins/data/public'; diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/update_source_editor.js b/x-pack/plugins/maps/public/classes/sources/es_search_source/update_source_editor.js index 86326660110651..7e9c864c508438 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/update_source_editor.js +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/update_source_editor.js @@ -23,7 +23,7 @@ import { SortDirection, indexPatterns } from '../../../../../../../src/plugins/d import { ESDocField } from '../../fields/es_doc_field'; import { FormattedMessage } from '@kbn/i18n/react'; -import { ScalingForm } from './scaling_form'; +import { ScalingForm } from './util/scaling_form'; export class UpdateSourceEditor extends Component { static propTypes = { diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/util/feature_edit.ts b/x-pack/plugins/maps/public/classes/sources/es_search_source/util/feature_edit.ts new file mode 100644 index 00000000000000..ac8e2ba42f2829 --- /dev/null +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/util/feature_edit.ts @@ -0,0 +1,34 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Geometry, Position } from 'geojson'; +import { set } from '@elastic/safer-lodash-set'; +import { GET_MATCHING_INDEXES_PATH, INDEX_FEATURE_PATH } from '../../../../../common'; +import { getHttp } from '../../../../kibana_services'; + +export const addFeatureToIndex = async ( + indexName: string, + geometry: Geometry | Position[], + path: string +) => { + const data = set({}, path, geometry); + return await getHttp().fetch({ + path: `${INDEX_FEATURE_PATH}`, + method: 'POST', + body: JSON.stringify({ + index: indexName, + data, + }), + }); +}; + +export const getMatchingIndexes = async (indexPattern: string) => { + return await getHttp().fetch({ + path: `${GET_MATCHING_INDEXES_PATH}/${indexPattern}`, + method: 'GET', + }); +}; diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/get_docvalue_source_fields.test.ts b/x-pack/plugins/maps/public/classes/sources/es_search_source/util/get_docvalue_source_fields.test.ts similarity index 84% rename from x-pack/plugins/maps/public/classes/sources/es_search_source/get_docvalue_source_fields.test.ts rename to x-pack/plugins/maps/public/classes/sources/es_search_source/util/get_docvalue_source_fields.test.ts index 41744c4343f971..0a24c140d735fa 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/get_docvalue_source_fields.test.ts +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/util/get_docvalue_source_fields.test.ts @@ -6,8 +6,8 @@ */ import { getDocValueAndSourceFields } from './get_docvalue_source_fields'; -import { IndexPattern } from '../../../../../../../src/plugins/data/common/index_patterns/index_patterns'; -import { IFieldType } from '../../../../../../../src/plugins/data/common/index_patterns/fields'; +import { IndexPattern } from '../../../../../../../../src/plugins/data/common/index_patterns/index_patterns'; +import { IFieldType } from '../../../../../../../../src/plugins/data/common/index_patterns/fields'; function createMockIndexPattern(fields: IFieldType[]): IndexPattern { const indexPattern = { diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/get_docvalue_source_fields.ts b/x-pack/plugins/maps/public/classes/sources/es_search_source/util/get_docvalue_source_fields.ts similarity index 89% rename from x-pack/plugins/maps/public/classes/sources/es_search_source/get_docvalue_source_fields.ts rename to x-pack/plugins/maps/public/classes/sources/es_search_source/util/get_docvalue_source_fields.ts index a8d10233b4d547..78823f4631cacd 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/get_docvalue_source_fields.ts +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/util/get_docvalue_source_fields.ts @@ -5,8 +5,8 @@ * 2.0. */ -import { IndexPattern } from '../../../../../../../src/plugins/data/common/index_patterns/index_patterns'; -import { getField } from '../../../../common/elasticsearch_util'; +import { IndexPattern } from '../../../../../../../../src/plugins/data/common/index_patterns/index_patterns'; +import { getField } from '../../../../../common/elasticsearch_util'; export interface ScriptField { source: string; diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/load_index_settings.ts b/x-pack/plugins/maps/public/classes/sources/es_search_source/util/load_index_settings.ts similarity index 87% rename from x-pack/plugins/maps/public/classes/sources/es_search_source/load_index_settings.ts rename to x-pack/plugins/maps/public/classes/sources/es_search_source/util/load_index_settings.ts index 4ed38f14b3c1d8..9dbc02d5661fa1 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/load_index_settings.ts +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/util/load_index_settings.ts @@ -5,13 +5,13 @@ * 2.0. */ -import { i18n } from '@kbn/i18n'; +import { i18n } from '../../../../../../../../../../../.cache/bazel/_bazel_aaron/624b00c49acd21a09431ae49da30ba85/execroot/kibana/bazel-out/k8-fastbuild/bin/packages/kbn-i18n'; import { DEFAULT_MAX_RESULT_WINDOW, DEFAULT_MAX_INNER_RESULT_WINDOW, INDEX_SETTINGS_API_PATH, -} from '../../../../common/constants'; -import { getHttp, getToasts } from '../../../kibana_services'; +} from '../../../../../common/constants'; +import { getHttp, getToasts } from '../../../../kibana_services'; let toastDisplayed = false; const indexSettings = new Map>(); diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/scaling_form.test.tsx b/x-pack/plugins/maps/public/classes/sources/es_search_source/util/scaling_form.test.tsx similarity index 95% rename from x-pack/plugins/maps/public/classes/sources/es_search_source/scaling_form.test.tsx rename to x-pack/plugins/maps/public/classes/sources/es_search_source/util/scaling_form.test.tsx index b02eacc1334672..6d2bb9d8a48f4c 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/scaling_form.test.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/util/scaling_form.test.tsx @@ -17,7 +17,7 @@ import React from 'react'; import { shallow } from 'enzyme'; import { ScalingForm } from './scaling_form'; -import { SCALING_TYPES } from '../../../../common/constants'; +import { SCALING_TYPES } from '../../../../../common/constants'; const defaultProps = { filterByMapBounds: true, diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/scaling_form.tsx b/x-pack/plugins/maps/public/classes/sources/es_search_source/util/scaling_form.tsx similarity index 89% rename from x-pack/plugins/maps/public/classes/sources/es_search_source/scaling_form.tsx rename to x-pack/plugins/maps/public/classes/sources/es_search_source/util/scaling_form.tsx index 5d095035331f8c..8f6b2f4e317744 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/scaling_form.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/util/scaling_form.tsx @@ -17,12 +17,16 @@ import { EuiToolTip, EuiBetaBadge, } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n/react'; -import { getIndexPatternService } from '../../../kibana_services'; -import { DEFAULT_MAX_RESULT_WINDOW, LAYER_TYPE, SCALING_TYPES } from '../../../../common/constants'; +import { i18n } from '../../../../../../../../../../../.cache/bazel/_bazel_aaron/624b00c49acd21a09431ae49da30ba85/execroot/kibana/bazel-out/k8-fastbuild/bin/packages/kbn-i18n'; +import { FormattedMessage } from '../../../../../../../../../../../.cache/bazel/_bazel_aaron/624b00c49acd21a09431ae49da30ba85/execroot/kibana/bazel-out/k8-fastbuild/bin/packages/kbn-i18n/target_types/react'; +import { getIndexPatternService } from '../../../../kibana_services'; +import { + DEFAULT_MAX_RESULT_WINDOW, + LAYER_TYPE, + SCALING_TYPES, +} from '../../../../../common/constants'; import { loadIndexSettings } from './load_index_settings'; -import { OnSourceChangeArgs } from '../source'; +import { OnSourceChangeArgs } from '../../source'; interface Props { filterByMapBounds: boolean; diff --git a/x-pack/plugins/maps/public/util.ts b/x-pack/plugins/maps/public/util.ts index ea0328ba91b27c..16743c00491166 100644 --- a/x-pack/plugins/maps/public/util.ts +++ b/x-pack/plugins/maps/public/util.ts @@ -7,14 +7,11 @@ import { i18n } from '@kbn/i18n'; import { EMSClient, FileLayer, TMSService } from '@elastic/ems-client'; -import { FeatureCollection, Geometry, Position } from 'geojson'; +import { FeatureCollection } from 'geojson'; import * as topojson from 'topojson-client'; import { GeometryCollection } from 'topojson-specification'; import _ from 'lodash'; -import { set } from '@elastic/safer-lodash-set'; import fetch from 'node-fetch'; -import { GET_MATCHING_INDEXES_PATH, INDEX_FEATURE_PATH } from '../common'; - import { GIS_API_PATH, EMS_FILES_CATALOGUE_PATH, @@ -158,26 +155,3 @@ export async function fetchGeoJson( }) ); } - -export const addFeatureToIndex = async ( - indexName: string, - geometry: Geometry | Position[], - path: string -) => { - const data = set({}, path, geometry); - return await getHttp().fetch({ - path: `${INDEX_FEATURE_PATH}`, - method: 'POST', - body: JSON.stringify({ - index: indexName, - data, - }), - }); -}; - -export const getMatchingIndexes = async (indexPattern: string) => { - return await getHttp().fetch({ - path: `${GET_MATCHING_INDEXES_PATH}/${indexPattern}`, - method: 'GET', - }); -}; diff --git a/x-pack/test/api_integration/apis/maps/get_indexes_matching_pattern.js b/x-pack/test/api_integration/apis/maps/get_indexes_matching_pattern.js index b272575f52964f..4129fdd02b72bf 100644 --- a/x-pack/test/api_integration/apis/maps/get_indexes_matching_pattern.js +++ b/x-pack/test/api_integration/apis/maps/get_indexes_matching_pattern.js @@ -19,7 +19,7 @@ export default function ({ getService }) { .expect(200); expect(resp.body.success).to.be(true); - expect(resp.body.matchingIndexes.length).to.be.greaterThan(0); + expect(resp.body.matchingIndexes.length).to.be(1); }); it('should return an empty array when no indexes match pattern', async () => { From 8e54e393c63b0d5aaed211ca80df647fb63bfc5b Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Thu, 10 Jun 2021 12:46:51 -0600 Subject: [PATCH 092/103] Fix imports bungled during move --- .../sources/es_search_source/util/load_index_settings.ts | 2 +- .../classes/sources/es_search_source/util/scaling_form.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/util/load_index_settings.ts b/x-pack/plugins/maps/public/classes/sources/es_search_source/util/load_index_settings.ts index 9dbc02d5661fa1..5e4748fb168199 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/util/load_index_settings.ts +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/util/load_index_settings.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { i18n } from '../../../../../../../../../../../.cache/bazel/_bazel_aaron/624b00c49acd21a09431ae49da30ba85/execroot/kibana/bazel-out/k8-fastbuild/bin/packages/kbn-i18n'; +import { i18n } from '@kbn/i18n'; import { DEFAULT_MAX_RESULT_WINDOW, DEFAULT_MAX_INNER_RESULT_WINDOW, diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/util/scaling_form.tsx b/x-pack/plugins/maps/public/classes/sources/es_search_source/util/scaling_form.tsx index 8f6b2f4e317744..beb26c3b99feb1 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/util/scaling_form.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/util/scaling_form.tsx @@ -17,8 +17,8 @@ import { EuiToolTip, EuiBetaBadge, } from '@elastic/eui'; -import { i18n } from '../../../../../../../../../../../.cache/bazel/_bazel_aaron/624b00c49acd21a09431ae49da30ba85/execroot/kibana/bazel-out/k8-fastbuild/bin/packages/kbn-i18n'; -import { FormattedMessage } from '../../../../../../../../../../../.cache/bazel/_bazel_aaron/624b00c49acd21a09431ae49da30ba85/execroot/kibana/bazel-out/k8-fastbuild/bin/packages/kbn-i18n/target_types/react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; import { getIndexPatternService } from '../../../../kibana_services'; import { DEFAULT_MAX_RESULT_WINDOW, From f79df81a544458dff8894cd96a0faa9381ae39f3 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Thu, 10 Jun 2021 16:22:05 -0600 Subject: [PATCH 093/103] Update jest test paths and snapshot locations --- .../classes/sources/es_search_source/es_search_source.test.ts | 2 +- .../sources/es_search_source/update_source_editor.test.js | 2 +- .../{ => util}/__snapshots__/scaling_form.test.tsx.snap | 0 .../classes/sources/es_search_source/util/scaling_form.test.tsx | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename x-pack/plugins/maps/public/classes/sources/es_search_source/{ => util}/__snapshots__/scaling_form.test.tsx.snap (100%) diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.test.ts b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.test.ts index c1d01cbec2ab8b..1a5ea8bb14e0e4 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.test.ts +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.test.ts @@ -8,7 +8,7 @@ import { ES_GEO_FIELD_TYPE, SCALING_TYPES } from '../../../../common/constants'; jest.mock('../../../kibana_services'); -jest.mock('./load_index_settings'); +jest.mock('./util/load_index_settings'); import { getIndexPatternService, getSearchService, getHttp } from '../../../kibana_services'; import { SearchSource } from 'src/plugins/data/public'; diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/update_source_editor.test.js b/x-pack/plugins/maps/public/classes/sources/es_search_source/update_source_editor.test.js index f54947bc91d192..cfc2090f537f2c 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/update_source_editor.test.js +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/update_source_editor.test.js @@ -7,7 +7,7 @@ jest.mock('../../../kibana_services', () => ({})); -jest.mock('./load_index_settings', () => ({ +jest.mock('./util/load_index_settings', () => ({ loadIndexSettings: async () => { return { maxInnerResultWindow: 100 }; }, diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/__snapshots__/scaling_form.test.tsx.snap b/x-pack/plugins/maps/public/classes/sources/es_search_source/util/__snapshots__/scaling_form.test.tsx.snap similarity index 100% rename from x-pack/plugins/maps/public/classes/sources/es_search_source/__snapshots__/scaling_form.test.tsx.snap rename to x-pack/plugins/maps/public/classes/sources/es_search_source/util/__snapshots__/scaling_form.test.tsx.snap diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/util/scaling_form.test.tsx b/x-pack/plugins/maps/public/classes/sources/es_search_source/util/scaling_form.test.tsx index 6d2bb9d8a48f4c..c02d855f13aa4c 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/util/scaling_form.test.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/util/scaling_form.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -jest.mock('../../../kibana_services', () => ({})); +jest.mock('../../../../kibana_services', () => ({})); jest.mock('./load_index_settings', () => ({ loadIndexSettings: async () => { From aba98cc0582f6d7a8cd62ea3cef3f2b337f986da Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Mon, 14 Jun 2021 13:55:43 -0600 Subject: [PATCH 094/103] Review feedback. Update onDraw callback to be single function with 2 args --- .../mb_map/draw_control/draw_control.tsx | 16 +++++++--------- .../draw_feature_control.tsx | 2 +- .../draw_filter_control/draw_filter_control.tsx | 2 +- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx index 5d35094a21c0a8..13ae3584478f32 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx @@ -39,7 +39,7 @@ mbDrawModes[DRAW_CIRCLE] = DrawCircle; export interface Props { drawShape?: DRAW_SHAPE; - onDraw: (drawControl: MapboxDraw) => (event: { features: Feature[] }) => void; + onDraw: (event: { features: Feature[] }, drawControl?: MapboxDraw) => void; mbMap: MbMap; drawActive: boolean; updateEditShape: (shapeToDraw: DRAW_SHAPE) => void; @@ -52,7 +52,6 @@ export class DrawControl extends Component { displayControlsDefault: false, modes: mbDrawModes, }); - private _drawFunction: ((event: { features: Feature[] }) => void) | null = null; componentWillReceiveProps() { this._syncDrawControl(); @@ -60,7 +59,6 @@ export class DrawControl extends Component { componentDidMount() { this._isMounted = true; - this._drawFunction = this.props.onDraw(this._mbDrawControl); this._syncDrawControl(); } @@ -69,6 +67,10 @@ export class DrawControl extends Component { this._removeDrawControl(); } + _onDraw = (event: { features: Feature[] }) => { + this.props.onDraw(event, this._mbDrawControl); + }; + // debounce with zero timeout needed to allow mapbox-draw finish logic to complete // before _removeDrawControl is called _syncDrawControl = _.debounce(() => { @@ -96,9 +98,7 @@ export class DrawControl extends Component { this.props.mbMap.getCanvas().style.cursor = ''; this.props.mbMap.off('draw.modechange', this._onModeChange); - if (this._drawFunction !== null) { - this.props.mbMap.off('draw.create', this._drawFunction); - } + this.props.mbMap.off('draw.create', this._onDraw); this.props.mbMap.removeControl(this._mbDrawControl); this._mbDrawControlAdded = false; } @@ -113,9 +113,7 @@ export class DrawControl extends Component { this._mbDrawControlAdded = true; this.props.mbMap.getCanvas().style.cursor = 'crosshair'; this.props.mbMap.on('draw.modechange', this._onModeChange); - if (this._drawFunction !== null) { - this.props.mbMap.on('draw.create', this._drawFunction); - } + this.props.mbMap.on('draw.create', this._onDraw); } const drawMode = this._mbDrawControl.getMode(); diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx index f415a3566d2a68..776d1631666687 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx @@ -36,7 +36,7 @@ export interface OwnProps { type Props = ReduxStateProps & ReduxDispatchProps & OwnProps; export class DrawFeatureControl extends Component { - _onDraw = (mbDrawControl: MapboxDraw) => async (e: { features: Feature[] }) => { + _onDraw = async (e: { features: Feature[] }, mbDrawControl: MapboxDraw) => { try { e.features.forEach((feature: Feature) => { const { geometry } = geoJSONReader.read(feature); diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_filter_control/draw_filter_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_filter_control/draw_filter_control.tsx index 918d8cfb8b6f48..faa30fd2482f2b 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_filter_control/draw_filter_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_filter_control/draw_filter_control.tsx @@ -33,7 +33,7 @@ export interface Props { } export class DrawFilterControl extends Component { - _onDraw = () => async (e: { features: Feature[] }) => { + _onDraw = async (e: { features: Feature[] }) => { if (!e.features.length || !this.props.drawState || !this.props.geoFieldNames.length) { return; } From b2569eebff34b72e9ac30599ba84ef09b758ff44 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Tue, 15 Jun 2021 11:24:02 -0600 Subject: [PATCH 095/103] Review feedback. Clean up draw control --- .../mb_map/draw_control/draw_control.tsx | 36 +++++++++---------- .../draw_feature_control.tsx | 2 +- .../draw_filter_control.tsx | 2 +- 3 files changed, 18 insertions(+), 22 deletions(-) diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx index 13ae3584478f32..879bd85dd6019d 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx @@ -17,22 +17,17 @@ import { DRAW_SHAPE } from '../../../../common/constants'; import { DrawCircle } from './draw_circle'; import { DrawTooltip } from './draw_tooltip'; -const SIMPLE_SELECT = 'simple_select'; -const DRAW_RECTANGLE = 'draw_rectangle'; -const DRAW_CIRCLE = 'draw_circle'; -const DRAW_POLYGON = 'draw_polygon'; -const DRAW_LINE = 'draw_line_string'; -const DRAW_POINT = 'draw_point'; - -const mbModeEquivalencies = new Map([ - ['simple_select', 'SIMPLE_SELECT'], - ['draw_rectangle', 'BOUNDS'], - ['draw_circle', 'DISTANCE'], - ['draw_polygon', 'POLYGON'], - ['draw_line_string', 'LINE'], - ['draw_point', 'POINT'], +const mbModeEquivalencies = new Map([ + ['simple_select', DRAW_SHAPE.SIMPLE_SELECT], + ['draw_rectangle', DRAW_SHAPE.BOUNDS], + ['draw_circle', DRAW_SHAPE.DISTANCE], + ['draw_polygon', DRAW_SHAPE.POLYGON], + ['draw_line_string', DRAW_SHAPE.LINE], + ['draw_point', DRAW_SHAPE.POINT], ]); +const DRAW_RECTANGLE = 'draw_rectangle'; +const DRAW_CIRCLE = 'draw_circle'; const mbDrawModes = MapboxDraw.modes; mbDrawModes[DRAW_RECTANGLE] = DrawRectangle; mbDrawModes[DRAW_CIRCLE] = DrawCircle; @@ -41,7 +36,7 @@ export interface Props { drawShape?: DRAW_SHAPE; onDraw: (event: { features: Feature[] }, drawControl?: MapboxDraw) => void; mbMap: MbMap; - drawActive: boolean; + enable: boolean; updateEditShape: (shapeToDraw: DRAW_SHAPE) => void; } @@ -53,7 +48,7 @@ export class DrawControl extends Component { modes: mbDrawModes, }); - componentWillReceiveProps() { + componentDidUpdate() { this._syncDrawControl(); } @@ -78,7 +73,7 @@ export class DrawControl extends Component { return; } - if (this.props.drawActive) { + if (this.props.enable) { this._updateDrawControl(); } else { this._removeDrawControl(); @@ -87,7 +82,7 @@ export class DrawControl extends Component { _onModeChange = ({ mode }: { mode: string }) => { if (mbModeEquivalencies.has(mode)) { - this.props.updateEditShape(mbModeEquivalencies.get(mode) as DRAW_SHAPE); + this.props.updateEditShape(mbModeEquivalencies.get(mode)!); } }; @@ -116,6 +111,7 @@ export class DrawControl extends Component { this.props.mbMap.on('draw.create', this._onDraw); } + const { DRAW_LINE_STRING, DRAW_POLYGON, DRAW_POINT, SIMPLE_SELECT } = this._mbDrawControl.modes; const drawMode = this._mbDrawControl.getMode(); if (drawMode !== DRAW_RECTANGLE && this.props.drawShape === DRAW_SHAPE.BOUNDS) { this._mbDrawControl.changeMode(DRAW_RECTANGLE); @@ -123,8 +119,8 @@ export class DrawControl extends Component { this._mbDrawControl.changeMode(DRAW_CIRCLE); } else if (drawMode !== DRAW_POLYGON && this.props.drawShape === DRAW_SHAPE.POLYGON) { this._mbDrawControl.changeMode(DRAW_POLYGON); - } else if (drawMode !== DRAW_LINE && this.props.drawShape === DRAW_SHAPE.LINE) { - this._mbDrawControl.changeMode(DRAW_LINE); + } else if (drawMode !== DRAW_LINE_STRING && this.props.drawShape === DRAW_SHAPE.LINE) { + this._mbDrawControl.changeMode(DRAW_LINE_STRING); } else if (drawMode !== DRAW_POINT && this.props.drawShape === DRAW_SHAPE.POINT) { this._mbDrawControl.changeMode(DRAW_POINT); } else if (drawMode !== SIMPLE_SELECT && this.props.drawShape === DRAW_SHAPE.SIMPLE_SELECT) { diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx index 776d1631666687..fb595e7804dfe8 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_feature_control/draw_feature_control.tsx @@ -81,7 +81,7 @@ export class DrawFeatureControl extends Component { drawShape={this.props.drawShape} onDraw={this._onDraw} mbMap={this.props.mbMap} - drawActive={true} + enable={true} /> ); } diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_filter_control/draw_filter_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_filter_control/draw_filter_control.tsx index faa30fd2482f2b..fb8420a2caebb5 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_filter_control/draw_filter_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_filter_control/draw_filter_control.tsx @@ -107,7 +107,7 @@ export class DrawFilterControl extends Component { } onDraw={this._onDraw} mbMap={this.props.mbMap} - drawActive={this.props.filterModeActive} + enable={this.props.filterModeActive} /> ); } From 19e8186f4aec17c144ede8f240a593d787fa8086 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Tue, 15 Jun 2021 17:34:06 -0600 Subject: [PATCH 096/103] Review feedback. Update edit state handling. Disable tools button on draw --- .../public/actions/map_action_constants.ts | 3 +- .../maps/public/actions/map_actions.ts | 20 +- .../plugins/maps/public/actions/ui_actions.ts | 6 +- .../mb_map/draw_control/draw_tooltip.tsx | 1 - .../toolbar_overlay.test.tsx.snap | 5 + .../feature_edit_tools/feature_edit_tools.tsx | 2 - .../toolbar_overlay/index.ts | 4 +- .../toolbar_overlay/toolbar_overlay.test.tsx | 4 +- .../toolbar_overlay/toolbar_overlay.tsx | 2 + .../__snapshots__/tools_control.test.tsx.snap | 344 ++++++++++-------- .../toolbar_overlay/tools_control/index.ts | 1 - .../tools_control/tools_control.test.tsx | 3 +- .../tools_control/tools_control.tsx | 5 +- .../plugins/maps/public/reducers/map/map.ts | 19 +- 14 files changed, 229 insertions(+), 190 deletions(-) diff --git a/x-pack/plugins/maps/public/actions/map_action_constants.ts b/x-pack/plugins/maps/public/actions/map_action_constants.ts index 9736dca2592e12..9f8e87889310e9 100644 --- a/x-pack/plugins/maps/public/actions/map_action_constants.ts +++ b/x-pack/plugins/maps/public/actions/map_action_constants.ts @@ -36,8 +36,7 @@ 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_OPEN_TOOLTIPS = 'SET_OPEN_TOOLTIPS'; export const UPDATE_DRAW_STATE = 'UPDATE_DRAW_STATE'; -export const UPDATE_EDIT_STATE_LAYER = 'UPDATE_EDIT_STATE_LAYER'; -export const UPDATE_EDIT_STATE_SHAPE = 'UPDATE_EDIT_STATE_SHAPE'; +export const UPDATE_EDIT_STATE = 'UPDATE_EDIT_STATE'; export const SET_SCROLL_ZOOM = 'SET_SCROLL_ZOOM'; export const SET_MAP_INIT_ERROR = 'SET_MAP_INIT_ERROR'; export const SET_WAITING_FOR_READY_HIDDEN_LAYERS = 'SET_WAITING_FOR_READY_HIDDEN_LAYERS'; diff --git a/x-pack/plugins/maps/public/actions/map_actions.ts b/x-pack/plugins/maps/public/actions/map_actions.ts index 050235affbc392..9d0d27496da928 100644 --- a/x-pack/plugins/maps/public/actions/map_actions.ts +++ b/x-pack/plugins/maps/public/actions/map_actions.ts @@ -45,9 +45,8 @@ import { SET_SCROLL_ZOOM, TRACK_MAP_SETTINGS, UPDATE_DRAW_STATE, - UPDATE_EDIT_STATE_SHAPE, UPDATE_MAP_SETTING, - UPDATE_EDIT_STATE_LAYER, + UPDATE_EDIT_STATE, } from './map_action_constants'; import { autoFitToBounds, syncDataForAllLayers, syncDataForLayer } from './data_request_actions'; import { addLayer, addLayerWithoutDataSync } from './layer_actions'; @@ -328,10 +327,17 @@ export function updateDrawState(drawState: DrawState | null) { } export function updateEditShape(shapeToDraw: DRAW_SHAPE | null) { - return (dispatch: Dispatch) => { + return (dispatch: Dispatch, getState: () => MapStoreState) => { + const editState = getEditState(getState()); + if (!editState) { + return; + } dispatch({ - type: UPDATE_EDIT_STATE_SHAPE, - shapeToDraw, + type: UPDATE_EDIT_STATE, + editState: { + ...editState, + drawShape: shapeToDraw, + }, }); }; } @@ -346,8 +352,8 @@ export function updateEditLayer(layerId: string | null) { drawMode: DRAW_MODE.NONE, }); dispatch({ - type: UPDATE_EDIT_STATE_LAYER, - layerId, + type: UPDATE_EDIT_STATE, + editState: layerId ? { layerId } : undefined, }); }; } diff --git a/x-pack/plugins/maps/public/actions/ui_actions.ts b/x-pack/plugins/maps/public/actions/ui_actions.ts index e4bbc161618dac..27e11a938e22b8 100644 --- a/x-pack/plugins/maps/public/actions/ui_actions.ts +++ b/x-pack/plugins/maps/public/actions/ui_actions.ts @@ -13,7 +13,7 @@ import { FLYOUT_STATE } from '../reducers/ui'; import { setQuery, trackMapSettings } from './map_actions'; import { setSelectedLayer } from './layer_actions'; import { DRAW_MODE } from '../../common'; -import { UPDATE_EDIT_STATE_LAYER } from './map_action_constants'; +import { UPDATE_EDIT_STATE } from './map_action_constants'; export const UPDATE_FLYOUT = 'UPDATE_FLYOUT'; export const SET_IS_LAYER_TOC_OPEN = 'SET_IS_LAYER_TOC_OPEN'; @@ -96,8 +96,8 @@ export function setDrawMode(drawMode: DRAW_MODE) { return (dispatch: ThunkDispatch) => { if (drawMode === DRAW_MODE.NONE) { dispatch({ - type: UPDATE_EDIT_STATE_LAYER, - layerId: null, + type: UPDATE_EDIT_STATE, + editState: undefined, }); } dispatch({ diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_tooltip.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_tooltip.tsx index 94b503f6ed1c6b..5321c30f752451 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_tooltip.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_tooltip.tsx @@ -109,7 +109,6 @@ export class DrawTooltip extends Component { return ( + + + diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/feature_edit_tools.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/feature_edit_tools.tsx index 578dee5c93d169..56391606267b89 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/feature_edit_tools.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/feature_edit_tools.tsx @@ -9,8 +9,6 @@ import React from 'react'; import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { DRAW_SHAPE } from '../../../../../common/constants'; -// @ts-expect-error -import { GeometryFilterForm } from '../../../../components/draw_forms/geometry_filter_form/geometry_filter_form'; import { VectorCircleIcon } from '../../icons/vector_circle_icon'; import { VectorLineIcon } from '../../icons/vector_line_icon'; import { VectorSquareIcon } from '../../icons/vector_square_icon'; diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts index cab28dee9851b9..4a17d13302161f 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts @@ -16,8 +16,8 @@ function mapStateToProps(state: MapStoreState) { const shapeDrawModeActive = getDrawMode(state) === DRAW_MODE.DRAW_SHAPES; const pointDrawModeActive = getDrawMode(state) === DRAW_MODE.DRAW_POINTS; return { - showToolsControl: - getGeoFieldNames(state).length !== 0 && !(shapeDrawModeActive || pointDrawModeActive), + showToolsControl: getGeoFieldNames(state).length !== 0, + disableToolsControl: shapeDrawModeActive || pointDrawModeActive, shapeDrawModeActive, pointDrawModeActive, }; diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.test.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.test.tsx index 240f620102cd23..19f7f1663226c1 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.test.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.test.tsx @@ -27,6 +27,7 @@ test('Should only show set view control', async () => { pointDrawModeActive={false} showFitToBoundsButton={false} showTimesliderButton={false} + disableToolsControl={false} /> ); expect(component).toMatchSnapshot(); @@ -35,12 +36,13 @@ test('Should only show set view control', async () => { test('Should show all controls', async () => { const component = shallow( {}} showFitToBoundsButton={true} showTimesliderButton={true} shapeDrawModeActive={false} pointDrawModeActive={false} + disableToolsControl={false} /> ); expect(component).toMatchSnapshot(); diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx index 23cf6039a1d880..405f23dfc729b7 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx @@ -18,6 +18,7 @@ import { TimesliderToggleButton } from './timeslider_toggle_button'; export interface Props { addFilters?: ((filters: Filter[], actionId: string) => Promise) | null; showToolsControl: boolean; + disableToolsControl: boolean; getFilterActions?: () => Promise; getActionContext?: () => ActionExecutionContext; shapeDrawModeActive: boolean; @@ -33,6 +34,7 @@ export function ToolbarOverlay(props: Props) { ) : null; diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/__snapshots__/tools_control.test.tsx.snap b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/__snapshots__/tools_control.test.tsx.snap index 38e32697660063..5481efe3cf4222 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/__snapshots__/tools_control.test.tsx.snap +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/__snapshots__/tools_control.test.tsx.snap @@ -1,173 +1,213 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Should render cancel button when drawing 1`] = ` - - - - } - closePopover={[Function]} - display="inlineBlock" - hasArrow={true} - id="toolsControlPopover" - isOpen={false} - ownFocus={true} - panelPaddingSize="none" + - + + + + } + closePopover={[Function]} + display="inlineBlock" + hasArrow={true} + id="toolsControlPopover" + isOpen={false} + ownFocus={true} + panelPaddingSize="none" + > + , + "id": 1, + "title": "Draw shape", }, Object { - "name": "Draw bounds to filter data", - "panel": 2, + "content": , + "id": 2, + "title": "Draw bounds", }, Object { - "name": "Draw distance to filter data", - "panel": 3, + "content": , + "id": 3, + "title": "Draw distance", }, - ], - "title": "Tools", - }, - Object { - "content": , - "id": 1, - "title": "Draw shape", - }, - Object { - "content": , - "id": 2, - "title": "Draw bounds", - }, - Object { - "content": , - "id": 3, - "title": "Draw distance", - }, - ] - } - size="m" - /> - + ] + } + size="m" + /> + + + + + + + + `; exports[`renders 1`] = ` - - - - } - closePopover={[Function]} - display="inlineBlock" - hasArrow={true} - id="toolsControlPopover" - isOpen={false} - ownFocus={true} - panelPaddingSize="none" + - + + + + } + closePopover={[Function]} + display="inlineBlock" + hasArrow={true} + id="toolsControlPopover" + isOpen={false} + ownFocus={true} + panelPaddingSize="none" + > + , + "id": 1, + "title": "Draw shape", }, Object { - "name": "Draw bounds to filter data", - "panel": 2, + "content": , + "id": 2, + "title": "Draw bounds", }, Object { - "name": "Draw distance to filter data", - "panel": 3, + "content": , + "id": 3, + "title": "Draw distance", }, - ], - "title": "Tools", - }, - Object { - "content": , - "id": 1, - "title": "Draw shape", - }, - Object { - "content": , - "id": 2, - "title": "Draw bounds", - }, - Object { - "content": , - "id": 3, - "title": "Draw distance", - }, - ] - } - size="m" - /> - + ] + } + size="m" + /> + + + + + + + + `; diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts index 49ce77661b1c8e..49464e2614c36b 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/index.ts @@ -32,7 +32,6 @@ function mapDispatchToProps(dispatch: ThunkDispatch dispatch(setDrawMode(DRAW_MODE.NONE)), }; } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.test.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.test.tsx index 36533002501872..82b1d0fe633464 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.test.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.test.tsx @@ -20,9 +20,10 @@ const defaultProps = { indexPatternId: '1', }, ], - filterModeActive: false, + filterModeActive: true, activateDrawFilterMode: () => {}, deactivateDrawMode: () => {}, + disableToolsControl: false, }; test('renders', async () => { diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx index 2d986c8a13c7a3..88a6637a7c84c0 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.tsx @@ -58,7 +58,7 @@ export interface Props { getFilterActions?: () => Promise; getActionContext?: () => ActionExecutionContext; initiateDraw: (drawState: DrawState) => void; - deactivateDrawMode: () => void; + disableToolsControl: boolean; } interface State { @@ -79,7 +79,7 @@ export class ToolsControl extends Component { _closePopover = () => { this.setState({ isPopoverOpen: false }); if (this.props.filterModeActive) { - this.props.deactivateDrawMode(); + this.props.cancelDraw(); } }; @@ -213,6 +213,7 @@ export class ToolsControl extends Component { title={i18n.translate('xpack.maps.toolbarOverlay.toolsControlTitle', { defaultMessage: 'Tools', })} + isDisabled={this.props.disableToolsControl} /> ); diff --git a/x-pack/plugins/maps/public/reducers/map/map.ts b/x-pack/plugins/maps/public/reducers/map/map.ts index 01057a678c6e76..eb860c3418adf9 100644 --- a/x-pack/plugins/maps/public/reducers/map/map.ts +++ b/x-pack/plugins/maps/public/reducers/map/map.ts @@ -44,8 +44,7 @@ import { ROLLBACK_MAP_SETTINGS, TRACK_MAP_SETTINGS, UPDATE_MAP_SETTING, - UPDATE_EDIT_STATE_SHAPE, - UPDATE_EDIT_STATE_LAYER, + UPDATE_EDIT_STATE, } from '../../actions'; import { getDefaultMapSettings } from './default_map_settings'; @@ -97,24 +96,12 @@ export function map(state: MapState = DEFAULT_MAP_STATE, action: Record Date: Wed, 16 Jun 2021 11:38:21 -0600 Subject: [PATCH 097/103] Add snapshot tests, test fixes, misc. updates --- .../layers/vector_layer/vector_layer.tsx | 5 ++- .../layer_toc/toc_entry/action_labels.ts | 2 +- .../layer_toc/toc_entry/toc_entry.tsx | 6 +-- .../toc_entry_actions_popover.tsx | 17 ++++++--- .../toolbar_overlay.test.tsx.snap | 38 +++++++++++++++++++ .../toolbar_overlay/index.ts | 7 +--- .../toolbar_overlay/toolbar_overlay.test.tsx | 28 +++++++++++++- .../toolbar_overlay/toolbar_overlay.tsx | 3 +- .../__snapshots__/tools_control.test.tsx.snap | 2 +- .../tools_control/tools_control.test.tsx | 2 +- 10 files changed, 88 insertions(+), 22 deletions(-) diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx index c0a6061d98dd48..bcd46568ef58ea 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx @@ -93,7 +93,7 @@ export interface IVectorLayer extends ILayer { getPropertiesForTooltip(properties: GeoJsonProperties): Promise; hasJoins(): boolean; canShowTooltip(): boolean; - isEditable(): boolean; + supportsFeatureEditing(): boolean; getLeftJoinFields(): Promise; addFeature(geometry: Geometry | Position[]): Promise; } @@ -176,9 +176,10 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { }); } - isEditable(): boolean { + supportsFeatureEditing(): boolean { const dataRequest = this.getDataRequest(IS_EDITABLE_REQUEST_ID); const data = dataRequest?.getData() as { isEditable: boolean } | undefined; + return data ? data.isEditable : false; } diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/action_labels.ts b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/action_labels.ts index f514f213958cbe..ba2f228024a872 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/action_labels.ts +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/action_labels.ts @@ -21,7 +21,7 @@ export function getVisibilityToggleLabel(isVisible: boolean) { }); } -export const LAYER_SETTINGS_LABEL = i18n.translate( +export const EDIT_LAYER_SETTINGS_LABEL = i18n.translate( 'xpack.maps.layerControl.layerTocActions.layerSettingsButtonLabel', { defaultMessage: 'Layer settings', diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.tsx index 62333a56b4db75..5862894c9c3bd2 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.tsx +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.tsx @@ -15,7 +15,7 @@ import { TOCEntryActionsPopover } from './toc_entry_actions_popover'; import { getVisibilityToggleIcon, getVisibilityToggleLabel, - LAYER_SETTINGS_LABEL, + EDIT_LAYER_SETTINGS_LABEL, FIT_TO_DATA_LABEL, } from './action_labels'; import { ILayer } from '../../../../../classes/layers/layer'; @@ -200,8 +200,8 @@ export class TOCEntry extends Component { key="settings" isDisabled={this.props.isEditButtonDisabled} iconType="gear" - aria-label={LAYER_SETTINGS_LABEL} - title={LAYER_SETTINGS_LABEL} + aria-label={EDIT_LAYER_SETTINGS_LABEL} + title={EDIT_LAYER_SETTINGS_LABEL} onClick={this._openLayerPanelWithCheck} /> ); diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx index 6a7a42a0d8df20..e978c78080af6b 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx @@ -13,12 +13,13 @@ import { TOCEntryButton } from '../toc_entry_button'; import { getVisibilityToggleIcon, getVisibilityToggleLabel, - LAYER_SETTINGS_LABEL, + EDIT_LAYER_SETTINGS_LABEL, FIT_TO_DATA_LABEL, EDIT_FEATURES_LABEL, } from '../action_labels'; import { ESSearchSource } from '../../../../../../classes/sources/es_search_source'; import { VectorLayer } from '../../../../../../classes/layers/vector_layer'; +import { SCALING_TYPES } from '../../../../../../../common'; export interface Props { cloneLayer: (layerId: string) => void; @@ -62,7 +63,7 @@ export class TOCEntryActionsPopover extends Component { if (!(this.props.layer instanceof VectorLayer)) { return; } - const isLayerEditable = await this.props.layer.isEditable(); + const isLayerEditable = this.props.layer.supportsFeatureEditing(); const editModeEnabled = await this._getEditModeEnabled(); if ( !this._isMounted || @@ -76,8 +77,14 @@ export class TOCEntryActionsPopover extends Component { async _getEditModeEnabled(): Promise { const vectorLayer = this.props.layer as VectorLayer; + const layerSource = await this.props.layer.getSource(); + if (!(layerSource instanceof ESSearchSource)) { + return false; + } + // @ts-ignore + const isClustered = layerSource?.getSyncMeta()?.scalingType === SCALING_TYPES.CLUSTERS; if ( - !(await vectorLayer.isEditable()) || + isClustered || (await vectorLayer.isFilteredByGlobalTime()) || vectorLayer.isPreviewLayer() || !vectorLayer.isVisible() || @@ -155,7 +162,7 @@ export class TOCEntryActionsPopover extends Component { ? null : i18n.translate('xpack.maps.layerTocActions.editLayerTooltip', { defaultMessage: - 'Only fully added document layers without clustering, joins or time filtering enabled can be modified', + 'Edit features only supported for document layers without clustering, joins, or time filtering', }), disabled: !this.state.editModeEnabled, onClick: async () => { @@ -171,7 +178,7 @@ export class TOCEntryActionsPopover extends Component { } actionItems.push({ disabled: this.props.isEditButtonDisabled, - name: LAYER_SETTINGS_LABEL, + name: EDIT_LAYER_SETTINGS_LABEL, icon: , 'data-test-subj': 'layerSettingsButton', toolTipContent: null, diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/__snapshots__/toolbar_overlay.test.tsx.snap b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/__snapshots__/toolbar_overlay.test.tsx.snap index 9f205ba7b11ce1..9357d1e45e2962 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/__snapshots__/toolbar_overlay.test.tsx.snap +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/__snapshots__/toolbar_overlay.test.tsx.snap @@ -38,3 +38,41 @@ exports[`Should show all controls 1`] = ` `; + +exports[`Should show point layer edit tools 1`] = ` + + + + + + + + +`; + +exports[`Should show shape layer edit tools 1`] = ` + + + + + + + + +`; diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts index 4a17d13302161f..d98d24a313ec5e 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/index.ts @@ -13,13 +13,10 @@ import { getGeoFieldNames } from '../../selectors/map_selectors'; import { DRAW_MODE } from '../../../common'; function mapStateToProps(state: MapStoreState) { - const shapeDrawModeActive = getDrawMode(state) === DRAW_MODE.DRAW_SHAPES; - const pointDrawModeActive = getDrawMode(state) === DRAW_MODE.DRAW_POINTS; return { showToolsControl: getGeoFieldNames(state).length !== 0, - disableToolsControl: shapeDrawModeActive || pointDrawModeActive, - shapeDrawModeActive, - pointDrawModeActive, + shapeDrawModeActive: getDrawMode(state) === DRAW_MODE.DRAW_SHAPES, + pointDrawModeActive: getDrawMode(state) === DRAW_MODE.DRAW_POINTS, }; } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.test.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.test.tsx index 19f7f1663226c1..4c6ec666b11605 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.test.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.test.tsx @@ -27,7 +27,6 @@ test('Should only show set view control', async () => { pointDrawModeActive={false} showFitToBoundsButton={false} showTimesliderButton={false} - disableToolsControl={false} /> ); expect(component).toMatchSnapshot(); @@ -42,7 +41,32 @@ test('Should show all controls', async () => { showTimesliderButton={true} shapeDrawModeActive={false} pointDrawModeActive={false} - disableToolsControl={false} + /> + ); + expect(component).toMatchSnapshot(); +}); + +test('Should show point layer edit tools', async () => { + const component = shallow( + + ); + expect(component).toMatchSnapshot(); +}); + +test('Should show shape layer edit tools', async () => { + const component = shallow( + ); expect(component).toMatchSnapshot(); diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx index 405f23dfc729b7..a5b61b9e486163 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx @@ -18,7 +18,6 @@ import { TimesliderToggleButton } from './timeslider_toggle_button'; export interface Props { addFilters?: ((filters: Filter[], actionId: string) => Promise) | null; showToolsControl: boolean; - disableToolsControl: boolean; getFilterActions?: () => Promise; getActionContext?: () => ActionExecutionContext; shapeDrawModeActive: boolean; @@ -34,7 +33,7 @@ export function ToolbarOverlay(props: Props) { ) : null; diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/__snapshots__/tools_control.test.tsx.snap b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/__snapshots__/tools_control.test.tsx.snap index 5481efe3cf4222..4d49555cc8192e 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/__snapshots__/tools_control.test.tsx.snap +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/__snapshots__/tools_control.test.tsx.snap @@ -16,7 +16,7 @@ exports[`Should render cancel button when drawing 1`] = ` aria-label="Tools" color="text" iconType="wrench" - isDisabled={false} + isDisabled={true} onClick={[Function]} size="s" title="Tools" diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.test.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.test.tsx index 82b1d0fe633464..b9cca7ad909d00 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.test.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.test.tsx @@ -33,7 +33,7 @@ test('renders', async () => { }); test('Should render cancel button when drawing', async () => { - const component = shallow(); + const component = shallow(); expect(component).toMatchSnapshot(); }); From 95e97c1faa0918cbfa001c0a45331d22036d334a Mon Sep 17 00:00:00 2001 From: miukimiu Date: Wed, 16 Jun 2021 18:44:05 +0100 Subject: [PATCH 098/103] Updating icons and toolbar styles --- .../__snapshots__/toc_entry.test.tsx.snap | 8 +- .../layer_toc/toc_entry/_toc_entry.scss | 3 +- .../layer_toc/toc_entry/toc_entry.tsx | 2 +- .../toc_entry_actions_popover.test.tsx.snap | 6 +- .../toc_entry_actions_popover.tsx | 4 +- .../toolbar_overlay/_toolbar_overlay.scss | 31 +-- .../feature_edit_tools/feature_edit_tools.tsx | 231 +++++++----------- 7 files changed, 114 insertions(+), 171 deletions(-) diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/__snapshots__/toc_entry.test.tsx.snap b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/__snapshots__/toc_entry.test.tsx.snap index 05158452ad8612..bc096dfe7fa638 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/__snapshots__/toc_entry.test.tsx.snap +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/__snapshots__/toc_entry.test.tsx.snap @@ -40,7 +40,7 @@ exports[`TOCEntry is rendered 1`] = ` /> { , "name": "Layer settings", "onClick": [Function], @@ -194,7 +194,7 @@ exports[`TOCEntryActionsPopover should disable fit to data when supportsFitToBou "disabled": false, "icon": , "name": "Layer settings", "onClick": [Function], @@ -310,7 +310,7 @@ exports[`TOCEntryActionsPopover should have "show layer" action when layer is no "disabled": false, "icon": , "name": "Layer settings", "onClick": [Function], diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx index 6a7a42a0d8df20..5dc36c2b86b460 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx @@ -149,7 +149,7 @@ export class TOCEntryActionsPopover extends Component { if (this.state.isLayerEditable) { actionItems.push({ name: EDIT_FEATURES_LABEL, - icon: , + icon: , 'data-test-subj': 'editLayerButton', toolTipContent: this.state.editModeEnabled ? null @@ -172,7 +172,7 @@ export class TOCEntryActionsPopover extends Component { actionItems.push({ disabled: this.props.isEditButtonDisabled, name: LAYER_SETTINGS_LABEL, - icon: , + icon: , 'data-test-subj': 'layerSettingsButton', toolTipContent: null, onClick: () => { diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/_toolbar_overlay.scss b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/_toolbar_overlay.scss index fe011fe5f66d70..459a22c82401c3 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/_toolbar_overlay.scss +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/_toolbar_overlay.scss @@ -21,7 +21,7 @@ } } - .euiButtonIcon { + .euiButtonIcon:not(.euiButtonIcon--fill) { color: $euiTextColor !important; } @@ -42,31 +42,18 @@ } } -.mapToolbarOverlay__button__exit { +.mapToolbarOverlay__buttonGroup { + @include mapToolbarButtonGroupBorderRadius; + display: flex; + flex-direction: column; + .euiButtonIcon { - color: $euiColorDangerText !important; + border-radius: 0; } } -.mapToolbarOverlay__button__selected { - position: relative; - transition: transform $euiAnimSpeedNormal ease-in-out, background $euiAnimSpeedNormal ease-in-out; - // sass-lint:disable-block no-important - color: $euiTextColor !important; - background-color: $euiColorLightShade !important; - - @include kbnThemeStyle($theme: 'v7') { - // Overrides the .euiPanel default border - // sass-lint:disable-block no-important - border: none !important; - - // Overrides the .euiPanel--hasShadow - &.euiPanel.euiPanel--hasShadow { - @include euiBottomShadowLarge; - } - } - +.mapToolbarOverlay__button__exit { .euiButtonIcon { - color: $euiTextColor !important; + color: $euiColorDangerText !important; } } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/feature_edit_tools.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/feature_edit_tools.tsx index 56391606267b89..ab8ac259b4c795 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/feature_edit_tools.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/feature_edit_tools.tsx @@ -36,143 +36,100 @@ export function FeatureEditTools(props: Props) { const drawPointSelected = props.drawShape === DRAW_SHAPE.POINT; return ( - - - {props.pointsOnly ? null : ( - <> - - - props.setDrawShape(DRAW_SHAPE.LINE)} - iconType={VectorLineIcon} - aria-label={i18n.translate( - 'xpack.maps.toolbarOverlay.featureDraw.drawLineLabel', - { - defaultMessage: 'Draw line', - } - )} - title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawLineTitle', { - defaultMessage: 'Draw line', - })} - aria-pressed={drawLineSelected} - isSelected={drawLineSelected} - /> - - - - - props.setDrawShape(DRAW_SHAPE.POLYGON)} - iconType="node" - aria-label={i18n.translate( - 'xpack.maps.toolbarOverlay.featureDraw.drawPolygonLabel', - { - defaultMessage: 'Draw polygon', - } - )} - title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawPolygonTitle', { - defaultMessage: 'Draw polygon', - })} - aria-pressed={drawPolygonSelected} - isSelected={drawPolygonSelected} - /> - - - - - props.setDrawShape(DRAW_SHAPE.DISTANCE)} - iconType={VectorCircleIcon} - aria-label={i18n.translate( - 'xpack.maps.toolbarOverlay.featureDraw.drawCircleLabel', - { - defaultMessage: 'Draw circle', - } - )} - title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawCircleTitle', { - defaultMessage: 'Draw circle', - })} - aria-pressed={drawCircleSelected} - isSelected={drawCircleSelected} - /> - - - - - props.setDrawShape(DRAW_SHAPE.BOUNDS)} - iconType={VectorSquareIcon} - aria-label={i18n.translate( - 'xpack.maps.toolbarOverlay.featureDraw.drawBBoxLabel', - { - defaultMessage: 'Draw bounding box', - } - )} - title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawBBoxTitle', { - defaultMessage: 'Draw bounding box', - })} - aria-pressed={drawBBoxSelected} - isSelected={drawBBoxSelected} - /> - - - - )} - - - props.setDrawShape(DRAW_SHAPE.POINT)} - iconType="dot" - aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawPointLabel', { - defaultMessage: 'Draw point', - })} - title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawPointTitle', { - defaultMessage: 'Draw point', - })} - aria-pressed={drawPointSelected} - isSelected={drawPointSelected} - /> - - - - - - - - + + {props.pointsOnly ? null : ( + <> + props.setDrawShape(DRAW_SHAPE.LINE)} + iconType={VectorLineIcon} + aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawLineLabel', { + defaultMessage: 'Draw line', + })} + title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawLineTitle', { + defaultMessage: 'Draw line', + })} + aria-pressed={drawLineSelected} + isSelected={drawLineSelected} + display={drawLineSelected ? 'fill' : 'empty'} + /> + + props.setDrawShape(DRAW_SHAPE.POLYGON)} + iconType="node" + aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawPolygonLabel', { + defaultMessage: 'Draw polygon', + })} + title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawPolygonTitle', { + defaultMessage: 'Draw polygon', + })} + aria-pressed={drawPolygonSelected} + isSelected={drawPolygonSelected} + display={drawPolygonSelected ? 'fill' : 'empty'} + /> + props.setDrawShape(DRAW_SHAPE.DISTANCE)} + iconType={VectorCircleIcon} + aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawCircleLabel', { + defaultMessage: 'Draw circle', + })} + title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawCircleTitle', { + defaultMessage: 'Draw circle', + })} + aria-pressed={drawCircleSelected} + isSelected={drawCircleSelected} + display={drawCircleSelected ? 'fill' : 'empty'} + /> + props.setDrawShape(DRAW_SHAPE.BOUNDS)} + iconType={VectorSquareIcon} + aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawBBoxLabel', { + defaultMessage: 'Draw bounding box', + })} + title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawBBoxTitle', { + defaultMessage: 'Draw bounding box', + })} + aria-pressed={drawBBoxSelected} + isSelected={drawBBoxSelected} + display={drawBBoxSelected ? 'fill' : 'empty'} + /> + + )} + props.setDrawShape(DRAW_SHAPE.POINT)} + iconType="dot" + aria-label={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawPointLabel', { + defaultMessage: 'Draw point', + })} + title={i18n.translate('xpack.maps.toolbarOverlay.featureDraw.drawPointTitle', { + defaultMessage: 'Draw point', + })} + aria-pressed={drawPointSelected} + isSelected={drawPointSelected} + display={drawPointSelected ? 'fill' : 'empty'} + /> + + ); } From a9311dd83ae8f8b8df0583eab12ec18f7390bd90 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 16 Jun 2021 14:10:18 -0600 Subject: [PATCH 099/103] TOC Entry Actions popover clean up. Var naming updates --- .../layer_toc/toc_entry/toc_entry.tsx | 2 +- .../toc_entry_actions_popover.test.tsx | 3 +- .../toc_entry_actions_popover.tsx | 35 ++-- .../feature_edit_tools/feature_edit_tools.tsx | 2 +- .../toolbar_overlay/toolbar_overlay.tsx | 4 +- .../__snapshots__/tools_control.test.tsx.snap | 175 ++++++++---------- .../tools_control/tools_control.test.tsx | 4 +- 7 files changed, 104 insertions(+), 121 deletions(-) diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.tsx index e6734ee308b063..712da6251fb96f 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.tsx +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.tsx @@ -278,7 +278,7 @@ export class TOCEntry extends Component { layer={layer} displayName={this.state.displayName} escapedDisplayName={escapeLayerName(this.state.displayName)} - layerSettings={this._openLayerPanelWithCheck} + openLayerSettings={this._openLayerPanelWithCheck} isEditButtonDisabled={this.props.isEditButtonDisabled} supportsFitToBounds={this.state.supportsFitToBounds} /> diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.test.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.test.tsx index 5a234c0241e987..1187bae19e178d 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.test.tsx +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.test.tsx @@ -37,7 +37,6 @@ class LayerMock extends AbstractLayer implements ILayer { const defaultProps = { cloneLayer: () => {}, displayName: 'layer 1', - editLayer: () => {}, escapedDisplayName: 'layer1', fitToBounds: () => {}, isEditButtonDisabled: false, @@ -48,7 +47,7 @@ const defaultProps = { supportsFitToBounds: true, enableShapeEditing: () => {}, enablePointEditing: () => {}, - layerSettings: () => {}, + openLayerSettings: () => {}, }; describe('TOCEntryActionsPopover', () => { diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx index 7e7f4839eaf01d..2606acbf077e92 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx @@ -6,27 +6,27 @@ */ import React, { Component } from 'react'; -import { EuiPopover, EuiContextMenu, EuiIcon } from '@elastic/eui'; +import { EuiContextMenu, EuiIcon, EuiPopover } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { ILayer } from '../../../../../../classes/layers/layer'; import { TOCEntryButton } from '../toc_entry_button'; import { - getVisibilityToggleIcon, - getVisibilityToggleLabel, + EDIT_FEATURES_LABEL, EDIT_LAYER_SETTINGS_LABEL, FIT_TO_DATA_LABEL, - EDIT_FEATURES_LABEL, + getVisibilityToggleIcon, + getVisibilityToggleLabel, } from '../action_labels'; import { ESSearchSource } from '../../../../../../classes/sources/es_search_source'; import { VectorLayer } from '../../../../../../classes/layers/vector_layer'; -import { SCALING_TYPES } from '../../../../../../../common'; +import { SCALING_TYPES, VECTOR_SHAPE_TYPE } from '../../../../../../../common'; export interface Props { cloneLayer: (layerId: string) => void; enableShapeEditing: (layerId: string) => void; enablePointEditing: (layerId: string) => void; displayName: string; - layerSettings: () => void; + openLayerSettings: () => void; escapedDisplayName: string; fitToBounds: (layerId: string) => void; isEditButtonDisabled: boolean; @@ -39,12 +39,12 @@ export interface Props { interface State { isPopoverOpen: boolean; - isLayerEditable: boolean; + supportsFeatureEditing: boolean; editModeEnabled: boolean; } export class TOCEntryActionsPopover extends Component { - state: State = { isPopoverOpen: false, isLayerEditable: false, editModeEnabled: false }; + state: State = { isPopoverOpen: false, supportsFeatureEditing: false, editModeEnabled: false }; private _isMounted = false; componentDidMount() { @@ -63,16 +63,16 @@ export class TOCEntryActionsPopover extends Component { if (!(this.props.layer instanceof VectorLayer)) { return; } - const isLayerEditable = this.props.layer.supportsFeatureEditing(); + const supportsFeatureEditing = this.props.layer.supportsFeatureEditing(); const editModeEnabled = await this._getEditModeEnabled(); if ( !this._isMounted || - (isLayerEditable === this.state.isLayerEditable && + (supportsFeatureEditing === this.state.supportsFeatureEditing && editModeEnabled === this.state.editModeEnabled) ) { return; } - this.setState({ isLayerEditable, editModeEnabled }); + this.setState({ supportsFeatureEditing, editModeEnabled }); } async _getEditModeEnabled(): Promise { @@ -153,7 +153,7 @@ export class TOCEntryActionsPopover extends Component { ]; if (!this.props.isReadOnly) { - if (this.state.isLayerEditable) { + if (this.state.supportsFeatureEditing) { actionItems.push({ name: EDIT_FEATURES_LABEL, icon: , @@ -168,10 +168,13 @@ export class TOCEntryActionsPopover extends Component { onClick: async () => { this._closePopover(); const supportedShapeTypes = await (this.props.layer.getSource() as ESSearchSource).getSupportedShapeTypes(); - if (supportedShapeTypes.length === 1) { - this.props.enablePointEditing(this.props.layer.getId()); - } else { + const supportsShapes = + supportedShapeTypes.includes(VECTOR_SHAPE_TYPE.POLYGON) && + supportedShapeTypes.includes(VECTOR_SHAPE_TYPE.LINE); + if (supportsShapes) { this.props.enableShapeEditing(this.props.layer.getId()); + } else { + this.props.enablePointEditing(this.props.layer.getId()); } }, }); @@ -184,7 +187,7 @@ export class TOCEntryActionsPopover extends Component { toolTipContent: null, onClick: () => { this._closePopover(); - this.props.layerSettings(); + this.props.openLayerSettings(); }, }); actionItems.push({ diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/feature_edit_tools.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/feature_edit_tools.tsx index ab8ac259b4c795..66948c0fc9bca3 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/feature_edit_tools.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/feature_draw_controls/feature_edit_tools/feature_edit_tools.tsx @@ -6,7 +6,7 @@ */ import React from 'react'; -import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui'; +import { EuiButtonIcon, EuiPanel } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { DRAW_SHAPE } from '../../../../../common/constants'; import { VectorCircleIcon } from '../../icons/vector_circle_icon'; diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx index a5b61b9e486163..3ec3e8afaf66cb 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/toolbar_overlay.tsx @@ -73,9 +73,9 @@ export function ToolbarOverlay(props: Props) { {toolsButton} - {featureDrawControl} - {timesliderToogleButon} + + {featureDrawControl} ); } diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/__snapshots__/tools_control.test.tsx.snap b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/__snapshots__/tools_control.test.tsx.snap index 4d49555cc8192e..bd9359112b9c34 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/__snapshots__/tools_control.test.tsx.snap +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/__snapshots__/tools_control.test.tsx.snap @@ -16,7 +16,7 @@ exports[`Should render cancel button when drawing 1`] = ` aria-label="Tools" color="text" iconType="wrench" - isDisabled={true} + isDisabled={false} onClick={[Function]} size="s" title="Tools" @@ -107,107 +107,88 @@ exports[`Should render cancel button when drawing 1`] = ` `; exports[`renders 1`] = ` - - - - - - } - closePopover={[Function]} - display="inlineBlock" - hasArrow={true} - id="toolsControlPopover" - isOpen={false} - ownFocus={true} - panelPaddingSize="none" + - + + } + closePopover={[Function]} + display="inlineBlock" + hasArrow={true} + id="toolsControlPopover" + isOpen={false} + ownFocus={true} + panelPaddingSize="none" +> + , - "id": 1, - "title": "Draw shape", + "name": "Draw shape to filter data", + "panel": 1, }, Object { - "content": , - "id": 2, - "title": "Draw bounds", + "name": "Draw bounds to filter data", + "panel": 2, }, Object { - "content": , - "id": 3, - "title": "Draw distance", + "name": "Draw distance to filter data", + "panel": 3, }, - ] - } - size="m" - /> - - - - - - - - + ], + "title": "Tools", + }, + Object { + "content": , + "id": 1, + "title": "Draw shape", + }, + Object { + "content": , + "id": 2, + "title": "Draw bounds", + }, + Object { + "content": , + "id": 3, + "title": "Draw distance", + }, + ] + } + size="m" + /> + `; diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.test.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.test.tsx index b9cca7ad909d00..4601b5c5692909 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.test.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/tools_control/tools_control.test.tsx @@ -20,7 +20,7 @@ const defaultProps = { indexPatternId: '1', }, ], - filterModeActive: true, + filterModeActive: false, activateDrawFilterMode: () => {}, deactivateDrawMode: () => {}, disableToolsControl: false, @@ -33,7 +33,7 @@ test('renders', async () => { }); test('Should render cancel button when drawing', async () => { - const component = shallow(); + const component = shallow(); expect(component).toMatchSnapshot(); }); From 3be71a50e7c326a52428c4b36f283035f754fd65 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 16 Jun 2021 16:13:31 -0600 Subject: [PATCH 100/103] Remove unneeded test props, label wording update, test snapshot updates --- .../mb_map/tooltip_control/tooltip_popover.test.tsx | 2 -- .../layer_control/layer_toc/toc_entry/action_labels.ts | 2 +- .../__snapshots__/toc_entry_actions_popover.test.tsx.snap | 6 +++--- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_popover.test.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_popover.test.tsx index b41ec59775fd58..002ec09e68c2fc 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_popover.test.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_popover.test.tsx @@ -66,9 +66,7 @@ const mockMBMap = ({ const defaultProps = { mbMap: mockMBMap, closeTooltip: () => {}, - layerList: [], addFilters: async () => {}, - geoFields: [{}], location: [-120, 30] as [number, number], features: [ { diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/action_labels.ts b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/action_labels.ts index ba2f228024a872..d3905c497052e3 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/action_labels.ts +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/action_labels.ts @@ -24,7 +24,7 @@ export function getVisibilityToggleLabel(isVisible: boolean) { export const EDIT_LAYER_SETTINGS_LABEL = i18n.translate( 'xpack.maps.layerControl.layerTocActions.layerSettingsButtonLabel', { - defaultMessage: 'Layer settings', + defaultMessage: 'Edit layer settings', } ); diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/__snapshots__/toc_entry_actions_popover.test.tsx.snap b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/__snapshots__/toc_entry_actions_popover.test.tsx.snap index 450a66407f3ed3..5068a5dc1ad711 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/__snapshots__/toc_entry_actions_popover.test.tsx.snap +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/__snapshots__/toc_entry_actions_popover.test.tsx.snap @@ -81,7 +81,7 @@ exports[`TOCEntryActionsPopover is rendered 1`] = ` size="m" type="pencil" />, - "name": "Layer settings", + "name": "Edit layer settings", "onClick": [Function], "toolTipContent": null, }, @@ -196,7 +196,7 @@ exports[`TOCEntryActionsPopover should disable fit to data when supportsFitToBou size="m" type="pencil" />, - "name": "Layer settings", + "name": "Edit layer settings", "onClick": [Function], "toolTipContent": null, }, @@ -312,7 +312,7 @@ exports[`TOCEntryActionsPopover should have "show layer" action when layer is no size="m" type="pencil" />, - "name": "Layer settings", + "name": "Edit layer settings", "onClick": [Function], "toolTipContent": null, }, From 7e78b38da5e7a85fd160678c2c5b4f72ba419adc Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 16 Jun 2021 17:01:03 -0600 Subject: [PATCH 101/103] Type fix. Cast getSyncMeta result to ESSearchSourceSyncMeta --- .../descriptor_types/data_request_descriptor_types.ts | 2 +- .../toc_entry_actions_popover/toc_entry_actions_popover.tsx | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/maps/common/descriptor_types/data_request_descriptor_types.ts b/x-pack/plugins/maps/common/descriptor_types/data_request_descriptor_types.ts index cda812700804e0..07de57d0ac8320 100644 --- a/x-pack/plugins/maps/common/descriptor_types/data_request_descriptor_types.ts +++ b/x-pack/plugins/maps/common/descriptor_types/data_request_descriptor_types.ts @@ -32,7 +32,7 @@ export type MapFilters = { isReadOnly: boolean; }; -type ESSearchSourceSyncMeta = { +export type ESSearchSourceSyncMeta = { filterByMapBounds: boolean; sortField: string; sortOrder: SortDirection; diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx index 2606acbf077e92..54b32aac629f1e 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx @@ -20,6 +20,7 @@ import { import { ESSearchSource } from '../../../../../../classes/sources/es_search_source'; import { VectorLayer } from '../../../../../../classes/layers/vector_layer'; import { SCALING_TYPES, VECTOR_SHAPE_TYPE } from '../../../../../../../common'; +import { ESSearchSourceSyncMeta } from '../../../../../../../common/descriptor_types'; export interface Props { cloneLayer: (layerId: string) => void; @@ -81,8 +82,9 @@ export class TOCEntryActionsPopover extends Component { if (!(layerSource instanceof ESSearchSource)) { return false; } - // @ts-ignore - const isClustered = layerSource?.getSyncMeta()?.scalingType === SCALING_TYPES.CLUSTERS; + const isClustered = + (layerSource?.getSyncMeta() as ESSearchSourceSyncMeta)?.scalingType === + SCALING_TYPES.CLUSTERS; if ( isClustered || (await vectorLayer.isFilteredByGlobalTime()) || From 9f365f7490f3c1b25b81325731f87fff247b631f Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 16 Jun 2021 17:09:29 -0600 Subject: [PATCH 102/103] Rename editModeEnabled -> canEditFeatures --- .../toc_entry_actions_popover.tsx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx index 54b32aac629f1e..526c157ceaabcf 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_actions_popover/toc_entry_actions_popover.tsx @@ -41,11 +41,11 @@ export interface Props { interface State { isPopoverOpen: boolean; supportsFeatureEditing: boolean; - editModeEnabled: boolean; + canEditFeatures: boolean; } export class TOCEntryActionsPopover extends Component { - state: State = { isPopoverOpen: false, supportsFeatureEditing: false, editModeEnabled: false }; + state: State = { isPopoverOpen: false, supportsFeatureEditing: false, canEditFeatures: false }; private _isMounted = false; componentDidMount() { @@ -65,18 +65,18 @@ export class TOCEntryActionsPopover extends Component { return; } const supportsFeatureEditing = this.props.layer.supportsFeatureEditing(); - const editModeEnabled = await this._getEditModeEnabled(); + const canEditFeatures = await this._getCanEditFeatures(); if ( !this._isMounted || (supportsFeatureEditing === this.state.supportsFeatureEditing && - editModeEnabled === this.state.editModeEnabled) + canEditFeatures === this.state.canEditFeatures) ) { return; } - this.setState({ supportsFeatureEditing, editModeEnabled }); + this.setState({ supportsFeatureEditing, canEditFeatures }); } - async _getEditModeEnabled(): Promise { + async _getCanEditFeatures(): Promise { const vectorLayer = this.props.layer as VectorLayer; const layerSource = await this.props.layer.getSource(); if (!(layerSource instanceof ESSearchSource)) { @@ -160,13 +160,13 @@ export class TOCEntryActionsPopover extends Component { name: EDIT_FEATURES_LABEL, icon: , 'data-test-subj': 'editLayerButton', - toolTipContent: this.state.editModeEnabled + toolTipContent: this.state.canEditFeatures ? null : i18n.translate('xpack.maps.layerTocActions.editLayerTooltip', { defaultMessage: 'Edit features only supported for document layers without clustering, joins, or time filtering', }), - disabled: !this.state.editModeEnabled, + disabled: !this.state.canEditFeatures, onClick: async () => { this._closePopover(); const supportedShapeTypes = await (this.props.layer.getSource() as ESSearchSource).getSupportedShapeTypes(); From 81da28af058e5c7c7261327752a5432a00bd2524 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Wed, 16 Jun 2021 18:27:05 -0600 Subject: [PATCH 103/103] Update jest test snapshot --- .../__snapshots__/toc_entry.test.tsx.snap | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/__snapshots__/toc_entry.test.tsx.snap b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/__snapshots__/toc_entry.test.tsx.snap index bc096dfe7fa638..6310b5507dca57 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/__snapshots__/toc_entry.test.tsx.snap +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/__snapshots__/toc_entry.test.tsx.snap @@ -25,7 +25,7 @@ exports[`TOCEntry is rendered 1`] = ` "showAtZoomLevel": [Function], } } - layerSettings={[Function]} + openLayerSettings={[Function]} supportsFitToBounds={false} />