Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Lens] Update frame to put suggestions at the bottom #42997

Merged
merged 9 commits into from
Aug 9, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ export function ChartSwitch(props: Props) {
>
(
{i18n.translate('xpack.lens.configPanel.changeVisualization', {
defaultMessage: 'Change',
defaultMessage: 'change',
})}
)
</EuiButtonEmpty>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
DatasourceMock,
} from '../mocks';
import { ExpressionRenderer } from 'src/legacy/core_plugins/data/public';
import { EuiPanel, EuiToolTip } from '@elastic/eui';

// calling this function will wait for all pending Promises from mock
// datasources to be processed by its callers.
Expand Down Expand Up @@ -1119,13 +1120,12 @@ describe('editor_frame', () => {

// TODO why is this necessary?
instance.update();
const suggestions = instance.find('[data-test-subj="suggestion-title"]');
expect(suggestions.map(el => el.text())).toEqual([
'Suggestion1',
'Suggestion2',
'Suggestion3',
'Suggestion4',
]);
expect(
instance
.find('[data-test-subj="lnsSuggestion"]')
.find(EuiPanel)
.map(el => el.parents(EuiToolTip).prop('content'))
).toEqual(['Suggestion1', 'Suggestion2', 'Suggestion3', 'Suggestion4']);
});

it('should switch to suggested visualization', async () => {
Expand Down Expand Up @@ -1167,7 +1167,10 @@ describe('editor_frame', () => {
instance.update();

act(() => {
instance.find('[data-test-subj="suggestion-title"]').simulate('click');
instance
.find('[data-test-subj="lnsSuggestion"]')
.first()
.simulate('click');
});

expect(mockVisualization.renderConfigPanel).toHaveBeenCalledTimes(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ export function FrameLayout(props: FrameLayoutProps) {
<EuiPageSideBar className="lnsSidebar">{props.dataPanel}</EuiPageSideBar>
<EuiPageBody className="lnsPageBody" restrictWidth={false}>
{props.workspacePanel}
{props.suggestionsPanel}
</EuiPageBody>
<EuiPageSideBar className="lnsSidebar lnsSidebar--right">
{props.configPanel}
{props.suggestionsPanel}
</EuiPageSideBar>
</div>
</EuiPage>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
$lnsPanelMinWidth: $euiSize * 18;

.lnsPage {
padding: 0;
Expand All @@ -24,7 +25,7 @@
.lnsSidebar {
margin: 0;
flex: 1 0 18%;
min-width: ($euiSize * 22);
min-width: $lnsPanelMinWidth + $euiSize;
display: flex;
flex-direction: column;
position: relative;
Expand All @@ -45,10 +46,13 @@
}

.lnsSidebar--right {
min-width: ($euiSize * 22);
@include euiScrollBar;
overflow: hidden auto;
padding: $euiSize;
min-width: $lnsPanelMinWidth + $euiSize;
overflow-x: hidden;
overflow-y: auto;
padding-top: $euiSize;
padding-right: $euiSize;
max-height: 100%;
}

.lnsSidebarContainer {
Expand All @@ -64,31 +68,37 @@

.lnsPageBody {
@include euiScrollBar;
padding-top: $euiSize;
padding-bottom: $euiSize;
overflow: hidden auto;
min-width: $lnsPanelMinWidth + $euiSizeXL;
overflow: hidden;
// Leave out bottom padding so the suggestions scrollbar stays flush to window edge
// This also means needing to add same amount of margin to page content and suggestion items
padding: $euiSize $euiSize 0;

&:first-child {
padding-left: $euiSize;
}

.lnsPageContent {
@include euiScrollBar;
overflow: hidden;
padding: 0;
margin-bottom: $euiSize;
display: flex;
flex-direction: column;

.lnsPageContentHeader {
padding: $euiSize;
padding: $euiSizeS;
border-bottom: $euiBorderThin;
margin-bottom: 0;
}

.lnsPageContentBody {
@include euiScrollBar;
flex-grow: 1;
padding: $euiSizeXL;
display: flex;
align-items: stretch;
justify-content: stretch;
overflow: auto;

> * {
flex: 1 1 100%;
Expand All @@ -108,6 +118,7 @@
align-items: center;
justify-content: center;
overflow-x: hidden;
padding: $euiSize;
}

.lnsTitleInput {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,59 @@
.lnsSidebar__suggestions {
> * {
margin-top: $euiSizeS;
// SASSTODO: Create this in EUI
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is nice. Made an issue so we remember.

elastic/eui#2215

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TY!

@mixin lnsOverflowShadowHorizontal {
$hideHeight: $euiScrollBarCorner * 1.25;
mask-image: linear-gradient(to right,
transparentize(red, .9) 0%,
transparentize(red, 0) $hideHeight,
transparentize(red, 0) calc(100% - #{$hideHeight}),
transparentize(red, .9) 100%
);
}

.lnsSuggestionsPanel__title {
margin: $euiSizeS 0 $euiSizeXS;
}

.lnsSuggestionsPanel__suggestions {
@include euiScrollBar;
@include lnsOverflowShadowHorizontal;
padding-top: $euiSizeXS;
overflow-x: auto;
overflow-y: hidden;
display: flex;

// Padding / negative margins to make room for overflow shadow
padding-left: $euiSizeXS;
margin-left: -$euiSizeXS;

// Add margin to the next of the same type
> * + * {
margin-left: $euiSizeS;
}
}

$suggestionHeight: 120px;
// These sizes also match canvas' page thumbnails for consistency
$lnsSuggestionHeight: 100px;
$lnsSuggestionWidth: 150px;

.lnsSuggestionPanel__button {
flex: 0 0 auto;
width: $lnsSuggestionWidth !important;
height: $lnsSuggestionHeight;
// Allows the scrollbar to stay flush to window
margin-bottom: $euiSize;
}

.lnsSidebar__suggestionIcon {
color: $euiColorDarkShade;
width: 100%;
height: $suggestionHeight;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
padding: $euiSize;
padding: $euiSizeS;
}

.lnsSuggestionChartWrapper {
height: $suggestionHeight;
pointer-events: none;
}
.lnsSuggestionChartWrapper {
height: $lnsSuggestionHeight - $euiSize;
pointer-events: none;
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { ExpressionRenderer } from 'src/legacy/core_plugins/data/public';
import { SuggestionPanel, SuggestionPanelProps } from './suggestion_panel';
import { getSuggestions, Suggestion } from './suggestion_helpers';
import { fromExpression } from '@kbn/interpreter/target/common';
import { EuiIcon } from '@elastic/eui';
import { EuiIcon, EuiPanel, EuiToolTip } from '@elastic/eui';

jest.mock('./suggestion_helpers');

Expand Down Expand Up @@ -82,17 +82,19 @@ describe('suggestion_panel', () => {
it('should list passed in suggestions', () => {
const wrapper = mount(<SuggestionPanel {...defaultProps} />);

expect(wrapper.find('[data-test-subj="suggestion-title"]').map(el => el.text())).toEqual([
'Suggestion1',
'Suggestion2',
]);
expect(
wrapper
.find('[data-test-subj="lnsSuggestion"]')
.find(EuiPanel)
.map(el => el.parents(EuiToolTip).prop('content'))
).toEqual(['Suggestion1', 'Suggestion2']);
});

it('should dispatch visualization switch action if suggestion is clicked', () => {
const wrapper = mount(<SuggestionPanel {...defaultProps} />);

wrapper
.find('[data-test-subj="suggestion-title"]')
.find('[data-test-subj="lnsSuggestion"]')
.first()
.simulate('click');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import React, { useState, useEffect } from 'react';
import { FormattedMessage } from '@kbn/i18n/react';
import { EuiIcon, EuiTitle, EuiPanel, EuiIconTip } from '@elastic/eui';
import { EuiIcon, EuiTitle, EuiPanel, EuiIconTip, EuiToolTip } from '@elastic/eui';
import { toExpression } from '@kbn/interpreter/common';
import { i18n } from '@kbn/i18n';
import { Action } from './state_management';
Expand Down Expand Up @@ -51,46 +51,46 @@ const SuggestionPreview = ({
}, [previewExpression]);

return (
<EuiPanel
paddingSize="s"
data-test-subj="suggestion"
onClick={() => {
dispatch(toSwitchAction(suggestion));
}}
>
<EuiTitle size="xxxs">
<h4 data-test-subj="suggestion-title">{suggestion.title}</h4>
</EuiTitle>
{expressionError ? (
<div className="lnsSidebar__suggestionIcon">
<EuiIconTip
size="xxl"
color="danger"
type="cross"
aria-label={i18n.translate('xpack.lens.editorFrame.previewErrorLabel', {
defaultMessage: 'Preview rendering failed',
})}
content={i18n.translate('xpack.lens.editorFrame.previewErrorTooltip', {
defaultMessage: 'Preview rendering failed',
})}
<EuiToolTip content={suggestion.title}>
<EuiPanel
className="lnsSuggestionPanel__button"
paddingSize="none"
data-test-subj="lnsSuggestion"
onClick={() => {
dispatch(toSwitchAction(suggestion));
}}
>
{expressionError ? (
<div className="lnsSidebar__suggestionIcon">
<EuiIconTip
size="xxl"
color="danger"
type="cross"
aria-label={i18n.translate('xpack.lens.editorFrame.previewErrorLabel', {
defaultMessage: 'Preview rendering failed',
})}
content={i18n.translate('xpack.lens.editorFrame.previewErrorTooltip', {
defaultMessage: 'Preview rendering failed',
})}
/>
</div>
) : previewExpression ? (
<ExpressionRendererComponent
className="lnsSuggestionChartWrapper"
expression={previewExpression}
onRenderFailure={(e: unknown) => {
// eslint-disable-next-line no-console
console.error(`Failed to render preview: `, e);
setExpressionError(true);
}}
/>
</div>
) : previewExpression ? (
<ExpressionRendererComponent
className="lnsSuggestionChartWrapper"
expression={previewExpression}
onRenderFailure={(e: unknown) => {
// eslint-disable-next-line no-console
console.error(`Failed to render preview: `, e);
setExpressionError(true);
}}
/>
) : (
<div className="lnsSidebar__suggestionIcon">
<EuiIcon size="xxl" color="subdued " type={suggestion.previewIcon} />
</div>
)}
</EuiPanel>
) : (
<div className="lnsSidebar__suggestionIcon">
<EuiIcon size="xxl" type={suggestion.previewIcon} />
</div>
)}
</EuiPanel>
</EuiToolTip>
);
};

Expand Down Expand Up @@ -125,33 +125,35 @@ function InnerSuggestionPanel({
}

return (
<div className="lnsSidebar__suggestions">
<EuiTitle size="xs">
<div className="lnsSuggestionsPanel">
<EuiTitle className="lnsSuggestionsPanel__title" size="xxs">
<h3>
<FormattedMessage
id="xpack.lens.editorFrame.suggestionPanelTitle"
defaultMessage="Suggestions"
/>
</h3>
</EuiTitle>
{suggestions.map(suggestion => {
const previewExpression = suggestion.previewExpression
? prependDatasourceExpression(
suggestion.previewExpression,
datasourceMap,
datasourceStates
)
: null;
return (
<SuggestionPreview
suggestion={suggestion}
dispatch={dispatch}
ExpressionRenderer={ExpressionRendererComponent}
previewExpression={previewExpression ? toExpression(previewExpression) : undefined}
key={`${suggestion.visualizationId}-${suggestion.title}`}
/>
);
})}
<div className="lnsSuggestionsPanel__suggestions">
{suggestions.map(suggestion => {
const previewExpression = suggestion.previewExpression
? prependDatasourceExpression(
suggestion.previewExpression,
datasourceMap,
datasourceStates
)
: null;
return (
<SuggestionPreview
suggestion={suggestion}
dispatch={dispatch}
ExpressionRenderer={ExpressionRendererComponent}
previewExpression={previewExpression ? toExpression(previewExpression) : undefined}
key={`${suggestion.visualizationId}-${suggestion.title}`}
/>
);
})}
</div>
</div>
);
}
Loading