From 470182be4f955a1c11d912743ce9e683ac4902a5 Mon Sep 17 00:00:00 2001
From: rsanchez <rsanchez@curisit.net>
Date: Mon, 20 Mar 2017 17:06:12 +0000
Subject: [PATCH] #3527 feature - Added skeleton for all other admin catalogs: users, orgs and lic types

---
 securis/src/main/webapp/src/app/forms/user.form.component.ts             |   51 +++
 securis/src/main/webapp/src/app/forms/application.form.component.ts      |   15 
 securis/src/main/webapp/src/app/forms/licensetype.form.component.ts      |   61 +++
 securis/src/main/webapp/src/app/forms/licensetype.form.html              |   94 +++++
 securis/src/main/webapp/src/app/forms/organization.form.html             |   94 +++++
 securis/src/main/webapp/src/app/listing/user.list.component.html         |   36 ++
 securis/src/main/webapp/src/app/forms/base.ts                            |   37 +
 securis/src/main/webapp/src/app/listing/organization.list.component.ts   |   89 +++++
 securis/src/main/webapp/src/app/app.routes.ts                            |   26 +
 securis/src/main/webapp/src/app/forms/application.form.html              |   12 
 securis/src/main/webapp/src/app/forms/user.form.html                     |   94 +++++
 securis/src/main/webapp/src/app/listing/user.list.component.ts           |   89 +++++
 securis/src/main/webapp/src/app/forms/pack.form.component.ts             |    8 
 securis/src/main/webapp/src/app/app.module.ts                            |   22 +
 securis/src/main/webapp/src/app/forms/organization.form.component.ts     |   59 +++
 securis/src/main/webapp/src/app/forms/license.form.component.ts          |    8 
 securis/src/main/webapp/src/app/forms/pack.form.html                     |   20 
 securis/src/main/webapp/src/app/listing/licensetype.list.component.html  |   36 ++
 securis/src/main/webapp/src/app/listing/licensetype.list.component.ts    |   89 +++++
 securis/src/main/webapp/src/app/forms/license.form.html                  |    8 
 securis/src/main/webapp/src/app/listing/organization.list.component.html |   36 ++
 21 files changed, 944 insertions(+), 40 deletions(-)

diff --git a/securis/src/main/webapp/src/app/app.module.ts b/securis/src/main/webapp/src/app/app.module.ts
index d065fd0..57df58a 100644
--- a/securis/src/main/webapp/src/app/app.module.ts
+++ b/securis/src/main/webapp/src/app/app.module.ts
@@ -28,17 +28,24 @@
 import { FooterComponent }  from './footer.component';
 import { LicenseListComponent } from './listing/license.list.component';
 import { PackListComponent }  from './listing/pack.list.component';
+import { ApplicationListComponent } from './listing/application.list.component';
+import { LicenseTypeListComponent } from './listing/licensetype.list.component';
+import { OrganizationListComponent } from './listing/organization.list.component';
+import { UserListComponent } from './listing/user.list.component';
+
 import { LoginFormComponent } from './forms/login.form.component';
 import { LicenseFormComponent } from './forms/license.form.component';
+import { LicenseTypeFormComponent } from './forms/licensetype.form.component';
+import { OrganizationFormComponent } from './forms/organization.form.component';
+import { UserFormComponent } from './forms/user.form.component';
+import { ApplicationFormComponent } from './forms/application.form.component';
+import { PackFormComponent } from "./forms/pack.form.component";
 
 
 import { appRoutes, appRoutingProviders } from './app.routes';
 import { requestOptionsProvider, requestBackendProvider } from './common/default.requests.options';
 import { LocaleServiceModule } from './common/i18n';
 import { SeCurisSession } from './common/session';
-import { PackFormComponent } from "./forms/pack.form.component";
-import { ApplicationFormComponent } from './forms/application.form.component';
-import { ApplicationListComponent } from './listing/application.list.component';
 
 @NgModule({
   imports: [
@@ -64,7 +71,13 @@
     LoginFormComponent,
     ErrorCheckerComponent,
     LicenseListComponent,
+    LicenseTypeListComponent,
+    OrganizationListComponent,
+    UserListComponent,
     LicenseFormComponent,
+    LicenseTypeFormComponent,
+    OrganizationFormComponent,
+    UserFormComponent,
     I18nDirective,
     HomeComponent,
     MenuComponent,
@@ -82,6 +95,9 @@
     LicensesService,
     PackFormComponent,
     LicenseFormComponent,
+    LicenseTypeFormComponent,
+    OrganizationFormComponent,
+    UserFormComponent,
     ApplicationsService,
     OrganizationsService,
     LicenseTypesService,
diff --git a/securis/src/main/webapp/src/app/app.routes.ts b/securis/src/main/webapp/src/app/app.routes.ts
index 628797e..e6ef16e 100644
--- a/securis/src/main/webapp/src/app/app.routes.ts
+++ b/securis/src/main/webapp/src/app/app.routes.ts
@@ -3,13 +3,20 @@
 import { HomeComponent } from './home.component';
 import { MenuComponent } from './menu.component';
 import { NoMenuComponent } from './nomenu.component';
-import { PackListComponent } from './listing/pack.list.component';
-import { LicenseListComponent } from './listing/license.list.component';
 import { LicenseFormComponent } from './forms/license.form.component';
 import { PackFormComponent } from './forms/pack.form.component';
 import { LoginFormComponent } from './forms/login.form.component';
 import { ApplicationFormComponent } from './forms/application.form.component';
+import { LicenseTypeFormComponent } from './forms/licensetype.form.component';
+import { OrganizationFormComponent } from './forms/organization.form.component';
+import { UserFormComponent } from './forms/user.form.component';
+
+import { PackListComponent } from './listing/pack.list.component';
+import { LicenseListComponent } from './listing/license.list.component';
 import { ApplicationListComponent } from './listing/application.list.component';
+import { LicenseTypeListComponent } from './listing/licensetype.list.component';
+import { OrganizationListComponent } from './listing/organization.list.component';
+import { UserListComponent } from './listing/user.list.component';
 
 const routes: Routes = [
   {path: 'public',  component: NoMenuComponent, children: [
@@ -30,7 +37,20 @@
         ]},
         {path: 'applications', component: ApplicationListComponent},
         {path: 'applications/create', component: ApplicationFormComponent},
-        {path: 'applications/edit/:applicationId', component: ApplicationFormComponent}
+        {path: 'applications/edit/:applicationId', component: ApplicationFormComponent},
+
+        {path: 'licensetypes', component: LicenseTypeListComponent},
+        {path: 'licensetypes/create', component: LicenseTypeFormComponent},
+        {path: 'licensetypes/edit/:applicationId', component: LicenseTypeFormComponent},
+
+        {path: 'organizations', component: OrganizationListComponent},
+        {path: 'organizations/create', component: OrganizationFormComponent},
+        {path: 'organizations/edit/:applicationId', component: OrganizationFormComponent},
+
+        {path: 'users', component: UserListComponent},
+        {path: 'users/create', component: UserFormComponent},
+        {path: 'users/edit/:applicationId', component: UserFormComponent}
+
     ]
   },
 
diff --git a/securis/src/main/webapp/src/app/forms/application.form.component.ts b/securis/src/main/webapp/src/app/forms/application.form.component.ts
index c9b4395..bda6dac 100644
--- a/securis/src/main/webapp/src/app/forms/application.form.component.ts
+++ b/securis/src/main/webapp/src/app/forms/application.form.component.ts
@@ -5,7 +5,7 @@
 import { LicenseTypesService } from '../resources/license_types';
 import { LocaleService } from '../common/i18n';
 import { TdDialogService } from '@covalent/core';
-import { Component, AfterViewInit } from '@angular/core';
+import { Component, AfterViewInit, ViewChild } from '@angular/core';
 import { TdMediaService } from '@covalent/core';
 import { FormBase, IComboOption } from './base';
 import { ActivatedRoute, Router } from '@angular/router';
@@ -32,13 +32,13 @@
 
   constructor(private http: Http,
               private licenseTypes: LicenseTypesService,
-              private router: Router,
               private applications: ApplicationsService,
+              router: Router,
               toaster: ToastsManager,
               route: ActivatedRoute,              
               $L: LocaleService,
               dialogs: TdDialogService) {
-    super($L, route, toaster, applications, $L.get('application'), dialogs);
+    super($L, router, route, toaster, applications, $L.get('application'), dialogs);
   }
 
  
@@ -46,11 +46,16 @@
     this.router.navigate([`applications`]);
   }
 
- 
-  ngAfterViewInit(): void {
+  init() : void {
+    super.setFirstFocus();
+    super.reset();
     super.prepareInitialData('applicationId', {
       metadata: []
     });
   }
+ 
+  ngAfterViewInit(): void {
+    this.init();
+  }
 }
 
diff --git a/securis/src/main/webapp/src/app/forms/application.form.html b/securis/src/main/webapp/src/app/forms/application.form.html
index afff290..6299a7c 100644
--- a/securis/src/main/webapp/src/app/forms/application.form.html
+++ b/securis/src/main/webapp/src/app/forms/application.form.html
@@ -28,18 +28,18 @@
 			</md-card-title>
 			<md-divider></md-divider>
 			<md-card-content>
-				<form #applicationForm="ngForm" class="inset">
+				<form #form="ngForm" class="inset">
 					<div layout="column" layout-align="start center">
 						<div layout="row" layout-fill layout-padding>
 							<field-readonly [value]="data.id" label="field.id" flex="15" *ngIf="!isNew"></field-readonly>
 							<div layout="column" layout-fill flex>
 								<md-input-container>
-									<input mdInput maxLength="50" type="text" [(ngModel)]="data.code" name="code" required [readonly]="!isNew" />
+									<input #firstField mdInput maxLength="50" type="text" [(ngModel)]="data.code" name="code" required [readonly]="!isNew" />
 									<md-placeholder>
 										<span i18n="field.code"></span>
 									</md-placeholder>
 								</md-input-container>
-								<error-checker [fieldName]="getFieldName('code')" [formField]="applicationForm.controls.code"></error-checker>
+								<error-checker [fieldName]="getFieldName('code')" [formField]="form.controls.code"></error-checker>
 							</div>
 						</div>
 						<div layout="row" layout-fill layout-padding>
@@ -50,7 +50,7 @@
 										<span i18n="field.name"></span>
 									</md-placeholder>
 								</md-input-container>
-								<error-checker [fieldName]="getFieldName('name')" [formField]="applicationForm.controls.name"></error-checker>
+								<error-checker [fieldName]="getFieldName('name')" [formField]="form.controls.name"></error-checker>
 							</div>
 							<div layout="column" layout-fill flex>
 								<md-input-container flex>
@@ -59,7 +59,7 @@
 										<span i18n="field.license_filename"></span>
 									</md-placeholder>
 								</md-input-container>
-								<error-checker [fieldName]="getFieldName('license_filename')" [formField]="applicationForm.controls.license_filename"></error-checker>
+								<error-checker [fieldName]="getFieldName('license_filename')" [formField]="form.controls.license_filename"></error-checker>
 							</div>
 						</div>
 						<div layout="row" layout-fill layout-padding>
@@ -85,7 +85,7 @@
 				<div layout="row" layout-align="start center" class="margin">
 					<button *ngIf="!isNew" md-raised-button color="warn" (click)="delete(data.id)">Delete</button>
 					<span flex></span>
-					<button [disabled]="!applicationForm.form.valid" md-raised-button color="primary" (click)="save()">Save</button>
+					<button [disabled]="!form.form.valid" md-raised-button color="primary" (click)="save()">Save</button>
 					<button md-button (click)="goBack()">Cancel</button>
 				</div>
 			</md-card-actions>
diff --git a/securis/src/main/webapp/src/app/forms/base.ts b/securis/src/main/webapp/src/app/forms/base.ts
index 17cba6d..67bf752 100644
--- a/securis/src/main/webapp/src/app/forms/base.ts
+++ b/securis/src/main/webapp/src/app/forms/base.ts
@@ -1,5 +1,5 @@
 import { Http } from '@angular/http';
-import { ActivatedRoute } from '@angular/router';
+import { ActivatedRoute, Router } from '@angular/router';
 import { TdDialogService } from '@covalent/core';
 import { ToastsManager } from 'ng2-toastr/ng2-toastr';
 
@@ -7,7 +7,8 @@
 import { BasicService } from '../common/utils';
 import { SeCurisResourceServices } from '../resources/base';
 
-import { AfterViewInit, Component, Input } from '@angular/core';
+import { ElementRef, ViewChild, AfterViewInit, Component, Input } from '@angular/core';
+import {FormGroup } from '@angular/forms';
 
 
 export interface IComboOption {
@@ -16,13 +17,17 @@
 }
 
 
-export class FormBase extends BasicService {
+export abstract class FormBase extends BasicService {
+	@ViewChild('firstField') firstField: ElementRef;
+	@ViewChild('form') form: FormGroup;
+
 	protected form_title: string = '';
 	protected form_subtitle: string = '';
 	protected data: any = {};
 	protected isNew : boolean = true;
 
 	constructor($L: LocaleService, 
+	            protected router: Router,
 	            protected route: ActivatedRoute,
 				protected toaster: ToastsManager,
 				protected resourceServices: SeCurisResourceServices, 
@@ -35,12 +40,31 @@
 		return this.$L.get(`field.${fieldId}`);
 	}
 
+	protected setFirstFocus() :void {
+		if (this.firstField) {
+			this.firstField.nativeElement.focus();
+		}
+	}
+
+	protected reset() :void {
+		if (this.form) {
+			this.form.reset();
+		}
+	}
+	
   	protected loadCombos(): void {}
+  	protected abstract init(): void;
+  	protected abstract goBack(): void;
 
 	save() {
 		var command = this.isNew ? this.resourceServices.create(this.data) : this.resourceServices.modify(this.data.id, this.data);
 		command.subscribe(
-			data => this.toaster.success(this.$L.get('{} saved sucessfully', this.resourceName.capitalize())),
+			data => {
+				this.toaster.success(this.$L.get('{} saved sucessfully', this.resourceName.capitalize()));
+				if (this.isNew) {
+					this.init();
+				}
+			},
 			err => this.toaster.error(err.message, this.$L.get('Error saving {}', this.resourceName))
 		);
 	}
@@ -56,7 +80,10 @@
 			if (accept) {
 				 this.resourceServices.remove(eleId)
 				 	.subscribe(
-						responseData => this.toaster.success(this.$L.get('{} was sucessfully deleted', this.resourceName.capitalize())),
+						responseData => {
+							this.toaster.success(this.$L.get('{} was sucessfully deleted', this.resourceName.capitalize()));
+							this.goBack();
+						},
 						err => this.toaster.success(err.message, this.$L.get('Error deleting the {}', this.resourceName))
 				);
 			}
diff --git a/securis/src/main/webapp/src/app/forms/license.form.component.ts b/securis/src/main/webapp/src/app/forms/license.form.component.ts
index b8089fb..90c3ef3 100644
--- a/securis/src/main/webapp/src/app/forms/license.form.component.ts
+++ b/securis/src/main/webapp/src/app/forms/license.form.component.ts
@@ -24,13 +24,13 @@
 
   constructor(private http: Http,
               private licenses: LicensesService,
-              private router: Router,
               private packs: PacksService,
+              router: Router,
               toaster: ToastsManager,
               route: ActivatedRoute,
               $L: LocaleService,
               dialogs: TdDialogService) {
-      super($L, route, toaster, licenses, $L.get('license'), dialogs);
+      super($L, router, route, toaster, licenses, $L.get('license'), dialogs);
   }
 
   requestFileSelected(file: File) : void {
@@ -77,6 +77,10 @@
 
 
   ngAfterViewInit(): void {
+    this.init();
+  }
+
+  init(): void {
 
     this.route.params.subscribe(params => {
       var packId = +params['packId']; // (+) converts string 'id' to a number
diff --git a/securis/src/main/webapp/src/app/forms/license.form.html b/securis/src/main/webapp/src/app/forms/license.form.html
index 545f5f0..bb559f3 100644
--- a/securis/src/main/webapp/src/app/forms/license.form.html
+++ b/securis/src/main/webapp/src/app/forms/license.form.html
@@ -29,7 +29,7 @@
 				</md-card-title>
 				<md-divider></md-divider>
 				<md-card-content>
-					<form #licenseForm="ngForm" class="inset" (keyup.enter)="save()">
+					<form #form="ngForm" class="inset" (keyup.enter)="save()">
 						<div layout="column" layout-align="start center">
 							<div layout="row" layout-fill layout-padding>
 								<field-readonly [value]="data.id" label="field.id" flex="20" *ngIf="!isNew"></field-readonly>
@@ -50,7 +50,7 @@
 											<span i18n="field.full_name"></span>
 										</md-placeholder>
 									</md-input-container>
-									<error-checker [fieldName]="$L.get('field.full_name')" [formField]="licenseForm.controls.full_name"></error-checker>
+									<error-checker [fieldName]="$L.get('field.full_name')" [formField]="form.controls.full_name"></error-checker>
 								</div>
 								<div layout="column" layout-fill flex>
 									<md-input-container flex>
@@ -59,7 +59,7 @@
 											<span i18n="field.email"></span>
 										</md-placeholder>
 									</md-input-container>
-									<error-checker [fieldName]="$L.get('field.full_name')" [formField]="licenseForm.controls.email"></error-checker>
+									<error-checker [fieldName]="$L.get('field.full_name')" [formField]="form.controls.email"></error-checker>
 								</div>
 							</div>
 							<div layout="row" layout-fill layout-padding>
@@ -100,7 +100,7 @@
 				<md-card-actions>
 					<div layout="row" layout-align="start center" class="margin">
 						<span flex></span>
-						<button [disabled]="!licenseForm.form.valid" md-raised-button color="primary" (click)="save()">Save</button>
+						<button [disabled]="!form.form.valid" md-raised-button color="primary" (click)="save()">Save</button>
 						<button md-button (click)="goBack()">Cancel</button>
 					</div>
 				</md-card-actions>
diff --git a/securis/src/main/webapp/src/app/forms/licensetype.form.component.ts b/securis/src/main/webapp/src/app/forms/licensetype.form.component.ts
new file mode 100644
index 0000000..03d66e2
--- /dev/null
+++ b/securis/src/main/webapp/src/app/forms/licensetype.form.component.ts
@@ -0,0 +1,61 @@
+import { Http } from '@angular/http';
+import { ToastsManager } from 'ng2-toastr/ng2-toastr';
+
+import { ApplicationsService } from '../resources/applications';
+import { LicenseTypesService } from '../resources/license_types';
+import { LocaleService } from '../common/i18n';
+import { TdDialogService } from '@covalent/core';
+import { Component, AfterViewInit, ViewChild } from '@angular/core';
+import { TdMediaService } from '@covalent/core';
+import { FormBase, IComboOption } from './base';
+import { ActivatedRoute, Router } from '@angular/router';
+
+var app_example = { 
+	code: 'CICS',
+  creation_timestamp: 1418384439000,
+  description: 'Wellbore integrity analysis software',
+  id: 1,
+  license_filename: 'config_server.lic',
+  name: 'CurisIntegrity',
+  metadata: 
+   [ { key: 'max_docs',
+       value: '250000',
+       readonly: true,
+       mandatory: true } ] 
+}
+
+@Component({
+  selector: 'licensetype-form',
+  templateUrl: 'src/app/forms/licensetype.form.html'
+})
+export class LicenseTypeFormComponent extends FormBase {
+
+  constructor(private http: Http,
+              private licenseTypes: LicenseTypesService,
+              private applications: ApplicationsService,
+              router: Router,
+              toaster: ToastsManager,
+              route: ActivatedRoute,              
+              $L: LocaleService,
+              dialogs: TdDialogService) {
+    super($L, router, route, toaster, licenseTypes, $L.get('license type'), dialogs);
+  }
+
+ 
+  goBack(): void {
+    this.router.navigate([`licensetypes`]);
+  }
+
+  init() : void {
+    super.setFirstFocus();
+    super.reset();
+    super.prepareInitialData('licenseTypeId', {
+      metadata: []
+    });
+  }
+ 
+  ngAfterViewInit(): void {
+    this.init();
+  }
+}
+
diff --git a/securis/src/main/webapp/src/app/forms/licensetype.form.html b/securis/src/main/webapp/src/app/forms/licensetype.form.html
new file mode 100644
index 0000000..6299a7c
--- /dev/null
+++ b/securis/src/main/webapp/src/app/forms/licensetype.form.html
@@ -0,0 +1,94 @@
+<td-layout-card-over cardWidth="60">
+	<md-toolbar role="toolbar" class="mat-secondary">
+		<button md-icon-button (click)="goBack()" color="accent">
+			<md-icon>arrow_back</md-icon>
+		</button>
+		<span class="md-title" [innerText]="form_title"></span>
+		<span flex></span>
+		<button md-icon-button (click)="save()"><md-icon>save</md-icon></button>
+	</md-toolbar>
+	<!--
+			code: 'CICS',
+  creation_timestamp: 1418384439000,
+  description: 'Wellbore integrity analysis software',
+  id: 1,
+  license_filename: 'config_server.lic',
+  name: 'CurisIntegrity',
+  metadata: 
+   [ { key: 'max_docs',
+       value: '250000',
+       readonly: true,
+       mandatory: true } ] 
+}
+		-->
+	<div class="margin" layout-align-gt-xs="center start" layout-fill="" layout-gt-xs="row">
+		<md-card flex="70">
+			<md-card-title>
+				{{form_subtitle}}
+			</md-card-title>
+			<md-divider></md-divider>
+			<md-card-content>
+				<form #form="ngForm" class="inset">
+					<div layout="column" layout-align="start center">
+						<div layout="row" layout-fill layout-padding>
+							<field-readonly [value]="data.id" label="field.id" flex="15" *ngIf="!isNew"></field-readonly>
+							<div layout="column" layout-fill flex>
+								<md-input-container>
+									<input #firstField mdInput maxLength="50" type="text" [(ngModel)]="data.code" name="code" required [readonly]="!isNew" />
+									<md-placeholder>
+										<span i18n="field.code"></span>
+									</md-placeholder>
+								</md-input-container>
+								<error-checker [fieldName]="getFieldName('code')" [formField]="form.controls.code"></error-checker>
+							</div>
+						</div>
+						<div layout="row" layout-fill layout-padding>
+							<div layout="column" layout-fill flex>
+								<md-input-container flex>
+									<input mdInput type="text" [(ngModel)]="data.name" name="name" required />
+									<md-placeholder>
+										<span i18n="field.name"></span>
+									</md-placeholder>
+								</md-input-container>
+								<error-checker [fieldName]="getFieldName('name')" [formField]="form.controls.name"></error-checker>
+							</div>
+							<div layout="column" layout-fill flex>
+								<md-input-container flex>
+									<input mdInput type="text" [(ngModel)]="data.license_filename" name="license_filename" required />
+									<md-placeholder>
+										<span i18n="field.license_filename"></span>
+									</md-placeholder>
+								</md-input-container>
+								<error-checker [fieldName]="getFieldName('license_filename')" [formField]="form.controls.license_filename"></error-checker>
+							</div>
+						</div>
+						<div layout="row" layout-fill layout-padding>
+							<div layout="column" layout-fill flex>
+								<md-input-container flex>
+									<textarea mdInput type="text" type="text" [(ngModel)]="data.description" name="description" maxlength="1024"></textarea>
+									<md-placeholder>
+										<span i18n="field.description"></span>
+									</md-placeholder>
+									<md-hint align="end">(max 1024)</md-hint>
+								</md-input-container>
+							</div>
+						</div>
+						<div layout="row" layout-fill layout-padding *ngIf="!isNew">
+							<field-readonly [value]="data.creation_timestamp | date: 'medium'" label="field.creation_timestamp" flex></field-readonly>
+						</div>
+						<metadata-manager addOrDelete="true" editKeys="true" [metadata]="data.metadata" ></metadata-manager>
+					</div>
+				</form>
+			</md-card-content>
+			<md-divider></md-divider>
+			<md-card-actions>
+				<div layout="row" layout-align="start center" class="margin">
+					<button *ngIf="!isNew" md-raised-button color="warn" (click)="delete(data.id)">Delete</button>
+					<span flex></span>
+					<button [disabled]="!form.form.valid" md-raised-button color="primary" (click)="save()">Save</button>
+					<button md-button (click)="goBack()">Cancel</button>
+				</div>
+			</md-card-actions>
+		</md-card>
+	</div>
+</td-layout-card-over>
\ No newline at end of file
diff --git a/securis/src/main/webapp/src/app/forms/organization.form.component.ts b/securis/src/main/webapp/src/app/forms/organization.form.component.ts
new file mode 100644
index 0000000..4d2caec
--- /dev/null
+++ b/securis/src/main/webapp/src/app/forms/organization.form.component.ts
@@ -0,0 +1,59 @@
+import { Http } from '@angular/http';
+import { ToastsManager } from 'ng2-toastr/ng2-toastr';
+
+import { OrganizationsService } from '../resources/organizations';
+import { LicenseTypesService } from '../resources/license_types';
+import { LocaleService } from '../common/i18n';
+import { TdDialogService } from '@covalent/core';
+import { Component, AfterViewInit, ViewChild } from '@angular/core';
+import { TdMediaService } from '@covalent/core';
+import { FormBase, IComboOption } from './base';
+import { ActivatedRoute, Router } from '@angular/router';
+
+var app_example = { 
+	code: 'CICS',
+  creation_timestamp: 1418384439000,
+  description: 'Wellbore integrity analysis software',
+  id: 1,
+  license_filename: 'config_server.lic',
+  name: 'CurisIntegrity',
+  metadata: 
+   [ { key: 'max_docs',
+       value: '250000',
+       readonly: true,
+       mandatory: true } ] 
+}
+
+@Component({
+  selector: 'organization-form',
+  templateUrl: 'src/app/forms/organization.form.html'
+})
+export class OrganizationFormComponent extends FormBase {
+
+  constructor(private http: Http,
+              private licenseTypes: LicenseTypesService,
+              private organizations: OrganizationsService,
+              router: Router,
+              toaster: ToastsManager,
+              route: ActivatedRoute,              
+              $L: LocaleService,
+              dialogs: TdDialogService) {
+    super($L, router, route, toaster, organizations, $L.get('organization'), dialogs);
+  }
+
+ 
+  goBack(): void {
+    this.router.navigate([`organizations`]);
+  }
+
+  init() : void {
+    super.setFirstFocus();
+    super.reset();
+    super.prepareInitialData('organizationId');
+  }
+ 
+  ngAfterViewInit(): void {
+    this.init();
+  }
+}
+
diff --git a/securis/src/main/webapp/src/app/forms/organization.form.html b/securis/src/main/webapp/src/app/forms/organization.form.html
new file mode 100644
index 0000000..6299a7c
--- /dev/null
+++ b/securis/src/main/webapp/src/app/forms/organization.form.html
@@ -0,0 +1,94 @@
+<td-layout-card-over cardWidth="60">
+	<md-toolbar role="toolbar" class="mat-secondary">
+		<button md-icon-button (click)="goBack()" color="accent">
+			<md-icon>arrow_back</md-icon>
+		</button>
+		<span class="md-title" [innerText]="form_title"></span>
+		<span flex></span>
+		<button md-icon-button (click)="save()"><md-icon>save</md-icon></button>
+	</md-toolbar>
+	<!--
+			code: 'CICS',
+  creation_timestamp: 1418384439000,
+  description: 'Wellbore integrity analysis software',
+  id: 1,
+  license_filename: 'config_server.lic',
+  name: 'CurisIntegrity',
+  metadata: 
+   [ { key: 'max_docs',
+       value: '250000',
+       readonly: true,
+       mandatory: true } ] 
+}
+		-->
+	<div class="margin" layout-align-gt-xs="center start" layout-fill="" layout-gt-xs="row">
+		<md-card flex="70">
+			<md-card-title>
+				{{form_subtitle}}
+			</md-card-title>
+			<md-divider></md-divider>
+			<md-card-content>
+				<form #form="ngForm" class="inset">
+					<div layout="column" layout-align="start center">
+						<div layout="row" layout-fill layout-padding>
+							<field-readonly [value]="data.id" label="field.id" flex="15" *ngIf="!isNew"></field-readonly>
+							<div layout="column" layout-fill flex>
+								<md-input-container>
+									<input #firstField mdInput maxLength="50" type="text" [(ngModel)]="data.code" name="code" required [readonly]="!isNew" />
+									<md-placeholder>
+										<span i18n="field.code"></span>
+									</md-placeholder>
+								</md-input-container>
+								<error-checker [fieldName]="getFieldName('code')" [formField]="form.controls.code"></error-checker>
+							</div>
+						</div>
+						<div layout="row" layout-fill layout-padding>
+							<div layout="column" layout-fill flex>
+								<md-input-container flex>
+									<input mdInput type="text" [(ngModel)]="data.name" name="name" required />
+									<md-placeholder>
+										<span i18n="field.name"></span>
+									</md-placeholder>
+								</md-input-container>
+								<error-checker [fieldName]="getFieldName('name')" [formField]="form.controls.name"></error-checker>
+							</div>
+							<div layout="column" layout-fill flex>
+								<md-input-container flex>
+									<input mdInput type="text" [(ngModel)]="data.license_filename" name="license_filename" required />
+									<md-placeholder>
+										<span i18n="field.license_filename"></span>
+									</md-placeholder>
+								</md-input-container>
+								<error-checker [fieldName]="getFieldName('license_filename')" [formField]="form.controls.license_filename"></error-checker>
+							</div>
+						</div>
+						<div layout="row" layout-fill layout-padding>
+							<div layout="column" layout-fill flex>
+								<md-input-container flex>
+									<textarea mdInput type="text" type="text" [(ngModel)]="data.description" name="description" maxlength="1024"></textarea>
+									<md-placeholder>
+										<span i18n="field.description"></span>
+									</md-placeholder>
+									<md-hint align="end">(max 1024)</md-hint>
+								</md-input-container>
+							</div>
+						</div>
+						<div layout="row" layout-fill layout-padding *ngIf="!isNew">
+							<field-readonly [value]="data.creation_timestamp | date: 'medium'" label="field.creation_timestamp" flex></field-readonly>
+						</div>
+						<metadata-manager addOrDelete="true" editKeys="true" [metadata]="data.metadata" ></metadata-manager>
+					</div>
+				</form>
+			</md-card-content>
+			<md-divider></md-divider>
+			<md-card-actions>
+				<div layout="row" layout-align="start center" class="margin">
+					<button *ngIf="!isNew" md-raised-button color="warn" (click)="delete(data.id)">Delete</button>
+					<span flex></span>
+					<button [disabled]="!form.form.valid" md-raised-button color="primary" (click)="save()">Save</button>
+					<button md-button (click)="goBack()">Cancel</button>
+				</div>
+			</md-card-actions>
+		</md-card>
+	</div>
+</td-layout-card-over>
\ No newline at end of file
diff --git a/securis/src/main/webapp/src/app/forms/pack.form.component.ts b/securis/src/main/webapp/src/app/forms/pack.form.component.ts
index 3652a15..0ac5044 100644
--- a/securis/src/main/webapp/src/app/forms/pack.form.component.ts
+++ b/securis/src/main/webapp/src/app/forms/pack.form.component.ts
@@ -24,13 +24,13 @@
   
   constructor(private http: Http,
               private licenseTypes: LicenseTypesService,
-              private router: Router,
               private packs: PacksService,
+              router: Router,
               toaster: ToastsManager,
               route: ActivatedRoute,              
               $L: LocaleService,
               dialogs: TdDialogService) {
-    super($L, route, toaster, packs, $L.get('pack'), dialogs);
+    super($L, router, route, toaster, packs, $L.get('pack'), dialogs);
   }
 
   loadCombos(): void {
@@ -72,6 +72,10 @@
   
 
   ngAfterViewInit(): void {
+    this.init();
+  }
+
+  init(): void {
     this.loadCombos();
     super.prepareInitialData('packId', {
       status: PACK_STATUS.CREATED
diff --git a/securis/src/main/webapp/src/app/forms/pack.form.html b/securis/src/main/webapp/src/app/forms/pack.form.html
index 5ba11e5..afbdb05 100644
--- a/securis/src/main/webapp/src/app/forms/pack.form.html
+++ b/securis/src/main/webapp/src/app/forms/pack.form.html
@@ -14,7 +14,7 @@
 			</md-card-title>
 			<md-divider></md-divider>
 			<md-card-content>
-				<form #packForm="ngForm" class="inset">
+				<form #form="ngForm" class="inset">
 					<div layout="column" layout-align="start center">
 						<div layout="row" layout-fill layout-padding>
 							<field-readonly [value]="data.id" label="field.id" flex="15" *ngIf="!isNew"></field-readonly>
@@ -25,7 +25,7 @@
 										<span i18n="field.code"></span>
 									</md-placeholder>
 								</md-input-container>
-								<error-checker [fieldName]="getFieldName('code')" [formField]="packForm.controls.code"></error-checker>
+								<error-checker [fieldName]="getFieldName('code')" [formField]="form.controls.code"></error-checker>
 							</div>
 							<div layout="column" layout-fill flex>
 								<md-input-container>
@@ -34,7 +34,7 @@
 										<span i18n="field.num_licenses"></span>
 									</md-placeholder>
 								</md-input-container>
-								<error-checker [fieldName]="getFieldName('num_licenses')" [formField]="packForm.controls.num_licenses"></error-checker>
+								<error-checker [fieldName]="getFieldName('num_licenses')" [formField]="form.controls.num_licenses"></error-checker>
 							</div>
 						</div>
 						<div layout="row" layout-fill layout-padding>
@@ -53,7 +53,7 @@
 										<span i18n="field.end_valid_date"></span>
 									</md-placeholder>
 								</md-input-container>
-								<error-checker [fieldName]="getFieldName('init_valid_date')" [formField]="packForm.controls.init_valid_date"></error-checker>
+								<error-checker [fieldName]="getFieldName('init_valid_date')" [formField]="form.controls.init_valid_date"></error-checker>
 							</div>
 							<div layout="column" layout-fill flex>
 								<md-input-container flex>
@@ -62,7 +62,7 @@
 										<span i18n="field.end_valid_date"></span>
 									</md-placeholder>
 								</md-input-container>
-								<error-checker [fieldName]="getFieldName('end_valid_date')" [formField]="packForm.controls.end_valid_date"></error-checker>
+								<error-checker [fieldName]="getFieldName('end_valid_date')" [formField]="form.controls.end_valid_date"></error-checker>
 							</div>
 						</div>
 						<div layout="row" layout-fill layout-padding *ngIf="isNew">
@@ -73,7 +73,7 @@
 										{{org.label}}
 									</md-option>
 								</md-select>
-								<error-checker [fieldName]="getFieldName('organization_id')" [formField]="packForm.controls.organization_id"></error-checker>
+								<error-checker [fieldName]="getFieldName('organization_id')" [formField]="form.controls.organization_id"></error-checker>
 							</div>
 							<div layout="column" layout-fill flex>
 								<md-select flex [placeholder]="getFieldName('license_type_id')" [(ngModel)]="data.license_type_id" name="license_type_id"
@@ -82,7 +82,7 @@
 										{{lt.label}}
 									</md-option>
 								</md-select>
-								<error-checker [fieldName]="getFieldName('license_type_id')" [formField]="packForm.controls.license_type_id"></error-checker>
+								<error-checker [fieldName]="getFieldName('license_type_id')" [formField]="form.controls.license_type_id"></error-checker>
 							</div>
 						</div>
 						<div layout="row" layout-fill layout-padding *ngIf="!isNew">
@@ -98,7 +98,7 @@
 									</md-placeholder>
 									<md-hint align="end">days</md-hint>
 								</md-input-container>
-								<error-checker [fieldName]="getFieldName('preactivation_valid_period')" [formField]="packForm.controls.preactivation_valid_period"></error-checker>
+								<error-checker [fieldName]="getFieldName('preactivation_valid_period')" [formField]="form.controls.preactivation_valid_period"></error-checker>
 							</div>
 							<div layout="column" layout-fill flex>
 								<md-input-container flex>
@@ -108,7 +108,7 @@
 									</md-placeholder>
 									<md-hint align="end">days</md-hint>
 								</md-input-container>
-								<error-checker [fieldName]="getFieldName('renew_valid_period')" [formField]="packForm.controls.renew_valid_period"></error-checker>
+								<error-checker [fieldName]="getFieldName('renew_valid_period')" [formField]="form.controls.renew_valid_period"></error-checker>
 							</div>
 						</div>
 						<div layout="row" layout-fill layout-padding>
@@ -134,7 +134,7 @@
 			<md-card-actions>
 				<div layout="row" layout-align="start center" class="margin">
 					<span flex></span>
-					<button [disabled]="!packForm.form.valid" md-raised-button color="primary" (click)="save()">Save</button>
+					<button [disabled]="!form.form.valid" md-raised-button color="primary" (click)="save()">Save</button>
 					<button md-button (click)="goBack()">Cancel</button>
 				</div>
 			</md-card-actions>
diff --git a/securis/src/main/webapp/src/app/forms/user.form.component.ts b/securis/src/main/webapp/src/app/forms/user.form.component.ts
new file mode 100644
index 0000000..6584c7d
--- /dev/null
+++ b/securis/src/main/webapp/src/app/forms/user.form.component.ts
@@ -0,0 +1,51 @@
+import { Http } from '@angular/http';
+import { ToastsManager } from 'ng2-toastr/ng2-toastr';
+
+import { ApplicationsService } from '../resources/applications';
+import { UsersService } from '../resources/users';
+import { LocaleService } from '../common/i18n';
+import { TdDialogService } from '@covalent/core';
+import { Component, AfterViewInit, ViewChild } from '@angular/core';
+import { TdMediaService } from '@covalent/core';
+import { FormBase, IComboOption } from './base';
+import { ActivatedRoute, Router } from '@angular/router';
+
+var app_example = { 
+
+}
+
+@Component({
+  selector: 'user-form',
+  templateUrl: 'src/app/forms/user.form.html'
+})
+export class UserFormComponent extends FormBase {
+
+  constructor(private http: Http,
+              private users: UsersService,
+              private applications: ApplicationsService,
+              router: Router,
+              toaster: ToastsManager,
+              route: ActivatedRoute,              
+              $L: LocaleService,
+              dialogs: TdDialogService) {
+    super($L, router, route, toaster, users, $L.get('user'), dialogs);
+  }
+
+ 
+  goBack(): void {
+    this.router.navigate([`users`]);
+  }
+
+  init() : void {
+    super.setFirstFocus();
+    super.reset();
+    super.prepareInitialData('userId', {
+      metadata: []
+    });
+  }
+ 
+  ngAfterViewInit(): void {
+    this.init();
+  }
+}
+
diff --git a/securis/src/main/webapp/src/app/forms/user.form.html b/securis/src/main/webapp/src/app/forms/user.form.html
new file mode 100644
index 0000000..6299a7c
--- /dev/null
+++ b/securis/src/main/webapp/src/app/forms/user.form.html
@@ -0,0 +1,94 @@
+<td-layout-card-over cardWidth="60">
+	<md-toolbar role="toolbar" class="mat-secondary">
+		<button md-icon-button (click)="goBack()" color="accent">
+			<md-icon>arrow_back</md-icon>
+		</button>
+		<span class="md-title" [innerText]="form_title"></span>
+		<span flex></span>
+		<button md-icon-button (click)="save()"><md-icon>save</md-icon></button>
+	</md-toolbar>
+	<!--
+			code: 'CICS',
+  creation_timestamp: 1418384439000,
+  description: 'Wellbore integrity analysis software',
+  id: 1,
+  license_filename: 'config_server.lic',
+  name: 'CurisIntegrity',
+  metadata: 
+   [ { key: 'max_docs',
+       value: '250000',
+       readonly: true,
+       mandatory: true } ] 
+}
+		-->
+	<div class="margin" layout-align-gt-xs="center start" layout-fill="" layout-gt-xs="row">
+		<md-card flex="70">
+			<md-card-title>
+				{{form_subtitle}}
+			</md-card-title>
+			<md-divider></md-divider>
+			<md-card-content>
+				<form #form="ngForm" class="inset">
+					<div layout="column" layout-align="start center">
+						<div layout="row" layout-fill layout-padding>
+							<field-readonly [value]="data.id" label="field.id" flex="15" *ngIf="!isNew"></field-readonly>
+							<div layout="column" layout-fill flex>
+								<md-input-container>
+									<input #firstField mdInput maxLength="50" type="text" [(ngModel)]="data.code" name="code" required [readonly]="!isNew" />
+									<md-placeholder>
+										<span i18n="field.code"></span>
+									</md-placeholder>
+								</md-input-container>
+								<error-checker [fieldName]="getFieldName('code')" [formField]="form.controls.code"></error-checker>
+							</div>
+						</div>
+						<div layout="row" layout-fill layout-padding>
+							<div layout="column" layout-fill flex>
+								<md-input-container flex>
+									<input mdInput type="text" [(ngModel)]="data.name" name="name" required />
+									<md-placeholder>
+										<span i18n="field.name"></span>
+									</md-placeholder>
+								</md-input-container>
+								<error-checker [fieldName]="getFieldName('name')" [formField]="form.controls.name"></error-checker>
+							</div>
+							<div layout="column" layout-fill flex>
+								<md-input-container flex>
+									<input mdInput type="text" [(ngModel)]="data.license_filename" name="license_filename" required />
+									<md-placeholder>
+										<span i18n="field.license_filename"></span>
+									</md-placeholder>
+								</md-input-container>
+								<error-checker [fieldName]="getFieldName('license_filename')" [formField]="form.controls.license_filename"></error-checker>
+							</div>
+						</div>
+						<div layout="row" layout-fill layout-padding>
+							<div layout="column" layout-fill flex>
+								<md-input-container flex>
+									<textarea mdInput type="text" type="text" [(ngModel)]="data.description" name="description" maxlength="1024"></textarea>
+									<md-placeholder>
+										<span i18n="field.description"></span>
+									</md-placeholder>
+									<md-hint align="end">(max 1024)</md-hint>
+								</md-input-container>
+							</div>
+						</div>
+						<div layout="row" layout-fill layout-padding *ngIf="!isNew">
+							<field-readonly [value]="data.creation_timestamp | date: 'medium'" label="field.creation_timestamp" flex></field-readonly>
+						</div>
+						<metadata-manager addOrDelete="true" editKeys="true" [metadata]="data.metadata" ></metadata-manager>
+					</div>
+				</form>
+			</md-card-content>
+			<md-divider></md-divider>
+			<md-card-actions>
+				<div layout="row" layout-align="start center" class="margin">
+					<button *ngIf="!isNew" md-raised-button color="warn" (click)="delete(data.id)">Delete</button>
+					<span flex></span>
+					<button [disabled]="!form.form.valid" md-raised-button color="primary" (click)="save()">Save</button>
+					<button md-button (click)="goBack()">Cancel</button>
+				</div>
+			</md-card-actions>
+		</md-card>
+	</div>
+</td-layout-card-over>
\ No newline at end of file
diff --git a/securis/src/main/webapp/src/app/listing/licensetype.list.component.html b/securis/src/main/webapp/src/app/listing/licensetype.list.component.html
new file mode 100644
index 0000000..522e7b7
--- /dev/null
+++ b/securis/src/main/webapp/src/app/listing/licensetype.list.component.html
@@ -0,0 +1,36 @@
+<td-layout-card-over cardWidth="70">
+  <md-toolbar role="toolbar" class="mat-secondary">
+    <span class="push-left-sm">
+        <span class="md-title" i18n>Applications</span>
+    </span>
+    <span class="push-left-sm" *ngIf="filteredItems < data.length">
+        <span class="md-body-1">{{filteredItems}} of {{data.length}} applications filtered</span>
+    </span>
+    <td-search-box #searchBox class="push-right-sm" placeholder="Search here" (searchDebounce)="search($event)" flex>
+    </td-search-box>
+    <button md-mini-fab color="accent" (click)="create()" [mdTooltip]="$L.get('Create a new application')">
+        <md-icon>add</md-icon>
+      </button>
+  </md-toolbar>
+ 	<div flex="84" layout-align="center end" layout="column">
+    <td-data-table 
+      [data]="filteredData" 
+      [columns]="columns" 
+      [sortable]="true"
+      [sortBy]="sortBy"
+      (sortChange)="sort($event)"
+      style="width: 100%">
+      <template tdDataTableTemplate="creation_timestamp" let-row="row" let-value="value">
+         <span>{{value | date: 'medium'}}</span>
+      </template>
+      <template tdDataTableTemplate="menu" let-row="row" let-index="index">
+        <div layout="row" layout-align="end center">
+          <button md-icon-button (click)="edit(row.id)" color="primary"><md-icon>edit</md-icon></button>
+        </div>
+      </template>
+    </td-data-table>
+    <td-paging-bar #pagingBar [pageSizes]="[10, 20, 40]" [total]="filteredTotal" (change)="page($event)" [hidden]="pagingBar.total <= 10">
+      <span td-paging-bar-label hide-xs>Rows per page:</span> {{pagingBar.range}} <span hide-xs>of {{pagingBar.total}}</span>
+    </td-paging-bar>
+  </div>
+</td-layout-card-over>
diff --git a/securis/src/main/webapp/src/app/listing/licensetype.list.component.ts b/securis/src/main/webapp/src/app/listing/licensetype.list.component.ts
new file mode 100644
index 0000000..ee22d6a
--- /dev/null
+++ b/securis/src/main/webapp/src/app/listing/licensetype.list.component.ts
@@ -0,0 +1,89 @@
+import { Router, ActivatedRoute } from '@angular/router';
+import { MdDialog, MdDialogConfig } from '@angular/material';
+import {
+    ITdDataTableColumn,
+    ITdDataTableSortChangeEvent,
+    TdDataTableService,
+    TdDataTableSortingOrder,
+    TdPagingBarComponent
+} from '@covalent/core';
+import { IPageChangeEvent } from '@covalent/core';
+import { Component, ViewChild, AfterViewInit } from '@angular/core';
+import { TdMediaService } from '@covalent/core';
+import { LicenseTypesService } from '../resources/license_types';
+import { PackFormComponent } from '../forms/pack.form.component';
+import { LocaleService } from '../common/i18n';
+import { ListingBase } from './base';
+
+
+var app_example = { 
+	code: 'CICS',
+  creation_timestamp: 1418384439000,
+  description: 'Wellbore integrity analysis software',
+  id: 1,
+  license_filename: 'config_server.lic',
+  name: 'CurisIntegrity',
+  metadata: 
+   [ { key: 'max_docs',
+       value: '250000',
+       readonly: true,
+       mandatory: true } ] 
+}
+
+@Component({
+  selector: 'licensetype-list',
+  templateUrl: 'src/app/listing/licensetype.list.component.html'
+})
+export class LicenseTypeListComponent extends ListingBase implements AfterViewInit {
+
+  columns: ITdDataTableColumn[] = [
+    { name: 'code', label: 'Code', tooltip: 'License type code' },
+    { name: 'name', label: 'Application name' },
+    { name: 'creation_timestamp', label: 'Creation date' },
+    { name: 'menu', label: '' }
+  ];
+
+  pack_menu_options : any[] = [{
+    command: 'edit',
+    name: 'Edit'
+  },{
+    command: 'cancel',
+    name: 'Cancel'
+  }]
+  
+
+  constructor(_dataTableService: TdDataTableService,
+    private media: TdMediaService,
+    private router: Router,
+    private $L: LocaleService,
+    private applicationForm: PackFormComponent,
+    private licensetypes: LicenseTypesService) {
+      super(_dataTableService);
+      this.licensetypes.get().subscribe(
+        (list : any[]) => {
+          this.data = list;
+          this.refresh();
+        },
+        (err: any) => console.error(err)
+      );
+  }
+
+
+  packAction(action: any) {
+    console.log(action.command);
+  }
+
+  isActionAvailable(pack : any) : boolean {
+    return true;
+  }
+
+  create() : void {
+    this.router.navigate(['licensetypes/create']);
+  }
+
+  edit(ltId: number | string) : void {
+    this.router.navigate([`licensetypes/edit/${ltId}`]);
+  }
+
+}
+
diff --git a/securis/src/main/webapp/src/app/listing/organization.list.component.html b/securis/src/main/webapp/src/app/listing/organization.list.component.html
new file mode 100644
index 0000000..522e7b7
--- /dev/null
+++ b/securis/src/main/webapp/src/app/listing/organization.list.component.html
@@ -0,0 +1,36 @@
+<td-layout-card-over cardWidth="70">
+  <md-toolbar role="toolbar" class="mat-secondary">
+    <span class="push-left-sm">
+        <span class="md-title" i18n>Applications</span>
+    </span>
+    <span class="push-left-sm" *ngIf="filteredItems < data.length">
+        <span class="md-body-1">{{filteredItems}} of {{data.length}} applications filtered</span>
+    </span>
+    <td-search-box #searchBox class="push-right-sm" placeholder="Search here" (searchDebounce)="search($event)" flex>
+    </td-search-box>
+    <button md-mini-fab color="accent" (click)="create()" [mdTooltip]="$L.get('Create a new application')">
+        <md-icon>add</md-icon>
+      </button>
+  </md-toolbar>
+ 	<div flex="84" layout-align="center end" layout="column">
+    <td-data-table 
+      [data]="filteredData" 
+      [columns]="columns" 
+      [sortable]="true"
+      [sortBy]="sortBy"
+      (sortChange)="sort($event)"
+      style="width: 100%">
+      <template tdDataTableTemplate="creation_timestamp" let-row="row" let-value="value">
+         <span>{{value | date: 'medium'}}</span>
+      </template>
+      <template tdDataTableTemplate="menu" let-row="row" let-index="index">
+        <div layout="row" layout-align="end center">
+          <button md-icon-button (click)="edit(row.id)" color="primary"><md-icon>edit</md-icon></button>
+        </div>
+      </template>
+    </td-data-table>
+    <td-paging-bar #pagingBar [pageSizes]="[10, 20, 40]" [total]="filteredTotal" (change)="page($event)" [hidden]="pagingBar.total <= 10">
+      <span td-paging-bar-label hide-xs>Rows per page:</span> {{pagingBar.range}} <span hide-xs>of {{pagingBar.total}}</span>
+    </td-paging-bar>
+  </div>
+</td-layout-card-over>
diff --git a/securis/src/main/webapp/src/app/listing/organization.list.component.ts b/securis/src/main/webapp/src/app/listing/organization.list.component.ts
new file mode 100644
index 0000000..c2d43fb
--- /dev/null
+++ b/securis/src/main/webapp/src/app/listing/organization.list.component.ts
@@ -0,0 +1,89 @@
+import { Router, ActivatedRoute } from '@angular/router';
+import { MdDialog, MdDialogConfig } from '@angular/material';
+import {
+    ITdDataTableColumn,
+    ITdDataTableSortChangeEvent,
+    TdDataTableService,
+    TdDataTableSortingOrder,
+    TdPagingBarComponent
+} from '@covalent/core';
+import { IPageChangeEvent } from '@covalent/core';
+import { Component, ViewChild, AfterViewInit } from '@angular/core';
+import { TdMediaService } from '@covalent/core';
+import { OrganizationsService } from '../resources/organizations';
+import { PackFormComponent } from '../forms/pack.form.component';
+import { LocaleService } from '../common/i18n';
+import { ListingBase } from './base';
+
+
+var app_example = { 
+	code: 'CICS',
+  creation_timestamp: 1418384439000,
+  description: 'Wellbore integrity analysis software',
+  id: 1,
+  license_filename: 'config_server.lic',
+  name: 'CurisIntegrity',
+  metadata: 
+   [ { key: 'max_docs',
+       value: '250000',
+       readonly: true,
+       mandatory: true } ] 
+}
+
+@Component({
+  selector: 'organization-list',
+  templateUrl: 'src/app/listing/organization.list.component.html'
+})
+export class OrganizationListComponent extends ListingBase implements AfterViewInit {
+
+  columns: ITdDataTableColumn[] = [
+    { name: 'code', label: 'Code', tooltip: 'Organization code' },
+    { name: 'name', label: 'Application name' },
+    { name: 'creation_timestamp', label: 'Creation date' },
+    { name: 'menu', label: '' }
+  ];
+
+  pack_menu_options : any[] = [{
+    command: 'edit',
+    name: 'Edit'
+  },{
+    command: 'cancel',
+    name: 'Cancel'
+  }]
+  
+
+  constructor(_dataTableService: TdDataTableService,
+    private media: TdMediaService,
+    private router: Router,
+    private $L: LocaleService,
+    private applicationForm: PackFormComponent,
+    private organizations: OrganizationsService) {
+      super(_dataTableService);
+      this.organizations.get().subscribe(
+        (list : any[]) => {
+          this.data = list;
+          this.refresh();
+        },
+        (err: any) => console.error(err)
+      );
+  }
+
+
+  packAction(action: any) {
+    console.log(action.command);
+  }
+
+  isActionAvailable(pack : any) : boolean {
+    return true;
+  }
+
+  create() : void {
+    this.router.navigate(['organizations/create']);
+  }
+
+  edit(eleId: number | string) : void {
+    this.router.navigate([`organizations/edit/${eleId}`]);
+  }
+
+}
+
diff --git a/securis/src/main/webapp/src/app/listing/user.list.component.html b/securis/src/main/webapp/src/app/listing/user.list.component.html
new file mode 100644
index 0000000..522e7b7
--- /dev/null
+++ b/securis/src/main/webapp/src/app/listing/user.list.component.html
@@ -0,0 +1,36 @@
+<td-layout-card-over cardWidth="70">
+  <md-toolbar role="toolbar" class="mat-secondary">
+    <span class="push-left-sm">
+        <span class="md-title" i18n>Applications</span>
+    </span>
+    <span class="push-left-sm" *ngIf="filteredItems < data.length">
+        <span class="md-body-1">{{filteredItems}} of {{data.length}} applications filtered</span>
+    </span>
+    <td-search-box #searchBox class="push-right-sm" placeholder="Search here" (searchDebounce)="search($event)" flex>
+    </td-search-box>
+    <button md-mini-fab color="accent" (click)="create()" [mdTooltip]="$L.get('Create a new application')">
+        <md-icon>add</md-icon>
+      </button>
+  </md-toolbar>
+ 	<div flex="84" layout-align="center end" layout="column">
+    <td-data-table 
+      [data]="filteredData" 
+      [columns]="columns" 
+      [sortable]="true"
+      [sortBy]="sortBy"
+      (sortChange)="sort($event)"
+      style="width: 100%">
+      <template tdDataTableTemplate="creation_timestamp" let-row="row" let-value="value">
+         <span>{{value | date: 'medium'}}</span>
+      </template>
+      <template tdDataTableTemplate="menu" let-row="row" let-index="index">
+        <div layout="row" layout-align="end center">
+          <button md-icon-button (click)="edit(row.id)" color="primary"><md-icon>edit</md-icon></button>
+        </div>
+      </template>
+    </td-data-table>
+    <td-paging-bar #pagingBar [pageSizes]="[10, 20, 40]" [total]="filteredTotal" (change)="page($event)" [hidden]="pagingBar.total <= 10">
+      <span td-paging-bar-label hide-xs>Rows per page:</span> {{pagingBar.range}} <span hide-xs>of {{pagingBar.total}}</span>
+    </td-paging-bar>
+  </div>
+</td-layout-card-over>
diff --git a/securis/src/main/webapp/src/app/listing/user.list.component.ts b/securis/src/main/webapp/src/app/listing/user.list.component.ts
new file mode 100644
index 0000000..7772a11
--- /dev/null
+++ b/securis/src/main/webapp/src/app/listing/user.list.component.ts
@@ -0,0 +1,89 @@
+import { Router, ActivatedRoute } from '@angular/router';
+import { MdDialog, MdDialogConfig } from '@angular/material';
+import {
+    ITdDataTableColumn,
+    ITdDataTableSortChangeEvent,
+    TdDataTableService,
+    TdDataTableSortingOrder,
+    TdPagingBarComponent
+} from '@covalent/core';
+import { IPageChangeEvent } from '@covalent/core';
+import { Component, ViewChild, AfterViewInit } from '@angular/core';
+import { TdMediaService } from '@covalent/core';
+import { UsersService } from '../resources/users';
+import { PackFormComponent } from '../forms/pack.form.component';
+import { LocaleService } from '../common/i18n';
+import { ListingBase } from './base';
+
+
+var app_example = { 
+	code: 'CICS',
+  creation_timestamp: 1418384439000,
+  description: 'Wellbore integrity analysis software',
+  id: 1,
+  license_filename: 'config_server.lic',
+  name: 'CurisIntegrity',
+  metadata: 
+   [ { key: 'max_docs',
+       value: '250000',
+       readonly: true,
+       mandatory: true } ] 
+}
+
+@Component({
+  selector: 'user-list',
+  templateUrl: 'src/app/listing/user.list.component.html'
+})
+export class UserListComponent extends ListingBase implements AfterViewInit {
+
+  columns: ITdDataTableColumn[] = [
+    { name: 'code', label: 'Code', tooltip: 'Application code' },
+    { name: 'name', label: 'Application name' },
+    { name: 'creation_timestamp', label: 'Creation date' },
+    { name: 'menu', label: '' }
+  ];
+
+  pack_menu_options : any[] = [{
+    command: 'edit',
+    name: 'Edit'
+  },{
+    command: 'cancel',
+    name: 'Cancel'
+  }]
+  
+
+  constructor(_dataTableService: TdDataTableService,
+    private media: TdMediaService,
+    private router: Router,
+    private $L: LocaleService,
+    private applicationForm: PackFormComponent,
+    private users: UsersService) {
+      super(_dataTableService);
+      this.users.get().subscribe(
+        (list : any[]) => {
+          this.data = list;
+          this.refresh();
+        },
+        (err: any) => console.error(err)
+      );
+  }
+
+
+  packAction(action: any) {
+    console.log(action.command);
+  }
+
+  isActionAvailable(pack : any) : boolean {
+    return true;
+  }
+
+  create() : void {
+    this.router.navigate(['users/create']);
+  }
+
+  edit(eleId: number | string) : void {
+    this.router.navigate([`users/edit/${eleId}`]);
+  }
+
+}
+

--
Gitblit v1.3.2