diff --git a/lib/core/datatable/components/datatable/datatable.component.ts b/lib/core/datatable/components/datatable/datatable.component.ts index 0b48fa4210..2c9e962295 100644 --- a/lib/core/datatable/components/datatable/datatable.component.ts +++ b/lib/core/datatable/components/datatable/datatable.component.ts @@ -253,6 +253,7 @@ export class DataTableComponent implements AfterContentInit, OnChanges, DoCheck, this.resetSelection(); } else if (rowChanges) { this.setTableRows(changes['rows'].currentValue); + this.setTableSorting(this.sorting); } else { this.setTableColumns(changes['columns'].currentValue); } @@ -544,6 +545,7 @@ export class DataTableComponent implements AfterContentInit, OnChanges, DoCheck, if (current && column.key === current.key) { newDirection = current.direction === 'asc' ? 'desc' : 'asc'; } + this.sorting = [column.key, newDirection]; this.data.setSorting(new DataSorting(column.key, newDirection)); this.emitSortingChangedEvent(column.key, newDirection); } diff --git a/lib/process-services-cloud/src/lib/process/process-list/components/process-list-cloud.component.html b/lib/process-services-cloud/src/lib/process/process-list/components/process-list-cloud.component.html index 70a8338452..b8884e6937 100644 --- a/lib/process-services-cloud/src/lib/process/process-list/components/process-list-cloud.component.html +++ b/lib/process-services-cloud/src/lib/process/process-list/components/process-list-cloud.component.html @@ -3,6 +3,7 @@ [columns]="columns" [stickyHeader]="stickyHeader" [loading]="isLoading" + [sorting]="formattedSorting" [selectionMode]="selectionMode" [multiselect]="multiselect" [actions]="showActions" @@ -14,7 +15,8 @@ (rowClick)="onRowClick($event)" (row-select)="onRowSelect($event)" (row-unselect)="onRowUnselect($event)" - (row-keyup)="onRowKeyUp($event)"> + (row-keyup)="onRowKeyUp($event)" + (sorting-changed)="onSortingChanged($event)"> { expect(component.isListEmpty()).toBeFalsy(); expect(getProcessByRequestSpy).toHaveBeenCalled(); }); + + it('should set formattedSorting if sorting input changes', () => { + spyOn(processListCloudService, 'getProcessByRequest').and.returnValue(of(fakeProcessCloudList)); + spyOn(component, 'formatSorting').and.callThrough(); + + component.appName = 'mock-app-name'; + const mockSort = [ + new ProcessListCloudSortingModel({ + orderBy: 'startDate', + direction: 'DESC' + }) + ]; + const sortChange = new SimpleChange(undefined, mockSort, true); + component.ngOnChanges({ + 'sorting': sortChange + }); + fixture.detectChanges(); + expect(component.formatSorting).toHaveBeenCalledWith(mockSort); + expect(component.formattedSorting).toEqual([ProcessListCloudComponent.ENTRY_PREFIX + 'startDate', 'desc']); + }); + + it('should reload process list when sorting on a column changes', () => { + const getProcessByRequestSpy = spyOn(processListCloudService, 'getProcessByRequest').and.returnValue(of(fakeProcessCloudList)); + component.onSortingChanged(new CustomEvent('sorting-changed', { + detail: { + key: 'fakeName', + direction: 'asc' + }, + bubbles: true + })); + fixture.detectChanges(); + expect(component.sorting).toEqual([ + new ProcessListCloudSortingModel({ + orderBy: 'fakeName', + direction: 'ASC' + }) + ]); + expect(component.formattedSorting).toEqual(['entry.fakeName', 'asc']); + expect(component.isListEmpty()).toBeFalsy(); + expect(getProcessByRequestSpy).toHaveBeenCalled(); + }); }); describe('Injecting custom colums for tasklist - CustomTaskListComponent', () => { diff --git a/lib/process-services-cloud/src/lib/process/process-list/components/process-list-cloud.component.ts b/lib/process-services-cloud/src/lib/process/process-list/components/process-list-cloud.component.ts index 68e46593cc..fa3bb6c9fc 100644 --- a/lib/process-services-cloud/src/lib/process/process-list/components/process-list-cloud.component.ts +++ b/lib/process-services-cloud/src/lib/process/process-list/components/process-list-cloud.component.ts @@ -35,6 +35,7 @@ import { ProcessListCloudSortingModel } from '../models/process-list-sorting.mod export class ProcessListCloudComponent extends DataTableSchema implements OnChanges, AfterContentInit, PaginatedComponent { static PRESET_KEY = 'adf-cloud-process-list.presets'; + static ENTRY_PREFIX = 'entry.'; @ContentChild(CustomEmptyContentTemplateDirective) emptyCustomContent: CustomEmptyContentTemplateDirective; @@ -156,7 +157,9 @@ export class ProcessListCloudComponent extends DataTableSchema implements OnChan selectedInstances: any[]; isLoading = true; rows: any[] = []; + formattedSorting: any[]; requestNode: ProcessQueryCloudRequestModel; + private defaultSorting = { key: 'startDate', direction: 'desc' }; constructor(private processListCloudService: ProcessListCloudService, appConfigService: AppConfigService, @@ -178,7 +181,10 @@ export class ProcessListCloudComponent extends DataTableSchema implements OnChan } ngOnChanges(changes: SimpleChanges) { - if (this.isPropertyChanged(changes)) { + if (this.isPropertyChanged(changes, 'sorting')) { + this.formatSorting(changes['sorting'].currentValue); + } + if (this.isAnyPropertyChanged(changes)) { this.reload(); } } @@ -210,18 +216,19 @@ export class ProcessListCloudComponent extends DataTableSchema implements OnChan }); } - private isPropertyChanged(changes: SimpleChanges): boolean { + private isAnyPropertyChanged(changes: SimpleChanges): boolean { for (const property in changes) { - if (changes.hasOwnProperty(property)) { - if (changes[property] && - (changes[property].currentValue !== changes[property].previousValue)) { - return true; - } + if (this.isPropertyChanged(changes, property)) { + return true; } } return false; } + private isPropertyChanged(changes: SimpleChanges, property: string): boolean { + return changes.hasOwnProperty(property); + } + isListEmpty(): boolean { return !this.rows || this.rows.length === 0; } @@ -233,6 +240,12 @@ export class ProcessListCloudComponent extends DataTableSchema implements OnChan this.reload(); } + onSortingChanged(event: CustomEvent) { + this.setSorting(event.detail); + this.formatSorting(this.sorting); + this.reload(); + } + onRowClick(item: DataRowEvent) { this.currentInstanceId = item.value.getValue('entry.id'); this.rowClick.emit(this.currentInstanceId); @@ -288,4 +301,18 @@ export class ProcessListCloudComponent extends DataTableSchema implements OnChan return new ProcessQueryCloudRequestModel(requestNode); } + setSorting(sortDetail) { + const sorting = sortDetail ? { + orderBy: sortDetail.key.replace(ProcessListCloudComponent.ENTRY_PREFIX, ''), + direction: sortDetail.direction.toUpperCase() + } : { ... this.defaultSorting }; + this.sorting = [new ProcessListCloudSortingModel(sorting)]; + } + + formatSorting(sorting: ProcessListCloudSortingModel[]) { + this.formattedSorting = sorting.length ? [ + ProcessListCloudComponent.ENTRY_PREFIX + sorting[0].orderBy, + sorting[0].direction.toLocaleLowerCase() + ] : null; + } } diff --git a/lib/process-services-cloud/src/lib/task/task-list/components/task-list-cloud.component.html b/lib/process-services-cloud/src/lib/task/task-list/components/task-list-cloud.component.html index e23cd277db..f70b432ca3 100644 --- a/lib/process-services-cloud/src/lib/task/task-list/components/task-list-cloud.component.html +++ b/lib/process-services-cloud/src/lib/task/task-list/components/task-list-cloud.component.html @@ -4,6 +4,7 @@ [rows]="rows" [columns]="columns" [loading]="isLoading" + [sorting]="formattedSorting" [multiselect]="multiselect" [selectionMode]="selectionMode" [stickyHeader]="stickyHeader" @@ -16,7 +17,8 @@ (row-select)="onRowSelect($event)" (row-unselect)="onRowUnselect($event)" (rowClick)="onRowClick($event)" - (row-keyup)="onRowKeyUp($event)"> + (row-keyup)="onRowKeyUp($event)" + (sorting-changed)="onSortingChanged($event)"> diff --git a/lib/process-services-cloud/src/lib/task/task-list/components/task-list-cloud.component.spec.ts b/lib/process-services-cloud/src/lib/task/task-list/components/task-list-cloud.component.spec.ts index e46caf0e3a..8c9f47bec6 100644 --- a/lib/process-services-cloud/src/lib/task/task-list/components/task-list-cloud.component.spec.ts +++ b/lib/process-services-cloud/src/lib/task/task-list/components/task-list-cloud.component.spec.ts @@ -27,6 +27,7 @@ import { ProcessServiceCloudTestingModule } from '../../../testing/process-servi import { Person } from '@alfresco/js-api'; import { TaskListModule } from '@alfresco/adf-process-services'; import { TranslateModule } from '@ngx-translate/core'; +import { TaskListCloudSortingModel } from '../models/task-list-sorting.model'; @Component({ template: ` @@ -289,6 +290,47 @@ describe('TaskListCloudComponent', () => { expect(component.isListEmpty()).toBeFalsy(); expect(getTaskByRequestSpy).toHaveBeenCalled(); }); + + it('should set formattedSorting if sorting input changes', () => { + spyOn(taskListCloudService, 'getTaskByRequest').and.returnValue(of(fakeGlobalTask)); + spyOn(component, 'formatSorting').and.callThrough(); + + component.appName = 'mock-app-name'; + const mockSort = [ + new TaskListCloudSortingModel({ + orderBy: 'startDate', + direction: 'DESC' + }) + ]; + const sortChange = new SimpleChange(undefined, mockSort, true); + component.ngOnChanges({ + 'sorting': sortChange + }); + fixture.detectChanges(); + expect(component.formatSorting).toHaveBeenCalledWith(mockSort); + expect(component.formattedSorting).toEqual([TaskListCloudComponent.ENTRY_PREFIX + 'startDate', 'desc']); + }); + + it('should reload task list when sorting on a column changes', () => { + const getTaskByRequestSpy = spyOn(taskListCloudService, 'getTaskByRequest').and.returnValue(of(fakeGlobalTask)); + component.onSortingChanged(new CustomEvent('sorting-changed', { + detail: { + key: 'fakeName', + direction: 'asc' + }, + bubbles: true + })); + fixture.detectChanges(); + expect(component.sorting).toEqual([ + new TaskListCloudSortingModel({ + orderBy: 'fakeName', + direction: 'ASC' + }) + ]); + expect(component.formattedSorting).toEqual(['entry.fakeName', 'asc']); + expect(component.isListEmpty()).toBeFalsy(); + expect(getTaskByRequestSpy).toHaveBeenCalled(); + }); }); describe('Injecting custom colums for tasklist - CustomTaskListComponent', () => { diff --git a/lib/process-services-cloud/src/lib/task/task-list/components/task-list-cloud.component.ts b/lib/process-services-cloud/src/lib/task/task-list/components/task-list-cloud.component.ts index b163063cdc..2ff9876f1d 100644 --- a/lib/process-services-cloud/src/lib/task/task-list/components/task-list-cloud.component.ts +++ b/lib/process-services-cloud/src/lib/task/task-list/components/task-list-cloud.component.ts @@ -37,6 +37,7 @@ import { takeUntil } from 'rxjs/operators'; export class TaskListCloudComponent extends DataTableSchema implements OnChanges, AfterContentInit, PaginatedComponent, OnDestroy, OnInit { static PRESET_KEY = 'adf-cloud-task-list.presets'; + static ENTRY_PREFIX = 'entry.'; @ContentChild(CustomEmptyContentTemplateDirective) emptyCustomContent: CustomEmptyContentTemplateDirective; @@ -176,6 +177,8 @@ export class TaskListCloudComponent extends DataTableSchema implements OnChanges currentInstanceId: any; isLoading = true; selectedInstances: any[]; + formattedSorting: any[]; + private defaultSorting = { key: 'startDate', direction: 'desc' }; private onDestroy$ = new Subject(); @@ -201,7 +204,10 @@ export class TaskListCloudComponent extends DataTableSchema implements OnChanges } ngOnChanges(changes: SimpleChanges) { - if (this.isPropertyChanged(changes)) { + if (this.isPropertyChanged(changes, 'sorting')) { + this.formatSorting(changes['sorting'].currentValue); + } + if (this.isAnyPropertyChanged(changes)) { this.reload(); } } @@ -219,18 +225,19 @@ export class TaskListCloudComponent extends DataTableSchema implements OnChanges return this.currentInstanceId; } - private isPropertyChanged(changes: SimpleChanges): boolean { + private isAnyPropertyChanged(changes: SimpleChanges): boolean { for (const property in changes) { - if (changes.hasOwnProperty(property)) { - if (changes[property] && - (changes[property].currentValue !== changes[property].previousValue)) { - return true; - } + if (this.isPropertyChanged(changes, property)) { + return true; } } return false; } + private isPropertyChanged(changes: SimpleChanges, property: string): boolean { + return changes.hasOwnProperty(property); + } + reload() { this.requestNode = this.createRequestNode(); if (this.requestNode.appName || this.requestNode.appName === '') { @@ -265,6 +272,12 @@ export class TaskListCloudComponent extends DataTableSchema implements OnChanges this.reload(); } + onSortingChanged(event: CustomEvent) { + this.setSorting(event.detail); + this.formatSorting(this.sorting); + this.reload(); + } + onRowClick(item: DataRowEvent) { this.currentInstanceId = item.value.getValue('entry.id'); this.rowClick.emit(this.currentInstanceId); @@ -324,4 +337,19 @@ export class TaskListCloudComponent extends DataTableSchema implements OnChanges }; return new TaskQueryCloudRequestModel(requestNode); } + + setSorting(sortDetail) { + const sorting = sortDetail ? { + orderBy: sortDetail.key.replace(TaskListCloudComponent.ENTRY_PREFIX, ''), + direction: sortDetail.direction.toUpperCase() + } : { ... this.defaultSorting }; + this.sorting = [new TaskListCloudSortingModel(sorting)]; + } + + formatSorting(sorting: TaskListCloudSortingModel[]) { + this.formattedSorting = sorting.length ? [ + TaskListCloudComponent.ENTRY_PREFIX + sorting[0].orderBy, + sorting[0].direction.toLocaleLowerCase() + ] : null; + } }