mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[ACA-3529] Custom filter doesn't work properly when Direction is set to ASC (#5829)
* [ACA-3479] Sort Order arrow not displayed in task and process list * Added unit tests * Fixed lint * Updated constant prefix * Added retention of sorting when ItemsPerPage changes * Removed unwanted changes check; Renamed sortInput * Updated unit tests * [ACA-3529] Custom filter doesn't work properly when Direction is set to "ASC" * Added server side sorting, when sort on column is changed * Added unit tests
This commit is contained in:
@@ -253,6 +253,7 @@ export class DataTableComponent implements AfterContentInit, OnChanges, DoCheck,
|
|||||||
this.resetSelection();
|
this.resetSelection();
|
||||||
} else if (rowChanges) {
|
} else if (rowChanges) {
|
||||||
this.setTableRows(changes['rows'].currentValue);
|
this.setTableRows(changes['rows'].currentValue);
|
||||||
|
this.setTableSorting(this.sorting);
|
||||||
} else {
|
} else {
|
||||||
this.setTableColumns(changes['columns'].currentValue);
|
this.setTableColumns(changes['columns'].currentValue);
|
||||||
}
|
}
|
||||||
@@ -544,6 +545,7 @@ export class DataTableComponent implements AfterContentInit, OnChanges, DoCheck,
|
|||||||
if (current && column.key === current.key) {
|
if (current && column.key === current.key) {
|
||||||
newDirection = current.direction === 'asc' ? 'desc' : 'asc';
|
newDirection = current.direction === 'asc' ? 'desc' : 'asc';
|
||||||
}
|
}
|
||||||
|
this.sorting = [column.key, newDirection];
|
||||||
this.data.setSorting(new DataSorting(column.key, newDirection));
|
this.data.setSorting(new DataSorting(column.key, newDirection));
|
||||||
this.emitSortingChangedEvent(column.key, newDirection);
|
this.emitSortingChangedEvent(column.key, newDirection);
|
||||||
}
|
}
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
[columns]="columns"
|
[columns]="columns"
|
||||||
[stickyHeader]="stickyHeader"
|
[stickyHeader]="stickyHeader"
|
||||||
[loading]="isLoading"
|
[loading]="isLoading"
|
||||||
|
[sorting]="formattedSorting"
|
||||||
[selectionMode]="selectionMode"
|
[selectionMode]="selectionMode"
|
||||||
[multiselect]="multiselect"
|
[multiselect]="multiselect"
|
||||||
[actions]="showActions"
|
[actions]="showActions"
|
||||||
@@ -14,7 +15,8 @@
|
|||||||
(rowClick)="onRowClick($event)"
|
(rowClick)="onRowClick($event)"
|
||||||
(row-select)="onRowSelect($event)"
|
(row-select)="onRowSelect($event)"
|
||||||
(row-unselect)="onRowUnselect($event)"
|
(row-unselect)="onRowUnselect($event)"
|
||||||
(row-keyup)="onRowKeyUp($event)">
|
(row-keyup)="onRowKeyUp($event)"
|
||||||
|
(sorting-changed)="onSortingChanged($event)">
|
||||||
<adf-loading-content-template>
|
<adf-loading-content-template>
|
||||||
<ng-template>
|
<ng-template>
|
||||||
<mat-progress-spinner
|
<mat-progress-spinner
|
||||||
|
@@ -29,6 +29,7 @@ import { fakeCustomSchema, fakeProcessCloudList, processListSchemaMock } from '.
|
|||||||
import { of } from 'rxjs';
|
import { of } from 'rxjs';
|
||||||
import { ProcessServiceCloudTestingModule } from '../../../testing/process-service-cloud.testing.module';
|
import { ProcessServiceCloudTestingModule } from '../../../testing/process-service-cloud.testing.module';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { ProcessListCloudSortingModel } from '../models/process-list-sorting.model';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
template: `
|
template: `
|
||||||
@@ -249,6 +250,47 @@ describe('ProcessListCloudComponent', () => {
|
|||||||
expect(component.isListEmpty()).toBeFalsy();
|
expect(component.isListEmpty()).toBeFalsy();
|
||||||
expect(getProcessByRequestSpy).toHaveBeenCalled();
|
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', () => {
|
describe('Injecting custom colums for tasklist - CustomTaskListComponent', () => {
|
||||||
|
@@ -35,6 +35,7 @@ import { ProcessListCloudSortingModel } from '../models/process-list-sorting.mod
|
|||||||
export class ProcessListCloudComponent extends DataTableSchema implements OnChanges, AfterContentInit, PaginatedComponent {
|
export class ProcessListCloudComponent extends DataTableSchema implements OnChanges, AfterContentInit, PaginatedComponent {
|
||||||
|
|
||||||
static PRESET_KEY = 'adf-cloud-process-list.presets';
|
static PRESET_KEY = 'adf-cloud-process-list.presets';
|
||||||
|
static ENTRY_PREFIX = 'entry.';
|
||||||
|
|
||||||
@ContentChild(CustomEmptyContentTemplateDirective)
|
@ContentChild(CustomEmptyContentTemplateDirective)
|
||||||
emptyCustomContent: CustomEmptyContentTemplateDirective;
|
emptyCustomContent: CustomEmptyContentTemplateDirective;
|
||||||
@@ -156,7 +157,9 @@ export class ProcessListCloudComponent extends DataTableSchema implements OnChan
|
|||||||
selectedInstances: any[];
|
selectedInstances: any[];
|
||||||
isLoading = true;
|
isLoading = true;
|
||||||
rows: any[] = [];
|
rows: any[] = [];
|
||||||
|
formattedSorting: any[];
|
||||||
requestNode: ProcessQueryCloudRequestModel;
|
requestNode: ProcessQueryCloudRequestModel;
|
||||||
|
private defaultSorting = { key: 'startDate', direction: 'desc' };
|
||||||
|
|
||||||
constructor(private processListCloudService: ProcessListCloudService,
|
constructor(private processListCloudService: ProcessListCloudService,
|
||||||
appConfigService: AppConfigService,
|
appConfigService: AppConfigService,
|
||||||
@@ -178,7 +181,10 @@ export class ProcessListCloudComponent extends DataTableSchema implements OnChan
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges) {
|
ngOnChanges(changes: SimpleChanges) {
|
||||||
if (this.isPropertyChanged(changes)) {
|
if (this.isPropertyChanged(changes, 'sorting')) {
|
||||||
|
this.formatSorting(changes['sorting'].currentValue);
|
||||||
|
}
|
||||||
|
if (this.isAnyPropertyChanged(changes)) {
|
||||||
this.reload();
|
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) {
|
for (const property in changes) {
|
||||||
if (changes.hasOwnProperty(property)) {
|
if (this.isPropertyChanged(changes, property)) {
|
||||||
if (changes[property] &&
|
|
||||||
(changes[property].currentValue !== changes[property].previousValue)) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private isPropertyChanged(changes: SimpleChanges, property: string): boolean {
|
||||||
|
return changes.hasOwnProperty(property);
|
||||||
|
}
|
||||||
|
|
||||||
isListEmpty(): boolean {
|
isListEmpty(): boolean {
|
||||||
return !this.rows || this.rows.length === 0;
|
return !this.rows || this.rows.length === 0;
|
||||||
}
|
}
|
||||||
@@ -233,6 +240,12 @@ export class ProcessListCloudComponent extends DataTableSchema implements OnChan
|
|||||||
this.reload();
|
this.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onSortingChanged(event: CustomEvent) {
|
||||||
|
this.setSorting(event.detail);
|
||||||
|
this.formatSorting(this.sorting);
|
||||||
|
this.reload();
|
||||||
|
}
|
||||||
|
|
||||||
onRowClick(item: DataRowEvent) {
|
onRowClick(item: DataRowEvent) {
|
||||||
this.currentInstanceId = item.value.getValue('entry.id');
|
this.currentInstanceId = item.value.getValue('entry.id');
|
||||||
this.rowClick.emit(this.currentInstanceId);
|
this.rowClick.emit(this.currentInstanceId);
|
||||||
@@ -288,4 +301,18 @@ export class ProcessListCloudComponent extends DataTableSchema implements OnChan
|
|||||||
return new ProcessQueryCloudRequestModel(requestNode);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,6 +4,7 @@
|
|||||||
[rows]="rows"
|
[rows]="rows"
|
||||||
[columns]="columns"
|
[columns]="columns"
|
||||||
[loading]="isLoading"
|
[loading]="isLoading"
|
||||||
|
[sorting]="formattedSorting"
|
||||||
[multiselect]="multiselect"
|
[multiselect]="multiselect"
|
||||||
[selectionMode]="selectionMode"
|
[selectionMode]="selectionMode"
|
||||||
[stickyHeader]="stickyHeader"
|
[stickyHeader]="stickyHeader"
|
||||||
@@ -16,7 +17,8 @@
|
|||||||
(row-select)="onRowSelect($event)"
|
(row-select)="onRowSelect($event)"
|
||||||
(row-unselect)="onRowUnselect($event)"
|
(row-unselect)="onRowUnselect($event)"
|
||||||
(rowClick)="onRowClick($event)"
|
(rowClick)="onRowClick($event)"
|
||||||
(row-keyup)="onRowKeyUp($event)">
|
(row-keyup)="onRowKeyUp($event)"
|
||||||
|
(sorting-changed)="onSortingChanged($event)">
|
||||||
<adf-loading-content-template>
|
<adf-loading-content-template>
|
||||||
<ng-template>
|
<ng-template>
|
||||||
<!-- Add your custom loading template here -->
|
<!-- Add your custom loading template here -->
|
||||||
|
@@ -27,6 +27,7 @@ import { ProcessServiceCloudTestingModule } from '../../../testing/process-servi
|
|||||||
import { Person } from '@alfresco/js-api';
|
import { Person } from '@alfresco/js-api';
|
||||||
import { TaskListModule } from '@alfresco/adf-process-services';
|
import { TaskListModule } from '@alfresco/adf-process-services';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { TaskListCloudSortingModel } from '../models/task-list-sorting.model';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
template: `
|
template: `
|
||||||
@@ -289,6 +290,47 @@ describe('TaskListCloudComponent', () => {
|
|||||||
expect(component.isListEmpty()).toBeFalsy();
|
expect(component.isListEmpty()).toBeFalsy();
|
||||||
expect(getTaskByRequestSpy).toHaveBeenCalled();
|
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', () => {
|
describe('Injecting custom colums for tasklist - CustomTaskListComponent', () => {
|
||||||
|
@@ -37,6 +37,7 @@ import { takeUntil } from 'rxjs/operators';
|
|||||||
export class TaskListCloudComponent extends DataTableSchema implements OnChanges, AfterContentInit, PaginatedComponent, OnDestroy, OnInit {
|
export class TaskListCloudComponent extends DataTableSchema implements OnChanges, AfterContentInit, PaginatedComponent, OnDestroy, OnInit {
|
||||||
|
|
||||||
static PRESET_KEY = 'adf-cloud-task-list.presets';
|
static PRESET_KEY = 'adf-cloud-task-list.presets';
|
||||||
|
static ENTRY_PREFIX = 'entry.';
|
||||||
|
|
||||||
@ContentChild(CustomEmptyContentTemplateDirective)
|
@ContentChild(CustomEmptyContentTemplateDirective)
|
||||||
emptyCustomContent: CustomEmptyContentTemplateDirective;
|
emptyCustomContent: CustomEmptyContentTemplateDirective;
|
||||||
@@ -176,6 +177,8 @@ export class TaskListCloudComponent extends DataTableSchema implements OnChanges
|
|||||||
currentInstanceId: any;
|
currentInstanceId: any;
|
||||||
isLoading = true;
|
isLoading = true;
|
||||||
selectedInstances: any[];
|
selectedInstances: any[];
|
||||||
|
formattedSorting: any[];
|
||||||
|
private defaultSorting = { key: 'startDate', direction: 'desc' };
|
||||||
|
|
||||||
private onDestroy$ = new Subject<boolean>();
|
private onDestroy$ = new Subject<boolean>();
|
||||||
|
|
||||||
@@ -201,7 +204,10 @@ export class TaskListCloudComponent extends DataTableSchema implements OnChanges
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges) {
|
ngOnChanges(changes: SimpleChanges) {
|
||||||
if (this.isPropertyChanged(changes)) {
|
if (this.isPropertyChanged(changes, 'sorting')) {
|
||||||
|
this.formatSorting(changes['sorting'].currentValue);
|
||||||
|
}
|
||||||
|
if (this.isAnyPropertyChanged(changes)) {
|
||||||
this.reload();
|
this.reload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -219,18 +225,19 @@ export class TaskListCloudComponent extends DataTableSchema implements OnChanges
|
|||||||
return this.currentInstanceId;
|
return this.currentInstanceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
private isPropertyChanged(changes: SimpleChanges): boolean {
|
private isAnyPropertyChanged(changes: SimpleChanges): boolean {
|
||||||
for (const property in changes) {
|
for (const property in changes) {
|
||||||
if (changes.hasOwnProperty(property)) {
|
if (this.isPropertyChanged(changes, property)) {
|
||||||
if (changes[property] &&
|
|
||||||
(changes[property].currentValue !== changes[property].previousValue)) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private isPropertyChanged(changes: SimpleChanges, property: string): boolean {
|
||||||
|
return changes.hasOwnProperty(property);
|
||||||
|
}
|
||||||
|
|
||||||
reload() {
|
reload() {
|
||||||
this.requestNode = this.createRequestNode();
|
this.requestNode = this.createRequestNode();
|
||||||
if (this.requestNode.appName || this.requestNode.appName === '') {
|
if (this.requestNode.appName || this.requestNode.appName === '') {
|
||||||
@@ -265,6 +272,12 @@ export class TaskListCloudComponent extends DataTableSchema implements OnChanges
|
|||||||
this.reload();
|
this.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onSortingChanged(event: CustomEvent) {
|
||||||
|
this.setSorting(event.detail);
|
||||||
|
this.formatSorting(this.sorting);
|
||||||
|
this.reload();
|
||||||
|
}
|
||||||
|
|
||||||
onRowClick(item: DataRowEvent) {
|
onRowClick(item: DataRowEvent) {
|
||||||
this.currentInstanceId = item.value.getValue('entry.id');
|
this.currentInstanceId = item.value.getValue('entry.id');
|
||||||
this.rowClick.emit(this.currentInstanceId);
|
this.rowClick.emit(this.currentInstanceId);
|
||||||
@@ -324,4 +337,19 @@ export class TaskListCloudComponent extends DataTableSchema implements OnChanges
|
|||||||
};
|
};
|
||||||
return new TaskQueryCloudRequestModel(requestNode);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user