Commiting sample-components folder - containing a sample in various versions of angular2

git-svn-id: https://svn.driver.research-infrastructures.eu/driver/dnet40/modules/uoa-services-portal/trunk@43765 d315682c-612b-4755-9ff5-7f18f6832af3
This commit is contained in:
argiro.kokogiannaki 2016-09-22 09:36:28 +00:00
parent 411f437f45
commit bf77522917
140 changed files with 7746 additions and 0 deletions

View File

@ -0,0 +1,15 @@
# http://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
insert_final_newline = false
trim_trailing_whitespace = false

View File

@ -0,0 +1,12 @@
/__build__
/__server_build__
/node_modules
/typings
/tsd_typings/
npm-debug.log
/dist/
.idea
.DS_Store

View File

@ -0,0 +1,23 @@
# Angular 2 Universal Starter [![Universal Angular 2](https://img.shields.io/badge/universal-angular2-brightgreen.svg?style=flat)](https://github.com/angular/universal)
> Server-Side Rendering for Angular 2
A minimal Angular 2 starter for Universal JavaScript using TypeScript 2 and Webpack 2
> If you're looking for the Angular Universal repo go to [angular/universal](https://github.com/angular/universal)
[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy)
## Installation
* `npm install`
## Serve
* `npm start` to build your client app and start a web server
* `npm run build` to prepare a distributable bundle
## Development
* run `npm start` and `npm run watch` in two separate terminals to build your client app, start a web server, and allow file changes to update in realtime
## Watch files
* `npm run watch` to build your client app and start a web server

View File

@ -0,0 +1,12 @@
{
"name": "Angular 2 Universal Starter",
"description": "Angular 2 Universal starter kit by @AngularClass",
"repository": "https://github.com/angular/universal-starter",
"logo": "https://cloud.githubusercontent.com/assets/1016365/10639063/138338bc-7806-11e5-8057-d34c75f3cafc.png",
"env": {
"NPM_CONFIG_PRODUCTION": {
"description": "Install `webpack` and other development modules when deploying to allow full builds.",
"value": "false"
}
}
}

View File

@ -0,0 +1,7 @@
{
"watch": [
"dist",
"src/index.html"
],
"ext" : "js ts json html"
}

View File

@ -0,0 +1,73 @@
{
"name": "universal-starter",
"version": "2.0.0",
"description": "Angular 2 Universal starter kit by @AngularClass",
"repository": {
"type": "git",
"url": "https://github.com/angular/universal-starter.git"
},
"scripts": {
"watch": "webpack --watch",
"prebuild": "rimraf dist",
"build": "webpack",
"build:prod": "webpack --progress -p",
"prestart": "npm run build",
"server": "nodemon dist/server/index.js",
"start": "npm run server",
"predebug": "npm run build",
"debug:build": "node-nightly --inspect --debug-brk node_modules/webpack/bin/webpack.js",
"debug": "node --debug-brk dist/server/index.js"
},
"license": "MIT",
"contributors": [
"AngularClass <hello@angularclass.com>",
"PatrickJS <patrick@angularclass.com>",
"Jeff Whelpley <jeff@gethuman.com>",
"Jeff Cross <crossj@google.com>",
"Mark Pieszak <mpieszak84@gmail.com>"
],
"dependencies": {
"@angular/common": "2.0.0",
"@angular/compiler": "2.0.0",
"@angular/core": "2.0.0",
"@angular/forms": "2.0.0",
"@angular/http": "2.0.0",
"@angular/platform-browser": "2.0.0",
"@angular/platform-browser-dynamic": "2.0.0",
"@angular/platform-server": "2.0.0",
"@angular/router": "3.0.0",
"angular2-platform-node": "~2.0.4",
"angular2-universal": "~2.0.4",
"angular2-universal-polyfills": "~2.0.4",
"angular2-express-engine": "~2.0.4",
"body-parser": "^1.15.2",
"express": "^4.14.0",
"methods": "~1.1.2",
"rxjs": "5.0.0-beta.12",
"zone.js": "~0.6.21"
},
"devDependencies": {
"@angularclass/resolve-angular-routes": "^1.0.9",
"@types/body-parser": "0.0.29",
"@types/compression": "0.0.29",
"@types/cookie-parser": "^1.3.29",
"@types/express": "^4.0.32",
"@types/express-serve-static-core": "^4.0.33",
"@types/mime": "0.0.28",
"@types/node": "^6.0.38",
"@types/serve-static": "^1.7.27",
"angular2-template-loader": "^0.4.0",
"cookie-parser": "^1.4.3",
"json-loader": "^0.5.4",
"nodemon": "^1.10.0",
"raw-loader": "^0.5.1",
"rimraf": "^2.5.4",
"ts-loader": "^0.8.2",
"ts-node": "^1.3.0",
"typescript": "2.0.0",
"webpack": "^2.1.0-beta.22",
"webpack-dev-middleware": "^1.6.1",
"webpack-dev-server": "^2.1.0-beta.0",
"webpack-merge": "^0.13.0"
}
}

View File

@ -0,0 +1,27 @@
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import {ClaimsAdminComponent} from './claimPages/claims/claimsAdmin.component';
import {HomeComponent} from './home/home.component';
const appRoutes: Routes = [
{ path: '', component: HomeComponent, pathMatch: 'full' },
{ path: 'claims', component: ClaimsAdminComponent },
{ path: 'home', component: HomeComponent }
];
// ,
// {
// path: 'heroes',
// component: HeroListComponent,
// data: {
// title: 'Heroes List'
// }
// },
// { path: 'hero/:id', component: HeroDetailComponent },
// { path: '**', component: PageNotFoundComponent }
// export const appRoutingProviders: any[] = [
//
// ];
export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);

View File

@ -0,0 +1,41 @@
import { Component } from '@angular/core';
import 'rxjs/Rx';
@Component({
selector: 'app',
template: `
<div>
<nav class="navbar navbar-default" id="top">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">OpenAire</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li><a routerLinkActive="active" routerLink="/claims">Claims Admin</a></li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<main>
<router-outlet></router-outlet>
</main>
</div>`
})
export class App {
}

View File

@ -0,0 +1,107 @@
<div class="container">
<div class="row row-offcanvas row-offcanvas-right">
<div class="col-xs-12 col-sm-3">
<div class="panel panel-default">
<!-- Default panel contents -->
<div class="panel-heading">Claims related to</div>
<!-- List group -->
<div class="panel-body">
<p>
<label> <input [(ngModel)]="projectCB" type="checkbox" (ngModelChange)="changeType()" /> Project </label>
</p>
<p>
<label> <input [(ngModel)]="publicationCB" type="checkbox" (ngModelChange)="changeType()" /> Publication </label>
</p>
<p>
<label> <input [(ngModel)]="datasetCB" type="checkbox" (ngModelChange)="changeType()" /> Dataset </label>
</p>
<p>
<label> <input [(ngModel)]="contextCB" type="checkbox" (ngModelChange)="changeType()" /> Context </label>
</p>
<p class="align-right">
<button class="btn btn-primary" (click)="clearFilters()">Clear filters</button>
</p>
</div>
</div>
</div>
<div class="col-xs-6 col-sm-9 sidebar-offcanvas" id="sidebar">
<h4 *ngIf="resultsNum>0" >Showing {{(size*page - size +1)}} to {{(size*page>resultsNum)?resultsNum:(size*page)}} of {{resultsNum}} claims</h4>
<div *ngIf="resultsNum>size*page " class="text-right">
<span class="dropdown">
Show <button class="btn btn-default dropdown-toggle" type="button" id="pagingDropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
{{size}}
</button>
<ul class="dropdown-menu" aria-labelledby="pagingDropdown">
<li *ngIf="resultsNum > 10" ><a (click)="size=10 " >10 </a></li>
<li *ngIf="resultsNum > 20" ><a (click)="size = 20 " >20 </a></li>
<li *ngIf="resultsNum > 30" ><a (click)="size = 30 " >30 </a></li>
<li *ngIf="resultsNum > 50" ><a (click)="size = 50 " >50 </a></li>
</ul>
</span>
</div>
<div *ngIf="showErrorMessage " class = "alert alert-danger " >
An Error occured.
</div>
<div class="text-right" *ngIf="resultsNum">
<!--<paging [currentPage]="page" [totalResults]="resultsNum" [navigateTo]="navigateTo" [size]="size" [params]="getParameters()" > </paging>-->
<!--paging-no-load [currentPage]="page" [totalResults]="resultsNum" [navigateTo]="navigateTo" [params]="getParameters()" [size]="size" (pageChange)="pageChange($event)"> </paging-no-load-->
<paging-no-load [currentPage]="page" [totalResults]="resultsNum" [navigateTo]="navigateTo" [params]="getParameters()" (pageChange)="pageChange($event)"> </paging-no-load>
</div>
<!-- Buttons for selecting and Delete Claims -->
<div *ngIf="enableDelete">
<div *ngIf="selected.length>0 && resultsNum > 0 ">
<div class = "alert alert-info " >
You have selected {{selected.length}} claim(s)
</div>
</div>
<div *ngIf="deleteMessage.length>0 " [innerHTML]="deleteMessage">
</div>
<button class="btn btn-default" (click)="selectAll()">Select All</button> <button class="btn btn-default" (click)="deselectAll()">Deselect All</button> <button class="btn btn-default" (click)="confirmOpen()">Delete</button>
</div>
<br>
<div class="input-group col-lg-6">
<span class="input-group-addon" id="sizing-addon2">Filter</span>
<input type="text" class="form-control" placeholder="Type keywords..." aria-describedby="sizing-addon2" [(ngModel)]="inputkeyword" (keyup)="changekeyword()" >
</div>
<div *ngIf=" claims && claims.length == 0" >
<div class = "alert alert-info " >No entries found.</div>
</div>
<div class="">
<table *ngIf="claims && claims.length > 0" class="table table-striped">
<thead>
<tr>
<th *ngIf="enableDelete"></th>
<!--<th>Id</th>
<!-- <th>Target Type</th> -->
<th><a (click)="changeOrderby('target')" >Research Result</a> </th>
<!--<th>Source type</th> -->
<th><a (click)="changeOrderby('source')" >Link to</a> </th>
<th><a (click)="changeOrderby('user')" >Claimed by</a> </th>
<th><a (click)="changeOrderby('date')"> Claimed Date</a></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let claim of claims " >
<td *ngIf="enableDelete"><input [id]="claim.id" type="checkbox" (click)="select(claim,$event)" [ngModel]="isSelected(claim.id)"/></td>
<td><claim-entity [entity]="claim.target" [type]="claim.targetType" > </claim-entity></td>
<td><claim-entity [entity]="claim.source" [type]="claim.sourceType" > </claim-entity></td>
<td>{{claim.userMail}}</td>
<td>{{claim.date}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<alert (alertOutput)="confirmClose($event)">
</alert>
<loading [message]= "'Please wait...'"></loading>

View File

@ -0,0 +1,490 @@
import {Component, ViewChild, Input} from '@angular/core';
import {Location} from '@angular/common';
import {Observable} from 'rxjs/Observable';
import {ActivatedRoute, Router} from '@angular/router';
import {ClaimsService} from '../../services/claims.service';
import {Loading} from '../../common/modal/loading.component';
import {Alert} from '../../common/modal/alert';
@Component({
selector: 'claims',
templateUrl: 'claims.component.html',
providers:[ ClaimsService]
})
export class ClaimsComponent {
constructor (private _claimService: ClaimsService, private route: ActivatedRoute, private _router:Router, private location: Location) {
}
ngOnInit() {
// this.sub = this.route.queryParams.subscribe(params => {
var params = [];
if( this.myClaims == 'true' ){
this.fetchBy = "User";
}else{
this.fetchBy = params['fetchBy'];
this.fetchBy = (this.types.indexOf(this.fetchBy) != -1)? this.fetchBy:'All';
this.fetchId = params['fetchId'];
this.fetchId=this.fetchId?this.fetchId:'';
}
let page = (params['page']=== undefined)?1:+params['page'];
let size = (params['size']=== undefined)?10:+params['size'];
this.keyword = (params['keyword']?params['keyword']:"");
this.inputkeyword = this.keyword;
this.page = ( page <= 0 ) ? 1 : page;
this.size = ( size <= 0 ) ? 10 : size;
this.entityTypes = []//(params['types']?params['types']:[]);
this.setTypes(params['types']); // check the appropriate checkboxes
// this.setSortby(params['sort']);
this.getClaims();
// });
// this.sub = this.route.params.subscribe(params => {
// console.info(this.isAdmin+" "+this.myClaims+" Fetch by: "+this.fetchBy+" Fetch id: "+this.fetchId);
// if( this.myClaims == 'true' ){
// console.info("Is myclaims");
// this.fetchBy = "User";
// }else{
// console.info("Is admin");
//
// console.info(this.isAdmin);
//
// this.fetchBy = params['fetchBy'];
// this.fetchBy = (this.types.indexOf(this.fetchBy) != -1)? this.fetchBy:'All';
// this.fetchId = params['fetchId'];
// console.info("Fetch by:"+this.fetchBy+"Fetch id:"+this.fetchId);
// this.fetchId=this.fetchId?this.fetchId:'';
//
// }
//
// console.info(this.isAdmin+" "+this.myClaims+" Fetch by: "+this.fetchBy+" Fetch id: "+this.fetchId);
// let page = (params['page']=== undefined)?1:+params['page'];
// let size = (params['size']=== undefined)?10:+params['size'];
//
// this.keyword = (params['keyword']?params['keyword']:"");
// this.inputkeyword = this.keyword;
// this.page = ( page <= 0 ) ? 1 : page;
// this.size = ( size <= 0 ) ? 10 : size;
// this.entityTypes = []//(params['types']?params['types']:[]);
// this.setTypes(params['types']); // check the appropriate checkboxes
// this.setSortby(params['sort']);
// this.getClaims();
// console.info("params: "+params['page']+" page "+page +" this.page: "+this.page );
// });
}
ngOnDestroy() {
this.sub.unsubscribe();
}
sub: any;
//string because comes as input from component directive
@Input() enableDelete: string = 'false';
@Input() myClaims: string= 'false' ;
@Input() isAdmin:string = 'false';
page : number;
size:number;
keyword:string; // the keyword string to give to the request as parameter
inputkeyword:string; // the string written in the input field (keyword=inputkeyword when its length is bigger than 3 and the user stops typing)
lengths = [10,20,30,50];
types = ["All","Project","Context","Result","User"];
@Input() fetchBy:string;
@Input() fetchId:string;
navigateTo: string = "Claims";
resultsNum: number ;
claims: string[];
@ViewChild (Loading) loading : Loading ;
//checkboxes:
publicationCB = false;
datasetCB = false;
contextCB = false;
projectCB = false;
entityTypes : string[] =[] ;
descending = true;
sortby = "date";
selected=[];
deleteMessage:string = "";
showErrorMessage:boolean = false;
//params for pagingFormatter to use when navigate to page
params;
@ViewChild(Alert) alert;
claimsDeleted:number = 0;
getClaims () {
this.selected=[];
var types = '';
this.showErrorMessage = false;
for (var type of this.entityTypes){
types+=(types.length>0?'&':'')+"types="+type;
}
if(this.fetchBy =="Project" ){
this._claimService.getClaimsByProject(this.size,this.page,this.fetchId,this.keyword,this.sortby,this.descending, types).subscribe(
data => {
this.claims = data.data;
this.resultsNum= data.total;
},
err => {
console.error(err);
this.showErrorMessage = true;
}
);
}else if(this.fetchBy =="User"){
this._claimService.getClaimsByUser(this.size,this.page,this.fetchId,this.keyword,this.sortby,this.descending, types).subscribe(
data => {
this.claims = data.data;
this.resultsNum= data.total;
},
err => {
console.error(err);
this.showErrorMessage = true;
}
);
}else if(this.fetchBy =="Result"){
this._claimService.getClaimsByResult(this.size,this.page,this.fetchId,this.keyword,this.sortby,this.descending, types).subscribe(
data => {
this.claims = data.data;
this.resultsNum= data.total;
},
err => {
console.error(err);
this.showErrorMessage = true;
}
);
}else if(this.fetchBy =="Context"){
this._claimService.getClaimsBycontext(this.size,this.page,this.fetchId,this.keyword,this.sortby,this.descending, types).subscribe(
data => {
this.claims = data.data;
this.resultsNum= null;
this.resultsNum= data.total;//data.length; //TODO get the total results num
},
err => {
console.error(err);
this.showErrorMessage = true;
}
);
}else{
this._claimService.getClaims(this.size,this.page,this.keyword,this.sortby,this.descending, types).subscribe(
data => {
this.claims = data.data;
this.resultsNum = null;
this.resultsNum= data.total;//data.length; //TODO get the total results num
},
err => {
console.error(err);
this.showErrorMessage = true;
}
);
}
}
goToClaim(claimId: number){
this._router.navigate( ['Claim', { id: claimId}] );
}
goTo(page:number = 1){
this.page = page;
this.location.go(location.pathname,this.getParametersString());
this.getClaims();
}
getParameters(){
let params={ page: this.page, size: this.size, types: this.entityTypes, fetchBy: this.fetchBy, fetchId:this.fetchId, keyword : this.keyword, sort: this.getSortby() };
return params;
}
getParametersString(){
var params='';
params+=(this.page==1?"":(params.length>0?'&':'')+"page="+this.page);
params+=(this.size==10?"":(params.length>0?'&':'')+"size="+this.size);
// params+=(this.entityTypes==''?"":(params.length>0?'&':'')+"types="+this.entityTypes);
var types="";
for (var type of this.entityTypes){
types+=(types.length>0?',':'')+type;
}
params+=(types.length>0)?"types="+types:"";
if(this.isAdmin === 'true'){
params+=(this.fetchBy=='All'?"":(params.length>0?'&':'')+"fetchBy="+this.fetchBy);
params+=(this.fetchId==''?"":(params.length>0?'&':'')+"fetchId="+this.fetchId);
}
params+=(this. getSortby()=='datedesc'?"":(params.length>0?'&':'')+"sort="+this. getSortby());
params+=(this.keyword==''?"":(params.length>0?'&':'')+"keyword="+this.keyword);
return params;
}
changeLength(){
this.goTo();
}
clearFilters(){
this.keyword = '';
this.inputkeyword = '';
this.publicationCB = false;
this.projectCB = false;
this.datasetCB = false;
this.contextCB = false;
this.entityTypes = [];
this.goTo();
}
changeOrderby(sortby:string){
if(sortby==this.sortby){
this.descending = !this.descending;
}else{
this.sortby = sortby;
this.descending = false;
}
this.goTo();
}
setSortby(sortby:string){
if(!sortby|| sortby == "datedesc"){
this.descending = true;
this.sortby = "date";
}else if(sortby == "dateasc"){
this.descending = false;
this.sortby = "date";
}else if(sortby == "userasc"){
this.descending = false;
this.sortby = "user";
}else if(sortby == "userdesc"){
this.descending = true;
this.sortby = "user";
}if(sortby =="sourceasc"){
this.descending = false;
this.sortby = "source";
}else if(sortby == "sourcedesc"){
this.descending = true;
this.sortby = "source";
}else if(sortby == "targetasc"){
this.descending = false;
this.sortby = "target";
}else if(sortby == "targetdesc"){
this.descending = true;
this.sortby = "target";
}
}
getSortby():string{
if(this.descending){
return this.sortby+"desc";
}else{
return this.sortby+"asc";
}
}
changeType(){
this.entityTypes = [];
if(this.publicationCB){
this.entityTypes.push('publication');
}
if(this.datasetCB){
this.entityTypes.push('dataset');
}
if(this.projectCB){
this.entityTypes.push('project');
}
if(this.contextCB){
this.entityTypes.push('context');
}
// if(this.publicationCB == true && this.datasetCB == true && this.contextCB == true && this.projectCB == true ){
// this.entityTypes="";
// }else{
// this.entityTypes = "";
// if(this.publicationCB == true){
// this.entityTypes = "publication";
// }
// if(this.datasetCB == true){
// this.entityTypes += (this.entityTypes.length > 0?",":"")+"dataset";
// }
// if(this.contextCB == true){
// this.entityTypes += (this.entityTypes.length > 0?",":"")+"context";
// }
// if(this.projectCB == true){
// this.entityTypes += (this.entityTypes.length > 0?",":"")+"project";
// }
// }
// console.debug("Type changed: "+this.entityTypes+" "+this.publicationCB+ this.datasetCB + this.contextCB + this.projectCB);
this.goTo();
}
setTypes(types:string){
if(!types){
return;
}
if(types.length > 0){
this.entityTypes = [];
if(types.indexOf("publication")!=-1){
this.publicationCB = true;
this.entityTypes.push("publication");
}
if(types.indexOf("dataset")!=-1){
this.datasetCB = true;
this.entityTypes.push("dataset");
}
if(types.indexOf("project")!=-1){
this.projectCB = true;
this.entityTypes.push("project");
}
if(types.indexOf("context")!=-1){
this.contextCB = true;
this.entityTypes.push("context");
}
}
if(this.publicationCB && this.datasetCB && this.contextCB && this.projectCB){
this.entityTypes=[];
}
}
changekeyword(){
if(this.inputkeyword.length >= 3 || this.inputkeyword.length == 0 ){
this.keyword = this.inputkeyword;
this.page = 1;
this.goTo();
}
}
select(item:any,event){
this.deleteMessage="";
var value = event.currentTarget.checked;
if(value){
this.selected.push(item);
}else{
for (var _i = 0; _i < this.selected.length; _i++) {
let claim = this.selected[_i];
if(claim['id'] == item.id){
this.selected.splice(_i, 1);
}
}
}
}
selectAll(){
this.selected = [];
for (var _i = 0; _i < this.claims.length; _i++) {
let claim = this.claims[_i];
this.selected.push(claim);
}
this.deleteMessage = "";
}
deselectAll(){
this.selected = [];
this.deleteMessage="";
}
isSelected(id:string){
for (var _i = 0; _i < this.selected.length; _i++) {
let claim = this.selected[_i];
if(claim['id'] == id){
return true;
}
}
return false;
}
confirmOpen(){
if(this.selected.length <= 0){
}else{
this.alert.cancelButton = true;
this.alert.okButton = true;
this.alert.alertTitle = "Delete "+this.selected.length+" claim(s)";
this.alert.message = this.selected.length+" claims will be deleted. Do you want to proceed? ";
this.alert.okButtonText = "Yes";
this.alert.cancelButtonText = "No";
this.alert.open();
}
}
confirmClose(data){
this.delete();
}
delete(){
this.deleteMessage="";
this.loading.open();
this.claimsDeleted = 0;
var ids = [];
for (var i = 0; i < this.selected.length; i++){
var id =this.selected[i].id;
ids.push(id);
// var selected =this.selected[i].id;
// console.warn("Deleting claim with id:"+id);
// this.deleteById(id);
//TODO for multiple concurrent
}
this.batchDeleteById(ids);
}
deleteById(id:string){
console.warn("Deleting claim with id:"+id);
// this._claimService.deleteClaimById(id);
this._claimService.deleteClaimById(id).subscribe(
res => {
console.info('Delete response'+res.code );
console.warn("Deleted claim with id:"+ id);
//remove this claim from the
let newClaims=this.claims;
for (var _i = 0; _i < this.claims.length; _i++) {
let claim = this.claims[_i];
if(claim['id'] == id){
newClaims.splice(_i, 1);
}
}
//TODO should call getClaims???
this.claimsDeleted++;
this.claims = newClaims;
if(this.claimsDeleted == this.selected.length){
this.resultsNum = this.resultsNum - this.selected.length;
this.loading.close();
this.selected = [];
}
});
}
batchDeleteById(ids:string[]){
console.warn("Deleting claim with ids:"+ids);
this._claimService.deleteBulk(ids).subscribe(
res => {
console.info('Delete response'+res.code );
console.warn("Deleted ids:"+ res.deletedIds);
console.warn("Not found ids:"+ res.notFoundIds);
//remove this claim from the
let newClaims=this.claims;
for(var id of res.deletedIds){
for (var _i = 0; _i < this.claims.length; _i++) {
let claim = this.claims[_i];
if(claim['id'] == id){
newClaims.splice(_i, 1);
}
}
for (var _i = 0; _i < this.selected.length; _i++) {
let claim = this.selected[_i];
if(claim['id'] == id){
this.selected.splice(_i, 1);
}
}
}
this.claims = newClaims;
this.resultsNum = this.resultsNum - res.deletedIds.length;
this.loading.close();
if(res.deletedIds.length>0){
this.deleteMessage=this.deleteMessage+'<div class = "alert alert-success " >'+res.deletedIds.length+' claim(s) successfully deleted.</div>';
}
if(res.notFoundIds.length>0){
this.deleteMessage=this.deleteMessage+'<div class = "alert alert-warning " >'+res.notFoundIds.length+' claim(s) couldn\'t be deleted.</div>';
}
});
}
pageChange($event) {
var page:number = +$event.value
this.goTo(page);
}
}

View File

@ -0,0 +1,36 @@
import {Component, ViewChild, Input} from '@angular/core';
import {Location} from '@angular/common';
import {Observable} from 'rxjs/Observable';
@Component({
selector: 'claims-admin',
template: `
<div *ngIf="user" class="container">
<div class="page-header">
<h1> Claims Administrator </h1>
</div>
<div>
<div class="text-right"><a [routerLink]=" ['/linking']">Add more Links?</a></div>
<claims enableDelete="true" myClaims="false" isAdim="true"></claims>
</div>
</div>
<div *ngIf="!user" class="container">
TODO login
</div>
`,
})
export class ClaimsAdminComponent {
constructor ( ) {
}
user:string="argirok@di.uoa.gr";
ngOnInit() {
}
}

View File

@ -0,0 +1,38 @@
import {Component, Input} from '@angular/core';
// import {PublicationTitleFormatter} from './publicationTitleFormatter.component';
// import {ProjectTitleFormatter} from './projectTitleFormatter.component';
//Usage Example "<claim-entity [entity]="" [type]="" > </claim-entity>"
//externalUrl
@Component({
selector: 'claim-entity',
template: `
<div *ngIf="type == 'publication' || type == 'dataset'">
<i>({{type}}) </i>
<publication-title [title]="entity.title" [url]="entity.externalUrl" ></publication-title>
</div>
<div *ngIf="type == 'project' ">
<i>(Project)</i>
<project-title [project]="entity"></project-title>
</div>
<div *ngIf="type == 'context' ">
<i>(Context)</i>
<h5>{{entity.title}}</h5>
</div>
`
})
export class ClaimEntityFormatter {
@Input() entity: string[];
@Input() type: string;
constructor () {}
ngOnInit() {
}
}

View File

@ -0,0 +1,110 @@
import {Component, ViewEncapsulation, ComponentRef, ElementRef, Input, EventEmitter, Output} from '@angular/core';
// import { DynamicComponentLoader} from '@angular/core';
import {Open} from './open.component';
@Component({
selector: 'alert',
template: `
<div class="modal fade" [open]="!isOpen" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="">
<div class="modal-content">
<div class="modal-header" [hidden]=!alertHeader>
<button type="button" class="close" data-dismiss="modal" (click)='cancel()' aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title text-center" id="myModalLabel">{{alertTitle}}</h4>
</div>
<div class="modal-body">
<div [hidden]=!alertMessage>
{{message}}
</div>
</div>
<div class="modal-footer" [hidden]=!alertFooter>
<span [hidden]=!okButton >
<button class="btn btn-primary" (click)="ok()">{{okButtonText}}</button>
</span>
<span [hidden]=!cancelButton>
<button class="btn btn-primary" (click)="cancel()">{{cancelButtonText}}</button>
</span>
</div>
</div>
</div>
</div>
`,
encapsulation: ViewEncapsulation.None,
})
/**
* API to an open alert window.
*/
export class Alert{
/**
* Caption for the title.
*/
public alertTitle:string;
/**
* Describes if the alert contains Ok Button.
* The default Ok button will close the alert and emit the callback.
* Defaults to true.
*/
public okButton:boolean = true;
/**
* Caption for the OK button.
* Default: Ok
*/
public okButtonText:string= 'Ok';
/**
* Describes if the alert contains cancel Button.
* The default Cancelbutton will close the alert.
* Defaults to true.
*/
public cancelButton:boolean = true;
/**
* Caption for the Cancel button.
* Default: Cancel
*/
public cancelButtonText:string = 'Cancel';
/**
* if the alertMessage is true it will show the contentString inside alert body.
*/
public alertMessage:boolean = true;
/**
* Some message/content can be set in message which will be shown in alert body.
*/
public message:string;
/**
* if the value is true alert footer will be visible or else it will be hidden.
*/
public alertFooter:boolean= true;
/**
* shows alert header if the value is true.
*/
public alertHeader:boolean = true;
/**
* if the value is true alert will be visible or else it will be hidden.
*/
public isOpen:boolean=false;
/**
* Emitted when a ok button was clicked
* or when Ok method is called.
*/
@Output() public alertOutput:EventEmitter<any> = new EventEmitter();
constructor( public _elementRef: ElementRef){}
/**
* Opens a alert window creating backdrop.
*/
open(){
this.isOpen= true;
}
/**
* ok method closes the modal and emits modalOutput.
*/
ok(){
this.isOpen = false;
this.alertOutput.emit(true);
}
/**
* cancel method closes the moda.
*/
cancel(){
this.isOpen = false;
}
}

View File

@ -0,0 +1,49 @@
import {Component, ViewEncapsulation, ComponentRef, ElementRef, Input, EventEmitter, Output} from '@angular/core';
@Component({
selector: 'loading',
template: `
<div class="modal fade" [open]="!isOpen" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="">
<div class="modal-content">
<div class="modal-body">
<div >
<h3 class="text-center" >{{message}}</h3>
</div>
</div>
</div>
</div>
</div>
`,
encapsulation: ViewEncapsulation.None,
})
/**
* API to an open alert window.
*/
export class Loading{
@Input() public message:string ="Loading";
/**
* if the value is true alert will be visible or else it will be hidden.
*/
public isOpen:boolean=false;
/**
* Emitted when a ok button was clicked
* or when Ok method is called.
*/
@Output() public alertOutput:EventEmitter<any> = new EventEmitter();
constructor( public _elementRef: ElementRef){}
/**
* Opens a alert window creating backdrop.
*/
open(){
this.isOpen= true;
}
close(){
this.isOpen = false;
}
}

View File

@ -0,0 +1,55 @@
import {Directive, Input, HostBinding} from '@angular/core';
// todo: add animate
// todo: add init and on change
@Directive({selector: '[open]'})
export class Open {
@HostBinding('style.display')
private display:string;
@HostBinding('class.in')
@HostBinding('attr.aria-expanded')
private isExpanded:boolean = true;
@Input()
private set open(value:boolean) {
this.isExpanded = value;
this.toggle();
}
private get open():boolean {
return this.isExpanded;
}
constructor() {
}
init() {
this.isExpanded = false;
this.display = 'none';
}
toggle() {
if (this.isExpanded) {
this.hide();
} else {
this.show();
}
}
hide() {
this.isExpanded = false;
this.display = 'none';
if (typeof document !== 'undefined') {
let backDrop = document.getElementsByClassName("modal-backdrop");
if(backDrop.length>0){
document.body.removeChild(backDrop[0]);
}
}
}
show() {
let backDrop = document.createElement('div');
backDrop.className="modal-backdrop fade in";
document.body.appendChild(backDrop);
this.isExpanded = true;
this.display = 'block';
}
}

View File

@ -0,0 +1,75 @@
import {Component, Input, Output, EventEmitter} from '@angular/core';
//Usage Example <paging [currentPage]="page" [totalResults]="resultsNum" [navigateTo]="Search" [term]="keyword"> </paging>
@Component({
selector: 'paging-no-load',
template: `
<div *ngIf=" ( getTotalPages() > 0 ) && (getTotalPages() > 1) && ( 0 < currentPage && currentPage <= getTotalPages() ) " >
<ul class="pagination pagination-sm">
<li *ngIf=" currentPage > 1" ><a (click)="onPage((1))" aria-label="Previous">
<span aria-hidden="true">&laquo;</span></a></li>
<li *ngIf=" currentPage -2 > 0"><a (click)="onPage((currentPage -2))">{{currentPage -2}}</a></li>
<li *ngIf=" currentPage -1 > 0 "><a (click)="onPage((currentPage -1))">{{currentPage -1}}</a></li>
<li class="active"><a >{{currentPage}}</a></li>
<li *ngIf=" currentPage +1 <= getTotalPages() "><a (click)="onPage((currentPage +1))">{{currentPage +1}}</a></li>
<li *ngIf=" currentPage +2 <= getTotalPages() "><a (click)="onPage((currentPage +2))">{{currentPage +2}}</a></li>
<li *ngIf=" (currentPage -2 <= 0)&&(currentPage +3 <= getTotalPages()) "><a (click)="onPage((currentPage +3))">{{currentPage +3}}</a></li>
<li *ngIf=" (currentPage -1 <= 0)&&(currentPage +4 <= getTotalPages()) "><a (click)="onPage((currentPage +4))">{{currentPage +4}}</a></li>
<li *ngIf="getTotalPages() > currentPage"><a (click)="onPage((getTotalPages()))" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
</ul>
</div>
`
})
export class pagingFormatterNoLoad {
@Input() currentPage: number = 1;
@Input() navigateTo: string;
@Input() term: string='';
@Input() size: number=10;
@Input() totalResults: number = 10;
@Input() params;
@Output() pageChange = new EventEmitter();
constructor () {
}
ngOnInit() {
console.info("In paging -- CurrentPage:"+this.currentPage+" "+"total Pages = "+this.getTotalPages() +" Results num:"+this.totalResults);
}
getTotalPages(){
var i= this.totalResults/this.size;
var integerI=parseInt(''+i);
return parseInt(''+((i==integerI)?i:i+1));
}
onPrev(){
this.currentPage=this.currentPage-1;
this.pageChange.emit({
value: this.currentPage
});
}
onNext(){
this.currentPage=this.currentPage+1;
this.pageChange.emit({
value: this.currentPage
});
}
onPage(pageNum: number){
this.currentPage=pageNum;
this.pageChange.emit({
value: this.currentPage
});
}
}

View File

@ -0,0 +1,23 @@
import {Component, Input} from '@angular/core';
import {OpenaireProperties} from '../openaireProperties';
//Usage Example "<project-title [project]="X" > </project-title>"
@Component({
selector: 'project-title',
template: `
<div class="project-title">
<h5 ><a target="_blank" [href]="url" >{{project.name}} ({{project.funderName}})</a></h5>
</div>
`
})
export class ProjectTitleFormatter {
@Input() project: string[];
private url:string;
constructor () {}
ngOnInit() {
this.url = OpenaireProperties.getsearchLinkToProject() + "?projectId=" + this.project["openaireId"];
}
}

View File

@ -0,0 +1,26 @@
import {Component, Input} from '@angular/core';
//Usage Example "<publication-title [title]="X" [url]="X" > </publication-title>"
@Component({
selector: 'publication-title',
template: `
<div class="publication-title">
<h5 *ngIf="url" ><a target="_blank" href="{{url}}" >{{title}}</a></h5>
<h5 *ngIf="!url" >{{title}}</h5>
</div>
`
})
export class PublicationTitleFormatter {
@Input() title: string[];
@Input() url: string[];
constructor () {}
ngOnInit() {
}
}

View File

@ -0,0 +1,15 @@
export class Claim {
id: string;
sourceType: string;
targetType: string;
sourceId: string;
targetId: string;
date: string;
DOI: string;
project: Project
userMail: string;
}
export class Project{
}

View File

@ -0,0 +1,15 @@
<div class="container">
<div class="row">
<form>
<div class="col-lg-6">
<div class="input-group">
<input #term type="text" class="form-control col-xs-5" placeholder="Search for..." name="keyword" >
<span class="input-group-btn">
<button class="btn btn-default" type="submit" >GO</button>
</span>
</div>
</div>
</form>
</div>
</div>

View File

@ -0,0 +1,15 @@
import {Component} from '@angular/core';
import {Router} from '@angular/router';
import {Observable} from 'rxjs/Observable';
import {Location} from '@angular/common';
@Component({
selector: 'home',
templateUrl: 'home.component.html',
})
export class HomeComponent {
constructor ( private _router: Router, private location: Location) {}
}

View File

@ -0,0 +1,89 @@
export class OpenaireProperties {
//landing Pages
private static baseSearchLink="/"
private static searchLinkToPublication = "publication?articleId=";
private static searchLinkToProject = "project?projectId=";
private static searchLinkToPerson = "person?personId=";
private static searchLinkToDataProvider = "https://beta.openaire.eu/search/dataprovider?datasourceId=";
private static searchLinkToDataset = "dataset?datasetId=";
private static searchLinkToOrganization = "organization?organizationId=";
// Services - APIs
// public claimsAPIURL = "http://rudie.di.uoa.gr:8080/dnet-openaire-connector-service-1.0.0-SNAPSHOT/rest/claimsService/"
private static claimsAPIURL = "http://scoobydoo.di.uoa.gr:8181/dnet-openaire-connector-service-1.0.0-SNAPSHOT/rest/claimsService/";
private static searchAPIURL = "http://astero.di.uoa.gr:8080/dnet-functionality-services-2.0.0-SNAPSHOT/rest/v2.0/api/";
// private searchAPIURL = "http://rudie.di.uoa.gr:8080/dnet-functionality-services-2.0.0-SNAPSHOT/rest/v2.0/api/";
// private searchAPIURL = "http://scoobydoo.di.uoa.gr:8181/dnet-functionality-services-2.0.0-SNAPSHOT/rest/v2.0/api/";
private static searchServiveURL = "http://astero.di.uoa.gr:8080/dnet-functionality-services-2.0.0-SNAPSHOT/";
// private static searchServiveURL = "http://scoobydoo.di.uoa.gr:8181/dnet-functionality-services-2.0.0-SNAPSHOT/";
// private static searchServiveURL = "http://services.openaire.eu:8380/search/";
//private static searchServiveURL = "http://rudie.di.uoa.gr:8080/dnet-functionality-services-2.0.0-SNAPSHOT/";
private static searchCrossrefAPIURL = "http://api.crossref.org/works";
private static searchDataciteAPIURL = "http://search.datacite.org/api";
private static searchOrcidURL = "https://pub.orcid.org/";
// Identifiers
private static pmidURL = "http://www.ncbi.nlm.nih.gov/pubmed/";
private static doiURL = "http://dx.doi.org/";
private static cordisURL = "http://cordis.europa.eu/projects/";
private static pmcURL = "http://europepmc.org/articles/";
//landing Pages' getters
public static getsearchLinkToPublication():string{
return this.baseSearchLink + this.searchLinkToPublication;
}
public static getsearchLinkToDataset():string{
return this.baseSearchLink + this.searchLinkToDataset;
}
public static getsearchLinkToProject():string{
return this.baseSearchLink + this.searchLinkToProject;
}
public static getsearchLinkToPerson():string{
return this.baseSearchLink + this.searchLinkToPerson;
}
public static getsearchLinkToOrganization():string{
return this.searchLinkToOrganization;
}
public static getsearchLinkToDataProvider():string{
return this.searchLinkToDataProvider;
}
// Services - APIs' getters
public static getSearchAPIURL():string{
return this.searchAPIURL;
}
public static getSearchServiceURL():string{
return this.searchServiveURL;
}
public static getClaimsAPIURL():string{
return this.claimsAPIURL;
}
public static getSearchCrossrefAPIURL():string{
return this.searchCrossrefAPIURL;
}
public static getSearchDataciteAPIURL():string{
return this.searchDataciteAPIURL;
}
public static getSearchOrcidURL():string{
return this.searchOrcidURL;
}
// Identifiers' getters
public static getPmidURL():string{
return this.pmidURL;
}
public static getDoiURL():string{
return this.doiURL;
}
public static getCordisURL():string{
return this.cordisURL;
}
public static getPmcURL():string{
return this.pmcURL;
}
}

View File

@ -0,0 +1,131 @@
import {Injectable} from '@angular/core';
import {Jsonp, URLSearchParams,ResponseOptions, RequestOptions, Headers} from '@angular/http';
import {Http, Response} from '@angular/http';
import {Observable} from 'rxjs/Observable';
import {Claim} from '../entities/claim';
import {OpenaireProperties} from '../openaireProperties';
@Injectable()
export class ClaimsService {
private baseUrl;
constructor(private jsonp: Jsonp, private http: Http) {
this.baseUrl = OpenaireProperties.getClaimsAPIURL();
}
private getClaimRequest(size : number, page : number, url :string):any {
console.info('ClaimsService: Claims request: '+url);
return this.http.get( url)
.map(request => <any> request.json())
.do(request => console.info("Get claims: offset = "+(size*(page-1)) + " limit ="+size ))
.catch(this.handleError);
}
getClaims( size : number, page : number, keyword:string, sortby: string, descending: boolean, types: string):any {
console.info('ClaimsService: getClaims ' );
console.info('ClaimsService: Types : '+types );
let url = this.baseUrl +"claims"+"?offset="+(size*(page-1) + "&limit="+size)+"&keyword="+keyword+"&sortby="+sortby+"&descending="+descending+""+types;
return this.getClaimRequest(size,page,url);
}
getClaimsByUser( size : number, page : number, user:string, keyword:string, sortby: string, descending: boolean, types: string):any {
console.info('ClaimsService: getClaims for user : '+user);
let url = this.baseUrl +"users/"+user+"/claims"+"?offset="+(size*(page-1) + "&limit="+size)+"&keyword="+keyword+"&sortby="+sortby+"&descending="+descending+""+types;
return this.getClaimRequest(size,page,url);
}
getClaimsBycontext( size : number, page : number, contextId:string, keyword:string, sortby: string, descending: boolean, types: string):any {
console.info('ClaimsService: getClaims for context : '+contextId);
let url = this.baseUrl +"contexts/"+contextId+"/claims"+"?offset="+(size*(page-1) + "&limit="+size)+"&keyword="+keyword+"&sortby="+sortby+"&descending="+descending+""+types;
return this.getClaimRequest(size,page,url);
}
getClaimsByResult( size : number, page : number, resultId:string, keyword:string, sortby: string, descending: boolean, types: string):any {
console.info('ClaimsService: getClaims for result : '+resultId);
let url = this.baseUrl +"results/"+resultId+"/claims"+"?offset="+(size*(page-1) + "&limit="+size)+"&keyword="+keyword+"&sortby="+sortby+"&descending="+descending+""+types;
return this.getClaimRequest(size,page,url);
}
getClaimsByProject( size : number, page : number, projectId:string, keyword:string, sortby: string, descending: boolean, types: string):any {
console.info('ClaimsService: getClaims for project : '+projectId);
let url = this.baseUrl +"projects/"+projectId+"/claims"+"?offset="+(size*(page-1) + "&limit="+size)+"&keyword="+keyword+"&sortby="+sortby+"&descending="+descending+""+types;
return this.getClaimRequest(size,page,url);
}
deleteClaimById(claimId:string):any{
console.warn('Trying to delete claim with id : '+claimId);
let url = this.baseUrl +"claims/"+claimId;
console.warn('Delete url: '+url);
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.delete( url, options).map(request => <any> request.json())
.do(request => console.info("After delete" ))
.catch(this.handleError);
}
deleteBulk(claimIds:string[]):any{
console.warn('Trying to delete claims with ids : '+claimIds);
var url = "";
for(var claimId of claimIds){
url=url+(url.length >0 ?"&":"")+"claimId="+claimId;
}
url= this.baseUrl +"claims/bulk?"+url;
console.warn('Delete url: '+url);
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.delete( url, options).map(request => <any> request.json())
.do(request => console.info("After delete" ))
.catch(this.handleError);
}
insertBulkClaims(claims):any{
console.warn('Trying toinsert claims : '+claims);
let url = this.baseUrl +"claims/bulk";
let body = JSON.stringify( claims );
console.warn('Json body: : '+body);
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.post(url, body, options)
.map(res => res.json())
.do(request => console.info("Insert Response:"+request.status) )
.catch(this.handleError);
}
insertClaim(claim):any{
console.warn('Trying toinsert claim : '+claim);
let url = this.baseUrl +"claims";
let body = JSON.stringify( claim );
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.post(url, body, options)
.map(res => res.json())
.do(request => console.info("Insert Response:"+request.status) )
.catch(this.handleError);
}
private handleError (error: Response) {
// in a real world app, we may send the error to some remote logging infrastructure
// instead of just logging it to the console
console.error(error);
return Observable.throw(error || 'Server error');
}
getClaim(id:string):any {
let url = this.baseUrl+"claims/"+id;
return new Promise((resolve, reject) => {
this.http.get(url)
.map(res => res.json())
.subscribe(
data => {
resolve(data.data);
},
err => {
reject(err);
}
)
;
});
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -0,0 +1,24 @@
// Our API for demos only
import {fakeDataBase} from './db';
import {fakeDemoRedisCache} from './cache';
// you would use cookies/token etc
var USER_ID = 'f9d98cf1-1b96-464e-8755-bcc2a5c09077'; // hardcoded as an example
// Our API for demos only
export function serverApi(req, res) {
let key = USER_ID + '/data.json';
let cache = fakeDemoRedisCache.get(key);
if (cache !== undefined) {
console.log('/data.json Cache Hit');
return res.json(cache);
}
console.log('/data.json Cache Miss');
fakeDataBase.get()
.then(data => {
fakeDemoRedisCache.set(key, data);
return data;
})
.then(data => res.json(data));
}

View File

@ -0,0 +1,17 @@
var _fakeLRUcount = 0;
export const fakeDemoRedisCache = {
_cache: {},
get: (key) => {
let cache = fakeDemoRedisCache._cache[key];
_fakeLRUcount++;
if (_fakeLRUcount >= 10) {
fakeDemoRedisCache.clear();
_fakeLRUcount = 0;
}
return cache;
},
set: (key, data) => fakeDemoRedisCache._cache[key] = data,
clear: () => fakeDemoRedisCache._cache = {}
};

View File

@ -0,0 +1,7 @@
// Our API for demos only
export const fakeDataBase = {
get() {
let res = { data: 'This fake data came from the db on the server.' };
return Promise.resolve(res);
}
};

View File

@ -0,0 +1,20 @@
// the polyfills must be the first thing imported
import 'angular2-universal-polyfills';
// Angular 2
import { enableProdMode} from '@angular/core';
import { platformUniversalDynamic } from 'angular2-universal';
// enable prod for faster renders
enableProdMode();
import { MainModule } from './main.browser';
const platformRef = platformUniversalDynamic();
// on document ready bootstrap Angular 2
document.addEventListener('DOMContentLoaded', () => {
platformRef.bootstrapModule(MainModule);
});

View File

@ -0,0 +1,31 @@
<!doctype html>
<html lang="en">
<head>
<title>OpenAIRE</title>
<meta charset="UTF-8">
<meta name="description" content="Open Access Infrastructure for Europe ">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!--script src="node_modules/bootstrap/dist/js/bootstrap.min.js" ></script-->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.2/css/bootstrap.min.css" integrity="sha384-y3tfxAZXuh4HwSYylfB+J125MxIs6mR5FOHamPBG064zB+AFeWH94NdvaCBm8qnd" crossorigin="anonymous">
<!--link rel="stylesheet" href="bootstrap/dist/css/bootstrap.min.css"-->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
<!-- Temporarily add here custom style -->
<style>
.custom-hidden-dropdown-menu {position:static !important;}
</style>
<base href="/">
</head>
<body>
<app>
Loading Universal ...
</app>
<script src="/index.js"></script>
</body>
</html>

View File

@ -0,0 +1,38 @@
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { UniversalModule } from 'angular2-universal';
import { App } from './app/app';
//for routing:
import {ClaimsAdminComponent} from './app/claimPages/claims/claimsAdmin.component';
import { routing } from './app/app.routing';
import {Routes, RouterModule} from "@angular/router";
import {Open} from './app/common/modal/open.component';
import {Alert} from './app/common/modal/alert';
import {Loading} from './app/common/modal/loading.component';
import {ClaimsComponent} from './app/claimPages/claims/claims.component';
import {ClaimsService} from './app/services/claims.service';
import {Claim} from './app/entities/claim';
import {pagingFormatterNoLoad} from './app/common/pagingFormatterNoLoad.component';
import {ClaimEntityFormatter} from './app/common/claimEntityFormatter.component';
import {PublicationTitleFormatter} from './app/common/publicationTitleFormatter.component';
import {ProjectTitleFormatter} from './app/common/projectTitleFormatter.component';
import {HomeComponent} from './app/home/home.component';
@NgModule({
bootstrap: [ App ],
declarations: [ App, ClaimsAdminComponent, ClaimsComponent, ClaimEntityFormatter,pagingFormatterNoLoad, Open, ProjectTitleFormatter, PublicationTitleFormatter,HomeComponent, Loading, Alert],
imports: [
UniversalModule, // BrowserModule, HttpModule, and JsonpModule are included
FormsModule,
routing
],
providers: [ ClaimsService ]
})
export class MainModule {
}

View File

@ -0,0 +1,21 @@
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { UniversalModule } from 'angular2-universal';
import { HomeComponent } from './app/home/home.component';
import { App } from './app/app';
@NgModule({
bootstrap: [ App ],
declarations: [ App, HomeComponent ],
imports: [
UniversalModule, // NodeModule, NodeHttpModule, and NodeJsonpModule are included
FormsModule,
RouterModule.forRoot([
{ path: '', component: HomeComponent, pathMatch: 'full' }
])
]
})
export class MainModule {
}

View File

@ -0,0 +1,70 @@
// the polyfills must be the first thing imported in node.js
import 'angular2-universal-polyfills';
import * as path from 'path';
import * as express from 'express';
import * as bodyParser from 'body-parser';
import * as cookieParser from 'cookie-parser';
// Angular 2
import { enableProdMode } from '@angular/core';
// Angular 2 Universal
import { createEngine } from 'angular2-express-engine';
// App
import { MainModule } from './main.node';
// enable prod for faster renders
enableProdMode();
const app = express();
const ROOT = path.join(path.resolve(__dirname, '..'));
// Express View
app.engine('.html', createEngine({}));
app.set('views', __dirname);
app.set('view engine', 'html');
app.use(cookieParser('Angular 2 Universal'));
app.use(bodyParser.json());
// Serve static files
app.use('/assets', express.static(path.join(__dirname, 'assets'), {maxAge: 30}));
app.use(express.static(path.join(ROOT, 'dist/client'), {index: false}));
/* **AK** Add this path so that index.html can see files from node_modules folder (e.g. bootstrap files)*/
app.use(express.static(path.join(ROOT, 'node_modules'), {index: false}));
// app.get('/bootstrap.css', express.static(path.join(ROOT, 'node_modules/bootstrap/dist/css/bootstrap.min.css')));
import { serverApi } from './backend/api';
// Our API for demos only
app.get('/data.json', serverApi);
function ngApp(req, res) {
res.render('index', {
req,
res,
ngModule: MainModule,
preboot: false,
baseUrl: '/',
requestUrl: req.originalUrl,
originUrl: req.hostname
});
}
// Routes with html5pushstate
// ensure routes match client-side-app
app.get('/', ngApp);
app.get('/claims', ngApp);
app.get('/home', ngApp);
app.get('*', function(req, res) {
res.setHeader('Content-Type', 'application/json');
var pojo = { status: 404, message: 'No Content' };
var json = JSON.stringify(pojo, null, 2);
res.status(404).send(json);
});
// Server
let server = app.listen(process.env.PORT || 3000, () => {
console.log(`Listening on: http://localhost:${server.address().port}`);
});

View File

@ -0,0 +1,56 @@
/*
* Custom Type Definitions
* When including 3rd party modules you also need to include the type definition for the module
* if they don't provide one within the module. You can try to install it with typings
typings install node --save
* If you can't find the type definition in the registry we can make an ambient definition in
* this file for now. For example
declare module "my-module" {
export function doesSomething(value: string): string;
}
*
* If you're prototying and you will fix the types later you can also declare it as type any
*
declare var assert: any;
*
* If you're importing a module that uses Node.js modules which are CommonJS you need to import as
*
import * as _ from 'lodash'
* You can include your type definitions in this file until you create one for the typings registry
* see https://github.com/typings/registry
*
*/
// Extra variables that live on Global that will be replaced by webpack DefinePlugin
declare var ENV: string;
declare var HMR: boolean;
interface GlobalEnvironment {
ENV;
HMR;
}
interface WebpackModule {
hot: {
data?: any,
idle: any,
accept(dependencies?: string | string[], callback?: (updatedDependencies?: any) => void): void;
decline(dependencies?: string | string[]): void;
dispose(callback?: (data?: any) => void): void;
addDisposeHandler(callback?: (data?: any) => void): void;
removeDisposeHandler(callback?: (data?: any) => void): void;
check(autoApply?: any, callback?: (err?: Error, outdatedModules?: any[]) => void): void;
apply(options?: any, callback?: (err?: Error, outdatedModules?: any[]) => void): void;
status(callback?: (status?: string) => void): void | string;
removeStatusHandler(callback?: (status?: string) => void): void;
};
}
interface WebpackRequire {
context(file: string, flag?: boolean, exp?: RegExp): any;
}
// Extend typings
interface NodeRequire extends WebpackRequire {}
interface NodeModule extends WebpackModule {}
interface Global extends GlobalEnvironment {}

View File

@ -0,0 +1,30 @@
{
"compilerOptions": {
"declaration": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"module": "commonjs",
"moduleResolution": "node",
"outDir": "dist",
"sourceMap": true,
"sourceRoot": "src",
"target": "es5",
"lib": ["es6", "dom"],
"types": [
"body-parser",
"compression",
"cookie-parser",
"express",
"express-serve-static-core",
"mime",
"node",
"serve-static"
]
},
"exclude": [
"node_modules"
],
"compileOnSave": false,
"buildOnSave": false,
"atom": { "rewriteTsconfig": false }
}

View File

@ -0,0 +1,102 @@
var webpack = require('webpack');
var path = require('path');
var resolveNgRoute = require('@angularclass/resolve-angular-routes');
var commonConfig = {
resolve: {
extensions: ['', '.ts', '.js', '.json']
},
module: {
preLoaders: [
],
loaders: [
// TypeScript
{ test: /\.ts$/, loaders: ['ts-loader', 'angular2-template-loader'] },
{ test: /\.html$/, loader: 'raw-loader' },
{ test: /\.css$/, loader: 'raw-loader' },
{ test: /\.json$/, loader: 'json-loader' }
],
},
plugins: [
new webpack.ContextReplacementPlugin(
// The (\\|\/) piece accounts for path separators in *nix and Windows
/angular(\\|\/)core(\\|\/)src(\\|\/)linker/,
root('./src'),
resolveNgRoute(root('./src'))
)
]
};
var clientConfig = {
target: 'web',
entry: './src/client',
output: {
path: root('dist/client')
},
node: {
global: true,
__dirname: true,
__filename: true,
process: true,
Buffer: false
}
};
var serverConfig = {
target: 'node',
entry: './src/server', // use the entry file of the node server if everything is ts rather than es5
output: {
path: root('dist/server'),
libraryTarget: 'commonjs2'
},
externals: checkNodeImport,
node: {
global: true,
__dirname: true,
__filename: true,
process: true,
Buffer: true
}
};
// Default config
var defaultConfig = {
context: __dirname,
resolve: {
root: root('/src')
},
output: {
publicPath: path.resolve(__dirname),
filename: 'index.js'
}
};
var webpackMerge = require('webpack-merge');
module.exports = [
// Client
webpackMerge({}, defaultConfig, commonConfig, clientConfig),
// Server
webpackMerge({}, defaultConfig, commonConfig, serverConfig)
];
// Helpers
function checkNodeImport(context, request, cb) {
if (!path.isAbsolute(request) && request.charAt(0) !== '.') {
cb(null, 'commonjs ' + request); return;
}
cb();
}
function root(args) {
args = Array.prototype.slice.call(arguments, 0);
return path.join.apply(path, [__dirname].concat(args));
}

View File

@ -0,0 +1,7 @@
{
"watch": [
"dist",
"src/index.html"
],
"ext" : "js ts json html"
}

View File

@ -0,0 +1,51 @@
{
"name": "test-portal",
"version": "1.0.0-rc4",
"description": "Open Access Infrastructure for Research in Europe ",
"scripts": {
"postinstall": "typings install",
"watch": "webpack --watch",
"prebuild": "rimraf dist",
"build": "webpack",
"build:prod": "webpack --progress -p",
"prestart": "npm run build",
"server": "nodemon dist/server/index.js",
"start": "npm run server",
"predebug": "npm run build",
"debug": "node --debug-brk dist/server/index.js"
},
"license": "UOA",
"dependencies": {
"@angular/common": "2.0.0-rc.4",
"@angular/compiler": "2.0.0-rc.4",
"@angular/core": "2.0.0-rc.4",
"@angular/forms": "0.2.0",
"@angular/http": "2.0.0-rc.4",
"@angular/platform-browser": "2.0.0-rc.4",
"@angular/platform-browser-dynamic": "2.0.0-rc.4",
"@angular/platform-server": "2.0.0-rc.4",
"@angular/router": "3.0.0-beta.1",
"angular2-universal": "~0.104.5",
"body-parser": "^1.15.1",
"bootstrap": "^3.3.6",
"express": "^4.14.0",
"methods": "~1.1.2",
"parse5": "^1.5.0",
"preboot": "^2.1.2",
"rxjs": "5.0.0-beta.6"
},
"devDependencies": {
"angular2-template-loader": "^0.4.0",
"cookie-parser": "^1.4.3",
"nodemon": "^1.9.2",
"raw-loader": "^0.5.1",
"rimraf": "^2.5.2",
"source-map-loader": "^0.1.5",
"ts-loader": "^0.8.2",
"typescript": "^1.8.9",
"typings": "~1.0.5",
"webpack": "^1.13.1",
"webpack-dev-server": "^1.14.0",
"webpack-merge": "^0.13.0"
}
}

View File

@ -0,0 +1,116 @@
import {Component, Directive, ElementRef, Renderer} from '@angular/core';
import {RouterConfig, ROUTER_DIRECTIVES } from '@angular/router';
import {Http} from '@angular/http';
// import {SearchComponent} from './searchPages/search.component';
// import {ClaimComponent} from './claimPages/claim/claim.component';
import {ClaimsAdminComponent} from './claimPages/claims/claimsAdmin.component';
import {HomeComponent} from './home/home.component';
// import {LinkingComponent} from './claimPages/linking/linking.component';
// import {LinkingHomeComponent} from './claimPages/linking/linkingHome.component';
// import {MyClaimsComponent} from './claimPages/myClaims/myClaims.component';
// import {ProjectComponent} from './landingPages/project/project.component';
// import {DatasetComponent} from './landingPages/dataset/dataset.component';
// import {PersonComponent} from './landingPages/person/person.component';
// import {PublicationComponent} from './landingPages/publication/publication.component';
// import {OrganizationComponent} from './landingPages/organization/organization.component';
// import {MyClaimsDemoComponent} from './claimPages/myClaimsDemo.component';
// import {SearchPublicationsComponent} from './searchPages/searchPublications.component';
// import {AdvancedSearchPublicationsComponent} from './searchPages/advancedSearchPublications.component';
// import {UploadComponent} from './upload.component';
// import {BulkLinkingComponent} from './claimPages/linking/bulkLinking.component';
// import {DepositComponent} from './deposit/deposit.component';
import 'rxjs/Rx';
@Component({
selector: 'app',
directives: [
...ROUTER_DIRECTIVES
],
precompile: [ ClaimsAdminComponent, HomeComponent],
styles: [`
.router-link-active {
background-color: lightgray;
}
`],
template: `
<div>
<nav class="navbar navbar-default" id="top">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">OpenAire</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li><a [routerLinkActive]="['active', 'router-link-active']" [routerLink]=" ['./claims'] ">Claims Admin</a></li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<main>
<router-outlet></router-outlet>
</main>
</div>
`
})
export class App {
name: string = 'Angular 2';
data = {};
server;
constructor(public http: Http ) {
}
ngOnInit() {
setTimeout(() => {
this.server = 'Rendered on the Server';
}, 10);
}
}
export const routes: RouterConfig = [
{ path: '',
pathMatch: 'full',
redirectTo: 'home' },
{ path: 'home', component: HomeComponent },
{ path: 'claims', component: ClaimsAdminComponent } ];
// ,
// { path: 'claim', component: ClaimComponent },
// { path: 'search', component: SearchComponent },
// { path: 'linking', component: LinkingComponent },
// { path: 'my-claims', component: MyClaimsComponent },
// { path: 'demo', component: MyClaimsDemoComponent },
// { path: 'project', component: ProjectComponent},
// { path: 'publication', component: PublicationComponent },
// { path: 'dataset', component: DatasetComponent},
// { path: 'person', component: PersonComponent },
// { path: 'organization', component: OrganizationComponent },
// { path: 'up', component: UploadComponent},
// { path: 'bulk-linking', component: BulkLinkingComponent},
// { path: 'search-publications', component: SearchPublicationsComponent },
// { path: 'advanced-search-publications', component: AdvancedSearchPublicationsComponent },
// { path: 'deposit', component: DepositComponent}
//
// ];

View File

@ -0,0 +1,107 @@
<div class="container">
<div class="row row-offcanvas row-offcanvas-right">
<div class="col-xs-12 col-sm-3">
<div class="panel panel-default">
<!-- Default panel contents -->
<div class="panel-heading">Claims related to</div>
<!-- List group -->
<div class="panel-body">
<p>
<label> <input [(ngModel)]="projectCB" type="checkbox" (ngModelChange)="changeType()" /> Project </label>
</p>
<p>
<label> <input [(ngModel)]="publicationCB" type="checkbox" (ngModelChange)="changeType()" /> Publication </label>
</p>
<p>
<label> <input [(ngModel)]="datasetCB" type="checkbox" (ngModelChange)="changeType()" /> Dataset </label>
</p>
<p>
<label> <input [(ngModel)]="contextCB" type="checkbox" (ngModelChange)="changeType()" /> Context </label>
</p>
<p class="align-right">
<button class="btn btn-primary" (click)="clearFilters()">Clear filters</button>
</p>
</div>
</div>
</div>
<div class="col-xs-6 col-sm-9 sidebar-offcanvas" id="sidebar">
<h4 *ngIf="resultsNum>0" >Showing {{(size*page - size +1)}} to {{(size*page>resultsNum)?resultsNum:(size*page)}} of {{resultsNum}} claims</h4>
<div *ngIf="resultsNum>size*page " class="text-right">
<span class="dropdown">
Show <button class="btn btn-default dropdown-toggle" type="button" id="pagingDropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
{{size}}
</button>
<ul class="dropdown-menu" aria-labelledby="pagingDropdown">
<li *ngIf="resultsNum > 10" ><a (click)="size=10 " >10 </a></li>
<li *ngIf="resultsNum > 20" ><a (click)="size = 20 " >20 </a></li>
<li *ngIf="resultsNum > 30" ><a (click)="size = 30 " >30 </a></li>
<li *ngIf="resultsNum > 50" ><a (click)="size = 50 " >50 </a></li>
</ul>
</span>
</div>
<div *ngIf="showErrorMessage " class = "alert alert-danger " >
An Error occured.
</div>
<div class="text-right" *ngIf="resultsNum">
<!--<paging [currentPage]="page" [totalResults]="resultsNum" [navigateTo]="navigateTo" [size]="size" [params]="getParameters()" > </paging>-->
<!--paging-no-load [currentPage]="page" [totalResults]="resultsNum" [navigateTo]="navigateTo" [params]="getParameters()" [size]="size" (pageChange)="pageChange($event)"> </paging-no-load-->
<paging-no-load [currentPage]="page" [totalResults]="resultsNum" [navigateTo]="navigateTo" [params]="getParameters()" (pageChange)="pageChange($event)"> </paging-no-load>
</div>
<!-- Buttons for selecting and Delete Claims -->
<div *ngIf="enableDelete">
<div *ngIf="selected.length>0 && resultsNum > 0 ">
<div class = "alert alert-info " >
You have selected {{selected.length}} claim(s)
</div>
</div>
<div *ngIf="deleteMessage.length>0 " [innerHTML]="deleteMessage">
</div>
<button class="btn btn-default" (click)="selectAll()">Select All</button> <button class="btn btn-default" (click)="deselectAll()">Deselect All</button> <!--button class="btn btn-default" (click)="confirmOpen()">Delete</button-->
</div>
<br>
<div class="input-group col-lg-6">
<span class="input-group-addon" id="sizing-addon2">Filter</span>
<input type="text" class="form-control" placeholder="Type keywords..." aria-describedby="sizing-addon2" [(ngModel)]="inputkeyword" (keyup)="changekeyword()" >
</div>
<div *ngIf=" claims && claims.length == 0" >
<div class = "alert alert-info " >No entries found.</div>
</div>
<div class="">
<table *ngIf="claims && claims.length > 0" class="table table-striped">
<thead>
<tr>
<th *ngIf="enableDelete"></th>
<!--<th>Id</th>
<!-- <th>Target Type</th> -->
<th><a (click)="changeOrderby('target')" >Research Result</a> </th>
<!--<th>Source type</th> -->
<th><a (click)="changeOrderby('source')" >Link to</a> </th>
<th><a (click)="changeOrderby('user')" >Claimed by</a> </th>
<th><a (click)="changeOrderby('date')"> Claimed Date</a></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let claim of claims " >
<td *ngIf="enableDelete"><input [id]="claim.id" type="checkbox" (click)="select(claim,$event)" [ngModel]="isSelected(claim.id)"/></td>
<td><claim-entity [entity]="claim.target" [type]="claim.targetType" > </claim-entity></td>
<td><claim-entity [entity]="claim.source" [type]="claim.sourceType" > </claim-entity></td>
<td>{{claim.userMail}}</td>
<td>{{claim.date}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<!--alert (alertOutput)="confirmClose($event)">
</alert>
<loading [message]= "'Please wait...'"></loading-->

View File

@ -0,0 +1,491 @@
import {Component, ViewChild, Input} from '@angular/core';
import {JSONP_PROVIDERS} from '@angular/http';
import {Location} from '@angular/common';
import {Observable} from 'rxjs/Observable';
import {ROUTER_DIRECTIVES,ActivatedRoute, Router} from '@angular/router';
import {ClaimsService} from '../../services/claims.service';
import {Claim} from '../../entities/claim';
import {pagingFormatterNoLoad} from '../../common/pagingFormatterNoLoad.component';
import {ClaimEntityFormatter} from '../../common/claimEntityFormatter.component';
@Component({
selector: 'claims',
directives: [...ROUTER_DIRECTIVES,ClaimEntityFormatter,pagingFormatterNoLoad ],
templateUrl: 'claims.component.html',
providers:[ ClaimsService, JSONP_PROVIDERS]
})
export class ClaimsComponent {
constructor (private _claimService: ClaimsService, private route: ActivatedRoute, private _router:Router, private location: Location) {
}
ngOnInit() {
this.sub = this._router.routerState.queryParams.subscribe(params => {
if( this.myClaims == 'true' ){
this.fetchBy = "User";
}else{
this.fetchBy = params['fetchBy'];
this.fetchBy = (this.types.indexOf(this.fetchBy) != -1)? this.fetchBy:'All';
this.fetchId = params['fetchId'];
this.fetchId=this.fetchId?this.fetchId:'';
}
let page = (params['page']=== undefined)?1:+params['page'];
let size = (params['size']=== undefined)?10:+params['size'];
this.keyword = (params['keyword']?params['keyword']:"");
this.inputkeyword = this.keyword;
this.page = ( page <= 0 ) ? 1 : page;
this.size = ( size <= 0 ) ? 10 : size;
this.entityTypes = []//(params['types']?params['types']:[]);
this.setTypes(params['types']); // check the appropriate checkboxes
this.setSortby(params['sort']);
this.getClaims();
});
// this.sub = this.route.params.subscribe(params => {
// console.info(this.isAdmin+" "+this.myClaims+" Fetch by: "+this.fetchBy+" Fetch id: "+this.fetchId);
// if( this.myClaims == 'true' ){
// console.info("Is myclaims");
// this.fetchBy = "User";
// }else{
// console.info("Is admin");
//
// console.info(this.isAdmin);
//
// this.fetchBy = params['fetchBy'];
// this.fetchBy = (this.types.indexOf(this.fetchBy) != -1)? this.fetchBy:'All';
// this.fetchId = params['fetchId'];
// console.info("Fetch by:"+this.fetchBy+"Fetch id:"+this.fetchId);
// this.fetchId=this.fetchId?this.fetchId:'';
//
// }
//
// console.info(this.isAdmin+" "+this.myClaims+" Fetch by: "+this.fetchBy+" Fetch id: "+this.fetchId);
// let page = (params['page']=== undefined)?1:+params['page'];
// let size = (params['size']=== undefined)?10:+params['size'];
//
// this.keyword = (params['keyword']?params['keyword']:"");
// this.inputkeyword = this.keyword;
// this.page = ( page <= 0 ) ? 1 : page;
// this.size = ( size <= 0 ) ? 10 : size;
// this.entityTypes = []//(params['types']?params['types']:[]);
// this.setTypes(params['types']); // check the appropriate checkboxes
// this.setSortby(params['sort']);
// this.getClaims();
// console.info("params: "+params['page']+" page "+page +" this.page: "+this.page );
// });
}
ngOnDestroy() {
this.sub.unsubscribe();
}
sub: any;
//string because comes as input from component directive
@Input() enableDelete: string = 'false';
@Input() myClaims: string= 'false' ;
@Input() isAdmin:string = 'false';
page : number;
size:number;
keyword:string; // the keyword string to give to the request as parameter
inputkeyword:string; // the string written in the input field (keyword=inputkeyword when its length is bigger than 3 and the user stops typing)
lengths = [10,20,30,50];
types = ["All","Project","Context","Result","User"];
@Input() fetchBy:string;
@Input() fetchId:string;
navigateTo: string = "Claims";
resultsNum: number ;
claims: string[];
// @ViewChild (Loading) loading : Loading ;
//checkboxes:
publicationCB = false;
datasetCB = false;
contextCB = false;
projectCB = false;
entityTypes : string[] =[] ;
descending = true;
sortby = "date";
selected=[];
deleteMessage:string = "";
showErrorMessage:boolean = false;
//params for pagingFormatter to use when navigate to page
params;
// @ViewChild(Alert) alert;
claimsDeleted:number = 0;
getClaims () {
this.selected=[];
var types = '';
this.showErrorMessage = false;
for (var type of this.entityTypes){
types+=(types.length>0?'&':'')+"types="+type;
}
if(this.fetchBy =="Project" ){
this._claimService.getClaimsByProject(this.size,this.page,this.fetchId,this.keyword,this.sortby,this.descending, types).subscribe(
data => {
this.claims = data.data;
this.resultsNum= data.total;
},
err => {
console.error(err);
this.showErrorMessage = true;
}
);
}else if(this.fetchBy =="User"){
this._claimService.getClaimsByUser(this.size,this.page,this.fetchId,this.keyword,this.sortby,this.descending, types).subscribe(
data => {
this.claims = data.data;
this.resultsNum= data.total;
},
err => {
console.error(err);
this.showErrorMessage = true;
}
);
}else if(this.fetchBy =="Result"){
this._claimService.getClaimsByResult(this.size,this.page,this.fetchId,this.keyword,this.sortby,this.descending, types).subscribe(
data => {
this.claims = data.data;
this.resultsNum= data.total;
},
err => {
console.error(err);
this.showErrorMessage = true;
}
);
}else if(this.fetchBy =="Context"){
this._claimService.getClaimsBycontext(this.size,this.page,this.fetchId,this.keyword,this.sortby,this.descending, types).subscribe(
data => {
this.claims = data.data;
this.resultsNum= null;
this.resultsNum= data.total;//data.length; //TODO get the total results num
},
err => {
console.error(err);
this.showErrorMessage = true;
}
);
}else{
this._claimService.getClaims(this.size,this.page,this.keyword,this.sortby,this.descending, types).subscribe(
data => {
this.claims = data.data;
this.resultsNum = null;
this.resultsNum= data.total;//data.length; //TODO get the total results num
},
err => {
console.error(err);
this.showErrorMessage = true;
}
);
}
}
goToClaim(claimId: number){
this._router.navigate( ['Claim', { id: claimId}] );
}
goTo(page:number = 1){
this.page = page;
this.location.go(location.pathname,this.getParametersString());
this.getClaims();
}
getParameters(){
let params={ page: this.page, size: this.size, types: this.entityTypes, fetchBy: this.fetchBy, fetchId:this.fetchId, keyword : this.keyword, sort: this.getSortby() };
return params;
}
getParametersString(){
var params='';
params+=(this.page==1?"":(params.length>0?'&':'')+"page="+this.page);
params+=(this.size==10?"":(params.length>0?'&':'')+"size="+this.size);
// params+=(this.entityTypes==''?"":(params.length>0?'&':'')+"types="+this.entityTypes);
var types="";
for (var type of this.entityTypes){
types+=(types.length>0?',':'')+type;
}
params+=(types.length>0)?"types="+types:"";
if(this.isAdmin === 'true'){
params+=(this.fetchBy=='All'?"":(params.length>0?'&':'')+"fetchBy="+this.fetchBy);
params+=(this.fetchId==''?"":(params.length>0?'&':'')+"fetchId="+this.fetchId);
}
params+=(this. getSortby()=='datedesc'?"":(params.length>0?'&':'')+"sort="+this. getSortby());
params+=(this.keyword==''?"":(params.length>0?'&':'')+"keyword="+this.keyword);
return params;
}
changeLength(){
this.goTo();
}
clearFilters(){
this.keyword = '';
this.inputkeyword = '';
this.publicationCB = false;
this.projectCB = false;
this.datasetCB = false;
this.contextCB = false;
this.entityTypes = [];
this.goTo();
}
changeOrderby(sortby:string){
if(sortby==this.sortby){
this.descending = !this.descending;
}else{
this.sortby = sortby;
this.descending = false;
}
this.goTo();
}
setSortby(sortby:string){
if(!sortby|| sortby == "datedesc"){
this.descending = true;
this.sortby = "date";
}else if(sortby == "dateasc"){
this.descending = false;
this.sortby = "date";
}else if(sortby == "userasc"){
this.descending = false;
this.sortby = "user";
}else if(sortby == "userdesc"){
this.descending = true;
this.sortby = "user";
}if(sortby =="sourceasc"){
this.descending = false;
this.sortby = "source";
}else if(sortby == "sourcedesc"){
this.descending = true;
this.sortby = "source";
}else if(sortby == "targetasc"){
this.descending = false;
this.sortby = "target";
}else if(sortby == "targetdesc"){
this.descending = true;
this.sortby = "target";
}
}
getSortby():string{
if(this.descending){
return this.sortby+"desc";
}else{
return this.sortby+"asc";
}
}
changeType(){
this.entityTypes = [];
if(this.publicationCB){
this.entityTypes.push('publication');
}
if(this.datasetCB){
this.entityTypes.push('dataset');
}
if(this.projectCB){
this.entityTypes.push('project');
}
if(this.contextCB){
this.entityTypes.push('context');
}
// if(this.publicationCB == true && this.datasetCB == true && this.contextCB == true && this.projectCB == true ){
// this.entityTypes="";
// }else{
// this.entityTypes = "";
// if(this.publicationCB == true){
// this.entityTypes = "publication";
// }
// if(this.datasetCB == true){
// this.entityTypes += (this.entityTypes.length > 0?",":"")+"dataset";
// }
// if(this.contextCB == true){
// this.entityTypes += (this.entityTypes.length > 0?",":"")+"context";
// }
// if(this.projectCB == true){
// this.entityTypes += (this.entityTypes.length > 0?",":"")+"project";
// }
// }
// console.debug("Type changed: "+this.entityTypes+" "+this.publicationCB+ this.datasetCB + this.contextCB + this.projectCB);
this.goTo();
}
setTypes(types:string){
if(!types){
return;
}
if(types.length > 0){
this.entityTypes = [];
if(types.indexOf("publication")!=-1){
this.publicationCB = true;
this.entityTypes.push("publication");
}
if(types.indexOf("dataset")!=-1){
this.datasetCB = true;
this.entityTypes.push("dataset");
}
if(types.indexOf("project")!=-1){
this.projectCB = true;
this.entityTypes.push("project");
}
if(types.indexOf("context")!=-1){
this.contextCB = true;
this.entityTypes.push("context");
}
}
if(this.publicationCB && this.datasetCB && this.contextCB && this.projectCB){
this.entityTypes=[];
}
}
changekeyword(){
if(this.inputkeyword.length >= 3 || this.inputkeyword.length == 0 ){
this.keyword = this.inputkeyword;
this.page = 1;
this.goTo();
}
}
select(item:any,event){
this.deleteMessage="";
var value = event.currentTarget.checked;
if(value){
this.selected.push(item);
}else{
for (var _i = 0; _i < this.selected.length; _i++) {
let claim = this.selected[_i];
if(claim['id'] == item.id){
this.selected.splice(_i, 1);
}
}
}
}
selectAll(){
this.selected = [];
for (var _i = 0; _i < this.claims.length; _i++) {
let claim = this.claims[_i];
this.selected.push(claim);
}
this.deleteMessage = "";
}
deselectAll(){
this.selected = [];
this.deleteMessage="";
}
isSelected(id:string){
for (var _i = 0; _i < this.selected.length; _i++) {
let claim = this.selected[_i];
if(claim['id'] == id){
return true;
}
}
return false;
}
// confirmOpen(){
// if(this.selected.length <= 0){
//
// }else{
// this.alert.cancelButton = true;
// this.alert.okButton = true;
// this.alert.alertTitle = "Delete "+this.selected.length+" claim(s)";
// this.alert.message = this.selected.length+" claims will be deleted. Do you want to proceed? ";
// this.alert.okButtonText = "Yes";
// this.alert.cancelButtonText = "No";
// this.alert.open();
// }
// }
// confirmClose(data){
// this.delete();
// }
// delete(){
// this.deleteMessage="";
// this.loading.open();
// this.claimsDeleted = 0;
// var ids = [];
// for (var i = 0; i < this.selected.length; i++){
// var id =this.selected[i].id;
// ids.push(id);
// // var selected =this.selected[i].id;
// // console.warn("Deleting claim with id:"+id);
// // this.deleteById(id);
// //TODO for multiple concurrent
// }
// this.batchDeleteById(ids);
// }
// deleteById(id:string){
//
// console.warn("Deleting claim with id:"+id);
// // this._claimService.deleteClaimById(id);
// this._claimService.deleteClaimById(id).subscribe(
// res => {
// console.info('Delete response'+res.code );
// console.warn("Deleted claim with id:"+ id);
// //remove this claim from the
// let newClaims=this.claims;
// for (var _i = 0; _i < this.claims.length; _i++) {
// let claim = this.claims[_i];
// if(claim['id'] == id){
// newClaims.splice(_i, 1);
// }
// }
// //TODO should call getClaims???
// this.claimsDeleted++;
// this.claims = newClaims;
// if(this.claimsDeleted == this.selected.length){
// this.resultsNum = this.resultsNum - this.selected.length;
// this.loading.close();
// this.selected = [];
// }
//
//
// });
// }
// batchDeleteById(ids:string[]){
//
// console.warn("Deleting claim with ids:"+ids);
// this._claimService.deleteBulk(ids).subscribe(
// res => {
// console.info('Delete response'+res.code );
// console.warn("Deleted ids:"+ res.deletedIds);
// console.warn("Not found ids:"+ res.notFoundIds);
// //remove this claim from the
// let newClaims=this.claims;
// for(var id of res.deletedIds){
// for (var _i = 0; _i < this.claims.length; _i++) {
// let claim = this.claims[_i];
// if(claim['id'] == id){
// newClaims.splice(_i, 1);
// }
// }
// for (var _i = 0; _i < this.selected.length; _i++) {
// let claim = this.selected[_i];
// if(claim['id'] == id){
// this.selected.splice(_i, 1);
// }
// }
// }
// this.claims = newClaims;
// this.resultsNum = this.resultsNum - res.deletedIds.length;
// this.loading.close();
// if(res.deletedIds.length>0){
// this.deleteMessage=this.deleteMessage+'<div class = "alert alert-success " >'+res.deletedIds.length+' claim(s) successfully deleted.</div>';
// }
// if(res.notFoundIds.length>0){
// this.deleteMessage=this.deleteMessage+'<div class = "alert alert-warning " >'+res.notFoundIds.length+' claim(s) couldn\'t be deleted.</div>';
// }
// });
// }
pageChange($event) {
var page:number = +$event.value
this.goTo(page);
}
}

View File

@ -0,0 +1,40 @@
import {Component, ViewChild, Input} from '@angular/core';
import {JSONP_PROVIDERS} from '@angular/http';
import {Location} from '@angular/common';
import {Observable} from 'rxjs/Observable';
import {ROUTER_DIRECTIVES } from '@angular/router';
import {ClaimsComponent} from './claims.component';
@Component({
selector: 'claims',
directives: [...ROUTER_DIRECTIVES , ClaimsComponent],
template: `
<div *ngIf="user" class="container">
<div class="page-header">
<h1> Claims Administrator </h1>
</div>
<div>
<div class="text-right"><a [routerLink]=" ['/linking']">Add more Links?</a></div>
<claims enableDelete="true" myClaims="false" isAdim="true"></claims>
</div>
</div>
<div *ngIf="!user" class="container">
TODO login
</div>
`,
})
export class ClaimsAdminComponent {
constructor ( ) {
}
user:string="argirok@di.uoa.gr";
ngOnInit() {
}
}

View File

@ -0,0 +1,39 @@
import {Component, Input} from '@angular/core';
import {PublicationTitleFormatter} from './publicationTitleFormatter.component';
import {ProjectTitleFormatter} from './projectTitleFormatter.component';
//Usage Example "<claim-entity [entity]="" [type]="" > </claim-entity>"
//externalUrl
@Component({
selector: 'claim-entity',
template: `
<div *ngIf="type == 'publication' || type == 'dataset'">
<i>({{type}}) </i>
<publication-title [title]="entity.title" [url]="entity.externalUrl" ></publication-title>
</div>
<div *ngIf="type == 'project' ">
<i>(Project)</i>
<project-title [project]="entity"></project-title>
</div>
<div *ngIf="type == 'context' ">
<i>(Context)</i>
<h5>{{entity.title}}</h5>
</div>
`,
directives: [PublicationTitleFormatter,ProjectTitleFormatter]
})
export class ClaimEntityFormatter {
@Input() entity: string[];
@Input() type: string;
constructor () {}
ngOnInit() {
}
}

View File

@ -0,0 +1,111 @@
import {Component, ViewEncapsulation, ComponentRef, DynamicComponentLoader,ElementRef, Input, EventEmitter, Output} from '@angular/core';
import {Open} from './open.component';
@Component({
selector: 'alert',
template: `
<div class="modal fade" [open]="!isOpen" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="">
<div class="modal-content">
<div class="modal-header" [hidden]=!alertHeader>
<button type="button" class="close" data-dismiss="modal" (click)='cancel()' aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title text-center" id="myModalLabel">{{alertTitle}}</h4>
</div>
<div class="modal-body">
<div [hidden]=!alertMessage>
{{message}}
</div>
</div>
<div class="modal-footer" [hidden]=!alertFooter>
<span [hidden]=!okButton >
<button class="btn btn-primary" (click)="ok()">{{okButtonText}}</button>
</span>
<span [hidden]=!cancelButton>
<button class="btn btn-primary" (click)="cancel()">{{cancelButtonText}}</button>
</span>
</div>
</div>
</div>
</div>
`,
providers: [],
directives: [Open],
encapsulation: ViewEncapsulation.None,
pipes: []
})
/**
* API to an open alert window.
*/
export class Alert{
/**
* Caption for the title.
*/
public alertTitle:string;
/**
* Describes if the alert contains Ok Button.
* The default Ok button will close the alert and emit the callback.
* Defaults to true.
*/
public okButton:boolean = true;
/**
* Caption for the OK button.
* Default: Ok
*/
public okButtonText:string= 'Ok';
/**
* Describes if the alert contains cancel Button.
* The default Cancelbutton will close the alert.
* Defaults to true.
*/
public cancelButton:boolean = true;
/**
* Caption for the Cancel button.
* Default: Cancel
*/
public cancelButtonText:string = 'Cancel';
/**
* if the alertMessage is true it will show the contentString inside alert body.
*/
public alertMessage:boolean = true;
/**
* Some message/content can be set in message which will be shown in alert body.
*/
public message:string;
/**
* if the value is true alert footer will be visible or else it will be hidden.
*/
public alertFooter:boolean= true;
/**
* shows alert header if the value is true.
*/
public alertHeader:boolean = true;
/**
* if the value is true alert will be visible or else it will be hidden.
*/
public isOpen:boolean=false;
/**
* Emitted when a ok button was clicked
* or when Ok method is called.
*/
@Output() public alertOutput:EventEmitter<any> = new EventEmitter();
constructor(public dcl:DynamicComponentLoader, public _elementRef: ElementRef){}
/**
* Opens a alert window creating backdrop.
*/
open(){
this.isOpen= true;
}
/**
* ok method closes the modal and emits modalOutput.
*/
ok(){
this.isOpen = false;
this.alertOutput.emit(true);
}
/**
* cancel method closes the moda.
*/
cancel(){
this.isOpen = false;
}
}

View File

@ -0,0 +1,53 @@
import {Component, ViewEncapsulation, ComponentRef, DynamicComponentLoader,ElementRef, Input, EventEmitter, Output} from '@angular/core';
import {Open} from './open.component';
@Component({
selector: 'loading',
template: `
<div class="modal fade" [open]="!isOpen" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="">
<div class="modal-content">
<div class="modal-body">
<div >
<h3 class="text-center" >{{message}}</h3>
</div>
</div>
</div>
</div>
</div>
`,
providers: [],
directives: [Open],
encapsulation: ViewEncapsulation.None,
pipes: []
})
/**
* API to an open alert window.
*/
export class Loading{
@Input() public message:string ="Loading";
/**
* if the value is true alert will be visible or else it will be hidden.
*/
public isOpen:boolean=false;
/**
* Emitted when a ok button was clicked
* or when Ok method is called.
*/
@Output() public alertOutput:EventEmitter<any> = new EventEmitter();
constructor(public dcl:DynamicComponentLoader, public _elementRef: ElementRef){}
/**
* Opens a alert window creating backdrop.
*/
open(){
this.isOpen= true;
}
close(){
this.isOpen = false;
}
}

View File

@ -0,0 +1,55 @@
import {Directive, Input, HostBinding} from '@angular/core';
// todo: add animate
// todo: add init and on change
@Directive({selector: '[open]'})
export class Open {
@HostBinding('style.display')
private display:string;
@HostBinding('class.in')
@HostBinding('attr.aria-expanded')
private isExpanded:boolean = true;
@Input()
private set open(value:boolean) {
this.isExpanded = value;
this.toggle();
}
private get open():boolean {
return this.isExpanded;
}
constructor() {
}
init() {
this.isExpanded = false;
this.display = 'none';
}
toggle() {
if (this.isExpanded) {
this.hide();
} else {
this.show();
}
}
hide() {
this.isExpanded = false;
this.display = 'none';
if (typeof document !== 'undefined') {
let backDrop = document.getElementsByClassName("modal-backdrop");
if(backDrop.length>0){
document.body.removeChild(backDrop[0]);
}
}
}
show() {
let backDrop = document.createElement('div');
backDrop.className="modal-backdrop fade in";
document.body.appendChild(backDrop);
this.isExpanded = true;
this.display = 'block';
}
}

View File

@ -0,0 +1,75 @@
import {Component, Input, Output, EventEmitter} from '@angular/core';
//Usage Example <paging [currentPage]="page" [totalResults]="resultsNum" [navigateTo]="Search" [term]="keyword"> </paging>
@Component({
selector: 'paging-no-load',
template: `
<div *ngIf=" ( getTotalPages() > 0 ) && (getTotalPages() > 1) && ( 0 < currentPage && currentPage <= getTotalPages() ) " >
<ul class="pagination pagination-sm">
<li *ngIf=" currentPage > 1" ><a (click)="onPage((1))" aria-label="Previous">
<span aria-hidden="true">&laquo;</span></a></li>
<li *ngIf=" currentPage -2 > 0"><a (click)="onPage((currentPage -2))">{{currentPage -2}}</a></li>
<li *ngIf=" currentPage -1 > 0 "><a (click)="onPage((currentPage -1))">{{currentPage -1}}</a></li>
<li class="active"><a >{{currentPage}}</a></li>
<li *ngIf=" currentPage +1 <= getTotalPages() "><a (click)="onPage((currentPage +1))">{{currentPage +1}}</a></li>
<li *ngIf=" currentPage +2 <= getTotalPages() "><a (click)="onPage((currentPage +2))">{{currentPage +2}}</a></li>
<li *ngIf=" (currentPage -2 <= 0)&&(currentPage +3 <= getTotalPages()) "><a (click)="onPage((currentPage +3))">{{currentPage +3}}</a></li>
<li *ngIf=" (currentPage -1 <= 0)&&(currentPage +4 <= getTotalPages()) "><a (click)="onPage((currentPage +4))">{{currentPage +4}}</a></li>
<li *ngIf="getTotalPages() > currentPage"><a (click)="onPage((getTotalPages()))" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
</ul>
</div>
`
})
export class pagingFormatterNoLoad {
@Input() currentPage: number = 1;
@Input() navigateTo: string;
@Input() term: string='';
@Input() size: number=10;
@Input() totalResults: number = 10;
@Input() params;
@Output() pageChange = new EventEmitter();
constructor () {
}
ngOnInit() {
console.info("In paging -- CurrentPage:"+this.currentPage+" "+"total Pages = "+this.getTotalPages() +" Results num:"+this.totalResults);
}
getTotalPages(){
var i= this.totalResults/this.size;
var integerI=parseInt(''+i);
return parseInt(''+((i==integerI)?i:i+1));
}
onPrev(){
this.currentPage=this.currentPage-1;
this.pageChange.emit({
value: this.currentPage
});
}
onNext(){
this.currentPage=this.currentPage+1;
this.pageChange.emit({
value: this.currentPage
});
}
onPage(pageNum: number){
this.currentPage=pageNum;
this.pageChange.emit({
value: this.currentPage
});
}
}

View File

@ -0,0 +1,23 @@
import {Component, Input} from '@angular/core';
import {OpenaireProperties} from '../openaireProperties';
//Usage Example "<project-title [project]="X" > </project-title>"
@Component({
selector: 'project-title',
template: `
<div class="project-title">
<h5 ><a target="_blank" [href]="url" >{{project.name}} ({{project.funderName}})</a></h5>
</div>
`
})
export class ProjectTitleFormatter {
@Input() project: string[];
private url:string;
constructor () {}
ngOnInit() {
this.url = OpenaireProperties.getsearchLinkToProject() + "?projectId=" + this.project["openaireId"];
}
}

View File

@ -0,0 +1,26 @@
import {Component, Input} from '@angular/core';
//Usage Example "<publication-title [title]="X" [url]="X" > </publication-title>"
@Component({
selector: 'publication-title',
template: `
<div class="publication-title">
<h5 *ngIf="url" ><a target="_blank" href="{{url}}" >{{title}}</a></h5>
<h5 *ngIf="!url" >{{title}}</h5>
</div>
`
})
export class PublicationTitleFormatter {
@Input() title: string[];
@Input() url: string[];
constructor () {}
ngOnInit() {
}
}

View File

@ -0,0 +1,15 @@
export class Claim {
id: string;
sourceType: string;
targetType: string;
sourceId: string;
targetId: string;
date: string;
DOI: string;
project: Project
userMail: string;
}
export class Project{
}

View File

@ -0,0 +1,15 @@
<div class="container">
<div class="row">
<form>
<div class="col-lg-6">
<div class="input-group">
<input #term type="text" class="form-control col-xs-5" placeholder="Search for..." name="keyword" >
<span class="input-group-btn">
<button class="btn btn-default" type="submit" >GO</button>
</span>
</div>
</div>
</form>
</div>
</div>

View File

@ -0,0 +1,17 @@
import {Component} from '@angular/core';
import { ROUTER_DIRECTIVES, Router} from '@angular/router';
import {JSONP_PROVIDERS} from '@angular/http';
import {Observable} from 'rxjs/Observable';
import {Location} from '@angular/common';
@Component({
selector: 'home',
templateUrl: 'home.component.html',
directives: [ ...ROUTER_DIRECTIVES ],
})
export class HomeComponent {
constructor ( private _router: Router, private location: Location) {}
}

View File

@ -0,0 +1,89 @@
export class OpenaireProperties {
//landing Pages
private static baseSearchLink="/"
private static searchLinkToPublication = "publication?articleId=";
private static searchLinkToProject = "project?projectId=";
private static searchLinkToPerson = "person?personId=";
private static searchLinkToDataProvider = "https://beta.openaire.eu/search/dataprovider?datasourceId=";
private static searchLinkToDataset = "dataset?datasetId=";
private static searchLinkToOrganization = "organization?organizationId=";
// Services - APIs
// public claimsAPIURL = "http://rudie.di.uoa.gr:8080/dnet-openaire-connector-service-1.0.0-SNAPSHOT/rest/claimsService/"
private static claimsAPIURL = "http://scoobydoo.di.uoa.gr:8181/dnet-openaire-connector-service-1.0.0-SNAPSHOT/rest/claimsService/";
private static searchAPIURL = "http://astero.di.uoa.gr:8080/dnet-functionality-services-2.0.0-SNAPSHOT/rest/v2.0/api/";
// private searchAPIURL = "http://rudie.di.uoa.gr:8080/dnet-functionality-services-2.0.0-SNAPSHOT/rest/v2.0/api/";
// private searchAPIURL = "http://scoobydoo.di.uoa.gr:8181/dnet-functionality-services-2.0.0-SNAPSHOT/rest/v2.0/api/";
private static searchServiveURL = "http://astero.di.uoa.gr:8080/dnet-functionality-services-2.0.0-SNAPSHOT/";
// private static searchServiveURL = "http://scoobydoo.di.uoa.gr:8181/dnet-functionality-services-2.0.0-SNAPSHOT/";
// private static searchServiveURL = "http://services.openaire.eu:8380/search/";
//private static searchServiveURL = "http://rudie.di.uoa.gr:8080/dnet-functionality-services-2.0.0-SNAPSHOT/";
private static searchCrossrefAPIURL = "http://api.crossref.org/works";
private static searchDataciteAPIURL = "http://search.datacite.org/api";
private static searchOrcidURL = "https://pub.orcid.org/";
// Identifiers
private static pmidURL = "http://www.ncbi.nlm.nih.gov/pubmed/";
private static doiURL = "http://dx.doi.org/";
private static cordisURL = "http://cordis.europa.eu/projects/";
private static pmcURL = "http://europepmc.org/articles/";
//landing Pages' getters
public static getsearchLinkToPublication():string{
return this.baseSearchLink + this.searchLinkToPublication;
}
public static getsearchLinkToDataset():string{
return this.baseSearchLink + this.searchLinkToDataset;
}
public static getsearchLinkToProject():string{
return this.baseSearchLink + this.searchLinkToProject;
}
public static getsearchLinkToPerson():string{
return this.baseSearchLink + this.searchLinkToPerson;
}
public static getsearchLinkToOrganization():string{
return this.searchLinkToOrganization;
}
public static getsearchLinkToDataProvider():string{
return this.searchLinkToDataProvider;
}
// Services - APIs' getters
public static getSearchAPIURL():string{
return this.searchAPIURL;
}
public static getSearchServiceURL():string{
return this.searchServiveURL;
}
public static getClaimsAPIURL():string{
return this.claimsAPIURL;
}
public static getSearchCrossrefAPIURL():string{
return this.searchCrossrefAPIURL;
}
public static getSearchDataciteAPIURL():string{
return this.searchDataciteAPIURL;
}
public static getSearchOrcidURL():string{
return this.searchOrcidURL;
}
// Identifiers' getters
public static getPmidURL():string{
return this.pmidURL;
}
public static getDoiURL():string{
return this.doiURL;
}
public static getCordisURL():string{
return this.cordisURL;
}
public static getPmcURL():string{
return this.pmcURL;
}
}

View File

@ -0,0 +1,21 @@
import {Pipe, PipeTransform} from '@angular/core';
@Pipe({
name: 'claimTextFilter'
})
export class ClaimTextFilterPipe implements PipeTransform {
transform(value: any, filter: string): any {
console.info('ClaimTextFilterPipe word to filter : '+filter);
filter = filter?filter.toLocaleLowerCase():'';
return filter ? value.filter(claim=> (
claim.sourceType.toLocaleLowerCase().indexOf(filter)!=-1|| //sourceType
claim.targetType.toLocaleLowerCase().indexOf(filter)!=-1|| //targetType
claim.userMail.toLocaleLowerCase().indexOf(filter)!=-1|| //mail
((claim.source.title && claim.source.title.toLocaleLowerCase().indexOf(filter)!=-1)||(claim.source.name && claim.source.name.toLocaleLowerCase().indexOf(filter)!=-1))|| //source title
((claim.target.title && claim.target.title.toLocaleLowerCase().indexOf(filter)!=-1)||(claim.target.name && claim.target.name.toLocaleLowerCase().indexOf(filter)!=-1))|| //target title
((claim.source.funderName && claim.source.funderName.toLocaleLowerCase().indexOf(filter)!=-1)||(claim.source.funderName && claim.source.funderName.toLocaleLowerCase().indexOf(filter)!=-1))|| //source funder name
((claim.target.funderName && claim.target.funderName.toLocaleLowerCase().indexOf(filter)!=-1)||(claim.target.funderName && claim.target.funderName.toLocaleLowerCase().indexOf(filter)!=-1)) //target funder name
)) : value;
}
}

View File

@ -0,0 +1,35 @@
import {Pipe, PipeTransform} from '@angular/core';
@Pipe({name: 'claimTypeFilter'})
export class ClaimTypeFilterPipe implements PipeTransform {
transform(value: any, publication:boolean,dataset:boolean,project:boolean,context:boolean) : any {
let filter = publication;
console.info('ClaimTypeFilterPipe types to show : '+(publication?'publication ':' ')+(dataset?'dataset ':' ')+(project?'project ':' ')+(context?'context ':' '));
return (value)?value.filter((claim) =>{
let filter =publication;
if(publication||dataset||project||context) {
let filter = publication
if(filter && (claim.sourceType.toLocaleLowerCase().indexOf('publication')!=-1 || claim.targetType.toLocaleLowerCase().indexOf('publication')!=-1 )) {
return true;
}
filter = dataset;
if(filter && (claim.sourceType.toLocaleLowerCase().indexOf('dataset')!=-1 || claim.targetType.toLocaleLowerCase().indexOf('dataset')!=-1 )) {
return true;
}
filter = project;
if(filter && (claim.sourceType.toLocaleLowerCase().indexOf('project')!=-1 || claim.targetType.toLocaleLowerCase().indexOf('project')!=-1 )) {
return true;
}
filter = context;
if(filter && (claim.sourceType.toLocaleLowerCase().indexOf('context')!=-1 || claim.targetType.toLocaleLowerCase().indexOf('context')!=-1 )) {
return true;
}
return false;
}else{
return true;
}
}):value;
}
}

View File

@ -0,0 +1,131 @@
import {Injectable} from '@angular/core';
import {Jsonp, URLSearchParams,ResponseOptions, RequestOptions, Headers} from '@angular/http';
import {Http, Response} from '@angular/http';
import {Observable} from 'rxjs/Observable';
import {Claim} from '../entities/claim';
import {OpenaireProperties} from '../openaireProperties';
@Injectable()
export class ClaimsService {
private baseUrl;
constructor(private jsonp: Jsonp, private http: Http) {
this.baseUrl = OpenaireProperties.getClaimsAPIURL();
}
private getClaimRequest(size : number, page : number, url :string):any {
console.info('ClaimsService: Claims request: '+url);
return this.http.get( url)
.map(request => <any> request.json())
.do(request => console.info("Get claims: offset = "+(size*(page-1)) + " limit ="+size ))
.catch(this.handleError);
}
getClaims( size : number, page : number, keyword:string, sortby: string, descending: boolean, types: string):any {
console.info('ClaimsService: getClaims ' );
console.info('ClaimsService: Types : '+types );
let url = this.baseUrl +"claims"+"?offset="+(size*(page-1) + "&limit="+size)+"&keyword="+keyword+"&sortby="+sortby+"&descending="+descending+""+types;
return this.getClaimRequest(size,page,url);
}
getClaimsByUser( size : number, page : number, user:string, keyword:string, sortby: string, descending: boolean, types: string):any {
console.info('ClaimsService: getClaims for user : '+user);
let url = this.baseUrl +"users/"+user+"/claims"+"?offset="+(size*(page-1) + "&limit="+size)+"&keyword="+keyword+"&sortby="+sortby+"&descending="+descending+""+types;
return this.getClaimRequest(size,page,url);
}
getClaimsBycontext( size : number, page : number, contextId:string, keyword:string, sortby: string, descending: boolean, types: string):any {
console.info('ClaimsService: getClaims for context : '+contextId);
let url = this.baseUrl +"contexts/"+contextId+"/claims"+"?offset="+(size*(page-1) + "&limit="+size)+"&keyword="+keyword+"&sortby="+sortby+"&descending="+descending+""+types;
return this.getClaimRequest(size,page,url);
}
getClaimsByResult( size : number, page : number, resultId:string, keyword:string, sortby: string, descending: boolean, types: string):any {
console.info('ClaimsService: getClaims for result : '+resultId);
let url = this.baseUrl +"results/"+resultId+"/claims"+"?offset="+(size*(page-1) + "&limit="+size)+"&keyword="+keyword+"&sortby="+sortby+"&descending="+descending+""+types;
return this.getClaimRequest(size,page,url);
}
getClaimsByProject( size : number, page : number, projectId:string, keyword:string, sortby: string, descending: boolean, types: string):any {
console.info('ClaimsService: getClaims for project : '+projectId);
let url = this.baseUrl +"projects/"+projectId+"/claims"+"?offset="+(size*(page-1) + "&limit="+size)+"&keyword="+keyword+"&sortby="+sortby+"&descending="+descending+""+types;
return this.getClaimRequest(size,page,url);
}
deleteClaimById(claimId:string):any{
console.warn('Trying to delete claim with id : '+claimId);
let url = this.baseUrl +"claims/"+claimId;
console.warn('Delete url: '+url);
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.delete( url, options).map(request => <any> request.json())
.do(request => console.info("After delete" ))
.catch(this.handleError);
}
deleteBulk(claimIds:string[]):any{
console.warn('Trying to delete claims with ids : '+claimIds);
var url = "";
for(var claimId of claimIds){
url=url+(url.length >0 ?"&":"")+"claimId="+claimId;
}
url= this.baseUrl +"claims/bulk?"+url;
console.warn('Delete url: '+url);
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.delete( url, options).map(request => <any> request.json())
.do(request => console.info("After delete" ))
.catch(this.handleError);
}
insertBulkClaims(claims):any{
console.warn('Trying toinsert claims : '+claims);
let url = this.baseUrl +"claims/bulk";
let body = JSON.stringify( claims );
console.warn('Json body: : '+body);
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.post(url, body, options)
.map(res => res.json())
.do(request => console.info("Insert Response:"+request.status) )
.catch(this.handleError);
}
insertClaim(claim):any{
console.warn('Trying toinsert claim : '+claim);
let url = this.baseUrl +"claims";
let body = JSON.stringify( claim );
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.post(url, body, options)
.map(res => res.json())
.do(request => console.info("Insert Response:"+request.status) )
.catch(this.handleError);
}
private handleError (error: Response) {
// in a real world app, we may send the error to some remote logging infrastructure
// instead of just logging it to the console
console.error(error);
return Observable.throw(error || 'Server error');
}
getClaim(id:string):any {
let url = this.baseUrl+"claims/"+id;
return new Promise((resolve, reject) => {
this.http.get(url)
.map(res => res.json())
.subscribe(
data => {
resolve(data.data);
},
err => {
reject(err);
}
)
;
});
}
}

View File

@ -0,0 +1,20 @@
// the polyfills must be the first thing imported
import 'angular2-universal/polyfills';
// Angular 2
import {enableProdMode} from '@angular/core';
// Angular 2 Universal
import {prebootComplete} from 'angular2-universal';
// enable prod for faster renders
enableProdMode();
import {ngApp} from './main.browser';
// on document ready bootstrap Angular 2
document.addEventListener('DOMContentLoaded', () => {
ngApp()
.then(prebootComplete);
});

View File

@ -0,0 +1,29 @@
<!doctype html>
<html lang="en">
<head>
<title>OpenAIRE</title>
<meta charset="UTF-8">
<meta name="description" content="Open Access Infrastructure for Europe ">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="bootstrap/dist/js/bootstrap.min.js" ></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.2/css/bootstrap.min.css" integrity="sha384-y3tfxAZXuh4HwSYylfB+J125MxIs6mR5FOHamPBG064zB+AFeWH94NdvaCBm8qnd" crossorigin="anonymous">
<link rel="stylesheet" href="bootstrap/dist/css/bootstrap.min.css">
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
<!-- Temporarily add here custom style -->
<style>
.custom-hidden-dropdown-menu {position:static !important;}
</style>
<base href="/">
</head>
<body>
<app>
Loading Universal ...
</app>
<script src="/index.js"></script>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -0,0 +1,21 @@
// Angular 2 Universal
import { bootstrap } from '@angular/platform-browser-dynamic';
import { provideRouter } from '@angular/router';
import { HTTP_PROVIDERS } from '@angular/http';
import { disableDeprecatedForms, provideForms} from '@angular/forms';
// Application
import {App, routes} from './app/app.component';
// import {routes} from './app/app.routes';
// you must return bootstrap for client.ts
export function ngApp() {
return bootstrap(App, [
...HTTP_PROVIDERS,
// FORM_DIRECTIVES,
// FORM_PROVIDERS,
disableDeprecatedForms(),
provideForms(),
provideRouter(routes)
]);
}

View File

@ -0,0 +1,46 @@
// the polyfills must be the first thing imported in node.js
// import 'angular2-universal/polyfills'; // polyfills are moved to server.ts
// Angular 2 Universal
import {
REQUEST_URL,
ORIGIN_URL,
NODE_LOCATION_PROVIDERS,
NODE_HTTP_PROVIDERS,
ExpressEngineConfig
} from 'angular2-universal';
import { provideRouter } from '@angular/router';
import { APP_BASE_HREF } from '@angular/common';
// Application
import {App,routes} from './app/app.component';
import { disableDeprecatedForms, provideForms} from '@angular/forms';
export function ngApp(req, res) {
let baseUrl = '/';
let url = req.originalUrl || '/';
let config: ExpressEngineConfig = {
directives: [
App
],
platformProviders: [
{provide: ORIGIN_URL, useValue: 'http://localhost:3000'},
{provide: APP_BASE_HREF, useValue: baseUrl},
],
providers: [
{provide: REQUEST_URL, useValue: url},
NODE_HTTP_PROVIDERS,
provideRouter(routes),
disableDeprecatedForms(),
provideForms(),
NODE_LOCATION_PROVIDERS
],
async: true,
preboot: false // { appRoot: 'app' } // your top level app component selector
};
res.render('index', config);
}

View File

@ -0,0 +1,79 @@
// the polyfills must be the first thing imported in node.js
import 'angular2-universal/polyfills';
import * as path from 'path';
import * as express from 'express';
import * as bodyParser from 'body-parser';
import * as cookieParser from 'cookie-parser';
// Angular 2
import { enableProdMode } from '@angular/core';
// Angular 2 Universal
import { expressEngine } from 'angular2-universal';
// enable prod for faster renders
enableProdMode();
const app = express();
const ROOT = path.join(path.resolve(__dirname, '..'));
// Express View
app.engine('.html', expressEngine);
app.set('views', __dirname);
app.set('view engine', 'html');
app.use(cookieParser('Angular 2 Universal'));
app.use(bodyParser.json());
// Serve static files
app.use('/assets', express.static(path.join(__dirname, 'assets'), {maxAge: 30}));
app.use(express.static(path.join(ROOT, 'dist/client'), {index: false}));
/* **AK** Add this path so that index.html can see files from node_modules folder (e.g. bootstrap files)*/
app.use(express.static(path.join(ROOT, 'node_modules'), {index: false}));
// import { serverApi } from './backend/api';
// // Our API for demos only
// app.get('/data.json', serverApi);
import { ngApp } from './main.node';
// Routes with html5pushstate
// ensure routes match client-side-app
app.get('/', ngApp);
app.get('/claims', ngApp);
app.get('/claim', ngApp);
app.get('/home', ngApp);
app.get('/search', ngApp);
app.get('/search-publications', ngApp);
app.get('/advanced-search-publications', ngApp);
app.get('/my-claims', ngApp);
app.get('/linking', ngApp);
app.get('/demo-up', ngApp);
app.get('/up', ngApp);
app.get('/bulk-linking', ngApp);
app.get('/publication', ngApp);
app.get('/project', ngApp);
app.get('/person', ngApp);
app.get('/dataset', ngApp);
app.get('/organization', ngApp);
app.get('/deposit', ngApp);
// use indexFile over ngApp only when there is too much load on the server
function indexFile(req, res) {
// when there is too much load on the server just send
// the index.html without prerendering for client-only
res.sendFile('/index.html', {root: __dirname});
}
app.get('*', function(req, res) {
res.setHeader('Content-Type', 'application/json');
var pojo = { status: 404, message: 'No Content' };
var json = JSON.stringify(pojo, null, 2);
res.status(404).send(json);
});
// Server
app.listen(3000, () => {
console.log('Listening on: http://localhost:3000');
});

View File

@ -0,0 +1,74 @@
/*
* Custom Type Definitions
* When including 3rd party modules you also need to include the type definition for the module
* if they don't provide one within the module. You can try to install it with typings
typings install node --save
* If you can't find the type definition in the registry we can make an ambient definition in
* this file for now. For example
declare module "my-module" {
export function doesSomething(value: string): string;
}
*
* If you're prototying and you will fix the types later you can also declare it as type any
*
declare var assert: any;
*
* If you're importing a module that uses Node.js modules which are CommonJS you need to import as
*
import * as _ from 'lodash'
* You can include your type definitions in this file until you create one for the typings registry
* see https://github.com/typings/registry
*
*/
// Extra variables that live on Global that will be replaced by webpack DefinePlugin
declare var ENV: string;
declare var HMR: boolean;
interface GlobalEnvironment {
ENV;
HMR;
}
interface WebpackModule {
hot: {
data?: any,
idle: any,
accept(dependencies?: string | string[], callback?: (updatedDependencies?: any) => void): void;
decline(dependencies?: string | string[]): void;
dispose(callback?: (data?: any) => void): void;
addDisposeHandler(callback?: (data?: any) => void): void;
removeDisposeHandler(callback?: (data?: any) => void): void;
check(autoApply?: any, callback?: (err?: Error, outdatedModules?: any[]) => void): void;
apply(options?: any, callback?: (err?: Error, outdatedModules?: any[]) => void): void;
status(callback?: (status?: string) => void): void | string;
removeStatusHandler(callback?: (status?: string) => void): void;
};
}
interface WebpackRequire {
context(file: string, flag?: boolean, exp?: RegExp): any;
}
interface ErrorStackTraceLimit {
stackTraceLimit: number;
}
// Extend typings
interface NodeRequire extends WebpackRequire {}
interface ErrorConstructor extends ErrorStackTraceLimit {}
interface NodeModule extends WebpackModule {}
interface Global extends GlobalEnvironment {}
interface Thenable<T> {
then<U>(
onFulfilled?: (value: T) => U | Thenable<U>,
onRejected?: (error: any) => U | Thenable<U>): Thenable<U>;
then<U>(
onFulfilled?: (value: T) => U | Thenable<U>,
onRejected?: (error: any) => void): Thenable<U>;
catch<U>(onRejected?: (error: any) => U | Thenable<U>): Thenable<U>;
}

View File

@ -0,0 +1,18 @@
{
"compilerOptions": {
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "es5",
"module": "commonjs",
"removeComments": true,
"sourceMap": true
},
"exclude": [
"typings/main.d.ts",
"typings/main",
"node_modules"
],
"compileOnSave": false,
"buildOnSave": false,
"atom": { "rewriteTsconfig": false }
}

View File

@ -0,0 +1,13 @@
{
"globalDependencies": {
"body-parser": "registry:dt/body-parser#0.0.0+20160317120654",
"compression": "registry:dt/compression#0.0.0+20160501162003",
"cookie-parser": "registry:dt/cookie-parser#1.3.4+20160316155526",
"es6-shim": "registry:dt/es6-shim#0.31.2+20160317120654",
"express": "registry:dt/express#4.0.0+20160317120654",
"express-serve-static-core": "registry:dt/express-serve-static-core#0.0.0+20160322035842",
"mime": "registry:dt/mime#0.0.0+20160316155526",
"node": "registry:dt/node#4.0.0+20160412142033",
"serve-static": "registry:dt/serve-static#0.0.0+20160317120654"
}
}

View File

@ -0,0 +1,97 @@
var webpack = require('webpack');
var path = require('path');
var commonConfig = {
resolve: {
extensions: ['', '.ts', '.js', '.json']
},
module: {
loaders: [
// TypeScript
{ test: /\.ts$/, loaders: ['ts-loader', 'angular2-template-loader'] },
{ test: /\.html$/, loader: 'raw-loader' },
{ test: /\.css$/, loader: 'raw-loader' },
{ test: /\.json$/, loader: 'raw-loader' }
],
preLoaders: [
// needed to lower the filesize of angular due to inline source-maps
{ test: /\.js$/, loader: 'source-map-loader' }
],
},
plugins: [
new webpack.optimize.OccurenceOrderPlugin(true)
]
};
var clientConfig = {
target: 'web',
entry: './src/client',
output: {
path: root('dist/client')
},
node: {
global: true,
__dirname: true,
__filename: true,
process: true,
Buffer: false
}
};
var serverConfig = {
target: 'node',
entry: './src/server', // use the entry file of the node server if everything is ts rather than es5
output: {
path: root('dist/server'),
libraryTarget: 'commonjs2'
},
externals: checkNodeImport,
node: {
global: true,
__dirname: true,
__filename: true,
process: true,
Buffer: true
}
};
// Default config
var defaultConfig = {
context: __dirname,
resolve: {
root: root('/src')
},
output: {
publicPath: path.resolve(__dirname),
filename: 'index.js'
}
}
var webpackMerge = require('webpack-merge');
module.exports = [
// Client
webpackMerge({}, defaultConfig, commonConfig, clientConfig),
// Server
webpackMerge({}, defaultConfig, commonConfig, serverConfig)
]
// Helpers
function checkNodeImport(context, request, cb) {
if (!path.isAbsolute(request) && request.charAt(0) !== '.') {
cb(null, 'commonjs ' + request); return;
}
cb();
}
function root(args) {
args = Array.prototype.slice.call(arguments, 0);
return path.join.apply(path, [__dirname].concat(args));
}

View File

@ -0,0 +1,15 @@
# http://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
insert_final_newline = false
trim_trailing_whitespace = false

View File

@ -0,0 +1,12 @@
/__build__
/__server_build__
/node_modules
/typings
/tsd_typings/
npm-debug.log
/dist/
.idea
.DS_Store

View File

@ -0,0 +1,46 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch",
"type": "node",
"request": "launch",
"program": "${workspaceRoot}/dist/server/index.js",
"stopOnEntry": false,
"args": [],
"cwd": "${workspaceRoot}",
"preLaunchTask": null,
"runtimeExecutable": null,
"runtimeArgs": [
"--nolazy"
],
"env": {
"NODE_ENV": "development"
},
"externalConsole": false,
"sourceMaps": false,
"outDir": null
},
{
"name": "Attach",
"type": "node",
"request": "attach",
"port": 5858,
"address": "localhost",
"restart": false,
"sourceMaps": false,
"outDir": null,
"localRoot": "${workspaceRoot}",
"remoteRoot": null
},
{
"name": "Attach to Process",
"type": "node",
"request": "attach",
"processId": "${command.PickProcess}",
"port": 5858,
"sourceMaps": false,
"outDir": null
}
]
}

View File

@ -0,0 +1,23 @@
# Angular 2 Universal Starter [![Universal Angular 2](https://img.shields.io/badge/universal-angular2-brightgreen.svg?style=flat)](https://github.com/angular/universal)
A minimal Angular 2 starter for Universal JavaScript using TypeScript and Webpack
> If you're looking for the repo from the AngularConnect talk look in the [angular-connect branch](https://github.com/angular/universal-starter/tree/angular-connect)
If you're looking for a SystemJS version of the repo look in the [systemjs branch](https://github.com/angular/universal-starter/tree/systemjs)
[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy)
## Installation
* `npm install`
## Serve
* `npm start` to build your client app and start a web server
* `npm run build` to prepare a distributable bundle
## Development
* run `npm start` and `npm run watch` in two separate terminals to build your client app, start a web server, and allow file changes to update in realtime
## Watch files
* `npm run watch` to build your client app and start a web server

View File

@ -0,0 +1,12 @@
{
"name": "Angular 2 Universal Starter",
"description": "Angular 2 Universal starter kit by @AngularClass",
"repository": "https://github.com/angular/universal-starter",
"logo": "https://cloud.githubusercontent.com/assets/1016365/10639063/138338bc-7806-11e5-8057-d34c75f3cafc.png",
"env": {
"NPM_CONFIG_PRODUCTION": {
"description": "Install `webpack` and other development modules when deploying to allow full builds.",
"value": "false"
}
}
}

View File

@ -0,0 +1,7 @@
{
"watch": [
"dist",
"src/index.html"
],
"ext" : "js ts json html"
}

View File

@ -0,0 +1,70 @@
{
"name": "universal-starter",
"version": "2.0.0",
"description": "Angular 2 Universal starter kit by @AngularClass",
"repository": {
"type": "git",
"url": "https://github.com/angular/universal-starter.git"
},
"scripts": {
"watch": "webpack --watch",
"prebuild": "rimraf dist",
"build": "webpack",
"build:prod": "webpack --progress -p",
"prestart": "npm run build",
"server": "nodemon dist/server/index.js",
"start": "npm run server",
"predebug": "npm run build",
"debug:build": "node-nightly --inspect --debug-brk node_modules/webpack/bin/webpack.js",
"debug": "node --debug-brk dist/server/index.js"
},
"license": "MIT",
"contributors": [
"AngularClass <hello@angularclass.com>",
"PatrickJS <patrick@angularclass.com>",
"Jeff Whelpley <jeff@gethuman.com>",
"Jeff Cross <crossj@google.com>",
"Mark Pieszak <mpieszak84@gmail.com>"
],
"dependencies": {
"@angular/common": "2.0.0-rc.6",
"@angular/compiler": "2.0.0-rc.6",
"@angular/core": "2.0.0-rc.6",
"@angular/forms": "2.0.0-rc.6",
"@angular/http": "2.0.0-rc.6",
"@angular/platform-browser": "2.0.0-rc.6",
"@angular/platform-browser-dynamic": "2.0.0-rc.6",
"@angular/platform-server": "2.0.0-rc.6",
"@angular/router": "3.0.0-rc.2",
"angular2-platform-node": "~1.0.4",
"angular2-universal": "~1.0.4",
"angular2-universal-polyfills": "~1.0.4",
"angular2-express-engine": "~1.0.4",
"body-parser": "^1.15.2",
"express": "^4.14.0",
"methods": "~1.1.2",
"rxjs": "5.0.0-beta.11",
"zone.js": "0.6.17"
},
"devDependencies": {
"@types/body-parser": "0.0.29",
"@types/compression": "0.0.29",
"@types/cookie-parser": "^1.3.29",
"@types/express": "^4.0.29",
"@types/express-serve-static-core": "^4.0.29",
"@types/mime": "0.0.28",
"@types/node": "^4.0.30",
"@types/serve-static": "^1.7.27",
"angular2-template-loader": "^0.4.0",
"cookie-parser": "^1.4.3",
"nodemon": "^1.10.0",
"raw-loader": "^0.5.1",
"rimraf": "^2.5.4",
"ts-loader": "^0.8.2",
"typescript": "2.0.0",
"webpack": "^2.1.0-beta.22",
"webpack-dev-middleware": "^1.6.1",
"webpack-dev-server": "^2.1.0-beta.0",
"webpack-merge": "^0.13.0"
}
}

View File

@ -0,0 +1,29 @@
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import {ClaimsAdminComponent} from './claimPages/claims/claimsAdmin.component';
import {HomeComponent} from './home/home.component';
const appRoutes: Routes = [
{ path: '',
pathMatch: 'full',
redirectTo: 'home' },
{ path: 'claims', component: ClaimsAdminComponent },
{ path: 'home', component: HomeComponent }
];
// ,
// {
// path: 'heroes',
// component: HeroListComponent,
// data: {
// title: 'Heroes List'
// }
// },
// { path: 'hero/:id', component: HeroDetailComponent },
// { path: '**', component: PageNotFoundComponent }
// export const appRoutingProviders: any[] = [
//
// ];
export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);

View File

@ -0,0 +1,40 @@
import { Component } from '@angular/core';
import 'rxjs/Rx';
@Component({
selector: 'app',
template: `
<div>
<nav class="navbar navbar-default" id="top">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">OpenAire</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li><a routerLinkActive="active" routerLink="/claims">Claims Admin</a></li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<main>
<router-outlet></router-outlet>
</main>
</div>`
})
export class App {
}

View File

@ -0,0 +1,107 @@
<div class="container">
<div class="row row-offcanvas row-offcanvas-right">
<div class="col-xs-12 col-sm-3">
<div class="panel panel-default">
<!-- Default panel contents -->
<div class="panel-heading">Claims related to</div>
<!-- List group -->
<div class="panel-body">
<p>
<label> <input [(ngModel)]="projectCB" type="checkbox" (ngModelChange)="changeType()" /> Project </label>
</p>
<p>
<label> <input [(ngModel)]="publicationCB" type="checkbox" (ngModelChange)="changeType()" /> Publication </label>
</p>
<p>
<label> <input [(ngModel)]="datasetCB" type="checkbox" (ngModelChange)="changeType()" /> Dataset </label>
</p>
<p>
<label> <input [(ngModel)]="contextCB" type="checkbox" (ngModelChange)="changeType()" /> Context </label>
</p>
<p class="align-right">
<button class="btn btn-primary" (click)="clearFilters()">Clear filters</button>
</p>
</div>
</div>
</div>
<div class="col-xs-6 col-sm-9 sidebar-offcanvas" id="sidebar">
<h4 *ngIf="resultsNum>0" >Showing {{(size*page - size +1)}} to {{(size*page>resultsNum)?resultsNum:(size*page)}} of {{resultsNum}} claims</h4>
<div *ngIf="resultsNum>size*page " class="text-right">
<span class="dropdown">
Show <button class="btn btn-default dropdown-toggle" type="button" id="pagingDropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
{{size}}
</button>
<ul class="dropdown-menu" aria-labelledby="pagingDropdown">
<li *ngIf="resultsNum > 10" ><a (click)="size=10 " >10 </a></li>
<li *ngIf="resultsNum > 20" ><a (click)="size = 20 " >20 </a></li>
<li *ngIf="resultsNum > 30" ><a (click)="size = 30 " >30 </a></li>
<li *ngIf="resultsNum > 50" ><a (click)="size = 50 " >50 </a></li>
</ul>
</span>
</div>
<div *ngIf="showErrorMessage " class = "alert alert-danger " >
An Error occured.
</div>
<div class="text-right" *ngIf="resultsNum">
<!--<paging [currentPage]="page" [totalResults]="resultsNum" [navigateTo]="navigateTo" [size]="size" [params]="getParameters()" > </paging>-->
<!--paging-no-load [currentPage]="page" [totalResults]="resultsNum" [navigateTo]="navigateTo" [params]="getParameters()" [size]="size" (pageChange)="pageChange($event)"> </paging-no-load-->
<paging-no-load [currentPage]="page" [totalResults]="resultsNum" [navigateTo]="navigateTo" [params]="getParameters()" (pageChange)="pageChange($event)"> </paging-no-load>
</div>
<!-- Buttons for selecting and Delete Claims -->
<div *ngIf="enableDelete">
<div *ngIf="selected.length>0 && resultsNum > 0 ">
<div class = "alert alert-info " >
You have selected {{selected.length}} claim(s)
</div>
</div>
<div *ngIf="deleteMessage.length>0 " [innerHTML]="deleteMessage">
</div>
<button class="btn btn-default" (click)="selectAll()">Select All</button> <button class="btn btn-default" (click)="deselectAll()">Deselect All</button> <button class="btn btn-default" (click)="confirmOpen()">Delete</button>
</div>
<br>
<div class="input-group col-lg-6">
<span class="input-group-addon" id="sizing-addon2">Filter</span>
<input type="text" class="form-control" placeholder="Type keywords..." aria-describedby="sizing-addon2" [(ngModel)]="inputkeyword" (keyup)="changekeyword()" >
</div>
<div *ngIf=" claims && claims.length == 0" >
<div class = "alert alert-info " >No entries found.</div>
</div>
<div class="">
<table *ngIf="claims && claims.length > 0" class="table table-striped">
<thead>
<tr>
<th *ngIf="enableDelete"></th>
<!--<th>Id</th>
<!-- <th>Target Type</th> -->
<th><a (click)="changeOrderby('target')" >Research Result</a> </th>
<!--<th>Source type</th> -->
<th><a (click)="changeOrderby('source')" >Link to</a> </th>
<th><a (click)="changeOrderby('user')" >Claimed by</a> </th>
<th><a (click)="changeOrderby('date')"> Claimed Date</a></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let claim of claims " >
<td *ngIf="enableDelete"><input [id]="claim.id" type="checkbox" (click)="select(claim,$event)" [ngModel]="isSelected(claim.id)"/></td>
<td><claim-entity [entity]="claim.target" [type]="claim.targetType" > </claim-entity></td>
<td><claim-entity [entity]="claim.source" [type]="claim.sourceType" > </claim-entity></td>
<td>{{claim.userMail}}</td>
<td>{{claim.date}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<alert (alertOutput)="confirmClose($event)">
</alert>
<loading [message]= "'Please wait...'"></loading>

View File

@ -0,0 +1,490 @@
import {Component, ViewChild, Input} from '@angular/core';
import {Location} from '@angular/common';
import {Observable} from 'rxjs/Observable';
import {ActivatedRoute, Router} from '@angular/router';
import {ClaimsService} from '../../services/claims.service';
import {Loading} from '../../common/modal/loading.component';
import {Alert} from '../../common/modal/alert';
@Component({
selector: 'claims',
templateUrl: 'claims.component.html',
providers:[ ClaimsService]
})
export class ClaimsComponent {
constructor (private _claimService: ClaimsService, private route: ActivatedRoute, private _router:Router, private location: Location) {
}
ngOnInit() {
// this.sub = this.route.queryParams.subscribe(params => {
var params = [];
if( this.myClaims == 'true' ){
this.fetchBy = "User";
}else{
this.fetchBy = params['fetchBy'];
this.fetchBy = (this.types.indexOf(this.fetchBy) != -1)? this.fetchBy:'All';
this.fetchId = params['fetchId'];
this.fetchId=this.fetchId?this.fetchId:'';
}
let page = (params['page']=== undefined)?1:+params['page'];
let size = (params['size']=== undefined)?10:+params['size'];
this.keyword = (params['keyword']?params['keyword']:"");
this.inputkeyword = this.keyword;
this.page = ( page <= 0 ) ? 1 : page;
this.size = ( size <= 0 ) ? 10 : size;
this.entityTypes = []//(params['types']?params['types']:[]);
this.setTypes(params['types']); // check the appropriate checkboxes
// this.setSortby(params['sort']);
this.getClaims();
// });
// this.sub = this.route.params.subscribe(params => {
// console.info(this.isAdmin+" "+this.myClaims+" Fetch by: "+this.fetchBy+" Fetch id: "+this.fetchId);
// if( this.myClaims == 'true' ){
// console.info("Is myclaims");
// this.fetchBy = "User";
// }else{
// console.info("Is admin");
//
// console.info(this.isAdmin);
//
// this.fetchBy = params['fetchBy'];
// this.fetchBy = (this.types.indexOf(this.fetchBy) != -1)? this.fetchBy:'All';
// this.fetchId = params['fetchId'];
// console.info("Fetch by:"+this.fetchBy+"Fetch id:"+this.fetchId);
// this.fetchId=this.fetchId?this.fetchId:'';
//
// }
//
// console.info(this.isAdmin+" "+this.myClaims+" Fetch by: "+this.fetchBy+" Fetch id: "+this.fetchId);
// let page = (params['page']=== undefined)?1:+params['page'];
// let size = (params['size']=== undefined)?10:+params['size'];
//
// this.keyword = (params['keyword']?params['keyword']:"");
// this.inputkeyword = this.keyword;
// this.page = ( page <= 0 ) ? 1 : page;
// this.size = ( size <= 0 ) ? 10 : size;
// this.entityTypes = []//(params['types']?params['types']:[]);
// this.setTypes(params['types']); // check the appropriate checkboxes
// this.setSortby(params['sort']);
// this.getClaims();
// console.info("params: "+params['page']+" page "+page +" this.page: "+this.page );
// });
}
ngOnDestroy() {
this.sub.unsubscribe();
}
sub: any;
//string because comes as input from component directive
@Input() enableDelete: string = 'false';
@Input() myClaims: string= 'false' ;
@Input() isAdmin:string = 'false';
page : number;
size:number;
keyword:string; // the keyword string to give to the request as parameter
inputkeyword:string; // the string written in the input field (keyword=inputkeyword when its length is bigger than 3 and the user stops typing)
lengths = [10,20,30,50];
types = ["All","Project","Context","Result","User"];
@Input() fetchBy:string;
@Input() fetchId:string;
navigateTo: string = "Claims";
resultsNum: number ;
claims: string[];
@ViewChild (Loading) loading : Loading ;
//checkboxes:
publicationCB = false;
datasetCB = false;
contextCB = false;
projectCB = false;
entityTypes : string[] =[] ;
descending = true;
sortby = "date";
selected=[];
deleteMessage:string = "";
showErrorMessage:boolean = false;
//params for pagingFormatter to use when navigate to page
params;
@ViewChild(Alert) alert;
claimsDeleted:number = 0;
getClaims () {
this.selected=[];
var types = '';
this.showErrorMessage = false;
for (var type of this.entityTypes){
types+=(types.length>0?'&':'')+"types="+type;
}
if(this.fetchBy =="Project" ){
this._claimService.getClaimsByProject(this.size,this.page,this.fetchId,this.keyword,this.sortby,this.descending, types).subscribe(
data => {
this.claims = data.data;
this.resultsNum= data.total;
},
err => {
console.error(err);
this.showErrorMessage = true;
}
);
}else if(this.fetchBy =="User"){
this._claimService.getClaimsByUser(this.size,this.page,this.fetchId,this.keyword,this.sortby,this.descending, types).subscribe(
data => {
this.claims = data.data;
this.resultsNum= data.total;
},
err => {
console.error(err);
this.showErrorMessage = true;
}
);
}else if(this.fetchBy =="Result"){
this._claimService.getClaimsByResult(this.size,this.page,this.fetchId,this.keyword,this.sortby,this.descending, types).subscribe(
data => {
this.claims = data.data;
this.resultsNum= data.total;
},
err => {
console.error(err);
this.showErrorMessage = true;
}
);
}else if(this.fetchBy =="Context"){
this._claimService.getClaimsBycontext(this.size,this.page,this.fetchId,this.keyword,this.sortby,this.descending, types).subscribe(
data => {
this.claims = data.data;
this.resultsNum= null;
this.resultsNum= data.total;//data.length; //TODO get the total results num
},
err => {
console.error(err);
this.showErrorMessage = true;
}
);
}else{
this._claimService.getClaims(this.size,this.page,this.keyword,this.sortby,this.descending, types).subscribe(
data => {
this.claims = data.data;
this.resultsNum = null;
this.resultsNum= data.total;//data.length; //TODO get the total results num
},
err => {
console.error(err);
this.showErrorMessage = true;
}
);
}
}
goToClaim(claimId: number){
this._router.navigate( ['Claim', { id: claimId}] );
}
goTo(page:number = 1){
this.page = page;
this.location.go(location.pathname,this.getParametersString());
this.getClaims();
}
getParameters(){
let params={ page: this.page, size: this.size, types: this.entityTypes, fetchBy: this.fetchBy, fetchId:this.fetchId, keyword : this.keyword, sort: this.getSortby() };
return params;
}
getParametersString(){
var params='';
params+=(this.page==1?"":(params.length>0?'&':'')+"page="+this.page);
params+=(this.size==10?"":(params.length>0?'&':'')+"size="+this.size);
// params+=(this.entityTypes==''?"":(params.length>0?'&':'')+"types="+this.entityTypes);
var types="";
for (var type of this.entityTypes){
types+=(types.length>0?',':'')+type;
}
params+=(types.length>0)?"types="+types:"";
if(this.isAdmin === 'true'){
params+=(this.fetchBy=='All'?"":(params.length>0?'&':'')+"fetchBy="+this.fetchBy);
params+=(this.fetchId==''?"":(params.length>0?'&':'')+"fetchId="+this.fetchId);
}
params+=(this. getSortby()=='datedesc'?"":(params.length>0?'&':'')+"sort="+this. getSortby());
params+=(this.keyword==''?"":(params.length>0?'&':'')+"keyword="+this.keyword);
return params;
}
changeLength(){
this.goTo();
}
clearFilters(){
this.keyword = '';
this.inputkeyword = '';
this.publicationCB = false;
this.projectCB = false;
this.datasetCB = false;
this.contextCB = false;
this.entityTypes = [];
this.goTo();
}
changeOrderby(sortby:string){
if(sortby==this.sortby){
this.descending = !this.descending;
}else{
this.sortby = sortby;
this.descending = false;
}
this.goTo();
}
setSortby(sortby:string){
if(!sortby|| sortby == "datedesc"){
this.descending = true;
this.sortby = "date";
}else if(sortby == "dateasc"){
this.descending = false;
this.sortby = "date";
}else if(sortby == "userasc"){
this.descending = false;
this.sortby = "user";
}else if(sortby == "userdesc"){
this.descending = true;
this.sortby = "user";
}if(sortby =="sourceasc"){
this.descending = false;
this.sortby = "source";
}else if(sortby == "sourcedesc"){
this.descending = true;
this.sortby = "source";
}else if(sortby == "targetasc"){
this.descending = false;
this.sortby = "target";
}else if(sortby == "targetdesc"){
this.descending = true;
this.sortby = "target";
}
}
getSortby():string{
if(this.descending){
return this.sortby+"desc";
}else{
return this.sortby+"asc";
}
}
changeType(){
this.entityTypes = [];
if(this.publicationCB){
this.entityTypes.push('publication');
}
if(this.datasetCB){
this.entityTypes.push('dataset');
}
if(this.projectCB){
this.entityTypes.push('project');
}
if(this.contextCB){
this.entityTypes.push('context');
}
// if(this.publicationCB == true && this.datasetCB == true && this.contextCB == true && this.projectCB == true ){
// this.entityTypes="";
// }else{
// this.entityTypes = "";
// if(this.publicationCB == true){
// this.entityTypes = "publication";
// }
// if(this.datasetCB == true){
// this.entityTypes += (this.entityTypes.length > 0?",":"")+"dataset";
// }
// if(this.contextCB == true){
// this.entityTypes += (this.entityTypes.length > 0?",":"")+"context";
// }
// if(this.projectCB == true){
// this.entityTypes += (this.entityTypes.length > 0?",":"")+"project";
// }
// }
// console.debug("Type changed: "+this.entityTypes+" "+this.publicationCB+ this.datasetCB + this.contextCB + this.projectCB);
this.goTo();
}
setTypes(types:string){
if(!types){
return;
}
if(types.length > 0){
this.entityTypes = [];
if(types.indexOf("publication")!=-1){
this.publicationCB = true;
this.entityTypes.push("publication");
}
if(types.indexOf("dataset")!=-1){
this.datasetCB = true;
this.entityTypes.push("dataset");
}
if(types.indexOf("project")!=-1){
this.projectCB = true;
this.entityTypes.push("project");
}
if(types.indexOf("context")!=-1){
this.contextCB = true;
this.entityTypes.push("context");
}
}
if(this.publicationCB && this.datasetCB && this.contextCB && this.projectCB){
this.entityTypes=[];
}
}
changekeyword(){
if(this.inputkeyword.length >= 3 || this.inputkeyword.length == 0 ){
this.keyword = this.inputkeyword;
this.page = 1;
this.goTo();
}
}
select(item:any,event){
this.deleteMessage="";
var value = event.currentTarget.checked;
if(value){
this.selected.push(item);
}else{
for (var _i = 0; _i < this.selected.length; _i++) {
let claim = this.selected[_i];
if(claim['id'] == item.id){
this.selected.splice(_i, 1);
}
}
}
}
selectAll(){
this.selected = [];
for (var _i = 0; _i < this.claims.length; _i++) {
let claim = this.claims[_i];
this.selected.push(claim);
}
this.deleteMessage = "";
}
deselectAll(){
this.selected = [];
this.deleteMessage="";
}
isSelected(id:string){
for (var _i = 0; _i < this.selected.length; _i++) {
let claim = this.selected[_i];
if(claim['id'] == id){
return true;
}
}
return false;
}
confirmOpen(){
if(this.selected.length <= 0){
}else{
this.alert.cancelButton = true;
this.alert.okButton = true;
this.alert.alertTitle = "Delete "+this.selected.length+" claim(s)";
this.alert.message = this.selected.length+" claims will be deleted. Do you want to proceed? ";
this.alert.okButtonText = "Yes";
this.alert.cancelButtonText = "No";
this.alert.open();
}
}
confirmClose(data){
this.delete();
}
delete(){
this.deleteMessage="";
this.loading.open();
this.claimsDeleted = 0;
var ids = [];
for (var i = 0; i < this.selected.length; i++){
var id =this.selected[i].id;
ids.push(id);
// var selected =this.selected[i].id;
// console.warn("Deleting claim with id:"+id);
// this.deleteById(id);
//TODO for multiple concurrent
}
this.batchDeleteById(ids);
}
deleteById(id:string){
console.warn("Deleting claim with id:"+id);
// this._claimService.deleteClaimById(id);
this._claimService.deleteClaimById(id).subscribe(
res => {
console.info('Delete response'+res.code );
console.warn("Deleted claim with id:"+ id);
//remove this claim from the
let newClaims=this.claims;
for (var _i = 0; _i < this.claims.length; _i++) {
let claim = this.claims[_i];
if(claim['id'] == id){
newClaims.splice(_i, 1);
}
}
//TODO should call getClaims???
this.claimsDeleted++;
this.claims = newClaims;
if(this.claimsDeleted == this.selected.length){
this.resultsNum = this.resultsNum - this.selected.length;
this.loading.close();
this.selected = [];
}
});
}
batchDeleteById(ids:string[]){
console.warn("Deleting claim with ids:"+ids);
this._claimService.deleteBulk(ids).subscribe(
res => {
console.info('Delete response'+res.code );
console.warn("Deleted ids:"+ res.deletedIds);
console.warn("Not found ids:"+ res.notFoundIds);
//remove this claim from the
let newClaims=this.claims;
for(var id of res.deletedIds){
for (var _i = 0; _i < this.claims.length; _i++) {
let claim = this.claims[_i];
if(claim['id'] == id){
newClaims.splice(_i, 1);
}
}
for (var _i = 0; _i < this.selected.length; _i++) {
let claim = this.selected[_i];
if(claim['id'] == id){
this.selected.splice(_i, 1);
}
}
}
this.claims = newClaims;
this.resultsNum = this.resultsNum - res.deletedIds.length;
this.loading.close();
if(res.deletedIds.length>0){
this.deleteMessage=this.deleteMessage+'<div class = "alert alert-success " >'+res.deletedIds.length+' claim(s) successfully deleted.</div>';
}
if(res.notFoundIds.length>0){
this.deleteMessage=this.deleteMessage+'<div class = "alert alert-warning " >'+res.notFoundIds.length+' claim(s) couldn\'t be deleted.</div>';
}
});
}
pageChange($event) {
var page:number = +$event.value
this.goTo(page);
}
}

View File

@ -0,0 +1,26 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import {ClaimsComponent} from './claims.component';
import {ClaimsService} from '../../services/claims.service';
import {Claim} from '../../entities/claim';
import {pagingFormatterNoLoad} from '../../common/pagingFormatterNoLoad.component';
// import {ClaimEntityFormatterModule} from '../../common/claimEntityFormatter.module';
import {ClaimEntityFormatter} from '../../common/claimEntityFormatter.component';
import {PublicationTitleFormatter} from '../../common/publicationTitleFormatter.component';
import {ProjectTitleFormatter} from '../../common/projectTitleFormatter.component';
import {LoadingModule} from '../../common/modal/loading.module';
// import {Loading} from '../../common/modal/loading.component';
@NgModule({
imports: [ CommonModule, FormsModule, LoadingModule ],
declarations: [ ClaimsComponent, pagingFormatterNoLoad, ClaimEntityFormatter,PublicationTitleFormatter,ProjectTitleFormatter],
providers: [ ClaimsService ]
})
// exports: [ ContactComponent ],
// providers: [ ContactService ]
export class ClaimsModule { }

View File

@ -0,0 +1,36 @@
import {Component, ViewChild, Input} from '@angular/core';
import {Location} from '@angular/common';
import {Observable} from 'rxjs/Observable';
@Component({
selector: 'claims-admin',
template: `
<div *ngIf="user" class="container">
<div class="page-header">
<h1> Claims Administrator </h1>
</div>
<div>
<div class="text-right"><a [routerLink]=" ['/linking']">Add more Links?</a></div>
<claims enableDelete="true" myClaims="false" isAdim="true"></claims>
</div>
</div>
<div *ngIf="!user" class="container">
TODO login
</div>
`,
})
export class ClaimsAdminComponent {
constructor ( ) {
}
user:string="argirok@di.uoa.gr";
ngOnInit() {
}
}

View File

@ -0,0 +1,36 @@
import {Component, Input} from '@angular/core';
//Usage Example "<claim-entity [entity]="" [type]="" > </claim-entity>"
//externalUrl
@Component({
selector: 'claim-entity',
template: `
<div *ngIf="type == 'publication' || type == 'dataset'">
<i>({{type}}) </i>
<publication-title [title]="entity.title" [url]="entity.externalUrl" ></publication-title>
</div>
<div *ngIf="type == 'project' ">
<i>(Project)</i>
<project-title [project]="entity"></project-title>
</div>
<div *ngIf="type == 'context' ">
<i>(Context)</i>
<h5>{{entity.title}}</h5>
</div>
`
})
export class ClaimEntityFormatter {
@Input() entity: string[];
@Input() type: string;
constructor () {}
ngOnInit() {
}
}

View File

@ -0,0 +1,12 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import {PublicationTitleFormatter} from './publicationTitleFormatter.component';
import {ProjectTitleFormatter} from './projectTitleFormatter.component';
@NgModule({
imports: [ CommonModule, FormsModule ],
declarations: [ PublicationTitleFormatter,ProjectTitleFormatter ]
})
export class ClaimEntityFormatterModule { }

View File

@ -0,0 +1,13 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import {Open} from './open.component';
@NgModule({
imports: [ CommonModule, FormsModule ],
declarations: [ Open]
})
// exports: [ ContactComponent ],
// providers: [ ContactService ]
export class AlertModule { }

View File

@ -0,0 +1,110 @@
import {Component, ViewEncapsulation, ComponentRef, ElementRef, Input, EventEmitter, Output} from '@angular/core';
// import { DynamicComponentLoader} from '@angular/core';
import {Open} from './open.component';
@Component({
selector: 'alert',
template: `
<div class="modal fade" [open]="!isOpen" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="">
<div class="modal-content">
<div class="modal-header" [hidden]=!alertHeader>
<button type="button" class="close" data-dismiss="modal" (click)='cancel()' aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title text-center" id="myModalLabel">{{alertTitle}}</h4>
</div>
<div class="modal-body">
<div [hidden]=!alertMessage>
{{message}}
</div>
</div>
<div class="modal-footer" [hidden]=!alertFooter>
<span [hidden]=!okButton >
<button class="btn btn-primary" (click)="ok()">{{okButtonText}}</button>
</span>
<span [hidden]=!cancelButton>
<button class="btn btn-primary" (click)="cancel()">{{cancelButtonText}}</button>
</span>
</div>
</div>
</div>
</div>
`,
encapsulation: ViewEncapsulation.None,
})
/**
* API to an open alert window.
*/
export class Alert{
/**
* Caption for the title.
*/
public alertTitle:string;
/**
* Describes if the alert contains Ok Button.
* The default Ok button will close the alert and emit the callback.
* Defaults to true.
*/
public okButton:boolean = true;
/**
* Caption for the OK button.
* Default: Ok
*/
public okButtonText:string= 'Ok';
/**
* Describes if the alert contains cancel Button.
* The default Cancelbutton will close the alert.
* Defaults to true.
*/
public cancelButton:boolean = true;
/**
* Caption for the Cancel button.
* Default: Cancel
*/
public cancelButtonText:string = 'Cancel';
/**
* if the alertMessage is true it will show the contentString inside alert body.
*/
public alertMessage:boolean = true;
/**
* Some message/content can be set in message which will be shown in alert body.
*/
public message:string;
/**
* if the value is true alert footer will be visible or else it will be hidden.
*/
public alertFooter:boolean= true;
/**
* shows alert header if the value is true.
*/
public alertHeader:boolean = true;
/**
* if the value is true alert will be visible or else it will be hidden.
*/
public isOpen:boolean=false;
/**
* Emitted when a ok button was clicked
* or when Ok method is called.
*/
@Output() public alertOutput:EventEmitter<any> = new EventEmitter();
constructor( public _elementRef: ElementRef){}
/**
* Opens a alert window creating backdrop.
*/
open(){
this.isOpen= true;
}
/**
* ok method closes the modal and emits modalOutput.
*/
ok(){
this.isOpen = false;
this.alertOutput.emit(true);
}
/**
* cancel method closes the moda.
*/
cancel(){
this.isOpen = false;
}
}

View File

@ -0,0 +1,49 @@
import {Component, ViewEncapsulation, ComponentRef, ElementRef, Input, EventEmitter, Output} from '@angular/core';
@Component({
selector: 'loading',
template: `
<div class="modal fade" [open]="!isOpen" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="">
<div class="modal-content">
<div class="modal-body">
<div >
<h3 class="text-center" >{{message}}</h3>
</div>
</div>
</div>
</div>
</div>
`,
encapsulation: ViewEncapsulation.None,
})
/**
* API to an open alert window.
*/
export class Loading{
@Input() public message:string ="Loading";
/**
* if the value is true alert will be visible or else it will be hidden.
*/
public isOpen:boolean=false;
/**
* Emitted when a ok button was clicked
* or when Ok method is called.
*/
@Output() public alertOutput:EventEmitter<any> = new EventEmitter();
constructor( public _elementRef: ElementRef){}
/**
* Opens a alert window creating backdrop.
*/
open(){
this.isOpen= true;
}
close(){
this.isOpen = false;
}
}

View File

@ -0,0 +1,13 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import {Open} from './open.component';
@NgModule({
imports: [ CommonModule, FormsModule ],
declarations: [ Open]
})
// exports: [ ContactComponent ],
// providers: [ ContactService ]
export class LoadingModule { }

View File

@ -0,0 +1,55 @@
import {Directive, Input, HostBinding} from '@angular/core';
// todo: add animate
// todo: add init and on change
@Directive({selector: '[open]'})
export class Open {
@HostBinding('style.display')
private display:string;
@HostBinding('class.in')
@HostBinding('attr.aria-expanded')
private isExpanded:boolean = true;
@Input()
private set open(value:boolean) {
this.isExpanded = value;
this.toggle();
}
private get open():boolean {
return this.isExpanded;
}
constructor() {
}
init() {
this.isExpanded = false;
this.display = 'none';
}
toggle() {
if (this.isExpanded) {
this.hide();
} else {
this.show();
}
}
hide() {
this.isExpanded = false;
this.display = 'none';
if (typeof document !== 'undefined') {
let backDrop = document.getElementsByClassName("modal-backdrop");
if(backDrop.length>0){
document.body.removeChild(backDrop[0]);
}
}
}
show() {
let backDrop = document.createElement('div');
backDrop.className="modal-backdrop fade in";
document.body.appendChild(backDrop);
this.isExpanded = true;
this.display = 'block';
}
}

View File

@ -0,0 +1,75 @@
import {Component, Input, Output, EventEmitter} from '@angular/core';
//Usage Example <paging [currentPage]="page" [totalResults]="resultsNum" [navigateTo]="Search" [term]="keyword"> </paging>
@Component({
selector: 'paging-no-load',
template: `
<div *ngIf=" ( getTotalPages() > 0 ) && (getTotalPages() > 1) && ( 0 < currentPage && currentPage <= getTotalPages() ) " >
<ul class="pagination pagination-sm">
<li *ngIf=" currentPage > 1" ><a (click)="onPage((1))" aria-label="Previous">
<span aria-hidden="true">&laquo;</span></a></li>
<li *ngIf=" currentPage -2 > 0"><a (click)="onPage((currentPage -2))">{{currentPage -2}}</a></li>
<li *ngIf=" currentPage -1 > 0 "><a (click)="onPage((currentPage -1))">{{currentPage -1}}</a></li>
<li class="active"><a >{{currentPage}}</a></li>
<li *ngIf=" currentPage +1 <= getTotalPages() "><a (click)="onPage((currentPage +1))">{{currentPage +1}}</a></li>
<li *ngIf=" currentPage +2 <= getTotalPages() "><a (click)="onPage((currentPage +2))">{{currentPage +2}}</a></li>
<li *ngIf=" (currentPage -2 <= 0)&&(currentPage +3 <= getTotalPages()) "><a (click)="onPage((currentPage +3))">{{currentPage +3}}</a></li>
<li *ngIf=" (currentPage -1 <= 0)&&(currentPage +4 <= getTotalPages()) "><a (click)="onPage((currentPage +4))">{{currentPage +4}}</a></li>
<li *ngIf="getTotalPages() > currentPage"><a (click)="onPage((getTotalPages()))" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
</ul>
</div>
`
})
export class pagingFormatterNoLoad {
@Input() currentPage: number = 1;
@Input() navigateTo: string;
@Input() term: string='';
@Input() size: number=10;
@Input() totalResults: number = 10;
@Input() params;
@Output() pageChange = new EventEmitter();
constructor () {
}
ngOnInit() {
console.info("In paging -- CurrentPage:"+this.currentPage+" "+"total Pages = "+this.getTotalPages() +" Results num:"+this.totalResults);
}
getTotalPages(){
var i= this.totalResults/this.size;
var integerI=parseInt(''+i);
return parseInt(''+((i==integerI)?i:i+1));
}
onPrev(){
this.currentPage=this.currentPage-1;
this.pageChange.emit({
value: this.currentPage
});
}
onNext(){
this.currentPage=this.currentPage+1;
this.pageChange.emit({
value: this.currentPage
});
}
onPage(pageNum: number){
this.currentPage=pageNum;
this.pageChange.emit({
value: this.currentPage
});
}
}

View File

@ -0,0 +1,23 @@
import {Component, Input} from '@angular/core';
import {OpenaireProperties} from '../openaireProperties';
//Usage Example "<project-title [project]="X" > </project-title>"
@Component({
selector: 'project-title',
template: `
<div class="project-title">
<h5 ><a target="_blank" [href]="url" >{{project.name}} ({{project.funderName}})</a></h5>
</div>
`
})
export class ProjectTitleFormatter {
@Input() project: string[];
private url:string;
constructor () {}
ngOnInit() {
this.url = OpenaireProperties.getsearchLinkToProject() + "?projectId=" + this.project["openaireId"];
}
}

View File

@ -0,0 +1,26 @@
import {Component, Input} from '@angular/core';
//Usage Example "<publication-title [title]="X" [url]="X" > </publication-title>"
@Component({
selector: 'publication-title',
template: `
<div class="publication-title">
<h5 *ngIf="url" ><a target="_blank" href="{{url}}" >{{title}}</a></h5>
<h5 *ngIf="!url" >{{title}}</h5>
</div>
`
})
export class PublicationTitleFormatter {
@Input() title: string[];
@Input() url: string[];
constructor () {}
ngOnInit() {
}
}

View File

@ -0,0 +1,15 @@
export class Claim {
id: string;
sourceType: string;
targetType: string;
sourceId: string;
targetId: string;
date: string;
DOI: string;
project: Project
userMail: string;
}
export class Project{
}

View File

@ -0,0 +1,15 @@
<div class="container">
<div class="row">
<form>
<div class="col-lg-6">
<div class="input-group">
<input #term type="text" class="form-control col-xs-5" placeholder="Search for..." name="keyword" >
<span class="input-group-btn">
<button class="btn btn-default" type="submit" >GO</button>
</span>
</div>
</div>
</form>
</div>
</div>

View File

@ -0,0 +1,15 @@
import {Component} from '@angular/core';
import {Router} from '@angular/router';
import {Observable} from 'rxjs/Observable';
import {Location} from '@angular/common';
@Component({
selector: 'home',
templateUrl: 'home.component.html',
})
export class HomeComponent {
constructor ( private _router: Router, private location: Location) {}
}

View File

@ -0,0 +1,89 @@
export class OpenaireProperties {
//landing Pages
private static baseSearchLink="/"
private static searchLinkToPublication = "publication?articleId=";
private static searchLinkToProject = "project?projectId=";
private static searchLinkToPerson = "person?personId=";
private static searchLinkToDataProvider = "https://beta.openaire.eu/search/dataprovider?datasourceId=";
private static searchLinkToDataset = "dataset?datasetId=";
private static searchLinkToOrganization = "organization?organizationId=";
// Services - APIs
// public claimsAPIURL = "http://rudie.di.uoa.gr:8080/dnet-openaire-connector-service-1.0.0-SNAPSHOT/rest/claimsService/"
private static claimsAPIURL = "http://scoobydoo.di.uoa.gr:8181/dnet-openaire-connector-service-1.0.0-SNAPSHOT/rest/claimsService/";
private static searchAPIURL = "http://astero.di.uoa.gr:8080/dnet-functionality-services-2.0.0-SNAPSHOT/rest/v2.0/api/";
// private searchAPIURL = "http://rudie.di.uoa.gr:8080/dnet-functionality-services-2.0.0-SNAPSHOT/rest/v2.0/api/";
// private searchAPIURL = "http://scoobydoo.di.uoa.gr:8181/dnet-functionality-services-2.0.0-SNAPSHOT/rest/v2.0/api/";
private static searchServiveURL = "http://astero.di.uoa.gr:8080/dnet-functionality-services-2.0.0-SNAPSHOT/";
// private static searchServiveURL = "http://scoobydoo.di.uoa.gr:8181/dnet-functionality-services-2.0.0-SNAPSHOT/";
// private static searchServiveURL = "http://services.openaire.eu:8380/search/";
//private static searchServiveURL = "http://rudie.di.uoa.gr:8080/dnet-functionality-services-2.0.0-SNAPSHOT/";
private static searchCrossrefAPIURL = "http://api.crossref.org/works";
private static searchDataciteAPIURL = "http://search.datacite.org/api";
private static searchOrcidURL = "https://pub.orcid.org/";
// Identifiers
private static pmidURL = "http://www.ncbi.nlm.nih.gov/pubmed/";
private static doiURL = "http://dx.doi.org/";
private static cordisURL = "http://cordis.europa.eu/projects/";
private static pmcURL = "http://europepmc.org/articles/";
//landing Pages' getters
public static getsearchLinkToPublication():string{
return this.baseSearchLink + this.searchLinkToPublication;
}
public static getsearchLinkToDataset():string{
return this.baseSearchLink + this.searchLinkToDataset;
}
public static getsearchLinkToProject():string{
return this.baseSearchLink + this.searchLinkToProject;
}
public static getsearchLinkToPerson():string{
return this.baseSearchLink + this.searchLinkToPerson;
}
public static getsearchLinkToOrganization():string{
return this.searchLinkToOrganization;
}
public static getsearchLinkToDataProvider():string{
return this.searchLinkToDataProvider;
}
// Services - APIs' getters
public static getSearchAPIURL():string{
return this.searchAPIURL;
}
public static getSearchServiceURL():string{
return this.searchServiveURL;
}
public static getClaimsAPIURL():string{
return this.claimsAPIURL;
}
public static getSearchCrossrefAPIURL():string{
return this.searchCrossrefAPIURL;
}
public static getSearchDataciteAPIURL():string{
return this.searchDataciteAPIURL;
}
public static getSearchOrcidURL():string{
return this.searchOrcidURL;
}
// Identifiers' getters
public static getPmidURL():string{
return this.pmidURL;
}
public static getDoiURL():string{
return this.doiURL;
}
public static getCordisURL():string{
return this.cordisURL;
}
public static getPmcURL():string{
return this.pmcURL;
}
}

View File

@ -0,0 +1,131 @@
import {Injectable} from '@angular/core';
import {Jsonp, URLSearchParams,ResponseOptions, RequestOptions, Headers} from '@angular/http';
import {Http, Response} from '@angular/http';
import {Observable} from 'rxjs/Observable';
import {Claim} from '../entities/claim';
import {OpenaireProperties} from '../openaireProperties';
@Injectable()
export class ClaimsService {
private baseUrl;
constructor(private jsonp: Jsonp, private http: Http) {
this.baseUrl = OpenaireProperties.getClaimsAPIURL();
}
private getClaimRequest(size : number, page : number, url :string):any {
console.info('ClaimsService: Claims request: '+url);
return this.http.get( url)
.map(request => <any> request.json())
.do(request => console.info("Get claims: offset = "+(size*(page-1)) + " limit ="+size ))
.catch(this.handleError);
}
getClaims( size : number, page : number, keyword:string, sortby: string, descending: boolean, types: string):any {
console.info('ClaimsService: getClaims ' );
console.info('ClaimsService: Types : '+types );
let url = this.baseUrl +"claims"+"?offset="+(size*(page-1) + "&limit="+size)+"&keyword="+keyword+"&sortby="+sortby+"&descending="+descending+""+types;
return this.getClaimRequest(size,page,url);
}
getClaimsByUser( size : number, page : number, user:string, keyword:string, sortby: string, descending: boolean, types: string):any {
console.info('ClaimsService: getClaims for user : '+user);
let url = this.baseUrl +"users/"+user+"/claims"+"?offset="+(size*(page-1) + "&limit="+size)+"&keyword="+keyword+"&sortby="+sortby+"&descending="+descending+""+types;
return this.getClaimRequest(size,page,url);
}
getClaimsBycontext( size : number, page : number, contextId:string, keyword:string, sortby: string, descending: boolean, types: string):any {
console.info('ClaimsService: getClaims for context : '+contextId);
let url = this.baseUrl +"contexts/"+contextId+"/claims"+"?offset="+(size*(page-1) + "&limit="+size)+"&keyword="+keyword+"&sortby="+sortby+"&descending="+descending+""+types;
return this.getClaimRequest(size,page,url);
}
getClaimsByResult( size : number, page : number, resultId:string, keyword:string, sortby: string, descending: boolean, types: string):any {
console.info('ClaimsService: getClaims for result : '+resultId);
let url = this.baseUrl +"results/"+resultId+"/claims"+"?offset="+(size*(page-1) + "&limit="+size)+"&keyword="+keyword+"&sortby="+sortby+"&descending="+descending+""+types;
return this.getClaimRequest(size,page,url);
}
getClaimsByProject( size : number, page : number, projectId:string, keyword:string, sortby: string, descending: boolean, types: string):any {
console.info('ClaimsService: getClaims for project : '+projectId);
let url = this.baseUrl +"projects/"+projectId+"/claims"+"?offset="+(size*(page-1) + "&limit="+size)+"&keyword="+keyword+"&sortby="+sortby+"&descending="+descending+""+types;
return this.getClaimRequest(size,page,url);
}
deleteClaimById(claimId:string):any{
console.warn('Trying to delete claim with id : '+claimId);
let url = this.baseUrl +"claims/"+claimId;
console.warn('Delete url: '+url);
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.delete( url, options).map(request => <any> request.json())
.do(request => console.info("After delete" ))
.catch(this.handleError);
}
deleteBulk(claimIds:string[]):any{
console.warn('Trying to delete claims with ids : '+claimIds);
var url = "";
for(var claimId of claimIds){
url=url+(url.length >0 ?"&":"")+"claimId="+claimId;
}
url= this.baseUrl +"claims/bulk?"+url;
console.warn('Delete url: '+url);
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.delete( url, options).map(request => <any> request.json())
.do(request => console.info("After delete" ))
.catch(this.handleError);
}
insertBulkClaims(claims):any{
console.warn('Trying toinsert claims : '+claims);
let url = this.baseUrl +"claims/bulk";
let body = JSON.stringify( claims );
console.warn('Json body: : '+body);
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.post(url, body, options)
.map(res => res.json())
.do(request => console.info("Insert Response:"+request.status) )
.catch(this.handleError);
}
insertClaim(claim):any{
console.warn('Trying toinsert claim : '+claim);
let url = this.baseUrl +"claims";
let body = JSON.stringify( claim );
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.post(url, body, options)
.map(res => res.json())
.do(request => console.info("Insert Response:"+request.status) )
.catch(this.handleError);
}
private handleError (error: Response) {
// in a real world app, we may send the error to some remote logging infrastructure
// instead of just logging it to the console
console.error(error);
return Observable.throw(error || 'Server error');
}
getClaim(id:string):any {
let url = this.baseUrl+"claims/"+id;
return new Promise((resolve, reject) => {
this.http.get(url)
.map(res => res.json())
.subscribe(
data => {
resolve(data.data);
},
err => {
reject(err);
}
)
;
});
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -0,0 +1,24 @@
// Our API for demos only
import {fakeDataBase} from './db';
import {fakeDemoRedisCache} from './cache';
// you would use cookies/token etc
var USER_ID = 'f9d98cf1-1b96-464e-8755-bcc2a5c09077'; // hardcoded as an example
// Our API for demos only
export function serverApi(req, res) {
let key = USER_ID + '/data.json';
let cache = fakeDemoRedisCache.get(key);
if (cache !== undefined) {
console.log('/data.json Cache Hit');
return res.json(cache);
}
console.log('/data.json Cache Miss');
fakeDataBase.get()
.then(data => {
fakeDemoRedisCache.set(key, data);
return data;
})
.then(data => res.json(data));
}

View File

@ -0,0 +1,17 @@
var _fakeLRUcount = 0;
export const fakeDemoRedisCache = {
_cache: {},
get: (key) => {
let cache = fakeDemoRedisCache._cache[key];
_fakeLRUcount++;
if (_fakeLRUcount >= 10) {
fakeDemoRedisCache.clear();
_fakeLRUcount = 0;
}
return cache;
},
set: (key, data) => fakeDemoRedisCache._cache[key] = data,
clear: () => fakeDemoRedisCache._cache = {}
};

View File

@ -0,0 +1,7 @@
// Our API for demos only
export const fakeDataBase = {
get() {
let res = { data: 'This fake data came from the db on the server.' };
return Promise.resolve(res);
}
};

View File

@ -0,0 +1,18 @@
// the polyfills must be the first thing imported
import 'angular2-universal-polyfills';
// Angular 2
import { enableProdMode} from '@angular/core';
import { platformUniversalDynamic } from 'angular2-universal';
// enable prod for faster renders
enableProdMode();
import { main } from './main.browser';
// on document ready bootstrap Angular 2
document.addEventListener('DOMContentLoaded', () => {
platformUniversalDynamic().bootstrapModule(main());
});

View File

@ -0,0 +1,29 @@
<!doctype html>
<html lang="en">
<head>
<title>OpenAIRE</title>
<meta charset="UTF-8">
<meta name="description" content="Open Access Infrastructure for Europe ">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="bootstrap/dist/js/bootstrap.min.js" ></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.2/css/bootstrap.min.css" integrity="sha384-y3tfxAZXuh4HwSYylfB+J125MxIs6mR5FOHamPBG064zB+AFeWH94NdvaCBm8qnd" crossorigin="anonymous">
<link rel="stylesheet" href="bootstrap/dist/css/bootstrap.min.css">
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
<!-- Temporarily add here custom style -->
<style>
.custom-hidden-dropdown-menu {position:static !important;}
</style>
<base href="/">
</head>
<body>
<app>
Loading Universal ...
</app>
<script src="/index.js"></script>
</body>
</html>

View File

@ -0,0 +1,72 @@
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { UniversalModule } from 'angular2-universal';
import { App } from './app/app';
/* Feature Modules */
import { LoadingModule } from './app/common/modal/loading.module';
import {ClaimEntityFormatterModule } from './app/common/claimEntityFormatter.module';
//
import {ClaimsModule } from './app/claimPages/claims/claims.module';
//for routing:
import {ClaimsAdminComponent} from './app/claimPages/claims/claimsAdmin.component';
import { routing } from './app/app.routing';
import {Routes, RouterModule} from "@angular/router";
import {Open} from './app/common/modal/open.component';
import {Alert} from './app/common/modal/alert';
import {Loading} from './app/common/modal/loading.component';
import {ClaimsComponent} from './app/claimPages/claims/claims.component';
import {ClaimsService} from './app/services/claims.service';
import {Claim} from './app/entities/claim';
import {pagingFormatterNoLoad} from './app/common/pagingFormatterNoLoad.component';
import {ClaimEntityFormatter} from './app/common/claimEntityFormatter.component';
import {PublicationTitleFormatter} from './app/common/publicationTitleFormatter.component';
import {ProjectTitleFormatter} from './app/common/projectTitleFormatter.component';
import {HomeComponent} from './app/home/home.component';
export function main() {
@NgModule({
bootstrap: [ App ],
declarations: [ App, ClaimsAdminComponent, ClaimsComponent, ClaimEntityFormatter,pagingFormatterNoLoad, Open, ProjectTitleFormatter, PublicationTitleFormatter,HomeComponent, Loading, Alert],
imports: [
UniversalModule,
FormsModule,
routing
],
providers: [ ClaimsService ]
})
//
// //OpenModule, ClaimEntityFormatterModule,ClaimEntityFormatter,
// //ClaimsService
// export function main() {
// @NgModule({
// bootstrap: [ App ],
// declarations: [ App, ClaimsAdminComponent],
// imports: [
// UniversalModule,
// FormsModule,
// ClaimsModule,
// LoadingModule,
//
// routing
// ],
//
// providers: [ ]
//
// })
class MainModule {
}
return MainModule;
}

Some files were not shown because too many files have changed in this diff Show More