diff --git a/portal-4cli/.angular-cli.json b/portal-4cli/.angular-cli.json new file mode 100644 index 00000000..a1364d22 --- /dev/null +++ b/portal-4cli/.angular-cli.json @@ -0,0 +1,106 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "project": { + "name": "ng-universal-demo" + }, + "apps": [ + { + "root": "src", + "outDir": "dist/browser", + "assets": [ + "assets", + "favicon.ico" + ], + "index": "index.html", + "main": "main.ts", + "polyfills": "polyfills.ts", + "test": "test.ts", + "tsconfig": "tsconfig.app.json", + "testTsconfig": "tsconfig.spec.json", + "prefix": "app", + "styles": [ + "styles.css" + ], + "scripts": [], + "environmentSource": "environments/environment.ts", + "environments": { + "dev": "environments/environment.ts", + "prod": "environments/environment.prod.ts" + } + }, + { + "platform": "server", + "root": "src", + "outDir": "dist/server", + "assets": [ + "assets", + "favicon.ico" + ], + "index": "index.html", + "main": "main.server.ts", + "test": "test.ts", + "tsconfig": "tsconfig.server.json", + "testTsconfig": "tsconfig.spec.json", + "prefix": "app", + "styles": [ + "styles.css" + ], + "scripts": [], + "environmentSource": "environments/environment.ts", + "environments": { + "dev": "environments/environment.ts", + "prod": "environments/environment.prod.ts" + } + } + ], + "e2e": { + "protractor": { + "config": "./protractor.conf.js" + } + }, + "lint": [ + { + "project": "src/tsconfig.app.json", + "exclude": "**/node_modules/**" + }, + { + "project": "src/tsconfig.spec.json", + "exclude": "**/node_modules/**" + }, + { + "project": "e2e/tsconfig.e2e.json", + "exclude": "**/node_modules/**" + } + ], + "test": { + "karma": { + "config": "./karma.conf.js" + } + }, + "defaults": { + "styleExt": "css", + "component": { + "spec": false, + "inlineStyle": true, + "inlineTemplate": true + }, + "directive": { + "spec": false + }, + "class": { + "spec": false + }, + "guard": { + "spec": false + }, + "module": { + "spec": false + }, + "pipe": { + "spec": false + }, + "service": { + "spec": false + } + } + } \ No newline at end of file diff --git a/portal-4cli/README.md b/portal-4cli/README.md new file mode 100644 index 00000000..96e55e90 --- /dev/null +++ b/portal-4cli/README.md @@ -0,0 +1,54 @@ +# Angular Universal & Anguar-CLI minimal starter + +> This demo is built following the [Angular-CLI Wiki guide](https://github.com/angular/angular-cli/wiki/stories-universal-rendering) + +We're utilizing packages from the [Angular Universal @nguniversal](https://github.com/angular/universal) repo, such as [ng-module-map-ngfactory-loader](https://github.com/angular/universal/tree/master/modules/module-map-ngfactory-loader) to enable Lazy Loading. + +--- + +## Static or Dynamic +This repo demonstrates the use of 2 different forms of Server Side Rendering. + +**Static** Also known as "prerendering" +* Happens at build time +* Renders your application and replaces the dist index.html with a version rendered at the route `/`. + +**Dynamic** +* Happens at runtime +* Uses `ngExpressEngine` to render you application on the fly at the requested url. + +--- + +## Installation +* `npm install` or `yarn` + +--- + +## Development (Client-side only rendering) +* run `npm run start` which will start `ng serve` (project served at the standard: localhost:4200) + +--- + +## Production + +Depending on whether you're publishing dynamic or static prerendering, run the build command, and then serve up your dist folder assets. + +> **NOTE**: To deploy your **Static** site to a static hosting platform you will have to deploy the *`dist/browser`* folder, rather than the usual *`dist`* + +ie: `npm run build:dynamic` or `npm run build:static`. All of the files that need to be served will be found within the `/dist` folder. + + + +--- + +## Testing Universal (dynamic or static) builds -Locally- + +**Dynamic** : **`npm run start:dynamic`** + +Compiles your application and spins up a Node Express to dynamically serve your Universal application on `http://localhost:4000`. + +**Static** : **`npm run start:static`** + +- Compiles your application and prerenders your applications files, spinning up a demo http-server so you can view it on `http://127.0.0.1:8080` + + diff --git a/portal-4cli/package.json b/portal-4cli/package.json new file mode 100644 index 00000000..37d4027b --- /dev/null +++ b/portal-4cli/package.json @@ -0,0 +1,57 @@ +{ + "name": "openaire-search", + "version": "1.0.0", + "license": "Openaire", + "contributors": [ + "Argiro Kokogiannaki ", + "Konstantina Galouni " + ], + "scripts": { + "ng": "ng", + "start": "ng serve --disable-host-check", + "start:dynamic": "npm run build:dynamic && npm run serve:dynamic", + "start:static": "npm run build:static && npm run serve:static", + "build": "ng build", + "build:client-and-server-bundles": "ng build --prod -sm --stats-json && ng build --prod --app 1 --output-hashing=false", + "build:static": "npm run build:client-and-server-bundles && npm run webpack:server && npm run generate:static", + "build:dynamic": "npm run build:client-and-server-bundles && npm run webpack:server", + "generate:static": "cd dist && node prerender", + "webpack:server": "webpack --config webpack.server.config.js --progress --colors", + "serve:static": "cd dist/browser && http-server", + "serve:dynamic": "node dist/server" + }, + "private": true, + "dependencies": { + "@angular/animations": "^4.2.4", + "@angular/common": "^4.2.4", + "@angular/compiler": "^4.2.4", + "@angular/core": "^4.2.4", + "@angular/forms": "^4.2.4", + "@angular/http": "^4.2.4", + "@angular/platform-browser": "^4.2.4", + "@angular/platform-browser-dynamic": "^4.2.4", + "@angular/platform-server": "^4.2.4", + "@angular/router": "^4.2.4", + "@nguniversal/express-engine": "^1.0.0-beta.3", + "@nguniversal/module-map-ngfactory-loader": "^1.0.0-beta.3", + "angular2-datatable": "^0.6.0", + "citation-js": "^0.3.4", + "clipboard": "^1.5.16", + "core-js": "^2.4.1", + "rxjs": "^5.4.2", + "ts-md5": "^1.2.0", + "wikidata-sdk": "^5.2.9", + "zone.js": "^0.8.14" + }, + "devDependencies": { + "@angular/cli": "^1.3.0", + "@angular/compiler-cli": "^4.2.4", + "@angular/language-service": "^4.2.4", + "@types/node": "^8.0.30", + "cpy-cli": "^1.0.1", + "http-server": "^0.10.0", + "reflect-metadata": "^0.1.10", + "ts-loader": "^2.3.7", + "typescript": "~2.3.3" + } +} diff --git a/portal-4cli/prerender.ts b/portal-4cli/prerender.ts new file mode 100644 index 00000000..5ddb8cd4 --- /dev/null +++ b/portal-4cli/prerender.ts @@ -0,0 +1,45 @@ +// Load zone.js for the server. +import 'zone.js/dist/zone-node'; +import 'reflect-metadata'; +import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs'; +import { join } from 'path'; + +import { enableProdMode } from '@angular/core'; +// Faster server renders w/ Prod mode (dev mode never needed) +enableProdMode(); + +// Express Engine +import { ngExpressEngine } from '@nguniversal/express-engine'; +// Import module map for lazy loading +import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader'; +import { renderModuleFactory } from '@angular/platform-server'; +import { ROUTES } from './static.paths'; + +// * NOTE :: leave this as require() since this file is built Dynamically from webpack +const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./dist/server/main.bundle'); + +const BROWSER_FOLDER = join(process.cwd(), 'browser'); + +// Load the index.html file containing referances to your application bundle. +const index = readFileSync(join('browser', 'index.html'), 'utf8'); + +let previousRender = Promise.resolve(); + +// Iterate each route path +ROUTES.forEach(route => { + var fullPath = join(BROWSER_FOLDER, route); + + // Make sure the directory structure is there + if(!existsSync(fullPath)){ + mkdirSync(fullPath); + } + + // Writes rendered HTML to index.html, replacing the file if it already exists. + previousRender = previousRender.then(_ => renderModuleFactory(AppServerModuleNgFactory, { + document: index, + url: route, + extraProviders: [ + provideModuleMap(LAZY_MODULE_MAP) + ] + })).then(html => writeFileSync(join(fullPath, 'index.html'), html)); +}); diff --git a/portal-4cli/server.ts b/portal-4cli/server.ts new file mode 100644 index 00000000..6aeb0faa --- /dev/null +++ b/portal-4cli/server.ts @@ -0,0 +1,58 @@ +import 'zone.js/dist/zone-node'; +import 'reflect-metadata'; +import { renderModuleFactory } from '@angular/platform-server'; +import { enableProdMode } from '@angular/core'; + +import * as express from 'express'; +import { join } from 'path'; +import { readFileSync } from 'fs'; + +// Faster server renders w/ Prod mode (dev mode never needed) +enableProdMode(); + +// Express server +const app = express(); + +const PORT = process.env.PORT || 4000; +const DIST_FOLDER = join(process.cwd(), 'dist'); + +// Our index.html we'll use as our template +const template = readFileSync(join(DIST_FOLDER, 'browser', 'index.html')).toString(); + +// * NOTE :: leave this as require() since this file is built Dynamically from webpack +const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./dist/server/main.bundle'); + +// Express Engine +import { ngExpressEngine } from '@nguniversal/express-engine'; +// Import module map for lazy loading +import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader'; + +// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine) +app.engine('html', ngExpressEngine({ + bootstrap: AppServerModuleNgFactory, + providers: [ + provideModuleMap(LAZY_MODULE_MAP) + ] +})); + +app.set('view engine', 'html'); +app.set('views', join(DIST_FOLDER, 'browser')); + +/* - Example Express Rest API endpoints - + app.get('/api/**', (req, res) => { }); +*/ + +// Server static files from /browser +app.get('*.*', express.static(join(DIST_FOLDER, 'browser'), { + maxAge: '1y' +})); + +// ALl regular routes use the Universal engine +app.get('*', (req, res) => { + res.render('index', { req }); +}); + +// Start up the Node server +app.listen(PORT, () => { + console.log(`Node Express server listening on http://localhost:${PORT}`); +}); diff --git a/portal-4cli/src/angular2-meta.ts b/portal-4cli/src/angular2-meta.ts new file mode 100644 index 00000000..a1d0ddc0 --- /dev/null +++ b/portal-4cli/src/angular2-meta.ts @@ -0,0 +1,220 @@ +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +import {Injectable, Inject} from '@angular/core'; +// es6-modules are used here +import { ɵgetDOM as getDOM} from '@angular/platform-browser'; +import {DOCUMENT} from '@angular/platform-browser'; +/** + * Represent meta element. + * + * ### Example + * + * ```ts + * { name: 'application-name', content: 'Name of my application' }, + * { name: 'description', content: 'A description of the page', id: 'desc' } + * // ... + * // Twitter + * { name: 'twitter:title', content: 'Content Title' } + * // ... + * // Google+ + * { itemprop: 'name', content: 'Content Title' }, + * { itemprop: 'description', content: 'Content Title' } + * // ... + * // Facebook / Open Graph + * { property: 'fb:app_id', content: '123456789' }, + * { property: 'og:title', content: 'Content Title' } + * ``` + * + * @experimental + */ +export interface MetaDefinition { + charset?: string; + content?: string; + httpEquiv?: string; + id?: string; + itemprop?: string; + name?: string; + property?: string; + scheme?: string; + url?: string; + [prop: string]: string; +} + +/** + * A service that can be used to get and add meta tags. + * + * @experimental + */ +@Injectable() +export class Meta { + private _dom: any = getDOM(); + constructor( @Inject(DOCUMENT) private _document: any) { } + /** + * Sets the title of the page + */ + setTitle(title: string) { + this._document.title = title + } + /** + * Adds a new meta tag to the dom. + * + * ### Example + * + * ```ts + * const name: MetaDefinition = {name: 'application-name', content: 'Name of my application'}; + * const desc: MetaDefinition = {name: 'description', content: 'A description of the page'}; + * const tags: HTMLMetaElement[] = this.meta.addTags([name, desc]); + * ``` + * + * @param tags + * @returns {HTMLMetaElement[]} + */ + addTags(...tags: Array): HTMLMetaElement[] { + const presentTags = this._flattenArray(tags); + if (presentTags.length === 0) return []; + return presentTags.map((tag: MetaDefinition) => this._addInternal(tag)); + } + + /** + * Gets the meta tag by the given selector. Returns element or null + * if there's no such meta element. + * + * ### Example + * + * ```ts + * const meta: HTMLMetaElement = this.meta.getTag('name=description'); + * const twitterMeta: HTMLMetaElement = this.meta.getTag('name="twitter:title"'); + * const fbMeta: HTMLMetaElement = this.meta.getTag('property="fb:app_id"'); + * ``` + * + * @param selector + * @returns {HTMLMetaElement} + */ + // getTag(selector: string): HTMLMetaElement { + // if (!selector) return null; + // return this._dom.query(`meta[${selector}]`); + // } + getTag(attrSelector: string): HTMLMetaElement|null { + if (!attrSelector) return null; + return this._dom.querySelector(this._document, `meta[${attrSelector}]`); +} + + /** + * Updates the meta tag with the given selector. + * + * * ### Example + * + * ```ts + * const meta: HTMLMetaElement = this.meta.updateTag('name=description', {name: 'description', + * content: 'New description'}); + * console.log(meta.content); // 'New description' + * ``` + * + * @param selector + * @param tag updated tag definition + * @returns {HTMLMetaElement} + */ + updateTag(selector: string, tag: MetaDefinition): HTMLMetaElement { + const meta: HTMLMetaElement = this.getTag(selector); + if (!meta) { + // create element if it doesn't exist + return this._addInternal(tag); + } + return this._prepareMetaElement(tag, meta); + } + + updateMeta(name, content) { + const head = this._document.head; + let childNodesAsList = this._dom.childNodesAsList(head); + let metaEl = childNodesAsList.find(el => el['attribs'] ? el['attribs'].name == name : false); + if (metaEl) metaEl['attribs'].content = content; + } + updateProperty(property, content) { + const head = this._document.head; + let childNodesAsList = this._dom.childNodesAsList(head); + let metaEl = childNodesAsList.find(el => el['attribs'] ? el['attribs'].property == property : false); + if (metaEl) metaEl['attribs'].content = content; + } + + /** + * Removes meta tag with the given selector from the dom. + * + * ### Example + * + * ```ts + * this.meta.removeTagBySelector('name=description'); + * ``` + * + * @param selector + */ + removeTagBySelector(selector: string): void { + const meta: HTMLMetaElement = this.getTag(selector); + this.removeTagElement(meta); + } + + /** + * Removes given meta element from the dom. + * + * ### Example + * ```ts + * const elem: HTMLMetaElement = this.meta.getTag('name=description'); + * this.meta.removeTagElement(elem); + * ``` + * + * @param meta meta element + */ + removeTagElement(meta: HTMLMetaElement): void { + if (meta) { + this._removeMetaElement(meta); + } + } + + private _addInternal(tag: MetaDefinition): HTMLMetaElement { + const meta: HTMLMetaElement = this._createMetaElement(); + this._prepareMetaElement(tag, meta); + this._appendMetaElement(meta); + return meta; + } + + private _createMetaElement(): HTMLMetaElement { + return this._dom.createElement('meta') as HTMLMetaElement; + } + + private _prepareMetaElement(tag: MetaDefinition, el: HTMLMetaElement): HTMLMetaElement { + Object.keys(tag).forEach((prop: string) => this._dom.setAttribute(el, prop, tag[prop])); + return el; + } + + // private _appendMetaElement(meta: HTMLMetaElement): void { + // const head = this._dom.getElementsByTagName(this._dom.defaultDoc(), 'head')[0]; + // this._dom.appendChild(head, meta); + // } + private _appendMetaElement(meta: HTMLMetaElement): void { + const head = this._document.head; + this._dom.appendChild(head, meta); + } + private _removeMetaElement(meta: HTMLMetaElement): void { + const head = this._dom.parentElement(meta); + this._dom.removeChild(head, meta); + } + + private _flattenArray(input: any[], out: any[] = []): any[] { + if (input) { + for (let i = 0; i < input.length; i++) { + const item: any = input[i]; + if (Array.isArray(item)) { + this._flattenArray(item, out); + } else if (item) { + out.push(item); + } + } + } + return out; + } +} diff --git a/portal-4cli/src/app/app.component.ts b/portal-4cli/src/app/app.component.ts new file mode 100644 index 00000000..01d1078c --- /dev/null +++ b/portal-4cli/src/app/app.component.ts @@ -0,0 +1,56 @@ +import { Component, Directive, ElementRef, Renderer, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core'; +import { ConfigurationService } from './utils/configuration/configuration.service'; +import {Observable} from 'rxjs/Observable'; + +@Component({ + //changeDetection: ChangeDetectionStrategy.Default, + //encapsulation: ViewEncapsulation.Emulated, + selector: 'app-root', + styles: [` + `], + template: ` + + + + + +
+
+ + +
+
+ + + + OpenAIRE uses cookies in order to function properly.
+ 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. Read more + + +
+ + +` + +}) +export class AppComponent { + isClient:boolean = false; + constructor(private config: ConfigurationService) {} + + ngOnInit() { + + if (typeof document !== 'undefined') { + try{ + this.isClient = true; + }catch (e) { + } + } + } +} diff --git a/portal-4cli/src/app/app.module.ts b/portal-4cli/src/app/app.module.ts new file mode 100755 index 00000000..cecf15cd --- /dev/null +++ b/portal-4cli/src/app/app.module.ts @@ -0,0 +1,78 @@ +import { NgModule } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { SharedModule } from './shared/shared.module'; +import { BrowserModule } from '@angular/platform-browser'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { APP_BASE_HREF, CommonModule } from '@angular/common'; +import { HttpModule } from '@angular/http'; +import { RouterModule } from '@angular/router'; +import { AppComponent } from './app.component'; +import {SharedComponentsModule} from './sharedComponents/sharedComponents.module'; //navbar +import { CookieLawModule } from './sharedComponents/cookie-law/cookie-law.module'; +import {Meta} from '../angular2-meta'; +// import { ErrorModule } from './error/error.module'; +import { ConfigurationService } from './utils/configuration/configuration.service'; +import { ErrorPageComponent } from './error/errorPage.component'; + +@NgModule({ + + imports: [ + SharedModule, + NoopAnimationsModule, + CommonModule, + HttpModule, + SharedComponentsModule, + CookieLawModule, + BrowserModule.withServerTransition({appId: 'my-app'}), + RouterModule.forRoot([ + { path: '', loadChildren: './home/home.module#HomeModule'}, + { path: 'home', loadChildren: './home/home.module#HomeModule'}, + { path: 'search/publication', loadChildren: './landingPages/publication/publication.module#PublicationModule' }, + { path: 'search/dataset', loadChildren: './landingPages/dataset/dataset.module#DatasetModule' }, + { path: 'search/software', loadChildren: './landingPages/software/software.module#SoftwareModule' }, + { path: 'search/project', loadChildren: './landingPages/project/project.module#ProjectModule' }, + { path: 'search/dataprovider', loadChildren: '././landingPages/dataProvider/dataProvider.module#DataProviderModule' }, + { path: 'search/organization', loadChildren: './landingPages/organization/organization.module#OrganizationModule' }, + { path: 'participate/deposit-datasets', loadChildren: './deposit/datasets/depositDatasets.module#DepositDatasetsModule' }, + { path: 'participate/deposit-datasets-result', loadChildren: './deposit/datasets/depositDatasetsResults.module#DepositDatasetsResultsModule' }, + { path: 'participate/deposit-subject-result', loadChildren: './deposit/datasets/depositBySubjectResults.module#DepositBySubjectResultsModule' }, + { path: 'participate/deposit-publications', loadChildren: './deposit/publications/depositPublications.module#DepositPublicationsModule' }, + { path: 'participate/deposit-publications-result', loadChildren: './deposit/publications/depositPublicationsResults.module#DepositPublicationsResultsModule' }, + { path: 'search/find', loadChildren: './searchPages/find/mainSearch.module#MainSearchModule' }, + { path: 'search/find/publications', loadChildren: './searchPages/simple/searchPublications.module#SearchPublicationsModule' }, + { path: 'search/find/datasets', loadChildren: './searchPages/simple/searchDatasets.module#SearchDatasetsModule' }, + { path: 'search/find/software', loadChildren: './searchPages/simple/searchSoftware.module#SearchSoftwareModule' }, + { path: 'search/find/projects', loadChildren: './searchPages/simple/searchProjects.module#SearchProjectsModule' }, + { path: 'search/find/dataproviders', loadChildren: './searchPages/simple/searchDataProviders.module#SearchDataProvidersModule' }, + { path: 'search/find/organizations', loadChildren: './searchPages/simple/searchOrganizations.module#SearchOrganizationsModule' }, + { path: 'search/content-providers', loadChildren: './searchPages/dataProviders/compatibleDataProviders.module#CompatibleDataProvidersModule' }, + { path: 'search/content-providers-table', loadChildren: './searchPages/dataProviders/compatibleDataProvidersTable.module#CompatibleDataProvidersTableModule' }, + { path: 'search/entity-registries', loadChildren: './searchPages/dataProviders/entityRegistries.module#EntityRegistriesModule' }, + { path: 'search/entity-registries-table', loadChildren: './searchPages/dataProviders/entityRegistriesTable.module#EntityRegistriesTableModule' }, + { path: 'search/journals', loadChildren: './searchPages/dataProviders/journals.module#JournalsModule' }, + { path: 'search/journals-table', loadChildren: './searchPages/dataProviders/journalsTable.module#JournalsTableModule' }, + { path: 'search/advanced/publications', loadChildren: './searchPages/advanced/advancedSearchPublications.module#AdvancedSearchPublicationsModule' }, + { path: 'search/advanced/datasets', loadChildren: './searchPages/advanced/advancedSearchDatasets.module#AdvancedSearchDatasetsModule' }, + { path: 'search/advanced/software', loadChildren: './searchPages/advanced/advancedSearchSoftware.module#AdvancedSearchSoftwareModule' }, + { path: 'search/advanced/organizations', loadChildren: './searchPages/advanced/advancedSearchOrganizations.module#AdvancedSearchOrganizationsModule' }, + { path: 'search/advanced/dataproviders', loadChildren: './searchPages/advanced/advancedSearchDataProviders.module#AdvancedSearchDataProvidersModule' }, + { path: 'search/advanced/projects', loadChildren: './searchPages/advanced/advancedSearchProjects.module#AdvancedSearchProjectsModule' }, + { path: 'project-report', loadChildren: './landingPages/htmlProjectReport/htmlProjectReport.module#HtmlProjectReportModule' }, + { path: 'myclaims', loadChildren: './claims/myClaims/myClaims.module#MyClaimsModule' }, + { path: 'claims', loadChildren: './claims/claimsAdmin/claimsAdmin.module#ClaimsAdminModule' }, + { path: 'participate/claim', loadChildren: './claims/linking/linkingGeneric.module#LinkingGenericModule' }, + { path: 'participate/direct-claim', loadChildren: './claims/directLinking/directLinking.module#DirectLinkingModule' }, + { path: 'claims-project-manager', loadChildren: './claims/claimsByToken/claimsByToken.module#ClaimsByTokenModule' }, + { path: 'user-info', loadChildren: './login/user.module#UserModule' }, + { path: 'error', component: ErrorPageComponent }, + { path: '**',pathMatch: 'full',component: ErrorPageComponent } + + + ]), + ], + declarations: [ AppComponent, ErrorPageComponent ], + exports: [ AppComponent ], + providers:[ Meta, ConfigurationService], + bootstrap: [AppComponent] +}) +export class AppModule {} diff --git a/portal-4cli/src/app/app.server.module.ts b/portal-4cli/src/app/app.server.module.ts new file mode 100644 index 00000000..79602ec8 --- /dev/null +++ b/portal-4cli/src/app/app.server.module.ts @@ -0,0 +1,20 @@ +import {NgModule} from '@angular/core'; +import {ServerModule} from '@angular/platform-server'; +import {ModuleMapLoaderModule} from '@nguniversal/module-map-ngfactory-loader'; + +import {AppModule} from './app.module'; +import {AppComponent} from './app.component'; + +@NgModule({ + imports: [ + // The AppServerModule should import your AppModule followed + // by the ServerModule from @angular/platform-server. + AppModule, + ServerModule, + ModuleMapLoaderModule, + ], + // Since the bootstrapped component is not inherited from your + // imported AppModule, it needs to be repeated here. + bootstrap: [AppComponent], +}) +export class AppServerModule {} diff --git a/portal-4cli/src/app/claims/claim-utils/claim.ts b/portal-4cli/src/app/claims/claim-utils/claim.ts new file mode 100644 index 00000000..b5378c5f --- /dev/null +++ b/portal-4cli/src/app/claims/claim-utils/claim.ts @@ -0,0 +1,15 @@ +export class Claim { + id: string; + sourceType: string; + targetType: string; + sourceId: string; + targetId: string; + date: string; + DOI: string; + project: Project + userMail: string; + +} +export class Project{ + +} diff --git a/portal-4cli/src/app/claims/claim-utils/claimContextSearchForm.component.ts b/portal-4cli/src/app/claims/claim-utils/claimContextSearchForm.component.ts new file mode 100644 index 00000000..8d1a8740 --- /dev/null +++ b/portal-4cli/src/app/claims/claim-utils/claimContextSearchForm.component.ts @@ -0,0 +1,343 @@ +import {Component, Input,Output, EventEmitter, ViewChild} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import { Router} from '@angular/router'; +import {ContextsService} from './service/contexts.service'; +import {ClaimContext} from './claimEntities.class'; +import { StaticAutoCompleteComponent } from '../../utils/staticAutoComplete/staticAutoComplete.component'; +declare var UIkit:any; +import {Session} from '../../login/utils/helper.class'; +import {ErrorCodes} from '../../login/utils/guardHelper.class'; + +@Component({ + // moduleId: module.id, + selector: 'claim-contexts-search-form', + template: ` + +
+
Search for Communities
+ + + + + +
+ + + + + +
+ + +
Or Browse through categories
+ + + +
+ + ` + +}) +export class ClaimContextSearchFormComponent { +// @Input() public inline:boolean = false ; // for claimed started from landing pages +public showComponent:boolean = true ; // for claimed started from landing pages +@Input() public selectedList; +//The following need to be kept in case we have to save the current state +@Input() public projects; +@Input() public results; +@Input() public inlineEntity; +public selectedCommunityId:string = "0"; +public selectedCategoryId:string ="0"; +// @Output() contextSelected = new EventEmitter(); + +@ViewChild (StaticAutoCompleteComponent) autocomplete : StaticAutoCompleteComponent ; + +public query = ''; +public filteredList = []; +public communities:any; +public selectedCommunityLabel:string = "Community:"; + +public categories:any; +public selectedCategoryLabel:string ="Category:"; +public concepts = []; +public conceptsClass = []; +public conceptsClassDisplay = []; +public conceptsCategoryLoading = []; +public warningMessage = ""; +public infoMessage = ""; +public loading:boolean = false; +public error:boolean = false; + +ngOnInit() { + this.getCommunities(); +} +constructor(private _contextService: ContextsService,private router: Router) { + +} + +select($event){ + var item = $event.value; + this.addNewContext( this.selectedCommunityLabel, this.selectedCategoryLabel, item); + } +isSelected(id):boolean{ + for (var _i = 0; _i < this.selectedList.length; _i++) { + let item = this.selectedList[_i]; + if(item.concept.id == id){ + return true; + // this.warningMessage = "Concept already in selected list"; + } + } + return false; +} + addNewContext(community,category,concept){ + var context: ClaimContext= { community: community, category: category, concept: concept }; + var found:boolean = false; + this.warningMessage = ""; + if (!this.isSelected(context.concept.id)) { + + this.selectedList.push(context); + UIkit.notification({ + message : 'A new concept is selected.', + status : 'info', + timeout : 1000, + pos : 'top-center' + }); + + }else{ + UIkit.notification({ + message : 'The concept is already on your list.', + status : 'warning', + timeout : 1000, + pos : 'top-center' + }); + } +} + +getCommunities () { + if(!Session.isValidAndRemove()){ + this.saveStateAndRedirectLogin(); + + }else{ + this.loading = true; + var token=Session.getUserJwt(); + this._contextService.getCommunities().subscribe( + data => { + this.communities = data.communities; + this.loading = false; + }, + err => { + console.log(err); + this.loading = false; + this.error = true; + } + ); + } + } + getCategories () { + this.loading = true; + this.categories=[]; + if(this.selectedCommunityId != '0'){ + if(!Session.isValidAndRemove()){ + this.saveStateAndRedirectLogin(); + + }else{ + var token=Session.getUserJwt(); + this._contextService.getCategories(this.selectedCommunityId).subscribe( + data => { + + this.categories = (Array.isArray(data.category))? data.category:[data.category]; + this.concepts = []; + this.addCommunityInConcepts(); + this.filteredList = []; + if (this.query !== ""){ + var event = {value: ""}; + event.value = this.query; + } + this.loading = false; + }, + err => { + console.log(err); + this.loading = false; + } + ); + } + } + } + getConcepts () { + this.loading = true; + if(this.selectedCategoryId != '0'){ + if(!Session.isValidAndRemove()){ + this.saveStateAndRedirectLogin(); + }else{ + this.concepts = []; + var token=Session.getUserJwt(); + this._contextService.getConcepts(this.selectedCategoryId, "",true).subscribe( + data => { + + this.concepts =data; + this.addCommunityInConcepts(); + if (this.query !== ""){ + var event = {value: ""}; + event.value = this.query; + // this.filter(event); + } + this.loading = false; + }, + err => { + console.log(err); + this.loading = false; + } + ); + } + }else{ + this.concepts=[]; + this.loading = false; + } + } + displaySubcategory(id) { + if(this.conceptsClassDisplay[id] != null){ + this.conceptsClassDisplay[id] = !this.conceptsClassDisplay[id]; + + }else{ + this.conceptsClassDisplay[id] = true; + } + } + browseConcepts (categoryId) { + if(!Session.isValidAndRemove()){ + this.saveStateAndRedirectLogin(); + }else{ + if(this.conceptsClass[categoryId] != null){ + this.conceptsClassDisplay[categoryId] = !this.conceptsClassDisplay[categoryId]; + return; + }else{ + this.conceptsClassDisplay[categoryId] = true; + } + this.conceptsClass[categoryId] = []; + var token=Session.getUserJwt(); + this.conceptsCategoryLoading[categoryId] = true; + this._contextService.getConcepts(categoryId, "",false).subscribe( + data => { + var concepts = (Array.isArray(data))? data:[data]; + for(var i=0;i { + console.log(err); + this.conceptsCategoryLoading[categoryId] = false; + } + ); + } + + } + communityChanged(){ + console.log(this.selectedCommunityId +" "); + this.warningMessage = ""; + this.infoMessage = ""; + for(var i = 0; i< this.communities.length; i++){ + if(this.communities[i].id==this.selectedCommunityId){ + this.selectedCommunityLabel = this.communities[i].label; + break; + } + } + this.selectedCategoryId = "0"; + this.selectedCategoryLabel="Select Category:"; + this.getCategories(); + } + categoryChanged(){ + this.warningMessage = ""; + this.infoMessage = ""; + for(var i = 0; i< this.categories.length; i++){ + if(this.categories[i].id==this.selectedCategoryId){ + this.selectedCategoryLabel = this.categories[i].label; + break; + } + } + this.getConcepts(); + } +addCommunityInConcepts(){ + this.concepts.push({"id":this.selectedCommunityId, "label":this.selectedCommunityLabel}); + this.autocomplete.updateList(this.concepts); +} +saveStateAndRedirectLogin(){ + if(this.projects != null){ + localStorage.setItem("projects", JSON.stringify(this.projects)); + } + localStorage.setItem("contexts", JSON.stringify(this.selectedList)); + if(this.results != null){ + localStorage.setItem("results", JSON.stringify(this.results)); + } + if(this.inlineEntity != null){ + localStorage.setItem("inlineEntity", JSON.stringify(this.inlineEntity)); + } + + this.router.navigate(['/user-info'], { queryParams: { "errorCode": ErrorCodes.NOT_VALID, "redirectUrl": this.router.url } }); +} +} diff --git a/portal-4cli/src/app/claims/claim-utils/claimContextSearchForm.module.ts b/portal-4cli/src/app/claims/claim-utils/claimContextSearchForm.module.ts new file mode 100644 index 00000000..345d2c93 --- /dev/null +++ b/portal-4cli/src/app/claims/claim-utils/claimContextSearchForm.module.ts @@ -0,0 +1,20 @@ +import { NgModule } from '@angular/core'; + +import { SharedModule } from '../../shared/shared.module'; +import { ClaimContextSearchFormComponent } from './claimContextSearchForm.component'; + import{ContextsServiceModule} from './service/contextsService.module'; + import {StaticAutocompleteModule} from '../../utils/staticAutoComplete/staticAutoComplete.module'; + import { RouterModule } from '@angular/router'; + +@NgModule({ + imports: [ + SharedModule,RouterModule, + ContextsServiceModule, + StaticAutocompleteModule + + ], + declarations: [ + ClaimContextSearchFormComponent + ], exports: [ClaimContextSearchFormComponent ] +}) +export class ClaimContextSearchFormModule { } diff --git a/portal-4cli/src/app/claims/claim-utils/claimEntities.class.ts b/portal-4cli/src/app/claims/claim-utils/claimEntities.class.ts new file mode 100644 index 00000000..7d866cea --- /dev/null +++ b/portal-4cli/src/app/claims/claim-utils/claimEntities.class.ts @@ -0,0 +1,100 @@ +//Classes used in linking / inlinelinking when selecting an entity +export class ClaimResult{ + public id: string; + public type: string; + public source: string; + public title: string; + public url: string; + public result: any; + public accessRights: string = "OPEN"; + public embargoEndDate: string; + public date: string; + public authors: string[] =[]; + public publisher: string; + public description: string; + public resourceType:string; + + public static generateResult(item, itemId,itemSource,itemType, itemUrl, itemTitle, date, accessmode){ + + var result: ClaimResult = new ClaimResult(); + result.id = itemId; + result.type = itemType; + result.source = itemSource; + + result.title = (Array.isArray(itemTitle) && itemTitle.length > 0 )?itemTitle[0]:itemTitle; + result.url = itemUrl; + result.accessRights = 'OPEN'; + result.date = date; + result.result = item; + if(item.publisher){ + result.publisher = item.publisher; + } + + if(itemSource == 'datacite'){ + + result.publisher = item.attributes['container-title']; + if(item.attributes.author){ + result.authors =[] + for(var i=0; i< item.attributes.author.length; i++){ + result.authors.push((item.attributes.author[i].family)?item.attributes.author[i].family+', '+item.attributes.author[i].given:item.attributes.author[i].literal); + } + } + + // result = {id: itemId, type :itemType, source : itemSource, title: itemTitle,url: itemUrl, result: item, accessRights: 'OPEN', embargoEndDate: this.nextDate, date : date}; + }else if (itemSource == 'openaire'){ + //TODO put right access rights + // result = {id:itemId, type :itemType, source : itemSource, title: itemTitle,url: itemUrl, result: item, accessRights: accessMode, embargoEndDate: this.nextDate, date: date}; + // result = {id:itemId, type :itemType, source : itemSource, title: itemTitle,url: itemUrl, result: item, accessRights: accessmode, embargoEndDate: this.nextDate, date : date}; + result.embargoEndDate = accessmode; + + }else if(itemSource == 'crossref'){ + date = (date == null) ? null : date.substring(0,10); + result.date = date; + result.resourceType = item.type; + result.description = item.abstract; + if(item.author){ + result.authors =[] + for(var i=0; i< item.author.length; i++){ + result.authors.push(item.author[i].family +" "+ item.author[i].given ); + } + } + // result = {id: itemId, type :itemType, source : itemSource, title: itemTitle,url: itemUrl, result: item, accessRights: 'OPEN', embargoEndDate: this.nextDate, date: date}; + }else if (itemSource == 'orcid'){ + date = (date == null) ? null : date + "-01.-01" + result.date = date; + if(item['work-type']){ + result.resourceType = item.type; + + } + if(item.contributors){ + result.authors =[] + for(var i=0; i< item.contributors.length; i++){ + result.authors.push(item.contributors[i]); + } + } + + } + return result; + } +} +export class ClaimProject{ + public funderId: string; + public funderName: string; + public projectId: string; + public projectName: string; + public projectAcronym: string; + public startDate: string; + public endDate: string; + public code: string; + public jurisdiction: string; + public fundingLevel0: string; + + +} + +export class ClaimContext{ + public community: string; + public category: string; + public concept:any; + +} diff --git a/portal-4cli/src/app/claims/claim-utils/claimProjectSearchForm.component.ts b/portal-4cli/src/app/claims/claim-utils/claimProjectSearchForm.component.ts new file mode 100644 index 00000000..d6a7c1fb --- /dev/null +++ b/portal-4cli/src/app/claims/claim-utils/claimProjectSearchForm.component.ts @@ -0,0 +1,194 @@ +import {Component, Input,Output, ElementRef, EventEmitter, ViewChild} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {SearchProjectsService} from '../../services/searchProjects.service'; +import {ProjectService} from '../../landingPages/project/project.service'; +// import {ModalLoading} from '../../utils/modal/loading.component'; +import { Subject } from 'rxjs/Subject'; +import {ClaimProject} from './claimEntities.class'; +declare var UIkit:any; +@Component({ + selector: 'claim-projects-search-form', + // styleUrls: ['/autoComplete.component.css'], + + template: ` +
+
+ + +
+ Search for projects +
+ + +
+
+ + + +
+ ` + +}) +export class ClaimProjectsSearchFormComponent { + ngOnInit() { + this.getFunders(); + } + // @ViewChild (ModalLoading) loading : ModalLoading ; + + // @Input() public inline: boolean = false ; // for claimed started from landing pages + public query = ''; + @Input() public selectedProjects=[] ; + public elementRef; + + public funders:string[]; + public selectedFunderId:string ="0"; + selectedFunderName:string ="Select funder:"; + @Output() projectSelected = new EventEmitter(); + + public projects:string[]; + public warningMessage = ""; + public infoMessage = ""; + + // public searchTermStream = new Subject(); + // filtered: Observable<{}> = this.searchTermStream + // .debounceTime(300).distinctUntilChanged() + // .switchMap((term: string) => this._projectService.searchForProjectsObs(term, this.selectedFunderId)); + public tries:number = 0 ; + public keywordlimit = 3; + +constructor(private _service: ProjectService, private _projectService: SearchProjectsService, myElement: ElementRef) { + this.elementRef = myElement; +} + + +// search() { +// console.info("heeere "+this.query ); +// this.infoMessage = ""; +// // this.filtered = []; +// if(this.query == ""){ +// this.tries = 0; +// this.warningMessage = ""; +// } else if(this.query && this.query.length < this.keywordlimit){ +// this.tries++; +// if(this.tries == this.keywordlimit -1 ){ +// this.warningMessage = "Type at least " + this.keywordlimit + " characters"; +// this.tries = 0; +// } +// }else{ +// console.info("doo the search "+this.query ); +// +// this.tries = 0; +// this.warningMessage = ""; +// this.searchTermStream.next(this.query); +// +// } +// +// } +select(item){ + this.query = ""; + // this.searchTermStream.next(this.query); //clear + item = item.value; + var project: ClaimProject = new ClaimProject(); + project.funderId = (this.selectedFunderId=="0")?item.funderId:this.selectedFunderId; + project.funderName = (this.selectedFunderId=="0")?item.funderName:this.selectedFunderName; + project.projectId = item.id; + project.projectName = item.projectName; + project.projectAcronym = item.projectAcronym; + project.startDate = item.startDate; + project.endDate = item.endDate; + project.code = item.code; + project.jurisdiction = item.jurisdiction; + project.fundingLevel0 = item.fundingLevel0; + + console.log(item); + + + // this._service.getProjectDates(project.projectId).subscribe( + // data => { + // project.startDate = data.startDate; + // project.endDate = data.endDate; + // }, + // err => console.log(err) + // ); + var index:number =this.selectedProjects.indexOf(project); + var found:boolean = false; + this.warningMessage = ""; + + for (var _i = 0; _i < this.selectedProjects.length; _i++) { + let item = this.selectedProjects[_i]; + if(item.projectId == project.projectId){ + found=true; + this.warningMessage = "Project already in selected list"; + } + } + + if (!found) { + this.selectedProjects.push(project); + this.projectSelected.emit({ + value: true + }); + UIkit.notification({ + message : 'A new project is selected.', + status : 'info', + timeout : 1000, + pos : 'top-center' + }); + }else{ + UIkit.notification({ + message : 'The project is already on your list.', + status : 'warning', + timeout : 1000, + pos : 'top-center' + }); + } + +} +showItem(item):string{ + return ((item.field[1]['@value'])?item.field[1]['@value']+" - ":"" ) + item.field[3]['@value']; +} +remove(item){ + var index:number =this.selectedProjects.indexOf(item); + if (index > -1) { + this.selectedProjects.splice(index, 1); + } + +} +handleClick(event){ + var clickedComponent = event.target; + var inside = false; + do { + if (clickedComponent === this.elementRef.nativeElement) { + inside = true; + } + clickedComponent = clickedComponent.parentNode; + } while (clickedComponent); + +} +getFunders () { + console.info("Getting Funders...."); + this._projectService.getFunders().subscribe( + data => { + this.funders = data[1]; + console.log("this.funders"); + }, + err => console.log(err) + ); + } + + getProjects () { + if(this.selectedFunderId != '0'){ + + } + } +funderChanged(funderId:string, funderName:string){ + this.selectedFunderId = funderId; + this.selectedFunderName = funderName; + console.info("Selected funder:"+this.selectedFunderId+ ' name:'+funderName ); + +} + +} diff --git a/portal-4cli/src/app/claims/claim-utils/claimProjectSearchForm.module.ts b/portal-4cli/src/app/claims/claim-utils/claimProjectSearchForm.module.ts new file mode 100644 index 00000000..660cb500 --- /dev/null +++ b/portal-4cli/src/app/claims/claim-utils/claimProjectSearchForm.module.ts @@ -0,0 +1,27 @@ +import { NgModule } from '@angular/core'; + +import { SharedModule } from '../../shared/shared.module'; +import { CommonModule } from '@angular/common'; + +import {ClaimProjectsSearchFormComponent} from './claimProjectSearchForm.component'; +// import {LoadingModalModule} from '../../utils/modal/loadingModal.module'; + +import {ProjectServiceModule} from '../../landingPages/project/projectService.module'; +import {ProjectsServiceModule} from '../../services/projectsService.module'; +import {EntitiesAutocompleteModule} from '../../utils/entitiesAutoComplete/entitiesAutoComplete.module'; + + @NgModule({ + imports: [ + SharedModule, CommonModule, + // LoadingModalModule, + ProjectServiceModule, ProjectsServiceModule, EntitiesAutocompleteModule + ], + providers:[ + ], + declarations: [ + ClaimProjectsSearchFormComponent + + ], + exports: [ClaimProjectsSearchFormComponent ] +}) +export class ClaimProjectsSearchFormModule { } diff --git a/portal-4cli/src/app/claims/claim-utils/claimResultSearchForm.component.html b/portal-4cli/src/app/claims/claim-utils/claimResultSearchForm.component.html new file mode 100644 index 00000000..218ea6f3 --- /dev/null +++ b/portal-4cli/src/app/claims/claim-utils/claimResultSearchForm.component.html @@ -0,0 +1,188 @@ +
+
Search for research results
+ + + + + +
+
+ + +
+
+ + + + +
+
+ +
+
+
+
    +
  • +
    + {{item.title}} + {{item.title}} + +
    + + + +
  • +
+
+
+
+
+
+ + + + +
+
+ +
+
+
+
    +
  • +
    + {{result['title'].name}} + {{result['title'].name}} + +
    + + + + +
  • +
+
+
+
+
+
+ + + +
No results found
+ +
+ Results for + {{authorGivenName}} {{authorFamilyName}} - {{authorId}} : + +
Not the author you are looking for? + + + + + + + +
+ + +
+
+ +
+ +
+
+
    +
  • +
    + {{item['work-title']['title'].value}} + +
    + + + +
  • +
+
No results found
+
+
+
+
+
+ + + + +
+
+
+ +
+
+
+
    +
  • +
    + {{item.attributes.title}} + {{item.attributes.title}} + + +
    + + + +
  • +
+ +
+
+
+
+ + + + +
+
+
+ +
+
+
+
    +
  • +
    + {{result['title'].name}} + {{result['title'].name}} + + + +
    + + + + +
  • +
+
+
+
+
diff --git a/portal-4cli/src/app/claims/claim-utils/claimResultSearchForm.component.ts b/portal-4cli/src/app/claims/claim-utils/claimResultSearchForm.component.ts new file mode 100644 index 00000000..26b6cd4d --- /dev/null +++ b/portal-4cli/src/app/claims/claim-utils/claimResultSearchForm.component.ts @@ -0,0 +1,587 @@ +import {Component, Input, Output, EventEmitter} from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import {SearchCrossrefService} from '../claim-utils/service/searchCrossref.service'; +import {SearchOrcidService} from '../claim-utils/service/searchOrcid.service'; +import {SearchPublicationsService} from '../../services/searchPublications.service'; +import { SearchDataciteService } from '../claim-utils/service/searchDatacite.service'; +import {SearchDatasetsService} from '../../services/searchDatasets.service'; + +import { ErrorCodes} from '../../utils/properties/openaireProperties'; +import {ClaimResult} from '../claim-utils/claimEntities.class'; +import{DOI} from '../../utils/string-utils.class'; +declare var UIkit:any; + +@Component({ + selector: 'claim-result-search-form', + templateUrl: 'claimResultSearchForm.component.html', + +}) +export class ClaimResultSearchFormComponent { + constructor (private _searchDataciteService: SearchDataciteService, private _searchDatasetsService:SearchDatasetsService, + private _searchCrossrefService: SearchCrossrefService,private _searchOrcidService: SearchOrcidService, private _searchPublicationsService: SearchPublicationsService, + private route: ActivatedRoute) { + var myDate = new Date(); + this.todayDate = myDate.getFullYear()+ "-" +(myDate.getMonth() + 1) + "-" + myDate.getDate() ; + this.nextDate = (myDate.getFullYear()+100)+ "-" +(myDate.getMonth() + 1) + "-" + myDate.getDate() ; + + } + ngOnInit() { + if(this.keyword !=null && this.keyword.length > 0){ + this.search(false); + } +} + + + page : number = 1; + size:number = 5; + navigateTo: string = "Search"; + source: string = "datacite"; + type : string = "dataset"; + showSearchResults:boolean=false; + // searchType ="publication"; + @Input() public select:boolean = true ; + @Input() public keyword:string = ''; + @Input() public selectedResults:ClaimResult[]; + // @Output() datasetsChange = new EventEmitter(); + // @Output() publicationsChange = new EventEmitter(); + + // @Output() resultsChange = new EventEmitter(); + + public errorCodes:ErrorCodes = new ErrorCodes(); + + dataciteResults=[]; + dataciteResultsNum:number = null; + // dataciteResultsNum : Observable = null; + dataciteStatus = this.errorCodes.NONE; + datacitePage : number = 1; + + openaireData=[]; + openaireDataNum:number = 0 ; + openaireDataStatus = this.errorCodes.NONE; + openaireDataPage : number = 1; + + public warningMessage = ""; + public infoMessage = ""; + + public todayDate = ''; + public nextDate = ''; + public DOIs:string[] = []; + sub: any; + public searchSource:string = "openaire" + public activeTab:string = "openairePub" + + + crossrefResults=[]; + crossrefResultsNum : number = null; + crossrefPage : number = 1; + crossrefStatus:number = this.errorCodes.NONE; + + openairePubs = []; + openairePubsNum: number ; + openairePubsPage : number = 1; + openairePubsStatus:number = this.errorCodes.NONE; + + orcidResults: string[]; + orcidResultsNum: number ; + totalPages: number; + orcidResultsToShow: string[]; + orcidPage : number = 1; + orcidStatus:number = this.errorCodes.NONE; + authorId: string; + selectAuthorId: string = "0"; + authorGivenName: string; + authorFamilyName: string; + + authorIds: string[]; + authorGivenNames: string[]; + authorFamilyNames: string[]; + + authorsNum : number ; + + reloadOpenaire:boolean = true; + reloadCrossref:boolean = false; + reloadDatacite:boolean = false; + reloadOrcid:boolean = false; + + + + + search(sourceChanged){ + this.warningMessage = ""; + this.infoMessage = ""; + if(!sourceChanged){ + this.DOIs = DOI.getDOIsFromString(this.keyword); + this.reloadOpenaire = true; + this.reloadCrossref = true; + this.reloadDatacite = true; + this.reloadOrcid = true; + } + if((this.searchSource == "all" || this.searchSource == "openaire") && this.reloadOpenaire){ + this.searchOpenairePubs(this.keyword, this.size, 1); + this.searchOpenaireData(this.keyword,this.size,1); + this.reloadOpenaire = false; + } + if((this.searchSource == "all" || this.searchSource == "crossref")&&this.reloadCrossref){ + this.getCrossrefResults(this.keyword, this.size,1); + this.reloadCrossref = false; + } + if((this.searchSource == "all" || this.searchSource == "datacite")&& this.reloadDatacite){ + this.searchDatacite(this.keyword,this.size,1); + this.reloadDatacite = false; + } + if((this.searchSource == "all" || this.searchSource == "orcid")&& this.reloadOrcid){ + this.searchOrcid(this.keyword); + this.reloadOrcid = false; + } + this.showSearchResults = true; + + } + +private getCrossrefResults (term: string, size : number, page : number) { + this.crossrefStatus = this.errorCodes.LOADING; + if( this.DOIs.length > 0 ){ + this._searchCrossrefService.searchCrossrefByDOIs(this.DOIs).subscribe( + data => { + if(data != null) { + this.crossrefResults = data.items; + this.crossrefPage=page; + this.crossrefResultsNum = data['total-results']; + if(data.items == 0){ + this._searchCrossrefService.searchCrossrefResults(term, size, page).subscribe( + data => { + if(data != null) { + this.crossrefResults = data.items; + this.crossrefPage=page; + this.crossrefResultsNum = data['total-results']; + this.crossrefStatus = this.errorCodes.DONE; + + }else{ + this.crossrefStatus = this.errorCodes.ERROR; + } + }, + err =>{ + console.log(err.status); + this.crossrefStatus = this.errorCodes.ERROR; + } + + ); + }else{ + this.crossrefStatus = this.errorCodes.DONE; + } + } + }, + err => { + //console.log(err); + this._searchCrossrefService.searchCrossrefResults(term, size, page).subscribe( + data => { + this.crossrefResults = data.items; + this.crossrefPage=page; + this.crossrefResultsNum = data['total-results']; + this.crossrefStatus = this.errorCodes.DONE; + + }, + err => { + console.log(err.status); + this.crossrefStatus = this.errorCodes.ERROR; + } + + ); + } + ); + + }else{ + + + this._searchCrossrefService.searchCrossrefResults(term, size, page).subscribe( + data => { + if(data != null) { + this.crossrefResults = data.items; + this.crossrefPage=page; + this.crossrefResultsNum = data['total-results']; + this.crossrefStatus = this.errorCodes.DONE; + + }else{ + this.crossrefStatus = this.errorCodes.ERROR; + } + + }, + err => { + console.log(err.status); + this.crossrefStatus = this.errorCodes.ERROR; + } + ); + } + } + private searchOpenairePubs(term: string, size : number, page : number) { + + if(this.DOIs.length > 0 ){ + this.openairePubsStatus = this.errorCodes.LOADING; + this._searchPublicationsService.searchPublicationsByDois(this.DOIs, null, page, size, []).subscribe( + data => { + if(data != null) { + this.openairePubsPage=page; + this.openairePubsNum = data[0]; + this.openairePubs = data[1]; + this.openairePubsStatus = this.errorCodes.DONE; + if(this.openairePubsNum == 0){ + this.openairePubsStatus = this.errorCodes.NONE; + } + }else { + this.openairePubsStatus = this.errorCodes.ERROR; + } + }, + err => { + this.openairePubsStatus = this.errorCodes.ERROR; + console.log(err.status); + } + ); + }else{ + this.openairePubsStatus = this.errorCodes.LOADING; + this._searchPublicationsService.searchPublications('q='+term, null, page, size, []).subscribe( + data => { + if(data != null) { + this.openairePubsPage=page; + this.openairePubsNum = data[0]; + this.openairePubs = data[1]; + this.openairePubsStatus = this.errorCodes.DONE; + if(this.openairePubsNum == 0){ + this.openairePubsStatus = this.errorCodes.NONE; + } + }else { + this.openairePubsStatus = this.errorCodes.ERROR; + } + }, + err => { + this.openairePubsStatus = this.errorCodes.ERROR; + console.log(err.status); + } + ); + } + } + + private searchOrcid (term: string) { + if(this.DOIs.length > 0){ + this.orcidStatus = this.errorCodes.NONE; + return; + } + this.orcidStatus = this.errorCodes.LOADING; + this.authorIds = new Array(); + this.authorGivenNames = new Array(); + this.authorFamilyNames = new Array(); + + this.getOrcidAuthor(term); + + console.info('searchOrcid in searchOrcid file'); + } + + private readData(data: any) { + this.authorIds.push(data[2].path); + + if(data[0] != null) { + this.authorGivenNames.push(data[0].value); + } else { + this.authorGivenNames.push(""); + } + if(data[1] != null) { + this.authorFamilyNames.push(data[1].value); + } else { + this.authorFamilyNames.push(""); + } + } + + private getOrcidAuthor (term: string) { + this.orcidResultsNum = null; + + //passing structures in order to fill them in service + this._searchOrcidService.searchOrcidAuthor(term, this.authorIds, + this.authorGivenNames, this.authorFamilyNames).subscribe( + data => { + if(data != null && data == true) { + this.getOrcidResultsByIndex(0); + } + + this.orcidStatus = this.errorCodes.NONE; + + }, + err => this.errorHandler(err, term) + + ); + } + + private errorHandler(err: any, term: string) { + if(err.status == 404){ + this.getOrcidAuthors(term); + } else { + this.orcidStatus = this.errorCodes.ERROR; + console.log(err.status); + + } + } + + private getOrcidAuthors (term: string) { + this.orcidResultsNum = null; + this.selectAuthorId = "0"; + this.orcidStatus = this.errorCodes.LOADING; + //passing structures in order to fill them in service + this._searchOrcidService.searchOrcidAuthors(term, this.authorIds, + this.authorGivenNames, this.authorFamilyNames).subscribe( + data => { + if(data != null && data == true) { + this.getOrcidResultsByIndex(0); + }else{ + this.orcidStatus = this.errorCodes.ERROR; + } + + }, + err => { + this.orcidStatus = this.errorCodes.ERROR; + console.log(err.status); + } + ); + } + + + private getOrcidResultsByIndex (index:number) { + if(this.authorIds.length > index) { + this.orcidStatus = this.errorCodes.LOADING; + let id = this.authorIds[index]; + this.authorGivenName = this.authorGivenNames[index]; + this.authorFamilyName = this.authorFamilyNames[index]; + this.getOrcidResultsById(id); + } + } + private getOrcidResultsById (id:string) { + if(id=="0"){ + return; + } + var index = this.authorIds.indexOf(id); + this.authorGivenName = this.authorGivenNames[index]; + this.authorFamilyName = this.authorFamilyNames[index]; + this.authorId = id; + console.info("getOrcidResultsById: "+id); + this.orcidStatus = this.errorCodes.LOADING; + this._searchOrcidService.searchOrcidPublications(id).subscribe( + data => { + if(data != null) { + this.orcidResults=data['orcid-work']; + this.orcidResultsNum = data['orcid-work'].length; + this.orcidPage = 1; + if((this.orcidResultsNum % this.size) == 0){ + this.totalPages=parseInt(''+(this.orcidResultsNum/this.size)); + } else{ + this.totalPages=parseInt(''+(this.orcidResultsNum/this.size+1)); + } + + this.orcidResultsToShow = this.orcidResults.slice(0,10); + + this.orcidStatus = this.errorCodes.DONE; + if(this.orcidResultsNum == 0){ + this.orcidStatus = this.errorCodes.NONE; + } + } else { + this.orcidResultsNum = 0; + this.totalPages=0; + this.orcidStatus = this.errorCodes.NONE; + } + + }, + err => { + console.log(err.status); + this.orcidStatus = this.errorCodes.ERROR; + } + ); + + + } + +/* +Is it USED??? +private remove(item){ + this.warningMessage = ""; + this.infoMessage = ""; + var index:number =this.selectedResults.indexOf(item); + item.selected=false; + if (index > -1) { + this.selectedResults.splice(index, 1); + // this.publicationsChange.emit({ + // value: this.selectedResults + // }); + } + + }*/ +private crossrefPageChange($event) { + this.crossrefPage=$event.value; + this.crossrefResults=[]; + console.log("Crossref chaenged "+this.crossrefPage); + this.getCrossrefResults(this.keyword,this.size,this.crossrefPage); +} +private orcidPageChange($event) { + this.orcidPage=$event.value; + this.orcidResultsToShow=[]; + this.orcidResultsToShow = this.orcidResults.slice(($event.value-1)*this.size, $event.value*this.size); +} +private openairePubsPageChange($event) { + this.openairePubsPage=$event.value; + this.searchOpenairePubs(this.keyword,this.size,this.openairePubsPage); +} +datacitePageChange($event) { + this.datacitePage=$event.value; + this.dataciteResults=[]; + this.searchDatacite(this.keyword,10,this.datacitePage); + this.warningMessage = ""; + this.infoMessage = ""; + +} +openaireDataPageChange($event) { + this.openaireDataPage=$event.value; + this.openaireData=[]; + this.searchOpenaireData(this.keyword,10,this.openaireDataPage); + this.warningMessage = ""; + this.infoMessage = ""; + +} + + + private isSelected(id:string){ + + var found:boolean = false; + this.warningMessage = ""; + for (var _i = 0; _i < this.selectedResults.length; _i++) { + let item = this.selectedResults[_i]; + if(item.id == id){ + found=true; + this.warningMessage = "Publication already in selected list"; + } + } + return found; + + + } + // isSelected(id:string){ + // + // var found:boolean = false; + // this.warningMessage = ""; + // for (var _i = 0; _i < this.selectedResults.length; _i++) { + // let item = this.selectedResults[_i]; + // if(item.id == id){ + // found=true; + // break; + // } + // } + // return found; + // } + private searchDatacite (term: string, size : number, page : number) { + this.getDataciteResults(term,size,page); + this.warningMessage = ""; + this.infoMessage = ""; + + } + private searchOpenaireData (term: string, size : number, page : number) { + if(this.DOIs.length > 0 ){ + this.openaireDataStatus = this.errorCodes.LOADING; + this._searchDatasetsService.searchDatasetsByDois(this.DOIs, null, page, size, []).subscribe( + data => { + if(data != null) { + this.openaireDataPage=page; + this.openaireDataNum = data[0]; + this.openaireData = data[1]; + this.openaireDataStatus = this.errorCodes.DONE; + if(this.openaireDataNum == 0){ + this.openaireDataStatus = this.errorCodes.NONE; + } + } + }, + err => { + this.openaireDataStatus = this.errorCodes.ERROR; + console.log(err.status); + } + ); + }else{ + this._searchDatasetsService.searchDatasets('q='+term+'', null, page, size, []).subscribe( + data => { + if(data != null) { + this.openaireDataPage=page; + this.openaireDataNum = data[0]; + this.openaireData = data[1]; + this.openaireDataStatus = this.errorCodes.DONE; + if(this.openaireDataNum == 0){ + this.openaireDataStatus = this.errorCodes.NONE; + } + } + }, + err => { + this.openaireDataStatus = this.errorCodes.ERROR; + console.log(err.status); + } + ); + } + this.warningMessage = ""; + this.infoMessage = ""; + + } + private getDataciteResults (term: string, size : number, page : number) { + this._searchDataciteService.searchDataciteResults(term, size, page).subscribe( + data => { + this.dataciteResults = data.data; + this.datacitePage=page; + this.dataciteResultsNum = data.meta.total; + this.dataciteStatus = this.errorCodes.DONE; + + + }, + err => { + this.dataciteStatus = this.errorCodes.ERROR; + console.log(err); + } + + ); + } + + add(item, itemId,itemSource,itemType, itemUrl, itemTitle, date, accessmode){ + + console.log(' adding ' + itemType + " From " + itemSource+" "+ itemTitle); + var result: ClaimResult = ClaimResult.generateResult(item, itemId,itemSource,itemType, itemUrl, itemTitle, date, accessmode); + + + if (itemSource == 'orcid'){ + if(result.authors.length ==0 ){ + result.authors.push(this.authorGivenName + ', '+ this.authorFamilyName); + } + } + var found:boolean = this.isSelected( result.id); + + this.warningMessage = ""; + if (!found) { + this.selectedResults.push(result); + + UIkit.notification({ + message : 'A new research result is selected.', + status : 'info', + timeout : 1000, + pos : 'top-center' + }); + + + }else{ + this.warningMessage = "Research Data already in selected list"; + UIkit.notification({ + message : 'The research result is already on your list.', + status : 'warning', + timeout : 1000, + pos : 'top-center' + }); + } + + } + + public searchSourceChanged(source){ + this.searchSource = source; + this.activeTab = (source == "openaire" || source == "all")?"openairePub":source; + if(this.keyword && this.keyword.length > 0){ + this.search(true); + } + } + public clickTab(tab){ + this.activeTab = tab; + } +} diff --git a/portal-4cli/src/app/claims/claim-utils/claimResultSearchForm.module.ts b/portal-4cli/src/app/claims/claim-utils/claimResultSearchForm.module.ts new file mode 100644 index 00000000..201c91b2 --- /dev/null +++ b/portal-4cli/src/app/claims/claim-utils/claimResultSearchForm.module.ts @@ -0,0 +1,29 @@ +import { NgModule } from '@angular/core'; + +import { SharedModule } from '../../shared/shared.module'; +import { CommonModule } from '@angular/common'; +import {ClaimResultSearchFormComponent} from './claimResultSearchForm.component'; + +import {SearchDataciteServiceModule} from './service/searchDataciteService.module'; + +import {SearchCrossrefServiceModule} from './service/searchCrossrefService.module'; +import {SearchOrcidService} from './service/searchOrcid.service'; + +import {PublicationsServiceModule} from '../../services/publicationsService.module'; +import {DatasetsServiceModule} from '../../services/datasetsService.module'; +import {PagingModule } from '../../utils/paging.module'; + + @NgModule({ + imports: [ + SharedModule, CommonModule, PublicationsServiceModule, DatasetsServiceModule, PagingModule, SearchCrossrefServiceModule, SearchDataciteServiceModule + ], + providers:[ + SearchOrcidService + ], + declarations: [ + ClaimResultSearchFormComponent + + ], + exports: [ClaimResultSearchFormComponent ] +}) +export class ClaimResultSearchFormModule { } diff --git a/portal-4cli/src/app/claims/claim-utils/displayClaims/displayClaims.component.html b/portal-4cli/src/app/claims/claim-utils/displayClaims/displayClaims.component.html new file mode 100644 index 00000000..7a64cc39 --- /dev/null +++ b/portal-4cli/src/app/claims/claim-utils/displayClaims/displayClaims.component.html @@ -0,0 +1,110 @@ + +
+ +
+
+ +
+
+ + +
+ Filter By: +
+
+ + + + +
+ +
+
+ +
+ +
+ +
+ Show + + + Showing {{(size*page - size +1)}} to {{(size*page>resultsNum)?resultsNum:(size*page)}} of {{resultsNum}} claims + +
+
+ + +
+ An Error occured. +
+
+ You are not allowed to access this page. +
+
+ User session is not valid. Please login again. +
+ + + +
+
+
+ You have selected {{selected.length}} claim(s) +
+
+
+ +
+ +
+
+ + +
+
No entries found.
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
Research Result Link to Claimed by Claimed Date
{{claim.userMail}}{{claim.date}}
+
+ +
+ + + + diff --git a/portal-4cli/src/app/claims/claim-utils/displayClaims/displayClaims.component.ts b/portal-4cli/src/app/claims/claim-utils/displayClaims/displayClaims.component.ts new file mode 100644 index 00000000..26cacfb7 --- /dev/null +++ b/portal-4cli/src/app/claims/claim-utils/displayClaims/displayClaims.component.ts @@ -0,0 +1,486 @@ +import {Component, ViewChild, Input} from '@angular/core'; +import {Location} from '@angular/common'; +import {Observable} from 'rxjs/Observable'; +import {ActivatedRoute, Router} from '@angular/router'; +import {ClaimsService} from '../service/claims.service'; +import {ModalLoading} from '../../../utils/modal/loading.component'; +import {AlertModal} from '../../../utils/modal/alert'; +import {Session} from '../../../login/utils/helper.class'; + + +@Component({ + selector: 'displayClaims', + templateUrl: 'displayClaims.component.html', + providers:[ ClaimsService] + +}) +export class DisplayClaimsComponent { + constructor (private _claimService: ClaimsService, private route: ActivatedRoute, private _router:Router, private location: Location) { + } + + ngOnInit() { + this.sub = this.route.queryParams.subscribe(params => { + if( this.myClaims){ + this.fetchBy = "User"; + this.fetchId = Session.getUserEmail(); + }else{ + + this.fetchBy = params['fetchBy']; + this.fetchBy = (this.types.indexOf(this.fetchBy) != -1)? this.fetchBy:'All'; + this.fetchId = params['fetchId']; + this.fetchId = this.fetchId?this.fetchId:''; + + } + + let page = (params['page']=== undefined)?1:+params['page']; + let size = (params['size']=== undefined)?10:+params['size']; + + this.keyword = (params['keyword']?params['keyword']:""); + this.inputkeyword = this.keyword; + this.page = ( page <= 0 ) ? 1 : page; + this.size = ( size <= 0 ) ? 10 : size; + this.entityTypes = []//(params['types']?params['types']:[]); + this.setTypes(params['types']); // check the appropriate checkboxes + this.setSortby(params['sort']); + this.getClaims(); + + }); + + } + ngOnDestroy() { + this.sub.unsubscribe(); + } + sub: any; + //string because comes as input from component directive + @Input() enableDelete: boolean = false; + @Input() showUserEmail: boolean = true; + @Input() myClaims: boolean= false ; + @Input() isAdmin:boolean = false; + page : number; + size:number; + sizes = [10,20,30,50]; + keyword:string; // the keyword string to give to the request as parameter + inputkeyword:string; // the string written in the input field (keyword=inputkeyword when its length is bigger than 3 and the user stops typing) + lengths = [10,20,30,50]; + types = ["All","Project","Context","Result","User"]; + @Input() fetchBy:string; + @Input() fetchId:string; + + navigateTo: string = "Claims"; + resultsNum: number ; + claims: string[]; + + @ViewChild (ModalLoading) loading : ModalLoading ; + + //checkboxes: + publicationCB = false; + datasetCB = false; + contextCB = false; + projectCB = false; + entityTypes : string[] =[] ; + + descending = true; + sortby = "date"; + + selected=[]; + deleteMessage:string = ""; + showErrorMessage:boolean = false; + showForbiddenMessage:boolean = false; + userValidMessage:string = ""; + + //params for pagingFormatter to use when navigate to page + params; + @ViewChild(AlertModal) alert; + + claimsDeleted:number = 0; + + getClaims () { + if(!Session.isValidAndRemove()){ + this.userValidMessage = "User session has expired. Please login again."; + + }else{ + var token=Session.getUserJwt(); + this.selected=[]; + var types = ''; + this.showErrorMessage = false; + this.showForbiddenMessage = false; + for (var type of this.entityTypes){ + types+=(types.length>0?'&':'')+"types="+type; + } + if(this.fetchBy =="Project" ){ + this._claimService.getClaimsByProject(this.size,this.page,this.fetchId,this.keyword,this.sortby,this.descending, types).subscribe( + data => { + this.claims = data.data; + this.resultsNum= data.total; + }, + err => { + this.handleErrors(err); + } + ); + }else if(this.fetchBy =="User"){ + this._claimService.getClaimsByUser(this.size,this.page,this.fetchId,this.keyword,this.sortby,this.descending, types).subscribe( + data => { + this.claims = data.data; + this.resultsNum= data.total; + }, + err => { + this.handleErrors(err); + } + ); + }else if(this.fetchBy =="Result"){ + this._claimService.getClaimsByResult(this.size,this.page,this.fetchId,this.keyword,this.sortby,this.descending, types).subscribe( + data => { + this.claims = data.data; + this.resultsNum= data.total; + }, + err => { + this.handleErrors(err); + } + ); + }else if(this.fetchBy =="Context"){ + this._claimService.getClaimsBycontext(this.size,this.page,this.fetchId,this.keyword,this.sortby,this.descending, types).subscribe( + data => { + this.claims = data.data; + this.resultsNum= null; + this.resultsNum= data.total;//data.length; //TODO get the total results num + }, + err => { + this.handleErrors(err); + } + ); + }else{ + this._claimService.getClaims(this.size,this.page,this.keyword,this.sortby,this.descending, types).subscribe( + data => { + this.claims = data.data; + this.resultsNum = null; + this.resultsNum= data.total;//data.length; //TODO get the total results num + }, + err => { + this.handleErrors(err); + } + ); + } + } +} +handleErrors(err){ + + this.showErrorMessage = true; + try{ + var error = err.json() + var code = error.code; + if(code == 403){ + this.showErrorMessage = false; + this.showForbiddenMessage = true; + } + }catch (e) { + console.log("Couldn't parse answer as json") + this.showErrorMessage = true; + } + +} + + goTo(page:number = 1){ + + this.page = page; + + this.location.go(location.pathname,this.getParametersString()); + this.getClaims(); + } + getParameters(){ + var params = {} + if(this.myClaims){ + params={ page: this.page, size: this.size, types: this.entityTypes, keyword : this.keyword, sort: this.getSortby() }; + }else{ + params={ page: this.page, size: this.size, types: this.entityTypes, fetchBy: this.fetchBy, fetchId:this.fetchId, keyword : this.keyword, sort: this.getSortby() }; + } + return params; + } + + getParametersString(){ + var params=''; + params+=(this.page==1?"":(params.length>0?'&':'')+"page="+this.page); + params+=(this.size==10?"":(params.length>0?'&':'')+"size="+this.size); + // params+=(this.entityTypes==''?"":(params.length>0?'&':'')+"types="+this.entityTypes); + var types=""; + for (var type of this.entityTypes){ + types+=(types.length>0?',':'')+type; + } + params+=(types.length>0)?"types="+types:""; + + if(this.isAdmin ){ + params+=(this.fetchBy=='All'?"":(params.length>0?'&':'')+"fetchBy="+this.fetchBy); + params+=(this.fetchId==''?"":(params.length>0?'&':'')+"fetchId="+this.fetchId); + } + params+=(this. getSortby()=='datedesc'?"":(params.length>0?'&':'')+"sort="+this. getSortby()); + params+=(this.keyword==''?"":(params.length>0?'&':'')+"keyword="+this.keyword); + return params; + } + changeSize(size: number ){ + this.goTo(); + } + + clearFilters(){ + this.keyword = ''; + this.inputkeyword = ''; + this.publicationCB = false; + this.projectCB = false; + this.datasetCB = false; + this.contextCB = false; + this.entityTypes = []; + this.goTo(); + } + + changeOrderby(sortby:string){ + if(sortby==this.sortby){ + this.descending = !this.descending; + }else{ + this.sortby = sortby; + this.descending = false; + } + this.goTo(); + } + setSortby(sortby:string){ + if(!sortby|| sortby == "datedesc"){ + this.descending = true; + this.sortby = "date"; + }else if(sortby == "dateasc"){ + this.descending = false; + this.sortby = "date"; + }else if(sortby == "userasc"){ + this.descending = false; + this.sortby = "user"; + }else if(sortby == "userdesc"){ + this.descending = true; + this.sortby = "user"; + }if(sortby =="sourceasc"){ + this.descending = false; + this.sortby = "source"; + }else if(sortby == "sourcedesc"){ + this.descending = true; + this.sortby = "source"; + }else if(sortby == "targetasc"){ + this.descending = false; + this.sortby = "target"; + }else if(sortby == "targetdesc"){ + this.descending = true; + this.sortby = "target"; + } + } + getSortby():string{ + if(this.descending){ + return this.sortby+"desc"; + }else{ + return this.sortby+"asc"; + } + + } + changeType(){ + this.entityTypes = []; + if(this.publicationCB){ + this.entityTypes.push('publication'); + } + if(this.datasetCB){ + this.entityTypes.push('dataset'); + } + if(this.projectCB){ + this.entityTypes.push('project'); + } + if(this.contextCB){ + this.entityTypes.push('context'); + } + + this.goTo(); + } + setTypes(types:string){ + if(!types){ + return; + } + if(types.length > 0){ + this.entityTypes = []; + if(types.indexOf("publication")!=-1){ + this.publicationCB = true; + this.entityTypes.push("publication"); + } + if(types.indexOf("dataset")!=-1){ + this.datasetCB = true; + this.entityTypes.push("dataset"); + } + if(types.indexOf("project")!=-1){ + this.projectCB = true; + this.entityTypes.push("project"); + } + if(types.indexOf("context")!=-1){ + this.contextCB = true; + this.entityTypes.push("context"); + } + } + if(this.publicationCB && this.datasetCB && this.contextCB && this.projectCB){ + this.entityTypes=[]; + } + } + changekeyword(){ + + if(this.inputkeyword.length >= 3 || this.inputkeyword.length == 0 ){ + this.keyword = this.inputkeyword; + this.page = 1; + this.goTo(); + } + + } + select(item:any,event){ + this.deleteMessage=""; + var value = event.currentTarget.checked; + if(value){ + this.selected.push(item); + }else{ + for (var _i = 0; _i < this.selected.length; _i++) { + let claim = this.selected[_i]; + if(claim['id'] == item.id){ + this.selected.splice(_i, 1); + } + } + + + } + } + selectAll(event){ + var value = event.currentTarget.checked; + if(value){ + this.selected = []; + for (var _i = 0; _i < this.claims.length; _i++) { + let claim = this.claims[_i]; + this.selected.push(claim); + } + this.deleteMessage = ""; + }else{ + this.selected = []; + this.deleteMessage=""; + } + } + + isSelected(id:string){ + for (var _i = 0; _i < this.selected.length; _i++) { + let claim = this.selected[_i]; + if(claim['id'] == id){ + return true; + } + } + return false; + } + + + confirmOpen(){ + if(this.selected.length <= 0){ + + }else{ + this.alert.cancelButton = true; + this.alert.okButton = true; + this.alert.alertTitle = "Delete "+this.selected.length+" claim(s)"; + this.alert.message = this.selected.length+" claims will be deleted. Do you want to proceed? "; + this.alert.okButtonText = "Yes"; + this.alert.cancelButtonText = "No"; + this.alert.open(); + } + } + confirmClose(data){ + this.delete(); + } + delete(){ + this.deleteMessage=""; + this.loading.open(); + this.claimsDeleted = 0; + var ids = []; + for (var i = 0; i < this.selected.length; i++){ + var id =this.selected[i].id; + ids.push(id); + // var selected =this.selected[i].id; + // console.warn("Deleting claim with id:"+id); + // this.deleteById(id); + //TODO for multiple concurrent + } + this.batchDeleteById(ids); + } + + deleteById(id:string){ + if(!Session.isValidAndRemove()){ + this.userValidMessage = "User session has expired. Please login again."; + + }else{ + var token=Session.getUserJwt(); + console.log("Deleting claim with id:"+id); + // this._claimService.deleteClaimById(id); + this._claimService.deleteClaimById(id).subscribe( + res => { + console.log('Delete response'+res.code ); + console.log("Deleted claim with id:"+ id); + //remove this claim from the + let newClaims=this.claims; + for (var _i = 0; _i < this.claims.length; _i++) { + let claim = this.claims[_i]; + if(claim['id'] == id){ + newClaims.splice(_i, 1); + } + } + //TODO should call getClaims??? + this.claimsDeleted++; + this.claims = newClaims; + if(this.claimsDeleted == this.selected.length){ + this.resultsNum = this.resultsNum - this.selected.length; + this.loading.close(); + this.selected = []; + } + + + }); + } + } + batchDeleteById(ids:string[]){ + if(!Session.isValidAndRemove()){ + this.userValidMessage = "User session has expired. Please login again."; + + }else{ + var token=Session.getUserJwt(); + console.warn("Deleting claim with ids:"+ids); + this._claimService.deleteBulk(ids).subscribe( + res => { + console.info('Delete response'+res.code ); + console.warn("Deleted ids:"+ res.deletedIds); + console.warn("Not found ids:"+ res.notFoundIds); + //remove this claim from the + let newClaims=this.claims; + for(var id of res.deletedIds){ + for (var _i = 0; _i < this.claims.length; _i++) { + let claim = this.claims[_i]; + if(claim['id'] == id){ + newClaims.splice(_i, 1); + } + } + for (var _i = 0; _i < this.selected.length; _i++) { + let claim = this.selected[_i]; + if(claim['id'] == id){ + this.selected.splice(_i, 1); + } + } + } + this.claims = newClaims; + this.resultsNum = this.resultsNum - res.deletedIds.length; + this.loading.close(); + if(res.deletedIds.length>0){ + this.deleteMessage=this.deleteMessage+'
'+res.deletedIds.length+' claim(s) successfully deleted.
'; + } + if(res.notFoundIds.length>0){ + this.deleteMessage=this.deleteMessage+'
'+res.notFoundIds.length+' claim(s) couldn\'t be deleted.
'; + } + }, err => { + console.log(err); + this.showErrorMessage = true; + this.loading.close(); + + }); + } + } + pageChange($event) { + var page:number = +$event.value + this.goTo(page); + } +} diff --git a/portal-4cli/src/app/claims/claim-utils/displayClaims/displayClaims.module.ts b/portal-4cli/src/app/claims/claim-utils/displayClaims/displayClaims.module.ts new file mode 100644 index 00000000..4c8e0bb0 --- /dev/null +++ b/portal-4cli/src/app/claims/claim-utils/displayClaims/displayClaims.module.ts @@ -0,0 +1,26 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import {ClaimServiceModule} from '../service/claimsService.module'; +import {DisplayClaimsComponent} from './displayClaims.component'; +import {LoadingModalModule} from '../../../utils/modal/loadingModal.module'; +import {AlertModalModule} from '../../../utils/modal/alertModal.module'; +import {ClaimEntityFormatterModule} from '../entityFormatter/claimEntityFormatter.module'; +import {PagingModule } from '../../../utils/paging.module'; +import {HelperModule} from '../../../utils/helper/helper.module'; + + @NgModule({ + imports: [ + CommonModule, FormsModule, ClaimServiceModule, LoadingModalModule, AlertModalModule, +ClaimEntityFormatterModule, PagingModule, HelperModule + + ], + declarations: [ + DisplayClaimsComponent + + ], + exports: [ + DisplayClaimsComponent + ] +}) +export class DisplayClaimsModule { } diff --git a/portal-4cli/src/app/claims/claim-utils/entityFormatter/claimEntityFormatter.component.ts b/portal-4cli/src/app/claims/claim-utils/entityFormatter/claimEntityFormatter.component.ts new file mode 100644 index 00000000..5055b32f --- /dev/null +++ b/portal-4cli/src/app/claims/claim-utils/entityFormatter/claimEntityFormatter.component.ts @@ -0,0 +1,39 @@ +import {Component, Input} from '@angular/core'; + +//Usage Example " " + +//externalUrl +@Component({ + selector: 'claim-entity', + template: ` +
+ + +
+
+ + +
+
+ + +
+
+ + {{entity.title}} +
+ ` +}) + +export class ClaimEntityFormatter { + @Input() entity: string[]; + @Input() type: string; + + constructor () {} + + ngOnInit() { + + } + + +} diff --git a/portal-4cli/src/app/claims/claim-utils/entityFormatter/claimEntityFormatter.module.ts b/portal-4cli/src/app/claims/claim-utils/entityFormatter/claimEntityFormatter.module.ts new file mode 100644 index 00000000..01a1d0ac --- /dev/null +++ b/portal-4cli/src/app/claims/claim-utils/entityFormatter/claimEntityFormatter.module.ts @@ -0,0 +1,24 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import {ProjectTitleFormatter} from './projectTitleFormatter.component'; +import {PublicationTitleFormatter} from './publicationTitleFormatter.component'; +import {ClaimEntityFormatter} from './claimEntityFormatter.component'; + + @NgModule({ + imports: [ + CommonModule, RouterModule + ], + declarations: [ + ProjectTitleFormatter, PublicationTitleFormatter, ClaimEntityFormatter + + ], + providers: [ ], + exports: [ + ProjectTitleFormatter, PublicationTitleFormatter, ClaimEntityFormatter + + ] +}) +export class ClaimEntityFormatterModule { } diff --git a/portal-4cli/src/app/claims/claim-utils/entityFormatter/projectTitleFormatter.component.ts b/portal-4cli/src/app/claims/claim-utils/entityFormatter/projectTitleFormatter.component.ts new file mode 100644 index 00000000..b1b95aa1 --- /dev/null +++ b/portal-4cli/src/app/claims/claim-utils/entityFormatter/projectTitleFormatter.component.ts @@ -0,0 +1,25 @@ +import {Component, Input} from '@angular/core'; +import {OpenaireProperties} from '../../../utils/properties/openaireProperties'; +import {RouterHelper} from '../../../utils/routerHelper.class'; + +//Usage Example " " + +@Component({ + selector: 'project-title', + template: ` + + {{project['name']}} ({{project['funderName']}}) + + ` +}) + +export class ProjectTitleFormatter { + @Input() project: string[]; + public url:string; + public routerHelper:RouterHelper = new RouterHelper(); + constructor () {} + + ngOnInit() { + this.url = OpenaireProperties.getsearchLinkToProject() + "?projectId=" + this.project["openaireId"]; + } +} diff --git a/portal-4cli/src/app/claims/claim-utils/entityFormatter/publicationTitleFormatter.component.ts b/portal-4cli/src/app/claims/claim-utils/entityFormatter/publicationTitleFormatter.component.ts new file mode 100644 index 00000000..321e440d --- /dev/null +++ b/portal-4cli/src/app/claims/claim-utils/entityFormatter/publicationTitleFormatter.component.ts @@ -0,0 +1,26 @@ +import {Component, Input} from '@angular/core'; + +//Usage Example " " + +@Component({ + selector: 'publication-title', + template: ` + + {{title}} + {{title}} + + ` +}) + +export class PublicationTitleFormatter { + @Input() title: string[]; + @Input() url: string[]; + + constructor () {} + + ngOnInit() { + + } + + +} diff --git a/portal-4cli/src/app/claims/claim-utils/service/claims.service.ts b/portal-4cli/src/app/claims/claim-utils/service/claims.service.ts new file mode 100644 index 00000000..58ce364c --- /dev/null +++ b/portal-4cli/src/app/claims/claim-utils/service/claims.service.ts @@ -0,0 +1,148 @@ +import {Injectable} from '@angular/core'; +import {URLSearchParams } from '@angular/http'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +// import {Claim} from '../claim'; +import {OpenaireProperties} from '../../../utils/properties/openaireProperties'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; +import { } from '../../../shared/cache.service'; +import { CustomOptions } from './customOptions.class'; +@Injectable() +export class ClaimsService { + private baseUrl; + constructor(private http: Http ) { + this.baseUrl = OpenaireProperties.getClaimsAPIURL(); + } + + private getClaimRequest(size : number, page : number, url :string, fromCache:boolean):any { + console.info('ClaimsService: Claims request: '+url); + let key = url; + return this.http.get((fromCache && OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url, CustomOptions.getAuthOptions()) + .map(request => request.json()) + .do(request => console.info("Get claims: offset = "+(size*(page-1)) + " limit ="+size )) + .catch(this.handleError); + } + getClaims( size : number, page : number, keyword:string, sortby: string, descending: boolean, types: string):any { + console.info('ClaimsService: getClaims ' ); + console.info('ClaimsService: Types : '+types ); + let url = this.baseUrl +"claims"+"?offset="+(size*(page-1) + "&limit="+size)+"&keyword="+keyword+"&sortby="+sortby+"&descending="+descending+"&"+types; + return this.getClaimRequest(size,page,url,true); + + } + getClaimsByUser( size : number, page : number, user:string, keyword:string, sortby: string, descending: boolean, types: string):any { + console.info('ClaimsService: getClaims for user : '+user); + let url = this.baseUrl +"users/claims"+"?offset="+(size*(page-1) + "&limit="+size)+"&keyword="+keyword+"&sortby="+sortby+"&descending="+descending+"&"+types; + return this.getClaimRequest(size,page,url,false); + + } + getClaimsBycontext( size : number, page : number, contextId:string, keyword:string, sortby: string, descending: boolean, types: string ):any { + console.info('ClaimsService: getClaims for context : '+contextId); + let url = this.baseUrl +"contexts/"+contextId+"/claims"+"?offset="+(size*(page-1) + "&limit="+size)+"&keyword="+keyword+"&sortby="+sortby+"&descending="+descending+"&"+types; + return this.getClaimRequest(size,page,url,true); + + } + getClaimsByResult( size : number, page : number, resultId:string, keyword:string, sortby: string, descending: boolean, types: string ):any { + console.info('ClaimsService: getClaims for result : '+resultId); + let url = this.baseUrl +"results/"+resultId+"/claims"+"?offset="+(size*(page-1) + "&limit="+size)+"&keyword="+keyword+"&sortby="+sortby+"&descending="+descending+"&"+types; + return this.getClaimRequest(size,page,url,true); + + } + getClaimsByProject( size : number, page : number, projectId:string, keyword:string, sortby: string, descending: boolean, types: string ):any { + console.info('ClaimsService: getClaims for project : '+projectId); + let url = this.baseUrl +"projects/"+projectId+"/claims"+"?offset="+(size*(page-1) + "&limit="+size)+"&keyword="+keyword+"&sortby="+sortby+"&descending="+descending+"&"+types; + return this.getClaimRequest(size,page,url,true); + } + + deleteClaimById(claimId:string ):any{ + console.warn('Trying to delete claim with id : '+claimId); + let url = this.baseUrl +"claims/"+claimId; + // let headers = new Headers({ 'Content-Type': 'application/json' }); + // let options = new RequestOptions({ headers: headers }); + return this.http.delete( url, CustomOptions.getAuthOptionsWithBody()).map(request => request.json()) + // .do(request => console.info("After delete" )) + .catch(this.handleError); + + } + deleteBulk(claimIds:string[]):any{ + + console.warn('Trying to delete claims with ids : '+claimIds); + var url = ""; + + for(var claimId of claimIds){ + url=url+(url.length >0 ?"&":"")+"claimId="+claimId; + } + url= this.baseUrl +"claims/bulk?"+url; + + // let headers = new Headers({ 'Content-Type': 'application/json' }); + // let options = new RequestOptions({ headers: headers }); + return this.http.delete( url, CustomOptions.getAuthOptions()).map(request => request.json()) + // .do(request => console.info("After delete" )) + .catch(this.handleError); + + } + insertBulkClaims(claims):any{ + console.warn('Trying toinsert claims : '+claims); + let url = this.baseUrl +"claims/bulk"; + let body = JSON.stringify( claims ); + console.warn('Json body: : '+body); + // let headers = new Headers({ 'Content-Type': 'application/json' }); + // let options = new RequestOptions({ headers: headers }); + return this.http.post(url, body, CustomOptions.getAuthOptionsWithBody()) + .map(res => res.json()) + .do(request => console.info("Insert Response:"+request.status) ) + .catch(this.handleError); + + } + insertClaim(claim):any{ + console.warn('Trying toinsert claim : '+claim); + let url = this.baseUrl +"claims"; + let body = JSON.stringify( claim ); + // let headers = new Headers({ 'Content-Type': 'application/json' }); + // let options = new RequestOptions({ headers: headers }); + return this.http.post(url, body, CustomOptions.getAuthOptionsWithBody()) + .map(res => res.json()) + .do(request => console.info("Insert Response:"+request.status) ) + .catch(this.handleError); + + } + insertDirectRecords(records):any{ + console.warn('Trying to feedrecords : '+records); + let url = this.baseUrl +"feed/bulk"; + let body = JSON.stringify( records ); + console.warn('Json body: : '+body); + // let headers = new Headers({ 'Content-Type': 'application/json' }); + // let options = new RequestOptions({ headers: headers }); + return this.http.post(url, body, CustomOptions.getAuthOptionsWithBody()) + .map(res => res.json()) + .do(request => console.info("Insert Response:"+request) ) + .catch(this.handleError); + + } + private handleError (error: Response) { + // in a real world app, we may send the error to some remote logging infrastructure + // instead of just logging it to the console + console.log(error); + return Observable.throw(error || 'Server error'); + } + + getClaim(id:string):any { + let url = this.baseUrl+"claims/"+id; + return new Promise((resolve, reject) => { + this.http.get(url) + .map(res => res.json()) + .subscribe( + data => { + resolve(data.data); + }, + err => { + reject(err); + } + ) + ; + }); + } + + +} diff --git a/portal-4cli/src/app/claims/claim-utils/service/claimsService.module.ts b/portal-4cli/src/app/claims/claim-utils/service/claimsService.module.ts new file mode 100644 index 00000000..d38d0f8d --- /dev/null +++ b/portal-4cli/src/app/claims/claim-utils/service/claimsService.module.ts @@ -0,0 +1,23 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {ClaimsService} from './claims.service'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule + ], + declarations: [ + ], + providers:[ + ClaimsService, + +], + exports: [ + ] +}) + + +export class ClaimServiceModule { } diff --git a/portal-4cli/src/app/claims/claim-utils/service/contexts.service.ts b/portal-4cli/src/app/claims/claim-utils/service/contexts.service.ts new file mode 100644 index 00000000..77170819 --- /dev/null +++ b/portal-4cli/src/app/claims/claim-utils/service/contexts.service.ts @@ -0,0 +1,85 @@ +import {Injectable} from '@angular/core'; +import {Jsonp, URLSearchParams, RequestOptions, Headers} from '@angular/http'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {Claim} from '../claim'; +import {OpenaireProperties} from '../../../utils/properties/openaireProperties'; +import {AutoCompleteValue} from '../../../searchPages/searchUtils/searchHelperClasses.class'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; +import { } from '../../../shared/cache.service'; +import { COOKIE } from '../../../login/utils/helper.class'; +@Injectable() +export class ContextsService { + private baseUrl; + constructor(private http: Http ) { + this.baseUrl = OpenaireProperties.getClaimsAPIURL(); + } + + public getCommunities():any { + let url = this.baseUrl + 'communities'; + let key = url; + + + console.info('ContextsService: request communities '+url); + return this.http.get( (OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url, this.getAuthOptions()) + .map(request => request.json().data) + // .do(request => console.info("Get claims: offset = ")) + .catch(this.handleError); + } + public getCategories(communityId :string):any { + console.info('ContextsService: request categories for community with id '+communityId); + let url= this.baseUrl + 'communities/' + communityId + '/categories'; + let key = url; + + + return this.http.get( (OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url, this.getAuthOptions()) + .map(request => request.json().data) + // .do(request => console.info("Get claims: offset = " )) + .catch(this.handleError);; + } + public getConcepts(categoryId :string, keyword: string, parsing:boolean):any { + console.info('ContextsService: request concept for category with id '+categoryId + ' and keyword '+ keyword); + let url= this.baseUrl + 'categories/' + categoryId+ "/concepts"; + let key = url+"_parsing="+parsing; + + + return this.http.get( (OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url, this.getAuthOptions()) + .map(request => request.json().data) + .catch(this.handleError) + .map(res => (parsing)?this.parse(res.concept):res.concept); + // .do(res => console.info("Result is "+ res.length )); + } + parse (data: any):AutoCompleteValue[] { + var array:AutoCompleteValue[] =[] + if(!Array.isArray(data) && data.id && data.label){ + var value:AutoCompleteValue = new AutoCompleteValue(); + value.id = data.id; + value.label = data.label; + array.push(value); + } + for(var i = 0; i < data.length; i++){ + var value:AutoCompleteValue = new AutoCompleteValue(); + value.id = data[i].id; + value.label = data[i].label; + array.push(value); + } + + return array; + + } + + private handleError (error: Response) { + // in a real world app, we may send the error to some remote logging infrastructure + // instead of just logging it to the console + console.log(error); + return Observable.throw(error || 'Server error'); + } + private getAuthOptions():RequestOptions{ + let headers = new Headers(); + headers.append('X-XSRF-TOKEN', COOKIE.getCookie(COOKIE.cookieName_id)); + let options = new RequestOptions({ headers: headers, withCredentials:true }); + return options; + } +} diff --git a/portal-4cli/src/app/claims/claim-utils/service/contextsService.module.ts b/portal-4cli/src/app/claims/claim-utils/service/contextsService.module.ts new file mode 100644 index 00000000..6bd55ced --- /dev/null +++ b/portal-4cli/src/app/claims/claim-utils/service/contextsService.module.ts @@ -0,0 +1,20 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {ContextsService} from './contexts.service'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule + ], + declarations: [ + ], + providers:[ + ContextsService +], + exports: [ + ] +}) +export class ContextsServiceModule { } diff --git a/portal-4cli/src/app/claims/claim-utils/service/customOptions.class.ts b/portal-4cli/src/app/claims/claim-utils/service/customOptions.class.ts new file mode 100644 index 00000000..7796c45e --- /dev/null +++ b/portal-4cli/src/app/claims/claim-utils/service/customOptions.class.ts @@ -0,0 +1,19 @@ +import { RequestOptions, Headers} from '@angular/http'; +import { COOKIE } from '../../../login/utils/helper.class'; + + +export class CustomOptions{ + public static getAuthOptionsWithBody():RequestOptions{ + let headers = new Headers(); + headers.append('Content-Type', 'application/json'); + headers.append('X-XSRF-TOKEN', COOKIE.getCookie(COOKIE.cookieName_id)); + let options = new RequestOptions({ headers: headers, withCredentials:true }); + return options; + } + public static getAuthOptions():RequestOptions{ + let headers = new Headers(); + headers.append('X-XSRF-TOKEN', COOKIE.getCookie(COOKIE.cookieName_id)); + let options = new RequestOptions({ headers: headers, withCredentials:true }); + return options; + } +} diff --git a/portal-4cli/src/app/claims/claim-utils/service/searchCrossref.service.ts b/portal-4cli/src/app/claims/claim-utils/service/searchCrossref.service.ts new file mode 100644 index 00000000..a65e0dd4 --- /dev/null +++ b/portal-4cli/src/app/claims/claim-utils/service/searchCrossref.service.ts @@ -0,0 +1,67 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {OpenaireProperties} from '../../../utils/properties/openaireProperties'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; +@Injectable() +export class SearchCrossrefService { + constructor( private http: Http ) {} + + + searchCrossrefResults (term: string, size : number, page : number):any { + let url = OpenaireProperties.getSearchCrossrefAPIURL()+'?query='+term+'&rows='+size+'&offset='+(size*(page-1)); + let key = url; + + return this.http.get( (OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(request => request.json().message) + .do(items => console.log("Crossref Results: total results = "+items['total-results']+" keyword = "+term)); + //.catch(this.handleError); + + } + searchCrossrefByDOIs(DOIs: string[]):any { + /* + $request ="http://api.crossref.org/works"."?filter="; + foreach($dois as $doi){ + $request.="doi:".urlencode( trim($doi)).","; + } + */ + var doisParams = ""; + for(var i =0 ;i < DOIs.length; i++){ + doisParams+=(doisParams.length > 0?",":"")+'doi:'+DOIs[i]; + } + let url = OpenaireProperties.getSearchCrossrefAPIURL()+'?filter='+doisParams; + let key = url; + + + return this.http.get( (OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(request => request.json().message) + .do(items => console.log("Crossref Results: total results = "+items['total-results']+" for doi = "+doisParams)); + //.catch(this.handleError); + + } + searchCrossrefByMultipleDOIs(dois: string[]):any { + let url = OpenaireProperties.getSearchCrossrefAPIURL()+'?filter=doi:'; + for(var i=0; i request.json().message) + .do(items => console.log("Crossref Results: total results = "+items['total-results'])); + //.catch(this.handleError); + + } + + private handleError (error: Response) { + // in a real world app, we may send the error to some remote logging infrastructure + // instead of just logging it to the console + console.log(error); + return Observable.throw(error || 'Server error'); + } + +} diff --git a/portal-4cli/src/app/claims/claim-utils/service/searchCrossrefService.module.ts b/portal-4cli/src/app/claims/claim-utils/service/searchCrossrefService.module.ts new file mode 100644 index 00000000..798acdb3 --- /dev/null +++ b/portal-4cli/src/app/claims/claim-utils/service/searchCrossrefService.module.ts @@ -0,0 +1,20 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {SearchCrossrefService} from './searchCrossref.service'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule + ], + declarations: [ + ], + providers:[ + SearchCrossrefService +], + exports: [ + ] +}) +export class SearchCrossrefServiceModule { } diff --git a/portal-4cli/src/app/claims/claim-utils/service/searchDatacite.service.ts b/portal-4cli/src/app/claims/claim-utils/service/searchDatacite.service.ts new file mode 100644 index 00000000..46b43032 --- /dev/null +++ b/portal-4cli/src/app/claims/claim-utils/service/searchDatacite.service.ts @@ -0,0 +1,50 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {OpenaireProperties} from '../../../utils/properties/openaireProperties'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; +@Injectable() +export class SearchDataciteService { + constructor(private http: Http ) {} + + searchDataciteResults (term: string, size : number, page : number):any { + console.info("In search datacite results "+term); + let url = OpenaireProperties.getSearchDataciteAPIURL()+'?query='+term+'&rows='+size+'&start='+(size*(page-1)); + let key = url; + + return this.http.get( (OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(request => request.json()) + .do(items => console.info(items)) + .do(items => console.log("Datacite Results: total results = "+items.meta.total+" keyword = "+term)); + //.catch(this.handleError); + } + getDataciteResultByDOI (doi: string):any { + console.info("Fetch datacite resultt by DOI: "+doi); + let url = OpenaireProperties.getSearchDataciteAPIURL()+'/'+doi; + let key = url; + + return this.http.get( (OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(request => request.json()) + .do(items => console.info(items)); + // .do(items => console.log("Datacite Results: total results = "+items.meta.total+" doi = "+doi)) + + //.catch(this.handleError); + } + + + private handleError (error: Response) { + // in a real world app, we may send the error to some remote logging infrastructure + // instead of just logging it to the console + console.log(error); + return Observable.throw(error || 'Server error'); + } + private extractData(res: Response) { + if (res.status < 200 || res.status >= 300) { + throw new Error('Bad response status: ' + res.status); + } + let body = res.json(); + return body.data || { }; + } +} diff --git a/portal-4cli/src/app/claims/claim-utils/service/searchDataciteService.module.ts b/portal-4cli/src/app/claims/claim-utils/service/searchDataciteService.module.ts new file mode 100644 index 00000000..659ca2e3 --- /dev/null +++ b/portal-4cli/src/app/claims/claim-utils/service/searchDataciteService.module.ts @@ -0,0 +1,20 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {SearchDataciteService} from './searchDatacite.service'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule + ], + declarations: [ + ], + providers:[ + SearchDataciteService +], + exports: [ + ] +}) +export class SearchDataciteServiceModule { } diff --git a/portal-4cli/src/app/claims/claim-utils/service/searchOrcid.service.ts b/portal-4cli/src/app/claims/claim-utils/service/searchOrcid.service.ts new file mode 100644 index 00000000..a9a60fcb --- /dev/null +++ b/portal-4cli/src/app/claims/claim-utils/service/searchOrcid.service.ts @@ -0,0 +1,126 @@ +import {Injectable} from '@angular/core'; +import {URLSearchParams} from '@angular/http'; +import {Http, Response} from '@angular/http'; +import { Headers, RequestOptions } from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {OpenaireProperties} from '../../../utils/properties/openaireProperties'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; + +@Injectable() +export class SearchOrcidService { + constructor( private http: Http ) {} + + + searchOrcidAuthor (term: string, authorIds: string[], + authorGivenNames: string[], authorFamilyNames: string[]):any { + console.info("In searchOrcidAuthor: "+term); + + var headers = new Headers(); + headers.append('Accept', 'application/orcid+json'); + + let url = OpenaireProperties.getSearchOrcidURL()+term+'/orcid-bio'; + let key = url; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url, { headers: headers }) + .map(res => res.json()['orcid-profile']) + .map(res => [res['orcid-bio']['personal-details']['given-names'], + res['orcid-bio']['personal-details']['family-name'], + res['orcid-identifier']]) + .map(res => this.parseOrcidAuthor(res, authorIds, authorGivenNames, authorFamilyNames)); + } + + searchOrcidAuthors (term: string, authorIds: string[], + authorGivenNames: string[], authorFamilyNames: string[]):any { + console.info("In search Orcid authors for keyword: "+term); + + var headers = new Headers(); + headers.append('Accept', 'application/orcid+json'); + + let url = OpenaireProperties.getSearchOrcidURL()+'search/orcid-bio?defType=edismax&q='+term+'&qf=given-name^1.0+family-name^2.0+other-names^1.0+credit-name^1.0&start=0&rows=10'; + let key = url; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url, { headers: headers }) + .map(res => res.json()['orcid-search-results']['orcid-search-result']) + .map(res => this.parseOrcidAuthors(res, authorIds, authorGivenNames, authorFamilyNames)); + + } + + searchOrcidPublications (id: string):any { + console.info("In search Orcid publications for author: "+id); + + var headers = new Headers(); + headers.append('Accept', 'application/orcid+json'); + + let url = OpenaireProperties.getSearchOrcidURL()+id+'/orcid-works'; + let key = url; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url, { headers: headers }) + .map(res => res.json()['orcid-profile']['orcid-activities']['orcid-works']); + //.map(res => res['orcid-work']); + } + + + parseOrcidAuthor (data: any, authorIds: string[], + authorGivenNames: string[], authorFamilyNames: string[]):any { + + if(data[2] != null) { + authorIds.push(data[2].path); + + if(data[0] != null) { + authorGivenNames.push(data[0].value); + } else { + authorGivenNames.push(""); + } + if(data[1] != null) { + authorFamilyNames.push(data[1].value); + } else { + authorFamilyNames.push(""); + } + + return true; + } + + return false; + } + + parseOrcidAuthors (data: any, authorIds: string[], + authorGivenNames: string[], authorFamilyNames: string[]):any { + let ret: boolean = false; + let mydata: any; + let length: number; + + if(data != null) { + length = data.length!=undefined ? data.length : 1; + + for(let i=0; i Clear All + + + `, + +}) +export class StartOverComponent { + constructor () { + + + } + ngOnInit() { + +} + + + // @Input() public inlineEntity = null; + @Input() public type:string; + @Input() public linkTo:string; + @Input() public results; + @Input() public projects; + @Input() public contexts; + + @ViewChild(AlertModal) alertApplyAll; + + confirmOpen(){ + this.alertApplyAll.cancelButton = true; + this.alertApplyAll.okButton = true; + this.alertApplyAll.alertTitle = "Remove selected"; + this.alertApplyAll.message = "This action will delete every selected entity (projects, communities, research results). Do you wish to continue?"; + this.alertApplyAll.okButtonText = "Yes"; + this.alertApplyAll.cancelButtonText = "No"; + this.alertApplyAll.open(); + } + confirmClose(data){ + this.startOver(); + } + startOver(){ + if(this.type != null && this.linkTo != null){ + console.log("inline"); + if(this.linkTo == "project"){ + this.projects.splice(0, this.projects.length); + }else if(this.linkTo == "context"){ + this.contexts.splice(0, this.contexts.length); + }else if(this.linkTo == "result"){ + this.results.splice(0, this.results.length); + } + }else{ + console.log("generic"); + this.results.splice(0, this.results.length); + this.projects.splice(0, this.projects.length); + this.contexts.splice(0, this.contexts.length); + } + console.log("projects:"+this.projects.length +" contexts:"+this.contexts.length + " results:"+this.results.length ); + } + +} diff --git a/portal-4cli/src/app/claims/claim-utils/startOver.module.ts b/portal-4cli/src/app/claims/claim-utils/startOver.module.ts new file mode 100644 index 00000000..bde3d0a2 --- /dev/null +++ b/portal-4cli/src/app/claims/claim-utils/startOver.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; +import { SharedModule } from '../../shared/shared.module'; +import { CommonModule } from '@angular/common'; +import {StartOverComponent} from './startOver.component'; +import {AlertModalModule} from '../../utils/modal/alertModal.module'; + + @NgModule({ + imports: [ + SharedModule, CommonModule, AlertModalModule + ], + declarations: [ + StartOverComponent + ], + exports: [StartOverComponent ] +}) +export class StartOverModule { } diff --git a/portal-4cli/src/app/claims/claim.module.ts b/portal-4cli/src/app/claims/claim.module.ts new file mode 100644 index 00000000..113e8597 --- /dev/null +++ b/portal-4cli/src/app/claims/claim.module.ts @@ -0,0 +1,68 @@ +// import { NgModule} from '@angular/core'; +// import { CommonModule } from '@angular/common'; +// import { FormsModule } from '@angular/forms'; +// // +// import {UtilsModule} from '../utils/utils.module'; +// import {ServicesModule} from '../services/services.module'; +// +// import { ClaimsService} from '../services/claims.service'; +// //main +// import {ClaimComponent} from './claim/claim.component'; +// import {ClaimsAdminComponent} from './claims/claimsAdmin.component'; +// import {MyClaimsComponent} from './myClaims/myClaims.component'; +// import {LinkingHomeComponent} from './linking/linkingHome.component'; +// import {LinkingComponent} from './linking/linking.component'; +// import { BulkLinkingComponent } from './linking/bulkLinking.component'; +// +// import {BulkClaimComponent} from './linking/bulkClaim/bulkClaim.component'; +// import {ClaimsComponent} from './claim-utils/claims.component'; +// +// import {ClaimContextComponent} from './claim-utils/claimContext.component'; +// import {ClaimProjectsComponent} from './claim-utils/claimProject.component'; +// import {ClaimResultComponent} from './claim-utils/claimResult.component'; +// import {ClaimPublicationComponent} from './claim-utils/claimPublication.component'; +// import {ClaimDatasetComponent} from './claim-utils/claimDataset.component'; +// +// import {ClaimInsertComponent} from './linking/insertClaim/insertClaim.component'; +// +// import {ClaimSelectedContextsComponent} from './linking/selected/selectedContexts.component'; +// import {ClaimSelectedComponent} from './linking/selected/selected.component'; +// import {ClaimSelectedDatasetsComponent} from './linking/selected/selectedDatasets.component'; +// import {ClaimSelectedResultsComponent} from './linking/selected/selectedResults.component'; +// import {ClaimSelectedProjectsComponent} from './linking/selected/selectedProjects.component'; +// import {ClaimSelectedPublicationsComponent} from './linking/selected/selectedPublications.component'; +// +// import {LinkingGenericComponent} from './linking/linkingGeneric.component'; +// +// import {InlineClaimContextComponent} from './inlineClaims/inlineClaimContext.component'; +// import {InlineClaimProjectComponent} from './inlineClaims/inlineClaimProject.component'; +// import {InlineClaimResultComponent} from './inlineClaims/inlineClaimResult.component'; +// import {ClaimEntityFormatter} from '../utils/claimEntityFormatter.component'; +// +// import { Claim } from '../utils/entities/claim'; +// //helpers +// +// import { ClaimRoutingModule } from './claim-routing.module'; +// @NgModule({ +// imports: [ +// CommonModule, FormsModule, +// UtilsModule, +// ServicesModule, +// ClaimRoutingModule +// +// ], +// declarations: [ +// ClaimsAdminComponent, MyClaimsComponent, ClaimComponent, ClaimsComponent, +// BulkLinkingComponent, LinkingComponent, LinkingHomeComponent, LinkingGenericComponent, +// InlineClaimContextComponent, InlineClaimProjectComponent, InlineClaimResultComponent, ClaimSelectedComponent, +// ClaimContextComponent, ClaimSelectedContextsComponent, ClaimInsertComponent, ClaimProjectsComponent, ClaimSelectedProjectsComponent, +// ClaimResultComponent, ClaimSelectedPublicationsComponent, ClaimSelectedDatasetsComponent, ClaimSelectedResultsComponent, ClaimPublicationComponent, +// ClaimDatasetComponent, BulkClaimComponent, +// ClaimEntityFormatter +// ], +// providers: [ ClaimsService ], +// exports: [ +// InlineClaimContextComponent, InlineClaimProjectComponent, InlineClaimResultComponent +// ] +// }) +// export class ClaimModule { } diff --git a/portal-4cli/src/app/claims/claim/claim.component.html b/portal-4cli/src/app/claims/claim/claim.component.html new file mode 100644 index 00000000..338d0097 --- /dev/null +++ b/portal-4cli/src/app/claims/claim/claim.component.html @@ -0,0 +1,10 @@ + diff --git a/portal-4cli/src/app/claims/claimsAdmin/claimsAdmin-routing.module.ts b/portal-4cli/src/app/claims/claimsAdmin/claimsAdmin-routing.module.ts new file mode 100644 index 00000000..f915d2e9 --- /dev/null +++ b/portal-4cli/src/app/claims/claimsAdmin/claimsAdmin-routing.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; +import { AdminLoginGuard} from'../../login/adminLoginGuard.guard'; + +import { ClaimsAdminComponent } from './claimsAdmin.component'; +import {PreviousRouteRecorder} from'../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: ClaimsAdminComponent, canActivate: [IsRouteEnabled, AdminLoginGuard], + data: {redirect: '/error'}, canDeactivate: [PreviousRouteRecorder]}]) + ] +}) +export class ClaimsAdminRoutingModule { } diff --git a/portal-4cli/src/app/claims/claimsAdmin/claimsAdmin.component.ts b/portal-4cli/src/app/claims/claimsAdmin/claimsAdmin.component.ts new file mode 100644 index 00000000..08b3dc11 --- /dev/null +++ b/portal-4cli/src/app/claims/claimsAdmin/claimsAdmin.component.ts @@ -0,0 +1,38 @@ +import {Component, ViewChild, Input} from '@angular/core'; +import {Location} from '@angular/common'; +import {Observable} from 'rxjs/Observable'; +import { Meta} from '../../../angular2-meta'; + +@Component({ + selector: 'claims-admin', + template: ` +
+
+
+ +
+
+
+
+
+ Claims Administrator +
+ +
+
+
+
+ + `, + +}) +export class ClaimsAdminComponent { + constructor ( private _meta: Meta ) { + this._meta.setTitle("OpenAIRE | Claims Administrator"); + } + ngOnInit() { + } +} diff --git a/portal-4cli/src/app/claims/claimsAdmin/claimsAdmin.module.ts b/portal-4cli/src/app/claims/claimsAdmin/claimsAdmin.module.ts new file mode 100644 index 00000000..947bc901 --- /dev/null +++ b/portal-4cli/src/app/claims/claimsAdmin/claimsAdmin.module.ts @@ -0,0 +1,25 @@ +import { NgModule } from '@angular/core'; + +import { SharedModule } from '../../shared/shared.module'; +import { ClaimsAdminComponent } from './claimsAdmin.component'; +import { ClaimsAdminRoutingModule } from './claimsAdmin-routing.module'; +// import{ClaimServiceModule} from '../claim-utils/service/claimsService.module'; +import {DisplayClaimsModule} from '../claim-utils/displayClaims/displayClaims.module'; +import { AdminLoginGuard} from'../../login/adminLoginGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + SharedModule, + ClaimsAdminRoutingModule, + // ClaimServiceModule, + DisplayClaimsModule + + ], + providers:[AdminLoginGuard, PreviousRouteRecorder,IsRouteEnabled], + declarations: [ + ClaimsAdminComponent + ] +}) +export class ClaimsAdminModule { } diff --git a/portal-4cli/src/app/claims/claimsByToken/claimsByToken-routing.module.ts b/portal-4cli/src/app/claims/claimsByToken/claimsByToken-routing.module.ts new file mode 100644 index 00000000..3d50376a --- /dev/null +++ b/portal-4cli/src/app/claims/claimsByToken/claimsByToken-routing.module.ts @@ -0,0 +1,15 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; +import { LoginGuard} from'../../login/loginGuard.guard'; +import { ClaimsByTokenComponent } from './claimsByToken.component'; +import {PreviousRouteRecorder} from'../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: ClaimsByTokenComponent, canActivate: [IsRouteEnabled, LoginGuard], + data: {redirect: '/error'}, canDeactivate: [PreviousRouteRecorder]}]) + ] +}) +export class ClaimsByTokenRoutingModule { } diff --git a/portal-4cli/src/app/claims/claimsByToken/claimsByToken.component.ts b/portal-4cli/src/app/claims/claimsByToken/claimsByToken.component.ts new file mode 100644 index 00000000..955210d4 --- /dev/null +++ b/portal-4cli/src/app/claims/claimsByToken/claimsByToken.component.ts @@ -0,0 +1,433 @@ +import {Component, ViewChild, Input} from '@angular/core'; +import {Location} from '@angular/common'; +import {Observable} from 'rxjs/Observable'; +import {ActivatedRoute, Params} from '@angular/router'; +import {ClaimsByTokenService} from './claimsByToken.service'; + +import {ModalSelect} from '../../utils/modal/selectModal.component'; +import {ModalLoading} from '../../utils/modal/loading.component'; + +import {Session} from '../../login/utils/helper.class'; + +import {RouterHelper} from '../../utils/routerHelper.class'; +import { Meta} from '../../../angular2-meta'; +import {ClaimsDatatablePipe} from '../../utils/pipes/claimsDatatable.pipe'; + +//import {DataTable} from "angular2-datatable"; + +@Component({ + selector: 'claims-project-manager', + template: ` +
+
+
+
+ + +
+
+ + +

Oops! Your email does not give you the authority to view claims for the selected project. Please contact the administrators.

+
+
+ +
+
+ Claims Administrator + + {{project['name']}} ({{project['funderName']}}) + + +
+

Pending Claims

+ +
+
No pending claims found.
+
+ +
+ +
+
+ +
+
+ + + {{totalPendingResults.count}} pending claims, page {{activePendingPage.page}} of {{totalPages(totalPendingResults.count)}} + + + + + + + + + + + + + + + + + + + + + +
Research ResultClaimed ByClaimed DateApprove
{{claim1.userMail}}{{claim1.date}} + + + +
+
+ +
*Note that claims you did not approved or disapproved are considered as right (but not curated)
+ + +

Already Curated Claims

+ +
+
No curated claims found.
+
+ +
+ +
+
+ +
+
+ + + {{totalCuratedResults.count}} curated claims, page {{activeCuratedPage.page}} of {{totalPages(totalCuratedResults.count)}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Research ResultClaimed byClaimed DateCurated byCuration DateApproved
{{claim.userMail}}{{claim.date}}{{claim.curatedBy}}{{claim.curationDate}} + + + + + +
+
+ + + +
+ +
+
+
+
+ `, + +}) +export class ClaimsByTokenComponent { + public token: string = ""; + public sub: any; + public project: any; + private claims:any = []; + public pending_claims: any = []; + public curated_claims: any = []; + public selectedRight: Set; + public selectedWrong: Set; + public editable: Set; + public contact_person: string[] = ["Konstantina", "Argiro", "Katerina"]; + + // when 'valid' show proper claims, when 'invalid' show no matched entry-wanna retry + public accessStatus: string;// = "empty"; + + public rowsOnPage = 5; + public sortOrder = "asc"; + public filterQuery:string = ""; + public filterQuery2:string = ""; + + public activePendingPage:any = {page: 1}; + public totalPendingResults:any = {count: 0}; + public activeCuratedPage:any = {page: 1}; + public totalCuratedResults:any = {count: 0}; + + + @ViewChild('mf1') table1: any;//DataTable; + @ViewChild('mf2') table2: any;//DataTable; + @ViewChild('filtered1') filteredItems1; + + + @ViewChild (ModalSelect) selectModal : ModalSelect; + @ViewChild (ModalLoading) loading : ModalLoading ; + + public routerHelper:RouterHelper = new RouterHelper(); + + constructor ( private route: ActivatedRoute, private claimsByTokenService: ClaimsByTokenService, private _meta: Meta) { + + } + ngOnInit() { + this.sub = this.route.queryParams.subscribe(params => { + this.token = params['token']; + this.selectedRight = new Set(); + this.selectedWrong = new Set(); + this.editable = new Set(); + //this.openSelect(); + //this.setMessageSelect("Please select your identity:"); + //this.setOptionsSelect(this.contact_person); + this.validateJWTandToken(); + this.updateTitle("Claims For Project Managers"); + } + ); + } + +refreshTable(table:any, $event:any, whichTable: string) { + if(whichTable == "pending") { + this.activePendingPage.page = $event.value; + } else if(whichTable == 'curated') { + this.activeCuratedPage.page = $event.value; + } + table.mfActivePage=$event.value; + table.setPage(table.mfActivePage, this.rowsOnPage); +} + +public sortByClaimDate1 = (claim: any) => { + return new Date(claim.date); +} + +public sortByCurationDate1 = (claim: any) => { + return new Date(claim.curationDate); +} + +public sortByTitle1 = (claim: any) => { + if(claim.targetType != 'project') { + return claim.target.title; + } else { + return claim.source.title; + } +} + +public sortByClaimDate2 = (claim: any) => { + return new Date(claim.date); +} + +public sortByCurationDate2 = (claim: any) => { + console.info(new Date(claim.curationDate)); + return new Date(claim.curationDate); +} + +public sortByTitle2= (claim: any) => { + if(claim.targetType != 'project') { + return claim.target.title; + } else { + return claim.source.title; + } +} + + + validateJWTandToken() { + var jwtToken=Session.getUserJwt(); + if(this.token) { + this.claimsByTokenService.getClaims(this.token, jwtToken).subscribe( + data => { + this.closeLoading(); + this.accessStatus = "valid"; + //console.info(data); + this.claims = data.data; + for(let claim of this.claims) { + if(claim.targetType == "project") { + this.project = claim.target; + } else { + this.project = claim.source; + } + if(claim.curatedBy) { + this.curated_claims.push(claim); + } else { + this.pending_claims.push(claim); + } + } + + this.totalPendingResults.count = this.pending_claims.length; + this.totalCuratedResults.count = this.curated_claims.length; + + this.updateTitle("Claims For Project Managers - "+this.project.name); + }, + err => { + this.accessStatus = "invalid"; + console.log(err); + } + ); + } else { + this.accessStatus = "invalid"; + } + } + + selectApprove(id:string, event) { + var value = event.currentTarget.checked; + if(value){ + this.selectedRight.add(id); + this.selectedWrong.delete(id); + console.info(this.selectedRight); + }else{ + this.selectedRight.delete(id); + console.info(this.selectedRight); + } + } + + selectDisapprove(id:string,event) { + var value = event.currentTarget.checked; + if(value){ + this.selectedWrong.add(id); + this.selectedRight.delete(id); + }else{ + this.selectedWrong.delete(id); + } + } + + isSelectedRight(id:string) { + return this.selectedRight.has(id); + } + + isSelectedWrong(id:string) { + return this.selectedWrong.has(id); + } + + isRight(claim: any) { + //claim.approved = true; + if(this.isSelectedRight(claim.id)) { + return true; + } else if(claim.approved == true && !this.isSelectedWrong(claim.id)) { + return true; + } + + return false; + } + + isWrong(claim: any) { + if(this.isSelectedWrong(claim.id)) { + return true; + } else if(claim.approved == false && !this.isSelectedRight(claim.id)) { + return true; + } + + return false; + } + + saveChanges() { + console.info("Changes Saved!"); + var jwtToken=Session.getUserJwt(); + + this.claimsByTokenService.updateClaimsCuration(this.selectedRight, this.selectedWrong).subscribe( + data => { + console.info(data); + }, + err => { + console.log(err); + } + ); + + } + + public closeLoading(){ + if(this.loading){ + this.loading.close(); + } + } + + curatorSelected(selected: string) { + console.info("selected curator: "+selected); + } + + public openSelect(){ + if(this.selectModal){ + this.selectModal.open(); + } + } + + public setMessageSelect(message: string){ + if(this.selectModal){ + this.selectModal.message = message; + } + } + + public setOptionsSelect(options: string[]){ + if(this.selectModal){ + this.selectModal.options = options; + } + } + + totalPages(totalResults: number): number { + let totalPages:any = totalResults/(this.rowsOnPage); + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, 10) + 1); + } + return totalPages; + } + + updateTitle(title:string){ + var _prefix ="OpenAIRE | "; + var _title = _prefix + ((title.length> 50 ) ?title.substring(0,50):title); + this._meta.setTitle(_title ); + } + +} diff --git a/portal-4cli/src/app/claims/claimsByToken/claimsByToken.module.ts b/portal-4cli/src/app/claims/claimsByToken/claimsByToken.module.ts new file mode 100644 index 00000000..9f5827b5 --- /dev/null +++ b/portal-4cli/src/app/claims/claimsByToken/claimsByToken.module.ts @@ -0,0 +1,49 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import {DataTableModule} from "angular2-datatable"; + +import { SharedModule } from '../../shared/shared.module'; +import { ClaimsByTokenComponent } from './claimsByToken.component'; +import { ClaimsByTokenService } from './claimsByToken.service'; +import { ClaimsByTokenRoutingModule } from './claimsByToken-routing.module'; +import {ClaimEntityFormatterModule} from '../claim-utils/entityFormatter/claimEntityFormatter.module'; +// import{ClaimServiceModule} from '../claim-utils/service/claimsService.module'; +//import {DisplayClaimsModule} from '../claim-utils/displayClaims/displayClaims.module'; +import {SelectModalModule} from '../../utils/modal/selectModal.module'; +import {LoadingModalModule} from '../../utils/modal/loadingModal.module'; + +import {LoginGuard} from'../../login/loginGuard.guard'; + +import {PagingModule} from '../../utils/paging.module'; +import {ClaimsDatatablePipe} from '../../utils/pipes/claimsDatatable.pipe'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + + +@NgModule({ + imports: [ + RouterModule, + DataTableModule, + SharedModule, + ClaimsByTokenRoutingModule, + ClaimEntityFormatterModule, + SelectModalModule, + LoadingModalModule, + PagingModule + // ClaimServiceModule, + //DisplayClaimsModule + + ], + providers:[ + ClaimsByTokenService, + LoginGuard, PreviousRouteRecorder, IsRouteEnabled + ], + declarations: [ + ClaimsByTokenComponent, ClaimsDatatablePipe + ], + exports: [ + ClaimsByTokenComponent, ClaimsDatatablePipe + ] +}) +export class ClaimsByTokenModule { } diff --git a/portal-4cli/src/app/claims/claimsByToken/claimsByToken.service.ts b/portal-4cli/src/app/claims/claimsByToken/claimsByToken.service.ts new file mode 100644 index 00000000..ab75c85a --- /dev/null +++ b/portal-4cli/src/app/claims/claimsByToken/claimsByToken.service.ts @@ -0,0 +1,77 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Jsonp, URLSearchParams,ResponseOptions, RequestOptions, Headers} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; +import 'rxjs/add/operator/do'; + +import { CustomOptions } from '../claim-utils/service/customOptions.class'; + +@Injectable() +export class ClaimsByTokenService { + + constructor(private http: Http ) {} + + getClaims(token: string, jwtToken: string):any { + console.info("getClaims in service"); + + let url = OpenaireProperties.getClaimsAPIURL()+"project/claims?projectToken="+token; + + let key = url; + + return this.http.get(url, CustomOptions.getAuthOptions()) + //.map(res => res.text()) + .map(request => request.json()); + + } + + +/* + getClaims(email: string, token: string, user_token: string):any { + let url = OpenaireProperties.getClaimsAPIURL(); // What else? + let body = JSON.stringify( {"email": email, "token": token} ); + console.warn('Json body: : '+body); + let headers = new Headers({ 'Content-Type': 'application/json' }); + let options = new RequestOptions({ headers: headers }); + return this.http.post(url, body, options) + .map(res => res.json()) + .do(request => console.info("Insert Response:"+request.status) ) + .catch(this.handleError); + } +*/ + + updateClaimsCuration( selectedRight: Set, selectedWrong: Set) { + let url = OpenaireProperties.getClaimsAPIURL() + "curate/bulk"; + let claimsCurationInfo: any = []; //e.g.: [{"id":"2","approved":true},{"id":"1","approved":true}] + + selectedRight.forEach(function(selected) { + console.info(selected); + let claimCurationInfo: {"id": string, "approved": boolean} = {"id": selected, "approved": true}; + claimsCurationInfo.push(claimCurationInfo); + }); + + selectedWrong.forEach(function(selected) { + let claimCurationInfo: any = {"id": selected, "approved": false}; + claimsCurationInfo.push(claimCurationInfo); + }); + + console.info("\n\n"+claimsCurationInfo); + + + let body = JSON.stringify( claimsCurationInfo ); + console.warn('Json body: : '+body); + let headers = new Headers({ 'Content-Type': 'application/json' }); + let options = new RequestOptions({ headers: headers }); + return this.http.post(url, body, CustomOptions.getAuthOptionsWithBody()) + .map(res => res.json()) + .do(request => console.info("Insert Response:"+request.status) ) + .catch(this.handleError); + } + + private handleError (error: Response) { + // in a real world app, we may send the error to some remote logging infrastructure + // instead of just logging it to the console + console.log(error); + return Observable.throw(error || 'Server error'); + } +} diff --git a/portal-4cli/src/app/claims/directLinking/directLinking-routing.module.ts b/portal-4cli/src/app/claims/directLinking/directLinking-routing.module.ts new file mode 100644 index 00000000..e9ed1f35 --- /dev/null +++ b/portal-4cli/src/app/claims/directLinking/directLinking-routing.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; +import { LoginGuard} from'../../login/loginGuard.guard'; + +import { DirectLinkingComponent } from './directLinking.component'; +import {PreviousRouteRecorder} from'../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: DirectLinkingComponent, canActivate: [IsRouteEnabled, LoginGuard], data: { + redirect: '/error' + }, canDeactivate: [PreviousRouteRecorder]}, + + ]) + ] +}) +export class DirectLinkingRoutingModule { } diff --git a/portal-4cli/src/app/claims/directLinking/directLinking.component.html b/portal-4cli/src/app/claims/directLinking/directLinking.component.html new file mode 100644 index 00000000..c997eb3d --- /dev/null +++ b/portal-4cli/src/app/claims/directLinking/directLinking.component.html @@ -0,0 +1,118 @@ +
+
+
+ +
+
+ Link +
+
+ +
+
+ +
+ +
+ +
+ + +
+
+ Link {{(type=="project")?'Project':' Research result'}}: +
+
+ +
+ +
+
+
+ {{displayedResult.title}} + {{displayedResult.title}} +
+ + +
+ +
+ +
+ {{projects[0].funderName}} | {{projects[0].projectName}} {{(projects[0].projectAcronym)?'('+projects[0].projectAcronym+')':''}} + +
+ + + +
+ + + + + + + +
+
+ + +
+ +
+
+ + + +
+
+ +
+ +
+
+
+
diff --git a/portal-4cli/src/app/claims/directLinking/directLinking.component.ts b/portal-4cli/src/app/claims/directLinking/directLinking.component.ts new file mode 100644 index 00000000..567909a3 --- /dev/null +++ b/portal-4cli/src/app/claims/directLinking/directLinking.component.ts @@ -0,0 +1,188 @@ +import {Component, Input} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {ActivatedRoute, Router} from '@angular/router'; +import {EntitiesSearchService} from '../../utils/entitiesAutoComplete/entitySearch.service'; +import {ClaimProject, ClaimResult} from '../claim-utils/claimEntities.class'; +import {SearchPublicationsService} from '../../services/searchPublications.service'; +import {SearchDatasetsService} from '../../services/searchDatasets.service'; +import { Meta} from '../../../angular2-meta'; + +@Component({ + selector: 'directLinking', + templateUrl: 'directLinking.component.html' +}) +export class DirectLinkingComponent { + contexts=[]; + projects=[]; + + results = []; + + linkType:string ="project"; // link type (selected in home page) : project, context, software, etc + /* url Parameters for inline linking */ + id:string = null; //entity id + type:string = null; // entity type (publication or dataset) + linkTo:string = null; // entity type (project or context or result) + + entityTypes=["dataset", "publication", "project","context"]; + inlineResult:ClaimResult =null; + displayedResult:ClaimResult =null; + sub:any =null; + show:string="claim"; //{claim,result} + validInput:boolean = null;//'true; + constructor ( private _router: Router, private route: ActivatedRoute, private entitySearch:EntitiesSearchService, + private publicationsSearch:SearchPublicationsService, private datasetsSearch:SearchDatasetsService, private _meta: Meta) { + this._meta.setTitle("OpenAIRE | Direct Linking"); + } + ngOnInit() { + if(localStorage.getItem("projects")){ + this.projects = JSON.parse(localStorage.getItem("projects")); + } + if(localStorage.getItem("contexts")){ + this.contexts = JSON.parse(localStorage.getItem("contexts")); + } + if(localStorage.getItem("results")){ + this.results = JSON.parse(localStorage.getItem("results")); + } + if(localStorage.getItem("results")){ + this.results = JSON.parse(localStorage.getItem("results")); + } + if(localStorage.getItem("inlineEntity")){ + this.inlineResult = JSON.parse(localStorage.getItem("inlineEntity")); + } + + localStorage.removeItem("projects"); + localStorage.removeItem("contexts"); + localStorage.removeItem("results"); + localStorage.removeItem("inlineEntity"); + + this.sub = this.route.queryParams.subscribe(params => { + this.id = params['id']; + this.type = params['type']; + this.linkTo = params['linkTo']; + if(this.type!=null && this.linkTo!=null){ + this.type = (this.entityTypes.indexOf(this.type) != -1)? this.type:'publication'; + this.linkTo = (this.entityTypes.indexOf(this.linkTo) != -1 || this.linkTo == "result")? this.linkTo:'project'; + this.show = (this.linkTo != "result")?"claim":"result"; + this.linkType = this.linkTo; + var isInlineResult:boolean = false; // is a link result - result + if((this.type == "publication" || this.type == "dataset") && ((this.linkTo == "publication" || this.linkTo == "dataset") || this.linkTo == "result" )){ + isInlineResult = true; + } + if(this.type == "project"){ + this.linkType = "project"; + this.getProjectById(this.id); + }else if(this.type == "publication"){ + this.getPublicationById(this.id,isInlineResult); + }else if(this.type == "dataset"){ + this.getDatasetById(this.id,isInlineResult); + }else{ + this.validInput = this.isValidInput(null); + } + + }else{ + this.validInput = this.isValidInput(null); + + } + + }); + } + isValidInput(result){ + if(result == null){ + return false; + }else if(this.type == "project" && this.linkTo != "result"){ + return false; + }else if(["dataset","publication"].indexOf(this.type) != -1 && (["project","context","result"].indexOf(this.linkTo) == -1)){ + return false; + }else if(["project","dataset","publication"].indexOf(this.type) == -1){ + return false; + }else{ + return true; + } + } + getProjectById(id:string){ + this.sub = this.entitySearch.fetchByType(id,"project").subscribe( + data => { + console.log(data); + var item =data[0]; + var project: ClaimProject = new ClaimProject(); + project.funderId = item.funderId; + project.funderName = item.funderName; + project.projectId = id; + project.projectName = item.projectName; + project.projectAcronym = item.projectAcronym; + project.startDate = item.startDate; + project.endDate = item.endDate; + project.code = item.code; + project.jurisdiction = item.jurisdiction; + project.fundingLevel0 = item.fundingLevel0; + + this.projects.push( project); + this.validInput = this.isValidInput(project); + + }, + err => { + this.validInput = this.isValidInput(null); + console.log("An error occured") + }); + } + getPublicationById(id:string, isInlineResult:boolean){ + + this.sub = this.publicationsSearch.searchPublicationById(id).subscribe( + data => { + var item =data[0]; + var result: ClaimResult = new ClaimResult(); + result.id=id; + result.type="publication"; + result.source="openaire"; + result.title = item['title'].name; + result.url= item['title'].url; + result.result = item; + result.accessRights = item['title'].accessMode; + result.date = item.year; + this.displayedResult = result; + if(isInlineResult){ + this.inlineResult = result; + }else{ + this.results.push( result); + } + this.validInput = this.isValidInput(result); + }, + err => { + this.validInput = this.isValidInput(null); + console.log("An error occured") + }); + } + getDatasetById(id:string, isInlineResult:boolean){ + this.sub = this.datasetsSearch.searchDatasetById(id).subscribe( + data => { + var item =data[0]; + var result: ClaimResult = new ClaimResult(); + result.id=id; + result.type="dataset"; + result.source="openaire"; + result.title = item['title'].name; + result.url= item['title'].url; + result.result = item; + result.accessRights = item['title'].accessMode; + result.date = item.year; this.displayedResult = result; + if(isInlineResult){ + this.inlineResult = result; + }else{ + this.results.push( result); + } + this.validInput = this.isValidInput(result); + }, + err => { + this.validInput = this.isValidInput(null); + console.log("An error occured") + }); + + } + + + + + + + +} diff --git a/portal-4cli/src/app/claims/directLinking/directLinking.module.ts b/portal-4cli/src/app/claims/directLinking/directLinking.module.ts new file mode 100644 index 00000000..aa5ab421 --- /dev/null +++ b/portal-4cli/src/app/claims/directLinking/directLinking.module.ts @@ -0,0 +1,39 @@ +import { NgModule } from '@angular/core'; + +import { SharedModule } from '../../shared/shared.module'; +import { DirectLinkingComponent } from './directLinking.component'; +import { DirectLinkingRoutingModule } from './directLinking-routing.module'; + +import {SelectedProjectsModule} from '../linking/selected/selectedProjects.module'; +import {SelectedContextsModule} from '../linking/selected/selectedContexts.module'; +import {SelectedPublicationsModule} from '../linking/selected/selectedResults.module'; +import {InsertClaimsModule} from '../linking/insertClaim/insertClaim.module'; +import {StartOverModule} from '../claim-utils/startOver.module'; + +import {EntitySearchServiceModule} from '../../utils/entitiesAutoComplete/entitySearchService.module'; +import {PublicationsServiceModule} from '../../services/publicationsService.module'; +import {DatasetsServiceModule} from '../../services/datasetsService.module'; +import {LoginGuard} from'../../login/loginGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {HelperModule} from '../../utils/helper/helper.module'; +import {ClaimContextSearchFormModule} from '../claim-utils/claimContextSearchForm.module'; +import {ClaimProjectsSearchFormModule} from '../claim-utils/claimProjectSearchForm.module'; +import {ClaimResultSearchFormModule} from '../claim-utils/claimResultSearchForm.module'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + + +@NgModule({ + imports: [ + SharedModule, + DirectLinkingRoutingModule,SelectedProjectsModule, SelectedContextsModule, SelectedPublicationsModule, InsertClaimsModule, + EntitySearchServiceModule, PublicationsServiceModule, DatasetsServiceModule, StartOverModule, HelperModule, + ClaimContextSearchFormModule, ClaimProjectsSearchFormModule, ClaimResultSearchFormModule + + + ], + providers:[LoginGuard, PreviousRouteRecorder, IsRouteEnabled], + declarations: [ + DirectLinkingComponent + ], exports:[DirectLinkingComponent] +}) +export class DirectLinkingModule { } diff --git a/portal-4cli/src/app/claims/linking/bulkClaim/bulkClaim.component.ts b/portal-4cli/src/app/claims/linking/bulkClaim/bulkClaim.component.ts new file mode 100644 index 00000000..bc9ea125 --- /dev/null +++ b/portal-4cli/src/app/claims/linking/bulkClaim/bulkClaim.component.ts @@ -0,0 +1,256 @@ +import {Component, Input, Output, EventEmitter,ViewChild} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {SearchCrossrefService} from '../../claim-utils/service/searchCrossref.service'; +import {SearchDataciteService} from '../../claim-utils/service/searchDatacite.service'; + +import {ModalLoading} from '../../../utils/modal/loading.component'; +import {Dates, DOI} from '../../../utils/string-utils.class'; +import {OpenaireProperties} from '../../../utils/properties/openaireProperties'; +import {ClaimResult} from '../../claim-utils/claimEntities.class'; + + +@Component({ + selector: 'bulk-claim', + template: ` +
+
+ + + + + + + +
Upload a DOI csv file:
+ + + + + + + +
+ + + +
+ ` + +}) +//[(ngModel)]="date" +export class BulkClaimComponent { + filesToUpload: Array; + navigateTo: string = "Search"; + source: string = "crossref"; + type : string = "publication"; + resultsFromSearch:number; + @Input() public select:boolean = true ; + @Input() public results; + + allIds:string[] = []; + foundIds:string[] = []; + duplicateIds:string[] = []; + notFoundIds:string[] = []; + noValidIds:string[] = []; + showReport:boolean = false; + showInfo :boolean = false; + @ViewChild (ModalLoading) loading : ModalLoading ; + errorMessage = ""; + infoMEssage = ""; + enableUpload:boolean = true; + constructor(private _searchCrossrefService: SearchCrossrefService, private _searchDataciteService: SearchDataciteService) { + this.filesToUpload = []; + } + ngOnInit() {} + + upload() { + this.enableUpload = false; + this.showReport = false; + this.errorMessage = ""; + if(this.filesToUpload.length == 0){ + this.errorMessage = "There is no selected file to upload."; + return ; + } + this.loading.open(); + + this.makeFileRequest(OpenaireProperties.getUploadServiceUrl(), [], this.filesToUpload).then((result) => { + var rows = (result as any).split('\n'); // I have used space, you can use any thing. + var i = 0; + this.duplicateIds = []; + this.allIds = []; + this.foundIds = []; + this.noValidIds = []; + this.results.slice(0,this.results.length); + this.notFoundIds = []; + + for(i=0;i-1){ + this.duplicateIds.push(id); + }else{ + this.allIds.push(id); + this.fetchResult(id,accessMode,embargoDate); + } + }else{ + this.noValidIds.push(id); + } + } + + } + + }, (error) => { + this.enableUpload = true; + console.log(error); + this.loading.close(); + this.errorMessage = "An error occured while uploading..."; + }); + } + private removeDoubleQuotes(value){ + if(value.indexOf('"')== 0){ + value = value.substring(1,value.length); + } + var index =+value.indexOf('"'); + if(index == (value.length - 1) || index == (value.length - 2) ){ + value = value.substring(0,index); + } + return value; + } + private validateAccessMode(value){ + var accessModes = ["OPEN", "CLOSED", "EMBARGO"]; + if(accessModes.indexOf(value) > -1){ + return true; + } + + return false; + } + + fileChangeEvent(fileInput: any){ + this.filesToUpload = > fileInput.target.files; + } + + makeFileRequest(url: string, params: Array, files: Array) { + return new Promise((resolve, reject) => { + var formData: any = new FormData(); + var xhr = new XMLHttpRequest(); + for(var i = 0; i < files.length; i++) { + formData.append("uploads[]", files[i], files[i].name); + } + xhr.onreadystatechange = function () { + if (xhr.readyState == 4) { + if (xhr.status == 200) { + resolve(xhr.response); + } else { + reject(xhr.response); + } + } + } + xhr.open("POST", url, true); + xhr.send(formData); + }); + } + + fetchResult(id:string,accessMode:string,date:string){ + this._searchCrossrefService.searchCrossrefByDOIs([id]).subscribe( + data => { + + var crossrefResult = data.items[0]; + if(data.items.length > 0){ + this.foundIds.push(id); + var result: ClaimResult = ClaimResult.generateResult(crossrefResult, id,"crossref","publication", crossrefResult.URL, crossrefResult.title, crossrefResult.created['date-time'], accessMode); + result.embargoEndDate = date; + this.results.push(result); + this.endOfFetching(); + }else{ + this.searchInDatacite(id,accessMode,date); + // this.notFoundIds.push(id); + } + }, + err => { + console.log(err); + this.notFoundIds.push(id); + this.endOfFetching(); + } + ); + } + searchInDatacite(id:string,accessMode:string,date:string){ + this._searchDataciteService.getDataciteResultByDOI(id).subscribe( + item => { + var dataciteResult = item.data; + + if(dataciteResult != null && dataciteResult.attributes!= null ){ + + this.foundIds.push(id); + var result: ClaimResult = ClaimResult.generateResult(dataciteResult, id,"datacite","dataset", 'http://dx.doi.org/'+dataciteResult.attributes.doi, dataciteResult.attributes.title, dataciteResult.attributes.published, accessMode); + result.embargoEndDate = date; + this.results.push(result); + }else{ + this.notFoundIds.push(id); + } + this.endOfFetching(); + }, + err => { + console.log(err); + this.notFoundIds.push(id); + this.endOfFetching(); + } + ); + } + endOfFetching(){ + if(this.allIds.length == this.foundIds.length+this.notFoundIds.length+ this.duplicateIds.length ){ + this.showReport = true; + this.enableUpload = true; + this.loading.close(); + + } + + } +} diff --git a/portal-4cli/src/app/claims/linking/bulkClaim/bulkClaim.module.ts b/portal-4cli/src/app/claims/linking/bulkClaim/bulkClaim.module.ts new file mode 100644 index 00000000..7f35a46f --- /dev/null +++ b/portal-4cli/src/app/claims/linking/bulkClaim/bulkClaim.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; + +import { SharedModule } from '../../../shared/shared.module'; +import {LoadingModalModule} from '../../../utils/modal/loadingModal.module'; +import {BulkClaimComponent} from './bulkClaim.component'; +import {SearchCrossrefServiceModule} from '../../claim-utils/service/searchCrossrefService.module'; +import {SearchDataciteServiceModule} from '../../claim-utils/service/searchDataciteService.module'; + +@NgModule({ + imports: [ + SharedModule, LoadingModalModule, SearchCrossrefServiceModule + ], + declarations: [ +BulkClaimComponent + ], exports:[ BulkClaimComponent] +}) +export class BulkClaimModule { } diff --git a/portal-4cli/src/app/claims/linking/bulkLinking.component.ts b/portal-4cli/src/app/claims/linking/bulkLinking.component.ts new file mode 100644 index 00000000..96e32dcf --- /dev/null +++ b/portal-4cli/src/app/claims/linking/bulkLinking.component.ts @@ -0,0 +1,16 @@ +// import {Component, Input} from '@angular/core'; +// import {Observable} from 'rxjs/Observable'; +// +// @Component({ +// selector: 'bulk-linking', +// //providers: [MdRadioDispatcher], +// template: ` +// +// ` +// +// }) +// //[(ngModel)]="date" +// export class BulkLinkingComponent { +// constructor () { +// } +// } diff --git a/portal-4cli/src/app/claims/linking/bulkLinking.module.ts b/portal-4cli/src/app/claims/linking/bulkLinking.module.ts new file mode 100644 index 00000000..55c71221 --- /dev/null +++ b/portal-4cli/src/app/claims/linking/bulkLinking.module.ts @@ -0,0 +1,20 @@ +// import { NgModule } from '@angular/core'; +// +// import { SharedModule } from '../../shared/shared.module'; +// import { BulkLinkingComponent } from './bulkLinking.component'; +// import { BulkLinkingRoutingModule } from './bulkLinking-routing.module'; +// import {LinkingGenericModule} from './linkingGeneric.module'; +// import {BulkClaimModule} from './bulkClaim/bulkClaim.module'; +// @NgModule({ +// imports: [ +// SharedModule, +// BulkLinkingRoutingModule, +// LinkingGenericModule, +// BulkClaimModule +// +// ], +// declarations: [ +// BulkLinkingComponent +// ], exports:[BulkLinkingComponent] +// }) +// export class BulkLinkingModule { } diff --git a/portal-4cli/src/app/claims/linking/insertClaim/insertClaim.component.ts b/portal-4cli/src/app/claims/linking/insertClaim/insertClaim.component.ts new file mode 100644 index 00000000..a916c757 --- /dev/null +++ b/portal-4cli/src/app/claims/linking/insertClaim/insertClaim.component.ts @@ -0,0 +1,369 @@ +import {Component, Input, Output, EventEmitter, ViewChild} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {Router} from '@angular/router'; +import {ClaimsService} from '../../claim-utils/service/claims.service'; + +import {ModalLoading} from '../../../utils/modal/loading.component'; +import {AlertModal} from '../../../utils/modal/alert'; +import {Md5} from 'ts-md5/dist/md5'; +import {Session} from '../../../login/utils/helper.class'; +import {ErrorCodes} from '../../../login/utils/guardHelper.class'; + +@Component({ + selector: 'claim-insert', + template: ` +
+ +
There are {{insertedClaims.length}} claims, follow the link to manage your claims
+
+
+ +
+ + + + + + + ` +}) +export class ClaimInsertComponent { + constructor (private claimService: ClaimsService, private _router:Router) {} + ngOnInit() { + // console.info("Inlineentity:" +(this.inlineEntity)?this.inlineEntity+(this.inlineEntity.id)?this.inlineEntity.id:"no id":"null"+ + " show "+ (!this.claiming && this.showButton) ); + } + + + @Input() public contexts; + @Input() public projects; + @Input() public results; + @Input() public showButton:boolean = true; + @Input() show='claim'; + @Input() inlineEntity = null; // the entity from the landing page + @Output() showChange = new EventEmitter(); + + @ViewChild (ModalLoading) loading : ModalLoading ; + @ViewChild(AlertModal) alert; + + public claiming =false; + public error = false; + public errorMessage = ""; + public warningMessage = ""; + public claimsTODO:number = 0; + public claims:number = 0; + + private servicesRespond:number = 0; + private insertedClaims=[]; + private errorInClaims=[]; + private insertedRecords=[]; + private errorInRecords=[]; +public validateInsertions(){ + // console.info("Inlineentity:" +(this.inlineEntity)?this.inlineEntity+(this.inlineEntity.id)?this.inlineEntity.id:"no id":"null"+ + " show "+ (!this.claiming && this.showButton) ); + if(this.validate()){ + if(this.validateDates()){ + this.insertActions(); + return true; + } + } + return +} +private insertActions(){ + this.servicesRespond = 0; + this.insertedClaims=[]; + this.errorInClaims=[]; + this.insertedRecords=[]; + this.errorInRecords=[]; + if(!Session.isValidAndRemove()){ + this.showButton = false; + localStorage.setItem("projects", JSON.stringify(this.projects)); + localStorage.setItem("contexts", JSON.stringify(this.contexts)); + localStorage.setItem("results", JSON.stringify(this.results)); + if(this.inlineEntity != null){ + localStorage.setItem("inlineEntity", JSON.stringify(this.inlineEntity)); + } + + this._router.navigate(['/user-info'], { queryParams: { "errorCode": ErrorCodes.NOT_VALID, "redirectUrl": this._router.url} }); + + }else{ + this.claiming = true; + var user=Session.getUserEmail(); + this.loading.open(); + var claims = []; + var directclaims = []; + if(this.results){ + console.info("results: "+this.results.length); + + for (var i = 0; i < this.results.length; i++) { + var result=this.results[i]; + if(["crossref","datacite","orcid"].indexOf(result.source) != -1){ + directclaims.push({"id":result.id, "record":this.createDirectClaim(result,this.projects,this.contexts)}); + } + if(this.contexts){ + for (var j = 0; j < this.contexts.length; j++) { + var context = this.contexts[j]; + var claim = this.createContextClaim(result, context, user); + claims.push(claim); + } + } + if(this.projects){ + for (var k = 0; k < this.projects.length; k++) { + var project = this.projects[k]; + var projectClaim = this.createProjectClaim(result, project, user); + claims.push(projectClaim); + } + } + if(this.inlineEntity != null){ + var resultClaim = this.createResultClaim(this.inlineEntity, result, user); + claims.push(resultClaim); + } + + } + } + //first call direct index service - when call is done (success or error) call isertBulkClaims method to insert claims in DB + console.info("\n\ndirectclaims: "+directclaims.length+"\n\n"); + this.claimService.insertDirectRecords(directclaims).subscribe( + data => { + this.insertedRecords = data.insertedIds; + + this.errorInRecords = data.errorInClaims; + this.isertBulkClaims(claims); + }, + err => { + err=err.json(); + if(err.insertedIds && err.insertedIds.length >0){ + this.insertedRecords = err.insertedIds; + } + if(err.errorInClaims && err.errorInClaims.length >0){ + this.errorInRecords = err.errorInClaims; + } + this.isertBulkClaims(claims); + } + ); + + } + +} + +private isertBulkClaims(claims){ + console.info("try to insert "+claims.length+" claims"); + this.claimService.insertBulkClaims(claims).subscribe( + data => { + this.insertedClaims = data.insertedIds; + this.errorInClaims = data.errorInClaims; + this.afterclaimsInsertion(); + }, + err => { + err=err.json(); + if(err.insertedIds && err.insertedIds.length >0){ + this.insertedClaims = err.insertedIds; + } + if(err.errorInClaims && err.errorInClaims.length >0){ + this.errorInClaims = err.errorInClaims; + } + this.afterclaimsInsertion(); + } + ); +} +private validate(){ + this.warningMessage = ""; + this.errorMessage = ""; + if( this.results && this.results.length == 0){ + this.warningMessage = "There are no research results selected."; + }else if((!this.contexts|| this.contexts.length==0 )&&(!this.projects|| this.projects.length==0 )&& ( this.inlineEntity == null)){ + this.warningMessage = "There are no projects or communities to link."; + // }else if (this.inline && !this.inlineEntity){ + // this.errorMessage = "No inline entity"; + // console.log(this.inline + " "+ this.inlineEntity); + }else{ + return true; + } + return false; +} +private validateDates(){ + if(this.projects){ + for (var k = 0; k < this.projects.length; k++) { + var project = this.projects[k]; + console.info(project.startDate+" "+project.endDate + " "+project.projectAcronym); + if(this.results){ + for (var i = 0; i < this.results.length; i++) { + var result = this.results[i]; + if(result.date && result.date != null){ + console.info("Date :"+ result.date + " & embargoEndDate :" +result.embargoEndDate ); + if((project.startDate && result.date < project.startDate) || ( project.endDate && result.date > (project.endDate+5)) ){ + this.confirmOpen(); + return false; + } + } + } + } + + + } + } + if(this.results){ + for (var i = 0; i < this.results.length; i++) { + var result = this.results[i]; + if(result.date && result.date != null){ + console.info("Date :"+ result.date + " & embargoEndDate :" +result.embargoEndDate ); + if((result.embargoEndDate && result.embargoEndDate != null) && result.date >result.embargoEndDate ){ + this.confirmOpen(); + return false; + } + } + } + } + + return true; +} +private afterclaimsInsertion(){ + + // this.servicesRespond++; + // if(this.servicesRespond == 2){ + this.loading.close(); + this.claiming = false; + + if(this.errorInClaims.length == 0 && this.insertedClaims.length > 0 && this.errorInRecords.length == 0){ + + this._router.navigate( ['/myclaims'] ); + this.showChange.emit({ + value: this.show + }); + }else{ + this.errorsInClaimsInsertion(); + } + // } +} +private errorsInClaimsInsertion(){ + this.errorMessage = ""; + this.loading.close(); + this.error = true; + this.claiming = false; + this.showButton = false; + var text ="" + console.log("Errors: this.errorInRecords.length: "+this.errorInRecords.length+" - this.errorInClaims.length: "+this.errorInClaims.length); + if(this.errorInRecords.length>0){ + text+="
The following records couldn't automatically inserted to the Openaire Info space:
    "; + for(var i=0; i< this.errorInRecords.length ; i++){ + for(var k=0; k< this.results.length ; k++){ + if(this.results[k].id == this.errorInRecords[i]){ + text+="
  • "+this.results[i].title+" from "+this.results[i].source+"
  • "; + } + } + } + text+="
"; + + } + if(this.errorInClaims.length > 0){ + text+="
The following links couldn't be saved:
    "; + for(var i=0; i< this.errorInClaims.length ; i++){ + // var claim = { claimedBy : user, sourceId : context.concept.id, sourceType : "context", sourceCollectedFrom:"openaire", sourceAccessRights:"OPEN", sourceEmbargoEndDate:"no", targetId : result.id , targetType : result.type, targetCollectedFrom: result.source, targetAccessRights:result.accessRights, targetEmbargoEndDate: (result.embargoEndDate == null?"":result.embargoEndDate)}; + + text+="
  • "+this.errorInClaims[i].sourceType+": "+this.errorInClaims[i].sourceId +"(from "+this.errorInClaims[i].sourceCollectedFrom+") link to "+this.errorInClaims[i].targetType+": "+this.errorInClaims[i].targetId +"(from "+this.errorInClaims[i].targetCollectedFrom+")
  • "; + + } + text+="
"; + } + this.errorMessage+="
An error occured:
"+text; + console.log(text); + // if(this.inline){ + // this.show = "error"; + // this.showChange.emit({ + // value: this.show + // }); + // } + +} + + + + private createContextClaim(result:any, context:any, user:any){ + var claim = { claimedBy : user, sourceId : context.concept.id, sourceType : "context", sourceCollectedFrom:"openaire", sourceAccessRights:"OPEN", sourceEmbargoEndDate:"no", targetId : result.id , targetType : result.type, targetCollectedFrom: result.source, targetAccessRights:result.accessRights, targetEmbargoEndDate: (result.embargoEndDate == null?"":result.embargoEndDate)}; + return claim; + } + private createProjectClaim(result:any, project:any, user:any){ + //project.projectId + // var dummyID = "dummyID"; + var claim = { claimedBy : user, sourceId : project.projectId, sourceType : "project", sourceCollectedFrom:"openaire", sourceAccessRights:"OPEN", sourceEmbargoEndDate:"", targetId : result.id , targetType : result.type, targetCollectedFrom: result.source, targetAccessRights:result.accessRights, targetEmbargoEndDate: (result.embargoEndDate == null?"":result.embargoEndDate)}; + return claim; + } + private createResultClaim(inlineResult:any, result:any, user:any){ + var claim = { claimedBy : user, sourceId : result.id, sourceType : result.type, sourceCollectedFrom: result.source, sourceAccessRights: result.accessRights, sourceEmbargoEndDate: result.embargoEndDate, targetId : inlineResult.id , targetType : inlineResult.type, targetCollectedFrom: inlineResult.source, targetAccessRights: inlineResult.accessRights, targetEmbargoEndDate: (inlineResult.embargoEndDate == null?"":inlineResult.embargoEndDate)}; + return claim; + } +createDirectClaim(result, projects, contexts){ + var entity = {}; + var md5_id = Md5.hashStr(result.id); + entity["originalId"]="userclaim___::"+md5_id; + entity["openaireId"]="userclaim___::"+md5_id; + entity["title"]=result.title; + entity["title"] =(Array.isArray(result.title) && result.title.length > 0 )?result.title[0]:result.title; + + if(result.authors && result.authors.length > 0){ + entity["authors"]=result.authors; + } + if(result.publisher){ + entity["publisher"]=result.publisher; + } + if(result.description){ + entity["description"]=result.description; + } + // entity["language"]=""; no info + entity["type"]=result.type; + if(result.source == "crossref" || result.source == "datacite"){ + entity["pids"]= [];//{type:string, value:string}[]; + entity["pids"].push({type:"doi",value:result.id}) + } + entity["licenseCode"]=result.accessRights; + if(result.accessRights == "EMBARGO"){ + entity["embargoEndDate"]=result.embargoEndDate; + } + if(result.type =="publication"){ + entity["resourceType"]="0001"; + }else{ + entity["resourceType"]="0021"; + } + entity["url"]=result.url; + entity["hostedById"]="openaire____::1256f046-bf1f-4afc-8b47-d0b147148b18"; + if(result.source == "crossref"){ + entity["collectedFromId"]="openaire____::crossref"; + }else if(result.source == "datacite"){ + entity["collectedFromId"]="openaire____::datacite"; + }else if(result.source == "orcid"){ + entity["collectedFromId"]="openaire____::orcid"; + }else if(result.source == "orpenaire"){ + entity["collectedFromId"]="openaire____::driver"; + } + + if(projects.length>0){ + entity["linksToProjects"]=[]; + for(var i =0; i < projects.length; i++){ + // "info:eu-repo/grantAgreement/EC/FP7/283595/EU//OpenAIREplus", + entity["linksToProjects"].push("info:eu-repo/grantAgreement/"+projects[i].funderName+"/"+projects[i].fundingLevel0+"/"+projects[i].code+"/"+projects[i].jurisdiction+"/"+projects[i].projectName+"/"+projects[i].projectAcronym); + } + } + if(contexts.length > 0){ + entity["contexts"]=[]; + for(var i =0; i < contexts.length; i++){ + entity["contexts"].push(contexts[i].concept.id); + } + } + var json = JSON.stringify(entity); + console.log("\nJSON:\n"+json); + return entity; + + + +} + confirmOpen(){ + this.alert.cancelButton = true; + this.alert.okButton = true; + this.alert.alertTitle = "Invalid dates"; + this.alert.message = "There is a research result whose publication date is after project end date or before project start date. Or embargo end date of a research result is before research result's publication date."; + this.alert.okButtonText = "Proceed anyway"; + this.alert.cancelButtonText = "Cancel"; + this.alert.open(); + } + confirmClose(data){ + this.insertActions(); + } +} diff --git a/portal-4cli/src/app/claims/linking/insertClaim/insertClaim.module.ts b/portal-4cli/src/app/claims/linking/insertClaim/insertClaim.module.ts new file mode 100644 index 00000000..6b2c4bb0 --- /dev/null +++ b/portal-4cli/src/app/claims/linking/insertClaim/insertClaim.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; + +import { SharedModule } from '../../../shared/shared.module'; +import {AlertModalModule} from '../../../utils/modal/alertModal.module'; +import {LoadingModalModule} from '../../../utils/modal/loadingModal.module'; +import {ClaimInsertComponent} from './insertClaim.component'; +import {ClaimServiceModule} from '../../claim-utils/service/claimsService.module'; + +@NgModule({ + imports: [ + SharedModule, AlertModalModule, LoadingModalModule, ClaimServiceModule + ], + declarations: [ClaimInsertComponent], + exports:[ ClaimInsertComponent] +}) +export class InsertClaimsModule { } diff --git a/portal-4cli/src/app/claims/linking/linking-routing.module.ts b/portal-4cli/src/app/claims/linking/linking-routing.module.ts new file mode 100644 index 00000000..2660b77f --- /dev/null +++ b/portal-4cli/src/app/claims/linking/linking-routing.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; +import { LoginGuard} from'../../login/loginGuard.guard'; + +import { LinkingGenericComponent } from './linkingGeneric.component'; +import {PreviousRouteRecorder} from'../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: LinkingGenericComponent, canActivate: [IsRouteEnabled, LoginGuard], data: { + redirect: '/error' + }, canDeactivate: [PreviousRouteRecorder]}, + + ]) + ] +}) +export class LinkingRoutingModule { } diff --git a/portal-4cli/src/app/claims/linking/linking.component.ts b/portal-4cli/src/app/claims/linking/linking.component.ts new file mode 100644 index 00000000..dbf7a23f --- /dev/null +++ b/portal-4cli/src/app/claims/linking/linking.component.ts @@ -0,0 +1,16 @@ +// import {Component, Input} from '@angular/core'; +// import {Observable} from 'rxjs/Observable'; +// import {LinkingGenericComponent} from './linkingGeneric.component'; +// +// @Component({ +// selector: 'linking', +// template: ` +// +// ` +// +// }) +// export class LinkingComponent { +// constructor () { +// } +// +// } diff --git a/portal-4cli/src/app/claims/linking/linkingGeneric.component.html b/portal-4cli/src/app/claims/linking/linkingGeneric.component.html new file mode 100644 index 00000000..218b2a68 --- /dev/null +++ b/portal-4cli/src/app/claims/linking/linkingGeneric.component.html @@ -0,0 +1,144 @@ +
+
+
+ +
+
+ Link +
+ +
+ +
+
+ +
+ + + + + + + + + + + + +
+ +
    +
  • + + +
  • +
  • + + +
  • + + +
+
+ + + + + +
+
+
+ + + + + + + + + + + + +
+ + +
+
+
+ + +
+ + + + +
+ +
+ + + + +
+ +
+
+
diff --git a/portal-4cli/src/app/claims/linking/linkingGeneric.component.ts b/portal-4cli/src/app/claims/linking/linkingGeneric.component.ts new file mode 100644 index 00000000..379b8677 --- /dev/null +++ b/portal-4cli/src/app/claims/linking/linkingGeneric.component.ts @@ -0,0 +1,117 @@ +import {Component, Input} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {ActivatedRoute, Router} from '@angular/router'; +import {EntitiesSearchService} from '../../utils/entitiesAutoComplete/entitySearch.service'; +import {ClaimProject, ClaimResult} from '../claim-utils/claimEntities.class'; +import {SearchPublicationsService} from '../../services/searchPublications.service'; +import {SearchDatasetsService} from '../../services/searchDatasets.service'; +import { Meta} from '../../../angular2-meta'; +declare var UIkit:any; + +@Component({ + selector: 'linking-generic', + templateUrl: 'linkingGeneric.component.html' + +}) +export class LinkingGenericComponent { + + @Input() bulkMode: boolean = false; + sourceType:string; + targetType:string; + step:number = 1; + contexts=[]; + projects=[]; + results = []; + show = "project"; + date='8-6-2016'; + keyword: string = ""; + linkType:string ="project"; // link type (selected in home page) : project, context, software, etc + /* url Parameters for inline linking */ + id:string = null; //entity id + type:string = null; // entity type (publication or research data) + linkTo:string = null; // entity type (project or context or result) + + entityTypes=["dataset", "publication", "project","context"]; + inlineResult:ClaimResult =null; + sub:any =null; + constructor ( private _router: Router, private route: ActivatedRoute, private entitySearch:EntitiesSearchService, + private publicationsSearch:SearchPublicationsService, private datasetsSearch:SearchDatasetsService, private _meta: Meta) { + this._meta.setTitle("OpenAIRE | Linking"); + } + ngOnInit() { + if( typeof localStorage !== 'undefined') { + if(localStorage.getItem("projects")){ + this.projects = JSON.parse(localStorage.getItem("projects")); + + } + if(localStorage.getItem("contexts")){ + this.contexts = JSON.parse(localStorage.getItem("contexts")); + } + if(localStorage.getItem("results")){ + this.results = JSON.parse(localStorage.getItem("results")); + + } + localStorage.removeItem("projects"); + localStorage.removeItem("contexts"); + localStorage.removeItem("results"); + } + } + + next(){ + + if((this.show == 'result' && this.keyword == '')||(this.show == 'dataset' || this.show == 'publication')){ + this.show='claim'; + + } + } + prev(){ + if(this.show == 'claim'){ + this.show='result'; + } + } + + + resultsChange($event) { + this.results=$event.value; + } + + projectsChange($event) { + this.projects=$event.value; + } + + linkTypeChange($event) { + + this.linkType =$event.value; + this.show="result"; + if(this.bulkMode){ + this.show="claim"; + } + } + + showChange($event) { + this.show=$event.value; + this.showChangedType($event.value); + } + + showChangedType(type:string) { + this.show=type; + if(this.show == 'project' || this.show == 'context' || this.show == 'software'){ + this.linkType = this.show; + } + } + + canProceedToMetadata(){ + if(this.results.length == 0){ + + UIkit.notification({ + message : 'No research results selected!
Please select research results to link with projects and/ or ommunities.', + status : 'warning', + timeout : 1000, + pos : 'top-center' + }); + }else{ + this.show = 'claim'; + this.step = 3; + } + } +} diff --git a/portal-4cli/src/app/claims/linking/linkingGeneric.module.ts b/portal-4cli/src/app/claims/linking/linkingGeneric.module.ts new file mode 100644 index 00000000..d9627a23 --- /dev/null +++ b/portal-4cli/src/app/claims/linking/linkingGeneric.module.ts @@ -0,0 +1,37 @@ +import { NgModule } from '@angular/core'; + +import { SharedModule } from '../../shared/shared.module'; +import {SelectedProjectsModule} from './selected/selectedProjects.module'; +import {SelectedContextsModule} from './selected/selectedContexts.module'; +import {SelectedPublicationsModule} from './selected/selectedResults.module'; +import {InsertClaimsModule} from './insertClaim/insertClaim.module'; +import {LinkingGenericComponent} from './linkingGeneric.component'; +import {EntitySearchServiceModule} from '../../utils/entitiesAutoComplete/entitySearchService.module'; +import {PublicationsServiceModule} from '../../services/publicationsService.module'; +import {DatasetsServiceModule} from '../../services/datasetsService.module'; +import { LinkingRoutingModule } from './linking-routing.module'; +import {StartOverModule} from '../claim-utils/startOver.module'; +import {LoginGuard} from'../../login/loginGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {ClaimContextSearchFormModule} from '../claim-utils/claimContextSearchForm.module'; +import {ClaimProjectsSearchFormModule} from '../claim-utils/claimProjectSearchForm.module'; +import {BulkClaimModule} from './bulkClaim/bulkClaim.module'; +import {ClaimResultSearchFormModule} from '../claim-utils/claimResultSearchForm.module'; +import {HelperModule} from '../../utils/helper/helper.module'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + SharedModule, SelectedProjectsModule, SelectedContextsModule, + SelectedPublicationsModule, + InsertClaimsModule, + EntitySearchServiceModule, PublicationsServiceModule, DatasetsServiceModule, LinkingRoutingModule, StartOverModule, + ClaimContextSearchFormModule, ClaimProjectsSearchFormModule, BulkClaimModule, ClaimResultSearchFormModule, HelperModule + ], + providers:[LoginGuard, PreviousRouteRecorder, IsRouteEnabled], + declarations: [ + LinkingGenericComponent + ], exports:[ + LinkingGenericComponent ] +}) +export class LinkingGenericModule { } diff --git a/portal-4cli/src/app/claims/linking/selected/selectedContexts.component.ts b/portal-4cli/src/app/claims/linking/selected/selectedContexts.component.ts new file mode 100644 index 00000000..c45f571e --- /dev/null +++ b/portal-4cli/src/app/claims/linking/selected/selectedContexts.component.ts @@ -0,0 +1,90 @@ +import {Component, Input,Output, EventEmitter} from '@angular/core'; +import {ClaimContext} from '../../claim-utils/claimEntities.class'; + +@Component({ + selector: 'claim-selected-contexts', + template: ` + + + +
+ + +
+

Selected Communities ({{contexts.length}})

+
    +
  • + {{context.community }} > {{context.category}} > {{context.concept.label}} + + +
  • +
+
+
There are no selected communities
+
+ + + + ` +}) +export class ClaimSelectedContextsComponent { + ngOnInit() { + var myDate = new Date(); + this.todayDate=( myDate.getFullYear()+ "-" +myDate.getMonth() + 1) + "-" + myDate.getDate() ; + this.nextDate= ( (myDate.getFullYear()+100)+ "-" +myDate.getMonth() + 1) + "-" + myDate.getDate() ; + //2015-05-01 + // if(this.linkType == "context"){ + this.showsearch = true + // }else{ + // this.showsearch = false; + // } +} + + + @Input() contexts:ClaimContext[]; + //The following need to be kept in case we have to save the current state + @Input() public projects; + @Input() public results; + @Input() public inlineEntity; + @Input() componentClass:string = ""; //"" or "col-sm-6" for horizontal display (besides projects) + @Input() show='home'; + @Input() title='Communities'; + @Input() linkType:string = "project"; + + @Input() hideType; + @Input() bulkMode:boolean = false; + @Output() showChange = new EventEmitter(); + + showsearch:boolean = false; + + todayDate = ''; + nextDate = ''; + + showType(type){ + if(type != this.show){ + this.show = type; + this.showChange.emit({ + value: this.show + }); + } + } + + + removeContext(item:any){ + var index:number =this.contexts.indexOf(item); + if (index > -1) { + this.contexts.splice(index, 1); + } + + } + contextSelected($event) { + // this.showsearch = false; + } + +} diff --git a/portal-4cli/src/app/claims/linking/selected/selectedContexts.module.ts b/portal-4cli/src/app/claims/linking/selected/selectedContexts.module.ts new file mode 100644 index 00000000..08d3d059 --- /dev/null +++ b/portal-4cli/src/app/claims/linking/selected/selectedContexts.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; + +import { SharedModule } from '../../../shared/shared.module'; +import {ClaimSelectedContextsComponent} from './selectedContexts.component'; +// import {ClaimContextSearchFormModule} from '../../claim-utils/claimContextSearchForm.module'; + + @NgModule({ + imports: [ + SharedModule, + // ClaimContextSearchFormModule + ], + declarations: [ + ClaimSelectedContextsComponent + ], exports:[ClaimSelectedContextsComponent] +}) +export class SelectedContextsModule { } diff --git a/portal-4cli/src/app/claims/linking/selected/selectedProjects.component.ts b/portal-4cli/src/app/claims/linking/selected/selectedProjects.component.ts new file mode 100644 index 00000000..5850f11b --- /dev/null +++ b/portal-4cli/src/app/claims/linking/selected/selectedProjects.component.ts @@ -0,0 +1,88 @@ +import {Component, Input,Output, EventEmitter} from '@angular/core'; +import {ClaimProject} from '../../claim-utils/claimEntities.class'; +import {RouterHelper} from '../../../utils/routerHelper.class'; + +@Component({ + selector: 'claim-selected-projects', + template: ` + + +
+ + + +
There are no selected projects
+
+ + + + ` +}) +export class ClaimSelectedProjectsComponent { + + +ngOnInit() { + var myDate = new Date(); + this.todayDate=( myDate.getFullYear()+ "-" +myDate.getMonth() + 1) + "-" + myDate.getDate() ; + this.nextDate= ( (myDate.getFullYear()+100)+ "-" +myDate.getMonth() + 1) + "-" + myDate.getDate() ; + // if(this.linkType == "project"){ + this.showsearch = true + // }else{ + // this.showsearch = false; + // } + //2015-05-01 +} + + +@Input() projects: ClaimProject[]; +@Input() show='home'; +@Input() title='Projects'; +@Input() linkType:string = "project"; +@Input() hideType; +@Input() bulkMode:boolean = false; +@Input() linkToResults:boolean = true; +@Output() projectsChange = new EventEmitter(); +@Output() showChange = new EventEmitter(); +showsearch:boolean = false; + +todayDate = ''; +nextDate = ''; +public routerHelper:RouterHelper = new RouterHelper(); + +removeProject(item:any){ + var index:number =this.projects.indexOf(item); + if (index > -1) { + this.projects.splice(index, 1); + } + this.projectsChange.emit({ + value: this.projects + }); +} +showType(type){ +if(type != this.show){ + this.show = type; + this.showChange.emit({ + value: this.show + }); +} +} +projectSelected($event) { + // this.showsearch = false; +} + + +} diff --git a/portal-4cli/src/app/claims/linking/selected/selectedProjects.module.ts b/portal-4cli/src/app/claims/linking/selected/selectedProjects.module.ts new file mode 100644 index 00000000..e3d96ef7 --- /dev/null +++ b/portal-4cli/src/app/claims/linking/selected/selectedProjects.module.ts @@ -0,0 +1,18 @@ + +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { SharedModule } from '../../../shared/shared.module'; +import {ClaimSelectedProjectsComponent} from './selectedProjects.component'; +// import {ClaimProjectsSearchFormModule} from '../../claim-utils/claimProjectSearchForm.module'; + + @NgModule({ + imports: [ + SharedModule, RouterModule, + // ClaimProjectsSearchFormModule + ], + declarations: [ + ClaimSelectedProjectsComponent + ], exports:[ClaimSelectedProjectsComponent] +}) +export class SelectedProjectsModule { } diff --git a/portal-4cli/src/app/claims/linking/selected/selectedResults.component.ts b/portal-4cli/src/app/claims/linking/selected/selectedResults.component.ts new file mode 100644 index 00000000..a33abc1f --- /dev/null +++ b/portal-4cli/src/app/claims/linking/selected/selectedResults.component.ts @@ -0,0 +1,224 @@ +import {Component, Input,Output, EventEmitter, ViewChild} from '@angular/core'; +import {AlertModal} from '../../../utils/modal/alert'; +import {ClaimResult} from '../../claim-utils/claimEntities.class'; +import {IMyOptions, IMyDateModel} from '../../../utils/my-date-picker/interfaces/index'; +import {Dates} from '../../../utils/string-utils.class'; + +@Component({ + selector: 'claim-selected-results', + template: ` + + + + + +
+
There are no selected research results
+
+

{{title}} ({{results.length}})

+ + + + + + + + + + + + + + + + + + +
Research Result Change type and access mode
+
+ + {{pub.title}} + {{pub.title}} + +
+ + Publisher: {{pub.publisher}} + Journal: {{pub.result['journal-title'].value}} + ({{pub.date.substring(0,4)}}) + +
Authors: {{author}}{{(i < (pub.authors.slice(0,10).length-1))?"; ":""}}{{(i == pub.authors.slice(0,10).length-1 && pub.authors.length > 10)?"...":""}}
+ + + +
Editors: {{author.family}} {{author.given}}{{(i < (pub.result.editor.slice(0,10).length-1))?"; ":""}}{{(i == pub.result.editor.slice(0,10).length-1 && pub.result.editor.length > 10)?"...":""}}
+ + +
Authors: {{author}}{{(i < (pub.result.authors.slice(0,10).length-1))?"; ":""}}{{(i == pub.result.authors.slice(0,10).length-1 && pub.result.authors.length > 10)?"...":""}}
+ + + + + + +
{{pub.source}} + {{pub.accessRights}} + {{pub.type}} +
+
+ + + + + + + + Currently you cannot change metadata from OpenAIRE + +
+
+ + +
+
+
+ + + ` + +}) +export class ClaimSelectedResultsComponent { + ngOnInit() { + var myDate = new Date(); + this.nextDate = { date: { year: myDate.getFullYear()+10, month: (myDate.getMonth()+1), day: myDate.getDate() } }; + //2015-05-01 + +} + + @Input() results: ClaimResult[]; + @Input() title:string = "Research Results"; + @Input() showAccessRights:boolean = false; + @Input() bulkMode:boolean = false; + // @Output()resultsChange = new EventEmitter(); + @Input() showSearch:boolean = false; + nextDate = {}; + @ViewChild(AlertModal) alertApplyAll; + +public commonAccessRights = "OPEN"; // for access rights- changes when user apply a change to every result +public commonEmbargoEndDate; // for access rights: embargoEndDate - changes when user apply a change to every result +public commonType; // for research result type - changes when user apply a change to every result +public typeChanged:boolean = true; // +accessTypes = ["OPEN","CLOSED","EMBARGO","RESTRICTED"]; +private myDatePickerOptions: IMyOptions = { + // other options... + dateFormat: 'yyyy-mm-dd', + selectionTxtFontSize: '15px', + height:'28px', + width: '100%', + editableDateField: false, + showClearDateBtn: false + }; + + + removePublication(item:any){ + var index:number =this.results.indexOf(item); + if (index > -1) { + this.results.splice(index, 1); + } + // this.resultsChange.emit({ + // value: this.results + // }); + } + + + onDateChanged (event:any, item:any) { + item.embargoEndDate = Dates.getDateFromString(event.formatted); + if(this.results.length > 1 ){ + this.commonAccessRights = "EMBARGO"; + this.commonEmbargoEndDate = item.embargoEndDate; + this.confirmOpen(false,"Do you wish to apply the change to every result?"); + } + + } + onTypeChanged (event:any, item:any) { + item.type =(event); + if(this.results.length > 1 ){ + this.commonType = item.type; + this.confirmOpen(true, "Do you wish to apply the change to every result?"); + } + + } + // resultsChanged($event) { + // this.results=$event.value; + // this.resultsChange.emit({ + // value: this.results + // }); + // } + /* The following methods: + *typeChanged + *confirmOpen + *confirmClose + implement the functionality: change accessRights of a publication - apply to all if asked */ + accessRightsTypeChanged (type:any, item:any) { + item.accessRights = type; + if(this.results.length > 1 ){ + this.commonAccessRights = type; + if(this.commonAccessRights != "EMBARGO"){ + this.commonEmbargoEndDate = item.embargoEndDate; + this.confirmOpen(false, "Do you wish to apply the change to every result?"); + } + } + + } + confirmOpen(type: boolean, message: string){ + this.typeChanged = type; + this.alertApplyAll.cancelButton = true; + this.alertApplyAll.okButton = true; + this.alertApplyAll.alertTitle = "Change metadata"; + this.alertApplyAll.message = "Do you wish to apply the change to every result?"; + this.alertApplyAll.okButtonText = "Yes"; + this.alertApplyAll.cancelButtonText = "No"; + this.alertApplyAll.open(); + } + confirmClose(data){ + if(this.typeChanged){ + + for (var i = 0; i < this.results.length; i++) { + if(this.results[i].source != 'openaire' ){ + this.results[i].type = this.commonType; + } + } + + }else{ + for (var i = 0; i < this.results.length; i++) { + if(this.results[i].source != 'openaire' ){ + this.results[i].accessRights = this.commonAccessRights; + if(this.commonAccessRights == "EMBARGO"){ + this.results[i].embargoEndDate = this.commonEmbargoEndDate; + } + } + } + } + } +} diff --git a/portal-4cli/src/app/claims/linking/selected/selectedResults.module.ts b/portal-4cli/src/app/claims/linking/selected/selectedResults.module.ts new file mode 100644 index 00000000..0b12fb2d --- /dev/null +++ b/portal-4cli/src/app/claims/linking/selected/selectedResults.module.ts @@ -0,0 +1,21 @@ +import { NgModule } from '@angular/core'; + +import { SharedModule } from '../../../shared/shared.module'; +import {ClaimSelectedResultsComponent} from './selectedResults.component'; +import {AlertModalModule} from '../../../utils/modal/alertModal.module'; +import { MyDatePickerModule } from '../../../utils/my-date-picker/my-date-picker.module'; +// import {BulkClaimModule} from '../bulkClaim/bulkClaim.module'; +// import {ClaimResultSearchFormModule} from '../../claim-utils/claimResultSearchForm.module'; + +@NgModule({ + imports: [ + SharedModule, + AlertModalModule, + MyDatePickerModule, + // BulkClaimModule, ClaimResultSearchFormModule, + ], + declarations: [ + ClaimSelectedResultsComponent + ], exports:[ClaimSelectedResultsComponent] +}) +export class SelectedPublicationsModule { } diff --git a/portal-4cli/src/app/claims/myClaims/myClaims-routing.module.ts b/portal-4cli/src/app/claims/myClaims/myClaims-routing.module.ts new file mode 100644 index 00000000..a5f99f5f --- /dev/null +++ b/portal-4cli/src/app/claims/myClaims/myClaims-routing.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; +import { LoginGuard} from'../../login/loginGuard.guard'; + +import { MyClaimsComponent } from './myClaims.component'; +import {PreviousRouteRecorder} from'../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: MyClaimsComponent, canActivate: [IsRouteEnabled, LoginGuard], + data: {redirect: '/error'}, canDeactivate: [PreviousRouteRecorder]}]) + ] +}) +export class MyClaimsRoutingModule { } diff --git a/portal-4cli/src/app/claims/myClaims/myClaims.component.ts b/portal-4cli/src/app/claims/myClaims/myClaims.component.ts new file mode 100644 index 00000000..f3d5adc3 --- /dev/null +++ b/portal-4cli/src/app/claims/myClaims/myClaims.component.ts @@ -0,0 +1,36 @@ +import {Component, Input} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import { Meta} from '../../../angular2-meta'; + + +@Component({ + selector: 'my-claims', + template: ` +
+
+
+ +
+
+ My Claims +
+ +
+
+
+
+` + +}) + export class MyClaimsComponent { + constructor ( private _meta: Meta ) { + this._meta.setTitle("OpenAIRE | My Claims"); + } + ngOnInit() { + + } + +} diff --git a/portal-4cli/src/app/claims/myClaims/myClaims.module.ts b/portal-4cli/src/app/claims/myClaims/myClaims.module.ts new file mode 100644 index 00000000..e7f0199b --- /dev/null +++ b/portal-4cli/src/app/claims/myClaims/myClaims.module.ts @@ -0,0 +1,25 @@ +import { NgModule } from '@angular/core'; + +import { SharedModule } from '../../shared/shared.module'; +import { MyClaimsComponent } from './myClaims.component'; +import { MyClaimsRoutingModule } from './myClaims-routing.module'; +// import{ClaimServiceModule} from '../claim-utils/service/claimsService.module'; +import {DisplayClaimsModule} from '../claim-utils/displayClaims/displayClaims.module'; +import {LoginGuard} from'../../login/loginGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + SharedModule, + MyClaimsRoutingModule, + // ClaimServiceModule, + DisplayClaimsModule + + ], + providers:[LoginGuard, PreviousRouteRecorder, IsRouteEnabled], + declarations: [ + MyClaimsComponent + ] +}) +export class MyClaimsModule { } diff --git a/portal-4cli/src/app/claims/myClaimsDemo.component.ts b/portal-4cli/src/app/claims/myClaimsDemo.component.ts new file mode 100644 index 00000000..6490a59c --- /dev/null +++ b/portal-4cli/src/app/claims/myClaimsDemo.component.ts @@ -0,0 +1,51 @@ +// import {Component, Input} from '@angular/core'; +// import {Observable} from 'rxjs/Observable'; +// import { Router } from '@angular/router'; +// +// +// +// @Component({ +// selector: 'my-claims-demo', +// template: ` +//
+// +//
+// +// +// +//

Extra parameters for claims admin

+// +// +// +// +// +// +// +//
+//
+// +// +// +// ` +// //(click)="changeOrderby('target')" +// //od_______908::3a5b2885656a91307156325644e73b92 +// +// }) +// export class MyClaimsDemoComponent { +// constructor ( private _router: Router ) { +// } +// user:string="argirok@di.uoa.gr"; +// ngOnInit() { +// +// } +// goToPub(id: number){ +// this._router.navigate( ['Publication', { articleId: id}] ); +// } +// } diff --git a/portal-4cli/src/app/deposit/datasets/depositBySubject.component.ts b/portal-4cli/src/app/deposit/datasets/depositBySubject.component.ts new file mode 100644 index 00000000..17a17268 --- /dev/null +++ b/portal-4cli/src/app/deposit/datasets/depositBySubject.component.ts @@ -0,0 +1,34 @@ +import {Component, Input} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import { Router } from '@angular/router'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; + + + +@Component({ + selector: 'deposit-by-subject', + template: ` +
+ +

Or search for domain specific repositories

+ +
+ + + +
+
+ ` +}) + +export class DepositBySubjectComponent { + @Input() subjectKeyword: string=''; + + constructor (private _router: Router) { } + + public search() { + this._router.navigate( ['participate/deposit-subject-result'], { queryParams: { "q": this.subjectKeyword } } ); + } +} diff --git a/portal-4cli/src/app/deposit/datasets/depositBySubjectResult-routing.module.ts b/portal-4cli/src/app/deposit/datasets/depositBySubjectResult-routing.module.ts new file mode 100644 index 00000000..e336d37b --- /dev/null +++ b/portal-4cli/src/app/deposit/datasets/depositBySubjectResult-routing.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { DepositBySubjectResultComponent } from './depositBySubjectResult.component'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PreviousRouteRecorder} from'../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: DepositBySubjectResultComponent, canActivate: [FreeGuard, IsRouteEnabled], data: { + redirect: '/error' + },canDeactivate: [PreviousRouteRecorder] } + + ]) + ] +}) +export class DepositBySubjectResultsRoutingModule { } diff --git a/portal-4cli/src/app/deposit/datasets/depositBySubjectResult.component.html b/portal-4cli/src/app/deposit/datasets/depositBySubjectResult.component.html new file mode 100644 index 00000000..940b4b58 --- /dev/null +++ b/portal-4cli/src/app/deposit/datasets/depositBySubjectResult.component.html @@ -0,0 +1,79 @@ + +
+
+
+ +
+
+ Deposit {{requestFor}} +
+ +
+
+ + + +
+
+ Keywords: {{subject}} + +
+
+
+ +
+
+ +
+ + + + +
+

Please use the information/contacts shown below to deposit your {{requestFor}}.

+ +
+ +
+
+ {{fetchDataproviders.searchUtils.totalResults}} content providers, page {{fetchDataproviders.searchUtils.page}} of {{(totalPages())}} +
+ + + +
+ +
+ No content providers found with classification "{{subject}}". +
+
+ An error occured. +
+ +
+ + You can still deposit your {{requestFor}} in + OpenAIRE's Zenodo catch-all repository () + hosted by CERN. +
+
+ +
+ + + +
+
+
+
diff --git a/portal-4cli/src/app/deposit/datasets/depositBySubjectResult.component.ts b/portal-4cli/src/app/deposit/datasets/depositBySubjectResult.component.ts new file mode 100644 index 00000000..438db3c1 --- /dev/null +++ b/portal-4cli/src/app/deposit/datasets/depositBySubjectResult.component.ts @@ -0,0 +1,127 @@ +import {Component, Input} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import { Router } from '@angular/router'; +import { ActivatedRoute } from '@angular/router'; +import { FetchDataproviders } from '../../utils/fetchEntitiesClasses/fetchDataproviders.class'; +import { SearchDataprovidersService } from '../../services/searchDataproviders.service'; + +import {OrganizationService} from '../../services/organization.service'; +import { Meta} from '../../../angular2-meta'; + +import {RouterHelper} from '../../utils/routerHelper.class'; +import {PiwikService} from '../../utils/piwik/piwik.service'; + +@Component({ + selector: 'deposit-by-subject-result', + templateUrl: 'depositBySubjectResult.component.html' +}) + +export class DepositBySubjectResultComponent { + @Input() compatibility: string = ''; + + // Type of entity: Publication or Research Data + @Input() requestFor: string = "Research Data"; + @Input() subject: string = ""; + + public newSubject: string= ""; + + public fetchDataproviders : FetchDataproviders; + public linkToSearchDataproviders = ""; + + // url of Zenodo + public zenodo: string; + + public page: number = 1; + + public status: number; + + public routerHelper:RouterHelper = new RouterHelper(); + public errorCodes:ErrorCodes = new ErrorCodes(); + + sub: any; + piwiksub: any; + + constructor ( private _router: Router, + private route: ActivatedRoute, + private _searchDataprovidersService: SearchDataprovidersService, + private _meta: Meta, private _piwikService:PiwikService) { + + this.zenodo = OpenaireProperties.getZenodoURL(); + this.fetchDataproviders = new FetchDataproviders(this._searchDataprovidersService); + + this.status = this.errorCodes.LOADING; + this.updateTitle("Deposit "+this.requestFor); + this.updateDescription("Openaire, repositories, open access, content provider, compatibility, organization, deposit "+ this.requestFor); + this.updateUrl(OpenaireProperties.getBaseLink()+this._router.url); + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.piwiksub = this._piwikService.trackView("Deposit "+this.requestFor).subscribe(); + } + } + + + + ngOnInit() { + console.info('depositResult init'); + + this.sub = this.route.queryParams.subscribe(params => { + this.subject = params['q']; + this.newSubject = this.subject; + this.searchDataproviders(); + }); + } + + // ngDoCheck() { + // if(this.organizationId == "" || this.organizationId == undefined) { + // this.organizationId = ""; + // this.status = this.errorCodes.ERROR; + // } + // } + + ngOnDestroy() { + this.sub.unsubscribe(); + if(this.piwiksub){ + this.piwiksub.unsubscribe(); + } + } + + public totalPages(): number { + let totalPages:any = this.fetchDataproviders.searchUtils.totalResults/(this.fetchDataproviders.searchUtils.size); + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, 10) + 1); + } + return totalPages; + } + + public searchDataproviders() { + this.subject = this.newSubject; + this.fetchDataproviders.getResultsBySubjectsForDeposit( (this.subject =="")?"*":this.subject, this.requestFor, this.page, 10); + this.linkToSearchDataproviders = OpenaireProperties.getLinkToSearchDataProviders(); + } + + public goToDeposit() { + if(this.requestFor == "Publications") { + this._router.navigate( ['participate/deposit-publications'] ); + } else if(this.requestFor == "Research Data") { + this._router.navigate( ['participate/deposit-datasets'] ); + } + } + public pageChange($event) { + this.page = +$event.value; + this.searchDataproviders(); + } + + private updateDescription(description:string){ + this._meta.updateMeta("description", description); + this._meta.updateProperty("og:description", description); + } + private updateTitle(title:string){ + var _prefix ="OpenAIRE | "; + var _title = _prefix + ((title.length> 50 ) ?title.substring(0,50):title); + this._meta.setTitle(_title ); + this._meta.updateProperty("og:title",_title); + } + private updateUrl(url:string){ + this._meta.updateProperty("og:url", url); + } +} diff --git a/portal-4cli/src/app/deposit/datasets/depositBySubjectResults.module.ts b/portal-4cli/src/app/deposit/datasets/depositBySubjectResults.module.ts new file mode 100644 index 00000000..3a27275c --- /dev/null +++ b/portal-4cli/src/app/deposit/datasets/depositBySubjectResults.module.ts @@ -0,0 +1,34 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import { DepositBySubjectResultComponent } from './depositBySubjectResult.component'; + +import {DepositBySubjectResultsRoutingModule} from './depositBySubjectResult-routing.module'; +import {DepoditModule} from '../deposit.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {PagingModule } from '../../utils/paging.module'; +import {DataProvidersServiceModule} from '../../services/dataProvidersService.module'; +import {SearchResultsModule } from '../../searchPages/searchUtils/searchResults.module'; +import {HelperModule} from '../../utils/helper/helper.module'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + DepoditModule, + DepositBySubjectResultsRoutingModule, SearchResultsModule, DataProvidersServiceModule, PagingModule, + HelperModule + ], + declarations: [ + + DepositBySubjectResultComponent + + ], + exports: [ + DepositBySubjectResultComponent + ], + providers: [FreeGuard,PreviousRouteRecorder, IsRouteEnabled] +}) +export class DepositBySubjectResultsModule { } diff --git a/portal-4cli/src/app/deposit/datasets/depositDatasets-routing.module.ts b/portal-4cli/src/app/deposit/datasets/depositDatasets-routing.module.ts new file mode 100644 index 00000000..0fd8260b --- /dev/null +++ b/portal-4cli/src/app/deposit/datasets/depositDatasets-routing.module.ts @@ -0,0 +1,20 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { DepositDatasetsComponent } from './depositDatasets.component'; +import { DepositDatasetsResultComponent } from './depositDatasetsResult.component'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; +import {PreviousRouteRecorder} from'../../utils/piwik/previousRouteRecorder.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: DepositDatasetsComponent, canActivate: [FreeGuard, IsRouteEnabled], data: { + redirect: '/error' + },canDeactivate: [PreviousRouteRecorder] } + + ]) + ] +}) +export class DepositDatasetsRoutingModule { } diff --git a/portal-4cli/src/app/deposit/datasets/depositDatasets.component.ts b/portal-4cli/src/app/deposit/datasets/depositDatasets.component.ts new file mode 100644 index 00000000..4c468aeb --- /dev/null +++ b/portal-4cli/src/app/deposit/datasets/depositDatasets.component.ts @@ -0,0 +1,21 @@ +import {Component} from '@angular/core'; + +@Component({ + selector: 'deposit-datasets', + template: ` +
+
+
+ +
+ +
+
+
+
+ ` +}) + +export class DepositDatasetsComponent { + +} diff --git a/portal-4cli/src/app/deposit/datasets/depositDatasets.module.ts b/portal-4cli/src/app/deposit/datasets/depositDatasets.module.ts new file mode 100644 index 00000000..3612863c --- /dev/null +++ b/portal-4cli/src/app/deposit/datasets/depositDatasets.module.ts @@ -0,0 +1,29 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import { DepositDatasetsComponent } from './depositDatasets.component'; +import { DepositDatasetsResultComponent } from './depositDatasetsResult.component'; +import {DepositDatasetsRoutingModule} from './depositDatasets-routing.module'; +import {DepoditModule} from '../deposit.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + DepoditModule, + DepositDatasetsRoutingModule + ], + declarations: [ + + DepositDatasetsComponent + + ], + exports: [ + DepositDatasetsComponent + ], + providers: [FreeGuard,PreviousRouteRecorder, IsRouteEnabled] +}) +export class DepositDatasetsModule { } diff --git a/portal-4cli/src/app/deposit/datasets/depositDatasetsResult.component.ts b/portal-4cli/src/app/deposit/datasets/depositDatasetsResult.component.ts new file mode 100644 index 00000000..edbe92db --- /dev/null +++ b/portal-4cli/src/app/deposit/datasets/depositDatasetsResult.component.ts @@ -0,0 +1,14 @@ +import {Component} from '@angular/core'; + +@Component({ + selector: 'deposit-datasets-result', + template: ` + + + + ` +}) + +export class DepositDatasetsResultComponent { + +} diff --git a/portal-4cli/src/app/deposit/datasets/depositDatasetsResults-routing.module.ts b/portal-4cli/src/app/deposit/datasets/depositDatasetsResults-routing.module.ts new file mode 100644 index 00000000..fb59803e --- /dev/null +++ b/portal-4cli/src/app/deposit/datasets/depositDatasetsResults-routing.module.ts @@ -0,0 +1,18 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; +import {PreviousRouteRecorder} from'../../utils/piwik/previousRouteRecorder.guard'; +import { DepositDatasetsResultComponent } from './depositDatasetsResult.component'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: DepositDatasetsResultComponent, canActivate: [FreeGuard, IsRouteEnabled], data: { + redirect: '/error' + },canDeactivate: [PreviousRouteRecorder] } + + ]) + ] +}) +export class DepositDatasetsResultsRoutingModule { } diff --git a/portal-4cli/src/app/deposit/datasets/depositDatasetsResults.module.ts b/portal-4cli/src/app/deposit/datasets/depositDatasetsResults.module.ts new file mode 100644 index 00000000..6fc3d2e8 --- /dev/null +++ b/portal-4cli/src/app/deposit/datasets/depositDatasetsResults.module.ts @@ -0,0 +1,29 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import { DepositDatasetsResultComponent } from './depositDatasetsResult.component'; + +import {DepositDatasetsResultsRoutingModule} from './depositDatasetsResults-routing.module'; +import {DepoditModule} from '../deposit.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + DepoditModule, + DepositDatasetsResultsRoutingModule + ], + declarations: [ + + DepositDatasetsResultComponent, + + ], + exports: [ + DepositDatasetsResultComponent, + ], + providers: [FreeGuard,PreviousRouteRecorder, IsRouteEnabled] +}) +export class DepositDatasetsResultsModule { } diff --git a/portal-4cli/src/app/deposit/deposit.component.html b/portal-4cli/src/app/deposit/deposit.component.html new file mode 100644 index 00000000..8415b1e8 --- /dev/null +++ b/portal-4cli/src/app/deposit/deposit.component.html @@ -0,0 +1,56 @@ +
+
+ Deposit {{requestFor}} +
+
+ +
+
+ +
+
+

+ + Are you a grant recipient from the following: H2020; FP7 with SC39; or ERC? + + Then you are required to publish in + open access (). + One way to do this is to deposit your {{requestFor}} into an + open access repository (). +

+

+ Click the following to find more information: + FP7 guidelines (), + H2020 guidelines (), + ERC guidelines () OR + ask a question () to OpenAIRE’s national representative. +

+
+

Locate repository via your institution

+ +
+
+ + +
+ + +
+
+ +
+
+

Or locate repository in map

+
+ +
+
+
+ +
+ +
diff --git a/portal-4cli/src/app/deposit/deposit.component.ts b/portal-4cli/src/app/deposit/deposit.component.ts new file mode 100644 index 00000000..04565a11 --- /dev/null +++ b/portal-4cli/src/app/deposit/deposit.component.ts @@ -0,0 +1,91 @@ +import {Component, Input} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import { Router } from '@angular/router'; +import {OpenaireProperties} from '../utils/properties/openaireProperties'; +import { Meta} from '../../angular2-meta'; +import {PiwikService} from '../utils/piwik/piwik.service'; + + +@Component({ + selector: 'deposit', + templateUrl: 'deposit.component.html' +}) + +export class DepositComponent { + @Input() compatibility: string = ''; + @Input() mapUrl: string = null; // optional in case i-frame is needed + @Input() searchBySubjects: boolean = false; // optional: in case search by subjects is needed + + + public status: number; + + // Type of entity: Publication or Research Data + @Input() requestFor: string = "Publications"; + + // url's needed for information text + public openAccess: string; + public openAccessRepo: string; + public fp7Guidlines: string; + public h2020Guidlines: string; + public ercGuidlines: string; + public helpdesk: string; + + // Id of the new selected organization to be searched + public selectedId: string = ""; + + public warningMessage: string = ""; + + piwiksub:any; + + constructor (private _router: Router, private _meta: Meta, private _piwikService:PiwikService) { + + this.openAccess = OpenaireProperties.getOpenAccess(); + this.openAccessRepo = OpenaireProperties.getOpenAccessRepo(); + this.fp7Guidlines = OpenaireProperties.getFP7Guidlines(); + this.h2020Guidlines = OpenaireProperties.getH2020Guidlines(); + this.ercGuidlines = OpenaireProperties.getERCGuidlines(); + this.helpdesk = OpenaireProperties.getHelpdesk(); + this.updateTitle("Deposit "+this.requestFor); + this.updateDescription("Openaire, repositories, open access, content provider, compatibility, organization, deposit "+ this.requestFor); + this.updateUrl(OpenaireProperties.getBaseLink()+this._router.url); + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.piwiksub = this._piwikService.trackView("Deposit "+this.requestFor).subscribe(); + } + } + ngOnDestroy() { + if(this.piwiksub){ + this.piwiksub.unsubscribe(); + } + } + + public organizationSelected(id: string) { + console.info("organization selected"); + if(id && id.length > 0){ + if(this.requestFor == "Publications") { + this._router.navigate( ['participate/deposit-publications-result'], { queryParams: { "organizationId": id } } ); + } else if(this.requestFor == "Research Data") { + this._router.navigate( ['participate/deposit-datasets-result'], { queryParams: { "organizationId": id } } ); + } + } else { + this.warningMessage = "No organization selected"; + } + } + + public valueChanged($event){ + this.selectedId = $event.value; + } + + private updateDescription(description:string){ + this._meta.updateMeta("description", description); + this._meta.updateProperty("og:description", description); + } + private updateTitle(title:string){ + var _prefix ="OpenAIRE | "; + var _title = _prefix + ((title.length> 50 ) ?title.substring(0,50):title); + this._meta.setTitle(_title ); + this._meta.updateProperty("og:title",_title); + } + private updateUrl(url:string){ + this._meta.updateProperty("og:url", url); + } +} diff --git a/portal-4cli/src/app/deposit/deposit.module.ts b/portal-4cli/src/app/deposit/deposit.module.ts new file mode 100644 index 00000000..6fa8149c --- /dev/null +++ b/portal-4cli/src/app/deposit/deposit.module.ts @@ -0,0 +1,45 @@ +/* Common Component of deposit for both research data & ppublications*/ + +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import { DepositComponent } from './deposit.component'; +import { DepositResultComponent } from './depositResult.component'; +import {EntitiesAutocompleteModule} from '../utils/entitiesAutoComplete/entitiesAutoComplete.module'; +import {DataProvidersServiceModule} from '../services/dataProvidersService.module'; +import {OrganizationServiceModule} from '../services/organizationService.module'; +import {SearchResultsModule } from '../searchPages/searchUtils/searchResults.module'; +import {PiwikServiceModule} from '../utils/piwik/piwikService.module'; +import {HelperModule} from '../utils/helper/helper.module'; +import { DepositBySubjectComponent } from './datasets/depositBySubject.component'; +import {IFrameModule} from '../utils/iframe.module'; + + + + @NgModule({ + imports: [ + CommonModule, FormsModule, + RouterModule, + EntitiesAutocompleteModule, + DataProvidersServiceModule, + OrganizationServiceModule, + SearchResultsModule, + PiwikServiceModule, + HelperModule, + IFrameModule + ], + declarations: [ + DepositComponent, + DepositResultComponent, + DepositBySubjectComponent + ], + exports: [ + DepositComponent, + DepositResultComponent + ], + providers: [ + ] +}) +export class DepoditModule { } diff --git a/portal-4cli/src/app/deposit/depositResult.component.ts b/portal-4cli/src/app/deposit/depositResult.component.ts new file mode 100644 index 00000000..be15f886 --- /dev/null +++ b/portal-4cli/src/app/deposit/depositResult.component.ts @@ -0,0 +1,284 @@ +import {Component, Input} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {OpenaireProperties, ErrorCodes} from '../utils/properties/openaireProperties'; +import { Router } from '@angular/router'; +import { ActivatedRoute } from '@angular/router'; +import { FetchDataproviders } from '../utils/fetchEntitiesClasses/fetchDataproviders.class'; +import { SearchDataprovidersService } from '../services/searchDataproviders.service'; + +import {OrganizationService} from '../services/organization.service'; +import { Meta} from '../../angular2-meta'; + +import {RouterHelper} from '../utils/routerHelper.class'; +import {PiwikService} from '../utils/piwik/piwik.service'; + +@Component({ + selector: 'deposit-result', + template: ` +
+
+
+ +
+
+ Deposit {{requestFor}} +
+ +
+ +
+ + + +
+

Locate repository via your institution

+ +
+
+ + +
+ + +
+
+ + +
+

+ content providers for institution: + + {{organization['name']}} () + + {{organization['name']}} +

+ + +
+ +
+

Please use the information/contacts shown below to deposit your {{requestFor}}.

+ + + + +
+ + +
+
+ + An error occured. + + No content providers found for institution: + + {{organization['name']}} () + + {{organization['name']}} + . +
+
+ No organization with ID: {{organizationId}} found. +
+
+ An error occured. +
+ + Service temprorarily unavailable. Please try again later. + +
+ No ID for organization. +
+ + You can still deposit your {{requestFor}} in + OpenAIRE's Zenodo catch-all repository () + hosted by CERN. +
+
+ +
+ + +
+
+
+
+ + ` +}) + +export class DepositResultComponent { + @Input() compatibility: string = ''; + + // Type of entity: Publication or Research Data + @Input() requestFor: string = "Publications"; + + public organization: {"name": string, "url": string}; + public organizationId: string = ""; + + // Id of the new selected organization to be searched + public selectedId: string = ""; + + public status: number; + public warningMessage: string = ""; + + public fetchDataproviders : FetchDataproviders; + public linkToSearchDataproviders: string = ""; + + // url of Zenodo + public zenodo: string; + + public routerHelper:RouterHelper = new RouterHelper(); + public errorCodes:ErrorCodes = new ErrorCodes(); + + sub: any; piwiksub: any; + + constructor ( private _router: Router, + private route: ActivatedRoute, + private _searchDataprovidersService: SearchDataprovidersService, + private _organizationService: OrganizationService, + private _meta: Meta, private _piwikService:PiwikService) { + + this.zenodo = OpenaireProperties.getZenodoURL(); + this.fetchDataproviders = new FetchDataproviders(this._searchDataprovidersService); + + this.status = this.errorCodes.LOADING; + this.updateTitle("Deposit "+this.requestFor); + this.updateDescription("Openaire, repositories, open access, content provider, compatibility, organization, deposit "+ this.requestFor); + this.updateUrl(OpenaireProperties.getBaseLink()+this._router.url); + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.piwiksub = this._piwikService.trackView("Deposit "+this.requestFor).subscribe(); + } + } + + ngOnInit() { + console.info('depositResult init'); + + this.sub = this.route.queryParams.subscribe(params => { + this.organizationId = params['organizationId']; + console.info("Id is :"+this.organizationId); + if(this.organizationId){ + this.getOrganizationInfo(); + } + this.selectedId = ""; + }); + } + + ngDoCheck() { + if(this.organizationId == "" || this.organizationId == undefined) { + this.organizationId = ""; + this.status = this.errorCodes.ERROR; + } + } + + ngOnDestroy() { + this.sub.unsubscribe(); + if(this.piwiksub){ + this.piwiksub.unsubscribe(); + } + } + + private searchDataproviders() { + // if(this.organization != undefined) { + // this.fetchDataproviders.getResults(this.organization.name, false, 1, 10); + // } else if(this.organizationId != undefined) { + this.fetchDataproviders.getResultsForDeposit( this.organizationId,this.requestFor, 1, 10); + //} + this.linkToSearchDataproviders = OpenaireProperties.getLinkToSearchDataProviders(); + } + + private getOrganizationInfo () { + console.info("inside getOrganizationInfo of component"); + + this._organizationService.getOrganizationInfo(this.organizationId).subscribe( + data => { + if(data == null) { + this.status = this.errorCodes.NOT_FOUND; + } else { + this.organization = data.title; + this.status = this.errorCodes.DONE; + this.searchDataproviders(); + } + }, + err => { + //console.log(err) + + if(err.status == '404') { + this.status = this.errorCodes.NOT_FOUND; + console.info("not found"); + } else if(err.status == '500') { + this.status = this.errorCodes.ERROR; + console.info("error"); + } else { + this.status = this.errorCodes.NOT_AVAILABLE; + console.info("not available"); + } + } + ); + } + + public goToDeposit() { + if(this.requestFor == "Publications") { + this._router.navigate( ['participate/deposit-publications'] ); + } else if(this.requestFor == "Research Data") { + this._router.navigate( ['participate/deposit-datasets'] ); + } + } + + public valueChanged($event){ + this.selectedId = $event.value; + } + + public organizationSelected(id: string) { + console.info("organization selected"); + if(id && id.length > 0 && id != this.organizationId){ + this.organization = null; + this.status = this.errorCodes.LOADING; + + if(this.requestFor == "Publications") { + this._router.navigate( ['participate/deposit-publications-result'], { queryParams: { "organizationId": id } } ); + } else if(this.requestFor == "Research Data") { + this._router.navigate( ['participate/deposit-datasets-result'], { queryParams: { "organizationId": id } } ); + } + } else { + this.warningMessage = "No new organization selected"; + } + } + + private updateDescription(description:string){ + this._meta.updateMeta("description", description); + this._meta.updateProperty("og:description", description); + } + private updateTitle(title:string){ + var _prefix ="OpenAIRE | "; + var _title = _prefix + ((title.length> 50 ) ?title.substring(0,50):title); + this._meta.setTitle(_title ); + this._meta.updateProperty("og:title",_title); + } + private updateUrl(url:string){ + this._meta.updateProperty("og:url", url); + } +} diff --git a/portal-4cli/src/app/deposit/publications/depositPublications-routing.module.ts b/portal-4cli/src/app/deposit/publications/depositPublications-routing.module.ts new file mode 100644 index 00000000..bead0e18 --- /dev/null +++ b/portal-4cli/src/app/deposit/publications/depositPublications-routing.module.ts @@ -0,0 +1,18 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; +import {PreviousRouteRecorder} from'../../utils/piwik/previousRouteRecorder.guard'; +import { DepositPublicationsComponent } from './depositPublications.component'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: DepositPublicationsComponent, canActivate: [FreeGuard, IsRouteEnabled], data: { + redirect: '/error' + }, canDeactivate: [PreviousRouteRecorder] } + + ]) + ] +}) +export class DepositPublicationsRoutingModule { } diff --git a/portal-4cli/src/app/deposit/publications/depositPublications.component.ts b/portal-4cli/src/app/deposit/publications/depositPublications.component.ts new file mode 100644 index 00000000..77ff9a23 --- /dev/null +++ b/portal-4cli/src/app/deposit/publications/depositPublications.component.ts @@ -0,0 +1,21 @@ +import {Component} from '@angular/core'; + +@Component({ + selector: 'deposit-publications', + template: ` +
+
+
+ +
+ +
+
+
+
+ ` +}) + +export class DepositPublicationsComponent { + public mapUrl ="https://beta.openaire.eu/stats/markers-demo.html"; +} diff --git a/portal-4cli/src/app/deposit/publications/depositPublications.module.ts b/portal-4cli/src/app/deposit/publications/depositPublications.module.ts new file mode 100644 index 00000000..ebe668c6 --- /dev/null +++ b/portal-4cli/src/app/deposit/publications/depositPublications.module.ts @@ -0,0 +1,27 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import { DepositPublicationsComponent } from './depositPublications.component'; + +import {DepositPublicationsRoutingModule} from './depositPublications-routing.module'; +import {DepoditModule} from '../deposit.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + DepoditModule, + DepositPublicationsRoutingModule + ], + declarations: [ + DepositPublicationsComponent + ], + exports: [ + DepositPublicationsComponent, + ], + providers: [FreeGuard,PreviousRouteRecorder, IsRouteEnabled] +}) +export class DepositPublicationsModule { } diff --git a/portal-4cli/src/app/deposit/publications/depositPublicationsResult-routing.module.ts b/portal-4cli/src/app/deposit/publications/depositPublicationsResult-routing.module.ts new file mode 100644 index 00000000..0d5dd77a --- /dev/null +++ b/portal-4cli/src/app/deposit/publications/depositPublicationsResult-routing.module.ts @@ -0,0 +1,18 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; +import {PreviousRouteRecorder} from'../../utils/piwik/previousRouteRecorder.guard'; +import { DepositPublicationsResultComponent } from './depositPublicationsResult.component'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: DepositPublicationsResultComponent, canActivate: [FreeGuard, IsRouteEnabled], data: { + redirect: '/error' + }, canDeactivate: [PreviousRouteRecorder] } + + ]) + ] +}) +export class DepositPublicationsResultRoutingModule { } diff --git a/portal-4cli/src/app/deposit/publications/depositPublicationsResult.component.ts b/portal-4cli/src/app/deposit/publications/depositPublicationsResult.component.ts new file mode 100644 index 00000000..c7da81eb --- /dev/null +++ b/portal-4cli/src/app/deposit/publications/depositPublicationsResult.component.ts @@ -0,0 +1,12 @@ +import {Component} from '@angular/core'; + +@Component({ + selector: 'deposit-publications-result', + template: ` + + ` +}) + +export class DepositPublicationsResultComponent { + +} diff --git a/portal-4cli/src/app/deposit/publications/depositPublicationsResults.module.ts b/portal-4cli/src/app/deposit/publications/depositPublicationsResults.module.ts new file mode 100644 index 00000000..1b5c45fc --- /dev/null +++ b/portal-4cli/src/app/deposit/publications/depositPublicationsResults.module.ts @@ -0,0 +1,27 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import { DepositPublicationsResultComponent } from './depositPublicationsResult.component'; + +import {DepositPublicationsResultRoutingModule} from './depositPublicationsResult-routing.module'; +import {DepoditModule} from '../deposit.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + DepoditModule, + DepositPublicationsResultRoutingModule + ], + declarations: [ + DepositPublicationsResultComponent + ], + exports: [ + DepositPublicationsResultComponent + ], + providers: [FreeGuard,PreviousRouteRecorder, IsRouteEnabled] +}) +export class DepositPublicationsResultsModule { } diff --git a/portal-4cli/src/app/error/error-routing.module.ts b/portal-4cli/src/app/error/error-routing.module.ts new file mode 100644 index 00000000..abb3c8f4 --- /dev/null +++ b/portal-4cli/src/app/error/error-routing.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { ErrorPageComponent } from './errorPage.component'; +import {PreviousRouteRecorder} from'../utils/piwik/previousRouteRecorder.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: ErrorPageComponent,canDeactivate: [PreviousRouteRecorder] }, + { path: '**', component: ErrorPageComponent,canDeactivate: [PreviousRouteRecorder] }, + + ]) + ] +}) +export class ErrorRoutingModule { } diff --git a/portal-4cli/src/app/error/error.module.ts b/portal-4cli/src/app/error/error.module.ts new file mode 100644 index 00000000..ee45d823 --- /dev/null +++ b/portal-4cli/src/app/error/error.module.ts @@ -0,0 +1,14 @@ +// import { NgModule} from '@angular/core'; +// import { CommonModule } from '@angular/common'; +// import { FormsModule } from '@angular/forms'; +// +// import { ErrorPageComponent } from './errorPage.component'; +// import { ErrorRoutingModule } from './error-routing.module'; +// import {PreviousRouteRecorder} from '../utils/piwik/previousRouteRecorder.guard'; +// +// @NgModule({ +// imports: [CommonModule, FormsModule, ErrorRoutingModule], +// providers:[PreviousRouteRecorder], +// declarations: [ErrorPageComponent] +// }) +// export class ErrorModule { } diff --git a/portal-4cli/src/app/error/errorPage.component.ts b/portal-4cli/src/app/error/errorPage.component.ts new file mode 100644 index 00000000..30029577 --- /dev/null +++ b/portal-4cli/src/app/error/errorPage.component.ts @@ -0,0 +1,55 @@ +import { Component, Input } from '@angular/core'; +import { Location } from '@angular/common'; +import { Meta} from '../../angular2-meta'; +import {ActivatedRoute} from '@angular/router'; + +@Component({ + selector: 'error', + template: ` +
+
+
+ +
+

+ Bad karma: we can't find that page! +

+
+ +

+ You asked for {{page}}, but despite our computers looking very hard, we could not find it. What happened ? +

+ +
    +
  • the link you clicked to arrive here has a typo in it
  • +
  • or somehow we removed that page, or gave it another name
  • +
  • or, quite unlikely for sure, maybe you typed it yourself and there was a little mistake ?
  • +
+ +
+
+
+
+ ` +}) + +export class ErrorPageComponent { + public page: string; + + constructor (private _location: Location, private _meta: Meta,private route: ActivatedRoute) { + this._meta.setTitle("OpenAIRE | Error page"); + this.page = _location.path(true); + //this.page = _router.url; + //this.page = location.href; + } + ngOnInit() { + this.route.queryParams.subscribe(data => { + + + this.page = data['page']; + if(!this.page){ + this.page = this._location.path(true); + } + }); + } +} diff --git a/portal-4cli/src/app/error/isRouteEnabled.guard.ts b/portal-4cli/src/app/error/isRouteEnabled.guard.ts new file mode 100644 index 00000000..c8566a5b --- /dev/null +++ b/portal-4cli/src/app/error/isRouteEnabled.guard.ts @@ -0,0 +1,23 @@ +import { Injectable } from '@angular/core'; +import { Router,CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router'; +import {Observable} from 'rxjs/Observable'; + +import { ConfigurationService } from '../utils/configuration/configuration.service'; + +@Injectable() +export class IsRouteEnabled implements CanActivate { + + constructor(private router: Router, private config: ConfigurationService) {} + + canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | boolean { + let customRedirect = route.data['redirect']; + console.log("In IsRouteEnabled"); + console.log(state.url.split("?")[0].substring(1)); + let isEnabled = this.config.isPageEnabled(state.url.split("?")[0].substring(1)); + let redirect = !!customRedirect ? customRedirect : '/error'; + isEnabled.filter(enabled => !enabled) + .subscribe(() => this.router.navigate([redirect], { queryParams: { "page": state.url } })); + + return isEnabled; + } +} diff --git a/portal-4cli/src/app/home/home-routing.module.ts b/portal-4cli/src/app/home/home-routing.module.ts new file mode 100644 index 00000000..6ba740bd --- /dev/null +++ b/portal-4cli/src/app/home/home-routing.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import{HomeComponent} from './home.component'; +import {FreeGuard} from'../login/freeGuard.guard'; +import {PreviousRouteRecorder} from '../utils/piwik/previousRouteRecorder.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: HomeComponent, canActivate: [FreeGuard], canDeactivate: [PreviousRouteRecorder] } + + ]) + ] +}) +export class HomeRoutingModule { } diff --git a/portal-4cli/src/app/home/home.component.html b/portal-4cli/src/app/home/home.component.html new file mode 100644 index 00000000..a1b1e1c4 --- /dev/null +++ b/portal-4cli/src/app/home/home.component.html @@ -0,0 +1,65 @@ + + + +
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+

+ {{publicationsSize.number}} {{publicationsSize.size}} publications +

+
+
+
+
+

+ {{datasetsSize.number}} {{datasetsSize.size}} research data +

+
+
+
+
+

+ {{datasourcesSize.number}} {{datasourcesSize.size}} data sources +

+
+
+
+
+

+ {{fundersSize.number}} {{fundersSize.size}} funders +

+
+
+
+
+ all linked together +
+
+
+
+
+
+
+
+ +
+ +
diff --git a/portal-4cli/src/app/home/home.component.ts b/portal-4cli/src/app/home/home.component.ts new file mode 100644 index 00000000..217b6bdc --- /dev/null +++ b/portal-4cli/src/app/home/home.component.ts @@ -0,0 +1,182 @@ +import {Component, Input, Output, EventEmitter, ViewChild, ChangeDetectionStrategy, ViewEncapsulation} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {ActivatedRoute, Router} from '@angular/router'; +import {Location} from '@angular/common'; + +import { Meta, MetaDefinition} from '../../angular2-meta'; +import {SearchPublicationsService} from '../services/searchPublications.service'; +import {SearchDataprovidersService} from '../services/searchDataproviders.service'; +import {SearchProjectsService} from '../services/searchProjects.service'; +import {SearchDatasetsService} from '../services/searchDatasets.service'; +import {SearchOrganizationsService} from '../services/searchOrganizations.service'; + +import {OpenaireProperties} from '../utils/properties/openaireProperties'; +import {SearchFields} from '../utils/properties/searchFields'; +import {ErrorCodes} from '../utils/properties/openaireProperties'; +import {RouterHelper} from '../utils/routerHelper.class'; +import {NumberUtils} from '../utils/number-utils.class'; +import {RefineFieldResultsService} from '../services/refineFieldResults.service'; +import {PiwikService} from '../utils/piwik/piwik.service'; +import { ConfigurationService } from '../utils/configuration/configuration.service'; + +@Component({ + selector: 'home', + templateUrl: 'home.component.html', +}) +export class HomeComponent { + public piwiksub: any; + public subfunders: any; + + public pageTitle = "OpenAIRE" + public keyword:string = ""; + + public searchFields:SearchFields = new SearchFields(); + public errorCodes:ErrorCodes = new ErrorCodes(); + public routerHelper:RouterHelper = new RouterHelper(); + + public publicationsSize:any = null; + public datasetsSize:any = null; + public fundersSize:any = null; + public projectsSize:any = null; + public datasourcesSize:any = null; + + showPublications:boolean= false; + showDatasets:boolean= false; + showProjects:boolean= false; + showDataProviders:boolean= false; + +public subPub;public subData;public subProjects;public subOrg; public subDataPr; + + constructor ( + private route: ActivatedRoute, + private _router: Router, + private _searchPublicationsService: SearchPublicationsService, + private _searchDataprovidersService: SearchDataprovidersService, + private _searchProjectsService: SearchProjectsService, + private _searchDatasetsService: SearchDatasetsService, + private _searchOrganizationsService: SearchOrganizationsService, + private _refineFieldResultsService:RefineFieldResultsService, + private location: Location, private _meta: Meta,private _piwikService:PiwikService, + private config: ConfigurationService) { + + var description = "open access, research, scientific publication, European Commission, EC, FP7, ERC, Horizon 2020, H2020, search, projects "; + + var title = "OpenAIRE"; + + var url = OpenaireProperties.getBaseLink()+this._router.url; + this._meta.setTitle(title); + this._meta.updateMeta("description", description); + this._meta.updateProperty("og:description", description); + this._meta.updateProperty("og:title", title); + this._meta.updateProperty("og:url", url); + + const entityOne = this.config.isEntityEnabled("publication"); + const entityTwo = this.config.isEntityEnabled("dataset"); + const entityThree = this.config.isEntityEnabled("project"); + const entityFour = this.config.isEntityEnabled("datasource"); + const example = Observable.zip(entityOne,entityTwo,entityThree,entityFour); + + //wait until all observables have emitted a value then emit all as an array + example.subscribe(data => { + this.showPublications = data[0]; + this.showDatasets = data[1]; + this.showProjects = data[2]; + this.showDataProviders = data[3]; + this.getNumbers(); + }); + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.piwiksub = this._piwikService.trackView("OpenAIRE").subscribe(); + } + + } + + public ngOnInit() { + } + public ngOnDestroy() { + if(this.piwiksub){ + this.piwiksub.unsubscribe(); + } + if(this.subfunders){ + this.subfunders.unsubscribe(); + } + if(this.subPub){ + this.subPub.unsubscribe(); + } + if(this.subData){ + this.subData.unsubscribe(); + } + // if(this.subProjects){ + // this.subProjects.unsubscribe(); + // } + // if(this.subOrg){ + // this.subOrg.unsubscribe(); + // } + if(this.subDataPr){ + this.subDataPr.unsubscribe(); + } + + } + + private getNumbers() { + if(this.showPublications){ + this.subPub = this._searchPublicationsService.numOfSearchPublications("").subscribe( + data => { + console.log("Count results: "+data); + if(data && data != null && data > 0 ){ + this.publicationsSize = NumberUtils.roundNumber(data); + console.log("After round"); + + } + }, + err => { + console.log(err); + } + ); + } + if(this.showDatasets){ + this.subData = this._searchDatasetsService.numOfSearchDatasets("").subscribe( + data => { + if(data && data != null && data > 0 ){ + this.datasetsSize = NumberUtils.roundNumber(data); + } + }, + err => { + console.log(err); + } + ); + } + if(this.showProjects){ + this.subfunders = this._refineFieldResultsService.getRefineFieldsResultsByEntityName(["funder"],"project").subscribe( + data => { + + console.info("Funders: "+data[1][0].title+ " values "+data[1][0].values.length+"]"); + console.info("Projects: "+data[0]); + + if(data[0] && data[0] > 0 ){ + this.projectsSize = NumberUtils.roundNumber(data[0]); + } + if(data[1].length > 0 && data[1][0].filterId == "funder" && data[1][0].values ){ + this.fundersSize = NumberUtils.roundNumber(data[1][0].values.length); + } + + }, + err => { + console.log(err); + }); + } + if(this.showDataProviders){ + this.subDataPr = this._searchDataprovidersService.numOfSearchDataproviders("").subscribe( + data => { + if(data && data != null && data > 0 ){ + this.datasourcesSize = NumberUtils.roundNumber(data); + } + + }, + err => { + console.log(err); + + } + ); + } + } +} diff --git a/portal-4cli/src/app/home/home.module.ts b/portal-4cli/src/app/home/home.module.ts new file mode 100644 index 00000000..61bbdc21 --- /dev/null +++ b/portal-4cli/src/app/home/home.module.ts @@ -0,0 +1,45 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import{HomeRoutingModule} from './home-routing.module'; +import{HomeComponent} from './home.component'; + + +import {DataProvidersServiceModule} from '../services/dataProvidersService.module'; +import {DatasetsServiceModule} from '../services/datasetsService.module'; +import {ProjectsServiceModule} from '../services/projectsService.module'; +import {PublicationsServiceModule} from '../services/publicationsService.module'; +import {OrganizationsServiceModule} from '../services/organizationsService.module'; +import {SearchFormModule} from '../searchPages/searchUtils/searchForm.module'; +import {FreeGuard} from'../login/freeGuard.guard'; +import {PiwikServiceModule} from '../utils/piwik/piwikService.module'; +import {PreviousRouteRecorder} from '../utils/piwik/previousRouteRecorder.guard'; +import {RefineFieldResultsServiceModule} from '../services/refineFieldResultsService.module'; +import {HelperModule} from '../utils/helper/helper.module'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, RouterModule, + RefineFieldResultsServiceModule, + DataProvidersServiceModule, DatasetsServiceModule, ProjectsServiceModule, + PublicationsServiceModule, + OrganizationsServiceModule, + SearchFormModule, + PiwikServiceModule, + HomeRoutingModule, + HelperModule + + ], + declarations: [ + HomeComponent + ], + providers:[ + FreeGuard, PreviousRouteRecorder + ], + exports: [ + HomeComponent + ] +}) +export class HomeModule { } diff --git a/portal-4cli/src/app/landingPages/dataProvider/dataProvider-routing.module.ts b/portal-4cli/src/app/landingPages/dataProvider/dataProvider-routing.module.ts new file mode 100644 index 00000000..7aaf631c --- /dev/null +++ b/portal-4cli/src/app/landingPages/dataProvider/dataProvider-routing.module.ts @@ -0,0 +1,18 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { DataProviderComponent } from './dataProvider.component'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PreviousRouteRecorder} from'../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: DataProviderComponent, canActivate: [FreeGuard, IsRouteEnabled], data: { + redirect: '/error' + },canDeactivate: [PreviousRouteRecorder] } + ]) +] +}) +export class DataProviderRoutingModule { } diff --git a/portal-4cli/src/app/landingPages/dataProvider/dataProvider.component.html b/portal-4cli/src/app/landingPages/dataProvider/dataProvider.component.html new file mode 100644 index 00000000..9e552a06 --- /dev/null +++ b/portal-4cli/src/app/landingPages/dataProvider/dataProvider.component.html @@ -0,0 +1,232 @@ +
+
+
+ +
+ + + + +
+ +
+ + +
{{dataProviderInfo.officialName}}
+ + {{dataProviderInfo.type}} + {{dataProviderInfo.compatibility}} + + + + +
+ + + + + + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+

Latest Research Result Timeline

+ +

Research Result Types

+ +
+ + +
+ +

Funders in Research Results of content provider

+ + +
+
+

Projects with most Publications

+ +
+
+
+

Projects with most Research Data

+ +
+
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+ Share - Bookmark +
+
+
+
+
+
+
diff --git a/portal-4cli/src/app/landingPages/dataProvider/dataProvider.component.ts b/portal-4cli/src/app/landingPages/dataProvider/dataProvider.component.ts new file mode 100644 index 00000000..155960ee --- /dev/null +++ b/portal-4cli/src/app/landingPages/dataProvider/dataProvider.component.ts @@ -0,0 +1,385 @@ +import {Component, ViewChild, ElementRef} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {DataProviderService} from './dataProvider.service'; +import {DataProviderInfo} from '../../utils/entities/dataProviderInfo'; +import {ActivatedRoute, Router} from '@angular/router'; +import { Meta} from '../../../angular2-meta'; +import { FetchPublications } from '../../utils/fetchEntitiesClasses/fetchPublications.class'; +import { SearchPublicationsService } from '../../services/searchPublications.service'; +import { FetchDatasets } from '../../utils/fetchEntitiesClasses/fetchDatasets.class'; +import { SearchDatasetsService } from '../../services/searchDatasets.service'; +import { FetchProjects } from '../../utils/fetchEntitiesClasses/fetchProjects.class'; +import { SearchProjectsService } from '../../services/searchProjects.service'; +import { FetchDataproviders } from '../../utils/fetchEntitiesClasses/fetchDataproviders.class'; +import { SearchDataprovidersService } from '../../services/searchDataproviders.service'; +import { RelatedDatasourcesTabComponent } from './relatedDatasourcesTab.component'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {RouterHelper} from '../../utils/routerHelper.class'; +import {PiwikService} from '../../utils/piwik/piwik.service'; + +import 'rxjs/add/operator/switch'; +import 'rxjs/add/operator/switchMap'; + +@Component({ + selector: 'dataprovider', + templateUrl: 'dataProvider.component.html', + }) + +export class DataProviderComponent { + public dataProviderInfo: DataProviderInfo; + public datasourceId: string; + + // Message variables + public warningMessage = ""; + public errorMessage = ""; + public showLoading: boolean = true; + + // Variable to specify requests with either collectedFrom or hostedBy + public paramsForSearchLink = {}; + + // Metrics tab variables + public metricsClicked: boolean; + public viewsFrameUrl: string; + public downloadsFrameUrl: string; + public totalViews: number; + public totalDownloads: number; + public pageViews: number; + + // Statistics tab variables + public statsClicked: boolean = false; + public docsTimelineUrl: string; + public docsTypesUrl:string; + public docsFunderUrl:string; + public dataProjectsUrl:string ; + public pubsProjectsUrl:string; + + // Variables for publications, research data, projects, content providers, related content providers tabs + public fetchPublications : FetchPublications; + public fetchDatasets: FetchDatasets; + public fetchProjects: FetchProjects; + public fetchDataproviders: FetchDataproviders; + public fetchAggregatorsPublications: FetchPublications; + public fetchAggregatorsDatasets: FetchDatasets; + + public loadingRelatedDatasources: boolean = true; + + // Active tab variable for responsiveness - show tabs only if main request is completed + public activeTab: string = ""; + public showTabs:boolean = false; + + public routerHelper:RouterHelper = new RouterHelper(); + public errorCodes:ErrorCodes = new ErrorCodes(); + + // Request results of each tab only the one time (first time tab is clicked) + private reloadPublications: boolean = true; + private reloadDatasets: boolean = true; + private reloadProjects: boolean = true; + private reloadDataproviders: boolean = true; + private reloadRelatedDatasources: boolean = true; + + private nativeElement : Node; + + sub: any; + piwiksub: any; + subInfo: any; + relatedDatasourcesSub: any; + + constructor (private element: ElementRef, + private _dataproviderService: DataProviderService, + private _piwikService:PiwikService, + private route: ActivatedRoute, + private _meta: Meta, + private _router: Router, + private _searchPublicationsService: SearchPublicationsService, + private _searchDatasetsService: SearchDatasetsService, + private _searchProjectsService: SearchProjectsService, + private _searchDataprovidersService: SearchDataprovidersService) { + this.fetchPublications = new FetchPublications(this._searchPublicationsService); + this.fetchDatasets = new FetchDatasets(this._searchDatasetsService); + this.fetchProjects = new FetchProjects(this._searchProjectsService); + this.fetchDataproviders = new FetchDataproviders(this._searchDataprovidersService); + + this.updateUrl(OpenaireProperties.getBaseLink()+this._router.url); + } + + ngOnInit() { + this.sub = this.route.queryParams.subscribe(data => { + this.updateTitle("Content provider"); + this.updateDescription("Content provider, search, repositories, open access"); + this.datasourceId = data['datasourceId']; + if(this.datasourceId){ + this.getDataProviderInfo(this.datasourceId); + }else{ + // console.info("Content Provider id not found"); + } + + if (typeof document !== 'undefined') { + this.element.nativeElement.scrollIntoView(); + } + }); + } + + ngOnDestroy() { + this.sub.unsubscribe(); + if(this.piwiksub){ + this.piwiksub.unsubscribe(); + } + if(this.subInfo) { + this.subInfo.unsubscribe(); + } + + if(this.relatedDatasourcesSub) { + this.relatedDatasourcesSub.unsubscribe(); + } + } + private getDataProviderInfo(id:string) { + this.warningMessage = ''; + this.errorMessage="" + this.showLoading = true; + + this.showTabs = false ; + if(this.datasourceId==null || this.datasourceId==''){ + this.showLoading = false; + this.warningMessage="No valid datasource id"; + }else{ + this.subInfo = this._dataproviderService.getDataproviderInfo(this.datasourceId).subscribe( + data => { + this.dataProviderInfo = data; + this.initTabs(); + this.showTabs = true ; + this.updateTitle(this.dataProviderInfo.title.name); + this.updateDescription("Content provider, search, repositories, open access,"+this.dataProviderInfo.title.name); + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.piwiksub = this._piwikService.trackView(this.dataProviderInfo.title.name).subscribe(); + } + + this.showLoading = false; + + if(this.dataProviderInfo.tabs != undefined && this.dataProviderInfo.tabs.length > 0) { + this.activeTab = this.dataProviderInfo.tabs[0].name; + } + }, + err => { + console.log(err); + // console.info("error"); + this.errorMessage = 'No dataProvider found'; + this.showLoading = false; + } + ); + } + } + + private updateDescription(description:string){ + this._meta.updateMeta("description", description); + this._meta.updateProperty("og:description", description); + } + private updateTitle(title:string){ + var _prefix ="OpenAIRE | "; + var _title = _prefix + ((title.length> 50 ) ?title.substring(0,50):title); + this._meta.setTitle(_title ); + this._meta.updateProperty("og:title",_title); + } + private updateUrl(url:string){ + this._meta.updateProperty("og:url", url); + } + + private initTabs(){ + + if(this.dataProviderInfo.tabs != undefined && this.dataProviderInfo.tabs.length > 0) { + this.reloadPublications = true; + this.reloadDatasets = true; + this.reloadProjects = true; + this.reloadDataproviders = true; + this.reloadRelatedDatasources = true; + this.statsClicked = false; + + this.search(this.dataProviderInfo.tabs[0].content, 1, 10); + this.count(1, 0); + + this.metricsClicked = false; + + this.viewsFrameUrl = OpenaireProperties.getFramesAPIURL()+'merge.php?com=query&data=[{"query":"dtsrcRepoViews","dtsrcName":"'+this.datasourceId+'","table":"","fields":[{"fld":"sum","agg":"sum","type":"column","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=["column"]&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'; + /*this.viewsFrameUrl = OpenaireProperties.getFramesAPIURL()+'merge.php?com=query&data=[{"query":"dtsrcOpenAIRETimeline", "dtsrcName":"'+this.datasourceId+'", "table":"","fields":[{"fld":"sum","agg":"sum","type":"column","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":"OpenAIRE","yaxisheaders":["Monthly views"],"generalxaxis":"","theme":0,"in":[],"filters":[{"name":"","values":[""],"to":"-1"}]},{"query":"dtsrcRepoTimeline", "dtsrcName":"'+this.datasourceId+'", "table":"","fields":[{"fld":"sum","agg":"sum","type":"column","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":"Repository","yaxisheaders":[""],"generalxaxis":"","theme":0,"in":[],"filters":[{"name":"","values":[""],"to":"-1"}]}]&info_types=["column","column"]&stacking=normal&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'; + */ + + this.downloadsFrameUrl = OpenaireProperties.getFramesAPIURL()+'merge.php?com=query&data=[{"query":"dtsrcRepoDownloads","dtsrcName":"'+this.datasourceId+'","table":"","fields":[{"fld":"sum","agg":"sum","type":"column","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=["column"]&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'; + /* + this.downloadsFrameUrl = OpenaireProperties.getFramesAPIURL()+'merge.php?com=query&data=[{"query":"dtsrcDownloadsTimeline","dtsrcName":"'+this.datasourceId+'","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'; + */ + + this.docsTimelineUrl ='https://beta.openaire.eu/stats/chart.php?com=query&persistent=false&data={"query":"dtsrcYear","dtsrcName":"'+this.datasourceId+'","table": "result", "fields": [{"fld": "number", "agg": "count", "type": "line", "yaxis":1, "c":true}], "xaxis":{"name": "year", "agg": "avg"}, "group": "", "color": "", "type": "chart", "size":30, "sort": "xaxis", "xStyle":{"r": -30, "s": "-", "l": "-", "ft": "-", "wt": "-"}, "yaxisheaders": [""], "fieldsheaders": ["Research Results"], "in": [{"f":0, "text": "Yearly"}], "filters": [{"name":"year","max":"2016","min":"1997"},{"name": "result_datasources-datasource-name", "values":[""], "to": "-1"}],"having": [], "incfilters": [], "inchaving": [], "title": "", "subtitle": "", "xaxistitle": "Year"}&w=600&h=250'; + this.docsTypesUrl = 'https://beta.openaire.eu/stats/chart.php?com=query&persistent=false&data={"query":"dtsrcPubs","dtsrcName":"'+this.datasourceId+'", "table": "result", "fields": [{"fld": "number", "agg": "count", "type": "pie", "yaxis":1, "c":false}], "xaxis":{"name": "result_classifications-type", "agg": "avg"}, "group": "", "color": "", "type": "chart", "size":30, "sort": "xaxis", "xStyle":{"r": "-", "s": "-", "l": "-", "ft": "-", "wt": "-"}, "yaxisheaders": [""], "fieldsheaders": ["Research Results"], "in": [], "filters": [{"name": "result_datasources-datasource-name", "values": [""], "to": "-1"}], "having": [], "incfilters": [], "inchaving": [], "title": "", "subtitle": "", "xaxistitle": ""}&w=600&h=250'; + this.docsFunderUrl =' https://beta.openaire.eu/stats/chart.php?com=query&persistent=false&data={"query":"dtsrcPubsFund","dtsrcName":"'+this.datasourceId+'", "table": "result", "fields": [{"fld": "number", "agg": "count", "type": "pie", "yaxis":1, "c":false}], "xaxis":{"name": "result_classifications-type", "agg": "avg"}, "group": "", "color": "", "type": "chart", "size":30, "sort": "xaxis", "xStyle":{"r": "-", "s": "-", "l": "-", "ft": "-", "wt": "-"}, "yaxisheaders": [""], "fieldsheaders": ["Research Results"], "in": [], "filters": [{"name": "result_datasources-datasource-name", "values": [""], "to": "-1"}], "having": [], "incfilters": [], "inchaving": [], "title": "", "subtitle": "", "xaxistitle": ""}&w=600&h=250'; + this.dataProjectsUrl ='https://beta.openaire.eu/stats/chart.php?com=query&persistent=false&data={"query":"dtsrcProjData","dtsrcName":"'+this.datasourceId+'", "table": "result", "fields": [{"fld": "number", "agg": "count", "type": "bar", "yaxis":1, "c":false}], "xaxis":{"name": "result_classifications-type", "agg": "avg"}, "group": "", "color": "", "type": "chart", "size":30, "sort": "xaxis", "xStyle":{"r": "-", "s": "-", "l": "-", "ft": "-", "wt": "-"}, "yaxisheaders": [""], "fieldsheaders": ["Research Data"], "in": [], "filters": [{"name": "result_datasources-datasource-name", "values": [""], "to": "-1"}], "having": [], "incfilters": [], "inchaving": [], "title": "", "subtitle": "", "xaxistitle": ""}&w=600&h=250'; + this.pubsProjectsUrl ='https://beta.openaire.eu/stats/chart.php?com=query&persistent=false&data={"query":"dtsrcProjPubs","dtsrcName":"'+this.datasourceId+'", "table": "result", "fields": [{"fld": "number", "agg": "count", "type": "bar", "yaxis":1, "c":false}], "xaxis":{"name": "result_classifications-type", "agg": "avg"}, "group": "", "color": "", "type": "chart", "size":30, "sort": "xaxis", "xStyle":{"r": "-", "s": "-", "l": "-", "ft": "-", "wt": "-"}, "yaxisheaders": [""], "fieldsheaders": ["Publications"], "in": [], "filters": [{"name": "result_datasources-datasource-name", "values": [""], "to": "-1"}], "having": [], "incfilters": [], "inchaving": [], "title": "", "subtitle": "", "xaxistitle": ""}&w=600&h=250'; + + //if({"name": "Publications", "content": "publicationsTab"} in this.dataProviderInfo.tabs) { + //if(this.dataProviderInfo.tabs.some(function (tab) { + // return tab.name === 'Publications'; + //})) { + // this.relatedDataprovidersResultsType = 'publications'; + this.fetchAggregatorsPublications = new FetchPublications(this._searchPublicationsService); + //} else { + // this.relatedDataprovidersResultsType = 'datasets'; + this.fetchAggregatorsDatasets = new FetchDatasets(this._searchDatasetsService); + //} + } + if(this.dataProviderInfo.resultsBy == "collectedFrom") { + //this.paramsForSearchLink = "?collectedFrom="+this.datasourceId+"&co=and"; + this.paramsForSearchLink = this.routerHelper.createQueryParams(['collectedFrom', 'co'], [this.datasourceId, 'and']); + } else if (this.dataProviderInfo.resultsBy == "hostedBy") { + //this.paramsForSearchLink = "?hostedBy="+this.datasourceId+"&ho=and"; + this.paramsForSearchLink = this.routerHelper.createQueryParams(['hostedBy', 'ho'], [this.datasourceId, 'and']); + } + + } + + private count(page: number, size: number) { + for(let i=1; i {}, + err => {}, + () => { this.preprocessRelatedDatasources(); } + ) + + this.fetchAggregatorsPublications.getAggregatorResults(this.datasourceId, page, size); + this.fetchAggregatorsDatasets.getAggregatorResults(this.datasourceId, page, size); + } else { + this.loadingRelatedDatasources = false; + } + + + this.reloadRelatedDatasources = false; + } + + private countRelatedDatasources(page: number, size: number) { + this.fetchAggregatorsPublications.getAggregatorResults(this.datasourceId, page, size); + this.fetchAggregatorsDatasets.getAggregatorResults(this.datasourceId, page, size); + } + + + private preprocessRelatedDatasources() { + if( this.fetchAggregatorsPublications.searchUtils.status == this.errorCodes.DONE || + this.fetchAggregatorsDatasets.searchUtils.status == this.errorCodes.DONE ) { + this.dataProviderInfo.relatedDatasources = new Map(); + } + for(let result of this.fetchAggregatorsPublications.results) { + if(!this.dataProviderInfo.relatedDatasources.has(result.id)) { + this.dataProviderInfo.relatedDatasources.set(result.id, {"name": result.name, "countPublications": result.count, "countDatasets": "0"}); + } else { + this.dataProviderInfo.relatedDatasources.get(result.id).countPublications = parseInt(this.dataProviderInfo.relatedDatasources.get(result.id).countPublications + result.count)+""; + } + } + + for(let result of this.fetchAggregatorsDatasets.results) { + if(!this.dataProviderInfo.relatedDatasources.has(result.id)) { + this.dataProviderInfo.relatedDatasources.set(result.id, {"name": result.name, "countPublications": "0", "countDatasets": result.count}); + } else { + this.dataProviderInfo.relatedDatasources.get(result.id).countDatasets = parseInt(this.dataProviderInfo.relatedDatasources.get(result.id).countDatasets + result.count)+""; + } + } + this.loadingRelatedDatasources = false; + } + + public metricsResults($event) { + this.totalViews = $event.totalViews; + this.totalDownloads = $event.totalDownloads; + this.pageViews = $event.pageViews; + } +} diff --git a/portal-4cli/src/app/landingPages/dataProvider/dataProvider.module.ts b/portal-4cli/src/app/landingPages/dataProvider/dataProvider.module.ts new file mode 100644 index 00000000..d1f7abba --- /dev/null +++ b/portal-4cli/src/app/landingPages/dataProvider/dataProvider.module.ts @@ -0,0 +1,51 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import {IFrameModule} from '../../utils/iframe.module'; +import {ErrorMessagesModule} from '../../utils/errorMessages.module'; +// import { ResultLandingModule } from '../resultLanding.module'; +import {TabResultModule } from '../../searchPages/searchUtils/tabResult.module'; +import {MetricsModule} from '../landing-utils/metrics.module'; +import {LandingModule} from '../landing-utils/landing.module'; +import {PagingModule} from '../../utils/paging.module'; + +import {PublicationsTabComponent} from './publicationsTab.component'; +import {DatasetsTabComponent} from './datasetsTab.component'; +import {StatisticsTabComponent} from './statisticsTab.component'; +import {ProjectsTabComponent} from './projectsTab.component'; +import {DatasourcesTabComponent} from './datasourcesTab.component'; +import {OrganizationsTabComponent} from './organizationsTab.component'; +import {RelatedDatasourcesTabComponent} from './relatedDatasourcesTab.component'; +// import {TabsComponent} from './tabs.component'; + +import {DataProviderComponent} from './dataProvider.component'; +import {DataProviderService} from './dataProvider.service'; +import {DataProvidersServiceModule} from '../../services/dataProvidersService.module'; +import {DatasetsServiceModule} from '../../services/datasetsService.module'; +import {ProjectsServiceModule} from '../../services/projectsService.module'; +import {PublicationsServiceModule} from '../../services/publicationsService.module'; + +import { DataProviderRoutingModule } from './dataProvider-routing.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: + [CommonModule, FormsModule, RouterModule,DataProviderRoutingModule, + TabResultModule, IFrameModule, ErrorMessagesModule, MetricsModule, LandingModule, + DataProvidersServiceModule, DatasetsServiceModule, ProjectsServiceModule, PublicationsServiceModule, + PagingModule], + declarations: + [PublicationsTabComponent, DatasetsTabComponent, StatisticsTabComponent, ProjectsTabComponent, DatasourcesTabComponent, OrganizationsTabComponent, + RelatedDatasourcesTabComponent, DataProviderComponent + ], + providers:[ + DataProviderService, FreeGuard, IsRouteEnabled], + exports: [ + DataProviderComponent + ] + +}) +export class DataProviderModule { } diff --git a/portal-4cli/src/app/landingPages/dataProvider/dataProvider.service.ts b/portal-4cli/src/app/landingPages/dataProvider/dataProvider.service.ts new file mode 100644 index 00000000..4b549e8d --- /dev/null +++ b/portal-4cli/src/app/landingPages/dataProvider/dataProvider.service.ts @@ -0,0 +1,162 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {DataProviderInfo} from '../../utils/entities/dataProviderInfo'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; + + +@Injectable() +export class DataProviderService { + + constructor(private http: Http ) {} + + dataProviderInfo: DataProviderInfo; + + getDataproviderInfo (id: string):any { + console.info("getDataProviderInfo in service"); + let url = OpenaireProperties.getSearchAPIURLLast() + 'datasources/' +id +"?format=json"; + let key = url; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => res['result']['metadata']['oaf:entity']) + .map(res => [res['oaf:datasource'], + res['oaf:datasource']['datasourcetype'], + res['oaf:datasource']['openairecompatibility'], + res['oaf:datasource']['accessinfopackage'], + res['oaf:datasource']['rels']['rel'] + ]) + .map(res => this.parseDataProviderInfo(res)); + + } + + private handleError (error: Response) { + // in a real world app, we may send the error to some remote logging infrastructure + // instead of just logging it to the console + console.log(error); + return Observable.throw(error || 'Server error'); + } + + parseDataProviderInfo (data: any):any { + this.dataProviderInfo = new DataProviderInfo(); + + if(data[0] != null) { + this.dataProviderInfo.title = {"name": (data[0].englishname)?data[0].englishname: data[0].officialname, "url": data[0].websiteurl}; + this.dataProviderInfo.officialName = data[0].officialname; + var originalId =(data[0].originalId)?data[0].originalId:""; + if(originalId && originalId != ""){ + if(originalId.indexOf("opendoar____::") != -1){ + this.dataProviderInfo.openDoarURL = "http://www.opendoar.org/find.php?format=full&rID="+originalId.split("opendoar____::")[1]; + + }else if (originalId.indexOf("re3data_____::") != -1){ + this.dataProviderInfo.r3DataURL = "http://service.re3data.org/repository/"+originalId.split("re3data_____::")[1]; + } + } + + } + + if(data[1] != null) { + this.dataProviderInfo.type = data[1].classname; + + if(data[1].classid == "entityregistry" || data[1].classid == "entityregistry::projects" || data[1].classid == "entityregistry::repositories") { + this.dataProviderInfo.registry = true; + } else { + this.dataProviderInfo.registry = false; + } + + if(this.dataProviderInfo.tabs == undefined) { + this.dataProviderInfo.tabs = new Array<{"name": string, "content": string}>(); + } + + if(this.dataProviderInfo.tabsInTypes.publicationsTab.has(data[1].classid)) { + this.dataProviderInfo.tabs.push({"name": "Publications", "content": "publicationsTab"}); + } + if(this.dataProviderInfo.tabsInTypes.datasetsTab.has(data[1].classid)) { + this.dataProviderInfo.tabs.push({"name": "Research Data", "content": "datasetsTab"}); + } + + if(this.dataProviderInfo.tabsInTypes.projectsTab.has(data[1].classid)) { + this.dataProviderInfo.tabs.push({"name": "Projects", "content": "projectsTab"}); + } + if(this.dataProviderInfo.tabsInTypes.datasourcesTab.has(data[1].classid)) { + this.dataProviderInfo.tabs.push({"name": "Content Providers", "content": "datasourcesTab"}); + } + this.dataProviderInfo.tabs.push({"name": "Organizations", "content": "organizationsTab"}); + + if(this.dataProviderInfo.tabsInTypes.relatedDatasourcesTab.has(data[1].classid)) { + this.dataProviderInfo.tabs.push({"name": "Related Content Providers", "content": "relatedDatasourcesTab"}); + } + + if(this.dataProviderInfo.tabsInTypes.statisticsTab.has(data[1].classid)) { + this.dataProviderInfo.tabs.push({"name": "Statistics", "content": "statisticsTab"}); + } + + this.dataProviderInfo.tabs.push({"name": "Metrics", "content": "metricsTab"}); + + if(this.dataProviderInfo.resultTypes.collectedFrom.has(data[1].classid)) { + this.dataProviderInfo.resultsBy = "collectedFrom"; + } else if(this.dataProviderInfo.resultTypes.hostedBy.has(data[1].classid)) { + this.dataProviderInfo.resultsBy = "hostedBy"; + } + } + + if(!this.dataProviderInfo.registry) { + if(data[2] != null) { + this.dataProviderInfo.compatibility = data[2].classname; + } + + if(data[3] != null) { + let oaiPmhURL: string; + if(Array.isArray(data[3])) { + oaiPmhURL = data[3][0]; + } + else { + oaiPmhURL = data[3]; + } + + if(oaiPmhURL != '' && oaiPmhURL != 'unknown') { + this.dataProviderInfo.oaiPmhURL = oaiPmhURL; + } + } + } + + if(data[4] != null) { + let mydata; + let counter = 0; + let countriesSet: Set; + let length = data[4].length!=undefined ? data[4].length : 1; + + for(let i=0; i(); + this.dataProviderInfo.countries = new Array(); + countriesSet = new Set(); + } + + this.dataProviderInfo.organizations[counter] = {"name": "", "id": ""}; + this.dataProviderInfo.organizations[counter]['name'] = mydata.legalname; + this.dataProviderInfo.organizations[counter]['id'] = /*OpenaireProperties.getsearchLinkToOrganization()+*/mydata['to'].content; + + if(mydata.country != '' && mydata['country'].classname != '') { + if(!countriesSet.has(mydata['country'].classname)) { + this.dataProviderInfo.countries.push(mydata['country'].classname); + countriesSet.add(mydata['country'].classname); + } + } + + counter++; + } + } + } + } + + return this.dataProviderInfo; + } +} diff --git a/portal-4cli/src/app/landingPages/dataProvider/datasetsTab.component.ts b/portal-4cli/src/app/landingPages/dataProvider/datasetsTab.component.ts new file mode 100644 index 00000000..d75edae7 --- /dev/null +++ b/portal-4cli/src/app/landingPages/dataProvider/datasetsTab.component.ts @@ -0,0 +1,48 @@ +import {Component, Input} from '@angular/core'; +import { FetchDatasets } from '../../utils/fetchEntitiesClasses/fetchDatasets.class'; + +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; + +@Component({ + selector: 'datasetsTab', + template: ` + + + + + + + ` +}) + +export class DatasetsTabComponent { + @Input() paramsForSearchLink = {}; + @Input() fetchDatasets : FetchDatasets; + public linkToSearchDatasets = ""; + public errorCodes:ErrorCodes = new ErrorCodes(); + + constructor () {} + + ngOnInit() { + this.linkToSearchDatasets = OpenaireProperties.getLinkToAdvancedSearchDatasets(); + } + + ngOnDestroy() {} +} diff --git a/portal-4cli/src/app/landingPages/dataProvider/datasourcesTab.component.ts b/portal-4cli/src/app/landingPages/dataProvider/datasourcesTab.component.ts new file mode 100644 index 00000000..4db8adf8 --- /dev/null +++ b/portal-4cli/src/app/landingPages/dataProvider/datasourcesTab.component.ts @@ -0,0 +1,50 @@ +import {Component, Input} from '@angular/core'; +import { FetchDataproviders } from '../../utils/fetchEntitiesClasses/fetchDataproviders.class'; + +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; + +@Component({ + selector: 'datasourcesTab', + template: ` + + + + + + + ` +}) + +export class DatasourcesTabComponent { + + @Input() paramsForSearchLink = {}; + @Input() fetchDataproviders : FetchDataproviders; + public linkToSearchDataproviders = ""; + public errorCodes:ErrorCodes = new ErrorCodes(); + + constructor () {} + + ngOnInit() { + this.linkToSearchDataproviders = OpenaireProperties.getLinkToAdvancedSearchDataProviders(); + } + + ngOnDestroy() {} +} diff --git a/portal-4cli/src/app/landingPages/dataProvider/organizationsTab.component.ts b/portal-4cli/src/app/landingPages/dataProvider/organizationsTab.component.ts new file mode 100644 index 00000000..c666fdae --- /dev/null +++ b/portal-4cli/src/app/landingPages/dataProvider/organizationsTab.component.ts @@ -0,0 +1,54 @@ +import {Component, Input} from '@angular/core'; + +@Component({ + selector: 'organizationsTab', + template: ` + + +
+
+ {{organizations.length}} organizations, page {{organizationsPage}} of {{totalPages(organizations.length)}} + +
+ +
+

+ + + {{item['name']}} + +

+

+ {{item['name']}} +

+
+
+ ` +}) + +export class OrganizationsTabComponent { + + @Input() organizations: {"name": string, "id": string}[]; + public organizationsPage: number = 1; + public pageSize: number = 10; + + constructor () {} + + ngOnInit() {} + + ngOnDestroy() {} + + totalPages(totalResults: number): number { + let totalPages:any = totalResults/this.pageSize; + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, this.pageSize) + 1); + } + return totalPages; + } + + updateOrganizationsPage($event) { + this.organizationsPage = $event.value; + } +} diff --git a/portal-4cli/src/app/landingPages/dataProvider/projectsTab.component.ts b/portal-4cli/src/app/landingPages/dataProvider/projectsTab.component.ts new file mode 100644 index 00000000..4102e285 --- /dev/null +++ b/portal-4cli/src/app/landingPages/dataProvider/projectsTab.component.ts @@ -0,0 +1,49 @@ +import {Component, Input} from '@angular/core'; + +import { FetchProjects } from '../../utils/fetchEntitiesClasses/fetchProjects.class'; + +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; + +@Component({ + selector: 'projectsTab', + template: ` + + + + + + + ` +}) + +export class ProjectsTabComponent { + + @Input() paramsForSearchLink = {}; + @Input() fetchProjects : FetchProjects; + public linkToSearchProjects = ""; + public errorCodes:ErrorCodes = new ErrorCodes(); + + constructor () {} + + ngOnInit() { + this.linkToSearchProjects = OpenaireProperties.getLinkToAdvancedSearchProjects(); + } + + ngOnDestroy() {} +} diff --git a/portal-4cli/src/app/landingPages/dataProvider/publicationsTab.component.ts b/portal-4cli/src/app/landingPages/dataProvider/publicationsTab.component.ts new file mode 100644 index 00000000..156e48e6 --- /dev/null +++ b/portal-4cli/src/app/landingPages/dataProvider/publicationsTab.component.ts @@ -0,0 +1,50 @@ +import {Component, Input} from '@angular/core'; +import { FetchPublications } from '../../utils/fetchEntitiesClasses/fetchPublications.class'; + +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; + +@Component({ + selector: 'publicationsTab', + template: ` + + + + + + + + + ` +}) + +export class PublicationsTabComponent { + @Input() paramsForSearchLink = {};//: string = ""; + @Input() fetchPublications : FetchPublications; + public linkToSearchPublications = ""; + public errorCodes:ErrorCodes = new ErrorCodes(); + + constructor () {} + + ngOnInit() { + this.linkToSearchPublications = OpenaireProperties.getLinkToAdvancedSearchPublications();//+this.paramsForSearchLink; + } + + ngOnDestroy() {} +} diff --git a/portal-4cli/src/app/landingPages/dataProvider/relatedDatasourcesTab.component.ts b/portal-4cli/src/app/landingPages/dataProvider/relatedDatasourcesTab.component.ts new file mode 100644 index 00000000..da85f597 --- /dev/null +++ b/portal-4cli/src/app/landingPages/dataProvider/relatedDatasourcesTab.component.ts @@ -0,0 +1,122 @@ +import {Component, Input} from '@angular/core'; + +import { FetchPublications } from '../../utils/fetchEntitiesClasses/fetchPublications.class'; +import { FetchDatasets } from '../../utils/fetchEntitiesClasses/fetchDatasets.class'; + +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {RouterHelper} from '../../utils/routerHelper.class'; +import { Observable } from 'rxjs/Observable'; + +@Component({ + selector: 'relatedDatasourcesTab', + template: ` + + + + + + +
+
+ {{results.size}} related content providers, page {{page}} of {{totalPages(results.size)}} + +
+ + + + + + + + + + + + + + + + + + + + + + + +
Content Provider Name + Number of Publications + + Number of Research Data +
+ + {{results.get(id).name}} + + + + {{results.get(id).countPublications}} + + - + + {{results.get(id).countDatasets}} + + -
+
+ ` +}) + +export class RelatedDatasourcesTabComponent { + @Input() dataproviderId: string; + @Input() fetchPublications : FetchPublications; + @Input() fetchDatasets : FetchDatasets; + // true: preprocessing is not over + @Input() loading: boolean = true; + // Εvery content provider's id is a single key of a map + @Input() results: Map; + + public linkToSearchPublications: string = ""; + public linkToSearchResearchData: string = ""; + + public routerHelper:RouterHelper = new RouterHelper(); + public errorCodes:ErrorCodes = new ErrorCodes(); + + public page: number = 1; + public pageSize: number = 10; + + constructor () {} + + ngOnInit() { + this.linkToSearchPublications = OpenaireProperties.getLinkToAdvancedSearchPublications();//+"?&hostedBy=";//+ +"&ho=and&collectedFrom="+ +"&co=and"; + this.linkToSearchResearchData = OpenaireProperties.getLinkToAdvancedSearchDatasets(); + } + + ngOnDestroy() {} + + totalPages(totalResults: number): number { + let totalPages:any = totalResults/this.pageSize; + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, this.pageSize) + 1); + } + return totalPages; + } + + updatePage($event) { + this.page = $event.value; + } +} diff --git a/portal-4cli/src/app/landingPages/dataProvider/statisticsTab.component.ts b/portal-4cli/src/app/landingPages/dataProvider/statisticsTab.component.ts new file mode 100644 index 00000000..4aae1f91 --- /dev/null +++ b/portal-4cli/src/app/landingPages/dataProvider/statisticsTab.component.ts @@ -0,0 +1,78 @@ +import {Component, Input} from '@angular/core'; +import { SearchDatasetsComponent } from '../../searchPages/simple/searchDatasets.component'; +import { SearchPublicationsComponent } from '../../searchPages/simple/searchPublications.component'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; + +@Component({ + selector: 'statisticsTab', + template: ` +
+ + + + +
+

Latest Documents Timeline

+ +

Documents Types

+ +
+ + +
+
+

Funders in content providers Publications

+ +

Projects with most Publications

+ + +
+
+
+

Projects with most Research Data

+ + +
+
+
+
+ ` +}) + +export class StatisticsTabComponent { + + @Input() statistics; + @Input() id; + @Input() searchDatasetsComponent : SearchDatasetsComponent; + @Input() searchPublicationsComponent : SearchPublicationsComponent; + @Input() show : boolean = false; + + private docsTimelineUrl: string; + private docsTypesUrl:string; + private docsFunderUrl:string; + private dataProjectsUrl:string ; + private pubsProjectsUrl:string; + public errorCodes:ErrorCodes = new ErrorCodes(); + + constructor () {} + + ngOnInit() { + + this.docsTimelineUrl ='https://beta.openaire.eu/stats/chart.php?com=query&persistent=false&data={"query":"dtsrcYear","dtsrcName":"'+this.id+'","table": "result", "fields": [{"fld": "number", "agg": "count", "type": "line", "yaxis":1, "c":true}], "xaxis":{"name": "year", "agg": "avg"}, "group": "", "color": "", "type": "chart", "size":30, "sort": "xaxis", "xStyle":{"r": "-", "s": "-", "l": "-", "ft": "-", "wt": "-"}, "yaxisheaders": [""], "fieldsheaders": ["Documents"], "in": [{"f":0, "text": "Yearly"}], "filters": [{"name":"year","max":"2016","min":"1997"},{"name": "result_datasources-datasource-name", "values":[""], "to": "-1"}],"having": [], "incfilters": [], "inchaving": [], "title": "", "subtitle": "", "xaxistitle": "Year"}&w=600&h=250'; + this.docsTypesUrl = 'https://beta.openaire.eu/stats/chart.php?com=query&persistent=false&data={"query":"dtsrcPubs","dtsrcName":"'+this.id+'", "table": "result", "fields": [{"fld": "number", "agg": "count", "type": "pie", "yaxis":1, "c":false}], "xaxis":{"name": "result_classifications-type", "agg": "avg"}, "group": "", "color": "", "type": "chart", "size":30, "sort": "xaxis", "xStyle":{"r": "-", "s": "-", "l": "-", "ft": "-", "wt": "-"}, "yaxisheaders": [""], "fieldsheaders": ["Documents"], "in": [], "filters": [{"name": "result_datasources-datasource-name", "values": [""], "to": "-1"}], "having": [], "incfilters": [], "inchaving": [], "title": "", "subtitle": "", "xaxistitle": ""}&w=600&h=250'; + this.docsFunderUrl =' https://beta.openaire.eu/stats/chart.php?com=query&persistent=false&data={"query":"dtsrcPubsFund","dtsrcName":"'+this.id+'", "table": "result", "fields": [{"fld": "number", "agg": "count", "type": "pie", "yaxis":1, "c":false}], "xaxis":{"name": "result_classifications-type", "agg": "avg"}, "group": "", "color": "", "type": "chart", "size":30, "sort": "xaxis", "xStyle":{"r": "-", "s": "-", "l": "-", "ft": "-", "wt": "-"}, "yaxisheaders": [""], "fieldsheaders": ["Documents"], "in": [], "filters": [{"name": "result_datasources-datasource-name", "values": [""], "to": "-1"}], "having": [], "incfilters": [], "inchaving": [], "title": "", "subtitle": "", "xaxistitle": ""}&w=600&h=250'; + this.dataProjectsUrl ='https://beta.openaire.eu/stats/chart.php?com=query&persistent=false&data={"query":"dtsrcProjData","dtsrcName":"'+this.id+'", "table": "result", "fields": [{"fld": "number", "agg": "count", "type": "bar", "yaxis":1, "c":false}], "xaxis":{"name": "result_classifications-type", "agg": "avg"}, "group": "", "color": "", "type": "chart", "size":30, "sort": "xaxis", "xStyle":{"r": "-", "s": "-", "l": "-", "ft": "-", "wt": "-"}, "yaxisheaders": [""], "fieldsheaders": ["Datasets"], "in": [], "filters": [{"name": "result_datasources-datasource-name", "values": [""], "to": "-1"}], "having": [], "incfilters": [], "inchaving": [], "title": "", "subtitle": "", "xaxistitle": ""}&w=600&h=250'; + this.pubsProjectsUrl ='https://beta.openaire.eu/stats/chart.php?com=query&persistent=false&data={"query":"dtsrcProjPubs","dtsrcName":"'+this.id+'", "table": "result", "fields": [{"fld": "number", "agg": "count", "type": "bar", "yaxis":1, "c":false}], "xaxis":{"name": "result_classifications-type", "agg": "avg"}, "group": "", "color": "", "type": "chart", "size":30, "sort": "xaxis", "xStyle":{"r": "-", "s": "-", "l": "-", "ft": "-", "wt": "-"}, "yaxisheaders": [""], "fieldsheaders": ["Publications"], "in": [], "filters": [{"name": "result_datasources-datasource-name", "values": [""], "to": "-1"}], "having": [], "incfilters": [], "inchaving": [], "title": "", "subtitle": "", "xaxistitle": ""}&w=600&h=250'; + } + + ngOnDestroy() {} +} diff --git a/portal-4cli/src/app/landingPages/dataset/dataset-routing.module.ts b/portal-4cli/src/app/landingPages/dataset/dataset-routing.module.ts new file mode 100644 index 00000000..ae8bf7aa --- /dev/null +++ b/portal-4cli/src/app/landingPages/dataset/dataset-routing.module.ts @@ -0,0 +1,18 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { DatasetComponent } from './dataset.component'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PreviousRouteRecorder} from'../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: DatasetComponent, canActivate: [FreeGuard, IsRouteEnabled], data: { + redirect: '/error' + },canDeactivate: [PreviousRouteRecorder] } + ]) +] +}) +export class DatasetRoutingModule { } diff --git a/portal-4cli/src/app/landingPages/dataset/dataset.component.html b/portal-4cli/src/app/landingPages/dataset/dataset.component.html new file mode 100644 index 00000000..3abcee28 --- /dev/null +++ b/portal-4cli/src/app/landingPages/dataset/dataset.component.html @@ -0,0 +1,328 @@ +
+
+
+ +
+ + + + + +
+
+ + {{datasetInfo.types.join(", ")}} + {{datasetInfo.title.accessMode}} + + + Record in preview + + + + +
+ + ({{datasetInfo.date}}) +
+ +
    +
  • Publisher: {{datasetInfo.publisher}}
  • + +
  • Embargo end date: {{datasetInfo.embargoEndDate}}
  • +
  • + +
  • +
  • + + +
  • +
+ +
+ {{datasetInfo.description}} +
+ +
+ + +
+ + + + + + + + + +
+
+
+ No related research results available +
+
+ +
+
{{provenanceaction}}
+ + +
+
+
+ +
+
+ No similar research results available +
+
+ +
+
+
+ + + + + + + +
+ +
+
+ +
+
+ Share - Bookmark + +
+ + + + + + +
+
+
+
+
+
diff --git a/portal-4cli/src/app/landingPages/dataset/dataset.component.ts b/portal-4cli/src/app/landingPages/dataset/dataset.component.ts new file mode 100644 index 00000000..b1c5829b --- /dev/null +++ b/portal-4cli/src/app/landingPages/dataset/dataset.component.ts @@ -0,0 +1,172 @@ +import {Component, ViewChild, ElementRef} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {DatasetService} from './dataset.service'; +import {DatasetInfo} from '../../utils/entities/datasetInfo'; +import {ActivatedRoute, Router} from '@angular/router'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties' +import {RouterHelper} from '../../utils/routerHelper.class'; +import { Meta} from '../../../angular2-meta'; +import {PiwikService} from '../../utils/piwik/piwik.service'; + +@Component({ + selector: 'dataset', + templateUrl: 'dataset.component.html', +}) + +export class DatasetComponent { + public datasetInfo: DatasetInfo; + public datasetId : string ; + + // APP BOX variables + public showAllCollectedFrom: boolean = false; + public showAllDownloadFrom: boolean = false; + public showAllPublishedIn: boolean = false; + + // Metrics tab variables + public metricsClicked: boolean; + public viewsFrameUrl: string; + public downloadsFrameUrl: string; + public totalViews: number; + public totalDownloads: number; + public pageViews: number; + + // Active tab variable for responsiveness + public activeTab: string = "Related Research Results"; + + // Map counting variable + public relatedResearchResultsNum: number = 0; + + // Message variables + public warningMessage = ""; + public errorMessage = ""; + public showLoading: boolean = true; + + public routerHelper:RouterHelper = new RouterHelper(); + + private result ; + sub: any; piwiksub: any; infoSub: any; + + constructor (private element: ElementRef, + private _datasetService: DatasetService, + private _piwikService:PiwikService, + private route: ActivatedRoute, + private _meta: Meta, + private _router: Router) { + this.updateUrl(OpenaireProperties.getBaseLink()+this._router.url); + } + + ngOnInit() { + this.sub = this.route.queryParams.subscribe(params => { + this.datasetInfo = null; + this.updateTitle("Dataset"); + this.updateDescription("Dataset, search, open access"); + + this.datasetId = params['datasetId']; + console.info("Id is :"+this.datasetId); + + if(this.datasetId){ + this.getDatasetInfo(this.datasetId); + }else{ + this.showLoading = false; + this.warningMessage="No valid research data id"; + } + + this.metricsClicked = false; + + this.viewsFrameUrl = OpenaireProperties.getFramesAPIURL()+'merge.php?com=query&data=[{"query":"resRepoViews", "resTitle":"'+this.datasetId+'", "table":"","fields":[{"fld":"sum","agg":"sum","type":"column","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":"Repository","yaxisheaders":["Monthly views"],"generalxaxis":"","theme":0,"in":[],"filters":[{"name":"","values":[""],"to":"-1"}]}]&info_types=["column"]&stacking=normal&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(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'; + /*this.viewsFrameUrl = OpenaireProperties.getFramesAPIURL()+'merge.php?com=query&data=[{"query":"resViewsTimeline", "resTitle":"'+this.datasetId+'", "table":"","fields":[{"fld":"sum","agg":"sum","type":"column","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":"Repository","yaxisheaders":["Monthly views"],"generalxaxis":"","theme":0,"in":[],"filters":[{"name":"","values":[""],"to":"-1"}]}]&info_types=["column"]&stacking=normal&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'; + */ + + this.downloadsFrameUrl = OpenaireProperties.getFramesAPIURL()+'merge.php?com=query&data=[{"query":"resRepoDownloads", "resTitle":"'+this.datasetId+'", "table":"","fields":[{"fld":"sum","agg":"sum","type":"column","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":"Repository","yaxisheaders":["Monthly downloads"],"generalxaxis":"","theme":0,"in":[],"filters":[{"name":"","values":[""],"to":"-1"}]}]&info_types=["column"]&stacking=normal&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(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'; + /*this.downloadsFrameUrl = OpenaireProperties.getFramesAPIURL()+'merge.php?com=query&data=[{"query":"resRepoDownloadTimeline", "resTitle":"'+this.datasetId+'", "table":"","fields":[{"fld":"sum","agg":"sum","type":"column","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":"Repository","yaxisheaders":["Monthly downloads"],"generalxaxis":"","theme":0,"in":[],"filters":[{"name":"","values":[""],"to":"-1"}]}]&info_types=["column"]&stacking=normal&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(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'; + */ + if (typeof document !== 'undefined') { + this.element.nativeElement.scrollIntoView(); + } + }); + + } + + ngOnDestroy() { + this.sub.unsubscribe(); + if(this.piwiksub){ + this.piwiksub.unsubscribe(); + } + if(this.infoSub) { + this.infoSub.unsubscribe(); + } + } + + private getDatasetInfo(id:string) { + this.warningMessage = ''; + this.errorMessage="" + this.showLoading = true; + + this.infoSub = this._datasetService.getDatasetInfo(id).subscribe( + data => { + this.datasetInfo = data; + this.updateTitle(this.datasetInfo.title.name); + this.updateDescription("Dataset, search, repositories, open access,"+this.datasetInfo.title.name); + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.piwiksub = this._piwikService.trackView(this.datasetInfo.title.name).subscribe(); + } + + this.result = [] + this.result = {id: id, type :"dataset", source : "openaire", title: this.datasetInfo.title,url: '', result: '', accessRights: this.datasetInfo.title.accessMode, embargoEndDate: ''}; + + let relatedResearchResultsNum = 0; + if(this.datasetInfo.relatedResearchResults != undefined) { + this.datasetInfo.relatedResearchResults.forEach(function (value, key, map) { + relatedResearchResultsNum += value.length; + }); + } + this.relatedResearchResultsNum = relatedResearchResultsNum; + + this.showLoading = false; + }, + err => { + console.log(err) + console.info("error"); + + this.errorMessage = 'No research data found'; + this.showLoading = false; + } + ); + } + + // showChange($event) { + // this.showAllReferences=$event.value; + // } + + public metricsResults($event) { + this.totalViews = $event.totalViews; + this.totalDownloads = $event.totalDownloads; + this.pageViews = $event.pageViews; + } + + private updateDescription(description:string){ + this._meta.updateMeta("description", description); + this._meta.updateProperty("og:description", description); + } + private updateTitle(title:string){ + var _prefix ="OpenAIRE | "; + var _title = _prefix + ((title.length> 50 ) ?title.substring(0,50):title); + this._meta.setTitle(_title ); + this._meta.updateProperty("og:title",_title); + } + private updateUrl(url:string){ + this._meta.updateProperty("og:url", url); + } + + public buildCurationTooltip() { + let tooltipContent: string = "
"; + + tooltipContent += "

Record in preview

"; + tooltipContent += "

Bibliographic record accepted by the system, but not yet processed by
OpenAIRE tools for information quality improvement and de-duplication

"; + + return tooltipContent; + } + public getKeys( map) { + return Array.from(map.keys()); + } +} diff --git a/portal-4cli/src/app/landingPages/dataset/dataset.module.ts b/portal-4cli/src/app/landingPages/dataset/dataset.module.ts new file mode 100644 index 00000000..90c0ded6 --- /dev/null +++ b/portal-4cli/src/app/landingPages/dataset/dataset.module.ts @@ -0,0 +1,37 @@ +//import {MaterialModule} from '@angular/material'; +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { SharedModule } from '../../shared/shared.module'; +import { RouterModule } from '@angular/router'; + +import { DatasetService} from './dataset.service'; +import { DatasetComponent } from './dataset.component'; +import { DatasetRoutingModule } from './dataset-routing.module'; +import {MetricsModule} from '../landing-utils/metrics.module'; +import {IFrameModule} from '../../utils/iframe.module'; +import {AltMetricsModule} from '../../utils/altmetrics.module'; +import {CiteThisModule} from '../landing-utils/citeThis/citeThis.module'; + +import { ResultLandingModule } from '../landing-utils/resultLanding.module'; +import { LandingModule } from '../landing-utils/landing.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + //MaterialModule.forRoot(), + CommonModule, FormsModule,SharedModule, RouterModule, LandingModule, CiteThisModule, + ResultLandingModule, DatasetRoutingModule, MetricsModule, IFrameModule, AltMetricsModule + ], + declarations: [ + DatasetComponent + ], + providers:[ + DatasetService, FreeGuard, IsRouteEnabled + ], + exports: [ + DatasetComponent + ] +}) +export class DatasetModule { } diff --git a/portal-4cli/src/app/landingPages/dataset/dataset.service.ts b/portal-4cli/src/app/landingPages/dataset/dataset.service.ts new file mode 100644 index 00000000..9074d326 --- /dev/null +++ b/portal-4cli/src/app/landingPages/dataset/dataset.service.ts @@ -0,0 +1,220 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {DatasetInfo} from '../../utils/entities/datasetInfo'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; + +import { ParsingFunctions } from '../landing-utils/parsingFunctions.class'; + +@Injectable() +export class DatasetService { + + constructor(private http: Http ) { + this.parsingFunctions = new ParsingFunctions(); + } + + public parsingFunctions: ParsingFunctions; + datasetInfo: DatasetInfo; + + getDatasetInfo (id: string):any { + console.info("getDatasetInfo in service"); + + let url = OpenaireProperties. getSearchAPIURLLast()+'datasets/'+id+"?format=json"; + let key = url; + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .do(res => console.info(res['result']['metadata']['oaf:entity'])) + .map(res => [res['result']['header']['dri:status'], res['result']['metadata']['oaf:entity']['oaf:result']]) + .map(res => [res[1], + res[1]['title'], + res[1]['rels']['rel'], + res[1]['children'], + res[1]['pid'], + res[1]['subject'], + res[1]['bestaccessright'], + res[1]['collectedfrom'], + res[1]['context'], + //res[1]['resulttype'], + res[0], + res[1]['creator'] + ]).map(res => this.parseDatasetInfo(res)); + } + + private handleError (error: Response) { + // in a real world app, we may send the error to some remote logging infrastructure + // instead of just logging it to the console + console.log(error); + return Observable.throw(error || 'Server error'); + } + + parseDatasetInfo (data: any):any { + this.datasetInfo = new DatasetInfo(); + + if(data[0] != null) { + var date:string = (data[0].dateofacceptance)+""; // transform to string in case it is an integer + this.datasetInfo.date = (date && (date).indexOf('-') !== -1)?date.split('-')[0]:date; + this.datasetInfo.dateofacceptance = data[0].dateofacceptance; + this.datasetInfo.publisher = data[0].publisher; + if(!Array.isArray(data[0].description)) { + this.datasetInfo.description = data[0].description; + } else { + this.datasetInfo.description = data[0].description[0]; + } + this.datasetInfo.embargoEndDate = data[0].embargoenddate; + } + this.datasetInfo.title = {"name": "", "url": "", "accessMode": ""}; + if(data[0]['bestaccessright'].hasOwnProperty("classid")) { + this.datasetInfo.title.accessMode = data[0]['bestaccessright'].classid; + } + if(data[1] != null) { + if(Array.isArray(data[1])) { + this.datasetInfo.title['name'] = data[1][0].content; + } else { + this.datasetInfo.title['name'] = data[1].content; + } + } + + if(data[2] != null) { + let relation; + let length = data[2].length!=undefined ? data[2].length : 1; + + for(let i=0; i(); + this.datasetInfo.publishedIn = new Map() + + this.datasetInfo.types = new Array(); + let types = new Set(); + + let counter = 0; + let instance; + + let length = data[3]['instance'].length!=undefined ? data[3]['instance'].length : 1; + + for(let i=0; i, Map] = this.parsingFunctions.parseAllSubjects(data[5]); + this.datasetInfo.subjects = subjectResults[0]; + this.datasetInfo.otherSubjects = subjectResults[1]; + this.datasetInfo.classifiedSubjects = subjectResults[2]; + } + + // if(data[6] != null) { + // this.datasetInfo.bestaccessright = data[6].classid; + // } + + // if(data[7] != null) { + // this.datasetInfo.collectedFrom = this.parsingFunctions.parseCollectedFrom(data[7]); + // } + + // null argument is for journal + this.datasetInfo.downloadFrom = this.parsingFunctions.addPublisherToDownloadFrom( + this.datasetInfo.downloadFrom, this.datasetInfo.publisher, + null, this.datasetInfo.identifiers, this.datasetInfo.title); + + if(data[8] != null) { + this.datasetInfo.contexts = this.parsingFunctions.parseContexts(data[8]); + } + + // if(data[9] != null && this.datasetInfo.type == undefined) { + // if(data[9].hasOwnProperty('classname')) { + // this.datasetInfo.type = data[9].classname; + // } + // } + + if(data[9] != null && data[9] == "under curation") { + this.datasetInfo.underCurationMessage = true; + } else { + this.datasetInfo.underCurationMessage = false; + } + + if(data[10] != null) { + if(this.datasetInfo.authors == undefined) { + this.datasetInfo.authors = new Array(); + } + + let authors = data[10]; + let length = Array.isArray(authors) ? authors.length : 1; + for(let i=0; i +
+
+ +
+ + + +
+

{{header1}}

+

{{header2}}

+ +
+ +
+ +
+ + +
+
+
+
+
+ + ` + }) +export class HtmlProjectReportComponent{ + private projectId: string; + private totalResults: number = 10; + private resultsType: string = "publication"; + + public header1: string = ""; + public header2: string = ""; + public htmlResult: string = ""; + + public sub: any; piwiksub: any; + public subHTML: any; + public subHTMLInfo: any; + + public warningMessage: string = ""; + public errorMessage: string = ""; + public showLoading: boolean = true; + + constructor ( private route: ActivatedRoute, + private htmlService: HtmlProjectReportService, + private _piwikService:PiwikService, + private _projectService: ProjectService, + private _meta: Meta, private _router: Router) { + this.updateUrl(OpenaireProperties.getBaseLink()+this._router.url); + } + + ngOnInit() { + this.sub = this.route.queryParams.subscribe(params => { + this.projectId = params['projectId']; + + if (params['size'] == parseInt(params['size'], 10)) { + this.totalResults = params['size']; + } else { + this.showLoading = false; + this.warningMessage="Requested size is not an integer"; + } +console.info(params['type']); + if(params['type'] && (params['type'] == "dataset" || params['type'] == "publication")){ + this.resultsType = (params['type'] == "dataset") ? 'research data' : params['type']; + this.updateTitle("Project's "+this.resultsType+" report"); + this.updateDescription("project, project "+ this.resultsType +" report, funding, open access, publications, research data"); + } else { + this.showLoading = false; + this.warningMessage="Requested type should be publication or research data"; + } + + //showLoading is true if no warnings + if(this.showLoading) { + if(this.projectId) { + this.createHeaders(); + } else { + this.showLoading = false; + this.warningMessage="No valid project id"; + } + } + }); + } + + ngOnDestroy() { + this.sub.unsubscribe(); + if(this.piwiksub){ + this.piwiksub.unsubscribe(); + } + if(this.subHTML) { + this.subHTML.unsubscribe(); + } + if(this.subHTMLInfo) { + this.subHTMLInfo.unsubscribe(); + } + } + + private createHeaders() { + this.subHTMLInfo = this._projectService.getHTMLInfo(this.projectId).subscribe( + data => { + this.createHeader1(data); + if(data.acronym) { + this.updateTitle(data.acronym+" "+this.resultsType+" report"); + } else if(data.title){ + this.updateTitle(data.title+" "+this.resultsType+" report"); + } + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.piwiksub = this._piwikService.trackView(((data.acronym)?data.acronym:data.title)+" "+this.resultsType+" report").subscribe(); + } + }, + err => { + console.log(err); + this.createClipboard(); + } + ); + + this.header2 = this.totalResults+((this.resultsType == "publication")?" publications":" research data"); + } + + private createClipboard() { + let intro: string = ''; + intro += ''; + intro += ''; + intro += ''+this.header1+'' + intro += ''; + + if (typeof window !== 'undefined') { + this.subHTML = this.htmlService.getHTML(this.projectId, this.totalResults, this.resultsType).subscribe( + data => { + let body: string = intro+'

'+this.header1+'

'+this.header2+'

'+data+''; + this.htmlResult = data; + + let clipboard; + let Clipboard; + Clipboard = require('clipboard'); + clipboard = new Clipboard('.clipBtn', { + /*target: function(trigger) { + return document.getElementById("clipboard"); + }*/ + text: function(trigger) { + return body;//document.getElementById("clipboard").getAttribute('innerHTML');//"aaaa"+tmp+"oo"; + } + }); + + this.showLoading = false; + }, + err => { + console.log(err); + this.errorMessage = 'Service not available'; + this.showLoading = false; + } + ); + } + } + + createHeader1(data: {"title": string, "acronym": string, "callIdentifier": string}) { + this.header1 = ((this.resultsType == "publication")?"Publications":"Research Data") + " of Project "; + + if(data != undefined) { + if(data.title != undefined && data.title != "") { + this.header1 += data.title; + } + if((data.title != undefined && data.title != "") && + ((data.acronym != undefined && data.acronym != "") || + (data.callIdentifier != undefined && data.callIdentifier != ""))) { + this.header1 += "("; + } + if(data.acronym != undefined && data.acronym != "") { + this.header1 += data.acronym + " - "; + } + if(data.callIdentifier != undefined && data.callIdentifier != "") { + this.header1 += data.callIdentifier; + } + if((data.title != undefined && data.title != "") && + ((data.acronym != undefined && data.acronym != "") || + (data.callIdentifier != undefined && data.callIdentifier != ""))) { + this.header1 += ")"; + } + } + + this.createClipboard(); + } + + public copied() { + UIkit.notification({ + message : 'Raw html is copied. Please paste it on an html file.', + status : 'success', + timeout : 3000, + pos : 'top-center' + }); + } + + private updateDescription(description:string){ + this._meta.updateMeta("description", description); + this._meta.updateProperty("og:description", description); + } + private updateTitle(title:string){ + var _prefix ="OpenAIRE | "; + var _title = _prefix + ((title.length> 50 ) ?title.substring(0,50):title); + this._meta.setTitle(_title ); + this._meta.updateProperty("og:title",_title); + } + private updateUrl(url:string){ + this._meta.updateProperty("og:url", url); + } +} diff --git a/portal-4cli/src/app/landingPages/htmlProjectReport/htmlProjectReport.module.ts b/portal-4cli/src/app/landingPages/htmlProjectReport/htmlProjectReport.module.ts new file mode 100644 index 00000000..8fea6ec1 --- /dev/null +++ b/portal-4cli/src/app/landingPages/htmlProjectReport/htmlProjectReport.module.ts @@ -0,0 +1,28 @@ +//import {MaterialModule} from '@angular/material'; +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { ProjectServiceModule} from '../project/projectService.module'; + + +import {HtmlProjectReportService} from './htmlProjectReport.service'; +import {HtmlProjectReportComponent} from './htmlProjectReport.component'; +import { HtmlProjectReportRoutingModule } from './htmlProjectReport-routing.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PiwikServiceModule} from '../../utils/piwik/piwikService.module'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, HtmlProjectReportRoutingModule, ProjectServiceModule,PiwikServiceModule + ], + declarations: [ + HtmlProjectReportComponent + ], + providers:[ + HtmlProjectReportService, FreeGuard + ], + exports: [ + HtmlProjectReportComponent + ] +}) +export class HtmlProjectReportModule { } diff --git a/portal-4cli/src/app/landingPages/htmlProjectReport/htmlProjectReport.service.ts b/portal-4cli/src/app/landingPages/htmlProjectReport/htmlProjectReport.service.ts new file mode 100644 index 00000000..de681974 --- /dev/null +++ b/portal-4cli/src/app/landingPages/htmlProjectReport/htmlProjectReport.service.ts @@ -0,0 +1,25 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; +import 'rxjs/add/operator/do'; + +@Injectable() +export class HtmlProjectReportService { + + constructor(private http: Http ) {} + + getHTML(id: string, size: number, type:string):any { + console.info("getHTML in service"); + + let resultTypeId: string = (type == "research data") ? 'dataset' : type; + let requestType: string = (resultTypeId == "dataset") ? 'datasets' : 'publications'; + //let url = OpenaireProperties. getSearchAPIURLLast() + 'publications/' +id+"?format=json"; + let url = OpenaireProperties.getCsvAPIURL(); + url += 'resources?format=html&page=0&size='+size+'&type='+requestType+'&query=(((oaftype exact result) and (resulttypeid exact '+resultTypeId+')) and (relprojectid exact "'+id+'"))'; + let key = url; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.text()); + } +} diff --git a/portal-4cli/src/app/landingPages/landing-utils/addThis.component.ts b/portal-4cli/src/app/landingPages/landing-utils/addThis.component.ts new file mode 100644 index 00000000..52951668 --- /dev/null +++ b/portal-4cli/src/app/landingPages/landing-utils/addThis.component.ts @@ -0,0 +1,40 @@ +import {Component, ElementRef, Input} from '@angular/core'; +import {ActivatedRoute} from '@angular/router'; + + interface addthis { + layers: refresh; + } + interface refresh { + refresh: Function; + } + declare var addthis: addthis; + +// +@Component({ + selector: 'addThis', + template: ` +
+ ` +}) +export class AddThisComponent { + private sub:any; + + + constructor(private route: ActivatedRoute) { + + } + ngOnInit() { + this.sub = this.route.queryParams.subscribe(data => { + + if (typeof document !== 'undefined') { + try{ + addthis.layers.refresh(); + }catch (e) { + } + } + }); + + } + + +} diff --git a/portal-4cli/src/app/landingPages/landing-utils/citeThis/citation.class.ts b/portal-4cli/src/app/landingPages/landing-utils/citeThis/citation.class.ts new file mode 100644 index 00000000..3a8f42d8 --- /dev/null +++ b/portal-4cli/src/app/landingPages/landing-utils/citeThis/citation.class.ts @@ -0,0 +1,110 @@ +export class Citation{ + public templates:string[]=["bibtex","chicago","ieee","science","apa","cell","harvard","mla","nature","acm"]; + + bibtex:string =` `; + ieee_csl:string =` `; + chicago_csl:string =` `; + science_csl:string =' '; + cell_csl:string =' '; + mla_csl:string =' '; + nature_csl:string =' '; +//nature_csl:string =' '; + acm_csl:string =' '; + + public getOptionsBy(template:string):any{ + if(template == "bibtex"){ + var options:any ={ // Subsequent calls + format: 'string', + type: 'string', + style: 'bibtex' + } + return options; + }else if(template == "apa"){ + var options:any ={ // Subsequent calls + format: 'string', + type: 'string', + style: 'citation-apa' + } + return options; + }else if(template == "harvard"){ + var options:any ={ // Subsequent calls + format: 'string', + type: 'string', + style: 'citation-harvard1' + } + return options; + }else if(template == "chicago"){ + var options:any ={ // Subsequent calls + format: 'string', + type: 'string', + style: 'citation-chicago', + template:this.chicago_csl + } + return options; + }else if(template == "ieee"){ + var options:any ={ // Subsequent calls + format: 'string', + type: 'string', + style: 'citation-ieee', + template:this.ieee_csl + } + return options; + }else if(template == "science"){ + var options:any ={ // Subsequent calls + format: 'string', + type: 'string', + style: 'citation-science', + template:this.science_csl + } + return options; + }else if(template == "cell"){ + var options:any ={ // Subsequent calls + format: 'string', + type: 'string', + style: 'citation-cell', + template:this.cell_csl + } + return options; + }else if(template == "mla"){ + var options:any ={ // Subsequent calls + format: 'string', + type: 'string', + style: 'citation-mla', + template:this.mla_csl + } + return options; + }else if(template == "nature"){ + var options:any ={ // Subsequent calls + format: 'string', + type: 'string', + style: 'citation-nature', + template:this.nature_csl + } + return options; + }else if(template == "acm"){ + var options:any ={ // Subsequent calls + format: 'string', + type: 'string', + style: 'citation-acm', + template:this.acm_csl + } + return options; + } + + + } + +} +export class CitationData{ + public id:string; + public type:string; + public title:string; + public DOI:string; + public "container-title":string; + public publisher:string; + public author:{given:string, family:string, 'parse-names':boolean}[] =[]; + public issued:any[] =[];//{"date-parts":string[]}[] =[]; + public date:string; + public authors:string[] =[]; + +} diff --git a/portal-4cli/src/app/landingPages/landing-utils/citeThis/citeThis.component.ts b/portal-4cli/src/app/landingPages/landing-utils/citeThis/citeThis.component.ts new file mode 100644 index 00000000..4a7b4676 --- /dev/null +++ b/portal-4cli/src/app/landingPages/landing-utils/citeThis/citeThis.component.ts @@ -0,0 +1,102 @@ +import {Component, ElementRef, Input} from '@angular/core'; +import {ActivatedRoute} from '@angular/router'; +import {Citation, CitationData} from './citation.class'; + +// +@Component({ + selector: 'citeThis', + template: ` + +
+
+
Cite this {{type}}
+
+ +
{{citationText}}
+
+
+
+ ` +}) +export class CiteThisComponent { + private sub:any; + public selectedStyle:string; + public citationText:string; + public citation:Citation = new Citation(); + // public cite: any; + @Input() result: any; + @Input() id: string; + @Input() type: string="article"; + + public data;//= '[ { "id": "Q23571040", "type": "apple", "title": "Correlation of the Base Strengths of Amines 1", "DOI": "10.1021/ja01577a030", "author": [ { "given": "H. K.", "family": "Hall" } ], "issued": [ { "date-parts": [ "1957", "1", "1" ] } ], "container-title": "Journal of the American Chemical Society", "volume": "79", "issue": "20", "page": "5441-5444" } ]'; + + + constructor(private route: ActivatedRoute) { + this.selectedStyle = this.citation.templates[0]; + } + + ngOnInit() { + if(typeof window !== 'undefined') { + this.parseData(); + // var Cite = require('citation-js'); + // this.cite = new Cite(this.data,this.citation.getOptionsBy(this.selectedStyle)); + // this.citationText = this.cite.get(this.citation.getOptionsBy(this.selectedStyle)); + } + } + parseData(){ + var citationData:CitationData = new CitationData(); + + citationData.id = this.id; + if(this.result.types != undefined && this.result.types.length > 0 && this.result.types[0]){ + citationData.type = this.result.types[0].toLowerCase(); + }else if(this.result.type != undefined ){ + citationData.type = this.result.type.toLowerCase(); + } + if(this.result.title && this.result.title.name){ + citationData.title = this.result.title.name; + } + if(this.result.journal && this.result.journal.journal){ + citationData["container-title"] = this.result.journal.journal; + } + if(this.result.publisher){ + citationData.publisher = this.result.publisher; + } + if( this.result.authors){ + citationData.author = []; + var max_length = (this.result.authors.length > 10)?10:this.result.authors.length; + for (var i =0 ;i < max_length; i++){ + if(this.result.authors[i] && this.result.authors[i].indexOf(", ") !== -1){ + citationData.author.push({given:this.result.authors[i].split(", ")[0], family:this.result.authors[i].split(", ")[1], 'parse-names':true}); + }else{ + citationData.author.push({given:"", family:this.result.authors[i], 'parse-names':true}); + } + citationData.authors.push(this.result.authors[i]); + } + } + if(this.result.dateofacceptance != undefined){ + citationData.issued = []; + var date:string = (this.result.dateofacceptance)+""; // transform to string in case it is an integer + var dateArray:string[] = (date && (date).indexOf('-') !== -1)?date.split('-'):[date]; + if(dateArray.length < 3){ + dateArray.push["01"]; + dateArray.push["01"]; + } + citationData.issued.push({"date-parts":[dateArray[0],dateArray[1], dateArray[2]]}); + if(this.result.date ){ + citationData.date = this.result.date ; + } + } + + + this.data = JSON.stringify(citationData); + console.log(this.data); + + } + styleChanged(){ + // this.citationText = this.cite.get(this.citation.getOptionsBy(this.selectedStyle)); + + } + +} diff --git a/portal-4cli/src/app/landingPages/landing-utils/citeThis/citeThis.module.ts b/portal-4cli/src/app/landingPages/landing-utils/citeThis/citeThis.module.ts new file mode 100644 index 00000000..4a14a36a --- /dev/null +++ b/portal-4cli/src/app/landingPages/landing-utils/citeThis/citeThis.module.ts @@ -0,0 +1,23 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + + import {CiteThisComponent} from './citeThis.component'; + +@NgModule({ + imports: [ + + CommonModule, FormsModule + ], + declarations: [ + CiteThisComponent + ], + providers:[ + + ], + exports: [ + + CiteThisComponent + ] +}) +export class CiteThisModule { } diff --git a/portal-4cli/src/app/landingPages/landing-utils/fundedBy.component.ts b/portal-4cli/src/app/landingPages/landing-utils/fundedBy.component.ts new file mode 100644 index 00000000..637ff787 --- /dev/null +++ b/portal-4cli/src/app/landingPages/landing-utils/fundedBy.component.ts @@ -0,0 +1,131 @@ +import {Component, Input, ElementRef} from '@angular/core'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; + +@Component({ + selector: 'fundedBy', + template: ` +
+
Funded By
+
+
+ + + + {{item['funderShortname']?item['funderShortname']:item['funderName']}} + [no funder available] + | {{ item['acronym']?item['acronym']:item['title']}} + + + + + {{item['funderShortname']?item['funderShortname']:item['funderName']}} + [no funder available] + | {{ item['acronym']?item['acronym']:item['title']}} + + + + + {{item['funderShortname']?item['funderShortname']:item['funderName']}} + [no funder available] + | {{ item['acronym']?item['acronym']:item['title']}} + + + + + {{item['funderShortname']?item['funderShortname']:item['funderName']}} + [no funder available] + | {{ item['acronym']?item['acronym']:item['title']}} + + + + + + + +
+
+
+ + View less + +
+
...
+
+ + View more + +
+
+ ` + }) + +export class FundedByComponent { + @Input() fundedByProjects: { "id": string, "acronym": string, "title": string, + "funderShortname": string, "funderName": string, + "funding": string, "code": string, "provenanceAction": string, + "inline": boolean }[]; + public showAll: boolean = false; + + constructor (private element: ElementRef) {} + + ngOnInit() {} + + public buildFundingTooltip(item: { "id": string, "acronym": string, "title": string, + "funderShortname": string, "funderName": string, + "funding": string, "code": string, "provenanceAction": string, inline: boolean}) { + let tooltipContent: string = "
"; + + if(item.title) { + tooltipContent += "
"+item.title+"
"; + } + + if(item.code || item.funderName || item.funderShortname || item.funding) { + tooltipContent += "

"; + } + + if(item.code) { + tooltipContent += "

Project Code: "+item.code+"
"; + } + if(item.funderName || item.funderShortname) { + tooltipContent += "
Funder: "; + if(item.funderName && item.funderShortname) { + tooltipContent += item.funderName + " ("+ item.funderShortname +")"; + } else if(item.funderName) { + tooltipContent += item.funderName; + } else { + tooltipContent += item.funderShortname; + } + tooltipContent += "
"; + } + + if(item.funding) { + tooltipContent += "
Funding: "+ item.funding + "
"; + } + + if(item.code || item.funderName || item.funderShortname || item.funding) { + tooltipContent += "

"; + } + + if(item.provenanceAction == 'Repository') { + tooltipContent += "Provided by Repository"; + } else if(item.provenanceAction == 'Algorithm') { + tooltipContent += "Inferred by Algorithm"; + } else if(item.provenanceAction == 'USer') { + tooltipContent += "Claimed by User"; + } + + tooltipContent+="
" + return tooltipContent; + } + + public scroll() { + console.info("scroll into view"); + if (typeof document !== 'undefined') { + this.element.nativeElement.scrollIntoView(); + } + } +} diff --git a/portal-4cli/src/app/landingPages/landing-utils/landing.module.ts b/portal-4cli/src/app/landingPages/landing-utils/landing.module.ts new file mode 100644 index 00000000..a7ae76f1 --- /dev/null +++ b/portal-4cli/src/app/landingPages/landing-utils/landing.module.ts @@ -0,0 +1,28 @@ +/* This module contains all common components for all landing pages */ + +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import {TabPagingComponent} from './tabPaging.component'; +import {ShowTitleComponent} from './showTitle.component'; +import {AddThisComponent} from './addThis.component'; +import {PiwikServiceModule} from '../../utils/piwik/piwikService.module'; +import {PreviousRouteRecorder} from'../../utils/piwik/previousRouteRecorder.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, RouterModule, PiwikServiceModule + ], + declarations: [ + TabPagingComponent, ShowTitleComponent, AddThisComponent + ], + providers:[ + PreviousRouteRecorder + ], + exports: [ + TabPagingComponent, ShowTitleComponent, AddThisComponent + ] +}) +export class LandingModule { } diff --git a/portal-4cli/src/app/landingPages/landing-utils/metrics.component.ts b/portal-4cli/src/app/landingPages/landing-utils/metrics.component.ts new file mode 100644 index 00000000..b4c75833 --- /dev/null +++ b/portal-4cli/src/app/landingPages/landing-utils/metrics.component.ts @@ -0,0 +1,224 @@ +import {Component, Input, Output, EventEmitter} from '@angular/core'; +import {Metrics} from '../../utils/entities/metrics'; +import {MetricsService } from '../../services/metrics.service'; +import {ErrorCodes} from '../../utils/properties/openaireProperties'; + +import { Subscription } from 'rxjs/Subscription'; + +@Component({ + selector: 'metrics', + template: ` + + + + + + + + + +
+
Project metrics are derived from aggregating individual research results metrics.
+
+
+ +
{{pageViews}}
+
views in OpenAIRE
+ + + +
+
+
+
+ +
{{metrics.totalViews}} + + ( {{metrics.totalOpenaireViews}} from OpenAIRE ) +
+
views in local repository
+ + + + + +
+
+
+
+ +
{{metrics.totalDownloads}} + + ( {{metrics.totalOpenaireDownloads}} from OpenAIRE ) +
+
downloads in local repository
+ + + + + + +
+
+ +
+ +

The information is available from the following content providers:

+ + + + + + + + + + + + + + + +
FromNumber Of ViewsNumber Of Downloads
+ + {{metrics.infos.get(key).name}} + + + {{metrics.infos.get(key).numOfViews}} + + ( {{metrics.infos.get(key).openaireViews}} from OpenAIRE ) + + + {{metrics.infos.get(key).numOfDownloads}} + + ( {{metrics.infos.get(key).openaireDownloads}} from OpenAIRE ) + +
+ ` + }) + +export class MetricsComponent { + @Output() metricsResults = new EventEmitter(); + @Input() id: string; + @Input() entityType: string; + @Input() entity: string; + //@Input() name: string = ""; + @Input() pageViews: number = 0; + + public metrics: Metrics; + public errorCodes:ErrorCodes; + private sub: Subscription; + + public status: number; + + constructor (private _metricsService: MetricsService) {} + + ngOnInit() { + this.errorCodes = new ErrorCodes(); + this.status = this.errorCodes.LOADING; + this.getMetrics(); + } + + ngOnDestroy() { + this.sub.unsubscribe(); + } + + private getMetrics() { + //if(this.id == undefined || this.id == "") { + // console.log("supplied id in metrics is not acceptable"); + //} + //if(this.type == undefined || this.type == "") { + // console.log("supplied id in metrics is not acceptable"); + //} + + this.sub = this._metricsService.getMetrics(this.id, this.entityType).subscribe( + data => { + this.metrics = data; + this.status = this.errorCodes.DONE; + + this.metricsResults.emit({ + totalViews: this.metrics.totalViews, + totalDownloads: this.metrics.totalDownloads, + pageViews: this.metrics.pageViews + }); + }, + err => { + console.log(err); + if(err.status == '404') { + this.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.status = this.errorCodes.ERROR; + } else { + this.status = this.errorCodes.NOT_AVAILABLE; + } + this.metricsResults.emit({ + totalViews: 0, + totalDownloads: 0 + }); + } + ); + } +} diff --git a/portal-4cli/src/app/landingPages/landing-utils/metrics.module.ts b/portal-4cli/src/app/landingPages/landing-utils/metrics.module.ts new file mode 100644 index 00000000..3fb241b4 --- /dev/null +++ b/portal-4cli/src/app/landingPages/landing-utils/metrics.module.ts @@ -0,0 +1,26 @@ +/* This module contains all common components for all landing pages */ + +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + + import {MetricsComponent} from './metrics.component'; + import { MetricsService } from '../../services/metrics.service'; + + import {ErrorMessagesModule} from '../../utils/errorMessages.module'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, ErrorMessagesModule + ], + declarations: [ + MetricsComponent + ], + providers:[ + MetricsService + ], + exports: [ + MetricsComponent + ] +}) +export class MetricsModule { } diff --git a/portal-4cli/src/app/landingPages/landing-utils/parsingFunctions.class.ts b/portal-4cli/src/app/landingPages/landing-utils/parsingFunctions.class.ts new file mode 100644 index 00000000..e3c7f2be --- /dev/null +++ b/portal-4cli/src/app/landingPages/landing-utils/parsingFunctions.class.ts @@ -0,0 +1,455 @@ +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; + +export class ParsingFunctions { + + constructor () {} + + public ngOnDestroy() {} + + public parseFundingByProjects(fundedByProjects: { "id": string, "acronym": string, "title": string, + "funderShortname": string, "funderName": string, + "funding": string, "code": string, + "provenanceAction": string, "inline": boolean + }[], + relation: any, projectsProvenanceVocabulary: any): + { "id": string, "acronym": string, "title": string, + "funderShortname": string, "funderName": string, + "funding": string, "code": string, + "provenanceAction": string, "inline": boolean + }[] { + if(fundedByProjects == undefined) { + fundedByProjects = new Array<{"id": string, "acronym": string, "title": string, + "funderShortname": string, "funderName": string, + "funding": string, "code": string, + "provenanceAction": string, "inline": boolean + }>(); + } + + let fundedByProject: { "id": string, "acronym": string, "title": string, + "funderShortname": string, "funderName": string, + "funding": string, "code": string, + "provenanceAction": string, "inline": boolean + } = { "id": "", "acronym": "", "title": "", + "funderShortname": "", "funderName": "", + "funding": "", "code": "", "provenanceAction": "", "inline": false + }; + + if(relation.title != 'unidentified') { + fundedByProject['id'] = relation['to'].content; + fundedByProject['acronym'] = relation.acronym; + fundedByProject['title'] = relation.title; + fundedByProject['code'] = relation.code; + + if(relation.provenanceaction in projectsProvenanceVocabulary) { + fundedByProject['provenanceAction'] = projectsProvenanceVocabulary[relation.provenanceaction]; + } + } else { + fundedByProject['id'] = ""; + fundedByProject['acronym'] = ""; + fundedByProject['title'] = ""; + fundedByProject['code'] = ""; + fundedByProject['provenanceAction'] = ""; + } + + if(relation.hasOwnProperty("funding")) { + let funding: {"funderName": string, "funderShortname": string, "stream": string}; + funding = this.parseFundingTrees(relation.funding); + + if(funding.funderName) { + fundedByProject['funderName'] = funding.funderName; + } + if(funding.funderShortname) { + fundedByProject['funderShortname'] = funding.funderShortname; + } + if(funding.stream) { + fundedByProject['funding'] = funding.stream; + } + } + fundedByProjects.push(fundedByProject); + return fundedByProjects; + } + + // publication & research data : for fundedByProjects | project landing : for funding + public parseFundingTrees(fundingTree: any): {"funderName": string, "funderShortname": string, "stream": string} { + let funding: {"funderName": string, "funderShortname": string, "stream": string} = {"funderName": "", "funderShortname": "", "stream": ""}; + let length = Array.isArray(fundingTree) ? fundingTree.length : 1; + + for(let i=0; i(); + + let collected; + let length = Array.isArray(_collectedFrom) ? _collectedFrom.length : 1; + for(let i=0; i, + publisher: string, journal:{"journal": string, "issn": string, "lissn": string}, + identifiers: Map, title: { "name": string, "url": string, "accessMode": string}) { + if( publisher && identifiers != null && identifiers.has('doi')) { + if( downloadFrom == null) { + downloadFrom = new Map(); + } + + let key: string; + if(journal && journal.journal) { + key = publisher + "/ "+journal['journal']; + } else { + key = publisher; + } + downloadFrom.set(key, {"url": null, "accessMode": null, "bestAccessMode": null}); + + let url = OpenaireProperties.getDoiURL()+identifiers.get("doi")[0]; + + downloadFrom.get(key)['url'] = new Array(); + downloadFrom.get(key)['accessMode'] = new Array(); + + downloadFrom.get(key)['url'][0] = url; + downloadFrom.get(key)['accessMode'][0] = ""; + + if(title != undefined && title['url'] == "") { + title['url'] = url; + } + } + return downloadFrom; + } + + // publication & dataset landing : for downloadFrom + parseDownloadFrom(downloadFrom: Map, instance: any, url: string) + { + let key: string = instance['hostedby'].name; + + if(key) { + this.addUrlAndAccessMode(downloadFrom, instance, key, url); + } + } + + // publication & dataset landing : for publishedIn + parsePublishedIn(publishedIn: Map, instance: any, result: any, url: string, counter: number): number { + if(result != null && result.hasOwnProperty("source")) { + let key: string; + if(Array.isArray(result.source)) { + if(counter==result.source.length) { + counter--; + } + key = result['source'][counter]; + } else { + key = result['source']; + } + + if(key) { + this.addUrlAndAccessMode(publishedIn, instance, key, url); + counter++; + } + } + return counter; + } + + // publication & dataset landing : for downloadFrom and publishedIn + addUrlAndAccessMode(mapStructure: Map, instance: any, key: string, url: string) { + if(!mapStructure.has(key)) { + mapStructure.set(key, {"url": null, "accessMode": null, "bestAccessMode": null}); + } + + if(mapStructure.get(key)['url'] == null) { + mapStructure.get(key)['url'] = new Array(); + } + + if(url) { + mapStructure.get(key)['url'].push(url); + } + + if(mapStructure.get(key)['accessMode'] == null) { + mapStructure.get(key)['accessMode'] = new Array(); + } + + if(instance.hasOwnProperty("licence")) { + if(url) { + mapStructure.get(key)['accessMode'].push(instance['licence'].classid); + } + + if(this.changeBestAccessMode(mapStructure.get(key)['bestAccessMode'], instance['licence'])) { + mapStructure.get(key)['bestAccessMode'] = instance['licence'].classid; + } + } else if(url) { + mapStructure.get(key)['accessMode'].push(""); + } + } + + // publication & dataset landing : for downloadFrom and publishedIn + changeBestAccessMode(currentAccessMode: string, accessMode: any): boolean { + if(!accessMode) { + return false; + } + accessMode = accessMode.classid; + + switch (currentAccessMode) { + case null: + return true; + case "CLOSED": + if( accessMode == "OPEN" || + accessMode == "EMBARGO" || + accessMode == "RESTRICTED") { + return true; + } + return false; + case "RESTRICTED": + if( accessMode == "OPEN" || + accessMode == "EMBARGO") { + return true; + } + return false; + case "EMBARGO": + if(accessMode == "OPEN") { + return true; + } + return false; + } + return false; + } + + // publication & dataset landing : for relatedResearchResults + parseRelatedResearchResults(relatedResearchResults_1: Map, relation: any, provenanceAction: string) : + Map { + + // if(relatedResearchResults == undefined) { +let relatedResearchResults = new Map(); + // } + + if(!relatedResearchResults.has(provenanceAction)) { + relatedResearchResults.set(provenanceAction, + new Array<{ "name": string, "id": string, "date": string, + "trust": number, "class": string }>()); + } + relatedResearchResults.get(provenanceAction).push(this.parseRelatedOrSimilarResearchResult(relation)); + + return relatedResearchResults; + } + + // publication & dataset landing : for similarResearchResults + parseSimilarResearchResults(similarResearchResults: { "name": string, "id": string, "date": string, + "trust": number, "class": string}[], relation: any) : + { "name": string, "id": string, "date": string, "trust": number, "class": string }[] { + if(similarResearchResults == undefined) { + similarResearchResults = new Array<{"name": string, "id": string, "date": string, + "trust": number, "class": string}>(); + } + similarResearchResults.push(this.parseRelatedOrSimilarResearchResult(relation)); + return similarResearchResults; + } + + // publication & dataset landing : for relatedResearchResults and similarResearchResults + parseRelatedOrSimilarResearchResult(relation: any): {"name": string, "id": string, "date": string, "trust": number, "class": string} { + let researchResult: {"name": string, "id": string, "date": string, "trust": number, "class": string} + = {"name": "", "id": "", "date": "", "trust": null, "class": ""} + + if(relation['resulttype'].classname == "publication") { + researchResult['class'] = "publication"; + } else if(relation['resulttype'].classname == "dataset") { + researchResult['class'] = "dataset"; + } else { + researchResult['class'] = "software"; + } + + researchResult['id'] = relation['to'].content; + let titleName = Array.isArray(relation['title']) ? relation['title'][0].content : relation['title'].content; + researchResult['name'] = titleName; + var date:string = ((Array.isArray(relation.dateofacceptance))?(relation.dateofacceptance[0]):(relation.dateofacceptance))+""; // transform to string in case it is an integer + researchResult['date'] = (date && (date).indexOf('-') !== -1)?date.split('-')[0]:date; + //researchResult['date'] = relation.dateofacceptance.substring(0,4);; + researchResult['trust'] = Math.round(relation.trust*100); + return researchResult; + } + + // publication & dataset landing : for identifiers + parseIdentifiers(pid: any): Map { + let identifiers = new Map(); + + if(pid.hasOwnProperty("classname") && pid['classname'] != "") { + if(pid.classname == "doi" || pid.classname == "pmc" || pid.classname == "handle") { + if(!identifiers.has(pid.classname)) { + identifiers.set(pid.classname, new Array()); + } + + identifiers.get(pid.classname).push(pid.content); + } + } else { + for(let i=0; i()); + } + identifiers.get(pid[i].classname).push(pid[i].content); + } + } + } + return identifiers; + } + + // publication & dataset landing : for subjects and otherSubjects and classifiedSubjects + parseAllSubjects(_subjects: any): [string[], Map, Map] { + let subjects: string[]; + let otherSubjects: Map; + let classifiedSubjects: Map; + + let subject; + let length = Array.isArray(_subjects) ? _subjects.length : 1; + + for(let i=0; i(); + } + + if(!classifiedSubjects.has(subject.classname)) { + classifiedSubjects.set(subject.classname, new Array()); + } + + classifiedSubjects.get(subject.classname).push(subject.content); + } else { + if(subject.classid == "keyword") { + if(subjects == undefined) { + subjects = new Array(); + } + + subjects.push(subject.content); + } else { + if(otherSubjects == undefined) { + otherSubjects = new Map(); + } + + if(!otherSubjects.has(subject.classname)) { + otherSubjects.set(subject.classname, new Array()); + } + otherSubjects.get(subject.classname).push(subject.content); + } + } + } + } + return [subjects, otherSubjects, classifiedSubjects]; + } + + parseContexts(_contexts: any): {"labelContext": string, "labelCategory": string, + "labelConcept": string, inline:boolean}[] { + let contexts = new Array<{"labelContext": string, "labelCategory": string, + "labelConcept": string, inline:boolean}>(); + + let position = 0; + let labels = ""; + let context; + let length = Array.isArray(_contexts) ? _contexts.length : 1; + for(let i=0; i, instance: any) { + if(instance.hasOwnProperty("instancetype") && instance['instancetype'].classname) { + if(!uniqueTypes.has(instance['instancetype'].classname)) { + types.push(instance['instancetype'].classname); + uniqueTypes.add(instance['instancetype'].classname); + } + } + } +} diff --git a/portal-4cli/src/app/landingPages/landing-utils/publishedIn.component.ts b/portal-4cli/src/app/landingPages/landing-utils/publishedIn.component.ts new file mode 100644 index 00000000..7a4f47be --- /dev/null +++ b/portal-4cli/src/app/landingPages/landing-utils/publishedIn.component.ts @@ -0,0 +1,71 @@ +import {Component, Input, ElementRef} from '@angular/core'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; + +@Component({ + selector: 'publishedIn', + template: ` +
+
Published in
+
+
+ + + {{key}} + + + [{{i+1}}] + + + + + {{key}} + + + {{key}} + + +
+
+
+ + View less + +
+
...
+
+ + View more + +
+
+ ` + }) + +export class PublishedInComponent { + //key is name + @Input() publishedIn: Map; + + public showAll: boolean = false; + + constructor (private element: ElementRef) {} + + ngOnInit() {} + + public scroll() { + console.info("scroll into view"); + if (typeof document !== 'undefined') { + this.element.nativeElement.scrollIntoView(); + } + } + public getKeys( map) { + return Array.from(map.keys()); + } +} diff --git a/portal-4cli/src/app/landingPages/landing-utils/resultLanding.module.ts b/portal-4cli/src/app/landingPages/landing-utils/resultLanding.module.ts new file mode 100644 index 00000000..e0607303 --- /dev/null +++ b/portal-4cli/src/app/landingPages/landing-utils/resultLanding.module.ts @@ -0,0 +1,27 @@ +/* This module contains all common components for Publication & Daasets Landing Pages */ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; +import {PagingModule} from '../../utils/paging.module'; + +import {ShowAuthorsComponent} from './showAuthors.component'; +import {ShowIdentifiersComponent} from './showIdentifiers.component'; +import {ShowSubjectsComponent} from './showSubjects.component'; +import {TabTableComponent} from './tabTable.component'; +import {FundedByComponent} from './fundedBy.component'; +import {PublishedInComponent} from './publishedIn.component'; +@NgModule({ + imports: [ + CommonModule, FormsModule, RouterModule, PagingModule + ], + declarations: [ + ShowAuthorsComponent,ShowIdentifiersComponent,ShowSubjectsComponent, TabTableComponent, FundedByComponent, PublishedInComponent + ], + providers:[ + ], + exports: [ + ShowAuthorsComponent,ShowIdentifiersComponent,ShowSubjectsComponent, TabTableComponent, FundedByComponent, PublishedInComponent + ] +}) +export class ResultLandingModule { } diff --git a/portal-4cli/src/app/landingPages/landing-utils/searchingProjectsInTab.component.ts b/portal-4cli/src/app/landingPages/landing-utils/searchingProjectsInTab.component.ts new file mode 100644 index 00000000..c96d23ba --- /dev/null +++ b/portal-4cli/src/app/landingPages/landing-utils/searchingProjectsInTab.component.ts @@ -0,0 +1,122 @@ +import {Component, Input} from '@angular/core'; +import {ActivatedRoute} from '@angular/router'; + +import { FetchProjects } from '../../utils/fetchEntitiesClasses/fetchProjects.class'; +import { SearchProjectsService } from '../../services/searchProjects.service'; + +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {StringUtils} from '../../utils/string-utils.class'; +import {RouterHelper} from '../../utils/routerHelper.class'; + +@Component({ + selector: 'searchingProjectsTab', + template: ` + + + + +
+ +
+
+
+ +
+
+
    +
  • + + + + {{value.name}} ({{value.number}}) + +
  • + +
  • Filtered {{fetchProjects.searchUtils.totalResults}} results of {{fetchProjects.searchUtils.totalResultsNoFilters}} total results
  • +
  • +
+ + + +
+
+ ` +}) + +export class SearchingProjectsTabComponent { + @Input() fetchProjects : FetchProjects; + @Input() organizationId:string = ""; + public page :number = 1; + public size :number = 10; + public linkToSearchProjects: string; + + public routerHelper:RouterHelper = new RouterHelper(); + public errorCodes:ErrorCodes = new ErrorCodes(); + + private filterQuery:string = ""; + + constructor (private route: ActivatedRoute, + private _searchProjectsService: SearchProjectsService) { + } + + + ngOnInit() { + + if(this.organizationId) { + this.linkToSearchProjects = OpenaireProperties.getLinkToAdvancedSearchProjects();//+"?organization="+this.organizationId+"or=and";; + if(this.fetchProjects.searchUtils.totalResults > 0) { + this.search(false,""); + } + } + } + + + private search(refine:boolean, filterQuery:string){ + var refineFields:string [] = ["funder"]; + this.fetchProjects.getResultsForOrganizations(this.organizationId, filterQuery, this.page, this.size,(refine)?refineFields:[]); + } + + public pageChange($event) { + this.page=$event.value; + this.search(false, this.filterQuery); + } + + public filterChange($event) { + console.log("Filter Changed"); + this.updateFilters(); + //this.search(true, this.filterQuery); + this.search(false, this.filterQuery); + } + + private updateFilters (){ + this.filterQuery = ""; + for (let filter of this.fetchProjects.filters){ + var filterLimits=""; + for (let value of filter.values){ + if(value.selected == true){ + //filterLimits+=((filterLimits.length == 0)?'':',') +'"'+ StringUtils.URIEncode(value.id)+'"'; + filterLimits+=((filterLimits.length == 0)?'':' or ')+filter.filterId+' exact '; + filterLimits+='"'+ StringUtils.URIEncode(value.id)+'"'; + } + } + if(filterLimits.length > 0){ + //this.filterQuery+=' and '+filter.filterId + ' exact '+ filterLimits + ' '; + this.filterQuery+=' and ( ' + filterLimits + ' ) '; + } + + } + console.log("Filter Changed"+this.filterQuery); + + } +} diff --git a/portal-4cli/src/app/landingPages/landing-utils/searchingProjectsInTab.module.ts b/portal-4cli/src/app/landingPages/landing-utils/searchingProjectsInTab.module.ts new file mode 100644 index 00000000..e3d7a061 --- /dev/null +++ b/portal-4cli/src/app/landingPages/landing-utils/searchingProjectsInTab.module.ts @@ -0,0 +1,31 @@ +/* This module contains all common components for all landing pages */ + +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import { ProjectsServiceModule} from '../../services/projectsService.module'; +import { TabResultModule } from '../../searchPages/searchUtils/tabResult.module'; +import { SearchingProjectsTabComponent} from './searchingProjectsInTab.component'; + +import {PagingModule } from '../../utils/paging.module'; +import {ErrorMessagesModule} from '../../utils/errorMessages.module'; + +@NgModule({ + imports: [ + RouterModule, CommonModule, FormsModule, + ProjectsServiceModule, TabResultModule, + PagingModule, ErrorMessagesModule + ], + declarations: [ + SearchingProjectsTabComponent + ], + providers:[ + ], + exports: [ + + SearchingProjectsTabComponent + ] +}) +export class SearchingProjectsTabModule { } diff --git a/portal-4cli/src/app/landingPages/landing-utils/showAuthors.component.ts b/portal-4cli/src/app/landingPages/landing-utils/showAuthors.component.ts new file mode 100644 index 00000000..d4dcc85e --- /dev/null +++ b/portal-4cli/src/app/landingPages/landing-utils/showAuthors.component.ts @@ -0,0 +1,65 @@ +import {Component, Input, ElementRef} from '@angular/core'; +import {RouterHelper} from '../../utils/routerHelper.class'; + +@Component({ + selector: 'showAuthors', + template: ` + + + + + {{author}} + ; + + ... + + + + {{author}} + ; + + + + + view all {{authors.length}} authors + + + + View less authors + + + + ` + + }) + +export class ShowAuthorsComponent { + @Input() authors: { [key: string]: string }[]; + @Input() searchPage:string ="publications" + + public showAll: boolean = false; + public routerHelper:RouterHelper = new RouterHelper(); + + constructor (private element: ElementRef) { + } + + ngOnInit() { + } + + public quote(params: string):string { + return '"'+params+'"'; + } + + public scroll() { + console.info("scroll into view"); + if (typeof document !== 'undefined') { + this.element.nativeElement.scrollIntoView(); + } + } +} diff --git a/portal-4cli/src/app/landingPages/landing-utils/showIdentifiers.component.ts b/portal-4cli/src/app/landingPages/landing-utils/showIdentifiers.component.ts new file mode 100644 index 00000000..687b5204 --- /dev/null +++ b/portal-4cli/src/app/landingPages/landing-utils/showIdentifiers.component.ts @@ -0,0 +1,94 @@ +import {Component, Input, ElementRef} from '@angular/core'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; + +@Component({ + selector: 'showIdentifiers', + template: ` + + + View less identifiers + + + + + + + {{key}}: {{item}}{{key}}: {{item}}{{key}}: {{item}}{{", "}} + ... + + + + + + + view all {{countIdentifiers()}} identifiers + + + + View less identifiers + + + + ` + }) + +export class ShowIdentifiersComponent { + @Input() identifiers: Map; + public doiURL: string; + public pmcURL: string; + public handleURL: string; + public showAll: boolean = false; + public sizeOfIdentifiers: number = -1; + public sizeOfPreviousIdentifiers: number = -1; + public pageSize: number = 10; + + constructor (private element: ElementRef) { + this.doiURL = OpenaireProperties.getDoiURL(); + this.pmcURL = OpenaireProperties.getPmcURL(); + this.handleURL = OpenaireProperties.getHandleURL(); + } + + ngOnInit() {} + + public countIdentifiers(): number { + if(this.sizeOfIdentifiers < 0) { + let num: number = 0; + if(this.identifiers != undefined) { + this.identifiers.forEach(function (value, key, map) { + num += value.length; + }); + } + this.sizeOfIdentifiers = num; + } + return this.sizeOfIdentifiers; + } + + public countSizeOfPreviousIdentifiers(index: number): number { + let num: number = 0; + let i: number = 0; + if(this.identifiers != undefined) { + this.identifiers.forEach(function (value, key, map) { + if(i < index) { + num += value.length; + } + i++; + }); + } + this.sizeOfPreviousIdentifiers= num; + return num; + } + + public scroll() { + console.info("scroll into view"); + if (typeof document !== 'undefined') { + this.element.nativeElement.scrollIntoView(); + } + } + public getKeys( map) { + return Array.from(map.keys()); + } +} diff --git a/portal-4cli/src/app/landingPages/landing-utils/showSubjects.component.ts b/portal-4cli/src/app/landingPages/landing-utils/showSubjects.component.ts new file mode 100644 index 00000000..e3f4faa5 --- /dev/null +++ b/portal-4cli/src/app/landingPages/landing-utils/showSubjects.component.ts @@ -0,0 +1,57 @@ +import {Component, Input} from '@angular/core'; + +@Component({ + selector: 'showSubjects', + template: ` +
+ +
+ Subject: + + {{subjects.join(" | ")}} +
    +
  • +
    + {{key}}: {{otherSubjects.get(key).join(" | ")}} +
    +
  • + +
+
+ +
+
+
+ Classified by OpenAIRE into +
+ {{key}}: {{classifiedSubjects.get(key).join(" | ")}} +
+
+
+
+
+ ` + + }) + +export class ShowSubjectsComponent { + @Input() subjects: string[]; + @Input() otherSubjects: Map; + @Input() classifiedSubjects: Map; + // private showClassifiedSbj: boolean = false; + + constructor () { + } + + ngOnInit() { + } + public getKeys( map) { + return Array.from(map.keys()); + } +} diff --git a/portal-4cli/src/app/landingPages/landing-utils/showTitle.component.ts b/portal-4cli/src/app/landingPages/landing-utils/showTitle.component.ts new file mode 100644 index 00000000..a458aae9 --- /dev/null +++ b/portal-4cli/src/app/landingPages/landing-utils/showTitle.component.ts @@ -0,0 +1,66 @@ +import {Component, Input} from '@angular/core'; +import {ActivatedRoute} from '@angular/router'; + +@Component({ + selector: 'showTitle', + template: ` +

+ + + + + + + [no title available] + + + + + + + [no title available] + +

+ + ` + + }) + +export class ShowTitleComponent { + @Input() title: { [key: string]: string }; + @Input() iconClass:string; + + sub: any; + + constructor (private route: ActivatedRoute) {} + + ngOnInit() { + this.sub = this.route.queryParams.subscribe( + params => { + console.info("onInit showTitle"); + + if(this.title['accessMode'] == undefined) { + this.title['accessMode'] = ""; + } + } + ); + } + + ngOnDestroy() { + console.info("onDestroy showTitle"); + this.sub.unsubscribe(); + } +} diff --git a/portal-4cli/src/app/landingPages/landing-utils/tabPaging.component.ts b/portal-4cli/src/app/landingPages/landing-utils/tabPaging.component.ts new file mode 100644 index 00000000..f0671764 --- /dev/null +++ b/portal-4cli/src/app/landingPages/landing-utils/tabPaging.component.ts @@ -0,0 +1,24 @@ +import {Component, Input, Output, EventEmitter} from '@angular/core'; + +@Component({ + selector: 'tabPaging', + template: ` + + ` + }) + +export class TabPagingComponent { + @Input() showAll: boolean; + @Input() length: number; + @Output() changeShowAll: EventEmitter = new EventEmitter(); + + constructor () { + } + + ngOnInit() { + } +} diff --git a/portal-4cli/src/app/landingPages/landing-utils/tabTable.component.ts b/portal-4cli/src/app/landingPages/landing-utils/tabTable.component.ts new file mode 100644 index 00000000..83e51e77 --- /dev/null +++ b/portal-4cli/src/app/landingPages/landing-utils/tabTable.component.ts @@ -0,0 +1,99 @@ +import {Component, Input} from '@angular/core'; +import {RouterHelper} from '../../utils/routerHelper.class'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; +//import {PagingModule} from '../utils/paging.module'; + +@Component({ + selector: 'tabTable', + template: ` +
+ {{info.length}} research results, page {{page}} of {{totalPages(info.length)}} + +
+ + + + + + + + + +
+ + (Publication) + (Dataset) + (Software) + + + + + {{item['name']}} + + + + {{item['name']}} + + + + + + {{item['name']}} + + +

{{item['name']}}

+ + ({{item['date']}}) + +
+
+
{{item['trust']}}%
+ +
+
+

No trust available

+
+
+ ` + + }) + +export class TabTableComponent { + @Input() info: { "name": string, "url": string, "date": string, "trust": number}[];//Map; + + public routerHelper:RouterHelper = new RouterHelper(); + public searchLinkToPublication: string; + public searchLinkToDataset: string; + + public page: number = 1; + public pageSize: number = 10; + + constructor () { + } + + ngOnInit() { + this.searchLinkToPublication = OpenaireProperties.getsearchLinkToPublication(); + this.searchLinkToDataset = OpenaireProperties.getsearchLinkToDataset(); + } + + totalPages(totalResults: number): number { + let totalPages:any = totalResults/this.pageSize; + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, this.pageSize) + 1); + } + return totalPages; + } + + updatePage($event) { + this.page = $event.value; + } +} diff --git a/portal-4cli/src/app/landingPages/organization/organization-routing.module.ts b/portal-4cli/src/app/landingPages/organization/organization-routing.module.ts new file mode 100644 index 00000000..0111f624 --- /dev/null +++ b/portal-4cli/src/app/landingPages/organization/organization-routing.module.ts @@ -0,0 +1,18 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { OrganizationComponent } from './organization.component'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PreviousRouteRecorder} from'../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: OrganizationComponent, canActivate: [FreeGuard, IsRouteEnabled], data: { + redirect: '/error' + },canDeactivate: [PreviousRouteRecorder] } + ]) +] +}) +export class OrganizationRoutingModule { } diff --git a/portal-4cli/src/app/landingPages/organization/organization.component.html b/portal-4cli/src/app/landingPages/organization/organization.component.html new file mode 100644 index 00000000..a4b748e3 --- /dev/null +++ b/portal-4cli/src/app/landingPages/organization/organization.component.html @@ -0,0 +1,195 @@ + diff --git a/portal-4cli/src/app/landingPages/organization/organization.component.ts b/portal-4cli/src/app/landingPages/organization/organization.component.ts new file mode 100644 index 00000000..1e02b02d --- /dev/null +++ b/portal-4cli/src/app/landingPages/organization/organization.component.ts @@ -0,0 +1,489 @@ +import {Component, ViewChild, ElementRef} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {Subject} from 'rxjs/Subject'; +import {ActivatedRoute, Router} from '@angular/router'; + +import {OrganizationService} from '../../services/organization.service'; +import {OrganizationInfo} from '../../utils/entities/organizationInfo'; +import {ReportsService} from '../../services/reports.service'; +import {FetchPublications} from '../../utils/fetchEntitiesClasses/fetchPublications.class'; +import {FetchProjects} from '../../utils/fetchEntitiesClasses/fetchProjects.class'; +import {FetchDataproviders} from '../../utils/fetchEntitiesClasses/fetchDataproviders.class'; +import {SearchPublicationsService} from '../../services/searchPublications.service'; +import {SearchDataprovidersService} from '../../services/searchDataproviders.service'; +import {SearchProjectsService} from '../../services/searchProjects.service'; +import { Meta} from '../../../angular2-meta'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchingProjectsTabComponent} from '../landing-utils/searchingProjectsInTab.component'; +import {RouterHelper} from '../../utils/routerHelper.class'; + +import {ModalLoading} from '../../utils/modal/loading.component'; +import {AlertModal} from '../../utils/modal/alert'; +import {PiwikService} from '../../utils/piwik/piwik.service'; +import {StringUtils} from '../../utils/string-utils.class'; + +@Component({ + selector: 'organization', + templateUrl: 'organization.component.html', +}) + +export class OrganizationComponent { + public organizationInfo: OrganizationInfo; + public organizationId: string; + + // Message variables + public warningMessage = ""; + public errorMessage = ""; + public showLoading: boolean = true; + + // CSV variables + public downloadURLAPI: string; + public csvProjectParamsHead: string; + public csvPublicationParamsHead: string; + public csvParamsTail: string; + + // Active tab variable for responsiveness + public activeTab: string = "Publications"; + + // Variables for publications, projects, dataproviders tabs + public fetchPublications: FetchPublications; + public linkToSearchPublications: string = ""; + public fetchProjects: FetchProjects; + public fetchDataproviders : FetchDataproviders; + public linkToSearchDataproviders:string = ""; + //public projectFunders:string[] = []; + + // Variables for projects query (query results only if projects tab is clicked) + public projectsClicked: boolean = false; + @ViewChild (SearchingProjectsTabComponent) searchingProjectsTabComponent : SearchingProjectsTabComponent ; + + @ViewChild (ModalLoading) loading : ModalLoading ; + // Alert box when CSV: Project Publications for a funder is requested + @ViewChild('AlertModalApplyAll') alertApplyAll; + // Alert box when something is wrong with CSV requests + @ViewChild('AlertModalCsvError') alertCsvError; + + public routerHelper:RouterHelper = new RouterHelper(); + public errorCodes:ErrorCodes = new ErrorCodes(); + + //private projectsNum: number = 0; + //private fundersSet: Set; + //private emptyFundersSet: boolean = true; + + // Request results for content providers only the one time (first time tab is clicked) + private reloadDataproviders: boolean = true; + + // Helper variables to specify funder in downloadPublicationsFile function + private funder: string; + private funderId: string; + private funderCountPublications: number; + sub: any; + infoSub: any; + piwiksub: any; + downloadFileSub: any; + downloadFilePiwikSub: any; + countProjectsSub: any; + countPublSub: any; + downloadProjectPublSub: any; + + //private ngUnsubscribe: Subject = new Subject(); + + constructor (private element: ElementRef, + private _organizationService: OrganizationService, + private _piwikService:PiwikService, + private route: ActivatedRoute, + private _searchDataprovidersService: SearchDataprovidersService, + private _reportsService: ReportsService, + private _searchPublicationsService: SearchPublicationsService, + private _searchProjectsService: SearchProjectsService, private _meta: Meta, + private _router: Router) { + + this.fetchPublications = new FetchPublications(this._searchPublicationsService); + this.fetchProjects = new FetchProjects(this._searchProjectsService); + this.fetchDataproviders = new FetchDataproviders(this._searchDataprovidersService); + this.updateUrl(OpenaireProperties.getBaseLink()+this._router.url); + } + + ngOnInit() { + console.info('organization init'); + this.sub = this.route.queryParams.subscribe(params => { + this.organizationInfo=null; + this.updateTitle("Organization"); + this.updateDescription("Organization, country, projects, search, repositories, open access"); + this.projectsClicked = false; + + this.organizationId = params['organizationId']; + console.info("Id is :"+this.organizationId); + + if(this.organizationId){ + this.getOrganizationInfo(); + }else{ + this.showLoading = false; + this.warningMessage="No valid organization id"; + } + + if (typeof document !== 'undefined') { + this.element.nativeElement.scrollIntoView(); + } + + this.csvParamsTail = '" and relorganizationid exact "'+this.organizationId+'" ))'; + + }); + + this.downloadURLAPI = OpenaireProperties.getCsvAPIURL(); + this.csvProjectParamsHead = 'format=csv&type=projects&page=0&query=( (oaftype exact project)and (funder exact "'; + //this.csvPublicationParamsHead = 'format=csv-special&type=publications&page=0&query=((((oaftype exact result) and (resulttypeid exact publication)) and (funderid exact '; + } + + + ngOnDestroy() { + this.sub.unsubscribe(); + if(this.piwiksub){ + this.piwiksub.unsubscribe(); + } + if(this.infoSub) { + this.infoSub.unsubscribe(); + } + if(this.downloadFileSub) { + this.downloadFileSub.unsubscribe(); + } + if(this.downloadFilePiwikSub) { + this.downloadFilePiwikSub.unsubscribe(); + } + if(this.countProjectsSub) { + this.countProjectsSub.unsubscribe(); + } + if(this.countPublSub) { + this.countPublSub.unsubscribe(); + } + if(this.downloadProjectPublSub) { + this.downloadProjectPublSub.unsubscribe(); + } + + /* + this.ngUnsubscribe.next(); + this.ngUnsubscribe.complete(); + */ + } + + private getOrganizationInfo () { + + this.warningMessage = ''; + this.errorMessage="" + this.showLoading = true; + + this.infoSub = this._organizationService.getOrganizationInfo(this.organizationId).subscribe( + data => { + if(data == null) { + this.showLoading = false; + this.errorMessage = 'No organization found'; + } else { + this.organizationInfo = data; + this.updateTitle(this.organizationInfo.title.name); + this.updateDescription("Organization, country, projects, search, repositories, open access"+this.organizationInfo.title.name); + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.piwiksub = this._piwikService.trackView(this.organizationInfo.title.name).subscribe(); + } + var refineFields:string [] = ["funder"]; + + this.searchPublications(); + + this.fetchProjects.getResultsForOrganizations(this.organizationId, "", 1, 0,refineFields); + + this.fetchDataproviders.getNumForEntity("organization", this.organizationId); + + this.showLoading = false; + + /*let projectsNum = 0; + + if(this.organizationInfo.projects != undefined) { + this.fundersSet = new Set(); + this.organizationInfo.projects.forEach(function (value, key, map) { + projectsNum += value.length; + this.fundersSet.add(key); + }.bind(this)); + } + + this.projectsNum = projectsNum;*/ + } + }, + err => { + console.log(err) + + this.errorMessage = 'No organization found'; + this.showLoading = false; + } + ); + } +/* + private getMetrics() { + console.info("getOrganizationMetrics: component"); + this._organizationService.getMetrics(this.organizationId).subscribe( + data => { + this.metrics = data; + }, + err => { + console.log(err); + } + ); + } +*/ +/* + private handleClick(funder: string) { + if(this.emptyFundersSet) { + this.fundersSet.clear(); + this.emptyFundersSet = false; + } + + if(this.fundersSet.has(funder)) { + this.fundersSet.delete(funder); + + if(this.fundersSet.size == 0) { + this.organizationInfo.projects.forEach(function (value, key, map) { + this.fundersSet.add(key); + }.bind(this)); + this.emptyFundersSet = true; + } + console.info(funder+" funder deleted"); + } else { + this.fundersSet.add(funder); + console.info(funder+" funder added"); + } + } +*/ + //private getProjectsData(key: string): any { + //return this.projectsData; + //} + + private searchPublications() { + this.fetchPublications.getResultsForEntity("organization", this.organizationId, 1, 10); + this.linkToSearchPublications = OpenaireProperties.getLinkToAdvancedSearchPublications();// + "?project=" + this.projectId+"&pr=and"; + if(this.fetchPublications.searchUtils.totalResults > 0) { + //this.activeTab = "Publications"; + } else { + //this.projectsClicked = true; + } + } + + private searchDataproviders() { + this.fetchDataproviders.getResultsForEntity("organization", this.organizationId, 1, 10); + this.linkToSearchDataproviders = OpenaireProperties.getLinkToAdvancedSearchDataProviders(); + + if(this.fetchDataproviders.searchUtils.totalResults > 0) { + this.reloadDataproviders = false; + //this.activeTab = "Content Providers"; + } else { + + } + } + + public searchDataprovidersInit() { + if(this.reloadDataproviders && this.fetchDataproviders.searchUtils.totalResults > 0) { + this.searchDataproviders(); + } + } + + public downloadFile(url:string){ + console.log("Downloading file: "+ url); + + this.openLoading(); + this.setMessageLoading("Downloading CSV file"); + + this.downloadFileSub = this._reportsService.downloadCSVFile(url).subscribe( + data => { + this.closeLoading(); + window.open(window.URL.createObjectURL(data)); + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.downloadFilePiwikSub = this._piwikService.trackDownload(url).subscribe(); + } + }, + err => { + console.log("Error downloading the file."); + this.closeLoading(); + this.confirmOpenCsvError(); + }, + () => console.log('Completed file download.')); + } + + private downloadPublicationsFile(funder: string, funderId:string, count:number){ + console.log("Downloading publications file"); + + this.openLoading(); + this.setMessageLoading("Downloading CSV file"); + + let response: string[] = []; + let totalResponse: string = ""; + let projects = []; + let counter: number = count; + let title: boolean = false; + + this.countProjectsSub = this._searchProjectsService.getProjectsForOrganizations(this.organizationId,' and (funder exact "'+ funderId + '" ) ',1,count,[]).subscribe( + data => + { + projects = data[1]; + for(let index=0; index < projects.length; index++) { + this.countPublSub = this._searchPublicationsService.numOfEntityPublications(projects[index].id, "project").subscribe( + data => + { + // let index: number = this.organizationInfo.projects.get(funder).indexOf(project); + + let url: string; + if(index == 0 || !title) { + url = this.downloadURLAPI+"projects/"+projects[index].id+"/publications?format=csv-special&size="+data; + } else { + url = this.downloadURLAPI+"projects/"+projects[index].id+"/publications?format=csv-special-notitle&size="+data; + } + + if(data == 0) { // if no publications for this project + counter--; + response[index] = ""; + if(counter == 0) { + for(let i=0; i + { + counter--; + response[index] = data; + + if(counter == 0) { + for(let i=0; i { + console.log("Error downloading the file."); + this.closeLoading(); + this.confirmOpenCsvError(); + }, + () => console.log('Completed file download.') + ); + } + }, + err => console.log("Error getting number of publications for project.")); + }//); + + }, + err => { + console.log("Error getting projects project."); + this.closeLoading(); + this.confirmOpenCsvError(); + } + ); + + // let counter: number = this.organizationInfo.projects.get(funder).length; + // + // for(let project of this.organizationInfo.projects.get(funder)) { + // this._searchPublicationsService.numOfEntityPublications(project.id, "projects/").subscribe( + // data => + // { + // let index: number = this.organizationInfo.projects.get(funder).indexOf(project); + // + // let url: string; + // if(index == 0) { + // url = this.downloadURLAPI+"projects/"+project.id+"/publications?format=csv-special&size="+data; + // } else { + // url = this.downloadURLAPI+"projects/"+project.id+"/publications?format=csv-special-notitle&size="+data; + // } + // + // this._reportsService.getCSVResponse(url).subscribe( + // data => + // { + // counter--; + // + // response[index] = data; + // + // if(counter == 0) { + // for(let i=0; i console.log("Error downloading the file."), + // () => console.log('Completed file download.')); + // }, + // error => console.log("Error getting number of publications for project.")); + // }//); + } + + private updateDescription(description:string){ + this._meta.updateMeta("description", description); + this._meta.updateProperty("og:description", description); + } + private updateTitle(title:string){ + var _prefix ="OpenAIRE | "; + var _title = _prefix + ((title.length> 50 ) ?title.substring(0,50):title); + this._meta.setTitle(_title ); + this._meta.updateProperty("og:title",_title); + } + private updateUrl(url:string){ + this._meta.updateProperty("og:url", url); + } + + private openLoading(){ + if(this.loading){ + this.loading.open(); + } + } + private closeLoading(){ + if(this.loading){ + this.loading.close(); + } + } + private setMessageLoading(message: string){ + if(this.loading){ + this.loading.message = message; + } + } + + public confirmOpenApplyAll(funder: string, funderId:string, funderCountPublications:number){ + this.alertApplyAll.cancelButton = true; + this.alertApplyAll.okButton = true; + this.alertApplyAll.alertTitle = "CSV FILE"; + this.alertApplyAll.message = "Do you wish to download a CSV file? Note that this process may take a while."; + this.alertApplyAll.okButtonText = "Yes"; + this.alertApplyAll.cancelButtonText = "No"; + this.alertApplyAll.open(); + + this.funder = funder; + this.funderId = funderId; + this.funderCountPublications = funderCountPublications; + } + public confirmCloseApplyAll(data){ + this.downloadPublicationsFile(this.funder, this.funderId, this.funderCountPublications); + } + + public confirmOpenCsvError(){ + this.alertCsvError.cancelButton = false; + this.alertCsvError.okButton = true; + this.alertCsvError.alertTitle = "ERROR DOWNLOADING CSV FILE"; + this.alertCsvError.message = "There was an error in csv downloading. Please try again later."; + this.alertCsvError.okButtonText = "OK"; + this.alertCsvError.open(); + } + + encodeURI(input: string): string { + return StringUtils.URIEncode(input); + } +} diff --git a/portal-4cli/src/app/landingPages/organization/organization.module.ts b/portal-4cli/src/app/landingPages/organization/organization.module.ts new file mode 100644 index 00000000..3e8e6f1d --- /dev/null +++ b/portal-4cli/src/app/landingPages/organization/organization.module.ts @@ -0,0 +1,52 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import {LoadingModalModule} from '../../utils/modal/loadingModal.module'; +import {AlertModalModule} from '../../utils/modal/alertModal.module'; +import {ErrorMessagesModule} from '../../utils/errorMessages.module'; + +import { OrganizationServiceModule} from '../../services/organizationService.module'; +// import { ProjectsServiceModule} from '../../services/projectsService.module'; +import { OrganizationComponent } from './organization.component'; +import { OrganizationRoutingModule } from './organization-routing.module'; + +import { LandingModule } from '../landing-utils/landing.module'; +import {TabResultModule } from '../../searchPages/searchUtils/tabResult.module'; +import {DataProvidersServiceModule} from '../../services/dataProvidersService.module'; +import {ReportsServiceModule} from '../../services/reportsService.module'; +import {PublicationsServiceModule} from '../../services/publicationsService.module'; +import {ProjectsServiceModule} from '../../services/projectsService.module'; + +import { SearchingProjectsTabModule} from '../landing-utils/searchingProjectsInTab.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, RouterModule, + LoadingModalModule, AlertModalModule, ErrorMessagesModule, + LandingModule, + OrganizationRoutingModule, + TabResultModule, + DataProvidersServiceModule, + ReportsServiceModule, + OrganizationServiceModule, + SearchingProjectsTabModule, + OrganizationServiceModule, + PublicationsServiceModule, + ProjectsServiceModule + + ], + declarations: [ + OrganizationComponent, + ], + providers:[ + FreeGuard, IsRouteEnabled + ], + exports: [ + OrganizationComponent + ] +}) +export class OrganizationModule { } diff --git a/portal-4cli/src/app/landingPages/project/project-routing.module.ts b/portal-4cli/src/app/landingPages/project/project-routing.module.ts new file mode 100644 index 00000000..4fa87efe --- /dev/null +++ b/portal-4cli/src/app/landingPages/project/project-routing.module.ts @@ -0,0 +1,18 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { ProjectComponent } from './project.component'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PreviousRouteRecorder} from'../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: ProjectComponent, canActivate: [FreeGuard, IsRouteEnabled], data: { + redirect: '/error' + },canDeactivate: [PreviousRouteRecorder] } + ]) + ] +}) +export class ProjectRoutingModule { } diff --git a/portal-4cli/src/app/landingPages/project/project.component.html b/portal-4cli/src/app/landingPages/project/project.component.html new file mode 100644 index 00000000..33e79633 --- /dev/null +++ b/portal-4cli/src/app/landingPages/project/project.component.html @@ -0,0 +1,382 @@ +
+
+
+ +
+ + + + +
+
+ +

+ + {{projectName}} + {{projectName}} + ({{projectInfo.contractNum}}) +

+
{{projectInfo.title}} ({{projectInfo.contractNum}})
+ + Project + {{projectInfo.funder}} + Open Access mandate + Special Clause 39 + + +
+ +
+ + +
+
+ + + + + + + + +
+ + + + + +
+ + + + +
+ +
+

Research Results

+ +

Access Mode of Research Results

+ +

By Datasource of Research Results

+ +
+
+
+
+ + + + + + + + + +
+ +
+
+ +
+
+ Share - Bookmark +
+
+
+ Application Box +
+ + +
+ + +
+
+ + +
+
+
+
diff --git a/portal-4cli/src/app/landingPages/project/project.component.ts b/portal-4cli/src/app/landingPages/project/project.component.ts new file mode 100644 index 00000000..39597b62 --- /dev/null +++ b/portal-4cli/src/app/landingPages/project/project.component.ts @@ -0,0 +1,360 @@ +import {Component, ViewChild, ElementRef} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {ActivatedRoute, Params, Router} from '@angular/router'; +import {ProjectService} from './project.service'; +import {ProjectInfo} from '../../utils/entities/projectInfo'; +import {RouterHelper} from '../../utils/routerHelper.class'; + +import { FetchPublications } from '../../utils/fetchEntitiesClasses/fetchPublications.class'; +import { SearchPublicationsService } from '../../services/searchPublications.service'; +import { FetchDatasets } from '../../utils/fetchEntitiesClasses/fetchDatasets.class'; +import { SearchDatasetsService } from '../../services/searchDatasets.service'; +import { FetchSoftware } from '../../utils/fetchEntitiesClasses/fetchSoftware.class'; +import { SearchSoftwareService } from '../../services/searchSoftware.service'; + +import {ModalLoading} from '../../utils/modal/loading.component'; + +import {ReportsService} from '../../services/reports.service'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import { Meta} from '../../../angular2-meta'; + +import {PiwikService} from '../../utils/piwik/piwik.service'; + +@Component({ + selector: 'project', + templateUrl: 'project.component.html', + }) +export class ProjectComponent{ + public projectInfo: ProjectInfo; + public projectId : string ; + public projectName: string; + + // Metrics tab variables + public metricsClicked: boolean; + public viewsFrameUrl: string; + public downloadsFrameUrl: string; + private totalViews: number; + private totalDownloads: number; + private pageViews: number; + + // Statistics tab variables + public statsClicked: boolean; + public chartScientificResultsUrl: string; + public chartAccessModeUrl: string; + public chartDatasourcesUrl: string; + + // HTML variables in APP BOX + public publications_dynamic: string; + public datasets_dynamic: string; + + public project ; + + // CSV variables + public downloadURLAPI: string; + public csvParams: string; + public csvParamsDatasets: string; + + // Message variables + public warningMessage = ""; + public errorMessage = ""; + public showLoading: boolean = true; + + // Active tab variable for responsiveness + public activeTab: string = "Publications"; + + // Request results for research data and software only the one time (first time tab is clicked) + private reloadDatasets: boolean = true; + private reloadSoftware: boolean = true; + + // Variables for publications, research data, software tabs + public fetchPublications : FetchPublications; + public linkToSearchPublications = ""; + public fetchDatasets : FetchDatasets; + public linkToSearchDatasets = ""; + public fetchSoftware: FetchSoftware; + public linkToSearchSoftware = ""; + + public routerHelper:RouterHelper = new RouterHelper(); + public errorCodes:ErrorCodes = new ErrorCodes(); + + @ViewChild (ModalLoading) loading : ModalLoading ; + // Alert box when something is wrong with CSV requests + @ViewChild('AlertModalCsvError') alertCsvError; + + sub: any; piwiksub: any; infoSub: any; downloadFilePiwikSub: any; + + constructor ( private element: ElementRef, + private _projectService: ProjectService, + private _piwikService:PiwikService, + private route: ActivatedRoute, + private _searchPublicationsService: SearchPublicationsService, + private _searchDatasetsService: SearchDatasetsService, + private _searchSoftwareService: SearchSoftwareService, + private _reportsService: ReportsService, private _meta: Meta, + private _router: Router) { + this.updateUrl(OpenaireProperties.getBaseLink()+this._router.url); + } + + ngOnInit() { + this.sub = this.route.queryParams.subscribe(params => { + this.metricsClicked = false; + this.statsClicked = false; + this.fetchPublications = new FetchPublications( this._searchPublicationsService); + this.fetchDatasets = new FetchDatasets(this._searchDatasetsService); + this.fetchSoftware = new FetchSoftware(this._searchSoftwareService); + + this.updateTitle("Project"); + this.updateDescription("project, funding, open access, publications, research data, software"); + + this.projectId = params['projectId']; + if(this.projectId){ + this.publications_dynamic = + ""; + + this.datasets_dynamic = + ""; + + this.getProjectInfo(this.projectId); + this.searchPublications(); + this.fetchDatasets.getNumForEntity("project", this.projectId); + this.fetchSoftware.getNumForEntity("project", this.projectId); + }else{ + this.showLoading = false; + this.warningMessage="No valid project id"; + } + + this.downloadURLAPI = OpenaireProperties.getCsvAPIURL(); + + this.createClipboard(); + this.csvParams = "format=csv-special&page=0&type=publications&query=(((oaftype exact result) and (resulttypeid exact publication)) and (relprojectid exact "+this.projectId+"))&size="; + this.csvParamsDatasets = "format=csv-special&page=0&type=datasets&query=(((oaftype exact result) and (resulttypeid exact dataset)) and (relprojectid exact "+this.projectId+"))&size="; + + if (typeof document !== 'undefined') { + this.element.nativeElement.scrollIntoView(); + } + }); +} + + + ngOnDestroy() { + this.sub.unsubscribe(); + if(this.piwiksub){ + this.piwiksub.unsubscribe(); + } + if(this.infoSub) { + this.infoSub.unsubscribe(); + } + if(this.downloadFilePiwikSub) { + this.downloadFilePiwikSub.unsubscribe(); + } + } + + private createClipboard() { + if(typeof window !== 'undefined') { + + let publ_clipboard, datasets_clipboard; + let Clipboard; + Clipboard = require('clipboard'); + publ_clipboard = new Clipboard('.publ_clipboard_btn'); + datasets_clipboard = new Clipboard('.datasets_clipboard_btn'); + } + } + + private searchPublications() { + this.fetchPublications.getResultsForEntity("project", this.projectId, 1, 10); + this.linkToSearchPublications = OpenaireProperties.getLinkToAdvancedSearchPublications();// + "?project=" + this.projectId+"&pr=and"; + if(this.fetchPublications.searchUtils.totalResults > 0) { + //this.activeTab = "Publications"; + } else { + //this.searchDatasetsInit(); + } + } + + private searchDatasets() { + this.fetchDatasets.getResultsForEntity("project", this.projectId, 1, 10); + this.linkToSearchDatasets = OpenaireProperties.getLinkToAdvancedSearchDatasets();// + "?project=" + this.projectId+"&pr=and"; + + this.reloadDatasets = false; + //this.activeTab = "Research Data"; + } + + private searchSoftware() { + this.fetchSoftware.getResultsForEntity("project", this.projectId, 1, 10); + this.linkToSearchSoftware = OpenaireProperties.getLinkToAdvancedSearchSoftware(); + this.reloadSoftware = false; + } + + public searchDatasetsInit() { + console.info("searchDatasetsInit"); + if(this.reloadDatasets && this.fetchDatasets.searchUtils.totalResults > 0) { + this.searchDatasets(); + } else if(this.fetchDatasets.searchUtils.totalResults == 0) { + //this.statsClicked=true; + //this.activeTab = "Statistics"; + } + } + + public searchSoftwareInit() { + console.info("searchSoftwareInit"); + if(this.reloadSoftware && this.fetchSoftware.searchUtils.totalResults > 0) { + this.searchSoftware(); + } + } + + private getProjectInfo (id:string) { + this.warningMessage = ''; + this.errorMessage="" + this.showLoading = true; + + this.infoSub = this._projectService.getProjectInfo(id).subscribe( + data => { + this.projectInfo = data; + + this.projectName = this.projectInfo.acronym; + if(this.projectName == undefined || this.projectName == '') { + this.projectName = this.projectInfo.title; + } + this.updateTitle(this.projectName); + this.updateDescription("project, funding, open access, publications, research data, "+this.projectName+ ","+this.projectInfo.funder); + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.piwiksub = this._piwikService.trackView(this.projectName).subscribe(); + } + + this.project= { funderId: "", funderName: this.projectInfo.funder, projectId: this.projectId, projectName: this.projectInfo.title, projectAcronym: this.projectInfo.acronym, startDate: this.projectInfo.startDate, endDate: this.projectInfo.endDate }; + + this.viewsFrameUrl = OpenaireProperties.getFramesAPIURL()+'merge.php?com=query&data=[{"query":"projRepoViews","projTitle":"'+this.projectId+'","table":"","fields":[{"fld":"sum","agg":"sum","type":"column","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=["column"]&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'; + + this.downloadsFrameUrl = OpenaireProperties.getFramesAPIURL()+'merge.php?com=query&data=[{"query":"projRepoDownloads","projTitle":"'+this.projectId+'","table":"","fields":[{"fld":"sum","agg":"sum","type":"column","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=["column"]&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'; + + //stats tab charts + this.chartScientificResultsUrl='https://beta.openaire.eu/stats/chart.php?com=query&persistent=false&data={"query":"projScient","projTitle":"'+this.projectId+'", "table": "result", "fields": [{"fld": "number", "agg": "count", "type": "spline", "yaxis":1, "c":false}], "xaxis":{"name": "result_classifications-type", "agg": "avg"}, "group": "", "color": "", "type": "chart", "size":30, "sort": "xaxis", "xStyle":{"r": "-", "s": "-", "l": "-", "ft": "-", "wt": "-"}, "yaxisheaders": [""], "fieldsheaders": ["Research Results"], "in": [], "filters": [{"name": "result_datasources-datasource-name", "values": [" "], "to": "-1"}], "having": [], "incfilters": [], "inchaving": [], "title": "", "subtitle": "", "xaxistitle": ""}&w=600&h=250'; + this.chartAccessModeUrl='https://beta.openaire.eu/stats/chart.php?com=query&persistent=false&data={"query":"projOA","projTitle":"'+this.projectId+'", "table": "result", "fields": [{"fld": "number", "agg": "count", "type": "pie", "yaxis":1, "c":false}], "xaxis":{"name": "result_classifications-type", "agg": "avg"}, "group": "", "color": "", "type": "chart", "size":30, "sort": "xaxis", "xStyle":{"r": "-", "s": "-", "l": "-", "ft": "-", "wt": "-"}, "yaxisheaders": [""], "fieldsheaders": ["Research Results"], "in": [], "filters": [{"name": "result_datasources-datasource-name", "values": [" "], "to": "-1"}], "having": [], "incfilters": [], "inchaving": [], "title": "", "subtitle": "", "xaxistitle": ""}&w=600&h=250'; + this.chartDatasourcesUrl= 'https://beta.openaire.eu/stats/chart.php?com=query&persistent=false&data={"query":"projPubsRepos","projTitle":"'+this.projectId+'", "table": "result", "fields": [{"fld": "number", "agg": "count", "type": "bar", "yaxis":1, "c":false}], "xaxis":{"name": "result_classifications-type", "agg": "avg"}, "group": "", "color": "", "type": "chart", "size":30, "sort": "xaxis", "xStyle":{"r": "-", "s": "-", "l": "-", "ft": "-", "wt": "-"}, "yaxisheaders": [""], "fieldsheaders": ["Research Results"], "in": [], "filters": [{"name": "result_datasources-datasource-name", "values": [" "], "to": "-1"}], "having": [], "incfilters": [], "inchaving": [], "title": "", "subtitle": "", "xaxistitle": ""}&w=600&h=250'; + + this.showLoading = false; + }, + err => { + console.log(err); + this.errorMessage = 'No project found'; + this.showLoading = false; + } + ); + } + + public downloadfile(url:string){ + this.openLoading(); + this.setMessageLoading("Downloading CSV file"); + + this._reportsService.downloadCSVFile(url).subscribe( + data => { + this.closeLoading(); + window.open(window.URL.createObjectURL(data)); + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.downloadFilePiwikSub = this._piwikService.trackDownload(url).subscribe(); + } + }, + error => { + console.log("Error downloading the file."); + this.closeLoading(); + this.confirmOpenCsvError(); + }, + () => console.log('Completed file download.') + ); + } + +/* + showHTML(){ + let info:string = "

Publications of Project "; + + if(this.projectInfo.title != undefined && this.projectInfo.title != "") { + info += this.projectInfo.title; + } + if((this.projectInfo.title != undefined && this.projectInfo.title != "") && + ((this.projectInfo.acronym != undefined && this.projectInfo.acronym != "") || + (this.projectInfo.callIdentifier != undefined && this.projectInfo.callIdentifier != ""))) { + info += "("; + } + if(this.projectInfo.acronym != undefined && this.projectInfo.acronym != "") { + info += this.projectInfo.acronym + " - "; + } + if(this.projectInfo.callIdentifier != undefined && this.projectInfo.callIdentifier != "") { + info += this.projectInfo.callIdentifier; + } + if((this.projectInfo.title != undefined && this.projectInfo.title != "") && + ((this.projectInfo.acronym != undefined && this.projectInfo.acronym != "") || + (this.projectInfo.callIdentifier != undefined && this.projectInfo.callIdentifier != ""))) { + info += ")"; + } + info +="

"; + info += "

"+this.fetchPublications.searchUtils.totalResults+" publications

"; + + let htmlParams = 'resources?format=html&page=0&size='+this.fetchPublications.searchUtils.totalResults+'&type=publications&query=(((oaftype exact result) and (resulttypeid exact publication)) and (relprojectid exact "'+this.projectId+'"))'; + this._reportsService.downloadHTMLFile(this.downloadURLAPI+htmlParams, info) + .subscribe(data => this.funct(data), + error => console.log("Error downloading the file."), + () => console.log('Completed file download.')); + } + + funct(data) { + var win = window.open(window.URL.createObjectURL(data)); + } +*/ + public metricsResults($event) { + this.totalViews = $event.totalViews; + this.totalDownloads = $event.totalDownloads; + this.pageViews = $event.pageViews; + } + + private updateDescription(description:string){ + this._meta.updateMeta("description", description); + this._meta.updateProperty("og:description", description); + } + private updateTitle(title:string){ + var _prefix ="OpenAIRE | "; + var _title = _prefix + ((title.length> 50 ) ?title.substring(0,50):title); + this._meta.setTitle(_title ); + this._meta.updateProperty("og:title",_title); + } + private updateUrl(url:string){ + this._meta.updateProperty("og:url", url); + } + + private openLoading(){ + if(this.loading){ + this.loading.open(); + } + } + private closeLoading(){ + if(this.loading){ + this.loading.close(); + } + } + private setMessageLoading(message: string){ + if(this.loading){ + this.loading.message = message; + } + } + + public confirmOpenCsvError(){ + this.alertCsvError.cancelButton = false; + this.alertCsvError.okButton = true; + this.alertCsvError.alertTitle = "ERROR DOWNLOADING CSV FILE"; + this.alertCsvError.message = "There was an error in csv downloading. Please try again later."; + this.alertCsvError.okButtonText = "OK"; + this.alertCsvError.open(); + } +} diff --git a/portal-4cli/src/app/landingPages/project/project.module.ts b/portal-4cli/src/app/landingPages/project/project.module.ts new file mode 100644 index 00000000..e77d471e --- /dev/null +++ b/portal-4cli/src/app/landingPages/project/project.module.ts @@ -0,0 +1,45 @@ +//import {MaterialModule} from '@angular/material'; +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import { ProjectServiceModule} from './projectService.module'; +// import {HtmlProgressReportService} from './htmlProgressReport.service'; +import{LoadingModalModule} from '../../utils/modal/loadingModal.module'; +import {AlertModalModule} from '../../utils/modal/alertModal.module'; +import {ErrorMessagesModule} from '../../utils/errorMessages.module'; + +import { ProjectComponent } from './project.component'; +import { ProjectRoutingModule } from './project-routing.module'; +import {IFrameModule} from '../../utils/iframe.module'; +import {MetricsModule} from '../landing-utils/metrics.module'; +import {ReportsServiceModule} from '../../services/reportsService.module'; +import {PublicationsServiceModule} from '../../services/publicationsService.module'; +import {DatasetsServiceModule} from '../../services/datasetsService.module'; +import {SoftwareServiceModule} from '../../services/softwareService.module'; +import {TabResultModule } from '../../searchPages/searchUtils/tabResult.module'; +import { LandingModule } from '../landing-utils/landing.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, RouterModule, LandingModule, + ProjectRoutingModule, LoadingModalModule, AlertModalModule, ErrorMessagesModule, + TabResultModule, IFrameModule, MetricsModule, ReportsServiceModule, + PublicationsServiceModule, DatasetsServiceModule, SoftwareServiceModule, ProjectServiceModule + ], + declarations: [ + ProjectComponent + ], + providers:[ + // ProjectService, + // HtmlProgressReportService + FreeGuard, IsRouteEnabled + ], + exports: [ + ProjectComponent + ] +}) +export class ProjectModule { } diff --git a/portal-4cli/src/app/landingPages/project/project.service.ts b/portal-4cli/src/app/landingPages/project/project.service.ts new file mode 100644 index 00000000..57b57d90 --- /dev/null +++ b/portal-4cli/src/app/landingPages/project/project.service.ts @@ -0,0 +1,207 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {ProjectInfo} from '../../utils/entities/projectInfo'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; + +import { ParsingFunctions } from '../landing-utils/parsingFunctions.class'; + +@Injectable() +export class ProjectService { + + constructor(private http: Http ) { + this.parsingFunctions = new ParsingFunctions(); + } + + public parsingFunctions: ParsingFunctions; + projectInfo: ProjectInfo; + + getProjectInfo (id: string):any { + console.info("getProjectInfo in service"); + + let url = OpenaireProperties. getSearchAPIURLLast() + 'projects/'+id+"?format=json"; + let key = url; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => res['result']['metadata']['oaf:entity']['oaf:project']) + .map(res => [res, + res['fundingtree'], + res['rels']['rel']]) + .map(res => this.parseProjectInfo(res)); + + } + + /* + get project strtDate and endDate + */ + getProjectDates (id: string):any { + + let url = OpenaireProperties. getSearchAPIURLLast()+'projects/'+id+"?format=json"; + let key = url+'_projectDates'; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => res['result']['metadata']['oaf:entity']['oaf:project']) + .map(res => [res, + res['fundingtree'], + res['rels']['rel']]) + .map(res => this.parseProjectDates(id,res)) + + } + + getHTMLInfo(id: string): any { + let url = OpenaireProperties. getSearchAPIURLLast() + 'projects/'+id+"?format=json"; + let key = url; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => res['result']['metadata']['oaf:entity']['oaf:project']) + .map(res => this.parseHTMLInfo(res)); + } + + private handleError (error: Response) { + // in a real world app, we may send the error to some remote logging infrastructure + // instead of just logging it to the console + console.log(error); + return Observable.throw(error || 'Server error'); + } + + parseHTMLInfo (data: any):any { + let htmlInfo: {"title": string, "acronym": string, "callIdentifier": string}; + + if(data != null) { + htmlInfo = {"title": data.title, "acronym": data.acronym, "callIdentifier": data.callidentifier}; + } + return htmlInfo; + } + + parseProjectInfo (data: any):any { + this.projectInfo = new ProjectInfo(); + + if(data[0] != null) { + this.projectInfo.acronym = data[0].acronym; + if(Array.isArray(data[0]['title'])) { + this.projectInfo.title = data[0].title[0]; + } else { + this.projectInfo.title = data[0].title; + } + this.projectInfo.callIdentifier = data[0].callidentifier; + this.projectInfo.contractNum = data[0].code; + this.projectInfo.startDate = data[0].startdate; + this.projectInfo.endDate = data[0].enddate; + this.projectInfo.openAccessMandate = data[0].oamandatepublications; + this.projectInfo.specialClause39 = data[0].ecsc39; + } + if(data[1] != null) { + /* + if(data[1]['funder'] != null) { + this.projectInfo.funder = data[1]['funder'].shortname; + } + + let funding; + this.projectInfo.funding = ""; + + if(data[1]['funding_level_2'] != null) { + funding = data[1]['funding_level_2'].id; + } else if(data[1]['funding_level_1'] != null) { + funding = data[1]['funding_level_1'].id; + } else if(data[1]['funding_level_0'] != null) { + funding = data[1]['funding_level_0'].id; + } + + if(funding != undefined) { + funding = funding.split("::"); + for(let i=1; i(); + + let acronym: string = ""; + let name: string = ""; + let id: string = ""; + + if(!Array.isArray(data[2])) { + if(data[2].hasOwnProperty("legalshortname")) { + acronym = data[2].legalshortname; + } + if(data[2].hasOwnProperty("legalname")) { + name = data[2].legalname; + } + if(!acronym && !name){ + // acronym is displayed with link and name only in tooltip + acronym = "[no title available]"; + } + + if(data[2].hasOwnProperty("to")) { + id = data[2]['to'].content; + } + + this.projectInfo.organizations.push({"acronym": acronym, "name": name, "id": id}); + } else { + for(let i=0; i +
+
+ +
+ + + + +
+
+ + {{publicationInfo.types.join(", ")}} + {{publicationInfo.languages.join(", ")}} + {{publicationInfo.title.accessMode}} + + + + Record in preview + + + + + +
+ + ({{publicationInfo.date}}) +
+ +
    +
  • Publisher: {{publicationInfo.publisher}}
  • +
  • + Journal: + {{publicationInfo.journal['journal']}} + + ( + + + issn: {{publicationInfo.journal['issn']}} + + + lissn: {{publicationInfo.journal['lissn']}} + + + ) + +
  • + +
  • Embargo end date: {{publicationInfo.embargoEndDate}}
  • +
  • + +
  • +
  • + + +
  • +
+ +
+ {{publicationInfo.description}} +
+ + +
+ + +
+ + + + + + + + + + + + + + +
+
+
+ No references available +
+ +
+ + +
+ {{publicationInfo.references.length}} references, page {{referencesPage}} of {{totalPages(publicationInfo.references.length)}} + +
+ +
+

+ + {{item['name']}} + +

+

+ {{item['name']}} +

+
+ + + + + +
+
+ +
+
+ No related research results available +
+
+
+
{{provenanceaction}}
+ + +
+
+
+ + +
+
+ No similar research results available +
+
+ + +
+
+ +
+
+ No related organizations available +
+
+
+ {{publicationInfo.organizations.length}} organizations, page {{organizationsPage}} of {{totalPages(publicationInfo.organizations.length)}} + +
+ + + + + + + + + +
+ + {{organization['name']}} + ( + {{organization.shortname}} + ) + +

+ {{organization['name']}} + ( + {{organization.shortname}} + ) +

+
{{organization.country}}
+
Website url: + {{organization.websiteUrl}} +
+
+
+
{{organization['trust']}}%
+ +
+
+

no trust available

+
+
+ + +
+
+ +
+
+ {{bioentitiesNum}} bioentities, page {{bioentitiesPage}} of {{totalPages(bioentitiesNum)}} + +
+ + + + + + + + + + + + + +
+ + + {{keyIn}} + + + + {{key}} +
+
+
+
+ {{publicationInfo.software.length}} software results, page {{softwarePage}} of {{totalPages(publicationInfo.software.length)}} + +
+ + + + + + + + +
+ + + {{item.name}} + + +
+
+
+ + + + + + + + +
+ +
+
+ +
+
+ Share - Bookmark + +
+ + + + +
+
+
+
+
+
diff --git a/portal-4cli/src/app/landingPages/publication/publication.component.ts b/portal-4cli/src/app/landingPages/publication/publication.component.ts new file mode 100644 index 00000000..b44a14c6 --- /dev/null +++ b/portal-4cli/src/app/landingPages/publication/publication.component.ts @@ -0,0 +1,312 @@ +import {Component, ViewChild, ElementRef} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {PublicationService} from './publication.service'; +import {PublicationInfo} from '../../utils/entities/publicationInfo'; +import {ActivatedRoute, Router} from '@angular/router'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; +import {RouterHelper} from '../../utils/routerHelper.class'; +import {PiwikService} from '../../utils/piwik/piwik.service'; + +import { Meta} from '../../../angular2-meta'; + + + +@Component({ + selector: 'publication', + templateUrl: 'publication.component.html', + +}) + +export class PublicationComponent { + public publicationInfo: PublicationInfo; + public articleId: string; + + // APP BOX variables + public showAllCollectedFrom: boolean = false; + public showAllDownloadFrom: boolean = false; + + // Metrics tab variables + public metricsClicked: boolean; + public viewsFrameUrl: string; + public downloadsFrameUrl: string; + public totalViews: number; + public totalDownloads: number; + public pageViews: number; + + // Custom tab paging variables + public referencesPage: number = 1; + public organizationsPage: number = 1; + public softwarePage: number = 1; + public bioentitiesPage: number = 1; + public pageSize: number = 10; + /* + public startt: number = 0; + public stopp: number = 0; + */ + + // Active tab variable for responsiveness + public activeTab: string = "References"; + + // Map counting variables + public bioentitiesNum: number = 0; + public relatedResearchResultsNum: number = 0; + + // Message variables + public warningMessage = ""; + public errorMessage = ""; + public showLoading: boolean = true; + + public routerHelper:RouterHelper = new RouterHelper(); + + private doi: string; + private result; + sub: any; piwiksub: any; infoSub: any; + + constructor ( private element: ElementRef, + private _publicationService: PublicationService, + private _piwikService:PiwikService, + private route: ActivatedRoute, private _meta: Meta, + private _router: Router) { + this.updateUrl(OpenaireProperties.getBaseLink()+this._router.url); + } + + ngOnInit() { + this.sub = this.route.queryParams.subscribe(data => { + this.publicationInfo = null; + this.updateTitle("Publication"); + this.updateDescription("Publication, open access, collected from"); + + this.articleId = data['articleId']; + console.info("Article id is :"+this.articleId); + + this.metricsClicked = false; + + if(this.articleId){ + + this.getPublicationInfo(this.articleId); + // if (typeof document !== 'undefined') { + // switcher(UIkit); + // } + }else{ + this.showLoading = false; + this.warningMessage="No valid publication id"; + } + + this.viewsFrameUrl = OpenaireProperties.getFramesAPIURL()+'merge.php?com=query&data=[{"query":"resRepoViews", "resTitle":"'+this.articleId+'", "table":"","fields":[{"fld":"sum","agg":"sum","type":"column","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":"Repository","yaxisheaders":["Monthly views"],"generalxaxis":"","theme":0,"in":[],"filters":[{"name":"","values":[""],"to":"-1"}]}]&info_types=["column"]&stacking=normal&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(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'; + + this.downloadsFrameUrl = OpenaireProperties.getFramesAPIURL()+'merge.php?com=query&data=[{"query":"resRepoDownloads", "resTitle":"'+this.articleId+'", "table":"","fields":[{"fld":"sum","agg":"sum","type":"column","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":"Repository","yaxisheaders":["Monthly downloads"],"generalxaxis":"","theme":0,"in":[],"filters":[{"name":"","values":[""],"to":"-1"}]}]&info_types=["column"]&stacking=normal&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(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'; + + if (typeof document !== 'undefined') { + this.element.nativeElement.scrollIntoView(); + } + }); + } + + ngOnDestroy() { + this.sub.unsubscribe(); + if(this.piwiksub){ + this.piwiksub.unsubscribe(); + } + if(this.infoSub) { + this.infoSub.unsubscribe(); + } + } + + private getPublicationInfo(id:string) { + this.warningMessage = ''; + this.errorMessage="" + this.showLoading = true; + + this.infoSub = this._publicationService.getPublicationInfo(this.articleId).subscribe( + data => { + this.publicationInfo = data; + + // this.result = [] + // this.result = {id: id, type :"dataset", source : "openaire", title: this.publicationInfo.title,url: '', result: '', accessRights: this.publicationInfo.bestaccessright, embargoEndDate: ''}; + this.updateTitle(this.publicationInfo.title.name); + this.updateDescription("Dataset, search, repositories, open access,"+this.publicationInfo.title.name); + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.piwiksub = this._piwikService.trackView(this.publicationInfo.title.name).subscribe(); + } + + let bioentitiesNum = 0; + if(this.publicationInfo.bioentities != undefined) { + this.publicationInfo.bioentities.forEach(function (value, key, map) { + bioentitiesNum += value.size; + }); + } + this.bioentitiesNum = bioentitiesNum; + + let relatedResearchResultsNum = 0; + if(this.publicationInfo.relatedResearchResults != undefined) { + this.publicationInfo.relatedResearchResults.forEach(function (value, key, map) { + relatedResearchResultsNum += value.length; + }); + } + this.relatedResearchResultsNum = relatedResearchResultsNum; + + this.result = {id: this.articleId, type :"publication", source : "openaire", title: this.publicationInfo.title,url: '', result: '', accessRights: this.publicationInfo.title.accessMode, embargoEndDate: ''}; + // this.result.push(result_); + + if(this.publicationInfo.identifiers != undefined && this.publicationInfo.identifiers.has('doi')) { + this.doi = this.publicationInfo.identifiers.get('doi')[0]; + } + + this.showLoading = false; + + if(this.publicationInfo.references) { + this.activeTab = "References"; + } else if(this.publicationInfo.relatedResearchResults) { + this.activeTab = "Related Research Results"; + } else if(this.publicationInfo.similarResearchResults) { + this.activeTab = "Similar Research Results"; + } else if(this.publicationInfo.organizations) { + this.activeTab = "Related Organizations"; + } else if(this.publicationInfo.bioentities) { + this.activeTab = "bioentities"; + } else if(this.publicationInfo.software) { + this.activeTab = "Software"; + } else { + this.activeTab = "Metrics"; + this.metricsClicked = true; + } + console.info("activeTab is "+this.activeTab); + }, + err => { + console.log(err); + console.info("error"); + + this.errorMessage = 'No publication found'; + this.showLoading = false; + } + ); + } + + public metricsResults($event) { + this.totalViews = $event.totalViews; + this.totalDownloads = $event.totalDownloads; + this.pageViews = $event.pageViews; + } + + public buildCurationTooltip() { + let tooltipContent: string = "
"; + + tooltipContent += "

Record in preview

"; + tooltipContent += "

Bibliographic record accepted by the system, but not yet processed by
OpenAIRE tools for information quality improvement and de-duplication

"; + + return tooltipContent+= "
"; + } + + private updateDescription(description:string){ + this._meta.updateMeta("description", description); + this._meta.updateProperty("og:description", description); + } + private updateTitle(title:string){ + var _prefix ="OpenAIRE | "; + var _title = _prefix + ((title.length> 50 ) ?title.substring(0,50):title); + this._meta.setTitle(_title ); + this._meta.updateProperty("og:title",_title); + } + + private updateUrl(url:string){ + this._meta.updateProperty("og:url", url); + } + + public totalPages(totalResults: number): number { + let totalPages:any = totalResults/this.pageSize; + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, this.pageSize) + 1); + } + return totalPages; + } + + public updateReferencesPage($event) { + this.referencesPage = $event.value; + } + + public updateOrganizationsPage($event) { + this.organizationsPage = $event.value; + } + + public updateSoftwarePage($event) { + this.softwarePage = $event.value; + } + + public updateBioentitiesPage($event) { + this.bioentitiesPage = $event.value; + } + + public keysToArray(bioentities: Map) : string[] { + let keys: string[] = []; + bioentities.forEach(function (value, key, map) { + keys.push(key); + }); + return keys; + } + public getKeys( map) { + return Array.from(map.keys()); + } +/* + start(i: number, bioentitiesPage: number) { + let sum = 0; + let index=0; + let retValue = 0; + let valuesToPage = this.pageSize*bioentitiesPage; + let valuesToPreviousPage = valuesToPage - this.pageSize; + + if(bioentitiesPage == 1) { + return 0; + } + + this.publicationInfo.bioentities.forEach(function (value, key, map) { + sum += map.get(key).size; + + if(index == i) { + if(sum <= valuesToPreviousPage) { + retValue = 0; + } else if((sum-map.get(key).size) >= valuesToPage){ + retValue = 0; + } else { + if(map.get(key).size < (sum - valuesToPreviousPage)) { + retValue = 0; + } else { + retValue = map.get(key).size - (sum - valuesToPreviousPage); + } + } + } + index++; + }); + this.startt = retValue; + return retValue; + } + + stop(i: number, bioentitiesPage: number) { + let sum = 0; + let index=0; + let retValue = 0; + let valuesToPage = this.pageSize*bioentitiesPage; + let valuesToPreviousPage = valuesToPage - this.pageSize; + + this.publicationInfo.bioentities.forEach(function (value, key, map) { + sum += map.get(key).size; + if(index == i) { + if(sum <= valuesToPreviousPage) { + retValue = 0; + } else if((sum - map.get(key).size) >= valuesToPage){ + retValue = 0; + } else { + if(sum < valuesToPage) { + retValue = map.get(key).size; + } else { + retValue = map.get(key).size - (sum - valuesToPage); + } + } + } + index++; + }); + this.stopp = retValue; + return retValue; + } +*/ + +} diff --git a/portal-4cli/src/app/landingPages/publication/publication.module.ts b/portal-4cli/src/app/landingPages/publication/publication.module.ts new file mode 100644 index 00000000..cfa5337a --- /dev/null +++ b/portal-4cli/src/app/landingPages/publication/publication.module.ts @@ -0,0 +1,30 @@ +//import {MaterialModule} from '@angular/material'; +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { SharedModule } from '../../shared/shared.module'; +import { RouterModule } from '@angular/router'; + +import { PublicationService} from './publication.service'; +import { PublicationComponent } from './publication.component'; +import { PublicationRoutingModule } from './publication-routing.module'; +import {MetricsModule} from '../landing-utils/metrics.module'; +import {IFrameModule} from '../../utils/iframe.module'; +import {AltMetricsModule} from '../../utils/altmetrics.module'; +import {CiteThisModule} from '../landing-utils/citeThis/citeThis.module'; +import {PagingModule} from '../../utils/paging.module'; + +import { ResultLandingModule } from '../landing-utils/resultLanding.module'; +import { LandingModule } from '../landing-utils/landing.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, LandingModule,SharedModule, RouterModule, CiteThisModule, PagingModule, + ResultLandingModule, PublicationRoutingModule, IFrameModule, MetricsModule, AltMetricsModule], + declarations: [PublicationComponent], + providers:[PublicationService, FreeGuard, IsRouteEnabled], + exports: [PublicationComponent] +}) +export class PublicationModule { } diff --git a/portal-4cli/src/app/landingPages/publication/publication.service.ts b/portal-4cli/src/app/landingPages/publication/publication.service.ts new file mode 100644 index 00000000..bf270bc6 --- /dev/null +++ b/portal-4cli/src/app/landingPages/publication/publication.service.ts @@ -0,0 +1,357 @@ + +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {PublicationInfo} from '../../utils/entities/publicationInfo'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; + + +import { ParsingFunctions } from '../landing-utils/parsingFunctions.class'; + +@Injectable() +export class PublicationService { + + constructor(private http: Http ) { + this.parsingFunctions = new ParsingFunctions(); + } + + public parsingFunctions: ParsingFunctions; + publicationInfo: PublicationInfo; + + getPublicationInfo (id: string):any { + console.info("getPublicationInfo in service"); + let url = OpenaireProperties. getSearchAPIURLLast() + 'publications/' +id+"?format=json"; + let key = url; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => [res['result']['header']['dri:status'], res['result']['metadata']['oaf:entity']]) + .map(res => [ res[1]['oaf:result'], + res[1]['oaf:result']['title'], + res[1]['oaf:result']['rels']['rel'], + res[1]['oaf:result']['children'], + res[1]['oaf:result']['pid'], + res[1]['oaf:result']['journal'], + res[1]['oaf:result']['language'], + res[1]['oaf:result']['subject'], + res[1]['oaf:result']['bestaccessright'], + res[1]['oaf:result']['collectedfrom'], + (res[1]['extraInfo']!= undefined && res[1]['extraInfo']['citations']!= undefined)? res[1]['extraInfo']['citations']['citation']:null, + res[1]['oaf:result']['context'], + res[0], + res[1]['oaf:result']['creator'] + ]) + .map(res => this.parsePublicationInfo(res)); + } + + private handleError (error: Response) { + // in a real world app, we may send the error to some remote logging infrastructure + // instead of just logging it to the console + console.log(error); + return Observable.throw(error || 'Server error'); + } + + parsePublicationInfo (data: any):any { + this.publicationInfo = new PublicationInfo(); + + if(data[0] != null) { + var date:string = (data[0].dateofacceptance)+""; // transform to string in case it is an integer + this.publicationInfo.date = (date && (date).indexOf('-') !== -1)?date.split('-')[0]:date; + this.publicationInfo.dateofacceptance = data[0].dateofacceptance; + this.publicationInfo.publisher = data[0].publisher; + if(!Array.isArray(data[0].description)) { + this.publicationInfo.description = data[0].description; + } else { + this.publicationInfo.description = data[0].description[0]; + } + this.publicationInfo.embargoEndDate = data[0].embargoenddate; + } + + this.publicationInfo.title = {"name": "", "url": "", "accessMode": ""}; + if(data[0]['bestaccessright'].hasOwnProperty("classid")) { + this.publicationInfo.title.accessMode = data[0]['bestaccessright'].classid; + } + + if(data[1] != null) { + if(Array.isArray(data[1])) { + this.publicationInfo.title['name'] = data[1][0].content; + } else { + this.publicationInfo.title['name'] = data[1].content; + } + } + + if(data[2] != null) { + let relation; + let length = Array.isArray(data[2]) ? data[2].length : 1; + + for(let i=0; i(); + // } + // + // this.publicationInfo.authors[relation.ranking-1] = {"name": "", "id": ""}; + // this.publicationInfo.authors[relation.ranking-1]['name'] = relation.fullname; + /*} else*/ if(relation['to'].class == "isProducedBy") { + this.publicationInfo.fundedByProjects = this.parsingFunctions.parseFundingByProjects(this.publicationInfo.fundedByProjects, relation, this.publicationInfo.projectsProvenanceVocabulary); + } else if(relation['to'].class == "isRelatedTo") { + let provenanceAction: string; + if(relation.provenanceaction in this.publicationInfo.researchResultsProvenanceVocabulary) { + provenanceAction = this.publicationInfo.researchResultsProvenanceVocabulary[relation.provenanceaction]; + } else { + provenanceAction = "Other"; + } + + this.publicationInfo.relatedResearchResults = this.parsingFunctions.parseRelatedResearchResults(this.publicationInfo.relatedResearchResults, relation, provenanceAction); + } else if(relation['to'].class == "hasAmongTopNSimilarDocuments") { + this.publicationInfo.similarResearchResults = this.parsingFunctions.parseSimilarResearchResults(this.publicationInfo.similarResearchResults, relation); + } else if(relation['to'].class == "hasAuthorInstitution") { + this.publicationInfo.organizations = this.parseRelatedOrganizations(this.publicationInfo.organizations, relation); + } + } + } + } + + if(data[3] != null) { + if(data[3].hasOwnProperty("instance")) { + this.publicationInfo.downloadFrom = new Map(); + this.publicationInfo.publishedIn = new Map(); + + this.publicationInfo.types = new Array(); + let types = new Set(); + + let counter = 0; + let instance; + + let length = Array.isArray(data[3]['instance']) ? data[3]['instance'].length : 1; + + for(let i=0; i>, { "name": string, "url": string}[]] = this.parseBioentitiesAndSoftware(data[3]); + this.publicationInfo.bioentities = externalResults[0]; + this.publicationInfo.software = externalResults[1]; + } + } + + if(data[4] != null) { + this.publicationInfo.identifiers = this.parsingFunctions.parseIdentifiers(data[4]); + } + + if(data[5] != null) { + this.publicationInfo.journal = {"journal": "", "issn": "", "lissn": ""} + + this.publicationInfo.journal['journal'] = data[5].content; + this.publicationInfo.journal['issn'] = data[5].issn; + this.publicationInfo.journal['lissn'] = data[5].lissn; + } + + if(data[6] != null) { + this.publicationInfo.languages = new Array(); + + if(!Array.isArray(data[6])) { + if(data[6].classname != "Undetermined" && data[6].classname) { + this.publicationInfo.languages.push(data[6].classname); + } + } else { + for(let i=0; i, Map] = this.parsingFunctions.parseAllSubjects(data[7]); + this.publicationInfo.subjects = subjectResults[0]; + this.publicationInfo.otherSubjects = subjectResults[1]; + this.publicationInfo.classifiedSubjects = subjectResults[2]; + } + + // if(data[8] != null) { + // this.publicationInfo.bestaccessright = data[8].classid; + // } + + // if(data[9] != null) { + // this.publicationInfo.collectedFrom = this.parsingFunctions.parseCollectedFrom(data[9]); + // } + + this.publicationInfo.downloadFrom = this.parsingFunctions.addPublisherToDownloadFrom( + this.publicationInfo.downloadFrom, this.publicationInfo.publisher, + this.publicationInfo.journal, this.publicationInfo.identifiers, + this.publicationInfo.title); + + if(data[10] != null) { + this.publicationInfo.references = this.parseReferences(data[10]); + } + + if(data[11] != null) { + this.publicationInfo.contexts = this.parsingFunctions.parseContexts(data[11]); + } + + if(data[12] != null && data[12] == "under curation") { + this.publicationInfo.underCurationMessage = true; + } else { + this.publicationInfo.underCurationMessage = false; + } + + if(data[13] != null) { + if(this.publicationInfo.authors == undefined) { + this.publicationInfo.authors = new Array(); + } + + let authors = data[13]; + let length = Array.isArray(authors) ? authors.length : 1; + + for(let i=0; i(); + } + + let organization: { "name": string, "shortname": string, + "id": string, "websiteUrl": string, + "country": string, "trust": number + } = { + "name": "", "shortname": "", + "id": "", "websiteUrl": "", + "country": "", "trust": null + }; + + organization.id = relation['to'].content; + organization.name = relation.legalname; + organization.shortname = relation.legalshortname; + organization.websiteUrl = relation.websiteurl; + if(relation.country) { + organization.country = relation.country.classname; + } + if(relation.trust) { + organization.trust = Math.round(relation.trust*100); + } + + organizations.push(organization); + return organizations; + } + + parseBioentitiesAndSoftware(children: any) : [Map>, { "name": string, "url": string}[]] { + let bioentities: Map>; + let software: {"name": string, "url": string}[]; + + let length = Array.isArray(children['externalreference']) ? children['externalreference'].length : 1; + + let externalreference; + for(let i=0; i>(); + } + + if(!bioentities.has(externalreference.sitename)) { + bioentities.set(externalreference.sitename, new Map()); + } + bioentities.get(externalreference.sitename).set(externalreference.refidentifier, externalreference.url); + + } else if(externalreference['qualifier'].classid == "software") { + + if(software == undefined) { + software = new Array<{"name": string, "url": string}>(); + } + + software.push({"name": externalreference.sitename, "url": externalreference.url}); + } + } + } + + return [bioentities, software]; + } + + parseReferences(citations: any): {"name": string, "url": string}[] { + let references = new Array<{"name": string, "url": string}>(); + + let citation; + let length = Array.isArray(citations) ? citations.length : 1; + for(let i=0; i +
+
+ +
+ + + + + +
+
+ + {{softwareInfo.types.join(", ")}} + {{softwareInfo.title.accessMode}} + + + Record in preview + + + + +
+ + ({{softwareInfo.date}}) +
+ +
    +
  • Publisher: {{softwareInfo.publisher}}
  • + +
  • Embargo end date: {{softwareInfo.embargoEndDate}}
  • +
  • + +
  • +
  • + + +
  • +
+ +
+ {{softwareInfo.description}} +
+ + + + + + + + + + + +
+
+
+ No related research results available +
+
+
+
{{provenanceaction}}
+ + +
+
+
+ +
+
+ No similar research results available +
+
+ +
+
+
+ + + + + + + +
+ +
+
+ +
+
+ Share - Bookmark + +
+ + + + + +
+
+
+
+
+
diff --git a/portal-4cli/src/app/landingPages/software/software.component.ts b/portal-4cli/src/app/landingPages/software/software.component.ts new file mode 100644 index 00000000..9e2456b3 --- /dev/null +++ b/portal-4cli/src/app/landingPages/software/software.component.ts @@ -0,0 +1,172 @@ +import {Component, ViewChild, ElementRef} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {SoftwareService} from './software.service'; +import {SoftwareInfo} from '../../utils/entities/softwareInfo'; +import {ActivatedRoute, Router} from '@angular/router'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties' +import {RouterHelper} from '../../utils/routerHelper.class'; +import { Meta} from '../../../angular2-meta'; +import {PiwikService} from '../../utils/piwik/piwik.service'; + +@Component({ + selector: 'software', + templateUrl: 'software.component.html', +}) + +export class SoftwareComponent { + public softwareInfo: SoftwareInfo; + public softwareId : string ; + + // APP BOX variables + public showAllCollectedFrom: boolean = false; + public showAllDownloadFrom: boolean = false; + public showAllPublishedIn: boolean = false; + + // Metrics tab variables + public metricsClicked: boolean; + public viewsFrameUrl: string; + public downloadsFrameUrl: string; + public totalViews: number; + public totalDownloads: number; + public pageViews: number; + + // Active tab variable for responsiveness + public activeTab: string = "Related Research Results"; + + // Map counting variable + public relatedResearchResultsNum: number = 0; + + // Message variables + public warningMessage = ""; + public errorMessage = ""; + public showLoading: boolean = true; + + public routerHelper:RouterHelper = new RouterHelper(); + + private result ; + sub: any; piwiksub: any; infoSub: any; + + constructor (private element: ElementRef, + private _softwareService: SoftwareService, + private _piwikService:PiwikService, + private route: ActivatedRoute, + private _meta: Meta, + private _router: Router) { + this.updateUrl(OpenaireProperties.getBaseLink()+this._router.url); + } + + ngOnInit() { + this.sub = this.route.queryParams.subscribe(params => { + this.softwareInfo = null; + this.updateTitle("Software"); + this.updateDescription("Software, search, open access"); + + this.softwareId = params['softwareId']; + console.info("Id is :"+this.softwareId); + + if(this.softwareId){ + this.getSoftwareInfo(this.softwareId); + }else{ + this.showLoading = false; + this.warningMessage="No valid software id"; + } + + this.metricsClicked = false; + + this.viewsFrameUrl = OpenaireProperties.getFramesAPIURL()+'merge.php?com=query&data=[{"query":"resRepoViews", "resTitle":"'+this.softwareId+'", "table":"","fields":[{"fld":"sum","agg":"sum","type":"column","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":"Repository","yaxisheaders":["Monthly views"],"generalxaxis":"","theme":0,"in":[],"filters":[{"name":"","values":[""],"to":"-1"}]}]&info_types=["column"]&stacking=normal&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(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'; + /*this.viewsFrameUrl = OpenaireProperties.getFramesAPIURL()+'merge.php?com=query&data=[{"query":"resViewsTimeline", "resTitle":"'+this.softwareId+'", "table":"","fields":[{"fld":"sum","agg":"sum","type":"column","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":"Repository","yaxisheaders":["Monthly views"],"generalxaxis":"","theme":0,"in":[],"filters":[{"name":"","values":[""],"to":"-1"}]}]&info_types=["column"]&stacking=normal&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'; + */ + + this.downloadsFrameUrl = OpenaireProperties.getFramesAPIURL()+'merge.php?com=query&data=[{"query":"resRepoDownloads", "resTitle":"'+this.softwareId+'", "table":"","fields":[{"fld":"sum","agg":"sum","type":"column","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":"Repository","yaxisheaders":["Monthly downloads"],"generalxaxis":"","theme":0,"in":[],"filters":[{"name":"","values":[""],"to":"-1"}]}]&info_types=["column"]&stacking=normal&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(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'; + /*this.downloadsFrameUrl = OpenaireProperties.getFramesAPIURL()+'merge.php?com=query&data=[{"query":"resRepoDownloadTimeline", "resTitle":"'+this.softwareId+'", "table":"","fields":[{"fld":"sum","agg":"sum","type":"column","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":"Repository","yaxisheaders":["Monthly downloads"],"generalxaxis":"","theme":0,"in":[],"filters":[{"name":"","values":[""],"to":"-1"}]}]&info_types=["column"]&stacking=normal&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(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'; + */ + if (typeof document !== 'undefined') { + this.element.nativeElement.scrollIntoView(); + } + }); + + } + + ngOnDestroy() { + this.sub.unsubscribe(); + if(this.piwiksub){ + this.piwiksub.unsubscribe(); + } + if(this.infoSub) { + this.infoSub.unsubscribe(); + } + } + + private getSoftwareInfo(id:string) { + this.warningMessage = ''; + this.errorMessage="" + this.showLoading = true; + + this.infoSub = this._softwareService.getSoftwareInfo(id).subscribe( + data => { + this.softwareInfo = data; + this.updateTitle(this.softwareInfo.title.name); + this.updateDescription("Software, search, repositories, open access,"+this.softwareInfo.title.name); + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.piwiksub = this._piwikService.trackView(this.softwareInfo.title.name).subscribe(); + } + + this.result = [] + this.result = {id: id, type :"software", source : "openaire", title: this.softwareInfo.title,url: '', result: '', accessRights: this.softwareInfo.title.accessMode, embargoEndDate: ''}; + + let relatedResearchResultsNum = 0; + if(this.softwareInfo.relatedResearchResults != undefined) { + this.softwareInfo.relatedResearchResults.forEach(function (value, key, map) { + relatedResearchResultsNum += value.length; + }); + } + this.relatedResearchResultsNum = relatedResearchResultsNum; + + this.showLoading = false; + }, + err => { + console.log(err) + console.info("error"); + + this.errorMessage = 'No software found'; + this.showLoading = false; + } + ); + } + + // showChange($event) { + // this.showAllReferences=$event.value; + // } + + public metricsResults($event) { + this.totalViews = $event.totalViews; + this.totalDownloads = $event.totalDownloads; + this.pageViews = $event.pageViews; + } + + private updateDescription(description:string){ + this._meta.updateMeta("description", description); + this._meta.updateProperty("og:description", description); + } + private updateTitle(title:string){ + var _prefix ="OpenAIRE | "; + var _title = _prefix + ((title.length> 50 ) ?title.substring(0,50):title); + this._meta.setTitle(_title ); + this._meta.updateProperty("og:title",_title); + } + private updateUrl(url:string){ + this._meta.updateProperty("og:url", url); + } + + public buildCurationTooltip() { + let tooltipContent: string = "
"; + + tooltipContent += "

Record in preview

"; + tooltipContent += "

Bibliographic record accepted by the system, but not yet processed by
OpenAIRE tools for information quality improvement and de-duplication

"; + + return tooltipContent; + } + public getKeys( map) { + return Array.from(map.keys()); + } +} diff --git a/portal-4cli/src/app/landingPages/software/software.module.ts b/portal-4cli/src/app/landingPages/software/software.module.ts new file mode 100644 index 00000000..572909d3 --- /dev/null +++ b/portal-4cli/src/app/landingPages/software/software.module.ts @@ -0,0 +1,36 @@ +//import {MaterialModule} from '@angular/material'; +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import { RouterModule } from '@angular/router'; + +import { SoftwareService } from './software.service'; +import { SoftwareComponent } from './software.component'; +import { SoftwareRoutingModule } from './software-routing.module'; +import { MetricsModule } from '../landing-utils/metrics.module'; +import { IFrameModule } from '../../utils/iframe.module'; +import { AltMetricsModule } from '../../utils/altmetrics.module'; +import { CiteThisModule } from '../landing-utils/citeThis/citeThis.module'; +import { PagingModule } from '../../utils/paging.module'; + +import { ResultLandingModule } from '../landing-utils/resultLanding.module'; +import { LandingModule } from '../landing-utils/landing.module'; +import { FreeGuard } from'../../login/freeGuard.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, LandingModule, RouterModule, CiteThisModule, PagingModule, + ResultLandingModule, SoftwareRoutingModule, IFrameModule, MetricsModule, AltMetricsModule + ], + declarations: [ + SoftwareComponent + ], + providers:[ + SoftwareService, FreeGuard + ], + exports: [ + SoftwareComponent + ] +}) +export class SoftwareModule { } diff --git a/portal-4cli/src/app/landingPages/software/software.service.ts b/portal-4cli/src/app/landingPages/software/software.service.ts new file mode 100644 index 00000000..118a92cd --- /dev/null +++ b/portal-4cli/src/app/landingPages/software/software.service.ts @@ -0,0 +1,220 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {SoftwareInfo} from '../../utils/entities/softwareInfo'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; + +import { ParsingFunctions } from '../landing-utils/parsingFunctions.class'; + +@Injectable() +export class SoftwareService { + + constructor(private http: Http ) { + this.parsingFunctions = new ParsingFunctions(); + } + + public parsingFunctions: ParsingFunctions; + softwareInfo: SoftwareInfo; + + getSoftwareInfo (id: string):any { + console.info("getSoftwareInfo in service"); + + let url = OpenaireProperties. getSearchAPIURLLast()+'software/'+id+"?format=json"; + let key = url; + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .do(res => console.info(res['result']['metadata']['oaf:entity'])) + .map(res => [res['result']['header']['dri:status'], res['result']['metadata']['oaf:entity']['oaf:result']]) + .map(res => [res[1], + res[1]['title'], + res[1]['rels']['rel'], + res[1]['children'], + res[1]['pid'], + res[1]['subject'], + res[1]['bestaccessright'], + res[1]['collectedfrom'], + res[1]['context'], + //res[1]['resulttype'], + res[0], + res[1]['creator'] + ]).map(res => this.parseSoftwareInfo(res)); + } + + private handleError (error: Response) { + // in a real world app, we may send the error to some remote logging infrastructure + // instead of just logging it to the console + console.log(error); + return Observable.throw(error || 'Server error'); + } + + parseSoftwareInfo (data: any):any { + this.softwareInfo = new SoftwareInfo(); + + if(data[0] != null) { + var date:string = (data[0].dateofacceptance)+""; // transform to string in case it is an integer + this.softwareInfo.date = (date && (date).indexOf('-') !== -1)?date.split('-')[0]:date; + this.softwareInfo.dateofacceptance = data[0].dateofacceptance; + this.softwareInfo.publisher = data[0].publisher; + if(!Array.isArray(data[0].description)) { + this.softwareInfo.description = data[0].description; + } else { + this.softwareInfo.description = data[0].description[0]; + } + this.softwareInfo.embargoEndDate = data[0].embargoenddate; + } + this.softwareInfo.title = {"name": "", "url": "", "accessMode": ""}; + if(data[0]['bestaccessright'].hasOwnProperty("classid")) { + this.softwareInfo.title.accessMode = data[0]['bestaccessright'].classid; + } + if(data[1] != null) { + if(Array.isArray(data[1])) { + this.softwareInfo.title['name'] = data[1][0].content; + } else { + this.softwareInfo.title['name'] = data[1].content; + } + } + + if(data[2] != null) { + let relation; + let length = data[2].length!=undefined ? data[2].length : 1; + + for(let i=0; i(); + this.softwareInfo.publishedIn = new Map() + + this.softwareInfo.types = new Array(); + let types = new Set(); + + let counter = 0; + let instance; + + let length = data[3]['instance'].length!=undefined ? data[3]['instance'].length : 1; + + for(let i=0; i, Map] = this.parsingFunctions.parseAllSubjects(data[5]); + this.softwareInfo.subjects = subjectResults[0]; + this.softwareInfo.otherSubjects = subjectResults[1]; + this.softwareInfo.classifiedSubjects = subjectResults[2]; + } + + // if(data[6] != null) { + // this.softwareInfo.bestaccessright = data[6].classid; + // } + + // if(data[7] != null) { + // this.softwareInfo.collectedFrom = this.parsingFunctions.parseCollectedFrom(data[7]); + // } + + // null argument is for journal + this.softwareInfo.downloadFrom = this.parsingFunctions.addPublisherToDownloadFrom( + this.softwareInfo.downloadFrom, this.softwareInfo.publisher, + null, this.softwareInfo.identifiers, this.softwareInfo.title); + + if(data[8] != null) { + this.softwareInfo.contexts = this.parsingFunctions.parseContexts(data[8]); + } + + // if(data[9] != null && this.softwareInfo.type == undefined) { + // if(data[9].hasOwnProperty('classname')) { + // this.softwareInfo.type = data[9].classname; + // } + // } + + if(data[9] != null && data[9] == "under curation") { + this.softwareInfo.underCurationMessage = true; + } else { + this.softwareInfo.underCurationMessage = false; + } + + if(data[10] != null) { + if(this.softwareInfo.authors == undefined) { + this.softwareInfo.authors = new Array(); + } + + let authors = data[10]; + let length = Array.isArray(authors) ? authors.length : 1; + + for(let i=0; i | boolean { + var user; + var loggedIn = false; + var isAdmin = false; + var errorCode = ErrorCodes.NOT_LOGGIN; + + if(Session.isLoggedIn()){ + loggedIn = true; + if(!Session.isValidAndRemove()){ + loggedIn = false; + errorCode = ErrorCodes.NOT_VALID; + }else { + isAdmin = Session.isAdminUser(); + if(!isAdmin){ + errorCode = ErrorCodes.NOT_ADMIN; + } + } + }else{ + errorCode =ErrorCodes.NOT_LOGGIN; + } + + if(!loggedIn){ + // this.guardHelper.redirect("/user-info",errorCode,state.url); + this.router.navigate(['/user-info'], { queryParams: { "errorCode": errorCode, "redirectUrl": state.url } }); + + return false; + }else if(!isAdmin){ + // this.guardHelper.redirect("/user-info",errorCode,state.url); + this.router.navigate(['/user-info'], { queryParams: { "errorCode": errorCode, "redirectUrl": state.url } }); + return false; + }else{ + return true; + } + } +} diff --git a/portal-4cli/src/app/login/freeGuard.guard.ts b/portal-4cli/src/app/login/freeGuard.guard.ts new file mode 100644 index 00000000..316ff266 --- /dev/null +++ b/portal-4cli/src/app/login/freeGuard.guard.ts @@ -0,0 +1,36 @@ +import { Injectable } from '@angular/core'; +import { Router,CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router'; +import {Observable} from 'rxjs/Observable'; +import {Session} from './utils/helper.class'; +import {ErrorCodes} from './utils/guardHelper.class'; + +@Injectable() +export class FreeGuard implements CanActivate { + + constructor(private router: Router) {} + + canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | boolean { + var user; + var valid = true; + var loggedIn = false; + var errorCode = ErrorCodes.NOT_LOGGIN; + + if(Session.isLoggedIn()){ + loggedIn = true; + if(!Session.isValidAndRemove()){ + loggedIn = false; + valid = false; + errorCode = ErrorCodes.NOT_VALID; + } + } + + if(!valid){ + // this.guardHelper.redirect("/user-info",errorCode,state.url); + + this.router.navigate(['/user-info'], { queryParams: { "errorCode": errorCode, "redirectUrl": state.url } }); + return false; + } + return true; + + } +} diff --git a/portal-4cli/src/app/login/loginGuard.guard.ts b/portal-4cli/src/app/login/loginGuard.guard.ts new file mode 100644 index 00000000..59999519 --- /dev/null +++ b/portal-4cli/src/app/login/loginGuard.guard.ts @@ -0,0 +1,33 @@ +import { Injectable } from '@angular/core'; +import { Router,CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router'; +import {Observable} from 'rxjs/Observable'; +import {Session} from './utils/helper.class'; +import {ErrorCodes} from './utils/guardHelper.class'; + +@Injectable() +export class LoginGuard implements CanActivate { + + constructor(private router: Router) {} + + canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | boolean { + var user; + var loggedIn = false; + var errorCode = ErrorCodes.NOT_LOGGIN; + if(Session.isLoggedIn()){ + loggedIn = true; + if(!Session.isValidAndRemove()){ + loggedIn = false; + errorCode = ErrorCodes.NOT_VALID; + } + }else{ + errorCode = ErrorCodes.NOT_LOGGIN; + } + if(!loggedIn){ + // this.guardHelper.redirect("/user-info",errorCode,state.url); + this.router.navigate(['/user-info'], { queryParams: { "errorCode": errorCode, "redirectUrl": state.url } }); + return false; + }else{ + return true; + } + } +} diff --git a/portal-4cli/src/app/login/user-routing.module.ts b/portal-4cli/src/app/login/user-routing.module.ts new file mode 100644 index 00000000..6bbadb82 --- /dev/null +++ b/portal-4cli/src/app/login/user-routing.module.ts @@ -0,0 +1,15 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { UserComponent } from './user.component'; +import {PreviousRouteRecorder} from '../utils/piwik/previousRouteRecorder.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: UserComponent, canDeactivate: [PreviousRouteRecorder]}, + + ]) + ] +}) +export class UserRoutingModule { } diff --git a/portal-4cli/src/app/login/user.component.html b/portal-4cli/src/app/login/user.component.html new file mode 100644 index 00000000..fc699009 --- /dev/null +++ b/portal-4cli/src/app/login/user.component.html @@ -0,0 +1,54 @@ + +
+
+
+ +
+ + + +
+ The requested page requires authentication. Please sign in. + + Sign in + +
+
+ You are not authorized to use the requested page +
+
+ The session has expired. Please sign in again or continue browsing as a guest. + + Sign in + +
+
{{errorMessage}}
+ +
+
+ Hello {{user.fullname}}! +
+ +
+
+
+
+
diff --git a/portal-4cli/src/app/login/user.component.ts b/portal-4cli/src/app/login/user.component.ts new file mode 100644 index 00000000..2babc40e --- /dev/null +++ b/portal-4cli/src/app/login/user.component.ts @@ -0,0 +1,119 @@ +import {Component, ElementRef} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {ActivatedRoute, Router} from '@angular/router'; + +// import {LoginService} from './login.service'; +import {User,Session} from './utils/helper.class'; +import {RouterHelper} from '../utils/routerHelper.class'; +import { Meta} from '../../angular2-meta'; +import {OpenaireProperties} from '../utils/properties/openaireProperties'; + +@Component({ + selector: 'user', + templateUrl: 'user.component.html' + }) + +export class UserComponent { + public user: User; + public loggedIn: boolean = false; + public server: boolean = true; + public errorMessage: string; + public username: string = ""; + public password: string = ""; + private sub:any;private sublogin:any; + public errorCode: string = ""; + public redirectUrl: string = ""; + public routerHelper:RouterHelper = new RouterHelper(); + public loginUrl= OpenaireProperties.getLoginURL(); + + constructor( private router: Router, + private route: ActivatedRoute, private _meta: Meta ) { + this._meta.setTitle("OpenAIRE | Login"); + } + + ngOnInit() { + if( typeof document !== 'undefined') { + this.server = false; + } + this.loggedIn = Session.isLoggedIn(); + this.user = Session.getUser(); + this.errorMessage = ""; + this.sub = this.route.queryParams.subscribe(params => { + this.errorCode = params["errorCode"]; + this.redirectUrl = params["redirectUrl"]; + this.loggedIn = Session.isLoggedIn(); + this.user = Session.getUser(); + this.errorMessage = ""; + if(this.loggedIn){ + this.redirect(); + } + }); + } + ngOnDestroy(){ + this.sub.unsubscribe(); + if(this.sublogin){ + this.sublogin.unsubscribe(); + } + } + logout(){ + if(Session.isLoggedIn()){ + Session.removeUser(); + } + this.loggedIn = false; + this.user = new User(); + this.username = ""; + this.password = ""; + this.redirect(); + + } + redirect(){ + if(this.redirectUrl && this.redirectUrl != null && this.redirectUrl != ""){ + this.redirectUrl = decodeURIComponent(this.redirectUrl); + var baseUrl = this.redirectUrl; + var queryParams = ""; + var paramsArray =[]; + var valuesArray =[]; + if(this.redirectUrl.indexOf('?') != -1){ + baseUrl = this.redirectUrl.split('?')[0]; + queryParams = this.redirectUrl.split('?')[1]; + } + if(queryParams != ""){ + var queryParamsArray = queryParams.split('&'); + for(var i = 0; i < queryParamsArray.length; i++){ + paramsArray.push(queryParamsArray[i].split("=")[0]); + valuesArray.push(queryParamsArray[i].split("=")[1]); + } + this.router.navigate([baseUrl], { queryParams: this.routerHelper.createQueryParams(paramsArray,valuesArray)}); + }else{ + this.router.navigate([baseUrl]); + } + }else{ + this.router.navigate(['/']); + } + } + // login() { + // this.sublogin =this._loginService.authenticate(/*this.user*/this.username, this.password).subscribe( + // data => { + // this.user = data; + // this.loggedIn = true; + // this.username = ""; + // this.password = ""; + // this.errorCode = ""; + // this.redirect(); + // + // }, + // err => { + // console.log(err); + // if(err.status == "404") { + // this.errorMessage = "Wrong username"; + // } else if(err.status == "401") { + // this.errorMessage = "Wrong password"; + // } + // this.username = ""; + // this.password = ""; + // this.errorCode = ""; + // + // } + // ); + // } +} diff --git a/portal-4cli/src/app/login/user.module.ts b/portal-4cli/src/app/login/user.module.ts new file mode 100644 index 00000000..f306984c --- /dev/null +++ b/portal-4cli/src/app/login/user.module.ts @@ -0,0 +1,22 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {UserComponent } from './user.component'; +import { UserRoutingModule } from './user-routing.module'; +import {PreviousRouteRecorder} from '../utils/piwik/previousRouteRecorder.guard'; + +// import {LoginService} from './login.service'; +@NgModule({ + imports: [ + CommonModule, FormsModule, + UserRoutingModule + + ], + providers:[PreviousRouteRecorder], + declarations: [ +UserComponent + +] +}) +export class UserModule { } diff --git a/portal-4cli/src/app/login/userMini.component.ts b/portal-4cli/src/app/login/userMini.component.ts new file mode 100644 index 00000000..9a122516 --- /dev/null +++ b/portal-4cli/src/app/login/userMini.component.ts @@ -0,0 +1,140 @@ +import {Component, ElementRef, Input} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {ActivatedRoute, Router} from '@angular/router'; +import {Location} from '@angular/common'; +// import {LoginService} from './login.service'; +import {User,Session} from './utils/helper.class'; +import {RouterHelper} from '../utils/routerHelper.class'; +import {OpenaireProperties} from '../utils/properties/openaireProperties'; +import {StringUtils} from '../utils/string-utils.class'; + +@Component({ + selector: 'user-mini', + template: ` + + +
  • + + + {{user.fullname+" "}} + + + Sign in | Register + + + + +
  • + + ` +}) + +export class UserMiniComponent { + public user: User; + public loggedIn: boolean = false; + public isAuthorized: boolean = false; + @Input() public mobileView:boolean = false ; + public server: boolean = true; + public routerHelper:RouterHelper = new RouterHelper(); + + public redirectUrl: string = ""; + private baseUrl = "user-info"; + sub:any; + constructor( private router: Router, private route: ActivatedRoute, private location: Location) {} + + ngOnInit() { + if( typeof document !== 'undefined') { + this.server = false; + } + this.initialize(); + this.sub = this.route.queryParams.subscribe(params => { + this.initialize(); + }); + } + ngOnDestroy(){ + this.sub.unsubscribe(); + } + initialize(){ + this.redirectUrl = this.location.path(); + if(Session.isLoggedIn()){ + if(Session.isUserValid()){ + this.loggedIn = Session.isLoggedIn(); + this.user = Session.getUser(); + if(Session.isAdminUser()){ + this.isAuthorized = true; + }else { + this.isAuthorized = false; + } + + }else{ + Session.removeUser(); + this.loggedIn = false; + this.isAuthorized = false; + this.user = null; + } + }else { + this.loggedIn = false; + this.isAuthorized = false; + this.user = null; + } + + } + gotoUserPage(){ + this.redirectUrl = this.location.path(); + if(this.redirectUrl && this.redirectUrl != null && this.redirectUrl != "" && this.redirectUrl !="user-info"){ + this.router.navigate([this.baseUrl], { queryParams: this.routerHelper.createQueryParam("redirectUrl",this.redirectUrl )}); + }else{ + this.router.navigate([this.baseUrl]); + } + } + logOut(){ + if(Session.isLoggedIn()){ + Session.removeUser(); + console.log("Redirect to "+location.href); + window.location.href = OpenaireProperties.getLogoutURL()+ StringUtils.URIEncode(location.href); + + } + this.loggedIn = false; + this.isAuthorized = false; + this.user = new User(); + } + + logIn(){ + Session.setCurrentUrl(location.pathname); + Session.setCurrentParameters(location.search); + window.location.href = OpenaireProperties.getLoginURL(); + } + + onClick(id: string) { + var el: HTMLElement = document.getElementById(id); + el.classList.remove('uk-open'); + } + +} diff --git a/portal-4cli/src/app/login/utils/guardHelper.class.ts b/portal-4cli/src/app/login/utils/guardHelper.class.ts new file mode 100644 index 00000000..2bee44e6 --- /dev/null +++ b/portal-4cli/src/app/login/utils/guardHelper.class.ts @@ -0,0 +1,19 @@ + +import { Router} from '@angular/router'; + +// export class GuardHelper{ +// constructor(private router: Router) {} +// +// redirect(url:string, errorCode:number, redirectUrl:string){ +// this.router.navigate([url], { queryParams: { "errorCode": errorCode, "redirectUrl": redirectUrl } }); +// +// } +// +// } +export class ErrorCodes { + public static NOT_LOGGIN:number =1; + public static NOT_ADMIN:number =2; + public static NOT_VALID:number =3; + +} + diff --git a/portal-4cli/src/app/login/utils/helper.class.ts b/portal-4cli/src/app/login/utils/helper.class.ts new file mode 100644 index 00000000..779d78f3 --- /dev/null +++ b/portal-4cli/src/app/login/utils/helper.class.ts @@ -0,0 +1,253 @@ +import {StringUtils} from '../../utils/string-utils.class'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; + + +export class User { + email:string; + firstname: string; + lastname: string; + id: string; + fullname: string; + expirationDate: number; + role:string[]; + jwt:string; + +} + +export class Session{ + // public static setUser(user:User): User { + // + // localStorage.setItem("user", JSON.stringify(user)); + // + // return user; + // } + public static removeUser() { + if(Session.isLoggedIn()){ + localStorage.removeItem("user"); + COOKIE.deleteCookie(COOKIE.cookieName_id) + } + } + public static getUser():User { + if(Session.isLoggedIn()){ + return JSON.parse(localStorage.getItem("user")); + }else{ + return null; + } + } + public static isLoggedIn(): boolean { + var loggedIn:boolean = false; + var user:User = null; + var cookie= COOKIE.getCookie(COOKIE.cookieName_u); + if( typeof localStorage !== 'undefined') { + if(localStorage.getItem("user")) { + user = JSON.parse(localStorage.getItem("user")); + if(user && (user.fullname != null || user.lastname !=null || user.firstname !=null)){ + + loggedIn = true; + }else if(cookie != null && this.getUserFromCookie()!= null){ + loggedIn = true + }else{ + loggedIn = false; + } + }else{ + if(cookie != null && this.getUserFromCookie()!= null){ + loggedIn = true + }else{ + loggedIn = false; + } + + } + }else{ + loggedIn = false; + } + return loggedIn; + } + public static getUserFromCookie():User{ + var cookie= COOKIE.getCookie(COOKIE.cookieName_u); + if(cookie != null){ + var user:User = MyJWT.parseUserInfo(cookie); + if( typeof localStorage !== 'undefined') { + localStorage.setItem("user", JSON.stringify(user)); + if(user && user.email && Session.isRegisteredUser()){ + COOKIE.deleteCookie(COOKIE.cookieName_u); // delete cookie to avoid transfer through requests + return user; + }else{ + return null; + } + }else{ + return null; + } + }else{ + return null; + } + } + public static getUserJwt():string { + if(Session.isLoggedIn()){ + return Session.getUser().jwt; + }else{ + return null; + } + + } + public static getUserEmail():string { + if(Session.isLoggedIn()){ + return Session.getUser().email; + }else{ + return null; + } + + } + public static getCurrentUrl():string { + if( typeof localStorage !== 'undefined') { + return localStorage.getItem("url"); + } + return ""; + + } + public static setCurrentUrl(url:string) { + if( typeof localStorage !== 'undefined') { + localStorage.setItem("url", url); + } + } + public static getCurrentParameters():any { + if( typeof localStorage !== 'undefined') { + var params = localStorage.getItem("params"); + var object = null; + if(params.split("&").length > 0){ + object = {}; + } + for(var i=0; i 1)? params.substring(1):""); + } + } + public static isAdminUser():boolean { + var isAdmin = false; + if(Session.isLoggedIn()){ + var claimRoles = ["urn:mace:openminted.eu:aai.openminted.eu:group:OpenAIRE+Curator+-+Claim","urn:mace:openminted.eu:aai.openminted.eu:group:OpenAIRE+Portal+Administrator"] + console.log(Session.getUser().role); + for (var i = 0; i < claimRoles.length; i++) { + if ((Session.getUser().role).indexOf(claimRoles[i]) > -1) { + isAdmin = true; + break; + } + } + // console.log("Is admin:"+ isAdmin) + return (isAdmin); + } + // console.log("Is admin:"+ isAdmin) + return (isAdmin); + } + public static isRegisteredUser():boolean { + var isRegisteredUser = false; + if(Session.isLoggedIn()){ + var claimRoles = ["urn:mace:openminted.eu:aai.openminted.eu:group:Registered+User"]; + for (var i = 0; i < claimRoles.length; i++) { + console.log(Session.getUser().role); + if ((Session.getUser().role).indexOf(claimRoles[i]) > -1) { + isRegisteredUser = true; + break; + } + } + // console.log("Is isRegisteredUser:"+ isRegisteredUser) + return (isRegisteredUser); + } + // console.log("Is isRegisteredUser:"+ isRegisteredUser) + return (isRegisteredUser); + } + public static isUserValid() { + if(Session.isLoggedIn()){ + var expires = Session.getUser().expirationDate; + var now = new Date().getTime() / 1000; + // console.log(" is still valid ? "+(now +0 < expires) +" Remaining:"+ (expires - (now+0))+ " now is:"+now + "expires at:"+expires); + return now +0 < expires; + } + return false; + } + public static isValidAndRemove() { + if(Session.isLoggedIn()){ + if(!Session.isUserValid()){ + Session.removeUser(); + return false; + }else{ + return true; + } + }else{ + return false; + } + } + +} +export class MyJWT{ + private static validateJWTFormat(data){ + if(data != null && (data.indexOf(".") !=-1 && data.split('.').length == 3)){ + return true; + } + return false; + } + private static getPayload(data){ + var payload = data.split('.')[1]; + return StringUtils.b64DecodeUnicode(payload); + } + public static parseUserInfo(data: any): User { + if(this.validateJWTFormat(data)){ + var info = JSON.parse(this.getPayload(data)); + }else{ + return null; + } + var user: User = new User(); + + user.firstname = (StringUtils.URIDecode(info.firstname)).replace("+"," "); + user.lastname = (StringUtils.URIDecode(info.lastname)).replace("+"," "); + user.email = info.email; + // user.id = info.userId; + user.fullname = (StringUtils.URIDecode(info.fullname)).replace("+"," "); + user.role =JSON.parse( StringUtils.URIDecode(info.role)); + // console.log("User Role is:"); + // console.log(user.role) + user.jwt = data; + user.expirationDate = info.exp; + localStorage.setItem("user", JSON.stringify(user)); + return user; + } + +} + export class COOKIE{ + public static cookieName_u:string="XCsrfToken"; + public static cookieName_id:string="AccessToken"; + + public static getCookie(name: string) : string { + if(typeof document == 'undefined'){ + return null; + } + let ca: Array = document.cookie.split(';'); + let caLen: number = ca.length; + let cookieName = `${name}=`; + let c: string; + + 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; + } + public static deleteCookie(name) { + this.setCookie(name, '', -1); + } + public static 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+'; path='+path+'; domain='+OpenaireProperties.getCookieDomain()+';'; + } +} diff --git a/portal-4cli/src/app/reload/reload-routing.module.ts b/portal-4cli/src/app/reload/reload-routing.module.ts new file mode 100644 index 00000000..f304da05 --- /dev/null +++ b/portal-4cli/src/app/reload/reload-routing.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import{ReloadComponent} from './reload.component'; +import {FreeGuard} from'../login/freeGuard.guard'; +import {PreviousRouteRecorder} from '../utils/piwik/previousRouteRecorder.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: ReloadComponent, canActivate: [FreeGuard], canDeactivate: [PreviousRouteRecorder] } + + ]) + ] +}) +export class ReloadRoutingModule { } diff --git a/portal-4cli/src/app/reload/reload.component.ts b/portal-4cli/src/app/reload/reload.component.ts new file mode 100644 index 00000000..eac98f96 --- /dev/null +++ b/portal-4cli/src/app/reload/reload.component.ts @@ -0,0 +1,53 @@ +import {Component, Input, Output, EventEmitter, ViewChild} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {ActivatedRoute, Router} from '@angular/router'; +import {Location} from '@angular/common'; + +import {OpenaireProperties} from '../utils/properties/openaireProperties'; +import {ErrorCodes} from '../utils/properties/openaireProperties'; +import {RouterHelper} from '../utils/routerHelper.class'; +import {Session} from '../login/utils/helper.class'; + +@Component({ + selector: 'reload', + template: ` +
    +
    +
    +
    + Go to initial page.... +
    +
    +
    +
    + ` +}) +export class ReloadComponent { + + constructor ( + private route: ActivatedRoute, + private _router: Router, + private location: Location + ) { + + } + + public ngOnInit() { + + var url = Session.getCurrentUrl(); + if(url && url != null && url != ""){ + Session.setCurrentUrl(""); + var paramsObject = Session.getCurrentParameters(); + Session.setCurrentParameters(""); + if(paramsObject && paramsObject != null){ + this._router.navigate([url],{ queryParams: paramsObject}); + }else{ + this._router.navigate([url]); + } + }else{ + this._router.navigate(['/']); + + } + } + +} diff --git a/portal-4cli/src/app/reload/reload.module.ts b/portal-4cli/src/app/reload/reload.module.ts new file mode 100644 index 00000000..2b7e8469 --- /dev/null +++ b/portal-4cli/src/app/reload/reload.module.ts @@ -0,0 +1,29 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import{ReloadRoutingModule } from './reload-routing.module'; +import{ReloadComponent} from './reload.component'; + + + import {FreeGuard} from'../login/freeGuard.guard'; +import {PreviousRouteRecorder} from '../utils/piwik/previousRouteRecorder.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, RouterModule, + ReloadRoutingModule + + ], + declarations: [ + ReloadComponent + ], + providers:[ + FreeGuard, PreviousRouteRecorder + ], + exports: [ + ReloadComponent + ] +}) +export class ReloadModule { } diff --git a/portal-4cli/src/app/searchPages/advanced/advancedSearchDataProviders-routing.module.ts b/portal-4cli/src/app/searchPages/advanced/advancedSearchDataProviders-routing.module.ts new file mode 100644 index 00000000..1225ed7a --- /dev/null +++ b/portal-4cli/src/app/searchPages/advanced/advancedSearchDataProviders-routing.module.ts @@ -0,0 +1,18 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import{AdvancedSearchDataProvidersComponent} from './advancedSearchDataProviders.component'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: AdvancedSearchDataProvidersComponent, canActivate: [FreeGuard, IsRouteEnabled], data: { + redirect: '/error' + }, canDeactivate: [PreviousRouteRecorder] } + + ]) + ] +}) +export class AdvancedSearchDataProvidersRoutingModule { } diff --git a/portal-4cli/src/app/searchPages/advanced/advancedSearchDataProviders.component.ts b/portal-4cli/src/app/searchPages/advanced/advancedSearchDataProviders.component.ts new file mode 100644 index 00000000..85f620eb --- /dev/null +++ b/portal-4cli/src/app/searchPages/advanced/advancedSearchDataProviders.component.ts @@ -0,0 +1,153 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import { Router, ActivatedRoute} from '@angular/router'; +import {Filter, Value,AdvancedField} from '../searchUtils/searchHelperClasses.class'; +import {SearchDataprovidersService} from '../../services/searchDataproviders.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {AdvancedSearchPageComponent} from '../searchUtils/advancedSearchPage.component'; +import {SearchFields} from '../../utils/properties/searchFields'; +import {SearchUtilsClass } from '../searchUtils/searchUtils.class'; + + + +@Component({ + selector: 'advanced-search-dataprovider', + template: ` + + + + ` + }) + +export class AdvancedSearchDataProvidersComponent { + private errorCodes: ErrorCodes; + + public results =[]; + public filters =[]; + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public searchFields:SearchFields = new SearchFields(); + + public fieldIds: string[] = this.searchFields.DATASOURCE_ADVANCED_FIELDS; + public fieldIdsMap= this.searchFields.DATASOURCE_FIELDS; + public selectedFields:AdvancedField[] = []; + + @ViewChild (AdvancedSearchPageComponent) searchPage : AdvancedSearchPageComponent ; + public resourcesQuery = "(oaftype exact datasource)"; + public csvParams: string; + public disableForms: boolean = false; + public loadPaging: boolean = true; + public oldTotalResults: number = 0; + + constructor (private route: ActivatedRoute, private _searchDataProvidersService: SearchDataprovidersService ) { + this.results =[]; + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.searchUtils.baseUrl = OpenaireProperties.searchLinkToAdvancedDataProviders; + console.info("Con -base url:"+this.searchUtils.baseUrl ); + + } + ngOnInit() { + this.sub = this.route.queryParams.subscribe(params => { + if(params['page'] && this.searchUtils.page != params['page']) { + this.loadPaging = false; + this.oldTotalResults = this.searchUtils.totalResults; + } + + let page = (params['page']=== undefined)?0:+params['page']; + this.searchUtils.page = ( page < 1 ) ? 1 : page; + this.searchPage.fieldIds = this.fieldIds; + this.selectedFields =[]; + this.searchPage.selectedFields = this.selectedFields; + this.searchPage.fieldIdsMap = this.fieldIdsMap; + this.searchPage.getSelectedFiltersFromUrl(params); + this.getResults(this.searchPage.createQueryParameters(), this.searchUtils.page, this.searchUtils.size); + }); + } + ngOnDestroy() { + this.sub.unsubscribe(); + } + sub: any; + public getResults(parameters:string, page: number, size: number){ + if(parameters!= null && parameters != '' ) { + this.csvParams ="&type=datasources&query=( "+this.resourcesQuery + "and (" + parameters + "))"; + }else{ + this.csvParams ="&type=datasources&query="+this.resourcesQuery; + } + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + //this.searchPage.openLoading(); + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + console.info("Advanced Search for Content Providers: Execute search query "+parameters); + this._searchDataProvidersService.advancedSearchDataproviders(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("Adv Search Content Providers total="+this.searchUtils.totalResults); + this.results = data[1]; + this.searchPage.updateBaseUrlWithParameters(); + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + //this.searchPage.closeLoading(); + this.disableForms = false; + + if(this.searchUtils.status == this.errorCodes.DONE) { + // Page out of limit + let totalPages:any = this.searchUtils.totalResults/(this.searchUtils.size); + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, 10) + 1); + } + if(totalPages < page) { + this.searchUtils.totalResults = 0; + this.searchUtils.status = this.errorCodes.OUT_OF_BOUND; + } + } + }, + err => { + console.log(err); + console.info("error"); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = errorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.NOT_AVAILABLE; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + //this.searchPage.closeLoading(); + this.disableForms = false; + } + ); + } + + public queryChanged($event) { + this.loadPaging = true; + + var parameters = $event.value; + this.getResults(parameters, this.searchUtils.page,this.searchUtils.size); + console.info("queryChanged: Execute search query "+parameters); + + } + + +} diff --git a/portal-4cli/src/app/searchPages/advanced/advancedSearchDataProviders.module.ts b/portal-4cli/src/app/searchPages/advanced/advancedSearchDataProviders.module.ts new file mode 100644 index 00000000..77d474b3 --- /dev/null +++ b/portal-4cli/src/app/searchPages/advanced/advancedSearchDataProviders.module.ts @@ -0,0 +1,29 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{ AdvancedSearchDataProvidersRoutingModule} from './advancedSearchDataProviders-routing.module'; +import{AdvancedSearchDataProvidersComponent} from './advancedSearchDataProviders.component'; + + +import {DataProvidersServiceModule} from '../../services/dataProvidersService.module'; + import {AdvancedSearchPageModule} from '../searchUtils/advancedSearchPage.module'; + import {FreeGuard} from'../../login/freeGuard.guard'; + import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + DataProvidersServiceModule, + AdvancedSearchDataProvidersRoutingModule, AdvancedSearchPageModule + + ], + declarations: [ + AdvancedSearchDataProvidersComponent + ], + providers:[FreeGuard, IsRouteEnabled], + exports: [ + AdvancedSearchDataProvidersComponent + ] +}) +export class AdvancedSearchDataProvidersModule { } diff --git a/portal-4cli/src/app/searchPages/advanced/advancedSearchDatasets-routing.module.ts b/portal-4cli/src/app/searchPages/advanced/advancedSearchDatasets-routing.module.ts new file mode 100644 index 00000000..6217c5da --- /dev/null +++ b/portal-4cli/src/app/searchPages/advanced/advancedSearchDatasets-routing.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import{AdvancedSearchDatasetsComponent} from './advancedSearchDatasets.component'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: AdvancedSearchDatasetsComponent, canActivate: [FreeGuard, IsRouteEnabled], data: { + redirect: '/error' + }, canDeactivate: [PreviousRouteRecorder] } + + ]) + ] +}) +export class AdvancedSearchDatasetsRoutingModule { } diff --git a/portal-4cli/src/app/searchPages/advanced/advancedSearchDatasets.component.ts b/portal-4cli/src/app/searchPages/advanced/advancedSearchDatasets.component.ts new file mode 100644 index 00000000..d5a41f05 --- /dev/null +++ b/portal-4cli/src/app/searchPages/advanced/advancedSearchDatasets.component.ts @@ -0,0 +1,161 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import { Router, ActivatedRoute} from '@angular/router'; +import {Filter, Value,AdvancedField} from '../searchUtils/searchHelperClasses.class'; +import {SearchDatasetsService} from '../../services/searchDatasets.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {AdvancedSearchPageComponent} from '../searchUtils/advancedSearchPage.component'; +import {SearchFields} from '../../utils/properties/searchFields'; +import {SearchUtilsClass } from '../searchUtils/searchUtils.class'; + + +@Component({ + selector: 'advanced-search-datasets', + template: ` + + + + ` + }) + +export class AdvancedSearchDatasetsComponent { + private errorCodes: ErrorCodes; + + public results =[]; + public filters =[]; + + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public searchFields:SearchFields = new SearchFields(); + + public fieldIds: string[] = this.searchFields.RESULT_ADVANCED_FIELDS; + public fieldIdsMap= this.searchFields.RESULT_FIELDS; + public selectedFields:AdvancedField[] = []; + + @ViewChild (AdvancedSearchPageComponent) searchPage : AdvancedSearchPageComponent ; + public resourcesQuery = "( (oaftype exact result) and (resulttypeid exact dataset) )"; + public csvParams: string; + public disableForms: boolean = false; + public loadPaging: boolean = true; + public oldTotalResults: number = 0; + + constructor (private route: ActivatedRoute, private _searchDatasetsService: SearchDatasetsService ) { + this.results =[]; + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.searchUtils.baseUrl = OpenaireProperties.searchLinkToAdvancedDatasets; + + + + } + ngOnInit() { + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.sub = this.route.queryParams.subscribe(params => { + if(params['page'] && this.searchUtils.page != params['page']) { + this.loadPaging = false; + this.oldTotalResults = this.searchUtils.totalResults; + } + + let page = (params['page']=== undefined)?1:+params['page']; + this.searchUtils.page = ( page <= 0 ) ? 1 : page; + this.searchPage.fieldIds = this.fieldIds; + this.selectedFields =[]; + this.searchPage.selectedFields = this.selectedFields; + this.searchPage.fieldIdsMap = this.fieldIdsMap; + this.searchPage.getSelectedFiltersFromUrl(params); + this.getResults(this.searchPage.createQueryParameters(), this.searchUtils.page, this.searchUtils.size); + + }); + } + ngOnDestroy() { + this.sub.unsubscribe(); + } + sub: any; + public getResults(parameters:string, page: number, size: number){ + if(parameters!= null && parameters != '' ) { + this.csvParams ="&type=datasets&query=( "+this.resourcesQuery + "and (" + parameters + "))"; + }else{ + this.csvParams ="&type=datasets&query="+this.resourcesQuery; + } + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + //this.searchPage.openLoading(); + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + console.info("Advanced Search for Research Data: Execute search query "+parameters); + this._searchDatasetsService.advancedSearchDatasets(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Research Data total="+this.searchUtils.totalResults); + this.results = data[1]; + this.searchPage.updateBaseUrlWithParameters(); + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + //this.searchPage.closeLoading(); + this.disableForms = false; + + if(this.searchUtils.status == this.errorCodes.DONE) { + // Page out of limit!!! + let totalPages:any = this.searchUtils.totalResults/(this.searchUtils.size); + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, 10) + 1); + } + if(totalPages < page) { + this.searchUtils.totalResults = 0; + this.searchUtils.status = this.errorCodes.OUT_OF_BOUND; + } + } + }, + err => { + console.log(err); + console.info("error"); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = errorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.NOT_AVAILABLE; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + //this.searchPage.closeLoading(); + this.disableForms = false; + } + ); + } + private setFilters(){ + //TODO set filters from + } + + public queryChanged($event) { + this.loadPaging = true; + + var parameters = $event.value; + this.getResults(parameters, this.searchUtils.page,this.searchUtils.size); + console.info("queryChanged: Execute search query "+parameters); + + } + + +} diff --git a/portal-4cli/src/app/searchPages/advanced/advancedSearchDatasets.module.ts b/portal-4cli/src/app/searchPages/advanced/advancedSearchDatasets.module.ts new file mode 100644 index 00000000..b68d2582 --- /dev/null +++ b/portal-4cli/src/app/searchPages/advanced/advancedSearchDatasets.module.ts @@ -0,0 +1,29 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{ AdvancedSearchDatasetsRoutingModule} from './advancedSearchDatasets-routing.module'; +import{AdvancedSearchDatasetsComponent} from './advancedSearchDatasets.component'; + + +import {DatasetsServiceModule} from '../../services/datasetsService.module'; + import {AdvancedSearchPageModule} from '../searchUtils/advancedSearchPage.module'; + import {FreeGuard} from'../../login/freeGuard.guard'; + import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + DatasetsServiceModule, + AdvancedSearchDatasetsRoutingModule, AdvancedSearchPageModule + + ], + declarations: [ + AdvancedSearchDatasetsComponent + ], + providers:[FreeGuard, IsRouteEnabled], + exports: [ + AdvancedSearchDatasetsComponent + ] +}) +export class AdvancedSearchDatasetsModule { } diff --git a/portal-4cli/src/app/searchPages/advanced/advancedSearchOrganizations-routing.module.ts b/portal-4cli/src/app/searchPages/advanced/advancedSearchOrganizations-routing.module.ts new file mode 100644 index 00000000..541dc659 --- /dev/null +++ b/portal-4cli/src/app/searchPages/advanced/advancedSearchOrganizations-routing.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import{AdvancedSearchOrganizationsComponent} from './advancedSearchOrganizations.component'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: AdvancedSearchOrganizationsComponent , canActivate: [FreeGuard, IsRouteEnabled], data: { + redirect: '/error' + },canDeactivate: [PreviousRouteRecorder]} + + ]) + ] +}) +export class AdvancedSearchOrganizationsRoutingModule { } diff --git a/portal-4cli/src/app/searchPages/advanced/advancedSearchOrganizations.component.ts b/portal-4cli/src/app/searchPages/advanced/advancedSearchOrganizations.component.ts new file mode 100644 index 00000000..dffde579 --- /dev/null +++ b/portal-4cli/src/app/searchPages/advanced/advancedSearchOrganizations.component.ts @@ -0,0 +1,161 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import { Router, ActivatedRoute} from '@angular/router'; +import {Filter, Value,AdvancedField} from '../searchUtils/searchHelperClasses.class'; +import {SearchOrganizationsService} from '../../services/searchOrganizations.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {AdvancedSearchPageComponent} from '../searchUtils/advancedSearchPage.component'; +import {SearchFields} from '../../utils/properties/searchFields'; +import {SearchUtilsClass } from '../searchUtils/searchUtils.class'; + + +@Component({ + selector: 'advanced-search-organizations', + template: ` + + + + ` + }) + +export class AdvancedSearchOrganizationsComponent { + private errorCodes: ErrorCodes; + + public results =[]; + public filters =[]; + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public searchFields:SearchFields = new SearchFields(); + + public fieldIds: string[] = this.searchFields.ORGANIZATION_ADVANCED_FIELDS; + public fieldIdsMap = this.searchFields.ORGANIZATION_FIELDS; + public selectedFields:AdvancedField[] = []; + public csvParams: string; + public disableForms: boolean = false; + public loadPaging: boolean = true; + public oldTotalResults: number = 0; + + @ViewChild (AdvancedSearchPageComponent) searchPage : AdvancedSearchPageComponent ; + +public resourcesQuery = "(oaftype exact organization)"; + constructor (private route: ActivatedRoute, private _searchOrganizationsService: SearchOrganizationsService ) { + this.results =[]; + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.searchUtils.baseUrl = OpenaireProperties.searchLinkToAdvancedOrganizations; + + + + } + ngOnInit() { + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + this.sub = this.route.queryParams.subscribe(params => { + if(params['page'] && this.searchUtils.page != params['page']) { + this.loadPaging = false; + this.oldTotalResults = this.searchUtils.totalResults; + } + + let page = (params['page']=== undefined)?1:+params['page']; + this.searchUtils.page = ( page <= 0 ) ? 1 : page; + this.searchPage.fieldIds = this.fieldIds; + this.selectedFields =[]; + this.searchPage.selectedFields = this.selectedFields; + this.searchPage.fieldIdsMap = this.fieldIdsMap; + this.searchPage.getSelectedFiltersFromUrl(params); + this.getResults(this.searchPage.createQueryParameters(), this.searchUtils.page, this.searchUtils.size); + + }); + } + ngOnDestroy() { + this.sub.unsubscribe(); + } + sub: any; + public getResults(parameters:string, page: number, size: number){ + if(parameters!= null && parameters != '' ) { + this.csvParams ="&type=organizations&query=( "+this.resourcesQuery + "and (" + parameters + "))"; + }else{ + this.csvParams ="&type=organizations&query="+this.resourcesQuery; + } + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + //this.searchPage.openLoading(); + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + console.info("Advanced Search for Organizations: Execute search query "+parameters); + this._searchOrganizationsService.advancedSearchOrganizations(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Organizations total="+this.searchUtils.totalResults); + this.results = data[1]; + this.searchPage.updateBaseUrlWithParameters(); + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + //this.searchPage.closeLoading(); + this.disableForms = false; + + if(this.searchUtils.status == this.errorCodes.DONE) { + // Page out of limit!!! + let totalPages:any = this.searchUtils.totalResults/(this.searchUtils.size); + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, 10) + 1); + } + if(totalPages < page) { + this.searchUtils.totalResults = 0; + this.searchUtils.status = this.errorCodes.OUT_OF_BOUND; + } + } + }, + err => { + console.log(err); + console.info("error"); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = errorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.NOT_AVAILABLE; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + //this.searchPage.closeLoading(); + this.disableForms = false; + } + ); + } + private setFilters(){ + //TODO set filters from + } + + public queryChanged($event) { + this.loadPaging = true; + + var parameters = $event.value; + this.getResults(parameters, this.searchUtils.page,this.searchUtils.size); + console.info("queryChanged: Execute search query "+parameters); + + } + + +} diff --git a/portal-4cli/src/app/searchPages/advanced/advancedSearchOrganizations.module.ts b/portal-4cli/src/app/searchPages/advanced/advancedSearchOrganizations.module.ts new file mode 100644 index 00000000..85432402 --- /dev/null +++ b/portal-4cli/src/app/searchPages/advanced/advancedSearchOrganizations.module.ts @@ -0,0 +1,29 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{ AdvancedSearchOrganizationsRoutingModule} from './advancedSearchOrganizations-routing.module'; +import{AdvancedSearchOrganizationsComponent} from './advancedSearchOrganizations.component'; + + +import {OrganizationsServiceModule} from '../../services/organizationsService.module'; + import {AdvancedSearchPageModule} from '../searchUtils/advancedSearchPage.module'; + import {FreeGuard} from'../../login/freeGuard.guard'; + import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + OrganizationsServiceModule, + AdvancedSearchOrganizationsRoutingModule, AdvancedSearchPageModule + + ], + declarations: [ + AdvancedSearchOrganizationsComponent + ], + providers:[FreeGuard, IsRouteEnabled], + exports: [ + AdvancedSearchOrganizationsComponent + ] +}) +export class AdvancedSearchOrganizationsModule { } diff --git a/portal-4cli/src/app/searchPages/advanced/advancedSearchProjects-routing.module.ts b/portal-4cli/src/app/searchPages/advanced/advancedSearchProjects-routing.module.ts new file mode 100644 index 00000000..6056b75b --- /dev/null +++ b/portal-4cli/src/app/searchPages/advanced/advancedSearchProjects-routing.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import{AdvancedSearchProjectsComponent} from './advancedSearchProjects.component'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: AdvancedSearchProjectsComponent, canActivate: [FreeGuard, IsRouteEnabled], data: { + redirect: '/error' + }, canDeactivate: [PreviousRouteRecorder] } + + ]) + ] +}) +export class AdvancedSearchProjectsRoutingModule { } diff --git a/portal-4cli/src/app/searchPages/advanced/advancedSearchProjects.component.ts b/portal-4cli/src/app/searchPages/advanced/advancedSearchProjects.component.ts new file mode 100644 index 00000000..bf1af211 --- /dev/null +++ b/portal-4cli/src/app/searchPages/advanced/advancedSearchProjects.component.ts @@ -0,0 +1,162 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import { Router, ActivatedRoute} from '@angular/router'; +import {Filter, Value,AdvancedField} from '../searchUtils/searchHelperClasses.class'; +import {SearchProjectsService} from '../../services/searchProjects.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {AdvancedSearchPageComponent} from '../searchUtils/advancedSearchPage.component'; +import {SearchFields} from '../../utils/properties/searchFields'; +import {SearchUtilsClass } from '../searchUtils/searchUtils.class'; + +@Component({ + selector: 'advanced-search-projects', + template: ` + + + + ` + }) + +export class AdvancedSearchProjectsComponent { + private errorCodes: ErrorCodes; + + public results =[]; + public filters =[]; + + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public searchFields:SearchFields = new SearchFields(); + + public fieldIds: string[] = this.searchFields.PROJECT_ADVANCED_FIELDS; + public fieldIdsMap = this.searchFields.PROJECT_FIELDS; + public selectedFields:AdvancedField[] = []; + + @ViewChild (AdvancedSearchPageComponent) searchPage : AdvancedSearchPageComponent ; + public resourcesQuery = "(oaftype exact project)"; + public csvParams: string; + public disableForms: boolean = false; + public loadPaging: boolean = true; + public oldTotalResults: number = 0; + + constructor (private route: ActivatedRoute, private _searchProjectsService: SearchProjectsService ) { + + this.results =[]; + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.searchUtils.baseUrl = OpenaireProperties.searchLinkToAdvancedProjects; + + + + } + ngOnInit() { + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.sub = this.route.queryParams.subscribe(params => { + if(params['page'] && this.searchUtils.page != params['page']) { + this.loadPaging = false; + this.oldTotalResults = this.searchUtils.totalResults; + } + + let page = (params['page']=== undefined)?1:+params['page']; + this.searchUtils.page = ( page <= 0 ) ? 1 : page; + this.searchPage.fieldIds = this.fieldIds; + this.selectedFields =[]; + this.searchPage.selectedFields = this.selectedFields; + this.searchPage.fieldIdsMap = this.fieldIdsMap; + this.searchPage.getSelectedFiltersFromUrl(params); + this.getResults(this.searchPage.createQueryParameters(), this.searchUtils.page, this.searchUtils.size); + + }); + } + ngOnDestroy() { + this.sub.unsubscribe(); + } + sub: any; + public getResults(parameters:string, page: number, size: number){ + if(parameters!= null && parameters != '' ) { + this.csvParams ="&type=projects&query=( "+this.resourcesQuery + "and (" + parameters + "))"; + }else{ + this.csvParams ="&type=projects&query="+this.resourcesQuery; + } + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + //this.searchPage.openLoading(); + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + console.info("Advanced Search for Publications: Execute search query "+parameters); + this._searchProjectsService.advancedSearchProjects(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("Advanced Search for Projects total="+this.searchUtils.totalResults); + this.results = data[1]; + this.searchPage.updateBaseUrlWithParameters(); + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + //this.searchPage.closeLoading(); + this.disableForms = false; + + if(this.searchUtils.status == this.errorCodes.DONE) { + // Page out of limit!!! + let totalPages:any = this.searchUtils.totalResults/(this.searchUtils.size); + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, 10) + 1); + } + if(totalPages < page) { + this.searchUtils.totalResults = 0; + this.searchUtils.status = this.errorCodes.OUT_OF_BOUND; + } + } + }, + err => { + console.log(err); + console.info("error"); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = errorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.NOT_AVAILABLE; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + //this.searchPage.closeLoading(); + this.disableForms = false; + + } + ); + } + private setFilters(){ + //TODO set filters from + } + + public queryChanged($event) { + this.loadPaging = true; + + var parameters = $event.value; + this.getResults(parameters, this.searchUtils.page,this.searchUtils.size); + console.info("queryChanged: Execute search query "+parameters); + + } + + +} diff --git a/portal-4cli/src/app/searchPages/advanced/advancedSearchProjects.module.ts b/portal-4cli/src/app/searchPages/advanced/advancedSearchProjects.module.ts new file mode 100644 index 00000000..cb81a43d --- /dev/null +++ b/portal-4cli/src/app/searchPages/advanced/advancedSearchProjects.module.ts @@ -0,0 +1,29 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{ AdvancedSearchProjectsRoutingModule} from './advancedSearchProjects-routing.module'; +import{AdvancedSearchProjectsComponent} from './advancedSearchProjects.component'; + + +import {ProjectsServiceModule} from '../../services/projectsService.module'; + import {AdvancedSearchPageModule} from '../searchUtils/advancedSearchPage.module'; + import {FreeGuard} from'../../login/freeGuard.guard'; + import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + ProjectsServiceModule, + AdvancedSearchProjectsRoutingModule, AdvancedSearchPageModule + + ], + declarations: [ + AdvancedSearchProjectsComponent + ], + providers:[FreeGuard, IsRouteEnabled], + exports: [ + AdvancedSearchProjectsComponent + ] +}) +export class AdvancedSearchProjectsModule { } diff --git a/portal-4cli/src/app/searchPages/advanced/advancedSearchPublications-routing.module.ts b/portal-4cli/src/app/searchPages/advanced/advancedSearchPublications-routing.module.ts new file mode 100644 index 00000000..3a467df9 --- /dev/null +++ b/portal-4cli/src/app/searchPages/advanced/advancedSearchPublications-routing.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import{AdvancedSearchPublicationsComponent} from './advancedSearchPublications.component'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: AdvancedSearchPublicationsComponent, canActivate: [FreeGuard, IsRouteEnabled], data: { + redirect: '/error' + }, canDeactivate: [PreviousRouteRecorder] } + + ]) + ] +}) +export class AdvancedSearchPublicationsRoutingModule { } diff --git a/portal-4cli/src/app/searchPages/advanced/advancedSearchPublications.component.ts b/portal-4cli/src/app/searchPages/advanced/advancedSearchPublications.component.ts new file mode 100644 index 00000000..8f0cfa26 --- /dev/null +++ b/portal-4cli/src/app/searchPages/advanced/advancedSearchPublications.component.ts @@ -0,0 +1,160 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import { Router, ActivatedRoute} from '@angular/router'; +import {Filter, Value,AdvancedField} from '../searchUtils/searchHelperClasses.class'; +import {SearchPublicationsService} from '../../services/searchPublications.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {AdvancedSearchPageComponent} from '../searchUtils/advancedSearchPage.component'; +import {SearchFields} from '../../utils/properties/searchFields'; +import {SearchUtilsClass } from '../searchUtils/searchUtils.class'; + + +@Component({ + selector: 'advanced-search-publications', + template: ` + + + ` + }) + +export class AdvancedSearchPublicationsComponent { + private errorCodes: ErrorCodes; + + public results =[]; + public filters =[]; + + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public searchFields:SearchFields = new SearchFields(); + + public fieldIds: string[] = this.searchFields.RESULT_ADVANCED_FIELDS; + public fieldIdsMap= this.searchFields.RESULT_FIELDS; + public selectedFields:AdvancedField[] = []; + public resourcesQuery = "((oaftype exact result) and (resulttypeid exact publication))"; + public csvParams: string; + public disableForms: boolean = false; + public loadPaging: boolean = true; + public oldTotalResults: number = 0; + + @ViewChild (AdvancedSearchPageComponent) searchPage : AdvancedSearchPageComponent ; + + + constructor (private route: ActivatedRoute, private _searchPublicationsService: SearchPublicationsService ) { + + this.results =[]; + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.searchUtils.baseUrl = OpenaireProperties.searchLinkToAdvancedPublications; + + + + } + ngOnInit() { + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.sub = this.route.queryParams.subscribe(params => { + if(params['page'] && this.searchUtils.page != params['page']) { + this.loadPaging = false; + this.oldTotalResults = this.searchUtils.totalResults; + } + + let page = (params['page']=== undefined)?1:+params['page']; + this.searchUtils.page = ( page <= 0 ) ? 1 : page; + this.searchPage.fieldIds = this.fieldIds; + this.selectedFields =[]; + this.searchPage.selectedFields = this.selectedFields; + this.searchPage.fieldIdsMap = this.fieldIdsMap; + + this.searchPage.getSelectedFiltersFromUrl(params); + this.getResults(this.searchPage.createQueryParameters(), this.searchUtils.page, this.searchUtils.size); + }); + } + ngOnDestroy() { + this.sub.unsubscribe(); + } + sub: any; + public getResults(parameters:string, page: number, size: number){ + if(parameters!= null && parameters != '' ) { + this.csvParams ="&type=publications&query=("+this.resourcesQuery +" and (" + parameters + "))"; + }else{ + this.csvParams ="&type=publications&query="+this.resourcesQuery; + } + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + //this.searchPage.openLoading(); + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + console.info("Advanced Search for Publications: Execute search query "+parameters); + this._searchPublicationsService.advancedSearchPublications(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("searchPubl total="+this.searchUtils.totalResults); + this.results = data[1]; + this.searchPage.updateBaseUrlWithParameters(); + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + //this.searchPage.closeLoading(); + this.disableForms = false; + + if(this.searchUtils.status == this.errorCodes.DONE) { + // Page out of limit!!! + let totalPages:any = this.searchUtils.totalResults/(this.searchUtils.size); + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, 10) + 1); + } + if(totalPages < page) { + this.searchUtils.totalResults = 0; + this.searchUtils.status = this.errorCodes.OUT_OF_BOUND; + } + } + }, + err => { + console.log(err); + console.info("error"); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.NOT_AVAILABLE; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + //this.searchPage.closeLoading(); + this.disableForms = false; + + } + ); + } + + public queryChanged($event) { + this.loadPaging = true; + + var parameters = $event.value; + this.getResults(parameters, this.searchUtils.page,this.searchUtils.size); + console.info("queryChanged: Execute search query "+parameters); + + } + + +} diff --git a/portal-4cli/src/app/searchPages/advanced/advancedSearchPublications.module.ts b/portal-4cli/src/app/searchPages/advanced/advancedSearchPublications.module.ts new file mode 100644 index 00000000..4e6a230d --- /dev/null +++ b/portal-4cli/src/app/searchPages/advanced/advancedSearchPublications.module.ts @@ -0,0 +1,29 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{ AdvancedSearchPublicationsRoutingModule} from './advancedSearchPublications-routing.module'; +import{AdvancedSearchPublicationsComponent} from './advancedSearchPublications.component'; + + +import {PublicationsServiceModule} from '../../services/publicationsService.module'; + import {AdvancedSearchPageModule} from '../searchUtils/advancedSearchPage.module'; + import {FreeGuard} from'../../login/freeGuard.guard'; + import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + PublicationsServiceModule, + AdvancedSearchPublicationsRoutingModule, AdvancedSearchPageModule + + ], + declarations: [ + AdvancedSearchPublicationsComponent + ], + providers:[FreeGuard, IsRouteEnabled], + exports: [ + AdvancedSearchPublicationsComponent + ] +}) +export class AdvancedSearchPublicationsModule { } diff --git a/portal-4cli/src/app/searchPages/advanced/advancedSearchSoftware-routing.module.ts b/portal-4cli/src/app/searchPages/advanced/advancedSearchSoftware-routing.module.ts new file mode 100644 index 00000000..95183ca0 --- /dev/null +++ b/portal-4cli/src/app/searchPages/advanced/advancedSearchSoftware-routing.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import{AdvancedSearchSoftwareComponent} from './advancedSearchSoftware.component'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: AdvancedSearchSoftwareComponent, canActivate: [FreeGuard],canDeactivate: [PreviousRouteRecorder] } + + ]) + ] +}) +export class AdvancedSearchSoftwareRoutingModule { } diff --git a/portal-4cli/src/app/searchPages/advanced/advancedSearchSoftware.component.ts b/portal-4cli/src/app/searchPages/advanced/advancedSearchSoftware.component.ts new file mode 100644 index 00000000..73275cea --- /dev/null +++ b/portal-4cli/src/app/searchPages/advanced/advancedSearchSoftware.component.ts @@ -0,0 +1,161 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import { Router, ActivatedRoute} from '@angular/router'; +import {Filter, Value,AdvancedField} from '../searchUtils/searchHelperClasses.class'; +import {SearchSoftwareService} from '../../services/searchSoftware.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {AdvancedSearchPageComponent} from '../searchUtils/advancedSearchPage.component'; +import {SearchFields} from '../../utils/properties/searchFields'; +import {SearchUtilsClass } from '../searchUtils/searchUtils.class'; + + +@Component({ + selector: 'advanced-search-software', + template: ` + + + + ` + }) + +export class AdvancedSearchSoftwareComponent { + private errorCodes: ErrorCodes; + + public results =[]; + public filters =[]; + + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public searchFields:SearchFields = new SearchFields(); + + public fieldIds: string[] = this.searchFields.RESULT_ADVANCED_FIELDS; + public fieldIdsMap= this.searchFields.RESULT_FIELDS; + public selectedFields:AdvancedField[] = []; + + @ViewChild (AdvancedSearchPageComponent) searchPage : AdvancedSearchPageComponent ; + public resourcesQuery = "( (oaftype exact result) and (resulttypeid exact software) )"; + public csvParams: string; + public disableForms: boolean = false; + public loadPaging: boolean = true; + public oldTotalResults: number = 0; + + constructor (private route: ActivatedRoute, private _searchSoftwareService: SearchSoftwareService ) { + this.results =[]; + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.searchUtils.baseUrl = OpenaireProperties.searchLinkToAdvancedSoftware; + + + + } + ngOnInit() { + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.sub = this.route.queryParams.subscribe(params => { + if(params['page'] && this.searchUtils.page != params['page']) { + this.loadPaging = false; + this.oldTotalResults = this.searchUtils.totalResults; + } + + let page = (params['page']=== undefined)?1:+params['page']; + this.searchUtils.page = ( page <= 0 ) ? 1 : page; + this.searchPage.fieldIds = this.fieldIds; + this.selectedFields =[]; + this.searchPage.selectedFields = this.selectedFields; + this.searchPage.fieldIdsMap = this.fieldIdsMap; + this.searchPage.getSelectedFiltersFromUrl(params); + this.getResults(this.searchPage.createQueryParameters(), this.searchUtils.page, this.searchUtils.size); + + }); + } + ngOnDestroy() { + this.sub.unsubscribe(); + } + sub: any; + public getResults(parameters:string, page: number, size: number){ + if(parameters!= null && parameters != '' ) { + this.csvParams ="&type=software&query=( "+this.resourcesQuery + "and (" + parameters + "))"; + }else{ + this.csvParams ="&type=software&query="+this.resourcesQuery; + } + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + //this.searchPage.openLoading(); + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + console.info("Advanced Search for Software: Execute search query "+parameters); + this._searchSoftwareService.advancedSearchSoftware(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Software total="+this.searchUtils.totalResults); + this.results = data[1]; + this.searchPage.updateBaseUrlWithParameters(); + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + //this.searchPage.closeLoading(); + this.disableForms = false; + + if(this.searchUtils.status == this.errorCodes.DONE) { + // Page out of limit!!! + let totalPages:any = this.searchUtils.totalResults/(this.searchUtils.size); + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, 10) + 1); + } + if(totalPages < page) { + this.searchUtils.totalResults = 0; + this.searchUtils.status = this.errorCodes.OUT_OF_BOUND; + } + } + }, + err => { + console.log(err); + console.info("error"); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = errorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.NOT_AVAILABLE; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + //this.searchPage.closeLoading(); + this.disableForms = false; + } + ); + } + private setFilters(){ + //TODO set filters from + } + + public queryChanged($event) { + this.loadPaging = true; + + var parameters = $event.value; + this.getResults(parameters, this.searchUtils.page,this.searchUtils.size); + console.info("queryChanged: Execute search query "+parameters); + + } + + +} diff --git a/portal-4cli/src/app/searchPages/advanced/advancedSearchSoftware.module.ts b/portal-4cli/src/app/searchPages/advanced/advancedSearchSoftware.module.ts new file mode 100644 index 00000000..c5c276ff --- /dev/null +++ b/portal-4cli/src/app/searchPages/advanced/advancedSearchSoftware.module.ts @@ -0,0 +1,29 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{ AdvancedSearchSoftwareRoutingModule} from './advancedSearchSoftware-routing.module'; +import{AdvancedSearchSoftwareComponent} from './advancedSearchSoftware.component'; + + +import {SoftwareServiceModule} from '../../services/softwareService.module'; + import {AdvancedSearchPageModule} from '../searchUtils/advancedSearchPage.module'; + import {FreeGuard} from'../../login/freeGuard.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + SoftwareServiceModule, + AdvancedSearchSoftwareRoutingModule, AdvancedSearchPageModule + + ], + declarations: [ + AdvancedSearchSoftwareComponent + ], + providers:[FreeGuard + ], + exports: [ + AdvancedSearchSoftwareComponent + ] +}) +export class AdvancedSearchSoftwareModule { } diff --git a/portal-4cli/src/app/searchPages/dataProviders/compatibleDataProviders-routing.module.ts b/portal-4cli/src/app/searchPages/dataProviders/compatibleDataProviders-routing.module.ts new file mode 100644 index 00000000..5c8b5cba --- /dev/null +++ b/portal-4cli/src/app/searchPages/dataProviders/compatibleDataProviders-routing.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import{SearchCompatibleDataprovidersComponent} from './compatibleDataProviders.component'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: SearchCompatibleDataprovidersComponent, canActivate: [FreeGuard, IsRouteEnabled], data: { + redirect: '/error' + }, canDeactivate: [PreviousRouteRecorder] } + + ]) + ] +}) +export class CompatibleDataProvidersRoutingModule { } diff --git a/portal-4cli/src/app/searchPages/dataProviders/compatibleDataProviders.component.ts b/portal-4cli/src/app/searchPages/dataProviders/compatibleDataProviders.component.ts new file mode 100644 index 00000000..4e842e97 --- /dev/null +++ b/portal-4cli/src/app/searchPages/dataProviders/compatibleDataProviders.component.ts @@ -0,0 +1,186 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import { ActivatedRoute} from '@angular/router'; + +import { Filter, Value} from '../searchUtils/searchHelperClasses.class'; + +import {SearchDataprovidersService} from '../../services/searchDataproviders.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchFields} from '../../utils/properties/searchFields'; +import {SearchPageComponent } from '../searchUtils/searchPage.component'; +import {SearchUtilsClass } from '../searchUtils/searchUtils.class'; + +@Component({ + selector: 'search-content-providers', + template: ` + + + + + + ` + +}) +export class SearchCompatibleDataprovidersComponent { + private errorCodes: ErrorCodes; + public results =[]; + public filters =[]; + public baseUrl:string; + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public sub: any; public subResults: any; + public _location:Location; + public searchFields:SearchFields = new SearchFields(); + public refineFields: string[] = this.searchFields.COMPATIBLE_DATAPROVIDER_FIELDS; + public fieldIdsMap= this.searchFields.DATASOURCE_FIELDS; + public _prefixQueryFields: {field:string,opName:string,opValue:string,values:string[]}[] =[{field:"compatibility",opName:"cm",opValue:"not", values:["UNKNOWN","hostedBy","notCompatible"]},{field:"type",opName:"tp",opValue:"not",values: ["other"]}]; + // ["entityregistry","entityregistry::projects","entityregistry::repositories"]}]; + public _prefixQuery: string = ""; + + public CSV: any = { "columnNames": [ "Title", "Type", "Coutries", "Compatibility" ], + "export":[] + }; + public CSVDownloaded = false; + public resourcesQuery = '&query=((oaftype exact datasource) not(datasourcecompatibilityid = UNKNOWN) not(datasourcecompatibilityid = notCompatible) not(datasourcetypeuiid = other) not(datasourcetypeuiid exact "pubsrepository::journal") not(datasourcetypeuiid exact "aggregator::pubsrepository::journals"))'; + public csvParams: string; + public disableForms: boolean = false; + + @ViewChild (SearchPageComponent) searchPage : SearchPageComponent ; + + constructor (private route: ActivatedRoute, private _searchDataprovidersService: SearchDataprovidersService ) { + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.baseUrl = OpenaireProperties.getLinkToSearchCompatibleDataProviders(); + for(var i = 0; i < this._prefixQueryFields.length; i++ ){ + for(var j =0; j < this._prefixQueryFields[i].values.length; j++){ + this._prefixQuery+="&" + this._prefixQueryFields[i].field + "=" + + this._prefixQueryFields[i].values[j] + "&" + + this._prefixQueryFields[i].opName + "=" + this._prefixQueryFields[i].opValue; + } + } + this._prefixQuery+="&"; + } + + public ngOnInit() { + this.searchPage.refineFields = this.refineFields; + this.searchPage.fieldIdsMap = this.fieldIdsMap; + this.sub = this.route.queryParams.subscribe(params => { + this.searchUtils.keyword = (params['keyword']?params['keyword']:''); + this.searchUtils.page = (params['page']=== undefined)?1:+params['page']; + this.filters = this.createFilters(); + var queryParameters = this.searchPage.getIndexQueryParametersFromUrl(params); + console.info("|"+queryParameters+"|"); + this._getResults(queryParameters, false, this.searchUtils.page, this.searchUtils.size); + }); + } + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } } + private _getResults(parameters:string,refine:boolean, page: number, size: number){ + this.csvParams = parameters+this.resourcesQuery+"&type=datasources"; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + //this.searchPage.openLoading(); + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + this.subResults = this._searchDataprovidersService.searchCompatibleDataproviders(parameters,(refine)?this.searchPage.getRefineFieldsQuery():null, page, size, []).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Content Providers: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + this.searchPage.checkSelectedFilters(this.filters); + this.searchPage.updateBaseUrlWithParameters(this.filters); + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + //this.searchPage.closeLoading(); + this.disableForms = false; + + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + //this.searchPage.closeLoading(); + this.disableForms = false; + + } + ); + } + private setFilters(){ + //TODO set filters from + } + + public queryChanged($event) { + var parameters = $event.index; + console.info("queryChanged: Execute search query "+parameters); + + this._getResults(parameters, false, this.searchUtils.page, this.searchUtils.size); + } + private createFilters():Filter[] { + var filter_names=["Type","Compatibility Level"]; + var filter_ids=["datasourcetypeuiid","datasourcecompatibilityname"]; + var searchFields = new SearchFields(); + var filter_original_ids = searchFields.COMPATIBLE_DATAPROVIDER_FIELDS; + var value_names=[ + /*[ + "Institutional Publication Repository","Thematic Publication Repository", "Other Publication Repository", + "Institutional Repositories Aggregators", + "Thematic Repositories Aggregators", "Other Repositories Aggregators", + "Data Repositories", "Data Repositories Aggregators", "Journals", "Journals Aggregators", "CRIS Systems", "Publication Catalogues"], + */ + [ + "Institutional Repository", "Thematic Repository", "Publication Repository", + "Institutional Repository Aggregator", + "Thematic Repositories Aggregators", "Publication Repository Aggregator", + "Data Repository", "Data Repository Aggregator", "CRIS Systems", "Publication Catalogue"], + ["OpenAIRE Basic (DRIVER OA)","OpenAIRE 2.0 (EC funding)", "OpenAIRE 2.0+ (DRIVER OA, EC funding)", "OpenAIRE 3.0 (OA, funding)","OpenAIRE Data (funded, referenced datasets)"]]; + + var value_original_ids=[ + ["pubsrepository::institutional","pubsrepository::thematic", "pubsrepository::unknown", "aggregator::pubsrepository::institutional","aggregator::pubsrepository::thematic","aggregator::pubsrepository::unknown", + "datarepository::unknown", "aggregator::datarepository", "cris", "pubscatalogue::unknown"], + //["driver","openaire2.0", "driver-openaire2.0", "openaire3.0","openaire2.0_data"] + ["OpenAIRE Basic (DRIVER OA)","OpenAIRE 2.0 (EC funding)", "OpenAIRE 2.0+ (DRIVER OA, EC funding)", "OpenAIRE 3.0 (OA, funding)","OpenAIRE Data (funded, referenced datasets)"]]; + var filters: Filter[] =[]; + for(var i =0 ; i < filter_names.length;i++){ + var values:Value[] = []; + for(var j =0 ; j < value_names[i].length;j++){ + var value:Value = {name: value_names[i][j], id: value_original_ids[i][j], number:j, selected:false} + values.push(value); + } + var filter:Filter = {title: filter_names[i], filterId: filter_ids[i], originalFilterId: filter_original_ids[i], values : values, countSelectedValues:0, "filterOperator": 'or' }; + filters.push(filter); + } + return filters; + } +} diff --git a/portal-4cli/src/app/searchPages/dataProviders/compatibleDataProviders.module.ts b/portal-4cli/src/app/searchPages/dataProviders/compatibleDataProviders.module.ts new file mode 100644 index 00000000..d5c3082e --- /dev/null +++ b/portal-4cli/src/app/searchPages/dataProviders/compatibleDataProviders.module.ts @@ -0,0 +1,32 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{ CompatibleDataProvidersRoutingModule} from './compatibleDataProviders-routing.module'; +import{SearchCompatibleDataprovidersComponent} from './compatibleDataProviders.component'; + +import {SearchResultsModule } from '../searchUtils/searchResults.module'; + +import {DataProvidersServiceModule} from '../../services/dataProvidersService.module'; +import {SearchFormModule} from '../searchUtils/searchForm.module'; +//import {SearchFilterModalModule} from '../searchUtils/searchFilterModal.module'; +import {SearchPageModule} from '../searchUtils/searchPage.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + DataProvidersServiceModule, + SearchFormModule, SearchResultsModule, CompatibleDataProvidersRoutingModule, SearchPageModule + + ], + declarations: [ + SearchCompatibleDataprovidersComponent + ], + providers:[FreeGuard, IsRouteEnabled], + exports: [ + SearchCompatibleDataprovidersComponent + ] +}) +export class CompatibleDataProvidersModule { } diff --git a/portal-4cli/src/app/searchPages/dataProviders/compatibleDataProvidersTable-routing.module.ts b/portal-4cli/src/app/searchPages/dataProviders/compatibleDataProvidersTable-routing.module.ts new file mode 100644 index 00000000..b00ad1ad --- /dev/null +++ b/portal-4cli/src/app/searchPages/dataProviders/compatibleDataProvidersTable-routing.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import{SearchCompatibleDataprovidersTableComponent} from './compatibleDataProvidersTable.component'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: SearchCompatibleDataprovidersTableComponent, canActivate: [FreeGuard, IsRouteEnabled], data: { + redirect: '/error' + }, canDeactivate: [PreviousRouteRecorder] } + + ]) + ] +}) +export class CompatibleDataProvidersTableRoutingModule { } diff --git a/portal-4cli/src/app/searchPages/dataProviders/compatibleDataProvidersTable.component.ts b/portal-4cli/src/app/searchPages/dataProviders/compatibleDataProvidersTable.component.ts new file mode 100644 index 00000000..3b4e7c4f --- /dev/null +++ b/portal-4cli/src/app/searchPages/dataProviders/compatibleDataProvidersTable.component.ts @@ -0,0 +1,196 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import { ActivatedRoute} from '@angular/router'; + +import { Filter, Value} from '../searchUtils/searchHelperClasses.class'; + +import {SearchDataprovidersService} from '../../services/searchDataproviders.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchFields} from '../../utils/properties/searchFields'; +import {SearchPageTableViewComponent } from '../searchUtils/searchPageTableView.component'; +import {SearchUtilsClass } from '../searchUtils/searchUtils.class'; + +@Component({ + selector: 'search-content-providers-table', + template: ` + + + + ` + +}) +export class SearchCompatibleDataprovidersTableComponent { + private errorCodes: ErrorCodes; + + public results =[]; + public filters =[]; + public baseUrl:string; + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public sub: any; public subResults: any; + public _location:Location; + public searchFields:SearchFields = new SearchFields(); + public refineFields: string[] = this.searchFields.COMPATIBLE_DATAPROVIDER_FIELDS; + + /*public CSV: any = { "columnNames": [ "Title", "Type", "Coutries", "Compatibility" ], + "export":[] + }; + public CSVDownloaded = false; + public csvParams: string; + public resourcesQuery = "&query=((oaftype exact datasource) not(datasourcecompatibilityid = UNKNOWN) not(datasourcecompatibilityid = notCompatible) not(datasourcetypeuiid = other))";*/ + + public disableForms: boolean = false; + + @ViewChild (SearchPageTableViewComponent) searchPage : SearchPageTableViewComponent ; + + constructor (private route: ActivatedRoute, private _searchDataprovidersService: SearchDataprovidersService ) { + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.baseUrl = OpenaireProperties.getLinkToSearchCompatibleDataProvidersTable(); + } + + public ngOnInit() { + this.searchPage.refineFields = this.refineFields; + this.sub = this.route.queryParams.subscribe(params => { + this.searchUtils.keyword = (params['keyword']?params['keyword']:''); + //this.searchUtils.page = (params['page']=== undefined)?1:+params['page']; + this.filters = this.createFilters(); + this.searchPage.getParametersFromUrl(params); + this._getResults(); + }); + } + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } } + private _getResults(){ + //this.csvParams = this.resourcesQuery+"&type=datasources"; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + let size: number = 0; + this.subResults = this._searchDataprovidersService.searchCompatibleDataprovidersTable().subscribe( + data => { + size = data; + if(size > 0) { + this.subResults = this._searchDataprovidersService.searchCompatibleDataproviders("", null, 1, size, []).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Content Providers [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + this.searchPage.checkSelectedFilters(this.filters); + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + this.disableForms = false; + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + this.disableForms = false; + + } + ); + } else { + this.searchPage.checkSelectedFilters(this.filters); + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.NONE; + this.disableForms = false; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + + } + private setFilters(){ + //TODO set filters from + } + + private createFilters():Filter[] { + var filter_names=["Type","Compatibility Level"]; + var filter_ids=["datasourcetypeuiid","datasourcecompatibilityname"]; + var searchFields = new SearchFields(); + var filter_original_ids = searchFields.COMPATIBLE_DATAPROVIDER_FIELDS; + var value_names=[ + /*[ + "Institutional Publication Repository","Thematic Publication Repository", "Other Publication Repository", + "Institutional Repositories Aggregators", + "Thematic Repositories Aggregators", "Other Repositories Aggregators", + "Data Repositories", "Data Repositories Aggregators", "Journals", "Journals Aggregators", "CRIS Systems", "Publication Catalogues"], + */ + [ + "Institutional Repository", "Thematic Repository", "Publication Repository", + "Institutional Repository Aggregator", + "Thematic Repositories Aggregators", "Publication Repository Aggregator", + "Data Repository", "Data Repository Aggregator", "CRIS Systems", "Publication Catalogue"], + + + + + ["OpenAIRE Basic (DRIVER OA)","OpenAIRE 2.0 (EC funding)", "OpenAIRE 2.0+ (DRIVER OA, EC funding)", "OpenAIRE 3.0 (OA, funding)","OpenAIRE Data (funded, referenced datasets)"]]; + + var value_original_ids=[ + ["pubsrepository::institutional","pubsrepository::thematic", "pubsrepository::unknown", "aggregator::pubsrepository::institutional","aggregator::pubsrepository::thematic","aggregator::pubsrepository::unknown", + "datarepository::unknown", "aggregator::datarepository", "cris", "pubscatalogue::unknown"], + //["driver","openaire2.0", "driver-openaire2.0", "openaire3.0","openaire2.0_data"] + ["OpenAIRE Basic (DRIVER OA)","OpenAIRE 2.0 (EC funding)", "OpenAIRE 2.0+ (DRIVER OA, EC funding)", "OpenAIRE 3.0 (OA, funding)","OpenAIRE Data (funded, referenced datasets)"]]; + var filters: Filter[] =[]; + for(var i =0 ; i < filter_names.length;i++){ + var values:Value[] = []; + for(var j =0 ; j < value_names[i].length;j++){ + var value:Value = {name: value_names[i][j], id: value_original_ids[i][j], number:j, selected:false} + values.push(value); + } + var filter:Filter = {title: filter_names[i], filterId: filter_ids[i], originalFilterId: filter_original_ids[i], values : values, countSelectedValues:0, "filterOperator": 'or' }; + filters.push(filter); + } + return filters; + } +} diff --git a/portal-4cli/src/app/searchPages/dataProviders/compatibleDataProvidersTable.module.ts b/portal-4cli/src/app/searchPages/dataProviders/compatibleDataProvidersTable.module.ts new file mode 100644 index 00000000..1efcace5 --- /dev/null +++ b/portal-4cli/src/app/searchPages/dataProviders/compatibleDataProvidersTable.module.ts @@ -0,0 +1,32 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{ CompatibleDataProvidersTableRoutingModule} from './compatibleDataProvidersTable-routing.module'; +import{SearchCompatibleDataprovidersTableComponent} from './compatibleDataProvidersTable.component'; + +//import {DatasourceTableViewModule } from '../searchUtils/datasourceTableView.module'; + +import {DataProvidersServiceModule} from '../../services/dataProvidersService.module'; +import {SearchFormModule} from '../searchUtils/searchForm.module'; +//import {SearchFilterModalModule} from '../searchUtils/searchFilterModal.module'; +import {SearchPageTableViewModule} from '../searchUtils/searchPageTableView.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + DataProvidersServiceModule, + SearchFormModule, CompatibleDataProvidersTableRoutingModule, SearchPageTableViewModule + + ], + declarations: [ + SearchCompatibleDataprovidersTableComponent + ], + providers:[FreeGuard, IsRouteEnabled], + exports: [ + SearchCompatibleDataprovidersTableComponent + ] +}) +export class CompatibleDataProvidersTableModule { } diff --git a/portal-4cli/src/app/searchPages/dataProviders/entityRegistries-routing.module.ts b/portal-4cli/src/app/searchPages/dataProviders/entityRegistries-routing.module.ts new file mode 100644 index 00000000..35e6b8bc --- /dev/null +++ b/portal-4cli/src/app/searchPages/dataProviders/entityRegistries-routing.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import{SearchEntityRegistriesComponent} from './entityRegistries.component'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: SearchEntityRegistriesComponent, canActivate: [FreeGuard, IsRouteEnabled], data: { + redirect: '/error' + }, canDeactivate: [PreviousRouteRecorder] } + + ]) + ] +}) +export class EntityRegistriesRoutingModule { } diff --git a/portal-4cli/src/app/searchPages/dataProviders/entityRegistries.component.ts b/portal-4cli/src/app/searchPages/dataProviders/entityRegistries.component.ts new file mode 100644 index 00000000..d3652b04 --- /dev/null +++ b/portal-4cli/src/app/searchPages/dataProviders/entityRegistries.component.ts @@ -0,0 +1,178 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import { ActivatedRoute} from '@angular/router'; + +import { Filter, Value} from '../searchUtils/searchHelperClasses.class'; + +import {SearchDataprovidersService} from '../../services/searchDataproviders.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchFields} from '../../utils/properties/searchFields'; +import {SearchPageComponent } from '../searchUtils/searchPage.component'; +import {SearchUtilsClass } from '../searchUtils/searchUtils.class'; + +@Component({ + selector: 'search-entity-registries', + template: ` + + + + + ` + +}) +export class SearchEntityRegistriesComponent { + private errorCodes: ErrorCodes; + + public results =[]; + public filters =[]; + public baseUrl:string; + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public sub: any; public subResults: any; + public _location:Location; + public searchFields:SearchFields = new SearchFields(); + public refineFields: string[] = this.searchFields.ENTITY_REGISTRIES_FIELDS; + public fieldIdsMap= this.searchFields.DATASOURCE_FIELDS; + public _prefixQueryFields: {field:string,opName:string,opValue:string,values:string[]}[] =[ + {field:"type",opName:"tp",opValue:"and",values: ["other"]}]; + // ["entityregistry","entityregistry::projects","entityregistry::repositories"]}]; + public _prefixQuery: string = ""; + + public CSV: any = { "columnNames": [ "Title", "Type", "Coutries", "Compatibility" ], + "export":[] + }; + public CSVDownloaded = false; + public disableForms: boolean = false; + + @ViewChild (SearchPageComponent) searchPage : SearchPageComponent ; + public resourcesQuery = "&query=((oaftype exact datasource) and(datasourcetypeuiid = other))"; + public csvParams: string; + + constructor (private route: ActivatedRoute, private _searchDataprovidersService: SearchDataprovidersService ) { + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.baseUrl = OpenaireProperties.getLinkToSearchEntityRegistries(); + for(var i = 0; i < this._prefixQueryFields.length; i++ ){ + for(var j =0; j < this._prefixQueryFields[i].values.length; j++){ + this._prefixQuery+="&" + this._prefixQueryFields[i].field + "=" + + this._prefixQueryFields[i].values[j] + "&" + + this._prefixQueryFields[i].opName + "=" + this._prefixQueryFields[i].opValue; + } + } + this._prefixQuery+="&"; + } + + public ngOnInit() { + this.searchPage.refineFields = this.refineFields; + this.searchPage.fieldIdsMap = this.fieldIdsMap; + this.sub = this.route.queryParams.subscribe(params => { + this.searchUtils.keyword = (params['keyword']?params['keyword']:''); + this.searchUtils.page = (params['page']=== undefined)?1:+params['page']; + this.filters = this.createFilters(); + + var queryParameters = this.searchPage.getIndexQueryParametersFromUrl(params); + this._getResults(queryParameters, false, this.searchUtils.page, this.searchUtils.size); + }); + } + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } } + private _getResults(parameters:string,refine:boolean, page: number, size: number){ + this.csvParams = parameters+this.resourcesQuery+"&type=datasources"; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + //this.searchPage.openLoading(); + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + this.subResults = this._searchDataprovidersService.searchEntityRegistries(parameters,(refine)?this.searchPage.getRefineFieldsQuery():null, page, size, []).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Entity Registries: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + this.searchPage.checkSelectedFilters(this.filters); + this.searchPage.updateBaseUrlWithParameters(this.filters); + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + //this.searchPage.closeLoading(); + this.disableForms = false; + + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + //this.searchPage.closeLoading(); + this.disableForms = false; + + } + ); + } + private setFilters(){ + //TODO set filters from + } + + public queryChanged($event) { + var parameters = $event.index; + console.info("queryChanged: Execute search query "+parameters); + this._getResults(parameters, false, this.searchUtils.page, this.searchUtils.size); + } + private createFilters():Filter[] { + var filter_names=["Type","Compatibility Level"]; + var filter_ids=["datasourcetypename","datasourcecompatibilityname"]; + var searchFields = new SearchFields(); + var filter_original_ids = searchFields.ENTITY_REGISTRIES_FIELDS; + var value_names=[ + ["Funder","Registry of repositories","Scholarly Comm. Infrastructure","Registry","Information Space","Web Source"], + + ["OpenAIRE Basic (DRIVER OA)","OpenAIRE 2.0 (EC funding)", "OpenAIRE 2.0+ (DRIVER OA, EC funding)", "OpenAIRE 3.0 (OA, funding)","OpenAIRE Data (funded, referenced datasets)"]]; + + var value_original_ids=[ + ["Funder database","Registry of repositories","Scholarly Comm. Infrastructure","Registry","Information Space","Web Source"], + //["entityregistry::projects","entityregistry::repositories","scholarcomminfra","entityregistry","infospace","websource"], + //["driver","openaire2.0", "driver-openaire2.0", "openaire3.0","openaire2.0_data"] + ["OpenAIRE Basic (DRIVER OA)","OpenAIRE 2.0 (EC funding)", "OpenAIRE 2.0+ (DRIVER OA, EC funding)", "OpenAIRE 3.0 (OA, funding)","OpenAIRE Data (funded, referenced datasets)"]]; + + var filters: Filter[] =[]; + for(var i =0 ; i < filter_names.length;i++){ + var values:Value[] = []; + for(var j =0 ; j < value_names[i].length;j++){ + var value:Value = {name: value_names[i][j], id: value_original_ids[i][j], number:j, selected:false} + values.push(value); + } + var filter:Filter = {title: filter_names[i], filterId: filter_ids[i], originalFilterId: filter_original_ids[i], values : values, countSelectedValues:0, "filterOperator": 'or' }; + filters.push(filter); + } + return filters; + } +} diff --git a/portal-4cli/src/app/searchPages/dataProviders/entityRegistries.module.ts b/portal-4cli/src/app/searchPages/dataProviders/entityRegistries.module.ts new file mode 100644 index 00000000..f1a2a277 --- /dev/null +++ b/portal-4cli/src/app/searchPages/dataProviders/entityRegistries.module.ts @@ -0,0 +1,32 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{ EntityRegistriesRoutingModule} from './entityRegistries-routing.module'; +import{SearchEntityRegistriesComponent} from './entityRegistries.component'; + +import {SearchResultsModule } from '../searchUtils/searchResults.module'; + +import {DataProvidersServiceModule} from '../../services/dataProvidersService.module'; +import {SearchFormModule} from '../searchUtils/searchForm.module'; +//import {SearchFilterModalModule} from '../searchUtils/searchFilterModal.module'; +import {SearchPageModule} from '../searchUtils/searchPage.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + DataProvidersServiceModule, + SearchFormModule, SearchResultsModule, EntityRegistriesRoutingModule, SearchPageModule + + ], + declarations: [ + SearchEntityRegistriesComponent + ], + providers:[FreeGuard, IsRouteEnabled], + exports: [ + SearchEntityRegistriesComponent + ] +}) +export class EntityRegistriesModule { } diff --git a/portal-4cli/src/app/searchPages/dataProviders/entityRegistriesTable-routing.module.ts b/portal-4cli/src/app/searchPages/dataProviders/entityRegistriesTable-routing.module.ts new file mode 100644 index 00000000..64986745 --- /dev/null +++ b/portal-4cli/src/app/searchPages/dataProviders/entityRegistriesTable-routing.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import{SearchEntityRegistriesTableComponent} from './entityRegistriesTable.component'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: SearchEntityRegistriesTableComponent, canActivate: [FreeGuard, IsRouteEnabled], data: { + redirect: '/error' + }, canDeactivate: [PreviousRouteRecorder] } + + ]) + ] +}) +export class EntityRegistriesTableRoutingModule { } diff --git a/portal-4cli/src/app/searchPages/dataProviders/entityRegistriesTable.component.ts b/portal-4cli/src/app/searchPages/dataProviders/entityRegistriesTable.component.ts new file mode 100644 index 00000000..c4c5a453 --- /dev/null +++ b/portal-4cli/src/app/searchPages/dataProviders/entityRegistriesTable.component.ts @@ -0,0 +1,206 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import { ActivatedRoute} from '@angular/router'; + +import { Filter, Value} from '../searchUtils/searchHelperClasses.class'; + +import {SearchDataprovidersService} from '../../services/searchDataproviders.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchFields} from '../../utils/properties/searchFields'; +import {SearchPageTableViewComponent } from '../searchUtils/searchPageTableView.component'; +import {SearchUtilsClass } from '../searchUtils/searchUtils.class'; + +@Component({ + selector: 'search-entity-registries-table', + template: ` + + + + + ` + +}) +export class SearchEntityRegistriesTableComponent { + private errorCodes: ErrorCodes; + + public results =[]; + public filters =[]; + public baseUrl:string; + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public sub: any; public subResults: any; + public _location:Location; + public searchFields:SearchFields = new SearchFields(); + public refineFields: string[] = this.searchFields.ENTITY_REGISTRIES_FIELDS; + public disableForms: boolean = false; + + @ViewChild (SearchPageTableViewComponent) searchPage : SearchPageTableViewComponent ; + + constructor (private route: ActivatedRoute, private _searchDataprovidersService: SearchDataprovidersService ) { + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + } + + public ngOnInit() { + this.searchPage.refineFields = this.refineFields; + this.sub = this.route.queryParams.subscribe(params => { + this.searchUtils.keyword = (params['keyword']?params['keyword']:''); + //this.searchUtils.page = (params['page']=== undefined)?1:+params['page']; + this.filters = this.createFilters(); + + this.searchPage.getParametersFromUrl(params); + this._getResults("", false, this.searchUtils.page); + }); + } + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } } + private _getResults(parameters:string,refine:boolean, page: number){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + let size: number = 0; + this.subResults = this._searchDataprovidersService.searchEntityRegistriesTable().subscribe( + data => { + size = data; + if(size > 0) { + this.subResults = this._searchDataprovidersService.searchEntityRegistries("",null, page, size, []).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Entity Registries [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + this.searchPage.checkSelectedFilters(this.filters); + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + this.disableForms = false; + + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + this.disableForms = false; + + } + ); + } else { + this.searchPage.checkSelectedFilters(this.filters); + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.NONE; + this.disableForms = false; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); +/* + this.subResults = this._searchDataprovidersService.searchEntityRegistries(parameters,(refine)?this.searchPage.getRefineFieldsQuery():null, page, size, []).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Entity Registries: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + this.searchPage.checkSelectedFilters(this.filters); + this.searchPage.updateBaseUrlWithParameters(this.filters); + var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = errorCodes.NONE; + } + //this.searchPage.closeLoading(); + this.disableForms = false; + + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = errorCodes.ERROR; + //this.searchPage.closeLoading(); + this.disableForms = false; + + } + ); +*/ + } + private setFilters(){ + //TODO set filters from + } + + + private createFilters():Filter[] { + var filter_names=["Type","Compatibility Level"]; + var filter_ids=["datasourcetypename","datasourcecompatibilityname"]; + var searchFields = new SearchFields(); + var filter_original_ids = searchFields.ENTITY_REGISTRIES_FIELDS; + var value_names=[ + ["Funder database","Registry of repositories","Scholarly Comm. Infrastructure","Registry","Information Space","Web Source"], + + ["OpenAIRE Basic (DRIVER OA)","OpenAIRE 2.0 (EC funding)", "OpenAIRE 2.0+ (DRIVER OA, EC funding)", "OpenAIRE 3.0 (OA, funding)","OpenAIRE Data (funded, referenced datasets)"]]; + + var value_original_ids=[ + ["Funder database","Registry of repositories","Scholarly Comm. Infrastructure","Registry","Information Space","Web Source"], + //["entityregistry::projects","entityregistry::repositories","scholarcomminfra","entityregistry","infospace","websource"], + //["driver","openaire2.0", "driver-openaire2.0", "openaire3.0","openaire2.0_data"] + ["OpenAIRE Basic (DRIVER OA)","OpenAIRE 2.0 (EC funding)", "OpenAIRE 2.0+ (DRIVER OA, EC funding)", "OpenAIRE 3.0 (OA, funding)","OpenAIRE Data (funded, referenced datasets)"]]; + + var filters: Filter[] =[]; + for(var i =0 ; i < filter_names.length;i++){ + var values:Value[] = []; + for(var j =0 ; j < value_names[i].length;j++){ + var value:Value = {name: value_names[i][j], id: value_original_ids[i][j], number:j, selected:false} + values.push(value); + } + var filter:Filter = {title: filter_names[i], filterId: filter_ids[i], originalFilterId: filter_original_ids[i], values : values, countSelectedValues:0, "filterOperator": 'or' }; + filters.push(filter); + } + return filters; + } +} diff --git a/portal-4cli/src/app/searchPages/dataProviders/entityRegistriesTable.module.ts b/portal-4cli/src/app/searchPages/dataProviders/entityRegistriesTable.module.ts new file mode 100644 index 00000000..9d9b824c --- /dev/null +++ b/portal-4cli/src/app/searchPages/dataProviders/entityRegistriesTable.module.ts @@ -0,0 +1,32 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{ EntityRegistriesTableRoutingModule} from './entityRegistriesTable-routing.module'; +import{SearchEntityRegistriesTableComponent} from './entityRegistriesTable.component'; + +//import {DatasourceTableViewModule } from '../searchUtils/datasourceTableView.module'; + +import {DataProvidersServiceModule} from '../../services/dataProvidersService.module'; +import {SearchFormModule} from '../searchUtils/searchForm.module'; +//import {SearchFilterModalModule} from '../searchUtils/searchFilterModal.module'; +import {SearchPageTableViewModule} from '../searchUtils/searchPageTableView.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + DataProvidersServiceModule, + SearchFormModule, EntityRegistriesTableRoutingModule, SearchPageTableViewModule + + ], + declarations: [ + SearchEntityRegistriesTableComponent + ], + providers:[FreeGuard, IsRouteEnabled], + exports: [ + SearchEntityRegistriesTableComponent + ] +}) +export class EntityRegistriesTableModule { } diff --git a/portal-4cli/src/app/searchPages/dataProviders/journals-routing.module.ts b/portal-4cli/src/app/searchPages/dataProviders/journals-routing.module.ts new file mode 100644 index 00000000..d9c3de9d --- /dev/null +++ b/portal-4cli/src/app/searchPages/dataProviders/journals-routing.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import{SearchJournalsComponent} from './journals.component'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: SearchJournalsComponent, canActivate: [FreeGuard, IsRouteEnabled], data: { + redirect: '/error' + }, canDeactivate: [PreviousRouteRecorder] } + + ]) + ] +}) +export class JournalsRoutingModule { } diff --git a/portal-4cli/src/app/searchPages/dataProviders/journals.component.ts b/portal-4cli/src/app/searchPages/dataProviders/journals.component.ts new file mode 100644 index 00000000..265d0126 --- /dev/null +++ b/portal-4cli/src/app/searchPages/dataProviders/journals.component.ts @@ -0,0 +1,181 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import { ActivatedRoute} from '@angular/router'; + +import { Filter, Value} from '../searchUtils/searchHelperClasses.class'; + +import {SearchDataprovidersService} from '../../services/searchDataproviders.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchFields} from '../../utils/properties/searchFields'; +import {SearchPageComponent } from '../searchUtils/searchPage.component'; +import {SearchUtilsClass } from '../searchUtils/searchUtils.class'; + +@Component({ + selector: 'search-journals', + template: ` + + + + ` + +}) +export class SearchJournalsComponent { + private errorCodes: ErrorCodes; + + public results =[]; + public filters =[]; + public baseUrl:string; + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public sub: any; public subResults: any; + public _location:Location; + public searchFields:SearchFields = new SearchFields(); + public refineFields: string[] = this.searchFields.JOURNAL_FIELDS; + public fieldIdsMap= this.searchFields.DATASOURCE_FIELDS; + public _prefixQueryFields: {field:string,opName:string,opValue:string,values:string[]}[] =[{field:"compatibility",opName:"cm",opValue:"not", values:["UNKNOWN","hostedBy","notCompatible"]},{field:"type",opName:"tp",opValue:"not",values: ["other"]}]; + // ["entityregistry","entityregistry::projects","entityregistry::repositories"]}]; + public _prefixQuery: string = ""; + + public CSV: any = { "columnNames": [ "Title", "Type", "Coutries", "Compatibility" ], + "export":[] + }; + public CSVDownloaded = false; + public resourcesQuery = '&query=((oaftype exact datasource) not(datasourcecompatibilityid = UNKNOWN) not(datasourcecompatibilityid = notCompatible) and (datasourcetypeuiid exact "pubsrepository::journal" or datasourcetypeuiid exact "aggregator::pubsrepository::journals" ))'; + //"&query=((oaftype exact datasource) not(datasourcecompatibilityid = UNKNOWN) not(datasourcecompatibilityid = notCompatible) not(datasourcetypeuiid = other))"; + public csvParams: string; + public disableForms: boolean = false; + + @ViewChild (SearchPageComponent) searchPage : SearchPageComponent ; + + constructor (private route: ActivatedRoute, private _searchDataprovidersService: SearchDataprovidersService ) { + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.baseUrl = OpenaireProperties.getLinkToSearchJournals(); + for(var i = 0; i < this._prefixQueryFields.length; i++ ){ + for(var j =0; j < this._prefixQueryFields[i].values.length; j++){ + this._prefixQuery+="&" + this._prefixQueryFields[i].field + "=" + + this._prefixQueryFields[i].values[j] + "&" + + this._prefixQueryFields[i].opName + "=" + this._prefixQueryFields[i].opValue; + } + } + this._prefixQuery+="&"; + } + + public ngOnInit() { + this.searchPage.refineFields = this.refineFields; + this.searchPage.fieldIdsMap = this.fieldIdsMap; + this.sub = this.route.queryParams.subscribe(params => { + this.searchUtils.keyword = (params['keyword']?params['keyword']:''); + this.searchUtils.page = (params['page']=== undefined)?1:+params['page']; + this.filters = this.createFilters(); + var queryParameters = this.searchPage.getIndexQueryParametersFromUrl(params); + console.info("|"+queryParameters+"|"); + this._getResults(queryParameters, false, this.searchUtils.page, this.searchUtils.size); + }); + } + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } } + private _getResults(parameters:string,refine:boolean, page: number, size: number){ + this.csvParams = parameters+this.resourcesQuery+"&type=datasources"; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + //this.searchPage.openLoading(); + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + this.subResults = this._searchDataprovidersService.searchJournals(parameters,(refine)?this.searchPage.getRefineFieldsQuery():null, page, size, []).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Journals: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + this.searchPage.checkSelectedFilters(this.filters); + this.searchPage.updateBaseUrlWithParameters(this.filters); + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + //this.searchPage.closeLoading(); + this.disableForms = false; + + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + //this.searchPage.closeLoading(); + this.disableForms = false; + + } + ); + } + private setFilters(){ + //TODO set filters from + } + + public queryChanged($event) { + var parameters = $event.index; + console.info("queryChanged: Execute search query "+parameters); + + this._getResults(parameters, false, this.searchUtils.page, this.searchUtils.size); + } + private createFilters():Filter[] { + var filter_names=["Type","Compatibility Level"]; + var filter_ids=["datasourcetypeuiid","datasourcecompatibilityname"]; + var searchFields = new SearchFields(); + var filter_original_ids = searchFields.JOURNAL_FIELDS; + var value_names=[ + /*[ + "Institutional Publication Repository","Thematic Publication Repository", "Other Publication Repository", + "Institutional Repositories Aggregators", + "Thematic Repositories Aggregators", "Other Repositories Aggregators", + "Data Repositories", "Data Repositories Aggregators", "Journals", "Journals Aggregators", "CRIS Systems", "Publication Catalogues"], + */ + ["Journal", "Journal Aggregator\/Publisher"], + ["OpenAIRE Basic (DRIVER OA)","OpenAIRE 2.0 (EC funding)", "OpenAIRE 2.0+ (DRIVER OA, EC funding)", "OpenAIRE 3.0 (OA, funding)","OpenAIRE Data (funded, referenced datasets)"]]; + + var value_original_ids=[ + ["pubsrepository::journal", "aggregator::pubsrepository::journals"], + //["driver","openaire2.0", "driver-openaire2.0", "openaire3.0","openaire2.0_data"] + ["OpenAIRE Basic (DRIVER OA)","OpenAIRE 2.0 (EC funding)", "OpenAIRE 2.0+ (DRIVER OA, EC funding)", "OpenAIRE 3.0 (OA, funding)","OpenAIRE Data (funded, referenced datasets)"]]; + var filters: Filter[] =[]; + for(var i =0 ; i < filter_names.length;i++){ + var values:Value[] = []; + for(var j =0 ; j < value_names[i].length;j++){ + var value:Value = {name: value_names[i][j], id: value_original_ids[i][j], number:j, selected:false} + values.push(value); + } + var filter:Filter = {title: filter_names[i], filterId: filter_ids[i], originalFilterId: filter_original_ids[i], values : values, countSelectedValues:0, "filterOperator": 'or' }; + filters.push(filter); + } + return filters; + } +} diff --git a/portal-4cli/src/app/searchPages/dataProviders/journals.module.ts b/portal-4cli/src/app/searchPages/dataProviders/journals.module.ts new file mode 100644 index 00000000..c8c76b1e --- /dev/null +++ b/portal-4cli/src/app/searchPages/dataProviders/journals.module.ts @@ -0,0 +1,32 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{ JournalsRoutingModule} from './journals-routing.module'; +import{SearchJournalsComponent} from './journals.component'; + +import {SearchResultsModule } from '../searchUtils/searchResults.module'; + +import {DataProvidersServiceModule} from '../../services/dataProvidersService.module'; +import {SearchFormModule} from '../searchUtils/searchForm.module'; +//import {SearchFilterModalModule} from '../searchUtils/searchFilterModal.module'; +import {SearchPageModule} from '../searchUtils/searchPage.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + DataProvidersServiceModule, + SearchFormModule, SearchResultsModule, JournalsRoutingModule, SearchPageModule + + ], + declarations: [ + SearchJournalsComponent + ], + providers:[FreeGuard, IsRouteEnabled], + exports: [ + SearchJournalsComponent + ] +}) +export class JournalsModule { } diff --git a/portal-4cli/src/app/searchPages/dataProviders/journalsTable-routing.module.ts b/portal-4cli/src/app/searchPages/dataProviders/journalsTable-routing.module.ts new file mode 100644 index 00000000..de701dcd --- /dev/null +++ b/portal-4cli/src/app/searchPages/dataProviders/journalsTable-routing.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import{SearchJournalsTableComponent} from './journalsTable.component'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: SearchJournalsTableComponent, canActivate: [FreeGuard, IsRouteEnabled], data: { + redirect: '/error' + } , canDeactivate: [PreviousRouteRecorder] } + + ]) + ] +}) +export class JournalsTableRoutingModule { } diff --git a/portal-4cli/src/app/searchPages/dataProviders/journalsTable.component.ts b/portal-4cli/src/app/searchPages/dataProviders/journalsTable.component.ts new file mode 100644 index 00000000..4322a268 --- /dev/null +++ b/portal-4cli/src/app/searchPages/dataProviders/journalsTable.component.ts @@ -0,0 +1,191 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import { ActivatedRoute} from '@angular/router'; + +import { Filter, Value} from '../searchUtils/searchHelperClasses.class'; + +import {SearchDataprovidersService} from '../../services/searchDataproviders.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchFields} from '../../utils/properties/searchFields'; +import {SearchPageTableViewComponent } from '../searchUtils/searchPageTableView.component'; +import {SearchUtilsClass } from '../searchUtils/searchUtils.class'; + +@Component({ + selector: 'search-journals-table', + template: ` + + + + ` + +}) +export class SearchJournalsTableComponent { + private errorCodes: ErrorCodes; + + public results =[]; + public filters =[]; + public baseUrl:string; + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public sub: any; public subResults: any; + public _location:Location; + public searchFields:SearchFields = new SearchFields(); + public refineFields: string[] = this.searchFields.JOURNAL_FIELDS; + + /*public CSV: any = { "columnNames": [ "Title", "Type", "Coutries", "Compatibility" ], + "export":[] + }; + public CSVDownloaded = false; + public csvParams: string; + public resourcesQuery = "&query=((oaftype exact datasource) not(datasourcecompatibilityid = UNKNOWN) not(datasourcecompatibilityid = notCompatible) not(datasourcetypeuiid = other))";*/ + + public disableForms: boolean = false; + + @ViewChild (SearchPageTableViewComponent) searchPage : SearchPageTableViewComponent ; + + constructor (private route: ActivatedRoute, private _searchDataprovidersService: SearchDataprovidersService ) { + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.baseUrl = OpenaireProperties.getLinkToSearchJournalsTable(); + } + + public ngOnInit() { + this.searchPage.refineFields = this.refineFields; + this.sub = this.route.queryParams.subscribe(params => { + this.searchUtils.keyword = (params['keyword']?params['keyword']:''); + //this.searchUtils.page = (params['page']=== undefined)?1:+params['page']; + this.filters = this.createFilters(); + this.searchPage.getParametersFromUrl(params); + this._getResults(); + }); + } + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } } + private _getResults(){ + //this.csvParams = this.resourcesQuery+"&type=datasources"; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + let size: number = 0; + this.subResults = this._searchDataprovidersService.searchJournalsTable().subscribe( + data => { + size = data; + if(size > 0) { + this.subResults = this._searchDataprovidersService.searchJournals("", null, 1, size, []).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Journals [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + this.searchPage.checkSelectedFilters(this.filters); + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + this.disableForms = false; + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + this.disableForms = false; + + } + ); + } else { + this.searchPage.checkSelectedFilters(this.filters); + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.NONE; + this.disableForms = false; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + + } + private setFilters(){ + //TODO set filters from + } + + private createFilters():Filter[] { + var filter_names=["Type","Compatibility Level"]; + var filter_ids=["datasourcetypeuiid","datasourcecompatibilityname"]; + var searchFields = new SearchFields(); + var filter_original_ids = searchFields.JOURNAL_FIELDS; + var value_names=[ + /*[ + "Institutional Publication Repository","Thematic Publication Repository", "Other Publication Repository", + "Institutional Repositories Aggregators", + "Thematic Repositories Aggregators", "Other Repositories Aggregators", + "Data Repositories", "Data Repositories Aggregators", "Journals", "Journals Aggregators", "CRIS Systems", "Publication Catalogues"], + */ + ["Journal", "Journal Aggregator\/Publisher"], + + + + + ["OpenAIRE Basic (DRIVER OA)","OpenAIRE 2.0 (EC funding)", "OpenAIRE 2.0+ (DRIVER OA, EC funding)", "OpenAIRE 3.0 (OA, funding)","OpenAIRE Data (funded, referenced datasets)"]]; + + var value_original_ids=[ + ["pubsrepository::journal", "aggregator::pubsrepository::journals"], + //["driver","openaire2.0", "driver-openaire2.0", "openaire3.0","openaire2.0_data"] + ["OpenAIRE Basic (DRIVER OA)","OpenAIRE 2.0 (EC funding)", "OpenAIRE 2.0+ (DRIVER OA, EC funding)", "OpenAIRE 3.0 (OA, funding)","OpenAIRE Data (funded, referenced datasets)"]]; + var filters: Filter[] =[]; + for(var i =0 ; i < filter_names.length;i++){ + var values:Value[] = []; + for(var j =0 ; j < value_names[i].length;j++){ + var value:Value = {name: value_names[i][j], id: value_original_ids[i][j], number:j, selected:false} + values.push(value); + } + var filter:Filter = {title: filter_names[i], filterId: filter_ids[i], originalFilterId: filter_original_ids[i], values : values, countSelectedValues:0, "filterOperator": 'or' }; + filters.push(filter); + } + return filters; + } +} diff --git a/portal-4cli/src/app/searchPages/dataProviders/journalsTable.module.ts b/portal-4cli/src/app/searchPages/dataProviders/journalsTable.module.ts new file mode 100644 index 00000000..307dcb89 --- /dev/null +++ b/portal-4cli/src/app/searchPages/dataProviders/journalsTable.module.ts @@ -0,0 +1,32 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{ JournalsTableRoutingModule} from './journalsTable-routing.module'; +import{SearchJournalsTableComponent} from './journalsTable.component'; + +//import {DatasourceTableViewModule } from '../searchUtils/datasourceTableView.module'; + +import {DataProvidersServiceModule} from '../../services/dataProvidersService.module'; +import {SearchFormModule} from '../searchUtils/searchForm.module'; +//import {SearchFilterModalModule} from '../searchUtils/searchFilterModal.module'; +import {SearchPageTableViewModule} from '../searchUtils/searchPageTableView.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + DataProvidersServiceModule, + SearchFormModule, JournalsTableRoutingModule, SearchPageTableViewModule + + ], + declarations: [ + SearchJournalsTableComponent + ], + providers:[FreeGuard, IsRouteEnabled], + exports: [ + SearchJournalsTableComponent + ] +}) +export class JournalsTableModule { } diff --git a/portal-4cli/src/app/searchPages/find/mainSearch-routing.module.ts b/portal-4cli/src/app/searchPages/find/mainSearch-routing.module.ts new file mode 100644 index 00000000..69df52f5 --- /dev/null +++ b/portal-4cli/src/app/searchPages/find/mainSearch-routing.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import{SearchComponent} from './search.component'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: SearchComponent, canActivate: [FreeGuard], canDeactivate: [PreviousRouteRecorder] } + + ]) + ] +}) +export class MainSearchRoutingModule { } diff --git a/portal-4cli/src/app/searchPages/find/mainSearch.module.ts b/portal-4cli/src/app/searchPages/find/mainSearch.module.ts new file mode 100644 index 00000000..fe01546d --- /dev/null +++ b/portal-4cli/src/app/searchPages/find/mainSearch.module.ts @@ -0,0 +1,41 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import{MainSearchRoutingModule} from './mainSearch-routing.module'; +import{SearchComponent} from './search.component'; + +import {SearchResultsModule } from '../searchUtils/searchResults.module'; + +import {DataProvidersServiceModule} from '../../services/dataProvidersService.module'; +import {DatasetsServiceModule} from '../../services/datasetsService.module'; +import {SoftwareServiceModule} from '../../services/softwareService.module'; +import {ProjectsServiceModule} from '../../services/projectsService.module'; +import {PublicationsServiceModule} from '../../services/publicationsService.module'; +import {OrganizationsServiceModule} from '../../services/organizationsService.module'; +import {BrowseEntitiesModule} from '../searchUtils/browseEntities.module'; +import {SearchFormModule} from '../searchUtils/searchForm.module'; +//import {SearchFilterModalModule} from '../searchUtils/searchFilterModal.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PiwikServiceModule} from '../../utils/piwik/piwikService.module'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, RouterModule, + DataProvidersServiceModule, DatasetsServiceModule, SoftwareServiceModule, ProjectsServiceModule, + PublicationsServiceModule, OrganizationsServiceModule, + BrowseEntitiesModule, SearchFormModule, SearchResultsModule, MainSearchRoutingModule, PiwikServiceModule + + ], + declarations: [ + SearchComponent + ], + providers:[FreeGuard, PreviousRouteRecorder + ], + exports: [ + SearchComponent + ] +}) +export class MainSearchModule { } diff --git a/portal-4cli/src/app/searchPages/find/search.component.html b/portal-4cli/src/app/searchPages/find/search.component.html new file mode 100644 index 00000000..16d936d9 --- /dev/null +++ b/portal-4cli/src/app/searchPages/find/search.component.html @@ -0,0 +1,241 @@ + + +
    +
    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + + + + + +
    + +
    +
    +
    +
    diff --git a/portal-4cli/src/app/searchPages/find/search.component.ts b/portal-4cli/src/app/searchPages/find/search.component.ts new file mode 100644 index 00000000..056c34e1 --- /dev/null +++ b/portal-4cli/src/app/searchPages/find/search.component.ts @@ -0,0 +1,400 @@ +import {Component, Input, Output, EventEmitter, ViewChild, ChangeDetectionStrategy, ViewEncapsulation} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {ActivatedRoute, Router} from '@angular/router'; +import {Location} from '@angular/common'; + +import { Meta, MetaDefinition} from '../../../angular2-meta'; + +import { FetchPublications } from '../../utils/fetchEntitiesClasses/fetchPublications.class'; +import { FetchDataproviders } from '../../utils/fetchEntitiesClasses/fetchDataproviders.class'; +import { FetchProjects } from '../../utils/fetchEntitiesClasses/fetchProjects.class'; +import { FetchDatasets } from '../../utils/fetchEntitiesClasses/fetchDatasets.class'; +import { FetchSoftware } from '../../utils/fetchEntitiesClasses/fetchSoftware.class'; +import { FetchOrganizations } from '../../utils/fetchEntitiesClasses/fetchOrganizations.class'; + +import {SearchPublicationsService} from '../../services/searchPublications.service'; +import {SearchDataprovidersService} from '../../services/searchDataproviders.service'; +import {SearchProjectsService} from '../../services/searchProjects.service'; +import {SearchDatasetsService} from '../../services/searchDatasets.service'; +import {SearchSoftwareService} from '../../services/searchSoftware.service'; +import {SearchOrganizationsService} from '../../services/searchOrganizations.service'; + +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; +import {SearchFields} from '../../utils/properties/searchFields'; +import {ErrorCodes} from '../../utils/properties/openaireProperties'; +import {RouterHelper} from '../../utils/routerHelper.class'; +import {RefineFieldResultsService} from '../../services/refineFieldResults.service'; +import {PiwikService} from '../../utils/piwik/piwik.service'; +import { ConfigurationService } from '../../utils/configuration/configuration.service'; + +@Component({ + changeDetection: ChangeDetectionStrategy.Default, + encapsulation: ViewEncapsulation.Emulated, + selector: 'search-find', + templateUrl: 'search.component.html' +}) +export class SearchComponent { + public sub: any; piwiksub: any; + public reloadPublications: boolean; + public reloadDatasets: boolean; + public reloadSoftware: boolean; + public reloadProjects: boolean; + public reloadDataproviders: boolean; + public reloadOrganizations: boolean; + + + public pageTitle = "Search in OpenAIRE" + public keyword:string = ""; + public publications:string[]; + public datasets:string[]; + public software:string[]; + public projectsTab:string[]; + public dataproviders:string[]; + public organizations:string[]; + + public activeTab = "publications"; + public linkToSearchPublications = ""; + public linkToSearchProjects = ""; + public linkToSearchDataproviders = ""; + public linkToSearchDatasets = ""; + public linkToSearchSoftware = ""; + public linkToSearchOrganizations = ""; + + public fetchPublications : FetchPublications; + public fetchDataproviders : FetchDataproviders; + public fetchProjects : FetchProjects; + public fetchDatasets: FetchDatasets; + public fetchSoftware: FetchSoftware; + public fetchOrganizations: FetchOrganizations; + + public searchFields:SearchFields = new SearchFields(); + public errorCodes:ErrorCodes = new ErrorCodes(); + public routerHelper:RouterHelper = new RouterHelper(); + + public publicationsSize:any = null; + public datasetsSize:any = null; + public softwareSize:any = null; + public fundersSize:any = null; + public projectsSize:any = null; + public datasourcesSize:any = null; + showPublications:boolean= false; + showDatasets:boolean= false; + showSoftware:boolean=false; + showProjects:boolean= false; + showDataProviders:boolean= false; + showOrganizations:boolean= false; +public subPub;public subData;public subProjects;public subOrg; public subDataPr; + constructor ( private route: ActivatedRoute, + private _router: Router, + private _searchPublicationsService: SearchPublicationsService, + private _searchDataprovidersService: SearchDataprovidersService, + private _searchProjectsService: SearchProjectsService, + private _searchDatasetsService: SearchDatasetsService, + private _searchSoftwareService: SearchSoftwareService, + private _searchOrganizationsService: SearchOrganizationsService, + private _refineFieldResultsService:RefineFieldResultsService, + private location: Location, private _meta: Meta,private _piwikService:PiwikService, + private config: ConfigurationService ) { + this.fetchPublications = new FetchPublications(this._searchPublicationsService); + this.fetchDataproviders = new FetchDataproviders(this._searchDataprovidersService); + this.fetchProjects = new FetchProjects(this._searchProjectsService); + this.fetchDatasets = new FetchDatasets( this._searchDatasetsService); + this.fetchSoftware = new FetchSoftware(this._searchSoftwareService); + this.fetchOrganizations = new FetchOrganizations( this._searchOrganizationsService); + + var description = "open access, research, scientific publication, European Commission, EC, FP7, ERC, Horizon 2020, H2020, search, projects "; + + var title = "OpenAIRE | Search publications, research data, projects... | OpenAIRE"; + + var url = OpenaireProperties.getBaseLink()+this._router.url; + this._meta.setTitle(title); + this._meta.updateMeta("description", description); + this._meta.updateProperty("og:description", description); + this._meta.updateProperty("og:title", title); + this._meta.updateProperty("og:url", url); + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.piwiksub = this._piwikService.trackView("OpenAIRE |Search publications, research data, projects...").subscribe(); + + } + + + + } + + public ngOnInit() { + const entityOne = this.config.isEntityEnabled("publication"); + const entityTwo = this.config.isEntityEnabled("dataset"); + const entityThree = this.config.isEntityEnabled("project"); + const entityFour = this.config.isEntityEnabled("organization"); + const entityFive = this.config.isEntityEnabled("datasource"); + const entitySix = this.config.isEntityEnabled("software"); + const example = Observable.zip(entityOne,entityTwo,entityThree,entityFour,entityFive,entitySix); + +//wait until all observables have emitted a value then emit all as an array + this.sub = this.route.queryParams.subscribe(params => { + const subscribe = example.subscribe(data => { + this.showPublications = data[0]; + this.showDatasets = data[1]; + this.showProjects = data[2]; + this.showOrganizations = data[3]; + this.showDataProviders = data[4]; + this.showSoftware = data[5]; + console.log(data) + this.keyword = (params['keyword'])?params['keyword']:""; + if(this.keyword !=null && this.keyword.length > 0){ + this.reloadTabs(); + //if showPublications == false will set another entity as the first + if(this.showPublications){ + this.activeTab = "publications"; + this.searchPublications(); + }else if(this.showDatasets){ + this.activeTab = "research data"; + this.searchDatasets(); + }else if(this.showSoftware){ + this.activeTab = "software"; + this.searchSoftware(); + }else if(this.showProjects){ + this.activeTab = "projects"; + this.searchProjects(); + }else if(this.showDataProviders){ + this.activeTab = "content providers"; + this.searchDataProviders(); + }else if(this.showOrganizations){ + this.activeTab = "organizations"; + this.searchOrganizations(); + } + this.count(); + } + }); + }); + + } + public ngOnDestroy() { + this.sub.unsubscribe(); + if(this.piwiksub){ + this.piwiksub.unsubscribe(); +} + if(this.keyword !=null && this.keyword.length > 0){ + if(this.subPub){ + this.subPub.unsubscribe(); + } + if(this.subData){ + this.subData.unsubscribe(); + } + if(this.subProjects){ + this.subProjects.unsubscribe(); + } + if(this.subOrg){ + this.subOrg.unsubscribe(); + } + if(this.subDataPr){ + this.subDataPr.unsubscribe(); + } + + } + } + public searchPublications() { + this.activeTab = "publications"; + if( this.reloadPublications && + this.fetchPublications.searchUtils.status != this.errorCodes.NONE && + this.fetchPublications.searchUtils.status != this.errorCodes.ERROR) { + this.reloadPublications = false; + this.fetchPublications.getResultsByKeyword(this.keyword, 1, 10); + this.linkToSearchPublications = OpenaireProperties.getLinkToSearchPublications();// + "?keyword=" + this.keyword; + } + } + public searchDatasets() { + this.activeTab = "research data"; + if(this.reloadDatasets && + this.fetchDatasets.searchUtils.status != this.errorCodes.NONE && + this.fetchDatasets.searchUtils.status != this.errorCodes.ERROR) { + this.reloadDatasets = false; + this.fetchDatasets.getResultsByKeyword(this.keyword, 1, 10); + this.linkToSearchDatasets = OpenaireProperties.getLinkToSearchDatasets();// + "?keyword=" + this.keyword; + } + } + public searchSoftware() { + this.activeTab = "software"; + if(this.reloadSoftware && + ( this.fetchSoftware.searchUtils.status == this.errorCodes.LOADING || + this.fetchSoftware.searchUtils.status == this.errorCodes.DONE )) { + this.reloadSoftware = false; + this.fetchSoftware.getResultsByKeyword(this.keyword, 1, 10); + this.linkToSearchSoftware = OpenaireProperties.getLinkToSearchSoftware();// + "?keyword=" + this.keyword; + } + } + public searchProjects() { + this.activeTab = "projects"; + if(this.reloadProjects && + this.fetchProjects.searchUtils.status != this.errorCodes.NONE && + this.fetchProjects.searchUtils.status != this.errorCodes.ERROR) { + this.reloadProjects = false; + this.fetchProjects.getResultsByKeyword(this.keyword, 1, 10); + this.linkToSearchProjects = OpenaireProperties.getLinkToSearchProjects();// + "?keyword=" + this.keyword; + } + } + public searchDataProviders() { + this.activeTab = "content providers"; + if( this.reloadDataproviders && + this.fetchDataproviders.searchUtils.status != this.errorCodes.NONE && + this.fetchDataproviders.searchUtils.status != this.errorCodes.ERROR) { + this.reloadDataproviders = false; + this.fetchDataproviders.getResultsByKeyword(this.keyword, 1, 10); + this.linkToSearchDataproviders = OpenaireProperties.getLinkToSearchDataProviders();// + "?keyword=" + this.keyword; + } + } + public searchOrganizations() { + this.activeTab = "organizations"; + if( this.reloadOrganizations && + this.fetchOrganizations.searchUtils.status != this.errorCodes.NONE && + this.fetchOrganizations.searchUtils.status != this.errorCodes.ERROR) { + this.reloadOrganizations = false; + this.fetchOrganizations.getResultsByKeyword(this.keyword, 1, 10); + this.linkToSearchOrganizations = OpenaireProperties.getLinkToSearchOrganizations();// + "?keyword=" + this.keyword; + } + } + + + public keywordChanged($event){ + + this.keyword = $event.value; + console.info("Search Find: search with keyword \"" + this.keyword + "\"" ); + this.location.go(location.pathname,"?keyword=" + this.keyword); + this.reloadTabs(); + if(this.activeTab == "publications") { + this.searchPublications(); + } + if(this.activeTab == "projects") { + this.searchProjects(); + } + if(this.activeTab == "content providers") { + this.searchDataProviders(); + } + if(this.activeTab == "research data") { + this.searchDatasets(); + } + if(this.activeTab == "software") { + this.searchSoftware(); + } + if(this.activeTab == "organizations") { + this.searchOrganizations(); + } + + this.count(); + } + + private count() { + if(this.activeTab != "publications" && this.showPublications){ + this.fetchPublications.searchUtils.status = this.errorCodes.LOADING; + this.fetchPublications.results = []; + this.subPub = this._searchPublicationsService.numOfSearchPublications(this.keyword).subscribe( + data => { + console.log("Count results: "+data); + this.fetchPublications.searchUtils.totalResults = data; + this.fetchPublications.searchUtils.status = this.errorCodes.DONE; + if(this.fetchPublications.searchUtils.totalResults == 0) { + this.fetchPublications.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + this.fetchPublications.searchUtils.status = this.errorCodes.ERROR; + } + ); + } + if(this.activeTab != "research data" && this.showDatasets){ + this.fetchDatasets.searchUtils.status = this.errorCodes.LOADING; + this.fetchDatasets.results = []; + this.subData = this._searchDatasetsService.numOfSearchDatasets(this.keyword).subscribe( + data => { + this.fetchDatasets.searchUtils.totalResults = data; + this.fetchDatasets.searchUtils.status = this.errorCodes.DONE; + if(this.fetchDatasets.searchUtils.totalResults == 0) { + this.fetchDatasets.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + this.fetchDatasets.searchUtils.status = this.errorCodes.ERROR; + } + ); + } + if(this.activeTab != "software" && this.showSoftware){ + this.fetchSoftware.searchUtils.status = this.errorCodes.LOADING; + this.fetchSoftware.results = []; + this.subData = this._searchSoftwareService.numOfSearchSoftware(this.keyword).subscribe( + data => { + this.fetchSoftware.searchUtils.totalResults = data; + this.fetchSoftware.searchUtils.status = this.errorCodes.DONE; + if(this.fetchSoftware.searchUtils.totalResults == 0) { + this.fetchSoftware.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + if(err.status == '404') { + this.fetchSoftware.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.fetchSoftware.searchUtils.status = this.errorCodes.ERROR; + } else { + this.fetchSoftware.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + //this.fetchSoftware.searchUtils.status = this.errorCodes.ERROR; + } + ); + } + if(this.activeTab != "projects" && this.showProjects){ + this.fetchProjects.searchUtils.status = this.errorCodes.LOADING; + this.fetchProjects.results = []; + this.subProjects = this._searchProjectsService.numOfSearchProjects(this.keyword).subscribe( + data => { + this.fetchProjects.searchUtils.totalResults = data; + this.fetchProjects.searchUtils.status = this.errorCodes.DONE; + if(this.fetchProjects.searchUtils.totalResults == 0) { + this.fetchProjects.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + this.fetchProjects.searchUtils.status = this.errorCodes.ERROR; + } + ); + } + if(this.activeTab != "content providers" && this.showDataProviders){ + this.fetchDataproviders.results = []; + this.fetchDataproviders.getNumForSearch(this.keyword); + } + if(this.activeTab != "organizations" && this.showOrganizations){ + this.fetchOrganizations.searchUtils.status = this.errorCodes.LOADING; + this.fetchOrganizations.results = []; + this.subOrg = this._searchOrganizationsService.numOfSearchOrganizations(this.keyword).subscribe( + data => { + this.fetchOrganizations.searchUtils.totalResults = data; + this.fetchOrganizations.searchUtils.status = this.errorCodes.DONE; + if(this.fetchOrganizations.searchUtils.totalResults == 0) { + this.fetchOrganizations.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + this.fetchOrganizations.searchUtils.status = this.errorCodes.ERROR; + + } + ); + } + + + } + + private reloadTabs() { + this.reloadPublications = true; + this.reloadDatasets = true; + this.reloadSoftware = true; + this.reloadProjects = true; + this.reloadDataproviders = true; + this.reloadOrganizations = true; + } + + + +} diff --git a/portal-4cli/src/app/searchPages/searchUtils/advancedSearchForm.component.html b/portal-4cli/src/app/searchPages/searchUtils/advancedSearchForm.component.html new file mode 100644 index 00000000..938ca3cd --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/advancedSearchForm.component.html @@ -0,0 +1,56 @@ + +
    + + + + + + + + + + + + + + + + +
    Search for: + + + + + + + + Yes
    +
    + + No
    +
    +
    + + + + + + + + +
    +
    + +
    + +
    diff --git a/portal-4cli/src/app/searchPages/searchUtils/advancedSearchForm.component.ts b/portal-4cli/src/app/searchPages/searchUtils/advancedSearchForm.component.ts new file mode 100644 index 00000000..1e7ef861 --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/advancedSearchForm.component.ts @@ -0,0 +1,95 @@ +import {Component, Input, Output, EventEmitter, ElementRef} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import { Subject } from 'rxjs/Subject'; + +import {AdvancedField, OPERATOR} from '../searchUtils/searchHelperClasses.class'; +import {SearchFields} from '../../utils/properties/searchFields'; +import {Dates} from '../../utils/string-utils.class'; + +@Component({ + selector: 'advanced-search-form', + templateUrl: 'advancedSearchForm.component.html' +}) +export class AdvancedSearchFormComponent { + @Input() entityType; + @Input() fieldIds: string[]; + @Input() fieldIdsMap; + @Input() selectedFields:AdvancedField[]; + @Input() isDisabled: boolean = false; + + @Output() queryChange = new EventEmitter(); + newFieldId:string; + newFieldName:string; + fieldList:{[id:string]:any[]} = {}; + public searchFields:SearchFields = new SearchFields(); + + public operators: [{name:string, id:string}] = this.searchFields.ADVANCED_SEARCH_OPERATORS; + constructor () { + } + + ngOnInit() { + for(var i = 0; i < this.fieldIds.length; i++){ + this.fieldList[this.fieldIds[i]]=[]; + } + this.newFieldId = this.fieldIds[0]; + this.newFieldName = this.fieldIdsMap[this.newFieldId].name; + } + + queryChanged() { + this.queryChange.emit({ + // selectedFields: this.selectedFields, + // selectedQuantifiers: this.selectedQuantifiers, + // keywords: this.keywords + }); + } + + addField() { + this.newFieldId = this.fieldIds[0]; + var type = this.fieldIdsMap[this.newFieldId].type; + if(type == "boolean"){ + this.selectedFields.push(new AdvancedField(this.newFieldId,this.fieldIdsMap[this.newFieldId].param, this.fieldIdsMap[this.newFieldId].name, type, "true", "and")); + }else{ + this.selectedFields.push(new AdvancedField(this.newFieldId, this.fieldIdsMap[this.newFieldId].param,this.fieldIdsMap[this.newFieldId].name, type, "", "and")); + } + + } + + removeField(index: number) { + this.selectedFields.splice(index, 1); + + } + + fieldOperatorChanged(index: number, operatorId: string, operatorName: string) { + this.selectedFields[index].operatorId = operatorId; + this.selectedFields[index].operatorName = operatorName; + } + validateDate(index: number, value: string){ + this.selectedFields[index].valid = Dates.isValidYear(value); + } + + fieldIdsChanged(index: number, fieldId:string ) { + console.log("Field index::"+index + " " + this.selectedFields[index].id + " function id:" +fieldId); + + var id= this.fieldIds[0]; + this.selectedFields[index].name = this.fieldIdsMap[id].name; + this.selectedFields[index].type = this.fieldIdsMap[id].type; + this.selectedFields[index].value = ""; + this.selectedFields[index].param = this.fieldIdsMap[id].param; + + var id =fieldId;//this.selectedFields[index].id; + this.selectedFields[index].name = this.fieldIdsMap[id].name; + this.selectedFields[index].type = this.fieldIdsMap[id].type; + this.selectedFields[index].value = ""; + this.selectedFields[index].param = this.fieldIdsMap[id].param; + if(this.fieldIdsMap[id].type == "boolean"){ + this.selectedFields[index].value = "true"; + } + } + valueChanged($event,index:number){ + this.selectedFields[index].value = $event.value; + } + listUpdated($event,fieldId:number){ + this.fieldList[fieldId] = $event.value; + } + +} diff --git a/portal-4cli/src/app/searchPages/searchUtils/advancedSearchForm.module.ts b/portal-4cli/src/app/searchPages/searchUtils/advancedSearchForm.module.ts new file mode 100644 index 00000000..1ee2f437 --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/advancedSearchForm.module.ts @@ -0,0 +1,26 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{AdvancedSearchFormComponent} from './advancedSearchForm.component'; +import {EntitiesAutocompleteModule} from '../../utils/entitiesAutoComplete/entitiesAutoComplete.module'; +import {StaticAutocompleteModule} from '../../utils/staticAutoComplete/staticAutoComplete.module'; +import {DateFilterModule} from './dateFilter.module'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule, EntitiesAutocompleteModule, StaticAutocompleteModule, DateFilterModule + ], + declarations: [ + AdvancedSearchFormComponent, +], + + providers:[ + ], + exports: [ + AdvancedSearchFormComponent + + ] +}) +export class AdvancedSearchFormModule { } diff --git a/portal-4cli/src/app/searchPages/searchUtils/advancedSearchPage.component.html b/portal-4cli/src/app/searchPages/searchUtils/advancedSearchPage.component.html new file mode 100644 index 00000000..e27fa9ed --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/advancedSearchPage.component.html @@ -0,0 +1,61 @@ +
    +
    +
    +
    +
    + {{pageTitle}} +
    +
    + Simple search + + + + +
    + +
    +
    + +
    +
    + +
    + + + +
    + + +
    +
    + +
    + + + +
    +
    + + +
    + +
    + +
    + +
    +
    +
    + +
    +
    +
    diff --git a/portal-4cli/src/app/searchPages/searchUtils/advancedSearchPage.component.ts b/portal-4cli/src/app/searchPages/searchUtils/advancedSearchPage.component.ts new file mode 100644 index 00000000..a668f7af --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/advancedSearchPage.component.ts @@ -0,0 +1,254 @@ +import {Component, Input, ViewChild, Output, EventEmitter} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {Location} from '@angular/common'; +import { Router} from '@angular/router'; +import {Filter, Value,AdvancedField} from '../searchUtils/searchHelperClasses.class'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {SearchFields} from '../../utils/properties/searchFields'; +import {SearchUtilsClass} from './searchUtils.class'; +import {ModalLoading} from '../../utils/modal/loading.component'; +import {StringUtils, Dates} from '../../utils/string-utils.class'; +import { Meta} from '../../../angular2-meta'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; +import {PiwikService} from '../../utils/piwik/piwik.service'; + +@Component({ + selector: 'advanced-search-page', + templateUrl: 'advancedSearchPage.component.html' +}) +export class AdvancedSearchPageComponent { + @Input() pageTitle = ""; + @Input() results = []; + @Input() type; + @Input() entityType; + @Input() searchUtils:SearchUtilsClass = new SearchUtilsClass(); + @Input() fieldIds: string[]; + @Input() fieldIdsMap;//:{ [key:string]:{ name:string, operator:string, type:string, indexField:string, equalityOperator:string }} ; + @Input() selectedFields:AdvancedField[]; + @Input() simpleSearchUrl: string; + @ViewChild (ModalLoading) loading : ModalLoading ; + @Input() csvParams: string; + @Input() csvPath: string; + @Input() simpleSearchLink: string = ""; + @Input() disableForms:boolean = false; + @Input() loadPaging: boolean = true; + @Input() oldTotalResults: number = 0; + + piwiksub: any; + public parameterNames:string[] =[]; + public parameterValues:string[] =[]; + + public baseURLWithParameters:string = ''; + + @Output() queryChange = new EventEmitter(); + constructor (private location: Location, private _meta: Meta, private _piwikService:PiwikService, private router: Router) { + } + + ngOnInit() { + this.updateTitle("Advanced search "+this.pageTitle); + this.updateDescription("Openaire, search, repositories, open access, type, content provider, funder, project, "+ this.pageTitle); + if(typeof window !== 'undefined') { + this.updateUrl(OpenaireProperties.getBaseLink()+location.pathname); + } + + this.searchUtils.baseUrl = "/" + this.searchUtils.baseUrl; + this.updateBaseUrlWithParameters(); + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.piwiksub = this._piwikService.trackView(this.pageTitle).subscribe(); + } + } + + ngOnDestroy() { + if(this.piwiksub){ + this.piwiksub.unsubscribe(); +} + } + updateDescription(description:string){ + this._meta.updateMeta("description", description); + this._meta.updateProperty("og:description", description); + } + updateTitle(title:string){ + var _prefix ="OpenAIRE | "; + var _title = _prefix + ((title.length> 50 ) ?title.substring(0,50):title); + this._meta.setTitle(_title ); + this._meta.updateProperty("og:title",_title); + } + updateUrl(url:string){ + this._meta.updateProperty("og:url", url); + } + + public getSelectedFiltersFromUrl(params){ + for(var i=0; i< this.fieldIds.length ; i++){ + + var fieldId = this.fieldIds[i]; + var fieldparam = (this.fieldIdsMap[fieldId])?this.fieldIdsMap[fieldId].param:""; + if(!this.fieldIdsMap[fieldId]){ + + console.error("Field: "+fieldId +" not found in fieldIds map"); + } + + var operatorId = this.getOperatorParameter(fieldparam); + if(params[fieldparam] != undefined && params[operatorId] != undefined) { + var values:string [] = StringUtils.URIDecode(params[fieldparam]).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/,-1); + var operators:string [] = (StringUtils.URIDecode(params[operatorId])).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/,-1); + if(values.length == operators.length){ + for(var j=0; j< values.length ; j++){ + if(this.fieldIdsMap[fieldId].type == "date"){ + var value:string =StringUtils.unquote(values[j]); + var validDates:boolean = true; + var dateField:AdvancedField = new AdvancedField(fieldId,fieldparam,this.fieldIdsMap[fieldId].name,this.fieldIdsMap[fieldId].type,value,operators[j]) ; + if(value.indexOf("range") != -1){ + dateField.dateValue.type="range"; + if(value.length < 26 ){ + validDates =false; + }else{ + if(!Dates.isValidDate(value.substring(5,15)) || !Dates.isValidDate(value.substring(16,26))){ + validDates =false; + }else { + dateField.dateValue.from = Dates.getDateFromString(value.substring(5,15)); + dateField.dateValue.to = Dates.getDateFromString(value.substring(16,26)); + } + } + // "rangeYYYY-MM-DD:YYYY-MM-DD" + }else{ + dateField.dateValue.setDatesByType(value); + } + if(validDates){ + this.selectedFields.push(dateField); + } + + }else{ + this.selectedFields.push(new AdvancedField(fieldId,fieldparam,this.fieldIdsMap[fieldId].name,this.fieldIdsMap[fieldId].type,StringUtils.unquote(values[j]),operators[j]) ); + } + } + } + } + } + if(this.selectedFields.length == 0){ + this.selectedFields.push(new AdvancedField(this.fieldIds[0],fieldparam,this.fieldIdsMap[this.fieldIds[0]].name,this.fieldIdsMap[this.fieldIds[0]].type,"","and")); + } + } + private createUrlParameters(includePage:boolean){ + var params=""; + this.parameterNames.splice(0,this.parameterNames.length); + this.parameterValues.splice(0,this.parameterValues.length); + var fields: { [key:string]:{ values:string[], operators:string[] }}={}; + for(var i = 0; i< this.selectedFields.length; i++){ + if(this.fieldIdsMap[this.selectedFields[i].id] != undefined && (this.selectedFields[i].value.length > 0 || this.selectedFields[i].type == "date" )){ + if(!fields[this.selectedFields[i].id]){ + fields[this.selectedFields[i].id] = {values:[], operators:[]}; + fields[this.selectedFields[i].id].values =[]; + fields[this.selectedFields[i].id].operators =[]; + } + if(this.selectedFields[i].type == "date"){ + if(this.selectedFields[i].dateValue.type == "range"){ + fields[this.selectedFields[i].id].values.push(StringUtils.quote(StringUtils.URIEncode("range"+Dates.getDateToString(this.selectedFields[i].dateValue.from)+":"+Dates.getDateToString(this.selectedFields[i].dateValue.to)))); + }else{ + fields[this.selectedFields[i].id].values.push(StringUtils.quote(StringUtils.URIEncode(this.selectedFields[i].dateValue.type))); + } + }else{ + fields[this.selectedFields[i].id].values.push(StringUtils.quote(StringUtils.URIEncode(this.selectedFields[i].value))); + } + fields[this.selectedFields[i].id].operators.push(this.selectedFields[i].operatorId); + + } + } + for(var i = 0; i< this.fieldIds.length; i++){ + if(fields[this.fieldIds[i]]){ + + params+="&"+this.fieldIdsMap[this.fieldIds[i]].param+"="+fields[this.fieldIds[i]].values.join()+ + "&"+this.getOperatorParameter(this.fieldIdsMap[this.fieldIds[i]].param)+"="+fields[this.fieldIds[i]].operators.join() + this.parameterNames.push(this.fieldIdsMap[this.fieldIds[i]].param); + this.parameterValues.push(fields[this.fieldIds[i]].values.join()); + this.parameterNames.push(this.getOperatorParameter(this.fieldIdsMap[this.fieldIds[i]].param)); + this.parameterValues.push(fields[this.fieldIds[i]].operators.join()); + } + } + if(includePage && this.searchUtils.page != 1){ + params += "&page="+this.searchUtils.page; + } + return '?'+params; + } + public createQueryParameters(){ + var params=""; + var countParams = 0; + for(var i = 0; i< this.selectedFields.length; i++){ + if(this.fieldIdsMap[this.selectedFields[i].id] != undefined && (this.selectedFields[i].value != "" ||this.selectedFields[i].type == "date")){ + console.log("createQueryParameters::"+this.selectedFields[i].type); + if(this.selectedFields[i].type == "date"){ + if(this.selectedFields[i].dateValue.type != "any"){ + params += (countParams == 0 ? "" : this.selectedFields[i].operatorId) + " " + this.selectedFields[i].id + this.fieldIdsMap[this.selectedFields[i].id].equalityOperator+ '"' + StringUtils.URIEncode(Dates.getDateToString(this.selectedFields[i].dateValue.from)) + " " + + StringUtils.URIEncode(Dates.getDateToString(this.selectedFields[i].dateValue.to)) + '"' + " "; + } + }else{ + if(this.selectedFields[i].id == "q"){ + var op = ""; + // if() + params += (countParams == 0 ? "" : this.selectedFields[i].operatorId) + " " + '"' + StringUtils.URIEncode(this.selectedFields[i].value) + '"' + " "; + }else if(countParams == 0 && this.selectedFields[i].operatorId == "not"){ + params += " "+ this.selectedFields[i].id + " <> "+'"' + StringUtils.URIEncode(this.selectedFields[i].value) +'"' + " "; + }else{ + params += (countParams == 0 ? "" : this.selectedFields[i].operatorId + " " ) + this.selectedFields[i].id + this.fieldIdsMap[this.selectedFields[i].id].equalityOperator+'"' + encodeURIComponent(this.selectedFields[i].value) +'"' + " "; + + } + } + countParams++; + } + } + + return params; + + } + clearFilters(){ + } + + goTo(page:number = 1){ + this.searchUtils.page = page; + var urlParameters = this.createUrlParameters(true); + var queryParameters = this.createQueryParameters(); + this.location.go(location.pathname,urlParameters); + this.queryChange.emit({ + value: queryParameters + }); + /* Code For Piwik*/ + if (typeof localStorage !== 'undefined') { + console.log("In PreviousRouteRecorder : "+this.router.url ); + localStorage.setItem('previousRoute', this.router.url); + } + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.piwiksub = this._piwikService.trackView(this.pageTitle).subscribe(); + } + /* End Piwik Code */ + } + + queryChanged($event) { + + this.goTo(1); + } + pageChanged($event) { + this.searchUtils.page = +$event.value; + this.goTo(this.searchUtils.page); + } + /* + * Update the url with proper parameters. This is used as base url in Paging Component + */ + public updateBaseUrlWithParameters(){ + this.baseURLWithParameters = this.searchUtils.baseUrl + this.createUrlParameters(false); + } + getOperatorParameter(parameter:string):string{ + if(parameter.length > 2){ + return parameter.substring(0,2); + }else if(parameter == "q"){ + return "op"; + }else{ + return parameter+"Op"; + } + } + // for loading + public openLoading(){ + this.loading.open(); + } + public closeLoading(){ + this.loading.close(); + } +} diff --git a/portal-4cli/src/app/searchPages/searchUtils/advancedSearchPage.module.ts b/portal-4cli/src/app/searchPages/searchUtils/advancedSearchPage.module.ts new file mode 100644 index 00000000..df34b56c --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/advancedSearchPage.module.ts @@ -0,0 +1,33 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import{AdvancedSearchPageComponent} from './advancedSearchPage.component'; +import{SearchResultsModule} from './searchResults.module'; +import{LoadingModalModule} from '../../utils/modal/loadingModal.module'; +import {ReportsServiceModule} from '../../services/reportsService.module'; +import {SearchDownloadModule} from './searchDownload.module'; +import{SearchPagingModule} from './searchPaging.module'; + +import {AdvancedSearchFormModule} from '../searchUtils/advancedSearchForm.module'; +import {PiwikServiceModule} from '../../utils/piwik/piwikService.module'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {HelperModule} from '../../utils/helper/helper.module'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, RouterModule, SearchResultsModule, LoadingModalModule, ReportsServiceModule, SearchPagingModule, AdvancedSearchFormModule, SearchDownloadModule, PiwikServiceModule, HelperModule + ], + declarations: [ + AdvancedSearchPageComponent, +], + + providers:[ + PreviousRouteRecorder + ], + exports: [ + AdvancedSearchPageComponent, + ] +}) +export class AdvancedSearchPageModule { } diff --git a/portal-4cli/src/app/searchPages/searchUtils/browseEntities.component.ts b/portal-4cli/src/app/searchPages/searchUtils/browseEntities.component.ts new file mode 100644 index 00000000..36cc7bbe --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/browseEntities.component.ts @@ -0,0 +1,96 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import { ActivatedRoute} from '@angular/router'; +import {Location} from '@angular/common'; + +import { Filter, Value} from '../searchUtils/searchHelperClasses.class'; + +import {RefineFieldResultsService} from '../../services/refineFieldResults.service'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchFields} from '../../utils/properties/searchFields'; +import {SearchPageComponent } from '../searchUtils/searchPage.component'; +import {SearchUtilsClass} from '../searchUtils/searchUtils.class'; + +@Component({ + selector: 'browse-entities', + template: ` +
    + + + +
    +
    + +
    +
    +
    +` + +}) +export class BrowseEntitiesComponent { + public searchFields:SearchFields = new SearchFields(); + public filters =[]; + @Input() public baseUrl:string = ""; + @Input() public entityName:string = ""; + @Input() public refineFields: string[] ;//= this.searchFields.RESULT_REFINE_FIELDS; + public sub: any; + public errorCodes:ErrorCodes = new ErrorCodes(); + public status = this.errorCodes.LOADING; + public fieldIdsMap=this.searchFields.RESULT_REFINE_FIELDS; + + constructor ( private _refineFieldsService: RefineFieldResultsService ) { + // this.baseUrl = OpenaireProperties.getLinkToSearchPublications(); + + } + + public ngOnInit() { + for(var i=0; i < this.searchFields.HIDDEN_FIELDS.length; i++){ + var index = this.refineFields.indexOf(this.searchFields.HIDDEN_FIELDS[i]) ; + if(index > -1){ + this.refineFields.splice(index,1); + + } + } + this.getStats(); + } + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + } + + +private getStats(){ + + this.status = this.errorCodes.LOADING; + this.sub = this._refineFieldsService.getRefineFieldsResultsByEntityName(this.refineFields,this.entityName).subscribe( + data => { + console.info("Get Stats for "+this.entityName+ ": [Total:"+data[0]+" ] [fields: "+data[1].length+"]"); + this.filters = data[1]; + this.status = this.errorCodes.DONE; + if(data[0] == 0 ){ + this.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //this.status = this.errorCodes.ERROR; + if(err.status == '404') { + this.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.status = this.errorCodes.ERROR; + } else { + this.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); +} +} diff --git a/portal-4cli/src/app/searchPages/searchUtils/browseEntities.module.ts b/portal-4cli/src/app/searchPages/searchUtils/browseEntities.module.ts new file mode 100644 index 00000000..2d8d3cda --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/browseEntities.module.ts @@ -0,0 +1,31 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import {RefineFieldResultsServiceModule} from '../../services/refineFieldResultsService.module'; + +import {BrowseEntitiesComponent} from './browseEntities.component'; +import {BrowseStatisticComponent} from './browseStatistic.component'; + +import {ErrorMessagesModule} from '../../utils/errorMessages.module'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, ErrorMessagesModule, + RefineFieldResultsServiceModule, RouterModule + ], + declarations: [ + BrowseEntitiesComponent, + BrowseStatisticComponent + +], + + providers:[ + ], + exports: [ + BrowseEntitiesComponent, + BrowseStatisticComponent + ] +}) +export class BrowseEntitiesModule { } diff --git a/portal-4cli/src/app/searchPages/searchUtils/browseStatistic.component.html b/portal-4cli/src/app/searchPages/searchUtils/browseStatistic.component.html new file mode 100644 index 00000000..3eb79bc6 --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/browseStatistic.component.html @@ -0,0 +1,50 @@ + + {{filter.title}} + + + + + + + diff --git a/portal-4cli/src/app/searchPages/searchUtils/browseStatistic.component.ts b/portal-4cli/src/app/searchPages/searchUtils/browseStatistic.component.ts new file mode 100644 index 00000000..485e6d97 --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/browseStatistic.component.ts @@ -0,0 +1,42 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import { ActivatedRoute} from '@angular/router'; +import {Location} from '@angular/common'; + +import { Filter, Value} from '../searchUtils/searchHelperClasses.class'; + +import {RefineFieldResultsService} from '../../services/refineFieldResults.service'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchFields} from '../../utils/properties/searchFields'; +import {SearchPageComponent } from '../searchUtils/searchPage.component'; +import {SearchUtilsClass} from '../searchUtils/searchUtils.class'; +import {RouterHelper} from '../../utils/routerHelper.class'; +@Component({ + selector: 'browse-statistic', + templateUrl: 'browseStatistic.component.html' + +}) +export class BrowseStatisticComponent { + + @Input() public baseUrl:string = ""; + @Input() public filter:any = ""; + private _maxCharacters = 30; + public viewAll = false; + public routerHelper:RouterHelper = new RouterHelper(); + constructor () { + + } + + public ngOnInit() { + + + } + + quote(str:string){ + return '"'+str+'"'; + } + + private _formatName(value){ + return value.name+" ";//(((value.name+" ("+value.number+")").length >this._maxCharacters)?(value.name.substring(0,(this._maxCharacters - (" ("+value.number+")").length - ('...').length))+"..."):value.name) + } + +} diff --git a/portal-4cli/src/app/searchPages/searchUtils/dateFilter.component.ts b/portal-4cli/src/app/searchPages/searchUtils/dateFilter.component.ts new file mode 100644 index 00000000..f03eb76a --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/dateFilter.component.ts @@ -0,0 +1,73 @@ +import {Component, Input, Output, EventEmitter} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; + +import { Filter, Value, DateValue} from './searchHelperClasses.class'; +import {IMyOptions, IMyDateModel} from '../../utils/my-date-picker/interfaces/index'; +// import {IMyDateModel} from '../../../utils/my-date-picker/interfaces/my-date-model.interface'; +import {Dates} from '../../utils/string-utils.class'; + +@Component({ + selector: 'date-filter', + template: ` + + +
    + + + + +
    + + From + + To
    +
    + ` + +}) + +export class DateFilterComponent { + + @Input() dateValue = new DateValue("any"); + @Input() filterId; + + private myDatePickerOptions: IMyOptions = { + // other options... + dateFormat: 'yyyy-mm-dd', + selectionTxtFontSize: '15px', + height:'28px', + width: '100%', + editableDateField: false, + showClearDateBtn: false + }; + + // Initialized to specific date (09.10.2018). + public from;//: Object = { date: { year: 2018, month: 10, day: 9 } }; + public to;//: Object = { date: { year: 2018, month: 10, day: 9 } }; + +constructor() { + this.updateDefaultRangeDates(this.dateValue.from,this.dateValue.to); +} +updateDefaultRangeDates(df:Date,dt:Date){ + this.from = { date: { year: df.getFullYear(), month: (df.getMonth()+1), day: df.getDate() } }; + this.to = { date: { year: dt.getFullYear(), month: (dt.getMonth()+1), day: dt.getDate() } }; + } +typeChanged(type:string){ + this.dateValue.setDatesByType(type); + this.updateDefaultRangeDates(this.dateValue.from, this.dateValue.to); +} + +onFromDateChanged(event: IMyDateModel) { + this.dateValue.from = Dates.getDateFromString(event.formatted); + +} +onToDateChanged(event: IMyDateModel) { + this.dateValue.to = Dates.getDateFromString(event.formatted); + +}} diff --git a/portal-4cli/src/app/searchPages/searchUtils/dateFilter.module.ts b/portal-4cli/src/app/searchPages/searchUtils/dateFilter.module.ts new file mode 100644 index 00000000..0c5dca82 --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/dateFilter.module.ts @@ -0,0 +1,20 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { MyDatePickerModule } from '../../utils/my-date-picker/my-date-picker.module'; +import {DateFilterComponent} from './dateFilter.component'; +@NgModule({ + imports: [ + CommonModule, FormsModule, MyDatePickerModule + ], + declarations: [ + DateFilterComponent +], + + providers:[ + ], + exports: [ + DateFilterComponent + ] +}) +export class DateFilterModule { } diff --git a/portal-4cli/src/app/searchPages/searchUtils/searchDownload.component.ts b/portal-4cli/src/app/searchPages/searchUtils/searchDownload.component.ts new file mode 100644 index 00000000..55df68d0 --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/searchDownload.component.ts @@ -0,0 +1,112 @@ +import {Component, Input, Output, EventEmitter, ViewChild} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {AlertModal} from '../../utils/modal/alert'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; +import {ReportsService} from '../../services/reports.service'; +import {ModalLoading} from '../../utils/modal/loading.component'; +import {PiwikService} from '../../utils/piwik/piwik.service'; + +@Component({ + selector: 'search-download', + template: ` + + + + (CSV) + + + + + + ` +}) + +export class SearchDownloadComponent { + @Input() totalResults:number = 0; + @Input() csvParams: string; + @Input() type: string; + @ViewChild(AlertModal) alertApplyAll; + private downloadURLAPI: string; + + sub: any; + downloadFilePiwikSub: any; + + @ViewChild (ModalLoading) loading : ModalLoading ; + // Alert box when something is wrong with CSV requests + @ViewChild('AlertModalCsvError') alertCsvError; + + constructor ( private _reportsService: ReportsService, private _piwikService:PiwikService) {} + + ngOnInit() { + this.downloadURLAPI = OpenaireProperties.getCsvAPIURL(); + } + + ngOnDestroy() { + if(this.sub) { + this.sub.unsubscribe(); + } + if(this.downloadFilePiwikSub) { + this.downloadFilePiwikSub.unsubscribe(); + } + } + + denialOfDownload() { + this.alertApplyAll.isOpen = true; + this.alertApplyAll.cancelButton = true; + this.alertApplyAll.okButton = false; + this.alertApplyAll.alertTitle = "Download Results in CSV"; + this.alertApplyAll.message = "Sorry, but the results are too many! Use the api instead!"; + this.alertApplyAll.cancelButtonText = "Ok"; + + console.info("denial of Download"); + + } + downloadfile(url:string,filename:string){ + console.log("Downloading file: "+ url); + this.openLoading(); + this.setMessageLoading("Downloading CSV file"); + + this._reportsService.downloadCSVFile(url).subscribe( + data => { + this.closeLoading(); + window.open(window.URL.createObjectURL(data),filename+".csv"); + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.downloadFilePiwikSub = this._piwikService.trackDownload(url).subscribe(); + } + }, + error => { + console.log("Error downloading the file."); + this.closeLoading(); + this.confirmOpenCsvError(); + }, + () => console.log('Completed file download.') + ); + } + + + public openLoading(){ + if(this.loading){ + this.loading.open(); + } + } + public closeLoading(){ + if(this.loading){ + this.loading.close(); + } + } + public setMessageLoading(message: string){ + if(this.loading){ + this.loading.message = message; + } + } + + public confirmOpenCsvError(){ + this.alertCsvError.cancelButton = false; + this.alertCsvError.okButton = true; + this.alertCsvError.alertTitle = "ERROR DOWNLOADING CSV FILE"; + this.alertCsvError.message = "There was an error in csv downloading. Please try again later."; + this.alertCsvError.okButtonText = "OK"; + this.alertCsvError.open(); + } + +} diff --git a/portal-4cli/src/app/searchPages/searchUtils/searchDownload.module.ts b/portal-4cli/src/app/searchPages/searchUtils/searchDownload.module.ts new file mode 100644 index 00000000..1275de01 --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/searchDownload.module.ts @@ -0,0 +1,24 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {SearchDownloadComponent} from './searchDownload.component'; +import {LoadingModalModule} from '../../utils/modal/loadingModal.module'; +import {AlertModalModule} from '../../utils/modal/alertModal.module'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, LoadingModalModule, AlertModalModule + ], + declarations: [ + SearchDownloadComponent +], + + providers:[ + ], + exports: [ + SearchDownloadComponent + + ] +}) +export class SearchDownloadModule { } diff --git a/portal-4cli/src/app/searchPages/searchUtils/searchFilter.component.html b/portal-4cli/src/app/searchPages/searchUtils/searchFilter.component.html new file mode 100644 index 00000000..fdf83db7 --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/searchFilter.component.html @@ -0,0 +1,67 @@ + +
      +
    • +
      {{_formatTitle(filter.title,filter.values.length)}} +
      + +
    • +
    diff --git a/portal-4cli/src/app/searchPages/searchUtils/searchFilter.component.ts b/portal-4cli/src/app/searchPages/searchUtils/searchFilter.component.ts new file mode 100644 index 00000000..a120673c --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/searchFilter.component.ts @@ -0,0 +1,144 @@ +import {Component, Input, Output, EventEmitter} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; + +import { Filter, Value} from './searchHelperClasses.class'; +import {Open} from '../../utils/modal/open.component'; + +@Component({ + selector: 'search-filter', + templateUrl: 'searchFilter.component.html' +}) + +export class SearchFilterComponent { + + @Input() filter:Filter; + @Input() showResultCount:boolean = true; + @Input() isDisabled:boolean = false; + @Input() addShowMore:boolean = true; + + public showAll:boolean = false; + public _maxCharacters:number =28; + + @Output() toggleModal = new EventEmitter(); + + @Output() modalChange = new EventEmitter(); + + + public isOpen:boolean=false; + + filterModalChange() { + console.info("Modal Changed"); + this.modalChange.emit({ + value: true + }); + //this.close(); + } + + constructor () { + } + + ngOnInit() { + + } + public _formatTitle(title,length){ + return (((title+" ("+length+")").length >this._maxCharacters)?(title.substring(0,(this._maxCharacters - (" ("+length+")").length - ('...').length))+"..."):title+" ("+((length >= 99)?length+"+":length)+")") + } + private _formatName(value){ + return value.name;//(((value.name+" ("+value.number+")").length >this._maxCharacters)?(value.name.substring(0,(this._maxCharacters - (" ("+value.number+")").length - ('...').length))+"..."):value.name) + } + toggleShowAll(){ + this.showAll = !this.showAll; + if(this.showAll == false) { + this.reorderFilterValues(); + } + } + + filterChange(selected:boolean){ + console.info("filter change: "+selected); + if(selected){ + this.filter.countSelectedValues++; + // this.reorderFilterValues(); + }else{ + this.filter.countSelectedValues--; + // this.reorderFilterValues(); + } + } + getSelectedValues(filter):any{ + var selected = []; + if(filter.countSelectedValues >0){ + for (var i=0; i < filter.values.length; i++){ + if(filter.values[i].selected){ + selected.push(filter.values[i]); + } + } + } + return selected; + + } + getNotSelectedValues(filter):any{ + var notSselected = []; + if(filter.countSelectedValues >0){ + for (var i=0; i < filter.values.length; i++){ + if(!filter.values[i].selected){ + notSselected.push(filter.values[i]); + } + } + }else { + notSselected = filter.values; + } + return notSselected; + } + reorderFilterValues() { + for(let value of this.filter.values) { + if(value.selected) { + let index: number = this.filter.values.indexOf(value); + let selectedValue:Value = this.filter.values[index]; + + this.filter.values.splice(index, 1); + this.filter.values.splice(0, 0, selectedValue); + } + } + } +// sliceSelected() { +// let values: Value[] = []; +// +// for(let value of this.filter.values) { +// if(value.selected) { +// let index: number = this.filter.values.indexOf(value); +// let selectedValue:Value = this.filter.values[index]; +// +// this.filter.values.splice(index, 1); +// this.filter.values.splice(0, 0, selectedValue); +// } +// } + + + toggle() { + this.toggleModal.emit({ + value: this.filter + }); + } + + + open() { + this.isOpen = true; + } + + close() { + this.isOpen = false; + } + + filterChange2(selected:boolean){ + + console.info("filter change2"); + if(selected){ + this.filter.countSelectedValues++; + // this.reorderFilterValues(); + }else{ + this.filter.countSelectedValues--; + // this.reorderFilterValues(); + } + this.close(); + } + +} diff --git a/portal-4cli/src/app/searchPages/searchUtils/searchFilter.module.ts b/portal-4cli/src/app/searchPages/searchUtils/searchFilter.module.ts new file mode 100644 index 00000000..3cc6792b --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/searchFilter.module.ts @@ -0,0 +1,24 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {SearchFilterComponent} from './searchFilter.component'; +import{SearchFilterModalComponent} from './searchFilterModal.component'; +import {ModalModule} from '../../utils/modal/modal.module'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, ModalModule + ], + declarations: [ + SearchFilterComponent, SearchFilterModalComponent +], + + providers:[ + ], + exports: [ + SearchFilterComponent, SearchFilterModalComponent + + ] +}) +export class SearchFilterModule { } diff --git a/portal-4cli/src/app/searchPages/searchUtils/searchFilterModal.component.ts b/portal-4cli/src/app/searchPages/searchUtils/searchFilterModal.component.ts new file mode 100644 index 00000000..bb0ed624 --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/searchFilterModal.component.ts @@ -0,0 +1,104 @@ +import {Component, ViewEncapsulation, ComponentRef, ElementRef, Input, EventEmitter, Output} from '@angular/core'; +// import { DynamicComponentLoader} from '@angular/core'; + +import {Open} from '../../utils/modal/open.component'; +import { Filter} from './searchHelperClasses.class'; + +@Component({ + selector: 'modal-search-filter', + template: ` + + + `, + encapsulation: ViewEncapsulation.None, +}) +/** + * API to an open search filter window. + */ +export class SearchFilterModalComponent{ + @Input() filter: Filter; + @Input() showResultCount:boolean = true; + @Output() modalChange = new EventEmitter(); + + public isOpen:boolean=false; + + constructor( public _elementRef: ElementRef){} + + filterModalChange(selected:boolean) { + console.info("Modal Changed"); + this.filterChange(selected); + this.modalChange.emit({ + value: selected + }); + this.close(); + } + filterChange(selected:boolean){ + if(selected){ + this.filter.countSelectedValues++; + // this.reorderFilterValues(); + }else{ + this.filter.countSelectedValues--; + // this.reorderFilterValues(); + } + } + getSelectedValues(filter):any{ + var selected = []; + if(filter.countSelectedValues >0){ + for (var i=0; i < filter.values.length; i++){ + if(filter.values[i].selected){ + selected.push(filter.values[i]); + } + } + } + return selected; + + } + getNotSelectedValues(filter):any{ + var notSselected = []; + if(filter.countSelectedValues >0){ + for (var i=0; i < filter.values.length; i++){ + if(!filter.values[i].selected){ + notSselected.push(filter.values[i]); + } + } + }else { + notSselected = filter.values; + } + return notSselected; + } + + open() { + this.isOpen = true; + } + + close() { + this.isOpen = false; + } + +} diff --git a/portal-4cli/src/app/searchPages/searchUtils/searchForm.component.ts b/portal-4cli/src/app/searchPages/searchUtils/searchForm.component.ts new file mode 100644 index 00000000..0a6ba9a8 --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/searchForm.component.ts @@ -0,0 +1,52 @@ +import {Component, Input, Output, EventEmitter} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {RouterHelper} from '../../utils/routerHelper.class'; +import {Router} from '@angular/router'; + +@Component({ + selector: 'search-form', + template: ` + +
    + + + +
    + ` +}) + +export class SearchFormComponent { + @Input() isDisabled: boolean = false; + @Input() keyword: string = ''; + @Input() generalSearch: boolean = false; + @Input() placeholderText: string = "Type keywords"; + @Input() link: boolean = false; + public routerHelper:RouterHelper = new RouterHelper(); + + @Output() keywordChange = new EventEmitter(); + + constructor (private _router:Router) { + } + + ngOnInit() { + + } + + keywordChanged() { + console.info("inside form: "+this.keyword); + this.keywordChange.emit({ + value: this.keyword + }); + } + goTo() { + this._router.navigate(['/search/find'], { queryParams: this.routerHelper.createQueryParam('keyword',this.keyword) }); + } +} diff --git a/portal-4cli/src/app/searchPages/searchUtils/searchForm.module.ts b/portal-4cli/src/app/searchPages/searchUtils/searchForm.module.ts new file mode 100644 index 00000000..21a9d9b1 --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/searchForm.module.ts @@ -0,0 +1,23 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import{SearchFormComponent} from './searchForm.component'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, RouterModule + ], + declarations: [ + SearchFormComponent +], + + providers:[ + ], + exports: [ + SearchFormComponent + + ] +}) +export class SearchFormModule { } diff --git a/portal-4cli/src/app/searchPages/searchUtils/searchHelperClasses.class.ts b/portal-4cli/src/app/searchPages/searchUtils/searchHelperClasses.class.ts new file mode 100644 index 00000000..c09b3440 --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/searchHelperClasses.class.ts @@ -0,0 +1,89 @@ +import {Dates} from '../../utils/string-utils.class'; +export class Filter{ + public title: string; // eg Type + public filterId: string; // type (name in url parameter) + public originalFilterId: string; // (in index) + public countSelectedValues: number = 0; + public values: Value[] = []; + public filterOperator: string ='or'; + + +} + +export class Value{ + public name: string; //eg Article, Journal + public id: string; //0001 + public selected: boolean = false; + public number: number = 0; + +} +export class AdvancedField{ + public id: string; // + public param:string; + public name: string; // + public type: string = "keyword"; //keyword, static or dynamic + public value: string = ''; + public operatorId: string; + public operatorName: string =""; + public valid: boolean = true; + public dateValue:DateValue = new DateValue("any"); + + constructor(id:string,param:string,name:string, type:string, value:string,operator:string){ + this.id = id; + this.param = param; + this.name = name; + this.type = type; + this.value = value; + this.operatorId = operator; + // this.operatorName = "AND"; + + } +} +export class DateValue{ + public types = ["any","range","1mon","2mon","3mon","6mon","12mon","2year","5year","10year"]; + public typesTitle = ["any","in the specified date range","in the last month","in the last 2 months","in the last 3 months","in the last 6 months","in the last year","in the last 2 years","in the last 5 years","in the last 10 years"]; + public type: string ; + public from:Date = new Date(); + public to:Date = new Date(); + constructor(type:string = "any"){ + this.setDatesByType(type); + } + public setDatesByType(type:string){ + if(this.types.indexOf(type) == -1){ + type=this.types[0]; + } + this.type = type; + this.to = Dates.getDateToday(); + if(this.type == "range" || this.type == "any"){ // for type "any" just to initiate with values + this.from = Dates.getDateXMonthsAgo(1); + }else if(this.type == "1mon"){ + this.from = Dates.getDateXMonthsAgo(1); + }else if(this.type == "2mon"){ + this.from = Dates.getDateXMonthsAgo(2); + }else if(this.type == "3mon"){ + this.from = Dates.getDateXMonthsAgo(3); + }else if(this.type == "6mon"){ + this.from = Dates.getDateXMonthsAgo(6); + }else if(this.type == "12mon"){ + this.from = Dates.getDateXMonthsAgo(12); + }else if(this.type == "2year"){ + this.from = Dates.getDateXYearsAgo(2); + }else if(this.type == "5year"){ + this.from = Dates.getDateXYearsAgo(5); + }else if(this.type == "10year"){ + this.from = Dates.getDateXYearsAgo(10); + } + } + +} +export class OPERATOR{ + public static AND: string ="and"; + public static OR: string ="or"; + public static NOT: string ="not"; + +} + +export class AutoCompleteValue{ + public id: string; + public label: string; +} diff --git a/portal-4cli/src/app/searchPages/searchUtils/searchPage.component.html b/portal-4cli/src/app/searchPages/searchUtils/searchPage.component.html new file mode 100644 index 00000000..2c6aa29b --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/searchPage.component.html @@ -0,0 +1,126 @@ +
    +
    +
    +
    + +
    +
    +
    + +
    +
    + + More search options + + + +
    + Keywords: + + + {{filter.title}}: + + , + + + + + + Clear All + +
    + +
    + +
    +
    +
    + +
    +
    + + + +
    +
    + +
    Filter By:
    + +
    +
    + +
    +
    + + +
    +
    + + +
    + + +
    + +
    + +
    + +
    + + + + + + + + +
    + +
    + + +
    + +
    + +
    + + + +
    + +
    + + + + + + + + + +
    + +
    + +
    + +
    +
    +
    +
    +
    +
    diff --git a/portal-4cli/src/app/searchPages/searchUtils/searchPage.component.ts b/portal-4cli/src/app/searchPages/searchUtils/searchPage.component.ts new file mode 100644 index 00000000..c25a7bd4 --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/searchPage.component.ts @@ -0,0 +1,515 @@ +import {Component, Input, ViewChild, Output, EventEmitter,ElementRef} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {Location} from '@angular/common'; +import { Router} from '@angular/router'; + +import { Filter, Value} from './searchHelperClasses.class'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {SearchFields} from '../../utils/properties/searchFields'; +import {SearchUtilsClass} from './searchUtils.class'; +import {DOI, StringUtils} from '../../utils/string-utils.class'; +import {ModalLoading} from '../../utils/modal/loading.component'; +import { Meta} from '../../../angular2-meta'; +import{SearchFilterComponent} from './searchFilter.component'; +import {SearchFilterModalComponent} from './searchFilterModal.component'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; +import { ErrorCodes} from '../../utils/properties/openaireProperties'; +import {PiwikService} from '../../utils/piwik/piwik.service'; + + +@Component({ + selector: 'search-page', + templateUrl: 'searchPage.component.html' + +}) +export class SearchPageComponent { + @Input() pageTitle = ""; + @Input() formPlaceholderText = "Type Keywords..."; + @Input() results = []; + @Input() filters = []; + @Input() type:string = ""; + @Input() entityType: string = ""; + @Input() searchUtils:SearchUtilsClass = new SearchUtilsClass(); + @Output() queryChange = new EventEmitter(); + @Input() baseUrl:string = ''; + @Input() showResultCount:boolean = true; + @Input() showRefine:boolean = true; + @Input() refineFields = []; + @Input() csvParams: string; + @Input() csvPath: string; + @Input() advancedSearchLink: string = ""; + @Input() tableViewLink: string; + @Input() disableForms: boolean = false; + @Input() loadPaging: boolean = true; + @Input() oldTotalResults: number = 0; + @Input() tableView: boolean = false; + @Input() searchFormClass: string = "searchForm"; + @ViewChild (ModalLoading) loading : ModalLoading ; + public fieldIdsMap;//: { [key:string]:{ name:string, operator:string, type:string, indexField:string, equalityOperator:string }}; + private searchFieldsHelper:SearchFields = new SearchFields(); + private queryParameters: Map = new Map(); + private baseURLWithParameters:string = ''; + private sub: any; piwiksub: any; + public countFilters= 0; + public parameterNames:string[] =[]; + public parameterValues:string[] =[]; + public showUnknownFilters:boolean = false; // when a filter exists in query but has no results, so no filters returned from the query + //@ViewChild (SearchFilterModalComponent) searchFilterModal : SearchFilterModalComponent ; + public currentFilter: Filter; + + constructor (private location: Location , private _meta: Meta,private element: ElementRef,private _piwikService:PiwikService, private router: Router) { + } + + ngOnInit() { + if (typeof document !== 'undefined') { + this.element.nativeElement.scrollIntoView(); + } + this.updateBaseUrlWithParameters(this.filters); + this.updateTitle(this.pageTitle); + this.updateDescription("Openaire, search, repositories, open access, type, content provider, funder, project, " + this.type + "," +this.pageTitle); + if(typeof window !== 'undefined') { + this.updateUrl(OpenaireProperties.getBaseLink()+location.pathname); + } + if(typeof document !== 'undefined' && OpenaireProperties.isPiwikTrackEnabled()){ + this.piwiksub = this._piwikService.trackView(this.pageTitle).subscribe(); + } + } + ngAfterViewChecked(){ + + } + ngOnDestroy() { + if(this.piwiksub){ + this.piwiksub.unsubscribe(); + } + } + toggleModal($event) { + this.currentFilter = $event.value; + //this.searchFilterModal.open(); + } + + updateDescription(description:string){ + this._meta.updateMeta("description", description); + this._meta.updateProperty("og:description", description); + } + updateTitle(title:string){ + var _prefix ="OpenAIRE | "; + var _title = _prefix + ((title.length> 50 ) ?title.substring(0,50):title); + this._meta.setTitle(_title ); + this._meta.updateProperty("og:title",_title); + } + updateUrl(url:string){ + this._meta.updateProperty("og:url", url); + } + + public getQueryParametersFromUrl(params){ + // var parameters = ""; + var allFqs = ""; + + this.queryParameters = new Map(); + + for(var i=0; i< this.refineFields.length ; i++){ + var filterId = this.refineFields[i]; + + if(params[filterId] != undefined) { + this.queryParameters[filterId]=StringUtils.URIDecode(params[filterId]); + + let values = (StringUtils.URIDecode(this.queryParameters[filterId])).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/,-1); + var countvalues = 0; + var fq = ""; + for(let value of values) { + countvalues++; + var paramId = this.fieldIdsMap[filterId].param; + // parameters+='&' + paramId+ '='+ value;//+"&" + this.fieldIdsMap[paramId].operator + "="+((countvalues == 1)?"and":"or"); + fq+=(fq.length > 0 ? " " + "or" + " ":"" ) + filterId +" exact " +StringUtils.URIEncode(value); + } + if(countvalues > 0){ + fq="&fq="+fq; + } + allFqs += fq; + } + } + var keyword = params['keyword']; + var doiQuery = ""; + var keywordQuery = ""; + if((keyword && keyword.length > 0)){ + if((this.type == 'publications' ||this.type == 'research data')){ + var DOIs:string[] = DOI.getDOIsFromString(keyword); + var doisParams = ""; + + for(var i =0 ;i < DOIs.length; i++){ + doisParams+=(doisParams.length > 0?"&":"")+'doi="'+ DOIs[i]+'"'; + } + if(doisParams.length > 0){ + doiQuery += "&"+doisParams; + }else { + keywordQuery += "&q="+StringUtils.URIEncode(keyword); + } + }else{ + keywordQuery += "&q="+StringUtils.URIEncode(keyword); + + } + } + return (doiQuery.length > 0 ? doiQuery:keywordQuery) + allFqs; + } + public getIndexQueryParametersFromUrl(params){ + // var parameters = ""; + var allFqs = ""; + + for(var i=0; i< this.refineFields.length ; i++){ + var filterId = this.refineFields[i]; + var fq = ""; + if(params[filterId] != undefined) { + this.queryParameters[filterId]=decodeURIComponent(params[filterId]); + let values = (decodeURIComponent(this.queryParameters[filterId])).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/,-1); + var countvalues = 0 + for(let value of values) { + countvalues++; + // parameters+= ((countvalues == 1)?" and (":" or ")+ filterId+ '='+ value; + fq+=(fq.length > 0 ? " " + "or" + " ":"" ) + filterId + " exact " + value;//StringUtils.quote(value); + } + // parameters+= " ) "; + if(countvalues > 0){ + fq="&fq="+fq; + } + allFqs += fq; + } + + } + var keyword = params['keyword']; + var doiQuery = ""; + var keywordQuery = ""; + if((keyword && keyword.length > 0)){ + if((this.type == 'publications' ||this.type == 'research data')){ + var DOIs:string[] = DOI.getDOIsFromString(keyword); + var doisParams = ""; + + for(var i =0 ;i < DOIs.length; i++){ + doisParams+=(doisParams.length > 0?"&":"")+'doi="'+ DOIs[i]+'"'; + } + if(doisParams.length > 0){ + doiQuery += "&"+doisParams; + } + }else{ + keywordQuery += "and ("+StringUtils.quote(StringUtils.URIEncode(keyword)) +")"; + + } + } + return (doiQuery.length > 0 ? doiQuery:keywordQuery) + allFqs; + +} + /* + * Mark as check the new filters that are selected, when you get them from search + */ + public checkSelectedFilters(filters:Filter[]){ + this.filters = filters; + for(var i=0; i< filters.length ; i++){ + var filter:Filter = filters[i]; + filter.countSelectedValues = 0; + if(this.queryParameters[filter.filterId] != undefined) { + let values = (decodeURIComponent(this.queryParameters[filter.filterId])).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/,-1); + for(let filterValue of filter.values) { + if(values.indexOf(StringUtils.quote(filterValue.id)) > -1) { + filterValue.selected = true; + filter.countSelectedValues++; + }else{ + filterValue.selected = false; + + } + } + }else{ + for(let filterValue of filter.values) { + filterValue.selected = false; + } + } + } + + return filters; + } + /* + * Update the url with proper parameters. This is used as base url in Paging Component + */ + public updateBaseUrlWithParameters(filters:Filter[]){ + this.baseURLWithParameters = this.baseUrl + this.createUrlParameters(filters,false); + + } + + /* + * + */ + private createUrlParameters(filters:Filter[], includePage:boolean){ + var allLimits="";//location.search.slice(1); + this.queryParameters = new Map(); + this.parameterNames.splice(0,this.parameterNames.length); + this.parameterValues.splice(0,this.parameterValues.length); + + for (let filter of filters){ + var filterLimits=""; + if(filter.countSelectedValues > 0){ + for (let value of filter.values){ + if(value.selected == true){ + filterLimits+=((filterLimits.length == 0)?'':',') +'"'+ StringUtils.URIEncode(value.id)+'"'; + } + } + this.queryParameters[filter.filterId]=filterLimits; + if(filterLimits.length > 0){ + this.parameterNames.push(filter.filterId); + this.parameterValues.push(filterLimits); + } + allLimits+=(allLimits.length==0?"?":"&")+((filterLimits.length == 0 )?'':filter.filterId + '='+ filterLimits) ; + } + } + if(this.searchUtils.keyword.length > 0 ){ + allLimits+=(allLimits.length==0?"?":"&")+'keyword=' + this.searchUtils.keyword; + this.parameterNames.push("keyword"); + this.parameterValues.push(this.searchUtils.keyword); + } + if(this.searchUtils.page != 1 && includePage){ + allLimits+=((allLimits.length == 0)?'?':'&') + 'page=' + this.searchUtils.page; + } + + return allLimits; + } + /* + * + */ + private createSearchQueryParameters(filters:Filter[]){ + var allFqs = ""; + for (let filter of filters){ + if(filter.countSelectedValues > 0){ + var fq = ""; + var count_selected=0; + for (let value of filter.values){ + if(value.selected == true){ + count_selected++; + fq+=(fq.length > 0 ? " " + filter.filterOperator + " ":"" ) + filter.filterId + " exact " + StringUtils.quote(StringUtils.URIEncode(value.id)); + } + } + fq="&fq="+fq; + allFqs += fq; + } + } + var doiQuery = ""; + var keywordQuery = ""; + if((this.searchUtils.keyword && this.searchUtils.keyword.length > 0)){ + if((this.type == 'publications' ||this.type == 'research data')){ + var DOIs:string[] = DOI.getDOIsFromString(this.searchUtils.keyword); + var doisParams = ""; + + for(var i =0 ;i < DOIs.length; i++){ + doisParams+=(doisParams.length > 0?"&":"")+'doi="'+ DOIs[i]+'"'; + } + if(doisParams.length > 0){ + doiQuery += "&"+doisParams; + }else{ + keywordQuery += "&q="+StringUtils.URIEncode(this.searchUtils.keyword); + } + }else{ + keywordQuery += "&q="+StringUtils.URIEncode(this.searchUtils.keyword); + } + } + + return (doiQuery.length > 0 ? doiQuery:keywordQuery) + allFqs; + + } + private createIndexQueryParameters(filters:Filter[]){ + var allFqs = ""; + for (let filter of filters){ + if(filter.countSelectedValues > 0){ + var count_selected=0; + var fq = ""; + for (let value of filter.values){ + if(value.selected == true){ + count_selected++; + fq+=(fq.length > 0 ? " " + filter.filterOperator + " ":"" ) + filter.filterId + " exact " + StringUtils.quote(StringUtils.URIEncode(value.id)); + } + } + if(count_selected > 0){ + fq="&fq="+fq; + allFqs += fq; + } + } + } + var doiQuery = ""; + var keywordQuery = ""; + if((this.searchUtils.keyword && this.searchUtils.keyword.length > 0)){ + if((this.type == 'publications' ||this.type == 'research data')){ + var DOIs:string[] = DOI.getDOIsFromString(this.searchUtils.keyword); + var doisParams = ""; + for(var i =0 ;i < DOIs.length; i++){ + doisParams+=(doisParams.length > 0?"&":"")+'doi="'+ DOIs[i]+'"'; + } + if(doisParams.length > 0){ + doiQuery += "&"+doisParams; + } + }else{ + keywordQuery += " and ("+StringUtils.quote(StringUtils.URIEncode(this.searchUtils.keyword)) +")" + + } + } + return (doiQuery.length > 0 ? doiQuery:keywordQuery) + allFqs; + + } + public isFiltered(){ + var filtered=false; + this.showUnknownFilters = false; + for (let filter of this.filters){ + if(filter.countSelectedValues > 0){ + filtered = true; + break; + } + } + if(this.searchUtils.keyword.length > 0 ){ + filtered = true; + } + var errorCodes:ErrorCodes = new ErrorCodes(); + if(this.queryParameters.keys() && this.searchUtils.totalResults == 0 && this.searchUtils.status !=errorCodes.LOADING ){ + this.showUnknownFilters = true; + } + return filtered; + } + private clearKeywords(){ + if(this.searchUtils.keyword.length > 0 ){ + this.searchUtils.keyword =''; + } + this.goTo(1); + } + private clearFilters(){ + for (var i =0 ; i < this.filters.length; i++){ + for (var j=0; j < this.filters[i].countSelectedValues; j++){ + if(this.filters[i].values[j].selected){ + this.filters[i].values[j].selected = false; + } + this.filters[i].countSelectedValues = 0; + } + } + this.clearKeywords(); + + } + private removeFilter(value:Value,filter:Filter){ + filter.countSelectedValues--; + if(value.selected == true){ + value.selected = false; + } + this.goTo(1); + + } + goTo(page:number = 1){ + this.searchUtils.page = page; + console.info("searchUtils.page goto = "+this.searchUtils.page); + var urlParameters = this.createUrlParameters(this.filters,true); + console.info("urlParams : "+urlParameters); + this.updateBaseUrlWithParameters(this.filters); + var queryParameters = this.createSearchQueryParameters(this.filters); + console.info("queryParams : "+queryParameters); + var indexQuery = this.createIndexQueryParameters(this.filters); + + this.location.go(location.pathname,urlParameters); +/* Code For Piwik*/ + if (typeof localStorage !== 'undefined') { + console.log("In PreviousRouteRecorder : "+this.router.url ); + localStorage.setItem('previousRoute', this.router.url); + } + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.piwiksub = this._piwikService.trackView(this.pageTitle).subscribe(); + } + /* End Piwik Code */ + this.queryChange.emit({ + value: queryParameters, + index:indexQuery + + }); + if (typeof document !== 'undefined') { + this.element.nativeElement.scrollIntoView(); + } + } + filterChanged($event){ + console.info("filter Changed"); + this.goTo(1); + } + keywordChanged($event) { + this.searchUtils.keyword = $event.value; + this.goTo(1); + } + + /* + * Get A sub-array of this.refineFields array, which contains the ids of the selected filters + */ + public getSelectedFilters():string[] { + var selected:string[] = []; + for(var i=0; i < this.filters.length; i++){ + var filter:Filter = this.filters[i]; + if(filter.countSelectedValues > 0){ + selected.push(filter.filterId); + } + } + return selected; + } + /* + * Get A sub-array of this.refineFields array, which contains the ids of the selected parameters + */ + private getSelectedParameters():string[] { + var selected:string[] = []; + var params:string[] = Object.keys(this.queryParameters); + for(var i=0; i < params.length; i++){ + if(this.refineFields.indexOf(params[i]) > -1){ + selected.push(params[i]); + } + } + return selected; + } + /* + * Get A sub-array of this.refineFields array, which hides hidden fields (e.g Funding level 0,1,2,..), and contains those that depend on another fields (e.g Funding level 0 if Funder is selected ) + */ + public getFields():string[] { + var selected_filters:string[] = this.getSelectedFilters(); + if(selected_filters.length == 0){ + selected_filters = this.getSelectedParameters(); + } + var fields:string[] = []; + for(var i =0 ; i < this.refineFields.length;i++){ + var dependentTo = this.searchFieldsHelper.DEPENDENT_FIELDS[this.refineFields[i]]; + + //if filter is not marked as hidden OR it is hidden but it is dependent to a field that it IS selected + if(this.searchFieldsHelper.HIDDEN_FIELDS.indexOf(this.refineFields[i]) == -1 || (selected_filters.indexOf(dependentTo) != -1) || (selected_filters.indexOf(this.refineFields[i]) != -1) ){ + fields.push(this.refineFields[i]); + } + } + return fields; + } + /* + * Get a query string of all fields, that want to get from search (e.g. &fields=funderid&fields=projectstartyear&...)) + */ + public getRefineFieldsQuery():string{ + + var fields:string[] = this.getFields(); + var fieldsStr = "" + for(var i =0 ; i < fields.length ;i++){ + fieldsStr+="&fields="+fields[i]; + } + return "&refine=true"+fieldsStr; + } + + // for loading + public openLoading(){ + if(this.loading){ + this.loading.open(); + } + } + public closeLoading(){ + if(this.loading){ + this.loading.close(); + } + } + getSelectedValues(filter):any{ + var selected = []; + if(filter.countSelectedValues >0){ + for (var i=0; i < filter.values.length; i++){ + if(filter.values[i].selected){ + selected.push(filter.values[i]); + } + } + } + return selected; + + } +} diff --git a/portal-4cli/src/app/searchPages/searchUtils/searchPage.module.ts b/portal-4cli/src/app/searchPages/searchUtils/searchPage.module.ts new file mode 100644 index 00000000..39fc78fd --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/searchPage.module.ts @@ -0,0 +1,40 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import{SearchPageComponent} from './searchPage.component'; +import{SearchFormModule} from './searchForm.module'; +import{SearchResultsModule} from './searchResults.module'; +//import{DatasourceTableViewModule} from './datasourceTableView.module'; +//import{SearchFilterComponent} from './searchFilter.component'; +//import{SearchFilterModalComponent} from './searchFilterModal.component'; +import {SearchFilterModule} from './searchFilter.module'; +import{LoadingModalModule} from '../../utils/modal/loadingModal.module'; +import {ReportsServiceModule} from '../../services/reportsService.module'; +import{SearchPagingModule} from './searchPaging.module'; +import {SearchDownloadModule} from './searchDownload.module'; +import {ModalModule} from '../../utils/modal/modal.module'; +import {PiwikServiceModule} from '../../utils/piwik/piwikService.module'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {HelperModule} from '../../utils/helper/helper.module'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule,RouterModule, SearchFormModule, SearchResultsModule, + LoadingModalModule, ReportsServiceModule, + SearchPagingModule, SearchDownloadModule, ModalModule, SearchFilterModule, PiwikServiceModule, HelperModule + ], + declarations: [ + SearchPageComponent +], + + providers:[ + PreviousRouteRecorder + ], + exports: [ + SearchPageComponent + ] +}) +export class SearchPageModule { } diff --git a/portal-4cli/src/app/searchPages/searchUtils/searchPageTableView.component.html b/portal-4cli/src/app/searchPages/searchUtils/searchPageTableView.component.html new file mode 100644 index 00000000..266c2136 --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/searchPageTableView.component.html @@ -0,0 +1,196 @@ +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + Keywords: {{searchUtils.keyword}} + + + {{filter.title}}: + {{value.name}} + , + + + + + + Clear All + +
    +
    +
    +
    +
    + + + +
    + +
    + + +
    +
    + +
    Filter By:
    + +
    +
    + +
    +
    + +
    +
    + + +
    + +
    +
    +
    + + {{searchUtils.totalResults}} content providers, page {{searchUtils.page}} of {{(totalPages())}} + + + + +
    +
    + +
    +

    + + + + + +

    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + +
    Name + + + + + Type + + + + + Country + + + + + Institution + + + + + Compatibility + + + + +
    + + + + + [no title available] + + + + {{dataprovider.type}} + - + + {{country}}{{(i < ( dataprovider['countries'].slice(0,5).length-1))?", ":""}}{{(i == dataprovider['countries'].slice(0,5).length-1 && dataprovider['countries'].length > 5)?"...":""}} + - + + + {{org.name}}{{org.name}}{{(i < ( dataprovider['organizations'].slice(0,5).length-1))?", ":""}}{{(i == dataprovider['organizations'].slice(0,5).length-1 && dataprovider['organizations'].length > 5)?"...":""}} + + - + + {{dataprovider.compatibility}} + - +
    +
    + +
    +
    + + {{searchUtils.totalResults}} content providers, page {{searchUtils.page}} of {{(totalPages())}} + + + + +
    +
    + + + +
    + +
    +

    + + + + + +

    + + +
    +
    + + +
    + +
    +
    +
    diff --git a/portal-4cli/src/app/searchPages/searchUtils/searchPageTableView.component.ts b/portal-4cli/src/app/searchPages/searchUtils/searchPageTableView.component.ts new file mode 100644 index 00000000..2de14356 --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/searchPageTableView.component.ts @@ -0,0 +1,274 @@ +import {Component, Input, ViewChild, Output, EventEmitter} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {Location} from '@angular/common'; +import { Filter, Value} from './searchHelperClasses.class'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {SearchFields} from '../../utils/properties/searchFields'; +import {SearchUtilsClass} from './searchUtils.class'; +import {DOI, StringUtils} from '../../utils/string-utils.class'; +import {ModalLoading} from '../../utils/modal/loading.component'; +import { Meta} from '../../../angular2-meta'; +import{SearchFilterComponent} from './searchFilter.component'; +import {SearchFilterModalComponent} from './searchFilterModal.component'; +import { ErrorCodes} from '../../utils/properties/openaireProperties'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; +import {ContentProvidersDatatablePipe} from '../../utils/pipes/contentProvidersDatatable.pipe'; +import {PiwikService} from '../../utils/piwik/piwik.service'; + +@Component({ + selector: 'search-page-table', + templateUrl:'searchPageTableView.component.html' + }) +export class SearchPageTableViewComponent { + @Input() pageTitle = ""; + @Input() results; + @Input() filters = []; + @Input() type:string = ""; + @Input() entityType: string = ""; + @Input() searchUtils:SearchUtilsClass;// = new SearchUtilsClass(); + //@Output() downloadClick = new EventEmitter(); + @Input() showResultCount:boolean = true; + @Input() showRefine:boolean = true; + @Input() refineFields = []; + //@Input() csvParams: string; + //@Input() csvPath: string; + @Input() searchViewLink: string; + @Input() disableForms: boolean = false; + @Input() searchFormClass: string = "searchForm"; +@Input() formPlaceholderText = "Type Keywords..."; + @ViewChild (ModalLoading) loading : ModalLoading ; + private searchFieldsHelper:SearchFields = new SearchFields(); + private queryParameters: Map = new Map(); + private sub: any; + public countFilters= 0; + public parameterNames:string[] =[]; + public parameterValues:string[] =[]; + + public triggerPipe: boolean = false; + + public rowsOnPage:number = 10; + @ViewChild('mf') table: any;//DataTable; + + @ViewChild (SearchFilterModalComponent) searchFilterModal : SearchFilterModalComponent ; + public currentFilter: Filter; + public errorCodes:ErrorCodes = new ErrorCodes(); + piwiksub: any; + constructor (private location: Location , private _meta: Meta, private _piwikService:PiwikService) { + } + + ngOnInit() { + this.updateTitle(this.pageTitle); + this.updateDescription("Openaire, search, repositories, open access, type, content provider, funder, project, " + this.type + "," +this.pageTitle); + if(typeof window !== 'undefined') { + this.updateUrl(OpenaireProperties.getBaseLink()+location.pathname); + } + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.piwiksub = this._piwikService.trackView(this.pageTitle).subscribe(); + } + } + ngOnDestroy() { + if(this.piwiksub){ + this.piwiksub.unsubscribe(); +} + } + public sortByOrganization = (dataprovider: any) => { + if(dataprovider.organizations && dataprovider.organizations.length > 0) { + return dataprovider.organizations[0].name.toUpperCase(); + } + return "-"; + } + + totalPages(): number { + let totalPages:any = this.searchUtils.totalResults/(this.rowsOnPage); + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, 10) + 1); + } + return totalPages; + } + + refreshTable(page:number) { + this.searchUtils.page=page; + //this.table.mfActivePage=$event.value; + this.table.setPage(this.searchUtils.page, this.rowsOnPage); + } + + toggleModal($event) { + this.currentFilter = $event.value; + this.searchFilterModal.open(); + } + + updateDescription(description:string){ + this._meta.updateMeta("description", description); + this._meta.updateProperty("og:description", description); + } + updateTitle(title:string){ + var _prefix ="OpenAIRE | "; + var _title = _prefix + ((title.length> 50 ) ?title.substring(0,50):title); + this._meta.setTitle(_title ); + this._meta.updateProperty("og:title",_title); + } + updateUrl(url:string){ + this._meta.updateProperty("og:url", url); + } + +public getParametersFromUrl(params) { + for(var i=0; i< this.refineFields.length ; i++) { + var filterId = this.refineFields[i]; + if(params[filterId] != undefined) { + if(this.queryParameters == undefined){ + this.queryParameters = new Map(); + } + this.queryParameters[filterId]=decodeURIComponent(params[filterId]); + } + } +} + /* + * Mark as check the new filters that are selected, when you get them from search + */ + public checkSelectedFilters(filters:Filter[]){ + + this.filters = filters; + for(var i=0; i< filters.length ; i++){ + var filter:Filter = filters[i]; + filter.countSelectedValues = 0; + + if(this.queryParameters[filter.filterId] != undefined) { + let values = (decodeURIComponent(this.queryParameters[filter.filterId])).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/,-1); + for(let filterValue of filter.values) { + if(values.indexOf(StringUtils.quote(filterValue.id)) > -1) { + filterValue.selected = true; + filter.countSelectedValues++; + }else{ + filterValue.selected = false; + } + } + }else{ + for(let filterValue of filter.values) { + filterValue.selected = false; + } + } + } + + return filters; + } + + /* + * + */ + private createUrlParameters(filters:Filter[], includePage:boolean){ + var allLimits="";//location.search.slice(1); + this.parameterNames.splice(0,this.parameterNames.length); + this.parameterValues.splice(0,this.parameterValues.length); + + for (let filter of filters){ + var filterLimits=""; + if(filter.countSelectedValues > 0){ + for (let value of filter.values){ + if(value.selected == true){ + filterLimits+=((filterLimits.length == 0)?'':',') +'"'+ StringUtils.URIEncode(value.id)+'"'; + } + } + this.queryParameters[filter.filterId]=filterLimits; + if(filterLimits.length > 0){ + this.parameterNames.push(filter.filterId); + this.parameterValues.push(filterLimits); + } + allLimits+=(allLimits.length==0?"?":"&")+((filterLimits.length == 0 )?'':filter.filterId + '='+ filterLimits) ; + } + } + if(this.searchUtils.keyword.length > 0 ){ + allLimits+=(allLimits.length==0?"?":"&")+'keyword=' + this.searchUtils.keyword; + this.parameterNames.push("keyword"); + this.parameterValues.push(this.searchUtils.keyword); + } + + //if(this.searchUtils.page != 1 && includePage){ + // allLimits+=((allLimits.length == 0)?'?':'&') + 'page=' + this.searchUtils.page; + //} + + return allLimits; + } + + public isFiltered(){ + var filtered=false; + for (let filter of this.filters){ + if(filter.countSelectedValues > 0){ + filtered = true; + break; + } + } + if(this.searchUtils.keyword.length > 0 ){ + filtered = true; + } + return filtered; + } + private clearKeywords(){ + if(this.searchUtils.keyword.length > 0 ){ + this.searchUtils.keyword =''; + } + this.goTo(1, true); + } + private clearFilters(){ + for (var i =0 ; i < this.filters.length; i++) { + for (var j=0; j < this.filters[i].values.length; j++) { + if(this.filters[i].values[j].selected) { + this.filters[i].values[j].selected = false; + } + } + this.filters[i].countSelectedValues = 0; + } + this.clearKeywords(); + + } + + private removeFilter(value:Value,filter:Filter){ + filter.countSelectedValues--; + if(value.selected == true){ + value.selected = false; + } + this.goTo(1, true); + } + goTo(page:number = 1, triggerPipe:boolean = true){ + this.refreshTable(page); + if(triggerPipe) { + this.triggerPipe = !this.triggerPipe; + } + + var urlParameters = this.createUrlParameters(this.filters,true); + this.location.go(location.pathname,urlParameters); + } + + filterChanged($event){ + console.info("filter Changed"); + this.goTo(1, true); + } + keywordChanged($event) { + this.searchUtils.keyword = $event.value; + this.goTo(1, true); + } +/* + downloadClicked($event) { + if($event.value == true) { + var queryParameters = this.createSearchQueryParameters(this.filters); + + this.downloadClick.emit({ + value: queryParameters + }); + } + } +*/ + + + getSelectedValues(filter):any{ + var selected = []; + if(filter.countSelectedValues >0){ + for (var i=0; i < filter.values.length; i++){ + if(filter.values[i].selected){ + selected.push(filter.values[i]); + } + } + } + return selected; + + } +} diff --git a/portal-4cli/src/app/searchPages/searchUtils/searchPageTableView.module.ts b/portal-4cli/src/app/searchPages/searchUtils/searchPageTableView.module.ts new file mode 100644 index 00000000..2586914e --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/searchPageTableView.module.ts @@ -0,0 +1,53 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import{SearchPageTableViewComponent} from './searchPageTableView.component'; +import{SearchFormModule} from './searchForm.module'; +import{SearchResultsModule} from './searchResults.module'; +//import{DatasourceTableViewModule} from './datasourceTableView.module'; +//import{SearchFilterComponent} from './searchFilter.component'; +//import{SearchFilterModalComponent} from './searchFilterModal.component'; +import {SearchFilterModule} from './searchFilter.module'; +import{LoadingModalModule} from '../../utils/modal/loadingModal.module'; +import {ReportsServiceModule} from '../../services/reportsService.module'; +import{SearchPagingModule} from './searchPaging.module'; +import {SearchDownloadModule} from './searchDownload.module'; +import {ModalModule} from '../../utils/modal/modal.module'; +import {PagingModule} from '../../utils/paging.module'; +import {DataTableModule} from "angular2-datatable"; +import {ContentProvidersDatatablePipe} from '../../utils/pipes/contentProvidersDatatable.pipe'; + +import {PiwikServiceModule} from '../../utils/piwik/piwikService.module'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; + +import {HelperModule} from '../../utils/helper/helper.module'; +import {ErrorMessagesModule} from '../../utils/errorMessages.module'; + +@NgModule({ + imports: [ + CommonModule, FormsModule,RouterModule, SearchFormModule, SearchResultsModule, LoadingModalModule, + ReportsServiceModule, SearchPagingModule, SearchDownloadModule, ModalModule, PagingModule, + DataTableModule, SearchFilterModule, PiwikServiceModule, HelperModule, ErrorMessagesModule + ], + declarations: [ + SearchPageTableViewComponent//, + //SearchFilterComponent, + //SearchFilterModalComponent + , + ContentProvidersDatatablePipe +], + + providers:[ + PreviousRouteRecorder + ], + exports: [ + SearchPageTableViewComponent//, + //SearchFilterComponent, + //SearchFilterModalComponent + , + ContentProvidersDatatablePipe + ] +}) +export class SearchPageTableViewModule { } diff --git a/portal-4cli/src/app/searchPages/searchUtils/searchPaging.component.ts b/portal-4cli/src/app/searchPages/searchUtils/searchPaging.component.ts new file mode 100644 index 00000000..5044baa3 --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/searchPaging.component.ts @@ -0,0 +1,58 @@ +import {Component, Input, Output, EventEmitter} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {ErrorCodes} from '../../utils/properties/openaireProperties'; + +@Component({ + selector: 'search-paging', + template: ` +
    +
    + {{searchUtils.totalResults}} {{type}}, page {{searchUtils.page}} of {{(totalPages(searchUtils.totalResults))}} +
    +
    + {{oldTotalResults}} {{type}}, page {{searchUtils.page}} of {{(totalPages(oldTotalResults))}} +
    +
    + +
    +
    + +
    +
    + ` +}) + +export class SearchPagingComponent { + @Input() searchUtils; + @Input() results; + @Input() baseUrl; + @Input() type; + @Input() parameterNames:string[]; + @Input() parameterValues:string[]; + + @Input() loadPaging: boolean = true; + @Input() oldTotalResults: number = 0; + + public totalResults: number = 0; + public errorCodes:ErrorCodes = new ErrorCodes(); + + // @Input() totalResults:number = 0; + constructor () {} + + ngOnInit() { + // this.totalResults = this.searchUtils.totalResults; + // if(!this.loadPaging && this.totalResults == 0) { + // this.totalResults = this.oldTotalResults; + // } + } + + totalPages(totalResults: number): number { + let totalPages:any = totalResults/(this.searchUtils.size); + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, 10) + 1); + } + return totalPages; + } + + +} diff --git a/portal-4cli/src/app/searchPages/searchUtils/searchPaging.module.ts b/portal-4cli/src/app/searchPages/searchUtils/searchPaging.module.ts new file mode 100644 index 00000000..4a403bd1 --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/searchPaging.module.ts @@ -0,0 +1,23 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{SearchPagingComponent} from './searchPaging.component'; +import{PagingModule} from '../../utils/paging.module'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, PagingModule + ], + declarations: [ + SearchPagingComponent +], + + providers:[ + ], + exports: [ + SearchPagingComponent + + ] +}) +export class SearchPagingModule { } diff --git a/portal-4cli/src/app/searchPages/searchUtils/searchResult.component.html b/portal-4cli/src/app/searchPages/searchUtils/searchResult.component.html new file mode 100644 index 00000000..47e73654 --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/searchResult.component.html @@ -0,0 +1,124 @@ + diff --git a/portal-4cli/src/app/searchPages/searchUtils/searchResult.component.ts b/portal-4cli/src/app/searchPages/searchUtils/searchResult.component.ts new file mode 100644 index 00000000..cca7ba9f --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/searchResult.component.ts @@ -0,0 +1,52 @@ +import {Component, Input} from '@angular/core'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {RouterHelper} from '../../utils/routerHelper.class'; + +@Component({ + selector: 'search-result', + templateUrl:'searchResult.component.html' +}) + +export class SearchResultComponent { + @Input() results: SearchResult[]; + @Input() status: number; + @Input() type: string; + @Input() showLoading: boolean = false; + @Input() showSubjects: boolean = false; + @Input() custom_class: string = "search-results"; + + public urlParam: string; + public linkToAdvancedSearchPage: string; + public errorCodes:ErrorCodes = new ErrorCodes(); + public routerHelper:RouterHelper = new RouterHelper(); + public errorMessage: string = "No results found"; + + constructor () {} + + ngOnInit() { + if(this.type == "publication") { + this.linkToAdvancedSearchPage = OpenaireProperties.getLinkToAdvancedSearchPublications(); + this.urlParam = "articleId"; + } else if(this.type == "dataset") { + this.linkToAdvancedSearchPage = OpenaireProperties.getLinkToAdvancedSearchDatasets(); + this.urlParam = "datasetId"; + } else if(this.type == "software") { + this.linkToAdvancedSearchPage = OpenaireProperties.getLinkToAdvancedSearchSoftware(); + this.urlParam = "softwareId"; + } else if(this.type == "project") { + this.linkToAdvancedSearchPage = OpenaireProperties.getLinkToAdvancedSearchProjects(); + this.urlParam = "projectId"; + } else if(this.type == "organization") { + this.linkToAdvancedSearchPage = OpenaireProperties.getLinkToAdvancedSearchOrganizations(); + this.urlParam = "organizationId"; + } else if(this.type == "dataprovider") { + this.linkToAdvancedSearchPage = OpenaireProperties.getLinkToAdvancedSearchDataProviders(); + this.urlParam = "datasourceId"; + } + } + + public quote(params: string):string { + return '"'+params+'"'; + } +} diff --git a/portal-4cli/src/app/searchPages/searchUtils/searchResults.module.ts b/portal-4cli/src/app/searchPages/searchUtils/searchResults.module.ts new file mode 100644 index 00000000..0ca38971 --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/searchResults.module.ts @@ -0,0 +1,29 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import {ErrorMessagesModule} from '../../utils/errorMessages.module'; + +import {SearchResult} from '../../utils/entities/searchResult'; +import {SearchResultComponent} from './searchResult.component'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + RouterModule, ErrorMessagesModule + ], + declarations: [ + SearchResultComponent, + +], + + providers:[ + ], + exports: [ + + SearchResultComponent + + ] +}) +export class SearchResultsModule { } diff --git a/portal-4cli/src/app/searchPages/searchUtils/searchUtils.class.ts b/portal-4cli/src/app/searchPages/searchUtils/searchUtils.class.ts new file mode 100644 index 00000000..da9fb9cb --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/searchUtils.class.ts @@ -0,0 +1,10 @@ +export class SearchUtilsClass{ + page:number = 1; + size:number = 10; + status:number = 1; + keyword:string = ""; + baseUrl:string = ""; + totalResults = 0; + totalResultsNoFilters:number; // for organization landing - tab with projects + +} diff --git a/portal-4cli/src/app/searchPages/searchUtils/tabResult.component.html b/portal-4cli/src/app/searchPages/searchUtils/tabResult.component.html new file mode 100644 index 00000000..da14e703 --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/tabResult.component.html @@ -0,0 +1,122 @@ + diff --git a/portal-4cli/src/app/searchPages/searchUtils/tabResult.component.ts b/portal-4cli/src/app/searchPages/searchUtils/tabResult.component.ts new file mode 100644 index 00000000..39576e56 --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/tabResult.component.ts @@ -0,0 +1,31 @@ +import {Component, Input} from '@angular/core'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {ErrorCodes} from '../../utils/properties/openaireProperties'; +import {RouterHelper} from '../../utils/routerHelper.class'; + +@Component({ + selector: 'tab-result', + templateUrl: 'tabResult.component.html' + }) + +export class TabResultComponent { + @Input() results: SearchResult[]; + @Input() status: number; + @Input() type: string; + @Input() urlParam: string; + @Input() showLoading: boolean = false; + @Input() showOrganizations: boolean = true; + + public errorCodes:ErrorCodes = new ErrorCodes(); + public routerHelper:RouterHelper = new RouterHelper(); + public errorMessage: string = "No results found"; + constructor () { + + } + + ngOnInit() {} + + public quote(params: string):string { + return '"'+params+'"'; + } +} diff --git a/portal-4cli/src/app/searchPages/searchUtils/tabResult.module.ts b/portal-4cli/src/app/searchPages/searchUtils/tabResult.module.ts new file mode 100644 index 00000000..589b5623 --- /dev/null +++ b/portal-4cli/src/app/searchPages/searchUtils/tabResult.module.ts @@ -0,0 +1,23 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {SearchResult} from '../../utils/entities/searchResult'; +import {TabResultComponent} from './tabResult.component'; +import {RouterModule} from '@angular/router'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + RouterModule + ], + declarations: [ + TabResultComponent, + ], + providers:[ + ], + exports: [ + TabResultComponent + ] +}) +export class TabResultModule { } diff --git a/portal-4cli/src/app/searchPages/simple/searchDataProviders-routing.module.ts b/portal-4cli/src/app/searchPages/simple/searchDataProviders-routing.module.ts new file mode 100644 index 00000000..c268a082 --- /dev/null +++ b/portal-4cli/src/app/searchPages/simple/searchDataProviders-routing.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import{SearchDataprovidersComponent} from './searchDataproviders.component'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: SearchDataprovidersComponent, canActivate: [FreeGuard, IsRouteEnabled], data: { + redirect: '/error' + }, canDeactivate: [PreviousRouteRecorder] } + + ]) + ] +}) +export class SearchDataProvidersRoutingModule { } diff --git a/portal-4cli/src/app/searchPages/simple/searchDataProviders.module.ts b/portal-4cli/src/app/searchPages/simple/searchDataProviders.module.ts new file mode 100644 index 00000000..45f1ef1b --- /dev/null +++ b/portal-4cli/src/app/searchPages/simple/searchDataProviders.module.ts @@ -0,0 +1,33 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{ SearchDataProvidersRoutingModule} from './searchDataProviders-routing.module'; +import{SearchDataprovidersComponent} from './searchDataproviders.component'; + +import {SearchResultsModule } from '../searchUtils/searchResults.module'; + +import {DataProvidersServiceModule} from '../../services/dataProvidersService.module'; +import {SearchFormModule} from '../searchUtils/searchForm.module'; +//import {SearchFilterModalModule} from '../searchUtils/searchFilterModal.module'; +import {SearchPageModule} from '../searchUtils/searchPage.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + + DataProvidersServiceModule, + SearchFormModule, SearchResultsModule, SearchDataProvidersRoutingModule, SearchPageModule + + ], + declarations: [ + SearchDataprovidersComponent + ], + providers:[FreeGuard, IsRouteEnabled], + exports: [ + SearchDataprovidersComponent + ] +}) +export class SearchDataProvidersModule { } diff --git a/portal-4cli/src/app/searchPages/simple/searchDataproviders.component.ts b/portal-4cli/src/app/searchPages/simple/searchDataproviders.component.ts new file mode 100644 index 00000000..8e57cd16 --- /dev/null +++ b/portal-4cli/src/app/searchPages/simple/searchDataproviders.component.ts @@ -0,0 +1,360 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import { ActivatedRoute} from '@angular/router'; +import {Location} from '@angular/common'; +import { Filter, Value} from '../searchUtils/searchHelperClasses.class'; +import {SearchDataprovidersService} from '../../services/searchDataproviders.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchFields} from '../../utils/properties/searchFields'; +import {SearchPageComponent } from '../searchUtils/searchPage.component'; +import {SearchUtilsClass } from '../searchUtils/searchUtils.class'; + +@Component({ + selector: 'search-dataproviders', + template: ` + + + + + ` +}) +export class SearchDataprovidersComponent { + private errorCodes: ErrorCodes; + + public results =[]; + public filters =[]; + public totalResults:number = 0 ; + public baseUrl:string; + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public sub: any; public subResults: any; + public _location:Location; + public searchFields:SearchFields = new SearchFields(); + public refineFields: string[] = this.searchFields.DATASOURCE_REFINE_FIELDS; + public fieldIdsMap= this.searchFields.DATASOURCE_FIELDS; + public CSV: any = { "columnNames": [ "Title", "Type", "Coutries", "Compatibility" ], + "export":[] + }; + public CSVDownloaded = false; + public csvParams: string; + + public disableForms: boolean = false; + public loadPaging: boolean = true; + public oldTotalResults: number = 0; + + @ViewChild (SearchPageComponent) searchPage : SearchPageComponent ; + + constructor (private route: ActivatedRoute, private _searchDataprovidersService: SearchDataprovidersService ) { + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.searchUtils.page =1; + this.baseUrl = OpenaireProperties.getLinkToSearchDataProviders(); + } + + public ngOnInit() { + this.searchPage.refineFields = this.refineFields; + this.searchPage.fieldIdsMap = this.fieldIdsMap; + var firstLoad =true; + + this.sub = this.route.queryParams.subscribe(params => { + if(params['page'] && this.searchUtils.page != params['page']) { + this.loadPaging = false; + this.oldTotalResults = this.searchUtils.totalResults; + } + + this.searchUtils.keyword = (params['keyword']?params['keyword']:''); + var refine = true; + if(this.searchUtils.page != ((params['page']=== undefined)?1:+params['page']) && this.filters && !firstLoad){ + refine = false; + + } + firstLoad = false; + this.searchUtils.page = (params['page']=== undefined)?1:+params['page']; + + var queryParameters = this.searchPage.getQueryParametersFromUrl(params); + this._getResults(queryParameters, refine, this.searchUtils.page, this.searchUtils.size); + }); + } + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } + } + + public getNumForEntity(entity: string, id:string) { + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + if(id != "" && entity != "") { + + this._searchDataprovidersService.numOfEntityDataproviders(id, entity).subscribe( + data => { + this.searchUtils.totalResults = data; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } + } + + public getNumForSearch(keyword: string) { + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + this._searchDataprovidersService.numOfDataproviders(keyword).subscribe( + data => { + this.searchUtils.totalResults = data; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } + +public getResultsForDeposit(id:string, type:string, page: number, size: number){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.status = errorCodes.LOADING; + if(id != "") { + + this._searchDataprovidersService.searchDataprovidersForDeposit(id,type, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Dataproviders forDeposit: [id:"+id+", type:"+type+" ] [total results:"+this.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } +} + public getResultsForEntity(entity:string, id:string, page: number, size: number){ + var parameters = ""; + + if(entity == "organization") { + parameters = "organizations/"+id; + } + + if(parameters != "") { + + this._searchDataprovidersService.searchDataprovidersForEntity(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Dataproviders for "+entity+": [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } + } + + public getResultsForDataproviders(id:string, page: number, size: number){ + + this._searchDataprovidersService.getDataProvidersforEntityRegistry(id, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Dataproviders for Entity Registry: [Id:"+id+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } + + public getResults(keyword:string,refine:boolean, page: number, size: number){ + var parameters = ""; + if(keyword.length > 0){ + parameters = "q="+ keyword; + } + this._getResults(parameters,refine,page,this.searchUtils.size); + } + private _getResults(parameters:string,refine:boolean, page: number, size: number){ + this.csvParams = parameters; + + // if(!refine && !this.searchPage){ + // this.searchPage = new SearchPageComponent(this._location); + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + //this.searchPage.openLoading(); + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + this.subResults = this._searchDataprovidersService.searchDataproviders(parameters,(refine)?this.searchPage.getRefineFieldsQuery():null, page, size, this.searchPage.getFields()).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Content Providers: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + if(refine){ + this.filters = data[2]; + } + this.searchPage.checkSelectedFilters(this.filters); + // this.filters = this.searchPage.checkSelectedFilters(data[2]); + this.searchPage.updateBaseUrlWithParameters(this.filters); + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + //this.searchPage.closeLoading(); + this.disableForms = false; + + if(this.searchUtils.status == this.errorCodes.DONE) { + // Page out of limit!!! + let totalPages:any = this.searchUtils.totalResults/(this.searchUtils.size); + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, 10) + 1); + } + if(totalPages < page) { + this.searchUtils.totalResults = 0; + this.searchUtils.status = this.errorCodes.OUT_OF_BOUND; + } + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + //this.searchPage.closeLoading(); + this.disableForms = false; + } + ); + } + + private setFilters(){ + //TODO set filters from + } + + public queryChanged($event) { + this.loadPaging = true; + + var parameters = $event.value; + this._getResults(parameters, true, this.searchUtils.page, this.searchUtils.size); + } +} diff --git a/portal-4cli/src/app/searchPages/simple/searchDatasets-routing.module.ts b/portal-4cli/src/app/searchPages/simple/searchDatasets-routing.module.ts new file mode 100644 index 00000000..6e970898 --- /dev/null +++ b/portal-4cli/src/app/searchPages/simple/searchDatasets-routing.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import{SearchDatasetsComponent} from './searchDatasets.component'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: SearchDatasetsComponent, canActivate: [FreeGuard, IsRouteEnabled], data: { + redirect: '/error' + }, canDeactivate: [PreviousRouteRecorder] } + + ]) + ] +}) +export class SearchDatasetsRoutingModule { } diff --git a/portal-4cli/src/app/searchPages/simple/searchDatasets.component.ts b/portal-4cli/src/app/searchPages/simple/searchDatasets.component.ts new file mode 100644 index 00000000..60a8099a --- /dev/null +++ b/portal-4cli/src/app/searchPages/simple/searchDatasets.component.ts @@ -0,0 +1,275 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import { ActivatedRoute} from '@angular/router'; +import {Location} from '@angular/common'; +import { Filter, Value} from '../searchUtils/searchHelperClasses.class'; + +import {SearchDatasetsService} from '../../services/searchDatasets.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchFields} from '../../utils/properties/searchFields'; +import {SearchPageComponent } from '../searchUtils/searchPage.component'; +import {SearchUtilsClass } from '../searchUtils/searchUtils.class'; +import {DOI} from '../../utils/string-utils.class'; + +@Component({ + selector: 'search-datasets', + template: ` + + + + ` +}) + +export class SearchDatasetsComponent { + private errorCodes: ErrorCodes; + + public results =[]; + public filters: Filter[] =[]; + // public totalResults:number = 0 ; + public baseUrl:string; + + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + private sub: any; + private subResults: any; + private searchFields:SearchFields = new SearchFields(); + public refineFields: string[] = this.searchFields.RESULT_REFINE_FIELDS; + public fieldIdsMap=this.searchFields.RESULT_FIELDS; + private urlParams : Map; + private _location:Location; + public csvParams: string; + public disableForms: boolean = false; + public loadPaging: boolean = true; + public oldTotalResults: number = 0; + + @ViewChild (SearchPageComponent) searchPage : SearchPageComponent ; + constructor (private route: ActivatedRoute, private _searchDatasetsService: SearchDatasetsService ) { + + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.searchUtils.page =1; + this.baseUrl = OpenaireProperties.getLinkToSearchDatasets(); + + } + + public ngOnInit() { + this.searchPage.refineFields = this.refineFields; + this.searchPage.fieldIdsMap = this.fieldIdsMap; + this.searchPage.type = "research data"; + var firstLoad =true; + this.sub = this.route.queryParams.subscribe(params => { + if(params['page'] && this.searchUtils.page != params['page']) { + this.loadPaging = false; + this.oldTotalResults = this.searchUtils.totalResults; + } + + this.searchUtils.keyword = (params['keyword']?params['keyword']:''); + var refine = true; + if(this.searchUtils.page != ((params['page']=== undefined)?1:+params['page']) && this.filters && !firstLoad){ + refine = false; + } + firstLoad = false; + this.searchUtils.page = (params['page']=== undefined)?1:+params['page']; + + var queryParameters = this.searchPage.getQueryParametersFromUrl(params); + this._getResults(queryParameters, refine, this.searchUtils.page, this.searchUtils.size); + + }); + } + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } + } + + +public getResultsForEntity(entity:string, id:string, page: number, size: number){ + var parameters = ""; + + if(entity == "project") { + parameters = "projects/"+id; + } + + if(parameters != "") { + + this._searchDatasetsService.searchDatasetsForEntity(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Research Data for "+entity+": [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } +} + +public getResultsForDataproviders(id:string, resultsFrom:string, page: number, size: number){ + var parameters; + if(resultsFrom == "collectedFrom") { + parameters = "datasets?fq=collectedfromdatasourceid exact "+'"'+id+'"'; + } else if(resultsFrom == "hostedBy") { + parameters = "datasets?fq=resulthostingdatasourceid exact "+'"'+id+'"'; + } + + if(parameters != "") { + + this._searchDatasetsService.searchDatasetsForDataproviders(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Research Data for Dataproviders: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } +} + +public getResults(keyword:string,refine:boolean, page: number, size: number){ + var parameters = ""; + if(keyword.length > 0){ + var DOIs:string[] = DOI.getDOIsFromString(keyword); + var doisParams = ""; + for(var i =0 ;i < DOIs.length; i++){ + doisParams+=(doisParams.length > 0?"&":"")+'doi="'+ DOIs[i]+'"'; + } + if(doisParams.length > 0){ + parameters += "&"+doisParams; + }else{ + parameters = "q=" + keyword; + } + } + this._getResults(parameters,refine,page,size); +} +private _getResults(parameters:string,refine:boolean, page: number, size: number){ + this.csvParams = parameters; + + // if(!refine && !this.searchPage){ + // this.searchPage = new SearchPageComponent(this._location); + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + //this.searchPage.openLoading(); + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + this.subResults = this._searchDatasetsService.searchDatasets(parameters,(refine)?this.searchPage.getRefineFieldsQuery():null, page, size, this.searchPage.getFields()).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Research Data: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + if(refine){ + this.filters = data[2]; + } + this.searchPage.checkSelectedFilters(this.filters); + this.searchPage.updateBaseUrlWithParameters(this.filters); + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + //this.searchPage.closeLoading(); + this.disableForms = false; + + if(this.searchUtils.status == this.errorCodes.DONE) { + // Page out of limit!!! + let totalPages:any = this.searchUtils.totalResults/(this.searchUtils.size); + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, 10) + 1); + } + if(totalPages < page) { + this.searchUtils.totalResults = 0; + this.searchUtils.status = this.errorCodes.OUT_OF_BOUND; + } + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + //this.searchPage.closeLoading(); + this.disableForms = false; + } + ); +} + + + + private setFilters(){ + //TODO set filters from + } + + public queryChanged($event) { + this.loadPaging = true; + + var parameters = $event.value; + //this.getResults(parameters, this.searchUtils.page, this.searchUtils.size, "searchPage"); + this._getResults(parameters, true, this.searchUtils.page, this.searchUtils.size); + } +} diff --git a/portal-4cli/src/app/searchPages/simple/searchDatasets.module.ts b/portal-4cli/src/app/searchPages/simple/searchDatasets.module.ts new file mode 100644 index 00000000..7bb43a80 --- /dev/null +++ b/portal-4cli/src/app/searchPages/simple/searchDatasets.module.ts @@ -0,0 +1,33 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{ SearchDatasetsRoutingModule} from './searchDatasets-routing.module'; +import{SearchDatasetsComponent} from './searchDatasets.component'; + +import {SearchResultsModule } from '../searchUtils/searchResults.module'; + +import {DatasetsServiceModule} from '../../services/datasetsService.module'; +import {SearchFormModule} from '../searchUtils/searchForm.module'; +//import {SearchFilterModalModule} from '../searchUtils/searchFilterModal.module'; +import {SearchPageModule} from '../searchUtils/searchPage.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + + DatasetsServiceModule, + SearchFormModule, SearchResultsModule, SearchDatasetsRoutingModule, SearchPageModule + + ], + declarations: [ + SearchDatasetsComponent + ], + providers:[FreeGuard, IsRouteEnabled], + exports: [ + SearchDatasetsComponent + ] +}) +export class SearchDatasetsModule { } diff --git a/portal-4cli/src/app/searchPages/simple/searchOrganizations-routing.module.ts b/portal-4cli/src/app/searchPages/simple/searchOrganizations-routing.module.ts new file mode 100644 index 00000000..a2b4ad8c --- /dev/null +++ b/portal-4cli/src/app/searchPages/simple/searchOrganizations-routing.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import{SearchOrganizationsComponent} from './searchOrganizations.component'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: SearchOrganizationsComponent, canActivate: [FreeGuard, IsRouteEnabled], data: { + redirect: '/error' + }, canDeactivate: [PreviousRouteRecorder] } + + ]) + ] +}) +export class SearchOrganizationsRoutingModule { } diff --git a/portal-4cli/src/app/searchPages/simple/searchOrganizations.component.ts b/portal-4cli/src/app/searchPages/simple/searchOrganizations.component.ts new file mode 100644 index 00000000..12c5d7ec --- /dev/null +++ b/portal-4cli/src/app/searchPages/simple/searchOrganizations.component.ts @@ -0,0 +1,175 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import { ActivatedRoute} from '@angular/router'; +import {Location} from '@angular/common'; +import { Filter, Value} from '../searchUtils/searchHelperClasses.class'; +import {SearchOrganizationsService} from '../../services/searchOrganizations.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchFields} from '../../utils/properties/searchFields'; +import {SearchPageComponent } from '../searchUtils/searchPage.component'; +import {SearchUtilsClass } from '../searchUtils/searchUtils.class'; + +@Component({ + selector: 'search-organizations', + template: ` + + + + + ` + +}) +export class SearchOrganizationsComponent { + private errorCodes: ErrorCodes; + + public results =[]; + public filters =[]; + public baseUrl:string; + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public sub: any; + public subResults: any; + public searchFields:SearchFields = new SearchFields(); + public refineFields: string[] = this.searchFields.ORGANIZATION_REFINE_FIELDS; + public fieldIdsMap = this.searchFields.ORGANIZATION_FIELDS; + public urlParams : Map; + public _location:Location; + public csvParams: string; + public disableForms: boolean = false; + public loadPaging: boolean = true; + public oldTotalResults: number = 0; + + @ViewChild (SearchPageComponent) searchPage : SearchPageComponent ; + + constructor (private route: ActivatedRoute, private _searchOrganizationsService: SearchOrganizationsService ) { + + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.searchUtils.page =1; + this.baseUrl = OpenaireProperties.getLinkToSearchOrganizations(); + + } + + public ngOnInit() { + this.searchPage.refineFields = this.refineFields; + this.searchPage.fieldIdsMap = this.fieldIdsMap; + var firstLoad = true; + this.sub = this.route.queryParams.subscribe(params => { + if(params['page'] && this.searchUtils.page != params['page']) { + this.loadPaging = false; + this.oldTotalResults = this.searchUtils.totalResults; + } + + this.searchUtils.keyword = (params['keyword']?params['keyword']:''); + var refine = true; + if(this.searchUtils.page != ((params['page']=== undefined)?1:+params['page']) && this.filters && !firstLoad){ + refine = false; + + } + firstLoad = false; + this.searchUtils.page = (params['page']=== undefined)?1:+params['page']; + + var queryParameters = this.searchPage.getQueryParametersFromUrl(params); + this._getResults(queryParameters, refine, this.searchUtils.page, this.searchUtils.size); + }); + } + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } + } + + + public getResults(keyword:string,refine:boolean, page: number, size: number){ + var parameters = ""; + if(keyword.length > 0){ + parameters = "q=" + keyword; + } + this._getResults(parameters,refine,page,this.searchUtils.size); + } + private _getResults(parameters:string,refine:boolean, page: number, size: number){ + this.csvParams = parameters; + + // if(!refine && !this.searchPage){ + // this.searchPage = new SearchPageComponent(this._location); + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + //this.searchPage.openLoading(); + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + this.subResults = this._searchOrganizationsService.searchOrganizations(parameters,(refine)?this.searchPage.getRefineFieldsQuery():null, page, size, this.searchPage.getFields()).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Organizations: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + if(refine){ + this.filters = data[2]; + } + this.searchPage.checkSelectedFilters(this.filters); + this.searchPage.updateBaseUrlWithParameters(this.filters); + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + //this.searchPage.closeLoading(); + this.disableForms = false; + + if(this.searchUtils.status == this.errorCodes.DONE) { + // Page out of limit!!! + let totalPages:any = this.searchUtils.totalResults/(this.searchUtils.size); + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, 10) + 1); + } + if(totalPages < page) { + this.searchUtils.totalResults = 0; + this.searchUtils.status = this.errorCodes.OUT_OF_BOUND; + } + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + //this.searchPage.closeLoading(); + this.disableForms = false; + } + ); + } + + + public queryChanged($event) { + this.loadPaging = true; + + var parameters = $event.value; + console.info("queryChanged: Execute search query "+parameters); + this._getResults(parameters, true, this.searchUtils.page, this.searchUtils.size); + } +} diff --git a/portal-4cli/src/app/searchPages/simple/searchOrganizations.module.ts b/portal-4cli/src/app/searchPages/simple/searchOrganizations.module.ts new file mode 100644 index 00000000..ca4c57d8 --- /dev/null +++ b/portal-4cli/src/app/searchPages/simple/searchOrganizations.module.ts @@ -0,0 +1,32 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{ SearchOrganizationsRoutingModule} from './searchOrganizations-routing.module'; +import{SearchOrganizationsComponent} from './searchOrganizations.component'; + +import {SearchResultsModule } from '../searchUtils/searchResults.module'; + +import {OrganizationsServiceModule} from '../../services/organizationsService.module'; +import {SearchFormModule} from '../searchUtils/searchForm.module'; +import {SearchPageModule} from '../searchUtils/searchPage.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + + OrganizationsServiceModule, + SearchFormModule, SearchResultsModule, SearchOrganizationsRoutingModule, SearchPageModule + + ], + declarations: [ + SearchOrganizationsComponent + ], + providers:[FreeGuard, IsRouteEnabled], + exports: [ + SearchOrganizationsComponent + ] +}) +export class SearchOrganizationsModule { } diff --git a/portal-4cli/src/app/searchPages/simple/searchProjects-routing.module.ts b/portal-4cli/src/app/searchPages/simple/searchProjects-routing.module.ts new file mode 100644 index 00000000..37ad2a39 --- /dev/null +++ b/portal-4cli/src/app/searchPages/simple/searchProjects-routing.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import{SearchProjectsComponent} from './searchProjects.component'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: SearchProjectsComponent, canActivate: [FreeGuard, IsRouteEnabled], data: { + redirect: '/error' + }, canDeactivate: [PreviousRouteRecorder] } + + ]) + ] +}) +export class SearchProjectsRoutingModule { } diff --git a/portal-4cli/src/app/searchPages/simple/searchProjects.component.ts b/portal-4cli/src/app/searchPages/simple/searchProjects.component.ts new file mode 100644 index 00000000..0c7bbb5f --- /dev/null +++ b/portal-4cli/src/app/searchPages/simple/searchProjects.component.ts @@ -0,0 +1,213 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import { ActivatedRoute} from '@angular/router'; +import {Location} from '@angular/common'; +import { Filter, Value} from '../searchUtils/searchHelperClasses.class'; +import {SearchProjectsService} from '../../services/searchProjects.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchFields} from '../../utils/properties/searchFields'; +import {SearchPageComponent } from '../searchUtils/searchPage.component'; +import {SearchUtilsClass } from '../searchUtils/searchUtils.class'; + +@Component({ + selector: 'search-projects', + template: ` + + + + ` + +}) +export class SearchProjectsComponent { + private errorCodes: ErrorCodes; + + public results =[]; + public filters: Filter[] =[]; + public baseUrl:string; + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public sub: any; + public subResults: any; + public searchFields:SearchFields = new SearchFields(); + public refineFields: string[] = this.searchFields.PROJECT_REFINE_FIELDS; + public fieldIdsMap = this.searchFields.PROJECT_FIELDS; + public urlParams : Map; + public _location:Location; + public csvParams: string; + public disableForms: boolean = false; + public loadPaging: boolean = true; + public oldTotalResults: number = 0; + + @ViewChild (SearchPageComponent) searchPage : SearchPageComponent ; + + constructor (private route: ActivatedRoute, private _searchProjectsService: SearchProjectsService) { + console.info(" constructor SearchProjectsComponent "+this.refineFields.length); + + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.searchUtils.page =1; + this.baseUrl = OpenaireProperties.getLinkToSearchProjects(); + + } + + public ngOnInit() { + this.searchPage.refineFields = this.refineFields; + this.searchPage.fieldIdsMap = this.fieldIdsMap; + console.info(" ngOnInit SearchProjectsComponent "+this.refineFields.length); + //get refine field filters from url parameters + var firstLoad = true; + this.sub = this.route.queryParams.subscribe(params => { + if(params['page'] && this.searchUtils.page != params['page']) { + this.loadPaging = false; + this.oldTotalResults = this.searchUtils.totalResults; + } + + //get keyword from url parameters + this.searchUtils.keyword = (params['keyword']?params['keyword']:''); + var refine = true; + if(this.searchUtils.page != ((params['page']=== undefined)?1:+params['page']) && this.filters && !firstLoad){ + refine = false; + + } + firstLoad = false; + //get page from url parameters + this.searchUtils.page = (params['page']=== undefined)?1:+params['page']; + var queryParameters = this.searchPage.getQueryParametersFromUrl(params); + this._getResults(queryParameters, refine, this.searchUtils.page, this.searchUtils.size); + }); + } + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } + } + + public getResults(keyword:string,refine:boolean, page: number, size: number){ + var parameters = ""; + if(keyword.length > 0){ + parameters = "q="+keyword; + } + this._getResults(parameters,refine,page,this.searchUtils.size); + } + private _getResults(parameters:string,refine:boolean, page: number, size: number){ + this.csvParams = parameters; + + // if(!refine && !this.searchPage){ + // this.searchPage = new SearchPageComponent(this._location); + // } + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + //this.searchPage.openLoading(); + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + this.subResults = this._searchProjectsService.searchProjects(parameters,(refine)?this.searchPage.getRefineFieldsQuery():null, page, size, this.searchPage.getFields()).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Projects: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + if(refine){ + this.filters = data[2]; + } + this.searchPage.checkSelectedFilters(this.filters); + // this.filters = this.searchPage.checkSelectedFilters(data[2]); + this.searchPage.updateBaseUrlWithParameters(this.filters); + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + //this.searchPage.closeLoading(); + this.disableForms = false; + + if(this.searchUtils.status == this.errorCodes.DONE) { + // Page out of limit!!! + let totalPages:any = this.searchUtils.totalResults/(this.searchUtils.size); + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, 10) + 1); + } + if(totalPages < page) { + this.searchUtils.totalResults = 0; + this.searchUtils.status = this.errorCodes.OUT_OF_BOUND; + } + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + //this.searchPage.closeLoading(); + this.disableForms = false; + } + ); + } + + public getResultsForDataproviders(id:string, page: number, size: number){ + + this._searchProjectsService.getProjectsforDataProvider(id, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Projects for Dataproviders: [Id:"+id+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } + + + public queryChanged($event) { + this.loadPaging = true; + + this.urlParams = undefined; + var parameters = $event.value; + this._getResults(parameters, true, this.searchUtils.page, this.searchUtils.size); + } + +} diff --git a/portal-4cli/src/app/searchPages/simple/searchProjects.module.ts b/portal-4cli/src/app/searchPages/simple/searchProjects.module.ts new file mode 100644 index 00000000..6a6d68ef --- /dev/null +++ b/portal-4cli/src/app/searchPages/simple/searchProjects.module.ts @@ -0,0 +1,33 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{ SearchProjectsRoutingModule} from './searchProjects-routing.module'; +import{SearchProjectsComponent} from './searchProjects.component'; + +import {SearchResultsModule } from '../searchUtils/searchResults.module'; + +import {ProjectsServiceModule} from '../../services/projectsService.module'; +import {SearchFormModule} from '../searchUtils/searchForm.module'; +//import {SearchFilterModalModule} from '../searchUtils/searchFilterModal.module'; +import {SearchPageModule} from '../searchUtils/searchPage.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + + ProjectsServiceModule, + SearchFormModule, SearchResultsModule, SearchProjectsRoutingModule, SearchPageModule + + ], + declarations: [ + SearchProjectsComponent + ], + providers:[FreeGuard, IsRouteEnabled], + exports: [ + SearchProjectsComponent + ] +}) +export class SearchProjectsModule { } diff --git a/portal-4cli/src/app/searchPages/simple/searchPublications-routing.module.ts b/portal-4cli/src/app/searchPages/simple/searchPublications-routing.module.ts new file mode 100644 index 00000000..97bebe07 --- /dev/null +++ b/portal-4cli/src/app/searchPages/simple/searchPublications-routing.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import{SearchPublicationsComponent} from './searchPublications.component'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: SearchPublicationsComponent, canActivate: [FreeGuard, IsRouteEnabled], data: { + redirect: '/error' + }, canDeactivate: [PreviousRouteRecorder] } + + ]) + ] +}) +export class SearchPublicationsRoutingModule { } diff --git a/portal-4cli/src/app/searchPages/simple/searchPublications.component.ts b/portal-4cli/src/app/searchPages/simple/searchPublications.component.ts new file mode 100644 index 00000000..2d667f14 --- /dev/null +++ b/portal-4cli/src/app/searchPages/simple/searchPublications.component.ts @@ -0,0 +1,308 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import { ActivatedRoute} from '@angular/router'; +import {Location} from '@angular/common'; + +import { Filter, Value} from '../searchUtils/searchHelperClasses.class'; + +import {SearchPublicationsService} from '../../services/searchPublications.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchFields} from '../../utils/properties/searchFields'; +import {SearchPageComponent } from '../searchUtils/searchPage.component'; +import {SearchUtilsClass} from '../searchUtils/searchUtils.class'; +import {DOI} from '../../utils/string-utils.class'; + +@Component({ + selector: 'search-publications', + template: ` + + + + + ` + +}) +export class SearchPublicationsComponent { + private errorCodes: ErrorCodes; + + public results =[]; + public filters =[]; + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public baseUrl:string = ""; + public sub: any; + public subResults: any; + public searchFields:SearchFields = new SearchFields(); + public refineFields: string[] = this.searchFields.RESULT_REFINE_FIELDS; + public fieldIdsMap=this.searchFields.RESULT_FIELDS; + //: { [key:string] :{ name:string, operator:string, type:string, indexField:string, equalityOperator:string }} = this.searchFields.PUBLICATION_FIELDS_MAP; + public urlParams : Map; + @ViewChild (SearchPageComponent) searchPage : SearchPageComponent ; + public _location:Location; + + public CSV: any = { "columnNames": ["Title", "Authors", "Publication Year", "DOI", + /*"Download From", "Publication type", "Journal",*/ + "Funder", "Project Name (GA Number)", "Access"], + "export":[] + }; + public CSVDownloaded = false; + public csvParams: string; + public disableForms: boolean = false; + public loadPaging: boolean = true; + public oldTotalResults: number = 0; + + constructor (private route: ActivatedRoute, private _searchPublicationsService: SearchPublicationsService ) { + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.searchUtils.page =1; + this.baseUrl = OpenaireProperties.getLinkToSearchPublications(); + + } + + public ngOnInit() { + this.searchPage.refineFields = this.refineFields; + this.searchPage.fieldIdsMap = this.fieldIdsMap; + this.searchPage.type = "publications"; + var firstLoad =true; + this.sub = this.route.queryParams.subscribe(params => { + if(params['page'] && this.searchUtils.page != params['page']) { + this.loadPaging = false; + this.oldTotalResults = this.searchUtils.totalResults; + } + + this.searchUtils.keyword = (params['keyword']?params['keyword']:''); + var refine = true; + if(this.searchUtils.page != ((params['page']=== undefined)?1:+params['page']) && this.filters && !firstLoad){ + refine = false; + + } + firstLoad = false; + this.searchUtils.page = (params['page']=== undefined)?1:+params['page']; + var queryParameters = this.searchPage.getQueryParametersFromUrl(params); + this._getResults(queryParameters, refine, this.searchUtils.page, this.searchUtils.size); + }); + } + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } + } + +public getResultsForEntity(entity:string, id:string, page: number, size: number){ + var parameters = ""; + + if(entity == "project") { + parameters = "projects/"+id; + } + + if(parameters != "") { + + this._searchPublicationsService.searchPublicationsForEntity(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Publications for "+entity+": [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } +} + +public getResultsForDataproviders(id:string, resultsFrom:string, page: number, size: number){ + var parameters; + if(resultsFrom == "collectedFrom") { + parameters = "publications?fq=collectedfromdatasourceid exact "+'"'+id+'"'; + } else if(resultsFrom == "hostedBy") { + parameters = "publications?fq=resulthostingdatasourceid exact "+'"'+id+'"'; + } + + if(parameters != "") { + + this._searchPublicationsService.searchPublicationsForDataproviders(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Publications for Dataproviders: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } +} + +public getResults(keyword:string,refine:boolean, page: number, size: number){ + var parameters = ""; + if(keyword.length > 0){ + var DOIs:string[] = DOI.getDOIsFromString(keyword); + var doisParams = ""; + + for(var i =0 ;i < DOIs.length; i++){ + doisParams+=(doisParams.length > 0?"&":"")+'doi="'+ DOIs[i]+'"'; + } + if(doisParams.length > 0){ + parameters += "&"+doisParams; + }else{ + parameters = "q=" + keyword; + } + } + this._getResults(parameters,refine,page,size); +} + +private _getResults(parameters:string,refine:boolean, page: number, size: number){ + this.csvParams = parameters; + + // if(!refine && !this.searchPage){ + // this.searchPage = new SearchPageComponent(this._location); + // } + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + //this.searchPage.openLoading(); + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + this.subResults = this._searchPublicationsService.searchPublications(parameters,(refine)?this.searchPage.getRefineFieldsQuery():null, page, size, this.searchPage.getFields()).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Publications: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + if(refine){ + this.filters = data[2]; + } + this.searchPage.checkSelectedFilters(this.filters); + this.searchPage.updateBaseUrlWithParameters(this.filters); + + //var errorCodes:ErrorCodes = new ErrorCodes(); + + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + //this.searchPage.closeLoading(); + this.disableForms = false; + + if(this.searchUtils.status == this.errorCodes.DONE) { + // Page out of limit!!! + let totalPages:any = this.searchUtils.totalResults/(this.searchUtils.size); + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, 10) + 1); + } + if(totalPages < page) { + this.searchUtils.totalResults = 0; + this.searchUtils.status = this.errorCodes.OUT_OF_BOUND; + } + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + //this.searchPage.closeLoading(); + this.disableForms = false; + + } + ); +} +/* +public getAggregatorResults(id:string, page: number, size: number){ + this.subResults = this._searchPublicationsService.searchAggregators('&fq=collectedfromdatasourceid exact "'+id+'"',"&refine=true&fields=resulthostingdatasource" , page, size).subscribe( + data => { + this.results = data; + + var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = errorCodes.ERROR; + } + ); +}*/ + + public queryChanged($event) { + this.loadPaging = true; + + var parameters = $event.value; + console.info("queryChanged: Execute search query "+parameters); + console.info("Search Pubs::page "+this.searchUtils.page); + this._getResults(parameters, true, this.searchUtils.page, this.searchUtils.size); + } + + +} diff --git a/portal-4cli/src/app/searchPages/simple/searchPublications.module.ts b/portal-4cli/src/app/searchPages/simple/searchPublications.module.ts new file mode 100644 index 00000000..784e29ac --- /dev/null +++ b/portal-4cli/src/app/searchPages/simple/searchPublications.module.ts @@ -0,0 +1,33 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{ SearchPublicationsRoutingModule} from './searchPublications-routing.module'; +import{SearchPublicationsComponent} from './searchPublications.component'; + +import {SearchResultsModule } from '../searchUtils/searchResults.module'; + +import {PublicationsServiceModule} from '../../services/publicationsService.module'; +import {SearchFormModule} from '../searchUtils/searchForm.module'; +//import {SearchFilterModalModule} from '../searchUtils/searchFilterModal.module'; +import {SearchPageModule} from '../searchUtils/searchPage.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + + PublicationsServiceModule, + SearchFormModule, SearchResultsModule, SearchPublicationsRoutingModule, SearchPageModule + + ], + declarations: [ + SearchPublicationsComponent + ], + providers:[FreeGuard, IsRouteEnabled], + exports: [ + SearchPublicationsComponent + ] +}) +export class SearchPublicationsModule { } diff --git a/portal-4cli/src/app/searchPages/simple/searchSoftware-routing.module.ts b/portal-4cli/src/app/searchPages/simple/searchSoftware-routing.module.ts new file mode 100644 index 00000000..0ec1e843 --- /dev/null +++ b/portal-4cli/src/app/searchPages/simple/searchSoftware-routing.module.ts @@ -0,0 +1,15 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import {SearchSoftwareComponent} from './searchSoftware.component'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: SearchSoftwareComponent, canActivate: [FreeGuard], canDeactivate: [PreviousRouteRecorder] } + + ]) + ] +}) +export class SearchSoftwareRoutingModule { } diff --git a/portal-4cli/src/app/searchPages/simple/searchSoftware.component.ts b/portal-4cli/src/app/searchPages/simple/searchSoftware.component.ts new file mode 100644 index 00000000..5e6e89c5 --- /dev/null +++ b/portal-4cli/src/app/searchPages/simple/searchSoftware.component.ts @@ -0,0 +1,275 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import { ActivatedRoute} from '@angular/router'; +import {Location} from '@angular/common'; +import { Filter, Value} from '../searchUtils/searchHelperClasses.class'; + +import {SearchSoftwareService} from '../../services/searchSoftware.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchFields} from '../../utils/properties/searchFields'; +import {SearchPageComponent } from '../searchUtils/searchPage.component'; +import {SearchUtilsClass } from '../searchUtils/searchUtils.class'; +import {DOI} from '../../utils/string-utils.class'; + +@Component({ + selector: 'search-software', + template: ` + + + + ` +}) + +export class SearchSoftwareComponent { + private errorCodes: ErrorCodes; + + public results =[]; + public filters: Filter[] =[]; + // public totalResults:number = 0 ; + public baseUrl:string; + + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + private sub: any; + private subResults: any; + private searchFields:SearchFields = new SearchFields(); + public refineFields: string[] = this.searchFields.RESULT_REFINE_FIELDS; + public fieldIdsMap=this.searchFields.RESULT_FIELDS; + private urlParams : Map; + private _location:Location; + public csvParams: string; + public disableForms: boolean = false; + public loadPaging: boolean = true; + public oldTotalResults: number = 0; + + @ViewChild (SearchPageComponent) searchPage : SearchPageComponent ; + constructor (private route: ActivatedRoute, private _searchSoftwareService: SearchSoftwareService ) { + + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.searchUtils.page =1; + this.baseUrl = OpenaireProperties.getLinkToSearchSoftware(); + + } + + public ngOnInit() { + this.searchPage.refineFields = this.refineFields; + this.searchPage.fieldIdsMap = this.fieldIdsMap; + this.searchPage.type = "software"; + var firstLoad =true; + this.sub = this.route.queryParams.subscribe(params => { + if(params['page'] && this.searchUtils.page != params['page']) { + this.loadPaging = false; + this.oldTotalResults = this.searchUtils.totalResults; + } + + this.searchUtils.keyword = (params['keyword']?params['keyword']:''); + var refine = true; + if(this.searchUtils.page != ((params['page']=== undefined)?1:+params['page']) && this.filters && !firstLoad){ + refine = false; + } + firstLoad = false; + this.searchUtils.page = (params['page']=== undefined)?1:+params['page']; + + var queryParameters = this.searchPage.getQueryParametersFromUrl(params); + this._getResults(queryParameters, refine, this.searchUtils.page, this.searchUtils.size); + + }); + } + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } + } + + +public getResultsForEntity(entity:string, id:string, page: number, size: number){ + var parameters = ""; + + if(entity == "project") { + parameters = "projects/"+id; + } + + if(parameters != "") { + + this._searchSoftwareService.searchSoftwareForEntity(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Software for "+entity+": [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } +} + +public getResultsForDataproviders(id:string, resultsFrom:string, page: number, size: number){ + var parameters; + if(resultsFrom == "collectedFrom") { + parameters = "software?fq=collectedfromdatasourceid exact "+'"'+id+'"'; + } else if(resultsFrom == "hostedBy") { + parameters = "software?fq=resulthostingdatasourceid exact "+'"'+id+'"'; + } + + if(parameters != "") { + + this._searchSoftwareService.searchSoftwareForDataproviders(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Software for Dataproviders: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } +} + +public getResults(keyword:string,refine:boolean, page: number, size: number){ + var parameters = ""; + if(keyword.length > 0){ + var DOIs:string[] = DOI.getDOIsFromString(keyword); + var doisParams = ""; + for(var i =0 ;i < DOIs.length; i++){ + doisParams+=(doisParams.length > 0?"&":"")+'doi="'+ DOIs[i]+'"'; + } + if(doisParams.length > 0){ + parameters += "&"+doisParams; + }else{ + parameters = "q=" + keyword; + } + } + this._getResults(parameters,refine,page,size); +} +private _getResults(parameters:string,refine:boolean, page: number, size: number){ + this.csvParams = parameters; + + // if(!refine && !this.searchPage){ + // this.searchPage = new SearchPageComponent(this._location); + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + //this.searchPage.openLoading(); + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + this.subResults = this._searchSoftwareService.searchSoftware(parameters,(refine)?this.searchPage.getRefineFieldsQuery():null, page, size, this.searchPage.getFields()).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Software: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + if(refine){ + this.filters = data[2]; + } + this.searchPage.checkSelectedFilters(this.filters); + this.searchPage.updateBaseUrlWithParameters(this.filters); + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + //this.searchPage.closeLoading(); + this.disableForms = false; + + if(this.searchUtils.status == this.errorCodes.DONE) { + // Page out of limit!!! + let totalPages:any = this.searchUtils.totalResults/(this.searchUtils.size); + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, 10) + 1); + } + if(totalPages < page) { + this.searchUtils.totalResults = 0; + this.searchUtils.status = this.errorCodes.OUT_OF_BOUND; + } + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + //this.searchPage.closeLoading(); + this.disableForms = false; + } + ); +} + + + + private setFilters(){ + //TODO set filters from + } + + public queryChanged($event) { + this.loadPaging = true; + + var parameters = $event.value; + //this.getResults(parameters, this.searchUtils.page, this.searchUtils.size, "searchPage"); + this._getResults(parameters, true, this.searchUtils.page, this.searchUtils.size); + } +} diff --git a/portal-4cli/src/app/searchPages/simple/searchSoftware.module.ts b/portal-4cli/src/app/searchPages/simple/searchSoftware.module.ts new file mode 100644 index 00000000..227cb49d --- /dev/null +++ b/portal-4cli/src/app/searchPages/simple/searchSoftware.module.ts @@ -0,0 +1,33 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{ SearchSoftwareRoutingModule} from './searchSoftware-routing.module'; +import{SearchSoftwareComponent} from './searchSoftware.component'; + +import {SearchResultsModule } from '../searchUtils/searchResults.module'; + +import {SoftwareServiceModule} from '../../services/softwareService.module'; +import {SearchFormModule} from '../searchUtils/searchForm.module'; +//import {SearchFilterModalModule} from '../searchUtils/searchFilterModal.module'; +import {SearchPageModule} from '../searchUtils/searchPage.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + + SoftwareServiceModule, + SearchFormModule, SearchResultsModule, SearchSoftwareRoutingModule, SearchPageModule + + ], + declarations: [ + SearchSoftwareComponent + ], + providers:[FreeGuard + ], + exports: [ + SearchSoftwareComponent + ] +}) +export class SearchSoftwareModule { } diff --git a/portal-4cli/src/app/services/dataProvidersService.module.ts b/portal-4cli/src/app/services/dataProvidersService.module.ts new file mode 100644 index 00000000..88e7b6df --- /dev/null +++ b/portal-4cli/src/app/services/dataProvidersService.module.ts @@ -0,0 +1,20 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {SearchDataprovidersService} from './searchDataproviders.service'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule + ], + declarations: [ + ], + providers:[ + SearchDataprovidersService +], + exports: [ + ] +}) +export class DataProvidersServiceModule { } diff --git a/portal-4cli/src/app/services/datasetsService.module.ts b/portal-4cli/src/app/services/datasetsService.module.ts new file mode 100644 index 00000000..e5298338 --- /dev/null +++ b/portal-4cli/src/app/services/datasetsService.module.ts @@ -0,0 +1,20 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {SearchDatasetsService} from './searchDatasets.service'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule + ], + declarations: [ + ], + providers:[ + SearchDatasetsService +], + exports: [ + ] +}) +export class DatasetsServiceModule { } diff --git a/portal-4cli/src/app/services/metrics.service.ts b/portal-4cli/src/app/services/metrics.service.ts new file mode 100644 index 00000000..b3b79b98 --- /dev/null +++ b/portal-4cli/src/app/services/metrics.service.ts @@ -0,0 +1,82 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {Metrics} from '../utils/entities/metrics'; +import {OpenaireProperties} from '../utils/properties/openaireProperties'; +import 'rxjs/add/operator/do'; +import { } from '../shared/cache.service'; +@Injectable() +export class MetricsService { + metrics: Metrics; + + constructor(private http: Http ) {} + + getMetrics (id: string, entityType: string):any { + console.info("getMetrics in service"); + //let url = OpenaireProperties. getSearchAPIURLLast() + 'publications/' +id+"?format=json"; + let url = OpenaireProperties.getMetricsAPIURL()+entityType+"/"+id+"/clicks"; + let key = url; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => this.parseMetrics(res["downloads"], res["views"], res["total_downloads"], res["total_views"], + res["total_openaire_views"], res["total_openaire_downloads"], res["pageviews"])); + } + + + parseMetrics(downloads: any, views: any, totalDownloads: string, totalViews: string, + totalOpenaireViews: string, totalOpenaireDownloads: string, pageViews: string): any { + this.metrics = new Metrics(); + + this.metrics.totalDownloads = totalDownloads; + this.metrics.totalViews = totalViews; + this.metrics.totalOpenaireViews = totalOpenaireViews; + this.metrics.totalOpenaireDownloads = totalOpenaireDownloads; + this.metrics.pageViews = pageViews; + + this.metrics.infos = new Map(); + + for(let i=0; i res.json()) + .map(res => res['results'][0]) + //.map(res => res[0]['result']['metadata']['oaf:entity']['oaf:organization']) + //.map(res => [res, res['rels']['rel']]) + .map(res => this.parseOrganizationInfo(res)); + + + } +/* + getMetrics (id: string):any { + console.info("getOrganizationMetrics in service"); + //let url = OpenaireProperties. getSearchAPIURLLast() + 'publications/' +id+"?format=json"; + let url = OpenaireProperties.getMetricsAPIURL()+"organizations/"+id+"/clicks"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => res['views']); + } +*/ + private handleError (error: Response) { + // in a real world app, we may send the error to some remote logging infrastructure + // instead of just logging it to the console + console.log(error); + return Observable.throw(error || 'Server error'); + } + + parseOrganizationInfo (data: any):any { + console.info("parseOrganizationInfo"); + this.organizationInfo = new OrganizationInfo(); + + let organization; + let relations; + + if(data != null) { + organization = data['result']['metadata']['oaf:entity']['oaf:organization']; + relations = data['result']['metadata']['oaf:entity']['oaf:organization']['rels']['rel']; + } else { + return null; + } + + if(organization != null) { + + if(organization.hasOwnProperty("websiteurl")) { + this.organizationInfo.title = {"name": organization.legalshortname, "url": organization.websiteurl}; + } else { + this.organizationInfo.title = {"name": organization.legalshortname, "url": ''}; + } + + this.organizationInfo.name = organization.legalname; + + if(this.organizationInfo.title.name == '') { + this.organizationInfo.title.name = this.organizationInfo.name; + } + + if(organization.hasOwnProperty("country")) { + this.organizationInfo.country = organization['country'].classname; + } + } + +//Comment Parsing Projects info +/* + if(data[1] != null) { + + let counter; + let length = relations.length!=undefined ? relations.length : 1; + + for(let i=0; i(); + } + + if(!this.organizationInfo.projects.has(relation['funding']['funder'].name)) { + this.organizationInfo.projects.set(relation['funding']['funder'].name, + new Array<{ "name": string, "id": string, "code": string, + "acronym": string, "funder": string, "funderId": string, + "fundingStream": string, "fundingLevel1": string, "fundingLevel2": string, + "sc39": string, "startDate": string, "endDate": string }>()); + } + + counter = this.organizationInfo.projects.get(relation['funding']['funder'].name).length; + this.organizationInfo.projects.get(relation['funding']['funder'].name)[counter] = + { "name": "", "id": "", "code": "", + "acronym": "", "funder": "", "funderId": "", + "fundingStream": "", "fundingLevel1": "", "fundingLevel2": "", + "sc39": "", "startDate": "", "endDate": "" }; + + //let url = ""; + if(relation['to'].content != null && relation['to'].content != "") { + this.organizationInfo.projects.get(relation['funding']['funder'].name)[counter]['id'] = relation['to'].content; + //url = OpenaireProperties.getsearchLinkToProject()+relation['to'].content; + } + this.organizationInfo.projects.get(relation['funding']['funder'].name)[counter]['name'] = relation.title; + //this.organizationInfo.projects.get(relation['funding']['funder'].name)[counter]['url'] = url; + this.organizationInfo.projects.get(relation['funding']['funder'].name)[counter]['code'] = relation.code; + this.organizationInfo.projects.get(relation['funding']['funder'].name)[counter]['acronym'] = relation.acronym; + + this.organizationInfo.projects.get(relation['funding']['funder'].name)[counter]['funder'] = relation['funding']['funder'].shortname; + this.organizationInfo.projects.get(relation['funding']['funder'].name)[counter]['funderId'] = relation['funding']['funder'].id; + if(relation['funding'].hasOwnProperty("funding_level_0")) { + this.organizationInfo.projects.get(relation['funding']['funder'].name)[counter]['fundingStream'] = relation['funding']['funding_level_0'].name; + } + if(relation['funding'].hasOwnProperty("funding_level_1")) { + this.organizationInfo.projects.get(relation['funding']['funder'].name)[counter]['fundingLevel1'] = relation['funding']['funding_level_1'].name; + } + if(relation['funding'].hasOwnProperty("funding_level_2")) { + this.organizationInfo.projects.get(relation['funding']['funder'].name)[counter]['fundingLevel2'] = relation['funding']['funding_level_2'].name; + } + //this.organizationInfo.projects.get(relation['funding']['funder'].name)[counter]['sc39'] = + //this.organizationInfo.projects.get(relation['funding']['funder'].name)[counter]['startDate'] = + //this.organizationInfo.projects.get(relation['funding']['funder'].name)[counter]['endDate'] = + } + } + + } + + + } /*else if(relation['to'].class == "isProvidedBy") { + + if(this.organizationInfo.dataProviders == undefined) { + this.organizationInfo.dataProviders = new Array<{ "name": string, "url": string, "type": string, "websiteUrl": string , "organizations": {"name": string, "url": string}[]}>(); + } + + counter = this.organizationInfo.dataProviders.length; + this.organizationInfo.dataProviders[counter] = { "name": "", "url": "", "type": "", "websiteUrl": "", "organizations": [] } + + let url=""; + if(relation['to'].content != null && relation['to'].content != "") { + url = OpenaireProperties.getsearchLinkToDataProvider()+relation['to'].content; + } + this.organizationInfo.dataProviders[counter]['name'] = relation.officialname; + this.organizationInfo.dataProviders[counter]['url'] = url; + if(relation.hasOwnProperty("datasourcetype")) { + this.organizationInfo.dataProviders[counter]['type'] = relation['datasourcetype'].classname; + } + this.organizationInfo.dataProviders[counter]['websiteUrl'] = relation.websiteurl; + }*/ +/* -----> + } + } + } +*/ + return this.organizationInfo; + + } + +} diff --git a/portal-4cli/src/app/services/organizationService.module.ts b/portal-4cli/src/app/services/organizationService.module.ts new file mode 100644 index 00000000..ee150c3e --- /dev/null +++ b/portal-4cli/src/app/services/organizationService.module.ts @@ -0,0 +1,20 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {OrganizationService} from './organization.service'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule + ], + declarations: [ + ], + providers:[ + OrganizationService +], + exports: [ + ] +}) +export class OrganizationServiceModule { } diff --git a/portal-4cli/src/app/services/organizationsService.module.ts b/portal-4cli/src/app/services/organizationsService.module.ts new file mode 100644 index 00000000..0810f680 --- /dev/null +++ b/portal-4cli/src/app/services/organizationsService.module.ts @@ -0,0 +1,20 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {SearchOrganizationsService} from './searchOrganizations.service'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule + ], + declarations: [ + ], + providers:[ + SearchOrganizationsService +], + exports: [ + ] +}) +export class OrganizationsServiceModule { } diff --git a/portal-4cli/src/app/services/projectsService.module.ts b/portal-4cli/src/app/services/projectsService.module.ts new file mode 100644 index 00000000..117f5ca7 --- /dev/null +++ b/portal-4cli/src/app/services/projectsService.module.ts @@ -0,0 +1,20 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {SearchProjectsService} from './searchProjects.service'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule + ], + declarations: [ + ], + providers:[ + SearchProjectsService +], + exports: [ + ] +}) +export class ProjectsServiceModule { } diff --git a/portal-4cli/src/app/services/publicationsService.module.ts b/portal-4cli/src/app/services/publicationsService.module.ts new file mode 100644 index 00000000..ab371386 --- /dev/null +++ b/portal-4cli/src/app/services/publicationsService.module.ts @@ -0,0 +1,20 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {SearchPublicationsService} from './searchPublications.service'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule + ], + declarations: [ + ], + providers:[ + SearchPublicationsService +], + exports: [ + ] +}) +export class PublicationsServiceModule { } diff --git a/portal-4cli/src/app/services/refineFieldResults.service.ts b/portal-4cli/src/app/services/refineFieldResults.service.ts new file mode 100644 index 00000000..71d3fe50 --- /dev/null +++ b/portal-4cli/src/app/services/refineFieldResults.service.ts @@ -0,0 +1,66 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {AutoCompleteValue} from '../searchPages/searchUtils/searchHelperClasses.class'; +import {OpenaireProperties} from '../utils/properties/openaireProperties'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; +import { } from '../shared/cache.service'; +import {RefineResultsUtils} from './servicesUtils/refineResults.class'; + +@Injectable() +export class RefineFieldResultsService { + // scoobydoo.di.uoa.gr:8181/dnet-functionality-services-2.0.0-SNAPSHOT/rest/v2/api/projects?refine=true&fields=funderid&page=1&size=0 + constructor(private http: Http ) {} + getRefineFieldsResultsByEntityName(fields:string[], entityName:string):any{ + let url = OpenaireProperties.getSearchAPIURLForEntity(entityName)+"?format=json&refine=true&page=1&size=0"; + for(var i=0; i < fields.length; i++){ + url += "&fields="+fields[i]; + } + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + + .map(res => [res['meta'].total, RefineResultsUtils.parse(res['refineResults'],fields, entityName)]); + + } + getRefineFieldResultsByFieldName(fieldName:string, entityName:string):any{ + let link = OpenaireProperties.getSearchAPIURLForEntity(entityName)+"?fields="+fieldName + "&format=json"; + return this.getField(link,fieldName) + + } + + getField (link:string,fieldName:string):any{ + let url = link+"&refine=true&page=1&size=0"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => res['refineResults']) + .map(res => this.parse(res,fieldName)); + + } + parse(data: any,fieldName:string):any { + var values:AutoCompleteValue[] = []; + if(data){ + let field = data[fieldName]; + for(let i=0; i new Blob([res['_body']], { type: 'text/csv' })); + } + getCSVResponse(url: string){ + var headers = new Headers(); + headers.append('responseType', 'arraybuffer'); + return this.http.get(url) + .map(res => res['_body']); + } + downloadHTMLFile(url: string, info: string){ + var headers = new Headers(); + headers.append('responseType', 'arraybuffer'); + return this.http.get(url) + .map(res => this.addInfo(res, info)) + .map(res => new Blob([res['_body']], { type: 'text/html' })) + .do(res => console.log(res)) + } + + addInfo(res:any, info:string) { + /* + var para = res.document.createElement("P"); // Create a

    element + var t = res.document.createTextNode("This is a paragraph"); // Create a text node + para.appendChild(t); // Append the text to

    + res.document.body.appendChild(para); + */ + res['_body'] = info+res['_body']; + return res; + } + + private handleError (error: Response) { + // in a real world app, we may send the error to some remote logging infrastructure + // instead of just logging it to the console + console.log(error); + return Observable.throw(error || 'Server error'); + } + + +} diff --git a/portal-4cli/src/app/services/reportsService.module.ts b/portal-4cli/src/app/services/reportsService.module.ts new file mode 100644 index 00000000..0d637dad --- /dev/null +++ b/portal-4cli/src/app/services/reportsService.module.ts @@ -0,0 +1,20 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {ReportsService} from './reports.service'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule + ], + declarations: [ + ], + providers:[ + ReportsService +], + exports: [ + ] +}) +export class ReportsServiceModule { } diff --git a/portal-4cli/src/app/services/searchDataproviders.service.ts b/portal-4cli/src/app/services/searchDataproviders.service.ts new file mode 100644 index 00000000..3f05580a --- /dev/null +++ b/portal-4cli/src/app/services/searchDataproviders.service.ts @@ -0,0 +1,433 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {OpenaireProperties} from '../utils/properties/openaireProperties'; +import {SearchResult} from '../utils/entities/searchResult'; +import {RefineResultsUtils} from './servicesUtils/refineResults.class'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; +import { } from '../shared/cache.service'; +import {StringUtils} from '../utils/string-utils.class'; +@Injectable() +export class SearchDataprovidersService { + constructor(private http: Http ) {} + + searchDataproviders (params: string, refineParams:string, page: number, size: number, refineFields:string[] ):any { + + let link = OpenaireProperties. getSearchAPIURLLast()+"datasources"; + + let url = link+"?"; + if(params!= null && params != '' ) { + url += params; + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+(page-1)+"&size="+size+"&format=json"; + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + .map(res => [res['meta'].total, this.parseResults(res['results']),RefineResultsUtils.parse(res['refineResults'],refineFields, "datasource")]); + } + //((oaftype exact datasource) and(collectedfromdatasourceid exact "openaire____::47ce9e9f4fad46e732cff06419ecaabb")) + advancedSearchDataproviders (params: string, page: number, size: number ):any { + let url = OpenaireProperties.getSearchResourcesAPIURL(); + var basicQuery = "(oaftype exact datasource) " + url += "?query="; + if(params!= null && params != '' ) { + url +=" ( "+basicQuery+ " ) " +" and (" + params + ")"; + }else{ + url +=" ( "+basicQuery+ " ) "; + } + + url += "&page="+(page-1)+"&size="+size+"&format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + .map(res => [res['meta'].total, this.parseResults(res['results'])]) + } + + searchCompatibleDataprovidersTable ():any { + let size: number = 0; + let url: string= OpenaireProperties.getSearchResourcesAPIURL(); + url += '?query=((oaftype exact datasource) not(datasourcecompatibilityid = UNKNOWN) not(datasourcecompatibilityid = notCompatible) not(datasourcetypeuiid = other) not(datasourcetypeuiid exact "pubsrepository::journal") not(datasourcetypeuiid exact "aggregator::pubsrepository::journals"))'; + url += "&page=0&size=0&format=json"; + + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url).map(res => res.json()) + + .map(res => res['meta'].total); + } + + searchCompatibleDataproviders (params: string,refineParams:string, page: number, size: number, refineFields:string[] ):any { + console.info("in search Compatible Dataproviders service function"); + let url: string = OpenaireProperties.getSearchResourcesAPIURL(); + url += '?query=((oaftype exact datasource) not(datasourcecompatibilityid = UNKNOWN) not(datasourcecompatibilityid = notCompatible) not(datasourcetypeuiid = other) not(datasourcetypeuiid exact "pubsrepository::journal") not(datasourcetypeuiid exact "aggregator::pubsrepository::journals"))'; + if(params!= null && params != '' ) { + url += params; + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+(page-1)+"&size="+size+"&format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + .map(res => [res['meta'].total, this.parseResults(res['results']),RefineResultsUtils.parse(res['refineResults'],refineFields, "datasource")]); + } + + searchEntityRegistriesTable ():any { + let size: number = 0; + let url: string= OpenaireProperties.getSearchResourcesAPIURL(); + url += "?query=((oaftype exact datasource) and(datasourcetypeuiid = other))"; + url += "&page=0&size=0&format=json"; + + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url).map(res => res.json()) + .map(res => res['meta'].total); + } + + searchEntityRegistries (params: string,refineParams:string, page: number, size: number, refineFields:string[] ):any { + let url = OpenaireProperties.getSearchResourcesAPIURL(); + url += "?query=((oaftype exact datasource) and(datasourcetypeuiid = other))"; + if(params!= null && params != '' ) { + url += params; + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+(page-1)+"&size="+size+"&format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + .map(res => [res['meta'].total, this.parseResults(res['results']),RefineResultsUtils.parse(res['refineResults'],refineFields, "datasource")]); + } + + searchJournalsTable ():any { + let size: number = 0; + let url: string= OpenaireProperties.getSearchResourcesAPIURL(); + url += '?query=((oaftype exact datasource) not(datasourcecompatibilityid = UNKNOWN) not(datasourcecompatibilityid = notCompatible) and (datasourcetypeuiid exact "pubsrepository::journal" or datasourcetypeuiid exact "aggregator::pubsrepository::journals" ))'; + url += "&page=0&size=0&format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url).map(res => res.json()) + .map(res => res['meta'].total); + } + + searchJournals (params: string,refineParams:string, page: number, size: number, refineFields:string[] ):any { + console.info("in search Journals service function"); + let url: string = OpenaireProperties.getSearchResourcesAPIURL(); + //url += "?query=((oaftype exact datasource) not(datasourcecompatibilityid = UNKNOWN) not(datasourcecompatibilityid = notCompatible) not(datasourcetypeuiid = other))" + url += '?query=((oaftype exact datasource) not(datasourcecompatibilityid = UNKNOWN) not(datasourcecompatibilityid = notCompatible) and (datasourcetypeuiid exact "pubsrepository::journal" or datasourcetypeuiid exact "aggregator::pubsrepository::journals" ))'; + + if(params!= null && params != '' ) { + url += params; + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+(page-1)+"&size="+size+"&format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + .map(res => [res['meta'].total, this.parseResults(res['results']),RefineResultsUtils.parse(res['refineResults'],refineFields, "datasource")]); + } + + searchDataprovidersForDeposit (id: string,type:string, page: number, size: number):any { + let link = OpenaireProperties.getSearchResourcesAPIURL(); + var compatibilities = ""; + if(type == "Research Data"){ + compatibilities = " and (datasourcecompatibilityid <> UNKNOWN) and (datasourcecompatibilityid = openaire2.0_data)" + }else if(type == "Publications"){ + compatibilities = " and (datasourcecompatibilityid <> UNKNOWN) and (datasourcecompatibilityid <> openaire2.0_data)" + } + let url = link+"?query=(((deletedbyinference = false) AND (oaftype exact datasource)) "+((compatibilities && compatibilities.length > 0)?" "+compatibilities+" ":"")+") and (relorganizationid exact "+id+")"; + url += "&page="+(page-1)+"&size="+size+"&format=json"; + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => [res['meta'].total, this.parseResults(res['results'])]); + } + searchDataProvidersBySubjects(keyword:string, type:string, page: number, size: number):any { + let link = OpenaireProperties.getSearchResourcesAPIURL(); + var compatibilities = ""; + if(type == "Research Data"){ + compatibilities = " and (datasourcecompatibilityid <> UNKNOWN) and (datasourcecompatibilityid = openaire2.0_data)" + }else if(type == "Publications"){ + compatibilities = " and (datasourcecompatibilityid <> UNKNOWN) and (datasourcecompatibilityid <> openaire2.0_data)" + } + let url = link+"?query=(((deletedbyinference = false) AND (oaftype exact datasource)) "+((compatibilities && compatibilities.length > 0)?" "+ + compatibilities+" ":"")+") "+ + " and (datasourcesubject all "+'"'+keyword+'"'+") " ; + url += "&page="+(page-1)+"&size="+size+"&format=json"; + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => [res['meta'].total, this.parseResults(res['results'])]); + + } + + getDataProvidersforEntityRegistry(datasourceId: string, page: number, size: number ):any { + let url = OpenaireProperties.getSearchResourcesAPIURL(); + var basicQuery = "(oaftype exact datasource) " + url += "?query="; + if(datasourceId!= null && datasourceId != '' ) { + url +=" ( "+basicQuery+ " ) " +" and (collectedfromdatasourceid exact \"" + datasourceId + "\")"; + }else{ + url +=" ( "+basicQuery+ " ) "; + } + + url += "&page="+(page-1)+"&size="+size+"&format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => [res['meta'].total, this.parseResults(res['results'])]); + } + searchDataprovidersForEntity (params: string, page: number, size: number):any { + let link = OpenaireProperties. getSearchAPIURLLast(); + let url = link+params+"/datasources?format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => [res['meta'].total, this.parseResults(res['results'])]); + } +/* + searchDataprovidersCSV (params: string, refineParams:string, page: number, size: number):any { + + let link = OpenaireProperties. getSearchAPIURLLast()+"datasources"; + + let url = link+"?"; + if(params!= null && params != '' ) { + url += params; + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+(page-1)+"&size="+size+"&format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + + .map(res => this.parseResultsCSV(res['results'])); + } +*/ +/* + searchEntityRegistriesCSV (params: string,refineParams:string, page: number, size: number):any { + let url = OpenaireProperties.getSearchResourcesAPIURL(); + url += "?query=((oaftype exact datasource) and(datasourcetypeuiid = other))" + if(params!= null && params != '' ) { + url += params; + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+(page - 1)+"&size="+size+"&format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + + .map(res => this.parseResultsCSV(res['results'])); + } +*/ +/* + searchCompatibleDataprovidersCSV (params: string,refineParams:string, page: number, size: number):any { + let url = OpenaireProperties.getSearchResourcesAPIURL(); + url += "?query=((oaftype exact datasource) not(datasourcecompatibilityid = UNKNOWN) not(datasourcecompatibilityid = notCompatible) not(datasourcetypeuiid = other))" + if(params!= null && params != '' ) { + url += params; + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+(page - 1)+"&size="+size+"&format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + + .map(res => this.parseResultsCSV(res['results'])); + } +*/ + + + parseResults(data: any): SearchResult[] { + let results: SearchResult[] = []; + + let length = Array.isArray(data) ? data.length : 1; + + for(let i=0; i = new Set(); + + let relLength = Array.isArray(resData['rels']['rel']) ? resData['rels']['rel'].length : 1; + + for(let i=0; i res.json()) + .map(res => res.total); + } + + numOfEntityDataproviders(id: string, entity: string):any { + var parameters = ""; + if(entity == "organization") { + parameters = "organizations/"+id+"/datasources/count"; + } + + let url = OpenaireProperties.getSearchAPIURLLast()+parameters+"?format=json"; + return this.numOfDataproviders(url); + } + + numOfSearchDataproviders(params: string):any { + let url: string = OpenaireProperties.getSearchAPIURLLast()+"datasources/count?format=json"; + if(params != "") { + url += "&q=" + params; + } + + return this.numOfDataproviders(url); + } +/* + private quote(word: any): string { + return '"'+word+'"'; + } +*/ +} diff --git a/portal-4cli/src/app/services/searchDatasets.service.ts b/portal-4cli/src/app/services/searchDatasets.service.ts new file mode 100644 index 00000000..beef7822 --- /dev/null +++ b/portal-4cli/src/app/services/searchDatasets.service.ts @@ -0,0 +1,314 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {OpenaireProperties} from '../utils/properties/openaireProperties'; +import {SearchResult} from '../utils/entities/searchResult'; +import {RefineResultsUtils} from './servicesUtils/refineResults.class'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; +import { } from '../shared/cache.service'; +@Injectable() +export class SearchDatasetsService { + private sizeOfDescription: number = 270; + + constructor(private http: Http ) {} + + searchDatasets (params: string, refineParams:string, page: number, size: number, refineFields:string[] ):any { + + let link = OpenaireProperties.getSearchAPIURLLast()+"datasets"; + + let url = link+"?"; + if(params!= null && params != '' ) { + url += params; + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+ (page-1) +"&size="+size+"&format=json"; + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + .map(res => [res['meta'].total, this.parseResults(res['results']),RefineResultsUtils.parse(res['refineResults'],refineFields, "dataset")]); + } + searchDatasetById (id: string ):any { + + let url = OpenaireProperties.getSearchAPIURLLast()+"datasets/"+id+"?format=json"; + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => this.parseResults(res)); + } + + searchAggregators (id: string, params: string, refineParams:string, page: number, size: number ):any { + + let link = OpenaireProperties.getSearchAPIURLLast()+"datasets"; + + let url = link+"?"+"&format=json"; + if(params!= null && params != '' ) { + url += params; + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+(page-1)+"&size="+size; + + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => this.parseRefineResults(id, res['refineResults'])) + } + + searchDatasetsByDois (DOIs: string[], refineParams:string, page: number, size: number, refineFields:string[] ):any { + let link = OpenaireProperties.getSearchAPIURLLast()+"datasets"; + let url = link+"?"; + var doisParams = ""; + + for(var i =0 ;i < DOIs.length; i++){ + doisParams+=(doisParams.length > 0?"&":"")+'doi="'+ DOIs[i]+'"'; + } + if(doisParams.length > 0){ + url += "&"+doisParams; + + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+ (page-1) +"&size="+size+"&format=json"; + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + + .map(res => [res['meta'].total, this.parseResults(res['results']),RefineResultsUtils.parse(res['refineResults'],refineFields, "dataset")]); + } + advancedSearchDatasets (params: string, page: number, size: number ):any { + let url = OpenaireProperties.getSearchResourcesAPIURL(); + var basicQuery = "(oaftype exact result) and (resulttypeid exact dataset) " + url += "?query="; + if(params!= null && params != '' ) { + url +=" ( "+basicQuery+ " ) " +" and (" + params + ")"; + }else{ + url +=" ( "+basicQuery+ " ) "; + } + + url += "&page="+(page-1)+"&size="+size; + url += "&format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + .map(res => [res['meta'].total, this.parseResults(res['results'])]); + } + searchDatasetsForEntity (params: string, page: number, size: number):any { + let link = OpenaireProperties.getSearchAPIURLLast(); + let url = link+params+"/datasets"+"?format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => [res['meta'].total, this.parseResults(res['results'])]); + } + + searchDatasetsForDataproviders(params: string, page: number, size: number):any { + let link = OpenaireProperties.getSearchAPIURLLast(); + let url = link+params+ "&page="+(page-1)+"&size="+size + "&format=json"; + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => [res['meta'].total, this.parseResults(res['results'])]); + } + + parseResults(data: any): SearchResult[] { + let results: SearchResult[] = []; + + let length = Array.isArray(data) ? data.length : 1; + + for(let i=0; i(); + } + + result['authors'].push({"name": relation.fullname, "id": relation['to'].content}); + } else */if(relation['to'].class == "isProducedBy") { + result['projects'] = this.parseProjects(result['projects'], relation); + } + } + } + } + + if(resData.hasOwnProperty("creator") && resData['creator'] != null) { + if(result['authors'] == undefined) { + result['authors'] = new Array(); + } + + let authors = resData['creator']; + let length = Array.isArray(authors) ? authors.length : 1; + + for(let i=0; i this.sizeOfDescription) { + result.description = result.description.substring(0, this.sizeOfDescription)+"..."; + } + + result.embargoEndDate = resData.embargoenddate; + + if(!Array.isArray(resData.publisher)) { + result.publisher = resData.publisher; + } else { + for(let i=0; i(); + } + + let countProjects = projects.length; + + projects[countProjects] = { + "id": "", "acronym": "", "title": "", + "funderShortname": "", "funderName": "", + "code": "" + } + + if(relation.title != 'unidentified') { + projects[countProjects]['id'] = + /*OpenaireProperties.getsearchLinkToProject() + */relation['to'].content; + projects[countProjects]['acronym'] = relation.acronym; + projects[countProjects]['title'] = relation.title; + projects[countProjects]['code'] = relation.code; + } else { + projects[countProjects]['id'] = ""; + projects[countProjects]['acronym'] = ""; + projects[countProjects]['title'] = ""; + projects[countProjects]['code'] = ""; + } + + if(relation.hasOwnProperty("funding")) { + let fundingLength = Array.isArray(relation['funding']) ? relation['funding'].length : 1; + + for(let z=0; z res.json()) + .map(res => res.total); + } + + numOfEntityDatasets(id: string, entity: string):any { + var parameters = ""; + + if(entity == "project") { + parameters = "projects/"+id+"/datasets/count"; + } + + let url = OpenaireProperties.getSearchAPIURLLast()+parameters+"?format=json"; + return this.numOfDatasets(url); + } + + numOfSearchDatasets(params: string):any { + let url = OpenaireProperties.getSearchAPIURLLast()+"datasets/count?format=json"; + if(params != "") { + url += "&q=" + params; + } + return this.numOfDatasets(url); + } +} diff --git a/portal-4cli/src/app/services/searchOrganizations.service.ts b/portal-4cli/src/app/services/searchOrganizations.service.ts new file mode 100644 index 00000000..5da21881 --- /dev/null +++ b/portal-4cli/src/app/services/searchOrganizations.service.ts @@ -0,0 +1,191 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; +import { } from '../shared/cache.service'; +import {OpenaireProperties} from '../utils/properties/openaireProperties'; +import {SearchResult} from '../utils/entities/searchResult'; +import {RefineResultsUtils} from './servicesUtils/refineResults.class'; + +@Injectable() +export class SearchOrganizationsService { + + constructor(private http: Http ) {} + + parseResultsForDeposit(data: any): {"name": string, "id": string}[] { + let results: {"name": string, "id": string}[] = []; + + let length = Array.isArray(data) ? data.length : 1; + + for(let i=0; i res.json()) + //.do(res => console.info(res)) + + .map(res => [res['meta'].total, this.parseResults(res['results']),RefineResultsUtils.parse(res['refineResults'],refineFields, "organization")]); + } + advancedSearchOrganizations (params: string, page: number, size: number ):any { + let url = OpenaireProperties.getSearchResourcesAPIURL(); + var basicQuery = "(oaftype exact organization) " + url += "?query="; + if(params!= null && params != '' ) { + url +=" ( "+basicQuery+ " ) " +" and (" + params + ")"; + }else{ + url +=" ( "+basicQuery+ " ) "; + } + + url += "&page="+(page-1)+"&size="+size; + url += "&format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + + .map(res => [res['meta'].total, this.parseResults(res['results'])]); + } + parseResults(data: any): SearchResult[] { + let results: SearchResult[] = []; + + let length = Array.isArray(data) ? data.length : 1; + + for(let i=0; i(); + } + + let countProjects = result['projects'].length; + + result['projects'][countProjects] = { + "id": "", "acronym": "", "title": "", + "funderShortname": "", "funderName": "", + "code": "" + } + + if(relation.title != 'unidentified') { + result['projects'][countProjects]['id'] = + /*OpenaireProperties.getsearchLinkToProject() + */relation['to'].content; + result['projects'][countProjects]['acronym'] = relation.acronym; + result['projects'][countProjects]['title'] = relation.title; + result['projects'][countProjects]['code'] = relation.code; + } else { + result['projects'][countProjects]['id'] = ""; + result['projects'][countProjects]['acronym'] = ""; + result['projects'][countProjects]['title'] = ""; + result['projects'][countProjects]['code'] = ""; + } + + if(relation.hasOwnProperty("funding")) { + let fundingLength = Array.isArray(relation['funding']) ? relation['funding'].length : 1; + + for(let z=0; z res.json()) + .map(res => res.total); + } + + numOfEntityOrganizations(id: string, entity: string):any { + // currently not used - if used fix entity comparison below + var parameters: string = ""; + if(entity == "organization") { + parameters = "organizations/"+id+"/organizations/count"; + } + + let url = OpenaireProperties.getSearchAPIURLLast()+parameters+"?format=json"; + return this.numOfOrganizations(url); + } + + numOfSearchOrganizations(params: string):any { + let url = OpenaireProperties.getSearchAPIURLLast()+"organizations/count?format=json"; + if(params != "") { + url += "&q=" + params; + } + return this.numOfOrganizations(url); + } +} diff --git a/portal-4cli/src/app/services/searchProjects.service.ts b/portal-4cli/src/app/services/searchProjects.service.ts new file mode 100644 index 00000000..4bfc5e6d --- /dev/null +++ b/portal-4cli/src/app/services/searchProjects.service.ts @@ -0,0 +1,242 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; +import { } from '../shared/cache.service'; +import {OpenaireProperties} from '../utils/properties/openaireProperties'; +import {SearchResult} from '../utils/entities/searchResult'; +import {RefineResultsUtils} from './servicesUtils/refineResults.class'; + +@Injectable() +export class SearchProjectsService { + private sizeOfDescription: number = 270; + + constructor(private http: Http ) {} + + searchProjects (params: string, refineParams:string, page: number, size: number, refineFields:string[] ):any { + + console.info("In searchProjects"); + + let link = OpenaireProperties.getSearchAPIURLLast()+"projects"; + + let url = link+"?"; + if(params!= null && params != '' ) { + url += params; + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+(page-1)+"&size="+size + "&format=json"; + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + .map(res => [res['meta'].total, this.parseResults(res['results']),RefineResultsUtils.parse(res['refineResults'],refineFields, "project")]); + } + getProjectsforDataProvider (datasourceId: string, page: number, size: number ):any { + let url = OpenaireProperties.getSearchResourcesAPIURL(); + var basicQuery = "(oaftype exact project) " + url += "?query="; + if(datasourceId!= null && datasourceId != '' ) { + url +=" ( "+basicQuery+ " ) " +" and (collectedfromdatasourceid exact \"" + datasourceId + "\")"; + }else{ + url +=" ( "+basicQuery+ " ) "; + } + + url += "&page="+(page-1)+"&size="+size; + url += "&format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => [res['meta'].total, this.parseResults(res['results'])]); + } + advancedSearchProjects (params: string, page: number, size: number ):any { + let url = OpenaireProperties.getSearchResourcesAPIURL(); + var basicQuery = "(oaftype exact project) " + url += "?query="; + if(params!= null && params != '' ) { + url +=" ( "+basicQuery+ " ) " +" and (" + params + ")"; + }else{ + url +=" ( "+basicQuery+ " ) "; + } + + url += "&page="+(page-1)+"&size="+size; + url += "&format=json"; + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + .map(res => [res['meta'].total, this.parseResults(res['results'])]); + } + getProjectsForOrganizations (organizationId: string, filterquery: string, page: number, size: number, refineFields:string[] ):any { + let url = OpenaireProperties.getSearchResourcesAPIURL(); + var basicQuery = "(oaftype exact project) " + url += "?query="; + if(filterquery!= null && filterquery != '' ) { + url +="( ( "+basicQuery+ " ) and (relorganizationid exact \"" + organizationId + "\")"+" " + filterquery + ")"; + }else{ + url +=" (( "+basicQuery+ " ) " +" and (relorganizationid exact \"" + organizationId + "\"))"; + } + if(refineFields!= null && refineFields.length > 0 ) { + url +="&refine=true"; + for(let i=0; i< refineFields.length ; i++ ){ + url +="&fields="+refineFields[i]; + } + } + url += "&page="+(page-1)+"&size="+size; + url += "&format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + .map(res => [res['meta'].total, this.parseResults(res['results']),RefineResultsUtils.parse(res['refineResults'],refineFields, "project")]); + } + getFunders():any { + let url = OpenaireProperties.getSearchAPIURLLast()+"projects?refine=true&fields=funder&size=0"+ "&format=json";; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => [res['meta'].total, res['refineResults']['funder']]); + + + } + + searchForProjectsObs(keyword:string, funderId:string):any { + let url = 'search?action=search&sTransformer=projects_openaire&query='+ + '%28oaftype+exact+project%29+and+%28%28projecttitle+%3D+%22'+keyword+'%22%29+or+%28projectacronym+%3D+%22'+keyword+'%22%29+or+%28projectcode+%3D+%22'+keyword+'%22%29%29+and+%28funder+exact+'+funderId+'%29&size=10&locale=en_GB&format=json'; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url).toPromise() + .then(request =>{ + return (request.json().response.results)?request.json().response.results.result:request.json().response.result; + + }) ; + } + parseResults(data: any): SearchResult[] { + let results: SearchResult[] = []; + + let length = Array.isArray(data) ? data.length : 1; + + for(let i=0; i(); + } + + let countOrganizations = result['organizations'].length; + + result['organizations'][countOrganizations] = { "name": "", "id": "" } + + result['organizations'][countOrganizations]['id'] = + /*OpenaireProperties.getsearchLinkToOrganization() + */relation['to'].content; + if(relation.legalshortname) { + result['organizations'][countOrganizations]['name'] = relation.legalshortname; + } else { + result['organizations'][countOrganizations]['name'] = relation.legalname; + } + } + } + } + } + if(resData.hasOwnProperty("fundingtree")) { + if(result['funders'] == undefined) { + result['funders'] = new Array< + {"funderShortname": string, "funderName": string}>(); + } + + let fundingLength = Array.isArray(resData['fundingtree']) ? resData['fundingtree'].length : 1; + + for(let z=0; z res.json()) + .map(res => res.total); + } + + numOfEntityProjects(id: string, entity: string):any { + //let url = OpenaireProperties.getSearchAPIURLLast()+params+(params.indexOf("?") == -1 ?"?":"&")+"format=json"; + var parameters: string = ""; + if(entity == "organization") { + parameters = "organizations/"+id+"/projects/count"; + } + + let url = OpenaireProperties.getSearchAPIURLLast()+parameters+ "?format=json"; + + return this.numOfProjects(url); + } + + numOfSearchProjects(params: string):any { + let url = OpenaireProperties.getSearchAPIURLLast()+"projects/count?format=json"; + if(params != "") { + url += "&q=" + params; + } + return this.numOfProjects(url); + } +} diff --git a/portal-4cli/src/app/services/searchPublications.service.ts b/portal-4cli/src/app/services/searchPublications.service.ts new file mode 100644 index 00000000..6962450f --- /dev/null +++ b/portal-4cli/src/app/services/searchPublications.service.ts @@ -0,0 +1,431 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; +import { } from '../shared/cache.service'; + +import {OpenaireProperties} from '../utils/properties/openaireProperties'; +import {SearchResult} from '../utils/entities/searchResult'; +import {RefineResultsUtils} from './servicesUtils/refineResults.class'; + +@Injectable() +export class SearchPublicationsService { + private sizeOfDescription: number = 270; + + constructor(private http: Http ) {} + + searchPublications (params: string, refineParams:string, page: number, size: number, refineFields:string[] ):any { + let link = OpenaireProperties.getSearchAPIURLLast()+"publications"; + + let url = link+"?"; + if(params!= null && params != '' ) { + url += params; + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+(page-1)+"&size="+size+"&format=json"; + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + // .do(res => console.info(res)) + .map(res => [res['meta'].total, this.parseResults(res['results']),RefineResultsUtils.parse(res['refineResults'],refineFields, "publication")]); + } + searchPublicationById (id: string ):any { + + let url = OpenaireProperties.getSearchAPIURLLast()+"publications/"+id+"?format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => this.parseResults(res)); + } + + searchAggregators (id: string, params: string, refineParams:string, page: number, size: number ):any { + + let link = OpenaireProperties.getSearchAPIURLLast()+"publications"; + + let url = link+"?"+"&format=json"; + if(params!= null && params != '' ) { + url += params; + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+(page-1)+"&size="+size; + + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => this.parseRefineResults(id, res['refineResults'])); + } + + searchPublicationsByDois (DOIs: string[], refineParams:string, page: number, size: number, refineFields:string[] ):any { + + let link = OpenaireProperties.getSearchAPIURLLast()+"publications"; + + let url = link+"?"+"&format=json&"; + var doisParams = ""; + + for(var i =0 ;i < DOIs.length; i++){ + doisParams+=(doisParams.length > 0?"&":"")+'doi="'+ DOIs[i]+'"'; + } + if(doisParams.length > 0){ + url +="&"+doisParams; + + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+(page-1)+"&size="+size; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + .map(res => [res['meta'].total, this.parseResults(res['results']),RefineResultsUtils.parse(res['refineResults'],refineFields, "publication")]); + } + + advancedSearchPublications (params: string, page: number, size: number ):any { + let url = OpenaireProperties.getSearchResourcesAPIURL(); + var basicQuery = "(oaftype exact result) and (resulttypeid exact publication) "; + url += "?query="; + if(params!= null && params != '' ) { + url +=" ( "+basicQuery+ " ) " +" and (" + params + ")"; + }else{ + url +=" ( "+basicQuery+ " ) "; + } + + url += "&page="+(page-1)+"&size="+size; + url += "&format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + + .map(res => [res['meta'].total, this.parseResults(res['results'])]); + } + searchPublicationsForEntity (params: string, page: number, size: number):any { + let link = OpenaireProperties.getSearchAPIURLLast(); + let url = link+params+"/publications"+ "?format=json"; + url += "&page="+(page-1)+"&size="+size; + + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => [res['meta'].total, this.parseResults(res['results'])]); + } + + searchPublicationsForDataproviders(params: string, page: number, size: number):any { + let link = OpenaireProperties.getSearchAPIURLLast(); + let url = link+params+ "&page="+(page-1)+"&size="+size + "&format=json"; + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => [res['meta'].total, this.parseResults(res['results'])]); + } +/* + searchPublicationsCSV (params: string, refineParams:string, page: number, size: number):any { + + let link = OpenaireProperties.getSearchAPIURLLast()+"publications"; + + let url = link+"?"; + if(params!= null && params != '' ) { + url += params; + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+(page-1)+"&size="+size+ "&format=json"; + + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + + .map(res => this.parseResultsCSV(res['results'])); + } +*/ + + parseResults(data: any): SearchResult[] { + let results: SearchResult[] = []; + + let length = Array.isArray(data) ? data.length : 1; + + for(let i=0; i(); + } + + result['authors'].push({"name": relation.fullname, "id": relation['to'].content}); + } else */if(relation['to'].class == "isProducedBy") { + result['projects'] = this.parseProjects(result['projects'], relation); + } + } + } + } + + if(resData.hasOwnProperty("creator") && resData['creator'] != null) { + if(result['authors'] == undefined) { + result['authors'] = new Array(); + } + + let authors = resData['creator']; + let length = Array.isArray(authors) ? authors.length : 1; + + for(let i=0; i this.sizeOfDescription) { + result.description = result.description.substring(0, this.sizeOfDescription) + "..."; + } + + + result.embargoEndDate = resData.embargoenddate; + + results.push(result); + } + + return results; + } + + parseProjects(projects: { "id": string, "acronym": string, "title": string, + "funderShortname": string, "funderName": string, + "code": string }[], relation: any ) : { + "id": string, "acronym": string, "title": string, + "funderShortname": string, "funderName": string, + "code": string }[] { + if(projects == undefined) { + projects = new Array< + { "id": string, "acronym": string, "title": string, + "funderShortname": string, "funderName": string, + "code": string + }>(); + } + + let countProjects = projects.length; + + projects[countProjects] = { + "id": "", "acronym": "", "title": "", + "funderShortname": "", "funderName": "", + "code": "" + } + + if(relation.title != 'unidentified') { + projects[countProjects]['id'] = + /*OpenaireProperties.getsearchLinkToProject() + */relation['to'].content; + projects[countProjects]['acronym'] = relation.acronym; + projects[countProjects]['title'] = relation.title; + projects[countProjects]['code'] = relation.code; + } else { + projects[countProjects]['id'] = ""; + projects[countProjects]['acronym'] = ""; + projects[countProjects]['title'] = ""; + projects[countProjects]['code'] = ""; + } + + if(relation.hasOwnProperty("funding")) { + let fundingLength = Array.isArray(relation['funding']) ? relation['funding'].length : 1; + + for(let z=0; z res.json()) + .map(res => res.total); + } + + numOfEntityPublications(id: string, entity: string):any { + var parameters: string = ""; + if(entity == "project") { + parameters = "projects/"+id+"/publications/count"; + } + let url = OpenaireProperties.getSearchAPIURLLast()+parameters+"?format=json"; + return this.numOfPublications(url); + } + + numOfSearchPublications(params: string):any { + let url = OpenaireProperties.getSearchAPIURLLast()+"publications/count?format=json"; + if(params != "") { + url += "&q=" + params; + } + return this.numOfPublications(url); + } +/* + private quote(word: any): string { + return '"'+word+'"'; + } +*/ +} diff --git a/portal-4cli/src/app/services/searchSoftware.service.ts b/portal-4cli/src/app/services/searchSoftware.service.ts new file mode 100644 index 00000000..c8e0a4e8 --- /dev/null +++ b/portal-4cli/src/app/services/searchSoftware.service.ts @@ -0,0 +1,315 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {OpenaireProperties} from '../utils/properties/openaireProperties'; +import {SearchResult} from '../utils/entities/searchResult'; +import {RefineResultsUtils} from './servicesUtils/refineResults.class'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; +import { } from '../shared/cache.service'; +@Injectable() +export class SearchSoftwareService { + private sizeOfDescription: number = 270; + + constructor(private http: Http ) {} + + searchSoftware (params: string, refineParams:string, page: number, size: number, refineFields:string[] ):any { + + let link = OpenaireProperties.getSearchAPIURLLast()+"software"; + + let url = link+"?"; + if(params!= null && params != '' ) { + url += params; + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+ (page-1) +"&size="+size+"&format=json"; + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + .map(res => [res['meta'].total, this.parseResults(res['results']),RefineResultsUtils.parse(res['refineResults'],refineFields, "software")]); + } + searchSoftwareById (id: string ):any { + + let url = OpenaireProperties.getSearchAPIURLLast()+"software/"+id+"?format=json"; + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => this.parseResults(res)); + } + + searchAggregators (id: string, params: string, refineParams:string, page: number, size: number ):any { + + let link = OpenaireProperties.getSearchAPIURLLast()+"software"; + + let url = link+"?"+"&format=json"; + if(params!= null && params != '' ) { + url += params; + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+(page-1)+"&size="+size; + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => this.parseRefineResults(id, res['refineResults'])) + } + + searchSoftwareByDois (DOIs: string[], refineParams:string, page: number, size: number, refineFields:string[] ):any { + let link = OpenaireProperties.getSearchAPIURLLast()+"software"; + let url = link+"?"; + var doisParams = ""; + + for(var i =0 ;i < DOIs.length; i++){ + doisParams+=(doisParams.length > 0?"&":"")+'doi="'+ DOIs[i]+'"'; + } + if(doisParams.length > 0){ + url += "&"+doisParams; + + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+ (page-1) +"&size="+size+"&format=json"; + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + .map(res => [res['meta'].total, this.parseResults(res['results']),RefineResultsUtils.parse(res['refineResults'],refineFields, "software")]); + } + advancedSearchSoftware (params: string, page: number, size: number ):any { + let url = OpenaireProperties.getSearchResourcesAPIURL(); + var basicQuery = "(oaftype exact result) and (resulttypeid exact software) " + url += "?query="; + if(params!= null && params != '' ) { + url +=" ( "+basicQuery+ " ) " +" and (" + params + ")"; + }else{ + url +=" ( "+basicQuery+ " ) "; + } + + url += "&page="+(page-1)+"&size="+size; + url += "&format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + .map(res => [res['meta'].total, this.parseResults(res['results'])]); + } + searchSoftwareForEntity (params: string, page: number, size: number):any { + let link = OpenaireProperties.getSearchAPIURLLast(); + let url = link+params+"/software"+"?format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => [res['meta'].total, this.parseResults(res['results'])]); + } + + searchSoftwareForDataproviders(params: string, page: number, size: number):any { + let link = OpenaireProperties.getSearchAPIURLLast(); + let url = link+params+ "&page="+(page-1)+"&size="+size + "&format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => [res['meta'].total, this.parseResults(res['results'])]); + } + + parseResults(data: any): SearchResult[] { + let results: SearchResult[] = []; + + let length = Array.isArray(data) ? data.length : 1; + + for(let i=0; i(); + } + + result['authors'].push({"name": relation.fullname, "id": relation['to'].content}); + } else */if(relation['to'].class == "isProducedBy") { + result['projects'] = this.parseProjects(result['projects'], relation); + } + } + } + } + + if(resData.hasOwnProperty("creator") && resData['creator'] != null) { + if(result['authors'] == undefined) { + result['authors'] = new Array(); + } + + let authors = resData['creator']; + let length = Array.isArray(authors) ? authors.length : 1; + + for(let i=0; i this.sizeOfDescription) { + result.description = result.description.substring(0, this.sizeOfDescription)+"..."; + } + + result.embargoEndDate = resData.embargoenddate; + + if(!Array.isArray(resData.publisher)) { + result.publisher = resData.publisher; + } else { + for(let i=0; i(); + } + + let countProjects = projects.length; + + projects[countProjects] = { + "id": "", "acronym": "", "title": "", + "funderShortname": "", "funderName": "", + "code": "" + } + + if(relation.title != 'unidentified') { + projects[countProjects]['id'] = + /*OpenaireProperties.getsearchLinkToProject() + */relation['to'].content; + projects[countProjects]['acronym'] = relation.acronym; + projects[countProjects]['title'] = relation.title; + projects[countProjects]['code'] = relation.code; + } else { + projects[countProjects]['id'] = ""; + projects[countProjects]['acronym'] = ""; + projects[countProjects]['title'] = ""; + projects[countProjects]['code'] = ""; + } + + if(relation.hasOwnProperty("funding")) { + let fundingLength = Array.isArray(relation['funding']) ? relation['funding'].length : 1; + + for(let z=0; z res.json()) + .map(res => res.total); + } + + numOfEntitySoftware(id: string, entity: string):any { + var parameters = ""; + + if(entity == "project") { + parameters = "projects/"+id+"/software/count"; + } + + let url = OpenaireProperties.getSearchAPIURLLast()+parameters+"?format=json"; + return this.numOfSoftware(url); + } + + numOfSearchSoftware(params: string):any { + let url = OpenaireProperties.getSearchAPIURLLast()+"software/count?format=json"; + if(params != "") { + url += "&q=" + params; + } + return this.numOfSoftware(url); + } +} diff --git a/portal-4cli/src/app/services/servicesUtils/refineResults.class.ts b/portal-4cli/src/app/services/servicesUtils/refineResults.class.ts new file mode 100644 index 00000000..b01b3a4f --- /dev/null +++ b/portal-4cli/src/app/services/servicesUtils/refineResults.class.ts @@ -0,0 +1,62 @@ + +import { Filter, Value} from '../../searchPages/searchUtils/searchHelperClasses.class'; +import { SearchFields} from '../../utils/properties/searchFields'; + + +export class RefineResultsUtils { + + + public static parse (data, fields:string[], entityType:string):Filter[] { + // var data = this.json.refineReuslts; + + var searchFields:SearchFields = new SearchFields(); + var filters:Filter[] = []; + if(data){ + for(let j=0; j +

    +
    +
    +
    +
    + + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + European Commission +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + OpenAIRE +
    + +
    + +
    +
    +
    +
    +
    +
    diff --git a/portal-4cli/src/app/sharedComponents/bottom.component.ts b/portal-4cli/src/app/sharedComponents/bottom.component.ts new file mode 100644 index 00000000..3ae13c03 --- /dev/null +++ b/portal-4cli/src/app/sharedComponents/bottom.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; +import 'rxjs/Rx'; + +@Component({ + selector: 'bottom', + templateUrl: 'bottom.component.html' +}) +export class BottomComponent { + +} diff --git a/portal-4cli/src/app/sharedComponents/cookie-law/cookie-law.component.ts b/portal-4cli/src/app/sharedComponents/cookie-law/cookie-law.component.ts new file mode 100644 index 00000000..3a72e7d0 --- /dev/null +++ b/portal-4cli/src/app/sharedComponents/cookie-law/cookie-law.component.ts @@ -0,0 +1,148 @@ +/** + * angular2-cookie-law + * + * Copyright 2016-2017, @andreasonny83, All rights reserved. + * + * @author: @andreasonny83 + */ + +import { + Component, + OnInit, + ViewEncapsulation, + HostBinding, + Input, + Output, + EventEmitter, + animate, + state, + trigger, + style, + transition, + AnimationTransitionEvent, +} from '@angular/core'; + +import { + DomSanitizer, + SafeHtml, +} from '@angular/platform-browser'; + +import { + CookieLawService, +} from './cookie-law.service'; + +// import { +// closeIcon, +// } from './icons'; + +export type CookieLawPosition = 'top' | 'bottom'; +export type CookieLawAnimation = 'topIn' | 'bottomIn' | 'topOut' | 'bottomOut'; +export type CookieLawTarget = '_blank' | '_self'; + +@Component({ + selector: 'cookie-law', + // encapsulation: ViewEncapsulation.None, + animations: [ + trigger('state', [ + state('bottomOut', style({ transform: 'translateY(100%)' })), + state('topOut', style({ transform: 'translateY(-100%)' })), + state('*', style({ transform: 'translateY(0)' })), + + transition('void => topIn', [ + style({ transform: 'translateY(-100%)' }), + animate('1000ms ease-in-out'), + ]), + + transition('void => bottomIn', [ + style({ transform: 'translateY(100%)' }), + animate('1000ms ease-in-out'), + ]), + + transition('* => *', animate('1000ms ease-out')), + ]) + ], + styleUrls: [ './cookie-law.css' ], + templateUrl: './cookie-law.html', +}) +export class CookieLawComponent implements OnInit { + public cookieLawSeen: boolean; + + @Input('learnMore') + get learnMore() { return this._learnMore; } + set learnMore(value: string) { + this._learnMore = (value !== null && `${value}` !== 'false') ? value : null; + } + + @Input('target') + get target() { return this._target; } + set target(value: CookieLawTarget) { + this._target = (value !== null && `${value}` !== 'false' && + (`${value}` === '_blank' || `${value}` === '_self') + ) ? value : '_blank'; + } + + @Input('position') + get position() { return this._position; } + set position(value: CookieLawPosition) { + this._position = (value !== null && `${value}` !== 'false' && + (`${value}` === 'top' || `${value}` === 'bottom') + ) ? value : 'bottom'; + } + + @Output('isSeen') + private isSeenEvt: EventEmitter; + + @HostBinding('attr.seen') + public isSeen: boolean; + + private animation: CookieLawAnimation; + private closeSvg: SafeHtml; + private currentStyles: {}; + private _learnMore: string; + private _target: CookieLawTarget; + private _position: CookieLawPosition; + + constructor( + private _service: CookieLawService, + private domSanitizer: DomSanitizer, + ) { + this.isSeenEvt = new EventEmitter(); + this.animation = 'topIn'; + this._position = 'bottom'; + this.cookieLawSeen = this._service.seen(); + } + + ngOnInit(): void { + if (typeof document !== 'undefined') { + this.animation = this.position === 'bottom' ? 'bottomIn' : 'topIn'; + + this.closeSvg = ' ' ; + + if (this.cookieLawSeen) { + this.isSeen = true; + } + + this.currentStyles = { + 'top': this.position === 'top' ? '0' : null, + 'bottom': this.position === 'top' ? 'initial' : null, + }; + } + } + + afterDismissAnimation(evt: AnimationTransitionEvent) { + if (evt.toState === 'topOut' || + evt.toState === 'bottomOut') { + this.isSeen = true; + this.isSeenEvt.emit(this.isSeen); + } + } + + public dismiss(evt?: MouseEvent): void { + if (evt) { + evt.preventDefault(); + } + + this._service.storeCookie(); + this.animation = this.position === 'top' ? 'topOut' : 'bottomOut'; + } +} diff --git a/portal-4cli/src/app/sharedComponents/cookie-law/cookie-law.css b/portal-4cli/src/app/sharedComponents/cookie-law/cookie-law.css new file mode 100644 index 00000000..17e09689 --- /dev/null +++ b/portal-4cli/src/app/sharedComponents/cookie-law/cookie-law.css @@ -0,0 +1,77 @@ +.cookie-law-wrapper a { + color: #bbb; + -webkit-transition: color .2s; + transition: color .2s; +} +.cookie-law-wrapper a:hover { + color: #fff; +} +.cookie-law-wrapper a:hover svg { + fill: #fff; +} +.cookie-law-wrapper { + background: #333; + color: #bbb; + display: block; + /*font-family: Helvetica Neue,Helvetica,Arial,sans-serif; + font-size: 15px; + font-weight: 200; + line-height: 20px;*/ + position: fixed; + bottom: 0; + left: 0; + width: 100%; + z-index: 999999999; + font-smooth: always; + -webkit-font-smoothing: antialiased; + text-align: center; +} +.dismiss { + display: block; + box-sizing: border-box; + padding: 10px; + position: absolute; + top: 0; + right: 10px; + text-decoration: none; + line-height: 20px; +} +.dismiss svg { + display: block; + fill: #bbb; + width: 20px; + height: 20px; + -webkit-transition: fill .2s; + transition: fill .2s; +} +.copy { + box-sizing: border-box; + padding: 10px 60px 10px 10px; +} +.copy span { + color: #fff; + /*font-weight: 400;*/ +} +.copy a { + text-decoration: underline; +} +.copy a:active, .copy a:hover { + outline: 0; +} + +@media (min-width: 600px) { + /* For bigger devices: */ + .copy { + padding: 20px 60px 20px 20px; + /*font-size: 18px; + line-height: 24px;*/ + } + .dismiss { + top: 10px; + right: 15px; + } + .dismiss svg { + width: 24px; + height: 24px; + } +} diff --git a/portal-4cli/src/app/sharedComponents/cookie-law/cookie-law.html b/portal-4cli/src/app/sharedComponents/cookie-law/cookie-law.html new file mode 100644 index 00000000..ccccbba4 --- /dev/null +++ b/portal-4cli/src/app/sharedComponents/cookie-law/cookie-law.html @@ -0,0 +1,23 @@ + + + + + + + ` + }) + + export class ErrorMessagesComponent { + @Input() status: Array; + @Input() type: string; + + public errorCodes:ErrorCodes; + + constructor () {} + + ngOnInit() { + this.errorCodes = new ErrorCodes(); + console.info("ngOnInit"); + if(!this.status) { + this.status = [this.errorCodes.LOADING]; + } + } + + ngOnDestroy() {} + + public checkErroCode(code: number) { + return function(status: number) { + return (status == code); + } + } + } diff --git a/portal-4cli/src/app/utils/errorMessages.module.ts b/portal-4cli/src/app/utils/errorMessages.module.ts new file mode 100644 index 00000000..9f7315af --- /dev/null +++ b/portal-4cli/src/app/utils/errorMessages.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {ErrorMessagesComponent} from './errorMessages.component'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule + ], + declarations: [ + ErrorMessagesComponent + ], + exports: [ + ErrorMessagesComponent + ] +}) +export class ErrorMessagesModule { } diff --git a/portal-4cli/src/app/utils/exportCSV.class.ts b/portal-4cli/src/app/utils/exportCSV.class.ts new file mode 100644 index 00000000..c5e39a33 --- /dev/null +++ b/portal-4cli/src/app/utils/exportCSV.class.ts @@ -0,0 +1,131 @@ + + + +export class ExportCSVComponent { + stockData : any = + { + "columnNames": + ["Symbol", "Company", "Price"], + "export": +/* + [ + { + Symbol: "AAPL", + Company: "Apple Inc.", + Price: "132.54" + }, + { + Symbol: "INTC", + Company: "Intel Corporation", + Price: "33.45" + }, + { + Symbol: "GOOG", + Company: "Google Inc", + Price: "554.52" + }, + ], +*/ + + [ + [ + "AAPL", + "Apple Inc.", + "132.54" + ], + [ + "INTC", + "Intel Corporation", + "33.45" + ], + [ + "GOOG", + "Google Inc", + "554.52" + ], + ], + + + "columnDelimiter": ',', + "lineDelimiter": '\n' + }; + + data: any = this.stockData; + filename: string; + linkname: string = "Download CSV"; + + constructor () { + } + + ngOnInit() { + } + + public static convertArrayOfObjectsToCSV(args) { + console.info("convertArrayOfObjectsToCSV"); + + var result, ctr, keys, columnDelimiter, lineDelimiter, data; + + data = args.export || null; + + if (data == null || !data.length) { + return null; + } + + columnDelimiter = args.columnDelimiter || ','; + lineDelimiter = args.lineDelimiter || '\n'; + + //keys = Object.keys(data[0]); + keys = args.columnNames; + + result = ''; + result += keys.join(columnDelimiter); + result += lineDelimiter; +/* + data.forEach(function(item) { + ctr = 0; + keys.forEach(function(key) { + if (ctr > 0) result += columnDelimiter; + result += item[key]; + ctr++; + }); + result += lineDelimiter; + }); +*/ + + for(let line of data) { + ctr = 0; + for(let column of line) { + if (ctr > 0) result += columnDelimiter; + result += column; + ctr++; + } + result += lineDelimiter; + } + + return result; + } + + public static downloadCSV(data: any, filenameArg: string) { + console.info("downloadCSV"); + + var encodedData, filename, link; + + var csv = this.convertArrayOfObjectsToCSV(data); + if (csv == null) return; + + filename = filenameArg || 'export.csv'; + + if (!csv.match(/^data:text\/csv/i)) { + csv = 'data:text/csv;charset=utf-8,' + csv; + } + encodedData = encodeURI(csv); + + //link = document.createElement('a'); + link = document.getElementsByTagName('a'); + link[0].setAttribute('href', encodedData); + link[0].setAttribute('download', filename); + //document.body.appendChild(link); + link[0].click(); + //document.body.removeChild(link); + } +} diff --git a/portal-4cli/src/app/utils/fetchEntitiesClasses/fetchDataproviders.class.ts b/portal-4cli/src/app/utils/fetchEntitiesClasses/fetchDataproviders.class.ts new file mode 100644 index 00000000..1ef9125c --- /dev/null +++ b/portal-4cli/src/app/utils/fetchEntitiesClasses/fetchDataproviders.class.ts @@ -0,0 +1,291 @@ +import {SearchDataprovidersService} from '../../services/searchDataproviders.service'; +import { ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchUtilsClass } from '../../searchPages/searchUtils/searchUtils.class'; + +export class FetchDataproviders { + private errorCodes: ErrorCodes; + + public results =[]; + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public sub: any; public subResults: any; + public CSV: any = { "columnNames": [ "Title", "Type", "Coutries", "Compatibility" ], + "export":[] + }; + public CSVDownloaded = false; + public csvParams: string; + + + constructor ( private _searchDataprovidersService: SearchDataprovidersService ) { + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + } + + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } + } + + public getResultsByKeyword(keyword:string, page: number, size: number){ + var parameters = ""; + if(keyword.length > 0){ + parameters = "q=" + keyword; + } + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + + this.subResults = this._searchDataprovidersService.searchDataproviders(parameters,null, page, size,[]).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Content Providers: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //ar errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } + + public getNumForEntity(entity: string, id:string) { + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + if(id != "" && entity != "") { + + this._searchDataprovidersService.numOfEntityDataproviders(id, entity).subscribe( + data => { + this.searchUtils.totalResults = data; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } + } + + public getNumForSearch(keyword: string) { + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + this._searchDataprovidersService.numOfSearchDataproviders(keyword).subscribe( + data => { + this.searchUtils.totalResults = data; + this.searchUtils.status = this.errorCodes.DONE; + + if(this.searchUtils.totalResults == 0) { + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } + +public getResultsForDeposit(id:string, type:string, page: number, size: number){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + if(id != "") { + + this._searchDataprovidersService.searchDataprovidersForDeposit(id,type, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Dataproviders forDeposit: [id:"+id+", type:"+type+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } +} +public getResultsBySubjectsForDeposit(subject:string, type:string, page: number, size: number){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this._searchDataprovidersService.searchDataProvidersBySubjects(subject,type, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Dataproviders forDeposit: [subject:"+subject+", type:"+type+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + +} + public getResultsForEntity(entity:string, id:string, page: number, size: number){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + var parameters = ""; + + if(entity == "organization") { + parameters = "organizations/"+id; + } + + if(parameters != "") { + + this._searchDataprovidersService.searchDataprovidersForEntity(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Dataproviders for "+entity+": [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } + } + + public getResultsForDataproviders(id:string, page: number, size: number){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + this._searchDataprovidersService.getDataProvidersforEntityRegistry(id, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Dataproviders for Entity Registry: [Id:"+id+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } +} diff --git a/portal-4cli/src/app/utils/fetchEntitiesClasses/fetchDatasets.class.ts b/portal-4cli/src/app/utils/fetchEntitiesClasses/fetchDatasets.class.ts new file mode 100644 index 00000000..9e6916b6 --- /dev/null +++ b/portal-4cli/src/app/utils/fetchEntitiesClasses/fetchDatasets.class.ts @@ -0,0 +1,253 @@ +import {SearchDatasetsService} from '../../services/searchDatasets.service'; +import { ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchUtilsClass } from '../../searchPages/searchUtils/searchUtils.class'; +import {DOI} from '../../utils/string-utils.class'; +import {Subject} from 'rxjs/Subject'; + +export class FetchDatasets{ + private errorCodes: ErrorCodes; + + public results =[]; + public requestComplete: Subject; + + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + private sub: any; + private subResults: any; + + public csvParams: string; + + constructor ( private _searchDatasetsService: SearchDatasetsService ) { + + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + this.requestComplete = new Subject(); + } + + + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } + } + + + public getResultsByKeyword(keyword:string, page: number, size: number){ + var parameters = ""; + if(keyword.length > 0){ + var DOIs:string[] = DOI.getDOIsFromString(keyword); + var doisParams = ""; + + for(var i =0 ;i < DOIs.length; i++){ + doisParams+=(doisParams.length > 0?"&":"")+'doi="'+ DOIs[i]+'"'; + } + if(doisParams.length > 0){ + parameters += "&"+doisParams; + }else{ + parameters = "q=" + keyword; + } + } + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + this.subResults = this._searchDatasetsService.searchDatasets(parameters,null, page, size, []).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Research Data: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } + +public getNumForEntity(entity:string, id:string){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + + if(id != "" && entity != "") { + this._searchDatasetsService.numOfEntityDatasets(id, entity).subscribe( + data => { + this.searchUtils.totalResults = data; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } +} + +public getResultsForEntity(entity:string, id:string, page: number, size: number){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + var parameters = ""; + + if(entity == "project") { + parameters = "projects/"+id; + } + + if(parameters != "") { + + this._searchDatasetsService.searchDatasetsForEntity(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Research Data for "+entity+": [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } +} + +public getResultsForDataproviders(id:string, resultsFrom:string, page: number, size: number){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + var parameters; + if(resultsFrom == "collectedFrom") { + parameters = "datasets?fq=collectedfromdatasourceid exact "+'"'+id+'"'; + } else if(resultsFrom == "hostedBy") { + parameters = "datasets?fq=resulthostingdatasourceid exact "+'"'+id+'"'; + } + + if(parameters != "") { + + this._searchDatasetsService.searchDatasetsForDataproviders(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Research Data for Dataproviders: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } +} + +public getAggregatorResults(id:string, page: number, size: number){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + this.subResults = this._searchDatasetsService.searchAggregators(id, '&fq=collectedfromdatasourceid exact "'+id+'"',"&refine=true&fields=resulthostingdatasource" , page, size).subscribe( + data => { + this.results = data; + this.searchUtils.totalResults = this.results.length; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + + this.requestComplete.complete(); + }, + err => { + console.log(err); + console.info("status: "+err.status); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + this.requestComplete.complete(); + } + ); +} + +} diff --git a/portal-4cli/src/app/utils/fetchEntitiesClasses/fetchOrganizations.class.ts b/portal-4cli/src/app/utils/fetchEntitiesClasses/fetchOrganizations.class.ts new file mode 100644 index 00000000..07cb4c61 --- /dev/null +++ b/portal-4cli/src/app/utils/fetchEntitiesClasses/fetchOrganizations.class.ts @@ -0,0 +1,76 @@ + import {SearchOrganizationsService} from '../../services/searchOrganizations.service'; + import { ErrorCodes} from '../../utils/properties/openaireProperties'; + import {SearchUtilsClass } from '../../searchPages/searchUtils/searchUtils.class'; + +export class FetchOrganizations { + private errorCodes: ErrorCodes; + + public results =[]; + + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public sub: any; + public subResults: any; + + + + constructor ( private _searchOrganizationsService: SearchOrganizationsService ) { + + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + } + + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } + } + + + public getResultsByKeyword(keyword:string , page: number, size: number){ + var parameters = ""; + if(keyword.length > 0){ + parameters = "q=" + keyword; + } + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + this.subResults = this._searchOrganizationsService.searchOrganizations(parameters, null, page, size, []).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Organizations: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } + + +} diff --git a/portal-4cli/src/app/utils/fetchEntitiesClasses/fetchProjects.class.ts b/portal-4cli/src/app/utils/fetchEntitiesClasses/fetchProjects.class.ts new file mode 100644 index 00000000..d31a3232 --- /dev/null +++ b/portal-4cli/src/app/utils/fetchEntitiesClasses/fetchProjects.class.ts @@ -0,0 +1,209 @@ +import {SearchProjectsService} from '../../services/searchProjects.service'; +import {ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchUtilsClass } from '../../searchPages/searchUtils/searchUtils.class'; + +export class FetchProjects{ + private errorCodes: ErrorCodes; + + public results =[]; + + public filters; // for getResultsForOrganizations + public funders:any = []; // for getResultsForOrganizations // this is filled with the initial query - before filtering + + public sub: any; + public subResults: any; + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + + + constructor (private _searchProjectsService: SearchProjectsService) { + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + } + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } + } + + public getResultsByKeyword(keyword:string, page: number, size: number){ + var parameters = ""; + if(keyword.length > 0){ + parameters = "q=" + keyword; + } + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + this.subResults = this._searchProjectsService.searchProjects(parameters, null, page, size, []).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Projects: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } + + public getResultsForDataproviders(id:string, page: number, size: number){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + this._searchProjectsService.getProjectsforDataProvider(id, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Projects for Dataproviders: [Id:"+id+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } + + public getNumForEntity(entity: string, id:string) { + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + if(id != "" && entity != "") { + + this._searchProjectsService.numOfEntityProjects(id, entity).subscribe( + data => { + this.searchUtils.totalResults = data; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } + } + + public getResultsForOrganizations(organizationId:string, filterquery:string, page: number, size: number, refineFields:string[]){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + this._searchProjectsService.getProjectsForOrganizations(organizationId,filterquery, page, size,refineFields).subscribe( + data => { + this.searchUtils.totalResults = data[0]; // the results can be filtered so this number can be no total results + console.info("search Projects for Organization: [Id:"+organizationId+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + if(refineFields && refineFields.length > 0){ + this.filters = data[2]; + filterquery = decodeURIComponent(filterquery); + for(var i = 0; i < this.filters.length; i++){ + if(filterquery.indexOf(this.filters[i].filterId) !== -1){ + console.log("this.filters[i].filterId:"+this.filters[i].filterId); + for(var j = 0; j < this.filters[i].values.length; j++){ + console.log("this.filters[i].values[j].id:"+this.filters[i].values[j].id); + if(filterquery.indexOf(this.filters[i].values[j].id) !== -1){ + this.filters[i].values[j].selected = true; + } + } + } + } + } + + if(filterquery == ""){ + this.searchUtils.totalResultsNoFilters = this.searchUtils.totalResults; + this.funders = []; + for(var i = 0; i < this.filters.length; i++){ + console.log("this.filters[i].filterId:"+this.filters[i].filterId); + if(this.filters[i].filterId == "funder"){ + this.funders = (this.filters[i].values); + + } + } + console.log(" this.funders:"+ this.funders); + + } + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } + + +} diff --git a/portal-4cli/src/app/utils/fetchEntitiesClasses/fetchPublications.class.ts b/portal-4cli/src/app/utils/fetchEntitiesClasses/fetchPublications.class.ts new file mode 100644 index 00000000..9e6959f1 --- /dev/null +++ b/portal-4cli/src/app/utils/fetchEntitiesClasses/fetchPublications.class.ts @@ -0,0 +1,233 @@ + +import {SearchPublicationsService} from '../../services/searchPublications.service'; +import {ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchFields} from '../../utils/properties/searchFields'; + import {SearchUtilsClass } from '../../searchPages/searchUtils/searchUtils.class'; +import {DOI} from '../../utils/string-utils.class'; +import {Subject} from 'rxjs/Subject'; + +export class FetchPublications { + private errorCodes: ErrorCodes; + + public results =[]; + + public requestComplete: Subject; + + // public filters =[]; + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + // public baseUrl:string = ""; + public sub: any; + public subResults: any; + public searchFields:SearchFields = new SearchFields(); + // public refineFields: string[] = this.searchFields.RESULT_REFINE_FIELDS; + // public fieldIdsMap=this.searchFields.RESULT_FIELDS; + //: { [key:string] :{ name:string, operator:string, type:string, indexField:string, equalityOperator:string }} = this.searchFields.PUBLICATION_FIELDS_MAP; + + public CSV: any = { "columnNames": ["Title", "Authors", "Publication Year", "DOI", + /*"Download From", "Publication type", "Journal",*/ + "Funder", "Project Name (GA Number)", "Access"], + "export":[] + }; + public CSVDownloaded = false; + public csvParams: string; + + constructor ( private _searchPublicationsService: SearchPublicationsService ) { + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + // this.baseUrl = OpenaireProperties.getLinkToSearchPublications(); + + this.requestComplete = new Subject(); + } + + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } + } + + public getResultsByKeyword(keyword:string, page: number, size: number){ + var parameters = ""; + if(keyword.length > 0){ + var DOIs:string[] = DOI.getDOIsFromString(keyword); + var doisParams = ""; + + for(var i =0 ;i < DOIs.length; i++){ + doisParams+=(doisParams.length > 0?"&":"")+'doi="'+ DOIs[i]+'"'; + } + if(doisParams.length > 0){ + parameters += "&"+doisParams; + }else{ + parameters = "q=" + keyword; + } + } + + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + this.subResults = this._searchPublicationsService.searchPublications(parameters,null, page, size, []).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Publications: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } + +public getResultsForEntity(entity:string, id:string, page: number, size: number){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + var parameters = ""; + if(entity == "project") { + parameters = "projects/"+id; + } else if(entity == "organization") { + parameters = "organizations/"+id; + } + + if(parameters != "") { + this._searchPublicationsService.searchPublicationsForEntity(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + + console.info("search Publications for "+entity+": [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } +} + +public getResultsForDataproviders(id:string, resultsFrom:string, page: number, size: number){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + var parameters; + if(resultsFrom == "collectedFrom") { + parameters = "publications?fq=collectedfromdatasourceid exact "+'"'+id+'"'; + } else if(resultsFrom == "hostedBy") { + parameters = "publications?fq=resulthostingdatasourceid exact "+'"'+id+'"'; + } + + if(parameters != "") { + + this._searchPublicationsService.searchPublicationsForDataproviders(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Publications for Dataproviders: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } +} + +public getAggregatorResults(id:string, page: number, size: number){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + this.subResults = this._searchPublicationsService.searchAggregators(id, '&fq=collectedfromdatasourceid exact "'+id+'"',"&refine=true&fields=resulthostingdatasource" , page, size).subscribe( + data => { + this.results = data; + this.searchUtils.totalResults = this.results.length; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + + this.requestComplete.complete(); + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + this.requestComplete.complete(); + } + ); +} + + +} diff --git a/portal-4cli/src/app/utils/fetchEntitiesClasses/fetchSoftware.class.ts b/portal-4cli/src/app/utils/fetchEntitiesClasses/fetchSoftware.class.ts new file mode 100644 index 00000000..9dbc37d6 --- /dev/null +++ b/portal-4cli/src/app/utils/fetchEntitiesClasses/fetchSoftware.class.ts @@ -0,0 +1,253 @@ +import {SearchSoftwareService} from '../../services/searchSoftware.service'; +import { ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchUtilsClass } from '../../searchPages/searchUtils/searchUtils.class'; +import {DOI} from '../../utils/string-utils.class'; +import {Subject} from 'rxjs/Subject'; + +export class FetchSoftware{ + private errorCodes: ErrorCodes; + + public results =[]; + public requestComplete: Subject; + + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + private sub: any; + private subResults: any; + + public csvParams: string; + + constructor ( private _searchSoftwareService: SearchSoftwareService ) { + + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + this.requestComplete = new Subject(); + } + + + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } + } + + + public getResultsByKeyword(keyword:string, page: number, size: number){ + var parameters = ""; + if(keyword.length > 0){ + var DOIs:string[] = DOI.getDOIsFromString(keyword); + var doisParams = ""; + + for(var i =0 ;i < DOIs.length; i++){ + doisParams+=(doisParams.length > 0?"&":"")+'doi="'+ DOIs[i]+'"'; + } + if(doisParams.length > 0){ + parameters += "&"+doisParams; + }else{ + parameters = "q=" + keyword; + } + } + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + this.subResults = this._searchSoftwareService.searchSoftware(parameters,null, page, size, []).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Software: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } + +public getNumForEntity(entity:string, id:string){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + + if(id != "" && entity != "") { + this._searchSoftwareService.numOfEntitySoftware(id, entity).subscribe( + data => { + this.searchUtils.totalResults = data; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } +} + +public getResultsForEntity(entity:string, id:string, page: number, size: number){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + var parameters = ""; + + if(entity == "project") { + parameters = "projects/"+id; + } + + if(parameters != "") { + + this._searchSoftwareService.searchSoftwareForEntity(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Software for "+entity+": [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } +} + +public getResultsForDataproviders(id:string, resultsFrom:string, page: number, size: number){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + var parameters; + if(resultsFrom == "collectedFrom") { + parameters = "software?fq=collectedfromdatasourceid exact "+'"'+id+'"'; + } else if(resultsFrom == "hostedBy") { + parameters = "software?fq=resulthostingdatasourceid exact "+'"'+id+'"'; + } + + if(parameters != "") { + + this._searchSoftwareService.searchSoftwareForDataproviders(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Software for Dataproviders: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } +} + +public getAggregatorResults(id:string, page: number, size: number){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + this.subResults = this._searchSoftwareService.searchAggregators(id, '&fq=collectedfromdatasourceid exact "'+id+'"',"&refine=true&fields=resulthostingdatasource" , page, size).subscribe( + data => { + this.results = data; + this.searchUtils.totalResults = this.results.length; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + + this.requestComplete.complete(); + }, + err => { + console.log(err); + console.info("status: "+err.status); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + this.requestComplete.complete(); + } + ); +} + +} diff --git a/portal-4cli/src/app/utils/helper/helper.component.ts b/portal-4cli/src/app/utils/helper/helper.component.ts new file mode 100644 index 00000000..66c3c70c --- /dev/null +++ b/portal-4cli/src/app/utils/helper/helper.component.ts @@ -0,0 +1,47 @@ +import { Component, Input } from '@angular/core'; +import 'rxjs/Rx'; +import {HelperService} from './helper.service'; +import {OpenaireProperties} from '../properties/openaireProperties'; + +@Component({ + selector: 'helper', + template: ` +
    +
    +
    +
    +` +}) +export class HelperComponent { + texts=[]; + @Input() style:boolean = false; + @Input() position:string = 'right'; + @Input() styleName:string = ''; + sub:any; + + constructor ( + private _service: HelperService + ) { + } + + ngOnInit() { + if(OpenaireProperties.isHelperEnabled() && location){ + this.sub = this._service.getHelper(location.pathname).subscribe( + data => { + this.texts =(data && data.content && data.content[this.position] )? data.content[this.position]:[]; + }, + err => { + console.log(err); + + } + ); + } + } + ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + } + + +} diff --git a/portal-4cli/src/app/utils/helper/helper.module.ts b/portal-4cli/src/app/utils/helper/helper.module.ts new file mode 100644 index 00000000..93752d19 --- /dev/null +++ b/portal-4cli/src/app/utils/helper/helper.module.ts @@ -0,0 +1,25 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +// import { RouterModule } from "@angular/router"; + +import {HelperComponent} from './helper.component'; +// import {HelperServiceModule} from './helperService.module'; +import {HelperService} from './helper.service'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule, + // RouterModule//,HelperServiceModule + ], + declarations: [ + HelperComponent + ], + providers:[HelperService], + exports: [ + HelperComponent + ] +}) +export class HelperModule{ } diff --git a/portal-4cli/src/app/utils/helper/helper.service.ts b/portal-4cli/src/app/utils/helper/helper.service.ts new file mode 100644 index 00000000..013ad903 --- /dev/null +++ b/portal-4cli/src/app/utils/helper/helper.service.ts @@ -0,0 +1,26 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; + +import { OpenaireProperties } from '../../utils/properties/openaireProperties'; + +@Injectable() +export class HelperService { + constructor(private http: Http ) {} + + getHelper (router: string):any { + console.info("get router helpText for : "+router); + + let url = OpenaireProperties.getHelperPageUrl() + '?q=' + router; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()); + + } + + + +} diff --git a/portal-4cli/src/app/utils/helper/helperService.module.ts b/portal-4cli/src/app/utils/helper/helperService.module.ts new file mode 100644 index 00000000..475fd82d --- /dev/null +++ b/portal-4cli/src/app/utils/helper/helperService.module.ts @@ -0,0 +1,20 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {HelperService} from './helper.service'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule + ], + declarations: [ + ], + providers:[ + HelperService +], + exports: [ + ] +}) +export class HelperServiceModule { } diff --git a/portal-4cli/src/app/utils/iframe.component.ts b/portal-4cli/src/app/utils/iframe.component.ts new file mode 100644 index 00000000..302f6431 --- /dev/null +++ b/portal-4cli/src/app/utils/iframe.component.ts @@ -0,0 +1,21 @@ +import {Component, ElementRef, Input} from '@angular/core'; +import { SafeResourceUrl, DomSanitizer } from '@angular/platform-browser'; +//Usage :: ` +@Component({ + selector: 'i-frame', + template: ` + + ` +}) +export class IFrameComponent { + public safeUrl: SafeResourceUrl; + @Input() url ; + @Input() width = '100%'; + @Input() height = '300'; + constructor(private sanitizer: DomSanitizer) { + } + ngOnInit() { + this.safeUrl = this.sanitizer.bypassSecurityTrustResourceUrl(this.url); + console.info("URL:" + this.safeUrl); + } +} diff --git a/portal-4cli/src/app/utils/iframe.module.ts b/portal-4cli/src/app/utils/iframe.module.ts new file mode 100644 index 00000000..702e5ab5 --- /dev/null +++ b/portal-4cli/src/app/utils/iframe.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {IFrameComponent} from './iframe.component'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule + ], + declarations: [ + IFrameComponent + ], + exports: [ + IFrameComponent + ] +}) +export class IFrameModule { } diff --git a/portal-4cli/src/app/utils/metaTags/openaireMetaTags.class.ts b/portal-4cli/src/app/utils/metaTags/openaireMetaTags.class.ts new file mode 100644 index 00000000..3b78aa42 --- /dev/null +++ b/portal-4cli/src/app/utils/metaTags/openaireMetaTags.class.ts @@ -0,0 +1,21 @@ +import {Meta} from '../../../angular2-meta'; + +export class OpenaireMetaTags{ + + constructor (private _meta: Meta ) { + } + + updateDescription(description:string){ + this._meta.updateMeta("description", description); + this._meta.updateProperty("og:description", description); + } + updateTitle(title:string){ + var _prefix ="OpenAIRE | "; + var _title = _prefix + ((title.length> 50 ) ?title.substring(0,50):title); + this._meta.setTitle(_title ); + this._meta.updateProperty("og:title",_title); + } + updateUrl(url:string){ + this._meta.updateProperty("og:url", url); + } +} diff --git a/portal-4cli/src/app/utils/modal/alert.ts b/portal-4cli/src/app/utils/modal/alert.ts new file mode 100644 index 00000000..c7155cd8 --- /dev/null +++ b/portal-4cli/src/app/utils/modal/alert.ts @@ -0,0 +1,111 @@ +import {Component, ViewEncapsulation, ComponentRef, ElementRef, Input, EventEmitter, Output} from '@angular/core'; +// import { DynamicComponentLoader} from '@angular/core'; + +import {Open} from './open.component'; + +@Component({ + selector: 'modal-alert', + template: ` + + + + `, + encapsulation: ViewEncapsulation.None, +}) +/** + * API to an open alert window. + */ +export class AlertModal{ + /** + * Caption for the title. + */ + public alertTitle:string; + /** + * Describes if the alert contains Ok Button. + * The default Ok button will close the alert and emit the callback. + * Defaults to true. + */ + public okButton:boolean = true; + /** + * Caption for the OK button. + * Default: Ok + */ + public okButtonText:string= 'Ok'; + /** + * Describes if the alert contains cancel Button. + * The default Cancelbutton will close the alert. + * Defaults to true. + */ + public cancelButton:boolean = true; + /** + * Caption for the Cancel button. + * Default: Cancel + */ + public cancelButtonText:string = 'Cancel'; + /** + * if the alertMessage is true it will show the contentString inside alert body. + */ + public alertMessage:boolean = true; + /** + * Some message/content can be set in message which will be shown in alert body. + */ + public message:string; + /** + * if the value is true alert footer will be visible or else it will be hidden. + */ + public alertFooter:boolean= true; + /** + * shows alert header if the value is true. + */ + public alertHeader:boolean = true; + /** + * if the value is true alert will be visible or else it will be hidden. + */ + public isOpen:boolean=false; + /** + * Emitted when a ok button was clicked + * or when Ok method is called. + */ + @Output() public alertOutput:EventEmitter = new EventEmitter(); + constructor( public _elementRef: ElementRef){} + /** + * Opens a alert window creating backdrop. + */ + open(){ + this.isOpen= true; + } + /** + * ok method closes the modal and emits modalOutput. + */ + ok(){ + this.isOpen = false; + this.alertOutput.emit(true); + } + /** + * cancel method closes the moda. + */ + cancel(){ + this.isOpen = false; + } +} diff --git a/portal-4cli/src/app/utils/modal/alertModal.module.ts b/portal-4cli/src/app/utils/modal/alertModal.module.ts new file mode 100644 index 00000000..d39e168d --- /dev/null +++ b/portal-4cli/src/app/utils/modal/alertModal.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {AlertModal} from './alert'; +import {ModalModule} from './modal.module'; + +@NgModule({ + imports: [ CommonModule, FormsModule, ModalModule ], + declarations: [ + AlertModal + ], + exports: [ + AlertModal + ] +}) +export class AlertModalModule { } diff --git a/portal-4cli/src/app/utils/modal/loading.component.ts b/portal-4cli/src/app/utils/modal/loading.component.ts new file mode 100644 index 00000000..55a5501e --- /dev/null +++ b/portal-4cli/src/app/utils/modal/loading.component.ts @@ -0,0 +1,56 @@ +import {Component, ViewEncapsulation, ComponentRef, ElementRef, Input, EventEmitter, Output} from '@angular/core'; + +@Component({ + selector: 'modal-loading', + template: ` + +
    +
    + + +
    +
    +

    {{message}}

    +
    +
    +
    + +
    + +
    + + `, + encapsulation: ViewEncapsulation.None, +}) +/** + * API to an open alert window. + */ +export class ModalLoading{ + +@Input() public message:string ="Loading"; + + /** + * if the value is true alert will be visible or else it will be hidden. + */ + public isOpen:boolean=false; + /** + * Emitted when a ok button was clicked + * or when Ok method is called. + */ + @Output() public alertOutput:EventEmitter = new EventEmitter(); + constructor( public _elementRef: ElementRef){} + /** + * Opens a alert window creating backdrop. + */ + open(){ + this.isOpen= true; + } + + close(){ + this.isOpen = false; + } +} diff --git a/portal-4cli/src/app/utils/modal/loadingModal.module.ts b/portal-4cli/src/app/utils/modal/loadingModal.module.ts new file mode 100644 index 00000000..6edf5c4a --- /dev/null +++ b/portal-4cli/src/app/utils/modal/loadingModal.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + + import {ModalLoading} from './loading.component'; +import {ModalModule} from './modal.module'; + +//helpers + +@NgModule({ + imports: [ CommonModule, FormsModule,ModalModule ], + declarations: [ + ModalLoading + ], + exports: [ + ModalLoading + ] +}) +export class LoadingModalModule { } diff --git a/portal-4cli/src/app/utils/modal/modal.module.ts b/portal-4cli/src/app/utils/modal/modal.module.ts new file mode 100644 index 00000000..fd48478c --- /dev/null +++ b/portal-4cli/src/app/utils/modal/modal.module.ts @@ -0,0 +1,13 @@ +/* common components of modal components */ +import { NgModule } from '@angular/core'; +import {Open} from './open.component'; +@NgModule({ + imports: [ ], + declarations: [ + Open + ], + exports: [ + Open + ] +}) +export class ModalModule { } diff --git a/portal-4cli/src/app/utils/modal/open.component.ts b/portal-4cli/src/app/utils/modal/open.component.ts new file mode 100644 index 00000000..fb9f011e --- /dev/null +++ b/portal-4cli/src/app/utils/modal/open.component.ts @@ -0,0 +1,57 @@ +import {Directive, Input, HostBinding} from '@angular/core'; + +// todo: add animate +// todo: add init and on change +@Directive({selector: '[open]'}) +export class Open { + @HostBinding('style.display') + public display:string; + @HostBinding('class.in') + @HostBinding('attr.aria-expanded') + public isExpanded:boolean = true; + + @Input() + public set open(value:boolean) { + this.isExpanded = value; + this.toggle(); + } + + public get open():boolean { + return this.isExpanded; + } + + constructor() { + } + init() { + this.isExpanded = false; + this.display = 'none'; + } + toggle() { + if (this.isExpanded) { + this.hide(); + } else { + this.show(); + } + } + + hide() { + this.isExpanded = false; + this.display = 'none'; + if (typeof document !== 'undefined') { + let backDrop = document.getElementsByClassName("modal-backdrop"); + if(backDrop.length>0){ + document.body.removeChild(backDrop[0]); + } + } + } + + show() { + if (typeof document !== 'undefined') { + // let backDrop = document.createElement('div'); + // backDrop.className="modal-backdrop fade in"; + // document.body.appendChild(backDrop); + } + this.isExpanded = true; + this.display = 'block'; + } +} diff --git a/portal-4cli/src/app/utils/modal/selectModal.component.ts b/portal-4cli/src/app/utils/modal/selectModal.component.ts new file mode 100644 index 00000000..78330b76 --- /dev/null +++ b/portal-4cli/src/app/utils/modal/selectModal.component.ts @@ -0,0 +1,79 @@ +import {Component, ViewEncapsulation, ComponentRef, ElementRef, Input, EventEmitter, Output} from '@angular/core'; + +@Component({ + selector: 'modal-select', + template: ` +
    +
    + +
    + + `, + encapsulation: ViewEncapsulation.None, +}) +/** + * API to an open alert window. + */ +export class ModalSelect{ + +@Input() public message:string ="Loading"; +@Input() public options:string[] = []; + +public selected: string; + + /** + * if the value is true alert will be visible or else it will be hidden. + */ + public isOpen:boolean=false; + /** + * Emitted when a ok button was clicked + * or when Ok method is called. + */ + @Output() public alertOutput:EventEmitter = new EventEmitter(); + constructor( public _elementRef: ElementRef){} + /** + * Opens a alert window creating backdrop. + */ + open(){ + this.isOpen= true; + } + + close(){ + this.isOpen = false; + if(!this.selected) { + this.selected = this.options[0]; + } + this.alertOutput.emit(this.selected); + } + +} diff --git a/portal-4cli/src/app/utils/modal/selectModal.module.ts b/portal-4cli/src/app/utils/modal/selectModal.module.ts new file mode 100644 index 00000000..971a7dd7 --- /dev/null +++ b/portal-4cli/src/app/utils/modal/selectModal.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + + import {ModalSelect} from './selectModal.component'; +import {ModalModule} from './modal.module'; + +//helpers + +@NgModule({ + imports: [ CommonModule, FormsModule,ModalModule ], + declarations: [ + ModalSelect + ], + exports: [ + ModalSelect + ] +}) +export class SelectModalModule { } diff --git a/portal-4cli/src/app/utils/my-date-picker/directives/my-date-picker.focus.directive.ts b/portal-4cli/src/app/utils/my-date-picker/directives/my-date-picker.focus.directive.ts new file mode 100644 index 00000000..5508ea6c --- /dev/null +++ b/portal-4cli/src/app/utils/my-date-picker/directives/my-date-picker.focus.directive.ts @@ -0,0 +1,26 @@ +import { Directive, ElementRef, Renderer, AfterViewInit, Input } from "@angular/core"; + +@Directive({ + selector: "[mydpfocus]" +}) + +export class FocusDirective implements AfterViewInit { + @Input("mydpfocus") value: string; + + constructor(private el: ElementRef, private renderer: Renderer) {} + + // Focus to element: if value 0 = don't set focus, 1 = set only focus, 2 = set focus and set cursor position + ngAfterViewInit() { + if (this.value === "0") { + return; + } + + this.renderer.invokeElementMethod(this.el.nativeElement, "focus", []); + + // Set cursor position at the end of text if input element + if (this.value === "2") { + let len = this.el.nativeElement.value.length; + this.el.nativeElement.setSelectionRange(len, len); + } + } +} \ No newline at end of file diff --git a/portal-4cli/src/app/utils/my-date-picker/directives/my-date-picker.input.auto.fill.directive.ts b/portal-4cli/src/app/utils/my-date-picker/directives/my-date-picker.input.auto.fill.directive.ts new file mode 100644 index 00000000..ef1a1501 --- /dev/null +++ b/portal-4cli/src/app/utils/my-date-picker/directives/my-date-picker.input.auto.fill.directive.ts @@ -0,0 +1,69 @@ +import { Directive, ElementRef, Renderer, Input, HostListener } from "@angular/core"; +import { IMyInputAutoFill } from "../interfaces/my-input-auto-fill.interface"; + +@Directive({ + selector: "[myinputautofill]" +}) + +export class InputAutoFillDirective { + @Input("myinputautofill") opts: IMyInputAutoFill; + + constructor(private el: ElementRef, private rndr: Renderer) {} + + @HostListener("keyup", ["$event"]) onKeyUp(evt: KeyboardEvent) { + if (!this.opts.enabled || evt.keyCode === 8 || evt.keyCode === 46) { + return; + } + + let val: string = this.getInputValue(); + let ews: boolean = this.endsWith(val, this.opts.separator); + let parts: Array = val.split(this.opts.separator); + let idx: number = parts.length - 1; + + if (val.indexOf(this.opts.separator + this.opts.separator) !== -1) { + return; + } + + if (!ews && (val.length === this.getPartLength(0) || val.length === this.getPartLength(0) + this.getPartLength(1) + this.opts.separator.length)) { + this.setInputValue(val + this.opts.separator); + } + else if (ews && parts[idx - 1].length < this.getPartLength(idx - 1) && this.isNumber(parts[idx - 1]) && (this.isDay(idx - 1) || this.isMonth(idx - 1))) { + this.setInputValue(this.insertPos(val, val.length - 2, "0")); + } + else if (parts[idx].length < this.getPartLength(idx) && this.isNumber(parts[idx]) && (Number(parts[idx]) > 3 && this.isDay(idx) || Number(parts[idx]) > 1 && this.isMonth(idx))) { + this.setInputValue(this.insertPos(val, val.length - 1, "0") + (idx < 2 ? this.opts.separator : "")); + } + } + + private endsWith(val: string, suffix: string): boolean { + return val.indexOf(suffix, val.length - suffix.length) !== -1; + } + + private insertPos(str: string, idx: number, val: string): string { + return str.substr(0, idx) + val + str.substr(idx); + } + + private getPartLength(idx: number): number { + return this.opts.formatParts[idx].length; + } + + private isNumber(val: string): boolean { + return val.match(/[1-9]/) !== null; + } + + private isDay(idx: number): boolean { + return this.opts.formatParts[idx].indexOf("d") !== -1; + } + + private isMonth(idx: number): boolean { + return this.opts.formatParts[idx].indexOf("m") !== -1 && this.opts.formatParts[idx].length === 2; + } + + private getInputValue(): string { + return this.el.nativeElement.value; + } + + private setInputValue(val: string): void { + this.rndr.setElementProperty(this.el.nativeElement, "value", val); + } +} \ No newline at end of file diff --git a/portal-4cli/src/app/utils/my-date-picker/index.ts b/portal-4cli/src/app/utils/my-date-picker/index.ts new file mode 100644 index 00000000..55613d2b --- /dev/null +++ b/portal-4cli/src/app/utils/my-date-picker/index.ts @@ -0,0 +1,7 @@ +export * from "./services/my-date-picker.locale.service"; +export * from "./services/my-date-picker.util.service"; +export * from "./directives/my-date-picker.focus.directive"; +export * from "./directives/my-date-picker.input.auto.fill.directive"; +export * from "./my-date-picker.component"; +export * from "./my-date-picker.module"; +export * from "./interfaces/index"; \ No newline at end of file diff --git a/portal-4cli/src/app/utils/my-date-picker/interfaces/index.ts b/portal-4cli/src/app/utils/my-date-picker/interfaces/index.ts new file mode 100644 index 00000000..ab34b252 --- /dev/null +++ b/portal-4cli/src/app/utils/my-date-picker/interfaces/index.ts @@ -0,0 +1,15 @@ +export * from "./my-date.interface"; +export * from "./my-date-range.interface"; +export * from "./my-day-labels.interface"; +export * from "./my-month-labels.interface"; +export * from "./my-month.interface"; +export * from "./my-calendar-day.interface"; +export * from "./my-week.interface"; +export * from "./my-options.interface"; +export * from "./my-locale.interface"; +export * from "./my-date-model.interface"; +export * from "./my-input-field-changed.interface"; +export * from "./my-input-focus-blur.interface"; +export * from "./my-weekday.interface"; +export * from "./my-calendar-view-changed.interface"; +export * from "./my-input-auto-fill.interface"; \ No newline at end of file diff --git a/portal-4cli/src/app/utils/my-date-picker/interfaces/my-calendar-day.interface.ts b/portal-4cli/src/app/utils/my-date-picker/interfaces/my-calendar-day.interface.ts new file mode 100644 index 00000000..d554243a --- /dev/null +++ b/portal-4cli/src/app/utils/my-date-picker/interfaces/my-calendar-day.interface.ts @@ -0,0 +1,9 @@ +import { IMyDate } from "./my-date.interface"; + +export interface IMyCalendarDay { + dateObj: IMyDate; + cmo: number; + currDay: boolean; + dayNbr: number; + disabled: boolean; +} \ No newline at end of file diff --git a/portal-4cli/src/app/utils/my-date-picker/interfaces/my-calendar-view-changed.interface.ts b/portal-4cli/src/app/utils/my-date-picker/interfaces/my-calendar-view-changed.interface.ts new file mode 100644 index 00000000..9b9baa5e --- /dev/null +++ b/portal-4cli/src/app/utils/my-date-picker/interfaces/my-calendar-view-changed.interface.ts @@ -0,0 +1,8 @@ +import { IMyWeekday } from "./my-weekday.interface"; + +export interface IMyCalendarViewChanged { + year: number; + month: number; + first: IMyWeekday; + last: IMyWeekday; +} diff --git a/portal-4cli/src/app/utils/my-date-picker/interfaces/my-date-model.interface.ts b/portal-4cli/src/app/utils/my-date-picker/interfaces/my-date-model.interface.ts new file mode 100644 index 00000000..35aa7535 --- /dev/null +++ b/portal-4cli/src/app/utils/my-date-picker/interfaces/my-date-model.interface.ts @@ -0,0 +1,8 @@ +import { IMyDate } from "./my-date.interface"; + +export interface IMyDateModel { + date: IMyDate; + jsdate: Date; + formatted: string; + epoc: number; +} diff --git a/portal-4cli/src/app/utils/my-date-picker/interfaces/my-date-range.interface.ts b/portal-4cli/src/app/utils/my-date-picker/interfaces/my-date-range.interface.ts new file mode 100644 index 00000000..e24b319b --- /dev/null +++ b/portal-4cli/src/app/utils/my-date-picker/interfaces/my-date-range.interface.ts @@ -0,0 +1,6 @@ +import { IMyDate } from "./my-date.interface"; + +export interface IMyDateRange { + begin: IMyDate; + end: IMyDate; +} diff --git a/portal-4cli/src/app/utils/my-date-picker/interfaces/my-date.interface.ts b/portal-4cli/src/app/utils/my-date-picker/interfaces/my-date.interface.ts new file mode 100644 index 00000000..99f00796 --- /dev/null +++ b/portal-4cli/src/app/utils/my-date-picker/interfaces/my-date.interface.ts @@ -0,0 +1,5 @@ +export interface IMyDate { + year: number; + month: number; + day: number; +} diff --git a/portal-4cli/src/app/utils/my-date-picker/interfaces/my-day-labels.interface.ts b/portal-4cli/src/app/utils/my-date-picker/interfaces/my-day-labels.interface.ts new file mode 100644 index 00000000..f2fcfa24 --- /dev/null +++ b/portal-4cli/src/app/utils/my-date-picker/interfaces/my-day-labels.interface.ts @@ -0,0 +1,3 @@ +export interface IMyDayLabels { + [day: string]: string; +} \ No newline at end of file diff --git a/portal-4cli/src/app/utils/my-date-picker/interfaces/my-input-auto-fill.interface.ts b/portal-4cli/src/app/utils/my-date-picker/interfaces/my-input-auto-fill.interface.ts new file mode 100644 index 00000000..695afa92 --- /dev/null +++ b/portal-4cli/src/app/utils/my-date-picker/interfaces/my-input-auto-fill.interface.ts @@ -0,0 +1,5 @@ +export interface IMyInputAutoFill { + separator: string; + formatParts: Array; + enabled: boolean; +} diff --git a/portal-4cli/src/app/utils/my-date-picker/interfaces/my-input-field-changed.interface.ts b/portal-4cli/src/app/utils/my-date-picker/interfaces/my-input-field-changed.interface.ts new file mode 100644 index 00000000..c93530b6 --- /dev/null +++ b/portal-4cli/src/app/utils/my-date-picker/interfaces/my-input-field-changed.interface.ts @@ -0,0 +1,5 @@ +export interface IMyInputFieldChanged { + value: string; + dateFormat: string; + valid: boolean; +} diff --git a/portal-4cli/src/app/utils/my-date-picker/interfaces/my-input-focus-blur.interface.ts b/portal-4cli/src/app/utils/my-date-picker/interfaces/my-input-focus-blur.interface.ts new file mode 100644 index 00000000..99678cbb --- /dev/null +++ b/portal-4cli/src/app/utils/my-date-picker/interfaces/my-input-focus-blur.interface.ts @@ -0,0 +1,4 @@ +export interface IMyInputFocusBlur { + reason: number; + value: string; +} diff --git a/portal-4cli/src/app/utils/my-date-picker/interfaces/my-locale.interface.ts b/portal-4cli/src/app/utils/my-date-picker/interfaces/my-locale.interface.ts new file mode 100644 index 00000000..25d268ba --- /dev/null +++ b/portal-4cli/src/app/utils/my-date-picker/interfaces/my-locale.interface.ts @@ -0,0 +1,5 @@ +import { IMyOptions } from "./my-options.interface"; + +export interface IMyLocales { + [lang: string]: IMyOptions; +} \ No newline at end of file diff --git a/portal-4cli/src/app/utils/my-date-picker/interfaces/my-month-labels.interface.ts b/portal-4cli/src/app/utils/my-date-picker/interfaces/my-month-labels.interface.ts new file mode 100644 index 00000000..0eede49b --- /dev/null +++ b/portal-4cli/src/app/utils/my-date-picker/interfaces/my-month-labels.interface.ts @@ -0,0 +1,3 @@ +export interface IMyMonthLabels { + [month: number]: string; +} \ No newline at end of file diff --git a/portal-4cli/src/app/utils/my-date-picker/interfaces/my-month.interface.ts b/portal-4cli/src/app/utils/my-date-picker/interfaces/my-month.interface.ts new file mode 100644 index 00000000..846a23eb --- /dev/null +++ b/portal-4cli/src/app/utils/my-date-picker/interfaces/my-month.interface.ts @@ -0,0 +1,5 @@ +export interface IMyMonth { + monthTxt: string; + monthNbr: number; + year: number; +} \ No newline at end of file diff --git a/portal-4cli/src/app/utils/my-date-picker/interfaces/my-options.interface.ts b/portal-4cli/src/app/utils/my-date-picker/interfaces/my-options.interface.ts new file mode 100644 index 00000000..89c26bea --- /dev/null +++ b/portal-4cli/src/app/utils/my-date-picker/interfaces/my-options.interface.ts @@ -0,0 +1,48 @@ +import { IMyDayLabels } from "./my-day-labels.interface"; +import { IMyMonthLabels } from "./my-month-labels.interface"; +import { IMyDate } from "./my-date.interface"; +import { IMyDateRange } from "./my-date-range.interface"; + +export interface IMyOptions { + dayLabels?: IMyDayLabels; + monthLabels?: IMyMonthLabels; + dateFormat?: string; + showTodayBtn?: boolean; + todayBtnTxt?: string; + firstDayOfWeek?: string; + sunHighlight?: boolean; + markCurrentDay?: boolean; + disableUntil?: IMyDate; + disableSince?: IMyDate; + disableDays?: Array; + enableDays?: Array; + disableDateRange?: IMyDateRange; + disableWeekends?: boolean; + showWeekNumbers?: boolean; + height?: string; + width?: string; + selectionTxtFontSize?: string; + inline?: boolean; + showClearDateBtn?: boolean; + alignSelectorRight?: boolean; + openSelectorTopOfInput?: boolean; + indicateInvalidDate?: boolean; + editableDateField?: boolean; + editableMonthAndYear?: boolean; + disableHeaderButtons?: boolean; + minYear?: number; + maxYear?: number; + componentDisabled?: boolean; + inputValueRequired?: boolean; + showSelectorArrow?: boolean; + showInputField?: boolean; + openSelectorOnInputClick?: boolean; + inputAutoFill?: boolean; + ariaLabelInputField?: string; + ariaLabelClearDate?: string; + ariaLabelOpenCalendar?: string; + ariaLabelPrevMonth?: string; + ariaLabelNextMonth?: string; + ariaLabelPrevYear?: string; + ariaLabelNextYear?: string; +} diff --git a/portal-4cli/src/app/utils/my-date-picker/interfaces/my-week.interface.ts b/portal-4cli/src/app/utils/my-date-picker/interfaces/my-week.interface.ts new file mode 100644 index 00000000..be7bca16 --- /dev/null +++ b/portal-4cli/src/app/utils/my-date-picker/interfaces/my-week.interface.ts @@ -0,0 +1,6 @@ +import { IMyCalendarDay } from "./my-calendar-day.interface"; + +export interface IMyWeek { + week: Array; + weekNbr: number; +} \ No newline at end of file diff --git a/portal-4cli/src/app/utils/my-date-picker/interfaces/my-weekday.interface.ts b/portal-4cli/src/app/utils/my-date-picker/interfaces/my-weekday.interface.ts new file mode 100644 index 00000000..da1df557 --- /dev/null +++ b/portal-4cli/src/app/utils/my-date-picker/interfaces/my-weekday.interface.ts @@ -0,0 +1,4 @@ +export interface IMyWeekday { + number: number; + weekday: string; +} diff --git a/portal-4cli/src/app/utils/my-date-picker/my-date-picker.component.css b/portal-4cli/src/app/utils/my-date-picker/my-date-picker.component.css new file mode 100644 index 00000000..3c21416d --- /dev/null +++ b/portal-4cli/src/app/utils/my-date-picker/my-date-picker.component.css @@ -0,0 +1,461 @@ +.mydp { + min-width: 30px; + border-radius: 2px; + line-height: 1.1; + display: inline-block; + position: relative; +} + +.mydp * { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + font-family: Arial, Helvetica, sans-serif; + padding: 0; + margin: 0; +} + +.mydp .selector { + margin-top: 2px; + margin-left: -1px; + position: absolute; + width: 252px; + padding: 0; + border: 1px solid #CCC; + border-radius: 2px; + z-index: 100; + animation: selectorfadein 0.1s; +} + +.mydp .selector:focus { + border: 1px solid #ADD8E6; + outline: none; +} + +@keyframes selectorfadein { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +.mydp .selectorarrow { + background: #FAFAFA; + margin-top: 12px; + padding: 0; +} + +.mydp .selectorarrow:after, +.mydp .selectorarrow:before { + bottom: 100%; + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; +} + +.mydp .selectorarrow:after { + border-color: rgba(250, 250, 250, 0); + border-bottom-color: #FAFAFA; + border-width: 10px; + margin-left: -10px; +} + +.mydp .selectorarrow:before { + border-color: rgba(204, 204, 204, 0); + border-bottom-color: #CCC; + border-width: 11px; + margin-left: -11px; +} + +.mydp .selectorarrow:focus:before { + border-bottom-color: #ADD8E6; +} + +.mydp .selectorarrowleft:after, +.mydp .selectorarrowleft:before { + left: 24px; +} + +.mydp .selectorarrowright:after, +.mydp .selectorarrowright:before { + left: 224px; +} + +.mydp .alignselectorright { + right: -1px; +} + +.mydp .selectiongroup { + position: relative; + display: table; + border: none; + border-spacing: 0; + background-color: #FFF; +} + +.mydp .selection { + outline: none; + background-color: #FFF; + display: table-cell; + position: absolute; + width: 100%; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + text-align: center; +} + +.mydp .invaliddate, +.mydp .invalidmonth, +.mydp .invalidyear { + background-color: #F1DEDE; +} + +.mydp ::-ms-clear { + display: none; +} + +.mydp .selbtngroup { + position: relative; + vertical-align: middle; + white-space: nowrap; + width: 1%; + display: table-cell; + font-size: 0; +} + +.mydp .btnpicker, +.mydp .btnclear { + height: 100%; + width: 30px; + border: none; + padding: 0; + outline: 0; + font: inherit; + -moz-user-select: none; +} + +.mydp .btnleftborder { + border-left: 1px solid #CCC; +} + +.mydp .btnpickerenabled, +.mydp .btnclearenabled, +.mydp .headertodaybtnenabled, +.mydp .headerbtnenabled { + cursor: pointer; +} + +.mydp .btnpickerdisabled, +.mydp .btncleardisabled, +.mydp .headertodaybtndisabled, +.mydp .headerbtndisabled { + cursor: not-allowed; +} + +.mydp .headerbtndisabled { + opacity: 0.4; +} + +.mydp .btnpicker, +.mydp .btnclear, +.mydp .headertodaybtn { + background: #FFF; +} + +.mydp .header { + width: 100%; + height: 30px; + background-color: #FAFAFA; +} + +.mydp .header td { + vertical-align: middle; + border: none; + line-height: 0; +} + +.mydp .header td:nth-child(1) { + padding-left: 4px; +} + +.mydp .header td:nth-child(2) { + text-align: center; +} + +.mydp .header td:nth-child(3) { + padding-right: 4px; +} + +.mydp .caltable { + table-layout: fixed; + width: 100%; + background-color: #FFF; + font-size: 14px; +} + +.mydp .caltable, +.mydp .weekdaytitle, +.mydp .daycell { + border-collapse: collapse; + color: #003366; + line-height: 1.1; +} + +.mydp .weekdaytitle, +.mydp .daycell { + padding: 5px; + text-align: center; +} + +.mydp .weekdaytitle { + background-color: #DDD; + font-size: 12px; + font-weight: bold; + vertical-align: middle; + max-width: 36px; + overflow: hidden; + white-space: nowrap; +} + +.mydp .weekdaytitleweeknbr { + width: 20px; + border-right: 1px solid #BBB; +} + +.mydp .daycell { + cursor: pointer; + height: 30px; +} + +.mydp .daycell div { + background-color: inherit; + vertical-align: middle; +} + +.mydp .daycell div span { + vertical-align: middle; +} + +.mydp .daycellweeknbr { + font-size: 10px; + border-right: 1px solid #CCC; + cursor: default; + color: #000; +} + +.mydp .inlinedp { + position: relative; + margin-top: -1px; +} + +.mydp .prevmonth { + color: #CCC; +} + +.mydp .nextmonth { + color: #CCC; +} + +.mydp .disabled { + cursor: default !important; + color: #CCC !important; + background: #FBEFEF !important; +} + +.mydp .sunday { + color: #C30000; +} + +.mydp .sundayDim { + opacity: 0.5; +} + +.mydp .currmonth { + background-color: #F6F6F6; + font-weight: bold; +} + +.mydp .currday { + text-decoration: underline; +} + +.mydp .selectedday div { + border: 1px solid #004198; + background-color: #8EBFFF !important; + border-radius: 2px; +} + +.mydp .headerbtncell { + background-color: #FAFAFA; + display: table-cell; + vertical-align: middle; +} + +.mydp .headerbtn, +.mydp .headerlabelbtn { + background: #FAFAFA; + border: none; + height: 22px; +} + +.mydp .headerbtn { + width: 16px; +} + +.mydp .headerlabelbtn { + font-size: 14px; +} + +.mydp, +.mydp .headertodaybtn, +.mydp .monthinput, +.mydp .yearinput { + border: 1px solid #CCC; +} + +.mydp .btnpicker, +.mydp .btnclear, +.mydp .headerbtn, +.mydp .headermonthtxt, +.mydp .headeryeartxt, +.mydp .headertodaybtn, +.mydp .selection { + color: #000; +} + +.mydp .headertodaybtn { + padding: 0 4px; + border-radius: 2px; + font-size: 11px; + height: 22px; + min-width: 60px; + max-width: 70px; + overflow: hidden; + white-space: nowrap; +} + +.mydp button::-moz-focus-inner { + border: 0; +} + +.mydp .headermonthtxt, +.mydp .headeryeartxt { + text-align: center; + display: table-cell; + vertical-align: middle; + font-size: 14px; + height: 26px; + width: 40px; + max-width: 40px; + overflow: hidden; + white-space: nowrap; +} + +.mydp .btnclear:focus, +.mydp .btnpicker:focus, +.mydp .headertodaybtn:focus { + background: #ADD8E6; +} + +.mydp .headerbtn:focus, +.mydp .monthlabel:focus, +.mydp .yearlabel:focus { + color: #ADD8E6; + outline: none; +} + +.mydp .daycell:focus { + outline: 1px solid #CCC; +} + +.mydp .icon-mydpcalendar, +.mydp .icon-mydpremove { + font-size: 16px; +} + +.mydp .icon-mydpleft, +.mydp .icon-mydpright { + color: #222; + font-size: 20px; +} + +.mydp table { + display: table; + border-spacing: 0; +} + +.mydp table td { + padding: 0; +} + +.mydp table, +.mydp th, +.mydp td { + border: none; +} + +.mydp .btnpickerenabled:hover, +.mydp .btnclearenabled:hover, +.mydp .headertodaybtnenabled:hover, +.mydp .tablesingleday:hover { + background-color: #8BDAF4; +} + +.mydp .monthlabel, +.mydp .yearlabel { + cursor: pointer; +} + +.mydp .yearinput, +.mydp .monthinput { + width: 40px; + height: 22px; + text-align: center; + font-weight: bold; + outline: none; + border-radius: 2px; +} + +.mydp .headerbtnenabled:hover, +.mydp .monthlabel:hover, +.mydp .yearlabel:hover { + color: #8BDAF4; +} + +@font-face { + font-family: 'mydatepicker'; + src: url('data:application/octet-stream;base64,AAEAAAAPAIAAAwBwR1NVQiCMJXkAAAD8AAAAVE9TLzI+IEhBAAABUAAAAFZjbWFwEIvU5AAAAagAAAGiY3Z0IAbV/wQAAApQAAAAIGZwZ22KkZBZAAAKcAAAC3BnYXNwAAAAEAAACkgAAAAIZ2x5ZsNblX4AAANMAAADBGhlYWQM+nt/AAAGUAAAADZoaGVhBz0DVgAABogAAAAkaG10eA1jAAAAAAasAAAAFGxvY2EBWgHMAAAGwAAAAAxtYXhwAXUMOgAABswAAAAgbmFtZZKUFgMAAAbsAAAC/XBvc3TOA7dOAAAJ7AAAAFpwcmVw5UErvAAAFeAAAACGAAEAAAAKADAAPgACbGF0bgAOREZMVAAaAAQAAAAAAAAAAQAAAAQAAAAAAAAAAQAAAAFsaWdhAAgAAAABAAAAAQAEAAQAAAABAAgAAQAGAAAAAQAAAAECrQGQAAUAAAJ6ArwAAACMAnoCvAAAAeAAMQECAAACAAUDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBmRWQAQOgA6AUDUv9qAFoDUgCWAAAAAQAAAAAAAAAAAAUAAAADAAAALAAAAAQAAAFiAAEAAAAAAFwAAwABAAAALAADAAoAAAFiAAQAMAAAAAYABAABAALoAugF//8AAOgA6AX//wAAAAAAAQAGAAoAAAABAAIAAwAEAAABBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAABAAAAAAAAAAAQAAOgAAADoAAAAAAEAAOgBAADoAQAAAAIAAOgCAADoAgAAAAMAAOgFAADoBQAAAAQAAAABAAAAAAFBAn0ADgAKtwAAAGYUAQUVKwEUDwEGIiY1ETQ+AR8BFgFBCvoLHBYWHAv6CgFeDgv6CxYOAfQPFAIM+goAAAEAAAAAAWcCfAANABdAFAABAAEBRwABAAFvAAAAZhcTAgUWKwERFAYiLwEmND8BNjIWAWUUIAn6Cgr6CxwYAlj+DA4WC/oLHAv6CxYAAAAADwAA/2oDoQNSAAMABwALAA8AEwAXABsAHwAjADMANwA7AD8ATwBzAJhAlUElAh0SSS0kAxMdAkchHwIdEwkdVBsBExkXDQMJCBMJXxgWDAMIFREHAwUECAVeFBAGAwQPCwMDAQAEAV4aARISHlggAR4eDEgOCgIDAAAcWAAcHA0cSXJwbWpnZmNgXVtWU01MRUQ/Pj08Ozo5ODc2NTQxLyknIyIhIB8eHRwbGhkYFxYVFBMSEREREREREREQIgUdKxczNSMXMzUjJzM1IxczNSMnMzUjATM1IyczNSMBMzUjJzM1IwM1NCYnIyIGBxUUFjczMjYBMzUjJzM1IxczNSM3NTQmJyMiBhcVFBY3MzI2NxEUBiMhIiY1ETQ2OwE1NDY7ATIWHQEzNTQ2OwEyFgcVMzIWR6GhxbKyxaGhxbKyxaGhAZuzs9aysgGsoaHWs7PEDAYkBwoBDAYkBwoBm6Gh1rOz1qGhEgoIIwcMAQoIIwgK1ywc/O4dKiodSDQlJCU01jYkIyU2AUcdKk+hoaEksrKyJKH9xKH6of3EoSSyATChBwoBDAahBwwBCv4msiShoaFroQcKAQwGoQcMAQos/TUdKiodAssdKjYlNDQlNjYlNDQlNioAAAABAAD/7wLUAoYAJAAeQBsiGRAHBAACAUcDAQIAAm8BAQAAZhQcFBQEBRgrJRQPAQYiLwEHBiIvASY0PwEnJjQ/ATYyHwE3NjIfARYUDwEXFgLUD0wQLBCkpBAsEEwQEKSkEBBMECwQpKQQLBBMDw+kpA9wFhBMDw+lpQ8PTBAsEKSkECwQTBAQpKQQEEwPLg+kpA8AAQAAAAEAAGAI8Y9fDzz1AAsD6AAAAADU+ZvvAAAAANT5m+8AAP9qA+gDUgAAAAgAAgAAAAAAAAABAAADUv9qAAAD6AAA//4D6AABAAAAAAAAAAAAAAAAAAAABQPoAAABZQAAAWUAAAOgAAADEQAAAAAAAAAiAEoBOAGCAAEAAAAFAHQADwAAAAAAAgBEAFQAcwAAAKkLcAAAAAAAAAASAN4AAQAAAAAAAAA1AAAAAQAAAAAAAQAMADUAAQAAAAAAAgAHAEEAAQAAAAAAAwAMAEgAAQAAAAAABAAMAFQAAQAAAAAABQALAGAAAQAAAAAABgAMAGsAAQAAAAAACgArAHcAAQAAAAAACwATAKIAAwABBAkAAABqALUAAwABBAkAAQAYAR8AAwABBAkAAgAOATcAAwABBAkAAwAYAUUAAwABBAkABAAYAV0AAwABBAkABQAWAXUAAwABBAkABgAYAYsAAwABBAkACgBWAaMAAwABBAkACwAmAflDb3B5cmlnaHQgKEMpIDIwMTcgYnkgb3JpZ2luYWwgYXV0aG9ycyBAIGZvbnRlbGxvLmNvbW15ZGF0ZXBpY2tlclJlZ3VsYXJteWRhdGVwaWNrZXJteWRhdGVwaWNrZXJWZXJzaW9uIDEuMG15ZGF0ZXBpY2tlckdlbmVyYXRlZCBieSBzdmcydHRmIGZyb20gRm9udGVsbG8gcHJvamVjdC5odHRwOi8vZm9udGVsbG8uY29tAEMAbwBwAHkAcgBpAGcAaAB0ACAAKABDACkAIAAyADAAMQA3ACAAYgB5ACAAbwByAGkAZwBpAG4AYQBsACAAYQB1AHQAaABvAHIAcwAgAEAAIABmAG8AbgB0AGUAbABsAG8ALgBjAG8AbQBtAHkAZABhAHQAZQBwAGkAYwBrAGUAcgBSAGUAZwB1AGwAYQByAG0AeQBkAGEAdABlAHAAaQBjAGsAZQByAG0AeQBkAGEAdABlAHAAaQBjAGsAZQByAFYAZQByAHMAaQBvAG4AIAAxAC4AMABtAHkAZABhAHQAZQBwAGkAYwBrAGUAcgBHAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAHMAdgBnADIAdAB0AGYAIABmAHIAbwBtACAARgBvAG4AdABlAGwAbABvACAAcAByAG8AagBlAGMAdAAuAGgAdAB0AHAAOgAvAC8AZgBvAG4AdABlAGwAbABvAC4AYwBvAG0AAAAAAgAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAQIBAwEEAQUBBgAJbXlkcHJpZ2h0CG15ZHBsZWZ0DG15ZHBjYWxlbmRhcgpteWRwcmVtb3ZlAAAAAAABAAH//wAPAAAAAAAAAAAAAAAAAAAAAAAYABgAGAAYA1L/agNS/2qwACwgsABVWEVZICBLuAAOUUuwBlNaWLA0G7AoWWBmIIpVWLACJWG5CAAIAGNjI2IbISGwAFmwAEMjRLIAAQBDYEItsAEssCBgZi2wAiwgZCCwwFCwBCZasigBCkNFY0VSW1ghIyEbilggsFBQWCGwQFkbILA4UFghsDhZWSCxAQpDRWNFYWSwKFBYIbEBCkNFY0UgsDBQWCGwMFkbILDAUFggZiCKimEgsApQWGAbILAgUFghsApgGyCwNlBYIbA2YBtgWVlZG7ABK1lZI7AAUFhlWVktsAMsIEUgsAQlYWQgsAVDUFiwBSNCsAYjQhshIVmwAWAtsAQsIyEjISBksQViQiCwBiNCsQEKQ0VjsQEKQ7ABYEVjsAMqISCwBkMgiiCKsAErsTAFJbAEJlFYYFAbYVJZWCNZISCwQFNYsAErGyGwQFkjsABQWGVZLbAFLLAHQyuyAAIAQ2BCLbAGLLAHI0IjILAAI0JhsAJiZrABY7ABYLAFKi2wBywgIEUgsAtDY7gEAGIgsABQWLBAYFlmsAFjYESwAWAtsAgssgcLAENFQiohsgABAENgQi2wCSywAEMjRLIAAQBDYEItsAosICBFILABKyOwAEOwBCVgIEWKI2EgZCCwIFBYIbAAG7AwUFiwIBuwQFlZI7AAUFhlWbADJSNhRESwAWAtsAssICBFILABKyOwAEOwBCVgIEWKI2EgZLAkUFiwABuwQFkjsABQWGVZsAMlI2FERLABYC2wDCwgsAAjQrILCgNFWCEbIyFZKiEtsA0ssQICRbBkYUQtsA4ssAFgICCwDENKsABQWCCwDCNCWbANQ0qwAFJYILANI0JZLbAPLCCwEGJmsAFjILgEAGOKI2GwDkNgIIpgILAOI0IjLbAQLEtUWLEEZERZJLANZSN4LbARLEtRWEtTWLEEZERZGyFZJLATZSN4LbASLLEAD0NVWLEPD0OwAWFCsA8rWbAAQ7ACJUKxDAIlQrENAiVCsAEWIyCwAyVQWLEBAENgsAQlQoqKIIojYbAOKiEjsAFhIIojYbAOKiEbsQEAQ2CwAiVCsAIlYbAOKiFZsAxDR7ANQ0dgsAJiILAAUFiwQGBZZrABYyCwC0NjuAQAYiCwAFBYsEBgWWawAWNgsQAAEyNEsAFDsAA+sgEBAUNgQi2wEywAsQACRVRYsA8jQiBFsAsjQrAKI7ABYEIgYLABYbUQEAEADgBCQopgsRIGK7ByKxsiWS2wFCyxABMrLbAVLLEBEystsBYssQITKy2wFyyxAxMrLbAYLLEEEystsBkssQUTKy2wGiyxBhMrLbAbLLEHEystsBwssQgTKy2wHSyxCRMrLbAeLACwDSuxAAJFVFiwDyNCIEWwCyNCsAojsAFgQiBgsAFhtRAQAQAOAEJCimCxEgYrsHIrGyJZLbAfLLEAHistsCAssQEeKy2wISyxAh4rLbAiLLEDHistsCMssQQeKy2wJCyxBR4rLbAlLLEGHistsCYssQceKy2wJyyxCB4rLbAoLLEJHistsCksIDywAWAtsCosIGCwEGAgQyOwAWBDsAIlYbABYLApKiEtsCsssCorsCoqLbAsLCAgRyAgsAtDY7gEAGIgsABQWLBAYFlmsAFjYCNhOCMgilVYIEcgILALQ2O4BABiILAAUFiwQGBZZrABY2AjYTgbIVktsC0sALEAAkVUWLABFrAsKrABFTAbIlktsC4sALANK7EAAkVUWLABFrAsKrABFTAbIlktsC8sIDWwAWAtsDAsALABRWO4BABiILAAUFiwQGBZZrABY7ABK7ALQ2O4BABiILAAUFiwQGBZZrABY7ABK7AAFrQAAAAAAEQ+IzixLwEVKi2wMSwgPCBHILALQ2O4BABiILAAUFiwQGBZZrABY2CwAENhOC2wMiwuFzwtsDMsIDwgRyCwC0NjuAQAYiCwAFBYsEBgWWawAWNgsABDYbABQ2M4LbA0LLECABYlIC4gR7AAI0KwAiVJiopHI0cjYSBYYhshWbABI0KyMwEBFRQqLbA1LLAAFrAEJbAEJUcjRyNhsAlDK2WKLiMgIDyKOC2wNiywABawBCWwBCUgLkcjRyNhILAEI0KwCUMrILBgUFggsEBRWLMCIAMgG7MCJgMaWUJCIyCwCEMgiiNHI0cjYSNGYLAEQ7ACYiCwAFBYsEBgWWawAWNgILABKyCKimEgsAJDYGQjsANDYWRQWLACQ2EbsANDYFmwAyWwAmIgsABQWLBAYFlmsAFjYSMgILAEJiNGYTgbI7AIQ0awAiWwCENHI0cjYWAgsARDsAJiILAAUFiwQGBZZrABY2AjILABKyOwBENgsAErsAUlYbAFJbACYiCwAFBYsEBgWWawAWOwBCZhILAEJWBkI7ADJWBkUFghGyMhWSMgILAEJiNGYThZLbA3LLAAFiAgILAFJiAuRyNHI2EjPDgtsDgssAAWILAII0IgICBGI0ewASsjYTgtsDkssAAWsAMlsAIlRyNHI2GwAFRYLiA8IyEbsAIlsAIlRyNHI2EgsAUlsAQlRyNHI2GwBiWwBSVJsAIlYbkIAAgAY2MjIFhiGyFZY7gEAGIgsABQWLBAYFlmsAFjYCMuIyAgPIo4IyFZLbA6LLAAFiCwCEMgLkcjRyNhIGCwIGBmsAJiILAAUFiwQGBZZrABYyMgIDyKOC2wOywjIC5GsAIlRlJYIDxZLrErARQrLbA8LCMgLkawAiVGUFggPFkusSsBFCstsD0sIyAuRrACJUZSWCA8WSMgLkawAiVGUFggPFkusSsBFCstsD4ssDUrIyAuRrACJUZSWCA8WS6xKwEUKy2wPyywNiuKICA8sAQjQoo4IyAuRrACJUZSWCA8WS6xKwEUK7AEQy6wKystsEAssAAWsAQlsAQmIC5HI0cjYbAJQysjIDwgLiM4sSsBFCstsEEssQgEJUKwABawBCWwBCUgLkcjRyNhILAEI0KwCUMrILBgUFggsEBRWLMCIAMgG7MCJgMaWUJCIyBHsARDsAJiILAAUFiwQGBZZrABY2AgsAErIIqKYSCwAkNgZCOwA0NhZFBYsAJDYRuwA0NgWbADJbACYiCwAFBYsEBgWWawAWNhsAIlRmE4IyA8IzgbISAgRiNHsAErI2E4IVmxKwEUKy2wQiywNSsusSsBFCstsEMssDYrISMgIDywBCNCIzixKwEUK7AEQy6wKystsEQssAAVIEewACNCsgABARUUEy6wMSotsEUssAAVIEewACNCsgABARUUEy6wMSotsEYssQABFBOwMiotsEcssDQqLbBILLAAFkUjIC4gRoojYTixKwEUKy2wSSywCCNCsEgrLbBKLLIAAEErLbBLLLIAAUErLbBMLLIBAEErLbBNLLIBAUErLbBOLLIAAEIrLbBPLLIAAUIrLbBQLLIBAEIrLbBRLLIBAUIrLbBSLLIAAD4rLbBTLLIAAT4rLbBULLIBAD4rLbBVLLIBAT4rLbBWLLIAAEArLbBXLLIAAUArLbBYLLIBAEArLbBZLLIBAUArLbBaLLIAAEMrLbBbLLIAAUMrLbBcLLIBAEMrLbBdLLIBAUMrLbBeLLIAAD8rLbBfLLIAAT8rLbBgLLIBAD8rLbBhLLIBAT8rLbBiLLA3Ky6xKwEUKy2wYyywNyuwOystsGQssDcrsDwrLbBlLLAAFrA3K7A9Ky2wZiywOCsusSsBFCstsGcssDgrsDsrLbBoLLA4K7A8Ky2waSywOCuwPSstsGossDkrLrErARQrLbBrLLA5K7A7Ky2wbCywOSuwPCstsG0ssDkrsD0rLbBuLLA6Ky6xKwEUKy2wbyywOiuwOystsHAssDorsDwrLbBxLLA6K7A9Ky2wciyzCQQCA0VYIRsjIVlCK7AIZbADJFB4sAEVMC0AS7gAyFJYsQEBjlmwAbkIAAgAY3CxAAVCsgABACqxAAVCswoCAQgqsQAFQrMOAAEIKrEABkK6AsAAAQAJKrEAB0K6AEAAAQAJKrEDAESxJAGIUViwQIhYsQNkRLEmAYhRWLoIgAABBECIY1RYsQMARFlZWVmzDAIBDCq4Af+FsASNsQIARAAA') format('truetype'); + font-weight: normal; + font-style: normal; +} + +.mydp .mydpicon { + font-family: 'mydatepicker'; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.mydp .icon-mydpright:before { + content: "\e800"; +} + +.mydp .icon-mydpleft:before { + content: "\e801"; +} + +.mydp .icon-mydpcalendar:before { + content: "\e802"; +} + +.mydp .icon-mydpremove:before { + content: "\e805"; +} diff --git a/portal-4cli/src/app/utils/my-date-picker/my-date-picker.component.html b/portal-4cli/src/app/utils/my-date-picker/my-date-picker.component.html new file mode 100644 index 00000000..9b7280e0 --- /dev/null +++ b/portal-4cli/src/app/utils/my-date-picker/my-date-picker.component.html @@ -0,0 +1,61 @@ +
    +
    + +
    + + +
    +
    +
    + + + + + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    +
    + + + + + + + + +
    #{{d}}
    {{w.weekNbr}} +
    + {{d.dateObj.day}} +
    +
    +
    +
    diff --git a/portal-4cli/src/app/utils/my-date-picker/my-date-picker.component.spec.ts b/portal-4cli/src/app/utils/my-date-picker/my-date-picker.component.spec.ts new file mode 100644 index 00000000..83801d58 --- /dev/null +++ b/portal-4cli/src/app/utils/my-date-picker/my-date-picker.component.spec.ts @@ -0,0 +1,2209 @@ +// // +// +// import {ComponentFixture, TestBed} from '@angular/core/testing'; +// import {By} from '@angular/platform-browser'; +// import {DebugElement} from '@angular/core'; +// import {MyDatePicker} from './my-date-picker.component'; +// import {FocusDirective} from './directives/my-date-picker.focus.directive'; +// import {InputAutoFillDirective} from './directives/my-date-picker.input.auto.fill.directive'; +// +// let comp: MyDatePicker; +// let fixture: ComponentFixture; +// let de: DebugElement; +// let el: HTMLElement; +// +// let PREVMONTH: string = '.header tr td:first-child div .headerbtncell:first-child .headerbtn'; +// let NEXTMONTH: string = '.header tr td:first-child div .headerbtncell:last-child .headerbtn'; +// let PREVYEAR: string = '.header tr td:last-child div .headerbtncell:first-child .headerbtn'; +// let NEXTYEAR: string = '.header tr td:last-child div .headerbtncell:last-child .headerbtn'; +// +// function getDateString(date:any):string { +// return date.getFullYear() + '-' + ((date.getMonth() + 1) < 10 ? '0' + (date.getMonth() + 1) : (date.getMonth() + 1)) + '-' + (date.getDate() < 10 ? '0' + date.getDate() : date.getDate()); +// } +// +// function getElement(id:string):DebugElement { +// return de.query(By.css(id)); +// } +// +// function getElements(id:string):Array { +// return de.queryAll(By.css(id)); +// } +// +// describe('MyDatePicker', () => { +// beforeEach(() => { +// TestBed.configureTestingModule({ +// declarations: [MyDatePicker, FocusDirective, InputAutoFillDirective], +// }); +// +// fixture = TestBed.createComponent(MyDatePicker); +// +// comp = fixture.componentInstance; +// +// de = fixture.debugElement.query(By.css('.mydp')); +// el = de.nativeElement; +// }); +// +// it('set valid date', () => { +// comp.selectionDayTxt = '2016-08-22'; +// fixture.detectChanges(); +// let selection = getElement('.selection'); +// expect(selection.nativeElement.value).toContain('2016-08-22'); +// }); +// +// it('open/close selector', () => { +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// let selector = getElement('.selector'); +// expect(selector).toBe(null); +// +// btnpicker.nativeElement.click(); +// fixture.detectChanges(); +// selector = getElement('.selector'); +// expect(selector).not.toBe(null); +// +// btnpicker.nativeElement.click(); +// fixture.detectChanges(); +// selector = getElement('.selector'); +// expect(selector).toBe(null); +// }); +// +// it('select current day from the selector and clear', () => { +// let date = new Date(); +// comp.selectedMonth = {monthTxt: '', monthNbr: date.getMonth() + 1, year: date.getFullYear()}; +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let currday = getElement('.currday'); +// expect(currday).not.toBe(null); +// +// currday.nativeElement.click(); +// +// let dateStr = getDateString(date); +// fixture.detectChanges(); +// let selection = getElement('.selection'); +// expect(selection.nativeElement.value).toContain(dateStr); +// +// fixture.detectChanges(); +// let btnclear = getElement('.btnclear'); +// btnclear.nativeElement.click(); +// expect(selection.nativeElement.value).toContain(''); +// }); +// +// it('select/unselect current day from the selector', () => { +// let date = new Date(); +// comp.selectedMonth = {monthTxt: '', monthNbr: date.getMonth() + 1, year: date.getFullYear()}; +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let currday = getElement('.currday'); +// expect(currday).not.toBe(null); +// +// currday.nativeElement.click(); +// +// let dateStr = getDateString(date); +// fixture.detectChanges(); +// let selection = getElement('.selection'); +// expect(selection.nativeElement.value).toContain(dateStr); +// +// fixture.detectChanges(); +// btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// +// fixture.detectChanges(); +// let selectedday = getElement('.selectedday'); +// expect(selectedday).not.toBe(null); +// +// fixture.detectChanges(); +// currday = getElement('.currday'); +// expect(currday).not.toBe(null); +// currday.nativeElement.click(); +// +// fixture.detectChanges(); +// selectedday = getElement('.selectedday'); +// expect(selectedday).toBe(null); +// +// fixture.detectChanges(); +// selection = getElement('.selection'); +// expect(selection.nativeElement.value).toBe(''); +// }); +// +// it('select today button', () => { +// let date = new Date(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let today = getElement('.headertodaybtn'); +// expect(today).not.toBe(null); +// +// today.nativeElement.click(); +// +// let dateStr = getDateString(date); +// fixture.detectChanges(); +// let selection = getElement('.selection'); +// expect(selection.nativeElement.value).toContain(dateStr); +// +// fixture.detectChanges(); +// let btnclear = getElement('.btnclear'); +// btnclear.nativeElement.click(); +// expect(selection.nativeElement.value).toContain(''); +// }); +// +// it('select previous month', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 5, year: 2016}; +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let prevmonth = getElement('.header tr td:first-child .headerbtn:first-child'); +// expect(prevmonth).not.toBe(null); +// +// prevmonth.nativeElement.click(); +// +// expect(comp.visibleMonth.monthTxt).toBe('Apr'); +// expect(comp.visibleMonth.monthNbr).toBe(4); +// expect(comp.visibleMonth.year).toBe(2016); +// }); +// +// it('select next month', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 5, year: 2016}; +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let nextmonth = getElement(NEXTMONTH); +// expect(nextmonth).not.toBe(null); +// +// nextmonth.nativeElement.click(); +// +// expect(comp.visibleMonth.monthTxt).toBe('Jun'); +// expect(comp.visibleMonth.monthNbr).toBe(6); +// expect(comp.visibleMonth.year).toBe(2016); +// }); +// +// it('select previous month january change year', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 1, year: 2016}; +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let prevmonth = getElement(PREVMONTH); +// expect(prevmonth).not.toBe(null); +// +// prevmonth.nativeElement.click(); +// +// expect(comp.visibleMonth.year).toBe(2015); +// }); +// +// it('select next month december change year', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 12, year: 2016}; +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let nextmonth = getElement(NEXTMONTH); +// expect(nextmonth).not.toBe(null); +// +// nextmonth.nativeElement.click(); +// +// expect(comp.visibleMonth.year).toBe(2017); +// }); +// +// it('select previous month from selector', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 5, year: 2016}; +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let prevmonth = getElement(PREVMONTH); +// expect(prevmonth).not.toBe(null); +// +// prevmonth.nativeElement.click(); +// expect(comp.visibleMonth.monthNbr).toBe(4); +// expect(comp.visibleMonth.monthTxt).toBe('Apr'); +// +// prevmonth.nativeElement.click(); +// expect(comp.visibleMonth.monthNbr).toBe(3); +// expect(comp.visibleMonth.monthTxt).toBe('Mar'); +// }); +// +// it('select next month from selector', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 5, year: 2016}; +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let nextmonth = getElement(NEXTMONTH); +// expect(nextmonth).not.toBe(null); +// +// nextmonth.nativeElement.click(); +// expect(comp.visibleMonth.monthNbr).toBe(6); +// expect(comp.visibleMonth.monthTxt).toBe('Jun'); +// +// nextmonth.nativeElement.click(); +// expect(comp.visibleMonth.monthNbr).toBe(7); +// expect(comp.visibleMonth.monthTxt).toBe('Jul'); +// }); +// +// it('select previous year', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 5, year: 2016}; +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let prevyear = getElement(PREVYEAR); +// expect(prevyear).not.toBe(null); +// +// prevyear.nativeElement.click(); +// fixture.detectChanges(); +// let yearLabel = getElement('.headeryeartxt .headerlabelbtn'); +// expect(yearLabel).not.toBe(null); +// expect(yearLabel.nativeElement.textContent).toBe('2015'); +// }); +// +// it('select next year', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 5, year: 2016}; +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let nextyear = getElement(NEXTYEAR); +// expect(nextyear).not.toBe(null); +// +// nextyear.nativeElement.click(); +// +// fixture.detectChanges(); +// let yearLabel = getElement('.headeryeartxt .headerlabelbtn'); +// expect(yearLabel).not.toBe(null); +// expect(yearLabel.nativeElement.textContent).toBe('2017'); +// }); +// +// it('test calendar year 2016 month one by one - next month button', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 1, year: 2016}; +// +// comp.options = {firstDayOfWeek: 'mo'}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let monthlabel = getElement('.monthlabel'); +// expect(monthlabel).not.toBe(null); +// expect(monthlabel.nativeElement.textContent.trim()).toBe('Jan'); +// +// fixture.detectChanges(); +// let yearlabel = getElement('.yearlabel'); +// expect(yearlabel).not.toBe(null); +// expect(yearlabel.nativeElement.textContent.trim()).toBe('2016'); +// +// comp.generateCalendar(1, 2016, true); +// +// let beginDate: Array = ['28', '1', '29', '28', '25', '30', '27', '1', '29', '26', '31', '28']; +// let endDate: Array = ['7', '13', '10', '8', '5', '10', '7', '11', '9', '6', '11', '8']; +// +// let i: number = 0; +// do { +// fixture.detectChanges(); +// let currmonth = getElements('.caltable tbody tr td'); +// expect(currmonth).not.toBe(null); +// expect(currmonth.length).toBe(42); +// +// expect(currmonth[0]).not.toBe(null); +// expect(currmonth[0].nativeElement.textContent.trim()).toBe(beginDate[i]); +// +// expect(currmonth[41]).not.toBe(null); +// expect(currmonth[41].nativeElement.textContent.trim()).toBe(endDate[i]); +// +// comp.nextMonth(); +// +// i++; +// } while (i < 12) +// }); +// +// it('test calendar year 2016 month one by one - previous month button', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 12, year: 2016}; +// +// comp.options = {firstDayOfWeek: 'mo'}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let monthlabel = getElement('.monthlabel'); +// expect(monthlabel).not.toBe(null); +// expect(monthlabel.nativeElement.textContent.trim()).toBe('Dec'); +// +// fixture.detectChanges(); +// let yearlabel = getElement('.yearlabel'); +// expect(yearlabel).not.toBe(null); +// expect(yearlabel.nativeElement.textContent.trim()).toBe('2016'); +// +// comp.generateCalendar(12, 2016, true); +// +// let beginDate: Array = ['28', '1', '29', '28', '25', '30', '27', '1', '29', '26', '31', '28']; +// let endDate: Array = ['7', '13', '10', '8', '5', '10', '7', '11', '9', '6', '11', '8']; +// +// let i: number = 11; +// do { +// fixture.detectChanges(); +// let currmonth = getElements('.caltable tbody tr td'); +// expect(currmonth).not.toBe(null); +// expect(currmonth.length).toBe(42); +// +// expect(currmonth[0]).not.toBe(null); +// expect(currmonth[0].nativeElement.textContent.trim()).toBe(beginDate[i]); +// +// expect(currmonth[41]).not.toBe(null); +// expect(currmonth[41].nativeElement.textContent.trim()).toBe(endDate[i]); +// +// comp.prevMonth(); +// +// i--; +// } while (i >= 0) +// }); +// +// // options +// it('options - dayLabels', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 5, year: 2016}; +// comp.options = {dayLabels: {su: '1', mo: '2', tu: '3', we: '4', th: '5', fr: '6', sa: '7'}, firstDayOfWeek: 'su'}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let ths = getElements('.caltable thead tr th'); +// expect(ths.length).toBe(7); +// for(let i in ths) { +// let el = ths[i]; +// expect(parseInt(el.nativeElement.textContent)).toBe(parseInt(i) + 1); +// } +// }); +// +// it('options - monthLabels', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 1, year: 2016}; +// comp.options = {monthLabels: { 1: '1', 2: '2', 3: '3', 4: '4', 5: '5', 6: '6', 7: '7', 8: '8', 9: '9', 10: '10', 11: '11', 12: '12' }}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let nextmonth = getElement(NEXTMONTH); +// expect(nextmonth).not.toBe(null); +// +// for(let i = 1; i <= 12; i++) { +// fixture.detectChanges(); +// let monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(parseInt(monthLabel.nativeElement.textContent)).toBe(i); +// nextmonth.nativeElement.click(); +// } +// }); +// +// it('options - date format', () => { +// comp.options = {dateFormat: 'dd.mm.yyyy', indicateInvalidDate: true}; +// +// comp.parseOptions(); +// +// let value = {target:{value:'2016-08-22'}}; +// comp.userDateInput(value); +// expect(comp.invalidDate).toBe(true); +// +// fixture.detectChanges(); +// let invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// value = {target:{value:'2016-08-2'}}; +// comp.userDateInput(value); +// expect(comp.invalidDate).toBe(true); +// +// value = {target:{value:'16.09/2016'}}; +// comp.userDateInput(value); +// expect(comp.invalidDate).toBe(true); +// +// value = {target:{value:'2016-08-xx'}}; +// comp.userDateInput(value); +// expect(comp.invalidDate).toBe(true); +// +// value = {target:{value:'16.09.999'}}; +// comp.userDateInput(value); +// expect(comp.invalidDate).toBe(true); +// +// value = {target:{value:'16.09.19999'}}; +// comp.userDateInput(value); +// expect(comp.invalidDate).toBe(true); +// +// value = {target:{value:'16.09.2016'}}; +// comp.userDateInput(value); +// expect(comp.invalidDate).toBe(false); +// +// comp.options = {dateFormat: 'dd mmm yyyy', indicateInvalidDate: true}; +// +// comp.parseOptions(); +// +// value = {target:{value:'2016-08-22'}}; +// comp.userDateInput(value); +// expect(comp.invalidDate).toBe(true); +// +// value = {target:{value:'22 Aug 2016'}}; +// comp.userDateInput(value); +// expect(comp.invalidDate).toBe(false); +// }); +// +// it('options - show today button', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 1, year: 2016}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let headertodaybtn = getElement('.headertodaybtn'); +// expect(headertodaybtn).not.toBe(null); +// +// btnpicker.nativeElement.click(); +// +// comp.options = {showTodayBtn: false}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// headertodaybtn = getElement('.headertodaybtn'); +// expect(headertodaybtn).toBe(null); +// +// btnpicker.nativeElement.click(); +// +// comp.options = {showTodayBtn: true}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// headertodaybtn = getElement('.headertodaybtn'); +// expect(headertodaybtn).not.toBe(null); +// }); +// +// it('options - today button text', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 1, year: 2016}; +// comp.options = {todayBtnTxt: 'test text'}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let headertodaybtn = getElement('.headertodaybtn'); +// expect(headertodaybtn).not.toBe(null); +// expect(headertodaybtn.nativeElement.textContent).toBe('test text'); +// }); +// +// it('options - first day of week', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 5, year: 2016}; +// comp.options = {firstDayOfWeek: 'tu'}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let first = getElement('.caltable thead tr th:first-child'); +// expect(first).not.toBe(null); +// expect(first.nativeElement.textContent).toBe('Tue'); +// +// let last = getElement('.caltable thead tr th:last-child'); +// expect(last).not.toBe(null); +// expect(last.nativeElement.textContent).toBe('Mon'); +// }); +// +// it('options - sunday highlight', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 5, year: 2016}; +// comp.options = {sunHighlight: true}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let sunday = getElement('.sunday'); +// expect(sunday).not.toBe(null); +// +// btnpicker.nativeElement.click(); +// +// comp.options = {sunHighlight: false}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// btnpicker.nativeElement.click(); +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// sunday = getElement('.sunday'); +// expect(sunday).toBe(null); +// }); +// +// it('options - current day marked', () => { +// comp.options = {markCurrentDay: true}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let currday = getElement('.currday'); +// expect(currday).not.toBe(null); +// +// btnpicker.nativeElement.click(); +// +// comp.options = {markCurrentDay: false}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// btnpicker.nativeElement.click(); +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// currday = getElement('.currday'); +// expect(currday).toBe(null); +// }); +// +// it('options - editable month and year', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 5, year: 2016}; +// comp.options = {editableMonthAndYear: true}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let montlabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(montlabel).not.toBe(null); +// montlabel.nativeElement.click(); +// +// fixture.detectChanges(); +// let monthinput = getElement('.monthinput'); +// expect(monthinput).not.toBe(null); +// +// comp.userMonthInput({target:{value:'jan'}}); +// +// fixture.detectChanges(); +// montlabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(montlabel).not.toBe(null); +// expect(montlabel.nativeElement.textContent).toBe('Jan'); +// +// +// fixture.detectChanges(); +// let yearlabel = getElement('.headeryeartxt .headerlabelbtn'); +// expect(yearlabel).not.toBe(null); +// yearlabel.nativeElement.click(); +// +// fixture.detectChanges(); +// let yearinput = getElement('.yearinput'); +// expect(yearinput).not.toBe(null); +// +// comp.userYearInput({target:{value:'2019'}}); +// +// fixture.detectChanges(); +// yearlabel = getElement('.headeryeartxt .headerlabelbtn'); +// expect(yearlabel).not.toBe(null); +// expect(yearlabel.nativeElement.textContent).toBe('2019'); +// }); +// +// it('options - disable header buttons', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 5, year: 2016}; +// comp.options = { +// disableHeaderButtons: true, +// disableUntil: {year: 2016, month: 4, day: 10} +// }; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let montlabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(montlabel).not.toBe(null); +// expect(montlabel.nativeElement.textContent).toBe('May'); +// +// fixture.detectChanges(); +// let prevmonth = getElement(PREVMONTH); +// expect(prevmonth).not.toBe(null); +// prevmonth.nativeElement.click(); +// +// fixture.detectChanges(); +// montlabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(montlabel).not.toBe(null); +// expect(montlabel.nativeElement.textContent).toBe('Apr'); +// +// fixture.detectChanges(); +// let headerbtndisabled = getElements('.headerbtndisabled'); +// expect(headerbtndisabled).not.toBe(null); +// expect(headerbtndisabled.length).toBe(2); +// +// prevmonth.nativeElement.click(); +// +// fixture.detectChanges(); +// montlabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(montlabel).not.toBe(null); +// expect(montlabel.nativeElement.textContent).toBe('Apr'); +// +// fixture.detectChanges(); +// let prevyear = getElement(PREVYEAR); +// expect(prevyear).not.toBe(null); +// prevyear.nativeElement.click(); +// +// fixture.detectChanges(); +// let yearlabel = getElement('.headeryeartxt .headerlabelbtn'); +// expect(yearlabel).not.toBe(null); +// expect(yearlabel.nativeElement.textContent).toBe('2016'); +// +// btnpicker.nativeElement.click(); +// +// +// comp.options = { +// disableHeaderButtons: true, +// disableSince: {year: 2016, month: 7, day: 10} +// }; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// montlabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(montlabel).not.toBe(null); +// expect(montlabel.nativeElement.textContent).toBe('May'); +// +// fixture.detectChanges(); +// let nextmonth = getElement(NEXTMONTH); +// expect(nextmonth).not.toBe(null); +// nextmonth.nativeElement.click(); +// +// fixture.detectChanges(); +// montlabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(montlabel).not.toBe(null); +// expect(montlabel.nativeElement.textContent).toBe('Jun'); +// +// fixture.detectChanges(); +// headerbtndisabled = getElements('.headerbtndisabled'); +// expect(headerbtndisabled).not.toBe(null); +// expect(headerbtndisabled.length).toBe(2); +// +// prevmonth.nativeElement.click(); +// +// fixture.detectChanges(); +// montlabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(montlabel).not.toBe(null); +// expect(montlabel.nativeElement.textContent).toBe('Jun'); +// +// fixture.detectChanges(); +// let nextyear = getElement(NEXTYEAR); +// expect(nextyear).not.toBe(null); +// nextyear.nativeElement.click(); +// +// fixture.detectChanges(); +// yearlabel = getElement('.headeryeartxt .headerlabelbtn'); +// expect(yearlabel).not.toBe(null); +// expect(yearlabel.nativeElement.textContent).toBe('2016'); +// }); +// +// it('options - min year', () => { +// comp.visibleMonth = {monthTxt: 'May', monthNbr: 5, year: 2016}; +// comp.options = {minYear: 2000}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let yearlabel = getElement('.headeryeartxt .headerlabelbtn'); +// expect(yearlabel).not.toBe(null); +// yearlabel.nativeElement.click(); +// +// fixture.detectChanges(); +// let yearinput = getElement('.yearinput'); +// expect(yearinput).not.toBe(null); +// +// comp.userYearInput({target:{value:1999}}); +// +// fixture.detectChanges(); +// let invalidyear = getElement('.invalidyear'); +// expect(invalidyear).not.toBe(null); +// +// comp.userYearInput({target:{value:2000}}); +// +// fixture.detectChanges(); +// yearlabel = getElement('.headeryeartxt .headerlabelbtn'); +// expect(yearlabel).not.toBe(null); +// expect(yearlabel.nativeElement.textContent).toBe('2000'); +// }); +// +// it('options - max year', () => { +// comp.visibleMonth = {monthTxt: 'May', monthNbr: 5, year: 2016}; +// comp.options = {maxYear: 2020}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let yearlabel = getElement('.headeryeartxt .headerlabelbtn'); +// expect(yearlabel).not.toBe(null); +// yearlabel.nativeElement.click(); +// +// fixture.detectChanges(); +// let yearinput = getElement('.yearinput'); +// expect(yearinput).not.toBe(null); +// +// comp.userYearInput({target:{value:2021}}); +// +// fixture.detectChanges(); +// let invalidyear = getElement('.invalidyear'); +// expect(invalidyear).not.toBe(null); +// +// comp.userYearInput({target:{value:2020}}); +// +// fixture.detectChanges(); +// yearlabel = getElement('.headeryeartxt .headerlabelbtn'); +// expect(yearlabel).not.toBe(null); +// expect(yearlabel.nativeElement.textContent).toBe('2020'); +// }); +// +// it('options - disable until', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {disableUntil: {year: 2016, month: 10, day: 5}}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// comp.generateCalendar(10, 2016, true); +// +// fixture.detectChanges(); +// let disabled = getElements('tr .disabled'); +// expect(disabled).not.toBe(null); +// expect(disabled.length).toBe(10); +// +// let firstDisabled = disabled[0]; +// expect(firstDisabled.nativeElement.textContent.trim()).toBe('26'); +// +// let lastDisabled = disabled[disabled.length - 1]; +// expect(lastDisabled.nativeElement.textContent.trim()).toBe('5'); +// +// fixture.detectChanges(); +// lastDisabled.nativeElement.click(); +// let selection = getElement('.selection'); +// expect(selection.nativeElement.value).toBe(''); +// +// fixture.detectChanges(); +// let selectableDays = getElements('.tablesingleday'); +// expect(selectableDays).not.toBe(null); +// expect(selectableDays.length).toBe(26); +// +// selectableDays[0].nativeElement.click(); +// fixture.detectChanges(); +// selection = getElement('.selection'); +// expect(selection.nativeElement.value).toContain('2016-10-06'); +// }); +// +// it('options - disable since', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {disableSince: {year: 2016, month: 10, day: 30}}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// comp.generateCalendar(10, 2016, true); +// +// fixture.detectChanges(); +// let disabled = getElements('tr .disabled'); +// expect(disabled).not.toBe(null); +// expect(disabled.length).toBe(8); +// +// let firstDisabled = disabled[0]; +// expect(firstDisabled.nativeElement.textContent.trim()).toBe('30'); +// +// let lastDisabled = disabled[disabled.length - 1]; +// expect(lastDisabled.nativeElement.textContent.trim()).toBe('6'); +// +// fixture.detectChanges(); +// lastDisabled.nativeElement.click(); +// let selection = getElement('.selection'); +// expect(selection.nativeElement.value).toBe(''); +// +// fixture.detectChanges(); +// let selectableDays = getElements('.tablesingleday'); +// expect(selectableDays).not.toBe(null); +// expect(selectableDays.length).toBe(29); +// +// selectableDays[5].nativeElement.click(); +// +// fixture.detectChanges(); +// selection = getElement('.selection'); +// expect(selection.nativeElement.value).toContain('2016-10-06'); +// }); +// +// it('options - disable days one by one', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {disableDays: [{year: 2016, month: 10, day: 5}, {year: 2016, month: 10, day: 10}]}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// comp.generateCalendar(10, 2016, true); +// +// fixture.detectChanges(); +// let disabled = getElements('tr .disabled'); +// expect(disabled).not.toBe(null); +// expect(disabled.length).toBe(2); +// +// let firstDisabled = disabled[0]; +// expect(firstDisabled.nativeElement.textContent.trim()).toBe('5'); +// +// let lastDisabled = disabled[1]; +// expect(lastDisabled.nativeElement.textContent.trim()).toBe('10'); +// }); +// +// it('options - enable disabled days one by one', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 1, year: 2017}; +// comp.options = { +// dateFormat: 'dd.mm.yyyy', +// disableDateRange: {begin: {year: 2017, month: 1, day: 1}, end: {year: 2017, month: 1, day: 31}}, +// enableDays: [{year: 2017, month: 1, day: 5}, {year: 2017, month: 1, day: 6}, {year: 2017, month: 1, day: 7}, {year: 2017, month: 1, day: 8}] +// }; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// comp.generateCalendar(1, 2017, true); +// +// fixture.detectChanges(); +// let disabled = getElements('tr .disabled'); +// expect(disabled).not.toBe(null); +// expect(disabled.length).toBe(27); +// +// let firstDisabled = disabled[0]; +// expect(firstDisabled.nativeElement.textContent.trim()).toBe('1'); +// +// let lastDisabled = disabled[disabled.length - 1]; +// expect(lastDisabled.nativeElement.textContent.trim()).toBe('31'); +// +// fixture.detectChanges(); +// let alldates = getElements('.caltable .daycell'); +// expect(alldates).not.toBe(null); +// expect(alldates.length).toBe(42); +// +// fixture.detectChanges(); +// let firstEnabled = alldates[10]; +// firstEnabled.nativeElement.click(); +// +// fixture.detectChanges(); +// let selection = getElement('.selection'); +// expect(selection).not.toBe(null); +// expect(selection.nativeElement.value).toBe('05.01.2017'); +// }); +// +// it('options - disable range', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {disableDateRange: {begin: {year: 2016, month: 10, day: 5}, end: {year: 2016, month: 10, day: 10}}}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// comp.generateCalendar(10, 2016, true); +// +// fixture.detectChanges(); +// let disabled = getElements('tr .disabled'); +// expect(disabled).not.toBe(null); +// expect(disabled.length).toBe(6); +// +// let firstDisabled = disabled[0]; +// expect(firstDisabled.nativeElement.textContent.trim()).toBe('5'); +// +// let lastDisabled = disabled[disabled.length - 1]; +// expect(lastDisabled.nativeElement.textContent.trim()).toBe('10'); +// btnpicker.nativeElement.click(); +// +// +// comp.options = {disableDateRange: {begin: {}, end: {}}}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// comp.generateCalendar(10, 2016, true); +// +// fixture.detectChanges(); +// disabled = getElements('tr .disabled'); +// expect(disabled).not.toBe(null); +// expect(disabled.length).toBe(0); +// }); +// +// it('options - disable today - today button disabled', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// +// let date = new Date(); +// comp.options = {disableDays: [{year: date.getFullYear(), month: date.getMonth() + 1, day: date.getDate()}]}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// comp.generateCalendar(10, 2016, true); +// +// fixture.detectChanges(); +// let headertodaybtn = getElement('.headertodaybtn'); +// expect(headertodaybtn).not.toBe(null); +// expect(headertodaybtn.properties['disabled']).toBe(true); +// +// fixture.detectChanges(); +// headertodaybtn.nativeElement.click(); +// let selector = getElement('.selector'); +// expect(selector).not.toBe(null); +// +// btnpicker.nativeElement.click(); +// +// comp.options = {disableDays: []}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// btnpicker.nativeElement.click(); +// comp.generateCalendar(10, 2016, true); +// +// fixture.detectChanges(); +// headertodaybtn = getElement('.headertodaybtn'); +// expect(headertodaybtn).not.toBe(null); +// expect(headertodaybtn.properties['disabled']).toBe(false); +// +// headertodaybtn.nativeElement.click(); +// +// fixture.detectChanges(); +// let selection = getElement('.selection'); +// expect(selection).not.toBe(null); +// expect(selection.nativeElement.value).toBe(getDateString(date)); +// }); +// +// it('options - disable weekends', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {firstDayOfWeek: 'mo', disableWeekends: true}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// comp.generateCalendar(10, 2016, true); +// +// fixture.detectChanges(); +// let disabled = getElements('tr .disabled'); +// expect(disabled).not.toBe(null); +// expect(disabled.length).toBe(12); +// +// let firstDisabled = disabled[0]; +// expect(firstDisabled.nativeElement.textContent.trim()).toBe('1'); +// +// let secondDisabled = disabled[1]; +// expect(secondDisabled.nativeElement.textContent.trim()).toBe('2'); +// +// let lastDisabled = disabled[disabled.length - 1]; +// expect(lastDisabled.nativeElement.textContent.trim()).toBe('6'); +// +// fixture.detectChanges(); +// firstDisabled.nativeElement.click(); +// let selection = getElement('.selection'); +// expect(selection.nativeElement.value).toBe(''); +// +// fixture.detectChanges(); +// secondDisabled.nativeElement.click(); +// selection = getElement('.selection'); +// expect(selection.nativeElement.value).toBe(''); +// +// fixture.detectChanges(); +// let selectableDays = getElements('.tablesingleday'); +// expect(selectableDays).not.toBe(null); +// expect(selectableDays.length).toBe(21); +// +// selectableDays[0].nativeElement.click(); +// +// fixture.detectChanges(); +// selection = getElement('.selection'); +// expect(selection.nativeElement.value).toContain('2016-10-03'); +// }); +// +// it('options - inline', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {inline: true}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let selector = getElement('.selector'); +// expect(selector).not.toBe(null); +// +// fixture.detectChanges(); +// let selectiongroup = getElement('.selectiongroup'); +// expect(selectiongroup).toBe(null); +// }); +// +// it('options - show clear date button', () => { +// let date = new Date(); +// comp.selectedMonth = {monthTxt: '', monthNbr: date.getMonth() + 1, year: date.getFullYear()}; +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let currday = getElement('.currday'); +// expect(currday).not.toBe(null); +// +// currday.nativeElement.click(); +// +// fixture.detectChanges(); +// let btnclear = getElement('.btnclear'); +// expect(btnclear).not.toBe(null); +// +// btnclear.nativeElement.click(); +// +// comp.options = {showClearDateBtn: true}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// currday = getElement('.currday'); +// expect(currday).not.toBe(null); +// +// currday.nativeElement.click(); +// +// fixture.detectChanges(); +// btnclear = getElement('.btnclear'); +// expect(btnclear).not.toBe(null); +// btnclear.nativeElement.click(); +// +// btnclear.nativeElement.click(); +// +// +// comp.options = {showClearDateBtn: false}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// currday = getElement('.currday'); +// expect(currday).not.toBe(null); +// +// currday.nativeElement.click(); +// +// fixture.detectChanges(); +// btnclear = getElement('.btnclear'); +// expect(btnclear).toBe(null); +// }); +// +// it('options - height', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {height: '50px'}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let selection = getElement('.selection'); +// expect(selection).not.toBe(null); +// expect(selection.styles['height']).toBe('50px'); +// }); +// +// it('options - width', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {width: '300px'}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// expect(de).not.toBe(null); +// expect(de.styles['width']).toBe('300px'); +// +// comp.options = {width: '20%'}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// expect(de).not.toBe(null); +// expect(de.styles['width']).toBe('20%'); +// }); +// +// it('options - selection text font size', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {selectionTxtFontSize: '10px'}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let selection = getElement('.selection'); +// expect(selection).not.toBe(null); +// expect(selection.styles['font-size']).toBe('10px'); +// }); +// +// it('options - align selector right', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {alignSelectorRight: true}; +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let alignselectorright = getElement('.alignselectorright'); +// expect(alignselectorright).not.toBe(null); +// +// comp.options = {alignSelectorRight: false}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// alignselectorright = getElement('.alignselectorright'); +// expect(alignselectorright).toBe(null); +// }); +// +// it('options - open selector top of input', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {openSelectorTopOfInput: true, height: '30px'}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// let value: string = comp.getSelectorTopPosition(); +// expect(value).not.toBe(null); +// expect(value).toBe('32px'); +// +// btnpicker.nativeElement.click(); +// +// +// comp.options = {openSelectorTopOfInput: false}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// value = comp.getSelectorTopPosition(); +// expect(value).toBe(undefined); +// +// +// btnpicker.nativeElement.click(); +// +// comp.options = {}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// value = comp.getSelectorTopPosition(); +// expect(value).toBe(undefined); +// }); +// +// it('options - indicate invalid date', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {indicateInvalidDate: true, dateFormat: 'dd.mm.yyyy'}; +// +// comp.parseOptions(); +// +// comp.userDateInput({target:{value:'2016-08-22'}}); +// fixture.detectChanges(); +// let invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'2016-08-xx'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'2016-08-99'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'10.10.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).toBe(null); +// }); +// +// it('options - disableUntil input dates validation', ()=> { +// comp.options = { +// indicateInvalidDate: true, +// dateFormat: 'dd.mm.yyyy', +// disableUntil:{year: 2016, month: 11, day: 4} +// }; +// +// comp.parseOptions(); +// +// comp.userDateInput({target:{value:'11.12.2015'}}); +// fixture.detectChanges(); +// let invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'11.06.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'04.11.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'05.11.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).toBe(null); +// +// comp.options = { +// indicateInvalidDate: true, +// dateFormat: 'dd.mm.yyyy', +// disableUntil:{year: 0, month: 0, day: 0} +// }; +// +// comp.parseOptions(); +// +// comp.userDateInput({target:{value:'11.12.2015'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).toBe(null); +// }); +// +// it('options - disableSince input dates validation', ()=> { +// comp.options = { +// indicateInvalidDate: true, +// dateFormat: 'dd.mm.yyyy', +// disableSince:{year: 2016, month: 11, day: 22} +// }; +// +// comp.parseOptions(); +// +// comp.userDateInput({target:{value:'08.12.2017'}}); +// fixture.detectChanges(); +// let invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'08.12.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'23.11.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'21.11.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).toBe(null); +// +// comp.options = { +// indicateInvalidDate: true, +// dateFormat: 'dd.mm.yyyy', +// disableSince:{year: 0, month: 0, day: 0} +// }; +// +// comp.parseOptions(); +// +// comp.userDateInput({target:{value:'11.12.2015'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).toBe(null); +// }); +// +// it('options - disable weekends input date validation', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 11, year: 2016}; +// comp.options = { +// indicateInvalidDate: true, +// dateFormat: 'dd.mm.yyyy', +// disableWeekends: true, +// firstDayOfWeek: 'mo' +// }; +// +// comp.parseOptions(); +// +// comp.userDateInput({target:{value:'05.11.2016'}}); +// fixture.detectChanges(); +// let invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'06.11.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'12.11.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'13.11.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'19.11.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'20.11.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'26.11.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'27.11.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'04.11.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).toBe(null); +// }); +// +// it('options - disableDays input date validation', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 11, year: 2016}; +// comp.options = { +// indicateInvalidDate: true, +// dateFormat: 'dd.mm.yyyy', +// disableDays: [ +// {year: 2016, month: 11, day: 1}, +// {year: 2016, month: 11, day: 3}, +// {year: 2016, month: 11, day: 5}, +// {year: 2016, month: 11, day: 7} +// ], +// firstDayOfWeek: 'mo' +// }; +// +// comp.parseOptions(); +// +// comp.userDateInput({target:{value:'01.11.2016'}}); +// fixture.detectChanges(); +// let invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'03.11.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'05.11.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'07.11.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'02.11.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).toBe(null); +// }); +// +// it('options - disable component', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {componentDisabled: true}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// +// btnpicker.nativeElement.click(); +// fixture.detectChanges(); +// +// let selector = getElement('.selector'); +// expect(selector).toBe(null); +// +// fixture.detectChanges(); +// let selection = getElement('.selection'); +// +// selection.nativeElement.value = '2016-11-14'; +// +// fixture.detectChanges(); +// expect(selection.nativeElement.value).toContain(''); +// }); +// +// it('options - editable date field', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {editableDateField: false}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let selection = getElement('.selection'); +// +// selection.nativeElement.value = '2016-11-14'; +// +// fixture.detectChanges(); +// expect(selection.nativeElement.value).toContain(''); +// +// comp.options = {editableDateField: true}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// selection = getElement('.selection'); +// +// selection.nativeElement.value = '2016-11-14'; +// +// fixture.detectChanges(); +// expect(selection.nativeElement.value).toContain('2016-11-14'); +// }); +// +// it('options - click input to open selector', () => { +// +// let selection: DebugElement, +// selector: DebugElement; +// +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {editableDateField: true}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// selection = getElement('.selection'); +// +// selection.nativeElement.click(); +// +// fixture.detectChanges(); +// selector = getElement('.selector'); +// expect(selector).toBe(null); +// +// comp.options = {editableDateField: false, openSelectorOnInputClick: true}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// selection = getElement('.selection'); +// +// selection.nativeElement.click(); +// +// fixture.detectChanges(); +// selector = getElement('.selector'); +// expect(selector).not.toBe(null); +// }); +// +// it('options - input field value required', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let selection = getElement('.selection'); +// expect(selection).not.toBe(null); +// expect(selection.properties['required']).toBe(false); +// +// comp.options = {inputValueRequired: true}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// selection = getElement('.selection'); +// expect(selection).not.toBe(null); +// expect(selection.properties['required']).toBe(true); +// +// comp.options = {inputValueRequired: false}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// selection = getElement('.selection'); +// expect(selection).not.toBe(null); +// expect(selection.properties['required']).toBe(false); +// }); +// +// it('options - show selector arrow', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let selectorarrow = getElement('.selectorarrow'); +// expect(selectorarrow).not.toBe(null); +// btnpicker.nativeElement.click(); +// +// +// comp.options = {showSelectorArrow: false}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// selectorarrow = getElement('.selectorarrow'); +// expect(selectorarrow).toBe(null); +// btnpicker.nativeElement.click(); +// +// +// comp.options = {showSelectorArrow: true}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// selectorarrow = getElement('.selectorarrow'); +// expect(selectorarrow).not.toBe(null); +// btnpicker.nativeElement.click(); +// }); +// +// it('options - show input field', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let selection = getElement('.selection'); +// expect(selection).not.toBe(null); +// +// +// comp.options = {showInputField: false}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// selection = getElement('.selection'); +// expect(selection).toBe(null); +// +// +// comp.options = {showInputField: true}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// selection = getElement('.selection'); +// expect(selection).not.toBe(null); +// }); +// +// it('options - input auto fill', () => { +// comp.options = {inputAutoFill: false}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let selection = getElement('.selection'); +// expect(selection).not.toBe(null); +// +// fixture.detectChanges(); +// selection.nativeElement.value = '2016-2-1'; +// fixture.nativeElement.querySelector('.selection').dispatchEvent(new Event('keyup')); +// +// fixture.detectChanges(); +// selection = getElement('.selection'); +// expect(selection.nativeElement.value).toBe('2016-2-1'); +// +// +// comp.options = {inputAutoFill: true}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// selection.nativeElement.value = ''; +// +// fixture.detectChanges(); +// selection.nativeElement.value = '2016-1-'; +// fixture.nativeElement.querySelector('.selection').dispatchEvent(new Event('keyup')); +// +// fixture.detectChanges(); +// selection = getElement('.selection'); +// expect(selection.nativeElement.value).toBe('2016-01-'); +// +// fixture.detectChanges(); +// selection.nativeElement.value = '2016-01-9'; +// fixture.nativeElement.querySelector('.selection').dispatchEvent(new Event('keyup')); +// +// fixture.detectChanges(); +// selection = getElement('.selection'); +// expect(selection.nativeElement.value).toBe('2016-01-09'); +// }); +// +// it('options - show week numbers', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 1, year: 2017}; +// comp.options = {showWeekNumbers: false}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let weekdaytitleweeknbr = getElement('.weekdaytitleweeknbr'); +// expect(weekdaytitleweeknbr).toBe(null); +// +// fixture.detectChanges(); +// let daycellweeknbr = getElements('.daycellweeknbr'); +// expect(daycellweeknbr.length).toBe(0); +// +// btnpicker.nativeElement.click(); +// +// +// comp.options = {showWeekNumbers: true}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// weekdaytitleweeknbr = getElement('.weekdaytitleweeknbr'); +// expect(weekdaytitleweeknbr).not.toBe(null); +// +// fixture.detectChanges(); +// daycellweeknbr = getElements('.daycellweeknbr'); +// expect(daycellweeknbr.length).toBe(6); +// +// expect(daycellweeknbr[0].nativeElement.textContent.trim()).toBe('52'); +// expect(daycellweeknbr[1].nativeElement.textContent.trim()).toBe('1'); +// expect(daycellweeknbr[2].nativeElement.textContent.trim()).toBe('2'); +// expect(daycellweeknbr[3].nativeElement.textContent.trim()).toBe('3'); +// expect(daycellweeknbr[4].nativeElement.textContent.trim()).toBe('4'); +// expect(daycellweeknbr[5].nativeElement.textContent.trim()).toBe('5'); +// +// fixture.detectChanges(); +// let prevyear = getElement(PREVYEAR); +// expect(prevyear).not.toBe(null); +// prevyear.nativeElement.click(); +// +// fixture.detectChanges(); +// daycellweeknbr = getElements('.daycellweeknbr'); +// expect(daycellweeknbr.length).toBe(6); +// +// expect(daycellweeknbr[0].nativeElement.textContent.trim()).toBe('53'); +// expect(daycellweeknbr[1].nativeElement.textContent.trim()).toBe('1'); +// expect(daycellweeknbr[2].nativeElement.textContent.trim()).toBe('2'); +// expect(daycellweeknbr[3].nativeElement.textContent.trim()).toBe('3'); +// expect(daycellweeknbr[4].nativeElement.textContent.trim()).toBe('4'); +// expect(daycellweeknbr[5].nativeElement.textContent.trim()).toBe('5'); +// +// prevyear.nativeElement.click(); +// +// fixture.detectChanges(); +// daycellweeknbr = getElements('.daycellweeknbr'); +// expect(daycellweeknbr.length).toBe(6); +// +// expect(daycellweeknbr[0].nativeElement.textContent.trim()).toBe('1'); +// expect(daycellweeknbr[1].nativeElement.textContent.trim()).toBe('2'); +// expect(daycellweeknbr[2].nativeElement.textContent.trim()).toBe('3'); +// expect(daycellweeknbr[3].nativeElement.textContent.trim()).toBe('4'); +// expect(daycellweeknbr[4].nativeElement.textContent.trim()).toBe('5'); +// expect(daycellweeknbr[5].nativeElement.textContent.trim()).toBe('6'); +// }); +// +// it('options - aria label texts', () => { +// comp.selectedDate = comp.parseSelectedDate('2017-10-11'); +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// expect(btnpicker).not.toBe(null); +// expect(btnpicker.nativeElement.attributes['aria-label'].textContent).toBe('Open Calendar'); +// +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let selection = getElement('.selection'); +// expect(selection).not.toBe(null); +// expect(selection.nativeElement.attributes['aria-label'].textContent).toBe('Date input field'); +// +// fixture.detectChanges(); +// let btnclear = getElement('.btnclear'); +// expect(btnclear).not.toBe(null); +// expect(btnclear.nativeElement.attributes['aria-label'].textContent).toBe('Clear Date'); +// +// +// fixture.detectChanges(); +// let prevmonth = getElement(PREVMONTH); +// expect(prevmonth).not.toBe(null); +// expect(prevmonth.nativeElement.attributes['aria-label'].textContent).toBe('Previous Month'); +// +// fixture.detectChanges(); +// let nextmonth = getElement(NEXTMONTH); +// expect(nextmonth).not.toBe(null); +// expect(nextmonth.nativeElement.attributes['aria-label'].textContent).toBe('Next Month'); +// +// fixture.detectChanges(); +// let prevyear = getElement(PREVYEAR); +// expect(prevyear).not.toBe(null); +// expect(prevyear.nativeElement.attributes['aria-label'].textContent).toBe('Previous Year'); +// +// fixture.detectChanges(); +// let nextyear = getElement(NEXTYEAR); +// expect(nextyear).not.toBe(null); +// expect(nextyear.nativeElement.attributes['aria-label'].textContent).toBe('Next Year'); +// +// btnpicker.nativeElement.click(); +// +// comp.options = { +// ariaLabelInputField: 'text 1', +// ariaLabelClearDate: 'text 2', +// ariaLabelOpenCalendar: 'text 3', +// ariaLabelPrevMonth: 'text 4', +// ariaLabelNextMonth: 'text 5', +// ariaLabelPrevYear: 'text 6', +// ariaLabelNextYear: 'text 7' +// }; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// btnpicker = getElement('.btnpicker'); +// expect(btnpicker).not.toBe(null); +// expect(btnpicker.nativeElement.attributes['aria-label'].textContent).toBe(comp.options.ariaLabelOpenCalendar); +// +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// selection = getElement('.selection'); +// expect(selection).not.toBe(null); +// expect(selection.nativeElement.attributes['aria-label'].textContent).toBe(comp.options.ariaLabelInputField); +// +// fixture.detectChanges(); +// btnclear = getElement('.btnclear'); +// expect(btnclear).not.toBe(null); +// expect(btnclear.nativeElement.attributes['aria-label'].textContent).toBe(comp.options.ariaLabelClearDate); +// +// +// fixture.detectChanges(); +// prevmonth = getElement(PREVMONTH); +// expect(prevmonth).not.toBe(null); +// expect(prevmonth.nativeElement.attributes['aria-label'].textContent).toBe(comp.options.ariaLabelPrevMonth); +// +// fixture.detectChanges(); +// nextmonth = getElement(NEXTMONTH); +// expect(nextmonth).not.toBe(null); +// expect(nextmonth.nativeElement.attributes['aria-label'].textContent).toBe(comp.options.ariaLabelNextMonth); +// +// fixture.detectChanges(); +// prevyear = getElement(PREVYEAR); +// expect(prevyear).not.toBe(null); +// expect(prevyear.nativeElement.attributes['aria-label'].textContent).toBe(comp.options.ariaLabelPrevYear); +// +// fixture.detectChanges(); +// nextyear = getElement(NEXTYEAR); +// expect(nextyear).not.toBe(null); +// expect(nextyear.nativeElement.attributes['aria-label'].textContent).toBe(comp.options.ariaLabelNextYear); +// }); +// +// it('locale - use fr locale', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 1, year: 2016}; +// comp.locale = 'fr'; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let days = getElements('.caltable thead tr th'); +// expect(days.length).toBe(7); +// expect(days[0].nativeElement.textContent).toBe('Lun'); +// expect(days[1].nativeElement.textContent).toBe('Mar'); +// expect(days[2].nativeElement.textContent).toBe('Mer'); +// expect(days[3].nativeElement.textContent).toBe('Jeu'); +// expect(days[4].nativeElement.textContent).toBe('Ven'); +// expect(days[5].nativeElement.textContent).toBe('Sam'); +// expect(days[6].nativeElement.textContent).toBe('Dim'); +// +// fixture.detectChanges(); +// let nextmonth = getElement(NEXTMONTH); +// expect(nextmonth).not.toBe(null); +// +// fixture.detectChanges(); +// let monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Jan'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Fév'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Mar'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Avr'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Mai'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Juin'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Juil'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Aoû'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Sep'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Oct'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Nov'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Déc'); +// +// fixture.detectChanges(); +// let headertodaybtn = getElement('.headertodaybtn'); +// expect(headertodaybtn).not.toBe(null); +// expect(headertodaybtn.nativeElement.textContent).toBe('Aujourd\'hui'); +// +// fixture.detectChanges(); +// let firstDayOfWeek = getElement('.caltable thead tr th:first-child'); +// expect(firstDayOfWeek).not.toBe(null); +// expect(firstDayOfWeek.nativeElement.textContent).toBe('Lun'); +// +// fixture.detectChanges(); +// let sunday = getElement('.sunday'); +// expect(sunday).not.toBe(null); +// +// comp.userDateInput({target:{value:'10/10/2016'}}); +// expect(comp.invalidDate).toBe(false); +// +// fixture.detectChanges(); +// let invaliddate = getElement('.invaliddate'); +// expect(invaliddate).toBe(null); +// }); +// +// it('selDate - initially selected date - string', () => { +// let date: string = '2017-10-11'; +// comp.selectedDate = comp.parseSelectedDate(date); +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let selection = getElement('.selection'); +// expect(selection).not.toBe(null); +// expect(selection.nativeElement.value).toContain('2017-10-11'); +// +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let selectedday = getElement('.selectedday div span'); +// expect(selectedday).not.toBe(null); +// expect(selectedday.nativeElement.textContent).toContain('11'); +// +// fixture.detectChanges(); +// let monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel).not.toBe(null); +// expect(monthLabel.nativeElement.textContent).toBe('Oct'); +// +// fixture.detectChanges(); +// let yearLabel = getElement('.headeryeartxt .headerlabelbtn'); +// expect(yearLabel).not.toBe(null); +// expect(yearLabel.nativeElement.textContent).toBe('2017'); +// }); +// +// it('selDate - initially selected date - object', () => { +// let date: Object = {year: 2017, month: 10, day: 11}; +// comp.selectedDate = comp.parseSelectedDate(date); +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let selection = getElement('.selection'); +// expect(selection).not.toBe(null); +// expect(selection.nativeElement.value).toContain('2017-10-11'); +// expect(comp.selectionDayTxt).toContain('2017-10-11'); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let selectedday = getElement('.selectedday div span'); +// expect(selectedday).not.toBe(null); +// expect(selectedday.nativeElement.textContent).toContain('11'); +// +// fixture.detectChanges(); +// let monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel).not.toBe(null); +// expect(monthLabel.nativeElement.textContent).toBe('Oct'); +// +// fixture.detectChanges(); +// let yearLabel = getElement('.headeryeartxt .headerlabelbtn'); +// expect(yearLabel).not.toBe(null); +// expect(yearLabel.nativeElement.textContent).toBe('2017'); +// }); +// +// it('defaultMonth - initially selected month', () => { +// comp.selectedMonth = comp.parseSelectedMonth('2019-08'); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel).not.toBe(null); +// expect(monthLabel.nativeElement.textContent).toBe('Aug'); +// +// fixture.detectChanges(); +// let yearLabel = getElement('.headeryeartxt .headerlabelbtn'); +// expect(yearLabel).not.toBe(null); +// expect(yearLabel.nativeElement.textContent).toBe('2019'); +// }); +// +// it('placeholder - placeholder text', () => { +// comp.placeholder = ''; +// +// fixture.detectChanges(); +// let selection = getElement('.selection'); +// expect(selection).not.toBe(null); +// expect(selection.properties['placeholder']).toBe(''); +// +// comp.placeholder = 'Select date'; +// +// fixture.detectChanges(); +// selection = getElement('.selection'); +// expect(selection).not.toBe(null); +// expect(selection.properties['placeholder']).toBe(comp.placeholder); +// +// +// }); +// +// it('locale - use id locale', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 1, year: 2016}; +// comp.locale = 'id'; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let days = getElements('.caltable thead tr th'); +// expect(days.length).toBe(7); +// expect(days[0].nativeElement.textContent).toBe('Min'); +// expect(days[1].nativeElement.textContent).toBe('Sen'); +// expect(days[2].nativeElement.textContent).toBe('Sel'); +// expect(days[3].nativeElement.textContent).toBe('Rab'); +// expect(days[4].nativeElement.textContent).toBe('Kam'); +// expect(days[5].nativeElement.textContent).toBe('Jum'); +// expect(days[6].nativeElement.textContent).toBe('Sab'); +// +// fixture.detectChanges(); +// let nextmonth = getElement(NEXTMONTH); +// expect(nextmonth).not.toBe(null); +// +// fixture.detectChanges(); +// let monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Jan'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Feb'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Mar'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Apr'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Mei'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Jun'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Jul'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Ags'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Sep'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Okt'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Nov'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Des'); +// +// fixture.detectChanges(); +// let headertodaybtn = getElement('.headertodaybtn'); +// expect(headertodaybtn).not.toBe(null); +// expect(headertodaybtn.nativeElement.textContent).toBe('Hari ini'); +// +// fixture.detectChanges(); +// let firstDayOfWeek = getElement('.caltable thead tr th:first-child'); +// expect(firstDayOfWeek).not.toBe(null); +// expect(firstDayOfWeek.nativeElement.textContent).toBe('Min'); +// +// fixture.detectChanges(); +// let sunday = getElement('.sunday'); +// expect(sunday).not.toBe(null); +// +// comp.userDateInput({target:{value:'10-10-2016'}}); +// expect(comp.invalidDate).toBe(false); +// +// fixture.detectChanges(); +// let invaliddate = getElement('.invaliddate'); +// expect(invaliddate).toBe(null); +// }); +// +// }); diff --git a/portal-4cli/src/app/utils/my-date-picker/my-date-picker.component.ts b/portal-4cli/src/app/utils/my-date-picker/my-date-picker.component.ts new file mode 100644 index 00000000..389a5be3 --- /dev/null +++ b/portal-4cli/src/app/utils/my-date-picker/my-date-picker.component.ts @@ -0,0 +1,677 @@ +import { Component, Input, Output, EventEmitter, OnChanges, SimpleChanges, ElementRef, ViewEncapsulation, ChangeDetectorRef, Renderer, forwardRef } from "@angular/core"; +import { ControlValueAccessor, NG_VALUE_ACCESSOR } from "@angular/forms"; +import { IMyDate, IMyDateRange, IMyMonth, IMyCalendarDay, IMyWeek, IMyDayLabels, IMyMonthLabels, IMyOptions, IMyDateModel, IMyInputAutoFill, IMyInputFieldChanged, IMyCalendarViewChanged, IMyInputFocusBlur } from "./interfaces/index"; +import { LocaleService } from "./services/my-date-picker.locale.service"; +import { UtilService } from "./services/my-date-picker.util.service"; + +// webpack1_ +declare var require: any; +// declare var myDpStyles: string = require("./my-date-picker.component.css"); +// declare var myDpTpl: string = require("./my-date-picker.component.html"); +// webpack2_ + +export const MYDP_VALUE_ACCESSOR: any = { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => MyDatePicker), + multi: true +}; + +@Component({ + selector: "my-date-picker", + styleUrls: ['my-date-picker.component.css'], + templateUrl: 'my-date-picker.component.html', + providers: [LocaleService, UtilService, MYDP_VALUE_ACCESSOR], + encapsulation: ViewEncapsulation.None +}) + +export class MyDatePicker implements OnChanges, ControlValueAccessor { + @Input() options: any; + @Input() locale: string; + @Input() defaultMonth: string; + @Input() selDate: string; + @Input() placeholder: string; + @Input() selector: number; + @Output() dateChanged: EventEmitter = new EventEmitter(); + @Output() inputFieldChanged: EventEmitter = new EventEmitter(); + @Output() calendarViewChanged: EventEmitter = new EventEmitter(); + @Output() calendarToggle: EventEmitter = new EventEmitter(); + @Output() inputFocusBlur: EventEmitter = new EventEmitter(); + + onChangeCb: (_: any) => void = () => { }; + onTouchedCb: () => void = () => { }; + + showSelector: boolean = false; + visibleMonth: IMyMonth = {monthTxt: "", monthNbr: 0, year: 0}; + selectedMonth: IMyMonth = {monthTxt: "", monthNbr: 0, year: 0}; + selectedDate: IMyDate = {year: 0, month: 0, day: 0}; + weekDays: Array = []; + dates: Array = []; + selectionDayTxt: string = ""; + invalidDate: boolean = false; + disableTodayBtn: boolean = false; + dayIdx: number = 0; + weekDayOpts: Array = ["su", "mo", "tu", "we", "th", "fr", "sa"]; + autoFillOpts: IMyInputAutoFill = {separator: "", formatParts: [], enabled: true}; + + editMonth: boolean = false; + invalidMonth: boolean = false; + editYear: boolean = false; + invalidYear: boolean = false; + + prevMonthDisabled: boolean = false; + nextMonthDisabled: boolean = false; + prevYearDisabled: boolean = false; + nextYearDisabled: boolean = false; + + PREV_MONTH: number = 1; + CURR_MONTH: number = 2; + NEXT_MONTH: number = 3; + + MIN_YEAR: number = 1000; + MAX_YEAR: number = 9999; + + // Default options + opts: IMyOptions = { + dayLabels: {}, + monthLabels: {}, + dateFormat: "", + showTodayBtn: true, + todayBtnTxt: "", + firstDayOfWeek: "", + sunHighlight: true, + markCurrentDay: true, + disableUntil: {year: 0, month: 0, day: 0}, + disableSince: {year: 0, month: 0, day: 0}, + disableDays: > [], + enableDays: > [], + disableDateRange: {begin: {year: 0, month: 0, day: 0}, end: {year: 0, month: 0, day: 0}}, + disableWeekends: false, + showWeekNumbers: false, + height: "34px", + width: "100%", + selectionTxtFontSize: "18px", + inline: false, + showClearDateBtn: true, + alignSelectorRight: false, + openSelectorTopOfInput: false, + indicateInvalidDate: true, + editableDateField: true, + editableMonthAndYear: true, + disableHeaderButtons: true, + minYear: this.MIN_YEAR, + maxYear: this.MAX_YEAR, + componentDisabled: false, + inputValueRequired: false, + showSelectorArrow: true, + showInputField: true, + openSelectorOnInputClick: false, + inputAutoFill: true, + ariaLabelInputField: "Date input field", + ariaLabelClearDate: "Clear Date", + ariaLabelOpenCalendar: "Open Calendar", + ariaLabelPrevMonth: "Previous Month", + ariaLabelNextMonth: "Next Month", + ariaLabelPrevYear: "Previous Year", + ariaLabelNextYear: "Next Year" + }; + + constructor(public elem: ElementRef, private renderer: Renderer, private cdr: ChangeDetectorRef, private localeService: LocaleService, private utilService: UtilService) { + this.setLocaleOptions(); + renderer.listenGlobal("document", "click", (event: any) => { + if (this.showSelector && event.target && this.elem.nativeElement !== event.target && !this.elem.nativeElement.contains(event.target)) { + this.showSelector = false; + this.calendarToggle.emit(4); + } + if (this.opts.editableMonthAndYear && event.target && this.elem.nativeElement.contains(event.target)) { + this.resetMonthYearEdit(); + } + }); + } + + setLocaleOptions(): void { + let opts: IMyOptions = this.localeService.getLocaleOptions(this.locale); + Object.keys(opts).forEach((k) => { + (this.opts)[k] = opts[k]; + }); + } + + setOptions(): void { + if (this.options !== undefined) { + Object.keys(this.options).forEach((k) => { + (this.opts)[k] = this.options[k]; + }); + } + if (this.opts.minYear < this.MIN_YEAR) { + this.opts.minYear = this.MIN_YEAR; + } + if (this.opts.maxYear > this.MAX_YEAR) { + this.opts.maxYear = this.MAX_YEAR; + } + + let separator: string = this.utilService.getDateFormatSeparator(this.opts.dateFormat); + this.autoFillOpts = {separator: separator, formatParts: this.opts.dateFormat.split(separator), enabled: this.opts.inputAutoFill}; + } + + getComponentWidth(): string { + if (this.opts.showInputField) { + return this.opts.width; + } + else if (this.selectionDayTxt.length > 0 && this.opts.showClearDateBtn) { + return "60px"; + } + else { + return "30px"; + } + } + + getSelectorTopPosition(): string { + if (this.opts.openSelectorTopOfInput) { + return this.elem.nativeElement.children[0].offsetHeight + "px"; + } + } + + resetMonthYearEdit(): void { + this.editMonth = false; + this.editYear = false; + this.invalidMonth = false; + this.invalidYear = false; + } + + editMonthClicked(event: any): void { + event.stopPropagation(); + if (this.opts.editableMonthAndYear) { + this.editMonth = true; + } + } + + editYearClicked(event: any): void { + event.stopPropagation(); + if (this.opts.editableMonthAndYear) { + this.editYear = true; + } + } + + userDateInput(event: any): void { + this.invalidDate = false; + if (event.target.value.length === 0) { + this.clearDate(); + } + else { + let date: IMyDate = this.utilService.isDateValid(event.target.value, this.opts.dateFormat, this.opts.minYear, this.opts.maxYear, this.opts.disableUntil, this.opts.disableSince, this.opts.disableWeekends, this.opts.disableDays, this.opts.disableDateRange, this.opts.monthLabels, this.opts.enableDays); + if (date.day !== 0 && date.month !== 0 && date.year !== 0) { + this.selectDate(date); + } + else { + this.invalidDate = true; + } + } + if (this.invalidDate) { + this.inputFieldChanged.emit({value: event.target.value, dateFormat: this.opts.dateFormat, valid: !(event.target.value.length === 0 || this.invalidDate)}); + this.onChangeCb(""); + this.onTouchedCb(); + } + } + + onFocusInput(event: any): void { + this.inputFocusBlur.emit({reason: 1, value: event.target.value}); + } + + lostFocusInput(event: any): void { + this.selectionDayTxt = event.target.value; + this.onTouchedCb(); + this.inputFocusBlur.emit({reason: 2, value: event.target.value}); + } + + userMonthInput(event: any): void { + if (event.keyCode === 13 || event.keyCode === 37 || event.keyCode === 39) { + return; + } + + this.invalidMonth = false; + + let m: number = this.utilService.isMonthLabelValid(event.target.value, this.opts.monthLabels); + if (m !== -1) { + this.editMonth = false; + if (m !== this.visibleMonth.monthNbr) { + this.visibleMonth = {monthTxt: this.monthText(m), monthNbr: m, year: this.visibleMonth.year}; + this.generateCalendar(m, this.visibleMonth.year, true); + } + } + else { + this.invalidMonth = true; + } + } + + userYearInput(event: any): void { + if (event.keyCode === 13 || event.keyCode === 37 || event.keyCode === 39) { + return; + } + + this.invalidYear = false; + + let y: number = this.utilService.isYearLabelValid(Number(event.target.value), this.opts.minYear, this.opts.maxYear); + if (y !== -1) { + this.editYear = false; + if (y !== this.visibleMonth.year) { + this.visibleMonth = {monthTxt: this.visibleMonth.monthTxt, monthNbr: this.visibleMonth.monthNbr, year: y}; + this.generateCalendar(this.visibleMonth.monthNbr, y, true); + } + } + else { + this.invalidYear = true; + } + } + + isTodayDisabled(): void { + this.disableTodayBtn = this.utilService.isDisabledDay(this.getToday(), this.opts.disableUntil, this.opts.disableSince, this.opts.disableWeekends, this.opts.disableDays, this.opts.disableDateRange, this.opts.enableDays); + } + + parseOptions(): void { + if (this.locale) { + this.setLocaleOptions(); + } + this.setOptions(); + this.isTodayDisabled(); + this.dayIdx = this.weekDayOpts.indexOf(this.opts.firstDayOfWeek); + if (this.dayIdx !== -1) { + let idx: number = this.dayIdx; + for (let i = 0; i < this.weekDayOpts.length; i++) { + this.weekDays.push(this.opts.dayLabels[this.weekDayOpts[idx]]); + idx = this.weekDayOpts[idx] === "sa" ? 0 : idx + 1; + } + } + } + + writeValue(value: Object): void { + if (value && value["date"]) { + this.updateDateValue(this.parseSelectedDate(value["date"]), false); + } + else if (value === "") { + this.updateDateValue({year: 0, month: 0, day: 0}, true); + } + } + + registerOnChange(fn: any): void { + this.onChangeCb = fn; + } + + registerOnTouched(fn: any): void { + this.onTouchedCb = fn; + } + + ngOnChanges(changes: SimpleChanges): void { + if (changes.hasOwnProperty("selector") && changes["selector"].currentValue > 0) { + this.openBtnClicked(); + } + + if (changes.hasOwnProperty("placeholder")) { + this.placeholder = changes["placeholder"].currentValue; + } + + if (changes.hasOwnProperty("locale")) { + this.locale = changes["locale"].currentValue; + } + + if (changes.hasOwnProperty("options")) { + this.options = changes["options"].currentValue; + } + + this.weekDays.length = 0; + this.parseOptions(); + + if (changes.hasOwnProperty("defaultMonth")) { + let dm: string = changes["defaultMonth"].currentValue; + if (dm !== null && dm !== undefined && dm !== "") { + this.selectedMonth = this.parseSelectedMonth(dm); + } + else { + this.selectedMonth = {monthTxt: "", monthNbr: 0, year: 0}; + } + } + + if (changes.hasOwnProperty("selDate")) { + let sd: any = changes["selDate"]; + if (sd.currentValue !== null && sd.currentValue !== undefined && sd.currentValue !== "" && Object.keys(sd.currentValue).length !== 0) { + this.selectedDate = this.parseSelectedDate(sd.currentValue); + setTimeout(() => { + this.onChangeCb(this.getDateModel(this.selectedDate)); + }); + } + else { + // Do not clear on init + if (!sd.isFirstChange()) { + this.clearDate(); + } + } + } + if (this.opts.inline) { + this.setVisibleMonth(); + } + else if (this.showSelector) { + this.generateCalendar(this.visibleMonth.monthNbr, this.visibleMonth.year, false); + } + } + + removeBtnClicked(): void { + // Remove date button clicked + this.clearDate(); + if (this.showSelector) { + this.calendarToggle.emit(3); + } + this.showSelector = false; + } + + openBtnClicked(): void { + // Open selector button clicked + this.showSelector = !this.showSelector; + if (this.showSelector) { + this.setVisibleMonth(); + this.calendarToggle.emit(1); + } + else { + this.calendarToggle.emit(3); + } + } + + setVisibleMonth(): void { + // Sets visible month of calendar + let y: number = 0, m: number = 0; + if (!this.utilService.isInitializedDate(this.selectedDate)) { + if (this.selectedMonth.year === 0 && this.selectedMonth.monthNbr === 0) { + let today: IMyDate = this.getToday(); + y = today.year; + m = today.month; + } else { + y = this.selectedMonth.year; + m = this.selectedMonth.monthNbr; + } + } + else { + y = this.selectedDate.year; + m = this.selectedDate.month; + } + this.visibleMonth = {monthTxt: this.opts.monthLabels[m], monthNbr: m, year: y}; + + // Create current month + this.generateCalendar(m, y, true); + } + + prevMonth(): void { + // Previous month from calendar + let d: Date = this.getDate(this.visibleMonth.year, this.visibleMonth.monthNbr, 1); + d.setMonth(d.getMonth() - 1); + + let y: number = d.getFullYear(); + let m: number = d.getMonth() + 1; + + this.visibleMonth = {monthTxt: this.monthText(m), monthNbr: m, year: y}; + this.generateCalendar(m, y, true); + } + + nextMonth(): void { + // Next month from calendar + let d: Date = this.getDate(this.visibleMonth.year, this.visibleMonth.monthNbr, 1); + d.setMonth(d.getMonth() + 1); + + let y: number = d.getFullYear(); + let m: number = d.getMonth() + 1; + + this.visibleMonth = {monthTxt: this.monthText(m), monthNbr: m, year: y}; + this.generateCalendar(m, y, true); + } + + prevYear(): void { + // Previous year from calendar + this.visibleMonth.year--; + this.generateCalendar(this.visibleMonth.monthNbr, this.visibleMonth.year, true); + } + + nextYear(): void { + // Next year from calendar + this.visibleMonth.year++; + this.generateCalendar(this.visibleMonth.monthNbr, this.visibleMonth.year, true); + } + + todayClicked(): void { + // Today button clicked + let today: IMyDate = this.getToday(); + this.selectDate(today); + if (this.opts.inline && today.year !== this.visibleMonth.year || today.month !== this.visibleMonth.monthNbr) { + this.visibleMonth = {monthTxt: this.opts.monthLabels[today.month], monthNbr: today.month, year: today.year}; + this.generateCalendar(today.month, today.year, true); + } + } + + cellClicked(cell: any): void { + // Cell clicked on the calendar + if (cell.cmo === this.PREV_MONTH) { + // Previous month day + this.prevMonth(); + } + else if (cell.cmo === this.CURR_MONTH) { + // Current month day - if date is already selected clear it + if (cell.dateObj.year === this.selectedDate.year && cell.dateObj.month === this.selectedDate.month && cell.dateObj.day === this.selectedDate.day) { + this.clearDate(); + } + else { + this.selectDate(cell.dateObj); + } + } + else if (cell.cmo === this.NEXT_MONTH) { + // Next month day + this.nextMonth(); + } + this.resetMonthYearEdit(); + } + + cellKeyDown(event: any, cell: any) { + // Cell keyboard handling + if ((event.keyCode === 13 || event.keyCode === 32) && !cell.disabled) { + event.preventDefault(); + this.cellClicked(cell); + } + } + + clearDate(): void { + // Clears the date and notifies parent using callbacks and value accessor + let date: IMyDate = {year: 0, month: 0, day: 0}; + this.dateChanged.emit({date: date, jsdate: null, formatted: "", epoc: 0}); + this.onChangeCb(""); + this.onTouchedCb(); + this.updateDateValue(date, true); + } + + selectDate(date: IMyDate): void { + // Date selected, notifies parent using callbacks and value accessor + let dateModel: IMyDateModel = this.getDateModel(date); + this.dateChanged.emit(dateModel); + this.onChangeCb(dateModel); + this.onTouchedCb(); + this.updateDateValue(date, false); + if (this.showSelector) { + this.calendarToggle.emit(2); + } + this.showSelector = false; + } + + updateDateValue(date: IMyDate, clear: boolean): void { + // Updates date values + this.selectedDate = date; + this.selectionDayTxt = clear ? "" : this.formatDate(date); + this.inputFieldChanged.emit({value: this.selectionDayTxt, dateFormat: this.opts.dateFormat, valid: !clear}); + this.invalidDate = false; + } + + getDateModel(date: IMyDate): IMyDateModel { + // Creates a date model object from the given parameter + return {date: date, jsdate: this.getDate(date.year, date.month, date.day), formatted: this.formatDate(date), epoc: Math.round(this.getTimeInMilliseconds(date) / 1000.0)}; + } + + preZero(val: string): string { + // Prepend zero if smaller than 10 + return parseInt(val) < 10 ? "0" + val : val; + } + + formatDate(val: any): string { + // Returns formatted date string, if mmm is part of dateFormat returns month as a string + let formatted: string = this.opts.dateFormat.replace("yyyy", val.year).replace("dd", this.preZero(val.day)); + return this.opts.dateFormat.indexOf("mmm") !== -1 ? formatted.replace("mmm", this.monthText(val.month)) : formatted.replace("mm", this.preZero(val.month)); + } + + monthText(m: number): string { + // Returns month as a text + return this.opts.monthLabels[m]; + } + + monthStartIdx(y: number, m: number): number { + // Month start index + let d = new Date(); + d.setDate(1); + d.setMonth(m - 1); + d.setFullYear(y); + let idx = d.getDay() + this.sundayIdx(); + return idx >= 7 ? idx - 7 : idx; + } + + daysInMonth(m: number, y: number): number { + // Return number of days of current month + return new Date(y, m, 0).getDate(); + } + + daysInPrevMonth(m: number, y: number): number { + // Return number of days of the previous month + let d: Date = this.getDate(y, m, 1); + d.setMonth(d.getMonth() - 1); + return this.daysInMonth(d.getMonth() + 1, d.getFullYear()); + } + + isCurrDay(d: number, m: number, y: number, cmo: number, today: IMyDate): boolean { + // Check is a given date the today + return d === today.day && m === today.month && y === today.year && cmo === this.CURR_MONTH; + } + + getToday(): IMyDate { + let date: Date = new Date(); + return {year: date.getFullYear(), month: date.getMonth() + 1, day: date.getDate()}; + } + + getTimeInMilliseconds(date: IMyDate): number { + return this.getDate(date.year, date.month, date.day).getTime(); + } + + getDayNumber(date: IMyDate): number { + // Get day number: su=0, mo=1, tu=2, we=3 ... + let d: Date = this.getDate(date.year, date.month, date.day); + return d.getDay(); + } + + getWeekday(date: IMyDate): string { + // Get weekday: su, mo, tu, we ... + return this.weekDayOpts[this.getDayNumber(date)]; + } + + getDate(year: number, month: number, day: number): Date { + // Creates a date object from given year, month and day + return new Date(year, month - 1, day, 0, 0, 0, 0); + } + + sundayIdx(): number { + // Index of Sunday day + return this.dayIdx > 0 ? 7 - this.dayIdx : 0; + } + + generateCalendar(m: number, y: number, notifyChange: boolean): void { + this.dates.length = 0; + let today: IMyDate = this.getToday(); + let monthStart: number = this.monthStartIdx(y, m); + let dInThisM: number = this.daysInMonth(m, y); + let dInPrevM: number = this.daysInPrevMonth(m, y); + + let dayNbr: number = 1; + let cmo: number = this.PREV_MONTH; + for (let i = 1; i < 7; i++) { + let week: Array = []; + if (i === 1) { + // First week + let pm = dInPrevM - monthStart + 1; + // Previous month + for (let j = pm; j <= dInPrevM; j++) { + let date: IMyDate = {year: y, month: m - 1, day: j}; + week.push({dateObj: date, cmo: cmo, currDay: this.isCurrDay(j, m, y, cmo, today), dayNbr: this.getDayNumber(date), disabled: this.utilService.isDisabledDay(date, this.opts.disableUntil, this.opts.disableSince, this.opts.disableWeekends, this.opts.disableDays, this.opts.disableDateRange, this.opts.enableDays)}); + } + + cmo = this.CURR_MONTH; + // Current month + let daysLeft: number = 7 - week.length; + for (let j = 0; j < daysLeft; j++) { + let date: IMyDate = {year: y, month: m, day: dayNbr}; + week.push({dateObj: date, cmo: cmo, currDay: this.isCurrDay(dayNbr, m, y, cmo, today), dayNbr: this.getDayNumber(date), disabled: this.utilService.isDisabledDay(date, this.opts.disableUntil, this.opts.disableSince, this.opts.disableWeekends, this.opts.disableDays, this.opts.disableDateRange, this.opts.enableDays)}); + dayNbr++; + } + } + else { + // Rest of the weeks + for (let j = 1; j < 8; j++) { + if (dayNbr > dInThisM) { + // Next month + dayNbr = 1; + cmo = this.NEXT_MONTH; + } + let date: IMyDate = {year: y, month: cmo === this.CURR_MONTH ? m : m + 1, day: dayNbr}; + week.push({dateObj: date, cmo: cmo, currDay: this.isCurrDay(dayNbr, m, y, cmo, today), dayNbr: this.getDayNumber(date), disabled: this.utilService.isDisabledDay(date, this.opts.disableUntil, this.opts.disableSince, this.opts.disableWeekends, this.opts.disableDays, this.opts.disableDateRange, this.opts.enableDays)}); + dayNbr++; + } + } + let weekNbr: number = this.opts.showWeekNumbers && this.opts.firstDayOfWeek === "mo" ? this.utilService.getWeekNumber(week[0].dateObj) : 0; + this.dates.push({week: week, weekNbr: weekNbr}); + } + + this.setHeaderBtnDisabledState(m, y); + + if (notifyChange) { + // Notify parent + this.calendarViewChanged.emit({year: y, month: m, first: {number: 1, weekday: this.getWeekday({year: y, month: m, day: 1})}, last: {number: dInThisM, weekday: this.getWeekday({year: y, month: m, day: dInThisM})}}); + } + } + + parseSelectedDate(selDate: any): IMyDate { + // Parse selDate value - it can be string or IMyDate object + let date: IMyDate = {day: 0, month: 0, year: 0}; + if (typeof selDate === "string") { + let sd: string = selDate; + date.day = this.utilService.parseDatePartNumber(this.opts.dateFormat, sd, "dd"); + + date.month = this.opts.dateFormat.indexOf("mmm") !== -1 + ? this.utilService.parseDatePartMonthName(this.opts.dateFormat, sd, "mmm", this.opts.monthLabels) + : this.utilService.parseDatePartNumber(this.opts.dateFormat, sd, "mm"); + + date.year = this.utilService.parseDatePartNumber(this.opts.dateFormat, sd, "yyyy"); + } + else if (typeof selDate === "object") { + date = selDate; + } + this.selectionDayTxt = this.formatDate(date); + return date; + } + + parseSelectedMonth(ms: string): IMyMonth { + return this.utilService.parseDefaultMonth(ms); + } + + setHeaderBtnDisabledState(m: number, y: number): void { + let dpm: boolean = false; + let dpy: boolean = false; + let dnm: boolean = false; + let dny: boolean = false; + if (this.opts.disableHeaderButtons) { + dpm = this.utilService.isMonthDisabledByDisableUntil({year: m === 1 ? y - 1 : y, month: m === 1 ? 12 : m - 1, day: this.daysInMonth(m === 1 ? 12 : m - 1, m === 1 ? y - 1 : y)}, this.opts.disableUntil); + dpy = this.utilService.isMonthDisabledByDisableUntil({year: y - 1, month: m, day: this.daysInMonth(m, y - 1)}, this.opts.disableUntil); + dnm = this.utilService.isMonthDisabledByDisableSince({year: m === 12 ? y + 1 : y, month: m === 12 ? 1 : m + 1, day: 1}, this.opts.disableSince); + dny = this.utilService.isMonthDisabledByDisableSince({year: y + 1, month: m, day: 1}, this.opts.disableSince); + } + this.prevMonthDisabled = m === 1 && y === this.opts.minYear || dpm; + this.prevYearDisabled = y - 1 < this.opts.minYear || dpy; + this.nextMonthDisabled = m === 12 && y === this.opts.maxYear || dnm; + this.nextYearDisabled = y + 1 > this.opts.maxYear || dny; + } +} diff --git a/portal-4cli/src/app/utils/my-date-picker/my-date-picker.module.ts b/portal-4cli/src/app/utils/my-date-picker/my-date-picker.module.ts new file mode 100644 index 00000000..a638a905 --- /dev/null +++ b/portal-4cli/src/app/utils/my-date-picker/my-date-picker.module.ts @@ -0,0 +1,14 @@ +import { CommonModule } from "@angular/common"; +import { FormsModule } from "@angular/forms"; +import { NgModule } from "@angular/core"; +import { MyDatePicker } from "./my-date-picker.component"; +import { FocusDirective } from "./directives/my-date-picker.focus.directive"; +import { InputAutoFillDirective } from "./directives/my-date-picker.input.auto.fill.directive"; + +@NgModule({ + imports: [CommonModule, FormsModule], + declarations: [MyDatePicker, FocusDirective, InputAutoFillDirective], + exports: [MyDatePicker, FocusDirective, InputAutoFillDirective] +}) +export class MyDatePickerModule { +} diff --git a/portal-4cli/src/app/utils/my-date-picker/services/my-date-picker.locale.service.ts b/portal-4cli/src/app/utils/my-date-picker/services/my-date-picker.locale.service.ts new file mode 100644 index 00000000..44c209e9 --- /dev/null +++ b/portal-4cli/src/app/utils/my-date-picker/services/my-date-picker.locale.service.ts @@ -0,0 +1,232 @@ +import { Injectable } from "@angular/core"; +import { IMyLocales, IMyOptions } from "../interfaces/index"; + +@Injectable() +export class LocaleService { + private locales: IMyLocales = { + "en": { + dayLabels: {su: "Sun", mo: "Mon", tu: "Tue", we: "Wed", th: "Thu", fr: "Fri", sa: "Sat"}, + monthLabels: { 1: "Jan", 2: "Feb", 3: "Mar", 4: "Apr", 5: "May", 6: "Jun", 7: "Jul", 8: "Aug", 9: "Sep", 10: "Oct", 11: "Nov", 12: "Dec" }, + dateFormat: "yyyy-mm-dd", + todayBtnTxt: "Today", + firstDayOfWeek: "mo", + sunHighlight: true, + }, + "he": { + dayLabels: {su: "רא", mo: "שנ", tu: "של", we: "רב", th: "חמ", fr: "שי", sa: "שב"}, + monthLabels: { 1: "ינו", 2: "פבר", 3: "מרץ", 4: "אפר", 5: "מאי", 6: "יונ", 7: "יול", 8: "אוג", 9: "ספט", 10: "אוק", 11: "נוב", 12: "דצמ" }, + dateFormat: "dd/mm/yyyy", + todayBtnTxt: "היום", + firstDayOfWeek: "su", + sunHighlight: false + }, + "ja": { + dayLabels: {su: "日", mo: "月", tu: "火", we: "水", th: "木", fr: "金", sa: "土"}, + monthLabels: {1: "1月", 2: "2月", 3: "3月", 4: "4月", 5: "5月", 6: "6月", 7: "7月", 8: "8月", 9: "9月", 10: "10月", 11: "11月", 12: "12月"}, + dateFormat: "yyyy.mm.dd", + todayBtnTxt: "今日", + sunHighlight: false + }, + "fr": { + dayLabels: {su: "Dim", mo: "Lun", tu: "Mar", we: "Mer", th: "Jeu", fr: "Ven", sa: "Sam"}, + monthLabels: {1: "Jan", 2: "Fév", 3: "Mar", 4: "Avr", 5: "Mai", 6: "Juin", 7: "Juil", 8: "Aoû", 9: "Sep", 10: "Oct", 11: "Nov", 12: "Déc"}, + dateFormat: "dd/mm/yyyy", + todayBtnTxt: "Aujourd'hui", + firstDayOfWeek: "mo", + sunHighlight: true, + }, + "fi": { + dayLabels: {su: "Su", mo: "Ma", tu: "Ti", we: "Ke", th: "To", fr: "Pe", sa: "La"}, + monthLabels: {1: "Tam", 2: "Hel", 3: "Maa", 4: "Huh", 5: "Tou", 6: "Kes", 7: "Hei", 8: "Elo", 9: "Syy", 10: "Lok", 11: "Mar", 12: "Jou"}, + dateFormat: "dd.mm.yyyy", + todayBtnTxt: "Tänään", + firstDayOfWeek: "mo", + sunHighlight: true, + }, + "es": { + dayLabels: {su: "Do", mo: "Lu", tu: "Ma", we: "Mi", th: "Ju", fr: "Vi", sa: "Sa"}, + monthLabels: {1: "Ene", 2: "Feb", 3: "Mar", 4: "Abr", 5: "May", 6: "Jun", 7: "Jul", 8: "Ago", 9: "Sep", 10: "Oct", 11: "Nov", 12: "Dic"}, + dateFormat: "dd.mm.yyyy", + todayBtnTxt: "Hoy", + firstDayOfWeek: "mo", + sunHighlight: true, + }, + "hu": { + dayLabels: {su: "Vas", mo: "Hét", tu: "Kedd", we: "Sze", th: "Csü", fr: "Pén", sa: "Szo"}, + monthLabels: { 1: "Jan", 2: "Feb", 3: "Már", 4: "Ápr", 5: "Máj", 6: "Jún", 7: "Júl", 8: "Aug", 9: "Szep", 10: "Okt", 11: "Nov", 12: "Dec" }, + dateFormat: "yyyy-mm-dd", + todayBtnTxt: "Ma", + firstDayOfWeek: "mo", + sunHighlight: true + }, + "sv": { + dayLabels: {su: "Sön", mo: "Mån", tu: "Tis", we: "Ons", th: "Tor", fr: "Fre", sa: "Lör"}, + monthLabels: { 1: "Jan", 2: "Feb", 3: "Mar", 4: "Apr", 5: "Maj", 6: "Jun", 7: "Jul", 8: "Aug", 9: "Sep", 10: "Okt", 11: "Nov", 12: "Dec" }, + dateFormat: "yyyy-mm-dd", + todayBtnTxt: "Idag", + firstDayOfWeek: "mo", + sunHighlight: false + }, + "nl": { + dayLabels: {su: "Zon", mo: "Maa", tu: "Din", we: "Woe", th: "Don", fr: "Vri", sa: "Zat"}, + monthLabels: { 1: "Jan", 2: "Feb", 3: "Mar", 4: "Apr", 5: "Mei", 6: "Jun", 7: "Jul", 8: "Aug", 9: "Sep", 10: "Okt", 11: "Nov", 12: "Dec" }, + dateFormat: "dd-mm-yyyy", + todayBtnTxt: "Vandaag", + firstDayOfWeek: "mo", + sunHighlight: false + }, + "ru": { + dayLabels: {su: "Вс", mo: "Пн", tu: "Вт", we: "Ср", th: "Чт", fr: "Пт", sa: "Сб"}, + monthLabels: { 1: "Янв", 2: "Фев", 3: "Март", 4: "Апр", 5: "Май", 6: "Июнь", 7: "Июль", 8: "Авг", 9: "Сент", 10: "Окт", 11: "Ноя", 12: "Дек" }, + dateFormat: "dd.mm.yyyy", + todayBtnTxt: "Сегодня", + firstDayOfWeek: "mo", + sunHighlight: true + }, + "uk": { + dayLabels: {su: "Нд", mo: "Пн", tu: "Вт", we: "Ср", th: "Чт", fr: "Пт", sa: "Сб"}, + monthLabels: { 1: "Січ", 2: "Лют", 3: "Бер", 4: "Кві", 5: "Тра", 6: "Чер", 7: "Лип", 8: "Сер", 9: "Вер", 10: "Жов", 11: "Лис", 12: "Гру" }, + dateFormat: "dd.mm.yyyy", + todayBtnTxt: "Сьогодні", + firstDayOfWeek: "mo", + sunHighlight: true + }, + "no": { + dayLabels: {su: "Søn", mo: "Man", tu: "Tir", we: "Ons", th: "Tor", fr: "Fre", sa: "Lør"}, + monthLabels: { 1: "Jan", 2: "Feb", 3: "Mar", 4: "Apr", 5: "Mai", 6: "Jun", 7: "Jul", 8: "Aug", 9: "Sep", 10: "Okt", 11: "Nov", 12: "Des" }, + dateFormat: "dd.mm.yyyy", + todayBtnTxt: "I dag", + firstDayOfWeek: "mo", + sunHighlight: false + }, + "tr": { + dayLabels: {su: "Paz", mo: "Pzt", tu: "Sal", we: "Çar", th: "Per", fr: "Cum", sa: "Cmt"}, + monthLabels: { 1: "Oca", 2: "Şub", 3: "Mar", 4: "Nis", 5: "May", 6: "Haz", 7: "Tem", 8: "Ağu", 9: "Eyl", 10: "Eki", 11: "Kas", 12: "Ara" }, + dateFormat: "dd.mm.yyyy", + todayBtnTxt: "Bugün", + firstDayOfWeek: "mo", + sunHighlight: false + }, + "pt-br": { + dayLabels: {su: "Dom", mo: "Seg", tu: "Ter", we: "Qua", th: "Qui", fr: "Sex", sa: "Sab"}, + monthLabels: { 1: "Jan", 2: "Fev", 3: "Mar", 4: "Abr", 5: "Mai", 6: "Jun", 7: "Jul", 8: "Ago", 9: "Set", 10: "Out", 11: "Nov", 12: "Dez" }, + dateFormat: "dd/mm/yyyy", + todayBtnTxt: "Hoje", + firstDayOfWeek: "su", + sunHighlight: true + }, + "de": { + dayLabels: {su: "So", mo: "Mo", tu: "Di", we: "Mi", th: "Do", fr: "Fr", sa: "Sa"}, + monthLabels: { 1: "Jan", 2: "Feb", 3: "Mär", 4: "Apr", 5: "Mai", 6: "Jun", 7: "Jul", 8: "Aug", 9: "Sep", 10: "Okt", 11: "Nov", 12: "Dez" }, + dateFormat: "dd.mm.yyyy", + todayBtnTxt: "Heute", + firstDayOfWeek: "mo", + sunHighlight: true + }, + "it": { + dayLabels: { su: "Dom", mo: "Lun", tu: "Mar", we: "Mer", th: "Gio", fr: "Ven", sa: "Sab" }, + monthLabels: { 1: "Gen", 2: "Feb", 3: "Mar", 4: "Apr", 5: "Mag", 6: "Giu", 7: "Lug", 8: "Ago", 9: "Set", 10: "Ott", 11: "Nov", 12: "Dic" }, + dateFormat: "dd/mm/yyyy", + todayBtnTxt: "Oggi", + firstDayOfWeek: "mo", + sunHighlight: true + }, + "it-ch": { + dayLabels: { su: "Dom", mo: "Lun", tu: "Mar", we: "Mer", th: "Gio", fr: "Ven", sa: "Sab" }, + monthLabels: { 1: "Gen", 2: "Feb", 3: "Mar", 4: "Apr", 5: "Mag", 6: "Giu", 7: "Lug", 8: "Ago", 9: "Set", 10: "Ott", 11: "Nov", 12: "Dic" }, + dateFormat: "dd.mm.yyyy", + todayBtnTxt: "Oggi", + firstDayOfWeek: "mo", + sunHighlight: true + }, + "pl": { + dayLabels: { su: "Nie", mo: "Pon", tu: "Wto", we: "Śro", th: "Czw", fr: "Pią", sa: "Sob" }, + monthLabels: { 1: "Sty", 2: "Lut", 3: "Mar", 4: "Kwi", 5: "Maj", 6: "Cze", 7: "Lip", 8: "Sie", 9: "Wrz", 10: "Paź", 11: "Lis", 12: "Gru" }, + dateFormat: "yyyy-mm-dd", + todayBtnTxt: "Dzisiaj", + firstDayOfWeek: "mo", + sunHighlight: true, + }, + "my": { + dayLabels: {su: "တနင်္ဂနွေ", mo: "တနင်္လာ", tu: "အင်္ဂါ", we: "ဗုဒ္ဓဟူး", th: "ကြသပတေး", fr: "သောကြာ", sa: "စနေ"}, + monthLabels: { 1: "ဇန်နဝါရီ", 2: "ဖေဖော်ဝါရီ", 3: "မတ်", 4: "ဧပြီ", 5: "မေ", 6: "ဇွန်", 7: "ဇူလိုင်", 8: "ဩဂုတ်", 9: "စက်တင်ဘာ", 10: "အောက်တိုဘာ", 11: "နိုဝင်ဘာ", 12: "ဒီဇင်ဘာ" }, + dateFormat: "yyyy-mm-dd", + todayBtnTxt: "ယနေ့", + firstDayOfWeek: "mo", + sunHighlight: true, + }, + "sk": { + dayLabels: { su: "Ne", mo: "Po", tu: "Ut", we: "St", th: "Št", fr: "Pi", sa: "So" }, + monthLabels: { 1: "Jan", 2: "Feb", 3: "Mar", 4: "Apr", 5: "Máj", 6: "Jún", 7: "Júl", 8: "Aug", 9: "Sep", 10: "Okt", 11: "Nov", 12: "Dec" }, + dateFormat: "dd.mm.yyyy", + todayBtnTxt: "Dnes", + firstDayOfWeek: "mo", + sunHighlight: true, + }, + "sl": { + dayLabels: { su: "Ned", mo: "Pon", tu: "Tor", we: "Sre", th: "Čet", fr: "Pet", sa: "Sob" }, + monthLabels: { 1: "Jan", 2: "Feb", 3: "Mar", 4: "Apr", 5: "Maj", 6: "Jun", 7: "Jul", 8: "Avg", 9: "Sep", 10: "Okt", 11: "Nov", 12: "Dec" }, + dateFormat: "dd. mm. yyyy", + todayBtnTxt: "Danes", + firstDayOfWeek: "mo", + sunHighlight: true, + }, + "zh-cn": { + dayLabels: {su: "日", mo: "一", tu: "二", we: "三", th: "四", fr: "五", sa: "六"}, + monthLabels: { 1: "1月", 2: "2月", 3: "3月", 4: "4月", 5: "5月", 6: "6月", 7: "7月", 8: "8月", 9: "9月", 10: "10月", 11: "11月", 12: "12月" }, + dateFormat: "yyyy-mm-dd", + todayBtnTxt: "今天", + firstDayOfWeek: "mo", + sunHighlight: true, + }, + "ro": { + dayLabels: {su: "du", mo: "lu", tu: "ma", we: "mi", th: "jo", fr: "vi", sa: "sa"}, + monthLabels: { 1: "ian", 2: "feb", 3: "mart", 4: "apr", 5: "mai", 6: "iun", 7: "iul", 8: "aug", 9: "sept", 10: "oct", 11: "nov", 12: "dec" }, + dateFormat: "dd.mm.yyyy", + todayBtnTxt: "Astăzi", + firstDayOfWeek: "mo", + sunHighlight: true, + }, + "ca": { + dayLabels: {su: "dg", mo: "dl", tu: "dt", we: "dc", th: "dj", fr: "dv", sa: "ds"}, + monthLabels: {1: "Gen", 2: "Febr", 3: "Març", 4: "Abr", 5: "Maig", 6: "Juny", 7: "Jul", 8: "Ag", 9: "Set", 10: "Oct", 11: "Nov", 12: "Des"}, + dateFormat: "dd.mm.yyyy", + todayBtnTxt: "Avui", + firstDayOfWeek: "mo", + sunHighlight: true, + }, + "id": { + dayLabels: {su: "Min", mo: "Sen", tu: "Sel", we: "Rab", th: "Kam", fr: "Jum", sa: "Sab"}, + monthLabels: {1: "Jan", 2: "Feb", 3: "Mar", 4: "Apr", 5: "Mei", 6: "Jun", 7: "Jul", 8: "Ags", 9: "Sep", 10: "Okt", 11: "Nov", 12: "Des"}, + dateFormat: "dd-mm-yyyy", + todayBtnTxt: "Hari ini", + firstDayOfWeek: "su", + sunHighlight: true + }, + "en-au": { + dayLabels: {su: "Sun", mo: "Mon", tu: "Tue", we: "Wed", th: "Thu", fr: "Fri", sa: "Sat"}, + monthLabels: { 1: "Jan", 2: "Feb", 3: "Mar", 4: "Apr", 5: "May", 6: "Jun", 7: "Jul", 8: "Aug", 9: "Sep", 10: "Oct", 11: "Nov", 12: "Dec" }, + dateFormat: "dd/mm/yyyy", + todayBtnTxt: "Today", + firstDayOfWeek: "mo", + sunHighlight: true + }, + "am-et": { + dayLabels: {su: "እሑድ", mo: "ሰኞ", tu: "ማክሰኞ", we: "ረቡዕ", th: "ሐሙስ", fr: "ዓርብ", sa: "ቅዳሜ"}, + monthLabels: { 1: "ጃንዩ", 2: "ፌብሩ", 3: "ማርች", 4: "ኤፕረ", 5: "ሜይ", 6: "ጁን", 7: "ጁላይ", 8: "ኦገስ", 9: "ሴፕቴ", 10: "ኦክተ", 11: "ኖቬም", 12: "ዲሴም" }, + dateFormat: "yyyy-mm-dd", + todayBtnTxt: "ዛሬ", + firstDayOfWeek: "mo", + sunHighlight: true + } + }; + + getLocaleOptions(locale: string): IMyOptions { + if (locale && this.locales.hasOwnProperty(locale)) { + // User given locale + return this.locales[locale]; + } + // Default: en + return this.locales["en"]; + } +} diff --git a/portal-4cli/src/app/utils/my-date-picker/services/my-date-picker.util.service.ts b/portal-4cli/src/app/utils/my-date-picker/services/my-date-picker.util.service.ts new file mode 100644 index 00000000..98b51bca --- /dev/null +++ b/portal-4cli/src/app/utils/my-date-picker/services/my-date-picker.util.service.ts @@ -0,0 +1,169 @@ +import { Injectable } from "@angular/core"; +import { IMyDate } from "../interfaces/my-date.interface"; +import { IMyDateRange } from "../interfaces/my-date-range.interface"; +import { IMyMonth } from "../interfaces/my-month.interface"; +import { IMyMonthLabels } from "../interfaces/my-month-labels.interface"; + +@Injectable() +export class UtilService { + isDateValid(dateStr: string, dateFormat: string, minYear: number, maxYear: number, disableUntil: IMyDate, disableSince: IMyDate, disableWeekends: boolean, disableDays: Array, disableDateRange: IMyDateRange, monthLabels: IMyMonthLabels, enableDays: Array): IMyDate { + let returnDate: IMyDate = {day: 0, month: 0, year: 0}; + let daysInMonth: Array = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; + let isMonthStr: boolean = this.getDatePartIndex(dateFormat, "mmm") !== -1; + + if (dateStr.length !== dateFormat.length) { + return returnDate; + } + + let separator: string = this.getDateFormatSeparator(dateFormat); + + let parts: Array = dateStr.split(separator); + if (parts.length !== 3) { + return returnDate; + } + + let day: number = this.parseDatePartNumber(dateFormat, dateStr, "dd"); + let month: number = isMonthStr ? this.parseDatePartMonthName(dateFormat, dateStr, "mmm", monthLabels) : this.parseDatePartNumber(dateFormat, dateStr, "mm"); + let year: number = this.parseDatePartNumber(dateFormat, dateStr, "yyyy"); + + if (day !== -1 && month !== -1 && year !== -1) { + if (year < minYear || year > maxYear || month < 1 || month > 12) { + return returnDate; + } + + let date: IMyDate = {year: year, month: month, day: day}; + + if (this.isDisabledDay(date, disableUntil, disableSince, disableWeekends, disableDays, disableDateRange, enableDays)) { + return returnDate; + } + + if (year % 400 === 0 || (year % 100 !== 0 && year % 4 === 0)) { + daysInMonth[1] = 29; + } + + if (day < 1 || day > daysInMonth[month - 1]) { + return returnDate; + } + + // Valid date + return date; + } + return returnDate; + } + + getDateFormatSeparator(dateFormat: string): string { + return dateFormat.replace(/[dmy]/g, "")[0]; + } + + isMonthLabelValid(monthLabel: string, monthLabels: IMyMonthLabels): number { + for (let key = 1; key <= 12; key++) { + if (monthLabel.toLowerCase() === monthLabels[key].toLowerCase()) { + return key; + } + } + return -1; + } + + isYearLabelValid(yearLabel: number, minYear: number, maxYear: number): number { + if (yearLabel >= minYear && yearLabel <= maxYear) { + return yearLabel; + } + return -1; + } + + parseDatePartNumber(dateFormat: string, dateString: string, datePart: string): number { + let pos: number = this.getDatePartIndex(dateFormat, datePart); + if (pos !== -1) { + let value: string = dateString.substring(pos, pos + datePart.length); + if (!/^\d+$/.test(value)) { + return -1; + } + return parseInt(value); + } + return -1; + } + + parseDatePartMonthName(dateFormat: string, dateString: string, datePart: string, monthLabels: IMyMonthLabels): number { + let pos: number = this.getDatePartIndex(dateFormat, datePart); + if (pos !== -1) { + return this.isMonthLabelValid(dateString.substring(pos, pos + datePart.length), monthLabels); + } + return -1; + } + + getDatePartIndex(dateFormat: string, datePart: string): number { + return dateFormat.indexOf(datePart); + } + + parseDefaultMonth(monthString: string): IMyMonth { + let month: IMyMonth = {monthTxt: "", monthNbr: 0, year: 0}; + if (monthString !== "") { + let split = monthString.split(monthString.match(/[^0-9]/)[0]); + month.monthNbr = split[0].length === 2 ? parseInt(split[0]) : parseInt(split[1]); + month.year = split[0].length === 2 ? parseInt(split[1]) : parseInt(split[0]); + } + return month; + } + + isDisabledDay(date: IMyDate, disableUntil: IMyDate, disableSince: IMyDate, disableWeekends: boolean, disableDays: Array, disableDateRange: IMyDateRange, enableDays: Array): boolean { + for (let obj of enableDays) { + if (obj.year === date.year && obj.month === date.month && obj.day === date.day) { + return false; + } + } + + let dateMs: number = this.getTimeInMilliseconds(date); + if (this.isInitializedDate(disableUntil) && dateMs <= this.getTimeInMilliseconds(disableUntil)) { + return true; + } + + if (this.isInitializedDate(disableSince) && dateMs >= this.getTimeInMilliseconds(disableSince)) { + return true; + } + + if (disableWeekends) { + let dayNbr = this.getDayNumber(date); + if (dayNbr === 0 || dayNbr === 6) { + return true; + } + } + + for (let obj of disableDays) { + if (obj.year === date.year && obj.month === date.month && obj.day === date.day) { + return true; + } + } + + if (this.isInitializedDate(disableDateRange.begin) && this.isInitializedDate(disableDateRange.end) && dateMs >= this.getTimeInMilliseconds(disableDateRange.begin) && dateMs <= this.getTimeInMilliseconds(disableDateRange.end)) { + return true; + } + return false; + } + + getWeekNumber(date: IMyDate): number { + let d: Date = new Date(date.year, date.month - 1, date.day, 0, 0, 0, 0); + d.setDate(d.getDate() + (d.getDay() === 0 ? -3 : 4 - d.getDay())); + return Math.round(((d.getTime() - new Date(d.getFullYear(), 0, 4).getTime()) / 86400000) / 7) + 1; + } + + isMonthDisabledByDisableUntil(date: IMyDate, disableUntil: IMyDate): boolean { + return this.isInitializedDate(disableUntil) && this.getTimeInMilliseconds(date) <= this.getTimeInMilliseconds(disableUntil); + } + + isMonthDisabledByDisableSince(date: IMyDate, disableSince: IMyDate): boolean { + return this.isInitializedDate(disableSince) && this.getTimeInMilliseconds(date) >= this.getTimeInMilliseconds(disableSince); + } + + isInitializedDate(date: IMyDate): boolean { + return date.year !== 0 && date.month !== 0 && date.day !== 0; + } + + getTimeInMilliseconds(date: IMyDate): number { + return new Date(date.year, date.month - 1, date.day, 0, 0, 0, 0).getTime(); + } + + getDayNumber(date: IMyDate): number { + let d: Date = new Date(date.year, date.month - 1, date.day, 0, 0, 0, 0); + return d.getDay(); + } +} \ No newline at end of file diff --git a/portal-4cli/src/app/utils/number-utils.class.ts b/portal-4cli/src/app/utils/number-utils.class.ts new file mode 100644 index 00000000..bc6e25ce --- /dev/null +++ b/portal-4cli/src/app/utils/number-utils.class.ts @@ -0,0 +1,31 @@ + +export class NumberUtils{ + + + + public static roundNumber(num: number):any { + console.log("Trying to round number: "+ num); + var roundNum = null; + if(num >= 1000000){ + num=num/1000000; + num= Math.round(num); + roundNum = { "number": num, "size": "mi" }; + }else if( num >= 10000){ + num=num/1000; + num= Math.round(num); + roundNum = { "number": num, "size": "K" }; + }else if (num >= 100) { + num=num/100; + num= Math.round(num); + num=num*100; + roundNum = { "number": num, "size": "" }; + }else{ + roundNum = { "number": num, "size": "" }; + } + console.log("Rounded number: "+ roundNum.number + " "+ roundNum.size); + return roundNum; + } + + + +} diff --git a/portal-4cli/src/app/utils/paging.module.ts b/portal-4cli/src/app/utils/paging.module.ts new file mode 100644 index 00000000..dbf53c87 --- /dev/null +++ b/portal-4cli/src/app/utils/paging.module.ts @@ -0,0 +1,28 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import {pagingFormatterNoLoad} from './pagingFormatterNoLoad.component'; + +import {PagingFormatter} from './pagingFormatter.component'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule, RouterModule + ], + declarations: [ + pagingFormatterNoLoad, + PagingFormatter, + + + ], + exports: [ + pagingFormatterNoLoad, + PagingFormatter, + + + ] +}) +export class PagingModule { } diff --git a/portal-4cli/src/app/utils/pagingFormatter.component.ts b/portal-4cli/src/app/utils/pagingFormatter.component.ts new file mode 100644 index 00000000..f199aaa9 --- /dev/null +++ b/portal-4cli/src/app/utils/pagingFormatter.component.ts @@ -0,0 +1,64 @@ +import {Component, Input} from '@angular/core'; +import {Router} from '@angular/router'; +import {DomSanitizer} from '@angular/platform-browser'; +//Usage Example +import {RouterHelper} from './routerHelper.class'; + +@Component({ + selector: 'paging', + template: ` + + + + ` +}) + +export class PagingFormatter { + @Input() currentPage: number = 1; + @Input() size: number=10; + @Input() totalResults: number = 10; + @Input() baseUrl:string=""; + @Input() parameterNames:string[]; + @Input() parameterValues:string[]; + + public routerHelper:RouterHelper = new RouterHelper(); + + constructor ( private _router: Router, private sanitizer:DomSanitizer) { + } + + ngOnInit() { + + } + getTotalPages(){ + var i:number =parseInt(''+(this.totalResults/this.size)); + return (((this.totalResults/this.size) == i )? i :(i+1)) ; + } + + // onPage(pageNum: number){ + // return this.sanitizer.bypassSecurityTrustUrl( this.baseUrl+((this.baseUrl.indexOf("?") > -1 )?'&':'?')+ "page=" + (pageNum)); + // + // } +} diff --git a/portal-4cli/src/app/utils/pagingFormatterNoLoad.component.ts b/portal-4cli/src/app/utils/pagingFormatterNoLoad.component.ts new file mode 100644 index 00000000..2ae49f49 --- /dev/null +++ b/portal-4cli/src/app/utils/pagingFormatterNoLoad.component.ts @@ -0,0 +1,76 @@ +import {Component, Input, Output, EventEmitter} from '@angular/core'; + + +//Usage Example + +@Component({ + selector: 'paging-no-load', + template: ` + + + ` +}) + +export class pagingFormatterNoLoad { + @Input() public currentPage: number = 1; + // @Input() public navigateTo: string; + @Input() public term: string=''; + @Input() public size: number=10; + @Input() public totalResults: number = 10; + // @Input() public params; + + @Output() pageChange = new EventEmitter(); + + constructor () { + } + + ngOnInit() { + console.info("In paging -- CurrentPage:"+this.currentPage+" "+"total Pages = "+this.getTotalPages() +" Results num:"+this.totalResults); + } + getTotalPages(){ + var i= this.totalResults/this.size; + var integerI=parseInt(''+i); + return parseInt(''+((i==integerI)?i:i+1)); + } + onPrev(){ + this.currentPage=this.currentPage-1; + this.pageChange.emit({ + value: this.currentPage + }); + + } + + onNext(){ + + this.currentPage=this.currentPage+1; + this.pageChange.emit({ + value: this.currentPage + }); + } + onPage(pageNum: number){ + + this.currentPage=pageNum; + this.pageChange.emit({ + value: this.currentPage + }); + } +} diff --git a/portal-4cli/src/app/utils/pipes/claimsDatatable.pipe.ts b/portal-4cli/src/app/utils/pipes/claimsDatatable.pipe.ts new file mode 100644 index 00000000..d05ca549 --- /dev/null +++ b/portal-4cli/src/app/utils/pipes/claimsDatatable.pipe.ts @@ -0,0 +1,48 @@ +import { Pipe, PipeTransform} from '@angular/core' + + +@Pipe({ + name: 'claimsDatatable' +}) +export class ClaimsDatatablePipe implements PipeTransform { + + transform(array: any[], args: any[]): any { + let query: string = args[0]; + let counter:any = args[1]; + let active: any = args[2]; + + active.page = 1; + + if (query) { + var result = array.filter(row=>this.filterAll(row, query)); + counter.count = result.length; + return result; + } + return array; + } + + filterAll(row: any, query: string) { + if(row.userMail.indexOf(query) > -1) { + return true; + } + if(row.targetType != 'project' && row.target.title.indexOf(query) > -1) { + return true; + } + if(row.sourceType != 'project' && row.source.title.indexOf(query) > -1) { + return true; + } + if(row.date.indexOf(query) > -1) { + return true; + } + + if(row.curatedBy != null && row.curatedBy.indexOf(query) > -1) { + return true; + } + + if(row.curationDate != null && row.curationDate.indexOf(query) > -1) { + return true; + } + + return false; + } +} diff --git a/portal-4cli/src/app/utils/pipes/contentProvidersDatatable.pipe.ts b/portal-4cli/src/app/utils/pipes/contentProvidersDatatable.pipe.ts new file mode 100644 index 00000000..6041d590 --- /dev/null +++ b/portal-4cli/src/app/utils/pipes/contentProvidersDatatable.pipe.ts @@ -0,0 +1,107 @@ +import { Pipe, PipeTransform} from '@angular/core'; +import { Filter, Value} from '../../searchPages/searchUtils/searchHelperClasses.class'; +import { SearchUtilsClass } from '../../searchPages/searchUtils/searchUtils.class'; +import { ErrorCodes} from '../properties/openaireProperties'; + +@Pipe({ + name: 'contentProvidersDatatable' +}) +export class ContentProvidersDatatablePipe implements PipeTransform { + + transform(array: any[], args: any[]): any { + if(array.length > 0) { + let searchUtils: SearchUtilsClass = args[0]; + let filters:Filter[] = args[1]; + + + var errorCodes:ErrorCodes = new ErrorCodes(); + searchUtils.status = errorCodes.LOADING; + + var result = array.filter(row=>this.filterAll(row, searchUtils.keyword.toLowerCase(), filters)); + + searchUtils.totalResults = result.length; + + var errorCodes:ErrorCodes = new ErrorCodes(); + searchUtils.status = errorCodes.DONE; + if(searchUtils.totalResults == 0 ){ + searchUtils.status = errorCodes.NONE; + } + return result; + } + return []; + } + + filterAll(row: any, query: string, filters:Filter[]) { + let returnValue: boolean = false; + + if(query) { + if(row.title.name.toLowerCase().indexOf(query) > -1) { + returnValue = true; + } + + if(row.type.toLowerCase().indexOf(query) > -1) { + returnValue = true; + } + + if(row.countries && row.countries.length > 0) { + for(let country of row.countries) { + if(country.toLowerCase().indexOf(query) > -1) { + returnValue = true; + break; + } + } + } + + if(row.compatibility && row.compatibility.toLowerCase().indexOf(query) > -1) { + returnValue = true; + } + + if(row.organizations && row.organizations.length > 0) { + for(let organization of row.organizations) { + if(organization.name.toLowerCase().indexOf(query) > -1) { + returnValue = true; + break; + } + } + } + + if(!returnValue) { + return false; + } + } + + for (let filter of filters){ + if(filter.countSelectedValues > 0){ + for (let value of filter.values){ + if(value.selected == true){ + + // make it generic in future commit + let field:string = ""; + if(filter.title == "Type") { + field = "type"; + } else if(filter.title == "Compatibility Level") { + field = "compatibility"; + } + + if(row[field] == value.name) { + returnValue = true; + if(filter.filterOperator == "or") { + break; + } + } else { + if(filter.filterOperator == "and") { + return false; + } + returnValue = false; + } + } + } + if(!returnValue) { + return false; + } + } + } + + return true; + } +} diff --git a/portal-4cli/src/app/utils/pipes/safeHTML.pipe.ts b/portal-4cli/src/app/utils/pipes/safeHTML.pipe.ts new file mode 100644 index 00000000..5912a07c --- /dev/null +++ b/portal-4cli/src/app/utils/pipes/safeHTML.pipe.ts @@ -0,0 +1,13 @@ +//our root app component +import { Pipe, PipeTransform} from '@angular/core' + +import { DomSanitizer } from '@angular/platform-browser' + + +@Pipe({ name: 'safeHtml'}) +export class SafeHtmlPipe implements PipeTransform { + constructor(private sanitized: DomSanitizer) {} + transform(value) { + return this.sanitized.bypassSecurityTrustHtml(value); + } +} diff --git a/portal-4cli/src/app/utils/piwik/piwik.service.ts b/portal-4cli/src/app/utils/piwik/piwik.service.ts new file mode 100644 index 00000000..c3c17746 --- /dev/null +++ b/portal-4cli/src/app/utils/piwik/piwik.service.ts @@ -0,0 +1,70 @@ +import {Injectable} from '@angular/core'; +import {Http, Response, Headers, RequestOptions, URLSearchParams} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; +import {Location} from '@angular/common'; + +import {OpenaireProperties} from '../properties/openaireProperties'; +import {StringUtils} from '../string-utils.class'; + + +@Injectable() +export class PiwikService { + private piwikbaseUrl:string = ""; + constructor(private http: Http, private location: Location ) {} + + trackView (title):any { + + var ua = this.getUserAgent(); + var referrer = this.getReferrer(); + if(typeof location !== 'undefined'){ + var url = OpenaireProperties.getPiwikBaseURL()+"&rec=1&url="+StringUtils.URIEncode(location.href)+"&action_name="+StringUtils.URIEncode(title)+ + ((ua != null && ua.length > 0)?('&ua='+StringUtils.URIEncode(ua)):'')+ + ((referrer != null && referrer.length > 0)?('&urlref='+StringUtils.URIEncode(referrer)):''); + console.log("Piwik - View: " + url); + + return this.http.get( url); + // .do(request => console.info("Piwik request completed" )); + + } + } + trackDownload (downloadURL):any { + var ua = this.getUserAgent(); + var referrer = this.getReferrer(); + var url = OpenaireProperties.getPiwikBaseURL()+"&rec=1&url="+StringUtils.URIEncode(downloadURL)+"&download="+StringUtils.URIEncode(downloadURL)+ + ((ua != null && ua.length > 0)?('&ua='+StringUtils.URIEncode(ua)):'')+ + ((referrer != null && referrer.length > 0)?('&urlref='+StringUtils.URIEncode(referrer)):''); + console.log("Piwik - trackDownload: "+url); + + return this.http.get( url) + .do(request => console.info("Piwik request completed" )); + + } + private getUserAgent(){ + if (typeof navigator !== 'undefined') { + console.log("navigator.userAgent:" + navigator.userAgent); + return navigator.userAgent; + + }else{ + return null; + } + } + private getReferrer(){ + var referrer = ""; + if (typeof document !== 'undefined') { + console.log("document.referrer:" + document.referrer); + referrer = document.referrer; + + } + if((referrer == null || referrer.length == 0)&&typeof localStorage !== 'undefined'){ + + referrer =localStorage.getItem('previousRoute'); + } + return referrer; + } + parse(data:any){ + } + +} diff --git a/portal-4cli/src/app/utils/piwik/piwikService.module.ts b/portal-4cli/src/app/utils/piwik/piwikService.module.ts new file mode 100644 index 00000000..0cfe47e3 --- /dev/null +++ b/portal-4cli/src/app/utils/piwik/piwikService.module.ts @@ -0,0 +1,21 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {PiwikService} from './piwik.service'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule, + + ], + declarations: [ + + ], + providers: [ PiwikService ], + exports: [ + + ] +}) +export class PiwikServiceModule{ } diff --git a/portal-4cli/src/app/utils/piwik/previousRouteRecorder.guard.ts b/portal-4cli/src/app/utils/piwik/previousRouteRecorder.guard.ts new file mode 100644 index 00000000..ae62b524 --- /dev/null +++ b/portal-4cli/src/app/utils/piwik/previousRouteRecorder.guard.ts @@ -0,0 +1,17 @@ + +import { Injectable } from '@angular/core'; +import { CanDeactivate, Router} from '@angular/router'; +import {Observable} from 'rxjs/Observable'; + +@Injectable() // do not forget to register this class as a provider +export class PreviousRouteRecorder implements CanDeactivate { + constructor(private router: Router) { + } + canDeactivate(component: any): Observable | boolean { + if (typeof localStorage !== 'undefined') { + console.log("In PreviousRouteRecorder : "+this.router.url ); + localStorage.setItem('previousRoute', this.router.url); + } + return true; + } +} diff --git a/portal-4cli/src/app/utils/properties/openaireProperties.ts b/portal-4cli/src/app/utils/properties/openaireProperties.ts new file mode 100644 index 00000000..3a623a83 --- /dev/null +++ b/portal-4cli/src/app/utils/properties/openaireProperties.ts @@ -0,0 +1,397 @@ +export class OpenaireProperties { + private static productionMode:boolean = false; + + //base url + private static baseLink = "https://demo.openaire.eu"; + + //landing Pages + private static baseSearchLink="/"; + private static searchLinkToPublication = "search/publication?articleId="; + private static searchLinkToProject = "search/project?projectId="; + private static searchLinkToDataProvider = "search/dataprovider?datasourceId="; + private static searchLinkToDataset = "search/dataset?datasetId="; + private static searchLinkToOrganization = "search/organization?organizationId="; + //Search pages + private static searchLinkToPublications = "search/find/publications"; + private static searchLinkToDataProviders = "search/find/dataproviders"; + private static searchLinkToProjects = "search/find/projects"; + private static searchLinkToDatasets = "search/find/datasets"; + private static searchLinkToSoftware = "search/find/software"; + private static searchLinkToOrganizations = "search/find/organizations"; + private static searchLinkToPeople = "search/find/people"; + public static searchLinkToCompatibleDataProviders = "search/content-providers"; + public static searchLinkToCompatibleDataProvidersTable = "search/content-providers-table"; + public static searchLinkToEntityRegistriesDataProviders = "search/entity-registries"; + public static searchLinkToEntityRegistriesDataProvidersTable = "search/entity-registries-table"; + public static searchLinkToJournals = "search/journals"; + public static searchLinkToJournalsTable = "search/journals-table"; + + //Advanced Search for pages + public static searchLinkToAdvancedPublications = "search/advanced/publications"; + public static searchLinkToAdvancedProjects = "search/advanced/projects"; + public static searchLinkToAdvancedDatasets = "search/advanced/datasets"; + public static searchLinkToAdvancedSoftware = "search/advanced/software"; + public static searchLinkToAdvancedDataProviders = "search/advanced/dataproviders"; + public static searchLinkToAdvancedOrganizations = "search/advanced/organizations"; + public static searchLinkToAdvancedPeople = "search/advanced/people"; + + + private static metricsAPIURL = "https://beta.services.openaire.eu/usagestats/"; + private static framesAPIURL = "https://beta.openaire.eu/stats3/"; + + private static loginAPIURL = "http://rudie.di.uoa.gr:8080/dnet%2Dopenaire%2Dusers%2D1.0.0%2DSNAPSHOT/api/users/authenticates" + //"http://scoobydoo.di.uoa.gr:8080/uoa-user-management-1.0.0-SNAPSHOT/api/users/authenticates"; + private static loginAPIURL_pm = "https://beta.services.openaire.eu/uoa-user-management/api/users/authenticates"; + + private static claimsAPIURL = "http://scoobydoo.di.uoa.gr:8080/dnet-claims-service-2.0.0-SNAPSHOT/rest/claimsService/"; + private static claimsAPIURL_pm = "https://beta.services.openaire.eu/claims/rest/claimsService/"; + + private static searchAPIURLLAst_pm = "https://beta.services.openaire.eu/search/v2/api/"; + private static searchAPIURLLAst = "https://beta.services.openaire.eu/search/v2/api/"; +// private static searchAPIURLLAst = "http://scoobydoo.di.uoa.gr:8080/dnet-functionality-services-2.0.0-SNAPSHOT/rest/v2/api/"; + + private static searchResourcesAPIURL_pm = "https://beta.services.openaire.eu/search/v2/api/resources"; + private static searchResourcesAPIURL = "https://beta.services.openaire.eu/search/v2/api/resources"; + // private static searchResourcesAPIURL = "http://scoobydoo.di.uoa.gr:8080/dnet-functionality-services-2.0.0-SNAPSHOT/rest/v2/api/resources"; + + + private static csvAPIURL_pm = "https://beta.services.openaire.eu/search/v2/api/";//publications?format=csv + // private static csvAPIURL = "http://rudie.di.uoa.gr:8080/dnet-functionality-services-2.0.0-SNAPSHOT/rest/v2/api/";//publications?format=csv + + private static csvAPIURL = "https://beta.services.openaire.eu/search/v2/api/";//publications?format=csv + + private static searchCrossrefAPIURL = "https://api.crossref.org/works"; + // private static searchDataciteAPIURL = "https://search.datacite.org/api"; + private static searchDataciteAPIURL = "https://api.datacite.org/works"; + + private static searchOrcidURL = "https://pub.orcid.org/"; + + // Identifiers + private static pmidURL = "http://www.ncbi.nlm.nih.gov/pubmed/"; + private static doiURL = "https://dx.doi.org/"; + private static cordisURL = "http://cordis.europa.eu/projects/"; + private static pmcURL = "http://europepmc.org/articles/"; + private static handleURL = "http://hdl.handle.net/"; + + // Zenodo's url + private static zenodo = "https://zenodo.org/"; + // Open access link + private static openAccess = "https://www.openaire.eu/support/faq#article-id-234"; + // Open access repository link + private static openAccessRepo = "https://www.openaire.eu/support/faq#article-id-310"; + // FP7 link + private static fp7Guidlines = "https://www.openaire.eu/open-access-in-fp7-seventh-research-framework-programme"; + // H2020 link + private static h2020Guidlines = "https://www.openaire.eu/oa-publications/h2020/open-access-in-horizon-2020"; + // ERC Guidlines + private static ercGuidlines = "http://erc.europa.eu/sites/default/files/document/file/ERC_Open_Access_Guidelines-revised_2014.pdf"; + // helpdesk link + private static helpdesk = "https://www.openaire.eu/support/helpdesk"; + + private static uploadService_pm = "https://demo.openaire.eu/upload"; + private static uploadService = "http://scoobydoo.di.uoa.gr:8000/upload"; + + private static vocabulariesAPI ="https://beta.services.openaire.eu/provision/mvc/vocabularies/"; + + private static piwikBaseUrl =" https://analytics.openaire.eu/piwik.php?idsite=6"; + private static enablePiwikTrack:boolean = false; + + private static loginUrl ="http://mpagasas.di.uoa.gr:8080/dnet-openaire-users-1.0.0-SNAPSHOT/openid_connect_login"; + private static loginUrl_pm ="https://beta.services.openaire.eu/uoa-user-management/openid_connect_login"; + + private static logoutUrl ="https://aai.openminted.eu/proxy/saml2/idp/SingleLogoutService.php?ReturnTo="; + private static logoutUrl_pm ="https://aai.openminted.eu/proxy/saml2/idp/SingleLogoutService.php?ReturnTo="; + + private static cookieDomain =".di.uoa.gr"; + private static cookieDomain_pm =".openaire.eu"; + + private static feedbackmail ="openaire.test@gmail.com"; + + private static helperPageUrl ="http://scoobydoo.di.uoa.gr:16000/api/page/route"; + private static enableHelper:boolean = false; + + private static cache ="http://scoobydoo.di.uoa.gr:3000/get?url="; + private static useCache:boolean = true; + + public static getBaseLink():string{ + return this.baseLink; + } + + //landing Pages' getters + public static getsearchLinkToPublication():string{ + return this.baseSearchLink + this.searchLinkToPublication; + } + public static getsearchLinkToDataset():string{ + return this.baseSearchLink + this.searchLinkToDataset; + } + public static getsearchLinkToProject():string{ + return this.baseSearchLink + this.searchLinkToProject; + } + + public static getsearchLinkToOrganization():string{ + return this.searchLinkToOrganization; + } + public static getsearchLinkToDataProvider():string{ + return this.searchLinkToDataProvider; + } + //searchPages + public static getLinkToSearchPublications():string{ + return this.baseSearchLink + this.searchLinkToPublications; + } + public static getLinkToSearchProjects():string{ + return this.baseSearchLink + this.searchLinkToProjects; + } + public static getLinkToSearchDataProviders():string{ + return this.baseSearchLink + this.searchLinkToDataProviders; + } + public static getLinkToSearchCompatibleDataProviders():string{ + return this.baseSearchLink + this.searchLinkToCompatibleDataProviders; + } + public static getLinkToSearchCompatibleDataProvidersTable():string{ + return this.baseSearchLink + this.searchLinkToCompatibleDataProvidersTable; + } + public static getLinkToSearchEntityRegistries():string{ + return this.baseSearchLink + this.searchLinkToEntityRegistriesDataProviders; + } + public static getLinkToSearchEntityRegistriesTable():string{ + return this.baseSearchLink + this.searchLinkToEntityRegistriesDataProvidersTable; + } + public static getLinkToSearchJournals():string{ + return this.baseSearchLink + this.searchLinkToJournals; + } + public static getLinkToSearchJournalsTable():string{ + return this.baseSearchLink + this.searchLinkToJournalsTable; + } + public static getLinkToSearchDatasets():string{ + return this.baseSearchLink + this.searchLinkToDatasets; + } + public static getLinkToSearchSoftware():string{ + return this.baseSearchLink + this.searchLinkToSoftware; + } + public static getLinkToSearchOrganizations():string{ + return this.baseSearchLink + this.searchLinkToOrganizations; + } + public static getLinkToSearchPeople():string{ + return this.baseSearchLink + this.searchLinkToPeople; + } + + //Advanced searchPages + public static getLinkToAdvancedSearchPublications():string{ + return this.baseSearchLink + this.searchLinkToAdvancedPublications; + } + public static getLinkToAdvancedSearchProjects():string{ + return this.baseSearchLink + this.searchLinkToAdvancedProjects; + } + public static getLinkToAdvancedSearchDataProviders():string{ + return this.baseSearchLink + this.searchLinkToAdvancedDataProviders; + } + public static getLinkToAdvancedSearchDatasets():string{ + return this.baseSearchLink + this.searchLinkToAdvancedDatasets; + } + public static getLinkToAdvancedSearchSoftware():string{ + return this.baseSearchLink + this.searchLinkToAdvancedSoftware; + } + public static getLinkToAdvancedSearchOrganizations():string{ + return this.baseSearchLink + this.searchLinkToAdvancedOrganizations; + } + public static getLinkToAdvancedSearchPeople():string{ + return this.baseSearchLink + this.searchLinkToAdvancedPeople; + } + + // Services - APIs' getters + // public static getSearchAPIURL():string{ + // return this.searchAPIURL; + // } + // Services - APIs' getters + public static getCsvAPIURL(): string { + if(this.productionMode){ + return this.csvAPIURL_pm; + }else{ + return this.csvAPIURL; + } + // return this.csvAPIURL; + } + + public static getFramesAPIURL(): string { + return this.framesAPIURL; + } + + public static getMetricsAPIURL(): string { + return this.metricsAPIURL; + } + + public static getLoginAPIURL(): string { + if(this.productionMode){ + return this.loginAPIURL_pm; + }else{ + return this.loginAPIURL; + } + // return this.loginAPIURL; + } + + public static getSearchAPIURLLast():string{ + if(this.productionMode){ + return this.searchAPIURLLAst_pm; + }else{ + return this.searchAPIURLLAst; + } + // return this.searchAPIURLLAst; + } + //query using full query: + // + public static getSearchResourcesAPIURL():string{ + if(this.productionMode){ + return this.searchResourcesAPIURL_pm; + }else{ + return this.searchResourcesAPIURL; + } + // return this.searchResourcesAPIURL; + } + public static getSearchAPIURLForEntity(entityType:string):string{ + var suffix = ""; + if(entityType == "project"){ + suffix="projects/"; + }else if(entityType == "publication"){ + suffix="publications/"; + }else if(entityType == "dataset"){ + suffix="datasets/"; + } else if(entityType == "software"){ + suffix="software/"; + }else if(entityType == "organization"){ + suffix="organizations/"; + }else if(entityType == "dataprovider"){ + suffix="datasources/"; + }else if(entityType == "person"){ + suffix="people/"; + } + return (this.productionMode?this.searchAPIURLLAst_pm:this.searchAPIURLLAst) + suffix; + } + + public static getClaimsAPIURL():string{ + if(this.productionMode){ + return this.claimsAPIURL_pm; + }else{ + return this.claimsAPIURL; + } + } + public static getSearchCrossrefAPIURL():string{ + return this.searchCrossrefAPIURL; + } + public static getSearchDataciteAPIURL():string{ + return this.searchDataciteAPIURL; + } + public static getSearchOrcidURL():string{ + return this.searchOrcidURL; + } + + // Identifiers' getters + public static getPmidURL():string{ + return this.pmidURL; + } + public static getDoiURL():string{ + return this.doiURL; + } + public static getCordisURL():string{ + return this.cordisURL; + } + public static getPmcURL():string{ + return this.pmcURL; + } + public static getHandleURL():string{ + return this.handleURL; + } + + // Zenodo's getter + public static getZenodoURL():string{ + return this.zenodo; + } + // Open access getter + public static getOpenAccess():string{ + return this.openAccess; + } + // Open access repository getter + public static getOpenAccessRepo():string{ + return this.openAccessRepo; + } + // FP7 link getter + public static getFP7Guidlines():string{ + return this.fp7Guidlines; + } + // H2020 link getter + public static getH2020Guidlines():string{ + return this.h2020Guidlines; + } + // ERC Guidlines getter + public static getERCGuidlines():string{ + return this.ercGuidlines; + } + // helpdesk link getter + public static getHelpdesk():string{ + return this.helpdesk; + } + + + //upload service for bulk claim - upload csv file + public static getUploadServiceUrl():string{ + if(this.productionMode){ + return this.uploadService_pm; + }else{ + return this.uploadService; + } + } + //vocabularies API + public static getVocabulariesAPI():string{ + return this.vocabulariesAPI; + } + public static getPiwikBaseURL():string{ + return this.piwikBaseUrl; + } + public static isPiwikTrackEnabled():boolean{ + return this.enablePiwikTrack; + } + public static getLoginURL():string{ + if(this.productionMode){ + return this.loginUrl_pm; + }else{ + return this.loginUrl; + } + } + public static getLogoutURL():string{ + if(this.productionMode){ + return this.logoutUrl_pm; + }else{ + return this.logoutUrl; + } + } + public static getCookieDomain():string{ + if(this.productionMode){ + return this.cookieDomain_pm; + }else{ + return this.cookieDomain; + } + } + public static getFeedbackMail():string{ + return this.feedbackmail; + } + public static getHelperPageUrl():string{ + return this.helperPageUrl; + } + public static isHelperEnabled():boolean{ + return this.enableHelper; + } + public static getCacheUrl():string{ + return this.cache; + } + public static isCacheEnabled():boolean{ + return this.useCache; + } +} +export class ErrorCodes { + public LOADING = 0; + public DONE = 1; + public NONE = 2; + public ERROR = 3; + public NOT_AVAILABLE = 4; + public OUT_OF_BOUND = 5; + public NOT_FOUND = 6; +} diff --git a/portal-4cli/src/app/utils/properties/searchFields.ts b/portal-4cli/src/app/utils/properties/searchFields.ts new file mode 100644 index 00000000..42589c28 --- /dev/null +++ b/portal-4cli/src/app/utils/properties/searchFields.ts @@ -0,0 +1,159 @@ +export class SearchFields { + //main Entities + //RESULTS + //Used for datasets and publications + //In case Datasets should display different fields, use seperate tables for fields + public RESULT_REFINE_FIELDS = [ + "relfunder", + "relfundinglevel0_id","relfundinglevel1_id","relfundinglevel2_id", + "relproject","resultacceptanceyear", + "resultbestaccessright", "instancetypename", "resultlanguagename", "community","resulthostingdatasource"]; + + public RESULT_ADVANCED_FIELDS:string[] = ["q","resulttitle","resultauthor","resultpublisher","instancetypename", + "resultlanguagename", "community","relprojectid", "relfunder", + "relfundinglevel0_id","relfundinglevel1_id","relfundinglevel2_id", + "resultdateofacceptance","resultbestaccessright","pid","resulthostingdatasourceid","collectedfromdatasourceid", "relorganizationid"]; + public RESULT_FIELDS: { [key:string]:FieldDetails}={ + ["q"]:{name:"All fields", type:"keyword", param:"q", equalityOperator: "="}, + ["resulttitle"]:{name:"Title", type:"keyword", param:"title", equalityOperator: "="}, + ["resultauthor"]:{name:"Author", type:"keyword", param:"author", equalityOperator: "="}, + ["resultpublisher"]:{name:"Publisher", type:"keyword", param:"publisher", equalityOperator: "="}, + ["pid"]:{name:"PID", type:"keyword", param:"pid", equalityOperator: " = "}, + ["resulthostingdatasourceid"]:{name:"Hosting Content Provider", type:"entity", param:"hostedBy", equalityOperator: " exact "}, + ["resulthostingdatasource"]:{name:"Content Provider", type:"refine", param:"hostedBy", equalityOperator: " exact "}, + ["instancetypename"]:{name:"Type", type:"vocabulary", param:"type", equalityOperator: " exact "}, + // ["instancetypenameid"]:{name:"Type", type:"vocabulary", param:"type", equalityOperator: " exact "}, + ["resultlanguagename"]:{name:"Language", type:"vocabulary", param:"lang", equalityOperator: " exact "}, + // ["resultlanguageid"]:{name:"Language", type:"vocabulary", param:"lang", equalityOperator: " exact "}, + ["community"]:{name:"Community", type:"refine", param:"community", equalityOperator: " exact "}, + ["relproject"]:{name:"Project", type:"refine", param:"project", equalityOperator: " exact "}, + ["relprojectid"]:{name:"Project", type:"entity", param:"project", equalityOperator: " exact "}, + ["relfunder"]:{name:"Funder", type:"refine", param:"funder", equalityOperator: " exact "}, + ["relfundinglevel0_id"]:{name:"Funding Stream", type:"refine", param:"funderlv0", equalityOperator: " exact "}, + ["relfundinglevel1_id"]:{name:"Funding Substream level 1", type:"refine", param:"funderlv1", equalityOperator: " exact "}, + ["relfundinglevel2_id"]:{name:"Funding Substream level 2", type:"refine", param:"funderlv2", equalityOperator: " exact "}, + ["resultacceptanceyear"]:{name:"Publication Date", type:"keyword", param:"year", equalityOperator: " exact "}, + ["resultdateofacceptance"]:{name:"Publication Date", type:"date", param:"date", equalityOperator: " within "}, + ["resultbestaccessright"]:{name:"Access Mode", type:"vocabulary", param:"access", equalityOperator: " exact "}, + // ["resultbestaccessright"]:{name:"Access Mode", type:"refine", param:"access", equalityOperator: " exact "}, + ["collectedfrom"]:{name:"Content Provider", type:"refine", param:"datasource", equalityOperator: " exact "}, + ["relorganizationid"]:{name:"Organization", type:"entity", param:"organization", equalityOperator: " exact "}, + ["collectedfromdatasourceid"]:{name:"Collected from Content Provider", type:"entity", param:"collectedFrom", equalityOperator: " exact "} + }; + + //PROJECT + + public PROJECT_REFINE_FIELDS:string[] = ["funder","fundinglevel0_id","fundinglevel1_id", + "fundinglevel2_id","projectstartyear","projectendyear","projectecsc39"]; + public PROJECT_ADVANCED_FIELDS:string[] = ["q","projectacronym","projecttitle","projectkeywords", + "funder", "fundinglevel0_id","fundinglevel1_id", "fundinglevel2_id", + "projectstartdate","projectenddate","projectecsc39", + "projectcode_nt","relorganizationid", "collectedfromdatasourceid"]; + public PROJECT_FIELDS: { [key:string]:FieldDetails}={ + ["q"]:{name:"All fields", type:"keyword", param:"q", equalityOperator: "="}, + ["projectacronym"]:{name:"Acronym", type:"keyword", param:"acronym", equalityOperator: "="}, + ["projecttitle"]:{name:"Title", type:"keyword", param:"title", equalityOperator: "="}, + ["projectkeywords"]:{name:"Keywords", type:"keyword", param:"keywords", equalityOperator: "="}, + + ["funder"]:{name:"Funder", type:"refine", param:"funder", equalityOperator: " exact "}, + ["fundinglevel0_id"]:{name:"Funding Stream", type:"refine", param:"funderlv0", equalityOperator: " exact "}, + ["fundinglevel1_id"]:{name:"Funding Substream level 1", type:"refine", param:"funderlv1", equalityOperator: " exact "}, + ["fundinglevel2_id"]:{name:"Funding Substream level 2", type:"refine", param:"funderlv2", equalityOperator: " exact "}, + ["projectstartyear"]:{name:"Start Year", type:"year", param:"startyear", equalityOperator: " exact "}, + ["projectendyear"]:{name:"End Year", type:"year", param:"endyear", equalityOperator: " exact "}, + ["projectstartdate"]:{name:"Start Date", type:"date", param:"startdate", equalityOperator: " within "}, + ["projectenddate"]:{name:"End Date", type:"date", param:"enddate", equalityOperator: " within "}, + ["projectecsc39"]:{name:"Special Clause 39", type:"boolean", param:"sc39", equalityOperator: " exact "}, + ["projectcode_nt"]:{name:"Project Code", type:"keyword", param:"code", equalityOperator: " exact "}, + ["relorganizationid"]:{name:"Organization", type:"entity", param:"organization", equalityOperator: " exact "}, + ["collectedfromdatasourceid"]:{name:"Collected from Content Provider", type:"entity", param:"collectedFrom", equalityOperator: " exact "} + + }; + + //DATAPROVIDERS + + public DATASOURCE_REFINE_FIELDS:string[] = ["datasourcetypeuiname", "datasourceodlanguages", "datasourceodcontenttypes", + "datasourcecompatibilityname"]; + public DATASOURCE_ADVANCED_FIELDS:string[] = ["q", "datasourceofficialname", + "datasourceenglishname","datasourceodsubjects", "datasourcetypename","datasourceodlanguages", + "datasourceodcontenttypes", "datasourcecompatibilityname","relorganizationid", "collectedfromdatasourceid"]; + + public DATASOURCE_FIELDS: { [key:string]:FieldDetails}={ + ["q"]:{name:"All fields", type:"keyword", param:"q", equalityOperator: "="}, + ["datasourceofficialname"]:{name:"English name", type:"keyword", param:"officialname", equalityOperator: "="}, + ["datasourceenglishname"]:{name:"Title", type:"keyword", param:"engname", equalityOperator: "="}, + ["datasourceodsubjects"]:{name:"Subject", type:"keyword", param:"subjects", equalityOperator: "="}, + ["datasourcetypeuiid"]:{name:"Type", type:"refine", param:"type", equalityOperator: " exact "}, + ["datasourcetypeuiname"]:{name:"Type", type:"refine", param:"type", equalityOperator: " exact "}, + ["datasourcetypename"]:{name:"Type", type:"vocabulary", param:"type", equalityOperator: " exact "}, + ["datasourceodlanguages"]:{name:"Language", type:"vocabulary", param:"lang", equalityOperator: " exact "}, + ["datasourceodcontenttypes"]:{name:"Content", type:"refine", param:"content", equalityOperator: " exact "}, + ["datasourcecompatibilityid"]:{name:"Compatibility Level", type:"refine", param:"compatibility", equalityOperator: " exact "}, + ["datasourcecompatibilityname"]:{name:"Compatibility Level", type:"vocabulary", param:"compatibility", equalityOperator: " exact "}, + ["relorganizationid"]:{name:"Organization", type:"entity", param:"organization", equalityOperator: " exact "}, + ["collectedfromdatasourceid"]:{name:"Collected from Content Provider", type:"entity", param:"collectedFrom", equalityOperator: " exact "} + }; + + public COMPATIBLE_DATAPROVIDER_FIELDS:string[] = ["datasourcetypeuiid","datasourcecompatibilityname"]; + public ENTITY_REGISTRIES_FIELDS:string[] = ["datasourcetypename","datasourcecompatibilityname"]; + public JOURNAL_FIELDS:string[] = ["datasourcetypeuiid","datasourcecompatibilityname"]; + + //ORGANIZATION + + public ORGANIZATION_REFINE_FIELDS:string[] = ["organizationcountryname"] + public ORGANIZATION_ADVANCED_FIELDS:string[] = ["q", "organizationlegalname","organizationlegalshortname","organizationcountryname"]; + + public ORGANIZATION_FIELDS: { [key:string]:FieldDetails}={ + ["q"]:{name:"All fields", type:"keyword", param:"q", equalityOperator: "="}, + ["organizationlegalname"]:{name:"Legal Name", type:"keyword", param:"name", equalityOperator: "="}, + ["organizationlegalshortname"]:{name:"Legal Short Name", type:"keyword", param:"shortname", equalityOperator: "="}, + ["organizationcountryname"]:{name:"Country", type:"vocabulary", param:"country", equalityOperator: "="}, + // ["organizationcountryname"]:{name:"Country", type:"refine", param:"country", equalityOperator: "="} + }; + public ORGANIZATION_INDEX:string[] = ["organizationcountryname"]//,"organizationeclegalbody"]; + public ADVANCED_SEARCH_ORGANIZATION_PARAM:string[] = ["q","contenttype","compatibility","country","type"]; + public ORGANIZATION_INDEX_PARAM_MAP:{ [key:string]:string } = {["organizationlegalname"]:"contenttype", ["organizationlegalshortname"]:"type", + ["organizationcountryname"]:"country"};//,["organizationeclegalbody"]:"type"}; + public ORGANIZATION_FIELDS_MAP: { [key:string]:{ name:string, operator:string, type:string, indexField:string , equalityOperator:string}} ={ + ["q"]:{name:"All fields",operator:"op", type:"keyword", indexField:null, equalityOperator: "="}, + ["contenttype"]:{name:"Legal Name",operator:"cn", type:"keyword" , indexField:"organizationlegalname", equalityOperator: "="}, + ["compatibility"]:{name:"Legal Short Name",operator:"cm", type:"keyword", indexField:"organizationlegalshortname", equalityOperator: "="}, + ["country"]:{name:"Country",operator:"cu", type:"vocabulary", indexField:"organizationcountryname", equalityOperator: " exact "}, + ["type"]:{name:"Type",operator:"tp", type:"refine", indexField:"organizationeclegalbody", equalityOperator: " exact "}, + + }; + + + + public HIDDEN_FIELDS:string[] = ["fundinglevel0_id","fundinglevel1_id","fundinglevel2_id", + "relfundinglevel0_id","relfundinglevel1_id","relfundinglevel2_id"]; + + public DEPENDENT_FIELDS: { [key:string]:string } = {["fundinglevel0_id"]:"funder", + ["fundinglevel1_id"]:"fundinglevel0_id", ["fundinglevel2_id"]:"fundinglevel1_id", ["relfundinglevel0_id"]:"relfunder", + ["relfundinglevel1_id"]:"relfundinglevel0_id", ["relfundinglevel2_id"]:"relfundinglevel1_id"}; + + + public ADVANCED_SEARCH_OPERATORS:[{name:string, id:string}] = [{name:"AND",id:"and"},{name:"OR",id:"or"},{name:"NOT",id:"not"}]; + + constructor (){ + } + getFieldName(fieldId:string,fieldType:string):string{ + if(fieldType == "publication" || fieldType == "dataset" || fieldType == "software"){ + return this.RESULT_FIELDS[fieldId].name; + }else if(fieldType == "project"){ + return this.PROJECT_FIELDS[fieldId].name; + }else if(fieldType == "organization"){ + return this.ORGANIZATION_FIELDS[fieldId].name; + }else if(fieldType == "datasource" || fieldType == "dataprovider"){ + return this.DATASOURCE_FIELDS[fieldId].name; + }else{ + return "UNDEFINED"; + } + } +} +class FieldDetails{ + name:string; + type:string; + param:string; + equalityOperator:string; + } diff --git a/portal-4cli/src/app/utils/properties/searchFields_new.ts b/portal-4cli/src/app/utils/properties/searchFields_new.ts new file mode 100644 index 00000000..e89edcd1 --- /dev/null +++ b/portal-4cli/src/app/utils/properties/searchFields_new.ts @@ -0,0 +1,164 @@ +export class SearchFields { + //main Entities + //RESULTS + //Used for datasets and publications + //In case Datasets should display different fields, use seperate tables for fields + public RESULT_REFINE_FIELDS = ["instancetypename", "resultlanguagename", "community","relproject", "relfunder", + "relfundinglevel0_id","relfundinglevel1_id","relfundinglevel2_id", + "resultacceptanceyear","resultbestlicense"];//,"collectedfrom"]; + + public RESULT_ADVANCED_FIELDS:string[] = ["q","resulttitle","relperson","resultpublisher","instancetypenameid", + "resultlanguageid", "community","relprojectid", "relfunder", + "relfundinglevel0_id","relfundinglevel1_id","relfundinglevel2_id", + "resultacceptanceyear","resultbestlicenseid","pid","resulthostingdatasourceid","collectedfromdatasourceid","relpersonid"]; + public RESULT_FIELDS: { [key:string]:FieldDetails}={ + ["q"]:{name:"All fields", type:"keyword", param:"q", equalityOperator: "="}, + ["resulttitle"]:{name:"Title", type:"keyword", param:"title", equalityOperator: "="}, + ["relperson"]:{name:"Author", type:"keyword", param:"author", equalityOperator: "="}, + ["resultpublisher"]:{name:"Publisher", type:"keyword", param:"publisher", equalityOperator: "="}, + ["pid"]:{name:"PID", type:"keyword", param:"pid", equalityOperator: " = "}, + ["resulthostingdatasourceid"]:{name:"Hosting Data Provider", type:"entity", param:"hostedBy", equalityOperator: " exact "}, + ["relpersonid"]:{name:"Person", type:"entity", param:"person", equalityOperator: " exact "}, + ["instancetypename"]:{name:"Type", type:"refine", param:"type", equalityOperator: " exact "}, + ["instancetypenameid"]:{name:"Type", type:"vocabulary", param:"type", equalityOperator: " exact "}, + ["resultlanguagename"]:{name:"Language", type:"refine", param:"lang", equalityOperator: " exact "}, + ["resultlanguageid"]:{name:"Language", type:"vocabulary", param:"lang", equalityOperator: " exact "}, + ["community"]:{name:"Community", type:"refine", param:"community", equalityOperator: " exact "}, + ["relproject"]:{name:"Project", type:"refine", param:"project", equalityOperator: " exact "}, + ["relprojectid"]:{name:"Project", type:"entity", param:"project", equalityOperator: " exact "}, + ["relfunder"]:{name:"Funder", type:"refine", param:"funder", equalityOperator: " exact "}, + ["relfundinglevel0_id"]:{name:"Funding Stream", type:"refine", param:"funderlv0", equalityOperator: " exact "}, + ["relfundinglevel1_id"]:{name:"Funding Substream level 1", type:"refine", param:"funderlv1", equalityOperator: " exact "}, + ["relfundinglevel2_id"]:{name:"Funding Substream level 2", type:"refine", param:"funderlv2", equalityOperator: " exact "}, + ["resultacceptanceyear"]:{name:"Year", type:"year", param:"year", equalityOperator: " exact "}, + ["resultbestlicense"]:{name:"Access Mode", type:"refine", param:"access", equalityOperator: " exact "}, + ["resultbestlicenseid"]:{name:"Access Mode", type:"vocabulary", param:"access", equalityOperator: " exact "}, + ["collectedfrom"]:{name:"Content Provider", type:"refine", param:"datasource", equalityOperator: " exact "}, + ["collectedfromdatasourceid"]:{name:"Collected from Content Provider", type:"entity", param:"collectedFrom", equalityOperator: " exact "} + }; + + //PROJECT + + public PROJECT_REFINE_FIELDS:string[] = ["funder","fundinglevel0_id","fundinglevel1_id", + "fundinglevel2_id","projectstartyear","projectendyear","projectecsc39"]; + public PROJECT_ADVANCED_FIELDS:string[] = ["q","projectacronym","projecttitle","projectkeywords", + "funder", "fundinglevel0_id","fundinglevel1_id", "fundinglevel2_id", + "projectstartyear","projectendyear","projectecsc39", + "projectcode","relorganizationid", "collectedfromdatasourceid"]; + public PROJECT_FIELDS: { [key:string]:FieldDetails}={ + ["q"]:{name:"All fields", type:"keyword", param:"q", equalityOperator: "="}, + ["projectacronym"]:{name:"Acronym", type:"keyword", param:"acronym", equalityOperator: "="}, + ["projecttitle"]:{name:"Title", type:"keyword", param:"title", equalityOperator: "="}, + ["projectkeywords"]:{name:"Keywords", type:"keyword", param:"keywords", equalityOperator: "="}, + + ["funder"]:{name:"Funder", type:"refine", param:"funder", equalityOperator: " exact "}, + ["fundinglevel0_id"]:{name:"Funding Stream", type:"refine", param:"funderlv0", equalityOperator: " exact "}, + ["fundinglevel1_id"]:{name:"Funding Substream level 1", type:"refine", param:"funderlv1", equalityOperator: " exact "}, + ["fundinglevel2_id"]:{name:"Funding Substream level 2", type:"refine", param:"funderlv2", equalityOperator: " exact "}, + ["projectstartyear"]:{name:"Start Year", type:"year", param:"startyear", equalityOperator: " exact "}, + ["projectendyear"]:{name:"End Year", type:"year", param:"endyear", equalityOperator: " exact "}, + + ["projectecsc39"]:{name:"Special Clause 39", type:"boolean", param:"sc39", equalityOperator: " exact "}, + ["projectcode"]:{name:"Project Code", type:"keyword", param:"code", equalityOperator: " exact "}, + ["relorganizationid"]:{name:"Organization", type:"entity", param:"organization", equalityOperator: " exact "}, + ["collectedfromdatasourceid"]:{name:"Collected from Content Provider", type:"entity", param:"collectedFrom", equalityOperator: " exact "} + + }; + + //DATAPROVIDERS + + public DATASOURCE_REFINE_FIELDS:string[] = ["datasourcetypeuiname", "datasourceodlanguages", "datasourceodcontenttypes", + "datasourcecompatibilityname"]; + public DATASOURCE_ADVANCED_FIELDS:string[] = ["q", "datasourceofficialname", + "datasourceenglishname","datasourceodsubjects", "datasourcetypeid","datasourceodlanguages", + "datasourceodcontenttypes", "datasourcecompatibilityid","relorganizationid", "collectedfromdatasourceid"]; + + public DATASOURCE_FIELDS: { [key:string]:FieldDetails}={ + ["q"]:{name:"All fields", type:"keyword", param:"q", equalityOperator: "="}, + ["datasourceofficialname"]:{name:"English name", type:"keyword", param:"officialname", equalityOperator: "="}, + ["datasourceenglishname"]:{name:"Title", type:"keyword", param:"engname", equalityOperator: "="}, + ["datasourceodsubjects"]:{name:"Subject", type:"keyword", param:"subjects", equalityOperator: "="}, + ["datasourcetypeuiid"]:{name:"Type", type:"refine", param:"type", equalityOperator: " exact "}, + ["datasourcetypeuiname"]:{name:"Type", type:"refine", param:"type", equalityOperator: " exact "}, + ["datasourcetypeid"]:{name:"Type", type:"vocabulary", param:"type", equalityOperator: " exact "}, + ["datasourceodlanguages"]:{name:"Language", type:"vocabulary", param:"lang", equalityOperator: " exact "}, + ["datasourceodcontenttypes"]:{name:"Content", type:"refine", param:"content", equalityOperator: " exact "}, + ["datasourcecompatibilityid"]:{name:"Compatibility Level", type:"vocabulary", param:"compatibility", equalityOperator: " exact "}, + ["datasourcecompatibilityname"]:{name:"Compatibility Level", type:"refine", param:"compatibility", equalityOperator: " exact "}, + ["relorganizationid"]:{name:"Organization", type:"entity", param:"organization", equalityOperator: " exact "}, + ["collectedfromdatasourceid"]:{name:"Collected from Content Provider", type:"entity", param:"collectedFrom", equalityOperator: " exact "} + + }; + + public COMPATIBLE_DATAPROVIDER_FIELDS:string[] = ["datasourcetypeuiid","datasourcecompatibilityid"]; + public ENTITY_REGISTRIES_FIELDS:string[] = ["datasourcetypeid","datasourcecompatibilityid"]; + + //ORGANIZATION + + public ORGANIZATION_REFINE_FIELDS:string[] = ["organizationcountryname"] + public ORGANIZATION_ADVANCED_FIELDS:string[] = ["q", + "organizationlegalname","organizationlegalshortname","organizationcountryid"]; + + public ORGANIZATION_FIELDS: { [key:string]:FieldDetails}={ + ["q"]:{name:"All fields", type:"keyword", param:"q", equalityOperator: "="}, + ["organizationlegalname"]:{name:"Legal Name", type:"keyword", param:"name", equalityOperator: "="}, + ["organizationlegalshortname"]:{name:"Legal Short Name", type:"keyword", param:"shortname", equalityOperator: "="}, + ["organizationcountryid"]:{name:"Country", type:"vocabulary", param:"country", equalityOperator: "="}, + ["organizationcountryname"]:{name:"Country", type:"refine", param:"country", equalityOperator: "="} + }; + public ORGANIZATION_INDEX:string[] = ["organizationcountryname"]//,"organizationeclegalbody"]; + public ADVANCED_SEARCH_ORGANIZATION_PARAM:string[] = ["q","contenttype","compatibility","country","type"]; + public ORGANIZATION_INDEX_PARAM_MAP:{ [key:string]:string } = {["organizationlegalname"]:"contenttype", ["organizationlegalshortname"]:"type", + ["organizationcountryname"]:"country"};//,["organizationeclegalbody"]:"type"}; + public ORGANIZATION_FIELDS_MAP: { [key:string]:{ name:string, operator:string, type:string, indexField:string , equalityOperator:string}} ={ + ["q"]:{name:"All fields",operator:"op", type:"keyword", indexField:null, equalityOperator: "="}, + ["contenttype"]:{name:"Legal Name",operator:"cn", type:"keyword" , indexField:"organizationlegalname", equalityOperator: "="}, + ["compatibility"]:{name:"Legal Short Name",operator:"cm", type:"keyword", indexField:"organizationlegalshortname", equalityOperator: "="}, + ["country"]:{name:"Country",operator:"cu", type:"vocabulary", indexField:"organizationcountryname", equalityOperator: " exact "}, + ["type"]:{name:"Type",operator:"tp", type:"refine", indexField:"organizationeclegalbody", equalityOperator: " exact "}, + + }; + + //PERSON + public PERSON_REFINE_FIELDS:string[] = []; + public PERSON_ADVANCED_FIELDS:string[] = ["q","personsecondnames","personfirstname","personfullname"]; + public PERSON_FIELDS: { [key:string]:FieldDetails}={ + ["q"]:{name:"All fields", type:"keyword", param:"q", equalityOperator: "="}, + ["personsecondnames"]:{name:"Surname", type:"keyword", param:"surname", equalityOperator: "="}, + ["personfirstname"]:{name:"First Name",type:"keyword", param:"name", equalityOperator: "="}, + ["personfullname"]:{name:"Full name", type:"keyword", param:"fullname", equalityOperator: "="} + }; + + + public HIDDEN_FIELDS:string[] = ["fundinglevel0_id","fundinglevel1_id","fundinglevel2_id", + "relfundinglevel0_id","relfundinglevel1_id,relfundinglevel2_id"]; + + public DEPENDENT_FIELDS: { [key:string]:string } = {["fundinglevel0_id"]:"funder", + ["fundinglevel1_id"]:"fundinglevel0_id", ["fundinglevel2_id"]:"fundinglevel1_id", ["relfundinglevel0_id"]:"relfunder", + ["relfundinglevel1_id"]:"relfundinglevel0_id", ["relfundinglevel2_id"]:"relfundinglevel1_id"}; + + + public ADVANCED_SEARCH_OPERATORS:[{name:string, id:string}] = [{name:"AND",id:"and"},{name:"OR",id:"or"},{name:"NOT",id:"not"}]; + + constructor (){ + } + getFieldName(fieldId:string,fieldType:string):string{ + if(fieldType == "publication" || fieldType == "dataset"){ + return this.RESULT_FIELDS[fieldId].name; + }else if(fieldType == "project"){ + return this.PROJECT_FIELDS[fieldId].name; + }else if(fieldType == "organization"){ + return this.ORGANIZATION_FIELDS[fieldId].name; + }else if(fieldType == "datasource"){ + return this.DATASOURCE_FIELDS[fieldId].name; + }else{ + return "UNDEFINED"; + } + } +} +class FieldDetails{ + name:string; + type:string; + param:string; + equalityOperator:string; + } diff --git a/portal-4cli/src/app/utils/properties/searchFields_old.ts b/portal-4cli/src/app/utils/properties/searchFields_old.ts new file mode 100644 index 00000000..9c74982a --- /dev/null +++ b/portal-4cli/src/app/utils/properties/searchFields_old.ts @@ -0,0 +1,164 @@ +export class SearchFields { + //main Entities + //RESULTS + //Used for datasets and publications + //In case Datasets should display different fields, use seperate tables for fields + public RESULT_REFINE_FIELDS = ["instancetypename", "resultlanguagename", "community","relproject", "relfunderid", + "relfundinglevel0_id","relfundinglevel1_id","relfundinglevel2_id", + "resultacceptanceyear","resultbestlicense"];//,"collectedfrom"]; + + public RESULT_ADVANCED_FIELDS:string[] = ["q","resulttitle","relperson","resultpublisher","instancetypenameid", + "resultlanguageid", "community","relprojectid", "relfunderid", + "relfundinglevel0_id","relfundinglevel1_id","relfundinglevel2_id", + "resultacceptanceyear","resultbestlicenseid","pid","resulthostingdatasourceid","collectedfromdatasourceid","relpersonid"]; + public RESULT_FIELDS: { [key:string]:FieldDetails}={ + ["q"]:{name:"All fields", type:"keyword", param:"q", equalityOperator: "="}, + ["resulttitle"]:{name:"Title", type:"keyword", param:"title", equalityOperator: "="}, + ["relperson"]:{name:"Author", type:"keyword", param:"author", equalityOperator: "="}, + ["resultpublisher"]:{name:"Publisher", type:"keyword", param:"publisher", equalityOperator: "="}, + ["pid"]:{name:"PID", type:"keyword", param:"pid", equalityOperator: " = "}, + ["resulthostingdatasourceid"]:{name:"Hosting Data Provider", type:"entity", param:"hostedBy", equalityOperator: " exact "}, + ["relpersonid"]:{name:"Person", type:"entity", param:"person", equalityOperator: " exact "}, + ["instancetypename"]:{name:"Type", type:"refine", param:"type", equalityOperator: " exact "}, + ["instancetypenameid"]:{name:"Type", type:"vocabulary", param:"type", equalityOperator: " exact "}, + ["resultlanguagename"]:{name:"Language", type:"refine", param:"lang", equalityOperator: " exact "}, + ["resultlanguageid"]:{name:"Language", type:"vocabulary", param:"lang", equalityOperator: " exact "}, + ["community"]:{name:"Community", type:"refine", param:"community", equalityOperator: " exact "}, + ["relproject"]:{name:"Project", type:"refine", param:"project", equalityOperator: " exact "}, + ["relprojectid"]:{name:"Project", type:"entity", param:"project", equalityOperator: " exact "}, + ["relfunderid"]:{name:"Funder", type:"refine", param:"funder", equalityOperator: " exact "}, + ["relfundinglevel0_id"]:{name:"Funding Stream", type:"refine", param:"funderlv0", equalityOperator: " exact "}, + ["relfundinglevel1_id"]:{name:"Funding Substream level 1", type:"refine", param:"funderlv1", equalityOperator: " exact "}, + ["relfundinglevel2_id"]:{name:"Funding Substream level 2", type:"refine", param:"funderlv2", equalityOperator: " exact "}, + ["resultacceptanceyear"]:{name:"Year", type:"year", param:"year", equalityOperator: " exact "}, + ["resultbestlicense"]:{name:"Access Mode", type:"refine", param:"access", equalityOperator: " exact "}, + ["resultbestlicenseid"]:{name:"Access Mode", type:"vocabulary", param:"access", equalityOperator: " exact "}, + ["collectedfrom"]:{name:"Content Provider", type:"refine", param:"datasource", equalityOperator: " exact "}, + ["collectedfromdatasourceid"]:{name:"Collected from Content Provider", type:"entity", param:"collectedFrom", equalityOperator: " exact "} + }; + + //PROJECT + + public PROJECT_REFINE_FIELDS:string[] = ["funderid","fundinglevel0_id","fundinglevel1_id", + "fundinglevel2_id","projectstartyear","projectendyear","projectecsc39"]; + public PROJECT_ADVANCED_FIELDS:string[] = ["q","projectacronym","projecttitle","projectkeywords", + "funderid", "fundinglevel0_id","fundinglevel1_id", "fundinglevel2_id", + "projectstartyear","projectendyear","projectecsc39", + "projectcode","relorganizationid", "collectedfromdatasourceid"]; + public PROJECT_FIELDS: { [key:string]:FieldDetails}={ + ["q"]:{name:"All fields", type:"keyword", param:"q", equalityOperator: "="}, + ["projectacronym"]:{name:"Acronym", type:"keyword", param:"acronym", equalityOperator: "="}, + ["projecttitle"]:{name:"Title", type:"keyword", param:"title", equalityOperator: "="}, + ["projectkeywords"]:{name:"Keywords", type:"keyword", param:"keywords", equalityOperator: "="}, + + ["funderid"]:{name:"Funder", type:"refine", param:"funder", equalityOperator: " exact "}, + ["fundinglevel0_id"]:{name:"Funding Stream", type:"refine", param:"funderlv0", equalityOperator: " exact "}, + ["fundinglevel1_id"]:{name:"Funding Substream level 1", type:"refine", param:"funderlv1", equalityOperator: " exact "}, + ["fundinglevel2_id"]:{name:"Funding Substream level 2", type:"refine", param:"funderlv2", equalityOperator: " exact "}, + ["projectstartyear"]:{name:"Start Year", type:"year", param:"startyear", equalityOperator: " exact "}, + ["projectendyear"]:{name:"End Year", type:"year", param:"endyear", equalityOperator: " exact "}, + + ["projectecsc39"]:{name:"Special Clause 39", type:"boolean", param:"sc39", equalityOperator: " exact "}, + ["projectcode"]:{name:"Project Code", type:"keyword", param:"code", equalityOperator: " exact "}, + ["relorganizationid"]:{name:"Organization", type:"entity", param:"organization", equalityOperator: " exact "}, + ["collectedfromdatasourceid"]:{name:"Collected from Content Provider", type:"entity", param:"collectedFrom", equalityOperator: " exact "} + + }; + + //DATAPROVIDERS + + public DATASOURCE_REFINE_FIELDS:string[] = ["datasourcetypeuiname", "datasourceodlanguages", "datasourceodcontenttypes", + "datasourcecompatibilityname"]; + public DATASOURCE_ADVANCED_FIELDS:string[] = ["q", "datasourceofficialname", + "datasourceenglishname","datasourceodsubjects", "datasourcetypeid","datasourceodlanguages", + "datasourceodcontenttypes", "datasourcecompatibilityid","relorganizationid", "collectedfromdatasourceid"]; + + public DATASOURCE_FIELDS: { [key:string]:FieldDetails}={ + ["q"]:{name:"All fields", type:"keyword", param:"q", equalityOperator: "="}, + ["datasourceofficialname"]:{name:"English name", type:"keyword", param:"officialname", equalityOperator: "="}, + ["datasourceenglishname"]:{name:"Title", type:"keyword", param:"engname", equalityOperator: "="}, + ["datasourceodsubjects"]:{name:"Subject", type:"keyword", param:"subjects", equalityOperator: "="}, + ["datasourcetypeuiid"]:{name:"Type", type:"refine", param:"type", equalityOperator: " exact "}, + ["datasourcetypeuiname"]:{name:"Type", type:"refine", param:"type", equalityOperator: " exact "}, + ["datasourcetypeid"]:{name:"Type", type:"vocabulary", param:"type", equalityOperator: " exact "}, + ["datasourceodlanguages"]:{name:"Language", type:"vocabulary", param:"lang", equalityOperator: " exact "}, + ["datasourceodcontenttypes"]:{name:"Content", type:"refine", param:"content", equalityOperator: " exact "}, + ["datasourcecompatibilityid"]:{name:"Compatibility Level", type:"vocabulary", param:"compatibility", equalityOperator: " exact "}, + ["datasourcecompatibilityname"]:{name:"Compatibility Level", type:"refine", param:"compatibility", equalityOperator: " exact "}, + ["relorganizationid"]:{name:"Organization", type:"entity", param:"organization", equalityOperator: " exact "}, + ["collectedfromdatasourceid"]:{name:"Collected from Content Provider", type:"entity", param:"collectedFrom", equalityOperator: " exact "} + + }; + + public COMPATIBLE_DATAPROVIDER_FIELDS:string[] = ["datasourcetypeuiid","datasourcecompatibilityid"]; + public ENTITY_REGISTRIES_FIELDS:string[] = ["datasourcetypeid","datasourcecompatibilityid"]; + + //ORGANIZATION + + public ORGANIZATION_REFINE_FIELDS:string[] = ["organizationcountryname"] + public ORGANIZATION_ADVANCED_FIELDS:string[] = ["q", + "organizationlegalname","organizationlegalshortname","organizationcountryid"]; + + public ORGANIZATION_FIELDS: { [key:string]:FieldDetails}={ + ["q"]:{name:"All fields", type:"keyword", param:"q", equalityOperator: "="}, + ["organizationlegalname"]:{name:"Legal Name", type:"keyword", param:"name", equalityOperator: "="}, + ["organizationlegalshortname"]:{name:"Legal Short Name", type:"keyword", param:"shortname", equalityOperator: "="}, + ["organizationcountryid"]:{name:"Country", type:"vocabulary", param:"country", equalityOperator: "="}, + ["organizationcountryname"]:{name:"Country", type:"refine", param:"country", equalityOperator: "="} + }; + public ORGANIZATION_INDEX:string[] = ["organizationcountryname"]//,"organizationeclegalbody"]; + public ADVANCED_SEARCH_ORGANIZATION_PARAM:string[] = ["q","contenttype","compatibility","country","type"]; + public ORGANIZATION_INDEX_PARAM_MAP:{ [key:string]:string } = {["organizationlegalname"]:"contenttype", ["organizationlegalshortname"]:"type", + ["organizationcountryname"]:"country"};//,["organizationeclegalbody"]:"type"}; + public ORGANIZATION_FIELDS_MAP: { [key:string]:{ name:string, operator:string, type:string, indexField:string , equalityOperator:string}} ={ + ["q"]:{name:"All fields",operator:"op", type:"keyword", indexField:null, equalityOperator: "="}, + ["contenttype"]:{name:"Legal Name",operator:"cn", type:"keyword" , indexField:"organizationlegalname", equalityOperator: "="}, + ["compatibility"]:{name:"Legal Short Name",operator:"cm", type:"keyword", indexField:"organizationlegalshortname", equalityOperator: "="}, + ["country"]:{name:"Country",operator:"cu", type:"vocabulary", indexField:"organizationcountryname", equalityOperator: " exact "}, + ["type"]:{name:"Type",operator:"tp", type:"refine", indexField:"organizationeclegalbody", equalityOperator: " exact "}, + + }; + + //PERSON + public PERSON_REFINE_FIELDS:string[] = []; + public PERSON_ADVANCED_FIELDS:string[] = ["q","personsecondnames","personfirstname","personfullname"]; + public PERSON_FIELDS: { [key:string]:FieldDetails}={ + ["q"]:{name:"All fields", type:"keyword", param:"q", equalityOperator: "="}, + ["personsecondnames"]:{name:"Surname", type:"keyword", param:"surname", equalityOperator: "="}, + ["personfirstname"]:{name:"First Name",type:"keyword", param:"name", equalityOperator: "="}, + ["personfullname"]:{name:"Full name", type:"keyword", param:"fullname", equalityOperator: "="} + }; + + + public HIDDEN_FIELDS:string[] = ["fundinglevel0_id","fundinglevel1_id","fundinglevel2_id", + "relfundinglevel0_id","relfundinglevel1_id,relfundinglevel2_id"]; + + public DEPENDENT_FIELDS: { [key:string]:string } = {["fundinglevel0_id"]:"funderid", + ["fundinglevel1_id"]:"fundinglevel0_id", ["fundinglevel2_id"]:"fundinglevel1_id", ["relfundinglevel0_id"]:"relfunderid", + ["relfundinglevel1_id"]:"relfundinglevel0_id", ["relfundinglevel2_id"]:"relfundinglevel1_id"}; + + + public ADVANCED_SEARCH_OPERATORS:[{name:string, id:string}] = [{name:"AND",id:"and"},{name:"OR",id:"or"},{name:"NOT",id:"not"}]; + + constructor (){ + } + getFieldName(fieldId:string,fieldType:string):string{ + if(fieldType == "publication" || fieldType == "dataset"){ + return this.RESULT_FIELDS[fieldId].name; + }else if(fieldType == "project"){ + return this.PROJECT_FIELDS[fieldId].name; + }else if(fieldType == "organization"){ + return this.ORGANIZATION_FIELDS[fieldId].name; + }else if(fieldType == "datasource"){ + return this.DATASOURCE_FIELDS[fieldId].name; + }else{ + return "UNDEFINED"; + } + } +} +class FieldDetails{ + name:string; + type:string; + param:string; + equalityOperator:string; + } diff --git a/portal-4cli/src/app/utils/routerHelper.class.ts b/portal-4cli/src/app/utils/routerHelper.class.ts new file mode 100644 index 00000000..fecaf296 --- /dev/null +++ b/portal-4cli/src/app/utils/routerHelper.class.ts @@ -0,0 +1,34 @@ + + + +export class RouterHelper { + //Use this class function to create queryParams Objects in format {key1:value1} or {key1:value1,key2:value2,key3:value3,...} for multiple parameters + constructor(){} + // Link + public createQueryParam(key:string,value:string){ + var obj ={}; + obj[key]=value; + return obj; + + } + public createQueryParamsPaging(keys:string[],values:string[],pageParameter:string,pageValue:number){ + var obj = this.createQueryParams(keys, values); + obj[pageParameter] = ""+pageValue; + return obj; + + } + public createQueryParams(keys:string[],values:string[]){ + var obj ={}; + if(!keys || !values || keys.length != values.length){ + return obj; + }else{ + for(var i=0; i< keys.length; i++){ + obj[keys[i]]=values[i]; + } + } + return obj; + + } + + +} diff --git a/portal-4cli/src/app/utils/showDataProviders.component.ts b/portal-4cli/src/app/utils/showDataProviders.component.ts new file mode 100644 index 00000000..6b377d38 --- /dev/null +++ b/portal-4cli/src/app/utils/showDataProviders.component.ts @@ -0,0 +1,61 @@ +// import {Component, Input} from '@angular/core'; +// +// @Component({ +// selector: 'showDataProviders', +// template: ` +// +//
    +// No content providers available +//
    +//
    +// +// +//
    +// ` +// }) +// +// // Possibly should be deleted. Not used anywhere. +// export class ShowDataProvidersComponent { +// @Input() dataProviders: { "name": string, "url": string, "type": string, "websiteUrl": string, +// "organizations": {"name": string, "url": string}[]}[]; +// +// constructor () { +// } +// +// ngOnInit() {} +// } diff --git a/portal-4cli/src/app/utils/staticAutoComplete/ISVocabularies.service.ts b/portal-4cli/src/app/utils/staticAutoComplete/ISVocabularies.service.ts new file mode 100644 index 00000000..7ec5902e --- /dev/null +++ b/portal-4cli/src/app/utils/staticAutoComplete/ISVocabularies.service.ts @@ -0,0 +1,110 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {AutoCompleteValue} from '../../searchPages/searchUtils/searchHelperClasses.class'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; + +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; + +@Injectable() +export class ISVocabulariesService { + private api =OpenaireProperties.getVocabulariesAPI(); + constructor(private http: Http ) {} + + getVocabularyByType(field:string,entity:string):any{ + console.log("getVocabulary field: "+ field + " for entity: "+ entity); + var file = ""; + var vocabulary = ""; + if( field == "lang"){ + // file="languages.json"; + // return this.getVocabularyFromFile(file); + vocabulary = "dnet:languages.json"; + return this.getVocabularyFromService(vocabulary); + }else if ( field == "type" && (entity == "publication")){ + // file = "publicationTypes.json"; + // return this.getVocabularyFromFile(file); + vocabulary = "dnet:publication_resource.json"; + return this.getVocabularyFromService(vocabulary); + + }else if ( field == "type" && (entity == "dataset")){ + // file = "dnet:dataCite_resource.json"; + // return this.getVocabularyFromFile(file); + vocabulary = "dnet:dataCite_resource.json"; + return this.getVocabularyFromService(vocabulary); + + }else if( field == "access" && (entity == "publication" || entity == "dataset")){ + // file= "accessMode.json"; + // return this.getVocabularyFromFile(file); + vocabulary = "dnet:access_modes.json"; + return this.getVocabularyFromService(vocabulary); + + } else if( (field == "type") && (entity == "dataprovider")){ + // file = "dataProviderType.json"; + // return this.getVocabularyFromFile(file); + vocabulary = "dnet:datasource_typologies.json"; + return this.getVocabularyFromService(vocabulary); + + } else if( field == "compatibility" && (entity == "dataprovider")){ + // file = "dataProviderCompatibility.json"; + // return this.getVocabularyFromFile(file); + vocabulary = "dnet:datasourceCompatibilityLevel.json"; + return this.getVocabularyFromService(vocabulary); + + } else if( field == "country" ){ + // file = "countries.json"; + // return this.getVocabularyFromFile(file); + vocabulary = "dnet:countries.json"; + return this.getVocabularyFromService(vocabulary); + + } + return null; + + } + // getVocabularyFromFile (file:string):AutoCompleteValue[] { + // var lang = JSON.parse(JSON.stringify(require('../utils/vocabularies/'+file))); + // return this.parse(lang["terms"]); + // } + getVocabularyFromService (vocabularyName:string):any { + let url = this.api + vocabularyName; + console.log(url); + + // return this.http.get(url).toPromise() + // .then(request => + // { + // request = request.json()['terms']; + // var results:AutoCompleteValue[] = this.parse(request); + // console.log("Get vocabulary : "+ vocabularyName+ " - get " +results.length+ "results"); + // return results; + // }); + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .do(res => console.log(res)) + .map(res => res.json()) + .map(res => res['terms']) + .do(res => console.log(res)) + .map(res => this.parse(res)) + .do(res => console.log(res)) + .catch(this.handleError); + + } + + parse (data: any):AutoCompleteValue[] { + var array:AutoCompleteValue[] =[] + for(var i = 0; i < data.length; i++){ + var value:AutoCompleteValue = new AutoCompleteValue(); + value.id = data[i].englishName;//data[i].code; + value.label = data[i].englishName; + array.push(value); + } + + return array; + + } +private handleError (error: Response) { + // in a real world app, we may send the error to some remote logging infrastructure + // instead of just logging it to the console + console.log(error); + return Observable.throw(error || 'Server error'); + } +} diff --git a/portal-4cli/src/app/utils/staticAutoComplete/staticAutoComplete.component.ts b/portal-4cli/src/app/utils/staticAutoComplete/staticAutoComplete.component.ts new file mode 100644 index 00000000..bb90dcac --- /dev/null +++ b/portal-4cli/src/app/utils/staticAutoComplete/staticAutoComplete.component.ts @@ -0,0 +1,300 @@ +import {Component, ElementRef, Input, Output, EventEmitter, OnChanges, SimpleChange} from '@angular/core'; +import {Value} from '../../searchPages/searchUtils/searchHelperClasses.class'; +import {ISVocabulariesService} from './ISVocabularies.service'; +import {RefineFieldResultsService} from '../../services/refineFieldResults.service'; +//Usage example +// + +@Component({ + selector: 'static-autocomplete', + styleUrls: ['../autoComplete.component.css'], + host: { + '(document:click)': 'handleClick($event)', + }, + template: ` + + + {{showItem(item)}} + + + + + +
    +
      +
    • + Loading... + {{results}} results found: + No results found +
    • +
    • + {{showItem(item)}} +
    • +
    +
    +
    + + ` +}) +export class StaticAutoCompleteComponent implements OnChanges{ + @Input() placeHolderMessage = "Search for entries"; + @Input() title = "Autocomplete"; + @Output() addItem = new EventEmitter(); // when selected list changes update parent component + @Output() selectedValueChanged = new EventEmitter(); // when changed a method for filtering will be called + @Output() listUpdated = new EventEmitter(); // when changed a method for filtering will be called + @Input() public list = []; // the entries resulted after filtering function + @Input() public filtered = []; // the entries resulted after filtering function + @Input() public selected = []; // the entries selected from user + @Input() public keywordlimit = 3; // the minimum length of keyword + @Input() public showSelected = true; // the minimum length of keyword + @Input() public multipleSelections:boolean = true; + @Input() public allowDuplicates:boolean = false; + @Input() public selectedValue:string = ''; + @Input() public vocabularyId:string ; + @Input() public fieldName:string ; + @Input() public entityName:string ; + @Input() public fieldId:string ; + + @Input() public keyword = ''; + @Input() public type = 'search' //search, result, context, project + public warningMessage = ""; + public infoMessage = ""; + public showLoading:boolean = false; + public tries = 0; + public showInput = true; + public sub; + public done = false; + public results = 0; + public focus:boolean = false; + public currentFieldId: string ; + constructor ( private _vocabulariesService: ISVocabulariesService,private _refineService: RefineFieldResultsService, private myElement: ElementRef) { + this.currentFieldId=this.fieldId; + + } + ngOnDestroy(){ + if(this.sub && this.sub != undefined){ + this.sub.unsubscribe(); + } + } + + ngOnChanges(changes: {[propKey: string]: SimpleChange}) { + if(this.currentFieldId!=this.fieldId){ //this is going to be called when + this.currentFieldId=this.fieldId; + this.initialize(); + } + } + private initialize(){ + + this.showInput = true; + if(this.list == undefined || this.list.length == 0){ + this.showLoading = true; + + if(this.vocabularyId){ + // this.list = this._vocabulariesService.getVocabularyByType(this.vocabularyId, this.entityName); + // this.afterListFetchedActions(); + this.sub = this._vocabulariesService.getVocabularyByType(this.vocabularyId, this.entityName).subscribe( + data => { + this.list = data; + this.afterListFetchedActions(); + + }, + err => { + console.log(err); + this.warningMessage = "An Error occured..." + } + ); + }else if(this.fieldName && this.entityName){ + // this.list = this._refineService.getRefineFieldResultsByFieldName(this.fieldName,this.entityName); + this.sub = this._refineService.getRefineFieldResultsByFieldName(this.fieldName,this.entityName).subscribe( + data => { + this.list = data; + this.afterListFetchedActions(); + + }, + err => { + console.log(err); + this.warningMessage = "An Error occured..." + } + ); + }else{ + this.showLoading = false; + + } + }else{ + this.afterListFetchedActions(); + } + + } + public updateList(list){ // used in claim context autocomplete + this.list = list; + this.afterListFetchedActions() + } + private afterListFetchedActions(){ + this.showLoading = false; + this.getSelectedNameFromGivenId(); + this.listUpdated.emit({ + value: this.list + }); + if(this.list == null || this.list.length == 0 ){ + this.warningMessage = "No results available"; + return; + } + this.done = true; + if(this.keyword != ""){ + this.filter(); + } + + } + filter() { + this.focus = true; + if(this.done){ + this.infoMessage = ""; + this.filtered = []; + if(this.keyword == ""){ + var cut = 10; + if(this.list.length < 5){ + cut = this.list.length; + } + this.results = this.list.length; + this.filtered =this.list.slice(0, cut); + this.tries = 0; + this.warningMessage = ""; + // } else if(this.keyword && this.keyword.length < this.keywordlimit){ + // this.tries++; + // if(this.tries == this.keywordlimit -1 ){ + // this.warningMessage = "Type at least " + this.keywordlimit + " characters"; + // this.tries = 0; + // } + }else{ + this.tries = 0; + this.warningMessage = ""; + this.filtered = this.list.filter(function(el){ + return el.label.toLowerCase().indexOf(this.keyword.toLowerCase()) > -1; + }.bind(this)); + var cut = 10; + if(this.filtered .length < 5){ + cut = this.list.length; + } + this.results = this.filtered.length; + this.filtered =this.filtered.slice(0, cut); + } + } + } + remove(item:any){ + var index:number =this.checkIfExists(item,this.selected); + if (index > -1) { + this.selected.splice(index, 1); + } + if(!this.multipleSelections && this.selected.length == 0 ){ + this.showInput = true; + this.selectedValue = ""; + this.selectedValueChanged.emit({ + value: this.selectedValue + }); + + + } + } + select(item:any){ + // console.log("select"+this.selected.length + item.id + " "+ item.label); + + if(this.multipleSelections){ + var index:number =this.checkIfExists(item,this.selected); + if (index > -1 && !this.allowDuplicates) { + this.keyword = ""; + this.filtered.splice(0, this.filtered.length); + return; + } + else{ + this.selected.push(item); + this.keyword = ""; + this.filtered.splice(0, this.filtered.length); + this.addItem.emit({ + value: item + }); + } + }else{ + this.selected.splice(0, this.selected.length); + this.selected.push(item); + this.filtered.splice(0, this.filtered.length); + this.keyword = ""; + this.showInput = false; + this.selectedValue = item.id; + this.selectedValueChanged.emit({ + value: this.selectedValue + }); + + } + + } + private checkIfExists(item:any,list):number{ + + if(item.concept && item.concept.id ){ + + for (var _i = 0; _i < list.length; _i++) { + let itemInList = list[_i]; + if(item.concept.id == itemInList.concept.id){ + return _i; + } + } + }else if(item.id){ + for (var _i = 0; _i < list.length; _i++) { + let itemInList = list[_i]; + if(item.id == itemInList.id){ + return _i; + } + } + } + return -1; + + } + showItem(item:any):string{ + + if (item.name){ //search + return item.name; + }else if( item.concept && item.concept.label){ //context + return item.concept.label; + }else if (item.label){ //simple + return item.label; + } + + } + truncate(str:string, size:number):string{ + if(str == null){return "";} + return (str.length > size)?str.substr(0,size)+'...':str; + } + private getSelectedNameFromGivenId(){ + if(this.list == null ){ + return; + } + this.showInput = true; + for( var i = 0; i < this.list.length; i++){ + if(this.list[i].id == this.selectedValue){ + this.selectedValue = this.list[i].label; + this.selected.push(this.list[i]); + this.showInput = false; + return; + + } + } + } + + handleClick(event){ + var clickedComponent = event.target; + var inside = false; + do { + if (clickedComponent === this.myElement.nativeElement) { + inside = true; + } + clickedComponent = clickedComponent.parentNode; + } while (clickedComponent); + if(!inside){ + this.focus =false; + this.filtered.splice(0, this.filtered.length); + } + } + +} diff --git a/portal-4cli/src/app/utils/staticAutoComplete/staticAutoComplete.module.ts b/portal-4cli/src/app/utils/staticAutoComplete/staticAutoComplete.module.ts new file mode 100644 index 00000000..1c876a15 --- /dev/null +++ b/portal-4cli/src/app/utils/staticAutoComplete/staticAutoComplete.module.ts @@ -0,0 +1,22 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {StaticAutoCompleteComponent} from './staticAutoComplete.component'; +import {RefineFieldResultsServiceModule} from '../../services/refineFieldResultsService.module'; +import {ISVocabulariesService} from './ISVocabularies.service'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule, RefineFieldResultsServiceModule + ], + declarations: [ + StaticAutoCompleteComponent + ], + exports: [ + StaticAutoCompleteComponent + ], + providers:[ ISVocabulariesService] +}) +export class StaticAutocompleteModule { } diff --git a/portal-4cli/src/app/utils/string-utils.class.ts b/portal-4cli/src/app/utils/string-utils.class.ts new file mode 100644 index 00000000..ece1ce3e --- /dev/null +++ b/portal-4cli/src/app/utils/string-utils.class.ts @@ -0,0 +1,129 @@ +export class Dates { + public static isValidYear(yearString){ + // First check for the pattern + if(!/^\d{4}$/.test(yearString)) + return false; + var year = parseInt(yearString, 10); + + // Check the ranges of month and year + if(year < 1000 || year > 3000 ) + return false; + return true; + } + //format YYYY-MM-DD + public static isValidDate(dateString:string) + { + // First check for the pattern + if(!/^\d{4}\-\d{1,2}\-\d{1,2}$/.test(dateString)) + return false; + + // Parse the date parts to integers + var parts = dateString.split("-"); + var day = parseInt(parts[2], 10); + var month = parseInt(parts[1], 10); + var year = parseInt(parts[0], 10); + if(!this.isValidYear(parts[0])){ + return false; + } + + // Check the ranges of month and year + if( month == 0 || month > 12) + return false; + + var monthLength = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]; + + // Adjust for leap years + if(year % 400 == 0 || (year % 100 != 0 && year % 4 == 0)) + monthLength[1] = 29; + + // Check the range of the day + return day > 0 && day <= monthLength[month - 1]; + + } + public static getDateToday():Date{ + var myDate = new Date(); + return myDate; + + } + public static getDateToString(myDate:Date):string{ + var date:string = myDate.getFullYear()+ "-" ; + date+=((myDate.getMonth() + 1)<10)?"0"+(myDate.getMonth() + 1):(myDate.getMonth() + 1) ; + date+="-"; + date+= (myDate.getDate() <10 )? "0"+myDate.getDate():myDate.getDate() ; + return date; + + } + public static getDateXMonthsAgo(x:number):Date{ + var myDate = new Date(); + myDate.setMonth(myDate.getMonth() - x); + return myDate; + + } + public static getDateXYearsAgo(x:number):Date{ + var myDate = new Date(); + myDate.setFullYear(myDate.getFullYear() - x); + return myDate; + + } + public static getDateFromString(date:string):Date{ + + var myDate = new Date(); + myDate.setFullYear(+date.substring(0,4)); + myDate.setMonth(+date.substring(5,7)-1); + myDate.setDate(+date.substring(8,11)) + return myDate; + + } + +} + +export class DOI{ + + public static getDOIsFromString(str:string):string[]{ + var DOIs:string[] = []; + var words:string[] = str.split(" "); + + for(var i=0; i< words.length; i++){ + if(DOI.isValidDOI(words[i]) && DOIs.indexOf(words[i]) == -1){ + DOIs.push(words[i]); + } + } + return DOIs; + } + public static isValidDOI(str:string):boolean{ + + var exp1 = /\b(10[.][0-9]{4,}(?:[.][0-9]+)*\/(?:(?!["&\'<>])\S)+)\b/g + var exp2 = /\b(10[.][0-9]{4,}(?:[.][0-9]+)*\/(?:(?!["&\'<>])[[:graph:]])+)\b/g + if(str.match(exp1)!=null || str.match(exp2)!=null){ + // console.log("It's a DOI"); + return true; + } + return false; + + } +} +export class StringUtils{ + public static quote(params: string):string { + return '"'+params+'"'; + } + + public static unquote(params: string):string { + if(params.length > 2 && (params[0]=='"' && params[params.length-1]=='"') || (params[0]=="'" && params[params.length-1]=="'")){ + params= params.substring(1, params.length-1); + } + return params; + } + public static URIEncode(params: string):string { + return encodeURIComponent(params); + } + public static URIDecode(params: string):string { + return decodeURIComponent(params); + } + public static b64DecodeUnicode(str) { + return decodeURIComponent(Array.prototype.map.call(atob(str), function(c) { + return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); + }).join('')); + } + + +} diff --git a/portal-4cli/src/assets/Home_24white.svg b/portal-4cli/src/assets/Home_24white.svg new file mode 100644 index 00000000..db4e815d --- /dev/null +++ b/portal-4cli/src/assets/Home_24white.svg @@ -0,0 +1 @@ + diff --git a/portal-4cli/src/assets/OA DISCOVER_A.png b/portal-4cli/src/assets/OA DISCOVER_A.png new file mode 100644 index 00000000..e8c097c5 Binary files /dev/null and b/portal-4cli/src/assets/OA DISCOVER_A.png differ diff --git a/portal-4cli/src/assets/OA DISCOVER_B.png b/portal-4cli/src/assets/OA DISCOVER_B.png new file mode 100644 index 00000000..26d48466 Binary files /dev/null and b/portal-4cli/src/assets/OA DISCOVER_B.png differ diff --git a/portal-4cli/src/assets/closedAccess.png b/portal-4cli/src/assets/closedAccess.png new file mode 100644 index 00000000..b1d033ce Binary files /dev/null and b/portal-4cli/src/assets/closedAccess.png differ diff --git a/portal-4cli/src/assets/common/80x15.png b/portal-4cli/src/assets/common/80x15.png new file mode 100644 index 00000000..863f00bb Binary files /dev/null and b/portal-4cli/src/assets/common/80x15.png differ diff --git a/portal-4cli/src/assets/common/Home-icon.png b/portal-4cli/src/assets/common/Home-icon.png new file mode 100644 index 00000000..6648060e Binary files /dev/null and b/portal-4cli/src/assets/common/Home-icon.png differ diff --git a/portal-4cli/src/assets/common/Logo_Horizontal.png b/portal-4cli/src/assets/common/Logo_Horizontal.png new file mode 100644 index 00000000..797a31bf Binary files /dev/null and b/portal-4cli/src/assets/common/Logo_Horizontal.png differ diff --git a/portal-4cli/src/assets/common/Logo_Horizontal_white_small.png b/portal-4cli/src/assets/common/Logo_Horizontal_white_small.png new file mode 100644 index 00000000..e8a3a6ac Binary files /dev/null and b/portal-4cli/src/assets/common/Logo_Horizontal_white_small.png differ diff --git a/portal-4cli/src/assets/common/Symbol.png b/portal-4cli/src/assets/common/Symbol.png new file mode 100644 index 00000000..b58e78dc Binary files /dev/null and b/portal-4cli/src/assets/common/Symbol.png differ diff --git a/portal-4cli/src/assets/common/custom.css b/portal-4cli/src/assets/common/custom.css new file mode 100644 index 00000000..b9f88055 --- /dev/null +++ b/portal-4cli/src/assets/common/custom.css @@ -0,0 +1,1111 @@ +@import url('https://fonts.googleapis.com/css?family=Josefin+Sans|Raleway|Roboto|Roboto:900|Roboto+Condensed|Roboto+Mono|Roboto+Slab'); +@import url('https://fonts.googleapis.com/css?family=Open+Sans:300,400'); +@import url('https://fonts.googleapis.com/css?family=Merriweather|Merriweather+Sans'); +@import url('https://fonts.googleapis.com/css?family=Roboto+Slab'); +@import url('https://fonts.googleapis.com/css?family=Lora'); +@import url('https://fonts.googleapis.com/css?family=Raleway|Raleway+Dots'); + + +body { +font-family: 'Open Sans', sans-serif!important; +font-family: Raleway, sans-serif!important; +font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif!important; +font-size: 14px; +font-weight:normal!important; +} +h1, .uk-h1, h2, .uk-h2, h3, .uk-h3 { + font-family: 'Open Sans', sans-serif !important; + text-transform:none!important; + font-weight:300; +} +h4, .uk-h4, h5, .uk-h5 { + font-family: 'Open Sans', sans-serif !important; + font-weight:bold; +} + +h6, .uk-h6 { + font-family: 'Open Sans', sans-serif !important; + font-weight: normal; +} +h2, .uk-h2 { + font-size:36px; +} + +a, .uk-link { + color: #2D72D6; +} +a:hover, .uk-link:hover{ +color: #D53B23; +} + +.uk-badge, .badge, a.badge { border-radius: 2px;} + + +.hero_to_top { +} +.image-front-topbar { + margin-top:-40px; +} + +.tm-header { +/*padding-top:40px;*/ +} + +.tm-toolbar { +border-top: 5px solid #05007A; +position:relative; +color: #fff; +padding-top: 0px; +padding-bottom:0px; +background:rgba(255,255,255, 0.0); +z-index:10000; +/*background: linear-gradient(rgba(255,255,255,0), rgba(255,255,255,0)), url(/images/toolbar_bg.png);*/ + +} +.tm-toolbar .forimage { +background:rgba(255,255,255, 0.4); +} + +.uk-section-overlap { + /*margin-top:-40px!important;*/ +} +.uk-sticky{ +} + +.tm-header .uk-navbar-left {position:relative;z-index:9999!important;} +.tm-header .uk-logo {padding: 5px 10px 10px 10px; position:relative;z-index:1000!important;} +.tm-header .uk-navbar-transparent{ + /* background:rgba(255,255,255, 0.7);*/ + padding-top:4px; +} +.inner { + left:0px; + background-color: #05007A; + margin-top:-5px; +} +.tm-toolbar .uk-container { +padding-right:0px; +} + +.tm-toolbar ul.uk-subnav.uk-subnav-line{ + margin-top:-10px; + background-color: #05007A; + padding:10px 10px 0px 0px; + transform: skew(25deg); + margin-right:10px; +} + +.tm-toolbar .uk-subnav-line li { + padding:5px 25px 5px 25px; + /*transition: background 0.2s;*/ + /* display:inline-block;*/ + font-family:Roboto!important; + font-weight:900!important; + text-transform:uppercase!important; + font-size:12px!important; + opacity:1!important; + display:inline-block; +} +.tm-toolbar .uk-subnav-line > :before { + content: none; + display: block; + /* display: inline-block*/ + height: 10px; + vertical-align: middle +} + +.uk-subnav-line > :nth-child(n + 2):before { + margin-right: 10px; + border-left: 0px ; +} + +.tm-toolbar .uk-subnav-line li a{ + display: block; + text-decoration:none; + transform: skew(-25deg); + font-family:Roboto:900!important; + text-transform:uppercase!important; + font-size:13px!important; + opacity:1!important; + color:#fff!important; +} + + +.tm-toolbar .uk-subnav-line li:hover { + color:#05007A!important; + background:#fff; + display: block; +} + + +.tm-toolbar .uk-subnav-line .uk-active .home-hover li:hover, +li.uk-active.home-hover +{ + background:#05007A!important; +} + +.tm-toolbar .uk-dotnav, .tm-toolbar .uk-subnav { + margin-bottom:0px!important; +} + +.tm-toolbar .uk-subnav-line li a:hover, +.tm-toolbar .uk-subnav-line li:hover a { + display: block; + color:#05007A!important; +} + +.movetotop .uk-slidenav-position{ + /*top:-130px; + z-index:5;*/ +} + +.uk-navbar-container:not(.uk-navbar-transparent) { + background: #fff; + box-shadow: 2px 15px 50px rgba(41, 44, 61, .1); +} + +.uk-navbar-sticky { + box-shadow: 2px 15px 50px rgba(41, 44, 61, .1); +} + +.navbar .nav>li>.dropdown-menu, .uk-navbar-dropdown +{display: none; +position: absolute; +z-index: 1020; +box-sizing: border-box; +width: 200px; +padding: 25px; +background: #fff; +color: #4F5260; +border-radius: 2px; +box-shadow: 2px 15px 50px rgba(41, 44, 61, .1) +} + + +/* +.uk-light a, .uk-light .uk-link, +.uk-section-primary:not(.uk-preserve-color) a, .uk-section-primary:not(.uk-preserve-color) .uk-link, +.uk-section-secondary:not(.uk-preserve-color) a, .uk-section-secondary:not(.uk-preserve-color) .uk-link, +.uk-tile-primary:not(.uk-preserve-color) a, .uk-tile-primary:not(.uk-preserve-color) .uk-link, +.uk-tile-secondary:not(.uk-preserve-color) a, .uk-tile-secondary:not(.uk-preserve-color) .uk-link, +.uk-card-primary.uk-card-body a, .uk-card-primary.uk-card-body .uk-link, .uk-card-primary>:not([class*='uk-card-media']) a, +.uk-card-primary>:not([class*='uk-card-media']) .uk-link, .uk-card-secondary.uk-card-body a, +.uk-card-secondary.uk-card-body .uk-link, .uk-card-secondary>:not([class*='uk-card-media']) a, +.uk-card-secondary>:not([class*='uk-card-media']) .uk-link, .uk-overlay-primary a, .uk-overlay-primary .uk-link, +*/ +.uk-navbar-container:not(.uk-navbar-transparent) a, .uk-navbar-container:not(.uk-navbar-transparent) .uk-link, +.uk-offcanvas-bar a, .uk-offcanvas-bar .uk-link, .tm-toolbar a, .tm-toolbar .uk-link { + color: #292C3D +} + + +.uk-navbar-container:not(.uk-navbar-transparent) a, .uk-navbar-container:not(.uk-navbar-transparent) .uk-link, +.uk-offcanvas-bar a, .uk-offcanvas-bar .uk-link, .tm-toolbar a, .tm-toolbar .uk-link { +/*color:#292C3D; +color: #245BCC; +color: #2D72D6; +*/ +/* +font-size: 14px; +line-height: 18px; +*/ +} + +/*footer*/ +.footer-license { +font-size:11px!important; +line-height:16px!important; +} +.footer-license .uk-section-primary:not(.uk-preserve-color) a{ + color: #128DD5!important; + font-size:11px!important; +line-height:16px!important; + +} +.footer-license a:hover { + color: #D33A24; +} + +.uk-light .uk-navbar-nav>li>a, .uk-section-primary:not(.uk-preserve-color) .uk-navbar-nav>li>a, .uk-section-secondary:not(.uk-preserve-color) .uk-navbar-nav>li>a, .uk-card-primary.uk-card-body .uk-navbar-nav>li>a, .uk-card-primary>:not([class*='uk-card-media']) .uk-navbar-nav>li>a, .uk-card-secondary.uk-card-body .uk-navbar-nav>li>a, .uk-card-secondary>:not([class*='uk-card-media']) .uk-navbar-nav>li>a, .uk-overlay-primary .uk-navbar-nav>li>a, .uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-nav>li>a, .uk-offcanvas-bar .uk-navbar-nav>li>a, .tm-toolbar .uk-navbar-nav>li>a { +color:#292C3D;} + +.uk-light .uk-navbar-nav>li.uk-active>a, .uk-section-primary:not(.uk-preserve-color) .uk-navbar-nav>li.uk-active>a, .uk-section-secondary:not(.uk-preserve-color) .uk-navbar-nav>li.uk-active>a, .uk-card-primary.uk-card-body .uk-navbar-nav>li.uk-active>a, .uk-card-primary>:not([class*='uk-card-media']) .uk-navbar-nav>li.uk-active>a, .uk-card-secondary.uk-card-body .uk-navbar-nav>li.uk-active>a, .uk-card-secondary>:not([class*='uk-card-media']) .uk-navbar-nav>li.uk-active>a, .uk-overlay-primary .uk-navbar-nav>li.uk-active>a, .uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-nav>li.uk-active>a, .uk-offcanvas-bar .uk-navbar-nav>li.uk-active>a, .tm-toolbar .uk-navbar-nav>li.uk-active>a +color:#292C3D;} + +.uk-light .uk-navbar-nav>li>a::before, .uk-section-primary:not(.uk-preserve-color) .uk-navbar-nav>li>a::before, +.uk-section-secondary:not(.uk-preserve-color) .uk-navbar-nav>li>a::before, +.uk-card-primary.uk-card-body .uk-navbar-nav>li>a::before, +.uk-card-primary>:not([class*='uk-card-media']) .uk-navbar-nav>li>a::before, . +uk-card-secondary.uk-card-body .uk-navbar-nav>li>a::before, +.uk-card-secondary>:not([class*='uk-card-media']) .uk-navbar-nav>li>a::before, +.uk-overlay-primary .uk-navbar-nav>li>a::before, .uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-nav>li>a::before, +.uk-offcanvas-bar .uk-navbar-nav>li>a::before, .tm-toolbar .uk-navbar-nav>li>a::before { + +background-color: #128DD5; +} +.uk-navbar-nav>li>a::before { +/*height:2px;*/ +background-color: #128DD5!important; +} +.uk-light .uk-navbar-nav>li:hover>a, .uk-light .uk-navbar-nav>li>a:focus, .uk-light .uk-navbar-nav>li>a.uk-open, +.uk-section-primary:not(.uk-preserve-color) .uk-navbar-nav>li:hover>a, +.uk-section-primary:not(.uk-preserve-color) .uk-navbar-nav>li>a:focus, +.uk-section-primary:not(.uk-preserve-color) .uk-navbar-nav>li>a.uk-open, +.uk-section-secondary:not(.uk-preserve-color) .uk-navbar-nav>li:hover>a, +.uk-section-secondary:not(.uk-preserve-color) .uk-navbar-nav>li>a:focus, +.uk-section-secondary:not(.uk-preserve-color) .uk-navbar-nav>li>a.uk-open, +.uk-card-primary.uk-card-body .uk-navbar-nav>li:hover>a, .uk-card-primary.uk-card-body .uk-navbar-nav>li>a:focus, +.uk-card-primary.uk-card-body .uk-navbar-nav>li>a.uk-open, +.uk-card-primary>:not([class*='uk-card-media']) .uk-navbar-nav>li:hover>a, +.uk-card-primary>:not([class*='uk-card-media']) .uk-navbar-nav>li>a:focus, +.uk-card-primary>:not([class*='uk-card-media']) .uk-navbar-nav>li>a.uk-open, +.uk-card-secondary.uk-card-body .uk-navbar-nav>li:hover>a, +.uk-card-secondary.uk-card-body .uk-navbar-nav>li>a:focus, +.uk-card-secondary.uk-card-body .uk-navbar-nav>li>a.uk-open, +.uk-card-secondary>:not([class*='uk-card-media']) .uk-navbar-nav>li:hover>a, +.uk-card-secondary>:not([class*='uk-card-media']) .uk-navbar-nav>li>a:focus, +.uk-card-secondary>:not([class*='uk-card-media']) .uk-navbar-nav>li>a.uk-open, +.uk-overlay-primary .uk-navbar-nav>li:hover>a, .uk-overlay-primary .uk-navbar-nav>li>a:focus, +.uk-overlay-primary .uk-navbar-nav>li>a.uk-open, .uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-nav>li:hover>a, +.uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-nav>li>a:focus, +.uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-nav>li>a.uk-open, +.uk-offcanvas-bar .uk-navbar-nav>li:hover>a, .uk-offcanvas-bar .uk-navbar-nav>li>a:focus, +.uk-offcanvas-bar .uk-navbar-nav>li>a.uk-open, .tm-toolbar .uk-navbar-nav>li:hover>a, +.tm-toolbar .uk-navbar-nav>li>a:focus, .tm-toolbar .uk-navbar-nav>li>a.uk-open { +color: #128DD5; +} + +.uk-light .uk-navbar-nav > li:hover > a, .uk-light .uk-navbar-nav > li > a:focus, +.uk-light .uk-navbar-nav > li > a.uk-open, .uk-section-primary:not(.uk-preserve-color) .uk-navbar-nav > li:hover > a, +.uk-section-primary:not(.uk-preserve-color) .uk-navbar-nav > li > a:focus, +.uk-section-primary:not(.uk-preserve-color) .uk-navbar-nav > li > a.uk-open, +.uk-section-secondary:not(.uk-preserve-color) .uk-navbar-nav > li:hover > a, +.uk-section-secondary:not(.uk-preserve-color) .uk-navbar-nav > li > a:focus, +.uk-section-secondary:not(.uk-preserve-color) .uk-navbar-nav > li > a.uk-open, +.uk-card-primary.uk-card-body .uk-navbar-nav > li:hover > a, .uk-card-primary.uk-card-body .uk-navbar-nav > li > a:focus, +.uk-card-primary.uk-card-body .uk-navbar-nav > li > a.uk-open, .uk-card-primary > :not([class * ='uk-card-media']) .uk-navbar-nav > li:hover > a, +.uk-card-primary > :not([class * ='uk-card-media']) .uk-navbar-nav > li > a:focus, +.uk-card-primary > :not([class * ='uk-card-media']) .uk-navbar-nav > li > a.uk-open, +.uk-card-secondary.uk-card-body .uk-navbar-nav > li:hover > a, .uk-card-secondary.uk-card-body .uk-navbar-nav > li > a:focus, +.uk-card-secondary.uk-card-body .uk-navbar-nav > li > a.uk-open, .uk-card-secondary > :not([class * ='uk-card-media']) .uk-navbar-nav > li:hover > a, +.uk-card-secondary > :not([class * ='uk-card-media']) .uk-navbar-nav > li > a:focus, +.uk-card-secondary > :not([class * ='uk-card-media']) .uk-navbar-nav > li > a.uk-open, +.uk-overlay-primary .uk-navbar-nav > li:hover > a, .uk-overlay-primary .uk-navbar-nav > li > a:focus, +.uk-overlay-primary .uk-navbar-nav > li > a.uk-open, .uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-nav > li:hover > a, +.uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-nav > li > a:focus, +.uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-nav > li > a.uk-open, +.uk-offcanvas-bar .uk-navbar-nav > li:hover > a, .uk-offcanvas-bar .uk-navbar-nav > li > a:focus, +.uk-offcanvas-bar .uk-navbar-nav > li > a.uk-open, .tm-toolbar .uk-navbar-nav > li:hover > a, +.tm-toolbar .uk-navbar-nav > li > a:focus, .tm-toolbar .uk-navbar-nav > li > a.uk-open { + color: #128DD5!important; +} +.uk-light .uk-navbar-nav>li.uk-active>a, .uk-section-primary:not(.uk-preserve-color) .uk-navbar-nav>li.uk-active>a, .uk-section-secondary:not(.uk-preserve-color) .uk-navbar-nav>li.uk-active>a, .uk-card-primary.uk-card-body .uk-navbar-nav>li.uk-active>a, .uk-card-primary>:not([class*='uk-card-media']) .uk-navbar-nav>li.uk-active>a, .uk-card-secondary.uk-card-body .uk-navbar-nav>li.uk-active>a, .uk-card-secondary>:not([class*='uk-card-media']) .uk-navbar-nav>li.uk-active>a, .uk-overlay-primary .uk-navbar-nav>li.uk-active>a, .uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-nav>li.uk-active>a, .uk-offcanvas-bar .uk-navbar-nav>li.uk-active>a, .tm-toolbar .uk-navbar-nav>li.uk-active>a { + color: #128DD5!important; +} +.uk-light a:hover, .uk-light .uk-link:hover, +.uk-section-primary:not(.uk-preserve-color) a:hover, .uk-section-primary:not(.uk-preserve-color) .uk-link:hover, +.uk-section-secondary:not(.uk-preserve-color) a:hover, .uk-section-secondary:not(.uk-preserve-color) .uk-link:hover, +.uk-card-primary.uk-card-body a:hover, .uk-card-primary.uk-card-body .uk-link:hover, +.uk-card-primary>:not([class*='uk-card-media']) a:hover, .uk-card-primary>:not([class*='uk-card-media']) .uk-link:hover, +.uk-card-secondary.uk-card-body a:hover, .uk-card-secondary.uk-card-body .uk-link:hover, +.uk-card-secondary>:not([class*='uk-card-media']) a:hover, .uk-card-secondary>:not([class*='uk-card-media']) .uk-link:hover, +.uk-overlay-primary a:hover, .uk-overlay-primary .uk-link:hover, +.uk-navbar-container:not(.uk-navbar-transparent) a:hover, .uk-navbar-container:not(.uk-navbar-transparent) .uk-link:hover, +.uk-offcanvas-bar a:hover, .uk-offcanvas-bar .uk-link:hover, .tm-toolbar a:hover, .tm-toolbar .uk-link:hover { + color: #128DD5!important; +} + +.uk-navbar-dropdown-nav>li.uk-active>a { + color: #128DD5!important; +} +.uk-light .uk-navbar-nav > li > a:active, .uk-section-primary:not(.uk-preserve-color) .uk-navbar-nav > li > a:active, +.uk-section-secondary:not(.uk-preserve-color) .uk-navbar-nav > li > a:active, +.uk-card-primary.uk-card-body .uk-navbar-nav > li > a:active, .uk-card-primary > :not([class * ='uk-card-media']) .uk-navbar-nav > li > a:active, +.uk-card-secondary.uk-card-body .uk-navbar-nav > li > a:active, .uk-card-secondary > :not([class * ='uk-card-media']) .uk-navbar-nav > li > a:active, +.uk-overlay-primary .uk-navbar-nav > li > a:active, .uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-nav > li > a:active, +.uk-offcanvas-bar .uk-navbar-nav > li > a:active, .tm-toolbar .uk-navbar-nav > li > a:active { + color: #292C3D!important; +} + +.uk-light .uk-navbar-nav > li.uk-active > a, .uk-section-primary:not(.uk-preserve-color) .uk-navbar-nav > li.uk-active > a, +.uk-section-secondary:not(.uk-preserve-color) .uk-navbar-nav > li.uk-active > a, +.uk-card-primary.uk-card-body .uk-navbar-nav > li.uk-active > a, .uk-card-primary > :not([class * ='uk-card-media']) .uk-navbar-nav > li.uk-active > a, +.uk-card-secondary.uk-card-body .uk-navbar-nav > li.uk-active > a, +.uk-card-secondary > :not([class * ='uk-card-media']) .uk-navbar-nav > li.uk-active > a, +.uk-overlay-primary .uk-navbar-nav > li.uk-active > a, .uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-nav > li.uk-active > a, +.uk-offcanvas-bar .uk-navbar-nav > li.uk-active > a, .tm-toolbar .uk-navbar-nav > li.uk-active > a { + color: #292C3D!important; +} +.uk-light .uk-navbar-nav>li>a:active, .uk-section-primary:not(.uk-preserve-color) .uk-navbar-nav>li>a:active, .uk-section-secondary:not(.uk-preserve-color) .uk-navbar-nav>li>a:active, .uk-card-primary.uk-card-body .uk-navbar-nav>li>a:active, .uk-card-primary>:not([class*='uk-card-media']) .uk-navbar-nav>li>a:active, .uk-card-secondary.uk-card-body .uk-navbar-nav>li>a:active, .uk-card-secondary>:not([class*='uk-card-media']) .uk-navbar-nav>li>a:active, .uk-overlay-primary .uk-navbar-nav>li>a:active, .uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-nav>li>a:active, .uk-offcanvas-bar .uk-navbar-nav>li>a:active, .tm-toolbar .uk-navbar-nav>li>a:active { +color:#128DD5!important; +} + +.uk-navbar-dropdown-nav { + font-size:14px; +} +.uk-navbar-nav>li>a, .uk-navbar-item, .uk-navbar-toggle, .navbar .brand, .navbar-search, .navbar .nav>li>a { + font-size: 14px; + font-family: Roboto; + font-family: "Merriweather", serif; + font-family: 'Merriweather Sans', sans-serif; + font-family: 'Roboto Slab', serif; + font-size: 16px; + line-height: 23px; +text-transform:none; +color: rgba(0, 0, 0, 0.8)!important; + font-weight: 500 !important; +} +.uk-nav-default .uk-nav-header, +.uk-navbar-dropdown-nav .uk-nav-header { +color: #245CCF; +font-size:14px; +} + +.sidemenu .uk-h3{ + +padding-bottom: 15px; +font-weight: 300; +text-transform: none; +color:#040067; +} +.sidemenu .uk-nav, .uk-nav ul, .dropdown-menu { +font-weight: 300; +font-size: 14px; +color: #80828B; + +} +.sidemenu ul>li>ul, .sidemenu ul>li>ol, .sidemenu ol>li>ol, .sidemenu ol>li>ul{ +padding-left: 40px; +} +.sidemenu ul>li>ul a { +color: #80828B!important; +color: rgba(99, 104, 114, 0.8)!important; +} +.sidemenu ul>li>ul a:hover { +color: #D53B23!important; +} +.uk-nav-header:not(:first-child) {margin-top:10px;} +.uk-navbar-dropdown, .navbar .nav>li>.dropdown-menu { + background:#fff; +} +.uk-nav>li>a, +.uk-navbar-dropdown-nav>li>a, +.uk-navbar-dropdown-nav .uk-nav-sub a { + color:#292C3D; + font-weight:300; + padding:4px 0; +} +.uk-section-secondary:not(.uk-preserve-color) h3, +.uk-section-secondary:not(.uk-preserve-color) h3 a, +.uk-section-secondary:not(.uk-preserve-color) a:hover { color:#444!important;} + + +.uk-article-title { +font-size: 38px; +line-height: 1.1; +} + +.uk-text-meta { +font-size: 14px; +line-height: 1.4; +color: #90929D; +font-family: PT Serif; +font-weight: 400; +text-transform: none; +letter-spacing: 0; +font-style: italic; +} +.uk-card-default .uk-card-title { +color: #292C3D !important; + +} +.uk-light .uk-text-meta, .uk-section-primary:not(.uk-preserve-color) .uk-text-meta, .uk-section-secondary:not(.uk-preserve-color) .uk-text-meta, .uk-card-primary.uk-card-body .uk-text-meta, .uk-card-primary>:not([class*='uk-card-media']) .uk-text-meta, .uk-card-secondary.uk-card-body .uk-text-meta, .uk-card-secondary>:not([class*='uk-card-media']) .uk-text-meta, .uk-overlay-primary .uk-text-meta, .uk-navbar-container:not(.uk-navbar-transparent) .uk-text-meta, .uk-offcanvas-bar .uk-text-meta, .tm-toolbar .uk-text-meta{ +color: #90929D; +} + +.uk-text-primary {color: #040067!important;} +.uk-text-secondary {color: #00a0de!important;} +.uk-section-primary { + background: #040067; +} +.uk-section-secondary { + background: #00a0de; +} +.first_page_section { + /*position: relative;*/ + } +.first_page_section .uk-section>:last-child { +position: relative; +top: 50%; +transform: translateY(-50%); +} + +.first_page_section .first_page_banner_headline { + /*position: relative;*/ + font-family: 'Open Sans', sans-serif; + font-weight: 300; + color:#fff; + +} +.first_page_panel h3.uk-h1 { + color:#fff; +} +.first_page_panel { + border: 0px solid #e5e5e7!important; + padding:20px 20px!important; +/*width:100%!important;*/ + font-size:24pt!important; + padding:20px!important; + color:#fff; +} +.first_page_panel .banner_text_bottom { + font-size:20pt; + padding:20px; +} +.mainHdr {background-color: rgb(4, 0, 103)!important; +} + + +/*tabs*/ +.wk-tab::before { + content: ""; + position: absolute; + bottom: 0; + left: 20px; + right: 0; + border-bottom: 1px solid #e5e5e5; +} +.wk-tab>li.wk-active>a { +border-color: transparent transparent #1678CB transparent !important; +background:tranparent; +border-bottom: 2px solid #1678CB; +} +.wk-tab>*>a { + display: block; + text-align: center; + padding: 9px 20px; + color: #444!important; + border-bottom: 2px solid transparent; + font-size: 12px; + text-transform: uppercase; + -webkit-transition: color 0.1s ease-in-out; + transition: color 0.1s ease-in-out; + line-height: 20px; +} + +.wk-tab>li.wk-open>a, .wk-tab>li>a:focus, .wk-tab>li>a:hover { +border-color: transparent transparent #1678CB transparent !important; +background: transparent!important; +color: #1678CB!important; +outline: 0 +} + +.serviceicon .wk-panel h3{ text-transform: uppercase!important; font-weight: 700; font-size:12px; +} +.serviceicon .wk-panel:hover h3{ + color: #D53B23!important; +} +.serviceicon .wk-margin, +.serviceicon .wk-panel-teaser, .serviceicon .wk-panel-title {margin-bottom:10px;} +.serviceicon *+.wk-margin {margin-top:10px;} + +.key_message { + color: #128DD5!important; +} +.larger-font { + font-size:120%; +} + +.nspArt h4.nspHeader { +font-family: 'Open Sans', sans-serif !important; +font-weight: 400; +font-size: 16px; +margin: 0; +padding: 5px 0 5px 0; +} +.nspArt p, .nspArt ul, .nspArt ol, .nspArt dl, .nspArt pre, .nspArt address, .nspArt fieldset, .nspArt figure { + margin-top: 0px; + margin-bottom: 8px; +} +.nspArt p.nspText {margin-bottom:15px;} +.readon , .readon:link{ + margin: 0; + border: 1px solid #eaeaea; + overflow: visible; + font: inherit; + color: inherit; + text-transform: none; + display: inline-block; + box-sizing: border-box; + padding: 0 25px; + vertical-align: middle; + font-size: 13px; + line-height: 40px; + text-align: center; + text-decoration: none; + -webkit-transition: .1s ease-in-out; + transition: .1s ease-in-out; + -webkit-transition-property: color, background-color, border-color, box-shadow; + transition-property: color, background-color, border-color, box-shadow; + font-family: Roboto; + font-weight: normal; + text-transform: uppercase; + border-radius: 2px; + background-color: #fff; + color: #5b5b5b; + box-shadow: 0px 3px 12px rgba(0, 0, 0, 0.07); +} + +.readon:hover{ +background-color: #fff; +color: #00a0de; +box-shadow: 0 6px 50px rgba(0, 0, 0, 0.05); +} +.banner_text_white {font-weight: 300; font-size: 28px; color:white;} + + +/*custom classes */ +.partner_slider .wk-link-reset, .partner_slider .wk-link-reset a, .partner_slider .wk-link-reset a:focus, +.partner_slider .wk-link-reset a:hover, .partner_slider .wk-link-reset:focus, .partner_slider .wk-link-reset:hover { +color: black; +} +.dark-divider hr, .dark-divider .uk-hr { +border-top: 1px solid #6c6c6c; +} + +/*events*/ +.calendar h3{text-transform:none; font-weight:300; margin-bottom:5px; margin-top:5px;} +.mod_events_latest_table td { + padding-top:5px; + padding-bottom:5px; +} +.mod_events_latest_table td p{ + margin-bottom:10px; + margin-top:0px; +} + +.mod_events_latest_date { + width: 18%; + float: left; + position: relative; + color:#757575; + color:#fff; + font-size:12px!important; + background: #9c9c9c; + font-weight:400; + /* + border-radius: 1px; + -moz-border-radius: 1px; + -webkit-border-radius: 1px; + border: 1px solid #757575; + -moz-box-shadow: 0px 0px 3px #757575; + -webkit-box-shadow: 0px 0px 3px #757575; + box-shadow: 0px 0px 3px #757575; + */ + margin-right:8px; + margin-top:5px; + text-align:center; + padding:10px 0px; + line-height:20px; + +} +.mod_events_latest_date .larger_font { + font-size:28px!important; + font-weight:700!important;} + +.mod_events_latest_time { + //float: left; + position: relative; + width: 75%; + overflow:visible; + line-height:14px; + font-weight:400; + font-size:12px; + padding: 5px 0px; + margin-bottom: 8px; + text-transform:none; +} +.mod_events_latest_time { + font-size:12px; +} +.mod_events_latest_table td .content{ + font-size:12px!important; + font-weight:300; + text-transform:none; +} +.mod_events_latest_table td .hdr{ + font-size:14px!important; + line-height: 16px; + font-weight:400!important; + text-transform:none; +} +.mod_events_latest_rsslink a { +color: #767779; + +} +.mod_events_latest_rsslink{ +padding: 30; +line-height: 1.625; +background: 0; +color: #767779; +position: relative; +padding-right: 27px; +margin: 0; +border: 0; +overflow: visible; +font: inherit; +display: block; +box-sizing: border-box; +vertical-align: middle; +font-size: 13px; +display:inline-block; +text-decoration: none; +-webkit-transition: .1s ease-in-out; +transition: .1s ease-in-out; +-webkit-transition-property: color, background-color, border-color, box-shadow; +transition-property: color, background-color, border-color, box-shadow; +font-family: Roboto; +font-weight: normal; +text-transform: uppercase; +border-radius: 2px; +background-origin: border-box; +} +.mod_events_latest_rsslink a:hover { +color: #00a0de; + +} +.mod_events_latest_rsslink:hover::before { +background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%2223%22%20height%3D%2211%22%20viewBox%3D%220%200%2023%2011%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%20%20%3Cpolyline%20fill%3D%22none%22%20stroke%3D%22%2300a0de%22%20points%3D%2217%201%2022%205.5%2017%2010%20%22%3E%3C%2Fpolyline%3E%0A%20%20%20%20%3Cline%20fill%3D%22none%22%20stroke%3D%22%2300a0de%22%20x1%3D%220%22%20y1%3D%225.5%22%20x2%3D%2222.4%22%20y2%3D%225.5%22%3E%3C%2Fline%3E%0A%3C%2Fsvg%3E"); +background-position: 100% 50%; + +} +.mod_events_latest_rsslink::before{ +content: ""; +position: absolute; +top: 0; +bottom: 0; +right: 0; +width: 22px; +background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%2223%22%20height%3D%2211%22%20viewBox%3D%220%200%2023%2011%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%20%20%3Cpolyline%20fill%3D%22none%22%20stroke%3D%22%23767779%22%20points%3D%2217%201%2022%205.5%2017%2010%20%22%3E%3C%2Fpolyline%3E%0A%20%20%20%20%3Cline%20fill%3D%22none%22%20stroke%3D%22%23767779%22%20x1%3D%220%22%20y1%3D%225.5%22%20x2%3D%2222.4%22%20y2%3D%225.5%22%3E%3C%2Fline%3E%0A%3C%2Fsvg%3E"); +background-repeat: no-repeat; +background-position: calc(100% - 5px) 50%; +-webkit-transition: background-position .2s ease-out; +transition: background-position .2s ease-out; +} +.mod_events_latest_callink a, .mod_events_latest_callink a:hover{ + color: #fff!important; +} +.mod_events_latest_callink { +padding:0px; + margin:10px 0px; + background-color: #00a0de; + color: #fff!important; + display: inline-block; + box-sizing: border-box; +padding: 0 25px; +vertical-align: middle; +font-size: 13px; +line-height: 40px; +text-align: center; +text-decoration: none; +-webkit-transition: .1s ease-in-out; +transition: .1s ease-in-out; +-webkit-transition-property: color, background-color, border-color, box-shadow; +transition-property: color, background-color, border-color, box-shadow; +font-family: Roboto; +font-weight: normal; +text-transform: uppercase; +border-radius: 2px; +background-origin: border-box; +} + +.mod_events_latest_callink:hover { +background-color: #008ec5; +color: #fff!important; +} +/* news pro */ +.nspLinks ul li h4 { +font-weight: 400; +font-size: 16px; +line-height: 18px; +} +.nspLinks ul li p { + text-transform:none; + font-size: 14px; + font-weight:300; + margin:10px; +} +.readon-button{ +text-transform: none; +font-size: 14px; +line-height: 20px; +font-weight: 300; +font-family: 'Open Sans', sans-serif !important; +} +.readon-button:hover { +} +.newsletter .uk-h2 {font-size:28px!important;} +.newsletter .uk-icon { +padding-left: 10px; +padding-bottom: 15px; +vertical-align: middle; +} +.newsletter .el-title{ +display: inline-block; +fill: currentcolor; +margin-bottom:0; +} + +.newsletter .acymailing_mootoolsbutton a:link, +.newsletter .acymailing_mootoolsbutton a:visited { +background:none!important; +border:none!important; +text-shadow:none!important; +color: rgba(255, 255, 255, 0.5)!important; +font-size: 14px; +font-weight: 300; +line-height: 20px; +} + +.newsletter .acysubbuttons input.button, .newsletter .acysubbuttons .button { +padding: 0 15px!important; +line-height: 30px; +font-size: 13px; +border-radius: 2px; +margin: 0; +border: 0; +overflow: visible; +font-family: Roboto; +font-weight: normal; + +color: inherit; +text-transform: none; +display: inline-block; +box-sizing: border-box; +vertical-align: middle; +text-align: center; +text-decoration: none; +-webkit-transition: .1s ease-in-out; +transition: .1s ease-in-out; +-webkit-transition-property: color, background-color, border-color, box-shadow; +transition-property: color, background-color, border-color, box-shadow; +font-family: Roboto; +font-weight: normal; +text-transform: uppercase; +background-origin: border-box; +box-shadow: 0 3px 12px rgba(0, 0, 0, 0.07); +} + +.newsletter .acysubbuttons input.button:hover, .newsletter .acysubbuttons .button:hover { +color:#444; +background-color:#fff!important; +background-image:none!important; +} + +.newsletter .acysubbuttons input.button:hover, .newsletter .acysubbuttons .button:hover, +.newsletter .acysubbuttons button.validate:hover, .newsletter .acymailing_mootoolsbutton a:hover, +.newsletter .acymailing_mootoolsbutton a:active { +box-shadow:none!important; +-moz-box-shadow:none!important; +-webkit-box-shadow:none!important; +color: #00a0de!important; +box-shadow: 0 6px 50px rgba(0, 0, 0, 0.05)!important; +} +.acymailing_module a.acymailing_togglemodule { +font-size: 14px; +font-weight: 300; +color: rgba(255, 255, 255, 0.5)!important; +} + + +/*login button */ +#btl .btl-panel > span .btl-dropdown { border:3!important;} + +#btl .btl-panel > span{ + border: 0px!important; + background-color: transparent!important; + color:#444!important; + padding-right:30px; + padding-left:6px; + height:0px!important; + line-height:20px!important; + margin:0px !important; + box-shadow: 0px 0px 0px; + border-radius:0px!important; + display: inline-table!important; + text-transform:none!important; + font-size: 14px; + font-family: 'Roboto Slab', serif; + font-size: 16px; + line-height: 23px; + font-weight: 500 !important; +} +.loginLink { +text-transform:none!important; +color: rgba(0, 0, 0, 0.8)!important; +} + +/*.btl-panel { + background: url(../images/key_login.png) right 40% no-repeat; +}*/ +#btl-panel-login >span { + border: 5px solid #d0d0d0!important; +} +.uk-navbar-item .btlogin{ color: red!important; +} + +#btl .btl-panel > #btl-panel-profile { +color: #040067!important; +font-size: 13px !important; +font-family: Roboto; +} + +.btl-content-block { +-webkit-font-smoothing: antialiased; +background-attachment: scroll; +background-clip: border-box; +background-color: rgb(255, 255, 255); +background-image: none; +background-origin: padding-box; +background-size: auto; +border-bottom-left-radius: 2px; +border-bottom-right-radius: 2px; +border-top-left-radius: 2px; +border-top-right-radius: 2px; +box-shadow: rgba(41, 44, 61, 0.0980392) 2px 15px 50px 0px; +box-sizing: border-box; +color: rgb(79, 82, 96); +display: none; +height: auto; +margin-top: 0px; +padding-bottom: 25px; +padding-left: 25px; +padding-right: 25px; +padding-top: 25px; +position: absolute; +text-align: left; +text-rendering: optimizeLegibility; +} + +#btl-content #btl-content-profile #module-in-profile ul li img, +#btl-content #btl-content-profile #module-in-profile ul li a {padding-right: 5px!important;} + +#btl-content #btl-content-profile #module-in-profile ul li a { +-webkit-font-smoothing: antialiased; +-webkit-text-decoration-skip: objects; +/*background-color: rgba(0, 0, 0, 0);*/ +box-sizing: border-box; +color: rgb(41, 44, 61); +cursor: pointer; +display: block; +font-family: Roboto; +font-size: 14px; +font-weight: 300; +height: auto; +line-height: 20px; +list-style-image: none; +list-style-position: outside; +list-style-type: none; +padding-bottom: 6px; +padding-left: 0px; +padding-right: 0px; +padding-top: 6px; +text-align: left; +text-decoration: none; +text-rendering: optimizeLegibility; +width: auto; +} + +#module-in-profile ul li a:hover { +color: #128DD5 !important; +} + +/*FAQs*/ + +.searchifaq label { +font-family: Roboto, sans-serif; +font-weight:500; +font-size:16px; +color: #040067; +} +.btn, +.buttonifaq{ +margin-top:10px; +background-color: #fff; + color: #5b5b5b; + box-shadow: 0 3px 12px rgba(0,0,0,0.07); + display: inline-block; + border:none; + box-sizing: border-box; + padding: 0 25px; + vertical-align: middle; + font-size: 13px; + line-height: 40px; + text-align: center; + text-decoration: none; + -webkit-transition: .1s ease-in-out; + transition: .1s ease-in-out; + -webkit-transition-property: color,background-color,border-color,box-shadow; + transition-property: color,background-color,border-color,box-shadow; + font-family: Roboto; + font-weight: normal; + text-transform: uppercase; + border-radius: 2px; + background-origin: border-box; + } +.buttonifaq:hover{ background-color: #fff; + color: #00a0de; + box-shadow: 0 6px 50px rgba(0,0,0,0.05); +} +.ifaq h5.ifaq-item-header { +margin-bottom:10px; +margin-top:10px; +} +.ifaq-tpl-clean_blue_arrow .collapse-open .ifaq-item-header { +font-weight:normal; +} +.ifaq .uk-tab>*>a, .ifaq .nav-tabs>li>a { +text-align:left; +color: #2D72D6; +} +.ifaq .nav-tabs>li>a:hover { + border-color:transparent; + color: #D53B23; +} + +.ifaq .nav>li>a:hover, .ifaq .nav>li>a:focus { background:none;} + +.ifaq-tpl-clean_blue_arrow .ifaq-panel { +box-shadow:none; + border-bottom: 1px solid #eee; + +} + +.ifaq-tpl-clean_blue_arrow .ifaq-collapsible > a { +display: block; padding: 1px 0 1px 0px; +background-image:url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%2213%22%20height%3D%2213%22%20viewBox%3D%220%200%2013%2013%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%20%20%3Crect%20fill%3D%22%236C6D74%22%20width%3D%2213%22%20height%3D%221%22%20x%3D%220%22%20y%3D%226%22%3E%3C%2Frect%3E%0A%20%20%20%20%3Crect%20fill%3D%22%236C6D74%22%20width%3D%221%22%20height%3D%2213%22%20x%3D%226%22%20y%3D%220%22%3E%3C%2Frect%3E%0A%3C%2Fsvg%3E"); +background-repeat: no-repeat; +background-position: 98% 50%; +} + +.ifaq-tpl-clean_blue_arrow .ifaq-collapsible { + text-shadow:none; + background:transparent; + box-shadow:none; + border-bottom: 1px solid #eee; +} +.ifaq-tpl-clean_blue_arrow .collapse-open, .ifaq-tpl-clean_blue_arrow .collapse-open > a { + background: transparent; + background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%2213%22%20height%3D%2213%22%20viewBox%3D%220%200%2013%2013%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%20%20%3Crect%20fill%3D%22%236C6D74%22%20width%3D%2213%22%20height%3D%221%22%20x%3D%220%22%20y%3D%226%22%3E%3C%2Frect%3E%0A%3C%2Fsvg%3E"); +background-repeat: no-repeat; + background-position: 98% 50%; +} +.ifaq-tpl-clean_blue_arrow .collapse-close:hover { + background:transparent; +} + +.ifaq-tpl-clean_blue_arrow .ifaq-collapsible > a:hover { +background-image:url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%2213%22%20height%3D%2213%22%20viewBox%3D%220%200%2013%2013%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%20%20%3Crect%20fill%3D%22%236C6D74%22%20width%3D%2213%22%20height%3D%221%22%20x%3D%220%22%20y%3D%226%22%3E%3C%2Frect%3E%0A%20%20%20%20%3Crect%20fill%3D%22%236C6D74%22%20width%3D%221%22%20height%3D%2213%22%20x%3D%226%22%20y%3D%220%22%3E%3C%2Frect%3E%0A%3C%2Fsvg%3E"); + background-repeat: no-repeat; + background-position: 98% 50%; +} + +.ifaq-tpl-clean_blue_arrow .collapse-open > a:hover { +background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%2213%22%20height%3D%2213%22%20viewBox%3D%220%200%2013%2013%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%20%20%3Crect%20fill%3D%22%236C6D74%22%20width%3D%2213%22%20height%3D%221%22%20x%3D%220%22%20y%3D%226%22%3E%3C%2Frect%3E%0A%3C%2Fsvg%3E"); +background-repeat: no-repeat; +background-position: 98% 50%; +} + +/*widget accordion */ +.wk-accordion, .wk-text-left {display:block!important;} + + +.faq .wk-accordion-title { + text-transform:none; + font-weight: 400; + font-size:16px; +} + +/* for DISCOVERY PORTAL */ +.discoverHrd {background-color: #f25f30!important;} + +.search_box_bg .uk-input, .search_box_bg .uk-input:focus { +background-color: rgba(255, 255, 255, 1.0)!important; +color: rgba(0, 0, 0, 1.0)!important; +} +.search_box_bg .uk-input::placeholder{ +color: rgba(0, 0, 0, 0.6)!important; +} + +.search_box_bg.uk-text-background{ +background-color: rgba(255, 255, 255, 0.7)!important; +font-size:28px!important; +font-weight: 500; +} +.search_box_bg .uk-grid-divider>:not(.uk-first-column)::before { +border-left-color: rgba(255, 255, 255, 0.6)!important; +} + +/*tags */ +.uk-label-arrow{ + display: inline-block; + height: 21px; + margin: 0 10px 0 0; + padding: 0 7px 0 14px; + white-space: nowrap; + position: relative; + + background-color: #5A9EDA; + + color: white; + font: normal 11px/21px Arial, Tahoma, sans-serif; + text-decoration: none; + + border-top: 1px solid #5A9EDA; + border-bottom: 1px solid #5A9EDA; + border-right: 1px solid #5A9EDA; + border-radius: 1px 3px 3px 1px; +} +.uk-label-arrow:before { + content: ''; + position: absolute; + top: 5px; + left: -6px; + width: 10px; + height: 10px; + + background-color: #5A9EDA; + border-left: 1px solid #5A9EDA; + border-bottom: 1px solid #5A9EDA; + border-radius: 0 0 0 2px; +} +.uk-label-arrow:before { + -webkit-transform: scale(1, 1.5) rotate(45deg); + -moz-transform: scale(1, 1.5) rotate(45deg); + -ms-transform: scale(1, 1.5) rotate(45deg); + transform: scale(1, 1.5) rotate(45deg); +} +.uk-label-arrow:after { + content: ''; + position: absolute; + top: 7px; + left: 1px; + width: 5px; + height: 5px; + background: #FFF; + border-radius: 4px; + border: 1px solid #5A9EDA; +} +.uk-label-arrow a:hover { + color: #FFF; + text-shadow: -1px -1px 0 rgba(153,102,51,0.3); +} +.featurednews.uk-card-default { +background: rgba(255,255,255, 0.6)!important; +color: black; +} + +.omtd_secondary > .uk-section-default, +.omtd_secondary.uk-section-default{ + background:#E7F3F2!important; +} \ No newline at end of file diff --git a/portal-4cli/src/assets/common/ec_logo_inv_small.png b/portal-4cli/src/assets/common/ec_logo_inv_small.png new file mode 100644 index 00000000..60f14621 Binary files /dev/null and b/portal-4cli/src/assets/common/ec_logo_inv_small.png differ diff --git a/portal-4cli/src/assets/common/jquery.js b/portal-4cli/src/assets/common/jquery.js new file mode 100644 index 00000000..e8364758 --- /dev/null +++ b/portal-4cli/src/assets/common/jquery.js @@ -0,0 +1,5 @@ +/*! jQuery v1.12.4 | (c) jQuery Foundation | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="1.12.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!k.call(a,"constructor")&&!k.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(!l.ownFirst)for(b in a)return k.call(a,b);for(b in a);return void 0===b||k.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(h)return h.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=e.call(arguments,2),d=function(){return a.apply(b||this,c.concat(e.call(arguments)))},d.guid=a.guid=a.guid||n.guid++,d):void 0},now:function(){return+new Date},support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+N+")*)|.*)\\)|)",P=new RegExp(L+"+","g"),Q=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),R=new RegExp("^"+L+"*,"+L+"*"),S=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),T=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),U=new RegExp(O),V=new RegExp("^"+M+"$"),W={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M+"|[*])"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,$=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,_=/[+~]/,aa=/'|\\/g,ba=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),ca=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(aa,"\\$&"):b.setAttribute("id",k=u),r=g(a),h=r.length,l=V.test(k)?"#"+k:"[id='"+k+"']";while(h--)r[h]=l+" "+qa(r[h]);s=r.join(","),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(Q,"$1"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ia(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ia(function(a){var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",O)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Z.test(o.compareDocumentPosition),t=b||Z.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fa.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fa.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fa.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fa.selectors={cacheLength:50,createPseudo:ha,match:W,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ba,ca),a[3]=(a[3]||a[4]||a[5]||"").replace(ba,ca),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fa.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&U.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ba,ca).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fa.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(P," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,"$1"));return d[u]?ha(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||"")||fa.error("unsupported lang: "+a),a=a.replace(ba,ca).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Y.test(a.nodeName)},input:function(a){return X.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function ra(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(Q,"$1"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ia(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ja("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ja("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute("disabled")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,y=/^.[^:#\[\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,"string"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,"string"==typeof a){if(e="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}if(f=d.getElementById(e[2]),f&&f.parentNode){if(f.id!==e[2])return A.find(a);this.length=1,this[0]=f}return this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,"parentNode")},parentsUntil:function(a,b,c){return u(a,"parentNode",c)},next:function(a){return F(a,"nextSibling")},prev:function(a){return F(a,"previousSibling")},nextAll:function(a){return u(a,"nextSibling")},prevAll:function(a){return u(a,"previousSibling")},nextUntil:function(a,b,c){return u(a,"nextSibling",c)},prevUntil:function(a,b,c){return u(a,"previousSibling",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||(e=n.uniqueSort(e)),D.test(a)&&(e=e.reverse())),this.pushStack(e)}});var G=/\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=!0,c||j.disable(),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler("ready"),n(d).off("ready"))))}});function J(){d.addEventListener?(d.removeEventListener("DOMContentLoaded",K),a.removeEventListener("load",K)):(d.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(d.addEventListener||"load"===a.event.type||"complete"===d.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll)a.setTimeout(n.ready);else if(d.addEventListener)d.addEventListener("DOMContentLoaded",K),a.addEventListener("load",K);else{d.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&d.documentElement}catch(e){}c&&c.doScroll&&!function f(){if(!n.isReady){try{c.doScroll("left")}catch(b){return a.setTimeout(f,50)}J(),n.ready()}}()}return I.promise(b)},n.ready.promise();var L;for(L in n(l))break;l.ownFirst="0"===L,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c,e;c=d.getElementsByTagName("body")[0],c&&c.style&&(b=d.createElement("div"),e=d.createElement("div"),e.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(e).appendChild(b),"undefined"!=typeof b.style.zoom&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",l.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(e))}),function(){var a=d.createElement("div");l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}a=null}();var M=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b},N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0; +}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(M(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),"object"!=typeof b&&"function"!=typeof b||(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f}}function S(a,b,c){if(M(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=void 0)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},Z=/^(?:checkbox|radio)$/i,$=/<([\w:-]+)/,_=/^$|\/(?:java|ecma)script/i,aa=/^\s+/,ba="abbr|article|aside|audio|bdi|canvas|data|datalist|details|dialog|figcaption|figure|footer|header|hgroup|main|mark|meter|nav|output|picture|progress|section|summary|template|time|video";function ca(a){var b=ba.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}!function(){var a=d.createElement("div"),b=d.createDocumentFragment(),c=d.createElement("input");a.innerHTML="
    a",l.leadingWhitespace=3===a.firstChild.nodeType,l.tbody=!a.getElementsByTagName("tbody").length,l.htmlSerialize=!!a.getElementsByTagName("link").length,l.html5Clone="<:nav>"!==d.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,b.appendChild(c),l.appendChecked=c.checked,a.innerHTML="",l.noCloneChecked=!!a.cloneNode(!0).lastChild.defaultValue,b.appendChild(a),c=d.createElement("input"),c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),a.appendChild(c),l.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!!a.addEventListener,a[n.expando]=1,l.attributes=!a.getAttribute(n.expando)}();var da={option:[1,""],legend:[1,"
    ","
    "],area:[1,"",""],param:[1,"",""],thead:[1,"","
    "],tr:[2,"","
    "],col:[2,"","
    "],td:[3,"","
    "],_default:l.htmlSerialize?[0,"",""]:[1,"X
    ","
    "]};da.optgroup=da.option,da.tbody=da.tfoot=da.colgroup=da.caption=da.thead,da.th=da.td;function ea(a,b){var c,d,e=0,f="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,ea(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function fa(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}var ga=/<|&#?\w+;/,ha=/r;r++)if(g=a[r],g||0===g)if("object"===n.type(g))n.merge(q,g.nodeType?[g]:g);else if(ga.test(g)){i=i||p.appendChild(b.createElement("div")),j=($.exec(g)||["",""])[1].toLowerCase(),m=da[j]||da._default,i.innerHTML=m[1]+n.htmlPrefilter(g)+m[2],f=m[0];while(f--)i=i.lastChild;if(!l.leadingWhitespace&&aa.test(g)&&q.push(b.createTextNode(aa.exec(g)[0])),!l.tbody){g="table"!==j||ha.test(g)?""!==m[1]||ha.test(g)?0:i:i.firstChild,f=g&&g.childNodes.length;while(f--)n.nodeName(k=g.childNodes[f],"tbody")&&!k.childNodes.length&&g.removeChild(k)}n.merge(q,i.childNodes),i.textContent="";while(i.firstChild)i.removeChild(i.firstChild);i=p.lastChild}else q.push(b.createTextNode(g));i&&p.removeChild(i),l.appendChecked||n.grep(ea(q,"input"),ia),r=0;while(g=q[r++])if(d&&n.inArray(g,d)>-1)e&&e.push(g);else if(h=n.contains(g.ownerDocument,g),i=ea(p.appendChild(g),"script"),h&&fa(i),c){f=0;while(g=i[f++])_.test(g.type||"")&&c.push(g)}return i=null,p}!function(){var b,c,e=d.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b]=c in a)||(e.setAttribute(c,"t"),l[b]=e.attributes[c].expando===!1);e=null}();var ka=/^(?:input|select|textarea)$/i,la=/^key/,ma=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,na=/^(?:focusinfocus|focusoutblur)$/,oa=/^([^.]*)(?:\.(.+)|)/;function pa(){return!0}function qa(){return!1}function ra(){try{return d.activeElement}catch(a){}}function sa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)sa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=qa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return"undefined"==typeof n||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(G)||[""],h=b.length;while(h--)f=oa.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(G)||[""],j=b.length;while(j--)if(h=oa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,e,f){var g,h,i,j,l,m,o,p=[e||d],q=k.call(b,"type")?b.type:b,r=k.call(b,"namespace")?b.namespace.split("."):[];if(i=m=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!na.test(q+n.event.triggered)&&(q.indexOf(".")>-1&&(r=q.split("."),q=r.shift(),r.sort()),h=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=r.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:n.makeArray(c,[b]),l=n.event.special[q]||{},f||!l.trigger||l.trigger.apply(e,c)!==!1)){if(!f&&!l.noBubble&&!n.isWindow(e)){for(j=l.delegateType||q,na.test(j+q)||(i=i.parentNode);i;i=i.parentNode)p.push(i),m=i;m===(e.ownerDocument||d)&&p.push(m.defaultView||m.parentWindow||a)}o=0;while((i=p[o++])&&!b.isPropagationStopped())b.type=o>1?j:l.bindType||q,g=(n._data(i,"events")||{})[b.type]&&n._data(i,"handle"),g&&g.apply(i,c),g=h&&i[h],g&&g.apply&&M(i)&&(b.result=g.apply(i,c),b.result===!1&&b.preventDefault());if(b.type=q,!f&&!b.isDefaultPrevented()&&(!l._default||l._default.apply(p.pop(),c)===!1)&&M(e)&&h&&e[q]&&!n.isWindow(e)){m=e[h],m&&(e[h]=null),n.event.triggered=q;try{e[q]()}catch(s){}n.event.triggered=void 0,m&&(e[h]=m)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())a.rnamespace&&!a.rnamespace.test(g.namespace)||(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]","i"),va=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,wa=/\s*$/g,Aa=ca(d),Ba=Aa.appendChild(d.createElement("div"));function Ca(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function Da(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function Ea(a){var b=ya.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Fa(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Ga(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(Da(b).text=a.text,Ea(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&Z.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}}function Ha(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&"string"==typeof q&&!l.checkClone&&xa.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(o&&(k=ja(b,a[0].ownerDocument,!1,a,d),e=k.firstChild,1===k.childNodes.length&&(k=e),e||d)){for(i=n.map(ea(k,"script"),Da),h=i.length;o>m;m++)g=k,m!==p&&(g=n.clone(g,!0,!0),h&&n.merge(i,ea(g,"script"))),c.call(a[m],g,m);if(h)for(j=i[i.length-1].ownerDocument,n.map(i,Ea),m=0;h>m;m++)g=i[m],_.test(g.type||"")&&!n._data(g,"globalEval")&&n.contains(j,g)&&(g.src?n._evalUrl&&n._evalUrl(g.src):n.globalEval((g.text||g.textContent||g.innerHTML||"").replace(za,"")));k=e=null}return a}function Ia(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(ea(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&fa(ea(d,"script")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(va,"<$1>")},clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!ua.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(Ba.innerHTML=a.outerHTML,Ba.removeChild(f=Ba.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=ea(f),h=ea(a),g=0;null!=(e=h[g]);++g)d[g]&&Ga(e,d[g]);if(b)if(c)for(h=h||ea(a),d=d||ea(f),g=0;null!=(e=h[g]);g++)Fa(e,d[g]);else Fa(a,f);return d=ea(f,"script"),d.length>0&&fa(d,!i&&ea(a,"script")),d=h=e=null,f},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.attributes,m=n.event.special;null!=(d=a[h]);h++)if((b||M(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k||"undefined"==typeof d.removeAttribute?d[i]=void 0:d.removeAttribute(i),c.push(f))}}}),n.fn.extend({domManip:Ha,detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return Y(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||d).createTextNode(a))},null,a,arguments.length)},append:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(ea(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return Y(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(ta,""):void 0;if("string"==typeof a&&!wa.test(a)&&(l.htmlSerialize||!ua.test(a))&&(l.leadingWhitespace||!aa.test(a))&&!da[($.exec(a)||["",""])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ea(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ha(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(ea(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],f=n(a),h=f.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(f[d])[b](c),g.apply(e,c.get());return this.pushStack(e)}});var Ja,Ka={HTML:"block",BODY:"block"};function La(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],"display");return c.detach(),d}function Ma(a){var b=d,c=Ka[a];return c||(c=La(a,b),"none"!==c&&c||(Ja=(Ja||n("',t,e)};s.onerror=function(){return a(640,320)},s.onload=function(){120===s.width&&90===s.height?r?a(640,320):(r=!0,s.src="//img.youtube.com/vi/"+o+"/0.jpg"):a(s.width,s.height)},s.src="//img.youtube.com/vi/"+o+"/maxresdefault.jpg",t.stopImmediatePropagation()}}}},"lightbox"),t.mixin({events:{showitem:function(t){var e,i=this,o=this.getItem();if(e=o.source.match(/(\/\/.*?)vimeo\.[a-z]+\/([0-9]+).*?/)){var s=e[2],r=function(t,e){return i.setItem(o,'',t,e)};n({type:"GET",url:"http://vimeo.com/api/oembed.json?url="+encodeURI(o.source),jsonp:"callback",dataType:"jsonp"}).then(function(t){return r(t.width,t.height)}),t.stopImmediatePropagation()}}}},"lightbox")}}function qt(t){if(!qt.installed){var e=t.util,i=e.$,n=e.each,o=e.pointerEnter,s=e.pointerLeave,r=e.Transition,a={};t.component("notification",{functional:!0,args:["message","status"],defaults:{message:"",status:"",timeout:5e3,group:null,pos:"top-center",onClose:null,clsClose:"uk-notification-close"},created:function(){a[this.pos]||(a[this.pos]=i('
    ').appendTo(t.container)),this.$mount(i('
    \n \n
    '+this.message+"
    \n
    ").appendTo(a[this.pos].show())[0])},ready:function(){var t=this,e=parseInt(this.$el.css("margin-bottom"),10);r.start(this.$el.css({opacity:0,marginTop:-1*this.$el.outerHeight(),marginBottom:0}),{opacity:1,marginTop:0,marginBottom:e}).then(function(){t.timeout&&(t.timer=setTimeout(t.close,t.timeout),t.$el.on(o,function(){return clearTimeout(t.timer)}).on(s,function(){return t.timer=setTimeout(t.close,t.timeout)}))})},events:{click:function(t){i(t.target).closest('a[href="#"]').length&&t.preventDefault(),this.close()}},methods:{close:function(t){var e=this,i=function(){e.onClose&&e.onClose(),e.$el.trigger("close",[e]).remove(),a[e.pos].children().length||a[e.pos].hide()};this.timer&&clearTimeout(this.timer),t?i():r.start(this.$el,{opacity:0,marginTop:-1*this.$el.outerHeight(),marginBottom:0}).then(i)}}}),t.notification.closeAll=function(e,i){n(t.instances,function(t,n){"notification"!==n.$options.name||e&&e!==n.group||n.close(i)})}}}function Yt(t){function e(i){return t.getComponent(i,"sortable")||i.parentNode&&e(i.parentNode)}function i(){var t=setTimeout(function(){return r.trigger("click")},0),e=function(i){i.preventDefault(),i.stopPropagation(),clearTimeout(t),u(r,"click",e,!0)};c(r,"click",e,!0)}if(!Yt.installed){var n=t.mixin,o=t.util,s=o.$,r=o.docElement,a=o.extend,l=o.getDimensions,h=o.isWithin,c=o.on,u=o.off,d=o.offsetTop,f=o.pointerDown,p=o.pointerMove,g=o.pointerUp,m=o.promise,v=o.win;t.component("sortable",{mixins:[n.class],props:{group:String,animation:Number,threshold:Number,clsItem:String,clsPlaceholder:String,clsDrag:String,clsDragState:String,clsBase:String,clsNoDrag:String,clsEmpty:String,clsCustom:String,handle:String},defaults:{group:!1,animation:150,threshold:5,clsItem:"uk-sortable-item",clsPlaceholder:"uk-sortable-placeholder",clsDrag:"uk-sortable-drag",clsDragState:"uk-drag",clsBase:"uk-sortable",clsNoDrag:"uk-sortable-nodrag",clsEmpty:"uk-sortable-empty",clsCustom:"",handle:!1},init:function(){var t=this;["init","start","move","end"].forEach(function(e){var i=t[e];t[e]=function(e){e=e.originalEvent||e,t.scrollY=window.scrollY;var n=e.touches&&e.touches[0]||e,o=n.pageX,s=n.pageY;t.pos={x:o,y:s},i(e)}})},events:(w={},w[f]="init",w),update:{write:function(){var t=this;if(this.clsEmpty&&this.$el.toggleClass(this.clsEmpty,!this.$el.children().length),this.drag){this.drag.offset({top:this.pos.y+this.origin.top,left:this.pos.x+this.origin.left});var e=d(this.drag),i=e+this.drag[0].offsetHeight;e>0&&ewindow.innerHeight+this.scrollY&&setTimeout(function(){return v.scrollTop(t.scrollY+5)},5)}}},methods:{init:function(t){var e=s(t.target),i=this.$el.children().filter(function(e,i){return h(t.target,i)});!i.length||e.is(":input")||this.handle&&!h(e,this.handle)||t.button&&0!==t.button||h(e,"."+this.clsNoDrag)||(t.preventDefault(),t.stopPropagation(),this.touched=[this],this.placeholder=i,this.origin=a({target:e,index:this.placeholder.index()},this.pos),r.on(p,this.move),r.on(g,this.end),v.on("scroll",this.scroll),this.threshold||this.start(t))},start:function(e){this.drag=s(this.placeholder[0].outerHTML.replace(/^
  • $/i,"div>")).attr("uk-no-boot","").addClass(this.clsDrag+" "+this.clsCustom).css({boxSizing:"border-box",width:this.placeholder.outerWidth(),height:this.placeholder.outerHeight()}).css(this.placeholder.css(["paddingLeft","paddingRight","paddingTop","paddingBottom"])).appendTo(t.container),this.drag.children().first().height(this.placeholder.children().height());var i=l(this.placeholder),n=i.left,o=i.top;a(this.origin,{left:n-this.pos.x,top:o-this.pos.y}),this.placeholder.addClass(this.clsPlaceholder),this.$el.children().addClass(this.clsItem),r.addClass(this.clsDragState),this.$el.trigger("start",[this,this.placeholder,this.drag]),this.move(e)},move:function(t){if(!this.drag)return void((Math.abs(this.pos.x-this.origin.x)>this.threshold||Math.abs(this.pos.y-this.origin.y)>this.threshold)&&this.start(t));this.$emit();var i="mousemove"===t.type?t.target:document.elementFromPoint(this.pos.x-document.body.scrollLeft,this.pos.y-document.body.scrollTop),n=e(i),o=e(this.placeholder[0]),r=n!==o;if(n&&!h(i,this.placeholder)&&(!r||n.group&&n.group===o.group)){if(i=n.$el.is(i.parentNode)&&s(i)||n.$el.children().has(i),r)o.remove(this.placeholder);else if(!i.length)return;n.insert(this.placeholder,i),~this.touched.indexOf(n)||this.touched.push(n)}},scroll:function(){var t=window.scrollY;t!==this.scrollY&&(this.pos.y+=t-this.scrollY,this.scrollY=t,this.$emit())},end:function(t){if(r.off(p,this.move),r.off(g,this.end),v.off("scroll",this.scroll),!this.drag)return void("mouseup"!==t.type&&h(t.target,"a[href]")&&(location.href=s(t.target).closest("a[href]").attr("href")));i();var n=e(this.placeholder[0]);this===n?this.origin.index!==this.placeholder.index()&&this.$el.trigger("change",[this,this.placeholder,"moved"]):(n.$el.trigger("change",[n,this.placeholder,"added"]),this.$el.trigger("change",[this,this.placeholder,"removed"])),this.$el.trigger("stop",[this]),this.drag.remove(),this.drag=null,this.touched.forEach(function(t){return t.$el.children().removeClass(t.clsPlaceholder+" "+t.clsItem)}),r.removeClass(this.clsDragState)},insert:function(t,e){var i=this;this.$el.children().addClass(this.clsItem);var n=function(){e.length?!i.$el.has(t).length||t.prevAll().filter(e).length?t.insertBefore(e):t.insertAfter(e):i.$el.append(t)};this.animation?this.animate(n):n()},remove:function(t){this.$el.has(t).length&&(this.animation?this.animate(function(){return t.detach()}):t.detach())},animate:function(t){var e=this,i=[],n=this.$el.children().toArray().map(function(t){return t=s(t),i.push(a({position:"absolute",pointerEvents:"none",width:t.outerWidth(),height:t.outerHeight()},t.position())),t}),o={position:"",width:"",height:"",pointerEvents:"",top:"",left:""};t(),n.forEach(function(t){return t.stop()}),this.$el.children().css(o),this.$updateSync("update",!0),this.$el.css("min-height",this.$el.height());var r=n.map(function(t){return t.position()});m.all(n.map(function(t,n){return t.css(i[n]).animate(r[n],e.animation).promise()})).then(function(){e.$el.css("min-height","").children().css(o),e.$updateSync("update",!0)})}}});var w}}function Rt(t){if(!Rt.installed){var e,i=t.util,n=t.mixin,o=i.$,s=i.doc,r=i.fastdom,a=i.flipPosition,l=i.isTouch,h=i.isWithin,c=i.pointerDown,u=i.pointerEnter,d=i.pointerLeave;t.component("tooltip",{attrs:!0,mixins:[n.togglable,n.position],props:{delay:Number,container:Boolean,title:String},defaults:{pos:"top",title:"",delay:0,animation:["uk-animation-scale-up"],duration:100,cls:"uk-active",clsPos:"uk-tooltip",container:!0},computed:{container:function(){return o(!0===this.$props.container&&t.container||this.$props.container||t.container)}},connected:function(){var t=this;r.mutate(function(){return t.$el.removeAttr("title").attr("aria-expanded",!1)})},disconnected:function(){this.hide()},methods:{show:function(){var t=this;e!==this&&(e&&e.hide(),e=this,s.on("click."+this.$options.name,function(e){h(e.target,t.$el)||t.hide()}),clearTimeout(this.showTimer),this.tooltip=o('").appendTo(this.container),this.$el.attr("aria-expanded",!0),this.positionAt(this.tooltip,this.$el),this.origin="y"===this.getAxis()?a(this.dir)+"-"+this.align:this.align+"-"+a(this.dir),this.showTimer=setTimeout(function(){t.toggleElement(t.tooltip,!0),t.hideTimer=setInterval(function(){t.$el.is(":visible")||t.hide()},150)},this.delay))},hide:function(){this.$el.is("input")&&this.$el[0]===document.activeElement||(e=e!==this&&e||!1,clearTimeout(this.showTimer),clearInterval(this.hideTimer),this.$el.attr("aria-expanded",!1),this.toggleElement(this.tooltip,!1),this.tooltip&&this.tooltip.remove(),this.tooltip=!1,s.off("click."+this.$options.name))}},events:(f={blur:"hide"},f["focus "+u+" "+c]=function(t){t.type===c&&l(t)||this.show()},f[d]=function(t){l(t)||this.hide()},f)});var f}}function Ut(t){function e(t,e){return e.match(new RegExp("^"+t.replace(/\//g,"\\/").replace(/\*\*/g,"(\\/[^\\/]+)*").replace(/\*/g,"[^\\/]+").replace(/((?!\\))\?/g,"$1.")+"$","i"))}function i(t,e){for(var i=[],n=0;ni[t]?n.ratio(e,t,i[t]):e}),e},cover:function(e,i){var n=this;return e=this.fit(e,i),t.each(e,function(t){return e=e[t]0||navigator.pointerEnabled&&navigator.maxTouchPoints>0,de=ue?le?"touchstart":"pointerdown":"mousedown",fe=ue?le?"touchmove":"pointermove":"mousemove",pe=ue?le?"touchend":"pointerup":"mouseup",ge=ue&&he?"pointerenter":"mouseenter",me=ue&&he?"pointerleave":"mouseleave",ve=ue&&le?"touchcancel":"pointercancel",we=L("transition","transition-end"),ye=L("animation","animation-start"),be=L("animation","animation-end"),$e={reads:[],writes:[],measure:function(t){return this.reads.push(t),F(this),t},mutate:function(t){return this.writes.push(t),F(this),t},clear:function(t){return q(this.reads,t)||q(this.writes,t)}};Y.prototype={positions:[],position:null,init:function(){var t=this;this.positions=[],this.position=null;var e=!1;this.handler=function(i){e||setTimeout(function(){var n=Date.now(),o=t.positions.length;o&&n-t.positions[o-1].time>100&&t.positions.splice(0,o),t.positions.push({time:n,x:i.pageX,y:i.pageY}),t.positions.length>5&&t.positions.shift(),e=!1},5),e=!0},Gt.on("mousemove",this.handler)},cancel:function(){this.handler&&Gt.off("mousemove",this.handler)},movesTo:function(t){if(this.positions.length<2)return!1;var e=X(t),i=this.positions[this.positions.length-1],n=this.positions[0];if(e.left<=i.x&&i.x<=e.right&&e.top<=i.y&&i.y<=e.bottom)return!1;var o=[[{x:e.left,y:e.top},{x:e.right,y:e.bottom}],[{x:e.right,y:e.top},{x:e.left,y:e.bottom}]];return e.right<=i.x||(e.left>=i.x?(o[0].reverse(),o[1].reverse()):e.bottom<=i.y?o[0].reverse():e.top>=i.y&&o[1].reverse()),!!o.reduce(function(t,e){return t+(R(n,e[0])R(i,e[1]))},0)}};var xe={};xe.args=xe.created=xe.events=xe.init=xe.ready=xe.connected=xe.disconnected=xe.destroy=function(e,i){return e=e&&!t.isArray(e)?[e]:e,i?e?e.concat(i):t.isArray(i)?i:[i]:e},xe.update=function(e,i){return xe.args(e,t.isFunction(i)?{write:i}:i)},xe.props=function(e,i){return t.isArray(i)&&(i=i.reduce(function(t,e){return t[e]=String,t},{})),xe.methods(e,i)},xe.computed=xe.defaults=xe.methods=function(e,i){return i?e?t.extend(!0,{},e,i):i:e};var ke,Ce,Te,_e,Se,Ee=function(t,e){return T(e)?t:e},Ae={x:["width","left","right"],y:["height","top","bottom"]},Oe={};i(function(){var e,i,o,s=0,r=0;"MSGesture"in window&&(_e=new MSGesture,_e.target=document.body),n(document,"click",function(){return Se=!0},!0);var a=function(t){var e=t.velocityX>1?"Right":t.velocityX<-1?"Left":t.velocityY>1?"Down":t.velocityY<-1?"Up":null;e&&void 0!==Oe.el&&(Oe.el.trigger("swipe"),Oe.el.trigger("swipe"+e))};n(document,"MSGestureEnd",a),n(document,"gestureend",a),n(document,de,function(t){o=t.touches?t.touches[0]:t,e=Date.now(),i=e-(Oe.last||e),Oe.el=Vt("tagName"in o.target?o.target:o.target.parentNode),ke&&clearTimeout(ke),Oe.x1=o.pageX,Oe.y1=o.pageY,i>0&&i<=250&&(Oe.isDoubleTap=!0),Oe.last=e,!_e||"pointerdown"!==t.type&&"touchstart"!==t.type||_e.addPointer(t.pointerId),Se=t.button>0}),n(document,fe,function(t){o=t.touches?t.touches[0]:t,Oe.x2=o.pageX,Oe.y2=o.pageY,s+=Math.abs(Oe.x1-Oe.x2),r+=Math.abs(Oe.y1-Oe.y2)}),n(document,pe,function(){Oe.x2&&Math.abs(Oe.x1-Oe.x2)>30||Oe.y2&&Math.abs(Oe.y1-Oe.y2)>30?Te=setTimeout(function(){void 0!==Oe.el&&(Oe.el.trigger("swipe"),Oe.el.trigger("swipe"+et(Oe.x1,Oe.x2,Oe.y1,Oe.y2))),Oe={}},0):"last"in Oe&&(isNaN(s)||s<30&&r<30?Ce=setTimeout(function(){var e=t.Event("tap");e.cancelTouch=it,void 0!==Oe.el&&Oe.el.trigger(e),Oe.isDoubleTap?(void 0!==Oe.el&&Oe.el.trigger("doubleTap"),Oe={}):ke=setTimeout(function(){ke=null,void 0!==Oe.el&&(Oe.el.trigger("singleTap"),Se||Oe.el.trigger("click")),Oe={}},300)}):Oe={},s=r=0)}),n(document,ve,it),n(window,"scroll",it)});var De=!1;n(document,"touchstart",function(){return De=!0},!0),n(document,"click",function(){De=!1}),n(document,"touchcancel",function(){return De=!1},!0);var Ie=Object.freeze({win:Xt,doc:Gt,docElement:Qt,isRtl:Jt,isReady:e,ready:i,on:n,off:o,transition:s,Transition:Zt,animate:r,Animation:Kt,isJQuery:a,isWithin:l,attrFilter:h,removeClass:c,createEvent:u,isInView:d,getIndex:f,isVoidElement:p,Dimensions:ee,query:g,Observer:re,requestAnimationFrame:ae,hasPromise:ce,hasTouch:ue,pointerDown:de,pointerMove:fe,pointerUp:pe,pointerEnter:ge,pointerLeave:me,pointerCancel:ve,transitionend:we,animationstart:ye,animationend:be,getStyle:M,getCssVar:j,fastdom:$e,$:Vt,bind:m,hasOwn:v,promise:w,classify:y,hyphenate:b,camelize:$,isString:k,isNumber:C,isUndefined:T,isContextSelector:_,getContextSelectors:S,toJQuery:E,toNode:A,toBoolean:O,toNumber:D,toList:I,toMedia:N,coerce:B,toMs:P,swap:H,ajax:t.ajax,contains:t.contains,each:t.each,Event:t.Event,extend:t.extend,map:t.map,merge:t.merge,isArray:t.isArray,isNumeric:t.isNumeric,isFunction:t.isFunction,isPlainObject:t.isPlainObject,MouseTracker:Y,mergeOptions:U,position:V,getDimensions:X,offsetTop:G,flipPosition:tt,isTouch:nt}),Ne=function(t){this._init(t)};Ne.util=Ie,Ne.data="__uikit__",Ne.prefix="uk-",Ne.options={},Ne.instances={},Ne.elements=[],function(t){var e=t.data;t.use=function(t){if(!t.installed)return t.call(null,this),t.installed=!0,this},t.mixin=function(e,i){i=(k(i)?t.components[i]:i)||this,e=U({},e),e.mixins=i.options.mixins,delete i.options.mixins,i.options=U(e,i.options)},t.extend=function(t){t=t||{};var e=this,i=t.name||e.options.name,n=ot(i||"UIkitComponent");return n.prototype=Object.create(e.prototype),n.prototype.constructor=n,n.options=U(e.options,t),n.super=e,n.extend=e.extend,n},t.update=function(i,n,o){if(void 0===o&&(o=!1),i=u(i||"update"),!n)return void rt(t.instances,i);if(n=A(n),o)do{rt(n[e],i),n=n.parentNode}while(n);else st(n,function(t){return rt(t[e],i)})};var i;Object.defineProperty(t,"container",{get:function(){return i||document.body},set:function(t){i=t}})}(Ne),function(t){t.prototype._callHook=function(t){var e=this,i=this.$options[t];i&&i.forEach(function(t){return t.call(e)})},t.prototype._callReady=function(){this._isReady||(this._isReady=!0,this._callHook("ready"),this._callUpdate())},t.prototype._callConnected=function(){var e=this;this._connected||(~t.elements.indexOf(this.$options.el)||t.elements.push(this.$options.el),t.instances[this._uid]=this,this._initEvents(),this._callHook("connected"),this._connected=!0,this._initObserver(),this._isReady||i(function(){return e._callReady()}),this._callUpdate())},t.prototype._callDisconnected=function(){if(this._connected){this._observer&&(this._observer.disconnect(),this._observer=null);var e=t.elements.indexOf(this.$options.el);~e&&t.elements.splice(e,1),delete t.instances[this._uid],this._initEvents(!0),this._callHook("disconnected"),this._connected=!1}},t.prototype._callUpdate=function(t){var e=this;t=u(t||"update"),"update"===t.type&&(this._computeds={});var i=this.$options.update;i&&i.forEach(function(i,n){if("update"===t.type||i.events&&~i.events.indexOf(t.type)){if(t.sync)return i.read&&i.read.call(e,t),void(i.write&&i.write.call(e,t));i.read&&!~$e.reads.indexOf(e._frames.reads[n])&&(e._frames.reads[n]=$e.measure(function(){i.read.call(e,t),delete e._frames.reads[n]})),i.write&&!~$e.writes.indexOf(e._frames.writes[n])&&(e._frames.writes[n]=$e.mutate(function(){i.write.call(e,t),delete e._frames.writes[n]}))}})}}(Ne),function(e){var i=0;e.prototype.props={},e.prototype._init=function(t){t=t||{},t=this.$options=U(this.constructor.options,t,this),this.$el=null,this.$name=e.prefix+b(this.$options.name),this.$props={},this._uid=i++,this._initData(),this._initMethods(),this._initComputeds(),this._callHook("created"),this._frames={reads:{},writes:{}},t.el&&this.$mount(t.el)},e.prototype._initData=function(){var e=this,i=t.extend(!0,{},this.$options.defaults),n=this.$options.data||{},o=this.$options.args||[],s=this.$options.props||{};if(i){o.length&&t.isArray(n)&&(n=n.slice(0,o.length).reduce(function(e,i,n){return t.isPlainObject(i)?t.extend(e,i):e[o[n]]=i,e},{}));for(var r in i)e.$props[r]=e[r]=v(n,r)?B(s[r],n[r],e.$options.el):i[r]}},e.prototype._initMethods=function(){var t=this,e=this.$options.methods;if(e)for(var i in e)t[i]=m(e[i],t)},e.prototype._initComputeds=function(){var t=this,e=this.$options.computed;if(this._computeds={},e)for(var i in e)at(t,i,e[i])},e.prototype._initProps=function(e){var i=this;this._computeds={},t.extend(this.$props,e||this._getProps());var n=[this.$options.computed,this.$options.methods];for(var o in i.$props)ct(n,o)&&(i[o]=i.$props[o])},e.prototype._initEvents=function(t){var e=this,i=this.$options.events;i&&i.forEach(function(i){if(v(i,"handler"))lt(e,t,i);else for(var n in i)lt(e,t,i[n],n)})},e.prototype._initObserver=function(){var e=this;if(!this._observer&&this.$options.props&&this.$options.attrs&&re){var i=t.isArray(this.$options.attrs)?this.$options.attrs:Object.keys(this.$options.props).map(function(t){return b(t)});this._observer=new re(function(){var t=e._getProps();i.some(function(i){return!ut(t[i],e.$props[i])})&&e.$reset(t)}),this._observer.observe(this.$options.el,{attributes:!0,attributeFilter:i.concat([this.$name,"data-"+this.$name])})}},e.prototype._getProps=function(){var t,e,i={},n=this.$el[0],o=this.$options.args||[],s=this.$options.props||{},r=n.getAttribute(this.$name)||n.getAttribute("data-"+this.$name);if(!s)return i;for(t in s)if(e=b(t),n.hasAttribute(e)){var a=B(s[t],n.getAttribute(e),n);if("target"===e&&(!a||0===a.lastIndexOf("_",0)))continue;i[t]=a}if(!r)return i;if("{"===r[0])try{r=JSON.parse(r)}catch(t){console.warn("Invalid JSON."),r={}}else if(o.length&&!~r.indexOf(":")){l={},l[o[0]]=r,r=l;var l}else{var h={};r.split(";").forEach(function(t){var e=t.split(/:(.+)/),i=e[0],n=e[1];i&&n&&(h[i.trim()]=n.trim())}),r=h}for(t in r||{})e=$(t),void 0!==s[e]&&(i[e]=B(s[e],r[t],n));return i}}(Ne),function(t){var e=t.data;t.prototype.$mount=function(t){var i=this.$options.name;if(t[e]||(t[e]={}),t[e][i])return void console.warn('Component "'+i+'" is already mounted on element: ',t);t[e][i]=this,this.$el=Vt(t),this._initProps(),this._callHook("init"),document.documentElement.contains(t)&&this._callConnected()},t.prototype.$emit=function(t){this._callUpdate(t)},t.prototype.$emitSync=function(t){this._callUpdate(u(t||"update",!0,!1,{sync:!0}))},t.prototype.$update=function(e,i){t.update(e,this.$el,i)},t.prototype.$updateSync=function(t,e){this.$update(u(t||"update",!0,!1,{sync:!0}),e)},t.prototype.$reset=function(t){this._callDisconnected(),this._initProps(t),this._callConnected()},t.prototype.$destroy=function(t){void 0===t&&(t=!1);var i=this.$options.el;i&&this._callDisconnected(),this._callHook("destroy"),i&&i[e]&&(delete i[e][this.$options.name],Object.keys(i[e]).length||delete i[e],t&&this.$el.remove())}}(Ne),function(e){var i=e.data;e.components={},e.component=function(i,n){var o=$(i);return t.isPlainObject(n)?(n.name=o,n=e.extend(n)):n.options.name=o,e.components[o]=n,e[o]=function(i,n){for(var s=arguments.length,r=Array(s);s--;)r[s]=arguments[s];return t.isPlainObject(i)?new e.components[o]({data:i}):e.components[o].options.functional?new e.components[o]({data:[].concat(r)}):Vt(i).toArray().map(function(t){return e.getComponent(t,o)||new e.components[o]({el:t,data:n||{}})})[0]},e._initialized&&!n.options.functional&&$e.measure(function(){return e[o]("[uk-"+i+"],[data-uk-"+i+"]")}),e.components[o]},e.getComponents=function(t){return t&&(t=a(t)?t[0]:t)&&t[i]||{}},e.getComponent=function(t,i){return e.getComponents(t)[i]},e.connect=function(t){var n;if(t[i])for(n in t[i])t[i][n]._callConnected();for(var o=0;o',We='',ze='',qe='',Ye='',Re='',Ue='',Ve='',Xe='',Ge='',Qe='',Je='',Ze='',Ke='',ti='',ei={},ii=new DOMParser;return Ne.version="3.0.0-beta.22",function(t){t.mixin.class=He,t.mixin.modal=je,t.mixin.position=Le,t.mixin.togglable=Me}(Ne),function(t){var e,i,o,s=null,r=0;Xt.on("load",t.update).on("resize",function(e){o||(ae(function(){t.update(e),o=!1}),o=!0)}).on("scroll",function(n){null===s&&(s=0),s!==window.pageYOffset&&(e=s li > a:hover { + background: #00a8e6 none repeat scroll 0 0; + box-shadow: 0 0 5px rgba(0, 0, 0, 0.05) inset; + color: #FFF; + outline: medium none; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.1); +} + +.custom-autocomplete .uk-nav-navbar > li > a { + color: #444; +} +.custom-description-list-horizontal{ line-height:200%} +.uk-alert-default { + background: #fff none repeat scroll 0 0; + border: 1px solid #ddd; + border-radius: 4px; + color: #444; + height: 30px; + max-width: 100%; + padding: 4px 6px; + +} +.custom-hidden-dropdown-menu {position:static !important;} +.searchFilterBoxValues {overflow:auto; max-height:200px; } +.selected-filters-box {margin:5px; background-color:#F8F8F8; } +.search-form {margin:5px; } +.clickable { cursor:pointer; } +.search-filters .uk-accordion-title{ + font-size: 14px; + line-height: 18px; +} +.search-results { + min-height: 1100px; +} +.searchPaging { + min-height: 46px; +} +.helper-left-right { + margin-top: 75px; + max-width: 20%; +} + +@media (min-width: 960px) { + .float-children-right-at-medium > * { + float: right; + } +} + +@media (max-width: 959px) { + .margin-small-top-at-small { + margin-top: 10px !important; + } +} + +.other-results { + min-height: 300px; +} +.OPEN { + background: rgba(0, 0, 0, 0) url("/assets/unlock.svg") no-repeat scroll right top; + padding-right: 25px; + min-height: 20px; + background-size: 20px 20px; + font-weight: 400; + text-transform: none; +} + + +.EMBARGO, .CLOSED, .RESTRICTED { + background: rgba(0, 0, 0, 0) url("/assets/lock.svg") no-repeat scroll right top; + padding-right: 25px; + min-height: 20px; + background-size: 20px 20px; + font-weight: 400; + text-transform: none; +} + +.sc39 { + background: rgba(0, 0, 0, 0) url("/assets/sc39.png") no-repeat scroll right center; + padding-right: 24px; +} + +.projectIcon { + display: inline-table; +} + +.dateFilter .mydp{ + margin-top:5px; +} + + +/*.tooltip { + max-width: none; + background: rgba(100, 100, 100, 1); +}*/ +.tooltip-custom-font-size { + font-size: 120%; +} + +.custom-select-mini{ + max-width:170px !important; +} +.custom-icon { + line-height: unset; +} +/*.custom-tab-content-large{ + min-height: 800px; +} + */ +.custom-tab-content { + min-height: 250px; +} + +.custom-dataTable-content { + min-height: 600px; +} + +.custom-html-table-height { + height: 500px; +} + + + + +.filterItem span { +display: inline-flex; +} +.filterItem .filterName { +max-width: 71%; + +} +.browseFilters .filterItem .filterName { +max-width: 68%; +} + +.filterItem .filterNumber { +width: 20%; +} +.filterItem span { + +white-space: nowrap; +} +.browseFilters .filterItem span div { + /*min-width: 45px;*/ +} +.filterItem span div { +overflow: hidden; +text-overflow: ellipsis; +/*min-width: 81px;*/ +} + +.browseFilters{ +overflow-y: auto; +overflow-x: hidden; +max-height:265px; +} + + + +.custom-offcanvas-close { + position: relative; + right: 0; + top: 0; +} +.uk-link{ + color: #292C3D !important; +} +.uk-breadcrumb > :last-child > * { + color:#cbcbcb !important; +} +.uk-breadcrumb .uk-active a{ + color: #767779 !important; +} + +.publicationTitleIcon { + background: url("/assets/publication.png") no-repeat; +} +.datasetTitleIcon { + background: url("/assets/dataset.png") no-repeat; +} +.projectTitleIcon { + background: url("/assets/project.png") no-repeat; +} +.organizationTitleIcon { + background: url("/assets/organization.png") no-repeat; +} +.datasourceTitleIcon { + background: url("/assets/datasource.png") no-repeat; +} +.entityTitleIcon{ + background-repeat: :no-repeat; + content: ''; + display: inline-block; + height: 36px; + width: 42px; + vertical-align: middle; +} +.entityIcon{ + height: 15px; + width: 20px; + +} +/*.uk-tab{ + border-bottom: 1px #cbcbcb solid; +}*/ +.label-underCuration{ + background: #fef5d2 !important; +} + +.label-blue { + background:#d4f3ff; + color:#00a0de +} +.label-green { + background:#d1f6e8; + color:#01a566 +} +.label-yellow { + background:#fef5d2; + color:#cca607 +} +.label-red { + background:#fef0ef; + color:#f54f43 +} +.label-grey{ + background: #f8f8f8; + color: #666; +} +.label-orange{ + background: #fef5d2; +color: #f0506e; + +} + +.label-OPEN, .label-open { +background: #F25F2F; +color: #fff; } +.label-CLOSED, .label-EMBARGO, .label-RESTRICTED, .label-closed { +background: #0F0F0F; +color: #fff } + +.label-publication{ + background: #4687E6; + color: #fff} + +.label-dataset +{ background: #1e906c; +color: #fff} + +.label-project +{ background: #d0307f; +color: #fff} + +.label-dataprovider +{ background: #00a0de; +color: #fff} + +.label-organization +{ background: #fbcd0d; +color: #414141} + + + +.uk-tab { + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -ms-flex-wrap: wrap; + -webkit-flex-wrap: wrap; + flex-wrap: wrap; + margin-left: -20px; + padding: 0; + list-style: none; + position: relative; +} +.uk-tab::before { + content: ""; + position: absolute; + bottom: 0; + left: 20px; + right: 0; + border-bottom: 1px solid #e5e5e5; +} +.uk-tab-left::before { + border-bottom: none !important; +} +.mainPageSearchForm{ + background-image: url("./home2.jpeg"); background-color: rgb(255, 255, 255); box-sizing: border-box; min-height: calc(100vh - 412.767px); +} + +.searchForm, .generalSearchForm{ + background-image: url('./search_general_3.jpg'); box-sizing: border-box; height: 250px; +} +.publicationsSearchForm{ + background-image: url('./search_pubs_1.jpg'); box-sizing: border-box; height: 250px; +} +.projectsSearchForm{ + background-image: url('./projects_search.jpg'); box-sizing: border-box; height: 250px; +} +.organizationsSearchForm{ + background-image: url('./search_organizations.jpg'); box-sizing: border-box; height: 250px; +} +.datasetsSearchForm{ + background-image: url('./search_data.jpg'); box-sizing: border-box; height: 250px; +} +.softwareSearchForm{ + background-image: url('./search_data.jpg'); box-sizing: border-box; height: 250px; +} +.datasourcesSearchForm, .compatibleDatasourcesSearchForm, + .compatibleDatasourcesTableSearchForm { + background-image: url('./providers_search.jpg'); box-sizing: border-box; height: 250px; +} + .journalsSearchForm, .journalsTableSearchForm{ + background-image: url('./search_journals.jpg'); box-sizing: border-box; height: 250px; +} +.entityRegistriesSearchForm, .entityRegistriesTableSearchForm { + background-image: url('./search_registries.jpg'); box-sizing: border-box; height: 250px; +} + +.divider-table tbody td, .uk-table th { + border-bottom: 1px solid #E5E5E5; + } + + #feedback { + float: left; + position: fixed; + top: calc(50% - 47px); + right: 0; + z-index: 10000; + display: block; + + } + + #feedback a { + background: #666; + border-radius: 5px 0 0 5px; + box-shadow:none; + border: none!important; + display: block; + padding: 20px 12px; + transition: all .2s ease-in-out; + opacity:0.5; + + } + + #feedback a:hover { + padding-right: 20px; + } + +.descriptionText{ + Padding-left: 25px !important; + Border-left: 10px solid #fafafa; + display: inline-block; + position: relative; + top: calc(-0.1 * 1em); + vertical-align: middle; + margin-right: 10px; + border-left: 8px solid #e5e5e5; + margin-top: 8px; + +} + + +/* +li span { + display: inline-flex; +} + +.item span { + width: 100px; + margin-left: 1em; + white-space: nowrap; +} + +.item span div { + overflow: hidden; + text-overflow: ellipsis; +}*/ + +.custom-offcanvas-bar{ + background: grey !important; + width:100% !important; + +} +.custom-offcanvas-bar .filtersModal{ + color:grey !important; + +} +.list-horizontal{ + display: flex; + } +.list-horizontal span{ + margin-right:5px; + padding-left: 0px !important; + +} +.list-horizontal-line span { + margin-right: 5px; + border-right: 1px solid #f1f1f1; + padding-right: 5px; + +} + +.list-horizontal-line > span:last-child { + border-right:none; +} +body { + font-family: Raleway, Arial, sans-serif !important; +} +html { + color: #444 !important; +} + +h2, h4{ + font-weight: 400; + text-transform: none; +} +.linkdropdown{ + min-width:250px; +} +.uk-button-action{ + background-color: #D6352B; + color: #fff +} +.uk-pagination>.uk-active>* { + color: #fff !important; + background-color: #296EE9 !important; + +} +.uk-pagination>*>* { + color:#666 !important; +} +h2, .uk-h2{ + font-size:28px !important; +} +.app-box { + border: #e5e5e5 solid 1px; +} + +.uk-subnav-line li:hover .home-icon svg #home{ + fill: #05007A !important; + +} + svg #home{ + fill: white !important; + +} +.tm-toolbar .uk-subnav-line li a:hover, .tm-toolbar .uk-subnav-line li:hover a{ + display: block; + color: #d4d4d4 !important; +} + +.tm-toolbar .uk-subnav-line li:hover {display: block;} /* remove the others*/ + +.helper-grid>*{ + padding-left: 25px !important; +} diff --git a/portal-4cli/src/assets/external-link.svg b/portal-4cli/src/assets/external-link.svg new file mode 100644 index 00000000..c291d7e2 --- /dev/null +++ b/portal-4cli/src/assets/external-link.svg @@ -0,0 +1 @@ + diff --git a/portal-4cli/src/assets/favicon.ico b/portal-4cli/src/assets/favicon.ico new file mode 100644 index 00000000..151eca1b Binary files /dev/null and b/portal-4cli/src/assets/favicon.ico differ diff --git a/portal-4cli/src/assets/formImage.jpg b/portal-4cli/src/assets/formImage.jpg new file mode 100644 index 00000000..16ca30fa Binary files /dev/null and b/portal-4cli/src/assets/formImage.jpg differ diff --git a/portal-4cli/src/assets/globe_tech.jpg b/portal-4cli/src/assets/globe_tech.jpg new file mode 100644 index 00000000..46f3c645 Binary files /dev/null and b/portal-4cli/src/assets/globe_tech.jpg differ diff --git a/portal-4cli/src/assets/home.jpeg b/portal-4cli/src/assets/home.jpeg new file mode 100644 index 00000000..655e923c Binary files /dev/null and b/portal-4cli/src/assets/home.jpeg differ diff --git a/portal-4cli/src/assets/home2.jpeg b/portal-4cli/src/assets/home2.jpeg new file mode 100644 index 00000000..628aff7d Binary files /dev/null and b/portal-4cli/src/assets/home2.jpeg differ diff --git a/portal-4cli/src/assets/icon_external.png b/portal-4cli/src/assets/icon_external.png new file mode 100644 index 00000000..e2436860 Binary files /dev/null and b/portal-4cli/src/assets/icon_external.png differ diff --git a/portal-4cli/src/assets/jquery/jquery.min.js b/portal-4cli/src/assets/jquery/jquery.min.js new file mode 100644 index 00000000..e8364758 --- /dev/null +++ b/portal-4cli/src/assets/jquery/jquery.min.js @@ -0,0 +1,5 @@ +/*! jQuery v1.12.4 | (c) jQuery Foundation | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="1.12.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!k.call(a,"constructor")&&!k.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(!l.ownFirst)for(b in a)return k.call(a,b);for(b in a);return void 0===b||k.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(h)return h.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=e.call(arguments,2),d=function(){return a.apply(b||this,c.concat(e.call(arguments)))},d.guid=a.guid=a.guid||n.guid++,d):void 0},now:function(){return+new Date},support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+N+")*)|.*)\\)|)",P=new RegExp(L+"+","g"),Q=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),R=new RegExp("^"+L+"*,"+L+"*"),S=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),T=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),U=new RegExp(O),V=new RegExp("^"+M+"$"),W={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M+"|[*])"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,$=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,_=/[+~]/,aa=/'|\\/g,ba=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),ca=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(aa,"\\$&"):b.setAttribute("id",k=u),r=g(a),h=r.length,l=V.test(k)?"#"+k:"[id='"+k+"']";while(h--)r[h]=l+" "+qa(r[h]);s=r.join(","),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(Q,"$1"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ia(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ia(function(a){var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",O)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Z.test(o.compareDocumentPosition),t=b||Z.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fa.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fa.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fa.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fa.selectors={cacheLength:50,createPseudo:ha,match:W,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ba,ca),a[3]=(a[3]||a[4]||a[5]||"").replace(ba,ca),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fa.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&U.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ba,ca).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fa.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(P," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,"$1"));return d[u]?ha(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||"")||fa.error("unsupported lang: "+a),a=a.replace(ba,ca).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Y.test(a.nodeName)},input:function(a){return X.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function ra(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(Q,"$1"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ia(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ja("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ja("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute("disabled")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,y=/^.[^:#\[\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,"string"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,"string"==typeof a){if(e="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}if(f=d.getElementById(e[2]),f&&f.parentNode){if(f.id!==e[2])return A.find(a);this.length=1,this[0]=f}return this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,"parentNode")},parentsUntil:function(a,b,c){return u(a,"parentNode",c)},next:function(a){return F(a,"nextSibling")},prev:function(a){return F(a,"previousSibling")},nextAll:function(a){return u(a,"nextSibling")},prevAll:function(a){return u(a,"previousSibling")},nextUntil:function(a,b,c){return u(a,"nextSibling",c)},prevUntil:function(a,b,c){return u(a,"previousSibling",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||(e=n.uniqueSort(e)),D.test(a)&&(e=e.reverse())),this.pushStack(e)}});var G=/\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=!0,c||j.disable(),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler("ready"),n(d).off("ready"))))}});function J(){d.addEventListener?(d.removeEventListener("DOMContentLoaded",K),a.removeEventListener("load",K)):(d.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(d.addEventListener||"load"===a.event.type||"complete"===d.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll)a.setTimeout(n.ready);else if(d.addEventListener)d.addEventListener("DOMContentLoaded",K),a.addEventListener("load",K);else{d.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&d.documentElement}catch(e){}c&&c.doScroll&&!function f(){if(!n.isReady){try{c.doScroll("left")}catch(b){return a.setTimeout(f,50)}J(),n.ready()}}()}return I.promise(b)},n.ready.promise();var L;for(L in n(l))break;l.ownFirst="0"===L,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c,e;c=d.getElementsByTagName("body")[0],c&&c.style&&(b=d.createElement("div"),e=d.createElement("div"),e.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(e).appendChild(b),"undefined"!=typeof b.style.zoom&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",l.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(e))}),function(){var a=d.createElement("div");l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}a=null}();var M=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b},N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0; +}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(M(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),"object"!=typeof b&&"function"!=typeof b||(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f}}function S(a,b,c){if(M(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=void 0)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},Z=/^(?:checkbox|radio)$/i,$=/<([\w:-]+)/,_=/^$|\/(?:java|ecma)script/i,aa=/^\s+/,ba="abbr|article|aside|audio|bdi|canvas|data|datalist|details|dialog|figcaption|figure|footer|header|hgroup|main|mark|meter|nav|output|picture|progress|section|summary|template|time|video";function ca(a){var b=ba.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}!function(){var a=d.createElement("div"),b=d.createDocumentFragment(),c=d.createElement("input");a.innerHTML="
  • a",l.leadingWhitespace=3===a.firstChild.nodeType,l.tbody=!a.getElementsByTagName("tbody").length,l.htmlSerialize=!!a.getElementsByTagName("link").length,l.html5Clone="<:nav>"!==d.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,b.appendChild(c),l.appendChecked=c.checked,a.innerHTML="",l.noCloneChecked=!!a.cloneNode(!0).lastChild.defaultValue,b.appendChild(a),c=d.createElement("input"),c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),a.appendChild(c),l.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!!a.addEventListener,a[n.expando]=1,l.attributes=!a.getAttribute(n.expando)}();var da={option:[1,""],legend:[1,"
    ","
    "],area:[1,"",""],param:[1,"",""],thead:[1,"","
    "],tr:[2,"","
    "],col:[2,"","
    "],td:[3,"","
    "],_default:l.htmlSerialize?[0,"",""]:[1,"X
    ","
    "]};da.optgroup=da.option,da.tbody=da.tfoot=da.colgroup=da.caption=da.thead,da.th=da.td;function ea(a,b){var c,d,e=0,f="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,ea(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function fa(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}var ga=/<|&#?\w+;/,ha=/r;r++)if(g=a[r],g||0===g)if("object"===n.type(g))n.merge(q,g.nodeType?[g]:g);else if(ga.test(g)){i=i||p.appendChild(b.createElement("div")),j=($.exec(g)||["",""])[1].toLowerCase(),m=da[j]||da._default,i.innerHTML=m[1]+n.htmlPrefilter(g)+m[2],f=m[0];while(f--)i=i.lastChild;if(!l.leadingWhitespace&&aa.test(g)&&q.push(b.createTextNode(aa.exec(g)[0])),!l.tbody){g="table"!==j||ha.test(g)?""!==m[1]||ha.test(g)?0:i:i.firstChild,f=g&&g.childNodes.length;while(f--)n.nodeName(k=g.childNodes[f],"tbody")&&!k.childNodes.length&&g.removeChild(k)}n.merge(q,i.childNodes),i.textContent="";while(i.firstChild)i.removeChild(i.firstChild);i=p.lastChild}else q.push(b.createTextNode(g));i&&p.removeChild(i),l.appendChecked||n.grep(ea(q,"input"),ia),r=0;while(g=q[r++])if(d&&n.inArray(g,d)>-1)e&&e.push(g);else if(h=n.contains(g.ownerDocument,g),i=ea(p.appendChild(g),"script"),h&&fa(i),c){f=0;while(g=i[f++])_.test(g.type||"")&&c.push(g)}return i=null,p}!function(){var b,c,e=d.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b]=c in a)||(e.setAttribute(c,"t"),l[b]=e.attributes[c].expando===!1);e=null}();var ka=/^(?:input|select|textarea)$/i,la=/^key/,ma=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,na=/^(?:focusinfocus|focusoutblur)$/,oa=/^([^.]*)(?:\.(.+)|)/;function pa(){return!0}function qa(){return!1}function ra(){try{return d.activeElement}catch(a){}}function sa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)sa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=qa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return"undefined"==typeof n||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(G)||[""],h=b.length;while(h--)f=oa.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(G)||[""],j=b.length;while(j--)if(h=oa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,e,f){var g,h,i,j,l,m,o,p=[e||d],q=k.call(b,"type")?b.type:b,r=k.call(b,"namespace")?b.namespace.split("."):[];if(i=m=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!na.test(q+n.event.triggered)&&(q.indexOf(".")>-1&&(r=q.split("."),q=r.shift(),r.sort()),h=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=r.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:n.makeArray(c,[b]),l=n.event.special[q]||{},f||!l.trigger||l.trigger.apply(e,c)!==!1)){if(!f&&!l.noBubble&&!n.isWindow(e)){for(j=l.delegateType||q,na.test(j+q)||(i=i.parentNode);i;i=i.parentNode)p.push(i),m=i;m===(e.ownerDocument||d)&&p.push(m.defaultView||m.parentWindow||a)}o=0;while((i=p[o++])&&!b.isPropagationStopped())b.type=o>1?j:l.bindType||q,g=(n._data(i,"events")||{})[b.type]&&n._data(i,"handle"),g&&g.apply(i,c),g=h&&i[h],g&&g.apply&&M(i)&&(b.result=g.apply(i,c),b.result===!1&&b.preventDefault());if(b.type=q,!f&&!b.isDefaultPrevented()&&(!l._default||l._default.apply(p.pop(),c)===!1)&&M(e)&&h&&e[q]&&!n.isWindow(e)){m=e[h],m&&(e[h]=null),n.event.triggered=q;try{e[q]()}catch(s){}n.event.triggered=void 0,m&&(e[h]=m)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())a.rnamespace&&!a.rnamespace.test(g.namespace)||(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]","i"),va=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,wa=/\s*$/g,Aa=ca(d),Ba=Aa.appendChild(d.createElement("div"));function Ca(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function Da(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function Ea(a){var b=ya.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Fa(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Ga(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(Da(b).text=a.text,Ea(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&Z.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}}function Ha(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&"string"==typeof q&&!l.checkClone&&xa.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(o&&(k=ja(b,a[0].ownerDocument,!1,a,d),e=k.firstChild,1===k.childNodes.length&&(k=e),e||d)){for(i=n.map(ea(k,"script"),Da),h=i.length;o>m;m++)g=k,m!==p&&(g=n.clone(g,!0,!0),h&&n.merge(i,ea(g,"script"))),c.call(a[m],g,m);if(h)for(j=i[i.length-1].ownerDocument,n.map(i,Ea),m=0;h>m;m++)g=i[m],_.test(g.type||"")&&!n._data(g,"globalEval")&&n.contains(j,g)&&(g.src?n._evalUrl&&n._evalUrl(g.src):n.globalEval((g.text||g.textContent||g.innerHTML||"").replace(za,"")));k=e=null}return a}function Ia(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(ea(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&fa(ea(d,"script")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(va,"<$1>")},clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!ua.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(Ba.innerHTML=a.outerHTML,Ba.removeChild(f=Ba.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=ea(f),h=ea(a),g=0;null!=(e=h[g]);++g)d[g]&&Ga(e,d[g]);if(b)if(c)for(h=h||ea(a),d=d||ea(f),g=0;null!=(e=h[g]);g++)Fa(e,d[g]);else Fa(a,f);return d=ea(f,"script"),d.length>0&&fa(d,!i&&ea(a,"script")),d=h=e=null,f},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.attributes,m=n.event.special;null!=(d=a[h]);h++)if((b||M(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k||"undefined"==typeof d.removeAttribute?d[i]=void 0:d.removeAttribute(i),c.push(f))}}}),n.fn.extend({domManip:Ha,detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return Y(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||d).createTextNode(a))},null,a,arguments.length)},append:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(ea(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return Y(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(ta,""):void 0;if("string"==typeof a&&!wa.test(a)&&(l.htmlSerialize||!ua.test(a))&&(l.leadingWhitespace||!aa.test(a))&&!da[($.exec(a)||["",""])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ea(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ha(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(ea(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],f=n(a),h=f.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(f[d])[b](c),g.apply(e,c.get());return this.pushStack(e)}});var Ja,Ka={HTML:"block",BODY:"block"};function La(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],"display");return c.detach(),d}function Ma(a){var b=d,c=Ka[a];return c||(c=La(a,b),"none"!==c&&c||(Ja=(Ja||n("