Basic single page with activiti task list and form render

This commit is contained in:
mauriziovitale84
2016-07-26 10:36:19 +01:00
parent 0d5274f54c
commit b96dcb7bb0
14 changed files with 416 additions and 110 deletions

View File

@@ -0,0 +1,17 @@
{
"TASK_LIST": {
"MESSAGES": {
"NONE": "No tasks list found."
}
},
"TASK_DETAILS": {
"MESSAGES": {
"NONE": "No task details found."
}
},
"TASK_FILTERS": {
"MESSAGES": {
"NONE": "No task filter selected."
}
}
}

View File

@@ -0,0 +1,17 @@
{
"TASK_LIST": {
"MESSAGES": {
"NONE": "Nessuna lista tasks trovata."
}
},
"TASK_DETAILS": {
"MESSAGES": {
"NONE": "Nessun dettaglio task trovato."
}
},
"TASK_FILTERS": {
"MESSAGES": {
"NONE": "Nessun filtro task selezionato."
}
}
}

View File

@@ -16,7 +16,9 @@
*/
import { ActivitiTaskList } from './src/components/activiti-tasklist.component';
import { ActivitiTaskDetails } from './src/components/activiti-task-details.component';
export * from './src/components/activiti-tasklist.component';
export const ALFRESCO_TASKLIST_DIRECTIVES: [any] = [ActivitiTaskList];
export const ALFRESCO_TASKLIST_DIRECTIVES: [any] = [ActivitiTaskList, ActivitiTaskDetails];

View File

@@ -70,7 +70,8 @@
"zone.js": "0.6.12",
"ng2-translate": "2.2.2",
"ng2-alfresco-core": "0.2.0",
"ng2-alfresco-datatable": "0.2.0",
"ng2-alfresco-datatable": "0.2.0",
"ng2-activiti-form": "0.2.0",
"alfresco-js-api": "^0.1.0"
},
"peerDependencies": {

View File

@@ -0,0 +1,3 @@
:host {
width: 100%;
}

View File

@@ -0,0 +1,13 @@
<div *ngIf="!taskDetails">
<h3 style="text-align: center">{{ 'TASK_DETAILS.MESSAGES.NONE' | translate }}</h3>
</div>
<div *ngIf="taskDetails">
<h2 class="mdl-card__title-text">{{taskDetails.name}}</h2>
<div class="mdl-grid">
<div class="mdl-cell mdl-cell--4-col">Email: {{taskDetails.assignee.email}}</div>
<div class="mdl-cell mdl-cell--4-col">FirstName: {{taskDetails.assignee.firstName}}</div>
<div class="mdl-cell mdl-cell--4-col">LastName: {{taskDetails.assignee.lastName}}</div>
</div>
<activiti-form *ngIf="taskDetails.formKey" [taskId]="taskDetails.id" ></activiti-form>
</div>

View File

@@ -0,0 +1,92 @@
/*!
* @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, Input, OnInit, OnChanges } from '@angular/core';
import { AlfrescoTranslationService, AlfrescoAuthenticationService, AlfrescoPipeTranslate } from 'ng2-alfresco-core';
import { ActivitiTaskListService } from './../services/activiti-tasklist.service';
import { TaskDetailsModel } from '../models/task-details.model';
import { ActivitiForm } from 'ng2-activiti-form';
declare let componentHandler: any;
declare let __moduleName: string;
@Component({
selector: 'activiti-task-details',
moduleId: __moduleName,
templateUrl: './activiti-task-details.component.html',
styleUrls: ['./activiti-task-details.component.css'],
providers: [ActivitiTaskListService],
directives: [ActivitiForm],
pipes: [ AlfrescoPipeTranslate ]
})
export class ActivitiTaskDetails implements OnInit, OnChanges {
@Input()
taskId: string;
taskDetails: TaskDetailsModel;
/**
* Constructor
* @param auth
* @param translate
*/
constructor(private auth: AlfrescoAuthenticationService,
private translate: AlfrescoTranslationService,
public activiti: ActivitiTaskListService) {
if (translate) {
translate.addTranslationFolder('node_modules/ng2-activiti-tasklist');
}
}
ngOnInit() {
if (this.taskId) {
this.activiti.getTaskDetails(this.taskId).subscribe(
(res: TaskDetailsModel) => {
this.taskDetails = res;
console.log(this.taskDetails);
}
);
}
}
ngOnChanges(change) {
this.loadDetails(this.taskId);
}
loadDetails(id: string) {
if (id) {
this.activiti.getTaskDetails(id).subscribe(
(res: TaskDetailsModel) => {
this.taskDetails = res;
console.log(this.taskDetails);
}
);
}
}
onComplete() {
this.activiti.completeTask(this.taskId).subscribe(
(res) => {
console.log(res);
}
);
}
}

View File

@@ -1,12 +1,23 @@
<div [ngStyle]="locationCss" class="menu-container">
<ul class="context-menu">
<li (click)="selectFilter(filter)" *ngFor="let filter of filtersList | async">
<div class="menu-container">
<ul class='mdl-list'>
<li class="mdl-list__item"(click)="selectFilter(filter)" *ngFor="let filter of filtersList | async">
<span class="mdl-list__item-primary-content">
<i class="material-icons mdl-list__item-icon">assignment</i>
{{filter.name}}
</span>
</li>
</ul>
</div>
<alfresco-datatable
[data]="tasks"
(rowClick)="onRowClick($event)">
</alfresco-datatable>
<div *ngIf="currentFilter">
<div *ngIf="!isTaskListEmpty()">
<alfresco-datatable
[data]="tasks"
(rowClick)="onRowClick($event)">
</alfresco-datatable>
</div>
<div *ngIf="isTaskListEmpty()">
{{ 'TASK_LIST.MESSAGES.NONE' | translate }}
</div>
</div>
<div *ngIf="!currentFilter">{{ 'TASK_FILTERS.MESSAGES.NONE' | translate }}</div>

View File

@@ -15,8 +15,8 @@
* limitations under the License.
*/
import { Component, Input, OnInit} from '@angular/core';
import { AlfrescoTranslationService, AlfrescoAuthenticationService } from 'ng2-alfresco-core';
import { Component, Input, Output, EventEmitter, OnInit} from '@angular/core';
import { AlfrescoTranslationService, AlfrescoAuthenticationService, AlfrescoPipeTranslate } from 'ng2-alfresco-core';
import { ALFRESCO_DATATABLE_DIRECTIVES, ObjectDataTableAdapter, DataTableAdapter, DataRowEvent } from 'ng2-alfresco-datatable';
import { ActivitiTaskListService } from './../services/activiti-tasklist.service';
import { FilterModel } from '../models/filter.model';
@@ -31,7 +31,8 @@ declare let __moduleName: string;
moduleId: __moduleName,
templateUrl: './activiti-tasklist.component.html',
directives: [ALFRESCO_DATATABLE_DIRECTIVES],
providers: [ActivitiTaskListService]
providers: [ActivitiTaskListService],
pipes: [ AlfrescoPipeTranslate ]
})
export class ActivitiTaskList implements OnInit {
@@ -39,11 +40,15 @@ export class ActivitiTaskList implements OnInit {
@Input()
data: DataTableAdapter;
@Output()
rowClick: EventEmitter<string> = new EventEmitter<string>();
private filterObserver: Observer<FilterModel>;
filter$: Observable<FilterModel>;
tasks: ObjectDataTableAdapter;
currentFilter: FilterModel;
currentTaskId: string;
filtersList: Observable<FilterModel>;
@@ -89,12 +94,18 @@ export class ActivitiTaskList implements OnInit {
* @param filter
*/
public selectFilter(filter: FilterModel) {
this.currentFilter = filter;
this.filterObserver.next(filter);
}
isTaskListEmpty(): boolean {
return this.tasks && this.tasks.getRows().length === 0;
}
onRowClick(event: DataRowEvent) {
let item = event;
this.currentTaskId = item.value.getValue('id');
this.rowClick.emit(this.currentTaskId);
}
/**

View File

@@ -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.
*/
/**
*
* This object represent the details of a task.
*
*
* @returns {TaskDetailsModel} .
*/
export class TaskDetailsModel {
id: string;
name: string;
assignee: User;
priority: number;
adhocTaskCanBeReassigned: number;
category: string;
created: string;
description: string;
dueDate: string;
duration: string;
endDate: string;
executionId: string;
formKey: string;
initiatorCanCompleteTask: boolean = false;
managerOfCandidateGroup: boolean = false;
memberOfCandidateGroup: boolean = false;
memberOfCandidateUsers: boolean = false;
involvedPeople: User [];
parentTaskId: string;
parentTaskName: string;
processDefinitionCategory: string;
processDefinitionDeploymentId: string;
processDefinitionDescription: string;
processDefinitionId: string;
processDefinitionKey: string;
processDefinitionName: string;
processDefinitionVersion: number = 0;
processInstanceId: string;
processInstanceName: string;
processInstanceStartUserId: string;
taskDefinitionKey: string;
constructor(obj: any) {
this.id = obj.id;
this.name = obj.name;
this.priority = obj.priority;
this.assignee = new User(obj.assignee.id, obj.assignee.email, obj.assignee.firstName, obj.assignee.lastName);
this.adhocTaskCanBeReassigned = obj.adhocTaskCanBeReassigned;
this.created = obj.created;
this.description = obj.description;
this.dueDate = obj.dueDate;
this.duration = obj.duration;
this.endDate = obj.endDate;
this.executionId = obj.executionId;
this.formKey = obj.formKey;
this.initiatorCanCompleteTask = obj.initiatorCanCompleteTask;
this.managerOfCandidateGroup = obj.managerOfCandidateGroup;
this.memberOfCandidateGroup = obj.memberOfCandidateGroup;
this.memberOfCandidateUsers = obj.memberOfCandidateUsers;
this.involvedPeople = obj.involvedPeople;
this.parentTaskId = obj.parentTaskId;
this.parentTaskName = obj.parentTaskName;
this.processDefinitionCategory = obj.processDefinitionCategory;
this.processDefinitionDeploymentId = obj.processDefinitionDeploymentId;
this.processDefinitionDescription = obj.processDefinitionDescription;
this.processDefinitionId = obj.processDefinitionId;
this.processDefinitionKey = obj.processDefinitionKey;
this.processDefinitionName = obj.processDefinitionName;
this.processDefinitionVersion = obj.processDefinitionVersion;
this.processInstanceId = obj.processInstanceId;
this.processInstanceName = obj.processInstanceName;
this.processInstanceStartUserId = obj.processInstanceStartUserId;
this.taskDefinitionKey = obj.taskDefinitionKey;
}
}
export class User {
id: number;
email: string;
firstName: string;
lastName: string;
constructor(id: number, email: string, firstName: string, lastName: string) {
this.id = id;
this.email = email;
this.firstName = firstName;
this.lastName = lastName;
}
}

View File

@@ -20,6 +20,7 @@ import { AlfrescoSettingsService } from 'ng2-alfresco-core';
import { Http, Headers, RequestOptions, Response } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import { FilterModel } from '../models/filter.model';
import { TaskDetailsModel } from '../models/task-details.model';
@Injectable()
export class ActivitiTaskListService {
@@ -45,10 +46,13 @@ export class ActivitiTaskListService {
*/
getTasks(filter: FilterModel): Observable<any> {
let data: any = {};
data.filterId = filter.id;
data.filter = filter.filter;
// data.filterId = filter.id;
// data.filter = filter.filter;
data = filter.filter;
data.text = filter.filter.name;
data = JSON.stringify(data);
return Observable.fromPromise(this.callApiTasksFiltered(data))
.map((res: Response) => {
return res.json();
@@ -56,12 +60,28 @@ export class ActivitiTaskListService {
.catch(this.handleError);
}
getTaskDetails(id: string): Observable<TaskDetailsModel> {
return Observable.fromPromise(this.callApiTaskDetails(id))
.map(res => res.json())
.map((details: any) => {
return new TaskDetailsModel(details);
})
.catch(this.handleError);
}
completeTask(id: string): Observable<TaskDetailsModel> {
return Observable.fromPromise(this.callApiCompleteTask(id))
.catch(this.handleError);
}
private callApiTasksFiltered(data: Object) {
let url = this.alfrescoSettingsService.getBPMApiBaseUrl() + '/rest/filter/tasks';
let url = this.alfrescoSettingsService.getBPMApiBaseUrl() + '/api/enterprise/tasks/query';
// let url = 'http://localhost:9999/activiti-app/app/rest/filter/tasks';
let headers = new Headers({
'Content-Type': 'application/json',
'Cache-Control': 'no-cache'
});
// let body = JSON.stringify(data);
let options = new RequestOptions({headers: headers});
return this.http
@@ -69,7 +89,8 @@ export class ActivitiTaskListService {
}
private callApiTaskFilters() {
let url = this.alfrescoSettingsService.getBPMApiBaseUrl() + '/rest/filters/tasks';
let url = this.alfrescoSettingsService.getBPMApiBaseUrl() + '/api/enterprise/filters/tasks';
// let url = 'http://localhost:9999/activiti-app/app/rest/filters/tasks';
let headers = new Headers({
'Content-Type': 'application/json',
'Cache-Control': 'no-cache'
@@ -80,6 +101,32 @@ export class ActivitiTaskListService {
.get(url, options).toPromise();
}
private callApiTaskDetails(id: string) {
let url = this.alfrescoSettingsService.getBPMApiBaseUrl() + `/api/enterprise/tasks/${id}`;
// let url = 'http://localhost:9999/activiti-app/app/rest/tasks/' + id;
let headers = new Headers({
'Content-Type': 'application/json',
'Cache-Control': 'no-cache'
});
let options = new RequestOptions({headers: headers});
return this.http
.get(url, options).toPromise();
}
private callApiCompleteTask(id: string) {
let url = this.alfrescoSettingsService.getBPMApiBaseUrl() + `/api/enterprise/tasks/${id}/action/complete`;
// let url = `http://localhost:9999/activiti-app/app/rest/tasks/${id}/action/complete`;
let headers = new Headers({
'Content-Type': 'application/json',
'Cache-Control': 'no-cache'
});
let options = new RequestOptions({headers: headers});
return this.http
.put(url, options).toPromise();
}
/**
* The method write the error in the console browser