From 6b3be2cc46c13df3693895b813ba1ddd8533a231 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Wed, 26 May 2021 11:21:38 -0400 Subject: [PATCH] [Maps] Add draw wizard (#100278) --- .../plugins/file_upload/public/api/index.ts | 25 +-- .../api/index_name_form_async_wrapper.tsx | 43 +++++ .../json_upload_and_parse_async_wrapper.tsx | 48 ++++++ .../public/lazy_load_bundle/index.ts | 2 +- x-pack/plugins/file_upload/public/plugin.ts | 8 +- x-pack/plugins/maps/common/constants.ts | 1 + x-pack/plugins/maps/common/types.ts | 1 + .../maps/public/actions/map_actions.ts | 1 - .../layers/file_upload_wizard/wizard.tsx | 19 +-- .../classes/layers/icons/draw_layer_icon.tsx | 37 ++++ .../classes/layers/load_layer_wizards.ts | 5 + .../layers/new_vector_layer_wizard/config.tsx | 49 ++++++ .../create_new_index_pattern.ts | 27 +++ .../layers/new_vector_layer_wizard/index.ts | 8 + .../layers/new_vector_layer_wizard/wizard.tsx | 161 ++++++++++++++++++ .../add_layer_panel/view.tsx | 2 +- .../connected_components/mb_map/mb_map.tsx | 6 +- .../icons/vector_circle_icon.tsx | 25 +++ .../icons/vector_line_icon.tsx | 26 +++ .../icons/vector_square_icon.tsx | 25 +++ x-pack/plugins/maps/public/kibana_services.ts | 4 +- .../server/data_indexing/create_doc_source.ts | 3 +- .../server/data_indexing/indexing_routes.ts | 4 +- x-pack/plugins/maps/server/index.ts | 1 + 24 files changed, 483 insertions(+), 48 deletions(-) create mode 100644 x-pack/plugins/file_upload/public/api/index_name_form_async_wrapper.tsx create mode 100644 x-pack/plugins/file_upload/public/api/json_upload_and_parse_async_wrapper.tsx create mode 100644 x-pack/plugins/maps/public/classes/layers/icons/draw_layer_icon.tsx 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/create_new_index_pattern.ts 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 create mode 100644 x-pack/plugins/maps/public/connected_components/toolbar_overlay/icons/vector_circle_icon.tsx create mode 100644 x-pack/plugins/maps/public/connected_components/toolbar_overlay/icons/vector_line_icon.tsx create mode 100644 x-pack/plugins/maps/public/connected_components/toolbar_overlay/icons/vector_square_icon.tsx diff --git a/x-pack/plugins/file_upload/public/api/index.ts b/x-pack/plugins/file_upload/public/api/index.ts index c2520547ddad9a9..f3a184f27dfac89 100644 --- a/x-pack/plugins/file_upload/public/api/index.ts +++ b/x-pack/plugins/file_upload/public/api/index.ts @@ -5,16 +5,16 @@ * 2.0. */ -import React from 'react'; -import { FileUploadComponentProps, lazyLoadModules } from '../lazy_load_bundle'; +import { lazyLoadModules } from '../lazy_load_bundle'; import type { IImporter, ImportFactoryOptions } from '../importer'; -import { IndexNameFormProps } from '../'; import type { HasImportPermission, FindFileStructureResponse } from '../../common'; import type { getMaxBytes, getMaxBytesFormatted } from '../importer/get_max_bytes'; +import { JsonUploadAndParseAsyncWrapper } from './json_upload_and_parse_async_wrapper'; +import { IndexNameFormAsyncWrapper } from './index_name_form_async_wrapper'; export interface FileUploadStartApi { - getFileUploadComponent(): ReturnType; - getIndexNameFormComponent(): Promise>; + FileUploadComponent: typeof JsonUploadAndParseAsyncWrapper; + IndexNameFormComponent: typeof IndexNameFormAsyncWrapper; importerFactory: typeof importerFactory; getMaxBytes: typeof getMaxBytes; getMaxBytesFormatted: typeof getMaxBytesFormatted; @@ -30,19 +30,8 @@ export interface GetTimeFieldRangeResponse { end: { epoch: number; string: string }; } -export async function getFileUploadComponent(): Promise< - React.ComponentType -> { - const fileUploadModules = await lazyLoadModules(); - return fileUploadModules.JsonUploadAndParse; -} - -export async function getIndexNameFormComponent(): Promise< - React.ComponentType -> { - const fileUploadModules = await lazyLoadModules(); - return fileUploadModules.IndexNameForm; -} +export const FileUploadComponent = JsonUploadAndParseAsyncWrapper; +export const IndexNameFormComponent = IndexNameFormAsyncWrapper; export async function importerFactory( format: string, diff --git a/x-pack/plugins/file_upload/public/api/index_name_form_async_wrapper.tsx b/x-pack/plugins/file_upload/public/api/index_name_form_async_wrapper.tsx new file mode 100644 index 000000000000000..382e2eedebe24e8 --- /dev/null +++ b/x-pack/plugins/file_upload/public/api/index_name_form_async_wrapper.tsx @@ -0,0 +1,43 @@ +/* + * 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 { EuiLoadingContent } from '@elastic/eui'; +import { lazyLoadModules } from '../lazy_load_bundle'; +import { IndexNameFormProps } from '../index'; + +interface State { + IndexNameForm: React.ComponentType | null; +} + +export class IndexNameFormAsyncWrapper extends React.Component { + state: State = { + IndexNameForm: null, + }; + + private _isMounted = false; + + componentWillUnmount(): void { + this._isMounted = false; + } + + componentDidMount() { + this._isMounted = true; + lazyLoadModules().then((modules) => { + if (this._isMounted) { + this.setState({ + IndexNameForm: modules.IndexNameForm, + }); + } + }); + } + + render() { + const { IndexNameForm } = this.state; + return IndexNameForm ? : ; + } +} diff --git a/x-pack/plugins/file_upload/public/api/json_upload_and_parse_async_wrapper.tsx b/x-pack/plugins/file_upload/public/api/json_upload_and_parse_async_wrapper.tsx new file mode 100644 index 000000000000000..281ea93b766947b --- /dev/null +++ b/x-pack/plugins/file_upload/public/api/json_upload_and_parse_async_wrapper.tsx @@ -0,0 +1,48 @@ +/* + * 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 { EuiLoadingContent } from '@elastic/eui'; +import { FileUploadComponentProps, lazyLoadModules } from '../lazy_load_bundle'; + +interface State { + JsonUploadAndParse: React.ComponentType | null; +} + +export class JsonUploadAndParseAsyncWrapper extends React.Component< + FileUploadComponentProps, + State +> { + state: State = { + JsonUploadAndParse: null, + }; + private _isMounted = false; + + componentDidMount() { + this._isMounted = true; + lazyLoadModules().then((modules) => { + if (this._isMounted) { + this.setState({ + JsonUploadAndParse: modules.JsonUploadAndParse, + }); + } + }); + } + + componentWillUnmount(): void { + this._isMounted = false; + } + + render() { + const { JsonUploadAndParse } = this.state; + return JsonUploadAndParse ? ( + + ) : ( + + ); + } +} diff --git a/x-pack/plugins/file_upload/public/lazy_load_bundle/index.ts b/x-pack/plugins/file_upload/public/lazy_load_bundle/index.ts index b0f1b98a9ae728b..9c7c6ff1e5180f2 100644 --- a/x-pack/plugins/file_upload/public/lazy_load_bundle/index.ts +++ b/x-pack/plugins/file_upload/public/lazy_load_bundle/index.ts @@ -32,7 +32,7 @@ export interface FileUploadComponentProps { let loadModulesPromise: Promise; -interface LazyLoadedFileUploadModules { +export interface LazyLoadedFileUploadModules { JsonUploadAndParse: React.ComponentType; IndexNameForm: React.ComponentType; importerFactory: (format: string, options: ImportFactoryOptions) => IImporter | undefined; diff --git a/x-pack/plugins/file_upload/public/plugin.ts b/x-pack/plugins/file_upload/public/plugin.ts index 6240dbe39a85e46..b7b81e19b221955 100644 --- a/x-pack/plugins/file_upload/public/plugin.ts +++ b/x-pack/plugins/file_upload/public/plugin.ts @@ -8,10 +8,10 @@ import { CoreStart, Plugin } from '../../../../src/core/public'; import { FileUploadStartApi, - getFileUploadComponent, + FileUploadComponent, importerFactory, hasImportPermission, - getIndexNameFormComponent, + IndexNameFormComponent, checkIndexExists, getTimeFieldRange, analyzeFile, @@ -42,8 +42,8 @@ export class FileUploadPlugin public start(core: CoreStart, plugins: FileUploadStartDependencies): FileUploadStartApi { setStartServices(core, plugins); return { - getFileUploadComponent, - getIndexNameFormComponent, + FileUploadComponent, + IndexNameFormComponent, importerFactory, getMaxBytes, getMaxBytesFormatted, diff --git a/x-pack/plugins/maps/common/constants.ts b/x-pack/plugins/maps/common/constants.ts index 0d8930bdb75b84c..29eccdea4e8a6bc 100644 --- a/x-pack/plugins/maps/common/constants.ts +++ b/x-pack/plugins/maps/common/constants.ts @@ -41,6 +41,7 @@ export const GIS_API_PATH = `api/${APP_ID}`; 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 INDEX_FEATURE_PATH = `/${GIS_API_PATH}/feature`; export const API_ROOT_PATH = `/${GIS_API_PATH}`; export const MVT_GETTILE_API_PATH = 'mvt/getTile'; diff --git a/x-pack/plugins/maps/common/types.ts b/x-pack/plugins/maps/common/types.ts index 6f2bd72c8089673..6ca3de3dac377c1 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/map_actions.ts b/x-pack/plugins/maps/public/actions/map_actions.ts index 9682306852ba920..4b2d5da31a242fe 100644 --- a/x-pack/plugins/maps/public/actions/map_actions.ts +++ b/x-pack/plugins/maps/public/actions/map_actions.ts @@ -10,7 +10,6 @@ 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 { MapStoreState } from '../reducers/store'; import { diff --git a/x-pack/plugins/maps/public/classes/layers/file_upload_wizard/wizard.tsx b/x-pack/plugins/maps/public/classes/layers/file_upload_wizard/wizard.tsx index 7d6f6757bef18fd..024c2308df6c67e 100644 --- a/x-pack/plugins/maps/public/classes/layers/file_upload_wizard/wizard.tsx +++ b/x-pack/plugins/maps/public/classes/layers/file_upload_wizard/wizard.tsx @@ -11,13 +11,13 @@ import React, { Component } from 'react'; import { FeatureCollection } from 'geojson'; import { EuiPanel } from '@elastic/eui'; import { DEFAULT_MAX_RESULT_WINDOW, SCALING_TYPES } from '../../../../common/constants'; -import { getFileUpload } from '../../../kibana_services'; import { GeoJsonFileSource } from '../../sources/geojson_file_source'; import { VectorLayer } from '../../layers/vector_layer'; import { createDefaultLayerDescriptor } from '../../sources/es_search_source'; import { RenderWizardArguments } from '../../layers/layer_wizard_registry'; -import { FileUploadComponentProps, FileUploadGeoResults } from '../../../../../file_upload/public'; +import { FileUploadGeoResults } from '../../../../../file_upload/public'; import { ES_FIELD_TYPES } from '../../../../../../../src/plugins/data/public'; +import { getFileUploadComponent } from '../../../kibana_services'; export enum UPLOAD_STEPS { CONFIGURE_UPLOAD = 'CONFIGURE_UPLOAD', @@ -34,7 +34,6 @@ enum INDEXING_STAGE { interface State { indexingStage: INDEXING_STAGE; - fileUploadComponent: React.ComponentType | null; results?: FileUploadGeoResults; } @@ -43,12 +42,10 @@ export class ClientFileCreateSourceEditor extends Component { if (!this._isMounted) { return; @@ -157,11 +147,8 @@ export class ClientFileCreateSourceEditor extends Component ( + + + + + + + + + + + +); 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 804352f5bede72c..6ee863cfdb600c2 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,8 @@ 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'; +import { getMapAppConfig } from '../../kibana_services'; let registered = false; export function registerLayerWizards() { @@ -39,6 +41,9 @@ export function registerLayerWizards() { // Registration order determines display order registerLayerWizard(uploadLayerWizardConfig); + if (getMapAppConfig().enableDrawingFeature) { + 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 000000000000000..2a0400c3d6beea6 --- /dev/null +++ b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/config.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 { i18n } from '@kbn/i18n'; +import React from 'react'; +import { LayerWizard, RenderWizardArguments } from '../../layers/layer_wizard_registry'; +import { NewVectorLayerEditor } from './wizard'; +import { DrawLayerIcon } from '../../layers/icons/draw_layer_icon'; +import { getFileUpload } from '../../../kibana_services'; +import { LAYER_WIZARD_CATEGORY } from '../../../../common'; + +const ADD_VECTOR_DRAWING_LAYER = 'ADD_VECTOR_DRAWING_LAYER'; + +export const newVectorLayerWizardConfig: LayerWizard = { + categories: [LAYER_WIZARD_CATEGORY.ELASTICSEARCH], + description: i18n.translate('xpack.maps.newVectorLayerWizard.description', { + defaultMessage: 'Creates a new empty layer. Use this to add shapes to the map', + }), + disabledReason: i18n.translate('xpack.maps.newVectorLayerWizard.disabledDesc', { + defaultMessage: + 'Unable to draw vector shapes, you are missing the Kibana privilege "Index Pattern Management".', + }), + getIsDisabled: async () => { + const hasImportPermission = await getFileUpload().hasImportPermission({ + checkCreateIndexPattern: true, + checkHasManagePipeline: false, + }); + return !hasImportPermission; + }, + icon: DrawLayerIcon, + prerequisiteSteps: [ + { + id: ADD_VECTOR_DRAWING_LAYER, + label: i18n.translate('xpack.maps.newVectorLayerWizard.indexNewLayer', { + defaultMessage: 'Index new layer', + }), + }, + ], + renderWizard: (renderWizardArguments: RenderWizardArguments) => { + return ; + }, + title: i18n.translate('xpack.maps.newVectorLayerWizard.title', { + defaultMessage: 'Create new layer', + }), +}; diff --git a/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/create_new_index_pattern.ts b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/create_new_index_pattern.ts new file mode 100644 index 000000000000000..d612c25157095f8 --- /dev/null +++ b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/create_new_index_pattern.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 { getHttp } from '../../../kibana_services'; +import { CreateDocSourceResp, INDEX_SOURCE_API_PATH } from '../../../../common'; + +export const createNewIndexAndPattern = async (indexName: string) => { + return await getHttp().fetch({ + path: `/${INDEX_SOURCE_API_PATH}`, + method: 'POST', + body: JSON.stringify({ + index: indexName, + // Initially set to static mappings + mappings: { + properties: { + coordinates: { + type: 'geo_shape', + }, + }, + }, + }), + }); +}; 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 000000000000000..c183c19f6e2af95 --- /dev/null +++ b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/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 { newVectorLayerWizardConfig } from './config'; 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 000000000000000..0d39c1c720bf22c --- /dev/null +++ b/x-pack/plugins/maps/public/classes/layers/new_vector_layer_wizard/wizard.tsx @@ -0,0 +1,161 @@ +/* + * 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, Fragment } from 'react'; +import { EuiEmptyPrompt, EuiPanel, EuiCallOut } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { createNewIndexAndPattern } from './create_new_index_pattern'; +import { RenderWizardArguments } from '../layer_wizard_registry'; +import { VectorLayer } from '../vector_layer'; +import { ESSearchSource } from '../../sources/es_search_source'; +import { ADD_LAYER_STEP_ID } from '../../../connected_components/add_layer_panel/view'; +import { getIndexNameFormComponent } from '../../../kibana_services'; + +interface State { + indexName: string; + indexNameError: string; + indexingTriggered: boolean; + createIndexError: string; +} + +export class NewVectorLayerEditor extends Component { + private _isMounted: boolean = false; + + state: State = { + indexName: '', + indexNameError: '', + indexingTriggered: false, + createIndexError: '', + }; + + componentDidMount() { + this._isMounted = true; + } + + componentWillUnmount() { + this._isMounted = false; + } + + async componentDidUpdate() { + if (this.props.currentStepId === ADD_LAYER_STEP_ID && !this.state.indexingTriggered) { + this.setState({ indexingTriggered: true }); + await this._createNewIndex(); + } + } + + _setCreateIndexError(errorMessage: string) { + if (!this._isMounted) { + return; + } + this.setState({ + createIndexError: errorMessage, + }); + } + + _createNewIndex = async () => { + let indexPatternId: string | undefined; + try { + const response = await createNewIndexAndPattern(this.state.indexName); + indexPatternId = response.indexPatternId; + } catch (e) { + this._setCreateIndexError(e.message); + return; + } + + if (!indexPatternId) { + this._setCreateIndexError( + i18n.translate('xpack.maps.layers.newVectorLayerWizard.createIndexError', { + defaultMessage: 'Could not create index with name {message}', + values: { + message: this.state.indexName, + }, + }) + ); + return; + } + + if (!this._isMounted) { + return; + } + // Creates empty layer + const sourceDescriptor = ESSearchSource.createDescriptor({ + indexPatternId, + geoField: 'coordinates', + filterByMapBounds: false, + }); + const layerDescriptor = VectorLayer.createDescriptor( + { sourceDescriptor }, + this.props.mapColors + ); + this.props.previewLayers([layerDescriptor]); + this.props.advanceToNextStep(); + }; + + _onIndexChange = (indexName: string, indexError?: string) => { + this.setState({ + indexName, + indexNameError: indexError ? indexError : '', + }); + if (indexName && !indexError) { + this.props.enableNextBtn(); + } else { + this.props.disableNextBtn(); + } + }; + + render() { + if (this.state.createIndexError) { + return ( + +

{this.state.createIndexError}

+
+ ); + } + + const IndexNameForm = getIndexNameFormComponent(); + return ( + + <> + + {i18n.translate('xpack.maps.layers.newVectorLayerWizard.createNewLayer', { + defaultMessage: 'Create new layer', + })} + + } + body={ + +

+ {i18n.translate( + 'xpack.maps.layers.newVectorLayerWizard.vectorEditorDescription', + { + defaultMessage: `Creates a new vector layer. This can be used to draw and store new shapes.`, + } + )} +

+
+ } + /> + {}} + onIndexNameValidationEnd={() => {}} + /> + +
+ ); + } +} 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 0774798eab46de4..2b18d87f03c8953 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 @@ -21,7 +21,7 @@ import { FlyoutBody } from './flyout_body'; import { LayerDescriptor } from '../../../common/descriptor_types'; import { LayerWizard } from '../../classes/layers/layer_wizard_registry'; -const ADD_LAYER_STEP_ID = 'ADD_LAYER_STEP_ID'; +export const ADD_LAYER_STEP_ID = 'ADD_LAYER_STEP_ID'; const ADD_LAYER_STEP_LABEL = i18n.translate('xpack.maps.addLayerPanel.addLayer', { defaultMessage: 'Add layer', }); 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 355e49564620ddd..ce36ec811df408c 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 @@ -418,11 +418,11 @@ export class MBMap extends Component { }; render() { - let drawControl; + let drawFilterControl; let tooltipControl; let scaleControl; if (this.state.mbMap) { - drawControl = this.props.addFilters ? ( + drawFilterControl = this.props.addFilters ? ( ) : null; tooltipControl = !this.props.settings.disableTooltipControl ? ( @@ -447,7 +447,7 @@ export class MBMap extends Component { ref={this._setContainerRef} data-test-subj="mapContainer" > - {drawControl} + {drawFilterControl} {scaleControl} {tooltipControl} diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/icons/vector_circle_icon.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/icons/vector_circle_icon.tsx new file mode 100644 index 000000000000000..1a39072d0842fd7 --- /dev/null +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/icons/vector_circle_icon.tsx @@ -0,0 +1,25 @@ +/* + * 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, { FunctionComponent } from 'react'; + +export const VectorCircleIcon: FunctionComponent = () => ( + + + +); diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/icons/vector_line_icon.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/icons/vector_line_icon.tsx new file mode 100644 index 000000000000000..0e4baf536e7007e --- /dev/null +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/icons/vector_line_icon.tsx @@ -0,0 +1,26 @@ +/* + * 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, { FunctionComponent } from 'react'; + +export const VectorLineIcon: FunctionComponent = () => ( + + + + +); diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/icons/vector_square_icon.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/icons/vector_square_icon.tsx new file mode 100644 index 000000000000000..4734a4feebc8fa6 --- /dev/null +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/icons/vector_square_icon.tsx @@ -0,0 +1,25 @@ +/* + * 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, { FunctionComponent } from 'react'; + +export const VectorSquareIcon: FunctionComponent = () => ( + + + +); diff --git a/x-pack/plugins/maps/public/kibana_services.ts b/x-pack/plugins/maps/public/kibana_services.ts index e4b9397fab8e79c..1652e78d3d2cbfc 100644 --- a/x-pack/plugins/maps/public/kibana_services.ts +++ b/x-pack/plugins/maps/public/kibana_services.ts @@ -22,6 +22,9 @@ export function setStartServices(core: CoreStart, plugins: MapsPluginStartDepend coreStart = core; pluginsStart = plugins; } + +export const getIndexNameFormComponent = () => pluginsStart.fileUpload.IndexNameFormComponent; +export const getFileUploadComponent = () => pluginsStart.fileUpload.FileUploadComponent; export const getIndexPatternService = () => pluginsStart.data.indexPatterns; export const getAutocompleteService = () => pluginsStart.data.autocomplete; export const getInspector = () => pluginsStart.inspector; @@ -55,7 +58,6 @@ let mapAppConfig: MapsConfigType; export const setMapAppConfig = (config: MapsConfigType) => (mapAppConfig = config); export const getMapAppConfig = () => mapAppConfig; -export const getEnabled = () => getMapAppConfig().enabled; export const getShowMapsInspectorAdapter = () => getMapAppConfig().showMapsInspectorAdapter; export const getPreserveDrawingBuffer = () => getMapAppConfig().preserveDrawingBuffer; 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 2b8984aa1534a1d..22c3da61244afa6 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) { 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 e6e6471ff9af61f..951d7ed085f39b9 100644 --- a/x-pack/plugins/maps/server/data_indexing/indexing_routes.ts +++ b/x-pack/plugins/maps/server/data_indexing/indexing_routes.ts @@ -11,8 +11,8 @@ import { IRouter } from 'src/core/server'; import type { DataRequestHandlerContext } from 'src/plugins/data/server'; import { INDEX_SOURCE_API_PATH, - GIS_API_PATH, MAX_DRAWING_SIZE_BYTES, + INDEX_FEATURE_PATH, } from '../../common/constants'; import { createDocSource } from './create_doc_source'; import { writeDataToIndex } from './index_data'; @@ -70,7 +70,7 @@ export function initIndexingRoutes({ router.post( { - path: `/${GIS_API_PATH}/feature`, + path: INDEX_FEATURE_PATH, validate: { body: schema.object({ index: schema.string(), diff --git a/x-pack/plugins/maps/server/index.ts b/x-pack/plugins/maps/server/index.ts index f77e7d182a3bba1..fecad3ae5cf97d5 100644 --- a/x-pack/plugins/maps/server/index.ts +++ b/x-pack/plugins/maps/server/index.ts @@ -16,6 +16,7 @@ export const config: PluginConfigDescriptor = { exposeToBrowser: { enabled: true, showMapVisualizationTypes: true, + enableDrawingFeature: true, showMapsInspectorAdapter: true, preserveDrawingBuffer: true, },