[Lens] Show icons/titles instead of previews in suggestions panel (#166808)

## Summary

Use icons/titles for the suggestions panel instead of previews.

We decided to move forward with this for performance reasons. Some
suggestions can be very heavy and we have many sdhs from the customers
complaining about it. It is not obvious to them that the performance
problem is due to the suggestions.

<img width="1773" alt="image"
src="92816b82-b6a5-4f19-a436-52f41eae6a1a">

The FTs changes are mostly changes to the selectors.
This commit is contained in:
Stratoula Kalafateli 2023-10-03 13:51:36 +03:00 committed by GitHub
parent db009f19fc
commit 40deb13458
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 86 additions and 46 deletions

View file

@ -104,6 +104,13 @@ export class KibanaPage {
});
}
async waitForChartsSuggestions(count: number) {
await this.retry.waitFor(`rendering of ${count} suggestions is completed`, async () => {
const renderingItems = await this.page.$$('button[data-test-subj="lnsSuggestion"]');
return renderingItems.length === count;
});
}
async clearInput(locator: string) {
const textArea = this.page.locator(locator);
await textArea.clear();

View file

@ -26,6 +26,8 @@ export const journey = new Journey({
})
.step('Open existing Lens visualization', async ({ page, kibanaPage }) => {
await page.click(subj('visListingTitleLink-Lens-Stress-Test'));
await page.waitForSelector(subj('lnsChartSwitchPopover'));
await kibanaPage.waitForCharts({ count: 6, timeout: 60000 });
await kibanaPage.waitForCharts({ count: 1, timeout: 60000 });
await kibanaPage.waitForChartsSuggestions(6);
});

View file

@ -186,6 +186,7 @@ export function EditorFrame(props: EditorFrameProps) {
getUserMessages={props.getUserMessages}
nowProvider={props.plugins.data.nowProvider}
core={props.core}
showOnlyIcons
/>
</ErrorBoundary>
)

View file

@ -28,6 +28,7 @@
margin-right: $euiSizeS;
margin-left: $euiSizeXS / 2;
margin-bottom: $euiSizeXS / 2;
padding: 0 $euiSizeS;
box-shadow: none !important; // sass-lint:disable-line no-important
&:focus {

View file

@ -103,6 +103,7 @@ export interface SuggestionPanelProps {
getUserMessages: UserMessagesGetter;
nowProvider: DataPublicPluginStart['nowProvider'];
core: CoreStart;
showOnlyIcons?: boolean;
}
const PreviewRenderer = ({
@ -230,6 +231,7 @@ export function SuggestionPanel({
getUserMessages,
nowProvider,
core,
showOnlyIcons,
}: SuggestionPanelProps) {
const dispatchLens = useLensDispatch();
const activeDatasourceId = useLensSelector(selectActiveDatasourceId);
@ -437,7 +439,7 @@ export function SuggestionPanel({
<SuggestionPreview
preview={{
error: currentStateError,
expression: currentStateExpression,
expression: !showOnlyIcons ? currentStateExpression : undefined,
icon:
visualizationMap[currentVisualization.activeId].getDescription(
currentVisualization.state
@ -458,7 +460,7 @@ export function SuggestionPanel({
return (
<SuggestionPreview
preview={{
expression: suggestion.previewExpression,
expression: !showOnlyIcons ? suggestion.previewExpression : undefined,
icon: suggestion.previewIcon,
title: suggestion.title,
}}
@ -474,6 +476,7 @@ export function SuggestionPanel({
}}
selected={index === lastSelectedSuggestion}
onRender={() => onSuggestionRender(index + 1)}
showTitleAsLabel={showOnlyIcons}
/>
);
})}

View file

@ -980,7 +980,7 @@ describe('xy_suggestions', () => {
],
});
expect(seriesSuggestion.title).toEqual('Line chart');
expect(stackSuggestion.title).toEqual('Stacked');
expect(stackSuggestion.title).toEqual('Bar vertical stacked');
});
test('suggests a flipped chart for unchanged table and existing bar chart on ordinal x axis', () => {
@ -1053,7 +1053,7 @@ describe('xy_suggestions', () => {
const visibleSuggestions = suggestions.filter((suggestion) => !suggestion.hide);
expect(visibleSuggestions).toContainEqual(
expect.objectContaining({
title: 'Stacked',
title: 'Bar vertical stacked',
state: expect.objectContaining({ preferredSeriesType: 'bar_stacked' }),
})
);

View file

@ -295,30 +295,19 @@ function getSuggestionsForLayer({
buildSuggestion({
...options,
seriesType: newSeriesType,
title: newSeriesType.startsWith('bar')
? i18n.translate('xpack.lens.xySuggestions.barChartTitle', {
defaultMessage: 'Bar chart',
})
: i18n.translate('xpack.lens.xySuggestions.lineChartTitle', {
defaultMessage: 'Line chart',
}),
title: seriesTypeLabels(newSeriesType),
})
);
}
if (seriesType !== 'line' && splitBy && !seriesType.includes('percentage')) {
// flip between stacked/unstacked
const suggestedSeriesType = toggleStackSeriesType(seriesType);
sameStateSuggestions.push(
buildSuggestion({
...options,
seriesType: toggleStackSeriesType(seriesType),
title: seriesType.endsWith('stacked')
? i18n.translate('xpack.lens.xySuggestions.unstackedChartTitle', {
defaultMessage: 'Unstacked',
})
: i18n.translate('xpack.lens.xySuggestions.stackedChartTitle', {
defaultMessage: 'Stacked',
}),
seriesType: suggestedSeriesType,
title: seriesTypeLabels(suggestedSeriesType),
})
);
}
@ -333,16 +322,15 @@ function getSuggestionsForLayer({
percentageOptions.splitBy = percentageOptions.xValue;
delete percentageOptions.xValue;
}
const suggestedSeriesType = asPercentageSeriesType(seriesType);
// percentage suggestion
sameStateSuggestions.push(
buildSuggestion({
...options,
// hide the suggestion if split by is missing
hide: !percentageOptions.splitBy,
seriesType: asPercentageSeriesType(seriesType),
title: i18n.translate('xpack.lens.xySuggestions.asPercentageTitle', {
defaultMessage: 'Percentage',
}),
seriesType: suggestedSeriesType,
title: seriesTypeLabels(suggestedSeriesType),
})
);
}
@ -364,6 +352,53 @@ function getSuggestionsForLayer({
);
}
function seriesTypeLabels(seriesType: SeriesType) {
switch (seriesType) {
case 'line':
return i18n.translate('xpack.lens.xySuggestions.lineChartTitle', {
defaultMessage: 'Line chart',
});
case 'area':
return i18n.translate('xpack.lens.xySuggestions.areaChartTitle', {
defaultMessage: 'Area chart',
});
case 'area_stacked':
return i18n.translate('xpack.lens.xySuggestions.areaStackedChartTitle', {
defaultMessage: 'Area stacked',
});
case 'area_percentage_stacked':
return i18n.translate('xpack.lens.xySuggestions.areaPercentageStackedChartTitle', {
defaultMessage: 'Area percentage',
});
case 'bar':
return i18n.translate('xpack.lens.xySuggestions.verticalBarChartTitle', {
defaultMessage: 'Bar vertical',
});
case 'bar_horizontal':
return i18n.translate('xpack.lens.xySuggestions.horizontalBarChartTitle', {
defaultMessage: 'Bar horizontal',
});
case 'bar_stacked':
return i18n.translate('xpack.lens.xySuggestions.verticalBarStackedChartTitle', {
defaultMessage: 'Bar vertical stacked',
});
case 'bar_horizontal_stacked':
return i18n.translate('xpack.lens.xySuggestions.horizontalBarStackedChartTitle', {
defaultMessage: 'Bar horizontal stacked',
});
case 'bar_percentage_stacked':
return i18n.translate('xpack.lens.xySuggestions.verticalBarPercentageChartTitle', {
defaultMessage: 'Bar percentage',
});
case 'bar_horizontal_percentage_stacked':
return i18n.translate('xpack.lens.xySuggestions.horizontalBarPercentageChartTitle', {
defaultMessage: 'Bar horizontal percentage',
});
default:
return seriesType;
}
}
function toggleStackSeriesType(oldSeriesType: SeriesType) {
switch (oldSeriesType) {
case 'area':

View file

@ -21420,13 +21420,9 @@
"xpack.lens.xyChart.verticalAxisLabel": "Axe vertical",
"xpack.lens.xyChart.verticalLeftAxisLabel": "Axe gauche vertical",
"xpack.lens.xyChart.verticalRightAxisLabel": "Axe droit vertical",
"xpack.lens.xySuggestions.asPercentageTitle": "Pourcentage",
"xpack.lens.xySuggestions.barChartTitle": "Graphique à barres",
"xpack.lens.xySuggestions.emptyAxisTitle": "(vide)",
"xpack.lens.xySuggestions.flipTitle": "Retourner",
"xpack.lens.xySuggestions.lineChartTitle": "Graphique en courbes",
"xpack.lens.xySuggestions.stackedChartTitle": "Empilé",
"xpack.lens.xySuggestions.unstackedChartTitle": "Non empilé",
"xpack.lens.xySuggestions.yAxixConjunctionSign": " & ",
"xpack.lens.xyVisualization.areaLabel": "Aire",
"xpack.lens.xyVisualization.barGroupLabel": "Barres",

View file

@ -21435,13 +21435,9 @@
"xpack.lens.xyChart.verticalAxisLabel": "縦軸",
"xpack.lens.xyChart.verticalLeftAxisLabel": "縦左軸",
"xpack.lens.xyChart.verticalRightAxisLabel": "縦右軸",
"xpack.lens.xySuggestions.asPercentageTitle": "割合(%",
"xpack.lens.xySuggestions.barChartTitle": "棒グラフ",
"xpack.lens.xySuggestions.emptyAxisTitle": "(空)",
"xpack.lens.xySuggestions.flipTitle": "反転",
"xpack.lens.xySuggestions.lineChartTitle": "折れ線グラフ",
"xpack.lens.xySuggestions.stackedChartTitle": "スタック",
"xpack.lens.xySuggestions.unstackedChartTitle": "スタックが解除されました",
"xpack.lens.xySuggestions.yAxixConjunctionSign": " & ",
"xpack.lens.xyVisualization.areaLabel": "エリア",
"xpack.lens.xyVisualization.barGroupLabel": "棒",

View file

@ -21435,13 +21435,9 @@
"xpack.lens.xyChart.verticalAxisLabel": "垂直轴",
"xpack.lens.xyChart.verticalLeftAxisLabel": "垂直左轴",
"xpack.lens.xyChart.verticalRightAxisLabel": "垂直右轴",
"xpack.lens.xySuggestions.asPercentageTitle": "百分比",
"xpack.lens.xySuggestions.barChartTitle": "条形图",
"xpack.lens.xySuggestions.emptyAxisTitle": "(空)",
"xpack.lens.xySuggestions.flipTitle": "翻转",
"xpack.lens.xySuggestions.lineChartTitle": "折线图",
"xpack.lens.xySuggestions.stackedChartTitle": "堆叠",
"xpack.lens.xySuggestions.unstackedChartTitle": "非堆叠",
"xpack.lens.xySuggestions.yAxixConjunctionSign": " & ",
"xpack.lens.xyVisualization.areaLabel": "面积图",
"xpack.lens.xyVisualization.barGroupLabel": "条形图",

View file

@ -138,7 +138,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
field: 'bytes',
});
await testSubjects.click('lnsSuggestion-barChart > lnsSuggestion');
await testSubjects.click('lnsSuggestion-barVerticalStacked > lnsSuggestion');
await a11y.testAppSnapshot();
});

View file

@ -43,7 +43,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
operation: 'count',
field: 'Records',
});
await PageObjects.lens.waitForVisualization('legacyMtrVis');
await PageObjects.lens.waitForVisualization('lnsSuggestion-countOfRecords');
expect(await PageObjects.lens.getDatatableCellText(0, 0)).to.eql('1');
});
@ -52,7 +52,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.lens.enableTimeShift();
await PageObjects.lens.setTimeShift('3d');
await PageObjects.lens.waitForVisualization('legacyMtrVis');
await PageObjects.lens.waitForVisualization('lnsSuggestion-countOfRecords3D');
expect(await PageObjects.lens.getDatatableCellText(0, 0)).to.eql('2');
});
});

View file

@ -359,11 +359,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.lens.createLayer('data');
// here the editor will error out as the mandatory vertical axis is missing
await PageObjects.lens.dragDimensionToExtraDropType(
'lns-layerPanel-0 > lnsXY_xDimensionPanel > lns-dimensionTrigger',
'lns-layerPanel-1 > lnsXY_xDimensionPanel',
'duplicate',
xyChartContainer
'workspace-error-message'
);
await PageObjects.lens.assertFocusedDimension('@timestamp [1]');
@ -446,11 +447,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
'lns-layerPanel-1 > lnsXY_splitDimensionPanel > lns-empty-dimension'
);
// here the editor will error out as the mandatory vertical axis is missing
await PageObjects.lens.dragDimensionToExtraDropType(
'lns-layerPanel-1 > lnsXY_splitDimensionPanel > lns-dimensionTrigger',
'lns-layerPanel-0 > lnsXY_splitDimensionPanel',
'swap',
xyChartContainer
'workspace-error-message'
);
expect(await PageObjects.lens.getDimensionTriggersTexts('lns-layerPanel-0')).to.eql([
@ -464,11 +466,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
]);
});
it('can combine dimensions', async () => {
// here the editor will error out as the mandatory vertical axis is missing
await PageObjects.lens.dragDimensionToExtraDropType(
'lns-layerPanel-0 > lnsXY_splitDimensionPanel > lns-dimensionTrigger',
'lns-layerPanel-1 > lnsXY_splitDimensionPanel',
'combine',
xyChartContainer
'workspace-error-message'
);
expect(await PageObjects.lens.getDimensionTriggersTexts('lns-layerPanel-0')).to.eql([

View file

@ -174,7 +174,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
operation: 'formula',
});
await PageObjects.lens.waitForVisualization('legacyMtrVis');
await PageObjects.lens.waitForVisualization();
expect(await PageObjects.lens.getWorkspaceErrorCount()).to.eql(0);
});

View file

@ -90,7 +90,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
await panelActions.clickEdit();
await visualize.navigateToLensFromAnotherVisulization();
await lens.waitForVisualization('legacyMtrVis');
await lens.waitForVisualization('xyVisChart');
await retry.try(async () => {
const dimensions = await testSubjects.findAll('lns-dimensionTrigger');
expect(await dimensions[1].getVisibleText()).to.be('Count of records');

View file

@ -244,7 +244,7 @@ export default function ({ getPageObject, getService }: FtrProviderContext) {
if (lensMetricField) {
await ml.dataVisualizerTable.assertLensActionShowChart(
lensMetricField.fieldName,
'legacyMtrVis'
'xyVisChart'
);
await ml.navigation.browserBackTo('dataVisualizerTableContainer');
}
@ -255,7 +255,7 @@ export default function ({ getPageObject, getService }: FtrProviderContext) {
if (lensNonMetricField) {
await ml.dataVisualizerTable.assertLensActionShowChart(
lensNonMetricField.fieldName,
'legacyMtrVis'
'xyVisChart'
);
await ml.navigation.browserBackTo('dataVisualizerTableContainer');
}