[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/>
`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 the table with a specified key and direction (ascending or descending).
`sort(key?: string, direction?: string, options?: Intl.CollatorOptions): void;`<br/>
Sort the table with a specified key, direction (ascending or descending) and options (eg. numeric).
## Details

View File

@ -752,13 +752,13 @@ describe('DataTable', () => {
dataTable.ngAfterViewInit();
const adapter = dataTable.data;
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');
headerColumns[0].click();
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', () => {
@ -767,7 +767,7 @@ describe('DataTable', () => {
dataTable.ngAfterViewInit();
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, 'getSorting').and.returnValue(sorting);
const headerColumns = fixture.debugElement.nativeElement.querySelectorAll('.adf-datatable-cell-header-content');
@ -776,14 +776,14 @@ describe('DataTable', () => {
headerColumns[0].click();
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
sorting.direction = 'desc';
headerColumns[0].click();
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', () => {

View File

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

View File

@ -18,6 +18,8 @@
export class DataSorting {
constructor(
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(
jasmine.objectContaining({
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();
expect(rows[0].getValue('id')).toBe(2);
@ -238,7 +241,7 @@ describe('ObjectDataTableAdapter', () => {
{ id: 50 }
],[{key: 'id'} as DataColumn]);
adapter.setSorting(new DataSorting('id', 'asc'));
adapter.setSorting(new DataSorting('id', 'asc', { numeric: true }));
const rowsAsc = adapter.getRows();
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()[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()[1].getValue('id')).toBe(1);
});
@ -290,7 +293,8 @@ describe('ObjectDataTableAdapter', () => {
expect(adapter.getSorting()).toEqual(
jasmine.objectContaining({
key: 'id',
direction: 'asc'
direction: 'asc',
options: { numeric: true }
})
);
});
@ -304,7 +308,8 @@ describe('ObjectDataTableAdapter', () => {
expect(adapter.getSorting()).toEqual(
jasmine.objectContaining({
key: 'id',
direction: 'desc'
direction: 'desc',
options: { numeric: true }
})
);
});

View File

@ -121,35 +121,33 @@ export class ObjectDataTableAdapter implements DataTableAdapter {
if (sorting?.key) {
this._rows.sort((a: DataRow, b: DataRow) => {
let left = a.getValue(sorting.key);
let right = b.getValue(sorting.key);
let left = a.getValue(sorting.key) ?? '';
let right = b.getValue(sorting.key) ?? '';
if (typeof left === 'number' && typeof right === 'number') {
return sorting.direction === 'asc' ? left - right : right - left;
} else {
if (left) {
left = left instanceof Date ? left.valueOf().toString() : left.toString();
} else {
left = '';
if (typeof left !== 'string') {
left = left.valueOf().toString();
}
if (right) {
right = right instanceof Date ? right.valueOf().toString() : right.toString();
} else {
right = '';
if (typeof right !== 'string') {
right = right.valueOf().toString();
}
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();
if (key) {
sorting.key = key;
sorting.direction = direction || 'asc';
sorting.options = {
numeric: true,
...options
};
}
this.setSorting(sorting);
}