#1426 - Checklist task delete action (#1812)

* #1426 - added remove checklist feature on task details
* #1426 - Improved test for tasklist service
* 426 - added component test for deleting a checklist
This commit is contained in:
Vito
2017-04-07 07:43:47 -07:00
committed by Mario Romano
parent d2f7a6858f
commit 4bee113e36
10 changed files with 840 additions and 589 deletions

View File

@@ -0,0 +1,226 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
FilterRepresentationModel,
AppDefinitionRepresentationModel
} from '../models/filter.model';
export var fakeFilters = {
size: 2, total: 2, start: 0,
data: [
new AppDefinitionRepresentationModel(
{
id: '1', name: 'FakeInvolvedTasks', recent: false, icon: 'glyphicon-align-left',
filter: { sort: 'created-desc', name: '', state: 'open', assignment: 'fake-involved' }
}
),
{
id: '2', name: 'FakeMyTasks', recent: false, icon: 'glyphicon-align-left',
filter: { sort: 'created-desc', name: '', state: 'open', assignment: 'fake-assignee' }
}
]
};
export var fakeAppFilter = {
size: 1, total: 1, start: 0,
data: [
{
id: 1, name: 'FakeInvolvedTasks', recent: false, icon: 'glyphicon-align-left',
filter: { sort: 'created-desc', name: '', state: 'open', assignment: 'fake-involved' }
}
]
};
export var fakeApps = {
size: 2, total: 2, start: 0,
data: [
{
id: 1, defaultAppId: null, name: 'Sales-Fakes-App', description: 'desc-fake1', modelId: 22,
theme: 'theme-1-fake', icon: 'glyphicon-asterisk', 'deploymentId': '111', 'tenantId': null
},
{
id: 2, defaultAppId: null, name: 'health-care-Fake', description: 'desc-fake2', modelId: 33,
theme: 'theme-2-fake', icon: 'glyphicon-asterisk', 'deploymentId': '444', 'tenantId': null
}
]
};
export var fakeFilter = {
sort: 'created-desc', text: '', state: 'open', assignment: 'fake-assignee'
};
export var fakeFilterWithProcessDefinitionKey = {
sort: 'created-desc', text: '', state: 'open', assignment: 'fake-assignee', processDefinitionKey: '1'
};
export var fakeUser = { id: 1, email: 'fake-email@dom.com', firstName: 'firstName', lastName: 'lastName' };
export var fakeTaskList = {
size: 1, total: 1, start: 0,
data: [
{
id: '1', name: 'FakeNameTask', description: null, category: null,
assignee: fakeUser,
created: '2016-07-15T11:19:17.440+0000'
}
]
};
export var fakeTaskListDifferentProcessDefinitionKey = {
size: 1, total: 1, start: 0,
data: [
{
id: '1', name: 'FakeNameTask', description: null, category: null,
assignee: fakeUser,
processDefinitionKey: '1',
created: '2016-07-15T11:19:17.440+0000'
},
{
id: '2', name: 'FakeNameTask2', description: null, category: null,
assignee: fakeUser,
processDefinitionKey: '2',
created: '2016-07-15T11:19:17.440+0000'
}
]
};
export var secondFakeTaskList = {
size: 1, total: 1, start: 0,
data: [
{
id: '200', name: 'FakeNameTask', description: null, category: null,
assignee: fakeUser,
created: '2016-07-15T11:19:17.440+0000'
}
]
};
export var fakeErrorTaskList = {
error: 'wrong request'
};
export var fakeTaskDetails = { id: '999', name: 'fake-task-name', formKey: '99', assignee: fakeUser };
export var fakeTasksComment = {
size: 2, total: 2, start: 0,
data: [
{
id: 1, message: 'fake-message-1', created: '', createdBy: fakeUser
},
{
id: 2, message: 'fake-message-2', created: '', createdBy: fakeUser
}
]
};
export var fakeTasksChecklist = {
size: 1, total: 1, start: 0,
data: [
{
id: 1, name: 'FakeCheckTask1', description: null, category: null,
assignee: fakeUser,
created: '2016-07-15T11:19:17.440+0000'
},
{
id: 2, name: 'FakeCheckTask2', description: null, category: null,
assignee: fakeUser,
created: '2016-07-15T11:19:17.440+0000'
}
]
};
export var fakeRepresentationFilter1: FilterRepresentationModel = new FilterRepresentationModel({
appId: 1,
name: 'CONTAIN FILTER',
recent: true,
icon: 'glyphicon-align-left',
filter: {
processDefinitionId: null,
processDefinitionKey: null,
name: null,
state: 'open',
sort: 'created-desc',
assignment: 'involved',
dueAfter: null,
dueBefore: null
}
});
export var fakeRepresentationFilter2: FilterRepresentationModel = new FilterRepresentationModel({
appId: 2,
name: 'NO TASK FILTER',
recent: false,
icon: 'glyphicon-inbox',
filter: {
processDefinitionId: null,
processDefinitionKey: null,
name: null,
state: 'open',
sort: 'created-desc',
assignment: 'assignee',
dueAfter: null,
dueBefore: null
}
});
export var fakeAppPromise = new Promise(function (resolve, reject) {
resolve(fakeAppFilter);
});
export var fakeFormList = {
size: 2,
total: 2,
start: 0,
data: [{
id: 1,
name: 'form with all widgets',
description: '',
createdBy: 2,
createdByFullName: 'Admin Admin',
lastUpdatedBy: 2,
lastUpdatedByFullName: 'Admin Admin',
lastUpdated: 1491400951205,
latestVersion: true,
version: 4,
comment: null,
stencilSet: null,
referenceId: null,
modelType: 2,
favorite: null,
permission: 'write',
tenantId: null
}, {
id: 2,
name: 'uppy',
description: '',
createdBy: 2,
createdByFullName: 'Admin Admin',
lastUpdatedBy: 2,
lastUpdatedByFullName: 'Admin Admin',
lastUpdated: 1490951054477,
latestVersion: true,
version: 2,
comment: null,
stencilSet: null,
referenceId: null,
modelType: 2,
favorite: null,
permission: 'write',
tenantId: null
}]
};

View File

@@ -7,9 +7,9 @@
<div class="menu-container" *ngIf="checklist?.length > 0">
<ul class='mdl-list'>
<li class="mdl-list__item" *ngFor="let check of checklist">
<span class="mdl-list__item-primary-content" id="check-{{check.id}}">
<i class="material-icons mdl-list__item-icon">done</i>
{{check.name}}
<span class="mdl-chip mdl-chip--deletable" id="check-{{check.id}}">
<span class="mdl-chip__text">{{check.name}}</span>
<button type="button" class="mdl-chip__action"><i id="remove-{{check.id}}" (click)="delete(check.id)" class="material-icons">cancel</i></button>
</span>
</li>
</ul>

View File

@@ -140,6 +140,42 @@ describe('ActivitiChecklist', () => {
});
}));
it('should remove a checklist element', async(() => {
checklistComponent.taskId = 'new-fake-task-id';
checklistComponent.checklist.push(fakeTaskDetail);
fixture.detectChanges();
let checklistElementRemove = <HTMLElement> element.querySelector('#remove-fake-check-id');
expect(checklistElementRemove).toBeDefined();
expect(checklistElementRemove).not.toBeNull();
checklistElementRemove.click();
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'json'
});
fixture.whenStable().then(() => {
fixture.detectChanges();
expect(element.querySelector('#fake-check-id')).toBeNull();
});
}));
it('should send an event when the checklist is deleted', (done) => {
checklistComponent.taskId = 'new-fake-task-id';
checklistComponent.checklist.push(fakeTaskDetail);
fixture.detectChanges();
let checklistElementRemove = <HTMLElement> element.querySelector('#remove-fake-check-id');
expect(checklistElementRemove).toBeDefined();
expect(checklistElementRemove).not.toBeNull();
checklistElementRemove.click();
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'json'
});
checklistComponent.checklistTaskDeleted.subscribe(() => {
expect(element.querySelector('#fake-check-id')).toBeNull();
done();
});
});
it('should show load task checklist on change', async(() => {
checklistComponent.taskId = 'new-fake-task-id';
checklistComponent.checklist.push(fakeTaskDetail);

View File

@@ -44,6 +44,9 @@ export class ActivitiChecklist implements OnInit, OnChanges {
@Output()
checklistTaskCreated: EventEmitter<TaskDetailsModel> = new EventEmitter<TaskDetailsModel>();
@Output()
checklistTaskDeleted: EventEmitter<string> = new EventEmitter<string>();
@ViewChild('dialog')
dialog: any;
@@ -129,6 +132,17 @@ export class ActivitiChecklist implements OnInit, OnChanges {
this.cancel();
}
public delete(taskId: string) {
this.activitiTaskList.deleteTask(taskId).subscribe(
() => {
this.checklist = this.checklist.filter(check => check.id !== taskId);
this.checklistTaskDeleted.emit(taskId);
},
(err) => {
this.logService.error(err);
});
}
public cancel() {
if (this.dialog) {
this.dialog.nativeElement.close();

View File

@@ -38,7 +38,8 @@
[readOnly]="readOnlyForm"
[taskId]="taskDetails.id"
[assignee]="taskDetails?.assignee?.id"
(checklistTaskCreated)="onChecklistTaskCreated($event)">
(checklistTaskCreated)="onChecklistTaskCreated($event)"
(checklistTaskDeleted)="onChecklistTaskDeleted($event)">
</activiti-checklist>
</div>
</div>

View File

@@ -96,6 +96,9 @@ export class ActivitiTaskDetails implements OnInit, OnChanges {
@Output()
taskCreated: EventEmitter<TaskDetailsModel> = new EventEmitter<TaskDetailsModel>();
@Output()
taskDeleted: EventEmitter<string> = new EventEmitter<string>();
@Output()
onError: EventEmitter<any> = new EventEmitter<any>();
@@ -258,6 +261,10 @@ export class ActivitiTaskDetails implements OnInit, OnChanges {
this.taskCreated.emit(task);
}
onChecklistTaskDeleted(taskId: string) {
this.taskDeleted.emit(taskId);
}
onFormError(error: any) {
this.errorDialog.nativeElement.showModal();
this.onError.emit(error);

View File

@@ -256,6 +256,15 @@ export class ActivitiTaskListService {
}).catch(err => this.handleError(err));
}
/**
* Delete a task
* @param taskId - string
*/
deleteTask(taskId: string): Observable<TaskDetailsModel> {
return Observable.fromPromise(this.callApiDeleteTask(taskId))
.catch(err => this.handleError(err));
}
/**
* Add a filter
* @param filter - FilterRepresentationModel
@@ -357,6 +366,10 @@ export class ActivitiTaskListService {
return this.apiService.getInstance().activiti.taskApi.addSubtask(task.parentTaskId, task);
}
private callApiDeleteTask(taskId: string) {
return this.apiService.getInstance().activiti.taskApi.deleteTask(taskId);
}
private callApiAddFilter(filter: FilterRepresentationModel) {
return this.apiService.getInstance().activiti.userFiltersApi.createUserTaskFilter(filter);
}