TablePanel: Fix updating footer values on data change (#57518)

* TablePanel: Fix updating footer values on data change

* tests
This commit is contained in:
Victor Marin 2022-10-25 08:32:16 +03:00 committed by GitHub
parent e485ddd13d
commit c30716a073
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 191 additions and 1 deletions

View File

@ -207,5 +207,195 @@ describe('Table', () => {
// 3 + header row // 3 + header row
expect(within(getTable()).getAllByRole('row')).toHaveLength(4); expect(within(getTable()).getAllByRole('row')).toHaveLength(4);
}); });
it('should redo footer calculations', async () => {
getTestContext({
footerOptions: { show: true, reducer: ['sum'] },
data: toDataFrame({
name: 'A',
fields: [
{
name: 'number',
type: FieldType.number,
values: [1, 1, 1, 2, 2],
config: {
custom: {
filterable: true,
},
},
},
],
}),
});
expect(within(getFooter()).getByRole('columnheader').getElementsByTagName('span')[0].textContent).toEqual('7');
await userEvent.click(within(getColumnHeader(/number/)).getByRole('button', { name: '' }));
await userEvent.click(screen.getByLabelText('1'));
await userEvent.click(screen.getByText('Ok'));
expect(within(getFooter()).getByRole('columnheader').getElementsByTagName('span')[0].textContent).toEqual('3');
});
it('should filter rows and recalculate footer values when multiple filter values are selected', async () => {
getTestContext({
footerOptions: { show: true, reducer: ['sum'] },
data: toDataFrame({
name: 'A',
fields: [
{
name: 'number',
type: FieldType.number,
values: [1, 1, 1, 2, 2, 3, 3],
config: {
custom: {
filterable: true,
},
},
},
],
}),
});
expect(within(getTable()).getAllByRole('row')).toHaveLength(8);
expect(within(getFooter()).getByRole('columnheader').getElementsByTagName('span')[0].textContent).toEqual('13');
await userEvent.click(within(getColumnHeader(/number/)).getByRole('button', { name: '' }));
await userEvent.click(screen.getByLabelText('2'));
await userEvent.click(screen.getByLabelText('3'));
await userEvent.click(screen.getByText('Ok'));
//4 + header row
expect(within(getTable()).getAllByRole('row')).toHaveLength(5);
expect(within(getFooter()).getByRole('columnheader').getElementsByTagName('span')[0].textContent).toEqual('10');
});
it('should reset when clear filters button is pressed', async () => {
getTestContext({
footerOptions: { show: true, reducer: ['sum'] },
data: toDataFrame({
name: 'A',
fields: [
{
name: 'number',
type: FieldType.number,
values: [1, 1, 1, 2, 2],
config: {
custom: {
filterable: true,
},
},
},
],
}),
});
await userEvent.click(within(getColumnHeader(/number/)).getByRole('button', { name: '' }));
await userEvent.click(screen.getByLabelText('1'));
await userEvent.click(screen.getByText('Ok'));
//3 + header row
expect(within(getTable()).getAllByRole('row')).toHaveLength(4);
expect(within(getFooter()).getByRole('columnheader').getElementsByTagName('span')[0].textContent).toEqual('3');
await userEvent.click(within(getColumnHeader(/number/)).getByRole('button', { name: '' }));
await userEvent.click(screen.getByText('Clear filter'));
//5 + header row
expect(within(getTable()).getAllByRole('row')).toHaveLength(6);
expect(within(getFooter()).getByRole('columnheader').getElementsByTagName('span')[0].textContent).toEqual('7');
});
});
describe('on data change', () => {
it('should redo footer value calculations', async () => {
const { rerender } = getTestContext({
footerOptions: { show: true, reducer: ['sum'] },
data: toDataFrame({
name: 'A',
fields: [
{
name: 'number',
type: FieldType.number,
values: [1, 1, 1, 2, 2],
config: {
custom: {
filterable: true,
},
},
},
],
}),
});
//5 + header row
expect(within(getTable()).getAllByRole('row')).toHaveLength(6);
expect(within(getFooter()).getByRole('columnheader').getElementsByTagName('span')[0].textContent).toEqual('7');
const onSortByChange = jest.fn();
const onCellFilterAdded = jest.fn();
const onColumnResize = jest.fn();
const props: Props = {
ariaLabel: 'aria-label',
data: getDefaultDataFrame(),
height: 600,
width: 800,
onSortByChange,
onCellFilterAdded,
onColumnResize,
};
const propOverrides = {
footerOptions: { show: true, reducer: ['sum'] },
data: toDataFrame({
name: 'A',
fields: [
{
name: 'number',
type: FieldType.number,
values: [1, 1, 1, 2],
config: {
custom: {
filterable: true,
},
},
},
],
}),
};
Object.assign(props, propOverrides);
rerender(<Table {...props} />);
//4 + header row
expect(within(getTable()).getAllByRole('row')).toHaveLength(5);
expect(within(getFooter()).getByRole('columnheader').getElementsByTagName('span')[0].textContent).toEqual('5');
});
});
describe('on table footer disabled', () => {
it('should not show footer', async () => {
getTestContext({
footerOptions: { show: false, reducer: ['sum'] },
data: toDataFrame({
name: 'A',
fields: [
{
name: 'number',
type: FieldType.number,
values: [1, 1, 1, 2, 2],
config: {
custom: {
filterable: true,
},
},
},
],
}),
});
expect(() => screen.getByTestId('table-footer')).toThrow('Unable to find an element');
});
}); });
}); });

View File

@ -244,7 +244,7 @@ export const Table = memo((props: Props) => {
setFooterItems(undefined); setFooterItems(undefined);
} }
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [footerOptions, theme, state.filters]); }, [footerOptions, theme, state.filters, data]);
let listHeight = height - (headerHeight + footerHeight); let listHeight = height - (headerHeight + footerHeight);