making new-ui branch the new trunk

This commit is contained in:
Antonis Lempesis 2021-07-09 10:11:25 +00:00
commit aed9d2c3c9
1422 changed files with 335189 additions and 0 deletions

12
.editorconfig Normal file
View File

@ -0,0 +1,12 @@
# EditorConfig is awesome: http://EditorConfig.org
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true

55
.gitignore vendored Normal file
View File

@ -0,0 +1,55 @@
# Logs
logs
*.log
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Users Environment Variables
.lock-wscript
# OS generated files #
.DS_Store
ehthumbs.db
Icon?
Thumbs.db
# Node Files #
/node_modules
/bower_components
# Coverage #
/coverage/
# Typing #
/src/typings/tsd/
/typings/
/tsd_typings/
# Dist #
/dist
/public/__build__/
/src/*/__build__/
__build__/**
.webpack.json
# Doc #
/doc/
# IDE #
.idea/
*.swp

49
README.md Executable file
View File

@ -0,0 +1,49 @@
# UOA Repository Manager UI
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 6.0.8 (Angular version 6.1.10).
## Minimum requirements for installing and building the project
[Node.js](https://nodejs.org/en/) version 8.x or 10.x.<br>
[npm client](https://docs.npmjs.com/cli/install) command line interface (it is installed with Node.js by default).
## Installing the project
After checking out (or updating) the repository enter the created folder and run `npm ci`.
This will install the exact versions of the dependencies as mentioned in the `package-lock.json` file (inside the root folder).
## Build for production
Run `npm run build` (equivalent of `ng build --prod`) to build the project. The build artifacts will be stored in the `dist/uoa-repository-manager-ui` directory.
## Deploy project to nginx server
Run `tar -czvf dist.tar.gz dist/` to generate a compressed `.gz` file containing the built angular folder<br>
Run `scp dist.tar.gz path/to/server/` to copy the compressed file to the server.<br>
Connect to server (`ssh user@server.ip.address`).<br>
Uncompress `dist.tar.gz` file.<br>
Navigate to the root folder of the server.
Copy the contents of the uncompressed dist/uoa-repository-manager-ui folder
into the `uoa-repository-manager-dashboard` folder (superuser privileges are normally required for this action).<br>
## Other topics
### Development server
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.<br>
Run `npm run start:proxy` (equivalent of `ng serve --proxy-config proxy.conf.json`) instead, to run the project using a development proxy. To configure the proxy modify the `proxy.conf.json` file (inside the root folder).
### Code scaffolding
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
### Running unit tests
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
### Running end-to-end tests
Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
### Further help
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).

154
angular.json Executable file
View File

@ -0,0 +1,154 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"uoa-repository-manager-ui": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {},
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/uoa-repository-manager-ui",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.scss"
],
"scripts": [
"node_modules/jquery/dist/jquery.min.js",
"node_modules/jquery-bez/lib/jquery.bez.js",
"node_modules/uikit/dist/js/uikit.min.js",
"node_modules/uikit/dist/js/uikit-icons.min.js",
"src/assets/js/altair_admin_common.min.js",
"src/assets/js/common.min.js",
"src/assets/js/pages/forms_wizard.js"
]
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true
},
"beta": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.beta.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "uoa-repository-manager-ui:build",
"port": 4200,
"host": "localhost"
},
"configurations": {
"production": {
"browserTarget": "uoa-repository-manager-ui:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "uoa-repository-manager-ui:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.spec.json",
"karmaConfig": "src/karma.conf.js",
"styles": [
"src/styles.scss"
],
"scripts": [],
"assets": [
"src/favicon.ico",
"src/assets"
]
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"src/tsconfig.app.json",
"src/tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**"
]
}
}
}
},
"uoa-repository-manager-ui-e2e": {
"root": "e2e/",
"projectType": "application",
"architect": {
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "uoa-repository-manager-ui:serve"
},
"configurations": {
"production": {
"devServerTarget": "uoa-repository-manager-ui:serve:production"
}
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": "e2e/tsconfig.e2e.json",
"exclude": [
"**/node_modules/**"
]
}
}
}
}
},
"defaultProject": "uoa-repository-manager-ui"
}

28
e2e/protractor.conf.js Executable file
View File

@ -0,0 +1,28 @@
// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts
const { SpecReporter } = require('jasmine-spec-reporter');
exports.config = {
allScriptsTimeout: 11000,
specs: [
'./src/**/*.e2e-spec.ts'
],
capabilities: {
'browserName': 'chrome'
},
directConnect: true,
baseUrl: 'http://localhost:4200/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
print: function() {}
},
onPrepare() {
require('ts-node').register({
project: require('path').join(__dirname, './tsconfig.e2e.json')
});
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
}
};

14
e2e/src/app.e2e-spec.ts Executable file
View File

@ -0,0 +1,14 @@
import { AppPage } from './app.po';
describe('workspace-project App', () => {
let page: AppPage;
beforeEach(() => {
page = new AppPage();
});
it('should display welcome message', () => {
page.navigateTo();
expect(page.getParagraphText()).toEqual('Welcome to uoa-repository-manager-ui!');
});
});

11
e2e/src/app.po.ts Executable file
View File

@ -0,0 +1,11 @@
import { browser, by, element } from 'protractor';
export class AppPage {
navigateTo() {
return browser.get('/');
}
getParagraphText() {
return element(by.css('app-root h1')).getText();
}
}

13
e2e/tsconfig.e2e.json Executable file
View File

@ -0,0 +1,13 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/app",
"module": "commonjs",
"target": "es5",
"types": [
"jasmine",
"jasminewd2",
"node"
]
}
}

22854
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

60
package.json Executable file
View File

@ -0,0 +1,60 @@
{
"name": "uoa-repository-manager-ui",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"start:proxy": "ng serve --proxy-config proxy.conf.json",
"build": "rm -rf dist; ng build --prod",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
"private": true,
"dependencies": {
"@angular/animations": "^6.0.3",
"@angular/common": "^6.0.3",
"@angular/compiler": "^6.0.3",
"@angular/core": "^6.0.3",
"@angular/forms": "^6.0.3",
"@angular/http": "^6.0.3",
"@angular/platform-browser": "^6.0.3",
"@angular/platform-browser-dynamic": "^6.0.3",
"@angular/router": "^6.0.3",
"altair": "^1.0.0",
"angular2-cookie-law": "^6.0.4",
"bootstrap": "^4.1.3",
"core-js": "^2.5.4",
"highcharts": "^7.2.1",
"highcharts-angular": "^2.4.0",
"jquery": "^3.4.1",
"jquery-bez": "^1.0.11",
"ngx-bootstrap": "^3.0.1",
"ngx-matomo": "^0.1.2",
"rxjs": "6.3.3",
"uikit": "^3.0.0-rc.19",
"zone.js": "^0.8.26"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.6.8",
"@angular/cli": "~6.0.8",
"@angular/compiler-cli": "^6.0.3",
"@angular/language-service": "^6.0.3",
"@types/jasmine": "~2.8.6",
"@types/jasminewd2": "~2.0.3",
"@types/node": "~8.9.4",
"node-sass": "^4.0.0",
"codelyzer": "~4.2.1",
"jasmine-core": "~2.99.1",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~4.0.0",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "~2.0.0",
"karma-jasmine": "~1.1.1",
"karma-jasmine-html-reporter": "^0.2.2",
"protractor": "^5.4.1",
"ts-node": "~5.0.1",
"tslint": "~5.9.1",
"typescript": "~2.7.2"
}
}

8
proxy.conf.json Executable file
View File

@ -0,0 +1,8 @@
{
"/uoa-repository-manager-service/*": {
"target": "http://localhost:8480",
"secure": false,
"logLevel": "debug",
"changeOrigin": true
}
}

100
src/app/app-routing.module.ts Executable file
View File

@ -0,0 +1,100 @@
import { RouterModule, Routes } from '@angular/router';
import { NgModule } from '@angular/core';
import { HomeComponent } from './pages/landing/home/home.component';
import { AuthGuardService } from './services/auth-guard.service';
import { ForbiddenPageComponent } from './shared/reusablecomponents/403-forbidden-page.component';
import { EmptyPageComponent } from "./pages/emptypage/empty-page.component";
import { JoinComponent } from "./pages/join/join.component";
import { AboutComponent } from "./pages/landing/about/about.component";
const appRoutes: Routes = [
{
path: '',
redirectTo: '/home',
pathMatch: 'full'
},
{
path: 'home',
component: HomeComponent
},
{
path: 'about',
component: AboutComponent
},
{
path: 'join',
component: JoinComponent,
canActivate: [AuthGuardService]
},
{
path: 'emptyPage',
component: EmptyPageComponent,
canActivate: [AuthGuardService]
},
{
path: 'repository',
loadChildren: './pages/repository/repository.module#RepositoryModule',
// loadChildren: () => import('./pages/repository/repository.module').then(m => m.RepositoryModule),
canActivate: [AuthGuardService]
},
{
path: 'repositoryAdmin',
loadChildren: './pages/repository/repository.module#RepositoryModule',
// loadChildren: () => import('./pages/repository/repository.module').then(m => m.RepositoryModule),
canActivate: [AuthGuardService]
},
// {
// path: 'dashboard',
// component: DashboardComponent,
// canActivate: [AuthGuardService]
// },
{
path: 'sources',
loadChildren: './pages/sources/sources.module#SourcesModule',
canActivate: [AuthGuardService]
},
{
path: 'compatibility',
loadChildren: './pages/compatibility/compatibility.module#CompatibilityModule'
},
{
path: 'content',
loadChildren: './pages/content/content.module#ContentModule',
canActivate: [AuthGuardService]
},
// {
// path: 'getImpact',
// loadChildren: './pages/metrics/metrics.module#MetricsModule',
// canActivate: [AuthGuardService]
// },
{
path: 'admin',
loadChildren: './pages/adminPg/adminPg.module#AdminPgModule',
},
{
path: '403-forbidden',
component: ForbiddenPageComponent
},
// {
// path: '',
// redirectTo: '/home',
// pathMatch: 'full'
// },
{
//fixme redirect to 404
path: '**',
redirectTo: '/403-forbidden',
// component: ForbiddenPageComponent
}
];
@NgModule ({
imports: [RouterModule.forRoot(appRoutes)],
exports: [RouterModule]
})
export class AppRoutingModule {}

0
src/app/app.component.css Executable file
View File

75
src/app/app.component.html Executable file
View File

@ -0,0 +1,75 @@
<div *ngIf="!isLandingRoute() ; else landing" class="sidebar_main_swipe" [class.sidebar_main_active]="open">
<!--<div *ngIf="!isHomeRoute() ; else home" class="sidebar_main_open sidebar_main_swipe uk-height-1-1">-->
<top-menu-dashboard></top-menu-dashboard>
<side-menu></side-menu>
<div id="hide_controls">
<div id="toggle" [class.sidebar_main_open]="open" (click)="toggleOpen($event)">
<i class="material-icons">play_circle_filled</i>
<span *ngIf="open" class="uk-margin-small-left">Hide Controls</span>
</div>
</div>
<router-outlet></router-outlet>
</div>
<ng-template #landing>
<top-menu-landing></top-menu-landing>
<router-outlet></router-outlet>
<footer></footer>
</ng-template>
<!--<div class="uk-offcanvas-content">-->
<!--<top-menu></top-menu>-->
<!--<router-outlet></router-outlet>-->
<!--<footer></footer>-->
<!--<cookie-law position="bottom">-->
<!--OpenAIRE uses cookies in order to function properly.<br>-->
<!--Cookies are small pieces of data that websites store in your browser to allow us to give you the best browsing experience possible.-->
<!--By using the OpenAIRE portal you accept our use of cookies. <a href="http://ec.europa.eu/ipg/basics/legal/cookies/index_en.htm" target="_blank"> Read more <span class="uk-icon">-->
<!--<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" icon="chevron-right" ratio="1"><polyline fill="none" stroke="#000" stroke-width="1.03" points="7 4 13 10 7 16"></polyline></svg>-->
<!--</span></a>-->
<!--</cookie-law>-->
<!--</div>-->
<!-- Matomo -->
<!--<script type="text/javascript">
var _paq = _paq || [];
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="//https://analytics.openaire.eu/";
_paq.push(['setTrackerUrl', u+'piwik.php']);
_paq.push(['setSiteId', piwikUrl]);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
})();
</script>-->
<!-- End Matomo Code -->
<!--&lt;!&ndash; Terms of Use (modal) &ndash;&gt;-->
<!--<confirmation-dialog #subscribeToTermsModal [title]=modalTitle [isModalShown]=isModalShown-->
<!-- [confirmActionButton]=modalButton (emitObject)="updateTerms()">-->
<!-- <form class="" [formGroup]="agreementForm">-->
<!-- <div formArrayName="terms">-->
<!-- <table class="table">-->
<!-- <tr class="uk-text-nowrap">Do you agree with the <a href="https://zenodo.org/record/1446384#.XiGIAdmxU5n" target="_blank">terms of use</a>?</tr>-->
<!-- <tbody>-->
<!-- <tr class="el-item" *ngFor="let term of terms.controls; let i=index">-->
<!--&lt;!&ndash; {{term.get('accept').value}}&ndash;&gt;-->
<!-- <br> {{term.get('name').value}} <br>-->
<!-- <div [formGroupName]="i">-->
<!-- <label>-->
<!-- <input id="i" type="checkbox" formControlName="accept"> Yes, I agree to the terms of use.-->
<!-- </label>-->
<!-- </div>-->
<!-- </tr>-->
<!-- </tbody>-->
<!-- </table>-->
<!-- </div>-->
<!-- </form>-->
<!-- &lt;!&ndash; <pre>{{this.agreementForm.value | json}}</pre>&ndash;&gt;-->
<!--</confirmation-dialog>-->

27
src/app/app.component.spec.ts Executable file
View File

@ -0,0 +1,27 @@
import { TestBed, async } from '@angular/core/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
AppComponent
],
}).compileComponents();
}));
it('should create the app', async(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app).toBeTruthy();
}));
it(`should have as title 'app'`, async(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app.title).toEqual('app');
}));
it('should render title in a h1 tag', async(() => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('h1').textContent).toContain('Welcome to uoa-repository-manager-ui!');
}));
});

185
src/app/app.component.ts Executable file
View File

@ -0,0 +1,185 @@
import {Component, OnInit, ViewChild} from '@angular/core';
import { NavigationEnd, Router, RoutesRecognized } from '@angular/router';
import { AuthenticationService } from './services/authentication.service';
import { environment } from '../environments/environment';
import { MatomoInjector, MatomoTracker } from 'ngx-matomo';
import { ConfirmationDialogComponent } from './shared/reusablecomponents/confirmation-dialog.component';
import { RepositoryService } from './services/repository.service';
import { RepositorySnippet } from './domain/typeScriptClasses';
import {FormBuilder, FormGroup, FormControl, FormArray} from '@angular/forms';
import {element} from 'protractor';
import {timestamp} from 'rxjs/operators';
@Component({
selector: 'oa-repo-manager',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
reposOfUser: RepositorySnippet[] = [];
modalTitle = 'Terms of Use';
isModalShown: boolean;
modalButton = 'OK';
agreementForm = this.fb.group({
terms: this.fb.array([])
});
consentTermsOfUseDate: Date;
@ViewChild('subscribeToTermsModal')
public subscribeToTermsModal: ConfirmationDialogComponent;
open: boolean = true;
constructor(private router: Router,
private authService: AuthenticationService,
private matomoInjector: MatomoInjector,
private matomoTracker: MatomoTracker,
private repositoryService: RepositoryService,
private fb: FormBuilder) {
console.log('21-06-2019. Fixed matomo to log userIds?');
let piwikUrl;
if (window.location.origin.includes('beta')) {
// piwikUrl = 'https://analytics.openaire.eu/piwik.php?idsite=92&rec=1';
piwikUrl = '92';
} else if (window.location.origin.includes('localhost:4200') ||
window.location.origin.includes('athenarc')) {
// piwikUrl = 'https://analytics.openaire.eu/piwik.php?idsite=92&rec=1';
piwikUrl = '9222222';
} else {
// piwikUrl = 'https://analytics.openaire.eu/piwik.php?idsite=111&rec=1';
piwikUrl = '111';
}
this.matomoInjector.init('https://analytics.openaire.eu/', piwikUrl);
/*disabling console.log in production*/
if ( environment.production === true ) {
console.log = function () {};
}
// URL of the SPA to redirect the user to after login
// this.authService.redirectUrl = "/dashboard";
if (window.location.pathname.includes('/compatibility/browseHistory/')) {
this.authService.redirectUrl = window.location.pathname;
console.log('redirectUrl', this.authService.redirectUrl);
}
this.authService.tryLogin();
}
getReposOfUser(): void {
this.repositoryService.getRepositoriesOfUser()
.subscribe(
repos => { this.reposOfUser = repos; },
error => { console.log(error); },
() => {
console.log(this.reposOfUser);
this.reposOfUser.forEach( repo => {
// TODO: change !repo.consentTermsOfUse check when it gets a non-null value
if (this.authService.isLoggedIn && !repo.consentTermsOfUse) {
this.addTerm(repo.officialname, repo.id, repo.consentTermsOfUse);
this.isModalShown = true;
}
});
}
);
}
updateTerms() {
/* update consentTermsOfUse, consentTermsOfUseDate(?)
depending on what value will consentTermsOfUse hold
Also what type of consentTermsOfUse will be? boolean or string */
for (let i = 0; i < this.terms.length; i++) {
const id = this.terms.controls[i].get('id').value;
if (this.terms.controls[i].get('accept').value === true) {
console.log(`Agreed to the Terms of Use for: `, id);
}
}
this.consentTermsOfUseDate = new Date(Date.now());
console.log(this.consentTermsOfUseDate);
console.log('will POST when backend is ready');
}
ngOnInit() {
this.router.events.subscribe((evt) => {
if (!(evt instanceof NavigationEnd)) {
return;
}
if (this.authService.isLoggedIn) {
this.matomoTracker.setUserId(this.authService.getUserEmail());
}
window.scrollTo(0, 0);
});
// this.getReposOfUser();
}
addTerm(name: string, id: string, consent: string) {
this.terms.push(this.newTerm(name, id, consent));
}
newTerm(name: string, id: string, consent: string): FormGroup {
return this.fb.group({
id: [id],
name: [name],
accept: [(consent ? consent : true)]
});
}
get terms() {
return this.agreementForm.get('terms') as FormArray;
}
isLandingRoute() {
// console.log('Is home route? Route is: ' + this.router.url);
return (this.router.url === '/') || (this.router.url === '/home') || (this.router.url === '/about');
}
public toggleOpen(event: MouseEvent) {
event.preventDefault();
this.open = !this.open;
}
// ngAfterContentInit() {
//
// // this.loadScript('assets/js/common.js');
// // this.loadScript('assets/js/uikit_custom.js');
// // this.loadScript('assets/js/altair_admin_common.js');
// this.loadScript('assets/js/altair_admin_common.min.js');
//
// // setTimeout( () => {
// // // this.loadScript('assets/js/common.js');
// // // this.loadScript('assets/js/uikit_custom.js');
// // this.loadScript('assets/js/altair_admin_common.min.js');
// // }, 2000);
//
// // $.getScript('assets/js/altair_admin_common.min.js');
//
//
//
// // // Load the script
// // // var self = this;
// //
// // var script = <HTMLScriptElement>document.createElement("SCRIPT");
// // script.src = 'assets/js/altair_admin_common.min.js';
// // script.type = 'text/javascript';
// // // self.script = <HTMLScriptElement>document.createElement("SCRIPT");
// // // self.script.src = '../Content/js/settings.js';
// // // self.script.type = 'text/javascript';
// // document.getElementsByTagName("head")[0].appendChild(script);
// }
//
// public loadScript(url) {
// console.log('preparing to load...')
// let node = document.createElement('script');
// node.src = url;
// node.type = 'text/javascript';
// document.getElementsByTagName('head')[0].appendChild(node);
// }
}

68
src/app/app.module.ts Executable file
View File

@ -0,0 +1,68 @@
import { AppComponent } from './app.component';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
import { ReusableComponentsModule } from './shared/reusablecomponents/reusable-components.module';
import { CookieLawModule } from './shared/reusablecomponents/cookie-law/cookie-law.module';
import { AppRoutingModule } from './app-routing.module';
import { AuthenticationInterceptor } from './services/authentication-interceptor';
import { BrokerService } from './services/broker.service';
import { MonitorService } from './services/monitor.service';
import { PiwikService } from './services/piwik.service';
import { RepositoryService } from './services/repository.service';
import { ValidatorService } from './services/validator.service';
import { UsagestatsService } from './services/usagestats.service';
import { StatisticsService } from './services/statistics.service';
import { AuthGuardService } from './services/auth-guard.service';
import { AuthenticationService } from './services/authentication.service';
import { HomeComponent } from './pages/landing/home/home.component';
import { MatomoModule } from 'ngx-matomo';
import { DashboardService } from "./services/dashboard.service";
import { EmptyPageComponent } from "./pages/emptypage/empty-page.component";
import { SharedService } from "./services/shared.service";
import { JoinComponent } from "./pages/join/join.component";
import { AboutComponent } from "./pages/landing/about/about.component";
@NgModule({
declarations: [
AppComponent,
HomeComponent,
AboutComponent,
EmptyPageComponent,
JoinComponent
],
imports: [
BrowserModule,
NoopAnimationsModule,
FormsModule,
ReactiveFormsModule,
HttpClientModule,
ReusableComponentsModule,
CookieLawModule,
MatomoModule,
AppRoutingModule
],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: AuthenticationInterceptor,
multi: true
},
BrokerService,
MonitorService,
PiwikService,
RepositoryService,
DashboardService,
ValidatorService,
UsagestatsService,
StatisticsService,
AuthGuardService,
AuthenticationService,
SharedService
],
bootstrap: [AppComponent]
})
export class AppModule { }

1
src/app/domain/job-types.ts Executable file
View File

@ -0,0 +1 @@
export const jobTypes = ['Compatibility Test', 'Registration Request', 'Workflow Request'];

193
src/app/domain/oa-description.ts Executable file
View File

@ -0,0 +1,193 @@
/*
* created by myrto 12/2017
*/
/* class copied from omtd-platform git repository */
/* THE DESCRIPTION TEXTS PROBABLY NEED REVIEWING ! */
export class Description {
desc: string;
label: string;
mandatory: boolean;
recommended: boolean;
}
/* Description of the repository interface repeating form */
export const interfaceFormDesc = {
desc : 'Form for updating or creating new interfaces for your repository/journal',
label : 'Interface',
mandatory : true,
recommended : false
};
/* Desription of the Datasource Info Forms Fields */
export const softwarePlatformDesc = {
desc: 'The typology used by your repository/journal.\nIf you use a typology not found in the drop-down list,\nyou can enter a custom name in the field below.',
label: 'Software Platform (*)',
mandatory: true,
recommended: false
};
export const platformNameDesc = {
desc: 'The typology used by your repository/journal.\nIf you use a typology not found in the above drop-down list,\nyou can enter a custom name here.',
label: '',
mandatory: true,
recommended: false
};
export const officialNameDesc = {
desc: 'Your repository\'s/journal\'s official name.',
label: 'Official Name (*)',
mandatory: true,
recommended: false
};
export const issnDesc = {
desc: 'Input your journal\'s issn (www.issn.org)',
label: 'ISSN (*)',
mandatory: true,
recommended: false
};
export const eissnDesc = {
desc: 'Input your journal\'s eissn, if it has one (www.issn.org)',
label: 'EISSN',
mandatory: false,
recommended: false
};
export const lissnDesc = {
desc: 'Input your journal\'s lissn, if it has one (www.issn.org)',
label: 'LISSN',
mandatory: false,
recommended: false
};
export const repoDescriptionDesc = {
desc: 'A description of your repository/journal',
label: 'Description (*)',
mandatory: true,
recommended: false
};
export const countryDesc = {
desc: 'The country where your repository/journal is located',
label: 'Country (*)',
mandatory: true,
recommended: false
};
export const longtitudeDesc = {
desc: 'The (approximate) longtitude of your repository/journal\'s location',
label: 'Longtitude (*)',
mandatory: true,
recommended: false
};
export const latitudeDesc = {
desc: 'The (approximate) latitude of your repository/journal\'s location',
label: 'Latitude (*)',
mandatory: true,
recommended: false
};
export const websiteUrlDesc = {
desc: 'The main page of your repository/journal\'s website',
label: 'Entry URL (*)',
mandatory: true,
recommended: false
};
export const institutionNameDesc = {
desc: 'The institution that your repository belongs to',
label: 'Institution (*)',
mandatory: true,
recommended: false
};
export const englishNameDesc = {
desc: 'Your repository/journal\'s name in english',
label: 'English Name (*)',
mandatory: true,
recommended: false
};
export const logoUrlDesc = {
desc: 'A link to an image file containing your repository/journal\'s logo',
label: 'Logo URL',
mandatory: false,
recommended: false
};
export const timezoneDesc = {
desc: 'The timezone of the area where your repository/ journal is located',
label: 'Timezone (*)',
mandatory: true,
recommended: false
};
export const datasourceTypeDesc = {
desc: 'The type of your repository',
label: 'Repository Type (*)',
mandatory: true,
recommended: false
};
export const journalTypeDesc = {
desc: 'The type of your journal',
label: 'Journal Type (*)',
mandatory: true,
recommended: false
};
export const aggregatorTypeDesc = {
desc: 'The type of your aggregator',
label: 'Aggregator Type (*)',
mandatory: true,
recommended: false
};
export const adminEmailDesc = {
desc: 'The email address of the repository/journal\'s administrator',
label: 'Admin Email (*)',
mandatory: true,
recommended: false
};
export const baseUrlDesc = {
desc: 'The url that handles the external OAI-PMH requests for the repository/journal.\nIf you are not sure about the base URL of the repository/journal you want to register,\nplease contact the repository/journal\s administrator.',
label: 'Base URL',
mandatory: true,
recommended: false
};
export const existingValSetDesc = {
desc: 'The main set that contains EC or other funder records and will be used for validation.\nIf you are using the OJS plugin make sure to specify it correctly.',
label: 'Available validation sets',
mandatory: false,
recommended: false
};
export const customValSetDesc = {
desc: 'If the validation set you want to use is not in the drop list above, enter a custom one here.',
label: 'Custom validation set',
mandatory: false,
recommended: false
};
export const compatibilityLevelDesc = {
desc: 'Choose your desired compatibility level from the list',
label: 'Desired Compatibility Level',
mandatory: true,
recommended: false
};
export const commentDesc = {
desc: 'Add your comments regarding the interface.',
label: 'Comments',
mandatory: false,
recommended: false
};

44
src/app/domain/page-content.ts Executable file
View File

@ -0,0 +1,44 @@
/**
* Created by stefania on 7/17/17.
*/
import {PiwikInfo} from './typeScriptClasses';
export class PageContent {
content: PositionContents;
route: string;
_id: string;
name: string;
}
export interface PositionContents {
top: Content[];
right: Content[];
bottom: Content[];
left: Content[];
}
export interface Content {
_id: string;
page: Page | string;
placement: string;
order: number;
content: string;
isActive: boolean;
}
export interface Page {
_id: string;
route: string;
name: string;
}
export class PiwikInfoPage {
total: number;
from: number;
to: number;
results: PiwikInfo[];
}

View File

@ -0,0 +1,99 @@
/* Service Down Message */
export const noServiceMessage = 'The service is not available at the moment.';
/* Repositories Messages */
export const loadingUserRepoInfoError = 'Failed to load information on your registered repositories';
export const loadingUserRepoInfoEmpty = 'You have not yet registered any repositories';
export const reposRetrievalError = 'The repositories can not be retrieved at the moment';
export const noRepositoriesFound = 'No Datasources were found';
export const loadingReposMessage = 'Retrieving repositories ...';
export const noRepositoryChosenMsg = 'You need to select a repository first.';
export const loadingRepoMessage = 'Retrieving repository information ...';
export const loadingRepoError = 'System error retrieving repository info';
export const loadingInterfacesError = 'System error retrieving interfaces';
export const loadingAggregationHistory = 'Retrieving aggregation history ...';
export const loadingAggregationHistoryError = 'System error retrieving repository aggregation history.';
export const noAggregationHistory = 'There is no aggregation history for this repository at the moment';
/* Interfaces Messages */
export const noInterfacesSaved = 'You have to create at least one interface.';
export const errorsInInterfaces = 'There are still invalid interfaces. Please correct or remove them.';
export const nonRemovableInterface = 'This interface can not be removed!';
/* Rules Messages */
export const loadingRuleSets = 'Retrieving sets of rules ...';
export const loadingRuleSetsError = 'The rule sets can not be retrieved at the moment';
export const noRuleSets = 'No rule sets were found';
export const noContentRulesResults = 'No content rules were tested';
export const noUsageRulesResults = 'No usage rules were tested';
export const didntSelectRules = 'You need to select at least one rule';
export const didntSelectCrisEntities = 'You need to select at least one entity';
/* Loading Validation Sets Messages */
export const loadingValSets = 'Retrieving validation sets ...';
export const loadingValSetsError = 'The validation sets can not be retrieved at the moment';
/* Jobs of User */
export const loadingUserJobs = 'Retrieving job results ...';
export const loadingUserJobsError = 'Your job results can not be retrieved at the moment';
export const noUserJobsFound = 'No stored jobs found';
export const loadingJobSummary = 'Retrieving job summary ...';
export const loadingJobSummaryError = 'The job summary can not be retrieved at the moment';
export const submittingJob = 'Submitting the new job';
export const submittingJobError = 'The job could not be submitted';
/* Loading Topics Messages */
export const loadingTopics = 'Retrieving topics for the datasource...';
export const loadingTopicsError = 'Failed to load the topics for your datasource';
export const noTopicsFound = 'No topics were found for this datasource';
/* Loading Events Messages */
export const loadingEvents = 'Retrieving events for topic ...';
export const loadingEventsError = 'Failed to retrieve events';
export const noEventsForTopic = 'No events were found for this topic';
export const noEventsWithParams = 'No events were found with the given parameters';
/* Loading Subscriptions Messages */
export const loadingSubscriptions = 'Retrieving subscriptions ...';
export const noSubscriptionsFound = 'No subscriptions found for your account';
export const deletingSubscription = 'Deleting subscription ...';
export const deletingSubscriptionError = 'Failed to delete your subscription';
export const deletingSubscriptionSuccess = 'The subscription was deleted successfully';
export const subscribingToEvents = 'Subscribing to events ...';
export const subscribingToEventsError = 'Failed to subscribe you to the chosen events';
export const subscribingToeventsSuccess = 'The subscription was submitted successfully';
export const subscribingChooseFrequency = 'Please choose a frequency for the notifications';
/* Piwik Messages */
export const loadingMetrics = 'Loading diagrams ...';
export const loadingMetricsError = 'Failed to load the metrics for this repository';
export const enablingMetrics = 'Enabling metrics for this repository...';
export const enabledMetricsSuccess = 'The metrics for this repository were enabled';
export const enabledMetricsError = 'System error enabling metrics for this repository.';
export const validatePiwikSiteSuccess = 'The piwik site was approved.';
/* Forms validation Messages */
export const formInfoLoading = 'Loading information';
export const formInterfacesLoading = 'Loading interfaces';
export const formSubmitting = 'Saving changes ...';
export const formErrorRequiredFields = 'All the fields marked with (*) are mandatory';
export const formErrorInvalidFields = 'There are invalid fields';
export const formErrorWasntSaved = 'The form could not be submitted';
let errorRegisterRepo = 'Due to an error, the registration can\'t be finished. ';
errorRegisterRepo = errorRegisterRepo + 'Please contact "helpdesk@openaire.eu" for support. ';
errorRegisterRepo = errorRegisterRepo + 'We\'re sorry for the inconvenience.';
export const formErrorRegisterRepo = errorRegisterRepo;
export const formSuccessUpdatedRepo = 'The datasource was updated successfully.';
export const formSuccessRegisteredDatasource = 'The datasource was registered successfully';
// export const formSuccessAddedInterface = 'The interface was added successfully.';
// export const formSuccessUpdatedInterface = 'The interface was updated successfully.';
export const formSuccessAddedInterface = 'The harvesting settings are valid!';
export const formSuccessUpdatedInterface = 'The harvesting settings are valid!';
/* BaseUrl validation Messages */
export const didntChooseBaseUrl = 'You need to select a base URL';
export const invalidCustomBaseUrl = 'The base URL could not be confirmed. Μake sure that you are using the correct protocol ("http" or "https"), as the service is currently unable to follow url redirects. If the warning persists, leave us a note in the comments section. We will check your interface and contact you if there are any problems.';
export const identifyingUrl = 'Identifying Url ...';

40
src/app/domain/timezones.ts Executable file
View File

@ -0,0 +1,40 @@
export const timezones = [
{ offset: -12.0, name: '[GMT - 12:00] United States Minor Outlying Islands' },
{ offset: -11.0, name: '[GMT - 11:00] United States, New Zealand' },
{ offset: -10.0, name: '[GMT - 10:00] Honolulu, Papeete...' },
{ offset: -9.5, name: '[GMT - 09:30] French Polynesia' },
{ offset: -9.0, name: '[GMT - 09:00] Anchorage...' },
{ offset: -8.0, name: '[GMT - 08:00] Los Angeles, Vancouver, Tijuana...' },
{ offset: -7.0, name: '[GMT - 07:00] Phoenix, Denver, Calgary, Ciudad Juárez...' },
{ offset: -6.0, name: '[GMT - 06:00] Chicago, Mexico City, Guatemala City, Tegucigalpa, Managua, Winnipeg, San José, San Salvador...' },
{ offset: -5.0, name: '[GMT - 05:00] New York, Toronto, Havana, Lima, Bogotá, Kingston...' },
{ offset: -4.0, name: '[GMT - 04:00] Santiago, Santo Domingo, Manaus, Caracas, La Paz, Asunción, Halifax...' },
{ offset: -3.5, name: '[GMT - 03:30] St. Johns...' },
{ offset: -3.0, name: '[GMT - 03:00] São Paulo, Buenos Aires, Montevideo...' },
{ offset: -2.0, name: '[GMT - 02:00] Brazil, United Kingdom...' },
{ offset: -1.0, name: '[GMT - 01:00] Praia, Ponta Delgada...' },
{ offset: 0.0, name: '[GMT] London, Dublin, Lisbon, Accra, Dakar...' },
{ offset: 1.0, name: '[GMT + 01:00] Berlin, Rome, Paris, Madrid, Vienna, Warsaw, Lagos, Kinshasa, Luanda, Algiers, Casablanca...' },
{ offset: 2.0, name: '[GMT + 02:00] Cairo, Khartoum, Johannesburg, Athens, Kiev, Bucharest, Lubumbashi, Jerusalem...' },
{ offset: 3.0, name: '[GMT + 03:00] Moscow, Istanbul, Riyadh, Baghdad, Nairobi, Minsk, Doha...' },
{ offset: 3.5, name: '[GMT + 03:30] Tehran...' },
{ offset: 4.0, name: '[GMT + 04:00] Dubai, Baku, Samara...' },
{ offset: 4.5, name: '[GMT + 04:30] Kabul...' },
{ offset: 5.0, name: '[GMT + 05:00] Karachi, Tashkent, Yekaterinburg...' },
{ offset: 5.5, name: '[GMT + 05:30] Mumbai, Delhi, Colombo...' },
{ offset: 5.75, name: '[GMT + 05:45] Kathmandu...' },
{ offset: 6.0, name: '[GMT + 06:00] Dhaka, Almaty, Omsk...' },
{ offset: 6.5, name: '[GMT + 06:30] Yangon...' },
{ offset: 7.0, name: '[GMT + 07:00] Jakarta, Bangkok, Ho Chi Minh City, Krasnoyarsk...' },
{ offset: 8.0, name: '[GMT + 08:00] Shanghai, Beijing, Hong Kong, Kuala Lumpur, Singapore, Taipei, Perth, Manila, Makassar, Irkutsk...' },
{ offset: 8.75, name: '[GMT + 08:45] Australia' },
{ offset: 9.0, name: '[GMT + 09:00] Tokyo, Seoul, Pyongyang, Ambon, Yakutsk...' },
{ offset: 9.5, name: '[GMT + 09:30] Adelaide, Darwin...' },
{ offset: 10.0, name: '[GMT + 10:00] Sydney, Melbourne, Port Moresby, Vladivostok...' },
{ offset: 10.5, name: '[GMT + 10:30] Australia (New South Wales)...' },
{ offset: 11.0, name: '[GMT + 11:00] Nouméa, Magadan...' },
{ offset: 12.0, name: '[GMT + 12:00] Auckland, Suva, Petropavlovsk-Kamchatsky...' },
{ offset: 12.75, name: '[GMT + 12:45] New Zealand (Chatham Islands)...' },
{ offset: 13.0, name: '[GMT + 13:00] Kiribati (Phoenix Islands), New Zealand (Tokelau), Samoa, Tonga' },
{ offset: 14.0, name: '[GMT + 14:00] Kiribati (Line Islands)' },
];

View File

@ -0,0 +1,718 @@
// Generated using typescript-generator version 1.29.366 on 2018-02-05 16:06:12.
export class BrowseData {
data: { [index: string]: FieldData };
fields: string[];
}
export class DataCollectionAccessProtocol {
value: string;
username: string;
password: string;
}
export class DataCollectionInterface {
protocol: DataCollectionAccessProtocol;
baseUrl: string;
format: string;
filter: string;
}
export class DataCollectionType {
dataCollectionInterface: DataCollectionInterface;
id: string;
label: string;
group: string;
}
export class Document {
map: { [index: string]: string[] };
fieldNames: string[];
}
export class FieldData {
fieldRowList: FieldRow[];
count: number[];
values: string[];
}
export class FieldRow {
value: string;
count: number;
}
export class FormattedSearchResult {
formattedResult: string;
resultsNumber: number;
}
export class Hint {
alternateTerm: string;
autoFollowHint: boolean;
}
export class DriverResource implements Serializable {
resourceId: string;
resourceUri: string;
resourceKind: string;
resourceType: string;
dateOfCreation: Date;
}
export class MDFormatDataStructure extends DriverResource {
resourceName: string;
layouts: { [index: string]: LayoutField[] };
}
export class PiwikInfo implements IsSerializable {
repositoryId: string;
openaireId: string;
repositoryName: string;
country: string;
siteId: string;
authenticationToken: string;
creationDate: Date;
requestorName: string;
requestorEmail: string;
validated: boolean;
validationDate: Date;
comment: string;
}
export class Repository extends DriverResource implements IsSerializable {
id: string;
officialName: string;
englishName: string;
websiteUrl: string;
logoUrl: string;
contactEmail: string;
countryName: string;
countryCode: string;
organization: string;
latitude: number;
longitude: number;
timezone: number;
namespacePrefix: string;
odNumberOfItems: string;
odNumberOfItemsDate: string;
odPolicies: string;
odLanguages: string;
odContentTypes: string;
collectedFrom: string;
inferred: boolean;
deletedByInference: boolean;
trust: number;
inferenceProvenance: string;
dateOfValidation: Date;
datasourceClass: string;
provenanceActionClass: string;
dateOfCollection: Date;
typology: string;
activationId: string;
mergehomonyms: boolean;
description: string;
releaseStartDate: Date;
releaseEndDate: Date;
missionStatementUrl: string;
dataProvider: boolean;
serviceProvider: boolean;
databaseAccessType: string;
dataUploadType: string;
databaseAccessRestriction: string;
dataUploadRestriction: string;
versioning: boolean;
citationGuidelineUrl: string;
qualityManagementKind: string;
pidSystems: string;
certificates: string;
aggregator: string;
issn: string;
eissn: string;
lissn: string;
interfaces: RepositoryInterface[];
availableDiskSpace: string;
securityParameters: string;
protocol: string;
registeredBy: string;
datasourceType: string;
datasourceAggregatorId: string;
datasourceOriginalIdValue: string;
datasourceOriginalIdProvenance: string;
datasourceAggregated: boolean;
datasourceComplianceDegreeValue: string;
datasourceComplianceDegreeEncoding: string;
numberOfObjects: number;
maxSizeOfDatastructure: number;
maxNumberOfDataStructures: number;
registered: boolean;
extraFields: { [index: string]: string };
piwikInfo: PiwikInfo;
environments: string[];
registrationDate: Date;
verified: boolean;
dataCollectionTypes: DataCollectionType[];
consentTermsOfUse: string;
consentTermsOfUseDate: Date;
fullTextDownload: string;
}
export class RepositorySnippet {
id: string;
officialname: string;
englishname: string;
websiteurl: string;
typology: string;
registeredby: string;
organizations: Organization[];
registrationdate: Date;
piwikInfo: PiwikInfo;
logoUrl: string;
description: string;
consentTermsOfUse: string;
consentTermsOfUseDate: Date;
fullTextDownload: string;
}
export class Organization {
country: string;
legalname: string;
websiteurl: string;
legalshortname: string;
logourl: string;
}
export class RepositoryAccessProtocol {
value: string;
username: string;
password: string;
filter: string;
}
export class RepositoryBlackboard {
lastrequest: string;
lastresponse: string;
messages: RepositoryBlackboardMessage[];
}
export class RepositoryBlackboardMessage {
id: string;
action: Action;
actionStatus: ActionStatus;
parameters: string[];
}
export class RepositoryComparator implements Comparator<Repository> {
}
export class RepositoryInterface implements Serializable, IsSerializable {
desiredCompatibilityLevel: string;
complianceName: string;
upgradeToV3: string;
deleteApi: boolean;
accessSet: string;
accessFormat: string;
metadataIdentifierPath: string;
lastCollectionDate: string;
nextScheduledExecution: string;
status: string;
collectedFrom: string;
id: string;
typology: string;
compliance: string;
contentDescription: string;
accessProtocol: string;
baseUrl: string;
active: boolean;
removable: boolean;
accessParams: { [index: string]: string };
extraFields: { [index: string]: string };
comments: string;
}
export class SearchCriteriaImpl implements SearchCriteria {
startsWith: string;
endsWith: string;
contains: string;
}
export class RepositorySearchCriteria extends SearchCriteriaImpl implements SearchCriteria {
haveDocuments: boolean;
protocolType: string;
adminInfo: string;
officialName: string;
registeredBy: string;
country: string;
verified: boolean;
}
export class SearchResult {
query: string;
locale: string;
total: number;
page: number;
size: number;
fields: string[];
searchResults: string[];
browseResults: string[];
}
export class SimilarDocument {
id: string;
score: number;
}
export class StoreInfo {
serviceUrl: string;
storeId: string;
}
export class StoreObjectInfo {
storeInfo: StoreInfo;
objectId: string;
}
export class SuggestiveResult {
epr: EPR;
alternativeTerm: string;
autofollow: boolean;
}
export class CustomProperties implements IsSerializable {
properties: { [index: string]: string };
}
export class JobForValidation implements IsSerializable {
officialName: string;
baseUrl: string;
userEmail: string;
validationSet: string;
datasourceId: string;
interfaceId: string;
desiredCompatibilityLevel: string;
activationId: string;
repoType: string;
interfaceIdOld: string;
groupByXpath: string;
metadataPrefix: string;
records: number;
registration: boolean;
updateExisting: boolean;
cris: boolean;
crisReferentialChecks: boolean;
selectedCrisEntities: string[];
selectedContentRules: number[];
selectedUsageRules: number[];
adminEmails: string[];
}
export class JobResultEntry implements IsSerializable {
name: string;
description: string;
successes: string;
weight: number;
errors: string[];
ruleId: number;
hasErrors: boolean;
mandatory: boolean;
type: string;
}
export class Rule implements IsSerializable {
id: number;
name: string;
description: string;
type: string;
mandatory: boolean;
weight: number;
provider_information: string;
job_type: string;
entity_type: string;
for_cris: boolean;
configuration: CustomProperties;
}
export class RuleSet implements Serializable, IsSerializable {
id: number;
name: string;
description: string;
guidelinesAcronym: string;
shortName: string;
visibility: string[];
contentRules: Rule[];
usageRules: Rule[];
contentRulesIds: number[];
usageRulesIds: number[];
}
export class StoredJob extends JobForValidation implements IsSerializable {
contentJobStatus: string;
usageJobStatus: string;
started: string;
ended: string;
duration: string;
error: string;
validationType: string;
jobType: string;
guidelinesShortName: string;
validationStatus: string;
recordsTested: number;
id: number;
contentJobScore: number;
usageJobScore: number;
rules: number[];
resultEntries: JobResultEntry[];
filteredScores: { [index: string]: number };
}
export class AdvQueryObject implements IsSerializable {
datasource: string;
topic: string;
titles: string[];
subjects: string[];
authors: string[];
dates: Range[];
trust: Range;
page: number;
}
export class BrowseEntry implements Comparable<BrowseEntry>, IsSerializable {
value: string;
size: number;
}
export class ConditionParams implements IsSerializable {
value: string;
otherValue: string;
}
export class OaBrokerRelatedDataset implements IsSerializable {
openaireId: string;
originalId: string;
title: string;
collectedFrom: string;
pids: OaBrokerTypedValue[];
instances: OaBrokerInstance[];
}
export class DatasourcesBroker implements IsSerializable {
datasourcesOfUser: Tuple<BrowseEntry, string>[];
sharedDatasources: Tuple<BrowseEntry, string>[];
datasourcesOfOthers: Tuple<BrowseEntry, string>[];
}
export class OaBrokerRelatedDatasource implements IsSerializable {
openaireId: string;
name: string;
type: string;
relType: string;
}
export class EventsPage implements IsSerializable {
datasource: string;
topic: string;
currPage: number;
totalPages: number;
total: number;
values: OaBrokerEventPayload[];
}
export class OaBrokerExternalReference implements IsSerializable {
url: string;
sitename: string;
type: string;
refidentifier: string;
}
export class OaBrokerInstance implements IsSerializable {
url: string;
license: string;
hostedby: string;
instancetype: string;
}
export class OaBrokerJournal implements IsSerializable {
name: string;
issn: string;
eissn: string;
lissn: string;
}
export class MapConditions implements IsSerializable {
field: string;
fieldType: MapValueType;
operator: ConditionOperator;
listParams: ConditionParams[];
}
export class OaBrokerEventPayload implements IsSerializable {
result: OaBrokerMainEntity; // old publication: Publication; ??
highlight: OaBrokerMainEntity;
provenance: OaBrokerProvenance;
trust: number;
}
export class OaBrokerAuthor implements IsSerializable {
fullname: string;
orcid: string;
}
export class OpenaireSubscription implements IsSerializable {
subscriber: string;
frequency: NotificationFrequency;
mode: NotificationMode;
query: AdvQueryObject;
}
export class OaBrokerTypedValue implements IsSerializable {
value: string;
type: string;
}
export class OaBrokerProject implements IsSerializable {
openaireId: string;
code: string;
acronym: string;
title: string;
funder: string;
fundingProgram: string;
jurisdiction: string;
}
export class OaBrokerProvenance implements IsSerializable {
repositoryName: string;
repositoryType: string;
url: string;
id: string;
}
export class OaBrokerRelatedPublication implements IsSerializable {
openaireId: string;
originalId: string;
title: string;
collectedFrom: string;
pids: OaBrokerTypedValue[];
instances: OaBrokerInstance[];
relType: string;
}
export class OaBrokerMainEntity implements IsSerializable {
openaireId: string;
originalId: string;
typology: string;
titles: string[];
abstracts: string[];
language: string;
subjects: OaBrokerTypedValue[];
creators: OaBrokerAuthor[];
publicationdate: string;
publisher: string;
embargoenddate: string;
contributor: string[];
journal: OaBrokerJournal;
pids: OaBrokerTypedValue[];
instances: OaBrokerInstance[];
externalReferences: OaBrokerExternalReference[];
publications: OaBrokerRelatedPublication[];
projects: OaBrokerProject[];
datasets: OaBrokerRelatedDataset[];
softwares: OaBrokerRelatedSoftware[];
datasources: OaBrokerRelatedDatasource[];
}
export class Range implements IsSerializable {
min: string;
max: string;
}
export class SimpleSubscriptionDesc implements IsSerializable {
id: string;
datasource: string;
topic: string;
count: number;
creationDate: Date;
lastNotificationDate: Date;
}
export class OaBrokerRelatedSoftware implements IsSerializable {
openaireId: string;
name: string;
description: string;
landingPage: string;
repository: string;
}
export class Subscription implements IsSerializable {
subscriptionId: string;
subscriber: string;
topic: string;
frequency: NotificationFrequency;
mode: NotificationMode;
creationDate: Date;
lastNotificationDate: Date;
conditions: string;
conditionsAsList: MapConditions[];
}
export class LayoutField {
name: string;
xpath: string;
type: string;
indexable: boolean;
result: boolean;
stat: boolean;
tokenizable: boolean;
}
export interface IsSerializable {
}
export interface Serializable {
}
export interface SearchCriteria {
}
export class EPR {
epr: string;
address: string;
serviceName: string;
endpointName: string;
parameterNames: string[];
}
export class Tuple<K, V> implements IsSerializable {
first: K;
second: V;
}
export interface Comparator<T> {
}
export interface Comparable<T> {
}
export type ConditionOperator = "EXACT" | "MATCH_ANY" | "MATCH_ALL" | "RANGE";
export type MapValueType = "STRING" | "INTEGER" | "FLOAT" | "DATE" | "BOOLEAN" | "LIST_STRING" | "LIST_INTEGER" | "LIST_FLOAT" | "LIST_DATE" | "LIST_BOOLEAN";
export type NotificationFrequency = "never" | "realtime" | "daily" | "weekly" | "monthly";
export type NotificationMode = "MOCK" | "EMAIL";
export type Action = "CREATE" | "DELETE" | "UPDATE" | "MANAGE" | "RELEASE" | "CANCEL";
export type ActionStatus = "DONE" | "ONGOING" | "FAILED" | "WAITING" | "ASSIGNED";
export class Country {
name: string;
code: string;
}
export class Term implements IsSerializable {
englishName: string;
nativeName: string;
encoding: string;
code: string;
}
export class Timezone {
name: string;
offset: number;
}
export class InterfaceInformation implements IsSerializable {
identified: boolean;
sets: string[];
adminEmails: string[];
}
export class JobsOfUser implements IsSerializable {
totalJobs: number;
totalJobsSuccessful: number;
totalJobsFailed: number;
totalJobsOngoing: number;
jobs: StoredJob[];
}
export class MetricsNumbers implements IsSerializable {
downloads: string[];
pageviews: string;
total_downloads: string;
total_openaire_downloads: string;
total_openaire_views: string;
total_views: string;
views: string[];
}
export class MetricsInfo implements IsSerializable {
diagramsBaseURL: string;
metricsNumbers: MetricsNumbers;
}
export class Typology {
value: string;
name: string;
}
export class AggregationDetails implements IsSerializable {
aggregationStage: string;
date: Date;
numberOfRecords: number;
collectionMode: string;
indexedVersion: boolean;
}
export class Aggregations implements IsSerializable {
aggregationHistory: AggregationDetails[];
lastCollection: AggregationDetails[];
lastTransformation: AggregationDetails[];
}
export class UserInfo implements IsSerializable {
sub: string;
role: string[];
name: string;
email: string;
}
export class UsageStatsSummary implements IsSerializable {
literature: string;
aggregators: string;
journal: string;
software: string;
lastYearUsagestats: { number: string; year: number; };
usagestats: string;
dataRepositories: string;
datasets: string;
publications: string;
}
export class RepositorySummaryInfo {
id: string;
repositoryName: string;
logoURL: string;
recordsCollected: number;
lastIndexedVersion: Date;
enrichmentEvents: number;
totalViews: string;
totalDownloads: string;
}
export class UsageSummary {
metricsInfo: MetricsInfo;
piwikInfo: PiwikInfo;
}
export class BrokerSummary {
userSubs: Map<string, SimpleSubscriptionDesc[]>;
topicsForDatasource: BrowseEntry[];
}
export class CollectionMonitorSummary {
aggregationDetails: AggregationDetails[];
lastIndexedVersion: AggregationDetails;
}

41
src/app/domain/typologies.ts Executable file
View File

@ -0,0 +1,41 @@
export const typologies = [
{ value: '', name: '[Other] (enter name below)' },
{ value: 'CONTENTdm', name: 'CONTENTdm' },
{ value: 'Digibib', name: 'Digibib' },
{ value: 'Digital Commons', name: 'Digital Commons' },
{ value: 'DigiTool', name: 'DigiTool' },
{ value: 'DIVA', name: 'DIVA' },
{ value: 'Diva-Portal', name: 'Diva-Portal' },
{ value: 'dLibra', name: 'dLibra' },
{ value: 'Doks', name: 'Doks' },
{ value: 'Drupal', name: 'Drupal' },
{ value: 'DSpace', name: 'DSpace' },
{ value: 'Earmas', name: 'Earmas' },
{ value: 'EPrints', name: 'EPrints' },
{ value: 'ETD', name: 'ETD' },
{ value: 'ETD - db', name: 'ETD - db' },
{ value: 'Fedora', name: 'Fedora' },
{ value: 'Fez', name: 'Fez' },
{ value: 'Greenstone', name: 'Greenstone' },
{ value: 'HAL', name: 'HAL' },
{ value: 'invenio', name: 'invenio' },
{ value: 'MyCoRe', name: 'MyCoRe' },
{ value: 'Open Repository', name: 'Open Repository' },
{ value: 'OPUS', name: 'OPUS' },
{ value: 'Pica - Verbundkatalog', name: 'Pica - Verbundkatalog' },
{ value: 'Proprietary Software', name: 'Proprietary Software' },
{ value: 'PUMA', name: 'PUMA' },
{ value: 'PURE', name: 'PURE' },
{ value: 'SciELO', name: 'SciELO' },
{ value: 'SFIX', name: 'SFIX' },
{ value: 'VITAL', name: 'VITAL' },
{ value: 'VTOAI', name: 'VTOAI' },
{ value: 'WEKO', name: 'WEKO' },
{ value: 'XooNIps', name: 'XooNIps' },
{ value: 'OJS', name: 'OJS' },
{ value: 'HyperJournal', name: 'HyperJournal' },
{ value: 'ePubTk', name: 'ePubTk' },
{ value: 'GAPworks', name: 'GAPworks' },
{ value: 'DPubS', name: 'DPubS' },
{ value: 'E - Journal', name: 'E - Journal' },
];

View File

@ -0,0 +1,7 @@
/**
* Created by stefania on 9/6/16.
*/
export class URLParameter {
key: string;
value: string[];
}

View File

@ -0,0 +1,110 @@
// Generated using typescript-generator version 1.29.366 on 2018-05-11 15:13:15.
export class Contact {
"E-mail": string;
Contact: string;
}
export class Customer {
ID: string;
ReportItems: ReportItem[];
}
export class Filter {
Name: string;
Value: string;
}
export class Filters {
UsageDateRange: UsageDateRange;
Filter: Filter[];
ReportAttribute: Filter[];
}
export class Instance {
MetricType: string;
Count: string;
}
export class ItemIdentifier {
Type: string;
Value: string;
}
export class ItemPerformance {
Period: Period;
Category: string;
Instance: Instance[];
}
export class Period {
Begin: string;
End: string;
}
export class Report {
"@Created": string;
"@Version": string;
"@Name": string;
Vendor: Vendor;
Customer: Customer;
}
export class ReportDefinition {
"@Name": string;
"@Release": string;
Filters: Filters;
}
export class ReportException {
"@Created": string;
Number: string;
Severity: string;
Message: string;
Data: string;
}
export class ReportItem {
ItemIdentifier: ItemIdentifier[];
ItemPublisher: string;
ItemPlatform: string;
ItemDataType: string;
ItemName: string;
ItemPerformance: ItemPerformance[];
}
export class ReportResponse {
"@Created": string;
Exception: ReportException[];
Requestor: Requestor;
ReportDefinition: ReportDefinition;
Report: ReportWrapper;
}
export class ReportResponseWrapper {
ReportResponse: ReportResponse;
}
export class ReportWrapper {
Report: Report;
}
export class Requestor {
ID: string;
}
export class UsageDateRange {
Begin: string;
End: string;
}
export class BaseRepository {
}
export class UsageReport extends BaseRepository {
}
export class Vendor {
Contact: Contact;
Name: string;
}

12
src/app/domain/utilities.ts Executable file
View File

@ -0,0 +1,12 @@
export function sortAlpgabetically (array: any[]) {
array.sort(function(a,b){
if(a < b ){
return -1;
} else if(a > b ){
return 1;
} else {
return 0;
}
});
}

43
src/app/domain/utils.ts Executable file
View File

@ -0,0 +1,43 @@
/**
* Created by stefanos on 2/3/2017.
*/
export function getCookie(name: string) : string {
let ca: string[] = document.cookie.split(';');
let caLen: number = ca.length;
let cookieName = `${name}=`;
let c: string;
/*console.log(`document.cookie is: ${document.cookie.toString()}`);
console.log(`ca is: ${JSON.stringify(ca)}`);*/
for (let i: number = 0; i < caLen; i += 1) {
c = ca[i].replace(/^\s+/g, '');
if (c.indexOf(cookieName) == 0) {
return c.substring(cookieName.length, c.length);
}
}
return null;
}
export function deleteCookie(name) {
setCookie(name, '', -1);
console.log(`after delete: document.cookie is: ${document.cookie.toString()}`);
}
/* defaulr path used to be '' */
function setCookie(name: string, value: string, expireDays: number, path: string = '/') {
let d:Date = new Date();
d.setTime(d.getTime() + expireDays * 24 * 60 * 60 * 1000);
let expires:string = `expires=${d.toUTCString()}`;
/*let cpath:string = path ? `; path=${path}` : '';*/
/*document.cookie = `${name}=${value}; ${expires}${cpath}`;*/
/* new code from Argyro */
let domain = "";
if (document.domain.indexOf(".di.uoa.gr")!= -1) { // for development
domain = ".athenarc.gr";
} else if(document.domain.indexOf(".openaire.eu") != -1) {
domain = ".openaire.eu";
}
document.cookie = name+'='+value+'; path='+path+'; domain='+domain+';';
}

View File

@ -0,0 +1,209 @@
<div id="page_content">
<div class="repositoryAdminMenu">
<div class="uk-margin-medium-left uk-margin-medium-right">
<div class="uk-padding-small">
<h3 class="heading_b">
Metrics Admin
</h3>
</div>
<div id="top_bar">
<div class="md-top-bar">
<div class="uk-width-1-2@l uk-margin-auto">
<form [formGroup]="dataForm" (ngSubmit)="handleChangeAndResetPage()" class="uk-search uk-search-default uk-width-1-1@m">
<div class="md-input-wrapper">
<label for="repository_name_search">Search...</label>
<input class="md-input" type="search" id="repository_name_search" formControlName="searchField">
<span class="md-input-bar"></span>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<div id="page_content_inner" class="whiteBackground uk-padding-remove-left uk-padding-remove-right">
<div class="uk-section uk-background-norepeat uk-background-cover uk-background-top-center"
style="background-image: url('../../../assets/imgs/landing/abstract2.svg'); !important; min-height: calc(80vh);" uk-height-viewport="offset-top: true; offset-bottom: 20;">
<!-- TOP HELP CONTENT -->
<help-content #topHelperContent [position]="'top'"
[ngClass]="topHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
<div class="uk-grid">
<!-- LEFT HELP CONTENT -->
<aside-help-content #leftHelperContent [position]="'left'"
[ngClass]="leftHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
<!-- MIDDLE -->
<div class="uk-width-expand@m">
<div *ngIf="errorMessage" class="uk-alert uk-alert-danger">{{ errorMessage }}</div>
<div *ngIf="successMessage" class="uk-alert uk-alert-success">{{ successMessage }}</div>
<div *ngIf="!errorMessage" class="uk-container">
<div class="">
<div class="">
<div class="uk-margin-medium uk-margin-top repositoryAdminActions">
<form [formGroup]="dataForm" class="uk-form-horizontal uk-flex">
<div class="uk-margin-right">
<div class="">
<label class="" for="quantity">Results per page </label>
<div class="uk-inline">
<select class="uk-select" id="quantity" (change)="handleChangeAndResetPage()" formControlName="quantity">
<option value="10">10</option>
<option value="25" selected>25</option>
<option value="50">50</option>
<option value="100">100</option>
</select>
</div>
</div>
</div>
<div class="uk-margin-right">
<div class="uk-inline uk-margin-right">
<label class="" for="orderBy">Order by </label>
<div class="uk-inline">
<select class="uk-select" id="orderBy" (change)="handleChangeAndResetPage()" formControlName="order">
<option value="DSC" selected>Descending</option>
<option value="ASC">Ascending</option>
</select>
</div>
</div>
<div class="uk-inline">
<label class="" for="orderField">Sort by </label>
<div class="uk-inline">
<select class="uk-select" id="orderField" (change)="handleChangeAndResetPage()" formControlName="orderField">
<option value="CREATION_DATE" selected>Date</option>
<option value="REPOSITORY_NAME">Name</option>
</select>
</div>
</div>
</div>
<div class="" style="margin-left:auto; margin-right:0;">
<button class="uk-button uk-button-link" (click)="downloadCSV()">
<i class="fas fa-download uk-margin-small-right"></i>Export to CSV
</button>
</div>
</form>
</div>
<div class="uk-width-1-1@m">
<div style="display: flex;justify-content: space-between;">
<div *ngIf="piwiks" class="resultsInfo" style="margin-top: auto;">
<span class="number">{{piwiks.total}}</span> RESULTS, PAGE <span class="number">{{(dataForm.get('page').value)*1 + 1}}</span> OF <span class="number">{{pages.length}}</span>
</div>
<div class="uk-inline">
<ul class="uk-pagination" uk-margin>
<li><a (click)="previousPage()" class="pagination_arrow"><span uk-pagination-previous></span></a></li>
<li [ngClass]="{'uk-active': (this.dataForm.get('page').value == page) }" *ngFor="let page of pages">
<a (click)="selectPage(page)">{{page+1}}</a>
</li>
<li><a (click)="nextPage()" class="pagination_arrow"><span uk-pagination-next></span></a></li>
</ul>
</div>
</div>
<hr class="adminResultsHeader">
<div *ngIf="loadingMessage" class="loading-big">
<div class="loader-big" style="text-align: center; padding-top: 170px; color: rgb(47, 64, 80); font-weight: bold;">
{{ loadingMessage }}
</div>
<div class="transparentFilm"></div>
</div>
<!-- REPOSITORY CARD -->
<ng-container *ngIf="piwiks && piwiks.results.length>0">
<div *ngFor="let piwik of piwiks.results" class="md-card repositoryCard">
<div class="md-card-content large-padding">
<div class="uk-text-meta">
Requested on: {{ piwik.creationDate | date : "yyyy-MM-dd" }}
<ng-container *ngIf="piwik.validated">
. Validated on: {{ piwik.validationDate | date : "yyyy-MM-dd" }}
</ng-container>
</div>
<div>
<div class="repositoryCardHeader uk-margin-bottom uk-margin-small-top uk-inline">
<a *ngIf="piwik.validated" [routerLink]="['/repositoryAdmin/' + piwik.repositoryId + '/getImpact/show']">{{ piwik.repositoryName }}</a>
<a *ngIf="!piwik.validated" [routerLink]="['/repositoryAdmin/' + piwik.repositoryId + '/getImpact/instructions']">{{ piwik.repositoryName }}</a>
</div>
<ng-container *ngIf="!piwik.validated">
<button class="uk-button uk-button-primary validate uk-inline uk-float-right" (click)="confirmApproval(piwik.repositoryId)">Validate</button>
</ng-container>
</div>
<div class="uk-margin-small-bottom"><span class="uk-badge uk-badge-primary uk-badge-notification uk-margin-small-right">ID</span>{{ piwik.repositoryId }}</div>
<div class="uk-margin-small-bottom"><span class="mute-title">Requestor: </span><span class="small-content">{{ piwik.requestorName }} - {{ piwik.requestorEmail }}</span></div>
<div class="uk-margin-small-bottom"><span class="mute-title">Matomo ID: </span><span class="small-content">{{ piwik.siteId }}</span></div>
<div class=""><span class="mute-title">Authentication Token: </span><span class="small-content">{{ piwik.authenticationToken }}</span></div>
</div>
</div>
</ng-container>
<ul class="uk-pagination uk-margin-top uk-flex-right" uk-margin>
<li><a (click)="previousPage()" class="pagination_arrow"><span uk-pagination-previous></span></a></li>
<li [ngClass]="{'uk-active': (this.dataForm.get('page').value == page) }" *ngFor="let page of pages">
<a (click)="selectPage(page)">{{page+1}}</a>
</li>
<li><a (click)="nextPage()" class="pagination_arrow"><span uk-pagination-next></span></a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
<!-- RIGHT HELP CONTENT -->
<aside-help-content #rightHelperContent [position]="'right'"
[ngClass]="rightHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
</div>
<!-- BOTTOM HELP CONTENT -->
<help-content #bottomHelperContent [position]="'bottom'"
[ngClass]="bottomHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
</div>
</div>
</div>
<confirmation-dialog #confirmApprovalModal [title]="modalTitle" [isModalShown]="isModalShown"
[confirmActionButton]="modalButton" (emitObject)="confirmedApproval($event)">
Are you sure you want to validate the selected piwik site(s)?
</confirmation-dialog>

View File

@ -0,0 +1,213 @@
import {Component, Input, OnInit, ViewChild} from '@angular/core';
import { PiwikService } from '../../services/piwik.service';
import { PiwikInfo } from '../../domain/typeScriptClasses';
import {
enabledMetricsError,
enablingMetrics,
loadingReposMessage,
reposRetrievalError,
validatePiwikSiteSuccess
} from '../../domain/shared-messages';
import { ConfirmationDialogComponent } from '../../shared/reusablecomponents/confirmation-dialog.component';
import {URLParameter} from '../../domain/url-parameter';
import {FormBuilder, FormGroup} from '@angular/forms';
import {RepositoryService} from '../../services/repository.service';
import {ActivatedRoute, Router} from '@angular/router';
import {PiwikInfoPage} from '../../domain/page-content';
import {environment} from '../../../environments/environment';
import {st} from '@angular/core/src/render3';
@Component ({
selector: 'app-admin-metrics',
templateUrl: 'adminPg-metrics.component.html'
})
export class AdminPgMetricsComponent implements OnInit {
piwiks: PiwikInfoPage;
urlParams: URLParameter[] = [];
errorMessage: string;
successMessage: string;
loadingMessage: string;
modalTitle = 'Approval Confirmation';
modalButton = 'Yes, validate';
isModalShown: boolean;
formPrepare = {
searchField: '',
orderField: 'REPOSITORY_NAME',
order: 'ASC',
page: '0',
quantity: '25',
from: '0'
};
dataForm: FormGroup;
@ViewChild('confirmApprovalModal')
public confirmApprovalModal: ConfirmationDialogComponent;
private pageTotal: number;
private piwiksTotal: number;
public pages = [];
private offset = 2;
constructor(private piwikService: PiwikService,
private fb: FormBuilder,
private route: ActivatedRoute,
private router: Router) {}
ngOnInit() {
this.dataForm = this.fb.group(this.formPrepare);
this.urlParams = [];
this.route.queryParams
.subscribe(params => {
for (const i in params) {
this.dataForm.get(i).setValue(params[i]);
}
for (let i in this.dataForm.controls) {
if (this.dataForm.get(i).value) {
this.urlParams.push({key: i, value: [this.dataForm.get(i).value]});
}
}
this.handleChange();
},
error => this.errorMessage = <any>error
);
this.isModalShown = false;
}
downloadCSV() {
const url = environment.API_ENDPOINT;
let csvUrlParams = '/piwik/getPiwikSitesForRepos/csv?';
for (let i in this.dataForm.controls) {
if (this.dataForm.get(i).value !== '') {
csvUrlParams = csvUrlParams.concat(i, '=', this.dataForm.get(i).value, '&');
}
}
csvUrlParams = csvUrlParams.split('&page=')[0];
window.open(url + csvUrlParams, '_blank');
}
getPiwiks() {
this.loadingMessage = loadingReposMessage;
this.piwikService.getPiwikSitesForRepos(this.urlParams)
.subscribe(
piwiks => {
this.piwiks = piwiks;
this.getPages();
},
error => {
console.log(error);
this.loadingMessage = '';
this.errorMessage = reposRetrievalError;
},
() => {
this.loadingMessage = '';
window.scroll(1, 1);
}
);
}
confirmApproval(repoId: string) {
this.confirmApprovalModal.ids = [repoId];
this.confirmApprovalModal.showModal();
}
confirmedApproval(ids: string[]) {
const id = ids[0];
console.log(`approving validation of piwik for repo with id: ${id}`);
this.approvePiwik(id);
}
approvePiwik(id: string) {
this.loadingMessage = enablingMetrics;
this.errorMessage = '';
this.successMessage = '';
/*this.piwikService.approvePiwikSite(id).subscribe(*/
this.piwikService.markPiwikSiteAsValidated(id).subscribe(
response => console.log(`approvePiwikSite responded: ${JSON.stringify(response)}`),
error => {
console.log(error);
this.loadingMessage = '';
this.errorMessage = enabledMetricsError;
},
() => {
this.loadingMessage = '';
this.errorMessage = '';
this.successMessage = validatePiwikSiteSuccess;
this.getPiwiks();
}
);
}
handleChange() {
this.urlParams = [];
const map: { [name: string]: string; } = {};
for (let i in this.dataForm.controls) {
if (this.dataForm.get(i).value !== '') {
this.urlParams.push({key: i, value: [this.dataForm.get(i).value]});
map[i] = this.dataForm.get(i).value;
}
}
this.router.navigate([`/admin/metrics`], {queryParams: map});
this.getPiwiks();
}
handleChangeAndResetPage() {
this.dataForm.get('page').setValue(0);
this.dataForm.get('from').setValue(0);
this.handleChange();
}
getPages() {
let addToEndCounter = 0;
let addToStartCounter = 0;
this.pages = [];
this.pageTotal = Math.ceil(this.piwiks.total / (this.dataForm.get('quantity').value));
for ( let i = (+this.dataForm.get('page').value - this.offset); i < (+this.dataForm.get('page').value + 1 + this.offset); ++i ) {
if ( i < 0 ) { addToEndCounter++; }
if ( i >= this.pageTotal ) { addToStartCounter++; }
if ((i >= 0) && (i < this.pageTotal)) {
this.pages.push(i);
}
}
for ( let i = 0; i < addToEndCounter; ++i ) {
if (this.pages.length < this.pageTotal) {
this.pages.push(this.pages.length);
}
}
for ( let i = 0; i < addToStartCounter; ++i ) {
if (this.pages[0] > 0) {
this.pages.unshift(this.pages[0] - 1 );
}
}
}
selectPage(page) {
this.dataForm.get('page').setValue(page);
this.dataForm.get('from').setValue(((+this.dataForm.get('page').value) * (+this.dataForm.get('quantity').value)));
this.handleChange();
}
previousPage() {
if (this.dataForm.get('page').value > 0) {
this.dataForm.get('page').setValue(+this.dataForm.get('page').value - 1);
this.dataForm.get('from').setValue(+this.dataForm.get('from').value - +this.dataForm.get('quantity').value);
this.handleChange();
}
}
nextPage() {
// if ((this.dataForm.get('searchField').value) !== '') { this.piwiksTotal = this.piwiks.to; } else { this.piwiksTotal = this.piwiks.total; }
this.pageTotal = Math.ceil(this.piwiks.total / (this.dataForm.get('quantity').value)) - 1;
if (this.dataForm.get('page').value < this.pageTotal) {
this.dataForm.get('page').setValue(+this.dataForm.get('page').value + 1);
this.dataForm.get('from').setValue(+this.dataForm.get('from').value + +this.dataForm.get('quantity').value);
this.handleChange();
}
}
}

View File

@ -0,0 +1,12 @@
.uk-form-horizontal .uk-form-label {
width: 100px;
}
.uk-form-horizontal .uk-form-controls {
margin-left: 115px;
}
.uk-search-default .uk-search-input {
padding-left: 15px;
padding-right: 15px;
}

View File

@ -0,0 +1,218 @@
<div id="page_content">
<div class="repositoryAdminMenu">
<div class="uk-margin-medium-left uk-margin-medium-right">
<div class="uk-padding-small">
<h3 class="heading_b">
Registrations Admin
</h3>
</div>
<div id="top_bar">
<div class="md-top-bar">
<div class="uk-width-1-2@l uk-margin-auto">
<form [formGroup]="dataForm" (ngSubmit)="handleChangeAndResetPage()" class="uk-search uk-search-default uk-width-1-1@m">
<div class="md-input-wrapper">
<label for="repository_name_search">Search (official name) ...</label>
<input class="md-input" type="search" id="repository_name_search" formControlName="officialName">
<span class="md-input-bar"></span>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<div id="page_content_inner" class="whiteBackground uk-padding-remove-left uk-padding-remove-right">
<div class="uk-section uk-background-norepeat uk-background-contain uk-background-bottom-center"
style="background-image: url('../../../assets/imgs/landing/abstract2.svg'); !important; min-height: calc(80vh);" uk-height-viewport="offset-top: true; offset-bottom: 20;">
<!-- TOP HELP CONTENT -->
<help-content #topHelperContent [position]="'top'"
[ngClass]="topHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
<div class="uk-grid">
<!-- LEFT HELP CONTENT -->
<aside-help-content #leftHelperContent [position]="'left'"
[ngClass]="leftHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
<!-- MIDDLE -->
<div class="uk-width-expand@m">
<div *ngIf="errorMessage" class="uk-alert uk-alert-danger">{{ errorMessage }}</div>
<div *ngIf="successMessage" class="uk-alert uk-alert-success">{{ successMessage }}</div>
<div *ngIf="!errorMessage" class="uk-container">
<div class="">
<div class="">
<div class="uk-margin-medium uk-margin-top repositoryAdminActions">
<form [formGroup]="dataForm" class="uk-form-horizontal uk-grid">
<div class="uk-inline">
<div class="uk-margin">
<label class="" for="size">Results per page </label>
<div class="uk-inline">
<select class="uk-select" id="size" (change)="handleChangeAndResetPage()" formControlName="size">
<option value="10">10</option>
<option value="25" selected>25</option>
<option value="50">50</option>
<option value="100">100</option>
</select>
</div>
</div>
</div>
<div class="uk-inline">
<div class="uk-inline uk-margin-right">
<label class="" for="orderBy">Order by </label>
<div class="uk-inline">
<select class="uk-select" id="orderBy" (change)="handleChangeAndResetPage()" formControlName="order">
<option value="DESCENDING" selected>Descending</option>
<option value="ASCENDING">Ascending</option>
</select>
</div>
</div>
<div class="uk-inline">
<label class="" for="sortBy">Sort by </label>
<div class="uk-inline">
<select class="uk-select" id="sortBy" (change)="handleChangeAndResetPage()" formControlName="requestSortBy">
<option value="registrationdate" selected>Date</option>
<option value="officialname">Name</option>
</select>
</div>
</div>
</div>
</form>
</div>
<div class="uk-width-1-1@m">
<ul class="uk-pagination uk-flex-right" uk-margin>
<li><a (click)="previousPage()" class="pagination_arrow"><span uk-pagination-previous></span></a></li>
<li class="uk-active"><span>{{+dataForm.get('page').value + 1}}</span></li>
<li><a (click)="nextPage()" class="pagination_arrow"><span uk-pagination-next></span></a></li>
</ul>
<hr class="adminResultsHeader">
<div *ngIf="loadingMessage" class="loading-big">
<div class="loader-big" style="text-align: center; padding-top: 170px; color: rgb(47, 64, 80); font-weight: bold;">
{{ loadingMessage }}
</div>
<div class="transparentFilm"></div>
</div>
<!-- REPOSITORY CARD -->
<div *ngFor="let res of repositorySnippet" class="md-card repositoryCard">
<div class="md-card-content large-padding">
<div class="uk-text-meta">{{res.typology.split('::')[0]}} {{res.typology.split('::')[1]}} {{res.typology.split('::')[2]}}</div>
<div class="repositoryCardHeader uk-margin-bottom uk-margin-small-top"><a [routerLink]="['/repositoryAdmin/' + res.id]">{{res.officialname}}</a></div>
<div class="uk-margin-small-bottom"><span class="uk-badge uk-badge-primary uk-badge-notification uk-margin-small-right">ID</span>{{res.id}}</div>
<div class="uk-margin-small-bottom"><span class="uk-badge uk-badge-primary uk-badge-notification uk-margin-small-right">RM</span>{{res.registeredby}}</div>
<div class="uk-margin-small-bottom"><span class="mute-title">Date: </span><span class="small-content">{{res.registrationdate}}</span></div>
<div><span class="mute-title">Organization: </span><span *ngFor="let organization of res.organizations; let i=index" class="small-content"><span *ngIf="i>0">, </span>{{organization.legalname + ' (' + getCountryName(organization.country) + ')'}}</span></div>
</div>
</div>
<ul class="uk-pagination uk-margin-top uk-flex-right" uk-margin>
<li><a (click)="previousPage()" class="pagination_arrow"><span uk-pagination-previous></span></a></li>
<li class="uk-active"><span>{{+dataForm.get('page').value + 1}}</span></li>
<li><a (click)="nextPage()" class="pagination_arrow"><span uk-pagination-next></span></a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
<!-- RIGHT HELP CONTENT -->
<aside-help-content #rightHelperContent [position]="'right'"
[ngClass]="rightHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
</div>
<!-- BOTTOM HELP CONTENT -->
<help-content #bottomHelperContent [position]="'bottom'"
[ngClass]="bottomHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
</div>
</div>
</div>
<div class="filter-overlay-toolbar uk-animation-scale-up ng-star-inserted">
<button class="uk-button filter-overlay-button" type="button" uk-toggle="target: #offcanvas-overlay">
<span class=""><i class="fas fa-filter"></i></span>
</button>
</div>
<div class="offcanvas-filters" id="offcanvas-overlay" uk-offcanvas="overlay: true">
<div class="uk-offcanvas-bar uk-light">
<button class="uk-offcanvas-close" type="button" uk-close></button>
<h4>Filters</h4>
<form [formGroup]="dataForm" class="uk-form-stacked">
<div class="uk-margin">
<h5 class="">Datasource Type</h5>
<div class="uk-form-controls">
<div class="uk-margin-small-bottom"><label><input class="uk-radio" type="radio" value="" (change)="handleChangeAndResetPage()" formControlName="typology"> Any</label></div>
<div class="uk-margin-small-bottom"><label><input class="uk-radio" type="radio" value="Aggregator" (change)="handleChangeAndResetPage()" formControlName="typology"> Aggregator</label></div>
<div class="uk-margin-small-bottom"><label><input class="uk-radio" type="radio" value="Journal" (change)="handleChangeAndResetPage()" formControlName="typology"> Journal</label></div>
<div class="uk-margin-small-bottom"><label><input class="uk-radio" type="radio" value="datarepository" (change)="handleChangeAndResetPage()" formControlName="typology"> Data Repository</label></div>
<div class="uk-margin-small-bottom"><label><input class="uk-radio" type="radio" value="pubsrepository" (change)="handleChangeAndResetPage()" formControlName="typology"> Public Repository</label></div>
<div class="uk-margin-small-bottom"><label><input class="uk-radio" type="radio" value="entityregistry" (change)="handleChangeAndResetPage()" formControlName="typology"> Entity Registry</label></div>
<div class="uk-margin-small-bottom"><label><input class="uk-radio" type="radio" value="Institutional" (change)="handleChangeAndResetPage()" formControlName="typology"> Institutional</label></div>
<div class="uk-margin-small-bottom"><label><input class="uk-radio" type="radio" value="Thematic" (change)="handleChangeAndResetPage()" formControlName="typology"> Thematic</label></div>
<div class="uk-margin-small-bottom"><label><input class="uk-radio" type="radio" value="Products" (change)="handleChangeAndResetPage()" formControlName="typology"> Products</label></div>
<div class="uk-margin-small-bottom"><label><input class="uk-radio" type="radio" value="Unknown" (change)="handleChangeAndResetPage()" formControlName="typology"> Unknown</label></div>
</div>
</div>
<hr>
<div class="uk-margin">
<h5 class="">Countries</h5>
<div class="uk-form-controls">
<ng-container *ngIf="countries && countries.length>0">
<read-more [maxHeight]="238">
<div class="uk-margin-small-bottom"><input class="uk-radio" type="radio" value="" (change)="handleChangeAndResetPage()" formControlName="country"> Any</div>
<ng-container *ngFor="let country of countries">
<div class="uk-margin-small-bottom">
<input class="uk-radio" type="radio" value="{{country.code}}"
(change)="handleChangeAndResetPage()" formControlName="country"> {{country.name}}
</div>
</ng-container>
</read-more>
</ng-container>
</div>
</div>
</form>
</div>
</div>

View File

@ -0,0 +1,157 @@
import {Component, OnInit} from '@angular/core';
import {loadingReposMessage, noServiceMessage} from '../../domain/shared-messages';
import {Country, RepositorySnippet} from '../../domain/typeScriptClasses';
import {RepositoryService} from '../../services/repository.service';
import {FormBuilder, FormGroup} from '@angular/forms';
import {ActivatedRoute, Params, Router} from '@angular/router';
import {URLParameter} from '../../domain/url-parameter';
@Component({
selector: 'app-registration',
templateUrl: 'adminPg-registrations.component.html',
styleUrls: ['./adminPg-registrations.component.css']
})
export class RegistrationComponent implements OnInit {
errorMessage: string;
successMessage: string;
loadingMessage: string;
countries: Country[] = [];
repositorySnippet: RepositorySnippet[] = [];
urlParams: URLParameter[] = [];
thisIsForBadUse: RepositorySnippet[] = []; // remove if page total is fixed!!!
formPrepare = {
country: '',
typology: '',
officialName: '',
requestSortBy: 'registrationdate',
order: 'DESCENDING',
page: '0',
size: '25'
};
dataForm: FormGroup;
constructor(private repoService: RepositoryService,
private fb: FormBuilder,
private route: ActivatedRoute,
private router: Router) { }
ngOnInit() {
this.dataForm = this.fb.group(this.formPrepare);
const tempUrlParams = new Array<URLParameter>();
this.route.queryParams
.subscribe(params => {
for (const i in params) {
this.dataForm.get(i).setValue(params[i]);
}
for (let i in this.dataForm.controls) {
if (this.dataForm.get(i).value) {
tempUrlParams.push({key: i, value: [this.dataForm.get(i).value]});
}
}
this.handleChange();
},
error => this.errorMessage = <any>error
);
this.getCountries();
}
getCountries() {
this.repoService.getCountries()
.subscribe(
countries => this.countries = countries.sort(function (a, b) {
if (a.name < b.name) {
return -1;
} else if (a.name > b.name) {
return 1;
} else {
return 0;
}
}),
error => {
this.loadingMessage = '';
this.errorMessage = noServiceMessage;
console.log(error);
}
);
}
getRegisteredRepositories(urlParams: URLParameter[]) {
this.loadingMessage = loadingReposMessage;
this.repoService.searchRegisteredRepositories(this.dataForm.get('page').value,
this.dataForm.get('size').value, urlParams).subscribe(
suc => this.repositorySnippet = suc,
error => {
console.log(error);
this.loadingMessage = '';
},
() => this.loadingMessage = ''
);
}
handleChange() {
const tempUrlParams = new Array<URLParameter>();
const map: { [name: string]: string; } = {};
for (let i in this.dataForm.controls) {
if (this.dataForm.get(i).value !== '') {
tempUrlParams.push({key: i, value: [this.dataForm.get(i).value]});
map[i] = this.dataForm.get(i).value;
}
}
this.router.navigate([`/admin/registrations`],
{queryParams: map});
this.getRegisteredRepositories(tempUrlParams);
}
handleChangeAndResetPage() {
this.dataForm.get('page').setValue(0);
this.handleChange();
}
getCountryName(countryCode): string {
for (const country of Object.values(this.countries)) {
if (country.code === countryCode) {
return country.name;
}
}
}
previousPage() {
if (this.dataForm.get('page').value > 0) {
this.dataForm.get('page').setValue(+this.dataForm.get('page').value - 1);
this.handleChange();
}
}
nextPage() {
/** remove when page total is fixed!!! **/
const tempUrlParams = new Array<URLParameter>();
for (let i in this.dataForm.controls) {
if (this.dataForm.get(i).value !== '') {
tempUrlParams.push({key: i, value: [this.dataForm.get(i).value]});
}
}
this.repoService.searchRegisteredRepositories(+this.dataForm.get('page').value + 1,
this.dataForm.get('size').value, tempUrlParams).subscribe(
suc => this.thisIsForBadUse = suc,
error => console.log(error),
() => {
if (!(this.thisIsForBadUse.length === 0)) {
this.dataForm.get('page').setValue(+this.dataForm.get('page').value + 1);
this.handleChange();
}
}
);
/** **/
}
}

View File

@ -0,0 +1,17 @@
/*
* updated by myrto on 19/12/2018
*/
import { Component, OnInit } from '@angular/core';
@Component ({
selector: 'app-admin',
templateUrl: '../pageContainer.html'
})
export class AdminPgComponent implements OnInit {
constructor() {}
ngOnInit() {}
}

View File

@ -0,0 +1,27 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { TabsModule } from 'ngx-bootstrap';
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
import { AdminPgRouting } from './adminPg.routing';
import { ReusableComponentsModule } from '../../shared/reusablecomponents/reusable-components.module';
import { AdminPgComponent } from './adminPg.component';
import { AdminPgMetricsComponent } from './adminPg-metrics.component';
import {RegistrationComponent} from './adminPg-registrations.component';
@NgModule ({
imports: [
CommonModule,
TabsModule.forRoot(),
FormsModule,
ReactiveFormsModule,
AdminPgRouting,
ReusableComponentsModule,
],
declarations: [
AdminPgComponent,
AdminPgMetricsComponent,
RegistrationComponent
]
})
export class AdminPgModule {}

View File

@ -0,0 +1,33 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AdminPgComponent } from './adminPg.component';
import { AdminPgMetricsComponent } from './adminPg-metrics.component';
import { AuthGuardService } from '../../services/auth-guard.service';
import {RegistrationComponent} from './adminPg-registrations.component';
const adminRoutes: Routes = [
{
path: '',
component: AdminPgComponent,
canActivate: [AuthGuardService],
canLoad: [AuthGuardService],
children: [
{
path: 'metrics',
component: AdminPgMetricsComponent
},
{
path: 'registrations',
component: RegistrationComponent
}
]
}
];
@NgModule ({
imports: [RouterModule.forChild(adminRoutes)],
exports: [RouterModule]
})
export class AdminPgRouting {}

View File

@ -0,0 +1,29 @@
<div *ngIf="baseUrlList" [formGroup]="group" class="radioButtonForm">
<!--<label class="control-label">Validation Set</label>-->
<div class="form-group">
<label for="selectRadio" class="uk-button uk-link-muted visible_uk_links" style="display: block; text-align: left;">
<input id="selectRadio" value="select" name="baseURLRadio" type="radio" (change)="chooseUrl(true)" checked>
<span class="uk-margin-small-left">Select base URL from one of your registered repositories</span>
</label>
</div>
<div class="md-input-wrapper">
<!--<label class="">Select repository's country</label>-->
<select class="md-input" id="selectBaseUrl" formControlName="selectBaseUrl">
<option value="">-- none selected --</option>
<option *ngFor="let url of baseUrlList" value="{{ url }}">{{ url }}</option>
</select>
<span class="md-input-bar"></span>
</div>
<div class="form-group">
<label for="customRadio" class="uk-button uk-link-muted visible_uk_links" style="display: block; text-align: left;">
<input id="customRadio" value="custom" name="baseURLRadio" type="radio" (change)="chooseUrl(false)">
<span class="uk-margin-small-left">or enter new</span>
</label>
</div>
<div class="md-input-wrapper">
<input id="customBaseUrl" formControlName="customBaseUrl" class="md-input" type="text">
<span class="md-input-bar"></span>
</div>
</div>

View File

@ -0,0 +1,62 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { didntChooseBaseUrl, invalidCustomBaseUrl } from '../../../domain/shared-messages';
import { ValidatorService } from '../../../services/validator.service';
@Component({
selector: 'compatibility-validate-step1',
templateUrl: 'compatibility-validate-step1.component.html'
})
export class CompatibilityValidateStep1Component implements OnInit {
group: FormGroup;
errorMessage: string;
@Input() baseUrlList: string[];
@Output() emitObject: EventEmitter<any> = new EventEmitter();
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.group = this.fb.group({
selectBaseUrl : '',
customBaseUrl : ''
});
this.group.get('customBaseUrl').disable();
}
chooseUrl(choice: boolean){
if (choice) {
this.group.get('selectBaseUrl').enable();
this.group.get('customBaseUrl').disable();
} else {
this.group.get('selectBaseUrl').disable();
this.group.get('customBaseUrl').enable();
}
}
submitForm() {
if (this.group.get('selectBaseUrl').enabled){
if ( this.group.get('selectBaseUrl').value) {
this.emitObject.emit(this.group.get('selectBaseUrl').value);
console.log(`selected baseUrl!`);
this.errorMessage = '';
return true;
} else {
this.errorMessage = didntChooseBaseUrl;
return false;
}
} else {
if ( this.group.get('customBaseUrl').value ) {
this.emitObject.emit(this.group.get('customBaseUrl').value);
console.log('added new baseUrl!');
this.errorMessage = '';
return true;
} else {
this.errorMessage = didntChooseBaseUrl;
return false;
}
}
}
}

View File

@ -0,0 +1,77 @@
<div *ngIf="ruleSets" [formGroup]="group" class="form-group radioButtonForm">
<div class="radioButtonForm uk-margin-bottom">
<div *ngFor="let set of ruleSets; let set_index = index" class="">
<label for="ruleSet_{{ set_index }}" class="uk-button uk-link-muted visible_uk_links" style="display: block; text-align: left;">
<input id="ruleSet_{{ set_index }}" value="{{ set.id }}" formControlName="ruleSet" name="ruleSet" type="radio"
(change)="refreshLists()" [checked]="set_index == 0">
<span class="uk-margin-small-left">{{ set.name }}</span>
</label>
</div>
</div>
<button class="uk-button uk-button-link" (click)="toggleShowRules()">
<span *ngIf="showRules">
<i class="fa fa-angle-up"></i>
Hide Content and Usage Rules</span>
<span *ngIf="!showRules">
<i class="fa fa-angle-down"></i>
Show Content and Usage Rules</span>
</button>
<div *ngIf="showRules" class="uk-grid uk-animation-fade">
<div class="uk-width-1-2 uk-grid-item-match uk-first-column" formArrayName="contentRules">
<div class="">
<div class="checkbox selectAll uk-margin-small-bottom">
<!--<div class="icheckbox_md">-->
<!--<input type="checkbox" name="checkbox_demo_mercury" id="checkbox_demo_1" data-md-icheck="" [checked]="selectedAllContentRules" (change)="toggleSelectAllContentRules()"-->
<!--style="position: absolute; top: -20%; left: -20%; display: block; width: 140%; height: 140%; margin: 0px; padding: 0px; background: rgb(255, 255, 255) none repeat scroll 0% 0%; border: 0px none; opacity: 0;">-->
<!--<ins class="iCheck-helper" style="position: absolute; top: -20%; left: -20%; display: block; width: 140%; height: 140%; margin: 0px; padding: 0px; background: rgb(255, 255, 255) none repeat scroll 0% 0%; border: 0px none; opacity: 0;"></ins>-->
<!--</div>-->
<!--<label for="checkbox_demo_1" class="inline-label">Select / Deselect All Content Rules</label>-->
<label>
<input type="checkbox" [checked]="selectedAllContentRules" (change)="toggleSelectAllContentRules()">
<span>Select / Deselect All Content Rules</span>
</label>
</div>
<div *ngFor="let content of group.controls['contentRules'].controls; let content_index = index" class="checkbox">
<div [formGroupName]="content_index">
<label class="uk-link-muted small" for="contentRules_{{ content_index }}">
<input id="contentRules_{{ content_index }}"
title="{{ currentContentRules[content_index].description }}"
formControlName="rule"
type="checkbox"
(change)="onToggleCheckRule($event,'content')">
<span class="uk-margin-small-left">{{ currentContentRules[content_index].name }}</span>
</label>
</div>
</div>
</div>
</div>
<div class="uk-width-1-2 uk-grid-item-match uk-first-column" formArrayName="usageRules">
<div class="">
<div class="checkbox selectAll uk-margin-small-bottom">
<label>
<input type="checkbox" [checked]="selectedAllUsageRules" (change)="toggleSelectAllUsageRules()">
<span>Select / Deselect All Usage Rules</span>
</label>
</div>
<div *ngFor="let usage of group.controls['usageRules'].controls; let usage_index = index" class="checkbox">
<div [formGroupName]="usage_index">
<label class="uk-link-muted small" for="usageRules_{{ usage_index }}">
<input id="usageRules_{{ usage_index }}"
value="{{ currentUsageRules[usage_index].id }}"
title="{{ currentUsageRules[usage_index].description }}"
formControlName="rule"
type="checkbox"
(change)="onToggleCheckRule($event,'usage')">
<span class="uk-margin-small-left">{{ currentUsageRules[usage_index].name }}</span>
</label>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,173 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { Rule, RuleSet } from '../../../domain/typeScriptClasses';
import { FormArray, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
@Component ({
selector: 'compatibility-validate-step2',
templateUrl: 'compatibility-validate-step2.component.html'
})
export class CompatibilityValidateStep2Component implements OnInit {
showRules: boolean;
currentContentRules: Rule[] = [];
currentUsageRules: Rule[] = [];
selectedAllContentRules: boolean;
selectedAllUsageRules: boolean;
group: FormGroup;
@Input() ruleSets: RuleSet[];
@Output() emitObject: EventEmitter<any> = new EventEmitter();
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.showRules = false;
this.selectedAllContentRules = true;
this.selectedAllUsageRules = true;
if ( this.ruleSets.length ) {
this.group = this.fb.group({
ruleSet: ['', Validators.required],
contentRules: this.fb.array([this.initRules()]),
usageRules: this.fb.array([this.initRules()])
});
this.group.get('ruleSet').setValue(this.ruleSets[0].id);
this.getCurrentRuleSets();
this.getRulesLists();
}
}
/* creates a formGroup of the Rules FormArray */
initRules() {
return this.fb.group({
rule : [true]
});
}
/* returns Rules for selected RuleSet */
getCurrentRuleSets () {
console.log(this.group.get('ruleSet').value);
let id = this.group.get('ruleSet').value;
let index: number;
this.currentContentRules = [];
this.currentUsageRules = [];
for (let i=0; i< this.ruleSets.length; i++ ) {
if (this.ruleSets[i].id == id) {
index = i;
break;
}
}
this.currentContentRules = this.ruleSets[index].contentRules;
this.currentUsageRules = this.ruleSets[index].usageRules;
console.log(`contentRules length: ${this.currentContentRules.length}`);
console.log(`usageRules length: ${this.currentUsageRules.length}`);
}
/* inputs the Rule Lists into the FormArrays */
getRulesLists() {
let contentRules = <FormArray>this.group.controls['contentRules'];
for ( let i = 0; i<this.currentContentRules.length-1; i++ ) {
contentRules.push(this.initRules());
}
let usageRules = <FormArray>this.group.controls['usageRules'];
for ( let i = 0; i<this.currentUsageRules.length-1; i++ ) {
usageRules.push(this.initRules());
}
}
/* refreshes the Rule Lists according to the selected RuleSet and reinitializes the form controls */
refreshLists(){
this.removeRulesControls();
this.getCurrentRuleSets();
this.getRulesLists();
}
/* removes form controls in order to reinitialize contentRules formArrays */
removeRulesControls() {
let contentRules = <FormArray>this.group.controls['contentRules'];
// contentRules.reset();
contentRules.controls = [];
contentRules.push(this.initRules());
let usageRules = <FormArray>this.group.controls['usageRules'];
// usageRules.reset();
usageRules.controls = [];
usageRules.push(this.initRules());
}
/* selects/deselects all content rules */
toggleSelectAllContentRules() {
let contentRules = <FormArray>this.group.controls['contentRules'];
if (this.selectedAllContentRules) {
this.selectedAllContentRules = false;
contentRules.controls.map(x => x.get('rule').setValue(false));
} else {
this.selectedAllContentRules = true;
contentRules.controls.map(x => x.get('rule').setValue(true));
}
}
/* selects/deselects all usage rules */
toggleSelectAllUsageRules() {
let usageRules = <FormArray>this.group.controls['usageRules'];
if (this.selectedAllUsageRules) {
this.selectedAllUsageRules = false;
usageRules.controls.map(x => x.get('rule').setValue(false))
} else {
this.selectedAllUsageRules = true;
usageRules.controls.map(x => x.get('rule').setValue(true))
}
}
onToggleCheckRule(event:any, contentOrUsage: string) {
if ( !event.target.checked ) {
if (contentOrUsage == 'content') {
this.selectedAllContentRules = false;
} else if (contentOrUsage == 'usage') {
this.selectedAllUsageRules = false;
}
}
}
toggleShowRules() {
this.showRules = !this.showRules;
return this.showRules;
}
saveChanges() {
let emitted: any[] = [];
let index: number;
for (let i=0; i< this.ruleSets.length; i++ ) {
if (this.ruleSets[i].id == this.group.get('ruleSet').value) {
index = i;
break;
}
}
emitted.push(this.ruleSets[index].guidelinesAcronym);
console.log(`saving the selected rules`);
let contentRules = <FormArray>this.group.controls['contentRules'];
let selectedContent: number[] = [];
for (let i=0; i< this.ruleSets[index].contentRules.length; i++ ) {
if (contentRules.at(i).get('rule').value) {
selectedContent.push(this.ruleSets[index].contentRules[i].id);
}
}
emitted.push(selectedContent);
let selectedUsage: number[] = [];
let usageRules = <FormArray>this.group.controls['usageRules'];
for (let i=0; i< this.ruleSets[index].usageRules.length; i++ ) {
if (usageRules.at(i).get('rule').value) {
selectedUsage.push(this.ruleSets[index].usageRules[i].id);
}
}
emitted.push(selectedUsage);
this.emitObject.emit(emitted);
}
}

View File

@ -0,0 +1,80 @@
<div *ngIf="entitiesList" [formGroup]="group">
<div class="uk-margin-bottom uk-margin-top">
<label class="uk-form-label">Cris Entities</label>
<div class="uk-grid uk-margin-top">
<div class="uk-width-1-2 uk-grid-item-match uk-first-column" formArrayName="entities">
<div class="">
<div class="checkbox selectAll uk-margin-small-bottom">
<label>
<input type="checkbox" [checked]="selectedAllContentRules" (change)="toggleSelectAllContentRules()">
<span>Select / Deselect All Entities</span>
</label>
</div>
<div *ngFor="let content of group.controls['entities'].controls; let i = index" class="checkbox">
<div [formGroupName]="i">
<label class="uk-link-muted small" for="entity_{{ i }}">
<input id="entity_{{ i }}"
formControlName="entity"
type="checkbox"
(change)="onToggleCheckEntity($event)">
<span class="uk-margin-small-left">{{ entitiesList[i] }}</span>
</label>
</div>
</div>
</div>
<!--<div class="checkbox selectAll">-->
<!--<label>-->
<!--<input type="checkbox" [checked]="selectedAllEntities" (change)="toggleSelectAllContentRules()">-->
<!--<span>Select / Deselect All Entities</span>-->
<!--</label>-->
<!--</div>-->
<!--<div *ngFor="let content of group.controls['entities'].controls; let i = index" class="checkbox">-->
<!--<div [formGroupName]="i">-->
<!--<label for="entity_{{ i }}">-->
<!--<input id="entity_{{ i }}"-->
<!--formControlName="entity"-->
<!--type="checkbox"-->
<!--(change)="onToggleCheckEntity($event)">-->
<!--<span class="uk-margin-small-left">{{ entitiesList[i] }}</span>-->
<!--</label>-->
<!--</div>-->
<!--</div>-->
</div>
</div>
</div>
<div class="uk-margin-bottom radioButtonForm">
<label class="uk-form-label">Check Referential Integrity</label>
<div class="uk-margin-bottom uk-grid uk-grid uk-grid-width-medium-1-2 uk-grid-width-large-1-4">
<div class="uk-input-group uk-row-first">
<div class="">
<label for="yes"
class="uk-button uk-link-muted visible_uk_links"
style="display: block; text-align: left;">
<input id="yes" name="referentialIntegrity" type="radio" value="yes" checked>
<span>Yes</span>
</label>
</div>
</div>
<div class="uk-input-group">
<div class="">
<label for="no"
class="uk-button uk-link-muted visible_uk_links"
style="display: block; text-align: left;">
<input id="no" name="referentialIntegrity" type="radio" value="no">
<span>No</span>
</label>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,87 @@
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
import { FormArray, FormBuilder, FormGroup } from '@angular/forms';
@Component ({
selector: 'compatibility-validate-step3-cris',
templateUrl: 'compatibility-validate-step3-cris.component.html'
})
export class CompatibilityValidateStep3CrisComponent implements OnInit {
entitiesList: string[] = [];
selectedAllEntities: boolean;
group: FormGroup;
@Output() emitObject: EventEmitter<any> = new EventEmitter();
constructor(private fb: FormBuilder) {}
ngOnInit () {
this.selectedAllEntities = true;
this.getEntitiesList();
if (this.entitiesList && this.entitiesList.length) {
this.group = this.fb.group({
entities: this.fb.array([this.initEntities()]),
refIntegrity: ''
});
this.setEntitiesControls();
}
}
getEntitiesList() {
this.entitiesList = ['Funding','Organisation','Person','Project','Publication','Product','Service'];
}
initEntities() {
return this.fb.group({
entity : [true]
});
}
/* inputs the entities List into the FormArray */
setEntitiesControls() {
let entities = <FormArray>this.group.controls['entities'];
for ( let i = 0; i<this.entitiesList.length-1; i++ ) {
entities.push(this.initEntities());
}
}
/* selects/deselects all entities */
toggleSelectAllContentRules() {
let entities = <FormArray>this.group.controls['entities'];
if (this.selectedAllEntities) {
this.selectedAllEntities = false;
entities.controls.map(x => x.get('entity').setValue(false));
} else {
this.selectedAllEntities = true;
entities.controls.map(x => x.get('entity').setValue(true));
}
}
onToggleCheckEntity(event:any) {
if ( !event.target.checked ) {
this.selectedAllEntities = false;
}
}
saveChanges() {
let emitted: any[] = [];
let chosenEntities: string[] = [];
console.log(`saving the selected entities`);
let entities = <FormArray>this.group.controls['entities'];
for (let i=0; i<this.entitiesList.length; i++ ) {
if (entities.at(i).get('entity').value) {
chosenEntities.push(this.entitiesList[i]);
}
}
emitted.push(chosenEntities);
if (this.group.get('refIntegrity').value){
emitted.push(true);
} else {
emitted.push(false);
}
this.emitObject.emit(emitted);
}
}

View File

@ -0,0 +1,89 @@
<div class="" [formGroup]="group">
<div *ngIf="errorMessage" class="uk-alert uk-alert-danger">{{errorMessage}}</div>
<div class="uk-margin-bottom radioButtonForm">
<label class="uk-form-label">Number of records to validate</label>
<div class="uk-margin-bottom uk-grid uk-grid uk-grid-width-medium-1-2 uk-grid-width-large-1-4">
<div class="uk-input-group uk-row-first">
<div class="">
<label for="allRecords"
class="uk-button uk-link-muted visible_uk_links"
style="display: block; text-align: left;">
<input id="allRecords" name="noOfRecords" type="radio" (change)="chooseAll(true)" checked>
<span>All</span>
</label>
</div>
</div>
<div class="uk-input-group">
<div class="">
<label for="someRecords"
class="uk-button uk-link-muted visible_uk_links"
style="display: block; text-align: left;">
<input id="someRecords" name="noOfRecords" type="radio" (change)="chooseAll(false)">
<span>Custom</span>
</label>
</div>
</div>
<div class="uk-input-group">
<div class="md-input-wrapper">
<input class="md-input" formControlName="noOfRecordsInput" type="number">
<span class="md-input-bar"></span>
</div>
</div>
</div>
</div>
<div class="uk-margin-medium-bottom">
<label for="selectValSet" class="uk-form-label">Validation Set</label>
<div class="uk-width-1-1">
<div class="md-input-wrapper md-input-filled">
<select class="md-input" id="selectValSet" formControlName="selectValSet">
<option value="">All sets</option>
<option *ngFor="let set of valSets" value="{{set}}">{{set}}</option>
</select>
<span class="md-input-bar"></span>
</div>
</div>
</div>
<div class="xPathPanel uk-margin-bottom radioButtonForm">
<label class="uk-form-label">Would you like to group your results by a specific field?</label>
<div class="uk-grid uk-grid-width-medium-1-2 uk-grid-width-large-1-4">
<div class="uk-input-group uk-row-first">
<div class="">
<label class="uk-button uk-link-muted visible_uk_links" for="noXPath">
<input id="noXPath" name="xpath" type="radio" (change)="addXpath(false)" checked>
<span class="uk-margin-small-left">No</span>
</label>
</div>
</div>
<div class="uk-input-group">
<div class="">
<label class="uk-button uk-link-muted visible_uk_links" for="customXPath">
<input id="customXPath" name="xpath" type="radio" (change)="addXpath(true)">
<span class="uk-margin-small-left">Yes</span>
</label>
</div>
</div>
<div class="uk-input-group">
<div class="md-input-wrapper">
<input class="md-input" formControlName="xpathInput" placeholder="-XPATH-" type="text">
<span class="md-input-bar"></span>
</div>
</div>
</div>
<div class="uk-text-italic uk-text-small uk-margin-top">
<strong>XPath Examples:</strong>
1. //header/setSpec 2. //record/metadata//*[name()='dc:language']
</div>
</div>
</div>

View File

@ -0,0 +1,75 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { formErrorRequiredFields } from '../../../domain/shared-messages';
@Component ({
selector: 'compatibility-validate-step3',
templateUrl: 'compatibility-validate-step3.component.html'
})
export class CompatibilityValidateStep3Component implements OnInit {
errorMessage: string;
@Input() valSets: string[];
@Output() emitObject: EventEmitter<any> = new EventEmitter();
group: FormGroup;
constructor (private fb: FormBuilder) {}
ngOnInit () {
this.group = this.fb.group({
noOfRecordsInput : '',
selectValSet : [''],
xpathInput : ''
});
this.group.get('noOfRecordsInput').setValue(10);
this.group.get('noOfRecordsInput').disable();
this.group.get('xpathInput').disable();
}
chooseAll(all: boolean) {
if (all) {
this.group.get('noOfRecordsInput').disable();
} else {
this.group.get('noOfRecordsInput').enable();
}
}
addXpath(xpath: boolean) {
if (xpath) {
this.group.get('xpathInput').enable();
} else {
this.group.get('xpathInput').disable();
}
}
submitChanges() {
if (this.group.valid) {
this.errorMessage = '';
const emitted: string [] = [];
if ( this.group.get('selectValSet').value) {
emitted.push(this.group.get('selectValSet').value);
} else {
emitted.push('none');
}
if ( this.group.get('noOfRecordsInput').enabled ) {
emitted.push(this.group.get('noOfRecordsInput').value);
} else {
emitted.push('-1');
}
if ( this.group.get('xpathInput').enabled ) {
emitted.push(this.group.get('xpathInput').value);
} else {
emitted.push('');
}
this.emitObject.emit(emitted);
} else {
this.errorMessage = formErrorRequiredFields;
}
}
}

View File

@ -0,0 +1,303 @@
<div id="page_content">
<div id="page_content_inner">
<h2 class="heading_b uk-margin-bottom">Run compatibility test</h2>
<!-- TOP HELP CONTENT -->
<help-content #topHelperContent [position]="'top'"
[ngClass]="topHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
<div class="uk-grid">
<!-- LEFT HELP CONTENT -->
<aside-help-content #leftHelperContent [position]="'left'"
[ngClass]="leftHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
<!-- MIDDLE -->
<div class=" uk-width-expand@m">
<div class="md-card uk-margin-large-bottom">
<div class="md-card-content">
<form class="uk-form-stacked" id="wizard_advanced_form" novalidate="">
<div id="wizard_advanced" role="application" class="wizard clearfix">
<div class="steps clearfix">
<ul role="tablist">
<li role="tab" class="first {{ (currentStep == 0) ? 'current' : '' }}" aria-disabled="false" aria-selected="true">
<a id="wizard_advanced-t-0" href="#wizard_advanced-h-0" aria-controls="wizard_advanced-p-0">
<!--<span class="current-info audible">current step: </span>-->
<span class="number">1</span>
<span class="title">Select datasource</span>
</a>
</li>
<li role="tab" class="{{ (currentStep < 1) ? 'disabled' : '' }} {{ (currentStep == 1) ? 'current' : '' }}" aria-disabled="true">
<a id="wizard_advanced-t-1" href="#wizard_advanced-h-1" aria-controls="wizard_advanced-p-1">
<span class="number">2</span>
<span class="title">{{ (type === 'cris') ? 'Finish' : 'Select guidelines' }}</span>
</a>
</li>
<li *ngIf="(type !== 'cris')" role="tab" class=" {{ (currentStep < 2) ? 'disabled' : '' }} {{ (currentStep == 2) ? 'current' : '' }}" aria-disabled="true">
<a id="wizard_advanced-t-2" href="#wizard_advanced-h-2" aria-controls="wizard_advanced-p-2">
<span class="number">3</span>
<span class="title">Select parameters</span>
</a>
</li>
<li *ngIf="(type !== 'cris')" role="tab" class="last {{ (currentStep < 3) ? 'disabled' : '' }} {{ (currentStep == 3) ? 'current' : '' }}" aria-disabled="true">
<a id="wizard_advanced-t-3" href="#wizard_advanced-h-3" aria-controls="wizard_advanced-p-3">
<span class="number">4</span>
<span class="title">Finish</span>
</a>
</li>
</ul>
</div>
<div class="content clearfix" style="height: 660px">
<div *ngIf="loadingMessage" class="loading-big">
<div class="loader-big" style="text-align: center; padding-top: 170px; color: rgb(47, 64, 80); font-weight: bold;">
{{ loadingMessage }}
</div>
<div class="whiteFilm"></div>
</div>
<div *ngIf="errorMessage" class="uk-alert uk-alert-danger uk-margin-top">{{ errorMessage }}</div>
<!-- first section -->
<h3 id="wizard_advanced-h-0" tabindex="-1" class="title {{ (currentStep == 0) ? 'current' : '' }}">Select Repository</h3>
<section id="wizard_advanced-p-0" role="tabpanel" aria-labelledby="wizard_advanced-h-0"
class="body step-0 {{ (currentStep == 0) ? 'current' : '' }}" data-step="0" aria-hidden="false">
<div *ngIf="(currentStep === 0) && !loadingMessage">
<compatibility-validate-step1 #step1ChooseBaseUrl
[baseUrlList]="baseUrlList"
(emitObject)="getChosenUrl($event)"></compatibility-validate-step1>
</div>
</section>
<!-- second section -->
<h3 id="wizard_advanced-h-1" tabindex="-1" class="title {{ (currentStep == 1) ? 'current' : '' }}">Enter Information</h3>
<section id="wizard_advanced-p-1" role="tabpanel" aria-labelledby="wizard_advanced-h-1"
class="body step-1 {{ (currentStep == 1) ? 'current' : '' }}" data-step="1" aria-hidden="true">
<div *ngIf="(currentStep === 1) && !loadingMessage">
<compatibility-validate-step2 #step2ChooseGuidelines
[ruleSets]="ruleSets"
(emitObject)="getChosenRules($event)">
</compatibility-validate-step2>
</div>
</section>
<!-- third section -->
<h3 id="wizard_advanced-h-2" tabindex="-1" class="title {{ (currentStep == 2) ? 'current' : '' }}">Add Interfaces</h3>
<section id="wizard_advanced-p-2" role="tabpanel" aria-labelledby="wizard_advanced-h-2"
class="body step-2 {{ (currentStep == 2) ? 'current' : '' }}" data-step="2" aria-hidden="true">
<div *ngIf="(currentStep === 2) && (type !== 'cris') && !loadingMessage">
<compatibility-validate-step3 #step3ChooseParameters
[valSets]="valSets"
(emitObject)="getChosenParameters($event)">
</compatibility-validate-step3>
</div>
<div *ngIf="(currentStep === 2) && (type === 'cris') && !loadingMessage">
<compatibility-validate-step3-cris #step3ChooseCrisEntities
(emitObject)="getChosenCrisEntities($event)">
</compatibility-validate-step3-cris>
</div>
</section>
<!-- fourth section -->
<h3 id="wizard_advanced-h-3" tabindex="-1" class="title {{ (currentStep == 3) ? 'current' : '' }}">Finish</h3>
<section id="wizard_advanced-p-3" role="tabpanel" aria-labelledby="wizard_advanced-h-3"
class="body step-3 {{ (currentStep == 3) ? 'current' : '' }}" data-step="2" aria-hidden="true">
<div *ngIf="(currentStep === 3) && !loadingMessage">
<div style="text-align: center">
<div class="success">
<i class="fa fa-check-circle fa-3x" style="color: green"></i>
<h3>Validation has begun</h3>
</div>
<div class="uk-margin-top">
You will be notified by email with the results of the compatibility test.
</div>
</div>
</div>
</section>
</div>
<div *ngIf="currentStep != 3" class="actions clearfix">
<ul role="menu" aria-label="Pagination">
<li class="button_previous {{ (currentStep < 1) ? 'disabled' : '' }}" aria-disabled="true">
<a (click)="moveBackAStep()" role="menuitem"><i class="material-icons"></i> Previous</a>
</li>
<li *ngIf="(((currentStep < 2) && (type !== 'cris')) || ((type === 'cris') && (currentStep == 0)))" class="button_next" aria-hidden="false" aria-disabled="false">
<a (click)="moveAStep()" role="menuitem">Next<i class="material-icons"></i></a>
</li>
<li *ngIf="((currentStep == 2) || ((type === 'cris') && (currentStep == 1)))" class="button_finish" aria-hidden="true">
<a (click)="(type !== 'cris') ? moveAStep() : moveAStep() + submitForValidation()" role="menuitem">Finish</a>
</li>
</ul>
</div>
</div>
</form>
</div>
</div>
</div>
<!-- RIGHT HELP CONTENT -->
<aside-help-content #rightHelperContent [position]="'right'"
[ngClass]="rightHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
</div>
<!-- BOTTOM HELP CONTENT -->
<help-content #bottomHelperContent [position]="'bottom'"
[ngClass]="bottomHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
</div>
</div>
<!--<div class="uk-grid-margin uk-grid uk-grid-stack" uk-grid="">-->
<!--<div class="uk-width-1-1@m uk-first-column">-->
<!--<h1 class="uk-h2">Run compatibility test</h1>-->
<!--&lt;!&ndash; TOP HELP CONTENT &ndash;&gt;-->
<!--<help-content #topHelperContent [position]="'top'"-->
<!--[ngClass]="topHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">-->
<!--</help-content>-->
<!--<div class="uk-container uk-container-large uk-margin-medium-top uk-margin-medium-bottom">-->
<!--<div class="uk-grid">-->
<!--&lt;!&ndash; LEFT HELP CONTENT &ndash;&gt;-->
<!--<aside-help-content #leftHelperContent [position]="'left'"-->
<!--[ngClass]="leftHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">-->
<!--</aside-help-content>-->
<!--&lt;!&ndash; MIDDLE &ndash;&gt;-->
<!--<div class=" uk-width-expand@m">-->
<!--<div class="wizard">-->
<!--<div class="wizardBreadcrumbs">-->
<!--<div class="steps clearfix">-->
<!--<div class="step active">-->
<!--<div>-->
<!--Select datasource-->
<!--<span></span>-->
<!--</div>-->
<!--</div>-->
<!--<div class="step {{ (currentStep > 0) ? 'active' : '' }}">-->
<!--<div>-->
<!--Select guidelines-->
<!--<span></span>-->
<!--</div>-->
<!--</div>-->
<!--<div class="step {{ (currentStep > 1) ? 'active' : '' }}">-->
<!--<div>-->
<!--Select parameters-->
<!--<span></span>-->
<!--</div>-->
<!--</div>-->
<!--<div class="step {{ (currentStep > 2) ? 'active' : '' }}">-->
<!--<div>-->
<!--Finish-->
<!--<span></span>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--<div class="content">-->
<!--<div>-->
<!--<div class="animated fadeInRight stepContent">-->
<!--<div *ngIf="errorMessage" class="uk-alert uk-alert-danger">{{ errorMessage }}</div>-->
<!--<div *ngIf="loadingMessage" class="loading-big">-->
<!--<div class="loader-big" style="text-align: center; padding-top: 170px; color: rgb(47, 64, 80); font-weight: bold;">-->
<!--{{ loadingMessage }}-->
<!--</div>-->
<!--<div class="whiteFilm"></div>-->
<!--</div>-->
<!--<div *ngIf="(currentStep === 0) && !loadingMessage">-->
<!--<compatibility-validate-step1 #step1ChooseBaseUrl-->
<!--[baseUrlList]="baseUrlList"-->
<!--(emitObject)="getChosenUrl($event)"></compatibility-validate-step1>-->
<!--</div>-->
<!--<div *ngIf="(currentStep === 1) && !loadingMessage">-->
<!--<compatibility-validate-step2 #step2ChooseGuidelines-->
<!--[ruleSets]="ruleSets"-->
<!--(emitObject)="getChosenRules($event)">-->
<!--</compatibility-validate-step2>-->
<!--</div>-->
<!--<div *ngIf="(currentStep === 2) && (type !== 'cris') && !loadingMessage">-->
<!--<compatibility-validate-step3 #step3ChooseParameters-->
<!--[valSets]="valSets"-->
<!--(emitObject)="getChosenParameters($event)">-->
<!--</compatibility-validate-step3>-->
<!--</div>-->
<!--<div *ngIf="(currentStep === 2) && (type === 'cris') && !loadingMessage">-->
<!--<compatibility-validate-step3-cris #step3ChooseCrisEntities-->
<!--(emitObject)="getChosenCrisEntities($event)">-->
<!--</compatibility-validate-step3-cris>-->
<!--</div>-->
<!--<div *ngIf="(currentStep === 3) && !loadingMessage">-->
<!--<div>-->
<!--<div class="success">-->
<!--<i class="fa fa-check-circle" style=""></i>-->
<!--<h3>Validation has begun</h3>-->
<!--</div>-->
<!--<div class="uk-alert uk-alert-primary marginTop20 textAlignCenter">-->
<!--You will be notified by email with the results of the compatibility test.-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--<div *ngIf="!loadingMessage" class="wizardActions">-->
<!--<button *ngIf="((currentStep === 1) || (currentStep === 2)) && !loadingMessage"-->
<!--class="uk-button uk-button-grey-light uk-margin-small-right" type="button"-->
<!--(click)="moveBackAStep()">-->
<!--<i class="fa fa-angle-double-left"></i>-->
<!--Back-->
<!--</button>-->
<!--<button *ngIf="(currentStep < 3) && !loadingMessage"-->
<!--class="uk-button uk-button-grey-light uk-margin-small-left" type="button"-->
<!--(click)="moveAStep()">-->
<!--<span class="{{(currentStep === 2) ? 'uk-link' : ''}}">-->
<!--{{ (currentStep < 2) ? 'Next' : 'Finish' }}-->
<!--</span>-->
<!--<i class="fa fa-angle-double-right"></i>-->
<!--</button>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--&lt;!&ndash; RIGHT HELP CONTENT &ndash;&gt;-->
<!--<aside-help-content #rightHelperContent [position]="'right'"-->
<!--[ngClass]="rightHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">-->
<!--</aside-help-content>-->
<!--</div>-->
<!--</div>-->
<!--&lt;!&ndash; BOTTOM HELP CONTENT &ndash;&gt;-->
<!--<help-content #bottomHelperContent [position]="'bottom'"-->
<!--[ngClass]="bottomHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">-->
<!--</help-content>-->
<!--</div>-->
<!--</div>-->

View File

@ -0,0 +1,322 @@
import { Component, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute, Router} from '@angular/router';
import { CompatibilityValidateStep1Component } from './compatibility-validate-forms/compatibility-validate-step1.component';
import { RepositoryService } from '../../services/repository.service';
import { JobForValidation, RuleSet } from '../../domain/typeScriptClasses';
import { AuthenticationService } from '../../services/authentication.service';
import { didntSelectCrisEntities, didntSelectRules, identifyingUrl, invalidCustomBaseUrl,
loadingReposMessage, loadingRuleSets, loadingRuleSetsError, loadingUserRepoInfoError,
loadingValSets, loadingValSetsError, noRuleSets, noServiceMessage, submittingJobError
} from '../../domain/shared-messages';
import { ValidatorService } from '../../services/validator.service';
import { CompatibilityValidateStep2Component } from './compatibility-validate-forms/compatibility-validate-step2.component';
import { CompatibilityValidateStep3Component } from './compatibility-validate-forms/compatibility-validate-step3.component';
import { CompatibilityValidateStep3CrisComponent } from './compatibility-validate-forms/compatibility-validate-step3-cris.component';
import { AsideHelpContentComponent, HelpContentComponent } from '../../shared/reusablecomponents/help-content.component';
@Component ({
selector: 'compatibility-validate-literature',
templateUrl: 'compatibility-validate-type.component.html'
})
export class CompatibilityValidateTypeComponent implements OnInit {
type = '';
/* queryParams is used to change the queryParams without refreshing the page
* This was needed for Help Service [which sends back info according to the current router.url]
* the param that is used is 'step' and the values are: 'baseUrl','guidelines','crisEntities'/'parameters','finish'
*/
currentStep: number;
@ViewChild('topHelperContent')
public topHelperContent: HelpContentComponent;
@ViewChild('leftHelperContent')
public leftHelperContent: AsideHelpContentComponent;
@ViewChild('rightHelperContent')
public rightHelperContent: AsideHelpContentComponent;
@ViewChild('bottomHelperContent')
public bottomHelperContent: HelpContentComponent;
baseUrlList: string[] = [];
ruleSets: RuleSet[] = [];
valSets: string[] = [];
chosenUrl: string;
identifiedUrl: boolean;
chosenGuidelinesAcronym: string;
chosenContentRules: number[];
chosenUsageRules: number[];
chosenValSet: string;
noOfRecords: number;
xPath: string;
chosenCrisEntities: string[];
crisRefIntegrity: boolean;
errorMessage: string;
loadingMessage: string;
@ViewChild('step1ChooseBaseUrl') step1ChooseBaseUrl: CompatibilityValidateStep1Component;
@ViewChild('step2ChooseGuidelines') step2ChooseGuidelines: CompatibilityValidateStep2Component;
@ViewChild('step3ChooseParameters') step3ChooseParameters: CompatibilityValidateStep3Component;
@ViewChild('step3ChooseCrisEntities') step3ChooseCrisEntities: CompatibilityValidateStep3CrisComponent;
constructor(private route: ActivatedRoute,
private router: Router,
private authService: AuthenticationService,
private repoService: RepositoryService,
private valService: ValidatorService) {}
ngOnInit() {
if (this.route.snapshot.paramMap.has('type')) {
this.type = this.route.snapshot.paramMap.get('type');
this.getBaseUrlList();
this.route.queryParams.subscribe(
() => this.getStep()
);
}
let body = document.getElementsByTagName('body')[0];
body.classList.remove("top_bar_active"); //remove the class
body.classList.remove("page_heading_active");
body.classList.remove("landing");
body.classList.add("dashboard");
}
getStep() {
this.currentStep = 0;
if (this.route.snapshot.queryParamMap.has('step')) {
const stepName = this.route.snapshot.queryParamMap.get('step');
if (stepName === 'guidelines') {
if (!this.identifiedUrl) {
this.router.navigateByUrl(`/compatibility/validate/${this.type}?step=baseUrl`);
} else {
this.currentStep = 1;
}
} else if ((stepName === 'parameters') || (stepName === 'crisEntities')) {
if (!this.chosenUrl) {
this.router.navigateByUrl(`/compatibility/validate/${this.type}?step=baseUrl`);
} else {
this.currentStep = 2;
}
} else if (stepName === 'finish') {
this.currentStep = 3;
}
}
this.rightHelperContent.ngOnInit();
this.topHelperContent.ngOnInit();
this.leftHelperContent.ngOnInit();
this.bottomHelperContent.ngOnInit();
}
/* retrieves the baseUrl list for the registered repositories of the user */
getBaseUrlList() {
this.loadingMessage = loadingReposMessage;
this.repoService.getUrlsOfUserRepos()
.subscribe(
repos => this.baseUrlList = repos.sort( function(a , b) {
if (a < b ) {
return -1;
} else if (a > b ) {
return 1;
} else {
return 0;
}
}),
error => {
console.log(error);
this.loadingMessage = '';
this.errorMessage = loadingUserRepoInfoError;
window.scroll(1, 1);
},
() => {
this.loadingMessage = '';
}
);
}
moveAStep() {
this.errorMessage = '';
if (this.currentStep === 0) {
this.step1ChooseBaseUrl.submitForm();
} else if (this.currentStep === 1) {
this.step2ChooseGuidelines.saveChanges();
console.log(this.chosenContentRules);
if (this.chosenContentRules.length || this.chosenUsageRules.length) {
if (this.type === 'cris') {
this.router.navigateByUrl(`/compatibility/validate/${this.type}?step=crisEntities`);
} else {
this.getValidationSets();
this.router.navigateByUrl(`/compatibility/validate/${this.type}?step=parameters`);
}
} else {
this.errorMessage = didntSelectRules;
window.scroll(1, 1);
}
} else if ((this.currentStep === 2) && (this.type !== 'cris')) {
this.step3ChooseParameters.submitChanges();
// save all changes
this.submitForValidation();
} else if ((this.currentStep === 2) && (this.type === 'cris')) {
this.step3ChooseCrisEntities.saveChanges();
if (this.chosenCrisEntities.length) {
// save all changes
this.submitForValidation();
} else {
this.errorMessage = didntSelectCrisEntities;
window.scroll(1, 1);
}
}
}
moveBackAStep () {
this.errorMessage = '';
if (this.currentStep === 1) {
this.router.navigateByUrl(`/compatibility/validate/${this.type}?step=baseUrl`);
} else if ((this.currentStep === 2) && (this.type !== 'cris')) {
this.router.navigateByUrl(`/compatibility/validate/${this.type}?step=guidelines`);
} else if ((this.currentStep === 2) && (this.type === 'cris')) {
this.router.navigateByUrl(`/compatibility/validate/${this.type}?step=guidelines`);
}
}
identifyUrl() {
this.loadingMessage = identifyingUrl;
console.log(`identifying ${this.chosenUrl}`);
this.valService.identifyRepository(this.chosenUrl).subscribe(
res => {
this.identifiedUrl = res;
console.log(`identifyRepository responded: ${this.identifiedUrl}`);
},
error => {
console.log(error);
this.loadingMessage = '';
this.identifiedUrl = false;
this.errorMessage = noServiceMessage;
window.scroll(1, 1);
}, () => {
this.loadingMessage = '';
if (this.identifiedUrl) {
this.getRuleSetsForType();
} else {
this.errorMessage = invalidCustomBaseUrl;
window.scroll(1, 1);
}
}
);
}
getRuleSetsForType() {
this.loadingMessage = loadingRuleSets;
this.valService.getRuleSets(this.type)
.subscribe(
rules => this.ruleSets = rules,
error => {
this.loadingMessage = '';
this.errorMessage = loadingRuleSetsError;
window.scroll(1, 1);
},
() => {
this.loadingMessage = '';
if (this.ruleSets && this.ruleSets.length) {
this.router.navigateByUrl(`/compatibility/validate/${this.type}?step=guidelines`);
} else {
this.errorMessage = noRuleSets;
window.scroll(1, 1);
}
}
);
}
getValidationSets() {
this.loadingMessage = loadingValSets;
this.valService.getSetsOfRepository(this.chosenUrl)
.subscribe(
sets => this.valSets = sets,
error => {
this.errorMessage = loadingValSetsError;
window.scroll(1, 1);
},
() => {
this.loadingMessage = '';
this.currentStep = 2;
}
);
}
getChosenUrl(url: string) {
this.chosenUrl = url;
this.identifyUrl();
}
getChosenRules(rules: any[]) {
this.chosenGuidelinesAcronym = rules[0];
this.chosenContentRules = rules[1];
this.chosenUsageRules = rules[2];
}
getChosenParameters (params: string[]) {
this.chosenValSet = params[0];
this.noOfRecords = +params[1];
this.xPath = params[2];
}
getChosenCrisEntities (crisParams: any[]) {
this.chosenCrisEntities = crisParams[0];
console.log(this.chosenCrisEntities);
this.crisRefIntegrity = crisParams[1];
}
submitForValidation() {
let isCris: boolean;
if (this.type === 'cris') {
isCris = true;
this.chosenValSet = 'none';
this.noOfRecords = -1;
} else {
isCris = false;
this.crisRefIntegrity = null;
this.chosenCrisEntities = null;
}
const newJob: JobForValidation = {
selectedCrisEntities: this.chosenCrisEntities,
selectedContentRules: this.chosenContentRules,
selectedUsageRules: this.chosenUsageRules,
desiredCompatibilityLevel: this.chosenGuidelinesAcronym,
baseUrl: this.chosenUrl,
validationSet: this.chosenValSet,
records: this.noOfRecords,
groupByXpath: this.xPath,
cris: isCris,
crisReferentialChecks: this.crisRefIntegrity,
userEmail: this.authService.getUserEmail(),
adminEmails: [],
officialName: '',
datasourceId: '',
interfaceId: '',
activationId: '',
repoType: '',
interfaceIdOld: '',
metadataPrefix: '',
registration: false,
updateExisting: false
};
console.log(JSON.stringify(newJob));
this.valService.submitJobForValidation(newJob).subscribe(
job => console.log(JSON.stringify(job)),
error => {
this.errorMessage = submittingJobError;
window.scroll(1, 1);
},
() => {
this.router.navigateByUrl(`/compatibility/validate/${this.type}?step=finish`);
}
);
}
}

View File

@ -0,0 +1,196 @@
<div id="page_content">
<div id="page_content_inner">
<h2 class="heading_b uk-margin-bottom">Validate your datasource</h2>
<!-- TOP HELP CONTENT -->
<help-content #topHelperContent [position]="'top'"
[ngClass]="topHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
<div class="uk-grid">
<!-- LEFT HELP CONTENT -->
<aside-help-content #leftHelperContent [position]="'left'"
[ngClass]="leftHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
<!-- MIDDLE -->
<div class=" uk-width-expand@m">
<div class="uk-grid uk-grid-match uk-grid-medium repositoryTypeSelection uk-child-width-1-3@l uk-child-widht-1-3@m" data-uk-grid-margin="">
<div class="uk-row-first">
<div class="uk-text-center md-card md-card-default md-card-hover uk-scrollspy-inview uk-animation-slide-top-medium
datasourceTypeCard uk-inline-clip uk-transition-toggle" uk-scrollspy-class="" tabindex="0">
<a [routerLink]="['literature']" [queryParams]="{ step: 'baseUrl' }" class="el-link uk-position-cover uk-margin-remove-adjacent"></a>
<div class="md-card-content large-padding uk-margin-medium-top uk-margin-bottom">
<div class="">
<img class="el-image" src="../../../assets/imgs/datasourcetypes/Literature%20repository.svg" alt="" width="50">
</div>
<h3>Literature repository</h3>
<div class="uk-transition-slide-bottom uk-position-bottom uk-overlay uk-overlay-primary">
<p class="uk-margin-remove">Run compatibility test against the OpenAIRE literature guidelines.</p>
</div>
</div>
</div>
</div>
<div class="">
<div class="uk-text-center md-card md-card-default md-card-hover uk-scrollspy-inview uk-animation-slide-top-medium
datasourceTypeCard uk-inline-clip uk-transition-toggle" uk-scrollspy-class="" tabindex="0">
<a [routerLink]="['data']" [queryParams]="{ step: 'baseUrl' }" class="el-link uk-position-cover uk-margin-remove-adjacent"></a>
<div class="md-card-content large-padding uk-margin-medium-top uk-margin-bottom">
<div class="">
<img class="el-image" src="../../../assets/imgs/datasourcetypes/Data%20repository.svg" alt="" width="50">
</div>
<h3>Data repository</h3>
<div class="uk-transition-slide-bottom uk-position-bottom uk-overlay uk-overlay-primary">
<p class="uk-margin-remove">Run compatibility test against the OpenAIRE Guidelines for Data Archives.</p>
</div>
</div>
</div>
</div>
<div class="">
<div class="uk-text-center md-card md-card-default md-card-hover uk-scrollspy-inview uk-animation-slide-top-medium
datasourceTypeCard uk-inline-clip uk-transition-toggle" uk-scrollspy-class="" tabindex="0">
<a [routerLink]="['cris']" [queryParams]="{ step: 'baseUrl' }" class="el-link uk-position-cover uk-margin-remove-adjacent"></a>
<div class="md-card-content large-padding uk-margin-medium-top uk-margin-bottom">
<div class="">
<img class="el-image" src="../../../assets/imgs/datasourcetypes/Cris.svg" alt="" width="50">
</div>
<h3>CRIS systems</h3>
<div class="uk-transition-slide-bottom uk-position-bottom uk-overlay uk-overlay-primary">
<p class="uk-margin-remove">Run compatibility test against the OpenAIRE Guidelines for CRIS Managers based on CERIF-XML.</p>
</div>
</div>
</div>
</div>
</div>
<div class="uk-grid uk-grid-match uk-grid-medium repositoryTypeSelection uk-child-width-1-3@l uk-child-widht-1-3@m" data-uk-grid-margin="">
<div class="uk-row-first">
<div class="uk-text-center md-card md-card-default md-card-hover uk-scrollspy-inview uk-animation-slide-top-medium
datasourceTypeCard uk-inline-clip uk-transition-toggle" uk-scrollspy-class="" tabindex="0">
<img alt="BETA" class="large-beta-indication" src="../../../assets/imgs/beta_flag.svg" width="100" style="position:absolute; left: 0;">
<a [routerLink]="['fair']" [queryParams]="{ step: 'baseUrl' }" class="el-link uk-position-cover uk-margin-remove-adjacent"></a>
<div class="md-card-content large-padding uk-margin-medium-top uk-margin-bottom">
<div class="">
<img class="el-image" src="../../../assets/imgs/datasourcetypes/Fair.svg" alt="" width="50">
</div>
<h3>FAIR assessment</h3>
<div class="uk-transition-slide-bottom uk-position-bottom uk-overlay uk-overlay-primary">
<p class="uk-margin-remove">Perform a fair assessment on your metadata.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- RIGHT HELP CONTENT -->
<aside-help-content #rightHelperContent [position]="'right'"
[ngClass]="rightHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
</div>
<!-- BOTTOM HELP CONTENT -->
<help-content #bottomHelperContent [position]="'bottom'"
[ngClass]="bottomHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
</div>
</div>
<!--<div class="uk-grid-margin uk-grid uk-grid-stack" uk-grid="">-->
<!--<div class="uk-width-1-1@m uk-first-column">-->
<!--<h1 class="uk-h2">Validate your datasource</h1>-->
<!--&lt;!&ndash; TOP HELP CONTENT &ndash;&gt;-->
<!--<help-content #topHelperContent [position]="'top'"-->
<!--[ngClass]="topHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">-->
<!--</help-content>-->
<!--<div class="uk-container uk-container-large uk-margin-medium-top uk-margin-medium-bottom">-->
<!--<div class="uk-grid">-->
<!--&lt;!&ndash; LEFT HELP CONTENT &ndash;&gt;-->
<!--<aside-help-content #leftHelperContent [position]="'left'"-->
<!--[ngClass]="leftHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">-->
<!--</aside-help-content>-->
<!--&lt;!&ndash; MIDDLE &ndash;&gt;-->
<!--<div class=" uk-width-expand@m">-->
<!--<div>-->
<!--<div class="uk-margin uk-grid repositoryTypeSelection">-->
<!--<div class="uk-width-expand@m uk-width-1-3@s uk-grid-item-match uk-first-column">-->
<!--<div class="uk-text-center uk-card uk-card-default uk-card-hover uk-scrollspy-inview uk-animation-slide-top-medium" uk-scrollspy-class="" data-id="" style="">-->
<!--<a class="uk-position-cover uk-margin-remove-adjacent" [routerLink]="['literature']" [queryParams]="{ step: 'baseUrl' }"></a>-->
<!--<div class="uk-card-media-top">-->
<!--<img src="../../../assets/imgs/Literature_repos_wide.png" alt="" style="width:100%;">-->
<!--</div>-->
<!--<div class="uk-card-body">-->
<!--<h3 class="el-title uk-margin uk-card-title uk-margin-remove-adjacent uk-margin-small-bottom">-->
<!--Run compatibility test against the OpenAIRE literature guidelines.-->
<!--</h3>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--<div class="uk-width-expand@m uk-width-1-3@s uk-grid-item-match uk-first-column">-->
<!--<div class="uk-text-center uk-card uk-card-default uk-card-hover uk-scrollspy-inview uk-animation-slide-top-medium" uk-scrollspy-class="" data-id="" style="">-->
<!--<a class="el-link uk-position-cover uk-margin-remove-adjacent" [routerLink]="['data']" [queryParams]="{ step: 'baseUrl' }"></a>-->
<!--<div class="uk-card-media-top">-->
<!--<img class="el-image" src="../../../assets/imgs/Data_repos_wide.png" alt="" style="width:100%;">-->
<!--</div>-->
<!--<div class="uk-card-body">-->
<!--<h3 class="el-title uk-margin uk-card-title uk-margin-remove-adjacent uk-margin-small-bottom">-->
<!--Run compatibility test against the OpenAIRE Guidelines for Data Archives.-->
<!--</h3>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--<div class="uk-width-expand@m uk-width-1-3@s uk-grid-item-match uk-first-column">-->
<!--<div class="uk-text-center uk-card uk-card-default uk-card-hover uk-scrollspy-inview uk-animation-slide-top-medium" uk-scrollspy-class="" data-id="" style="">-->
<!--<a class="el-link uk-position-cover uk-margin-remove-adjacent" [routerLink]="['cris']" [queryParams]="{ step: 'baseUrl' }"></a>-->
<!--<div class="uk-card-media-top">-->
<!--<img class="el-image" src="../../../assets/imgs/CRIS_wide.png" alt="" style="width:100%;">-->
<!--</div>-->
<!--<div class="uk-card-body">-->
<!--<h3 class="el-title uk-margin uk-card-title uk-margin-remove-adjacent uk-margin-small-bottom">-->
<!--Run compatibility test against the OpenAIRE Guidelines for CRIS Managers based on CERIF-XML.-->
<!--</h3>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--&lt;!&ndash; RIGHT HELP CONTENT &ndash;&gt;-->
<!--<aside-help-content #rightHelperContent [position]="'right'"-->
<!--[ngClass]="rightHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">-->
<!--</aside-help-content>-->
<!--</div>-->
<!--</div>-->
<!--&lt;!&ndash; BOTTOM HELP CONTENT &ndash;&gt;-->
<!--<help-content #bottomHelperContent [position]="'bottom'"-->
<!--[ngClass]="bottomHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">-->
<!--</help-content>-->
<!--</div>-->
<!--</div>-->

View File

@ -0,0 +1,19 @@
import { Component, OnInit } from '@angular/core';
@Component ({
selector: 'app-compatibility-validation',
templateUrl: 'compatibility-validate.component.html'
})
export class CompatibilityValidateComponent implements OnInit {
constructor() {}
ngOnInit() {
let body = document.getElementsByTagName('body')[0];
body.classList.remove("top_bar_active"); //remove the class
body.classList.remove("page_heading_active");
body.classList.remove("landing");
body.classList.add("dashboard");
}
}

View File

@ -0,0 +1,314 @@
<div id="page_content">
<div id="page_content_inner">
<h2 class="heading_b uk-margin-bottom">Previous validations</h2>
<!-- TOP HELP CONTENT -->
<help-content #topHelperContent [position]="'top'"
[ngClass]="topHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
<div class="uk-grid">
<!-- LEFT HELP CONTENT -->
<aside-help-content #leftHelperContent [position]="'left'"
[ngClass]="leftHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
<!-- MIDDLE -->
<div class=" uk-width-expand@m">
<div *ngIf="successMessage" class="uk-alert uk-alert-success">{{ successMessage }}</div>
<div *ngIf="failureMessage" class="uk-alert uk-alert-danger">{{ failureMessage }}</div>
<div *ngIf="errorMessage" class="uk-alert uk-alert-danger">{{ errorMessage }}</div>
<div *ngIf="loadingMessage" class="loading-big">
<div class="loader-big"
style="text-align: center; padding-top: 170px; color: rgb(47, 64, 80); font-weight: bold;">
{{ loadingMessage }}
</div>
<div class="transparentFilm"></div>
</div>
<div *ngIf="jobsOfUser">
<div class="page-controls">
<div class="md-card uk-margin-medium-bottom">
<div class="md-card-content">
<div class="uk-grid" data-uk-grid-margin="">
<div class="uk-width-1-5 uk-row-first">
<div class="uk-margin-small-top">
<div class="md-input-wrapper md-input-filled">
<label class="">Filter by job type</label>
<select class="md-input" #selectType (change)="getJobType(selectType.value)">
<option value="">--none selected--</option>
<option *ngFor="let type of jobTypes" value="{{type}}">{{type}}</option>
</select>
<span class="md-input-bar"></span>
</div>
<!--<select id="product_search_status1" data-md-selectize="" multiple="multiple" data-md-selectize-bottom="" tabindex="-1" style="display: none;" class="selectized"></select>-->
<!--<div class="selectize-control multi plugin-tooltip">-->
<!--<div class="selectize-input items not-full has-options">-->
<!--<input type="select-multiple" autocomplete="off" tabindex="" id="product_search_status-selectized1" placeholder="Status" style="width: 47px;">-->
<!--</div>-->
<!--</div>-->
<!--<div class="selectize_fix"></div>-->
</div>
</div>
<div class="uk-width-3-5">
</div>
<div class="uk-width-1-5">
<div class="uk-margin-small-top">
<div class="md-input-wrapper md-input-filled">
<label class="">Jobs per page</label>
<select #itemsPerPage class="md-input" (change)="getItemsPerPage(+itemsPerPage.value)">
<option value="10" selected>10</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option>
</select>
<span class="md-input-bar"></span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="uk-margin-bottom uk-width-1-1 filters">
<!--<h3 class="heading_a uk-margin-bottom">Filter validation jobs:</h3>-->
<ul id="filter" class="uk-subnav uk-subnav-pill">
<li class="uk-active" [class.uk-active]="currentFilter==='all'" data-uk-filter="">
<a (click)="filterJobs('all')">All jobs ({{this.jobsOfUser.totalJobs}})</a>
</li>
<li class="" [class.uk-active]="currentFilter==='successful'" data-uk-filter="filter-a">
<a (click)="filterJobs('successful')">successful ({{this.jobsOfUser.totalJobsSuccessful}})</a>
</li>
<li class="" [class.uk-active]="currentFilter==='failed'" data-uk-filter="filter-b">
<a (click)="filterJobs('failed')">failed ({{this.jobsOfUser.totalJobsFailed}})</a>
</li>
<li class="" [class.uk-active]="currentFilter==='ongoing'" data-uk-filter="filter-c">
<a (click)="filterJobs('ongoing')">ongoing ({{this.jobsOfUser.totalJobsOngoing}})</a>
</li>
</ul>
</div>
</div>
<div class="md-card uk-margin-medium-bottom">
<div class="md-card-content">
<div class="uk-overflow-container">
<table class="uk-table uk-table-nowrap table_check">
<thead>
<tr>
<th class="uk-width-2-10">Repository</th>
<th class="uk-width-1-10">Validation Type</th>
<th class="uk-width-1-10">Status</th>
<th class="uk-width-1-10">Score</th>
<th class="uk-width-1-10">Started</th>
<th class="uk-width-2-10">Guidelines</th>
<th class="uk-width-1-10">Actions</th>
<th class="uk-width-1-10"></th>
</tr>
</thead>
<tbody>
<tr *ngIf="infoMessage">
<td colspan="7">{{ infoMessage }}</td>
</tr>
<ng-container *ngIf="jobsOfUser && jobsOfUser.jobs">
<tr *ngFor="let job of jobsOfUser.jobs">
<td style="vertical-align: top !important;">
<div class="">{{ job.baseUrl }}</div>
</td>
<td style="vertical-align: top !important;">
<div *ngIf="job.validationType.includes('C')" class="">OAI Content</div>
<div *ngIf="job.validationType.includes('U')" class="">OAI Usage</div>
</td>
<td style="vertical-align: top !important;">
<div *ngIf="job.validationType.includes('C')" class="">{{ job.contentJobStatus }}</div>
<div *ngIf="job.validationType.includes('U')" class="">{{ job.usageJobStatus }}</div>
</td>
<td style="vertical-align: top !important;">
<div *ngIf="job.validationType.includes('C')" class="">{{ job.contentJobScore }}</div>
<div *ngIf="job.validationType.includes('U')" class="">{{ job.usageJobScore }}</div>
</td>
<td style="vertical-align: top !important;">
<div class="">{{ job.started }}</div>
</td>
<td style="vertical-align: top !important;">
<div class="">{{ job.guidelinesShortName }}</div>
</td>
<td style="vertical-align: top !important;">
<div>
<a [routerLink]="[job.id]">
View Results<i class="fa fa-angle-right uk-margin-small-left"></i>
</a>
</div>
<div>
<a (click)="resubmitJob(job.id.toString(), job.userEmail)">Resubmit Job<i class="fa fa-repeat uk-margin-small-left"></i></a>
</div>
</td>
<td class="uk-text-center">
<i *ngIf="job.validationStatus === 'ongoing'" title="{{job.validationStatus}}" class="material-icons" style="color: yellow; font-size: 25px;">help</i>
<i *ngIf="job.validationStatus === 'successful'" title="{{job.validationStatus}}" class="material-icons" style="color: green; font-size: 25px;">check_circle</i>
<i *ngIf="job.validationStatus === 'failed'" title="{{job.validationStatus}}" class="material-icons" style="color: red; font-size: 25px;">cancel</i>
<!--<img type="image" [src]="getResultImage(job.validationStatus)" title="{{job.validationStatus}}">-->
</td>
</tr>
</ng-container>
</tbody>
</table>
</div>
<ul class="uk-pagination uk-margin-top uk-flex-right" uk-margin>
<li><a (click)="goToPreviousPage()" class="pagination_arrow"><span uk-pagination-previous></span></a></li>
<li class="uk-active"><span>{{ (totalPages > 0) ? currentPage+1 : 0 }}</span></li>
<li><a (click)="goToNextPage()" class="pagination_arrow"><span uk-pagination-next></span></a></li>
</ul>
<!--<ul class="uk-pagination uk-margin-medium-top">-->
<!--<li class="uk-pagination-previous"><a (click)="goToPreviousPage()"><i class="uk-icon-angle-left"></i><span class="uk-margin-left">Previous</span></a></li>-->
<!--<li class=""><span>page {{ (totalPages > 0) ? currentPage+1 : 0 }} of {{ totalPages }}</span></li>-->
<!--<li class="uk-pagination-next"><a (click)="goToNextPage()"><span class="uk-margin-right">Next</span><i class="uk-icon-angle-right"></i></a></li>-->
<!--</ul>-->
</div>
</div>
<!--<div class="contentAndPagerPanel">-->
<!--<div>-->
<!--<ul class="uk-pagination">-->
<!--<li>-->
<!--<a class="uk-link uk-link-muted" (click)="goToPreviousPage()">-->
<!--<span class="uk-margin-small-right uk-pagination-previous uk-icon" uk-pagination-previous="">-->
<!--<svg width="7" height="12" viewBox="0 0 7 12" xmlns="http://www.w3.org/2000/svg"-->
<!--icon="pagination-previous" ratio="1"></svg>-->
<!--</span>-->
<!--Previous-->
<!--</a>-->
<!--</li>-->
<!--<li class="uk-margin-auto-left">-->
<!--<a class="uk-link uk-link-muted" (click)="goToNextPage()">-->
<!--Next-->
<!--<span class="uk-margin-small-left uk-pagination-next uk-icon" uk-pagination-next="">-->
<!--<svg width="7" height="12" viewBox="0 0 7 12" xmlns="http://www.w3.org/2000/svg"-->
<!--icon="pagination-next" ratio="1"></svg>-->
<!--</span>-->
<!--</a>-->
<!--</li>-->
<!--</ul>-->
<!--<div class="resultsPageLabel">page {{ (totalPages > 0) ? currentPage+1 : 0 }} of {{ totalPages }}</div>-->
<!--</div>-->
<!--<div>-->
<!--<div>-->
<!--<div class="uk-overflow-auto uk-scrollspy-inview uk-animation-slide-top-medium uk-margin-top uk-margin-bottom">-->
<!--<table class="uk-table uk-table-middle uk-table-striped" style="vertical-align: top !important;">-->
<!--<thead>-->
<!--<tr>-->
<!--<th>Repository</th>-->
<!--<th>Validation Type</th>-->
<!--<th>Status</th>-->
<!--<th>Score</th>-->
<!--<th>Started</th>-->
<!--<th>Guidelines</th>-->
<!--<th>Actions</th>-->
<!--<th></th>-->
<!--</tr>-->
<!--</thead>-->
<!--<tr *ngIf="infoMessage">-->
<!--<td colspan="7">{{ infoMessage }}</td>-->
<!--</tr>-->
<!--<tbody *ngIf="jobsOfUser && jobsOfUser.jobs">-->
<!--<tr class="el-item" *ngFor="let job of jobsOfUser.jobs">-->
<!--<td class="uk-table-shrink" style="vertical-align: top !important;">-->
<!--<div class="el-title">{{ job.baseUrl }}</div>-->
<!--</td>-->
<!--<td class="uk-table-shrink" style="vertical-align: top !important;">-->
<!--<div *ngIf="job.validationType.includes('C')" class="el-title">OAI Content</div>-->
<!--<div *ngIf="job.validationType.includes('U')" class="el-title">OAI Usage</div>-->
<!--</td>-->
<!--<td class="uk-table-shrink" style="vertical-align: top !important;">-->
<!--<div *ngIf="job.validationType.includes('C')" class="el-title">{{ job.contentJobStatus }}</div>-->
<!--<div *ngIf="job.validationType.includes('U')" class="el-title">{{ job.usageJobStatus }}</div>-->
<!--</td>-->
<!--<td class="uk-table-shrink" style="vertical-align: top !important;">-->
<!--<div *ngIf="job.validationType.includes('C')" class="el-title">{{ job.contentJobScore }}</div>-->
<!--<div *ngIf="job.validationType.includes('U')" class="el-title">{{ job.usageJobScore }}</div>-->
<!--</td>-->
<!--<td class="uk-table-shrink" style="vertical-align: top !important;">-->
<!--<div class="el-title">{{ job.started }}</div>-->
<!--</td>-->
<!--<td class="uk-table-shrink" style="vertical-align: top !important;">-->
<!--<div class="el-title">{{ job.guidelinesShortName }}</div>-->
<!--</td>-->
<!--<td class="uk-table-shrink" style="vertical-align: top !important;">-->
<!--<div class="el-link">-->
<!--<div class="viewDetailsLinkWrapper">-->
<!--<a class="viewDetails" [routerLink]="[job.id]">-->
<!--View Results<i class="fa fa-angle-right"></i>-->
<!--</a>-->
<!--</div>-->
<!--<div>-->
<!--<a class="resubmitJob" (click)="resubmitJob(job.id.toString(), job.userEmail)">Resubmit Job<i class="fa fa-repeat"></i></a>-->
<!--</div>-->
<!--</div>-->
<!--</td>-->
<!--<td class="uk-table-shrink" style="vertical-align: top !important;">-->
<!--<img type="image" [src]="getResultImage(job.validationStatus)" title="{{job.validationStatus}}">-->
<!--</td>-->
<!--</tr>-->
<!--</tbody>-->
<!--</table>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--<div>-->
<!--<ul class="uk-pagination">-->
<!--<li>-->
<!--<a class="uk-link uk-link-muted" (click)="goToPreviousPage()">-->
<!--<span class="uk-margin-small-right uk-pagination-previous uk-icon" uk-pagination-previous="">-->
<!--<svg width="7" height="12" viewBox="0 0 7 12" xmlns="http://www.w3.org/2000/svg"-->
<!--icon="pagination-previous" ratio="1"></svg>-->
<!--</span>-->
<!--Previous-->
<!--</a>-->
<!--</li>-->
<!--<li class="uk-margin-auto-left">-->
<!--<a class="uk-link uk-link-muted" (click)="goToNextPage()">-->
<!--Next-->
<!--<span class="uk-margin-small-left uk-pagination-next uk-icon" uk-pagination-next="">-->
<!--<svg width="7" height="12" viewBox="0 0 7 12" xmlns="http://www.w3.org/2000/svg"-->
<!--icon="pagination-next" ratio="1"></svg>-->
<!--</span>-->
<!--</a>-->
<!--</li>-->
<!--</ul>-->
<!--<div class="resultsPageLabel">page {{ (totalPages > 0) ? currentPage+1 : 0 }} of {{ totalPages }}</div>-->
<!--</div>-->
<!--</div>-->
<!--<div class="row"></div>-->
</div>
</div>
<!-- RIGHT HELP CONTENT -->
<aside-help-content #rightHelperContent [position]="'right'"
[ngClass]="rightHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
</div>
<!-- BOTTOM HELP CONTENT -->
<help-content #bottomHelperContent [position]="'bottom'"
[ngClass]="bottomHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
</div>
</div>

View File

@ -0,0 +1,184 @@
import { Component, OnInit } from '@angular/core';
import { jobTypes } from '../../domain/job-types';
import { MonitorService } from '../../services/monitor.service';
import { AuthenticationService } from '../../services/authentication.service';
import { JobsOfUser, StoredJob } from '../../domain/typeScriptClasses';
import { ValidatorService } from '../../services/validator.service';
import { loadingUserJobs, loadingUserJobsError, noUserJobsFound } from '../../domain/shared-messages';
import { URLParameter } from '../../domain/url-parameter';
@Component ({
selector: 'app-compatibility-validation-history',
templateUrl: 'compatibility-validation-history.component.html'
})
export class CompatibilityValidationHistoryComponent implements OnInit {
userEmail: string;
loadingMessage: string;
errorMessage: string;
infoMessage: string;
successMessage: string;
failureMessage: string;
jobTypes: string[];
jobsOfUser: JobsOfUser;
jobs: StoredJob[];
itemsPerPage: number;
currentPage: number;
currentTotalJobs: number;
totalPages: number;
currentFilter: string;
chosenJobType: string;
constructor(private authService: AuthenticationService,
private monitorService: MonitorService,
private valService: ValidatorService) {}
ngOnInit() {
this.loadTable();
let body = document.getElementsByTagName('body')[0];
body.classList.remove("top_bar_active"); //remove the class
body.classList.remove("page_heading_active");
body.classList.remove("landing");
body.classList.add("dashboard");
}
loadTable() {
// initialize
this.userEmail = this.authService.getUserEmail();
this.jobTypes = jobTypes;
this.itemsPerPage = 10;
this.currentPage = 0;
this.currentFilter = 'all';
this.chosenJobType = '';
// call API and get all jobs:
this.getJobs();
}
getJobType(type: string) {
this.chosenJobType = type;
this.currentPage = 0;
this.getJobs();
}
filterJobs(filter: string) {
this.currentFilter = filter;
this.currentPage = 0;
console.log(`requesting ${this.currentFilter} jobs`);
this.getJobs();
}
getItemsPerPage(num: number) {
this.itemsPerPage = num;
this.currentPage = 0;
this.getJobs();
}
goToNextPage() {
if ( (this.currentPage + 1) < this.totalPages ) {
this.currentPage++;
console.log(`Get me page ${this.currentPage}!`);
this.getJobs();
}
}
goToPreviousPage() {
if (this.currentPage > 0) {
this.currentPage--;
console.log(`Get me page ${this.currentPage}!`);
this.getJobs();
}
}
storedJobs () {
this.valService.getStoredJobsNew().subscribe(
jobs => this.jobs = jobs,
error => console.log(error.status),
() => {
console.log('Also hit getStoredJobsNew and got:');
console.log(this.jobs);
}
);
}
getJobs() {
this.loadingMessage = loadingUserJobs;
this.errorMessage = '';
this.infoMessage = '';
this.successMessage = '';
this.failureMessage = '';
const params: URLParameter[] = [];
// params.push({key: 'user', value: [this.userEmail]});
if ( this.chosenJobType ) {
params.push({key: 'jobType', value: [this.chosenJobType]});
}
params.push({key: 'offset', value: [( (this.currentPage) * this.itemsPerPage).toString()]});
params.push({key: 'limit', value: [this.itemsPerPage.toString()]});
/* can also add dateFrom and dateTo if needed */
params.push({key: 'validationStatus', value: [this.currentFilter]});
params.push({key: 'includeJobsTotal', value: ['true']});
this.monitorService.getJobsOfUser(params).subscribe(
jobs => this.jobsOfUser = jobs,
error => {
console.log(`The API returned ${error.status}`);
this.loadingMessage = '';
this.jobsOfUser = null;
this.errorMessage = loadingUserJobsError;
},
() => {
if (this.currentFilter === 'all') {
this.currentTotalJobs = this.jobsOfUser.totalJobs;
} else if (this.currentFilter === 'successful') {
this.currentTotalJobs = this.jobsOfUser.totalJobsSuccessful;
} else if (this.currentFilter === 'failed') {
this.currentTotalJobs = this.jobsOfUser.totalJobsFailed;
} else {
this.currentTotalJobs = this.jobsOfUser.totalJobsOngoing;
}
this.totalPages = Math.ceil(this.currentTotalJobs / this.itemsPerPage);
this.loadingMessage = '';
if (!this.totalPages || !this.jobsOfUser.jobs) {
this.infoMessage = noUserJobsFound;
this.currentPage = -1;
}
}
);
}
getResultImage(status: string) {
// if (status === 'ongoing') {
// return `../../../assets/imgs/icon_colours-question.jpg`;
// } else if (status === 'successful') {
// return `../../../assets/imgs/icon_colours-check.jpg`;
// } else {
// return `../../../assets/imgs/icon_colours-x.jpg`;
// }
if (status === 'ongoing') {
return `../../../assets/imgs/icon_colours-question.jpg`;
} else if (status === 'successful') {
return `check_circle`;
} else {
return `../../../assets/imgs/icon_colours-x.jpg`;
}
}
resubmitJob (id: string) {
this.valService.reSubmitJobForValidation(id).subscribe(
res => this.successMessage = `The job with id ${id} was successfully resubmitted`,
error => {
this.failureMessage = `Could not resubmit the job with id ${id}`;
console.log(error);
}
);
this.getJobs();
}
}

View File

@ -0,0 +1,288 @@
<div id="page_content">
<div id="page_content_inner">
<h2 class="heading_b uk-margin-bottom">Validation results for</h2>
<!-- TOP HELP CONTENT -->
<help-content #topHelperContent [position]="'top'"
[ngClass]="topHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
<div class="uk-grid">
<!-- LEFT HELP CONTENT -->
<aside-help-content #leftHelperContent [position]="'left'"
[ngClass]="leftHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
<!-- MIDDLE -->
<div class=" uk-width-expand@m">
<div>
<div *ngIf="errorMessage" class="uk-alert uk-alert-danger">{{ errorMessage }}</div>
<div *ngIf="loadingMessage" class="loading-big">
<div class="loader-big"
style="text-align: center; padding-top: 170px; color: rgb(47, 64, 80); font-weight: bold;">
{{ loadingMessage }}
</div>
<div class="transparentFilm"></div>
</div>
<div *ngIf="jobSummary">
<div class="uk-margin-medium-bottom">
<h4 class="uk-h4 uk-text-primary uk-scrollspy-inview uk-animation-slide-top-medium"
uk-scrollspy-class=""><span>{{jobSummary.baseUrl}}</span></h4>
<div class="uk-margin-small">by {{jobSummary.userEmail}}</div>
</div>
<div class="uk-grid">
<div class="uk-width-3-4">
<div id="container_C" class="md-card tabs">
<div class="md-card-content">
<highcharts-chart
[Highcharts] = "HighchartsForContent"
[options] = "chartOptionsForContent"
style="width: 100%; height: 400px; display: block; margin-top: 20px"
></highcharts-chart>
</div>
</div>
</div>
<div class="uk-width-1-4">
<div id="container_U" class="md-card tabs">
<div class="md-card-content">
<highcharts-chart
[Highcharts] = "HighchartsForUsage"
[options] = "chartOptionsForUsage"
style="width: 100%; height: 400px; display: block; margin-top: 20px"
></highcharts-chart>
</div>
</div>
</div>
</div>
<div class="md-card tabs">
<div class="md-card-content">
<div class="uk-grid uk-grid-divider" data-uk-grid-margin="">
<div class="uk-width-3-4@m uk-row-first">
<ul class="uk-tab" data-uk-tab="{connect:'#tabs_anim4', animation:'slide-left'}">
<li id="forContent" class="uk-active" aria-expanded="true"><a href="#">for Content</a></li>
<li id="forUsage" aria-expanded="false" class=""><a href="#">for Usage</a></li>
</ul>
<ul id="tabs_anim4" class="uk-switcher uk-margin">
<li aria-hidden="false" class="uk-active" style="animation-duration: 200ms;">
<div class="uk-grid-margin uk-grid uk-grid-stack">
<div class="uk-width-1-1@m uk-first-column">
<div class="uk-overflow-auto uk-scrollspy-inview uk-animation-slide-top-medium">
<div *ngIf="noContent" class="uk-alert">{{ noContent }}</div>
<div *ngIf="contentResults && contentResults.length > 0">
<table class="uk-table uk-table-striped uk-table-middle rules-table">
<thead>
<tr>
<th class="uk-width-2-10">Rule Name</th>
<th class="uk-width-4-10 uk-text-nowrap">Rule Description</th>
<th class="uk-width-1-10 uk-text-nowrap">Rule Weight</th>
<th class="uk-width-1-10 uk-text-nowrap"># of records</th>
<th class="uk-width-2-10 uk-text-nowrap">Status</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let contentRule of contentResults" class="el-item">
<td class="uk-table-shrink">
<div class="el-title">{{ contentRule.name }}</div>
</td>
<td class="uk-table-shrink">
<div class="el-title" [innerHtml]="contentRule.description">
</div>
</td>
<td class="uk-table-shrink">
<div class="el-title">{{ contentRule.weight }}</div>
</td>
<td class="uk-table-shrink">
<div class="el-title">{{ contentRule.successes }}</div>
</td>
<td class="uk-table-shrink">
<div *ngIf="!contentRule.hasErrors" class="el-title">
<i class="material-icons" style="color: #4b991f">check_circle_outline</i>
</div>
<div *ngIf="contentRule.hasErrors && contentRule.mandatory">
<i class="material-icons" style="color: #cd242b">highlight_off</i>
<a class="errorlink viewErrors uk-margin-left"
(click)="viewErrors(contentRule)"><span>View Errors</span></a>
</div>
<div *ngIf="contentRule.hasErrors && !contentRule.mandatory">
<i class="material-icons" style="color: #e9d60d">error_outline</i>
<a class="warninglink viewErrors uk-margin-left"
(click)="viewErrors(contentRule)"><span>View Warnings</span></a>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</li>
<li aria-hidden="true" style="animation-duration: 200ms;" class="">
<div class="uk-grid-margin uk-grid uk-grid-stack">
<div class="uk-width-1-1@m uk-first-column">
<div class="uk-overflow-auto uk-scrollspy-inview uk-animation-slide-top-medium">
<div *ngIf="noUsage" class="uk-alert">{{ noUsage }}</div>
<div *ngIf="usageResults && usageResults.length > 0">
<table class="uk-table uk-table-striped uk-table-middle rules-table">
<thead>
<tr>
<th class="uk-width-2-10">Rule Name</th>
<th class="uk-width-4-10 uk-text-nowrap">Rule Description</th>
<th class="uk-width-1-10 uk-text-nowrap">Rule Weight</th>
<th class="uk-width-1-10 uk-text-nowrap"># of records</th>
<th class="uk-width-2-10 uk-text-nowrap">Status</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let usageRule of usageResults" class="el-item">
<td class="uk-table-shrink">
<div class="el-title">{{ usageRule.name }}</div>
</td>
<td class="uk-table-shrink">
<div class="el-title" [innerHtml]="usageRule.description">
</div>
</td>
<td class="uk-table-shrink">
<div class="el-title">{{ usageRule.weight }}</div>
</td>
<td class="uk-table-shrink">
<div class="el-title">{{ usageRule.successes }}</div>
</td>
<td class="uk-table-shrink">
<div *ngIf="!usageRule.hasErrors" class="el-title">
<i class="material-icons" style="color: #4b991f">check_circle_outline</i>
</div>
<div *ngIf="usageRule.hasErrors && usageRule.mandatory">
<i class="material-icons" style="color: #cd242b">highlight_off</i>
<a class="errorlink viewErrors uk-margin-left"
(click)="viewErrors(usageRule)"><span>View Errors</span></a>
</div>
<div *ngIf="usageRule.hasErrors && !usageRule.mandatory">
<i class="material-icons" style="color: #e9d60d">error_outline</i>
<a class="warninglink viewErrors uk-margin-left"
(click)="viewErrors(usageRule)"><span>View Warnings</span></a>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</li>
</ul>
</div>
<div class="uk-width-1-4@m">
<div class="uk-margin-medium-bottom">
<p>
Score for content:
<span *ngIf="jobSummary.contentJobScore>=50" class="uk-badge uk-badge-success uk-text-upper uk-margin-small-left">{{ jobSummary.contentJobScore }}</span>
<span *ngIf="jobSummary.contentJobScore<50" class="uk-badge uk-badge-danger uk-text-upper uk-margin-small-left">{{ jobSummary.contentJobScore }}</span>
</p>
<p>
Score for usage:
<span *ngIf="jobSummary.usageJobScore>=50" class="uk-badge uk-badge-success uk-text-upper uk-margin-small-left">{{ jobSummary.usageJobScore }}</span>
<span *ngIf="jobSummary.usageJobScore<50" class="uk-badge uk-badge-danger uk-text-upper uk-margin-small-left">{{ jobSummary.usageJobScore }}</span>
</p>
</div>
<h2 class="heading_c uk-margin-small-bottom">Details</h2>
<ul class="md-list md-list-addon">
<li>
<div class="md-list-addon-element">
<!--<img class="md-user-image md-list-addon-avatar dense-image dense-ready" src="assets/img/avatars/avatar_02_tn@2x.png" alt="" data-dense-cap="2">-->
</div>
<div class="md-list-content">
<span class="md-list-heading">{{ jobSummary.jobType }}</span>
</div>
</li>
<li>
<div class="md-list-addon-element">
<i class="md-list-addon-icon material-icons">gavel</i>
</div>
<div class="md-list-content">
<span class="md-list-heading">{{ jobSummary.guidelinesShortName }}</span>
<span class="uk-text-small uk-text-muted">Guidelines</span>
</div>
</li>
<li>
<div class="md-list-addon-element">
<i class="md-list-addon-icon material-icons">collections_bookmark</i>
</div>
<div class="md-list-content">
<span class="md-list-heading">{{ jobSummary.validationSet }}</span>
<span class="uk-text-small uk-text-muted">Validation set</span>
</div>
</li>
<li>
<div class="md-list-addon-element">
<i class="md-list-addon-icon material-icons"></i>
</div>
<div class="md-list-content uk-margin-small-bottom">
<span class="md-list-heading">{{ jobSummary.started }}</span>
<span class="uk-text-small uk-text-muted">Started</span>
</div>
<div class="md-list-content">
<span class="md-list-heading">{{ jobSummary.ended ? jobSummary.ended : '--' }}</span>
<span class="uk-text-small uk-text-muted">Ended</span>
</div>
</li>
<li>
<div class="md-list-addon-element">
<i class="md-list-addon-icon material-icons"></i>
</div>
<div class="md-list-content">
<span class="md-list-heading">{{ jobSummary.duration }}</span>
<span class="uk-text-small uk-text-muted">Duration</span>
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- RIGHT HELP CONTENT -->
<aside-help-content #rightHelperContent [position]="'right'"
[ngClass]="rightHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
</div>
<!-- BOTTOM HELP CONTENT -->
<help-content #bottomHelperContent [position]="'bottom'"
[ngClass]="bottomHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
</div>
</div>
<confirmation-dialog #checkErrors [title]="modalTitle" [isModalShown]="false" [hideModalButton]="'OK'">
<div>
<p>See the list of errors found for this specific rule</p>
<a *ngFor="let er of currentErrors" class="uk-display-block" target="_blank" href="{{ linkToError(er) }}">{{ er }}</a>
</div>
</confirmation-dialog>

View File

@ -0,0 +1,135 @@
import { Component, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { JobResultEntry, StoredJob } from '../../domain/typeScriptClasses';
import { MonitorService } from '../../services/monitor.service';
import { loadingJobSummary, loadingJobSummaryError, noContentRulesResults,
noUsageRulesResults } from '../../domain/shared-messages';
import { ConfirmationDialogComponent } from '../../shared/reusablecomponents/confirmation-dialog.component';
import { AuthenticationService } from '../../services/authentication.service';
import * as Highcharts from 'highcharts';
import {text} from '@angular/core/src/render3/instructions';
@Component({
selector: 'app-compatibility-validation-results',
templateUrl: 'compatibility-validation-results.component.html'
})
export class CompatibilityValidationResultsComponent implements OnInit {
errorMessage: string;
loadingMessage: string;
noRulesTested: string;
noContent: string;
noUsage: string;
jobSummary: StoredJob;
contentResults: JobResultEntry[] = [];
usageResults: JobResultEntry[] = [];
currentErrors: string[] = [];
modalTitle: string;
isModalShown: boolean;
ruleNameForContent: string[] = [];
ruleNameForUsage: string[] = [];
unprocessedDataForContent: string[] = [];
unprocessedDataForUsage: string[] = [];
processedDataForContent: number[] = [];
processedDataForUsage: number[] = [];
HighchartsForContent: typeof Highcharts = Highcharts;
HighchartsForUsage: typeof Highcharts = Highcharts;
chartOptionsForContent: Highcharts.Options;
chartOptionsForUsage: Highcharts.Options;
@ViewChild('checkErrors')
public checkErrors: ConfirmationDialogComponent;
constructor (private route: ActivatedRoute,
private router: Router,
private monitorService: MonitorService,
private authService: AuthenticationService) {}
ngOnInit () {
if (this.authService.getIsUserLoggedIn()) {
this.getJobInfo();
} else {
const id = this.route.snapshot.paramMap.get('id');
this.authService.redirectUrl = '/compatibility/browseHistory/' + id;
this.authService.loginWithState();
}
let body = document.getElementsByTagName('body')[0];
body.classList.remove("top_bar_active"); //remove the class
body.classList.remove("page_heading_active");
body.classList.remove("landing");
body.classList.add("dashboard");
}
getJobInfo() {
const id = this.route.snapshot.paramMap.get('id');
this.loadingMessage = loadingJobSummary;
this.monitorService.getJobSummary(id, 'all').subscribe(
job => {
this.jobSummary = job;
if (this.jobSummary.resultEntries && this.jobSummary.resultEntries.length) {
this.jobSummary.resultEntries.forEach(
entry => {
if (entry.type === 'content') {
this.contentResults.push(entry);
this.ruleNameForContent.push(entry.name);
this.unprocessedDataForContent.push(entry.successes.split('/')[0]);
} else if (entry.type === 'usage') {
this.usageResults.push(entry);
this.ruleNameForUsage.push(entry.name);
this.unprocessedDataForUsage.push(entry.successes.split('/')[0]);
}
}
);
}
},
error => {
console.log(error);
this.errorMessage = loadingJobSummaryError;
this.loadingMessage = '';
},
() => {
this.loadingMessage = '';
if (!this.contentResults.length) {
this.noContent = noContentRulesResults;
} else {
this.processedDataForContent = this.unprocessedDataForContent.map(Number);
this.chartOptionsForContent = {
title: { text: ''},
yAxis: { title: { text: 'Number of records' } },
xAxis: { categories: this.ruleNameForContent },
series: [{ name: 'For content', data: this.processedDataForContent, type: 'column' }]
};
}
if (!this.usageResults.length) {
this.noUsage = noUsageRulesResults;
} else {
this.processedDataForUsage = this.unprocessedDataForUsage.map(Number);
this.chartOptionsForUsage = {
title: { text: ''},
yAxis: { title: { text: 'Number of records' } },
xAxis: { categories: this.ruleNameForUsage },
series: [{ name: 'For usage', data: this.processedDataForUsage, type: 'column' }]
};
}
/*if ( this.authService.activateFrontAuthorization && (this.authService.getUserEmail() !== this.jobSummary.userEmail.trim()) ) {
this.router.navigateByUrl('/403-forbidden', { skipLocationChange: true });
}*/
}
);
}
viewErrors(rule: JobResultEntry) {
this.modalTitle = `Rule: ${rule.name}`;
this.currentErrors = rule.errors;
this.checkErrors.showModal();
}
linkToError(er: string) {
return encodeURI(`${this.jobSummary.baseUrl}?verb=GetRecord&metadataPrefix=${this.jobSummary.metadataPrefix}&identifier=${er}`);
}
}

View File

@ -0,0 +1,12 @@
import {Component, OnInit} from '@angular/core';
@Component ({
selector: 'app-compatibility',
templateUrl: '../pageContainer.html'
})
export class CompatibilityComponent implements OnInit {
constructor() {}
ngOnInit() {}
}

View File

@ -0,0 +1,41 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { TabsModule } from 'ngx-bootstrap';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { CompatibilityRouting } from './compatibility.routing';
import { ReusableComponentsModule } from '../../shared/reusablecomponents/reusable-components.module';
import { CompatibilityComponent } from './compatibility.component';
import { CompatibilityValidateComponent } from './compatibility-validate.component';
import { CompatibilityValidationHistoryComponent } from './compatibility-validation-history.component';
import { CompatibilityValidationResultsComponent } from './compatibility-validation-results.component';
import { CompatibilityValidateTypeComponent } from './compatibility-validate-type.component';
import { CompatibilityValidateStep1Component } from './compatibility-validate-forms/compatibility-validate-step1.component';
import { CompatibilityValidateStep2Component } from './compatibility-validate-forms/compatibility-validate-step2.component';
import { CompatibilityValidateStep3Component } from './compatibility-validate-forms/compatibility-validate-step3.component';
import { CompatibilityValidateStep3CrisComponent } from './compatibility-validate-forms/compatibility-validate-step3-cris.component';
import {HighchartsChartModule} from 'highcharts-angular';
@NgModule ({
imports: [
CommonModule,
TabsModule.forRoot(),
FormsModule,
ReactiveFormsModule,
CompatibilityRouting,
ReusableComponentsModule,
HighchartsChartModule
],
declarations: [
CompatibilityComponent,
CompatibilityValidateComponent,
CompatibilityValidationHistoryComponent,
CompatibilityValidationResultsComponent,
CompatibilityValidateTypeComponent,
CompatibilityValidateStep1Component,
CompatibilityValidateStep2Component,
CompatibilityValidateStep3Component,
CompatibilityValidateStep3CrisComponent
]
})
export class CompatibilityModule {}

View File

@ -0,0 +1,59 @@
import { NgModule} from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { CompatibilityComponent } from './compatibility.component';
import { CompatibilityValidateTypeComponent } from './compatibility-validate-type.component';
import { CompatibilityValidationHistoryComponent } from './compatibility-validation-history.component';
import { CompatibilityValidationResultsComponent } from './compatibility-validation-results.component';
import { CompatibilityValidateComponent } from './compatibility-validate.component';
import { AuthGuardService } from '../../services/auth-guard.service';
const compatibilityRoutes: Routes = [
{
path: '',
component: CompatibilityComponent,
children: [
{
path: 'validate',
component: CompatibilityValidateComponent,
canActivate: [AuthGuardService]
},
{
path: 'validate/:type',
component: CompatibilityValidateTypeComponent,
canActivate: [AuthGuardService]
},
{
path: 'browseHistory',
component: CompatibilityValidationHistoryComponent,
canActivate: [AuthGuardService]
},
{
path: 'browseHistory/:id',
component: CompatibilityValidationResultsComponent
},
// {
// path: 'monitor',
// component: CompatibilityMonitorComponent,
// canActivate: [AuthGuardService]
// },
// {
// path: 'monitor/:id',
// component: CompatibilityMonitorRepoComponent,
// canActivate: [AuthGuardService]
// },
// {
// path: 'monitor/fullHistory/:id',
// component: CompatibilityMonitorFullHistoryRepoComponent,
// canActivate: [AuthGuardService]
// }
]
}
];
@NgModule ({
imports: [RouterModule.forChild(compatibilityRoutes)],
exports: [RouterModule]
})
export class CompatibilityRouting {}

View File

@ -0,0 +1,435 @@
<div id="page_content">
<div id="page_content_inner">
<h2 *ngIf="eventsPage" class="heading_b uk-margin-bottom">
{{ eventsPage.datasource }}
<span class="sub-heading">{{ topic }}</span>
</h2>
<!-- TOP HELP CONTENT -->
<help-content #topHelperContent [position]="'top'"
[ngClass]="topHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
<div class="uk-grid">
<!-- LEFT HELP CONTENT -->
<aside-help-content #leftHelperContent [position]="'left'"
[ngClass]="leftHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
<!-- MIDDLE -->
<div class=" uk-width-expand@m">
<div>
<div *ngIf="errorMessage" class="uk-alert uk-alert-danger">{{errorMessage}}</div>
<div *ngIf="loadingMessage" class="loading-big">
<div class="loader-big" style="text-align: center; padding-top: 170px; color: rgb(47, 64, 80); font-weight: bold;">{{ loadingMessage }}</div>
<div class="transparentFilm"></div>
</div>
<div *ngIf="noEvents" class="uk-alert">{{ noEvents }}</div>
<div *ngIf="!noEvents && !loadingMessage && !errorMessage && eventsPage && eventsPage.totalPages>0" class="events-results">
<div style="display: flex;justify-content: space-between;">
<div class="resultsInfo" style="margin-top: auto;">
<span class="number">{{eventsPage.total}}</span> RESULTS, PAGE <span class="number">{{(currentPage)+1}}</span> OF <span class="number">{{ eventsPage.totalPages }}</span>
</div>
<div class="uk-inline">
<ul class="uk-pagination" uk-margin>
<li><a (click)="goToPreviousPage()" class="pagination_arrow"><span uk-pagination-previous></span></a></li>
<li class="uk-active"><span>{{ (eventsPage.totalPages > 0) ? currentPage+1 : 0 }}</span></li>
<li><a (click)="goToNextPage()" class="pagination_arrow"><span uk-pagination-next></span></a></li>
</ul>
</div>
</div>
<hr class="adminResultsHeader">
<!--<div class="uk-margin-bottom">Showing {{(currentPage*10)+1 }}-{{ ( (eventsPage.total < 10) || (eventsPage.total < (currentPage+1)*10) ) ? (eventsPage.total) : (currentPage+1)*10 }} of {{ eventsPage.total }} results</div>-->
<div *ngFor="let event of eventsPage.values; let item_i = index" class="md-card md-card-hover eventCard">
<div class="md-card-content large-padding">
<div *ngIf="event.result.originalId" class="uk-text-meta">ID: {{event.result.originalId}}</div>
<div *ngIf="event.result.titles && event.result.titles.length>0">
<div class="repositoryCardHeader uk-margin-bottom uk-margin-small-top">
<h4>{{ event.result.titles[0] }}</h4>
</div>
</div>
<ng-container *ngIf="event.highlight.creators && event.highlight.creators.length>0">
<div class="small-content">
<span class="uk-badge uk-badge-success uk-margin-small-right">{{event.highlight.creators.length}} author ORCID(s) added</span>
<span class="mute-title">FROM: </span>
<ng-container *ngIf="event.provenance.url">
<a href="{{ event.provenance.url }}" target="_blank">{{ event.provenance.repositoryName }}</a>
<span *ngIf="event.provenance.id"> (ID: {{ event.provenance.id }})</span>
</ng-container>
<ng-container *ngIf="!event.provenance.url">
<span>{{ event.provenance.repositoryName }}</span>
</ng-container>
</div>
<div class="uk-margin-top uk-margin-medium-bottom small-content">
<div *ngFor="let author of event.highlight.creators; let p_index = index" class="uk-margin-small-bottom">
<span class="highlightIndex">{{(p_index + 1)}}. </span>
<span>{{ author.fullname }} <b>&nbsp;&nbsp;({{ author.orcid }})&nbsp;&nbsp;</b></span>
</div>
</div>
</ng-container>
<ng-container *ngIf="event.highlight.pids && event.highlight.pids.length>0">
<div class="small-content">
<span class="uk-badge uk-badge-success uk-margin-small-right">{{event.highlight.pids.length}} PID(s) added</span>
<span class="mute-title">FROM: </span>
<ng-container *ngIf="event.provenance.url">
<a href="{{ event.provenance.url }}" target="_blank">{{ event.provenance.repositoryName }}</a>
<span *ngIf="event.provenance.id"> (ID: {{ event.provenance.id }})</span>
</ng-container>
<ng-container *ngIf="!event.provenance.url">
<span>{{ event.provenance.repositoryName }}</span>
</ng-container>
</div>
<div class="uk-margin-top uk-margin-medium-bottom small-content">
<div *ngFor="let pid of event.highlight.pids; let p_index = index" class="uk-margin-small-bottom">
<span class="highlightIndex">{{(p_index + 1)}}. </span>
<span>{{ pid.value }} <b>&nbsp;&nbsp;({{ pid.type }})&nbsp;&nbsp;</b></span>
</div>
</div>
</ng-container>
<ng-container *ngIf="event.highlight.abstracts && event.highlight.abstracts.length>0">
<div class="small-content">
<span class="uk-badge uk-badge-success uk-margin-small-right">{{event.highlight.abstracts.length}} Abstract(s) added</span>
<span class="mute-title">FROM: </span>
<ng-container *ngIf="event.provenance.url">
<a href="{{ event.provenance.url }}" target="_blank">{{ event.provenance.repositoryName }}</a>
<span *ngIf="event.provenance.id"> (ID: {{ event.provenance.id }})</span>
</ng-container>
<ng-container *ngIf="!event.provenance.url">
<span>{{ event.provenance.repositoryName }}</span>
</ng-container>
</div>
<div class="uk-margin-top uk-margin-medium-bottom small-content">
<div *ngFor="let abs of event.highlight.abstracts; let a_index = index" class="uk-margin-small-bottom">
<span class="highlightIndex">{{(a_index + 1)}}. </span>
<span class=""><read-more-text [text]="abs" [maxHeight]="40"></read-more-text></span>
</div>
</div>
</ng-container>
<ng-container *ngIf="event.highlight.projects && event.highlight.projects.length>0">
<div class="small-content">
<span class="uk-badge uk-badge-success uk-margin-small-right">{{event.highlight.projects.length}} Project(s) added</span>
<span class="mute-title">FROM: </span>
<ng-container *ngIf="event.provenance.url">
<a href="{{ event.provenance.url }}" target="_blank">{{ event.provenance.repositoryName }}</a>
<span *ngIf="event.provenance.id"> (ID: {{ event.provenance.id }})</span>
</ng-container>
<ng-container *ngIf="!event.provenance.url">
<span>{{ event.provenance.repositoryName }}</span>
</ng-container>
</div>
<div class="uk-margin-top uk-margin-medium-bottom small-content">
<div *ngFor="let proj of event.highlight.projects; let p_index = index" class="uk-margin-small-bottom">
<span class="highlightIndex">{{(p_index + 1)}}. </span>
<span *ngIf="proj.acronym && proj.acronym !==''">{{ proj.acronym }}</span>
<span *ngIf="!proj.acronym || proj.acronym ===''">{{ proj.title }}</span>
<span *ngIf="(proj.funder && proj.funder !=='') ||
(proj.fundingProgram && proj.fundingProgram !=='')">
(<span *ngIf="proj.funder && proj.funder !==''">{{ proj.funder }} </span>
<span *ngIf="(proj.funder && proj.funder !=='') &&
(proj.fundingProgram && proj.fundingProgram !=='')">/</span>
<span *ngIf="proj.fundingProgram && proj.fundingProgram !==''">{{ proj.fundingProgram }}</span>)
</span>
</div>
</div>
</ng-container>
<ng-container *ngIf="event.highlight.subjects && event.highlight.subjects.length>0">
<div class="small-content">
<span class="uk-badge uk-badge-success uk-margin-small-right">{{event.highlight.subjects.length}} Subject(s) added</span>
<span class="mute-title">FROM: </span>
<ng-container *ngIf="event.provenance.url">
<a href="{{ event.provenance.url }}" target="_blank">{{ event.provenance.repositoryName }}</a>
<span *ngIf="event.provenance.id"> (ID: {{ event.provenance.id }})</span>
</ng-container>
<ng-container *ngIf="!event.provenance.url">
<span>{{ event.provenance.repositoryName }}</span>
</ng-container>
</div>
<div class="uk-margin-top uk-margin-medium-bottom small-content">
<div *ngFor="let subj of event.highlight.subjects; let s_index = index" class="uk-margin-small-bottom">
<span class="highlightIndex">{{(s_index + 1)}}. </span>
<span>{{ subj.value }}</span>
</div>
</div>
</ng-container>
<ng-container *ngIf="event.highlight.publications && event.highlight.publications.length>0">
<div class="small-content">
<span class="uk-badge uk-badge-success uk-margin-small-right">{{event.highlight.publications.length}} Publications(s) added</span>
<span class="mute-title">FROM: </span>
<ng-container *ngIf="event.provenance.url">
<a href="{{ event.provenance.url }}" target="_blank">{{ event.provenance.repositoryName }}</a>
<span *ngIf="event.provenance.id"> (ID: {{ event.provenance.id }})</span>
</ng-container>
<ng-container *ngIf="!event.provenance.url">
<span>{{ event.provenance.repositoryName }}</span>
</ng-container>
</div>
<div class="uk-margin-top uk-margin-medium-bottom small-content">
<div *ngFor="let pub of event.highlight.publications; let p_index = index" class="uk-margin-small-bottom">
<span class="highlightIndex">{{(p_index + 1)}}. </span>
<span>{{ pub.title }} (ID: {{pub.originalId}})</span>
</div>
</div>
</ng-container>
<ng-container *ngIf="event.highlight.datasets && event.highlight.datasets.length>0">
<div class="small-content">
<span class="uk-badge uk-badge-success uk-margin-small-right">{{event.highlight.datasets.length}} Dataset(s) added</span>
<span class="mute-title">FROM: </span>
<ng-container *ngIf="event.provenance.url">
<a href="{{ event.provenance.url }}" target="_blank">{{ event.provenance.repositoryName }}</a>
<span *ngIf="event.provenance.id"> (ID: {{ event.provenance.id }})</span>
</ng-container>
<ng-container *ngIf="!event.provenance.url">
<span>{{ event.provenance.repositoryName }}</span>
</ng-container>
</div>
<div class="uk-margin-top uk-margin-medium-bottom small-content">
<div *ngFor="let dataset of event.highlight.datasets; let d_index = index" class="uk-margin-small-bottom">
<span class="highlightIndex">{{(d_index + 1)}}. </span>
<span>{{ dataset.title }} <span *ngIf="dataset.pids && dataset.pids.length>0">({{dataset.pids[0].type}}: {{dataset.pids[0].value}})</span></span>
</div>
</div>
</ng-container>
<ng-container *ngIf="event.highlight.softwares && event.highlight.softwares.length>0">
<div class="small-content">
<span class="uk-badge uk-badge-success uk-margin-small-right">{{event.highlight.softwares.length}} Software(s) added</span>
<span class="mute-title">FROM: </span>
<ng-container *ngIf="event.provenance.url">
<a href="{{ event.provenance.url }}" target="_blank">{{ event.provenance.repositoryName }}</a>
<span *ngIf="event.provenance.id"> (ID: {{ event.provenance.id }})</span>
</ng-container>
<ng-container *ngIf="!event.provenance.url">
<span>{{ event.provenance.repositoryName }}</span>
</ng-container>
</div>
<div class="uk-margin-top uk-margin-medium-bottom small-content">
<div *ngFor="let software of event.highlight.softwares; let s_index = index" class="uk-margin-small-bottom">
<span class="highlightIndex">{{(s_index + 1)}}. </span>
<span>{{ software.name }}</span>
<span *ngIf="software.description"> <br> {{ software.description }}</span>
<span><br><a href="{{ software.landingPage }}" target="_blank">{{ software.landingPage }}</a></span>
</div>
</div>
</ng-container>
<ng-container *ngIf="event.highlight.instances && event.highlight.instances.length>0">
<div class="small-content">
<span class="uk-badge uk-badge-success uk-margin-small-right">{{event.highlight.instances.length}} OA version(s) added</span>
<span class="mute-title">FROM: </span>
<ng-container *ngIf="event.provenance.url">
<a href="{{ event.provenance.url }}" target="_blank">{{ event.provenance.repositoryName }}</a>
<span *ngIf="event.provenance.id"> (ID: {{ event.provenance.id }})</span>
</ng-container>
<ng-container *ngIf="!event.provenance.url">
<span>{{ event.provenance.repositoryName }}</span>
</ng-container>
</div>
<div class="uk-margin-top uk-margin-medium-bottom small-content">
<div *ngFor="let l of event.highlight.instances; let l_index = index" class="uk-margin-small-bottom">
<span class="highlightIndex">{{(l_index + 1)}}. </span>
<span>
{{ l.license }}&nbsp;&nbsp;<b>{{ l.hostedby }}</b>
<a href="{{ l.url }}" target="_blank" class="uk-margin-left">{{ l.url }}</a>
</span>
</div>
</div>
</ng-container>
<div *ngIf="selectedItemIndex == item_i" class="uk-text-meta uk-text-center">
<a (click)="showLess(item_i)">Show less <i class="fas fa-angle-up uk-margin-small-left"></i></a>
</div>
<div *ngIf="selectedItemIndex != item_i" class="uk-text-meta uk-text-center">
<a (click)="showMore(item_i)">Show more <i class="fas fa-angle-down uk-margin-small-left"></i></a>
</div>
<ng-container *ngIf="selectedItemIndex == item_i">
<hr>
<!--AUTHORS-->
<div *ngIf="event.result.creators && event.result.creators.length>0" class="uk-margin-small-bottom">
<span class="mute-title">Author(s): </span>
<span *ngFor="let auth of event.result.creators; let au_index = index" class="small-content">
<span *ngIf="au_index>0"> | </span>
<span>{{ auth.fullname }} <b>&nbsp;({{ auth.orcid }})&nbsp;&nbsp;</b></span>
</span>
</div>
<!--PIDs-->
<div *ngIf="event.result.pids && event.result.pids.length>0" class="uk-margin-small-bottom">
<span class="mute-title">PID(s): </span>
<span *ngFor="let pid of event.result.pids; let p_index = index" class="small-content">
<br *ngIf="p_index > 0">
<span>{{ pid.value }} <b>&nbsp;&nbsp;({{ pid.type }})&nbsp;&nbsp;</b></span>
</span>
</div>
<!--Abstracts-->
<div *ngIf="event.result.abstracts && event.result.abstracts.length>0" class="uk-margin-small-bottom">
<span class="mute-title">Abstract(s): </span>
<span *ngFor="let abs of event.result.abstracts; let a_index = index" class="small-content">
<br *ngIf="a_index > 0">
<span>
<read-more-text [text]="abs" [maxHeight]="83"></read-more-text>
</span>
</span>
</div>
<!--Projects/Relations-->
<div *ngIf="event.result.projects && event.result.projects.length>0" class="uk-margin-small-bottom">
<span class="mute-title">Project(s)/Relation(s): </span>
<span *ngFor="let proj of event.result.projects; let p_index = index" class="small-content">
<br *ngIf="p_index > 0">
<span *ngIf="proj.acronym && proj.acronym !==''">{{ proj.acronym }}</span>
<span *ngIf="!proj.acronym || proj.acronym ===''">{{ proj.title }}</span>
<span *ngIf="(proj.funder && proj.funder !=='') ||
(proj.fundingProgram && proj.fundingProgram !=='')">
(<span *ngIf="proj.funder && proj.funder !==''">{{ proj.funder }} </span>
<span *ngIf="(proj.funder && proj.funder !=='') &&
(proj.fundingProgram && proj.fundingProgram !=='')">/</span>
<span *ngIf="proj.fundingProgram && proj.fundingProgram !==''">{{ proj.fundingProgram }}</span>)
</span>
</span>
</div>
<!--Subjects-->
<div *ngIf="event.result.subjects && event.result.subjects.length>0" class="uk-margin-small-bottom">
<span class="mute-title">Subject(s): </span>
<span *ngFor="let subj of event.result.subjects; let s_index = index" class="small-content">
<span *ngIf="s_index>0"> | </span>
<span>{{ subj.value }}</span>
</span>
</div>
<!--Publications-->
<div *ngIf="event.result.publications && event.result.publications.length>0" class="uk-margin-small-bottom">
<span *ngIf="this.topic.includes('PUBLICATION')" class="mute-title">{{this.lastTopicEntry}} Publication(s): </span>
<span *ngIf="!this.topic.includes('PUBLICATION')" class="mute-title">Publication(s): </span>
<span *ngFor="let pub of event.result.publications; let p_index = index" class="small-content">
<br *ngIf="p_index > 0">
<span>{{ pub.title }} (ID: {{pub.originalId}})</span>
</span>
</div>
<!--Datasets-->
<div *ngIf="event.result.datasets && event.result.datasets.length>0" class="uk-margin-small-bottom">
<span *ngIf="this.topic.includes('DATASET')" class="mute-title">{{this.lastTopicEntry}} Dataset(s): </span>
<span *ngIf="!this.topic.includes('DATASET')" class="mute-title">Dataset(s): </span>
<span *ngFor="let dataset of event.result.datasets; let d_index = index" class="small-content">
<br *ngIf="d_index > 0">
<span>{{ dataset.title }} <span *ngIf="dataset.pids && dataset.pids.length>0">({{dataset.pids[0].type}}: {{dataset.pids[0].value}})</span></span>
</span>
</div>
<!--Software-->
<div *ngIf="event.result.softwares && event.result.softwares.length>0" class="uk-margin-small-bottom">
<span *ngIf="this.topic.includes('SOFTWARE')" class="mute-title">{{this.lastTopicEntry}} Software(s): </span>
<span *ngIf="!this.topic.includes('SOFTWARE')" class="mute-title">Software(s): </span>
<span *ngFor="let software of event.result.softwares; let s_index = index" class="small-content">
<br *ngIf="s_index > 0">
<span>{{ software.name }}</span>
<span *ngIf="software.description"> <br> {{ software.description }}</span>
<span><br><a href="{{ software.landingPage }}" target="_blank">{{ software.landingPage }}</a></span>
<span *ngIf="software.landingPage !== software.repository"><br><a href="{{ software.repository }}" target="_blank">{{ software.repository }}</a></span>
</span>
</div>
<!--Publication Date-->
<div *ngIf="event.result.publicationdate && event.result.publicationdate.length>0" class="uk-margin-small-bottom">
<span class="mute-title">Publication date(s): </span>
<span class="small-content">
{{ event.result.publicationdate }}
</span>
</div>
<!--Rights-->
<div *ngIf="event.result.instances && event.result.instances.length>0" class="uk-margin-small-bottom">
<span class="mute-title">Rights: </span>
<span *ngFor="let l of event.result.instances; let l_index = index" class="small-content">
<br *ngIf="l_index > 0">
<span>
{{ l.license }}&nbsp;&nbsp;<b>{{ l.hostedby }}</b> - <a class="" href="{{ l.url }}" target="_blank">{{ l.url }}</a>
</span>
</span>
</div>
</ng-container>
</div>
</div>
<!-- BOTTOM PAGINATION LINKS -->
<ul class="uk-pagination uk-margin-top uk-flex-right" uk-margin>
<li><a (click)="goToPreviousPage()" class="pagination_arrow"><span uk-pagination-previous></span></a></li>
<li class="uk-active"><span>{{ (eventsPage.totalPages > 0) ? currentPage+1 : 0 }}</span></li>
<li><a (click)="goToNextPage()" class="pagination_arrow"><span uk-pagination-next></span></a></li>
</ul>
</div>
</div>
</div>
<!-- RIGHT HELP CONTENT -->
<aside-help-content #rightHelperContent [position]="'right'"
[ngClass]="rightHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
</div>
<!-- BOTTOM HELP CONTENT -->
<help-content #bottomHelperContent [position]="'bottom'"
[ngClass]="bottomHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
</div>
</div>

View File

@ -0,0 +1,132 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { BrokerService } from '../../services/broker.service';
import { loadingEvents, noEventsForTopic, noServiceMessage } from '../../domain/shared-messages';
import { EventsPage } from '../../domain/typeScriptClasses';
@Component ({
selector: 'app-content-notifications-of-subscription',
templateUrl: 'content-notifications-of-subscription.component.html'
})
export class ContentNotificationsOfSubscriptionComponent implements OnInit {
noEvents: string;
errorMessage: string;
loadingMessage: string;
subId: string;
topic: string;
lastTopicEntry = '';
eventsPage: EventsPage;
currentPage: number; /* DELETE WHEN getNotificationsBySubscriptionId IS FIXED AND SENDS CORRECT VALUE FOR CURRENT PAGE */
selectedItemIndex: number;
constructor(private route: ActivatedRoute,
private brokerService: BrokerService) {}
ngOnInit () {
this.subId = this.route.snapshot.paramMap.get('id');
this.currentPage = 0; /* DELETE WHEN getNotificationsBySubscriptionId IS FIXED AND SENDS CORRECT VALUE FOR CURRENT PAGE */
this.getEventsPage(0);
let body = document.getElementsByTagName('body')[0];
body.classList.remove("top_bar_active"); //remove the class
body.classList.remove("page_heading_active");
body.classList.remove("landing");
body.classList.add("dashboard");
}
getEventsPage(page: number) {
this.noEvents = '';
this.errorMessage = '';
this. loadingMessage = loadingEvents;
this.brokerService.getNotificationsBySubscriptionId(this.subId, page, 10).subscribe(
events => this.eventsPage = events,
error => {
this.loadingMessage = '';
this.errorMessage = noServiceMessage;
console.log(error);
},
() => {
this.loadingMessage = '';
console.log(this.eventsPage);
if (!this.eventsPage.total) {
this.noEvents = noEventsForTopic;
}
this.getCorrectTopic();
// console.log('Topic: ' + this.topic);
this.lastTopicEntry = this.topic.substring(this.topic.lastIndexOf('|') + 1).toLowerCase();
this.lastTopicEntry = this.replaceAll(this.lastTopicEntry, '_', ' ');
// console.log('Last topic entry: ' + this.lastTopicEntry);
}
);
}
replaceAll(str, find, replace) {
return str.replace(new RegExp(find, 'g'), replace);
}
goToNextPage() {
/* RESTORE WHEN getNotificationsBySubscriptionId IS FIXED AND SENDS CORRECT VALUE FOR CURRENT PAGE */
/*if(this.eventsPage.currPage < this.eventsPage.totalPages) {
console.log(`Get me page ${this.eventsPage.currPage+1}!`);
this.getEventsPage(this.eventsPage.currPage+1);
}*/
/* DELETE WHEN getNotificationsBySubscriptionId IS FIXED AND SENDS CORRECT VALUE FOR CURRENT PAGE */
if ( (this.currentPage + 1) < this.eventsPage.totalPages) {
this.currentPage = this.currentPage + 1;
console.log(`Get me page ${this.currentPage}!`);
this.getEventsPage(this.currentPage);
window.scrollTo(0, 0);
}
}
goToPreviousPage() {
/* RESTORE WHEN getNotificationsBySubscriptionId IS FIXED AND SENDS CORRECT VALUE FOR CURRENT PAGE */
/*if(this.eventsPage.currPage > 0) {
console.log(`Get me page ${this.eventsPage.currPage-1}!`);
this.getEventsPage(this.eventsPage.currPage-1);
}*/
/* DELETE WHEN getNotificationsBySubscriptionId IS FIXED AND SENDS CORRECT VALUE FOR CURRENT PAGE */
if (this.currentPage > 0) {
this.currentPage = this.currentPage - 1;
console.log(`Get me page ${this.currentPage}!`);
this.getEventsPage(this.currentPage);
window.scrollTo(0, 0);
}
}
isHighlighted(item: any, itemList: any[]) {
return itemList.some(x => x === item);
}
getCorrectTopic() {
const temp = this.eventsPage.topic.split('/');
this.topic = temp[0];
for (let i = 1; i < temp.length; i++) {
this.topic += ` | ${temp[i]}`;
}
}
displayFullResultInfo(i: number) {
if (this.selectedItemIndex === i) {
this.selectedItemIndex = null;
} else {
this.selectedItemIndex = i;
}
}
showMore(i: number) {
this.selectedItemIndex = i;
}
showLess(i: number) {
this.selectedItemIndex = null;
}
}

View File

@ -0,0 +1,94 @@
<div id="page_content">
<div id="page_content_inner">
<h2 class="heading_b uk-margin-bottom">Enrich Your Content - Browse Subscriptions</h2>
<!-- TOP HELP CONTENT -->
<help-content #topHelperContent [position]="'top'"
[ngClass]="topHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
<div class="uk-grid">
<!-- LEFT HELP CONTENT -->
<aside-help-content #leftHelperContent [position]="'left'"
[ngClass]="leftHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
<!-- MIDDLE -->
<div class=" uk-width-expand@m">
<div>
<div *ngIf="errorMessage" class="uk-alert uk-alert-danger">{{errorMessage}}</div>
<div *ngIf="successMessage" class="uk-alert uk-alert-success">{{successMessage}}</div>
<div *ngIf="loadingMessage" class="loading-big">
<div class="loader-big" style="text-align: center; padding-top: 170px; color: rgb(47, 64, 80); font-weight: bold;">{{ loadingMessage }}</div>
<div class="transparentFilm"></div>
</div>
<div *ngIf="noSubscriptions" class="uk-alert">{{noSubscriptions}}</div>
</div>
<div *ngIf="subscrOfUser && subKeys">
<div *ngFor="let key of subKeys" class="uk-margin-medium-top">
<div class="md-card">
<div class="md-card-toolbar">
<h3 class="md-card-toolbar-heading-text">
{{ key }}
</h3>
</div>
<div class="md-card-content">
<table class="uk-table uk-table-striped uk-table-middle">
<thead>
<tr>
<th>Topic</th>
<th>Creation Date</th>
<th>Last Notification Date</th>
<th class="uk-text-nowrap"># of notifications</th>
<th class="uk-text-nowrap">Actions</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let sub of subscrOfUser[key]" class="el-item">
<td class="uk-table-shrink">
<a [routerLink]="sub.id">
<div class="el-title">{{ sub.topic }}</div>
</a>
</td>
<td class="uk-table-shrink">
<div class="el-title">{{ sub.creationDate | date:'yyyy-MM-dd HH:mm:ss' }}</div>
</td>
<td class="uk-table-shrink">
<div class="el-title">{{ sub.lastNotificationDate | date:'yyyy-MM-dd HH:mm:ss' }}</div>
</td>
<td class="uk-text-nowrap uk-table-shrink">
<div class="el-title">{{ sub.count }}</div>
</td>
<td class="uk-text-nowrap uk-table-shrink">
<a class="el-link" (click)="deleteSubscription(sub.id)">
<i class="fa fa-remove" aria-hidden="true"></i>
</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<!-- RIGHT HELP CONTENT -->
<aside-help-content #rightHelperContent [position]="'right'"
[ngClass]="rightHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
</div>
<!-- BOTTOM HELP CONTENT -->
<help-content #bottomHelperContent [position]="'bottom'"
[ngClass]="bottomHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
</div>
</div>

View File

@ -0,0 +1,79 @@
import {Component, OnInit} from '@angular/core';
import { SimpleSubscriptionDesc } from '../../domain/typeScriptClasses';
import { AuthenticationService } from '../../services/authentication.service';
import { BrokerService } from '../../services/broker.service';
import { deletingSubscription, deletingSubscriptionError, deletingSubscriptionSuccess,
loadingSubscriptions, noServiceMessage, noSubscriptionsFound } from '../../domain/shared-messages';
@Component ({
selector: 'app-content-notifications',
templateUrl: 'content-notifications.component.html'
})
export class ContentNotificationsComponent implements OnInit {
errorMessage: string;
successMessage: string;
loadingMessage: string;
noSubscriptions: string;
subscrOfUser: Map<string, SimpleSubscriptionDesc[]> = new Map<string, SimpleSubscriptionDesc[]>();
subKeys: string[];
constructor(private authService: AuthenticationService,
private brokerService: BrokerService) {}
ngOnInit() {
this.getSubscriptions();
let body = document.getElementsByTagName('body')[0];
body.classList.remove("top_bar_active"); //remove the class
body.classList.remove("page_heading_active");
body.classList.remove("landing");
body.classList.add("dashboard");
}
getSubscriptions() {
this.errorMessage = '';
this.loadingMessage = loadingSubscriptions;
this.subKeys = [];
this.brokerService.getSimpleSubscriptionsOfUser().subscribe(
subscrs => this.subscrOfUser = subscrs,
error => {
console.log(`getSimpleSubscriptions returned error`);
console.log(error);
this.loadingMessage = '';
this.errorMessage = noServiceMessage;
},
() => {
this.loadingMessage = '';
for (const key in this.subscrOfUser) {
this.subKeys.push(key);
console.log(key);
}
if (!this.subKeys.length) {
this.noSubscriptions = noSubscriptionsFound;
}
}
);
}
deleteSubscription(key: string) {
this.loadingMessage = deletingSubscription;
this.successMessage = '';
this.errorMessage = '';
this.brokerService.unsubscribe(key).subscribe(
response => console.log(`unsubscribe responded with ${response}`),
error => {
console.log(error);
this.loadingMessage = '';
this.errorMessage = deletingSubscriptionError;
},
() => {
this.loadingMessage = '';
this.successMessage = deletingSubscriptionSuccess;
this.getSubscriptions();
}
);
}
}

View File

@ -0,0 +1,13 @@
import { Component, OnInit } from '@angular/core';
@Component ({
selector: 'app-content',
templateUrl: '../pageContainer.html'
})
export class ContentComponent implements OnInit {
constructor() {}
ngOnInit() {}
}

View File

@ -0,0 +1,29 @@
import { ReusableComponentsModule } from '../../shared/reusablecomponents/reusable-components.module';
import { ReactiveFormsModule } from '@angular/forms';
import { ContentNotificationsOfSubscriptionComponent } from './content-notifications-of-subscription.component';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { TabsModule } from 'ngx-bootstrap';
import { ContentRouting } from './content.routing';
import { ContentComponent } from './content.component';
import { ContentNotificationsComponent } from './content-notifications.component';
@NgModule ({
imports: [
CommonModule,
TabsModule.forRoot(),
ContentRouting,
ReactiveFormsModule,
ReusableComponentsModule
],
declarations: [
ContentComponent,
// ContentEventsComponent,
// ContentEventsOfRepositoryComponent,
// ContentEventsOfRepoEventslistComponent,
ContentNotificationsComponent,
ContentNotificationsOfSubscriptionComponent
]
})
export class ContentModule {}

View File

@ -0,0 +1,41 @@
import { RouterModule, Routes } from '@angular/router';
import { NgModule } from '@angular/core';
import { ContentComponent } from './content.component';
import { ContentNotificationsComponent } from './content-notifications.component';
import { ContentNotificationsOfSubscriptionComponent } from './content-notifications-of-subscription.component';
const contentRoutes: Routes = [
{
path: '',
component: ContentComponent,
children: [
// {
// path: 'events',
// component: ContentEventsComponent,
// },
// {
// path: 'events/:name',
// component: ContentEventsOfRepositoryComponent,
// },
// {
// path: 'events/:name/:topic',
// component: ContentEventsOfRepoEventslistComponent,
// },
{
path: 'notifications',
component: ContentNotificationsComponent,
},
{
path: 'notifications/:id',
component: ContentNotificationsOfSubscriptionComponent,
}
]
}
];
@NgModule ({
imports: [RouterModule.forChild(contentRoutes)],
exports: [RouterModule]
})
export class ContentRouting {}

View File

@ -0,0 +1,5 @@
<div id="page_content">
<div id="page_content_inner">
<div>This is an empty page</div>
</div>
</div>

View File

@ -0,0 +1,11 @@
import { Component } from '@angular/core';
@Component ({
selector: 'app-empty-page',
templateUrl: './empty-page.component.html',
})
export class EmptyPageComponent {
constructor() {}
}

View File

@ -0,0 +1,172 @@
<div id="page_content">
<div id="page_content_inner" class="whiteBackground uk-padding-remove-left uk-padding-remove-right">
<div *ngIf="loadingMessage" class="loading-big">
<div class="loader-big" style="text-align: center; padding-top: 170px; color: rgb(47, 64, 80); font-weight: bold;">{{ loadingMessage }}</div>
<div class="transparentFilm"></div>
</div>
<div *ngIf="!loadingMessage" class="uk-margin-top">
<div class="uk-section">
<div class="uk-margin-large-left uk-margin-large-right">
<h3 class="heading_b" style="font-weight: 500">You have not yet registered any repositories</h3>
<div class="uk-grid uk-child-width-1-3@l uk-child-width-1-2@m uk-child-width-1-1@s uk-grid-match">
<div class="">
<div class="md-card md-card-hover">
<a [routerLink]="['/sources/register']">
<div class="md-card-content large-padding" style="min-height: 150px;">
<div class="">
<strong>Register</strong>
</div>
<p>Register data sources in the OpenAIRE infrastructure.</p>
</div>
</a>
</div>
</div>
<div class="">
<div class="md-card md-card-hover">
<a [routerLink]="['/compatibility/validate']">
<div class="md-card-content large-padding" style="min-height: 150px;">
<div class="">
<strong>Validate</strong>
</div>
<p>Validate data sources against OpenAIRE guidelines.</p>
</div>
</a>
</div>
</div>
</div>
</div>
</div>
<div class="uk-section uk-background-norepeat uk-background-cover uk-background-top-center"
style="background-image: url('../../../assets/imgs/landing/abstract2.svg'); !important; min-height: calc(80vh);" uk-height-viewport="offset-top: true; offset-bottom: 20;">
<div class="uk-margin-large-top uk-margin-large-left uk-margin-large-right">
<h3 class="heading_b" style="font-weight: 700">Take a look at the Provide Dashboard and functionalities</h3>
<div class="uk-container uk-container-large uk-margin-medium-top">
<div class="uk-slider" tabindex="-1" uk-slider="velocity: 0;autoplay: true;autoplay-interval: 5000;pause-on-hover: false;center: true">
<div class="uk-position-relative">
<div class="uk-slider-container">
<ul class="uk-slider-items uk-child-width-1-1" style="transform: translateX(-1300px);">
<li class="ng-star-inserted uk-active" tabindex="-1" style="order: 1;">
<div class="uk-flex uk-padding uk-child-width-1-2@m uk-child-width-1-1@s uk-grid" uk-grid="">
<div class="uk-first-column">
<video class="uk-box-shadow-large uk-border-rounded" autoplay loop>
<source src="../../../../assets/mp4/validate.mp4" type="video/mp4">
</video>
<!--<img class="uk-box-shadow-large uk-border-rounded" src="../../../../assets/gifs/validate.gif">-->
</div>
<div class="uk-margin-top">
<div>
<div class="uk-text-bold uk-h4">Validate</div>
<div class="uk-margin-medium">
Interoperable metadata is key for effective content sharing.
<p class="uk-margin-top">
OpenAIRE guidelines are a global standard to expose and share your content. Use our validation service and see how you can apply them.
</p>
</div>
<div class="uk-inline">
<a class="uk-button uk-button-primary uk-text-uppercase" [routerLink]="['/about']">learn more</a>
</div>
</div>
</div>
</div>
</li>
<li tabindex="-1" style="order: 1;">
<div class="uk-flex uk-padding uk-child-width-1-2@m uk-child-width-1-1@s uk-grid" uk-grid="">
<div class="uk-first-column">
<video class="uk-box-shadow-large uk-border-rounded" autoplay loop>
<source src="../../../../assets/mp4/register.mp4" type="video/mp4">
</video>
<!--<img class="uk-box-shadow-large uk-border-rounded" src="../../../../assets/gifs/register.gif">-->
</div>
<div class="uk-margin-top">
<div>
<div class="uk-text-bold uk-h4">Register</div>
<div class="uk-margin-medium">
Reach a wider audience around the world.
<p class="uk-margin-top">
Register your literature or data repository, OA Journal, CRIS in OpenAIRE and be part of a global interlinked network.
</p>
</div>
<div class="uk-inline">
<a class="uk-button uk-button-primary uk-text-uppercase" [routerLink]="['/about']">learn more</a>
</div>
</div>
</div>
</div>
</li>
<li tabindex="-1" style="order: 1;">
<div class="uk-flex uk-padding uk-child-width-1-2@m uk-child-width-1-1@s uk-grid" uk-grid="">
<div class="uk-first-column">
<video class="uk-box-shadow-large uk-border-rounded" autoplay loop>
<source src="../../../../assets/mp4/enrich.mp4" type="video/mp4">
</video>
<!--<img class="uk-box-shadow-large uk-border-rounded" src="../../../../assets/gifs/enrichments.gif">-->
</div>
<div class="uk-margin-top">
<div>
<div class="uk-text-bold uk-h4">Enrich</div>
<div class="uk-margin-medium">
Improve your metadata. Get more connections.
<p class="uk-margin-top">
Our newly released OA Broker service offers a wealth of information on scholarly communication data. Find out what interests you and subscribe to enrich your records.
</p>
</div>
<div class="uk-inline">
<a class="uk-button uk-button-primary uk-text-uppercase" [routerLink]="['/about']">learn more</a>
</div>
</div>
</div>
</div>
</li>
<li tabindex="-1" style="order: 1;">
<div class="uk-flex uk-padding uk-child-width-1-2@m uk-child-width-1-1@s uk-grid" uk-grid="">
<div class="uk-first-column">
<video class="uk-box-shadow-large uk-border-rounded" autoplay loop>
<source src="../../../../assets/mp4/usage-stat.mp4" type="video/mp4">
</video>
<!--<img class="uk-box-shadow-large uk-border-rounded" src="../../../../assets/gifs/usageStats.gif">-->
</div>
<div class="uk-margin-top">
<div>
<div class="uk-text-bold uk-h4">Usage statistics</div>
<div class="uk-margin-medium">
Open research impact empowers Open Science.
<p class="uk-margin-top">
Share usage data via OpenAIRE's global Open Metrics Service. Get the benefit of an aggregated environment to broaden the mechanisms for impact assessment.
</p>
</div>
<div class="uk-inline">
<a class="uk-button uk-button-primary uk-text-uppercase" [routerLink]="['/about']">learn more</a>
</div>
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
<ul class="uk-position-relative uk-slider-nav uk-dotnav uk-flex-center uk-margin">
<li uk-slider-item="0" class="uk-active"><a href="#"></a></li>
<li uk-slider-item="1" class=""><a href="#"></a></li>
<li uk-slider-item="2" class=""><a href="#"></a></li>
<li uk-slider-item="3" class=""><a href="#"></a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,56 @@
import { Component, OnInit } from '@angular/core';
import { RepositoryService } from "../../services/repository.service";
import { SharedService } from "../../services/shared.service";
import { RepositorySnippet } from "../../domain/typeScriptClasses";
import { Router } from "@angular/router";
@Component ({
selector: 'app-join',
templateUrl: './join.component.html',
})
export class JoinComponent implements OnInit {
repositoriesOfUser: RepositorySnippet[];
loadingMessage: string;
constructor(private repositoryService: RepositoryService,
private sharedService: SharedService,
private router: Router) {
}
ngOnInit() {
this.loadingMessage = ' ';
let body = document.getElementsByTagName('body')[0];
body.classList.remove("landing");
body.classList.add("dashboard");
if(this.sharedService.getRepositoriesOfUser() && this.sharedService.getRepositoriesOfUser().length>0) {
this.repositoriesOfUser = this.sharedService.getRepositoriesOfUser();
if(this.repositoriesOfUser.length>0)
this.router.navigate([`/repository/${this.repositoriesOfUser[0].id}/dashboard`]);
else
this.loadingMessage = null;
} else {
this.getReposOfUser();
}
}
getReposOfUser(): void {
this.repositoryService.getRepositoriesOfUser()
.subscribe(
repos => {
this.repositoriesOfUser = repos;
if(this.repositoriesOfUser.length>0)
this.router.navigate([`/repository/${this.repositoriesOfUser[0].id}/dashboard`]);
else
this.loadingMessage = null;
},
error => { console.log(error); }
);
}
}

View File

@ -0,0 +1,367 @@
<!--MOBILE & PAD PORTRAIT-->
<div class="uk-hidden@m">
<div class="provideLanding">
<div class="image-front-topbar uk-section-default"
uk-scrollspy="{&quot;target&quot;:&quot;[uk-scrollspy-class]&quot;,&quot;cls&quot;:&quot;uk-animation-fade&quot;,&quot;delay&quot;:false}" tm-header-transparent="light">
<!--<div style="background-image: url('../../../../assets/imgs/landing/Group 1149.svg'); background-color: rgb(255, 255, 255); box-sizing: border-box; min-height: calc(-101.35px + 100vh);"-->
<!--<div style="background-image: url('../../../../assets/imgs/landing/Group 1149.svg'); background-color: rgb(255, 255, 255); box-sizing: border-box; min-height: calc(-101.35px + 100vh);"-->
<div style="background: transparent linear-gradient(0deg, #F7F7F7 20%, #E2EEFA 30%) 0% 0% no-repeat padding-box; box-sizing: border-box; min-height: calc(-101.35px + 100vh);"
class="uk-background-norepeat uk-background-cover uk-background-top-center uk-background-fixed uk-section uk-padding-remove-bottom uk-flex uk-flex-middle" uk-height-viewport="offset-top: true;offset-bottom: 20">
<div class="uk-width-1-1">
<!--<div class="uk-margin-medium uk-grid uk-grid-stack" uk-grid="">-->
<!--<div class="uk-width-1-1@m">-->
<!--</div>-->
<!--</div>-->
<div class="uk-container uk-container-large uk-margin-large aboutPage">
<!--<div class="uk-sticky-placeholder" style="height: 84px; margin: 0px;"></div>-->
<div class="uk-grid uk-flex-middle uk-grid uk-grid-stack uk-margin-small-left" uk-grid="">
<div class="el-overlay uk-panel uk-width-1-2@l uk-width-1-2@m uk-dark">
<div class="uk-margin-left uk-margin-right">
<h1 class="el-title uk-margin">Capture the essence</h1>
<div class="uk-margin-medium-top">
<p class="text-muted">The OpenAIRE Content Provider Dashboard is a one-stop-shop web service where data providers (repository, data archive, journal, aggregator, CRIS system) interact with OpenAIRE. It provides the front-end access to many of OpenAIREs backend services.</p>
</div>
</div>
<!--<p><a (click)="goToPage('/dashboard')" class="el-link uk-button uk-button-primary">Start here</a></p>-->
</div>
<div class="el-overlay uk-panel uk-width-1-2@l uk-width-1-2@m uk-dark" style="text-align: right">
<div class="uk-margin-left uk-margin-right">
<img style="box-shadow: 0px 3px 8px #00000033;" src="../../../../assets/imgs/landing/about-us-dashboard-2.png">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="uk-section-secondary uk-section uk-section-small uk-padding-remove-bottom uk-padding-remove-top uk-preserve-color">
<div style="position: relative; top: 120px">
<div style="text-align: center">
<img src="../../../../assets/imgs/landing/_0002_Group-2.png" width="214">
</div>
</div>
<div class="uk-container uk-container-expand uk-margin-large-top">
<div class="validationAndRegistrationSection uk-padding">
<div class="uk-container uk-container-medium uk-container-center uk-margin-large-top">
<div class="" style="text-align: center">
<h2 class="">Validation & Registration</h2>
<p>
The OpenAIRE Validator service allows to test your repositorys compatibility with the OpenAIRE Guidelines. If validation succeeds the data source can be registered for regular aggregation and indexing in OpenAIRE. OpenAIRE allows for registration of institutional and thematic repositories registered in OpenDOAR, research data repositories registered in re3data, individual e-Journals, CRIS, aggregators and publishers.
</p>
<p class="uk-margin-remove-bottom">
The Validator service includes two main steps to perform the aggregation and indexing of your datasource in OpenAIRE:
</p>
</div>
</div>
<div class="uk-container uk-container-large uk-container-center">
<div class="uk-grid uk-child-width-1-2@l uk-child-width-1-2@m">
<div class="uk-margin-medium-top">
<!--<div>-->
<!--<div style="position: relative; top: 10px; text-align: right;right: 82px;">-->
<!--<img src="../../../../assets/imgs/landing/arrow5.svg">-->
<!--</div>-->
<h3 class="uk-margin-remove-top">1st: Validate your datasource</h3>
<p>Test the compatibility of your repository/journal or aggregator to the OpenAIRE guidelines. If validation
succeeds the data source can be registered for regular aggregation and indexing in OpenAIRE.</p>
<!--<div style="position: relative; top: -10px; text-align: right;right: -145px;">-->
<!--<img src="../../../../assets/imgs/landing/arrow7.svg">-->
<!--</div>-->
</div>
<div class="uk-margin-medium-top">
<h3>2nd: Register your datasource</h3>
<p>Register your literature repository, data repository, journal or aggregator in OpenAIRE.</p>
<p>Once registered in OpenAIRE, the data source manager are able to use the Provide functionalities to validate their data source compatibility with the OpenAIRE Guidelines, to get notification to enrich their research results with additional or missing metadata, and to track the data source usage activity.</p>
</div>
</div>
</div>
<div class="uk-container uk-container-large uk-container-center uk-margin-large-top">
<div class="uk-text-center">
<p>Learn more: <a href="https://www.openaire.eu/validator-registration-guide" target="_blank">https://www.openaire.eu/validator-registration-guide</a></p>
</div>
</div>
</div>
</div>
</div>
<div class="uk-section-secondary uk-section uk-section-large uk-padding-remove-top uk-padding-remove-bottom uk-preserve-color">
<div class="uk-container uk-container-expand" style="position: relative; top: -260px">
<div class="uk-grid">
<div class="uk-width-1-2@l uk-width-1-2@m">
<div style="position: relative; top: 255px">
<div style="text-align: center">
<img src="../../../../assets/imgs/landing/_0001_Group-3.png" width="158">
</div>
</div>
<!--<div style="position: relative; top: -4px; left: 550px;">-->
<!--<img src="../../../../assets/imgs/landing/arrow3.svg">-->
<!--</div>-->
<div class="enrichmentsSection uk-padding" style="margin-top: 175px">
<!--<div style="text-align: center">-->
<!--<img src="../../../../assets/imgs/landing/_0001_Group-3.png" width="158">-->
<!--</div>-->
<div class="uk-margin-large-top" style="text-align: center">
<h2 class="">Enrichments</h2>
<p>Content enrichment is a powerful tool that enables Content providers to enrich research artifacts with additional metadata, through the OpenAIRE Notification Broker Service.</p>
<p>Learn more: <a href="https://www.openaire.eu/content-enrichment-guide" target="_blank">https://www.openaire.eu/content-enrichment-guide</a></p>
</div>
</div>
<!--<div style="position: relative; top: -50px; text-align: right;right: -40px;">-->
<!--<img src="../../../../assets/imgs/landing/arrow4.svg">-->
<!--</div>-->
</div>
<div class="uk-width-1-2@l uk-width-1-2@m uk-margin-xlarge" style="position: relative; top: -290px">
<div style="position: relative; top: 275px">
<div style="text-align: center">
<img src="../../../../assets/imgs/landing/_0003_Group-1.png" width="258">
</div>
</div>
<div class="measureSection uk-padding">
<!--<div style="text-align: center">-->
<!--<img src="../../../../assets/imgs/landing/_0003_Group-1.png" width="258">-->
<!--</div>-->
<div class="uk-margin-large-top" style="text-align: center">
<h2 class="">Usage Statistics</h2>
<p>OpenAIREs Usage Statistic service uses the Matomo Open Source Analytics platform (matomo.org) to track usage activity. It collects and analyzes usage data from the network of OpenAIRE data providers and exploits usage metrics like downloads and metadata views.</p>
<p>Learn more: <a href="https://www.openaire.eu/guides-usage-statistics" target="_blank">https://www.openaire.eu/guides-usage-statistics</a></p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="uk-section uk-section-large uk-section-muted uk-background-norepeat uk-background-cover uk-background-top-center
uk-background-fixed uk-section uk-flex uk-flex-middle"
style="background: transparent linear-gradient(0deg, #E2EEFA 20%, #F7F7F7 70%) 0% 0% no-repeat padding-box; box-sizing: border-box; position: relative; top: -450px">
<div class="uk-container uk-container-xsmall uk-container-center uk-margin-left uk-margin-right">
<div class="uk-grid uk-flex" style="display: block; text-align: center">
<div class="">
<h2>Contact us to help you.</h2>
<p class="text-muted">Are you looking for more? Get in touch with our team and let us help you.</p>
<a class="uk-margin-large-top uk-text-uppercase uk-button uk-button-primary" href="https://www.openaire.eu/contact-us/" target="_blank">Get in touch</a>
</div>
<div class="uk-margin-top">
<img src="../../../../assets/imgs/landing/_0000_Group-4.png" width="153">
</div>
</div>
</div>
<!--<div class="uk-container uk-container-large">-->
<!--<div class="uk-grid uk-flex" style="align-items: center">-->
<!--<div class="uk-width-1-3@l uk-width-1-3@m">-->
<!--<img src="../../../../assets/imgs/landing/_0000_Group-4.png">-->
<!--</div>-->
<!--<div class="uk-width-2-3@l uk-width-2-3@m">-->
<!--<div class="uk-margin-large-left">-->
<!--<h2>Contact us to help you.</h2>-->
<!--<p class="text-muted">Are you looking for more? Get in touch with our team and let us help you.</p>-->
<!--<button class="uk-margin-large-top uk-text-uppercase uk-button uk-button-primary">Get in touch</button>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
</div>
</div>
</div>
<!--LAPTOP & PAD LANDSCAPE-->
<div class="uk-visible@m">
<div class="provideLanding">
<div class="image-front-topbar uk-section-default"
uk-scrollspy="{&quot;target&quot;:&quot;[uk-scrollspy-class]&quot;,&quot;cls&quot;:&quot;uk-animation-fade&quot;,&quot;delay&quot;:false}" tm-header-transparent="light">
<div style="background-color: #F7F7F7; box-sizing: border-box; min-height: calc(-101.35px + 100vh);"
class="uk-background-norepeat uk-background-cover uk-background-top-center uk-background-fixed uk-section uk-padding-remove-bottom uk-flex uk-flex-middle" uk-height-viewport="offset-top: true;offset-bottom: 20">
<div class="uk-width-1-1">
<div class="uk-margin-medium uk-grid uk-grid-stack" uk-grid="">
<div class="uk-width-1-1@m">
</div>
</div>
<div class="uk-container uk-container-expand uk-margin-large aboutPage">
<div class="uk-sticky-placeholder" style="height: 84px; margin: 0px;"></div>
<div class="uk-grid-large uk-flex-middle uk-grid uk-grid-stack uk-margin-large-left" uk-grid="">
<div class="el-overlay uk-panel uk-width-1-2@l uk-width-1-2@m uk-dark">
<div class="uk-margin-left uk-margin-right">
<h1 class="el-title uk-margin">Capture the essence</h1>
<div class="uk-margin-medium-top">
<p class="text-muted">The OpenAIRE Content Provider Dashboard is a one-stop-shop web service where data providers (repository, data archive, journal, aggregator, CRIS system) interact with OpenAIRE. It provides the front-end access to many of OpenAIREs backend services.</p>
</div>
</div>
<!--<p><a (click)="goToPage('/dashboard')" class="el-link uk-button uk-button-primary">Start here</a></p>-->
</div>
<div class="el-overlay uk-panel uk-width-1-2@l uk-width-1-2@m uk-dark" style="text-align: right">
<div class="uk-margin-left uk-margin-right">
<img style="box-shadow: 0px 3px 8px #00000033;" src="../../../../assets/imgs/landing/about-us-dashboard-2.png">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="uk-section-secondary uk-section uk-section-small uk-padding-remove-bottom uk-padding-remove-top uk-preserve-color">
<div style="position: relative; top: 150px">
<div style="text-align: center">
<img src="../../../../assets/imgs/landing/_0002_Group-2.png" width="214">
</div>
</div>
<div class="uk-container uk-container-expand uk-margin-large-top">
<div class="validationAndRegistrationSection uk-padding">
<div class="uk-container uk-container-medium uk-container-center uk-margin-large-top">
<div class="" style="text-align: center">
<h2 class="">Validation & Registration</h2>
<p>
The OpenAIRE Validator service allows to test your repositorys compatibility with the OpenAIRE Guidelines. If validation succeeds the data source can be registered for regular aggregation and indexing in OpenAIRE. OpenAIRE allows for registration of institutional and thematic repositories registered in OpenDOAR, research data repositories registered in re3data, individual e-Journals, CRIS, aggregators and publishers.
</p>
<p class="uk-margin-remove-bottom">
The Validator service includes two main steps to perform the aggregation and indexing of your datasource in OpenAIRE:
</p>
</div>
</div>
<div class="uk-container uk-container-large uk-container-center">
<div class="uk-grid uk-child-width-1-2@l uk-child-width-1-2@m">
<div class="paddingLargeLeft paddingLargeRight">
<!--<div>-->
<div style="position: relative; top: 10px; text-align: right;right: 82px;">
<img src="../../../../assets/imgs/landing/arrow5.svg">
</div>
<h3 class="uk-margin-remove-top">1st: Validate your datasource</h3>
<p>Test the compatibility of your repository/journal or aggregator to the OpenAIRE guidelines. If validation
succeeds the data source can be registered for regular aggregation and indexing in OpenAIRE.</p>
<div style="position: relative; top: -10px; text-align: right;right: -145px;">
<img src="../../../../assets/imgs/landing/arrow7.svg">
</div>
</div>
<div class="padding paddingLargeLeft paddingLargeRight uk-margin-xlarge">
<h3>2nd: Register your datasource</h3>
<p>Register your literature repository, data repository, journal or aggregator in OpenAIRE.</p>
<p>Once registered in OpenAIRE, the data source manager are able to use the Provide functionalities to validate their data source compatibility with the OpenAIRE Guidelines, to get notification to enrich their research results with additional or missing metadata, and to track the data source usage activity.</p>
</div>
</div>
</div>
<div class="uk-container uk-container-large uk-container-center uk-margin-large-top">
<div class="uk-text-center">
<p>Learn more: <a href="https://www.openaire.eu/validator-registration-guide" target="_blank">https://www.openaire.eu/validator-registration-guide</a></p>
</div>
</div>
</div>
</div>
</div>
<div class="uk-section-secondary uk-section uk-section-large uk-padding-remove-top uk-padding-remove-bottom uk-preserve-color">
<div class="uk-container uk-container-expand" style="position: relative; top: -260px">
<div class="uk-grid">
<div class="uk-width-1-2@l uk-width-1-2@m">
<div style="position: relative; top: 275px">
<div style="text-align: center">
<img src="../../../../assets/imgs/landing/_0001_Group-3.png" width="158">
</div>
</div>
<div style="position: relative; top: -4px; left: 550px;">
<img src="../../../../assets/imgs/landing/arrow3.svg">
</div>
<div class="enrichmentsSection uk-padding" style="margin-top: -23px">
<!--<div style="text-align: center">-->
<!--<img src="../../../../assets/imgs/landing/_0001_Group-3.png" width="158">-->
<!--</div>-->
<div class="uk-margin-large-top" style="text-align: center">
<h2 class="">Enrichments</h2>
<p>Content enrichment is a powerful tool that enables Content providers to enrich research artifacts with additional metadata, through the OpenAIRE Notification Broker Service.</p>
<p>Learn more: <a href="https://www.openaire.eu/content-enrichment-guide" target="_blank">https://www.openaire.eu/content-enrichment-guide</a></p>
</div>
</div>
<div style="position: relative; top: -50px; text-align: right;right: -40px;">
<img src="../../../../assets/imgs/landing/arrow4.svg">
</div>
</div>
<div class="uk-width-1-2@l uk-width-1-2@m uk-margin-xlarge">
<div style="position: relative; top: 275px">
<div style="text-align: center">
<img src="../../../../assets/imgs/landing/_0003_Group-1.png" width="258">
</div>
</div>
<div class="measureSection uk-padding">
<!--<div style="text-align: center">-->
<!--<img src="../../../../assets/imgs/landing/_0003_Group-1.png" width="258">-->
<!--</div>-->
<div class="uk-margin-large-top" style="text-align: center">
<h2 class="">Usage Statistics</h2>
<p>OpenAIREs Usage Statistic service uses the Matomo Open Source Analytics platform (matomo.org) to track usage activity. It collects and analyzes usage data from the network of OpenAIRE data providers and exploits usage metrics like downloads and metadata views.</p>
<p>Learn more: <a href="https://www.openaire.eu/guides-usage-statistics" target="_blank">https://www.openaire.eu/guides-usage-statistics</a></p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="uk-section uk-section-large uk-section-muted uk-background-norepeat uk-background-cover uk-background-top-center
uk-background-fixed uk-section uk-flex uk-flex-middle uk-padding-remove-top"
style="background: transparent linear-gradient(0deg, #E2EEFA 20%, #F7F7F7 70%) 0% 0% no-repeat padding-box; box-sizing: border-box;">
<div class="uk-container uk-container-large">
<div class="uk-grid uk-flex" style="align-items: center">
<div class="uk-width-1-3@l uk-width-1-3@m">
<img src="../../../../assets/imgs/landing/_0000_Group-4.png">
</div>
<div class="uk-width-2-3@l uk-width-2-3@m">
<div class="uk-margin-large-left">
<h2>Contact us to help you.</h2>
<p class="text-muted">Are you looking for more? Get in touch with our team and let us help you.</p>
<a class="uk-margin-large-top uk-text-uppercase uk-button uk-button-primary" href="https://www.openaire.eu/contact-us/" target="_blank">Get in touch</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,38 @@
import { Component, OnInit } from '@angular/core';
import { AuthenticationService } from '../../../services/authentication.service';
import { StatisticsService } from '../../../services/statistics.service';
import { Router } from '@angular/router';
@Component ({
selector: 'app-about',
templateUrl: './about.component.html',
styleUrls: ['../../../../assets/css/landingpage/theme.css','../../../../assets/css/landingpage/custom.css','../../../../assets/css/landingpage/custom-provide.css'],
})
export class AboutComponent implements OnInit {
constructor(private authService: AuthenticationService,
private statsService: StatisticsService,
private router: Router) { }
ngOnInit() {
let body = document.getElementsByTagName('body')[0];
body.classList.remove("dashboard");
body.classList.add("landing");
}
login() {
this.authService.loginWithState();
}
goToPage(pageUrl: string) {
if (this.authService.getIsUserLoggedIn()) {
this.router.navigate([pageUrl]);
} else {
this.authService.redirectUrl = pageUrl;
this.login();
}
}
}

View File

@ -0,0 +1,933 @@
<!--MOBILE & PAD PORTRAIT-->
<div class="uk-hidden@m">
<div class="provideLanding">
<div class="image-front-topbar uk-section-default"
uk-scrollspy="{&quot;target&quot;:&quot;[uk-scrollspy-class]&quot;,&quot;cls&quot;:&quot;uk-animation-fade&quot;,&quot;delay&quot;:false}" tm-header-transparent="light">
<!--<div style="background-image: url('../../../../assets/imgs/landing/Group 1149.svg'); background-color: rgb(255, 255, 255); box-sizing: border-box; min-height: calc(-101.35px + 100vh);"-->
<!--<div style="background-image: url('../../../../assets/imgs/landing/Group 1149.svg'); background-color: rgb(255, 255, 255); box-sizing: border-box; min-height: calc(-101.35px + 100vh);"-->
<div style="background: transparent linear-gradient(0deg, #F7F7F7 20%, #E2EEFA 30%) 0% 0% no-repeat padding-box; box-sizing: border-box; min-height: calc(-101.35px + 100vh);"
class="uk-background-norepeat uk-background-cover uk-background-top-center uk-background-fixed uk-section uk-padding-remove-bottom uk-flex uk-flex-middle" uk-height-viewport="offset-top: true;offset-bottom: 20">
<div class="uk-width-1-1">
<!--<div class="uk-margin-medium uk-grid uk-grid-stack" uk-grid="">-->
<!--<div class="uk-width-1-1@m">-->
<!--</div>-->
<!--</div>-->
<div class="uk-container uk-container-large uk-margin-large">
<!--<div class="uk-sticky-placeholder" style="height: 84px; margin: 0px;"></div>-->
<div class="search_box_bg uk-grid-large uk-flex-middle uk-grid uk-grid-stack" uk-grid="">
<div class="el-overlay uk-panel uk-width-1-1 uk-dark uk-text-center">
<h1 class="uk-margin">Your data is valuable. Get connected. Participate</h1>
<div class="uk-container uk-container-xsmall uk-container-center">
<div class="uk-margin-medium-top uk-margin-medium-left uk-margin-medium-right text-muted">
The Provide Dashboard is a one-stop-service where content providers interact
with OpenAIRE and become a building block of a global Open Research community. A gateway to the European Open Science Cloud.
</div>
</div>
<div class="uk-container uk-container-small uk-container-center">
<div class="uk-margin-left uk-margin-right uk-margin-top">
<div class="uk-grid uk-child-width-1-3">
<div class="uk-width-1-3">
<img src="../../../../assets/imgs/landing/paidaki_me_xartia.png">
</div>
<div class="uk-width-1-3" style="display: flex; align-items: center; justify-content: center">
<!--fixme remove custom padding??-->
<a style="padding: 0 17px" (click)="goToPage('/join')" class="el-link uk-button uk-button-primary">SIGN IN</a>
</div>
</div>
</div>
</div>
<!--<div class="el-content uk-margin"><h2 style="color:#1a1a1a!important">A one-stop-shop for sharing, finding and enriching your content</h2></div>-->
<!--<p><a (click)="goToPage('/dashboard')" class="el-link uk-button uk-button-primary">Sign In</a></p>-->
</div>
</div>
</div>
</div>
</div>
</div>
<div class="uk-section-muted uk-section uk-section-large uk-section-overlap uk-position-relative">
<h2 class="uk-text-center">PROVIDE Dashboard brings all your data together</h2>
<div class="uk-margin-medium-left uk-margin-medium-right uk-text-center text-muted">Get front-end access to many of OpenAIREs backend services</div>
<div class="uk-container uk-container-large uk-margin-medium-top">
<div class="slider-mobile-card">
<div class="uk-slider" tabindex="-1" uk-slider="velocity: 0;autoplay: true;autoplay-interval: 5000;pause-on-hover: false;center: true">
<div class="uk-position-relative">
<div class="uk-slider-container">
<ul class="uk-slider-items uk-child-width-1-1" style="transform: translateX(-1300px);">
<li class="ng-star-inserted uk-active" tabindex="-1" style="order: 1;">
<div class="uk-flex uk-padding uk-child-width-1-2@m uk-child-width-1-1@s uk-grid" uk-grid="">
<div class="uk-first-column">
<video class="uk-box-shadow-large uk-border-rounded" autoplay loop>
<source src="../../../../assets/mp4/validate.mp4" type="video/mp4">
</video>
<!--<img class="uk-box-shadow-large uk-border-rounded" src="../../../../assets/gifs/validate.gif">-->
</div>
<div class="uk-margin-top">
<div>
<div class="uk-text-bold uk-h4">Validate</div>
<div class="uk-margin-medium">
Interoperable metadata is key for effective content sharing.
<p class="uk-margin-top">
OpenAIRE guidelines are a global standard to expose and share your content. Use our validation service and see how you can apply them.
</p>
</div>
<div class="uk-inline">
<a class="uk-button uk-button-primary uk-text-uppercase" [routerLink]="['/about']">learn more</a>
</div>
</div>
</div>
</div>
</li>
<li tabindex="-1" style="order: 1;">
<div class="uk-flex uk-padding uk-child-width-1-2@m uk-child-width-1-1@s uk-grid" uk-grid="">
<div class="uk-first-column">
<video class="uk-box-shadow-large uk-border-rounded" autoplay loop>
<source src="../../../../assets/mp4/register.mp4" type="video/mp4">
</video>
<!--<img class="uk-box-shadow-large uk-border-rounded" src="../../../../assets/gifs/register.gif">-->
</div>
<div class="uk-margin-top">
<div>
<div class="uk-text-bold uk-h4">Register</div>
<div class="uk-margin-medium">
Reach a wider audience around the world.
<p class="uk-margin-top">
Register your literature or data repository, OA Journal, CRIS in OpenAIRE and be part of a global interlinked network.
</p>
</div>
<div class="uk-inline">
<a class="uk-button uk-button-primary uk-text-uppercase" [routerLink]="['/about']">learn more</a>
</div>
</div>
</div>
</div>
</li>
<li tabindex="-1" style="order: 1;">
<div class="uk-flex uk-padding uk-child-width-1-2@m uk-child-width-1-1@s uk-grid" uk-grid="">
<div class="uk-first-column">
<video class="uk-box-shadow-large uk-border-rounded" autoplay loop>
<source src="../../../../assets/mp4/enrich.mp4" type="video/mp4">
</video>
<!--<img class="uk-box-shadow-large uk-border-rounded" src="../../../../assets/gifs/enrichments.gif">-->
</div>
<div class="uk-margin-top">
<div>
<div class="uk-text-bold uk-h4">Enrich</div>
<div class="uk-margin-medium">
Improve your metadata. Get more connections.
<p class="uk-margin-top">
Our newly released OA Broker service offers a wealth of information on scholarly communication data. Find out what interests you and subscribe to enrich your records.
</p>
</div>
<div class="uk-inline">
<a class="uk-button uk-button-primary uk-text-uppercase" [routerLink]="['/about']">learn more</a>
</div>
</div>
</div>
</div>
</li>
<li tabindex="-1" style="order: 1;">
<div class="uk-flex uk-padding uk-child-width-1-2@m uk-child-width-1-1@s uk-grid" uk-grid="">
<div class="uk-first-column">
<video class="uk-box-shadow-large uk-border-rounded" autoplay loop>
<source src="../../../../assets/mp4/usage-stat.mp4" type="video/mp4">
</video>
<!--<img class="uk-box-shadow-large uk-border-rounded" src="../../../../assets/gifs/usageStats.gif">-->
</div>
<div class="uk-margin-top">
<div>
<div class="uk-text-bold uk-h4">Usage statistics</div>
<div class="uk-margin-medium">
Open research impact empowers Open Science.
<p class="uk-margin-top">
Share usage data via OpenAIRE's global Open Metrics Service. Get the benefit of an aggregated environment to broaden the mechanisms for impact assessment.
</p>
</div>
<div class="uk-inline">
<a class="uk-button uk-button-primary uk-text-uppercase" [routerLink]="['/about']">learn more</a>
</div>
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
<ul class="uk-position-relative uk-slider-nav uk-dotnav uk-flex-center uk-margin">
<li uk-slider-item="0" class="uk-active"><a href="#"></a></li>
<li uk-slider-item="1" class=""><a href="#"></a></li>
<li uk-slider-item="2" class=""><a href="#"></a></li>
<li uk-slider-item="3" class=""><a href="#"></a></li>
</ul>
</div>
</div>
</div>
</div>
<div class="uk-section uk-section-muted uk-section-large uk-preserve-color uk-background-norepeat uk-background-cover uk-background-top-center"
style="background-image: url('../../../../assets/imgs/landing/abstract2.svg'); !important; min-height: calc(80vh);" uk-height-viewport="offset-top: true; offset-bottom: 20;">
<div class="uk-container uk-container-expand">
<h1 class="uk-text-center">Do numbers make you happy?</h1>
<div class="uk-margin-medium-top">
<div class="" style="display: block; width: 60%; margin-left: auto; margin-right: auto">
<img src="../../../../assets/imgs/landing/avakas.png">
</div>
</div>
<div class="uk-grid">
<div class="uk-width-expand">
<div class="uk-grid uk-child-width-1-2 uk-text-center" style="display: flex;align-items: center;height: 70%;">
<div class="uk-margin-top">
<div class="bigNumber">{{ (statisticsNumbers && statisticsNumbers.literature) ? (statisticsNumbers.literature | number) : 'N/A' }}</div>
<div class="uk-text-uppercase">Literature repositories</div>
</div>
<div class="uk-margin-top">
<div class="bigNumber">{{ (statisticsNumbers && statisticsNumbers.journal) ? (statisticsNumbers.journal | number) : 'N/A' }}</div>
<div class="uk-text-uppercase">Data repositories</div>
</div>
<div class="uk-margin-top">
<div class="bigNumber">{{ (statisticsNumbers && statisticsNumbers.dataRepositories) ? (statisticsNumbers.dataRepositories | number) : 'N/A' }}</div>
<div class="uk-text-uppercase">OA journals</div>
</div>
<div class="uk-margin-top">
<div class="bigNumber">{{ (statisticsNumbers && statisticsNumbers.aggregators) ? (statisticsNumbers.aggregators | number) : 'N/A' }}</div>
<div class="uk-text-uppercase">Aggregators</div>
</div>
</div>
</div>
</div>
</div>
<!--<div class="uk-container uk-container-large uk-margin-top">-->
<!--<div class="uk-grid uk-child-width-1-5@l uk-child-width-1-5@m uk-child-width-1-2@s uk-margin-medium-left">-->
<!--<div class="uk-margin-top">-->
<!--<h3>{{ (statisticsNumbers && statisticsNumbers.publications) ? (statisticsNumbers.publications | number) : 'N/A' }}</h3>-->
<!--<div class="uk-text-uppercase text-small iconsWithText">-->
<!--<span><i class="fas fa-book fa-2x uk-margin-small-right" style="color: #3EC8FE"></i></span>-->
<!--<span>publications</span>-->
<!--</div>-->
<!--</div>-->
<!--<div class="uk-margin-top">-->
<!--<h3>{{ (statisticsNumbers && statisticsNumbers.datasets) ? (statisticsNumbers.datasets | number) : 'N/A' }}</h3>-->
<!--<div class="uk-text-uppercase text-small iconsWithText">-->
<!--<span><i class="fas fa-database fa-2x uk-margin-small-right" style="color: #3EC8FE"></i></span>-->
<!--<span>datasets</span>-->
<!--</div>-->
<!--</div>-->
<!--<div class="uk-margin-top">-->
<!--<h3>{{ (statisticsNumbers && statisticsNumbers.software) ? (statisticsNumbers.software | number) : 'N/A' }}</h3>-->
<!--<div class="uk-text-uppercase text-small iconsWithText">-->
<!--<span><i class="fas fa-cog fa-2x uk-margin-small-right" style="color: #3EC8FE"></i></span>-->
<!--<span>software</span>-->
<!--</div>-->
<!--</div>-->
<!--<div class="uk-margin-top">-->
<!--<h3>{{ (statisticsNumbers && statisticsNumbers.usagestats) ? statisticsNumbers.usagestats : 'N/A' }}</h3>-->
<!--<div class="uk-text-uppercase text-small iconsWithText">-->
<!--<span><i class="fas fa-globe-americas fa-2x uk-margin-small-right" style="color: #3EC8FE"></i></span>-->
<!--<span>metadata exchange events</span>-->
<!--</div>-->
<!--</div>-->
<!--<div class="uk-margin-top">-->
<!--<h3>{{ statisticsNumbers ? (statisticsNumbers.lastYearUsagestats.number | number) : 'N/A' }}</h3>-->
<!--<div class="uk-text-uppercase text-small iconsWithText">-->
<!--<span><i class="fas fa-globe-americas fa-2x uk-margin-small-right" style="color: #3EC8FE"></i></span>-->
<!--<span>usage statistics views & downloads ({{ statisticsNumbers ? statisticsNumbers.lastYearUsagestats.year : 'N/A' }})</span>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
</div>
<!--<div class="uk-section uk-section-muted uk-section-large text-small" style="background: transparent url('../../../../assets/imgs/landing/kathisto%20paidaki.png') 0% 0% no-repeat padding-box;">-->
<div class="uk-section uk-section-muted uk-padding-remove-top text-small">
<div style="position: relative; top: 25px; text-align: right;right: 33px;">
<img src="../../../../assets/imgs/landing/kathisto%20paidaki.png" width="58">
</div>
<div class="uk-container uk-container-xsmall uk-margin-left uk-margin-right openAIREGuidelinesBoxMobile">
<div>
<div class="uk-margin-medium-top">
<h5 class="uk-text-uppercase uk-text-center">
<span><strong>Follow OpenAIRE Guidelines</strong></span>
</h5>
</div>
<div style="">
<div class="uk-grid uk-child-width-1-1">
<div class="uk-margin-medium-bottom uk-margin-medium-top">
<div style="border-bottom: 1px solid #BFBFBF; padding-bottom: 20px" class="uk-margin-left uk-margin-right">
<div style="display: block; text-align: center">
<img width="56" src="../../../../assets/imgs/landing/Guidelines%20color.svg">
</div>
<div class="uk-margin-bottom uk-margin-top" style="font-weight: 600">OpenAIRE Guidelines</div>
<p>Follow the OpenAIRE <strong>Guidelines</strong> to expose your metadata in order to integrate with OpenAIRE infrastructure. <br>Learn more:
<a href="https://guidelines.openaire.eu/en/latest/" target="_blank">https://guidelines.openaire.eu/en/latest/</a></p>
<p>Follow the OpenAIRE <strong>Usage Statistics Guidelines</strong> to get ready to track the usage activity of your data source. <br>Learn more:
<a href="https://openaire.github.io/usage-statistics-guidelines/" target="_blank">https://openaire.github.io/usage-statistics-guidelines/</a></p>
</div>
</div>
<div class="uk-margin-medium-bottom">
<div style="border-bottom: 1px solid #BFBFBF; padding-bottom: 20px" class="uk-margin-left uk-margin-right">
<div style="display: block; text-align: center">
<img width="43" src="../../../../assets/imgs/landing/Data%20color.svg">
</div>
<div class="uk-margin-bottom uk-margin-top" style="font-weight: 600">Our Data Policies</div>
<p>
<strong>Data Acquisition</strong> - How we retrieve data, how often, what processes it goes through (aggregating cleaning, transforming, inferring, de-duplicating), what are the quality checks along all data processing stages.
</p>
<p>
<strong>Data usage</strong> - Who is able to retrieve our data, what are the licences, what about specific SLAs. <br>Learn more:
<a href="https://www.openaire.eu/content-aquisition-policy" target="_blank">https://www.openaire.eu/content-aquisition-policy</a>
</p>
</div>
</div>
</div>
</div>
<div class="uk-grid uk-child-width-1-1">
<div class="uk-margin-medium-bottom">
<div style="border-bottom: 1px solid #BFBFBF; padding-bottom: 20px" class="uk-margin-left uk-margin-right">
<div style="display: block; text-align: center">
<img width="55" src="../../../../assets/imgs/landing/Agreement%20color.svg">
</div>
<div class="uk-margin-bottom uk-margin-top" style="font-weight: 600">Terms of Agreement for Content Providers</div>
<p>Learn more: <a href="https://www.openaire.eu/terms-of-use-for-content-providers" target="_blank">https://www.openaire.eu/terms-of-use-for-content-providers</a></p>
</div>
</div>
<div class="uk-margin-medium-bottom">
<div class="uk-margin-left uk-margin-right">
<div style="display: block; text-align: center">
<img width="38" src="../../../../assets/imgs/landing/Support%20color.svg">
</div>
<div class="uk-margin-bottom uk-margin-top" style="font-weight: 600">Support</div>
<p>Read <strong>how to use OpenAIRE</strong> to best serve your needs. <br>Learn more: <a href="https://www.openaire.eu/guides" target="_blank">https://www.openaire.eu/guides</a></p>
<p>Ask a question. Contact us via our <strong>ticketing system.</strong> <br>Learn more: <a href="https://www.openaire.eu/support/helpdesk" target="_blank">https://www.openaire.eu/support/helpdesk</a></p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="uk-section uk-section-muted uk-background-norepeat uk-background-cover uk-background-top-center uk-background-fixed uk-section uk-flex uk-flex-middle"
style="background: transparent linear-gradient(0deg, #E2EEFA 20%, #F7F7F7 70%) 0% 0% no-repeat padding-box; box-sizing: border-box;">
<!--<div style="background: transparent linear-gradient(0deg, #E2EEFA 20%, #F7F7F7 30%) 0% 0% no-repeat padding-box; box-sizing: border-box;"-->
<!--class="uk-background-norepeat uk-background-cover uk-background-top-center uk-background-fixed uk-section uk-padding-remove-bottom uk-flex uk-flex-middle">-->
<!--</div>-->
<div class="uk-container uk-container-xsmall uk-container-center uk-margin-left uk-margin-right">
<div class="uk-grid uk-flex" style="display: block; text-align: center">
<div class="">
<h2>We're here to help you.</h2>
<p class="text-muted">Do you want more information? Our team is happy to assist you.</p>
<a class="uk-margin-large-top uk-text-uppercase uk-button uk-button-primary" href="https://www.openaire.eu/contact-us/" target="_blank">Get in touch</a>
</div>
<div class="uk-margin-top">
<img src="../../../../assets/imgs/landing/contact%20us%20provide.png" width="66">
</div>
</div>
</div>
</div>
<div class="uk-section uk-section-muted" uk-scrollspy="{&quot;target&quot;:&quot;[uk-scrollspy-class]&quot;,&quot;cls&quot;:&quot;uk-animation-fade&quot;,&quot;delay&quot;:false}">
<div class="uk-container uk-container-large">
<div class="uk-grid uk-margin-large-top uk-margin-large-bottom" uk-grid="">
<div class="uk-width-1-1 uk-width-1-2@s uk-dark uk-grid-item-match uk-first-column explore">
<div class="uk-margin uk-panel uk-scrollspy-inview uk-animation-fade" uk-scrollspy-class="" style="">
<h4 class="el-title uk-margin uk-h4">
Researcher?
</h4>
<div class="el-content uk-margin">
Explore all OA research results. Link all your research. Build your profile
</div>
<p>
<a href="https://{{ inBeta ? 'beta.' : '' }}explore.openaire.eu" class="el-link uk-button uk-button-default" target="_blank">
OpenAIRE.EXPLORE
</a>
</p>
</div>
</div>
<div class="uk-width-1-1 uk-width-1-2@s uk-dark uk-grid-item-match connect">
<div class="uk-margin uk-panel uk-scrollspy-inview uk-animation-fade" uk-scrollspy-class="" style="">
<h4 class="el-title uk-margin uk-h4">
Research community?
</h4>
<div class="el-content uk-margin">
Use a trusted partner to share, link, disseminate and monitor your research.
</div>
<p>
<a href="https://{{ inBeta ? 'beta.' : '' }}connect.openaire.eu" class="el-link uk-button uk-button-default" target="_blank">
OpenAIRE.CONNECT
</a>
</p>
</div>
</div>
<div class="uk-width-1-1 uk-width-1-2@s uk-dark uk-grid-item-match monitor">
<div class="uk-margin uk-panel uk-scrollspy-inview uk-animation-fade" uk-scrollspy-class="" style="">
<h4 class="el-title uk-margin uk-h4">
Research manager?
</h4>
<div class="el-content uk-margin">
Use our monitoring services and easily track all relevant research results.
</div>
<p>
<a href="https://monitor.openaire.eu" class="el-link uk-button uk-button-default" target="_blank">
OpenAIRE.MONITOR
</a>
</p>
</div>
</div>
<div class="uk-width-1-1 uk-width-1-2@s uk-dark uk-grid-item-match develop">
<div class="uk-margin uk-panel uk-scrollspy-inview uk-animation-fade" uk-scrollspy-class="" style="">
<h4 class="el-title uk-margin uk-h4">
Developer?
</h4>
<div class="el-content uk-margin">
Get access to OpenAIRE data and capitalize on on Europe's open linked research
</div>
<p>
<a href="https://develop.openaire.eu" class="el-link uk-button uk-button-default" target="_blank">
OpenAIRE.DEVELOP
</a>
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!--LAPTOP & PAD LANDSCAPE-->
<div class="uk-visible@m">
<div class="provideLanding">
<div class="image-front-topbar uk-section-default"
uk-scrollspy="{&quot;target&quot;:&quot;[uk-scrollspy-class]&quot;,&quot;cls&quot;:&quot;uk-animation-fade&quot;,&quot;delay&quot;:false}" tm-header-transparent="light">
<!--<div style="background-image: url('../../../../assets/imgs/landing/Group 1149.svg'); background-color: rgb(255, 255, 255); box-sizing: border-box; min-height: calc(-101.35px + 100vh);"-->
<!--<div style="background-image: url('../../../../assets/imgs/landing/Group 1149.svg'); background-color: rgb(255, 255, 255); box-sizing: border-box; min-height: calc(-101.35px + 100vh);"-->
<div style="background: transparent linear-gradient(0deg, #F7F7F7 20%, #E2EEFA 30%) 0% 0% no-repeat padding-box; box-sizing: border-box; min-height: calc(-101.35px + 100vh);"
class="uk-background-norepeat uk-background-cover uk-background-top-center uk-background-fixed uk-section uk-padding-remove-bottom uk-flex uk-flex-middle" uk-height-viewport="offset-top: true;offset-bottom: 20">
<div class="uk-width-1-1">
<div class="uk-margin-medium uk-grid uk-grid-stack" uk-grid="">
<div class="uk-width-1-1@m">
</div>
</div>
<div class="uk-container uk-container-large uk-margin-large">
<div class="uk-sticky-placeholder" style="height: 84px; margin: 0px;"></div>
<div class="search_box_bg uk-grid-large uk-flex-middle uk-grid uk-grid-stack" uk-grid="">
<div class="el-overlay uk-panel uk-width-1-1 uk-dark uk-text-center">
<h1 class="uk-margin">Your data is valuable. Get connected. Participate</h1>
<div class="uk-container uk-container-xsmall uk-container-center">
<div class="uk-margin-medium-top uk-margin-medium-left uk-margin-medium-right text-muted">
The Provide Dashboard is a one-stop-service where content providers interact
with OpenAIRE and become a building block of a global Open Research community. A gateway to the European Open Science Cloud.
</div>
</div>
<div class="uk-container uk-container-large uk-container-center">
<div class="uk-margin-large-left uk-margin-large-right uk-margin-top">
<div class="uk-grid uk-child-width-1-3@l uk-child-width-1-3@m uk-child-width-1-3@s">
<div class="">
<img src="../../../../assets/imgs/landing/paidaki_me_xartia.png">
</div>
<div style="display: flex; align-items: center; justify-content: center">
<a (click)="goToPage('/join')" class="el-link uk-button uk-button-primary">SIGN IN</a>
</div>
</div>
</div>
</div>
<!--<div class="el-content uk-margin"><h2 style="color:#1a1a1a!important">A one-stop-shop for sharing, finding and enriching your content</h2></div>-->
<!--<p><a (click)="goToPage('/dashboard')" class="el-link uk-button uk-button-primary">Sign In</a></p>-->
</div>
</div>
</div>
</div>
</div>
</div>
<div class="uk-section-muted uk-section uk-section-large uk-section-overlap uk-position-relative">
<h2 class="uk-text-center">PROVIDE Dashboard brings all your data together</h2>
<div class="uk-margin-medium-left uk-margin-medium-right uk-text-center text-muted">Get front-end access to many of OpenAIREs backend services</div>
<div class="uk-container uk-container-large uk-margin-medium-top">
<div class="uk-slider" tabindex="-1" uk-slider="velocity: 0;autoplay: true;autoplay-interval: 5000;pause-on-hover: false;center: true">
<div class="uk-position-relative">
<div class="uk-slider-container">
<ul class="uk-slider-items uk-child-width-1-1" style="transform: translateX(-1300px);">
<li class="ng-star-inserted uk-active" tabindex="-1" style="order: 1;">
<div class="uk-flex uk-padding uk-child-width-1-2@m uk-child-width-1-1@s uk-grid" uk-grid="">
<div class="uk-first-column">
<video class="uk-box-shadow-large uk-border-rounded" autoplay loop>
<source src="../../../../assets/mp4/validate.mp4" type="video/mp4">
</video>
<!--<img class="uk-box-shadow-large uk-border-rounded" src="../../../../assets/gifs/validate.gif">-->
</div>
<div class="uk-margin-top">
<div>
<div class="uk-text-bold uk-h4">Validate</div>
<div class="uk-margin-medium">
Interoperable metadata is key for effective content sharing.
<p class="uk-margin-top">
OpenAIRE guidelines are a global standard to expose and share your content. Use our validation service and see how you can apply them.
</p>
</div>
<div class="uk-inline">
<a class="uk-button uk-button-primary uk-text-uppercase" [routerLink]="['/about']">learn more</a>
</div>
</div>
</div>
</div>
</li>
<li tabindex="-1" style="order: 1;">
<div class="uk-flex uk-padding uk-child-width-1-2@m uk-child-width-1-1@s uk-grid" uk-grid="">
<div class="uk-first-column">
<video class="uk-box-shadow-large uk-border-rounded" autoplay loop>
<source src="../../../../assets/mp4/register.mp4" type="video/mp4">
</video>
<!--<img class="uk-box-shadow-large uk-border-rounded" src="../../../../assets/gifs/register.gif">-->
</div>
<div class="uk-margin-top">
<div>
<div class="uk-text-bold uk-h4">Register</div>
<div class="uk-margin-medium">
Reach a wider audience around the world.
<p class="uk-margin-top">
Register your literature or data repository, OA Journal, CRIS in OpenAIRE and be part of a global interlinked network.
</p>
</div>
<div class="uk-inline">
<a class="uk-button uk-button-primary uk-text-uppercase" [routerLink]="['/about']">learn more</a>
</div>
</div>
</div>
</div>
</li>
<li tabindex="-1" style="order: 1;">
<div class="uk-flex uk-padding uk-child-width-1-2@m uk-child-width-1-1@s uk-grid" uk-grid="">
<div class="uk-first-column">
<video class="uk-box-shadow-large uk-border-rounded" autoplay loop>
<source src="../../../../assets/mp4/enrich.mp4" type="video/mp4">
</video>
<!--<img class="uk-box-shadow-large uk-border-rounded" src="../../../../assets/gifs/enrichments.gif">-->
</div>
<div class="uk-margin-top">
<div>
<div class="uk-text-bold uk-h4">Enrich</div>
<div class="uk-margin-medium">
Improve your metadata. Get more connections.
<p class="uk-margin-top">
Our newly released OA Broker service offers a wealth of information on scholarly communication data. Find out what interests you and subscribe to enrich your records.
</p>
</div>
<div class="uk-inline">
<a class="uk-button uk-button-primary uk-text-uppercase" [routerLink]="['/about']">learn more</a>
</div>
</div>
</div>
</div>
</li>
<li tabindex="-1" style="order: 1;">
<div class="uk-flex uk-padding uk-child-width-1-2@m uk-child-width-1-1@s uk-grid" uk-grid="">
<div class="uk-first-column">
<video class="uk-box-shadow-large uk-border-rounded" autoplay loop>
<source src="../../../../assets/mp4/usage-stat.mp4" type="video/mp4">
</video>
<!--<img class="uk-box-shadow-large uk-border-rounded" src="../../../../assets/gifs/usageStats.gif">-->
</div>
<div class="uk-margin-top">
<div>
<div class="uk-text-bold uk-h4">Usage statistics</div>
<div class="uk-margin-medium">
Open research impact empowers Open Science.
<p class="uk-margin-top">
Share usage data via OpenAIRE's global Open Metrics Service. Get the benefit of an aggregated environment to broaden the mechanisms for impact assessment.
</p>
</div>
<div class="uk-inline">
<a class="uk-button uk-button-primary uk-text-uppercase" [routerLink]="['/about']">learn more</a>
</div>
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
<ul class="uk-position-relative uk-slider-nav uk-dotnav uk-flex-center uk-margin">
<li uk-slider-item="0" class="uk-active"><a href="#"></a></li>
<li uk-slider-item="1" class=""><a href="#"></a></li>
<li uk-slider-item="2" class=""><a href="#"></a></li>
<li uk-slider-item="3" class=""><a href="#"></a></li>
</ul>
</div>
</div>
</div>
<div class="uk-section uk-section-muted uk-section-large uk-preserve-color uk-background-norepeat uk-background-cover uk-background-top-center"
style="background-image: url('../../../../assets/imgs/landing/abstract2.svg'); !important; min-height: calc(80vh);" uk-height-viewport="offset-top: true; offset-bottom: 20;">
<div class="uk-container uk-container-expand">
<div class="uk-grid uk-child-width-1-3@l uk-child-width-1-3@m">
<div>
<img src="../../../../assets/imgs/landing/avakas.png">
</div>
<div class="uk-width-expand">
<h1 class="uk-text-center">Do numbers make you happy?</h1>
<div class="uk-grid uk-child-width-1-4@l uk-child-width-1-4@m uk-child-width-1-1@s uk-margin-medium-left uk-margin-medium-right uk-text-center" style="display: flex;align-items: center;height: 70%;">
<div class="uk-margin-top">
<div class="bigNumber">{{ (statisticsNumbers && statisticsNumbers.literature) ? (statisticsNumbers.literature | number) : 'N/A' }}</div>
<div class="uk-text-uppercase">Literature repositories</div>
</div>
<div class="uk-margin-top">
<div class="bigNumber">{{ (statisticsNumbers && statisticsNumbers.dataRepositories) ? (statisticsNumbers.dataRepositories | number) : 'N/A' }}</div>
<div class="uk-text-uppercase">Data repositories</div>
</div>
<div class="uk-margin-top">
<div class="bigNumber">{{ (statisticsNumbers && statisticsNumbers.journal) ? (statisticsNumbers.journal | number) : 'N/A' }}</div>
<div class="uk-text-uppercase">OA journals</div>
</div>
<div class="uk-margin-top">
<div class="bigNumber">{{ (statisticsNumbers && statisticsNumbers.aggregators) ? (statisticsNumbers.aggregators | number) : 'N/A' }}</div>
<div class="uk-text-uppercase">Aggregators</div>
</div>
</div>
</div>
</div>
</div>
<div class="uk-container uk-container-large uk-margin-top">
<div class="uk-grid uk-child-width-1-5@l uk-child-width-1-5@m uk-child-width-1-2@s uk-margin-medium-left">
<div class="uk-margin-top">
<h3>{{ (statisticsNumbers && statisticsNumbers.publications) ? (statisticsNumbers.publications | number) : 'N/A' }}</h3>
<div class="uk-text-uppercase text-small iconsWithText">
<span><i class="fas fa-book fa-2x uk-margin-small-right" style="color: #3EC8FE"></i></span>
<span>publications</span>
</div>
</div>
<div class="uk-margin-top">
<h3>{{ (statisticsNumbers && statisticsNumbers.datasets) ? (statisticsNumbers.datasets | number) : 'N/A' }}</h3>
<div class="uk-text-uppercase text-small iconsWithText">
<span><i class="fas fa-database fa-2x uk-margin-small-right" style="color: #3EC8FE"></i></span>
<span>datasets</span>
</div>
</div>
<div class="uk-margin-top">
<h3>{{ (statisticsNumbers && statisticsNumbers.software) ? (statisticsNumbers.software | number) : 'N/A' }}</h3>
<div class="uk-text-uppercase text-small iconsWithText">
<span><i class="fas fa-cog fa-2x uk-margin-small-right" style="color: #3EC8FE"></i></span>
<span>software</span>
</div>
</div>
<div class="uk-margin-top">
<h3>{{ (statisticsNumbers && statisticsNumbers.usagestats) ? (statisticsNumbers.usagestats | number) : 'N/A' }}</h3>
<div class="uk-text-uppercase text-small iconsWithText">
<span><i class="fas fa-globe-americas fa-2x uk-margin-small-right" style="color: #3EC8FE"></i></span>
<span>metadata exchange events</span>
</div>
</div>
<div class="uk-margin-top">
<h3>{{ statisticsNumbers ? (statisticsNumbers.lastYearUsagestats.number | number) : 'N/A' }}</h3>
<div class="uk-text-uppercase text-small iconsWithText">
<span><i class="fas fa-globe-americas fa-2x uk-margin-small-right" style="color: #3EC8FE"></i></span>
<span>usage statistics views & downloads ({{ statisticsNumbers ? statisticsNumbers.lastYearUsagestats.year : 'N/A' }})</span>
</div>
</div>
</div>
</div>
</div>
<!--<div class="uk-section uk-section-muted uk-section-large text-small" style="background: transparent url('../../../../assets/imgs/landing/kathisto%20paidaki.png') 0% 0% no-repeat padding-box;">-->
<div class="uk-section uk-section-muted uk-padding-remove-top text-small">
<!--LAPTOP ONLY-->
<div class="uk-visible@l" style="position: relative; top: 86px; text-align: right;right: 195px;">
<img src="../../../../assets/imgs/landing/kathisto%20paidaki.png" width="130">
</div>
<!--PAD ONLY-->
<div class="uk-hidden@l" style="position: relative; top: 86px; text-align: right;right: 130px;">
<img src="../../../../assets/imgs/landing/kathisto%20paidaki.png" width="130">
</div>
<!--LAPTOP ONLY-->
<div class="uk-container uk-visible@l uk-container-large openAIREGuidelinesBox">
<div>
<div class="">
<h5 class="uk-text-uppercase uk-text-center uk-margin-remove">
<img class="" src="../../../../assets/imgs/landing/Arrow%20left.svg" style="margin-top: 35px; margin-right: 25px">
<span>Follow OpenAIRE Guidelines</span>
<img class="" src="../../../../assets/imgs/landing/Arrow%20right.svg" style="margin-top: 35px; margin-left: 25px">
</h5>
</div>
<div style="border-bottom: 1px solid #BFBFBF;border-top: 1px solid #BFBFBF;margin-top: -15px;">
<div class="uk-grid uk-child-width-1-2@l uk-child-width-1-2@m uk-grid-divider">
<div class="uk-first-column">
<div class="uk-margin-medium-left uk-margin-medium-top uk-margin-medium-bottom">
<img width="56" src="../../../../assets/imgs/landing/Guidelines%20color.svg">
<div class="uk-margin-bottom uk-margin-top" style="font-weight: 600">OpenAIRE Guidelines</div>
<p>Follow the OpenAIRE <strong>Guidelines</strong> to expose your metadata in order to integrate with OpenAIRE infrastructure. <br>Learn more:
<a href="https://guidelines.openaire.eu/en/latest/" target="_blank">https://guidelines.openaire.eu/en/latest/</a></p>
<p>Follow the OpenAIRE <strong>Usage Statistics Guidelines</strong> to get ready to track the usage activity of your data source. <br>Learn more:
<a href="https://openaire.github.io/usage-statistics-guidelines/" target="_blank">https://openaire.github.io/usage-statistics-guidelines/</a></p>
</div>
</div>
<div class="">
<div class="uk-margin-medium-right uk-margin-medium-top uk-margin-medium-bottom">
<img width="43" src="../../../../assets/imgs/landing/Data%20color.svg">
<div class="uk-margin-bottom uk-margin-top" style="font-weight: 600">Our Data Policies</div>
<p>
<strong>Data Acquisition</strong> - How we retrieve data, how often, what processes it goes through (aggregating cleaning, transforming, inferring, de-duplicating), what are the quality checks along all data processing stages.
</p>
<p>
<strong>Data usage</strong> - Who is able to retrieve our data, what are the licences, what about specific SLAs. <br>Learn more:
<a href="https://www.openaire.eu/content-aquisition-policy" target="_blank">https://www.openaire.eu/content-aquisition-policy</a>
</p>
</div>
</div>
</div>
</div>
<div class="uk-grid uk-child-width-1-2@l uk-child-width-1-2@m uk-grid-divider">
<div class="uk-first-column">
<div class="uk-margin-medium-left uk-margin-medium-top uk-margin-medium-bottom">
<img width="55" src="../../../../assets/imgs/landing/Agreement%20color.svg">
<div class="uk-margin-bottom uk-margin-top" style="font-weight: 600">Terms of Agreement for Content Providers</div>
<p>Learn more: <a href="https://www.openaire.eu/terms-of-use-for-content-providers" target="_blank">https://www.openaire.eu/terms-of-use-for-content-providers</a></p>
</div>
</div>
<div class="">
<div class="uk-margin-medium-right uk-margin-medium-top uk-margin-medium-bottom">
<img width="38" src="../../../../assets/imgs/landing/Support%20color.svg">
<div class="uk-margin-bottom uk-margin-top" style="font-weight: 600">Support</div>
<p>Read <strong>how to use OpenAIRE</strong> to best serve your needs. <br>Learn more: <a href="https://www.openaire.eu/guides" target="_blank">https://www.openaire.eu/guides</a></p>
<p>Ask a question. Contact us via our <strong>ticketing system.</strong> <br>Learn more: <a href="https://www.openaire.eu/support/helpdesk" target="_blank">https://www.openaire.eu/support/helpdesk</a></p>
</div>
</div>
</div>
</div>
</div>
<!--PAD ONLY-->
<div class="uk-container uk-hidden@l uk-container-small openAIREGuidelinesBox">
<div>
<div class="">
<h5 class="uk-text-uppercase uk-text-center uk-margin-remove">
<img class="" src="../../../../assets/imgs/landing/Arrow%20left.svg" style="margin-top: 35px; margin-right: 25px">
<span>Follow OpenAIRE Guidelines</span>
<img class="" src="../../../../assets/imgs/landing/Arrow%20right.svg" style="margin-top: 35px; margin-left: 25px">
</h5>
</div>
<div style="border-bottom: 1px solid #BFBFBF;border-top: 1px solid #BFBFBF;margin-top: -15px;">
<div class="uk-grid uk-child-width-1-2@l uk-child-width-1-2@m uk-grid-divider">
<div class="uk-first-column">
<div class="uk-margin-medium-left uk-margin-medium-top uk-margin-medium-bottom">
<img width="56" src="../../../../assets/imgs/landing/Guidelines%20color.svg">
<div class="uk-margin-bottom uk-margin-top" style="font-weight: 600">OpenAIRE Guidelines</div>
<p>Follow the OpenAIRE <strong>Guidelines</strong> to expose your metadata in order to integrate with OpenAIRE infrastructure. <br>Learn more:
<a href="https://guidelines.openaire.eu/en/latest/" target="_blank">https://guidelines.openaire.eu/en/latest/</a></p>
<p>Follow the OpenAIRE <strong>Usage Statistics Guidelines</strong> to get ready to track the usage activity of your data source. <br>Learn more:
<a href="https://openaire.github.io/usage-statistics-guidelines/" target="_blank">https://openaire.github.io/usage-statistics-guidelines/</a></p>
</div>
</div>
<div class="">
<div class="uk-margin-medium-right uk-margin-medium-top uk-margin-medium-bottom">
<img width="43" src="../../../../assets/imgs/landing/Data%20color.svg">
<div class="uk-margin-bottom uk-margin-top" style="font-weight: 600">Our Data Policies</div>
<p>
<strong>Data Acquisition</strong> - How we retrieve data, how often, what processes it goes through (aggregating cleaning, transforming, inferring, de-duplicating), what are the quality checks along all data processing stages.
</p>
<p>
<strong>Data usage</strong> - Who is able to retrieve our data, what are the licences, what about specific SLAs. <br>Learn more:
<a href="https://www.openaire.eu/content-aquisition-policy" target="_blank">https://www.openaire.eu/content-aquisition-policy</a>
</p>
</div>
</div>
</div>
</div>
<div class="uk-grid uk-child-width-1-2@l uk-child-width-1-2@m uk-grid-divider">
<div class="uk-first-column">
<div class="uk-margin-medium-left uk-margin-medium-top uk-margin-medium-bottom">
<img width="55" src="../../../../assets/imgs/landing/Agreement%20color.svg">
<div class="uk-margin-bottom uk-margin-top" style="font-weight: 600">Terms of Agreement for Content Providers</div>
<p>Learn more: <a href="https://www.openaire.eu/terms-of-use-for-content-providers" target="_blank">https://www.openaire.eu/terms-of-use-for-content-providers</a></p>
</div>
</div>
<div class="">
<div class="uk-margin-medium-right uk-margin-medium-top uk-margin-medium-bottom">
<img width="38" src="../../../../assets/imgs/landing/Support%20color.svg">
<div class="uk-margin-bottom uk-margin-top" style="font-weight: 600">Support</div>
<p>Read <strong>how to use OpenAIRE</strong> to best serve your needs. <br>Learn more: <a href="https://www.openaire.eu/guides" target="_blank">https://www.openaire.eu/guides</a></p>
<p>Ask a question. Contact us via our <strong>ticketing system.</strong> <br>Learn more: <a href="https://www.openaire.eu/support/helpdesk" target="_blank">https://www.openaire.eu/support/helpdesk</a></p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="uk-section uk-section-muted uk-background-norepeat uk-background-cover uk-background-top-center uk-background-fixed uk-section uk-flex uk-flex-middle"
style="background: transparent linear-gradient(0deg, #E2EEFA 20%, #F7F7F7 70%) 0% 0% no-repeat padding-box; box-sizing: border-box;">
<!--<div style="background: transparent linear-gradient(0deg, #E2EEFA 20%, #F7F7F7 30%) 0% 0% no-repeat padding-box; box-sizing: border-box;"-->
<!--class="uk-background-norepeat uk-background-cover uk-background-top-center uk-background-fixed uk-section uk-padding-remove-bottom uk-flex uk-flex-middle">-->
<!--</div>-->
<div class="uk-container uk-container-xlarge">
<div class="uk-grid uk-flex" style="align-items: center">
<div class="uk-width-3-4@l uk-width-3-4@m">
<h2>We're here to help you.</h2>
<p class="text-muted">Do you want more information? Our team is happy to assist you.</p>
<a class="uk-margin-large-top uk-text-uppercase uk-button uk-button-primary" href="https://www.openaire.eu/contact-us/" target="_blank">Get in touch</a>
</div>
<div class="uk-width-1-4@l uk-width-1-4@m">
<img src="../../../../assets/imgs/landing/contact%20us%20provide.png">
</div>
</div>
</div>
</div>
<div class="uk-section uk-section-muted" uk-scrollspy="{&quot;target&quot;:&quot;[uk-scrollspy-class]&quot;,&quot;cls&quot;:&quot;uk-animation-fade&quot;,&quot;delay&quot;:false}">
<div class="uk-container uk-container-large">
<div class="uk-grid uk-margin-large-top uk-margin-large-bottom" uk-grid="">
<div class="uk-width-expand@m uk-width-1-2@s uk-dark uk-grid-item-match uk-first-column explore">
<div class="uk-margin uk-panel uk-scrollspy-inview uk-animation-fade" uk-scrollspy-class="" style="">
<h4 class="el-title uk-margin uk-h4">
Researcher?
</h4>
<div class="el-content uk-margin">
Explore all OA research results. Link all your research. Build your profile
</div>
<p>
<a href="https://{{ inBeta ? 'beta.' : '' }}explore.openaire.eu" class="el-link uk-button uk-button-default" target="_blank">
OpenAIRE.EXPLORE
</a>
</p>
</div>
</div>
<div class="uk-width-expand@m uk-width-1-2@s uk-dark uk-grid-item-match connect">
<div class="uk-margin uk-panel uk-scrollspy-inview uk-animation-fade" uk-scrollspy-class="" style="">
<h4 class="el-title uk-margin uk-h4">
Research community?
</h4>
<div class="el-content uk-margin">
Use a trusted partner to share, link, disseminate and monitor your research.
</div>
<p>
<a href="https://{{ inBeta ? 'beta.' : '' }}connect.openaire.eu" class="el-link uk-button uk-button-default" target="_blank">
OpenAIRE.CONNECT
</a>
</p>
</div>
</div>
<div class="uk-width-expand@m uk-width-1-2@s uk-dark uk-grid-item-match monitor">
<div class="uk-margin uk-panel uk-scrollspy-inview uk-animation-fade" uk-scrollspy-class="" style="">
<h4 class="el-title uk-margin uk-h4">
Research manager?
</h4>
<div class="el-content uk-margin">
Use our monitoring services and easily track all relevant research results.
</div>
<p>
<a href="https://monitor.openaire.eu" class="el-link uk-button uk-button-default" target="_blank">
OpenAIRE.MONITOR
</a>
</p>
</div>
</div>
<div class="uk-width-expand@m uk-width-1-2@s uk-dark uk-grid-item-match develop">
<div class="uk-margin uk-panel uk-scrollspy-inview uk-animation-fade" uk-scrollspy-class="" style="">
<h4 class="el-title uk-margin uk-h4">
Developer?
</h4>
<div class="el-content uk-margin">
Get access to OpenAIRE data and capitalize on on Europe's open linked research
</div>
<p>
<a href="https://develop.openaire.eu" class="el-link uk-button uk-button-default" target="_blank">
OpenAIRE.DEVELOP
</a>
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,61 @@
import { Component, OnInit } from '@angular/core';
import { UsageStatsSummary } from '../../../domain/typeScriptClasses';
import { AuthenticationService } from '../../../services/authentication.service';
import { StatisticsService } from '../../../services/statistics.service';
import { Router } from '@angular/router';
@Component ({
selector: 'app-landing',
templateUrl: './home.component.html',
styleUrls: ['../../../../assets/css/landingpage/theme.css','../../../../assets/css/landingpage/custom.css','../../../../assets/css/landingpage/custom-provide.css'],
})
export class HomeComponent implements OnInit {
statisticsNumbers: UsageStatsSummary;
inBeta: boolean;
constructor(private authService: AuthenticationService,
private statsService: StatisticsService,
private router: Router) { }
ngOnInit() {
this.getStatisticsNumbers();
const baseUrl = window.location.origin;
this.inBeta = ( baseUrl.includes('beta') || baseUrl.includes('athenarc') );
let body = document.getElementsByTagName('body')[0];
body.classList.remove("dashboard");
body.classList.add("landing");
}
login() {
this.authService.loginWithState();
}
getStatisticsNumbers() {
this.statsService.getStatisticsNumbers().subscribe(
res => {
this.statisticsNumbers = res;
// this.statisticsNumbers.lastYearUsagestats = JSON.parse(res['lastYearUsagestats'].toString());
},
error => console.log(error),
() => {
console.log('statisticsNumbers is', JSON.stringify(this.statisticsNumbers));
}
);
}
goToPage(pageUrl: string) {
if (this.authService.getIsUserLoggedIn()) {
this.router.navigate([pageUrl]);
} else {
this.authService.redirectUrl = pageUrl;
this.login();
}
}
}

View File

@ -0,0 +1,10 @@
<!--<div class="uk-section-default uk-section uk-section-small uk-padding-remove-bottom" style="min-height: 325px">-->
<!--&lt;!&ndash; MARGIN-TOP &ndash;&gt;-->
<!--<div class="uk-sticky-placeholder" style="height: 84px; margin: 0px;" aria-hidden="true"></div>-->
<!--<div class="uk-container uk-container-large" style="min-height: 500px;">-->
<!--<router-outlet></router-outlet>-->
<!--</div>-->
<!--</div>-->
<router-outlet></router-outlet>

View File

@ -0,0 +1,88 @@
<div id="page_content_inner">
<!--<h2 class="heading_b uk-margin-bottom">Aggregation history for {{ repoName }}</h2>-->
<!-- TOP HELP CONTENT -->
<help-content #topHelperContent [position]="'top'"
[ngClass]="topHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
<div class="uk-grid">
<!-- LEFT HELP CONTENT -->
<aside-help-content #leftHelperContent [position]="'left'"
[ngClass]="leftHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
<!-- MIDDLE -->
<div class=" uk-width-expand@m">
<div *ngIf="errorMessage" class="uk-alert uk-alert-danger">{{ errorMessage }}</div>
<div *ngIf="loadingMessage" class="loading-big">
<div class="loader-big" style="text-align: center; padding-top: 170px; color: rgb(47, 64, 80); font-weight: bold;">
{{ loadingMessage }}
</div>
<div class="transparentFilm"></div>
</div>
<div *ngIf="noAggregations">{{ noAggregations }}</div>
<div *ngIf="aggregationsMap && years && (years.length > 0) && !noAggregations">
<div *ngFor="let year of years" class="uk-width-1-1@m uk-margin-medium-bottom">
<h2 class="heading_b uk-margin-bottom">
<span class="sub-heading">{{ year }}</span>
</h2>
<div class="md-card uk-margin-medium-bottom">
<div class="md-card-content">
<div class="uk-overflow-container">
<table class="uk-table uk-table-nowrap table_check">
<thead>
<tr>
<!--<th class="uk-width-1-10 uk-text-center small_col"><div class="icheckbox_md"><input type="checkbox" data-md-icheck="" class="check_all" style="position: absolute; top: -20%; left: -20%; display: block; width: 140%; height: 140%; margin: 0px; padding: 0px; background: rgb(255, 255, 255) none repeat scroll 0% 0%; border: 0px none; opacity: 0;"><ins class="iCheck-helper" style="position: absolute; top: -20%; left: -20%; display: block; width: 140%; height: 140%; margin: 0px; padding: 0px; background: rgb(255, 255, 255) none repeat scroll 0% 0%; border: 0px none; opacity: 0;"></ins></div></th>-->
<th class="uk-width-2-10">Date</th>
<th class="uk-width-2-10">Aggregation stage</th>
<th class="uk-width-2-10">Collection mode</th>
<th class="uk-width-2-10 uk-text-center">Number of records</th>
<th class="uk-width-2-10 uk-text-center">Indexed version?</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let aggr of aggregationsMap[year]">
<!--<td class="uk-text-center uk-table-middle small_col"><div class="icheckbox_md"><input type="checkbox" data-md-icheck="" class="check_row" style="position: absolute; top: -20%; left: -20%; display: block; width: 140%; height: 140%; margin: 0px; padding: 0px; background: rgb(255, 255, 255) none repeat scroll 0% 0%; border: 0px none; opacity: 0;"><ins class="iCheck-helper" style="position: absolute; top: -20%; left: -20%; display: block; width: 140%; height: 140%; margin: 0px; padding: 0px; background: rgb(255, 255, 255) none repeat scroll 0% 0%; border: 0px none; opacity: 0;"></ins></div></td>-->
<!--<td class="uk-text-center"><img class="md-user-image dense-image dense-ready" src="assets/img/avatars/avatar_01_tn@2x.png" alt="" data-dense-cap="2"></td>-->
<td><span *ngIf="aggr.date">{{ aggr.date | date : "yyyy-MM-dd" }}</span></td>
<td class=""><span *ngIf="aggr.aggregationStage">{{ aggr.aggregationStage }}</span></td>
<td class=""><span *ngIf="aggr.collectionMode">{{ aggr.collectionMode }}</span></td>
<td class="uk-text-center"><span *ngIf="aggr.numberOfRecords">{{ aggr.numberOfRecords }}</span></td>
<td class="uk-text-center"><span *ngIf="aggr.indexedVersion !== null && (aggr.indexedVersion === true)" class="uk-badge">Indexed version</span></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div *ngIf="repo" class="md-fab-wrapper">
<a class="md-fab md-fab-success md-fab-wave-light waves-effect waves-button waves-light" [routerLink]="['/repository/' + repo.id + '/aggregationHistory']">
<i class="material-icons">arrow_back</i>
</a>
</div>
</div>
<!-- RIGHT HELP CONTENT -->
<aside-help-content #rightHelperContent [position]="'right'"
[ngClass]="rightHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
</div>
<!-- BOTTOM HELP CONTENT -->
<help-content #bottomHelperContent [position]="'bottom'"
[ngClass]="bottomHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
</div>

View File

@ -0,0 +1,74 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { AggregationDetails, Repository } from '../../../domain/typeScriptClasses';
import { RepositoryService } from '../../../services/repository.service';
import { loadingAggregationHistory, loadingAggregationHistoryError, noAggregationHistory } from '../../../domain/shared-messages';
import { SharedService } from "../../../services/shared.service";
@Component ({
selector: 'app-compatibility-fullhistory-monitor-repo',
templateUrl: 'compatibility-monitor-fullHistory-repo.component.html'
})
export class CompatibilityMonitorFullHistoryRepoComponent implements OnInit {
loadingMessage: string;
errorMessage: string;
noAggregations: string;
repoName = '';
repo: Repository;
aggregationsMap: Map<string, AggregationDetails[]> = new Map<string, AggregationDetails[]>();
years: string[] = [];
constructor(private route: ActivatedRoute,
private router: Router,
private repoService: RepositoryService,
private sharedService: SharedService) {}
ngOnInit() {
if(this.sharedService.getRepository()) {
this.repo = this.sharedService.getRepository();
this.repoName = this.repo.officialName;
this.getAllAggregationHistory();
}
this.sharedService.repository$.subscribe(
r => {
this.repo = r;
if (this.repo) {
this.repoName = this.repo.officialName;
this.getAllAggregationHistory();
}
}
);
let body = document.getElementsByTagName('body')[0];
body.classList.remove("top_bar_active"); //remove the class
body.classList.remove("page_heading_active");
body.classList.remove("landing");
body.classList.add("dashboard");
}
getAllAggregationHistory() {
this.loadingMessage = loadingAggregationHistory;
this.repoService.getRepositoryAggregationsByYear(this.repo.id).subscribe(
aggr => this.aggregationsMap = aggr,
error => {
this.loadingMessage = '';
this.errorMessage = loadingAggregationHistoryError;
},
() => {
this.loadingMessage = '';
this.years = Object.keys(this.aggregationsMap);
if ( this.years.length === 0 ) {
this.noAggregations = noAggregationHistory;
} else {
this.years.sort( (a, b) => ( a > b ? -1 : 1 ) );
}
}
);
}
}

View File

@ -0,0 +1,118 @@
<div id="page_content_inner">
<!--<h2 *ngIf="repoName" class="heading_b uk-margin-bottom">Recent aggregation history for {{ repoName }}</h2>-->
<!-- TOP HELP CONTENT -->
<help-content #topHelperContent [position]="'top'"
[ngClass]="topHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
<div class="uk-grid">
<!-- LEFT HELP CONTENT -->
<aside-help-content #leftHelperContent [position]="'left'"
[ngClass]="leftHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
<!-- MIDDLE -->
<div class=" uk-width-expand@m">
<div *ngIf="errorMessage" class="uk-alert uk-alert-danger">{{ errorMessage }}</div>
<div *ngIf="loadingMessage" class="loading-big">
<div class="loader-big" style="text-align: center; padding-top: 170px; color: rgb(47, 64, 80); font-weight: bold;">
{{ loadingMessage }}
</div>
<div class="transparentFilm"></div>
</div>
<div *ngIf="noAggregations">{{ noAggregations }}</div>
<div *ngIf="latestAggregations && (latestAggregations.length > 0) && !noAggregations">
<div class="uk-width-large-2-3 uk-container-center">
<div class="timeline timeline-center">
<div *ngFor="let aggr of latestAggregations" class="timeline_item">
<div class="timeline_icon timeline_icon_white uk-scrollspy-init-inview uk-scrollspy-inview uk-animation-scale-up"
data-uk-scrollspy="{cls:'uk-animation-scale-up uk-invisible', delay:300, repeat: true}">
<ng-container *ngIf="aggr.indexedVersion">
<img src="https://www.openaire.eu/images/Logos/Favicon-90x90.png" style="width: 80%;margin-top: 9%;">
</ng-container>
<!--<i class="material-icons"></i>-->
</div>
<div *ngIf="aggr.date" class="timeline_date uk-scrollspy-init-inview uk-scrollspy-inview uk-animation-slide-right"
data-uk-scrollspy="{cls:'uk-animation-slide-right uk-invisible', delay:300}">
{{ aggr.date | date : "yyyy-MM-dd" }}
</div>
<div class="timeline_content uk-scrollspy-init-inview uk-scrollspy-inview uk-animation-slide-left"
data-uk-scrollspy="{cls:'uk-animation-slide-left uk-invisible', delay:300}">
<span *ngIf="aggr.indexedVersion" class="ng-star-inserted uk-inline uk-float-right uk-badge"
style="padding-top: 3px;padding-left: 10px;padding-right: 10px;margin-top: 5px;">Indexed version</span>
<div class="timeline_content_addon">
<ul class="md-list md-list-addon">
<li *ngIf="aggr.aggregationStage">
<!--<div class="md-list-addon-element">-->
<!--<span *ngIf="aggr.aggregationStage=='TRANSFORM'" class="md-user-image md-list-addon-avatar dense-image dense-ready">-->
<!--<i class="material-icons">transform</i>-->
<!--</span>-->
<!--<span *ngIf="aggr.aggregationStage=='COLLECT'" class="md-user-image md-list-addon-avatar dense-image dense-ready">-->
<!--<i class="material-icons">collections</i>-->
<!--</span>-->
<!--&lt;!&ndash;<img class="md-user-image md-list-addon-avatar dense-image dense-ready" src="assets/img/avatars/avatar_02_tn@2x.png" alt="" data-dense-cap="2">&ndash;&gt;-->
<!--</div>-->
<div class="md-list-content">
<span class="md-list-heading">Aggregation stage</span>
<span class="uk-text-small uk-text-muted">{{ aggr.aggregationStage }}</span>
</div>
</li>
<li *ngIf="aggr.collectionMode">
<!--<div class="md-list-addon-element">-->
<!--<span *ngIf="aggr.collectionMode=='REFRESH'" class="md-user-image md-list-addon-avatar dense-image dense-ready">-->
<!--<i class="material-icons">refresh</i>-->
<!--</span>-->
<!--&lt;!&ndash;<img class="md-user-image md-list-addon-avatar dense-image dense-ready" src="assets/img/avatars/avatar_02_tn@2x.png" alt="" data-dense-cap="2">&ndash;&gt;-->
<!--</div>-->
<div class="md-list-content">
<span class="md-list-heading">Collection mode</span>
<span class="uk-text-small uk-text-muted">{{ aggr.collectionMode }}</span>
</div>
</li>
<li *ngIf="aggr.numberOfRecords">
<!--<div class="md-list-addon-element">-->
<!--<span class="md-user-image md-list-addon-avatar dense-image dense-ready">-->
<!--<i class="material-icons">list</i>-->
<!--</span>-->
<!--</div>-->
<div class="md-list-content">
<span class="md-list-heading">Number of records</span>
<span class="uk-text-small uk-text-muted">{{ aggr.numberOfRecords }}</span>
</div>
</li>
</ul>
<!--<p *ngIf="aggr.indexedVersion !== null">Is the indexed version - {{ (aggr.indexedVersion === true) ? 'Yes': 'No' }}</p>-->
</div>
</div>
</div>
</div>
</div>
<div class="uk-margin-top uk-text-center">
<a *ngIf="repo" [routerLink]="['/repository/' + repo.id + '/aggregationHistory/fullHistory']" class="uk-h3 uk-link">See more results ...</a>
</div>
</div>
</div>
<!-- RIGHT HELP CONTENT -->
<aside-help-content #rightHelperContent [position]="'right'"
[ngClass]="rightHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
</div>
<!-- BOTTOM HELP CONTENT -->
<help-content #bottomHelperContent [position]="'bottom'"
[ngClass]="bottomHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
</div>

View File

@ -0,0 +1,70 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { AggregationDetails, Repository } from '../../../domain/typeScriptClasses';
import { RepositoryService } from '../../../services/repository.service';
import { loadingAggregationHistory, loadingAggregationHistoryError, noAggregationHistory } from '../../../domain/shared-messages';
import { SharedService } from "../../../services/shared.service";
@Component ({
selector: 'app-compatibility-monitor-repo',
templateUrl: 'compatibility-monitor-repo.component.html'
})
export class CompatibilityMonitorRepoComponent implements OnInit {
loadingMessage: string;
errorMessage: string;
noAggregations: string;
repoName = '';
repo: Repository;
latestAggregations: AggregationDetails[] = [];
constructor(private route: ActivatedRoute,
private router: Router,
private repoService: RepositoryService,
private sharedService: SharedService) {}
ngOnInit() {
if(this.sharedService.getRepository()) {
this.repo = this.sharedService.getRepository();
this.repoName = this.repo.officialName;
this.getLatestAggregationHistory();
}
this.sharedService.repository$.subscribe(
r => {
this.repo = r;
if (this.repo) {
this.repoName = this.repo.officialName;
this.getLatestAggregationHistory();
}
}
);
let body = document.getElementsByTagName('body')[0];
body.classList.remove("top_bar_active"); //remove the class
body.classList.remove("page_heading_active");
body.classList.remove("landing");
body.classList.add("dashboard");
}
getLatestAggregationHistory() {
this.loadingMessage = loadingAggregationHistory;
this.repoService.getRepositoryAggregations(this.repo.id).subscribe(
aggr => this.latestAggregations = aggr,
error => {
this.loadingMessage = '';
this.errorMessage = loadingAggregationHistoryError;
},
() => {
this.loadingMessage = '';
if ( !this.latestAggregations || (this.latestAggregations.length === 0) ) {
this.noAggregations = noAggregationHistory;
}
}
);
}
}

View File

@ -0,0 +1,27 @@
import { RouterModule, Routes } from '@angular/router';
import { NgModule } from '@angular/core';
import { CompatibilityMonitorRepoComponent } from "./compatibility-monitor-repo.component";
import { AuthGuardService } from "../../../services/auth-guard.service";
import { CompatibilityMonitorFullHistoryRepoComponent } from "./compatibility-monitor-fullHistory-repo.component";
const aggregationHistoryRoutes: Routes = [
{
path: '',
component: CompatibilityMonitorRepoComponent,
canActivate: [AuthGuardService],
},
{
path: 'fullHistory',
component: CompatibilityMonitorFullHistoryRepoComponent,
canActivate: [AuthGuardService]
}
];
@NgModule ({
imports: [RouterModule.forChild(aggregationHistoryRoutes)],
exports: [RouterModule]
})
export class AggregationHistoryRoutingModule {}

View File

@ -0,0 +1,22 @@
import { NgModule } from '@angular/core';
import { TabsModule } from 'ngx-bootstrap';
import { CommonModule } from '@angular/common';
import { ReusableComponentsModule } from "../../../shared/reusablecomponents/reusable-components.module";
import { AggregationHistoryRoutingModule } from "./compatibility-monitor-routing.module";
import { CompatibilityMonitorRepoComponent } from "./compatibility-monitor-repo.component";
import { CompatibilityMonitorFullHistoryRepoComponent } from "./compatibility-monitor-fullHistory-repo.component";
@NgModule ({
imports: [
CommonModule,
TabsModule.forRoot(),
AggregationHistoryRoutingModule,
ReusableComponentsModule
],
declarations: [
CompatibilityMonitorRepoComponent,
CompatibilityMonitorFullHistoryRepoComponent
]
})
export class AggregationHistoryModule { }

View File

@ -0,0 +1,399 @@
<div id="page_content_inner">
<div *ngIf="errorMessage" class="uk-alert uk-alert-danger">{{ errorMessage }}</div>
<!--<div *ngIf="noRepos" class="">{{ noRepos }}</div>-->
<div *ngIf="loadingMessage" class="loading-big">
<div class="loader-big" style="text-align: center; padding-top: 170px; color: rgb(47, 64, 80); font-weight: bold;">
{{ loadingMessage }}
</div>
<div class="transparentFilm"></div>
</div>
<div *ngIf="!loadingMessage && repository">
<!--<div *ngIf="reposOfUser.length>1" class="md-card uk-margin-bottom uk-width-1-3">-->
<!--<div class="md-card-content">-->
<!--<div class="md-input-wrapper md-input-filled">-->
<!--<label class="">Select repository</label>-->
<!--<select class="md-input" (change)="changeSelectedRepository($event.target.value)">-->
<!--<option *ngFor="let repo of reposOfUser; let i = index" value="{{ repo.id }}">{{ repo.officialname }}</option>-->
<!--</select>-->
<!--<span class="md-input-bar"></span>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--FIRST NUMBERS-->
<div class="uk-grid uk-grid-match uk-child-width-1-4@l uk-child-width-1-2@m uk-child-width-1-1@s uk-grid-medium uk-sortable sortable-handler" data-uk-sortable="" data-uk-grid-margin="">
<div class="uk-row-first" style="">
<div class="md-card">
<a [routerLink]="['/repository/' + repository.id + '/aggregationHistory']">
<div class="md-card-content">
<div class="uk-float-right uk-margin-top uk-margin-small-right"><span class="peity_live peity_data" style="display: none;">7,5,8,7,6,5,2,5,3,10,10,3,6,5,6,3,3,6,8,3</span><svg class="peity" height="28" width="64"><polygon fill="#efebe9" points="0 27.5 0 8.600000000000001 3.3684210526315788 14 6.7368421052631575 5.899999999999999 10.105263157894736 8.600000000000001 13.473684210526315 11.3 16.842105263157894 14 20.210526315789473 22.1 23.57894736842105 14 26.94736842105263 19.4 30.31578947368421 0.5 33.68421052631579 0.5 37.05263157894737 19.4 40.421052631578945 11.3 43.78947368421052 14 47.1578947368421 11.3 50.526315789473685 19.4 53.89473684210526 19.4 57.263157894736835 11.3 60.63157894736842 5.899999999999999 64 19.4 64 27.5"></polygon><polyline fill="none" points="0 8.600000000000001 3.3684210526315788 14 6.7368421052631575 5.899999999999999 10.105263157894736 8.600000000000001 13.473684210526315 11.3 16.842105263157894 14 20.210526315789473 22.1 23.57894736842105 14 26.94736842105263 19.4 30.31578947368421 0.5 33.68421052631579 0.5 37.05263157894737 19.4 40.421052631578945 11.3 43.78947368421052 14 47.1578947368421 11.3 50.526315789473685 19.4 53.89473684210526 19.4 57.263157894736835 11.3 60.63157894736842 5.899999999999999 64 19.4" stroke="#5d4037" stroke-width="1" stroke-linecap="square"></polyline></svg></div>
<ng-container *ngIf="lastIndexedVersion">
<span class="uk-text-muted uk-text-small">Records collected <span *ngIf="lastIndexedVersion.date">on {{lastIndexedVersion.date | date : "yyyy-MM-dd"}}</span></span>
<h2 class="uk-margin-remove">{{lastIndexedVersion.numberOfRecords | number}}</h2>
</ng-container>
<ng-container *ngIf="!lastIndexedVersion">
<span class="uk-text-muted uk-text-small">Records collected</span>
<h2 class="uk-margin-remove">no data available</h2>
</ng-container>
</div>
</a>
</div>
</div>
<div style="">
<div class="md-card">
<a [routerLink]="['/repository/' + repository.id + '/events']">
<div class="md-card-content">
<div class="uk-float-right uk-margin-top uk-margin-small-right"><span class="peity_orders peity_data" style="display: none;">64/100</span><svg class="peity" height="24" width="24"><path d="M 12 0 A 12 12 0 1 1 2.7538410866905263 19.649087876984275 L 7.376920543345263 15.824543938492138 A 6 6 0 1 0 12 6" data-value="64" fill="#8bc34a"></path><path d="M 2.7538410866905263 19.649087876984275 A 12 12 0 0 1 11.999999999999998 0 L 11.999999999999998 6 A 6 6 0 0 0 7.376920543345263 15.824543938492138" data-value="36" fill="#eee"></path></svg></div>
<span class="uk-text-muted uk-text-small">Enrichments</span>
<h2 class="uk-margin-remove">
<span class="countUpMe">{{ totalNumberOfEvents | number }}</span>
</h2>
</div>
</a>
</div>
</div>
<div style="">
<div class="md-card">
<a [routerLink]="['/repository/' + repository.id + '/getImpact/show_metrics']">
<div class="md-card-content">
<div class="uk-float-right uk-margin-top uk-margin-small-right"><span class="peity_sale peity_data" style="display: none;">5,3,9,6,5,9,7,3,5,2</span><svg class="peity" height="28" width="64"><polygon fill="#d1e4f6" points="0 27.5 0 12.5 7.111111111111111 18.5 14.222222222222221 0.5 21.333333333333332 9.5 28.444444444444443 12.5 35.55555555555556 0.5 42.666666666666664 6.5 49.77777777777777 18.5 56.888888888888886 12.5 64 21.5 64 27.5"></polygon><polyline fill="none" points="0 12.5 7.111111111111111 18.5 14.222222222222221 0.5 21.333333333333332 9.5 28.444444444444443 12.5 35.55555555555556 0.5 42.666666666666664 6.5 49.77777777777777 18.5 56.888888888888886 12.5 64 21.5" stroke="#0288d1" stroke-width="1" stroke-linecap="square"></polyline></svg></div>
<span class="uk-text-muted uk-text-small">Downloads</span>
<h2 class="uk-margin-remove">
<span *ngIf="totalDownloads == '--'">{{ totalDownloads }}</span>
<span *ngIf="totalDownloads != '--'">{{ totalDownloads | number }}</span>
</h2>
</div>
</a>
</div>
</div>
<div style="">
<div class="md-card">
<a [routerLink]="['/repository/' + repository.id + '/getImpact/show_metrics']">
<div class="md-card-content">
<div class="uk-float-right uk-margin-top uk-margin-small-right"><span class="peity_visitors peity_data" style="display: none;">5,3,9,6,5,9,7</span><svg class="peity" height="28" width="48"><rect data-value="5" fill="#d84315" x="1.3714285714285717" y="12.444444444444443" width="4.114285714285715" height="15.555555555555557"></rect><rect data-value="3" fill="#d84315" x="8.228571428571428" y="18.666666666666668" width="4.114285714285716" height="9.333333333333332"></rect><rect data-value="9" fill="#d84315" x="15.085714285714287" y="0" width="4.1142857142857086" height="28"></rect><rect data-value="6" fill="#d84315" x="21.942857142857147" y="9.333333333333336" width="4.114285714285707" height="18.666666666666664"></rect><rect data-value="5" fill="#d84315" x="28.800000000000004" y="12.444444444444443" width="4.114285714285707" height="15.555555555555557"></rect><rect data-value="9" fill="#d84315" x="35.65714285714286" y="0" width="4.114285714285707" height="28"></rect><rect data-value="7" fill="#d84315" x="42.51428571428572" y="6.222222222222221" width="4.114285714285707" height="21.77777777777778"></rect></svg></div>
<span class="uk-text-muted uk-text-small">Views</span>
<h2 class="uk-margin-remove">
<span *ngIf="pageViews == '--'" class="countUpMe">{{ pageViews }}</span>
<span *ngIf="pageViews != '--'" class="countUpMe">{{ pageViews | number }}</span>
</h2>
</div>
</a>
</div>
</div>
</div>
<div class="uk-grid uk-grid-medium uk-grid-match" data-uk-grid-margin="" data-uk-grid-match="{target:'.md-card-content'}">
<!--COLLECTION MONITOR-->
<div class="uk-width-1-4@m uk-row-first">
<div class="md-card" style="min-height: 600px">
<div class="md-card-content">
<h3 class="heading_a uk-margin-bottom">Aggregation History</h3>
<div *ngIf="errorAggregationsMessage" class="uk-alert uk-alert-danger">{{ errorAggregationsMessage }}</div>
<div *ngIf="loadingAggregationsMessage" class="loading-big">
<div class="loader-big" style="text-align: center; padding-top: 170px; color: rgb(47, 64, 80); font-weight: bold;">
{{ loadingAggregationsMessage }}
</div>
<div class="whiteFilm"></div>
</div>
<div *ngIf="noAggregations">{{ noAggregations }}</div>
<div *ngIf="latestAggregations && (latestAggregations.length > 0) && !noAggregations">
<div class="timeline timeline_small uk-margin-bottom">
<div *ngFor="let aggr of latestAggregations" class="timeline_item">
<div class="timeline_icon">
<ng-container *ngIf="aggr.indexedVersion">
<img src="https://www.openaire.eu/images/Logos/Favicon-90x90.png" style="width: 80%;margin-top: 9%;">
</ng-container>
</div>
<div *ngIf="aggr.date" class="timeline_date">
{{ aggr.date | date : "yyyy-MM-dd" }}
</div>
<div class="timeline_content">
<div *ngIf="aggr.indexedVersion" class="ng-star-inserted uk-badge uk-margin-small-bottom">Indexed version</div>
<div *ngIf="aggr.aggregationStage" class="uk-margin-small-bottom">
<!--<div class="inline-block" style="vertical-align: top">-->
<!--<span *ngIf="aggr.aggregationStage=='TRANSFORM'" class="md-user-image md-list-addon-avatar dense-image dense-ready">-->
<!--<i class="material-icons">transform</i>-->
<!--</span>-->
<!--<span *ngIf="aggr.aggregationStage=='COLLECT'" class="md-user-image md-list-addon-avatar dense-image dense-ready">-->
<!--<i class="material-icons">collections</i>-->
<!--</span>-->
<!--</div>-->
<div class="">
<div class="md-list-heading">Aggregation stage</div>
<div class="uk-text-small uk-text-muted">{{ aggr.aggregationStage }}</div>
</div>
</div>
<div *ngIf="aggr.collectionMode" class="uk-margin-small-bottom">
<!--<div class="inline-block" style="vertical-align: top">-->
<!--<span *ngIf="aggr.collectionMode=='REFRESH'" class="md-user-image md-list-addon-avatar dense-image dense-ready">-->
<!--<i class="material-icons">refresh</i>-->
<!--</span>-->
<!--</div>-->
<div class="">
<div class="md-list-heading">Collection mode</div>
<div class="uk-text-small uk-text-muted">{{ aggr.collectionMode }}</div>
</div>
</div>
<div *ngIf="aggr.numberOfRecords" class="uk-margin-small-bottom">
<!--<div class="inline-block" style="vertical-align: top">-->
<!--<span class="md-user-image md-list-addon-avatar dense-image dense-ready">-->
<!--<i class="material-icons">list</i>-->
<!--</span>-->
<!--</div>-->
<div class="">
<div class="md-list-heading">Number of records</div>
<div class="uk-text-small uk-text-muted">{{ aggr.numberOfRecords | number }}</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="uk-position-bottom-right" style="margin-bottom: 10px; margin-right: 10px"><a [routerLink]="['/repository/' + repository.id + '/aggregationHistory']">view more..</a></div>
</div>
</div>
</div>
<div class="uk-width-expand@m">
<!--&lt;!&ndash;VALIDATIONS&ndash;&gt;-->
<!--<div class="md-card" style="min-height: 300px">-->
<!--<div class="md-card-content">-->
<!--<h3 class="heading_a uk-margin-bottom">Validation History</h3>-->
<!--<div class="uk-overflow-container">-->
<!--<div *ngIf="noValidationsMessage">{{ noValidationsMessage }}</div>-->
<!--<div *ngIf="errorValidationsMessage" class="uk-alert uk-alert-danger">{{ errorValidationsMessage }}</div>-->
<!--<div *ngIf="loadingJobSummaryMessage" class="loading-big">-->
<!--<div class="loader-big" style="text-align: center; padding-top: 170px; color: rgb(47, 64, 80); font-weight: bold;">-->
<!--{{ loadingJobSummaryMessage }}-->
<!--</div>-->
<!--<div class="whiteFilm"></div>-->
<!--</div>-->
<!--<table *ngIf="storedJob && (storedJob.length > 0) && !noValidationsMessage" class="uk-table">-->
<!--<thead>-->
<!--<tr>-->
<!--<th class="uk-text-nowrap">Base URL</th>-->
<!--<th class="uk-text-nowrap">Validation Type</th>-->
<!--<th class="uk-text-nowrap">Status</th>-->
<!--<th class="uk-text-nowrap">Score</th>-->
<!--<th class="uk-text-nowrap uk-text-right">Guidelines</th>-->
<!--</tr>-->
<!--</thead>-->
<!--<tbody>-->
<!--<tr *ngFor="let job of storedJob" class="uk-table-middle uk-text-muted">-->
<!--<td class="uk-width-3-10 uk-text-nowrap"><div>{{ job.baseUrl }}</div></td>-->
<!--<td>-->
<!--<div *ngIf="job.validationType.includes('C')" class="">OAI Content</div>-->
<!--<div *ngIf="job.validationType.includes('U')" class="">OAI Usage</div>-->
<!--</td>-->
<!--<td class="uk-text-nowrap">-->
<!--<div [ngClass]="job.contentJobStatus == 'finished' ? 'uk-badge uk-badge-success':-->
<!--( job.contentJobStatus == 'ongoing' ) ? 'uk-badge' :-->
<!--( job.contentJobStatus == 'none' ) ? 'uk-badge uk-badge-warning' : 'clear-style' ">{{ job.contentJobStatus }}</div>-->
<!--<br *ngIf="job.contentJobStatus == 'finished' || 'ongoing' || 'none' ">-->
<!--<div [ngClass]="job.usageJobStatus == 'finished' ? 'uk-badge uk-badge-success':-->
<!--( job.usageJobStatus == 'ongoing' ) ? 'uk-badge' :-->
<!--( job.usageJobStatus == 'none' ) ? 'uk-badge uk-badge-warning' : 'clear-style' ">{{ job.usageJobStatus }}</div>-->
<!--</td>-->
<!--<td>-->
<!--<div>{{ job.contentJobScore }}</div>-->
<!--<div>{{ job.usageJobScore }}</div>-->
<!--</td>-->
<!--<td class="uk-width-3-10 uk-text-right"><div>{{ job.guidelinesShortName }}</div></td>-->
<!--</tr>-->
<!--</tbody>-->
<!--</table>-->
<!--<div class="uk-position-bottom-right" style="margin-bottom: 10px; margin-right: 10px"><a [routerLink]="['/compatibility/browseHistory/']">view more..</a></div>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--USAGE STATISTICS-->
<div class="md-card" style="min-height: 300px">
<div class="md-card-content">
<h3 class="heading_a uk-margin-bottom">Usage Counts</h3>
<div *ngIf="errorUsageStatsMessage" class="uk-alert uk-alert-danger">{{ errorUsageStatsMessage }}</div>
<div *ngIf="noUsageStats" class="">{{ noUsageStats }}</div>
<div *ngIf="loadingUsageStatsMessage" class="loading-big">
<div class="loader-big" style="text-align: center; padding-top: 170px; color: rgb(47, 64, 80); font-weight: bold;">
{{ loadingUsageStatsMessage }}
</div>
<div class="whiteFilm"></div>
</div>
<div *ngIf="!loadingUsageStatsMessage && !errorUsageStatsMessage && !noUsageStats && usageSummary" class="uk-grid">
<div class="uk-width-3-4">
<iframe *ngIf="viewsUrl" class="statsFrame" [src]="viewsUrl"></iframe>
</div>
<div class="uk-width-1-4">
<h2 class="heading_b uk-margin-bottom">
<span class="sub-heading">Last month's reports</span>
</h2>
<div class="uk-margin-top">
<a class="md-btn md-btn-large md-btn-block md-btn-wave-light waves-effect waves-button waves-light"
[routerLink]="['/repository/' + repository.id + '/getImpact/usagestats-report-results']" [queryParams]="{ report:'AR1', beginDate: currentDate, endDate: currentDate, repoId: shortRepositoryId, granularity:'Monthly'}">AR1</a>
</div>
<div class="uk-margin-top">
<a class="md-btn md-btn-large md-btn-block md-btn-wave-light waves-effect waves-button waves-light"
[routerLink]="['/repository/' + repository.id + '/getImpact/usagestats-report-results']" [queryParams]="{ report:'IR1', beginDate: currentDate, endDate: currentDate, repoId: shortRepositoryId, granularity:'Monthly'}">IR1</a>
</div>
<div class="uk-margin-top">
<a class="md-btn md-btn-large md-btn-block md-btn-wave-light waves-effect waves-button waves-light"
[routerLink]="['/repository/' + repository.id + '/getImpact/usagestats-report-results']" [queryParams]="{ report:'RR1', beginDate: currentDate, endDate: currentDate, repoId: shortRepositoryId, granularity:'Monthly'}">RR1</a>
</div>
<div class="uk-margin-top">
<a class="md-btn md-btn-large md-btn-block md-btn-wave-light waves-effect waves-button waves-light"
[routerLink]="['/repository/' + repository.id + '/getImpact/usagestats-report-results']" [queryParams]="{ report:'BR1', beginDate: currentDate, endDate: currentDate, repoId: shortRepositoryId, granularity:'Monthly'}">BR1</a>
</div>
<div class="uk-margin-top">
<a class="md-btn md-btn-large md-btn-block md-btn-wave-light waves-effect waves-button waves-light"
[routerLink]="['/repository/' + repository.id + '/getImpact/usagestats-report-results']" [queryParams]="{ report:'BR2', beginDate: currentDate, endDate: currentDate, repoId: shortRepositoryId, granularity:'Monthly'}">BR2</a>
</div>
<div *ngIf="repository && repository.typology.includes('journal')" class="uk-margin-top">
<a class="md-btn md-btn-large md-btn-block md-btn-wave-light waves-effect waves-button waves-light"
[routerLink]="['/repository/' + repository.id + '/getImpact/usagestats-report-results']" [queryParams]="{ report:'RR1', beginDate: currentDate, endDate: currentDate, repoId: shortRepositoryId, granularity:'Monthly'}">RR1</a>
</div>
</div>
</div>
</div>
<div class="uk-position-bottom-right" style="margin-bottom: 10px; margin-right: 10px"><a [routerLink]="['/repository/' + repository.id + '/getImpact/show_metrics']">view more..</a></div>
</div>
</div>
</div>
<div class="uk-grid uk-grid-medium" data-uk-grid-margin="" data-uk-grid-match="{target:'.md-card-content'}">
<!--EVENTS - MORE-->
<div class="uk-width-1-3@m uk-row-first">
<div class="md-card" style="min-height: 200px">
<div class="md-card-toolbar">
<h3 class="md-card-toolbar-heading-text">
Events - MORE
</h3>
</div>
<div class="md-card-content">
<div *ngIf="errorTopicsMessage" class="uk-alert uk-alert-danger">{{ errorTopicsMessage }}</div>
<div *ngIf="loadingTopicsMessage" class="loading-big">
<div class="loader-big" style="text-align: center; padding-top: 170px; color: rgb(47, 64, 80); font-weight: bold;">
{{ loadingTopicsMessage }}
</div>
<div class="whiteFilm"></div>
</div>
<div *ngIf="!moreList || moreList.length==0">No topics for these kind of events were found</div>
<div *ngIf="moreList && moreList.length>0">
<ul class="md-list md-list-addon gmap_list">
<li *ngFor="let moreTopic of moreList">
<div class="md-list-addon-element">
<span>{{ moreTopic.size | number }}</span>
<!--<img class="md-user-image md-list-addon-avatar" src="assets/img/avatars/avatar_01_tn.png" alt="">-->
</div>
<div class="md-list-content">
<span class="md-list-heading">{{ moreTopic.value }}</span>
<!--<span class="uk-text-small uk-text-muted">Lockman, Pouros and Kilback</span>-->
</div>
</li>
</ul>
</div>
</div>
<div class="uk-position-bottom-right" style="margin-bottom: 10px; margin-right: 10px"><a [routerLink]="['/repository/' + repository.id + '/events']">view more..</a></div>
</div>
</div>
<!--EVENTS - MISSING-->
<div class="uk-width-1-3@m">
<div class="md-card" style="min-height: 200px">
<div class="md-card-toolbar">
<h3 class="md-card-toolbar-heading-text">
Events - MISSING
</h3>
</div>
<div class="md-card-content">
<div *ngIf="errorTopicsMessage" class="uk-alert uk-alert-danger">{{ errorTopicsMessage }}</div>
<div *ngIf="loadingTopicsMessage" class="loading-big">
<div class="loader-big" style="text-align: center; padding-top: 170px; color: rgb(47, 64, 80); font-weight: bold;">
{{ loadingTopicsMessage }}
</div>
<div class="whiteFilm"></div>
</div>
<div *ngIf="!missingList || missingList.length==0">No topics for these kind of events were found</div>
<div *ngIf="missingList && missingList.length>0">
<ul class="md-list md-list-addon gmap_list">
<li *ngFor="let missingTopic of missingList">
<div class="md-list-addon-element">
<span>{{ missingTopic.size | number }}</span>
<!--<img class="md-user-image md-list-addon-avatar" src="assets/img/avatars/avatar_01_tn.png" alt="">-->
</div>
<div class="md-list-content">
<span class="md-list-heading">{{ missingTopic.value }}</span>
<!--<span class="uk-text-small uk-text-muted">Lockman, Pouros and Kilback</span>-->
</div>
</li>
</ul>
</div>
</div>
<div class="uk-position-bottom-right" style="margin-bottom: 10px; margin-right: 10px"><a [routerLink]="['/repository/' + repository.id + '/events']">view more..</a></div>
</div>
</div>
<!--NOTIFICATIONS-->
<div class="uk-width-1-3@m">
<div class="md-card" style="min-height: 200px">
<div class="md-card-toolbar">
<h3 class="md-card-toolbar-heading-text">
Notifications
</h3>
</div>
<div class="md-card-content">
<div *ngIf="errorSubscriptionsMessage" class="uk-alert uk-alert-danger">{{ errorSubscriptionsMessage }}</div>
<div *ngIf="loadingSubscriptionsMessage" class="loading-big">
<div class="loader-big" style="text-align: center; padding-top: 170px; color: rgb(47, 64, 80); font-weight: bold;">
{{ loadingSubscriptionsMessage }}
</div>
<div class="whiteFilm"></div>
</div>
<div *ngIf="!brokerSummary || !brokerSummary.userSubs">No notifications were found</div>
<div *ngIf="brokerSummary && brokerSummary.userSubs">
<ul class="md-list md-list-addon gmap_list">
<li *ngFor="let sub of brokerSummary.userSubs[repository.officialName]">
<div class="md-list-addon-element">
<span>{{ sub.count | number }}</span>
<!--<img class="md-user-image md-list-addon-avatar" src="assets/img/avatars/avatar_01_tn.png" alt="">-->
</div>
<div class="md-list-content">
<span class="md-list-heading">{{ sub.topic }}</span>
<!--<span class="uk-text-small uk-text-muted">Lockman, Pouros and Kilback</span>-->
</div>
</li>
</ul>
</div>
</div>
<div class="uk-position-bottom-right" style="margin-bottom: 10px; margin-right: 10px"><a [routerLink]="['/content/notifications']">view more..</a></div>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,296 @@
import { Component, OnInit } from '@angular/core';
import { AuthenticationService } from '../../../services/authentication.service';
import { RepositoryService } from '../../../services/repository.service';
import {
AggregationDetails, BrokerSummary, BrowseEntry, CollectionMonitorSummary,
MetricsInfo, PiwikInfo,
Repository, StoredJob, UsageSummary
} from '../../../domain/typeScriptClasses';
import {
loadingAggregationHistory, loadingAggregationHistoryError, loadingMetrics,
loadingMetricsError, loadingSubscriptions, loadingTopics, loadingTopicsError,
noAggregationHistory, noSubscriptionsFound, noTopicsFound,
loadingJobSummary, loadingJobSummaryError
} from '../../../domain/shared-messages';
import {DashboardService} from '../../../services/dashboard.service';
import {DomSanitizer, SafeResourceUrl} from '@angular/platform-browser';
import {PiwikService} from '../../../services/piwik.service';
import {ValidatorService} from '../../../services/validator.service';
import {ActivatedRoute} from "@angular/router";
import {SharedService} from "../../../services/shared.service";
@Component ({
selector: 'app-dashboard',
templateUrl: 'dashboard.component.html'
})
export class DashboardComponent implements OnInit {
repository: Repository = null;
errorMessage: string;
loadingMessage: string;
constructor(private authService: AuthenticationService,
private repositoryService: RepositoryService,
private sharedService: SharedService,
private dashboardService: DashboardService,
private piwikService: PiwikService,
private validatorService: ValidatorService,
private sanitizer: DomSanitizer,
private route: ActivatedRoute) {
}
loading: boolean = true;
// Aggregations
collectionMonitorSummary: CollectionMonitorSummary;
lastIndexedVersion: AggregationDetails;
latestAggregations: AggregationDetails[] = [];
errorAggregationsMessage: string;
noAggregations: string;
loadingAggregationsMessage: string;
// Usage Statistics
usageSummary: UsageSummary;
piwik: PiwikInfo;
repoMetrics: MetricsInfo;
errorUsageStatsMessage: string;
noUsageStats: string;
loadingUsageStatsMessage: string;
pageViews = '--';
totalViews = '--';
totalDownloads = '--';
viewsUrl: SafeResourceUrl;
downloadsUrl: SafeResourceUrl;
shortRepositoryId: string;
currentDate: string;
// Broker
brokerSummary: BrokerSummary;
errorTopicsMessage: string;
noTopics: string;
loadingTopicsMessage: string;
errorSubscriptionsMessage: string;
noSubscriptions: string;
loadingSubscriptionsMessage: string;
totalNumberOfEvents: number = 0;
moreList: BrowseEntry[] = [];
missingList: BrowseEntry[] = [];
totalMore: number = 0;
totalMissing: number = 0;
// Validation
storedJob: StoredJob[] = [];
noValidationsMessage: string;
errorValidationsMessage: string;
loadingJobSummaryMessage: string;
ngOnInit() {
if(this.sharedService.getRepository()) {
this.repository = this.sharedService.getRepository();
this.getSelectedRepositorySummaryInfo(this.repository);
}
this.sharedService.repository$.subscribe(
r => {
this.repository = r;
// console.log("RepositoryID: ", this.repository.id);
this.getSelectedRepositorySummaryInfo(this.repository);
}
);
let body = document.getElementsByTagName('body')[0];
body.classList.remove("top_bar_active");
body.classList.remove("page_heading_active");
body.classList.remove("landing");
body.classList.add("dashboard");
const currentTime = new Date();
this.currentDate = currentTime.getFullYear() + '-' + (currentTime.getMonth() + 1);
}
getSelectedRepositorySummaryInfo(repository: Repository) {
// Aggregations
this.loadingAggregationsMessage = loadingAggregationHistory;
this.latestAggregations = [];
this.lastIndexedVersion = null;
this.dashboardService.getCollectionMonitorSummary(repository.id, 5).subscribe(
collectionMonitorSummary => this.getCollectionMonitorSummary(collectionMonitorSummary),
error => {
this.loadingAggregationsMessage = '';
this.errorAggregationsMessage = loadingAggregationHistoryError;
},
() => {
this.loadingAggregationsMessage = '';
this.errorAggregationsMessage = '';
}
);
// Usage Statistics
this.loadingUsageStatsMessage = loadingMetrics;
this.usageSummary = null;
this.piwik = null;
this.repoMetrics = null;
this.pageViews = '--';
this.totalViews = '--';
this.totalDownloads = '--';
this.viewsUrl = null;
this.downloadsUrl = null;
this.shortRepositoryId = null;
this.dashboardService.getUsageSummary(repository.id).subscribe(
usageSummary => this.getUsageSummary(usageSummary),
error => {
this.loadingUsageStatsMessage = '';
this.errorUsageStatsMessage = loadingMetricsError;
console.log(error);
} ,
() => {
this.shortRepositoryId = repository.id.replace(/_/g, '').replace('::', ':');
this.loadingUsageStatsMessage = '';
this.errorUsageStatsMessage = '';
}
);
// Broker
this.loadingTopicsMessage = loadingTopics;
this.loadingSubscriptionsMessage = loadingSubscriptions;
this.brokerSummary = null;
this.totalNumberOfEvents = 0;
this.moreList = [];
this.missingList = [];
this.totalMore = 0;
this.totalMissing = 0;
this.dashboardService.getBrokerSummary(this.getCorrectName()).subscribe(
brokerSummary => this.getBrokerSummary(brokerSummary),
error => {
this.loadingTopicsMessage = '';
this.loadingSubscriptionsMessage = '';
this.errorTopicsMessage = loadingTopicsError;
this.errorSubscriptionsMessage = 'Failed to load the subscriptions for your datasource';
console.log(error);
},
() => {
this.loadingTopicsMessage = '';
this.loadingSubscriptionsMessage = '';
this.errorTopicsMessage = '';
this.errorSubscriptionsMessage = '';
}
);
// Validation
this.loadingJobSummaryMessage = loadingJobSummary;
this.noValidationsMessage = '';
this.errorValidationsMessage = '';
this.validatorService.getValidationSummary(repository.id).subscribe(
validationSummary => {
this.storedJob = validationSummary;
console.log(validationSummary);
},
error => {
this.errorValidationsMessage = loadingJobSummaryError;
this.loadingJobSummaryMessage = '';
console.log(error);
} ,
() => {
this.getValidationSummary(this.storedJob);
this.loadingJobSummaryMessage = '';
}
);
}
getCollectionMonitorSummary(collectionMonitorSummary: CollectionMonitorSummary) {
this.latestAggregations = collectionMonitorSummary.aggregationDetails;
this.lastIndexedVersion = collectionMonitorSummary.lastIndexedVersion;
if ( !this.latestAggregations || (this.latestAggregations.length === 0) ) {
this.noAggregations = noAggregationHistory;
}
}
getBrokerSummary(brokerSummary: BrokerSummary) {
this.noSubscriptions = '';
this.noTopics = '';
this.brokerSummary = brokerSummary;
if(this.brokerSummary.userSubs==null)
this.noSubscriptions = noTopicsFound;
if(this.brokerSummary.topicsForDatasource==null)
this.noTopics = noSubscriptionsFound;
this.totalNumberOfEvents = 0;
this.totalMore = 0;
this.totalMissing = 0;
if(brokerSummary.topicsForDatasource) {
for (let browseEntry of brokerSummary.topicsForDatasource) {
this.totalNumberOfEvents += browseEntry.size;
if (browseEntry.value.startsWith('ENRICH/MORE')) {
this.totalMore += browseEntry.size;
this.moreList.push(browseEntry);
} else if (browseEntry.value.startsWith('ENRICH/MISSING')) {
this.totalMissing += browseEntry.size;
this.missingList.push(browseEntry);
}
}
}
}
getUsageSummary(usageSummary: UsageSummary) {
this.noUsageStats = '';
if (usageSummary.piwikInfo == null) {
this.noUsageStats = 'This repository does not have our Usage Statistics service enabled yet';
} else {
this.usageSummary = usageSummary;
this.piwik = usageSummary.piwikInfo;
this.repoMetrics = usageSummary.metricsInfo;
if (this.repoMetrics.metricsNumbers.pageviews) {
this.pageViews = this.repoMetrics.metricsNumbers.pageviews;
}
if (this.repoMetrics.metricsNumbers.total_views) {
this.totalViews = this.repoMetrics.metricsNumbers.total_views;
}
if (this.repoMetrics.metricsNumbers.total_downloads) {
this.totalDownloads = this.repoMetrics.metricsNumbers.total_downloads;
}
this.getViewsUrl();
this.getDownloadsUrl();
}
}
getValidationSummary(validationSummary: StoredJob[]) {
if (validationSummary == null) { this.noValidationsMessage = 'There is no validation history for this repository at the moment'; }
}
getViewsUrl () {
let encodedURL = encodeURIComponent('{"library":"HighCharts","chartDescription":{"queries":[{"name":"Monthly views","type":"line","query":{"name":"usagestats.views.monthly", "parameters":["' + this.piwik.openaireId + '"], "profile":"OpenAIRE All-inclusive" }}],"chart":{"backgroundColor":"#FFFFFFFF","borderColor":"#335cadff","borderRadius":0,"borderWidth":0,"plotBorderColor":"#ccccccff","plotBorderWidth":0},"title":{"text":""},"subtitle":{},"yAxis":{"title":{"text":"Monthly views"}},"xAxis":{"title":{}},"lang":{"noData":"No Data available for the Query"},"exporting":{"enabled":false},"plotOptions":{"series":{"dataLabels":{"enabled":false}}},"legend":{"enabled":false},"credits":{"href":null,"enabled":true,"text":"Created by OpenAIRE via HighCharts"}}}');
this.viewsUrl = this.sanitizer.bypassSecurityTrustResourceUrl(`${this.repoMetrics.diagramsBaseURL}chart?json=${encodedURL}`);
}
getDownloadsUrl () {
let encodedURL = encodeURIComponent('{"library":"HighCharts","chartDescription":{"queries":[{"name":"Monthly downloads","type":"line","query":{"name":"usagestats.downloads.monthly", "parameters":["' + this.piwik.openaireId + '"], "profile":"OpenAIRE All-inclusive" }}],"chart":{"backgroundColor":"#FFFFFFFF","borderColor":"#335cadff","borderRadius":0,"borderWidth":0,"plotBorderColor":"#ccccccff","plotBorderWidth":0},"title":{"text":""},"subtitle":{},"yAxis":{"title":{"text":"Monthly downloads"}},"xAxis":{"title":{}},"lang":{"noData":"No Data available for the Query"},"exporting":{"enabled":false},"plotOptions":{"series":{"dataLabels":{"enabled":false}}},"legend":{"enabled":false},"credits":{"href":null,"enabled":true,"text":"Created by OpenAIRE via HighCharts"}}}');
this.downloadsUrl = this.sanitizer.bypassSecurityTrustResourceUrl(`${this.repoMetrics.diagramsBaseURL}chart?json=${encodedURL}`);
}
getCorrectName() {
const temp = this.repository.officialName.split('|');
let correctName = temp[0];
let repoName = temp[0];
for (let i = 1; i < temp.length; i++) {
correctName += `/${temp[i]}`;
repoName += ` | ${temp[i]}`;
}
return correctName;
}
}

View File

@ -0,0 +1,950 @@
<!--<div class="uk-sticky-placeholder" style="height: 81px; margin: 0px;">-->
<!--<div id="page_heading" style="position: fixed; top: 48px; width: 1440px;" class="uk-sticky-init uk-active">-->
<!--&lt;!&ndash;<div id="page_heading" data-uk-sticky="{ top: 48, media: 960 }" style="position: fixed; top: 48px; width: 1440px;" class="uk-sticky-init uk-active">&ndash;&gt;-->
<!--<div class="heading_actions">-->
<!--<button id="subscribe" type="button" class="uk-button uk-button-success" (click)="showSubscriptionModal()">Subscribe to these events</button>-->
<!--</div>-->
<!--<h1>{{ repoName }}</h1>-->
<!--<span class="uk-text-upper uk-text-small">{{ topic }}</span>-->
<!--</div>-->
<!--</div>-->
<div id="page_content_inner" class="uk-margin-medium-left uk-margin-medium-right uk-margin-top">
<div class="uk-margin-bottom">
<h2 class="heading_b uk-margin-bottom uk-inline">{{ topic }}</h2>
<div class="heading_actions uk-float-right repositoryAdminActions">
<button class="uk-button uk-button-link" (click)="showSubscriptionModal()">
<img src="../../../../assets/icons/noun_subscribe_2322541.svg" width="20">
Subscribe to these events
</button>
<!--<button id="subscribe" type="button" class="uk-button uk-button-success" (click)="showSubscriptionModal()">Subscribe to these events</button>-->
</div>
</div>
<!-- TOP HELP CONTENT -->
<help-content #topHelperContent [position]="'top'"
[ngClass]="topHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
<div class="uk-grid">
<!-- LEFT HELP CONTENT -->
<aside-help-content #leftHelperContent [position]="'left'"
[ngClass]="leftHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
<!-- MIDDLE -->
<div class=" uk-width-expand@m">
<div>
<div *ngIf="errorMessage" class="uk-alert uk-alert-danger">{{errorMessage}}</div>
<div *ngIf="successMessage" class="uk-alert uk-alert-success">{{successMessage}}</div>
<div *ngIf="loadingMessage" class="loading-big">
<div class="loader-big" style="text-align: center; padding-top: 170px; color: rgb(47, 64, 80); font-weight: bold;">{{ loadingMessage }}</div>
<div class="transparentFilm"></div>
</div>
<div *ngIf="noEvents" class="uk-alert">{{ noEvents }}</div>
<div *ngIf="!noEvents && !loadingMessage && !errorMessage && eventsPage && eventsPage.totalPages>0" class="events-results">
<!-- RESTORE WHEN ADVANCED SHOW EVENTS IS FIXED AND SENDS CORRECT VALUE FOR CURRENT PAGE -->
<!--<span>Showing {{(eventsPage.currPage*10)+1 }}-{{ ( (eventsPage.total < 10) || (eventsPage.total < (eventsPage.currPage+1)*10) ) ? (eventsPage.total) : (eventsPage.currPage+1)*10 }} of {{ eventsPage.total }} results</span>-->
<!-- DELETE WHEN ADVANCED SHOW EVENTS IS FIXED AND SENDS CORRECT VALUE FOR CURRENT PAGE -->
<!--<div class="uk-margin-bottom">Showing {{(currentPage*10)+1 }}-{{ ( (eventsPage.total < 10) || (eventsPage.total < (currentPage+1)*10) ) ? (eventsPage.total) : (currentPage+1)*10 }} of {{ eventsPage.total }} results</div>-->
<div class="uk-alert uk-alert-info">
This is a preview of the top 100 events generated for this topic. If you are interested to receive the full list, please subscribe to these events and then be notified about the new enrichment events for your data source.
</div>
<div style="display: flex;justify-content: space-between;">
<div class="resultsInfo" style="margin-top: auto;">
<span class="number">{{eventsPage.total}}</span> RESULTS, PAGE <span class="number">{{(currentPage)+1}}</span> OF <span class="number">{{ eventsPage.totalPages }}</span>
</div>
<div class="uk-inline">
<ul class="uk-pagination" uk-margin>
<li><a (click)="goToPreviousPage()"><span uk-pagination-previous></span></a></li>
<li class="uk-active"><span>{{ (eventsPage.totalPages > 0) ? currentPage+1 : 0 }}</span></li>
<li><a (click)="goToNextPage()"><span uk-pagination-next></span></a></li>
</ul>
</div>
</div>
<hr class="adminResultsHeader">
<!--<div *ngFor="let event of eventsPage.values; let item_i = index" class="md-card md-card-hover md-card-overlay {{ (selectedItemIndex == item_i) ? 'md-card-overlay-active' : '' }}">-->
<div *ngFor="let event of eventsPage.values; let item_i = index" class="md-card md-card-hover eventCard">
<div class="md-card-content large-padding">
<div *ngIf="event.result.originalId" class="uk-text-meta">ID: {{event.result.originalId}}</div>
<div *ngIf="event.result.titles && event.result.titles.length>0">
<div class="repositoryCardHeader uk-margin-bottom uk-margin-small-top">
<h4>{{ event.result.titles[0] }}</h4>
</div>
</div>
<ng-container *ngIf="event.highlight.creators && event.highlight.creators.length>0">
<div class="small-content">
<span class="uk-badge uk-badge-success uk-margin-small-right">{{event.highlight.creators.length}} author ORCID(s) added</span>
<span class="mute-title">FROM: </span>
<ng-container *ngIf="event.provenance.url">
<a href="{{ event.provenance.url }}" target="_blank">{{ event.provenance.repositoryName }}</a>
<span *ngIf="event.provenance.id"> (ID: {{ event.provenance.id }})</span>
</ng-container>
<ng-container *ngIf="!event.provenance.url">
<span>{{ event.provenance.repositoryName }}</span>
</ng-container>
</div>
<div class="uk-margin-top uk-margin-medium-bottom small-content">
<div *ngFor="let author of event.highlight.creators; let p_index = index" class="uk-margin-small-bottom">
<span class="highlightIndex">{{(p_index + 1)}}. </span>
<span>{{ author.fullname }} <b>&nbsp;&nbsp;({{ author.orcid }})&nbsp;&nbsp;</b></span>
</div>
</div>
</ng-container>
<ng-container *ngIf="event.highlight.pids && event.highlight.pids.length>0">
<div class="small-content">
<span class="uk-badge uk-badge-success uk-margin-small-right">{{event.highlight.pids.length}} PID(s) added</span>
<span class="mute-title">FROM: </span>
<ng-container *ngIf="event.provenance.url">
<a href="{{ event.provenance.url }}" target="_blank">{{ event.provenance.repositoryName }}</a>
<span *ngIf="event.provenance.id"> (ID: {{ event.provenance.id }})</span>
</ng-container>
<ng-container *ngIf="!event.provenance.url">
<span>{{ event.provenance.repositoryName }}</span>
</ng-container>
</div>
<div class="uk-margin-top uk-margin-medium-bottom small-content">
<div *ngFor="let pid of event.highlight.pids; let p_index = index" class="uk-margin-small-bottom">
<span class="highlightIndex">{{(p_index + 1)}}. </span>
<span>{{ pid.value }} <b>&nbsp;&nbsp;({{ pid.type }})&nbsp;&nbsp;</b></span>
</div>
</div>
</ng-container>
<ng-container *ngIf="event.highlight.abstracts && event.highlight.abstracts.length>0">
<div class="small-content">
<span class="uk-badge uk-badge-success uk-margin-small-right">{{event.highlight.abstracts.length}} Abstract(s) added</span>
<span class="mute-title">FROM: </span>
<ng-container *ngIf="event.provenance.url">
<a href="{{ event.provenance.url }}" target="_blank">{{ event.provenance.repositoryName }}</a>
<span *ngIf="event.provenance.id"> (ID: {{ event.provenance.id }})</span>
</ng-container>
<ng-container *ngIf="!event.provenance.url">
<span>{{ event.provenance.repositoryName }}</span>
</ng-container>
</div>
<div class="uk-margin-top uk-margin-medium-bottom small-content">
<div *ngFor="let abs of event.highlight.abstracts; let a_index = index" class="uk-margin-small-bottom">
<span class="highlightIndex">{{(a_index + 1)}}. </span>
<span class=""><read-more-text [text]="abs" [maxHeight]="40"></read-more-text></span>
</div>
</div>
</ng-container>
<ng-container *ngIf="event.highlight.projects && event.highlight.projects.length>0">
<div class="small-content">
<span class="uk-badge uk-badge-success uk-margin-small-right">{{event.highlight.projects.length}} Project(s) added</span>
<span class="mute-title">FROM: </span>
<ng-container *ngIf="event.provenance.url">
<a href="{{ event.provenance.url }}" target="_blank">{{ event.provenance.repositoryName }}</a>
<span *ngIf="event.provenance.id"> (ID: {{ event.provenance.id }})</span>
</ng-container>
<ng-container *ngIf="!event.provenance.url">
<span>{{ event.provenance.repositoryName }}</span>
</ng-container>
</div>
<div class="uk-margin-top uk-margin-medium-bottom small-content">
<div *ngFor="let proj of event.highlight.projects; let p_index = index" class="uk-margin-small-bottom">
<span class="highlightIndex">{{(p_index + 1)}}. </span>
<span *ngIf="proj.acronym && proj.acronym !==''">{{ proj.acronym }}</span>
<span *ngIf="!proj.acronym || proj.acronym ===''">{{ proj.title }}</span>
<span *ngIf="(proj.funder && proj.funder !=='') ||
(proj.fundingProgram && proj.fundingProgram !=='')">
(<span *ngIf="proj.funder && proj.funder !==''">{{ proj.funder }} </span>
<span *ngIf="(proj.funder && proj.funder !=='') &&
(proj.fundingProgram && proj.fundingProgram !=='')">/</span>
<span *ngIf="proj.fundingProgram && proj.fundingProgram !==''">{{ proj.fundingProgram }}</span>)
</span>
</div>
</div>
</ng-container>
<ng-container *ngIf="event.highlight.subjects && event.highlight.subjects.length>0">
<div class="small-content">
<span class="uk-badge uk-badge-success uk-margin-small-right">{{event.highlight.subjects.length}} Subject(s) added</span>
<span class="mute-title">FROM: </span>
<ng-container *ngIf="event.provenance.url">
<a href="{{ event.provenance.url }}" target="_blank">{{ event.provenance.repositoryName }}</a>
<span *ngIf="event.provenance.id"> (ID: {{ event.provenance.id }})</span>
</ng-container>
<ng-container *ngIf="!event.provenance.url">
<span>{{ event.provenance.repositoryName }}</span>
</ng-container>
</div>
<div class="uk-margin-top uk-margin-medium-bottom small-content">
<div *ngFor="let subj of event.highlight.subjects; let s_index = index" class="uk-margin-small-bottom">
<span class="highlightIndex">{{(s_index + 1)}}. </span>
<span>{{ subj.value }}</span>
</div>
</div>
</ng-container>
<ng-container *ngIf="event.highlight.publications && event.highlight.publications.length>0">
<div class="small-content">
<span class="uk-badge uk-badge-success uk-margin-small-right">{{event.highlight.publications.length}} Publications(s) added</span>
<span class="mute-title">FROM: </span>
<ng-container *ngIf="event.provenance.url">
<a href="{{ event.provenance.url }}" target="_blank">{{ event.provenance.repositoryName }}</a>
<span *ngIf="event.provenance.id"> (ID: {{ event.provenance.id }})</span>
</ng-container>
<ng-container *ngIf="!event.provenance.url">
<span>{{ event.provenance.repositoryName }}</span>
</ng-container>
</div>
<div class="uk-margin-top uk-margin-medium-bottom small-content">
<div *ngFor="let pub of event.highlight.publications; let p_index = index" class="uk-margin-small-bottom">
<span class="highlightIndex">{{(p_index + 1)}}. </span>
<span>{{ pub.title }} (ID: {{pub.originalId}})</span>
</div>
</div>
</ng-container>
<ng-container *ngIf="event.highlight.datasets && event.highlight.datasets.length>0">
<div class="small-content">
<span class="uk-badge uk-badge-success uk-margin-small-right">{{event.highlight.datasets.length}} Dataset(s) added</span>
<span class="mute-title">FROM: </span>
<ng-container *ngIf="event.provenance.url">
<a href="{{ event.provenance.url }}" target="_blank">{{ event.provenance.repositoryName }}</a>
<span *ngIf="event.provenance.id"> (ID: {{ event.provenance.id }})</span>
</ng-container>
<ng-container *ngIf="!event.provenance.url">
<span>{{ event.provenance.repositoryName }}</span>
</ng-container>
</div>
<div class="uk-margin-top uk-margin-medium-bottom small-content">
<div *ngFor="let dataset of event.highlight.datasets; let d_index = index" class="uk-margin-small-bottom">
<span class="highlightIndex">{{(d_index + 1)}}. </span>
<span>{{ dataset.title }} <span *ngIf="dataset.pids && dataset.pids.length>0">({{dataset.pids[0].type}}: {{dataset.pids[0].value}})</span></span>
</div>
</div>
</ng-container>
<ng-container *ngIf="event.highlight.softwares && event.highlight.softwares.length>0">
<div class="small-content">
<span class="uk-badge uk-badge-success uk-margin-small-right">{{event.highlight.softwares.length}} Software(s) added</span>
<span class="mute-title">FROM: </span>
<ng-container *ngIf="event.provenance.url">
<a href="{{ event.provenance.url }}" target="_blank">{{ event.provenance.repositoryName }}</a>
<span *ngIf="event.provenance.id"> (ID: {{ event.provenance.id }})</span>
</ng-container>
<ng-container *ngIf="!event.provenance.url">
<span>{{ event.provenance.repositoryName }}</span>
</ng-container>
</div>
<div class="uk-margin-top uk-margin-medium-bottom small-content">
<div *ngFor="let software of event.highlight.softwares; let s_index = index" class="uk-margin-small-bottom">
<span class="highlightIndex">{{(s_index + 1)}}. </span>
<span>{{ software.name }}</span>
<span *ngIf="software.description"> <br> {{ software.description }}</span>
<span><br><a href="{{ software.landingPage }}" target="_blank">{{ software.landingPage }}</a></span>
</div>
</div>
</ng-container>
<ng-container *ngIf="event.highlight.instances && event.highlight.instances.length>0">
<div class="small-content">
<span class="uk-badge uk-badge-success uk-margin-small-right">{{event.highlight.instances.length}} OA version(s) added</span>
<span class="mute-title">FROM: </span>
<ng-container *ngIf="event.provenance.url">
<a href="{{ event.provenance.url }}" target="_blank">{{ event.provenance.repositoryName }}</a>
<span *ngIf="event.provenance.id"> (ID: {{ event.provenance.id }})</span>
</ng-container>
<ng-container *ngIf="!event.provenance.url">
<span>{{ event.provenance.repositoryName }}</span>
</ng-container>
</div>
<div class="uk-margin-top uk-margin-medium-bottom small-content">
<div *ngFor="let l of event.highlight.instances; let l_index = index" class="uk-margin-small-bottom">
<span class="highlightIndex">{{(l_index + 1)}}. </span>
<span>
{{ l.license }}&nbsp;&nbsp;<b>{{ l.hostedby }}</b>
<a href="{{ l.url }}" target="_blank" class="uk-margin-left">{{ l.url }}</a>
</span>
</div>
</div>
</ng-container>
<div *ngIf="selectedItemIndex == item_i" class="uk-text-meta uk-text-center">
<a (click)="showLess(item_i)">Show less <i class="fas fa-angle-up uk-margin-small-left"></i></a>
</div>
<div *ngIf="selectedItemIndex != item_i" class="uk-text-meta uk-text-center">
<a (click)="showMore(item_i)">Show more <i class="fas fa-angle-down uk-margin-small-left"></i></a>
</div>
<ng-container *ngIf="selectedItemIndex == item_i">
<hr>
<!--AUTHORS-->
<div *ngIf="event.result.creators && event.result.creators.length>0" class="uk-margin-small-bottom">
<span class="mute-title">Author(s): </span>
<span *ngFor="let auth of event.result.creators; let au_index = index" class="small-content">
<span *ngIf="au_index>0"> | </span>
<span>{{ auth.fullname }} <b>&nbsp;({{ auth.orcid }})&nbsp;&nbsp;</b></span>
</span>
</div>
<!--PIDs-->
<div *ngIf="event.result.pids && event.result.pids.length>0" class="uk-margin-small-bottom">
<span class="mute-title">PID(s): </span>
<span *ngFor="let pid of event.result.pids; let p_index = index" class="small-content">
<br *ngIf="p_index > 0">
<span>{{ pid.value }} <b>&nbsp;&nbsp;({{ pid.type }})&nbsp;&nbsp;</b></span>
</span>
</div>
<!--Abstracts-->
<div *ngIf="event.result.abstracts && event.result.abstracts.length>0" class="uk-margin-small-bottom">
<span class="mute-title">Abstract(s): </span>
<span *ngFor="let abs of event.result.abstracts; let a_index = index" class="small-content">
<br *ngIf="a_index > 0">
<span>
<read-more-text [text]="abs" [maxHeight]="83"></read-more-text>
</span>
</span>
</div>
<!--Projects/Relations-->
<div *ngIf="event.result.projects && event.result.projects.length>0" class="uk-margin-small-bottom">
<span class="mute-title">Project(s)/Relation(s): </span>
<span *ngFor="let proj of event.result.projects; let p_index = index" class="small-content">
<br *ngIf="p_index > 0">
<span *ngIf="proj.acronym && proj.acronym !==''">{{ proj.acronym }}</span>
<span *ngIf="!proj.acronym || proj.acronym ===''">{{ proj.title }}</span>
<span *ngIf="(proj.funder && proj.funder !=='') ||
(proj.fundingProgram && proj.fundingProgram !=='')">
(<span *ngIf="proj.funder && proj.funder !==''">{{ proj.funder }} </span>
<span *ngIf="(proj.funder && proj.funder !=='') &&
(proj.fundingProgram && proj.fundingProgram !=='')">/</span>
<span *ngIf="proj.fundingProgram && proj.fundingProgram !==''">{{ proj.fundingProgram }}</span>)
</span>
</span>
</div>
<!--Subjects-->
<div *ngIf="event.result.subjects && event.result.subjects.length>0" class="uk-margin-small-bottom">
<span class="mute-title">Subject(s): </span>
<span *ngFor="let subj of event.result.subjects; let s_index = index" class="small-content">
<span *ngIf="s_index>0"> | </span>
<span>{{ subj.value }}</span>
</span>
</div>
<!--Publications-->
<div *ngIf="event.result.publications && event.result.publications.length>0" class="uk-margin-small-bottom">
<span *ngIf="this.topic.includes('PUBLICATION')" class="mute-title">{{this.lastTopicEntry}} Publication(s): </span>
<span *ngIf="!this.topic.includes('PUBLICATION')" class="mute-title">Publication(s): </span>
<span *ngFor="let pub of event.result.publications; let p_index = index" class="small-content">
<br *ngIf="p_index > 0">
<span>{{ pub.title }} (ID: {{pub.originalId}})</span>
</span>
</div>
<!--Datasets-->
<div *ngIf="event.result.datasets && event.result.datasets.length>0" class="uk-margin-small-bottom">
<span *ngIf="this.topic.includes('DATASET')" class="mute-title">{{this.lastTopicEntry}} Dataset(s): </span>
<span *ngIf="!this.topic.includes('DATASET')" class="mute-title">Dataset(s): </span>
<span *ngFor="let dataset of event.result.datasets; let d_index = index" class="small-content">
<br *ngIf="d_index > 0">
<span>{{ dataset.titles[0] }} <span *ngIf="dataset.pids && dataset.pids.length>0">({{dataset.pids[0].type}}: {{dataset.pids[0].value}})</span></span>
</span>
</div>
<!--Software-->
<div *ngIf="event.result.softwares && event.result.softwares.length>0" class="uk-margin-small-bottom">
<span *ngIf="this.topic.includes('SOFTWARE')" class="mute-title">{{this.lastTopicEntry}} Software(s): </span>
<span *ngIf="!this.topic.includes('SOFTWARE')" class="mute-title">Software(s): </span>
<span *ngFor="let software of event.result.softwares; let s_index = index" class="small-content">
<br *ngIf="s_index > 0">
<span>{{ software.name }}</span>
<span *ngIf="software.description"> <br> {{ software.description }}</span>
<span><br><a href="{{ software.landingPage }}" target="_blank">{{ software.landingPage }}</a></span>
<span *ngIf="software.landingPage !== software.repository"><br><a href="{{ software.repository }}" target="_blank">{{ software.repository }}</a></span>
</span>
</div>
<!--Publication Date-->
<div *ngIf="event.result.publicationdate && event.result.publicationdate.length>0" class="uk-margin-small-bottom">
<span class="mute-title">Publication date(s): </span>
<span class="small-content">
{{ event.result.publicationdate }}
</span>
</div>
<!--Rights-->
<div *ngIf="event.result.instances && event.result.instances.length>0" class="uk-margin-small-bottom">
<span class="mute-title">Rights: </span>
<span *ngFor="let l of event.result.instances; let l_index = index" class="small-content">
<br *ngIf="l_index > 0">
<span>
{{ l.license }}&nbsp;&nbsp;<b>{{ l.hostedby }}</b> - <a class="" href="{{ l.url }}" target="_blank">{{ l.url }}</a>
</span>
</span>
</div>
</ng-container>
</div>
</div>
<!-- BOTTOM PAGINATION LINKS -->
<ul class="uk-pagination uk-margin-top uk-flex-right" uk-margin>
<li><a (click)="goToPreviousPage()"><span uk-pagination-previous></span></a></li>
<li class="uk-active"><span>{{ (eventsPage.totalPages > 0) ? currentPage+1 : 0 }}</span></li>
<li><a (click)="goToNextPage()"><span uk-pagination-next></span></a></li>
</ul>
</div>
</div>
</div>
<!-- RIGHT HELP CONTENT -->
<aside-help-content #rightHelperContent [position]="'right'"
[ngClass]="rightHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
</div>
<!-- BOTTOM HELP CONTENT -->
<help-content #bottomHelperContent [position]="'bottom'"
[ngClass]="bottomHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
</div>
<div class="filter-overlay-toolbar uk-animation-scale-up ng-star-inserted">
<button class="uk-button filter-overlay-button" type="button" uk-toggle="target: #offcanvas-overlay">
<span class=""><i class="fas fa-filter"></i></span>
</button>
</div>
<div class="offcanvas-filters" id="offcanvas-overlay" uk-offcanvas="overlay: true">
<div class="uk-offcanvas-bar uk-light">
<button class="uk-offcanvas-close" type="button" uk-close></button>
<h4>Filters
<button type="button" (click)="updateQuery()" class="uk-button uk-button-link advancedSearch uk-margin-right uk-margin-medium-left">Apply<i class="fas fa-check uk-margin-small-left"></i></button>
<button type="reset" (click)="clearForm()" class="uk-button uk-button-link clearCriteria">Clear<i class="fas fa-times uk-margin-small-left"></i></button>
</h4>
<div [formGroup]="group" class="">
<div class="enrichContentAdvancedSearch">
<div role="form" class="uk-form-horizontal">
<div class="uk-form-horizontal uk-margin-bottom">
<div class="form-group">
<label class="control-label">Trust [{{group.get('trustMin').value}} - {{group.get('trustMax').value}}]</label><br>
<input type="range" min="0" max="1" step="0.05" formControlName="trustMin" class="uk-range"/>
<input type="range" min="0" max="1" step="0.05" formControlName="trustMax" class="uk-range"/>
</div>
</div>
<div class="uk-form-horizontal uk-margin-small-bottom">
<div data-dynamic-fields="field_template_b" dynamic-fields-counter="1">
<div formArrayName="eventTitles" class="uk-grid form_section" *ngFor="let title of eventTitleFormArray; let title_index = index; let last_title = last;">
<div [formGroupName]="title_index" class="uk-width-1-1 uk-margin-small-bottom">
<div class="uk-input-group">
<div class="md-input-wrapper md-input-filled">
<label>Title</label>
<input type="text" class="md-input label-fixed" formControlName="eventTitle">
<span class="md-input-bar "></span>
</div>
<span *ngIf="last_title" class="uk-input-group-addon">
<a (click)="addControl('eventTitles',titleDefinition)" class="btnSectionClone"><i class="material-icons md-24"></i></a>
</span>
<span *ngIf="!last_title" class="uk-input-group-addon">
<a (click)="removeControl('eventTitles',title_index)" class="btnSectionRemove"><i class="material-icons md-24"></i></a>
</span>
</div>
</div>
</div>
</div>
<!--<div class="form-group">-->
<!--<label class="control-label" style="display: block;">Title</label>-->
<!--<div formArrayName="eventTitles" *ngFor="let title of eventTitleFormArray; let title_index = index">-->
<!--<div [formGroupName]="title_index">-->
<!--<input class="form-control inlineBlock" style="width:88%;" type="text" formControlName="eventTitle">-->
<!--<a class="inlineBlock deleteIcon" (click)="removeControl('eventTitles',title_index)"><i class="fa fa-remove"></i></a>-->
<!--</div>-->
<!--</div>-->
<!--<a (click)="addControl('eventTitles',titleDefinition)"><i class="fa fa-plus"></i> Add another</a>-->
<!--</div>-->
</div>
<div class="uk-form-horizontal uk-margin-small-bottom">
<div data-dynamic-fields="field_template_b" dynamic-fields-counter="1">
<div formArrayName="eventAuthors" class="uk-grid form_section" *ngFor="let author of eventAuthorFormArray; let author_index = index; let last_author = last;">
<div [formGroupName]="author_index" class="uk-width-1-1 uk-margin-small-bottom">
<div class="uk-input-group">
<div class="md-input-wrapper md-input-filled">
<label>Author</label>
<input type="text" class="md-input label-fixed" formControlName="eventAuthor">
<span class="md-input-bar "></span>
</div>
<span *ngIf="last_author" class="uk-input-group-addon">
<a (click)="addControl('eventAuthors',authorDefinition)" class="btnSectionClone"><i class="material-icons md-24"></i></a>
</span>
<span *ngIf="!last_author" class="uk-input-group-addon">
<a (click)="removeControl('eventAuthors',author_index)" class="btnSectionRemove"><i class="material-icons md-24"></i></a>
</span>
</div>
</div>
</div>
</div>
<!--<div class="form-group">-->
<!--<label class="control-label" style="display: block;">Author</label>-->
<!--<div formArrayName="eventAuthors" *ngFor="let author of eventAuthorFormArray; let author_index = index">-->
<!--<div [formGroupName]="author_index">-->
<!--<input class="form-control inlineBlock" style="width:88%;" type="text" formControlName="eventAuthor">-->
<!--<a class="inlineBlock deleteIcon" (click)="removeControl('eventAuthors',author_index)"><i class="fa fa-remove"></i></a>-->
<!--</div>-->
<!--</div>-->
<!--<a (click)="addControl('eventAuthors', authorDefinition)"><i class="fa fa-plus"></i> Add another</a>-->
<!--</div>-->
</div>
<div class="uk-form-horizontal uk-margin-small-bottom">
<div data-dynamic-fields="field_template_b" dynamic-fields-counter="1">
<div formArrayName="eventSubjects" class="uk-grid form_section" *ngFor="let subject of eventSubjectsFormArray; let subject_index = index; let last_subject = last;">
<div [formGroupName]="subject_index" class="uk-width-1-1 uk-margin-small-bottom">
<div class="uk-input-group">
<div class="md-input-wrapper md-input-filled">
<label>Subject</label>
<input type="text" class="md-input label-fixed" formControlName="eventSubject">
<span class="md-input-bar "></span>
</div>
<span *ngIf="last_subject" class="uk-input-group-addon">
<a (click)="addControl('eventSubjects',subjectDefinition)" class="btnSectionClone"><i class="material-icons md-24"></i></a>
</span>
<span *ngIf="!last_subject" class="uk-input-group-addon">
<a (click)="removeControl('eventSubjects',subject_index)" class="btnSectionRemove"><i class="material-icons md-24"></i></a>
</span>
</div>
</div>
</div>
</div>
<!--<div class="form-group">-->
<!--<label class="control-label" style="display: block;">Subject</label>-->
<!--<div formArrayName="eventSubjects" *ngFor="let subject of eventSubjectsFormArray; let subject_index = index">-->
<!--<div [formGroupName]="subject_index">-->
<!--<input class="form-control inlineBlock" style="width:88%;" type="text" formControlName="eventSubject">-->
<!--<a class="inlineBlock deleteIcon" (click)="removeControl('eventSubjects', subject_index)"><i class="fa fa-remove"></i></a>-->
<!--</div>-->
<!--</div>-->
<!--<a (click)="addControl('eventSubjects', subjectDefinition)"><i class="fa fa-plus"></i> Add another</a>-->
<!--</div>-->
</div>
<div>
<div class="uk-form-horizontal">
<div data-dynamic-fields="field_template_b" dynamic-fields-counter="1">
<div formArrayName="eventDateRanges" class="uk-grid form_section" *ngFor="let date of eventDateRangesFormArray; let date_index = index; let last_date = last;">
<div [formGroupName]="date_index" class="uk-width-1-1 uk-margin-small-bottom">
<div class="uk-input-group">
<div class="md-input-wrapper md-input-filled">
<label>Date From</label>
<input type="text" class="md-input label-fixed" onfocus="(this.type='date')" formControlName="dateFrom">
<span class="md-input-bar "></span>
</div>
<div class="md-input-wrapper md-input-filled">
<label>Date To</label>
<input type="text" class="md-input label-fixed" onfocus="(this.type='date')" formControlName="dateTo">
<span class="md-input-bar "></span>
</div>
<span *ngIf="last_date" class="uk-input-group-addon">
<a (click)="addControl('eventDateRanges',dateRangeDefinition)" class="btnSectionClone"><i class="material-icons md-24"></i></a>
</span>
<span *ngIf="!last_date" class="uk-input-group-addon">
<a (click)="removeControl('eventDateRanges',date_index)" class="btnSectionRemove"><i class="material-icons md-24"></i></a>
</span>
</div>
</div>
</div>
</div>
<!--<div class="form-group">-->
<!--<label class="control-label" style="display: block;">Date</label>-->
<!--<div formArrayName="eventDateRanges" *ngFor="let date of eventDateRangesFormArray; let date_index = index">-->
<!--<div class="uk-form" style="position: relative;" [formGroupName]=date_index>-->
<!--<input class="form-control inlineBlock dateFrom" style="width:88%;"-->
<!--placeholder="From"-->
<!--type="text"-->
<!--onfocus="(this.type='date')"-->
<!--formControlName=dateFrom>-->
<!--<input class="form-control inlineBlock dateTo" style="width:88%;"-->
<!--placeholder="To"-->
<!--type="text"-->
<!--onfocus="(this.type='date')"-->
<!--formControlName=dateTo>-->
<!--<a class="inlineBlock deleteIcon" (click)="removeControl('eventDateRanges',date_index)"><i class="fa fa-remove" style=""></i></a>-->
<!--</div>-->
<!--</div>-->
<!--<a (click)="addControl('eventDateRanges', dateRangeDefinition)"><i class="fa fa-plus"></i> Add another</a>-->
<!--</div>-->
</div>
</div>
<!--<div role="form" class="form-horizontal">-->
<!--<div class="form-group">-->
<!--<div class="actionButtons">-->
<!--<button type="button" (click)="updateQuery()" class="uk-button uk-button-primary advancedSearch uk-margin-small-right">Apply</button>-->
<!--<button type="reset" (click)="clearForm()" class="uk-button uk-button-default clearCriteria">Clear</button>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
</div>
</div>
<!--<div class="enrichContentAdvancedSearch md-card sidemenu">-->
<!--<div class="md-card-toolbar">-->
<!--<div class="md-card-toolbar-actions">-->
<!--<button type="button" (click)="updateQuery()" class="uk-button uk-button-primary advancedSearch uk-margin-small-right">Apply</button>-->
<!--<button type="reset" (click)="clearForm()" class="uk-button uk-button-default clearCriteria">Clear</button>-->
<!--&lt;!&ndash;<a href="#" class="md-btn md-btn-small md-btn-flat">Button</a>&ndash;&gt;-->
<!--&lt;!&ndash;<a href="#" class="md-btn md-btn-small md-btn-flat md-btn-flat-primary">Button</a>&ndash;&gt;-->
<!--</div>-->
<!--<h3 class="md-card-toolbar-heading-text">-->
<!--Tweak and refine events-->
<!--</h3>-->
<!--</div>-->
<!--<div class="md-card-content">-->
<!--<div role="form" class="uk-form-horizontal">-->
<!--<div class="uk-form-horizontal uk-margin-bottom">-->
<!--<div class="form-group">-->
<!--<label class="control-label">Trust [{{group.get('trustMin').value}} - {{group.get('trustMax').value}}]</label><br>-->
<!--<input type="range" min="0" max="1" step="0.05" formControlName="trustMin" class="uk-range"/>-->
<!--<input type="range" min="0" max="1" step="0.05" formControlName="trustMax" class="uk-range"/>-->
<!--</div>-->
<!--</div>-->
<!--<div class="uk-form-horizontal uk-margin-small-bottom">-->
<!--<div data-dynamic-fields="field_template_b" dynamic-fields-counter="1">-->
<!--<div formArrayName="eventTitles" class="uk-grid form_section" *ngFor="let title of eventTitleFormArray; let title_index = index; let last_title = last;">-->
<!--<div [formGroupName]="title_index" class="uk-width-1-1 uk-margin-small-bottom">-->
<!--<div class="uk-input-group">-->
<!--<div class="md-input-wrapper md-input-filled">-->
<!--<label>Title</label>-->
<!--<input type="text" class="md-input label-fixed" formControlName="eventTitle">-->
<!--<span class="md-input-bar "></span>-->
<!--</div>-->
<!--<span *ngIf="last_title" class="uk-input-group-addon">-->
<!--<a (click)="addControl('eventTitles',titleDefinition)" class="btnSectionClone"><i class="material-icons md-24"></i></a>-->
<!--</span>-->
<!--<span *ngIf="!last_title" class="uk-input-group-addon">-->
<!--<a (click)="removeControl('eventTitles',title_index)" class="btnSectionRemove"><i class="material-icons md-24"></i></a>-->
<!--</span>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--&lt;!&ndash;<div class="form-group">&ndash;&gt;-->
<!--&lt;!&ndash;<label class="control-label" style="display: block;">Title</label>&ndash;&gt;-->
<!--&lt;!&ndash;<div formArrayName="eventTitles" *ngFor="let title of eventTitleFormArray; let title_index = index">&ndash;&gt;-->
<!--&lt;!&ndash;<div [formGroupName]="title_index">&ndash;&gt;-->
<!--&lt;!&ndash;<input class="form-control inlineBlock" style="width:88%;" type="text" formControlName="eventTitle">&ndash;&gt;-->
<!--&lt;!&ndash;<a class="inlineBlock deleteIcon" (click)="removeControl('eventTitles',title_index)"><i class="fa fa-remove"></i></a>&ndash;&gt;-->
<!--&lt;!&ndash;</div>&ndash;&gt;-->
<!--&lt;!&ndash;</div>&ndash;&gt;-->
<!--&lt;!&ndash;<a (click)="addControl('eventTitles',titleDefinition)"><i class="fa fa-plus"></i> Add another</a>&ndash;&gt;-->
<!--&lt;!&ndash;</div>&ndash;&gt;-->
<!--</div>-->
<!--<div class="uk-form-horizontal uk-margin-small-bottom">-->
<!--<div data-dynamic-fields="field_template_b" dynamic-fields-counter="1">-->
<!--<div formArrayName="eventAuthors" class="uk-grid form_section" *ngFor="let author of eventAuthorFormArray; let author_index = index; let last_author = last;">-->
<!--<div [formGroupName]="author_index" class="uk-width-1-1 uk-margin-small-bottom">-->
<!--<div class="uk-input-group">-->
<!--<div class="md-input-wrapper md-input-filled">-->
<!--<label>Author</label>-->
<!--<input type="text" class="md-input label-fixed" formControlName="eventAuthor">-->
<!--<span class="md-input-bar "></span>-->
<!--</div>-->
<!--<span *ngIf="last_author" class="uk-input-group-addon">-->
<!--<a (click)="addControl('eventAuthors',authorDefinition)" class="btnSectionClone"><i class="material-icons md-24"></i></a>-->
<!--</span>-->
<!--<span *ngIf="!last_author" class="uk-input-group-addon">-->
<!--<a (click)="removeControl('eventAuthors',author_index)" class="btnSectionRemove"><i class="material-icons md-24"></i></a>-->
<!--</span>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--&lt;!&ndash;<div class="form-group">&ndash;&gt;-->
<!--&lt;!&ndash;<label class="control-label" style="display: block;">Author</label>&ndash;&gt;-->
<!--&lt;!&ndash;<div formArrayName="eventAuthors" *ngFor="let author of eventAuthorFormArray; let author_index = index">&ndash;&gt;-->
<!--&lt;!&ndash;<div [formGroupName]="author_index">&ndash;&gt;-->
<!--&lt;!&ndash;<input class="form-control inlineBlock" style="width:88%;" type="text" formControlName="eventAuthor">&ndash;&gt;-->
<!--&lt;!&ndash;<a class="inlineBlock deleteIcon" (click)="removeControl('eventAuthors',author_index)"><i class="fa fa-remove"></i></a>&ndash;&gt;-->
<!--&lt;!&ndash;</div>&ndash;&gt;-->
<!--&lt;!&ndash;</div>&ndash;&gt;-->
<!--&lt;!&ndash;<a (click)="addControl('eventAuthors', authorDefinition)"><i class="fa fa-plus"></i> Add another</a>&ndash;&gt;-->
<!--&lt;!&ndash;</div>&ndash;&gt;-->
<!--</div>-->
<!--<div class="uk-form-horizontal uk-margin-small-bottom">-->
<!--<div data-dynamic-fields="field_template_b" dynamic-fields-counter="1">-->
<!--<div formArrayName="eventSubjects" class="uk-grid form_section" *ngFor="let subject of eventSubjectsFormArray; let subject_index = index; let last_subject = last;">-->
<!--<div [formGroupName]="subject_index" class="uk-width-1-1 uk-margin-small-bottom">-->
<!--<div class="uk-input-group">-->
<!--<div class="md-input-wrapper md-input-filled">-->
<!--<label>Subject</label>-->
<!--<input type="text" class="md-input label-fixed" formControlName="eventSubject">-->
<!--<span class="md-input-bar "></span>-->
<!--</div>-->
<!--<span *ngIf="last_subject" class="uk-input-group-addon">-->
<!--<a (click)="addControl('eventSubjects',subjectDefinition)" class="btnSectionClone"><i class="material-icons md-24"></i></a>-->
<!--</span>-->
<!--<span *ngIf="!last_subject" class="uk-input-group-addon">-->
<!--<a (click)="removeControl('eventSubjects',subject_index)" class="btnSectionRemove"><i class="material-icons md-24"></i></a>-->
<!--</span>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--&lt;!&ndash;<div class="form-group">&ndash;&gt;-->
<!--&lt;!&ndash;<label class="control-label" style="display: block;">Subject</label>&ndash;&gt;-->
<!--&lt;!&ndash;<div formArrayName="eventSubjects" *ngFor="let subject of eventSubjectsFormArray; let subject_index = index">&ndash;&gt;-->
<!--&lt;!&ndash;<div [formGroupName]="subject_index">&ndash;&gt;-->
<!--&lt;!&ndash;<input class="form-control inlineBlock" style="width:88%;" type="text" formControlName="eventSubject">&ndash;&gt;-->
<!--&lt;!&ndash;<a class="inlineBlock deleteIcon" (click)="removeControl('eventSubjects', subject_index)"><i class="fa fa-remove"></i></a>&ndash;&gt;-->
<!--&lt;!&ndash;</div>&ndash;&gt;-->
<!--&lt;!&ndash;</div>&ndash;&gt;-->
<!--&lt;!&ndash;<a (click)="addControl('eventSubjects', subjectDefinition)"><i class="fa fa-plus"></i> Add another</a>&ndash;&gt;-->
<!--&lt;!&ndash;</div>&ndash;&gt;-->
<!--</div>-->
<!--<div>-->
<!--<div class="uk-form-horizontal">-->
<!--<div data-dynamic-fields="field_template_b" dynamic-fields-counter="1">-->
<!--<div formArrayName="eventDateRanges" class="uk-grid form_section" *ngFor="let date of eventDateRangesFormArray; let date_index = index; let last_date = last;">-->
<!--<div [formGroupName]="date_index" class="uk-width-1-1 uk-margin-small-bottom">-->
<!--<div class="uk-input-group">-->
<!--<div class="md-input-wrapper md-input-filled">-->
<!--<label>Date From</label>-->
<!--<input type="text" class="md-input label-fixed" onfocus="(this.type='date')" formControlName="dateFrom">-->
<!--<span class="md-input-bar "></span>-->
<!--</div>-->
<!--<div class="md-input-wrapper md-input-filled">-->
<!--<label>Date To</label>-->
<!--<input type="text" class="md-input label-fixed" onfocus="(this.type='date')" formControlName="dateTo">-->
<!--<span class="md-input-bar "></span>-->
<!--</div>-->
<!--<span *ngIf="last_date" class="uk-input-group-addon">-->
<!--<a (click)="addControl('eventDateRanges',dateRangeDefinition)" class="btnSectionClone"><i class="material-icons md-24"></i></a>-->
<!--</span>-->
<!--<span *ngIf="!last_date" class="uk-input-group-addon">-->
<!--<a (click)="removeControl('eventDateRanges',date_index)" class="btnSectionRemove"><i class="material-icons md-24"></i></a>-->
<!--</span>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--&lt;!&ndash;<div class="form-group">&ndash;&gt;-->
<!--&lt;!&ndash;<label class="control-label" style="display: block;">Date</label>&ndash;&gt;-->
<!--&lt;!&ndash;<div formArrayName="eventDateRanges" *ngFor="let date of eventDateRangesFormArray; let date_index = index">&ndash;&gt;-->
<!--&lt;!&ndash;<div class="uk-form" style="position: relative;" [formGroupName]=date_index>&ndash;&gt;-->
<!--&lt;!&ndash;<input class="form-control inlineBlock dateFrom" style="width:88%;"&ndash;&gt;-->
<!--&lt;!&ndash;placeholder="From"&ndash;&gt;-->
<!--&lt;!&ndash;type="text"&ndash;&gt;-->
<!--&lt;!&ndash;onfocus="(this.type='date')"&ndash;&gt;-->
<!--&lt;!&ndash;formControlName=dateFrom>&ndash;&gt;-->
<!--&lt;!&ndash;<input class="form-control inlineBlock dateTo" style="width:88%;"&ndash;&gt;-->
<!--&lt;!&ndash;placeholder="To"&ndash;&gt;-->
<!--&lt;!&ndash;type="text"&ndash;&gt;-->
<!--&lt;!&ndash;onfocus="(this.type='date')"&ndash;&gt;-->
<!--&lt;!&ndash;formControlName=dateTo>&ndash;&gt;-->
<!--&lt;!&ndash;<a class="inlineBlock deleteIcon" (click)="removeControl('eventDateRanges',date_index)"><i class="fa fa-remove" style=""></i></a>&ndash;&gt;-->
<!--&lt;!&ndash;</div>&ndash;&gt;-->
<!--&lt;!&ndash;</div>&ndash;&gt;-->
<!--&lt;!&ndash;<a (click)="addControl('eventDateRanges', dateRangeDefinition)"><i class="fa fa-plus"></i> Add another</a>&ndash;&gt;-->
<!--&lt;!&ndash;</div>&ndash;&gt;-->
<!--</div>-->
<!--</div>-->
<!--&lt;!&ndash;<div role="form" class="form-horizontal">&ndash;&gt;-->
<!--&lt;!&ndash;<div class="form-group">&ndash;&gt;-->
<!--&lt;!&ndash;<div class="actionButtons">&ndash;&gt;-->
<!--&lt;!&ndash;<button type="button" (click)="updateQuery()" class="uk-button uk-button-primary advancedSearch uk-margin-small-right">Apply</button>&ndash;&gt;-->
<!--&lt;!&ndash;<button type="reset" (click)="clearForm()" class="uk-button uk-button-default clearCriteria">Clear</button>&ndash;&gt;-->
<!--&lt;!&ndash;</div>&ndash;&gt;-->
<!--&lt;!&ndash;</div>&ndash;&gt;-->
<!--&lt;!&ndash;</div>&ndash;&gt;-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
</div>
<!--<form [formGroup]="dataForm" class="uk-form-stacked">-->
<!--<div class="uk-margin">-->
<!--<h5 class="">Datasource Type</h5>-->
<!--<div class="uk-form-controls">-->
<!--<div class="uk-margin-small-bottom"><label><input class="uk-radio" type="radio" value="" (change)="handleChangeAndResetPage()" formControlName="typology"> Any</label></div>-->
<!--<div class="uk-margin-small-bottom"><label><input class="uk-radio" type="radio" value="Aggregator" (change)="handleChangeAndResetPage()" formControlName="typology"> Aggregator</label></div>-->
<!--<div class="uk-margin-small-bottom"><label><input class="uk-radio" type="radio" value="Journal" (change)="handleChangeAndResetPage()" formControlName="typology"> Journal</label></div>-->
<!--<div class="uk-margin-small-bottom"><label><input class="uk-radio" type="radio" value="datarepository" (change)="handleChangeAndResetPage()" formControlName="typology"> Data Repository</label></div>-->
<!--<div class="uk-margin-small-bottom"><label><input class="uk-radio" type="radio" value="pubsrepository" (change)="handleChangeAndResetPage()" formControlName="typology"> Public Repository</label></div>-->
<!--<div class="uk-margin-small-bottom"><label><input class="uk-radio" type="radio" value="entityregistry" (change)="handleChangeAndResetPage()" formControlName="typology"> Entity Registry</label></div>-->
<!--<div class="uk-margin-small-bottom"><label><input class="uk-radio" type="radio" value="Institutional" (change)="handleChangeAndResetPage()" formControlName="typology"> Institutional</label></div>-->
<!--<div class="uk-margin-small-bottom"><label><input class="uk-radio" type="radio" value="Thematic" (change)="handleChangeAndResetPage()" formControlName="typology"> Thematic</label></div>-->
<!--<div class="uk-margin-small-bottom"><label><input class="uk-radio" type="radio" value="Products" (change)="handleChangeAndResetPage()" formControlName="typology"> Products</label></div>-->
<!--<div class="uk-margin-small-bottom"><label><input class="uk-radio" type="radio" value="Unknown" (change)="handleChangeAndResetPage()" formControlName="typology"> Unknown</label></div>-->
<!--</div>-->
<!--</div>-->
<!--<hr>-->
<!--<div class="uk-margin">-->
<!--<h5 class="">Countries</h5>-->
<!--<div class="uk-form-controls">-->
<!--<ng-container *ngIf="countries && countries.length>0">-->
<!--<read-more [maxHeight]="238">-->
<!--<div class="uk-margin-small-bottom"><input class="uk-radio" type="radio" value="" (change)="handleChangeAndResetPage()" formControlName="country"> Any</div>-->
<!--<ng-container *ngFor="let country of countries">-->
<!--<div class="uk-margin-small-bottom">-->
<!--<input class="uk-radio" type="radio" value="{{country.code}}"-->
<!--(change)="handleChangeAndResetPage()" formControlName="country"> {{country.name}}-->
<!--</div>-->
<!--</ng-container>-->
<!--</read-more>-->
<!--</ng-container>-->
<!--</div>-->
<!--</div>-->
<!--</form>-->
</div>
</div>
<confirmation-dialog #subscribeToEventsModal [title]="'Create subscription for'" [isModalShown]="isModalShown"
[confirmActionButton]="'Subscribe'" (emitObject)="subscribeToEvents($event)">
<div *ngIf="eventsPage">
<div *ngIf="modalErrorMessage" class="uk-alert uk-alert-danger">{{ modalErrorMessage }}</div>
<div>
<h2 class="heading_c uk-margin-bottom">
{{ eventsPage.datasource }}
<span class="sub-heading">{{ eventsPage.topic }}</span>
</h2>
</div>
<div>
<div class="md-input-wrapper md-input-filled uk-margin-bottom">
<label>Email</label>
<input class="md-input label-fixed" type="text" value="{{ userEmail }}" disabled>
<span class="md-input-bar "></span>
</div>
<!--<div class="form-group">-->
<!--<label class="control-label">Email</label>-->
<!--<div>{{ userEmail }}</div>-->
<!--</div>-->
<!-- <div class="md-input-wrapper md-input-filled">
<label class="">Frequency (*)</label>
<select class="md-input" #selectFreq (change)="choseFrequency(selectFreq.value)">
<option value="">&#45;&#45; none selected &#45;&#45;</option>
<option value="never">never</option>
<option value="realtime">realtime</option>
<option value="daily">daily</option>
<option value="weekly">weekly</option>
<option value="monthly">monthly</option>
</select>
<span class="md-input-bar"></span>
</div>-->
<div class="uk-margin-top">
<div class="uk-margin-small-bottom">Selected Options</div>
<div>
<table class="uk-table uk-table-striped">
<tbody>
<tr>
<td class="uk-width-1-5">Trust</td>
<td>[{{advanceSearch.trust.min}}, {{advanceSearch.trust.max}}]</td>
</tr>
<tr *ngIf="advanceSearch.titles && advanceSearch.titles.length>0">
<td class="uk-width-1-5">Titles</td>
<td>
<span *ngFor="let title of advanceSearch.titles; let i = index">
<br *ngIf="i>0">
{{title}}
</span>
</td>
</tr>
<tr *ngIf="advanceSearch.authors && advanceSearch.authors.length>0">
<td class="uk-width-1-5">Authors</td>
<td>
<span *ngFor="let author of advanceSearch.authors; let i = index">
<br *ngIf="i>0">
{{author}}
</span>
</td>
</tr>
<tr *ngIf="advanceSearch.subjects && advanceSearch.subjects.length>0">
<td class="uk-width-1-5">Subjects</td>
<td>
<span *ngFor="let subject of advanceSearch.subjects; let i = index">
<br *ngIf="i>0">
{{subject}}
</span>
</td>
</tr>
<tr *ngIf="advanceSearch.dates && advanceSearch.dates.length>0">
<td class="uk-width-1-5">Dates</td>
<td>
<span *ngFor="let date of advanceSearch.dates; let i = index">
<br *ngIf="i>0">
{{date.min}} <span class="uk-margin-small-left uk-margin-small-right">-</span> {{date.max}}
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</confirmation-dialog>

View File

@ -0,0 +1,381 @@
import { Component, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { AdvQueryObject, EventsPage, NotificationFrequency, NotificationMode } from '../../../domain/typeScriptClasses';
import { BrokerService } from '../../../services/broker.service';
import { loadingEvents, noEventsForTopic, noEventsWithParams, noServiceMessage,
subscribingChooseFrequency, subscribingToEvents, subscribingToEventsError,
subscribingToeventsSuccess } from '../../../domain/shared-messages';
import { AbstractControl, FormArray, FormBuilder, FormGroup } from '@angular/forms';
import { AuthenticationService } from '../../../services/authentication.service';
import { ConfirmationDialogComponent } from '../../../shared/reusablecomponents/confirmation-dialog.component';
import { SharedService } from "../../../services/shared.service";
@Component ({
selector: 'app-content-events-of-repo-eventslist',
templateUrl: 'content-events-of-repo-eventslist.component.html'
})
export class ContentEventsOfRepoEventslistComponent implements OnInit {
errorMessage: string;
loadingMessage: string;
successMessage: string;
noEvents: string;
eventsPageInitialized = false;
topic = '';
lastTopicEntry = '';
correctTopic = '';
repoName = '';
advanceSearch: AdvQueryObject;
eventsPage: EventsPage;
currentPage: number; /* DELETE WHEN ADVANCED SHOW EVENTS IS FIXED AND SENDS CORRECT VALUE FOR CURRENT PAGE */
selectedItemIndex: number;
group: FormGroup;
readonly titleDefinition = { eventTitle: [''] };
readonly authorDefinition = { eventAuthor: [''] };
readonly subjectDefinition = { eventSubject: [''] };
readonly dateRangeDefinition = { dateFrom: '', dateTo: '' };
readonly groupDefinition = {
trustMin: [+''],
trustMax: [+''],
eventTitles: this.fb.array([this.initControl(this.titleDefinition)]),
eventAuthors: this.fb.array([this.initControl(this.authorDefinition)]),
eventSubjects: this.fb.array([this.initControl(this.subjectDefinition)]),
eventDateRanges: this.fb.array([this.initControl(this.dateRangeDefinition)])
};
eventTitleFormArray: any;
eventAuthorFormArray: any;
eventSubjectsFormArray: any;
eventDateRangesFormArray: any;
frequencyChoice = 'daily';
userEmail: string;
modalErrorMessage: string;
isModalShown: boolean;
@ViewChild('subscribeToEventsModal')
public subscribeToEventsModal: ConfirmationDialogComponent;
constructor (private route: ActivatedRoute,
private fb: FormBuilder,
private brokerService: BrokerService,
private authService: AuthenticationService,
private sharedService: SharedService) {}
ngOnInit () {
this.userEmail = this.authService.getUserEmail();
this.getParams();
if(this.sharedService.getRepository()) {
this.repoName = this.sharedService.getRepository().officialName;
this.initQuery();
this.initForm();
this.currentPage = 0; /* DELETE WHEN ADVANCED SHOW EVENTS IS FIXED AND SENDS CORRECT VALUE FOR CURRENT PAGE */
this.getEventsPage(0);
}
this.sharedService.repository$.subscribe(
r => {
if (r) {
this.repoName = r.officialName;
this.initQuery();
this.initForm();
this.currentPage = 0; /* DELETE WHEN ADVANCED SHOW EVENTS IS FIXED AND SENDS CORRECT VALUE FOR CURRENT PAGE */
this.getEventsPage(0);
}
}
);
let body = document.getElementsByTagName('body')[0];
body.classList.remove("top_bar_active"); //remove the class
body.classList.add("page_heading_active");
body.classList.remove("landing");
body.classList.add("dashboard");
}
getParams() {
this.topic = this.route.snapshot.paramMap.get('topic');
console.log(`my topic is: ${this.topic}`);
this.lastTopicEntry = this.topic.substring(this.topic.lastIndexOf('|') + 1).toLowerCase();
this.lastTopicEntry = this.replaceAll(this.lastTopicEntry, '_', ' ');
this.getCorrectTopic();
// this.repoName = this.route.snapshot.paramMap.get('name');
}
replaceAll(str, find, replace) {
return str.replace(new RegExp(find, 'g'), replace);
}
initQuery() {
this.advanceSearch = {
datasource: this.repoName,
topic: this.correctTopic,
titles: [],
subjects: [],
authors: [],
dates: [],
trust: {min: '0', max: '1'},
page: 0
};
}
initForm() {
this.group = this.fb.group( this.groupDefinition, { validator: checkMinMax } );
this.group.get('trustMin').setValue(0);
this.group.get('trustMax').setValue(1);
}
initControl(definition: any) {
return this.fb.group(definition);
}
removeControl(controlName: string, i: number) {
const controlArray = <FormArray>this.group.controls[controlName];
controlArray.removeAt(i);
}
addControl(controlName: string, definition: any) {
const controlArray = <FormArray>this.group.controls[controlName];
controlArray.push(this.initControl(definition));
}
clearForm() {
let controlArray: FormArray;
controlArray = <FormArray>this.group.controls['eventTitles'];
controlArray.controls = [];
controlArray.push(this.initControl(this.titleDefinition));
controlArray = <FormArray>this.group.controls['eventAuthors'];
controlArray.controls = [];
controlArray.push(this.initControl(this.authorDefinition));
controlArray = <FormArray>this.group.controls['eventSubjects'];
controlArray.controls = [];
controlArray.push(this.initControl(this.subjectDefinition));
controlArray = <FormArray>this.group.controls['eventDateRanges'];
controlArray.controls = [];
controlArray.push(this.initControl(this.dateRangeDefinition));
this.group.get('trustMin').setValue(0);
this.group.get('trustMax').setValue(1);
this.initQuery();
this.getEventsPage(0);
}
updateQuery() {
let i: number;
let controlArray: FormArray;
if ( this.group.valid ) {
this.initQuery();
this.advanceSearch.trust.min = this.group.get('trustMin').value;
this.advanceSearch.trust.max = this.group.get('trustMax').value;
controlArray = <FormArray>this.group.controls['eventTitles'];
for (i = 0; i < controlArray.length; i++) {
if (controlArray.at(i).get('eventTitle').value) {
this.advanceSearch.titles.push(controlArray.at(i).get('eventTitle').value);
}
}
controlArray = <FormArray>this.group.controls['eventAuthors'];
for (i = 0; i < controlArray.length; i++) {
if (controlArray.at(i).get('eventAuthor').value) {
this.advanceSearch.authors.push(controlArray.at(i).get('eventAuthor').value);
}
}
controlArray = <FormArray>this.group.controls['eventSubjects'];
for (i = 0; i < controlArray.length; i++) {
if (controlArray.at(i).get('eventSubject').value) {
this.advanceSearch.subjects.push(controlArray.at(i).get('eventSubject').value);
}
}
controlArray = <FormArray>this.group.controls['eventDateRanges'];
for (i = 0; i < controlArray.length; i++) {
if (controlArray.at(i).get('dateFrom').value) {
let toDate;
if (controlArray.at(i).get('dateTo').value ||
(controlArray.at(i).get('dateFrom').value > controlArray.at(i).get('dateTo').value) ) {
toDate = controlArray.at(i).get('dateTo').value;
} else {
toDate = Date.now();
}
this.advanceSearch.dates.push({
min: controlArray.at(i).get('dateFrom').value,
max: toDate
});
}
}
console.log(this.advanceSearch);
this.currentPage = 0; /* DELETE WHEN ADVANCED SHOW EVENTS IS FIXED AND SENDS CORRECT VALUE FOR CURRENT PAGE */
this.getEventsPage(0);
}
}
getEventsPage(page: number) {
this.noEvents = '';
this.errorMessage = '';
this.successMessage = '';
this.loadingMessage = loadingEvents;
this.brokerService.advancedShowEvents(page, 10, this.advanceSearch).subscribe(
events => this.eventsPage = events,
error => {
this.loadingMessage = '';
this.errorMessage = noServiceMessage;
console.log(error);
},
() => {
this.loadingMessage = '';
console.log(this.eventsPage);
if (!this.eventsPage.total) {
if (!this.eventsPageInitialized) {
this.noEvents = noEventsForTopic;
} else {
this.noEvents = noEventsWithParams;
}
}
let tempArray = <FormArray>this.group.controls['eventTitles'];
this.eventTitleFormArray = tempArray.controls;
tempArray = <FormArray>this.group.controls['eventAuthors'];
this.eventAuthorFormArray = tempArray.controls;
tempArray = <FormArray>this.group.controls['eventSubjects'];
this.eventSubjectsFormArray = tempArray.controls;
tempArray = <FormArray>this.group.controls['eventDateRanges'];
this.eventDateRangesFormArray = tempArray.controls;
console.log(`total pages is ${this.eventsPage.totalPages}`);
this.eventsPageInitialized = true;
}
);
}
isHighlighted(item: any, itemList: any[]) {
return itemList.some(x => x === item);
}
getCorrectTopic() {
const temp = this.topic.split('|');
this.correctTopic = temp[0];
this.topic = temp[0];
for (let i = 1; i < temp.length; i++) {
this.correctTopic += `/${temp[i]}`;
this.topic += ` | ${temp[i]}`;
}
}
goToNextPage() {
/* RESTORE WHEN ADVANCED SHOW EVENTS IS FIXED AND SENDS CORRECT VALUE FOR CURRENT PAGE */
/*if(this.eventsPage.currPage < this.eventsPage.totalPages) {
console.log(`Get me page ${this.eventsPage.currPage+1}!`);
this.getEventsPage(this.eventsPage.currPage+1);
}*/
/* DELETE WHEN ADVANCED SHOW EVENTS IS FIXED AND SENDS CORRECT VALUE FOR CURRENT PAGE */
if ( (this.currentPage + 1) < this.eventsPage.totalPages) {
this.currentPage = this.currentPage + 1;
console.log(`Get me page ${this.currentPage}!`);
this.getEventsPage(this.currentPage);
window.scrollTo(0, 0);
}
}
goToPreviousPage() {
/* RESTORE WHEN ADVANCED SHOW EVENTS IS FIXED AND SENDS CORRECT VALUE FOR CURRENT PAGE */
/*if(this.eventsPage.currPage > 0) {
console.log(`Get me page ${this.eventsPage.currPage-1}!`);
this.getEventsPage(this.eventsPage.currPage-1);
}*/
/* DELETE WHEN ADVANCED SHOW EVENTS IS FIXED AND SENDS CORRECT VALUE FOR CURRENT PAGE */
if (this.currentPage > 0) {
this.currentPage = this.currentPage - 1;
console.log(`Get me page ${this.currentPage}!`);
this.getEventsPage(this.currentPage);
window.scrollTo(0, 0);
}
}
showSubscriptionModal() {
if (this.advanceSearch && this.eventsPage) {
this.subscribeToEventsModal.confirmed = false;
this.subscribeToEventsModal.showModal();
}
}
choseFrequency(freq: string) {
this.frequencyChoice = freq;
}
subscribeToEvents(event: any) {
this.modalErrorMessage = '';
if (this.frequencyChoice) {
this.subscribeToEventsModal.confirmed = true;
const freq = <NotificationFrequency>this.frequencyChoice;
const mod: NotificationMode = 'EMAIL';
const sub = {
subscriber: this.userEmail,
frequency: freq,
mode: mod,
query: this.advanceSearch
};
this.errorMessage = '';
this.successMessage = '';
console.log(JSON.stringify(sub));
this.loadingMessage = subscribingToEvents;
this.brokerService.subscribeToEvent(sub).subscribe(
response => console.log(`subscribeToEvents responded ${JSON.stringify(response)}`),
error => {
this.errorMessage = subscribingToEventsError;
this.loadingMessage = '';
},
() => {
this.loadingMessage = '';
this.successMessage = subscribingToeventsSuccess;
}
);
} else {
this.modalErrorMessage = subscribingChooseFrequency;
}
}
// displayFullResultInfo(i: number) {
// if (this.selectedItemIndex === i) {
// this.selectedItemIndex = null;
// } else {
// this.selectedItemIndex = i;
// }
// }
showMore(i: number) {
this.selectedItemIndex = i;
}
showLess(i: number) {
this.selectedItemIndex = null;
}
}
export function checkMinMax(c: AbstractControl) {
if ( c.get('trustMin').value > c.get('trustMax').value ) {
return 'invalid';
}
return null;
}
export function checkDates(c: AbstractControl) {
if ( c.get('dateFrom').value > c.get('dateTo').value ) {
return 'invalid';
}
return null;
}

View File

@ -0,0 +1,140 @@
<div id="page_content_inner" class="uk-margin-medium-left uk-margin-medium-right uk-margin-top">
<h2 class="heading_b uk-margin-bottom">Enrich Your Content - Browse Events</h2>
<!-- TOP HELP CONTENT -->
<help-content #topHelperContent [position]="'top'"
[ngClass]="topHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
<div class="uk-grid">
<!-- LEFT HELP CONTENT -->
<aside-help-content #leftHelperContent [position]="'left'"
[ngClass]="leftHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
<!-- MIDDLE -->
<div class=" uk-width-expand@m">
<div>
<div *ngIf="errorMessage" class="uk-alert uk-alert-danger">{{errorMessage}}</div>
<div *ngIf="loadingMessage" class="loading-big">
<div class="loader-big" style="text-align: center; padding-top: 170px; color: rgb(47, 64, 80); font-weight: bold;">{{ loadingMessage }}</div>
<div class="transparentFilm"></div>
</div>
<div *ngIf="noTopics" class="uk-alert">{{ noTopics }}</div>
<ng-container *ngIf="repoTopics && repoTopics.length > 0">
<div class="uk-alert uk-alert-info">
For each topic a sample of 100 events will be displayed, as well as the total number that can be potentially built for your data source. If you are interested to receive the full list, you can subscribe to these events and then be notified about the new enrichment events.
</div>
<div class="uk-grid-margin uk-grid uk-grid-stack repos-list">
<div class="uk-width-1-2 uk-first-column">
<div class="md-card">
<div class="md-card-toolbar">
<!--<div class="md-card-toolbar-actions">-->
<!--<a href="#" class="md-btn md-btn-small md-btn-flat">Button</a>-->
<!--<a href="#" class="md-btn md-btn-small md-btn-flat md-btn-flat-primary">Button</a>-->
<!--</div>-->
<h3 class="md-card-toolbar-heading-text">
More
</h3>
</div>
<div class="md-card-content">
<table class="uk-table uk-table-striped uk-table-middle">
<thead>
<tr>
<th>Additional metadata information that may enrich or supplement {{ repoName }} content</th>
<th class="uk-text-nowrap uk-text-right"># of events</th>
</tr>
</thead>
<tbody>
<tr class="el-item" *ngFor="let moreTopic of moreList">
<td class="uk-table-shrink uk-width-4-5">
<a (click)="goToEventsList(moreTopic.value)" class="el-link">{{ moreTopic.value }}</a>
<div *ngIf="topics[moreTopic.value]" class="uk-text uk-text-small">{{ topics[moreTopic.value]['englishName'] }}</div>
</td>
<td class="uk-text-nowrap uk-table-shrink uk-width-1-5 uk-text-right">
<div class="el-title">{{ moreTopic.size }}</div>
</td>
</tr>
<tr class="el-item uk-text-bold">
<td class="uk-text-nowrap uk-table-shrink uk-width-4-5">
<div class="el-title">Total</div>
</td>
<td class="uk-text-nowrap uk-table-shrink uk-width-1-5 uk-text-right">
<div class="el-title">{{ totalMore }}</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="uk-width-1-2 uk-first-column">
<div class="md-card">
<div class="md-card-toolbar">
<!--<div class="md-card-toolbar-actions">-->
<!--<a href="#" class="md-btn md-btn-small md-btn-flat">Button</a>-->
<!--<a href="#" class="md-btn md-btn-small md-btn-flat md-btn-flat-primary">Button</a>-->
<!--</div>-->
<h3 class="md-card-toolbar-heading-text">
Missing
</h3>
</div>
<div class="md-card-content">
<table class="uk-table uk-table-striped uk-table-middle">
<thead>
<tr>
<th>Missing metadata information that may enrich or complete {{ repoName }} content</th>
<th class="uk-text-nowrap uk-text-right"># of events</th>
</tr>
</thead>
<tbody>
<tr class="el-item" *ngFor="let missingTopic of missingList">
<td class="uk-table-shrink uk-width-4-5">
<a (click)="goToEventsList(missingTopic.value)" class="el-link">{{ missingTopic.value }}</a>
<div *ngIf="topics[missingTopic.value]" class="uk-text uk-text-small">{{ topics[missingTopic.value]['englishName'] }}</div>
</td>
<td class="uk-text-nowrap uk-table-shrink uk-width-1-5">
<div class="el-title uk-text-right">{{ missingTopic.size }}</div>
</td>
</tr>
<tr class="el-item uk-text-bold">
<td class="uk-text-nowrap uk-table-shrink uk-width-4-5">
<div class="el-title">Total</div>
</td>
<td class="uk-text-nowrap uk-table-shrink uk-width-1-5">
<div class="el-title uk-text-right">{{ totalMissing }}</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</ng-container>
</div>
</div>
<!-- RIGHT HELP CONTENT -->
<aside-help-content #rightHelperContent [position]="'right'"
[ngClass]="rightHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
</div>
<!-- BOTTOM HELP CONTENT -->
<help-content #bottomHelperContent [position]="'bottom'"
[ngClass]="bottomHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
</div>

View File

@ -0,0 +1,134 @@
import { Component, OnInit } from '@angular/core';
import { BrowseEntry, Term } from '../../../domain/typeScriptClasses';
import { ActivatedRoute, Router } from '@angular/router';
import { loadingTopics, loadingTopicsError, noTopicsFound } from '../../../domain/shared-messages';
import { BrokerService } from '../../../services/broker.service';
import { SharedService } from "../../../services/shared.service";
@Component ({
selector: 'content-events-of-repository',
templateUrl: 'content-events-of-repository.component.html'
})
export class ContentEventsOfRepositoryComponent implements OnInit {
errorMessage: string;
loadingMessage: string;
noTopics: string;
repoName = '';
correctName = '';
topics: Map<string, Term> = new Map<string, Term>();
repoTopics: BrowseEntry[] = [];
moreList: BrowseEntry[] = [];
missingList: BrowseEntry[] = [];
totalMore = 0;
totalMissing = 0;
constructor(
private route: ActivatedRoute,
private router: Router,
private brokerService: BrokerService,
private sharedService: SharedService
) {}
ngOnInit() {
if(this.sharedService.getRepository()) {
this.repoName = this.sharedService.getRepository().officialName;
this.getCorrectName();
this.getTopics();
}
this.sharedService.repository$.subscribe(
r => {
if (r) {
this.repoName = r.officialName;
this.getCorrectName();
this.getTopics();
}
}
);
// this.repoName = this.route.snapshot.paramMap.get('name');
// this.getCorrectName();
// this.getTopics();
let body = document.getElementsByTagName('body')[0];
body.classList.remove("top_bar_active"); //remove the class
body.classList.remove("page_heading_active");
body.classList.remove("landing");
body.classList.add("dashboard");
}
getRepoTopics(): void {
this.loadingMessage = loadingTopics;
this.brokerService.getTopicsForDataSource(this.correctName)
.subscribe(
topics => {
this.repoTopics = topics;
},
error => {
console.log(error);
this.errorMessage = loadingTopicsError;
this.loadingMessage = '';
},
() => {
this.loadingMessage = '';
if (this.repoTopics.length === 0) {
this.noTopics = noTopicsFound;
} else {
for (const browseEntry of this.repoTopics) {
if (browseEntry.value.startsWith('ENRICH/MORE')) {
this.totalMore += browseEntry.size;
this.moreList.push(browseEntry);
} else if (browseEntry.value.startsWith('ENRICH/MISSING')) {
this.totalMissing += browseEntry.size;
this.missingList.push(browseEntry);
}
}
}
}
);
}
getTopics () {
this.loadingMessage = loadingTopics;
this.brokerService.getDnetTopics().subscribe(
topics => this.topics = topics,
error => {
console.log(error);
this.errorMessage = loadingTopicsError;
this.loadingMessage = '';
},
() => {
this.loadingMessage = '';
console.log(this.topics);
this.getRepoTopics();
}
);
}
goToEventsList(topic: string) {
const temp = topic.replace(/\//g, '|');
let chosenTopic = temp[0];
for (let i = 1; i < temp.length; i++) {
chosenTopic += '|' + temp[i];
}
chosenTopic = encodeURIComponent(chosenTopic);
/*this.router.navigate([`/content/events/${this.repoName}`, chosenTopic]);*/
console.log(temp, this.route.url);
this.router.navigate([temp], {relativeTo: this.route});
}
getCorrectName() {
const temp = this.repoName.split('|');
this.correctName = temp[0];
this.repoName = temp[0];
for (let i = 1; i < temp.length; i++) {
this.correctName += `/${temp[i]}`;
this.repoName += ` | ${temp[i]}`;
}
}
}

View File

@ -0,0 +1,27 @@
import { RouterModule, Routes } from '@angular/router';
import { NgModule } from '@angular/core';
import { AuthGuardService } from "../../../services/auth-guard.service";
import { ContentEventsOfRepositoryComponent } from "./content-events-of-repository.component";
import { ContentEventsOfRepoEventslistComponent } from "./content-events-of-repo-eventslist.component";
const eventsRoutes: Routes = [
{
path: '',
component: ContentEventsOfRepositoryComponent,
canActivate: [AuthGuardService],
},
{
path: ':topic',
component: ContentEventsOfRepoEventslistComponent,
canActivate: [AuthGuardService]
}
];
@NgModule ({
imports: [RouterModule.forChild(eventsRoutes)],
exports: [RouterModule]
})
export class EventsRoutingModule {}

View File

@ -0,0 +1,25 @@
import { NgModule } from '@angular/core';
import { TabsModule } from 'ngx-bootstrap';
import { CommonModule } from '@angular/common';
import { ReusableComponentsModule } from "../../../shared/reusablecomponents/reusable-components.module";
import { EventsRoutingModule } from "./events-routing.module";
import { ContentEventsOfRepositoryComponent } from "./content-events-of-repository.component";
import { ContentEventsOfRepoEventslistComponent } from "./content-events-of-repo-eventslist.component";
import { ReactiveFormsModule } from "@angular/forms";
@NgModule ({
imports: [
CommonModule,
TabsModule.forRoot(),
EventsRoutingModule,
ReusableComponentsModule,
ReactiveFormsModule,
],
declarations: [
ContentEventsOfRepositoryComponent,
ContentEventsOfRepoEventslistComponent
]
})
export class EventsModule { }

View File

@ -0,0 +1,91 @@
<div id="page_content_inner">
<!--<h2 class="heading_b uk-margin-bottom">Metrics for repository....</h2>-->
<h2 *ngIf="repo" class="heading_b uk-margin-bottom">Metrics for {{repo.officialName}}</h2>
<!-- TOP HELP CONTENT -->
<help-content #topHelperContent [position]="'top'"
[ngClass]="topHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
<div class="uk-grid">
<!-- LEFT HELP CONTENT -->
<aside-help-content #leftHelperContent [position]="'left'"
[ngClass]="leftHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
<!-- MIDDLE -->
<div class=" uk-width-expand@m">
<div>
<div *ngIf="successMessage" class="uk-alert uk-alert-success">{{ successMessage }}</div>
<div *ngIf="errorMessage" class="uk-alert uk-alert-danger">{{ errorMessage }}</div>
<div *ngIf="loadingMessage" class="loading-big">
<div class="loader-big" style="text-align: center; padding-top: 170px; color: rgb(47, 64, 80); font-weight: bold;">
{{ loadingMessage }}
</div>
<div class="transparentFilm"></div>
</div>
<div *ngIf="repo && !loadingMessage">
<div class="md-card">
<div class="md-card-content large-padding">
<div class="uk-article">
<p class="uk-article-lead uk-margin-bottom">You don't have metrics enabled for this repository yet. Would you like to enable them?</p>
<div class="uk-grid uk-margin-medium-top uk-margin-medium-bottom">
<figure class="uk-width-1-3 uk-first-column">
<img src="../../../../assets/imgs/metricsWorkflow-new.svg" alt="" data-dense-cap="2" class="dense-image dense-ready">
<figcaption class="uk-thumbnail-caption">Usage stats enable workflow</figcaption>
</figure>
<div class="info uk-width-2-3">
<p>Once you select to enable metrics for your repository, the following actions need to be performed:</p>
<p><i>As the repository manager, on datasource site:</i><br>
1. Download the tracking code for your datasource platform.<br>
2. Follow the instructions to configure the tracking code.<br>
3. Deploy the tracking code into your datasource platform.
</p>
<p><i>As OpenAIRE's Usage Counts Technical Staff, on our data analytics platform:</i><br>
4. Validate the installation and inform you accordingly.<br>
</p>
</div>
</div>
<blockquote>
For more details about the workflows, please consult the
<a href="https://openaire.github.io/usage-statistics-guidelines/">OpenAIRE Usage Counts Guidelines</a>.<br>
If you have any questions, please create a <a href="https://www.openaire.eu/support/helpdesk">helpdesk ticket</a> or write to <a href="mailto:usagecounts-helpdesk@openaire.eu">usagecounts-helpdesk@openaire.eu</a>.
</blockquote>
<button class="uk-button uk-button-primary uk-margin-top" (click)="confirmEnabling()">Enable Metrics</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- RIGHT HELP CONTENT -->
<aside-help-content #rightHelperContent [position]="'right'"
[ngClass]="rightHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
</div>
<!-- BOTTOM HELP CONTENT -->
<help-content #bottomHelperContent [position]="'bottom'"
[ngClass]="bottomHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
</div>
<confirmation-dialog #confirmEnablingModal [title]="modalTitle" [isModalShown]="isModalShown"
[confirmActionButton]="modalButton" (emitObject)="confirmedEnabling($event)">
Are you sure you want to enable metrics for this repository?
</confirmation-dialog>

View File

@ -0,0 +1,146 @@
import { Component, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { ConfirmationDialogComponent } from '../../../shared/reusablecomponents/confirmation-dialog.component';
import { PiwikService } from '../../../services/piwik.service';
import { RepositoryService } from '../../../services/repository.service';
import { PiwikInfo, Repository } from '../../../domain/typeScriptClasses';
import { enabledMetricsError, enabledMetricsSuccess, enablingMetrics,
loadingRepoError, loadingRepoMessage } from '../../../domain/shared-messages';
import { AuthenticationService } from '../../../services/authentication.service';
import { SharedService } from "../../../services/shared.service";
@Component ({
selector: 'metrics-enable',
templateUrl: 'metrics-enable.component.html'
})
export class MetricsEnableComponent implements OnInit {
successMessage: string;
errorMessage: string;
loadingMessage: string;
readonly analyticsUrl = 'https://analytics.openaire.eu/addsite.php?';
readonly authenticationToken = '32846584f571be9b57488bf4088f30ea'; /* THE ACTUAL TOKEN WILL BE NEEDED EVENTUALLY!! */
repo: Repository;
oaId: string;
modalTitle = 'Confirmation';
modalButton = 'Yes, enable it';
isModalShown: boolean;
@ViewChild('confirmEnablingModal')
public confirmEnablingModal: ConfirmationDialogComponent;
constructor (
private route: ActivatedRoute,
private router: Router,
private authService: AuthenticationService,
private piwikService: PiwikService,
private repoService: RepositoryService,
private sharedService: SharedService
) {}
ngOnInit() {
if(this.sharedService.getRepository()) {
this.repo = this.sharedService.getRepository();
this.getOAid();
}
this.sharedService.repository$.subscribe(
r => {
this.repo = r;
if (this.repo) {
this.getOAid();
}
}
);
// this.getRepo();
this.isModalShown = false;
let body = document.getElementsByTagName('body')[0];
body.classList.remove("top_bar_active"); //remove the class
body.classList.remove("page_heading_active");
body.classList.remove("landing");
body.classList.add("dashboard");
}
// getRepo(): void {
// const id = this.route.snapshot.paramMap.get('id');
// this.loadingMessage = loadingRepoMessage;
// this.repoService.getRepositoryById(id).subscribe(
// repo => {
// this.repo = repo;
// },
// error => {
// console.log(error);
// this.errorMessage = loadingRepoError;
// this.loadingMessage = '';
// }, () => {
// if (this.repo) {
// this.getOAid();
// }
// this.loadingMessage = '';
// }
// );
// }
getOAid () {
this.piwikService.getOpenaireId(this.repo.id).subscribe(
id => {
this.oaId = id;
console.log(`getOpenaireId responded: ${this.oaId}`);
},
error => console.log(`ERROR is ${error}`)
);
}
confirmEnabling() {
if (this.repo) {
this.confirmEnablingModal.showModal();
}
}
confirmedEnabling(event: any) {
if (this.repo) {
this.loadingMessage = enablingMetrics;
const piwik: PiwikInfo = {
repositoryId: this.repo.id,
openaireId: this.oaId,
repositoryName: this.repo.officialName,
country: this.repo.countryName,
siteId: '',
authenticationToken: this.authenticationToken,
creationDate: null,
requestorName: this.authService.getUserName(),
requestorEmail: this.authService.getUserEmail(),
validated: false,
validationDate: null,
comment: ''
};
this.piwikService.enableMetricsForRepository(this.repo.officialName, this.repo.websiteUrl, piwik).subscribe(
response => {
console.log(`enableMetrics answered: ${response}`);
this.successMessage = enabledMetricsSuccess;
this.loadingMessage = '';
//save piwik and update shareRepo
this.repo.piwikInfo = piwik;
this.sharedService.setRepository(this.repo);
},
error => {
console.log(error);
this.errorMessage = enabledMetricsError;
this.loadingMessage = '';
},
() => {
this.router.navigate([`../instructions/`]);
// this.router.navigate([`/getImpact/instructions/${this.repo.id}`]);
}
);
}
}
}

View File

@ -0,0 +1,80 @@
<div id="page_content_inner">
<h2 *ngIf="piwik" class="heading_b uk-margin-bottom">Usage Statistics Configuration & Software Details for {{piwik.repositoryName}}</h2>
<!-- TOP HELP CONTENT -->
<help-content #topHelperContent [position]="'top'"
[ngClass]="topHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
<div class="uk-grid">
<!-- LEFT HELP CONTENT -->
<aside-help-content #leftHelperContent [position]="'left'"
[ngClass]="leftHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
<!-- MIDDLE -->
<div class=" uk-width-expand@m">
<div *ngIf="errorMessage" class="uk-alert uk-alert-danger">{{ errorMessage }}</div>
<div *ngIf="piwik">
<div class="md-card">
<div class="md-card-content large-padding">
<div class="uk-article">
<p>
OpenAIREs usage statistic service uses the <i>Matomo Open Source Analytics platform</i> (matomo.org) to track usage activity. When <i>metrics</i>
are enabled for a repository, two unique identifiers are generated - a matomo-ID that associates the repository with its usage events in Matomo
and an authentication-ID that allows to track usage activity on the Matomo platform. Metadata views and item downloads are tracked and automatically sent to Matomo. Statistics are generated using the COUNTER Code of practice directives.
</p>
<p>
OpenAIRE's usage statistics service tracking code exploits Matomos API. In order to make the tracking of usage events from repositories more robust, it was necessary to implement repository platform specific patches and plugins starting with DSpace and EPrints. The code is maintained on Github:
</p>
<ul>
<li>as a patch for various versions of DSpace
(<a target="_blank" href="https://github.com/openaire/OpenAIRE-Piwik-DSpace">https://github.com/openaire/OpenAIRE-Piwik-DSpace</a>)</li>
<li>as an Eprints plugin for version 3
(<a target="_blank" href="https://github.com/openaire/EPrints-OAPiwik">https://github.com/openaire/EPrints-OAPiwik</a>)</li>
<li>as a python script for all other cases
(<a target="_blank" href="https://github.com/openaire/Generic-Matomo-Tracker">https://github.com/openaire/Generic-Matomo-Tracker</a>)</li>
</ul>
<p>
To configure your repository to allow tracking in Matomo platform, please change the configuration files with the following parameters and values, generated for your site:
</p>
<dl class="uk-description-list">
<dt>MatomoID</dt>
<dd>{{ piwik.siteId }}</dd>
<dt>AuthenticationToken</dt>
<dd>{{ piwik.authenticationToken }}</dd>
</dl>
<p>
Details for the configuration files are given in the README of the tracking code.
</p>
<div class="uk-alert uk-alert-info">
<strong>NOTE</strong>
- You will be informed by e-mail that the installation of the tracking code has been validated and when the usage statistics will be available.
</div>
</div>
</div>
</div>
</div>
</div>
<!-- RIGHT HELP CONTENT -->
<aside-help-content #rightHelperContent [position]="'right'"
[ngClass]="rightHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
</div>
<!-- BOTTOM HELP CONTENT -->
<help-content #bottomHelperContent [position]="'bottom'"
[ngClass]="bottomHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
</div>

View File

@ -0,0 +1,45 @@
/**
* Created by myrto on 11/24/17.
*/
import { Component, OnInit } from '@angular/core';
import { PiwikInfo, Repository } from '../../../domain/typeScriptClasses';
import { ActivatedRoute, Router } from '@angular/router';
import { PiwikService } from '../../../services/piwik.service';
import { AuthenticationService } from '../../../services/authentication.service';
import { SharedService } from "../../../services/shared.service";
@Component ({
selector: 'app-metrics-instructions',
templateUrl: 'metrics-instructions.component.html'
})
export class MetricsInstructionsComponent implements OnInit {
piwik: PiwikInfo;
errorMessage: string;
constructor(
private route: ActivatedRoute,
private router: Router,
private piwikService: PiwikService,
private authService: AuthenticationService,
private sharedService: SharedService) {}
ngOnInit() {
if(this.sharedService.getRepository())
this.piwik = this.sharedService.getRepository().piwikInfo;
this.sharedService.repository$.subscribe(
r => {
this.piwik = r.piwikInfo;
}
);
let body = document.getElementsByTagName('body')[0];
body.classList.remove("top_bar_active"); //remove the class
body.classList.remove("page_heading_active");
body.classList.remove("landing");
body.classList.add("dashboard");
}
}

View File

@ -0,0 +1,102 @@
<div id="page_content_inner">
<h2 *ngIf="piwik" class="heading_b uk-margin-bottom">{{ piwik ? piwik.repositoryName : 'Metrics'}}</h2>
<!-- TOP HELP CONTENT -->
<help-content #topHelperContent [position]="'top'"
[ngClass]="topHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
<div class="uk-grid">
<!-- LEFT HELP CONTENT -->
<aside-help-content #leftHelperContent [position]="'left'"
[ngClass]="leftHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
<!-- MIDDLE -->
<div class=" uk-width-expand@m">
<div *ngIf="errorMessage" class="uk-alert uk-alert-danger">{{ errorMessage }}</div>
<div *ngIf="loadingMessage" class="loading-big">
<div class="loader-big" style="text-align: center; padding-top: 170px; color: rgb(47, 64, 80); font-weight: bold;">
{{ loadingMessage }}
</div>
<div class="transparentFilm"></div>
</div>
<div *ngIf="repoMetrics">
<div class="uk-grid">
<div class="uk-width-1-1">
<div class="uk-float-right">
<a class="uk-button uk-button-primary"
[routerLink]="['../usagestats']" title="">Get statistics report</a>
</div>
</div>
</div>
<div class="uk-grid uk-grid-match uk-child-width-1-3@l uk-child-width-1-3@m uk-grid-medium uk-sortable sortable-handler" data-uk-sortable="" data-uk-grid-margin="">
<div class="uk-row-first" style="">
<div class="md-card">
<div class="md-card-content">
<div class="uk-float-right uk-margin-top uk-margin-small-right"><span class="peity_sale peity_data" style="display: none;">5,3,9,6,5,9,7,3,5,2</span><svg class="peity" height="28" width="64"><polygon fill="#d1e4f6" points="0 27.5 0 12.5 7.111111111111111 18.5 14.222222222222221 0.5 21.333333333333332 9.5 28.444444444444443 12.5 35.55555555555556 0.5 42.666666666666664 6.5 49.77777777777777 18.5 56.888888888888886 12.5 64 21.5 64 27.5"></polygon><polyline fill="none" points="0 12.5 7.111111111111111 18.5 14.222222222222221 0.5 21.333333333333332 9.5 28.444444444444443 12.5 35.55555555555556 0.5 42.666666666666664 6.5 49.77777777777777 18.5 56.888888888888886 12.5 64 21.5" stroke="#0288d1" stroke-width="1" stroke-linecap="square"></polyline></svg></div>
<span class="uk-text-muted uk-text-small">views in OpenAIRE</span>
<h2 class="uk-margin-remove"><span class="countUpMe">{{ pageViews | number }}</span></h2>
</div>
</div>
</div>
<div style="">
<div class="md-card">
<div class="md-card-content">
<div class="uk-float-right uk-margin-top uk-margin-small-right"><span class="peity_live peity_data" style="display: none;">3,5,2,10,2,7,0,2,8,8,7,2,4,8,0,6,6,7,9,5</span><svg class="peity" height="28" width="64"><polygon fill="#efebe9" points="0 27.5 0 19.4 3.3684210526315788 14 6.7368421052631575 22.1 10.105263157894736 0.5 13.473684210526315 22.1 16.842105263157894 8.600000000000001 20.210526315789473 27.5 23.57894736842105 22.1 26.94736842105263 5.899999999999999 30.31578947368421 5.899999999999999 33.68421052631579 8.600000000000001 37.05263157894737 22.1 40.421052631578945 16.7 43.78947368421052 5.899999999999999 47.1578947368421 27.5 50.526315789473685 11.3 53.89473684210526 11.3 57.263157894736835 8.600000000000001 60.63157894736842 3.1999999999999993 64 14 64 27.5"></polygon><polyline fill="none" points="0 19.4 3.3684210526315788 14 6.7368421052631575 22.1 10.105263157894736 0.5 13.473684210526315 22.1 16.842105263157894 8.600000000000001 20.210526315789473 27.5 23.57894736842105 22.1 26.94736842105263 5.899999999999999 30.31578947368421 5.899999999999999 33.68421052631579 8.600000000000001 37.05263157894737 22.1 40.421052631578945 16.7 43.78947368421052 5.899999999999999 47.1578947368421 27.5 50.526315789473685 11.3 53.89473684210526 11.3 57.263157894736835 8.600000000000001 60.63157894736842 3.1999999999999993 64 14" stroke="#5d4037" stroke-width="1" stroke-linecap="square"></polyline></svg></div>
<span class="uk-text-muted uk-text-small">views in local repository</span>
<h2 class="uk-margin-remove" id="peity_live_text">{{ totalViews | number }}
<span *ngIf="repoMetrics.metricsNumbers.total_openaire_views" class="comment">( {{ repoMetrics.metricsNumbers.total_openaire_views | number }} from OpenAIRE )</span></h2>
</div>
</div>
</div>
<div class="" style="">
<div class="md-card">
<div class="md-card-content">
<div class="uk-float-right uk-margin-top uk-margin-small-right"><span class="peity_visitors peity_data" style="display: none;">5,3,9,6,5,9,7</span><svg class="peity" height="28" width="48"><rect data-value="5" fill="#d84315" x="1.3714285714285717" y="12.444444444444443" width="4.114285714285715" height="15.555555555555557"></rect><rect data-value="3" fill="#d84315" x="8.228571428571428" y="18.666666666666668" width="4.114285714285716" height="9.333333333333332"></rect><rect data-value="9" fill="#d84315" x="15.085714285714287" y="0" width="4.1142857142857086" height="28"></rect><rect data-value="6" fill="#d84315" x="21.942857142857147" y="9.333333333333336" width="4.114285714285707" height="18.666666666666664"></rect><rect data-value="5" fill="#d84315" x="28.800000000000004" y="12.444444444444443" width="4.114285714285707" height="15.555555555555557"></rect><rect data-value="9" fill="#d84315" x="35.65714285714286" y="0" width="4.114285714285707" height="28"></rect><rect data-value="7" fill="#d84315" x="42.51428571428572" y="6.222222222222221" width="4.114285714285707" height="21.77777777777778"></rect></svg></div>
<span class="uk-text-muted uk-text-small">downloads in local repository</span>
<h2 class="uk-margin-remove">{{ totalDownloads | number }}
<span *ngIf="repoMetrics.metricsNumbers.total_openaire_downloads" class="comment">( {{ repoMetrics.metricsNumbers.total_openaire_downloads | number }} from OpenAIRE )</span></h2>
</div>
</div>
</div>
</div>
<div class="uk-grid">
<div class="uk-width-1-1">
<div class="md-card">
<div class="md-card-content">
<iframe class="statsFrame" [src]="viewsUrl"></iframe>
</div>
</div>
</div>
<div class="uk-width-1-1 uk-margin-medium-top">
<div class="md-card">
<div class="md-card-content">
<iframe class="statsFrame" [src]="downloadsUrl"></iframe>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- RIGHT HELP CONTENT -->
<aside-help-content #rightHelperContent [position]="'right'"
[ngClass]="rightHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
</div>
<!-- BOTTOM HELP CONTENT -->
<help-content #bottomHelperContent [position]="'bottom'"
[ngClass]="bottomHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
</div>

View File

@ -0,0 +1,135 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { MetricsInfo, PiwikInfo } from '../../../domain/typeScriptClasses';
import { PiwikService } from '../../../services/piwik.service';
import { RepositoryService } from '../../../services/repository.service';
import { loadingMetrics, loadingMetricsError } from '../../../domain/shared-messages';
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
import { AuthenticationService } from '../../../services/authentication.service';
import { SharedService } from "../../../services/shared.service";
@Component ({
selector: 'metrics-show',
templateUrl: 'metrics-show.component.html'
})
export class MetricsShowComponent implements OnInit {
errorMessage: string;
loadingMessage: string;
repoId: string;
piwik: PiwikInfo;
repoMetrics: MetricsInfo;
pageViews = '--';
totalViews = '--';
totalDownloads = '--';
viewsUrl: SafeResourceUrl;
downloadsUrl: SafeResourceUrl;
constructor(
private route: ActivatedRoute,
private router: Router,
private sanitizer: DomSanitizer,
private piwikService: PiwikService,
private repoService: RepositoryService,
private authService: AuthenticationService,
private sharedService: SharedService) {}
ngOnInit() {
if(this.sharedService.getRepository()) {
this.repoId = this.sharedService.getRepository().id;
this.piwik = this.sharedService.getRepository().piwikInfo;
this.getMetrics();
}
this.sharedService.repository$.subscribe(
r => {
this.repoId = r.id;
this.piwik = r.piwikInfo;
this.getMetrics();
}
);
let body = document.getElementsByTagName('body')[0];
body.classList.remove("top_bar_active"); //remove the class
body.classList.remove("page_heading_active");
body.classList.remove("landing");
body.classList.add("dashboard");
}
getMetrics() {
this.loadingMessage = loadingMetrics;
this.repoService.getMetricsInfoForRepository(this.repoId).subscribe(
metrics => {
this.repoMetrics = metrics;
if (this.repoMetrics.metricsNumbers.pageviews) {
this.pageViews = this.repoMetrics.metricsNumbers.pageviews;
}
if (this.repoMetrics.metricsNumbers.total_views) {
this.totalViews = this.repoMetrics.metricsNumbers.total_views;
}
if (this.repoMetrics.metricsNumbers.total_downloads) {
this.totalDownloads = this.repoMetrics.metricsNumbers.total_downloads;
}
this.getViewsUrl();
this.getDownloadsUrl();
},
error => {
this.loadingMessage = '';
this.errorMessage = loadingMetricsError;
console.log(error);
},
() => {
this.loadingMessage = '';
this.errorMessage = '';
}
);
}
getViewsUrl () {
let encodedURL = encodeURIComponent('{"library":"HighCharts","chartDescription":{"queries":[{"name":"Monthly views","type":"line","query":{"name":"usagestats.views.monthly", "parameters":["' + this.piwik.openaireId + '"], "profile":"OpenAIRE All-inclusive" }}],"chart":{"backgroundColor":"#FFFFFFFF","borderColor":"#335cadff","borderRadius":0,"borderWidth":0,"plotBorderColor":"#ccccccff","plotBorderWidth":0},"title":{"text":""},"subtitle":{},"yAxis":{"title":{"text":"Monthly views"}},"xAxis":{"title":{}},"lang":{"noData":"No Data available for the Query"},"exporting":{"enabled":false},"plotOptions":{"series":{"dataLabels":{"enabled":false}}},"legend":{"enabled":false},"credits":{"href":null,"enabled":true,"text":"Created by OpenAIRE via HighCharts"}}}');
this.viewsUrl = this.sanitizer.bypassSecurityTrustResourceUrl(`${this.repoMetrics.diagramsBaseURL}chart?json=${encodedURL}`);
// this.viewsUrl = this.sanitizer.bypassSecurityTrustResourceUrl(
// `${this.repoMetrics.diagramsBaseURL}merge.php?com=query
// &data=[{"query":"dtsrcRepoViews","dtsrcName":"${this.piwik.openaireId}",
// "table":"","fields":[{"fld":"sum","agg":"sum","type":"chart","yaxis":1,"c":false}],
// "xaxis":{"name":"month","agg":"sum"},"group":"","color":"","type":"chart","size":30,
// "sort":"xaxis","xStyle":{"r":-30,"s":"0","l":"-","ft":"-","wt":"-"},"title":"","subtitle":"",
// "xaxistitle":"","yaxisheaders":["Monthly views"],"generalxaxis":"","theme":0,"in":[]}]
// &info_types=["spline"]&stacking=&steps=false&fontFamily=Courier&spacing=[5,0,0,0]
// &style=[{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"rgba(0, 0, 0, 1)","size":"18"},
// {"color":"000000","size":""},{"color":"000000","size":""}]&backgroundColor=rgba(255,255,255,1)
// &colors[]=rgba(124,181, 236, 1)&colors[]=rgba(67, 67, 72, 1)&colors[]=rgba(144, 237, 125,1)
// &colors[]=rgba(247, 163, 92, 1)&colors[]=rgba(128, 133, 233,1)&colors[]=rgba(241, 92, 128, 1)
// &colors[]=rgba(228, 211, 84,1)&colors[]=rgba(43, 144, 143, 1)&colors[]=rgba(244, 91, 91,1)
// &colors[]=rgba(145, 232, 225,1)&xlinew=0&ylinew=1&legends=true&tooltips=true&persistent=false`
// );
}
getDownloadsUrl () {
let encodedURL = encodeURIComponent('{"library":"HighCharts","chartDescription":{"queries":[{"name":"Monthly downloads","type":"line","query":{"name":"usagestats.downloads.monthly", "parameters":["' + this.piwik.openaireId + '"], "profile":"OpenAIRE All-inclusive" }}],"chart":{"backgroundColor":"#FFFFFFFF","borderColor":"#335cadff","borderRadius":0,"borderWidth":0,"plotBorderColor":"#ccccccff","plotBorderWidth":0},"title":{"text":""},"subtitle":{},"yAxis":{"title":{"text":"Monthly downloads"}},"xAxis":{"title":{}},"lang":{"noData":"No Data available for the Query"},"exporting":{"enabled":false},"plotOptions":{"series":{"dataLabels":{"enabled":false}}},"legend":{"enabled":false},"credits":{"href":null,"enabled":true,"text":"Created by OpenAIRE via HighCharts"}}}');
this.downloadsUrl = this.sanitizer.bypassSecurityTrustResourceUrl(`${this.repoMetrics.diagramsBaseURL}chart?json=${encodedURL}`);
// this.downloadsUrl = this.sanitizer.bypassSecurityTrustResourceUrl(
// `${this.repoMetrics.diagramsBaseURL}merge.php?com=query
// &data=[{"query":"dtsrcRepoDownloads","dtsrcName":"${this.piwik.openaireId}",
// "table":"","fields":[{"fld":"sum","agg":"sum","type":"chart","yaxis":1,"c":false}],
// "xaxis":{"name":"month","agg":"sum"},"group":"","color":"","type":"chart","size":30,
// "sort":"xaxis","xStyle":{"r":-30,"s":"0","l":"-","ft":"-","wt":"-"},"title":"","subtitle":"",
// "xaxistitle":"","yaxisheaders":["Monthly downloads"],"generalxaxis":"","theme":0,"in":[]}]
// &info_types=["spline"]&stacking=&steps=false&fontFamily=Courier&spacing=[5,0,0,0]
// &style=[{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"rgba(0, 0, 0,1)","size":"18"},
// {"color":"000000","size":""},{"color":"000000","size":""}]&backgroundColor=rgba(255,255,255,1)
// &colors[]=rgba(124, 181, 236, 1)&colors[]=rgba(67, 67, 72, 1)&colors[]=rgba(144, 237, 125,1)
// &colors[]=rgba(247, 163, 92, 1)&colors[]=rgba(128, 133, 233,1)&colors[]=rgba(241, 92, 128, 1)
// &colors[]=rgba(228, 211, 84,1)&colors[]=rgba(43, 144, 143, 1)&colors[]=rgba(244, 91, 91,1)
// &colors[]=rgba(145, 232, 225,1)&xlinew=0&ylinew=1&legends=true&tooltips=true&persistent=false`
// );
}
}

View File

@ -0,0 +1,7 @@
.innerTable {
padding: 50px;
}
.innerTable th, .innerTable td {
padding: 11px 12px;
}

View File

@ -0,0 +1,451 @@
<div id="page_content_inner">
<h2 class="heading_b uk-margin-bottom">Get usage statistics report</h2>
<!-- TOP HELP CONTENT -->
<help-content #topHelperContent [position]="'top'"
[ngClass]="topHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
<div class="uk-grid">
<!-- LEFT HELP CONTENT -->
<aside-help-content #leftHelperContent [position]="'left'"
[ngClass]="leftHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
<!-- MIDDLE -->
<div class=" uk-width-expand@m">
<div *ngIf="errorMessage" class="uk-alert uk-alert-warning">{{errorMessage}}</div>
<div *ngIf="loadingMessage" class="loading-big">
<div class="loader-big" style="text-align: center; padding-top: 170px; color: rgb(47, 64, 80); font-weight: bold;">
{{ loadingMessage }}
</div>
<div class="transparentFilm"></div>
</div>
<div *ngIf="repoResponse" class="md-card">
<div class="md-card-content large-padding">
<div class="uk-margin-bottom" data-uk-margin="">
<div class="uk-grid">
<div class="uk-width-4-5@m">
<h3>{{ repoResponse.ReportDefinition['@Name'] }} Report Results
<!--<span *ngIf="repoResponse.Report &&-->
<!--repoResponse.Report.Report &&-->
<!--repoResponse.Report.Report.Customer &&-->
<!--repoResponse.Report.Report.Customer.ReportItems &&-->
<!--repoResponse.Report.Report.Customer.ReportItems.length > 0">for {{ repoResponse.Report.Report.Customer.ReportItems[0].ItemPlatform }}</span>-->
</h3>
</div>
<div class="uk-width-1-5@m">
<div [formGroup]="pageSizeSelect" class="md-input-wrapper md-input-filled">
<label class="">Results per page</label>
<select class="md-input" formControlName="selectPageSize" (change)="getPageSize()">
<option value="10" selected>10</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option>
</select>
<span class="md-input-bar"></span>
</div>
</div>
</div>
</div>
<hr>
<div class="uk-grid uk-grid-divider" data-uk-grid-margin="">
<div class="uk-width-3-4@m uk-row-first">
<!-- RESULTS TABLE -->
<div class="uk-overflow-container">
<table class="uk-table table_check" style="overflow-wrap: anywhere;">
<thead>
<tr>
<th class="uk-width-1-6" *ngIf="chosenReport !== 'RR1'">Title</th>
<th class="uk-width-1-6" *ngIf="chosenReport !== 'RR1'">Publisher</th>
<th class="uk-width-1-6" *ngIf="chosenReport === 'RR1'">Platform name</th>
<th class="uk-width-1-6">{{ (chosenReport !== 'RR1') ? 'Item Urls' : 'Url' }}</th>
<th class="uk-width-1-6">Type</th>
<th class="uk-width-1-6" colspan="2">Downloads/Views</th>
<!--<th class="uk-width-2-10">Repository</th>-->
<!--<th class="uk-width-1-10">Validation Type</th>-->
<!--<th class="uk-width-1-10">Status</th>-->
<!--<th class="uk-width-1-10">Score</th>-->
<!--<th class="uk-width-1-10">Started</th>-->
<!--<th class="uk-width-2-10">Guidelines</th>-->
<!--<th class="uk-width-1-10">Actions</th>-->
<!--<th class="uk-width-1-10"></th>-->
</tr>
</thead>
<tbody>
<tr *ngIf="infoMessage">
<td colspan="6">{{ infoMessage }}</td>
</tr>
<ng-container *ngIf="repoResponse?.Report?.Report?.Customer?.ReportItems">
<ng-container *ngFor="let item of repoResponse.Report.Report.Customer.ReportItems; let item_i = index">
<tr>
<td *ngIf="chosenReport !== 'RR1'">{{ item.ItemName }}</td>
<td *ngIf="chosenReport !== 'RR1'">{{ item.ItemPublisher }}</td>
<td *ngIf="chosenReport === 'RR1'">{{ item.ItemPlatform }}</td>
<td>
<div *ngFor="let url of transformItem(item.ItemIdentifier); let i = index" class="uk-margin-small-bottom">
<!--<br *ngIf="i>0">-->
{{ url }}
</div>
</td>
<td>{{ item.ItemDataType }}</td>
<td class="uk-text-center"
*ngIf="repoResponse.ReportDefinition.Filters.ReportAttribute[0].Value === 'Monthly'" colspan="2">
<a *ngIf="item.ItemPerformance && (item.ItemPerformance.length > 0)"
(click)="displayItemPerformance(item_i)">{{ (selectedItemIndex === item_i) ? 'Hide' : 'See' }} results</a>
</td>
<td class="uk-text-center"
*ngIf="repoResponse.ReportDefinition.Filters.ReportAttribute[0].Value === 'Totals'">
{{ item.ItemPerformance[0].Instance[0].Count }}
</td>
<td class="uk-text-center"
*ngIf="repoResponse.ReportDefinition.Filters.ReportAttribute[0].Value === 'Totals'">
{{ item.ItemPerformance[0].Instance[1].Count }}
</td>
</tr>
<tr *ngIf="(selectedItemIndex === item_i)">
<td colspan="6">
<div class="uk-animation-slide-top-medium uk-margin-small-top">
<table class="uk-table uk-table-middle uk-table-striped innerTable uk-margin-small-top uk-margin-small-bottom">
<tr>
<th>Month</th>
<th>Downloads</th>
<th>Views</th>
</tr>
<tr *ngFor="let month of item.ItemPerformance">
<td>{{ month.Period.Begin | date: "MMM yyyy" }}</td>
<td>{{ month.Instance[0].Count }}</td>
<td>{{ month.Instance[1].Count }}</td>
</tr>
</table>
</div>
</td>
</tr>
</ng-container>
</ng-container>
</tbody>
</table>
</div>
<!--<div>-->
<!--<div>-->
<!--<div class="uk-overflow-auto uk-scrollspy-inview uk-animation-slide-top-medium uk-margin-top uk-margin-bottom">-->
<!--<table class="uk-table uk-table-middle uk-table-striped" style="vertical-align: top !important;">-->
<!--<thead>-->
<!--<tr>-->
<!--<th *ngIf="chosenReport !== 'RR1'">Title</th>-->
<!--<th *ngIf="chosenReport !== 'RR1'">Publisher</th>-->
<!--<th *ngIf="chosenReport === 'RR1'">Platform name</th>-->
<!--<th>{{ (chosenReport !== 'RR1') ? 'Item Urls' : 'Url' }}</th>-->
<!--<th>Type</th>-->
<!--<th colspan="2">Downloads/Views</th>-->
<!--</tr>-->
<!--</thead>-->
<!--<td colspan="6" *ngIf="infoMessage">{{ infoMessage }}</td>-->
<!--<tbody *ngFor="let item of repoResponse.Report.Report.Customer.ReportItems; let item_i = index"-->
<!--style="border-bottom: 1px solid whitesmoke;">-->
<!--<tr>-->
<!--<td *ngIf="chosenReport !== 'RR1'">{{ item.ItemName }}</td>-->
<!--<td *ngIf="chosenReport !== 'RR1'">{{ item.ItemPublisher }}</td>-->
<!--<td *ngIf="chosenReport === 'RR1'">{{ item.ItemPlatform }}</td>-->
<!--<td style="min-width: 300px;">-->
<!--<span *ngFor="let url of transformItem(item.ItemIdentifier); let i = index">-->
<!--<br *ngIf="i>0">{{ url }}-->
<!--</span>-->
<!--</td>-->
<!--<td>{{ item.ItemDataType }}</td>-->
<!--<td class="uk-text-center"-->
<!--*ngIf="repoResponse.ReportDefinition.Filters.ReportAttribute[0].Value === 'Monthly'" colspan="2">-->
<!--<a *ngIf="item.ItemPerformance && (item.ItemPerformance.length > 0)"-->
<!--(click)="displayItemPerformance(item_i)">{{ (selectedItemIndex === item_i) ? 'Hide' : 'See' }} results</a>-->
<!--</td>-->
<!--<td class="uk-text-center"-->
<!--*ngIf="repoResponse.ReportDefinition.Filters.ReportAttribute[0].Value === 'Totals'">-->
<!--{{ item.ItemPerformance[0].Instance[0].Count }}-->
<!--</td>-->
<!--<td class="uk-text-center"-->
<!--*ngIf="repoResponse.ReportDefinition.Filters.ReportAttribute[0].Value === 'Totals'">-->
<!--{{ item.ItemPerformance[0].Instance[1].Count }}-->
<!--</td>-->
<!--</tr>-->
<!--<tr *ngIf="(selectedItemIndex === item_i)">-->
<!--<td colspan="6">-->
<!--<div class="uk-animation-slide-top-medium uk-margin-small-top">-->
<!--<table class="uk-table uk-table-middle uk-table-striped innerTable">-->
<!--<tr>-->
<!--<th>Month</th>-->
<!--<th>Downloads</th>-->
<!--<th>Views</th>-->
<!--</tr>-->
<!--<tr *ngFor="let month of item.ItemPerformance">-->
<!--<td>{{ month.Period.Begin | date: "MMM yyyy" }}</td>-->
<!--<td>{{ month.Instance[0].Count }}</td>-->
<!--<td>{{ month.Instance[1].Count }}</td>-->
<!--</tr>-->
<!--</table>-->
<!--</div>-->
<!--</td>-->
<!--</tr>-->
<!--</tbody>-->
<!--</table>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!-- BOTTOM PAGINATION LINKS -->
<ul class="uk-pagination uk-margin-medium-top">
<li class="uk-pagination-previous"><a (click)="goToPreviousPage()"><i class="uk-icon-angle-left"></i><span class="uk-margin-left">Previous</span></a></li>
<li class=""><span>page {{ (totalPages > 0) ? page+1 : 0 }} of {{ totalPages }}</span></li>
<li class="uk-pagination-next"><a (click)="goToNextPage()"><span class="uk-margin-right">Next</span><i class="uk-icon-angle-right"></i></a></li>
</ul>
</div>
<div class="uk-width-1-4@m">
<div class="uk-margin-medium-bottom">
<p>
Number of results:
<span class="uk-badge uk-badge-success uk-text-upper uk-margin-small-left">{{ repoResponse.ReportDefinition.Filters.ReportAttribute[1].Value }}</span>
</p>
<p>
Filters:
<span *ngFor="let filter of repoResponse.ReportDefinition.Filters.Filter; let i = index" class="uk-badge uk-badge-outline uk-text-upper uk-margin-small-left">
{{ filter.Name }}: {{ filter.Value }}
</span>
</p>
</div>
<h2 class="heading_c uk-margin-small-bottom">Details</h2>
<ul class="md-list md-list-addon">
<li>
<div class="md-list-addon-element">
<i class="md-list-addon-icon material-icons"></i>
</div>
<div class="md-list-content">
<span class="md-list-heading">{{ repoResponse.Report.Report['@Created'] | date: "yyyy-MM-dd HH:mm:ss" }}</span>
<span class="uk-text-small uk-text-muted">Date run</span>
</div>
</li>
<li>
<div class="md-list-addon-element">
<i class="md-list-addon-icon material-icons"></i>
</div>
<div class="md-list-content">
<span class="md-list-heading">{{ coveredPeriod }}</span>
<span class="uk-text-small uk-text-muted">Period covered</span>
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
<!--<div *ngIf="repoResponse" class="uk-margin-top">-->
<!--<h3>{{ repoResponse.ReportDefinition['@Name'] }} Report Results-->
<!--<span *ngIf="repoResponse.Report &&-->
<!--repoResponse.Report.Report &&-->
<!--repoResponse.Report.Report.Customer &&-->
<!--repoResponse.Report.Report.Customer.ReportItems &&-->
<!--repoResponse.Report.Report.Customer.ReportItems.length > 0">for {{ repoResponse.Report.Report.Customer.ReportItems[0].ItemPlatform }}</span>-->
<!--</h3>-->
<!--<div class="uk-width-1-2">-->
<!--<table class="uk-table">-->
<!--<tr>-->
<!--<th>Period covered</th>-->
<!--<td>{{ coveredPeriod }}</td>-->
<!--</tr>-->
<!--<tr>-->
<!--<th>Filters</th>-->
<!--<td>-->
<!--<span *ngFor="let filter of repoResponse.ReportDefinition.Filters.Filter; let i = index">-->
<!--<br *ngIf="i>0">-->
<!--{{ filter.Name }}: {{ filter.Value }}-->
<!--</span>-->
<!--</td>-->
<!--</tr>-->
<!--<tr>-->
<!--<th>Date run</th>-->
<!--<td>{{ repoResponse.Report.Report['@Created'] | date: "yyyy-MM-dd HH:mm:ss" }}</td>-->
<!--</tr>-->
<!--<tr>-->
<!--<th>Number of results</th>-->
<!--<td>{{ repoResponse.ReportDefinition.Filters.ReportAttribute[1].Value }}</td>-->
<!--</tr>-->
<!--</table>-->
<!--</div>-->
<!--<div *ngIf="repoResponse.Report.Report.Customer &&-->
<!--repoResponse.Report.Report.Customer.ReportItems">-->
<!--<div>-->
<!--<div class="show-options uk-inline" style="float: right;">-->
<!--<div class="filterLabel" style="display: inline;">Results per page:</div>-->
<!--<div [formGroup]="pageSizeSelect" class="inlineBlock">-->
<!--<select class="form-control" formControlName="selectPageSize" (change)="getPageSize()">-->
<!--<option value="10" selected>10</option>-->
<!--<option value="25">25</option>-->
<!--<option value="50">50</option>-->
<!--<option value="100">100</option>-->
<!--</select>-->
<!--</div>-->
<!--</div>-->
<!--</div><br>-->
<!--<div class="contentAndPagerPanel">-->
<!--&lt;!&ndash; TOP PAGINATION LINKS &ndash;&gt;-->
<!--<div>-->
<!--<ul class="uk-pagination">-->
<!--<li>-->
<!--<a class="uk-link uk-link-muted" (click)="goToPreviousPage()">-->
<!--<span class="uk-margin-small-right uk-pagination-previous uk-icon" uk-pagination-previous="">-->
<!--<svg width="7" height="12" viewBox="0 0 7 12" xmlns="http://www.w3.org/2000/svg"-->
<!--icon="pagination-previous" ratio="1"></svg>-->
<!--</span>-->
<!--Previous-->
<!--</a>-->
<!--</li>-->
<!--<li class="uk-margin-auto-left">-->
<!--<a class="uk-link uk-link-muted" (click)="goToNextPage()">-->
<!--Next-->
<!--<span class="uk-margin-small-left uk-pagination-next uk-icon" uk-pagination-next="">-->
<!--<svg width="7" height="12" viewBox="0 0 7 12" xmlns="http://www.w3.org/2000/svg"-->
<!--icon="pagination-next" ratio="1"></svg>-->
<!--</span>-->
<!--</a>-->
<!--</li>-->
<!--</ul>-->
<!--<div class="resultsPageLabel">page {{ (totalPages > 0) ? page+1 : 0 }} of {{ totalPages }}</div>-->
<!--</div>-->
<!--&lt;!&ndash; RESULTS TABLE &ndash;&gt;-->
<!--<div>-->
<!--<div>-->
<!--<div class="uk-overflow-auto uk-scrollspy-inview uk-animation-slide-top-medium uk-margin-top uk-margin-bottom">-->
<!--<table class="uk-table uk-table-middle uk-table-striped" style="vertical-align: top !important;">-->
<!--<thead>-->
<!--<tr>-->
<!--<th *ngIf="chosenReport !== 'RR1'">Title</th>-->
<!--<th *ngIf="chosenReport !== 'RR1'">Publisher</th>-->
<!--<th *ngIf="chosenReport === 'RR1'">Platform name</th>-->
<!--<th>{{ (chosenReport !== 'RR1') ? 'Item Urls' : 'Url' }}</th>-->
<!--<th>Type</th>-->
<!--<th colspan="2">Downloads/Views</th>-->
<!--</tr>-->
<!--</thead>-->
<!--<td colspan="6" *ngIf="infoMessage" class="uk-alert">{{ infoMessage }}</td>-->
<!--<tbody *ngFor="let item of repoResponse.Report.Report.Customer.ReportItems; let item_i = index"-->
<!--style="border-bottom: 1px solid whitesmoke;">-->
<!--<tr>-->
<!--<td *ngIf="chosenReport !== 'RR1'">{{ item.ItemName }}</td>-->
<!--<td *ngIf="chosenReport !== 'RR1'">{{ item.ItemPublisher }}</td>-->
<!--<td *ngIf="chosenReport === 'RR1'">{{ item.ItemPlatform }}</td>-->
<!--<td style="min-width: 300px;">-->
<!--<span *ngFor="let url of transformItem(item.ItemIdentifier); let i = index">-->
<!--<br *ngIf="i>0">{{ url }}-->
<!--</span>-->
<!--</td>-->
<!--<td>{{ item.ItemDataType }}</td>-->
<!--<td class="uk-text-center"-->
<!--*ngIf="repoResponse.ReportDefinition.Filters.ReportAttribute[0].Value === 'Monthly'" colspan="2">-->
<!--<a *ngIf="item.ItemPerformance && (item.ItemPerformance.length > 0)"-->
<!--(click)="displayItemPerformance(item_i)">{{ (selectedItemIndex === item_i) ? 'Hide' : 'See' }} results</a>-->
<!--</td>-->
<!--<td class="uk-text-center"-->
<!--*ngIf="repoResponse.ReportDefinition.Filters.ReportAttribute[0].Value === 'Totals'">-->
<!--{{ item.ItemPerformance[0].Instance[0].Count }}-->
<!--</td>-->
<!--<td class="uk-text-center"-->
<!--*ngIf="repoResponse.ReportDefinition.Filters.ReportAttribute[0].Value === 'Totals'">-->
<!--{{ item.ItemPerformance[0].Instance[1].Count }}-->
<!--</td>-->
<!--</tr>-->
<!--<tr *ngIf="(selectedItemIndex === item_i)">-->
<!--<td colspan="6">-->
<!--<div class="uk-animation-slide-top-medium uk-margin-small-top">-->
<!--<table class="uk-table uk-table-middle uk-table-striped innerTable">-->
<!--<tr>-->
<!--<th>Month</th>-->
<!--<th>Downloads</th>-->
<!--<th>Views</th>-->
<!--</tr>-->
<!--<tr *ngFor="let month of item.ItemPerformance">-->
<!--<td>{{ month.Period.Begin | date: "MMM yyyy" }}</td>-->
<!--<td>{{ month.Instance[0].Count }}</td>-->
<!--<td>{{ month.Instance[1].Count }}</td>-->
<!--</tr>-->
<!--</table>-->
<!--</div>-->
<!--</td>-->
<!--</tr>-->
<!--</tbody>-->
<!--</table>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--&lt;!&ndash; BOTTOM PAGINATION LINKS &ndash;&gt;-->
<!--<div>-->
<!--<ul class="uk-pagination">-->
<!--<li>-->
<!--<a class="uk-link uk-link-muted" (click)="goToPreviousPage()">-->
<!--<span class="uk-margin-small-right uk-pagination-previous uk-icon" uk-pagination-previous="">-->
<!--<svg width="7" height="12" viewBox="0 0 7 12" xmlns="http://www.w3.org/2000/svg"-->
<!--icon="pagination-previous" ratio="1"></svg>-->
<!--</span>-->
<!--Previous-->
<!--</a>-->
<!--</li>-->
<!--<li class="uk-margin-auto-left">-->
<!--<a class="uk-link uk-link-muted" (click)="goToNextPage()">-->
<!--Next-->
<!--<span class="uk-margin-small-left uk-pagination-next uk-icon" uk-pagination-next="">-->
<!--<svg width="7" height="12" viewBox="0 0 7 12" xmlns="http://www.w3.org/2000/svg"-->
<!--icon="pagination-next" ratio="1"></svg>-->
<!--</span>-->
<!--</a>-->
<!--</li>-->
<!--</ul>-->
<!--<div class="resultsPageLabel">page {{ (totalPages > 0) ? page+1 : 0 }} of {{ totalPages }}</div>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
</div>
<!-- RIGHT HELP CONTENT -->
<aside-help-content #rightHelperContent [position]="'right'"
[ngClass]="rightHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
</div>
<!-- BOTTOM HELP CONTENT -->
<help-content #bottomHelperContent [position]="'bottom'"
[ngClass]="bottomHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
</div>

View File

@ -0,0 +1,164 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { AuthenticationService } from '../../../services/authentication.service';
import { UsagestatsService } from '../../../services/usagestats.service';
import { ReportResponse } from '../../../domain/usageStatsClasses';
import { FormBuilder, FormGroup } from '@angular/forms';
@Component({
selector: 'metrics-usagestats-report-results',
templateUrl: 'metrics-usagestats-report-results.component.html',
styleUrls: ['metrics-usagestats-report-results.component.css']
})
export class MetricsUsagestatsReportResultsComponent implements OnInit {
loadingMessage: string;
errorMessage: string;
infoMessage: string;
repoResponse: ReportResponse;
coveredPeriod: string;
params: URLSearchParams;
page: number;
pageSize: number;
totalPages: number;
selectedItemIndex: number;
pageSizeSelect: FormGroup;
chosenReport: string;
constructor(private route: ActivatedRoute,
private authService: AuthenticationService,
private usageService: UsagestatsService,
private fb: FormBuilder) {}
ngOnInit() {
this.page = 0;
this.pageSize = 10;
this.readParams();
this.pageSizeSelect = this.fb.group({selectPageSize: ['']});
let body = document.getElementsByTagName('body')[0];
body.classList.remove("top_bar_active"); //remove the class
body.classList.remove("page_heading_active");
body.classList.remove("landing");
body.classList.add("dashboard");
}
readParams() {
this.params = new URLSearchParams();
this.route.queryParams.subscribe( qparams => {
this.params.append('Report', qparams['report']);
this.params.append('Release', '4');
this.params.append('RequestorID', this.authService.getUserEmail());
this.params.append('BeginDate', qparams['beginDate']);
this.params.append('EndDate', qparams['endDate']);
this.params.append('RepositoryIdentifier', qparams['repoId']);
this.params.append('ItemIdentifier', qparams['itemIdentifier']);
this.params.append('ItemDataType', qparams['itemIdentifier']);
this.params.append('Granularity', qparams['granularity']);
});
this.chosenReport = this.params.get('Report');
this.getReportResponse();
}
getReportResponse() {
this.errorMessage = '';
this.loadingMessage = 'Loading results...';
this.infoMessage = '';
this.selectedItemIndex = null;
this.repoResponse = null;
this.usageService.getReportResponse(this.page.toString(), this.pageSize.toString(), this.params).subscribe(
responseWrapper => {
this.repoResponse = responseWrapper.ReportResponse;
},
error => {
this.errorMessage = 'Failed to load the report results!';
this.loadingMessage = '';
},
() => {
this.errorMessage = '';
this.loadingMessage = '';
this.pageSizeSelect.get('selectPageSize').setValue(this.pageSize);
this.pageSizeSelect.get('selectPageSize').updateValueAndValidity();
this.totalPages = Math.ceil(
+this.repoResponse.ReportDefinition.Filters
.ReportAttribute.filter(x => x['Name'] === 'ReportItemCount')[0].Value / this.pageSize);
if ( this.totalPages === 0 ) {
this.infoMessage = 'No results were found';
}
if (this.repoResponse.ReportDefinition && this.repoResponse.ReportDefinition.Filters &&
this.repoResponse.ReportDefinition.Filters.ReportAttribute) {
if (this.repoResponse.Report && this.repoResponse.ReportDefinition.Filters.UsageDateRange &&
this.repoResponse.ReportDefinition.Filters.UsageDateRange.Begin &&
this.repoResponse.ReportDefinition.Filters.UsageDateRange.End) {
this.coveredPeriod = this.repoResponse.ReportDefinition.Filters.UsageDateRange.Begin + ' to ';
this.coveredPeriod = this.coveredPeriod + this.repoResponse.ReportDefinition.Filters.UsageDateRange.End;
} else {
const defaultDatePeriod = this.repoResponse.Exception.filter(x => x['Message'] === 'Unspecified Date Arguments');
this.coveredPeriod = defaultDatePeriod[0].Data.split(':')[1].trim() + ' to ';
this.coveredPeriod = this.coveredPeriod + defaultDatePeriod[1].Data.split(':')[1].trim() + ' (default)';
}
} else {
this.repoResponse = null;
}
}
);
}
getPageSize() {
this.pageSize = +(this.pageSizeSelect.get('selectPageSize').value);
this.page = 0;
this.getReportResponse();
}
goToNextPage() {
if ( (this.page + 1) < this.totalPages) {
this.page++;
console.log(`Get me page ${this.page}!`);
this.getReportResponse();
}
}
goToPreviousPage() {
if (this.page > 0) {
this.page--;
console.log(`Get me page ${this.page}!`);
this.getReportResponse();
}
}
displayItemPerformance(i: number) {
if (this.selectedItemIndex === i) {
this.selectedItemIndex = null;
} else {
this.selectedItemIndex = i;
}
}
transformItem(itemIdentifiers: any[]) {
let field: string;
if (this.chosenReport === 'RR1') {
field = 'URL';
} else {
field = 'URLs';
}
const i = itemIdentifiers.findIndex(x => x['Type'] === field);
if ( i > -1 ) {
const urls = itemIdentifiers[i]['Value'];
return urls.split(';');
}
return '';
}
}

View File

@ -0,0 +1,218 @@
<div id="page_content_inner">
<h2 class="heading_b uk-margin-bottom">{{ title }}</h2>
<!-- TOP HELP CONTENT -->
<help-content #topHelperContent [position]="'top'"
[ngClass]="topHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
<div class="uk-grid">
<!-- LEFT HELP CONTENT -->
<aside-help-content #leftHelperContent [position]="'left'"
[ngClass]="leftHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
<!-- MIDDLE -->
<div class=" uk-width-expand@m">
<div *ngIf="errorMessage" class="uk-alert uk-alert-warning">{{errorMessage}}</div>
<div *ngIf="loadingMessage" class="loading-big">
<div class="loader-big" style="text-align: center; padding-top: 170px; color: rgb(47, 64, 80); font-weight: bold;">
{{ loadingMessage }}
</div>
<div class="transparentFilm"></div>
</div>
<div *ngIf="repo && chosen_report" class="uk-margin-top">
<div class="md-card">
<div class="md-card-content large-padding">
<div class="uk-grid uk-grid-divider" data-uk-grid-margin="">
<div class="uk-width-1-3@l uk-width-1-3@m uk-row-first">
<h3>Report Request</h3>
<div class="md-input-wrapper md-input-filled uk-margin-bottom">
<label>Report Name</label>
<input class="md-input label-fixed" type="text" value="{{ chosen_report }}" disabled>
<span class="md-input-bar "></span>
</div>
<div class="md-input-wrapper md-input-filled uk-margin-bottom">
<label>Release</label>
<input class="md-input label-fixed" type="text" value="4" disabled>
<span class="md-input-bar "></span>
</div>
<div class="md-input-wrapper md-input-filled uk-margin-bottom">
<label>Requestor</label>
<input class="md-input label-fixed" type="text" value="{{ userEmail }}" disabled>
<span class="md-input-bar "></span>
</div>
</div>
<!--<hr>-->
<div class="uk-width-1-3@l uk-width-1-3@m">
<h3>Report Filters</h3>
<h5>Date range</h5>
<div class="uk-text-italic">
<p>Valid date formats are yyyy-mm-dd or yyyy-mm. Default range is the last available month.</p>
</div>
<div class="">
<div class="md-input-wrapper md-input-filled uk-margin-bottom">
<label>Begin Date</label>
<input class="md-input label-fixed" name="BeginDate" placeholder="2016-03" type="text" (blur)="updateBeginDate($event)">
<span class="md-input-bar "></span>
</div>
<div class="md-input-wrapper md-input-filled">
<label>End Date</label>
<input class="md-input label-fixed" name="EndDate" placeholder="2016-06" type="text" (blur)="updateEndDate($event)">
<span class="md-input-bar "></span>
</div>
</div>
<h5><span *ngIf="chosen_report == 'RR1' || chosen_report == 'JR1'">Optional </span>Filters</h5>
<div class="uk-text-italic">
<p *ngIf="chosen_report != 'RR1' && chosen_report != 'JR1'">
For more specific results, provide an Item Identifier.<br>
Identifier format: <b>namespace:value</b><br>
Valid namespace for Item Identifier: <b>openaire</b>, <b>doi</b> or <b>oid</b>(for OAI-PMH).
</p>
<p *ngIf="chosen_report =='RR1'">
By default results are returned for all repositories.<br>
To get just the results for the current repository, check the box.</p>
</div>
<div *ngIf="chosen_report != 'JR1'">
<div class="md-input-wrapper md-input-filled uk-margin-bottom">
<label>Repository Identifier</label>
<input class="md-input label-fixed" type="text" value="{{ shownRepoId }}" disabled>
<span class="md-input-bar "></span>
</div>
<div *ngIf="chosen_report =='RR1'" class="uk-margin-bottom">
<input class="md-input label-fixed" type="checkbox" value="useCurrentRepo" (change)="updateUseCurrentRepo($event)">
<label class="inline-label">Select current repository</label>
</div>
</div>
<div *ngIf="repo.issn && chosen_report == 'JR1'" class="">
<div class="md-input-wrapper md-input-filled uk-margin-bottom">
<label>Journal Identifier</label>
<input class="md-input label-fixed" type="text" value="{{ shownRepoId }}" disabled>
<span class="md-input-bar "></span>
</div>
</div>
<div *ngIf="chosen_report != 'JR1' && chosen_report != 'RR1'" class="">
<div class="md-input-wrapper md-input-filled uk-margin-bottom">
<label>Item Identifier</label>
<input class="md-input label-fixed" name="ItemIdentifier" placeholder="e.g. openaire:od_________::fb90de6f20d79783d05749d8f60417d5"
type="text" (blur)="updateItemIdentifier($event)">
<span class="md-input-bar "></span>
</div>
</div>
<div *ngIf="chosen_report == 'IR1' || chosen_report == 'RR1' || chosen_report == 'JR1'">
<div class="uk-text-italic uk-margin-top uk-margin-bottom">
<p>Optional filter to only show results for a single item type, e.g. article, book, etc.</p>
</div>
<div class="md-input-wrapper md-input-filled">
<label class="">Item Data Type</label>
<select class="md-input" name="ItemDataType" (change)="updateItemDataType($event)">
<!-- TODO: get the list from api if it becomes available -->
<option value="">--- Select Item Data Type ---</option>
<option value="Annotation">Annotation</option>
<option value="Article">Article</option>
<option value="Bachelor thesis">Bachelor thesis</option>
<option value="Book">Book</option>
<option value="clinical trial">clinical trial</option>
<option value="Collection">Collection</option>
<option value="Conference object">Conference object</option>
<option value="Contribution for newspaper or weekly magazine">Contribution for newspaper or weekly magazine</option>
<option value="Dataset">Dataset</option>
<option value="Doctoral thesis">Doctoral thesis</option>
<option value="Event">Event</option>
<option value="External research report">External research report</option>
<option value="Film">Film</option>
<option value="Image">Image</option>
<option value="InteractiveResource">InteractiveResource</option>
<option value="Internal report">Internal report</option>
<option value="Lecture">Lecture</option>
<option value="Master thesis">Master thesis</option>
<option value="Newsletter">Newsletter</option>
<option value="Other">Other</option>
<option value="Part of book or chapter of book">Part of book or chapter of book</option>
<option value="Patent">Patent</option>
<option value="PhysicalObject">PhysicalObject</option>
<option value="Preprint">Preprint</option>
<option value="Report">Report</option>
<option value="Research">Research</option>
<option value="Review">Review</option>
<option value="Software">Software</option>
<option value="Sound">Sound</option>
<option value="Unknown">Unknown</option>
</select>
<span class="md-input-bar"></span>
</div>
</div>
</div>
<!--<hr>-->
<div class="uk-width-1-3@l uk-width-1-3@m">
<h3>Report Attributes</h3>
<div class="uk-text-italic">
<p>Valid Granularity values: Monthly or Totals</p>
</div>
<div class="md-input-wrapper md-input-filled">
<label class="">Granularity</label>
<select class="md-input" name="Granularity" (change)="updateGranularity($event)">
<option value="Monthly">Monthly</option>
<option value="Totals">Totals</option>
</select>
<span class="md-input-bar"></span>
</div>
</div>
</div>
<a class="uk-button uk-button-primary uk-margin-top" (click)="goToReport()">Get Report</a>
</div>
</div>
</div>
</div>
<!-- RIGHT HELP CONTENT -->
<aside-help-content #rightHelperContent [position]="'right'"
[ngClass]="rightHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
</div>
<!-- BOTTOM HELP CONTENT -->
<help-content #bottomHelperContent [position]="'bottom'"
[ngClass]="bottomHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
</div>

View File

@ -0,0 +1,177 @@
import { Component, OnInit } from '@angular/core';
import { Repository } from '../../../domain/typeScriptClasses';
import { ActivatedRoute, Router } from '@angular/router';
import { RepositoryService } from '../../../services/repository.service';
import { AuthenticationService } from '../../../services/authentication.service';
import { loadingRepoMessage } from '../../../domain/shared-messages';
import { SharedService } from "../../../services/shared.service";
@Component({
selector: 'metrics-usagestats-report',
templateUrl: './metrics-usagestats-report.component.html'
})
export class MetricsUsagestatsReportComponent implements OnInit {
errorMessage: string;
loadingMessage: string;
title: string;
repo: Repository;
// repoId: string;
shownRepoId: string;
shownOpenaireId: string;
useCurrentRepo: boolean;
issnToShow = '';
chosen_report: string;
userEmail: string;
beginDate = '';
endDate = '';
itemIdentifier = '';
itemDataType = '';
granularity = 'Monthly';
constructor(private repoService: RepositoryService,
private sharedService: SharedService,
private route: ActivatedRoute,
private router: Router,
private authService: AuthenticationService) {}
ngOnInit() {
if(this.sharedService.getRepository()) {
this.repo = this.sharedService.getRepository();
this.getInfo();
}
this.sharedService.repository$.subscribe(
r => {
this.repo = r;
this.getInfo();
}
);
let body = document.getElementsByTagName('body')[0];
body.classList.remove("top_bar_active"); //remove the class
body.classList.remove("page_heading_active");
body.classList.remove("landing");
body.classList.add("dashboard");
}
getInfo() {
this.getParams();
this.getUserEmail();
if (this.repo.piwikInfo) {
this.shownOpenaireId = this.convertToDisplayedFormat(this.repo.piwikInfo.openaireId);
}
if (this.repo.issn && this.repo.issn !== 'null') {
this.shownRepoId = this.repo.issn.slice(0, 4) + '-' + this.repo.issn.toString().slice(4);
}
this.title = `${this.chosen_report} report for ${this.repo.officialName}`;
}
getParams() {
// this.repoId = this.route.snapshot.paramMap.get('id');
this.chosen_report = this.route.snapshot.paramMap.get('reportID');
this.shownRepoId = this.convertToDisplayedFormat(this.repo.id);
console.log(`shownRepoId is ${this.repo.id}`);
this.title = `${this.chosen_report} report`;
if (this.chosen_report !== 'RR1') {
this.useCurrentRepo = true;
}
}
convertToDisplayedFormat(input: string) {
const tempArray = this.repo.id.split('____::');
return tempArray[0] + ':' + tempArray[1];
}
getUserEmail() {
this.userEmail = this.authService.getUserEmail();
}
// getRepo() {
// this.loadingMessage = loadingRepoMessage;
// this.repoService.getRepositoryById(this.repoId).subscribe(
// repo => this.repo = repo,
// error => {
// console.log(error);
// this.loadingMessage = '';
// this.errorMessage = 'The repository could not be retrieved';
// },
// () => {
// this.loadingMessage = '';
// if (this.repo.piwikInfo) {
// this.shownOpenaireId = this.convertToDisplayedFormat(this.repo.piwikInfo.openaireId);
// }
// if (this.repo.issn && this.repo.issn !== 'null') {
// this.shownRepoId = this.repo.issn.slice(0, 4) + '-' + this.repo.issn.toString().slice(4);
// }
// this.title = `${this.chosen_report} report for ${this.repo.officialName}`;
// }
// );
// }
updateBeginDate(event: any) {
this.beginDate = event.target.value;
}
updateEndDate(event: any) {
this.endDate = event.target.value;
}
updateItemDataType(event: any) {
this.itemDataType = event.target.value;
}
updateItemIdentifier(event: any) {
this.itemIdentifier = event.target.value;
}
updateGranularity(event: any) {
this.granularity = event.target.value;
}
updateUseCurrentRepo(event: any) {
this.useCurrentRepo = event.target.value;
}
goToReport() {
if (!this.useCurrentRepo) { this.shownRepoId = ''; }
this.router.navigate(['usagestats-report-results'], {
relativeTo: this.route.parent,
queryParams: {
report: this.chosen_report,
beginDate: this.beginDate,
endDate: this.endDate,
repoId: this.shownRepoId,
itemDataType: this.itemDataType,
itemIdentifier: this.itemIdentifier,
granularity: this.granularity
}
});
/*const params = new URLSearchParams();
params.append('Report', this.chosen_report);
params.append('Release', '4');
params.append('RequestorID', this.authService.getUserEmail());
params.append('BeginDate', this.beginDate);
params.append('EndDate', this.endDate);
params.append('RepositoryIdentifier', this.shownRepoId);
if (this.itemIdentifier) {
params.append('ItemIdentifier', this.itemIdentifier);
}
if (this.itemDataType) {
params.append('ItemDataType', this.itemDataType);
}
params.append('Pretty', 'Pretty');
let url = `http://beta.services.openaire.eu/usagestats/sushilite/GetReport/?${params}`;
console.log(`going to: ${url}`);
window.location.href = url;*/
}
}

View File

@ -0,0 +1,125 @@
<div id="page_content_inner">
<h2 class="heading_b uk-margin-bottom">{{ title }}</h2>
<!-- TOP HELP CONTENT -->
<help-content #topHelperContent [position]="'top'"
[ngClass]="topHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
<div class="uk-grid">
<!-- LEFT HELP CONTENT -->
<aside-help-content #leftHelperContent [position]="'left'"
[ngClass]="leftHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
<!-- MIDDLE -->
<div class=" uk-width-expand@m">
<div *ngIf="errorMessage" class="uk-alert uk-alert-warning">{{ errorMessage }}</div>
<div *ngIf="repo">
<h3>Supported Reports</h3>
<div class="uk-grid uk-grid-match repositoryTypeSelection" data-uk-grid-margin="">
<div class="uk-width-1-3@m uk-row-first">
<div class="uk-text-center md-card md-card-default md-card-hover uk-scrollspy-inview uk-animation-slide-top-medium" uk-scrollspy-class="">
<a [routerLink]="['AR1']" class="el-link uk-position-cover uk-margin-remove-adjacent"></a>
<div class="uk-card-media-top">
<img class="el-image" src="../../../../assets/imgs/Icons_Reports_wide_AR1.png" alt="" style="width: 100%;">
</div>
<div class="uk-card-body">
<h3 class="el-title uk-margin uk-card-title uk-margin-remove-adjacent uk-margin-small-bottom">
Article Report 1, number of successful article download requests by month and repository.
</h3>
</div>
</div>
</div>
<div class="uk-width-1-3@m">
<div class="uk-margin uk-text-center md-card md-card-default md-card-hover uk-scrollspy-inview uk-animation-slide-top-medium" uk-scrollspy-class="" data-id="" style="">
<a [routerLink]="['IR1']" class="el-link uk-position-cover uk-margin-remove-adjacent" href=""></a>
<div class="uk-card-media-top">
<img class="el-image" src="../../../../assets/imgs/Icons_Reports_wide_IR1.png" alt="" style="width:100%;">
</div>
<div class="uk-card-body">
<h3 class="el-title uk-margin uk-card-title uk-margin-remove-adjacent uk-margin-small-bottom" >
Item Report 1, number of successful item download requests by month and repository.
</h3>
</div>
</div>
</div>
<div class="uk-width-1-3@m">
<div class="uk-margin uk-text-center md-card md-card-default md-card-hover uk-scrollspy-inview uk-animation-slide-top-medium" uk-scrollspy-class="" data-id="" style="">
<a [routerLink]="['RR1']" class="el-link uk-position-cover uk-margin-remove-adjacent"></a>
<div class="uk-card-media-top">
<img class="el-image" src="../../../../assets/imgs/Icons_Reports_wide_RR1.png" alt="" style="width:100%;">
</div>
<div class="uk-card-body">
<h3 class="el-title uk-margin uk-card-title uk-margin-remove-adjacent uk-margin-small-bottom">
Repository Report 1, number of successful item downloads for all repositories participating in the usage statistics service.
</h3>
</div>
</div>
</div>
</div>
<div class="uk-grid uk-grid-match repositoryTypeSelection" data-uk-grid-margin="">
<div class="uk-width-1-3@m uk-row-first">
<div class="uk-text-center md-card md-card-default md-card-hover uk-scrollspy-inview uk-animation-slide-top-medium" uk-scrollspy-class="">
<a [routerLink]="['BR1']" class="el-link uk-position-cover uk-margin-remove-adjacent"></a>
<div class="uk-card-media-top">
<img class="el-image" src="../../../../assets/imgs/Icons_Reports_wide_BR1.png" alt="" style="width: 100%;">
</div>
<div class="uk-card-body">
<h3 class="el-title uk-margin uk-card-title uk-margin-remove-adjacent uk-margin-small-bottom">
Book Report 1, number of successful title requests by month and title.
</h3>
</div>
</div>
</div>
<div class="uk-width-1-3@m">
<div class="uk-margin uk-text-center md-card md-card-default md-card-hover uk-scrollspy-inview uk-animation-slide-top-medium" uk-scrollspy-class="" data-id="" style="">
<a [routerLink]="['BR2']" class="el-link uk-position-cover uk-margin-remove-adjacent" href=""></a>
<div class="uk-card-media-top">
<img class="el-image" src="../../../../assets/imgs/Icons_Reports_wide_BR2.png" alt="" style="width:100%;">
</div>
<div class="uk-card-body">
<h3 class="el-title uk-margin uk-card-title uk-margin-remove-adjacent uk-margin-small-bottom" >
Book Report 2, number of successful section requests by month and title.
</h3>
</div>
</div>
</div>
<div *ngIf="repo.datasourceType === 'journal'" class="uk-width-1-3@m">
<div class="uk-margin uk-text-center md-card md-card-default md-card-hover uk-scrollspy-inview uk-animation-slide-top-medium" uk-scrollspy-class="" data-id="" style="">
<a [routerLink]="['JR1']" class="el-link uk-position-cover uk-margin-remove-adjacent"></a>
<div class="uk-card-media-top">
<img class="el-image" src="../../../../assets/imgs/Icons_Reports_wide_JR1.png" alt="" style="width:100%;">
</div>
<div class="uk-card-body">
<h3 class="el-title uk-margin uk-card-title uk-margin-remove-adjacent uk-margin-small-bottom">
Journal Report 1, number of successful full-text article requests by month and journal.
</h3>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- RIGHT HELP CONTENT -->
<aside-help-content #rightHelperContent [position]="'right'"
[ngClass]="rightHelperContent.isPresent()?'tm-sidebar uk-width-1-4@m uk-first-column':'clear-style'">
</aside-help-content>
</div>
<!-- BOTTOM HELP CONTENT -->
<help-content #bottomHelperContent [position]="'bottom'"
[ngClass]="bottomHelperContent.isPresent()?'uk-margin-medium-top uk-margin-medium-bottom':'clear-style'">
</help-content>
</div>

View File

@ -0,0 +1,65 @@
import { Component, OnInit } from '@angular/core';
import { Repository } from '../../../domain/typeScriptClasses';
import { RepositoryService } from '../../../services/repository.service';
import { AuthenticationService } from '../../../services/authentication.service';
import { ActivatedRoute, Router } from '@angular/router';
import { SharedService } from "../../../services/shared.service";
@Component({
selector: 'metrics-usagestats',
templateUrl: 'metrics-usagestats.component.html'
})
export class MetricsUsagestatsComponent implements OnInit {
errorMessage: string;
title = 'Get usage counts report';
repo: Repository;
constructor(private repoService: RepositoryService,
private sharedService: SharedService,
private authService: AuthenticationService,
private route: ActivatedRoute,
private router: Router) {}
ngOnInit() {
if(this.sharedService.getRepository()) {
this.repo = this.sharedService.getRepository();
this.title = this.title + ' for ' + this.repo.officialName;
}
this.sharedService.repository$.subscribe(
r => {
this.repo = r;
this.title = this.title + ' for ' + this.repo.officialName;
}
);
// this.getRepo();
let body = document.getElementsByTagName('body')[0];
body.classList.remove("top_bar_active"); //remove the class
body.classList.remove("page_heading_active");
body.classList.remove("landing");
body.classList.add("dashboard");
}
// getRepo() {
//
// if (this.repoId) {
// this.repoService.getRepositoryById(this.repoId).subscribe(
// repo => this.repo = repo,
// error => {
// console.log(error);
// this.errorMessage = 'The repository could not be retrieved';
// },
// () => {
// this.title = this.title + ' for ' + this.repo.officialName;
// console.log(this.authService.getUserEmail(), this.repo.registeredBy);
// }
// );
// }
// }
}

View File

@ -0,0 +1,35 @@
/**
* Created by myrto on 11/27/17.
*/
import { NgModule } from '@angular/core';
import { TabsModule } from 'ngx-bootstrap';
import { CommonModule } from '@angular/common';
import { MetricsRouting } from './metrics.routing';
import { ReactiveFormsModule } from '@angular/forms';
import { MetricsEnableComponent } from './metrics-enable.component';
import { MetricsInstructionsComponent } from './metrics-instructions.component';
import { MetricsShowComponent } from './metrics-show.component';
import { MetricsUsagestatsComponent } from './metrics-usagestats.component';
import { MetricsUsagestatsReportComponent } from './metrics-usagestats-report.component';
import { MetricsUsagestatsReportResultsComponent } from './metrics-usagestats-report-results.component';
import { ReusableComponentsModule } from "../../../shared/reusablecomponents/reusable-components.module";
@NgModule ({
imports: [
CommonModule,
TabsModule.forRoot(),
MetricsRouting,
ReusableComponentsModule,
ReactiveFormsModule
],
declarations: [
MetricsEnableComponent,
MetricsInstructionsComponent,
MetricsShowComponent,
MetricsUsagestatsComponent,
MetricsUsagestatsReportComponent,
MetricsUsagestatsReportResultsComponent
]
})
export class MetricsModule { }

View File

@ -0,0 +1,57 @@
/**
* Created by myrto on 11/27/17.
*/
import { RouterModule, Routes } from '@angular/router';
import { MetricsEnableComponent } from './metrics-enable.component';
import { MetricsShowComponent } from './metrics-show.component';
import { MetricsInstructionsComponent } from './metrics-instructions.component';
import { MetricsUsagestatsComponent } from './metrics-usagestats.component';
import { MetricsUsagestatsReportComponent } from './metrics-usagestats-report.component';
import { MetricsUsagestatsReportResultsComponent } from './metrics-usagestats-report-results.component';
import { NgModule } from '@angular/core';
const metricsRoutes: Routes = [
{
path: '',
children: [
{
path: '',
redirectTo: 'enable',
// pathMatch: 'full'
},
{
path: 'enable',
component: MetricsEnableComponent
},
{
path: 'show_metrics',
component: MetricsShowComponent
},
{
path: 'instructions',
component: MetricsInstructionsComponent
},
{
path: 'usagestats',
component: MetricsUsagestatsComponent
},
{
path: 'usagestats/:reportID',
component: MetricsUsagestatsReportComponent
},
{
path: 'usagestats-report-results',
component: MetricsUsagestatsReportResultsComponent
}
]
}
];
@NgModule ({
imports: [RouterModule.forChild(metricsRoutes)],
exports: [RouterModule]
})
export class MetricsRouting {}

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