diff --git a/.travis.yml b/.travis.yml index e7266534d6..871656636c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,8 +28,8 @@ env: - MODULE=ng2-alfresco-viewer - MODULE=ng2-alfresco-webscript - MODULE=ng2-activiti-form - - MODULE=ng2-activiti-processlist - MODULE=ng2-activiti-tasklist + - MODULE=ng2-activiti-processlist before_script: - if ([ "$MODULE" != "ng2-alfresco-core" ]); then @@ -38,9 +38,12 @@ before_script: - if ([ "$MODULE" == "ng2-alfresco-documentlist" ] || [ "$MODULE" == "ng2-alfresco-webscript" ] || [ "$MODULE" == "ng2-activiti-processlist" ] || [ "$MODULE" == "ng2-activiti-tasklist" ]); then (cd ng2-components/ng2-alfresco-datatable; npm link ng2-alfresco-core; npm install; npm link); fi - - if ([ "$MODULE" == "ng2-activiti-tasklist" ]); then + - if ([ "$MODULE" == "ng2-activiti-tasklist" ] || [ "$MODULE" == "ng2-activiti-processlist" ]); then (cd ng2-components/ng2-activiti-form; npm link ng2-alfresco-core; npm install; npm link); fi + - if ([ "$MODULE" == "ng2-activiti-processlist" ]); then + (cd ng2-components/ng2-activiti-tasklist; npm link ng2-alfresco-core; npm link ng2-alfresco-datatable; npm link ng2-activiti-form; npm install; npm link); + fi - cd ng2-components/$MODULE; - if ([ "$MODULE" != "ng2-alfresco-core" ]); then npm link ng2-alfresco-core; @@ -51,6 +54,9 @@ before_script: - if ([ "$MODULE" == "ng2-activiti-tasklist" ]); then npm link ng2-activiti-form; fi + - if ([ "$MODULE" == "ng2-activiti-processlist" ]); then + npm link ng2-activiti-tasklist; + fi - npm install; - npm run travis - ls -ltrh ./node_modules/ diff --git a/README.md b/README.md index ea86bb2d88..29820028e0 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,8 @@ The following is a list of some of the components that you can use when building - [Core library](ng2-components/ng2-alfresco-core/README.md) - [DataTable](ng2-components/ng2-alfresco-datatable/README.md) - [DocumentList](ng2-components/ng2-alfresco-documentlist/README.md) +- Activiti [ProcessList](ng2-components/ng2-activiti-processlist/README.md) and [TaskList](ng2-components/ng2-activiti-tasklist/README.md) +- [Activiti Form](ng2-components/ng2-activiti-form/README.md) - [Viewer](ng2-components/ng2-alfresco-viewer/README.md) - [Login](ng2-components/ng2-alfresco-login/README.md) - [Upload](ng2-components/ng2-alfresco-upload/README.md) diff --git a/appveyor.yml b/appveyor.yml index 58802c0ba7..6487d8bafb 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -27,6 +27,8 @@ install: - IF %COMPONENT_NAME% NEQ ng2-alfresco-core (cd ng2-components/ng2-alfresco-core && npm install && npm link && cd ../../) - IF %COMPONENT_NAME% EQU ng2-alfresco-documentlist (cd ng2-components/ng2-alfresco-datatable && npm link ng2-alfresco-core && npm install && npm link && cd ../../) - IF %COMPONENT_NAME% EQU ng2-activiti-processlist (cd ng2-components/ng2-alfresco-datatable && npm link ng2-alfresco-core && npm install && npm link && cd ../../) + - IF %COMPONENT_NAME% EQU ng2-activiti-processlist (cd ng2-components/ng2-activiti-form && npm link ng2-alfresco-core && npm install && npm link && cd ../../) + - IF %COMPONENT_NAME% EQU ng2-activiti-processlist (cd ng2-components/ng2-activiti-tasklist && npm link ng2-alfresco-core && npm link ng2-alfresco-datatable && npm link ng2-activiti-form && npm install && npm link && cd ../../) - IF %COMPONENT_NAME% EQU ng2-activiti-tasklist (cd ng2-components/ng2-alfresco-datatable && npm link ng2-alfresco-core && npm install && npm link && cd ../../) - IF %COMPONENT_NAME% EQU ng2-activiti-tasklist (cd ng2-components/ng2-activiti-form && npm link ng2-alfresco-core && npm install && npm link && cd ../../) - IF %COMPONENT_NAME% EQU ng2-alfresco-webscript (cd ng2-components/ng2-alfresco-datatable && npm link ng2-alfresco-core && npm install && npm link && cd ../../) @@ -34,6 +36,7 @@ install: - IF %COMPONENT_NAME% NEQ ng2-alfresco-core (npm link ng2-alfresco-core) - IF %COMPONENT_NAME% EQU ng2-alfresco-documentlist (npm link ng2-alfresco-datatable) - IF %COMPONENT_NAME% EQU ng2-activiti-processlist (npm link ng2-alfresco-datatable) + - IF %COMPONENT_NAME% EQU ng2-activiti-processlist (npm link ng2-activiti-tasklist) - IF %COMPONENT_NAME% EQU ng2-activiti-tasklist (npm link ng2-alfresco-datatable && npm link ng2-activiti-form) - IF %COMPONENT_NAME% EQU ng2-alfresco-webscript (npm link ng2-alfresco-datatable) - npm install diff --git a/demo-shell-ng2/app/app.routes.ts b/demo-shell-ng2/app/app.routes.ts index c2bea7144d..feaa94f7c0 100644 --- a/demo-shell-ng2/app/app.routes.ts +++ b/demo-shell-ng2/app/app.routes.ts @@ -28,6 +28,7 @@ import { AboutComponent, FormViewer } from './components/index'; +import { FormNodeViewer } from './components/activiti/form-node-viewer.component'; export const routes: RouterConfig = [ { path: 'home', component: FilesComponent }, @@ -39,6 +40,7 @@ export const routes: RouterConfig = [ { path: 'search', component: SearchComponent }, { path: 'activiti', component: ActivitiDemoComponent }, { path: 'activiti/tasks/:id', component: FormViewer }, + { path: 'activiti/tasksnode/:id', component: FormNodeViewer }, { path: 'webscript', component: WebscriptComponent }, { path: 'about', component: AboutComponent } ]; 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..19de46d0f9 100644 --- a/demo-shell-ng2/app/components/activiti/activiti-demo.component.html +++ b/demo-shell-ng2/app/components/activiti/activiti-demo.component.html @@ -13,16 +13,17 @@
Task Filters - +
Task List - +
Task Details - +
@@ -33,12 +34,17 @@
Process Filters + +
Process List +
Process Details +
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..66b05625f9 100644 --- a/demo-shell-ng2/app/components/activiti/activiti-demo.component.ts +++ b/demo-shell-ng2/app/components/activiti/activiti-demo.component.ts @@ -15,8 +15,9 @@ * limitations under the License. */ -import { Component, AfterViewChecked, ViewChild } from '@angular/core'; +import { Component, AfterViewChecked, ViewChild, Input } 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,23 @@ 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; + + @Input() + appId: string; setChoice($event) { this.currentChoice = $event.target.value; @@ -58,23 +71,50 @@ 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(); + } + + onFormCompleted(form) { + this.activititasklist.load(this.taskFilter); + this.currentTaskId = null; + this.activitidetails.loadDetails(this.currentTaskId); + } + ngAfterViewChecked() { // workaround for MDL issues with dynamic components if (componentHandler) { diff --git a/demo-shell-ng2/app/components/activiti/form-node-viewer.component.css b/demo-shell-ng2/app/components/activiti/form-node-viewer.component.css new file mode 100644 index 0000000000..0e5cdfdd65 --- /dev/null +++ b/demo-shell-ng2/app/components/activiti/form-node-viewer.component.css @@ -0,0 +1,3 @@ +.activiti-form-viewer { + margin: 10px; +} diff --git a/demo-shell-ng2/app/components/activiti/form-node-viewer.component.html b/demo-shell-ng2/app/components/activiti/form-node-viewer.component.html new file mode 100644 index 0000000000..e2f166282b --- /dev/null +++ b/demo-shell-ng2/app/components/activiti/form-node-viewer.component.html @@ -0,0 +1,6 @@ +
+ + +
diff --git a/demo-shell-ng2/app/components/activiti/form-node-viewer.component.ts b/demo-shell-ng2/app/components/activiti/form-node-viewer.component.ts new file mode 100644 index 0000000000..1b5f994660 --- /dev/null +++ b/demo-shell-ng2/app/components/activiti/form-node-viewer.component.ts @@ -0,0 +1,62 @@ +/*! + * @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, OnDestroy, AfterViewChecked } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { ActivitiForm, FormService, EcmModelService, NodeService } from 'ng2-activiti-form'; +import { Subscription } from 'rxjs/Rx'; + +declare let __moduleName: string; +declare var componentHandler; + +@Component({ + moduleId: __moduleName, + selector: 'form-node-viewer', + templateUrl: './form-node-viewer.component.html', + styleUrls: ['./form-node-viewer.component.css'], + directives: [ActivitiForm], + providers: [FormService, EcmModelService, NodeService] +}) +export class FormNodeViewer implements OnInit, OnDestroy, AfterViewChecked { + + nodeId: string; + + private sub: Subscription; + + constructor(private formService: FormService, + private route: ActivatedRoute, + private router: Router) { + } + + ngOnInit() { + this.sub = this.route.params.subscribe(params => { + this.nodeId = params['id']; + }); + } + + ngOnDestroy() { + this.sub.unsubscribe(); + } + + ngAfterViewChecked() { + // workaround for MDL issues with dynamic components + if (componentHandler) { + componentHandler.upgradeAllRegistered(); + } + } + +} diff --git a/demo-shell-ng2/app/components/activiti/form-viewer.component.html b/demo-shell-ng2/app/components/activiti/form-viewer.component.html index df826d2116..2a5c98ccdb 100644 --- a/demo-shell-ng2/app/components/activiti/form-viewer.component.html +++ b/demo-shell-ng2/app/components/activiti/form-viewer.component.html @@ -1,3 +1,11 @@
+ + + + + + + +
diff --git a/demo-shell-ng2/app/components/activiti/form-viewer.component.ts b/demo-shell-ng2/app/components/activiti/form-viewer.component.ts index fd06f7254e..2acfc75777 100644 --- a/demo-shell-ng2/app/components/activiti/form-viewer.component.ts +++ b/demo-shell-ng2/app/components/activiti/form-viewer.component.ts @@ -17,7 +17,7 @@ import { Component, OnInit, OnDestroy, AfterViewChecked } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; -import { ActivitiForm, FormService } from 'ng2-activiti-form'; +import { ActivitiForm, FormService, EcmModelService, NodeService } from 'ng2-activiti-form'; import { Subscription } from 'rxjs/Rx'; declare let __moduleName: string; @@ -29,7 +29,7 @@ declare var componentHandler; templateUrl: './form-viewer.component.html', styleUrls: ['./form-viewer.component.css'], directives: [ActivitiForm], - providers: [FormService] + providers: [FormService, EcmModelService, NodeService] }) export class FormViewer implements OnInit, OnDestroy, AfterViewChecked { diff --git a/demo-shell-ng2/app/components/files/files.component.html b/demo-shell-ng2/app/components/files/files.component.html index 3cf95cd013..fabeb89aef 100644 --- a/demo-shell-ng2/app/components/files/files.component.html +++ b/demo-shell-ng2/app/components/files/files.component.html @@ -3,6 +3,7 @@ [showUploadDialog]="true" [currentFolderPath]="currentPath" [uploaddirectory]="" + [versioning] = "versioning" (onSuccess)="documentList.reload()"> @@ -147,6 +148,13 @@

+

+ +

+
Upload

@@ -160,6 +168,7 @@ [currentFolderPath]="currentPath" [multipleFiles]="multipleFileUpload" [uploadFolders]="folderUpload" + [versioning] = "versioning" (onSuccess)="documentList.reload()">
@@ -171,6 +180,7 @@ acceptedFilesType="{{acceptedFilesType}}" [multipleFiles]="multipleFileUpload" [uploadFolders]="folderUpload" + [versioning] = "versioning" (onSuccess)="documentList.reload()">
diff --git a/demo-shell-ng2/app/components/files/files.component.ts b/demo-shell-ng2/app/components/files/files.component.ts index 371536eb78..c6d8e3fad9 100644 --- a/demo-shell-ng2/app/components/files/files.component.ts +++ b/demo-shell-ng2/app/components/files/files.component.ts @@ -63,6 +63,7 @@ export class FilesComponent implements OnInit { multipleFileUpload: boolean = false; folderUpload: boolean = false; acceptedFilesTypeShow: boolean = false; + versioning: boolean = false; acceptedFilesType: string = '.jpg,.pdf,.js'; @@ -119,6 +120,11 @@ export class FilesComponent implements OnInit { return this.acceptedFilesTypeShow; } + toggleVersioning() { + this.versioning = !this.versioning; + return this.versioning; + } + ngOnInit() { this.formService.getProcessDefinitions().subscribe( defs => this.setupBpmActions(defs || []), @@ -127,7 +133,7 @@ export class FilesComponent implements OnInit { } viewActivitiForm(event?: any) { - this.router.navigate(['/activiti/tasks', '1']); + this.router.navigate(['/activiti/tasksnode', event.value.entry.id]); } private setupBpmActions(actions: any[]) { diff --git a/demo-shell-ng2/app/components/search/search-bar.component.ts b/demo-shell-ng2/app/components/search/search-bar.component.ts index a55f630e1c..318bfb7877 100644 --- a/demo-shell-ng2/app/components/search/search-bar.component.ts +++ b/demo-shell-ng2/app/components/search/search-bar.component.ts @@ -16,13 +16,9 @@ */ import { Component, EventEmitter, Output } from '@angular/core'; -import { Router } from '@angular/router'; import { ALFRESCO_SEARCH_DIRECTIVES } from 'ng2-alfresco-search'; import { VIEWERCOMPONENT } from 'ng2-alfresco-viewer'; -import { - AlfrescoAuthenticationService, - AlfrescoContentService -} from 'ng2-alfresco-core'; +import { AlfrescoAuthenticationService } from 'ng2-alfresco-core'; declare let __moduleName: string; @@ -30,52 +26,36 @@ declare let __moduleName: string; moduleId: __moduleName, selector: 'search-bar', templateUrl: './search-bar.component.html', - styles: [` - `], - directives: [ ALFRESCO_SEARCH_DIRECTIVES, VIEWERCOMPONENT ] + directives: [ALFRESCO_SEARCH_DIRECTIVES, VIEWERCOMPONENT] }) export class SearchBarComponent { - urlFile: string; - fileName: string; - mimeType: string; + fileNodeId: string; fileShowed: boolean = false; + searchTerm: string = ''; @Output() expand = new EventEmitter(); - constructor( - public router: Router, - public auth: AlfrescoAuthenticationService, - public contentService: AlfrescoContentService - - ) { + constructor(public auth: AlfrescoAuthenticationService) { } isLoggedIn(): boolean { return this.auth.isLoggedIn(); } - /** - * Called when a new search term is submitted - * - * @param params Parameters relating to the search - */ - searchTermChange(params) { - this.router.navigate(['Search', { - q: params.value - }]); - } - onFileClicked(event) { if (event.value.entry.isFile) { - this.fileName = event.value.entry.name; - this.mimeType = event.value.entry.content.mimeType; - this.urlFile = this.contentService.getContentUrl(event.value); + this.fileNodeId = event.value.entry.id; this.fileShowed = true; } } + searchTermChange(event) { + console.log('Search term changed', event); + this.searchTerm = event.value; + } + onExpandToggle(event) { this.expand.emit(event); } diff --git a/demo-shell-ng2/app/components/search/search.component.html b/demo-shell-ng2/app/components/search/search.component.html index 93568e6b8d..d67a727047 100644 --- a/demo-shell-ng2/app/components/search/search.component.html +++ b/demo-shell-ng2/app/components/search/search.component.html @@ -3,6 +3,6 @@
- +
diff --git a/demo-shell-ng2/app/components/search/search.component.ts b/demo-shell-ng2/app/components/search/search.component.ts index bf836b7783..2d14f09e4b 100644 --- a/demo-shell-ng2/app/components/search/search.component.ts +++ b/demo-shell-ng2/app/components/search/search.component.ts @@ -52,10 +52,7 @@ declare let __moduleName: string; }) export class SearchComponent { - previewContentUrl: string; - previewName: string; - previewMimeType: string; - previewActive: boolean = false; + fileShowed: boolean = false; fileNodeId: string; constructor(public contentService: AlfrescoContentService) { @@ -64,7 +61,7 @@ export class SearchComponent { onFileClicked(event) { if (event.value.entry.isFile) { this.fileNodeId = event.value.entry.id; - this.previewActive = true; + this.fileShowed = true; } } } diff --git a/demo-shell-ng2/app/main.ts b/demo-shell-ng2/app/main.ts index 1ae1a4152d..d7ae6ebc81 100644 --- a/demo-shell-ng2/app/main.ts +++ b/demo-shell-ng2/app/main.ts @@ -19,9 +19,9 @@ import { bootstrap } from '@angular/platform-browser-dynamic'; import { HTTP_PROVIDERS } from '@angular/http'; import { ALFRESCO_SEARCH_PROVIDERS } from 'ng2-alfresco-search'; import { ALFRESCO_CORE_PROVIDERS } from 'ng2-alfresco-core'; +import { ATIVITI_FORM_PROVIDERS } from 'ng2-activiti-form'; import { UploadService } from 'ng2-alfresco-upload'; import { AppComponent } from './app.component'; - import { appRouterProviders } from './app.routes'; bootstrap(AppComponent, [ @@ -29,5 +29,6 @@ bootstrap(AppComponent, [ HTTP_PROVIDERS, ALFRESCO_CORE_PROVIDERS, ALFRESCO_SEARCH_PROVIDERS, - UploadService + UploadService, + ATIVITI_FORM_PROVIDERS ]).catch(err => console.error(err)); diff --git a/demo-shell-ng2/i18n/en.json b/demo-shell-ng2/i18n/en.json index 6f006a8158..1a35a1e670 100644 --- a/demo-shell-ng2/i18n/en.json +++ b/demo-shell-ng2/i18n/en.json @@ -4,7 +4,7 @@ "DOCUMENT_LIST": { "COLUMNS": { "DISPLAY_NAME": "Display name", - "CREATED_BY": "mario", + "CREATED_BY": "Created by", "CREATED_ON": "Created on" }, "ACTIONS": { diff --git a/demo-shell-ng2/index.html b/demo-shell-ng2/index.html index 3fbdbbf291..bb2bb3260f 100644 --- a/demo-shell-ng2/index.html +++ b/demo-shell-ng2/index.html @@ -16,6 +16,10 @@ + + + + diff --git a/demo-shell-ng2/package.json b/demo-shell-ng2/package.json index 00c0a6bd02..b211986a22 100644 --- a/demo-shell-ng2/package.json +++ b/demo-shell-ng2/package.json @@ -1,7 +1,7 @@ { "name": "Alfresco-Angular2-Demo", "description": "Demo shell for Alfresco Angular2 components", - "version": "0.2.0", + "version": "0.3.0", "author": "Alfresco Software, Ltd.", "scripts": { "postinstall": "typings install", @@ -73,18 +73,20 @@ "material-design-icons": "2.2.3", "material-design-lite": "1.1.3", "ng2-translate": "2.2.0", - "pdfjs-dist": "1.5.258", + "pdfjs-dist": "1.5.404", "flag-icon-css": "2.3.0", - "ng2-alfresco-core": "0.2.0", - "ng2-alfresco-datatable": "0.2.0", - "ng2-alfresco-documentlist": "0.2.0", - "ng2-alfresco-login": "0.2.0", - "ng2-alfresco-search": "0.2.0", - "ng2-alfresco-upload": "0.2.0", - "ng2-alfresco-viewer": "0.2.0", - "ng2-activiti-form": "0.2.0", - "ng2-activiti-tasklist": "0.2.0", - "ng2-alfresco-webscript": "0.2.0" + "intl": "1.2.4", + "ng2-alfresco-core": "0.3.0", + "ng2-alfresco-datatable": "0.3.0", + "ng2-alfresco-documentlist": "0.3.0", + "ng2-alfresco-login": "0.3.0", + "ng2-alfresco-search": "0.3.0", + "ng2-alfresco-upload": "0.3.0", + "ng2-alfresco-viewer": "0.3.0", + "ng2-activiti-form": "0.3.0", + "ng2-activiti-tasklist": "0.3.0", + "ng2-activiti-processlist": "0.3.0", + "ng2-alfresco-webscript": "0.3.0" }, "devDependencies": { "concurrently": "2.0.0", diff --git a/demo-shell-ng2/systemjs.config.js b/demo-shell-ng2/systemjs.config.js index 726992d104..2b0b1daf97 100644 --- a/demo-shell-ng2/systemjs.config.js +++ b/demo-shell-ng2/systemjs.config.js @@ -22,6 +22,7 @@ 'ng2-alfresco-webscript': 'node_modules/ng2-alfresco-webscript/dist', 'ng2-activiti-tasklist': 'node_modules/ng2-activiti-tasklist/dist', 'alfresco-js-api': 'node_modules/alfresco-js-api/dist' + 'ng2-activiti-processlist': 'node_modules/ng2-activiti-processlist/dist' }; // packages tells the System loader how to load when no filename and/or no extension var packages = { @@ -39,6 +40,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'}, 'alfresco-js-api': { main: 'alfresco-js-api.js', defaultExtension: 'js'} diff --git a/ng2-components/ng2-activiti-form/README.md b/ng2-components/ng2-activiti-form/README.md index cd66c1e8f6..e0ddb5af56 100644 --- a/ng2-components/ng2-activiti-form/README.md +++ b/ng2-components/ng2-activiti-form/README.md @@ -78,6 +78,38 @@ Only form definition will be fetched ``` +### Display form definition by ECM nodeId, in this case the metadata of the node are showed in an activiti Form. If there are no form +definied in activiti for the type of the node, a new form will be automaticaly created in activiti. + +```html + + +``` + +### Display form definition by form name, and store the form field as metadata. The param nameNode is optional. + +```html + + +``` + +### Display form definition by ECM nodeId, in this case the metadata of the node are showed in an activiti Form, and store the form field + as metadata. The param nameNode is optional. + +```html + + +``` + ## Configuration ### Properties @@ -95,7 +127,14 @@ The recommended set of properties can be found in the following table: | showSaveButton | boolean | true | Toggle rendering of the `Save` outcome button. | | readOnly | boolean | false | Toggle readonly state of the form. Enforces all form widgets render readonly if enabled. | | showRefreshButton | boolean | true | Toggle rendering of the `Refresh` button. | +| saveMetadata | boolean | false | Store the value of the form as metadata. | +| path | string | | Path of the folder where to store the metadata. | +| nameNode (optional) | string | true | Name to assign to the new node where the metadata are stored. | + + * {path} string - path of the folder where the to store the metadata + * + * {nameNode} string (optional) - name of the node stored, if not defined the node will be sotred with an uuid as name #### Advanced properties The following properties are for complex customisation purposes: @@ -120,7 +159,7 @@ All `form*` events receive an instance of the `FormModel` as event argument for ```html + (formSaved)="onFormSaved($event)"> ``` diff --git a/ng2-components/ng2-activiti-form/index.ts b/ng2-components/ng2-activiti-form/index.ts index f57a867f26..093ae1f90c 100644 --- a/ng2-components/ng2-activiti-form/index.ts +++ b/ng2-components/ng2-activiti-form/index.ts @@ -15,6 +15,19 @@ * limitations under the License. */ +import { FormService } from './src/services/form.service'; +import { EcmModelService } from './src/services/ecm-model.service'; +import { NodeService } from './src/services/node.service'; + export * from './src/components/activiti-form.component'; export * from './src/services/form.service'; export * from './src/components/widgets/index'; +export * from './src/services/ecm-model.service'; +export * from './src/services/node.service'; + + +export const ATIVITI_FORM_PROVIDERS: [any] = [ + FormService, + EcmModelService, + NodeService +]; diff --git a/ng2-components/ng2-activiti-form/package.json b/ng2-components/ng2-activiti-form/package.json index d656f1422c..d0594e8c52 100644 --- a/ng2-components/ng2-activiti-form/package.json +++ b/ng2-components/ng2-activiti-form/package.json @@ -1,7 +1,7 @@ { "name": "ng2-activiti-form", "description": "Alfresco Activiti Form Component for Angular 2", - "version": "0.2.0", + "version": "0.3.0", "author": "Alfresco Software, Ltd.", "scripts": { "postinstall": "typings install", @@ -65,7 +65,7 @@ "rxjs": "5.0.0-beta.6", "zone.js": "0.6.12", "ng2-translate": "2.2.2", - "ng2-alfresco-core": "0.2.0" + "ng2-alfresco-core": "0.3.0" }, "peerDependencies": { "material-design-icons": "^2.2.3", diff --git a/ng2-components/ng2-activiti-form/src/components/activiti-form.component.html b/ng2-components/ng2-activiti-form/src/components/activiti-form.component.html index b0a1858552..7bb2551e8a 100644 --- a/ng2-components/ng2-activiti-form/src/components/activiti-form.component.html +++ b/ng2-components/ng2-activiti-form/src/components/activiti-form.component.html @@ -1,6 +1,6 @@
-

Please select a Visit

+

Please select a Task

diff --git a/ng2-components/ng2-activiti-form/src/components/activiti-form.component.spec.ts b/ng2-components/ng2-activiti-form/src/components/activiti-form.component.spec.ts index 4571c1a6a4..133206d5b6 100644 --- a/ng2-components/ng2-activiti-form/src/components/activiti-form.component.spec.ts +++ b/ng2-components/ng2-activiti-form/src/components/activiti-form.component.spec.ts @@ -32,7 +32,7 @@ describe('ActivitiForm', () => { let visibilityService: WidgetVisibilityService; beforeEach(() => { - componentHandler = jasmine.createSpyObj('componentHandler', [ + componentHandler = jasmine.createSpyObj('componentHandler', [ 'upgradeAllRegistered' ]); visibilityService = jasmine.createSpyObj('WidgetVisibilityService', [ @@ -40,8 +40,8 @@ describe('ActivitiForm', () => { ]); window['componentHandler'] = componentHandler; - formService = new FormService(null); - formComponent = new ActivitiForm(formService, visibilityService); + formService = new FormService(null, null); + formComponent = new ActivitiForm(formService, visibilityService, null, null, null); }); it('should upgrade MDL content on view checked', () => { diff --git a/ng2-components/ng2-activiti-form/src/components/activiti-form.component.ts b/ng2-components/ng2-activiti-form/src/components/activiti-form.component.ts index 69865b8a1c..d763eb0128 100644 --- a/ng2-components/ng2-activiti-form/src/components/activiti-form.component.ts +++ b/ng2-components/ng2-activiti-form/src/components/activiti-form.component.ts @@ -23,9 +23,10 @@ import { Output, EventEmitter } from '@angular/core'; -import { MATERIAL_DESIGN_DIRECTIVES } from 'ng2-alfresco-core'; - +import { MATERIAL_DESIGN_DIRECTIVES, AlfrescoAuthenticationService } from 'ng2-alfresco-core'; +import { EcmModelService } from './../services/ecm-model.service'; import { FormService } from './../services/form.service'; +import { NodeService } from './../services/node.service'; import { FormModel, FormOutcomeModel, FormValues, FormFieldModel, FormOutcomeEvent } from './widgets/core/index'; import { TabsWidget } from './widgets/tabs/tabs.widget'; @@ -38,19 +39,23 @@ import { WidgetVisibilityService } from './../services/widget-visibility.servic /** * @Input - * ActivitiForm can show 3 forms searching by 3 type of params: + * ActivitiForm can show 4 types of forms searching by 4 type of params: * 1) Form attached to a task passing the {taskId}. + * * 2) Form that are only defined with the {formId} (in this case you receive only the form definition and the form will not be * attached to any process, useful in case you want to use ActivitiForm as form designer), in this case you can pass also other 2 * parameters: * - {saveOption} as parameter to tell what is the function to call on the save action. * - {data} to fill the form field with some data, the id of the form must to match the name of the field of the provided data object. + * * 3) Form that are only defined with the {formName} (in this case you receive only the form definition and the form will not be * attached to any process, useful in case you want to use ActivitiForm as form designer), * in this case you can pass also other 2 parameters: * - {saveOption} as parameter to tell what is the function to call on the save action. * - {data} to fill the form field with some data, the id of the form must to match the name of the field of the provided data object. * + * 4) Form that show the metadata of a {nodeId} + * * {showTitle} boolean - to hide the title of the form pass false, default true; * * {showRefreshButton} boolean - to hide the refresh button of the form pass false, default true; @@ -59,6 +64,12 @@ import { WidgetVisibilityService } from './../services/widget-visibility.servic * * {showSaveButton} boolean - to hide the save button of the form pass false, default true; * + * {saveMetadata} boolean - store the value of the form as metadata, default false; + * + * {path} string - path of the folder where to store the metadata; + * + * {nameNode} string (optional) - Name to assign to the new node where the metadata are stored; + * * @Output * {formLoaded} EventEmitter - This event is fired when the form is loaded, it pass all the value in the form. * {formSaved} EventEmitter - This event is fired when the form is saved, it pass all the value in the form. @@ -72,7 +83,7 @@ import { WidgetVisibilityService } from './../services/widget-visibility.servic templateUrl: './activiti-form.component.html', styleUrls: ['./activiti-form.component.css'], directives: [MATERIAL_DESIGN_DIRECTIVES, ContainerWidget, TabsWidget], - providers: [FormService, WidgetVisibilityService] + providers: [EcmModelService, FormService, WidgetVisibilityService, NodeService] }) export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges { @@ -83,15 +94,27 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges { @Input() taskId: string; + @Input() + nodeId: string; + @Input() formId: string; @Input() formName: string; + @Input() + saveMetadata: boolean = false; + @Input() data: FormValues; + @Input() + path: string; + + @Input() + nameNode: string; + @Input() showTitle: boolean = true; @@ -124,7 +147,10 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges { debugMode: boolean = false; constructor(private formService: FormService, - private visibilityService: WidgetVisibilityService) { + private visibilityService: WidgetVisibilityService, + private authService: AlfrescoAuthenticationService, + private ecmModelService: EcmModelService, + private nodeService: NodeService) { } hasForm(): boolean { @@ -154,7 +180,11 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges { } ngOnInit() { - this.loadForm(); + if (this.nodeId) { + this.loadActivitiFormForEcmNode(); + } else { + this.loadForm(); + } } ngAfterViewChecked() { @@ -208,6 +238,7 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges { if (outcome.id === ActivitiForm.CUSTOM_OUTCOME_ID) { this.formSaved.emit(this.form); + this.storeFormAsMetadata(); return true; } } else { @@ -275,7 +306,7 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges { .getFormDefinitionById(formId) .subscribe( form => { - // console.log('Get Form By definition Id', form); + this.formName = form.name; this.form = this.parseForm(form); this.formLoaded.emit(this.form); }, @@ -306,7 +337,10 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges { this.formService .saveTaskForm(this.form.taskId, this.form.values) .subscribe( - () => this.formSaved.emit(this.form), + () => { + this.formSaved.emit(this.form); + this.storeFormAsMetadata(); + }, this.handleError ); } @@ -317,13 +351,16 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges { this.formService .completeTaskForm(this.form.taskId, this.form.values, outcome) .subscribe( - () => this.formCompleted.emit(this.form), + () => { + this.formCompleted.emit(this.form); + this.storeFormAsMetadata(); + }, this.handleError ); } } - handleError(err: any) { + handleError(err: any): any { console.log(err); } @@ -345,7 +382,7 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges { */ getFormDefinitionOutcomes(form: FormModel): FormOutcomeModel[] { return [ - new FormOutcomeModel(form, { id: '$custom', name: FormOutcomeModel.SAVE_ACTION, isSystem: true }) + new FormOutcomeModel(form, {id: '$custom', name: FormOutcomeModel.SAVE_ACTION, isSystem: true}) ]; } @@ -354,4 +391,41 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges { this.visibilityService.updateVisibilityForForm(field.form); } } + + private loadActivitiFormForEcmNode(): void { + this.nodeService.getNodeMetadata(this.nodeId).subscribe(data => { + this.data = data.metadata; + this.loadFormFromActiviti(data.nodeType); + }, + this.handleError); + } + + public loadFormFromActiviti(nodeType: string): any { + this.formService.searchFrom(nodeType).subscribe( + form => { + if (!form) { + this.formService.createFormFromNodeType(nodeType).subscribe(formMetadata => { + this.loadFormFromFormId(formMetadata.id); + }); + } else { + this.loadFormFromFormId(form.id); + } + }, + this.handleError + ); + } + + private loadFormFromFormId(formId: string) { + this.formId = formId; + this.loadForm(); + } + + private storeFormAsMetadata() { + if (this.saveMetadata) { + this.ecmModelService.createEcmTypeForActivitiForm(this.formName, this.form).subscribe(type => { + this.nodeService.createNodeMetadata(type.nodeType || type.entry.prefixedName, EcmModelService.MODEL_NAMESPACE, this.form.values, this.path, this.nameNode); + }, this.handleError + ); + } + } } diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.html b/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.html index bd2732ddc4..6cffc9730c 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.html +++ b/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.html @@ -43,6 +43,9 @@
+
+ +
UNKNOWN WIDGET TYPE: {{field.type}}
diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field-types.ts b/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field-types.ts index e01b261033..627bcfe5d2 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field-types.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field-types.ts @@ -23,6 +23,7 @@ export class FormFieldTypes { static RADIO_BUTTONS: string = 'radio-buttons'; static DISPLAY_VALUE: string = 'readonly'; static READONLY_TEXT: string = 'readonly-text'; + static UPLOAD: string = 'upload'; static READONLY_TYPES: string[] = [ FormFieldTypes.HYPERLINK, diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field.model.ts b/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field.model.ts index 916c8714df..22bd3822ae 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field.model.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field.model.ts @@ -129,34 +129,45 @@ export class FormFieldModel extends FormWidgetModel { } updateForm() { - if (this.type === FormFieldTypes.DROPDOWN) { - /* - This is needed due to Activiti reading dropdown values as string - but saving back as object: { id: , name: } - */ - if (this.value === 'empty' || this.value === '') { - this.form.values[this.id] = {}; - } else { + + switch (this.type) { + case FormFieldTypes.DROPDOWN: + /* + This is needed due to Activiti reading dropdown values as string + but saving back as object: { id: , name: } + */ + if (this.value === 'empty' || this.value === '') { + this.form.values[this.id] = {}; + } else { + let entry: FormFieldOption[] = this.options.filter(opt => opt.id === this.value); + if (entry.length > 0) { + this.form.values[this.id] = entry[0]; + } + } + break; + case FormFieldTypes.RADIO_BUTTONS: + /* + This is needed due to Activiti issue related to reading radio button values as value string + but saving back as object: { id: , name: } + */ let entry: FormFieldOption[] = this.options.filter(opt => opt.id === this.value); if (entry.length > 0) { this.form.values[this.id] = entry[0]; + } else if (this.options.length > 0) { + this.form.values[this.id] = this.options[0]; + } + break; + case FormFieldTypes.UPLOAD: + if (this.value && this.value.length > 0) { + this.form.values[this.id] = `${this.value[0].id}`; + } else { + this.form.values[this.id] = null; + } + break; + default: + if (!FormFieldTypes.isReadOnlyType(this.type)) { + this.form.values[this.id] = this.value; } - } - } else if (this.type === FormFieldTypes.RADIO_BUTTONS) { - /* - This is needed due to Activiti issue related to reading radio button values as value string - but saving back as object: { id: , name: } - */ - let entry: FormFieldOption[] = this.options.filter(opt => opt.id === this.value); - if (entry.length > 0) { - this.form.values[this.id] = entry[0]; - } else if (this.options.length > 0) { - this.form.values[this.id] = this.options[0]; - } - } else { - if (!FormFieldTypes.isReadOnlyType(this.type)) { - this.form.values[this.id] = this.value; - } } } } diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.html b/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.html index 3da33231b0..a6c3d50a94 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.html +++ b/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.html @@ -1,4 +1,5 @@