diff --git a/x-pack/plugins/gis/public/components/layer_panel/_layer_panel.scss b/x-pack/plugins/gis/public/components/layer_panel/_layer_panel.scss index e5eb76e562bf8..64ed57a211301 100644 --- a/x-pack/plugins/gis/public/components/layer_panel/_layer_panel.scss +++ b/x-pack/plugins/gis/public/components/layer_panel/_layer_panel.scss @@ -23,6 +23,14 @@ box-shadow: 0 $euiSize $euiSize (-$euiSize / 2) $euiColorLightestShade; } +.gisLayerPanel__sourceDetails { + margin-left: $euiSizeXL; +} + +.gisLayerPanel__sourceDetail { + margin-bottom: 0px !important; +} + .gisLayerPanel__footer { border-top: $euiBorderThin; box-shadow: 0 ($euiSize *-1) $euiSize (-$euiSize / 2) $euiColorLightestShade; diff --git a/x-pack/plugins/gis/public/components/layer_panel/settings_panel/settings_panel.js b/x-pack/plugins/gis/public/components/layer_panel/settings_panel/settings_panel.js index d551852961400..e69b114184bd8 100644 --- a/x-pack/plugins/gis/public/components/layer_panel/settings_panel/settings_panel.js +++ b/x-pack/plugins/gis/public/components/layer_panel/settings_panel/settings_panel.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { Component, Fragment } from 'react'; +import React from 'react'; import { EuiFlexGroup, @@ -15,46 +15,35 @@ import { EuiFieldText, EuiRange, EuiSpacer, - EuiLink, } from '@elastic/eui'; import { ValidatedRange } from '../../../shared/components/validated_range'; -export class SettingsPanel extends Component { +export function SettingsPanel(props) { - state = { - showSourceDetails: false, - } - - toggleSourceDetails = () => { - this.setState((prevState) => ({ - showSourceDetails: !prevState.showSourceDetails, - })); - } - - onLabelChange = (event) => { + const onLabelChange = (event) => { const label = event.target.value; - this.props.updateLabel(this.props.layerId, label); - } + props.updateLabel(props.layerId, label); + }; - onMinZoomChange = (event) => { + const onMinZoomChange = (event) => { const zoom = parseInt(event.target.value, 10); - this.props.updateMinZoom(this.props.layerId, zoom); - } + props.updateMinZoom(props.layerId, zoom); + }; - onMaxZoomChange = (event) => { + const onMaxZoomChange = (event) => { const zoom = parseInt(event.target.value, 10); - this.props.updateMaxZoom(this.props.layerId, zoom); - } + props.updateMaxZoom(props.layerId, zoom); + }; - onAlphaChange = (alpha) => { - this.props.updateAlpha(this.props.layerId, alpha); - } + const onAlphaChange = (alpha) => { + props.updateAlpha(props.layerId, alpha); + }; - onSourceChange = ({ propName, value }) => { - this.props.updateSourceProp(this.props.layerId, propName, value); - } + const onSourceChange = ({ propName, value }) => { + props.updateSourceProp(props.layerId, propName, value); + }; - renderZoomSliders() { + const renderZoomSliders = () => { return ( @@ -81,8 +70,8 @@ export class SettingsPanel extends Component { @@ -91,22 +80,22 @@ export class SettingsPanel extends Component { ); - } + }; - renderLabel() { + const renderLabel = () => { return ( ); - } + }; - renderAlphaSlider() { + const renderAlphaSlider = () => { return ( ); - } + }; - renderSourceDetails() { - if (!this.state.showSourceDetails) { - return null; - } + return ( + + + +
Settings
+
+
- return ( - - {this.props.layer.renderSourceDetails()} - - - ); - } + - render() { - return ( - - - -
Settings
-
- - - source details - - -
- - + {renderLabel()} - {this.renderSourceDetails()} + {renderZoomSliders()} - {this.renderLabel()} + {renderAlphaSlider()} - {this.renderZoomSliders()} + {props.layer.renderSourceSettingsEditor({ onChange: onSourceChange })} - {this.renderAlphaSlider()} - - {this.props.layer.renderSourceSettingsEditor({ onChange: this.onSourceChange })} - -
- ); - } +
+ ); } diff --git a/x-pack/plugins/gis/public/components/layer_panel/view.js b/x-pack/plugins/gis/public/components/layer_panel/view.js index 6c46c94c75602..400d2f0f7d9e4 100644 --- a/x-pack/plugins/gis/public/components/layer_panel/view.js +++ b/x-pack/plugins/gis/public/components/layer_panel/view.js @@ -21,17 +21,38 @@ import { EuiFlyoutBody, EuiFlyoutFooter, EuiSpacer, + EuiAccordion, + EuiText, + EuiLink, } from '@elastic/eui'; export class LayerPanel extends React.Component { - state = { - displayName: null + static getDerivedStateFromProps(nextProps, prevState) { + const nextId = nextProps.selectedLayer.getId(); + if (nextId !== prevState.prevId) { + return { + displayName: '', + immutableSourceProps: [], + hasLoadedSourcePropsForLayer: false, + prevId: nextId, + }; + } + + return null; } + state = {} + componentDidMount() { this._isMounted = true; this.loadDisplayName(); + this.loadImmutableSourceProperties(); + } + + componentDidUpdate() { + this.loadDisplayName(); + this.loadImmutableSourceProperties(); } componentWillUnmount() { @@ -40,8 +61,24 @@ export class LayerPanel extends React.Component { loadDisplayName = async () => { const displayName = await this.props.selectedLayer.getDisplayName(); + if (!this._isMounted || displayName === this.state.displayName) { + return; + } + + this.setState({ displayName }); + } + + loadImmutableSourceProperties = async () => { + if (this.state.hasLoadedSourcePropsForLayer) { + return; + } + + const immutableSourceProps = await this.props.selectedLayer.getImmutableSourceProperties(); if (this._isMounted) { - this.setState({ displayName }); + this.setState({ + immutableSourceProps, + hasLoadedSourcePropsForLayer: true, + }); } } @@ -60,6 +97,23 @@ export class LayerPanel extends React.Component { ); } + _renderSourceProperties() { + return this.state.immutableSourceProps.map(({ label, value, link }) => { + function renderValue() { + if (link) { + return ({value}); + } + return ({value}); + } + return ( +

+ {label}{' '} + {renderValue()} +

+ ); + }); + } + render() { const { selectedLayer } = this.props; @@ -81,6 +135,18 @@ export class LayerPanel extends React.Component { + +
+ + + + {this._renderSourceProperties()} + + +
diff --git a/x-pack/plugins/gis/public/shared/components/es_source_details.js b/x-pack/plugins/gis/public/shared/components/es_source_details.js deleted file mode 100644 index 2cf424fae84d9..0000000000000 --- a/x-pack/plugins/gis/public/shared/components/es_source_details.js +++ /dev/null @@ -1,46 +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, { Component } from 'react'; - -import { - EuiText, -} from '@elastic/eui'; - -export class ESSourceDetails extends Component { - - state = { - indexPatternTitle: null - } - - componentDidMount() { - this._isMounted = true; - this.loadDisplayName(); - } - - componentWillUnmount() { - this._isMounted = false; - } - - loadDisplayName = async () => { - const indexPatternTitle = await this.props.source.getDisplayName(); - if (this._isMounted) { - this.setState({ indexPatternTitle }); - } - } - - render() { - return ( - -

- Type {this.props.sourceType}
- Index pattern {this.state.indexPatternTitle}
- {this.props.geoFieldType}{this.props.geoField}
-

-
- ); - } -} diff --git a/x-pack/plugins/gis/public/shared/layers/_index.scss b/x-pack/plugins/gis/public/shared/layers/_index.scss index f51627d55c2c5..a2ce58e0381af 100644 --- a/x-pack/plugins/gis/public/shared/layers/_index.scss +++ b/x-pack/plugins/gis/public/shared/layers/_index.scss @@ -1,2 +1 @@ @import './styles/index'; -@import './layers'; diff --git a/x-pack/plugins/gis/public/shared/layers/_layers.scss b/x-pack/plugins/gis/public/shared/layers/_layers.scss deleted file mode 100644 index 33a81a949d650..0000000000000 --- a/x-pack/plugins/gis/public/shared/layers/_layers.scss +++ /dev/null @@ -1,10 +0,0 @@ -.gisLayerDetails__label { - display: inline-block; - min-width: 5.5em; - margin-right: $euiSizeS; - white-space: nowrap; - - + span { - word-break: break-all; - } -} diff --git a/x-pack/plugins/gis/public/shared/layers/layer.js b/x-pack/plugins/gis/public/shared/layers/layer.js index ab6c5ef5345e2..8be7a06e86af0 100644 --- a/x-pack/plugins/gis/public/shared/layers/layer.js +++ b/x-pack/plugins/gis/public/shared/layers/layer.js @@ -133,9 +133,9 @@ export class AbstractLayer { return this._style; } - renderSourceDetails = () => { - return this._source.renderDetails(); - }; + async getImmutableSourceProperties() { + return this._source.getImmutableProperties(); + } renderSourceSettingsEditor = ({ onChange }) => { return this._source.renderSourceSettingsEditor({ onChange }); diff --git a/x-pack/plugins/gis/public/shared/layers/sources/ems_file_source.js b/x-pack/plugins/gis/public/shared/layers/sources/ems_file_source.js index 2af4a08a92f33..85dd5e6dc156b 100644 --- a/x-pack/plugins/gis/public/shared/layers/sources/ems_file_source.js +++ b/x-pack/plugins/gis/public/shared/layers/sources/ems_file_source.js @@ -7,8 +7,6 @@ import { AbstractVectorSource } from './vector_source'; import React from 'react'; import { - EuiLink, - EuiText, EuiSelect, EuiFormRow, } from '@elastic/eui'; @@ -70,17 +68,12 @@ export class EMSFileSource extends AbstractVectorSource { }; } - renderDetails() { - const emsHotLink = emsServiceSettings.getEMSHotLink(this._descriptor.id); - return ( - -

- Source Elastic Maps Service
- Id {this._descriptor.id}
- Preview on maps.elastic.co
-

-
- ); + async getImmutableProperties() { + const emsLink = await emsServiceSettings.getEMSHotLink({ id: this._descriptor.id }); + return [ + { label: 'Data source', value: EMSFileSource.title }, + { label: 'Layer', value: this._descriptor.id, link: emsLink } + ]; } async getDisplayName() { diff --git a/x-pack/plugins/gis/public/shared/layers/sources/ems_tms_source/ems_tms_source.js b/x-pack/plugins/gis/public/shared/layers/sources/ems_tms_source/ems_tms_source.js index a7ae50061d3f0..129f00ee6a541 100644 --- a/x-pack/plugins/gis/public/shared/layers/sources/ems_tms_source/ems_tms_source.js +++ b/x-pack/plugins/gis/public/shared/layers/sources/ems_tms_source/ems_tms_source.js @@ -7,7 +7,6 @@ import React from 'react'; import { AbstractTMSSource } from '../tms_source'; import { TileLayer } from '../../tile_layer'; import { - EuiText, EuiSelect, EuiFormRow, } from '@elastic/eui'; @@ -58,16 +57,11 @@ export class EMSTMSSource extends AbstractTMSSource { this._emsTileServices = emsTmsServices; } - renderDetails() { - return ( - -

- Source Elastic Maps Service
- Type Tile
- Id {this._descriptor.id}
-

-
- ); + async getImmutableProperties() { + return [ + { label: 'Data source', value: EMSTMSSource.title }, + { label: 'Tile service', value: this._descriptor.id } + ]; } _getTMSOptions() { diff --git a/x-pack/plugins/gis/public/shared/layers/sources/es_geo_grid_source/es_geo_grid_source.js b/x-pack/plugins/gis/public/shared/layers/sources/es_geo_grid_source/es_geo_grid_source.js index 7ad9ac41ad117..e76d7beef9978 100644 --- a/x-pack/plugins/gis/public/shared/layers/sources/es_geo_grid_source/es_geo_grid_source.js +++ b/x-pack/plugins/gis/public/shared/layers/sources/es_geo_grid_source/es_geo_grid_source.js @@ -16,7 +16,6 @@ import { makeGeohashGridPolygon } from '../../../../elasticsearch_geo_utils'; import { AggConfigs } from 'ui/vis/agg_configs'; import { tabifyAggResponse } from 'ui/agg_response/tabify'; import { convertToGeoJson } from './convert_to_geojson'; -import { ESSourceDetails } from '../../../components/es_source_details'; import { VectorStyle } from '../../styles/vector_style'; import { RENDER_AS } from './render_as'; import { CreateSourceEditor } from './create_source_editor'; @@ -88,15 +87,21 @@ export class ESGeoGridSource extends AbstractESSource { ); } - renderDetails() { - return ( - - ); + async getImmutableProperties() { + let indexPatternTitle = this._descriptor.indexPatternId; + try { + const indexPattern = await this._getIndexPattern(); + indexPatternTitle = indexPattern.title; + } catch (error) { + // ignore error, title will just default to id + } + + return [ + { label: 'Data source', value: ESGeoGridSource.title }, + { label: 'Index pattern', value: indexPatternTitle }, + { label: 'Geospatial field', value: this._descriptor.geoField }, + { label: 'Show as', value: this._descriptor.requestType }, + ]; } getFieldNames() { diff --git a/x-pack/plugins/gis/public/shared/layers/sources/es_join_source.js b/x-pack/plugins/gis/public/shared/layers/sources/es_join_source.js index 1c43dbdd9634e..ca8c44ed7942a 100644 --- a/x-pack/plugins/gis/public/shared/layers/sources/es_join_source.js +++ b/x-pack/plugins/gis/public/shared/layers/sources/es_join_source.js @@ -5,7 +5,6 @@ */ import _ from 'lodash'; -import React, { Fragment } from 'react'; import { AbstractSource } from './source'; import { Schemas } from 'ui/vis/editors/default/schemas'; @@ -68,10 +67,6 @@ export class ESJoinSource extends AbstractSource { return `
editor details
`; } - renderDetails() { - return (table source details); - } - hasCompleteConfig() { if (_.has(this._descriptor, 'indexPatternId') && _.has(this._descriptor, 'term')) { return true; diff --git a/x-pack/plugins/gis/public/shared/layers/sources/es_search_source/es_search_source.js b/x-pack/plugins/gis/public/shared/layers/sources/es_search_source/es_search_source.js index 27caf9e133533..3fdb2f6a07129 100644 --- a/x-pack/plugins/gis/public/shared/layers/sources/es_search_source/es_search_source.js +++ b/x-pack/plugins/gis/public/shared/layers/sources/es_search_source/es_search_source.js @@ -13,7 +13,6 @@ import { indexPatternService, } from '../../../../kibana_services'; import { hitsToGeoJson } from '../../../../elasticsearch_geo_utils'; -import { ESSourceDetails } from '../../../components/es_source_details'; import { CreateSourceEditor } from './create_source_editor'; import { UpdateSourceEditor } from './update_source_editor'; @@ -73,21 +72,27 @@ export class ESSearchSource extends AbstractESSource { ]; } + async getImmutableProperties() { + let indexPatternTitle = this._descriptor.indexPatternId; + let geoFieldType = ''; + try { + const indexPattern = await this._getIndexPattern(); + indexPatternTitle = indexPattern.title; + const geoField = await this._getGeoField(); + geoFieldType = geoField.type; + } catch (error) { + // ignore error, title will just default to id + } - renderDetails() { - return ( - - ); + return [ + { label: 'Data source', value: ESSearchSource.title }, + { label: 'Index pattern', value: indexPatternTitle }, + { label: 'Geospatial field', value: this._descriptor.geoField }, + { label: 'Geospatial field type', value: geoFieldType }, + ]; } async getGeoJsonWithMeta({ layerName }, searchFilters) { - - const searchSource = await this._makeSearchSource(searchFilters, this._descriptor.limit); // Setting "fields" instead of "source: { includes: []}" // because SearchSource automatically adds the following by default @@ -107,7 +112,6 @@ export class ESSearchSource extends AbstractESSource { return properties; }; - const resp = await this._runEsQuery(layerName, searchSource, 'Elasticsearch document request'); try { const geoField = await this._getGeoField(); @@ -158,7 +162,6 @@ export class ESSearchSource extends AbstractESSource { return _.get(this._descriptor, 'filterByMapBounds', false); } - async getStringFields() { const indexPattern = await this._getIndexPattern(); const stringFields = indexPattern.fields.filter(field => { @@ -168,5 +171,4 @@ export class ESSearchSource extends AbstractESSource { return { name: stringField.name, label: stringField.name }; }); } - } diff --git a/x-pack/plugins/gis/public/shared/layers/sources/kibana_regionmap_source/kibana_regionmap_source.js b/x-pack/plugins/gis/public/shared/layers/sources/kibana_regionmap_source/kibana_regionmap_source.js index 7377423cb66f1..cbdc31c516a37 100644 --- a/x-pack/plugins/gis/public/shared/layers/sources/kibana_regionmap_source/kibana_regionmap_source.js +++ b/x-pack/plugins/gis/public/shared/layers/sources/kibana_regionmap_source/kibana_regionmap_source.js @@ -7,9 +7,6 @@ import _ from 'lodash'; import { AbstractVectorSource } from '../vector_source'; import React from 'react'; -import { - EuiText, -} from '@elastic/eui'; import { CreateSourceEditor } from './create_source_editor'; export class KibanaRegionmapSource extends AbstractVectorSource { @@ -48,16 +45,11 @@ export class KibanaRegionmapSource extends AbstractVectorSource { ); }; - renderDetails() { - return ( - -

- Source Kibana Region Map
- Type Vector
- Name {this._descriptor.name}
-

-
- ); + async getImmutableProperties() { + return [ + { label: 'Data source', value: KibanaRegionmapSource.title }, + { label: 'Vector layer', value: this._descriptor.name }, + ]; } async getGeoJsonWithMeta() { diff --git a/x-pack/plugins/gis/public/shared/layers/sources/kibana_tilemap_source/kibana_tilemap_source.js b/x-pack/plugins/gis/public/shared/layers/sources/kibana_tilemap_source/kibana_tilemap_source.js index 89b81f3989452..a14b8d90fc976 100644 --- a/x-pack/plugins/gis/public/shared/layers/sources/kibana_tilemap_source/kibana_tilemap_source.js +++ b/x-pack/plugins/gis/public/shared/layers/sources/kibana_tilemap_source/kibana_tilemap_source.js @@ -7,7 +7,6 @@ import React from 'react'; import { AbstractTMSSource } from '../tms_source'; import { TileLayer } from '../../tile_layer'; import { CreateSourceEditor } from './create_source_editor'; -import { EuiText } from '@elastic/eui'; export class KibanaTilemapSource extends AbstractTMSSource { @@ -33,16 +32,11 @@ export class KibanaTilemapSource extends AbstractTMSSource { return (); }; - renderDetails() { - return ( - -

- Source Kibana Tilemap Configuration
- Type Tile
- Id {this._descriptor.id}
-

-
- ); + async getImmutableProperties() { + return [ + { label: 'Data source', value: KibanaTilemapSource.title }, + { label: 'Tilemap url', value: this.getUrlTemplate() }, + ]; } _createDefaultLayerDescriptor(options) { diff --git a/x-pack/plugins/gis/public/shared/layers/sources/source.js b/x-pack/plugins/gis/public/shared/layers/sources/source.js index 3dd206ffb1e8a..576d867ae7bc4 100644 --- a/x-pack/plugins/gis/public/shared/layers/sources/source.js +++ b/x-pack/plugins/gis/public/shared/layers/sources/source.js @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; - export class AbstractSource { static renderEditor() { @@ -26,8 +24,12 @@ export class AbstractSource { destroy() {} - renderDetails() { - return (
{`Here be details for source`}
); + /** + * return list of immutable source properties. + * Immutable source properties are properties that can not be edited by the user. + */ + async getImmutableProperties() { + return []; } _createDefaultLayerDescriptor() { diff --git a/x-pack/plugins/gis/public/shared/layers/sources/wms_source.js b/x-pack/plugins/gis/public/shared/layers/sources/wms_source.js index f8ef5c7c5851c..6dcfaef921669 100644 --- a/x-pack/plugins/gis/public/shared/layers/sources/wms_source.js +++ b/x-pack/plugins/gis/public/shared/layers/sources/wms_source.js @@ -8,7 +8,6 @@ import React, { Fragment } from 'react'; import { EuiFieldText, - EuiText, EuiFormRow, } from '@elastic/eui'; @@ -20,6 +19,7 @@ export class WMSSource extends AbstractTMSSource { static type = 'WMS'; static title = 'Web Map Service'; static description = 'Maps from OGC Standard WMS'; + static icon = 'grid'; static createDescriptor({ serviceUrl, layers, styles }) { return { @@ -39,20 +39,13 @@ export class WMSSource extends AbstractTMSSource { return (); } - renderDetails() { - return ( - -

- Type WMSSource.typeDisplayName
- Service - {this._descriptor.serviceUrl}
- Layers - {this._descriptor.layers}
- Styles - {this._descriptor.styles}
-

-
- ); + async getImmutableProperties() { + return [ + { label: 'Data source', value: WMSSource.title }, + { label: 'Url', value: this._descriptor.serviceUrl }, + { label: 'Layers', value: this._descriptor.layers }, + { label: 'Styles', value: this._descriptor.styles }, + ]; } _createDefaultLayerDescriptor(options) { diff --git a/x-pack/plugins/gis/public/shared/layers/sources/xyz_tms_source.js b/x-pack/plugins/gis/public/shared/layers/sources/xyz_tms_source.js index 602e3fb4eb960..b5bce0d868000 100644 --- a/x-pack/plugins/gis/public/shared/layers/sources/xyz_tms_source.js +++ b/x-pack/plugins/gis/public/shared/layers/sources/xyz_tms_source.js @@ -8,7 +8,6 @@ import React from 'react'; import { EuiFieldText, - EuiText, EuiFormRow, } from '@elastic/eui'; @@ -20,6 +19,7 @@ export class XYZTMSSource extends AbstractTMSSource { static type = 'EMS_XYZ'; static title = 'Tile Map Service from URL'; static description = 'Map tiles from a URL that includes the XYZ coordinates'; + static icon = 'grid'; static createDescriptor(urlTemplate) { return { @@ -37,16 +37,11 @@ export class XYZTMSSource extends AbstractTMSSource { return (); } - renderDetails() { - return ( - -

- Type Tile
- Url - {this._descriptor.urlTemplate}
-

-
- ); + async getImmutableProperties() { + return [ + { label: 'Data source', value: XYZTMSSource.title }, + { label: 'Url', value: this._descriptor.urlTemplate }, + ]; } _createDefaultLayerDescriptor(options) {