From 03ef0149ab6a50cf2684214bdace52c27d0fc5ad Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Mon, 13 Apr 2020 09:24:16 -0400 Subject: [PATCH] [Maps] Cleanup sources (#63175) - Introduces additional TS typing for sources - Organizes sources in sub-directories by type - migrates XYZTMSSource to TS --- .../server/maps_telemetry/maps_telemetry.ts | 2 + .../descriptor_types/descriptor_types.d.ts | 26 ++- .../public/layers/blended_vector_layer.ts | 6 +- x-pack/plugins/maps/public/layers/layer.d.ts | 1 + .../public/layers/layer_wizard_registry.ts | 20 +- .../{ => es_agg_source}/es_agg_source.d.ts | 10 +- .../{ => es_agg_source}/es_agg_source.js | 6 +- .../{ => es_agg_source}/es_agg_source.test.ts | 10 +- .../layers/sources/es_agg_source/index.ts | 7 + .../sources/{ => es_source}/es_source.d.ts | 8 +- .../sources/{ => es_source}/es_source.js | 14 +- .../public/layers/sources/es_source/index.ts | 7 + .../{ => es_term_source}/es_term_source.d.ts | 4 +- .../{ => es_term_source}/es_term_source.js | 8 +- .../es_term_source.test.js | 2 +- .../layers/sources/es_term_source/index.ts | 7 + .../maps/public/layers/sources/source.d.ts | 22 ++- .../public/layers/sources/source_registry.ts | 3 +- .../public/layers/sources/tms_source/index.ts | 7 + .../sources/{ => tms_source}/tms_source.d.ts | 3 +- .../sources/{ => tms_source}/tms_source.js | 2 +- .../layers/sources/vector_source/index.ts | 7 + .../{ => vector_source}/vector_source.d.ts | 6 +- .../{ => vector_source}/vector_source.js | 10 +- .../public/layers/sources/xyz_tms_source.d.ts | 11 -- .../public/layers/sources/xyz_tms_source.js | 187 ------------------ .../layers/sources/xyz_tms_source/index.ts | 8 + .../sources/xyz_tms_source/layer_wizard.tsx | 27 +++ .../sources/xyz_tms_source/xyz_tms_editor.tsx | 122 ++++++++++++ .../xyz_tms_source.test.ts | 12 +- .../sources/xyz_tms_source/xyz_tms_source.ts | 87 ++++++++ .../plugins/maps/public/layers/tile_layer.js | 4 +- .../maps/public/layers/tile_layer.test.ts | 2 +- .../maps/public/layers/vector_layer.d.ts | 4 +- 34 files changed, 392 insertions(+), 270 deletions(-) rename x-pack/plugins/maps/public/layers/sources/{ => es_agg_source}/es_agg_source.d.ts (73%) rename x-pack/plugins/maps/public/layers/sources/{ => es_agg_source}/es_agg_source.js (95%) rename x-pack/plugins/maps/public/layers/sources/{ => es_agg_source}/es_agg_source.test.ts (89%) create mode 100644 x-pack/plugins/maps/public/layers/sources/es_agg_source/index.ts rename x-pack/plugins/maps/public/layers/sources/{ => es_source}/es_source.d.ts (78%) rename x-pack/plugins/maps/public/layers/sources/{ => es_source}/es_source.js (95%) create mode 100644 x-pack/plugins/maps/public/layers/sources/es_source/index.ts rename x-pack/plugins/maps/public/layers/sources/{ => es_term_source}/es_term_source.d.ts (77%) rename x-pack/plugins/maps/public/layers/sources/{ => es_term_source}/es_term_source.js (95%) rename x-pack/plugins/maps/public/layers/sources/{ => es_term_source}/es_term_source.test.js (98%) create mode 100644 x-pack/plugins/maps/public/layers/sources/es_term_source/index.ts create mode 100644 x-pack/plugins/maps/public/layers/sources/tms_source/index.ts rename x-pack/plugins/maps/public/layers/sources/{ => tms_source}/tms_source.d.ts (80%) rename x-pack/plugins/maps/public/layers/sources/{ => tms_source}/tms_source.js (94%) create mode 100644 x-pack/plugins/maps/public/layers/sources/vector_source/index.ts rename x-pack/plugins/maps/public/layers/sources/{ => vector_source}/vector_source.d.ts (91%) rename x-pack/plugins/maps/public/layers/sources/{ => vector_source}/vector_source.js (93%) delete mode 100644 x-pack/plugins/maps/public/layers/sources/xyz_tms_source.d.ts delete mode 100644 x-pack/plugins/maps/public/layers/sources/xyz_tms_source.js create mode 100644 x-pack/plugins/maps/public/layers/sources/xyz_tms_source/index.ts create mode 100644 x-pack/plugins/maps/public/layers/sources/xyz_tms_source/layer_wizard.tsx create mode 100644 x-pack/plugins/maps/public/layers/sources/xyz_tms_source/xyz_tms_editor.tsx rename x-pack/plugins/maps/public/layers/sources/{ => xyz_tms_source}/xyz_tms_source.test.ts (71%) create mode 100644 x-pack/plugins/maps/public/layers/sources/xyz_tms_source/xyz_tms_source.ts diff --git a/x-pack/legacy/plugins/maps/server/maps_telemetry/maps_telemetry.ts b/x-pack/legacy/plugins/maps/server/maps_telemetry/maps_telemetry.ts index 5657e14622e9b..0300f22eeeb82 100644 --- a/x-pack/legacy/plugins/maps/server/maps_telemetry/maps_telemetry.ts +++ b/x-pack/legacy/plugins/maps/server/maps_telemetry/maps_telemetry.ts @@ -87,6 +87,8 @@ export function buildMapsTelemetry({ const mapsCount = layerLists.length; const dataSourcesCount = layerLists.map(lList => { + // todo: not every source-descriptor has an id + // @ts-ignore const sourceIdList = lList.map((layer: LayerDescriptor) => layer.sourceDescriptor.id); return _.uniq(sourceIdList).length; }); diff --git a/x-pack/plugins/maps/common/descriptor_types/descriptor_types.d.ts b/x-pack/plugins/maps/common/descriptor_types/descriptor_types.d.ts index fb49e1aaebe1c..ff285877750c5 100644 --- a/x-pack/plugins/maps/common/descriptor_types/descriptor_types.d.ts +++ b/x-pack/plugins/maps/common/descriptor_types/descriptor_types.d.ts @@ -9,6 +9,11 @@ import { AGG_TYPE, GRID_RESOLUTION, RENDER_AS, SORT_ORDER, SCALING_TYPES } from import { VectorStyleDescriptor } from './style_property_descriptor_types'; import { DataRequestDescriptor } from './data_request_descriptor_types'; +export type AttributionDescriptor = { + attributionText?: string; + attributionUrl?: string; +}; + export type AbstractSourceDescriptor = { id?: string; type: string; @@ -84,17 +89,26 @@ export type WMSSourceDescriptor = { attributionUrl: string; }; -export type XYZTMSSourceDescriptor = { - id: string; - type: string; - urlTemplate: string; -}; +export type XYZTMSSourceDescriptor = AbstractSourceDescriptor & + AttributionDescriptor & { + urlTemplate: string; + }; export type JoinDescriptor = { leftField: string; right: ESTermSourceDescriptor; }; +export type SourceDescriptor = + | XYZTMSSourceDescriptor + | WMSSourceDescriptor + | KibanaTilemapSourceDescriptor + | KibanaRegionmapSourceDescriptor + | ESTermSourceDescriptor + | ESSearchSourceDescriptor + | ESGeoGridSourceDescriptor + | EMSFileSourceDescriptor; + export type LayerDescriptor = { __dataRequests?: DataRequestDescriptor[]; __isInErrorState?: boolean; @@ -104,7 +118,7 @@ export type LayerDescriptor = { label?: string; minZoom?: number; maxZoom?: number; - sourceDescriptor: AbstractSourceDescriptor; + sourceDescriptor: SourceDescriptor; type?: string; visible?: boolean; }; diff --git a/x-pack/plugins/maps/public/layers/blended_vector_layer.ts b/x-pack/plugins/maps/public/layers/blended_vector_layer.ts index f5526ad703dd2..80bf0299380d9 100644 --- a/x-pack/plugins/maps/public/layers/blended_vector_layer.ts +++ b/x-pack/plugins/maps/public/layers/blended_vector_layer.ts @@ -34,6 +34,7 @@ import { VectorStyleDescriptor, SizeDynamicOptions, DynamicStylePropertyOptions, + VectorLayerDescriptor, } from '../../common/descriptor_types'; const ACTIVE_COUNT_DATA_ID = 'ACTIVE_COUNT_DATA_ID'; @@ -147,7 +148,10 @@ function getClusterStyleDescriptor( export class BlendedVectorLayer extends VectorLayer implements IVectorLayer { static type = LAYER_TYPE.BLENDED_VECTOR; - static createDescriptor(options: VectorLayerArguments, mapColors: string[]) { + static createDescriptor( + options: VectorLayerDescriptor, + mapColors: string[] + ): VectorLayerDescriptor { const layerDescriptor = VectorLayer.createDescriptor(options, mapColors); layerDescriptor.type = BlendedVectorLayer.type; return layerDescriptor; diff --git a/x-pack/plugins/maps/public/layers/layer.d.ts b/x-pack/plugins/maps/public/layers/layer.d.ts index de59642ede8ab..8fb69734d3d06 100644 --- a/x-pack/plugins/maps/public/layers/layer.d.ts +++ b/x-pack/plugins/maps/public/layers/layer.d.ts @@ -25,6 +25,7 @@ export interface ILayerArguments { } export class AbstractLayer implements ILayer { + static createDescriptor(options: Partial, mapColors?: string[]): LayerDescriptor; constructor(layerArguments: ILayerArguments); getBounds(mapFilters: MapFilters): Promise; getDataRequest(id: string): DataRequest | undefined; diff --git a/x-pack/plugins/maps/public/layers/layer_wizard_registry.ts b/x-pack/plugins/maps/public/layers/layer_wizard_registry.ts index 3ef4701269994..cb87aeaa9da3f 100644 --- a/x-pack/plugins/maps/public/layers/layer_wizard_registry.ts +++ b/x-pack/plugins/maps/public/layers/layer_wizard_registry.ts @@ -5,17 +5,21 @@ */ /* eslint-disable @typescript-eslint/consistent-type-definitions */ -type LayerWizard = { +import { ReactElement } from 'react'; +import { ISource } from './sources/source'; + +export type PreviewSourceHandler = (source: ISource | null) => void; + +export type RenderWizardArguments = { + onPreviewSource: PreviewSourceHandler; + inspectorAdapters: object; +}; + +export type LayerWizard = { description: string; icon: string; isIndexingSource?: boolean; - renderWizard({ - onPreviewSource, - inspectorAdapters, - }: { - onPreviewSource: () => void; - inspectorAdapters: unknown; - }): unknown; + renderWizard(renderWizardArguments: RenderWizardArguments): ReactElement; title: string; }; diff --git a/x-pack/plugins/maps/public/layers/sources/es_agg_source.d.ts b/x-pack/plugins/maps/public/layers/sources/es_agg_source/es_agg_source.d.ts similarity index 73% rename from x-pack/plugins/maps/public/layers/sources/es_agg_source.d.ts rename to x-pack/plugins/maps/public/layers/sources/es_agg_source/es_agg_source.d.ts index 99ee1ec652b54..a93f9121d1e62 100644 --- a/x-pack/plugins/maps/public/layers/sources/es_agg_source.d.ts +++ b/x-pack/plugins/maps/public/layers/sources/es_agg_source/es_agg_source.d.ts @@ -4,11 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import { IESSource } from './es_source'; -import { AbstractESSource } from './es_source'; -import { AGG_TYPE } from '../../../common/constants'; -import { IESAggField } from '../fields/es_agg_field'; -import { AbstractESAggSourceDescriptor } from '../../../common/descriptor_types'; +import { IESSource } from '../es_source'; +import { AbstractESSource } from '../es_source'; +import { AGG_TYPE } from '../../../../common/constants'; +import { IESAggField } from '../../fields/es_agg_field'; +import { AbstractESAggSourceDescriptor } from '../../../../common/descriptor_types'; export interface IESAggSource extends IESSource { getAggKey(aggType: AGG_TYPE, fieldName: string): string; diff --git a/x-pack/plugins/maps/public/layers/sources/es_agg_source.js b/x-pack/plugins/maps/public/layers/sources/es_agg_source/es_agg_source.js similarity index 95% rename from x-pack/plugins/maps/public/layers/sources/es_agg_source.js rename to x-pack/plugins/maps/public/layers/sources/es_agg_source/es_agg_source.js index 9f4b89cadc777..c6197f137f212 100644 --- a/x-pack/plugins/maps/public/layers/sources/es_agg_source.js +++ b/x-pack/plugins/maps/public/layers/sources/es_agg_source/es_agg_source.js @@ -5,15 +5,15 @@ */ import { i18n } from '@kbn/i18n'; -import { AbstractESSource } from './es_source'; -import { esAggFieldsFactory } from '../fields/es_agg_field'; +import { AbstractESSource } from '../es_source'; +import { esAggFieldsFactory } from '../../fields/es_agg_field'; import { AGG_TYPE, COUNT_PROP_LABEL, COUNT_PROP_NAME, FIELD_ORIGIN, -} from '../../../common/constants'; +} from '../../../../common/constants'; export const AGG_DELIMITER = '_of_'; diff --git a/x-pack/plugins/maps/public/layers/sources/es_agg_source.test.ts b/x-pack/plugins/maps/public/layers/sources/es_agg_source/es_agg_source.test.ts similarity index 89% rename from x-pack/plugins/maps/public/layers/sources/es_agg_source.test.ts rename to x-pack/plugins/maps/public/layers/sources/es_agg_source/es_agg_source.test.ts index 848091586eb9c..87abbedfdf50e 100644 --- a/x-pack/plugins/maps/public/layers/sources/es_agg_source.test.ts +++ b/x-pack/plugins/maps/public/layers/sources/es_agg_source/es_agg_source.test.ts @@ -4,12 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -import { AbstractESAggSource } from './es_agg_source'; -import { IField } from '../fields/field'; -import { IESAggField } from '../fields/es_agg_field'; +import { AbstractESAggSource } from '../es_agg_source'; +import { IField } from '../../fields/field'; +import { IESAggField } from '../../fields/es_agg_field'; import _ from 'lodash'; -import { AGG_TYPE } from '../../../common/constants'; -import { AggDescriptor } from '../../../common/descriptor_types'; +import { AGG_TYPE } from '../../../../common/constants'; +import { AggDescriptor } from '../../../../common/descriptor_types'; jest.mock('ui/new_platform'); diff --git a/x-pack/plugins/maps/public/layers/sources/es_agg_source/index.ts b/x-pack/plugins/maps/public/layers/sources/es_agg_source/index.ts new file mode 100644 index 0000000000000..cbf4eceefd432 --- /dev/null +++ b/x-pack/plugins/maps/public/layers/sources/es_agg_source/index.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export * from './es_agg_source'; diff --git a/x-pack/plugins/maps/public/layers/sources/es_source.d.ts b/x-pack/plugins/maps/public/layers/sources/es_source/es_source.d.ts similarity index 78% rename from x-pack/plugins/maps/public/layers/sources/es_source.d.ts rename to x-pack/plugins/maps/public/layers/sources/es_source/es_source.d.ts index 65851d0e7bd38..092dc3bf0d5a8 100644 --- a/x-pack/plugins/maps/public/layers/sources/es_source.d.ts +++ b/x-pack/plugins/maps/public/layers/sources/es_source/es_source.d.ts @@ -4,10 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import { AbstractVectorSource } from './vector_source'; -import { IVectorSource } from './vector_source'; -import { IndexPattern, SearchSource } from '../../../../../../src/plugins/data/public'; -import { VectorSourceRequestMeta } from '../../../common/descriptor_types'; +import { AbstractVectorSource } from '../vector_source'; +import { IVectorSource } from '../vector_source'; +import { IndexPattern, SearchSource } from '../../../../../../../src/plugins/data/public'; +import { VectorSourceRequestMeta } from '../../../../common/descriptor_types'; export interface IESSource extends IVectorSource { getId(): string; diff --git a/x-pack/plugins/maps/public/layers/sources/es_source.js b/x-pack/plugins/maps/public/layers/sources/es_source/es_source.js similarity index 95% rename from x-pack/plugins/maps/public/layers/sources/es_source.js rename to x-pack/plugins/maps/public/layers/sources/es_source/es_source.js index d90a802a38344..3402e367cbd73 100644 --- a/x-pack/plugins/maps/public/layers/sources/es_source.js +++ b/x-pack/plugins/maps/public/layers/sources/es_source/es_source.js @@ -4,23 +4,23 @@ * you may not use this file except in compliance with the Elastic License. */ -import { AbstractVectorSource } from './vector_source'; +import { AbstractVectorSource } from '../vector_source'; import { getAutocompleteService, fetchSearchSourceAndRecordWithInspector, getIndexPatternService, SearchSource, getTimeFilter, -} from '../../kibana_services'; -import { createExtentFilter } from '../../elasticsearch_geo_utils'; +} from '../../../kibana_services'; +import { createExtentFilter } from '../../../elasticsearch_geo_utils'; import _ from 'lodash'; import { i18n } from '@kbn/i18n'; import uuid from 'uuid/v4'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { copyPersistentState } from '../../reducers/util'; -import { ES_GEO_FIELD_TYPE } from '../../../common/constants'; -import { DataRequestAbortError } from '../util/data_request'; -import { expandToTileBoundaries } from './es_geo_grid_source/geo_tile_utils'; +import { copyPersistentState } from '../../../reducers/util'; +import { ES_GEO_FIELD_TYPE } from '../../../../common/constants'; +import { DataRequestAbortError } from '../../util/data_request'; +import { expandToTileBoundaries } from '../es_geo_grid_source/geo_tile_utils'; export class AbstractESSource extends AbstractVectorSource { constructor(descriptor, inspectorAdapters) { diff --git a/x-pack/plugins/maps/public/layers/sources/es_source/index.ts b/x-pack/plugins/maps/public/layers/sources/es_source/index.ts new file mode 100644 index 0000000000000..227a4dd634457 --- /dev/null +++ b/x-pack/plugins/maps/public/layers/sources/es_source/index.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export * from './es_source'; diff --git a/x-pack/plugins/maps/public/layers/sources/es_term_source.d.ts b/x-pack/plugins/maps/public/layers/sources/es_term_source/es_term_source.d.ts similarity index 77% rename from x-pack/plugins/maps/public/layers/sources/es_term_source.d.ts rename to x-pack/plugins/maps/public/layers/sources/es_term_source/es_term_source.d.ts index 44cdc851b4fc7..701bd5e2c8b5e 100644 --- a/x-pack/plugins/maps/public/layers/sources/es_term_source.d.ts +++ b/x-pack/plugins/maps/public/layers/sources/es_term_source/es_term_source.d.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { IField } from '../fields/field'; -import { IESAggSource } from './es_agg_source'; +import { IField } from '../../fields/field'; +import { IESAggSource } from '../es_agg_source'; export interface IESTermSource extends IESAggSource { getTermField(): IField; diff --git a/x-pack/plugins/maps/public/layers/sources/es_term_source.js b/x-pack/plugins/maps/public/layers/sources/es_term_source/es_term_source.js similarity index 95% rename from x-pack/plugins/maps/public/layers/sources/es_term_source.js rename to x-pack/plugins/maps/public/layers/sources/es_term_source/es_term_source.js index 3ce0fb58aba19..826197cc4fec7 100644 --- a/x-pack/plugins/maps/public/layers/sources/es_term_source.js +++ b/x-pack/plugins/maps/public/layers/sources/es_term_source/es_term_source.js @@ -7,10 +7,10 @@ import _ from 'lodash'; import { i18n } from '@kbn/i18n'; -import { DEFAULT_MAX_BUCKETS_LIMIT, FIELD_ORIGIN, AGG_TYPE } from '../../../common/constants'; -import { ESDocField } from '../fields/es_doc_field'; -import { AbstractESAggSource, AGG_DELIMITER } from './es_agg_source'; -import { getField, addFieldToDSL, extractPropertiesFromBucket } from '../util/es_agg_utils'; +import { DEFAULT_MAX_BUCKETS_LIMIT, FIELD_ORIGIN, AGG_TYPE } from '../../../../common/constants'; +import { ESDocField } from '../../fields/es_doc_field'; +import { AbstractESAggSource, AGG_DELIMITER } from '../es_agg_source'; +import { getField, addFieldToDSL, extractPropertiesFromBucket } from '../../util/es_agg_utils'; const TERMS_AGG_NAME = 'join'; diff --git a/x-pack/plugins/maps/public/layers/sources/es_term_source.test.js b/x-pack/plugins/maps/public/layers/sources/es_term_source/es_term_source.test.js similarity index 98% rename from x-pack/plugins/maps/public/layers/sources/es_term_source.test.js rename to x-pack/plugins/maps/public/layers/sources/es_term_source/es_term_source.test.js index 14ffd068df465..b6cd3b670d3ce 100644 --- a/x-pack/plugins/maps/public/layers/sources/es_term_source.test.js +++ b/x-pack/plugins/maps/public/layers/sources/es_term_source/es_term_source.test.js @@ -7,7 +7,7 @@ import { ESTermSource, extractPropertiesMap } from './es_term_source'; jest.mock('ui/new_platform'); -jest.mock('../vector_layer', () => {}); +jest.mock('../../vector_layer', () => {}); const indexPatternTitle = 'myIndex'; const termFieldName = 'myTermField'; diff --git a/x-pack/plugins/maps/public/layers/sources/es_term_source/index.ts b/x-pack/plugins/maps/public/layers/sources/es_term_source/index.ts new file mode 100644 index 0000000000000..6fad8384c690d --- /dev/null +++ b/x-pack/plugins/maps/public/layers/sources/es_term_source/index.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export * from './es_term_source'; diff --git a/x-pack/plugins/maps/public/layers/sources/source.d.ts b/x-pack/plugins/maps/public/layers/sources/source.d.ts index e1706ad7b7d77..a1581b826d9a6 100644 --- a/x-pack/plugins/maps/public/layers/sources/source.d.ts +++ b/x-pack/plugins/maps/public/layers/sources/source.d.ts @@ -3,10 +3,21 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ +/* eslint-disable @typescript-eslint/consistent-type-definitions */ -import { AbstractSourceDescriptor } from '../../../common/descriptor_types'; +import { AbstractSourceDescriptor, LayerDescriptor } from '../../../common/descriptor_types'; import { ILayer } from '../layer'; +export type ImmutableSourceProperty = { + label: string; + value: string; +}; + +export type Attribution = { + url: string; + label: string; +}; + export interface ISource { createDefaultLayer(): ILayer; destroy(): void; @@ -18,13 +29,16 @@ export interface ISource { isQueryAware(): boolean; isRefreshTimerAware(): Promise; isTimeAware(): Promise; + getImmutableProperties(): Promise; + getAttributions(): Promise; } export class AbstractSource implements ISource { - constructor(sourceDescriptor: AbstractSourceDescriptor, inspectorAdapters: object); + readonly _descriptor: AbstractSourceDescriptor; + constructor(sourceDescriptor: AbstractSourceDescriptor, inspectorAdapters?: object); destroy(): void; - createDefaultLayer(): ILayer; + createDefaultLayer(options?: LayerDescriptor, mapColors?: string[]): ILayer; getDisplayName(): Promise; getInspectorAdapters(): object; isFieldAware(): boolean; @@ -33,4 +47,6 @@ export class AbstractSource implements ISource { isQueryAware(): boolean; isRefreshTimerAware(): Promise; isTimeAware(): Promise; + getImmutableProperties(): Promise; + getAttributions(): Promise; } diff --git a/x-pack/plugins/maps/public/layers/sources/source_registry.ts b/x-pack/plugins/maps/public/layers/sources/source_registry.ts index 518cab68b601b..d16b16af74e9d 100644 --- a/x-pack/plugins/maps/public/layers/sources/source_registry.ts +++ b/x-pack/plugins/maps/public/layers/sources/source_registry.ts @@ -5,12 +5,11 @@ */ /* eslint-disable @typescript-eslint/consistent-type-definitions */ -import { AbstractSourceDescriptor } from '../../../common/descriptor_types'; import { ISource } from './source'; type SourceRegistryEntry = { ConstructorFunction: new ( - sourceDescriptor: AbstractSourceDescriptor, + sourceDescriptor: any, // this is the source-descriptor that corresponds specifically to the particular ISource instance inspectorAdapters: unknown ) => ISource; type: string; diff --git a/x-pack/plugins/maps/public/layers/sources/tms_source/index.ts b/x-pack/plugins/maps/public/layers/sources/tms_source/index.ts new file mode 100644 index 0000000000000..f6bb1c6bc34ec --- /dev/null +++ b/x-pack/plugins/maps/public/layers/sources/tms_source/index.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export * from './tms_source'; diff --git a/x-pack/plugins/maps/public/layers/sources/tms_source.d.ts b/x-pack/plugins/maps/public/layers/sources/tms_source/tms_source.d.ts similarity index 80% rename from x-pack/plugins/maps/public/layers/sources/tms_source.d.ts rename to x-pack/plugins/maps/public/layers/sources/tms_source/tms_source.d.ts index 90b6f28e050fd..b31138f4cdb86 100644 --- a/x-pack/plugins/maps/public/layers/sources/tms_source.d.ts +++ b/x-pack/plugins/maps/public/layers/sources/tms_source/tms_source.d.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { AbstractSource, ISource } from './source'; +import { AbstractSource, Attribution, ISource } from '../source'; export interface ITMSSource extends ISource { getUrlTemplate(): Promise; @@ -12,4 +12,5 @@ export interface ITMSSource extends ISource { export class AbstractTMSSource extends AbstractSource implements ITMSSource { getUrlTemplate(): Promise; + getAttributions(): Promise; } diff --git a/x-pack/plugins/maps/public/layers/sources/tms_source.js b/x-pack/plugins/maps/public/layers/sources/tms_source/tms_source.js similarity index 94% rename from x-pack/plugins/maps/public/layers/sources/tms_source.js rename to x-pack/plugins/maps/public/layers/sources/tms_source/tms_source.js index f2ec9f2a29378..13b8da11633bc 100644 --- a/x-pack/plugins/maps/public/layers/sources/tms_source.js +++ b/x-pack/plugins/maps/public/layers/sources/tms_source/tms_source.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { AbstractSource } from './source'; +import { AbstractSource } from '../source'; export class AbstractTMSSource extends AbstractSource { async getUrlTemplate() { diff --git a/x-pack/plugins/maps/public/layers/sources/vector_source/index.ts b/x-pack/plugins/maps/public/layers/sources/vector_source/index.ts new file mode 100644 index 0000000000000..62e801d027634 --- /dev/null +++ b/x-pack/plugins/maps/public/layers/sources/vector_source/index.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export * from './vector_source'; diff --git a/x-pack/plugins/maps/public/layers/sources/vector_source.d.ts b/x-pack/plugins/maps/public/layers/sources/vector_source/vector_source.d.ts similarity index 91% rename from x-pack/plugins/maps/public/layers/sources/vector_source.d.ts rename to x-pack/plugins/maps/public/layers/sources/vector_source/vector_source.d.ts index d597e64277186..63429830d9f4f 100644 --- a/x-pack/plugins/maps/public/layers/sources/vector_source.d.ts +++ b/x-pack/plugins/maps/public/layers/sources/vector_source/vector_source.d.ts @@ -6,14 +6,14 @@ /* eslint-disable @typescript-eslint/consistent-type-definitions */ import { FeatureCollection } from 'geojson'; -import { AbstractSource, ISource } from './source'; -import { IField } from '../fields/field'; +import { AbstractSource, ISource } from '../source'; +import { IField } from '../../fields/field'; import { ESSearchSourceResponseMeta, MapExtent, VectorSourceRequestMeta, VectorSourceSyncMeta, -} from '../../../common/descriptor_types'; +} from '../../../../common/descriptor_types'; export type GeoJsonFetchMeta = ESSearchSourceResponseMeta; diff --git a/x-pack/plugins/maps/public/layers/sources/vector_source.js b/x-pack/plugins/maps/public/layers/sources/vector_source/vector_source.js similarity index 93% rename from x-pack/plugins/maps/public/layers/sources/vector_source.js rename to x-pack/plugins/maps/public/layers/sources/vector_source/vector_source.js index 7f97b1b21d189..bb37175b48655 100644 --- a/x-pack/plugins/maps/public/layers/sources/vector_source.js +++ b/x-pack/plugins/maps/public/layers/sources/vector_source/vector_source.js @@ -4,14 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ -import { VectorLayer } from '../vector_layer'; -import { TooltipProperty } from '../tooltips/tooltip_property'; -import { VectorStyle } from '../styles/vector/vector_style'; -import { AbstractSource } from './source'; +import { VectorLayer } from '../../vector_layer'; +import { TooltipProperty } from '../../tooltips/tooltip_property'; +import { VectorStyle } from '../../styles/vector/vector_style'; +import { AbstractSource } from './../source'; import * as topojson from 'topojson-client'; import _ from 'lodash'; import { i18n } from '@kbn/i18n'; -import { VECTOR_SHAPE_TYPES } from './vector_feature_types'; +import { VECTOR_SHAPE_TYPES } from './../vector_feature_types'; export class AbstractVectorSource extends AbstractSource { static async getGeoJson({ format, featureCollectionPath, fetchUrl }) { diff --git a/x-pack/plugins/maps/public/layers/sources/xyz_tms_source.d.ts b/x-pack/plugins/maps/public/layers/sources/xyz_tms_source.d.ts deleted file mode 100644 index 579c9debeab3e..0000000000000 --- a/x-pack/plugins/maps/public/layers/sources/xyz_tms_source.d.ts +++ /dev/null @@ -1,11 +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; - * you may not use this file except in compliance with the Elastic License. - */ -import { AbstractTMSSource } from './tms_source'; -import { XYZTMSSourceDescriptor } from '../../../common/descriptor_types'; - -export class XYZTMSSource extends AbstractTMSSource { - constructor(sourceDescriptor: XYZTMSSourceDescriptor, inspectorAdapters: unknown); -} diff --git a/x-pack/plugins/maps/public/layers/sources/xyz_tms_source.js b/x-pack/plugins/maps/public/layers/sources/xyz_tms_source.js deleted file mode 100644 index d53fbffd21512..0000000000000 --- a/x-pack/plugins/maps/public/layers/sources/xyz_tms_source.js +++ /dev/null @@ -1,187 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import React, { Fragment } from 'react'; -import { EuiFieldText, EuiFormRow } from '@elastic/eui'; - -import { AbstractTMSSource } from './tms_source'; -import { TileLayer } from '../tile_layer'; -import { i18n } from '@kbn/i18n'; -import { getDataSourceLabel, getUrlLabel } from '../../../common/i18n_getters'; -import _ from 'lodash'; -import { EMS_XYZ } from '../../../common/constants'; -import { registerSource } from './source_registry'; - -const sourceTitle = i18n.translate('xpack.maps.source.ems_xyzTitle', { - defaultMessage: 'Tile Map Service', -}); - -export class XYZTMSSource extends AbstractTMSSource { - static type = EMS_XYZ; - - static createDescriptor({ urlTemplate, attributionText, attributionUrl }) { - return { - type: XYZTMSSource.type, - urlTemplate, - attributionText, - attributionUrl, - }; - } - - async getImmutableProperties() { - return [ - { label: getDataSourceLabel(), value: sourceTitle }, - { label: getUrlLabel(), value: this._descriptor.urlTemplate }, - ]; - } - - _createDefaultLayerDescriptor(options) { - return TileLayer.createDescriptor({ - sourceDescriptor: this._descriptor, - ...options, - }); - } - - createDefaultLayer(options) { - return new TileLayer({ - layerDescriptor: this._createDefaultLayerDescriptor(options), - source: this, - }); - } - - async getDisplayName() { - return this._descriptor.urlTemplate; - } - - getAttributions() { - const { attributionText, attributionUrl } = this._descriptor; - const attributionComplete = !!attributionText && !!attributionUrl; - - return attributionComplete - ? [ - { - url: attributionUrl, - label: attributionText, - }, - ] - : []; - } - - getUrlTemplate() { - return this._descriptor.urlTemplate; - } -} - -class XYZTMSEditor extends React.Component { - state = { - tmsInput: '', - tmsCanPreview: false, - attributionText: '', - attributionUrl: '', - }; - - _sourceConfigChange = _.debounce(updatedSourceConfig => { - if (this.state.tmsCanPreview) { - this.props.onSourceConfigChange(updatedSourceConfig); - } - }, 2000); - - _handleTMSInputChange(e) { - const url = e.target.value; - - const canPreview = - url.indexOf('{x}') >= 0 && url.indexOf('{y}') >= 0 && url.indexOf('{z}') >= 0; - this.setState( - { - tmsInput: url, - tmsCanPreview: canPreview, - }, - () => this._sourceConfigChange({ urlTemplate: url }) - ); - } - - _handleTMSAttributionChange(attributionUpdate) { - this.setState(attributionUpdate, () => { - const { attributionText, attributionUrl, tmsInput } = this.state; - - if (tmsInput && attributionText && attributionUrl) { - this._sourceConfigChange({ - urlTemplate: tmsInput, - attributionText, - attributionUrl, - }); - } - }); - } - - render() { - const { attributionText, attributionUrl } = this.state; - - return ( - - - this._handleTMSInputChange(e)} - /> - - - - this._handleTMSAttributionChange({ attributionText: target.value }) - } - /> - - - - this._handleTMSAttributionChange({ attributionUrl: target.value }) - } - /> - - - ); - } -} - -registerSource({ - ConstructorFunction: XYZTMSSource, - type: EMS_XYZ, -}); - -export const tmsLayerWizardConfig = { - description: i18n.translate('xpack.maps.source.ems_xyzDescription', { - defaultMessage: 'Tile map service configured in interface', - }), - icon: 'grid', - renderWizard: ({ onPreviewSource, inspectorAdapters }) => { - const onSourceConfigChange = sourceConfig => { - const sourceDescriptor = XYZTMSSource.createDescriptor(sourceConfig); - const source = new XYZTMSSource(sourceDescriptor, inspectorAdapters); - onPreviewSource(source); - }; - return ; - }, - title: sourceTitle, -}; diff --git a/x-pack/plugins/maps/public/layers/sources/xyz_tms_source/index.ts b/x-pack/plugins/maps/public/layers/sources/xyz_tms_source/index.ts new file mode 100644 index 0000000000000..c1116ad47a375 --- /dev/null +++ b/x-pack/plugins/maps/public/layers/sources/xyz_tms_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; + * you may not use this file except in compliance with the Elastic License. + */ + +export * from './xyz_tms_source'; +export * from './layer_wizard'; diff --git a/x-pack/plugins/maps/public/layers/sources/xyz_tms_source/layer_wizard.tsx b/x-pack/plugins/maps/public/layers/sources/xyz_tms_source/layer_wizard.tsx new file mode 100644 index 0000000000000..8b1ed588c8dd1 --- /dev/null +++ b/x-pack/plugins/maps/public/layers/sources/xyz_tms_source/layer_wizard.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; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; +import React from 'react'; +import { XYZTMSEditor, XYZTMSSourceConfig } from './xyz_tms_editor'; +import { XYZTMSSource, sourceTitle } from './xyz_tms_source'; +import { LayerWizard, RenderWizardArguments } from '../../layer_wizard_registry'; + +export const tmsLayerWizardConfig: LayerWizard = { + description: i18n.translate('xpack.maps.source.ems_xyzDescription', { + defaultMessage: 'Tile map service configured in interface', + }), + icon: 'grid', + renderWizard: ({ onPreviewSource }: RenderWizardArguments) => { + const onSourceConfigChange = (sourceConfig: XYZTMSSourceConfig) => { + const sourceDescriptor = XYZTMSSource.createDescriptor(sourceConfig); + const source = new XYZTMSSource(sourceDescriptor); + onPreviewSource(source); + }; + return ; + }, + title: sourceTitle, +}; diff --git a/x-pack/plugins/maps/public/layers/sources/xyz_tms_source/xyz_tms_editor.tsx b/x-pack/plugins/maps/public/layers/sources/xyz_tms_source/xyz_tms_editor.tsx new file mode 100644 index 0000000000000..0ee0fbb23bcff --- /dev/null +++ b/x-pack/plugins/maps/public/layers/sources/xyz_tms_source/xyz_tms_editor.tsx @@ -0,0 +1,122 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +/* eslint-disable @typescript-eslint/consistent-type-definitions */ + +import React, { Fragment, Component, ChangeEvent } from 'react'; +import _ from 'lodash'; +import { EuiFormRow, EuiFieldText } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { AttributionDescriptor } from '../../../../common/descriptor_types'; + +export type XYZTMSSourceConfig = AttributionDescriptor & { + urlTemplate: string; +}; + +export interface Props { + onSourceConfigChange: (sourceConfig: XYZTMSSourceConfig) => void; +} + +interface State { + tmsInput: string; + tmsCanPreview: boolean; + attributionText: string; + attributionUrl: string; +} + +export class XYZTMSEditor extends Component { + state = { + tmsInput: '', + tmsCanPreview: false, + attributionText: '', + attributionUrl: '', + }; + + _sourceConfigChange = _.debounce((updatedSourceConfig: XYZTMSSourceConfig) => { + if (this.state.tmsCanPreview) { + this.props.onSourceConfigChange(updatedSourceConfig); + } + }, 2000); + + _handleTMSInputChange(e: ChangeEvent) { + const url = e.target.value; + + const canPreview = + url.indexOf('{x}') >= 0 && url.indexOf('{y}') >= 0 && url.indexOf('{z}') >= 0; + this.setState( + { + tmsInput: url, + tmsCanPreview: canPreview, + }, + () => this._sourceConfigChange({ urlTemplate: url }) + ); + } + + _handleTMSAttributionChange(attributionUpdate: AttributionDescriptor) { + this.setState( + { + attributionUrl: attributionUpdate.attributionUrl || '', + attributionText: attributionUpdate.attributionText || '', + }, + () => { + const { attributionText, attributionUrl, tmsInput } = this.state; + + if (tmsInput && attributionText && attributionUrl) { + this._sourceConfigChange({ + urlTemplate: tmsInput, + attributionText, + attributionUrl, + }); + } + } + ); + } + + render() { + const { attributionText, attributionUrl } = this.state; + return ( + + + this._handleTMSInputChange(e)} + /> + + + ) => + this._handleTMSAttributionChange({ attributionText: target.value }) + } + /> + + + ) => + this._handleTMSAttributionChange({ attributionUrl: target.value }) + } + /> + + + ); + } +} diff --git a/x-pack/plugins/maps/public/layers/sources/xyz_tms_source.test.ts b/x-pack/plugins/maps/public/layers/sources/xyz_tms_source/xyz_tms_source.test.ts similarity index 71% rename from x-pack/plugins/maps/public/layers/sources/xyz_tms_source.test.ts rename to x-pack/plugins/maps/public/layers/sources/xyz_tms_source/xyz_tms_source.test.ts index e5ab5e57122ba..8a5cfb01e5821 100644 --- a/x-pack/plugins/maps/public/layers/sources/xyz_tms_source.test.ts +++ b/x-pack/plugins/maps/public/layers/sources/xyz_tms_source/xyz_tms_source.test.ts @@ -5,10 +5,10 @@ */ import { XYZTMSSource } from './xyz_tms_source'; -import { ILayer } from '../layer'; -import { TileLayer } from '../tile_layer'; -import { EMS_XYZ } from '../../../common/constants'; -import { XYZTMSSourceDescriptor } from '../../../common/descriptor_types'; +import { ILayer } from '../../layer'; +import { TileLayer } from '../../tile_layer'; +import { EMS_XYZ } from '../../../../common/constants'; +import { XYZTMSSourceDescriptor } from '../../../../common/descriptor_types'; const descriptor: XYZTMSSourceDescriptor = { type: EMS_XYZ, @@ -17,13 +17,13 @@ const descriptor: XYZTMSSourceDescriptor = { }; describe('xyz Tilemap Source', () => { it('should create a tile-layer', () => { - const source = new XYZTMSSource(descriptor, null); + const source = new XYZTMSSource(descriptor); const layer: ILayer = source.createDefaultLayer(); expect(layer instanceof TileLayer).toEqual(true); }); it('should echo url template for url template', async () => { - const source = new XYZTMSSource(descriptor, null); + const source = new XYZTMSSource(descriptor); const template = await source.getUrlTemplate(); expect(template).toEqual(descriptor.urlTemplate); }); diff --git a/x-pack/plugins/maps/public/layers/sources/xyz_tms_source/xyz_tms_source.ts b/x-pack/plugins/maps/public/layers/sources/xyz_tms_source/xyz_tms_source.ts new file mode 100644 index 0000000000000..dd96c31573316 --- /dev/null +++ b/x-pack/plugins/maps/public/layers/sources/xyz_tms_source/xyz_tms_source.ts @@ -0,0 +1,87 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; +import { TileLayer } from '../../tile_layer'; +import { getDataSourceLabel, getUrlLabel } from '../../../../common/i18n_getters'; +import { EMS_XYZ } from '../../../../common/constants'; +import { registerSource } from '../source_registry'; +import { AbstractTMSSource } from '../tms_source'; +import { LayerDescriptor, XYZTMSSourceDescriptor } from '../../../../common/descriptor_types'; +import { Attribution, ImmutableSourceProperty } from '../source'; +import { XYZTMSSourceConfig } from './xyz_tms_editor'; + +export const sourceTitle = i18n.translate('xpack.maps.source.ems_xyzTitle', { + defaultMessage: 'Tile Map Service', +}); + +export class XYZTMSSource extends AbstractTMSSource { + static type = EMS_XYZ; + + readonly _descriptor: XYZTMSSourceDescriptor; + + static createDescriptor({ + urlTemplate, + attributionText, + attributionUrl, + }: XYZTMSSourceConfig): XYZTMSSourceDescriptor { + return { + type: XYZTMSSource.type, + urlTemplate, + attributionText, + attributionUrl, + }; + } + + constructor(sourceDescriptor: XYZTMSSourceDescriptor) { + super(sourceDescriptor); + this._descriptor = sourceDescriptor; + } + + async getImmutableProperties(): Promise { + return [ + { label: getDataSourceLabel(), value: sourceTitle }, + { label: getUrlLabel(), value: this._descriptor.urlTemplate }, + ]; + } + + createDefaultLayer(options?: LayerDescriptor): TileLayer { + const layerDescriptor: LayerDescriptor = TileLayer.createDescriptor({ + sourceDescriptor: this._descriptor, + ...options, + }); + return new TileLayer({ + layerDescriptor, + source: this, + }); + } + + async getDisplayName(): Promise { + return this._descriptor.urlTemplate; + } + + async getAttributions(): Promise { + const { attributionText, attributionUrl } = this._descriptor; + const attributionComplete = !!attributionText && !!attributionUrl; + return attributionComplete + ? [ + { + url: attributionUrl as string, + label: attributionText as string, + }, + ] + : []; + } + + async getUrlTemplate(): Promise { + return this._descriptor.urlTemplate; + } +} + +registerSource({ + ConstructorFunction: XYZTMSSource, + type: EMS_XYZ, +}); diff --git a/x-pack/plugins/maps/public/layers/tile_layer.js b/x-pack/plugins/maps/public/layers/tile_layer.js index aa2619e96f834..2ac60e12d137a 100644 --- a/x-pack/plugins/maps/public/layers/tile_layer.js +++ b/x-pack/plugins/maps/public/layers/tile_layer.js @@ -11,8 +11,8 @@ import { SOURCE_DATA_ID_ORIGIN, LAYER_TYPE } from '../../common/constants'; export class TileLayer extends AbstractLayer { static type = LAYER_TYPE.TILE; - static createDescriptor(options) { - const tileLayerDescriptor = super.createDescriptor(options); + static createDescriptor(options, mapColors) { + const tileLayerDescriptor = super.createDescriptor(options, mapColors); tileLayerDescriptor.type = TileLayer.type; tileLayerDescriptor.alpha = _.get(options, 'alpha', 1); return tileLayerDescriptor; diff --git a/x-pack/plugins/maps/public/layers/tile_layer.test.ts b/x-pack/plugins/maps/public/layers/tile_layer.test.ts index 1cb99dcbc1a70..43465eac7f3ce 100644 --- a/x-pack/plugins/maps/public/layers/tile_layer.test.ts +++ b/x-pack/plugins/maps/public/layers/tile_layer.test.ts @@ -17,7 +17,7 @@ const sourceDescriptor: XYZTMSSourceDescriptor = { }; class MockTileSource extends AbstractTMSSource implements ITMSSource { - private readonly _descriptor: XYZTMSSourceDescriptor; + readonly _descriptor: XYZTMSSourceDescriptor; constructor(descriptor: XYZTMSSourceDescriptor) { super(descriptor, {}); this._descriptor = descriptor; diff --git a/x-pack/plugins/maps/public/layers/vector_layer.d.ts b/x-pack/plugins/maps/public/layers/vector_layer.d.ts index 70fd9927b7732..88b1a1ce8535e 100644 --- a/x-pack/plugins/maps/public/layers/vector_layer.d.ts +++ b/x-pack/plugins/maps/public/layers/vector_layer.d.ts @@ -32,8 +32,8 @@ export interface IVectorLayer extends ILayer { export class VectorLayer extends AbstractLayer implements IVectorLayer { static createDescriptor( - options: VectorLayerArguments, - mapColors: string[] + options: Partial, + mapColors?: string[] ): VectorLayerDescriptor; protected readonly _source: IVectorSource;