From faf4d7eeaca0573b07fd2aea19c6cb3d39f92459 Mon Sep 17 00:00:00 2001 From: Will Abson Date: Thu, 22 Sep 2016 14:55:25 +0100 Subject: [PATCH] Add new Start Task button Refs #530 --- .../activiti/activiti-demo.component.html | 1 + .../activiti/activiti-demo.component.ts | 9 +- .../activiti-start-process.component.html | 2 +- ng2-components/ng2-activiti-tasklist/index.ts | 3 + .../activiti-start-task.component.css | 7 ++ .../activiti-start-task.component.html | 19 ++++ .../activiti-start-task.component.ts | 105 ++++++++++++++++++ .../components/activiti-tasklist.component.ts | 7 ++ .../ng2-activiti-tasklist/src/i18n/en.json | 16 ++- .../src/models/task-details.model.ts | 1 + .../activiti-tasklist.service.spec.ts | 33 ++++++ .../src/services/activiti-tasklist.service.ts | 17 +++ 12 files changed, 216 insertions(+), 4 deletions(-) create mode 100644 ng2-components/ng2-activiti-tasklist/src/components/activiti-start-task.component.css create mode 100644 ng2-components/ng2-activiti-tasklist/src/components/activiti-start-task.component.html create mode 100644 ng2-components/ng2-activiti-tasklist/src/components/activiti-start-task.component.ts diff --git a/demo-shell-ng2/app/components/activiti/activiti-demo.component.html b/demo-shell-ng2/app/components/activiti/activiti-demo.component.html index 08cf0aca94..fd462fa8bd 100644 --- a/demo-shell-ng2/app/components/activiti/activiti-demo.component.html +++ b/demo-shell-ng2/app/components/activiti/activiti-demo.component.html @@ -19,6 +19,7 @@
Task Filters +
diff --git a/demo-shell-ng2/app/components/activiti/activiti-demo.component.ts b/demo-shell-ng2/app/components/activiti/activiti-demo.component.ts index 27dc8394a4..cc89a8e2b8 100644 --- a/demo-shell-ng2/app/components/activiti/activiti-demo.component.ts +++ b/demo-shell-ng2/app/components/activiti/activiti-demo.component.ts @@ -20,7 +20,8 @@ import { ALFRESCO_TASKLIST_DIRECTIVES, AppDefinitionRepresentationModel, FilterRepresentationModel, UserTaskFilterRepresentationModel, - ActivitiApps + ActivitiApps, + ActivitiTaskList } from 'ng2-activiti-tasklist'; import { ACTIVITI_PROCESSLIST_DIRECTIVES } from 'ng2-activiti-processlist'; import { ActivitiForm } from 'ng2-activiti-form'; @@ -53,7 +54,7 @@ export class ActivitiDemoComponent implements AfterViewChecked { activitidetails: any; @ViewChild('activititasklist') - activititasklist: any; + activititasklist: ActivitiTaskList; @ViewChild('activitiprocessfilter') activitiprocessfilter: any; @@ -146,6 +147,10 @@ export class ActivitiDemoComponent implements AfterViewChecked { this.taskFilter = this.activitifilter.getCurrentFilter(); } + onStartTaskSuccess(event: any) { + this.activititasklist.reload(); + } + onSuccessTaskList(event: UserTaskFilterRepresentationModel) { this.currentTaskId = this.activititasklist.getCurrentTaskId(); } diff --git a/ng2-components/ng2-activiti-processlist/src/components/activiti-start-process.component.html b/ng2-components/ng2-activiti-processlist/src/components/activiti-start-process.component.html index e5ca33e2be..f33ad4fb17 100644 --- a/ng2-components/ng2-activiti-processlist/src/components/activiti-start-process.component.html +++ b/ng2-components/ng2-activiti-processlist/src/components/activiti-start-process.component.html @@ -12,7 +12,7 @@
- +
diff --git a/ng2-components/ng2-activiti-tasklist/index.ts b/ng2-components/ng2-activiti-tasklist/index.ts index edc055d35d..47b081f70c 100644 --- a/ng2-components/ng2-activiti-tasklist/index.ts +++ b/ng2-components/ng2-activiti-tasklist/index.ts @@ -16,6 +16,7 @@ */ import { ActivitiApps } from './src/components/activiti-apps.component'; +import { ActivitiStartProcessButton } from './src/components/activiti-start-task.component'; import { ActivitiTaskList } from './src/components/activiti-tasklist.component'; import { ActivitiTaskDetails } from './src/components/activiti-task-details.component'; import { ActivitiFilters } from './src/components/activiti-filters.component'; @@ -23,6 +24,7 @@ import { NoTaskDetailsTemplateComponent } from './src/components/no-task-detail- export * from './src/components/activiti-apps.component'; export * from './src/components/activiti-tasklist.component'; +export * from './src/components/activiti-start-task.component'; export * from './src/services/activiti-tasklist.service'; export * from './src/models/filter.model'; @@ -30,6 +32,7 @@ export const ALFRESCO_TASKLIST_DIRECTIVES: [any] = [ NoTaskDetailsTemplateComponent, ActivitiApps, ActivitiFilters, + ActivitiStartProcessButton, ActivitiTaskList, ActivitiTaskDetails ]; diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-start-task.component.css b/ng2-components/ng2-activiti-tasklist/src/components/activiti-start-task.component.css new file mode 100644 index 0000000000..ff0f8dd865 --- /dev/null +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-start-task.component.css @@ -0,0 +1,7 @@ +:host { + width: 100%; +} + +.activiti-label { + font-weight: bolder; +} diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-start-task.component.html b/ng2-components/ng2-activiti-tasklist/src/components/activiti-start-task.component.html new file mode 100644 index 0000000000..837e1730fb --- /dev/null +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-start-task.component.html @@ -0,0 +1,19 @@ + + + +

{{'START_TASK.DIALOG.TITLE'|translate}}

+
+
+ + +
+
+ + +
+
+
+ + +
+
diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-start-task.component.ts b/ng2-components/ng2-activiti-tasklist/src/components/activiti-start-task.component.ts new file mode 100644 index 0000000000..5340d5ac8c --- /dev/null +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-start-task.component.ts @@ -0,0 +1,105 @@ +/*! + * @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 { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core'; +import { AlfrescoTranslationService, AlfrescoAuthenticationService } from 'ng2-alfresco-core'; +import { TaskDetailsModel } from '../models/task-details.model'; +import { ActivitiTaskListService } from './../services/activiti-tasklist.service'; + +declare let componentHandler: any; +declare let __moduleName: string; + +@Component({ + selector: 'activiti-start-task', + moduleId: __moduleName, + templateUrl: './activiti-start-task.component.html', + styleUrls: ['./activiti-start-task.component.css'], + providers: [ActivitiTaskListService] +}) +export class ActivitiStartProcessButton implements OnInit { + + @Input() + appId: string; + + @Output() + onSuccess: EventEmitter = new EventEmitter(); + + @ViewChild('dialog') + dialog: any; + + name: string; + description: string; + + /** + * Constructor + * @param auth + * @param translate + * @param taskService + */ + constructor(private auth: AlfrescoAuthenticationService, + private translate: AlfrescoTranslationService, + private taskService: ActivitiTaskListService) { + + if (translate) { + translate.addTranslationFolder('node_modules/ng2-activiti-tasklist/src'); + } + } + + ngOnInit() { + } + + public start() { + if (this.name) { + this.taskService.createNewTask(new TaskDetailsModel({ + name: this.name, + description: this.description, + category: this.appId ? '' + this.appId : null + })).subscribe( + (res: any) => { + this.onSuccess.emit(res); + this.closeDialog(); + this.resetForm(); + }, + (err) => { + window.alert('An error occurred while trying to add the task'); + console.log(err); + } + ); + } + } + + public cancel() { + this.closeDialog(); + } + + public showDialog() { + if (this.dialog) { + this.dialog.nativeElement.showModal(); + } + } + + private closeDialog() { + if (this.dialog) { + this.dialog.nativeElement.close(); + } + } + + private resetForm() { + this.name = ''; + this.description = ''; + } +} diff --git a/ng2-components/ng2-activiti-tasklist/src/components/activiti-tasklist.component.ts b/ng2-components/ng2-activiti-tasklist/src/components/activiti-tasklist.component.ts index ae8da9b896..39ecb41b38 100644 --- a/ng2-components/ng2-activiti-tasklist/src/components/activiti-tasklist.component.ts +++ b/ng2-components/ng2-activiti-tasklist/src/components/activiti-tasklist.component.ts @@ -96,6 +96,13 @@ export class ActivitiTaskList implements OnInit, OnChanges { } } + public reload() { + if (this.taskFilter) { + let requestNode = this.convertTaskUserToTaskQuery(this.taskFilter); + this.load(new TaskQueryRequestRepresentationModel(requestNode)); + } + } + public load(requestNode: TaskQueryRequestRepresentationModel) { this.activiti.getTotalTasks(requestNode).subscribe( (res) => { diff --git a/ng2-components/ng2-activiti-tasklist/src/i18n/en.json b/ng2-components/ng2-activiti-tasklist/src/i18n/en.json index d83089f9f6..8d559cac14 100644 --- a/ng2-components/ng2-activiti-tasklist/src/i18n/en.json +++ b/ng2-components/ng2-activiti-tasklist/src/i18n/en.json @@ -36,5 +36,19 @@ "MESSAGES": { "NONE": "No task filter selected." } + }, + "START_TASK": { + "BUTTON": "Start Task", + "DIALOG": { + "TITLE": "Start Task", + "LABEL": { + "NAME": "Name", + "DESCRIPTION": "Description" + }, + "ACTION": { + "START": "Start", + "CANCEL": "Cancel" + } + } } -} \ No newline at end of file +} diff --git a/ng2-components/ng2-activiti-tasklist/src/models/task-details.model.ts b/ng2-components/ng2-activiti-tasklist/src/models/task-details.model.ts index 7fdc4d37a6..e9408e7c6d 100644 --- a/ng2-components/ng2-activiti-tasklist/src/models/task-details.model.ts +++ b/ng2-components/ng2-activiti-tasklist/src/models/task-details.model.ts @@ -64,6 +64,7 @@ export class TaskDetailsModel { this.priority = obj && obj.priority; this.assignee = new User(obj.assignee); this.adhocTaskCanBeReassigned = obj && obj.adhocTaskCanBeReassigned; + this.category = obj && obj.category || null; this.created = obj && obj.created || null; this.description = obj && obj.description || null; this.dueDate = obj && obj.dueDate || null; diff --git a/ng2-components/ng2-activiti-tasklist/src/services/activiti-tasklist.service.spec.ts b/ng2-components/ng2-activiti-tasklist/src/services/activiti-tasklist.service.spec.ts index f472d08e8a..0262585cb5 100644 --- a/ng2-components/ng2-activiti-tasklist/src/services/activiti-tasklist.service.spec.ts +++ b/ng2-components/ng2-activiti-tasklist/src/services/activiti-tasklist.service.spec.ts @@ -477,5 +477,38 @@ describe('ActivitiTaskListService', () => { }); }); + it('should create a new standalone task ', (done) => { + let taskFake = new TaskDetailsModel({ + name: 'FakeNameTask', + description: 'FakeDescription', + category: '3' + }); + + service.createNewTask(taskFake).subscribe( + (res: TaskDetailsModel) => { + expect(res).toBeDefined(); + expect(res.id).not.toEqual(''); + expect(res.name).toEqual('FakeNameTask'); + expect(res.description).toEqual('FakeDescription'); + expect(res.category).toEqual('3'); + expect(res.created).not.toEqual(''); + done(); + } + ); + + jasmine.Ajax.requests.mostRecent().respondWith({ + 'status': 200, + contentType: 'application/json', + responseText: JSON.stringify({ + id: '777', + name: 'FakeNameTask', + description: 'FakeDescription', + category: '3', + assignee: fakeUser, + created: '2016-07-15T11:19:17.440+0000' + }) + }); + }); + }); diff --git a/ng2-components/ng2-activiti-tasklist/src/services/activiti-tasklist.service.ts b/ng2-components/ng2-activiti-tasklist/src/services/activiti-tasklist.service.ts index c6c86e0db7..8bc00c94d6 100644 --- a/ng2-components/ng2-activiti-tasklist/src/services/activiti-tasklist.service.ts +++ b/ng2-components/ng2-activiti-tasklist/src/services/activiti-tasklist.service.ts @@ -216,6 +216,19 @@ export class ActivitiTaskListService { }).catch(this.handleError); } + /** + * Create a new standalone task + * @param task - TaskDetailsModel + * @returns {TaskDetailsModel} + */ + createNewTask(task: TaskDetailsModel): Observable { + return Observable.fromPromise(this.callApiCreateTask(task)) + .map(res => res) + .map((response: TaskDetailsModel) => { + return new TaskDetailsModel(response); + }).catch(this.handleError); + } + private callApiTasksFiltered(requestNode: TaskQueryRequestRepresentationModel) { return this.authService.getAlfrescoApi().activiti.taskApi.listTasks(requestNode); } @@ -256,6 +269,10 @@ export class ActivitiTaskListService { return this.authService.getAlfrescoApi().activiti.taskApi.completeTask(id); } + private callApiCreateTask(task: TaskDetailsModel) { + return this.authService.getAlfrescoApi().activiti.taskApi.createNewTask(task); + } + private handleError(error: any) { console.error(error); return Observable.throw(error || 'Server error');