This commit is contained in:
annampak 2017-12-14 12:47:39 +02:00
commit 3ab46d7b53
25 changed files with 7348 additions and 9347 deletions

File diff suppressed because it is too large Load Diff

View File

@ -12,17 +12,21 @@
},
"private": true,
"dependencies": {
"@angular/animations": "4.3.6",
"@angular/common": "4.3.6",
"@angular/compiler": "4.3.6",
"@angular/core": "4.3.6",
"@angular/forms": "4.3.6",
"@angular/http": "4.3.6",
"@angular/platform-browser": "4.3.6",
"@angular/platform-browser-dynamic": "4.3.6",
"@angular/router": "4.3.6",
"@ng-bootstrap/ng-bootstrap": "1.0.0-beta.5",
"@angular/animations": "^5.1.1",
"@angular/cdk": "^5.0.1",
"@angular/common": "5.1.1",
"@angular/compiler": "5.1.1",
"@angular/core": "5.1.1",
"@angular/forms": "5.1.1",
"@angular/http": "5.1.1",
"@angular/material": "^5.0.1",
"@angular/platform-browser": "5.1.1",
"@angular/platform-browser-dynamic": "5.1.1",
"@angular/router": "5.1.1",
"@ng-bootstrap/ng-bootstrap": "1.0.0-beta.7",
"@ngui/auto-complete": "^0.16.0",
"@ngx-translate/core": "^9.0.1",
"@ngx-translate/http-loader": "^2.0.0",
"angular-2-data-table": "^0.1.2",
"angular-4-data-table-bootstrap-4": "^0.2.0",
"angular-google-signin": "^0.1.5",
@ -39,31 +43,31 @@
"ng-sidebar": "^6.0.4",
"ng2-datepicker": "^2.1.3",
"ng4-loading-spinner": "^1.0.27",
"ngx-webstorage": "^1.8.0",
"primeng": "^4.3.0",
"ngx-webstorage": "^2.0.1",
"primeng": "^5.0.2",
"rxjs": "^5.4.2",
"zone.js": "^0.8.17"
},
"devDependencies": {
"@angular/cli": "1.3.1",
"@angular/compiler-cli": "^4.3.6",
"@angular/language-service": "^4.3.6",
"@types/jasmine": "~2.5.53",
"@angular/cli": "1.6.1",
"@angular/compiler-cli": "^5.1.1",
"@angular/language-service": "^5.1.1",
"@types/jasmine": "~2.8.2",
"@types/jasminewd2": "~2.0.2",
"@types/node": "^6.0.90",
"@types/node": "^8.5.1",
"angular-ide": "^0.9.31",
"codelyzer": "~3.1.1",
"jasmine-core": "~2.6.2",
"jasmine-spec-reporter": "~4.1.0",
"codelyzer": "~4.0.2",
"jasmine-core": "~2.8.0",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~1.7.0",
"karma-chrome-launcher": "~2.1.1",
"karma-chrome-launcher": "~2.2.0",
"karma-cli": "~1.0.1",
"karma-coverage-istanbul-reporter": "^1.2.1",
"karma-jasmine": "~1.1.0",
"karma-jasmine-html-reporter": "^0.2.2",
"protractor": "~5.1.2",
"ts-node": "~3.2.0",
"tslint": "~5.3.2",
"typescript": "~2.3.3"
"protractor": "~5.2.2",
"ts-node": "~4.0.1",
"tslint": "~5.8.0",
"typescript": "^2.4.2"
}
}

View File

@ -1,21 +1,11 @@
<div>
<app-navigation></app-navigation>
<div class="container">
<router-outlet></router-outlet>
</div>
<!-- <div>
<nav class="navbar navbar-default shadowed">
<div class="col-md-5">
<!--
<button class="btn btn-primary " [ngClass]="{true:'visible', false:'invisible'}[tokenService.isLoggedIn() == true]" (click)='slideNav()'>
<span style="font-size:20px;cursor:pointer" >&#9776;</span>
</button>
-->
<div class="nav navbar-nav navbar-left">
<!--
<div class="dropdown" [ngClass]="{false:'invisible'}[tokenService.isLoggedIn() == true]">
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown"> Go To <span class="caret"></span> </button>
<ul class="dropdown-menu">
<li><a class="cursor" (click)="goToDMPs()">My DMPs</a></li>
<li><a class="cursor" (click)="goToProjects()">My Projects</a></li>
</ul>
</div>
-->
<li class="dropdown" [ngClass]="{false:'invisible'}[tokenService.isLoggedIn() == true]">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Quick Navigate
<span class="caret"></span>
@ -80,9 +70,9 @@
</div>
<!-- breadcrumb bar -->
<div class="col-md-12">
<breadcrumb></breadcrumb>
</div>
<router-outlet></router-outlet>
</div> -->
<!--
<router-outlet></router-outlet> -->

View File

@ -7,6 +7,7 @@ import { MainSignInComponent } from './login/main-sign-in/main-sign-in.component
import {BreadcrumbModule,MenuItem} from 'primeng/primeng';
import { BreadcrumbComponent } from './widgets/breadcrumb/breadcrumb.component';
import { TranslateService } from '@ngx-translate/core';
declare const gapi: any;
@ -31,7 +32,11 @@ export class AppComponent implements OnInit {
constructor(private tokenService : TokenService, private router: Router, private route: ActivatedRoute) {
constructor(private tokenService : TokenService, private router: Router, private route: ActivatedRoute, private translate: TranslateService) {
// this language will be used as a fallback when a translation isn't found in the current language
translate.setDefaultLang('en');
// the lang to use, if the lang isn't available, it will use the current loader to get them
translate.use('en');
}

View File

@ -0,0 +1,5 @@
export const HostConfiguration = {
Server: 'http://localhost:4200/',
//CASHost: 'https://login-devel.uoa.gr/login',
//Service: 'http://elkefinman/login'
}

View File

@ -1,23 +1,23 @@
import { PaginationService } from './form/pagination/pagination-service';
import {
TableOfContentsFieldComponent,
TableOfContentsFieldComponent,
} from './form/tableOfContents/table-of-content-field/table-of-content-field.component';
import { ProgressBarComponent } from './form/pprogress-bar/progress-bar.component';
import {
TableOfContentsSectionComponent,
TableOfContentsSectionComponent,
} from './form/tableOfContents/table-of-content-section/table-of-content-section.component';
import {
TableOfContentsGroupComponent,
TableOfContentsGroupComponent,
} from './form/tableOfContents/table-of-content-group/table-of-content-group.component';
import {
TableOfContentsFieldSetComponent,
TableOfContentsFieldSetComponent,
} from './form/tableOfContents/table-of-content-fieldset/table-of-content-fieldset.component';
import { TableOfContentsComponent } from './form/tableOfContents/table-of-contents.component';
import {
DynamicFieldRadioBoxComponent,
DynamicFieldRadioBoxComponent,
} from './form/dynamic-fields/dynamic-field-radiobox/dynamic-field-radiobox.component';
import {
DynamicFieldBooleanDecisionComponent,
DynamicFieldBooleanDecisionComponent,
} from './form/dynamic-fields/dynamic-field-boolean-decision/dynamic-field-boolean-decision.component';
import { AutocompleteRemoteComponent } from './form/dynamic-fields/dynamic-field-autocomplete/autocomplete-remote.component';
import { DynamicFieldDropdownComponent } from './form/dynamic-fields/dynamic-field-dropdown/dynamic-field-dropdown';
@ -28,13 +28,11 @@ import { DynamicFormCompositeFieldComponent } from './form/dynamic-form-composit
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, forwardRef } from '@angular/core';
import { FormsModule, ReactiveFormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { HttpClientModule, HttpClient } from '@angular/common/http';
import { HttpModule } from '@angular/http';
import { RouterModule, Routes, Router } from '@angular/router';
import { DataTableModule } from "angular2-datatable";
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { AppComponent } from './app.component';
import { RestBase } from './services/rest-base';
import { DynamicFormComponent } from './form/dynamic-form.component';
@ -81,7 +79,7 @@ import { DmpVersionFilterPipe } from './pipes/dmp-version-filter.pipe';
import { ProjectTableFilterPipe } from './pipes/project-table-filter.pipe';
import { ProjectsComponent } from './projects/projects.component';
import { ProjectsComponent } from './projects/projects.component';
import { ModalComponent } from './modal/modal.component';
import { NgDatepickerModule } from 'ng2-datepicker';
@ -93,12 +91,21 @@ import { BreadcrumbComponent } from './widgets/breadcrumb/breadcrumb.component';
import { DmpDetailedComponent } from './viewers/dmp-detailed/dmp-detailed.component';
import { ProjectDetailedComponent } from './viewers/project-detailed/project-detailed.component';
import {ProgressBarModule} from 'primeng/primeng';
import {StepsModule,MenuItem} from 'primeng/primeng';
import {CheckboxModule} from 'primeng/primeng';
import {RadioButtonModule} from 'primeng/primeng';
import {AutoCompleteModule} from 'primeng/primeng';
import {NgbModule} from '@ng-bootstrap/ng-bootstrap';
import { ProgressBarModule } from 'primeng/primeng';
import { StepsModule, MenuItem } from 'primeng/primeng';
import { CheckboxModule } from 'primeng/primeng';
import { RadioButtonModule } from 'primeng/primeng';
import { AutoCompleteModule } from 'primeng/primeng';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { TranslateModule } from '@ngx-translate/core';
import { TranslateLoader } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { SharedModule } from './shared/shared.module';
import { MaterialModule } from './shared/material/material.module';
import { AuthService } from './services/auth/auth.service';
@NgModule({
declarations: [
@ -135,11 +142,13 @@ import {NgbModule} from '@ng-bootstrap/ng-bootstrap';
TableOfContentsFieldComponent,
ProgressBarComponent,
DynamicFieldCheckBoxComponent,
BreadcrumbComponent, DmpDetailedComponent, ProjectDetailedComponent
BreadcrumbComponent, DmpDetailedComponent, ProjectDetailedComponent,
],
imports: [
BrowserModule,
ReactiveFormsModule,
SharedModule,
FormsModule,
HttpModule,
HttpClientModule,
@ -160,14 +169,25 @@ import {NgbModule} from '@ng-bootstrap/ng-bootstrap';
StepsModule,
CheckboxModule,
RadioButtonModule,
AutoCompleteModule
AutoCompleteModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient]
}
}),
BrowserAnimationsModule,
MaterialModule
],
providers: [{
provide: HTTP_INTERCEPTORS,
useClass: GlobalInterceptor,
multi: true,
},
ServerService, VisibilityRulesService,PaginationService, GlobalVariables, AuthGuard, TokenService, LocalStorageService, RestBase, EestoreService, NativeLoginService, PDFService
ServerService, VisibilityRulesService, PaginationService, GlobalVariables, AuthGuard, TokenService,
LocalStorageService, RestBase, EestoreService, NativeLoginService, PDFService,
AuthService
],
bootstrap: [AppComponent]
})
@ -175,3 +195,7 @@ export class AppModule {
constructor() {
}
}
export function HttpLoaderFactory(httpClient: HttpClient) {
return new TranslateHttpLoader(httpClient, 'assets/lang/', '.json');
}

View File

@ -1,4 +1,4 @@
<app-spinner> </app-spinner>
<!-- <app-spinner> </app-spinner> -->
<table class="table table-striped" [mfData]="tableData | datasetTableFilter : filterQuery | datasetstatusFilter: statusFilter"
#mf="mfDataTable" [mfRowsOnPage]="rowsOnPage" [(mfSortBy)]="sortBy" [(mfSortOrder)]="sortOrder">

View File

@ -0,0 +1,3 @@
export interface Serializable<T> {
fromJSONObject(item: Object): T;
}

View File

@ -0,0 +1,4 @@
export class Credential {
public username: string;
public password: string;
}

View File

@ -0,0 +1,4 @@
export class LoginInfo {
public ticket: string;
public service: string;
}

View File

@ -0,0 +1,26 @@
import { Serializable } from '../Serializable';
export class Principal implements Serializable<Principal> {
id: number;
token: string;
name: string;
expiresAt: Date;
appRoles: Principal.AppRole[];
fromJSONObject(item: any): Principal {
this.id = item.id;
this.token = item.token;
this.name = item.name;
this.expiresAt = item.expiresAt;
this.appRoles = item.appRoles;
return this;
}
}
export namespace Principal {
export enum AppRole {
Admin = 0,
User = 1
}
}

View File

@ -0,0 +1,135 @@
import { Injectable } from '@angular/core';
import { HttpHeaders } from '@angular/common/http';
import { HttpClient } from '@angular/common/http';
import { HostConfiguration } from '../../app.constants';
import { Principal } from '../../models/login/Principal';
import { Credential } from '../../models/login/Credential';
import { Observable } from 'rxjs/Rx';
import { MatSnackBar } from '@angular/material';
import { TranslateService } from '@ngx-translate/core';
import { Router } from '@angular/router';
import { JsonSerializer } from '../../utilities/JsonSerializer';
import { LoginInfo } from '../../models/login/LoginInfo';
import { SnackBarNotificationComponent } from '../../shared/components/notificaiton/snack-bar-notification.component';
@Injectable()
export class AuthService {
private actionUrl: string;
private headers: HttpHeaders;
constructor(
private http: HttpClient,
public snackBar: MatSnackBar,
public language: TranslateService,
public router: Router
) {
this.actionUrl = HostConfiguration.Server + 'api/auth/';
this.headers = new HttpHeaders();
this.headers = this.headers.set('Content-Type', 'application/json');
this.headers = this.headers.set('Accept', 'application/json');
}
private clear(): void {
localStorage.removeItem('principal');
}
public current(principal?: Principal): Principal {
if (principal) {
localStorage.setItem('principal', JSON.stringify(principal));
return principal;
}
const principalJson = localStorage.getItem('principal');
if (!principalJson) { return null; }
const principalObj = JSON.parse(principalJson) as Principal;
return principalObj;
}
//public login(credential: Credential): Observable<Principal> {
// const url = this.actionUrl + 'login';
// return this.http.post(url, credential, { headers: this.headers })
// .map((res: Response) => {
// let principal = this.current(new JsonSerializer<Principal>().fromJSONObject(res, Principal));
// //this.loginContextSubject.next(true);
// return principal;
// })
// .catch((error: any) => {
// //this.loginContextSubject.next(false);
// return Observable.throw(error);
// });
//}
public login(loginInfo: LoginInfo): Observable<Principal> {
const url = this.actionUrl + 'login';
return this.http.post(url, loginInfo, { headers: this.headers })
.map((res: Response) => {
const principal = this.current(new JsonSerializer<Principal>().fromJSONObject(res, Principal));
//this.loginContextSubject.next(true);
return principal;
})
.catch((error: any) => {
//this.loginContextSubject.next(false);
return Observable.throw(error);
});
}
public logout(): void {
const url = this.actionUrl + 'logout';
const principal = this.current();
this.clear();
if (!principal) { return; }
let headers = this.headers;
headers = headers.set('AuthToken', principal.token)
this.http.post(url, null, { headers: headers }).subscribe(
res => this.onLogOutSuccess(res),
error => this.onLogOutError(error)
)
}
public me(): Observable<Principal> {
const url = this.actionUrl + '/me';
const principal = this.current();
if (!principal) {
this.clear();
return Observable.of<Principal>();
}
let headers = this.headers;
headers = headers.set('AuthToken', principal.token)
return this.http.post(url, null, { headers: headers })
.map((r: Response) => {
const princ = this.current(new JsonSerializer<Principal>().fromJSONObject(r.json(), Principal));
//this.loginContextSubject.next(true);
return princ;
})
.catch((error: any) => {
console.warn('could not retrieve me info:\n', error);
this.clear();
const princ = this.current();
this.router.navigate(['/login']);
return Observable.of<Principal>(princ);
});
}
public onLogOutSuccess(logoutMessage: any) {
this.snackBar.openFromComponent(SnackBarNotificationComponent, {
data: { message: 'GENERAL.SNACK-BAR.SUCCESSFUL-LOGOUT', language: this.language },
duration: 3000,
extraClasses: ['snackbar-success']
})
this.router.navigate(['/login']);
}
public onLogOutError(errorMessage: string) {
console.log(errorMessage);
this.snackBar.openFromComponent(SnackBarNotificationComponent, {
data: { message: 'GENERAL.SNACK-BAR.UNSUCCESSFUL-LOGOUT', language: this.language },
duration: 3000,
extraClasses: ['snackbar-warning']
})
this.router.navigate(['/login']);
}
}

View File

@ -0,0 +1,11 @@
.navbar-icon {
padding: 0 14px;
}
.navbar-spacer {
flex: 1 1 auto;
}
.navbar-button {
text-transform: uppercase;
}

View File

@ -0,0 +1,10 @@
<mat-toolbar color="primary">
{{'NAV-BAR.TITLE' | translate}}
<span class="navbar-spacer"></span>
<div *ngIf="isAuthenticated()">
<a mat-button class="navbar-button" routerLink="/forms">Forms</a>
<a mat-button *ngIf="isAdmin()" class="navbar-button" routerLink="/configuration">Configuration</a>
<a mat-button *ngIf="isAdmin()" class="navbar-button" routerLink="/users">Users</a>
<button mat-icon-button class="navbar-icon" (click)="logout()"><mat-icon class="navbar-icon">exit_to_app</mat-icon></button>
</div>
</mat-toolbar>

View File

@ -0,0 +1,36 @@
import { Component } from '@angular/core';
import { Principal } from '../../../models/login/Principal';
import { AuthService } from '../../../services/auth/auth.service';
@Component({
selector: 'app-navigation',
templateUrl: 'navigation.component.html',
styleUrls: ['./navigation.component.css']
})
export class NavigationComponent {
invert = false;
constructor(private authentication: AuthService) {
}
public logout(): void {
this.authentication.logout();
}
public isAuthenticated(): boolean {
return !(!this.authentication.current())
}
public isAdmin(): boolean {
if (!this.authentication.current()) { return false }
const principalRoles = this.authentication.current().appRoles;
for (let i = 0; i < principalRoles.length; i++) {
if (principalRoles[i] === Principal.AppRole.Admin) {
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,12 @@
<div class="jumbotron">
<h2>Hello {{ userInfo?.name!=null ? userInfo?.name : userInfo?.email }}</h2>
<p>Welcome {{ userInfo?.created != userInfo?.lastloggedin ? "back" : "" }} to the <a href="https://en.wikipedia.org/wiki/Data_management_plan">Data Management Plans</a> composer application. </p>
<!--
<p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p>
-->
</div>
<!--
{{userInfo | json}}
-->

View File

@ -0,0 +1,20 @@
import { TranslateService } from '@ngx-translate/core';
import { Component, Inject } from '@angular/core';
import { MAT_SNACK_BAR_DATA } from '@angular/material';
@Component({
selector: 'snack-bar-notification',
templateUrl: 'snack-bar-notification.component.html'
})
export class SnackBarNotificationComponent {
message: string;
constructor( @Inject(MAT_SNACK_BAR_DATA) public data: any) {
this.parseMessage(data.message, data.language);
}
parseMessage(message: any, language: TranslateService): void {
language.get(message).subscribe((value: string) => {
this.message = value;
});
}
}

View File

@ -0,0 +1,73 @@
import { NgModule } from '@angular/core';
import {
MatToolbarModule,
MatIconModule,
MatSidenavModule,
MatButtonModule,
MatTableModule,
MatPaginatorModule,
MatSortModule,
MatDialogModule,
MatDatepickerModule,
MatNativeDateModule,
MatInputModule,
MatFormFieldModule,
MatSnackBarModule,
MatAutocompleteModule,
MatExpansionModule,
MatSelectModule,
MatOptionModule,
MatCardModule,
MatProgressBarModule,
MatProgressSpinnerModule,
DateAdapter,
MatTooltipModule,
MatTabsModule
} from '@angular/material';
import { CdkTableModule } from '@angular/cdk/table';
import { SnackBarNotificationComponent } from '../components/notificaiton/snack-bar-notification.component';
@NgModule({
imports: [
],
exports: [
MatToolbarModule,
MatIconModule,
MatSidenavModule,
MatButtonModule,
MatTableModule,
MatPaginatorModule,
CdkTableModule,
MatSortModule,
MatDialogModule,
MatDatepickerModule,
MatNativeDateModule,
MatInputModule,
MatFormFieldModule,
MatSnackBarModule,
MatAutocompleteModule,
MatExpansionModule,
MatSelectModule,
MatOptionModule,
MatCardModule,
MatProgressBarModule,
MatProgressSpinnerModule,
MatTooltipModule,
MatTabsModule
],
providers: [
//{ provide: DateAdapter, useClass: LocalizedDateAdapter },
],
entryComponents: [
SnackBarNotificationComponent
]
})
export class MaterialModule {
// constructor(dateAdapter: DateAdapter<LocalizedDateAdapter>) {
// dateAdapter.setLocale('el-GR');
// }
}

View File

@ -0,0 +1,30 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { NavigationComponent } from './components/navigation/navigation.component';
import { SnackBarNotificationComponent } from './components/notificaiton/snack-bar-notification.component';
import { MaterialModule } from './material/material.module';
import { TranslateModule } from '@ngx-translate/core';
@NgModule({
imports: [
CommonModule,
RouterModule,
MaterialModule,
TranslateModule
],
declarations: [
NavigationComponent,
SnackBarNotificationComponent
],
exports: [
NavigationComponent,
SnackBarNotificationComponent
],
entryComponents: [
]
})
export class SharedModule { }

View File

@ -1,7 +1,7 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import {DataTableModule } from 'angular-4-data-table-bootstrap-4';
//import {DataTableModule } from 'angular-4-data-table-bootstrap-4';
import { TabComponent } from './tabs.component';
@ -12,7 +12,7 @@ import { TabRoutingModule } from './tabs-routing.module';
CommonModule,
FormsModule,
TabRoutingModule,
DataTableModule
//DataTableModule
],
declarations: [
TabComponent

View File

@ -0,0 +1,5 @@
{
"NAV-BAR": {
"TITLE": "DMPS"
}
}

View File

@ -50,6 +50,7 @@
<script src="assets/custom.js"></script>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
</head>
<body>

View File

@ -1,3 +1,5 @@
@import "~@angular/material/prebuilt-themes/indigo-pink.css";
/* You can add global styles to this file, and also import other style files */
/*
body {

View File

@ -1,7 +1,7 @@
{
"compileOnSave": false,
"compilerOptions": {
"allowJs": true,
// "allowJs": true,
"outDir": "./dist/out-tsc",
"sourceMap": true,
"declaration": false,

6855
dmp-frontend/yarn.lock Normal file

File diff suppressed because it is too large Load Diff