Skip to content

Commit

Permalink
Made datagrid's numeric sorting work against all digit groups in a va…
Browse files Browse the repository at this point in the history
…lue instead of the first float value found
  • Loading branch information
chandlerprall committed Dec 6, 2019
1 parent a0b3b70 commit 395048d
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 7 deletions.
48 changes: 48 additions & 0 deletions src/components/datagrid/data_grid.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1404,6 +1404,54 @@ Array [
['0', '9'],
]);
});

it('sorts with all digit groups in numerical-like', () => {
const onSort = jest.fn(columns => {
component.setProps({ sorting: { columns, onSort } });
component.update();
});

const component = mount(
<EuiDataGrid
aria-label="test"
columns={[{ id: 'version' }]}
columnVisibility={{
visibleColumns: ['version'],
setVisibleColumns: () => {},
}}
rowCount={5}
renderCellValue={
({ rowIndex }) => `1.0.${(rowIndex % 3) + rowIndex}` // computes as 0,2,4,3,5
}
inMemory={{ level: 'sorting' }}
sorting={{
columns: [],
onSort,
}}
/>
);

// verify rows are unordered
expect(extractGridData(component)).toEqual([
['version'],
['1.0.0'],
['1.0.2'],
['1.0.4'],
['1.0.3'],
['1.0.5'],
]);

sortByColumn(component, 'version', 'asc');

expect(extractGridData(component)).toEqual([
['version'],
['1.0.0'],
['1.0.2'],
['1.0.3'],
['1.0.4'],
['1.0.5'],
]);
});
});

it('uses schema information to sort', () => {
Expand Down
25 changes: 18 additions & 7 deletions src/components/datagrid/data_grid_schema.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -167,14 +167,25 @@ export const schemaDetectors: EuiDataGridSchemaDetector[] = [
return matchLength / value.length || 0;
},
comparator: (a, b, direction) => {
const aChars = a.split('').filter(char => numericChars.has(char));
const aValue = parseFloat(aChars.join(''));

const bChars = b.split('').filter(char => numericChars.has(char));
const bValue = parseFloat(bChars.join(''));
// sort on all digits groups
const aGroups = a.split(/\D+/);
const bGroups = b.split(/\D+/);

const maxGroups = Math.max(aGroups.length, bGroups.length);
for (let i = 0; i < maxGroups; i++) {
// if A and B's group counts differ and they match until that difference, prefer whichever is shorter
if (i >= aGroups.length) return direction === 'asc' ? -1 : 1;
if (i >= bGroups.length) return direction === 'asc' ? 1 : -1;

const aChars = aGroups[i];
const bChars = bGroups[i];
const aValue = parseInt(aChars, 10);
const bValue = parseInt(bChars, 10);

if (aValue < bValue) return direction === 'asc' ? -1 : 1;
if (aValue > bValue) return direction === 'asc' ? 1 : -1;
}

if (aValue < bValue) return direction === 'asc' ? -1 : 1;
if (aValue > bValue) return direction === 'asc' ? 1 : -1;
return 0;
},
icon: 'number',
Expand Down

0 comments on commit 395048d

Please sign in to comment.