[Lens] Improve Datatable content height with custom row height (#127134)

*  Add new rowHeight feature

*  Add unit tests for new feature

* 🗃️ Update migration logic

* 🏷️ Fix type issue

*  fix usual map migration test

* Update x-pack/plugins/lens/public/datatable_visualization/components/toolbar.tsx

* 🐛 Enable word wrap for multi lines

*  Fix unit test

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Marco Liberati 2022-03-09 15:44:24 +01:00 committed by GitHub
parent e932d83944
commit b7f3271fae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 426 additions and 51 deletions

View file

@ -28,6 +28,7 @@ export interface DatatableArgs {
sortingColumnId: SortingState['columnId'];
sortingDirection: SortingState['direction'];
fitRowToContent?: boolean;
rowHeightLines?: number;
pageSize?: PagingState['size'];
}
@ -68,6 +69,10 @@ export const getDatatable = (
types: ['boolean'],
help: '',
},
rowHeightLines: {
types: ['number'],
help: '',
},
pageSize: {
types: ['number'],
help: '',

View file

@ -227,6 +227,13 @@ exports[`DatatableComponent it renders actions column when there are row actions
onColumnResize={[Function]}
renderCellValue={[Function]}
rowCount={1}
rowHeightsOptions={
Object {
"defaultHeight": Object {
"lineCount": 1,
},
}
}
sorting={
Object {
"columns": Array [],
@ -472,6 +479,13 @@ exports[`DatatableComponent it renders the title and value 1`] = `
onColumnResize={[Function]}
renderCellValue={[Function]}
rowCount={1}
rowHeightsOptions={
Object {
"defaultHeight": Object {
"lineCount": 1,
},
}
}
sorting={
Object {
"columns": Array [],
@ -712,6 +726,13 @@ exports[`DatatableComponent it should render hide, reset, and sort actions on he
onColumnResize={[Function]}
renderCellValue={[Function]}
rowCount={1}
rowHeightsOptions={
Object {
"defaultHeight": Object {
"lineCount": 1,
},
}
}
sorting={
Object {
"columns": Array [],

View file

@ -86,7 +86,7 @@ describe('datatable cell renderer', () => {
/>
</DataContext.Provider>
);
expect(cell.find('.lnsTableCell').prop('className')).toContain('--right');
expect(cell.find('.lnsTableCell--right').exists()).toBeTruthy();
});
describe('dynamic coloring', () => {
@ -127,6 +127,7 @@ describe('datatable cell renderer', () => {
],
sortingColumnId: '',
sortingDirection: 'none',
rowHeightLines: 1,
};
}

View file

@ -20,7 +20,8 @@ export const createGridCell = (
columnConfig: ColumnConfig,
DataContext: React.Context<DataContextType>,
uiSettings: IUiSettingsClient,
fitRowToContent?: boolean
fitRowToContent?: boolean,
rowHeight?: number
) => {
// Changing theme requires a full reload of the page, so we can cache here
const IS_DARK_THEME = uiSettings.get('theme:darkMode');
@ -31,7 +32,7 @@ export const createGridCell = (
const currentAlignment = alignments && alignments[columnId];
const alignmentClassName = `lnsTableCell--${currentAlignment}`;
const className = classNames(alignmentClassName, {
lnsTableCell: !fitRowToContent,
lnsTableCell: !fitRowToContent && rowHeight === 1,
});
const { colorMode, palette } =

View file

@ -84,6 +84,7 @@ function sampleArgs() {
],
sortingColumnId: '',
sortingDirection: 'none',
rowHeightLines: 1,
};
return { data, args };
@ -299,6 +300,7 @@ describe('DatatableComponent', () => {
],
sortingColumnId: '',
sortingDirection: 'none',
rowHeightLines: 1,
};
const wrapper = mountWithIntl(

View file

@ -334,9 +334,16 @@ export const DatatableComponent = (props: DatatableRenderProps) => {
columnConfig,
DataContext,
props.uiSettings,
props.args.fitRowToContent
props.args.fitRowToContent,
props.args.rowHeightLines
),
[formatters, columnConfig, props.uiSettings, props.args.fitRowToContent]
[
formatters,
columnConfig,
props.uiSettings,
props.args.fitRowToContent,
props.args.rowHeightLines,
]
);
const columnVisibility = useMemo(
@ -414,13 +421,15 @@ export const DatatableComponent = (props: DatatableRenderProps) => {
<EuiDataGrid
aria-label={dataGridAriaLabel}
data-test-subj="lnsDataTable"
rowHeightsOptions={
props.args.fitRowToContent
rowHeightsOptions={{
defaultHeight: props.args.fitRowToContent
? 'auto'
: props.args.rowHeightLines
? {
defaultHeight: 'auto',
lineCount: props.args.rowHeightLines,
}
: undefined
}
: undefined,
}}
columns={columns}
columnVisibility={columnVisibility}
trailingControlColumns={trailingControlColumns}

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import React, { FormEvent } from 'react';
import React, { ChangeEvent, FormEvent } from 'react';
import { mountWithIntl } from '@kbn/test-jest-helpers';
import { DataTableToolbar } from './toolbar';
import { DatatableVisualizationState } from '../visualization';
@ -13,6 +13,19 @@ import { FramePublicAPI, VisualizationToolbarProps } from '../../types';
import { ToolbarButton } from 'src/plugins/kibana_react/public';
import { ReactWrapper } from 'enzyme';
import { PagingState } from '../../../common/expressions';
import { EuiButtonGroup, EuiRange } from '@elastic/eui';
// mocking random id generator function
jest.mock('@elastic/eui', () => {
const original = jest.requireActual('@elastic/eui');
return {
...original,
htmlIdGenerator: (fn: unknown) => {
return () => '';
},
};
});
class Harness {
wrapper: ReactWrapper;
@ -25,12 +38,25 @@ class Harness {
this.wrapper.find(ToolbarButton).simulate('click');
}
public get fitRowToContentSwitch() {
return this.wrapper.find('EuiSwitch[data-test-subj="lens-legend-auto-height-switch"]');
public get rowHeight() {
return this.wrapper.find(EuiButtonGroup);
}
toggleFitRowToContent() {
this.fitRowToContentSwitch.prop('onChange')!({} as FormEvent);
changeRowHeight(newMode: 'single' | 'auto' | 'custom') {
this.rowHeight.prop('onChange')!(newMode);
}
public get rowHeightLines() {
return this.wrapper.find(EuiRange);
}
changeRowHeightLines(lineCount: number) {
this.rowHeightLines.prop('onChange')!(
{
currentTarget: { value: lineCount },
} as unknown as ChangeEvent<HTMLInputElement>,
true
);
}
public get paginationSwitch() {
@ -56,7 +82,7 @@ describe('datatable toolbar', () => {
setState: jest.fn(),
frame: {} as FramePublicAPI,
state: {
fitRowToContent: false,
rowHeight: 'single',
} as DatatableVisualizationState,
};
@ -66,39 +92,57 @@ describe('datatable toolbar', () => {
it('should reflect state in the UI', async () => {
harness.togglePopover();
expect(harness.fitRowToContentSwitch.prop('checked')).toBe(false);
expect(harness.rowHeight.prop('idSelected')).toBe('single');
expect(harness.paginationSwitch.prop('checked')).toBe(false);
harness.wrapper.setProps({
state: {
fitRowToContent: true,
rowHeight: 'auto',
paging: defaultPagingState,
},
});
expect(harness.fitRowToContentSwitch.prop('checked')).toBe(true);
expect(harness.rowHeight.prop('idSelected')).toBe('auto');
expect(harness.paginationSwitch.prop('checked')).toBe(true);
});
it('should toggle fit-row-to-content', async () => {
it('should change row height to "Auto" mode', async () => {
harness.togglePopover();
harness.toggleFitRowToContent();
harness.changeRowHeight('auto');
expect(defaultProps.setState).toHaveBeenCalledTimes(1);
expect(defaultProps.setState).toHaveBeenNthCalledWith(1, {
fitRowToContent: true,
rowHeight: 'auto',
rowHeightLines: undefined,
});
harness.wrapper.setProps({ state: { fitRowToContent: true } }); // update state manually
harness.toggleFitRowToContent(); // turn it off
harness.wrapper.setProps({ state: { rowHeight: 'auto' } }); // update state manually
harness.changeRowHeight('single'); // turn it off
expect(defaultProps.setState).toHaveBeenCalledTimes(2);
expect(defaultProps.setState).toHaveBeenNthCalledWith(2, {
fitRowToContent: false,
rowHeight: 'single',
rowHeightLines: 1,
});
});
it('should change row height to "Custom" mode', async () => {
harness.togglePopover();
harness.changeRowHeight('custom');
expect(defaultProps.setState).toHaveBeenCalledTimes(1);
expect(defaultProps.setState).toHaveBeenNthCalledWith(1, {
rowHeight: 'custom',
rowHeightLines: 2,
});
harness.wrapper.setProps({ state: { rowHeight: 'custom' } }); // update state manually
expect(harness.rowHeightLines.prop('value')).toBe(2);
});
it('should toggle table pagination', async () => {
harness.togglePopover();
@ -107,18 +151,18 @@ describe('datatable toolbar', () => {
expect(defaultProps.setState).toHaveBeenCalledTimes(1);
expect(defaultProps.setState).toHaveBeenNthCalledWith(1, {
paging: defaultPagingState,
fitRowToContent: false,
rowHeight: 'single',
});
// update state manually
harness.wrapper.setProps({
state: { fitRowToContent: false, paging: defaultPagingState },
state: { rowHeight: 'single', paging: defaultPagingState },
});
harness.togglePagination(); // turn it off. this should disable pagination but preserve the default page size
expect(defaultProps.setState).toHaveBeenCalledTimes(2);
expect(defaultProps.setState).toHaveBeenNthCalledWith(2, {
fitRowToContent: false,
rowHeight: 'single',
paging: { ...defaultPagingState, enabled: false },
});
});

View file

@ -7,22 +7,47 @@
import React, { useCallback } from 'react';
import { i18n } from '@kbn/i18n';
import { EuiFlexGroup, EuiFormRow, EuiSwitch, EuiToolTip } from '@elastic/eui';
import {
EuiButtonGroup,
EuiFlexGroup,
EuiFormRow,
EuiRange,
EuiSwitch,
EuiToolTip,
htmlIdGenerator,
} from '@elastic/eui';
import { ToolbarPopover } from '../../shared_components';
import type { VisualizationToolbarProps } from '../../types';
import type { DatatableVisualizationState } from '../visualization';
import { DEFAULT_PAGE_SIZE } from './table_basic';
const idPrefix = htmlIdGenerator()();
export function DataTableToolbar(props: VisualizationToolbarProps<DatatableVisualizationState>) {
const { state, setState } = props;
const onToggleFitRow = useCallback(() => {
const current = state.fitRowToContent ?? false;
setState({
...state,
fitRowToContent: !current,
});
}, [setState, state]);
const onChangeRowHeight = useCallback(
(newHeightMode) => {
const rowHeightLines =
newHeightMode === 'single' ? 1 : newHeightMode !== 'auto' ? 2 : undefined;
setState({
...state,
rowHeight: newHeightMode,
rowHeightLines,
});
},
[setState, state]
);
const onChangeRowHeightLines = useCallback(
(newRowHeightLines) => {
setState({
...state,
rowHeightLines: newRowHeightLines,
});
},
[state, setState]
);
const onTogglePagination = useCallback(() => {
const current = state.paging ?? { size: DEFAULT_PAGE_SIZE, enabled: false };
@ -33,6 +58,30 @@ export function DataTableToolbar(props: VisualizationToolbarProps<DatatableVisua
});
}, [setState, state]);
const rowHeightModeOptions = [
{
id: `${idPrefix}single`,
label: i18n.translate('xpack.lens.table.rowHeight.single', {
defaultMessage: 'Single',
}),
'data-test-subj': 'lnsDatatable_rowHeight_single',
},
{
id: `${idPrefix}auto`,
label: i18n.translate('xpack.lens.table.rowHeight.auto', {
defaultMessage: 'Auto fit',
}),
'data-test-subj': 'lnsDatatable_rowHeight_auto',
},
{
id: `${idPrefix}custom`,
label: i18n.translate('xpack.lens.table.rowHeight.custom', {
defaultMessage: 'Custom',
}),
'data-test-subj': 'lnsDatatable_rowHeight_custom',
},
];
return (
<EuiFlexGroup gutterSize="none" justifyContent="spaceBetween" responsive={false}>
<ToolbarPopover
@ -45,19 +94,52 @@ export function DataTableToolbar(props: VisualizationToolbarProps<DatatableVisua
>
<EuiFormRow
label={i18n.translate('xpack.lens.table.visualOptionsFitRowToContentLabel', {
defaultMessage: 'Fit row to content',
defaultMessage: 'Row height',
})}
display="columnCompressedSwitch"
display="columnCompressed"
>
<EuiSwitch
compressed
data-test-subj="lens-legend-auto-height-switch"
label=""
showLabel={false}
checked={Boolean(state.fitRowToContent)}
onChange={onToggleFitRow}
<EuiButtonGroup
isFullWidth
legend={i18n.translate('xpack.lens.table.visualOptionsRowHeight', {
defaultMessage: 'Row height',
})}
data-test-subj="lens-table-row-height"
name="legendLocation"
buttonSize="compressed"
options={rowHeightModeOptions}
idSelected={`${idPrefix}${state.rowHeight ?? 'single'}`}
onChange={(optionId) => {
const newMode = optionId.replace(
idPrefix,
''
) as DatatableVisualizationState['rowHeight'];
onChangeRowHeight(newMode);
}}
/>
</EuiFormRow>
{state.rowHeight === 'custom' ? (
<EuiFormRow
label={i18n.translate('xpack.lens.table.visualOptionsCustomRowHeight', {
defaultMessage: 'Lines per row',
})}
display="columnCompressed"
>
<EuiRange
compressed
fullWidth
showInput
min={1}
max={20}
step={1}
value={state.rowHeightLines ?? 2}
onChange={(e) => {
const lineCount = Number(e.currentTarget.value);
onChangeRowHeightLines(lineCount);
}}
data-test-subj="lens-table-row-height-lineCountNumber"
/>
</EuiFormRow>
) : null}
<EuiFormRow
label={i18n.translate('xpack.lens.table.visualOptionsPaginateTable', {
defaultMessage: 'Paginate table',

View file

@ -597,21 +597,62 @@ describe('Datatable Visualization', () => {
).toEqual([20]);
});
it('sets fitRowToContent based on state', () => {
it('sets rowHeight "auto" fit based on state', () => {
expect(
getDatatableExpressionArgs({ ...defaultExpressionTableState }).fitRowToContent
).toEqual([false]);
expect(
getDatatableExpressionArgs({ ...defaultExpressionTableState, fitRowToContent: false })
getDatatableExpressionArgs({ ...defaultExpressionTableState, rowHeight: 'single' })
.fitRowToContent
).toEqual([false]);
expect(
getDatatableExpressionArgs({ ...defaultExpressionTableState, fitRowToContent: true })
getDatatableExpressionArgs({ ...defaultExpressionTableState, rowHeight: 'custom' })
.fitRowToContent
).toEqual([false]);
expect(
getDatatableExpressionArgs({ ...defaultExpressionTableState, rowHeight: 'auto' })
.fitRowToContent
).toEqual([true]);
});
it('sets rowHeightLines fit based on state', () => {
expect(getDatatableExpressionArgs({ ...defaultExpressionTableState }).rowHeightLines).toEqual(
[1]
);
expect(
getDatatableExpressionArgs({ ...defaultExpressionTableState, rowHeight: 'single' })
.rowHeightLines
).toEqual([1]);
// should ignore lines value based on mode
expect(
getDatatableExpressionArgs({
...defaultExpressionTableState,
rowHeight: 'single',
rowHeightLines: 5,
}).rowHeightLines
).toEqual([1]);
expect(
getDatatableExpressionArgs({
...defaultExpressionTableState,
rowHeight: 'custom',
rowHeightLines: 5,
}).rowHeightLines
).toEqual([5]);
// should fallback to 2 for custom in case it's not set
expect(
getDatatableExpressionArgs({
...defaultExpressionTableState,
rowHeight: 'custom',
}).rowHeightLines
).toEqual([2]);
});
});
describe('#getErrorMessages', () => {

View file

@ -32,7 +32,8 @@ export interface DatatableVisualizationState {
layerId: string;
layerType: LayerType;
sorting?: SortingState;
fitRowToContent?: boolean;
rowHeight?: 'auto' | 'single' | 'custom';
rowHeightLines?: number;
paging?: PagingState;
}
@ -400,7 +401,10 @@ export const getDatatableVisualization = ({
}),
sortingColumnId: [state.sorting?.columnId || ''],
sortingDirection: [state.sorting?.direction || 'none'],
fitRowToContent: [state.fitRowToContent ?? false],
fitRowToContent: [state.rowHeight === 'auto'],
rowHeightLines: [
!state.rowHeight || state.rowHeight === 'single' ? 1 : state.rowHeightLines ?? 2,
],
pageSize: state.paging?.enabled ? [state.paging.size] : [],
},
},

View file

@ -13,6 +13,7 @@ import {
} from '../../../../../src/plugins/kibana_utils/common';
import { DOC_TYPE } from '../../common';
import {
commonEnhanceTableRowHeight,
commonMakeReversePaletteAsCustom,
commonRemoveTimezoneDateHistogramParam,
commonRenameFilterReferences,
@ -26,8 +27,10 @@ import {
CustomVisualizationMigrations,
LensDocShape713,
LensDocShape715,
LensDocShape810,
LensDocShapePre712,
VisState716,
VisState810,
VisStatePre715,
} from '../migrations/types';
import { extract, inject } from '../../common/embeddable_factory';
@ -88,6 +91,14 @@ export const makeLensEmbeddableFactory =
attributes: migratedLensState,
} as unknown as SerializableRecord;
},
'8.2.0': (state) => {
const lensState = state as unknown as { attributes: LensDocShape810<VisState810> };
const migratedLensState = commonEnhanceTableRowHeight(lensState.attributes);
return {
...lensState,
attributes: migratedLensState,
} as unknown as SerializableRecord;
},
}),
getLensCustomVisualizationMigrations(customVisualizationMigrations)
),

View file

@ -23,6 +23,8 @@ import {
VisStatePost715,
VisStatePre715,
VisState716,
VisState810,
VisState820,
CustomVisualizationMigrations,
LensDocShape810,
} from './types';
@ -192,6 +194,20 @@ export const commonRenameFilterReferences = (attributes: LensDocShape715): LensD
return newAttributes as LensDocShape810;
};
export const commonEnhanceTableRowHeight = (
attributes: LensDocShape810<VisState810>
): LensDocShape810<VisState820> => {
if (attributes.visualizationType !== 'lnsDatatable') {
return attributes;
}
const visState810 = attributes.state.visualization as VisState810;
const newAttributes = cloneDeep(attributes);
const vizState = newAttributes.state.visualization as VisState820;
vizState.rowHeight = visState810.fitRowToContent ? 'auto' : 'single';
vizState.rowHeightLines = visState810.fitRowToContent ? 2 : 1;
return newAttributes;
};
const getApplyCustomVisualizationMigrationToLens = (id: string, migration: MigrateFunction) => {
return (savedObject: { attributes: LensDocShape }) => {
if (savedObject.attributes.visualizationType !== id) return savedObject;

View file

@ -18,6 +18,8 @@ import {
VisState716,
VisStatePost715,
VisStatePre715,
VisState810,
VisState820,
} from './types';
import { CustomPaletteParams, layerTypes } from '../../common';
import { PaletteOutput } from 'src/plugins/charts/common';
@ -1779,4 +1781,122 @@ describe('Lens migrations', () => {
);
});
});
describe('8.2.0 rename fitRowToContent to new detailed rowHeight and rowHeightLines', () => {
const context = { log: { warning: () => {} } } as unknown as SavedObjectMigrationContext;
function getExample(fitToContent: boolean) {
return {
type: 'lens',
id: 'mocked-saved-object-id',
attributes: {
visualizationType: 'lnsDatatable',
title: 'Lens visualization',
references: [
{
id: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f',
name: 'indexpattern-datasource-current-indexpattern',
type: 'index-pattern',
},
{
id: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f',
name: 'indexpattern-datasource-layer-cddd8f79-fb20-4191-a3e7-92484780cc62',
type: 'index-pattern',
},
],
state: {
datasourceStates: {
indexpattern: {
layers: {
'cddd8f79-fb20-4191-a3e7-92484780cc62': {
indexPatternId: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f',
columns: {
'221f0abf-6e54-4c61-9316-4107ad6fa500': {
label: 'Top values of category.keyword',
dataType: 'string',
operationType: 'terms',
scale: 'ordinal',
sourceField: 'category.keyword',
isBucketed: true,
params: {
size: 5,
orderBy: {
type: 'column',
columnId: 'c6f07a26-64eb-4871-ad62-c7d937230e33',
},
orderDirection: 'desc',
otherBucket: true,
missingBucket: false,
parentFormat: {
id: 'terms',
},
},
},
'c6f07a26-64eb-4871-ad62-c7d937230e33': {
label: 'Count of records',
dataType: 'number',
operationType: 'count',
isBucketed: false,
scale: 'ratio',
sourceField: '___records___',
},
},
columnOrder: [
'221f0abf-6e54-4c61-9316-4107ad6fa500',
'c6f07a26-64eb-4871-ad62-c7d937230e33',
],
incompleteColumns: {},
},
},
},
},
visualization: {
columns: [
{
isTransposed: false,
columnId: '221f0abf-6e54-4c61-9316-4107ad6fa500',
},
{
isTransposed: false,
columnId: 'c6f07a26-64eb-4871-ad62-c7d937230e33',
},
],
layerId: 'cddd8f79-fb20-4191-a3e7-92484780cc62',
layerType: 'data',
fitRowToContent: fitToContent,
},
filters: [],
query: {
query: '',
language: 'kuery',
},
},
},
} as unknown as SavedObjectUnsanitizedDoc<LensDocShape810>;
}
it('should migrate enabled fitRowToContent to new rowHeight: "auto"', () => {
const result = migrations['8.2.0'](getExample(true), context) as ReturnType<
SavedObjectMigrationFn<LensDocShape810<VisState810>, LensDocShape810<VisState820>>
>;
expect(result.attributes.state.visualization as VisState820).toEqual(
expect.objectContaining({
rowHeight: 'auto',
})
);
});
it('should migrate disabled fitRowToContent to new rowHeight: "single"', () => {
const result = migrations['8.2.0'](getExample(false), context) as ReturnType<
SavedObjectMigrationFn<LensDocShape810<VisState810>, LensDocShape810<VisState820>>
>;
expect(result.attributes.state.visualization as VisState820).toEqual(
expect.objectContaining({
rowHeight: 'single',
rowHeightLines: 1,
})
);
});
});
});

View file

@ -40,6 +40,7 @@ import {
getLensCustomVisualizationMigrations,
commonRenameRecordsField,
fixLensTopValuesCustomFormatting,
commonEnhanceTableRowHeight,
} from './common_migrations';
interface LensDocShapePre710<VisualizationState = unknown> {
@ -464,6 +465,11 @@ const addParentFormatter: SavedObjectMigrationFn<LensDocShape810, LensDocShape81
return { ...newDoc, attributes: fixLensTopValuesCustomFormatting(newDoc.attributes) };
};
const enhanceTableRowHeight: SavedObjectMigrationFn<LensDocShape810, LensDocShape810> = (doc) => {
const newDoc = cloneDeep(doc);
return { ...newDoc, attributes: commonEnhanceTableRowHeight(newDoc.attributes) };
};
const lensMigrations: SavedObjectMigrationMap = {
'7.7.0': removeInvalidAccessors,
// The order of these migrations matter, since the timefield migration relies on the aggConfigs
@ -478,6 +484,7 @@ const lensMigrations: SavedObjectMigrationMap = {
'7.15.0': addLayerTypeToVisualization,
'7.16.0': moveDefaultReversedPaletteToCustom,
'8.1.0': flow(renameFilterReferences, renameRecordsField, addParentFormatter),
'8.2.0': enhanceTableRowHeight,
};
export const getAllMigrations = (

View file

@ -246,3 +246,14 @@ export type VisState716 =
| {
palette?: PaletteOutput<CustomPaletteParams>;
};
// Datatable only
export interface VisState810 {
fitRowToContent?: boolean;
}
// Datatable only
export interface VisState820 {
rowHeight: 'auto' | 'single' | 'custom';
rowHeightLines: number;
}

View file

@ -77,7 +77,7 @@ export default function ({ getService }) {
}
expect(panels.length).to.be(1);
expect(panels[0].type).to.be('map');
expect(panels[0].version).to.be('8.1.0');
expect(panels[0].version).to.be('8.2.0');
});
});
});