Skip to content

Commit 2b47114

Browse files
Table visualization re-write (#11031)
* Re-write table vis Signed-off-by: abbyhu2000 <[email protected]> * UI changes Signed-off-by: abbyhu2000 <[email protected]> * Changeset file for PR #11031 created/updated * add tests Signed-off-by: abbyhu2000 <[email protected]> * fix hover Signed-off-by: abbyhu2000 <[email protected]> * fix unit test Signed-off-by: abbyhu2000 <[email protected]> --------- Signed-off-by: abbyhu2000 <[email protected]> Co-authored-by: opensearch-changeset-bot[bot] <154024398+opensearch-changeset-bot[bot]@users.noreply.github.com>
1 parent 904fa6a commit 2b47114

File tree

6 files changed

+1131
-257
lines changed

6 files changed

+1131
-257
lines changed

changelogs/fragments/11031.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
feat:
2+
- Table visualization re-write ([#11031](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/11031))

src/plugins/vis_type_table/public/components/table_vis_component.test.tsx

Lines changed: 64 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -4,36 +4,36 @@
44
*/
55

66
import React from 'react';
7-
import { shallow } from 'enzyme';
8-
import { TableVisConfig, ColumnSort } from '../types';
7+
import { shallow, mount } from 'enzyme';
8+
import { TableVisConfig, ColumnSort, AggTypes } from '../types';
99
import { TableVisComponent } from './table_vis_component';
1010
import { FormattedColumn } from '../types';
1111
import { FormattedTableContext } from '../table_vis_response_handler';
12-
import { getTableVisCellValue } from './table_vis_cell';
13-
import { getDataGridColumns } from './table_vis_grid_columns';
14-
import { EuiDataGridColumn } from '@elastic/eui';
15-
16-
jest.mock('./table_vis_cell', () => ({
17-
getTableVisCellValue: jest.fn(() => () => {}),
18-
}));
19-
20-
const mockGetDataGridColumns = jest.fn(() => []);
21-
jest.mock('./table_vis_grid_columns', () => ({
22-
getDataGridColumns: jest.fn(() => mockGetDataGridColumns()),
23-
}));
12+
import { TableVisDynamicTable } from './table_vis_dynamic_table';
13+
import { TableUiState } from '../utils/get_table_ui_state';
14+
15+
const mockFormatter = {
16+
convert: jest.fn((val) => val),
17+
getConverterFor: jest.fn(),
18+
getParamDefaults: jest.fn(),
19+
param: jest.fn(),
20+
params: jest.fn(),
21+
type: { id: 'string' },
22+
toJSON: jest.fn(),
23+
} as any;
2424

2525
const table = {
2626
formattedColumns: [
2727
{
2828
id: 'col-0-2',
2929
title: 'name.keyword: Descending',
30-
formatter: {},
30+
formatter: mockFormatter,
3131
filterable: true,
3232
},
3333
{
3434
id: 'col-1-1',
3535
title: 'Count',
36-
formatter: {},
36+
formatter: mockFormatter,
3737
filterable: false,
3838
sumTotal: 5,
3939
formattedTotal: 5,
@@ -90,7 +90,7 @@ const visConfig = {
9090
showPartialRows: false,
9191
showTotal: false,
9292
title: '',
93-
totalFunc: 'sum',
93+
totalFunc: AggTypes.SUM,
9494
} as TableVisConfig;
9595

9696
const uiState = {
@@ -109,128 +109,68 @@ describe('TableVisComponent', function () {
109109
uiState,
110110
};
111111

112-
const dataGridColumnsValue = [
113-
{
114-
id: 'col-0-2',
115-
display: 'name.keyword: Descending',
116-
displayAsText: 'name.keyword: Descending',
117-
actions: {
118-
showHide: false,
119-
showMoveLeft: false,
120-
showMoveRight: false,
121-
showSortAsc: {},
122-
showSortDesc: {},
123-
},
124-
cellActions: expect.any(Function),
125-
},
126-
{
127-
id: 'col-1-1',
128-
display: 'Count',
129-
displayAsText: 'Count',
130-
actions: {
131-
showHide: false,
132-
showMoveLeft: false,
133-
showMoveRight: false,
134-
showSortAsc: {},
135-
showSortDesc: {},
136-
},
137-
cellActions: undefined,
138-
},
139-
] as EuiDataGridColumn[];
112+
beforeEach(() => {
113+
jest.clearAllMocks();
114+
});
140115

141-
it('should render data grid', () => {
116+
it('should render TableVisDynamicTable', () => {
142117
const comp = shallow(<TableVisComponent {...props} />);
143-
expect(comp.find('EuiDataGrid')).toHaveLength(1);
118+
expect(comp.find(TableVisDynamicTable)).toHaveLength(1);
144119
});
145120

146-
it('should render title when provided', () => {
147-
const compWithTitle = shallow(<TableVisComponent {...props} title="Test Title" />);
148-
const titleElement = compWithTitle.find('EuiTitle');
149-
expect(titleElement).toHaveLength(1);
150-
expect(titleElement.find('h3').text()).toEqual('Test Title');
121+
it('should pass all props to TableVisDynamicTable', () => {
122+
const comp = shallow(<TableVisComponent {...props} />);
123+
const dynamicTable = comp.find(TableVisDynamicTable);
124+
125+
expect(dynamicTable.prop('title')).toEqual(props.title);
126+
expect(dynamicTable.prop('table')).toEqual(props.table);
127+
expect(dynamicTable.prop('visConfig')).toEqual(props.visConfig);
128+
expect(dynamicTable.prop('event')).toEqual(props.event);
129+
expect(dynamicTable.prop('uiState')).toEqual(props.uiState);
151130
});
152131

153-
it('should not render title when not provided', () => {
154-
const compWithoutTitle = shallow(<TableVisComponent {...props} title={undefined} />);
155-
const titleElement = compWithoutTitle.find('EuiTitle');
156-
expect(titleElement).toHaveLength(0);
132+
it('should pass title when provided', () => {
133+
const compWithTitle = shallow(<TableVisComponent {...props} title="Test Title" />);
134+
const dynamicTable = compWithTitle.find(TableVisDynamicTable);
135+
expect(dynamicTable.prop('title')).toEqual('Test Title');
157136
});
158137

159-
it('should set sort if sort column', () => {
160-
// @ts-expect-error TS2345 TODO(ts-error): fixme
161-
mockGetDataGridColumns.mockReturnValueOnce(dataGridColumnsValue);
162-
const comp = shallow(<TableVisComponent {...props} />);
163-
const { onSort } = comp.find('EuiDataGrid').prop('sorting') as any;
164-
onSort([]);
165-
expect(props.uiState.setSort).toHaveBeenCalledWith([]);
166-
onSort([{ id: 'col-0-2', direction: 'asc' }]);
167-
expect(props.uiState.setSort).toHaveBeenCalledWith({ colIndex: 0, direction: 'asc' });
168-
onSort([
169-
{ id: 'col-0-2', direction: 'asc' },
170-
{ id: 'col-1-1', direction: 'desc' },
171-
]);
172-
expect(props.uiState.setSort).toHaveBeenCalledWith({ colIndex: 1, direction: 'desc' });
138+
it('should pass undefined title when not provided', () => {
139+
const compWithoutTitle = shallow(<TableVisComponent {...props} title={undefined} />);
140+
const dynamicTable = compWithoutTitle.find(TableVisDynamicTable);
141+
expect(dynamicTable.prop('title')).toBeUndefined();
173142
});
174143

175-
it('should set width if adjust column width', () => {
176-
const uiStateProps = {
177-
...props.uiState,
178-
width: [
179-
{ colIndex: 0, width: 12 },
180-
{ colIndex: 1, width: 8 },
181-
],
182-
};
183-
const comp = shallow(<TableVisComponent {...props} />);
184-
const onColumnResize = comp.find('EuiDataGrid').prop('onColumnResize') as any;
185-
onColumnResize({ columnId: 'col-0-2', width: 18 });
186-
expect(props.uiState.setWidth).toHaveBeenCalledWith({ colIndex: 0, width: 18 });
187-
const updatedComp = shallow(<TableVisComponent {...props} uiState={uiStateProps} />);
188-
const onColumnResizeUpdate = updatedComp.find('EuiDataGrid').prop('onColumnResize') as any;
189-
onColumnResizeUpdate({ columnId: 'col-0-2', width: 18 });
190-
expect(props.uiState.setWidth).toHaveBeenCalledWith({ colIndex: 0, width: 18 });
144+
it('should pass visConfig with showTotal', () => {
145+
const visConfigWithTotal = { ...visConfig, showTotal: true };
146+
const comp = shallow(<TableVisComponent {...props} visConfig={visConfigWithTotal} />);
147+
const dynamicTable = comp.find(TableVisDynamicTable);
148+
expect(dynamicTable.prop('visConfig').showTotal).toBe(true);
191149
});
192150

193-
it('should create sortedRows and pass to getTableVisCellValue', () => {
194-
const uiStateProps = {
195-
...props.uiState,
151+
it('should pass uiState with sort configuration', () => {
152+
const uiStateWithSort = {
153+
...uiState,
196154
sort: { colIndex: 1, direction: 'asc' } as ColumnSort,
197155
};
198-
const sortedRows = [
199-
{ 'col-0-2': 'Anthony', 'col-1-1': 1 },
200-
{ 'col-0-2': 'Timmy', 'col-1-1': 1 },
201-
{ 'col-0-2': 'Alice', 'col-1-1': 3 },
202-
];
203-
// @ts-expect-error TS2345 TODO(ts-error): fixme
204-
mockGetDataGridColumns.mockReturnValueOnce(dataGridColumnsValue);
205-
shallow(<TableVisComponent {...props} uiState={uiStateProps} />);
206-
expect(getTableVisCellValue).toHaveBeenCalledWith(sortedRows, table.formattedColumns);
207-
expect(getDataGridColumns).toHaveBeenCalledWith(table, props.event, props.uiState.colWidth);
208-
});
209-
210-
it('should return formattedTotal from footerCellValue', () => {
211-
let comp = shallow(<TableVisComponent {...props} />);
212-
let renderFooterCellValue = comp.find('EuiDataGrid').prop('renderFooterCellValue') as any;
213-
expect(renderFooterCellValue).toEqual(undefined);
214-
comp = shallow(<TableVisComponent {...props} visConfig={{ ...visConfig, showTotal: true }} />);
215-
renderFooterCellValue = comp.find('EuiDataGrid').prop('renderFooterCellValue');
216-
expect(renderFooterCellValue({ columnId: 'col-1-1' })).toEqual(5);
217-
expect(renderFooterCellValue({ columnId: 'col-0-2' })).toEqual(null);
156+
const comp = shallow(<TableVisComponent {...props} uiState={uiStateWithSort} />);
157+
const dynamicTable = comp.find(TableVisDynamicTable);
158+
expect(dynamicTable.prop('uiState').sort).toEqual({ colIndex: 1, direction: 'asc' });
218159
});
219160

220-
it('should apply pagination correctly', () => {
221-
const comp = shallow(<TableVisComponent {...props} />);
222-
const paginationProps = comp.find('EuiDataGrid').prop('pagination');
223-
expect(paginationProps).toMatchObject({
224-
pageIndex: 0,
225-
pageSize: 3,
226-
onChangeItemsPerPage: expect.any(Function),
227-
onChangePage: expect.any(Function),
228-
});
229-
});
230-
231-
it('should not call renderFooterCellValue when showTotal is false', () => {
232-
const comp = shallow(<TableVisComponent {...props} />);
233-
const renderFooterCellValue = comp.find('EuiDataGrid').prop('renderFooterCellValue');
234-
expect(renderFooterCellValue).toBeUndefined();
161+
it('should pass uiState with column width configuration', () => {
162+
const uiStateWithWidth = {
163+
...uiState,
164+
colWidth: [
165+
{ colIndex: 0, width: 12 },
166+
{ colIndex: 1, width: 8 },
167+
],
168+
};
169+
const comp = shallow(<TableVisComponent {...props} uiState={uiStateWithWidth} />);
170+
const dynamicTable = comp.find(TableVisDynamicTable);
171+
expect(dynamicTable.prop('uiState').colWidth).toEqual([
172+
{ colIndex: 0, width: 12 },
173+
{ colIndex: 1, width: 8 },
174+
]);
235175
});
236176
});

0 commit comments

Comments
 (0)