diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 457c2f3b76..76d5ed14b4 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,8 +1,9 @@ **Please check if the PR fulfills these requirements** -- [ ] The commit message follows our [guidelines](https://github.com/Alfresco/alfresco-ng2-components/wiki/Commit-format) -- [ ] Tests for the changes have been added (for bug fixes / features) -- [ ] Docs have been added / updated (for bug fixes / features) - +``` +[ ] The commit message follows our [guidelines](https://github.com/Alfresco/alfresco-ng2-components/wiki/Commit-format) +[ ] Tests for the changes have been added (for bug fixes / features) +[ ] Docs have been added / updated (for bug fixes / features) +```
-
-
-
+
+
+ + - + + Demo Application + +
+ + - - Demo Application - -
- - - - - - - - - - - -
-
- +
+ +
diff --git a/demo-shell-ng2/app/app.component.ts b/demo-shell-ng2/app/app.component.ts index e4858bc172..766bbdd6fd 100644 --- a/demo-shell-ng2/app/app.component.ts +++ b/demo-shell-ng2/app/app.component.ts @@ -21,15 +21,16 @@ import { Router } from '@angular/router'; import { AlfrescoTranslationService, AlfrescoAuthenticationService, - AlfrescoSettingsService + AlfrescoSettingsService, + StorageService } from 'ng2-alfresco-core'; declare var document: any; @Component({ selector: 'alfresco-app', - templateUrl: 'app/app.component.html', - styleUrls: ['app/app.component.css'] + templateUrl: './app.component.html', + styleUrls: ['./app.component.css'] }) export class AppComponent { searchTerm: string = ''; @@ -40,14 +41,20 @@ export class AppComponent { constructor(public auth: AlfrescoAuthenticationService, public router: Router, public alfrescoSettingsService: AlfrescoSettingsService, - private translate: AlfrescoTranslationService) { + private translate: AlfrescoTranslationService, + private storage: StorageService) { this.setEcmHost(); this.setBpmHost(); this.setProvider(); if (translate) { - translate.addTranslationFolder('custom', 'custom-translation/'); - translate.addTranslationFolder('ng2-alfresco-login', 'custom-translation/alfresco-login'); + if (process.env.ENV === 'production') { + translate.addTranslationFolder('custom', 'i18n/custom-translation'); + translate.addTranslationFolder('ng2-alfresco-login', 'i18n/custom-translation/alfresco-login'); + } else { + translate.addTranslationFolder('custom', 'custom-translation'); + translate.addTranslationFolder('ng2-alfresco-login', 'custom-translation/alfresco-login'); + } } } @@ -63,7 +70,7 @@ export class AppComponent { } isLoginPage(): boolean { - return location.pathname === '/login' || location.pathname === '/' || location.pathname === '/settings'; + return location.pathname === '/login' || location.pathname === '/settings'; } onLogout(event) { @@ -71,18 +78,24 @@ export class AppComponent { this.auth.logout() .subscribe( () => { - this.router.navigate(['/login']); + this.navigateToLogin(); }, - ($event: any) => { - if ($event && $event.response && $event.response.status === 401) { - this.router.navigate(['/login']); + (error: any) => { + if (error && error.response && error.response.status === 401) { + this.navigateToLogin(); } else { - console.error('An unknown error occurred while logging out', $event); + console.error('An unknown error occurred while logging out', error); + this.navigateToLogin(); } } ); } + navigateToLogin(){ + this.router.navigate(['/login']); + this.hideDrawer(); + } + onToggleSearch(event) { let expandedHeaderClass = 'header-search-expanded', header = document.querySelector('header'); @@ -95,6 +108,7 @@ export class AppComponent { changeLanguage(lang: string) { this.translate.use(lang); + this.hideDrawer(); } hideDrawer() { @@ -103,26 +117,26 @@ export class AppComponent { } private setEcmHost() { - if (localStorage.getItem(`ecmHost`)) { - this.alfrescoSettingsService.ecmHost = localStorage.getItem(`ecmHost`); - this.ecmHost = localStorage.getItem(`ecmHost`); + if (this.storage.hasItem(`ecmHost`)) { + this.alfrescoSettingsService.ecmHost = this.storage.getItem(`ecmHost`); + this.ecmHost = this.storage.getItem(`ecmHost`); } else { this.alfrescoSettingsService.ecmHost = this.ecmHost; } } private setBpmHost() { - if (localStorage.getItem(`bpmHost`)) { - this.alfrescoSettingsService.bpmHost = localStorage.getItem(`bpmHost`); - this.bpmHost = localStorage.getItem(`bpmHost`); + if (this.storage.hasItem(`bpmHost`)) { + this.alfrescoSettingsService.bpmHost = this.storage.getItem(`bpmHost`); + this.bpmHost = this.storage.getItem(`bpmHost`); } else { this.alfrescoSettingsService.bpmHost = this.bpmHost; } } private setProvider() { - if (localStorage.getItem(`providers`)) { - this.alfrescoSettingsService.setProviders(localStorage.getItem(`providers`)); + if (this.storage.hasItem(`providers`)) { + this.alfrescoSettingsService.setProviders(this.storage.getItem(`providers`)); } } } diff --git a/demo-shell-ng2/app/app.module.ts b/demo-shell-ng2/app/app.module.ts index bf2cdc287f..8be249c882 100644 --- a/demo-shell-ng2/app/app.module.ts +++ b/demo-shell-ng2/app/app.module.ts @@ -38,11 +38,13 @@ import { routing } from './app.routes'; import { CustomEditorsModule } from './components/activiti/custom-editor/custom-editor.component'; import { + HomeComponent, DataTableDemoComponent, SearchComponent, SearchBarComponent, LoginDemoComponent, ActivitiDemoComponent, + ActivitiAppsView, FormViewer, WebscriptComponent, TagComponent, @@ -74,12 +76,13 @@ import { ], declarations: [ AppComponent, - SearchBarComponent, + HomeComponent, DataTableDemoComponent, SearchComponent, SearchBarComponent, LoginDemoComponent, ActivitiDemoComponent, + ActivitiAppsView, FormViewer, WebscriptComponent, TagComponent, diff --git a/demo-shell-ng2/app/app.routes.ts b/demo-shell-ng2/app/app.routes.ts index 234bfcdc6f..139c70467b 100644 --- a/demo-shell-ng2/app/app.routes.ts +++ b/demo-shell-ng2/app/app.routes.ts @@ -17,13 +17,16 @@ import { ModuleWithProviders } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; +import { AuthGuard, AuthGuardEcm, AuthGuardBpm } from 'ng2-alfresco-core'; import { + HomeComponent, FilesComponent, DataTableDemoComponent, SearchComponent, LoginDemoComponent, ActivitiDemoComponent, + ActivitiAppsView, WebscriptComponent, TagComponent, AboutComponent, @@ -35,19 +38,85 @@ import { import { UploadButtonComponent } from 'ng2-alfresco-upload'; export const appRoutes: Routes = [ - { path: 'home', component: FilesComponent }, - { path: 'files', component: FilesComponent }, - { path: 'datatable', component: DataTableDemoComponent }, - { path: '', component: LoginDemoComponent }, - { path: 'uploader', component: UploadButtonComponent }, { path: 'login', component: LoginDemoComponent }, - { path: 'search', component: SearchComponent }, - { path: 'activiti', component: ActivitiDemoComponent }, - { path: 'activiti/appId/:appId', component: ActivitiDemoComponent }, - { path: 'activiti/tasks/:id', component: FormViewer }, - { path: 'activiti/tasksnode/:id', component: FormNodeViewer }, - { path: 'webscript', component: WebscriptComponent }, - { path: 'tag', component: TagComponent }, + { + path: '', + component: HomeComponent, + canActivate: [AuthGuard] + }, + { + path: 'home', + component: HomeComponent, + canActivate: [AuthGuard] + }, + { + path: 'files', + component: FilesComponent, + canActivate: [AuthGuardEcm] + }, + { + path: 'files/:id', + component: FilesComponent, + canActivate: [AuthGuardEcm] + }, + { + path: 'datatable', + component: DataTableDemoComponent, + canActivate: [AuthGuard] + }, + { + path: 'uploader', + component: UploadButtonComponent, + canActivate: [AuthGuardEcm] + }, + { + path: 'search', + component: SearchComponent, + canActivate: [AuthGuardEcm] + }, + { + path: 'activiti', + component: ActivitiAppsView, + canActivate: [AuthGuardBpm] + }, + { + path: 'activiti/apps', + component: ActivitiAppsView, + canActivate: [AuthGuardBpm] + }, + { + path: 'activiti/apps/:appId/tasks', + component: ActivitiDemoComponent, + canActivate: [AuthGuardBpm] + }, + // TODO: check if neeeded + { + path: 'activiti/appId/:appId', + component: ActivitiDemoComponent, + canActivate: [AuthGuardBpm] + }, + // TODO: check if needed + { + path: 'activiti/tasks/:id', + component: FormViewer, + canActivate: [AuthGuardBpm] + }, + // TODO: check if needed + { + path: 'activiti/tasksnode/:id', + component: FormNodeViewer, + canActivate: [AuthGuardBpm] + }, + { + path: 'webscript', + component: WebscriptComponent, + canActivate: [AuthGuardEcm] + }, + { + path: 'tag', + component: TagComponent, + canActivate: [AuthGuardEcm] + }, { path: 'about', component: AboutComponent }, { path: 'settings', component: SettingComponent } ]; diff --git a/demo-shell-ng2/app/components/about/about.component.ts b/demo-shell-ng2/app/components/about/about.component.ts index 93320f2746..fbcd09611d 100644 --- a/demo-shell-ng2/app/components/about/about.component.ts +++ b/demo-shell-ng2/app/components/about/about.component.ts @@ -19,10 +19,7 @@ import { Component, OnInit } from '@angular/core'; import { Http } from '@angular/http'; import { ObjectDataTableAdapter } from 'ng2-alfresco-datatable'; -declare let __moduleName: string; - @Component({ - moduleId: __moduleName, selector: 'about-page', templateUrl: './about.component.html' }) @@ -30,17 +27,29 @@ export class AboutComponent implements OnInit { data: ObjectDataTableAdapter; - constructor(private http: Http) {} + constructor(private http: Http) { + } ngOnInit() { - // this.data = new ObjectDataTableAdapter(); - this.http.get('/versions').subscribe(response => { - let data = response.json() || {}; - let packages = data.packages || []; + this.http.get('/versions.json').subscribe(response => { + var regexp = new RegExp("^(ng2-activiti|ng2-alfresco|alfresco-)", 'g'); - this.data = new ObjectDataTableAdapter(packages, [ - { type: 'text', key: 'name', title: 'Name', sortable: true }, - { type: 'text', key: 'version', title: 'Version', sortable: true } + var alfrescoPackages = Object.keys(response.json().dependencies).filter(function (val) { + console.log(val); + return regexp.test(val); + }); + + let alfrescoPackagesTableRappresentation = []; + alfrescoPackages.forEach((val)=> { + console.log(response.json().dependencies[val]); + alfrescoPackagesTableRappresentation.push({name:val,version:response.json().dependencies[val].version}); + }); + + console.log(alfrescoPackagesTableRappresentation); + + this.data = new ObjectDataTableAdapter(alfrescoPackagesTableRappresentation, [ + {type: 'text', key: 'name', title: 'Name', sortable: true}, + {type: 'text', key: 'version', title: 'Version', sortable: true} ]); }); diff --git a/demo-shell-ng2/app/components/activiti/activiti-demo.component.css b/demo-shell-ng2/app/components/activiti/activiti-demo.component.css index 8fd0aed0b7..483a152276 100644 --- a/demo-shell-ng2/app/components/activiti/activiti-demo.component.css +++ b/demo-shell-ng2/app/components/activiti/activiti-demo.component.css @@ -10,9 +10,13 @@ .task-column { background-color: #f5f5f5; padding: 10px 10px 10px 10px; - border: solid 2px rgb(31,188,210); + border-right: solid 2px rgb(144, 143, 143); +} + +.list-column { + width: 320px; } .mdl-layout__header { z-index: 1; -} \ No newline at end of file +} 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 3ab75114d5..5206baf609 100644 --- a/demo-shell-ng2/app/components/activiti/activiti-demo.component.html +++ b/demo-shell-ng2/app/components/activiti/activiti-demo.component.html @@ -4,38 +4,31 @@ -
- APPS - TASK LIST - PROCESS LIST - ANALYTICS + -
- - - -
-
- -
-
- +
-
+
- Task Filters +
Task Filters
+
-
-
- Task List +
+
Task List
+
- Task Details +
Task Details
+
@@ -59,33 +53,41 @@
-
+
-
- Process Filters - +
+
Process Filters
+
+ + (filterClick)="onProcessFilterClick($event)" + (onSuccess)="onSuccessProcessFilterList($event)">
-
- Process List +
+
Process List
+
+ [processDefinitionKey]="processFilter.filter.processDefinitionKey" + [name]="processFilter.filter.name" + [state]="processFilter.filter.state" + [sort]="processFilter.filter.sort" + [data]="dataProcesses" + (rowClick)="onProcessRowClick($event)" + (onSuccess)="onSuccessProcessList($event)">
-
- Process Details - +
+
Process Details
+
+
Start Process +
@@ -97,13 +99,22 @@
-
+
- +
Report List
+
+ +
- + +
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 82feddfefd..98125b3730 100644 --- a/demo-shell-ng2/app/components/activiti/activiti-demo.component.ts +++ b/demo-shell-ng2/app/components/activiti/activiti-demo.component.ts @@ -15,70 +15,69 @@ * limitations under the License. */ -import { Component, AfterViewChecked, ViewChild, Input } from '@angular/core'; +import { AfterViewInit, Component, ElementRef, Input, ViewChild } from '@angular/core'; import { - AppDefinitionRepresentationModel, - FilterRepresentationModel, ActivitiApps, - ActivitiTaskList + ActivitiFilters, + ActivitiTaskDetails, + ActivitiTaskList, + FilterRepresentationModel } from 'ng2-activiti-tasklist'; import { + ActivitiProcessFilters, + ActivitiProcessInstanceDetails, ActivitiProcessInstanceListComponent, ActivitiStartProcessInstance, ProcessInstance } from 'ng2-activiti-processlist'; +import { AnalyticsReportListComponent } from 'ng2-activiti-analytics'; import { ActivatedRoute } from '@angular/router'; import { Subscription } from 'rxjs/Rx'; import { ObjectDataTableAdapter, DataSorting } from 'ng2-alfresco-datatable'; - +import { AlfrescoApiService } from 'ng2-alfresco-core'; import { FormRenderingService } from 'ng2-activiti-form'; import { /*CustomEditorComponent*/ CustomStencil01 } from './custom-editor/custom-editor.component'; -declare let __moduleName: string; declare var componentHandler; const currentProcessIdNew = '__NEW__'; @Component({ - moduleId: __moduleName, selector: 'activiti-demo', templateUrl: './activiti-demo.component.html', styleUrls: ['./activiti-demo.component.css'] }) -export class ActivitiDemoComponent implements AfterViewChecked { +export class ActivitiDemoComponent implements AfterViewInit { - @ViewChild('activitiapps') + @ViewChild(ActivitiApps) activitiapps: ActivitiApps; - @ViewChild('activitifilter') - activitifilter: any; - - @ViewChild('activitidetails') - activitidetails: any; + @ViewChild(ActivitiFilters) + activitifilter: ActivitiFilters; @ViewChild(ActivitiTaskList) activititasklist: ActivitiTaskList; - @ViewChild('activitiprocessfilter') - activitiprocessfilter: any; + @ViewChild(ActivitiTaskDetails) + activitidetails: ActivitiTaskDetails; + + @ViewChild(ActivitiProcessFilters) + activitiprocessfilter: ActivitiProcessFilters; @ViewChild(ActivitiProcessInstanceListComponent) activitiprocesslist: ActivitiProcessInstanceListComponent; - @ViewChild('activitiprocessdetails') - activitiprocessdetails: any; + @ViewChild(ActivitiProcessInstanceDetails) + activitiprocessdetails: ActivitiProcessInstanceDetails; @ViewChild(ActivitiStartProcessInstance) activitiStartProcess: ActivitiStartProcessInstance; - @ViewChild('tabmain') - tabMain: any; - - @ViewChild('tabheader') - tabHeader: any; + @ViewChild(AnalyticsReportListComponent) + analyticsreportlist: AnalyticsReportListComponent; @Input() appId: number; @@ -90,6 +89,10 @@ export class ActivitiDemoComponent implements AfterViewChecked { taskSchemaColumns: any [] = []; processSchemaColumns: any [] = []; + processTabActivie: boolean = false; + + reportsTabActivie: boolean = false; + taskFilter: FilterRepresentationModel; report: any; processFilter: FilterRepresentationModel; @@ -99,7 +102,10 @@ export class ActivitiDemoComponent implements AfterViewChecked { dataTasks: ObjectDataTableAdapter; dataProcesses: ObjectDataTableAdapter; - constructor(private route: ActivatedRoute, private formRenderingService: FormRenderingService) { + constructor(private elementRef: ElementRef, + private route: ActivatedRoute, + private apiService: AlfrescoApiService, + private formRenderingService: FormRenderingService) { this.dataTasks = new ObjectDataTableAdapter( [], [ @@ -112,8 +118,8 @@ export class ActivitiDemoComponent implements AfterViewChecked { this.dataProcesses = new ObjectDataTableAdapter( [], [ - {type: 'text', key: 'name', title: 'Name', cssClass: 'full-width name-column'}, - {type: 'text', key: 'started', title: 'Started', cssClass: 'hidden'} + {type: 'text', key: 'name', title: 'Name', cssClass: 'full-width name-column', sortable: true}, + {type: 'text', key: 'started', title: 'Started', cssClass: 'hidden', sortable: true} ] ); @@ -126,7 +132,15 @@ export class ActivitiDemoComponent implements AfterViewChecked { ngOnInit() { this.sub = this.route.params.subscribe(params => { - this.appId = params['appId']; + let applicationId = params['appId']; + if (applicationId && applicationId !== '0') { + this.appId = params['appId']; + } + + this.taskFilter = null; + this.currentTaskId = null; + this.processFilter = null; + this.currentProcessInstanceId = null; }); this.layoutType = ActivitiApps.LAYOUT_GRID; } @@ -135,25 +149,6 @@ export class ActivitiDemoComponent implements AfterViewChecked { this.sub.unsubscribe(); } - onAppClick(app: AppDefinitionRepresentationModel) { - this.appId = app.id; - this.taskFilter = null; - this.currentTaskId = null; - - this.processFilter = null; - this.currentProcessInstanceId = null; - - this.changeTab('apps', 'tasks'); - } - - changeTab(origin: string, destination: string) { - this.tabMain.nativeElement.children[origin].classList.remove('is-active'); - this.tabMain.nativeElement.children[destination].classList.add('is-active'); - - this.tabHeader.nativeElement.children[`${origin}-header`].classList.remove('is-active'); - this.tabHeader.nativeElement.children[`${destination}-header`].classList.add('is-active'); - } - onTaskFilterClick(event: FilterRepresentationModel) { this.taskFilter = event; } @@ -167,6 +162,8 @@ export class ActivitiDemoComponent implements AfterViewChecked { } onStartTaskSuccess(event: any) { + this.activitifilter.selectFirstFilter(); + this.taskFilter = this.activitifilter.getCurrentFilter(); this.activititasklist.reload(); } @@ -194,6 +191,10 @@ export class ActivitiDemoComponent implements AfterViewChecked { this.currentProcessInstanceId = processInstanceId; } + onEditReport(name: string) { + this.analyticsreportlist.reload(); + } + navigateStartProcess() { this.currentProcessInstanceId = currentProcessIdNew; } @@ -201,6 +202,7 @@ export class ActivitiDemoComponent implements AfterViewChecked { onStartProcessInstance(instance: ProcessInstance) { this.currentProcessInstanceId = instance.id; this.activitiStartProcess.reset(); + this.activitiprocesslist.reload(); } isStartProcessMode() { @@ -225,11 +227,32 @@ export class ActivitiDemoComponent implements AfterViewChecked { this.currentTaskId = null; } - ngAfterViewChecked() { + ngAfterViewInit() { // workaround for MDL issues with dynamic components if (componentHandler) { componentHandler.upgradeAllRegistered(); } + + this.loadStencilScriptsInPageFromActiviti(); + } + + activeProcess() { + this.processTabActivie = true; + } + + activeReports() { + this.reportsTabActivie = true; + } + + loadStencilScriptsInPageFromActiviti() { + this.apiService.getInstance().activiti.scriptFileApi.getControllers().then(response => { + if (response) { + let s = document.createElement('script'); + s.type = 'text/javascript'; + s.text = response; + this.elementRef.nativeElement.appendChild(s); + } + }); } } diff --git a/demo-shell-ng2/app/components/activiti/apps.view.ts b/demo-shell-ng2/app/components/activiti/apps.view.ts new file mode 100644 index 0000000000..3deca72972 --- /dev/null +++ b/demo-shell-ng2/app/components/activiti/apps.view.ts @@ -0,0 +1,37 @@ +/*! + * @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 } from '@angular/core'; +import { Router, ActivatedRoute } from '@angular/router'; +import { AppDefinitionRepresentationModel } from 'ng2-activiti-tasklist'; + +@Component({ + selector: 'activiti-apps-view', + template: ` + + ` +}) +export class ActivitiAppsView { + + constructor(private router: Router, private route: ActivatedRoute) { + } + + onAppClicked(app: AppDefinitionRepresentationModel) { + this.router.navigate(['/activiti/apps', app.id || 0, 'tasks']); + } + +} diff --git a/demo-shell-ng2/app/components/activiti/custom-editor/custom-editor.component.ts b/demo-shell-ng2/app/components/activiti/custom-editor/custom-editor.component.ts index b71a11ae3c..841fda57f0 100644 --- a/demo-shell-ng2/app/components/activiti/custom-editor/custom-editor.component.ts +++ b/demo-shell-ng2/app/components/activiti/custom-editor/custom-editor.component.ts @@ -1,3 +1,20 @@ +/*! + * @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 { NgModule, Component } from '@angular/core'; import { WidgetComponent } from 'ng2-activiti-form'; 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 index a73a709543..cde623c06e 100644 --- a/demo-shell-ng2/app/components/activiti/form-node-viewer.component.ts +++ b/demo-shell-ng2/app/components/activiti/form-node-viewer.component.ts @@ -19,11 +19,9 @@ import { Component, OnInit, OnDestroy, AfterViewChecked } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; 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'] 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 6998e1fcb5..080229194c 100644 --- a/demo-shell-ng2/app/components/activiti/form-viewer.component.ts +++ b/demo-shell-ng2/app/components/activiti/form-viewer.component.ts @@ -19,11 +19,9 @@ import { Component, OnInit, OnDestroy, AfterViewChecked } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { Subscription } from 'rxjs/Rx'; -declare let __moduleName: string; declare var componentHandler; @Component({ - moduleId: __moduleName, selector: 'form-viewer', templateUrl: './form-viewer.component.html', styleUrls: ['./form-viewer.component.css'] diff --git a/demo-shell-ng2/app/components/datatable/datatable-demo.component.ts b/demo-shell-ng2/app/components/datatable/datatable-demo.component.ts index ae615fe7e6..ae5854cabd 100644 --- a/demo-shell-ng2/app/components/datatable/datatable-demo.component.ts +++ b/demo-shell-ng2/app/components/datatable/datatable-demo.component.ts @@ -23,10 +23,7 @@ import { ObjectDataColumn } from 'ng2-alfresco-datatable'; -declare let __moduleName: string; - @Component({ - moduleId: __moduleName, selector: 'datatable-demo', templateUrl: './datatable-demo.component.html' }) diff --git a/demo-shell-ng2/app/components/files/files.component.css b/demo-shell-ng2/app/components/files/files.component.css index c2bac0048e..cb4cb685aa 100644 --- a/demo-shell-ng2/app/components/files/files.component.css +++ b/demo-shell-ng2/app/components/files/files.component.css @@ -7,3 +7,11 @@ margin: 0; } } + +.error-message { + text-align: left; +} + +.error-message--text { + color: #d50000; +} diff --git a/demo-shell-ng2/app/components/files/files.component.html b/demo-shell-ng2/app/components/files/files.component.html index 1ea0941097..5cf0ac0361 100644 --- a/demo-shell-ng2/app/components/files/files.component.html +++ b/demo-shell-ng2/app/components/files/files.component.html @@ -1,191 +1,211 @@ -
-
- + + + +
+ + {{errorMessage}} +
+ - - - + [currentFolderId]="currentFolderId" + [contextMenuActions]="true" + [contentActions]="true" + (error)="onNavigationError($event)" + (success)="resetError()" + (preview)="showFile($event)" + (folderChange)="onFolderChanged($event)"> + + + + + - - - - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - -
-
    -
  • Current path: {{documentList.currentFolderPath}}
  • -
  • - -
  • -
  • - -
  • -
  • - -
  • -
  • - -
  • -
-
- - -

- -

- - -

- -

- -

- -

- -

- -

- -
Upload
-
-
- -
-
-
- -
-
-
-
- -
-
-
- + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
    +
  • Current path: {{currentPath}}
  • +
  • + +
  • +
  • + +
  • +
  • + +
  • +
  • + +
  • +
  • + +
  • +
  • + +
  • +
  • + +
  • +
+
+ + +

+ +

+ + +

+ +

+ +

+ +

+ +

+ +

+ +
Upload
+
+
+ +
+
+
+ +
+
+
+
+ +
+
+
+ +
this.setupBpmActions(defs || []), - err => console.log(err) - ); - } else { - console.log('You are not logged in'); - } + if (this.route) { + this.route.params.forEach((params: Params) => { + this.currentFolderId = params.hasOwnProperty('id') ? params['id'] : null; + }); + } + if (this.auth.isBpmLoggedIn()) { + this.formService.getProcessDefinitions().subscribe( + defs => this.setupBpmActions(defs || []), + err => console.log(err) + ); + } else { + console.log('You are not logged in'); + } } viewActivitiForm(event?: any) { this.router.navigate(['/activiti/tasksnode', event.value.entry.id]); } + onNavigationError(err: any) { + if (err) { + this.errorMessage = err.message || 'Navigation error'; + } + } + + resetError() { + this.errorMessage = null; + } + private setupBpmActions(actions: any[]) { actions.map(def => { let documentAction = new DocumentActionModel(); diff --git a/demo-shell-ng2/app/components/home/home.component.css b/demo-shell-ng2/app/components/home/home.component.css new file mode 100644 index 0000000000..0de97b445c --- /dev/null +++ b/demo-shell-ng2/app/components/home/home.component.css @@ -0,0 +1,48 @@ +.home-cards { + float: left; + margin: 10px 10px 10px 10px; +} + +.mdl-card__supporting-text { + display: block; + overflow-y: auto; + height: 400px; +} + +.demo-card-square.mdl-card { + width: 320px; + height: 380px; +} + +.demo-card-square > .mdl-card__title { + color: #fff; + background-color: rgb(158, 158, 158); +} + +.mdl-card__title { + cursor: pointer; + height: 70px; +} + +.home--card__icon { + padding-top: 2px; + margin-right: 4px; +} + +.home--feature-list { + list-style: none; + padding-left: 0; +} + +.home--feature-list__icon { + float: left; +} + +.home--feature-list__text { + padding-top: 2px; +} + +span.home--feature-list__text:before { + content: ''; + padding-left: 4px; +} diff --git a/demo-shell-ng2/app/components/home/home.component.html b/demo-shell-ng2/app/components/home/home.component.html new file mode 100644 index 0000000000..c889158838 --- /dev/null +++ b/demo-shell-ng2/app/components/home/home.component.html @@ -0,0 +1,187 @@ + +
+
+

+ dvr + DocumentList - ECM +

+
+
+ Demonstrates multiple Alfresco ECM components used together to show the files of you ECM instance : + +
+
+ + + +
+
+

+ apps + Activiti - BPM +

+
+
+ Demonstrates multiple Alfresco BPM components used together to show your BPM prorcess and tasks: + +
+
+ + + +
+
+

+ view_module + DataTable-ECM&BPM +

+
+
+ Basic table component: +
    +
  • + brightness_1 + Comunication with the Rest Api and core services + ng2-alfresco-core +
  • +
+
+
+ + +
+
+

+ file_upload + Uploader - ECM +

+
+
+ Basic table uploader component for the ECM and BPM: +
    +
  • + brightness_1 + Comunication with the Rest Api and core services + ng2-alfresco-core +
  • +
+
+
+ + +
+
+

+ account_circle + Login - ECM & BPM +

+
+
+ Login component for the ECM and BPM: +
    +
  • + brightness_1 + Comunication with the Rest Api and core services + ng2-alfresco-core +
  • +
+
+
+ + +
+
+

+ extension + Webscript - ECM +

+
+
+ Shows and create webscripts in your ECM instance: +
    +
  • + brightness_1 + Comunication with the Rest Api and core services + ng2-alfresco-core +
  • +
+
+
+ + +
+
+

+ local_offer + Tag - ECM +

+
+
+ Shows and add tags to the node of your ECM instance: + +
+
diff --git a/demo-shell-ng2/app/components/home/home.component.spec.ts b/demo-shell-ng2/app/components/home/home.component.spec.ts new file mode 100644 index 0000000000..1ef0242bd1 --- /dev/null +++ b/demo-shell-ng2/app/components/home/home.component.spec.ts @@ -0,0 +1,36 @@ +/*! + * @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 { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { TestBed } from '@angular/core/testing'; +import { HomeComponent } from './home.component'; +import { CoreModule } from 'ng2-alfresco-core'; + +describe('HomeComponent', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [CoreModule], + declarations: [HomeComponent], + schemas: [CUSTOM_ELEMENTS_SCHEMA] + }); + }); + + it ('should work', () => { + let fixture = TestBed.createComponent(HomeComponent); + expect(fixture.componentInstance instanceof HomeComponent).toBe(true, 'should create HomeComponent'); + }); +}); diff --git a/ng2-components/ng2-activiti-analytics/src/declarations.d.ts b/demo-shell-ng2/app/components/home/home.component.ts similarity index 75% rename from ng2-components/ng2-activiti-analytics/src/declarations.d.ts rename to demo-shell-ng2/app/components/home/home.component.ts index a4cceff023..06cb1aaccb 100644 --- a/ng2-components/ng2-activiti-analytics/src/declarations.d.ts +++ b/demo-shell-ng2/app/components/home/home.component.ts @@ -15,9 +15,11 @@ * limitations under the License. */ -declare let moment: any; -declare let mdDateTimePicker: any; +import { Component } from '@angular/core'; -// MDL -declare let componentHandler: any; -declare let dialogPolyfill: any; +@Component({ + selector: 'home-view', + templateUrl: './home.component.html', + styleUrls: ['./home.component.css'] +}) +export class HomeComponent {} diff --git a/demo-shell-ng2/app/components/index.ts b/demo-shell-ng2/app/components/index.ts index 28ca7a9b56..fb66f819f6 100644 --- a/demo-shell-ng2/app/components/index.ts +++ b/demo-shell-ng2/app/components/index.ts @@ -15,6 +15,7 @@ * limitations under the License. */ +export { HomeComponent } from './home/home.component'; export { DataTableDemoComponent } from './datatable/datatable-demo.component'; export { SearchComponent } from './search/search.component'; export { SearchBarComponent } from './search/search-bar.component'; @@ -27,3 +28,4 @@ export { AboutComponent } from './about/about.component'; export { FilesComponent } from './files/files.component'; export { FormNodeViewer } from './activiti/form-node-viewer.component'; export { SettingComponent } from './setting/setting.component'; +export { ActivitiAppsView } from './activiti/apps.view'; diff --git a/demo-shell-ng2/app/components/login/login-demo.component.css b/demo-shell-ng2/app/components/login/login-demo.component.css index d3b186c7c4..78c114b065 100644 --- a/demo-shell-ng2/app/components/login/login-demo.component.css +++ b/demo-shell-ng2/app/components/login/login-demo.component.css @@ -1,14 +1,39 @@ -.setting { - border-radius: 8px; position: absolute; background-color: papayawhip; color: cadetblue; left: 10px; top: 10px; z-index: 1; +.setting-button { + position: absolute; + right: 10px; + top: 10px; + z-index: 1; } -.banned{ - width:130px;margin: 10px; + +.settings { + border-radius: 8px; + position: absolute; + background-color: papayawhip; + color: cadetblue; + left: 10px; + top: 10px; + z-index: 1; +} + +.banned { + width: 130px; + margin: 10px; } .toggle { - width:120px;margin: 20px; + width: 120px; + margin: 20px; } -.setting-button { - position: absolute; right: 10px; top: 10px; z-index: 1; +@media (min-width: 721px) { + .mobile-settings { + display: none; + } } + +@media (max-width: 720px) { + .settings { + display: none; + } +} + diff --git a/demo-shell-ng2/app/components/login/login-demo.component.html b/demo-shell-ng2/app/components/login/login-demo.component.html index b77993525d..c8e5f3a2aa 100644 --- a/demo-shell-ng2/app/components/login/login-demo.component.html +++ b/demo-shell-ng2/app/components/login/login-demo.component.html @@ -1,21 +1,23 @@ -
+ + +

@@ -25,12 +27,47 @@

+ + - + + + (onError)="onError($event)"> +
+

+ +

+

+ +

+

+ +

+
+ + +
+
+
diff --git a/demo-shell-ng2/app/components/login/login-demo.component.ts b/demo-shell-ng2/app/components/login/login-demo.component.ts index f11e33dcae..d5ee054b33 100644 --- a/demo-shell-ng2/app/components/login/login-demo.component.ts +++ b/demo-shell-ng2/app/components/login/login-demo.component.ts @@ -18,11 +18,9 @@ import { Component, ViewChild, OnInit } from '@angular/core'; import { Router } from '@angular/router'; import { Validators } from '@angular/forms'; - -declare let __moduleName: string; +import { StorageService } from 'ng2-alfresco-core'; @Component({ - moduleId: __moduleName, selector: 'login-demo', templateUrl: './login-demo.component.html', styleUrls: ['./login-demo.component.css'] @@ -33,14 +31,14 @@ export class LoginDemoComponent implements OnInit { alfrescologin: any; providers: string = 'ECM'; - disableCsrf: boolean = false; blackListUsername: string; customValidation: any; + disableCsrf: boolean = false; isECM: boolean = true; isBPM: boolean = false; - constructor(public router: Router) { + constructor(public router: Router, private storage: StorageService) { this.customValidation = { username: ['', Validators.compose([Validators.required, Validators.minLength(4)])], password: ['', Validators.required] @@ -52,14 +50,14 @@ export class LoginDemoComponent implements OnInit { this.alfrescologin.addCustomValidationError('username', 'minlength', 'LOGIN.MESSAGES.USERNAME-MIN'); this.alfrescologin.addCustomValidationError('password', 'required', 'LOGIN.MESSAGES.PASSWORD-REQUIRED'); - if (localStorage.getItem('providers')) { - this.providers = localStorage.getItem('providers'); + if (this.storage.hasItem('providers')) { + this.providers = this.storage.getItem('providers'); } - this.setProviders(); + this.initProviders(); } - setProviders() { + initProviders() { if (this.providers === 'BPM') { this.isECM = false; this.isBPM = true; @@ -80,38 +78,40 @@ export class LoginDemoComponent implements OnInit { console.log($event); } - toggleECM(checked) { - if (checked && this.providers === 'BPM') { - this.providers = 'ALL'; - } else if (checked) { - this.providers = 'ECM'; - } else if (!checked && this.providers === 'ALL') { - this.providers = 'BPM'; - } else if (!checked && this.providers === 'ECM') { - this.providers = ''; - } - - localStorage.setItem('providers', this.providers); + toggleECM() { + this.isECM = !this.isECM; + this.storage.setItem('providers', this.updateProvider()); } - toggleBPM(checked) { - if (checked && this.providers === 'ECM') { - this.providers = 'ALL'; - } else if (checked) { - this.providers = 'BPM'; - } else if (!checked && this.providers === 'ALL') { - this.providers = 'ECM'; - } else if (!checked && this.providers === 'BPM') { - this.providers = ''; - } - - localStorage.setItem('providers', this.providers); + toggleBPM() { + this.isBPM = !this.isBPM; + this.storage.setItem('providers', this.updateProvider()); } toggleCSRF() { this.disableCsrf = !this.disableCsrf; } + updateProvider(){ + if (this.isBPM && this.isECM) { + this.providers = 'ALL'; + return this.providers; + } + + if (this.isECM) { + this.providers = 'ECM'; + return this.providers; + } + + if (this.isBPM) { + this.providers = 'BPM'; + return this.providers; + } + + this.providers = ''; + return this.providers; + }; + validateForm(event: any) { let values = event.values; if (values.controls['username'].value === this.blackListUsername) { diff --git a/demo-shell-ng2/app/components/search/search-bar.component.html b/demo-shell-ng2/app/components/search/search-bar.component.html index 2533df52c2..821646954e 100644 --- a/demo-shell-ng2/app/components/search/search-bar.component.html +++ b/demo-shell-ng2/app/components/search/search-bar.component.html @@ -1,14 +1,13 @@ + (fileSelect)="onItemClicked($event)"> -
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 689cf21f5e..366e618434 100644 --- a/demo-shell-ng2/app/components/search/search-bar.component.ts +++ b/demo-shell-ng2/app/components/search/search-bar.component.ts @@ -18,11 +18,9 @@ import { Component, EventEmitter, Output } from '@angular/core'; import { Router } from '@angular/router'; import { AlfrescoAuthenticationService } from 'ng2-alfresco-core'; - -declare let __moduleName: string; +import { MinimalNodeEntity } from 'alfresco-js-api'; @Component({ - moduleId: __moduleName, selector: 'search-bar', templateUrl: './search-bar.component.html' }) @@ -54,10 +52,12 @@ export class SearchBarComponent { }]); } - onFileClicked(event) { - if (event.value.entry.isFile) { - this.fileNodeId = event.value.entry.id; + onItemClicked(event: MinimalNodeEntity) { + if (event.entry.isFile) { + this.fileNodeId = event.entry.id; this.fileShowed = true; + } else if (event.entry.isFolder) { + this.router.navigate(['/files', event.entry.id]); } } diff --git a/demo-shell-ng2/app/components/search/search.component.html b/demo-shell-ng2/app/components/search/search.component.html index 6962e2d759..8e5f7d755c 100644 --- a/demo-shell-ng2/app/components/search/search.component.html +++ b/demo-shell-ng2/app/components/search/search.component.html @@ -1,8 +1,8 @@

Search results

- +
- +
diff --git a/demo-shell-ng2/app/components/search/search.component.ts b/demo-shell-ng2/app/components/search/search.component.ts index a7306c954f..6351a0b5b2 100644 --- a/demo-shell-ng2/app/components/search/search.component.ts +++ b/demo-shell-ng2/app/components/search/search.component.ts @@ -16,11 +16,10 @@ */ import { Component } from '@angular/core'; - -declare let __moduleName: string; +import { Router } from '@angular/router'; +import { MinimalNodeEntity } from 'alfresco-js-api'; @Component({ - moduleId: __moduleName, selector: 'search-component', templateUrl: './search.component.html', styles: [` @@ -51,10 +50,15 @@ export class SearchComponent { fileShowed: boolean = false; fileNodeId: string; - onFileClicked(event) { - if (event.value.entry.isFile) { - this.fileNodeId = event.value.entry.id; + constructor(public router: Router) { + } + + onNavigateItem(event: MinimalNodeEntity) { + if (event.entry.isFile) { + this.fileNodeId = event.entry.id; this.fileShowed = true; + } else if (event.entry.isFolder) { + this.router.navigate(['/files', event.entry.id]); } } } diff --git a/demo-shell-ng2/app/components/setting/setting.component.html b/demo-shell-ng2/app/components/setting/setting.component.html index 60d372d4e8..29566444e1 100644 --- a/demo-shell-ng2/app/components/setting/setting.component.html +++ b/demo-shell-ng2/app/components/setting/setting.component.html @@ -24,6 +24,11 @@ tabindex="1" (change)="onChangeBPMHost($event)" value="{{bpmHost}}"/>
+
diff --git a/demo-shell-ng2/app/components/setting/setting.component.ts b/demo-shell-ng2/app/components/setting/setting.component.ts index d33e258c91..3fd9278643 100644 --- a/demo-shell-ng2/app/components/setting/setting.component.ts +++ b/demo-shell-ng2/app/components/setting/setting.component.ts @@ -16,14 +16,9 @@ */ import { Component } from '@angular/core'; -import { - AlfrescoSettingsService -} from 'ng2-alfresco-core'; - -declare let __moduleName: string; +import { AlfrescoSettingsService, StorageService } from 'ng2-alfresco-core'; @Component({ - moduleId: __moduleName, selector: 'alfresco-setting-demo', templateUrl: './setting.component.html', styleUrls: ['./setting.component.css'] @@ -33,7 +28,8 @@ export class SettingComponent { ecmHost: string; bpmHost: string; - constructor(public alfrescoSettingsService: AlfrescoSettingsService) { + constructor(public alfrescoSettingsService: AlfrescoSettingsService, + private storage: StorageService) { this.ecmHost = this.alfrescoSettingsService.ecmHost; this.bpmHost = this.alfrescoSettingsService.bpmHost; } @@ -42,14 +38,14 @@ export class SettingComponent { console.log((event.target).value); this.ecmHost = (event.target).value; this.alfrescoSettingsService.ecmHost = this.ecmHost; - localStorage.setItem(`ecmHost`, this.ecmHost); + this.storage.setItem(`ecmHost`, this.ecmHost); } public onChangeBPMHost(event: KeyboardEvent): void { console.log((event.target).value); this.bpmHost = (event.target).value; this.alfrescoSettingsService.bpmHost = this.bpmHost; - localStorage.setItem(`bpmHost`, this.bpmHost); + this.storage.setItem(`bpmHost`, this.bpmHost); } } diff --git a/demo-shell-ng2/app/fonts/material-icons.woff2 b/demo-shell-ng2/app/fonts/material-icons.woff2 deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/demo-shell-ng2/app/js/Polyline.js b/demo-shell-ng2/app/js/Polyline.js deleted file mode 100644 index 9983929cf1..0000000000 --- a/demo-shell-ng2/app/js/Polyline.js +++ /dev/null @@ -1,372 +0,0 @@ -/** - * Class to generate polyline - * - * @author Dmitry Farafonov - */ - -var ANCHOR_TYPE= { - main: "main", - middle: "middle", - first: "first", - last: "last" -}; - -function Anchor(uuid, type, x, y) { - this.uuid = uuid; - this.x = x; - this.y = y; - this.type = (type == ANCHOR_TYPE.middle) ? ANCHOR_TYPE.middle : ANCHOR_TYPE.main; -}; -Anchor.prototype = { - uuid: null, - x: 0, - y: 0, - type: ANCHOR_TYPE.main, - isFirst: false, - isLast: false, - ndex: 0, - typeIndex: 0 -}; - -function Polyline(uuid, points, strokeWidth, paper) { - /* Array on coordinates: - * points: [{x: 410, y: 110}, 1 - * {x: 570, y: 110}, 1 2 - * {x: 620, y: 240}, 2 3 - * {x: 750, y: 270}, 3 4 - * {x: 650, y: 370}]; 4 - */ - this.points = points; - - /* - * path for graph - * [["M", x1, y1], ["L", x2, y2], ["C", ax, ay, bx, by, x3, y3], ["L", x3, y3]] - */ - this.path = []; - - this.anchors = []; - - if (strokeWidth) this.strokeWidth = strokeWidth; - - this.paper = paper; - - this.closePath = false; - - this.init(); -}; - -Polyline.prototype = { - id: null, - points: [], - path: [], - anchors: [], - strokeWidth: 1, - radius: 1, - showDetails: false, - paper: null, - element: null, - isDefaultConditionAvailable: false, - closePath: false, - - init: function(points){ - var linesCount = this.getLinesCount(); - if (linesCount < 1) - return; - - this.normalizeCoordinates(); - - // create anchors - - this.pushAnchor(ANCHOR_TYPE.first, this.getLine(0).x1, this.getLine(0).y1); - - for (var i = 1; i < linesCount; i++) - { - var line1 = this.getLine(i-1); - this.pushAnchor(ANCHOR_TYPE.main, line1.x2, line1.y2); - } - - this.pushAnchor(ANCHOR_TYPE.last, this.getLine(linesCount-1).x2, this.getLine(linesCount-1).y2); - - this.rebuildPath(); - }, - - normalizeCoordinates: function(){ - for(var i=0; i < this.points.length; i++){ - this.points[i].x = parseFloat(this.points[i].x); - this.points[i].y = parseFloat(this.points[i].y); - } - }, - - getLinesCount: function(){ - return this.points.length-1; - }, - _getLine: function(i){ - if (this.points.length > i && this.points[i]) { - return {x1: this.points[i].x, y1: this.points[i].y, x2: this.points[i+1].x, y2: this.points[i+1].y}; - } else { - return undefined; - } - }, - getLine: function(i){ - var line = this._getLine(i); - if (line != undefined) { - line.angle = this.getLineAngle(i); - } - return line; - }, - getLineAngle: function(i){ - var line = this._getLine(i); - return Math.atan2(line.y2 - line.y1, line.x2 - line.x1); - }, - getLineLengthX: function(i){ - var line = this.getLine(i); - return (line.x2 - line.x1); - }, - getLineLengthY: function(i){ - var line = this.getLine(i); - return (line.y2 - line.y1); - }, - getLineLength: function(i){ - return Math.sqrt(Math.pow(this.getLineLengthX(i), 2) + Math.pow(this.getLineLengthY(i), 2)); - }, - - getAnchors: function(){ - return this.anchors; - }, - getAnchorsCount: function(type){ - if (!type) - return this.anchors.length; - else { - var count = 0; - for(var i=0; i < this.getAnchorsCount(); i++){ - var anchor = this.anchors[i]; - if (anchor.getType() == type) { - count++; - } - } - return count; - } - }, - - pushAnchor: function(type, x, y, index){ - if (type == ANCHOR_TYPE.first) { - index = 0; - typeIndex = 0; - } else if (type == ANCHOR_TYPE.last) { - index = this.getAnchorsCount(); - typeIndex = 0; - } else if (!index) { - index = this.anchors.length; - } else { - for(var i=0; i < this.getAnchorsCount(); i++){ - var anchor = this.anchors[i]; - if (anchor.index > index) { - anchor.index++; - anchor.typeIndex++; - } - } - } - - var anchor = new Anchor(this.id, ANCHOR_TYPE.main, x, y, index, typeIndex); - - this.anchors.push(anchor); - }, - - getAnchor: function(position){ - return this.anchors[position]; - }, - - getAnchorByType: function(type, position){ - if (type == ANCHOR_TYPE.first) - return this.anchors[0]; - if (type == ANCHOR_TYPE.last) - return this.anchors[this.getAnchorsCount()-1]; - - for(var i=0; i < this.getAnchorsCount(); i++){ - var anchor = this.anchors[i]; - if (anchor.type == type) { - if( position == anchor.position) - return anchor; - } - } - return null; - }, - - addNewPoint: function(position, x, y){ - // - for(var i = 0; i < this.getLinesCount(); i++){ - var line = this.getLine(i); - if (x > line.x1 && x < line.x2 && y > line.y1 && y < line.y2) { - this.points.splice(i+1,0,{x: x, y: y}); - break; - } - } - - this.rebuildPath(); - }, - - rebuildPath: function(){ - var path = []; - - for(var i = 0; i < this.getAnchorsCount(); i++){ - var anchor = this.getAnchor(i); - - var pathType = ""; - if (i == 0) - pathType = "M"; - else - pathType = "L"; - - // TODO: save previous points and calculate new path just if points are updated, and then save currents values as previous - - var targetX = anchor.x, targetY = anchor.y; - if (i>0 && i < this.getAnchorsCount()-1) { - // get new x,y - var cx = anchor.x, cy = anchor.y; - - // pivot point of prev line - var AO = this.getLineLength(i-1); - if (AO < this.radius) { - AO = this.radius; - } - - this.isDefaultConditionAvailable = (this.isDefaultConditionAvailable || (i == 1 && AO > 10)); - - var ED = this.getLineLengthY(i-1) * this.radius / AO; - var OD = this.getLineLengthX(i-1) * this.radius / AO; - targetX = anchor.x - OD; - targetY = anchor.y - ED; - - if (AO < 2*this.radius && i>1) { - targetX = anchor.x - this.getLineLengthX(i-1)/2; - targetY = anchor.y - this.getLineLengthY(i-1)/2;; - } - - // pivot point of next line - var AO = this.getLineLength(i); - if (AO < this.radius) { - AO = this.radius; - } - var ED = this.getLineLengthY(i) * this.radius / AO; - var OD = this.getLineLengthX(i) * this.radius / AO; - var nextSrcX = anchor.x + OD; - var nextSrcY = anchor.y + ED; - - if (AO < 2*this.radius && i 10)); - } - - // anti smoothing - if (this.strokeWidth%2 == 1) { - targetX += 0.5; - targetY += 0.5; - } - - path.push([pathType, targetX, targetY]); - - if (i>0 && i < this.getAnchorsCount()-1) { - path.push(["C", ax, ay, bx, by, zx, zy]); - } - } - - if (this.closePath) - { - path.push(["Z"]); - } - - this.path = path; - }, - - transform: function(transformation) - { - this.element.transform(transformation); - }, - attr: function(attrs) - { - // TODO: foreach and set each - this.element.attr(attrs); - } -}; - -function Polygone(points, strokeWidth) { - /* Array on coordinates: - * points: [{x: 410, y: 110}, 1 - * {x: 570, y: 110}, 1 2 - * {x: 620, y: 240}, 2 3 - * {x: 750, y: 270}, 3 4 - * {x: 650, y: 370}]; 4 - */ - this.points = points; - - /* - * path for graph - * [["M", x1, y1], ["L", x2, y2], ["C", ax, ay, bx, by, x3, y3], ["L", x3, y3]] - */ - this.path = []; - - this.anchors = []; - - if (strokeWidth) this.strokeWidth = strokeWidth; - - this.closePath = true; - this.init(); -}; - - -/* - * Poligone is inherited from Poliline: draws closedPath of polyline - */ - -var Foo = function () { }; -Foo.prototype = Polyline.prototype; - -Polygone.prototype = new Foo(); - -Polygone.prototype.rebuildPath = function(){ - var path = []; - for(var i = 0; i < this.getAnchorsCount(); i++){ - var anchor = this.getAnchor(i); - - var pathType = ""; - if (i == 0) - pathType = "M"; - else - pathType = "L"; - - var targetX = anchor.x, targetY = anchor.y; - - // anti smoothing - if (this.strokeWidth%2 == 1) { - targetX += 0.5; - targetY += 0.5; - } - - path.push([pathType, targetX, targetY]); - } - if (this.closePath) - path.push(["Z"]); - - this.path = path; -}; \ No newline at end of file diff --git a/demo-shell-ng2/app/main.ts b/demo-shell-ng2/app/main.ts index d585676518..a60d89409f 100644 --- a/demo-shell-ng2/app/main.ts +++ b/demo-shell-ng2/app/main.ts @@ -16,7 +16,12 @@ */ import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { enableProdMode } from '@angular/core'; import { AppModule } from './app.module'; +if (process.env.ENV === 'production') { + enableProdMode(); +} + const platform = platformBrowserDynamic(); platform.bootstrapModule(AppModule); diff --git a/demo-shell-ng2/app/polyfills.ts b/demo-shell-ng2/app/polyfills.ts new file mode 100644 index 0000000000..d5be0fad92 --- /dev/null +++ b/demo-shell-ng2/app/polyfills.ts @@ -0,0 +1,16 @@ +import 'core-js/es6'; +import 'core-js/es7/reflect'; + +// IE 8-11 +require('zone.js/dist/zone'); + +if (process.env.ENV === 'production') { + // Production + +} else { + // Development + + Error['stackTraceLimit'] = Infinity; + + require('zone.js/dist/long-stack-trace-zone'); +} diff --git a/demo-shell-ng2/app/vendor.ts b/demo-shell-ng2/app/vendor.ts new file mode 100644 index 0000000000..f5333ae066 --- /dev/null +++ b/demo-shell-ng2/app/vendor.ts @@ -0,0 +1,60 @@ +// Angular +import '@angular/platform-browser'; +import '@angular/platform-browser-dynamic'; +import '@angular/core'; +import '@angular/common'; +import '@angular/http'; +import '@angular/router'; + +// RxJS +import 'rxjs'; + +//Alfresco +import 'ng2-alfresco-core'; +import 'ng2-alfresco-datatable'; +import 'ng2-activiti-diagrams'; +import 'ng2-activiti-analytics'; +import 'ng2-activiti-form'; +import 'ng2-activiti-processlist'; +import 'ng2-activiti-tasklist'; +import 'ng2-alfresco-documentlist'; +import 'ng2-alfresco-login'; +import 'ng2-alfresco-search'; +import 'ng2-alfresco-tag'; +import 'ng2-alfresco-upload'; +import 'ng2-alfresco-viewer'; +import 'ng2-alfresco-webscript'; +import 'ng2-alfresco-userinfo'; + +// Polyfill(s) for dialogs +require('script!dialog-polyfill/dialog-polyfill'); +import 'dialog-polyfill/dialog-polyfill.css'; + +// Flags +import 'flag-icon-css/css/flag-icon.min.css'; +import '../public/css/app.css'; +import '../public/css/muli-font.css'; + +import 'ng2-activiti-form/stencils/runtime.ng1'; +import 'ng2-activiti-form/stencils/runtime.adf'; + +import 'chart.js'; +require('script!raphael/raphael.min.js'); + +require('script!moment/min/moment.min.js'); + +import 'md-date-time-picker/dist/css/mdDateTimePicker.css'; +require('script!md-date-time-picker/dist/js/mdDateTimePicker.min.js'); +require('script!md-date-time-picker/dist/js/draggabilly.pkgd.min.js'); + +require('pdfjs-dist/web/compatibility.js'); + +// Setting worker path to worker bundle. +let pdfjsLib = require('pdfjs-dist'); +if (process.env.ENV === 'production') { + pdfjsLib.PDFJS.workerSrc = './pdf.worker.js'; +} else { + pdfjsLib.PDFJS.workerSrc = '../../node_modules/pdfjs-dist/build/pdf.worker.js'; +} + +require('pdfjs-dist/web/pdf_viewer.js'); diff --git a/demo-shell-ng2/config/helpers.js b/demo-shell-ng2/config/helpers.js new file mode 100644 index 0000000000..15dc4a5a46 --- /dev/null +++ b/demo-shell-ng2/config/helpers.js @@ -0,0 +1,7 @@ +var path = require('path'); +var _root = path.resolve(__dirname, '..'); +function root(args) { + args = Array.prototype.slice.call(arguments, 0); + return path.join.apply(path, [_root].concat(args)); +} +exports.root = root; diff --git a/demo-shell-ng2/config/karma-test-shim.js b/demo-shell-ng2/config/karma-test-shim.js new file mode 100644 index 0000000000..dc7798bb7e --- /dev/null +++ b/demo-shell-ng2/config/karma-test-shim.js @@ -0,0 +1,21 @@ +Error.stackTraceLimit = Infinity; + +require('core-js/es6'); +require('core-js/es7/reflect'); + +require('zone.js/dist/zone'); +require('zone.js/dist/long-stack-trace-zone'); +require('zone.js/dist/proxy'); +require('zone.js/dist/sync-test'); +require('zone.js/dist/jasmine-patch'); +require('zone.js/dist/async-test'); +require('zone.js/dist/fake-async-test'); + +var appContext = require.context('../app', true, /\.spec\.ts/); + +appContext.keys().forEach(appContext); + +var testing = require('@angular/core/testing'); +var browser = require('@angular/platform-browser-dynamic/testing'); + +testing.TestBed.initTestEnvironment(browser.BrowserDynamicTestingModule, browser.platformBrowserDynamicTesting()); diff --git a/demo-shell-ng2/config/karma.conf.js b/demo-shell-ng2/config/karma.conf.js new file mode 100644 index 0000000000..f54d084542 --- /dev/null +++ b/demo-shell-ng2/config/karma.conf.js @@ -0,0 +1,37 @@ +var webpackConfig = require('./webpack.test'); + +module.exports = function (config) { + var _config = { + basePath: '', + + frameworks: ['jasmine'], + + files: [ + { pattern: './config/karma-test-shim.js', watched: false } + ], + + preprocessors: { + './config/karma-test-shim.js': ['webpack', 'sourcemap'] + }, + + webpack: webpackConfig, + + webpackMiddleware: { + stats: 'errors-only' + }, + + webpackServer: { + noInfo: true + }, + + reporters: ['mocha'], + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + autoWatch: false, + browsers: ['PhantomJS'], + singleRun: true + }; + + config.set(_config); +}; diff --git a/demo-shell-ng2/config/loaders/debug.js b/demo-shell-ng2/config/loaders/debug.js new file mode 100644 index 0000000000..841cccf223 --- /dev/null +++ b/demo-shell-ng2/config/loaders/debug.js @@ -0,0 +1,5 @@ +module.exports = function(source) { + this.cacheable(); + console.log(this.resource); + return source; +} diff --git a/demo-shell-ng2/config/loaders/system.js b/demo-shell-ng2/config/loaders/system.js new file mode 100644 index 0000000000..3e3e4aa3b6 --- /dev/null +++ b/demo-shell-ng2/config/loaders/system.js @@ -0,0 +1,27 @@ +const moduleIdRegex = /moduleId: module.id,/g; +const moduleNameRegex = /moduleId: __moduleName,/g; +const moduleIdPath = /module.id.replace/g; + +module.exports = function(source) { + this.cacheable(); + + if (moduleIdRegex.test(source)) { + source = source.replace(moduleIdRegex, (match) => { + return `// ${match}`; + }); + } + + if (moduleNameRegex.test(source)) { + source = source.replace(moduleNameRegex, (match) => { + return `// ${match}`; + }); + } + + if (moduleIdPath.test(source)) { + source = source.replace(moduleIdPath, (match) => { + return `''.replace`; + }); + } + + return source; +} diff --git a/demo-shell-ng2/config/webpack.common.js b/demo-shell-ng2/config/webpack.common.js new file mode 100644 index 0000000000..21c6fc688b --- /dev/null +++ b/demo-shell-ng2/config/webpack.common.js @@ -0,0 +1,213 @@ +var webpack = require('webpack'); +var HtmlWebpackPlugin = require('html-webpack-plugin'); +var ExtractTextPlugin = require('extract-text-webpack-plugin'); +var helpers = require('./helpers'); +var path = require('path'); +var fs = require('fs'); +var glob = require('glob'); +var CopyWebpackPlugin = require('copy-webpack-plugin'); + +const rootPath = helpers.root('node_modules'); + +let pattern = '+(alfresco-js-api|ng2-alfresco|ng2-activiti)*'; +let options = { + cwd: rootPath, + realpath: true +}; + +let alfrescoLibs = glob.sync(pattern, options); +// console.dir(alfrescoLibs); + +module.exports = { + entry: { + 'polyfills': './app/polyfills.ts', + 'vendor': './app/vendor.ts', + 'app': './app/main.ts' + }, + + resolve: { + extensions: ['', '.ts', '.js'], + modules: [ + helpers.root('app'), + helpers.root('node_modules') + ], + root: rootPath, + fallback: rootPath + }, + + resolveLoader: { + alias: { + 'systemjs-loader': helpers.root('config', 'loaders', 'system.js'), + 'debug-loader': helpers.root('config', 'loaders', 'debug.js') + }, + fallback: rootPath + }, + module: { + preLoaders: [ + { + test: /\.js$/, + include: [ + ...alfrescoLibs + ], + loader: 'source-map-loader' + } + ], + loaders: [ + { + test: /\.ts$/, + loaders: ['awesome-typescript-loader', 'angular2-template-loader', 'systemjs-loader'], + exclude: ['node_modules','public'] + }, + { + test: /\.js$/, + include: [ + ...alfrescoLibs + ], + loaders: ['angular2-template-loader', 'source-map-loader', 'systemjs-loader'] + }, + { + test: /\.html$/, + exclude: alfrescoLibs, + loader: 'html' + }, + { + test: /\.html$/, + include: alfrescoLibs, + loader: 'html', + query: { + interpolate: true + } + }, + { + test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/, + loader: 'file?name=assets/[name].[hash].[ext]' + }, + { + test: /\.css$/, + exclude: [ + helpers.root('app'), + ...alfrescoLibs + ], + loader: ExtractTextPlugin.extract('style', 'css?sourceMap') + }, + { + test: /\.css$/, + include: [ + helpers.root('app'), + ...alfrescoLibs + ], + loader: 'raw' + } + ] + }, + + plugins: [ + + new webpack.WatchIgnorePlugin([ new RegExp('^((?!(ng2-activiti|ng2-alfresco|demo-shell-ng2)).)((?!(src|app)).)*$')]), + + new CopyWebpackPlugin([ + { + from: 'versions.json' + },{ + context: 'node_modules', + from: 'element.scrollintoviewifneeded-polyfill/index.js', + to: 'js/element.scrollintoviewifneeded-polyfill.js', + flatten: true + },{ + context: 'node_modules', + from: 'classlist-polyfill/src/index.js', + to: 'js/classlist-polyfill.js', + flatten: true + }, { + context: 'node_modules', + from: 'intl/dist/Intl.min.js', + to: 'js/Intl.min.js', + flatten: true + }, { + context: 'node_modules', + from: 'web-animations-js/web-animations.min.js', + to: 'js/web-animations.min.js', + flatten: true + }, { + context: 'node_modules', + from: 'core-js/client/shim.min.js', + to: 'js/shim.min.js', + flatten: true + }, { + context: 'node_modules', + from: 'es6-shim/es6-shim.min.js', + to: 'js/es6-shim.min.js', + flatten: true + }, { + context: 'node_modules', + from: 'es5-shim/es5-shim.min.js', + to: 'js/es5-shim.min.js', + flatten: true + }, { + context: 'node_modules', + from: 'systemjs/dist/system-polyfills.js', + to: 'js/system-polyfills.js', + flatten: true + }, { + context: 'node_modules', + from: 'material-design-lite/material.min.js', + to: 'js/material.min.js', + flatten: true + }, { + context: 'node_modules', + from: 'material-design-lite/material.min.js', + to: 'js/material.min.js', + flatten: true + }, { + context: 'public', + from: 'css/material.orange-blue.min.css', + to: 'css/material.orange-blue.min.css', + flatten: true + }, { + context: 'node_modules', + from: 'material-design-icons/iconfont/', + to: 'css/iconfont/', + flatten: true + }, { + context: 'public', + from: 'js/typedarray.js', + to: 'js/typedarray.js', + flatten: true + }, { + context: 'public', + from: 'js/Blob.js', + to: 'js/Blob.js', + flatten: true + }, { + context: 'public', + from: 'js/formdata.js', + to: 'js/formdata.js', + flatten: true + }, { + context: 'public', + from: 'js/promisePolyfill.js', + to: 'js/promisePolyfill.js', + flatten: true + }, { + context: 'public', + from: 'css/muli-font.css', + to: 'css/muli-font.css', + flatten: true + } + + ]), + + new webpack.optimize.CommonsChunkPlugin({ + name: ['app', 'vendor', 'polyfills'] + }), + + new HtmlWebpackPlugin({ + template: 'index.html' + }) + ], + + node: { + fs: 'empty', + module: false + } +}; diff --git a/demo-shell-ng2/config/webpack.dev.js b/demo-shell-ng2/config/webpack.dev.js new file mode 100644 index 0000000000..40a565e070 --- /dev/null +++ b/demo-shell-ng2/config/webpack.dev.js @@ -0,0 +1,66 @@ +var webpackMerge = require('webpack-merge'); +var ExtractTextPlugin = require('extract-text-webpack-plugin'); +var commonConfig = require('./webpack.common.js'); +var helpers = require('./helpers'); +var CopyWebpackPlugin = require('copy-webpack-plugin'); + +module.exports = webpackMerge(commonConfig, { + + devtool: 'cheap-module-eval-source-map', + + output: { + path: helpers.root('dist'), + publicPath: 'http://localhost:3000/', + filename: '[name].js', + chunkFilename: '[id].chunk.js' + }, + + plugins: [ + new ExtractTextPlugin('[name].css'), + new CopyWebpackPlugin([ + { + from: 'favicon-96x96.png' + }, + { + from: 'node_modules/pdfjs-dist/build/pdf.worker.js', + to: 'pdf.worker.js' + }, + { + context: 'custom-translation', + from: '**/*.json', + to: 'i18n/custom-translation' + }, + // Copy i18n folders for all modules with ng2-alfresco- prefix + { + context: 'node_modules', + from: 'ng2-alfresco-*/src/i18n/*.json', + to: 'node_modules' + }, + // Copy i18n folders for all modules with ng2-activiti- prefix + { + context: 'node_modules', + from: 'ng2-activiti-*/src/i18n/*.json', + to: 'node_modules' + }, + // Copy asstes folders for all modules with ng2-activiti- prefix + { + context: 'node_modules', + from: 'ng2-activiti-*/src/assets/images/*.*', + to: 'assets/images', + flatten: true + }, + // Copy asstes folders for all modules with ng2-alfresco- prefix + { + context: 'node_modules', + from: 'ng2-alfresco-*/src/assets/images/*.*', + to: 'assets/images', + flatten: true + } + ]) + ], + + devServer: { + historyApiFallback: true, + stats: 'minimal' + } +}); diff --git a/demo-shell-ng2/config/webpack.prod.js b/demo-shell-ng2/config/webpack.prod.js new file mode 100644 index 0000000000..14e0493451 --- /dev/null +++ b/demo-shell-ng2/config/webpack.prod.js @@ -0,0 +1,101 @@ +var webpack = require('webpack'); +var webpackMerge = require('webpack-merge'); +var ExtractTextPlugin = require('extract-text-webpack-plugin'); +var CopyWebpackPlugin = require('copy-webpack-plugin'); +var commonConfig = require('./webpack.common.js'); +var helpers = require('./helpers'); + +const ENV = process.env.NODE_ENV = process.env.ENV = 'production'; + +module.exports = webpackMerge(commonConfig, { + devtool: 'source-map', + + output: { + path: helpers.root('dist'), + publicPath: '/', + filename: '[name].[hash].js', + chunkFilename: '[id].[hash].chunk.js' + }, + + htmlLoader: { + minimize: false // workaround for ng2 + }, + + plugins: [ + // Define env variables to help with builds + // Reference: https://webpack.github.io/docs/list-of-plugins.html#defineplugin + new webpack.DefinePlugin({ + 'process.env': { + 'ENV': JSON.stringify(ENV) + } + }), + + // Reference: http://webpack.github.io/docs/list-of-plugins.html#noerrorsplugin + // Only emit files when there are no errors + new webpack.NoErrorsPlugin(), + + // Reference: http://webpack.github.io/docs/list-of-plugins.html#dedupeplugin + // Dedupe modules in the output + new webpack.optimize.DedupePlugin(), + + // Reference: http://webpack.github.io/docs/list-of-plugins.html#uglifyjsplugin + // Minify all javascript, switch loaders to minimizing mode + new webpack.optimize.UglifyJsPlugin({ // https://github.com/angular/angular/issues/10618 + mangle: { + keep_fnames: true + }, + compressor: { + screw_ie8: true, + warnings: false + } + }), + + // Extract css files + // Reference: https://github.com/webpack/extract-text-webpack-plugin + // Disabled when in test mode or not in build mode + new ExtractTextPlugin('[name].[hash].css'), + + // Copy assets from the public folder + // Reference: https://github.com/kevlened/copy-webpack-plugin + new CopyWebpackPlugin([ + { + from: 'favicon-96x96.png' + }, + { + from: 'node_modules/pdfjs-dist/build/pdf.worker.js', + to: 'pdf.worker.js' + }, + { + context: 'custom-translation', + from: '**/*.json', + to: 'i18n/custom-translation' + }, + // Copy i18n folders for all modules with ng2-alfresco- prefix + { + context: 'node_modules', + from: 'ng2-alfresco-*/src/i18n/*.json', + to: 'node_modules' + }, + // Copy i18n folders for all modules with ng2-activiti- prefix + { + context: 'node_modules', + from: 'ng2-activiti-*/src/i18n/*.json', + to: 'node_modules' + }, + // Copy asstes folders for all modules with ng2-activiti- prefix + { + context: 'node_modules', + from: 'ng2-activiti-*/src/assets/images/*.*', + to: 'assets/images', + flatten : true + }, + // Copy asstes folders for all modules with ng2-alfresco- prefix + { + context: 'node_modules', + from: 'ng2-alfresco-*/src/assets/images/*.*', + to: 'assets/images', + flatten : true + } + ]) + ] +}); diff --git a/demo-shell-ng2/config/webpack.test.js b/demo-shell-ng2/config/webpack.test.js new file mode 100644 index 0000000000..d1f6c28a87 --- /dev/null +++ b/demo-shell-ng2/config/webpack.test.js @@ -0,0 +1,70 @@ +var helpers = require('./helpers'); +var fs = require('fs'); +var ExtractTextPlugin = require('extract-text-webpack-plugin'); +var glob = require('glob'); + +const rootPath = helpers.root('node_modules'); + +let pattern = '+(alfresco-js-api|ng2-alfresco|ng2-activiti)*'; +let options = { + cwd: rootPath, + realpath: true +}; + +let alfrescoLibs = glob.sync(pattern, options); + +module.exports = { + devtool: 'inline-source-map', + + resolve: { + extensions: ['', '.ts', '.js'], + modules: [ + helpers.root('app'), + helpers.root('node_modules') + ], + root: rootPath, + fallback: rootPath + }, + + resolveLoader: { + alias: { + 'systemjs-loader': helpers.root('config', 'loaders', 'system.js') + }, + fallback: rootPath + }, + + module: { + loaders: [ + { + test: /\.ts$/, + exclude: /node_modules/, + loaders: ['awesome-typescript-loader', 'angular2-template-loader'] + }, + { + test: /\.js$/, + include: [ + ...alfrescoLibs + ], + loaders: ['angular2-template-loader', 'source-map-loader', 'systemjs-loader'] + }, + { + test: /\.html$/, + loader: 'html' + + }, + { + test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/, + loader: 'null' + }, + { + test: /\.css$/, + loader: 'raw' + } + ] + }, + + node: { + fs: 'empty', + module: false + } +} diff --git a/demo-shell-ng2/index.html b/demo-shell-ng2/index.html index 2fe2040a7f..e8f703cec7 100644 --- a/demo-shell-ng2/index.html +++ b/demo-shell-ng2/index.html @@ -5,69 +5,52 @@ Demo Application - Angular 2 - - - - - - - - - - - - - - + - - - - + - - - + + + + - - - - - - - - - - - - - + - -
-
-
-
Loading Demo Shell..
-
-
-
+ +
+
+
+
Loading Demo Shell..
+
+
+
+ diff --git a/demo-shell-ng2/karma.conf.js b/demo-shell-ng2/karma.conf.js new file mode 100644 index 0000000000..9649b15661 --- /dev/null +++ b/demo-shell-ng2/karma.conf.js @@ -0,0 +1 @@ +module.exports = require('./config/karma.conf.js'); diff --git a/demo-shell-ng2/package.json b/demo-shell-ng2/package.json index f29185d008..ce2e1f0464 100644 --- a/demo-shell-ng2/package.json +++ b/demo-shell-ng2/package.json @@ -1,18 +1,17 @@ { "name": "Alfresco-Angular2-Demo", "description": "Demo shell for Alfresco Angular2 components", - "version": "0.5.0", + "version": "1.0.0", "author": "Alfresco Software, Ltd.", "scripts": { - "clean": "npm install rimraf && rimraf dist node_modules typings", - "build": "npm run tslint && npm run tsc && npm run licensecheck", - "start": "npm run build && npm run serve", - "start:dev": "npm run build && concurrently \"npm run tsc:w\" \"npm run serve:dev\" ", + "clean": "npm install rimraf && npm run clean-build && rimraf dist node_modules typings dist", + "start": "npm run server-versions && webpack-dev-server --inline --progress --port 3000 --max_old_space_size=4096 --max_new_space_size=4096", + "start:dist": "wsrv -s dist/ -p 3000 -a 0.0.0.0", + "clean-build": "rimraf 'app/{,**/}**.js' 'app/{,**/}**.js.map' 'app/{,**/}**.d.ts'", + "test": "karma start", + "build": "npm run server-versions && rimraf dist && webpack --config config/webpack.prod.js --progress --profile --bail", + "server-versions": "rimraf versions.json && npm list --depth=0 --json=true --prod=true > versions.json || true", "aws": "node app.js", - "tsc": "tsc", - "tsc:w": "tsc -w", - "serve": "wsrv -O http://localhost:3000 -s -p 3000 -a 0.0.0.0 -x ./server/versions.js", - "serve:dev": "wsrv -O http://localhost:3000 -s -l -p 3000 -a 0.0.0.0 -x ./server/versions.js", "tslint": "tslint -c tslint.json *.ts && tslint -c tslint.json 'app/{,**/}**.ts'", "licensecheck": "license-check" }, @@ -53,61 +52,88 @@ "alfresco" ], "dependencies": { - "@angular/common": "2.0.0", - "@angular/compiler": "2.0.0", - "@angular/core": "2.0.0", - "@angular/forms": "2.0.0", - "@angular/http": "2.0.0", - "@angular/platform-browser": "2.0.0", - "@angular/platform-browser-dynamic": "2.0.0", - "@angular/router": "3.0.0", - "@angular/upgrade": "2.0.0", - "@types/node": "^6.0.42", - "core-js": "^2.4.1", - "reflect-metadata": "^0.1.3", - "rxjs": "5.0.0-beta.12", + "@angular/common": "2.2.2", + "@angular/compiler": "2.2.2", + "@angular/compiler-cli": "2.2.2", + "@angular/core": "2.2.2", + "@angular/forms": "2.2.2", + "@angular/http": "2.2.2", + "@angular/platform-browser": "2.2.2", + "@angular/platform-browser-dynamic": "2.2.2", + "@angular/router": "3.2.2", + "@angular/upgrade": "2.2.2", "systemjs": "0.19.27", + "core-js": "^2.4.1", + "reflect-metadata": "^0.1.8", + "rxjs": "5.0.0-beta.12", "zone.js": "^0.6.23", - - "rimraf": "2.5.2", "material-design-icons": "2.2.3", "material-design-lite": "1.2.1", "ng2-translate": "2.5.0", "pdfjs-dist": "1.5.404", "flag-icon-css": "2.3.0", - "intl": "1.2.4", "moment": "2.15.1", "chart.js": "^2.1.4", "ng2-charts": "1.1.0", "raphael": "^2.2.6", "md-date-time-picker": "^2.2.0", - "alfresco-js-api": "^0.5.0", - "ng2-activiti-analytics": "0.5.0", - "ng2-alfresco-core": "0.5.0", - "ng2-alfresco-datatable": "0.5.0", - "ng2-alfresco-documentlist": "0.5.0", - "ng2-alfresco-login": "0.5.0", - "ng2-alfresco-search": "0.5.0", - "ng2-alfresco-upload": "0.5.0", - "ng2-alfresco-viewer": "0.5.0", - "ng2-activiti-form": "0.5.0", - "ng2-activiti-tasklist": "0.5.0", - "ng2-alfresco-userinfo": "0.5.0", - "ng2-activiti-processlist": "0.5.0", - "ng2-alfresco-webscript": "0.5.0", - "ng2-alfresco-tag": "0.5.0", + "alfresco-js-api": "^1.0.0", + "ng2-activiti-analytics": "1.0.0", + "ng2-alfresco-core": "1.0.0", + "ng2-alfresco-datatable": "1.0.0", + "ng2-alfresco-documentlist": "1.0.0", + "ng2-alfresco-login": "1.0.0", + "ng2-alfresco-search": "1.0.0", + "ng2-alfresco-upload": "1.0.0", + "ng2-alfresco-viewer": "1.0.0", + "ng2-activiti-form": "1.0.0", + "ng2-activiti-tasklist": "1.0.0", + "ng2-alfresco-userinfo": "1.0.0", + "ng2-activiti-processlist": "1.0.0", + "ng2-alfresco-webscript": "1.0.0", + "ng2-alfresco-tag": "1.0.0", "dialog-polyfill": "^0.4.3", "element.scrollintoviewifneeded-polyfill": "^1.0.1" }, "devDependencies": { - "@types/core-js": "^0.9.32", - "@types/jasmine": "^2.2.33", - "concurrently": "^2.2.0", + "@types/jasmine": "^2.5.35", + "@types/node": "^6.0.45", + "angular2-template-loader": "^0.6.0", + "awesome-typescript-loader": "^2.2.4", + "classlist-polyfill": "^1.0.3", + "copy-webpack-plugin": "^4.0.1", + "css-loader": "^0.23.1", + "es5-shim": "^4.5.9", + "es6-shim": "^0.35.2", + "extract-text-webpack-plugin": "^1.0.1", + "file-loader": "^0.8.5", + "glob": "^7.1.1", + "html-loader": "^0.4.3", + "html-webpack-plugin": "^2.15.0", + "intl": "^1.2.5", + "jasmine-core": "^2.4.1", + "karma": "^1.2.0", + "karma-jasmine": "^1.0.2", + "karma-mocha-reporter": "^2.2.1", + "karma-phantomjs-launcher": "^1.0.2", + "karma-sourcemap-loader": "^0.3.7", + "karma-webpack": "^1.8.0", "license-check": "1.1.5", "mime": "^1.3.4", + "null-loader": "^0.1.1", + "phantomjs-prebuilt": "^2.1.7", + "raw-loader": "^0.5.1", + "rimraf": "^2.5.2", + "script-loader": "^0.7.0", + "source-map-loader": "^0.1.5", + "style-loader": "^0.13.1", "tslint": "3.15.1", - "typescript": "^2.0.3", - "wsrv": "^0.1.5" + "typescript": "2.0.3", + "web-animations-js": "^2.2.2", + "webpack": "^1.13.0", + "webpack-dev-server": "^1.14.1", + "webpack-merge": "^0.14.0", + "wsrv": "^0.1.6" }, "license-check-config": { "src": [ diff --git a/demo-shell-ng2/app/css/app.css b/demo-shell-ng2/public/css/app.css similarity index 100% rename from demo-shell-ng2/app/css/app.css rename to demo-shell-ng2/public/css/app.css diff --git a/demo-shell-ng2/assets/material.orange-blue.min.css b/demo-shell-ng2/public/css/material.orange-blue.min.css similarity index 100% rename from demo-shell-ng2/assets/material.orange-blue.min.css rename to demo-shell-ng2/public/css/material.orange-blue.min.css diff --git a/demo-shell-ng2/app/css/muli-font.css b/demo-shell-ng2/public/css/muli-font.css similarity index 100% rename from demo-shell-ng2/app/css/muli-font.css rename to demo-shell-ng2/public/css/muli-font.css diff --git a/demo-shell-ng2/app/fonts/Muli-Italic.ttf b/demo-shell-ng2/public/fonts/Muli-Italic.ttf similarity index 100% rename from demo-shell-ng2/app/fonts/Muli-Italic.ttf rename to demo-shell-ng2/public/fonts/Muli-Italic.ttf diff --git a/demo-shell-ng2/app/fonts/Muli-Light.ttf b/demo-shell-ng2/public/fonts/Muli-Light.ttf similarity index 100% rename from demo-shell-ng2/app/fonts/Muli-Light.ttf rename to demo-shell-ng2/public/fonts/Muli-Light.ttf diff --git a/demo-shell-ng2/app/fonts/Muli-LightItalic.ttf b/demo-shell-ng2/public/fonts/Muli-LightItalic.ttf similarity index 100% rename from demo-shell-ng2/app/fonts/Muli-LightItalic.ttf rename to demo-shell-ng2/public/fonts/Muli-LightItalic.ttf diff --git a/demo-shell-ng2/app/fonts/Muli-Regular.ttf b/demo-shell-ng2/public/fonts/Muli-Regular.ttf similarity index 100% rename from demo-shell-ng2/app/fonts/Muli-Regular.ttf rename to demo-shell-ng2/public/fonts/Muli-Regular.ttf diff --git a/demo-shell-ng2/public/js/Blob.js b/demo-shell-ng2/public/js/Blob.js new file mode 100644 index 0000000000..bd41a44806 --- /dev/null +++ b/demo-shell-ng2/public/js/Blob.js @@ -0,0 +1,211 @@ +/* Blob.js + * A Blob implementation. + * 2014-07-24 + * + * By Eli Grey, http://eligrey.com + * By Devin Samarin, https://github.com/dsamarin + * License: MIT + * See https://github.com/eligrey/Blob.js/blob/master/LICENSE.md + */ + +/*global self, unescape */ +/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true, + plusplus: true */ + +/*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */ + +(function (view) { + "use strict"; + + view.URL = view.URL || view.webkitURL; + + if (view.Blob && view.URL) { + try { + new Blob; + return; + } catch (e) {} + } + + // Internally we use a BlobBuilder implementation to base Blob off of + // in order to support older browsers that only have BlobBuilder + var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || (function(view) { + var + get_class = function(object) { + return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1]; + } + , FakeBlobBuilder = function BlobBuilder() { + this.data = []; + } + , FakeBlob = function Blob(data, type, encoding) { + this.data = data; + this.size = data.length; + this.type = type; + this.encoding = encoding; + } + , FBB_proto = FakeBlobBuilder.prototype + , FB_proto = FakeBlob.prototype + , FileReaderSync = view.FileReaderSync + , FileException = function(type) { + this.code = this[this.name = type]; + } + , file_ex_codes = ( + "NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR " + + "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR" + ).split(" ") + , file_ex_code = file_ex_codes.length + , real_URL = view.URL || view.webkitURL || view + , real_create_object_URL = real_URL.createObjectURL + , real_revoke_object_URL = real_URL.revokeObjectURL + , URL = real_URL + , btoa = view.btoa + , atob = view.atob + + , ArrayBuffer = view.ArrayBuffer + , Uint8Array = view.Uint8Array + + , origin = /^[\w-]+:\/*\[?[\w\.:-]+\]?(?::[0-9]+)?/ + ; + FakeBlob.fake = FB_proto.fake = true; + while (file_ex_code--) { + FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1; + } + // Polyfill URL + if (!real_URL.createObjectURL) { + URL = view.URL = function(uri) { + var + uri_info = document.createElementNS("http://www.w3.org/1999/xhtml", "a") + , uri_origin + ; + uri_info.href = uri; + if (!("origin" in uri_info)) { + if (uri_info.protocol.toLowerCase() === "data:") { + uri_info.origin = null; + } else { + uri_origin = uri.match(origin); + uri_info.origin = uri_origin && uri_origin[1]; + } + } + return uri_info; + }; + } + URL.createObjectURL = function(blob) { + var + type = blob.type + , data_URI_header + ; + if (type === null) { + type = "application/octet-stream"; + } + if (blob instanceof FakeBlob) { + data_URI_header = "data:" + type; + if (blob.encoding === "base64") { + return data_URI_header + ";base64," + blob.data; + } else if (blob.encoding === "URI") { + return data_URI_header + "," + decodeURIComponent(blob.data); + } if (btoa) { + return data_URI_header + ";base64," + btoa(blob.data); + } else { + return data_URI_header + "," + encodeURIComponent(blob.data); + } + } else if (real_create_object_URL) { + return real_create_object_URL.call(real_URL, blob); + } + }; + URL.revokeObjectURL = function(object_URL) { + if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) { + real_revoke_object_URL.call(real_URL, object_URL); + } + }; + FBB_proto.append = function(data/*, endings*/) { + var bb = this.data; + // decode data to a binary string + if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) { + var + str = "" + , buf = new Uint8Array(data) + , i = 0 + , buf_len = buf.length + ; + for (; i < buf_len; i++) { + str += String.fromCharCode(buf[i]); + } + bb.push(str); + } else if (get_class(data) === "Blob" || get_class(data) === "File") { + if (FileReaderSync) { + var fr = new FileReaderSync; + bb.push(fr.readAsBinaryString(data)); + } else { + // async FileReader won't work as BlobBuilder is sync + throw new FileException("NOT_READABLE_ERR"); + } + } else if (data instanceof FakeBlob) { + if (data.encoding === "base64" && atob) { + bb.push(atob(data.data)); + } else if (data.encoding === "URI") { + bb.push(decodeURIComponent(data.data)); + } else if (data.encoding === "raw") { + bb.push(data.data); + } + } else { + if (typeof data !== "string") { + data += ""; // convert unsupported types to strings + } + // decode UTF-16 to binary string + bb.push(unescape(encodeURIComponent(data))); + } + }; + FBB_proto.getBlob = function(type) { + if (!arguments.length) { + type = null; + } + return new FakeBlob(this.data.join(""), type, "raw"); + }; + FBB_proto.toString = function() { + return "[object BlobBuilder]"; + }; + FB_proto.slice = function(start, end, type) { + var args = arguments.length; + if (args < 3) { + type = null; + } + return new FakeBlob( + this.data.slice(start, args > 1 ? end : this.data.length) + , type + , this.encoding + ); + }; + FB_proto.toString = function() { + return "[object Blob]"; + }; + FB_proto.close = function() { + this.size = 0; + delete this.data; + }; + return FakeBlobBuilder; + }(view)); + + view.Blob = function(blobParts, options) { + var type = options ? (options.type || "") : ""; + var builder = new BlobBuilder(); + if (blobParts) { + for (var i = 0, len = blobParts.length; i < len; i++) { + if (Uint8Array && blobParts[i] instanceof Uint8Array) { + builder.append(blobParts[i].buffer); + } + else { + builder.append(blobParts[i]); + } + } + } + var blob = builder.getBlob(type); + if (!blob.slice && blob.webkitSlice) { + blob.slice = blob.webkitSlice; + } + return blob; + }; + + var getPrototypeOf = Object.getPrototypeOf || function(object) { + return object.__proto__; + }; + view.Blob.prototype = getPrototypeOf(new view.Blob()); +}(typeof self !== "undefined" && self || typeof window !== "undefined" && window || this.content || this)); diff --git a/demo-shell-ng2/public/js/formdata.js b/demo-shell-ng2/public/js/formdata.js new file mode 100644 index 0000000000..4eabc4815b --- /dev/null +++ b/demo-shell-ng2/public/js/formdata.js @@ -0,0 +1,37 @@ +/** + * Emulate FormData for some browsers + * MIT License + * (c) 2010 François de Metz + */ +(function(w) { + if (w.FormData) + return; + function FormData() { + this.fake = true; + this.boundary = "--------FormData" + Math.random(); + this._fields = []; + } + FormData.prototype.append = function(key, value) { + this._fields.push([key, value]); + } + FormData.prototype.toString = function() { + var boundary = this.boundary; + var body = ""; + this._fields.forEach(function(field) { + body += "--" + boundary + "\r\n"; + // file upload + if (field[1].name) { + var file = field[1]; + body += "Content-Disposition: form-data; name=\""+ field[0] +"\"; filename=\""+ file.name +"\"\r\n"; + body += "Content-Type: "+ file.type +"\r\n\r\n"; + body += file.getAsBinary() + "\r\n"; + } else { + body += "Content-Disposition: form-data; name=\""+ field[0] +"\";\r\n\r\n"; + body += field[1] + "\r\n"; + } + }); + body += "--" + boundary +"--"; + return body; + } + w.FormData = FormData; +})(window); diff --git a/demo-shell-ng2/public/js/promisePolyfill.js b/demo-shell-ng2/public/js/promisePolyfill.js new file mode 100644 index 0000000000..ef7bf2e267 --- /dev/null +++ b/demo-shell-ng2/public/js/promisePolyfill.js @@ -0,0 +1,3 @@ +/* Disable minification (remove `.min` from URL path) for more info */ + +(function(undefined) {if (!('Symbol' in this && 'iterator' in this.Symbol && !!Array.prototype[Symbol.iterator] && !!Array.prototype.values && (Array.prototype[Symbol.iterator] === Array.prototype.values))) {Object.defineProperty(Array.prototype,"values",{value:Array.prototype[Symbol.iterator],enumerable:!1,writable:!1});}if (!('contains' in String.prototype)) {String.prototype.contains=String.prototype.includes;}var ArrayIterator=function(){var e=function(){var e=function(){return this.length=0,this},t=function(e){if("function"!=typeof e)throw new TypeError(e+" is not a function");return e},_=function(e,n){return this instanceof _?(Object.defineProperties(this,{__list__:{writable:!0,value:e},__context__:{writable:!0,value:n},__nextIndex__:{writable:!0,value:0}}),void(n&&(t(n.on),n.on("_add",this._onAdd.bind(this)),n.on("_delete",this._onDelete.bind(this)),n.on("_clear",this._onClear.bind(this))))):new _(e,n)};return Object.defineProperties(_.prototype,Object.assign({constructor:{value:_,configurable:!0,enumerable:!1,writable:!0},_next:{value:function(){var e;if(this.__list__)return this.__redo__&&(e=this.__redo__.shift(),void 0!==e)?e:this.__nextIndex__=this.__nextIndex__)){if(++this.__nextIndex__,!this.__redo__)return void Object.defineProperty(this,"__redo__",{value:[e],configurable:!0,enumerable:!1,writable:!1});this.__redo__.forEach(function(t,_){t>=e&&(this.__redo__[_]=++t)},this),this.__redo__.push(e)}},configurable:!0,enumerable:!1,writable:!0},_onDelete:{value:function(e){var t;e>=this.__nextIndex__||(--this.__nextIndex__,this.__redo__&&(t=this.__redo__.indexOf(e),t!==-1&&this.__redo__.splice(t,1),this.__redo__.forEach(function(t,_){t>e&&(this.__redo__[_]=--t)},this)))},configurable:!0,enumerable:!1,writable:!0},_onClear:{value:function(){this.__redo__&&e.call(this.__redo__),this.__nextIndex__=0},configurable:!0,enumerable:!1,writable:!0}})),Object.defineProperty(_.prototype,Symbol.iterator,{value:function(){return this},configurable:!0,enumerable:!1,writable:!0}),Object.defineProperty(_.prototype,Symbol.toStringTag,{value:"Iterator",configurable:!1,enumerable:!1,writable:!1}),_}(),t=function(_,n){return this instanceof t?(e.call(this,_),n=n?String.prototype.contains.call(n,"key+value")?"key+value":String.prototype.contains.call(n,"key")?"key":"value":"value",void Object.defineProperty(this,"__kind__",{value:n,configurable:!1,enumerable:!1,writable:!1})):new t(_,n)};return Object.setPrototypeOf&&Object.setPrototypeOf(t,e.prototype),t.prototype=Object.create(e.prototype,{constructor:{value:t,configurable:!0,enumerable:!1,writable:!0},_resolve:{value:function(e){return"value"===this.__kind__?this.__list__[e]:"key+value"===this.__kind__?[e,this.__list__[e]]:e},configurable:!0,enumerable:!1,writable:!0},toString:{value:function(){return"[object Array Iterator]"},configurable:!0,enumerable:!1,writable:!0}}),t}();}).call('object' === typeof window && window || 'object' === typeof self && self || 'object' === typeof global && global || {}); diff --git a/demo-shell-ng2/public/js/typedarray.js b/demo-shell-ng2/public/js/typedarray.js new file mode 100644 index 0000000000..3d9fafd437 --- /dev/null +++ b/demo-shell-ng2/public/js/typedarray.js @@ -0,0 +1,1048 @@ +/* + Copyright (c) 2010, Linden Research, Inc. + Copyright (c) 2014, Joshua Bell + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + $/LicenseInfo$ + */ + +// Original can be found at: +// https://bitbucket.org/lindenlab/llsd +// Modifications by Joshua Bell inexorabletash@gmail.com +// https://github.com/inexorabletash/polyfill + +// ES3/ES5 implementation of the Krhonos Typed Array Specification +// Ref: http://www.khronos.org/registry/typedarray/specs/latest/ +// Date: 2011-02-01 +// +// Variations: +// * Allows typed_array.get/set() as alias for subscripts (typed_array[]) +// * Gradually migrating structure from Khronos spec to ES2015 spec +// +// Caveats: +// * Beyond 10000 or so entries, polyfilled array accessors (ta[0], +// etc) become memory-prohibitive, so array creation will fail. Set +// self.TYPED_ARRAY_POLYFILL_NO_ARRAY_ACCESSORS=true to disable +// creation of accessors. Your code will need to use the +// non-standard get()/set() instead, and will need to add those to +// native arrays for interop. +(function(global) { + 'use strict'; + var undefined = (void 0); // Paranoia + + // Beyond this value, index getters/setters (i.e. array[0], array[1]) are so slow to + // create, and consume so much memory, that the browser appears frozen. + var MAX_ARRAY_LENGTH = 1e5; + + // Approximations of internal ECMAScript conversion functions + function Type(v) { + switch(typeof v) { + case 'undefined': return 'undefined'; + case 'boolean': return 'boolean'; + case 'number': return 'number'; + case 'string': return 'string'; + default: return v === null ? 'null' : 'object'; + } + } + + // Class returns internal [[Class]] property, used to avoid cross-frame instanceof issues: + function Class(v) { return Object.prototype.toString.call(v).replace(/^\[object *|\]$/g, ''); } + function IsCallable(o) { return typeof o === 'function'; } + function ToObject(v) { + if (v === null || v === undefined) throw TypeError(); + return Object(v); + } + function ToInt32(v) { return v >> 0; } + function ToUint32(v) { return v >>> 0; } + + // Snapshot intrinsics + var LN2 = Math.LN2, + abs = Math.abs, + floor = Math.floor, + log = Math.log, + max = Math.max, + min = Math.min, + pow = Math.pow, + round = Math.round; + + // emulate ES5 getter/setter API using legacy APIs + // http://blogs.msdn.com/b/ie/archive/2010/09/07/transitioning-existing-code-to-the-es5-getter-setter-apis.aspx + // (second clause tests for Object.defineProperty() in IE<9 that only supports extending DOM prototypes, but + // note that IE<9 does not support __defineGetter__ or __defineSetter__ so it just renders the method harmless) + + (function() { + var orig = Object.defineProperty; + var dom_only = !(function(){try{return Object.defineProperty({},'x',{});}catch(_){return false;}}()); + + if (!orig || dom_only) { + Object.defineProperty = function (o, prop, desc) { + // In IE8 try built-in implementation for defining properties on DOM prototypes. + if (orig) + try { return orig(o, prop, desc); } catch (_) {} + if (o !== Object(o)) + throw TypeError('Object.defineProperty called on non-object'); + if (Object.prototype.__defineGetter__ && ('get' in desc)) + Object.prototype.__defineGetter__.call(o, prop, desc.get); + if (Object.prototype.__defineSetter__ && ('set' in desc)) + Object.prototype.__defineSetter__.call(o, prop, desc.set); + if ('value' in desc) + o[prop] = desc.value; + return o; + }; + } + }()); + + // ES5: Make obj[index] an alias for obj._getter(index)/obj._setter(index, value) + // for index in 0 ... obj.length + function makeArrayAccessors(obj) { + if ('TYPED_ARRAY_POLYFILL_NO_ARRAY_ACCESSORS' in global) + return; + + if (obj.length > MAX_ARRAY_LENGTH) throw RangeError('Array too large for polyfill'); + + function makeArrayAccessor(index) { + Object.defineProperty(obj, index, { + 'get': function() { return obj._getter(index); }, + 'set': function(v) { obj._setter(index, v); }, + enumerable: true, + configurable: false + }); + } + + var i; + for (i = 0; i < obj.length; i += 1) { + makeArrayAccessor(i); + } + } + + // Internal conversion functions: + // pack() - take a number (interpreted as Type), output a byte array + // unpack() - take a byte array, output a Type-like number + + function as_signed(value, bits) { var s = 32 - bits; return (value << s) >> s; } + function as_unsigned(value, bits) { var s = 32 - bits; return (value << s) >>> s; } + + function packI8(n) { return [n & 0xff]; } + function unpackI8(bytes) { return as_signed(bytes[0], 8); } + + function packU8(n) { return [n & 0xff]; } + function unpackU8(bytes) { return as_unsigned(bytes[0], 8); } + + function packU8Clamped(n) { n = round(Number(n)); return [n < 0 ? 0 : n > 0xff ? 0xff : n & 0xff]; } + + function packI16(n) { return [n & 0xff, (n >> 8) & 0xff]; } + function unpackI16(bytes) { return as_signed(bytes[1] << 8 | bytes[0], 16); } + + function packU16(n) { return [n & 0xff, (n >> 8) & 0xff]; } + function unpackU16(bytes) { return as_unsigned(bytes[1] << 8 | bytes[0], 16); } + + function packI32(n) { return [n & 0xff, (n >> 8) & 0xff, (n >> 16) & 0xff, (n >> 24) & 0xff]; } + function unpackI32(bytes) { return as_signed(bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0], 32); } + + function packU32(n) { return [n & 0xff, (n >> 8) & 0xff, (n >> 16) & 0xff, (n >> 24) & 0xff]; } + function unpackU32(bytes) { return as_unsigned(bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0], 32); } + + function packIEEE754(v, ebits, fbits) { + + var bias = (1 << (ebits - 1)) - 1; + + function roundToEven(n) { + var w = floor(n), f = n - w; + if (f < 0.5) + return w; + if (f > 0.5) + return w + 1; + return w % 2 ? w + 1 : w; + } + + // Compute sign, exponent, fraction + var s, e, f; + if (v !== v) { + // NaN + // http://dev.w3.org/2006/webapi/WebIDL/#es-type-mapping + e = (1 << ebits) - 1; f = pow(2, fbits - 1); s = 0; + } else if (v === Infinity || v === -Infinity) { + e = (1 << ebits) - 1; f = 0; s = (v < 0) ? 1 : 0; + } else if (v === 0) { + e = 0; f = 0; s = (1 / v === -Infinity) ? 1 : 0; + } else { + s = v < 0; + v = abs(v); + + if (v >= pow(2, 1 - bias)) { + // Normalized + e = min(floor(log(v) / LN2), 1023); + var significand = v / pow(2, e); + if (significand < 1) { + e -= 1; + significand *= 2; + } + if (significand >= 2) { + e += 1; + significand /= 2; + } + var d = pow(2, fbits); + f = roundToEven(significand * d) - d; + e += bias; + if (f / d >= 1) { + e += 1; + f = 0; + } + if (e > 2 * bias) { + // Overflow + e = (1 << ebits) - 1; + f = 0; + } + } else { + // Denormalized + e = 0; + f = roundToEven(v / pow(2, 1 - bias - fbits)); + } + } + + // Pack sign, exponent, fraction + var bits = [], i; + for (i = fbits; i; i -= 1) { bits.push(f % 2 ? 1 : 0); f = floor(f / 2); } + for (i = ebits; i; i -= 1) { bits.push(e % 2 ? 1 : 0); e = floor(e / 2); } + bits.push(s ? 1 : 0); + bits.reverse(); + var str = bits.join(''); + + // Bits to bytes + var bytes = []; + while (str.length) { + bytes.unshift(parseInt(str.substring(0, 8), 2)); + str = str.substring(8); + } + return bytes; + } + + function unpackIEEE754(bytes, ebits, fbits) { + // Bytes to bits + var bits = [], i, j, b, str, + bias, s, e, f; + + for (i = 0; i < bytes.length; ++i) { + b = bytes[i]; + for (j = 8; j; j -= 1) { + bits.push(b % 2 ? 1 : 0); b = b >> 1; + } + } + bits.reverse(); + str = bits.join(''); + + // Unpack sign, exponent, fraction + bias = (1 << (ebits - 1)) - 1; + s = parseInt(str.substring(0, 1), 2) ? -1 : 1; + e = parseInt(str.substring(1, 1 + ebits), 2); + f = parseInt(str.substring(1 + ebits), 2); + + // Produce number + if (e === (1 << ebits) - 1) { + return f !== 0 ? NaN : s * Infinity; + } else if (e > 0) { + // Normalized + return s * pow(2, e - bias) * (1 + f / pow(2, fbits)); + } else if (f !== 0) { + // Denormalized + return s * pow(2, -(bias - 1)) * (f / pow(2, fbits)); + } else { + return s < 0 ? -0 : 0; + } + } + + function unpackF64(b) { return unpackIEEE754(b, 11, 52); } + function packF64(v) { return packIEEE754(v, 11, 52); } + function unpackF32(b) { return unpackIEEE754(b, 8, 23); } + function packF32(v) { return packIEEE754(v, 8, 23); } + + // + // 3 The ArrayBuffer Type + // + + (function() { + + function ArrayBuffer(length) { + length = ToInt32(length); + if (length < 0) throw RangeError('ArrayBuffer size is not a small enough positive integer.'); + Object.defineProperty(this, 'byteLength', {value: length}); + Object.defineProperty(this, '_bytes', {value: Array(length)}); + + for (var i = 0; i < length; i += 1) + this._bytes[i] = 0; + } + + global.ArrayBuffer = global.ArrayBuffer || ArrayBuffer; + + // + // 5 The Typed Array View Types + // + + function $TypedArray$() { + + // %TypedArray% ( length ) + if (!arguments.length || typeof arguments[0] !== 'object') { + return (function(length) { + length = ToInt32(length); + if (length < 0) throw RangeError('length is not a small enough positive integer.'); + Object.defineProperty(this, 'length', {value: length}); + Object.defineProperty(this, 'byteLength', {value: length * this.BYTES_PER_ELEMENT}); + Object.defineProperty(this, 'buffer', {value: new ArrayBuffer(this.byteLength)}); + Object.defineProperty(this, 'byteOffset', {value: 0}); + + }).apply(this, arguments); + } + + // %TypedArray% ( typedArray ) + if (arguments.length >= 1 && + Type(arguments[0]) === 'object' && + arguments[0] instanceof $TypedArray$) { + return (function(typedArray){ + if (this.constructor !== typedArray.constructor) throw TypeError(); + + var byteLength = typedArray.length * this.BYTES_PER_ELEMENT; + Object.defineProperty(this, 'buffer', {value: new ArrayBuffer(byteLength)}); + Object.defineProperty(this, 'byteLength', {value: byteLength}); + Object.defineProperty(this, 'byteOffset', {value: 0}); + Object.defineProperty(this, 'length', {value: typedArray.length}); + + for (var i = 0; i < this.length; i += 1) + this._setter(i, typedArray._getter(i)); + + }).apply(this, arguments); + } + + // %TypedArray% ( array ) + if (arguments.length >= 1 && + Type(arguments[0]) === 'object' && + !(arguments[0] instanceof $TypedArray$) && + !(arguments[0] instanceof ArrayBuffer || Class(arguments[0]) === 'ArrayBuffer')) { + return (function(array) { + + var byteLength = array.length * this.BYTES_PER_ELEMENT; + Object.defineProperty(this, 'buffer', {value: new ArrayBuffer(byteLength)}); + Object.defineProperty(this, 'byteLength', {value: byteLength}); + Object.defineProperty(this, 'byteOffset', {value: 0}); + Object.defineProperty(this, 'length', {value: array.length}); + + for (var i = 0; i < this.length; i += 1) { + var s = array[i]; + this._setter(i, Number(s)); + } + }).apply(this, arguments); + } + + // %TypedArray% ( buffer, byteOffset=0, length=undefined ) + if (arguments.length >= 1 && + Type(arguments[0]) === 'object' && + (arguments[0] instanceof ArrayBuffer || Class(arguments[0]) === 'ArrayBuffer')) { + return (function(buffer, byteOffset, length) { + + byteOffset = ToUint32(byteOffset); + if (byteOffset > buffer.byteLength) + throw RangeError('byteOffset out of range'); + + // The given byteOffset must be a multiple of the element + // size of the specific type, otherwise an exception is raised. + if (byteOffset % this.BYTES_PER_ELEMENT) + throw RangeError('buffer length minus the byteOffset is not a multiple of the element size.'); + + if (length === undefined) { + var byteLength = buffer.byteLength - byteOffset; + if (byteLength % this.BYTES_PER_ELEMENT) + throw RangeError('length of buffer minus byteOffset not a multiple of the element size'); + length = byteLength / this.BYTES_PER_ELEMENT; + + } else { + length = ToUint32(length); + byteLength = length * this.BYTES_PER_ELEMENT; + } + + if ((byteOffset + byteLength) > buffer.byteLength) + throw RangeError('byteOffset and length reference an area beyond the end of the buffer'); + + Object.defineProperty(this, 'buffer', {value: buffer}); + Object.defineProperty(this, 'byteLength', {value: byteLength}); + Object.defineProperty(this, 'byteOffset', {value: byteOffset}); + Object.defineProperty(this, 'length', {value: length}); + + }).apply(this, arguments); + } + + // %TypedArray% ( all other argument combinations ) + throw TypeError(); + } + + // Properties of the %TypedArray Instrinsic Object + + // %TypedArray%.from ( source , mapfn=undefined, thisArg=undefined ) + Object.defineProperty($TypedArray$, 'from', {value: function(iterable) { + return new this(iterable); + }}); + + // %TypedArray%.of ( ...items ) + Object.defineProperty($TypedArray$, 'of', {value: function(/*...items*/) { + return new this(arguments); + }}); + + // %TypedArray%.prototype + var $TypedArrayPrototype$ = {}; + $TypedArray$.prototype = $TypedArrayPrototype$; + + // WebIDL: getter type (unsigned long index); + Object.defineProperty($TypedArray$.prototype, '_getter', {value: function(index) { + if (arguments.length < 1) throw SyntaxError('Not enough arguments'); + + index = ToUint32(index); + if (index >= this.length) + return undefined; + + var bytes = [], i, o; + for (i = 0, o = this.byteOffset + index * this.BYTES_PER_ELEMENT; + i < this.BYTES_PER_ELEMENT; + i += 1, o += 1) { + bytes.push(this.buffer._bytes[o]); + } + return this._unpack(bytes); + }}); + + // NONSTANDARD: convenience alias for getter: type get(unsigned long index); + Object.defineProperty($TypedArray$.prototype, 'get', {value: $TypedArray$.prototype._getter}); + + // WebIDL: setter void (unsigned long index, type value); + Object.defineProperty($TypedArray$.prototype, '_setter', {value: function(index, value) { + if (arguments.length < 2) throw SyntaxError('Not enough arguments'); + + index = ToUint32(index); + if (index >= this.length) + return; + + var bytes = this._pack(value), i, o; + for (i = 0, o = this.byteOffset + index * this.BYTES_PER_ELEMENT; + i < this.BYTES_PER_ELEMENT; + i += 1, o += 1) { + this.buffer._bytes[o] = bytes[i]; + } + }}); + + // get %TypedArray%.prototype.buffer + // get %TypedArray%.prototype.byteLength + // get %TypedArray%.prototype.byteOffset + // -- applied directly to the object in the constructor + + // %TypedArray%.prototype.constructor + Object.defineProperty($TypedArray$.prototype, 'constructor', {value: $TypedArray$}); + + // %TypedArray%.prototype.copyWithin (target, start, end = this.length ) + Object.defineProperty($TypedArray$.prototype, 'copyWithin', {value: function(target, start) { + var end = arguments[2]; + + var o = ToObject(this); + var lenVal = o.length; + var len = ToUint32(lenVal); + len = max(len, 0); + var relativeTarget = ToInt32(target); + var to; + if (relativeTarget < 0) + to = max(len + relativeTarget, 0); + else + to = min(relativeTarget, len); + var relativeStart = ToInt32(start); + var from; + if (relativeStart < 0) + from = max(len + relativeStart, 0); + else + from = min(relativeStart, len); + var relativeEnd; + if (end === undefined) + relativeEnd = len; + else + relativeEnd = ToInt32(end); + var final; + if (relativeEnd < 0) + final = max(len + relativeEnd, 0); + else + final = min(relativeEnd, len); + var count = min(final - from, len - to); + var direction; + if (from < to && to < from + count) { + direction = -1; + from = from + count - 1; + to = to + count - 1; + } else { + direction = 1; + } + while (count > 0) { + o._setter(to, o._getter(from)); + from = from + direction; + to = to + direction; + count = count - 1; + } + return o; + }}); + + // %TypedArray%.prototype.entries ( ) + // -- defined in es6.js to shim browsers w/ native TypedArrays + + // %TypedArray%.prototype.every ( callbackfn, thisArg = undefined ) + Object.defineProperty($TypedArray$.prototype, 'every', {value: function(callbackfn) { + if (this === undefined || this === null) throw TypeError(); + var t = Object(this); + var len = ToUint32(t.length); + if (!IsCallable(callbackfn)) throw TypeError(); + var thisArg = arguments[1]; + for (var i = 0; i < len; i++) { + if (!callbackfn.call(thisArg, t._getter(i), i, t)) + return false; + } + return true; + }}); + + // %TypedArray%.prototype.fill (value, start = 0, end = this.length ) + Object.defineProperty($TypedArray$.prototype, 'fill', {value: function(value) { + var start = arguments[1], + end = arguments[2]; + + var o = ToObject(this); + var lenVal = o.length; + var len = ToUint32(lenVal); + len = max(len, 0); + var relativeStart = ToInt32(start); + var k; + if (relativeStart < 0) + k = max((len + relativeStart), 0); + else + k = min(relativeStart, len); + var relativeEnd; + if (end === undefined) + relativeEnd = len; + else + relativeEnd = ToInt32(end); + var final; + if (relativeEnd < 0) + final = max((len + relativeEnd), 0); + else + final = min(relativeEnd, len); + while (k < final) { + o._setter(k, value); + k += 1; + } + return o; + }}); + + // %TypedArray%.prototype.filter ( callbackfn, thisArg = undefined ) + Object.defineProperty($TypedArray$.prototype, 'filter', {value: function(callbackfn) { + if (this === undefined || this === null) throw TypeError(); + var t = Object(this); + var len = ToUint32(t.length); + if (!IsCallable(callbackfn)) throw TypeError(); + var res = []; + var thisp = arguments[1]; + for (var i = 0; i < len; i++) { + var val = t._getter(i); // in case fun mutates this + if (callbackfn.call(thisp, val, i, t)) + res.push(val); + } + return new this.constructor(res); + }}); + + // %TypedArray%.prototype.find (predicate, thisArg = undefined) + Object.defineProperty($TypedArray$.prototype, 'find', {value: function(predicate) { + var o = ToObject(this); + var lenValue = o.length; + var len = ToUint32(lenValue); + if (!IsCallable(predicate)) throw TypeError(); + var t = arguments.length > 1 ? arguments[1] : undefined; + var k = 0; + while (k < len) { + var kValue = o._getter(k); + var testResult = predicate.call(t, kValue, k, o); + if (Boolean(testResult)) + return kValue; + ++k; + } + return undefined; + }}); + + // %TypedArray%.prototype.findIndex ( predicate, thisArg = undefined ) + Object.defineProperty($TypedArray$.prototype, 'findIndex', {value: function(predicate) { + var o = ToObject(this); + var lenValue = o.length; + var len = ToUint32(lenValue); + if (!IsCallable(predicate)) throw TypeError(); + var t = arguments.length > 1 ? arguments[1] : undefined; + var k = 0; + while (k < len) { + var kValue = o._getter(k); + var testResult = predicate.call(t, kValue, k, o); + if (Boolean(testResult)) + return k; + ++k; + } + return -1; + }}); + + // %TypedArray%.prototype.forEach ( callbackfn, thisArg = undefined ) + Object.defineProperty($TypedArray$.prototype, 'forEach', {value: function(callbackfn) { + if (this === undefined || this === null) throw TypeError(); + var t = Object(this); + var len = ToUint32(t.length); + if (!IsCallable(callbackfn)) throw TypeError(); + var thisp = arguments[1]; + for (var i = 0; i < len; i++) + callbackfn.call(thisp, t._getter(i), i, t); + }}); + + // %TypedArray%.prototype.indexOf (searchElement, fromIndex = 0 ) + Object.defineProperty($TypedArray$.prototype, 'indexOf', {value: function(searchElement) { + if (this === undefined || this === null) throw TypeError(); + var t = Object(this); + var len = ToUint32(t.length); + if (len === 0) return -1; + var n = 0; + if (arguments.length > 0) { + n = Number(arguments[1]); + if (n !== n) { + n = 0; + } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) { + n = (n > 0 || -1) * floor(abs(n)); + } + } + if (n >= len) return -1; + var k = n >= 0 ? n : max(len - abs(n), 0); + for (; k < len; k++) { + if (t._getter(k) === searchElement) { + return k; + } + } + return -1; + }}); + + // %TypedArray%.prototype.join ( separator ) + Object.defineProperty($TypedArray$.prototype, 'join', {value: function(separator) { + if (this === undefined || this === null) throw TypeError(); + var t = Object(this); + var len = ToUint32(t.length); + var tmp = Array(len); + for (var i = 0; i < len; ++i) + tmp[i] = t._getter(i); + return tmp.join(separator === undefined ? ',' : separator); // Hack for IE7 + }}); + + // %TypedArray%.prototype.keys ( ) + // -- defined in es6.js to shim browsers w/ native TypedArrays + + // %TypedArray%.prototype.lastIndexOf ( searchElement, fromIndex = this.length-1 ) + Object.defineProperty($TypedArray$.prototype, 'lastIndexOf', {value: function(searchElement) { + if (this === undefined || this === null) throw TypeError(); + var t = Object(this); + var len = ToUint32(t.length); + if (len === 0) return -1; + var n = len; + if (arguments.length > 1) { + n = Number(arguments[1]); + if (n !== n) { + n = 0; + } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) { + n = (n > 0 || -1) * floor(abs(n)); + } + } + var k = n >= 0 ? min(n, len - 1) : len - abs(n); + for (; k >= 0; k--) { + if (t._getter(k) === searchElement) + return k; + } + return -1; + }}); + + // get %TypedArray%.prototype.length + // -- applied directly to the object in the constructor + + // %TypedArray%.prototype.map ( callbackfn, thisArg = undefined ) + Object.defineProperty($TypedArray$.prototype, 'map', {value: function(callbackfn) { + if (this === undefined || this === null) throw TypeError(); + var t = Object(this); + var len = ToUint32(t.length); + if (!IsCallable(callbackfn)) throw TypeError(); + var res = []; res.length = len; + var thisp = arguments[1]; + for (var i = 0; i < len; i++) + res[i] = callbackfn.call(thisp, t._getter(i), i, t); + return new this.constructor(res); + }}); + + // %TypedArray%.prototype.reduce ( callbackfn [, initialValue] ) + Object.defineProperty($TypedArray$.prototype, 'reduce', {value: function(callbackfn) { + if (this === undefined || this === null) throw TypeError(); + var t = Object(this); + var len = ToUint32(t.length); + if (!IsCallable(callbackfn)) throw TypeError(); + // no value to return if no initial value and an empty array + if (len === 0 && arguments.length === 1) throw TypeError(); + var k = 0; + var accumulator; + if (arguments.length >= 2) { + accumulator = arguments[1]; + } else { + accumulator = t._getter(k++); + } + while (k < len) { + accumulator = callbackfn.call(undefined, accumulator, t._getter(k), k, t); + k++; + } + return accumulator; + }}); + + // %TypedArray%.prototype.reduceRight ( callbackfn [, initialValue] ) + Object.defineProperty($TypedArray$.prototype, 'reduceRight', {value: function(callbackfn) { + if (this === undefined || this === null) throw TypeError(); + var t = Object(this); + var len = ToUint32(t.length); + if (!IsCallable(callbackfn)) throw TypeError(); + // no value to return if no initial value, empty array + if (len === 0 && arguments.length === 1) throw TypeError(); + var k = len - 1; + var accumulator; + if (arguments.length >= 2) { + accumulator = arguments[1]; + } else { + accumulator = t._getter(k--); + } + while (k >= 0) { + accumulator = callbackfn.call(undefined, accumulator, t._getter(k), k, t); + k--; + } + return accumulator; + }}); + + // %TypedArray%.prototype.reverse ( ) + Object.defineProperty($TypedArray$.prototype, 'reverse', {value: function() { + if (this === undefined || this === null) throw TypeError(); + var t = Object(this); + var len = ToUint32(t.length); + var half = floor(len / 2); + for (var i = 0, j = len - 1; i < half; ++i, --j) { + var tmp = t._getter(i); + t._setter(i, t._getter(j)); + t._setter(j, tmp); + } + return t; + }}); + + // %TypedArray%.prototype.set(array, offset = 0 ) + // %TypedArray%.prototype.set(typedArray, offset = 0 ) + // WebIDL: void set(TypedArray array, optional unsigned long offset); + // WebIDL: void set(sequence array, optional unsigned long offset); + Object.defineProperty($TypedArray$.prototype, 'set', {value: function(index, value) { + if (arguments.length < 1) throw SyntaxError('Not enough arguments'); + var array, sequence, offset, len, + i, s, d, + byteOffset, byteLength, tmp; + + if (typeof arguments[0] === 'object' && arguments[0].constructor === this.constructor) { + // void set(TypedArray array, optional unsigned long offset); + array = arguments[0]; + offset = ToUint32(arguments[1]); + + if (offset + array.length > this.length) { + throw RangeError('Offset plus length of array is out of range'); + } + + byteOffset = this.byteOffset + offset * this.BYTES_PER_ELEMENT; + byteLength = array.length * this.BYTES_PER_ELEMENT; + + if (array.buffer === this.buffer) { + tmp = []; + for (i = 0, s = array.byteOffset; i < byteLength; i += 1, s += 1) { + tmp[i] = array.buffer._bytes[s]; + } + for (i = 0, d = byteOffset; i < byteLength; i += 1, d += 1) { + this.buffer._bytes[d] = tmp[i]; + } + } else { + for (i = 0, s = array.byteOffset, d = byteOffset; + i < byteLength; i += 1, s += 1, d += 1) { + this.buffer._bytes[d] = array.buffer._bytes[s]; + } + } + } else if (typeof arguments[0] === 'object' && typeof arguments[0].length !== 'undefined') { + // void set(sequence array, optional unsigned long offset); + sequence = arguments[0]; + len = ToUint32(sequence.length); + offset = ToUint32(arguments[1]); + + if (offset + len > this.length) { + throw RangeError('Offset plus length of array is out of range'); + } + + for (i = 0; i < len; i += 1) { + s = sequence[i]; + this._setter(offset + i, Number(s)); + } + } else { + throw TypeError('Unexpected argument type(s)'); + } + }}); + + // %TypedArray%.prototype.slice ( start, end ) + Object.defineProperty($TypedArray$.prototype, 'slice', {value: function(start, end) { + var o = ToObject(this); + var lenVal = o.length; + var len = ToUint32(lenVal); + var relativeStart = ToInt32(start); + var k = (relativeStart < 0) ? max(len + relativeStart, 0) : min(relativeStart, len); + var relativeEnd = (end === undefined) ? len : ToInt32(end); + var final = (relativeEnd < 0) ? max(len + relativeEnd, 0) : min(relativeEnd, len); + var count = final - k; + var c = o.constructor; + var a = new c(count); + var n = 0; + while (k < final) { + var kValue = o._getter(k); + a._setter(n, kValue); + ++k; + ++n; + } + return a; + }}); + + // %TypedArray%.prototype.some ( callbackfn, thisArg = undefined ) + Object.defineProperty($TypedArray$.prototype, 'some', {value: function(callbackfn) { + if (this === undefined || this === null) throw TypeError(); + var t = Object(this); + var len = ToUint32(t.length); + if (!IsCallable(callbackfn)) throw TypeError(); + var thisp = arguments[1]; + for (var i = 0; i < len; i++) { + if (callbackfn.call(thisp, t._getter(i), i, t)) { + return true; + } + } + return false; + }}); + + // %TypedArray%.prototype.sort ( comparefn ) + Object.defineProperty($TypedArray$.prototype, 'sort', {value: function(comparefn) { + if (this === undefined || this === null) throw TypeError(); + var t = Object(this); + var len = ToUint32(t.length); + var tmp = Array(len); + for (var i = 0; i < len; ++i) + tmp[i] = t._getter(i); + if (comparefn) tmp.sort(comparefn); else tmp.sort(); // Hack for IE8/9 + for (i = 0; i < len; ++i) + t._setter(i, tmp[i]); + return t; + }}); + + // %TypedArray%.prototype.subarray(begin = 0, end = this.length ) + // WebIDL: TypedArray subarray(long begin, optional long end); + Object.defineProperty($TypedArray$.prototype, 'subarray', {value: function(start, end) { + function clamp(v, min, max) { return v < min ? min : v > max ? max : v; } + + start = ToInt32(start); + end = ToInt32(end); + + if (arguments.length < 1) { start = 0; } + if (arguments.length < 2) { end = this.length; } + + if (start < 0) { start = this.length + start; } + if (end < 0) { end = this.length + end; } + + start = clamp(start, 0, this.length); + end = clamp(end, 0, this.length); + + var len = end - start; + if (len < 0) { + len = 0; + } + + return new this.constructor( + this.buffer, this.byteOffset + start * this.BYTES_PER_ELEMENT, len); + }}); + + // %TypedArray%.prototype.toLocaleString ( ) + // %TypedArray%.prototype.toString ( ) + // %TypedArray%.prototype.values ( ) + // %TypedArray%.prototype [ @@iterator ] ( ) + // get %TypedArray%.prototype [ @@toStringTag ] + // -- defined in es6.js to shim browsers w/ native TypedArrays + + function makeTypedArray(elementSize, pack, unpack) { + // Each TypedArray type requires a distinct constructor instance with + // identical logic, which this produces. + var TypedArray = function() { + Object.defineProperty(this, 'constructor', {value: TypedArray}); + $TypedArray$.apply(this, arguments); + makeArrayAccessors(this); + }; + if ('__proto__' in TypedArray) { + TypedArray.__proto__ = $TypedArray$; + } else { + TypedArray.from = $TypedArray$.from; + TypedArray.of = $TypedArray$.of; + } + + TypedArray.BYTES_PER_ELEMENT = elementSize; + + var TypedArrayPrototype = function() {}; + TypedArrayPrototype.prototype = $TypedArrayPrototype$; + + TypedArray.prototype = new TypedArrayPrototype(); + + Object.defineProperty(TypedArray.prototype, 'BYTES_PER_ELEMENT', {value: elementSize}); + Object.defineProperty(TypedArray.prototype, '_pack', {value: pack}); + Object.defineProperty(TypedArray.prototype, '_unpack', {value: unpack}); + + return TypedArray; + } + + var Int8Array = makeTypedArray(1, packI8, unpackI8); + var Uint8Array = makeTypedArray(1, packU8, unpackU8); + var Uint8ClampedArray = makeTypedArray(1, packU8Clamped, unpackU8); + var Int16Array = makeTypedArray(2, packI16, unpackI16); + var Uint16Array = makeTypedArray(2, packU16, unpackU16); + var Int32Array = makeTypedArray(4, packI32, unpackI32); + var Uint32Array = makeTypedArray(4, packU32, unpackU32); + var Float32Array = makeTypedArray(4, packF32, unpackF32); + var Float64Array = makeTypedArray(8, packF64, unpackF64); + + global.Int8Array = global.Int8Array || Int8Array; + global.Uint8Array = global.Uint8Array || Uint8Array; + global.Uint8ClampedArray = global.Uint8ClampedArray || Uint8ClampedArray; + global.Int16Array = global.Int16Array || Int16Array; + global.Uint16Array = global.Uint16Array || Uint16Array; + global.Int32Array = global.Int32Array || Int32Array; + global.Uint32Array = global.Uint32Array || Uint32Array; + global.Float32Array = global.Float32Array || Float32Array; + global.Float64Array = global.Float64Array || Float64Array; + }()); + + // + // 6 The DataView View Type + // + + (function() { + function r(array, index) { + return IsCallable(array.get) ? array.get(index) : array[index]; + } + + var IS_BIG_ENDIAN = (function() { + var u16array = new Uint16Array([0x1234]), + u8array = new Uint8Array(u16array.buffer); + return r(u8array, 0) === 0x12; + }()); + + // DataView(buffer, byteOffset=0, byteLength=undefined) + // WebIDL: Constructor(ArrayBuffer buffer, + // optional unsigned long byteOffset, + // optional unsigned long byteLength) + function DataView(buffer, byteOffset, byteLength) { + if (!(buffer instanceof ArrayBuffer || Class(buffer) === 'ArrayBuffer')) throw TypeError(); + + byteOffset = ToUint32(byteOffset); + if (byteOffset > buffer.byteLength) + throw RangeError('byteOffset out of range'); + + if (byteLength === undefined) + byteLength = buffer.byteLength - byteOffset; + else + byteLength = ToUint32(byteLength); + + if ((byteOffset + byteLength) > buffer.byteLength) + throw RangeError('byteOffset and length reference an area beyond the end of the buffer'); + + Object.defineProperty(this, 'buffer', {value: buffer}); + Object.defineProperty(this, 'byteLength', {value: byteLength}); + Object.defineProperty(this, 'byteOffset', {value: byteOffset}); + }; + + // get DataView.prototype.buffer + // get DataView.prototype.byteLength + // get DataView.prototype.byteOffset + // -- applied directly to instances by the constructor + + function makeGetter(arrayType) { + return function GetViewValue(byteOffset, littleEndian) { + byteOffset = ToUint32(byteOffset); + + if (byteOffset + arrayType.BYTES_PER_ELEMENT > this.byteLength) + throw RangeError('Array index out of range'); + + byteOffset += this.byteOffset; + + var uint8Array = new Uint8Array(this.buffer, byteOffset, arrayType.BYTES_PER_ELEMENT), + bytes = []; + for (var i = 0; i < arrayType.BYTES_PER_ELEMENT; i += 1) + bytes.push(r(uint8Array, i)); + + if (Boolean(littleEndian) === Boolean(IS_BIG_ENDIAN)) + bytes.reverse(); + + return r(new arrayType(new Uint8Array(bytes).buffer), 0); + }; + } + + Object.defineProperty(DataView.prototype, 'getUint8', {value: makeGetter(Uint8Array)}); + Object.defineProperty(DataView.prototype, 'getInt8', {value: makeGetter(Int8Array)}); + Object.defineProperty(DataView.prototype, 'getUint16', {value: makeGetter(Uint16Array)}); + Object.defineProperty(DataView.prototype, 'getInt16', {value: makeGetter(Int16Array)}); + Object.defineProperty(DataView.prototype, 'getUint32', {value: makeGetter(Uint32Array)}); + Object.defineProperty(DataView.prototype, 'getInt32', {value: makeGetter(Int32Array)}); + Object.defineProperty(DataView.prototype, 'getFloat32', {value: makeGetter(Float32Array)}); + Object.defineProperty(DataView.prototype, 'getFloat64', {value: makeGetter(Float64Array)}); + + function makeSetter(arrayType) { + return function SetViewValue(byteOffset, value, littleEndian) { + byteOffset = ToUint32(byteOffset); + if (byteOffset + arrayType.BYTES_PER_ELEMENT > this.byteLength) + throw RangeError('Array index out of range'); + + // Get bytes + var typeArray = new arrayType([value]), + byteArray = new Uint8Array(typeArray.buffer), + bytes = [], i, byteView; + + for (i = 0; i < arrayType.BYTES_PER_ELEMENT; i += 1) + bytes.push(r(byteArray, i)); + + // Flip if necessary + if (Boolean(littleEndian) === Boolean(IS_BIG_ENDIAN)) + bytes.reverse(); + + // Write them + byteView = new Uint8Array(this.buffer, byteOffset, arrayType.BYTES_PER_ELEMENT); + byteView.set(bytes); + }; + } + + Object.defineProperty(DataView.prototype, 'setUint8', {value: makeSetter(Uint8Array)}); + Object.defineProperty(DataView.prototype, 'setInt8', {value: makeSetter(Int8Array)}); + Object.defineProperty(DataView.prototype, 'setUint16', {value: makeSetter(Uint16Array)}); + Object.defineProperty(DataView.prototype, 'setInt16', {value: makeSetter(Int16Array)}); + Object.defineProperty(DataView.prototype, 'setUint32', {value: makeSetter(Uint32Array)}); + Object.defineProperty(DataView.prototype, 'setInt32', {value: makeSetter(Int32Array)}); + Object.defineProperty(DataView.prototype, 'setFloat32', {value: makeSetter(Float32Array)}); + Object.defineProperty(DataView.prototype, 'setFloat64', {value: makeSetter(Float64Array)}); + + global.DataView = global.DataView || DataView; + + }()); + +}(self)); diff --git a/demo-shell-ng2/server/versions.js b/demo-shell-ng2/server/versions.js deleted file mode 100644 index 020843cf53..0000000000 --- a/demo-shell-ng2/server/versions.js +++ /dev/null @@ -1,42 +0,0 @@ -'use strict'; - -// wsrv extension that provides dynamic '/versions' route - -exports.register = function (server, options, next) { - - var packages = [ - 'ng2-activiti-form', - 'ng2-alfresco-core', - 'ng2-alfresco-datatable', - 'ng2-alfresco-documentlist', - 'ng2-alfresco-login', - 'ng2-alfresco-search', - 'ng2-alfresco-upload', - 'ng2-alfresco-viewer', - 'ng2-alfresco-webscript' - ]; - - server.route({ - method: 'GET', - path: '/versions', - handler: function (request, reply) { - var result = { - packages: packages.map(function (packageName) { - return { - name: packageName, - version: require('./../node_modules/' + packageName + '/package.json').version - } - }) - }; - - return reply(result).type('application/json'); - } - }); - - next(); -}; - -exports.register.attributes = { - name: 'ng2-module-versions', - version: '1.0.0' -}; diff --git a/demo-shell-ng2/systemjs.config.js b/demo-shell-ng2/systemjs.config.js deleted file mode 100644 index 94daf63400..0000000000 --- a/demo-shell-ng2/systemjs.config.js +++ /dev/null @@ -1,76 +0,0 @@ -/** - * System configuration for Angular 2 samples - * Adjust as necessary for your application needs. - */ -(function (global) { - System.config({ - paths: { - // paths serve as alias - 'npm:': 'node_modules/' - }, - // map tells the System loader where to look for things - map: { - // our app is within the app folder - app: 'app', - // angular bundles - '@angular/core': 'npm:@angular/core/bundles/core.umd.js', - '@angular/common': 'npm:@angular/common/bundles/common.umd.js', - '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js', - '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js', - '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js', - '@angular/http': 'npm:@angular/http/bundles/http.umd.js', - '@angular/router': 'npm:@angular/router/bundles/router.umd.js', - '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js', - // other libraries - 'rxjs': 'npm:rxjs', - 'moment': 'npm:moment/min/moment.min.js', - 'ng2-charts' : 'npm:ng2-charts', - 'ng2-translate': 'npm:ng2-translate', - 'ng2-alfresco-core': 'npm:ng2-alfresco-core/dist', - 'ng2-alfresco-datatable': 'npm:ng2-alfresco-datatable/dist', - 'ng2-alfresco-documentlist': 'npm:ng2-alfresco-documentlist/dist', - 'ng2-alfresco-login': 'npm:ng2-alfresco-login/dist', - 'ng2-alfresco-search': 'npm:ng2-alfresco-search/dist', - 'ng2-alfresco-upload': 'npm:ng2-alfresco-upload/dist', - 'ng2-activiti-form': 'npm:ng2-activiti-form/dist', - 'ng2-alfresco-viewer': 'npm:ng2-alfresco-viewer/dist', - 'ng2-alfresco-webscript': 'npm:ng2-alfresco-webscript/dist', - 'ng2-alfresco-tag': 'npm:ng2-alfresco-tag/dist', - 'ng2-activiti-tasklist': 'npm:ng2-activiti-tasklist/dist', - 'alfresco-js-api': 'npm:alfresco-js-api/dist', - 'ng2-activiti-processlist': 'npm:ng2-activiti-processlist/dist', - 'ng2-alfresco-userinfo': 'npm:ng2-alfresco-userinfo/dist', - 'ng2-activiti-analytics': 'npm:ng2-activiti-analytics/dist', - 'ng2-activiti-diagrams': 'npm:ng2-activiti-diagrams/dist' - }, - // packages tells the System loader how to load when no filename and/or no extension - packages: { - app: { - main: './main.js', - defaultExtension: 'js' - }, - rxjs: { - defaultExtension: 'js' - }, - 'ng2-translate': { defaultExtension: 'js' }, - 'ng2-charts': { defaultExtension: 'js' }, - - 'ng2-alfresco-core': { main: './index.js', defaultExtension: 'js'}, - 'ng2-alfresco-datatable': { main: './index.js', defaultExtension: 'js'}, - 'ng2-alfresco-documentlist': { main: './index.js', defaultExtension: 'js'}, - 'ng2-alfresco-login': { main: './index.js', defaultExtension: 'js'}, - 'ng2-alfresco-search': { main: './index.js', defaultExtension: 'js'}, - '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'}, - 'ng2-alfresco-tag': { main: './index.js', defaultExtension: 'js'}, - 'alfresco-js-api': { main: './alfresco-js-api.js', defaultExtension: 'js'}, - 'ng2-alfresco-userinfo': { main: './index.js', defaultExtension: 'js'}, - 'ng2-activiti-analytics': { main: './index.js', defaultExtension: 'js'}, - 'ng2-activiti-diagrams': { main: './index.js', defaultExtension: 'js'} - } - }); -})(this); diff --git a/demo-shell-ng2/tsconfig.json b/demo-shell-ng2/tsconfig.json index b48f1186e3..335fc62939 100644 --- a/demo-shell-ng2/tsconfig.json +++ b/demo-shell-ng2/tsconfig.json @@ -1,19 +1,16 @@ { "compilerOptions": { "target": "es5", - "module": "system", + "module": "commonjs", "moduleResolution": "node", "sourceMap": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, - "removeComments": false, + "lib": ["es2015", "dom"], "noImplicitAny": false, - "types": ["core-js", "jasmine"] + "suppressImplicitAnyIndexErrors": true }, "exclude": [ - "dist", - "node_modules", - "typings/main", - "typings/main.d.ts" + "node_modules" ] } diff --git a/demo-shell-ng2/tslint.json b/demo-shell-ng2/tslint.json index 4b43d6658e..aacef3b7ac 100644 --- a/demo-shell-ng2/tslint.json +++ b/demo-shell-ng2/tslint.json @@ -55,7 +55,7 @@ "no-eval": true, "no-inferrable-types": false, "no-internal-module": true, - "no-require-imports": true, + "no-require-imports": false, "no-shadowed-variable": true, "no-switch-case-fall-through": true, "no-trailing-whitespace": true, @@ -64,7 +64,7 @@ "no-unused-variable": true, "no-use-before-declare": true, "no-var-keyword": true, - "no-var-requires": true, + "no-var-requires": false, "object-literal-sort-keys": false, "one-line": [ true, diff --git a/demo-shell-ng2/webpack.config.js b/demo-shell-ng2/webpack.config.js new file mode 100644 index 0000000000..26df33c5f6 --- /dev/null +++ b/demo-shell-ng2/webpack.config.js @@ -0,0 +1 @@ +module.exports = require('./config/webpack.dev.js'); diff --git a/demo-shell-ng2/wsrv-config.json b/demo-shell-ng2/wsrv-config.json deleted file mode 100644 index bacfda5339..0000000000 --- a/demo-shell-ng2/wsrv-config.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "watch": [ - "node_modules/ng2-alfresco-core/dist/**/*.{html,css,js}", - "node_modules/ng2-alfresco-datatable/dist/**/*.{html,css,js}", - "node_modules/ng2-alfresco-documentlist/dist/**/*.{html,css,js}", - "node_modules/ng2-alfresco-login/dist/**/*.{html,css,js}", - "node_modules/ng2-alfresco-search/dist/**/*.{html,css,js}", - "node_modules/ng2-alfresco-upload/dist/**/*.{html,css,js}", - "node_modules/ng2-alfresco-viewer/dist/**/*.{html,css,js}", - "node_modules/ng2-alfresco-webscript/dist/**/*.{html,css,js}", - "node_modules/ng2-activiti-form/dist/**/*.{html,css,js}", - "node_modules/ng2-activiti-tasklist/dist/**/*.{html,css,js}" - ] -} diff --git a/ng2-components/ng2-activiti-analytics/.gitignore b/ng2-components/ng2-activiti-analytics/.gitignore index fe20e77f42..fb23a7fef5 100644 --- a/ng2-components/ng2-activiti-analytics/.gitignore +++ b/ng2-components/ng2-activiti-analytics/.gitignore @@ -6,10 +6,14 @@ coverage dist src/**/*.js src/**/*.js.map - +src/**/*.d.ts demo/**/*.js demo/**/*.js.map demo/**/*.d.ts index.js index.js.map !systemjs.config.js +*.tgz +/package/ +/bundles/ +index.d.ts diff --git a/ng2-components/ng2-activiti-analytics/.npmignore b/ng2-components/ng2-activiti-analytics/.npmignore index c5ca623298..8bb008aff4 100644 --- a/ng2-components/ng2-activiti-analytics/.npmignore +++ b/ng2-components/ng2-activiti-analytics/.npmignore @@ -2,14 +2,15 @@ npm-debug.log .idea coverage/ +demo/ node_modules typings/ fonts/ /.editorconfig /.travis.yml -/*.js /*.json -/*.ts -/*.js.map +/karma-test-shim.js +/karma.conf.js +/gulpfile.ts /.npmignore diff --git a/ng2-components/ng2-activiti-analytics/demo/.editorconfig b/ng2-components/ng2-activiti-analytics/demo/.editorconfig new file mode 100644 index 0000000000..75a2477db7 --- /dev/null +++ b/ng2-components/ng2-activiti-analytics/demo/.editorconfig @@ -0,0 +1,23 @@ +# http://editorconfig.org + +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 4 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[package.json] +indent_style = space +indent_size = 2 + +[karma.conf.js] +indent_style = space +indent_size = 2 + +[*.md] +insert_final_newline = false +trim_trailing_whitespace = false diff --git a/ng2-components/ng2-activiti-analytics/demo/package.json b/ng2-components/ng2-activiti-analytics/demo/package.json index 7cd5283028..17a7b119eb 100644 --- a/ng2-components/ng2-activiti-analytics/demo/package.json +++ b/ng2-components/ng2-activiti-analytics/demo/package.json @@ -5,15 +5,16 @@ "author": "Alfresco Software, Ltd.", "main": "index.js", "scripts": { - "clean": "npm install rimraf && rimraf dist node_modules typings dist", + "clean": "npm install rimraf && npm run clean-build && rimraf dist node_modules typings dist", + "clean-build" : "rimraf 'src/{,**/}**.js' 'src/{,**/}**.js.map' 'src/{,**/}**.d.ts'", "postinstall": "npm run build", "start": "npm run build && concurrently \"npm run tsc:w\" \"npm run server\" ", "server": "wsrv -o -s -l", - "build": "npm run tslint && rimraf dist && tsc", - "build:w": "npm run tslint && rimraf dist && tsc -w", + "build": "npm run tslint && npm run clean-build && npm run tsc", + "build:w": "npm run tslint && rimraf dist && npm run tsc:w", "tsc": "tsc", "tsc:w": "tsc -w", - "tslint": "tslint -c tslint.json *.ts && tslint -c tslint.json src/{,**/}**.ts" + "tslint": "tslint -c tslint.json *.ts && tslint -c tslint.json src/{,**/}**.ts -e '{,**/}**.d.ts'" }, "license": "Apache-2.0", "contributors": [ @@ -30,41 +31,40 @@ "activiti-diagrams" ], "dependencies": { - "@angular/common": "2.0.0", - "@angular/compiler": "2.0.0", - "@angular/core": "2.0.0", - "@angular/forms": "2.0.0", - "@angular/http": "2.0.0", - "@angular/platform-browser": "2.0.0", - "@angular/platform-browser-dynamic": "2.0.0", + "@angular/common": "2.2.2", + "@angular/compiler": "2.2.2", + "@angular/compiler-cli": "2.2.2", + "@angular/core": "2.2.2", + "@angular/forms": "2.2.2", + "@angular/http": "2.2.2", + "@angular/platform-browser": "2.2.2", + "@angular/platform-browser-dynamic": "2.2.2", + "@angular/router": "3.2.2", + "@angular/upgrade": "2.2.2", "core-js": "^2.4.1", "reflect-metadata": "^0.1.3", "rxjs": "5.0.0-beta.12", "systemjs": "0.19.27", "zone.js": "^0.6.23", - "intl": "1.2.4", "dialog-polyfill": "^0.4.3", "element.scrollintoviewifneeded-polyfill": "^1.0.1", "material-design-icons": "2.2.3", "material-design-lite": "1.2.1", - "chart.js": "^2.1.4", "md-date-time-picker": "^2.2.0", "ng2-charts": "1.1.0", "moment": "2.15.1", "raphael": "^2.2.6", - "ng2-translate": "2.5.0", - "alfresco-js-api": "^0.5.0", - "ng2-alfresco-core": "0.5.0", - "ng2-activiti-diagrams": "0.5.0", - "ng2-activiti-analytics": "^0.5.0" + "alfresco-js-api": "^1.0.0", + "ng2-alfresco-core": "1.0.0", + "ng2-activiti-diagrams": "1.0.0", + "ng2-activiti-analytics": "^1.0.0" }, "devDependencies": { - "@types/node": "^6.0.42", - "@types/core-js": "^0.9.32", "@types/jasmine": "^2.2.33", + "@types/node": "^6.0.42", "concurrently": "^2.2.0", "rimraf": "2.5.2", "tslint": "^3.8.1", diff --git a/ng2-components/ng2-activiti-analytics/demo/src/main.ts b/ng2-components/ng2-activiti-analytics/demo/src/main.ts index b897f7cb7b..67e19a017f 100644 --- a/ng2-components/ng2-activiti-analytics/demo/src/main.ts +++ b/ng2-components/ng2-activiti-analytics/demo/src/main.ts @@ -18,7 +18,7 @@ import { NgModule, Component, OnInit } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; -import { CoreModule, AlfrescoSettingsService, AlfrescoAuthenticationService } from 'ng2-alfresco-core'; +import { CoreModule, AlfrescoSettingsService, AlfrescoAuthenticationService, StorageService } from 'ng2-alfresco-core'; import { AnalyticsModule } from 'ng2-activiti-analytics'; @Component({ @@ -60,7 +60,9 @@ export class AnalyticsDemoComponent implements OnInit { ticket: string; - constructor(private authService: AlfrescoAuthenticationService, private settingsService: AlfrescoSettingsService) { + constructor(private authService: AlfrescoAuthenticationService, + private settingsService: AlfrescoSettingsService, + private storage: StorageService) { settingsService.bpmHost = this.host; settingsService.setProviders('BPM'); @@ -74,7 +76,7 @@ export class AnalyticsDemoComponent implements OnInit { } public updateTicket(): void { - localStorage.setItem('ticket-BPM', this.ticket); + this.storage.setItem('ticket-BPM', this.ticket); } public updateHost(): void { diff --git a/ng2-components/ng2-activiti-analytics/demo/systemjs.config.js b/ng2-components/ng2-activiti-analytics/demo/systemjs.config.js index 54b1de6634..edc575807d 100644 --- a/ng2-components/ng2-activiti-analytics/demo/systemjs.config.js +++ b/ng2-components/ng2-activiti-analytics/demo/systemjs.config.js @@ -11,7 +11,7 @@ // map tells the System loader where to look for things map: { // our app is within the app folder - app: 'dist', + app: 'src', // angular bundles '@angular/core': 'npm:@angular/core/bundles/core.umd.js', '@angular/common': 'npm:@angular/common/bundles/common.umd.js', @@ -27,9 +27,9 @@ 'ng2-charts': 'npm:ng2-charts', 'ng2-translate': 'npm:ng2-translate', 'alfresco-js-api': 'npm:alfresco-js-api/dist', - 'ng2-alfresco-core': 'npm:ng2-alfresco-core/dist', - 'ng2-activiti-diagrams': 'npm:ng2-activiti-diagrams/dist', - 'ng2-activiti-analytics': 'npm:ng2-activiti-analytics/dist' + 'ng2-alfresco-core': 'npm:ng2-alfresco-core', + 'ng2-activiti-diagrams': 'npm:ng2-activiti-diagrams', + 'ng2-activiti-analytics': 'npm:ng2-activiti-analytics' }, // packages tells the System loader how to load when no filename and/or no extension packages: { @@ -40,6 +40,7 @@ rxjs: { defaultExtension: 'js' }, + 'moment': 'npm:moment/min/moment.min.js', 'ng2-translate': { defaultExtension: 'js' }, 'ng2-charts': { main: 'ng2-charts.js', defaultExtension: 'js'}, 'alfresco-js-api': { main: './alfresco-js-api.js', defaultExtension: 'js'}, diff --git a/ng2-components/ng2-activiti-analytics/demo/tsconfig.json b/ng2-components/ng2-activiti-analytics/demo/tsconfig.json index 7be35bfec8..524fcfda8e 100644 --- a/ng2-components/ng2-activiti-analytics/demo/tsconfig.json +++ b/ng2-components/ng2-activiti-analytics/demo/tsconfig.json @@ -3,11 +3,10 @@ "target": "es5", "module": "commonjs", "moduleResolution": "node", + "sourceMap": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, - "sourceMap": true, - "removeComments": true, - "declaration": true, + "skipLibCheck": true, "noLib": false, "allowUnreachableCode": false, "allowUnusedLabels": false, @@ -15,12 +14,19 @@ "noImplicitReturns": false, "noImplicitUseStrict": false, "noFallthroughCasesInSwitch": true, - "outDir": "dist", - "types": ["core-js", "jasmine", "node"] + "removeComments": true, + "declaration": true, + "lib": [ + "es2015", + "dom" + ], + "suppressImplicitAnyIndexErrors": true }, "exclude": [ - "demo", - "node_modules", - "dist" - ] + "node_modules" + ], + "angularCompilerOptions": { + "strictMetadataEmit": false, + "skipTemplateCodegen": true + } } diff --git a/ng2-components/ng2-activiti-analytics/gulpfile.ts b/ng2-components/ng2-activiti-analytics/gulpfile.ts new file mode 100755 index 0000000000..57011140d1 --- /dev/null +++ b/ng2-components/ng2-activiti-analytics/gulpfile.ts @@ -0,0 +1,312 @@ +import * as gulp from 'gulp'; +import * as util from 'gulp-util'; +import * as runSequence from 'run-sequence'; +import * as gulpLoadPlugins from 'gulp-load-plugins'; +import * as merge from 'merge-stream'; +import * as rimraf from 'rimraf'; +import { join } from 'path'; +import * as Builder from 'systemjs-builder'; +var autoprefixer = require('autoprefixer'); +import * as cssnano from 'cssnano'; +import * as filter from 'gulp-filter'; +import * as sourcemaps from 'gulp-sourcemaps'; + +var APP_SRC = `.`; +var CSS_PROD_BUNDLE = 'main.css'; +var JS_PROD_SHIMS_BUNDLE = 'shims.js'; +var NG_FACTORY_FILE = 'main-prod'; + +const BUILD_TYPES = { + DEVELOPMENT: 'dev', + PRODUCTION: 'prod' +}; + +function normalizeDependencies(deps) { + deps + .filter((d) => !/\*/.test(d.src)) // Skip globs + .forEach((d) => d.src = require.resolve(d.src)); + return deps; +} + +function filterDependency(type: string, d): boolean { + const t = d.buildType || d.env; + d.buildType = t; + if (!t) { + d.buildType = Object.keys(BUILD_TYPES).map(k => BUILD_TYPES[k]); + } + if (!(d.buildType instanceof Array)) { + (d).env = [d.buildType]; + } + return d.buildType.indexOf(type) >= 0; +} + +function getInjectableDependency() { + var APP_ASSETS = [ + {src: `src/css/main.css`, inject: true, vendor: false}, + ]; + + var NPM_DEPENDENCIES = [ + {src: 'zone.js/dist/zone.js', inject: 'libs'}, + {src: 'core-js/client/shim.min.js', inject: 'shims'}, + {src: 'intl/dist/Intl.min.js', inject: 'shims'}, + {src: 'systemjs/dist/system.src.js', inject: 'shims', buildType:'dev'} + ]; + + return normalizeDependencies(NPM_DEPENDENCIES.filter(filterDependency.bind(null, 'dev'))) + .concat(APP_ASSETS.filter(filterDependency.bind(null, 'dev'))); +} + +const plugins = gulpLoadPlugins(); + +let tsProjects: any = {}; + +function makeTsProject(options: Object = {}) { + let optionsHash = JSON.stringify(options); + if (!tsProjects[optionsHash]) { + let config = Object.assign({ + typescript: require('typescript') + }, options); + tsProjects[optionsHash] = + plugins.typescript.createProject('tsconfig.json', config); + } + return tsProjects[optionsHash]; +} + +gulp.task('build.html_css', () => { + const gulpConcatCssConfig = { + targetFile: CSS_PROD_BUNDLE, + options: { + rebaseUrls: false + } + }; + + const processors = [ + autoprefixer({ + browsers: [ + 'ie >= 10', + 'ie_mob >= 10', + 'ff >= 30', + 'chrome >= 34', + 'safari >= 7', + 'opera >= 23', + 'ios >= 7', + 'android >= 4.4', + 'bb >= 10' + ] + }) + ]; + + const reportPostCssError = (e: any) => util.log(util.colors.red(e.message)); + + processors.push( + cssnano({ + discardComments: {removeAll: true}, + discardUnused: false, // unsafe, see http://goo.gl/RtrzwF + zindex: false, // unsafe, see http://goo.gl/vZ4gbQ + reduceIdents: false // unsafe, see http://goo.gl/tNOPv0 + }) + ); + + /** + * Processes the CSS files within `src/client` excluding those in `src/client/assets` using `postcss` with the + * configured processors + * Execute the appropriate component-stylesheet processing method based on user stylesheet preference. + */ + function processComponentStylesheets() { + return gulp.src(join('src/**', '*.css')) + .pipe(plugins.cached('process-component-css')) + .pipe(plugins.postcss(processors)) + .on('error', reportPostCssError); + } + + + /** + * Get a stream of external css files for subsequent processing. + */ + function getExternalCssStream() { + return gulp.src(getExternalCss()) + .pipe(plugins.cached('process-external-css')); + } + + /** + * Get an array of filenames referring to all external css stylesheets. + */ + function getExternalCss() { + return getInjectableDependency().filter(dep => /\.css$/.test(dep.src)).map(dep => dep.src); + } + + /** + * Processes the external CSS files using `postcss` with the configured processors. + */ + function processExternalCss() { + return getExternalCssStream() + .pipe(plugins.postcss(processors)) + .pipe(plugins.concatCss(gulpConcatCssConfig.targetFile, gulpConcatCssConfig.options)) + .on('error', reportPostCssError); + } + + return merge(processComponentStylesheets(), processExternalCss()); + +}); + +gulp.task('build.bundles.app', (done) => { + var BUNDLER_OPTIONS = { + format: 'umd', + minify: false, + mangle: false, + sourceMaps: true + }; + var CONFIG_TYPESCRIPT = { + baseURL: '.', + transpiler: 'typescript', + typescriptOptions: { + module: 'cjs' + }, + map: { + typescript: 'node_modules/typescript/lib/typescript.js', + '@angular': 'node_modules/@angular', + rxjs: 'node_modules/rxjs', + 'ng2-translate': 'node_modules/ng2-translate', + 'alfresco-js-api': 'node_modules/alfresco-js-api/dist/alfresco-js-api', + 'ng2-alfresco-core': 'node_modules/ng2-alfresco-core/', + 'ng2-activiti-diagrams': 'node_modules/ng2-activiti-diagrams/', + 'ng2-activiti-analytics': 'node_modules/ng2-activiti-analytics/', + 'ng2-alfresco-datatable': 'node_modules/ng2-alfresco-datatable/', + 'ng2-alfresco-documentlist': 'node_modules/ng2-alfresco-documentlist/', + 'ng2-activiti-form': 'node_modules/ng2-activiti-form/', + 'ng2-alfresco-login': 'node_modules/ng2-alfresco-login/', + 'ng2-activiti-processlist': 'node_modules/ng2-activiti-processlist/', + 'ng2-alfresco-search': 'node_modules/ng2-alfresco-search/', + 'ng2-activiti-tasklist': 'node_modules/ng2-activiti-tasklist/', + 'ng2-alfresco-tag': 'node_modules/ng2-alfresco-tag/', + 'ng2-alfresco-upload': 'node_modules/ng2-alfresco-upload/', + 'ng2-alfresco-userinfo': 'node_modules/ng2-alfresco-userinfo/', + 'ng2-alfresco-viewer': 'node_modules/ng2-alfresco-viewer/', + 'ng2-alfresco-webscript': 'node_modules/ng2-alfresco-webscript/', + 'ng2-charts': 'node_modules/ng2-charts', + 'moment': 'node_modules/moment/min/moment.min' + + }, + paths: { + '*': '*.js' + }, + meta: { + 'node_modules/@angular/*': {build: false}, + 'node_modules/rxjs/*': {build: false}, + 'node_modules/ng2-translate/*': {build: false}, + 'node_modules/ng2-charts/*': {build: false}, + 'node_modules/ng2-alfresco-core/*': {build: false}, + 'node_modules/ng2-activiti-diagrams/*': {build: false}, + 'node_modules/ng2-activiti-analytics/*': {build: false}, + 'node_modules/ng2-alfresco-datatable/*': {build: false}, + 'node_modules/ng2-alfresco-documentlist/*': {build: false}, + 'node_modules/ng2-activiti-form/*': {build: false}, + 'node_modules/ng2-alfresco-login/*': {build: false}, + 'node_modules/ng2-activiti-processlist/*': {build: false}, + 'node_modules/ng2-alfresco-search/*': {build: false}, + 'node_modules/ng2-activiti-tasklist/*': {build: false}, + 'node_modules/ng2-alfresco-tag/*': {build: false}, + 'node_modules/ng2-alfresco-upload/*': {build: false}, + 'node_modules/ng2-alfresco-userinfo/*': {build: false}, + 'node_modules/ng2-alfresco-viewer/*': {build: false}, + 'node_modules/ng2-alfresco-webscript/*': {build: false} + } + }; + + var pkg = require('./package.json'); + var namePkg = pkg.name; + + var builder = new Builder(CONFIG_TYPESCRIPT); + builder + .buildStatic(APP_SRC + "/index", 'bundles/' + namePkg + '.js', BUNDLER_OPTIONS) + .then(function () { + return done(); + }) + .catch(function (err) { + return done(err); + }); +}); + +gulp.task('build.assets.prod', () => { + return gulp.src([ + join('src/**', '*.ts'), + 'index.ts', + join('src/**', '*.css'), + join('src/**', '*.html'), + '!'+join('*/**', '*.d.ts'), + '!'+join('*/**', '*.spec.ts'), + '!gulpfile.ts']) + +}); + +gulp.task('build.bundles', () => { + merge(bundleShims()); + + /** + * Returns the shim files to be injected. + */ + function getShims() { + let libs = getInjectableDependency() + .filter(d => /\.js$/.test(d.src)); + + return libs.filter(l => l.inject === 'shims') + .concat(libs.filter(l => l.inject === 'libs')) + .concat(libs.filter(l => l.inject === true)) + .map(l => l.src); + } + + /** + * Bundles the shim files. + */ + function bundleShims() { + return gulp.src(getShims()) + .pipe(plugins.concat(JS_PROD_SHIMS_BUNDLE)) + // Strip the first (global) 'use strict' added by reflect-metadata, but don't strip any others to avoid unintended scope leaks. + .pipe(plugins.replace(/('|")use strict\1;var Reflect;/, 'var Reflect;')) + .pipe(gulp.dest('bundles')); + } + +}); + +gulp.task('build.js.prod', () => { + const INLINE_OPTIONS = { + base: APP_SRC, + target: 'es5', + useRelativePaths: true, + removeLineBreaks: true + }; + + let tsProject = makeTsProject(); + let src = [ + join('src/**/*.ts'), + join('!src/**/*.d.ts'), + join('!src/**/*.spec.ts'), + `!src/**/${NG_FACTORY_FILE}.ts` + ]; + + let result = gulp.src(src) + .pipe(plugins.plumber()) + .pipe(plugins.inlineNg2Template(INLINE_OPTIONS)) + .pipe(sourcemaps.init()) + .pipe(tsProject()) + .once('error', function (e: any) { + this.once('finish', () => process.exit(1)); + }); + + return result.js + .pipe(plugins.template()) + .pipe(sourcemaps.write()) + .pipe(gulp.dest('src')) + .on('error', (e: any) => { + console.log(e); + }); +}); + +gulp.task('build.prod', (done: any) => + runSequence( + 'build.assets.prod', + 'build.html_css', + 'build.js.prod', + 'build.bundles', + 'build.bundles.app', + done)); diff --git a/ng2-components/ng2-activiti-analytics/karma-test-shim.js b/ng2-components/ng2-activiti-analytics/karma-test-shim.js index 3b4258d80a..4d66211142 100644 --- a/ng2-components/ng2-activiti-analytics/karma-test-shim.js +++ b/ng2-components/ng2-activiti-analytics/karma-test-shim.js @@ -5,7 +5,7 @@ jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; __karma__.loaded = function() {}; -var builtPath = '/base/dist/'; +var builtPath = '/base/src/'; function isJsFile(path) { return path.slice(-3) == '.js'; @@ -29,7 +29,7 @@ var paths = { }; var map = { - 'app': 'base/dist', + 'app': 'base/src', // angular bundles '@angular/core': 'npm:@angular/core/bundles/core.umd.js', '@angular/common': 'npm:@angular/common/bundles/common.umd.js', @@ -57,9 +57,8 @@ var map = { 'moment' : 'npm:moment/min/moment.min.js', 'alfresco-js-api': 'npm:alfresco-js-api/dist', - 'ng2-activiti-analytics': 'npm:ng2-activiti-analytics/dist', - 'ng2-activiti-diagrams': 'npm:ng2-activiti-diagrams/dist', - 'ng2-alfresco-core': 'npm:ng2-alfresco-core/dist' + 'ng2-activiti-diagrams': 'npm:ng2-activiti-diagrams', + 'ng2-alfresco-core': 'npm:ng2-alfresco-core' }; var packages = { @@ -71,7 +70,6 @@ var packages = { 'moment': { defaultExtension: 'js' }, 'alfresco-js-api': { main: './alfresco-js-api.js', defaultExtension: 'js'}, - 'ng2-activiti-analytics': { main: './index.js', defaultExtension: 'js'}, 'ng2-activiti-diagrams': { main: './index.js', defaultExtension: 'js'}, 'ng2-alfresco-core': { main: './index.js', defaultExtension: 'js'} }; diff --git a/ng2-components/ng2-activiti-analytics/karma.conf.js b/ng2-components/ng2-activiti-analytics/karma.conf.js index 496c6a6e9b..b58f0e4d3d 100644 --- a/ng2-components/ng2-activiti-analytics/karma.conf.js +++ b/ng2-components/ng2-activiti-analytics/karma.conf.js @@ -24,8 +24,8 @@ module.exports = function (config) { 'node_modules/zone.js/dist/fake-async-test.js', // RxJs - {pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false}, - {pattern: 'node_modules/rxjs/**/*.js.map', included: false, watched: false}, + { pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false }, + { pattern: 'node_modules/rxjs/**/*.js.map', included: false, watched: false }, // Paths loaded via module imports: // Angular itself @@ -41,20 +41,25 @@ module.exports = function (config) { 'karma-test-shim.js', // paths loaded via module imports - {pattern: 'dist/**/*.js', included: false, watched: true}, - {pattern: 'dist/**/*.html', included: true, served: true, watched: true}, - {pattern: 'dist/**/*.css', included: true, served: true, watched: true}, + {pattern: 'src/**/*.js', included: false, watched: true}, + {pattern: 'src/**/*.html', included: true, served: true, watched: true}, + {pattern: 'src/**/*.css', included: true, served: true, watched: true}, // ng2-components - { pattern: 'node_modules/ng2-alfresco-core/dist/**/*.*', included: false, served: true, watched: false }, - { pattern: 'node_modules/ng2-activiti-diagrams/dist/**/*.*', included: false, served: true, watched: false }, + { pattern: 'node_modules/ng2-alfresco-core/src/**/*.*', included: false, served: true, watched: false }, + { pattern: 'node_modules/ng2-alfresco-core/index.js', included: false, served: true, watched: false }, + + { pattern: 'node_modules/ng2-activiti-diagrams/src/**/*.*', included: false, served: true, watched: false }, + { pattern: 'node_modules/ng2-activiti-diagrams/index.js', included: false, served: true, watched: false }, + { pattern: 'node_modules/ng2-charts/**/*.js', included: false, served: true, watched: false }, { pattern: 'node_modules/md-date-time-picker/**/*.js', included: false, served: true, watched: false }, { pattern: 'node_modules/moment/**/*.js', included: false, served: true, watched: false }, // paths to support debugging with source maps in dev tools {pattern: 'src/**/*.ts', included: false, watched: false}, - {pattern: 'dist/**/*.js.map', included: false, watched: false} + {pattern: 'src/**/*.js.map', included: false, watched: false}, + {pattern: 'src/**/*.json', included: false, watched: false} ], exclude: [ @@ -102,7 +107,7 @@ module.exports = function (config) { // Source files that you wanna generate coverage for. // Do not include tests or libraries (these files will be instrumented by Istanbul) preprocessors: { - 'dist/**/!(*spec|index|*mock|*model).js': 'coverage' + 'src/**/!(*spec|index|*mock|*model).js': 'coverage' }, coverageReporter: { diff --git a/ng2-components/ng2-activiti-analytics/package.json b/ng2-components/ng2-activiti-analytics/package.json index 229d77a173..4db8b4ea3e 100644 --- a/ng2-components/ng2-activiti-analytics/package.json +++ b/ng2-components/ng2-activiti-analytics/package.json @@ -1,28 +1,30 @@ { "name": "ng2-activiti-analytics", "description": "Activiti Angular2 Analytics Component", - "version": "0.5.0", + "version": "1.0.0", "author": "Alfresco Software, Ltd.", - "main": "./dist/index.js", - "typings": "./dist/index.d.ts", "scripts": { - "clean": "npm install rimraf && rimraf dist node_modules typings", - "build": "npm run tslint && rimraf dist && tsc && npm run copy-dist && license-check", - "build:w": "npm run tslint && rimraf dist && npm run watch-task", - "watch-task": "concurrently \"npm run tsc:w\" \"npm run copy-dist:w\" \"license-check\"", - "tslint": "tslint -c tslint.json *.ts && tslint -c tslint.json 'src/{,**/}**.ts'", - "copy-dist": "cpx \"./src/**/*.{html,css,json,png,jpg,gif,svg}\" ./dist/src", - "copy-dist:w": "cpx \"./src/**/*.{html,css,json,png,jpg,gif,svg}\" ./dist/src -w", + "clean": "npm install rimraf && npm run clean-build && rimraf dist node_modules typings", + "clean-build": "rimraf index.js index.js.map index.d.ts'src/{,**/}**.js' 'src/{,**/}**.js.map' 'src/{,**/}**.d.ts' bundles", + "build": "npm run clean-build && npm run tslint && rimraf dist && tsc && license-check && npm run build.umd", + "build:w": "npm run clean-build && npm run tslint && rimraf dist && tsc:w && license-check npm run build.umd", + "tslint": "tslint -c tslint.json 'src/{,**/}**.ts' 'index.ts' -e '{,**/}**.d.ts' -e './gulpfile.ts'", "tsc": "tsc", "tsc:w": "tsc -w", "pretest": "npm run build", "test": "karma start karma.conf.js --reporters mocha,coverage --single-run", - "test-browser": "concurrently \"karma start karma.conf.js --reporters kjhtml\" \"npm run watch-task\"", + "test-browser": "npm run build && concurrently \"karma start karma.conf.js --reporters kjhtml\" \"npm run watch-task\"", "posttest": "remap-istanbul -i coverage/report/coverage-final.json -o coverage/report -t html && remap-istanbul -i coverage/report/coverage-final.json -o coverage/report/coverage-final.json", "coverage": "npm run test && wsrv -o -p 9875 ./coverage/report", "prepublish": "npm run build", - "travis": "npm link ng2-alfresco-core ng2-activiti-diagrams" + "travis": "npm link ng2-alfresco-core ng2-activiti-diagrams", + "gulp": "gulp", + "build.umd": "gulp build.prod --color --env-config prod --build-type prod", + "reinstall": "npm cache clean && npm install" }, + "main": "./index.js", + "module": "./index.js", + "typings": "./index.d.ts", "contributors": [ { "name": "Mario Romano", @@ -41,6 +43,7 @@ "url": "https://github.com/Alfresco/alfresco-ng2-components/issues" }, "dependencies": { + "@angular/router": "3.0.0", "@angular/common": "2.0.0", "@angular/compiler": "2.0.0", "@angular/core": "2.0.0", @@ -53,36 +56,53 @@ "rxjs": "5.0.0-beta.12", "systemjs": "0.19.27", "zone.js": "^0.6.23", - "chart.js": "^2.1.4", "md-date-time-picker": "^2.2.0", "ng2-charts": "1.1.0", "moment": "2.15.1", "raphael": "^2.2.6", - - "alfresco-js-api": "^0.5.0", + "alfresco-js-api": "^1.0.0", "ng2-translate": "2.5.0", - "ng2-alfresco-core": "0.5.0", - "ng2-activiti-diagrams": "0.5.0" + "ng2-alfresco-core": "1.0.0", + "ng2-activiti-diagrams": "1.0.0" }, "devDependencies": { - "@types/node": "^6.0.42", - "@types/core-js": "^0.9.32", "@types/jasmine": "^2.2.33", + "@types/node": "^6.0.42", "concurrently": "^2.2.0", "cpx": "1.3.1", + "cssnano": "^3.8.1", + "gulp": "^3.9.1", + "gulp-autoprefixer": "^3.1.1", + "gulp-cached": "^1.1.1", + "gulp-concat": "^2.6.1", + "gulp-concat-css": "^2.3.0", + "gulp-filter": "^4.0.0", + "gulp-inline-ng2-template": "^4.0.0", + "gulp-load-plugins": "^1.4.0", + "gulp-plumber": "^1.1.0", + "gulp-postcss": "^6.2.0", + "gulp-replace": "^0.5.4", + "gulp-sourcemaps": "^1.9.1", + "gulp-template": "^4.0.0", + "gulp-typescript": "^3.1.3", + "gulp-uglify": "^2.0.0", + "intl": "^1.2.5", "jasmine-core": "2.4.1", "karma": "0.13.22", "karma-chrome-launcher": "1.0.1", "karma-coverage": "1.0.0", "karma-jasmine": "1.0.2", "karma-jasmine-ajax": "^0.1.13", - "karma-mocha-reporter": "2.0.3", "karma-jasmine-html-reporter": "0.2.0", + "karma-mocha-reporter": "2.0.3", "license-check": "1.1.5", "remap-istanbul": "0.6.3", "rimraf": "2.5.2", + "run-sequence": "^1.2.2", + "systemjs-builder": "^0.15.34", "traceur": "0.0.91", + "ts-node": "^1.7.0", "tslint": "3.15.1", "typescript": "^2.0.3", "wsrv": "^0.1.5" @@ -93,7 +113,7 @@ ], "license-check-config": { "src": [ - "./dist/**/*.js" + "./src/**/*.js" ], "path": "assets/license_header.txt", "blocking": true, diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-heat-map.component.html b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-heat-map.component.html index e9c271f63f..b61bbc4257 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-heat-map.component.html +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-heat-map.component.html @@ -1,9 +1,9 @@ -

Process Heat map

+

Process Heat map

- +
-
No metric found
\ No newline at end of file +
No metric found
diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-heat-map.component.spec.ts b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-heat-map.component.spec.ts index 3be8225c59..bb02e9a5e9 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-heat-map.component.spec.ts +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-heat-map.component.spec.ts @@ -33,9 +33,13 @@ describe('Test ng2-activiti-analytics-report-heat-map', () => { let debug: DebugElement; let element: HTMLElement; - let totalCountPerc = {'sid-fake-id': 0, 'fake-start-event': 100}; - let totalTimePerc = {'sid-fake-id': 10, 'fake-start-event': 30}; - let avgTimePercentages = {'sid-fake-id': 5, 'fake-start-event': 50}; + let totalCountPerc = { 'sid-fake-id': 0, 'fake-start-event': 100 }; + let totalTimePerc = { 'sid-fake-id': 10, 'fake-start-event': 30 }; + let avgTimePercentages = { 'sid-fake-id': 5, 'fake-start-event': 50 }; + + let totalCountValues = { 'sid-fake-id': 2, 'fake-start-event': 3 }; + let totalTimeValues = { 'sid-fake-id': 1, 'fake-start-event': 4 }; + let avgTimeValues = { 'sid-fake-id': 4, 'fake-start-event': 5 }; beforeEach(async(() => { TestBed.configureTestingModule({ @@ -65,7 +69,10 @@ describe('Test ng2-activiti-analytics-report-heat-map', () => { component.report = { totalCountsPercentages: totalCountPerc, + totalCountValues: totalCountValues, totalTimePercentages: totalTimePerc, + totalTimeValues: totalTimeValues, + avgTimeValues: avgTimeValues, avgTimePercentages: avgTimePercentages }; }); @@ -81,7 +88,7 @@ describe('Test ng2-activiti-analytics-report-heat-map', () => { }); it('should render the dropdown with the metric options', async(() => { - component.report = {totalCountsPercentages: {'sid-fake-id': 10, 'fake-start-event': 30}}; + component.report = { totalCountsPercentages: { 'sid-fake-id': 10, 'fake-start-event': 30 } }; component.onSuccess.subscribe(() => { fixture.whenStable().then(() => { @@ -106,21 +113,24 @@ describe('Test ng2-activiti-analytics-report-heat-map', () => { })); it('should change the currentmetric width totalCount', async(() => { - let field = {value: 'totalCount'}; + let field = { value: 'totalCount' }; component.onMetricChanges(field); - expect(component.currentMetric).toEqual(totalCountPerc); + expect(component.currentMetric).toEqual(totalCountValues); + expect(component.currentMetricColors).toEqual(totalCountPerc); })); it('should change the currentmetric width totalTime', async(() => { - let field = {value: 'totalTime'}; + let field = { value: 'totalTime' }; component.onMetricChanges(field); - expect(component.currentMetric).toEqual(totalTimePerc); + expect(component.currentMetric).toEqual(totalTimeValues); + expect(component.currentMetricColors).toEqual(totalTimePerc); })); it('should change the currentmetric width avgTime', async(() => { - let field = {value: 'avgTime'}; + let field = { value: 'avgTime' }; component.onMetricChanges(field); - expect(component.currentMetric).toEqual(avgTimePercentages); + expect(component.currentMetric).toEqual(avgTimeValues); + expect(component.currentMetricColors).toEqual(avgTimePercentages); })); }); diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-heat-map.component.ts b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-heat-map.component.ts index a9e9bf8db0..064b4a04c2 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-heat-map.component.ts +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-heat-map.component.ts @@ -40,12 +40,14 @@ export class AnalyticsReportHeatMapComponent implements OnInit { metricForm: FormGroup; currentMetric: string; + currentMetricColors: string; + metricType: string; constructor(private translate: AlfrescoTranslationService, private analyticsService: AnalyticsService, private formBuilder: FormBuilder) { if (translate) { - translate.addTranslationFolder('ng2-activiti-analytics', 'node_modules/ng2-activiti-analytics/dist/src'); + translate.addTranslationFolder('ng2-activiti-analytics', 'node_modules/ng2-activiti-analytics/src'); } } @@ -64,11 +66,17 @@ export class AnalyticsReportHeatMapComponent implements OnInit { onMetricChanges(field: any) { if (field.value === 'totalCount') { - this.currentMetric = this.report.totalCountsPercentages; + this.currentMetric = this.report.totalCountValues; + this.currentMetricColors = this.report.totalCountsPercentages; + this.metricType = 'times'; } else if (field.value === 'totalTime') { - this.currentMetric = this.report.totalTimePercentages; + this.currentMetric = this.report.totalTimeValues; + this.currentMetricColors = this.report.totalTimePercentages; + this.metricType = 'hours'; } else if (field.value === 'avgTime') { - this.currentMetric = this.report.avgTimePercentages; + this.currentMetric = this.report.avgTimeValues; + this.currentMetricColors = this.report.avgTimePercentages; + this.metricType = 'hours'; } } diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-list.component.spec.ts b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-list.component.spec.ts index 8709b8157c..ce2cf64a8f 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-list.component.spec.ts +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-list.component.spec.ts @@ -82,8 +82,26 @@ describe('Test ng2-activiti-analytics Report list', () => { }); it('should return the default reports when the report list is empty', (done) => { + jasmine.Ajax.stubRequest('http://localhost:9999/activiti-app/app/rest/reporting/reports').andReturn({ + status: 200, + contentType: 'json', + responseText: [] + }); + fixture.detectChanges(); + jasmine.Ajax.stubRequest('http://localhost:9999/activiti-app/app/rest/reporting/default-reports').andReturn({ + status: 200, + contentType: 'json', + responseText: [] + }); + + jasmine.Ajax.stubRequest('http://localhost:9999/activiti-app/app/rest/reporting/reports').andReturn({ + status: 200, + contentType: 'json', + responseText: reportList + }); + component.onSuccess.subscribe(() => { fixture.detectChanges(); expect(element.querySelector('#report-list-0 > i').innerHTML).toBe('assignment'); @@ -96,23 +114,6 @@ describe('Test ng2-activiti-analytics Report list', () => { done(); }); - jasmine.Ajax.requests.mostRecent().respondWith({ - status: 200, - contentType: 'json', - responseText: [] - }); - - jasmine.Ajax.requests.mostRecent().respondWith({ - status: 200, - contentType: 'json', - responseText: [] - }); - - jasmine.Ajax.requests.mostRecent().respondWith({ - status: 200, - contentType: 'json', - responseText: reportList - }); }); it('Report render the report list relative to a single app', (done) => { diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-list.component.ts b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-list.component.ts index 979d8ad0b1..47ce38c21b 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-list.component.ts +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-list.component.ts @@ -57,13 +57,21 @@ export class AnalyticsReportListComponent implements OnInit { this.reports.push(report); }); - this.getReportListByAppId(); + this.getReportList(); } /** - * Get the report list by app id + * Reload the component */ - getReportListByAppId() { + reload() { + this.reset(); + this.getReportList(); + } + + /** + * Get the report list + */ + getReportList() { this.analyticsService.getReportList().subscribe( (res: ReportParametersModel[]) => { if (res && res.length === 0) { @@ -108,6 +116,15 @@ export class AnalyticsReportListComponent implements OnInit { return this.reports === undefined || (this.reports && this.reports.length === 0); } + /** + * Reset the list + */ + private reset() { + if (!this.isReportsEmpty()) { + this.reports = []; + } + } + /** * Select the current report * @param report diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.css b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.css index ae995ca854..344b6e0525 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.css +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.css @@ -21,3 +21,30 @@ .dropdown-widget__invalid .mdl-textfield__error { visibility: visible !important; } + +.large { + font-size: x-large; + margin-top: 24px; + margin-left: 12px; +} + +.icon-small i { + float: left; + margin-right: 10px; + display: none; + position: absolute; +} + +.icon-small h4 { + clear: left; + margin-left: 26px; +} + +.icon-small:hover { + color: rgb(68,138,255); + cursor: pointer; +} + +.icon-small:hover .material-icons { + display: block; +} diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.html b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.html index 3fe322d9f7..7c277338bb 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.html +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.html @@ -1,7 +1,24 @@
-

{{reportParameters.name}}

+
+ +
+
+ + mode_edit +

{{reportParameters.name}}

+
+

@@ -55,4 +72,4 @@
-
\ No newline at end of file +
diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.spec.ts b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.spec.ts index bb435e61cc..74eb9075ee 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.spec.ts +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.spec.ts @@ -87,7 +87,7 @@ describe('Test ng2-analytics-report-parameters Report Parameters ', () => { component.onSuccessReportParams.subscribe(() => { fixture.detectChanges(); let dropDown: any = element.querySelector('#select-status'); - expect(element.querySelector('h1').innerHTML).toEqual('Fake Task overview status'); + expect(element.querySelector('h4').innerHTML).toEqual('Fake Task overview status'); expect(dropDown).toBeDefined(); expect(dropDown.length).toEqual(4); expect(dropDown[0].innerHTML).toEqual('Choose One'); @@ -280,21 +280,22 @@ describe('Test ng2-analytics-report-parameters Report Parameters ', () => { done(); }); - let reportId = 1; - let change = new SimpleChange(null, reportId); - component.ngOnChanges({ 'reportId': change }); - - jasmine.Ajax.requests.first().respondWith({ + jasmine.Ajax.stubRequest('http://localhost:9999/activiti-app/app/rest/reporting/report-params/1').andReturn({ status: 200, contentType: 'json', responseText: analyticParamsMock.reportDefParamProcessDef }); - jasmine.Ajax.requests.mostRecent().respondWith({ + jasmine.Ajax.stubRequest('http://localhost:9999/activiti-app/app/rest/reporting/process-definitions').andReturn({ status: 200, contentType: 'json', responseText: analyticParamsMock.reportDefParamProcessDefOptionsNoApp }); + + let reportId = 1; + let change = new SimpleChange(null, reportId); + component.ngOnChanges({ 'reportId': change }); + }); it('Should render a dropdown with all the process definition when the definition parameter type is \'processDefinition\' and the' + @@ -310,22 +311,24 @@ describe('Test ng2-analytics-report-parameters Report Parameters ', () => { done(); }); - let appId = 1; - component.appId = appId; - let change = new SimpleChange(null, appId); - component.ngOnChanges({ 'appId': change }); - - jasmine.Ajax.requests.first().respondWith({ + jasmine.Ajax.stubRequest('http://localhost:9999/activiti-app/app/rest/reporting/report-params/1').andReturn({ status: 200, contentType: 'json', responseText: analyticParamsMock.reportDefParamProcessDef }); - jasmine.Ajax.requests.mostRecent().respondWith({ + jasmine.Ajax.stubRequest('http://localhost:9999/activiti-app/api/enterprise/process-definitions').andReturn({ status: 200, contentType: 'json', responseText: analyticParamsMock.reportDefParamProcessDefOptionsApp }); + + let appId = 1; + component.appId = appId; + component.reportId = 1; + let change = new SimpleChange(null, appId); + component.ngOnChanges({ 'appId': change }); + }); it('Should load the task list when a process definition is selected', () => { @@ -355,21 +358,22 @@ describe('Test ng2-analytics-report-parameters Report Parameters ', () => { done(); }); - let reportId = 1; - let change = new SimpleChange(null, reportId); - component.ngOnChanges({ 'reportId': change }); - - jasmine.Ajax.requests.first().respondWith({ + jasmine.Ajax.stubRequest('http://localhost:9999/activiti-app/app/rest/reporting/report-params/1').andReturn({ status: 200, contentType: 'json', responseText: analyticParamsMock.reportDefParamProcessDef }); - jasmine.Ajax.requests.mostRecent().respondWith({ + jasmine.Ajax.stubRequest('http://localhost:9999/activiti-app/app/rest/reporting/process-definitions').andReturn({ status: 404, contentType: 'json', responseText: [] }); + + let reportId = 1; + let change = new SimpleChange(null, reportId); + component.ngOnChanges({ 'reportId': change }); + }); it('Should emit an error with a 404 response when the report parameters response is not found', (done) => { diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.ts b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.ts index cf16698e80..cd9b7366e2 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.ts +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.ts @@ -47,6 +47,9 @@ export class AnalyticsReportParametersComponent implements OnInit, OnChanges { @Output() onError = new EventEmitter(); + @Output() + onEdit = new EventEmitter(); + @Output() onFormValueChanged = new EventEmitter(); @@ -63,12 +66,13 @@ export class AnalyticsReportParametersComponent implements OnInit, OnChanges { private dropDownSub; private reportParamsSub; private paramOpts; + private isEditable: boolean = false; constructor(private translate: AlfrescoTranslationService, private analyticsService: AnalyticsService, private formBuilder: FormBuilder ) { if (translate) { - translate.addTranslationFolder('ng2-activiti-analytics', 'node_modules/ng2-activiti-analytics/dist/src'); + translate.addTranslationFolder('ng2-activiti-analytics', 'node_modules/ng2-activiti-analytics/src'); } } @@ -92,6 +96,7 @@ export class AnalyticsReportParametersComponent implements OnInit, OnChanges { } ngOnChanges(changes: SimpleChanges) { + this.isEditable = false; let reportId = changes['reportId']; if (reportId && reportId.currentValue) { this.getReportParams(reportId.currentValue); @@ -210,4 +215,25 @@ export class AnalyticsReportParametersComponent implements OnInit, OnChanges { this.reportParamsSub.unsubscribe(); } } + + public editEnable() { + this.isEditable = true; + } + + public editDisable() { + this.isEditable = false; + } + + public editTitle() { + this.reportParamsSub = this.analyticsService.updateReport(this.reportParameters.id, this.reportParameters.name).subscribe( + (res: ReportParametersModel) => { + this.editDisable(); + this.onEdit.emit(this.reportParameters.name); + }, + (err: any) => { + console.log(err); + this.onError.emit(err); + } + ); + } } diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics.component.html b/ng2-components/ng2-activiti-analytics/src/components/analytics.component.html index 3f0e5c2e8c..a52b7480c7 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/analytics.component.html +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics.component.html @@ -1,10 +1,13 @@
+ (onFormValueChanged)="reset()" + (onSuccess)="showReport($event)" + (onEdit)="onEditReport($event)"> +
-

{{report.title}}

+

{{report.title}}

diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics.component.spec.ts b/ng2-components/ng2-activiti-analytics/src/components/analytics.component.spec.ts index ea77c223f8..4adbcbbed8 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/analytics.component.spec.ts +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics.component.spec.ts @@ -190,6 +190,7 @@ describe('Test ng2-activiti-analytics Report ', () => { }); let reportParamQuery = new ReportQuery({status: 'All'}); + component.reportId = 1; component.showReport(reportParamQuery); jasmine.Ajax.requests.mostRecent().respondWith({ @@ -214,6 +215,7 @@ describe('Test ng2-activiti-analytics Report ', () => { }); let reportParamQuery = new ReportQuery({status: 'All'}); + component.reportId = 1; component.showReport(reportParamQuery); jasmine.Ajax.requests.mostRecent().respondWith({ diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics.component.ts b/ng2-components/ng2-activiti-analytics/src/components/analytics.component.ts index 3d12832940..6db510d36d 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/analytics.component.ts +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics.component.ts @@ -41,12 +41,15 @@ export class AnalyticsComponent implements OnChanges { @Output() onSuccess = new EventEmitter(); + @Output() + editReport = new EventEmitter(); + @Output() onError = new EventEmitter(); reportParamQuery = new ReportQuery(); - reports: any[]; + reports: Chart[]; public barChartOptions: any = { responsive: true, @@ -69,7 +72,7 @@ export class AnalyticsComponent implements OnChanges { private analyticsService: AnalyticsService) { console.log('AnalyticsComponent'); if (translate) { - translate.addTranslationFolder('ng2-activiti-analytics', 'node_modules/ng2-activiti-analytics/dist/src'); + translate.addTranslationFolder('ng2-activiti-analytics', 'node_modules/ng2-activiti-analytics/src'); } } @@ -107,4 +110,8 @@ export class AnalyticsComponent implements OnChanges { let clone = JSON.parse(JSON.stringify(report)); report.datasets = clone.datasets; } + + public onEditReport(name: string) { + this.editReport.emit(name); + } } diff --git a/ng2-components/ng2-activiti-analytics/src/components/widgets/date-range/date-range.widget.ts b/ng2-components/ng2-activiti-analytics/src/components/widgets/date-range/date-range.widget.ts index 6b781fd1f8..efd7567d46 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/widgets/date-range/date-range.widget.ts +++ b/ng2-components/ng2-activiti-analytics/src/components/widgets/date-range/date-range.widget.ts @@ -27,6 +27,8 @@ function dateCheck(c: AbstractControl) { return result ? {'greaterThan': true} : null; } +declare let mdDateTimePicker: any; + @Component({ moduleId: module.id, selector: 'date-range-widget', @@ -54,15 +56,9 @@ export class DateRangeWidget extends WidgetComponent { debug: boolean = false; - dialogStart: any = new mdDateTimePicker.default({ - type: 'date', - future: moment().add(21, 'years') - }); + dialogStart: any; - dialogEnd: any = new mdDateTimePicker.default({ - type: 'date', - future: moment().add(21, 'years') - }); + dialogEnd: any; constructor(public elementRef: ElementRef, private formBuilder: FormBuilder) { @@ -72,26 +68,39 @@ export class DateRangeWidget extends WidgetComponent { ngOnInit() { this.initForm(); this.addAccessibilityLabelToDatePicker(); - this.initSartDateDialog(); - this.initEndDateDialog(); } initForm() { - let today = moment().format('YYYY-MM-DD'); + let startDateForm = this.field.value ? this.field.value.startDate : '' ; + let startDate = this.convertToMomentDate(startDateForm); + let endDateForm = this.field.value ? this.field.value.endDate : '' ; + let endDate = this.convertToMomentDate(endDateForm); - let startDateControl = new FormControl(today); + let startDateControl = new FormControl(startDate); startDateControl.setValidators(Validators.required); this.dateRange.addControl('startDate', startDateControl); - let endDateControl = new FormControl(today); + let endDateControl = new FormControl(endDate); endDateControl.setValidators(Validators.required); this.dateRange.addControl('endDate', endDateControl); this.dateRange.setValidators(dateCheck); this.dateRange.valueChanges.subscribe(data => this.onGroupValueChanged(data)); + + this.initSartDateDialog(startDate); + this.initEndDateDialog(endDate); } - initSartDateDialog() { + initSartDateDialog(date: string) { + let settings: any = { + type: 'date', + past: moment().subtract(100, 'years'), + future: moment().add(100, 'years') + }; + + settings.init = moment(date, DateRangeWidget.FORMAT_DATE_ACTIVITI); + + this.dialogStart = new mdDateTimePicker.default(settings); this.dialogStart.trigger = this.startElement.nativeElement; let startDateButton = document.getElementById('startDateButton'); @@ -130,7 +139,16 @@ export class DateRangeWidget extends WidgetComponent { return span; } - initEndDateDialog() { + initEndDateDialog(date: string) { + let settings: any = { + type: 'date', + past: moment().subtract(100, 'years'), + future: moment().add(100, 'years') + }; + + settings.init = moment(date, DateRangeWidget.FORMAT_DATE_ACTIVITI); + + this.dialogEnd = new mdDateTimePicker.default(settings); this.dialogEnd.trigger = this.endElement.nativeElement; let endDateButton = document.getElementById('endDateButton'); @@ -164,16 +182,24 @@ export class DateRangeWidget extends WidgetComponent { onGroupValueChanged(data: any) { if (this.dateRange.valid) { - let dateStart = this.convertMomentDate(this.dateRange.controls['startDate'].value); - let endStart = this.convertMomentDate(this.dateRange.controls['endDate'].value); + let dateStart = this.convertToMomentDateWithTime(this.dateRange.controls['startDate'].value); + let endStart = this.convertToMomentDateWithTime(this.dateRange.controls['endDate'].value); this.dateRangeChanged.emit({startDate: dateStart, endDate: endStart}); } } - public convertMomentDate(date: string) { + public convertToMomentDateWithTime(date: string) { return moment(date, DateRangeWidget.FORMAT_DATE_ACTIVITI, true).format(DateRangeWidget.FORMAT_DATE_ACTIVITI) + 'T00:00:00.000Z'; } + private convertToMomentDate(date: string) { + if (date) { + return moment(date).format(DateRangeWidget.FORMAT_DATE_ACTIVITI); + } else { + return moment().format(DateRangeWidget.FORMAT_DATE_ACTIVITI); + } + } + ngOnDestroy() { } diff --git a/ng2-components/ng2-activiti-analytics/src/components/widgets/widget.component.ts b/ng2-components/ng2-activiti-analytics/src/components/widgets/widget.component.ts index dbab34a340..960c0efc9b 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/widgets/widget.component.ts +++ b/ng2-components/ng2-activiti-analytics/src/components/widgets/widget.component.ts @@ -17,6 +17,8 @@ import { Input, AfterViewInit, Output, EventEmitter, SimpleChanges, OnChanges } from '@angular/core'; +let componentHandler: any; + /** * Base widget component. */ diff --git a/ng2-components/ng2-activiti-analytics/src/models/chart.model.ts b/ng2-components/ng2-activiti-analytics/src/models/chart.model.ts index 658f2e34f1..57ee906a89 100644 --- a/ng2-components/ng2-activiti-analytics/src/models/chart.model.ts +++ b/ng2-components/ng2-activiti-analytics/src/models/chart.model.ts @@ -15,6 +15,8 @@ * limitations under the License. */ +import * as moment from 'moment'; + export class Chart { id: string; type: string; @@ -76,7 +78,7 @@ export class LineChart extends Chart { export class BarChart extends Chart { title: string; titleKey: string; - labels: string[] = []; + labels: any = []; datasets: any[] = []; data: any[] = []; xAxisType: string; diff --git a/ng2-components/ng2-activiti-analytics/src/models/report.model.ts b/ng2-components/ng2-activiti-analytics/src/models/report.model.ts index 54ef72c176..df82947ac2 100644 --- a/ng2-components/ng2-activiti-analytics/src/models/report.model.ts +++ b/ng2-components/ng2-activiti-analytics/src/models/report.model.ts @@ -72,7 +72,7 @@ export class ReportParameterDetailsModel { name: string; nameKey: string; type: string; - value: string; + value: any; options: ParameterValueModel[]; dependsOn: string; diff --git a/ng2-components/ng2-activiti-analytics/src/services/analytics.service.ts b/ng2-components/ng2-activiti-analytics/src/services/analytics.service.ts index 4e3f81dc55..f1ccd7c731 100644 --- a/ng2-components/ng2-activiti-analytics/src/services/analytics.service.ts +++ b/ng2-components/ng2-activiti-analytics/src/services/analytics.service.ts @@ -16,9 +16,9 @@ */ import { Injectable } from '@angular/core'; -import { AlfrescoAuthenticationService, AlfrescoSettingsService } from 'ng2-alfresco-core'; +import { AlfrescoAuthenticationService, AlfrescoSettingsService, AlfrescoApiService } from 'ng2-alfresco-core'; import { Observable } from 'rxjs/Rx'; -import { Response, Http, Headers, RequestOptions, URLSearchParams } from '@angular/http'; +import { Response } from '@angular/http'; import { ReportParametersModel, ParameterValueModel } from '../models/report.model'; import { Chart, PieChart, TableChart, BarChart, HeatMapChart, MultiBarChart } from '../models/chart.model'; @@ -26,7 +26,7 @@ import { Chart, PieChart, TableChart, BarChart, HeatMapChart, MultiBarChart } fr export class AnalyticsService { constructor(private authService: AlfrescoAuthenticationService, - private http: Http, + public apiService: AlfrescoApiService, private alfrescoSettingsService: AlfrescoSettingsService) { } @@ -35,14 +35,10 @@ export class AnalyticsService { * @returns {Observable} */ getReportList(): Observable { - let url = `${this.alfrescoSettingsService.getBPMApiBaseUrl()}/app/rest/reporting/reports`; - let options = this.getRequestOptions(); - return this.http - .get(url, options) + return Observable.fromPromise(this.apiService.getInstance().activiti.reportApi.getReportList()) .map((res: any) => { let reports: ReportParametersModel[] = []; - let body = res.json(); - body.forEach((report: ReportParametersModel) => { + res.forEach((report: ReportParametersModel) => { let reportModel = new ReportParametersModel(report); reports.push(reportModel); }); @@ -51,13 +47,9 @@ export class AnalyticsService { } getReportParams(reportId: string): Observable { - let url = `${this.alfrescoSettingsService.getBPMApiBaseUrl()}/app/rest/reporting/report-params/${reportId}`; - let options = this.getRequestOptions(); - return this.http - .get(url, options) + return Observable.fromPromise(this.apiService.getInstance().activiti.reportApi.getReportParams(reportId)) .map((res: any) => { - let body = res.json(); - return new ReportParametersModel(body); + return new ReportParametersModel(res); }).catch(this.handleError); } @@ -72,7 +64,7 @@ export class AnalyticsService { } } else if (type === 'dateInterval') { return this.getDateIntervalValues(); - } else if (type === 'task') { + } else if (type === 'task' && reportId && processDefinitionId) { return this.getTasksByProcessDefinitionId(reportId, processDefinitionId); } else { return Observable.create(observer => { @@ -124,14 +116,10 @@ export class AnalyticsService { } getProcessDefinitionsValuesNoApp(): Observable { - let url = `${this.alfrescoSettingsService.getBPMApiBaseUrl()}/app/rest/reporting/process-definitions`; - let options = this.getRequestOptions(); - return this.http - .get(url, options) + return Observable.fromPromise(this.apiService.getInstance().activiti.reportApi.getProcessDefinitions()) .map((res: any) => { let paramOptions: ParameterValueModel[] = []; - let body = res.json(); - body.forEach((opt) => { + res.forEach((opt) => { paramOptions.push(new ParameterValueModel(opt)); }); return paramOptions; @@ -139,17 +127,10 @@ export class AnalyticsService { } getProcessDefinitionsValues(appId: string): Observable { - let url = `${this.alfrescoSettingsService.getBPMApiBaseUrl()}/app/rest/process-definitions`; - let params: URLSearchParams; - params = new URLSearchParams(); - params.set('appDefinitionId', appId); - let options = this.getRequestOptions(params); - return this.http - .get(url, options) + return Observable.fromPromise(this.apiService.getInstance().activiti.processDefinitionsApi.getProcessDefinitions(appId)) .map((res: any) => { let paramOptions: ParameterValueModel[] = []; - let body = res.json(); - body.data.forEach((opt) => { + res.data.forEach((opt) => { paramOptions.push(new ParameterValueModel(opt)); }); return paramOptions; @@ -157,42 +138,21 @@ export class AnalyticsService { } getTasksByProcessDefinitionId(reportId: string, processDefinitionId: string): Observable { - if (reportId && processDefinitionId) { - let url = `${this.alfrescoSettingsService.getBPMApiBaseUrl()}/app/rest/reporting/report-params/${reportId}/tasks`; - let params: URLSearchParams; - if (processDefinitionId) { - params = new URLSearchParams(); - params.set('processDefinitionId', processDefinitionId); - } - let options = this.getRequestOptions(params); - return this.http - .get(url, options) - .map((res: any) => { - let paramOptions: ParameterValueModel[] = []; - let body = res.json(); - body.forEach((opt) => { - paramOptions.push(new ParameterValueModel({ id: opt, name: opt })); - }); - return paramOptions; - }).catch(this.handleError); - } else { - return Observable.create(observer => { - observer.next(null); - observer.complete(); - }); - } + return Observable.fromPromise(this.apiService.getInstance().activiti.reportApi.getTasksByProcessDefinitionId(reportId, processDefinitionId)) + .map((res: any) => { + let paramOptions: ParameterValueModel[] = []; + res.forEach((opt) => { + paramOptions.push(new ParameterValueModel({ id: opt, name: opt })); + }); + return paramOptions; + }).catch(this.handleError); } getReportsByParams(reportId: number, paramsQuery: any): Observable { - let url = `${this.alfrescoSettingsService.getBPMApiBaseUrl()}/app/rest/reporting/report-params/${reportId}`; - let body = paramsQuery ? JSON.stringify(paramsQuery) : {}; - let options = this.getRequestOptions(); - return this.http - .post(url, body, options) + return Observable.fromPromise(this.apiService.getInstance().activiti.reportApi.getReportsByParams(reportId, paramsQuery)) .map((res: any) => { let elements: Chart[] = []; - let bodyRes = res.json(); - bodyRes.elements.forEach((chartData) => { + res.elements.forEach((chartData) => { if (chartData.type === 'pieChart') { elements.push(new PieChart(chartData)); } else if (chartData.type === 'table') { @@ -213,31 +173,24 @@ export class AnalyticsService { } public createDefaultReports(): Observable { - let url = `${this.alfrescoSettingsService.getBPMApiBaseUrl()}/app/rest/reporting/default-reports`; - let options = this.getRequestOptions(); - let body = {}; - return this.http - .post(url, body, options) + return Observable.fromPromise(this.apiService.getInstance().activiti.reportApi.createDefaultReports()) + .map(this.toJson) + .catch(this.handleError); + } + + public updateReport(reportId: number, name: string): Observable { + return Observable.fromPromise(this.apiService.getInstance().activiti.reportApi.updateReport(reportId, name)) .map((res: any) => { - return res; + console.log('upload'); }).catch(this.handleError); } - public getHeaders(): Headers { - return new Headers({ - 'Accept': 'application/json', - 'Content-Type': 'application/json', - 'Authorization': this.authService.getTicketBpm() - }); - } - - public getRequestOptions(param?: any): RequestOptions { - let headers = this.getHeaders(); - return new RequestOptions({ headers: headers, withCredentials: true, search: param }); - } - private handleError(error: Response) { console.error(error); return Observable.throw(error.json().error || 'Server error'); } + + toJson(res: any) { + return res || {}; + } } diff --git a/ng2-components/ng2-activiti-analytics/tsconfig.json b/ng2-components/ng2-activiti-analytics/tsconfig.json index 7be35bfec8..276e808597 100644 --- a/ng2-components/ng2-activiti-analytics/tsconfig.json +++ b/ng2-components/ng2-activiti-analytics/tsconfig.json @@ -3,11 +3,10 @@ "target": "es5", "module": "commonjs", "moduleResolution": "node", + "sourceMap": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, - "sourceMap": true, - "removeComments": true, - "declaration": true, + "skipLibCheck": true, "noLib": false, "allowUnreachableCode": false, "allowUnusedLabels": false, @@ -15,12 +14,24 @@ "noImplicitReturns": false, "noImplicitUseStrict": false, "noFallthroughCasesInSwitch": true, - "outDir": "dist", - "types": ["core-js", "jasmine", "node"] + "removeComments": true, + "declaration": true, + "lib": [ + "es2015", + "dom" + ], + "suppressImplicitAnyIndexErrors": true }, "exclude": [ "demo", "node_modules", - "dist" - ] + "dist", + "tools", + "gulpfile.ts", + "gulpfile.d.ts" + ], + "angularCompilerOptions": { + "strictMetadataEmit": false, + "skipTemplateCodegen": true + } } diff --git a/ng2-components/ng2-activiti-analytics/tslint.json b/ng2-components/ng2-activiti-analytics/tslint.json index 27e0dd81da..acc666937e 100644 --- a/ng2-components/ng2-activiti-analytics/tslint.json +++ b/ng2-components/ng2-activiti-analytics/tslint.json @@ -53,7 +53,7 @@ "no-eval": true, "no-inferrable-types": false, "no-internal-module": true, - "no-require-imports": true, + "no-require-imports": false, "no-shadowed-variable": true, "no-switch-case-fall-through": true, "no-trailing-whitespace": true, diff --git a/ng2-components/ng2-activiti-diagrams/.gitignore b/ng2-components/ng2-activiti-diagrams/.gitignore index fe20e77f42..fb23a7fef5 100644 --- a/ng2-components/ng2-activiti-diagrams/.gitignore +++ b/ng2-components/ng2-activiti-diagrams/.gitignore @@ -6,10 +6,14 @@ coverage dist src/**/*.js src/**/*.js.map - +src/**/*.d.ts demo/**/*.js demo/**/*.js.map demo/**/*.d.ts index.js index.js.map !systemjs.config.js +*.tgz +/package/ +/bundles/ +index.d.ts diff --git a/ng2-components/ng2-activiti-diagrams/.npmignore b/ng2-components/ng2-activiti-diagrams/.npmignore index c5ca623298..8bb008aff4 100644 --- a/ng2-components/ng2-activiti-diagrams/.npmignore +++ b/ng2-components/ng2-activiti-diagrams/.npmignore @@ -2,14 +2,15 @@ npm-debug.log .idea coverage/ +demo/ node_modules typings/ fonts/ /.editorconfig /.travis.yml -/*.js /*.json -/*.ts -/*.js.map +/karma-test-shim.js +/karma.conf.js +/gulpfile.ts /.npmignore diff --git a/ng2-components/ng2-activiti-diagrams/assets/Polyline.js b/ng2-components/ng2-activiti-diagrams/assets/Polyline.js deleted file mode 100644 index 9983929cf1..0000000000 --- a/ng2-components/ng2-activiti-diagrams/assets/Polyline.js +++ /dev/null @@ -1,372 +0,0 @@ -/** - * Class to generate polyline - * - * @author Dmitry Farafonov - */ - -var ANCHOR_TYPE= { - main: "main", - middle: "middle", - first: "first", - last: "last" -}; - -function Anchor(uuid, type, x, y) { - this.uuid = uuid; - this.x = x; - this.y = y; - this.type = (type == ANCHOR_TYPE.middle) ? ANCHOR_TYPE.middle : ANCHOR_TYPE.main; -}; -Anchor.prototype = { - uuid: null, - x: 0, - y: 0, - type: ANCHOR_TYPE.main, - isFirst: false, - isLast: false, - ndex: 0, - typeIndex: 0 -}; - -function Polyline(uuid, points, strokeWidth, paper) { - /* Array on coordinates: - * points: [{x: 410, y: 110}, 1 - * {x: 570, y: 110}, 1 2 - * {x: 620, y: 240}, 2 3 - * {x: 750, y: 270}, 3 4 - * {x: 650, y: 370}]; 4 - */ - this.points = points; - - /* - * path for graph - * [["M", x1, y1], ["L", x2, y2], ["C", ax, ay, bx, by, x3, y3], ["L", x3, y3]] - */ - this.path = []; - - this.anchors = []; - - if (strokeWidth) this.strokeWidth = strokeWidth; - - this.paper = paper; - - this.closePath = false; - - this.init(); -}; - -Polyline.prototype = { - id: null, - points: [], - path: [], - anchors: [], - strokeWidth: 1, - radius: 1, - showDetails: false, - paper: null, - element: null, - isDefaultConditionAvailable: false, - closePath: false, - - init: function(points){ - var linesCount = this.getLinesCount(); - if (linesCount < 1) - return; - - this.normalizeCoordinates(); - - // create anchors - - this.pushAnchor(ANCHOR_TYPE.first, this.getLine(0).x1, this.getLine(0).y1); - - for (var i = 1; i < linesCount; i++) - { - var line1 = this.getLine(i-1); - this.pushAnchor(ANCHOR_TYPE.main, line1.x2, line1.y2); - } - - this.pushAnchor(ANCHOR_TYPE.last, this.getLine(linesCount-1).x2, this.getLine(linesCount-1).y2); - - this.rebuildPath(); - }, - - normalizeCoordinates: function(){ - for(var i=0; i < this.points.length; i++){ - this.points[i].x = parseFloat(this.points[i].x); - this.points[i].y = parseFloat(this.points[i].y); - } - }, - - getLinesCount: function(){ - return this.points.length-1; - }, - _getLine: function(i){ - if (this.points.length > i && this.points[i]) { - return {x1: this.points[i].x, y1: this.points[i].y, x2: this.points[i+1].x, y2: this.points[i+1].y}; - } else { - return undefined; - } - }, - getLine: function(i){ - var line = this._getLine(i); - if (line != undefined) { - line.angle = this.getLineAngle(i); - } - return line; - }, - getLineAngle: function(i){ - var line = this._getLine(i); - return Math.atan2(line.y2 - line.y1, line.x2 - line.x1); - }, - getLineLengthX: function(i){ - var line = this.getLine(i); - return (line.x2 - line.x1); - }, - getLineLengthY: function(i){ - var line = this.getLine(i); - return (line.y2 - line.y1); - }, - getLineLength: function(i){ - return Math.sqrt(Math.pow(this.getLineLengthX(i), 2) + Math.pow(this.getLineLengthY(i), 2)); - }, - - getAnchors: function(){ - return this.anchors; - }, - getAnchorsCount: function(type){ - if (!type) - return this.anchors.length; - else { - var count = 0; - for(var i=0; i < this.getAnchorsCount(); i++){ - var anchor = this.anchors[i]; - if (anchor.getType() == type) { - count++; - } - } - return count; - } - }, - - pushAnchor: function(type, x, y, index){ - if (type == ANCHOR_TYPE.first) { - index = 0; - typeIndex = 0; - } else if (type == ANCHOR_TYPE.last) { - index = this.getAnchorsCount(); - typeIndex = 0; - } else if (!index) { - index = this.anchors.length; - } else { - for(var i=0; i < this.getAnchorsCount(); i++){ - var anchor = this.anchors[i]; - if (anchor.index > index) { - anchor.index++; - anchor.typeIndex++; - } - } - } - - var anchor = new Anchor(this.id, ANCHOR_TYPE.main, x, y, index, typeIndex); - - this.anchors.push(anchor); - }, - - getAnchor: function(position){ - return this.anchors[position]; - }, - - getAnchorByType: function(type, position){ - if (type == ANCHOR_TYPE.first) - return this.anchors[0]; - if (type == ANCHOR_TYPE.last) - return this.anchors[this.getAnchorsCount()-1]; - - for(var i=0; i < this.getAnchorsCount(); i++){ - var anchor = this.anchors[i]; - if (anchor.type == type) { - if( position == anchor.position) - return anchor; - } - } - return null; - }, - - addNewPoint: function(position, x, y){ - // - for(var i = 0; i < this.getLinesCount(); i++){ - var line = this.getLine(i); - if (x > line.x1 && x < line.x2 && y > line.y1 && y < line.y2) { - this.points.splice(i+1,0,{x: x, y: y}); - break; - } - } - - this.rebuildPath(); - }, - - rebuildPath: function(){ - var path = []; - - for(var i = 0; i < this.getAnchorsCount(); i++){ - var anchor = this.getAnchor(i); - - var pathType = ""; - if (i == 0) - pathType = "M"; - else - pathType = "L"; - - // TODO: save previous points and calculate new path just if points are updated, and then save currents values as previous - - var targetX = anchor.x, targetY = anchor.y; - if (i>0 && i < this.getAnchorsCount()-1) { - // get new x,y - var cx = anchor.x, cy = anchor.y; - - // pivot point of prev line - var AO = this.getLineLength(i-1); - if (AO < this.radius) { - AO = this.radius; - } - - this.isDefaultConditionAvailable = (this.isDefaultConditionAvailable || (i == 1 && AO > 10)); - - var ED = this.getLineLengthY(i-1) * this.radius / AO; - var OD = this.getLineLengthX(i-1) * this.radius / AO; - targetX = anchor.x - OD; - targetY = anchor.y - ED; - - if (AO < 2*this.radius && i>1) { - targetX = anchor.x - this.getLineLengthX(i-1)/2; - targetY = anchor.y - this.getLineLengthY(i-1)/2;; - } - - // pivot point of next line - var AO = this.getLineLength(i); - if (AO < this.radius) { - AO = this.radius; - } - var ED = this.getLineLengthY(i) * this.radius / AO; - var OD = this.getLineLengthX(i) * this.radius / AO; - var nextSrcX = anchor.x + OD; - var nextSrcY = anchor.y + ED; - - if (AO < 2*this.radius && i 10)); - } - - // anti smoothing - if (this.strokeWidth%2 == 1) { - targetX += 0.5; - targetY += 0.5; - } - - path.push([pathType, targetX, targetY]); - - if (i>0 && i < this.getAnchorsCount()-1) { - path.push(["C", ax, ay, bx, by, zx, zy]); - } - } - - if (this.closePath) - { - path.push(["Z"]); - } - - this.path = path; - }, - - transform: function(transformation) - { - this.element.transform(transformation); - }, - attr: function(attrs) - { - // TODO: foreach and set each - this.element.attr(attrs); - } -}; - -function Polygone(points, strokeWidth) { - /* Array on coordinates: - * points: [{x: 410, y: 110}, 1 - * {x: 570, y: 110}, 1 2 - * {x: 620, y: 240}, 2 3 - * {x: 750, y: 270}, 3 4 - * {x: 650, y: 370}]; 4 - */ - this.points = points; - - /* - * path for graph - * [["M", x1, y1], ["L", x2, y2], ["C", ax, ay, bx, by, x3, y3], ["L", x3, y3]] - */ - this.path = []; - - this.anchors = []; - - if (strokeWidth) this.strokeWidth = strokeWidth; - - this.closePath = true; - this.init(); -}; - - -/* - * Poligone is inherited from Poliline: draws closedPath of polyline - */ - -var Foo = function () { }; -Foo.prototype = Polyline.prototype; - -Polygone.prototype = new Foo(); - -Polygone.prototype.rebuildPath = function(){ - var path = []; - for(var i = 0; i < this.getAnchorsCount(); i++){ - var anchor = this.getAnchor(i); - - var pathType = ""; - if (i == 0) - pathType = "M"; - else - pathType = "L"; - - var targetX = anchor.x, targetY = anchor.y; - - // anti smoothing - if (this.strokeWidth%2 == 1) { - targetX += 0.5; - targetY += 0.5; - } - - path.push([pathType, targetX, targetY]); - } - if (this.closePath) - path.push(["Z"]); - - this.path = path; -}; \ No newline at end of file diff --git a/ng2-components/ng2-activiti-diagrams/demo/.editorconfig b/ng2-components/ng2-activiti-diagrams/demo/.editorconfig new file mode 100644 index 0000000000..75a2477db7 --- /dev/null +++ b/ng2-components/ng2-activiti-diagrams/demo/.editorconfig @@ -0,0 +1,23 @@ +# http://editorconfig.org + +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 4 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[package.json] +indent_style = space +indent_size = 2 + +[karma.conf.js] +indent_style = space +indent_size = 2 + +[*.md] +insert_final_newline = false +trim_trailing_whitespace = false diff --git a/ng2-components/ng2-activiti-diagrams/demo/package.json b/ng2-components/ng2-activiti-diagrams/demo/package.json index 381dafd2c9..d00651baa9 100644 --- a/ng2-components/ng2-activiti-diagrams/demo/package.json +++ b/ng2-components/ng2-activiti-diagrams/demo/package.json @@ -5,15 +5,16 @@ "author": "Alfresco Software, Ltd.", "main": "index.js", "scripts": { - "clean": "npm install rimraf && rimraf dist node_modules typings dist", + "clean": "npm install rimraf && npm run clean-build && rimraf dist node_modules typings dist", + "clean-build" : "rimraf 'src/{,**/}**.js' 'src/{,**/}**.js.map' 'src/{,**/}**.d.ts'", "postinstall": "npm run build", "start": "npm run build && concurrently \"npm run tsc:w\" \"npm run server\" ", "server": "wsrv -o -s -l", - "build": "npm run tslint && rimraf dist && tsc", - "build:w": "npm run tslint && rimraf dist && tsc -w", + "build": "npm run tslint && npm run clean-build && npm run tsc", + "build:w": "npm run tslint && rimraf dist && npm run tsc:w", "tsc": "tsc", "tsc:w": "tsc -w", - "tslint": "tslint -c tslint.json *.ts && tslint -c tslint.json src/{,**/}**.ts" + "tslint": "tslint -c tslint.json *.ts && tslint -c tslint.json src/{,**/}**.ts -e '{,**/}**.d.ts'" }, "license": "Apache-2.0", "contributors": [ @@ -30,36 +31,35 @@ "activiti-diagrams" ], "dependencies": { - "@angular/common": "2.0.0", - "@angular/compiler": "2.0.0", - "@angular/core": "2.0.0", - "@angular/forms": "2.0.0", - "@angular/http": "2.0.0", - "@angular/platform-browser": "2.0.0", - "@angular/platform-browser-dynamic": "2.0.0", + "@angular/common": "2.2.2", + "@angular/compiler": "2.2.2", + "@angular/compiler-cli": "2.2.2", + "@angular/core": "2.2.2", + "@angular/forms": "2.2.2", + "@angular/http": "2.2.2", + "@angular/platform-browser": "2.2.2", + "@angular/platform-browser-dynamic": "2.2.2", + "@angular/router": "3.2.2", + "@angular/upgrade": "2.2.2", + "alfresco-js-api": "^1.0.0", "core-js": "^2.4.1", + "dialog-polyfill": "^0.4.3", + "element.scrollintoviewifneeded-polyfill": "^1.0.1", + "intl": "1.2.4", + "material-design-icons": "2.2.3", + "material-design-lite": "1.2.1", + "ng2-activiti-diagrams": "^1.0.0", + "ng2-alfresco-core": "1.0.0", + "ng2-translate": "2.5.0", + "raphael": "^2.2.6", "reflect-metadata": "^0.1.3", "rxjs": "5.0.0-beta.12", "systemjs": "0.19.27", - "zone.js": "^0.6.23", - - "intl": "1.2.4", - "dialog-polyfill": "^0.4.3", - "element.scrollintoviewifneeded-polyfill": "^1.0.1", - "material-design-icons": "2.2.3", - "material-design-lite": "1.2.1", - - "raphael": "^2.2.6", - - "ng2-translate": "2.5.0", - "alfresco-js-api": "^0.5.0", - "ng2-alfresco-core": "0.5.0", - "ng2-activiti-diagrams": "^0.5.0" + "zone.js": "^0.6.23" }, "devDependencies": { - "@types/node": "^6.0.42", - "@types/core-js": "^0.9.32", "@types/jasmine": "^2.2.33", + "@types/node": "^6.0.42", "concurrently": "^2.2.0", "rimraf": "2.5.2", "tslint": "^3.8.1", diff --git a/ng2-components/ng2-activiti-diagrams/demo/src/main.ts b/ng2-components/ng2-activiti-diagrams/demo/src/main.ts index e48a224366..cf673fabdb 100644 --- a/ng2-components/ng2-activiti-diagrams/demo/src/main.ts +++ b/ng2-components/ng2-activiti-diagrams/demo/src/main.ts @@ -19,7 +19,7 @@ import { NgModule, Component } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; -import { CoreModule, AlfrescoSettingsService, AlfrescoAuthenticationService } from 'ng2-alfresco-core'; +import { CoreModule, AlfrescoSettingsService, AlfrescoAuthenticationService, StorageService } from 'ng2-alfresco-core'; import { DiagramsModule } from 'ng2-activiti-diagrams'; @Component({ @@ -50,7 +50,9 @@ export class DiagramDemoComponent { ticket: string; - constructor(private authService: AlfrescoAuthenticationService, private settingsService: AlfrescoSettingsService) { + constructor(private authService: AlfrescoAuthenticationService, + private settingsService: AlfrescoSettingsService, + private storage: StorageService) { settingsService.bpmHost = this.host; settingsService.setProviders('BPM'); @@ -60,7 +62,7 @@ export class DiagramDemoComponent { } public updateTicket(): void { - localStorage.setItem('ticket-BPM', this.ticket); + this.storage.setItem('ticket-BPM', this.ticket); } public updateHost(): void { diff --git a/ng2-components/ng2-activiti-diagrams/demo/systemjs.config.js b/ng2-components/ng2-activiti-diagrams/demo/systemjs.config.js index 07cbc7aeee..76deb7497b 100644 --- a/ng2-components/ng2-activiti-diagrams/demo/systemjs.config.js +++ b/ng2-components/ng2-activiti-diagrams/demo/systemjs.config.js @@ -11,7 +11,7 @@ // map tells the System loader where to look for things map: { // our app is within the app folder - app: 'dist', + app: 'src', // angular bundles '@angular/core': 'npm:@angular/core/bundles/core.umd.js', '@angular/common': 'npm:@angular/common/bundles/common.umd.js', @@ -23,11 +23,12 @@ '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js', // other libraries 'rxjs': 'npm:rxjs', + 'moment': 'npm:moment/min/moment.min.js', 'raphael': 'npm:raphael', 'ng2-translate': 'npm:ng2-translate', 'alfresco-js-api': 'npm:alfresco-js-api/dist', - 'ng2-alfresco-core': 'npm:ng2-alfresco-core/dist', - 'ng2-activiti-diagrams': 'npm:ng2-activiti-diagrams/dist' + 'ng2-alfresco-core': 'npm:ng2-alfresco-core', + 'ng2-activiti-diagrams': 'npm:ng2-activiti-diagrams' }, // packages tells the System loader how to load when no filename and/or no extension packages: { @@ -38,6 +39,7 @@ rxjs: { defaultExtension: 'js' }, + 'moment': { defaultExtension: 'js' }, 'ng2-translate': { defaultExtension: 'js' }, 'alfresco-js-api': { main: './alfresco-js-api.js', defaultExtension: 'js'}, 'ng2-alfresco-core': { main: './index.js', defaultExtension: 'js'}, diff --git a/ng2-components/ng2-activiti-diagrams/demo/tsconfig.json b/ng2-components/ng2-activiti-diagrams/demo/tsconfig.json index 7be35bfec8..524fcfda8e 100644 --- a/ng2-components/ng2-activiti-diagrams/demo/tsconfig.json +++ b/ng2-components/ng2-activiti-diagrams/demo/tsconfig.json @@ -3,11 +3,10 @@ "target": "es5", "module": "commonjs", "moduleResolution": "node", + "sourceMap": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, - "sourceMap": true, - "removeComments": true, - "declaration": true, + "skipLibCheck": true, "noLib": false, "allowUnreachableCode": false, "allowUnusedLabels": false, @@ -15,12 +14,19 @@ "noImplicitReturns": false, "noImplicitUseStrict": false, "noFallthroughCasesInSwitch": true, - "outDir": "dist", - "types": ["core-js", "jasmine", "node"] + "removeComments": true, + "declaration": true, + "lib": [ + "es2015", + "dom" + ], + "suppressImplicitAnyIndexErrors": true }, "exclude": [ - "demo", - "node_modules", - "dist" - ] + "node_modules" + ], + "angularCompilerOptions": { + "strictMetadataEmit": false, + "skipTemplateCodegen": true + } } diff --git a/ng2-components/ng2-activiti-diagrams/gulpfile.ts b/ng2-components/ng2-activiti-diagrams/gulpfile.ts new file mode 100755 index 0000000000..b6a49ebe06 --- /dev/null +++ b/ng2-components/ng2-activiti-diagrams/gulpfile.ts @@ -0,0 +1,311 @@ +import * as gulp from 'gulp'; +import * as util from 'gulp-util'; +import * as runSequence from 'run-sequence'; +import * as gulpLoadPlugins from 'gulp-load-plugins'; +import * as merge from 'merge-stream'; +import * as rimraf from 'rimraf'; +import { join } from 'path'; +import * as Builder from 'systemjs-builder'; +var autoprefixer = require('autoprefixer'); +import * as cssnano from 'cssnano'; +import * as filter from 'gulp-filter'; +import * as sourcemaps from 'gulp-sourcemaps'; + +var APP_SRC = `.`; +var CSS_PROD_BUNDLE = 'main.css'; +var JS_PROD_SHIMS_BUNDLE = 'shims.js'; +var NG_FACTORY_FILE = 'main-prod'; + +const BUILD_TYPES = { + DEVELOPMENT: 'dev', + PRODUCTION: 'prod' +}; + +function normalizeDependencies(deps) { + deps + .filter((d) => !/\*/.test(d.src)) // Skip globs + .forEach((d) => d.src = require.resolve(d.src)); + return deps; +} + +function filterDependency(type: string, d): boolean { + const t = d.buildType || d.env; + d.buildType = t; + if (!t) { + d.buildType = Object.keys(BUILD_TYPES).map(k => BUILD_TYPES[k]); + } + if (!(d.buildType instanceof Array)) { + (d).env = [d.buildType]; + } + return d.buildType.indexOf(type) >= 0; +} + +function getInjectableDependency() { + var APP_ASSETS = [ + {src: `src/css/main.css`, inject: true, vendor: false}, + ]; + + var NPM_DEPENDENCIES = [ + {src: 'zone.js/dist/zone.js', inject: 'libs'}, + {src: 'core-js/client/shim.min.js', inject: 'shims'}, + {src: 'intl/dist/Intl.min.js', inject: 'shims'}, + {src: 'systemjs/dist/system.src.js', inject: 'shims', buildType:'dev'} + ]; + + return normalizeDependencies(NPM_DEPENDENCIES.filter(filterDependency.bind(null, 'dev'))) + .concat(APP_ASSETS.filter(filterDependency.bind(null, 'dev'))); +} + +const plugins = gulpLoadPlugins(); + +let tsProjects: any = {}; + +function makeTsProject(options: Object = {}) { + let optionsHash = JSON.stringify(options); + if (!tsProjects[optionsHash]) { + let config = Object.assign({ + typescript: require('typescript') + }, options); + tsProjects[optionsHash] = + plugins.typescript.createProject('tsconfig.json', config); + } + return tsProjects[optionsHash]; +} + +gulp.task('build.html_css', () => { + const gulpConcatCssConfig = { + targetFile: CSS_PROD_BUNDLE, + options: { + rebaseUrls: false + } + }; + + const processors = [ + autoprefixer({ + browsers: [ + 'ie >= 10', + 'ie_mob >= 10', + 'ff >= 30', + 'chrome >= 34', + 'safari >= 7', + 'opera >= 23', + 'ios >= 7', + 'android >= 4.4', + 'bb >= 10' + ] + }) + ]; + + const reportPostCssError = (e: any) => util.log(util.colors.red(e.message)); + + processors.push( + cssnano({ + discardComments: {removeAll: true}, + discardUnused: false, // unsafe, see http://goo.gl/RtrzwF + zindex: false, // unsafe, see http://goo.gl/vZ4gbQ + reduceIdents: false // unsafe, see http://goo.gl/tNOPv0 + }) + ); + + /** + * Processes the CSS files within `src/client` excluding those in `src/client/assets` using `postcss` with the + * configured processors + * Execute the appropriate component-stylesheet processing method based on user stylesheet preference. + */ + function processComponentStylesheets() { + return gulp.src(join('src/**', '*.css')) + .pipe(plugins.cached('process-component-css')) + .pipe(plugins.postcss(processors)) + .on('error', reportPostCssError); + } + + + /** + * Get a stream of external css files for subsequent processing. + */ + function getExternalCssStream() { + return gulp.src(getExternalCss()) + .pipe(plugins.cached('process-external-css')); + } + + /** + * Get an array of filenames referring to all external css stylesheets. + */ + function getExternalCss() { + return getInjectableDependency().filter(dep => /\.css$/.test(dep.src)).map(dep => dep.src); + } + + /** + * Processes the external CSS files using `postcss` with the configured processors. + */ + function processExternalCss() { + return getExternalCssStream() + .pipe(plugins.postcss(processors)) + .pipe(plugins.concatCss(gulpConcatCssConfig.targetFile, gulpConcatCssConfig.options)) + .on('error', reportPostCssError); + } + + return merge(processComponentStylesheets(), processExternalCss()); + +}); + +gulp.task('build.bundles.app', (done) => { + var BUNDLER_OPTIONS = { + format: 'umd', + minify: false, + mangle: false, + sourceMaps: true + }; + var CONFIG_TYPESCRIPT = { + baseURL: '.', + transpiler: 'typescript', + typescriptOptions: { + module: 'cjs' + }, + map: { + typescript: 'node_modules/typescript/lib/typescript.js', + '@angular': 'node_modules/@angular', + rxjs: 'node_modules/rxjs', + 'ng2-translate': 'node_modules/ng2-translate', + 'alfresco-js-api': 'node_modules/alfresco-js-api/dist/alfresco-js-api', + 'ng2-alfresco-core': 'node_modules/ng2-alfresco-core/', + 'ng2-activiti-diagrams': 'node_modules/ng2-activiti-diagrams/', + 'ng2-activiti-analytics': 'node_modules/ng2-activiti-analytics/', + 'ng2-alfresco-datatable': 'node_modules/ng2-alfresco-datatable/', + 'ng2-alfresco-documentlist': 'node_modules/ng2-alfresco-documentlist/', + 'ng2-activiti-form': 'node_modules/ng2-activiti-form/', + 'ng2-alfresco-login': 'node_modules/ng2-alfresco-login/', + 'ng2-activiti-processlist': 'node_modules/ng2-activiti-processlist/', + 'ng2-alfresco-search': 'node_modules/ng2-alfresco-search/', + 'ng2-activiti-tasklist': 'node_modules/ng2-activiti-tasklist/', + 'ng2-alfresco-tag': 'node_modules/ng2-alfresco-tag/', + 'ng2-alfresco-upload': 'node_modules/ng2-alfresco-upload/', + 'ng2-alfresco-userinfo': 'node_modules/ng2-alfresco-userinfo/', + 'ng2-alfresco-viewer': 'node_modules/ng2-alfresco-viewer/', + 'ng2-alfresco-webscript': 'node_modules/ng2-alfresco-webscript/', + 'ng2-charts' : 'node_modules/ng2-charts', + 'raphael':'node_modules/raphael/raphael' + + }, + paths: { + '*': '*.js' + }, + meta: { + 'node_modules/@angular/*': {build: false}, + 'node_modules/rxjs/*': {build: false}, + 'node_modules/ng2-translate/*': {build: false}, + 'node_modules/ng2-alfresco-core/*': {build: false}, + 'node_modules/ng2-activiti-diagrams/*': {build: false}, + 'node_modules/ng2-activiti-analytics/*': {build: false}, + 'node_modules/ng2-alfresco-datatable/*': {build: false}, + 'node_modules/ng2-alfresco-documentlist/*': {build: false}, + 'node_modules/ng2-activiti-form/*': {build: false}, + 'node_modules/ng2-alfresco-login/*': {build: false}, + 'node_modules/ng2-activiti-processlist/*': {build: false}, + 'node_modules/ng2-alfresco-search/*': {build: false}, + 'node_modules/ng2-activiti-tasklist/*': {build: false}, + 'node_modules/ng2-alfresco-tag/*': {build: false}, + 'node_modules/ng2-alfresco-upload/*': {build: false}, + 'node_modules/ng2-alfresco-userinfo/*': {build: false}, + 'node_modules/ng2-alfresco-viewer/*': {build: false}, + 'node_modules/ng2-alfresco-webscript/*': {build: false} + } + }; + + var pkg = require('./package.json'); + var namePkg = pkg.name; + + var builder = new Builder(CONFIG_TYPESCRIPT); + builder + .buildStatic(APP_SRC + "/index", 'bundles/' + namePkg + '.js', BUNDLER_OPTIONS) + .then(function () { + return done(); + }) + .catch(function (err) { + return done(err); + }); +}); + +gulp.task('build.assets.prod', () => { + return gulp.src([ + join('src/**', '*.ts'), + 'index.ts', + join('src/**', '*.css'), + join('src/**', '*.html'), + '!'+join('*/**', '*.d.ts'), + '!'+join('*/**', '*.spec.ts'), + '!gulpfile.ts']) + +}); + +gulp.task('build.bundles', () => { + merge(bundleShims()); + + /** + * Returns the shim files to be injected. + */ + function getShims() { + let libs = getInjectableDependency() + .filter(d => /\.js$/.test(d.src)); + + return libs.filter(l => l.inject === 'shims') + .concat(libs.filter(l => l.inject === 'libs')) + .concat(libs.filter(l => l.inject === true)) + .map(l => l.src); + } + + /** + * Bundles the shim files. + */ + function bundleShims() { + return gulp.src(getShims()) + .pipe(plugins.concat(JS_PROD_SHIMS_BUNDLE)) + // Strip the first (global) 'use strict' added by reflect-metadata, but don't strip any others to avoid unintended scope leaks. + .pipe(plugins.replace(/('|")use strict\1;var Reflect;/, 'var Reflect;')) + .pipe(gulp.dest('bundles')); + } + +}); + +gulp.task('build.js.prod', () => { + const INLINE_OPTIONS = { + base: APP_SRC, + target: 'es5', + useRelativePaths: true, + removeLineBreaks: true + }; + + let tsProject = makeTsProject(); + let src = [ + join('src/**/*.ts'), + join('!src/**/*.d.ts'), + join('!src/**/*.spec.ts'), + `!src/**/${NG_FACTORY_FILE}.ts` + ]; + + let result = gulp.src(src) + .pipe(plugins.plumber()) + .pipe(plugins.inlineNg2Template(INLINE_OPTIONS)) + .pipe(sourcemaps.init()) + .pipe(tsProject()) + .once('error', function (e: any) { + this.once('finish', () => process.exit(1)); + }); + + return result.js + .pipe(plugins.template()) + .pipe(sourcemaps.write()) + .pipe(gulp.dest('src')) + .on('error', (e: any) => { + console.log(e); + }); +}); + +gulp.task('build.prod', (done: any) => + runSequence( + 'build.assets.prod', + 'build.html_css', + 'build.js.prod', + 'build.bundles', + 'build.bundles.app', + done)); diff --git a/ng2-components/ng2-activiti-diagrams/karma-test-shim.js b/ng2-components/ng2-activiti-diagrams/karma-test-shim.js index 47e3d71f55..d08f1ebd76 100644 --- a/ng2-components/ng2-activiti-diagrams/karma-test-shim.js +++ b/ng2-components/ng2-activiti-diagrams/karma-test-shim.js @@ -5,7 +5,7 @@ jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; __karma__.loaded = function() {}; -var builtPath = '/base/dist/'; +var builtPath = '/base/src/'; function isJsFile(path) { return path.slice(-3) == '.js'; @@ -29,7 +29,7 @@ var paths = { }; var map = { - 'app': 'base/dist', + 'app': 'base/src', // angular bundles '@angular/core': 'npm:@angular/core/bundles/core.umd.js', '@angular/common': 'npm:@angular/common/bundles/common.umd.js', @@ -52,17 +52,20 @@ var map = { // other libraries 'rxjs': 'npm:rxjs', 'ng2-translate': 'npm:ng2-translate', + 'ng2-charts' : 'npm:ng2-charts', + + 'raphael':'npm:raphael/raphael.js', 'alfresco-js-api': 'npm:alfresco-js-api/dist', - 'ng2-activiti-diagrams': 'npm:ng2-activiti-diagrams/dist', - 'ng2-alfresco-core': 'npm:ng2-alfresco-core/dist' + 'ng2-alfresco-core': 'npm:ng2-alfresco-core' }; var packages = { 'app': { main: 'main.js', defaultExtension: 'js' }, 'rxjs': { defaultExtension: 'js' }, 'ng2-translate': { defaultExtension: 'js' }, + 'ng2-charts': { defaultExtension: 'js' }, + 'alfresco-js-api': { main: './alfresco-js-api.js', defaultExtension: 'js'}, - 'ng2-activiti-diagrams': { main: './index.js', defaultExtension: 'js'}, 'ng2-alfresco-core': { main: './index.js', defaultExtension: 'js'} }; diff --git a/ng2-components/ng2-activiti-diagrams/karma.conf.js b/ng2-components/ng2-activiti-diagrams/karma.conf.js index 2806957c37..4fadbd3a18 100644 --- a/ng2-components/ng2-activiti-diagrams/karma.conf.js +++ b/ng2-components/ng2-activiti-diagrams/karma.conf.js @@ -24,32 +24,36 @@ module.exports = function (config) { 'node_modules/zone.js/dist/fake-async-test.js', // RxJs - {pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false}, - {pattern: 'node_modules/rxjs/**/*.js.map', included: false, watched: false}, + { pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false }, + { pattern: 'node_modules/rxjs/**/*.js.map', included: false, watched: false }, // Paths loaded via module imports: // Angular itself {pattern: 'node_modules/@angular/**/*.js', included: false, watched: false}, {pattern: 'node_modules/@angular/**/*.js.map', included: false, watched: false}, + 'node_modules/chart.js/dist/Chart.js', 'node_modules/alfresco-js-api/dist/alfresco-js-api.js', - 'node_modules/raphael/raphael.min.js', - 'assets/Polyline.js', + 'node_modules/raphael/raphael.js', + {pattern: 'node_modules/ng2-translate/**/*.js', included: false, watched: false}, + {pattern: 'node_modules/ng2-charts/**/*.js', included: false, served: true, watched: false}, 'karma-test-shim.js', // paths loaded via module imports - {pattern: 'dist/**/*.js', included: false, watched: true}, - {pattern: 'dist/**/*.html', included: true, served: true, watched: true}, - {pattern: 'dist/**/*.css', included: true, served: true, watched: true}, + {pattern: 'src/**/*.js', included: false, watched: true}, + {pattern: 'src/**/*.html', included: true, served: true, watched: true}, + {pattern: 'src/**/*.css', included: true, served: true, watched: true}, // ng2-components - { pattern: 'node_modules/ng2-alfresco-core/dist/**/*.*', included: false, served: true, watched: false }, + { pattern: 'node_modules/ng2-alfresco-core/src/**/*.*', included: false, served: true, watched: false }, + { pattern: 'node_modules/ng2-alfresco-core/index.js', included: false, served: true, watched: false }, // paths to support debugging with source maps in dev tools {pattern: 'src/**/*.ts', included: false, watched: false}, - {pattern: 'dist/**/*.js.map', included: false, watched: false} + {pattern: 'src/**/*.json', included: false, watched: false}, + {pattern: 'src/**/*.js.map', included: false, watched: false} ], exclude: [ @@ -97,7 +101,7 @@ module.exports = function (config) { // Source files that you wanna generate coverage for. // Do not include tests or libraries (these files will be instrumented by Istanbul) preprocessors: { - 'dist/**/!(*spec|index|*mock|*model).js': 'coverage' + 'src/**/!(*spec|index|*mock|*model).js': 'coverage' }, coverageReporter: { diff --git a/ng2-components/ng2-activiti-diagrams/package.json b/ng2-components/ng2-activiti-diagrams/package.json index 58b1d1c1e1..613f2d6238 100644 --- a/ng2-components/ng2-activiti-diagrams/package.json +++ b/ng2-components/ng2-activiti-diagrams/package.json @@ -1,28 +1,30 @@ { "name": "ng2-activiti-diagrams", "description": "Activiti Angular2 Diagrams Component", - "version": "0.5.0", + "version": "1.0.0", "author": "Alfresco Software, Ltd.", - "main": "./dist/index.js", - "typings": "./dist/index.d.ts", "scripts": { - "clean": "npm install rimraf && rimraf dist node_modules typings", - "build": "npm run tslint && rimraf dist && tsc && npm run copy-dist && license-check", - "build:w": "npm run tslint && rimraf dist && npm run watch-task", - "watch-task": "concurrently \"npm run tsc:w\" \"npm run copy-dist:w\" \"license-check\"", - "tslint": "tslint -c tslint.json *.ts && tslint -c tslint.json 'src/{,**/}**.ts'", - "copy-dist": "cpx \"./src/**/*.{html,css,json,png,jpg,gif,svg}\" ./dist/src", - "copy-dist:w": "cpx \"./src/**/*.{html,css,json,png,jpg,gif,svg}\" ./dist/src -w", + "clean": "npm install rimraf && npm run clean-build && rimraf dist node_modules typings", + "clean-build": "rimraf index.js index.js.map index.d.ts'src/{,**/}**.js' 'src/{,**/}**.js.map' 'src/{,**/}**.d.ts' bundles", + "build": "npm run clean-build && npm run tslint && rimraf dist && tsc && license-check && npm run build.umd", + "build:w": "npm run clean-build && npm run tslint && rimraf dist && tsc:w && license-check npm run build.umd", + "tslint": "tslint -c tslint.json 'src/{,**/}**.ts' 'index.ts' -e '{,**/}**.d.ts' -e './gulpfile.ts'", "tsc": "tsc", "tsc:w": "tsc -w", "pretest": "npm run build", "test": "karma start karma.conf.js --reporters mocha,coverage --single-run", - "test-browser": "concurrently \"karma start karma.conf.js --reporters kjhtml\" \"npm run watch-task\"", + "test-browser": "npm run build && concurrently \"karma start karma.conf.js --reporters kjhtml\" \"npm run watch-task\"", "posttest": "remap-istanbul -i coverage/report/coverage-final.json -o coverage/report -t html && remap-istanbul -i coverage/report/coverage-final.json -o coverage/report/coverage-final.json", "coverage": "npm run test && wsrv -o -p 9875 ./coverage/report", "prepublish": "npm run build", - "travis": "npm link ng2-alfresco-core" + "travis": "npm link ng2-alfresco-core", + "gulp": "gulp", + "build.umd": "gulp build.prod --color --env-config prod --build-type prod", + "reinstall": "npm cache clean && npm install" }, + "main": "./index.js", + "module": "./index.js", + "typings": "./index.d.ts", "contributors": [ { "name": "Maurizio Vitale", @@ -37,6 +39,7 @@ "url": "https://github.com/Alfresco/alfresco-ng2-components/issues" }, "dependencies": { + "@angular/router": "3.0.0", "@angular/common": "2.0.0", "@angular/compiler": "2.0.0", "@angular/core": "2.0.0", @@ -49,31 +52,50 @@ "rxjs": "5.0.0-beta.12", "systemjs": "0.19.27", "zone.js": "^0.6.23", - "raphael": "^2.2.6", - + "chart.js": "^2.1.4", + "ng2-charts": "1.1.0", "ng2-translate": "2.5.0", - "alfresco-js-api": "^0.5.0", - "ng2-alfresco-core": "0.5.0" + "alfresco-js-api": "^1.0.0", + "ng2-alfresco-core": "1.0.0" }, "devDependencies": { - "@types/node": "^6.0.42", - "@types/core-js": "^0.9.32", "@types/jasmine": "^2.2.33", + "@types/node": "^6.0.42", "concurrently": "^2.2.0", "cpx": "1.3.1", + "cssnano": "^3.8.1", + "gulp": "^3.9.1", + "gulp-autoprefixer": "^3.1.1", + "gulp-cached": "^1.1.1", + "gulp-concat": "^2.6.1", + "gulp-concat-css": "^2.3.0", + "gulp-filter": "^4.0.0", + "gulp-inline-ng2-template": "^4.0.0", + "gulp-load-plugins": "^1.4.0", + "gulp-plumber": "^1.1.0", + "gulp-postcss": "^6.2.0", + "gulp-replace": "^0.5.4", + "gulp-sourcemaps": "^1.9.1", + "gulp-template": "^4.0.0", + "gulp-typescript": "^3.1.3", + "gulp-uglify": "^2.0.0", + "intl": "^1.2.5", "jasmine-core": "2.4.1", "karma": "0.13.22", "karma-chrome-launcher": "1.0.1", "karma-coverage": "1.0.0", "karma-jasmine": "1.0.2", "karma-jasmine-ajax": "^0.1.13", - "karma-mocha-reporter": "2.0.3", "karma-jasmine-html-reporter": "0.2.0", + "karma-mocha-reporter": "2.0.3", "license-check": "1.1.5", "remap-istanbul": "0.6.3", "rimraf": "2.5.2", + "run-sequence": "^1.2.2", + "systemjs-builder": "^0.15.34", "traceur": "0.0.91", + "ts-node": "^1.7.0", "tslint": "3.15.1", "typescript": "^2.0.3", "wsrv": "^0.1.5" @@ -85,7 +107,7 @@ ], "license-check-config": { "src": [ - "./dist/**/*.js" + "./src/**/*.js" ], "path": "assets/license_header.txt", "blocking": true, diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/cell.editor.ts b/ng2-components/ng2-activiti-diagrams/src/assets/translation.service.mock.ts similarity index 58% rename from ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/cell.editor.ts rename to ng2-components/ng2-activiti-diagrams/src/assets/translation.service.mock.ts index 7eb30d93f6..3ddf9a9050 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/cell.editor.ts +++ b/ng2-components/ng2-activiti-diagrams/src/assets/translation.service.mock.ts @@ -15,22 +15,23 @@ * limitations under the License. */ -import { Input } from '@angular/core'; -import { DynamicTableModel, DynamicTableRow, DynamicTableColumn } from './../dynamic-table.widget.model'; +import { Observable } from 'rxjs/Rx'; +import { EventEmitter } from '@angular/core'; -export abstract class CellEditorComponent { +export interface LangChangeEvent { + lang: string; + translations: any; +} - @Input() - table: DynamicTableModel; +export class TranslationMock { - @Input() - row: DynamicTableRow; + public onLangChange: EventEmitter = new EventEmitter(); - @Input() - column: DynamicTableColumn; + addTranslationFolder() { - handleError(error: any) { - console.error(error); } + public get(key: string|Array, interpolateParams?: Object): Observable { + return Observable.of(key); + } } diff --git a/ng2-components/ng2-activiti-diagrams/src/components/activities/diagram-task.component.html b/ng2-components/ng2-activiti-diagrams/src/components/activities/diagram-task.component.html index fe7f52ec74..14533b7813 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/activities/diagram-task.component.html +++ b/ng2-components/ng2-activiti-diagrams/src/components/activities/diagram-task.component.html @@ -1,4 +1,5 @@ - - \ No newline at end of file + + diff --git a/ng2-components/ng2-activiti-diagrams/src/components/boundary-events/diagram-boundary-event.component.html b/ng2-components/ng2-activiti-diagrams/src/components/boundary-events/diagram-boundary-event.component.html index 9607de4538..648231ffcd 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/boundary-events/diagram-boundary-event.component.html +++ b/ng2-components/ng2-activiti-diagrams/src/components/boundary-events/diagram-boundary-event.component.html @@ -1,5 +1,6 @@ - - \ No newline at end of file + + diff --git a/ng2-components/ng2-activiti-diagrams/src/components/boundary-events/diagram-throw-event.component.html b/ng2-components/ng2-activiti-diagrams/src/components/boundary-events/diagram-throw-event.component.html index b4dddf5c31..c3d32453f3 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/boundary-events/diagram-throw-event.component.html +++ b/ng2-components/ng2-activiti-diagrams/src/components/boundary-events/diagram-throw-event.component.html @@ -1,6 +1,7 @@ - \ No newline at end of file + [fillColor]="signalFillColor"> + diff --git a/ng2-components/ng2-activiti-diagrams/src/components/diagram-sequence-flow.component.html b/ng2-components/ng2-activiti-diagrams/src/components/diagram-sequence-flow.component.html index 985c72c443..e2bc21f852 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/diagram-sequence-flow.component.html +++ b/ng2-components/ng2-activiti-diagrams/src/components/diagram-sequence-flow.component.html @@ -1 +1,2 @@ - \ No newline at end of file + + diff --git a/ng2-components/ng2-activiti-diagrams/src/components/diagram-sequence-flow.component.ts b/ng2-components/ng2-activiti-diagrams/src/components/diagram-sequence-flow.component.ts index aa89eecbf6..d90287cd7f 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/diagram-sequence-flow.component.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/diagram-sequence-flow.component.ts @@ -32,6 +32,6 @@ export class DiagramSequenceFlowComponent { constructor(public elementRef: ElementRef) {} ngOnInit() { - console.log(this.elementRef); + } } diff --git a/ng2-components/ng2-activiti-diagrams/src/components/diagram.component.css b/ng2-components/ng2-activiti-diagrams/src/components/diagram.component.css new file mode 100644 index 0000000000..34f840208d --- /dev/null +++ b/ng2-components/ng2-activiti-diagrams/src/components/diagram.component.css @@ -0,0 +1,3 @@ +.diagram { + border: 1px solid lightgray; overflow:auto +} \ No newline at end of file diff --git a/ng2-components/ng2-activiti-diagrams/src/components/diagram.component.html b/ng2-components/ng2-activiti-diagrams/src/components/diagram.component.html index 9cf62cc2d4..d9c35653a2 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/diagram.component.html +++ b/ng2-components/ng2-activiti-diagrams/src/components/diagram.component.html @@ -1,4 +1,4 @@ -
+
diff --git a/ng2-components/ng2-activiti-diagrams/src/components/diagram.component.spec.ts b/ng2-components/ng2-activiti-diagrams/src/components/diagram.component.spec.ts index 67a9b0ebcc..bacd8c1cc1 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/diagram.component.spec.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/diagram.component.spec.ts @@ -17,13 +17,15 @@ import { ComponentFixture, TestBed, async } from '@angular/core/testing'; import { - CoreModule + CoreModule, + AlfrescoTranslationService } from 'ng2-alfresco-core'; import { DIAGRAM_DIRECTIVES, DIAGRAM_PROVIDERS } from './index'; import { RAPHAEL_DIRECTIVES, RAPHAEL_PROVIDERS } from './raphael/index'; import { DiagramComponent } from './index'; import { DebugElement } from '@angular/core'; +import { TranslationMock } from '../assets/translation.service.mock'; import * as diagramsEventsMock from '../assets/diagramEvents.mock'; import * as diagramsActivitiesMock from '../assets/diagramActivities.mock'; import * as diagramsGatewaysMock from '../assets/diagramGateways.mock'; @@ -56,7 +58,8 @@ describe('Test ng2-activiti-diagrams ', () => { ], providers: [ ...DIAGRAM_PROVIDERS, - ...RAPHAEL_PROVIDERS + ...RAPHAEL_PROVIDERS, + {provide: AlfrescoTranslationService, useClass: TranslationMock} ] }).compileComponents(); })); @@ -74,6 +77,7 @@ describe('Test ng2-activiti-diagrams ', () => { }); describe('Diagrams component Events: ', () => { + beforeEach(() => { jasmine.Ajax.install(); component.processDefinitionId = 'fakeprocess:24:38399'; @@ -91,6 +95,9 @@ describe('Test ng2-activiti-diagrams ', () => { expect(res).not.toBeNull(); let event: any = element.querySelector('diagram-start-event > diagram-event > raphael-circle'); expect(event).not.toBeNull(); + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].id); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -113,6 +120,9 @@ describe('Test ng2-activiti-diagrams ', () => { let iconEvent: any = element.querySelector('diagram-start-event > diagram-event >' + ' diagram-container-icon-event > div > div > diagram-icon-timer > raphael-icon-timer'); expect(iconEvent).not.toBeNull(); + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].id); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -136,6 +146,9 @@ describe('Test ng2-activiti-diagrams ', () => { let iconEvent: any = element.querySelector('diagram-start-event > diagram-event >' + ' diagram-container-icon-event > div > div > diagram-icon-signal > raphael-icon-signal'); expect(iconEvent).not.toBeNull(); + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].id); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -158,6 +171,9 @@ describe('Test ng2-activiti-diagrams ', () => { let iconEvent: any = element.querySelector('diagram-start-event > diagram-event >' + ' diagram-container-icon-event > div > div > diagram-icon-message > raphael-icon-message'); expect(iconEvent).not.toBeNull(); + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].id); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -180,6 +196,9 @@ describe('Test ng2-activiti-diagrams ', () => { let iconEvent: any = element.querySelector('diagram-start-event > diagram-event >' + ' diagram-container-icon-event > div > div > diagram-icon-error > raphael-icon-error'); expect(iconEvent).not.toBeNull(); + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].id); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -198,6 +217,9 @@ describe('Test ng2-activiti-diagrams ', () => { expect(res).toBeDefined(); let event: any = element.querySelector('diagram-end-event > diagram-event > raphael-circle'); expect(event).not.toBeNull(); + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].id); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -220,6 +242,9 @@ describe('Test ng2-activiti-diagrams ', () => { let iconEvent: any = element.querySelector('diagram-end-event > diagram-event >' + ' diagram-container-icon-event > div > div > diagram-icon-error > raphael-icon-error'); expect(iconEvent).not.toBeNull(); + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].id); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -251,12 +276,16 @@ describe('Test ng2-activiti-diagrams ', () => { let task: any = element.querySelector('diagram-user-task > diagram-task > raphael-rect'); expect(task).not.toBeNull(); - let taskText: any = element.querySelector('diagram-user-task > diagram-task > raphael-text'); + let taskText: any = element.querySelector('diagram-user-task > diagram-task > raphael-multiline-text'); expect(taskText).not.toBeNull(); expect(taskText.attributes[1].value).toEqual('Fake User task'); let iconTask: any = element.querySelector('diagram-user-task > diagram-icon-user-task > raphael-icon-user'); expect(iconTask).not.toBeNull(); + + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].name); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -276,12 +305,16 @@ describe('Test ng2-activiti-diagrams ', () => { let task: any = element.querySelector('diagram-manual-task > diagram-task > raphael-rect'); expect(task).not.toBeNull(); - let taskText: any = element.querySelector('diagram-manual-task > diagram-task > raphael-text'); + let taskText: any = element.querySelector('diagram-manual-task > diagram-task > raphael-multiline-text'); expect(taskText).not.toBeNull(); expect(taskText.attributes[1].value).toEqual('Fake Manual task'); let iconTask: any = element.querySelector('diagram-manual-task > diagram-icon-manual-task > raphael-icon-manual'); expect(iconTask).not.toBeNull(); + + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].name); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -301,12 +334,16 @@ describe('Test ng2-activiti-diagrams ', () => { let task: any = element.querySelector('diagram-service-task > diagram-task > raphael-rect'); expect(task).not.toBeNull(); - let taskText: any = element.querySelector('diagram-service-task > diagram-task > raphael-text'); + let taskText: any = element.querySelector('diagram-service-task > diagram-task > raphael-multiline-text'); expect(taskText).not.toBeNull(); expect(taskText.attributes[1].value).toEqual('Fake Service task'); let iconTask: any = element.querySelector('diagram-service-task > diagram-icon-service-task > raphael-icon-service'); expect(iconTask).not.toBeNull(); + + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].name); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -342,12 +379,16 @@ describe('Test ng2-activiti-diagrams ', () => { let task: any = element.querySelector('diagram-camel-task > diagram-task > raphael-rect'); expect(task).not.toBeNull(); - let taskText: any = element.querySelector('diagram-camel-task > diagram-task > raphael-text'); + let taskText: any = element.querySelector('diagram-camel-task > diagram-task > raphael-multiline-text'); expect(taskText).not.toBeNull(); expect(taskText.attributes[1].value).toEqual('Fake Camel task'); let iconTask: any = element.querySelector('diagram-camel-task > diagram-icon-camel-task > raphael-icon-camel'); expect(iconTask).not.toBeNull(); + + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].name); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -367,7 +408,7 @@ describe('Test ng2-activiti-diagrams ', () => { let task: any = element.querySelector('diagram-mule-task > diagram-task > raphael-rect'); expect(task).not.toBeNull(); - let taskText: any = element.querySelector('diagram-mule-task > diagram-task > raphael-text'); + let taskText: any = element.querySelector('diagram-mule-task > diagram-task > raphael-multiline-text'); expect(taskText).not.toBeNull(); expect(taskText.attributes[1].value).toEqual('Fake Mule task'); @@ -392,13 +433,17 @@ describe('Test ng2-activiti-diagrams ', () => { let task: any = element.querySelector('diagram-alfresco-publish-task > diagram-task > raphael-rect'); expect(task).not.toBeNull(); - let taskText: any = element.querySelector('diagram-alfresco-publish-task > diagram-task > raphael-text'); + let taskText: any = element.querySelector('diagram-alfresco-publish-task > diagram-task > raphael-multiline-text'); expect(taskText).not.toBeNull(); expect(taskText.attributes[1].value).toEqual('Fake Alfresco Publish task'); let iconTask: any = element.querySelector('diagram-alfresco-publish-task > diagram-icon-alfresco-publish-task >' + ' raphael-icon-alfresco-publish'); expect(iconTask).not.toBeNull(); + + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].name); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -418,13 +463,17 @@ describe('Test ng2-activiti-diagrams ', () => { let task: any = element.querySelector('diagram-google-drive-publish-task > diagram-task > raphael-rect'); expect(task).not.toBeNull(); - let taskText: any = element.querySelector('diagram-google-drive-publish-task > diagram-task > raphael-text'); + let taskText: any = element.querySelector('diagram-google-drive-publish-task > diagram-task > raphael-multiline-text'); expect(taskText).not.toBeNull(); expect(taskText.attributes[1].value).toEqual('Fake Google Drive Publish task'); let iconTask: any = element.querySelector('diagram-google-drive-publish-task >' + ' diagram-icon-google-drive-publish-task > raphael-icon-google-drive-publish'); expect(iconTask).not.toBeNull(); + + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].name); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -444,13 +493,17 @@ describe('Test ng2-activiti-diagrams ', () => { let task: any = element.querySelector('diagram-rest-call-task > diagram-task > raphael-rect'); expect(task).not.toBeNull(); - let taskText: any = element.querySelector('diagram-rest-call-task > diagram-task > raphael-text'); + let taskText: any = element.querySelector('diagram-rest-call-task > diagram-task > raphael-multiline-text'); expect(taskText).not.toBeNull(); expect(taskText.attributes[1].value).toEqual('Fake Rest Call task'); let iconTask: any = element.querySelector('diagram-rest-call-task > diagram-icon-rest-call-task >' + ' raphael-icon-rest-call'); expect(iconTask).not.toBeNull(); + + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].name); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -470,13 +523,17 @@ describe('Test ng2-activiti-diagrams ', () => { let task: any = element.querySelector('diagram-box-publish-task > diagram-task > raphael-rect'); expect(task).not.toBeNull(); - let taskText: any = element.querySelector('diagram-box-publish-task > diagram-task > raphael-text'); + let taskText: any = element.querySelector('diagram-box-publish-task > diagram-task > raphael-multiline-text'); expect(taskText).not.toBeNull(); expect(taskText.attributes[1].value).toEqual('Fake Box Publish task'); let iconTask: any = element.querySelector('diagram-box-publish-task >' + ' diagram-icon-box-publish-task > raphael-icon-box-publish'); expect(iconTask).not.toBeNull(); + + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].name); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -496,12 +553,16 @@ describe('Test ng2-activiti-diagrams ', () => { let task: any = element.querySelector('diagram-receive-task > diagram-task > raphael-rect'); expect(task).not.toBeNull(); - let taskText: any = element.querySelector('diagram-receive-task > diagram-task > raphael-text'); + let taskText: any = element.querySelector('diagram-receive-task > diagram-task > raphael-multiline-text'); expect(taskText).not.toBeNull(); expect(taskText.attributes[1].value).toEqual('Fake Receive task'); let iconTask: any = element.querySelector('diagram-receive-task > diagram-icon-receive-task > raphael-icon-receive'); expect(iconTask).not.toBeNull(); + + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].name); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -521,12 +582,16 @@ describe('Test ng2-activiti-diagrams ', () => { let task: any = element.querySelector('diagram-script-task > diagram-task > raphael-rect'); expect(task).not.toBeNull(); - let taskText: any = element.querySelector('diagram-script-task > diagram-task > raphael-text'); + let taskText: any = element.querySelector('diagram-script-task > diagram-task > raphael-multiline-text'); expect(taskText).not.toBeNull(); expect(taskText.attributes[1].value).toEqual('Fake Script task'); let iconTask: any = element.querySelector('diagram-script-task > diagram-icon-script-task > raphael-icon-script'); expect(iconTask).not.toBeNull(); + + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].name); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -546,12 +611,16 @@ describe('Test ng2-activiti-diagrams ', () => { let task: any = element.querySelector('diagram-business-rule-task > diagram-task > raphael-rect'); expect(task).not.toBeNull(); - let taskText: any = element.querySelector('diagram-business-rule-task > diagram-task > raphael-text'); + let taskText: any = element.querySelector('diagram-business-rule-task > diagram-task > raphael-multiline-text'); expect(taskText).not.toBeNull(); expect(taskText.attributes[1].value).toEqual('Fake BusinessRule task'); let iconTask: any = element.querySelector('diagram-business-rule-task > diagram-icon-business-rule-task > raphael-icon-business-rule'); expect(iconTask).not.toBeNull(); + + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].name); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -586,6 +655,10 @@ describe('Test ng2-activiti-diagrams ', () => { let shape1: any = element.querySelector('diagram-exclusive-gateway > raphael-cross'); expect(shape1).not.toBeNull(); + + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].id); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -607,6 +680,10 @@ describe('Test ng2-activiti-diagrams ', () => { let shape1: any = element.querySelector('diagram-inclusive-gateway > raphael-circle'); expect(shape1).not.toBeNull(); + + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].id); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -628,6 +705,10 @@ describe('Test ng2-activiti-diagrams ', () => { let shape1: any = element.querySelector('diagram-parallel-gateway > raphael-plus'); expect(shape1).not.toBeNull(); + + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].id); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -659,6 +740,10 @@ describe('Test ng2-activiti-diagrams ', () => { let shape2: any = element.querySelector('diagram-event-gateway > raphael-pentagon'); expect(shape2).not.toBeNull(); + + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].id); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -689,7 +774,7 @@ describe('Test ng2-activiti-diagrams ', () => { expect(res).not.toBeNull(); let shape: any = element.querySelector('diagram-intermediate-catching-event'); expect(shape).not.toBeNull(); - expect(shape.children.length).toBe(3); + expect(shape.children.length).toBe(4); let outerCircle = shape.children[0]; expect(outerCircle.localName).toEqual('raphael-circle'); @@ -700,6 +785,10 @@ describe('Test ng2-activiti-diagrams ', () => { let iconShape: any = element.querySelector('diagram-intermediate-catching-event > diagram-container-icon-event >' + ' div > div > diagram-icon-timer'); expect(iconShape).not.toBeNull(); + + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].id); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -718,7 +807,7 @@ describe('Test ng2-activiti-diagrams ', () => { expect(res).not.toBeNull(); let shape: any = element.querySelector('diagram-intermediate-catching-event'); expect(shape).not.toBeNull(); - expect(shape.children.length).toBe(3); + expect(shape.children.length).toBe(4); let outerCircle = shape.children[0]; expect(outerCircle.localName).toEqual('raphael-circle'); @@ -729,6 +818,10 @@ describe('Test ng2-activiti-diagrams ', () => { let iconShape: any = element.querySelector('diagram-intermediate-catching-event > diagram-container-icon-event >' + ' div > div > diagram-icon-error'); expect(iconShape).not.toBeNull(); + + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].id); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -747,7 +840,7 @@ describe('Test ng2-activiti-diagrams ', () => { expect(res).not.toBeNull(); let shape: any = element.querySelector('diagram-intermediate-catching-event'); expect(shape).not.toBeNull(); - expect(shape.children.length).toBe(3); + expect(shape.children.length).toBe(4); let outerCircle = shape.children[0]; expect(outerCircle.localName).toEqual('raphael-circle'); @@ -758,6 +851,10 @@ describe('Test ng2-activiti-diagrams ', () => { let iconShape: any = element.querySelector('diagram-intermediate-catching-event > diagram-container-icon-event >' + ' div > div > diagram-icon-signal'); expect(iconShape).not.toBeNull(); + + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].id); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -776,7 +873,7 @@ describe('Test ng2-activiti-diagrams ', () => { expect(res).not.toBeNull(); let shape: any = element.querySelector('diagram-intermediate-catching-event'); expect(shape).not.toBeNull(); - expect(shape.children.length).toBe(3); + expect(shape.children.length).toBe(4); let outerCircle = shape.children[0]; expect(outerCircle.localName).toEqual('raphael-circle'); @@ -787,6 +884,10 @@ describe('Test ng2-activiti-diagrams ', () => { let iconShape: any = element.querySelector('diagram-intermediate-catching-event > diagram-container-icon-event >' + ' div > div > diagram-icon-message'); expect(iconShape).not.toBeNull(); + + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].id); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -817,7 +918,7 @@ describe('Test ng2-activiti-diagrams ', () => { expect(res).not.toBeNull(); let shape: any = element.querySelector('diagram-boundary-event'); expect(shape).not.toBeNull(); - expect(shape.children.length).toBe(3); + expect(shape.children.length).toBe(4); let outerCircle = shape.children[0]; expect(outerCircle.localName).toEqual('raphael-circle'); @@ -828,6 +929,10 @@ describe('Test ng2-activiti-diagrams ', () => { let iconShape: any = element.querySelector('diagram-boundary-event > diagram-container-icon-event >' + ' div > div > diagram-icon-timer'); expect(iconShape).not.toBeNull(); + + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].id); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -846,7 +951,7 @@ describe('Test ng2-activiti-diagrams ', () => { expect(res).not.toBeNull(); let shape: any = element.querySelector('diagram-boundary-event'); expect(shape).not.toBeNull(); - expect(shape.children.length).toBe(3); + expect(shape.children.length).toBe(4); let outerCircle = shape.children[0]; expect(outerCircle.localName).toEqual('raphael-circle'); @@ -857,6 +962,10 @@ describe('Test ng2-activiti-diagrams ', () => { let iconShape: any = element.querySelector('diagram-boundary-event > diagram-container-icon-event >' + ' div > div > diagram-icon-error'); expect(iconShape).not.toBeNull(); + + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].id); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -875,7 +984,7 @@ describe('Test ng2-activiti-diagrams ', () => { expect(res).not.toBeNull(); let shape: any = element.querySelector('diagram-boundary-event'); expect(shape).not.toBeNull(); - expect(shape.children.length).toBe(3); + expect(shape.children.length).toBe(4); let outerCircle = shape.children[0]; expect(outerCircle.localName).toEqual('raphael-circle'); @@ -886,6 +995,10 @@ describe('Test ng2-activiti-diagrams ', () => { let iconShape: any = element.querySelector('diagram-boundary-event > diagram-container-icon-event >' + ' div > div > diagram-icon-signal'); expect(iconShape).not.toBeNull(); + + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].id); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -904,7 +1017,7 @@ describe('Test ng2-activiti-diagrams ', () => { expect(res).not.toBeNull(); let shape: any = element.querySelector('diagram-boundary-event'); expect(shape).not.toBeNull(); - expect(shape.children.length).toBe(3); + expect(shape.children.length).toBe(4); let outerCircle = shape.children[0]; expect(outerCircle.localName).toEqual('raphael-circle'); @@ -915,6 +1028,10 @@ describe('Test ng2-activiti-diagrams ', () => { let iconShape: any = element.querySelector('diagram-boundary-event > diagram-container-icon-event >' + ' div > div > diagram-icon-message'); expect(iconShape).not.toBeNull(); + + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].id); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -933,7 +1050,7 @@ describe('Test ng2-activiti-diagrams ', () => { expect(res).not.toBeNull(); let shape: any = element.querySelector('diagram-boundary-event'); expect(shape).not.toBeNull(); - expect(shape.children.length).toBe(3); + expect(shape.children.length).toBe(4); let outerCircle = shape.children[0]; expect(outerCircle.localName).toEqual('raphael-circle'); @@ -944,6 +1061,10 @@ describe('Test ng2-activiti-diagrams ', () => { let iconShape: any = element.querySelector('diagram-boundary-event > diagram-container-icon-event >' + ' div > div > diagram-icon-message'); expect(iconShape).not.toBeNull(); + + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].id); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -974,7 +1095,7 @@ describe('Test ng2-activiti-diagrams ', () => { expect(res).not.toBeNull(); let shape: any = element.querySelector('diagram-throw-event'); expect(shape).not.toBeNull(); - expect(shape.children.length).toBe(3); + expect(shape.children.length).toBe(4); let outerCircle = shape.children[0]; expect(outerCircle.localName).toEqual('raphael-circle'); @@ -1003,7 +1124,7 @@ describe('Test ng2-activiti-diagrams ', () => { expect(res).not.toBeNull(); let shape: any = element.querySelector('diagram-throw-event'); expect(shape).not.toBeNull(); - expect(shape.children.length).toBe(3); + expect(shape.children.length).toBe(4); let outerCircle = shape.children[0]; expect(outerCircle.localName).toEqual('raphael-circle'); @@ -1014,6 +1135,10 @@ describe('Test ng2-activiti-diagrams ', () => { let iconShape: any = element.querySelector('diagram-throw-event > diagram-container-icon-event >' + ' div > div > diagram-icon-error'); expect(iconShape).not.toBeNull(); + + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].id); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -1032,7 +1157,7 @@ describe('Test ng2-activiti-diagrams ', () => { expect(res).not.toBeNull(); let shape: any = element.querySelector('diagram-throw-event'); expect(shape).not.toBeNull(); - expect(shape.children.length).toBe(3); + expect(shape.children.length).toBe(4); let outerCircle = shape.children[0]; expect(outerCircle.localName).toEqual('raphael-circle'); @@ -1043,6 +1168,10 @@ describe('Test ng2-activiti-diagrams ', () => { let iconShape: any = element.querySelector('diagram-throw-event > diagram-container-icon-event >' + ' div > div > diagram-icon-signal'); expect(iconShape).not.toBeNull(); + + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].id); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -1061,7 +1190,7 @@ describe('Test ng2-activiti-diagrams ', () => { expect(res).not.toBeNull(); let shape: any = element.querySelector('diagram-throw-event'); expect(shape).not.toBeNull(); - expect(shape.children.length).toBe(3); + expect(shape.children.length).toBe(4); let outerCircle = shape.children[0]; expect(outerCircle.localName).toEqual('raphael-circle'); @@ -1072,6 +1201,10 @@ describe('Test ng2-activiti-diagrams ', () => { let iconShape: any = element.querySelector('diagram-throw-event > diagram-container-icon-event >' + ' div > div > diagram-icon-message'); expect(iconShape).not.toBeNull(); + + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].id); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -1090,7 +1223,7 @@ describe('Test ng2-activiti-diagrams ', () => { expect(res).not.toBeNull(); let shape: any = element.querySelector('diagram-throw-event'); expect(shape).not.toBeNull(); - expect(shape.children.length).toBe(3); + expect(shape.children.length).toBe(4); let outerCircle = shape.children[0]; expect(outerCircle.localName).toEqual('raphael-circle'); @@ -1101,6 +1234,10 @@ describe('Test ng2-activiti-diagrams ', () => { let iconShape: any = element.querySelector('diagram-throw-event > diagram-container-icon-event >' + ' div > div > diagram-icon-message'); expect(iconShape).not.toBeNull(); + + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].id); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -1131,6 +1268,10 @@ describe('Test ng2-activiti-diagrams ', () => { expect(res).not.toBeNull(); let shape: any = element.querySelector('diagram-subprocess > raphael-rect'); expect(shape).not.toBeNull(); + + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].id); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -1149,6 +1290,10 @@ describe('Test ng2-activiti-diagrams ', () => { expect(res).not.toBeNull(); let shape: any = element.querySelector('diagram-event-subprocess > raphael-rect'); expect(shape).not.toBeNull(); + + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.elements[0].id); + expect(tooltip.textContent).toContain(res.elements[0].type); }); }); component.ngOnChanges(); @@ -1238,6 +1383,10 @@ describe('Test ng2-activiti-diagrams ', () => { expect(res).not.toBeNull(); let shape: any = element.querySelector('diagram-sequence-flow > raphael-flow-arrow'); expect(shape).not.toBeNull(); + + let tooltip: any = element.querySelector('diagram-tooltip > div'); + expect(tooltip.textContent).toContain(res.flows[0].id); + expect(tooltip.textContent).toContain(res.flows[0].type); }); }); component.ngOnChanges(); diff --git a/ng2-components/ng2-activiti-diagrams/src/components/diagram.component.ts b/ng2-components/ng2-activiti-diagrams/src/components/diagram.component.ts index d0c426c9a3..d4e78c7248 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/diagram.component.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/diagram.component.ts @@ -20,10 +20,12 @@ import { AlfrescoTranslationService } from 'ng2-alfresco-core'; import { DiagramsService } from '../services/diagrams.service'; import { DiagramColorService } from '../services/diagram-color.service'; import { RaphaelService } from './raphael/raphael.service'; +import { DiagramModel, DiagramElementModel } from '../models/diagram.model'; @Component({ moduleId: module.id, selector: 'activiti-diagram', + styleUrls: ['./diagram.component.css'], templateUrl: './diagram.component.html' }) export class DiagramComponent { @@ -33,6 +35,12 @@ export class DiagramComponent { @Input() metricPercentages: any; + @Input() + metricColor: any; + + @Input() + metricType: string = ''; + @Input() width: number = 1000; @@ -45,7 +53,10 @@ export class DiagramComponent { @Output() onError = new EventEmitter(); - private diagram: any; + PADDING_WIDTH: number = 60; + PADDING_HEIGHT: number = 60; + + private diagram: DiagramModel; private elementRef: ElementRef; constructor(elementRef: ElementRef, @@ -54,25 +65,23 @@ export class DiagramComponent { private raphaelService: RaphaelService, private diagramsService: DiagramsService) { if (translate) { - translate.addTranslationFolder('ng2-activiti-analytics', 'node_modules/ng2-activiti-analytics/dist/src'); + translate.addTranslationFolder('ng2-activiti-diagrams', 'node_modules/ng2-activiti-diagrams/src'); } this.elementRef = elementRef; } - ngOnInit() { - this.raphaelService.setting(this.width, this.height); - } - ngOnChanges(changes: SimpleChanges) { this.reset(); - this.diagramColorService.setTotalColors(this.metricPercentages); + this.diagramColorService.setTotalColors(this.metricColor); this.getProcessDefinitionModel(this.processDefinitionId); } getProcessDefinitionModel(processDefinitionId: string) { this.diagramsService.getProcessDefinitionModel(processDefinitionId).subscribe( (res: any) => { - this.diagram = res; + this.diagram = new DiagramModel(res); + this.raphaelService.setting(this.diagram.diagramWidth + this.PADDING_WIDTH, this.diagram.diagramHeight + this.PADDING_HEIGHT); + this.setMetricValueToDiagramElement(this.diagram, this.metricPercentages, this.metricType); this.onSuccess.emit(res); }, (err: any) => { @@ -82,6 +91,19 @@ export class DiagramComponent { ); } + setMetricValueToDiagramElement(diagram: DiagramModel, metrics: any, metricType: string) { + for (let key in metrics) { + if (metrics.hasOwnProperty(key)) { + let foundElement: DiagramElementModel = diagram.elements.find( + (element: DiagramElementModel) => element.id === key); + if (foundElement) { + foundElement.value = metrics[key]; + foundElement.dataType = metricType; + } + } + } + } + reset() { this.raphaelService.reset(); } diff --git a/ng2-components/ng2-activiti-diagrams/src/components/events/diagram-end-event.component.ts b/ng2-components/ng2-activiti-diagrams/src/components/events/diagram-end-event.component.ts index c7b8a9287d..f84d0c553b 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/events/diagram-end-event.component.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/events/diagram-end-event.component.ts @@ -37,7 +37,6 @@ export class DiagramEndEventComponent { private diagramColorService: DiagramColorService) {} ngOnInit() { - console.log(this.elementRef); this.options.radius = 14; this.options.strokeWidth = 4; diff --git a/ng2-components/ng2-activiti-diagrams/src/components/events/diagram-event.component.html b/ng2-components/ng2-activiti-diagrams/src/components/events/diagram-event.component.html index e85a6aee8d..d5f271463e 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/events/diagram-event.component.html +++ b/ng2-components/ng2-activiti-diagrams/src/components/events/diagram-event.component.html @@ -1,4 +1,5 @@ - \ No newline at end of file + [fillColor]="iconFillColor"> + diff --git a/ng2-components/ng2-activiti-diagrams/src/components/events/diagram-event.component.ts b/ng2-components/ng2-activiti-diagrams/src/components/events/diagram-event.component.ts index 8bf1ebd557..4555ccdac2 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/events/diagram-event.component.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/events/diagram-event.component.ts @@ -42,7 +42,7 @@ export class DiagramEventComponent { private diagramColorService: DiagramColorService) {} ngOnInit() { - console.log(this.elementRef); + this.center.x = this.data.x + (this.data.width / 2); this.center.y = this.data.y + (this.data.height / 2); } diff --git a/ng2-components/ng2-activiti-diagrams/src/components/events/diagram-start-event.component.ts b/ng2-components/ng2-activiti-diagrams/src/components/events/diagram-start-event.component.ts index 83d0369894..57b19b4ad6 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/events/diagram-start-event.component.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/events/diagram-start-event.component.ts @@ -37,7 +37,6 @@ export class DiagramStartEventComponent { private diagramColorService: DiagramColorService) {} ngOnInit() { - console.log(this.elementRef); this.options.radius = 15; this.options.strokeWidth = 1; diff --git a/ng2-components/ng2-activiti-diagrams/src/components/gateways/diagram-gateway.component.html b/ng2-components/ng2-activiti-diagrams/src/components/gateways/diagram-gateway.component.html index 6550ba6dca..675fd3d428 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/gateways/diagram-gateway.component.html +++ b/ng2-components/ng2-activiti-diagrams/src/components/gateways/diagram-gateway.component.html @@ -1,2 +1,3 @@ - \ No newline at end of file + + diff --git a/ng2-components/ng2-activiti-diagrams/src/components/icons/diagram-icon-send-task.component.html b/ng2-components/ng2-activiti-diagrams/src/components/icons/diagram-icon-send-task.component.html index 50185da5f6..5f87206541 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/icons/diagram-icon-send-task.component.html +++ b/ng2-components/ng2-activiti-diagrams/src/components/icons/diagram-icon-send-task.component.html @@ -1,2 +1,3 @@ \ No newline at end of file + [fillColors]="options.fillColors" [fillOpacity]="options.fillOpacity"> + diff --git a/ng2-components/ng2-activiti-diagrams/src/components/icons/diagram-icon-timer.component.html b/ng2-components/ng2-activiti-diagrams/src/components/icons/diagram-icon-timer.component.html index 1bb93fff2a..73ddeeb3a0 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/icons/diagram-icon-timer.component.html +++ b/ng2-components/ng2-activiti-diagrams/src/components/icons/diagram-icon-timer.component.html @@ -1,4 +1,5 @@ \ No newline at end of file + [fillColors]="timerOptions.fillColors" [fillOpacity]="timerOptions.fillOpacity"> + diff --git a/ng2-components/ng2-activiti-diagrams/src/components/index.ts b/ng2-components/ng2-activiti-diagrams/src/components/index.ts index b6346365b9..68ca24bf0d 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/index.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/index.ts @@ -25,6 +25,7 @@ import { DIAGRAM_BOUNDARY_EVENTS_DIRECTIVES } from './boundary-events/index'; import { DIAGRAM_INTERMEDIATE_EVENTS_DIRECTIVES } from './intermediate-catching-events/index'; import { DIAGRAM_STRUCTURAL_DIRECTIVES } from './structural/index'; import { DIAGRAM_SWIMLANES_DIRECTIVES } from './swimlanes/index'; +import { DiagramTooltip } from './tooltip/index'; import { DiagramColorService } from '../services/diagram-color.service'; import { DiagramsService } from '../services/diagrams.service'; @@ -50,7 +51,8 @@ export const DIAGRAM_DIRECTIVES: any[] = [ DIAGRAM_BOUNDARY_EVENTS_DIRECTIVES, DIAGRAM_INTERMEDIATE_EVENTS_DIRECTIVES, DIAGRAM_STRUCTURAL_DIRECTIVES, - DIAGRAM_SWIMLANES_DIRECTIVES + DIAGRAM_SWIMLANES_DIRECTIVES, + DiagramTooltip ]; export const DIAGRAM_PROVIDERS: any[] = [ diff --git a/ng2-components/ng2-activiti-diagrams/src/components/intermediate-catching-events/diagram-intermediate-catching-event.component.html b/ng2-components/ng2-activiti-diagrams/src/components/intermediate-catching-events/diagram-intermediate-catching-event.component.html index b5eb151f55..d1717ccfab 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/intermediate-catching-events/diagram-intermediate-catching-event.component.html +++ b/ng2-components/ng2-activiti-diagrams/src/components/intermediate-catching-events/diagram-intermediate-catching-event.component.html @@ -1,5 +1,6 @@ - - \ No newline at end of file + + diff --git a/ng2-components/ng2-activiti-diagrams/src/components/raphael/anchor.ts b/ng2-components/ng2-activiti-diagrams/src/components/raphael/anchor.ts new file mode 100644 index 0000000000..7371193e52 --- /dev/null +++ b/ng2-components/ng2-activiti-diagrams/src/components/raphael/anchor.ts @@ -0,0 +1,41 @@ +/*! + * @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. + */ + +export class Anchor { + + public static ANCHOR_TYPE: any = { + main: 'main', + middle: 'middle', + first: 'first', + last: 'last' + }; + + uuid: any = null; + x: any = 0; + y: any = 0; + isFirst: any = false; + isLast: any = false; + typeIndex: any = 0; + type: any = Anchor.ANCHOR_TYPE.main; + + constructor(uuid: any, type: any, x: any, y: any) { + this.uuid = uuid; + this.x = x; + this.y = y; + this.type = (type === Anchor.ANCHOR_TYPE.middle) ? Anchor.ANCHOR_TYPE.middle : Anchor.ANCHOR_TYPE.main; + } +} diff --git a/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-alfresco-publish.component.ts b/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-alfresco-publish.component.ts index 878b094511..8a410194fb 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-alfresco-publish.component.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-alfresco-publish.component.ts @@ -52,7 +52,7 @@ export class RaphaelIconAlfrescoPublishDirective extends RaphaelBase implements } ngOnInit() { - console.log(this.elementRef); + this.draw(this.position); } diff --git a/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-box-publish.component.ts b/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-box-publish.component.ts index 545d4b0c63..ac8dfc4efe 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-box-publish.component.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-box-publish.component.ts @@ -52,7 +52,7 @@ export class RaphaelIconBoxPublishDirective extends RaphaelBase implements OnIni } ngOnInit() { - console.log(this.elementRef); + this.draw(this.position); } diff --git a/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-business-rule.component.ts b/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-business-rule.component.ts index c782593f0c..15b7f5718b 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-business-rule.component.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-business-rule.component.ts @@ -52,7 +52,7 @@ export class RaphaelIconBusinessRuleDirective extends RaphaelBase implements OnI } ngOnInit() { - console.log(this.elementRef); + this.draw(this.position); } diff --git a/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-camel.component.ts b/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-camel.component.ts index 81339c4abb..80b6a41c49 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-camel.component.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-camel.component.ts @@ -52,7 +52,7 @@ export class RaphaelIconCamelDirective extends RaphaelBase implements OnInit { } ngOnInit() { - console.log(this.elementRef); + this.draw(this.position); } diff --git a/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-error.component.ts b/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-error.component.ts index c77ab84943..8f4090bffc 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-error.component.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-error.component.ts @@ -52,7 +52,7 @@ export class RaphaelIconErrorDirective extends RaphaelBase implements OnInit { } ngOnInit() { - console.log(this.elementRef); + this.draw(this.position); } diff --git a/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-google-drive-publish.component.ts b/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-google-drive-publish.component.ts index 065cf35235..ec9bfe0ec2 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-google-drive-publish.component.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-google-drive-publish.component.ts @@ -52,7 +52,7 @@ export class RaphaelIconGoogleDrivePublishDirective extends RaphaelBase implemen } ngOnInit() { - console.log(this.elementRef); + this.draw(this.position); } diff --git a/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-manual.component.ts b/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-manual.component.ts index 9f073711f6..e76bea1445 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-manual.component.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-manual.component.ts @@ -52,7 +52,7 @@ export class RaphaelIconManualDirective extends RaphaelBase implements OnInit { } ngOnInit() { - console.log(this.elementRef); + this.draw(this.position); } diff --git a/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-message.component.ts b/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-message.component.ts index 85ea452f61..2dae9c034d 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-message.component.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-message.component.ts @@ -52,7 +52,7 @@ export class RaphaelIconMessageDirective extends RaphaelBase implements OnInit { } ngOnInit() { - console.log(this.elementRef); + this.draw(this.position); } diff --git a/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-mule.component.ts b/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-mule.component.ts index 3bf4e42147..344496618e 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-mule.component.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-mule.component.ts @@ -52,7 +52,7 @@ export class RaphaelIconMuleDirective extends RaphaelBase implements OnInit { } ngOnInit() { - console.log(this.elementRef); + this.draw(this.position); } diff --git a/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-receive.component.ts b/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-receive.component.ts index 6b1aea8a1b..055bcba22a 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-receive.component.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-receive.component.ts @@ -52,7 +52,7 @@ export class RaphaelIconReceiveDirective extends RaphaelBase implements OnInit { } ngOnInit() { - console.log(this.elementRef); + this.draw(this.position); } diff --git a/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-rest-call.component.ts b/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-rest-call.component.ts index a46e83d67d..06e7e2ae2d 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-rest-call.component.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-rest-call.component.ts @@ -52,7 +52,7 @@ export class RaphaelIconRestCallDirective extends RaphaelBase implements OnInit } ngOnInit() { - console.log(this.elementRef); + this.draw(this.position); } diff --git a/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-script.component.ts b/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-script.component.ts index beee45747b..f36ec14c96 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-script.component.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-script.component.ts @@ -52,7 +52,7 @@ export class RaphaelIconScriptDirective extends RaphaelBase implements OnInit { } ngOnInit() { - console.log(this.elementRef); + this.draw(this.position); } diff --git a/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-send.component.ts b/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-send.component.ts index cd2adc4004..e47d2e66fb 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-send.component.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-send.component.ts @@ -52,7 +52,7 @@ export class RaphaelIconSendDirective extends RaphaelBase implements OnInit { } ngOnInit() { - console.log(this.elementRef); + this.draw(this.position); } diff --git a/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-service.component.ts b/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-service.component.ts index c5db7a5601..bf336e2bbc 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-service.component.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-service.component.ts @@ -52,7 +52,7 @@ export class RaphaelIconServiceDirective extends RaphaelBase implements OnInit { } ngOnInit() { - console.log(this.elementRef); + this.draw(this.position); } diff --git a/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-signal.component.ts b/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-signal.component.ts index 7a0b6f5657..955880e0b7 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-signal.component.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-signal.component.ts @@ -52,7 +52,7 @@ export class RaphaelIconSignalDirective extends RaphaelBase implements OnInit { } ngOnInit() { - console.log(this.elementRef); + this.draw(this.position); } diff --git a/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-timer.component.ts b/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-timer.component.ts index 22156b044a..fb5d3675d8 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-timer.component.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-timer.component.ts @@ -52,7 +52,7 @@ export class RaphaelIconTimerDirective extends RaphaelBase implements OnInit { } ngOnInit() { - console.log(this.elementRef); + this.draw(this.position); } diff --git a/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-user.component.ts b/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-user.component.ts index b0ee5a149e..362e0d6522 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-user.component.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/raphael/icons/raphael-icon-user.component.ts @@ -52,7 +52,7 @@ export class RaphaelIconUserDirective extends RaphaelBase implements OnInit { } ngOnInit() { - console.log(this.elementRef); + this.draw(this.position); } diff --git a/ng2-components/ng2-activiti-diagrams/src/components/raphael/index.ts b/ng2-components/ng2-activiti-diagrams/src/components/raphael/index.ts index fff8b99a57..8f8cba2323 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/raphael/index.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/raphael/index.ts @@ -18,6 +18,7 @@ import { RaphaelCircleDirective } from './raphael-circle.component'; import { RaphaelRectDirective } from './raphael-rect.component'; import { RaphaelTextDirective } from './raphael-text.component'; +import { RaphaelMultilineTextDirective } from './raphael-multiline-text.component'; import { RaphaelFlowArrowDirective } from './raphael-flow-arrow.component'; import { RaphaelCrossDirective } from './raphael-cross.component'; import { RaphaelPlusDirective } from './raphael-plus.component'; @@ -34,6 +35,7 @@ import { RAPHAEL_ICONS_DIRECTIVES } from './icons/index'; export * from './raphael-circle.component'; export * from './raphael-rect.component'; export * from './raphael-text.component'; +export * from './raphael-multiline-text.component'; export * from './raphael-flow-arrow.component'; export * from './raphael-cross.component'; export * from './raphael-plus.component'; @@ -45,6 +47,7 @@ export const RAPHAEL_DIRECTIVES: any[] = [ RaphaelCircleDirective, RaphaelRectDirective, RaphaelTextDirective, + RaphaelMultilineTextDirective, RaphaelFlowArrowDirective, RaphaelCrossDirective, RaphaelPlusDirective, diff --git a/ng2-components/ng2-activiti-diagrams/src/components/raphael/polyline.ts b/ng2-components/ng2-activiti-diagrams/src/components/raphael/polyline.ts new file mode 100644 index 0000000000..2f44227246 --- /dev/null +++ b/ng2-components/ng2-activiti-diagrams/src/components/raphael/polyline.ts @@ -0,0 +1,312 @@ +/*! + * @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 { Anchor } from './anchor'; + +/* tslint:disable */ +export class Polyline { + + id: any = null; + points: any = []; + path: any = []; + anchors: any = []; + strokeWidth: any = 1; + radius: any = 1; + showDetails: any = false; + paper: any = null; + element: any = null; + isDefaultConditionAvailable: any = false; + closePath: any = false; + + constructor(uuid, points, strokeWidth, paper) { + /* Array on coordinates: + * points: [{x: 410, y: 110}, 1 + * {x: 570, y: 110}, 1 2 + * {x: 620, y: 240}, 2 3 + * {x: 750, y: 270}, 3 4 + * {x: 650, y: 370}]; 4 + */ + this.points = points; + /* + * path for graph + * [['M', x1, y1], ['L', x2, y2], ['C', ax, ay, bx, by, x3, y3], ['L', x3, y3]] + */ + this.path = []; + + this.anchors = []; + + if (strokeWidth) { + this.strokeWidth = strokeWidth; + } + + this.paper = paper; + + this.closePath = false; + + this.init(); + } + + init() { + var linesCount = this.getLinesCount(); + if (linesCount < 1) { + return; + } + + this.normalizeCoordinates(); + + // create anchors + + this.pushAnchor(Anchor.ANCHOR_TYPE.first, this.getLine(0).x1, this.getLine(0).y1); + + for (var i = 1; i < linesCount; i++) { + var line1 = this.getLine(i - 1); + this.pushAnchor(Anchor.ANCHOR_TYPE.main, line1.x2, line1.y2); + } + + this.pushAnchor(Anchor.ANCHOR_TYPE.last, this.getLine(linesCount - 1).x2, this.getLine(linesCount - 1).y2); + + this.rebuildPath(); + } + + normalizeCoordinates() { + for (var i = 0; i < this.points.length; i++) { + this.points[i].x = parseFloat(this.points[i].x); + this.points[i].y = parseFloat(this.points[i].y); + } + } + + getLinesCount() { + return this.points.length - 1; + } + + _getLine(i) { + if (this.points.length > i && this.points[i]) { + return {x1: this.points[i].x, y1: this.points[i].y, x2: this.points[i + 1].x, y2: this.points[i + 1].y}; + } else { + return undefined; + } + } + + getLine(i) { + var line: any = this._getLine(i); + if (line !== undefined) { + line.angle = this.getLineAngle(i); + } + return line; + } + + getLineAngle(i) { + var line = this._getLine(i); + return Math.atan2(line.y2 - line.y1, line.x2 - line.x1); + } + + getLineLengthX(i) { + var line = this.getLine(i); + return (line.x2 - line.x1); + } + + getLineLengthY(i) { + var line = this.getLine(i); + return (line.y2 - line.y1); + } + + getLineLength(i) { + return Math.sqrt(Math.pow(this.getLineLengthX(i), 2) + Math.pow(this.getLineLengthY(i), 2)); + } + + getAnchors() { + return this.anchors; + } + + getAnchorsCount(type: any = null) { + if (!type) { + return this.anchors.length; + } else { + var count = 0; + for (var i = 0; i < this.getAnchorsCount(null); i++) { + var anchor = this.anchors[i]; + if (anchor.getType() === type) { + count++; + } + } + return count; + } + } + + pushAnchor(type, x, y) { + var index, typeIndex; + if (type === Anchor.ANCHOR_TYPE.first) { + index = 0; + typeIndex = 0; + } else if (type === Anchor.ANCHOR_TYPE.last) { + index = this.getAnchorsCount(); + typeIndex = 0; + } else if (!index) { + index = this.anchors.length; + } else { + for (var i = 0; i < this.getAnchorsCount(); i++) { + var anchor = this.anchors[i]; + if (anchor.index > index) { + anchor.index++; + anchor.typeIndex++; + } + } + } + + var anchor: any = new Anchor(this.id, Anchor.ANCHOR_TYPE.main, x, y); + + this.anchors.push(anchor); + } + + getAnchor(position) { + return this.anchors[position]; + } + + getAnchorByType(type, position) { + if (type === Anchor.ANCHOR_TYPE.first) { + return this.anchors[0]; + } + if (type === Anchor.ANCHOR_TYPE.last) { + return this.anchors[this.getAnchorsCount() - 1]; + } + for (var i = 0; i < this.getAnchorsCount(); i++) { + var anchor = this.anchors[i]; + if (anchor.type === type) { + if (position === anchor.position) { + return anchor; + } + } + } + return null; + } + + addNewPoint(position, x, y) { + // + for (var i = 0; i < this.getLinesCount(); i++) { + var line = this.getLine(i); + if (x > line.x1 && x < line.x2 && y > line.y1 && y < line.y2) { + this.points.splice(i + 1, 0, {x: x, y: y}); + break; + } + } + + this.rebuildPath(); + } + + rebuildPath() { + var path = []; + + for (var i = 0; i < this.getAnchorsCount(); i++) { + var anchor = this.getAnchor(i); + + var pathType = ''; + + if (i === 0) { + pathType = 'M'; + } else { + pathType = 'L'; + } + // TODO: save previous points and calculate new path just if points are updated, and then save currents values as previous + + var targetX = anchor.x, targetY = anchor.y; + if (i > 0 && i < this.getAnchorsCount() - 1) { + // get new x,y + var cx = anchor.x, cy = anchor.y; + + // pivot point of prev line + var AO = this.getLineLength(i - 1); + if (AO < this.radius) { + AO = this.radius; + } + + this.isDefaultConditionAvailable = (this.isDefaultConditionAvailable || (i === 1 && AO > 10)); + + var ED = this.getLineLengthY(i - 1) * this.radius / AO; + var OD = this.getLineLengthX(i - 1) * this.radius / AO; + targetX = anchor.x - OD; + targetY = anchor.y - ED; + + if (AO < 2 * this.radius && i > 1) { + targetX = anchor.x - this.getLineLengthX(i - 1) / 2; + targetY = anchor.y - this.getLineLengthY(i - 1) / 2; + } + + // pivot point of next line + var AO = this.getLineLength(i); + if (AO < this.radius) { + AO = this.radius; + } + var ED = this.getLineLengthY(i) * this.radius / AO; + var OD = this.getLineLengthX(i) * this.radius / AO; + var nextSrcX = anchor.x + OD; + var nextSrcY = anchor.y + ED; + + if (AO < 2 * this.radius && i < this.getAnchorsCount() - 2) { + nextSrcX = anchor.x + this.getLineLengthX(i) / 2; + nextSrcY = anchor.y + this.getLineLengthY(i) / 2; + ; + } + + var dx0 = (cx - targetX) / 3, + dy0 = (cy - targetY) / 3, + ax = cx - dx0, + ay = cy - dy0, + + dx1 = (cx - nextSrcX) / 3, + dy1 = (cy - nextSrcY) / 3, + bx = cx - dx1, + by = cy - dy1, + + zx = nextSrcX, zy = nextSrcY; + + } else if (i === 1 && this.getAnchorsCount() === 2) { + var AO = this.getLineLength(i - 1); + if (AO < this.radius) { + AO = this.radius; + } + this.isDefaultConditionAvailable = (this.isDefaultConditionAvailable || (i === 1 && AO > 10)); + } + + // anti smoothing + if (this.strokeWidth % 2 === 1) { + targetX += 0.5; + targetY += 0.5; + } + + path.push([pathType, targetX, targetY]); + + if (i > 0 && i < this.getAnchorsCount() - 1) { + path.push(['C', ax, ay, bx, by, zx, zy]); + } + } + + if (this.closePath) { + path.push(['Z']); + } + + this.path = path; + } + + transform(transformation) { + this.element.transform(transformation); + } + + function(attrs) { + this.element.attr(attrs); + } + +} diff --git a/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-circle.component.ts b/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-circle.component.ts index 566ceb0754..f146b7d233 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-circle.component.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-circle.component.ts @@ -43,6 +43,9 @@ export class RaphaelCircleDirective extends RaphaelBase implements OnInit { @Input() fillOpacity: any; + @Input() + elementId: string; + @Output() onError = new EventEmitter(); @@ -52,9 +55,10 @@ export class RaphaelCircleDirective extends RaphaelBase implements OnInit { } ngOnInit() { - console.log(this.elementRef); + let opts = {'stroke-width': this.strokeWidth, 'fill': this.fillColors, 'stroke': this.stroke, 'fill-opacity': this.fillOpacity}; - this.draw(this.center, this.radius, opts); + let drawElement = this.draw(this.center, this.radius, opts); + drawElement.node.id = this.elementId; } public draw(center: Point, radius: number, opts: any) { diff --git a/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-cross.component.ts b/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-cross.component.ts index e023868792..f2d1b6631c 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-cross.component.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-cross.component.ts @@ -52,7 +52,7 @@ export class RaphaelCrossDirective extends RaphaelBase implements OnInit { } ngOnInit() { - console.log(this.elementRef); + let opts = {'stroke-width': this.strokeWidth, 'fill': this.fillColors, 'stroke': this.stroke, 'fill-opacity': this.fillOpacity}; this.draw(this.center, this.width, this.height, opts); } diff --git a/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-flow-arrow.component.ts b/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-flow-arrow.component.ts index 3cf8ae5cb3..0a44c55bc8 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-flow-arrow.component.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-flow-arrow.component.ts @@ -18,6 +18,9 @@ import { Directive, OnInit, ElementRef, Input, Output, EventEmitter } from '@angular/core'; import { RaphaelBase } from './raphael-base'; import { RaphaelService } from './raphael.service'; +import { Polyline } from './polyline'; + +declare let Raphael: any; @Directive({selector: 'raphael-flow-arrow'}) export class RaphaelFlowArrowDirective extends RaphaelBase implements OnInit { @@ -39,7 +42,7 @@ export class RaphaelFlowArrowDirective extends RaphaelBase implements OnInit { } ngOnInit() { - console.log(this.elementRef); + this.draw(this.flow); } @@ -54,7 +57,7 @@ export class RaphaelFlowArrowDirective extends RaphaelBase implements OnInit { polyline.element.attr({'stroke-width': this.SEQUENCEFLOW_STROKE}); polyline.element.attr({'stroke': '#585858'}); - polyline.element.id = this.flow.id; + polyline.element.node.id = this.flow.id; let lastLineIndex = polyline.getLinesCount() - 1; let line = polyline.getLine(lastLineIndex); diff --git a/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-multiline-text.component.ts b/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-multiline-text.component.ts new file mode 100644 index 0000000000..0b294970a0 --- /dev/null +++ b/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-multiline-text.component.ts @@ -0,0 +1,94 @@ +/*! + * @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 { Directive, OnInit, ElementRef, Input, Output, EventEmitter } from '@angular/core'; +import { Point } from './models/point'; +import { RaphaelBase } from './raphael-base'; +import { RaphaelService } from './raphael.service'; + +@Directive({ selector: 'raphael-multiline-text' }) +export class RaphaelMultilineTextDirective extends RaphaelBase implements OnInit { + @Input() + paper: any; + + @Input() + position: Point; + + @Input() + transform: string; + + @Input() + text: string; + + @Input() + elementWidth: number; + + @Output() + onError = new EventEmitter(); + + TEXT_PADDING = 3; + + constructor(public elementRef: ElementRef, + raphaelService: RaphaelService) { + super(elementRef, raphaelService); + } + + ngOnInit() { + console.log(this.elementRef); + if (this.text === null || this.text === undefined) { + this.text = ''; + } + this.draw(this.position, this.text); + } + + public draw(position: Point, text: string) { + let textPaper = this.paper.text(position.x + this.TEXT_PADDING, position.y + this.TEXT_PADDING, text).attr({ + 'text-anchor': 'middle', + 'font-family': 'Arial', + 'font-size': '11', + 'fill': '#373e48' + }); + + let formattedText = this.formatText(textPaper, text, this.elementWidth); + textPaper.attr({ + 'text': formattedText + }); + textPaper.transform(this.transform); + return textPaper; + } + + private formatText(textPaper, text, elementWidth) { + let letterWidth = textPaper.getBBox().width / text.length; + let removedLineBreaks = text.split('\n'); + let actualRowLength = 0, formattedText = []; + removedLineBreaks.forEach(senteces => { + let words = senteces.split(' '); + words.forEach(word => { + let length = word.length; + if (actualRowLength + (length * letterWidth) > elementWidth) { + formattedText.push('\n'); + actualRowLength = 0; + } + actualRowLength += length * letterWidth; + formattedText.push(word + ' '); + }); + formattedText.push('\n'); + actualRowLength = 0; + }); + return formattedText.join(''); + } +} diff --git a/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-pentagon.component.ts b/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-pentagon.component.ts index cdc6a26892..5ad6990be6 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-pentagon.component.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-pentagon.component.ts @@ -49,7 +49,7 @@ export class RaphaelPentagonDirective extends RaphaelBase implements OnInit { } ngOnInit() { - console.log(this.elementRef); + let opts = { 'stroke-width': this.strokeWidth, 'fill': this.fillColors, diff --git a/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-plus.component.ts b/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-plus.component.ts index 81db7bd020..6620d35b9a 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-plus.component.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-plus.component.ts @@ -46,7 +46,7 @@ export class RaphaelPlusDirective extends RaphaelBase implements OnInit { } ngOnInit() { - console.log(this.elementRef); + let opts = {'stroke-width': this.strokeWidth, 'fill': this.fillColors, 'stroke': this.stroke, 'fill-opacity': this.fillOpacity}; this.draw(this.center, opts); } diff --git a/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-rect.component.ts b/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-rect.component.ts index d4b147f914..ee073216f1 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-rect.component.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-rect.component.ts @@ -20,7 +20,7 @@ import { Point } from './models/point'; import { RaphaelBase } from './raphael-base'; import { RaphaelService } from './raphael.service'; -@Directive({selector: 'raphael-rect'}) +@Directive({ selector: 'raphael-rect' }) export class RaphaelRectDirective extends RaphaelBase implements OnInit { @Input() paper: any; @@ -49,6 +49,9 @@ export class RaphaelRectDirective extends RaphaelBase implements OnInit { @Input() fillOpacity: any; + @Input() + elementId: string; + @Output() onError = new EventEmitter(); @@ -58,9 +61,15 @@ export class RaphaelRectDirective extends RaphaelBase implements OnInit { } ngOnInit() { - console.log(this.elementRef); - let opts = {'stroke-width': this.strokeWidth, 'fill': this.fillColors, 'stroke': this.stroke, 'fill-opacity': this.fillOpacity}; - this.draw(this.leftCorner, this.width, this.height, this.radius, opts); + + let opts = { + 'stroke-width': this.strokeWidth, + 'fill': this.fillColors, + 'stroke': this.stroke, + 'fill-opacity': this.fillOpacity + }; + let elementDraw = this.draw(this.leftCorner, this.width, this.height, this.radius, opts); + elementDraw.node.id = this.elementId; } public draw(leftCorner: Point, width: number, height: number, radius: number, opts: any) { diff --git a/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-rhombus.component.ts b/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-rhombus.component.ts index 08e2d7d3fd..4820fedbb4 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-rhombus.component.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-rhombus.component.ts @@ -43,6 +43,9 @@ export class RaphaelRhombusDirective extends RaphaelBase implements OnInit { @Input() fillOpacity: any; + @Input() + elementId: string; + @Output() onError = new EventEmitter(); @@ -52,13 +55,14 @@ export class RaphaelRhombusDirective extends RaphaelBase implements OnInit { } ngOnInit() { - console.log(this.elementRef); + let opts = {'stroke-width': this.strokeWidth, 'fill': this.fillColors, 'stroke': this.stroke, 'fill-opacity': this.fillOpacity}; - this.draw(this.center, this.width, this.height, opts); + let elementDraw = this.draw(this.center, this.width, this.height, opts); + elementDraw.node.id = this.elementId; } public draw(center: Point, width: number, height: number, opts?: any) { - this.paper.path('M' + center.x + ' ' + (center.y + (height / 2)) + + return this.paper.path('M' + center.x + ' ' + (center.y + (height / 2)) + 'L' + (center.x + (width / 2)) + ' ' + (center.y + height) + 'L' + (center.x + width) + ' ' + (center.y + (height / 2)) + 'L' + (center.x + (width / 2)) + ' ' + center.y + 'z' diff --git a/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-text.component.ts b/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-text.component.ts index bb177072bb..673db8ea7c 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-text.component.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael-text.component.ts @@ -43,7 +43,7 @@ export class RaphaelTextDirective extends RaphaelBase implements OnInit { } ngOnInit() { - console.log(this.elementRef); + if (this.text === null || this.text === undefined) { this.text = ''; } diff --git a/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael.service.ts b/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael.service.ts index 44da5c3324..21314b8e54 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael.service.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/raphael/raphael.service.ts @@ -17,12 +17,14 @@ import { Injectable } from '@angular/core'; +declare let Raphael: any; + @Injectable() export class RaphaelService { paper: any; width: number = 300; - height: number = 400 ; + height: number = 400; private ctx: any; constructor() { diff --git a/ng2-components/ng2-activiti-diagrams/src/components/structural/diagram-event-subprocess.component.html b/ng2-components/ng2-activiti-diagrams/src/components/structural/diagram-event-subprocess.component.html index a3b195375b..35f293f7fb 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/structural/diagram-event-subprocess.component.html +++ b/ng2-components/ng2-activiti-diagrams/src/components/structural/diagram-event-subprocess.component.html @@ -1,3 +1,4 @@ \ No newline at end of file + [fillColors]="options.fillColors" [fillOpacity]="options.fillOpacity"> + diff --git a/ng2-components/ng2-activiti-diagrams/src/components/structural/diagram-subprocess.component.html b/ng2-components/ng2-activiti-diagrams/src/components/structural/diagram-subprocess.component.html index a3b195375b..35f293f7fb 100644 --- a/ng2-components/ng2-activiti-diagrams/src/components/structural/diagram-subprocess.component.html +++ b/ng2-components/ng2-activiti-diagrams/src/components/structural/diagram-subprocess.component.html @@ -1,3 +1,4 @@ \ No newline at end of file + [fillColors]="options.fillColors" [fillOpacity]="options.fillOpacity"> + diff --git a/ng2-components/ng2-activiti-diagrams/src/components/tooltip/diagram-tooltip-style.css b/ng2-components/ng2-activiti-diagrams/src/components/tooltip/diagram-tooltip-style.css new file mode 100644 index 0000000000..93868ce92c --- /dev/null +++ b/ng2-components/ng2-activiti-diagrams/src/components/tooltip/diagram-tooltip-style.css @@ -0,0 +1,21 @@ +.mdl-tooltip { + will-change: unset; +} + +.mdl-tooltip-diagram { + background: white; + padding: 0px; +} + +.mdl-tooltip-header__message { + background: black; + color: white; + margin-top: 0px; + margin-bottom: 3px; + width:100%; +} + +.mdl-tooltip-body__message { + color: black; + text-align: center; +} diff --git a/ng2-components/ng2-activiti-diagrams/src/components/tooltip/diagram-tooltip.component.html b/ng2-components/ng2-activiti-diagrams/src/components/tooltip/diagram-tooltip.component.html new file mode 100644 index 0000000000..0d2084beba --- /dev/null +++ b/ng2-components/ng2-activiti-diagrams/src/components/tooltip/diagram-tooltip.component.html @@ -0,0 +1,6 @@ +
+
+
{{getTooltipHeader(data)}}
+ {{getTooltipMessage(data)}} +
+
diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/cell.editor.spec.ts b/ng2-components/ng2-activiti-diagrams/src/components/tooltip/diagram-tooltip.component.ts similarity index 52% rename from ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/cell.editor.spec.ts rename to ng2-components/ng2-activiti-diagrams/src/components/tooltip/diagram-tooltip.component.ts index 239ce25eee..daadc6a173 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/cell.editor.spec.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/tooltip/diagram-tooltip.component.ts @@ -15,28 +15,25 @@ * limitations under the License. */ -import { CellEditorComponent } from './cell.editor'; +import { Component, Input } from '@angular/core'; -describe('CellEditorComponent', () => { +@Component({ + moduleId: module.id, + selector: 'diagram-tooltip', + templateUrl: './diagram-tooltip.component.html', + styleUrls: ['./diagram-tooltip-style.css'] +}) +export class DiagramTooltip { - class CustomEditor extends CellEditorComponent { - onError(error: any) { - this.handleError(error); - } + @Input() + data: any; + + getTooltipHeader(data: any) { + let headerValue = data.name || data.id; + return data.type + ' ' + headerValue; } - let component: CustomEditor; - - beforeEach(() => { - component = new CustomEditor(); - }); - - it('should handle error', () => { - const error = 'error'; - spyOn(console, 'error').and.stub(); - - component.onError(error); - expect(console.error).toHaveBeenCalledWith(error); - }); - -}); + getTooltipMessage(data: any) { + return (data.value !== undefined && data.value !== null ) ? data.value + ' ' + data.dataType : ''; + } +} diff --git a/ng2-components/ng2-activiti-diagrams/src/declarations.d.ts b/ng2-components/ng2-activiti-diagrams/src/components/tooltip/index.ts similarity index 93% rename from ng2-components/ng2-activiti-diagrams/src/declarations.d.ts rename to ng2-components/ng2-activiti-diagrams/src/components/tooltip/index.ts index e1b5a9e9fc..969117c620 100644 --- a/ng2-components/ng2-activiti-diagrams/src/declarations.d.ts +++ b/ng2-components/ng2-activiti-diagrams/src/components/tooltip/index.ts @@ -15,5 +15,4 @@ * limitations under the License. */ -// MDL -declare let componentHandler: any; +export * from './diagram-tooltip.component'; diff --git a/ng2-components/ng2-activiti-diagrams/src/models/diagram.model.ts b/ng2-components/ng2-activiti-diagrams/src/models/diagram.model.ts new file mode 100644 index 0000000000..32510ca0db --- /dev/null +++ b/ng2-components/ng2-activiti-diagrams/src/models/diagram.model.ts @@ -0,0 +1,198 @@ +/*! + * @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. + */ + +export class DiagramModel { + diagramBeginX: number; + diagramBeginY: number; + diagramHeight: number; + diagramWidth: number; + elements: DiagramElementModel[] = []; + flows: DiagramFlowElementModel[] = []; + pools: DiagramPoolElementModel[] = []; + + constructor(obj?: any) { + if (obj) { + this.diagramBeginX = obj.diagramBeginX; + this.diagramBeginY = obj.diagramBeginY; + this.diagramHeight = obj.diagramHeight; + this.diagramWidth = obj.diagramWidth; + if (obj.elements) { + obj.elements.forEach((element: DiagramElementModel) => { + this.elements.push(new DiagramElementModel(element)); + }); + } + if (obj.flows) { + obj.flows.forEach((flow: DiagramFlowElementModel) => { + this.flows.push(new DiagramFlowElementModel(flow)); + }); + } + if (obj.pools) { + obj.pools.forEach((pool: DiagramPoolElementModel) => { + this.pools.push(new DiagramPoolElementModel(pool)); + }); + } + } + } +} + +export class DiagramElementModel { + height: string; + id: string; + name: string; + type: string; + width: string; + value: string; + x: string; + y: string; + properties: DiagramElementPropertyModel[] = []; + dataType: string = ''; + eventDefinition: DiagramEventDefinitionModel; + taskType: string = ''; + + constructor(obj?: any) { + if (obj) { + this.height = obj.height || ''; + this.id = obj.id || ''; + this.name = obj.name || ''; + this.type = obj.type || ''; + this.width = obj.width || ''; + this.value = obj.value || ''; + this.x = obj.x || ''; + this.y = obj.y || ''; + this.taskType = obj.taskType || ''; + if (obj.properties) { + obj.properties.forEach((property: DiagramElementPropertyModel) => { + this.properties.push(new DiagramElementPropertyModel(property)); + }); + } + this.dataType = obj.dataType || ''; + if (obj.eventDefinition) { + this.eventDefinition = new DiagramEventDefinitionModel(obj.eventDefinition); + } + } + } +} + +export class DiagramElementPropertyModel { + name: string; + type: string; + value: any; + + constructor(obj?: any) { + if (obj) { + this.name = obj.name; + this.type = obj.type; + this.value = obj.value; + } + } +} + +export class DiagramFlowElementModel { + id: string; + properties: any[] = []; + sourceRef: string; + targetRef: string; + type: string; + waypoints: DiagramWayPointModel[] = []; + + constructor(obj?: any) { + if (obj) { + this.id = obj.id; + this.properties = obj.properties; + this.sourceRef = obj.sourceRef; + this.targetRef = obj.targetRef; + this.type = obj.type; + if (obj.waypoints) { + obj.waypoints.forEach((waypoint: DiagramWayPointModel) => { + this.waypoints.push(new DiagramWayPointModel(waypoint)); + }); + } + } + } +} + +export class DiagramWayPointModel { + x: number; + y: number; + + constructor(obj?: any) { + if (obj) { + this.x = obj.x; + this.y = obj.y; + } + } +} + +export class DiagramEventDefinitionModel { + timeCycle: string; + type: string; + + constructor(obj?: any) { + if (obj) { + this.timeCycle = obj.timeCycle; + this.type = obj.type; + } + } +} + +export class DiagramPoolElementModel { + height: string; + id: string; + name: string; + properties: any; + lanes: DiagramLaneElementModel[] = []; + width: string; + x: number; + y: number; + + constructor(obj?: any) { + if (obj) { + this.height = obj.height; + this.id = obj.id; + this.name = obj.name; + this.properties = obj.properties; + this.width = obj.width; + this.x = obj.x; + this.y = obj.y; + if (obj.lanes) { + obj.lanes.forEach((lane: DiagramLaneElementModel) => { + this.lanes.push(new DiagramLaneElementModel(lane)); + }); + } + } + } +} + +export class DiagramLaneElementModel { + height: number; + id: string; + name: string; + width: number; + x: number; + y: number; + + constructor(obj?: any) { + if (obj) { + this.height = obj.height; + this.id = obj.id; + this.name = obj.name; + this.width = obj.width; + this.x = obj.x; + this.y = obj.y; + } + } +} diff --git a/ng2-components/ng2-activiti-diagrams/tsconfig.json b/ng2-components/ng2-activiti-diagrams/tsconfig.json index 7be35bfec8..276e808597 100644 --- a/ng2-components/ng2-activiti-diagrams/tsconfig.json +++ b/ng2-components/ng2-activiti-diagrams/tsconfig.json @@ -3,11 +3,10 @@ "target": "es5", "module": "commonjs", "moduleResolution": "node", + "sourceMap": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, - "sourceMap": true, - "removeComments": true, - "declaration": true, + "skipLibCheck": true, "noLib": false, "allowUnreachableCode": false, "allowUnusedLabels": false, @@ -15,12 +14,24 @@ "noImplicitReturns": false, "noImplicitUseStrict": false, "noFallthroughCasesInSwitch": true, - "outDir": "dist", - "types": ["core-js", "jasmine", "node"] + "removeComments": true, + "declaration": true, + "lib": [ + "es2015", + "dom" + ], + "suppressImplicitAnyIndexErrors": true }, "exclude": [ "demo", "node_modules", - "dist" - ] + "dist", + "tools", + "gulpfile.ts", + "gulpfile.d.ts" + ], + "angularCompilerOptions": { + "strictMetadataEmit": false, + "skipTemplateCodegen": true + } } diff --git a/ng2-components/ng2-activiti-diagrams/tslint.json b/ng2-components/ng2-activiti-diagrams/tslint.json index 27e0dd81da..acc666937e 100644 --- a/ng2-components/ng2-activiti-diagrams/tslint.json +++ b/ng2-components/ng2-activiti-diagrams/tslint.json @@ -53,7 +53,7 @@ "no-eval": true, "no-inferrable-types": false, "no-internal-module": true, - "no-require-imports": true, + "no-require-imports": false, "no-shadowed-variable": true, "no-switch-case-fall-through": true, "no-trailing-whitespace": true, diff --git a/ng2-components/ng2-activiti-form/.gitignore b/ng2-components/ng2-activiti-form/.gitignore index 787032431d..fb23a7fef5 100644 --- a/ng2-components/ng2-activiti-form/.gitignore +++ b/ng2-components/ng2-activiti-form/.gitignore @@ -1,11 +1,19 @@ npm-debug.log -node_modules/ -.idea/ +node_modules +.idea typings -coverage/ -dist/ +coverage +dist src/**/*.js src/**/*.js.map +src/**/*.d.ts +demo/**/*.js +demo/**/*.js.map +demo/**/*.d.ts index.js index.js.map !systemjs.config.js +*.tgz +/package/ +/bundles/ +index.d.ts diff --git a/ng2-components/ng2-activiti-form/.npmignore b/ng2-components/ng2-activiti-form/.npmignore index c5ca623298..8bb008aff4 100644 --- a/ng2-components/ng2-activiti-form/.npmignore +++ b/ng2-components/ng2-activiti-form/.npmignore @@ -2,14 +2,15 @@ npm-debug.log .idea coverage/ +demo/ node_modules typings/ fonts/ /.editorconfig /.travis.yml -/*.js /*.json -/*.ts -/*.js.map +/karma-test-shim.js +/karma.conf.js +/gulpfile.ts /.npmignore diff --git a/ng2-components/ng2-activiti-form/demo/.editorconfig b/ng2-components/ng2-activiti-form/demo/.editorconfig new file mode 100644 index 0000000000..75a2477db7 --- /dev/null +++ b/ng2-components/ng2-activiti-form/demo/.editorconfig @@ -0,0 +1,23 @@ +# http://editorconfig.org + +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 4 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[package.json] +indent_style = space +indent_size = 2 + +[karma.conf.js] +indent_style = space +indent_size = 2 + +[*.md] +insert_final_newline = false +trim_trailing_whitespace = false diff --git a/ng2-components/ng2-activiti-form/demo/package.json b/ng2-components/ng2-activiti-form/demo/package.json index 3479ffed3e..c907bf29b1 100644 --- a/ng2-components/ng2-activiti-form/demo/package.json +++ b/ng2-components/ng2-activiti-form/demo/package.json @@ -5,15 +5,16 @@ "author": "Alfresco Software, Ltd.", "main": "index.js", "scripts": { - "clean": "npm install rimraf && rimraf dist node_modules typings dist", + "clean": "npm install rimraf && npm run clean-build && rimraf dist node_modules typings dist", + "clean-build" : "rimraf 'src/{,**/}**.js' 'src/{,**/}**.js.map' 'src/{,**/}**.d.ts'", "postinstall": "npm run build", "start": "npm run build && concurrently \"npm run tsc:w\" \"npm run server\" ", "server": "wsrv -o -s -l", - "build": "npm run tslint && rimraf dist && tsc", - "build:w": "npm run tslint && rimraf dist && tsc -w", + "build": "npm run tslint && npm run clean-build && npm run tsc", + "build:w": "npm run tslint && rimraf dist && npm run tsc:w", "tsc": "tsc", "tsc:w": "tsc -w", - "tslint": "tslint -c tslint.json *.ts && tslint -c tslint.json src/{,**/}**.ts" + "tslint": "tslint -c tslint.json *.ts && tslint -c tslint.json src/{,**/}**.ts -e '{,**/}**.d.ts'" }, "license": "Apache-2.0", "contributors": [ @@ -30,37 +31,36 @@ "activiti-form" ], "dependencies": { - "@angular/common": "2.0.0", - "@angular/compiler": "2.0.0", - "@angular/core": "2.0.0", - "@angular/forms": "2.0.0", - "@angular/http": "2.0.0", - "@angular/platform-browser": "2.0.0", - "@angular/platform-browser-dynamic": "2.0.0", + "@angular/common": "2.2.2", + "@angular/compiler": "2.2.2", + "@angular/compiler-cli": "2.2.2", + "@angular/core": "2.2.2", + "@angular/forms": "2.2.2", + "@angular/http": "2.2.2", + "@angular/platform-browser": "2.2.2", + "@angular/platform-browser-dynamic": "2.2.2", + "@angular/router": "3.2.2", + "@angular/upgrade": "2.2.2", "core-js": "^2.4.1", "reflect-metadata": "^0.1.3", "rxjs": "5.0.0-beta.12", "systemjs": "0.19.27", "zone.js": "^0.6.23", - "intl": "1.2.4", "dialog-polyfill": "^0.4.3", "element.scrollintoviewifneeded-polyfill": "^1.0.1", "material-design-icons": "2.2.3", "material-design-lite": "1.2.1", - "moment": "2.15.1", "md-date-time-picker": "^2.2.0", - "ng2-translate": "2.5.0", - "alfresco-js-api": "^0.5.0", - "ng2-alfresco-core": "0.5.0", - "ng2-activiti-form": "^0.5.0" + "alfresco-js-api": "^1.0.0", + "ng2-alfresco-core": "1.0.0", + "ng2-activiti-form": "^1.0.0" }, "devDependencies": { - "@types/node": "^6.0.42", - "@types/core-js": "^0.9.32", "@types/jasmine": "^2.2.33", + "@types/node": "^6.0.42", "concurrently": "^2.2.0", "rimraf": "2.5.2", "tslint": "^3.8.1", diff --git a/ng2-components/ng2-activiti-form/demo/src/main.ts b/ng2-components/ng2-activiti-form/demo/src/main.ts index ea35ad17b1..c933643a38 100644 --- a/ng2-components/ng2-activiti-form/demo/src/main.ts +++ b/ng2-components/ng2-activiti-form/demo/src/main.ts @@ -18,7 +18,7 @@ import { NgModule, Component, OnInit } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; -import { CoreModule, AlfrescoSettingsService, AlfrescoAuthenticationService } from 'ng2-alfresco-core'; +import { CoreModule, AlfrescoSettingsService, AlfrescoAuthenticationService, StorageService } from 'ng2-alfresco-core'; import { ActivitiFormModule } from 'ng2-activiti-form'; @Component({ @@ -49,7 +49,9 @@ export class FormDemoComponent implements OnInit { ticket: string; - constructor(private authService: AlfrescoAuthenticationService, private settingsService: AlfrescoSettingsService) { + constructor(private authService: AlfrescoAuthenticationService, + private settingsService: AlfrescoSettingsService, + private storage: StorageService) { settingsService.bpmHost = this.host; settingsService.setProviders('BPM'); @@ -59,7 +61,7 @@ export class FormDemoComponent implements OnInit { } public updateTicket(): void { - localStorage.setItem('ticket-BPM', this.ticket); + this.storage.setItem('ticket-BPM', this.ticket); } public updateHost(): void { diff --git a/ng2-components/ng2-activiti-form/demo/systemjs.config.js b/ng2-components/ng2-activiti-form/demo/systemjs.config.js index 3860ed6679..e5748f461d 100644 --- a/ng2-components/ng2-activiti-form/demo/systemjs.config.js +++ b/ng2-components/ng2-activiti-form/demo/systemjs.config.js @@ -11,7 +11,7 @@ // map tells the System loader where to look for things map: { // our app is within the app folder - app: 'dist', + app: 'src', // angular bundles '@angular/core': 'npm:@angular/core/bundles/core.umd.js', '@angular/common': 'npm:@angular/common/bundles/common.umd.js', @@ -26,8 +26,8 @@ 'moment': 'npm:moment/min/moment.min.js', 'ng2-translate': 'npm:ng2-translate', 'alfresco-js-api': 'npm:alfresco-js-api/dist', - 'ng2-alfresco-core': 'npm:ng2-alfresco-core/dist', - 'ng2-activiti-form': 'npm:ng2-activiti-form/dist' + 'ng2-alfresco-core': 'npm:ng2-alfresco-core', + 'ng2-activiti-form': 'npm:ng2-activiti-form' }, // packages tells the System loader how to load when no filename and/or no extension packages: { @@ -38,6 +38,7 @@ rxjs: { defaultExtension: 'js' }, + 'moment': { defaultExtension: 'js' }, 'ng2-translate': { defaultExtension: 'js' }, 'ng2-charts': { main: 'ng2-charts.js', defaultExtension: 'js'}, 'alfresco-js-api': { main: './alfresco-js-api.js', defaultExtension: 'js'}, diff --git a/ng2-components/ng2-activiti-form/demo/tsconfig.json b/ng2-components/ng2-activiti-form/demo/tsconfig.json index 7be35bfec8..524fcfda8e 100644 --- a/ng2-components/ng2-activiti-form/demo/tsconfig.json +++ b/ng2-components/ng2-activiti-form/demo/tsconfig.json @@ -3,11 +3,10 @@ "target": "es5", "module": "commonjs", "moduleResolution": "node", + "sourceMap": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, - "sourceMap": true, - "removeComments": true, - "declaration": true, + "skipLibCheck": true, "noLib": false, "allowUnreachableCode": false, "allowUnusedLabels": false, @@ -15,12 +14,19 @@ "noImplicitReturns": false, "noImplicitUseStrict": false, "noFallthroughCasesInSwitch": true, - "outDir": "dist", - "types": ["core-js", "jasmine", "node"] + "removeComments": true, + "declaration": true, + "lib": [ + "es2015", + "dom" + ], + "suppressImplicitAnyIndexErrors": true }, "exclude": [ - "demo", - "node_modules", - "dist" - ] + "node_modules" + ], + "angularCompilerOptions": { + "strictMetadataEmit": false, + "skipTemplateCodegen": true + } } diff --git a/ng2-components/ng2-activiti-form/gulpfile.ts b/ng2-components/ng2-activiti-form/gulpfile.ts new file mode 100755 index 0000000000..ac6b7cc738 --- /dev/null +++ b/ng2-components/ng2-activiti-form/gulpfile.ts @@ -0,0 +1,311 @@ +import * as gulp from 'gulp'; +import * as util from 'gulp-util'; +import * as runSequence from 'run-sequence'; +import * as gulpLoadPlugins from 'gulp-load-plugins'; +import * as merge from 'merge-stream'; +import * as rimraf from 'rimraf'; +import { join } from 'path'; +import * as Builder from 'systemjs-builder'; +var autoprefixer = require('autoprefixer'); +import * as cssnano from 'cssnano'; +import * as filter from 'gulp-filter'; +import * as sourcemaps from 'gulp-sourcemaps'; + +var APP_SRC = `.`; +var CSS_PROD_BUNDLE = 'main.css'; +var JS_PROD_SHIMS_BUNDLE = 'shims.js'; +var NG_FACTORY_FILE = 'main-prod'; + +const BUILD_TYPES = { + DEVELOPMENT: 'dev', + PRODUCTION: 'prod' +}; + +function normalizeDependencies(deps) { + deps + .filter((d) => !/\*/.test(d.src)) // Skip globs + .forEach((d) => d.src = require.resolve(d.src)); + return deps; +} + +function filterDependency(type: string, d): boolean { + const t = d.buildType || d.env; + d.buildType = t; + if (!t) { + d.buildType = Object.keys(BUILD_TYPES).map(k => BUILD_TYPES[k]); + } + if (!(d.buildType instanceof Array)) { + (d).env = [d.buildType]; + } + return d.buildType.indexOf(type) >= 0; +} + +function getInjectableDependency() { + var APP_ASSETS = [ + {src: `src/css/main.css`, inject: true, vendor: false}, + ]; + + var NPM_DEPENDENCIES = [ + {src: 'zone.js/dist/zone.js', inject: 'libs'}, + {src: 'core-js/client/shim.min.js', inject: 'shims'}, + {src: 'intl/dist/Intl.min.js', inject: 'shims'}, + {src: 'systemjs/dist/system.src.js', inject: 'shims', buildType:'dev'} + ]; + + return normalizeDependencies(NPM_DEPENDENCIES.filter(filterDependency.bind(null, 'dev'))) + .concat(APP_ASSETS.filter(filterDependency.bind(null, 'dev'))); +} + +const plugins = gulpLoadPlugins(); + +let tsProjects: any = {}; + +function makeTsProject(options: Object = {}) { + let optionsHash = JSON.stringify(options); + if (!tsProjects[optionsHash]) { + let config = Object.assign({ + typescript: require('typescript') + }, options); + tsProjects[optionsHash] = + plugins.typescript.createProject('tsconfig.json', config); + } + return tsProjects[optionsHash]; +} + +gulp.task('build.html_css', () => { + const gulpConcatCssConfig = { + targetFile: CSS_PROD_BUNDLE, + options: { + rebaseUrls: false + } + }; + + const processors = [ + autoprefixer({ + browsers: [ + 'ie >= 10', + 'ie_mob >= 10', + 'ff >= 30', + 'chrome >= 34', + 'safari >= 7', + 'opera >= 23', + 'ios >= 7', + 'android >= 4.4', + 'bb >= 10' + ] + }) + ]; + + const reportPostCssError = (e: any) => util.log(util.colors.red(e.message)); + + processors.push( + cssnano({ + discardComments: {removeAll: true}, + discardUnused: false, // unsafe, see http://goo.gl/RtrzwF + zindex: false, // unsafe, see http://goo.gl/vZ4gbQ + reduceIdents: false // unsafe, see http://goo.gl/tNOPv0 + }) + ); + + /** + * Processes the CSS files within `src/client` excluding those in `src/client/assets` using `postcss` with the + * configured processors + * Execute the appropriate component-stylesheet processing method based on user stylesheet preference. + */ + function processComponentStylesheets() { + return gulp.src(join('src/**', '*.css')) + .pipe(plugins.cached('process-component-css')) + .pipe(plugins.postcss(processors)) + .on('error', reportPostCssError); + } + + + /** + * Get a stream of external css files for subsequent processing. + */ + function getExternalCssStream() { + return gulp.src(getExternalCss()) + .pipe(plugins.cached('process-external-css')); + } + + /** + * Get an array of filenames referring to all external css stylesheets. + */ + function getExternalCss() { + return getInjectableDependency().filter(dep => /\.css$/.test(dep.src)).map(dep => dep.src); + } + + /** + * Processes the external CSS files using `postcss` with the configured processors. + */ + function processExternalCss() { + return getExternalCssStream() + .pipe(plugins.postcss(processors)) + .pipe(plugins.concatCss(gulpConcatCssConfig.targetFile, gulpConcatCssConfig.options)) + .on('error', reportPostCssError); + } + + return merge(processComponentStylesheets(), processExternalCss()); + +}); + +gulp.task('build.bundles.app', (done) => { + var BUNDLER_OPTIONS = { + format: 'umd', + minify: false, + mangle: false, + sourceMaps: true + }; + var CONFIG_TYPESCRIPT = { + baseURL: '.', + transpiler: 'typescript', + typescriptOptions: { + module: 'cjs' + }, + map: { + typescript: 'node_modules/typescript/lib/typescript.js', + '@angular': 'node_modules/@angular', + rxjs: 'node_modules/rxjs', + 'ng2-translate': 'node_modules/ng2-translate', + 'alfresco-js-api': 'node_modules/alfresco-js-api/dist/alfresco-js-api', + 'ng2-alfresco-core': 'node_modules/ng2-alfresco-core/', + 'ng2-activiti-diagrams': 'node_modules/ng2-activiti-diagrams/', + 'ng2-activiti-analytics': 'node_modules/ng2-activiti-analytics/', + 'ng2-alfresco-datatable': 'node_modules/ng2-alfresco-datatable/', + 'ng2-alfresco-documentlist': 'node_modules/ng2-alfresco-documentlist/', + 'ng2-activiti-form': 'node_modules/ng2-activiti-form/', + 'ng2-alfresco-login': 'node_modules/ng2-alfresco-login/', + 'ng2-activiti-processlist': 'node_modules/ng2-activiti-processlist/', + 'ng2-alfresco-search': 'node_modules/ng2-alfresco-search/', + 'ng2-activiti-tasklist': 'node_modules/ng2-activiti-tasklist/', + 'ng2-alfresco-tag': 'node_modules/ng2-alfresco-tag/', + 'ng2-alfresco-upload': 'node_modules/ng2-alfresco-upload/', + 'ng2-alfresco-userinfo': 'node_modules/ng2-alfresco-userinfo/', + 'ng2-alfresco-viewer': 'node_modules/ng2-alfresco-viewer/', + 'ng2-alfresco-webscript': 'node_modules/ng2-alfresco-webscript/', + 'moment':'node_modules/moment/min/moment.min' + //'node_modules/md-date-time-picker/dist/js/mdDateTimePicker.min.js', + //'node_modules/md-date-time-picker/dist/js/draggabilly.pkgd.min.js' + }, + paths: { + '*': '*.js' + }, + meta: { + 'node_modules/@angular/*': {build: false}, + 'node_modules/rxjs/*': {build: false}, + 'node_modules/ng2-translate/*': {build: false}, + 'node_modules/ng2-alfresco-core/*': {build: false}, + 'node_modules/ng2-activiti-diagrams/*': {build: false}, + 'node_modules/ng2-activiti-analytics/*': {build: false}, + 'node_modules/ng2-alfresco-datatable/*': {build: false}, + 'node_modules/ng2-alfresco-documentlist/*': {build: false}, + 'node_modules/ng2-activiti-form/*': {build: false}, + 'node_modules/ng2-alfresco-login/*': {build: false}, + 'node_modules/ng2-activiti-processlist/*': {build: false}, + 'node_modules/ng2-alfresco-search/*': {build: false}, + 'node_modules/ng2-activiti-tasklist/*': {build: false}, + 'node_modules/ng2-alfresco-tag/*': {build: false}, + 'node_modules/ng2-alfresco-upload/*': {build: false}, + 'node_modules/ng2-alfresco-userinfo/*': {build: false}, + 'node_modules/ng2-alfresco-viewer/*': {build: false}, + 'node_modules/ng2-alfresco-webscript/*': {build: false} + } + }; + + var pkg = require('./package.json'); + var namePkg = pkg.name; + + var builder = new Builder(CONFIG_TYPESCRIPT); + builder + .buildStatic(APP_SRC + "/index", 'bundles/' + namePkg + '.js', BUNDLER_OPTIONS) + .then(function () { + return done(); + }) + .catch(function (err) { + return done(err); + }); +}); + +gulp.task('build.assets.prod', () => { + return gulp.src([ + join('src/**', '*.ts'), + 'index.ts', + join('src/**', '*.css'), + join('src/**', '*.html'), + '!'+join('*/**', '*.d.ts'), + '!'+join('*/**', '*.spec.ts'), + '!gulpfile.ts']) + +}); + +gulp.task('build.bundles', () => { + merge(bundleShims()); + + /** + * Returns the shim files to be injected. + */ + function getShims() { + let libs = getInjectableDependency() + .filter(d => /\.js$/.test(d.src)); + + return libs.filter(l => l.inject === 'shims') + .concat(libs.filter(l => l.inject === 'libs')) + .concat(libs.filter(l => l.inject === true)) + .map(l => l.src); + } + + /** + * Bundles the shim files. + */ + function bundleShims() { + return gulp.src(getShims()) + .pipe(plugins.concat(JS_PROD_SHIMS_BUNDLE)) + // Strip the first (global) 'use strict' added by reflect-metadata, but don't strip any others to avoid unintended scope leaks. + .pipe(plugins.replace(/('|")use strict\1;var Reflect;/, 'var Reflect;')) + .pipe(gulp.dest('bundles')); + } + +}); + +gulp.task('build.js.prod', () => { + const INLINE_OPTIONS = { + base: APP_SRC, + target: 'es5', + useRelativePaths: true, + removeLineBreaks: true + }; + + let tsProject = makeTsProject(); + let src = [ + join('src/**/*.ts'), + join('!src/**/*.d.ts'), + join('!src/**/*.spec.ts'), + `!src/**/${NG_FACTORY_FILE}.ts` + ]; + + let result = gulp.src(src) + .pipe(plugins.plumber()) + .pipe(plugins.inlineNg2Template(INLINE_OPTIONS)) + .pipe(sourcemaps.init()) + .pipe(tsProject()) + .once('error', function (e: any) { + this.once('finish', () => process.exit(1)); + }); + + return result.js + .pipe(plugins.template()) + .pipe(sourcemaps.write()) + .pipe(gulp.dest('src')) + .on('error', (e: any) => { + console.log(e); + }); +}); + +gulp.task('build.prod', (done: any) => + runSequence( + 'build.assets.prod', + 'build.html_css', + 'build.js.prod', + 'build.bundles', + 'build.bundles.app', + done)); diff --git a/ng2-components/ng2-activiti-form/index.ts b/ng2-components/ng2-activiti-form/index.ts index 9c8ecde6b8..98e9d2970c 100644 --- a/ng2-components/ng2-activiti-form/index.ts +++ b/ng2-components/ng2-activiti-form/index.ts @@ -34,8 +34,8 @@ export * from './src/components/activiti-form.component'; export * from './src/components/activiti-start-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 * from './src/services/ecm-model.service'; +export * from './src/services/node.service'; export * from './src/services/form-rendering.service'; export const ACTIVITI_FORM_DIRECTIVES: any[] = [ diff --git a/ng2-components/ng2-activiti-form/karma-test-shim.js b/ng2-components/ng2-activiti-form/karma-test-shim.js index a58f01a39b..a02d98e315 100644 --- a/ng2-components/ng2-activiti-form/karma-test-shim.js +++ b/ng2-components/ng2-activiti-form/karma-test-shim.js @@ -5,7 +5,7 @@ jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; __karma__.loaded = function() {}; -var builtPath = '/base/dist/'; +var builtPath = '/base/src/'; function isJsFile(path) { return path.slice(-3) == '.js'; @@ -29,7 +29,7 @@ var paths = { }; var map = { - 'app': 'base/dist', + 'app': 'base/src', // angular bundles '@angular/core': 'npm:@angular/core/bundles/core.umd.js', '@angular/common': 'npm:@angular/common/bundles/common.umd.js', @@ -52,15 +52,19 @@ var map = { // other libraries 'rxjs': 'npm:rxjs', 'ng2-translate': 'npm:ng2-translate', + 'md-date-time-picker' : 'npm:md-date-time-picker', + 'moment' : 'npm:moment/min/moment.min.js', 'alfresco-js-api': 'npm:alfresco-js-api/dist', - 'ng2-alfresco-core': 'npm:ng2-alfresco-core/dist' + 'ng2-alfresco-core': 'npm:ng2-alfresco-core' }; var packages = { 'app': { main: 'main.js', defaultExtension: 'js' }, 'rxjs': { defaultExtension: 'js' }, 'ng2-translate': { defaultExtension: 'js' }, + 'md-date-time-picker': { defaultExtension: 'js' }, + 'moment': { defaultExtension: 'js' }, 'alfresco-js-api': { main: './alfresco-js-api.js', defaultExtension: 'js'}, 'ng2-alfresco-core': { main: './index.js', defaultExtension: 'js'} diff --git a/ng2-components/ng2-activiti-form/karma.conf.js b/ng2-components/ng2-activiti-form/karma.conf.js index 1b8835cd42..b69537e247 100644 --- a/ng2-components/ng2-activiti-form/karma.conf.js +++ b/ng2-components/ng2-activiti-form/karma.conf.js @@ -34,24 +34,29 @@ module.exports = function (config) { 'node_modules/alfresco-js-api/dist/alfresco-js-api.js', 'node_modules/moment/min/moment.min.js', - 'node_modules/md-date-time-picker/dist/js/mdDateTimePicker.min.js', - 'node_modules/md-date-time-picker/dist/js/draggabilly.pkgd.min.js', + 'node_modules/md-date-time-picker/dist/js/mdDateTimePicker.js', + {pattern: 'node_modules/ng2-translate/**/*.js', included: false, watched: false}, - {pattern: 'node_modules/ng2-translate/**/*.js.map', included: false, watched: false}, 'karma-test-shim.js', // paths loaded via module imports - {pattern: 'dist/**/*.js', included: false, watched: true}, - {pattern: 'dist/**/*.html', included: true, served: true, watched: true}, - {pattern: 'dist/**/*.css', included: true, served: true, watched: true}, // ng2-components - { pattern: 'node_modules/ng2-alfresco-core/dist/**/*.js', included: false, served: true, watched: false }, + { pattern: 'node_modules/ng2-alfresco-core/src/**/*.js', included: false, served: true, watched: false }, + { pattern: 'node_modules/ng2-alfresco-core/src/**/*.js.map', included: false, served: true, watched: false }, + { pattern: 'node_modules/ng2-alfresco-core/index.js', included: false, served: true, watched: false }, // paths to support debugging with source maps in dev tools + + {pattern: './index.ts', included: false, watched: true}, + {pattern: './index.js', included: false, watched: true}, {pattern: 'src/**/*.ts', included: false, watched: false}, - {pattern: 'dist/**/*.js.map', included: false, watched: false} + {pattern: 'src/**/*.js', included: false, watched: true}, + {pattern: 'src/**/*.js.map', included: false, watched: false}, + {pattern: 'src/**/*.html', included: true, served: true, watched: true}, + {pattern: 'src/**/*.css', included: true, served: true, watched: true} + ], exclude: [ @@ -99,7 +104,7 @@ module.exports = function (config) { // Source files that you wanna generate coverage for. // Do not include tests or libraries (these files will be instrumented by Istanbul) preprocessors: { - 'dist/**/!(*spec|index|*mock|*model).js': 'coverage' + 'src/**/!(*spec|index|*mock|*model).js': 'coverage' }, coverageReporter: { diff --git a/ng2-components/ng2-activiti-form/package.json b/ng2-components/ng2-activiti-form/package.json index 4194e67ce9..214d9d8415 100644 --- a/ng2-components/ng2-activiti-form/package.json +++ b/ng2-components/ng2-activiti-form/package.json @@ -1,28 +1,30 @@ { "name": "ng2-activiti-form", "description": "Alfresco Activiti Form Component for Angular 2", - "version": "0.5.0", + "version": "1.0.0", "author": "Alfresco Software, Ltd.", "scripts": { - "clean": "npm install rimraf && rimraf dist node_modules typings", - "build": "npm run tslint && rimraf dist && tsc && npm run copy-dist && license-check", - "build:w": "npm run tslint && rimraf dist && npm run watch-task", - "watch-task": "concurrently \"npm run tsc:w\" \"npm run copy-dist:w\" \"license-check\"", - "tslint": "tslint -c tslint.json *.ts && tslint -c tslint.json 'src/{,**/}**.ts'", - "copy-dist": "cpx \"./src/**/*.{html,css,json,png,jpg,gif,svg}\" ./dist/src", - "copy-dist:w": "cpx \"./src/**/*.{html,css,json,png,jpg,gif,svg}\" ./dist/src -w", + "clean": "npm install rimraf && npm run clean-build && rimraf dist node_modules typings", + "clean-build": "rimraf index.js index.js.map index.d.ts'src/{,**/}**.js' 'src/{,**/}**.js.map' 'src/{,**/}**.d.ts' bundles", + "build": "npm run clean-build && npm run tslint && rimraf dist && tsc && license-check && npm run build.umd", + "build:w": "npm run clean-build && npm run tslint && rimraf dist && tsc:w && license-check npm run build.umd", + "tslint": "tslint -c tslint.json 'src/{,**/}**.ts' 'index.ts' -e '{,**/}**.d.ts' -e './gulpfile.ts'", "tsc": "tsc", "tsc:w": "tsc -w", "pretest": "npm run build", "test": "karma start karma.conf.js --reporters mocha,coverage --single-run", - "test-browser": "concurrently \"karma start karma.conf.js --reporters kjhtml\" \"npm run watch-task\"", + "test-browser": "npm run build && concurrently \"karma start karma.conf.js --reporters kjhtml\" \"npm run watch-task\"", "posttest": "remap-istanbul -i coverage/report/coverage-final.json -o coverage/report -t html && remap-istanbul -i coverage/report/coverage-final.json -o coverage/report/coverage-final.json", "coverage": "npm run test && wsrv -o -p 9875 ./coverage/report", "prepublish": "npm run build", - "travis": "npm link ng2-alfresco-core" + "travis": "npm link ng2-alfresco-core", + "gulp": "gulp", + "build.umd": "gulp build.prod --color --env-config prod --build-type prod", + "reinstall": "npm cache clean && npm install" }, - "main": "./dist/index.js", - "typings": "./dist/index.d.ts", + "main": "./index.js", + "module": "./index.js", + "typings": "./index.d.ts", "repository": { "type": "git", "url": "https://github.com/Alfresco/alfresco-ng2-components.git" @@ -30,7 +32,6 @@ "bugs": { "url": "https://github.com/Alfresco/alfresco-ng2-components/issues" }, - "license": "Apache-2.0", "contributors": [ { "name": "Denys Vuika", @@ -45,6 +46,7 @@ "activiti" ], "dependencies": { + "@angular/router": "3.0.0", "@angular/common": "2.0.0", "@angular/compiler": "2.0.0", "@angular/core": "2.0.0", @@ -57,43 +59,63 @@ "rxjs": "5.0.0-beta.12", "systemjs": "0.19.27", "zone.js": "^0.6.23", - "moment": "2.15.1", "md-date-time-picker": "^2.2.0", - "ng2-translate": "2.5.0", - "alfresco-js-api": "^0.5.0", - "ng2-alfresco-core": "0.5.0" + "alfresco-js-api": "^1.0.0", + "ng2-alfresco-core": "1.0.0" }, "devDependencies": { - "@types/node": "^6.0.42", - "@types/core-js": "^0.9.32", "@types/jasmine": "^2.2.33", + "@types/node": "^6.0.42", + "autoprefixer": "^6.5.1", "concurrently": "^2.2.0", - "cpx": "1.3.1", + "cpx": "^1.3.1", + "cssnano": "^3.8.1", + "gulp": "^3.9.1", + "gulp-autoprefixer": "^3.1.1", + "gulp-cached": "^1.1.1", + "gulp-concat": "^2.6.1", + "gulp-concat-css": "^2.3.0", + "gulp-filter": "^4.0.0", + "gulp-inline-ng2-template": "^4.0.0", + "gulp-load-plugins": "^1.4.0", + "gulp-plumber": "^1.1.0", + "gulp-postcss": "^6.2.0", + "gulp-replace": "^0.5.4", + "gulp-sourcemaps": "^1.9.1", + "gulp-template": "^4.0.0", + "gulp-typescript": "^3.1.3", + "gulp-uglify": "^2.0.0", + "intl": "^1.2.5", + "jasmine-ajax": "^3.2.0", "jasmine-core": "2.4.1", - "karma": "0.13.22", - "karma-chrome-launcher": "1.0.1", - "karma-coverage": "1.0.0", - "karma-jasmine": "1.0.2", - "karma-jasmine-ajax": "0.1.13", - "karma-jasmine-html-reporter": "0.2.0", - "karma-mocha-reporter": "2.0.3", - "license-check": "1.1.5", - "remap-istanbul": "0.6.3", + "karma": "~0.13.22", + "karma-chrome-launcher": "~1.0.1", + "karma-coverage": "^1.0.0", + "karma-jasmine": "~1.0.2", + "karma-jasmine-ajax": "^0.1.13", + "karma-jasmine-html-reporter": "^0.2.0", + "karma-mocha-reporter": "^2.0.3", + "license-check": "^1.0.4", + "remap-istanbul": "^0.6.3", "rimraf": "2.5.2", - "traceur": "0.0.91", - "tslint": "3.15.1", + "run-sequence": "^1.2.2", + "systemjs-builder": "^0.15.34", + "traceur": "^0.0.91", + "ts-node": "^1.7.0", + "tslint": "^3.8.1", "typescript": "^2.0.3", "wsrv": "^0.1.5" }, "license-check-config": { "src": [ - "./dist/**/*.js" + "./src/**/*.js" ], "path": "assets/license_header.txt", "blocking": true, "logInfo": false, "logError": true - } + }, + "license": "Apache-2.0" } 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 14ee3e96aa..3e6eca3be6 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 @@ -28,20 +28,19 @@ describe('ActivitiForm', () => { let componentHandler: any; let formService: FormService; let formComponent: ActivitiForm; - let visibilityService: WidgetVisibilityService; + let visibilityService: WidgetVisibilityService; let nodeService: NodeService; beforeEach(() => { componentHandler = jasmine.createSpyObj('componentHandler', [ 'upgradeAllRegistered' ]); - visibilityService = jasmine.createSpyObj('WidgetVisibilityService', [ - 'refreshVisibility', 'getTaskProcessVariable' - ]); window['componentHandler'] = componentHandler; + visibilityService = new WidgetVisibilityService(null); + spyOn(visibilityService, 'refreshVisibility').and.stub(); formService = new FormService(null, null); - nodeService = new NodeService(null); + nodeService = new NodeService(null, null); formComponent = new ActivitiForm(formService, visibilityService, null, nodeService); }); @@ -104,13 +103,13 @@ describe('ActivitiForm', () => { it('should enable custom outcome buttons', () => { let formModel = new FormModel(); - let outcome = new FormOutcomeModel(formModel, { id: 'action1', name: 'Action 1' }); + let outcome = new FormOutcomeModel(formModel, {id: 'action1', name: 'Action 1'}); expect(formComponent.isOutcomeButtonVisible(outcome)).toBeTruthy(); }); it('should allow controlling [complete] button visibility', () => { let formModel = new FormModel(); - let outcome = new FormOutcomeModel(formModel, { id: '$save', name: FormOutcomeModel.SAVE_ACTION }); + let outcome = new FormOutcomeModel(formModel, {id: '$save', name: FormOutcomeModel.SAVE_ACTION}); formComponent.showSaveButton = true; expect(formComponent.isOutcomeButtonVisible(outcome)).toBeTruthy(); @@ -121,7 +120,7 @@ describe('ActivitiForm', () => { it('should allow controlling [save] button visibility', () => { let formModel = new FormModel(); - let outcome = new FormOutcomeModel(formModel, { id: '$save', name: FormOutcomeModel.COMPLETE_ACTION }); + let outcome = new FormOutcomeModel(formModel, {id: '$save', name: FormOutcomeModel.COMPLETE_ACTION}); formComponent.showCompleteButton = true; expect(formComponent.isOutcomeButtonVisible(outcome)).toBeTruthy(); @@ -139,12 +138,58 @@ describe('ActivitiForm', () => { it('should get form by task id on load', () => { spyOn(formComponent, 'getFormByTaskId').and.stub(); + const taskId = '123'; formComponent.taskId = taskId; formComponent.loadForm(); expect(formComponent.getFormByTaskId).toHaveBeenCalledWith(taskId); + }); + + it('should get process variable if is a process task', () => { + spyOn(formService, 'getTaskForm').and.callFake((taskId) => { + return Observable.create(observer => { + observer.next({taskId: taskId}); + observer.complete(); + }); + }); + + spyOn(visibilityService, 'getTaskProcessVariable').and.returnValue(Observable.of({})); + spyOn(formService, 'getTask').and.callFake((taskId) => { + return Observable.create(observer => { + observer.next({taskId: taskId, processDefinitionId: '10201'}); + observer.complete(); + }); + }); + const taskId = '123'; + + formComponent.taskId = taskId; + formComponent.loadForm(); + + expect(visibilityService.getTaskProcessVariable).toHaveBeenCalledWith(taskId); + }); + + it('should not get process variable if is not a process task', () => { + spyOn(formService, 'getTaskForm').and.callFake((taskId) => { + return Observable.create(observer => { + observer.next({taskId: taskId}); + observer.complete(); + }); + }); + + spyOn(visibilityService, 'getTaskProcessVariable').and.returnValue(Observable.of({})); + spyOn(formService, 'getTask').and.callFake((taskId) => { + return Observable.create(observer => { + observer.next({taskId: taskId, processDefinitionId: 'null'}); + observer.complete(); + }); + }); + const taskId = '123'; + + formComponent.taskId = taskId; + formComponent.loadForm(); + expect(visibilityService.getTaskProcessVariable).toHaveBeenCalledWith(taskId); }); @@ -173,7 +218,7 @@ describe('ActivitiForm', () => { const taskId = ''; let change = new SimpleChange(null, taskId); - formComponent.ngOnChanges({ 'taskId': change }); + formComponent.ngOnChanges({'taskId': change}); expect(formComponent.getFormByTaskId).toHaveBeenCalledWith(taskId); }); @@ -183,7 +228,7 @@ describe('ActivitiForm', () => { const formId = '123'; let change = new SimpleChange(null, formId); - formComponent.ngOnChanges({ 'formId': change }); + formComponent.ngOnChanges({'formId': change}); expect(formComponent.getFormDefinitionByFormId).toHaveBeenCalledWith(formId); }); @@ -193,7 +238,7 @@ describe('ActivitiForm', () => { const formName = '
'; let change = new SimpleChange(null, formName); - formComponent.ngOnChanges({ 'formName': change }); + formComponent.ngOnChanges({'formName': change}); expect(formComponent.getFormDefinitionByFormName).toHaveBeenCalledWith(formName); }); @@ -218,7 +263,7 @@ describe('ActivitiForm', () => { spyOn(formComponent, 'getFormDefinitionByFormId').and.stub(); spyOn(formComponent, 'getFormDefinitionByFormName').and.stub(); - formComponent.ngOnChanges({ 'tag': new SimpleChange(null, 'hello world')}); + formComponent.ngOnChanges({'tag': new SimpleChange(null, 'hello world')}); expect(formComponent.getFormByTaskId).not.toHaveBeenCalled(); expect(formComponent.getFormDefinitionByFormId).not.toHaveBeenCalled(); @@ -228,7 +273,7 @@ describe('ActivitiForm', () => { it('should complete form on custom outcome click', () => { let formModel = new FormModel(); let outcomeName = 'Custom Action'; - let outcome = new FormOutcomeModel(formModel, { id: 'custom1', name: outcomeName }); + let outcome = new FormOutcomeModel(formModel, {id: 'custom1', name: outcomeName}); let saved = false; formComponent.form = formModel; @@ -293,7 +338,7 @@ describe('ActivitiForm', () => { it('should do nothing when clicking outcome for readonly form', () => { let formModel = new FormModel(); const outcomeName = 'Custom Action'; - let outcome = new FormOutcomeModel(formModel, { id: 'custom1', name: outcomeName }); + let outcome = new FormOutcomeModel(formModel, {id: 'custom1', name: outcomeName}); formComponent.form = formModel; spyOn(formComponent, 'completeTaskForm').and.stub(); @@ -312,7 +357,7 @@ describe('ActivitiForm', () => { it('should require loaded form when clicking outcome', () => { let formModel = new FormModel(); const outcomeName = 'Custom Action'; - let outcome = new FormOutcomeModel(formModel, { id: 'custom1', name: outcomeName }); + let outcome = new FormOutcomeModel(formModel, {id: 'custom1', name: outcomeName}); formComponent.readOnly = false; formComponent.form = null; @@ -321,7 +366,7 @@ describe('ActivitiForm', () => { it('should not execute unknown system outcome', () => { let formModel = new FormModel(); - let outcome = new FormOutcomeModel(formModel, { id: 'unknown', name: 'Unknown', isSystem: true }); + let outcome = new FormOutcomeModel(formModel, {id: 'unknown', name: 'Unknown', isSystem: true}); formComponent.form = formModel; expect(formComponent.onOutcomeClicked(outcome)).toBeFalsy(); @@ -329,20 +374,21 @@ describe('ActivitiForm', () => { it('should require custom action name to complete form', () => { let formModel = new FormModel(); - let outcome = new FormOutcomeModel(formModel, { id: 'custom' }); + let outcome = new FormOutcomeModel(formModel, {id: 'custom'}); formComponent.form = formModel; expect(formComponent.onOutcomeClicked(outcome)).toBeFalsy(); - outcome = new FormOutcomeModel(formModel, { id: 'custom', name: 'Custom' }); + outcome = new FormOutcomeModel(formModel, {id: 'custom', name: 'Custom'}); spyOn(formComponent, 'completeTaskForm').and.stub(); expect(formComponent.onOutcomeClicked(outcome)).toBeTruthy(); }); it('should fetch and parse form by task id', () => { + spyOn(formService, 'getTask').and.returnValue(Observable.of({})); spyOn(formService, 'getTaskForm').and.callFake((taskId) => { return Observable.create(observer => { - observer.next({ taskId: taskId }); + observer.next({taskId: taskId}); observer.complete(); }); }); @@ -363,6 +409,7 @@ describe('ActivitiForm', () => { it('should handle error when getting form by task id', () => { const error = 'Some error'; + spyOn(formService, 'getTask').and.returnValue(Observable.of({})); spyOn(formComponent, 'handleError').and.stub(); spyOn(formService, 'getTaskForm').and.callFake((taskId) => { return Observable.throw(error); @@ -373,9 +420,10 @@ describe('ActivitiForm', () => { }); it('should apply readonly state when getting form by task id', () => { + spyOn(formService, 'getTask').and.returnValue(Observable.of({})); spyOn(formService, 'getTaskForm').and.callFake((taskId) => { return Observable.create(observer => { - observer.next({ taskId: taskId }); + observer.next({taskId: taskId}); observer.complete(); }); }); @@ -390,7 +438,7 @@ describe('ActivitiForm', () => { it('should fetch and parse form definition by id', () => { spyOn(formService, 'getFormDefinitionById').and.callFake((formId) => { return Observable.create(observer => { - observer.next({ id: formId }); + observer.next({id: formId}); observer.complete(); }); }); @@ -429,7 +477,7 @@ describe('ActivitiForm', () => { spyOn(formService, 'getFormDefinitionById').and.callFake((formName) => { return Observable.create(observer => { - observer.next({ name: formName }); + observer.next({name: formName}); observer.complete(); }); }); @@ -465,8 +513,8 @@ describe('ActivitiForm', () => { let formModel = new FormModel({ taskId: '123', fields: [ - { id: 'field1' }, - { id: 'field2' } + {id: 'field1'}, + {id: 'field2'} ] }); formComponent.form = formModel; @@ -482,7 +530,7 @@ describe('ActivitiForm', () => { spyOn(formService, 'saveTaskForm').and.callFake(() => Observable.throw(error)); spyOn(formComponent, 'handleError').and.stub(); - formComponent.form = new FormModel({ taskId: '123' }); + formComponent.form = new FormModel({taskId: '123'}); formComponent.saveTaskForm(); expect(formComponent.handleError).toHaveBeenCalledWith(error); @@ -521,10 +569,10 @@ describe('ActivitiForm', () => { it('should complete form form and raise corresponding event', () => { spyOn(formService, 'completeTaskForm').and.callFake(() => { - return Observable.create(observer => { - observer.next(); - observer.complete(); - }); + return Observable.create(observer => { + observer.next(); + observer.complete(); + }); }); const outcome = 'complete'; @@ -534,8 +582,8 @@ describe('ActivitiForm', () => { let formModel = new FormModel({ taskId: '123', fields: [ - { id: 'field1' }, - { id: 'field2' } + {id: 'field1'}, + {id: 'field2'} ] }); @@ -554,7 +602,7 @@ describe('ActivitiForm', () => { let form = formComponent.parseForm({ id: '', fields: [ - { id: 'field1', type: FormFieldTypes.CONTAINER } + {id: 'field1', type: FormFieldTypes.CONTAINER} ] }); @@ -567,22 +615,22 @@ describe('ActivitiForm', () => { it('should provide outcomes for form definition', () => { spyOn(formComponent, 'getFormDefinitionOutcomes').and.callThrough(); - let form = formComponent.parseForm({ id: '' }); + let form = formComponent.parseForm({id: ''}); expect(formComponent.getFormDefinitionOutcomes).toHaveBeenCalledWith(form); }); /* - it('should update the visibility when the container raise the change event', (valueChanged) => { - spyOn(formComponent, 'checkVisibility').and.callThrough(); - let widget = new ContainerWidget(); - let fakeForm = new FormModel(); - let fakeField = new FormFieldModel(fakeForm, {id: 'fakeField', value: 'fakeValue'}); - widget.formValueChanged.subscribe(field => { valueChanged(); }); - widget.fieldChanged(fakeField); + it('should update the visibility when the container raise the change event', (valueChanged) => { + spyOn(formComponent, 'checkVisibility').and.callThrough(); + let widget = new ContainerWidget(); + let fakeForm = new FormModel(); + let fakeField = new FormFieldModel(fakeForm, {id: 'fakeField', value: 'fakeValue'}); + widget.formValueChanged.subscribe(field => { valueChanged(); }); + widget.fieldChanged(fakeField); - expect(formComponent.checkVisibility).toHaveBeenCalledWith(fakeField); - }); - */ + expect(formComponent.checkVisibility).toHaveBeenCalledWith(fakeField); + }); + */ it('should prevent default outcome execution', () => { @@ -640,7 +688,7 @@ describe('ActivitiForm', () => { let metadata = {}; spyOn(nodeService, 'getNodeMetadata').and.returnValue( Observable.create(observer => { - observer.next({ metadata: metadata }); + observer.next({metadata: metadata}); observer.complete(); }) ); 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 e25ee1e82c..e515d5f0ac 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 @@ -30,6 +30,9 @@ import { FormModel, FormOutcomeModel, FormValues, FormFieldModel, FormOutcomeEve import { WidgetVisibilityService } from './../services/widget-visibility.service'; +declare let dialogPolyfill: any; +declare var componentHandler: any; + /** * @Input * ActivitiForm can show 4 types of forms searching by 4 type of params: @@ -146,7 +149,7 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges { debugMode: boolean = false; constructor(protected formService: FormService, - private visibilityService: WidgetVisibilityService, + public visibilityService: WidgetVisibilityService, private ecmModelService: EcmModelService, private nodeService: NodeService) { } @@ -277,7 +280,6 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges { loadForm() { if (this.taskId) { this.getFormByTaskId(this.taskId); - this.visibilityService.getTaskProcessVariable(this.taskId); return; } @@ -292,6 +294,22 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges { } } + loadFormPorcessVariable(taskId) { + this.formService.getTask(taskId).subscribe( + task => { + if (this.isAProcessTask(task)) { + this.visibilityService.getTaskProcessVariable(taskId).subscribe(); + } + }, + (error) => { + this.handleError(error); + }); + } + + isAProcessTask(taskRepresentation) { + return taskRepresentation.processDefinitionId && taskRepresentation.processDefinitionDeploymentId !== 'null'; + } + setupMaterialComponents(): boolean { // workaround for MDL issues with dynamic components if (componentHandler) { @@ -302,6 +320,7 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges { } getFormByTaskId(taskId: string) { + this.loadFormPorcessVariable(this.taskId); let data = this.data; this.formService .getTaskForm(taskId) diff --git a/ng2-components/ng2-activiti-form/src/components/activiti-start-form.component.spec.ts b/ng2-components/ng2-activiti-form/src/components/activiti-start-form.component.spec.ts index 76701f658b..cf835494e0 100644 --- a/ng2-components/ng2-activiti-form/src/components/activiti-start-form.component.spec.ts +++ b/ng2-components/ng2-activiti-form/src/components/activiti-start-form.component.spec.ts @@ -41,7 +41,7 @@ describe('ActivitiStartForm', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - imports: [ CoreModule ], + imports: [CoreModule], declarations: [ ActivitiStartForm, FormFieldComponent, @@ -73,26 +73,21 @@ describe('ActivitiStartForm', () => { window['componentHandler'] = componentHandler; }); - it('should load start form on init if processDefinitionId defined', () => { + it('should load start form on change if processDefinitionId defined', () => { component.processDefinitionId = exampleId1; - component.ngOnInit(); + component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2) }); expect(formService.getStartFormDefinition).toHaveBeenCalled(); }); - it('should load not start form on init if no processDefinitionId defined', () => { - component.ngOnInit(); - expect(formService.getStartFormDefinition).not.toHaveBeenCalled(); - }); - it('should load start form when processDefinitionId changed', () => { component.processDefinitionId = exampleId1; - component.ngOnChanges({processDefinitionId: new SimpleChange(exampleId1, exampleId2)}); + component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2) }); expect(formService.getStartFormDefinition).toHaveBeenCalled(); }); it('should not load start form when changes notified but no change to processDefinitionId', () => { component.processDefinitionId = exampleId1; - component.ngOnChanges({otherProp: new SimpleChange(exampleId1, exampleId2)}); + component.ngOnChanges({ otherProp: new SimpleChange(exampleId1, exampleId2) }); expect(formService.getStartFormDefinition).not.toHaveBeenCalled(); }); @@ -102,7 +97,7 @@ describe('ActivitiStartForm', () => { component.ngOnInit(); }); - it('should not show outcome buttons by default', () => { + it('should show outcome buttons by default', () => { getStartFormSpy.and.returnValue(Observable.of({ id: '1', processDefinitionName: 'my:process', @@ -113,8 +108,9 @@ describe('ActivitiStartForm', () => { })); component.processDefinitionId = exampleId1; component.ngOnInit(); + component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2) }); fixture.detectChanges(); - expect(component.outcomesContainer).not.toBeTruthy(); + expect(component.outcomesContainer).toBeTruthy(); }); it('should show outcome buttons if showOutcomeButtons is true', () => { @@ -128,7 +124,7 @@ describe('ActivitiStartForm', () => { })); component.processDefinitionId = exampleId1; component.showOutcomeButtons = true; - component.ngOnInit(); + component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2) }); fixture.detectChanges(); expect(component.outcomesContainer).toBeTruthy(); }); diff --git a/ng2-components/ng2-activiti-form/src/components/activiti-start-form.component.ts b/ng2-components/ng2-activiti-form/src/components/activiti-start-form.component.ts index d4793c8601..ad4e5b74df 100644 --- a/ng2-components/ng2-activiti-form/src/components/activiti-start-form.component.ts +++ b/ng2-components/ng2-activiti-form/src/components/activiti-start-form.component.ts @@ -17,11 +17,13 @@ import { Component, - OnInit, AfterViewChecked, OnChanges, + AfterViewChecked, OnChanges, SimpleChanges, Input, ViewChild, - ElementRef + ElementRef, + Output, + EventEmitter } from '@angular/core'; import { AlfrescoTranslationService } from 'ng2-alfresco-core'; import { ActivitiForm } from './activiti-form.component'; @@ -37,8 +39,7 @@ import { WidgetVisibilityService } from './../services/widget-visibility.servic * * @Input * {processDefinitionId} string: The process definition ID - * {showOutcomeButtons} boolean: Whether form outcome buttons should be shown, as yet these don't do anything so this - * is false by default + * {showOutcomeButtons} boolean: Whether form outcome buttons should be shown, this is now always active to show form outcomes * @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. @@ -52,7 +53,7 @@ import { WidgetVisibilityService } from './../services/widget-visibility.servic templateUrl: './activiti-start-form.component.html', styleUrls: ['./activiti-form.component.css'] }) -export class ActivitiStartForm extends ActivitiForm implements OnInit, AfterViewChecked, OnChanges { +export class ActivitiStartForm extends ActivitiForm implements AfterViewChecked, OnChanges { @Input() processDefinitionId: string; @@ -61,11 +62,14 @@ export class ActivitiStartForm extends ActivitiForm implements OnInit, AfterView processId: string; @Input() - showOutcomeButtons: boolean = false; + showOutcomeButtons: boolean = true; @Input() showRefreshButton: boolean = true; + @Output() + outcomeClick: EventEmitter = new EventEmitter(); + @ViewChild('outcomesContainer', {}) outcomesContainer: ElementRef = null; @@ -73,41 +77,28 @@ export class ActivitiStartForm extends ActivitiForm implements OnInit, AfterView formService: FormService, visibilityService: WidgetVisibilityService) { super(formService, visibilityService, null, null); - } - - ngOnInit() { - if (this.processId) { - this.loadStartForm(this.processId); - }else { - this.loadForm(); - } if (this.translate) { - this.translate.addTranslationFolder('ng2-activiti-form', 'node_modules/ng2-activiti-form/dist/src'); + this.translate.addTranslationFolder('ng2-activiti-form', 'node_modules/ng2-activiti-form/src'); } } ngOnChanges(changes: SimpleChanges) { let processDefinitionId = changes['processDefinitionId']; if (processDefinitionId && processDefinitionId.currentValue) { + this.visibilityService.cleanProcessVariable(); this.getStartFormDefinition(processDefinitionId.currentValue); return; } let processId = changes['processId']; - if (processId && processId.currentValue) { + if (processId && processId.currentValue) { + this.visibilityService.cleanProcessVariable(); this.loadStartForm(processId.currentValue); return; } } - loadForm() { - if (this.processDefinitionId) { - this.getStartFormDefinition(this.processDefinitionId); - return; - } - } - loadStartForm(processId: string) { this.formService .getStartFormInstance(processId) @@ -144,5 +135,6 @@ export class ActivitiStartForm extends ActivitiForm implements OnInit, AfterView } completeTaskForm(outcome?: string) { + this.outcomeClick.emit(outcome); } } diff --git a/ng2-components/ng2-activiti-form/src/components/form-field/form-field.component.spec.ts b/ng2-components/ng2-activiti-form/src/components/form-field/form-field.component.spec.ts index d0e85f82c3..675f875fd3 100644 --- a/ng2-components/ng2-activiti-form/src/components/form-field/form-field.component.spec.ts +++ b/ng2-components/ng2-activiti-form/src/components/form-field/form-field.component.spec.ts @@ -16,12 +16,13 @@ */ import { CoreModule } from 'ng2-alfresco-core'; -import { ActivitiFormModule } from './../../../index'; import { ComponentFixture, TestBed, async } from '@angular/core/testing'; import { FormFieldComponent } from './form-field.component'; import { FormRenderingService } from './../../services/form-rendering.service'; import { FormModel, FormFieldModel, FormFieldTypes } from './../widgets/core/index'; -import { TextWidget, CheckboxWidget } from './../widgets/index'; +import { TextWidget } from './../widgets/text/text.widget'; +import { CheckboxWidget } from './../widgets/checkbox/checkbox.widget'; +import { WidgetVisibilityService } from './../../services/widget-visibility.service'; describe('FormFieldComponent', () => { @@ -34,9 +35,14 @@ describe('FormFieldComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - imports: [ CoreModule, ActivitiFormModule ] - }) - .compileComponents(); + imports: [CoreModule], + declarations: [FormFieldComponent, TextWidget, CheckboxWidget], + providers: [ + FormRenderingService, + WidgetVisibilityService + ] + }) + .compileComponents(); })); beforeEach(() => { @@ -52,7 +58,7 @@ describe('FormFieldComponent', () => { form = new FormModel(); }); - it('should create default component instance', () => { + xit('should create default component instance', () => { let field = new FormFieldModel(form, { type: FormFieldTypes.TEXT }); @@ -64,7 +70,7 @@ describe('FormFieldComponent', () => { expect(component.componentRef.componentType).toBe(TextWidget); }); - it('should create custom component instance', () => { + xit('should create custom component instance', () => { let field = new FormFieldModel(form, { type: FormFieldTypes.TEXT }); diff --git a/ng2-components/ng2-activiti-form/src/components/form-field/form-field.component.ts b/ng2-components/ng2-activiti-form/src/components/form-field/form-field.component.ts index 5657511464..3662f76944 100644 --- a/ng2-components/ng2-activiti-form/src/components/form-field/form-field.component.ts +++ b/ng2-components/ng2-activiti-form/src/components/form-field/form-field.component.ts @@ -81,7 +81,6 @@ export class FormFieldComponent implements OnInit, OnDestroy { let instance = this.componentRef.instance; instance.field = this.field; instance.fieldChanged.subscribe(field => { - console.log('WidgetComponent.fieldChanged was used only to trigger visibility engine, components should do that internally if needed'); if (field && field.form) { this.visibilityService.refreshVisibility(field.form); } diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.spec.ts b/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.spec.ts index 95121ed10b..de78edfa12 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.spec.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.spec.ts @@ -30,7 +30,7 @@ describe('AttachWidget', () => { let dialogPolyfill: any; beforeEach(() => { - contentService = new ActivitiAlfrescoContentService(null); + contentService = new ActivitiAlfrescoContentService(null, null); widget = new AttachWidget(contentService); dialogPolyfill = { diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.ts b/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.ts index 101accf328..e4881ac9f9 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/attach/attach.widget.ts @@ -22,6 +22,8 @@ import { ExternalContent } from '../core/external-content'; import { ExternalContentLink } from '../core/external-content-link'; import { FormFieldModel } from '../core/form-field.model'; +declare let dialogPolyfill: any; + @Component({ moduleId: module.id, selector: 'attach-widget', 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 bcdc57ebf6..b876e645c2 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 @@ -1,5 +1,5 @@
-
+

-
+
diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.spec.ts b/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.spec.ts index 54deb27273..f1967abee5 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.spec.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.spec.ts @@ -169,8 +169,7 @@ describe('ContainerWidget', () => { fixture.detectChanges(); fixture.whenStable() .then(() => { - expect(element.querySelector('#container-header')).toBeDefined(); - expect(element.querySelector('#container-header')).not.toBeNull(); + expect(element.querySelector('.container-widget__header').classList.contains('hidden')).toBe(false); expect(element.querySelector('#container-header-label')).toBeDefined(); expect(element.querySelector('#container-header-label').innerHTML).toContain('fake-cont-1-name'); }); @@ -181,8 +180,7 @@ describe('ContainerWidget', () => { fixture.detectChanges(); fixture.whenStable() .then(() => { - expect(element.querySelector('#container-header')).toBeNull(); - expect(element.querySelector('#container-header-label')).toBeNull(); + expect(element.querySelector('.container-widget__header').classList.contains('hidden')).toBe(true); }); }); @@ -194,8 +192,7 @@ describe('ContainerWidget', () => { fixture.detectChanges(); fixture.whenStable() .then(() => { - expect(element.querySelector('#container-header')).toBeNull(); - expect(element.querySelector('#container-header-label')).toBeNull(); + expect(element.querySelector('.container-widget__header').classList.contains('hidden')).toBe(true); }); }); containerWidgetComponent.onFieldChanged(null); diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.ts b/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.ts index 4c6c24784b..af367ca9a4 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.ts @@ -19,6 +19,8 @@ import { Component, AfterViewInit, OnInit } from '@angular/core'; import { ContainerWidgetModel } from './container.widget.model'; import { WidgetComponent } from './../widget.component'; +declare var componentHandler: any; + @Component({ moduleId: module.id, selector: 'container-widget', diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field-validator.spec.ts b/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field-validator.spec.ts index 245fdf1b6a..576b393d25 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field-validator.spec.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field-validator.spec.ts @@ -134,6 +134,30 @@ describe('FormFieldValidator', () => { expect(validator.validate(field)).toBeFalsy(); }); + it('should succeed for date', () => { + let field = new FormFieldModel(new FormModel(), { + type: FormFieldTypes.DATE, + value: '2016-12-31', + required: true + }); + + expect(validator.validate(field)).toBeTruthy(); + }); + + it('should fail for date', () => { + let field = new FormFieldModel(new FormModel(), { + type: FormFieldTypes.DATE, + value: null, + required: true + }); + + field.value = null; + expect(validator.validate(field)).toBeFalsy(); + + field.value = ''; + expect(validator.validate(field)).toBeFalsy(); + }); + it('should succeed for text', () => { let field = new FormFieldModel(new FormModel(), { type: FormFieldTypes.TEXT, diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field-validator.ts b/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field-validator.ts index 8b6ae005e8..12f84889b4 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field-validator.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field-validator.ts @@ -17,6 +17,7 @@ import { FormFieldModel } from './form-field.model'; import { FormFieldTypes } from './form-field-types'; +import * as moment from 'moment'; export interface FormFieldValidator { @@ -38,7 +39,8 @@ export class RequiredFieldValidator implements FormFieldValidator { FormFieldTypes.RADIO_BUTTONS, FormFieldTypes.UPLOAD, FormFieldTypes.AMOUNT, - FormFieldTypes.DYNAMIC_TABLE + FormFieldTypes.DYNAMIC_TABLE, + FormFieldTypes.DATE ]; isSupported(field: FormFieldModel): boolean { @@ -161,8 +163,7 @@ export class MinDateFieldValidator implements FormFieldValidator { isSupported(field: FormFieldModel): boolean { return field && - this.supportedTypes.indexOf(field.type) > -1 && - !!field.minValue; + this.supportedTypes.indexOf(field.type) > -1 && !!field.minValue; } validate(field: FormFieldModel): boolean { @@ -195,8 +196,7 @@ export class MaxDateFieldValidator implements FormFieldValidator { isSupported(field: FormFieldModel): boolean { return field && - this.supportedTypes.indexOf(field.type) > -1 && - !!field.maxValue; + this.supportedTypes.indexOf(field.type) > -1 && !!field.maxValue; } validate(field: FormFieldModel): boolean { @@ -338,8 +338,7 @@ export class RegExFieldValidator implements FormFieldValidator { isSupported(field: FormFieldModel): boolean { return field && - this.supportedTypes.indexOf(field.type) > -1 && - !!field.regexPattern; + this.supportedTypes.indexOf(field.type) > -1 && !!field.regexPattern; } validate(field: FormFieldModel): boolean { 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 76e30e9d95..dcaed466dc 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 @@ -35,8 +35,7 @@ import { MinDateFieldValidator, MaxDateFieldValidator } from './form-field-validator'; - -declare var moment: any; +import * as moment from 'moment'; // Maps to FormFieldRepresentation export class FormFieldModel extends FormWidgetModel { @@ -318,11 +317,23 @@ export class FormFieldModel extends FormWidgetModel { this.form.values[this.id] = this.enableFractions ? parseFloat(this.value) : parseInt(this.value, 10); break; default: - if (!FormFieldTypes.isReadOnlyType(this.type)) { + if (!FormFieldTypes.isReadOnlyType(this.type) && !this.isInvalidFieldType(this.type)) { this.form.values[this.id] = this.value; } } this.form.onFormFieldChanged(this); } + + /** + * Skip the invalid field type + * @param type + */ + isInvalidFieldType(type: string) { + if (type === 'container') { + return true; + } else { + return false; + } + } } diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/date/date.widget.spec.ts b/ng2-components/ng2-activiti-form/src/components/widgets/date/date.widget.spec.ts index 8b890fd6c9..65c2f17924 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/date/date.widget.spec.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/date/date.widget.spec.ts @@ -21,6 +21,7 @@ import { FormFieldModel } from './../core/form-field.model'; import { FormModel } from './../core/form.model'; import { CoreModule } from 'ng2-alfresco-core'; import { ComponentFixture, TestBed, async } from '@angular/core/testing'; +import * as moment from 'moment'; describe('DateWidget', () => { diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/date/date.widget.ts b/ng2-components/ng2-activiti-form/src/components/widgets/date/date.widget.ts index 969211b94f..7a36b067b6 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/date/date.widget.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/date/date.widget.ts @@ -17,6 +17,10 @@ import { Component, ElementRef, OnInit, AfterViewChecked } from '@angular/core'; import { WidgetComponent } from './../widget.component'; +import * as moment from 'moment'; + +declare let mdDateTimePicker: any; +declare var componentHandler: any; @Component({ moduleId: module.id, diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/display-value/display-value.widget.css b/ng2-components/ng2-activiti-form/src/components/widgets/display-value/display-value.widget.css index e896055f8c..43ebf44d05 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/display-value/display-value.widget.css +++ b/ng2-components/ng2-activiti-form/src/components/widgets/display-value/display-value.widget.css @@ -8,30 +8,45 @@ .display-value-widget__dynamic-table .is-disabled { background-color: transparent; - border-bottom: 1px dotted rgba(0,0,0,.12); - color: rgba(0,0,0,.26); + border-bottom: 1px dotted rgba(0, 0, 0, .12); + color: rgba(0, 0, 0, .26); } .display-value-widget__dynamic-table table { width: 100%; } +.display-value-dynamic-table-widget__table-container { + overflow-y: auto; + width: 100%; +} + + .upload-widget { - width:100%; + width: 100%; word-break: break-all; } .upload-widget__icon { float: left; - color: rgba(0,0,0,.26); + color: rgba(0, 0, 0, .26); } .upload-widget__file { float: left; margin-top: 4px; - color: rgba(0,0,0,.26); + color: rgba(0, 0, 0, .26); } .upload-widget__label { - color: rgba(0,0,0,.26); + color: rgba(0, 0, 0, .26); +} + +.img-upload-widget { + width: 100px; + height: 100px; + padding: 2px; + border: 1px solid rgba(117, 117, 117, 0.57); + box-shadow: 1px 1px 2px #dddddd; + background-color: #ffffff; } diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/display-value/display-value.widget.html b/ng2-components/ng2-activiti-form/src/components/widgets/display-value/display-value.widget.html index 04e7803ffb..6f39f72256 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/display-value/display-value.widget.html +++ b/ng2-components/ng2-activiti-form/src/components/widgets/display-value/display-value.widget.html @@ -1,6 +1,6 @@ -
+
-
+ +
+
+`, + styles: [` + header { + min-height: 48px; + } + h2 { + font-size: 14px; + line-height: 20px; + margin: 10px 0; + } + `] +}) +class MyDemoApp implements OnInit { + + authenticated: boolean; + + host: string = 'http://localhost:9999'; + + ticket: string; + + @ViewChild('tabmain') + tabMain: DebugElement; + + @ViewChild('tabheader') + tabHeader: DebugElement; + + @ViewChild(ActivitiProcessFilters) + activitiprocessfilter: ActivitiProcessFilters; + + @ViewChild(ActivitiProcessInstanceListComponent) + activitiprocesslist: ActivitiProcessInstanceListComponent; + + @ViewChild(ActivitiProcessInstanceDetails) + activitiprocessdetails: ActivitiProcessInstanceDetails; + + @ViewChild(ActivitiStartProcessInstance) + activitiStartProcess: ActivitiStartProcessInstance; + + @Input() + appId: number; + + processFilter: any; + + currentProcessInstanceId: string; + + dataProcesses: ObjectDataTableAdapter; + + constructor(private authService: AlfrescoAuthenticationService, + private settingsService: AlfrescoSettingsService, + private storage: StorageService) { + settingsService.bpmHost = this.host; + settingsService.setProviders('BPM'); + + if (this.authService.getTicketBpm()) { + this.ticket = this.authService.getTicketBpm(); + } + + this.dataProcesses = new ObjectDataTableAdapter( + [], + [ + {type: 'text', key: 'name', title: 'Name', cssClass: 'full-width name-column', sortable: true}, + {type: 'text', key: 'started', title: 'Started', sortable: true, cssClass: 'hidden'} + ] + ); + } + + public updateTicket(): void { + this.storage.setItem('ticket-BPM', this.ticket); + } + + public updateHost(): void { + this.settingsService.bpmHost = this.host; + this.login(); + } + + public ngOnInit(): void { + this.login(); + } + + login() { + this.authService.login('admin', 'admin').subscribe( + ticket => { + console.log(ticket); + this.ticket = this.authService.getTicketBpm(); + this.authenticated = true; + }, + error => { + console.log(error); + this.authenticated = false; + }); + } + + onAppClick(app: AppDefinitionRepresentationModel) { + this.appId = app.id; + + this.processFilter = null; + this.currentProcessInstanceId = null; + + this.changeTab('apps', 'processes'); + } + + navigateStartProcess() { + this.currentProcessInstanceId = currentProcessIdNew; + } + + onStartProcessInstance(instance: ProcessInstance) { + this.currentProcessInstanceId = instance.id; + this.activitiStartProcess.reset(); + } + + isStartProcessMode() { + return this.currentProcessInstanceId === currentProcessIdNew; + } + + onProcessFilterClick(event: any) { + this.processFilter = event; + } + + onSuccessProcessFilterList(event: any) { + this.processFilter = this.activitiprocessfilter.getCurrentFilter(); + } + + onSuccessProcessList(event: any) { + this.currentProcessInstanceId = this.activitiprocesslist.getCurrentId(); + } + + onProcessRowClick(processInstanceId) { + this.currentProcessInstanceId = processInstanceId; + } + + processCancelled(data: any) { + this.currentProcessInstanceId = null; + this.activitiprocesslist.reload(); + } + + changeTab(origin: string, destination: string) { + this.tabMain.nativeElement.children[origin].classList.remove('is-active'); + this.tabMain.nativeElement.children[destination].classList.add('is-active'); + + this.tabHeader.nativeElement.children[`${origin}-header`].classList.remove('is-active'); + this.tabHeader.nativeElement.children[`${destination}-header`].classList.add('is-active'); + } + +} + +@NgModule({ + imports: [ + BrowserModule, + CoreModule.forRoot(), + ActivitiProcessListModule, + ActivitiTaskListModule.forRoot() + ], + declarations: [MyDemoApp], + bootstrap: [MyDemoApp] +}) +export class AppModule { +} + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/ng2-components/ng2-activiti-processlist/demo/systemjs.config.js b/ng2-components/ng2-activiti-processlist/demo/systemjs.config.js index f1fe243137..37f2e2fcc1 100644 --- a/ng2-components/ng2-activiti-processlist/demo/systemjs.config.js +++ b/ng2-components/ng2-activiti-processlist/demo/systemjs.config.js @@ -11,7 +11,7 @@ // map tells the System loader where to look for things map: { // our app is within the app folder - app: 'dist', + app: 'src', // angular bundles '@angular/core': 'npm:@angular/core/bundles/core.umd.js', '@angular/common': 'npm:@angular/common/bundles/common.umd.js', @@ -22,14 +22,15 @@ '@angular/router': 'npm:@angular/router/bundles/router.umd.js', '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js', // other libraries + 'moment' : 'npm:moment/min/moment.min.js', 'rxjs': 'npm:rxjs', 'ng2-translate': 'npm:ng2-translate', 'alfresco-js-api': 'npm:alfresco-js-api/dist', - 'ng2-alfresco-core': 'npm:ng2-alfresco-core/dist', - 'ng2-alfresco-datatable': 'npm:ng2-alfresco-datatable/dist', - 'ng2-activiti-form': 'npm:ng2-activiti-form/dist', - 'ng2-activiti-tasklist': 'npm:ng2-activiti-tasklist/dist', - 'ng2-activiti-processlist': 'npm:ng2-activiti-processlist/dist' + 'ng2-alfresco-core': 'npm:ng2-alfresco-core', + 'ng2-alfresco-datatable': 'npm:ng2-alfresco-datatable', + 'ng2-activiti-form': 'npm:ng2-activiti-form', + 'ng2-activiti-tasklist': 'npm:ng2-activiti-tasklist', + 'ng2-activiti-processlist': 'npm:ng2-activiti-processlist' }, // packages tells the System loader how to load when no filename and/or no extension packages: { @@ -40,6 +41,7 @@ rxjs: { defaultExtension: 'js' }, + 'moment': { defaultExtension: 'js' }, 'ng2-translate': { defaultExtension: 'js' }, 'alfresco-js-api': { main: './alfresco-js-api.js', defaultExtension: 'js'}, 'ng2-alfresco-core': { main: './index.js', defaultExtension: 'js'}, diff --git a/ng2-components/ng2-activiti-processlist/demo/tsconfig.json b/ng2-components/ng2-activiti-processlist/demo/tsconfig.json index c586e1848e..524fcfda8e 100644 --- a/ng2-components/ng2-activiti-processlist/demo/tsconfig.json +++ b/ng2-components/ng2-activiti-processlist/demo/tsconfig.json @@ -1,26 +1,32 @@ { - "compilerOptions": { - "target": "es5", - "module": "commonjs", - "moduleResolution": "node", - "emitDecoratorMetadata": true, - "experimentalDecorators": true, - "sourceMap": true, - "removeComments": true, - "declaration": true, - "noLib": false, - "allowUnreachableCode": false, - "allowUnusedLabels": false, - "noImplicitAny": false, - "noImplicitReturns": false, - "noImplicitUseStrict": false, - "noFallthroughCasesInSwitch": true, - "outDir": "dist", - "types": ["core-js", "jasmine", "node"] - }, - "exclude": [ - "demo", - "node_modules", - "dist" - ] + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "moduleResolution": "node", + "sourceMap": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "skipLibCheck": true, + "noLib": false, + "allowUnreachableCode": false, + "allowUnusedLabels": false, + "noImplicitAny": false, + "noImplicitReturns": false, + "noImplicitUseStrict": false, + "noFallthroughCasesInSwitch": true, + "removeComments": true, + "declaration": true, + "lib": [ + "es2015", + "dom" + ], + "suppressImplicitAnyIndexErrors": true + }, + "exclude": [ + "node_modules" + ], + "angularCompilerOptions": { + "strictMetadataEmit": false, + "skipTemplateCodegen": true + } } diff --git a/ng2-components/ng2-activiti-processlist/gulpfile.ts b/ng2-components/ng2-activiti-processlist/gulpfile.ts new file mode 100755 index 0000000000..8524a10c96 --- /dev/null +++ b/ng2-components/ng2-activiti-processlist/gulpfile.ts @@ -0,0 +1,308 @@ +import * as gulp from 'gulp'; +import * as util from 'gulp-util'; +import * as runSequence from 'run-sequence'; +import * as gulpLoadPlugins from 'gulp-load-plugins'; +import * as merge from 'merge-stream'; +import * as rimraf from 'rimraf'; +import { join } from 'path'; +import * as Builder from 'systemjs-builder'; +var autoprefixer = require('autoprefixer'); +import * as cssnano from 'cssnano'; +import * as filter from 'gulp-filter'; +import * as sourcemaps from 'gulp-sourcemaps'; + +var APP_SRC = `.`; +var CSS_PROD_BUNDLE = 'main.css'; +var JS_PROD_SHIMS_BUNDLE = 'shims.js'; +var NG_FACTORY_FILE = 'main-prod'; + +const BUILD_TYPES = { + DEVELOPMENT: 'dev', + PRODUCTION: 'prod' +}; + +function normalizeDependencies(deps) { + deps + .filter((d) => !/\*/.test(d.src)) // Skip globs + .forEach((d) => d.src = require.resolve(d.src)); + return deps; +} + +function filterDependency(type: string, d): boolean { + const t = d.buildType || d.env; + d.buildType = t; + if (!t) { + d.buildType = Object.keys(BUILD_TYPES).map(k => BUILD_TYPES[k]); + } + if (!(d.buildType instanceof Array)) { + (d).env = [d.buildType]; + } + return d.buildType.indexOf(type) >= 0; +} + +function getInjectableDependency() { + var APP_ASSETS = [ + {src: `src/css/main.css`, inject: true, vendor: false}, + ]; + + var NPM_DEPENDENCIES = [ + {src: 'zone.js/dist/zone.js', inject: 'libs'}, + {src: 'core-js/client/shim.min.js', inject: 'shims'}, + {src: 'intl/dist/Intl.min.js', inject: 'shims'}, + {src: 'systemjs/dist/system.src.js', inject: 'shims', buildType:'dev'} + ]; + + return normalizeDependencies(NPM_DEPENDENCIES.filter(filterDependency.bind(null, 'dev'))) + .concat(APP_ASSETS.filter(filterDependency.bind(null, 'dev'))); +} + +const plugins = gulpLoadPlugins(); + +let tsProjects: any = {}; + +function makeTsProject(options: Object = {}) { + let optionsHash = JSON.stringify(options); + if (!tsProjects[optionsHash]) { + let config = Object.assign({ + typescript: require('typescript') + }, options); + tsProjects[optionsHash] = + plugins.typescript.createProject('tsconfig.json', config); + } + return tsProjects[optionsHash]; +} + +gulp.task('build.html_css', () => { + const gulpConcatCssConfig = { + targetFile: CSS_PROD_BUNDLE, + options: { + rebaseUrls: false + } + }; + + const processors = [ + autoprefixer({ + browsers: [ + 'ie >= 10', + 'ie_mob >= 10', + 'ff >= 30', + 'chrome >= 34', + 'safari >= 7', + 'opera >= 23', + 'ios >= 7', + 'android >= 4.4', + 'bb >= 10' + ] + }) + ]; + + const reportPostCssError = (e: any) => util.log(util.colors.red(e.message)); + + processors.push( + cssnano({ + discardComments: {removeAll: true}, + discardUnused: false, // unsafe, see http://goo.gl/RtrzwF + zindex: false, // unsafe, see http://goo.gl/vZ4gbQ + reduceIdents: false // unsafe, see http://goo.gl/tNOPv0 + }) + ); + + /** + * Processes the CSS files within `src/client` excluding those in `src/client/assets` using `postcss` with the + * configured processors + * Execute the appropriate component-stylesheet processing method based on user stylesheet preference. + */ + function processComponentStylesheets() { + return gulp.src(join('src/**', '*.css')) + .pipe(plugins.cached('process-component-css')) + .pipe(plugins.postcss(processors)) + .on('error', reportPostCssError); + } + + + /** + * Get a stream of external css files for subsequent processing. + */ + function getExternalCssStream() { + return gulp.src(getExternalCss()) + .pipe(plugins.cached('process-external-css')); + } + + /** + * Get an array of filenames referring to all external css stylesheets. + */ + function getExternalCss() { + return getInjectableDependency().filter(dep => /\.css$/.test(dep.src)).map(dep => dep.src); + } + + /** + * Processes the external CSS files using `postcss` with the configured processors. + */ + function processExternalCss() { + return getExternalCssStream() + .pipe(plugins.postcss(processors)) + .pipe(plugins.concatCss(gulpConcatCssConfig.targetFile, gulpConcatCssConfig.options)) + .on('error', reportPostCssError); + } + + return merge(processComponentStylesheets(), processExternalCss()); + +}); + +gulp.task('build.bundles.app', (done) => { + var BUNDLER_OPTIONS = { + format: 'umd', + minify: false, + mangle: false, + sourceMaps: true + }; + var CONFIG_TYPESCRIPT = { + baseURL: '.', + transpiler: 'typescript', + typescriptOptions: { + module: 'cjs' + }, + map: { + typescript: 'node_modules/typescript/lib/typescript.js', + '@angular': 'node_modules/@angular', + rxjs: 'node_modules/rxjs', + 'ng2-translate': 'node_modules/ng2-translate', + 'alfresco-js-api': 'node_modules/alfresco-js-api/dist/alfresco-js-api', + 'ng2-alfresco-core': 'node_modules/ng2-alfresco-core/', + 'ng2-activiti-diagrams': 'node_modules/ng2-activiti-diagrams/', + 'ng2-activiti-analytics': 'node_modules/ng2-activiti-analytics/', + 'ng2-alfresco-datatable': 'node_modules/ng2-alfresco-datatable/', + 'ng2-alfresco-documentlist': 'node_modules/ng2-alfresco-documentlist/', + 'ng2-activiti-form': 'node_modules/ng2-activiti-form/', + 'ng2-alfresco-login': 'node_modules/ng2-alfresco-login/', + 'ng2-activiti-processlist': 'node_modules/ng2-activiti-processlist/', + 'ng2-alfresco-search': 'node_modules/ng2-alfresco-search/', + 'ng2-activiti-tasklist': 'node_modules/ng2-activiti-tasklist/', + 'ng2-alfresco-tag': 'node_modules/ng2-alfresco-tag/', + 'ng2-alfresco-upload': 'node_modules/ng2-alfresco-upload/', + 'ng2-alfresco-userinfo': 'node_modules/ng2-alfresco-userinfo/', + 'ng2-alfresco-viewer': 'node_modules/ng2-alfresco-viewer/', + 'ng2-alfresco-webscript': 'node_modules/ng2-alfresco-webscript/' + }, + paths: { + '*': '*.js' + }, + meta: { + 'node_modules/@angular/*': {build: false}, + 'node_modules/rxjs/*': {build: false}, + 'node_modules/ng2-translate/*': {build: false}, + 'node_modules/ng2-alfresco-core/*': {build: false}, + 'node_modules/ng2-activiti-diagrams/*': {build: false}, + 'node_modules/ng2-activiti-analytics/*': {build: false}, + 'node_modules/ng2-alfresco-datatable/*': {build: false}, + 'node_modules/ng2-alfresco-documentlist/*': {build: false}, + 'node_modules/ng2-activiti-form/*': {build: false}, + 'node_modules/ng2-alfresco-login/*': {build: false}, + 'node_modules/ng2-activiti-processlist/*': {build: false}, + 'node_modules/ng2-alfresco-search/*': {build: false}, + 'node_modules/ng2-activiti-tasklist/*': {build: false}, + 'node_modules/ng2-alfresco-tag/*': {build: false}, + 'node_modules/ng2-alfresco-upload/*': {build: false}, + 'node_modules/ng2-alfresco-userinfo/*': {build: false}, + 'node_modules/ng2-alfresco-viewer/*': {build: false}, + 'node_modules/ng2-alfresco-webscript/*': {build: false} + } + }; + + var pkg = require('./package.json'); + var namePkg = pkg.name; + + var builder = new Builder(CONFIG_TYPESCRIPT); + builder + .buildStatic(APP_SRC + "/index", 'bundles/' + namePkg + '.js', BUNDLER_OPTIONS) + .then(function () { + return done(); + }) + .catch(function (err) { + return done(err); + }); +}); + +gulp.task('build.assets.prod', () => { + return gulp.src([ + join('src/**', '*.ts'), + 'index.ts', + join('src/**', '*.css'), + join('src/**', '*.html'), + '!'+join('*/**', '*.d.ts'), + '!'+join('*/**', '*.spec.ts'), + '!gulpfile.ts']) + +}); + +gulp.task('build.bundles', () => { + merge(bundleShims()); + + /** + * Returns the shim files to be injected. + */ + function getShims() { + let libs = getInjectableDependency() + .filter(d => /\.js$/.test(d.src)); + + return libs.filter(l => l.inject === 'shims') + .concat(libs.filter(l => l.inject === 'libs')) + .concat(libs.filter(l => l.inject === true)) + .map(l => l.src); + } + + /** + * Bundles the shim files. + */ + function bundleShims() { + return gulp.src(getShims()) + .pipe(plugins.concat(JS_PROD_SHIMS_BUNDLE)) + // Strip the first (global) 'use strict' added by reflect-metadata, but don't strip any others to avoid unintended scope leaks. + .pipe(plugins.replace(/('|")use strict\1;var Reflect;/, 'var Reflect;')) + .pipe(gulp.dest('bundles')); + } + +}); + +gulp.task('build.js.prod', () => { + const INLINE_OPTIONS = { + base: APP_SRC, + target: 'es5', + useRelativePaths: true, + removeLineBreaks: true + }; + + let tsProject = makeTsProject(); + let src = [ + join('src/**/*.ts'), + join('!src/**/*.d.ts'), + join('!src/**/*.spec.ts'), + `!src/**/${NG_FACTORY_FILE}.ts` + ]; + + let result = gulp.src(src) + .pipe(plugins.plumber()) + .pipe(plugins.inlineNg2Template(INLINE_OPTIONS)) + .pipe(sourcemaps.init()) + .pipe(tsProject()) + .once('error', function (e: any) { + this.once('finish', () => process.exit(1)); + }); + + return result.js + .pipe(plugins.template()) + .pipe(sourcemaps.write()) + .pipe(gulp.dest('src')) + .on('error', (e: any) => { + console.log(e); + }); +}); + +gulp.task('build.prod', (done: any) => + runSequence( + 'build.assets.prod', + 'build.html_css', + 'build.js.prod', + 'build.bundles', + 'build.bundles.app', + done)); diff --git a/ng2-components/ng2-activiti-processlist/index.ts b/ng2-components/ng2-activiti-processlist/index.ts index 8cb4397556..055737baaa 100644 --- a/ng2-components/ng2-activiti-processlist/index.ts +++ b/ng2-components/ng2-activiti-processlist/index.ts @@ -21,21 +21,24 @@ import { DataTableModule } from 'ng2-alfresco-datatable'; import { ActivitiFormModule } from 'ng2-activiti-form'; import { ActivitiTaskListModule } from 'ng2-activiti-tasklist'; -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 { ActivitiStartProcessInstance } from './src/components/activiti-start-process.component'; -import { ActivitiStartProcessInstanceDialog } from './src/components/activiti-start-process-dialog.component'; +import { + ActivitiProcessInstanceListComponent, + ActivitiProcessFilters, + ActivitiProcessInstanceHeader, + ActivitiProcessInstanceTasks, + ActivitiProcessInstanceVariables, + ActivitiProcessComments, + ActivitiProcessInstanceDetails, + ActivitiStartProcessInstance +} from './src/components/index'; + import { ActivitiProcessService } from './src/services/activiti-process.service'; // components export * from './src/components/activiti-processlist.component'; +export * from './src/components/activiti-filters.component'; export * from './src/components/activiti-process-instance-details.component'; export * from './src/components/activiti-start-process.component'; -export * from './src/components/activiti-start-process-dialog.component'; // models export * from './src/models/index'; @@ -49,9 +52,9 @@ export const ACTIVITI_PROCESSLIST_DIRECTIVES: [any] = [ ActivitiProcessInstanceDetails, ActivitiProcessInstanceHeader, ActivitiProcessInstanceTasks, - ActivitiComments, - ActivitiStartProcessInstance, - ActivitiStartProcessInstanceDialog + ActivitiProcessInstanceVariables, + ActivitiProcessComments, + ActivitiStartProcessInstance ]; export const ACTIVITI_PROCESSLIST_PROVIDERS: [any] = [ diff --git a/ng2-components/ng2-activiti-processlist/karma-test-shim.js b/ng2-components/ng2-activiti-processlist/karma-test-shim.js index b931cf3867..b628e7b92b 100644 --- a/ng2-components/ng2-activiti-processlist/karma-test-shim.js +++ b/ng2-components/ng2-activiti-processlist/karma-test-shim.js @@ -5,7 +5,7 @@ jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; __karma__.loaded = function() {}; -var builtPath = '/base/dist/'; +var builtPath = '/base/src/'; function isJsFile(path) { return path.slice(-3) == '.js'; @@ -29,7 +29,7 @@ var paths = { }; var map = { - 'app': 'base/dist', + 'app': 'base/src', // angular bundles '@angular/core': 'npm:@angular/core/bundles/core.umd.js', '@angular/common': 'npm:@angular/common/bundles/common.umd.js', @@ -52,18 +52,20 @@ var map = { // other libraries 'rxjs': 'npm:rxjs', 'ng2-translate': 'npm:ng2-translate', + 'moment' : 'npm:moment/min/moment.min.js', 'alfresco-js-api': 'npm:alfresco-js-api/dist', - 'ng2-activiti-form': 'npm:ng2-activiti-form/dist', - 'ng2-activiti-tasklist': 'npm:ng2-activiti-tasklist/dist', - 'ng2-alfresco-core': 'npm:ng2-alfresco-core/dist', - 'ng2-alfresco-datatable': 'npm:ng2-alfresco-datatable/dist' + 'ng2-activiti-form': 'npm:ng2-activiti-form', + 'ng2-activiti-tasklist': 'npm:ng2-activiti-tasklist', + 'ng2-alfresco-core': 'npm:ng2-alfresco-core', + 'ng2-alfresco-datatable': 'npm:ng2-alfresco-datatable' }; var packages = { 'app': { main: 'main.js', defaultExtension: 'js' }, 'rxjs': { defaultExtension: 'js' }, 'ng2-translate': { defaultExtension: 'js' }, + 'moment': { defaultExtension: 'js' }, 'alfresco-js-api': { main: './alfresco-js-api.js', defaultExtension: 'js'}, 'ng2-activiti-form': { main: './index.js', defaultExtension: 'js'}, diff --git a/ng2-components/ng2-activiti-processlist/karma.conf.js b/ng2-components/ng2-activiti-processlist/karma.conf.js index 279184d459..4b5c17fd42 100644 --- a/ng2-components/ng2-activiti-processlist/karma.conf.js +++ b/ng2-components/ng2-activiti-processlist/karma.conf.js @@ -33,27 +33,34 @@ module.exports = function (config) { {pattern: 'node_modules/@angular/**/*.js.map', included: false, watched: false}, 'node_modules/alfresco-js-api/dist/alfresco-js-api.js', + 'node_modules/moment/min/moment.min.js', + {pattern: 'node_modules/ng2-translate/**/*.js', included: false, watched: false}, 'karma-test-shim.js', // paths loaded via module imports - {pattern: 'dist/**/*.js', included: false, watched: true}, - {pattern: 'dist/**/*.html', included: true, served: true, watched: true}, - {pattern: 'dist/**/*.css', included: true, served: true, watched: true}, + {pattern: 'src/**/*.js', included: false, watched: true}, + {pattern: 'src/**/*.html', included: true, served: true, watched: true}, + {pattern: 'src/**/*.css', included: true, served: true, watched: true}, // ng2-components - { pattern: 'node_modules/ng2-alfresco-core/dist/**/*.*', included: false, served: true, watched: false }, - { pattern: 'node_modules/ng2-alfresco-datatable/dist/**/*.*', included: false, served: true, watched: false }, - { pattern: 'node_modules/ng2-activiti-tasklist/dist/**/*.*', included: false, served: true, watched: false }, - { pattern: 'node_modules/ng2-activiti-form/dist/**/*.*', included: false, served: true, watched: false }, + { pattern: 'node_modules/ng2-activiti-form/src/**/*.*', included: false, served: true, watched: false }, + { pattern: 'node_modules/ng2-activiti-form/index.js', included: false, served: true, watched: false }, + + { pattern: 'node_modules/ng2-alfresco-core/src/**/*.js', included: false, served: true, watched: false }, + { pattern: 'node_modules/ng2-alfresco-core/index.js', included: false, served: true, watched: false }, + + { pattern: 'node_modules/ng2-alfresco-datatable/src/**/*.*', included: false, served: true, watched: false }, + { pattern: 'node_modules/ng2-alfresco-datatable/index.js', included: false, served: true, watched: false }, + + { pattern: 'node_modules/ng2-activiti-tasklist/src/**/*.*', included: false, served: true, watched: false }, + { pattern: 'node_modules/ng2-activiti-tasklist/index.js', included: false, served: true, watched: false }, - // library dependencies - { pattern: 'node_modules/moment/moment.js', included: true, watched: false }, // paths to support debugging with source maps in dev tools {pattern: 'src/**/*.ts', included: false, watched: false}, - {pattern: 'dist/**/*.js.map', included: false, watched: false} + {pattern: 'src/**/*.js.map', included: false, watched: false} ], exclude: [ @@ -101,7 +108,7 @@ module.exports = function (config) { // Source files that you wanna generate coverage for. // Do not include tests or libraries (these files will be instrumented by Istanbul) preprocessors: { - 'dist/**/!(*spec|index|*mock|*model).js': 'coverage' + 'src/**/!(*spec|index|*mock|*model|mdl*).js': 'coverage' }, coverageReporter: { diff --git a/ng2-components/ng2-activiti-processlist/package.json b/ng2-components/ng2-activiti-processlist/package.json index fbd93374f8..857c38e317 100644 --- a/ng2-components/ng2-activiti-processlist/package.json +++ b/ng2-components/ng2-activiti-processlist/package.json @@ -1,28 +1,30 @@ { "name": "ng2-activiti-processlist", "description": "Show active processes from the Activiti BPM suite", - "version": "0.5.0", + "version": "1.0.0", "author": "Alfresco Software, Ltd.", "scripts": { - "clean": "npm install rimraf && rimraf dist node_modules typings", - "build": "npm run tslint && rimraf dist && tsc && npm run copy-dist && license-check", - "build:w": "npm run tslint && rimraf dist && npm run watch-task", - "watch-task": "concurrently \"npm run tsc:w\" \"npm run copy-dist:w\" \"license-check\"", - "tslint": "tslint -c tslint.json *.ts && tslint -c tslint.json 'src/{,**/}**.ts'", - "copy-dist": "cpx \"./src/**/*.{html,css,json,png,jpg,gif,svg}\" ./dist/src", - "copy-dist:w": "cpx \"./src/**/*.{html,css,json,png,jpg,gif,svg}\" ./dist/src -w", + "clean": "npm install rimraf && npm run clean-build && rimraf dist node_modules typings", + "clean-build": "rimraf index.js index.js.map index.d.ts'src/{,**/}**.js' 'src/{,**/}**.js.map' 'src/{,**/}**.d.ts' bundles", + "build": "npm run clean-build && npm run tslint && rimraf dist && tsc && license-check && npm run build.umd", + "build:w": "npm run clean-build && npm run tslint && rimraf dist && tsc:w && license-check npm run build.umd", + "tslint": "tslint -c tslint.json 'src/{,**/}**.ts' 'index.ts' -e '{,**/}**.d.ts' -e './gulpfile.ts'", "tsc": "tsc", "tsc:w": "tsc -w", "pretest": "npm run build", "test": "karma start karma.conf.js --reporters mocha,coverage --single-run", "test-browser": "npm run build && concurrently \"karma start karma.conf.js --reporters kjhtml\" \"npm run watch-task\"", - "posttest": "node_modules/.bin/remap-istanbul -i coverage/report/coverage-final.json -o coverage/report -t html", + "posttest": "remap-istanbul -i coverage/report/coverage-final.json -o coverage/report -t html && remap-istanbul -i coverage/report/coverage-final.json -o coverage/report/coverage-final.json", "coverage": "npm run test && wsrv -o -p 9875 ./coverage/report", "prepublish": "npm run build", - "travis": "npm link ng2-alfresco-core ng2-alfresco-datatable ng2-activiti-form ng2-activiti-tasklist" + "travis": "npm link ng2-alfresco-core ng2-alfresco-datatable ng2-activiti-form ng2-activiti-tasklist", + "gulp": "gulp", + "build.umd": "gulp build.prod --color --env-config prod --build-type prod", + "reinstall": "npm cache clean && npm install" }, - "main": "./dist/index.js", - "typings": "./dist/index.d.ts", + "main": "./index.js", + "module": "./index.js", + "typings": "./index.d.ts", "repository": { "type": "git", "url": "https://github.com/Alfresco/alfresco-ng2-components.git" @@ -30,7 +32,6 @@ "bugs": { "url": "https://github.com/Alfresco/alfresco-ng2-components/issues" }, - "license": "Apache-2.0", "contributors": [ { "name": "Will Abson", @@ -44,6 +45,7 @@ "alfresco" ], "dependencies": { + "@angular/router": "3.0.0", "@angular/common": "2.0.0", "@angular/compiler": "2.0.0", "@angular/core": "2.0.0", @@ -56,22 +58,36 @@ "rxjs": "5.0.0-beta.12", "systemjs": "0.19.27", "zone.js": "^0.6.23", - "moment": "2.15.1", "md-date-time-picker": "^2.2.0", - "ng2-translate": "2.5.0", - "alfresco-js-api": "^0.5.0", - "ng2-activiti-tasklist": "0.5.0", - "ng2-alfresco-core": "0.5.0", - "ng2-alfresco-datatable": "0.5.0" + "alfresco-js-api": "^1.0.0", + "ng2-activiti-tasklist": "1.0.0", + "ng2-alfresco-core": "1.0.0", + "ng2-alfresco-datatable": "1.0.0" }, "devDependencies": { - "@types/node": "^6.0.42", - "@types/core-js": "^0.9.32", "@types/jasmine": "^2.2.33", + "@types/node": "^6.0.42", "concurrently": "^2.2.0", "cpx": "^1.3.1", + "cssnano": "^3.8.1", + "gulp": "^3.9.1", + "gulp-autoprefixer": "^3.1.1", + "gulp-cached": "^1.1.1", + "gulp-concat": "^2.6.1", + "gulp-concat-css": "^2.3.0", + "gulp-filter": "^4.0.0", + "gulp-inline-ng2-template": "^4.0.0", + "gulp-load-plugins": "^1.4.0", + "gulp-plumber": "^1.1.0", + "gulp-postcss": "^6.2.0", + "gulp-replace": "^0.5.4", + "gulp-sourcemaps": "^1.9.1", + "gulp-template": "^4.0.0", + "gulp-typescript": "^3.1.3", + "gulp-uglify": "^2.0.0", + "intl": "^1.2.5", "jasmine-ajax": "^3.2.0", "jasmine-core": "2.4.1", "karma": "~0.13.22", @@ -84,18 +100,22 @@ "license-check": "^1.0.4", "remap-istanbul": "^0.6.3", "rimraf": "2.5.2", + "run-sequence": "^1.2.2", + "systemjs-builder": "^0.15.34", "traceur": "^0.0.91", + "ts-node": "^1.7.0", "tslint": "^3.8.1", "typescript": "^2.0.3", "wsrv": "^0.1.5" }, "license-check-config": { "src": [ - "./dist/**/*.js" + "./src/**/*.js" ], "path": "assets/license_header.txt", "blocking": false, "logInfo": false, "logError": true - } + }, + "license": "Apache-2.0" } diff --git a/ng2-components/ng2-activiti-processlist/src/components/activiti-filters.component.spec.ts b/ng2-components/ng2-activiti-processlist/src/components/activiti-filters.component.spec.ts index fcc540f7e1..69bfee68ba 100644 --- a/ng2-components/ng2-activiti-processlist/src/components/activiti-filters.component.spec.ts +++ b/ng2-components/ng2-activiti-processlist/src/components/activiti-filters.component.spec.ts @@ -43,7 +43,7 @@ describe('ActivitiFilters', () => { }); beforeEach(() => { - activitiService = new ActivitiProcessService(null); + activitiService = new ActivitiProcessService(null, null); filterList = new ActivitiProcessFilters(null, activitiService); }); 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 index 97025c5902..a6a800cdb1 100644 --- a/ng2-components/ng2-activiti-processlist/src/components/activiti-filters.component.ts +++ b/ng2-components/ng2-activiti-processlist/src/components/activiti-filters.component.ts @@ -58,7 +58,7 @@ export class ActivitiProcessFilters implements OnInit, OnChanges { this.filter$ = new Observable(observer => this.filterObserver = observer).share(); if (translate) { - translate.addTranslationFolder('ng2-activiti-processlist', 'node_modules/ng2-activiti-processlist/dist/src'); + translate.addTranslationFolder('ng2-activiti-processlist', 'node_modules/ng2-activiti-processlist/src'); } } @@ -145,7 +145,7 @@ export class ActivitiProcessFilters implements OnInit, OnChanges { /** * Select the first filter of a list if present */ - private selectFirstFilter() { + public selectFirstFilter() { if (!this.isFilterListEmpty()) { this.currentFilter = this.filters[0]; } else { diff --git a/ng2-components/ng2-activiti-processlist/src/components/activiti-comments.component.css b/ng2-components/ng2-activiti-processlist/src/components/activiti-process-comments.component.css similarity index 85% rename from ng2-components/ng2-activiti-processlist/src/components/activiti-comments.component.css rename to ng2-components/ng2-activiti-processlist/src/components/activiti-process-comments.component.css index 69521b25cf..65ef475088 100644 --- a/ng2-components/ng2-activiti-processlist/src/components/activiti-comments.component.css +++ b/ng2-components/ng2-activiti-processlist/src/components/activiti-process-comments.component.css @@ -16,3 +16,7 @@ position: relative; top: -2px; } + +.material-icons { + cursor: pointer; +} diff --git a/ng2-components/ng2-activiti-processlist/src/components/activiti-comments.component.html b/ng2-components/ng2-activiti-processlist/src/components/activiti-process-comments.component.html similarity index 78% rename from ng2-components/ng2-activiti-processlist/src/components/activiti-comments.component.html rename to ng2-components/ng2-activiti-processlist/src/components/activiti-process-comments.component.html index c24ffd50ce..f1760200c3 100644 --- a/ng2-components/ng2-activiti-processlist/src/components/activiti-comments.component.html +++ b/ng2-components/ng2-activiti-processlist/src/components/activiti-process-comments.component.html @@ -2,7 +2,7 @@ [attr.data-badge]="comments?.length">{{ 'DETAILS.LABELS.COMMENTS' |translate }}
add
- Add a comment + {{ 'DETAILS.COMMENTS.BUTTON.ADD' |translate }}