diff --git a/dmp-admin/src/app/app.component.ts b/dmp-admin/src/app/app.component.ts
index ae78b858b..176e3a616 100644
--- a/dmp-admin/src/app/app.component.ts
+++ b/dmp-admin/src/app/app.component.ts
@@ -23,6 +23,9 @@ export class AppComponent {
showLogin : boolean = false;
+ login(){
+ //redirect to login page
+ }
logout(){
this.tokenService.logout();
diff --git a/dmp-frontend/dmp-frontend-1-nov-2017.tar.gz b/dmp-frontend/dmp-frontend-1-nov-2017.tar.gz
new file mode 100644
index 000000000..11a14df3f
Binary files /dev/null and b/dmp-frontend/dmp-frontend-1-nov-2017.tar.gz differ
diff --git a/dmp-frontend/package.json b/dmp-frontend/package.json
index 238b93fad..e58999961 100644
--- a/dmp-frontend/package.json
+++ b/dmp-frontend/package.json
@@ -24,8 +24,8 @@
"angular-2-data-table": "^0.1.2",
"angular-4-data-table-bootstrap-4": "^0.2.0",
"angular-google-signin": "^0.1.5",
- "angular2-draggable": "^1.0.7",
"angular2-datatable": "^0.6.0",
+ "angular2-draggable": "^1.0.7",
"bootstrap": "^3.3.7",
"core-js": "^2.4.1",
"flat": "^4.0.0",
diff --git a/dmp-frontend/src/app/app-routing.module.ts b/dmp-frontend/src/app/app-routing.module.ts
index 3ff7e5790..da77b8c46 100644
--- a/dmp-frontend/src/app/app-routing.module.ts
+++ b/dmp-frontend/src/app/app-routing.module.ts
@@ -2,17 +2,26 @@ import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { PageNotFoundComponent } from './not-found.component';
import { DynamicFormComponent } from './form/dynamic-form.component';
-import { LoginComponent } from './login/login-page';
import { AuthGuard } from './guards/auth.guard';
import { ProjectsComponent } from './projects/projects.component';
import { DatasetsComponent } from './datasets/dataset.component';
+import { DmpComponent } from './dmps/dmp.component';
+import { AppComponent } from './app.component';
+import { MainSignInComponent } from './login/main-sign-in/main-sign-in.component';
const appRoutes: Routes = [
{ path: 'dynamic-form', component: DynamicFormComponent, canActivate: [AuthGuard] },
- { path: 'login-page', component: LoginComponent },
- //{ path: 'projects', component: ProjectsComponent},
+ { path: 'login-page', component: MainSignInComponent},
+ { path: 'projects', component: ProjectsComponent},
+ { path: 'dmps', component: DmpComponent},
{ path: '', redirectTo: '/login-page', pathMatch: 'full' },
- { path: '**', component: PageNotFoundComponent }
+ { path: '**', component: PageNotFoundComponent },
+ {
+ path: '',
+ redirectTo: 'app-root',
+ pathMatch: 'full'
+ }
+
];
@NgModule({
@@ -29,4 +38,5 @@ const appRoutes: Routes = [
]
})
-export class AppRoutingModule { }
\ No newline at end of file
+export class AppRoutingModule { }
+
diff --git a/dmp-frontend/src/app/app.component.css b/dmp-frontend/src/app/app.component.css
index 28e2fba60..372eb2f17 100644
--- a/dmp-frontend/src/app/app.component.css
+++ b/dmp-frontend/src/app/app.component.css
@@ -13,4 +13,25 @@
.ng-invalid:not(form) {
border-left: 5px solid #a94442; /* red */
}
-
\ No newline at end of file
+
+
+ .navbar-center {
+ position: absolute;
+ width: 100%;
+ left: 0;
+ text-align: center;
+ vertical-align: middle;
+ margin:0 auto;
+}
+
+.invisible {
+ display:none;
+}
+
+.visible {
+ display:block;
+}
+
+.cursor{
+ cursor: pointer;
+}
\ No newline at end of file
diff --git a/dmp-frontend/src/app/app.component.html b/dmp-frontend/src/app/app.component.html
new file mode 100644
index 000000000..a1039912d
--- /dev/null
+++ b/dmp-frontend/src/app/app.component.html
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Digital Management Plans
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/dmp-frontend/src/app/app.component.ts b/dmp-frontend/src/app/app.component.ts
index 3342a1ce6..8472a4f8d 100644
--- a/dmp-frontend/src/app/app.component.ts
+++ b/dmp-frontend/src/app/app.component.ts
@@ -2,24 +2,41 @@ import { Component } from '@angular/core';
import { ServerService } from './services/server.service';
import { FieldBase } from '../app/form/fields/field-base';
import { JsonObjest } from '../app/entities/JsonObject.class';
-
+import { TokenService, TokenProvider } from './services/login/token.service';
+import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
+import { MainSignInComponent } from './login/main-sign-in/main-sign-in.component';
@Component({
selector: 'app-root',
- template: `
-
-
-`,
- // template: `
- //
- //
- //
- // `,
+ templateUrl: './app.component.html',
+ styleUrls: ['./app.component.css'],
providers: []
})
export class AppComponent {
fields: any[];
+
+ constructor(private tokenService : TokenService, private router: Router) {
+
+ }
+
+
+ //loggedInAs : string = null;
+
+ showLogin : boolean = false;
+
+
+ login(){
+ //redirect to login page
+ this.router.navigate(['/login-page'], { queryParams: { /*returnUrl: this.state.url*/ }});
+ }
+
+ logout(){
+ this.tokenService.logout();
+ this.router.navigate(['/login-page'], { queryParams: { /*returnUrl: this.state.url*/ }});
+ }
+
+
}
-//
\ No newline at end of file
+
diff --git a/dmp-frontend/src/app/app.module.ts b/dmp-frontend/src/app/app.module.ts
index 2d7b67aee..4345ea4db 100644
--- a/dmp-frontend/src/app/app.module.ts
+++ b/dmp-frontend/src/app/app.module.ts
@@ -14,12 +14,11 @@ import { RestBase } from './services/rest-base';
import { DynamicFormComponent } from './form/dynamic-form.component';
import { DynamicFormFieldComponent } from './form/fields/dynamic-form-field.component';
import { ServerService } from './services/server.service';
-import { TokenService, TokenProvider } from './services/token.service';
+import { TokenService, TokenProvider } from './services/login/token.service';
import { LocalStorageService } from 'ngx-webstorage';
import { dataModelBuilder } from './services/dataModelBuilder.service';
import { DynamicFormGroupComponent } from './form/dynamic-form-group/dynamic-form-group.component';
-import { LoginComponent } from './login/login-page';
-import {GoogleSignInComponent} from 'angular-google-signin';
+//import { LoginComponent } from './login/login-page';
import { AppRoutingModule } from './app-routing.module';
import { AuthGuard } from './guards/auth.guard';
import { PageNotFoundComponent } from './not-found.component';
@@ -33,6 +32,10 @@ import { DmpModule } from './dmps/dmp.module';
import { TabModule } from './tabs/tab.module';
import { AngularDraggableModule } from 'angular2-draggable';
+import { NativeLoginService } from './services/login/native-login.service';
+import { GooggleSignInComponent } from './login/googgle-sign-in/googgle-sign-in.component';
+import { MainSignInComponent } from './login/main-sign-in/main-sign-in.component';
+
import { HTTP_INTERCEPTORS } from '@angular/common/http';
@@ -43,8 +46,9 @@ import { HTTP_INTERCEPTORS } from '@angular/common/http';
DynamicFormFieldComponent,
DynamicFormGroupComponent,
TocComponent,
- LoginComponent,
- GoogleSignInComponent,
+ //LoginComponent,
+ GooggleSignInComponent,
+ MainSignInComponent,
PageNotFoundComponent
],
imports: [
@@ -67,7 +71,8 @@ import { HTTP_INTERCEPTORS } from '@angular/common/http';
useClass: GlobalInterceptor,
multi: true,
},
- ServerService, dataModelBuilder, AuthGuard, PaginationService, TokenService, LocalStorageService, RestBase, EestoreService
+ ServerService, dataModelBuilder, AuthGuard, PaginationService, TokenService, LocalStorageService, RestBase, EestoreService,NativeLoginService
+
],
bootstrap: [AppComponent]
})
diff --git a/dmp-frontend/src/app/form/dynamic-form.component.ts b/dmp-frontend/src/app/form/dynamic-form.component.ts
index a66e0dff5..491984e9e 100644
--- a/dmp-frontend/src/app/form/dynamic-form.component.ts
+++ b/dmp-frontend/src/app/form/dynamic-form.component.ts
@@ -11,7 +11,7 @@ import { dataModelBuilder } from '../../app/services/dataModelBuilder.service';
import { DataModel } from '../entities/DataModel';
import { GroupBase } from './dynamic-form-group/group-base';
import { PaginationService } from '../../app/services/pagination.service';
-import { TokenService, TokenProvider } from '../services/token.service';
+import { TokenService, TokenProvider } from '../services/login/token.service';
import { AngularDraggableModule } from 'angular2-draggable';
diff --git a/dmp-frontend/src/app/guards/auth.guard.ts b/dmp-frontend/src/app/guards/auth.guard.ts
index 4b77957ef..069689145 100644
--- a/dmp-frontend/src/app/guards/auth.guard.ts
+++ b/dmp-frontend/src/app/guards/auth.guard.ts
@@ -1,6 +1,6 @@
import { Injectable } from '@angular/core';
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
-import { TokenService, TokenProvider } from '../services/token.service';
+import { TokenService, TokenProvider } from '../services/login/token.service';
@Injectable()
export class AuthGuard implements CanActivate {
@@ -8,14 +8,13 @@ export class AuthGuard implements CanActivate {
constructor(private router: Router, private tokenService: TokenService) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
- //if (localStorage.getItem('currentUser')) { it always returns true
- if(this.tokenService.getToken()!=null){
- // logged in so return true
- return true;
- }
+ if(this.tokenService.isLoggedIn() == true){
+ return true;
+ }
// not logged in so redirect to login page with the return url
this.router.navigate(['/login-page'], { queryParams: { returnUrl: state.url }});
return false;
+
}
-}
\ No newline at end of file
+}
diff --git a/dmp-frontend/src/app/login/googgle-sign-in/googgle-sign-in.component.css b/dmp-frontend/src/app/login/googgle-sign-in/googgle-sign-in.component.css
new file mode 100644
index 000000000..7ecba8a01
--- /dev/null
+++ b/dmp-frontend/src/app/login/googgle-sign-in/googgle-sign-in.component.css
@@ -0,0 +1,11 @@
+.nomargin{
+ margin-top: 0px;
+ margin-bottom: 0px;
+ margin-left: 0px;
+ margin-right: 0px;
+}
+
+.width-range {
+ max-width: 500px;
+ min-width: 300px;
+}
\ No newline at end of file
diff --git a/dmp-frontend/src/app/login/googgle-sign-in/googgle-sign-in.component.html b/dmp-frontend/src/app/login/googgle-sign-in/googgle-sign-in.component.html
new file mode 100644
index 000000000..e84f17f92
--- /dev/null
+++ b/dmp-frontend/src/app/login/googgle-sign-in/googgle-sign-in.component.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+
diff --git a/dmp-frontend/src/app/login/googgle-sign-in/googgle-sign-in.component.spec.ts b/dmp-frontend/src/app/login/googgle-sign-in/googgle-sign-in.component.spec.ts
new file mode 100644
index 000000000..ee11f64bd
--- /dev/null
+++ b/dmp-frontend/src/app/login/googgle-sign-in/googgle-sign-in.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { GooggleSignInComponent } from './googgle-sign-in.component';
+
+describe('GooggleSignInComponent', () => {
+ let component: GooggleSignInComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ GooggleSignInComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(GooggleSignInComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should be created', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/dmp-frontend/src/app/login/googgle-sign-in/googgle-sign-in.component.ts b/dmp-frontend/src/app/login/googgle-sign-in/googgle-sign-in.component.ts
new file mode 100644
index 000000000..316c22035
--- /dev/null
+++ b/dmp-frontend/src/app/login/googgle-sign-in/googgle-sign-in.component.ts
@@ -0,0 +1,86 @@
+import { Component, OnInit, ElementRef, AfterViewInit, VERSION } from '@angular/core';
+import { TokenService, TokenProvider } from '../../services/login/token.service';
+import {Router} from '@angular/router';
+
+declare const gapi: any;
+
+var $ = require("jquery");
+
+import '../../../assets/custom.js';
+declare function simple_notifier(type: string, title: string, message:string): any;
+
+@Component({
+ selector: 'googgle-sign-in',
+ templateUrl: './googgle-sign-in.component.html',
+ styleUrls: ['./googgle-sign-in.component.css']
+})
+export class GooggleSignInComponent implements OnInit, AfterViewInit {
+
+ //token:any;
+
+ constructor(private element: ElementRef, private tokenService : TokenService, private router : Router) {
+
+ }
+
+ ngOnInit() {
+ }
+
+ private clientId:string = '1010962018903-glegmqudqtl1lub0150vacopbu06lgsg.apps.googleusercontent.com';
+
+ private scope = [
+ 'profile',
+ 'email'
+ //,
+ //'https://www.googleapis.com/auth/plus.me',
+ //'https://www.googleapis.com/auth/contacts.readonly',
+ //'https://www.googleapis.com/auth/admin.directory.user.readonly'
+ ].join(' ');
+
+ public auth2: any;
+
+ public googleInit() {
+
+ gapi.load('auth2', () => {
+ this.auth2 = gapi.auth2.init({
+ client_id: this.clientId,
+ cookiepolicy: 'single_host_origin',
+ scope: this.scope
+ });
+ var buttonElement = this.element.nativeElement.querySelector('#googleBtn');
+ this.attachSignin(buttonElement);
+ });
+ }
+
+ public attachSignin(element) {
+ this.auth2.attachClickHandler(element, {},
+ (googleUser) => {
+ //simple_notifier("success",null,"Successful login");
+ let profile = googleUser.getBasicProfile();
+ this.tokenService.login(googleUser.getAuthResponse().id_token, TokenProvider.google, profile.getName(), profile.getEmail());
+ this.router.navigate(['/dmps'], { queryParams: { /*returnUrl: this.state.url*/ }});
+ },
+ function (error) {
+ simple_notifier("danger",null,"Failed to login");
+ console.log(JSON.stringify(error, undefined, 2));
+ });
+
+ }
+
+
+
+ ngAfterViewInit() {
+ this.googleInit();
+ }
+
+/*
+ signOut() {
+ var auth2 = gapi.auth2.getAuthInstance();
+ auth2.signOut().then(function () {
+ console.log('User signed out.');
+ });
+ }
+*/
+
+}
+
+
diff --git a/dmp-frontend/src/app/login/login-page.html b/dmp-frontend/src/app/login/login-page.html
deleted file mode 100644
index 56caf9983..000000000
--- a/dmp-frontend/src/app/login/login-page.html
+++ /dev/null
@@ -1,55 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/dmp-frontend/src/app/login/login-page.ts b/dmp-frontend/src/app/login/login-page.ts
deleted file mode 100644
index 8a3c002e1..000000000
--- a/dmp-frontend/src/app/login/login-page.ts
+++ /dev/null
@@ -1,87 +0,0 @@
-import { Component, OnInit, NgZone, AfterViewInit, ElementRef } from '@angular/core';
-import { GoogleSignInSuccess } from 'angular-google-signin';
-import { Router, ActivatedRoute } from '@angular/router';
-import { TokenService, TokenProvider } from '../services/token.service';
-
-@Component({
- selector: 'login-page',
- templateUrl: './login-page.html',
- providers: []
-})
-export class LoginComponent implements OnInit, AfterViewInit {
- returnUrl: string;
- token: any;
-
- constructor(
- private route: ActivatedRoute,
- private router: Router,
- private ngZone: NgZone,
- private tokenService: TokenService,
- private element: ElementRef
- ) {
-
- }
-
- ngOnInit() {
- // reset login status
- //this.authenticationService.logout();
-
- // get return url from route parameters or default to '/'
-
- //this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
- }
- //private myClientId: string = '524432312250-vhgidft856v8qftsc81kls4c74v87d8o.apps.googleusercontent.com';
- private myClientId: string = '1010962018903-glegmqudqtl1lub0150vacopbu06lgsg.apps.googleusercontent.com';
-
- public auth2: any;
-
- private scope = [
- 'profile',
- 'email'
- ].join(' ');
-
- public googleInit() {
-
- gapi.load('auth2', () => {
- this.auth2 = gapi.auth2.init({
- client_id: this.myClientId,
- cookie_policy: 'single_host_origin',
- scope: this.scope
- });
- var buttonElement = this.element.nativeElement.querySelector('#googleBtn');
- this.attachSignin(buttonElement);
- });
- }
-
- public attachSignin(element) {
- this.auth2.attachClickHandler(element, {},
- (googleUser) => {
- this.token = googleUser.getAuthResponse().id_token;
-
- let profile = googleUser.getBasicProfile();
-
- this.tokenService.setLoggedIn(true);
- this.tokenService.setToken(this.token);
- this.tokenService.setProvider(TokenProvider.google);
- this.tokenService.setUsername(profile.getName());
- this.tokenService.setEmail(profile.getEmail());
-
- this.ngZone.run(() => this.router.navigateByUrl('tabs'));
-
- window.location.reload();
-
- }, function (error) {
- console.log(JSON.stringify(error, undefined, 2));
- });
-
-
-
- }
-
- ngAfterViewInit() {
- this.googleInit();
- }
-
-
-
-}
diff --git a/dmp-frontend/src/app/login/main-sign-in/main-sign-in.component.css b/dmp-frontend/src/app/login/main-sign-in/main-sign-in.component.css
new file mode 100644
index 000000000..e49f49b9a
--- /dev/null
+++ b/dmp-frontend/src/app/login/main-sign-in/main-sign-in.component.css
@@ -0,0 +1,75 @@
+.form-signin
+{
+ max-width: 330px;
+ padding: 15px;
+ margin: 0 auto;
+}
+.form-signin .form-signin-heading, .form-signin .checkbox
+{
+ margin-bottom: 10px;
+}
+.form-signin .checkbox
+{
+ font-weight: normal;
+}
+.form-signin .form-control
+{
+ position: relative;
+ font-size: 16px;
+ height: auto;
+ padding: 10px;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+.form-signin .form-control:focus
+{
+ z-index: 2;
+}
+.form-signin input[type="text"]
+{
+ margin-bottom: -1px;
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0;
+}
+.form-signin input[type="password"]
+{
+ margin-bottom: 10px;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+}
+.account-wall
+{
+ margin-top: 20px;
+ padding: 40px 0px 20px 0px;
+ background-color: #f7f7f7;
+ -moz-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
+ -webkit-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
+ box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
+}
+.login-title
+{
+ color: #555;
+ font-size: 18px;
+ font-weight: 400;
+ display: block;
+}
+.profile-img
+{
+ width: 96px;
+ height: 96px;
+ margin: 0 auto 10px;
+ display: block;
+ -moz-border-radius: 50%;
+ -webkit-border-radius: 50%;
+ border-radius: 50%;
+}
+.need-help
+{
+ margin-top: 10px;
+}
+.new-account
+{
+ display: block;
+ margin-top: 10px;
+}
\ No newline at end of file
diff --git a/dmp-frontend/src/app/login/main-sign-in/main-sign-in.component.html b/dmp-frontend/src/app/login/main-sign-in/main-sign-in.component.html
new file mode 100644
index 000000000..660c3348b
--- /dev/null
+++ b/dmp-frontend/src/app/login/main-sign-in/main-sign-in.component.html
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+ Sign in with social
+
+
+
+
+
+
+
diff --git a/dmp-frontend/src/app/login/main-sign-in/main-sign-in.component.spec.ts b/dmp-frontend/src/app/login/main-sign-in/main-sign-in.component.spec.ts
new file mode 100644
index 000000000..cd7c7a960
--- /dev/null
+++ b/dmp-frontend/src/app/login/main-sign-in/main-sign-in.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { MainSignInComponent } from './main-sign-in.component';
+
+describe('MainSignInComponent', () => {
+ let component: MainSignInComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ MainSignInComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(MainSignInComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should be created', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/dmp-frontend/src/app/login/main-sign-in/main-sign-in.component.ts b/dmp-frontend/src/app/login/main-sign-in/main-sign-in.component.ts
new file mode 100644
index 000000000..ef16d6c9a
--- /dev/null
+++ b/dmp-frontend/src/app/login/main-sign-in/main-sign-in.component.ts
@@ -0,0 +1,61 @@
+import { Component, OnInit } from '@angular/core';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+import { NativeLoginService } from '../../services/login/native-login.service';
+import { TokenService, TokenProvider } from '../../services/login/token.service';
+import {Router} from '@angular/router';
+
+import '../../../assets/custom.js';
+declare function simple_notifier(type: string, title: string, message:string): any;
+
+@Component({
+ selector: 'app-main-sign-in',
+ templateUrl: './main-sign-in.component.html',
+ styleUrls: ['./main-sign-in.component.css']
+})
+export class MainSignInComponent implements OnInit {
+
+
+ nativeLoginForm : any;
+
+ creds : any = {"username":"","password":""};
+
+
+ constructor( private fb: FormBuilder, private nativeLogin : NativeLoginService, private tokenService : TokenService, private router : Router) {
+
+ }
+
+
+ createProjectEditorForm(){
+
+ this.nativeLoginForm = this.fb.group({
+ username: ['', Validators.required ],
+ password: ['', Validators.required ]
+ });
+
+ }
+
+
+ ngOnInit() {
+ this.createProjectEditorForm();
+ }
+
+
+ login(){
+ //login using the credentials
+
+ this.nativeLogin.login(this.creds.username, this.creds.password).subscribe(
+ response => {
+
+ simple_notifier("success",null,"Successful login");
+
+ this.tokenService.login(response['token'], TokenProvider.native, this.creds.username, response['email']);
+ this.router.navigate(['/dmps'], { queryParams: { /*returnUrl: this.state.url*/ }});
+ },
+ err => {
+ simple_notifier("danger",null,"Failed to login");
+ }
+ );
+
+ }
+
+}
diff --git a/dmp-frontend/src/app/projects/projects.component.ts b/dmp-frontend/src/app/projects/projects.component.ts
index 6214acbd5..cefdf21c9 100644
--- a/dmp-frontend/src/app/projects/projects.component.ts
+++ b/dmp-frontend/src/app/projects/projects.component.ts
@@ -13,7 +13,6 @@ import { ModalComponent } from '../modal/modal.component';
import { HttpErrorResponse } from '@angular/common/http';
import { FormGroup, FormControl } from '@angular/forms'; //na dw an xreiazontai
import { NgForm } from '@angular/forms';
-import { TokenService, TokenProvider } from '../services/token.service';
declare var $ :any;
@@ -67,7 +66,7 @@ export class ProjectsComponent implements OnInit{
constructor(
private serverService: ServerService,
private route: ActivatedRoute,
- private router: Router, private tokenService: TokenService){
+ private router: Router){
this.datasetDropDown = new DropdownField();
this.datasetDropDown.options = [];
this.datasets = [];
diff --git a/dmp-frontend/src/app/services/interceptor.ts b/dmp-frontend/src/app/services/interceptor.ts
index 3ccc2d28e..9ac5e9d7e 100644
--- a/dmp-frontend/src/app/services/interceptor.ts
+++ b/dmp-frontend/src/app/services/interceptor.ts
@@ -1,15 +1,13 @@
import {Injectable} from '@angular/core';
import {Observable} from 'rxjs/Observable';
import {HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpResponse, HttpErrorResponse} from '@angular/common/http';
-import { TokenService, TokenProvider } from './token.service';
+import { TokenService, TokenProvider } from './login/token.service';
@Injectable()
export class GlobalInterceptor implements HttpInterceptor {
- constructor(private tokenService: TokenService) {
-
- }
+ constructor(public tokenService: TokenService) {}
intercept(req: HttpRequest, next: HttpHandler): Observable> {
@@ -20,19 +18,14 @@ export class GlobalInterceptor implements HttpInterceptor {
}
*/
}, (err: any) => {
- if (err instanceof HttpErrorResponse) {debugger;
+ if (err instanceof HttpErrorResponse) {
if (err.status === 401) {
- var auth2 = gapi.auth2.getAuthInstance();
- auth2.signOut().then(function () {
- console.log('User signed out.');
- localStorage.removeItem('currentUser');
- this.router.navigate(['/login-page']);
- });
- this.tokenService.setToken(null);
- //EDW VALE TO KWDIKA GIA TO LOGOUT KAI SXOLIASE TON OPOU ALLOU TON EXEIS
+ this.tokenService.logout();
}
}
});
+
+ //return next.handle(req);
}
}
\ No newline at end of file
diff --git a/dmp-frontend/src/app/services/login/native-login.service.ts b/dmp-frontend/src/app/services/login/native-login.service.ts
new file mode 100644
index 000000000..5330defdd
--- /dev/null
+++ b/dmp-frontend/src/app/services/login/native-login.service.ts
@@ -0,0 +1,31 @@
+import { Injectable, OnInit } from '@angular/core';
+import { Observable } from 'rxjs';
+import { TokenService, TokenProvider } from '../login/token.service'
+import { HttpClient , HttpHeaders, HttpParams} from '@angular/common/http';
+import {RestBase} from '../rest-base';
+
+@Injectable()
+export class NativeLoginService implements OnInit {
+
+
+ constructor(private restBase: RestBase) {
+ }
+
+ ngOnInit(){
+
+ }
+
+
+ login(username, password){
+ var credentials = {"username": username, "password":password};
+ return this.restBase.login("nativeLogin", credentials);
+ }
+
+
+
+}
+
+
+
+
+
diff --git a/dmp-frontend/src/app/services/token.service.ts b/dmp-frontend/src/app/services/login/token.service.ts
similarity index 70%
rename from dmp-frontend/src/app/services/token.service.ts
rename to dmp-frontend/src/app/services/login/token.service.ts
index 0521179f6..38f777af6 100644
--- a/dmp-frontend/src/app/services/token.service.ts
+++ b/dmp-frontend/src/app/services/login/token.service.ts
@@ -4,12 +4,15 @@ import {LocalStorageService} from 'ngx-webstorage';
import 'rxjs/add/operator/map';
import { DOCUMENT } from '@angular/platform-browser';
+
declare var jQuery : any;
+import '../../../assets/custom.js';
+declare function sign_out_google(): any;
+
@Injectable()
export class TokenService {
-
constructor (private storage : LocalStorageService, @Inject(DOCUMENT) private document) {
//var csrfToken : string = jQuery(document).find('meta[name="csrf-token"]').attr('content');
//this.setCSRFToken(csrfToken);
@@ -66,12 +69,37 @@ export class TokenService {
}
+ login(token: string, provider: TokenProvider, username: string, email: string){
+
+ this.setLoggedIn(true);
+ this.setToken(token);
+ this.setProvider(provider);
+ this.setUsername(username);
+ this.setEmail(email);
+
+ window.location.reload();
+
+ }
+
+
+ logout(){
+ //set the log out actions here
+ this.setLoggedIn(false);
+ this.setEmail(null);
+ this.setUsername(null);
+ this.setToken(null);
+
+ if(this.getProvider() == TokenProvider.google){
+ sign_out_google();
+ }
+
+ this.setProvider(null);
+ }
+
+
}
export enum TokenProvider {
native,
google
}
-
-
-
diff --git a/dmp-frontend/src/app/services/rest-base.ts b/dmp-frontend/src/app/services/rest-base.ts
index 46e77966c..7a3c2acb3 100644
--- a/dmp-frontend/src/app/services/rest-base.ts
+++ b/dmp-frontend/src/app/services/rest-base.ts
@@ -1,5 +1,5 @@
import { HttpClient , HttpHeaders, HttpParams } from '@angular/common/http';
-import { TokenService, TokenProvider } from './token.service'
+import { TokenService, TokenProvider } from './login/token.service'
import 'rxjs/Rx';
diff --git a/dmp-frontend/src/app/services/server.service.ts b/dmp-frontend/src/app/services/server.service.ts
index 8d9169dfa..4366e49e4 100644
--- a/dmp-frontend/src/app/services/server.service.ts
+++ b/dmp-frontend/src/app/services/server.service.ts
@@ -6,8 +6,8 @@ import {dataModelBuilder} from '../../app/services/dataModelBuilder.service';
import { DatasetProfile } from '../entities/datasetprofile';
import {DataModel} from '../entities/DataModel';
import {Project} from '../entities/model/project';
-import {LoginComponent} from '../../app/login/login-page';
-import { TokenService, TokenProvider } from './token.service';
+//import {LoginComponent} from '../../app/login/login-page';
+import { TokenService, TokenProvider } from './login/token.service';
import {RestBase} from './rest-base';
import 'rxjs/Rx';
@@ -130,14 +130,8 @@ public updateDatsetsProfile(data:any){
logOut() {
-
- var auth2 = gapi.auth2.getAuthInstance();
- auth2.signOut().then(function () {
- console.log('User signed out.');
- localStorage.removeItem('currentUser');
- });
- this.tokenService.setToken(null); //kanonika prepei na mpei mesa sthn function.....
- }
+ this.tokenService.logout();
+ }
getData() {
diff --git a/dmp-frontend/src/assets/bootstrap-notify.min.js b/dmp-frontend/src/assets/bootstrap-notify.min.js
new file mode 100644
index 000000000..01e7f3091
--- /dev/null
+++ b/dmp-frontend/src/assets/bootstrap-notify.min.js
@@ -0,0 +1 @@
+!function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t("object"==typeof exports?require("jquery"):jQuery)}(function(t){function s(s){var e=!1;return t('[data-notify="container"]').each(function(i,n){var a=t(n),o=a.find('[data-notify="title"]').text().trim(),r=a.find('[data-notify="message"]').html().trim(),l=o===t(""+s.settings.content.title+"
").html().trim(),d=r===t(""+s.settings.content.message+"
").html().trim(),g=a.hasClass("alert-"+s.settings.type);return l&&d&&g&&(e=!0),!e}),e}function e(e,n,a){var o={content:{message:"object"==typeof n?n.message:n,title:n.title?n.title:"",icon:n.icon?n.icon:"",url:n.url?n.url:"#",target:n.target?n.target:"-"}};a=t.extend(!0,{},o,a),this.settings=t.extend(!0,{},i,a),this._defaults=i,"-"===this.settings.content.target&&(this.settings.content.target=this.settings.url_target),this.animations={start:"webkitAnimationStart oanimationstart MSAnimationStart animationstart",end:"webkitAnimationEnd oanimationend MSAnimationEnd animationend"},"number"==typeof this.settings.offset&&(this.settings.offset={x:this.settings.offset,y:this.settings.offset}),(this.settings.allow_duplicates||!this.settings.allow_duplicates&&!s(this))&&this.init()}var i={element:"body",position:null,type:"info",allow_dismiss:!0,allow_duplicates:!0,newest_on_top:!1,showProgressbar:!1,placement:{from:"top",align:"right"},offset:20,spacing:10,z_index:1031,delay:5e3,timer:1e3,url_target:"_blank",mouse_over:null,animate:{enter:"animated fadeInDown",exit:"animated fadeOutUp"},onShow:null,onShown:null,onClose:null,onClosed:null,icon_type:"class",template:''};String.format=function(){for(var t=arguments[0],s=1;s .progress-bar').removeClass("progress-bar-"+t.settings.type),t.settings.type=i[n],this.$ele.addClass("alert-"+i[n]).find('[data-notify="progressbar"] > .progress-bar').addClass("progress-bar-"+i[n]);break;case"icon":var a=this.$ele.find('[data-notify="icon"]');"class"===t.settings.icon_type.toLowerCase()?a.removeClass(t.settings.content.icon).addClass(i[n]):(a.is("img")||a.find("img"),a.attr("src",i[n]));break;case"progress":var o=t.settings.delay-t.settings.delay*(i[n]/100);this.$ele.data("notify-delay",o),this.$ele.find('[data-notify="progressbar"] > div').attr("aria-valuenow",i[n]).css("width",i[n]+"%");break;case"url":this.$ele.find('[data-notify="url"]').attr("href",i[n]);break;case"target":this.$ele.find('[data-notify="url"]').attr("target",i[n]);break;default:this.$ele.find('[data-notify="'+n+'"]').html(i[n])}var r=this.$ele.outerHeight()+parseInt(t.settings.spacing)+parseInt(t.settings.offset.y);t.reposition(r)},close:function(){t.close()}}},buildNotify:function(){var s=this.settings.content;this.$ele=t(String.format(this.settings.template,this.settings.type,s.title,s.message,s.url,s.target)),this.$ele.attr("data-notify-position",this.settings.placement.from+"-"+this.settings.placement.align),this.settings.allow_dismiss||this.$ele.find('[data-notify="dismiss"]').css("display","none"),(this.settings.delay<=0&&!this.settings.showProgressbar||!this.settings.showProgressbar)&&this.$ele.find('[data-notify="progressbar"]').remove()},setIcon:function(){"class"===this.settings.icon_type.toLowerCase()?this.$ele.find('[data-notify="icon"]').addClass(this.settings.content.icon):this.$ele.find('[data-notify="icon"]').is("img")?this.$ele.find('[data-notify="icon"]').attr("src",this.settings.content.icon):this.$ele.find('[data-notify="icon"]').append(' ')},styleDismiss:function(){this.$ele.find('[data-notify="dismiss"]').css({position:"absolute",right:"10px",top:"5px",zIndex:this.settings.z_index+2})},styleURL:function(){this.$ele.find('[data-notify="url"]').css({backgroundImage:"url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)",height:"100%",left:0,position:"absolute",top:0,width:"100%",zIndex:this.settings.z_index+1})},placement:function(){var s=this,e=this.settings.offset.y,i={display:"inline-block",margin:"0px auto",position:this.settings.position?this.settings.position:"body"===this.settings.element?"fixed":"absolute",transition:"all .5s ease-in-out",zIndex:this.settings.z_index},n=!1,a=this.settings;switch(t('[data-notify-position="'+this.settings.placement.from+"-"+this.settings.placement.align+'"]:not([data-closing="true"])').each(function(){e=Math.max(e,parseInt(t(this).css(a.placement.from))+parseInt(t(this).outerHeight())+parseInt(a.spacing))}),this.settings.newest_on_top===!0&&(e=this.settings.offset.y),i[this.settings.placement.from]=e+"px",this.settings.placement.align){case"left":case"right":i[this.settings.placement.align]=this.settings.offset.x+"px";break;case"center":i.left=0,i.right=0}this.$ele.css(i).addClass(this.settings.animate.enter),t.each(Array("webkit-","moz-","o-","ms-",""),function(t,e){s.$ele[0].style[e+"AnimationIterationCount"]=1}),t(this.settings.element).append(this.$ele),this.settings.newest_on_top===!0&&(e=parseInt(e)+parseInt(this.settings.spacing)+this.$ele.outerHeight(),this.reposition(e)),t.isFunction(s.settings.onShow)&&s.settings.onShow.call(this.$ele),this.$ele.one(this.animations.start,function(){n=!0}).one(this.animations.end,function(){s.$ele.removeClass(s.settings.animate.enter),t.isFunction(s.settings.onShown)&&s.settings.onShown.call(this)}),setTimeout(function(){n||t.isFunction(s.settings.onShown)&&s.settings.onShown.call(this)},600)},bind:function(){var s=this;if(this.$ele.find('[data-notify="dismiss"]').on("click",function(){s.close()}),this.$ele.mouseover(function(){t(this).data("data-hover","true")}).mouseout(function(){t(this).data("data-hover","false")}),this.$ele.data("data-hover","false"),this.settings.delay>0){s.$ele.data("notify-delay",s.settings.delay);var e=setInterval(function(){var t=parseInt(s.$ele.data("notify-delay"))-s.settings.timer;if("false"===s.$ele.data("data-hover")&&"pause"===s.settings.mouse_over||"pause"!=s.settings.mouse_over){var i=(s.settings.delay-t)/s.settings.delay*100;s.$ele.data("notify-delay",t),s.$ele.find('[data-notify="progressbar"] > div').attr("aria-valuenow",i).css("width",i+"%")}t<=-s.settings.timer&&(clearInterval(e),s.close())},s.settings.timer)}},close:function(){var s=this,e=parseInt(this.$ele.css(this.settings.placement.from)),i=!1;this.$ele.attr("data-closing","true").addClass(this.settings.animate.exit),s.reposition(e),t.isFunction(s.settings.onClose)&&s.settings.onClose.call(this.$ele),this.$ele.one(this.animations.start,function(){i=!0}).one(this.animations.end,function(){t(this).remove(),t.isFunction(s.settings.onClosed)&&s.settings.onClosed.call(this)}),setTimeout(function(){i||(s.$ele.remove(),s.settings.onClosed&&s.settings.onClosed(s.$ele))},600)},reposition:function(s){var e=this,i='[data-notify-position="'+this.settings.placement.from+"-"+this.settings.placement.align+'"]:not([data-closing="true"])',n=this.$ele.nextAll(i);this.settings.newest_on_top===!0&&(n=this.$ele.prevAll(i)),n.each(function(){t(this).css(e.settings.placement.from,s),s=parseInt(s)+parseInt(e.settings.spacing)+t(this).outerHeight()})}}),t.notify=function(t,s){var i=new e(this,t,s);return i.notify},t.notifyDefaults=function(s){return i=t.extend(!0,{},i,s)},t.notifyClose=function(s){"warning"===s&&(s="danger"),"undefined"==typeof s||"all"===s?t("[data-notify]").find('[data-notify="dismiss"]').trigger("click"):"success"===s||"info"===s||"warning"===s||"danger"===s?t(".alert-"+s+"[data-notify]").find('[data-notify="dismiss"]').trigger("click"):s?t(s+"[data-notify]").find('[data-notify="dismiss"]').trigger("click"):t('[data-notify-position="'+s+'"]').find('[data-notify="dismiss"]').trigger("click")},t.notifyCloseExcept=function(s){"warning"===s&&(s="danger"),"success"===s||"info"===s||"warning"===s||"danger"===s?t("[data-notify]").not(".alert-"+s).find('[data-notify="dismiss"]').trigger("click"):t("[data-notify]").not(s).find('[data-notify="dismiss"]').trigger("click")}});
\ No newline at end of file
diff --git a/dmp-frontend/src/assets/custom.css b/dmp-frontend/src/assets/custom.css
new file mode 100644
index 000000000..e69de29bb
diff --git a/dmp-frontend/src/assets/custom.js b/dmp-frontend/src/assets/custom.js
new file mode 100644
index 000000000..eb5dc8256
--- /dev/null
+++ b/dmp-frontend/src/assets/custom.js
@@ -0,0 +1,38 @@
+
+var sign_out_google = (function() {
+ var auth2 = gapi.auth2.getAuthInstance();
+ auth2.signOut().then(function () {
+ console.log('User signed out from google.');
+ });
+});
+
+
+var simple_notifier = (function(type, title, message) {
+ return notify(type, title, message, null, null, null, null, null, null, null, null, null, null);
+});
+
+
+
+function notify(type, title, message, delay, icon, url, target, allow_dismiss, offset_x, offset_y, animate_enter, animate_exit, newest_on_top){
+
+ var options = {};
+ if(icon!=null) options.icon = icon;
+ if(title!=null) options.title = title;
+ if(message!=null) options.message = message;
+ if(url!=null) options.url = url;
+ if(target!=null) options.target = target;
+
+ var settings = {};
+ if(type!=null) settings.type = type;
+ if(allow_dismiss!=null) settings.allow_dismiss = allow_dismiss;
+ if(delay!=null) settings.delay = delay;
+ //settings.delay = -1;
+
+ return $.notify(options,settings, delay);
+
+}
+
+
+
+
+
diff --git a/dmp-frontend/src/assets/icons/google-icon.svg b/dmp-frontend/src/assets/icons/google-icon.svg
new file mode 100644
index 000000000..06dc52f0a
--- /dev/null
+++ b/dmp-frontend/src/assets/icons/google-icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/dmp-frontend/src/assets/icons/google-logo.svg b/dmp-frontend/src/assets/icons/google-logo.svg
new file mode 100644
index 000000000..519fe653e
--- /dev/null
+++ b/dmp-frontend/src/assets/icons/google-logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/dmp-frontend/src/assets/icons/google_logo.png b/dmp-frontend/src/assets/icons/google_logo.png
new file mode 100644
index 000000000..dd259538d
Binary files /dev/null and b/dmp-frontend/src/assets/icons/google_logo.png differ
diff --git a/dmp-frontend/src/assets/icons/index.dual-gear-loading-icon.svg b/dmp-frontend/src/assets/icons/index.dual-gear-loading-icon.svg
new file mode 100644
index 000000000..22f36a1ef
--- /dev/null
+++ b/dmp-frontend/src/assets/icons/index.dual-gear-loading-icon.svg
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/dmp-frontend/src/assets/icons/user-icon.png b/dmp-frontend/src/assets/icons/user-icon.png
new file mode 100644
index 000000000..fa881fcdd
Binary files /dev/null and b/dmp-frontend/src/assets/icons/user-icon.png differ
diff --git a/dmp-frontend/src/assets/jquery.json-viewer.css b/dmp-frontend/src/assets/jquery.json-viewer.css
new file mode 100644
index 000000000..2c72ae5fa
--- /dev/null
+++ b/dmp-frontend/src/assets/jquery.json-viewer.css
@@ -0,0 +1,47 @@
+/* Syntax highlighting for JSON objects */
+ul.json-dict, ol.json-array {
+ list-style-type: none;
+ margin: 0 0 0 1px;
+ border-left: 1px dotted #ccc;
+ padding-left: 2em;
+}
+.json-string {
+ color: #0B7500;
+}
+.json-literal {
+ color: #1A01CC;
+ font-weight: bold;
+}
+
+/* Toggle button */
+a.json-toggle {
+ position: relative;
+ color: inherit;
+ text-decoration: none;
+}
+a.json-toggle:focus {
+ outline: none;
+}
+a.json-toggle:before {
+ color: #aaa;
+ content: "\25BC"; /* down arrow */
+ position: absolute;
+ display: inline-block;
+ width: 1em;
+ left: -1em;
+}
+a.json-toggle.collapsed:before {
+ transform: rotate(-90deg); /* Use rotated down arrow, prevents right arrow appearing smaller than down arrow in some browsers */
+ -ms-transform: rotate(-90deg);
+ -webkit-transform: rotate(-90deg);
+}
+
+/* Collapsable placeholder links */
+a.json-placeholder {
+ color: #aaa;
+ padding: 0 1em;
+ text-decoration: none;
+}
+a.json-placeholder:hover {
+ text-decoration: underline;
+}
diff --git a/dmp-frontend/src/assets/jquery.json-viewer.js b/dmp-frontend/src/assets/jquery.json-viewer.js
new file mode 100644
index 000000000..3ecbc3f7b
--- /dev/null
+++ b/dmp-frontend/src/assets/jquery.json-viewer.js
@@ -0,0 +1,148 @@
+/**
+ * jQuery json-viewer
+ * @author: Alexandre Bodelot
+ */
+(function($){
+
+ /**
+ * Check if arg is either an array with at least 1 element, or a dict with at least 1 key
+ * @return boolean
+ */
+ function isCollapsable(arg) {
+ return arg instanceof Object && Object.keys(arg).length > 0;
+ }
+
+ /**
+ * Check if a string represents a valid url
+ * @return boolean
+ */
+ function isUrl(string) {
+ var regexp = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
+ return regexp.test(string);
+ }
+
+ /**
+ * Transform a json object into html representation
+ * @return string
+ */
+ function json2html(json, options) {
+ var html = '';
+ if (typeof json === 'string') {
+ /* Escape tags */
+ json = json.replace(/&/g, '&').replace(//g, '>');
+ if (isUrl(json))
+ html += '' + json + ' ';
+ else
+ html += '"' + json + '" ';
+ }
+ else if (typeof json === 'number') {
+ html += '' + json + ' ';
+ }
+ else if (typeof json === 'boolean') {
+ html += '' + json + ' ';
+ }
+ else if (json === null) {
+ html += 'null ';
+ }
+ else if (json instanceof Array) {
+ if (json.length > 0) {
+ html += '[';
+ for (var i = 0; i < json.length; ++i) {
+ html += '';
+ /* Add toggle button if item is collapsable */
+ if (isCollapsable(json[i])) {
+ html += ' ';
+ }
+ html += json2html(json[i], options);
+ /* Add comma if item is not last */
+ if (i < json.length - 1) {
+ html += ',';
+ }
+ html += ' ';
+ }
+ html += ' ]';
+ }
+ else {
+ html += '[]';
+ }
+ }
+ else if (typeof json === 'object') {
+ var key_count = Object.keys(json).length;
+ if (key_count > 0) {
+ html += '{';
+ for (var key in json) {
+ if (json.hasOwnProperty(key)) {
+ html += '';
+ var keyRepr = options.withQuotes ?
+ '"' + key + '" ' : key;
+ /* Add toggle button if item is collapsable */
+ if (isCollapsable(json[key])) {
+ html += '' + keyRepr + ' ';
+ }
+ else {
+ html += keyRepr;
+ }
+ html += ': ' + json2html(json[key], options);
+ /* Add comma if item is not last */
+ if (--key_count > 0)
+ html += ',';
+ html += ' ';
+ }
+ }
+ html += ' }';
+ }
+ else {
+ html += '{}';
+ }
+ }
+ return html;
+ }
+
+ /**
+ * jQuery plugin method
+ * @param json: a javascript object
+ * @param options: an optional options hash
+ */
+ $.fn.jsonViewer = function(json, options) {
+ options = options || {};
+
+ /* jQuery chaining */
+ return this.each(function() {
+
+ /* Transform to HTML */
+ var html = json2html(json, options);
+ if (isCollapsable(json))
+ html = ' ' + html;
+
+ /* Insert HTML in target DOM element */
+ $(this).html(html);
+
+ /* Bind click on toggle buttons */
+ $(this).off('click');
+ $(this).on('click', 'a.json-toggle', function() {
+ var target = $(this).toggleClass('collapsed').siblings('ul.json-dict, ol.json-array');
+ target.toggle();
+ if (target.is(':visible')) {
+ target.siblings('.json-placeholder').remove();
+ }
+ else {
+ var count = target.children('li').length;
+ var placeholder = count + (count > 1 ? ' items' : ' item');
+ target.after('' + placeholder + ' ');
+ }
+ return false;
+ });
+
+ /* Simulate click on toggle button when placeholder is clicked */
+ $(this).on('click', 'a.json-placeholder', function() {
+ $(this).siblings('a.json-toggle').click();
+ return false;
+ });
+
+ if (options.collapsed == true) {
+ /* Trigger click to collapse all nodes */
+ $(this).find('a.json-toggle').click();
+ }
+ });
+ };
+})(jQuery);
diff --git a/dmp-frontend/src/assets/simple-sidebar.css b/dmp-frontend/src/assets/simple-sidebar.css
new file mode 100644
index 000000000..390dc906b
--- /dev/null
+++ b/dmp-frontend/src/assets/simple-sidebar.css
@@ -0,0 +1,122 @@
+/*!
+ * Start Bootstrap - Simple Sidebar (https://startbootstrap.com/template-overviews/simple-sidebar)
+ * Copyright 2013-2017 Start Bootstrap
+ * Licensed under MIT (https://github.com/BlackrockDigital/startbootstrap-simple-sidebar/blob/master/LICENSE)
+ */
+
+body {
+ overflow-x: hidden;
+}
+
+#wrapper {
+ padding-left: 0;
+ -webkit-transition: all 0.5s ease;
+ -moz-transition: all 0.5s ease;
+ -o-transition: all 0.5s ease;
+ transition: all 0.5s ease;
+}
+
+#wrapper.toggled {
+ padding-left: 250px;
+}
+
+#sidebar-wrapper {
+ z-index: 1000;
+ position: fixed;
+ left: 250px;
+ width: 0;
+ height: 100%;
+ margin-left: -250px;
+ overflow-y: auto;
+ background: #000;
+ -webkit-transition: all 0.5s ease;
+ -moz-transition: all 0.5s ease;
+ -o-transition: all 0.5s ease;
+ transition: all 0.5s ease;
+}
+
+#wrapper.toggled #sidebar-wrapper {
+ width: 250px;
+}
+
+#page-content-wrapper {
+ width: 100%;
+ position: absolute;
+ padding: 15px;
+}
+
+#wrapper.toggled #page-content-wrapper {
+ position: absolute;
+ margin-right: -250px;
+}
+
+
+/* Sidebar Styles */
+
+.sidebar-nav {
+ position: absolute;
+ top: 0;
+ width: 250px;
+ margin: 0;
+ padding: 0;
+ list-style: none;
+}
+
+.sidebar-nav li {
+ text-indent: 20px;
+ line-height: 40px;
+}
+
+.sidebar-nav li a {
+ display: block;
+ text-decoration: none;
+ color: #999999;
+}
+
+.sidebar-nav li a:hover {
+ text-decoration: none;
+ color: #fff;
+ background: rgba(255, 255, 255, 0.2);
+}
+
+.sidebar-nav li a:active, .sidebar-nav li a:focus {
+ text-decoration: none;
+}
+
+.sidebar-nav>.sidebar-brand {
+ height: 65px;
+ font-size: 18px;
+ line-height: 60px;
+}
+
+.sidebar-nav>.sidebar-brand a {
+ color: #999999;
+}
+
+.sidebar-nav>.sidebar-brand a:hover {
+ color: #fff;
+ background: none;
+}
+
+@media(min-width:768px) {
+ #wrapper {
+ padding-left: 0;
+ }
+ #wrapper.toggled {
+ padding-left: 250px;
+ }
+ #sidebar-wrapper {
+ width: 0;
+ }
+ #wrapper.toggled #sidebar-wrapper {
+ width: 250px;
+ }
+ #page-content-wrapper {
+ padding: 20px;
+ position: relative;
+ }
+ #wrapper.toggled #page-content-wrapper {
+ position: relative;
+ margin-right: 0;
+ }
+}
diff --git a/dmp-frontend/src/assets/vkbeautify.0.99.00.js b/dmp-frontend/src/assets/vkbeautify.0.99.00.js
new file mode 100644
index 000000000..57effaeca
--- /dev/null
+++ b/dmp-frontend/src/assets/vkbeautify.0.99.00.js
@@ -0,0 +1,358 @@
+/**
+* vkBeautify - javascript plugin to pretty-print or minify text in XML, JSON, CSS and SQL formats.
+*
+* Version - 0.99.00.beta
+* Copyright (c) 2012 Vadim Kiryukhin
+* vkiryukhin @ gmail.com
+* http://www.eslinstructor.net/vkbeautify/
+*
+* Dual licensed under the MIT and GPL licenses:
+* http://www.opensource.org/licenses/mit-license.php
+* http://www.gnu.org/licenses/gpl.html
+*
+* Pretty print
+*
+* vkbeautify.xml(text [,indent_pattern]);
+* vkbeautify.json(text [,indent_pattern]);
+* vkbeautify.css(text [,indent_pattern]);
+* vkbeautify.sql(text [,indent_pattern]);
+*
+* @text - String; text to beatufy;
+* @indent_pattern - Integer | String;
+* Integer: number of white spaces;
+* String: character string to visualize indentation ( can also be a set of white spaces )
+* Minify
+*
+* vkbeautify.xmlmin(text [,preserve_comments]);
+* vkbeautify.jsonmin(text);
+* vkbeautify.cssmin(text [,preserve_comments]);
+* vkbeautify.sqlmin(text);
+*
+* @text - String; text to minify;
+* @preserve_comments - Bool; [optional];
+* Set this flag to true to prevent removing comments from @text ( minxml and mincss functions only. )
+*
+* Examples:
+* vkbeautify.xml(text); // pretty print XML
+* vkbeautify.json(text, 4 ); // pretty print JSON
+* vkbeautify.css(text, '. . . .'); // pretty print CSS
+* vkbeautify.sql(text, '----'); // pretty print SQL
+*
+* vkbeautify.xmlmin(text, true);// minify XML, preserve comments
+* vkbeautify.jsonmin(text);// minify JSON
+* vkbeautify.cssmin(text);// minify CSS, remove comments ( default )
+* vkbeautify.sqlmin(text);// minify SQL
+*
+*/
+
+(function() {
+
+function createShiftArr(step) {
+
+ var space = ' ';
+
+ if ( isNaN(parseInt(step)) ) { // argument is string
+ space = step;
+ } else { // argument is integer
+ switch(step) {
+ case 1: space = ' '; break;
+ case 2: space = ' '; break;
+ case 3: space = ' '; break;
+ case 4: space = ' '; break;
+ case 5: space = ' '; break;
+ case 6: space = ' '; break;
+ case 7: space = ' '; break;
+ case 8: space = ' '; break;
+ case 9: space = ' '; break;
+ case 10: space = ' '; break;
+ case 11: space = ' '; break;
+ case 12: space = ' '; break;
+ }
+ }
+
+ var shift = ['\n']; // array of shifts
+ for(ix=0;ix<100;ix++){
+ shift.push(shift[ix]+space);
+ }
+ return shift;
+}
+
+function vkbeautify(){
+ this.step = ' '; // 4 spaces
+ this.shift = createShiftArr(this.step);
+};
+
+vkbeautify.prototype.xml = function(text,step) {
+
+ var ar = text.replace(/>\s{0,}<")
+ .replace(/ or -1) {
+ str += shift[deep]+ar[ix];
+ inComment = true;
+ // end comment or //
+ if(ar[ix].search(/-->/) > -1 || ar[ix].search(/\]>/) > -1 || ar[ix].search(/!DOCTYPE/) > -1 ) {
+ inComment = false;
+ }
+ } else
+ // end comment or //
+ if(ar[ix].search(/-->/) > -1 || ar[ix].search(/\]>/) > -1) {
+ str += ar[ix];
+ inComment = false;
+ } else
+ // //
+ if( /^<\w/.exec(ar[ix-1]) && /^<\/\w/.exec(ar[ix]) &&
+ /^<[\w:\-\.\,]+/.exec(ar[ix-1]) == /^<\/[\w:\-\.\,]+/.exec(ar[ix])[0].replace('/','')) {
+ str += ar[ix];
+ if(!inComment) deep--;
+ } else
+ // //
+ if(ar[ix].search(/<\w/) > -1 && ar[ix].search(/<\//) == -1 && ar[ix].search(/\/>/) == -1 ) {
+ str = !inComment ? str += shift[deep++]+ar[ix] : str += ar[ix];
+ } else
+ // ... //
+ if(ar[ix].search(/<\w/) > -1 && ar[ix].search(/<\//) > -1) {
+ str = !inComment ? str += shift[deep]+ar[ix] : str += ar[ix];
+ } else
+ // //
+ if(ar[ix].search(/<\//) > -1) {
+ str = !inComment ? str += shift[--deep]+ar[ix] : str += ar[ix];
+ } else
+ // //
+ if(ar[ix].search(/\/>/) > -1 ) {
+ str = !inComment ? str += shift[deep]+ar[ix] : str += ar[ix];
+ } else
+ // xml ... ?> //
+ if(ar[ix].search(/<\?/) > -1) {
+ str += shift[deep]+ar[ix];
+ } else
+ // xmlns //
+ if( ar[ix].search(/xmlns\:/) > -1 || ar[ix].search(/xmlns\=/) > -1) {
+ str += shift[deep]+ar[ix];
+ }
+
+ else {
+ str += ar[ix];
+ }
+ }
+
+ return (str[0] == '\n') ? str.slice(1) : str;
+}
+
+vkbeautify.prototype.json = function(text,step) {
+
+ var step = step ? step : this.step;
+
+ if (typeof JSON === 'undefined' ) return text;
+
+ if ( typeof text === "string" ) return JSON.stringify(JSON.parse(text), null, step);
+ if ( typeof text === "object" ) return JSON.stringify(text, null, step);
+
+ return text; // text is not string nor object
+}
+
+vkbeautify.prototype.css = function(text, step) {
+
+ var ar = text.replace(/\s{1,}/g,' ')
+ .replace(/\{/g,"{~::~")
+ .replace(/\}/g,"~::~}~::~")
+ .replace(/\;/g,";~::~")
+ .replace(/\/\*/g,"~::~/*")
+ .replace(/\*\//g,"*/~::~")
+ .replace(/~::~\s{0,}~::~/g,"~::~")
+ .split('~::~'),
+ len = ar.length,
+ deep = 0,
+ str = '',
+ ix = 0,
+ shift = step ? createShiftArr(step) : this.shift;
+
+ for(ix=0;ix/g,"")
+ .replace(/[ \r\n\t]{1,}xmlns/g, ' xmlns');
+ return str.replace(/>\s{0,}<");
+}
+
+vkbeautify.prototype.jsonmin = function(text) {
+
+ if (typeof JSON === 'undefined' ) return text;
+
+ return JSON.stringify(JSON.parse(text), null, 0);
+
+}
+
+vkbeautify.prototype.cssmin = function(text, preserveComments) {
+
+ var str = preserveComments ? text
+ : text.replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+\//g,"") ;
+
+ return str.replace(/\s{1,}/g,' ')
+ .replace(/\{\s{1,}/g,"{")
+ .replace(/\}\s{1,}/g,"}")
+ .replace(/\;\s{1,}/g,";")
+ .replace(/\/\*\s{1,}/g,"/*")
+ .replace(/\*\/\s{1,}/g,"*/");
+}
+
+vkbeautify.prototype.sqlmin = function(text) {
+ return text.replace(/\s{1,}/g," ").replace(/\s{1,}\(/,"(").replace(/\s{1,}\)/,")");
+}
+
+window.vkbeautify = new vkbeautify();
+
+})();
+
diff --git a/dmp-frontend/src/index.html b/dmp-frontend/src/index.html
index 374d0f02d..c01e0f2ae 100644
--- a/dmp-frontend/src/index.html
+++ b/dmp-frontend/src/index.html
@@ -1,22 +1,49 @@
-
+
+
+
+
+ Digital Management Plans Creator APP
+
+
+
+
-
-
-
-
-
-
-
- Data Management Plans - Manager
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -31,15 +58,7 @@
}
-
-
-
Data Management Plan
-
-
-
-
+
+
diff --git a/dmp-frontend/src/styles.css b/dmp-frontend/src/styles.css
index 272697696..76065f8d8 100644
--- a/dmp-frontend/src/styles.css
+++ b/dmp-frontend/src/styles.css
@@ -1,11 +1,11 @@
/* You can add global styles to this file, and also import other style files */
-
+/*
body {
padding-top: 40px;
padding-bottom: 40px;
background-color: #eee;
}
-
+ */
.form-signin {
max-width: 330px;
padding: 15px;