mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-19 17:14:57 +00:00
Merge pull request #800 from Alfresco/dev-mvitale-776
Automatically open the new task when the task is completed
This commit is contained in:
commit
11d4ac4427
@ -77,30 +77,40 @@ export class ActivitiProcessFilters implements OnInit, OnChanges {
|
||||
this.filters.push(filter);
|
||||
});
|
||||
|
||||
this.load();
|
||||
this.getFilters(this.appId, this.appName);
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
let appId = changes['appId'];
|
||||
if (appId && (appId.currentValue || appId.currentValue === null)) {
|
||||
this.load();
|
||||
this.getFiltersByAppId(appId.currentValue);
|
||||
return;
|
||||
}
|
||||
let appName = changes['appName'];
|
||||
if (appName && appName.currentValue) {
|
||||
this.getFiltersByAppName(appName.currentValue);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The method call the adapter data table component for render the task list
|
||||
* @param tasks
|
||||
* Return the task list filtered by appId or by appName
|
||||
* @param appId
|
||||
* @param appName
|
||||
*/
|
||||
private load() {
|
||||
if (this.appName) {
|
||||
this.filterByAppName();
|
||||
getFilters(appId?: string, appName?: string) {
|
||||
if (appName) {
|
||||
this.getFiltersByAppName(appName);
|
||||
} else {
|
||||
this.filterByAppId(this.appId);
|
||||
this.getFiltersByAppId(appId);
|
||||
}
|
||||
}
|
||||
|
||||
private filterByAppId(appId) {
|
||||
/**
|
||||
* Return the filter list filtered by appId
|
||||
* @param appId - optional
|
||||
*/
|
||||
getFiltersByAppId(appId?: string) {
|
||||
this.activiti.getProcessFilters(appId).subscribe(
|
||||
(res: FilterRepresentationModel[]) => {
|
||||
this.resetFilter();
|
||||
@ -117,10 +127,14 @@ export class ActivitiProcessFilters implements OnInit, OnChanges {
|
||||
);
|
||||
}
|
||||
|
||||
private filterByAppName() {
|
||||
this.activiti.getDeployedApplications(this.appName).subscribe(
|
||||
/**
|
||||
* Return the filter list filtered by appName
|
||||
* @param appName
|
||||
*/
|
||||
getFiltersByAppName(appName: string) {
|
||||
this.activiti.getDeployedApplications(appName).subscribe(
|
||||
application => {
|
||||
this.filterByAppId(application.id);
|
||||
this.getFiltersByAppId(application.id);
|
||||
this.selectFirstFilter();
|
||||
},
|
||||
(err) => {
|
||||
|
@ -106,8 +106,13 @@ The component shows the details of the task id passed in input
|
||||
|
||||
#### Options
|
||||
|
||||
**taskId**: { string } required) The id of the task details that we
|
||||
are asking for.
|
||||
**taskId**: { string } required) The id of the task details that we are asking for.
|
||||
**showNextTask**: { boolean } optional) Automatically render the next one, when the task is completed.
|
||||
**showFormTitle**: { boolean } optional) Toggle rendering of the form title.
|
||||
**readOnlyForm**: { boolean } optional) Toggle readonly state of the form. Enforces all form widgets render readonly if enabled.
|
||||
**showFormRefreshButton**: { boolean } optional) Toggle rendering of the `Refresh` button.
|
||||
**showFormSaveButton**: { boolean } optional) Toggle rendering of the `Save` outcome button.
|
||||
**showFormCompleteButton**: { boolean } optional) Toggle rendering of the Form `Complete` outcome button
|
||||
|
||||
### Custom 'empty Activiti Task Details' template
|
||||
|
||||
|
@ -21,7 +21,7 @@ import {
|
||||
expect,
|
||||
beforeEach
|
||||
} from '@angular/core/testing';
|
||||
|
||||
import { SimpleChange } from '@angular/core';
|
||||
import { ActivitiFilters } from './activiti-filters.component';
|
||||
import { ActivitiTaskListService } from '../services/activiti-tasklist.service';
|
||||
import { Observable } from 'rxjs/Rx';
|
||||
@ -89,6 +89,7 @@ describe('ActivitiFilters', () => {
|
||||
});
|
||||
|
||||
it('should emit an error with a bad response', (done) => {
|
||||
filterList.appId = '1';
|
||||
spyOn(filterList.activiti, 'getTaskListFilters').and.returnValue(Observable.fromPromise(fakeErrorFilterPromise));
|
||||
|
||||
filterList.onError.subscribe((err) => {
|
||||
@ -99,6 +100,18 @@ describe('ActivitiFilters', () => {
|
||||
filterList.ngOnInit();
|
||||
});
|
||||
|
||||
it('should emit an error with a bad response', (done) => {
|
||||
filterList.appName = 'fake-app';
|
||||
spyOn(filterList.activiti, 'getDeployedApplications').and.returnValue(Observable.fromPromise(fakeErrorFilterPromise));
|
||||
|
||||
filterList.onError.subscribe((err) => {
|
||||
expect(err).toBeDefined();
|
||||
done();
|
||||
});
|
||||
|
||||
filterList.ngOnInit();
|
||||
});
|
||||
|
||||
it('should emit an event when a filter is selected', (done) => {
|
||||
let currentFilter = new FilterRepresentationModel({filter: { state: 'open', assignment: 'fake-involved'}});
|
||||
|
||||
@ -112,4 +125,41 @@ describe('ActivitiFilters', () => {
|
||||
filterList.selectFilter(currentFilter);
|
||||
});
|
||||
|
||||
it('should reload filters by appId on binding changes', () => {
|
||||
spyOn(filterList, 'getFiltersByAppId').and.stub();
|
||||
const appId = '1';
|
||||
|
||||
let change = new SimpleChange(null, appId);
|
||||
filterList.ngOnChanges({ 'appId': change });
|
||||
|
||||
expect(filterList.getFiltersByAppId).toHaveBeenCalledWith(appId);
|
||||
});
|
||||
|
||||
it('should reload filters by appId null on binding changes', () => {
|
||||
spyOn(filterList, 'getFiltersByAppId').and.stub();
|
||||
const appId = null;
|
||||
|
||||
let change = new SimpleChange(null, appId);
|
||||
filterList.ngOnChanges({ 'appId': change });
|
||||
|
||||
expect(filterList.getFiltersByAppId).toHaveBeenCalledWith(appId);
|
||||
});
|
||||
|
||||
it('should reload filters by app name on binding changes', () => {
|
||||
spyOn(filterList, 'getFiltersByAppName').and.stub();
|
||||
const appName = 'fake-app-name';
|
||||
|
||||
let change = new SimpleChange(null, appName);
|
||||
filterList.ngOnChanges({ 'appName': change });
|
||||
|
||||
expect(filterList.getFiltersByAppName).toHaveBeenCalledWith(appName);
|
||||
});
|
||||
|
||||
it('should return the current filter after one is selected', () => {
|
||||
let filter = new FilterRepresentationModel({name: 'FakeMyTasks', filter: { state: 'open', assignment: 'fake-assignee'}});
|
||||
expect(filterList.currentFilter).toBeUndefined();
|
||||
filterList.selectFilter(filter);
|
||||
expect(filterList.getCurrentFilter()).toBe(filter);
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -77,37 +77,47 @@ export class ActivitiFilters implements OnInit, OnChanges {
|
||||
this.filters.push(filter);
|
||||
});
|
||||
|
||||
this.load();
|
||||
this.getFilters(this.appId, this.appName);
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
let appId = changes['appId'];
|
||||
if (appId && (appId.currentValue || appId.currentValue === null)) {
|
||||
this.load();
|
||||
this.getFiltersByAppId(appId.currentValue);
|
||||
return;
|
||||
}
|
||||
let appName = changes['appName'];
|
||||
if (appName && appName.currentValue) {
|
||||
this.getFiltersByAppName(appName.currentValue);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The method call the adapter data table component for render the task list
|
||||
* @param tasks
|
||||
* Return the task list filtered by appId or by appName
|
||||
* @param appId
|
||||
* @param appName
|
||||
*/
|
||||
private load() {
|
||||
if (this.appName) {
|
||||
this.filterByAppName();
|
||||
getFilters(appId?: string, appName?: string) {
|
||||
if (appName) {
|
||||
this.getFiltersByAppName(appName);
|
||||
} else {
|
||||
this.filterByAppId(this.appId);
|
||||
this.getFiltersByAppId(appId);
|
||||
}
|
||||
}
|
||||
|
||||
private filterByAppId(appId) {
|
||||
/**
|
||||
* Return the filter list filtered by appId
|
||||
* @param appId - optional
|
||||
*/
|
||||
getFiltersByAppId(appId?: string) {
|
||||
this.activiti.getTaskListFilters(appId).subscribe(
|
||||
(res: FilterRepresentationModel[]) => {
|
||||
this.resetFilter();
|
||||
res.forEach((filter) => {
|
||||
this.filterObserver.next(filter);
|
||||
this.selectFirstFilter();
|
||||
});
|
||||
this.selectFirstFilter();
|
||||
this.onSuccess.emit(res);
|
||||
},
|
||||
(err) => {
|
||||
@ -117,10 +127,14 @@ export class ActivitiFilters implements OnInit, OnChanges {
|
||||
);
|
||||
}
|
||||
|
||||
private filterByAppName() {
|
||||
this.activiti.getDeployedApplications(this.appName).subscribe(
|
||||
/**
|
||||
* Return the filter list filtered by appName
|
||||
* @param appName
|
||||
*/
|
||||
getFiltersByAppName(appName: string) {
|
||||
this.activiti.getDeployedApplications(appName).subscribe(
|
||||
application => {
|
||||
this.filterByAppId(application.id);
|
||||
this.getFiltersByAppId(application.id);
|
||||
this.selectFirstFilter();
|
||||
},
|
||||
(err) => {
|
||||
|
@ -22,11 +22,11 @@
|
||||
</div>
|
||||
</div>
|
||||
<activiti-form *ngIf="hasFormKey()" [taskId]="taskDetails.id"
|
||||
[showTitle]="showTitle"
|
||||
[showTitle]="showFormTitle"
|
||||
[showRefreshButton]="showRefreshButton"
|
||||
[showCompleteButton]="showCompleteButton"
|
||||
[showSaveButton]="showSaveButton"
|
||||
[readOnly]="readOnly"
|
||||
[showCompleteButton]="showFormCompleteButton"
|
||||
[showSaveButton]="showFormSaveButton"
|
||||
[readOnly]="readOnlyForm"
|
||||
(formSaved)='formSavedEmitter($event)'
|
||||
(formCompleted)='formCompletedEmitter($event)'
|
||||
(formLoaded)='formLoadedEmitter($event)'
|
||||
|
@ -25,6 +25,7 @@ import { ActivitiPeople } from './activiti-people.component';
|
||||
import { TaskDetailsModel } from '../models/task-details.model';
|
||||
import { User } from '../models/user.model';
|
||||
import { ActivitiForm, FormModel, FormService } from 'ng2-activiti-form';
|
||||
import { TaskQueryRequestRepresentationModel } from '../models/filter.model';
|
||||
|
||||
|
||||
declare let componentHandler: any;
|
||||
@ -40,9 +41,6 @@ declare let __moduleName: string;
|
||||
})
|
||||
export class ActivitiTaskDetails implements OnInit, OnChanges {
|
||||
|
||||
@Input()
|
||||
taskId: string;
|
||||
|
||||
@ViewChild('activiticomments')
|
||||
activiticomments: any;
|
||||
|
||||
@ -50,19 +48,25 @@ export class ActivitiTaskDetails implements OnInit, OnChanges {
|
||||
activitichecklist: any;
|
||||
|
||||
@Input()
|
||||
showTitle: boolean = true;
|
||||
taskId: string;
|
||||
|
||||
@Input()
|
||||
showCompleteButton: boolean = true;
|
||||
showNextTask: boolean = true;
|
||||
|
||||
@Input()
|
||||
showSaveButton: boolean = true;
|
||||
showFormTitle: boolean = true;
|
||||
|
||||
@Input()
|
||||
readOnly: boolean = false;
|
||||
showFormCompleteButton: boolean = true;
|
||||
|
||||
@Input()
|
||||
showRefreshButton: boolean = true;
|
||||
showFormSaveButton: boolean = true;
|
||||
|
||||
@Input()
|
||||
readOnlyForm: boolean = false;
|
||||
|
||||
@Input()
|
||||
showFormRefreshButton: boolean = true;
|
||||
|
||||
@Output()
|
||||
formSaved = new EventEmitter();
|
||||
@ -127,10 +131,14 @@ export class ActivitiTaskDetails implements OnInit, OnChanges {
|
||||
this.taskDetails = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the task has a form
|
||||
* @returns {TaskDetailsModel|string|boolean}
|
||||
*/
|
||||
hasFormKey() {
|
||||
return this.taskDetails
|
||||
return (this.taskDetails
|
||||
&& this.taskDetails.formKey
|
||||
&& this.taskDetails.formKey !== 'null';
|
||||
&& this.taskDetails.formKey !== 'null');
|
||||
}
|
||||
|
||||
isTaskActive() {
|
||||
@ -150,7 +158,7 @@ export class ActivitiTaskDetails implements OnInit, OnChanges {
|
||||
this.taskDetails = res;
|
||||
|
||||
let endDate: any = res.endDate;
|
||||
this.readOnly = !!(endDate && !isNaN(endDate.getTime()));
|
||||
this.readOnlyForm = !!(endDate && !isNaN(endDate.getTime()));
|
||||
|
||||
if (this.taskDetails && this.taskDetails.involvedPeople) {
|
||||
this.taskDetails.involvedPeople.forEach((user) => {
|
||||
@ -172,6 +180,31 @@ export class ActivitiTaskDetails implements OnInit, OnChanges {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the next open task
|
||||
* @param processInstanceId
|
||||
* @param processDefinitionId
|
||||
*/
|
||||
loadNextTask(processInstanceId: string, processDefinitionId: string) {
|
||||
let requestNode = new TaskQueryRequestRepresentationModel(
|
||||
{
|
||||
processInstanceId: processInstanceId,
|
||||
processDefinitionId: processDefinitionId
|
||||
}
|
||||
);
|
||||
this.activitiTaskList.getTasks(requestNode).subscribe(
|
||||
(response) => {
|
||||
if (response.data && response.data.length > 0) {
|
||||
this.taskDetails = response.data[0];
|
||||
} else {
|
||||
this.reset();
|
||||
}
|
||||
}, (error) => {
|
||||
console.error(error);
|
||||
this.onError.emit(error);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Complete the activiti task
|
||||
*/
|
||||
@ -198,6 +231,9 @@ export class ActivitiTaskDetails implements OnInit, OnChanges {
|
||||
*/
|
||||
formCompletedEmitter(data: any) {
|
||||
this.formCompleted.emit(data);
|
||||
if (this.isShowNextTask()) {
|
||||
this.loadNextTask(this.taskDetails.processInstanceId, this.taskDetails.processDefinitionId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -208,11 +244,27 @@ export class ActivitiTaskDetails implements OnInit, OnChanges {
|
||||
this.formLoaded.emit(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit the error event of the form
|
||||
* @param data
|
||||
*/
|
||||
onErrorEmitter(err: any) {
|
||||
this.onError.emit(err);
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit the execute outcome of the form
|
||||
* @param data
|
||||
*/
|
||||
executeOutcomeEmitter(data: any) {
|
||||
this.executeOutcome.emit(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the showNexTask value
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isShowNextTask(): boolean {
|
||||
return this.showNextTask;
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ import {
|
||||
expect,
|
||||
beforeEach
|
||||
} from '@angular/core/testing';
|
||||
|
||||
import { SimpleChange } from '@angular/core';
|
||||
import { ActivitiTaskList } from './activiti-tasklist.component';
|
||||
import { ActivitiTaskListService } from '../services/activiti-tasklist.service';
|
||||
import { UserTaskFilterRepresentationModel } from '../models/filter.model';
|
||||
@ -120,6 +120,11 @@ describe('ActivitiTaskList', () => {
|
||||
taskList.ngOnInit();
|
||||
});
|
||||
|
||||
it('should return a currentId null when the taskList is empty', () => {
|
||||
taskList.selectFirstTask();
|
||||
expect(taskList.getCurrentTaskId()).toBeNull();
|
||||
});
|
||||
|
||||
it('should throw an exception when the response is wrong', (done) => {
|
||||
spyOn(taskList.activiti, 'getTotalTasks').and.returnValue(Observable.fromPromise(fakeErrorTaskPromise));
|
||||
taskList.taskFilter = new UserTaskFilterRepresentationModel({filter: { state: 'open', assignment: 'fake-assignee'}});
|
||||
@ -157,10 +162,21 @@ describe('ActivitiTaskList', () => {
|
||||
|
||||
taskList.rowClick.subscribe(taskId => {
|
||||
expect(taskId).toEqual(999);
|
||||
expect(taskList.getCurrentTaskId()).toEqual(999);
|
||||
done();
|
||||
});
|
||||
|
||||
taskList.onRowClick(rowEvent);
|
||||
});
|
||||
|
||||
it('should reload task list by filter on binding changes', () => {
|
||||
spyOn(taskList, 'load').and.stub();
|
||||
const taskFilter = new UserTaskFilterRepresentationModel({filter: { state: 'open', assignment: 'fake-assignee'}});
|
||||
|
||||
let change = new SimpleChange(null, taskFilter);
|
||||
taskList.ngOnChanges({ 'taskFilter': change });
|
||||
|
||||
expect(taskList.load).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -153,7 +153,7 @@ export class ActivitiTaskList implements OnInit, OnChanges {
|
||||
/**
|
||||
* Select the first task of a tasklist if present
|
||||
*/
|
||||
private selectFirstTask() {
|
||||
selectFirstTask() {
|
||||
if (!this.isTaskListEmpty()) {
|
||||
this.currentTaskId = this.data.getRows()[0].getValue('id');
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user