diff --git a/x-pack/platform/plugins/shared/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx b/x-pack/platform/plugins/shared/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx
index 1b331043a530d..5ff9f9ed810ed 100644
--- a/x-pack/platform/plugins/shared/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx
+++ b/x-pack/platform/plugins/shared/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx
@@ -5,7 +5,7 @@
* 2.0.
*/
-import { camelCase } from 'lodash';
+import { camelCase, pick } from 'lodash';
import React, { useState, useEffect, useMemo, useRef, useCallback } from 'react';
import { FormattedMessage } from '@kbn/i18n-react';
import { css } from '@emotion/react';
@@ -46,6 +46,7 @@ import {
DatasourceMap,
VisualizationMap,
UserMessagesGetter,
+ DatasourceLayers,
} from '../../types';
import { getSuggestions, switchToSuggestion } from './suggestion_helpers';
import { getDatasourceExpressionsByLayers } from './expression_helpers';
@@ -130,7 +131,7 @@ const PreviewRenderer = ({
const euiThemeContext = useEuiTheme();
const { euiTheme } = euiThemeContext;
const onErrorMessage = (
-
+
{
+ if (updatedLayerApis[layerId]) {
+ updatedLayerApis[layerId] = datasource.getPublicAPI({
+ layerId,
+ state: datasourceState,
+ indexPatterns: frame.dataViews.indexPatterns,
+ });
+ }
+ suggestionFrameApi.datasourceLayers[layerId] = updatedLayerApis[layerId];
+ });
+ }
const datasourceExpressionsByLayers = getDatasourceExpressionsByLayers(
datasources,
datasourceStates,
diff --git a/x-pack/platform/plugins/shared/lens/public/visualizations/xy/visualization.tsx b/x-pack/platform/plugins/shared/lens/public/visualizations/xy/visualization.tsx
index 0a596ca1ea224..9df8ce382497b 100644
--- a/x-pack/platform/plugins/shared/lens/public/visualizations/xy/visualization.tsx
+++ b/x-pack/platform/plugins/shared/lens/public/visualizations/xy/visualization.tsx
@@ -1345,6 +1345,7 @@ export const stackingTypes = [
defaultMessage: 'Stacked',
}),
subtypes: ['bar_stacked', 'area_stacked', 'bar_horizontal_stacked'],
+ dataTestSubj: 'lnsStackingOptionsButtonStacked',
},
{
type: 'unstacked',
@@ -1352,6 +1353,7 @@ export const stackingTypes = [
defaultMessage: 'Unstacked',
}),
subtypes: ['bar', 'area', 'bar_horizontal'],
+ dataTestSubj: 'lnsStackingOptionsButtonUnstacked',
},
{
type: 'percentage',
@@ -1363,6 +1365,7 @@ export const stackingTypes = [
'area_percentage_stacked',
'bar_horizontal_percentage_stacked',
],
+ dataTestSubj: 'lnsStackingOptionsButtonPercentage',
},
];
@@ -1380,10 +1383,11 @@ const SubtypeSwitch = ({
return null;
}
const subTypeIndex = stackingType.subtypes.indexOf(layer.seriesType);
- const options = stackingTypes.map(({ label, subtypes }) => ({
+ const options = stackingTypes.map(({ label, subtypes, dataTestSubj }) => ({
label,
value: subtypes[subTypeIndex],
checked: subtypes[subTypeIndex] === layer.seriesType ? ('on' as const) : undefined,
+ 'data-test-subj': dataTestSubj,
}));
return (
@@ -1400,6 +1404,7 @@ const SubtypeSwitch = ({
fullWidth
size="s"
label={stackingType.label}
+ data-test-subj="lnsStackingOptionsButton"
/>
}
isOpen={flyoutOpen}
diff --git a/x-pack/test/functional/apps/lens/group1/smokescreen.ts b/x-pack/test/functional/apps/lens/group1/smokescreen.ts
index dbe48cdd395da..ff9274d7b1c40 100644
--- a/x-pack/test/functional/apps/lens/group1/smokescreen.ts
+++ b/x-pack/test/functional/apps/lens/group1/smokescreen.ts
@@ -829,5 +829,39 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await lens.waitForVisualization('xyVisChart');
expect(await lens.getWorkspaceErrorCount()).to.eql(0);
});
+
+ it('should keep suggestions up to date with the current configuration', async () => {
+ await visualize.navigateToNewVisualization();
+ await visualize.clickVisType('lens');
+ await lens.configureDimension({
+ dimension: 'lnsXY_xDimensionPanel > lns-empty-dimension',
+ operation: 'date_histogram',
+ field: '@timestamp',
+ });
+ await lens.configureDimension({
+ dimension: 'lnsXY_yDimensionPanel > lns-empty-dimension',
+ operation: 'average',
+ field: 'bytes',
+ });
+ // duplicate the layer
+ await lens.duplicateLayer();
+
+ // now make the first layer bar percentage to lead it in an broken rendering state
+ await lens.switchToVisualizationSubtype('Percentage');
+
+ // now check that both the main visualization and the current visualization suggestion are in error state
+ expect(await lens.getWorkspaceErrorCount()).to.eql(1);
+ await testSubjects.existOrFail(
+ 'lnsSuggestion-currentVisualization > lnsSuggestionPanel__error'
+ );
+
+ // revert the subtype to stacked and everything should be fine again
+ await lens.switchToVisualizationSubtype('Stacked');
+
+ expect(await lens.getWorkspaceErrorCount()).to.eql(0);
+ await testSubjects.missingOrFail(
+ 'lnsSuggestion-currentVisualization > lnsSuggestionPanel__error'
+ );
+ });
});
}
diff --git a/x-pack/test/functional/page_objects/lens_page.ts b/x-pack/test/functional/page_objects/lens_page.ts
index 635a9c4ba6c3a..40ba82f7fa84d 100644
--- a/x-pack/test/functional/page_objects/lens_page.ts
+++ b/x-pack/test/functional/page_objects/lens_page.ts
@@ -925,6 +925,19 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont
});
},
+ async switchToVisualizationSubtype(subType: string, layerIndex: number = 0) {
+ if (!(await testSubjects.exists(`lns-layerPanel-${layerIndex} > lnsStackingOptionsButton`))) {
+ throw new Error('No subtype available for the current visualization');
+ }
+ await testSubjects.click(`lns-layerPanel-${layerIndex} > lnsStackingOptionsButton`);
+ await testSubjects.click(`lnsStackingOptionsButton${subType}`);
+ },
+
+ async getChartTypeFromChartSwitcher() {
+ const chartSwitcher = await testSubjects.find('lnsChartSwitchPopover');
+ return await chartSwitcher.getVisibleText();
+ },
+
async openChartSwitchPopover(layerIndex = 0) {
if (await testSubjects.exists('lnsChartSwitchList', { timeout: 50 })) {
return;
@@ -1104,6 +1117,15 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont
}
},
+ async duplicateLayer(index: number = 0) {
+ await retry.try(async () => {
+ if (await testSubjects.exists(`lnsLayerSplitButton--${index}`)) {
+ await testSubjects.click(`lnsLayerSplitButton--${index}`);
+ }
+ await testSubjects.click(`lnsLayerClone--${index}`);
+ });
+ },
+
/**
* Changes the index pattern in the data panel
*/