Skip to content

Commit

Permalink
[Lens] Split apart config panel component to more manageable chunks (#…
Browse files Browse the repository at this point in the history
…63910)

* [Lens] Split apart config panel component to more manageable chunks

* Moving around and renaming SASS appropriately

* Remove layer limit

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
Co-authored-by: cchaos <caroline.horn@elastic.co>
  • Loading branch information
3 people authored Apr 22, 2020
1 parent f7ea9b9 commit dd094f2
Show file tree
Hide file tree
Showing 20 changed files with 832 additions and 723 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.lnsConfigPanel__addLayerBtn {
color: transparentize($euiColorMediumShade, .3);
// Remove EuiButton's default shadow to make button more subtle
// sass-lint:disable-block no-important
box-shadow: none !important;
border: 1px dashed currentColor;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.lnsDimensionPopover {
line-height: 0;
flex-grow: 1;
}

.lnsDimensionPopover__trigger {
max-width: 100%;
display: block;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@import 'chart_switch';
@import 'config_panel';
@import 'dimension_popover';
@import 'layer_panel';
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
.lnsConfigPanel__panel {
.lnsLayerPanel {
margin-bottom: $euiSizeS;
}

.lnsConfigPanel__row {
.lnsLayerPanel__row {
background: $euiColorLightestShade;
padding: $euiSizeS;
border-radius: $euiBorderRadius;
Expand All @@ -13,15 +13,7 @@
}
}

.lnsConfigPanel__addLayerBtn {
color: transparentize($euiColorMediumShade, .3);
// Remove EuiButton's default shadow to make button more subtle
// sass-lint:disable-block no-important
box-shadow: none !important;
border: 1px dashed currentColor;
}

.lnsConfigPanel__dimension {
.lnsLayerPanel__dimension {
@include euiFontSizeS;
background: lightOrDarkTheme($euiColorEmptyShade, $euiColorLightestShade);
border-radius: $euiBorderRadius;
Expand All @@ -31,20 +23,11 @@
overflow: hidden;
}

.lnsConfigPanel__trigger {
max-width: 100%;
display: block;
}

.lnsConfigPanel__triggerLink {
.lnsLayerPanel__triggerLink {
padding: $euiSizeS;
width: 100%;
display: flex;
align-items: center;
min-height: $euiSizeXXL;
}

.lnsConfigPanel__popover {
line-height: 0;
flex-grow: 1;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@
*/

import React from 'react';
import { createMockVisualization, createMockFramePublicAPI, createMockDatasource } from '../mocks';
import { mountWithIntl as mount } from 'test_utils/enzyme_helpers';
import { ReactWrapper } from 'enzyme';
import { ChartSwitch } from './chart_switch';
import { Visualization, FramePublicAPI, DatasourcePublicAPI } from '../../types';
import {
createMockVisualization,
createMockFramePublicAPI,
createMockDatasource,
} from '../../mocks';
import { EuiKeyPadMenuItem } from '@elastic/eui';
import { Action } from './state_management';
import { mountWithIntl as mount } from 'test_utils/enzyme_helpers';
import { Visualization, FramePublicAPI, DatasourcePublicAPI } from '../../../types';
import { Action } from '../state_management';
import { ChartSwitch } from './chart_switch';

describe('chart_switch', () => {
function generateVisualization(id: string): jest.Mocked<Visualization> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ import {
} from '@elastic/eui';
import { flatten } from 'lodash';
import { i18n } from '@kbn/i18n';
import { Visualization, FramePublicAPI, Datasource } from '../../types';
import { Action } from './state_management';
import { getSuggestions, switchToSuggestion, Suggestion } from './suggestion_helpers';
import { trackUiEvent } from '../../lens_ui_telemetry';
import { Visualization, FramePublicAPI, Datasource } from '../../../types';
import { Action } from '../state_management';
import { getSuggestions, switchToSuggestion, Suggestion } from '../suggestion_helpers';
import { trackUiEvent } from '../../../lens_ui_telemetry';

interface VisualizationSelection {
visualizationId: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
/*
* 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, { useMemo, memo } from 'react';
import { EuiFlexItem, EuiToolTip, EuiButton, EuiForm } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { Visualization } from '../../../types';
import { ChartSwitch } from './chart_switch';
import { LayerPanel } from './layer_panel';
import { trackUiEvent } from '../../../lens_ui_telemetry';
import { generateId } from '../../../id_generator';
import { removeLayer, appendLayer } from './layer_actions';
import { ConfigPanelWrapperProps } from './types';

export const ConfigPanelWrapper = memo(function ConfigPanelWrapper(props: ConfigPanelWrapperProps) {
const activeVisualization = props.visualizationMap[props.activeVisualizationId || ''];
const { visualizationState } = props;

return (
<>
<ChartSwitch
data-test-subj="lnsChartSwitcher"
visualizationMap={props.visualizationMap}
visualizationId={props.activeVisualizationId}
visualizationState={props.visualizationState}
datasourceMap={props.datasourceMap}
datasourceStates={props.datasourceStates}
dispatch={props.dispatch}
framePublicAPI={props.framePublicAPI}
/>
{activeVisualization && visualizationState && (
<LayerPanels {...props} activeVisualization={activeVisualization} />
)}
</>
);
});

function LayerPanels(
props: ConfigPanelWrapperProps & {
activeDatasourceId: string;
activeVisualization: Visualization;
}
) {
const {
framePublicAPI,
activeVisualization,
visualizationState,
dispatch,
activeDatasourceId,
datasourceMap,
} = props;
const setVisualizationState = useMemo(
() => (newState: unknown) => {
props.dispatch({
type: 'UPDATE_VISUALIZATION_STATE',
visualizationId: activeVisualization.id,
newState,
clearStagedPreview: false,
});
},
[props.dispatch, activeVisualization]
);
const updateDatasource = useMemo(
() => (datasourceId: string, newState: unknown) => {
props.dispatch({
type: 'UPDATE_DATASOURCE_STATE',
updater: () => newState,
datasourceId,
clearStagedPreview: false,
});
},
[props.dispatch]
);
const updateAll = useMemo(
() => (datasourceId: string, newDatasourceState: unknown, newVisualizationState: unknown) => {
props.dispatch({
type: 'UPDATE_STATE',
subType: 'UPDATE_ALL_STATES',
updater: prevState => {
return {
...prevState,
datasourceStates: {
...prevState.datasourceStates,
[datasourceId]: {
state: newDatasourceState,
isLoading: false,
},
},
visualization: {
...prevState.visualization,
state: newVisualizationState,
},
stagedPreview: undefined,
};
},
});
},
[props.dispatch]
);
const layerIds = activeVisualization.getLayerIds(visualizationState);

return (
<EuiForm className="lnsConfigPanel">
{layerIds.map(layerId => (
<LayerPanel
{...props}
key={layerId}
layerId={layerId}
activeVisualization={activeVisualization}
visualizationState={visualizationState}
updateVisualization={setVisualizationState}
updateDatasource={updateDatasource}
updateAll={updateAll}
frame={framePublicAPI}
isOnlyLayer={layerIds.length === 1}
onRemoveLayer={() => {
dispatch({
type: 'UPDATE_STATE',
subType: 'REMOVE_OR_CLEAR_LAYER',
updater: state =>
removeLayer({
activeVisualization,
layerId,
trackUiEvent,
datasourceMap,
state,
}),
});
}}
/>
))}
{activeVisualization.appendLayer && visualizationState && (
<EuiFlexItem grow={true}>
<EuiToolTip
className="eui-fullWidth"
content={i18n.translate('xpack.lens.xyChart.addLayerTooltip', {
defaultMessage:
'Use multiple layers to combine chart types or visualize different index patterns.',
})}
position="bottom"
>
<EuiButton
className="lnsConfigPanel__addLayerBtn"
fullWidth
size="s"
data-test-subj="lnsXY_layer_add"
aria-label={i18n.translate('xpack.lens.xyChart.addLayerButton', {
defaultMessage: 'Add layer',
})}
title={i18n.translate('xpack.lens.xyChart.addLayerButton', {
defaultMessage: 'Add layer',
})}
onClick={() => {
dispatch({
type: 'UPDATE_STATE',
subType: 'ADD_LAYER',
updater: state =>
appendLayer({
activeVisualization,
generateId,
trackUiEvent,
activeDatasource: datasourceMap[activeDatasourceId],
state,
}),
});
}}
iconType="plusInCircleFilled"
/>
</EuiToolTip>
</EuiFlexItem>
)}
</EuiForm>
);
}
Original file line number Diff line number Diff line change
@@ -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;
* you may not use this file except in compliance with the Elastic License.
*/

import React from 'react';
import { EuiPopover } from '@elastic/eui';
import { VisualizationDimensionGroupConfig } from '../../../types';
import { DimensionPopoverState } from './types';

export function DimensionPopover({
popoverState,
setPopoverState,
groups,
accessor,
groupId,
trigger,
panel,
}: {
popoverState: DimensionPopoverState;
setPopoverState: (newState: DimensionPopoverState) => void;
groups: VisualizationDimensionGroupConfig[];
accessor: string;
groupId: string;
trigger: React.ReactElement;
panel: React.ReactElement;
}) {
const noMatch = popoverState.isOpen ? !groups.some(d => d.accessors.includes(accessor)) : false;
return (
<EuiPopover
className="lnsDimensionPopover"
anchorClassName="lnsDimensionPopover__trigger"
isOpen={
popoverState.isOpen &&
(popoverState.openId === accessor || (noMatch && popoverState.addingToGroupId === groupId))
}
closePopover={() => {
setPopoverState({ isOpen: false, openId: null, addingToGroupId: null });
}}
button={trigger}
anchorPosition="leftUp"
withTitle
panelPaddingSize="s"
>
{panel}
</EuiPopover>
);
}
Original file line number Diff line number Diff line change
@@ -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 { ConfigPanelWrapper } from './config_panel';
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
*/

import _ from 'lodash';
import { EditorFrameState } from './state_management';
import { Datasource, Visualization } from '../../types';
import { EditorFrameState } from '../state_management';
import { Datasource, Visualization } from '../../../types';

interface RemoveLayerOptions {
trackUiEvent: (name: string) => void;
Expand Down
Loading

0 comments on commit dd094f2

Please sign in to comment.