mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[Maps] split settings into layer and source panels (#33788)
* [Maps] split settings into layer and source panels * fix SCSS import
This commit is contained in:
parent
2f9ad0a814
commit
e247609e8b
15 changed files with 317 additions and 54 deletions
|
@ -82,10 +82,9 @@ exports[`LayerPanel is rendered 1`] = `
|
|||
<EuiFlyoutBody
|
||||
className="mapLayerPanel__body"
|
||||
>
|
||||
<SettingsPanel />
|
||||
<EuiSpacer
|
||||
size="s"
|
||||
/>
|
||||
<LayerErrors />
|
||||
<LayerSettings />
|
||||
<SourceSettings />
|
||||
<EuiPanel
|
||||
grow={true}
|
||||
hasShadow={false}
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
@import './layer_panel';
|
||||
@import './join_editor/resources/join';
|
||||
@import './settings_panel/settings_panel';
|
||||
@import './layer_settings/layer_settings';
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Should render errors when layer has errors 1`] = `
|
||||
<Fragment>
|
||||
<EuiCallOut
|
||||
color="warning"
|
||||
size="m"
|
||||
title="Unable to load layer"
|
||||
>
|
||||
<p
|
||||
data-test-subj="layerErrorMessage"
|
||||
>
|
||||
simulated layer error
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
<EuiSpacer
|
||||
margin="m"
|
||||
/>
|
||||
</Fragment>
|
||||
`;
|
||||
|
||||
exports[`should render nothing when layer has no errors 1`] = `""`;
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* 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 { connect } from 'react-redux';
|
||||
import { LayerErrors } from './layer_errors';
|
||||
import { getSelectedLayer } from '../../../selectors/map_selectors';
|
||||
|
||||
function mapStateToProps(state = {}) {
|
||||
return {
|
||||
layer: getSelectedLayer(state)
|
||||
};
|
||||
}
|
||||
|
||||
const connectedLayerErrors = connect(mapStateToProps, null)(LayerErrors);
|
||||
export { connectedLayerErrors as LayerErrors };
|
|
@ -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, { Fragment } from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import {
|
||||
EuiCallOut,
|
||||
EuiSpacer,
|
||||
} from '@elastic/eui';
|
||||
|
||||
export function LayerErrors({ layer }) {
|
||||
|
||||
if (!layer.hasErrors()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<EuiCallOut
|
||||
color="warning"
|
||||
title={
|
||||
i18n.translate('xpack.maps.layerPanel.settingsPanel.unableToLoadTitle', {
|
||||
defaultMessage: 'Unable to load layer'
|
||||
})
|
||||
}
|
||||
>
|
||||
<p data-test-subj="layerErrorMessage">
|
||||
{layer.getErrors()}
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
<EuiSpacer margin="m"/>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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 { LayerErrors } from './layer_errors';
|
||||
|
||||
test('Should render errors when layer has errors', () => {
|
||||
const mockLayer = {
|
||||
hasErrors: () => { return true; },
|
||||
getErrors: () => { return 'simulated layer error'; }
|
||||
};
|
||||
const component = shallow(
|
||||
<LayerErrors
|
||||
layer={mockLayer}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(component)
|
||||
.toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should render nothing when layer has no errors', () => {
|
||||
const mockLayer = {
|
||||
hasErrors: () => { return false; },
|
||||
};
|
||||
const component = shallow(
|
||||
<LayerErrors
|
||||
layer={mockLayer}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(component)
|
||||
.toMatchSnapshot();
|
||||
});
|
|
@ -5,14 +5,13 @@
|
|||
*/
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
import { SettingsPanel } from './settings_panel';
|
||||
import { LayerSettings } from './layer_settings';
|
||||
import { getSelectedLayer } from '../../../selectors/map_selectors';
|
||||
import {
|
||||
updateLayerLabel,
|
||||
updateLayerMaxZoom,
|
||||
updateLayerMinZoom,
|
||||
updateLayerAlpha,
|
||||
updateSourceProp,
|
||||
} from '../../../actions/store_actions';
|
||||
|
||||
function mapStateToProps(state = {}) {
|
||||
|
@ -33,9 +32,8 @@ function mapDispatchToProps(dispatch) {
|
|||
updateMinZoom: (id, minZoom) => dispatch(updateLayerMinZoom(id, minZoom)),
|
||||
updateMaxZoom: (id, maxZoom) => dispatch(updateLayerMaxZoom(id, maxZoom)),
|
||||
updateAlpha: (id, alpha) => dispatch(updateLayerAlpha(id, alpha)),
|
||||
updateSourceProp: (id, propName, value) => dispatch(updateSourceProp(id, propName, value)),
|
||||
};
|
||||
}
|
||||
|
||||
const connectedSettingsPanel = connect(mapStateToProps, mapDispatchToProps)(SettingsPanel);
|
||||
export { connectedSettingsPanel as SettingsPanel };
|
||||
const connectedLayerSettings = connect(mapStateToProps, mapDispatchToProps)(LayerSettings);
|
||||
export { connectedLayerSettings as LayerSettings };
|
|
@ -14,7 +14,6 @@ import {
|
|||
EuiFormRow,
|
||||
EuiFieldText,
|
||||
EuiSpacer,
|
||||
EuiCallOut
|
||||
} from '@elastic/eui';
|
||||
|
||||
import { ValidatedRange } from '../../../shared/components/validated_range';
|
||||
|
@ -25,7 +24,7 @@ import { ValidatedDualRange } from 'ui/validated_range';
|
|||
const MIN_ZOOM = 0;
|
||||
const MAX_ZOOM = 24;
|
||||
|
||||
export function SettingsPanel(props) {
|
||||
export function LayerSettings(props) {
|
||||
|
||||
const onLabelChange = (event) => {
|
||||
const label = event.target.value;
|
||||
|
@ -41,34 +40,6 @@ export function SettingsPanel(props) {
|
|||
props.updateAlpha(props.layerId, alpha);
|
||||
};
|
||||
|
||||
const onSourceChange = ({ propName, value }) => {
|
||||
props.updateSourceProp(props.layerId, propName, value);
|
||||
};
|
||||
|
||||
const renderLayerErrors = () => {
|
||||
if (!props.layer.hasErrors()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<EuiCallOut
|
||||
color="warning"
|
||||
title={
|
||||
i18n.translate('xpack.maps.layerPanel.settingsPanel.unableToLoadTitle', {
|
||||
defaultMessage: 'Unable to load layer'
|
||||
})
|
||||
}
|
||||
>
|
||||
<p data-test-subj="layerErrorMessage">
|
||||
{props.layer.getErrors()}
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
<EuiSpacer margin="m"/>
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
const renderZoomSliders = () => {
|
||||
return (
|
||||
<EuiFormRow
|
||||
|
@ -146,17 +117,14 @@ export function SettingsPanel(props) {
|
|||
|
||||
return (
|
||||
<Fragment>
|
||||
|
||||
{renderLayerErrors()}
|
||||
|
||||
<EuiPanel>
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem>
|
||||
<EuiTitle size="xs">
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
id="xpack.maps.layerPanel.settingsPanel.settingsTitle"
|
||||
defaultMessage="Settings"
|
||||
id="xpack.maps.layerPanel.layerSettingsTitle"
|
||||
defaultMessage="Layer Settings"
|
||||
/>
|
||||
</h5>
|
||||
</EuiTitle>
|
||||
|
@ -170,9 +138,9 @@ export function SettingsPanel(props) {
|
|||
{renderZoomSliders()}
|
||||
|
||||
{renderAlphaSlider()}
|
||||
|
||||
{props.layer.renderSourceSettingsEditor({ onChange: onSourceChange })}
|
||||
</EuiPanel>
|
||||
|
||||
<EuiSpacer size="s" />
|
||||
</Fragment>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Should render source settings editor 1`] = `
|
||||
<Fragment>
|
||||
<EuiPanel
|
||||
grow={true}
|
||||
hasShadow={false}
|
||||
paddingSize="m"
|
||||
>
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem>
|
||||
<EuiTitle
|
||||
size="xs"
|
||||
textTransform="none"
|
||||
>
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
defaultMessage="Source Settings"
|
||||
id="xpack.maps.layerPanel.sourceSettingsTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h5>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<EuiSpacer
|
||||
margin="m"
|
||||
/>
|
||||
<div>
|
||||
mockSourceEditor
|
||||
</div>
|
||||
</EuiPanel>
|
||||
<EuiSpacer
|
||||
size="s"
|
||||
/>
|
||||
</Fragment>
|
||||
`;
|
||||
|
||||
exports[`should render nothing when source has no editor 1`] = `""`;
|
|
@ -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;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
import { SourceSettings } from './source_settings';
|
||||
import { getSelectedLayer } from '../../../selectors/map_selectors';
|
||||
import { updateSourceProp } from '../../../actions/store_actions';
|
||||
|
||||
function mapStateToProps(state = {}) {
|
||||
return {
|
||||
layer: getSelectedLayer(state)
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return {
|
||||
updateSourceProp: (id, propName, value) => dispatch(updateSourceProp(id, propName, value)),
|
||||
};
|
||||
}
|
||||
|
||||
const connectedSourceSettings = connect(mapStateToProps, mapDispatchToProps)(SourceSettings);
|
||||
export { connectedSourceSettings as SourceSettings };
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* 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 {
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiTitle,
|
||||
EuiPanel,
|
||||
EuiSpacer,
|
||||
} from '@elastic/eui';
|
||||
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
export function SourceSettings({ layer, updateSourceProp }) {
|
||||
|
||||
const onSourceChange = ({ propName, value }) => {
|
||||
updateSourceProp(layer.getId(), propName, value);
|
||||
};
|
||||
|
||||
const sourceSettingsEditor = layer.renderSourceSettingsEditor({ onChange: onSourceChange });
|
||||
|
||||
if (!sourceSettingsEditor) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<EuiPanel>
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem>
|
||||
<EuiTitle size="xs">
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
id="xpack.maps.layerPanel.sourceSettingsTitle"
|
||||
defaultMessage="Source Settings"
|
||||
/>
|
||||
</h5>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
||||
<EuiSpacer margin="m"/>
|
||||
|
||||
{sourceSettingsEditor}
|
||||
</EuiPanel>
|
||||
|
||||
<EuiSpacer size="s" />
|
||||
</Fragment>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* 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 { SourceSettings } from './source_settings';
|
||||
|
||||
test('Should render source settings editor', () => {
|
||||
const mockLayer = {
|
||||
renderSourceSettingsEditor: () => {
|
||||
return (<div>mockSourceEditor</div>);
|
||||
},
|
||||
};
|
||||
const component = shallow(
|
||||
<SourceSettings
|
||||
layer={mockLayer}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(component)
|
||||
.toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should render nothing when source has no editor', () => {
|
||||
const mockLayer = {
|
||||
renderSourceSettingsEditor: () => {
|
||||
return null;
|
||||
},
|
||||
};
|
||||
const component = shallow(
|
||||
<SourceSettings
|
||||
layer={mockLayer}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(component)
|
||||
.toMatchSnapshot();
|
||||
});
|
|
@ -9,7 +9,9 @@ import React, { Fragment } from 'react';
|
|||
import { StyleTabs } from './style_tabs';
|
||||
import { JoinEditor } from './join_editor';
|
||||
import { FlyoutFooter } from './flyout_footer';
|
||||
import { SettingsPanel } from './settings_panel';
|
||||
import { LayerErrors } from './layer_errors';
|
||||
import { LayerSettings } from './layer_settings';
|
||||
import { SourceSettings } from './source_settings';
|
||||
import {
|
||||
EuiButtonIcon,
|
||||
EuiFlexItem,
|
||||
|
@ -175,10 +177,17 @@ export class LayerPanel extends React.Component {
|
|||
</EuiFlyoutHeader>
|
||||
|
||||
<EuiFlyoutBody className="mapLayerPanel__body">
|
||||
<SettingsPanel/>
|
||||
<EuiSpacer size="s" />
|
||||
|
||||
<LayerErrors/>
|
||||
|
||||
<LayerSettings/>
|
||||
|
||||
<SourceSettings/>
|
||||
|
||||
{this._renderJoinSection()}
|
||||
|
||||
<StyleTabs layer={selectedLayer}/>
|
||||
|
||||
</EuiFlyoutBody>
|
||||
|
||||
<EuiFlyoutFooter className="mapLayerPanel__footer">
|
||||
|
|
|
@ -22,9 +22,21 @@ jest.mock('./flyout_footer', () => ({
|
|||
}
|
||||
}));
|
||||
|
||||
jest.mock('./settings_panel', () => ({
|
||||
SettingsPanel: () => {
|
||||
return (<div>mockSettingsPanel</div>);
|
||||
jest.mock('./layer_errors', () => ({
|
||||
LayerErrors: () => {
|
||||
return (<div>mockLayerErrors</div>);
|
||||
}
|
||||
}));
|
||||
|
||||
jest.mock('./layer_settings', () => ({
|
||||
LayerSettings: () => {
|
||||
return (<div>mockLayerSettings</div>);
|
||||
}
|
||||
}));
|
||||
|
||||
jest.mock('./source_settings', () => ({
|
||||
SourceSettings: () => {
|
||||
return (<div>mockSourceSettings</div>);
|
||||
}
|
||||
}));
|
||||
|
||||
|
@ -42,7 +54,7 @@ const mockLayer = {
|
|||
];
|
||||
},
|
||||
isJoinable: () => { return true; },
|
||||
getLayerTypeIconName: () => { return 'vector'; }
|
||||
getLayerTypeIconName: () => { return 'vector'; },
|
||||
};
|
||||
|
||||
const defaultProps = {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue