mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2026-09-09 18:03:21 +00:00
Merge pull request #494 from Alfresco/dev-mvitale-464
Create a single page for Activiti components
This commit is contained in:
@@ -2,3 +2,13 @@
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.activiti {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.task-column {
|
||||
background-color: #f5f5f5;
|
||||
padding: 10px 10px 10px 10px;
|
||||
border: solid 2px rgb(31,188,210);
|
||||
}
|
||||
|
||||
@@ -1,22 +1,60 @@
|
||||
<div class="mdl-grid">
|
||||
|
||||
<div class="mdl-cell mdl-cell--2-col">
|
||||
<div *ngIf="!hasTasks()">No tasks found</div>
|
||||
<div *ngIf="hasTasks()">
|
||||
<ul class="mdl-list">
|
||||
<li *ngFor="let task of tasks"
|
||||
class="mdl-list__item activiti-task-list__item"
|
||||
(click)="onTaskClicked(task, $event)">
|
||||
<span class="mdl-list__item-primary-content">
|
||||
<i class="material-icons mdl-list__item-icon">launch</i>
|
||||
{{task.name || 'Nameless task'}}
|
||||
</span>
|
||||
</ul>
|
||||
<div class="mdl-layout mdl-js-layout mdl-layout--fixed-header">
|
||||
<header class="mdl-layout__header">
|
||||
<!-- Tabs -->
|
||||
<div class="mdl-layout__tab-bar mdl-js-ripple-effect">
|
||||
<a href="#scroll-tab-1" class="mdl-layout__tab is-active">TASK LIST</a>
|
||||
<a href="#scroll-tab-2" class="mdl-layout__tab">PROCESS LIST</a>
|
||||
<a href="#scroll-tab-3" class="mdl-layout__tab">REPORT</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mdl-cell mdl-cell--10-col">
|
||||
<activiti-form [taskId]="selectedTask?.id"></activiti-form>
|
||||
</div>
|
||||
|
||||
</header>
|
||||
<main class="mdl-layout__content activiti">
|
||||
<section class="mdl-layout__tab-panel is-active" id="scroll-tab-1">
|
||||
<div class="page-content">
|
||||
<div class="mdl-grid">
|
||||
<div class="mdl-cell mdl-cell--2-col task-column">
|
||||
<span>Task Filters</span>
|
||||
<activiti-filters (filterClick)="onFilterClick($event)"></activiti-filters>
|
||||
</div>
|
||||
<div class="mdl-cell mdl-cell--3-col task-column">
|
||||
<span>Task List</span>
|
||||
<activiti-tasklist *ngIf="isTaskListSelected()" [taskFilter]="taskFilter" [schemaColumn]="schemaColumn"
|
||||
(rowClick)="onRowClick($event)" #activititasklist></activiti-tasklist>
|
||||
</div>
|
||||
<div class="mdl-cell mdl-cell--7-col task-column">
|
||||
<span>Task Details</span>
|
||||
<activiti-task-details [taskId]="currentTaskId" #activitidetails></activiti-task-details>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="mdl-layout__tab-panel" id="scroll-tab-2">
|
||||
<div class="page-content">
|
||||
<div class="page-content">
|
||||
<div class="mdl-grid">
|
||||
<div class="mdl-cell mdl-cell--2-col task-column">
|
||||
<span>Process Filters</span>
|
||||
</div>
|
||||
<div class="mdl-cell mdl-cell--3-col task-column">
|
||||
<span>Process List</span>
|
||||
</div>
|
||||
<div class="mdl-cell mdl-cell--7-col task-column">
|
||||
<span>Process Details</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="mdl-layout__tab-panel" id="scroll-tab-3">
|
||||
<div class="page-content"><!-- Your content goes here --></div>
|
||||
</section>
|
||||
<section class="mdl-layout__tab-panel" id="scroll-tab-4">
|
||||
<div class="page-content"><!-- Your content goes here --></div>
|
||||
</section>
|
||||
<section class="mdl-layout__tab-panel" id="scroll-tab-5">
|
||||
<div class="page-content"><!-- Your content goes here --></div>
|
||||
</section>
|
||||
<section class="mdl-layout__tab-panel" id="scroll-tab-6">
|
||||
<div class="page-content"><!-- Your content goes here --></div>
|
||||
</section>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, OnInit, AfterViewChecked } from '@angular/core';
|
||||
import { ActivitiForm, FormService } from 'ng2-activiti-form';
|
||||
|
||||
import { Component, OnInit, AfterViewChecked, ViewChild } from '@angular/core';
|
||||
import { ALFRESCO_TASKLIST_DIRECTIVES } from 'ng2-activiti-tasklist';
|
||||
import { ActivitiForm } from 'ng2-activiti-form';
|
||||
|
||||
declare let __moduleName: string;
|
||||
declare var componentHandler;
|
||||
@@ -27,22 +27,52 @@ declare var componentHandler;
|
||||
selector: 'activiti-demo',
|
||||
templateUrl: './activiti-demo.component.html',
|
||||
styleUrls: ['./activiti-demo.component.css'],
|
||||
directives: [ActivitiForm],
|
||||
providers: [FormService]
|
||||
directives: [ALFRESCO_TASKLIST_DIRECTIVES, ActivitiForm]
|
||||
})
|
||||
export class ActivitiDemoComponent implements OnInit, AfterViewChecked {
|
||||
|
||||
tasks: any[] = [];
|
||||
selectedTask: any;
|
||||
currentChoice: string = 'task-list';
|
||||
|
||||
hasTasks(): boolean {
|
||||
return this.tasks && this.tasks.length > 0;
|
||||
@ViewChild('activitidetails')
|
||||
activitidetails: any;
|
||||
|
||||
@ViewChild('activititasklist')
|
||||
activititasklist: any;
|
||||
|
||||
currentTaskId: string;
|
||||
|
||||
schemaColumn: any [] = [];
|
||||
|
||||
taskFilter: any;
|
||||
|
||||
setChoice($event) {
|
||||
this.currentChoice = $event.target.value;
|
||||
}
|
||||
|
||||
constructor(private formService: FormService) {}
|
||||
isProcessListSelected() {
|
||||
return this.currentChoice === 'process-list';
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.formService.getTasks().subscribe(val => this.tasks = val || []);
|
||||
isTaskListSelected() {
|
||||
return this.currentChoice === 'task-list';
|
||||
}
|
||||
|
||||
constructor() {
|
||||
console.log('Activiti demo component');
|
||||
this.schemaColumn = [
|
||||
{type: 'text', key: 'name', title: 'Name', cssClass: 'full-width name-column', sortable: true}
|
||||
// {type: 'text', key: 'created', title: 'Created', sortable: true}
|
||||
];
|
||||
}
|
||||
|
||||
onFilterClick(event: any) {
|
||||
this.taskFilter = event;
|
||||
this.activititasklist.load(this.taskFilter);
|
||||
}
|
||||
|
||||
onRowClick(taskId) {
|
||||
this.currentTaskId = taskId;
|
||||
this.activitidetails.loadDetails(this.currentTaskId);
|
||||
}
|
||||
|
||||
ngAfterViewChecked() {
|
||||
@@ -52,8 +82,4 @@ export class ActivitiDemoComponent implements OnInit, AfterViewChecked {
|
||||
}
|
||||
}
|
||||
|
||||
onTaskClicked(task, e) {
|
||||
this.selectedTask = task;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
/*!
|
||||
* @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 { Injectable } from '@angular/core';
|
||||
import { Http, Headers, RequestOptions, Response } from '@angular/http';
|
||||
// import { Observable } from 'rxjs/Rx';
|
||||
|
||||
@Injectable()
|
||||
export class ActivitiService {
|
||||
|
||||
constructor(private http: Http) {}
|
||||
|
||||
login(username: string, password: string) {
|
||||
let url = 'http://localhost:9999/activiti-app/app/authentication';
|
||||
let headers = new Headers({
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
'Cache-Control': 'no-cache'
|
||||
});
|
||||
let options = new RequestOptions({ headers: headers });
|
||||
let data = 'j_username='
|
||||
+ encodeURIComponent(username)
|
||||
+ '&j_password='
|
||||
+ encodeURIComponent(password)
|
||||
+ '&_spring_security_remember_me=true&submit=Login';
|
||||
|
||||
return this.http
|
||||
.post(url, data, options)
|
||||
.toPromise()
|
||||
// .then(res => console.log(res))
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
getTasks() {
|
||||
// emulate filter value
|
||||
let data = JSON.stringify({
|
||||
'page': 0,
|
||||
'filterId': 3,
|
||||
'filter': {
|
||||
'sort': 'created-desc',
|
||||
'name': '',
|
||||
'state': 'open',
|
||||
'assignment': 'involved'
|
||||
},
|
||||
'appDefinitionId': null
|
||||
});
|
||||
|
||||
let url = 'http://localhost:9999/activiti-app/app/rest/filter/tasks';
|
||||
let headers = new Headers({
|
||||
'Content-Type': 'application/json',
|
||||
'Cache-Control': 'no-cache'
|
||||
});
|
||||
let options = new RequestOptions({ headers: headers });
|
||||
|
||||
return this.http
|
||||
.post(url, data, options)
|
||||
.toPromise()
|
||||
.then(this.parseJSON)
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
private parseJSON(res: Response) {
|
||||
let body = res.json();
|
||||
return body.data || { };
|
||||
}
|
||||
|
||||
private handleError(error: any) {
|
||||
console.error('An error occurred', error);
|
||||
return Promise.reject(error.message || error);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/*!
|
||||
* @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, OnInit } from '@angular/core';
|
||||
import { ActivitiTaskList } from 'ng2-activiti-tasklist';
|
||||
import { ObjectDataTableAdapter, ObjectDataColumn } from 'ng2-alfresco-datatable';
|
||||
|
||||
@Component({
|
||||
selector: 'tasks-demo',
|
||||
template: `
|
||||
<div class="container">
|
||||
<activiti-tasklist [data]="data"></activiti-tasklist>
|
||||
</div>
|
||||
`,
|
||||
directives: [ActivitiTaskList],
|
||||
styles: [':host > .container { padding: 10px; }']
|
||||
})
|
||||
export class TasksDemoComponent implements OnInit {
|
||||
|
||||
data: ObjectDataTableAdapter;
|
||||
constructor() {
|
||||
this.data = new ObjectDataTableAdapter([], []);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
let schema = [
|
||||
{type: 'text', key: 'id', title: 'Id'},
|
||||
{type: 'text', key: 'name', title: 'Name', cssClass: 'full-width name-column', sortable: true},
|
||||
{type: 'text', key: 'formKey', title: 'Form Key', sortable: true},
|
||||
{type: 'text', key: 'created', title: 'Created', sortable: true}
|
||||
];
|
||||
|
||||
let columns = schema.map(col => new ObjectDataColumn(col));
|
||||
this.data.setColumns(columns);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1 +1,150 @@
|
||||
# Activiti Task List Component for Angular 2
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you start using this development framework, make sure you have installed all required software and done all the
|
||||
necessary configuration, see this [page](https://github.com/Alfresco/alfresco-ng2-components/blob/master/PREREQUISITES.md).
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
npm install --save ng2-activiti-tasklist
|
||||
```
|
||||
|
||||
### Dependencies
|
||||
|
||||
You must separately install the following libraries for your application:
|
||||
|
||||
- [ng2-translate](https://github.com/ocombe/ng2-translate)
|
||||
- [ng2-alfresco-core](https://www.npmjs.com/package/ng2-alfresco-core)
|
||||
- [ng2-alfresco-datatable](https://www.npmjs.com/package/ng2-alfresco-datatable)
|
||||
|
||||
|
||||
```sh
|
||||
npm install --save ng2-translate ng2-alfresco-core ng2-alfresco-datatable
|
||||
```
|
||||
|
||||
#### Material Design Lite
|
||||
|
||||
The style of this component is based on [material design](https://getmdl.io/), so if you want to visualize it correctly you have to add the material
|
||||
design dependency to your project:
|
||||
|
||||
```sh
|
||||
npm install --save material-design-icons material-design-lite
|
||||
```
|
||||
|
||||
Also make sure you include these dependencies in your `index.html` file:
|
||||
|
||||
```html
|
||||
<!-- Google Material Design Lite -->
|
||||
<link rel="stylesheet" href="node_modules/material-design-lite/material.min.css">
|
||||
<script src="node_modules/material-design-lite/material.min.js"></script>
|
||||
<link rel="stylesheet" href="node_modules/material-design-icons/iconfont/material-icons.css">
|
||||
```
|
||||
|
||||
## Basic usage example Activiti Task List
|
||||
The component shows the list of all the tasks filter by the
|
||||
FilterModel passed in input.
|
||||
```html
|
||||
<activiti-tasklist [taskFilter]="taskFilterModel"></activiti-tasklist>
|
||||
```
|
||||
|
||||
#### Events
|
||||
**onSuccess**: The event is emitted when the task list is loaded
|
||||
**rowClick**: The event is emitted when the task in the list is
|
||||
clicked<br />
|
||||
|
||||
#### Options
|
||||
|
||||
**taskFilter**: { FilterModel } required) FilterModel object that
|
||||
is passed to the task list API to filter the task list.
|
||||
Example:
|
||||
```json
|
||||
{
|
||||
"id": 4,
|
||||
"name": "Involved Tasks",
|
||||
"recent": false,
|
||||
"icon": "glyphicon-align-left",
|
||||
"filter": {
|
||||
"sort": "created-desc",
|
||||
"name": "",
|
||||
"state": "open",
|
||||
"assignment": "involved"
|
||||
}
|
||||
}
|
||||
```
|
||||
**schemaColumn**: { any[] } optional) JSON object that represent
|
||||
the number and the type of the columns that you want show
|
||||
Example:
|
||||
```json
|
||||
[
|
||||
{type: 'text', key: 'id', title: 'Id'},
|
||||
{type: 'text', key: 'name', title: 'Name', cssClass: 'full-width name-column', sortable: true},
|
||||
{type: 'text', key: 'formKey', title: 'Form Key', sortable: true},
|
||||
{type: 'text', key: 'created', title: 'Created', sortable: true}
|
||||
]
|
||||
```
|
||||
|
||||
## Basic usage example Activiti Task Details
|
||||
The component shows the details of the task id passed in input
|
||||
```html
|
||||
<activiti-task-details [taskId]="taskId"></activiti-task-details>
|
||||
```
|
||||
|
||||
#### Events
|
||||
No events
|
||||
|
||||
#### Options
|
||||
|
||||
**taskId**: { string } required) The id of the task details that we
|
||||
are asking for.
|
||||
|
||||
## Basic usage example Activiti Filter
|
||||
The component shows all the available filters.
|
||||
|
||||
```html
|
||||
<activiti-filters></activiti-filters>
|
||||
```
|
||||
|
||||
#### Events
|
||||
**filterClick**: The event is emitted when the filter in the list is
|
||||
clicked
|
||||
|
||||
#### Options
|
||||
No options
|
||||
|
||||
## Build from sources
|
||||
|
||||
Alternatively you can build component from sources with the following commands:
|
||||
|
||||
```sh
|
||||
npm install
|
||||
npm run build
|
||||
```
|
||||
|
||||
### Build the files and keep watching for changes
|
||||
|
||||
```sh
|
||||
$ npm run build:w
|
||||
```
|
||||
|
||||
### Running unit tests
|
||||
|
||||
```sh
|
||||
npm test
|
||||
```
|
||||
|
||||
### Running unit tests in browser
|
||||
|
||||
```sh
|
||||
npm test-browser
|
||||
```
|
||||
|
||||
This task rebuilds all the code, runs tslint, license checks and other quality check tools
|
||||
before performing unit testing.
|
||||
|
||||
### Code coverage
|
||||
|
||||
```sh
|
||||
npm run coverage
|
||||
```
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"TASK_LIST": {
|
||||
"MESSAGES": {
|
||||
"NONE": "No tasks list found."
|
||||
}
|
||||
},
|
||||
"TASK_DETAILS": {
|
||||
"LABELS": {
|
||||
"ASSIGNEE": "Assignee",
|
||||
"DUE": "Due",
|
||||
"FORM": "Form",
|
||||
"PEOPLE": "People",
|
||||
"COMMENTS": "Comments",
|
||||
"CHECKLIST": "Checklist"
|
||||
},
|
||||
"MESSAGES": {
|
||||
"NONE": "No task details found."
|
||||
},
|
||||
"FORM": {
|
||||
"NONE": "No form."
|
||||
},
|
||||
"DUE": {
|
||||
"NONE": "No due date."
|
||||
},
|
||||
"PEOPLE": {
|
||||
"NONE": "No people involved."
|
||||
},
|
||||
"COMMENTS": {
|
||||
"NONE": "No comments."
|
||||
},
|
||||
"CHECKLIST": {
|
||||
"NONE": "No checklist."
|
||||
}
|
||||
},
|
||||
"TASK_FILTERS": {
|
||||
"MESSAGES": {
|
||||
"NONE": "No task filter selected."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"TASK_LIST": {
|
||||
"MESSAGES": {
|
||||
"NONE": "Nessuna lista tasks trovata."
|
||||
}
|
||||
},
|
||||
"TASK_DETAILS": {
|
||||
"LABELS": {
|
||||
"ASSIGNEE": "Assegnatario",
|
||||
"DUE": "Scadenza",
|
||||
"FORM": "Form"
|
||||
},
|
||||
"MESSAGES": {
|
||||
"NONE": "Nessun dettaglio task trovato."
|
||||
},
|
||||
"FORM": {
|
||||
"NONE": "Nessuna form."
|
||||
},
|
||||
"DUE": {
|
||||
"NONE": "Nessuna data di scadenza."
|
||||
}
|
||||
},
|
||||
"TASK_FILTERS": {
|
||||
"MESSAGES": {
|
||||
"NONE": "Nessun filtro task selezionato."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,9 @@
|
||||
*/
|
||||
|
||||
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';
|
||||
|
||||
export * from './src/components/activiti-tasklist.component';
|
||||
|
||||
export const ALFRESCO_TASKLIST_DIRECTIVES: [any] = [ActivitiTaskList];
|
||||
export const ALFRESCO_TASKLIST_DIRECTIVES: [any] = [ActivitiFilters, ActivitiTaskList, ActivitiTaskDetails];
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
:host {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.activiti-label {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
.material-icons:hover {
|
||||
color: rgb(255, 152, 0);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<span class="activiti-label mdl-badge"
|
||||
[attr.data-badge]="checklist?.length">{{ 'TASK_DETAILS.LABELS.CHECKLIST' | translate }}</span>
|
||||
<div id="addChecklist" (click)="showDialog()" class="icon material-icons">add</div>
|
||||
<div class="mdl-tooltip" for="addChecklist">
|
||||
Add a checklist
|
||||
</div>
|
||||
<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">
|
||||
<i class="material-icons mdl-list__item-icon">done</i>
|
||||
{{check.name}}
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div *ngIf="checklist?.length === 0">
|
||||
{{ 'TASK_DETAILS.CHECKLIST.NONE' | translate }}
|
||||
</div>
|
||||
|
||||
<dialog class="mdl-dialog" #dialog>
|
||||
<h4 class="mdl-dialog__title">New Task</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)]="taskName" id="task" />
|
||||
<label class="mdl-textfield__label" for="task">Name</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mdl-dialog__actions">
|
||||
<button type="button" (click)="add()" class="mdl-button">Add Checklist</button>
|
||||
<button type="button" (click)="cancel()" class="mdl-button close">Cancel</button>
|
||||
</div>
|
||||
</dialog>
|
||||
@@ -0,0 +1,120 @@
|
||||
/*!
|
||||
* @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, ViewChild } 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 { Observer } from 'rxjs/Observer';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
|
||||
declare let componentHandler: any;
|
||||
declare let __moduleName: string;
|
||||
|
||||
@Component({
|
||||
selector: 'activiti-checklist',
|
||||
moduleId: __moduleName,
|
||||
templateUrl: './activiti-checklist.component.html',
|
||||
styleUrls: ['./activiti-checklist.component.css'],
|
||||
providers: [ActivitiTaskListService],
|
||||
pipes: [AlfrescoPipeTranslate]
|
||||
|
||||
})
|
||||
export class ActivitiChecklist implements OnInit {
|
||||
|
||||
@Input()
|
||||
taskId: string;
|
||||
|
||||
@ViewChild('dialog')
|
||||
dialog: any;
|
||||
|
||||
taskName: string;
|
||||
|
||||
checklist: TaskDetailsModel [] = [];
|
||||
|
||||
private taskObserver: Observer<TaskDetailsModel>;
|
||||
task$: Observable<TaskDetailsModel>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param auth
|
||||
* @param translate
|
||||
*/
|
||||
constructor(private auth: AlfrescoAuthenticationService,
|
||||
private translate: AlfrescoTranslationService,
|
||||
private activitiTaskList: ActivitiTaskListService) {
|
||||
|
||||
if (translate) {
|
||||
translate.addTranslationFolder('node_modules/ng2-activiti-tasklist');
|
||||
}
|
||||
this.task$ = new Observable<TaskDetailsModel>(observer => this.taskObserver = observer).share();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.task$.subscribe((task: TaskDetailsModel) => {
|
||||
this.checklist.push(task);
|
||||
});
|
||||
|
||||
if (this.taskId) {
|
||||
this.load(this.taskId);
|
||||
}
|
||||
}
|
||||
|
||||
public load(taskId: string) {
|
||||
this.checklist = [];
|
||||
if (this.taskId) {
|
||||
this.activitiTaskList.getTaskChecklist(this.taskId).subscribe(
|
||||
(res: TaskDetailsModel[]) => {
|
||||
res.forEach((task) => {
|
||||
this.taskObserver.next(task);
|
||||
});
|
||||
},
|
||||
(err) => {
|
||||
console.log(err);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
this.checklist = [];
|
||||
}
|
||||
}
|
||||
|
||||
public showDialog() {
|
||||
if (this.dialog) {
|
||||
this.dialog.nativeElement.showModal();
|
||||
}
|
||||
}
|
||||
|
||||
public add() {
|
||||
let newTask = new TaskDetailsModel({name: this.taskName, parentTaskId: this.taskId, assignee: {id: '1'}});
|
||||
this.activitiTaskList.addTask(newTask).subscribe(
|
||||
(res: TaskDetailsModel) => {
|
||||
this.checklist.push(res);
|
||||
},
|
||||
(err) => {
|
||||
console.log(err);
|
||||
}
|
||||
);
|
||||
|
||||
this.cancel();
|
||||
}
|
||||
|
||||
public cancel() {
|
||||
if (this.dialog) {
|
||||
this.dialog.nativeElement.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
:host {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.activiti-label {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
.material-icons:hover {
|
||||
color: rgb(255, 152, 0);
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<span class="activiti-label mdl-badge"
|
||||
[attr.data-badge]="comments?.length">{{ 'TASK_DETAILS.LABELS.COMMENTS' |translate }}</span>
|
||||
<div id="addComment" (click)="showDialog()" class="icon material-icons">add</div>
|
||||
<div class="mdl-tooltip" for="addComment">
|
||||
Add a comment
|
||||
</div>
|
||||
|
||||
<div class="menu-container" *ngIf="comments?.length > 0">
|
||||
<ul class='mdl-list'>
|
||||
<li class="mdl-list__item" *ngFor="let comment of comments">
|
||||
<span class="mdl-list__item-primary-content">
|
||||
<i class="material-icons mdl-list__item-icon">comment</i>
|
||||
{{comment.message}}
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div *ngIf="comments?.length === 0">
|
||||
{{ 'TASK_DETAILS.COMMENTS.NONE' | translate }}
|
||||
</div>
|
||||
|
||||
|
||||
<dialog class="mdl-dialog" #dialog>
|
||||
<h4 class="mdl-dialog__title">New comment</h4>
|
||||
<div class="mdl-dialog__content">
|
||||
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
|
||||
<textarea class="mdl-textfield__input" type="text" [(ngModel)]="message" rows="1" id="commentText"></textarea>
|
||||
<label class="mdl-textfield__label" for="commentText">Message</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mdl-dialog__actions">
|
||||
<button type="button" (click)="add()" class="mdl-button">Add Comment</button>
|
||||
<button type="button" (click)="cancel()" class="mdl-button close">Cancel</button>
|
||||
</div>
|
||||
</dialog>
|
||||
@@ -0,0 +1,121 @@
|
||||
/*!
|
||||
* @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, ViewChild } from '@angular/core';
|
||||
import { AlfrescoTranslationService, AlfrescoAuthenticationService, AlfrescoPipeTranslate } from 'ng2-alfresco-core';
|
||||
import { ActivitiTaskListService } from './../services/activiti-tasklist.service';
|
||||
import { Comment } from '../models/comment.model';
|
||||
import { Observer } from 'rxjs/Observer';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
|
||||
declare let componentHandler: any;
|
||||
declare let __moduleName: string;
|
||||
|
||||
@Component({
|
||||
selector: 'activiti-comments',
|
||||
moduleId: __moduleName,
|
||||
templateUrl: './activiti-comments.component.html',
|
||||
styleUrls: ['./activiti-comments.component.css'],
|
||||
providers: [ActivitiTaskListService],
|
||||
pipes: [ AlfrescoPipeTranslate ]
|
||||
|
||||
})
|
||||
export class ActivitiComments implements OnInit {
|
||||
|
||||
@Input()
|
||||
taskId: string;
|
||||
|
||||
@ViewChild('dialog')
|
||||
dialog: any;
|
||||
|
||||
comments: Comment [] = [];
|
||||
|
||||
private commentObserver: Observer<Comment>;
|
||||
comment$: Observable<Comment>;
|
||||
|
||||
message: string;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param auth
|
||||
* @param translate
|
||||
*/
|
||||
constructor(private auth: AlfrescoAuthenticationService,
|
||||
private translate: AlfrescoTranslationService,
|
||||
private activitiTaskList: ActivitiTaskListService) {
|
||||
|
||||
if (translate) {
|
||||
translate.addTranslationFolder('node_modules/ng2-activiti-tasklist');
|
||||
}
|
||||
|
||||
this.comment$ = new Observable<Comment>(observer => this.commentObserver = observer).share();
|
||||
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.comment$.subscribe((comment: Comment) => {
|
||||
this.comments.push(comment);
|
||||
});
|
||||
|
||||
if (this.taskId) {
|
||||
this.load(this.taskId);
|
||||
}
|
||||
}
|
||||
|
||||
public load(taskId: string) {
|
||||
this.comments = [];
|
||||
if (this.taskId) {
|
||||
this.activitiTaskList.getTaskComments(this.taskId).subscribe(
|
||||
(res: Comment[]) => {
|
||||
res.forEach((comment) => {
|
||||
this.commentObserver.next(comment);
|
||||
});
|
||||
},
|
||||
(err) => {
|
||||
console.log(err);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
this.comments = [];
|
||||
}
|
||||
}
|
||||
|
||||
public showDialog() {
|
||||
if (this.dialog) {
|
||||
this.dialog.nativeElement.showModal();
|
||||
}
|
||||
}
|
||||
|
||||
public add() {
|
||||
this.activitiTaskList.addTaskComment(this.taskId, this.message).subscribe(
|
||||
(res: Comment) => {
|
||||
this.comments.push(res);
|
||||
this.message = '';
|
||||
},
|
||||
(err) => {
|
||||
console.log(err);
|
||||
}
|
||||
);
|
||||
this.cancel();
|
||||
}
|
||||
|
||||
public cancel() {
|
||||
if (this.dialog) {
|
||||
this.dialog.nativeElement.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<div class="menu-container">
|
||||
<ul class='mdl-list'>
|
||||
<li class="mdl-list__item"(click)="selectFilter(filter)" *ngFor="let filter of filters">
|
||||
<span class="mdl-list__item-primary-content">
|
||||
<i class="material-icons mdl-list__item-icon">assignment</i>
|
||||
{{filter.name}}
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
/*!
|
||||
* @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 {
|
||||
it,
|
||||
describe,
|
||||
expect,
|
||||
beforeEach
|
||||
} from '@angular/core/testing';
|
||||
|
||||
import { ActivitiFilters } from './activiti-filters.component';
|
||||
import { ActivitiTaskListService } from '../services/activiti-tasklist.service';
|
||||
import { Observable } from 'rxjs/Rx';
|
||||
import { FilterModel } from '../models/filter.model';
|
||||
|
||||
describe('ActivitiFilters', () => {
|
||||
|
||||
let filterList: ActivitiFilters;
|
||||
|
||||
let fakeGlobalFilter = [];
|
||||
fakeGlobalFilter.push(new FilterModel('FakeInvolvedTasks', false, 'glyphicon-align-left', '', 'open', 'fake-involved'));
|
||||
fakeGlobalFilter.push(new FilterModel('FakeMyTasks', false, 'glyphicon-align-left', '', 'open', 'fake-assignee'));
|
||||
|
||||
let fakeGlobalFilterPromise = new Promise(function (resolve, reject) {
|
||||
resolve(fakeGlobalFilter);
|
||||
});
|
||||
|
||||
let fakeErrorFilterList = {
|
||||
error: 'wrong request'
|
||||
};
|
||||
|
||||
let fakeErrorFilterPromise = new Promise(function (resolve, reject) {
|
||||
reject(fakeErrorFilterList);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
let activitiService = new ActivitiTaskListService(null, null);
|
||||
filterList = new ActivitiFilters(null, null, activitiService);
|
||||
});
|
||||
|
||||
it('should return the filter task list', (done) => {
|
||||
spyOn(filterList.activiti, 'getTaskListFilters').and.returnValue(Observable.fromPromise(fakeGlobalFilterPromise));
|
||||
|
||||
filterList.onSuccess.subscribe( (res) => {
|
||||
expect(res).toBeDefined();
|
||||
expect(res).toEqual('Filter task list loaded');
|
||||
expect(filterList.filters).toBeDefined();
|
||||
expect(filterList.filters.length).toEqual(2);
|
||||
expect(filterList.filters[0].name).toEqual('FakeInvolvedTasks');
|
||||
expect(filterList.filters[1].name).toEqual('FakeMyTasks');
|
||||
done();
|
||||
});
|
||||
|
||||
filterList.ngOnInit();
|
||||
});
|
||||
|
||||
it('should emit an error with a bad response', (done) => {
|
||||
spyOn(filterList.activiti, 'getTaskListFilters').and.returnValue(Observable.fromPromise(fakeErrorFilterPromise));
|
||||
|
||||
filterList.onError.subscribe( (err) => {
|
||||
expect(err).toBeDefined();
|
||||
expect(err).toEqual('Error to load a task filter list');
|
||||
done();
|
||||
});
|
||||
|
||||
filterList.ngOnInit();
|
||||
});
|
||||
|
||||
it('should emit an event when a filter is selected', (done) => {
|
||||
let currentFilter = new FilterModel('FakeInvolvedTasks', false, 'glyphicon-align-left', '', 'open', 'fake-involved');
|
||||
|
||||
filterList.filterClick.subscribe((filter: FilterModel) => {
|
||||
expect(filter).toBeDefined();
|
||||
expect(filter).toEqual(currentFilter);
|
||||
expect(filterList.currentFilter).toEqual(currentFilter);
|
||||
done();
|
||||
});
|
||||
|
||||
filterList.selectFilter(currentFilter);
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,103 @@
|
||||
/*!
|
||||
* @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, Output, EventEmitter, OnInit} from '@angular/core';
|
||||
import { AlfrescoTranslationService, AlfrescoAuthenticationService, AlfrescoPipeTranslate } from 'ng2-alfresco-core';
|
||||
import { ActivitiTaskListService } from './../services/activiti-tasklist.service';
|
||||
import { FilterModel } from '../models/filter.model';
|
||||
import { Observer } from 'rxjs/Observer';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
|
||||
declare let componentHandler: any;
|
||||
declare let __moduleName: string;
|
||||
|
||||
@Component({
|
||||
selector: 'activiti-filters',
|
||||
moduleId: __moduleName,
|
||||
templateUrl: './activiti-filters.component.html',
|
||||
providers: [ActivitiTaskListService],
|
||||
pipes: [ AlfrescoPipeTranslate ]
|
||||
|
||||
})
|
||||
export class ActivitiFilters implements OnInit {
|
||||
|
||||
@Output()
|
||||
filterClick: EventEmitter<FilterModel> = new EventEmitter<FilterModel>();
|
||||
|
||||
@Output()
|
||||
onSuccess: EventEmitter<string> = new EventEmitter<string>();
|
||||
|
||||
@Output()
|
||||
onError: EventEmitter<string> = new EventEmitter<string>();
|
||||
|
||||
private filterObserver: Observer<FilterModel>;
|
||||
filter$: Observable<FilterModel>;
|
||||
|
||||
currentFilter: FilterModel;
|
||||
|
||||
filters: FilterModel [] = [];
|
||||
/**
|
||||
* Constructor
|
||||
* @param auth
|
||||
* @param translate
|
||||
*/
|
||||
constructor(private auth: AlfrescoAuthenticationService,
|
||||
private translate: AlfrescoTranslationService,
|
||||
public activiti: ActivitiTaskListService) {
|
||||
this.filter$ = new Observable<FilterModel>(observer => this.filterObserver = observer).share();
|
||||
|
||||
if (translate) {
|
||||
translate.addTranslationFolder('node_modules/ng2-activiti-tasklist');
|
||||
}
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.filter$.subscribe((filter: FilterModel) => {
|
||||
this.filters.push(filter);
|
||||
});
|
||||
|
||||
this.load();
|
||||
}
|
||||
|
||||
/**
|
||||
* The method call the adapter data table component for render the task list
|
||||
* @param tasks
|
||||
*/
|
||||
private load() {
|
||||
this.activiti.getTaskListFilters().subscribe(
|
||||
(res: FilterModel[]) => {
|
||||
res.forEach((filter) => {
|
||||
this.filterObserver.next(filter);
|
||||
});
|
||||
this.onSuccess.emit('Filter task list loaded');
|
||||
},
|
||||
(err) => {
|
||||
console.log(err);
|
||||
this.onError.emit('Error to load a task filter list');
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pass the selected filter as next
|
||||
* @param filter
|
||||
*/
|
||||
public selectFilter(filter: FilterModel) {
|
||||
this.currentFilter = filter;
|
||||
this.filterClick.emit(filter);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
:host {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.activiti-label {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
.material-icons:hover {
|
||||
color: rgb(255, 152, 0);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<span class="activiti-label mdl-badge"
|
||||
[attr.data-badge]="people?.length">{{ 'TASK_DETAILS.LABELS.PEOPLE' | translate }}</span>
|
||||
<div id="addPeople" (click)="showDialog()" class="icon material-icons">add</div>
|
||||
<div class="mdl-tooltip" for="addPeople">
|
||||
Add a people
|
||||
</div>
|
||||
<div class="menu-container" *ngIf="people?.length > 0">
|
||||
<ul class='mdl-list'>
|
||||
<li class="mdl-list__item" *ngFor="let user of people">
|
||||
<span class="mdl-list__item-primary-content">
|
||||
<i class="material-icons mdl-list__item-icon">face</i>
|
||||
{{user.firstName}}
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div *ngIf="people?.length === 0">
|
||||
{{ 'TASK_DETAILS.PEOPLE.NONE' | translate }}
|
||||
</div>
|
||||
|
||||
<dialog class="mdl-dialog" #dialog>
|
||||
<h4 class="mdl-dialog__title">New User</h4>
|
||||
<div class="mdl-dialog__content">
|
||||
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
|
||||
<input class="mdl-textfield__input" type="text" id="people" />
|
||||
<label class="mdl-textfield__label" for="people">Name</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mdl-dialog__actions">
|
||||
<button type="button" (click)="add()" class="mdl-button">Add User</button>
|
||||
<button type="button" (click)="cancel()" class="mdl-button close">Cancel</button>
|
||||
</div>
|
||||
</dialog>
|
||||
@@ -0,0 +1,84 @@
|
||||
/*!
|
||||
* @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, ViewChild } from '@angular/core';
|
||||
import { AlfrescoTranslationService, AlfrescoAuthenticationService, AlfrescoPipeTranslate } from 'ng2-alfresco-core';
|
||||
import { User } from '../models/user.model';
|
||||
import { Observer } from 'rxjs/Observer';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
|
||||
declare let componentHandler: any;
|
||||
declare let __moduleName: string;
|
||||
|
||||
@Component({
|
||||
selector: 'activiti-people',
|
||||
moduleId: __moduleName,
|
||||
templateUrl: './activiti-people.component.html',
|
||||
styleUrls: ['./activiti-people.component.css'],
|
||||
pipes: [ AlfrescoPipeTranslate ]
|
||||
|
||||
})
|
||||
export class ActivitiPeople implements OnInit {
|
||||
|
||||
@Input()
|
||||
people: User [] = [];
|
||||
|
||||
@ViewChild('dialog')
|
||||
dialog: any;
|
||||
|
||||
private peopleObserver: Observer<User>;
|
||||
people$: Observable<User>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param auth
|
||||
* @param translate
|
||||
*/
|
||||
constructor(private auth: AlfrescoAuthenticationService,
|
||||
private translate: AlfrescoTranslationService) {
|
||||
|
||||
if (translate) {
|
||||
translate.addTranslationFolder('node_modules/ng2-activiti-tasklist');
|
||||
}
|
||||
this.people$ = new Observable<User>(observer => this.peopleObserver = observer).share();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.people$.subscribe((user: User) => {
|
||||
this.people.push(user);
|
||||
});
|
||||
}
|
||||
|
||||
public showDialog() {
|
||||
if (this.dialog) {
|
||||
this.dialog.nativeElement.showModal();
|
||||
}
|
||||
}
|
||||
|
||||
public add() {
|
||||
alert('add people');
|
||||
|
||||
this.cancel();
|
||||
}
|
||||
|
||||
public cancel() {
|
||||
if (this.dialog) {
|
||||
this.dialog.nativeElement.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
:host {
|
||||
width: 100%;
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
<div *ngIf="!taskDetails">{{ 'TASK_DETAILS.MESSAGES.NONE' | translate }}</div>
|
||||
<div *ngIf="taskDetails">
|
||||
<h2 class="mdl-card__title-text">{{taskDetails.name}}</h2>
|
||||
<activiti-task-header [taskDetails]="taskDetails" #activitiheader></activiti-task-header>
|
||||
<div class="mdl-grid">
|
||||
<div class="mdl-cell mdl-cell--4-col">
|
||||
<activiti-people [people]="taskPeople"></activiti-people>
|
||||
</div>
|
||||
<div class="mdl-cell mdl-cell--4-col">
|
||||
<activiti-comments [taskId]="taskId" #activiticomments></activiti-comments>
|
||||
</div>
|
||||
<div class="mdl-cell mdl-cell--4-col">
|
||||
<activiti-checklist [taskId]="taskId" #activitichecklist></activiti-checklist>
|
||||
</div>
|
||||
</div>
|
||||
<activiti-form *ngIf="taskDetails.formKey" [taskId]="taskId" #activitiForm ></activiti-form>
|
||||
</div>
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
/*!
|
||||
* @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, ViewChild } from '@angular/core';
|
||||
import { AlfrescoTranslationService, AlfrescoAuthenticationService, AlfrescoPipeTranslate } from 'ng2-alfresco-core';
|
||||
import { ActivitiTaskListService } from './../services/activiti-tasklist.service';
|
||||
import { ActivitiTaskHeader } from './activiti-task-header.component';
|
||||
import { ActivitiComments } from './activiti-comments.component';
|
||||
import { ActivitiChecklist } from './activiti-checklist.component';
|
||||
import { ActivitiPeople } from './activiti-people.component';
|
||||
import { TaskDetailsModel } from '../models/task-details.model';
|
||||
import { User } from '../models/user.model';
|
||||
import { ActivitiForm, FormModel, FormService } 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, FormService],
|
||||
directives: [ActivitiTaskHeader, ActivitiPeople, ActivitiComments, ActivitiChecklist, ActivitiForm],
|
||||
pipes: [AlfrescoPipeTranslate]
|
||||
|
||||
})
|
||||
export class ActivitiTaskDetails implements OnInit {
|
||||
|
||||
@Input()
|
||||
taskId: string;
|
||||
|
||||
@ViewChild('activiticomments')
|
||||
activiticomments: any;
|
||||
|
||||
@ViewChild('activitichecklist')
|
||||
activitichecklist: any;
|
||||
|
||||
taskDetails: TaskDetailsModel;
|
||||
|
||||
taskForm: FormModel;
|
||||
|
||||
taskPeople: User[] = [];
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param auth
|
||||
* @param translate
|
||||
*/
|
||||
constructor(private auth: AlfrescoAuthenticationService,
|
||||
private translate: AlfrescoTranslationService,
|
||||
private activitiForm: FormService,
|
||||
private activitiTaskList: ActivitiTaskListService) {
|
||||
|
||||
if (translate) {
|
||||
translate.addTranslationFolder('node_modules/ng2-activiti-tasklist');
|
||||
}
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (this.taskId) {
|
||||
this.loadDetails(this.taskId);
|
||||
}
|
||||
}
|
||||
|
||||
loadDetails(taskId: string) {
|
||||
this.taskForm = null;
|
||||
this.taskPeople = [];
|
||||
if (taskId) {
|
||||
this.activitiTaskList.getTaskDetails(taskId).subscribe(
|
||||
(res: TaskDetailsModel) => {
|
||||
this.taskDetails = res;
|
||||
if (this.taskDetails && this.taskDetails.involvedPeople) {
|
||||
this.taskDetails.involvedPeople.forEach((user) => {
|
||||
this.taskPeople.push(new User(user.id, user.email, user.firstName, user.lastName));
|
||||
});
|
||||
|
||||
if (this.activiticomments) {
|
||||
this.activiticomments.load(this.taskDetails.id);
|
||||
}
|
||||
|
||||
if (this.activitichecklist) {
|
||||
this.activitichecklist.load(this.taskDetails.id);
|
||||
}
|
||||
}
|
||||
console.log(this.taskDetails);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
onComplete() {
|
||||
this.activitiTaskList.completeTask(this.taskId).subscribe(
|
||||
(res) => {
|
||||
console.log(res);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
:host {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.activiti-label {
|
||||
font-weight: bolder;
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
<div *ngIf="taskDetails">
|
||||
<div class="mdl-grid">
|
||||
<div class="mdl-cell mdl-cell--4-col">
|
||||
<span class="activiti-label">{{ 'TASK_DETAILS.LABELS.ASSIGNEE' | translate }}</span>:
|
||||
{{taskDetails.assignee.lastName }}
|
||||
</div>
|
||||
<div class="mdl-cell mdl-cell--4-col">
|
||||
<span class="activiti-label">
|
||||
{{ 'TASK_DETAILS.LABELS.DUE' | translate }}</span>:
|
||||
{{taskDetails?.dueDate ? taskDetails.dueDate : ('TASK_DETAILS.DUE.NONE' |translate) }}
|
||||
|
||||
</div>
|
||||
<div class="mdl-cell mdl-cell--4-col">
|
||||
<span class="activiti-label">{{ 'TASK_DETAILS.LABELS.FORM' | translate }}</span>:
|
||||
{{taskForm?.name ? taskForm.name : ('TASK_DETAILS.FORM.NONE' | translate) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,82 @@
|
||||
/*!
|
||||
* @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 { TaskDetailsModel } from '../models/task-details.model';
|
||||
import { FormModel, FormService } from 'ng2-activiti-form';
|
||||
|
||||
declare let componentHandler: any;
|
||||
declare let __moduleName: string;
|
||||
|
||||
@Component({
|
||||
selector: 'activiti-task-header',
|
||||
moduleId: __moduleName,
|
||||
templateUrl: './activiti-task-header.component.html',
|
||||
styleUrls: ['./activiti-task-header.component.css'],
|
||||
providers: [ FormService ],
|
||||
pipes: [ AlfrescoPipeTranslate ]
|
||||
|
||||
})
|
||||
export class ActivitiTaskHeader implements OnInit, OnChanges {
|
||||
|
||||
@Input()
|
||||
taskDetails: TaskDetailsModel;
|
||||
|
||||
taskForm: FormModel;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param auth
|
||||
* @param translate
|
||||
*/
|
||||
constructor(private auth: AlfrescoAuthenticationService,
|
||||
private activitiForm: FormService,
|
||||
private translate: AlfrescoTranslationService) {
|
||||
|
||||
if (translate) {
|
||||
translate.addTranslationFolder('node_modules/ng2-activiti-tasklist');
|
||||
}
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (this.taskDetails && this.taskDetails.formKey) {
|
||||
this.load(this.taskDetails.id);
|
||||
}
|
||||
}
|
||||
|
||||
ngOnChanges(change) {
|
||||
if (this.taskDetails && this.taskDetails.formKey) {
|
||||
this.load(this.taskDetails.id);
|
||||
} else {
|
||||
this.taskForm = null;
|
||||
}
|
||||
}
|
||||
|
||||
public load(taskId: string) {
|
||||
if (taskId) {
|
||||
this.activitiForm.getTaskForm(taskId).subscribe(
|
||||
(response) => {
|
||||
this.taskForm = response;
|
||||
},
|
||||
(err) => {
|
||||
console.error(err);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
-11
@@ -1,12 +1,12 @@
|
||||
<div [ngStyle]="locationCss" class="menu-container">
|
||||
<ul class="context-menu">
|
||||
<li (click)="selectFilter(filter)" *ngFor="let filter of filtersList | async">
|
||||
{{filter.name}}
|
||||
</li>
|
||||
</ul>
|
||||
<div *ngIf="!taskFilter">{{ 'TASK_FILTERS.MESSAGES.NONE' | translate }}</div>
|
||||
<div *ngIf="taskFilter">
|
||||
<div *ngIf="!isTaskListEmpty()">
|
||||
<alfresco-datatable
|
||||
[data]="tasks"
|
||||
(rowClick)="onRowClick($event)">
|
||||
</alfresco-datatable>
|
||||
</div>
|
||||
<div *ngIf="isTaskListEmpty()">
|
||||
{{ 'TASK_LIST.MESSAGES.NONE' | translate }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<alfresco-datatable
|
||||
[data]="tasks"
|
||||
(rowClick)="onRowClick($event)">
|
||||
</alfresco-datatable>
|
||||
+54
-76
@@ -26,26 +26,13 @@ import { ActivitiTaskList } from './activiti-tasklist.component';
|
||||
import { ActivitiTaskListService } from '../services/activiti-tasklist.service';
|
||||
import { FilterModel } from '../models/filter.model';
|
||||
import { Observable } from 'rxjs/Rx';
|
||||
import { ObjectDataRow, DataRowEvent } from 'ng2-alfresco-datatable';
|
||||
|
||||
|
||||
describe('ActivitiTaskList', () => {
|
||||
|
||||
let taskList: ActivitiTaskList;
|
||||
|
||||
let fakeGlobalFilter = {
|
||||
size: 2, total: 2, start: 0,
|
||||
data: [
|
||||
{
|
||||
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'}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
let fakeGlobalTask = {
|
||||
size: 1, total: 12, start: 0,
|
||||
data: [
|
||||
@@ -64,18 +51,14 @@ describe('ActivitiTaskList', () => {
|
||||
]
|
||||
};
|
||||
|
||||
let fakeErrorTaskList = {
|
||||
error: 'wrong request'
|
||||
};
|
||||
|
||||
let fakeGlobalFilterPromise = new Promise(function (resolve, reject) {
|
||||
resolve(fakeGlobalFilter);
|
||||
});
|
||||
|
||||
let fakeGlobalTaskPromise = new Promise(function (resolve, reject) {
|
||||
resolve(fakeGlobalTask);
|
||||
});
|
||||
|
||||
let fakeErrorTaskList = {
|
||||
error: 'wrong request'
|
||||
};
|
||||
|
||||
let fakeErrorTaskPromise = new Promise(function (resolve, reject) {
|
||||
reject(fakeErrorTaskList);
|
||||
});
|
||||
@@ -85,76 +68,71 @@ describe('ActivitiTaskList', () => {
|
||||
taskList = new ActivitiTaskList(null, null, activitiSerevice);
|
||||
});
|
||||
|
||||
it('should return the default filters', (done) => {
|
||||
spyOn(taskList.activiti, 'getTaskListFilters').and.returnValue(Observable.fromPromise(fakeGlobalFilterPromise));
|
||||
it('should use the default schemaColumn as default', () => {
|
||||
taskList.ngOnInit();
|
||||
|
||||
taskList.filtersList.subscribe((res: any) => {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.length).toEqual(2);
|
||||
expect(res[0].name).toEqual('FakeInvolvedTasks');
|
||||
expect(res[1].name).toEqual('FakeMyTasks');
|
||||
done();
|
||||
});
|
||||
expect(taskList.schemaColumn).toBeDefined();
|
||||
expect(taskList.schemaColumn.length).toEqual(4);
|
||||
});
|
||||
|
||||
it('should subscribe to Filter when a filter is selected', (done) => {
|
||||
let filterModel: FilterModel = new FilterModel('name', false, 'icon', 'open', 'fake-assignee');
|
||||
taskList.filter$.subscribe((filter: FilterModel) => {
|
||||
expect(filter).toBe(filterModel);
|
||||
done();
|
||||
});
|
||||
taskList.selectFilter(filterModel);
|
||||
it('should use the schemaColumn passed in input', () => {
|
||||
taskList.schemaColumn = [
|
||||
{type: 'text', key: 'fake-id', title: 'Name'}
|
||||
];
|
||||
|
||||
taskList.ngOnInit();
|
||||
expect(taskList.schemaColumn).toBeDefined();
|
||||
expect(taskList.schemaColumn.length).toEqual(1);
|
||||
});
|
||||
|
||||
it('should return the tasks when a filter is selected', (done) => {
|
||||
it('should return an empty task list when the taskFilter is not passed', () => {
|
||||
taskList.ngOnInit();
|
||||
expect(taskList.tasks).toBeUndefined();
|
||||
expect(taskList.isTaskListEmpty()).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should return the filtered task list when the taskFilter is passed', (done) => {
|
||||
spyOn(taskList.activiti, 'getTasks').and.returnValue(Observable.fromPromise(fakeGlobalTaskPromise));
|
||||
spyOn(taskList.activiti, 'getTaskListFilters').and.returnValue(Observable.fromPromise(fakeGlobalFilterPromise));
|
||||
taskList.taskFilter = new FilterModel('name', false, 'icon', '', 'open', 'fake-assignee');
|
||||
|
||||
taskList.onSuccess.subscribe( (res) => {
|
||||
expect(res).toBeDefined();
|
||||
expect(res).toEqual('Task List loaded');
|
||||
expect(taskList.tasks).toBeDefined();
|
||||
expect(taskList.isTaskListEmpty()).not.toBeTruthy();
|
||||
expect(taskList.tasks.getRows().length).toEqual(2);
|
||||
expect(taskList.tasks.getRows()[0].getValue('name')).toEqual('fake-long-name-fake-long-name-fake-long-name-fak50...');
|
||||
expect(taskList.tasks.getRows()[1].getValue('name')).toEqual('Nameless task');
|
||||
done();
|
||||
});
|
||||
|
||||
taskList.ngOnInit();
|
||||
|
||||
let filterModel: FilterModel = new FilterModel('name', false, 'icon', 'open', 'fake-assignee');
|
||||
taskList.selectFilter(filterModel);
|
||||
|
||||
taskList.activiti.getTasks(filterModel).subscribe(
|
||||
(res) => {
|
||||
expect(res).toBeDefined();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw an exception when the response is wrong', (done) => {
|
||||
spyOn(taskList.activiti, 'getTasks').and.returnValue(Observable.fromPromise(fakeErrorTaskPromise));
|
||||
spyOn(taskList.activiti, 'getTaskListFilters').and.returnValue(Observable.fromPromise(fakeGlobalFilterPromise));
|
||||
taskList.taskFilter = new FilterModel('name', false, 'icon', '', 'open', 'fake-assignee');
|
||||
|
||||
taskList.onError.subscribe( (err) => {
|
||||
expect(err).toBeDefined();
|
||||
expect(err).toEqual('Error to load a tasks list');
|
||||
done();
|
||||
});
|
||||
|
||||
taskList.ngOnInit();
|
||||
|
||||
let filterModel: FilterModel = new FilterModel('name', false, 'icon', 'open', 'fake-assignee');
|
||||
taskList.selectFilter(filterModel);
|
||||
|
||||
taskList.activiti.getTasks(filterModel).subscribe(
|
||||
(res) => {
|
||||
expect(res).toBeUndefined();
|
||||
},
|
||||
(err: any) => {
|
||||
expect(err).toBeDefined();
|
||||
expect(err.error).toEqual('wrong request');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should optimize the task name when are empty or exceed 50 characters', (done) => {
|
||||
spyOn(taskList.activiti, 'getTasks').and.returnValue(Observable.fromPromise(fakeGlobalTaskPromise));
|
||||
spyOn(taskList.activiti, 'getTaskListFilters').and.returnValue(Observable.fromPromise(fakeGlobalFilterPromise));
|
||||
taskList.ngOnInit();
|
||||
it('should emit row click event', (done) => {
|
||||
let row = new ObjectDataRow({
|
||||
id: 999
|
||||
});
|
||||
let rowEvent = <DataRowEvent> {value: row};
|
||||
|
||||
let filterModel: FilterModel = new FilterModel('name', false, 'icon', 'open', 'fake-assignee');
|
||||
taskList.selectFilter(filterModel);
|
||||
taskList.rowClick.subscribe(taskId => {
|
||||
expect(taskId).toEqual(999);
|
||||
done();
|
||||
});
|
||||
|
||||
taskList.activiti.getTasks(filterModel).subscribe(
|
||||
(res) => {
|
||||
expect(res.data[0].name).toEqual('fake-long-name-fake-long-name-fake-long-name-fak50...');
|
||||
expect(res.data[1].name).toEqual('Nameless task');
|
||||
done();
|
||||
});
|
||||
taskList.onRowClick(rowEvent);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
+52
-25
@@ -15,13 +15,11 @@
|
||||
* 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';
|
||||
import { Observer } from 'rxjs/Observer';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
|
||||
declare let componentHandler: any;
|
||||
declare let __moduleName: string;
|
||||
@@ -31,22 +29,38 @@ 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 {
|
||||
|
||||
@Input()
|
||||
taskFilter: FilterModel;
|
||||
|
||||
@Input()
|
||||
schemaColumn: any[] = [
|
||||
{type: 'text', key: 'id', title: 'Id'},
|
||||
{type: 'text', key: 'name', title: 'Name', cssClass: 'full-width name-column', sortable: true},
|
||||
{type: 'text', key: 'formKey', title: 'Form Key', sortable: true},
|
||||
{type: 'text', key: 'created', title: 'Created', sortable: true}
|
||||
];
|
||||
|
||||
@Output()
|
||||
rowClick: EventEmitter<string> = new EventEmitter<string>();
|
||||
|
||||
@Output()
|
||||
onSuccess: EventEmitter<string> = new EventEmitter<string>();
|
||||
|
||||
@Output()
|
||||
onError: EventEmitter<string> = new EventEmitter<string>();
|
||||
|
||||
data: DataTableAdapter;
|
||||
|
||||
private filterObserver: Observer<FilterModel>;
|
||||
|
||||
filter$: Observable<FilterModel>;
|
||||
|
||||
tasks: ObjectDataTableAdapter;
|
||||
|
||||
currentTaskId: string;
|
||||
|
||||
filtersList: Observable<FilterModel>;
|
||||
/**
|
||||
* Constructor
|
||||
* @param auth
|
||||
@@ -55,7 +69,6 @@ export class ActivitiTaskList implements OnInit {
|
||||
constructor(private auth: AlfrescoAuthenticationService,
|
||||
private translate: AlfrescoTranslationService,
|
||||
public activiti: ActivitiTaskListService) {
|
||||
this.filter$ = new Observable<FilterModel>(observer => this.filterObserver = observer).share();
|
||||
|
||||
if (translate) {
|
||||
translate.addTranslationFolder('node_modules/ng2-activiti-tasklist');
|
||||
@@ -63,38 +76,52 @@ export class ActivitiTaskList implements OnInit {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.filtersList = this.activiti.getTaskListFilters().map(res => (res.data));
|
||||
this.data = new ObjectDataTableAdapter(
|
||||
[],
|
||||
this.schemaColumn
|
||||
);
|
||||
|
||||
this.filter$.subscribe((filter: FilterModel) => {
|
||||
this.activiti.getTasks(filter).subscribe(
|
||||
(res) => {
|
||||
this.loadTasks(res.data);
|
||||
}, (err) => {
|
||||
console.error(err);
|
||||
});
|
||||
});
|
||||
if (this.taskFilter) {
|
||||
this.load(this.taskFilter);
|
||||
}
|
||||
}
|
||||
|
||||
public load(filter: FilterModel) {
|
||||
this.activiti.getTasks(filter).subscribe(
|
||||
(res) => {
|
||||
this.renderTasks(res.data);
|
||||
this.onSuccess.emit('Task List loaded');
|
||||
}, (err) => {
|
||||
console.error(err);
|
||||
this.onError.emit('Error to load a tasks list');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* The method call the adapter data table component for render the task list
|
||||
* @param tasks
|
||||
*/
|
||||
private loadTasks(tasks: any[]) {
|
||||
private renderTasks(tasks: any[]) {
|
||||
tasks = this.optimizeTaskName(tasks);
|
||||
this.tasks = new ObjectDataTableAdapter(tasks, this.data.getColumns());
|
||||
}
|
||||
|
||||
/**
|
||||
* Pass the selected filter as next
|
||||
* @param filter
|
||||
* Check if the tasks list is empty
|
||||
* @returns {ObjectDataTableAdapter|boolean}
|
||||
*/
|
||||
public selectFilter(filter: FilterModel) {
|
||||
this.filterObserver.next(filter);
|
||||
isTaskListEmpty(): boolean {
|
||||
return this.tasks === undefined || (this.tasks && this.tasks.getRows() && this.tasks.getRows().length === 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit the event rowClick passing the current task id when the row is clicked
|
||||
* @param event
|
||||
*/
|
||||
onRowClick(event: DataRowEvent) {
|
||||
let item = event;
|
||||
this.currentTaskId = item.value.getValue('id');
|
||||
this.rowClick.emit(this.currentTaskId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*!
|
||||
* @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 comment of a task.
|
||||
*
|
||||
*
|
||||
* @returns {Comment} .
|
||||
*/
|
||||
import { User } from './user.model';
|
||||
|
||||
export class Comment {
|
||||
id: number;
|
||||
message: string;
|
||||
created: string;
|
||||
createdBy: User;
|
||||
|
||||
constructor(id: number, message: string, created: string, createdBy: User) {
|
||||
this.id = id;
|
||||
this.message = message;
|
||||
this.created = created;
|
||||
this.createdBy = createdBy;
|
||||
}
|
||||
}
|
||||
@@ -29,11 +29,11 @@ export class FilterModel {
|
||||
icon: string;
|
||||
filter: FilterParamsModel;
|
||||
|
||||
constructor(name: string, recent: boolean, icon: string, state: string, assignment: string) {
|
||||
constructor(name: string, recent: boolean, icon: string, query: string, state: string, assignment: string) {
|
||||
this.name = name;
|
||||
this.recent = recent;
|
||||
this.icon = icon;
|
||||
this.filter = new FilterParamsModel(name, state, assignment);
|
||||
this.filter = new FilterParamsModel(query, state, assignment);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,8 +49,8 @@ export class FilterParamsModel {
|
||||
state: string;
|
||||
assignment: string;
|
||||
|
||||
constructor(name: string, state: string, assignment: string) {
|
||||
this.name = name;
|
||||
constructor(query: string, state: string, assignment: string) {
|
||||
this.name = query;
|
||||
this.state = state;
|
||||
this.assignment = assignment;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/*!
|
||||
* @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} .
|
||||
*/
|
||||
import { User } from './user.model';
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*!
|
||||
* @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 user.
|
||||
*
|
||||
*
|
||||
* @returns {User} .
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
+239
-91
@@ -19,21 +19,79 @@ import { it, describe, inject, beforeEach, beforeEachProviders } from '@angular/
|
||||
import { ActivitiTaskListService } from './activiti-tasklist.service';
|
||||
import { AlfrescoSettingsService, AlfrescoAuthenticationService } from 'ng2-alfresco-core';
|
||||
import { HTTP_PROVIDERS } from '@angular/http';
|
||||
import { TaskDetailsModel } from '../models/task-details.model';
|
||||
import { Comment } from '../models/comment.model';
|
||||
|
||||
declare let AlfrescoApi: any;
|
||||
declare let jasmine: any;
|
||||
|
||||
describe('AlfrescoUploadService', () => {
|
||||
let service, options: any;
|
||||
describe('ActivitiTaskListService', () => {
|
||||
let service: any;
|
||||
|
||||
options = {
|
||||
host: 'fakehost',
|
||||
url: '/some/cool/url',
|
||||
baseUrlPath: 'fakebasepath',
|
||||
formFields: {
|
||||
siteid: 'fakeSite',
|
||||
containerid: 'fakeFolder'
|
||||
}
|
||||
let fakeFilters = {
|
||||
size: 2, total: 2, start: 0,
|
||||
data: [
|
||||
{
|
||||
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'}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
let fakeFilter = {
|
||||
page: 2, filterId: 2, appDefinitionId: null,
|
||||
filter: {sort: 'created-desc', name: '', state: 'open', assignment: 'fake-assignee' }
|
||||
};
|
||||
|
||||
let fakeUser = { id: 1, email: 'fake-email@dom.com', firstName: 'firstName', lastName: 'lastName' };
|
||||
|
||||
let 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'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
let fakeErrorTaskList = {
|
||||
error: 'wrong request'
|
||||
};
|
||||
|
||||
let fakeTaskDetails = {id: '999', name: 'fake-task-name', formKey: '99', assignee: fakeUser };
|
||||
|
||||
let 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
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
let 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'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
beforeEachProviders(() => {
|
||||
@@ -55,69 +113,37 @@ describe('AlfrescoUploadService', () => {
|
||||
});
|
||||
|
||||
it('should return the task list filters', (done) => {
|
||||
let fakeFilter = {
|
||||
size: 2, total: 2, start: 0,
|
||||
data: [
|
||||
{
|
||||
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'}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
let filters = service.getTaskListFilters();
|
||||
filters.subscribe(res => {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.size).toEqual(2);
|
||||
expect(res.total).toEqual(2);
|
||||
expect(res.data.length).toEqual(2);
|
||||
expect(res.data[0].name).toEqual('FakeInvolvedTasks');
|
||||
expect(res.data[1].name).toEqual('FakeMyTasks');
|
||||
done();
|
||||
});
|
||||
service.getTaskListFilters().subscribe(
|
||||
(res) => {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.length).toEqual(2);
|
||||
expect(res[0].name).toEqual('FakeInvolvedTasks');
|
||||
expect(res[1].name).toEqual('FakeMyTasks');
|
||||
done();
|
||||
}
|
||||
);
|
||||
|
||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||
'status': 200,
|
||||
contentType: 'application/json',
|
||||
responseText: JSON.stringify(fakeFilter)
|
||||
responseText: JSON.stringify(fakeFilters)
|
||||
});
|
||||
});
|
||||
|
||||
it('should return the task list filtered', (done) => {
|
||||
let fakeTaskList = {
|
||||
size: 1, total: 1, start: 0,
|
||||
data: [
|
||||
{
|
||||
id: 1, name: 'FakeNameTask', description: null, category: null,
|
||||
assignee: {
|
||||
id: 1,
|
||||
firstName: null,
|
||||
lastName: 'Fake Admin',
|
||||
email: 'fake-admin'
|
||||
},
|
||||
created: '2016-07-15T11:19:17.440+0000'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
let fakeFilter = {
|
||||
page: 2, filterId: 2, appDefinitionId: null,
|
||||
filter: {sort: 'created-desc', name: '', state: 'open', assignment: 'fake-assignee'}
|
||||
};
|
||||
|
||||
let taskList = service.getTasks(fakeFilter);
|
||||
taskList.subscribe(res => {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.size).toEqual(1);
|
||||
expect(res.total).toEqual(1);
|
||||
expect(res.data.length).toEqual(1);
|
||||
expect(res.data[0].name).toEqual('FakeNameTask');
|
||||
done();
|
||||
});
|
||||
service.getTasks(fakeFilter).subscribe(
|
||||
res => {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.size).toEqual(1);
|
||||
expect(res.total).toEqual(1);
|
||||
expect(res.data.length).toEqual(1);
|
||||
expect(res.data[0].name).toEqual('FakeNameTask');
|
||||
expect(res.data[0].assignee.email).toEqual('fake-email@dom.com');
|
||||
expect(res.data[0].assignee.firstName).toEqual('firstName');
|
||||
expect(res.data[0].assignee.lastName).toEqual('lastName');
|
||||
done();
|
||||
}
|
||||
);
|
||||
|
||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||
'status': 200,
|
||||
@@ -126,36 +152,158 @@ describe('AlfrescoUploadService', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw an exception when the response is wrong', (done) => {
|
||||
let fakeTaskList = {
|
||||
error: 'wrong request'
|
||||
};
|
||||
|
||||
let fakeFilter = {
|
||||
page: 2, filterId: 2, appDefinitionId: null,
|
||||
wrongfilter: {sort: 'created-desc', name: '', state: 'open', assignment: 'fake-assignee'}
|
||||
};
|
||||
|
||||
let fakePromise = new Promise(function (resolve, reject) {
|
||||
reject(fakeTaskList);
|
||||
});
|
||||
spyOn(service, 'callApiTasksFiltered').and.returnValue(fakePromise);
|
||||
|
||||
let taskList = service.getTasks(fakeFilter);
|
||||
|
||||
service.getTasks(fakeFilter).subscribe((res) => {
|
||||
let tasks = res.data;
|
||||
service.loadTasks(tasks);
|
||||
});
|
||||
taskList.subscribe(
|
||||
it('should throw an exception when the response is wrong', () => {
|
||||
service.getTasks(fakeFilter).subscribe(
|
||||
(res) => {
|
||||
|
||||
},
|
||||
(err: any) => {
|
||||
expect(err).toBeDefined();
|
||||
expect(err.error).toEqual('wrong request');
|
||||
done();
|
||||
});
|
||||
expect(err.json().error).toEqual('wrong request');
|
||||
}
|
||||
);
|
||||
|
||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||
'status': 404,
|
||||
contentType: 'application/json',
|
||||
responseText: JSON.stringify(fakeErrorTaskList)
|
||||
});
|
||||
});
|
||||
|
||||
it('should return the task details ', (done) => {
|
||||
service.getTaskDetails(999).subscribe(
|
||||
(res: TaskDetailsModel) => {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.id).toEqual('999');
|
||||
expect(res.name).toEqual('fake-task-name');
|
||||
expect(res.formKey).toEqual('99');
|
||||
expect(res.assignee).toBeDefined();
|
||||
expect(res.assignee.email).toEqual('fake-email@dom.com');
|
||||
expect(res.assignee.firstName).toEqual('firstName');
|
||||
expect(res.assignee.lastName).toEqual('lastName');
|
||||
done();
|
||||
}
|
||||
);
|
||||
|
||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||
'status': 200,
|
||||
contentType: 'application/json',
|
||||
responseText: JSON.stringify(fakeTaskDetails)
|
||||
});
|
||||
});
|
||||
|
||||
it('should return the tasks comments ', (done) => {
|
||||
service.getTaskComments(999).subscribe(
|
||||
(res: Comment[]) => {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.length).toEqual(2);
|
||||
expect(res[0].message).toEqual('fake-message-1');
|
||||
expect(res[1].message).toEqual('fake-message-2');
|
||||
done();
|
||||
}
|
||||
);
|
||||
|
||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||
'status': 200,
|
||||
contentType: 'application/json',
|
||||
responseText: JSON.stringify(fakeTasksComment)
|
||||
});
|
||||
});
|
||||
|
||||
it('should return the tasks checklists ', (done) => {
|
||||
service.getTaskChecklist(999).subscribe(
|
||||
(res: TaskDetailsModel[]) => {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.length).toEqual(2);
|
||||
expect(res[0].name).toEqual('FakeCheckTask1');
|
||||
expect(res[0].assignee.email).toEqual('fake-email@dom.com');
|
||||
expect(res[0].assignee.firstName).toEqual('firstName');
|
||||
expect(res[0].assignee.lastName).toEqual('lastName');
|
||||
expect(res[1].name).toEqual('FakeCheckTask2');
|
||||
expect(res[1].assignee.email).toEqual('fake-email@dom.com');
|
||||
expect(res[1].assignee.firstName).toEqual('firstName');
|
||||
expect(res[0].assignee.lastName).toEqual('lastName');
|
||||
done();
|
||||
}
|
||||
);
|
||||
|
||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||
'status': 200,
|
||||
contentType: 'application/json',
|
||||
responseText: JSON.stringify(fakeTasksChecklist)
|
||||
});
|
||||
});
|
||||
|
||||
it('should add a task ', (done) => {
|
||||
let taskFake = new TaskDetailsModel({
|
||||
id: '', name: 'FakeNameTask', description: null, category: null,
|
||||
assignee: fakeUser,
|
||||
created: ''
|
||||
});
|
||||
|
||||
service.addTask(taskFake).subscribe(
|
||||
(res: TaskDetailsModel) => {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.id).not.toEqual('');
|
||||
expect(res.name).toEqual('FakeNameTask');
|
||||
expect(res.created).not.toEqual('');
|
||||
done();
|
||||
}
|
||||
);
|
||||
|
||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||
'status': 200,
|
||||
contentType: 'application/json',
|
||||
responseText: JSON.stringify({
|
||||
id: '777', name: 'FakeNameTask', description: null, category: null,
|
||||
assignee: fakeUser,
|
||||
created: '2016-07-15T11:19:17.440+0000'
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
it('should add a comment task ', (done) => {
|
||||
|
||||
service.addTaskComment(999, 'fake-comment-message').subscribe(
|
||||
(res: Comment) => {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.id).not.toEqual('');
|
||||
expect(res.message).toEqual('fake-comment-message');
|
||||
expect(res.created).not.toEqual('');
|
||||
expect(res.createdBy.email).toEqual('fake-email@dom.com');
|
||||
expect(res.createdBy.firstName).toEqual('firstName');
|
||||
expect(res.createdBy.lastName).toEqual('lastName');
|
||||
done();
|
||||
}
|
||||
);
|
||||
|
||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||
'status': 200,
|
||||
contentType: 'application/json',
|
||||
responseText: JSON.stringify({
|
||||
id: '111', message: 'fake-comment-message',
|
||||
createdBy: fakeUser,
|
||||
created: '2016-07-15T11:19:17.440+0000'
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should complete the task ', (done) => {
|
||||
|
||||
service.completeTask(999).subscribe(
|
||||
(res: any) => {
|
||||
expect(res).toBeDefined();
|
||||
done();
|
||||
}
|
||||
);
|
||||
|
||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||
'status': 200,
|
||||
contentType: 'application/json',
|
||||
responseText: JSON.stringify({})
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
@@ -20,6 +20,11 @@ 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 { FilterParamsModel } from '../models/filter.model';
|
||||
import { Comment } from '../models/comment.model';
|
||||
import { User } from '../models/user.model';
|
||||
|
||||
import { TaskDetailsModel } from '../models/task-details.model';
|
||||
|
||||
@Injectable()
|
||||
export class ActivitiTaskListService {
|
||||
@@ -33,6 +38,27 @@ export class ActivitiTaskListService {
|
||||
*/
|
||||
getTaskListFilters(): Observable<any> {
|
||||
return Observable.fromPromise(this.callApiTaskFilters())
|
||||
.map(res => res.json())
|
||||
.map((response: any) => {
|
||||
let filters: FilterModel[] = [];
|
||||
response.data.forEach((filter) => {
|
||||
let filterModel = new FilterModel(filter.name, filter.recent, filter.icon,
|
||||
filter.filter.name, filter.filter.state, filter.filter.assignment);
|
||||
filters.push(filterModel);
|
||||
});
|
||||
return filters;
|
||||
})
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrive all the tasks filtered by filterModel
|
||||
* @param filter - FilterModel
|
||||
* @returns {any}
|
||||
*/
|
||||
getTasks(filter: FilterModel): Observable<any> {
|
||||
|
||||
return Observable.fromPromise(this.callApiTasksFiltered(filter.filter))
|
||||
.map((res: Response) => {
|
||||
return res.json();
|
||||
})
|
||||
@@ -40,24 +66,100 @@ export class ActivitiTaskListService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrive all the tasks created in activiti
|
||||
* @returns {any}
|
||||
* Retrive all the task details
|
||||
* @param id - taskId
|
||||
* @returns {<TaskDetailsModel>}
|
||||
*/
|
||||
getTasks(filter: FilterModel): Observable<any> {
|
||||
let data: any = {};
|
||||
data.filterId = filter.id;
|
||||
data.filter = filter.filter;
|
||||
data = JSON.stringify(data);
|
||||
|
||||
return Observable.fromPromise(this.callApiTasksFiltered(data))
|
||||
.map((res: Response) => {
|
||||
return res.json();
|
||||
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);
|
||||
}
|
||||
|
||||
private callApiTasksFiltered(data: Object) {
|
||||
let url = this.alfrescoSettingsService.getBPMApiBaseUrl() + '/rest/filter/tasks';
|
||||
/**
|
||||
* Retrive all the task's comments
|
||||
* @param id - taskId
|
||||
* @returns {<Comment[]>}
|
||||
*/
|
||||
getTaskComments(id: string): Observable<Comment[]> {
|
||||
return Observable.fromPromise(this.callApiTaskComments(id))
|
||||
.map(res => res.json())
|
||||
.map((response: any) => {
|
||||
let comments: Comment[] = [];
|
||||
response.data.forEach((comment) => {
|
||||
let user = new User(
|
||||
comment.createdBy.id, comment.createdBy.email, comment.createdBy.firstName, comment.createdBy.lastName);
|
||||
comments.push(new Comment(comment.id, comment.message, comment.created, user));
|
||||
});
|
||||
return comments;
|
||||
})
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrive all the task's checklist
|
||||
* @param id - taskId
|
||||
* @returns {TaskDetailsModel}
|
||||
*/
|
||||
getTaskChecklist(id: string): Observable<TaskDetailsModel[]> {
|
||||
return Observable.fromPromise(this.callApiTaskChecklist(id))
|
||||
.map(res => res.json())
|
||||
.map((response: any) => {
|
||||
let checklists: TaskDetailsModel[] = [];
|
||||
response.data.forEach((checklist) => {
|
||||
checklists.push(new TaskDetailsModel(checklist));
|
||||
});
|
||||
return checklists;
|
||||
})
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a task
|
||||
* @param task - TaskDetailsModel
|
||||
* @returns {TaskDetailsModel}
|
||||
*/
|
||||
addTask(task: TaskDetailsModel): Observable<TaskDetailsModel> {
|
||||
return Observable.fromPromise(this.callApiAddTask(task))
|
||||
.map(res => res.json())
|
||||
.map((response: TaskDetailsModel) => {
|
||||
return new TaskDetailsModel(response);
|
||||
})
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a comment to a task
|
||||
* @param id - taskId
|
||||
* @param message - content of the comment
|
||||
* @returns {Comment}
|
||||
*/
|
||||
addTaskComment(id: string, message: string): Observable<Comment> {
|
||||
return Observable.fromPromise(this.callApiAddTaskComment(id, message))
|
||||
.map(res => res.json())
|
||||
.map((response: Comment) => {
|
||||
return new Comment(response.id, response.message, response.created, response.createdBy);
|
||||
})
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the task completed
|
||||
* @param id - taskId
|
||||
* @returns {TaskDetailsModel}
|
||||
*/
|
||||
completeTask(id: string): Observable<TaskDetailsModel> {
|
||||
return Observable.fromPromise(this.callApiCompleteTask(id))
|
||||
.map(res => res.json())
|
||||
.catch(this.handleError);
|
||||
}
|
||||
|
||||
private callApiTasksFiltered(filter: FilterParamsModel) {
|
||||
let data = JSON.stringify(filter);
|
||||
let url = this.alfrescoSettingsService.getBPMApiBaseUrl() + `/api/enterprise/tasks/query`;
|
||||
let headers = new Headers({
|
||||
'Content-Type': 'application/json',
|
||||
'Cache-Control': 'no-cache'
|
||||
@@ -69,7 +171,7 @@ export class ActivitiTaskListService {
|
||||
}
|
||||
|
||||
private callApiTaskFilters() {
|
||||
let url = this.alfrescoSettingsService.getBPMApiBaseUrl() + '/rest/filters/tasks';
|
||||
let url = this.alfrescoSettingsService.getBPMApiBaseUrl() + `/api/enterprise/filters/tasks`;
|
||||
let headers = new Headers({
|
||||
'Content-Type': 'application/json',
|
||||
'Cache-Control': 'no-cache'
|
||||
@@ -80,6 +182,80 @@ export class ActivitiTaskListService {
|
||||
.get(url, options).toPromise();
|
||||
}
|
||||
|
||||
private callApiTaskDetails(id: string) {
|
||||
let url = this.alfrescoSettingsService.getBPMApiBaseUrl() + `/api/enterprise/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 callApiTaskComments(id: string) {
|
||||
let url = this.alfrescoSettingsService.getBPMApiBaseUrl() + `/api/enterprise/tasks/${id}/comments`;
|
||||
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 callApiAddTaskComment(id: string, message: string) {
|
||||
let url = this.alfrescoSettingsService.getBPMApiBaseUrl() + `/api/enterprise/tasks/${id}/comments`;
|
||||
let headers = new Headers({
|
||||
'Content-Type': 'application/json',
|
||||
'Cache-Control': 'no-cache'
|
||||
});
|
||||
let body = JSON.stringify({message: message});
|
||||
let options = new RequestOptions({headers: headers});
|
||||
|
||||
return this.http
|
||||
.post(url, body, options).toPromise();
|
||||
}
|
||||
|
||||
private callApiAddTask(task: TaskDetailsModel) {
|
||||
let url = this.alfrescoSettingsService.getBPMApiBaseUrl() + `/api/enterprise/tasks/${task.parentTaskId}/checklist`;
|
||||
let headers = new Headers({
|
||||
'Content-Type': 'application/json',
|
||||
'Cache-Control': 'no-cache'
|
||||
});
|
||||
let body = JSON.stringify(task);
|
||||
let options = new RequestOptions({headers: headers});
|
||||
|
||||
return this.http
|
||||
.post(url, body, options).toPromise();
|
||||
}
|
||||
|
||||
private callApiTaskChecklist(id: string) {
|
||||
let url = this.alfrescoSettingsService.getBPMApiBaseUrl() + `/api/enterprise/tasks/${id}/checklist`;
|
||||
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 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
|
||||
|
||||
@@ -75,7 +75,7 @@ export class AlfrescoAuthenticationBPM extends AlfrescoAuthenticationBase implem
|
||||
}
|
||||
|
||||
private apiActivitiLogin(username: string, password: string) {
|
||||
let url = this.alfrescoSettingsService.getBPMApiBaseUrl() + '/authentication';
|
||||
let url = this.alfrescoSettingsService.getBPMApiBaseUrl() + '/app/authentication';
|
||||
let headers = new Headers({
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
});
|
||||
@@ -91,7 +91,7 @@ export class AlfrescoAuthenticationBPM extends AlfrescoAuthenticationBase implem
|
||||
}
|
||||
|
||||
private apiActivitiLogout() {
|
||||
let url = this.alfrescoSettingsService.getBPMApiBaseUrl() + '/logout';
|
||||
let url = this.alfrescoSettingsService.getBPMApiBaseUrl() + '/app/logout';
|
||||
return this.http.get(url).toPromise();
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ export class AlfrescoSettingsService {
|
||||
static DEFAULT_BPM_CONTEXT_PATH: string = '/activiti-app';
|
||||
|
||||
static DEFAULT_ECM_BASE_API_PATH: string = '/api/-default-/public/alfresco/versions/1';
|
||||
static DEFAULT_BPM_BASE_API_PATH: string = '/app';
|
||||
|
||||
private _ecmHost: string = AlfrescoSettingsService.DEFAULT_ECM_ADDRESS;
|
||||
private _bpmHost: string = AlfrescoSettingsService.DEFAULT_BPM_ADDRESS;
|
||||
@@ -36,7 +35,6 @@ export class AlfrescoSettingsService {
|
||||
private _bpmContextPath = AlfrescoSettingsService.DEFAULT_BPM_CONTEXT_PATH;
|
||||
|
||||
private _apiECMBasePath: string = AlfrescoSettingsService.DEFAULT_ECM_BASE_API_PATH;
|
||||
private _apiBPMBasePath: string = AlfrescoSettingsService.DEFAULT_BPM_BASE_API_PATH;
|
||||
|
||||
private providers: string[] = ['ECM', 'BPM'];
|
||||
|
||||
@@ -57,7 +55,7 @@ export class AlfrescoSettingsService {
|
||||
}
|
||||
|
||||
public getBPMApiBaseUrl(): string {
|
||||
return this._bpmHost + this._bpmContextPath + this._apiBPMBasePath;
|
||||
return this._bpmHost + this._bpmContextPath;
|
||||
}
|
||||
|
||||
public getECMApiBaseUrl(): string {
|
||||
|
||||
Reference in New Issue
Block a user