diff --git a/CHANGELOG.md b/CHANGELOG.md index 05c6dcdf6a56..99a907b60bf9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ ## [`main`](https://github.com/elastic/eui/tree/main) -No public interface changes since `46.2.0`. +**Bug fixes** + +- Fixed `EuiInMemoryTable`'s `onTableChange` callback not returning the correct `sort.field` value on pagination ([#5588](https://github.com/elastic/eui/pull/5588)) ## [`46.2.0`](https://github.com/elastic/eui/tree/v46.2.0) diff --git a/src/components/basic_table/in_memory_table.test.tsx b/src/components/basic_table/in_memory_table.test.tsx index b6cc969fec2f..a768338c2fae 100644 --- a/src/components/basic_table/in_memory_table.test.tsx +++ b/src/components/basic_table/in_memory_table.test.tsx @@ -1015,13 +1015,14 @@ describe('EuiInMemoryTable', () => { }; const component = mount(); - expect(props.onTableChange).toHaveBeenCalledTimes(0); + + // Pagination change component .find('EuiButtonEmpty[data-test-subj="pagination-button-1"]') .simulate('click'); expect(props.onTableChange).toHaveBeenCalledTimes(1); - expect(props.onTableChange).toHaveBeenCalledWith({ + expect(props.onTableChange).toHaveBeenLastCalledWith({ sort: {}, page: { index: 1, @@ -1029,14 +1030,14 @@ describe('EuiInMemoryTable', () => { }, }); - (props.onTableChange as jest.Mock).mockClear(); + // Sorting change component .find( '[data-test-subj*="tableHeaderCell_name_0"] [data-test-subj="tableHeaderSortButton"]' ) .simulate('click'); - expect(props.onTableChange).toHaveBeenCalledTimes(1); - expect(props.onTableChange).toHaveBeenCalledWith({ + expect(props.onTableChange).toHaveBeenCalledTimes(2); + expect(props.onTableChange).toHaveBeenLastCalledWith({ sort: { direction: SortDirection.ASC, field: 'name', @@ -1046,6 +1047,22 @@ describe('EuiInMemoryTable', () => { size: 2, }, }); + + // Sorted pagination change + component + .find('EuiButtonEmpty[data-test-subj="pagination-button-1"]') + .simulate('click'); + expect(props.onTableChange).toHaveBeenCalledTimes(3); + expect(props.onTableChange).toHaveBeenLastCalledWith({ + sort: { + direction: SortDirection.ASC, + field: 'name', + }, + page: { + index: 1, + size: 2, + }, + }); }); }); diff --git a/src/components/basic_table/in_memory_table.tsx b/src/components/basic_table/in_memory_table.tsx index 0509cc78752d..548840a2e9a9 100644 --- a/src/components/basic_table/in_memory_table.tsx +++ b/src/components/basic_table/in_memory_table.tsx @@ -188,7 +188,7 @@ const getInitialPagination = (pagination: Pagination | undefined) => { function findColumnByProp( columns: Array>, prop: 'field' | 'name', - value: string + value: string | ReactNode ) { for (let i = 0; i < columns.length; i++) { const column = columns[i]; @@ -202,6 +202,19 @@ function findColumnByProp( } } +function findColumnByFieldOrName( + columns: Array>, + value: string | ReactNode +) { + // The passed value can be a column's `field` or its `name` + // for backwards compatibility `field` must be checked first + let column = findColumnByProp(columns, 'field', value); + if (column == null) { + column = findColumnByProp(columns, 'name', value); + } + return column; +} + function getInitialSorting( columns: Array>, sorting: Sorting | undefined @@ -218,12 +231,7 @@ function getInitialSorting( direction: sortDirection, } = (sorting as SortingOptions).sort; - // sortable could be a column's `field` or its `name` - // for backwards compatibility `field` must be checked first - let sortColumn = findColumnByProp(columns, 'field', sortable); - if (sortColumn == null) { - sortColumn = findColumnByProp(columns, 'name', sortable); - } + const sortColumn = findColumnByFieldOrName(columns, sortable); if (sortColumn == null) { return { @@ -401,16 +409,17 @@ export class EuiInMemoryTable extends Component< // from sortName; sortName gets stored internally while reportedSortName is sent to the callback let reportedSortName = sortName; - // EuiBasicTable returns the column's `field` if it exists instead of `name`, - // map back to `name` if this is the case - for (let i = 0; i < this.props.columns.length; i++) { - const column = this.props.columns[i]; - if ( - 'field' in column && - (column as EuiTableFieldDataColumnType).field === sortName - ) { - sortName = column.name as keyof T; - break; + // EuiBasicTable returns the column's `field` instead of `name` on sort + // and the column's `name` instead of `field` on pagination + if (sortName) { + const sortColumn = findColumnByFieldOrName(this.props.columns, sortName); + if (sortColumn) { + // Ensure sortName uses `name` + sortName = sortColumn.name as keyof T; + + // Ensure reportedSortName uses `field` if it exists + const sortField = (sortColumn as EuiTableFieldDataColumnType).field; + if (sortField) reportedSortName = sortField as keyof T; } }