From c9520bb29bd7f6c66db670a2c58992bf2922baab Mon Sep 17 00:00:00 2001 From: Alex Molodyh Date: Thu, 21 Nov 2024 09:36:18 -0800 Subject: [PATCH 1/2] [AAE-22900] Update ObjectDataTableAdapter to support server and client sorting modes --- .../data/object-datatable-adapter.spec.ts | 87 ++++++++++--------- .../data/object-datatable-adapter.ts | 10 ++- .../process-list-datatable-adapter.spec.ts | 5 ++ .../process-list-datatable-adapter.ts | 2 +- .../task-list-datatable-adapter.spec.ts | 5 ++ .../datatable/task-list-datatable-adapter.ts | 2 +- 6 files changed, 69 insertions(+), 42 deletions(-) diff --git a/lib/core/src/lib/datatable/data/object-datatable-adapter.spec.ts b/lib/core/src/lib/datatable/data/object-datatable-adapter.spec.ts index ba2064c390c..7dfbd6bb5ad 100644 --- a/lib/core/src/lib/datatable/data/object-datatable-adapter.spec.ts +++ b/lib/core/src/lib/datatable/data/object-datatable-adapter.spec.ts @@ -23,7 +23,6 @@ import { ObjectDataRow } from './object-datarow.model'; import { ObjectDataColumn } from './object-datacolumn.model'; describe('ObjectDataTableAdapter', () => { - it('should init with empty row collection', () => { const adapter = new ObjectDataTableAdapter(null, []); expect(adapter.getRows()).toBeDefined(); @@ -46,10 +45,7 @@ describe('ObjectDataTableAdapter', () => { }); it('should map columns without rows', () => { - const adapter = new ObjectDataTableAdapter(null, [ - {} as DataColumn, - {} as DataColumn - ]); + const adapter = new ObjectDataTableAdapter(null, [{} as DataColumn, {} as DataColumn]); const columns = adapter.getColumns(); expect(columns.length).toBe(2); @@ -99,7 +95,7 @@ describe('ObjectDataTableAdapter', () => { it('should apply new columns array', () => { const adapter = new ObjectDataTableAdapter([], []); - const columns = [{},{}] as DataColumn[]; + const columns = [{}, {}] as DataColumn[]; adapter.setColumns(columns); expect(adapter.getColumns()).toBe(columns); @@ -116,10 +112,7 @@ describe('ObjectDataTableAdapter', () => { }); it('should reset columns by null value', () => { - const adapter = new ObjectDataTableAdapter([], [ - {} as DataColumn, - {} as DataColumn - ]); + const adapter = new ObjectDataTableAdapter([], [{} as DataColumn, {} as DataColumn]); expect(adapter.getColumns()).toBeDefined(); expect(adapter.getColumns().length).toBe(2); @@ -188,9 +181,7 @@ describe('ObjectDataTableAdapter', () => { { id: 2, name: 'abs' }, { id: 1, name: 'xyz' } ], - [ - new ObjectDataColumn({ key: 'id', sortable: true }) - ] + [new ObjectDataColumn({ key: 'id', sortable: true })] ); const rows = adapter.getRows(); @@ -199,10 +190,7 @@ describe('ObjectDataTableAdapter', () => { }); it('should take first sortable column by default', () => { - const adapter = new ObjectDataTableAdapter([], [ - { key: 'icon' } as DataColumn, - new ObjectDataColumn({ key: 'id', sortable: true }) - ]); + const adapter = new ObjectDataTableAdapter([], [{ key: 'icon' } as DataColumn, new ObjectDataColumn({ key: 'id', sortable: true })]); expect(adapter.getSorting()).toEqual( jasmine.objectContaining({ @@ -221,10 +209,7 @@ describe('ObjectDataTableAdapter', () => { { id: 1, created: new Date(2016, 7, 6, 15, 7, 2) }, { id: 2, created: new Date(2016, 7, 6, 15, 7, 1) } ], - [ - { key: 'id' } as DataColumn, - { key: 'created' } as DataColumn - ] + [{ key: 'id' } as DataColumn, { key: 'created' } as DataColumn] ); adapter.setSorting(new DataSorting('created', 'asc', { numeric: true })); @@ -235,11 +220,7 @@ describe('ObjectDataTableAdapter', () => { }); it('should sort by numbers', () => { - const adapter = new ObjectDataTableAdapter([ - { id: 123 }, - { id: 38 }, - { id: 50 } - ],[{key: 'id'} as DataColumn]); + const adapter = new ObjectDataTableAdapter([{ id: 123 }, { id: 38 }, { id: 50 }], [{ key: 'id' } as DataColumn]); adapter.setSorting(new DataSorting('id', 'asc', { numeric: true })); @@ -255,10 +236,7 @@ describe('ObjectDataTableAdapter', () => { { id: 2, name: 'abs' }, { id: 1, name: 'xyz' } ], - [ - new ObjectDataColumn({ key: 'id' }), - new ObjectDataColumn({ key: 'name' }) - ] + [new ObjectDataColumn({ key: 'id' }), new ObjectDataColumn({ key: 'name' })] ); expect(adapter.getSorting()).toBeUndefined(); @@ -270,9 +248,7 @@ describe('ObjectDataTableAdapter', () => { { id: 2, name: 'abs' }, { id: 1, name: 'xyz' } ], - [ - new ObjectDataColumn({ key: 'id', sortable: true }) - ] + [new ObjectDataColumn({ key: 'id', sortable: true })] ); adapter.setSorting(new DataSorting('id', 'asc', { numeric: true })); @@ -313,10 +289,43 @@ describe('ObjectDataTableAdapter', () => { }) ); }); + + it('should not sort rows ascending when in server sorting mode', () => { + const adapter = new ObjectDataTableAdapter( + [ + { id: 2, name: 'abs' }, + { id: 1, name: 'xyz' } + ], + [new ObjectDataColumn({ key: 'id', sortable: true })], + 'server' + ); + + adapter.setSorting(new DataSorting('id', 'asc', { numeric: true })); + + const rows = adapter.getRows(); + expect(rows[0].getValue('id')).toBe(2); + expect(rows[1].getValue('id')).toBe(1); + }); + + it('should not sort rows descending when in server sorting mode', () => { + const adapter = new ObjectDataTableAdapter( + [ + { id: 1, name: 'xyz' }, + { id: 2, name: 'abs' } + ], + [new ObjectDataColumn({ key: 'id', sortable: true })], + 'server' + ); + + adapter.setSorting(new DataSorting('id ', 'desc', { numeric: true })); + + const rows = adapter.getRows(); + expect(rows[0].getValue('id')).toBe(1); + expect(rows[1].getValue('id')).toBe(2); + }); }); describe('ObjectDataRow', () => { - it('should require object source', () => { expect(() => new ObjectDataRow(null)).toThrowError('Object source not found'); }); @@ -335,10 +344,10 @@ describe('ObjectDataRow', () => { it('should get nested property value', () => { const row = new ObjectDataRow({ - name: { - firstName: 'John', - lastName: 'Doe' - } + name: { + firstName: 'John', + lastName: 'Doe' + } }); expect(row.getValue('name.lastName')).toBe('Doe'); @@ -370,7 +379,7 @@ describe('ObjectDataRow', () => { }); it('should generateSchema generate a schema from data', () => { - const data = [ + const data = [ { id: 2, name: 'abs' }, { id: 1, name: 'xyz' } ]; diff --git a/lib/core/src/lib/datatable/data/object-datatable-adapter.ts b/lib/core/src/lib/datatable/data/object-datatable-adapter.ts index aea687446a6..f1fb9fcd02b 100644 --- a/lib/core/src/lib/datatable/data/object-datatable-adapter.ts +++ b/lib/core/src/lib/datatable/data/object-datatable-adapter.ts @@ -23,11 +23,14 @@ import { DataSorting } from './data-sorting.model'; import { DataTableAdapter } from './datatable-adapter'; import { Subject } from 'rxjs'; +export type SortingMode = 'client' | 'server'; + // Simple implementation of the DataTableAdapter interface. export class ObjectDataTableAdapter implements DataTableAdapter { private _sorting: DataSorting; private _rows: DataRow[]; private _columns: DataColumn[]; + private readonly _sortingMode: SortingMode; selectedRow: DataRow; rowsChanged: Subject>; @@ -54,9 +57,10 @@ export class ObjectDataTableAdapter implements DataTableAdapter { return schema; } - constructor(data: any[] = [], schema: DataColumn[] = []) { + constructor(data: any[] = [], schema: DataColumn[] = [], sortingMode: SortingMode = 'client') { this._rows = []; this._columns = []; + this._sortingMode = sortingMode?.toString().toLowerCase() === 'server' ? 'server' : 'client'; if (data && data.length > 0) { this._rows = data.map((item) => new ObjectDataRow(item)); @@ -119,6 +123,10 @@ export class ObjectDataTableAdapter implements DataTableAdapter { setSorting(sorting: DataSorting): void { this._sorting = sorting; + if (this._sortingMode === 'server') { + return; + } + if (sorting?.key) { this._rows.sort((a: DataRow, b: DataRow) => { let left = a.getValue(sorting.key) ?? ''; diff --git a/lib/process-services-cloud/src/lib/process/process-list/datatable/process-list-datatable-adapter.spec.ts b/lib/process-services-cloud/src/lib/process/process-list/datatable/process-list-datatable-adapter.spec.ts index e67d46a4fab..4164df47920 100644 --- a/lib/process-services-cloud/src/lib/process/process-list/datatable/process-list-datatable-adapter.spec.ts +++ b/lib/process-services-cloud/src/lib/process/process-list/datatable/process-list-datatable-adapter.spec.ts @@ -50,4 +50,9 @@ describe('ProcessListDatatableAdapter', () => { expect(adapter.getColumnType(row, column)).toBe('number'); }); + + it('should initialize constructor with server sortingMode', () => { + const adapter = new ProcessListDatatableAdapter([], []); + expect(adapter['_sortingMode']).toBe('server'); + }); }); diff --git a/lib/process-services-cloud/src/lib/process/process-list/datatable/process-list-datatable-adapter.ts b/lib/process-services-cloud/src/lib/process/process-list/datatable/process-list-datatable-adapter.ts index 836b6e257df..d4ed6c4b98d 100644 --- a/lib/process-services-cloud/src/lib/process/process-list/datatable/process-list-datatable-adapter.ts +++ b/lib/process-services-cloud/src/lib/process/process-list/datatable/process-list-datatable-adapter.ts @@ -21,7 +21,7 @@ import { ProcessInstanceCloudListViewModel } from '../models/perocess-instance-c export class ProcessListDatatableAdapter extends ObjectDataTableAdapter { constructor(data: ProcessInstanceCloudListViewModel[], schema: DataColumn[]) { - super(data, schema); + super(data, schema, 'server'); } getColumnType(row: DataRow, col: DataColumn): string { diff --git a/lib/process-services-cloud/src/lib/task/task-list/datatable/task-list-datatable-adapter.spec.ts b/lib/process-services-cloud/src/lib/task/task-list/datatable/task-list-datatable-adapter.spec.ts index 10d5e7a375c..16a9089eb3d 100644 --- a/lib/process-services-cloud/src/lib/task/task-list/datatable/task-list-datatable-adapter.spec.ts +++ b/lib/process-services-cloud/src/lib/task/task-list/datatable/task-list-datatable-adapter.spec.ts @@ -60,4 +60,9 @@ describe('TasksListDatatableAdapter', () => { expect(adapter.getColumnType(row, column)).toBe('number'); }); + + it('should initialize constructor with server sortingMode', () => { + const adapter = new TasksListDatatableAdapter([], []); + expect(adapter['_sortingMode']).toBe('server'); + }); }); diff --git a/lib/process-services-cloud/src/lib/task/task-list/datatable/task-list-datatable-adapter.ts b/lib/process-services-cloud/src/lib/task/task-list/datatable/task-list-datatable-adapter.ts index d338edd88fb..75f1edb98b9 100644 --- a/lib/process-services-cloud/src/lib/task/task-list/datatable/task-list-datatable-adapter.ts +++ b/lib/process-services-cloud/src/lib/task/task-list/datatable/task-list-datatable-adapter.ts @@ -21,7 +21,7 @@ import { TaskInstanceCloudListViewModel } from '../models/task-cloud-view.model' export class TasksListDatatableAdapter extends ObjectDataTableAdapter { constructor(data: TaskInstanceCloudListViewModel[], schema: DataColumn[]) { - super(data, schema); + super(data, schema, 'server'); } getColumnType(row: DataRow, col: DataColumn): string { From d3353f49615983c565f82cb6cce43568d1a7f644 Mon Sep 17 00:00:00 2001 From: Alex Molodyh Date: Fri, 22 Nov 2024 07:59:35 -0800 Subject: [PATCH 2/2] [AAE-22900] PR comments update - only checking for falsy sortingMode --- lib/core/src/lib/datatable/data/object-datatable-adapter.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/core/src/lib/datatable/data/object-datatable-adapter.ts b/lib/core/src/lib/datatable/data/object-datatable-adapter.ts index f1fb9fcd02b..91df2698322 100644 --- a/lib/core/src/lib/datatable/data/object-datatable-adapter.ts +++ b/lib/core/src/lib/datatable/data/object-datatable-adapter.ts @@ -60,7 +60,10 @@ export class ObjectDataTableAdapter implements DataTableAdapter { constructor(data: any[] = [], schema: DataColumn[] = [], sortingMode: SortingMode = 'client') { this._rows = []; this._columns = []; - this._sortingMode = sortingMode?.toString().toLowerCase() === 'server' ? 'server' : 'client'; + + if (!sortingMode) { + sortingMode = 'client'; + } if (data && data.length > 0) { this._rows = data.map((item) => new ObjectDataRow(item));