dmp-admin v.0.9
This commit is contained in:
parent
d3c85a08b7
commit
ea2e3340fe
|
@ -0,0 +1,60 @@
|
|||
{
|
||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||
"project": {
|
||||
"name": "dmp-admin"
|
||||
},
|
||||
"apps": [
|
||||
{
|
||||
"root": "src",
|
||||
"outDir": "dist",
|
||||
"assets": [
|
||||
"assets",
|
||||
"favicon.ico"
|
||||
],
|
||||
"index": "index.html",
|
||||
"main": "main.ts",
|
||||
"polyfills": "polyfills.ts",
|
||||
"test": "test.ts",
|
||||
"tsconfig": "tsconfig.app.json",
|
||||
"testTsconfig": "tsconfig.spec.json",
|
||||
"prefix": "app",
|
||||
"styles": [
|
||||
"styles.css"
|
||||
],
|
||||
"scripts": [],
|
||||
"environmentSource": "environments/environment.ts",
|
||||
"environments": {
|
||||
"dev": "environments/environment.ts",
|
||||
"prod": "environments/environment.prod.ts"
|
||||
}
|
||||
}
|
||||
],
|
||||
"e2e": {
|
||||
"protractor": {
|
||||
"config": "./protractor.conf.js"
|
||||
}
|
||||
},
|
||||
"lint": [
|
||||
{
|
||||
"project": "src/tsconfig.app.json",
|
||||
"exclude": "**/node_modules/**"
|
||||
},
|
||||
{
|
||||
"project": "src/tsconfig.spec.json",
|
||||
"exclude": "**/node_modules/**"
|
||||
},
|
||||
{
|
||||
"project": "e2e/tsconfig.e2e.json",
|
||||
"exclude": "**/node_modules/**"
|
||||
}
|
||||
],
|
||||
"test": {
|
||||
"karma": {
|
||||
"config": "./karma.conf.js"
|
||||
}
|
||||
},
|
||||
"defaults": {
|
||||
"styleExt": "css",
|
||||
"component": {}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
# Editor configuration, see http://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
max_line_length = off
|
||||
trim_trailing_whitespace = false
|
|
@ -0,0 +1,43 @@
|
|||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
# compiled output
|
||||
/dist
|
||||
/tmp
|
||||
/out-tsc
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
|
||||
# IDEs and editors
|
||||
/.idea
|
||||
.project
|
||||
.classpath
|
||||
.c9/
|
||||
*.launch
|
||||
.settings/
|
||||
*.sublime-workspace
|
||||
|
||||
# IDE - VSCode
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
|
||||
# misc
|
||||
/.sass-cache
|
||||
/connect.lock
|
||||
/coverage
|
||||
/libpeerconnection.log
|
||||
npm-debug.log
|
||||
testem.log
|
||||
/typings
|
||||
yarn-error.log
|
||||
|
||||
# e2e
|
||||
/e2e/*.js
|
||||
/e2e/*.map
|
||||
|
||||
# System Files
|
||||
.DS_Store
|
||||
Thumbs.db
|
|
@ -0,0 +1,28 @@
|
|||
# DmpAdmin
|
||||
|
||||
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 1.3.1.
|
||||
|
||||
## Development server
|
||||
|
||||
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
|
||||
|
||||
## Code scaffolding
|
||||
|
||||
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
|
||||
|
||||
## Build
|
||||
|
||||
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build.
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
||||
|
||||
## Running end-to-end tests
|
||||
|
||||
Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
|
||||
Before running the tests make sure you are serving the app via `ng serve`.
|
||||
|
||||
## Further help
|
||||
|
||||
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
|
|
@ -0,0 +1,14 @@
|
|||
import { AppPage } from './app.po';
|
||||
|
||||
describe('dmp-admin App', () => {
|
||||
let page: AppPage;
|
||||
|
||||
beforeEach(() => {
|
||||
page = new AppPage();
|
||||
});
|
||||
|
||||
it('should display welcome message', () => {
|
||||
page.navigateTo();
|
||||
expect(page.getParagraphText()).toEqual('Welcome to app!');
|
||||
});
|
||||
});
|
|
@ -0,0 +1,11 @@
|
|||
import { browser, by, element } from 'protractor';
|
||||
|
||||
export class AppPage {
|
||||
navigateTo() {
|
||||
return browser.get('/');
|
||||
}
|
||||
|
||||
getParagraphText() {
|
||||
return element(by.css('app-root h1')).getText();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../out-tsc/e2e",
|
||||
"baseUrl": "./",
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"types": [
|
||||
"jasmine",
|
||||
"jasminewd2",
|
||||
"node"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
basePath: '',
|
||||
frameworks: ['jasmine', '@angular/cli'],
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage-istanbul-reporter'),
|
||||
require('@angular/cli/plugins/karma')
|
||||
],
|
||||
client:{
|
||||
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
coverageIstanbulReporter: {
|
||||
reports: [ 'html', 'lcovonly' ],
|
||||
fixWebpackSourcePaths: true
|
||||
},
|
||||
angularCli: {
|
||||
environment: 'dev'
|
||||
},
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
singleRun: false
|
||||
});
|
||||
};
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,61 @@
|
|||
{
|
||||
"name": "dmp-admin",
|
||||
"version": "0.0.0",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"build": "ng build",
|
||||
"test": "ng test",
|
||||
"lint": "ng lint",
|
||||
"e2e": "ng e2e"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "^4.2.4",
|
||||
"@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/platform-browser": "^4.2.4",
|
||||
"@angular/platform-browser-dynamic": "^4.2.4",
|
||||
"@angular/router": "^4.2.4",
|
||||
"@ng-bootstrap/ng-bootstrap": "^1.0.0-beta.5",
|
||||
"angular-datatables": "^4.4.0",
|
||||
"angular2-datatable": "^0.6.0",
|
||||
"angular2-localstorage": "^0.4.0",
|
||||
"bootstrap": "^3.3.7",
|
||||
"bootstrap-menu": "^1.0.14",
|
||||
"core-js": "^2.4.1",
|
||||
"jquery": "^3.2.1",
|
||||
"ng2-bootstrap-modal": "^1.0.1",
|
||||
"ng2-simple-global": "^1.2.5",
|
||||
"ngx-contextmenu": "^1.3.5",
|
||||
"ngx-webstorage": "^1.8.0",
|
||||
"rxjs": "^5.4.2",
|
||||
"zone.js": "^0.8.14"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular/cli": "1.3.1",
|
||||
"@angular/compiler-cli": "^4.2.4",
|
||||
"@angular/language-service": "^4.2.4",
|
||||
"@types/jasmine": "~2.5.53",
|
||||
"@types/jasminewd2": "~2.0.2",
|
||||
"@types/jquery": "^3.2.12",
|
||||
"@types/node": "~6.0.60",
|
||||
"codelyzer": "~3.1.1",
|
||||
"jasmine-core": "~2.6.2",
|
||||
"jasmine-spec-reporter": "~4.1.0",
|
||||
"karma": "~1.7.0",
|
||||
"karma-chrome-launcher": "~2.1.1",
|
||||
"karma-cli": "~1.0.1",
|
||||
"karma-coverage-istanbul-reporter": "^1.2.1",
|
||||
"karma-jasmine": "~1.1.0",
|
||||
"karma-jasmine-html-reporter": "^0.2.2",
|
||||
"protractor": "~5.1.2",
|
||||
"ts-node": "~3.2.0",
|
||||
"tslint": "~5.3.2",
|
||||
"typescript": "~2.3.3"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
// Protractor configuration file, see link for more information
|
||||
// https://github.com/angular/protractor/blob/master/lib/config.ts
|
||||
|
||||
const { SpecReporter } = require('jasmine-spec-reporter');
|
||||
|
||||
exports.config = {
|
||||
allScriptsTimeout: 11000,
|
||||
specs: [
|
||||
'./e2e/**/*.e2e-spec.ts'
|
||||
],
|
||||
capabilities: {
|
||||
'browserName': 'chrome'
|
||||
},
|
||||
directConnect: true,
|
||||
baseUrl: 'http://localhost:4200/',
|
||||
framework: 'jasmine',
|
||||
jasmineNodeOpts: {
|
||||
showColors: true,
|
||||
defaultTimeoutInterval: 30000,
|
||||
print: function() {}
|
||||
},
|
||||
onPrepare() {
|
||||
require('ts-node').register({
|
||||
project: 'e2e/tsconfig.e2e.json'
|
||||
});
|
||||
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
|
||||
}
|
||||
};
|
|
@ -0,0 +1,20 @@
|
|||
.navbar-center {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
margin:0 auto;
|
||||
}
|
||||
|
||||
.invisible {
|
||||
display:none;
|
||||
}
|
||||
|
||||
.visible {
|
||||
display:block;
|
||||
}
|
||||
|
||||
.cursor{
|
||||
cursor: pointer;
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
|
||||
<div>
|
||||
|
||||
|
||||
<nav class="navbar navbar-default">
|
||||
<div class="container-fluid">
|
||||
<!-- Brand and toggle get grouped for better mobile display -->
|
||||
<div class="navbar-header">
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Collect the nav links, forms, and other content for toggling -->
|
||||
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
||||
<div class="nav navbar-nav">
|
||||
|
||||
</div>
|
||||
<div class="navbar-left">
|
||||
|
||||
</div>
|
||||
<div class="navbar-center">
|
||||
<h3>Digital Management Plans Backend Administration</h3>
|
||||
</div>
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li class="dropdown" [ngClass]="{true:'invisible'}[loggedInAs == null]">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Quick links <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#">Action</a></li>
|
||||
<li><a href="#">Another action</a></li>
|
||||
<li><a href="#">Something else here</a></li>
|
||||
<li role="separator" class="divider"></li>
|
||||
<li><a href="#">Separated link</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li [ngClass]="{false:'invisible'}[tokenService.isLoggedIn() == true]"><a>{{tokenService.getEmail()}}</a></li>
|
||||
<li class="cursor" [ngClass]="{false:'invisible'}[tokenService.isLoggedIn() == true]" (click)="logout()"><a>Logout</a></li>
|
||||
<li class="cursor" [ngClass]="{true:'invisible'}[tokenService.isLoggedIn() == true]" (click)="login()" ><a>Login</a></li>
|
||||
</ul>
|
||||
</div><!-- /.navbar-collapse -->
|
||||
</div><!-- /.container-fluid -->
|
||||
</nav>
|
||||
|
||||
<main-window [ngClass]="{false:'invisible'}[tokenService.isLoggedIn() == true]"></main-window>
|
||||
|
||||
<app-main-sign-in [ngClass]="{true:'invisible'}[tokenService.isLoggedIn() == true]"></app-main-sign-in>
|
||||
|
||||
|
||||
</div>
|
|
@ -0,0 +1,32 @@
|
|||
import { TestBed, async } from '@angular/core/testing';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
describe('AppComponent', () => {
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [
|
||||
AppComponent
|
||||
],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
it('should create the app', async(() => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.debugElement.componentInstance;
|
||||
expect(app).toBeTruthy();
|
||||
}));
|
||||
|
||||
it(`should have as title 'app'`, async(() => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.debugElement.componentInstance;
|
||||
expect(app.title).toEqual('app');
|
||||
}));
|
||||
|
||||
it('should render title in a h1 tag', async(() => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
fixture.detectChanges();
|
||||
const compiled = fixture.debugElement.nativeElement;
|
||||
expect(compiled.querySelector('h1').textContent).toContain('Welcome to app!');
|
||||
}));
|
||||
});
|
|
@ -0,0 +1,59 @@
|
|||
import { Component } from '@angular/core';
|
||||
import { TokenService, TokenProvider } from './services/login/token.service';
|
||||
import {Router} from '@angular/router';
|
||||
|
||||
import '../assets/custom.js';
|
||||
declare function sign_out_google(): any;
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.css']
|
||||
})
|
||||
|
||||
export class AppComponent {
|
||||
|
||||
|
||||
constructor(private tokenService : TokenService, private router: Router) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
//loggedInAs : string = null;
|
||||
|
||||
showLogin : boolean = false;
|
||||
|
||||
|
||||
authenticateToServer(tokenInfo){
|
||||
|
||||
console.log("Running authenticateToServer");
|
||||
console.log(tokenInfo);
|
||||
|
||||
//backendURL, token
|
||||
//return this.tokenService.authenticate_backend(backendURL, token);
|
||||
}
|
||||
|
||||
|
||||
|
||||
logout(){
|
||||
//set the log out actions here
|
||||
this.tokenService.setLoggedIn(false);
|
||||
this.tokenService.setEmail(null);
|
||||
this.tokenService.setUsername(null);
|
||||
this.tokenService.setToken(null);
|
||||
|
||||
if(this.tokenService.getProvider() == TokenProvider.google){
|
||||
sign_out_google();
|
||||
}
|
||||
|
||||
|
||||
this.tokenService.setProvider(null);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { NgModule } from '@angular/core';
|
||||
//import { HttpModule, Http, Response, RequestOptions, RequestMethod, Headers, URLSearchParams } from '@angular/http';
|
||||
import { HttpClientModule, HttpClient, HTTP_INTERCEPTORS } from '@angular/common/http';
|
||||
import { HttpModule} from '@angular/http';
|
||||
import { DataTableModule } from "angular2-datatable";
|
||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { DialogService } from "ng2-bootstrap-modal";
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { ContextMenuModule } from 'ngx-contextmenu';
|
||||
import { Ng2Webstorage } from 'ngx-webstorage';
|
||||
|
||||
import { AuthInterceptor } from './services/interceptors/auth-interceptor';
|
||||
import { RestBase } from './services/rest-base';
|
||||
import { TokenService } from './services/login/token.service';
|
||||
import { NativeLoginService } from './services/login/native-login.service';
|
||||
import { DatasetsServiceService } from './services/datasets-service.service';
|
||||
import { DatasetProfileService } from './services/dataset-profile.service';
|
||||
import { DmpsServiceService } from './services/dmps-service.service';
|
||||
import { ProjectService } from './services/project-service';
|
||||
import { ServiceService } from './services/service-service';
|
||||
import { OrganisationService } from './services/organisation-service';
|
||||
import { DmpProfileService } from './services/dmpprofile-service';
|
||||
import { RegistryService } from './services/registry-service';
|
||||
import { Toolbox } from './services/toolbox';
|
||||
|
||||
import { DataFilterPipe } from './pipes/data-filter.pipe';
|
||||
import { DmpTableFilterPipe } from './pipes/dmp-table-filter.pipe';
|
||||
import { ServiceTableFilterPipe } from './pipes/service-table-filter.pipe';
|
||||
import { DmpProfileTableFilterPipe } from './pipes/dmp-profile-table-filter.pipe';
|
||||
import { ProjectTableFilterPipe } from './pipes/project-table-filter.pipe';
|
||||
import { RegistryTableFilterPipe } from './pipes/registry-table-filter.pipe';
|
||||
import { OrganisationTableFilterPipe } from './pipes/organisation-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';
|
||||
import { ProfileEditorComponent } from './bootstrap/profile-editor/profile-editor.component';
|
||||
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';
|
||||
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
DataFilterPipe,
|
||||
DmpTableFilterPipe,
|
||||
DmpProfileTableFilterPipe,
|
||||
ProjectTableFilterPipe,
|
||||
OrganisationTableFilterPipe,
|
||||
RegistryTableFilterPipe,
|
||||
ServiceTableFilterPipe,
|
||||
|
||||
AppComponent,
|
||||
GooggleSignInComponent,
|
||||
DatasetsViewerComponent,
|
||||
ProfileEditorComponent,
|
||||
PropertiesEditorComponent,
|
||||
NewDatasetComponent,
|
||||
ConfirmationComponent,
|
||||
DmpEditorComponent,
|
||||
MainWindowComponent,
|
||||
ProjectEditorComponent,
|
||||
DmpProfileEditorComponent,
|
||||
OrganisationEditorComponent,
|
||||
RegistryEditorComponent,
|
||||
ServiceEditorComponent,
|
||||
MainSignInComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
HttpClientModule,
|
||||
HttpModule,
|
||||
DataTableModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
ContextMenuModule,
|
||||
Ng2Webstorage,
|
||||
NgbModule.forRoot(),
|
||||
AppRouting
|
||||
],
|
||||
providers: [ DatasetsServiceService, TokenService, DmpsServiceService,
|
||||
DialogService, DatasetProfileService, ProjectService, OrganisationService,
|
||||
DmpProfileService, RegistryService, ServiceService, NativeLoginService, HttpModule, Toolbox, HttpClient, RestBase],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule { }
|
|
@ -0,0 +1,11 @@
|
|||
.modal-header {
|
||||
padding:9px 15px;
|
||||
border-bottom:1px solid #eee;
|
||||
background-color: #0480be;
|
||||
-webkit-border-top-left-radius: 5px;
|
||||
-webkit-border-top-right-radius: 5px;
|
||||
-moz-border-radius-topleft: 5px;
|
||||
-moz-border-radius-topright: 5px;
|
||||
border-top-left-radius: 5px;
|
||||
border-top-right-radius: 5px;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<!-- Modal -->
|
||||
<div class="modal fade" id="confirmation-modal" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
|
||||
<!-- Modal content-->
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||
<h4 class="modal-title">{{confirmationTitle}}</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>{{confirmationDescr}}</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal" (click)=saidYes()>Yes</button>
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal" (click)=saidNo()>NO</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ConfirmationComponent } from './confirmation.component';
|
||||
|
||||
describe('ConfirmationComponent', () => {
|
||||
let component: ConfirmationComponent;
|
||||
let fixture: ComponentFixture<ConfirmationComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ConfirmationComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ConfirmationComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,34 @@
|
|||
import { Component, OnInit, Input,Output,EventEmitter } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'confirmation',
|
||||
templateUrl: './confirmation.component.html',
|
||||
styleUrls: ['./confirmation.component.css']
|
||||
})
|
||||
export class ConfirmationComponent implements OnInit {
|
||||
|
||||
@Input() confirmationTitle : string;
|
||||
@Input() confirmationDescr : string;
|
||||
@Input() subjectObj : any;
|
||||
|
||||
@Output() responseSender: EventEmitter<any> = new EventEmitter<any>();
|
||||
|
||||
constructor() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
ngOnInit() {
|
||||
|
||||
}
|
||||
|
||||
saidNo(){
|
||||
this.responseSender.emit(false);
|
||||
}
|
||||
|
||||
saidYes(){
|
||||
this.responseSender.emit(true);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
.form-control {
|
||||
width: 540px;
|
||||
}
|
||||
|
||||
.form-control.props{
|
||||
height: 240px;
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
<!-- Modal -->
|
||||
<div class="modal fade" id="newdataset-modal-container" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
|
||||
<!-- Modal content-->
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||
<h4 class="modal-title"> Create a new dataset</h4>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="container">
|
||||
|
||||
<form [formGroup]="newdatasetform" novalidate>
|
||||
<div class="form-group">
|
||||
<label class="center-block">Label:
|
||||
<input class="form-control" formControlName="label">
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="center-block">DMP:
|
||||
<input class="form-control" formControlName="dmp">
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="center-block">Uri:
|
||||
<input class="form-control" formControlName="uri">
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="center-block">Properties:
|
||||
<textarea class="form-control props" formControlName="properties"></textarea>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="center-block">Profile:
|
||||
<input class="form-control" formControlName="profile">
|
||||
</label>
|
||||
</div>
|
||||
<div style="width:540px;">
|
||||
<button style="float:right;" type="submit" class="btn btn-success" (click)="store()">Submit</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<!--
|
||||
<p>Form value: {{ newdatasetform.value | json }}</p>
|
||||
-->
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { NewDatasetComponent } from './new-dataset.component';
|
||||
|
||||
describe('NewDatasetComponent', () => {
|
||||
let component: NewDatasetComponent;
|
||||
let fixture: ComponentFixture<NewDatasetComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ NewDatasetComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(NewDatasetComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,54 @@
|
|||
import { Component, OnInit, Output, EventEmitter } from '@angular/core';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { DatasetsServiceService } from '../../services/datasets-service.service';
|
||||
|
||||
declare var jQuery:any;
|
||||
|
||||
@Component({
|
||||
selector: 'new-dataset',
|
||||
templateUrl: './new-dataset.component.html',
|
||||
styleUrls: ['./new-dataset.component.css']
|
||||
})
|
||||
export class NewDatasetComponent implements OnInit {
|
||||
|
||||
|
||||
newdatasetform: FormGroup;
|
||||
|
||||
@Output() idSender: EventEmitter<any> = new EventEmitter<any>();
|
||||
|
||||
constructor(private datasetsService : DatasetsServiceService, private fb: FormBuilder) {
|
||||
|
||||
this.newdatasetform = this.fb.group({
|
||||
label: ['', Validators.required ],
|
||||
dmp: '',
|
||||
uri: '',
|
||||
properties: '',
|
||||
profile: ''
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
|
||||
//minimum dataset -> {"label": ""}
|
||||
}
|
||||
|
||||
|
||||
store(){
|
||||
for(var key in this.newdatasetform.value) {
|
||||
if(this.newdatasetform.value[key]=="")
|
||||
this.newdatasetform.value[key] = null;
|
||||
}
|
||||
this.datasetsService.setDataset(this.newdatasetform.value).subscribe(
|
||||
(data) => {
|
||||
console.log("Created a new dataset with id: "+data.json().objID);
|
||||
jQuery("#newdataset-modal-container").modal("hide");
|
||||
this.idSender.emit(data.json().objID);
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
.margin10{
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
margin-right: 10px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
|
||||
/* The ones below are for fields*/
|
||||
.custom-table {
|
||||
display: table; }
|
||||
|
||||
label {
|
||||
display: table-header-group;
|
||||
}
|
||||
|
||||
input {
|
||||
display: table-row-group;
|
||||
}
|
||||
|
||||
input:focus + label {
|
||||
color:black;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
<div>
|
||||
<!--{{profile| json}}-->
|
||||
<div class="panel panel-default margin10">
|
||||
<div class="panel-heading"><h4>Editing profile: {{profileID}}</h4></div>
|
||||
<div class="panel-body">
|
||||
|
||||
<ul class="nav nav-tabs content-tabs" id="maincontent" role="tablist">
|
||||
<li class="active"><a href="#profile" role="tab" data-toggle="tab">Profile</a></li>
|
||||
<li class=""><a href="#viewstyle" role="tab" data-toggle="tab">Profile's viewstyle</a></li>
|
||||
<li class=""><a href="#ruleset" role="tab" data-toggle="tab">Profile's ruleset</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content">
|
||||
|
||||
<div class="tab-pane fade active in" id="profile">
|
||||
<br />
|
||||
<div class="custom-table">
|
||||
<input name="profile-label" type="text" placeholder="Enter profile label" [(ngModel)]="profile.label" (focusin)="onFocusIn($event)" (ngModelChange)="onValueChanged($event)" (focusout)="onFocusOut($event)" (keydown)="preventDefaults($event)">
|
||||
<label for="profile-label">Label</label>
|
||||
</div>
|
||||
<br />
|
||||
<div class="custom-table">
|
||||
<textarea class="form-control custom" rows="10" cols="65" name="profile-definition" [(ngModel)]="profile.definition" (focusin)="onFocusIn($event)" (ngModelChange)="onValueChanged($event)" (focusout)="onFocusOut($event)" (keydown)="preventDefaults($event)" placeholder="Enter profile definition"></textarea>
|
||||
<label for="profile-definition">Definition</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="viewstyle">
|
||||
<br />
|
||||
<div class="custom-table">
|
||||
<input name="viewstyle-label" type="text" placeholder="Enter viewstyle label" [(ngModel)]="profile.viewstyle.label" (focusin)="onFocusIn($event)" (ngModelChange)="onValueChanged($event)" (focusout)="onFocusOut($event)" (keydown)="preventDefaults($event)">
|
||||
<label for="viewstyle-label">Label</label>
|
||||
</div>
|
||||
<br />
|
||||
<div class="custom-table">
|
||||
<textarea class="form-control custom" rows="10" cols="65" name="viewstyle-definition" [(ngModel)]="profile.viewstyle.definition" (focusin)="onFocusIn($event)" (ngModelChange)="onValueChanged($event)" (focusout)="onFocusOut($event)" (keydown)="preventDefaults($event)"></textarea>
|
||||
<label for="viewstyle-definition">Definition</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="ruleset">
|
||||
<br />
|
||||
<div class="custom-table">
|
||||
<input name="ruleset-label" type="text" placeholder="Enter ruleset label" [(ngModel)]="profile.ruleset.label" (focusin)="onFocusIn($event)" (ngModelChange)="onValueChanged($event)" (focusout)="onFocusOut($event)" (keydown)="preventDefaults($event)">
|
||||
<label for="ruleset-label">Label</label>
|
||||
</div>
|
||||
<br />
|
||||
<div class="custom-table">
|
||||
<textarea class="form-control custom" rows="10" cols="65" name="ruleset-definition" [(ngModel)]="profile.ruleset.definition" (focusin)="onFocusIn($event)" (ngModelChange)="onValueChanged($event)" (focusout)="onFocusOut($event)" (keydown)="preventDefaults($event)"></textarea>
|
||||
<label for="ruleset-definition">Definition</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ProfileEditorComponent } from './profile-editor.component';
|
||||
|
||||
describe('ProfileEditorComponent', () => {
|
||||
let component: ProfileEditorComponent;
|
||||
let fixture: ComponentFixture<ProfileEditorComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ProfileEditorComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ProfileEditorComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,93 @@
|
|||
import { Component, OnInit, SimpleChanges, Input} from '@angular/core';
|
||||
import {DatasetProfileService} from '../../services/dataset-profile.service';
|
||||
import {ActivatedRoute} from '@angular/router';
|
||||
|
||||
import '../../../assets/custom.js';
|
||||
declare function simple_notifier(type: string, title: string, message:string): any;
|
||||
|
||||
@Component({
|
||||
selector: 'profile-editor',
|
||||
templateUrl: './profile-editor.component.html',
|
||||
styleUrls: ['./profile-editor.component.css']
|
||||
})
|
||||
export class ProfileEditorComponent implements OnInit {
|
||||
|
||||
@Input('profileID') profileID: string = null;
|
||||
|
||||
profile : any = new Array();
|
||||
|
||||
//for update sensing...
|
||||
private haveChanges : boolean = false;
|
||||
|
||||
constructor(private datasetProfileService: DatasetProfileService, private route: ActivatedRoute) {
|
||||
this.profileID = route.snapshot.params['profileID'];
|
||||
//console.log(route.snapshot.params['profileID'])
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
/*
|
||||
if(this.profileID==null)
|
||||
return;
|
||||
if(changes.profileID != null){
|
||||
this.datasetProfileService.getDatasetProfileById(this.profileID).subscribe((data) => {
|
||||
this.profile = data;
|
||||
});
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.datasetProfileService.getDatasetProfileById(this.profileID).subscribe((data) => {
|
||||
this.profile = data;
|
||||
//console.log(data)
|
||||
});
|
||||
}
|
||||
|
||||
onFocusIn($event){
|
||||
console.log("on-focus-in");
|
||||
this.haveChanges = false;
|
||||
}
|
||||
|
||||
onValueChanged($event){
|
||||
console.log("on-text-changed");
|
||||
this.haveChanges = true;
|
||||
}
|
||||
|
||||
|
||||
onFocusOut($event, value:string){
|
||||
console.log("on-focus-out");
|
||||
if(this.haveChanges){
|
||||
var fieldName = $event.target.name;
|
||||
this.datasetProfileService.getDatasetProfileById(this.profileID).subscribe((data) => {
|
||||
var database_profile : any = data;
|
||||
//update appropriate field
|
||||
if(fieldName == 'profile-label') database_profile.label = this.profile.label;
|
||||
if(fieldName == 'profile-definition') database_profile.definition = this.profile.definition;
|
||||
if(fieldName == 'viewstyle-label') database_profile.viewstyle.label = this.profile.viewstyle.label;
|
||||
if(fieldName == 'viewstyle-definition') database_profile.viewstyle.definition = this.profile.viewstyle.definition;
|
||||
if(fieldName == 'ruleset-label') database_profile.ruleset.label = this.profile.ruleset.label;
|
||||
if(fieldName == 'ruleset-definition') database_profile.ruleset.definition = this.profile.ruleset.definition;
|
||||
//save back
|
||||
this.datasetProfileService.setDatasetProfile(database_profile);
|
||||
simple_notifier("success",null,"Updated value of field");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
preventDefaults($event){
|
||||
if($event.code == 'Tab') {
|
||||
$event.preventDefault();
|
||||
//AND NOW HACK THE TAB KEY WITHIN THE TEXT EDITOR
|
||||
var start = $event.srcElement.selectionStart;
|
||||
var end = $event.srcElement.selectionEnd;
|
||||
// set textarea value to: text before caret + tab + text after caret
|
||||
$event.target.value = $event.target.value.substring(0, start)+"\t"+$event.target.value.substring(end);
|
||||
// put caret at right position again
|
||||
$event.srcElement.selectionStart =
|
||||
$event.srcElement.selectionEnd = start + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
textarea.custom{
|
||||
border-style: dotted;
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
<!-- Modal -->
|
||||
<div class="modal fade" id="edit-properties-modal-container" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
|
||||
<!-- Modal content-->
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||
<h4 class="modal-title"> Edit properties data of {{datasetID}}</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<textarea class="form-control custom" rows="10" cols="65" [(ngModel)]="propstext" (focusin)="onFocusIn($event)" (ngModelChange)="onTextChanged($event)" (focusout)="onFocusOut($event)" (keydown)="preventDefaults($event)">
|
||||
</textarea>
|
||||
</div>
|
||||
<!--
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { PropertiesEditorComponent } from './properties-editor.component';
|
||||
|
||||
describe('PropertiesEditorComponent', () => {
|
||||
let component: PropertiesEditorComponent;
|
||||
let fixture: ComponentFixture<PropertiesEditorComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ PropertiesEditorComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(PropertiesEditorComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,82 @@
|
|||
import { Component, OnInit, Input, SimpleChanges } from '@angular/core';
|
||||
import { DatasetsServiceService } from '../../services/datasets-service.service';
|
||||
|
||||
import '../../../assets/custom.js';
|
||||
declare function simple_notifier(type: string, title: string, message:string): any;
|
||||
|
||||
@Component({
|
||||
selector: 'properties-editor',
|
||||
templateUrl: './properties-editor.component.html',
|
||||
styleUrls: ['./properties-editor.component.css']
|
||||
})
|
||||
export class PropertiesEditorComponent implements OnInit {
|
||||
|
||||
@Input('datasetID') datasetID : string;
|
||||
private propstext : string;
|
||||
|
||||
//for update sensing...
|
||||
private haveChanges : boolean = false;
|
||||
|
||||
|
||||
constructor(private datasetsService : DatasetsServiceService) {
|
||||
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
|
||||
if(this.datasetID==null)
|
||||
return;
|
||||
if(changes.datasetID != null){
|
||||
this.datasetsService.getDatasetById(this.datasetID).subscribe((data) => {
|
||||
this.propstext = data.properties;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
onFocusIn($event){
|
||||
this.haveChanges = false;
|
||||
}
|
||||
|
||||
onTextChanged($event){
|
||||
this.haveChanges = true;
|
||||
}
|
||||
|
||||
onFocusOut($event){
|
||||
if(this.haveChanges){
|
||||
//console.log("Updating the value of properties to: "+$event.target.value+" on row with id: "+this.datasetID);
|
||||
this.datasetsService.getDatasetById(this.datasetID).subscribe( (data) => {
|
||||
data.properties = $event.target.value;
|
||||
this.datasetsService.setDataset(data).subscribe( (data) => {
|
||||
if(data.status == 201){
|
||||
simple_notifier("success",null,"Updated value of properties field");
|
||||
}
|
||||
else{
|
||||
simple_notifier("danger",null,"Could not update value of properties field");
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
preventDefaults($event){
|
||||
if($event.code == 'Tab') {
|
||||
$event.preventDefault();
|
||||
//AND NOW HACK THE TAB KEY WITHIN THE TEXT EDITOR
|
||||
var start = $event.srcElement.selectionStart;
|
||||
var end = $event.srcElement.selectionEnd;
|
||||
// set textarea value to: text before caret + tab + text after caret
|
||||
$event.target.value = $event.target.value.substring(0, start)+"\t"+$event.target.value.substring(end);
|
||||
// put caret at right position again
|
||||
$event.srcElement.selectionStart =
|
||||
$event.srcElement.selectionEnd = start + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
div.container{
|
||||
margin-top: 30px;
|
||||
margin-bottom: 30px;
|
||||
margin-right: 30px;
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
height: auto;
|
||||
max-height: 180px;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.margined {
|
||||
margin-left: 5px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.dropdown-menu::-webkit-scrollbar {
|
||||
-webkit-appearance: none;
|
||||
width: 4px;
|
||||
}
|
||||
.dropdown-menu::-webkit-scrollbar-thumb {
|
||||
border-radius: 3px;
|
||||
background-color: lightgray;
|
||||
-webkit-box-shadow: 0 0 1px rgba(255,255,255,.75);
|
||||
}
|
||||
/*
|
||||
.dropdown-list-elem {
|
||||
margin-left: 5px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
tr:hover {
|
||||
background-color: #56615D;
|
||||
}
|
||||
td:hover {
|
||||
background-color: #56615D;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
tr.hover:hover > * {
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
|
||||
|
||||
.red{
|
||||
color:red;
|
||||
}
|
||||
|
||||
.noborder{
|
||||
border-style: hidden;
|
||||
}
|
||||
|
||||
.invisible {
|
||||
display:none;
|
||||
}
|
||||
|
||||
.visible {
|
||||
display:block;
|
||||
}
|
||||
|
||||
|
||||
.dmp-btn-width{
|
||||
min-width: 140px;
|
||||
max-width: 180px;
|
||||
}
|
|
@ -0,0 +1,175 @@
|
|||
<!-- This is the dataset viewer -->
|
||||
<div [ngClass]="{true:'visible', false:'invisible'}[viewingComponent==1]">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
|
||||
<div class="">
|
||||
|
||||
<div class="panel panel-default panel-table">
|
||||
<div class="panel-heading">
|
||||
<div class="row">
|
||||
<div class="col col-xs-6">
|
||||
<h3 class="panel-title">Manage Datasets</h3>
|
||||
</div>
|
||||
<div class="col col-xs-6 text-right">
|
||||
<button type="button" class="btn btn-sm btn-primary btn-create" data-toggle="modal" data-target="#newdataset-modal-container">Create New</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<table class="table table-striped" [mfData]="data | dataFilter : filterQuery" #mf="mfDataTable" [mfRowsOnPage]="rowsOnPage" [(mfSortBy)]="sortBy" [(mfSortOrder)]="sortOrder">
|
||||
<!--<table class="table table-striped" [mfData]="data" #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>DMP</th>
|
||||
<th><mfDefaultSorter by="uri">Uri</mfDefaultSorter></th>
|
||||
<th>Properties</th>
|
||||
<th>Profile</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let dataset of mf.data" class="hover">
|
||||
<td [ngClass]="{true:'visible', false:'invisible'}[showIDs]">{{dataset.id}}</td>
|
||||
<td><input class="noborder" type="text" [(ngModel)]="dataset.label" (focusin)="onFocusIn($event)" (ngModelChange)="onValueChanged($event)" (focusout)="onFocusOutLabel($event)"></td>
|
||||
<td>
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-primary dropdown-toggle dmp-btn-width" type="button" data-toggle="dropdown">{{dataset.dmp.label}}
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" >
|
||||
<li class="margined" *ngFor="let idLabel of dmpsIDLabels" (click)="assignDMPToDataset($event, idLabel.id)"><a style="cursor:pointer;">{{idLabel.label}}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
<td><input class="noborder" type="text" [(ngModel)]="dataset.uri" (focusin)="onFocusIn($event)" (ngModelChange)="onValueChanged($event)" (focusout)="onFocusOutURI($event)"></td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-default" data-toggle="modal" data-target="#edit-properties-modal-container" (click)="onShowingPropertiesModal($event)">
|
||||
<span class="glyphicon glyphicon-pencil"></span>
|
||||
</button>
|
||||
</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-default" (click)="gotoProfileEditor($event, dataset.profile?.id)">
|
||||
<span [ngClass]="{true:'glyphicon glyphicon-plus', false:'glyphicon glyphicon-pencil'}[dataset?.profile?.id==null]"></span>
|
||||
</button>
|
||||
</td>
|
||||
<td style='float: left;'>
|
||||
|
||||
<button class="btn btn-default" data-toggle="modal" data-target="#confirmation-modal" (click)="setClickedDatasetID($event)">
|
||||
<span class="glyphicon glyphicon-trash red"></span>
|
||||
</button>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="7">
|
||||
<mfBootstrapPaginator [rowsOnPageSet]="[10,20,40]"></mfBootstrapPaginator>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<new-dataset (idSender)="notifyNewDatasetID($event)"></new-dataset>
|
||||
<properties-editor [datasetID]=clickedDatasetID></properties-editor>
|
||||
<confirmation [confirmationTitle]="'Caution'" [confirmationDescr]="'This action will delete the dataset. Are you sure you want to delete this dataset ? This is not revertable !'" (responseSender)="applyConfirmation($event)"></confirmation>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<!-- END oF DatasetViewer -->
|
||||
|
||||
<!-- Profile Editor -->
|
||||
<div [ngClass]="{true:'visible', false:'invisible'}[viewingComponent==2]">
|
||||
<div class="panel panel-default margin10">
|
||||
<div class="panel-heading">
|
||||
<div class="row">
|
||||
<div class="col col-xs-6">
|
||||
<h3 class="panel-title">Editing profile: {{profile?.label}}</h3>
|
||||
</div>
|
||||
<div class="col col-xs-6 text-right">
|
||||
<button type="button" class="btn btn-sm btn-primary btn-create" (click)="goToMain()" > <span class="glyphicon glyphicon-arrow-left"></span> Go back</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
|
||||
<ul class="nav nav-tabs content-tabs" id="maincontent" role="tablist">
|
||||
<li class="active"><a href="#profile" role="tab" data-toggle="tab">Profile</a></li>
|
||||
<li class=""><a href="#viewstyle" role="tab" data-toggle="tab">Profile's viewstyle</a></li>
|
||||
<li class=""><a href="#ruleset" role="tab" data-toggle="tab">Profile's ruleset</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content">
|
||||
|
||||
<div class="tab-pane fade active in" id="profile">
|
||||
<br />
|
||||
<div class="custom-table">
|
||||
<input name="profile-label" type="text" placeholder="Enter profile label" [ngModel]="profile?.label" (ngModelChange)="profile.label=$event" (focusin)="onFocusIn($event)" (ngModelChange)="onValueChanged($event)" (focusout)="onFocusOutProfileWin($event)" (keydown)="preventDefaults($event)">
|
||||
<label for="profile-label">Label</label>
|
||||
</div>
|
||||
<br />
|
||||
<div class="custom-table">
|
||||
<textarea class="form-control custom" rows="10" cols="65" name="profile-definition" [ngModel]="profile?.definition" (ngModelChange)="profile.definition=$event" (focusin)="onFocusIn($event)" (ngModelChange)="onValueChanged($event)" (focusout)="onFocusOutProfileWin($event)" (keydown)="preventDefaults($event)" placeholder="Enter profile definition"></textarea>
|
||||
<label for="profile-definition">Definition</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="viewstyle">
|
||||
<br />
|
||||
<div class="custom-table">
|
||||
<input name="viewstyle-label" type="text" placeholder="Enter viewstyle label" [ngModel]="profile?.viewstyle?.label" (ngModelChange)="profile.viewstyle.label=$event" (focusin)="onFocusIn($event)" (ngModelChange)="onValueChanged($event)" (focusout)="onFocusOutProfileWin($event)" (keydown)="preventDefaults($event)">
|
||||
<label for="viewstyle-label">Label</label>
|
||||
</div>
|
||||
<br />
|
||||
<div class="custom-table">
|
||||
<textarea class="form-control custom" rows="10" cols="65" name="viewstyle-definition" [ngModel]="profile?.viewstyle?.definition" (ngModelChange)="profile.viewstyle.definition=$event" (focusin)="onFocusIn($event)" (ngModelChange)="onValueChanged($event)" (focusout)="onFocusOutProfileWin($event)" (keydown)="preventDefaults($event)"></textarea>
|
||||
<label for="viewstyle-definition">Definition</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="ruleset">
|
||||
<br />
|
||||
<div class="custom-table">
|
||||
<input name="ruleset-label" type="text" placeholder="Enter ruleset label" [ngModel]="profile?.ruleset?.label" (ngModelChange)="profile.ruleset.label=$event" (focusin)="onFocusIn($event)" (ngModelChange)="onValueChanged($event)" (focusout)="onFocusOutProfileWin($event)" (keydown)="preventDefaults($event)">
|
||||
<label for="ruleset-label">Label</label>
|
||||
</div>
|
||||
<br />
|
||||
<div class="custom-table">
|
||||
<textarea class="form-control custom" rows="10" cols="65" name="ruleset-definition" [ngModel]="profile?.ruleset?.definition" (ngModelChange)="profile.ruleset.definition=$event" (focusin)="onFocusIn($event)" (ngModelChange)="onValueChanged($event)" (focusout)="onFocusOutProfileWin($event)" (keydown)="preventDefaults($event)"></textarea>
|
||||
<label for="ruleset-definition">Definition</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- End of Profile Editor -->
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { DatasetsViewerComponent } from './datasets-viewer.component';
|
||||
|
||||
describe('DatasetsViewerComponent', () => {
|
||||
let component: DatasetsViewerComponent;
|
||||
let fixture: ComponentFixture<DatasetsViewerComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ DatasetsViewerComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(DatasetsViewerComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,368 @@
|
|||
import { Component, Input, OnInit, AfterViewInit, ElementRef} from '@angular/core';
|
||||
import { DialogService } from "ng2-bootstrap-modal";
|
||||
import { Router } from '@angular/router';
|
||||
import { DatasetsServiceService } from '../services/datasets-service.service';
|
||||
import { DatasetProfileService } from '../services/dataset-profile.service';
|
||||
import { DmpsServiceService } from '../services/dmps-service.service';
|
||||
|
||||
import '../../assets/custom.js';
|
||||
declare function simple_notifier(type: string, title: string, message:string): any;
|
||||
|
||||
import {Headers, Http, Response} from '@angular/http';
|
||||
import {Observable} from 'rxjs/Observable';
|
||||
import * as jQuery from 'jquery';
|
||||
|
||||
@Component({
|
||||
selector: 'app-datasets-viewer',
|
||||
templateUrl: './datasets-viewer.component.html',
|
||||
styleUrls: ['./datasets-viewer.component.css']
|
||||
})
|
||||
export class DatasetsViewerComponent implements OnInit, AfterViewInit {
|
||||
|
||||
//This is the table data
|
||||
public data: any[] = new Array();
|
||||
public filterQuery = "";
|
||||
public rowsOnPage = 10;
|
||||
public sortBy = "email";
|
||||
public sortOrder = "asc";
|
||||
|
||||
//this is for viewing or not ids
|
||||
private showIDs: boolean = false;
|
||||
|
||||
//this is for switching between components
|
||||
private viewingComponent: number = 1;
|
||||
|
||||
public dmpsIDLabels : any = null;
|
||||
|
||||
//for update sensing...
|
||||
private haveChanges : boolean = false;
|
||||
|
||||
//for popups
|
||||
private clickedDatasetID: string;
|
||||
|
||||
//this is the profile under edit
|
||||
private profile : any;
|
||||
|
||||
|
||||
constructor(
|
||||
private el: ElementRef,
|
||||
private datasetsService : DatasetsServiceService,
|
||||
private datasetProfileService: DatasetProfileService,
|
||||
private http : Http,
|
||||
private dmpsService: DmpsServiceService,
|
||||
private dialogService:DialogService,
|
||||
private router: Router
|
||||
) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
ngOnInit() : void {
|
||||
//this.getDatasetIDs();
|
||||
this.getTabularDatasets(false);
|
||||
this.dmpsIDLabels = this.dmpsService.getDmpIdsLabels().subscribe((data)=> {this.dmpsIDLabels = data;} );
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
|
||||
}
|
||||
|
||||
onFocusIn($event){
|
||||
this.nullSafeProfile();
|
||||
this.haveChanges = false;
|
||||
}
|
||||
|
||||
onValueChanged($event){
|
||||
this.nullSafeProfile();
|
||||
this.haveChanges = true;
|
||||
}
|
||||
|
||||
onFocusOutLabel($event){
|
||||
if(this.haveChanges){
|
||||
let datasetID = $event.srcElement.parentElement.parentElement.children[0].textContent;
|
||||
console.log("Updating the value of label to: "+$event.target.value+" on row with id: "+datasetID);
|
||||
this.datasetsService.getDatasetById(datasetID).subscribe( (data) => {
|
||||
data.label = $event.target.value;
|
||||
this.datasetsService.setDataset(data).subscribe( (data) => {
|
||||
//console.log(data);
|
||||
});
|
||||
simple_notifier("success",null,"Updated value of label to '"+data.label+"'");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onFocusOutURI($event){
|
||||
if(this.haveChanges){
|
||||
let datasetID = $event.srcElement.parentElement.parentElement.children[0].textContent;
|
||||
console.log("Updating the value of uri to: "+$event.target.value+" on row with id: "+datasetID);
|
||||
this.datasetsService.getDatasetById(datasetID).subscribe(
|
||||
(data) => {
|
||||
data.uri = $event.target.value;
|
||||
this.datasetsService.setDataset(data).subscribe( (data) => {
|
||||
//console.log(data);
|
||||
}
|
||||
);
|
||||
simple_notifier("success",null,"Updated value of Uri to '"+data.uri+"'");
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
onFocusOutProfileWin($event, value:string) {
|
||||
this.nullSafeProfile();
|
||||
if(this.haveChanges){
|
||||
console.log("Saving profile: "+JSON.stringify(this.profile));
|
||||
//save back
|
||||
if(this.profile.id == null){ //if profile is new
|
||||
//create profile and a) assign it on data[] and on current profile b) assign it to dataset
|
||||
this.datasetProfileService.setDatasetProfile(this.profile).subscribe((resp) => {
|
||||
|
||||
/*
|
||||
console.log("SERVICE RESPONSE: ");
|
||||
console.log(resp);
|
||||
console.log(resp.json());
|
||||
this.datasetsService.getDatasetById(this.clickedDatasetID).subscribe( (dataset) => {
|
||||
|
||||
if(dataset.profile != null){
|
||||
this.profile.id = dataset.profile.id;
|
||||
|
||||
}
|
||||
dataset.profile = this.profile;
|
||||
|
||||
console.log("SAVING DATASET: "+JSON.stringify(dataset));
|
||||
|
||||
this.datasetsService.setDataset(dataset).subscribe( (resp) => {
|
||||
|
||||
//console.log(resp);
|
||||
simple_notifier("success",null,"Updated profile element");
|
||||
});
|
||||
});
|
||||
*/
|
||||
simple_notifier("success",null,"Updated profile element");
|
||||
});
|
||||
}
|
||||
else{
|
||||
//this.getDatasetFromDataArray()
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
onFocusOutProfileWin($event, value:string){
|
||||
if(this.haveChanges){
|
||||
console.log("Saving profile: "+JSON.stringify(this.profile));
|
||||
//save back
|
||||
if(this.profile.id == null){ //if profile is new
|
||||
console.log("================CH 1 =======================");
|
||||
simple_notifier("info",null,"Dataset didn't have a profile. Created and associated a new one");
|
||||
//get the appropriate dataset, and add the new profile
|
||||
this.datasetsService.getDatasetById(this.clickedDatasetID).subscribe( (dataset) => {
|
||||
console.log("================CH 2 =======================");
|
||||
if(dataset.profile != null){
|
||||
this.profile.id = dataset.profile.id;
|
||||
console.log("================CH 3 =======================");
|
||||
}
|
||||
dataset.profile = this.profile;
|
||||
|
||||
console.log("SAVING DATASET: "+JSON.stringify(dataset));
|
||||
|
||||
this.datasetsService.setDataset(dataset).subscribe( (resp) => {
|
||||
console.log("================CH 4 =======================");
|
||||
//console.log(resp);
|
||||
simple_notifier("success",null,"Updated profile element");
|
||||
});
|
||||
});
|
||||
}
|
||||
else{
|
||||
console.log("================CH 5 =======================");
|
||||
this.datasetProfileService.setDatasetProfile(this.profile).subscribe((resp) => {
|
||||
console.log("================CH 6 =======================");
|
||||
console.log(resp.status);
|
||||
simple_notifier("success",null,"Updated profile element");
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
nullSafeProfile(){
|
||||
if(this.profile==null){
|
||||
console.log("BEFORE:");
|
||||
console.log(this.profile);
|
||||
this.profile = {'label':null, 'definition':null, 'viewstyle':{'label':null, 'definition':null}, 'ruleset':{'label':null, 'definition':null}};
|
||||
console.log("AFTER:");
|
||||
console.log(this.profile);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
preventDefaults($event){
|
||||
if($event.code == 'Tab') {
|
||||
$event.preventDefault();
|
||||
//AND NOW HACK THE TAB KEY WITHIN THE TEXT EDITOR
|
||||
var start = $event.srcElement.selectionStart;
|
||||
var end = $event.srcElement.selectionEnd;
|
||||
// set textarea value to: text before caret + tab + text after caret
|
||||
$event.target.value = $event.target.value.substring(0, start)+"\t"+$event.target.value.substring(end);
|
||||
// put caret at right position again
|
||||
$event.srcElement.selectionStart =
|
||||
$event.srcElement.selectionEnd = start + 1;
|
||||
}
|
||||
}
|
||||
|
||||
getTabularDatasets(notifyAlso){
|
||||
|
||||
this.datasetsService.fetchAllDatasets()
|
||||
.map((elems) => {
|
||||
let tmpData = new Array();
|
||||
for (let elem of elems) {
|
||||
let row = {
|
||||
"id": elem.id,
|
||||
"label":elem.label,
|
||||
"dmp": elem.dmp,
|
||||
"uri": elem.uri,
|
||||
"properties": elem.properties,
|
||||
"profile": elem.profile
|
||||
};
|
||||
tmpData.push(row);
|
||||
}
|
||||
return tmpData;
|
||||
}
|
||||
)
|
||||
.subscribe((data)=> {
|
||||
this.data = data;
|
||||
if(notifyAlso)
|
||||
simple_notifier("info",null,"Refreshed table");
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
onShowingPropertiesModal($event){
|
||||
var trElem = $event.target;
|
||||
while(trElem.nodeName != "TR")
|
||||
trElem = trElem.parentElement;
|
||||
this.clickedDatasetID = trElem.children[0].textContent;
|
||||
}
|
||||
|
||||
|
||||
gotoProfileEditor($event) {
|
||||
var trElem = $event.target;
|
||||
while(trElem.nodeName != "TR")
|
||||
trElem = trElem.parentElement;
|
||||
this.clickedDatasetID = trElem.children[0].textContent;
|
||||
|
||||
if(this.clickedDatasetID == null) console.log("Could not retrieve the id of the clicked dataset");
|
||||
|
||||
var dataset = this.getDatasetFromDataArray(this.clickedDatasetID);
|
||||
if(dataset != null){
|
||||
this.profile = dataset.profile;
|
||||
this.goToEditor();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getDatasetFromDataArray(datasetID){
|
||||
for(var dataRow of this.data){
|
||||
if(datasetID == dataRow.id)
|
||||
return dataRow;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
deleteDataset(dataset){
|
||||
this.datasetsService.deleteDataset(dataset).subscribe(
|
||||
resp =>{
|
||||
console.log(status);
|
||||
this.refreshTable(null);
|
||||
simple_notifier("success",null,"Dataset was deleted");
|
||||
},
|
||||
err => {
|
||||
simple_notifier("danger",null,"Dataset could not be deleted");
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
goToEditor(){
|
||||
this.viewingComponent = 2;
|
||||
}
|
||||
|
||||
goToMain(){
|
||||
this.viewingComponent = 1;
|
||||
}
|
||||
|
||||
|
||||
setDmpLabelValueOfDatasetID(datasetID, newVal){
|
||||
for(var i=0;i<this.data.length;i++){
|
||||
var row = this.data[i];
|
||||
if(row.id == datasetID){
|
||||
if(row["dmp"] != null && row["dmp"].label != null)
|
||||
row["dmp"].label = newVal;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setClickedDatasetID($event){
|
||||
var trElem = $event.srcElement;
|
||||
while(trElem.nodeName != "TR")
|
||||
trElem = trElem.parentElement;
|
||||
this.clickedDatasetID = trElem.children[0].textContent;
|
||||
}
|
||||
|
||||
|
||||
applyConfirmation($event){
|
||||
if($event==true){
|
||||
console.log("will delete dataset: "+ this.clickedDatasetID);
|
||||
//method 1
|
||||
var dataset = {};
|
||||
dataset["id"] = this.clickedDatasetID;
|
||||
dataset["label"] = " ";
|
||||
this.deleteDataset(dataset);
|
||||
}
|
||||
}
|
||||
|
||||
notifyNewDatasetID($event){
|
||||
this.filterQuery = $event;
|
||||
this.refreshTable($event);
|
||||
}
|
||||
|
||||
|
||||
refreshTable($event){
|
||||
this.getTabularDatasets(true);
|
||||
}
|
||||
|
||||
|
||||
assignDMPToDataset($event, dmpID){
|
||||
var trElem = $event.srcElement;
|
||||
while(trElem.nodeName != "TR")
|
||||
trElem = trElem.parentElement;
|
||||
var datasetID = trElem.children[0].textContent;
|
||||
|
||||
this.datasetsService.assignDMPToDataset(datasetID, dmpID).subscribe(
|
||||
(resp) => {
|
||||
this.setDmpLabelValueOfDatasetID(datasetID, $event.target.text);
|
||||
simple_notifier("success",null,"Assigned the dmp on dataset");
|
||||
},
|
||||
err => {
|
||||
simple_notifier("danger",null,"Could not assign the dmp on dataset");
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
.nomargin{
|
||||
margin-top: 0px;
|
||||
margin-bottom: 0px;
|
||||
margin-left: 0px;
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
.width-range {
|
||||
max-width: 500px;
|
||||
min-width: 300px;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr align="center">
|
||||
<div class="g-signin2" id="googleBtn"></div>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { GooggleSignInComponent } from './googgle-sign-in.component';
|
||||
|
||||
describe('GooggleSignInComponent', () => {
|
||||
let component: GooggleSignInComponent;
|
||||
let fixture: ComponentFixture<GooggleSignInComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ GooggleSignInComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(GooggleSignInComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,88 @@
|
|||
import { Component, OnInit, ElementRef, AfterViewInit, VERSION } from '@angular/core';
|
||||
import { TokenService, TokenProvider } from '../../services/login/token.service';
|
||||
import {Router} from '@angular/router';
|
||||
|
||||
declare const gapi: any;
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'googgle-sign-in',
|
||||
templateUrl: './googgle-sign-in.component.html',
|
||||
styleUrls: ['./googgle-sign-in.component.css']
|
||||
})
|
||||
export class GooggleSignInComponent implements OnInit, AfterViewInit {
|
||||
|
||||
token:any;
|
||||
|
||||
constructor(private element: ElementRef, private tokenService : TokenService, private router : Router) {
|
||||
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
private clientId:string = '1010962018903-glegmqudqtl1lub0150vacopbu06lgsg.apps.googleusercontent.com';
|
||||
|
||||
private scope = [
|
||||
'profile',
|
||||
'email'
|
||||
//,
|
||||
//'https://www.googleapis.com/auth/plus.me',
|
||||
//'https://www.googleapis.com/auth/contacts.readonly',
|
||||
//'https://www.googleapis.com/auth/admin.directory.user.readonly'
|
||||
].join(' ');
|
||||
|
||||
public auth2: any;
|
||||
|
||||
public googleInit() {
|
||||
|
||||
gapi.load('auth2', () => {
|
||||
this.auth2 = gapi.auth2.init({
|
||||
client_id: this.clientId,
|
||||
cookiepolicy: 'single_host_origin',
|
||||
scope: this.scope
|
||||
});
|
||||
var buttonElement = this.element.nativeElement.querySelector('#googleBtn');
|
||||
this.attachSignin(buttonElement);
|
||||
});
|
||||
}
|
||||
|
||||
public attachSignin(element) {
|
||||
this.auth2.attachClickHandler(element, {},
|
||||
(googleUser) => {
|
||||
this.token = googleUser.getAuthResponse().id_token;
|
||||
|
||||
let profile = googleUser.getBasicProfile();
|
||||
|
||||
this.tokenService.setLoggedIn(true);
|
||||
this.tokenService.setToken(this.token);
|
||||
this.tokenService.setProvider(TokenProvider.google);
|
||||
this.tokenService.setUsername(profile.getName());
|
||||
this.tokenService.setEmail(profile.getEmail());
|
||||
|
||||
window.location.reload();
|
||||
|
||||
}, function (error) {
|
||||
console.log(JSON.stringify(error, undefined, 2));
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
ngAfterViewInit() {
|
||||
this.googleInit();
|
||||
}
|
||||
|
||||
/*
|
||||
signOut() {
|
||||
var auth2 = gapi.auth2.getAuthInstance();
|
||||
auth2.signOut().then(function () {
|
||||
console.log('User signed out.');
|
||||
});
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
.form-signin
|
||||
{
|
||||
max-width: 330px;
|
||||
padding: 15px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.form-signin .form-signin-heading, .form-signin .checkbox
|
||||
{
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.form-signin .checkbox
|
||||
{
|
||||
font-weight: normal;
|
||||
}
|
||||
.form-signin .form-control
|
||||
{
|
||||
position: relative;
|
||||
font-size: 16px;
|
||||
height: auto;
|
||||
padding: 10px;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.form-signin .form-control:focus
|
||||
{
|
||||
z-index: 2;
|
||||
}
|
||||
.form-signin input[type="text"]
|
||||
{
|
||||
margin-bottom: -1px;
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
.form-signin input[type="password"]
|
||||
{
|
||||
margin-bottom: 10px;
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
.account-wall
|
||||
{
|
||||
margin-top: 20px;
|
||||
padding: 40px 0px 20px 0px;
|
||||
background-color: #f7f7f7;
|
||||
-moz-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
|
||||
-webkit-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
|
||||
box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
.login-title
|
||||
{
|
||||
color: #555;
|
||||
font-size: 18px;
|
||||
font-weight: 400;
|
||||
display: block;
|
||||
}
|
||||
.profile-img
|
||||
{
|
||||
width: 96px;
|
||||
height: 96px;
|
||||
margin: 0 auto 10px;
|
||||
display: block;
|
||||
-moz-border-radius: 50%;
|
||||
-webkit-border-radius: 50%;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.need-help
|
||||
{
|
||||
margin-top: 10px;
|
||||
}
|
||||
.new-account
|
||||
{
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-sm-6 col-md-4 col-md-offset-4">
|
||||
<h1 class="text-center login-title"></h1>
|
||||
<div class="account-wall">
|
||||
<img class="profile-img" src="/assets/icons/user-icon.png">
|
||||
<form class="form-signin" [formGroup]="nativeLoginForm">
|
||||
<input type="text" class="form-control" [(ngModel)]="creds.username" formControlName="username" placeholder="Username or Email" required autofocus>
|
||||
<input type="password" class="form-control" [(ngModel)]="creds.password" formControlName="password" placeholder="Password" required>
|
||||
<button class="btn btn-lg btn-primary btn-block" type="submit" (click)="login()">
|
||||
Sign in
|
||||
</button>
|
||||
<label class="checkbox pull-left">
|
||||
<input type="checkbox" value="remember-me">
|
||||
Remember me
|
||||
</label>
|
||||
<a href="#" class="pull-right need-help">Need help? </a><span class="clearfix"></span>
|
||||
</form>
|
||||
|
||||
<p>Form value: {{ nativeLoginForm.value | json }}</p>
|
||||
|
||||
<a href="#" class="text-center new-account">Create an account </a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-sm-6 col-md-4 col-md-offset-4">
|
||||
<div class="account-wall">
|
||||
<h1 class="text-center login-title"></h1>
|
||||
<h4 class="text-center">Sign in with social</h4>
|
||||
<googgle-sign-in></googgle-sign-in>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { MainSignInComponent } from './main-sign-in.component';
|
||||
|
||||
describe('MainSignInComponent', () => {
|
||||
let component: MainSignInComponent;
|
||||
let fixture: ComponentFixture<MainSignInComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ MainSignInComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(MainSignInComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,66 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { NativeLoginService } from '../../services/login/native-login.service';
|
||||
import { TokenService, TokenProvider } from '../../services/login/token.service';
|
||||
import {Router} from '@angular/router';
|
||||
|
||||
import '../../../assets/custom.js';
|
||||
declare function simple_notifier(type: string, title: string, message:string): any;
|
||||
|
||||
@Component({
|
||||
selector: 'app-main-sign-in',
|
||||
templateUrl: './main-sign-in.component.html',
|
||||
styleUrls: ['./main-sign-in.component.css']
|
||||
})
|
||||
export class MainSignInComponent implements OnInit {
|
||||
|
||||
|
||||
nativeLoginForm : any;
|
||||
|
||||
creds : any = {"username":"","password":""};
|
||||
|
||||
|
||||
constructor( private fb: FormBuilder, private nativeLogin : NativeLoginService, private tokenService : TokenService, private router : Router) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
createProjectEditorForm(){
|
||||
|
||||
this.nativeLoginForm = this.fb.group({
|
||||
username: ['', Validators.required ],
|
||||
password: ['', Validators.required ]
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
ngOnInit() {
|
||||
this.createProjectEditorForm();
|
||||
}
|
||||
|
||||
|
||||
login(){
|
||||
//login using the credentials
|
||||
|
||||
this.nativeLogin.login(this.creds.username, this.creds.password).subscribe(
|
||||
response => {
|
||||
simple_notifier("success",null,"Successful login");
|
||||
|
||||
this.tokenService.setLoggedIn(true);
|
||||
this.tokenService.setToken(response['token']);
|
||||
this.tokenService.setProvider(TokenProvider.native);
|
||||
this.tokenService.setUsername(this.creds.username);
|
||||
this.tokenService.setEmail(response['email']);
|
||||
|
||||
window.location.reload();
|
||||
|
||||
},
|
||||
err => {
|
||||
simple_notifier("danger",null,"Failed to login");
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,172 @@
|
|||
|
||||
/* MY CUSTOM CSS */
|
||||
|
||||
.float-left{
|
||||
float: left;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
#3a679c
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/* SIDEBAR's CSS */
|
||||
.nav-side-menu {
|
||||
overflow: auto;
|
||||
font-family: verdana;
|
||||
font-size: 12px;
|
||||
font-weight: 200;
|
||||
background-color: #557DAA;
|
||||
position: inherit;
|
||||
top: 0px;
|
||||
width: 300px;
|
||||
height: 100%;
|
||||
color: #e1ffff;
|
||||
}
|
||||
.nav-side-menu .brand {
|
||||
background-color: #345881;
|
||||
line-height: 50px;
|
||||
display: block;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
}
|
||||
.nav-side-menu .toggle-btn {
|
||||
display: none;
|
||||
}
|
||||
.nav-side-menu ul,
|
||||
.nav-side-menu li {
|
||||
list-style: none;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
line-height: 35px;
|
||||
cursor: pointer;
|
||||
/*
|
||||
.collapsed{
|
||||
.arrow:before{
|
||||
font-family: FontAwesome;
|
||||
content: "\f053";
|
||||
display: inline-block;
|
||||
padding-left:10px;
|
||||
padding-right: 10px;
|
||||
vertical-align: middle;
|
||||
float:right;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
.nav-side-menu ul :not(collapsed) .arrow:before,
|
||||
.nav-side-menu li :not(collapsed) .arrow:before {
|
||||
font-family: FontAwesome;
|
||||
content: "\f078";
|
||||
display: inline-block;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
vertical-align: middle;
|
||||
float: right;
|
||||
}
|
||||
.nav-side-menu ul .active,
|
||||
.nav-side-menu li .active {
|
||||
border-left: 3px solid #d19b3d;
|
||||
background-color: #587AA1;
|
||||
}
|
||||
.nav-side-menu ul .sub-menu li.active,
|
||||
.nav-side-menu li .sub-menu li.active {
|
||||
color: #d19b3d;
|
||||
}
|
||||
.nav-side-menu ul .sub-menu li.active a,
|
||||
.nav-side-menu li .sub-menu li.active a {
|
||||
color: #d19b3d;
|
||||
}
|
||||
.nav-side-menu ul .sub-menu li,
|
||||
.nav-side-menu li .sub-menu li {
|
||||
background-color: #181c20;
|
||||
border: none;
|
||||
line-height: 28px;
|
||||
border-bottom: 1px solid #18375A;
|
||||
margin-left: 0px;
|
||||
}
|
||||
.nav-side-menu ul .sub-menu li:hover,
|
||||
.nav-side-menu li .sub-menu li:hover {
|
||||
background-color: #020203;
|
||||
}
|
||||
.nav-side-menu ul .sub-menu li:before,
|
||||
.nav-side-menu li .sub-menu li:before {
|
||||
font-family: FontAwesome;
|
||||
content: "\f105";
|
||||
display: inline-block;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.nav-side-menu li {
|
||||
padding-left: 0px;
|
||||
border-left: 3px solid #2e353d;
|
||||
border-bottom: 1px solid #23282e;
|
||||
}
|
||||
.nav-side-menu li a {
|
||||
text-decoration: none;
|
||||
color: #e1ffff;
|
||||
}
|
||||
.nav-side-menu li a i {
|
||||
padding-left: 10px;
|
||||
width: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
.nav-side-menu li:hover {
|
||||
border-left: 3px solid #d19b3d;
|
||||
background-color: #4f5b69;
|
||||
-webkit-transition: all 1s ease;
|
||||
-moz-transition: all 1s ease;
|
||||
-o-transition: all 1s ease;
|
||||
-ms-transition: all 1s ease;
|
||||
transition: all 1s ease;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
.nav-side-menu {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.nav-side-menu .toggle-btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 10px;
|
||||
z-index: 10 !important;
|
||||
padding: 3px;
|
||||
background-color: #ffffff;
|
||||
color: #000;
|
||||
width: 40px;
|
||||
text-align: center;
|
||||
}
|
||||
.brand {
|
||||
text-align: left !important;
|
||||
font-size: 22px;
|
||||
padding-left: 20px;
|
||||
line-height: 50px !important;
|
||||
}
|
||||
}
|
||||
@media (min-width: 767px) {
|
||||
.nav-side-menu .menu-list .menu-content {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
/*
|
||||
body {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
*/
|
||||
/* END OF SIDEBAR's CSS */
|
||||
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
<div class="float-left">
|
||||
<div class="nav-side-menu">
|
||||
<div class="brand">Quick Navigation</div>
|
||||
<i class="fa fa-bars fa-2x toggle-btn" data-toggle="collapse" data-target="#menu-content"></i>
|
||||
|
||||
<div class="menu-list">
|
||||
|
||||
<ul id="menu-content" class="menu-content collapse out">
|
||||
|
||||
<li data-toggle="collapse" data-target="#manage-datasets" class="collapsed">
|
||||
<a style="cursor:pointer"><i class="fa fa-file-text-o"></i> Manage Datasets <span class="arrow"></span></a>
|
||||
</li>
|
||||
<ul class="sub-menu collapse" id="manage-datasets">
|
||||
<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')" ><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="#data-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="data-repositories">
|
||||
<li>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-users" class="collapsed">
|
||||
<a style="cursor:pointer"><i class="fa fa-newspaper-o"></i> Users <span class="arrow"></span></a>
|
||||
</li>
|
||||
<ul class="sub-menu collapse" id="manage-users">
|
||||
<li [ngClass]="{true:'active'}[currentlySelected=='users']" (click)="setActive('users')" >User List</li>
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="float-left">
|
||||
|
||||
<router-outlet></router-outlet>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!--
|
||||
|
||||
<div class="nav-side-menu">
|
||||
<div class="brand">Quick Navigation</div>
|
||||
<i class="fa fa-bars fa-2x toggle-btn" data-toggle="collapse" data-target="#menu-content"></i>
|
||||
|
||||
<div class="menu-list">
|
||||
|
||||
<ul id="menu-content" class="menu-content collapse out">
|
||||
|
||||
<li data-toggle="collapse" data-target="#products" class="collapsed active">
|
||||
<a style="cursor:pointer"><i class="fa fa-gift fa-lg"></i> Manage Datasets <span class="arrow"></span></a>
|
||||
</li>
|
||||
<ul class="sub-menu collapse" id="products">
|
||||
<li class="active"><a style="cursor:pointer">Datasets</a></li>
|
||||
<li><a style="cursor:pointer">Dataset Profiles</a></li>
|
||||
<li><a style="cursor:pointer">Buttons</a></li>
|
||||
<li><a style="cursor:pointer">Tabs & Accordions</a></li>
|
||||
<li><a style="cursor:pointer">Typography</a></li>
|
||||
<li><a style="cursor:pointer">FontAwesome</a></li>
|
||||
<li><a style="cursor:pointer">Slider</a></li>
|
||||
<li><a style="cursor:pointer">Panels</a></li>
|
||||
<li><a style="cursor:pointer">Widgets</a></li>
|
||||
<li><a style="cursor:pointer">Bootstrap Model</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<li data-toggle="collapse" data-target="#service" class="collapsed">
|
||||
<a style="cursor:pointer"><i class="fa fa-globe fa-lg"></i> Services <span class="arrow"></span></a>
|
||||
</li>
|
||||
<ul class="sub-menu collapse" id="service">
|
||||
<li>New Service 1</li>
|
||||
<li>New Service 2</li>
|
||||
<li>New Service 3</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<li data-toggle="collapse" data-target="#new" class="collapsed">
|
||||
<a style="cursor:pointer"><i class="fa fa-car fa-lg"></i> New <span class="arrow"></span></a>
|
||||
</li>
|
||||
<ul class="sub-menu collapse" id="new">
|
||||
<li>New New 1</li>
|
||||
<li>New New 2</li>
|
||||
<li>New New 3</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<li>
|
||||
<a style="cursor:pointer">
|
||||
<i class="fa fa-user fa-lg"></i> Profile
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a style="cursor:pointer">
|
||||
<i class="fa fa-users fa-lg"></i> Users
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
-->
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { MainWindowComponent } from './main-window.component';
|
||||
|
||||
describe('MainWindowComponent', () => {
|
||||
let component: MainWindowComponent;
|
||||
let fixture: ComponentFixture<MainWindowComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ MainWindowComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(MainWindowComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,31 @@
|
|||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { TokenService } from '../services/login/token.service';
|
||||
|
||||
@Component({
|
||||
selector: 'main-window',
|
||||
templateUrl: './main-window.component.html',
|
||||
styleUrls: ['../../assets/simple-sidebar.css', './main-window.component.css']
|
||||
})
|
||||
export class MainWindowComponent implements OnInit {
|
||||
|
||||
constructor(public tokenService : TokenService) {
|
||||
|
||||
}
|
||||
|
||||
//@Input() loggedInAs;
|
||||
|
||||
showSidebar : boolean = true;
|
||||
|
||||
currentlySelected : string = "";
|
||||
|
||||
ngOnInit() {
|
||||
|
||||
}
|
||||
|
||||
setActive(val) {
|
||||
this.currentlySelected = val;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
.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;
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
|
||||
<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>
|
|
@ -0,0 +1,25 @@
|
|||
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();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,158 @@
|
|||
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);
|
||||
},
|
||||
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");
|
||||
console.log(response);
|
||||
},
|
||||
(err) => {
|
||||
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
refreshTable($event){
|
||||
this.getAllDmps(true);
|
||||
}
|
||||
|
||||
|
||||
@ViewChild(ContextMenuComponent) public basicMenu: ContextMenuComponent;
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
.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;
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
|
||||
<div class="editor-container container">
|
||||
|
||||
<div [ngClass]="{true:'visible', false:'invisible'}[tableVisible]">
|
||||
<table class="table table-striped" [mfData]="tableData | dmpProfileTableFilter : 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="definition">Definition</mfDefaultSorter></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="grayout-empty-table" *ngIf="!mf.data[0]" [contextMenu]="basicMenu" [contextMenuSubject]="dmpProfile"> <td colspan="3">No elements</td></tr>
|
||||
<tr *ngFor="let dmpProfile of mf.data" class="hover" [contextMenu]="basicMenu" [contextMenuSubject]="dmpProfile">
|
||||
<td [ngClass]="{true:'visible', false:'invisible'}[showIDs]">{{dmpProfile.id}}</td>
|
||||
<td>{{dmpProfile?.label}}</td>
|
||||
<td>{{dmpProfile?.definition}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<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]="dmpProfileEditorForm" novalidate style="display:block;">
|
||||
<div class="form-group" [ngClass]="{null:'invisible'}[editingDmpProfile?.id]">
|
||||
<label class="center-block">ID: {{editingProject?.id}}
|
||||
<input class="form-control invisible" formControlName="id" [ngModel]="editingDmpProfile?.id">
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="center-block">Label:
|
||||
<input class="form-control" formControlName="label" [ngModel]="editingDmpProfile?.label" (ngModelChange)="editingDmpProfile.label=$event">
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="center-block">Definition:
|
||||
<input class="form-control" formControlName="definition" [ngModel]="editingDmpProfile?.definition" (ngModelChange)="editingDmpProfile.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: {{ dmpProfileEditorForm.value | json }}</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<context-menu>
|
||||
<ng-template contextMenuItem [subMenu]="manage">
|
||||
<span></span>Manage DMP Profiles
|
||||
</ng-template>
|
||||
<context-menu #manage>
|
||||
<ng-template contextMenuItem (execute)="newDmpProfile($event?.item)">
|
||||
<span class="glyphicon glyphicon-plus"></span>Create DMP Profile
|
||||
</ng-template>
|
||||
<ng-template contextMenuItem (execute)="editDmpProfile($event?.item?.id)">
|
||||
<span class="glyphicon glyphicon-pencil"></span>Edit this DMP Profile
|
||||
</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>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { DmpProfileEditorComponent } from './dmp-profile-editor.component';
|
||||
|
||||
describe('DmpProfileEditorComponent', () => {
|
||||
let component: DmpProfileEditorComponent;
|
||||
let fixture: ComponentFixture<DmpProfileEditorComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ DmpProfileEditorComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(DmpProfileEditorComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,133 @@
|
|||
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||
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-profile-editor',
|
||||
templateUrl: './dmp-profile-editor.component.html',
|
||||
styleUrls: ['./dmp-profile-editor.component.css']
|
||||
})
|
||||
export class DmpProfileEditorComponent implements OnInit {
|
||||
|
||||
constructor(private dmpProfileService : DmpProfileService, private fb: FormBuilder) {
|
||||
|
||||
}
|
||||
|
||||
//whole dmp data model
|
||||
tableData : any[] = new Array();
|
||||
|
||||
//editor's data model
|
||||
editingDmpProfile: any = {};
|
||||
dmpProfileEditorForm : 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.getAllDmpProfiles(false);
|
||||
this.createDmpProfileEditorForm();
|
||||
}
|
||||
|
||||
createDmpProfileEditorForm(){
|
||||
this.dmpProfileEditorForm = this.fb.group({
|
||||
id: null,
|
||||
label: ['', Validators.required ],
|
||||
definition: ''
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
switchToTable(){
|
||||
this.tableVisible = true;
|
||||
this.editorVisible = false;
|
||||
}
|
||||
|
||||
switchToEditor(dmpProfileID){
|
||||
|
||||
this.tableVisible = false;
|
||||
this.editorVisible = true;
|
||||
if(dmpProfileID == null){
|
||||
this.editingDmpProfile = {id: null, label: "", definition: "" };
|
||||
}
|
||||
else{
|
||||
this.editingDmpProfile = this.tableData.filter((dmpProfile) => dmpProfile.id === dmpProfileID)[0];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
getAllDmpProfiles(showNotification : boolean){
|
||||
this.dmpProfileService.getAllDmpProfiles().subscribe( (data) => {
|
||||
this.tableData = data;
|
||||
if(showNotification)
|
||||
simple_notifier("info",null,"Refreshed the table");
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
editDmpProfile(dmpProfile){
|
||||
this.switchToEditor(dmpProfile);
|
||||
}
|
||||
|
||||
newDmpProfile(){
|
||||
this.switchToEditor(null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
save(mouseEvent){
|
||||
this.dmpProfileService.create(this.dmpProfileEditorForm.value).subscribe(
|
||||
response => {
|
||||
simple_notifier("success",null,"Saved DMP Profile");
|
||||
this.getAllDmpProfiles(false);
|
||||
},
|
||||
err => {
|
||||
simple_notifier("danger",null,"Could not save DMP Profile");
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
delete(dmpProfile){
|
||||
this.dmpProfileService.delete(dmpProfile).subscribe(
|
||||
(response) => {
|
||||
simple_notifier("success",null,"Deleted DMP Profile");
|
||||
},
|
||||
(err) => {
|
||||
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
refreshTable($event){
|
||||
this.getAllDmpProfiles(true);
|
||||
}
|
||||
|
||||
|
||||
@ViewChild(ContextMenuComponent) public basicMenu: ContextMenuComponent;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
.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;
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
|
||||
<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>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
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();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,135 @@
|
|||
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);
|
||||
},
|
||||
err => {
|
||||
simple_notifier("danger",null,"Could not save organisation");
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
delete(organisation){
|
||||
this.organisationService.delete(organisation).subscribe(
|
||||
(response) => {
|
||||
simple_notifier("success",null,"Deleted organisation");
|
||||
},
|
||||
(err) => {
|
||||
simple_notifier("danger",null,"Could not delete organisation");
|
||||
console.log(err);
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
refreshTable($event){
|
||||
this.getAllOrganisations(true);
|
||||
}
|
||||
|
||||
|
||||
@ViewChild(ContextMenuComponent) public basicMenu: ContextMenuComponent;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
.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;
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
|
||||
<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>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
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();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,137 @@
|
|||
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);
|
||||
},
|
||||
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");
|
||||
console.log(response);
|
||||
},
|
||||
(err) => {
|
||||
simple_notifier("danger",null,"Could not delete project");
|
||||
console.log(err);
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
refreshTable($event){
|
||||
this.getAllProjects(true);
|
||||
}
|
||||
|
||||
|
||||
@ViewChild(ContextMenuComponent) public basicMenu: ContextMenuComponent;
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
.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;
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
|
||||
<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>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
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();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,136 @@
|
|||
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");
|
||||
},
|
||||
err => {
|
||||
simple_notifier("danger",null,"Could not save registry");
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
delete(registry){
|
||||
this.registryService.delete(registry).subscribe(
|
||||
(response) => {
|
||||
simple_notifier("success",null,"Deleted registry");
|
||||
},
|
||||
(err) => {
|
||||
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
refreshTable($event){
|
||||
this.getAllRegistries(true);
|
||||
}
|
||||
|
||||
|
||||
@ViewChild(ContextMenuComponent) public basicMenu: ContextMenuComponent;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
.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;
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
|
||||
|
||||
<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>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
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();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,131 @@
|
|||
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);
|
||||
},
|
||||
err => {
|
||||
simple_notifier("danger",null,"Could not save service");
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
delete(service){
|
||||
this.serviceService.delete(service).subscribe(
|
||||
(response) => {
|
||||
simple_notifier("success",null,"Deleted service");
|
||||
},
|
||||
(err) => {
|
||||
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
refreshTable($event){
|
||||
this.getAllServices(true);
|
||||
}
|
||||
|
||||
|
||||
@ViewChild(ContextMenuComponent) public basicMenu: ContextMenuComponent;
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
import * as _ from "lodash";
|
||||
import {Pipe, PipeTransform} from "@angular/core";
|
||||
|
||||
@Pipe({
|
||||
name: "dataFilter"
|
||||
})
|
||||
export class DataFilterPipe implements PipeTransform {
|
||||
|
||||
transform(array: any[], query: string): any {
|
||||
|
||||
if (query) {
|
||||
return _.filter(array, row => {
|
||||
if (row.uri == null) row.uri = "";
|
||||
if (row.label == null) row.label = "";
|
||||
if (row.id == null) row.id = "";
|
||||
return (
|
||||
row.label.indexOf(query) > -1 ||
|
||||
//row.dmp.indexOf(query) > -1 ||
|
||||
row.id.indexOf(query) > -1 ||
|
||||
row.uri.indexOf(query) > -1
|
||||
)
|
||||
});
|
||||
}
|
||||
return array;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
import * as _ from "lodash";
|
||||
import {Pipe, PipeTransform} from "@angular/core";
|
||||
|
||||
@Pipe({
|
||||
name: "dmpProfileTableFilter"
|
||||
})
|
||||
export class DmpProfileTableFilterPipe implements PipeTransform {
|
||||
|
||||
transform(array: any[], query: string): any {
|
||||
|
||||
if (query) {
|
||||
|
||||
return _.filter(array, row => {
|
||||
if (row.definition == null) row.definition = "";
|
||||
if (row.label == null) row.label = "";
|
||||
if (row.id == null) row.id = "";
|
||||
return (
|
||||
row.definition.indexOf(query) > -1 ||
|
||||
row.label.indexOf(query) > -1 ||
|
||||
row.id.indexOf(query) > -1
|
||||
)
|
||||
});
|
||||
|
||||
}
|
||||
return array;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
import * as _ from "lodash";
|
||||
import {Pipe, PipeTransform} from "@angular/core";
|
||||
|
||||
@Pipe({
|
||||
name: "dmpTableFilter"
|
||||
})
|
||||
export class DmpTableFilterPipe implements PipeTransform {
|
||||
|
||||
transform(array: any[], query: string): any {
|
||||
|
||||
if (query) {
|
||||
|
||||
return _.filter(array, row => {
|
||||
if (row.uri == null) row.uri = "";
|
||||
if (row.label == null) row.label = "";
|
||||
if(row.project == null || row.project.label==null) row.project = {"label":""};
|
||||
if(row.profile == null || row.profile.label==null) row.profile = {"label":""};
|
||||
if (row.id == null) row.id = "";
|
||||
return (
|
||||
row.project.label.indexOf(query) > -1 ||
|
||||
row.label.indexOf(query) > -1 ||
|
||||
row.profile.label.indexOf(query) > -1 ||
|
||||
row.profileData.indexOf(query) > -1 ||
|
||||
//row.version == query ||
|
||||
row.id.indexOf(query) > -1
|
||||
)
|
||||
});
|
||||
|
||||
}
|
||||
return array;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
import * as _ from "lodash";
|
||||
import {Pipe, PipeTransform} from "@angular/core";
|
||||
|
||||
@Pipe({
|
||||
name: "organisationTableFilter"
|
||||
})
|
||||
export class OrganisationTableFilterPipe implements PipeTransform {
|
||||
|
||||
transform(array: any[], query: string): any {
|
||||
|
||||
if (query) {
|
||||
|
||||
return _.filter(array, row => {
|
||||
if (row.uri == null) row.uri = "";
|
||||
if (row.label == null) row.label = "";
|
||||
if (row.id == null) row.id = "";
|
||||
return (
|
||||
|
||||
row.label.indexOf(query) > -1 ||
|
||||
|
||||
//row.version == query ||
|
||||
row.id.indexOf(query) > -1
|
||||
)
|
||||
});
|
||||
|
||||
}
|
||||
return array;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
import * as _ from "lodash";
|
||||
import {Pipe, PipeTransform} from "@angular/core";
|
||||
|
||||
@Pipe({
|
||||
name: "projectTableFilter"
|
||||
})
|
||||
export class ProjectTableFilterPipe implements PipeTransform {
|
||||
|
||||
transform(array: any[], query: string): any {
|
||||
|
||||
if (query) {
|
||||
|
||||
return _.filter(array, row => {
|
||||
if (row.uri == null) row.uri = "";
|
||||
if (row.label == null) row.label = "";
|
||||
if (row.id == null) row.id = "";
|
||||
return (
|
||||
|
||||
row.label.indexOf(query) > -1 ||
|
||||
|
||||
//row.version == query ||
|
||||
row.id.indexOf(query) > -1
|
||||
)
|
||||
});
|
||||
|
||||
}
|
||||
return array;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
import * as _ from "lodash";
|
||||
import {Pipe, PipeTransform} from "@angular/core";
|
||||
|
||||
@Pipe({
|
||||
name: "registryTableFilter"
|
||||
})
|
||||
export class RegistryTableFilterPipe implements PipeTransform {
|
||||
|
||||
transform(array: any[], query: string): any {
|
||||
|
||||
if (query) {
|
||||
|
||||
return _.filter(array, row => {
|
||||
if (row.uri == null) row.uri = "";
|
||||
if (row.label == null) row.label = "";
|
||||
if (row.id == null) row.id = "";
|
||||
return (
|
||||
|
||||
row.label.indexOf(query) > -1 ||
|
||||
|
||||
//row.version == query ||
|
||||
row.id.indexOf(query) > -1
|
||||
)
|
||||
});
|
||||
|
||||
}
|
||||
return array;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
import * as _ from "lodash";
|
||||
import {Pipe, PipeTransform} from "@angular/core";
|
||||
|
||||
@Pipe({
|
||||
name: "serviceTableFilter"
|
||||
})
|
||||
export class ServiceTableFilterPipe implements PipeTransform {
|
||||
|
||||
transform(array: any[], query: string): any {
|
||||
|
||||
if (query) {
|
||||
|
||||
return _.filter(array, row => {
|
||||
if (row.uri == null) row.uri = "";
|
||||
if (row.label == null) row.label = "";
|
||||
if (row.id == null) row.id = "";
|
||||
return (
|
||||
|
||||
row.label.indexOf(query) > -1 ||
|
||||
|
||||
//row.version == query ||
|
||||
row.id.indexOf(query) > -1
|
||||
)
|
||||
});
|
||||
|
||||
}
|
||||
return array;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
import { ModuleWithProviders } from '@angular/core';
|
||||
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 { MainWindowComponent } from './main-window/main-window.component';
|
||||
|
||||
|
||||
|
||||
// Route Configuration
|
||||
export const routes: Routes = [
|
||||
|
||||
{
|
||||
path: '',
|
||||
redirectTo: 'app-root',
|
||||
pathMatch: 'full'
|
||||
},
|
||||
{
|
||||
path: 'datasets',
|
||||
component: DatasetsViewerComponent
|
||||
},
|
||||
{
|
||||
path: 'datasets/profile',
|
||||
component: ProfileEditorComponent
|
||||
//,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: 'main',
|
||||
component: MainWindowComponent
|
||||
}
|
||||
|
||||
|
||||
];
|
||||
|
||||
|
||||
export const AppRouting: ModuleWithProviders = RouterModule.forRoot(routes);
|
|
@ -0,0 +1,32 @@
|
|||
import { Component, Input, OnInit, AfterViewChecked, ViewChild } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { TokenService, TokenProvider } from './login/token.service'
|
||||
import 'rxjs/Rx';
|
||||
import { Injectable } from '@angular/core';
|
||||
import {RestBase} from './rest-base';
|
||||
|
||||
@Injectable()
|
||||
export class DatasetProfileService implements OnInit {
|
||||
|
||||
constructor(public restBase: RestBase) {
|
||||
}
|
||||
|
||||
|
||||
ngOnInit(){
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
getDatasetProfileById(datasetProfileID){
|
||||
return this.restBase.get("datasetprofile/"+datasetProfileID)
|
||||
.map((response: Response) => response.json());
|
||||
}
|
||||
|
||||
setDatasetProfile(datasetProfile){
|
||||
return this.restBase.post("setDatasetProfile", datasetProfile);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
import { Component, Input, OnInit, AfterViewChecked, ViewChild } from '@angular/core';
|
||||
import { HttpClient,HttpParams } from '@angular/common/http';
|
||||
import { TokenService, TokenProvider } from './login/token.service'
|
||||
import 'rxjs/Rx';
|
||||
import { Injectable } from '@angular/core';
|
||||
import {RestBase} from './rest-base';
|
||||
|
||||
@Injectable()
|
||||
export class DatasetsServiceService implements OnInit {
|
||||
|
||||
constructor(public restBase: RestBase) {
|
||||
}
|
||||
|
||||
|
||||
ngOnInit(){
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
getDatasetById(datasetID){
|
||||
return this.restBase.get("dataset/"+datasetID);
|
||||
}
|
||||
|
||||
|
||||
fetchAllDatasets(){
|
||||
return this.restBase.get("getAllDatasets");
|
||||
}
|
||||
|
||||
|
||||
setDataset(fullDataset){
|
||||
return this.restBase.post("setDataset", fullDataset);
|
||||
}
|
||||
|
||||
|
||||
deleteDataset(dataset){
|
||||
return this.restBase.post("deleteDataset", dataset);
|
||||
}
|
||||
|
||||
assignDMPToDataset(datasetID, dmpID){
|
||||
return this.restBase.get("assignDMPToDataset" +"?datasetID="+datasetID+"&dmpID="+dmpID);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
import { Component, Input, OnInit, AfterViewChecked, ViewChild } from '@angular/core';
|
||||
import { HttpClient , HttpHeaders, HttpParams} from '@angular/common/http';
|
||||
import { TokenService, TokenProvider } from './login/token.service'
|
||||
import 'rxjs/Rx';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Toolbox } from '../services/toolbox';
|
||||
import {RestBase} from './rest-base';
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class DmpProfileService implements OnInit {
|
||||
|
||||
|
||||
constructor(public restBase: RestBase) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
ngOnInit(){
|
||||
|
||||
}
|
||||
|
||||
getDmpProfileIdsLabels() {
|
||||
return this.restBase.get("dmpprofile/listAllLabelIDs");
|
||||
}
|
||||
|
||||
|
||||
getDmpProfileIds(){
|
||||
return this.restBase.get("dmpprofiles");
|
||||
}
|
||||
|
||||
getAllDmpProfiles(){
|
||||
return this.restBase.get("dmpprofile/getAll");
|
||||
}
|
||||
|
||||
create(dmpProfile){
|
||||
return this.restBase.post("dmpprofile/create", dmpProfile);
|
||||
}
|
||||
|
||||
|
||||
delete(dmpprofileID){
|
||||
var dmpprofile = {"id": dmpprofileID};
|
||||
return this.restBase.post("dmpprofile/delete", dmpprofile);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
import { Component, Input, OnInit, AfterViewChecked, ViewChild } from '@angular/core';
|
||||
import { HttpClient , HttpHeaders, HttpParams} from '@angular/common/http';
|
||||
import { TokenService, TokenProvider } from './login/token.service'
|
||||
import 'rxjs/Rx';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Toolbox } from '../services/toolbox';
|
||||
import {RestBase} from './rest-base';
|
||||
|
||||
@Injectable()
|
||||
export class DmpsServiceService implements OnInit {
|
||||
|
||||
|
||||
constructor(public restBase: RestBase, private toolbox : Toolbox) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
ngOnInit(){
|
||||
|
||||
}
|
||||
|
||||
getDmpIdsLabels() {
|
||||
return this.restBase.get("dmp/listDMPLabelID");
|
||||
}
|
||||
|
||||
getDmpIds(){
|
||||
return this.restBase.get("dmps");
|
||||
}
|
||||
|
||||
getAllDmps(){
|
||||
return this.restBase.get("dmp/getAll");
|
||||
}
|
||||
|
||||
create(dmp){
|
||||
var cloned = this.toolbox.deepCopy(dmp);
|
||||
cloned.project = {"id": dmp.project};
|
||||
cloned.profile = {"id": dmp.profile};
|
||||
return this.restBase.post("dmp/create", cloned);
|
||||
}
|
||||
|
||||
|
||||
delete(dmpID){
|
||||
var dmp = {"id": dmpID};
|
||||
return this.restBase.post("dmp/delete", dmp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
import { Injectable, OnInit } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { TokenService, TokenProvider } from '../login/token.service'
|
||||
import { HttpClient , HttpHeaders, HttpParams} from '@angular/common/http';
|
||||
import {RestBase} from '../rest-base';
|
||||
|
||||
@Injectable()
|
||||
export class NativeLoginService implements OnInit {
|
||||
|
||||
|
||||
constructor(private restBase: RestBase) {
|
||||
}
|
||||
|
||||
ngOnInit(){
|
||||
|
||||
}
|
||||
|
||||
|
||||
login(username, password){
|
||||
var credentials = {"username": username, "password":password};
|
||||
return this.restBase.post("project/create", credentials);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
import { Injectable, } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import {LocalStorageService} from 'ngx-webstorage';
|
||||
import 'rxjs/add/operator/map';
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class TokenService {
|
||||
|
||||
|
||||
constructor (private storage : LocalStorageService) {
|
||||
|
||||
}
|
||||
|
||||
getProvider() : TokenProvider {
|
||||
return this.storage.retrieve('provider');
|
||||
}
|
||||
|
||||
setProvider(provider : TokenProvider){
|
||||
this.storage.store('provider',provider);
|
||||
}
|
||||
|
||||
getToken() : string{
|
||||
return this.storage.retrieve('token');
|
||||
}
|
||||
|
||||
setToken(token : string){
|
||||
this.storage.store('token',token);
|
||||
}
|
||||
|
||||
isLoggedIn(){
|
||||
return this.storage.retrieve('loggedIn');
|
||||
}
|
||||
|
||||
setLoggedIn(boolStatus){
|
||||
this.storage.store('loggedIn',boolStatus);
|
||||
}
|
||||
|
||||
getEmail(){
|
||||
return this.storage.retrieve('email');
|
||||
}
|
||||
|
||||
setEmail(email){
|
||||
this.storage.store('email',email);
|
||||
}
|
||||
|
||||
getUsername(){
|
||||
return this.storage.retrieve('username');
|
||||
}
|
||||
|
||||
setUsername(username){
|
||||
this.storage.store('username',username);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
export enum TokenProvider {
|
||||
native,
|
||||
google
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
import { Component, Input, OnInit, AfterViewChecked, ViewChild } from '@angular/core';
|
||||
import { HttpClient , HttpHeaders, HttpParams} from '@angular/common/http';
|
||||
import { TokenService, TokenProvider } from './login/token.service'
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Toolbox } from '../services/toolbox';
|
||||
import {RestBase} from './rest-base';
|
||||
import 'rxjs/Rx';
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class OrganisationService implements OnInit {
|
||||
|
||||
|
||||
constructor(public restBase: RestBase) {
|
||||
}
|
||||
|
||||
ngOnInit(){
|
||||
|
||||
}
|
||||
|
||||
getOrganisationIdsLabels() {
|
||||
return this.restBase.get("organisation/listAllLabelIDs");
|
||||
}
|
||||
|
||||
getOrganisationIds(){
|
||||
return this.restBase.get("organisations");
|
||||
}
|
||||
|
||||
getAllOrganisations(){
|
||||
return this.restBase.get("organisation/getAll");
|
||||
}
|
||||
|
||||
create(organisation){
|
||||
return this.restBase.post("organisation/create", organisation);
|
||||
}
|
||||
|
||||
|
||||
delete(organisationID){
|
||||
var organisation = {"id": organisationID};
|
||||
return this.restBase.post("organisation/delete", organisation);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
import { Component, Input, OnInit, AfterViewChecked, ViewChild } from '@angular/core';
|
||||
import { HttpClient , HttpHeaders, HttpParams} from '@angular/common/http';
|
||||
import { TokenService, TokenProvider } from './login/token.service'
|
||||
import { Toolbox } from '../services/toolbox';
|
||||
import 'rxjs/Rx';
|
||||
import { Injectable } from '@angular/core';
|
||||
import {RestBase} from './rest-base';
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class ProjectService implements OnInit {
|
||||
|
||||
|
||||
constructor(private restBase: RestBase) {
|
||||
}
|
||||
|
||||
|
||||
ngOnInit(){
|
||||
|
||||
}
|
||||
|
||||
getProjectIdsLabels() {
|
||||
return this.restBase.get("project/listAllLabelIDs");
|
||||
}
|
||||
|
||||
getProjectIds(){
|
||||
return this.restBase.get("projects");
|
||||
}
|
||||
|
||||
getAllProjects(){
|
||||
return this.restBase.get("project/getAll");
|
||||
}
|
||||
|
||||
create(project){
|
||||
return this.restBase.post("project/create", project);
|
||||
}
|
||||
|
||||
delete(projectID){
|
||||
var project = {"id": projectID};
|
||||
return this.restBase.post("project/delete", project);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
import { Component, Input, OnInit, AfterViewChecked, ViewChild } from '@angular/core';
|
||||
import { HttpClient , HttpHeaders, HttpParams} from '@angular/common/http';
|
||||
import { TokenService, TokenProvider } from './login/token.service'
|
||||
import 'rxjs/Rx';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Toolbox } from '../services/toolbox';
|
||||
import {RestBase} from './rest-base';
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class RegistryService implements OnInit {
|
||||
|
||||
|
||||
constructor(public restBase: RestBase) {
|
||||
}
|
||||
|
||||
|
||||
ngOnInit(){
|
||||
|
||||
}
|
||||
|
||||
|
||||
getRegistryIdsLabels() {
|
||||
return this.restBase.get("registry/listAllLabelIDs");
|
||||
}
|
||||
|
||||
getRegistryIds(){
|
||||
return this.restBase.get("registries");
|
||||
}
|
||||
|
||||
getAllRegistries(){
|
||||
return this.restBase.get("registry/getAll");
|
||||
}
|
||||
|
||||
create(registry){
|
||||
return this.restBase.post("registry/create", registry);
|
||||
}
|
||||
|
||||
delete(registryID){
|
||||
var registry = {"id": registryID};
|
||||
return this.restBase.post("registry/delete", registry);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
import { HttpClient , HttpHeaders, HttpParams } from '@angular/common/http';
|
||||
import { TokenService, TokenProvider } from './login/token.service'
|
||||
import 'rxjs/Rx';
|
||||
|
||||
|
||||
declare var X2JS: any;
|
||||
|
||||
export class RestBase {
|
||||
|
||||
xml2jsonOBJ: any;
|
||||
|
||||
static get parameters() { return [HttpClient, TokenService] }
|
||||
|
||||
constructor(public http : HttpClient, public tokenService : TokenService) {
|
||||
this.xml2jsonOBJ = new X2JS();
|
||||
}
|
||||
|
||||
protocol: string = "http";
|
||||
hostname: string = "localhost";//"dl010.madgik.di.uoa.gr";//
|
||||
port: number = 7070;//8080;//
|
||||
webappname: string = "dmp-backend";//"dmp-backend-new";//
|
||||
restpath: string = "rest";
|
||||
|
||||
|
||||
restBasePath: string = this.protocol+"://"+this.hostname+":"+this.port+"/"+this.webappname+"/"+this.restpath+"/";
|
||||
|
||||
|
||||
|
||||
public get(path : string){
|
||||
var options = this.createOptions();
|
||||
return this.http.get<any>(this.restBasePath + path, options);
|
||||
}
|
||||
|
||||
|
||||
public post (path : string, data : any){
|
||||
var options = this.createOptions();
|
||||
return this.http.post<any>(this.restBasePath + path, JSON.stringify(data), options);
|
||||
}
|
||||
|
||||
|
||||
private createOptions(){
|
||||
var token = this.tokenService.getToken();
|
||||
var provider: TokenProvider = this.tokenService.getProvider();
|
||||
const params = new HttpParams();
|
||||
var headers;
|
||||
if(provider == TokenProvider.google)
|
||||
headers = new HttpHeaders().set('Content-Type', 'application/json').set("google-token", token);
|
||||
if(provider == TokenProvider.google)
|
||||
headers = new HttpHeaders().set('Content-Type', 'application/json').set("google-token", token);
|
||||
let options = { params: params, headers: headers };
|
||||
return options;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
import { Component, Input, OnInit, AfterViewChecked, ViewChild } from '@angular/core';
|
||||
import { HttpClient , HttpHeaders, HttpParams} from '@angular/common/http';
|
||||
import { TokenService, TokenProvider } from './login/token.service'
|
||||
import 'rxjs/Rx';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Toolbox } from '../services/toolbox';
|
||||
import {RestBase} from './rest-base';
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class ServiceService implements OnInit {
|
||||
|
||||
|
||||
constructor(public restBase: RestBase) {
|
||||
}
|
||||
|
||||
|
||||
ngOnInit(){
|
||||
|
||||
}
|
||||
|
||||
getServiceIdsLabels() {
|
||||
return this.restBase.get("service/listAllLabelIDs");
|
||||
}
|
||||
|
||||
getServiceIds(){
|
||||
return this.restBase.get("services");
|
||||
}
|
||||
|
||||
getAllServices(){
|
||||
return this.restBase.get("service/getAll");
|
||||
}
|
||||
|
||||
create(service){
|
||||
return this.restBase.post("service/create", service);
|
||||
}
|
||||
|
||||
delete(serviceID){
|
||||
var service = {"id": serviceID};
|
||||
return this.restBase.post("service/delete", service);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
import { Injectable, } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import {LocalStorageService} from 'ngx-webstorage';
|
||||
import 'rxjs/add/operator/map';
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class TokenService {
|
||||
|
||||
|
||||
constructor (private storage : LocalStorageService) {
|
||||
|
||||
}
|
||||
|
||||
getProvider(){
|
||||
return this.storage.retrieve('provider');
|
||||
}
|
||||
|
||||
setProvider(provider : TokenProvider){
|
||||
this.storage.store('provider',provider);
|
||||
}
|
||||
|
||||
getToken(){
|
||||
return this.storage.retrieve('token');
|
||||
}
|
||||
|
||||
setToken(token){
|
||||
this.storage.store('token',token);
|
||||
}
|
||||
|
||||
isLoggedIn(){
|
||||
return this.storage.retrieve('loggedIn');
|
||||
}
|
||||
|
||||
setLoggedIn(boolStatus){
|
||||
this.storage.store('loggedIn',boolStatus);
|
||||
}
|
||||
|
||||
getEmail(){
|
||||
return this.storage.retrieve('email');
|
||||
}
|
||||
|
||||
setEmail(email){
|
||||
this.storage.store('email',email);
|
||||
}
|
||||
|
||||
getUsername(){
|
||||
return this.storage.retrieve('username');
|
||||
}
|
||||
|
||||
setUsername(username){
|
||||
this.storage.store('username',username);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
export enum TokenProvider {
|
||||
native,
|
||||
google
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
|
||||
declare var X2JS: any;
|
||||
|
||||
export class Toolbox {
|
||||
|
||||
xml2jsonOBJ: any;
|
||||
|
||||
constructor() {
|
||||
this.xml2jsonOBJ = new X2JS();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
deepCopy(obj) {
|
||||
var copy;
|
||||
|
||||
// Handle the 3 simple types, and null or undefined
|
||||
if (null == obj || "object" != typeof obj) return obj;
|
||||
|
||||
// Handle Date
|
||||
if (obj instanceof Date) {
|
||||
copy = new Date();
|
||||
copy.setTime(obj.getTime());
|
||||
return copy;
|
||||
}
|
||||
|
||||
// Handle Array
|
||||
if (obj instanceof Array) {
|
||||
copy = [];
|
||||
for (var i = 0, len = obj.length; i < len; i++) {
|
||||
copy[i] = this.deepCopy(obj[i]);
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
// Handle Object
|
||||
if (obj instanceof Object) {
|
||||
copy = {};
|
||||
for (var attr in obj) {
|
||||
if (obj.hasOwnProperty(attr)) copy[attr] = this.deepCopy(obj[attr]);
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
throw new Error("Unable to copy obj! Its type isn't supported.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,38 @@
|
|||
|
||||
var sign_out_google = (function() {
|
||||
var auth2 = gapi.auth2.getAuthInstance();
|
||||
auth2.signOut().then(function () {
|
||||
console.log('User signed out from google.');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
var simple_notifier = (function(type, title, message) {
|
||||
return notify(type, title, message, null, null, null, null, null, null, null, null, null, null);
|
||||
});
|
||||
|
||||
|
||||
|
||||
function notify(type, title, message, delay, icon, url, target, allow_dismiss, offset_x, offset_y, animate_enter, animate_exit, newest_on_top){
|
||||
|
||||
var options = {};
|
||||
if(icon!=null) options.icon = icon;
|
||||
if(title!=null) options.title = title;
|
||||
if(message!=null) options.message = message;
|
||||
if(url!=null) options.url = url;
|
||||
if(target!=null) options.target = target;
|
||||
|
||||
var settings = {};
|
||||
if(type!=null) settings.type = type;
|
||||
if(allow_dismiss!=null) settings.allow_dismiss = allow_dismiss;
|
||||
if(delay!=null) settings.delay = delay;
|
||||
//settings.delay = -1;
|
||||
|
||||
return $.notify(options,settings, delay);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
<svg width="2443" height="2500" viewBox="0 0 256 262" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid"><path d="M255.878 133.451c0-10.734-.871-18.567-2.756-26.69H130.55v48.448h71.947c-1.45 12.04-9.283 30.172-26.69 42.356l-.244 1.622 38.755 30.023 2.685.268c24.659-22.774 38.875-56.282 38.875-96.027" fill="#4285F4"/><path d="M130.55 261.1c35.248 0 64.839-11.605 86.453-31.622l-41.196-31.913c-11.024 7.688-25.82 13.055-45.257 13.055-34.523 0-63.824-22.773-74.269-54.25l-1.531.13-40.298 31.187-.527 1.465C35.393 231.798 79.49 261.1 130.55 261.1" fill="#34A853"/><path d="M56.281 156.37c-2.756-8.123-4.351-16.827-4.351-25.82 0-8.994 1.595-17.697 4.206-25.82l-.073-1.73L15.26 71.312l-1.335.635C5.077 89.644 0 109.517 0 130.55s5.077 40.905 13.925 58.602l42.356-32.782" fill="#FBBC05"/><path d="M130.55 50.479c24.514 0 41.05 10.589 50.479 19.438l36.844-35.974C195.245 12.91 165.798 0 130.55 0 79.49 0 35.393 29.301 13.925 71.947l42.211 32.783c10.59-31.477 39.891-54.251 74.414-54.251" fill="#EB4335"/></svg>
|
After Width: | Height: | Size: 1018 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="2500" height="857" viewBox="0.512 0.511 748.99 256.61"><g transform="translate(4636.413 -2865.209)"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="-11445.563" y1="603.918" x2="-11445.563" y2="465.768" gradientTransform="matrix(1.3509 0 0 -1.3509 10917.478 3681.026)"><stop offset="0" stop-color="#196eef"/><stop offset=".5" stop-color="#186dee"/><stop offset="1" stop-color="#1065e7"/></linearGradient><path d="M-4520.08 2990.41h32.21v45.24c-10.05 3.229-22.74 5-35.931 5-53.46 0-84.88-45.78-84.88-90.49 0-43.851 28.42-74.61 68.07-74.61 25.09 0 39.689 8.5 52.75 20.34v14.76l24.49-24.49c-15.49-10.48-37.92-20.44-69.98-20.44-70.38 0-102.55 50.351-102.55 91.73 0 58.899 42.9 94.38 96.811 94.38 26.14 0 49.35-3.99 76.16-11.45v-46.74c0-2.39 1.05-4.03 2.62-5.47l8.46-8.46h-57.45l-10.78 10.7z" fill="url(#a)"/><linearGradient id="b" gradientUnits="userSpaceOnUse" x1="-11323.519" y1="556.948" x2="-11323.519" y2="467.618" gradientTransform="matrix(1.3509 0 0 -1.3509 10917.478 3681.026)"><stop offset="0" stop-color="#de5744"/><stop offset=".5" stop-color="#db4632"/><stop offset="1" stop-color="#d13d29"/></linearGradient><path d="M-4375.79 2928.93c-40.51 0-65.61 29.601-65.61 61.021 0 27.12 20.221 59.319 61.19 59.319 39.41 0 63.59-29.659 63.59-61.629 0-29.78-23.63-58.7-59.17-58.7v-.011zm-6.721 8.63c28.561 0 41.28 37.21 41.28 63.75 0 39.47-29.61 40.25-33.15 40.25-13.55 0-23.02-8.189-30.109-18.93-6.24-9.899-12.34-28.29-12.34-46.26 0-17.9 5.859-26.64 15.08-33.07 7.54-4.82 14.6-5.74 19.229-5.74h.01z" fill="url(#b)"/><linearGradient id="c" gradientUnits="userSpaceOnUse" x1="-11130.575" y1="556.948" x2="-11130.575" y2="413.518" gradientTransform="matrix(1.3509 0 0 -1.3509 10917.478 3681.026)"><stop offset="0" stop-color="#1a6fef"/><stop offset=".25" stop-color="#1e72ef"/><stop offset=".5" stop-color="#166bec"/><stop offset=".75" stop-color="#1267e9"/><stop offset="1" stop-color="#1063e5" stop-opacity=".87"/></linearGradient><path d="M-4110.979 2928.92c-35.381 0-54.521 22.4-54.521 47.41 0 19.04 13.64 40.52 41.78 40.52h7.119s-1.939 4.71-1.949 9.26c0 6.711 2.41 10.48 7.529 16.28-48.42 2.95-67.88 22.48-67.88 43.47 0 18.381 17.601 36.471 54.59 36.471 43.79 0 66.47-24.311 66.47-48.17 0-16.82-8.38-26.04-29.6-41.94-6.24-4.85-7.45-7.939-7.45-11.569 0-5.2 3.11-8.641 4.25-9.94 2.01-2.12 5.49-4.54 6.79-5.7 7.13-6.04 17.2-14.979 17.2-32.82 0-12.24-5.091-22.77-16.69-32.63h14.16l10.64-10.64h-52.438zm-9.76 7.96c6.42 0 11.779 2.27 17.439 6.98 6.279 5.66 16.311 20.87 16.311 39.69 0 20.31-15.78 25.87-24.32 25.87-4.18 0-9.189-1.17-13.43-4.07-9.42-6.109-18.771-22.37-18.771-41.72 0-17.46 10.4-26.75 22.771-26.75zm14.01 113.22c2.699 0 4.64.221 4.64.221s6.37 4.55 10.82 7.949c10.36 8.19 16.819 14.45 16.819 25.601 0 15.33-14.22 27.35-37.25 27.35-25.279 0-44.6-11.77-44.6-30.989 0-15.921 13.24-29.623 49.571-30.132z" fill="url(#c)"/><linearGradient id="d" gradientUnits="userSpaceOnUse" x1="-11061.771" y1="601.408" x2="-11061.771" y2="470.128" gradientTransform="matrix(1.3509 0 0 -1.3509 10917.478 3681.026)"><stop offset="0" stop-color="#0aa561"/><stop offset=".5" stop-color="#009b58"/><stop offset="1" stop-color="#00914b"/></linearGradient><path d="M-4050.88 3045.76h48.57l7.399-7.399-13.93-1.74c-3.75-.46-5.979-3.7-5.979-6.84v-146.71c0-2.89 1.34-4.37 2.319-5.311l8.761-8.76h-41.42l-10.78 10.78h16.1v151.97c0 2.16-.68 3.63-2.14 5.14l-8.9 8.87z" fill="url(#d)"/><linearGradient id="e" gradientUnits="userSpaceOnUse" x1="-10998.289" y1="556.948" x2="-10998.289" y2="467.864" gradientTransform="matrix(1.3509 0 0 -1.3509 10917.478 3681.026)"><stop offset="0" stop-color="#de5644"/><stop offset=".5" stop-color="#da4531"/><stop offset="1" stop-color="#ce3a28"/></linearGradient><path d="M-3936.5 2928.93c-27.12 0-55.93 20.67-55.93 57.78 0 30.649 20.67 62.56 59.29 62.56 9.63 0 17.56-1.239 24.99-4.649 7.97-3.67 15.64-9.63 21.239-17.12-10.569 5.33-19.189 8.83-30.64 8.83-21.76 0-42.74-15.7-50.08-44.56l76.87-31.07c-4.44-15.83-16.96-31.771-45.729-31.771h-.01zm-5.021 8.49c14.551 0 25.07 11.97 25.07 21.34 0 3.03-1.899 4.63-5.66 6.11l-47.25 19.11s-1.279-5.95-1.279-12.38c0-26.97 19.5-34.18 29.119-34.18z" fill="url(#e)"/><linearGradient id="f" gradientUnits="userSpaceOnUse" x1="-11221.762" y1="556.754" x2="-11221.762" y2="467.795" gradientTransform="matrix(1.3509 0 0 -1.3509 10917.478 3681.026)"><stop offset="0" stop-color="#ffc01a"/><stop offset=".5" stop-color="#ffba03"/><stop offset="1" stop-color="#ffb300"/></linearGradient><path d="M-4238.33 2928.93c-40.51 0-65.61 29.601-65.61 61.021 0 27.12 20.221 59.319 61.19 59.319 39.41 0 63.59-29.659 63.59-61.629 0-29.78-23.63-58.7-59.17-58.7v-.011zm-6.721 8.63c28.561 0 41.28 37.21 41.28 63.75 0 39.47-29.61 40.25-33.15 40.25-13.55 0-23.02-8.189-30.109-18.93-6.24-9.899-12.34-28.29-12.34-46.26 0-17.9 5.859-26.64 15.08-33.07 7.54-4.82 14.6-5.74 19.229-5.74h.01z" fill="url(#f)"/></g></svg>
|
After Width: | Height: | Size: 4.8 KiB |
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue