mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[ADF-226] Add requeue button to task header (#2366)
* Add requeue button to task header * Fixing typescript declaration
This commit is contained in:
committed by
Eugenio Romano
parent
417071db01
commit
fbaf901462
@@ -37,6 +37,7 @@ Shows all the information related to a task.
|
|||||||
| Name | Description |
|
| Name | Description |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| claim | Raised when the task is claimed. |
|
| claim | Raised when the task is claimed. |
|
||||||
|
| unclaim | Raised when the task is unclaimed (requeued). |
|
||||||
|
|
||||||
## Details
|
## Details
|
||||||
|
|
||||||
|
@@ -478,6 +478,7 @@ Shows all the information related to a task.
|
|||||||
| Name | Description |
|
| Name | Description |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| claim | Raised when the task is claimed. |
|
| claim | Raised when the task is claimed. |
|
||||||
|
| unclaim | Raised when the task is unclaimed (requeued). |
|
||||||
|
|
||||||
### Details
|
### Details
|
||||||
|
|
||||||
|
@@ -69,7 +69,8 @@
|
|||||||
[class]="getTaskHeaderViewClass()"
|
[class]="getTaskHeaderViewClass()"
|
||||||
[taskDetails]="taskDetails"
|
[taskDetails]="taskDetails"
|
||||||
[formName]="taskFormName"
|
[formName]="taskFormName"
|
||||||
(claim)="onClaimTask($event)">
|
(claim)="onClaimAction($event)"
|
||||||
|
(unclaim)="onClaimAction($event)">
|
||||||
</adf-task-header>
|
</adf-task-header>
|
||||||
<adf-people *ngIf="showInvolvePeople" #people
|
<adf-people *ngIf="showInvolvePeople" #people
|
||||||
[iconImageUrl]="peopleIconImageUrl"
|
[iconImageUrl]="peopleIconImageUrl"
|
||||||
|
@@ -324,7 +324,7 @@ export class TaskDetailsComponent implements OnInit, OnChanges {
|
|||||||
this.dialog.closeAll();
|
this.dialog.closeAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
onClaimTask(taskId: string): void {
|
onClaimAction(taskId: string): void {
|
||||||
this.loadDetails(taskId);
|
this.loadDetails(taskId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -3,8 +3,10 @@
|
|||||||
<adf-card-view [properties]="properties" [editable]="!isCompleted()"></adf-card-view>
|
<adf-card-view [properties]="properties" [editable]="!isCompleted()"></adf-card-view>
|
||||||
</md-card-content>
|
</md-card-content>
|
||||||
|
|
||||||
<md-card-actions *ngIf="!isAssignedToMe()" class="adf-controls">
|
<md-card-actions class="adf-controls">
|
||||||
<button md-button data-automation-id="header-claim-button" id="claim-task" (click)="claimTask(taskDetails.id)" class="adf-claim-controls">{{ 'TASK_DETAILS.BUTTON.CLAIM' | translate }}
|
<button *ngIf="isAssignedToMe()" md-button data-automation-id="header-unclaim-button" id="unclaim-task" (click)="unclaimTask(taskDetails.id)" class="adf-claim-controls">{{ 'TASK_DETAILS.BUTTON.UNCLAIM' | translate }}
|
||||||
|
</button>
|
||||||
|
<button *ngIf="!isAssignedToMe()" md-button data-automation-id="header-claim-button" id="claim-task" (click)="claimTask(taskDetails.id)" class="adf-claim-controls">{{ 'TASK_DETAILS.BUTTON.CLAIM' | translate }}
|
||||||
</button>
|
</button>
|
||||||
</md-card-actions>
|
</md-card-actions>
|
||||||
</md-card>
|
</md-card>
|
||||||
|
@@ -19,6 +19,7 @@ import { DebugElement } from '@angular/core';
|
|||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
import { AppConfigService, CardViewUpdateService, CoreModule, TranslationService } from 'ng2-alfresco-core';
|
import { AppConfigService, CardViewUpdateService, CoreModule, TranslationService } from 'ng2-alfresco-core';
|
||||||
|
import { Observable } from 'rxjs/Rx';
|
||||||
import { AppConfigServiceMock } from '../assets/app-config.service.mock';
|
import { AppConfigServiceMock } from '../assets/app-config.service.mock';
|
||||||
import { TranslationMock } from '../assets/translation.service.mock';
|
import { TranslationMock } from '../assets/translation.service.mock';
|
||||||
|
|
||||||
@@ -122,12 +123,55 @@ describe('TaskHeaderComponent', () => {
|
|||||||
expect(datePicker).not.toBeNull('Datepicker should be in DOM');
|
expect(datePicker).not.toBeNull('Datepicker should be in DOM');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Claiming', () => {
|
||||||
|
|
||||||
it('should display the claim button if no assignee', () => {
|
it('should display the claim button if no assignee', () => {
|
||||||
component.taskDetails.assignee = null;
|
component.taskDetails.assignee = null;
|
||||||
|
|
||||||
component.ngOnChanges({});
|
component.ngOnChanges({});
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
let valueEl = fixture.debugElement.query(By.css('[data-automation-id="header-claim-button"]'));
|
|
||||||
expect(valueEl.nativeElement.innerText).toBe('TASK_DETAILS.BUTTON.CLAIM');
|
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', () => {
|
it('should display due date', () => {
|
||||||
|
@@ -36,6 +36,9 @@ export class TaskHeaderComponent implements OnChanges {
|
|||||||
@Output()
|
@Output()
|
||||||
claim: EventEmitter<any> = new EventEmitter<any>();
|
claim: EventEmitter<any> = new EventEmitter<any>();
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
unclaim: EventEmitter<any> = new EventEmitter<any>();
|
||||||
|
|
||||||
properties: CardViewItem [];
|
properties: CardViewItem [];
|
||||||
inEdit: boolean = false;
|
inEdit: boolean = false;
|
||||||
|
|
||||||
@@ -47,6 +50,9 @@ export class TaskHeaderComponent implements OnChanges {
|
|||||||
this.refreshData();
|
this.refreshData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh the card data
|
||||||
|
*/
|
||||||
refreshData() {
|
refreshData() {
|
||||||
if (this.taskDetails) {
|
if (this.taskDetails) {
|
||||||
let valueMap = new Map([[this.taskDetails.processInstanceId, this.taskDetails.processDefinitionName]]);
|
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 {
|
public hasAssignee(): boolean {
|
||||||
return (this.taskDetails && this.taskDetails.assignee) ? true : false;
|
return (this.taskDetails && this.taskDetails.assignee) ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the task assigned to the currently loggedin user
|
||||||
|
*/
|
||||||
isAssignedToMe(): boolean {
|
isAssignedToMe(): boolean {
|
||||||
return this.taskDetails.assignee ? true : false;
|
return this.taskDetails.assignee ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns task's status
|
||||||
|
*/
|
||||||
getTaskStatus(): string {
|
getTaskStatus(): string {
|
||||||
return this.isCompleted() ? 'Completed' : 'Running';
|
return this.isCompleted() ? 'Completed' : 'Running';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Claim task
|
||||||
|
*
|
||||||
|
* @param taskId
|
||||||
|
*/
|
||||||
claimTask(taskId: string) {
|
claimTask(taskId: string) {
|
||||||
this.activitiTaskService.claimTask(taskId).subscribe(
|
this.activitiTaskService.claimTask(taskId).subscribe(
|
||||||
(res: any) => {
|
(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() {
|
isCompleted() {
|
||||||
return !!this.taskDetails.endDate;
|
return !!this.taskDetails.endDate;
|
||||||
}
|
}
|
||||||
|
@@ -22,6 +22,7 @@
|
|||||||
"BUTTON": {
|
"BUTTON": {
|
||||||
"COMPLETE": "Complete",
|
"COMPLETE": "Complete",
|
||||||
"CLAIM": "Claim",
|
"CLAIM": "Claim",
|
||||||
|
"UNCLAIM": "Requeue",
|
||||||
"DRAG-ATTACHMENT": "Drop Files Here...",
|
"DRAG-ATTACHMENT": "Drop Files Here...",
|
||||||
"UPLOAD-ATTACHMENT": "Upload Attachment"
|
"UPLOAD-ATTACHMENT": "Upload Attachment"
|
||||||
},
|
},
|
||||||
|
@@ -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) => {
|
it('should update a task', (done) => {
|
||||||
let taskId = '111';
|
let taskId = '111';
|
||||||
|
|
||||||
|
@@ -446,6 +446,15 @@ export class TaskListService {
|
|||||||
.catch(err => this.handleError(err));
|
.catch(err => this.handleError(err));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unclaim a task
|
||||||
|
* @param id - taskId
|
||||||
|
*/
|
||||||
|
unclaimTask(taskId: string): Observable<TaskDetailsModel> {
|
||||||
|
return Observable.fromPromise(this.apiService.getInstance().activiti.taskApi.unclaimTask(taskId))
|
||||||
|
.catch(err => this.handleError(err));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update due date
|
* Update due date
|
||||||
* @param dueDate - the new due date
|
* @param dueDate - the new due date
|
||||||
|
Reference in New Issue
Block a user