Skip to content

Commit

Permalink
[Datatable] Sorts null values last (#172691)
Browse files Browse the repository at this point in the history
## Summary

Closes #169126

We were using the orderBy which sorts the null values at the beginning
on descending order lodash/lodash#4169

I created my own function. Now they are sorted always last like Lens
does.

<img width="1820" alt="image"
src="https://github.com/elastic/kibana/assets/17003240/d6fbd6b9-96fe-4e71-b90f-63a030902cca">

### Checklist

- [ ] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios

(cherry picked from commit 6be8e5e)
  • Loading branch information
stratoula committed Dec 7, 2023
1 parent ff04f68 commit 8f4b366
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,13 @@ import {
EuiTitle,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { orderBy } from 'lodash';

import { IInterpreterRenderHandlers } from '@kbn/expressions-plugin/common';
import { createTableVisCell } from './table_vis_cell';
import { TableContext, TableVisConfig, TableVisUseUiStateProps } from '../types';
import { usePagination } from '../utils';
import { TableVisControls } from './table_vis_controls';
import { createGridColumns } from './table_vis_columns';
import { sortNullsLast } from './utils';

interface TableVisBasicProps {
fireEvent: IInterpreterRenderHandlers['event'];
Expand All @@ -45,13 +44,14 @@ export const TableVisBasic = memo(
const { columns, rows, formattedColumns } = table;

// custom sorting is in place until the EuiDataGrid sorting gets rid of flaws -> https://github.com/elastic/eui/issues/4108
const sortedRows = useMemo(
() =>
sort.columnIndex !== null && sort.direction
? orderBy(rows, columns[sort.columnIndex]?.id, sort.direction)
: rows,
[columns, rows, sort]
);
const sortedRows = useMemo(() => {
if (sort.columnIndex !== null && sort.direction) {
const id = columns[sort.columnIndex]?.id;
return sortNullsLast(rows, sort.direction, id);
}

return rows;
}, [columns, rows, sort.columnIndex, sort.direction]);

// renderCellValue is a component which renders a cell based on column and row indexes
const renderCellValue = useMemo(
Expand Down
52 changes: 52 additions & 0 deletions src/plugins/vis_types/table/public/components/utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { sortNullsLast } from './utils';

describe('sortNullsLast', () => {
const rows = [
{
col1: null,
},
{
col1: 'meow',
},
{
col1: 'woof',
},
];
test('should sort correctly in ascending order', async () => {
const sortedRows = sortNullsLast(rows, 'asc', 'col1');
expect(sortedRows).toStrictEqual([
{
col1: 'meow',
},
{
col1: 'woof',
},
{
col1: null,
},
]);
});

test('should sort correctly in descending order', async () => {
const sortedRows = sortNullsLast(rows, 'desc', 'col1');
expect(sortedRows).toStrictEqual([
{
col1: 'woof',
},
{
col1: 'meow',
},
{
col1: null,
},
]);
});
});
30 changes: 29 additions & 1 deletion src/plugins/vis_types/table/public/components/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

import { i18n } from '@kbn/i18n';
import type { DatatableRow } from '@kbn/expressions-plugin/common';
import { AggTypes } from '../../common';

const totalAggregations = [
Expand Down Expand Up @@ -42,4 +43,31 @@ const totalAggregations = [
},
];

export { totalAggregations };
const sortNullsLast = (
rows: DatatableRow[],
direction: 'asc' | 'desc',
id: string
): DatatableRow[] => {
return rows.sort((row1, row2) => {
const rowA = row1[id];
const rowB = row2[id];

if (rowA === null) {
return 1;
}
if (rowB === null) {
return -1;
}
if (rowA === rowB) {
return 0;
}

if (direction === 'desc') {
return rowA < rowB ? 1 : -1;
} else {
return rowA < rowB ? -1 : 1;
}
});
};

export { totalAggregations, sortNullsLast };

0 comments on commit 8f4b366

Please sign in to comment.