mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-26 17:24:56 +00:00
Merge pull request #801 from Alfresco/dev-wabson-530
Add start task button component and add to demo-shell
This commit is contained in:
commit
ef1769bae7
@ -19,6 +19,7 @@
|
||||
<div class="mdl-grid">
|
||||
<div class="mdl-cell mdl-cell--2-col task-column mdl-shadow--2dp">
|
||||
<span>Task Filters</span>
|
||||
<activiti-start-task [appId]="appId" (onSuccess)="onStartTaskSuccess($event)"></activiti-start-task>
|
||||
<activiti-filters [appId]="appId" (filterClick)="onTaskFilterClick($event)" (onSuccess)="onSuccessTaskFilterList($event)"
|
||||
#activitifilter></activiti-filters>
|
||||
</div>
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
<label class="mdl-textfield__label" for="processDefinition">{{'START_PROCESS.DIALOG.LABEL.TYPE'|translate}}</label>
|
||||
</div>
|
||||
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
|
||||
<input class="mdl-textfield__input" type="text" [(ngModel)]="name" rows="1" id="processName" />
|
||||
<input class="mdl-textfield__input" type="text" [(ngModel)]="name" id="processName" />
|
||||
<label class="mdl-textfield__label" for="processName">{{'START_PROCESS.DIALOG.LABEL.NAME'|translate}}</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -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
|
||||
];
|
||||
|
@ -0,0 +1,7 @@
|
||||
:host {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.activiti-label {
|
||||
font-weight: bolder;
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
<button type="button" (click)="showDialog()" class="mdl-button">{{'START_TASK.BUTTON'|translate}}</button>
|
||||
|
||||
<dialog class="mdl-dialog" #dialog>
|
||||
<h4 class="mdl-dialog__title">{{'START_TASK.DIALOG.TITLE'|translate}}</h4>
|
||||
<div class="mdl-dialog__content">
|
||||
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
|
||||
<input class="mdl-textfield__input" type="text" [(ngModel)]="name" id="taskName" />
|
||||
<label class="mdl-textfield__label" for="taskName">{{'START_TASK.DIALOG.LABEL.NAME'|translate}}</label>
|
||||
</div>
|
||||
<div class="mdl-textfield mdl-js-textfield">
|
||||
<textarea class="mdl-textfield__input" type="text" [(ngModel)]="description" rows="3" id="taskDescription"></textarea>
|
||||
<label class="mdl-textfield__label" for="taskDescription">{{'START_TASK.DIALOG.LABEL.DESCRIPTION'|translate}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mdl-dialog__actions">
|
||||
<button type="button" (click)="start()" class="mdl-button">{{'START_TASK.DIALOG.ACTION.START'|translate}}</button>
|
||||
<button type="button" (click)="cancel()" class="mdl-button close">{{'START_TASK.DIALOG.ACTION.CANCEL'|translate}}</button>
|
||||
</div>
|
||||
</dialog>
|
@ -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<any> = new EventEmitter<any>();
|
||||
|
||||
@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 = '';
|
||||
}
|
||||
}
|
@ -33,6 +33,8 @@
|
||||
(onError)='onErrorEmitter($event)'
|
||||
(executeOutcome)='executeOutcomeEmitter($event)'
|
||||
#activitiForm>
|
||||
|
||||
</activiti-form>
|
||||
<button type="button" class="mdl-button" *ngIf="!hasFormKey() && isTaskActive()" (click)="onComplete()">
|
||||
{{ 'TASK_DETAILS.BUTTON.COMPLETE' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -133,6 +133,10 @@ export class ActivitiTaskDetails implements OnInit, OnChanges {
|
||||
&& this.taskDetails.formKey !== 'null';
|
||||
}
|
||||
|
||||
isTaskActive() {
|
||||
return this.taskDetails && this.taskDetails.duration === null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the activiti task details
|
||||
* @param taskId
|
||||
@ -160,7 +164,6 @@ export class ActivitiTaskDetails implements OnInit, OnChanges {
|
||||
if (this.activitichecklist) {
|
||||
this.activitichecklist.load(this.taskDetails.id);
|
||||
}
|
||||
console.log(this.taskDetails);
|
||||
|
||||
}
|
||||
);
|
||||
@ -176,6 +179,7 @@ export class ActivitiTaskDetails implements OnInit, OnChanges {
|
||||
this.activitiTaskList.completeTask(this.taskId).subscribe(
|
||||
(res) => {
|
||||
console.log(res);
|
||||
this.formCompleted.emit(res);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -132,6 +132,23 @@ describe('ActivitiTaskList', () => {
|
||||
taskList.ngOnInit();
|
||||
});
|
||||
|
||||
it('should reload tasks when reload() is called', (done) => {
|
||||
spyOn(taskList.activiti, 'getTotalTasks').and.returnValue(Observable.fromPromise(fakeGlobalTotalTasksPromise));
|
||||
spyOn(taskList.activiti, 'getTasks').and.returnValue(Observable.fromPromise(fakeGlobalTaskPromise));
|
||||
taskList.taskFilter = new UserTaskFilterRepresentationModel({filter: { state: 'open', assignment: 'fake-assignee'}});
|
||||
taskList.ngOnInit();
|
||||
taskList.onSuccess.subscribe( (res) => {
|
||||
expect(res).toBeDefined();
|
||||
expect(taskList.data).toBeDefined();
|
||||
expect(taskList.isTaskListEmpty()).not.toBeTruthy();
|
||||
expect(taskList.data.getRows().length).toEqual(2);
|
||||
expect(taskList.data.getRows()[0].getValue('name')).toEqual('fake-long-name-fake-long-name-fake-long-name-fak50...');
|
||||
expect(taskList.data.getRows()[1].getValue('name')).toEqual('Nameless task');
|
||||
done();
|
||||
});
|
||||
taskList.reload();
|
||||
});
|
||||
|
||||
it('should emit row click event', (done) => {
|
||||
let row = new ObjectDataRow({
|
||||
id: 999
|
||||
|
@ -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) => {
|
||||
|
@ -13,6 +13,9 @@
|
||||
"COMMENTS": "Comments",
|
||||
"CHECKLIST": "Checklist"
|
||||
},
|
||||
"BUTTON": {
|
||||
"COMPLETE": "Complete"
|
||||
},
|
||||
"MESSAGES": {
|
||||
"NONE": "No task details found."
|
||||
},
|
||||
@ -36,5 +39,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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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'
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
@ -216,6 +216,19 @@ export class ActivitiTaskListService {
|
||||
}).catch(this.handleError);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new standalone task
|
||||
* @param task - TaskDetailsModel
|
||||
* @returns {TaskDetailsModel}
|
||||
*/
|
||||
createNewTask(task: TaskDetailsModel): Observable<TaskDetailsModel> {
|
||||
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');
|
||||
|
Loading…
x
Reference in New Issue
Block a user