From fbaf901462c5bd2153034f2462e2a1f187cc4ec6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Popovics=20Andr=C3=A1s?= Date: Thu, 21 Sep 2017 18:37:27 +0100 Subject: [PATCH] [ADF-226] Add requeue button to task header (#2366) * Add requeue button to task header * Fixing typescript declaration --- docs/task-header.component.md | 1 + .../ng2-activiti-tasklist/README.md | 1 + .../components/task-details.component.html | 3 +- .../src/components/task-details.component.ts | 2 +- .../src/components/task-header.component.html | 6 +- .../components/task-header.component.spec.ts | 56 +++++++++++++++++-- .../src/components/task-header.component.ts | 36 ++++++++++++ .../ng2-activiti-tasklist/src/i18n/en.json | 1 + .../src/services/tasklist.service.spec.ts | 16 ++++++ .../src/services/tasklist.service.ts | 9 +++ 10 files changed, 121 insertions(+), 10 deletions(-) diff --git a/docs/task-header.component.md b/docs/task-header.component.md index 47e113268c..4881a76766 100644 --- a/docs/task-header.component.md +++ b/docs/task-header.component.md @@ -37,6 +37,7 @@ Shows all the information related to a task. | Name | Description | | --- | --- | | claim | Raised when the task is claimed. | +| unclaim | Raised when the task is unclaimed (requeued). | ## Details diff --git a/ng2-components/ng2-activiti-tasklist/README.md b/ng2-components/ng2-activiti-tasklist/README.md index 1eef80467d..88acdfa69e 100644 --- a/ng2-components/ng2-activiti-tasklist/README.md +++ b/ng2-components/ng2-activiti-tasklist/README.md @@ -478,6 +478,7 @@ Shows all the information related to a task. | Name | Description | | --- | --- | | claim | Raised when the task is claimed. | +| unclaim | Raised when the task is unclaimed (requeued). | ### Details diff --git a/ng2-components/ng2-activiti-tasklist/src/components/task-details.component.html b/ng2-components/ng2-activiti-tasklist/src/components/task-details.component.html index 21baaaab51..dc910a9bdf 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/task-details.component.html +++ b/ng2-components/ng2-activiti-tasklist/src/components/task-details.component.html @@ -69,7 +69,8 @@ [class]="getTaskHeaderViewClass()" [taskDetails]="taskDetails" [formName]="taskFormName" - (claim)="onClaimTask($event)"> + (claim)="onClaimAction($event)" + (unclaim)="onClaimAction($event)"> - - + diff --git a/ng2-components/ng2-activiti-tasklist/src/components/task-header.component.spec.ts b/ng2-components/ng2-activiti-tasklist/src/components/task-header.component.spec.ts index 3e1677e6cd..bf6008a30d 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/task-header.component.spec.ts +++ b/ng2-components/ng2-activiti-tasklist/src/components/task-header.component.spec.ts @@ -19,6 +19,7 @@ import { DebugElement } from '@angular/core'; import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { AppConfigService, CardViewUpdateService, CoreModule, TranslationService } from 'ng2-alfresco-core'; +import { Observable } from 'rxjs/Rx'; import { AppConfigServiceMock } from '../assets/app-config.service.mock'; import { TranslationMock } from '../assets/translation.service.mock'; @@ -122,12 +123,55 @@ describe('TaskHeaderComponent', () => { expect(datePicker).not.toBeNull('Datepicker should be in DOM'); }); - it('should display the claim button if no assignee', () => { - component.taskDetails.assignee = null; - component.ngOnChanges({}); - fixture.detectChanges(); - let valueEl = fixture.debugElement.query(By.css('[data-automation-id="header-claim-button"]')); - expect(valueEl.nativeElement.innerText).toBe('TASK_DETAILS.BUTTON.CLAIM'); + describe('Claiming', () => { + + it('should display the claim button if no assignee', () => { + component.taskDetails.assignee = null; + + component.ngOnChanges({}); + fixture.detectChanges(); + + let claimButton = fixture.debugElement.query(By.css('[data-automation-id="header-claim-button"]')); + expect(claimButton.nativeElement.innerText).toBe('TASK_DETAILS.BUTTON.CLAIM'); + }); + }); + + describe('Unclaim', () => { + + const batman = { id : 1, email: 'bruce.wayne@gotham.com', firstName: 'Bruce', lastName: 'Wayne', userImage: 'batman.jpg' }; + let taskListService; + + beforeEach(() => { + taskListService = TestBed.get(TaskListService); + component.taskDetails.assignee = batman; + component.taskDetails.id = 'repair-batmobile'; + fixture.detectChanges(); + }); + + it('should display the requeue button if there is assignee', () => { + let unclaimButton = fixture.debugElement.query(By.css('[data-automation-id="header-unclaim-button"]')); + expect(unclaimButton.nativeElement.innerText).toBe('TASK_DETAILS.BUTTON.UNCLAIM'); + }); + + it('should call the service\'s unclaim method on unclaiming' , () => { + spyOn(taskListService, 'unclaimTask'); + + let unclaimButton = fixture.debugElement.query(By.css('[data-automation-id="header-unclaim-button"]')); + unclaimButton.triggerEventHandler('click', {}); + + expect(taskListService.unclaimTask).toHaveBeenCalledWith('repair-batmobile'); + }); + + it('should trigger the unclaim event on successfull unclaiming', () => { + let unclaimed: boolean = false; + component.unclaim.subscribe(() => { unclaimed = true; }); + spyOn(taskListService, 'unclaimTask').and.returnValue(Observable.of(true)); + + let unclaimButton = fixture.debugElement.query(By.css('[data-automation-id="header-unclaim-button"]')); + unclaimButton.triggerEventHandler('click', {}); + + expect(unclaimed).toBeTruthy(); + }); }); it('should display due date', () => { diff --git a/ng2-components/ng2-activiti-tasklist/src/components/task-header.component.ts b/ng2-components/ng2-activiti-tasklist/src/components/task-header.component.ts index a93ff7930b..d7b0ce606a 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/task-header.component.ts +++ b/ng2-components/ng2-activiti-tasklist/src/components/task-header.component.ts @@ -36,6 +36,9 @@ export class TaskHeaderComponent implements OnChanges { @Output() claim: EventEmitter = new EventEmitter(); + @Output() + unclaim: EventEmitter = new EventEmitter(); + properties: CardViewItem []; inEdit: boolean = false; @@ -47,6 +50,9 @@ export class TaskHeaderComponent implements OnChanges { this.refreshData(); } + /** + * Refresh the card data + */ refreshData() { if (this.taskDetails) { let valueMap = new Map([[this.taskDetails.processInstanceId, this.taskDetails.processDefinitionName]]); @@ -72,18 +78,32 @@ export class TaskHeaderComponent implements OnChanges { } } + /** + * Does the task have an assignee + */ public hasAssignee(): boolean { return (this.taskDetails && this.taskDetails.assignee) ? true : false; } + /** + * Is the task assigned to the currently loggedin user + */ isAssignedToMe(): boolean { return this.taskDetails.assignee ? true : false; } + /** + * Returns task's status + */ getTaskStatus(): string { return this.isCompleted() ? 'Completed' : 'Running'; } + /** + * Claim task + * + * @param taskId + */ claimTask(taskId: string) { this.activitiTaskService.claimTask(taskId).subscribe( (res: any) => { @@ -92,6 +112,22 @@ export class TaskHeaderComponent implements OnChanges { }); } + /** + * Unclaim task + * + * @param taskId + */ + unclaimTask(taskId: string) { + this.activitiTaskService.unclaimTask(taskId).subscribe( + (res: any) => { + this.logService.info('Task unclaimed'); + this.unclaim.emit(taskId); + }); + } + + /** + * Returns true if the task is completed + */ isCompleted() { return !!this.taskDetails.endDate; } diff --git a/ng2-components/ng2-activiti-tasklist/src/i18n/en.json b/ng2-components/ng2-activiti-tasklist/src/i18n/en.json index 0a93b1adcb..fa24322bd4 100644 --- a/ng2-components/ng2-activiti-tasklist/src/i18n/en.json +++ b/ng2-components/ng2-activiti-tasklist/src/i18n/en.json @@ -22,6 +22,7 @@ "BUTTON": { "COMPLETE": "Complete", "CLAIM": "Claim", + "UNCLAIM": "Requeue", "DRAG-ATTACHMENT": "Drop Files Here...", "UPLOAD-ATTACHMENT": "Upload Attachment" }, diff --git a/ng2-components/ng2-activiti-tasklist/src/services/tasklist.service.spec.ts b/ng2-components/ng2-activiti-tasklist/src/services/tasklist.service.spec.ts index 39b88e5240..954ab9bb5b 100644 --- a/ng2-components/ng2-activiti-tasklist/src/services/tasklist.service.spec.ts +++ b/ng2-components/ng2-activiti-tasklist/src/services/tasklist.service.spec.ts @@ -750,6 +750,22 @@ describe('Activiti TaskList Service', () => { }); }); + it('should unclaim a task', (done) => { + let taskId = '111'; + + service.unclaimTask(taskId).subscribe( + (res: any) => { + done(); + } + ); + + jasmine.Ajax.requests.mostRecent().respondWith({ + 'status': 200, + contentType: 'application/json', + responseText: JSON.stringify({}) + }); + }); + it('should update a task', (done) => { let taskId = '111'; diff --git a/ng2-components/ng2-activiti-tasklist/src/services/tasklist.service.ts b/ng2-components/ng2-activiti-tasklist/src/services/tasklist.service.ts index dbc4216f9c..d160f14bf5 100644 --- a/ng2-components/ng2-activiti-tasklist/src/services/tasklist.service.ts +++ b/ng2-components/ng2-activiti-tasklist/src/services/tasklist.service.ts @@ -446,6 +446,15 @@ export class TaskListService { .catch(err => this.handleError(err)); } + /** + * Unclaim a task + * @param id - taskId + */ + unclaimTask(taskId: string): Observable { + return Observable.fromPromise(this.apiService.getInstance().activiti.taskApi.unclaimTask(taskId)) + .catch(err => this.handleError(err)); + } + /** * Update due date * @param dueDate - the new due date