admin delete components, create module, native login, authguard

This commit is contained in:
annampak 2018-01-31 17:46:32 +02:00
parent 702339d9d6
commit 5f959361d9
47 changed files with 566 additions and 2433 deletions

View File

@ -23,6 +23,14 @@
"tslib": "1.7.1"
}
},
"@angular/cdk": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-5.1.1.tgz",
"integrity": "sha512-V8kQmwf1PhtxiiE0cS1x9SW7/VFrJ7LcL9RqxUOMmJMl8kVR43dQBEeuVOOYJlGo9LAR5ctfemlJHwd9+PoHew==",
"requires": {
"tslib": "1.7.1"
}
},
"@angular/cli": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/@angular/cli/-/cli-1.3.1.tgz",
@ -159,6 +167,14 @@
"integrity": "sha1-RScBGllJZ6OW7/PAXtFb1MhtUbc=",
"dev": true
},
"@angular/material": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/@angular/material/-/material-5.1.1.tgz",
"integrity": "sha512-RC3xkbX35daNq4w+XBmm+Vgi16TJvLbSkw5xkdxCqLSysFx9ymwDOjUbLeHt2nJtvYWvnSjuVukdSAeaBknTFg==",
"requires": {
"tslib": "1.7.1"
}
},
"@angular/platform-browser": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-4.4.3.tgz",

View File

@ -13,11 +13,13 @@
"private": true,
"dependencies": {
"@angular/animations": "^4.2.4",
"@angular/cdk": "^5.1.1",
"@angular/common": "^4.2.4",
"@angular/compiler": "^4.2.4",
"@angular/core": "^4.2.4",
"@angular/forms": "^4.2.4",
"@angular/http": "^4.2.4",
"@angular/material": "^5.1.1",
"@angular/platform-browser": "^4.2.4",
"@angular/platform-browser-dynamic": "^4.2.4",
"@angular/router": "^4.2.4",

View File

@ -1,13 +1,15 @@
import { CheckBoxComponent } from './components/checkbox/checkbox-component';
import { FreeTextData } from './models/DataField/FreeTextData';
import { BooleanDecisionComponent } from './components/booleanDecision/booleanDecision-component';
import { FreeTextComponent } from './components/freetext/freetext-component';
import { TextAreaComponent } from './components/textarea/textarea-component';
import { RadioBoxComponent } from './components/radiobox/radiobox-component';
import { WordlistComponent } from './components/wordlist/wordlist-component';
import { AutocompleteComponent } from './components/autocomplete/autocomplete-component';
import { ComboboxComponent } from './components/combobox/combobox-component';
// import { CheckBoxComponent } from './components/checkbox/checkbox-component';
// import { FreeTextData } from './models/DataField/FreeTextData';
// import { BooleanDecisionComponent } from './components/booleanDecision/booleanDecision-component';
// import { FreeTextComponent } from './components/freetext/freetext-component';
// import { TextAreaComponent } from './components/textarea/textarea-component';
// import { RadioBoxComponent } from './components/radiobox/radiobox-component';
// import { WordlistComponent } from './components/wordlist/wordlist-component';
// import { AutocompleteComponent } from './components/autocomplete/autocomplete-component';
// import { ComboboxComponent } from './components/combobox/combobox-component';
//import { MaterialModule } from './shared/material/material.module';
import { AuthService } from './services/auth/auth.service';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule, Routes } from '@angular/router';
@ -51,7 +53,6 @@ import { DatarepoTableFilterPipe } from './pipes/datarepo-table-filter.pipe';
import { GooggleSignInComponent } from './login/googgle-sign-in/googgle-sign-in.component';
import { MainSignInComponent } from './login/main-sign-in/main-sign-in.component';
import { ProjectEditorComponent } from './managers/project-editor/project-editor.component';
import { DatasetsViewerComponent } from './datasets-viewer/datasets-viewer.component';
import { AppComponent } from './app.component';
import { FormsModule } from '@angular/forms';
@ -59,25 +60,21 @@ import { ProfileEditorComponent } from './bootstrap/profile-editor/profile-edito
import { PropertiesEditorComponent } from './bootstrap/properties-editor/properties-editor.component';
import { NewDatasetComponent } from './bootstrap/new-dataset/new-dataset.component';
import { ConfirmationComponent } from './bootstrap/confirmation/confirmation.component';
import { DmpEditorComponent } from './managers/dmp-editor/dmp-editor.component';
import { MainWindowComponent } from './main-window/main-window.component';
import { AppRouting } from './routes';
import { DmpProfileEditorComponent } from './managers/dmp-profile-editor/dmp-profile-editor.component';
import { OrganisationEditorComponent } from './managers/organisation-editor/organisation-editor.component';
import { RegistryEditorComponent } from './managers/registry-editor/registry-editor.component';
import { ServiceEditorComponent } from './managers/service-editor/service-editor.component';
import { ResearcherEditorComponent } from './managers/researcher-editor/researcher-editor.component';
import { DatareposEditorComponent } from './managers/datarepos-editor/datarepos-editor.component';
import { DatasetprofileEditorComponent } from './managers/datasetprofile-editor/datasetprofile-editor.component';
import { DatasetProfileGUIEditorComponent } from './dataset-profile-gui-editor/dataset-profile-gui-editor.component';
import { FieldFormComponent } from './dataset-profile-form/field-form/field-form.component';
import { FormComponent } from './dataset-profile-form/form/form.component';
import { GroupFieldFormComponent } from './dataset-profile-form/groupfield-form/groupfield-form.component';
import { RuleFormComponent } from './dataset-profile-form/rule-component/rule.component';
import { SectionFormComponent } from './dataset-profile-form/section-form/section-form.component';
import { PageFormComponent } from './dataset-profile-form/page-form/page-component';
import { CompositeFieldFormComponent } from './dataset-profile-form/compositefield-form/compositefield-form.component';
import { DatasetProfileModule } from './dataset-profile-form/dataset-profile.module';
// import { FieldFormComponent } from './dataset-profile-form/field-form/field-form.component';
// import { FormComponent } from './dataset-profile-form/form/form.component';
// import { GroupFieldFormComponent } from './dataset-profile-form/groupfield-form/groupfield-form.component';
// import { RuleFormComponent } from './dataset-profile-form/rule-component/rule.component';
// import { SectionFormComponent } from './dataset-profile-form/section-form/section-form.component';
// import { PageFormComponent } from './dataset-profile-form/page-form/page-component';
// import { CompositeFieldFormComponent } from './dataset-profile-form/compositefield-form/compositefield-form.component';
@ -97,38 +94,31 @@ import { CompositeFieldFormComponent } from './dataset-profile-form/compositefie
AppComponent,
GooggleSignInComponent,
FieldFormComponent,
FormComponent,
GroupFieldFormComponent,
RuleFormComponent,
SectionFormComponent,
PageFormComponent,
CompositeFieldFormComponent,
ComboboxComponent,
AutocompleteComponent,
WordlistComponent,
RadioBoxComponent,
// FieldFormComponent,
// FormComponent,
// GroupFieldFormComponent,
// RuleFormComponent,
// SectionFormComponent,
// PageFormComponent,
// CompositeFieldFormComponent,
// ComboboxComponent,
// AutocompleteComponent,
// WordlistComponent,
// RadioBoxComponent,
DatasetsViewerComponent,
ProfileEditorComponent,
PropertiesEditorComponent,
NewDatasetComponent,
ConfirmationComponent,
DmpEditorComponent,
MainWindowComponent,
ProjectEditorComponent,
DmpProfileEditorComponent,
OrganisationEditorComponent,
RegistryEditorComponent,
ServiceEditorComponent,
MainSignInComponent,
ResearcherEditorComponent,
DatareposEditorComponent,
DatasetprofileEditorComponent,
DatasetProfileGUIEditorComponent,
TextAreaComponent,
CheckBoxComponent,
BooleanDecisionComponent,
FreeTextComponent
// TextAreaComponent,
// CheckBoxComponent,
// BooleanDecisionComponent,
// FreeTextComponent
],
imports: [
BrowserModule,
@ -142,7 +132,8 @@ import { CompositeFieldFormComponent } from './dataset-profile-form/compositefie
NgbModule.forRoot(),
AppRouting
],
providers: [{
providers: [AuthService,
{
provide: HTTP_INTERCEPTORS,
useClass: GlobalInterceptor,
multi: true,

View File

@ -0,0 +1,77 @@
import { NgModule } from "@angular/core";
import { CommonModule } from '@angular/common';
import { FormsModule,ReactiveFormsModule } from '@angular/forms';
import { DatasetProfileRoutes } from "./dataset-profile.router";
import { RouterModule } from "@angular/router";
import { FormComponent } from './form/form.component';
import { GroupFieldFormComponent } from './groupfield-form/groupfield-form.component';
import { RuleFormComponent } from './rule-component/rule.component';
import { SectionFormComponent } from './section-form/section-form.component';
import { PageFormComponent } from './page-form/page-component';
import { CompositeFieldFormComponent } from './compositefield-form/compositefield-form.component';
import { FieldFormComponent } from './field-form/field-form.component';
import { HttpClientModule, HttpClient } from "@angular/common/http";
import { CheckBoxComponent } from '../components/checkbox/checkbox-component';
import { FreeTextData } from '../models/DataField/FreeTextData';
import { BooleanDecisionComponent } from '../components/booleanDecision/booleanDecision-component';
import { FreeTextComponent } from '../components/freetext/freetext-component';
import { TextAreaComponent } from '../components/textarea/textarea-component';
import { RadioBoxComponent } from '../components/radiobox/radiobox-component';
import { WordlistComponent } from '../components/wordlist/wordlist-component';
import { AutocompleteComponent } from '../components/autocomplete/autocomplete-component';
import { ComboboxComponent } from '../components/combobox/combobox-component';
@NgModule({
imports: [
CommonModule,
FormsModule,
HttpClientModule,
ReactiveFormsModule,
RouterModule,
RouterModule.forChild(DatasetProfileRoutes)
],
declarations: [
FormComponent,
GroupFieldFormComponent,
RuleFormComponent,
SectionFormComponent,
PageFormComponent,
CompositeFieldFormComponent,
FieldFormComponent,
TextAreaComponent,
CheckBoxComponent,
BooleanDecisionComponent,
FreeTextComponent,
ComboboxComponent,
AutocompleteComponent,
WordlistComponent,
RadioBoxComponent
],
exports: [
FormComponent,
GroupFieldFormComponent,
RuleFormComponent,
SectionFormComponent,
PageFormComponent,
CompositeFieldFormComponent,
FieldFormComponent,
TextAreaComponent,
CheckBoxComponent,
BooleanDecisionComponent,
FreeTextComponent,
ComboboxComponent,
AutocompleteComponent,
WordlistComponent,
RadioBoxComponent
],
providers:[
]
})
export class DatasetProfileModule { }

View File

@ -0,0 +1,15 @@
import { RouterModule, Routes } from '@angular/router';
import { FormComponent } from 'app/dataset-profile-form/form/form.component';
export const DatasetProfileRoutes: Routes = [
//{ path: "new/:dmpId", component: DatasetWizardComponent, canActivate: [AuthGuard] }
{
path: ':id',
component: FormComponent
},
{
path: '',
component: FormComponent
}
];

View File

@ -29,11 +29,11 @@ export class FormComponent {
ngOnInit() {
this.dataModel = new JsonSerializer<DatasetProfileModel>().fromJSONObject(new DatasetProfileModel(), DatasetProfileModel);
this.dataModel = JsonSerializer.fromJSONObject(new DatasetProfileModel(), DatasetProfileModel);
this.form = this.dataModel.buildForm();
if (this.profileID) {
this.datasetProfileService.getDatasetProfileById(this.profileID).subscribe((data) => {
this.dataModel = new JsonSerializer<DatasetProfileModel>().fromJSONObject(data, DatasetProfileModel);
this.dataModel = JsonSerializer.fromJSONObject(data, DatasetProfileModel);
this.form = this.dataModel.buildForm();
});
}

View File

@ -0,0 +1,17 @@
import { AuthService } from '../services/auth/auth.service';
import { Injectable } from '@angular/core';
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private auth: AuthService, private router: Router) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
let url: string = state.url;
if (!this.auth.current()) {
this.router.navigate(['/unauthorized'], { queryParams: { returnUrl: url } });
return false;
}
return true;
}
}

View File

@ -2,10 +2,13 @@ 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 { Router } from '@angular/router';
import '../../../assets/custom.js';
declare function simple_notifier(type: string, title: string, message:string): any;
import { AuthService } from 'app/services/auth/auth.service';
import { Credential } from 'app/models/login/Credential';
import { ActivatedRoute, Params } from '@angular/router';
import { NgZone } from '@angular/core';
@Component({
selector: 'app-main-sign-in',
@ -15,21 +18,22 @@ declare function simple_notifier(type: string, title: string, message:string): a
export class MainSignInComponent implements OnInit {
nativeLoginForm : any;
nativeLoginForm: any;
creds : any = {"username":"","password":""};
creds: any = { "username": "", "password": "" };
constructor( private fb: FormBuilder, private nativeLogin : NativeLoginService, private tokenService : TokenService, private router : Router) {
constructor(private fb: FormBuilder, private nativeLogin: NativeLoginService, private tokenService: TokenService,
private router: Router, private authservice: AuthService, public route: ActivatedRoute, private zone: NgZone) {
}
createProjectEditorForm(){
createProjectEditorForm() {
this.nativeLoginForm = this.fb.group({
username: ['', Validators.required ],
password: ['', Validators.required ]
username: ['', Validators.required],
password: ['', Validators.required]
});
}
@ -40,22 +44,50 @@ export class MainSignInComponent implements OnInit {
}
login(){
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']);
},
err => {
simple_notifier("danger",null,"Failed to login");
}
);
// 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']);
// },
// err => {
// simple_notifier("danger",null,"Failed to login");
// }
// );
let credentials = new Credential();
credentials.username = this.creds.username;
credentials.secret = this.creds.password;
this.authservice.nativeLogin(credentials).subscribe(
res => this.onLogInSuccess(res),
error => this.onLogInError(error)
);
}
public onLogInSuccess(logoutMessage: any) {
// this.snackBar.openFromComponent(SnackBarNotificationComponent, {
// data: { message: 'GENERAL.SNACK-BAR.SUCCESSFUL-LOGIN', language: this.language },
// duration: 3000,
// extraClasses: ['snackbar-success']
// });
this.route.queryParams.subscribe((params: Params) => {
let redirectUrl = params['returnUrl'] ? params['returnUrl'] : '/';
this.zone.run(() => this.router.navigate([redirectUrl]));
})
}
public onLogInError(errorMessage: string) {
// this.snackBar.openFromComponent(SnackBarNotificationComponent, {
// data: { message: 'GENERAL.SNACK-BAR.UNSUCCESSFUL-LOGIN', language: this.language },
// duration: 3000,
// extraClasses: ['snackbar-warning']
// })
}
}

View File

@ -14,57 +14,6 @@
<li [ngClass]="{true:'active'}[currentlySelected=='datasets']" (click)="setActive('datasets')" [routerLink]="['/datasets']" ><a style="cursor:pointer">Datasets</a></li>
<li [ngClass]="{true:'active'}[currentlySelected=='datasetprofiles']" (click)="setActive('datasetprofiles')" [routerLink]="['/datasetprofiles']" ><a style="cursor:pointer">Dataset Profiles</a></li>
</ul>
<li data-toggle="collapse" data-target="#manage-dmps" class="collapsed">
<a style="cursor:pointer"><i class="fa fa-newspaper-o"></i>Manage DMPs <span class="arrow"></span></a>
</li>
<ul class="sub-menu collapse" id="manage-dmps">
<li [ngClass]="{true:'active'}[currentlySelected=='dmps']" (click)="setActive('dmps')" [routerLink]="['/dmps']">DMP</li>
<li [ngClass]="{true:'active'}[currentlySelected=='dmpprofiles']" (click)="setActive('dmpprofiles')" [routerLink]="['/dmpprofiles']">DMP profiles</li>
</ul>
<li data-toggle="collapse" data-target="#manage-repositories" class="collapsed">
<a style="cursor:pointer"><i class="fa fa-database"></i> Manage Data Repositories <span class="arrow"></span></a>
</li>
<ul class="sub-menu collapse" id="manage-repositories">
<li [ngClass]="{true:'active'}[currentlySelected=='datarepos']" (click)="setActive('datarepos')" [routerLink]="['/datarepos']">Data Repositories</li>
<li>Non-assigned repositories</li>
</ul>
<li data-toggle="collapse" data-target="#manage-projects" class="collapsed">
<a style="cursor:pointer"><i class="fa fa-newspaper-o"></i>Manage Projects <span class="arrow"></span></a>
</li>
<ul class="sub-menu collapse" id="manage-projects">
<li [ngClass]="{true:'active'}[currentlySelected=='projects']" (click)="setActive('projects')" [routerLink]="['/projects']">All Projects</li>
</ul>
<li data-toggle="collapse" data-target="#manage-organisations" class="collapsed">
<a style="cursor:pointer"><i class="fa fa-newspaper-o"></i>Manage Organisations <span class="arrow"></span></a>
</li>
<ul class="sub-menu collapse" id="manage-organisations">
<li [ngClass]="{true:'active'}[currentlySelected=='organisations']" (click)="setActive('organisations')" [routerLink]="['/organisations']">All Organisations</li>
</ul>
<li data-toggle="collapse" data-target="#manage-registries" class="collapsed">
<a style="cursor:pointer"><i class="fa fa-newspaper-o"></i>Manage Registries <span class="arrow"></span></a>
</li>
<ul class="sub-menu collapse" id="manage-registries">
<li [ngClass]="{true:'active'}[currentlySelected=='registries']" (click)="setActive('registries')" [routerLink]="['/registries']">All Registries</li>
</ul>
<li data-toggle="collapse" data-target="#manage-services" class="collapsed">
<a style="cursor:pointer"><i class="fa fa-newspaper-o"></i>Manage Services <span class="arrow"></span></a>
</li>
<ul class="sub-menu collapse" id="manage-services">
<li [ngClass]="{true:'active'}[currentlySelected=='services']" (click)="setActive('services')" [routerLink]="['/services']">All services</li>
</ul>
<li data-toggle="collapse" data-target="#manage-researchers" class="collapsed">
<a style="cursor:pointer"><i class="fa fa-newspaper-o"></i>Manage Researchers <span class="arrow"></span></a>
</li>
<ul class="sub-menu collapse" id="manage-researchers">
<li [ngClass]="{true:'active'}[currentlySelected=='researchers']" (click)="setActive('researchers')" [routerLink]="['/researchers']">All researchers</li>
</ul>
<li data-toggle="collapse" data-target="#manage-users" class="collapsed">
<a style="cursor:pointer"><i class="fa fa-newspaper-o"></i> Users <span class="arrow"></span></a>

View File

@ -1,33 +0,0 @@
.invisible {
display:none;
}
.visible {
display:block;
}
tr.hover:hover > * {
background-color: #eeeeee;
}
.editor-container{
padding-top: 10px;
padding-right: 10px;
padding-bottom: 10px;
padding-left: 10px;
}
.button-150px {
max-width: 150px;
}
.ng-template{
text-align: right;
}
.grayout-empty-table {
opacity: 0.6; /* Real browsers */
filter: alpha(opacity = 60); /* MSIE */
text-align: center;
vertical-align: middle;
}

View File

@ -1,122 +0,0 @@
<div class="editor-container container">
<div [ngClass]="{true:'visible', false:'invisible'}[tableVisible]">
<table class="table table-striped" [mfData]="tableData | datarepoTableFilter : filterQuery" #mf="mfDataTable" [mfRowsOnPage]="rowsOnPage" [(mfSortBy)]="sortBy" [(mfSortOrder)]="sortOrder">
<thead>
<tr>
<th colspan="1">
<input class="form-control" [(ngModel)]="filterQuery" placeholder='Filter'/>
</th>
<th>
<button class="btn btn-default" (click)="refreshTable($event)">
<span class="glyphicon glyphicon-refresh"></span>
</button>
</th>
</tr>
<tr>
<th [ngClass]="{true:'visible', false:'invisible'}[showIDs]"><mfDefaultSorter by="id">ID</mfDefaultSorter></th>
<th><mfDefaultSorter by="label">Label</mfDefaultSorter></th>
<th><mfDefaultSorter by="abbreviation">Abbreviation</mfDefaultSorter></th>
<th><mfDefaultSorter by="reference">Reference</mfDefaultSorter></th>
<th><mfDefaultSorter by="uri">Uri</mfDefaultSorter></th>
<th><mfDefaultSorter by="definition">Definition</mfDefaultSorter></th>
</tr>
</thead>
<tbody>
<tr class="grayout-empty-table" *ngIf="!mf.data[0]" [contextMenu]="basicMenu" [contextMenuSubject]="datarepo"> <td colspan="5">No elements</td></tr>
<tr *ngFor="let datarepo of mf.data" class="hover" [contextMenu]="basicMenu" [contextMenuSubject]="datarepo">
<td [ngClass]="{true:'visible', false:'invisible'}[showIDs]">{{datarepo.id}}</td>
<td>{{datarepo?.label}}</td>
<td>{{datarepo?.abbreviation}}</td>
<td>{{datarepo?.reference}}</td>
<td>{{datarepo?.uri}}</td>
<td>{{datarepo?.definition}}</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5">
<mfBootstrapPaginator [rowsOnPageSet]="[10,20,40]"></mfBootstrapPaginator>
</td>
</tr>
</tfoot>
</table>
</div>
<!-- this is the dmp editor -->
<div [ngClass]="{true:'visible', false:'invisible'}[editorVisible]">
<div> <!-- form container -->
<div style="display:block;">
<button (click)="switchToTable()" class="btn btn-lg btn-success pull-right" style="max-width:120px;">
<span class="glyphicon glyphicon-arrow-left"></span> Go back
</button>
</div>
<form [formGroup]="datarepoEditorForm" novalidate style="display:block;">
<div class="form-group" [ngClass]="{null:'invisible'}[editingDatarepo?.id]">
<label class="center-block">ID: {{editingDatarepo?.id}}
<input class="form-control invisible" formControlName="id" [ngModel]="editingDatarepo?.id">
</label>
</div>
<div class="form-group">
<label class="center-block">Label:
<input class="form-control" formControlName="label" [ngModel]="editingDatarepo?.label" (ngModelChange)="editingDatarepo.label=$event">
</label>
</div>
<div class="form-group">
<label class="center-block">Abbreviation:
<input class="form-control" formControlName="abbreviation" [ngModel]="editingDatarepo?.abbreviation" (ngModelChange)="editingDatarepo.abbreviation=$event">
</label>
</div>
<div class="form-group">
<label class="center-block">Reference:
<input class="form-control" formControlName="reference" [ngModel]="editingDatarepo?.reference" (ngModelChange)="editingDatarepo.reference$event">
</label>
</div>
<div class="form-group">
<label class="center-block">Uri:
<input class="form-control" formControlName="uri" [ngModel]="editingDatarepo?.uri" (ngModelChange)="editingDatarepo.uri$event">
</label>
</div>
<div class="form-group">
<label class="center-block">Definition:
<input class="form-control" formControlName="definition" [ngModel]="editingDatarepo?.definition" (ngModelChange)="editingDatarepo.definition$event">
</label>
</div>
<div class="form-group" style="width:540px;">
<button style="float:right;" type="submit" (click)="save($event, $data, $form)"class="btn btn-success">Save</button>
</div>
</form>
<!--
<p>Form value: {{ datarepoEditorForm.value | json }}</p>
-->
</div>
</div>
</div>
<context-menu>
<ng-template contextMenuItem [subMenu]="manage">
<span></span>Manage data repositories
</ng-template>
<context-menu #manage>
<ng-template contextMenuItem (execute)="newDatarepo($event?.item)">
<span class="glyphicon glyphicon-plus"></span>Create data repository
</ng-template>
<ng-template contextMenuItem (execute)="editDatarepo($event?.item?.id)">
<span class="glyphicon glyphicon-pencil"></span>Edit this data repository
</ng-template>
<ng-template contextMenuItem (execute)="delete($event?.item?.id)">
<span class="glyphicon glyphicon-trash red"></span> Delete this
</ng-template>
</context-menu>
<ng-template contextMenuItem>
<span></span>Show full tree connections
</ng-template>
</context-menu>

View File

@ -1,25 +0,0 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { DatareposEditorComponent } from './datarepos-editor.component';
describe('DatareposEditorComponent', () => {
let component: DatareposEditorComponent;
let fixture: ComponentFixture<DatareposEditorComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ DatareposEditorComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(DatareposEditorComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should be created', () => {
expect(component).toBeTruthy();
});
});

View File

@ -1,137 +0,0 @@
import { Component, OnInit, ViewChild } from '@angular/core';
import { DatarepoService } from '../../services/datarepo-service';
import { ContextMenuComponent } from 'ngx-contextmenu';
import { ReactiveFormsModule } from '@angular/forms';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import '../../../assets/custom.js';
declare function simple_notifier(type: string, title: string, message:string): any;
@Component({
selector: 'app-datarepos-editor',
templateUrl: './datarepos-editor.component.html',
styleUrls: ['./datarepos-editor.component.css']
})
export class DatareposEditorComponent implements OnInit {
constructor(private datarepoService : DatarepoService, private fb: FormBuilder) {
}
//whole dmp data model
tableData : any[] = new Array();
//datarepos editor data model
editingDatarepo: any = {};
datarepoEditorForm : any;
//required by the table
public filterQuery = "";
public rowsOnPage = 10;
//public sortBy = "email";
public sortOrder = "asc";
//visibility rules for containers
tableVisible: boolean = true;
editorVisible: boolean = false;
// for tableIds
showIDs : boolean = false;
ngOnInit() {
this.getAllDatarepos(false);
this.createDatareposEditorForm();
}
createDatareposEditorForm(){
this.datarepoEditorForm = this.fb.group({
id: null,
label: ['', Validators.required ],
abbreviation: '',
reference: '',
uri: '',
definition: ''
});
}
switchToTable(){
this.tableVisible = true;
this.editorVisible = false;
}
switchToEditor(datarepoID){
this.tableVisible = false;
this.editorVisible = true;
if(datarepoID == null){
this.editingDatarepo = {id: null, label: "", abbreviation: "", reference: "", uri: "", definition: "" };
}
else{
this.editingDatarepo = this.tableData.filter((datarepo) => datarepo.id === datarepoID)[0];
}
}
getAllDatarepos(showNotification : boolean){
this.datarepoService.getAllDatarepos().subscribe( (data) => {
this.tableData = data;
if(showNotification)
simple_notifier("info",null,"Refreshed the table");
});
}
editDatarepo(datarepo){
this.switchToEditor(datarepo);
}
newDatarepo(){
this.switchToEditor(null);
}
save(mouseEvent){
this.datarepoService.create(this.datarepoEditorForm.value).subscribe(
response => {
simple_notifier("success",null,"Saved data repository");
this.getAllDatarepos(false);
this.switchToTable();
},
err => {
simple_notifier("danger",null,"Could not save data repository");
}
);
}
delete(datarepo){
this.datarepoService.delete(datarepo).subscribe(
(response) => {
simple_notifier("success",null,"Deleted data repository");
this.getAllDatarepos(false);
this.switchToTable();
},
(err) => {
simple_notifier("danger",null,"Could not delete data repository");
}
)
}
refreshTable($event){
this.getAllDatarepos(true);
}
@ViewChild(ContextMenuComponent) public basicMenu: ContextMenuComponent;
}

View File

@ -0,0 +1,64 @@
<div class="container-fluid">
<h3>{{titlePrefix}} {{'DATASET-LISTING.TITLE' | translate}}</h3>
<app-datasets-criteria-component></app-datasets-criteria-component>
<mat-card class="mat-card">
<mat-card-header>
<mat-progress-bar *ngIf="dataSource?.isLoadingResults" mode="query"></mat-progress-bar>
</mat-card-header>
<mat-table [dataSource]="dataSource" matSort>
<!-- Column Definition: Name -->
<ng-container cdkColumnDef="label">
<mat-header-cell *matHeaderCellDef>Label</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.label}}</mat-cell>
</ng-container>
<!-- Column Definition: Status -->
<ng-container cdkColumnDef="status">
<mat-header-cell *matHeaderCellDef>Status</mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.status}}
</mat-cell>
</ng-container>
<!-- Column Definition: Description -->
<ng-container cdkColumnDef="description">
<mat-header-cell *matHeaderCellDef>Description</mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.description}} </mat-cell>
</ng-container>
<!-- Column Definition: Created -->
<ng-container cdkColumnDef="created">
<mat-header-cell *matHeaderCellDef>Created}</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.created | date:'shortDate'}}</mat-cell>
</ng-container>
<!-- Column Definition: Submission Time -->
<ng-container cdkColumnDef="actions">
<mat-header-cell *matHeaderCellDef>{{'DATASET-LISTING.COLUMNS.ACTIONS' | translate}}</mat-header-cell>
<mat-cell *matCellDef="let row">
<mat-menu #actionsMenu="matMenu">
<button *ngIf="row.status==0" mat-menu-item (click)="rowClick(row.id)"><mat-icon>mode_edit</mat-icon>{{'DATASET-LISTING.ACTIONS.EDIT' | translate}}</button>
<button *ngIf="row.status==1" mat-menu-item (click)="rowClick(row.id)"><mat-icon>visibility</mat-icon>{{'DATASET-LISTING.ACTIONS.VIEW' | translate}}</button>
<button *ngIf="row.status==1" mat-menu-item (click)="makeItPublic(row.id)"><mat-icon>people_outline</mat-icon>{{'DATASET-LISTING.ACTIONS.MAKE-IT-PUBLIC' | translate}}</button>
</mat-menu>
<button mat-icon-button [matMenuTriggerFor]="actionsMenu">
<mat-icon>more_vert</mat-icon>
</button>
</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns"></mat-row>
<!-- (click)="rowClick(row.id)" -->
</mat-table>
<mat-paginator #paginator [length]="dataSource?.totalCount" [pageSizeOptions]="[10, 25, 100]">
</mat-paginator>
</mat-card>
<button *ngIf="dmpId" mat-fab class="mat-fab-bottom-right" color="primary" [routerLink]="['/datasets/new/'+dmpId] ">
<mat-icon class="mat-24">add</mat-icon>
</button>
</div>

View File

@ -0,0 +1,146 @@
// import { Component, ViewChild, OnInit, AfterViewInit } from "@angular/core";
// //import { MatPaginator, MatSort, MatSnackBar } from "@angular/material";
// import { Router, Params, ActivatedRoute } from "@angular/router";
// import { Observable } from "rxjs/Observable";
// @Component({
// selector: 'app-dataset-listing-component',
// templateUrl: 'dataset-listing.component.html',
// styleUrls: ['./dataset-listing.component.scss'],
// providers: [DatasetService, DataManagementPlanService]
// })
// export class DatasetListingComponent implements OnInit {
// @ViewChild(MatPaginator) _paginator: MatPaginator;
// @ViewChild(MatSort) sort: MatSort;
// @ViewChild(DatasetCriteriaComponent) criteria: DatasetCriteriaComponent;
// dataSource: DatasetDataSource | null;
// displayedColumns: String[] = ['label', 'dmp', 'profile', 'dataRepositories', 'registries', 'services', 'description', 'created', 'actions'];
// pageEvent: PageEvent;
// titlePrefix: String;
// dmpId: String;
// statuses = [
// { value: '0', viewValue: 'Active' },
// { value: '1', viewValue: 'Inactive' }
// ];
// constructor(
// private datasetService: DatasetService,
// private router: Router,
// private languageService: TranslateService,
// public snackBar: MatSnackBar,
// public route: ActivatedRoute,
// public dataManagementPlanService: DataManagementPlanService
// ) {
// }
// ngOnInit() {
// this.route.params.subscribe((params: Params) => {
// this.dmpId = params['dmpId'];
// if(this.dmpId != null) this.setDmpTitle(this.dmpId);
// this.criteria.setCriteria(this.getDefaultCriteria(this.dmpId));
// this.refresh();
// this.criteria.setRefreshCallback(() => this.refresh());
// });
// }
// setDmpTitle(dmpId: String) {
// this.dataManagementPlanService.getSingle(dmpId).map(data => data as DataManagementPlanModel)
// .subscribe(data => {
// this.titlePrefix = data.label;
// });
// }
// refresh() {
// this.dataSource = new DatasetDataSource(this.datasetService, this._paginator, this.sort, this.languageService, this.snackBar, this.criteria);
// }
// rowClick(rowId: String) {
// this.router.navigate(['/datasets/edit/' + rowId]);
// }
// getDefaultCriteria(dmpId: String): DatasetCriteria {
// const defaultCriteria = new DatasetCriteria();
// if (dmpId != null) {
// defaultCriteria.dmpIds.push(dmpId);
// }
// return defaultCriteria;
// }
// makeItPublic(id:String){debugger;
// this.datasetService.makeDatasetPublic(id).subscribe();
// }
// }
// export class DatasetDataSource extends DataSource<DatasetListingModel> {
// totalCount = 0;
// isLoadingResults = false;
// constructor(
// private _service: DatasetService,
// private _paginator: MatPaginator,
// private _sort: MatSort,
// private _languageService: TranslateService,
// private _snackBar: MatSnackBar,
// private _criteria: DatasetCriteriaComponent
// ) {
// super();
// }
// connect(): Observable<DatasetListingModel[]> {
// const displayDataChanges = [
// this._paginator.page
// //this._sort.matSortChange
// ];
// return Observable.merge(...displayDataChanges)
// .startWith(null)
// .switchMap(() => {
// setTimeout(() => {
// this.isLoadingResults = true;
// });
// const startIndex = this._paginator.pageIndex * this._paginator.pageSize;
// const request = new DataTableRequest<DatasetCriteria>(startIndex, this._paginator.pageSize);
// request.criteria = this._criteria.criteria;
// return this._service.getPaged(request);
// })
// /*.catch((error: any) => {
// this._snackBar.openFromComponent(SnackBarNotificationComponent, {
// data: { message: 'GENERAL.SNACK-BAR.FORMS-BAD-REQUEST', language: this._languageService },
// duration: 3000,
// extraClasses: ['snackbar-warning']
// });
// //this._criteria.criteria.onCallbackError(error);
// return Observable.of(null);
// })*/
// .map(result => {
// setTimeout(() => {
// this.isLoadingResults = false;
// });
// return result;
// })
// .map(result => {
// if (!result) { return []; }
// if (this._paginator.pageIndex === 0) { this.totalCount = result.totalCount; }
// return result.data;
// });
// }
// disconnect() {
// // No-op
// }
// }

View File

@ -1,33 +0,0 @@
.invisible {
display:none;
}
.visible {
display:block;
}
tr.hover:hover > * {
background-color: #eeeeee;
}
.editor-container{
padding-top: 10px;
padding-right: 10px;
padding-bottom: 10px;
padding-left: 10px;
}
.button-150px {
max-width: 150px;
}
.ng-template{
text-align: right;
}
.grayout-empty-table {
opacity: 0.6; /* Real browsers */
filter: alpha(opacity = 60); /* MSIE */
text-align: center;
vertical-align: middle;
}

View File

@ -1,134 +0,0 @@
<div class="editor-container container">
<div [ngClass]="{true:'visible', false:'invisible'}[dmpTableVisible]">
<table class="table table-striped" [mfData]="tableData | dmpTableFilter : filterQuery" #mf="mfDataTable" [mfRowsOnPage]="rowsOnPage" [(mfSortBy)]="sortBy" [(mfSortOrder)]="sortOrder">
<thead>
<tr>
<th colspan="1">
<input class="form-control" [(ngModel)]="filterQuery" placeholder='Filter'/>
</th>
<th>
<button class="btn btn-default" (click)="refreshTable($event)">
<span class="glyphicon glyphicon-refresh"></span>
</button>
</th>
</tr>
<tr>
<th [ngClass]="{true:'visible', false:'invisible'}[showIDs]"><mfDefaultSorter by="id">ID</mfDefaultSorter></th>
<th [ngClass]="{true:'visible', false:'invisible'}[showIDs]"><mfDefaultSorter by="previous">Previous</mfDefaultSorter></th>
<th><mfDefaultSorter by="label">Label</mfDefaultSorter></th>
<th><mfDefaultSorter by="version">Version</mfDefaultSorter></th>
<th><mfDefaultSorter by="project.label">Project</mfDefaultSorter></th>
<th>ProfileData</th>
<th>Profile</th>
</tr>
</thead>
<tbody>
<tr class="grayout-empty-table" *ngIf="!mf.data[0]" [contextMenu]="basicMenu" [contextMenuSubject]="dmp"> <td colspan="5">No elements</td></tr>
<tr *ngFor="let dmp of mf.data" class="hover" [contextMenu]="basicMenu" [contextMenuSubject]="dmp">
<td [ngClass]="{true:'visible', false:'invisible'}[showIDs]">{{dmp.id}}</td>
<td [ngClass]="{true:'visible', false:'invisible'}[showIDs]">{{dmp.previous}}</td>
<td>{{dmp?.label}}</td>
<td>{{dmp?.version}}</td>
<td>{{dmp?.project?.label}}</td>
<td>{{dmp?.profileData}}</td>
<td>{{dmp?.profile?.label}}</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5">
<mfBootstrapPaginator [rowsOnPageSet]="[10,20,40]"></mfBootstrapPaginator>
</td>
</tr>
</tfoot>
</table>
</div>
<!-- this is the dmp editor -->
<div [ngClass]="{true:'visible', false:'invisible'}[dmpEditorVisible]">
<div> <!-- form container -->
<div style="display:block;">
<button (click)="switchToTable()" class="btn btn-lg btn-success pull-right" style="max-width:120px;">
<span class="glyphicon glyphicon-arrow-left"></span> Go back
</button>
</div>
<form [formGroup]="dmpEditorForm" novalidate style="display:block;">
<div class="form-group" [ngClass]="{null:'invisible'}[editingDmp?.id]">
<label class="center-block">ID: {{editingDmp?.id}}
<input class="form-control invisible" formControlName="id" [ngModel]="editingDmp?.id">
</label>
</div>
<div class="form-group">
<label class="center-block">Previous:
<select class="form-control" name="previous" formControlName="previous" [ngModel]="editingDmp?.previous" (ngModelChange)="setFormPreviousValue($event)">
<option *ngFor="let idLabel of dmpsLabelsIDs" value="{{idLabel.id}}" >{{idLabel.label}}</option>
</select>
</label>
</div>
<div class="form-group">
<label class="center-block">Label:
<input class="form-control" formControlName="label" [ngModel]="editingDmp?.label" (ngModelChange)="editingDmp.label=$event">
</label>
</div>
<div class="form-group">
<label class="center-block">Version:
<input class="form-control" type="number" min="1" max="10000" formControlName="version" [ngModel]="editingDmp?.version" (ngModelChange)="editingDmp.version=$event">
</label>
</div>
<div class="form-group">
<label class="center-block">Project:
<select class="form-control" name="project" formControlName="project" [ngModel]="editingDmp?.project?.id" (ngModelChange)="setFormProjectValue($event)">
<option *ngFor="let idLabel of projectLabelsIDs" [ngValue]="idLabel.id">{{idLabel.label}}</option>
</select>
</label>
</div>
<div class="form-group">
<label class="center-block">ProfileData:
<input class="form-control" formControlName="profileData" [ngModel]="editingDmp?.profileData" (ngModelChange)="editingDmp.profileData=$event">
</label>
</div>
<div class="form-group">
<label class="center-block">Profile:
<select class="form-control" name="profile" formControlName="profile" [ngModel]="editingDmp?.profile?.id" (ngModelChange)="setFormProfileValue($event)">
<option *ngFor="let idLabel of profileLabelsIDs" [ngValue]="idLabel.id">{{idLabel.label}}</option>
</select>
</label>
</div>
<div class="form-group" style="width:540px;">
<button style="float:right;" type="submit" (click)="save($event, $data, $form)"class="btn btn-success">Save</button>
</div>
</form>
<!--
<p>Form value: {{ dmpEditorForm.value | json }}</p>
-->
</div>
</div>
</div>
<context-menu>
<ng-template contextMenuItem [subMenu]="managedmp">
<span></span>Manage DMPs
</ng-template>
<context-menu #managedmp>
<ng-template contextMenuItem (execute)="newDmp($event?.item)">
<span class="glyphicon glyphicon-plus"></span>Create DMP
</ng-template>
<ng-template contextMenuItem (execute)="editDmp($event?.item?.id)">
<span class="glyphicon glyphicon-pencil"></span>Edit this DMP
</ng-template>
<ng-template contextMenuItem (execute)="delete($event?.item?.id)">
<span class="glyphicon glyphicon-trash red"></span> Delete this
</ng-template>
</context-menu>
<ng-template contextMenuItem>
<span></span>Show full tree connections
</ng-template>
</context-menu>

View File

@ -1,25 +0,0 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { DmpEditorComponent } from './dmp-editor.component';
describe('DmpEditorComponent', () => {
let component: DmpEditorComponent;
let fixture: ComponentFixture<DmpEditorComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ DmpEditorComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(DmpEditorComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should be created', () => {
expect(component).toBeTruthy();
});
});

View File

@ -1,160 +0,0 @@
import { Component, OnInit, ViewChild } from '@angular/core';
import { DmpsServiceService } from '../../services/dmps-service.service';
import { ProjectService } from '../../services/project-service';
import { DmpProfileService } from '../../services/dmpprofile-service';
import { ContextMenuComponent } from 'ngx-contextmenu';
import { ReactiveFormsModule } from '@angular/forms';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import '../../../assets/custom.js';
declare function simple_notifier(type: string, title: string, message:string): any;
@Component({
selector: 'app-dmp-editor',
templateUrl: './dmp-editor.component.html',
styleUrls: ['./dmp-editor.component.css']
})
export class DmpEditorComponent implements OnInit {
constructor(private dmpsServiceService : DmpsServiceService, private projectService : ProjectService, private dmpProfileService: DmpProfileService, private fb: FormBuilder) {
}
//whole dmp data model
tableData : any[] = new Array();
//dmp editor data model
editingDmp: any = {};
dmpEditorForm : any;
//required by the table
public filterQuery = "";
public rowsOnPage = 10;
//public sortBy = "email";
public sortOrder = "asc";
//visibility rules for containers
dmpTableVisible: boolean = true;
dmpEditorVisible: boolean = false;
dmpsLabelsIDs: any = new Array();
projectLabelsIDs: any = new Array();
profileLabelsIDs: any = new Array();
// for tableIds
showIDs : boolean = false;
ngOnInit() {
this.getAllDmps(false);
this.createDmpEditorForm();
}
createDmpEditorForm(){
this.dmpEditorForm = this.fb.group({
id: null,
previous: null,
label: ['', Validators.required ],
version: '',
project: '',
profileData: '',
profile: ''
});
}
switchToTable(){
this.dmpTableVisible = true;
this.dmpEditorVisible = false;
}
switchToEditor(dmpID){
this.dmpTableVisible = false;
this.dmpEditorVisible = true;
if(dmpID == null){
this.editingDmp = {id: null, previous: "", label: "", version: "", project: "", profileData: "", profile: "" };
}
else{
this.editingDmp = this.tableData.filter((dmp) => dmp.id === dmpID)[0];
}
this.projectService.getProjectIdsLabels().subscribe((data) => this.projectLabelsIDs = data);
this.dmpProfileService.getDmpProfileIdsLabels().subscribe( (data) => this.profileLabelsIDs = data);
this.dmpsServiceService.getDmpIdsLabels().subscribe ( (data) => this.dmpsLabelsIDs = data);
}
getAllDmps(showNotification : boolean){
this.dmpsServiceService.getAllDmps().subscribe( (data) => {
this.tableData = data;
if(showNotification)
simple_notifier("info",null,"Refreshed the table");
});
}
editDmp(dmp){
this.switchToEditor(dmp);
}
newDmp(){
this.switchToEditor(null);
}
//for setting option selection of form (because it's not supported by angular native functions) (see https://github.com/angular/angular/issues/6573)
setFormPreviousValue($event){
if($event != null && $event.target != null)
this.editingDmp.previous = $event.target.value;
}
setFormProjectValue($event){
if($event != null && $event.target != null)
this.editingDmp.project = $event.target.value;
}
setFormProfileValue($event){
if($event != null && $event.target != null)
this.editingDmp.profile = $event.target.value;
}
save(mouseEvent){
this.dmpsServiceService.create(this.dmpEditorForm.value).subscribe(
response => {
simple_notifier("success",null,"Saved dmp");
this.getAllDmps(false);
this.switchToTable();
},
err => {
simple_notifier("danger",null,"Could not save dmp");
}
);
}
delete(dmp){
console.log(dmp);
this.dmpsServiceService.delete(dmp).subscribe(
(response) => {
simple_notifier("success",null,"Deleted dataset");
this.getAllDmps(false);
this.switchToTable();
},
(err) => {
simple_notifier("danger",null,"Could not delete dmp");
}
)
}
refreshTable($event){
this.getAllDmps(true);
}
@ViewChild(ContextMenuComponent) public basicMenu: ContextMenuComponent;
}

View File

@ -1,33 +0,0 @@
.invisible {
display:none;
}
.visible {
display:block;
}
tr.hover:hover > * {
background-color: #eeeeee;
}
.editor-container{
padding-top: 10px;
padding-right: 10px;
padding-bottom: 10px;
padding-left: 10px;
}
.button-150px {
max-width: 150px;
}
.ng-template{
text-align: right;
}
.grayout-empty-table {
opacity: 0.6; /* Real browsers */
filter: alpha(opacity = 60); /* MSIE */
text-align: center;
vertical-align: middle;
}

View File

@ -1,122 +0,0 @@
<div class="editor-container container">
<div [ngClass]="{true:'visible', false:'invisible'}[tableVisible]">
<table class="table table-striped" [mfData]="tableData | organisationTableFilter : filterQuery" #mf="mfDataTable" [mfRowsOnPage]="rowsOnPage" [(mfSortBy)]="sortBy" [(mfSortOrder)]="sortOrder">
<thead>
<tr>
<th colspan="1">
<input class="form-control" [(ngModel)]="filterQuery" placeholder='Filter'/>
</th>
<th>
<button class="btn btn-default" (click)="refreshTable($event)">
<span class="glyphicon glyphicon-refresh"></span>
</button>
</th>
</tr>
<tr>
<th [ngClass]="{true:'visible', false:'invisible'}[showIDs]"><mfDefaultSorter by="id">ID</mfDefaultSorter></th>
<th><mfDefaultSorter by="label">Label</mfDefaultSorter></th>
<th><mfDefaultSorter by="abbreviation">Abbreviation</mfDefaultSorter></th>
<th><mfDefaultSorter by="reference">Reference</mfDefaultSorter></th>
<th><mfDefaultSorter by="uri">Uri</mfDefaultSorter></th>
<th><mfDefaultSorter by="definition">Definition</mfDefaultSorter></th>
</tr>
</thead>
<tbody>
<tr class="grayout-empty-table" *ngIf="!mf.data[0]" [contextMenu]="basicMenu" [contextMenuSubject]="organisation"> <td colspan="5">No elements</td></tr>
<tr *ngFor="let organisation of mf.data" class="hover" [contextMenu]="basicMenu" [contextMenuSubject]="organisation">
<td [ngClass]="{true:'visible', false:'invisible'}[showIDs]">{{organisation.id}}</td>
<td>{{organisation?.label}}</td>
<td>{{organisation?.abbreviation}}</td>
<td>{{organisation?.reference}}</td>
<td>{{organisation?.uri}}</td>
<td>{{organisation?.definition}}</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5">
<mfBootstrapPaginator [rowsOnPageSet]="[10,20,40]"></mfBootstrapPaginator>
</td>
</tr>
</tfoot>
</table>
</div>
<!-- this is the dmp editor -->
<div [ngClass]="{true:'visible', false:'invisible'}[editorVisible]">
<div> <!-- form container -->
<div style="display:block;">
<button (click)="switchToTable()" class="btn btn-lg btn-success pull-right" style="max-width:120px;">
<span class="glyphicon glyphicon-arrow-left"></span> Go back
</button>
</div>
<form [formGroup]="organisationEditorForm" novalidate style="display:block;">
<div class="form-group" [ngClass]="{null:'invisible'}[editingOrganisation?.id]">
<label class="center-block">ID: {{editingOrganisation?.id}}
<input class="form-control invisible" formControlName="id" [ngModel]="editingOrganisation?.id">
</label>
</div>
<div class="form-group">
<label class="center-block">Label:
<input class="form-control" formControlName="label" [ngModel]="editingOrganisation?.label" (ngModelChange)="editingOrganisation.label=$event">
</label>
</div>
<div class="form-group">
<label class="center-block">Abbreviation:
<input class="form-control" formControlName="abbreviation" [ngModel]="editingOrganisation?.abbreviation" (ngModelChange)="editingOrganisation.abbreviation=$event">
</label>
</div>
<div class="form-group">
<label class="center-block">Reference:
<input class="form-control" formControlName="reference" [ngModel]="editingOrganisation?.reference" (ngModelChange)="editingOrganisation.reference$event">
</label>
</div>
<div class="form-group">
<label class="center-block">Uri:
<input class="form-control" formControlName="uri" [ngModel]="editingOrganisation?.uri" (ngModelChange)="editingOrganisation.uri$event">
</label>
</div>
<div class="form-group">
<label class="center-block">Definition:
<input class="form-control" formControlName="definition" [ngModel]="editingOrganisation?.definition" (ngModelChange)="editingOrganisation.definition$event">
</label>
</div>
<div class="form-group" style="width:540px;">
<button style="float:right;" type="submit" (click)="save($event, $data, $form)"class="btn btn-success">Save</button>
</div>
</form>
<!--
<p>Form value: {{ organisationEditorForm.value | json }}</p>
-->
</div>
</div>
</div>
<context-menu>
<ng-template contextMenuItem [subMenu]="manage">
<span></span>Manage organisations
</ng-template>
<context-menu #manage>
<ng-template contextMenuItem (execute)="newOrganisation($event?.item)">
<span class="glyphicon glyphicon-plus"></span>Create organisation
</ng-template>
<ng-template contextMenuItem (execute)="editOrganisation($event?.item?.id)">
<span class="glyphicon glyphicon-pencil"></span>Edit this organisation
</ng-template>
<ng-template contextMenuItem (execute)="delete($event?.item?.id)">
<span class="glyphicon glyphicon-trash red"></span> Delete this
</ng-template>
</context-menu>
<ng-template contextMenuItem>
<span></span>Show full tree connections
</ng-template>
</context-menu>

View File

@ -1,25 +0,0 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { OrganisationEditorComponent } from './organisation-editor.component';
describe('OrganisationEditorComponent', () => {
let component: OrganisationEditorComponent;
let fixture: ComponentFixture<OrganisationEditorComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ OrganisationEditorComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(OrganisationEditorComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should be created', () => {
expect(component).toBeTruthy();
});
});

View File

@ -1,137 +0,0 @@
import { Component, OnInit, ViewChild } from '@angular/core';
import { OrganisationService } from '../../services/organisation-service';
import { ContextMenuComponent } from 'ngx-contextmenu';
import { ReactiveFormsModule } from '@angular/forms';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import '../../../assets/custom.js';
declare function simple_notifier(type: string, title: string, message:string): any;
@Component({
selector: 'app-organisation-editor',
templateUrl: './organisation-editor.component.html',
styleUrls: ['./organisation-editor.component.css']
})
export class OrganisationEditorComponent implements OnInit {
constructor(private organisationService : OrganisationService, private fb: FormBuilder) {
}
//whole dmp data model
tableData : any[] = new Array();
//organisation editor data model
editingOrganisation: any = {};
organisationEditorForm : any;
//required by the table
public filterQuery = "";
public rowsOnPage = 10;
//public sortBy = "email";
public sortOrder = "asc";
//visibility rules for containers
tableVisible: boolean = true;
editorVisible: boolean = false;
// for tableIds
showIDs : boolean = false;
ngOnInit() {
this.getAllOrganisations(false);
this.createOrganisationEditorForm();
}
createOrganisationEditorForm(){
this.organisationEditorForm = this.fb.group({
id: null,
label: ['', Validators.required ],
abbreviation: '',
reference: '',
uri: '',
definition: ''
});
}
switchToTable(){
this.tableVisible = true;
this.editorVisible = false;
}
switchToEditor(organisationID){
this.tableVisible = false;
this.editorVisible = true;
if(organisationID == null){
this.editingOrganisation = {id: null, label: "", abbreviation: "", reference: "", uri: "", definition: "" };
}
else{
this.editingOrganisation = this.tableData.filter((organisation) => organisation.id === organisationID)[0];
}
}
getAllOrganisations(showNotification : boolean){
this.organisationService.getAllOrganisations().subscribe( (data) => {
this.tableData = data;
if(showNotification)
simple_notifier("info",null,"Refreshed the table");
});
}
editOrganisation(organisation){
this.switchToEditor(organisation);
}
newOrganisation(){
this.switchToEditor(null);
}
save(mouseEvent){
this.organisationService.create(this.organisationEditorForm.value).subscribe(
response => {
simple_notifier("success",null,"Saved organisation");
this.getAllOrganisations(false);
this.switchToTable();
},
err => {
simple_notifier("danger",null,"Could not save organisation");
}
);
}
delete(organisation){
this.organisationService.delete(organisation).subscribe(
(response) => {
simple_notifier("success",null,"Deleted organisation");
this.getAllOrganisations(false);
this.switchToTable();
},
(err) => {
simple_notifier("danger",null,"Could not delete organisation");
}
)
}
refreshTable($event){
this.getAllOrganisations(true);
}
@ViewChild(ContextMenuComponent) public basicMenu: ContextMenuComponent;
}

View File

@ -1,33 +0,0 @@
.invisible {
display:none;
}
.visible {
display:block;
}
tr.hover:hover > * {
background-color: #eeeeee;
}
.editor-container{
padding-top: 10px;
padding-right: 10px;
padding-bottom: 10px;
padding-left: 10px;
}
.button-150px {
max-width: 150px;
}
.ng-template{
text-align: right;
}
.grayout-empty-table {
opacity: 0.6; /* Real browsers */
filter: alpha(opacity = 60); /* MSIE */
text-align: center;
vertical-align: middle;
}

View File

@ -1,121 +0,0 @@
<div class="editor-container container">
<div [ngClass]="{true:'visible', false:'invisible'}[tableVisible]">
<table class="table table-striped" [mfData]="tableData | projectTableFilter : filterQuery" #mf="mfDataTable" [mfRowsOnPage]="rowsOnPage" [(mfSortBy)]="sortBy" [(mfSortOrder)]="sortOrder">
<thead>
<tr>
<th colspan="1">
<input class="form-control" [(ngModel)]="filterQuery" placeholder='Filter'/>
</th>
<th>
<button class="btn btn-default" (click)="refreshTable($event)">
<span class="glyphicon glyphicon-refresh"></span>
</button>
</th>
</tr>
<tr>
<th [ngClass]="{true:'visible', false:'invisible'}[showIDs]"><mfDefaultSorter by="id">ID</mfDefaultSorter></th>
<th><mfDefaultSorter by="label">Label</mfDefaultSorter></th>
<th><mfDefaultSorter by="abbreviation">Abbreviation</mfDefaultSorter></th>
<th><mfDefaultSorter by="reference">Reference</mfDefaultSorter></th>
<th><mfDefaultSorter by="uri">Uri</mfDefaultSorter></th>
<th><mfDefaultSorter by="definition">Definition</mfDefaultSorter></th>
</tr>
</thead>
<tbody>
<tr class="grayout-empty-table" *ngIf="!mf.data[0]" [contextMenu]="basicMenu" [contextMenuSubject]="project"> <td colspan="5">No elements</td></tr>
<tr *ngFor="let project of mf.data" class="hover" [contextMenu]="basicMenu" [contextMenuSubject]="project">
<td [ngClass]="{true:'visible', false:'invisible'}[showIDs]">{{project.id}}</td>
<td>{{project?.label}}</td>
<td>{{project?.abbreviation}}</td>
<td>{{project?.reference}}</td>
<td>{{project?.uri}}</td>
<td>{{project?.definition}}</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5">
<mfBootstrapPaginator [rowsOnPageSet]="[10,20,40]"></mfBootstrapPaginator>
</td>
</tr>
</tfoot>
</table>
</div>
<!-- this is the form editor -->
<div [ngClass]="{true:'visible', false:'invisible'}[editorVisible]">
<div> <!-- form container -->
<div style="display:block;">
<button (click)="switchToTable()" class="btn btn-lg btn-success pull-right" style="max-width:120px;">
<span class="glyphicon glyphicon-arrow-left"></span> Go back
</button>
</div>
<form [formGroup]="projectEditorForm" novalidate style="display:block;">
<div class="form-group" [ngClass]="{null:'invisible'}[editingProject?.id]">
<label class="center-block">ID: {{editingProject?.id}}
<input class="form-control invisible" formControlName="id" [ngModel]="editingProject?.id">
</label>
</div>
<div class="form-group">
<label class="center-block">Label:
<input class="form-control" formControlName="label" [ngModel]="editingProject?.label" (ngModelChange)="editingProject.label=$event">
</label>
</div>
<div class="form-group">
<label class="center-block">Abbreviation:
<input class="form-control" formControlName="abbreviation" [ngModel]="editingProject?.abbreviation" (ngModelChange)="editingProject.abbreviation=$event">
</label>
</div>
<div class="form-group">
<label class="center-block">Reference:
<input class="form-control" formControlName="reference" [ngModel]="editingProject?.reference" (ngModelChange)="editingProject.reference$event">
</label>
</div>
<div class="form-group">
<label class="center-block">Uri:
<input class="form-control" formControlName="uri" [ngModel]="editingProject?.uri" (ngModelChange)="editingProject.uri$event">
</label>
</div>
<div class="form-group">
<label class="center-block">Definition:
<input class="form-control" formControlName="definition" [ngModel]="editingProject?.definition" (ngModelChange)="editingProject.definition$event">
</label>
</div>
<div class="form-group" style="width:540px;">
<button style="float:right;" type="submit" (click)="save($event, $data, $form)"class="btn btn-success">Save</button>
</div>
</form>
<!--
<p>Form value: {{ projectEditorForm.value | json }}</p>
-->
</div>
</div>
</div>
<context-menu>
<ng-template contextMenuItem [subMenu]="manage">
<span></span>Manage Projects
</ng-template>
<context-menu #manage>
<ng-template contextMenuItem (execute)="newProject($event?.item)">
<span class="glyphicon glyphicon-plus"></span>Create Project
</ng-template>
<ng-template contextMenuItem (execute)="editProject($event?.item?.id)">
<span class="glyphicon glyphicon-pencil"></span>Edit this Project
</ng-template>
<ng-template contextMenuItem (execute)="delete($event?.item?.id)">
<span class="glyphicon glyphicon-trash red"></span> Delete this
</ng-template>
</context-menu>
<ng-template contextMenuItem>
<span></span>Show full tree connections
</ng-template>
</context-menu>

View File

@ -1,25 +0,0 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ProjectEditorComponent } from './project-editor.component';
describe('ProjectEditorComponent', () => {
let component: ProjectEditorComponent;
let fixture: ComponentFixture<ProjectEditorComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ProjectEditorComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ProjectEditorComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should be created', () => {
expect(component).toBeTruthy();
});
});

View File

@ -1,138 +0,0 @@
import { Component, OnInit, ViewChild } from '@angular/core';
import { DmpsServiceService } from '../../services/dmps-service.service';
import { ProjectService } from '../../services/project-service';
import { DmpProfileService } from '../../services/dmpprofile-service';
import { ContextMenuComponent } from 'ngx-contextmenu';
import { ReactiveFormsModule } from '@angular/forms';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import '../../../assets/custom.js';
declare function simple_notifier(type: string, title: string, message:string): any;
@Component({
selector: 'app-project-editor',
templateUrl: './project-editor.component.html',
styleUrls: ['./project-editor.component.css']
})
export class ProjectEditorComponent implements OnInit {
constructor(private projectService : ProjectService, private fb: FormBuilder) {
}
//whole dmp data model
tableData : any[] = new Array();
//project editor data model
editingProject: any = {};
projectEditorForm : any;
//required by the table
public filterQuery = "";
public rowsOnPage = 10;
//public sortBy = "email";
public sortOrder = "asc";
//visibility rules for containers
tableVisible: boolean = true;
editorVisible: boolean = false;
// for tableIds
showIDs : boolean = false;
ngOnInit() {
this.getAllProjects(false);
this.createProjectEditorForm();
}
createProjectEditorForm(){
this.projectEditorForm = this.fb.group({
id: null,
label: ['', Validators.required ],
abbreviation: '',
reference: '',
uri: '',
definition: ''
});
}
switchToTable(){
this.tableVisible = true;
this.editorVisible = false;
}
switchToEditor(projectID){
this.tableVisible = false;
this.editorVisible = true;
if(projectID == null){
this.editingProject = {id: null, label: "", abbreviation: "", reference: "", uri: "", definition: "" };
}
else{
this.editingProject = this.tableData.filter((project) => project.id === projectID)[0];
}
}
getAllProjects(showNotification : boolean){
this.projectService.getAllProjects().subscribe( (data) => {
this.tableData = data;
if(showNotification)
simple_notifier("info",null,"Refreshed the table");
});
}
editProject(project){
this.switchToEditor(project);
}
newProject(){
this.switchToEditor(null);
}
save(mouseEvent){
this.projectService.create(this.projectEditorForm.value).subscribe(
response => {
simple_notifier("success",null,"Saved project");
this.getAllProjects(false);
this.switchToTable();
},
err => {
simple_notifier("danger",null,"Could not save project");
}
);
}
delete(project){
console.log(project);
this.projectService.delete(project).subscribe(
(response) => {
simple_notifier("success",null,"Deleted project");
this.getAllProjects(false);
this.switchToTable();
},
(err) => {
simple_notifier("danger",null,"Could not delete project");
}
)
}
refreshTable($event){
this.getAllProjects(true);
}
@ViewChild(ContextMenuComponent) public basicMenu: ContextMenuComponent;
}

View File

@ -1,33 +0,0 @@
.invisible {
display:none;
}
.visible {
display:block;
}
tr.hover:hover > * {
background-color: #eeeeee;
}
.editor-container{
padding-top: 10px;
padding-right: 10px;
padding-bottom: 10px;
padding-left: 10px;
}
.button-150px {
max-width: 150px;
}
.ng-template{
text-align: right;
}
.grayout-empty-table {
opacity: 0.6; /* Real browsers */
filter: alpha(opacity = 60); /* MSIE */
text-align: center;
vertical-align: middle;
}

View File

@ -1,121 +0,0 @@
<div class="editor-container container">
<div [ngClass]="{true:'visible', false:'invisible'}[tableVisible]">
<table class="table table-striped" [mfData]="tableData | registryTableFilter : filterQuery" #mf="mfDataTable" [mfRowsOnPage]="rowsOnPage" [(mfSortBy)]="sortBy" [(mfSortOrder)]="sortOrder">
<thead>
<tr>
<th colspan="1">
<input class="form-control" [(ngModel)]="filterQuery" placeholder='Filter'/>
</th>
<th>
<button class="btn btn-default" (click)="refreshTable($event)">
<span class="glyphicon glyphicon-refresh"></span>
</button>
</th>
</tr>
<tr>
<th [ngClass]="{true:'visible', false:'invisible'}[showIDs]"><mfDefaultSorter by="id">ID</mfDefaultSorter></th>
<th><mfDefaultSorter by="label">Label</mfDefaultSorter></th>
<th><mfDefaultSorter by="abbreviation">Abbreviation</mfDefaultSorter></th>
<th><mfDefaultSorter by="reference">Reference</mfDefaultSorter></th>
<th><mfDefaultSorter by="uri">Uri</mfDefaultSorter></th>
<th><mfDefaultSorter by="definition">Definition</mfDefaultSorter></th>
</tr>
</thead>
<tbody>
<tr class="grayout-empty-table" *ngIf="!mf.data[0]" [contextMenu]="basicMenu" [contextMenuSubject]="registry"> <td colspan="5">No elements</td></tr>
<tr *ngFor="let registry of mf.data" class="hover" [contextMenu]="basicMenu" [contextMenuSubject]="registry">
<td [ngClass]="{true:'visible', false:'invisible'}[showIDs]">{{registry.id}}</td>
<td>{{registry?.label}}</td>
<td>{{registry?.abbreviation}}</td>
<td>{{registry?.reference}}</td>
<td>{{registry?.uri}}</td>
<td>{{registry?.definition}}</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5">
<mfBootstrapPaginator [rowsOnPageSet]="[10,20,40]"></mfBootstrapPaginator>
</td>
</tr>
</tfoot>
</table>
</div>
<!-- this is the dmp editor -->
<div [ngClass]="{true:'visible', false:'invisible'}[editorVisible]">
<div> <!-- form container -->
<div style="display:block;">
<button (click)="switchToTable()" class="btn btn-lg btn-success pull-right" style="max-width:120px;">
<span class="glyphicon glyphicon-arrow-left"></span> Go back
</button>
</div>
<form [formGroup]="registryEditorForm" novalidate style="display:block;">
<div class="form-group" [ngClass]="{null:'invisible'}[editingRegistry?.id]">
<label class="center-block">ID: {{editingRegistry?.id}}
<input class="form-control invisible" formControlName="id" [ngModel]="editingRegistry?.id">
</label>
</div>
<div class="form-group">
<label class="center-block">Label:
<input class="form-control" formControlName="label" [ngModel]="editingRegistry?.label" (ngModelChange)="editingRegistry.label=$event">
</label>
</div>
<div class="form-group">
<label class="center-block">Abbreviation:
<input class="form-control" formControlName="abbreviation" [ngModel]="editingRegistry?.abbreviation" (ngModelChange)="editingRegistry.abbreviation=$event">
</label>
</div>
<div class="form-group">
<label class="center-block">Reference:
<input class="form-control" formControlName="reference" [ngModel]="editingRegistry?.reference" (ngModelChange)="editingRegistry.reference$event">
</label>
</div>
<div class="form-group">
<label class="center-block">Uri:
<input class="form-control" formControlName="uri" [ngModel]="editingRegistry?.uri" (ngModelChange)="editingRegistry.uri$event">
</label>
</div>
<div class="form-group">
<label class="center-block">Definition:
<input class="form-control" formControlName="definition" [ngModel]="editingRegistry?.definition" (ngModelChange)="editingRegistry.definition$event">
</label>
</div>
<div class="form-group" style="width:540px;">
<button style="float:right;" type="submit" (click)="save($event, $data, $form)"class="btn btn-success">Save</button>
</div>
</form>
<!--
<p>Form value: {{ registryEditorForm.value | json }}</p>
-->
</div>
</div>
</div>
<context-menu>
<ng-template contextMenuItem [subMenu]="manage">
<span></span>Manage Registries
</ng-template>
<context-menu #manage>
<ng-template contextMenuItem (execute)="newRegistry($event?.item)">
<span class="glyphicon glyphicon-plus"></span>Create Registry
</ng-template>
<ng-template contextMenuItem (execute)="editRegistry($event?.item?.id)">
<span class="glyphicon glyphicon-pencil"></span>Edit this Registry
</ng-template>
<ng-template contextMenuItem (execute)="delete($event?.item?.id)">
<span class="glyphicon glyphicon-trash red"></span> Delete this
</ng-template>
</context-menu>
<ng-template contextMenuItem>
<span></span>Show full tree connections
</ng-template>
</context-menu>

View File

@ -1,25 +0,0 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { RegistryEditorComponent } from './registry-editor.component';
describe('RegistryEditorComponent', () => {
let component: RegistryEditorComponent;
let fixture: ComponentFixture<RegistryEditorComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ RegistryEditorComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(RegistryEditorComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should be created', () => {
expect(component).toBeTruthy();
});
});

View File

@ -1,140 +0,0 @@
import { Component, OnInit, ViewChild } from '@angular/core';
import { RegistryService } from '../../services/registry-service';
import { ContextMenuComponent } from 'ngx-contextmenu';
import { ReactiveFormsModule } from '@angular/forms';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import '../../../assets/custom.js';
declare function simple_notifier(type: string, title: string, message:string): any;
@Component({
selector: 'app-registry-editor',
templateUrl: './registry-editor.component.html',
styleUrls: ['./registry-editor.component.css']
})
export class RegistryEditorComponent implements OnInit {
//whole dmp data model
tableData : any[] = new Array();
//project editor data model
editingRegistry: any = {};
registryEditorForm : any;
//required by the table
public filterQuery = "";
public rowsOnPage = 10;
//public sortBy = "email";
public sortOrder = "asc";
//visibility rules for containers
tableVisible: boolean = true;
editorVisible: boolean = false;
// for tableIds
showIDs : boolean = false;
constructor(private registryService : RegistryService, private fb: FormBuilder) {
}
ngOnInit() {
this.getAllRegistries(false);
this.createRegistrytEditorForm();
}
createRegistrytEditorForm(){
this.registryEditorForm = this.fb.group({
id: null,
label: ['', Validators.required ],
abbreviation: '',
reference: '',
uri: '',
definition: ''
});
}
switchToTable(){
this.tableVisible = true;
this.editorVisible = false;
}
switchToEditor(registryID){
this.tableVisible = false;
this.editorVisible = true;
if(registryID == null){
this.editingRegistry = {id: null, label: "", abbreviation: "", reference: "", uri: "", definition: "" };
}
else{
this.editingRegistry = this.tableData.filter((registry) => registry.id === registryID)[0];
}
}
getAllRegistries(showNotification : boolean){
this.registryService.getAllRegistries().subscribe( (data) => {
this.tableData = data;
if(showNotification)
simple_notifier("info",null,"Refreshed the table");
});
}
editRegistry(registry){
this.switchToEditor(registry);
}
newProject(){
this.switchToEditor(null);
}
save(mouseEvent){
this.registryService.create(this.registryEditorForm.value).subscribe(
response => {
simple_notifier("success",null,"Saved registry");
this.getAllRegistries(false);
this.switchToTable();
},
err => {
simple_notifier("danger",null,"Could not save registry");
}
);
}
delete(registry){
this.registryService.delete(registry).subscribe(
(response) => {
simple_notifier("success",null,"Deleted registry");
this.getAllRegistries(false);
this.switchToTable();
},
(err) => {
simple_notifier("danger",null,"Could not delete registry");
}
)
}
refreshTable($event){
this.getAllRegistries(true);
}
@ViewChild(ContextMenuComponent) public basicMenu: ContextMenuComponent;
}

View File

@ -1,33 +0,0 @@
.invisible {
display:none;
}
.visible {
display:block;
}
tr.hover:hover > * {
background-color: #eeeeee;
}
.editor-container{
padding-top: 10px;
padding-right: 10px;
padding-bottom: 10px;
padding-left: 10px;
}
.button-150px {
max-width: 150px;
}
.ng-template{
text-align: right;
}
.grayout-empty-table {
opacity: 0.6; /* Real browsers */
filter: alpha(opacity = 60); /* MSIE */
text-align: center;
vertical-align: middle;
}

View File

@ -1,122 +0,0 @@
<div class="editor-container container">
<div [ngClass]="{true:'visible', false:'invisible'}[tableVisible]">
<table class="table table-striped" [mfData]="tableData | researcherTableFilter : filterQuery" #mf="mfDataTable" [mfRowsOnPage]="rowsOnPage" [(mfSortBy)]="sortBy" [(mfSortOrder)]="sortOrder">
<thead>
<tr>
<th colspan="1">
<input class="form-control" [(ngModel)]="filterQuery" placeholder='Filter'/>
</th>
<th>
<button class="btn btn-default" (click)="refreshTable($event)">
<span class="glyphicon glyphicon-refresh"></span>
</button>
</th>
</tr>
<tr>
<th [ngClass]="{true:'visible', false:'invisible'}[showIDs]"><mfDefaultSorter by="id">ID</mfDefaultSorter></th>
<th><mfDefaultSorter by="label">Label</mfDefaultSorter></th>
<th><mfDefaultSorter by="uri">Uri</mfDefaultSorter></th>
<th><mfDefaultSorter by="primaryEmail">PrimaryEmail</mfDefaultSorter></th>
<th><mfDefaultSorter by="definition">Definition</mfDefaultSorter></th>
<th><mfDefaultSorter by="reference">Reference</mfDefaultSorter></th>
</tr>
</thead>
<tbody>
<tr class="grayout-empty-table" *ngIf="!mf.data[0]" [contextMenu]="basicMenu" [contextMenuSubject]="researcher"> <td colspan="5">No elements</td></tr>
<tr *ngFor="let researcher of mf.data" class="hover" [contextMenu]="basicMenu" [contextMenuSubject]="researcher">
<td [ngClass]="{true:'visible', false:'invisible'}[showIDs]">{{researcher.id}}</td>
<td>{{researcher?.label}}</td>
<td>{{researcher?.uri}}</td>
<td>{{researcher?.primaryEmail}}</td>
<td>{{researcher?.definition}}</td>
<td>{{researcher?.reference}}</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5">
<mfBootstrapPaginator [rowsOnPageSet]="[10,20,40]"></mfBootstrapPaginator>
</td>
</tr>
</tfoot>
</table>
</div>
<!-- this is the dmp editor -->
<div [ngClass]="{true:'visible', false:'invisible'}[editorVisible]">
<div> <!-- form container -->
<div style="display:block;">
<button (click)="switchToTable()" class="btn btn-lg btn-success pull-right" style="max-width:120px;">
<span class="glyphicon glyphicon-arrow-left"></span> Go back
</button>
</div>
<form [formGroup]="researcherEditorForm" novalidate style="display:block;">
<div class="form-group" [ngClass]="{null:'invisible'}[editingResearcher?.id]">
<label class="center-block">ID: {{editingResearcher?.id}}
<input class="form-control invisible" formControlName="id" [ngModel]="editingResearcher?.id">
</label>
</div>
<div class="form-group">
<label class="center-block">Label:
<input class="form-control" formControlName="label" [ngModel]="editingResearcher?.label" (ngModelChange)="editingResearcher.label=$event">
</label>
</div>
<div class="form-group">
<label class="center-block">Uri:
<input class="form-control" formControlName="uri" [ngModel]="editingResearcher?.uri" (ngModelChange)="editingResearcher.uri$event">
</label>
</div>
<div class="form-group">
<label class="center-block">Primary Email:
<input class="form-control" formControlName="primaryEmail" [ngModel]="editingResearcher?.primaryEmail" (ngModelChange)="editingResearcher.primaryEmail=$event">
</label>
</div>
<div class="form-group">
<label class="center-block">Definition:
<input class="form-control" formControlName="definition" [ngModel]="editingResearcher?.definition" (ngModelChange)="editingResearcher.definition$event">
</label>
</div>
<div class="form-group">
<label class="center-block">Reference:
<input class="form-control" formControlName="reference" [ngModel]="editingResearcher?.reference" (ngModelChange)="editingResearcher.reference$event">
</label>
</div>
<div class="form-group" style="width:540px;">
<button style="float:right;" type="submit" (click)="save($event, $data, $form)"class="btn btn-success">Save</button>
</div>
</form>
<!--
<p>Form value: {{ researcherEditorForm.value | json }}</p>
-->
</div>
</div>
</div>
<context-menu>
<ng-template contextMenuItem [subMenu]="manage">
<span></span>Manage researchers
</ng-template>
<context-menu #manage>
<ng-template contextMenuItem (execute)="newResearcher($event?.item)">
<span class="glyphicon glyphicon-plus"></span>Create researcher
</ng-template>
<ng-template contextMenuItem (execute)="editResearcher($event?.item?.id)">
<span class="glyphicon glyphicon-pencil"></span>Edit this researcher
</ng-template>
<ng-template contextMenuItem (execute)="delete($event?.item?.id)">
<span class="glyphicon glyphicon-trash red"></span> Delete this
</ng-template>
</context-menu>
<ng-template contextMenuItem>
<span></span>Show full tree connections
</ng-template>
</context-menu>

View File

@ -1,25 +0,0 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ResearcherEditorComponent } from './researcher-editor.component';
describe('ResearcherEditorComponent', () => {
let component: ResearcherEditorComponent;
let fixture: ComponentFixture<ResearcherEditorComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ResearcherEditorComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ResearcherEditorComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should be created', () => {
expect(component).toBeTruthy();
});
});

View File

@ -1,135 +0,0 @@
import { Component, OnInit, ViewChild } from '@angular/core';
import { ResearcherService } from '../../services/researcher-service';
import { ContextMenuComponent } from 'ngx-contextmenu';
import { ReactiveFormsModule } from '@angular/forms';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import '../../../assets/custom.js';
declare function simple_notifier(type: string, title: string, message:string): any;
@Component({
selector: 'app-researcher-editor',
templateUrl: './researcher-editor.component.html',
styleUrls: ['./researcher-editor.component.css']
})
export class ResearcherEditorComponent implements OnInit {
constructor(private researcherService : ResearcherService, private fb: FormBuilder) {
}
//whole dmp data model
tableData : any[] = new Array();
//researcher editor data model
editingResearcher: any = {};
researcherEditorForm : any;
//required by the table
public filterQuery = "";
public rowsOnPage = 10;
//public sortBy = "email";
public sortOrder = "asc";
//visibility rules for containers
tableVisible: boolean = true;
editorVisible: boolean = false;
// for tableIds
showIDs : boolean = false;
ngOnInit() {
this.getAllResearchers(false);
this.createResearcherEditorForm();
}
createResearcherEditorForm(){
this.researcherEditorForm = this.fb.group({
id: null,
label: ['', Validators.required ],
uri: '',
primaryEmail: '',
definition: '',
reference: ''
});
}
switchToTable(){
this.tableVisible = true;
this.editorVisible = false;
}
switchToEditor(researcherID){
this.tableVisible = false;
this.editorVisible = true;
if(researcherID == null){
this.editingResearcher = {id: null, label: "", uri: "", primaryEmail: "", definition: "", reference: "" };
}
else{
this.editingResearcher = this.tableData.filter((researcher) => researcher.id === researcherID)[0];
}
}
getAllResearchers(showNotification : boolean){
this.researcherService.getAllResearchers().subscribe( (data) => {
this.tableData = data;
if(showNotification)
simple_notifier("info",null,"Refreshed the table");
});
}
editResearcher(researcher){
this.switchToEditor(researcher);
}
newResearcher(){
this.switchToEditor(null);
}
save(mouseEvent){
this.researcherService.create(this.researcherEditorForm.value).subscribe(
response => {
simple_notifier("success",null,"Saved resercher");
this.getAllResearchers(false);
this.switchToTable();
},
err => {
simple_notifier("danger",null,"Could not save researcher");
}
);
}
delete(resercher){
this.researcherService.delete(resercher).subscribe(
(response) => {
simple_notifier("success",null,"Deleted researcher");
this.getAllResearchers(false);
this.switchToTable();
},
(err) => {
simple_notifier("danger",null,"Could not delete researcher");
}
)
}
refreshTable($event){
this.getAllResearchers(true);
}
@ViewChild(ContextMenuComponent) public basicMenu: ContextMenuComponent;
}

View File

@ -1,33 +0,0 @@
.invisible {
display:none;
}
.visible {
display:block;
}
tr.hover:hover > * {
background-color: #eeeeee;
}
.editor-container{
padding-top: 10px;
padding-right: 10px;
padding-bottom: 10px;
padding-left: 10px;
}
.button-150px {
max-width: 150px;
}
.ng-template{
text-align: right;
}
.grayout-empty-table {
opacity: 0.6; /* Real browsers */
filter: alpha(opacity = 60); /* MSIE */
text-align: center;
vertical-align: middle;
}

View File

@ -1,122 +0,0 @@
<div class="editor-container container">
<div [ngClass]="{true:'visible', false:'invisible'}[tableVisible]">
<table class="table table-striped" [mfData]="tableData | serviceTableFilter : filterQuery" #mf="mfDataTable" [mfRowsOnPage]="rowsOnPage" [(mfSortBy)]="sortBy" [(mfSortOrder)]="sortOrder">
<thead>
<tr>
<th colspan="1">
<input class="form-control" [(ngModel)]="filterQuery" placeholder='Filter'/>
</th>
<th>
<button class="btn btn-default" (click)="refreshTable($event)">
<span class="glyphicon glyphicon-refresh"></span>
</button>
</th>
</tr>
<tr>
<th [ngClass]="{true:'visible', false:'invisible'}[showIDs]"><mfDefaultSorter by="id">ID</mfDefaultSorter></th>
<th><mfDefaultSorter by="label">Label</mfDefaultSorter></th>
<th><mfDefaultSorter by="abbreviation">Abbreviation</mfDefaultSorter></th>
<th><mfDefaultSorter by="reference">Reference</mfDefaultSorter></th>
<th><mfDefaultSorter by="uri">Uri</mfDefaultSorter></th>
<th><mfDefaultSorter by="definition">Definition</mfDefaultSorter></th>
</tr>
</thead>
<tbody>
<tr class="grayout-empty-table" *ngIf="!mf.data[0]" [contextMenu]="basicMenu" [contextMenuSubject]="service"> <td colspan="5">No elements</td></tr>
<tr *ngFor="let service of mf.data" class="hover" [contextMenu]="basicMenu" [contextMenuSubject]="service">
<td [ngClass]="{true:'visible', false:'invisible'}[showIDs]">{{service?.id}}</td>
<td>{{service?.label}}</td>
<td>{{service?.abbreviation}}</td>
<td>{{service?.reference}}</td>
<td>{{service?.uri}}</td>
<td>{{service?.definition}}</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5">
<mfBootstrapPaginator [rowsOnPageSet]="[10,20,40]"></mfBootstrapPaginator>
</td>
</tr>
</tfoot>
</table>
</div>
<!-- this is the dmp editor -->
<div [ngClass]="{true:'visible', false:'invisible'}[editorVisible]">
<div> <!-- form container -->
<div style="display:block;">
<button (click)="switchToTable()" class="btn btn-lg btn-success pull-right" style="max-width:120px;">
<span class="glyphicon glyphicon-arrow-left"></span> Go back
</button>
</div>
<form [formGroup]="serviceEditorForm" novalidate style="display:block;">
<div class="form-group" [ngClass]="{null:'invisible'}[editingService?.id]">
<label class="center-block">ID: {{editingService?.id}}
<input class="form-control invisible" formControlName="id" [ngModel]="editingService?.id">
</label>
</div>
<div class="form-group">
<label class="center-block">Label:
<input class="form-control" formControlName="label" [ngModel]="editingService?.label" (ngModelChange)="editingService.label=$event">
</label>
</div>
<div class="form-group">
<label class="center-block">Abbreviation:
<input class="form-control" formControlName="abbreviation" [ngModel]="editingService?.abbreviation" (ngModelChange)="editingService.abbreviation=$event">
</label>
</div>
<div class="form-group">
<label class="center-block">Reference:
<input class="form-control" formControlName="reference" [ngModel]="editingService?.reference" (ngModelChange)="editingService.reference$event">
</label>
</div>
<div class="form-group">
<label class="center-block">Uri:
<input class="form-control" formControlName="uri" [ngModel]="editingService?.uri" (ngModelChange)="editingService.uri$event">
</label>
</div>
<div class="form-group">
<label class="center-block">Definition:
<input class="form-control" formControlName="definition" [ngModel]="editingService?.definition" (ngModelChange)="editingService.definition$event">
</label>
</div>
<div class="form-group" style="width:540px;">
<button style="float:right;" type="submit" (click)="save($event, $data, $form)"class="btn btn-success">Save</button>
</div>
</form>
<!--
<p>Form value: {{ serviceEditorForm.value | json }}</p>
-->
</div>
</div>
</div>
<context-menu>
<ng-template contextMenuItem [subMenu]="manage">
<span></span>Manage Services
</ng-template>
<context-menu #manage>
<ng-template contextMenuItem (execute)="newService($event?.item)">
<span class="glyphicon glyphicon-plus"></span>Create service
</ng-template>
<ng-template contextMenuItem (execute)="editService($event?.item?.id)">
<span class="glyphicon glyphicon-pencil"></span>Edit this service
</ng-template>
<ng-template contextMenuItem (execute)="delete($event?.item?.id)">
<span class="glyphicon glyphicon-trash red"></span> Delete this
</ng-template>
</context-menu>
<ng-template contextMenuItem>
<span></span>Show full tree connections
</ng-template>
</context-menu>

View File

@ -1,25 +0,0 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ServiceEditorComponent } from './service-editor.component';
describe('ServiceEditorComponent', () => {
let component: ServiceEditorComponent;
let fixture: ComponentFixture<ServiceEditorComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ServiceEditorComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ServiceEditorComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should be created', () => {
expect(component).toBeTruthy();
});
});

View File

@ -1,134 +0,0 @@
import { Component, OnInit, ViewChild } from '@angular/core';
import { ServiceService } from '../../services/service-service';
import { ContextMenuComponent } from 'ngx-contextmenu';
import { ReactiveFormsModule } from '@angular/forms';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import '../../../assets/custom.js';
declare function simple_notifier(type: string, title: string, message:string): any;
@Component({
selector: 'app-service-editor',
templateUrl: './service-editor.component.html',
styleUrls: ['./service-editor.component.css']
})
export class ServiceEditorComponent implements OnInit {
constructor(private serviceService : ServiceService, private fb: FormBuilder) {
}
//whole dmp data model
tableData : any[] = new Array();
//project editor data model
editingService: any = {};
serviceEditorForm : any;
//required by the table
public filterQuery = "";
public rowsOnPage = 10;
//public sortBy = "email";
public sortOrder = "asc";
//visibility rules for containers
tableVisible: boolean = true;
editorVisible: boolean = false;
// for tableIds
showIDs : boolean = false;
ngOnInit() {
this.getAllServices(false);
this.createServiceEditorForm();
}
createServiceEditorForm(){
this.serviceEditorForm = this.fb.group({
id: null,
label: ['', Validators.required ],
abbreviation: '',
reference: '',
uri: '',
definition: ''
});
}
switchToTable(){
this.tableVisible = true;
this.editorVisible = false;
}
switchToEditor(serviceID){
this.tableVisible = false;
this.editorVisible = true;
if(serviceID == null){
this.editingService = {id: null, label: "", abbreviation: "", reference: "", uri: "", definition: "" };
}
else{
this.editingService = this.tableData.filter((service) => service.id === serviceID)[0];
}
}
getAllServices(showNotification : boolean){
this.serviceService.getAllServices().subscribe( (data) => {
this.tableData = data;
if(showNotification)
simple_notifier("info",null,"Refreshed the table");
});
}
editService(service){
this.switchToEditor(service);
}
newService(){
this.switchToEditor(null);
}
save(mouseEvent){
this.serviceService.create(this.serviceEditorForm.value).subscribe(
response => {
simple_notifier("success",null,"Saved service");
this.getAllServices(false);
this.switchToTable();
},
err => {
simple_notifier("danger",null,"Could not save service");
}
);
}
delete(service){
this.serviceService.delete(service).subscribe(
(response) => {
simple_notifier("success",null,"Deleted service");
this.getAllServices(false);
this.switchToTable();
},
(err) => {
}
)
}
refreshTable($event){
this.getAllServices(true);
}
@ViewChild(ContextMenuComponent) public basicMenu: ContextMenuComponent;
}

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 secret: string;
}

View File

@ -0,0 +1,12 @@
export enum LoginProviders {
Google = 1,
Facebook = 2,
Twitter = 3,
LinkedIn = 4
}
export class LoginInfo {
public ticket: string;
public provider: LoginProviders;
public data?: any;
}

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

@ -5,22 +5,17 @@ import { Routes, RouterModule } from '@angular/router';
import { GooggleSignInComponent } from './login/googgle-sign-in/googgle-sign-in.component';
import { DatasetsViewerComponent } from './datasets-viewer/datasets-viewer.component';
import { ProfileEditorComponent } from './bootstrap/profile-editor/profile-editor.component';
import { DmpEditorComponent } from './managers/dmp-editor/dmp-editor.component';
import { DmpProfileEditorComponent } from './managers/dmp-profile-editor/dmp-profile-editor.component';
import { ProjectEditorComponent } from './managers/project-editor/project-editor.component';
import { ServiceEditorComponent } from './managers/service-editor/service-editor.component';
import { RegistryEditorComponent } from './managers/registry-editor/registry-editor.component';
import { OrganisationEditorComponent } from './managers/organisation-editor/organisation-editor.component';
import { ResearcherEditorComponent } from './managers/researcher-editor/researcher-editor.component';
import { DatareposEditorComponent } from './managers/datarepos-editor/datarepos-editor.component';
import { DatasetprofileEditorComponent } from './managers/datasetprofile-editor/datasetprofile-editor.component';
import { MainWindowComponent } from './main-window/main-window.component';
import { NgModule } from '@angular/core';
import { AuthGuard } from './guards/auth.guard';
// Route Configuration
export const routes: Routes = [
const routes: Routes = [
{
path: '',
@ -29,65 +24,41 @@ export const routes: Routes = [
},
{
path: 'datasets',
component: DatasetsViewerComponent
component: DatasetsViewerComponent,
canActivate: [AuthGuard]
},
{
path: 'datasetprofiles',
component: DatasetprofileEditorComponent
},
{
path: 'datarepos',
component: DatareposEditorComponent
component: DatasetprofileEditorComponent,
canActivate: [AuthGuard]
},
{
path: 'datasets/profile',
component: ProfileEditorComponent
component: ProfileEditorComponent,
canActivate: [AuthGuard]
//,data: { title: 'a title' }
},
{
path: 'dmps',
component: DmpEditorComponent
},
{
path: 'dmpprofiles',
component: DmpProfileEditorComponent
},
{
path: 'projects',
component: ProjectEditorComponent
},
{
path: 'services',
component: ServiceEditorComponent
},
{
path: 'organisations',
component: OrganisationEditorComponent
},
{
path: 'registries',
component: RegistryEditorComponent
},
{
path: 'researchers',
component: ResearcherEditorComponent
},
{
path: 'main',
component: MainWindowComponent
component: MainWindowComponent,
canActivate: [AuthGuard]
},
{
path: 'form/:id',
component: FormComponent
},
{
path: 'form',
component: FormComponent
}
{ path: 'form', loadChildren: './dataset-profile-form/dataset-profile.module#DatasetProfileModule', canActivate: [AuthGuard]}
];
@NgModule({
imports: [
RouterModule.forRoot(
routes
)
],
exports: [
RouterModule
],
providers: [
]
})
export const AppRouting: ModuleWithProviders = RouterModule.forRoot(routes);
export class AppRouting { }
//export const AppRouting: ModuleWithProviders = RouterModule.forRoot(routes);

View File

@ -0,0 +1,59 @@
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 { Router } from '@angular/router';
import { JsonSerializer } from '../../utilities/JsonSerializer';
import { LoginInfo } from '../../models/login/LoginInfo';
import { Credential } from 'app/models/login/Credential';
//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 router: Router
) {
this.actionUrl = 'http://192.168.32.67:8080/' + 'auth/';
this.headers = new HttpHeaders();
this.headers = this.headers.set('Content-Type', 'application/json');
this.headers = this.headers.set('Accept', 'application/json');
}
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 nativeLogin(credentials: Credential): Observable<Principal> { debugger;
const url = this.actionUrl + 'nativelogin';
return this.http.post(url, credentials, { headers: this.headers })
.map((res: any) => {
const principal = this.current(JsonSerializer.fromJSONObject(res.payload, Principal));
//this.loginContextSubject.next(true);
return principal;
})
.catch((error: any) => {
//this.loginContextSubject.next(false);
return Observable.throw(error);
});
}
}

View File

@ -19,7 +19,7 @@ export class RestBase {
*/
protocol: string = "http";
//hostname: string = "localhost";
hostname: string = "192.168.32.73";
hostname: string = "192.168.32.67";
port: number = 8080;
webappname: string = "";
restpath: string = "";

View File

@ -1,8 +1,8 @@
import { Serializable } from '../models/interfaces/Serializable';
export class JsonSerializer<T extends Serializable<T>>{
export class JsonSerializer{
public fromJSONArray(items: any[], type: { new(): T; }): T[] {
if(!items)return null;
public static fromJSONArray<T extends Serializable<T>>(items: any[], type: { new(): T; }): T[] {
if(!items)return new Array<T>();
const objectList: T[] = new Array<T>();
for (let i = 0; i < items.length; i++) {
objectList.push(new type().fromJSONObject(items[i]))
@ -10,7 +10,7 @@ export class JsonSerializer<T extends Serializable<T>>{
return objectList;
}
public fromJSONObject(item: any, type: { new(): T; }): T {
public static fromJSONObject<T extends Serializable<T>>(item: any, type: { new(): T; }): T {
if(!item)return null;
return new type().fromJSONObject(item);
}