[ACS-5704][Community request] ObjectDataTableAdapter sorting (#9272)

* [ACS-5704] change table sorting

* [ACS-5704] change table sorting

* [ACS-5704] change table sorting

* [ci:force] fix integer mapping

* [ACS-5704] set alphanumeric sorting as default
This commit is contained in:
tamaragruszka 2024-02-09 17:07:19 +01:00 committed by GitHub
parent cddbcc0700
commit 01b6bc6417
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 43 additions and 38 deletions

View File

@ -35,10 +35,10 @@ Get the data value from a specific table cell.
`getSorting():`[`DataSorting`](../../../lib/core/src/lib/datatable/data/data-sorting.model.ts)`;`<br/> `getSorting():`[`DataSorting`](../../../lib/core/src/lib/datatable/data/data-sorting.model.ts)`;`<br/>
`setSorting(sorting: DataSorting): void;`<br/> `setSorting(sorting: DataSorting): void;`<br/>
Get/set the sorting key and direction (ascending or descending). Get/set the sorting key, direction (ascending or descending) and options (eg. numeric).
`sort(key?: string, direction?: string): void;`<br/> `sort(key?: string, direction?: string, options?: Intl.CollatorOptions): void;`<br/>
Sort the table with a specified key and direction (ascending or descending). Sort the table with a specified key, direction (ascending or descending) and options (eg. numeric).
## Details ## Details

View File

@ -752,13 +752,13 @@ describe('DataTable', () => {
dataTable.ngAfterViewInit(); dataTable.ngAfterViewInit();
const adapter = dataTable.data; const adapter = dataTable.data;
spyOn(adapter, 'setSorting').and.callThrough(); spyOn(adapter, 'setSorting').and.callThrough();
spyOn(dataTable.data, 'getSorting').and.returnValue(new DataSorting('column_1', 'desc')); spyOn(dataTable.data, 'getSorting').and.returnValue(new DataSorting('column_1', 'desc', { numeric: true }));
const headerColumns = fixture.debugElement.nativeElement.querySelectorAll('.adf-datatable-cell-header-content'); const headerColumns = fixture.debugElement.nativeElement.querySelectorAll('.adf-datatable-cell-header-content');
headerColumns[0].click(); headerColumns[0].click();
fixture.detectChanges(); fixture.detectChanges();
expect(adapter.setSorting).toHaveBeenCalledWith(new DataSorting('column_1', 'asc')); expect(adapter.setSorting).toHaveBeenCalledWith(new DataSorting('column_1', 'asc', { numeric: true }));
}); });
it('should invert sorting upon column header clicked', () => { it('should invert sorting upon column header clicked', () => {
@ -767,7 +767,7 @@ describe('DataTable', () => {
dataTable.ngAfterViewInit(); dataTable.ngAfterViewInit();
const adapter = dataTable.data; const adapter = dataTable.data;
const sorting = new DataSorting('column_1', 'asc'); const sorting = new DataSorting('column_1', 'asc', { numeric: true });
spyOn(adapter, 'setSorting').and.callThrough(); spyOn(adapter, 'setSorting').and.callThrough();
spyOn(adapter, 'getSorting').and.returnValue(sorting); spyOn(adapter, 'getSorting').and.returnValue(sorting);
const headerColumns = fixture.debugElement.nativeElement.querySelectorAll('.adf-datatable-cell-header-content'); const headerColumns = fixture.debugElement.nativeElement.querySelectorAll('.adf-datatable-cell-header-content');
@ -776,14 +776,14 @@ describe('DataTable', () => {
headerColumns[0].click(); headerColumns[0].click();
fixture.detectChanges(); fixture.detectChanges();
expect(adapter.setSorting).toHaveBeenCalledWith(new DataSorting('column_1', 'desc')); expect(adapter.setSorting).toHaveBeenCalledWith(new DataSorting('column_1', 'desc', { numeric: true }));
// check second click on the header // check second click on the header
sorting.direction = 'desc'; sorting.direction = 'desc';
headerColumns[0].click(); headerColumns[0].click();
fixture.detectChanges(); fixture.detectChanges();
expect(adapter.setSorting).toHaveBeenCalledWith(new DataSorting('column_1', 'asc')); expect(adapter.setSorting).toHaveBeenCalledWith(new DataSorting('column_1', 'asc', { numeric: true }));
}); });
it('should indicate column that has sorting applied', () => { it('should indicate column that has sorting applied', () => {

View File

@ -395,7 +395,7 @@ export class DataTableComponent implements OnInit, AfterContentInit, OnChanges,
convertToDataSorting(sorting: any[]): DataSorting | null { convertToDataSorting(sorting: any[]): DataSorting | null {
if (sorting && sorting.length > 0) { if (sorting && sorting.length > 0) {
return new DataSorting(sorting[0], sorting[1]); return new DataSorting(sorting[0], sorting[1], sorting[2]);
} }
return null; return null;
} }
@ -639,8 +639,8 @@ export class DataTableComponent implements OnInit, AfterContentInit, OnChanges,
if (current && column.key === current.key) { if (current && column.key === current.key) {
newDirection = current.direction?.toLowerCase() === 'asc' ? 'desc' : 'asc'; newDirection = current.direction?.toLowerCase() === 'asc' ? 'desc' : 'asc';
} }
this.sorting = [column.key, newDirection]; this.sorting = [column.key, newDirection, { numeric: true }];
this.data.setSorting(new DataSorting(column.key, newDirection)); this.data.setSorting(new DataSorting(column.key, newDirection, { numeric: true }));
this.emitSortingChangedEvent(column.key, column.sortingKey, newDirection); this.emitSortingChangedEvent(column.key, column.sortingKey, newDirection);
} }

View File

@ -18,6 +18,8 @@
export class DataSorting { export class DataSorting {
constructor( constructor(
public key?: string, public key?: string,
public direction?: string) { public direction?: string,
public options?: Intl.CollatorOptions
) {
} }
} }

View File

@ -207,7 +207,10 @@ describe('ObjectDataTableAdapter', () => {
expect(adapter.getSorting()).toEqual( expect(adapter.getSorting()).toEqual(
jasmine.objectContaining({ jasmine.objectContaining({
key: 'id', key: 'id',
direction: 'asc' direction: 'asc',
options: {
numeric: true
}
}) })
); );
}); });
@ -224,7 +227,7 @@ describe('ObjectDataTableAdapter', () => {
] ]
); );
adapter.setSorting(new DataSorting('created', 'asc')); adapter.setSorting(new DataSorting('created', 'asc', { numeric: true }));
const rows = adapter.getRows(); const rows = adapter.getRows();
expect(rows[0].getValue('id')).toBe(2); expect(rows[0].getValue('id')).toBe(2);
@ -238,7 +241,7 @@ describe('ObjectDataTableAdapter', () => {
{ id: 50 } { id: 50 }
],[{key: 'id'} as DataColumn]); ],[{key: 'id'} as DataColumn]);
adapter.setSorting(new DataSorting('id', 'asc')); adapter.setSorting(new DataSorting('id', 'asc', { numeric: true }));
const rowsAsc = adapter.getRows(); const rowsAsc = adapter.getRows();
expect(rowsAsc[0].getValue('id')).toBe(38); expect(rowsAsc[0].getValue('id')).toBe(38);
@ -272,11 +275,11 @@ describe('ObjectDataTableAdapter', () => {
] ]
); );
adapter.setSorting(new DataSorting('id', 'asc')); adapter.setSorting(new DataSorting('id', 'asc', { numeric: true }));
expect(adapter.getRows()[0].getValue('id')).toBe(1); expect(adapter.getRows()[0].getValue('id')).toBe(1);
expect(adapter.getRows()[1].getValue('id')).toBe(2); expect(adapter.getRows()[1].getValue('id')).toBe(2);
adapter.setSorting(new DataSorting('id', 'desc')); adapter.setSorting(new DataSorting('id', 'desc', { numeric: true }));
expect(adapter.getRows()[0].getValue('id')).toBe(2); expect(adapter.getRows()[0].getValue('id')).toBe(2);
expect(adapter.getRows()[1].getValue('id')).toBe(1); expect(adapter.getRows()[1].getValue('id')).toBe(1);
}); });
@ -290,7 +293,8 @@ describe('ObjectDataTableAdapter', () => {
expect(adapter.getSorting()).toEqual( expect(adapter.getSorting()).toEqual(
jasmine.objectContaining({ jasmine.objectContaining({
key: 'id', key: 'id',
direction: 'asc' direction: 'asc',
options: { numeric: true }
}) })
); );
}); });
@ -304,7 +308,8 @@ describe('ObjectDataTableAdapter', () => {
expect(adapter.getSorting()).toEqual( expect(adapter.getSorting()).toEqual(
jasmine.objectContaining({ jasmine.objectContaining({
key: 'id', key: 'id',
direction: 'desc' direction: 'desc',
options: { numeric: true }
}) })
); );
}); });

View File

@ -121,35 +121,33 @@ export class ObjectDataTableAdapter implements DataTableAdapter {
if (sorting?.key) { if (sorting?.key) {
this._rows.sort((a: DataRow, b: DataRow) => { this._rows.sort((a: DataRow, b: DataRow) => {
let left = a.getValue(sorting.key); let left = a.getValue(sorting.key) ?? '';
let right = b.getValue(sorting.key); let right = b.getValue(sorting.key) ?? '';
if (typeof left === 'number' && typeof right === 'number') { if (typeof left !== 'string') {
return sorting.direction === 'asc' ? left - right : right - left; left = left.valueOf().toString();
} else {
if (left) {
left = left instanceof Date ? left.valueOf().toString() : left.toString();
} else {
left = '';
} }
if (right) { if (typeof right !== 'string') {
right = right instanceof Date ? right.valueOf().toString() : right.toString(); right = right.valueOf().toString();
} else {
right = '';
} }
return sorting.direction === 'asc' ? left.localeCompare(right) : right.localeCompare(left); return sorting.direction === 'asc'
} ? left.localeCompare(right, undefined, sorting.options)
: right.localeCompare(left, undefined, sorting.options);
}); });
} }
} }
sort(key?: string, direction?: string): void { sort(key?: string, direction?: string, options?: Intl.CollatorOptions): void {
const sorting = this._sorting || new DataSorting(); const sorting = this._sorting || new DataSorting();
if (key) { if (key) {
sorting.key = key; sorting.key = key;
sorting.direction = direction || 'asc'; sorting.direction = direction || 'asc';
sorting.options = {
numeric: true,
...options
};
} }
this.setSorting(sorting); this.setSorting(sorting);
} }