diff --git a/x-pack/plugins/maps/public/classes/sources/xyz_tms_source/__snapshots__/xyz_tms_editor.test.tsx.snap b/x-pack/plugins/maps/public/classes/sources/xyz_tms_source/__snapshots__/xyz_tms_editor.test.tsx.snap
new file mode 100644
index 000000000000..b8ed4a727fad
--- /dev/null
+++ b/x-pack/plugins/maps/public/classes/sources/xyz_tms_source/__snapshots__/xyz_tms_editor.test.tsx.snap
@@ -0,0 +1,237 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`attribution validation should provide no validation errors when attribution text and attribution url are provided 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`attribution validation should provide validation error when attribution text is provided without attribution url 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`attribution validation should provide validation error when attribution url is provided without attribution text 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`should render 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/x-pack/plugins/maps/public/classes/sources/xyz_tms_source/layer_wizard.tsx b/x-pack/plugins/maps/public/classes/sources/xyz_tms_source/layer_wizard.tsx
index 48c526855d3a..b0344a3e0e31 100644
--- a/x-pack/plugins/maps/public/classes/sources/xyz_tms_source/layer_wizard.tsx
+++ b/x-pack/plugins/maps/public/classes/sources/xyz_tms_source/layer_wizard.tsx
@@ -19,7 +19,12 @@ export const tmsLayerWizardConfig: LayerWizard = {
}),
icon: 'grid',
renderWizard: ({ previewLayers }: RenderWizardArguments) => {
- const onSourceConfigChange = (sourceConfig: XYZTMSSourceConfig) => {
+ const onSourceConfigChange = (sourceConfig: XYZTMSSourceConfig | null) => {
+ if (!sourceConfig) {
+ previewLayers([]);
+ return;
+ }
+
const layerDescriptor = TileLayer.createDescriptor({
sourceDescriptor: XYZTMSSource.createDescriptor(sourceConfig),
});
diff --git a/x-pack/plugins/maps/public/classes/sources/xyz_tms_source/xyz_tms_editor.test.tsx b/x-pack/plugins/maps/public/classes/sources/xyz_tms_source/xyz_tms_editor.test.tsx
new file mode 100644
index 000000000000..71f78c3e1515
--- /dev/null
+++ b/x-pack/plugins/maps/public/classes/sources/xyz_tms_source/xyz_tms_editor.test.tsx
@@ -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;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+import { shallow } from 'enzyme';
+import { XYZTMSEditor } from './xyz_tms_editor';
+
+const onSourceConfigChange = () => {};
+
+test('should render', () => {
+ const component = shallow();
+ expect(component).toMatchSnapshot();
+});
+
+describe('attribution validation', () => {
+ test('should provide validation error when attribution text is provided without attribution url', () => {
+ const component = shallow();
+ component.setState({ attributionText: 'myAttribtionLabel' });
+ expect(component).toMatchSnapshot();
+ });
+
+ test('should provide validation error when attribution url is provided without attribution text', () => {
+ const component = shallow();
+ component.setState({ attributionUrl: 'http://mySource' });
+ expect(component).toMatchSnapshot();
+ });
+
+ test('should provide no validation errors when attribution text and attribution url are provided', () => {
+ const component = shallow();
+ component.setState({ attributionText: 'myAttribtionLabel' });
+ component.setState({ attributionUrl: 'http://mySource' });
+ expect(component).toMatchSnapshot();
+ });
+});
diff --git a/x-pack/plugins/maps/public/classes/sources/xyz_tms_source/xyz_tms_editor.tsx b/x-pack/plugins/maps/public/classes/sources/xyz_tms_source/xyz_tms_editor.tsx
index bf5f2c3dfe04..5583f637b447 100644
--- a/x-pack/plugins/maps/public/classes/sources/xyz_tms_source/xyz_tms_editor.tsx
+++ b/x-pack/plugins/maps/public/classes/sources/xyz_tms_source/xyz_tms_editor.tsx
@@ -9,70 +9,56 @@ import React, { Component, ChangeEvent } from 'react';
import _ from 'lodash';
import { EuiFormRow, EuiFieldText, EuiPanel } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { AttributionDescriptor } from '../../../../common/descriptor_types';
-export type XYZTMSSourceConfig = AttributionDescriptor & {
+export type XYZTMSSourceConfig = {
urlTemplate: string;
+ attributionText: string;
+ attributionUrl: string;
};
-export interface Props {
- onSourceConfigChange: (sourceConfig: XYZTMSSourceConfig) => void;
+interface Props {
+ onSourceConfigChange: (sourceConfig: XYZTMSSourceConfig | null) => void;
}
interface State {
- tmsInput: string;
- tmsCanPreview: boolean;
+ url: string;
attributionText: string;
attributionUrl: string;
}
export class XYZTMSEditor extends Component {
state = {
- tmsInput: '',
- tmsCanPreview: false,
+ url: '',
attributionText: '',
attributionUrl: '',
};
- _sourceConfigChange = _.debounce((updatedSourceConfig: XYZTMSSourceConfig) => {
- if (this.state.tmsCanPreview) {
- this.props.onSourceConfigChange(updatedSourceConfig);
- }
- }, 2000);
-
- _handleTMSInputChange(e: ChangeEvent) {
- const url = e.target.value;
+ _previewLayer = _.debounce(() => {
+ const { url, attributionText, attributionUrl } = this.state;
- const canPreview =
+ const isUrlValid =
url.indexOf('{x}') >= 0 && url.indexOf('{y}') >= 0 && url.indexOf('{z}') >= 0;
- this.setState(
- {
- tmsInput: url,
- tmsCanPreview: canPreview,
- },
- () => this._sourceConfigChange({ urlTemplate: url })
- );
- }
+ const sourceConfig = isUrlValid
+ ? {
+ urlTemplate: url,
+ attributionText,
+ attributionUrl,
+ }
+ : null;
+ this.props.onSourceConfigChange(sourceConfig);
+ }, 500);
- _handleTMSAttributionChange(attributionUpdate: AttributionDescriptor) {
- this.setState(
- {
- attributionUrl: attributionUpdate.attributionUrl || '',
- attributionText: attributionUpdate.attributionText || '',
- },
- () => {
- const { attributionText, attributionUrl, tmsInput } = this.state;
+ _onUrlChange = (event: ChangeEvent) => {
+ this.setState({ url: event.target.value }, this._previewLayer);
+ };
- if (tmsInput && attributionText && attributionUrl) {
- this._sourceConfigChange({
- urlTemplate: tmsInput,
- attributionText,
- attributionUrl,
- });
- }
- }
- );
- }
+ _onAttributionTextChange = (event: ChangeEvent) => {
+ this.setState({ attributionText: event.target.value }, this._previewLayer);
+ };
+
+ _onAttributionUrlChange = (event: ChangeEvent) => {
+ this.setState({ attributionUrl: event.target.value }, this._previewLayer);
+ };
render() {
const { attributionText, attributionUrl } = this.state;
@@ -81,11 +67,13 @@ export class XYZTMSEditor extends Component {
this._handleTMSInputChange(e)}
+ onChange={this._onUrlChange}
/>
{
}),
]}
>
- ) =>
- this._handleTMSAttributionChange({ attributionText: target.value })
- }
- />
+
{
}),
]}
>
- ) =>
- this._handleTMSAttributionChange({ attributionUrl: target.value })
- }
- />
+
);