diff --git a/demo-shell-ng2/app/components/activiti/activiti-demo.component.html b/demo-shell-ng2/app/components/activiti/activiti-demo.component.html
index 766434a190..41bfb72f31 100644
--- a/demo-shell-ng2/app/components/activiti/activiti-demo.component.html
+++ b/demo-shell-ng2/app/components/activiti/activiti-demo.component.html
@@ -13,12 +13,12 @@
Task Details
@@ -33,12 +33,16 @@
diff --git a/demo-shell-ng2/app/components/activiti/activiti-demo.component.ts b/demo-shell-ng2/app/components/activiti/activiti-demo.component.ts
index 9775ac02b8..95ed87e8dd 100644
--- a/demo-shell-ng2/app/components/activiti/activiti-demo.component.ts
+++ b/demo-shell-ng2/app/components/activiti/activiti-demo.component.ts
@@ -17,6 +17,7 @@
import { Component, AfterViewChecked, ViewChild } from '@angular/core';
import { ALFRESCO_TASKLIST_DIRECTIVES } from 'ng2-activiti-tasklist';
+import { ACTIVITI_PROCESSLIST_DIRECTIVES } from 'ng2-activiti-processlist';
import { ActivitiForm } from 'ng2-activiti-form';
declare let __moduleName: string;
@@ -27,7 +28,7 @@ declare var componentHandler;
selector: 'activiti-demo',
templateUrl: './activiti-demo.component.html',
styleUrls: ['./activiti-demo.component.css'],
- directives: [ALFRESCO_TASKLIST_DIRECTIVES, ActivitiForm]
+ directives: [ALFRESCO_TASKLIST_DIRECTIVES, ACTIVITI_PROCESSLIST_DIRECTIVES, ActivitiForm]
})
export class ActivitiDemoComponent implements AfterViewChecked {
@@ -39,11 +40,20 @@ export class ActivitiDemoComponent implements AfterViewChecked {
@ViewChild('activititasklist')
activititasklist: any;
- currentTaskId: string;
+ @ViewChild('activitiprocesslist')
+ activitiprocesslist: any;
- schemaColumn: any [] = [];
+ @ViewChild('activitiprocessdetails')
+ activitiprocessdetails: any;
+
+ currentTaskId: string;
+ currentProcessInstanceId: string;
+
+ taskSchemaColumns: any [] = [];
+ processSchemaColumns: any [] = [];
taskFilter: any;
+ processFilter: any;
setChoice($event) {
this.currentChoice = $event.target.value;
@@ -58,23 +68,44 @@ export class ActivitiDemoComponent implements AfterViewChecked {
}
constructor() {
- console.log('Activiti demo component');
- this.schemaColumn = [
+ this.taskSchemaColumns = [
{type: 'text', key: 'name', title: 'Name', cssClass: 'full-width name-column', sortable: true}
// {type: 'text', key: 'created', title: 'Created', sortable: true}
];
+ this.processSchemaColumns = [
+ {type: 'text', key: 'name', title: 'Name', cssClass: 'full-width name-column', sortable: true}
+ ];
}
- onFilterClick(event: any) {
+ onTaskFilterClick(event: any) {
this.taskFilter = event;
this.activititasklist.load(this.taskFilter);
}
- onRowClick(taskId) {
+ onProcessFilterClick(event: any) {
+ this.processFilter = event.filter;
+ this.activitiprocesslist.load(this.processFilter);
+ }
+
+ onTaskRowClick(taskId) {
this.currentTaskId = taskId;
this.activitidetails.loadDetails(this.currentTaskId);
}
+ onProcessRowClick(processInstanceId) {
+ this.currentProcessInstanceId = processInstanceId;
+ this.activitiprocessdetails.load(this.currentProcessInstanceId);
+ }
+
+ processCancelled(data: any) {
+ this.currentProcessInstanceId = null;
+ this.activitiprocesslist.reload();
+ }
+
+ taskFormCompleted(data: any) {
+ this.activitiprocesslist.reload();
+ }
+
ngAfterViewChecked() {
// workaround for MDL issues with dynamic components
if (componentHandler) {
diff --git a/demo-shell-ng2/systemjs.config.js b/demo-shell-ng2/systemjs.config.js
index 70c4466d67..782acb4d85 100644
--- a/demo-shell-ng2/systemjs.config.js
+++ b/demo-shell-ng2/systemjs.config.js
@@ -20,6 +20,7 @@
'ng2-activiti-form': 'node_modules/ng2-activiti-form/dist',
'ng2-alfresco-viewer': 'node_modules/ng2-alfresco-viewer/dist',
'ng2-alfresco-webscript': 'node_modules/ng2-alfresco-webscript/dist',
+ 'ng2-activiti-processlist': 'node_modules/ng2-activiti-processlist/dist',
'ng2-activiti-tasklist': 'node_modules/ng2-activiti-tasklist/dist'
};
// packages tells the System loader how to load when no filename and/or no extension
@@ -38,6 +39,7 @@
'ng2-alfresco-upload': { main: 'index.js', defaultExtension: 'js'},
'ng2-alfresco-viewer': { main: 'index.js', defaultExtension: 'js'},
'ng2-activiti-form': { main: 'index.js', defaultExtension: 'js'},
+ 'ng2-activiti-processlist': { main: 'index.js', defaultExtension: 'js'},
'ng2-activiti-tasklist': { main: 'index.js', defaultExtension: 'js'},
'ng2-alfresco-webscript': { main: 'index.js', defaultExtension: 'js'}
};
diff --git a/ng2-components/ng2-activiti-processlist/data/processlist-datatable-adapter.ts b/ng2-components/ng2-activiti-processlist/data/processlist-datatable-adapter.ts
new file mode 100644
index 0000000000..b3e39360f4
--- /dev/null
+++ b/ng2-components/ng2-activiti-processlist/data/processlist-datatable-adapter.ts
@@ -0,0 +1,123 @@
+/*!
+ * @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 { DatePipe } from '@angular/common';
+import {
+ DataTableAdapter, ObjectDataTableAdapter, ObjectDataColumn,
+ DataRow, DataColumn, DataSorting
+} from 'ng2-alfresco-datatable';
+
+export class ProcessListDataTableAdapter extends ObjectDataTableAdapter implements DataTableAdapter {
+
+ ERR_ROW_NOT_FOUND: string = 'Row not found';
+ ERR_COL_NOT_FOUND: string = 'Column not found';
+
+ DEFAULT_DATE_FORMAT: string = 'medium';
+
+ private sorting: DataSorting;
+ private rows: DataRow[];
+ private columns: DataColumn[];
+
+ constructor(rows: any, schema: DataColumn[]) {
+ super(rows, schema);
+ this.rows = rows;
+ this.columns = schema || [];
+ }
+
+ getRows(): Array
{
+ return this.rows;
+ }
+
+ // TODO: disable this api
+ setRows(rows: Array) {
+ this.rows = rows || [];
+ this.sort();
+ }
+
+ getColumns(): Array {
+ return this.columns;
+ }
+
+ setColumns(columns: Array) {
+ this.columns = columns || [];
+ }
+
+ getValue(row: DataRow, col: DataColumn): any {
+ if (!row) {
+ throw new Error(this.ERR_ROW_NOT_FOUND);
+ }
+ if (!col) {
+ throw new Error(this.ERR_COL_NOT_FOUND);
+ }
+ let value = row.getValue(col.key);
+
+ if (col.type === 'date') {
+ let datePipe = new DatePipe();
+ let format = ((col)).format || this.DEFAULT_DATE_FORMAT;
+ try {
+ return datePipe.transform(value, format);
+ } catch (err) {
+ console.error(`Error parsing date ${value} to format ${format}`);
+ }
+ }
+
+ return value;
+ }
+
+ getSorting(): DataSorting {
+ return this.sorting;
+ }
+
+ setSorting(sorting: DataSorting): void {
+ this.sorting = sorting;
+
+ if (sorting && sorting.key && this.rows && this.rows.length > 0) {
+ this.rows.sort((a: DataRow, b: DataRow) => {
+ let left = a.getValue(sorting.key);
+ if (left) {
+ left = (left instanceof Date) ? left.valueOf().toString() : left.toString();
+ } else {
+ left = '';
+ }
+
+ let right = b.getValue(sorting.key);
+ if (right) {
+ right = (right instanceof Date) ? right.valueOf().toString() : right.toString();
+ } else {
+ right = '';
+ }
+
+ return sorting.direction === 'asc'
+ ? left.localeCompare(right)
+ : right.localeCompare(left);
+ });
+ }
+ }
+
+ sort(key?: string, direction?: string): void {
+ let sorting = this.sorting || new DataSorting();
+ if (key) {
+ sorting.key = key;
+ sorting.direction = direction || 'asc';
+ }
+ this.setSorting(sorting);
+ }
+}
+
+export class ActivitiDataColumn extends ObjectDataColumn {
+ format: string;
+}
diff --git a/ng2-components/ng2-activiti-processlist/demo/src/main.ts b/ng2-components/ng2-activiti-processlist/demo/src/main.ts
index 36900923c0..9d3c4df947 100644
--- a/ng2-components/ng2-activiti-processlist/demo/src/main.ts
+++ b/ng2-components/ng2-activiti-processlist/demo/src/main.ts
@@ -44,7 +44,7 @@ import {
`,
providers: [ACTIVITI_PROCESSLIST_PROVIDERS],
directives: [ACTIVITI_PROCESSLIST_DIRECTIVES]
diff --git a/ng2-components/ng2-activiti-processlist/index.ts b/ng2-components/ng2-activiti-processlist/index.ts
index b1f8081c26..34bd934992 100644
--- a/ng2-components/ng2-activiti-processlist/index.ts
+++ b/ng2-components/ng2-activiti-processlist/index.ts
@@ -15,17 +15,30 @@
* limitations under the License.
*/
-import { ActivitiProcesslistComponent } from './src/components/activiti-processlist.component';
+import { ActivitiProcessInstanceListComponent } from './src/components/activiti-processlist.component';
+import { ActivitiProcessFilters } from './src/components/activiti-filters.component';
+import { ActivitiProcessInstanceHeader } from './src/components/activiti-process-instance-header.component';
+import { ActivitiProcessInstanceTasks } from './src/components/activiti-process-instance-tasks.component';
+import { ActivitiComments } from './src/components/activiti-comments.component';
+import { ActivitiProcessInstanceDetails } from './src/components/activiti-process-instance-details.component';
+import { ActivitiStartProcessButton } from './src/components/activiti-start-process.component';
import { ActivitiProcessService } from './src/services/activiti-process.service';
// components
export * from './src/components/activiti-processlist.component';
+export * from './src/components/activiti-process-instance-details.component';
// services
export * from './src/services/activiti-process.service';
export const ACTIVITI_PROCESSLIST_DIRECTIVES: [any] = [
- ActivitiProcesslistComponent
+ ActivitiProcessInstanceListComponent,
+ ActivitiProcessFilters,
+ ActivitiProcessInstanceDetails,
+ ActivitiProcessInstanceHeader,
+ ActivitiProcessInstanceTasks,
+ ActivitiComments,
+ ActivitiStartProcessButton
];
export const ACTIVITI_PROCESSLIST_PROVIDERS: [any] = [
diff --git a/ng2-components/ng2-activiti-processlist/karma.conf.js b/ng2-components/ng2-activiti-processlist/karma.conf.js
index f9a39b76a0..1a3d76b9db 100644
--- a/ng2-components/ng2-activiti-processlist/karma.conf.js
+++ b/ng2-components/ng2-activiti-processlist/karma.conf.js
@@ -20,6 +20,9 @@ module.exports = function (config) {
{pattern: 'node_modules/ng2-alfresco-datatable/dist/**/*.js', included: false, served: true, watched: false},
{pattern: 'node_modules/ng2-alfresco-datatable/dist/**/*.html', included: false, served: true, watched: false},
{pattern: 'node_modules/ng2-alfresco-datatable/dist/**/*.css', included: false, served: true, watched: false},
+ {pattern: 'node_modules/ng2-activiti-tasklist/dist/**/*.js', included: false, served: true, watched: false},
+ {pattern: 'node_modules/ng2-activiti-tasklist/dist/**/*.html', included: false, served: true, watched: false},
+ {pattern: 'node_modules/ng2-activiti-tasklist/dist/**/*.css', included: false, served: true, watched: false},
{pattern: 'node_modules/ng2-translate/**/*.js', included: false, served: true, watched: false},
{pattern: 'node_modules/alfresco-js-api/dist/alfresco-js-api.js', included: true, watched: false},
diff --git a/ng2-components/ng2-activiti-processlist/package.json b/ng2-components/ng2-activiti-processlist/package.json
index 27fe458691..01307a17a0 100644
--- a/ng2-components/ng2-activiti-processlist/package.json
+++ b/ng2-components/ng2-activiti-processlist/package.json
@@ -64,7 +64,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-tasklist": "0.2.0"
},
"devDependencies": {
"angular-cli": "1.0.0-beta.9",
diff --git a/ng2-components/ng2-activiti-processlist/src/components/activiti-comments.component.css b/ng2-components/ng2-activiti-processlist/src/components/activiti-comments.component.css
new file mode 100644
index 0000000000..ff0f8dd865
--- /dev/null
+++ b/ng2-components/ng2-activiti-processlist/src/components/activiti-comments.component.css
@@ -0,0 +1,7 @@
+:host {
+ width: 100%;
+}
+
+.activiti-label {
+ font-weight: bolder;
+}
diff --git a/ng2-components/ng2-activiti-processlist/src/components/activiti-comments.component.html b/ng2-components/ng2-activiti-processlist/src/components/activiti-comments.component.html
new file mode 100644
index 0000000000..169719612e
--- /dev/null
+++ b/ng2-components/ng2-activiti-processlist/src/components/activiti-comments.component.html
@@ -0,0 +1,35 @@
+{{ 'DETAILS.LABELS.COMMENTS' |translate }}
+
+
+ Add a comment
+
+
+
+
+ {{ 'DETAILS.COMMENTS.NONE' | translate }}
+
+
+
+
diff --git a/ng2-components/ng2-activiti-processlist/src/components/activiti-comments.component.ts b/ng2-components/ng2-activiti-processlist/src/components/activiti-comments.component.ts
new file mode 100644
index 0000000000..95f1219c92
--- /dev/null
+++ b/ng2-components/ng2-activiti-processlist/src/components/activiti-comments.component.ts
@@ -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 { ActivitiProcessService } from './../services/activiti-process.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: [ActivitiProcessService],
+ pipes: [ AlfrescoPipeTranslate ]
+
+})
+export class ActivitiComments implements OnInit {
+
+ @Input()
+ processId: string;
+
+ @ViewChild('dialog')
+ dialog: any;
+
+ comments: Comment [] = [];
+
+ private commentObserver: Observer;
+ comment$: Observable;
+
+ message: string;
+
+ /**
+ * Constructor
+ * @param auth
+ * @param translate
+ */
+ constructor(private auth: AlfrescoAuthenticationService,
+ private translate: AlfrescoTranslationService,
+ private activitiProcess: ActivitiProcessService) {
+
+ if (translate) {
+ translate.addTranslationFolder('node_modules/ng2-activiti-processlist/src');
+ }
+
+ this.comment$ = new Observable(observer => this.commentObserver = observer).share();
+
+ }
+
+ ngOnInit() {
+ this.comment$.subscribe((comment: Comment) => {
+ this.comments.push(comment);
+ });
+
+ if (this.processId) {
+ this.load(this.processId);
+ }
+ }
+
+ public load(taskId: string) {
+ this.comments = [];
+ if (this.processId) {
+ this.activitiProcess.getProcessInstanceComments(this.processId).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.activitiProcess.addProcessInstanceComment(this.processId, 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();
+ }
+ }
+}
diff --git a/ng2-components/ng2-activiti-processlist/src/components/activiti-filters.component.css b/ng2-components/ng2-activiti-processlist/src/components/activiti-filters.component.css
new file mode 100644
index 0000000000..6b7e0a7a66
--- /dev/null
+++ b/ng2-components/ng2-activiti-processlist/src/components/activiti-filters.component.css
@@ -0,0 +1,3 @@
+.mdl-list__item {
+ cursor: pointer;
+}
diff --git a/ng2-components/ng2-activiti-processlist/src/components/activiti-filters.component.html b/ng2-components/ng2-activiti-processlist/src/components/activiti-filters.component.html
new file mode 100644
index 0000000000..580798c6a3
--- /dev/null
+++ b/ng2-components/ng2-activiti-processlist/src/components/activiti-filters.component.html
@@ -0,0 +1,10 @@
+
\ No newline at end of file
diff --git a/ng2-components/ng2-activiti-processlist/src/components/activiti-filters.component.ts b/ng2-components/ng2-activiti-processlist/src/components/activiti-filters.component.ts
new file mode 100644
index 0000000000..9032d2f173
--- /dev/null
+++ b/ng2-components/ng2-activiti-processlist/src/components/activiti-filters.component.ts
@@ -0,0 +1,131 @@
+/*!
+ * @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, Input } from '@angular/core';
+import { AlfrescoTranslationService, AlfrescoAuthenticationService, AlfrescoPipeTranslate } from 'ng2-alfresco-core';
+import { ActivitiProcessService } from './../services/activiti-process.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-process-filters',
+ moduleId: __moduleName,
+ templateUrl: './activiti-filters.component.html',
+ styleUrls: ['activiti-filters.component.css'],
+ providers: [ActivitiProcessService],
+ pipes: [AlfrescoPipeTranslate]
+
+})
+export class ActivitiProcessFilters implements OnInit {
+
+ @Output()
+ filterClick: EventEmitter = new EventEmitter();
+
+ @Output()
+ onSuccess: EventEmitter = new EventEmitter();
+
+ @Output()
+ onError: EventEmitter = new EventEmitter();
+
+ @Input()
+ appId: string;
+
+ @Input()
+ appName: string;
+
+ private filterObserver: Observer;
+ filter$: Observable;
+
+ currentFilter: FilterModel;
+
+ filters: FilterModel [] = [];
+
+ /**
+ * Constructor
+ * @param auth
+ * @param translate
+ * @param activiti
+ */
+ constructor(private auth: AlfrescoAuthenticationService,
+ private translate: AlfrescoTranslationService,
+ public activiti: ActivitiProcessService) {
+ this.filter$ = new Observable(observer => this.filterObserver = observer).share();
+
+ if (translate) {
+ translate.addTranslationFolder('node_modules/ng2-activiti-processlist/src');
+ }
+ }
+
+ 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() {
+ if (this.appName) {
+ this.filterByAppName();
+ } else {
+ this.filterByAppId(this.appId);
+ }
+ }
+
+ private filterByAppId(appId) {
+ this.activiti.getProcessFilters(appId).subscribe(
+ (res: FilterModel[]) => {
+ res.forEach((filter) => {
+ this.filterObserver.next(filter);
+ });
+ this.onSuccess.emit(res);
+ },
+ (err) => {
+ console.log(err);
+ this.onError.emit(err);
+ }
+ );
+ }
+
+ private filterByAppName() {
+ this.activiti.getDeployedApplications(this.appName).subscribe(
+ application => {
+ this.filterByAppId(application.id);
+ },
+ (err) => {
+ console.log(err);
+ this.onError.emit(err);
+ });
+ }
+
+ /**
+ * Pass the selected filter as next
+ * @param filter
+ */
+ public selectFilter(filter: FilterModel) {
+ this.currentFilter = filter;
+ this.filterClick.emit(filter);
+ }
+}
diff --git a/ng2-components/ng2-activiti-processlist/src/components/activiti-process-instance-details.component.css b/ng2-components/ng2-activiti-processlist/src/components/activiti-process-instance-details.component.css
new file mode 100644
index 0000000000..07eaf92d80
--- /dev/null
+++ b/ng2-components/ng2-activiti-processlist/src/components/activiti-process-instance-details.component.css
@@ -0,0 +1,3 @@
+:host {
+ width: 100%;
+}
\ No newline at end of file
diff --git a/ng2-components/ng2-activiti-processlist/src/components/activiti-process-instance-details.component.html b/ng2-components/ng2-activiti-processlist/src/components/activiti-process-instance-details.component.html
new file mode 100644
index 0000000000..741dcabc47
--- /dev/null
+++ b/ng2-components/ng2-activiti-processlist/src/components/activiti-process-instance-details.component.html
@@ -0,0 +1,13 @@
+{{ 'DETAILS.MESSAGES.NONE'|translate }}
+
+
{{processInstanceDetails.name}}
+
+
+
diff --git a/ng2-components/ng2-activiti-processlist/src/components/activiti-process-instance-details.component.ts b/ng2-components/ng2-activiti-processlist/src/components/activiti-process-instance-details.component.ts
new file mode 100644
index 0000000000..bd50c40303
--- /dev/null
+++ b/ng2-components/ng2-activiti-processlist/src/components/activiti-process-instance-details.component.ts
@@ -0,0 +1,109 @@
+/*!
+ * @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, ViewChild, Output, EventEmitter } from '@angular/core';
+import { AlfrescoTranslationService, AlfrescoAuthenticationService, AlfrescoPipeTranslate } from 'ng2-alfresco-core';
+import { ActivitiProcessService } from './../services/activiti-process.service';
+import { ActivitiProcessInstanceHeader } from './activiti-process-instance-header.component';
+import { ActivitiProcessInstanceTasks } from './activiti-process-instance-tasks.component';
+import { ActivitiComments } from './activiti-comments.component';
+import { ProcessInstance } from '../models/process-instance';
+
+
+declare let componentHandler: any;
+declare let __moduleName: string;
+
+@Component({
+ selector: 'activiti-process-instance-details',
+ moduleId: __moduleName,
+ templateUrl: './activiti-process-instance-details.component.html',
+ styleUrls: ['./activiti-process-instance-details.component.css'],
+ providers: [ActivitiProcessService],
+ directives: [ActivitiProcessInstanceHeader, ActivitiComments, ActivitiProcessInstanceTasks],
+ pipes: [AlfrescoPipeTranslate]
+
+})
+export class ActivitiProcessInstanceDetails {
+
+ @Input()
+ processInstanceId: string;
+
+ @ViewChild('activitiprocessheader')
+ processInstanceHeader: ActivitiProcessInstanceHeader;
+
+ @ViewChild('activitiprocesstasks')
+ tasksList: ActivitiProcessInstanceTasks;
+
+ @ViewChild('activitiprocesscomments')
+ commentsList: ActivitiComments;
+
+ @Input()
+ showTitle: boolean = true;
+
+ @Input()
+ showRefreshButton: boolean = true;
+
+ @Output()
+ processCancelledEmitter = new EventEmitter();
+
+ @Output()
+ taskFormCompletedEmitter = new EventEmitter();
+
+ processInstanceDetails: ProcessInstance;
+
+ /**
+ * Constructor
+ * @param auth
+ * @param translate
+ * @param activitiProcess
+ */
+ constructor(private auth: AlfrescoAuthenticationService,
+ private translate: AlfrescoTranslationService,
+ private activitiProcess: ActivitiProcessService) {
+
+ if (translate) {
+ translate.addTranslationFolder('node_modules/ng2-activiti-processlist/src');
+ }
+ }
+
+ load(processId: string) {
+ if (processId) {
+ this.activitiProcess.getProcess(processId).subscribe(
+ (res: ProcessInstance) => {
+ this.processInstanceDetails = res;
+ if (this.processInstanceDetails) {
+ if (this.commentsList) {
+ this.commentsList.load(this.processInstanceDetails.id);
+ }
+ if (this.tasksList) {
+ this.tasksList.load(this.processInstanceDetails.id);
+ }
+ }
+ console.log('Loaded process instance', this.processInstanceDetails);
+ }
+ );
+ }
+ }
+
+ processCancelled(data: any) {
+ this.processCancelledEmitter.emit(data);
+ }
+
+ taskFormCompleted(data: any) {
+ this.taskFormCompletedEmitter.emit(data);
+ }
+}
diff --git a/ng2-components/ng2-activiti-processlist/src/components/activiti-process-instance-header.component.css b/ng2-components/ng2-activiti-processlist/src/components/activiti-process-instance-header.component.css
new file mode 100644
index 0000000000..20fbab0626
--- /dev/null
+++ b/ng2-components/ng2-activiti-processlist/src/components/activiti-process-instance-header.component.css
@@ -0,0 +1,7 @@
+:host {
+ width: 100%;
+}
+
+.activiti-label {
+ font-weight: bolder;
+}
\ No newline at end of file
diff --git a/ng2-components/ng2-activiti-processlist/src/components/activiti-process-instance-header.component.html b/ng2-components/ng2-activiti-processlist/src/components/activiti-process-instance-header.component.html
new file mode 100644
index 0000000000..8e7a434a7f
--- /dev/null
+++ b/ng2-components/ng2-activiti-processlist/src/components/activiti-process-instance-header.component.html
@@ -0,0 +1,15 @@
+
+
+
+ {{ 'DETAILS.LABELS.STARTED_BY' | translate }}:
+ {{getStartedByFullName()}}
+
+
+ {{ 'DETAILS.LABELS.STARTED' | translate }}:
+ {{getStartedDate() | date:'medium'}}
+
+
+
+
+
+
diff --git a/ng2-components/ng2-activiti-processlist/src/components/activiti-process-instance-header.component.ts b/ng2-components/ng2-activiti-processlist/src/components/activiti-process-instance-header.component.ts
new file mode 100644
index 0000000000..ed4f354cd4
--- /dev/null
+++ b/ng2-components/ng2-activiti-processlist/src/components/activiti-process-instance-header.component.ts
@@ -0,0 +1,74 @@
+/*!
+ * @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, Output, EventEmitter } from '@angular/core';
+import { AlfrescoTranslationService, AlfrescoAuthenticationService, AlfrescoPipeTranslate } from 'ng2-alfresco-core';
+import { ProcessInstance } from '../models/process-instance';
+import { ActivitiProcessService } from './../services/activiti-process.service';
+
+declare let componentHandler: any;
+declare let __moduleName: string;
+
+@Component({
+ selector: 'activiti-process-instance-header',
+ moduleId: __moduleName,
+ templateUrl: './activiti-process-instance-header.component.html',
+ styleUrls: ['./activiti-process-instance-header.component.css'],
+ pipes: [ AlfrescoPipeTranslate ]
+
+})
+export class ActivitiProcessInstanceHeader {
+
+ @Input()
+ processInstance: ProcessInstance;
+
+ @Output()
+ processCancelled = new EventEmitter();
+
+ /**
+ * Constructor
+ * @param auth
+ * @param translate
+ * @param activitiProcess
+ */
+ constructor(private auth: AlfrescoAuthenticationService,
+ private translate: AlfrescoTranslationService,
+ private activitiProcess: ActivitiProcessService) {
+
+ if (translate) {
+ translate.addTranslationFolder('node_modules/ng2-activiti-tasklist/src');
+ }
+ }
+
+ getStartedByFullName() {
+ if (this.processInstance && this.processInstance.startedBy) {
+ return (this.processInstance.startedBy.firstName && this.processInstance.startedBy.firstName !== 'null'
+ ? this.processInstance.startedBy.firstName + ' ' : '') +
+ this.processInstance.startedBy.lastName;
+ }
+ return '';
+ }
+
+ getStartedDate() {
+ return this.processInstance ? new Date(this.processInstance.started) : null;
+ }
+
+ cancelProcess() {
+ console.log('Cancel process', this.processInstance);
+ this.processCancelled.emit(this.activitiProcess.cancelProcess(this.processInstance.id));
+ }
+}
diff --git a/ng2-components/ng2-activiti-processlist/src/components/activiti-process-instance-tasks.component.css b/ng2-components/ng2-activiti-processlist/src/components/activiti-process-instance-tasks.component.css
new file mode 100644
index 0000000000..ca7a24db2c
--- /dev/null
+++ b/ng2-components/ng2-activiti-processlist/src/components/activiti-process-instance-tasks.component.css
@@ -0,0 +1,19 @@
+:host {
+ width: 100%;
+}
+
+.activiti-label {
+ font-weight: bolder;
+}
+
+.material-icons:hover {
+ color: rgb(255, 152, 0);
+}
+
+.task-details-dialog {
+ width: 600px;
+}
+
+.process-tasks-refresh {
+ float: right;
+}
diff --git a/ng2-components/ng2-activiti-processlist/src/components/activiti-process-instance-tasks.component.html b/ng2-components/ng2-activiti-processlist/src/components/activiti-process-instance-tasks.component.html
new file mode 100644
index 0000000000..b4ab3f9ee5
--- /dev/null
+++ b/ng2-components/ng2-activiti-processlist/src/components/activiti-process-instance-tasks.component.html
@@ -0,0 +1,52 @@
+
+
+
+
+{{ 'DETAILS.LABELS.TASKS_ACTIVE'|translate }}
+
+
+
+ {{ 'DETAILS.TASKS.NO_ACTIVE' | translate }}
+
+
+{{ 'DETAILS.LABELS.TASKS_COMPLETED'|translate }}
+
+
+
+ {{ 'DETAILS.TASKS.NO_COMPLETED' | translate }}
+
+
+
diff --git a/ng2-components/ng2-activiti-processlist/src/components/activiti-process-instance-tasks.component.ts b/ng2-components/ng2-activiti-processlist/src/components/activiti-process-instance-tasks.component.ts
new file mode 100644
index 0000000000..612e9674cf
--- /dev/null
+++ b/ng2-components/ng2-activiti-processlist/src/components/activiti-process-instance-tasks.component.ts
@@ -0,0 +1,183 @@
+/*!
+ * @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, Output, EventEmitter } from '@angular/core';
+import { AlfrescoTranslationService, AlfrescoAuthenticationService, AlfrescoPipeTranslate } from 'ng2-alfresco-core';
+import { ActivitiProcessService } from './../services/activiti-process.service';
+import { TaskDetailsModel } from '../models/task-details.model';
+import { ALFRESCO_TASKLIST_DIRECTIVES } from 'ng2-activiti-tasklist';
+import { Observer } from 'rxjs/Observer';
+import { Observable } from 'rxjs/Observable';
+
+declare let componentHandler: any;
+declare let __moduleName: string;
+
+@Component({
+ selector: 'activiti-process-instance-tasks',
+ moduleId: __moduleName,
+ templateUrl: './activiti-process-instance-tasks.component.html',
+ styleUrls: ['./activiti-process-instance-tasks.component.css'],
+ providers: [ActivitiProcessService],
+ directives: [ ALFRESCO_TASKLIST_DIRECTIVES ],
+ pipes: [ AlfrescoPipeTranslate ]
+
+})
+export class ActivitiProcessInstanceTasks implements OnInit {
+
+ @Input()
+ processId: string;
+
+ @Input()
+ showRefreshButton: boolean = true;
+
+ @Output()
+ taskFormCompletedEmitter = new EventEmitter();
+
+ activeTasks: TaskDetailsModel[] = [];
+ completedTasks: TaskDetailsModel[] = [];
+
+ private taskObserver: Observer;
+ private completedTaskObserver: Observer;
+
+ task$: Observable;
+ completedTask$: Observable;
+
+ message: string;
+
+ selectedTaskId: string;
+
+ @ViewChild('dialog')
+ dialog: any;
+
+ @ViewChild('taskdetails')
+ taskdetails: any;
+
+ /**
+ * Constructor
+ * @param auth
+ * @param translate
+ * @param activitiProcess
+ */
+ constructor(private auth: AlfrescoAuthenticationService,
+ private translate: AlfrescoTranslationService,
+ private activitiProcess: ActivitiProcessService) {
+
+ if (translate) {
+ translate.addTranslationFolder('node_modules/ng2-activiti-processlist/src');
+ }
+
+ this.task$ = new Observable(observer => this.taskObserver = observer).share();
+ this.completedTask$ = new Observable(observer => this.completedTaskObserver = observer).share();
+
+ }
+
+ ngOnInit() {
+ this.task$.subscribe((task: TaskDetailsModel) => {
+ this.activeTasks.push(task);
+ });
+ this.completedTask$.subscribe((task: TaskDetailsModel) => {
+ this.completedTasks.push(task);
+ });
+
+ if (this.processId) {
+ this.load(this.processId);
+ }
+ }
+
+ public load(processId: string) {
+ this.loadActive(processId);
+ this.loadCompleted(processId);
+ }
+
+ public loadActive(processId: string) {
+ this.activeTasks = [];
+ if (processId) {
+ this.activitiProcess.getProcessTasks(processId, null).subscribe(
+ (res: TaskDetailsModel[]) => {
+ res.forEach((task) => {
+ this.taskObserver.next(task);
+ });
+ },
+ (err) => {
+ console.log(err);
+ }
+ );
+ } else {
+ this.activeTasks = [];
+ }
+ }
+
+ public loadCompleted(processId: string) {
+ this.completedTasks = [];
+ if (processId) {
+ this.activitiProcess.getProcessTasks(processId, 'completed').subscribe(
+ (res: TaskDetailsModel[]) => {
+ res.forEach((task) => {
+ this.completedTaskObserver.next(task);
+ });
+ },
+ (err) => {
+ console.log(err);
+ }
+ );
+ } else {
+ this.completedTasks = [];
+ }
+ }
+
+ getUserFullName(user: any) {
+ if (user) {
+ return (user.firstName && user.firstName !== 'null'
+ ? user.firstName + ' ' : '') +
+ user.lastName;
+ }
+ return '';
+ }
+
+ public clickTask($event: any, task: TaskDetailsModel) {
+ console.log('selected task', task);
+ this.selectedTaskId = task.id;
+ this.taskdetails.loadDetails(task.id);
+ this.showDialog();
+ }
+
+ public showDialog() {
+ if (this.dialog) {
+ this.dialog.nativeElement.showModal();
+ }
+ }
+
+ public cancelDialog() {
+ this.closeDialog();
+ }
+
+ private closeDialog() {
+ if (this.dialog) {
+ this.dialog.nativeElement.close();
+ }
+ }
+
+ public taskFormCompleted() {
+ this.closeDialog();
+ this.load(this.processId);
+ this.taskFormCompletedEmitter.emit(this.processId);
+ }
+
+ public onRefreshClicked() {
+ this.load(this.processId);
+ }
+}
diff --git a/ng2-components/ng2-activiti-processlist/src/components/activiti-processlist.component.html b/ng2-components/ng2-activiti-processlist/src/components/activiti-processlist.component.html
index beedb69313..81e5da9857 100644
--- a/ng2-components/ng2-activiti-processlist/src/components/activiti-processlist.component.html
+++ b/ng2-components/ng2-activiti-processlist/src/components/activiti-processlist.component.html
@@ -1,6 +1,12 @@
-My Activiti Processes
-
-{{ 'PROCESSLIST.NONE' | translate }}
-
-
+{{ 'FILTERS.MESSAGES.NONE' | translate }}
+
+
+
+ {{ 'PROCESSLIST.NONE' | translate }}
+
+
diff --git a/ng2-components/ng2-activiti-processlist/src/components/activiti-processlist.component.spec.ts b/ng2-components/ng2-activiti-processlist/src/components/activiti-processlist.component.spec.ts
index a6feba83bd..420a617bb0 100644
--- a/ng2-components/ng2-activiti-processlist/src/components/activiti-processlist.component.spec.ts
+++ b/ng2-components/ng2-activiti-processlist/src/components/activiti-processlist.component.spec.ts
@@ -18,7 +18,7 @@
import {describe, expect, it, inject, beforeEachProviders, beforeEach} from '@angular/core/testing';
import {TestComponentBuilder} from '@angular/compiler/testing';
import {AlfrescoSettingsService, AlfrescoTranslationService, AlfrescoAuthenticationService} from 'ng2-alfresco-core';
-import {ActivitiProcesslistComponent} from '../../src/components/activiti-processlist.component';
+import {ActivitiProcessInstanceListComponent} from '../../src/components/activiti-processlist.component';
import {TranslationMock} from './../assets/translation.service.mock';
import {ActivitiProcessService} from '../services/activiti-process.service';
@@ -38,7 +38,7 @@ describe('ActivitiProcesslistComponent', () => {
beforeEach(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
return tcb
- .createAsync(ActivitiProcesslistComponent)
+ .createAsync(ActivitiProcessInstanceListComponent)
.then(fixture => {
processlistComponentFixture = fixture;
element = processlistComponentFixture.nativeElement;
diff --git a/ng2-components/ng2-activiti-processlist/src/components/activiti-processlist.component.ts b/ng2-components/ng2-activiti-processlist/src/components/activiti-processlist.component.ts
index a63a7dac0b..6f22951373 100644
--- a/ng2-components/ng2-activiti-processlist/src/components/activiti-processlist.component.ts
+++ b/ng2-components/ng2-activiti-processlist/src/components/activiti-processlist.component.ts
@@ -15,17 +15,17 @@
* limitations under the License.
*/
-import {Component, OnInit } from '@angular/core';
+import {Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { AlfrescoPipeTranslate, AlfrescoTranslationService, CONTEXT_MENU_DIRECTIVES, CONTEXT_MENU_PROVIDERS } from 'ng2-alfresco-core';
-import { ALFRESCO_DATATABLE_DIRECTIVES, ObjectDataTableAdapter } from 'ng2-alfresco-datatable';
+import { ALFRESCO_DATATABLE_DIRECTIVES, ObjectDataTableAdapter, DataRowEvent } from 'ng2-alfresco-datatable';
import { ActivitiProcessService } from '../services/activiti-process.service';
-import { ProcessInstance } from '../models/process-instance';
+import { FilterModel } from '../models/filter.model';
declare let __moduleName: string;
@Component({
moduleId: __moduleName,
- selector: 'activiti-processlist',
+ selector: 'activiti-process-instance-list',
styles: [
`
:host h1 {
@@ -36,13 +36,33 @@ declare let __moduleName: string;
templateUrl: './activiti-processlist.component.html',
directives: [ ALFRESCO_DATATABLE_DIRECTIVES, CONTEXT_MENU_DIRECTIVES ],
pipes: [ AlfrescoPipeTranslate ],
- providers: [ CONTEXT_MENU_PROVIDERS ]
+ providers: [ CONTEXT_MENU_PROVIDERS, ActivitiProcessService ]
})
-export class ActivitiProcesslistComponent implements OnInit {
+export class ActivitiProcessInstanceListComponent implements OnInit {
errorMessage: string;
- processInstances: ProcessInstance[];
data: ObjectDataTableAdapter;
+ currentProcessInstanceId: string;
+
+ @Input()
+ filter: FilterModel;
+
+ @Input()
+ schemaColumn: any[] = [
+ {type: 'text', key: 'id', title: 'Id', sortable: true},
+ {type: 'text', key: 'name', title: 'Name', cssClass: 'full-width name-column', sortable: true},
+ {type: 'text', key: 'started', title: 'Started', sortable: true},
+ {type: 'text', key: 'startedBy.email', title: 'Started By', sortable: true}
+ ];
+
+ @Output()
+ rowClick: EventEmitter = new EventEmitter();
+
+ @Output()
+ onSuccess: EventEmitter = new EventEmitter();
+
+ @Output()
+ onError: EventEmitter = new EventEmitter();
constructor (private processService: ActivitiProcessService, private translate: AlfrescoTranslationService) {
if (translate !== null) {
@@ -51,27 +71,77 @@ export class ActivitiProcesslistComponent implements OnInit {
}
ngOnInit() {
- this.getProcesses();
+ this.data = new ObjectDataTableAdapter(
+ [],
+ this.schemaColumn
+ );
+ if (this.filter) {
+ this.load(this.filter);
+ }
}
- getProcesses() {
- this.processService.getProcesses()
+ load(filter: FilterModel) {
+ this.processService.getProcessInstances(filter)
.subscribe(
(processInstances) => {
- this.data = new ObjectDataTableAdapter(
- processInstances,
- [
- {type: 'text', key: 'id', title: 'Id', sortable: true},
- {type: 'text', key: 'name', title: 'Name', cssClass: 'full-width name-column', sortable: true},
- {type: 'text', key: 'started', title: 'Started', sortable: true},
- {type: 'text', key: 'startedBy.email', title: 'Started By', sortable: true}
- ]
- );
+ this.renderProcessInstances(processInstances);
+ this.onSuccess.emit(processInstances);
},
- error => this.errorMessage = error);
+ error => {
+ this.errorMessage = error;
+ this.onError.emit(error);
+ });
}
- onItemClick(processInstance: ProcessInstance, event: any) {
- console.log(processInstance, event);
+ reload() {
+ this.load(this.filter);
+ }
+
+ /**
+ * Render the process list
+ *
+ * @param processInstances
+ */
+ private renderProcessInstances(processInstances: any[]) {
+ processInstances = this.optimizeProcessNames(processInstances);
+ this.data = new ObjectDataTableAdapter(
+ processInstances,
+ this.schemaColumn
+ );
+ }
+
+ /**
+ * Check if the list is empty
+ * @returns {ObjectDataTableAdapter|boolean}
+ */
+ isListEmpty(): boolean {
+ return this.data === undefined ||
+ (this.data && this.data.getRows() && this.data.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.currentProcessInstanceId = item.value.getValue('id');
+ this.rowClick.emit(this.currentProcessInstanceId);
+ }
+
+ /**
+ * Optimize process name field
+ * @param tasks
+ * @returns {any[]}
+ */
+ private optimizeProcessNames(tasks: any[]) {
+ tasks = tasks.map(t => {
+ t.name = t.name || 'No name';
+ if (t.name.length > 50) {
+ t.name = t.name.substring(0, 50) + '...';
+ }
+ return t;
+ });
+ return tasks;
}
}
diff --git a/ng2-components/ng2-activiti-processlist/src/i18n/en.json b/ng2-components/ng2-activiti-processlist/src/i18n/en.json
index 8706fab794..a3bbf24137 100644
--- a/ng2-components/ng2-activiti-processlist/src/i18n/en.json
+++ b/ng2-components/ng2-activiti-processlist/src/i18n/en.json
@@ -1,10 +1,34 @@
{
"PROCESSLIST": {
- "NONE": "No active processes were found",
- "SUMMARY": "Found {{total}} active process instances",
- "ERROR": "An error occurred while loading the processes: {{errorMessage}}",
+ "NONE": "No process instances were found",
+ "SUMMARY": "Found {{total}} process instances",
+ "ERROR": "An error occurred while loading the processes instances: {{errorMessage}}",
"COLUMN": {
"NAME": "Name"
}
+ },
+ "FILTERS": {
+ "MESSAGES": {
+ "NONE": "No process instance filter selected."
+ }
+ },
+ "DETAILS": {
+ "LABELS": {
+ "STARTED_BY": "Started by",
+ "STARTED": "Started",
+ "COMMENTS": "Comments",
+ "TASKS_ACTIVE": "Active Tasks",
+ "TASKS_COMPLETED": "Completed Tasks"
+ },
+ "MESSAGES": {
+ "NONE": "No process details found."
+ },
+ "TASKS": {
+ "NO_ACTIVE": "No tasks are currently active",
+ "NO_COMPLETED": "No tasks have been completed yet"
+ },
+ "COMMENTS": {
+ "NONE": "No comments."
+ }
}
}
diff --git a/ng2-components/ng2-activiti-processlist/src/models/comment.model.ts b/ng2-components/ng2-activiti-processlist/src/models/comment.model.ts
new file mode 100644
index 0000000000..d275e7ca1e
--- /dev/null
+++ b/ng2-components/ng2-activiti-processlist/src/models/comment.model.ts
@@ -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.
+ */
+
+/**
+ *
+ * Comment submitted against a process
+ *
+ * @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;
+ }
+}
diff --git a/ng2-components/ng2-activiti-processlist/src/models/filter.model.ts b/ng2-components/ng2-activiti-processlist/src/models/filter.model.ts
new file mode 100644
index 0000000000..2cd0c0eb42
--- /dev/null
+++ b/ng2-components/ng2-activiti-processlist/src/models/filter.model.ts
@@ -0,0 +1,60 @@
+/*!
+ * @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 filter.
+ *
+ *
+ * @returns {FilterModel} .
+ */
+export class FilterModel {
+ id: number;
+ name: string;
+ recent: boolean = false;
+ icon: string;
+ filter: FilterParamsModel;
+ appId: number;
+
+ constructor(name: string, recent: boolean, icon: string, query: string, state: string, assignment: string, appDefinitionId?: string) {
+ this.name = name;
+ this.recent = recent;
+ this.icon = icon;
+ this.filter = new FilterParamsModel(query, state, assignment, appDefinitionId);
+ }
+}
+
+/**
+ *
+ * This object represent the parameters of a filter.
+ *
+ *
+ * @returns {FilterModel} .
+ */
+export class FilterParamsModel {
+ name: string;
+ sort: string;
+ state: string;
+ appDefinitionId: string;
+
+ constructor(query: string, sort: string, state: string, appDefinitionId?: string) {
+ this.name = query;
+ this.sort = sort;
+ this.state = state;
+ this.appDefinitionId = appDefinitionId;
+ }
+}
diff --git a/ng2-components/ng2-activiti-processlist/src/models/task-details.model.ts b/ng2-components/ng2-activiti-processlist/src/models/task-details.model.ts
new file mode 100644
index 0000000000..5ab0361aaa
--- /dev/null
+++ b/ng2-components/ng2-activiti-processlist/src/models/task-details.model.ts
@@ -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;
+ }
+}
diff --git a/ng2-components/ng2-activiti-processlist/src/models/user.model.ts b/ng2-components/ng2-activiti-processlist/src/models/user.model.ts
new file mode 100644
index 0000000000..6d21ad4e0b
--- /dev/null
+++ b/ng2-components/ng2-activiti-processlist/src/models/user.model.ts
@@ -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;
+ }
+}
diff --git a/ng2-components/ng2-activiti-processlist/src/services/activiti-process.service.ts b/ng2-components/ng2-activiti-processlist/src/services/activiti-process.service.ts
index ee876a298d..751fb04252 100644
--- a/ng2-components/ng2-activiti-processlist/src/services/activiti-process.service.ts
+++ b/ng2-components/ng2-activiti-processlist/src/services/activiti-process.service.ts
@@ -17,6 +17,9 @@
import {AlfrescoAuthenticationService} from 'ng2-alfresco-core';
import {ProcessInstance} from '../models/process-instance';
+import {FilterModel} from '../models/filter.model';
+import {User} from '../models/user.model';
+import {Comment} from '../models/comment.model';
import {Injectable} from '@angular/core';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';
@@ -28,6 +31,16 @@ export class ActivitiProcessService {
constructor(public authService: AlfrescoAuthenticationService) {
}
+ /**
+ * Retrive all the Deployed app
+ * @returns {Observable}
+ */
+ getDeployedApplications(name: string): Observable {
+ return Observable.fromPromise(this.authService.getAlfrescoApi().activiti.appsApi.getAppDefinitions())
+ .map((response: any) => response.data.find(p => p.name === name))
+ .do(data => console.log('Application: ' + JSON.stringify(data)));
+ }
+
getProcesses(): Observable {
let request = {'page': 0, 'sort': 'created-desc', 'state': 'all'};
@@ -36,6 +49,99 @@ export class ActivitiProcessService {
.catch(this.handleError);
}
+ getProcessInstances(filter: FilterModel): Observable {
+ return Observable.fromPromise(this.authService.getAlfrescoApi().activiti.processApi.getProcessInstances(filter))
+ .map(this.extractData)
+ .catch(this.handleError);
+ }
+
+ getProcessFilters(appId: string): Observable {
+ let filterOpts = appId ? {
+ appId: appId
+ } : {};
+ return Observable.fromPromise(this.authService.getAlfrescoApi().activiti.userFiltersApi.getUserProcessInstanceFilters(filterOpts))
+ .map(this.extractData)
+ .catch(this.handleError);
+ }
+
+ getProcess(id: string): Observable {
+ return Observable.fromPromise(this.authService.getAlfrescoApi().activiti.processApi.getProcessInstance(id))
+ .catch(this.handleError);
+ }
+
+ getProcessTasks(id: string, state: string): Observable {
+ let taskOpts = state ? {
+ processInstanceId: id,
+ state: state
+ } : {
+ processInstanceId: id
+ };
+ return Observable.fromPromise(this.authService.getAlfrescoApi().activiti.taskApi.listTasks(taskOpts))
+ .map(this.extractData)
+ .map(tasks => tasks.map((task: any) => {
+ task.created = new Date(task.created);
+ return task;
+ }))
+ .catch(this.handleError);
+ }
+
+ /**
+ * Retrive all the process instance's comments
+ * @param id - process instance ID
+ * @returns {}
+ */
+ getProcessInstanceComments(id: string): Observable {
+ return Observable.fromPromise(this.authService.getAlfrescoApi().activiti.commentsApi.getProcessInstanceComments(id))
+ .map(res => res)
+ .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);
+ }
+
+ /**
+ * Add a comment to a process instance
+ * @param id - process instance Id
+ * @param message - content of the comment
+ * @returns {Comment}
+ */
+ addProcessInstanceComment(id: string, message: string): Observable {
+ return Observable.fromPromise(
+ this.authService.getAlfrescoApi().activiti.commentsApi.addProcessInstanceComment({message: message}, id)
+ )
+ .map(res => res)
+ .map((response: Comment) => {
+ return new Comment(response.id, response.message, response.created, response.createdBy);
+ }).catch(this.handleError);
+
+ }
+
+ getProcessDefinitions(appId: string) {
+ let opts = appId ? {
+ latest: true,
+ appId: appId
+ } : {
+ latest: true
+ };
+ return Observable.fromPromise(
+ this.authService.getAlfrescoApi().activiti.processApi.getProcessDefinitions(opts)
+ )
+ .map(this.extractData)
+ .catch(this.handleError);
+ }
+
+ cancelProcess(processInstanceId: string) {
+ return Observable.fromPromise(
+ this.authService.getAlfrescoApi().activiti.processApi.deleteProcessInstance(processInstanceId)
+ )
+ .catch(this.handleError);
+ }
+
private extractData(res: any) {
return res.data || {};
}