[Maps] Add draw wizard (#100278)
This commit is contained in:
parent
639df23aa4
commit
c5aa39835d
|
@ -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<typeof getFileUploadComponent>;
|
||||
getIndexNameFormComponent(): Promise<React.ComponentType<IndexNameFormProps>>;
|
||||
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<FileUploadComponentProps>
|
||||
> {
|
||||
const fileUploadModules = await lazyLoadModules();
|
||||
return fileUploadModules.JsonUploadAndParse;
|
||||
}
|
||||
|
||||
export async function getIndexNameFormComponent(): Promise<
|
||||
React.ComponentType<IndexNameFormProps>
|
||||
> {
|
||||
const fileUploadModules = await lazyLoadModules();
|
||||
return fileUploadModules.IndexNameForm;
|
||||
}
|
||||
export const FileUploadComponent = JsonUploadAndParseAsyncWrapper;
|
||||
export const IndexNameFormComponent = IndexNameFormAsyncWrapper;
|
||||
|
||||
export async function importerFactory(
|
||||
format: string,
|
||||
|
|
|
@ -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<IndexNameFormProps> | null;
|
||||
}
|
||||
|
||||
export class IndexNameFormAsyncWrapper extends React.Component<IndexNameFormProps, State> {
|
||||
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 ? <IndexNameForm {...this.props} /> : <EuiLoadingContent lines={3} />;
|
||||
}
|
||||
}
|
|
@ -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<FileUploadComponentProps> | 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 ? (
|
||||
<JsonUploadAndParse {...this.props} />
|
||||
) : (
|
||||
<EuiLoadingContent lines={3} />
|
||||
);
|
||||
}
|
||||
}
|
|
@ -32,7 +32,7 @@ export interface FileUploadComponentProps {
|
|||
|
||||
let loadModulesPromise: Promise<LazyLoadedFileUploadModules>;
|
||||
|
||||
interface LazyLoadedFileUploadModules {
|
||||
export interface LazyLoadedFileUploadModules {
|
||||
JsonUploadAndParse: React.ComponentType<FileUploadComponentProps>;
|
||||
IndexNameForm: React.ComponentType<IndexNameFormProps>;
|
||||
importerFactory: (format: string, options: ImportFactoryOptions) => IImporter | undefined;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
export interface CreateDocSourceResp {
|
||||
indexPatternId?: string;
|
||||
success: boolean;
|
||||
error?: Error;
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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<FileUploadComponentProps> | null;
|
||||
results?: FileUploadGeoResults;
|
||||
}
|
||||
|
||||
|
@ -43,12 +42,10 @@ export class ClientFileCreateSourceEditor extends Component<RenderWizardArgument
|
|||
|
||||
state: State = {
|
||||
indexingStage: INDEXING_STAGE.CONFIGURE,
|
||||
fileUploadComponent: null,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this._isMounted = true;
|
||||
this._loadFileUploadComponent();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
@ -91,13 +88,6 @@ export class ClientFileCreateSourceEditor extends Component<RenderWizardArgument
|
|||
this.props.advanceToNextStep();
|
||||
});
|
||||
|
||||
async _loadFileUploadComponent() {
|
||||
const fileUploadComponent = await getFileUpload().getFileUploadComponent();
|
||||
if (this._isMounted) {
|
||||
this.setState({ fileUploadComponent });
|
||||
}
|
||||
}
|
||||
|
||||
_onFileSelect = (geojsonFile: FeatureCollection, name: string, previewCoverage: number) => {
|
||||
if (!this._isMounted) {
|
||||
return;
|
||||
|
@ -157,11 +147,8 @@ export class ClientFileCreateSourceEditor extends Component<RenderWizardArgument
|
|||
};
|
||||
|
||||
render() {
|
||||
if (!this.state.fileUploadComponent) {
|
||||
return null;
|
||||
}
|
||||
const FileUpload = getFileUploadComponent();
|
||||
|
||||
const FileUpload = this.state.fileUploadComponent;
|
||||
return (
|
||||
<EuiPanel>
|
||||
<FileUpload
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* 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 DrawLayerIcon: FunctionComponent = () => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="49"
|
||||
height="25"
|
||||
fill="none"
|
||||
viewBox="0 0 49 25"
|
||||
className="mapLayersWizardIcon"
|
||||
>
|
||||
<path
|
||||
className="mapLayersWizardIcon__background"
|
||||
d="M12.281 3l-6.625 7.625 1.657 8.938 35.218-.813v-13l-10.625-3.5-9.781 9.5L12.281 3z"
|
||||
/>
|
||||
<path
|
||||
className="mapLayersWizardIcon__highlight"
|
||||
fillRule="evenodd"
|
||||
d="M31.775 1.68l11.256 3.708v13.85l-36.133.834-1.777-9.593 7.114-8.189 9.875 8.778 9.665-9.388zm.262 1.14l-9.897 9.612-9.813-8.722-6.135 7.06 1.535 8.283 34.304-.792V6.111L32.037 2.82z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
<circle cx="7.281" cy="19.5" r="2.5" className="mapLayersWizardIcon__highlight" />
|
||||
<circle cx="5.656" cy="10.25" r="2.5" className="mapLayersWizardIcon__highlight" />
|
||||
<circle cx="12.156" cy="3.625" r="2.5" className="mapLayersWizardIcon__highlight" />
|
||||
<circle cx="22" cy="11.6" r="2.5" className="mapLayersWizardIcon__highlight" />
|
||||
<circle cx="31.969" cy="2.5" r="2.5" className="mapLayersWizardIcon__highlight" />
|
||||
<circle cx="42.344" cy="6.125" r="2.5" className="mapLayersWizardIcon__highlight" />
|
||||
<circle cx="42.344" cy="19" r="2.5" className="mapLayersWizardIcon__highlight" />
|
||||
</svg>
|
||||
);
|
|
@ -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);
|
||||
|
|
|
@ -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 <NewVectorLayerEditor {...renderWizardArguments} />;
|
||||
},
|
||||
title: i18n.translate('xpack.maps.newVectorLayerWizard.title', {
|
||||
defaultMessage: 'Create new layer',
|
||||
}),
|
||||
};
|
|
@ -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<CreateDocSourceResp>({
|
||||
path: `/${INDEX_SOURCE_API_PATH}`,
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
index: indexName,
|
||||
// Initially set to static mappings
|
||||
mappings: {
|
||||
properties: {
|
||||
coordinates: {
|
||||
type: 'geo_shape',
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
});
|
||||
};
|
|
@ -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';
|
|
@ -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<RenderWizardArguments, State> {
|
||||
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 (
|
||||
<EuiCallOut
|
||||
title={i18n.translate('xpack.maps.layers.newVectorLayerWizard.createIndexErrorTitle', {
|
||||
defaultMessage: 'Sorry, could not create index pattern',
|
||||
})}
|
||||
color="danger"
|
||||
iconType="alert"
|
||||
>
|
||||
<p>{this.state.createIndexError}</p>
|
||||
</EuiCallOut>
|
||||
);
|
||||
}
|
||||
|
||||
const IndexNameForm = getIndexNameFormComponent();
|
||||
return (
|
||||
<EuiPanel>
|
||||
<>
|
||||
<EuiEmptyPrompt
|
||||
title={
|
||||
<h4>
|
||||
{i18n.translate('xpack.maps.layers.newVectorLayerWizard.createNewLayer', {
|
||||
defaultMessage: 'Create new layer',
|
||||
})}
|
||||
</h4>
|
||||
}
|
||||
body={
|
||||
<Fragment>
|
||||
<p>
|
||||
{i18n.translate(
|
||||
'xpack.maps.layers.newVectorLayerWizard.vectorEditorDescription',
|
||||
{
|
||||
defaultMessage: `Creates a new vector layer. This can be used to draw and store new shapes.`,
|
||||
}
|
||||
)}
|
||||
</p>
|
||||
</Fragment>
|
||||
}
|
||||
/>
|
||||
<IndexNameForm
|
||||
indexName={this.state.indexName}
|
||||
indexNameError={this.state.indexNameError}
|
||||
onIndexNameChange={this._onIndexChange}
|
||||
onIndexNameValidationStart={() => {}}
|
||||
onIndexNameValidationEnd={() => {}}
|
||||
/>
|
||||
</>
|
||||
</EuiPanel>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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',
|
||||
});
|
||||
|
|
|
@ -418,11 +418,11 @@ export class MBMap extends Component<Props, State> {
|
|||
};
|
||||
|
||||
render() {
|
||||
let drawControl;
|
||||
let drawFilterControl;
|
||||
let tooltipControl;
|
||||
let scaleControl;
|
||||
if (this.state.mbMap) {
|
||||
drawControl = this.props.addFilters ? (
|
||||
drawFilterControl = this.props.addFilters ? (
|
||||
<DrawFilterControl mbMap={this.state.mbMap} addFilters={this.props.addFilters} />
|
||||
) : null;
|
||||
tooltipControl = !this.props.settings.disableTooltipControl ? (
|
||||
|
@ -447,7 +447,7 @@ export class MBMap extends Component<Props, State> {
|
|||
ref={this._setContainerRef}
|
||||
data-test-subj="mapContainer"
|
||||
>
|
||||
{drawControl}
|
||||
{drawFilterControl}
|
||||
{scaleControl}
|
||||
{tooltipControl}
|
||||
</div>
|
||||
|
|
|
@ -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 = () => (
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="euiIcon"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M8 15C11.866 15 15 11.866 15 8C15 4.13401 11.866 1 8 1C4.13401 1 1 4.13401 1 8C1 11.866 4.13401 15 8 15ZM8 14C11.3137 14 14 11.3137 14 8C14 4.68629 11.3137 2 8 2C4.68629 2 2 4.68629 2 8C2 11.3137 4.68629 14 8 14Z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
|
@ -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 = () => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
fill="none"
|
||||
viewBox="0 0 16 16"
|
||||
className="euiIcon"
|
||||
>
|
||||
<path d="M11.506 3.881l.707.707-7.594 7.594-.707-.707z" />
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M5 11H1v4h4v-4zm-1 1H2v2h2v-2zM15 1h-4v4h4V1zm-1 1h-2v2h2V2z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
);
|
|
@ -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 = () => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
fill="none"
|
||||
viewBox="0 0 16 16"
|
||||
className="euiIcon"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M1.5 2a.5.5 0 01.5-.5h12a.5.5 0 01.5.5v12a.5.5 0 01-.5.5H2a.5.5 0 01-.5-.5V2zm1 .5v11h11v-11h-11z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
);
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -29,9 +29,10 @@ export async function createDocSource(
|
|||
): Promise<CreateDocSourceResp> {
|
||||
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) {
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -16,6 +16,7 @@ export const config: PluginConfigDescriptor<MapsXPackConfig> = {
|
|||
exposeToBrowser: {
|
||||
enabled: true,
|
||||
showMapVisualizationTypes: true,
|
||||
enableDrawingFeature: true,
|
||||
showMapsInspectorAdapter: true,
|
||||
preserveDrawingBuffer: true,
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue