[Lens] Fixes dimension button on configuration panel palette is not cleaned up on changing to unsupported operation type (#175912)

Fixes https://github.com/elastic/kibana/issues/174747

This is one of the type of bugs we get quite often and I think we
reached a moment we should holistically rethink how we could validate
the state of the visualization when we update datasource state. I'll be
taking a look at that, but here's some adhoc fix!
This commit is contained in:
Marta Bondyra 2024-02-08 12:56:43 +01:00 committed by GitHub
parent 0f3a72d700
commit baa80de3d8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 77 additions and 3 deletions

View file

@ -7,7 +7,13 @@
import { Ast } from '@kbn/interpreter';
import { buildExpression } from '@kbn/expressions-plugin/public';
import { createMockDatasource, createMockFramePublicAPI, DatasourceMock } from '../../mocks';
import {
createMockDatasource,
createMockFramePublicAPI,
DatasourceMock,
generateActiveData,
} from '../../mocks';
import faker from 'faker';
import { DatatableVisualizationState, getDatatableVisualization } from './visualization';
import {
Operation,
@ -15,6 +21,7 @@ import {
FramePublicAPI,
TableSuggestionColumn,
VisualizationDimensionGroupConfig,
VisualizationConfigProps,
} from '../../types';
import { chartPluginMock } from '@kbn/charts-plugin/public/mocks';
import { LayerTypes } from '@kbn/expression-xy-plugin/public';
@ -408,6 +415,68 @@ describe('Datatable Visualization', () => {
).toEqual([{ columnId: 'c' }, { columnId: 'b' }]);
});
describe('with palette', () => {
let params: VisualizationConfigProps<DatatableVisualizationState>;
beforeEach(() => {
const datasource = createMockDatasource('test');
datasource.publicAPIMock.getTableSpec.mockReturnValue([{ columnId: 'b', fields: [] }]);
params = {
layerId: 'a',
state: {
layerId: 'a',
layerType: LayerTypes.DATA,
columns: [
{
columnId: 'b',
palette: {
type: 'palette' as const,
name: '',
params: { stops: [{ color: 'blue', stop: 0 }] },
},
},
],
},
frame: {
...mockFrame(),
activeData: generateActiveData([
{
id: 'a',
rows: Array(3).fill({
b: faker.random.number(),
}),
},
]),
datasourceLayers: { a: datasource.publicAPIMock },
},
};
});
it('does include palette for accessor config if the values are numeric and palette exists', () => {
expect(datatableVisualization.getConfiguration(params).groups[2].accessors).toEqual([
{ columnId: 'b', palette: ['blue'], triggerIconType: 'colorBy' },
]);
});
it('does not include palette for accessor config if the values are not numeric and palette exists', () => {
params.frame.activeData = generateActiveData([
{
id: 'a',
rows: Array(3).fill({
b: faker.random.word(),
}),
},
]);
expect(datatableVisualization.getConfiguration(params).groups[2].accessors).toEqual([
{ columnId: 'b' },
]);
});
it('does not include palette for accessor config if the values are numeric but palette exists', () => {
params.state.columns[0].palette = undefined;
expect(datatableVisualization.getConfiguration(params).groups[2].accessors).toEqual([
{ columnId: 'b' },
]);
});
});
it('should compute the groups correctly for text based languages', () => {
const datasource = createMockDatasource('textBased', {
isTextBasedLanguage: jest.fn(() => true),

View file

@ -14,6 +14,7 @@ import { VIS_EVENT_TO_TRIGGER } from '@kbn/visualizations-plugin/public';
import { IconChartDatatable } from '@kbn/chart-icons';
import { LayerTypes } from '@kbn/expression-xy-plugin/public';
import { buildExpression, buildExpressionFunction } from '@kbn/expressions-plugin/common';
import { isNumericFieldForDatatable } from '../../../common/expressions/datatable/utils';
import type { FormBasedPersistedState } from '../../datasources/form_based/types';
import type {
SuggestionRequest,
@ -315,16 +316,20 @@ export const getDatatableVisualization = ({
.map((accessor) => {
const columnConfig = columnMap[accessor];
const stops = columnConfig?.palette?.params?.stops;
const isNumeric = Boolean(
accessor && isNumericFieldForDatatable(frame.activeData?.[state.layerId], accessor)
);
const hasColoring = Boolean(columnConfig?.colorMode !== 'none' && stops);
return {
columnId: accessor,
triggerIconType: columnConfig?.hidden
? 'invisible'
: hasColoring
: hasColoring && isNumeric
? 'colorBy'
: undefined,
palette: hasColoring && stops ? stops.map(({ color }) => color) : undefined,
palette:
hasColoring && isNumeric && stops ? stops.map(({ color }) => color) : undefined,
};
}),
supportsMoreColumns: true,