[ADF-1116] Task list without any status filter (#2189)

* Added a new service to fetch tasks without state filter

* Added services to fetch tasks with state filter

* Added processInstanceId input for tasklist to filter task for a single process

* Updated README with new processInstanceId input
This commit is contained in:
Deepak Paul 2017-08-09 19:41:49 +05:30 committed by Mario Romano
parent cfe6cacc8f
commit ecc6aecd80
5 changed files with 216 additions and 17 deletions

View File

@ -124,6 +124,7 @@ Here's the list of available properties you can define for a Data Column definit
| --- | --- | --- | --- |
| appId | string || The id of the app. |
| processDefinitionKey | string || The processDefinitionKey of the process. |
| processInstanceId | string || The processInstanceId of the process. |
| assignment | string || The assignment of the process. <ul>Possible values are: <li>assignee : where the current user is the assignee</li> <li>candidate: where the current user is a task candidate </li><li>group_x: where the task is assigned to a group where the current user is a member of.</li> <li>no value: where the current user is involved</li> </ul> |
| state | string || Define state of the processes. Possible values are: `completed`, `active` |
| hasIcon | boolean | true | Toggle the icon on the left . |

View File

@ -66,7 +66,10 @@ describe('TaskListComponent', () => {
id: 2, name: '', description: 'descriptionFake2', category: null,
assignee: {
id: 1, firstName: 'fistNameFake2', lastName: 'Administrator2', email: 'admin'
}
},
created: '2017-03-01T12:25:17.189+0000',
dueDate: '2017-04-02T12:25:17.189+0000',
endDate: null
}
];
@ -206,6 +209,54 @@ describe('TaskListComponent', () => {
fixture.detectChanges();
});
it('should return the filtered task list by processInstanceId', (done) => {
spyOn(taskListService, 'getTotalTasks').and.returnValue(Observable.of(fakeGlobalTotalTasks));
spyOn(taskListService, 'getTasks').and.returnValue(Observable.of(fakeGlobalTask));
let state = new SimpleChange(null, 'open', true);
let processInstanceId = new SimpleChange(null, 'fakeprocessId', true);
let assignment = new SimpleChange(null, 'fake-assignee', true);
component.onSuccess.subscribe((res) => {
expect(res).toBeDefined();
expect(component.data).toBeDefined();
expect(component.isListEmpty()).not.toBeTruthy();
expect(component.data.getRows().length).toEqual(2);
expect(component.data.getRows()[0].getValue('name')).toEqual('nameFake1');
expect(component.data.getRows()[0].getValue('processInstanceId')).toEqual(2511);
done();
});
component.ngAfterContentInit();
component.ngOnChanges({'state': state, 'processInstanceId': processInstanceId, 'assignment': assignment});
fixture.detectChanges();
});
it('should return the filtered task list for all state', (done) => {
spyOn(taskListService, 'getTotalTasks').and.returnValue(Observable.of(fakeGlobalTotalTasks));
spyOn(taskListService, 'getTasks').and.returnValue(Observable.of(fakeGlobalTask));
let state = new SimpleChange(null, 'all', true);
let processInstanceId = new SimpleChange(null, 'fakeprocessId', true);
component.onSuccess.subscribe((res) => {
expect(res).toBeDefined();
expect(component.data).toBeDefined();
expect(component.isListEmpty()).not.toBeTruthy();
expect(component.data.getRows().length).toEqual(2);
expect(component.data.getRows()[0].getValue('name')).toEqual('nameFake1');
expect(component.data.getRows()[0].getValue('processInstanceId')).toEqual(2511);
expect(component.data.getRows()[0].getValue('endDate')).toBeDefined();
expect(component.data.getRows()[1].getValue('name')).toEqual('No name');
expect(component.data.getRows()[1].getValue('endDate')).toBeNull();
done();
});
component.ngAfterContentInit();
component.ngOnChanges({'state': state, 'processInstanceId': processInstanceId});
fixture.detectChanges();
});
it('should return a currentId null when the taskList is empty', () => {
component.selectTask(null);
expect(component.getCurrentId()).toBeNull();

View File

@ -33,7 +33,9 @@ import {
ObjectDataRow,
ObjectDataTableAdapter
} from 'ng2-alfresco-datatable';
import { Observable } from 'rxjs/Rx';
import { TaskQueryRequestRepresentationModel } from '../models/filter.model';
import { TaskDetailsModel } from '../models/task-details.model';
import { TaskListService } from './../services/tasklist.service';
@Component({
@ -50,6 +52,9 @@ export class TaskListComponent implements OnChanges, AfterContentInit {
@Input()
appId: string;
@Input()
processInstanceId: string;
@Input()
processDefinitionKey: string;
@ -149,6 +154,7 @@ export class TaskListComponent implements OnChanges, AfterContentInit {
let changed: boolean = false;
let appId = changes['appId'];
let processInstanceId = changes['processInstanceId'];
let processDefinitionKey = changes['processDefinitionKey'];
let state = changes['state'];
let sort = changes['sort'];
@ -157,6 +163,8 @@ export class TaskListComponent implements OnChanges, AfterContentInit {
let landingTaskId = changes['landingTaskId'];
if (appId && appId.currentValue) {
changed = true;
} else if (processInstanceId && processInstanceId.currentValue) {
changed = true;
} else if (processDefinitionKey && processDefinitionKey.currentValue) {
changed = true;
} else if (state && state.currentValue) {
@ -182,26 +190,24 @@ export class TaskListComponent implements OnChanges, AfterContentInit {
private load(requestNode: TaskQueryRequestRepresentationModel) {
this.isLoading = true;
this.taskListService.getTotalTasks(requestNode).subscribe(
(res) => {
requestNode.size = res.total;
this.taskListService.getTasks(requestNode).subscribe(
(response) => {
let instancesRow = this.createDataRow(response);
this.renderInstances(instancesRow);
this.selectTask(requestNode.landingTaskId);
this.onSuccess.emit(response);
this.isLoading = false;
}, (error) => {
this.onError.emit(error);
this.isLoading = false;
});
}, (err) => {
this.onError.emit(err);
this.loadTasksByState().subscribe(
(response) => {
let instancesRow = this.createDataRow(response);
this.renderInstances(instancesRow);
this.selectTask(requestNode.landingTaskId);
this.onSuccess.emit(response);
this.isLoading = false;
}, (error) => {
this.onError.emit(error);
this.isLoading = false;
});
}
private loadTasksByState(): Observable<TaskDetailsModel[]> {
return this.requestNode.state === 'all'
? this.taskListService.findAllTasksWhitoutState(this.requestNode)
: this.taskListService.findAllTaskByState(this.requestNode);
}
/**
* Create an array of ObjectDataRow
* @param instances
@ -296,6 +302,7 @@ export class TaskListComponent implements OnChanges, AfterContentInit {
private createRequestNode() {
let requestNode = {
appDefinitionId: this.appId,
processInstanceId: this.processInstanceId,
processDefinitionKey: this.processDefinitionKey,
text: this.name,
assignment: this.assignment,

View File

@ -17,6 +17,7 @@
import { async, TestBed } from '@angular/core/testing';
import { CoreModule } from 'ng2-alfresco-core';
import { Observable } from 'rxjs/Rx';
import {
fakeAppFilter,
fakeAppPromise,
@ -219,6 +220,102 @@ describe('Activiti TaskList Service', () => {
});
});
it('should return the task list with all tasks filtered by state', (done) => {
spyOn(service, 'getTasks').and.returnValue(Observable.of(fakeTaskList.data));
spyOn(service, 'getTotalTasks').and.returnValue(Observable.of(fakeTaskList));
service.findAllTaskByState(<TaskQueryRequestRepresentationModel> fakeFilter, 'open').subscribe(
res => {
expect(res).toBeDefined();
expect(res.length).toEqual(1);
expect(res[0].name).toEqual('FakeNameTask');
expect(res[0].assignee.email).toEqual('fake-email@dom.com');
expect(res[0].assignee.firstName).toEqual('firstName');
expect(res[0].assignee.lastName).toEqual('lastName');
done();
}
);
});
it('should return the task list with all tasks filtered', (done) => {
spyOn(service, 'getTasks').and.returnValue(Observable.of(fakeTaskList.data));
spyOn(service, 'getTotalTasks').and.returnValue(Observable.of(fakeTaskList));
service.findAllTaskByState(<TaskQueryRequestRepresentationModel> fakeFilter).subscribe(
res => {
expect(res).toBeDefined();
expect(res.length).toEqual(1);
expect(res[0].name).toEqual('FakeNameTask');
expect(res[0].assignee.email).toEqual('fake-email@dom.com');
expect(res[0].assignee.firstName).toEqual('firstName');
expect(res[0].assignee.lastName).toEqual('lastName');
done();
}
);
});
it('should return the task list filtered by state', (done) => {
service.findTasksByState(<TaskQueryRequestRepresentationModel> fakeFilter, 'open').subscribe(
res => {
expect(res).toBeDefined();
expect(res.length).toEqual(1);
expect(res[0].name).toEqual('FakeNameTask');
expect(res[0].assignee.email).toEqual('fake-email@dom.com');
expect(res[0].assignee.firstName).toEqual('firstName');
expect(res[0].assignee.lastName).toEqual('lastName');
done();
}
);
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 200,
contentType: 'application/json',
responseText: JSON.stringify(fakeTaskList)
});
});
it('should return the task list filtered', (done) => {
service.findTasksByState(<TaskQueryRequestRepresentationModel> fakeFilter).subscribe(
res => {
expect(res).toBeDefined();
expect(res.length).toEqual(1);
expect(res[0].name).toEqual('FakeNameTask');
expect(res[0].assignee.email).toEqual('fake-email@dom.com');
expect(res[0].assignee.firstName).toEqual('firstName');
expect(res[0].assignee.lastName).toEqual('lastName');
done();
}
);
jasmine.Ajax.requests.mostRecent().respondWith({
'status': 200,
contentType: 'application/json',
responseText: JSON.stringify(fakeTaskList)
});
});
it('should return the task list with all tasks filtered without state', (done) => {
spyOn(service, 'getTasks').and.returnValue(Observable.of(fakeTaskList.data));
spyOn(service, 'getTotalTasks').and.returnValue(Observable.of(fakeTaskList));
service.findAllTasksWhitoutState(<TaskQueryRequestRepresentationModel> fakeFilter).subscribe(
res => {
expect(res).toBeDefined();
expect(res.length).toEqual(2);
expect(res[0].name).toEqual('FakeNameTask');
expect(res[0].assignee.email).toEqual('fake-email@dom.com');
expect(res[0].assignee.firstName).toEqual('firstName');
expect(res[0].assignee.lastName).toEqual('lastName');
expect(res[1].name).toEqual('FakeNameTask');
expect(res[1].assignee.email).toEqual('fake-email@dom.com');
expect(res[1].assignee.firstName).toEqual('firstName');
expect(res[1].assignee.lastName).toEqual('lastName');
done();
}
);
});
it('should return the task details ', (done) => {
service.getTaskDetails('999').subscribe(
(res: TaskDetailsModel) => {

View File

@ -160,6 +160,49 @@ export class TaskListService {
}).catch(err => this.handleError(err));
}
/**
* Retrieve tasks filtered by filterModel and state
* @param filter - TaskFilterRepresentationModel
* @returns {any}
*/
findTasksByState(requestNode: TaskQueryRequestRepresentationModel, state?: string): Observable<TaskDetailsModel[]> {
if (state) {
requestNode.state = state;
}
return this.getTasks(requestNode);
}
/**
* Retrieve all tasks filtered by filterModel and state
* @param filter - TaskFilterRepresentationModel
* @returns {any}
*/
findAllTaskByState(requestNode: TaskQueryRequestRepresentationModel, state?: string): Observable<TaskDetailsModel[]> {
if (state) {
requestNode.state = state;
}
return this.getTotalTasks(requestNode).
switchMap((res: any) => {
requestNode.size = res.total;
return this.getTasks(requestNode);
});
}
/**
* Retrieve all tasks filtered by filterModel irrespective of state
* @param filter - TaskFilterRepresentationModel
* @returns {any}
*/
findAllTasksWhitoutState(requestNode: TaskQueryRequestRepresentationModel): Observable<TaskDetailsModel[]> {
return Observable.forkJoin(
this.findTasksByState(requestNode, 'open'),
this.findAllTaskByState(requestNode, 'completed'),
(activeTasks: any, completedTasks: any) => {
return activeTasks.concat(completedTasks);
}
);
}
/**
* Retrieve all the task details
* @param id - taskId