Merge pull request #1341 from Alfresco/development

1.0.0
This commit is contained in:
Eugenio Romano
2016-12-20 17:05:27 +00:00
committed by GitHub
587 changed files with 16991 additions and 6205 deletions
+5 -4
View File
@@ -1,8 +1,9 @@
**Please check if the PR fulfills these requirements** **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) [ ] The commit message follows our [guidelines](https://github.com/Alfresco/alfresco-ng2-components/wiki/Commit-format)
- [ ] Docs have been added / updated (for bug fixes / features) [ ] Tests for the changes have been added (for bug fixes / features)
[ ] Docs have been added / updated (for bug fixes / features)
```
<!-- <!--
Before submitting your PR, please check that your code follows our contribution guidelines: Before submitting your PR, please check that your code follows our contribution guidelines:
https://github.com/Alfresco/alfresco-ng2-components/wiki/Code-contribution-acceptance-criteria https://github.com/Alfresco/alfresco-ng2-components/wiki/Code-contribution-acceptance-criteria
+2
View File
@@ -8,3 +8,5 @@ demo-shell-ng2/app/components/router/
ng2-components/ng2-alfresco-userinfo-old/demo/src/app/ ng2-components/ng2-alfresco-userinfo-old/demo/src/app/
ng2-components/ng2-alfresco-userinfo-old/src/services/bpm-user.service.spec.ts ng2-components/ng2-alfresco-userinfo-old/src/services/bpm-user.service.spec.ts
ng2-components/ng2-alfresco-userinfo-old/src/services/ecm-user.service.spec.ts ng2-components/ng2-alfresco-userinfo-old/src/services/ecm-user.service.spec.ts
src/environments/
/ng2-components/ng2-example-webpack/
+67
View File
@@ -0,0 +1,67 @@
### Enable CORS in Alfresco
The web client that we are building with the application development framework will be loaded from a different web server than the Alfresco Platform is running on.
So we need to tell the Alfresco server that any request that comes in from this custom web client should be allowed access
to the Content Repository. This is done by enabling CORS.
To enable CORS in the Alfresco Platform do **one of the following**:
##Recommended - Download and install the enable CORS module
This is the easiest way, add the [enablecors](https://artifacts.alfresco.com/nexus/service/local/repositories/releases/content/org/alfresco/enablecors/1.0/enablecors-1.0.jar)
platform module JAR to the *$ALF_INSTALL_DIR/modules/platform* directory and restart the server.
Note. by default the CORS filter that is enabled will allow any orgin.
##Or - Manually update the web.xml file
Modify *$ALF_INSTALL_DIR/tomcat/webapps/alfresco/WEB-INF/web.xml* and uncomment the following section and update
`cors.allowOrigin` to `http://localhost:3000`:
```
<filter>
<filter-name>CORS</filter-name>
<filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
<init-param>
<param-name>cors.allowGenericHttpRequests</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.allowOrigin</param-name>
<param-value>http://localhost:3000</param-value>
</init-param>
<init-param>
<param-name>cors.allowSubdomains</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.supportedMethods</param-name>
<param-value>GET, HEAD, POST, PUT, DELETE, OPTIONS</param-value>
</init-param>
<init-param>
<param-name>cors.supportedHeaders</param-name>
<param-value>origin, authorization, x-file-size, x-file-name, content-type, accept, x-file-type</param-value>
</init-param>
<init-param>
<param-name>cors.supportsCredentials</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.maxAge</param-name>
<param-value>3600</param-value>
</init-param>
</filter>
```
When specifying the `cors.allowOrigin` URL make sure to use the URL that will be used by the web client.
Then uncomment filter mappings:
```
<filter-mapping>
<filter-name>CORS</filter-name>
<url-pattern>/api/*</url-pattern>
<url-pattern>/service/*</url-pattern>
<url-pattern>/s/*</url-pattern>
<url-pattern>/cmisbrowser/*</url-pattern>
</filter-mapping>
```
+2 -1
View File
@@ -2,7 +2,8 @@
The [Angular 2](https://angular.io/) based application development framework requires the following: The [Angular 2](https://angular.io/) based application development framework requires the following:
- An Alfresco Platform Repository (version [201609 Early Access](https://community.alfresco.com/docs/DOC-6372-alfresco-community-edition-file-list-201609-ea) or newer) to talk to, which has [CORS](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing) enabled. - An Alfresco Platform Repository (version [201609 Early Access](https://community.alfresco.com/docs/DOC-6372-alfresco-community-edition-file-list-201609-ea) or newer)
- [Enable cors on Alfresco One](/ALFRESCOCORS.md)
- [Download and install Activiti](https://www.alfresco.com/products/bpm/alfresco-activiti/trial) - [Download and install Activiti](https://www.alfresco.com/products/bpm/alfresco-activiti/trial)
- [Node.js](https://nodejs.org/en/) JavaScript runtime. - [Node.js](https://nodejs.org/en/) JavaScript runtime.
- [npm](https://www.npmjs.com/) package manager for JavaScript. - [npm](https://www.npmjs.com/) package manager for JavaScript.
+2
View File
@@ -5,7 +5,9 @@ app/**/*.js
app/**/*.js.map app/**/*.js.map
!app/js/Polyline.js !app/js/Polyline.js
.idea .idea
versions.json
dist/ dist/
coverage/
# docker files # docker files
docker-compose.yml docker-compose.yml
+25 -11
View File
@@ -10,28 +10,42 @@
</a> </a>
</p> </p>
### Node ## Installing
To correctly use this demo check that on your machine is running Node version 5.0.0 or higher.
#### Local build To correctly use this demo check that on your machine is running Node version 6.9.2 LTS or higher.
1 Install dependencies
```sh ```sh
npm install npm install
``` ```
2 Fast build and watch for dev purposes ## Development build
```sh ```sh
npm start npm start
``` ```
>`start` script also includes live reload and watchers for all the `.ts` files. This command compiles and starts the project in watch mode.
TypeScript watchers are also configured for `node_modules` folder within demo shell Browser will automatically reload upon changes.
and provide live reload for all the component libraries as well. Upon start you can navigate to `http://localhost:3000` with your preferred browser.
#### Development branch build ## Production build
```sh
npm run build
```
This command builds broject in `production` mode.
All output is placed to `dist` folder and can be served your preferred web server.
You should need no additional files outside the `dist` folder.
In order to quickly test the output you can use the [wsrv](https://www.npmjs.com/package/wsrv) tool (lightweight web server):
```sh
npm install -g wsrv
wsrv -s -o dist/
```
## Development branch build
If you want to run the demo shell with the latest change from the development branch, use the following command from the /script folder: If you want to run the demo shell with the latest change from the development branch, use the following command from the /script folder:
@@ -40,7 +54,7 @@ If you want to run the demo shell with the latest change from the development br
./start-linked.sh -install ./start-linked.sh -install
``` ```
###Multi-language ## Multi-language
To support a new language you need to create your language file (.json) and add it to `i18n/` folder. To support a new language you need to create your language file (.json) and add it to `i18n/` folder.
```json ```json
+21 -3
View File
@@ -1,6 +1,12 @@
@media only screen and (max-width: 640px) { @media screen and (max-width: 1024px) {
.mdl-layout__header.header-search-expanded .mdl-layout-title { .mdl-layout__header {
display: none; display: block;
}
}
@media screen and (max-width: 1024px) {
.mdl-layout__header {
display: block;
} }
} }
@@ -15,3 +21,15 @@
.mdl-button-padding { .mdl-button-padding {
padding-left: 20px; padding-left: 20px;
} }
.hide {
display: none !important;
}
.mdl-navigation__link {
cursor: pointer;
}
.mdl-navigation__link label {
cursor: pointer;
}
+55 -71
View File
@@ -1,82 +1,66 @@
<!-- Always shows a header, even in smaller screens. --> <!-- Always shows a header, even in smaller screens. -->
<div mdl class="mdl-layout mdl-js-layout mdl-layout--fixed-header"> <div mdl class="mdl-layout mdl-js-layout mdl-layout--fixed-header">
<div *ngIf="!isLoginPage()"> <header class="mdl-layout__header main_header_adf" [ngClass]="{hide: isLoginPage()}">
<header class="mdl-layout__header"> <div class="mdl-button-padding mdl-layout__header-row">
<div class="mdl-button-padding mdl-layout__header-row">
<!-- User Info -->
<ng2-alfresco-userinfo class="user-profile" [menuOpenType]="left">
</ng2-alfresco-userinfo>
<ng2-alfresco-userinfo class="user-profile" [menuOpenType]="left"> <!-- Title -->
</ng2-alfresco-userinfo> <span class="mdl-layout-title">Demo Application</span>
<!-- Add spacer, to align navigation to the right -->
<div class="mdl-layout-spacer"></div>
<!-- Search bar -->
<search-bar (expand)="onToggleSearch($event)"></search-bar>
<!-- Title --> <!-- Navigation. We hide it in small screens. -->
<span class="mdl-layout-title">Demo Application</span> <nav class="mdl-navigation mdl-layout--large-screen-only">
<!-- Add spacer, to align navigation to the right --> <a class="mdl-navigation__link" data-automation-id="home" href="" routerLink="/">Home</a>
<div class="mdl-layout-spacer"></div> <a class="mdl-navigation__link" data-automation-id="files" href="" routerLink="/files">DocumentList</a>
<a class="mdl-navigation__link" data-automation-id="activiti" href="" routerLink="/activiti">Activiti</a>
<!-- Search bar --> <a class="mdl-navigation__link" data-automation-id="login" href="" routerLink="/login">Login</a>
<search-bar (expand)="onToggleSearch($event)"></search-bar> <a class="mdl-navigation__link" data-automation-id="settings" href="" routerLink="/settings">Settings</a>
<!-- Navigation. We hide it in small screens. -->
<nav class="mdl-navigation mdl-layout--large-screen-only">
<a class="mdl-navigation__link" data-automation-id="files" href=""
routerLink="/files">DocumentList</a>
<a class="mdl-navigation__link" data-automation-id="datatable" href="" routerLink="/datatable">DataTable</a>
<a class="mdl-navigation__link" data-automation-id="uploader" href="" routerLink="/uploader">Uploader</a>
<a class="mdl-navigation__link" data-automation-id="activiti" href="" routerLink="/activiti">Activiti</a>
<a class="mdl-navigation__link" data-automation-id="webscript" href="" routerLink="/webscript">Webscript</a>
<a class="mdl-navigation__link" data-automation-id="tag" href="" routerLink="/tag">Tag</a>
<a class="mdl-navigation__link" data-automation-id="login" href="" routerLink="/login">Login</a>
<a class="mdl-navigation__link" data-automation-id="settings" href="" routerLink="/settings">Settings</a>
</nav>
<!-- Right aligned menu below button -->
<button id="demo-menu-lower-right" data-automation-id="right-action-menu"
class="mdl-button mdl-js-button mdl-button--icon">
<i class="material-icons">more_vert</i>
</button>
<ul class="mdl-menu mdl-menu--bottom-right mdl-js-menu mdl-js-ripple-effect"
for="demo-menu-lower-right">
<li class="mdl-menu__item" (click)="changeLanguage('en')">
<span class="flag-icon flag-icon-gb"></span>
<label tabindex="0"> English</label>
</li>
<li class="mdl-menu__item" (click)="changeLanguage('gr')">
<span class="flag-icon flag-icon-gr"></span>
<label tabindex="0"> Greek</label>
</li>
<li class="mdl-menu__item" (click)="changeLanguage('it')">
<span class="flag-icon flag-icon-it"></span>
<label tabindex="0"> Italian</label>
</li>
<a class="mdl-menu__item" routerLink="/about">
<label tabindex="0">About</label>
</a>
<a *ngIf="!isLoggedIn()" class="mdl-menu__item" routerLink="/login">
<label tabindex="0">Login</label>
</a>
<li *ngIf="isLoggedIn()" class="mdl-menu__item" (click)="onLogout($event)">
<label tabindex="0">Logout</label>
</li>
</ul>
</div>
</header>
<div class="mdl-layout__drawer">
<span class="mdl-layout-title">Components List</span>
<nav class="mdl-navigation">
<a class="mdl-navigation__link" href="" routerLink="/files" (click)="hideDrawer()">DocumentList Demo</a>
<a class="mdl-navigation__link" href="" routerLink="/datatable" (click)="hideDrawer()">DataTable
Demo</a>
<a class="mdl-navigation__link" href="" routerLink="/uploader" (click)="hideDrawer()">Uploader Demo</a>
<a class="mdl-navigation__link" href="" routerLink="/login" (click)="hideDrawer()">Login Demo</a>
<a class="mdl-navigation__link" href="" routerLink="/activiti" (click)="hideDrawer()">Activiti
Components Demo</a>
<a class="mdl-navigation__link" href="" routerLink="/webscript" (click)="hideDrawer()">Webscript</a>
<a class="mdl-navigation__link" href="" routerLink="/tag" (click)="hideDrawer()">Tag</a>
<a class="mdl-navigation__link" href="" routerLink="/settings" (click)="hideDrawer()">Settings</a>
</nav> </nav>
</div> </div>
</header>
<div class="mdl-layout__drawer">
<nav class="mdl-navigation">
<a class="mdl-navigation__link" (click)="onLogout($event)">
<label tabindex="0">Logout</label>
</a>
</nav>
<span class="mdl-layout-title">Languages</span>
<nav class="mdl-navigation">
<a class="mdl-navigation__link" (click)="changeLanguage('en')">
<span class="flag-icon flag-icon-gb"></span>
<label tabindex="0"> English</label>
</a>
<a class="mdl-navigation__link" (click)="changeLanguage('gr')">
<span class="flag-icon flag-icon-gr"></span>
<label tabindex="0"> Greek</label>
</a>
<a class="mdl-navigation__link" (click)="changeLanguage('it')">
<span class="flag-icon flag-icon-it"></span>
<label tabindex="0"> Italian</label>
</a>
</nav>
<span class="mdl-layout-title">Components</span>
<nav class="mdl-navigation">
<a class="mdl-navigation__link" href="" routerLink="/" (click)="hideDrawer()">Home</a>
<a class="mdl-navigation__link" href="" routerLink="/files" (click)="hideDrawer()">DocumentList</a>
<a class="mdl-navigation__link" href="" routerLink="/datatable" (click)="hideDrawer()">DataTable</a>
<a class="mdl-navigation__link" href="" routerLink="/uploader" (click)="hideDrawer()">Uploader</a>
<a class="mdl-navigation__link" href="" routerLink="/login" (click)="hideDrawer()">Login</a>
<a class="mdl-navigation__link" href="" routerLink="/activiti" (click)="hideDrawer()">Activiti</a>
<a class="mdl-navigation__link" href="" routerLink="/webscript" (click)="hideDrawer()">Webscript</a>
<a class="mdl-navigation__link" href="" routerLink="/tag" (click)="hideDrawer()">Tag</a>
<a class="mdl-navigation__link" href="" routerLink="/about" (click)="hideDrawer()">About</a>
<a class="mdl-navigation__link" href="" routerLink="/settings" (click)="hideDrawer()">Settings</a>
</nav>
</div> </div>
<main class="mdl-layout__content"> <main class="mdl-layout__content">
<div class="page-content"> <div class="page-content">
+34 -20
View File
@@ -21,15 +21,16 @@ import { Router } from '@angular/router';
import { import {
AlfrescoTranslationService, AlfrescoTranslationService,
AlfrescoAuthenticationService, AlfrescoAuthenticationService,
AlfrescoSettingsService AlfrescoSettingsService,
StorageService
} from 'ng2-alfresco-core'; } from 'ng2-alfresco-core';
declare var document: any; declare var document: any;
@Component({ @Component({
selector: 'alfresco-app', selector: 'alfresco-app',
templateUrl: 'app/app.component.html', templateUrl: './app.component.html',
styleUrls: ['app/app.component.css'] styleUrls: ['./app.component.css']
}) })
export class AppComponent { export class AppComponent {
searchTerm: string = ''; searchTerm: string = '';
@@ -40,14 +41,20 @@ export class AppComponent {
constructor(public auth: AlfrescoAuthenticationService, constructor(public auth: AlfrescoAuthenticationService,
public router: Router, public router: Router,
public alfrescoSettingsService: AlfrescoSettingsService, public alfrescoSettingsService: AlfrescoSettingsService,
private translate: AlfrescoTranslationService) { private translate: AlfrescoTranslationService,
private storage: StorageService) {
this.setEcmHost(); this.setEcmHost();
this.setBpmHost(); this.setBpmHost();
this.setProvider(); this.setProvider();
if (translate) { if (translate) {
translate.addTranslationFolder('custom', 'custom-translation/'); if (process.env.ENV === 'production') {
translate.addTranslationFolder('ng2-alfresco-login', 'custom-translation/alfresco-login'); 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 { isLoginPage(): boolean {
return location.pathname === '/login' || location.pathname === '/' || location.pathname === '/settings'; return location.pathname === '/login' || location.pathname === '/settings';
} }
onLogout(event) { onLogout(event) {
@@ -71,18 +78,24 @@ export class AppComponent {
this.auth.logout() this.auth.logout()
.subscribe( .subscribe(
() => { () => {
this.router.navigate(['/login']); this.navigateToLogin();
}, },
($event: any) => { (error: any) => {
if ($event && $event.response && $event.response.status === 401) { if (error && error.response && error.response.status === 401) {
this.router.navigate(['/login']); this.navigateToLogin();
} else { } 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) { onToggleSearch(event) {
let expandedHeaderClass = 'header-search-expanded', let expandedHeaderClass = 'header-search-expanded',
header = document.querySelector('header'); header = document.querySelector('header');
@@ -95,6 +108,7 @@ export class AppComponent {
changeLanguage(lang: string) { changeLanguage(lang: string) {
this.translate.use(lang); this.translate.use(lang);
this.hideDrawer();
} }
hideDrawer() { hideDrawer() {
@@ -103,26 +117,26 @@ export class AppComponent {
} }
private setEcmHost() { private setEcmHost() {
if (localStorage.getItem(`ecmHost`)) { if (this.storage.hasItem(`ecmHost`)) {
this.alfrescoSettingsService.ecmHost = localStorage.getItem(`ecmHost`); this.alfrescoSettingsService.ecmHost = this.storage.getItem(`ecmHost`);
this.ecmHost = localStorage.getItem(`ecmHost`); this.ecmHost = this.storage.getItem(`ecmHost`);
} else { } else {
this.alfrescoSettingsService.ecmHost = this.ecmHost; this.alfrescoSettingsService.ecmHost = this.ecmHost;
} }
} }
private setBpmHost() { private setBpmHost() {
if (localStorage.getItem(`bpmHost`)) { if (this.storage.hasItem(`bpmHost`)) {
this.alfrescoSettingsService.bpmHost = localStorage.getItem(`bpmHost`); this.alfrescoSettingsService.bpmHost = this.storage.getItem(`bpmHost`);
this.bpmHost = localStorage.getItem(`bpmHost`); this.bpmHost = this.storage.getItem(`bpmHost`);
} else { } else {
this.alfrescoSettingsService.bpmHost = this.bpmHost; this.alfrescoSettingsService.bpmHost = this.bpmHost;
} }
} }
private setProvider() { private setProvider() {
if (localStorage.getItem(`providers`)) { if (this.storage.hasItem(`providers`)) {
this.alfrescoSettingsService.setProviders(localStorage.getItem(`providers`)); this.alfrescoSettingsService.setProviders(this.storage.getItem(`providers`));
} }
} }
} }
+4 -1
View File
@@ -38,11 +38,13 @@ import { routing } from './app.routes';
import { CustomEditorsModule } from './components/activiti/custom-editor/custom-editor.component'; import { CustomEditorsModule } from './components/activiti/custom-editor/custom-editor.component';
import { import {
HomeComponent,
DataTableDemoComponent, DataTableDemoComponent,
SearchComponent, SearchComponent,
SearchBarComponent, SearchBarComponent,
LoginDemoComponent, LoginDemoComponent,
ActivitiDemoComponent, ActivitiDemoComponent,
ActivitiAppsView,
FormViewer, FormViewer,
WebscriptComponent, WebscriptComponent,
TagComponent, TagComponent,
@@ -74,12 +76,13 @@ import {
], ],
declarations: [ declarations: [
AppComponent, AppComponent,
SearchBarComponent, HomeComponent,
DataTableDemoComponent, DataTableDemoComponent,
SearchComponent, SearchComponent,
SearchBarComponent, SearchBarComponent,
LoginDemoComponent, LoginDemoComponent,
ActivitiDemoComponent, ActivitiDemoComponent,
ActivitiAppsView,
FormViewer, FormViewer,
WebscriptComponent, WebscriptComponent,
TagComponent, TagComponent,
+81 -12
View File
@@ -17,13 +17,16 @@
import { ModuleWithProviders } from '@angular/core'; import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router'; import { Routes, RouterModule } from '@angular/router';
import { AuthGuard, AuthGuardEcm, AuthGuardBpm } from 'ng2-alfresco-core';
import { import {
HomeComponent,
FilesComponent, FilesComponent,
DataTableDemoComponent, DataTableDemoComponent,
SearchComponent, SearchComponent,
LoginDemoComponent, LoginDemoComponent,
ActivitiDemoComponent, ActivitiDemoComponent,
ActivitiAppsView,
WebscriptComponent, WebscriptComponent,
TagComponent, TagComponent,
AboutComponent, AboutComponent,
@@ -35,19 +38,85 @@ import {
import { UploadButtonComponent } from 'ng2-alfresco-upload'; import { UploadButtonComponent } from 'ng2-alfresco-upload';
export const appRoutes: Routes = [ 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: 'login', component: LoginDemoComponent },
{ path: 'search', component: SearchComponent }, {
{ path: 'activiti', component: ActivitiDemoComponent }, path: '',
{ path: 'activiti/appId/:appId', component: ActivitiDemoComponent }, component: HomeComponent,
{ path: 'activiti/tasks/:id', component: FormViewer }, canActivate: [AuthGuard]
{ path: 'activiti/tasksnode/:id', component: FormNodeViewer }, },
{ path: 'webscript', component: WebscriptComponent }, {
{ path: 'tag', component: TagComponent }, 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: 'about', component: AboutComponent },
{ path: 'settings', component: SettingComponent } { path: 'settings', component: SettingComponent }
]; ];
@@ -19,10 +19,7 @@ import { Component, OnInit } from '@angular/core';
import { Http } from '@angular/http'; import { Http } from '@angular/http';
import { ObjectDataTableAdapter } from 'ng2-alfresco-datatable'; import { ObjectDataTableAdapter } from 'ng2-alfresco-datatable';
declare let __moduleName: string;
@Component({ @Component({
moduleId: __moduleName,
selector: 'about-page', selector: 'about-page',
templateUrl: './about.component.html' templateUrl: './about.component.html'
}) })
@@ -30,17 +27,29 @@ export class AboutComponent implements OnInit {
data: ObjectDataTableAdapter; data: ObjectDataTableAdapter;
constructor(private http: Http) {} constructor(private http: Http) {
}
ngOnInit() { ngOnInit() {
// this.data = new ObjectDataTableAdapter(); this.http.get('/versions.json').subscribe(response => {
this.http.get('/versions').subscribe(response => { var regexp = new RegExp("^(ng2-activiti|ng2-alfresco|alfresco-)", 'g');
let data = response.json() || {};
let packages = data.packages || [];
this.data = new ObjectDataTableAdapter(packages, [ var alfrescoPackages = Object.keys(response.json().dependencies).filter(function (val) {
{ type: 'text', key: 'name', title: 'Name', sortable: true }, console.log(val);
{ type: 'text', key: 'version', title: 'Version', sortable: true } 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}
]); ]);
}); });
@@ -10,7 +10,11 @@
.task-column { .task-column {
background-color: #f5f5f5; background-color: #f5f5f5;
padding: 10px 10px 10px 10px; 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 { .mdl-layout__header {
@@ -4,38 +4,31 @@
<!-- TABS --> <!-- TABS -->
<div class="mdl-layout__tab-bar mdl-js-ripple-effect" #tabheader> <div class="mdl-layout__tab-bar mdl-js-ripple-effect">
<a id="apps-header" href="#apps" class="mdl-layout__tab is-active">APPS</a> <a id="tasks-header" href="#tasks" class="mdl-layout__tab is-active">TASKS</a>
<a id="tasks-header" href="#tasks" class="mdl-layout__tab">TASK LIST</a> <a id="processes-header" href="#processes" class="mdl-layout__tab" (click)="activeProcess()">PROCESSES</a>
<a id="processes-header" href="#processes" class="mdl-layout__tab">PROCESS LIST</a> <a id="report-header" href="#report" class="mdl-layout__tab" (click)="activeReports()">REPORTS</a>
<a id="report-header" href="#report" class="mdl-layout__tab">ANALYTICS</a>
</div> </div>
</header> </header>
<main class="mdl-layout__content activiti" #tabmain> <main class="mdl-layout__content activiti">
<!-- APPPS COMPONENT -->
<section class="mdl-layout__tab-panel is-active" id="apps">
<div class="page-content">
<activiti-apps [layoutType]="layoutType" (appClick)="onAppClick($event)" #activitiapps></activiti-apps>
</div>
</section>
<!-- TASKS COMPONENT --> <!-- TASKS COMPONENT -->
<section class="mdl-layout__tab-panel" id="tasks"> <section class="mdl-layout__tab-panel is-active" id="tasks">
<div class="page-content"> <div class="page-content">
<div class="mdl-grid"> <div class="mdl-grid">
<div class="mdl-cell mdl-cell--2-col task-column mdl-shadow--2dp"> <div class="mdl-cell mdl-cell--2-col task-column mdl-shadow--2dp">
<span>Task Filters</span> <span><h5>Task Filters</h5></span>
<hr>
<activiti-start-task [appId]="appId" (onSuccess)="onStartTaskSuccess($event)"></activiti-start-task> <activiti-start-task [appId]="appId" (onSuccess)="onStartTaskSuccess($event)"></activiti-start-task>
<activiti-filters [appId]="appId" (filterClick)="onTaskFilterClick($event)" (onSuccess)="onSuccessTaskFilterList($event)" <activiti-filters [appId]="appId" (filterClick)="onTaskFilterClick($event)"
(onSuccess)="onSuccessTaskFilterList($event)"
#activitifilter></activiti-filters> #activitifilter></activiti-filters>
</div> </div>
<div class="mdl-cell mdl-cell--3-col task-column mdl-shadow--2dp"> <div class="mdl-cell mdl-cell--3-col task-column mdl-shadow--2dp list-column">
<span>Task List</span> <span><h5>Task List</h5></span>
<hr>
<activiti-tasklist *ngIf="taskFilter?.hasFilter()" [appId]="taskFilter.appId" <activiti-tasklist *ngIf="taskFilter?.hasFilter()" [appId]="taskFilter.appId"
[processDefinitionKey]="taskFilter.filter.processDefinitionKey" [processDefinitionKey]="taskFilter.filter.processDefinitionKey"
[name]="taskFilter.filter.name" [name]="taskFilter.filter.name"
@@ -47,7 +40,8 @@
#activititasklist></activiti-tasklist> #activititasklist></activiti-tasklist>
</div> </div>
<div class="mdl-cell mdl-cell--7-col task-column mdl-shadow--2dp"> <div class="mdl-cell mdl-cell--7-col task-column mdl-shadow--2dp">
<span>Task Details</span> <span><h5>Task Details</h5></span>
<hr>
<activiti-task-details [taskId]="currentTaskId" (formCompleted)="onFormCompleted($event)" <activiti-task-details [taskId]="currentTaskId" (formCompleted)="onFormCompleted($event)"
#activitidetails></activiti-task-details> #activitidetails></activiti-task-details>
</div> </div>
@@ -59,33 +53,41 @@
<!-- PROCESS COMPONENT --> <!-- PROCESS COMPONENT -->
<section class="mdl-layout__tab-panel" id="processes"> <section class="mdl-layout__tab-panel" id="processes">
<div class="page-content"> <div class="page-content" *ngIf="processTabActivie">
<div class="page-content"> <div class="page-content">
<div class="mdl-grid"> <div class="mdl-grid">
<div class="mdl-cell mdl-cell--2-col task-column"> <div class="mdl-cell mdl-cell--2-col task-column mdl-shadow--2dp">
<span>Process Filters</span> <span><h5>Process Filters</h5></span>
<button type="button" (click)="navigateStartProcess()" class="mdl-button" data-automation-id="btn-start-process">Start Process</button> <hr>
<button type="button" (click)="navigateStartProcess()" class="mdl-button"
data-automation-id="btn-start-process">Start Process
</button>
<activiti-process-instance-filters [appId]="appId" <activiti-process-instance-filters [appId]="appId"
(filterClick)="onProcessFilterClick($event)" (onSuccess)="onSuccessProcessFilterList($event)" (filterClick)="onProcessFilterClick($event)"
#activitiprocessfilter></activiti-process-instance-filters> (onSuccess)="onSuccessProcessFilterList($event)"></activiti-process-instance-filters>
</div> </div>
<div class="mdl-cell mdl-cell--3-col task-column"> <div class="mdl-cell mdl-cell--3-col task-column list-column mdl-shadow--2dp">
<span>Process List</span> <span><h5>Process List</h5></span>
<hr>
<activiti-process-instance-list *ngIf="processFilter?.hasFilter()" [appId]="processFilter.appId" <activiti-process-instance-list *ngIf="processFilter?.hasFilter()" [appId]="processFilter.appId"
[processDefinitionKey]="processFilter.filter.processDefinitionKey" [processDefinitionKey]="processFilter.filter.processDefinitionKey"
[name]="processFilter.filter.name" [name]="processFilter.filter.name"
[state]="processFilter.filter.state" [state]="processFilter.filter.state"
[sort]="processFilter.filter.sort" [sort]="processFilter.filter.sort"
[data]="dataProcesses" [data]="dataProcesses"
(rowClick)="onProcessRowClick($event)" (onSuccess)="onSuccessProcessList($event)" (rowClick)="onProcessRowClick($event)"
#activitiprocesslist></activiti-process-instance-list> (onSuccess)="onSuccessProcessList($event)"></activiti-process-instance-list>
</div> </div>
<div class="mdl-cell mdl-cell--7-col task-column" *ngIf="!isStartProcessMode()"> <div class="mdl-cell mdl-cell--7-col task-column mdl-shadow--2dp" *ngIf="!isStartProcessMode()">
<span>Process Details</span> <span><h5>Process Details</h5></span>
<activiti-process-instance-details [processInstanceId]="currentProcessInstanceId" (activitiprocesslist)="taskFormCompleted()" (processCancelled)="processCancelled()" #activitiprocessdetails></activiti-process-instance-details> <hr>
<activiti-process-instance-details [processInstanceId]="currentProcessInstanceId"
(activitiprocesslist)="taskFormCompleted()"
(processCancelled)="processCancelled()"></activiti-process-instance-details>
</div> </div>
<div class="mdl-cell mdl-cell--7-col task-column" *ngIf="isStartProcessMode()"> <div class="mdl-cell mdl-cell--7-col task-column" *ngIf="isStartProcessMode()">
<span>Start Process</span> <span>Start Process</span>
<hr>
<activiti-start-process [appId]="appId" (start)="onStartProcessInstance($event)"></activiti-start-process> <activiti-start-process [appId]="appId" (start)="onStartProcessInstance($event)"></activiti-start-process>
</div> </div>
</div> </div>
@@ -97,13 +99,22 @@
<!-- ANALYTICS COMPONENT --> <!-- ANALYTICS COMPONENT -->
<section class="mdl-layout__tab-panel" id="report"> <section class="mdl-layout__tab-panel" id="report">
<div class="page-content"> <div class="page-content" *ngIf="reportsTabActivie">
<div class="mdl-grid"> <div class="mdl-grid">
<div class="mdl-cell mdl-cell--4-col task-column mdl-shadow--2dp"> <div class="mdl-cell mdl-cell--4-col task-column mdl-shadow--2dp">
<analytics-report-list (reportClick)="onReportClick($event)"></analytics-report-list> <span><h5>Report List</h5></span>
<hr>
<analytics-report-list
(reportClick)="onReportClick($event)"
#analyticsreportlist>
</analytics-report-list>
</div> </div>
<div class="mdl-cell mdl-cell--8-col task-column mdl-shadow--2dp"> <div class="mdl-cell mdl-cell--8-col task-column mdl-shadow--2dp">
<activiti-analytics [appId]="appId" *ngIf="report" [reportId]="report.id"></activiti-analytics> <activiti-analytics *ngIf="report"
[appId]="appId"
[reportId]="report.id"
(editReport)="onEditReport($event)">
</activiti-analytics>
</div> </div>
</div> </div>
</div> </div>
@@ -15,70 +15,69 @@
* limitations under the License. * limitations under the License.
*/ */
import { Component, AfterViewChecked, ViewChild, Input } from '@angular/core'; import { AfterViewInit, Component, ElementRef, Input, ViewChild } from '@angular/core';
import { import {
AppDefinitionRepresentationModel,
FilterRepresentationModel,
ActivitiApps, ActivitiApps,
ActivitiTaskList ActivitiFilters,
ActivitiTaskDetails,
ActivitiTaskList,
FilterRepresentationModel
} from 'ng2-activiti-tasklist'; } from 'ng2-activiti-tasklist';
import { import {
ActivitiProcessFilters,
ActivitiProcessInstanceDetails,
ActivitiProcessInstanceListComponent, ActivitiProcessInstanceListComponent,
ActivitiStartProcessInstance, ActivitiStartProcessInstance,
ProcessInstance ProcessInstance
} from 'ng2-activiti-processlist'; } from 'ng2-activiti-processlist';
import { AnalyticsReportListComponent } from 'ng2-activiti-analytics';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { Subscription } from 'rxjs/Rx'; import { Subscription } from 'rxjs/Rx';
import { import {
ObjectDataTableAdapter, ObjectDataTableAdapter,
DataSorting DataSorting
} from 'ng2-alfresco-datatable'; } from 'ng2-alfresco-datatable';
import { AlfrescoApiService } from 'ng2-alfresco-core';
import { FormRenderingService } from 'ng2-activiti-form'; import { FormRenderingService } from 'ng2-activiti-form';
import { /*CustomEditorComponent*/ CustomStencil01 } from './custom-editor/custom-editor.component'; import { /*CustomEditorComponent*/ CustomStencil01 } from './custom-editor/custom-editor.component';
declare let __moduleName: string;
declare var componentHandler; declare var componentHandler;
const currentProcessIdNew = '__NEW__'; const currentProcessIdNew = '__NEW__';
@Component({ @Component({
moduleId: __moduleName,
selector: 'activiti-demo', selector: 'activiti-demo',
templateUrl: './activiti-demo.component.html', templateUrl: './activiti-demo.component.html',
styleUrls: ['./activiti-demo.component.css'] styleUrls: ['./activiti-demo.component.css']
}) })
export class ActivitiDemoComponent implements AfterViewChecked { export class ActivitiDemoComponent implements AfterViewInit {
@ViewChild('activitiapps') @ViewChild(ActivitiApps)
activitiapps: ActivitiApps; activitiapps: ActivitiApps;
@ViewChild('activitifilter') @ViewChild(ActivitiFilters)
activitifilter: any; activitifilter: ActivitiFilters;
@ViewChild('activitidetails')
activitidetails: any;
@ViewChild(ActivitiTaskList) @ViewChild(ActivitiTaskList)
activititasklist: ActivitiTaskList; activititasklist: ActivitiTaskList;
@ViewChild('activitiprocessfilter') @ViewChild(ActivitiTaskDetails)
activitiprocessfilter: any; activitidetails: ActivitiTaskDetails;
@ViewChild(ActivitiProcessFilters)
activitiprocessfilter: ActivitiProcessFilters;
@ViewChild(ActivitiProcessInstanceListComponent) @ViewChild(ActivitiProcessInstanceListComponent)
activitiprocesslist: ActivitiProcessInstanceListComponent; activitiprocesslist: ActivitiProcessInstanceListComponent;
@ViewChild('activitiprocessdetails') @ViewChild(ActivitiProcessInstanceDetails)
activitiprocessdetails: any; activitiprocessdetails: ActivitiProcessInstanceDetails;
@ViewChild(ActivitiStartProcessInstance) @ViewChild(ActivitiStartProcessInstance)
activitiStartProcess: ActivitiStartProcessInstance; activitiStartProcess: ActivitiStartProcessInstance;
@ViewChild('tabmain') @ViewChild(AnalyticsReportListComponent)
tabMain: any; analyticsreportlist: AnalyticsReportListComponent;
@ViewChild('tabheader')
tabHeader: any;
@Input() @Input()
appId: number; appId: number;
@@ -90,6 +89,10 @@ export class ActivitiDemoComponent implements AfterViewChecked {
taskSchemaColumns: any [] = []; taskSchemaColumns: any [] = [];
processSchemaColumns: any [] = []; processSchemaColumns: any [] = [];
processTabActivie: boolean = false;
reportsTabActivie: boolean = false;
taskFilter: FilterRepresentationModel; taskFilter: FilterRepresentationModel;
report: any; report: any;
processFilter: FilterRepresentationModel; processFilter: FilterRepresentationModel;
@@ -99,7 +102,10 @@ export class ActivitiDemoComponent implements AfterViewChecked {
dataTasks: ObjectDataTableAdapter; dataTasks: ObjectDataTableAdapter;
dataProcesses: 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( this.dataTasks = new ObjectDataTableAdapter(
[], [],
[ [
@@ -112,8 +118,8 @@ export class ActivitiDemoComponent implements AfterViewChecked {
this.dataProcesses = new ObjectDataTableAdapter( this.dataProcesses = new ObjectDataTableAdapter(
[], [],
[ [
{type: 'text', key: 'name', title: 'Name', cssClass: 'full-width name-column'}, {type: 'text', key: 'name', title: 'Name', cssClass: 'full-width name-column', sortable: true},
{type: 'text', key: 'started', title: 'Started', cssClass: 'hidden'} {type: 'text', key: 'started', title: 'Started', cssClass: 'hidden', sortable: true}
] ]
); );
@@ -126,7 +132,15 @@ export class ActivitiDemoComponent implements AfterViewChecked {
ngOnInit() { ngOnInit() {
this.sub = this.route.params.subscribe(params => { 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; this.layoutType = ActivitiApps.LAYOUT_GRID;
} }
@@ -135,25 +149,6 @@ export class ActivitiDemoComponent implements AfterViewChecked {
this.sub.unsubscribe(); 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) { onTaskFilterClick(event: FilterRepresentationModel) {
this.taskFilter = event; this.taskFilter = event;
} }
@@ -167,6 +162,8 @@ export class ActivitiDemoComponent implements AfterViewChecked {
} }
onStartTaskSuccess(event: any) { onStartTaskSuccess(event: any) {
this.activitifilter.selectFirstFilter();
this.taskFilter = this.activitifilter.getCurrentFilter();
this.activititasklist.reload(); this.activititasklist.reload();
} }
@@ -194,6 +191,10 @@ export class ActivitiDemoComponent implements AfterViewChecked {
this.currentProcessInstanceId = processInstanceId; this.currentProcessInstanceId = processInstanceId;
} }
onEditReport(name: string) {
this.analyticsreportlist.reload();
}
navigateStartProcess() { navigateStartProcess() {
this.currentProcessInstanceId = currentProcessIdNew; this.currentProcessInstanceId = currentProcessIdNew;
} }
@@ -201,6 +202,7 @@ export class ActivitiDemoComponent implements AfterViewChecked {
onStartProcessInstance(instance: ProcessInstance) { onStartProcessInstance(instance: ProcessInstance) {
this.currentProcessInstanceId = instance.id; this.currentProcessInstanceId = instance.id;
this.activitiStartProcess.reset(); this.activitiStartProcess.reset();
this.activitiprocesslist.reload();
} }
isStartProcessMode() { isStartProcessMode() {
@@ -225,11 +227,32 @@ export class ActivitiDemoComponent implements AfterViewChecked {
this.currentTaskId = null; this.currentTaskId = null;
} }
ngAfterViewChecked() { ngAfterViewInit() {
// workaround for MDL issues with dynamic components // workaround for MDL issues with dynamic components
if (componentHandler) { if (componentHandler) {
componentHandler.upgradeAllRegistered(); 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);
}
});
} }
} }
@@ -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: `
<activiti-apps (appClick)="onAppClicked($event)"></activiti-apps>
`
})
export class ActivitiAppsView {
constructor(private router: Router, private route: ActivatedRoute) {
}
onAppClicked(app: AppDefinitionRepresentationModel) {
this.router.navigate(['/activiti/apps', app.id || 0, 'tasks']);
}
}
@@ -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 { NgModule, Component } from '@angular/core';
import { WidgetComponent } from 'ng2-activiti-form'; import { WidgetComponent } from 'ng2-activiti-form';
@@ -19,11 +19,9 @@ import { Component, OnInit, OnDestroy, AfterViewChecked } from '@angular/core';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { Subscription } from 'rxjs/Rx'; import { Subscription } from 'rxjs/Rx';
declare let __moduleName: string;
declare var componentHandler; declare var componentHandler;
@Component({ @Component({
moduleId: __moduleName,
selector: 'form-node-viewer', selector: 'form-node-viewer',
templateUrl: './form-node-viewer.component.html', templateUrl: './form-node-viewer.component.html',
styleUrls: ['./form-node-viewer.component.css'] styleUrls: ['./form-node-viewer.component.css']
@@ -19,11 +19,9 @@ import { Component, OnInit, OnDestroy, AfterViewChecked } from '@angular/core';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { Subscription } from 'rxjs/Rx'; import { Subscription } from 'rxjs/Rx';
declare let __moduleName: string;
declare var componentHandler; declare var componentHandler;
@Component({ @Component({
moduleId: __moduleName,
selector: 'form-viewer', selector: 'form-viewer',
templateUrl: './form-viewer.component.html', templateUrl: './form-viewer.component.html',
styleUrls: ['./form-viewer.component.css'] styleUrls: ['./form-viewer.component.css']
@@ -23,10 +23,7 @@ import {
ObjectDataColumn ObjectDataColumn
} from 'ng2-alfresco-datatable'; } from 'ng2-alfresco-datatable';
declare let __moduleName: string;
@Component({ @Component({
moduleId: __moduleName,
selector: 'datatable-demo', selector: 'datatable-demo',
templateUrl: './datatable-demo.component.html' templateUrl: './datatable-demo.component.html'
}) })
@@ -7,3 +7,11 @@
margin: 0; margin: 0;
} }
} }
.error-message {
text-align: left;
}
.error-message--text {
color: #d50000;
}
@@ -1,191 +1,211 @@
<div *ngIf="!fileShowed"> <div class="container">
<div class="container"> <alfresco-upload-drag-area
<alfresco-upload-drag-area [rootFolderId]="uploadRootFolderId"
[currentFolderPath]="uploadFolderPath"
[versioning] = "versioning"
(onSuccess)="documentList.reload()">
<alfresco-document-list-breadcrumb
[currentFolderPath]="currentPath"
(pathChanged)="onBreadcrumbPathChanged($event)" *ngIf="!currentFolderId">
</alfresco-document-list-breadcrumb>
<div *ngIf="errorMessage" class="error-message">
<button (click)="resetError()" class="mdl-button mdl-js-button mdl-button--icon">
<i class="material-icons">highlight_off</i>
</button>
<span class="error-message--text">{{errorMessage}}</span>
</div>
<alfresco-document-list
#documentList
[rootFolderId]="rootFolderId"
[currentFolderPath]="currentPath" [currentFolderPath]="currentPath"
[versioning] = "versioning" [currentFolderId]="currentFolderId"
(onSuccess)="documentList.reload()"> [contextMenuActions]="true"
<alfresco-document-list-breadcrumb [contentActions]="true"
[currentFolderPath]="currentPath" (error)="onNavigationError($event)"
[target]="documentList"> (success)="resetError()"
</alfresco-document-list-breadcrumb> (preview)="showFile($event)"
<alfresco-document-list (folderChange)="onFolderChanged($event)">
#documentList <!--
[currentFolderPath]="currentPath" <empty-folder-content>
[contextMenuActions]="true" <template>
[contentActions]="true" <h1>Sorry, no content here</h1>
(preview)="showFile($event)" </template>
(folderChange)="onFolderChanged($event)"> </empty-folder-content>
-->
<content-columns>
<content-column key="$thumbnail" type="image"></content-column>
<content-column
title="{{'DOCUMENT_LIST.COLUMNS.DISPLAY_NAME' | translate}}"
key="name"
sortable="true"
class="full-width ellipsis-cell">
</content-column>
<!-- <!--
<empty-folder-content> <content-column
<template> title="Type"
<h1>Sorry, no content here</h1> source="content.mimeType">
</template> </content-column>
</empty-folder-content>
--> -->
<content-columns> <content-column
<content-column key="$thumbnail" type="image"></content-column> title="{{'DOCUMENT_LIST.COLUMNS.CREATED_BY' | translate}}"
<content-column key="createdByUser.displayName"
title="{{'DOCUMENT_LIST.COLUMNS.DISPLAY_NAME' | translate}}" sortable="true"
key="name" class="desktop-only">
sortable="true" </content-column>
class="full-width ellipsis-cell"> <content-column
</content-column> title="{{'DOCUMENT_LIST.COLUMNS.CREATED_ON' | translate}}"
<!-- key="createdAt"
<content-column type="date"
title="Type" format="medium"
source="content.mimeType"> sortable="true"
</content-column> class="desktop-only">
--> </content-column>
<content-column </content-columns>
title="{{'DOCUMENT_LIST.COLUMNS.CREATED_BY' | translate}}"
key="createdByUser.displayName"
sortable="true"
class="desktop-only">
</content-column>
<content-column
title="{{'DOCUMENT_LIST.COLUMNS.CREATED_ON' | translate}}"
key="createdAt"
type="date"
format="medium"
sortable="true"
class="desktop-only">
</content-column>
</content-columns>
<content-actions> <content-actions>
<!-- folder actions --> <!-- folder actions -->
<content-action <content-action
target="folder" target="folder"
title="{{'DOCUMENT_LIST.ACTIONS.FOLDER.SYSTEM_1' | translate}}" title="{{'DOCUMENT_LIST.ACTIONS.FOLDER.SYSTEM_1' | translate}}"
handler="system1"> handler="system1">
</content-action> </content-action>
<content-action <content-action
target="folder" target="folder"
title="{{'DOCUMENT_LIST.ACTIONS.FOLDER.CUSTOM' | translate}}" title="{{'DOCUMENT_LIST.ACTIONS.FOLDER.CUSTOM' | translate}}"
(execute)="myFolderAction1($event)"> (execute)="myFolderAction1($event)">
</content-action> </content-action>
<content-action <content-action
target="folder" target="folder"
title="{{'DOCUMENT_LIST.ACTIONS.FOLDER.DELETE' | translate}}" title="{{'DOCUMENT_LIST.ACTIONS.FOLDER.DELETE' | translate}}"
handler="delete"> handler="delete">
</content-action> </content-action>
<!-- document actions --> <!-- document actions -->
<content-action <content-action
target="document" target="document"
title="{{'DOCUMENT_LIST.ACTIONS.DOCUMENT.DOWNLOAD' | translate}}" title="{{'DOCUMENT_LIST.ACTIONS.DOCUMENT.DOWNLOAD' | translate}}"
handler="download"> handler="download">
</content-action> </content-action>
<content-action <content-action
target="document" target="document"
title="{{'DOCUMENT_LIST.ACTIONS.DOCUMENT.SYSTEM_2' | translate}}" title="{{'DOCUMENT_LIST.ACTIONS.DOCUMENT.SYSTEM_2' | translate}}"
handler="system2"> handler="system2">
</content-action> </content-action>
<content-action <content-action
target="document" target="document"
title="{{'DOCUMENT_LIST.ACTIONS.DOCUMENT.CUSTOM' | translate}}" title="{{'DOCUMENT_LIST.ACTIONS.DOCUMENT.CUSTOM' | translate}}"
(execute)="myCustomAction1($event)"> (execute)="myCustomAction1($event)">
</content-action> </content-action>
<content-action <content-action
target="document" target="document"
title="{{'DOCUMENT_LIST.ACTIONS.DOCUMENT.DELETE' | translate}}" title="{{'DOCUMENT_LIST.ACTIONS.DOCUMENT.DELETE' | translate}}"
handler="delete"> handler="delete">
</content-action> </content-action>
<content-action <content-action
target="folder" target="folder"
title="Activiti: View Form" title="Activiti: View Form"
(execute)="viewActivitiForm($event)"> (execute)="viewActivitiForm($event)">
</content-action> </content-action>
</content-actions> </content-actions>
</alfresco-document-list> </alfresco-document-list>
<alfresco-pagination <alfresco-pagination
[provider]="documentList.data" [provider]="documentList.data"
[supportedPageSizes]="[5, 10, 15, 20]"> [supportedPageSizes]="[5, 10, 15, 20]">
</alfresco-pagination> </alfresco-pagination>
</alfresco-upload-drag-area> </alfresco-upload-drag-area>
</div>
<context-menu-holder></context-menu-holder>
<div class="p-10">
<ul>
<li>Current path: {{documentList.currentFolderPath}}</li>
<li>
<button (click)="documentList.currentFolderPath = '/Sites/swsdp/documentLibrary';">Go to Document Library</button>
</li>
<li>
<button (click)="documentList.currentFolderPath = '/Sites/swsdp/documentLibrary/Agency Files/Contracts'">Go to agency contracts</button>
</li>
<li>
<button (click)="documentList.currentFolderPath = '/'">Go to root</button>
</li>
<li>
<button (click)="fileDialog.toggleShowDialog()">Show/Hide File Dialog</button>
</li>
</ul>
</div>
<p style="width:250px;margin: 20px;">
<label for="switch-multiple-file" class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
<input type="checkbox" id="switch-multiple-file" class="mdl-switch__input" (change)="toggleMultipleFileUpload()" >
<span class="mdl-switch__label">Multiple File Upload</span>
</label>
</p>
<p style="width:250px;margin: 20px;">
<label for="switch-folder-upload" class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
<input type="checkbox" id="switch-folder-upload" class="mdl-switch__input" (change)="toggleFolder()">
<span class="mdl-switch__label">Folder Upload</span>
</label>
</p>
<p style="width:250px;margin: 20px;">
<label for="switch-accepted-file-type" class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
<input type="checkbox" id="switch-accepted-file-type" class="mdl-switch__input" (change)="toggleAcceptedFilesType()">
<span class="mdl-switch__label">Filter extension</span>
</label>
</p>
<p style="width:250px;margin: 20px;">
<label for="switch-versioning" class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
<input type="checkbox" id="switch-versioning" class="mdl-switch__input" (change)="toggleVersioning()">
<span class="mdl-switch__label">Versioning</span>
</label>
</p>
<h5>Upload</h5>
<br>
<div *ngIf="acceptedFilesTypeShow">
<label class="mdl-input__label">Extension accepted
<input type="text" data-automation-id="accepted-files-type" [(ngModel)]="acceptedFilesType">
</label>
<br/>
</div>
<div *ngIf="!acceptedFilesTypeShow">
<alfresco-upload-button data-automation-id="multiple-file-upload"
[currentFolderPath]="currentPath"
[multipleFiles]="multipleFileUpload"
[uploadFolders]="folderUpload"
[versioning] = "versioning"
(onSuccess)="documentList.reload()">
<div class="mdl-spinner mdl-js-spinner is-active"></div>
</alfresco-upload-button>
</div>
<div *ngIf="acceptedFilesTypeShow">
<alfresco-upload-button data-automation-id="multiple-file-upload"
[currentFolderPath]="currentPath"
acceptedFilesType="{{acceptedFilesType}}"
[multipleFiles]="multipleFileUpload"
[uploadFolders]="folderUpload"
[versioning] = "versioning"
(onSuccess)="documentList.reload()">
<div class="mdl-spinner mdl-js-spinner is-active"></div>
</alfresco-upload-button>
</div>
<file-uploading-dialog #fileDialog></file-uploading-dialog>
</div> </div>
<context-menu-holder></context-menu-holder>
<div class="p-10">
<ul>
<li>Current path: {{currentPath}}</li>
<li>
<button (click)="currentPath = '/'">Go to root</button>
</li>
<li>
<button (click)="currentPath = '/Sites'">Go to Sites</button>
</li>
<li>
<button (click)="currentPath = '/Sites/swsdp';">Go to Web Site Design Project site</button>
</li>
<li>
<button (click)="currentPath = '/Sites/swsdp/documentLibrary';">Go to Document Library</button>
</li>
<li>
<button (click)="currentPath = '/Sites/swsdp/documentLibrary/Agency Files/Contracts'">Go to Agency Contracts</button>
</li>
<li>
<button (click)="currentPath = '!@£$%^&*()'">Go to the wrong path</button>
</li>
<li>
<button (click)="fileDialog.toggleShowDialog()">Show/Hide File Dialog</button>
</li>
</ul>
</div>
<p style="width:250px;margin: 20px;">
<label for="switch-multiple-file" class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
<input type="checkbox" id="switch-multiple-file" class="mdl-switch__input" (change)="toggleMultipleFileUpload()" >
<span class="mdl-switch__label">Multiple File Upload</span>
</label>
</p>
<p style="width:250px;margin: 20px;">
<label for="switch-folder-upload" class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
<input type="checkbox" id="switch-folder-upload" class="mdl-switch__input" (change)="toggleFolder()">
<span class="mdl-switch__label">Folder Upload</span>
</label>
</p>
<p style="width:250px;margin: 20px;">
<label for="switch-accepted-file-type" class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
<input type="checkbox" id="switch-accepted-file-type" class="mdl-switch__input" (change)="toggleAcceptedFilesType()">
<span class="mdl-switch__label">Filter extension</span>
</label>
</p>
<p style="width:250px;margin: 20px;">
<label for="switch-versioning" class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
<input type="checkbox" id="switch-versioning" class="mdl-switch__input" (change)="toggleVersioning()">
<span class="mdl-switch__label">Versioning</span>
</label>
</p>
<h5>Upload</h5>
<br>
<div *ngIf="acceptedFilesTypeShow">
<label class="mdl-input__label">Extension accepted
<input type="text" data-automation-id="accepted-files-type" [(ngModel)]="acceptedFilesType">
</label>
<br/>
</div>
<div *ngIf="!acceptedFilesTypeShow">
<alfresco-upload-button data-automation-id="multiple-file-upload"
[rootFolderId]="uploadRootFolderId"
[currentFolderPath]="uploadFolderPath"
[multipleFiles]="multipleFileUpload"
[uploadFolders]="folderUpload"
[versioning] = "versioning"
(onSuccess)="documentList.reload()">
<div class="mdl-spinner mdl-js-spinner is-active"></div>
</alfresco-upload-button>
</div>
<div *ngIf="acceptedFilesTypeShow">
<alfresco-upload-button data-automation-id="multiple-file-upload"
[rootFolderId]="uploadRootFolderId"
[currentFolderPath]="uploadFolderPath"
acceptedFilesType="{{acceptedFilesType}}"
[multipleFiles]="multipleFileUpload"
[uploadFolders]="folderUpload"
[versioning] = "versioning"
(onSuccess)="documentList.reload()">
<div class="mdl-spinner mdl-js-spinner is-active"></div>
</alfresco-upload-button>
</div>
<file-uploading-dialog #fileDialog></file-uploading-dialog>
<div *ngIf="fileShowed"> <div *ngIf="fileShowed">
<alfresco-viewer [(showViewer)]="fileShowed" <alfresco-viewer [(showViewer)]="fileShowed"
[fileNodeId]="fileNodeId" [fileNodeId]="fileNodeId"
@@ -15,8 +15,8 @@
* limitations under the License. * limitations under the License.
*/ */
import { Component, OnInit, ViewChild } from '@angular/core'; import { Component, OnInit, Optional, ViewChild } from '@angular/core';
import { Router } from '@angular/router'; import { ActivatedRoute, Params, Router } from '@angular/router';
import { AlfrescoAuthenticationService } from 'ng2-alfresco-core'; import { AlfrescoAuthenticationService } from 'ng2-alfresco-core';
import { import {
DocumentActionsService, DocumentActionsService,
@@ -27,17 +27,17 @@ import {
} from 'ng2-alfresco-documentlist'; } from 'ng2-alfresco-documentlist';
import { FormService } from 'ng2-activiti-form'; import { FormService } from 'ng2-activiti-form';
declare let __moduleName: string;
@Component({ @Component({
moduleId: __moduleName,
selector: 'files-component', selector: 'files-component',
templateUrl: './files.component.html', templateUrl: './files.component.html',
styleUrls: ['./files.component.css'] styleUrls: ['./files.component.css']
}) })
export class FilesComponent implements OnInit { export class FilesComponent implements OnInit {
currentPath: string = '/Sites/swsdp/documentLibrary'; currentPath: string = '/Sites/swsdp/documentLibrary';
rootFolderId: string = '-root-';
currentFolderId: string = null;
errorMessage: string = null;
fileNodeId: any; fileNodeId: any;
fileShowed: boolean = false; fileShowed: boolean = false;
multipleFileUpload: boolean = false; multipleFileUpload: boolean = false;
@@ -47,13 +47,22 @@ export class FilesComponent implements OnInit {
acceptedFilesType: string = '.jpg,.pdf,.js'; acceptedFilesType: string = '.jpg,.pdf,.js';
get uploadRootFolderId(): string {
return this.currentFolderId || this.rootFolderId;
}
get uploadFolderPath(): string {
return this.currentFolderId ? '/' : this.currentPath;
}
@ViewChild(DocumentList) @ViewChild(DocumentList)
documentList: DocumentList; documentList: DocumentList;
constructor(private documentActions: DocumentActionsService, constructor(private documentActions: DocumentActionsService,
public auth: AlfrescoAuthenticationService, public auth: AlfrescoAuthenticationService,
private formService: FormService, private formService: FormService,
private router: Router) { private router: Router,
@Optional() private route: ActivatedRoute) {
documentActions.setHandler('my-handler', this.myDocumentActionHandler.bind(this)); documentActions.setHandler('my-handler', this.myDocumentActionHandler.bind(this));
} }
@@ -84,6 +93,12 @@ export class FilesComponent implements OnInit {
} }
} }
onBreadcrumbPathChanged(event?: any) {
if (event) {
this.currentPath = event.value;
}
}
toggleMultipleFileUpload() { toggleMultipleFileUpload() {
this.multipleFileUpload = !this.multipleFileUpload; this.multipleFileUpload = !this.multipleFileUpload;
return this.multipleFileUpload; return this.multipleFileUpload;
@@ -106,20 +121,35 @@ export class FilesComponent implements OnInit {
} }
ngOnInit() { ngOnInit() {
if ( this.auth.isBpmLoggedIn() ) { if (this.route) {
this.formService.getProcessDefinitions().subscribe( this.route.params.forEach((params: Params) => {
defs => this.setupBpmActions(defs || []), this.currentFolderId = params.hasOwnProperty('id') ? params['id'] : null;
err => console.log(err) });
); }
} else { if (this.auth.isBpmLoggedIn()) {
console.log('You are not logged in'); this.formService.getProcessDefinitions().subscribe(
} defs => this.setupBpmActions(defs || []),
err => console.log(err)
);
} else {
console.log('You are not logged in');
}
} }
viewActivitiForm(event?: any) { viewActivitiForm(event?: any) {
this.router.navigate(['/activiti/tasksnode', event.value.entry.id]); 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[]) { private setupBpmActions(actions: any[]) {
actions.map(def => { actions.map(def => {
let documentAction = new DocumentActionModel(); let documentAction = new DocumentActionModel();
@@ -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;
}
@@ -0,0 +1,187 @@
<!-- DOCUMENT LIST-->
<div class="demo-card-square mdl-card mdl-shadow--2dp home-cards">
<div class="mdl-card__title mdl-card--expand" routerLink="/files">
<h2 class="mdl-card__title-text">
<i class="material-icons home--card__icon">dvr</i>
<span>DocumentList - ECM</span>
</h2>
</div>
<div class="mdl-card__supporting-text">
Demonstrates multiple Alfresco ECM components used together to show the files of you ECM instance :
<ul class="home--feature-list">
<li>
<i class="material-icons home--feature-list__icon">brightness_1</i>
<span class="home--feature-list__text">Comunication with the Rest Api and core services</span>
<a href="https://www.npmjs.com/package/ng2-alfresco-core" target="_blank">ng2-alfresco-core</a>
</li>
<li>
<i class="material-icons home--feature-list__icon">dvr</i>
<span class="home--feature-list__text">Document List</span>
<a href="https://www.npmjs.com/package/ng2-alfresco-documentlist" target="_blank">ng2-alfresco-documentlist</a>
</li>
<li>
<i class="material-icons home--feature-list__icon">file_upload</i>
<span class="home--feature-list__text">Upload</span>
<a href="https://www.npmjs.com/package/ng2-alfresco-upload" target="_blank">ng2-alfresco-upload</a>
</li>
<li>
<i class="material-icons home--feature-list__icon">view_module</i>
<span class="home--feature-list__text">DataTable</span>
<a href="https://www.npmjs.com/package/ng2-alfresco-datatable" target="_blank">ng2-alfresco-datatable</a>
</li>
</ul>
</div>
</div>
<!-- ACTIVITI-->
<div class="demo-card-square mdl-card mdl-shadow--2dp home-cards">
<div class="mdl-card__title mdl-card--expand" routerLink="/activiti">
<h2 class="mdl-card__title-text">
<i class="material-icons home--card__icon">apps</i>
<span>Activiti - BPM</span>
</h2>
</div>
<div class="mdl-card__supporting-text">
Demonstrates multiple Alfresco BPM components used together to show your BPM prorcess and tasks:
<ul class="home--feature-list">
<li>
<i class="material-icons home--feature-list__icon">brightness_1</i>
<span class="home--feature-list__text">Comunication with the Rest Api and core services</span>
<a href="https://www.npmjs.com/package/ng2-alfresco-core" target="_blank">ng2-alfresco-core</a>
</li>
<li>
<i class="material-icons home--feature-list__icon">view_module</i>
<span class="home--feature-list__text">App List</span>
<a href="https://www.npmjs.com/package/ng2-activiti-tasklist" target="_blank">ng2-activiti-apps</a>
</li>
<li>
<i class="material-icons home--feature-list__icon">view_headline</i>
<span class="home--feature-list__text">Task List</span>
<a href="https://www.npmjs.com/package/ng2-activiti-tasklist" target="_blank">ng2-activiti-tasklist</a>
</li>
<li>
<i class="material-icons home--feature-list__icon">view_headline</i>
<span class="home--feature-list__text">Process List</span>
<a href="https://www.npmjs.com/package/ng2-activiti-processlist" target="_blank">ng2-activiti-processlist</a>
</li>
<li>
<i class="material-icons home--feature-list__icon">view_quilt</i>
<span class="home--feature-list__text">Form</span>
<a href="https://www.npmjs.com/package/ng2-activiti-form" target="_blank">ng2-activiti-form</a>
</li>
<li>
<i class="material-icons home--feature-list__icon">pie_chart</i>
<span class="home--feature-list__text">Analytics</span>
<a href="https://www.npmjs.com/package/ng2-activiti-analytics" target="_blank">ng2-activiti-analytics</a>,
<a href="https://www.npmjs.com/package/ng2-activiti-diagrams" target="_blank">ng2-activiti-diagrams</a>
</li>
<li>
<i class="material-icons home--feature-list__icon">view_module</i>
<span class="home--feature-list__text">DataTable</span>
<a href="https://www.npmjs.com/package/ng2-alfresco-datatable" target="_blank">ng2-alfresco-datatable</a>
</li>
</ul>
</div>
</div>
<!-- DATATABLE-->
<div class="demo-card-square mdl-card mdl-shadow--2dp home-cards">
<div class="mdl-card__title mdl-card--expand" routerLink="/datatable">
<h2 class="mdl-card__title-text">
<i class="material-icons home--card__icon">view_module</i>
<span>DataTable-ECM&BPM</span>
</h2>
</div>
<div class="mdl-card__supporting-text">
Basic table component:
<ul class="home--feature-list">
<li>
<i class="material-icons home--feature-list__icon">brightness_1</i>
<span class="home--feature-list__text">Comunication with the Rest Api and core services</span>
<a href="https://www.npmjs.com/package/ng2-alfresco-core" target="_blank">ng2-alfresco-core</a>
</li>
</ul>
</div>
</div>
<!-- UPLOADER-->
<div class="demo-card-square mdl-card mdl-shadow--2dp home-cards">
<div class="mdl-card__title mdl-card--expand" routerLink="/uploader">
<h2 class="mdl-card__title-text">
<i class="material-icons home--card__icon">file_upload</i>
<span>Uploader - ECM</span>
</h2>
</div>
<div class="mdl-card__supporting-text">
Basic table uploader component for the ECM and BPM:
<ul class="home--feature-list">
<li>
<i class="material-icons home--feature-list__icon">brightness_1</i>
<span class="home--feature-list__text">Comunication with the Rest Api and core services</span>
<a href="https://www.npmjs.com/package/ng2-alfresco-core" target="_blank">ng2-alfresco-core</a>
</li>
</ul>
</div>
</div>
<!-- LOGIN-->
<div class="demo-card-square mdl-card mdl-shadow--2dp home-cards">
<div class="mdl-card__title mdl-card--expand" routerLink="/login">
<h2 class="mdl-card__title-text">
<i class="material-icons home--card__icon">account_circle</i>
<span>Login - ECM & BPM</span>
</h2>
</div>
<div class="mdl-card__supporting-text">
Login component for the ECM and BPM:
<ul class="home--feature-list">
<li>
<i class="material-icons home--feature-list__icon">brightness_1</i>
<span class="home--feature-list__text">Comunication with the Rest Api and core services</span>
<a href="https://www.npmjs.com/package/ng2-alfresco-core" target="_blank">ng2-alfresco-core</a>
</li>
</ul>
</div>
</div>
<!-- WEBSCRIPT-->
<div class="demo-card-square mdl-card mdl-shadow--2dp home-cards">
<div class="mdl-card__title mdl-card--expand" routerLink="/webscript">
<h2 class="mdl-card__title-text">
<i class="material-icons home--card__icon">extension</i>
<span>Webscript - ECM</span>
</h2>
</div>
<div class="mdl-card__supporting-text">
Shows and create webscripts in your ECM instance:
<ul class="home--feature-list">
<li>
<i class="material-icons home--feature-list__icon">brightness_1</i>
<span class="home--feature-list__text">Comunication with the Rest Api and core services</span>
<a href="https://www.npmjs.com/package/ng2-alfresco-core" target="_blank">ng2-alfresco-core</a>
</li>
</ul>
</div>
</div>
<!-- TAG-->
<div class="demo-card-square mdl-card mdl-shadow--2dp home-cards">
<div class="mdl-card__title mdl-card--expand" routerLink="/tag">
<h2 class="mdl-card__title-text">
<i class="material-icons home--card__icon">local_offer</i>
<span>Tag - ECM</span>
</h2>
</div>
<div class="mdl-card__supporting-text">
Shows and add tags to the node of your ECM instance:
<ul class="home--feature-list">
<li>
<i class="material-icons home--feature-list__icon">brightness_1</i>
<span class="home--feature-list__text">Comunication with Rest</span>
<a href="https://www.npmjs.com/package/ng2-alfresco-core" target="_blank">ng2-alfresco-core</a>
</li>
</ul>
</div>
</div>
@@ -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');
});
});
@@ -15,9 +15,11 @@
* limitations under the License. * limitations under the License.
*/ */
declare let moment: any; import { Component } from '@angular/core';
declare let mdDateTimePicker: any;
// MDL @Component({
declare let componentHandler: any; selector: 'home-view',
declare let dialogPolyfill: any; templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent {}
+2
View File
@@ -15,6 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
export { HomeComponent } from './home/home.component';
export { DataTableDemoComponent } from './datatable/datatable-demo.component'; export { DataTableDemoComponent } from './datatable/datatable-demo.component';
export { SearchComponent } from './search/search.component'; export { SearchComponent } from './search/search.component';
export { SearchBarComponent } from './search/search-bar.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 { FilesComponent } from './files/files.component';
export { FormNodeViewer } from './activiti/form-node-viewer.component'; export { FormNodeViewer } from './activiti/form-node-viewer.component';
export { SettingComponent } from './setting/setting.component'; export { SettingComponent } from './setting/setting.component';
export { ActivitiAppsView } from './activiti/apps.view';
@@ -1,14 +1,39 @@
.setting { .setting-button {
border-radius: 8px; position: absolute; background-color: papayawhip; color: cadetblue; left: 10px; top: 10px; z-index: 1; 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 { .toggle {
width:120px;margin: 20px; width: 120px;
margin: 20px;
} }
.setting-button { @media (min-width: 721px) {
position: absolute; right: 10px; top: 10px; z-index: 1; .mobile-settings {
display: none;
}
} }
@media (max-width: 720px) {
.settings {
display: none;
}
}
@@ -1,21 +1,23 @@
<div class="setting"> <!--BPM, ECN AND CSRF TOGGLE-->
<div class="settings">
<p class="toggle"> <p class="toggle">
<label for="switch1" class="mdl-switch mdl-js-switch mdl-js-ripple-effect"> <label for="switch1" class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
<input type="checkbox" id="switch1" [checked]="isECM" class="mdl-switch__input" <input type="checkbox" id="switch1" [checked]="isECM" class="mdl-switch__input"
(click)="toggleECM(ecm.checked)" #ecm> (click)="toggleECM()">
<span class="mdl-switch__label">ECM</span> <span class="mdl-switch__label">ECM</span>
</label> </label>
</p> </p>
<p class="toggle"> <p class="toggle">
<label for="switch2" class="mdl-switch mdl-js-switch mdl-js-ripple-effect"> <label for="switch2" class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
<input type="checkbox" id="switch2" [checked]="isBPM" class="mdl-switch__input" <input type="checkbox" id="switch2" [checked]="isBPM" class="mdl-switch__input"
(click)="toggleBPM(bpm.checked)" #bpm> (click)="toggleBPM()">
<span class="mdl-switch__label">BPM</span> <span class="mdl-switch__label">BPM</span>
</label> </label>
</p> </p>
<p class="toggle"> <p class="toggle">
<label for="switch3" class="mdl-switch mdl-js-switch mdl-js-ripple-effect"> <label for="switch3" class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
<input type="checkbox" id="switch3" class="mdl-switch__input" checked (click)="toggleCSRF()" #csrf> <input type="checkbox" id="switch3" class="mdl-switch__input" [checked]="!disableCsrf" (click)="toggleCSRF()">
<span class="mdl-switch__label">CSRF</span> <span class="mdl-switch__label">CSRF</span>
</label> </label>
</p> </p>
@@ -25,12 +27,47 @@
</p> </p>
</div> </div>
<!--SETTING BUTTON-->
<a class="mdl-navigation__link setting-button" data-automation-id="settings" href="" routerLink="/settings"> <a class="mdl-navigation__link setting-button" data-automation-id="settings" href="" routerLink="/settings">
<button class="mdl-button mdl-js-button mdl-button--fab mdl-button--colored"> <button class="mdl-button mdl-js-button mdl-button--fab mdl-button--colored">
<i class="material-icons">settings</i> <i class="material-icons">settings</i>
</button> </button>
</a> </a>
<alfresco-login [providers]="providers" [fieldsValidation]="customValidation" [disableCsrf]="disableCsrf"
<!--LOGIN-->
<alfresco-login #alfrescologin
[providers]="providers"
[fieldsValidation]="customValidation"
[disableCsrf]="disableCsrf"
(executeSubmit)="validateForm($event)" (executeSubmit)="validateForm($event)"
(onSuccess)="onLogin($event)" (onSuccess)="onLogin($event)"
(onError)="onError($event)" #alfrescologin></alfresco-login> (onError)="onError($event)">
<div class="mobile-settings">
<p>
<label for="switch1-mobile" class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
<input type="checkbox" id="switch1-mobile" [checked]="isECM" class="mdl-switch__input"
(click)="toggleECM()">
<span class="mdl-switch__label">ECM</span>
</label>
</p>
<p>
<label for="switch2-mobile" class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
<input type="checkbox" id="switch2-mobile" [checked]="isBPM" class="mdl-switch__input"
(click)="toggleBPM()">
<span class="mdl-switch__label">BPM</span>
</label>
</p>
<p>
<label for="switch3-mobile" class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
<input type="checkbox" id="switch3-mobile" class="mdl-switch__input" [checked]="!disableCsrf" (click)="toggleCSRF()">
<span class="mdl-switch__label">CSRF</span>
</label>
</p>
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
<input class="mdl-textfield__input" type="text" [(ngModel)]="blackListUsername" id="blacklistusername"/>
<label class="mdl-textfield__label" for="blacklistusername">Banned username</label>
</div>
</div>
</alfresco-login>
@@ -18,11 +18,9 @@
import { Component, ViewChild, OnInit } from '@angular/core'; import { Component, ViewChild, OnInit } from '@angular/core';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { Validators } from '@angular/forms'; import { Validators } from '@angular/forms';
import { StorageService } from 'ng2-alfresco-core';
declare let __moduleName: string;
@Component({ @Component({
moduleId: __moduleName,
selector: 'login-demo', selector: 'login-demo',
templateUrl: './login-demo.component.html', templateUrl: './login-demo.component.html',
styleUrls: ['./login-demo.component.css'] styleUrls: ['./login-demo.component.css']
@@ -33,14 +31,14 @@ export class LoginDemoComponent implements OnInit {
alfrescologin: any; alfrescologin: any;
providers: string = 'ECM'; providers: string = 'ECM';
disableCsrf: boolean = false;
blackListUsername: string; blackListUsername: string;
customValidation: any; customValidation: any;
disableCsrf: boolean = false;
isECM: boolean = true; isECM: boolean = true;
isBPM: boolean = false; isBPM: boolean = false;
constructor(public router: Router) { constructor(public router: Router, private storage: StorageService) {
this.customValidation = { this.customValidation = {
username: ['', Validators.compose([Validators.required, Validators.minLength(4)])], username: ['', Validators.compose([Validators.required, Validators.minLength(4)])],
password: ['', Validators.required] password: ['', Validators.required]
@@ -52,14 +50,14 @@ export class LoginDemoComponent implements OnInit {
this.alfrescologin.addCustomValidationError('username', 'minlength', 'LOGIN.MESSAGES.USERNAME-MIN'); this.alfrescologin.addCustomValidationError('username', 'minlength', 'LOGIN.MESSAGES.USERNAME-MIN');
this.alfrescologin.addCustomValidationError('password', 'required', 'LOGIN.MESSAGES.PASSWORD-REQUIRED'); this.alfrescologin.addCustomValidationError('password', 'required', 'LOGIN.MESSAGES.PASSWORD-REQUIRED');
if (localStorage.getItem('providers')) { if (this.storage.hasItem('providers')) {
this.providers = localStorage.getItem('providers'); this.providers = this.storage.getItem('providers');
} }
this.setProviders(); this.initProviders();
} }
setProviders() { initProviders() {
if (this.providers === 'BPM') { if (this.providers === 'BPM') {
this.isECM = false; this.isECM = false;
this.isBPM = true; this.isBPM = true;
@@ -80,38 +78,40 @@ export class LoginDemoComponent implements OnInit {
console.log($event); console.log($event);
} }
toggleECM(checked) { toggleECM() {
if (checked && this.providers === 'BPM') { this.isECM = !this.isECM;
this.providers = 'ALL'; this.storage.setItem('providers', this.updateProvider());
} 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);
} }
toggleBPM(checked) { toggleBPM() {
if (checked && this.providers === 'ECM') { this.isBPM = !this.isBPM;
this.providers = 'ALL'; this.storage.setItem('providers', this.updateProvider());
} 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);
} }
toggleCSRF() { toggleCSRF() {
this.disableCsrf = !this.disableCsrf; 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) { validateForm(event: any) {
let values = event.values; let values = event.values;
if (values.controls['username'].value === this.blackListUsername) { if (values.controls['username'].value === this.blackListUsername) {
@@ -1,14 +1,13 @@
<alfresco-search-control *ngIf="isLoggedIn()" <alfresco-search-control *ngIf="isLoggedIn()"
[searchTerm]="searchTerm" [searchTerm]="searchTerm"
[autocomplete]="false" [autocomplete]="false"
[liveSearchResultType]="'cm:content'"
(searchSubmit)="onSearchSubmit($event);" (searchSubmit)="onSearchSubmit($event);"
(searchChange)="onSearchTermChange($event);" (searchChange)="onSearchTermChange($event);"
(expand)="onExpandToggle($event);" (expand)="onExpandToggle($event);"
(fileSelect)="onFileClicked($event)"> (fileSelect)="onItemClicked($event)">
</alfresco-search-control> </alfresco-search-control>
<alfresco-viewer [(showViewer)]="fileShowed" <alfresco-viewer *ngIf="fileShowed" [(showViewer)]="fileShowed"
[fileNodeId]="fileNodeId" [fileNodeId]="fileNodeId"
[overlayMode]="true"> [overlayMode]="true">
<div class="mdl-spinner mdl-js-spinner is-active"></div> <div class="mdl-spinner mdl-js-spinner is-active"></div>
@@ -18,11 +18,9 @@
import { Component, EventEmitter, Output } from '@angular/core'; import { Component, EventEmitter, Output } from '@angular/core';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { AlfrescoAuthenticationService } from 'ng2-alfresco-core'; import { AlfrescoAuthenticationService } from 'ng2-alfresco-core';
import { MinimalNodeEntity } from 'alfresco-js-api';
declare let __moduleName: string;
@Component({ @Component({
moduleId: __moduleName,
selector: 'search-bar', selector: 'search-bar',
templateUrl: './search-bar.component.html' templateUrl: './search-bar.component.html'
}) })
@@ -54,10 +52,12 @@ export class SearchBarComponent {
}]); }]);
} }
onFileClicked(event) { onItemClicked(event: MinimalNodeEntity) {
if (event.value.entry.isFile) { if (event.entry.isFile) {
this.fileNodeId = event.value.entry.id; this.fileNodeId = event.entry.id;
this.fileShowed = true; this.fileShowed = true;
} else if (event.entry.isFolder) {
this.router.navigate(['/files', event.entry.id]);
} }
} }
@@ -1,8 +1,8 @@
<div class="search-results-container"> <div class="search-results-container">
<h1>Search results</h1> <h1>Search results</h1>
<alfresco-search [resultType]="'cm:content'" (preview)="onFileClicked($event)"></alfresco-search> <alfresco-search (navigate)="onNavigateItem($event)"></alfresco-search>
</div> </div>
<alfresco-viewer [(showViewer)]="fileShowed" [fileNodeId]="fileNodeId" [overlayMode]="true"> <alfresco-viewer *ngIf="fileShowed" [(showViewer)]="fileShowed" [fileNodeId]="fileNodeId" [overlayMode]="true">
<div class="mdl-spinner mdl-js-spinner is-active"></div> <div class="mdl-spinner mdl-js-spinner is-active"></div>
</alfresco-viewer> </alfresco-viewer>
@@ -16,11 +16,10 @@
*/ */
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { Router } from '@angular/router';
declare let __moduleName: string; import { MinimalNodeEntity } from 'alfresco-js-api';
@Component({ @Component({
moduleId: __moduleName,
selector: 'search-component', selector: 'search-component',
templateUrl: './search.component.html', templateUrl: './search.component.html',
styles: [` styles: [`
@@ -51,10 +50,15 @@ export class SearchComponent {
fileShowed: boolean = false; fileShowed: boolean = false;
fileNodeId: string; fileNodeId: string;
onFileClicked(event) { constructor(public router: Router) {
if (event.value.entry.isFile) { }
this.fileNodeId = event.value.entry.id;
onNavigateItem(event: MinimalNodeEntity) {
if (event.entry.isFile) {
this.fileNodeId = event.entry.id;
this.fileShowed = true; this.fileShowed = true;
} else if (event.entry.isFolder) {
this.router.navigate(['/files', event.entry.id]);
} }
} }
} }
@@ -24,6 +24,11 @@
tabindex="1" (change)="onChangeBPMHost($event)" value="{{bpmHost}}"/> tabindex="1" (change)="onChangeBPMHost($event)" value="{{bpmHost}}"/>
</nav> </nav>
</div> </div>
<div class="mdl-card__actions mdl-card--border">
<a class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect" onclick="window.history.back()" >
Back
</a>
</div>
</div> </div>
<div class="setting-card-padding"></div> <div class="setting-card-padding"></div>
</div> </div>
@@ -16,14 +16,9 @@
*/ */
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { import { AlfrescoSettingsService, StorageService } from 'ng2-alfresco-core';
AlfrescoSettingsService
} from 'ng2-alfresco-core';
declare let __moduleName: string;
@Component({ @Component({
moduleId: __moduleName,
selector: 'alfresco-setting-demo', selector: 'alfresco-setting-demo',
templateUrl: './setting.component.html', templateUrl: './setting.component.html',
styleUrls: ['./setting.component.css'] styleUrls: ['./setting.component.css']
@@ -33,7 +28,8 @@ export class SettingComponent {
ecmHost: string; ecmHost: string;
bpmHost: string; bpmHost: string;
constructor(public alfrescoSettingsService: AlfrescoSettingsService) { constructor(public alfrescoSettingsService: AlfrescoSettingsService,
private storage: StorageService) {
this.ecmHost = this.alfrescoSettingsService.ecmHost; this.ecmHost = this.alfrescoSettingsService.ecmHost;
this.bpmHost = this.alfrescoSettingsService.bpmHost; this.bpmHost = this.alfrescoSettingsService.bpmHost;
} }
@@ -42,14 +38,14 @@ export class SettingComponent {
console.log((<HTMLInputElement>event.target).value); console.log((<HTMLInputElement>event.target).value);
this.ecmHost = (<HTMLInputElement>event.target).value; this.ecmHost = (<HTMLInputElement>event.target).value;
this.alfrescoSettingsService.ecmHost = this.ecmHost; this.alfrescoSettingsService.ecmHost = this.ecmHost;
localStorage.setItem(`ecmHost`, this.ecmHost); this.storage.setItem(`ecmHost`, this.ecmHost);
} }
public onChangeBPMHost(event: KeyboardEvent): void { public onChangeBPMHost(event: KeyboardEvent): void {
console.log((<HTMLInputElement>event.target).value); console.log((<HTMLInputElement>event.target).value);
this.bpmHost = (<HTMLInputElement>event.target).value; this.bpmHost = (<HTMLInputElement>event.target).value;
this.alfrescoSettingsService.bpmHost = this.bpmHost; this.alfrescoSettingsService.bpmHost = this.bpmHost;
localStorage.setItem(`bpmHost`, this.bpmHost); this.storage.setItem(`bpmHost`, this.bpmHost);
} }
} }
-372
View File
@@ -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<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: 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;
};
+5
View File
@@ -16,7 +16,12 @@
*/ */
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module'; import { AppModule } from './app.module';
if (process.env.ENV === 'production') {
enableProdMode();
}
const platform = platformBrowserDynamic(); const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule); platform.bootstrapModule(AppModule);
+16
View File
@@ -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');
}
+60
View File
@@ -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');
+7
View File
@@ -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;
+21
View File
@@ -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());
+37
View File
@@ -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);
};
+5
View File
@@ -0,0 +1,5 @@
module.exports = function(source) {
this.cacheable();
console.log(this.resource);
return source;
}
+27
View File
@@ -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;
}
+213
View File
@@ -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
}
};
+66
View File
@@ -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'
}
});
+101
View File
@@ -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
}
])
]
});
+70
View File
@@ -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
}
}
+35 -52
View File
@@ -5,69 +5,52 @@
<title>Demo Application - Angular 2</title> <title>Demo Application - Angular 2</title>
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<link href="app/css/app.css" rel="stylesheet">
<link href="app/css/muli-font.css" rel="stylesheet">
<link rel="icon" type="image/png" href="favicon-96x96.png" sizes="96x96"> <link rel="icon" type="image/png" href="favicon-96x96.png" sizes="96x96">
<!-- Google Material Design Lite -->
<link href="./assets/material.orange-blue.min.css" rel="stylesheet">
<script src="node_modules/material-design-lite/material.min.js"></script>
<link href="node_modules/material-design-icons/iconfont/material-icons.css" rel="stylesheet">
<link href="node_modules/flag-icon-css/css/flag-icon.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Roboto:regular,bold,italic,thin,light,bolditalic,black,medium&amp;lang=en" rel="stylesheet" type="text/css">
<link href="node_modules/md-date-time-picker/dist/css/mdDateTimePicker.css" media="all" rel="stylesheet">
<!-- 1. Load libraries --> <!-- 1. Load libraries -->
<!-- Polyfill(s) for Safari (pre-10.x) --> <!-- Polyfill(s) for Safari (pre-10.x) -->
<script src="node_modules/intl/dist/Intl.min.js"></script> <script src=js/Intl.min.js></script>
<script src="node_modules/intl/locale-data/jsonp/en.js"></script>
<!-- Polyfill(s) for older browsers --> <!--[if IE]>
<script src="node_modules/core-js/client/shim.min.js"></script> <script src=js/shim.min.js></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/dom4/1.8.3/dom4.js"></script> <script src=//cdnjs.cloudflare.com/ajax/libs/dom4/1.8.3/dom4.js></script>
<script src="node_modules/element.scrollintoviewifneeded-polyfill/index.js"></script> <script src=js/element.scrollintoviewifneeded-polyfill.js></script>
<script src=js/classlist-polyfill.js></script>
<script src=js/web-animations.min.js></script>
<script src=js/typedarray.js></script>
<script src=js/Blob.js></script>
<script src=js/formdata.js></script>
<script src=https://npmcdn.com/angular2/es6/dev/src/testing/shims_for_IE.js></script>
<script src=js/es5-shim.min.js></script>
<script src=js/es6-shim.min.js></script>
<script src=js/system-polyfills.js></script>
<![endif]-->
<!-- Polyfill(s) for dialogs --> <!-- Google Material Design Lite -->
<script src="node_modules/dialog-polyfill/dialog-polyfill.js"></script> <link href="css/material.orange-blue.min.css" rel="stylesheet">
<link href="node_modules/dialog-polyfill/dialog-polyfill.css" rel="stylesheet" type="text/css" /> <script src="js/material.min.js"></script>
<link href="css/iconfont/material-icons.css" rel="stylesheet">
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="node_modules/moment/min/moment.min.js"></script> <style>
<script src="/app/js/Polyline.js"></script> .main_header_adf .mdl-layout__drawer-button {
<script src="node_modules/pdfjs-dist/web/compatibility.js"></script> right: 0 !important;
<script src="node_modules/pdfjs-dist/build/pdf.js"></script> left: initial !important;
<script src="node_modules/pdfjs-dist/build/pdf.worker.js"></script> left: auto;
<script src="node_modules/pdfjs-dist/web/pdf_viewer.js"></script>
<script src="node_modules/chart.js/dist/Chart.bundle.min.js"></script>
<script src="node_modules/raphael/raphael.min.js"></script>
<script src="node_modules/md-date-time-picker/dist/js/mdDateTimePicker.min.js"></script>
<script src="node_modules/md-date-time-picker/dist/js/draggabilly.pkgd.min.js"></script>
<!-- Stencils integration --> }
<script src="node_modules/ng2-activiti-form/stencils/runtime.ng1.js"></script> </style>
<script src="node_modules/ng2-activiti-form/stencils/runtime.adf.js"></script>
<script src="http://localhost:9999/activiti-app/app/rest/script-files/controllers"></script>
<!-- 2. Configure SystemJS -->
<script src="systemjs.config.js"></script>
<script>
System.import('app').catch(function(err){ console.error(err); });
</script>
</head> </head>
<!-- 3. Display the application --> <!-- 3. Display the application -->
<body> <body>
<alfresco-app> <alfresco-app>
<div id="loader-container" class="loader-container"> <div id="loader-container" class="loader-container">
<div class="loader-item"> <div class="loader-item">
<div id="loader-spin" class="mdl-progress mdl-js-progress mdl-progress__indeterminate"></div> <div id="loader-spin" class="mdl-progress mdl-js-progress mdl-progress__indeterminate"></div>
<div id="loader-text" class="loader-text">Loading Demo Shell..</div> <div id="loader-text" class="loader-text">Loading Demo Shell..</div>
</div > </div >
</div> </div>
</alfresco-app> </alfresco-app>
</body> </body>
</html> </html>
+1
View File
@@ -0,0 +1 @@
module.exports = require('./config/karma.conf.js');
+71 -45
View File
@@ -1,18 +1,17 @@
{ {
"name": "Alfresco-Angular2-Demo", "name": "Alfresco-Angular2-Demo",
"description": "Demo shell for Alfresco Angular2 components", "description": "Demo shell for Alfresco Angular2 components",
"version": "0.5.0", "version": "1.0.0",
"author": "Alfresco Software, Ltd.", "author": "Alfresco Software, Ltd.",
"scripts": { "scripts": {
"clean": "npm install rimraf && rimraf dist node_modules typings", "clean": "npm install rimraf && npm run clean-build && rimraf dist node_modules typings dist",
"build": "npm run tslint && npm run tsc && npm run licensecheck", "start": "npm run server-versions && webpack-dev-server --inline --progress --port 3000 --max_old_space_size=4096 --max_new_space_size=4096",
"start": "npm run build && npm run serve", "start:dist": "wsrv -s dist/ -p 3000 -a 0.0.0.0",
"start:dev": "npm run build && concurrently \"npm run tsc:w\" \"npm run serve:dev\" ", "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", "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'", "tslint": "tslint -c tslint.json *.ts && tslint -c tslint.json 'app/{,**/}**.ts'",
"licensecheck": "license-check" "licensecheck": "license-check"
}, },
@@ -53,61 +52,88 @@
"alfresco" "alfresco"
], ],
"dependencies": { "dependencies": {
"@angular/common": "2.0.0", "@angular/common": "2.2.2",
"@angular/compiler": "2.0.0", "@angular/compiler": "2.2.2",
"@angular/core": "2.0.0", "@angular/compiler-cli": "2.2.2",
"@angular/forms": "2.0.0", "@angular/core": "2.2.2",
"@angular/http": "2.0.0", "@angular/forms": "2.2.2",
"@angular/platform-browser": "2.0.0", "@angular/http": "2.2.2",
"@angular/platform-browser-dynamic": "2.0.0", "@angular/platform-browser": "2.2.2",
"@angular/router": "3.0.0", "@angular/platform-browser-dynamic": "2.2.2",
"@angular/upgrade": "2.0.0", "@angular/router": "3.2.2",
"@types/node": "^6.0.42", "@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", "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", "zone.js": "^0.6.23",
"rimraf": "2.5.2",
"material-design-icons": "2.2.3", "material-design-icons": "2.2.3",
"material-design-lite": "1.2.1", "material-design-lite": "1.2.1",
"ng2-translate": "2.5.0", "ng2-translate": "2.5.0",
"pdfjs-dist": "1.5.404", "pdfjs-dist": "1.5.404",
"flag-icon-css": "2.3.0", "flag-icon-css": "2.3.0",
"intl": "1.2.4",
"moment": "2.15.1", "moment": "2.15.1",
"chart.js": "^2.1.4", "chart.js": "^2.1.4",
"ng2-charts": "1.1.0", "ng2-charts": "1.1.0",
"raphael": "^2.2.6", "raphael": "^2.2.6",
"md-date-time-picker": "^2.2.0", "md-date-time-picker": "^2.2.0",
"alfresco-js-api": "^0.5.0", "alfresco-js-api": "^1.0.0",
"ng2-activiti-analytics": "0.5.0", "ng2-activiti-analytics": "1.0.0",
"ng2-alfresco-core": "0.5.0", "ng2-alfresco-core": "1.0.0",
"ng2-alfresco-datatable": "0.5.0", "ng2-alfresco-datatable": "1.0.0",
"ng2-alfresco-documentlist": "0.5.0", "ng2-alfresco-documentlist": "1.0.0",
"ng2-alfresco-login": "0.5.0", "ng2-alfresco-login": "1.0.0",
"ng2-alfresco-search": "0.5.0", "ng2-alfresco-search": "1.0.0",
"ng2-alfresco-upload": "0.5.0", "ng2-alfresco-upload": "1.0.0",
"ng2-alfresco-viewer": "0.5.0", "ng2-alfresco-viewer": "1.0.0",
"ng2-activiti-form": "0.5.0", "ng2-activiti-form": "1.0.0",
"ng2-activiti-tasklist": "0.5.0", "ng2-activiti-tasklist": "1.0.0",
"ng2-alfresco-userinfo": "0.5.0", "ng2-alfresco-userinfo": "1.0.0",
"ng2-activiti-processlist": "0.5.0", "ng2-activiti-processlist": "1.0.0",
"ng2-alfresco-webscript": "0.5.0", "ng2-alfresco-webscript": "1.0.0",
"ng2-alfresco-tag": "0.5.0", "ng2-alfresco-tag": "1.0.0",
"dialog-polyfill": "^0.4.3", "dialog-polyfill": "^0.4.3",
"element.scrollintoviewifneeded-polyfill": "^1.0.1" "element.scrollintoviewifneeded-polyfill": "^1.0.1"
}, },
"devDependencies": { "devDependencies": {
"@types/core-js": "^0.9.32", "@types/jasmine": "^2.5.35",
"@types/jasmine": "^2.2.33", "@types/node": "^6.0.45",
"concurrently": "^2.2.0", "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", "license-check": "1.1.5",
"mime": "^1.3.4", "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", "tslint": "3.15.1",
"typescript": "^2.0.3", "typescript": "2.0.3",
"wsrv": "^0.1.5" "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": { "license-check-config": {
"src": [ "src": [
+211
View File
@@ -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));
+37
View File
@@ -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);
@@ -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.__list__.length?this.__nextIndex__++:void this._unBind()},configurable:!0,enumerable:!1,writable:!0},next:{value:function(){return this._createResult(this._next())},configurable:!0,enumerable:!1,writable:!0},_createResult:{value:function(e){return void 0===e?{done:!0,value:void 0}:{done:!1,value:this._resolve(e)}},configurable:!0,enumerable:!1,writable:!0},_resolve:{value:function(e){return this.__list__[e]},configurable:!0,enumerable:!1,writable:!0},_unBind:{value:function(){this.__list__=null,delete this.__redo__,this.__context__&&(this.__context__.off("_add",this._onAdd.bind(this)),this.__context__.off("_delete",this._onDelete.bind(this)),this.__context__.off("_clear",this._onClear.bind(this)),this.__context__=null)},configurable:!0,enumerable:!1,writable:!0},toString:{value:function(){return"[object Iterator]"},configurable:!0,enumerable:!1,writable:!0}},{_onAdd:{value:function(e){if(!(e>=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 || {});
File diff suppressed because it is too large Load Diff
-42
View File
@@ -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'
};
-76
View File
@@ -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);
+4 -7
View File
@@ -1,19 +1,16 @@
{ {
"compilerOptions": { "compilerOptions": {
"target": "es5", "target": "es5",
"module": "system", "module": "commonjs",
"moduleResolution": "node", "moduleResolution": "node",
"sourceMap": true, "sourceMap": true,
"emitDecoratorMetadata": true, "emitDecoratorMetadata": true,
"experimentalDecorators": true, "experimentalDecorators": true,
"removeComments": false, "lib": ["es2015", "dom"],
"noImplicitAny": false, "noImplicitAny": false,
"types": ["core-js", "jasmine"] "suppressImplicitAnyIndexErrors": true
}, },
"exclude": [ "exclude": [
"dist", "node_modules"
"node_modules",
"typings/main",
"typings/main.d.ts"
] ]
} }
+2 -2
View File
@@ -55,7 +55,7 @@
"no-eval": true, "no-eval": true,
"no-inferrable-types": false, "no-inferrable-types": false,
"no-internal-module": true, "no-internal-module": true,
"no-require-imports": true, "no-require-imports": false,
"no-shadowed-variable": true, "no-shadowed-variable": true,
"no-switch-case-fall-through": true, "no-switch-case-fall-through": true,
"no-trailing-whitespace": true, "no-trailing-whitespace": true,
@@ -64,7 +64,7 @@
"no-unused-variable": true, "no-unused-variable": true,
"no-use-before-declare": true, "no-use-before-declare": true,
"no-var-keyword": true, "no-var-keyword": true,
"no-var-requires": true, "no-var-requires": false,
"object-literal-sort-keys": false, "object-literal-sort-keys": false,
"one-line": [ "one-line": [
true, true,
+1
View File
@@ -0,0 +1 @@
module.exports = require('./config/webpack.dev.js');
-14
View File
@@ -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}"
]
}
@@ -6,10 +6,14 @@ coverage
dist dist
src/**/*.js src/**/*.js
src/**/*.js.map src/**/*.js.map
src/**/*.d.ts
demo/**/*.js demo/**/*.js
demo/**/*.js.map demo/**/*.js.map
demo/**/*.d.ts demo/**/*.d.ts
index.js index.js
index.js.map index.js.map
!systemjs.config.js !systemjs.config.js
*.tgz
/package/
/bundles/
index.d.ts
@@ -2,14 +2,15 @@ npm-debug.log
.idea .idea
coverage/ coverage/
demo/
node_modules node_modules
typings/ typings/
fonts/ fonts/
/.editorconfig /.editorconfig
/.travis.yml /.travis.yml
/*.js
/*.json /*.json
/*.ts /karma-test-shim.js
/*.js.map /karma.conf.js
/gulpfile.ts
/.npmignore /.npmignore
@@ -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
@@ -5,15 +5,16 @@
"author": "Alfresco Software, Ltd.", "author": "Alfresco Software, Ltd.",
"main": "index.js", "main": "index.js",
"scripts": { "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", "postinstall": "npm run build",
"start": "npm run build && concurrently \"npm run tsc:w\" \"npm run server\" ", "start": "npm run build && concurrently \"npm run tsc:w\" \"npm run server\" ",
"server": "wsrv -o -s -l", "server": "wsrv -o -s -l",
"build": "npm run tslint && rimraf dist && tsc", "build": "npm run tslint && npm run clean-build && npm run tsc",
"build:w": "npm run tslint && rimraf dist && tsc -w", "build:w": "npm run tslint && rimraf dist && npm run tsc:w",
"tsc": "tsc", "tsc": "tsc",
"tsc:w": "tsc -w", "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", "license": "Apache-2.0",
"contributors": [ "contributors": [
@@ -30,41 +31,40 @@
"activiti-diagrams" "activiti-diagrams"
], ],
"dependencies": { "dependencies": {
"@angular/common": "2.0.0", "@angular/common": "2.2.2",
"@angular/compiler": "2.0.0", "@angular/compiler": "2.2.2",
"@angular/core": "2.0.0", "@angular/compiler-cli": "2.2.2",
"@angular/forms": "2.0.0", "@angular/core": "2.2.2",
"@angular/http": "2.0.0", "@angular/forms": "2.2.2",
"@angular/platform-browser": "2.0.0", "@angular/http": "2.2.2",
"@angular/platform-browser-dynamic": "2.0.0", "@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", "core-js": "^2.4.1",
"reflect-metadata": "^0.1.3", "reflect-metadata": "^0.1.3",
"rxjs": "5.0.0-beta.12", "rxjs": "5.0.0-beta.12",
"systemjs": "0.19.27", "systemjs": "0.19.27",
"zone.js": "^0.6.23", "zone.js": "^0.6.23",
"intl": "1.2.4", "intl": "1.2.4",
"dialog-polyfill": "^0.4.3", "dialog-polyfill": "^0.4.3",
"element.scrollintoviewifneeded-polyfill": "^1.0.1", "element.scrollintoviewifneeded-polyfill": "^1.0.1",
"material-design-icons": "2.2.3", "material-design-icons": "2.2.3",
"material-design-lite": "1.2.1", "material-design-lite": "1.2.1",
"chart.js": "^2.1.4", "chart.js": "^2.1.4",
"md-date-time-picker": "^2.2.0", "md-date-time-picker": "^2.2.0",
"ng2-charts": "1.1.0", "ng2-charts": "1.1.0",
"moment": "2.15.1", "moment": "2.15.1",
"raphael": "^2.2.6", "raphael": "^2.2.6",
"ng2-translate": "2.5.0", "ng2-translate": "2.5.0",
"alfresco-js-api": "^0.5.0", "alfresco-js-api": "^1.0.0",
"ng2-alfresco-core": "0.5.0", "ng2-alfresco-core": "1.0.0",
"ng2-activiti-diagrams": "0.5.0", "ng2-activiti-diagrams": "1.0.0",
"ng2-activiti-analytics": "^0.5.0" "ng2-activiti-analytics": "^1.0.0"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^6.0.42",
"@types/core-js": "^0.9.32",
"@types/jasmine": "^2.2.33", "@types/jasmine": "^2.2.33",
"@types/node": "^6.0.42",
"concurrently": "^2.2.0", "concurrently": "^2.2.0",
"rimraf": "2.5.2", "rimraf": "2.5.2",
"tslint": "^3.8.1", "tslint": "^3.8.1",
@@ -18,7 +18,7 @@
import { NgModule, Component, OnInit } from '@angular/core'; import { NgModule, Component, OnInit } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser'; import { BrowserModule } from '@angular/platform-browser';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 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'; import { AnalyticsModule } from 'ng2-activiti-analytics';
@Component({ @Component({
@@ -60,7 +60,9 @@ export class AnalyticsDemoComponent implements OnInit {
ticket: string; ticket: string;
constructor(private authService: AlfrescoAuthenticationService, private settingsService: AlfrescoSettingsService) { constructor(private authService: AlfrescoAuthenticationService,
private settingsService: AlfrescoSettingsService,
private storage: StorageService) {
settingsService.bpmHost = this.host; settingsService.bpmHost = this.host;
settingsService.setProviders('BPM'); settingsService.setProviders('BPM');
@@ -74,7 +76,7 @@ export class AnalyticsDemoComponent implements OnInit {
} }
public updateTicket(): void { public updateTicket(): void {
localStorage.setItem('ticket-BPM', this.ticket); this.storage.setItem('ticket-BPM', this.ticket);
} }
public updateHost(): void { public updateHost(): void {
@@ -11,7 +11,7 @@
// map tells the System loader where to look for things // map tells the System loader where to look for things
map: { map: {
// our app is within the app folder // our app is within the app folder
app: 'dist', app: 'src',
// angular bundles // angular bundles
'@angular/core': 'npm:@angular/core/bundles/core.umd.js', '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
'@angular/common': 'npm:@angular/common/bundles/common.umd.js', '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
@@ -27,9 +27,9 @@
'ng2-charts': 'npm:ng2-charts', 'ng2-charts': 'npm:ng2-charts',
'ng2-translate': 'npm:ng2-translate', 'ng2-translate': 'npm:ng2-translate',
'alfresco-js-api': 'npm:alfresco-js-api/dist', 'alfresco-js-api': 'npm:alfresco-js-api/dist',
'ng2-alfresco-core': 'npm:ng2-alfresco-core/dist', 'ng2-alfresco-core': 'npm:ng2-alfresco-core',
'ng2-activiti-diagrams': 'npm:ng2-activiti-diagrams/dist', 'ng2-activiti-diagrams': 'npm:ng2-activiti-diagrams',
'ng2-activiti-analytics': 'npm:ng2-activiti-analytics/dist' 'ng2-activiti-analytics': 'npm:ng2-activiti-analytics'
}, },
// packages tells the System loader how to load when no filename and/or no extension // packages tells the System loader how to load when no filename and/or no extension
packages: { packages: {
@@ -40,6 +40,7 @@
rxjs: { rxjs: {
defaultExtension: 'js' defaultExtension: 'js'
}, },
'moment': 'npm:moment/min/moment.min.js',
'ng2-translate': { defaultExtension: 'js' }, 'ng2-translate': { defaultExtension: 'js' },
'ng2-charts': { main: 'ng2-charts.js', defaultExtension: 'js'}, 'ng2-charts': { main: 'ng2-charts.js', defaultExtension: 'js'},
'alfresco-js-api': { main: './alfresco-js-api.js', defaultExtension: 'js'}, 'alfresco-js-api': { main: './alfresco-js-api.js', defaultExtension: 'js'},
@@ -3,11 +3,10 @@
"target": "es5", "target": "es5",
"module": "commonjs", "module": "commonjs",
"moduleResolution": "node", "moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true, "emitDecoratorMetadata": true,
"experimentalDecorators": true, "experimentalDecorators": true,
"sourceMap": true, "skipLibCheck": true,
"removeComments": true,
"declaration": true,
"noLib": false, "noLib": false,
"allowUnreachableCode": false, "allowUnreachableCode": false,
"allowUnusedLabels": false, "allowUnusedLabels": false,
@@ -15,12 +14,19 @@
"noImplicitReturns": false, "noImplicitReturns": false,
"noImplicitUseStrict": false, "noImplicitUseStrict": false,
"noFallthroughCasesInSwitch": true, "noFallthroughCasesInSwitch": true,
"outDir": "dist", "removeComments": true,
"types": ["core-js", "jasmine", "node"] "declaration": true,
"lib": [
"es2015",
"dom"
],
"suppressImplicitAnyIndexErrors": true
}, },
"exclude": [ "exclude": [
"demo", "node_modules"
"node_modules", ],
"dist" "angularCompilerOptions": {
] "strictMetadataEmit": false,
"skipTemplateCodegen": true
}
} }
+312
View File
@@ -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)) {
(<any>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 = <any>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));
@@ -5,7 +5,7 @@ jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000;
__karma__.loaded = function() {}; __karma__.loaded = function() {};
var builtPath = '/base/dist/'; var builtPath = '/base/src/';
function isJsFile(path) { function isJsFile(path) {
return path.slice(-3) == '.js'; return path.slice(-3) == '.js';
@@ -29,7 +29,7 @@ var paths = {
}; };
var map = { var map = {
'app': 'base/dist', 'app': 'base/src',
// angular bundles // angular bundles
'@angular/core': 'npm:@angular/core/bundles/core.umd.js', '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
'@angular/common': 'npm:@angular/common/bundles/common.umd.js', '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
@@ -57,9 +57,8 @@ var map = {
'moment' : 'npm:moment/min/moment.min.js', 'moment' : 'npm:moment/min/moment.min.js',
'alfresco-js-api': 'npm:alfresco-js-api/dist', 'alfresco-js-api': 'npm:alfresco-js-api/dist',
'ng2-activiti-analytics': 'npm:ng2-activiti-analytics/dist', 'ng2-activiti-diagrams': 'npm:ng2-activiti-diagrams',
'ng2-activiti-diagrams': 'npm:ng2-activiti-diagrams/dist', 'ng2-alfresco-core': 'npm:ng2-alfresco-core'
'ng2-alfresco-core': 'npm:ng2-alfresco-core/dist'
}; };
var packages = { var packages = {
@@ -71,7 +70,6 @@ var packages = {
'moment': { defaultExtension: 'js' }, 'moment': { defaultExtension: 'js' },
'alfresco-js-api': { main: './alfresco-js-api.js', 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-activiti-diagrams': { main: './index.js', defaultExtension: 'js'},
'ng2-alfresco-core': { main: './index.js', defaultExtension: 'js'} 'ng2-alfresco-core': { main: './index.js', defaultExtension: 'js'}
}; };
@@ -24,8 +24,8 @@ module.exports = function (config) {
'node_modules/zone.js/dist/fake-async-test.js', 'node_modules/zone.js/dist/fake-async-test.js',
// RxJs // RxJs
{pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false}, { pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false },
{pattern: 'node_modules/rxjs/**/*.js.map', included: false, watched: false}, { pattern: 'node_modules/rxjs/**/*.js.map', included: false, watched: false },
// Paths loaded via module imports: // Paths loaded via module imports:
// Angular itself // Angular itself
@@ -41,20 +41,25 @@ module.exports = function (config) {
'karma-test-shim.js', 'karma-test-shim.js',
// paths loaded via module imports // paths loaded via module imports
{pattern: 'dist/**/*.js', included: false, watched: true}, {pattern: 'src/**/*.js', included: false, watched: true},
{pattern: 'dist/**/*.html', included: true, served: true, watched: true}, {pattern: 'src/**/*.html', included: true, served: true, watched: true},
{pattern: 'dist/**/*.css', included: true, served: true, watched: true}, {pattern: 'src/**/*.css', included: true, served: true, watched: true},
// ng2-components // 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-activiti-diagrams/dist/**/*.*', 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/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/md-date-time-picker/**/*.js', included: false, served: true, watched: false },
{ pattern: 'node_modules/moment/**/*.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 // paths to support debugging with source maps in dev tools
{pattern: 'src/**/*.ts', included: false, watched: false}, {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: [ exclude: [
@@ -102,7 +107,7 @@ module.exports = function (config) {
// Source files that you wanna generate coverage for. // Source files that you wanna generate coverage for.
// Do not include tests or libraries (these files will be instrumented by Istanbul) // Do not include tests or libraries (these files will be instrumented by Istanbul)
preprocessors: { preprocessors: {
'dist/**/!(*spec|index|*mock|*model).js': 'coverage' 'src/**/!(*spec|index|*mock|*model).js': 'coverage'
}, },
coverageReporter: { coverageReporter: {
@@ -1,28 +1,30 @@
{ {
"name": "ng2-activiti-analytics", "name": "ng2-activiti-analytics",
"description": "Activiti Angular2 Analytics Component", "description": "Activiti Angular2 Analytics Component",
"version": "0.5.0", "version": "1.0.0",
"author": "Alfresco Software, Ltd.", "author": "Alfresco Software, Ltd.",
"main": "./dist/index.js",
"typings": "./dist/index.d.ts",
"scripts": { "scripts": {
"clean": "npm install rimraf && rimraf dist node_modules typings", "clean": "npm install rimraf && npm run clean-build && rimraf dist node_modules typings",
"build": "npm run tslint && rimraf dist && tsc && npm run copy-dist && license-check", "clean-build": "rimraf index.js index.js.map index.d.ts'src/{,**/}**.js' 'src/{,**/}**.js.map' 'src/{,**/}**.d.ts' bundles",
"build:w": "npm run tslint && rimraf dist && npm run watch-task", "build": "npm run clean-build && npm run tslint && rimraf dist && tsc && license-check && npm run build.umd",
"watch-task": "concurrently \"npm run tsc:w\" \"npm run copy-dist:w\" \"license-check\"", "build:w": "npm run clean-build && npm run tslint && rimraf dist && tsc:w && license-check npm run build.umd",
"tslint": "tslint -c tslint.json *.ts && tslint -c tslint.json 'src/{,**/}**.ts'", "tslint": "tslint -c tslint.json 'src/{,**/}**.ts' 'index.ts' -e '{,**/}**.d.ts' -e './gulpfile.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",
"tsc": "tsc", "tsc": "tsc",
"tsc:w": "tsc -w", "tsc:w": "tsc -w",
"pretest": "npm run build", "pretest": "npm run build",
"test": "karma start karma.conf.js --reporters mocha,coverage --single-run", "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", "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", "coverage": "npm run test && wsrv -o -p 9875 ./coverage/report",
"prepublish": "npm run build", "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": [ "contributors": [
{ {
"name": "Mario Romano", "name": "Mario Romano",
@@ -41,6 +43,7 @@
"url": "https://github.com/Alfresco/alfresco-ng2-components/issues" "url": "https://github.com/Alfresco/alfresco-ng2-components/issues"
}, },
"dependencies": { "dependencies": {
"@angular/router": "3.0.0",
"@angular/common": "2.0.0", "@angular/common": "2.0.0",
"@angular/compiler": "2.0.0", "@angular/compiler": "2.0.0",
"@angular/core": "2.0.0", "@angular/core": "2.0.0",
@@ -53,36 +56,53 @@
"rxjs": "5.0.0-beta.12", "rxjs": "5.0.0-beta.12",
"systemjs": "0.19.27", "systemjs": "0.19.27",
"zone.js": "^0.6.23", "zone.js": "^0.6.23",
"chart.js": "^2.1.4", "chart.js": "^2.1.4",
"md-date-time-picker": "^2.2.0", "md-date-time-picker": "^2.2.0",
"ng2-charts": "1.1.0", "ng2-charts": "1.1.0",
"moment": "2.15.1", "moment": "2.15.1",
"raphael": "^2.2.6", "raphael": "^2.2.6",
"alfresco-js-api": "^1.0.0",
"alfresco-js-api": "^0.5.0",
"ng2-translate": "2.5.0", "ng2-translate": "2.5.0",
"ng2-alfresco-core": "0.5.0", "ng2-alfresco-core": "1.0.0",
"ng2-activiti-diagrams": "0.5.0" "ng2-activiti-diagrams": "1.0.0"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^6.0.42",
"@types/core-js": "^0.9.32",
"@types/jasmine": "^2.2.33", "@types/jasmine": "^2.2.33",
"@types/node": "^6.0.42",
"concurrently": "^2.2.0", "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-core": "2.4.1", "jasmine-core": "2.4.1",
"karma": "0.13.22", "karma": "0.13.22",
"karma-chrome-launcher": "1.0.1", "karma-chrome-launcher": "1.0.1",
"karma-coverage": "1.0.0", "karma-coverage": "1.0.0",
"karma-jasmine": "1.0.2", "karma-jasmine": "1.0.2",
"karma-jasmine-ajax": "^0.1.13", "karma-jasmine-ajax": "^0.1.13",
"karma-mocha-reporter": "2.0.3",
"karma-jasmine-html-reporter": "0.2.0", "karma-jasmine-html-reporter": "0.2.0",
"karma-mocha-reporter": "2.0.3",
"license-check": "1.1.5", "license-check": "1.1.5",
"remap-istanbul": "0.6.3", "remap-istanbul": "0.6.3",
"rimraf": "2.5.2", "rimraf": "2.5.2",
"run-sequence": "^1.2.2",
"systemjs-builder": "^0.15.34",
"traceur": "0.0.91", "traceur": "0.0.91",
"ts-node": "^1.7.0",
"tslint": "3.15.1", "tslint": "3.15.1",
"typescript": "^2.0.3", "typescript": "^2.0.3",
"wsrv": "^0.1.5" "wsrv": "^0.1.5"
@@ -93,7 +113,7 @@
], ],
"license-check-config": { "license-check-config": {
"src": [ "src": [
"./dist/**/*.js" "./src/**/*.js"
], ],
"path": "assets/license_header.txt", "path": "assets/license_header.txt",
"blocking": true, "blocking": true,
@@ -1,9 +1,9 @@
<h2>Process Heat map</h2> <h4>Process Heat map</h4>
<div *ngIf="hasMetric()"> <div *ngIf="hasMetric()">
<form [formGroup]="metricForm" novalidate> <form [formGroup]="metricForm" novalidate>
<dropdown-widget [field]="field" [group]="metricForm.controls.metricGroup" [controllerName]="'metric'" <dropdown-widget [field]="field" [group]="metricForm.controls.metricGroup" [controllerName]="'metric'"
(fieldChanged)="onMetricChanges(field)" [showDefaultOption]="false"></dropdown-widget> (fieldChanged)="onMetricChanges(field)" [showDefaultOption]="false"></dropdown-widget>
</form> </form>
<activiti-diagram *ngIf="currentMetric" [processDefinitionId]="report.processDefinitionId" [metricPercentages]="currentMetric"></activiti-diagram> <activiti-diagram *ngIf="currentMetric" [processDefinitionId]="report.processDefinitionId" [metricPercentages]="currentMetric" [metricColor]="currentMetricColors" [metricType]="metricType"></activiti-diagram>
</div> </div>
<div *ngIf="!hasMetric()">No metric found</div> <div *ngIf="!hasMetric()">No metric found</div>
@@ -33,9 +33,13 @@ describe('Test ng2-activiti-analytics-report-heat-map', () => {
let debug: DebugElement; let debug: DebugElement;
let element: HTMLElement; let element: HTMLElement;
let totalCountPerc = {'sid-fake-id': 0, 'fake-start-event': 100}; let totalCountPerc = { 'sid-fake-id': 0, 'fake-start-event': 100 };
let totalTimePerc = {'sid-fake-id': 10, 'fake-start-event': 30}; let totalTimePerc = { 'sid-fake-id': 10, 'fake-start-event': 30 };
let avgTimePercentages = {'sid-fake-id': 5, 'fake-start-event': 50}; 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(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
@@ -65,7 +69,10 @@ describe('Test ng2-activiti-analytics-report-heat-map', () => {
component.report = { component.report = {
totalCountsPercentages: totalCountPerc, totalCountsPercentages: totalCountPerc,
totalCountValues: totalCountValues,
totalTimePercentages: totalTimePerc, totalTimePercentages: totalTimePerc,
totalTimeValues: totalTimeValues,
avgTimeValues: avgTimeValues,
avgTimePercentages: avgTimePercentages avgTimePercentages: avgTimePercentages
}; };
}); });
@@ -81,7 +88,7 @@ describe('Test ng2-activiti-analytics-report-heat-map', () => {
}); });
it('should render the dropdown with the metric options', async(() => { 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(() => { component.onSuccess.subscribe(() => {
fixture.whenStable().then(() => { fixture.whenStable().then(() => {
@@ -106,21 +113,24 @@ describe('Test ng2-activiti-analytics-report-heat-map', () => {
})); }));
it('should change the currentmetric width totalCount', async(() => { it('should change the currentmetric width totalCount', async(() => {
let field = {value: 'totalCount'}; let field = { value: 'totalCount' };
component.onMetricChanges(field); 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(() => { it('should change the currentmetric width totalTime', async(() => {
let field = {value: 'totalTime'}; let field = { value: 'totalTime' };
component.onMetricChanges(field); 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(() => { it('should change the currentmetric width avgTime', async(() => {
let field = {value: 'avgTime'}; let field = { value: 'avgTime' };
component.onMetricChanges(field); component.onMetricChanges(field);
expect(component.currentMetric).toEqual(avgTimePercentages); expect(component.currentMetric).toEqual(avgTimeValues);
expect(component.currentMetricColors).toEqual(avgTimePercentages);
})); }));
}); });
@@ -40,12 +40,14 @@ export class AnalyticsReportHeatMapComponent implements OnInit {
metricForm: FormGroup; metricForm: FormGroup;
currentMetric: string; currentMetric: string;
currentMetricColors: string;
metricType: string;
constructor(private translate: AlfrescoTranslationService, constructor(private translate: AlfrescoTranslationService,
private analyticsService: AnalyticsService, private analyticsService: AnalyticsService,
private formBuilder: FormBuilder) { private formBuilder: FormBuilder) {
if (translate) { 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) { onMetricChanges(field: any) {
if (field.value === 'totalCount') { 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') { } 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') { } else if (field.value === 'avgTime') {
this.currentMetric = this.report.avgTimePercentages; this.currentMetric = this.report.avgTimeValues;
this.currentMetricColors = this.report.avgTimePercentages;
this.metricType = 'hours';
} }
} }
@@ -82,8 +82,26 @@ describe('Test ng2-activiti-analytics Report list', () => {
}); });
it('should return the default reports when the report list is empty', (done) => { 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(); 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(() => { component.onSuccess.subscribe(() => {
fixture.detectChanges(); fixture.detectChanges();
expect(element.querySelector('#report-list-0 > i').innerHTML).toBe('assignment'); expect(element.querySelector('#report-list-0 > i').innerHTML).toBe('assignment');
@@ -96,23 +114,6 @@ describe('Test ng2-activiti-analytics Report list', () => {
done(); 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) => { it('Report render the report list relative to a single app', (done) => {
@@ -57,13 +57,21 @@ export class AnalyticsReportListComponent implements OnInit {
this.reports.push(report); 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( this.analyticsService.getReportList().subscribe(
(res: ReportParametersModel[]) => { (res: ReportParametersModel[]) => {
if (res && res.length === 0) { if (res && res.length === 0) {
@@ -108,6 +116,15 @@ export class AnalyticsReportListComponent implements OnInit {
return this.reports === undefined || (this.reports && this.reports.length === 0); return this.reports === undefined || (this.reports && this.reports.length === 0);
} }
/**
* Reset the list
*/
private reset() {
if (!this.isReportsEmpty()) {
this.reports = [];
}
}
/** /**
* Select the current report * Select the current report
* @param report * @param report
@@ -21,3 +21,30 @@
.dropdown-widget__invalid .mdl-textfield__error { .dropdown-widget__invalid .mdl-textfield__error {
visibility: visible !important; 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;
}
@@ -1,7 +1,24 @@
<div class="col-md-6"> <div class="col-md-6">
<div *ngIf="reportParameters"> <div *ngIf="reportParameters">
<form [formGroup]="reportForm" novalidate> <form [formGroup]="reportForm" novalidate>
<h1>{{reportParameters.name}}</h1> <div *ngIf="isEditable">
<input
type="text"
class="mdl-textfield__input large"
id="reportName"
autofocus
data-automation-id="reportName"
[value]="reportParameters.name"
(input)="reportParameters.name=$event.target.value"
(blur)="editTitle($event)"
/>
</div>
<div *ngIf="!isEditable">
<span class="icon-small">
<i class="material-icons">mode_edit</i>
<h4 (click)="editEnable()">{{reportParameters.name}}</h4>
</span>
</div><hr>
<div *ngFor="let field of reportParameters.definition.parameters"> <div *ngFor="let field of reportParameters.definition.parameters">
<div [ngSwitch]="field.type"> <div [ngSwitch]="field.type">
<div *ngSwitchCase="'integer'"> <div *ngSwitchCase="'integer'">
@@ -87,7 +87,7 @@ describe('Test ng2-analytics-report-parameters Report Parameters ', () => {
component.onSuccessReportParams.subscribe(() => { component.onSuccessReportParams.subscribe(() => {
fixture.detectChanges(); fixture.detectChanges();
let dropDown: any = element.querySelector('#select-status'); 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).toBeDefined();
expect(dropDown.length).toEqual(4); expect(dropDown.length).toEqual(4);
expect(dropDown[0].innerHTML).toEqual('Choose One'); expect(dropDown[0].innerHTML).toEqual('Choose One');
@@ -280,21 +280,22 @@ describe('Test ng2-analytics-report-parameters Report Parameters ', () => {
done(); done();
}); });
let reportId = 1; jasmine.Ajax.stubRequest('http://localhost:9999/activiti-app/app/rest/reporting/report-params/1').andReturn({
let change = new SimpleChange(null, reportId);
component.ngOnChanges({ 'reportId': change });
jasmine.Ajax.requests.first().respondWith({
status: 200, status: 200,
contentType: 'json', contentType: 'json',
responseText: analyticParamsMock.reportDefParamProcessDef responseText: analyticParamsMock.reportDefParamProcessDef
}); });
jasmine.Ajax.requests.mostRecent().respondWith({ jasmine.Ajax.stubRequest('http://localhost:9999/activiti-app/app/rest/reporting/process-definitions').andReturn({
status: 200, status: 200,
contentType: 'json', contentType: 'json',
responseText: analyticParamsMock.reportDefParamProcessDefOptionsNoApp 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' + 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(); done();
}); });
let appId = 1; jasmine.Ajax.stubRequest('http://localhost:9999/activiti-app/app/rest/reporting/report-params/1').andReturn({
component.appId = appId;
let change = new SimpleChange(null, appId);
component.ngOnChanges({ 'appId': change });
jasmine.Ajax.requests.first().respondWith({
status: 200, status: 200,
contentType: 'json', contentType: 'json',
responseText: analyticParamsMock.reportDefParamProcessDef responseText: analyticParamsMock.reportDefParamProcessDef
}); });
jasmine.Ajax.requests.mostRecent().respondWith({ jasmine.Ajax.stubRequest('http://localhost:9999/activiti-app/api/enterprise/process-definitions').andReturn({
status: 200, status: 200,
contentType: 'json', contentType: 'json',
responseText: analyticParamsMock.reportDefParamProcessDefOptionsApp 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', () => { 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(); done();
}); });
let reportId = 1; jasmine.Ajax.stubRequest('http://localhost:9999/activiti-app/app/rest/reporting/report-params/1').andReturn({
let change = new SimpleChange(null, reportId);
component.ngOnChanges({ 'reportId': change });
jasmine.Ajax.requests.first().respondWith({
status: 200, status: 200,
contentType: 'json', contentType: 'json',
responseText: analyticParamsMock.reportDefParamProcessDef responseText: analyticParamsMock.reportDefParamProcessDef
}); });
jasmine.Ajax.requests.mostRecent().respondWith({ jasmine.Ajax.stubRequest('http://localhost:9999/activiti-app/app/rest/reporting/process-definitions').andReturn({
status: 404, status: 404,
contentType: 'json', contentType: 'json',
responseText: [] 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) => { it('Should emit an error with a 404 response when the report parameters response is not found', (done) => {
@@ -47,6 +47,9 @@ export class AnalyticsReportParametersComponent implements OnInit, OnChanges {
@Output() @Output()
onError = new EventEmitter(); onError = new EventEmitter();
@Output()
onEdit = new EventEmitter();
@Output() @Output()
onFormValueChanged = new EventEmitter(); onFormValueChanged = new EventEmitter();
@@ -63,12 +66,13 @@ export class AnalyticsReportParametersComponent implements OnInit, OnChanges {
private dropDownSub; private dropDownSub;
private reportParamsSub; private reportParamsSub;
private paramOpts; private paramOpts;
private isEditable: boolean = false;
constructor(private translate: AlfrescoTranslationService, constructor(private translate: AlfrescoTranslationService,
private analyticsService: AnalyticsService, private analyticsService: AnalyticsService,
private formBuilder: FormBuilder ) { private formBuilder: FormBuilder ) {
if (translate) { 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) { ngOnChanges(changes: SimpleChanges) {
this.isEditable = false;
let reportId = changes['reportId']; let reportId = changes['reportId'];
if (reportId && reportId.currentValue) { if (reportId && reportId.currentValue) {
this.getReportParams(reportId.currentValue); this.getReportParams(reportId.currentValue);
@@ -210,4 +215,25 @@ export class AnalyticsReportParametersComponent implements OnInit, OnChanges {
this.reportParamsSub.unsubscribe(); 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);
}
);
}
} }
@@ -1,10 +1,13 @@
<div class="col-md-6"> <div class="col-md-6">
<analytics-report-parameters [appId]="appId" [reportId]="reportId" <analytics-report-parameters [appId]="appId" [reportId]="reportId"
(onFormValueChanged)="reset()" (onSuccess)="showReport($event)"></analytics-report-parameters> (onFormValueChanged)="reset()"
(onSuccess)="showReport($event)"
(onEdit)="onEditReport($event)">
</analytics-report-parameters>
<div *ngIf="reports"> <div *ngIf="reports">
<div *ngFor="let report of reports"> <div *ngFor="let report of reports">
<h2>{{report.title}}</h2> <h4>{{report.title}}</h4>
<div [ngSwitch]="report.type"> <div [ngSwitch]="report.type">
<div *ngSwitchCase="'pie'"> <div *ngSwitchCase="'pie'">
<div class="col-md-6"> <div class="col-md-6">
@@ -190,6 +190,7 @@ describe('Test ng2-activiti-analytics Report ', () => {
}); });
let reportParamQuery = new ReportQuery({status: 'All'}); let reportParamQuery = new ReportQuery({status: 'All'});
component.reportId = 1;
component.showReport(reportParamQuery); component.showReport(reportParamQuery);
jasmine.Ajax.requests.mostRecent().respondWith({ jasmine.Ajax.requests.mostRecent().respondWith({
@@ -214,6 +215,7 @@ describe('Test ng2-activiti-analytics Report ', () => {
}); });
let reportParamQuery = new ReportQuery({status: 'All'}); let reportParamQuery = new ReportQuery({status: 'All'});
component.reportId = 1;
component.showReport(reportParamQuery); component.showReport(reportParamQuery);
jasmine.Ajax.requests.mostRecent().respondWith({ jasmine.Ajax.requests.mostRecent().respondWith({
@@ -41,12 +41,15 @@ export class AnalyticsComponent implements OnChanges {
@Output() @Output()
onSuccess = new EventEmitter(); onSuccess = new EventEmitter();
@Output()
editReport = new EventEmitter();
@Output() @Output()
onError = new EventEmitter(); onError = new EventEmitter();
reportParamQuery = new ReportQuery(); reportParamQuery = new ReportQuery();
reports: any[]; reports: Chart[];
public barChartOptions: any = { public barChartOptions: any = {
responsive: true, responsive: true,
@@ -69,7 +72,7 @@ export class AnalyticsComponent implements OnChanges {
private analyticsService: AnalyticsService) { private analyticsService: AnalyticsService) {
console.log('AnalyticsComponent'); console.log('AnalyticsComponent');
if (translate) { 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)); let clone = JSON.parse(JSON.stringify(report));
report.datasets = clone.datasets; report.datasets = clone.datasets;
} }
public onEditReport(name: string) {
this.editReport.emit(name);
}
} }
@@ -27,6 +27,8 @@ function dateCheck(c: AbstractControl) {
return result ? {'greaterThan': true} : null; return result ? {'greaterThan': true} : null;
} }
declare let mdDateTimePicker: any;
@Component({ @Component({
moduleId: module.id, moduleId: module.id,
selector: 'date-range-widget', selector: 'date-range-widget',
@@ -54,15 +56,9 @@ export class DateRangeWidget extends WidgetComponent {
debug: boolean = false; debug: boolean = false;
dialogStart: any = new mdDateTimePicker.default({ dialogStart: any;
type: 'date',
future: moment().add(21, 'years')
});
dialogEnd: any = new mdDateTimePicker.default({ dialogEnd: any;
type: 'date',
future: moment().add(21, 'years')
});
constructor(public elementRef: ElementRef, constructor(public elementRef: ElementRef,
private formBuilder: FormBuilder) { private formBuilder: FormBuilder) {
@@ -72,26 +68,39 @@ export class DateRangeWidget extends WidgetComponent {
ngOnInit() { ngOnInit() {
this.initForm(); this.initForm();
this.addAccessibilityLabelToDatePicker(); this.addAccessibilityLabelToDatePicker();
this.initSartDateDialog();
this.initEndDateDialog();
} }
initForm() { 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); startDateControl.setValidators(Validators.required);
this.dateRange.addControl('startDate', startDateControl); this.dateRange.addControl('startDate', startDateControl);
let endDateControl = new FormControl(today); let endDateControl = new FormControl(endDate);
endDateControl.setValidators(Validators.required); endDateControl.setValidators(Validators.required);
this.dateRange.addControl('endDate', endDateControl); this.dateRange.addControl('endDate', endDateControl);
this.dateRange.setValidators(dateCheck); this.dateRange.setValidators(dateCheck);
this.dateRange.valueChanges.subscribe(data => this.onGroupValueChanged(data)); 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; this.dialogStart.trigger = this.startElement.nativeElement;
let startDateButton = document.getElementById('startDateButton'); let startDateButton = document.getElementById('startDateButton');
@@ -130,7 +139,16 @@ export class DateRangeWidget extends WidgetComponent {
return span; 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; this.dialogEnd.trigger = this.endElement.nativeElement;
let endDateButton = document.getElementById('endDateButton'); let endDateButton = document.getElementById('endDateButton');
@@ -164,16 +182,24 @@ export class DateRangeWidget extends WidgetComponent {
onGroupValueChanged(data: any) { onGroupValueChanged(data: any) {
if (this.dateRange.valid) { if (this.dateRange.valid) {
let dateStart = this.convertMomentDate(this.dateRange.controls['startDate'].value); let dateStart = this.convertToMomentDateWithTime(this.dateRange.controls['startDate'].value);
let endStart = this.convertMomentDate(this.dateRange.controls['endDate'].value); let endStart = this.convertToMomentDateWithTime(this.dateRange.controls['endDate'].value);
this.dateRangeChanged.emit({startDate: dateStart, endDate: endStart}); 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'; 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() { ngOnDestroy() {
} }
@@ -17,6 +17,8 @@
import { Input, AfterViewInit, Output, EventEmitter, SimpleChanges, OnChanges } from '@angular/core'; import { Input, AfterViewInit, Output, EventEmitter, SimpleChanges, OnChanges } from '@angular/core';
let componentHandler: any;
/** /**
* Base widget component. * Base widget component.
*/ */
@@ -15,6 +15,8 @@
* limitations under the License. * limitations under the License.
*/ */
import * as moment from 'moment';
export class Chart { export class Chart {
id: string; id: string;
type: string; type: string;
@@ -76,7 +78,7 @@ export class LineChart extends Chart {
export class BarChart extends Chart { export class BarChart extends Chart {
title: string; title: string;
titleKey: string; titleKey: string;
labels: string[] = []; labels: any = [];
datasets: any[] = []; datasets: any[] = [];
data: any[] = []; data: any[] = [];
xAxisType: string; xAxisType: string;
@@ -72,7 +72,7 @@ export class ReportParameterDetailsModel {
name: string; name: string;
nameKey: string; nameKey: string;
type: string; type: string;
value: string; value: any;
options: ParameterValueModel[]; options: ParameterValueModel[];
dependsOn: string; dependsOn: string;
@@ -16,9 +16,9 @@
*/ */
import { Injectable } from '@angular/core'; 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 { 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 { ReportParametersModel, ParameterValueModel } from '../models/report.model';
import { Chart, PieChart, TableChart, BarChart, HeatMapChart, MultiBarChart } from '../models/chart.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 { export class AnalyticsService {
constructor(private authService: AlfrescoAuthenticationService, constructor(private authService: AlfrescoAuthenticationService,
private http: Http, public apiService: AlfrescoApiService,
private alfrescoSettingsService: AlfrescoSettingsService) { private alfrescoSettingsService: AlfrescoSettingsService) {
} }
@@ -35,14 +35,10 @@ export class AnalyticsService {
* @returns {Observable<any>} * @returns {Observable<any>}
*/ */
getReportList(): Observable<any> { getReportList(): Observable<any> {
let url = `${this.alfrescoSettingsService.getBPMApiBaseUrl()}/app/rest/reporting/reports`; return Observable.fromPromise(this.apiService.getInstance().activiti.reportApi.getReportList())
let options = this.getRequestOptions();
return this.http
.get(url, options)
.map((res: any) => { .map((res: any) => {
let reports: ReportParametersModel[] = []; let reports: ReportParametersModel[] = [];
let body = res.json(); res.forEach((report: ReportParametersModel) => {
body.forEach((report: ReportParametersModel) => {
let reportModel = new ReportParametersModel(report); let reportModel = new ReportParametersModel(report);
reports.push(reportModel); reports.push(reportModel);
}); });
@@ -51,13 +47,9 @@ export class AnalyticsService {
} }
getReportParams(reportId: string): Observable<any> { getReportParams(reportId: string): Observable<any> {
let url = `${this.alfrescoSettingsService.getBPMApiBaseUrl()}/app/rest/reporting/report-params/${reportId}`; return Observable.fromPromise(this.apiService.getInstance().activiti.reportApi.getReportParams(reportId))
let options = this.getRequestOptions();
return this.http
.get(url, options)
.map((res: any) => { .map((res: any) => {
let body = res.json(); return new ReportParametersModel(res);
return new ReportParametersModel(body);
}).catch(this.handleError); }).catch(this.handleError);
} }
@@ -72,7 +64,7 @@ export class AnalyticsService {
} }
} else if (type === 'dateInterval') { } else if (type === 'dateInterval') {
return this.getDateIntervalValues(); return this.getDateIntervalValues();
} else if (type === 'task') { } else if (type === 'task' && reportId && processDefinitionId) {
return this.getTasksByProcessDefinitionId(reportId, processDefinitionId); return this.getTasksByProcessDefinitionId(reportId, processDefinitionId);
} else { } else {
return Observable.create(observer => { return Observable.create(observer => {
@@ -124,14 +116,10 @@ export class AnalyticsService {
} }
getProcessDefinitionsValuesNoApp(): Observable<any> { getProcessDefinitionsValuesNoApp(): Observable<any> {
let url = `${this.alfrescoSettingsService.getBPMApiBaseUrl()}/app/rest/reporting/process-definitions`; return Observable.fromPromise(this.apiService.getInstance().activiti.reportApi.getProcessDefinitions())
let options = this.getRequestOptions();
return this.http
.get(url, options)
.map((res: any) => { .map((res: any) => {
let paramOptions: ParameterValueModel[] = []; let paramOptions: ParameterValueModel[] = [];
let body = res.json(); res.forEach((opt) => {
body.forEach((opt) => {
paramOptions.push(new ParameterValueModel(opt)); paramOptions.push(new ParameterValueModel(opt));
}); });
return paramOptions; return paramOptions;
@@ -139,17 +127,10 @@ export class AnalyticsService {
} }
getProcessDefinitionsValues(appId: string): Observable<any> { getProcessDefinitionsValues(appId: string): Observable<any> {
let url = `${this.alfrescoSettingsService.getBPMApiBaseUrl()}/app/rest/process-definitions`; return Observable.fromPromise(this.apiService.getInstance().activiti.processDefinitionsApi.getProcessDefinitions(appId))
let params: URLSearchParams;
params = new URLSearchParams();
params.set('appDefinitionId', appId);
let options = this.getRequestOptions(params);
return this.http
.get(url, options)
.map((res: any) => { .map((res: any) => {
let paramOptions: ParameterValueModel[] = []; let paramOptions: ParameterValueModel[] = [];
let body = res.json(); res.data.forEach((opt) => {
body.data.forEach((opt) => {
paramOptions.push(new ParameterValueModel(opt)); paramOptions.push(new ParameterValueModel(opt));
}); });
return paramOptions; return paramOptions;
@@ -157,42 +138,21 @@ export class AnalyticsService {
} }
getTasksByProcessDefinitionId(reportId: string, processDefinitionId: string): Observable<any> { getTasksByProcessDefinitionId(reportId: string, processDefinitionId: string): Observable<any> {
if (reportId && processDefinitionId) { return Observable.fromPromise(this.apiService.getInstance().activiti.reportApi.getTasksByProcessDefinitionId(reportId, processDefinitionId))
let url = `${this.alfrescoSettingsService.getBPMApiBaseUrl()}/app/rest/reporting/report-params/${reportId}/tasks`; .map((res: any) => {
let params: URLSearchParams; let paramOptions: ParameterValueModel[] = [];
if (processDefinitionId) { res.forEach((opt) => {
params = new URLSearchParams(); paramOptions.push(new ParameterValueModel({ id: opt, name: opt }));
params.set('processDefinitionId', processDefinitionId); });
} return paramOptions;
let options = this.getRequestOptions(params); }).catch(this.handleError);
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();
});
}
} }
getReportsByParams(reportId: number, paramsQuery: any): Observable<any> { getReportsByParams(reportId: number, paramsQuery: any): Observable<any> {
let url = `${this.alfrescoSettingsService.getBPMApiBaseUrl()}/app/rest/reporting/report-params/${reportId}`; return Observable.fromPromise(this.apiService.getInstance().activiti.reportApi.getReportsByParams(reportId, paramsQuery))
let body = paramsQuery ? JSON.stringify(paramsQuery) : {};
let options = this.getRequestOptions();
return this.http
.post(url, body, options)
.map((res: any) => { .map((res: any) => {
let elements: Chart[] = []; let elements: Chart[] = [];
let bodyRes = res.json(); res.elements.forEach((chartData) => {
bodyRes.elements.forEach((chartData) => {
if (chartData.type === 'pieChart') { if (chartData.type === 'pieChart') {
elements.push(new PieChart(chartData)); elements.push(new PieChart(chartData));
} else if (chartData.type === 'table') { } else if (chartData.type === 'table') {
@@ -213,31 +173,24 @@ export class AnalyticsService {
} }
public createDefaultReports(): Observable<any> { public createDefaultReports(): Observable<any> {
let url = `${this.alfrescoSettingsService.getBPMApiBaseUrl()}/app/rest/reporting/default-reports`; return Observable.fromPromise(this.apiService.getInstance().activiti.reportApi.createDefaultReports())
let options = this.getRequestOptions(); .map(this.toJson)
let body = {}; .catch(this.handleError);
return this.http }
.post(url, body, options)
public updateReport(reportId: number, name: string): Observable<any> {
return Observable.fromPromise(this.apiService.getInstance().activiti.reportApi.updateReport(reportId, name))
.map((res: any) => { .map((res: any) => {
return res; console.log('upload');
}).catch(this.handleError); }).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) { private handleError(error: Response) {
console.error(error); console.error(error);
return Observable.throw(error.json().error || 'Server error'); return Observable.throw(error.json().error || 'Server error');
} }
toJson(res: any) {
return res || {};
}
} }
@@ -3,11 +3,10 @@
"target": "es5", "target": "es5",
"module": "commonjs", "module": "commonjs",
"moduleResolution": "node", "moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true, "emitDecoratorMetadata": true,
"experimentalDecorators": true, "experimentalDecorators": true,
"sourceMap": true, "skipLibCheck": true,
"removeComments": true,
"declaration": true,
"noLib": false, "noLib": false,
"allowUnreachableCode": false, "allowUnreachableCode": false,
"allowUnusedLabels": false, "allowUnusedLabels": false,
@@ -15,12 +14,24 @@
"noImplicitReturns": false, "noImplicitReturns": false,
"noImplicitUseStrict": false, "noImplicitUseStrict": false,
"noFallthroughCasesInSwitch": true, "noFallthroughCasesInSwitch": true,
"outDir": "dist", "removeComments": true,
"types": ["core-js", "jasmine", "node"] "declaration": true,
"lib": [
"es2015",
"dom"
],
"suppressImplicitAnyIndexErrors": true
}, },
"exclude": [ "exclude": [
"demo", "demo",
"node_modules", "node_modules",
"dist" "dist",
] "tools",
"gulpfile.ts",
"gulpfile.d.ts"
],
"angularCompilerOptions": {
"strictMetadataEmit": false,
"skipTemplateCodegen": true
}
} }

Some files were not shown because too many files have changed in this diff Show More