Merge pull request 'Merging explore-redesign branch into develop for Explore July release' (#7) from explore-redesign into develop

Reviewed-on: #7
This commit is contained in:
Konstantina Galouni 2023-07-05 11:11:52 +02:00
commit ea1b054b63
119 changed files with 7482 additions and 3825 deletions

View File

@ -49,6 +49,11 @@ export class CacheInterceptorService implements HttpInterceptor {
}
public checkForCachedRequests(url){
// Do not call cache when it is not enabled at all.
// This property is not correctly used here. A new property should be introduced. For now it is ok.
if (!properties.useLongCache) {
return false;
}
if(url.indexOf("refine=true") !== -1 || url.indexOf("/count?format=json") !== -1 || url.indexOf("relresulttype%3Dpublication") !== -1) {
return this.cachingRequests.some(partUrl => (url.indexOf(partUrl) !== -1));
}

View File

@ -1,5 +1,5 @@
<div>
<div class="uk-width-xlarge@l uk-width-large">
<div class="uk-width-xlarge@l uk-width-large" [ngClass]="centerAlign ? 'uk-align-center':''">
<advanced-search-input>
<div input type="select" [(value)]="showOptions.show" placeholder="Type" hint="Select..."
[options]="showOptions.selectOptions" class="uk-width-2-5"></div>

View File

@ -18,6 +18,7 @@ declare var UIkit: any;
})
export class ClaimContextSearchFormComponent {
@Input() public centerAlign: boolean = false;
@Input() public results:ClaimEntity[];
@Input() public sources;
@Input() public properties: EnvProperties;

View File

@ -168,7 +168,7 @@ export class ShowOptions {
this.basketShowSources = false;
}
showLinkTo() {
console.log(this.linkTo, "showLinkTo")
// console.log(this.linkTo, "showLinkTo")
this.show = this.linkTo;
this.basketswitchToLinkTo();
HelperFunctions.scroll();

View File

@ -1,4 +1,4 @@
<div class="uk-width-xlarge@l uk-width-large">
<div class="uk-width-xlarge@l uk-width-large" [ngClass]="centerAlign ? 'uk-align-center':''">
<advanced-search-input (searchEmitter)="search(page,size)">
<div input type="select" [(value)]="showOptions.show" placeholder="Type" hint="Select..."
[options]="showOptions.selectOptions" class="uk-width-2-5"></div>

View File

@ -21,6 +21,7 @@ declare var UIkit:any;
})
export class ClaimProjectsSearchFormComponent {
public query = '';
@Input() public centerAlign: boolean = false;
@Input() public selectedProjects:ClaimEntity[]=[] ;
public elementRef;

View File

@ -1,4 +1,4 @@
<div *ngIf="showOptions && showOptions.linkToEntities.length > 0" class="uk-width-xlarge@l uk-width-large">
<div *ngIf="showOptions && showOptions.linkToEntities.length > 0" class="uk-width-xlarge@l uk-width-large" [ngClass]="centerAlign ? 'uk-align-center':''">
<advanced-search-input (searchEmitter)="search(true)">
<div input type="select" [(value)]="showOptions.show" placeholder="Type" hint="Select..."
[options]="showOptions.selectOptions" class="uk-width-2-5"></div>
@ -8,7 +8,7 @@
</div>
<div *ngIf="!showOptions" class="uk-width-xlarge@l uk-width-large">
<div search-input [(value)]="keyword" [placeholder]="'Search for ' + openaireEntities.RESULTS.toLowerCase() + '...'"
(searchEmitter)="search(true)"></div>
[searchInputClass]="'inner background'" (searchEmitter)="search(true)"></div>
</div>
<div *ngIf="!showSearchResults">
<div class="uk-text-center uk-text-large uk-text-meta uk-margin-large-top">

View File

@ -23,6 +23,7 @@ export class ClaimResultSearchFormComponent {
source: string = "datacite";
type: string = "dataset";
showSearchResults: boolean = false;
@Input() public centerAlign: boolean = false;
@Input() public select: boolean = true;
@Input() public keyword: string = '';
@Input() public selectedResults: ClaimEntity[];

View File

@ -6,13 +6,9 @@ declare var UIkit: any;
@Component({
selector: 'claim-results',
template: `
<div *ngIf="results.length > 0 " class="uk-margin-top">
<div *ngFor=" let entity of results " [class]="(isSelected(entity))?'uk-block-muted':''" class=" uk-card uk-card-default uk-card-body uk-margin-bottom">
<div>
<div class="uk-text-small ">
{{(!entity.result) ? entity.type : ((entity.result && entity.result.source == 'openaire') ? entity.type : (entity.result && entity.result.source + ' result'))}}
</div>
<div *ngFor="let entity of results" class="uk-card">
<div class="uk-padding-small">
<div class="uk-grid">
<div class="uk-width-expand uk-margin-right">
<claim-title [entity]="entity" [showIcon]="false"></claim-title>
@ -20,20 +16,19 @@ declare var UIkit: any;
<claim-project-metadata [entity]="entity"></claim-project-metadata>
</div>
<div class="uk-margin-auto-vertical uk-padding-remove-left uk-margin-small-left uk-margin-small-right" [title]="(this.selectedResults.length>=basketLimit)?'Basket reached the size limit':''">
<button class="linking-add-button" [class.uk-disabled]="(this.selectedResults.length>=basketLimit)" *ngIf="!isSelected(entity)"
<button class="linking-add-button uk-icon-button-small" [class.uk-disabled]="(this.selectedResults.length>=basketLimit)" *ngIf="!isSelected(entity)"
(click)="add(entity)">
<icon name="add" [flex]="true"></icon>
</button>
<button *ngIf="isSelected(entity)" class="linking-selected-button" (click)="remove(entity)">
<button *ngIf="isSelected(entity)" class="linking-selected-button uk-icon-button-small" (click)="remove(entity)">
<icon name="check" [flex]="true"></icon>
</button>
</div>
</div>
</div>
</div>
</div>`,
</div>
`
})
export class ClaimResultsComponent {
@Input() results: ClaimEntity[];
@ -41,6 +36,9 @@ export class ClaimResultsComponent {
@Input() localStoragePrefix: string = "";
@Input() basketLimit;
ngOnInit() {
}
public isSelected(item: ClaimEntity) {
return !!this.selectedResults.find(result => item.id === result.id);
}

View File

@ -16,7 +16,7 @@
</div>
<div [class.uk-padding]="actions" class="uk-padding-remove-vertical">
<div class="uk-margin-medium-top">
<results-and-pages [type]="resultsNum !== 1?'Links':'Link'" [page]="page" [pageSize]="size"
<results-and-pages [type]="resultsNum !== 1?'Links':'Link'" [page]="page" [pageSize]="size" [hasSearch]="true" [searchTerm]="keyword"
[totalResults]="resultsNum" customClasses="uk-margin-remove"></results-and-pages>
</div>
<div class="uk-grid uk-flex-middle uk-margin-medium-top" uk-grid>

View File

@ -240,7 +240,7 @@ export class DisplayClaimsComponent implements OnInit, OnDestroy {
handleErrors(err, message) {
NotificationHandler.rise(message, "danger");
console.error("Dispaly Claims (component): " + message + " " + (err && err.error ? err.error : ''));
console.error("Display Claims (component): " + message + " " + (err && err.error ? err.error : ''));
}
goTo(page: number = 1) {
@ -290,7 +290,7 @@ export class DisplayClaimsComponent implements OnInit, OnDestroy {
}
changeKeyword() {
if (this.filterForm.get("keyword") && (this.filterForm.get("keyword").value.length >= 3 || this.filterForm.get("keyword").value.length == 0)) {
if (this.filterForm.get("keyword") && (this.filterForm.get("keyword").value?.length >= 3 || this.filterForm.get("keyword").value?.length == 0)) {
this.searchTermStream.next(this.filterForm.get("keyword").value);
}
}

View File

@ -50,7 +50,6 @@ export class SearchDataciteService {
static parse(response): ClaimEntity[] {
const results: ClaimEntity[] = [];
console.log(response);
for (let i = 0; i < response.length; i++) {
const item = response[i];
const entity: ClaimEntity = new ClaimEntity();

View File

@ -10,6 +10,7 @@ import {Subscriber} from "rxjs";
import {properties} from "../../../../environments/environment";
import {OpenaireEntities} from "../../utils/properties/searchFields";
import {StringUtils} from "../../utils/string-utils.class";
import {ClaimProjectsSearchFormComponent} from "../claim-utils/claimProjectSearchForm.component";
@Component({
@ -152,6 +153,7 @@ export class DirectLinkingComponent {
entity.type = "project";
entity.title = project.projectName;
entity.project = new ClaimProject();
entity.project.url = properties.searchLinkToProject + entity.id;
entity.project.acronym = project.projectAcronym;
entity.project.code = project.code;
entity.project.endDate = project.endDate;

View File

@ -1,20 +1,61 @@
<ng-template #destinations_basket>
<div *ngIf="(results.length)> 0 || showOptions.show=='result'" class="uk-padding-small uk-padding-remove-horizontal" style="min-height: 17px;">
<start-over *ngIf=" (results.length)> 0"
[results]="results" [localStoragePrefix]="localStoragePrefix+'results'"
message="all results (projects, communities, research results)"
class="uk-float-right"></start-over>
<bulk-claim *ngIf="showOptions.show=='result'" [results]="results" [properties]=properties
[localStoragePrefix]="localStoragePrefix+'results'"
[basketLimit]="basketLimit"></bulk-claim>
</div>
<div class="uk-padding-small uk-padding-remove-horizontal">
<div *ngIf="results.length >= basketLimit "
class="uk-alert uk-alert-warning uk-text-center">
Basket reached the size limit. No more entities can be added.
</div>
<claim-selected-results sectionTitle="Selected Results" [results]="results"
[localStoragePrefix]="localStoragePrefix+'results'" type="target">
</claim-selected-results>
<div *ngIf="(results.length) == 0 " class=" uk-text-center">
No entities to link with the sources. Start adding entities from the left panel.
</div>
</div>
</ng-template>
<div class="linking uk-background-default">
<div class="uk-container uk-container-large uk-section uk-section-small uk-padding-remove-bottom">
<div class="uk-padding-small uk-padding-remove-horizontal">
<breadcrumbs [breadcrumbs]="breadcrumbs"></breadcrumbs>
<breadcrumbs *ngIf="!inlineEntity" [breadcrumbs]="breadcrumbs"></breadcrumbs>
<!-- [routerLink]="inlineEntity.result?.url.split('?')[0]"-->
<!-- [queryParams]="routerHelper.createQueryParam(inlineEntity.result?.url.split('?')[1].split('=')[0], inlineEntity.id)"-->
<a *ngIf="inlineEntity && inlineEntity.result"
(click)="back()"
class="uk-button uk-button-link uk-text-transform-none uk-flex uk-flex-middle">
<icon name="west" [flex]="true"></icon>
<span class="uk-margin-small-left">Back to {{getEntityName(inlineEntity.type, false)}}</span>
</a>
<a *ngIf="inlineEntity && inlineEntity.project"
[routerLink]="inlineEntity.project?.url?.split('?')[0]"
[queryParams]="routerHelper.createQueryParam(inlineEntity.project?.url.split('?')[1].split('=')[0], inlineEntity.id)"
class="uk-button uk-button-link uk-text-transform-none uk-flex uk-flex-middle">
<icon name="west" [flex]="true"></icon>
<span class="uk-margin-small-left">Back to {{getEntityName(inlineEntity.type, false)}}</span>
</a>
</div>
</div>
<div uk-sticky="offset: 65; bottom: #pageBottom; media: @m" class="uk-blur-background">
<div *ngIf="!inlineEntity" uk-sticky="offset: 65; bottom: #pageBottom; media: @m" class="uk-blur-background">
<div class="uk-section-xsmall">
<stepper>
<step *ngIf="!inlineEntity" [status]="stepStatus('source')" stepId="source" stepNumber="1"
<step [status]="stepStatus('source')" stepId="source" stepNumber="1"
[stepText]="'Find Sources'" (stepChanged)="stepHasChanged($event)"
[active]="this.showOptions.show" [showStepLine]="false"></step>
<step [status]="stepStatus('target')" stepId="target" [stepNumber]="inlineEntity?1:2"
[stepText]="'Link Source' + (inlineEntity?'':'s') + ' to Entities'"
<step [status]="stepStatus('target')" stepId="target" [stepNumber]="2"
[stepText]="'Link Sources to Entities'"
(stepChanged)="stepHasChanged($event)" [active]="this.showOptions.show"
[showStepLine]="!inlineEntity"></step>
<step [status]="stepStatus('claim')" stepId="claim" [stepNumber]="inlineEntity?2:3"
[showStepLine]="true"></step>
<step [status]="stepStatus('claim')" stepId="claim" [stepNumber]="3"
[stepText]="'Summarize and finish'"
(stepChanged)="stepHasChanged($event)" [active]="this.showOptions.show"
[showStepLine]="true"></step>
@ -37,16 +78,18 @@
<div [class]="((showOptions.show == 'claim')?'':' uk-margin-top ')+' uk-container uk-container-large '">
<div class="uk-grid basketContainer" *ngIf="showOptions.show!='claim'" uk-grid>
<div class="uk-width-2-3 uk-position-z-index">
<h2 *ngIf="inlineEntity" class="uk-text-center">Link source to</h2>
<div *ngIf="showOptions.show=='source'">
<claim-result-search-form [selectedResults]="sources" [properties]=properties
[localStoragePrefix]="localStoragePrefix+'sources'"
[basketLimit]="basketLimit"
[basketLimit]="basketLimit" [centerAlign]="!!inlineEntity"
></claim-result-search-form>
</div>
<div *ngIf="showOptions.show=='project'">
<claim-projects-search-form [selectedProjects]="results" [properties]=properties
[localStoragePrefix]="localStoragePrefix+'results'"
[basketLimit]="basketLimit" [showOptions]="showOptions"
[centerAlign]="!!inlineEntity"
></claim-projects-search-form>
</div>
<div *ngIf="showOptions.show=='context'">
@ -54,12 +97,14 @@
[properties]=properties
[localStoragePrefix]="localStoragePrefix+'results'"
[basketLimit]="basketLimit" [showOptions]="showOptions"
[centerAlign]="!!inlineEntity"
></claim-contexts-search-form>
</div>
<div *ngIf="showOptions.show=='result'">
<claim-result-search-form [selectedResults]="results" [properties]=properties
[localStoragePrefix]="localStoragePrefix+'results'"
[basketLimit]="basketLimit" [showOptions]="showOptions"
[centerAlign]="!!inlineEntity"
></claim-result-search-form>
</div>
</div>
@ -69,78 +114,70 @@
<div class="uk-card uk-card-default linkingBasket">
<div class="uk-card-body uk-padding-small">
<div class="uk-margin-right">
<ul class="uk-tab" uk-tab>
<li [class.uk-active]="showOptions.basketShowSources"
(click)="showOptions.basketswitchToSources()">
<a>
Sources to link ({{(sources.length + (inlineEntity ? 1 : 0)) |number}})
</a>
</li>
<li [class.uk-disabled]="sources.length == 0 && !inlineEntity"
[class.uk-active]="showOptions.basketShowLinksTo">
<a (click)="showOptions.basketswitchToLinkTo()">Link to <span
*ngIf="results.length> 0">({{(results.length) | number}})</span>
</a>
</li>
</ul>
<div *ngIf="showOptions.basketShowSources">
<div class="uk-height-medium uk-overflow-auto">
<div *ngIf="showOptions.show == 'source'" class="uk-padding-small uk-padding-remove-horizontal" style="min-height:17px;">
<start-over *ngIf="showOptions.show == 'source' && sources.length> 0"
[results]="sources"
[localStoragePrefix]="localStoragePrefix+'sources'"
message="all sources" class="uk-float-right"></start-over>
<bulk-claim *ngIf="showOptions.show == 'source'" [results]="sources"
[properties]=properties
[localStoragePrefix]="localStoragePrefix+'sources'" [basketLimit]="basketLimit"
>
</bulk-claim>
<ng-container *ngIf="inlineEntity">
<div class="uk-margin-small-bottom">
<div class="uk-text-emphasis uk-text-bolder">Source</div>
<claim-selected-results [results]="[inlineEntity]"
[localStoragePrefix]="localStoragePrefix+'sources'" class=""
[enableRemove]="false" type="source">
</claim-selected-results>
</div>
<div class="uk-padding-small uk-padding-remove-horizontal"><hr class="uk-margin-remove"/></div>
<div class="uk-margin-small-top">
<div class="uk-text-emphasis uk-text-bolder">Link source to <span *ngIf="results.length> 0">({{(results.length) | number}})</span></div>
<ng-container *ngTemplateOutlet="destinations_basket"></ng-container>
</div>
</ng-container>
<ng-container *ngIf="!inlineEntity">
<ul class="uk-tab" uk-tab>
<li [class.uk-active]="showOptions.basketShowSources"
(click)="showOptions.basketswitchToSources()">
<a>
Sources to link ({{(sources.length) |number}})
</a>
</li>
<li [class.uk-disabled]="sources.length == 0"
[class.uk-active]="showOptions.basketShowLinksTo">
<a (click)="showOptions.basketswitchToLinkTo()">Link to <span
*ngIf="results.length> 0">({{(results.length) | number}})</span>
</a>
</li>
</ul>
<div *ngIf="showOptions.basketShowSources">
<div class="uk-height-medium uk-overflow-auto">
<div *ngIf="showOptions.show == 'source'" class="uk-padding-small uk-padding-remove-horizontal" style="min-height:17px;">
<start-over *ngIf="showOptions.show == 'source' && sources.length> 0"
[results]="sources"
[localStoragePrefix]="localStoragePrefix+'sources'"
message="all sources" class="uk-float-right"></start-over>
<bulk-claim *ngIf="showOptions.show == 'source'" [results]="sources"
[properties]=properties
[localStoragePrefix]="localStoragePrefix+'sources'" [basketLimit]="basketLimit"
>
</bulk-claim>
</div>
<div class="uk-padding-small uk-padding-remove-horizontal">
<div *ngIf="sources.length == 0 && !inlineEntity " class="uk-text-center uk-text-meta">
No Sources added yet. Start adding sources from the left panel. Or upload a DOI's CSV file.
</div>
<div *ngIf="sources.length >= basketLimit " class="uk-alert uk-alert-warning uk-text-center">
Basket reached the size limit. No more sources can be added.
<div class="uk-padding-small uk-padding-remove-horizontal">
<div *ngIf="sources.length == 0" class="uk-text-center uk-text-meta">
No Sources added yet. Start adding sources from the left panel. Or upload a DOI's CSV file.
</div>
<div *ngIf="sources.length >= basketLimit " class="uk-alert uk-alert-warning uk-text-center">
Basket reached the size limit. No more sources can be added.
</div>
<claim-selected-results *ngIf="sources.length > 0" [results]="sources"
[localStoragePrefix]="localStoragePrefix+'sources'" class=""
[enableRemove]="true" type="source">
</claim-selected-results>
</div>
<claim-selected-results *ngIf="inlineEntity" [results]="[inlineEntity]"
[localStoragePrefix]="localStoragePrefix+'sources'" class=""
[enableRemove]="false" type="source">
</claim-selected-results>
<claim-selected-results *ngIf="sources.length > 0" [results]="sources"
[localStoragePrefix]="localStoragePrefix+'sources'" class=""
[enableRemove]="true" type="source">
</claim-selected-results>
</div>
</div>
</div>
<div *ngIf="showOptions.basketShowLinksTo">
<div class="uk-height-medium uk-overflow-auto">
<div *ngIf="(results.length)> 0 || showOptions.show=='result'" class="uk-padding-small uk-padding-remove-horizontal" style="min-height: 17px;">
<start-over *ngIf=" (results.length)> 0"
[results]="results" [localStoragePrefix]="localStoragePrefix+'results'"
message="all results (projects, communities, research results)"
class="uk-float-right"></start-over>
<bulk-claim *ngIf="showOptions.show=='result'" [results]="results" [properties]=properties
[localStoragePrefix]="localStoragePrefix+'results'"
[basketLimit]="basketLimit"></bulk-claim>
</div>
<div class="uk-padding-small uk-padding-remove-horizontal">
<div *ngIf="results.length >= basketLimit "
class="uk-alert uk-alert-warning uk-text-center">
Basket reached the size limit. No more entities can be added.
</div>
<claim-selected-results sectionTitle="Selected Results" [results]="results"
[localStoragePrefix]="localStoragePrefix+'results'" type="target">
</claim-selected-results>
<div *ngIf="(results.length) == 0 " class=" uk-text-center">
No entities to link with the sources. Start adding entities from the left panel.
</div>
<div *ngIf="showOptions.basketShowLinksTo">
<div class="uk-height-medium uk-overflow-auto">
<ng-container *ngTemplateOutlet="destinations_basket"></ng-container>
</div>
</div>
</div>
</ng-container>
</div>
</div>
<div *ngIf="showOptions.show == 'source'"
@ -164,7 +201,7 @@
<button class="uk-flex uk-flex-middle uk-button uk-button-text"
[class.uk-disabled]="results.length == 0" [disabled]="results.length == 0">
<icon *ngIf="inlineEntity" name="link" visuallyHidden="link" [flex]="true"></icon>
<div class="uk-width-expand uk-margin-small-left">STEP {{inlineEntity ? '2' : '3'}} - FINALISE AND FINISH</div>
<div class="uk-width-expand uk-margin-small-left"><ng-container *ngIf="!inlineEntity">STEP {{inlineEntity ? '2' : '3'}} - </ng-container>SUMMARISE</div>
</button>
</div>
</div>

View File

@ -13,6 +13,9 @@ import {Subscriber} from "rxjs";
import {properties} from "../../../../environments/environment";
import {Breadcrumb} from "../../utils/breadcrumbs/breadcrumbs.component";
import {OpenaireEntities} from "../../utils/properties/searchFields";
import {StringUtils} from "../../utils/string-utils.class";
import {RouterHelper} from "../../utils/routerHelper.class";
import { Location } from '@angular/common';
@Component({
selector: 'linking-generic',
@ -44,10 +47,12 @@ export class LinkingGenericComponent {
@ViewChild(AlertModal) alert;
public pageContents = null;
@Input() breadcrumbs: Breadcrumb[] = [];
public routerHelper: RouterHelper = new RouterHelper();
constructor (private _router: Router, private route: ActivatedRoute, private entitySearch:EntitiesSearchService,
private _meta: Meta, private _title: Title, private _piwikService:PiwikService,
private seoService: SEOService, private helper: HelperService, private cdr: ChangeDetectorRef ) {
private seoService: SEOService, private helper: HelperService, private cdr: ChangeDetectorRef,
private location: Location) {
}
subscriptions = [];
@ -161,6 +166,7 @@ export class LinkingGenericComponent {
this.showOptions.show = 'claim';
}
this.cdr.detectChanges();
HelperFunctions.scroll(true);
console.log('stepHasChanged', stepId, this.showOptions.show)
}
@ -194,4 +200,13 @@ export class LinkingGenericComponent {
}
}
private getEntityName (entityType:string, plural:boolean) {
return StringUtils.getEntityName(entityType, plural);
}
back(): void {
if(typeof document !== 'undefined') {
this.location.back();
}
}
}

View File

@ -0,0 +1,11 @@
@import (reference) "~src/assets/openaire-theme/less/_import-variables";
.claim-entity-metadata {
& > *:not(:last-child):not(.other-separator)::after {
content: "\2022";
font-weight: normal;
margin-left: @global-xsmall-margin;
margin-right: @global-xsmall-margin;
}
}

View File

@ -4,18 +4,28 @@ import {ClaimEntity} from '../../claim-utils/claimHelper.class';
@Component({
selector: 'claim-project-metadata',
template: `
<div *ngIf="entity.type == 'project' && entity.project" class="uk-text-small uk-flex uk-flex-wrap" [style.grid-gap]="shortVersion?'10px':'20px'">
<div *ngIf="entity.project.funderName">
<span class="uk-text-meta">Funder: </span>{{entity.project.funderName}}
</div>
<div *ngIf="entity.project.code">
<span class="uk-text-meta">GrandID: </span>{{entity.project.code}}
</div>
<div *ngIf=" !shortVersion && (entity.project.startDate || entity.project.endDate)">
<span class="uk-text-meta">Duration: </span>{{(entity.project.startDate) ? entity.project.startDate : 'Unknown'}}{{'-' + ((entity.project.endDate) ? entity.project.endDate : 'Unknown')}}
</div>
</div>
`
<ng-container *ngIf="entity.type == 'project' && entity.project">
<div *ngIf="!shortVersion" class="claim-entity-metadata uk-flex-inline uk-flex-wrap uk-text-xsmall uk-text-emphasis"
[class.uk-margin-xsmall-top]="!shortVersion">
<span class="uk-text-capitalize">
{{entity.type}}
</span>
<span *ngIf="entity.project.startDate || entity.project.endDate">
{{(entity.project.startDate) ? entity.project.startDate : 'Unknown'}}{{'-' + ((entity.project.endDate) ? entity.project.endDate : 'Unknown')}}
</span>
</div>
<div class="uk-text-small uk-flex uk-flex-wrap" [style.grid-gap]="shortVersion?'10px':'20px'"
[class.uk-margin-small-top]="!shortVersion">
<div *ngIf="entity.project.funderName">
<span class="uk-text-meta">Funder: </span>{{entity.project.funderName}}
</div>
<div *ngIf="entity.project.code">
<span class="uk-text-meta">Project Code: </span>{{entity.project.code}}
</div>
</div>
</ng-container>
`,
styleUrls: ['ClaimEntityMetadata.component.less']
})

View File

@ -4,29 +4,37 @@ import {ClaimEntity} from '../../claim-utils/claimHelper.class';
@Component({
selector: 'claim-result-metadata',
template: `
<div *ngIf="entity.result" class="uk-text-small">
<div *ngIf="entity.result.authors && entity.result.authors.length >0 " class="uk-margin-small-bottom">
<span class="uk-text-meta">Authors: </span>{{sliceArray(entity.result.authors)}}
</div>
<div *ngIf="!shortVersion && entity.result.editors&& entity.result.editors.length > 0" class="uk-margin-small-bottom">
<span class="uk-text-meta">Editors: </span>{{sliceArray(entity.result.editors)}}
</div>
<div *ngIf="!shortVersion" class="uk-flex uk-flex-wrap" style="grid-gap: 20px;">
<span *ngIf="entity.result.publisher!=null">
<span class="uk-text-meta uk-margin-small-bottom">Publisher: </span>{{entity.result.publisher}}
<div *ngIf="entity.result">
<!-- display all existing data similar to entity-metadata -->
<div *ngIf="!shortVersion" class="claim-entity-metadata uk-flex-inline uk-flex-wrap uk-text-xsmall uk-text-emphasis uk-margin-xsmall-top">
<span class="uk-text-capitalize uk-text-italic">
{{(!entity.result) ? entity.type : ((entity.result && entity.result.source == 'openaire') ? entity.type : (entity.result && entity.result.source + ' result'))}}
</span>
<span *ngIf="entity.result.publisher!=null">
{{entity.result.publisher}}
</span>
<span *ngIf="entity.result.journal!=null">
<span class="uk-text-meta uk-margin-small-bottom">Journal: </span>{{entity.result.journal}}
</span>
<span *ngIf="entity.result.date">
<span class="uk-text-meta uk-margin-small-bottom">Published: </span>
<span *ngIf="entity.result.date">
<span [class]="(getProjectDurationMessage(entity)?'uk-text-warning':'')">{{entity.result.date}}</span>
</span>
<div [class]="(getProjectDurationMessage(entity)?'uk-text-warning':'')">{{getProjectDurationMessage(entity)}}
</div>
<span *ngIf="entity.result.journal!=null">
{{entity.result.journal}}
</span>
<div *ngIf="entity.result.editors && entity.result.editors.length > 0">
{{sliceArray(entity.result.editors)}}
</div>
</div>
<div *ngIf="entity.result.authors && entity.result.authors.length > 0" class="uk-flex uk-flex-wrap uk-text-small uk-text-emphasis uk-text-italic"
[class.uk-margin-small-top]="!shortVersion">
{{sliceArray(entity.result.authors)}}
</div>
<div class="uk-text-small uk-margin-top">
<span *ngIf="getProjectDurationMessage(entity)" [class]="(getProjectDurationMessage(entity)?'uk-text-warning':'')">
{{getProjectDurationMessage(entity)}}
</span>
</div>
</div>
`
`,
styleUrls: ['ClaimEntityMetadata.component.less']
})

View File

@ -1,64 +1,67 @@
import {Component, Input} from '@angular/core';
import {ClaimEntity} from '../../claim-utils/claimHelper.class';
import {StringUtils} from "../../../utils/string-utils.class";
@Component({
selector: 'claim-title',
template:
`
<div class="uk-grid uk-flex uk-flex-middle">
<span *ngIf="showIcon" >
<span *ngIf=" entity.result" class="material-icons uk-text-small uk-text-meta" >insert_drive_file
</span>
<span *ngIf=" entity.project"
class="material-icons uk-text-small uk-text-meta">assignment_turned_in
</span>
<span *ngIf="entity.type=='community'" style="margin-right: 2px;"
class="material-icons uk-text-small uk-text-meta">people
</span></span>
<div class="uk-width-expand " style="word-break: break-word;" [class.uk-h6]="!shortVersion" [class.uk-text-bold]="shortVersion" [class.uk-text-truncate]="shortVersion" [class.uk-margin-bottom]="!shortVersion" [class.uk-padding-remove-left]="showIcon">
<a *ngIf="entity.result && entity.result.url" target="_blank" [href]="entity.result.url"
class="uk-link uk-link-heading">{{entity.title ? sliceString(entity.title) : '[No title available]'}}</a>
<span
*ngIf="(entity.result && !entity.result.url)">{{entity.title ? sliceString(entity.title) : '[No title available]'}}</span>
<span *ngIf="entity.type=='project' && entity.project">
<a *ngIf="entity.project && entity.project.url" target="_blank" [href]="entity.project.url"
class="uk-text-link">
<span *ngIf="!shortVersion">
{{(entity.project.acronym ? '[' + entity.project.acronym + '] ' : '') + entity.title}}
</span>
<span *ngIf="shortVersion">
{{(entity.project.acronym ? sliceString(entity.project.acronym):sliceString(entity.title))}}
</span>
template: `
<div class="uk-grid uk-flex uk-flex-middle">
<span *ngIf="showIcon" class="uk-flex">
<span *ngIf="entity.result" class="material-icons uk-text-small uk-text-meta">
insert_drive_file
</span>
<span *ngIf="entity.project" class="material-icons uk-text-small uk-text-meta">
assignment_turned_in
</span>
<span *ngIf="entity.type=='community'" class="material-icons uk-text-small uk-text-meta" style="margin-right: 2px;">
people
</span>
</span>
<div class="uk-width-expand multi-line-ellipsis lines-3" style="word-break: break-word;"
[class.uk-padding-remove-left]="showIcon" [class.uk-text-truncate]="shortVersion">
<div class="uk-margin-remove uk-text-break uk-inline-block"
[class.uk-h6]="!shortVersion" [class.uk-text-bold]="shortVersion">
<a *ngIf="entity.result && entity.result.url" target="_blank" [href]="entity.result.url"
class="uk-link uk-text-decoration-none uk-width-expand">
{{entity.title ? sliceString(entity.title) : '[No title available]'}}
</a>
<span
*ngIf="(entity.project && !entity.project.url)">
<span *ngIf="!shortVersion">
{{(entity.project.acronym ? '[' + entity.project.acronym + '] ' : '') + entity.title}}
</span>
<span *ngIf="shortVersion">
{{(entity.project.acronym ? sliceString(entity.project.acronym):sliceString(entity.title))}}
</span>
</span>
</span>
<span *ngIf="entity.type=='community' && entity.context">
<span *ngIf=" entity.context.community != entity.context.concept.label">
{{entity.context.community }} > {{entity.context.category}} >
</span>
<span> {{entity.context.concept.label}}</span>
</span>
<span *ngIf="(entity.result && !entity.result.url)">
{{entity.title ? sliceString(entity.title) : '[No title available]'}}
</span>
<span *ngIf="entity.type=='project' && entity.project">
<a *ngIf="entity.project && entity.project.url" target="_blank" [href]="entity.project.url"
class="uk-link uk-text-decoration-none uk-width-expand">
<span *ngIf="!shortVersion">
{{(entity.project.acronym ? '[' + entity.project.acronym + '] ' : '') + entity.title}}
</span>
<span *ngIf="shortVersion">
{{(entity.project.acronym ? sliceString(entity.project.acronym):sliceString(entity.title))}}
</span>
</a>
<span *ngIf="(entity.project && !entity.project.url)">
<span *ngIf="!shortVersion">
{{(entity.project.acronym ? '[' + entity.project.acronym + '] ' : '') + entity.title}}
</span>
<span *ngIf="shortVersion">
{{(entity.project.acronym ? sliceString(entity.project.acronym):sliceString(entity.title))}}
</span>
</span>
</span>
<span *ngIf="entity.type=='community' && entity.context">
<span *ngIf=" entity.context.community != entity.context.concept.label">
{{entity.context.community }} > {{entity.context.category}} >
</span>
<span>
{{entity.context.concept.label}}
</span>
</span>
</div>
</div>
</div>
</div>
`
})
export class ClaimEntityTitleComponent {
@Input() entity: ClaimEntity;
@Input() slice:boolean = false;
@Input() sliceSize:number = 45;
@ -66,14 +69,13 @@ export class ClaimEntityTitleComponent {
@Input() showIcon: boolean = false;
ngOnInit() {
}
sliceString(mystr:string): string {
if(this.slice){
if(this.slice){
// return StringUtils.sliceString(mystr,this.sliceSize);
}
return mystr;
}
return mystr;
}
}

View File

@ -12,8 +12,8 @@
<div class=" uk-margin uk-animation-toggle">
<span class="uk-h6 "> SOURCES ({{sources.length + (inlineEntity ? 1 : 0) | number}})
</span>
<a *ngIf="!inlineEntity" class="uk-float-right" (click)="showOptions.showSource() "> <span
uk-icon="pencil"></span>Edit
<a *ngIf="!inlineEntity" class="uk-float-right uk-text-small" (click)="showOptions.showSource() "> <span
uk-icon="pencil" class="uk-margin-xsmall-right"></span>Edit
sources</a>
</div>
<ul *ngIf="inlineEntity" class="uk-list uk-animation-fade uk-list-divider">
@ -51,10 +51,10 @@
<ul *ngIf="!inlineEntity && sources.length > 0 " class="uk-list uk-animation-fade uk-list-divider">
<li *ngFor=" let entity of sources ">
<div class="uk-grid uk-text-small uk-margin-top">
<div class="uk-text-muted uk-width-1-2 uk-flex uk-flex-middle">
<!-- <div class="uk-text-muted uk-width-1-2 uk-flex uk-flex-middle">
<span class="material-icons uk-text-small uk-text-meta">insert_drive_file</span>
{{(!entity.result) ? entity.type : ((entity.result && entity.result.source == 'openaire') ? entity.type : (entity.result && entity.result.source + ' result'))}}
</div>
</div> -->
<div *ngIf="entity.errorMessages.length > 0"
class="uk-text-danger uk-width-1-2"> Link couldn't be saved
</div>
@ -157,8 +157,8 @@
<span class=" uk-h6 "> LINK TO ({{results.length | number}})</span>
<a class="uk-float-right" (click)="showOptions.showLinkTo()"> <span
uk-icon="pencil"></span>Edit
<a class="uk-float-right uk-text-small" (click)="showOptions.showLinkTo()"> <span
uk-icon="pencil" class="uk-margin-xsmall-right"></span>Edit
entities</a>
</div>
<div *ngIf="results.length == 0">
@ -174,7 +174,7 @@
<li *ngFor=" let entity of results "
style="z-index: 0 !important;">
<div class="uk-grid uk-text-small uk-margin-top">
<div class="uk-text-muted uk-width-1-2 uk-flex uk-flex-middle">
<!-- <div class="uk-text-muted uk-width-1-2 uk-flex uk-flex-middle">
<span *ngIf="entity.result" class="material-icons uk-text-small uk-text-meta">insert_drive_file
</span>
<span *ngIf="entity.project"
@ -184,7 +184,7 @@
class="material-icons uk-text-small uk-text-meta">people
</span>
{{(!entity.result) ? entity.type : ((entity.result && entity.result.source == 'openaire') ? entity.type : (entity.result && entity.result.source + ' result'))}}
</div>
</div> -->
<div *ngIf="entity.errorMessages.length > 0"
class="uk-text-danger uk-width-1-2"> Link couldn't be saved
</div>

View File

@ -75,6 +75,11 @@ export class LayoutService {
private isMobileSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
/** Active sidebar Item*/
private activeSidebarItemSubject: BehaviorSubject<SidebarItem> = new BehaviorSubject<SidebarItem>(null);
/**
* Add hasMenuSearchBar: false/ nothing on data of route config, if the search bar in the menu should not appear, otherwise true.
*/
private hasMenuSearchBarSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
private subscriptions: any[] = [];
ngOnDestroy() {
@ -166,6 +171,12 @@ export class LayoutService {
} else {
this.setActiveMenuItem('');
}
if (data['hasMenuSearchBar'] !== undefined &&
data['hasMenuSearchBar'] === true) {
this.setHasMenuSearchBar(true);
} else {
this.setHasMenuSearchBar(false);
}
}
}));
this.setObserver();
@ -292,4 +303,12 @@ export class LayoutService {
setActiveSidebarItem(value: SidebarItem) {
this.activeSidebarItemSubject.next(value);
}
get hasMenuSearchBar(): Observable<boolean> {
return this.hasMenuSearchBarSubject.asObservable();
}
setHasMenuSearchBar(value: boolean) {
this.hasMenuSearchBarSubject.next(value);
}
}

View File

@ -29,7 +29,8 @@ import {SearchForm} from "../searchPages/searchUtils/newSearchPage.component";
<div class="uk-container uk-container-large">
<div class="uk-margin-top uk-flex uk-flex-center">
<div class="uk-width-large" [class.dark]="searchForm.dark">
<div search-input [(value)]="keyword" placeholder="Search by name, description, subject..." (searchEmitter)="keywordChanged()"></div>
<div search-input [(value)]="keyword" placeholder="Search by name, description, subject..." (searchEmitter)="keywordChanged()"
[searchInputClass]="'inner background'"></div>
<div class="uk-margin-top uk-text-center uk-margin-medium-bottom">
<a *ngIf="zenodoInformation.url" [href]="zenodoInformation.url" target="_blank" class="uk-display-inline-block uk-text-uppercase uk-button uk-button-text">
<span class="uk-flex uk-flex-middle">

View File

@ -22,7 +22,7 @@
<ul *ngIf="keyword?.length" class="uk-tab uk-tab-left">
<li *ngFor="let item of viewResults; index as i"
class="uk-margin-small-bottom uk-text-capitalize" [class.uk-active]="activeSection === item.id">
<a (click)="scrollToId(item.id)">{{item.id}}</a>
<a (click)="scrollToId(item.id)">{{item.id}}</a>
</li>
</ul>
</div>

View File

@ -18,7 +18,7 @@
We have integrated a Field-of-Science (FoS) taxonomy into our dataset to organize and discover research more effectively. Using the full capabilities of the OpenAIRE Graph (full-texts, citations, references, venues) we apply AI and bring forward any multidisciplinarity potential.
</div>
<div class="uk-text-meta uk-margin-top" uk-scrollspy-class>
Our work is based on the work from our partner Athena Research Center: SciNoBo : A Hierarchical Multi-Label Classifier of Scientific Publications - <a href="https://doi.org/10.1145/3487553.3524677" target="_blank">https://doi.org/10.1145/3487553.3524677</a>
Our work is based on the work from our partner Athena Research Center: SciNoBo : a novel system classifying scholarly communication in a dynamically constructed hierarchical Field-of-Science taxonomy - <a href="https://doi.org/10.3389/frma.2023.1149834" target="_blank">https://doi.org/10.3389/frma.2023.1149834</a>
</div>
<!-- TODO: We need a page for the button link -->
<!-- <div>
@ -113,7 +113,7 @@
<div *ngFor="let subChild of child.children" style="margin-bottom: 5px;">
<a [routerLink]="properties.searchLinkToResults" [queryParams]="{'fos': urlEncodeAndQuote(subChild.id)}"
class="uk-link-text">
{{subChild.id}}
{{subChild.label}}
</a>
</div>
</div>
@ -139,7 +139,7 @@
</h3>
<div *ngFor="let subSubItem of subItem.children" style="margin-bottom: 5px;">
<a [routerLink]="properties.searchLinkToResults" [queryParams]="{'fos': urlEncodeAndQuote(subSubItem.id)}"
class="uk-link-text" [innerHTML]="highlightKeyword(subSubItem.id)">
class="uk-link-text" [innerHTML]="highlightKeyword(subSubItem.label)">
</a>
</div>
</div>

View File

@ -26,7 +26,7 @@ declare var UIkit;
export class FosComponent implements OnInit, OnDestroy {
public url: string = null;
public pageTitle: string = "OpenAIRE | Fields of Science";
public pageDescription: string = "We have integrated a Field-of-Science (FoS) taxonomy into our dataset to organize and discover research more effectively. Using the full capabilities of the OpenAIRE Research Graph (full-texts, citations, references, venues) we apply AI and bring forward any multidisciplinarity potential.";
public pageDescription: string = "We have integrated a Field-of-Science (FoS) taxonomy into our dataset to organize and discover research more effectively. Using the full capabilities of the OpenAIRE Graph (full-texts, citations, references, venues) we apply AI and bring forward any multidisciplinarity potential.";
@Input() piwikSiteId = null;
public fos: any[] = [];

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
import {ChangeDetectorRef, Component, ElementRef, HostListener, Input, ViewChild} from '@angular/core';
import {ChangeDetectorRef, Component, ElementRef, Input, ViewChild} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import {Meta, Title} from '@angular/platform-browser';
@ -25,9 +25,12 @@ import {SearchResult} from "../../utils/entities/searchResult";
import {ResultPreview} from "../../utils/result-preview/result-preview";
import {IndexInfoService} from "../../utils/indexInfo.service";
import {properties} from "../../../../environments/environment";
import {Subscriber} from "rxjs";
import {TabComponent} from "../../utils/tabs/tab.component";
import {Subscriber, Subscription, zip} from "rxjs";
import {OpenaireEntities} from "../../utils/properties/searchFields";
import {MetricsService} from '../../services/metrics.service';
import {NumberUtils} from '../../utils/number-utils.class';
import {LayoutService} from '../../dashboard/sharedComponents/sidebar/layout.service';
import {FullScreenModalComponent} from '../../utils/modal/full-screen-modal/full-screen-modal.component';
declare var ResizeObserver;
@ -64,16 +67,21 @@ export class DataProviderComponent {
public metricsClicked: boolean;
public viewsFrameUrl: string;
public downloadsFrameUrl: string;
public totalViews: number;
public totalDownloads: number;
public pageViews: number;
/** @deprecated*/
public totalViews: number = null;
/** @deprecated*/
public totalDownloads: number = null;
public hasViews: boolean = false;
public hasDownloads: boolean = false;
// public pageViews: number;
// Statistics tab variables
public statsClicked: boolean = false;
// @ViewChild('statisticsModal') statisticsModal;
// @ViewChild('relatedDatasourcesModal') relatedDatasourcesModal;
@ViewChild('addThisModal') addThisModal
@ViewChild('addThisModal') addThisModal;
@ViewChild('addThisFsModal') addThisFsModal: FullScreenModalComponent;
// Variables for publications, research data, projects, datasources, related datasources tabs
public fetchPublications: FetchResearchResults;
@ -144,9 +152,25 @@ export class DataProviderComponent {
// public shouldSticky: boolean = true;
subscriptions = [];
private sub: Subscription;
properties: EnvProperties = properties;
public openaireEntities = OpenaireEntities;
public isMobile: boolean = false;
public mobileContent: "info" | "metrics" | "actions" = "info";
public tabMobile: string = "";
public viewAllMobile: string = "";
// Full screen modals for small screens (mobile)
@ViewChild('summaryFsModal') summaryFsModal: FullScreenModalComponent;
@ViewChild('projectsFsModal') projectsFsModal: FullScreenModalComponent;
@ViewChild('dataprovidersFsModal') dataprovidersFsModal: FullScreenModalComponent;
@ViewChild('publicationsFsModal') publicationsFsModal: FullScreenModalComponent;
@ViewChild('datasetsFsModal') datasetsFsModal: FullScreenModalComponent;
@ViewChild('softwareFsModal') softwareFsModal: FullScreenModalComponent;
@ViewChild('otherFsModal') otherFsModal: FullScreenModalComponent;
@ViewChild('relatedDatasourcesFsModal') relatedDatasourcesFsModal: FullScreenModalComponent;
@ViewChild('statisticsFsModal') statisticsFsModal: FullScreenModalComponent;
constructor(private _dataproviderService: DataProviderService,
private _piwikService: PiwikService,
private route: ActivatedRoute,
@ -160,7 +184,9 @@ export class DataProviderComponent {
private helper: HelperService,
private _location: Location,
private indexInfoService: IndexInfoService,
private cdr: ChangeDetectorRef) {
private metricsService: MetricsService,
private cdr: ChangeDetectorRef,
private layoutService: LayoutService) {
this.fetchPublications = new FetchResearchResults(this._searchResearchResultsService);
this.fetchDatasets = new FetchResearchResults(this._searchResearchResultsService);
this.fetchSoftware = new FetchResearchResults(this._searchResearchResultsService);
@ -171,6 +197,9 @@ export class DataProviderComponent {
}
ngOnInit() {
this.subscriptions.push(this.layoutService.isMobile.subscribe(isMobile => {
this.isMobile = isMobile;
}));
if (typeof document !== 'undefined') {
this.subscriptions.push(this.indexInfoService.getLastIndexDate(this.properties).subscribe(lastIndexUpdate => {
if (lastIndexUpdate) {
@ -328,7 +357,8 @@ export class DataProviderComponent {
this.subscriptions.forEach(subscription => {
if (subscription instanceof Subscriber) {
subscription.unsubscribe();
} else if (subscription instanceof (ResizeObserver || IntersectionObserver)) {
} else if ((typeof ResizeObserver != 'undefined' && subscription instanceof ResizeObserver) ||
(typeof IntersectionObserver != 'undefined' && subscription instanceof IntersectionObserver)) {
subscription.disconnect();
}
});
@ -366,6 +396,7 @@ export class DataProviderComponent {
this.seoService.createLinkForCanonicalURL(this.properties.domain +this.properties.baseLink + this._router.url);
if (typeof document !== 'undefined') {
this.getDataProviderAggregationStatus(this.dataProviderInfo.originalId);
// this.getCollectedFulltexts();
this.countResultsWithFundingInfo();
} else {
this.aggregationStatusIsInitialized = true;
@ -381,6 +412,23 @@ export class DataProviderComponent {
}
this.showLoading = false;
this.hasViews = false;
this.hasDownloads = false;
// ensure that if the API call to index does not have metrics, we get them from old metrics service call
if(this.dataProviderInfo && !this.dataProviderInfo.measure) {
this.getMetrics();
} else if(this.dataProviderInfo && this.dataProviderInfo.measure && this.dataProviderInfo.measure.counts) {
this.dataProviderInfo.measure.counts.forEach(measure => {
if(measure.name == "views" && measure.value > 0) {
this.hasViews = true;
}
if(measure.name == "downloads" && measure.value > 0) {
this.hasDownloads = true;
}
});
}
this.cdr.detectChanges();
// if (this.dataProviderInfo.tabs != undefined && this.dataProviderInfo.tabs.length > 0) {
@ -423,6 +471,20 @@ export class DataProviderComponent {
));
}
// private getCollectedFulltexts() {
// this.subscriptions.push(this._dataproviderService.getCollectedFulltexts(this.datasourceId).subscribe(
// (data: string) => {
// this.dataProviderInfo.aggregationStatus = {"fulltexts": data};
// this.aggregationStatusIsInitialized = true;
// },
// err => {
// //console.log(err);
// this.aggregationStatusIsInitialized = true;
// this.handleError("Error getting "+this.getTypeName()+" collected fulltexts for id: " + this.datasourceId, err);
// }
// ));
// }
private countResultsWithFundingInfo() {
this.subscriptions.push(this._searchResearchResultsService.countCollectedResultsWithFundingInfo(this.datasourceId).subscribe(
fundedContent => {
@ -680,11 +742,33 @@ export class DataProviderComponent {
public metricsResults($event) {
this.totalViews = $event.totalViews;
this.totalDownloads = $event.totalDownloads;
this.pageViews = $event.pageViews;
// this.pageViews = $event.pageViews;
}
private getMetrics() {
let obs;
obs = zip(this.metricsService.getMetricsNumber(this.datasourceId, "usagestats.views.repository.local", this.properties),
this.metricsService.getMetricsNumber(this.datasourceId, "usagestats.downloads.repository.local", this.properties));
this.sub = obs.subscribe(data => {
if((data[0] && data[0] > 0) || (data[1] && data[1] > 0)) {
this.dataProviderInfo.measure = {counts: []};
if(data[0] && data[0] > 0) {
this.dataProviderInfo.measure.counts.push({name: 'views', order: 0, icon: 'visibility', value: data[0]});
this.hasViews = true;
}
if(data[1] && data[1] > 0) {
this.dataProviderInfo.measure.counts.push({name: 'downloads', order: 1, icon: 'downloads', value: data[1]});
this.hasDownloads = true;
}
this.cdr.detectChanges();
}
});
}
public get hasMetrics(): boolean {
return !(this.totalViews != null && this.totalDownloads != null && this.pageViews != null) || this.totalViews > 0 || this.totalDownloads > 0 || this.pageViews > 0;
// return !(this.totalViews != null && this.totalDownloads != null) || this.totalViews > 0 || this.totalDownloads > 0;
// return (this.totalViews != null && this.totalViews > 0) || (this.totalDownloads != null && this.totalDownloads > 0);
return this.dataProviderInfo.measure?.counts?.length > 0;
}
// public openStatistics() {
@ -715,7 +799,13 @@ export class DataProviderComponent {
if(this.dataProviderInfo.organizations.length <= this.thresholdOrganizations*2) {
this.lessBtnOrganizations = true;
} else {
this.openOrganizationsModal();
if(this.isMobile) {
this.summaryFsModal.title += " - Organizations";
this.summaryFsModal.back = true;
this.viewAllMobile = "organizations";
} else {
this.openOrganizationsModal();
}
}
}
@ -731,7 +821,13 @@ export class DataProviderComponent {
if(this.dataProviderInfo.subjects.length <= this.thresholdSubjects*2) {
this.lessBtnSubjects = true;
} else {
this.openSubjectsModal();
if(this.isMobile) {
this.summaryFsModal.title += " - Subjects";
this.summaryFsModal.back = true;
this.viewAllMobile = "subjects";
} else {
this.openSubjectsModal();
}
}
}
@ -795,7 +891,6 @@ export class DataProviderComponent {
// ((!!this.dataProviderInfo.aggregationStatus.fulltexts && parseInt(this.dataProviderInfo.aggregationStatus.fulltexts) != -1)
// || (!!this.dataProviderInfo.aggregationStatus.fundedContent && parseInt(this.dataProviderInfo.aggregationStatus.fundedContent) != -1)
// || !!this.dataProviderInfo.aggregationStatus.lastUpdateDate));
return (!!this.dataProviderInfo.aggregationStatus &&
((!!this.dataProviderInfo.aggregationStatus.fulltexts && parseInt(this.dataProviderInfo.aggregationStatus.fulltexts) != -1)));
}
@ -837,12 +932,56 @@ export class DataProviderComponent {
return StringUtils.getEntityName(this.type, false);
}
public viewAllDescriptionClicked() {
if(this.isMobile) {
this.summaryFsModal.title += " - Description";
this.summaryFsModal.back = true;
this.viewAllMobile = "description";
} else {
this.openDescriptionModal();
}
}
public openDescriptionModal() {
this.descriptionModal.alertFooter = false;
this.descriptionModal.alertTitle = "Description";
this.descriptionModal.open();
}
public clickedUsageMetrics() {
setTimeout( () => {
this.metricsClicked = true;
});
}
public formatNumber(num: number | string) {
let formatted = NumberUtils.roundNumber(+num);
return formatted.number + formatted.size;
}
public cancelSummaryClicked() {
this.summaryFsModal.title = "Summary";
this.summaryFsModal.back = false;
this.lessBtnOrganizations = false;
this.viewAllMobile = "";
}
public openFsModal(fsModal: FullScreenModalComponent, title: string) {
fsModal.title = title;
fsModal.okButton = false;
fsModal.stayOpenInBack = true;
fsModal.open();
this.tabMobile = title;
}
public getMetricsTooltip(value: string) {
if (value == 'downloads') {
return "<div class='uk-flex uk-flex-middle'><a href='https://usagecounts.openaire.eu/' target='_blank'><img src='assets/common-assets/logo-small-usage-counts.png' loading='lazy' alt='OpenAIRE UsageCounts'></a><span class='uk-text-uppercase uk-margin-small-left'>Downloads provided by <a href='https://usagecounts.openaire.eu/' target='_blank' class='uk-link-reset'><strong>UsageCounts</strong></a></div>";
} else if (value == 'views') {
return "<div class='uk-flex uk-flex-middle'><a href='https://usagecounts.openaire.eu/' target='_blank'><img class='uk-margin-small-right' src='assets/common-assets/logo-small-usage-counts.png' loading='lazy' alt='OpenAIRE UsageCounts'></a><span class='uk-text-uppercase uk-margin-small-left'>Views provided by <a href='https://usagecounts.openaire.eu/' target='_blank' class='uk-link-reset'><strong>UsageCounts</strong></a></div>";
}
}
public addEoscPrevInParams(obj) {
if(properties.adminToolsPortalType == "eosc" && this.prevPath) {
let splitted: string[] = this.prevPath.split("?");

View File

@ -34,6 +34,9 @@ import {IconsService} from "../../utils/icons/icons.service";
import {graph} from "../../utils/icons/icons";
import {LoadingModalModule} from "../../utils/modal/loadingModal.module";
import {ResultLandingUtilsModule} from "../landing-utils/resultLandingUtils.module";
import {FullScreenModalModule} from '../../utils/modal/full-screen-modal/full-screen-modal.module';
import {SafeHtmlPipeModule} from '../../utils/pipes/safeHTMLPipe.module';
import {EntityActionsModule} from "../../utils/entity-actions/entity-actions.module";
@NgModule({
imports:
@ -42,7 +45,8 @@ import {ResultLandingUtilsModule} from "../landing-utils/resultLandingUtils.modu
DataProvidersServiceModule, ProjectsServiceModule, SearchResearchResultsServiceModule,
PagingModule, Schema2jsonldModule, SEOServiceModule, ShowPublisherModule, HelperModule,
LandingHeaderModule, AlertModalModule, NoLoadPaging, FeedbackModule,
TabsModule, SearchTabModule, LoadingModule, IconsModule, LoadingModalModule, ResultLandingUtilsModule
TabsModule, SearchTabModule, LoadingModule, IconsModule, LoadingModalModule, ResultLandingUtilsModule,
FullScreenModalModule, SafeHtmlPipeModule, EntityActionsModule
],
declarations:
[StatisticsTabComponent,

View File

@ -83,6 +83,11 @@ export class DataProviderService {
.pipe(map(res => this.parseDataproviderAggregationStatus(res)));
}
// getCollectedFulltexts(datasourceId: string) {
// return this.http.get(properties.pdfStatisticsAPIURL+"/api/stats/getNumberOfPayloadsForDatasource?datasourceId="+datasourceId)
// .pipe(map(res => res))
// }
private handleError (error: HttpErrorResponse) {
// in a real world app, we may send the error to some remote logging infrastructure
// instead of just logging it to the console
@ -360,9 +365,12 @@ export class DataProviderService {
this.dataProviderInfo.journal['lissn'] = data[6]['lissn'];
this.dataProviderInfo.journal['eissn'] = data[6]['eissn'];
}else{
}else {
this.dataProviderInfo.journal = null;
this.dataProviderInfo.journal = {"journal": "", "issn": "", "lissn": "", "eissn": ""};
// this.dataProviderInfo.journal = {"journal": "", "issn": "", "lissn": "", "eissn": ""};
}
if (data[0]?.measure) {
this.dataProviderInfo.measure = this.parsingFunctions.parseMeasures(data[0].measure);
}
return this.dataProviderInfo;

View File

@ -1,59 +1,84 @@
import {
ChangeDetectorRef,
Component,
EventEmitter,
Inject,
Inject, Input,
OnInit,
Output,
RendererFactory2,
ViewChild,
ViewEncapsulation
} from '@angular/core';
import {ActivatedRoute} from '@angular/router';
import {DOCUMENT} from "@angular/common";
import {Subscriber} from "rxjs";
interface addthis {
layers: Refresh;
init: Function;
toolbox: Function;
}
interface Refresh {
refresh: Function;
}
declare var addthis: addthis;
declare var a2a;
@Component({
selector: 'addThis',
template: `
<div id="addThis" class="addthis_inline_share_toolbox_lcx9_8cfy"></div>
<div *ngIf="showWarning" class="uk-alert uk-alert-warning uk-animation-fade" >
Do the share buttons not appear? Please make sure, any blocking addon is disabled, and then reload the page.
</div>
<div [id]="'addToAny'+(url ? ('_'+url) : '')" #addToAny class="a2a_kit a2a_kit_size_42 a2a_default_style fully_rounded" [attr.data-a2a-url]="url">
<a class="a2a_button_twitter"></a>
<a class="a2a_button_facebook"></a>
<a class="a2a_button_linkedin"></a>
<a class="a2a_button_mendeley"></a>
<a class="a2a_button_reddit"></a>
<a class="a2a_button_email"></a>
<a class="a2a_dd" href="https://www.addtoany.com/share"></a>
</div>
<div *ngIf="showWarning" class="uk-alert uk-alert-warning uk-animation-fade">
Do the share buttons not appear? Please make sure, any blocking addon is disabled, and then reload the page.
</div>
`
})
export class AddThisComponent implements OnInit {
subs=[];
subs = [];
showWarning = false;
constructor(private route: ActivatedRoute, @Inject(DOCUMENT) private document, private rendererFactory: RendererFactory2) {}
@Input() url: string = null;
constructor(private route: ActivatedRoute, @Inject(DOCUMENT) private document, private rendererFactory: RendererFactory2) {
}
public ngOnDestroy() {
for(let value of this.subs){
for (let value of this.subs) {
if (value instanceof Subscriber) {
value.unsubscribe();
} else if (value instanceof Function) {
value();
}
}
//
// if(typeof document !== 'undefined') {
// const renderer = this.rendererFactory.createRenderer(this.document, {
// id: '-1',
// encapsulation: ViewEncapsulation.None,
// styles: [],
// data: {}
// });
// const head = this.document.body;
// if (head === null) {
// throw new Error('<head> not found within DOCUMENT.');
// }
//
//
// let script = null;
// head.childNodes.forEach(node => {
// if(node.id === "addToAnyScript") {
// // script = node;
// node.remove();
// }
// })
// // let script = head.nativeElement.getElementById("script");
// // if(script) {
// // renderer.removeChild(head, script);
// // script.remove();
// // }
// }
}
ngOnInit() {
this.subs.push(this.route.queryParams.subscribe(data => {
this.showWarning = false;
try {
if (!this.document.getElementById('addThisScript') && typeof document !== 'undefined') {
// console.log(" create script AddThis");
if (!this.document.getElementById('addToAnyScript') && typeof document !== 'undefined') {
const renderer = this.rendererFactory.createRenderer(this.document, {
id: '-1',
encapsulation: ViewEncapsulation.None,
@ -65,24 +90,23 @@ export class AddThisComponent implements OnInit {
throw new Error('<head> not found within DOCUMENT.');
}
const script = renderer.createElement('script');
renderer.setAttribute(script, "id", "addThisScript");
renderer.setAttribute(script, "src", "https://s7.addthis.com/js/300/addthis_widget.js#pubid=ra-559d24521cd8c080");
renderer.setAttribute(script, "id", "addToAnyScript");
renderer.setAttribute(script, "src", "https://static.addtoany.com/menu/page.js");
renderer.setAttribute(script, "type", "text/javascript");
renderer.appendChild(head, script);
}
if (typeof document !== 'undefined') {
if(typeof addthis !== 'undefined' && addthis.layers && addthis.layers.refresh) {
// console.log("Add This: Call Refresh")
addthis.layers.refresh();
if(typeof a2a !== 'undefined' && this.document.getElementById('addToAny'+(this.url ? ('_'+this.url) : '')) && !this.document.getElementById('addToAny'+(this.url ? ('_'+this.url) : '')).innerText) {
a2a.init_all();
}
}
this.subs.push(setTimeout(() => {
if(this.document.getElementById('addThis') && !this.document.getElementById('addThis').innerText){
if (this.document.getElementById('addToAny'+(this.url ? ('_'+this.url) : '')) && !this.document.getElementById('addToAny'+(this.url ? ('_'+this.url) : '')).innerText) {
this.showWarning = true;
}
}, 4000));
}catch (e) {
// console.error(e)
} catch (e) {
// console.error(e)
}
}));

View File

@ -1,31 +1,60 @@
import {Component, EventEmitter, Input, Output} from '@angular/core';
import {Component, ElementRef, EventEmitter, Input, Output, ViewChild} from '@angular/core';
import {HostedByCollectedFrom} from "../../utils/result-preview/result-preview";
import {properties} from "../../../../environments/environment";
import {StringUtils} from '../../utils/string-utils.class';
import {FullScreenModalComponent} from "../../utils/modal/full-screen-modal/full-screen-modal.component";
declare var UIkit;
import {RouterHelper} from "../../utils/routerHelper.class";
@Component({
selector: 'availableOn',
template: `
<div class="uk-margin-small-bottom uk-flex uk-flex-between">
<span *ngIf="viewAll && !lessBtn" class="clickable uk-h6 uk-flex uk-flex-middle" (click)="viewLessClick()">
<icon class="uk-margin-small-right" name="arrow_back" flex="true" ratio="1.2"></icon>
{{title}}
</span>
<span *ngIf="!viewAll || lessBtn" class="uk-margin-small-bottom uk-flex uk-flex-middle">
<span class="uk-text-light-grey uk-margin-small-right">Download from</span>
</span>
<a *ngIf="viewAll && lessBtn" (click)="viewAll = !viewAll; lessBtn=false;" class="view-more-less-link">View less</a>
<a *ngIf="availableOn && availableOn.length > threshold && !viewAll" class="view-more-less-link"
(click)="viewAllClick();">View all {{availableOn.length}} sources</a>
</div>
<ng-container *ngIf="availableOn && availableOn.length > 0">
<div class="uk-flex uk-flex-middle" [ngClass]="isMobile && !(usedBy == 'landing') ? 'uk-margin-left uk-margin-xsmall-bottom' : ''">
<ng-container *ngIf="availableOn[0].downloadUrl">
<span [class]="'uk-margin-xsmall-right ' + (availableOn[0].accessRightIcon == 'open_access' ? 'open-access' : 'closed-access')"
uk-tooltip [title]="getAccessLabel(availableOn[0].accessRight)">
<icon [name]="availableOn[0].accessRightIcon" [flex]="true" [ratio]="(isMobile && usedBy == 'landing') ? 1 : 0.8"></icon>
</span>
<ng-container *ngIf="!(isMobile && usedBy == 'landing')">
<a uk-tooltip="Source" target="_blank"
class="uk-flex uk-flex-middle uk-flex-center uk-button-link uk-text-bolder">
<span>{{sliceString(availableOn[0].downloadNames.join("; "), 20)}}</span>
<span>
<!-- <icon [flex]="true" [name]="'expand_' + (isOpen?'less':'more')"></icon>-->
<icon [flex]="true" [name]="(isOpen?'arrow_drop_up':'arrow_drop_down')"></icon>
</span>
</a>
<div #dropElement uk-drop="mode: click; pos: bottom-left;"
class="uk-drop download-drop uk-card uk-card-default uk-padding-small uk-padding-remove-horizontal uk-text-small uk-height-max-large uk-overflow-auto">
<ng-container *ngTemplateOutlet="availableOnList"></ng-container>
</div>
</ng-container>
<div *ngIf="availableOn" class="download-from uk-margin-small-bottom">
<div *ngFor="let instance of availableOn.slice(0, viewAll?availableOn.length:threshold) let i=index"
class="uk-flex uk-flex-top uk-padding-small uk-margin-small-bottom"
uk-tooltip [title]="instance.accessRight ? instance.accessRight : 'Not available'">
<span [class]="'uk-margin-small-right ' + (instance.accessRightIcon == 'lock_open' ? 'uk-text-success' : 'uk-text-meta')"
uk-tooltip [title]="instance.accessRight ? instance.accessRight : 'Not available'">
<icon [name]="instance.accessRightIcon" flex="true" type="outlined"></icon>
<ng-container *ngIf="(isMobile && usedBy == 'landing')">
<a class="uk-flex uk-flex-between uk-flex-middle uk-flex-center uk-width-expand uk-button-link" (click)="openAvailableListFsModal()">
<span uk-tooltip="Source">{{sliceString(availableOn[0].downloadNames.join("; "), 20)}}</span>
<span>
<icon [flex]="true" ratio="1.5" name="arrow_right"></icon>
</span>
</a>
<fs-modal #availableListFsModal classTitle="uk-tile-default uk-border-bottom">
<div class="uk-text-small download-drop">
<ng-container *ngTemplateOutlet="availableOnList"></ng-container>
</div>
</fs-modal>
</ng-container>
</ng-container>
</div>
</ng-container>
<ng-template #availableOnList>
<div *ngFor="let instance of availableOn let i=index" class="download-drop-item uk-flex uk-flex-top">
<span
[class]="'uk-margin-small-right ' + (instance.accessRightIcon == 'open_access' ? 'open-access' : 'closed-access')"
uk-tooltip [title]="getAccessLabel(instance.accessRight)">
<icon [name]="instance.accessRightIcon" [flex]="true"></icon>
</span>
<div class="uk-width-expand uk-padding-small uk-padding-remove-left uk-padding-remove-vertical">
<span class="uk-text-emphasis">
@ -56,36 +85,19 @@ import {RouterHelper} from "../../utils/routerHelper.class";
</div>
</div>
</div>
</div>
<!-- <div *ngIf="showNum > threshold" class="uk-margin-bottom">-->
<!-- <a (click)="showNum = threshold;" class="uk-flex uk-flex-middle uk-flex-center">-->
<!-- <span>View less</span>-->
<!-- <span class="space uk-icon">-->
<!-- <svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" data-svg="chevron-up">-->
<!-- <polyline fill="none" stroke="#000" stroke-width="1.03" points="4 13 10 7 16 13"></polyline>-->
<!-- </svg>-->
<!-- </span>-->
<!-- </a>-->
<!-- </div>-->
<!-- <div *ngIf="showNum == threshold && availableOn && availableOn.length > 5" class="uk-margin-bottom">-->
<!-- <a (click)="showNum = availableOn.length;" class="uk-flex uk-flex-middle uk-flex-center">-->
<!-- <span>View more</span>-->
<!-- <span class="space uk-icon">-->
<!-- <svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" data-svg="chevron-down">-->
<!-- <polyline fill="none" stroke="#000" stroke-width="1.03" points="16 7 10 13 4 7"></polyline>-->
<!-- </svg>-->
<!-- </span>-->
<!-- </a>-->
<!-- </div>-->
</ng-template>
`
})
export class AvailableOnComponent {
@Input() isMobile: boolean = false;
@Input() usedBy: "search" | "landing" = "search";
@Input() prevPath: string = "";
@Input() availableOn: HostedByCollectedFrom[];
@Input() viewAll: boolean = false;
@Output() viewAllClicked = new EventEmitter();
public lessBtn: boolean = false;
/** @deprecated */
@Output() viewAllClicked = new EventEmitter();
@ViewChild("dropElement") dropElement: ElementRef;
@ViewChild("availableListFsModal") availableListFsModal: FullScreenModalComponent;
public threshold: number = 1;
public dataProviderUrl = properties.searchLinkToDataProvider.split('?')[0];
public title: string = "Download from";
@ -94,38 +106,38 @@ export class AvailableOnComponent {
constructor() {
}
ngOnInit() {}
public removeUnknown(value: string): string {
if (value.toLowerCase() === 'unknown') {
return null;
}
return value;
ngOnInit() {
}
public getKeys( map) {
public getKeys(map) {
return Array.from(map.keys());
}
public viewAllClick() {
if(this.availableOn.length <= this.threshold*2) {
this.viewAll = true;
this.lessBtn = true;
} else {
this.viewAll = true;
this.viewAllClicked.emit('availableOn');
}
}
public viewLessClick() {
this.viewAll = false;
this.viewAllClicked.emit("");
}
public isUrl(str: string): boolean {
return str.startsWith('http://') || str.startsWith('https://') || str.startsWith('//') || str.startsWith('www.');
}
get isOpen() {
return (typeof document !== 'undefined') && this.dropElement && UIkit.drop(this.dropElement.nativeElement).isActive();
}
public sliceString(str: string, size: number) {
return StringUtils.sliceString(str, size)
}
public openAvailableListFsModal() {
this.availableListFsModal.title = "Sources";
this.availableListFsModal.okButton = false;
this.availableListFsModal.open();
}
public getAccessLabel(accessRight) : string {
if(accessRight) {
return (accessRight + (accessRight.toLowerCase().endsWith(" access") ? "" : " access"));
}
return "Not available access";
}
public addEoscPrevInParams(obj) {
if(properties.adminToolsPortalType == "eosc" && this.prevPath) {
let splitted: string[] = this.prevPath.split("?");

View File

@ -13,6 +13,7 @@ import {DOCUMENT} from "@angular/common";
import {EnvProperties} from "../../../utils/properties/env-properties";
import {properties} from "../../../../../environments/environment";
import {PiwikService} from "../../../utils/piwik/piwik.service";
import {ResultPreview} from "../../../utils/result-preview/result-preview";
declare var Cite: any;
// Based on https://citation.js.org/api/tutorial-getting_started.html browser release
@ -53,7 +54,7 @@ export class CiteThisComponent implements OnInit, OnDestroy {
properties:EnvProperties;
public citationText: string;
public citation: Citation = new Citation();
@Input() result: ResultLandingInfo;
@Input() result: any;
@Input() id: string;
@Input() type: string = "article";
@Input() piwikSiteId;
@ -256,7 +257,7 @@ export class CiteThisComponent implements OnInit, OnDestroy {
/**
* Based on this and citeproc library https://citation.js.org/api/tutorial-plugins.html
* if the template doesn;t exist add the CSL xml and the library will produce the citation
* if the template doesn't exist add the CSL xml and the library will produce the citation
* @param template
*/

View File

@ -0,0 +1,11 @@
@import (reference) "~src/assets/openaire-theme/less/_import-variables";
.entity-metadata {
& > *:not(:last-child):not(.other-separator)::after {
content: "\2022";
font-weight: normal;
margin-left: @global-xsmall-margin;
margin-right: @global-xsmall-margin;
}
}

View File

@ -0,0 +1,263 @@
import {Component, Input} from "@angular/core";
import {EnvProperties} from "../../utils/properties/env-properties";
import {properties} from "../../../../environments/environment";
import {OpenaireEntities} from "../../utils/properties/searchFields";
import {Organization, Project} from "../../utils/result-preview/result-preview";
import {RouterHelper} from "../../utils/routerHelper.class";
@Component({
selector: 'entity-metadata',
template: `
<div class="uk-text-xsmall entity-metadata uk-flex-inline uk-flex-wrap uk-text-emphasis">
<!-- oa -->
<span class="uk-flex-inline uk-flex-middle uk-flex-wrap"
*ngIf="(openAccessMandatePublications != undefined && openAccessMandatePublications) || (openAccessMandateDatasets != undefined && openAccessMandateDatasets)">
<span class="uk-margin-xsmall-right open-access">
<icon name="open_access" [flex]="true" [ratio]="0.8"></icon>
</span>
<span class="uk-text-bolder"
*ngIf="openAccessMandatePublications != undefined && openAccessMandatePublications && openAccessMandateDatasets != undefined && openAccessMandateDatasets">
Open Access Mandate for {{openaireEntities.PUBLICATIONS}} and {{openaireEntities.DATASETS}}
</span>
<span class="uk-text-bolder"
*ngIf="openAccessMandatePublications != undefined && openAccessMandatePublications && (openAccessMandateDatasets == undefined || !openAccessMandateDatasets)">
Open Access Mandate for {{openaireEntities.PUBLICATIONS}}
</span>
<span class="uk-text-bolder"
*ngIf="openAccessMandateDatasets != undefined && openAccessMandateDatasets && (openAccessMandatePublications == undefined || !openAccessMandatePublications)">
Open Access Mandate for {{openaireEntities.DATASETS}}
</span>
</span>
<!-- types -->
<span *ngIf="entityType" class="uk-flex-inline uk-flex-middle uk-flex-wrap"
[class.other-separator]="types && removeUnknown(types, true).length > 0">
<span class="uk-margin-xsmall-right">
<icon *ngIf="entityType.toLowerCase() == 'publication'" name="description" type="outlined"
[flex]="true" [ratio]="0.8"></icon>
<icon *ngIf="entityType.toLowerCase() == 'research data'" name="database" type="outlined"
[flex]="true" [ratio]="0.8"></icon>
<icon *ngIf="entityType.toLowerCase() == 'research software'" name="integration_instructions"
type="outlined" [flex]="true" [ratio]="0.8"></icon>
<icon *ngIf="entityType.toLowerCase() == 'other research product'" name="apps" type="outlined"
[flex]="true" [ratio]="0.8"></icon>
<icon *ngIf="entityType.toLowerCase() == 'project'" name="assignment_turned_in" type="outlined"
[flex]="true" [ratio]="0.8"></icon>
<icon *ngIf="entityType.toLowerCase() == 'data source'" name="note_add" type="outlined"
[flex]="true" [ratio]="0.8"></icon>
<icon *ngIf="entityType.toLowerCase() == 'organization'" name="corporate_fare" type="outlined"
[flex]="true" [ratio]="0.8"></icon>
</span>
<u class="uk-text-capitalize uk-text-bolder">{{entityType}}</u>
<span *ngIf="types && removeUnknown(types, true).length > 0">
<icon name="keyboard_double_arrow_right" [flex]="true" [ratio]="0.8"></icon>
</span>
</span>
<span *ngIf="types && removeUnknown(types, true).length > 0" class="uk-text-italic">
{{removeUnknown(types, true).join(' , ')}}
</span>
<!-- years -->
<ng-container *ngIf="year">
<span>{{year}}</span>
</ng-container>
<ng-container *ngIf="startYear && !endYear">
<span>{{startYear}}</span>
</ng-container>
<ng-container *ngIf="!startYear && endYear">
<span>{{endYear}}</span>
</ng-container>
<ng-container *ngIf="startYear && endYear">
<ng-container>
<span>{{startYear}} - {{endYear}}</span>
</ng-container>
</ng-container>
<!-- dates -->
<span *ngIf="startDate && !endDate">
<span class="uk-margin-xsmall-right">From</span>
<span>{{startDate | date: 'dd MMM yyyy'}}</span>
</span>
<span *ngIf="!startDate && endDate">
<span class="uk-margin-xsmall-right">Until</span>
<span>{{endDate | date: 'dd MMM yyyy'}}</span>
</span>
<span *ngIf="startDate && endDate">
<ng-container *ngIf="startDate">
<span>{{startDate | date: 'dd MMM yyyy'}}</span>
<span class="uk-margin-xsmall-left">(Started)</span>
</ng-container>
<span *ngIf="startDate && endDate" class="uk-margin-xsmall-left uk-margin-xsmall-right">-</span>
<ng-container *ngIf="endDate">
<span>{{endDate | date: 'dd MMM yyyy'}}</span>
<span class="uk-margin-xsmall-left">{{currentDate >= endDate ? '(Ended)' : '(Ending)'}}</span>
</ng-container>
</span>
<ng-container *ngIf="status">
<span>{{status}}</span>
</ng-container>
<ng-container *ngIf="date">
<span>{{date | date: 'dd MMM yyyy': 'UTC'}}</span>
</ng-container>
<ng-container *ngIf="embargoEndDate">
<span>Embargo end date: {{embargoEndDate | date: 'dd MMM yyyy'}}</span>
</ng-container>
<span *ngIf="underCuration">
<span title="{{buildCurationTooltip()}}" uk-tooltip="pos:bottom-right; delay:10;"
class="uk-text-primary">Under curation</span>
</span>
<!-- countries -->
<span *ngIf="countries && removeUnknown(countries).length > 0">
{{removeUnknown(countries).join(', ')}}
</span>
<!-- languages -->
<span *ngIf="languages && removeUnknown(languages).length > 0">
{{removeUnknown(languages).join(', ')}}
</span>
<!-- programming languages -->
<span *ngIf="programmingLanguages && removeUnknown(programmingLanguages).length > 0"
class="uk-flex uk-flex-middle uk-flex-wrap">
{{removeUnknown(programmingLanguages).join(', ')}}
</span>
<!-- published info -->
<showPublisher *ngIf="publisher || journal" [publisher]="publisher" [journal]="journal"
[properties]="properties"></showPublisher>
<!-- data provider labels -->
<ng-container *ngIf="compatibility && !(compatibility.info == 'not available' && type == 'service')">
<span uk-tooltip title="Compatibility">
<a *ngIf="compatibility.id"
[queryParams]="addEoscPrevInParams({datasourceId: compatibility.id})" routerLinkActive="router-link-active"
[routerLink]="properties.searchLinkToDataProvider.split('?')[0]">
{{compatibility.info}}
<ng-container *ngIf="compatibility.name">{{compatibility.name}}</ng-container>
</a>
<span *ngIf="!compatibility.id && compatibility.info">
<ng-container
*ngIf="compatibility.info.toLowerCase() != 'not yet registered'">{{compatibility.info}}</ng-container>
<ng-container *ngIf="compatibility.info.toLowerCase() == 'not yet registered'">
{{compatibility.info}} <span *ngIf="properties.adminToolsPortalType == 'eosc'">in OpenAIRE</span>
</ng-container>
</span>
<span *ngIf="compatibility.name && !compatibility.id">
{{compatibility.name}}
</span>
</span>
</ng-container>
<ng-container *ngIf="compatibilityString">
<span uk-tooltip title="Compatibility">{{compatibilityString}}</span>
</ng-container>
<ng-container
*ngIf="aggregationStatus && aggregationStatus.fulltexts && aggregationStatus.fulltexts > 0">
<span>OpenAIRE Text Mining</span>
</ng-container>
<ng-container *ngIf="thematic">
<span>Thematic</span>
</ng-container>
<!-- Projects -->
<span uk-tooltip="Projects" *ngIf="projects && projects.length > 0" [class.truncated]="projects.length > 3">
{{projectNames.slice(0,3).join(', ')}}
</span>
<!-- Organizations -->
<span uk-tooltip="Partners" *ngIf="organizations && organizations.length > 0" [class.truncated]="organizations.length > 3">
{{organizationNames.slice(0, 3).join(', ')}}
</span>
<!-- Subjects -->
<span uk-tooltip="Subjects" *ngIf="subjects && subjects.length > 0" [class.truncated]="subjects.length > 3">
{{subjects.slice(0, 3).join(', ')}}
</span>
<ng-container *ngIf="provenanceAction">
<span>{{provenanceAction}}</span>
</ng-container>
<ng-container *ngIf="relationName">
<span>{{relationName}}</span>
</ng-container>
</div>
`,
styleUrls: ['entity-metadata.component.less']
})
export class EntityMetadataComponent {
@Input() entityType: string;
@Input() types: string[];
@Input() year: string; // search result
@Input() startDate: number; // project landing
@Input() startYear: string; // search result
@Input() endDate: number; // project landing
@Input() endYear: string; // search result
@Input() currentDate: number; // project landing
@Input() status: string; // project landing
@Input() openAccessMandatePublications: boolean // project landing
@Input() openAccessMandateDatasets: boolean // project landing
@Input() date: Date;
@Input() embargoEndDate: Date | string;
@Input() underCuration: boolean = false;
@Input() publisher; // showPublisher component
@Input() journal; // showPublisher component
@Input() countries;
@Input() languages;
@Input() programmingLanguages;
@Input() compatibilityString: string;
@Input() compatibility; // data provider landing
@Input() aggregationStatus; // data provider landing
@Input() thematic: boolean; // data provider landing
@Input() type; // data provider landing
@Input() provenanceAction: string; // search result
@Input() relationName: string; // search result
@Input() projects: Project[];
@Input() organizations: Organization[];
@Input() subjects: string[];
@Input() prevPath: string = "";
properties: EnvProperties = properties;
public openaireEntities = OpenaireEntities;
public routerHelper: RouterHelper = new RouterHelper();
public removeUnknown(array: string[], type: boolean = false): string[] {
if (type) {
return this.removeDuplicates(array).filter(value => value.toLowerCase() !== 'unknown');
} else {
return array.filter(value => value.toLowerCase() !== 'unknown');
}
}
public removeDuplicates(array: string[]): string[] {
return array.filter(value => value.toLowerCase() !== this.entityType);
}
public buildCurationTooltip(): string {
let tooltipContent: string = "<div class='uk-padding-small'>";
tooltipContent += "<h5>Record in preview</h5>";
tooltipContent += "<p>Bibliographic record accepted by the system, but not yet processed by <br> OpenAIRE tools for information quality improvement and de-duplication</p>";
tooltipContent += "</div>";
return tooltipContent;
}
get projectNames(): string[] {
if (this.projects && this.projects.length > 0) {
return this.projects.map(project => {
let value = project.funderShortname ? project.funderShortname : project.funderName;
if (project.acronym || project.title) {
value = value + ' | ' + (project.acronym ? project.acronym :
(project.title.length > 25 ? (project.title.slice(0, 25) + '...'): project.title));
}
if(project.code) {
value = value + ' (' + project.code + ')';
}
return value;
});
}
return [];
}
get organizationNames(): string[] {
if (this.organizations && this.organizations.length > 0) {
return this.organizations.map(organization => organization.name);
}
return [];
}
public addEoscPrevInParams(obj) {
if(properties.adminToolsPortalType == "eosc" && this.prevPath) {
return this.routerHelper.addQueryParam("pv", this.prevPath, obj);
}
return obj;
}
}

View File

@ -6,45 +6,75 @@ import {StringUtils} from "../../utils/string-utils.class";
@Component({
selector: 'fos',
template: `
<div class="uk-text-xsmall" style="color: #EEB204">Beta</div>
<div [class]="'uk-flex uk-flex-between uk-flex-middle uk-margin-'+(viewAll?'':'small-')+'bottom'">
<span *ngIf="viewAll" class="clickable uk-h6 uk-flex uk-flex-middle uk-margin-small-right uk-margin-remove-bottom" (click)="viewLessClick()">
<icon class="uk-margin-small-right" name="arrow_back" flex="true" ratio="1.2"></icon>
<span class="uk-text-nowrap">{{title}}</span>
</span>
<span *ngIf="!viewAll" class="uk-text-light-grey uk-text-nowrap uk-margin-small-right">{{title}}</span>
<!-- <a *ngIf="viewAll && lessBtn" (click)="viewAll = !viewAll; lessBtn=false;">View less</a>-->
<a *ngIf="properties.adminToolsPortalType == 'eosc' && subjects && subjects.length > threshold && !viewAll"
(click)="viewAllClick();" class="view-more-less-link uk-text-truncate" uk-tooltip="View all">
<span class="">View all</span>
</a>
<a *ngIf="properties.adminToolsPortalType !== 'eosc' && subjects && subjects.length > threshold && !viewAll"
(click)="viewAllClick();" class="view-more-less-link uk-text-truncate" uk-tooltip="View all & feedback">
<span class="">View all & feedback</span>
</a>
<a *ngIf="properties.adminToolsPortalType !== 'eosc' && (subjects && subjects.length <= threshold || viewAll)" class="uk-link uk-text-truncate"
(click)="feedbackClick();">Feedback</a>
</div>
<div class="uk-margin-small-top">
<div *ngFor="let subject of subjects.slice(0, viewAll?subjects.length:threshold); let i=index" class="uk-text-truncate">
<a *ngIf="properties.adminToolsPortalType !== 'eosc'"
[routerLink]="properties.searchLinkToResults" [queryParams]="{'fos': urlEncodeAndQuote(subject)}">
{{subject}}
<div class="uk-visible@m">
<div class="uk-text-xsmall" style="color: #EEB204">Beta</div>
<div [class]="'uk-flex uk-flex-between uk-flex-middle uk-margin-'+(viewAll?'':'small-')+'bottom'">
<span *ngIf="viewAll" class="clickable uk-h6 uk-flex uk-flex-middle uk-margin-small-right uk-margin-remove-bottom" (click)="viewLessClick()">
<icon class="uk-margin-small-right" name="arrow_back" [flex]="true" [ratio]="1.2"></icon>
<span class="uk-text-nowrap">{{title}}</span>
</span>
<span *ngIf="!viewAll" class="uk-text-emphasis uk-text-bolder uk-text-nowrap uk-margin-small-right">
{{title}}
<span *ngIf="subjects && subjects.length > threshold && !viewAll">({{subjects.length}})</span>
</span>
<a *ngIf="properties.adminToolsPortalType == 'eosc' && subjects && subjects.length > threshold && !viewAll"
(click)="viewAllClick();" class="view-more-less-link uk-link uk-link-text uk-text-truncate">
View all
</a>
<a *ngIf="properties.adminToolsPortalType == 'eosc'" class="custom-external" target="_blank"
[href]="'https://explore.openaire.eu'+properties.searchLinkToResults+'?fos='+urlEncodeAndQuote(subject)">
{{subject}}
<!-- <a *ngIf="viewAll && lessBtn" (click)="viewAll = !viewAll; lessBtn=false;">View less</a> -->
<a *ngIf="properties.adminToolsPortalType != 'eosc' && subjects && subjects.length > threshold && !viewAll"
(click)="viewAllClick();" class="view-more-less-link uk-link uk-link-text uk-text-truncate">
View all & suggest
</a>
<a *ngIf="properties.adminToolsPortalType != 'eosc' && (subjects && subjects.length <= threshold || viewAll)" class="uk-link uk-link-text uk-text-truncate"
(click)="suggestClick();">Suggest</a>
</div>
<div class="uk-margin-small-top">
<div *ngFor="let subject of subjects.slice(0, viewAll?subjects.length:threshold); let i=index" class="uk-text-truncate">
<a [routerLink]="properties.searchLinkToResults"
[queryParams]="{'fos': urlEncodeAndQuote(subject.id)}">
{{subject.label}}
</a>
</div>
</div>
</div>
<div class="uk-hidden@m">
<div class="uk-grid uk-grid-small uk-grid-divider" uk-grid>
<div class="uk-width-1-4 uk-text-meta">
<div class="uk-text-xsmall" style="color: #EEB204">Beta</div>
{{title}}
</div>
<div class="uk-width-expand">
<div *ngFor="let subject of subjects.slice(0, viewAll?subjects.length:threshold); let i=index" class="uk-text-truncate">
<a *ngIf="properties.adminToolsPortalType != 'eosc'"
[routerLink]="properties.searchLinkToResults" [queryParams]="{'fos': urlEncodeAndQuote(subject.id)}">
{{subject.label}}
</a>
<a *ngIf="properties.adminToolsPortalType == 'eosc'" class="custom-external" target="_blank"
[href]="'https://explore.openaire.eu'+properties.searchLinkToResults+'?fos='+urlEncodeAndQuote(subject.id)">
{{subject.label}}
</a>
</div>
</div>
</div>
<div class="uk-text-right uk-margin-small-top">
<a *ngIf="subjects && subjects.length > threshold && !viewAll"
(click)="viewAllClick();" class="view-more-less-link uk-text-truncate">
<span class="">View all</span>
<!-- <span class="">View all & suggest</span>-->
</a>
<!-- <a *ngIf="(subjects && subjects.length <= threshold || viewAll)" class="uk-link uk-text-truncate"-->
<!-- (click)="feedbackClick();">Feedback</a>-->
</div>
</div>
</div>
`
})
export class FosComponent {
@Input() subjects: string[];
@Input() subjects: {"id": string, "label": string}[];
@Input() viewAll: boolean = false;
@Output() viewAllClicked = new EventEmitter();
@Output() feedbackClicked = new EventEmitter();
@Output() suggestClicked = new EventEmitter();
public lessBtn: boolean = false;
public threshold: number = 2;
public routerHelper: RouterHelper = new RouterHelper();
@ -66,8 +96,8 @@ export class FosComponent {
this.viewAllClicked.emit("");
}
public feedbackClick() {
this.feedbackClicked.emit("");
public suggestClick() {
this.suggestClicked.emit('fos');
}
public urlEncodeAndQuote(str: string): string {

View File

@ -7,72 +7,94 @@ import {RouterHelper} from "../../utils/routerHelper.class";
@Component({
selector: 'fundedBy',
template: `
<div class="uk-margin-small-bottom uk-flex uk-flex-between">
<div *ngIf="!isMobile" class="uk-margin-small-bottom uk-flex uk-flex-between">
<span *ngIf="viewAll && !lessBtn" class="clickable uk-h6 uk-flex uk-flex-middle" (click)="viewLessClick()">
<icon class="uk-margin-small-right" name="arrow_back" flex="true" ratio="1.2"></icon>
{{title}}
</span>
<span *ngIf="!viewAll || lessBtn" class="uk-text-light-grey">{{title}}</span>
<a *ngIf="viewAll && lessBtn" (click)="viewAll = !viewAll; lessBtn=false;" class="view-more-less-link">View less</a>
<span *ngIf="!viewAll || lessBtn" class="uk-text-emphasis uk-text-bolder">{{title}}</span>
<a *ngIf="viewAll && lessBtn" (click)="viewAll = !viewAll; lessBtn=false;"
class="view-more-less-link uk-link-text">View less</a>
<a *ngIf="fundedByProjects && fundedByProjects.length > threshold && !viewAll"
(click)="viewAllClick();" class="view-more-less-link">View all</a>
(click)="viewAllClick();" class="view-more-less-link uk-link-text">View all</a>
</div>
<div>
<div *ngIf="!isMobile">
<span *ngFor="let item of fundedByProjects.slice(0, viewAll?fundedByProjects.length:threshold) let i=index">
<span class="uk-text-emphasis">
<a class="uk-link uk-link-text">
<span
*ngIf="item['funderShortname'] || item['funderName']">{{item['funderShortname'] ? item['funderShortname'] : item['funderName']}}</span>
<span *ngIf="!item['funderShortname'] && !item['funderName']">[no funder available]</span>
<span
*ngIf="item['acronym'] || item['title']">| {{ item['acronym'] ? item['acronym'] : item['title']}}</span>
</a>
</span>
<div class="default-dropdown uk-margin-remove-top uk-dropdown"
uk-dropdown="pos: bottom-left; mode:click">
<div class="uk-padding-small">
<span>Project</span>
<div class="uk-margin-bottom">
<a *ngIf="item.id" class="uk-h6 uk-margin-remove portal-link"
[queryParams]="addEoscPrevInParams({projectId: item.id})" [routerLink]="url">
{{item['acronym'] ? item['acronym'] : item['title']}}
</a>
<span *ngIf="!item.id" class="uk-h6 uk-margin-remove">
<span class="uk-text-emphasis">
<a class="uk-link uk-link-text">
<ng-container *ngTemplateOutlet="funder; context: {item: item}"></ng-container>
</a>
</span>
<div class="default-dropdown uk-margin-remove-top uk-dropdown"
uk-dropdown="pos: bottom-left; mode:click">
<ng-container *ngTemplateOutlet="dropInfo; context: { item: item}"></ng-container>
</div>
<span *ngIf="i < (fundedByProjects.slice(0, viewAll?fundedByProjects.length:threshold).length - 1)">, </span>
</span>
</div>
<div *ngIf="isMobile">
<div *ngFor="let item of fundedByProjects.slice(0, viewAll?fundedByProjects.length:threshold) let i=index"
class="uk-flex uk-flex-between uk-flex-middle uk-margin-small-bottom">
<span class="uk-text-emphasis">
<ng-container *ngTemplateOutlet="funder; context: {item: item}"></ng-container>
</span>
<icon name="info" visuallyHidden="info" [type]="'outlined'" class="uk-link"></icon>
<div class="default-dropdown uk-margin-remove-top uk-dropdown"
uk-dropdown="pos: bottom-left; mode:click">
<ng-container *ngTemplateOutlet="dropInfo; context: { item: item}"></ng-container>
</div>
</div>
</div>
<ng-template #funder let-item=item>
<span
*ngIf="item['funderShortname'] || item['funderName']">{{item['funderShortname'] ? item['funderShortname'] : item['funderName']}}</span>
<span *ngIf="!item['funderShortname'] && !item['funderName']">[no funder available]</span>
<span *ngIf="item['acronym'] || item['title']">| {{ item['acronym'] ? item['acronym'] : item['title']}}</span>
</ng-template>
<ng-template #dropInfo let-item=item>
<div class="uk-padding-small">
<span>Project</span>
<div class="uk-margin-bottom">
<a *ngIf="item.id" class="uk-h6 uk-margin-remove portal-link"
[queryParams]="addEoscPrevInParams({projectId: item.id})" [routerLink]="url">
{{item['acronym'] ? item['acronym'] : item['title']}}
</a>
<span *ngIf="!item.id" class="uk-h6 uk-margin-remove">
{{item['acronym'] ? item['acronym'] : item['title']}}
</span>
<div *ngIf="item.acronym && item.title" class="uk-text-meta">
{{item.title}}
</div>
</div>
<ul class="uk-list uk-padding-remove-left uk-margin-bottom">
<li *ngIf="item.funderShortname || item.funderName">
<span class="uk-text-meta">Funder: </span>
{{item.funderName ? item.funderName : item.funderShortname}}
<span *ngIf="item.funderShortname && item.funderName">
<div *ngIf="item.acronym && item.title" class="uk-text-meta">
{{item.title}}
</div>
</div>
<ul class="uk-list uk-padding-remove-left uk-margin-bottom">
<li *ngIf="item.funderShortname || item.funderName">
<span class="uk-text-meta">Funder: </span>
{{item.funderName ? item.funderName : item.funderShortname}}
<span *ngIf="item.funderShortname && item.funderName">
({{item.funderShortname}})
</span>
</li>
<li *ngIf="item.code">
<span class="uk-text-meta">Project Code: </span>{{item.code}}
</li>
<li *ngIf="item.funding">
<span class="uk-text-meta">Funding stream: </span>{{item.funding}}
</li>
</ul>
<div *ngIf="getVocabularyLabel(item, provenanceActionVocabulary, i) || item.validated" class="uk-text-meta">
<span *ngIf="item.validated">Validated by funder</span>
<span *ngIf="item.provenanceAction && item.validated"> | </span>
<span *ngIf="item.provenanceAction">{{item.provenanceAction}}</span>
</div>
</div>
</div>
<span *ngIf="i < (fundedByProjects.slice(0, viewAll?fundedByProjects.length:threshold).length - 1)">, </span>
</span>
</div>
</li>
<li *ngIf="item.code">
<span class="uk-text-meta">Project Code: </span>{{item.code}}
</li>
<li *ngIf="item.funding">
<span class="uk-text-meta">Funding stream: </span>{{item.funding}}
</li>
</ul>
<div *ngIf="getVocabularyLabel(item, provenanceActionVocabulary, i) || item.validated" class="uk-text-meta">
<span *ngIf="item.validated">Validated by funder</span>
<span *ngIf="item.provenanceAction && item.validated"> | </span>
<span *ngIf="item.provenanceAction">{{item.provenanceAction}}</span>
</div>
</div>
</ng-template>
`
})
export class FundedByComponent {
@Input() isMobile: boolean = false;
@Input() prevPath: string = "";
@Input() fundedByProjects: Project[];
@Input() viewAll: boolean = false;

View File

@ -4,100 +4,61 @@ import {Author} from "../../../utils/result-preview/result-preview";
import {AlertModal} from "../../../utils/modal/alert";
@Component({
selector: 'landing-header',
template: `
<div class="title-section" [class.uk-margin-bottom]="!isSticky" [ngClass]="titleClass">
<div class="uk-text-small">
<span *ngIf="entityType" class="uk-text-capitalize uk-text-small">
{{entityType}}
</span>
<span *ngIf="types && removeUnknown(types, true).length > 0">
{{(entityType?' . ':'') + removeUnknown(types, true).join(' . ')}}
</span>
<span>
<span *ngIf="startDate || endDate">
{{' . '}}
</span>
<span *ngIf="startDate && !endDate">
{{'from '}}
</span>
<span *ngIf="!startDate && endDate">
{{'until '}}
</span>
<span *ngIf="startDate">
{{startDate | date: 'yyyy'}}
</span>
<span *ngIf="startDate && endDate">
{{' - '}}
</span>
<span *ngIf="endDate">
{{endDate | date: 'yyyy'}}
</span>
</span>
<span *ngIf="status && status != ''">
{{' . ' + status}}
</span>
<span *ngIf="year && year != ''">
{{' . ' + year}}
</span>
<span *ngIf="embargoEndDate">
. Embargo end date: {{embargoEndDate | date: 'dd MMM yyyy'}}
</span>
<span *ngIf="underCuration">
. <span title="{{buildCurationTooltip()}}"
uk-tooltip="pos:bottom-right; delay:10;"
class="uk-text-primary">Under curation</span>
</span>
</div>
<div [class]="isSticky ? 'uk-margin-bottom' : 'uk-margin-medium-bottom'">
<showTitle [titleName]="title" classNames="uk-margin-remove-bottom"></showTitle>
<div *ngIf="subTitle">
<span class="uk-text-meta uk-text-small" [innerHTML]="subTitle"></span>
</div>
</div>
<div *ngIf="authors">
<showAuthors [authorsLimit]="authorLimit" [modal]="modal" [showAll]="showAllAuthors" [authors]="authors" [isSticky]="isSticky"></showAuthors>
</div>
</div>`
selector: 'landing-header',
template: `
<div class="title-section" [class.uk-margin-small-bottom]="!isSticky" [ngClass]="titleClass">
<div class="uk-margin-small-bottom">
<showTitle [isSticky]=isSticky [titleName]="title" classNames="uk-margin-remove-bottom"></showTitle>
<div *ngIf="subTitle && !isSticky">
<span class="uk-text-meta uk-text-small" [innerHTML]="subTitle"></span>
</div>
</div>
<div *ngIf="!isSticky" class="uk-margin-bottom">
<entity-metadata [entityType]="entityType" [types]="types" [startDate]="startDate" [endDate]="endDate"
[currentDate]="currentDate" [status]="status" [openAccessMandatePublications]="openAccessMandatePublications"
[openAccessMandateDatasets]="openAccessMandateDatasets" [date]="date" [embargoEndDate]="embargoEndDate"
[underCuration]="underCuration" [publisher]="publisher" [journal]="journal"
[languages]="languages" [programmingLanguages]="programmingLanguages"
[compatibility]="compatibility" [aggregationStatus]="aggregationStatus"
[thematic]="thematic" [type]="type" [prevPath]="prevPath"
></entity-metadata>
</div>
<div *ngIf="authors">
<showAuthors [authorsLimit]="authorLimit" [modal]="modal" [showAll]="showAllAuthors" [authors]="authors"
[isSticky]="isSticky" [isMobile]="isMobile"></showAuthors>
</div>
</div>
`
})
export class LandingHeaderComponent {
@Input() entityType: string;
@Input() properties: EnvProperties;
@Input() types: string[];
@Input() startDate: number; // project landing
@Input() endDate: number; // project landing
@Input() status: string; // project landing
@Input() year: string;
@Input() embargoEndDate: Date;
@Input() title: string;
@Input() subTitle: string;
@Input() authors: Author[];
@Input() authorLimit: number = 7;
@Input() showAllAuthors: boolean = true;
@Input() underCuration: boolean = false;
@Input() modal: AlertModal;
@Input() titleClass: string = null;
@Input() isTitleH1:boolean =true;
@Input() isSticky: boolean = false;
public removeUnknown(array: string[], type: boolean = false): string[] {
if (type) {
return this.removeDuplicates(array).filter(value => value.toLowerCase() !== 'unknown');
} else {
return array.filter(value => value.toLowerCase() !== 'unknown');
}
}
public removeDuplicates(array: string[]): string[] {
return array.filter(value => value.toLowerCase() !== this.entityType);
}
public buildCurationTooltip(): string {
let tooltipContent: string = "<div class='uk-padding-small'>";
tooltipContent += "<h5>Record in preview</h5>";
tooltipContent += "<p>Bibliographic record accepted by the system, but not yet processed by <br> OpenAIRE tools for information quality improvement and de-duplication</p>";
tooltipContent += "</div>";
return tooltipContent;
}
@Input() isMobile: boolean = false;
@Input() entityType: string;
@Input() properties: EnvProperties;
@Input() types: string[];
@Input() startDate: number; // project landing
@Input() endDate: number; // project landing
@Input() currentDate: number; // project landing
@Input() status: string; // project landing
@Input() openAccessMandatePublications: boolean // project landing
@Input() openAccessMandateDatasets: boolean // project landing
@Input() date: Date;
@Input() embargoEndDate: Date;
@Input() title: string;
@Input() subTitle: string;
@Input() authors: Author[];
@Input() authorLimit: number = 7;
@Input() showAllAuthors: boolean = true;
@Input() underCuration: boolean = false;
@Input() modal: AlertModal;
@Input() titleClass: string = null;
@Input() isSticky: boolean = false;
@Input() publisher; // showPublisher component
@Input() journal; // showPublisher component
@Input() languages;
@Input() programmingLanguages;
@Input() compatibility; // data provider landing
@Input() aggregationStatus; // data provider landing
@Input() thematic: boolean; // data provider landing
@Input() type; // data provider landing
@Input() prevPath: string = "";
}

View File

@ -3,9 +3,13 @@ import {LandingHeaderComponent} from "./landing-header.component";
import {CommonModule} from "@angular/common";
import {LandingModule} from "../landing.module";
import {ShowAuthorsModule} from "../../../utils/authors/showAuthors.module";
import {IconsModule} from "src/app/openaireLibrary/utils/icons/icons.module";
import {ShowPublisherModule} from "../showPublisher.module";
import {RouterModule} from "@angular/router";
import {ResultLandingUtilsModule} from "../resultLandingUtils.module";
@NgModule({
imports: [CommonModule, LandingModule, ShowAuthorsModule],
imports: [CommonModule, LandingModule, ShowAuthorsModule, IconsModule, ShowPublisherModule, RouterModule, ResultLandingUtilsModule],
declarations: [LandingHeaderComponent],
exports: [LandingHeaderComponent]
})

View File

@ -1,5 +1,5 @@
import {HostedByCollectedFrom, Journal, Project, RelationResult} from "../../utils/result-preview/result-preview";
import {Context, Reference} from "../../utils/entities/resultLandingInfo";
import {HostedByCollectedFrom, Project, RelationResult} from "../../utils/result-preview/result-preview";
import {Context, Measure, Metric, Reference} from "../../utils/entities/resultLandingInfo";
import {Injectable} from '@angular/core';
import {properties} from "../../../../environments/environment";
import {StringUtils} from "../../utils/string-utils.class";
@ -15,15 +15,14 @@ export class ParsingFunctions {
{label: 'EOSC::Twitter Data', link: 'https://' + (properties.environment != 'production'?'beta.':'') + 'search.marketplace.eosc-portal.eu/search/service?q=*&fq=tag_list:%22EOSC%5C:%5C:Twitter%20Data%22', value: 'Twitter Data'},
{label: 'EOSC::Data Cube', link: 'https://' + (properties.environment != 'production'?'beta.':'') + 'search.marketplace.eosc-portal.eu/search/service?q=*&fq=tag_list:%22EOSC%5C:%5C:Data%20Cube%22', value: 'Data Cube'}
]
public notebookInSubjects: boolean = false;
private notebookKeyword: string = "eosc jupyter notebook";
private notebook_label: string = "EOSC";
private notebook_value: string = "EOSC Jupyter Notebook";
public open = 'lock_open';
public closed = 'lock';
public unknown = 'question_mark';
public open = 'open_access';
public closed = 'closed_access';
public unknown = 'unknown_access';
private instanceWithDoiExists: boolean = false;
@ -49,10 +48,10 @@ export class ParsingFunctions {
fundedByProject['acronym'] = relation.acronym;
fundedByProject['title'] = relation.title;
fundedByProject['code'] = relation.code;
if(relation.validated && relation.validated.date) {
if (relation.validated && relation.validated.date) {
fundedByProject['validated'] = true;
}
fundedByProject['provenanceAction'] = relation.provenanceaction;
fundedByProject['provenanceAction'] = relation.provenanceaction;
} else {
fundedByProject['id'] = "";
fundedByProject['acronym'] = "";
@ -156,7 +155,7 @@ export class ParsingFunctions {
// publication & dataset landing : for downloadFrom
addPublisherToHostedBy_collectedFrom(hostedBy_collectedFrom: HostedByCollectedFrom[],
publisher: string, journal: Journal,
publisher: string, journal: string,
identifiers: Map<string, string[]>/*, title: { "name": string, "url": string, "accessMode": string}*/) {
if (!this.instanceWithDoiExists && publisher && identifiers != null && identifiers.has('doi')) {
if (hostedBy_collectedFrom == null) {
@ -172,13 +171,13 @@ export class ParsingFunctions {
accessRightIcon: ""
};
if (journal && journal.journal) {
if (journal) {
available.downloadNames.push(publisher + "/ " + journal['journal']);
} else {
available.downloadNames.push(publisher);
}
available.downloadUrl = properties.doiURL + identifiers.get("doi")[0];;
available.downloadUrl = properties.doiURL + identifiers.get("doi")[0];
available.accessRightIcon = this.unknown;
/*
if(title != undefined && title['url'] == "") {
@ -253,7 +252,7 @@ export class ParsingFunctions {
parseHostedBy_collectedFrom(hostedBy_collectedFrom: HostedByCollectedFrom[],
instance: any, url: string, globalAccessRight: string) {
if(!url) {
if (!url) {
return;
}
@ -288,7 +287,7 @@ export class ParsingFunctions {
let length = Array.isArray(instance['collectedfrom']) ? instance['collectedfrom'].length : 1;
for (let i = 0; i < length; i++) {
let collectedFrom = Array.isArray(instance['collectedfrom']) ? instance['collectedfrom'][i] : instance['collectedfrom'];
if(collectedFrom.name && collectedFrom.id) {
if (collectedFrom.name && collectedFrom.id) {
available.collectedNamesAndIds.set(String(collectedFrom.name), collectedFrom.id);
}
}
@ -299,7 +298,7 @@ export class ParsingFunctions {
let length = Array.isArray(instance['instancetype']) ? instance['instancetype'].length : 1;
for (let i = 0; i < length; i++) {
let instanceType = Array.isArray(instance['instancetype']) ? instance['instancetype'][i] : instance['instancetype'];
if(instanceType.classname && instanceType.classname.toLowerCase() !== "unknown") {
if (instanceType.classname && instanceType.classname.toLowerCase() !== "unknown") {
types.add(instanceType.classname);
}
}
@ -318,7 +317,7 @@ export class ParsingFunctions {
}
available['downloadUrl'] = url;
if(url.includes("doi.org/")) {
if (url.includes("doi.org/")) {
this.instanceWithDoiExists = true;
}
@ -340,22 +339,60 @@ export class ParsingFunctions {
if (available.accessRight) {
if (available.accessRight.toLowerCase().indexOf('open') !== -1) {
available.accessRightIcon = this.open;
} else if (available.accessRight.toLowerCase().indexOf('not available') !== -1) {
}
else if (available.accessRight.toLowerCase().indexOf('not available') !== -1) {
available.accessRightIcon = this.unknown;
} else {
}
else {
available.accessRightIcon = this.closed;
}
} else {
available.accessRightIcon = this.unknown;
}
if(instance.hasOwnProperty("license")) {
if (instance.hasOwnProperty("license")) {
available.license = Array.isArray(instance['license']) ? instance['license'][0] : instance['license'];
}
hostedBy_collectedFrom.push(available);
}
compareHostedByCollectedFrom(a: HostedByCollectedFrom, b: HostedByCollectedFrom) {
let firstAccessRight: string = (a.accessRight ? a.accessRight.toLowerCase() : null);
let secondAccessRight: string = (b.accessRight ? b.accessRight.toLowerCase() : null);
if (firstAccessRight === secondAccessRight) {
return 0;
} else {
if (firstAccessRight === 'open access') {
return -1;
} else if (secondAccessRight === 'open access') {
return 1;
} else if (firstAccessRight === "open source") {
return -1;
} else if (secondAccessRight === "open source") {
return 1;
} else if (firstAccessRight === "embargo") {
return -1;
} else if (secondAccessRight === "embargo") {
return 1;
} else if (firstAccessRight === "restricted") {
return -1;
} else if (secondAccessRight === "restricted") {
return 1;
} else if (firstAccessRight === "closed access") {
return -1;
} else if (secondAccessRight === "closed access") {
return 1;
} else if (firstAccessRight === "not available") {
return -1;
} else if (secondAccessRight === "not available") {
return 1;
}
}
return 0;
}
// publication & dataset landing : for downloadFrom and publishedIn
changeBestAccessMode(currentAccessMode: string, accessMode: any): boolean {
if (!accessMode) {
@ -418,7 +455,7 @@ export class ParsingFunctions {
// researchResult.relationName = relation.to.class;
if(relation['resulttype']) {
if (relation['resulttype']) {
if (relation['resulttype'].classname == "publication") {
researchResult['class'] = "publication";
} else if (relation['resulttype'].classname == "dataset") {
@ -430,10 +467,10 @@ export class ParsingFunctions {
}
}
researchResult['id'] = relation['to'].content;
if(Array.isArray(relation['title'])) {
for(let i=0; i<relation['title'].length; i++) {
if(relation['title'][i] && relation['title'][i].content) {
if(!researchResult['name'] || relation['title'][i].classid == "main title") {
if (Array.isArray(relation['title'])) {
for (let i = 0; i < relation['title'].length; i++) {
if (relation['title'][i] && relation['title'][i].content) {
if (!researchResult['name'] || relation['title'][i].classid == "main title") {
researchResult['name'] = String(relation['title'][i].content);
}
}
@ -441,7 +478,7 @@ export class ParsingFunctions {
} else {
researchResult['name'] = (relation['title'] && relation['title'].content) ? String(relation['title'].content) : "";
}
if(!researchResult['name']) {
if (!researchResult['name']) {
researchResult['name'] = "[no title available]";
}
if (relation.hasOwnProperty("dateofacceptance")) {
@ -450,12 +487,12 @@ export class ParsingFunctions {
}
//researchResult['date'] = relation.dateofacceptance.substring(0,4);;
let percentageName: string;
if(relation.trust) {
if (relation.trust) {
percentageName = "trust";
} else if(relation.similarity) {
} else if (relation.similarity) {
percentageName = "similarity";
}
if(percentageName) {
if (percentageName) {
researchResult['percentage'] = Math.round(relation[percentageName] * 100);
researchResult['percentageName'] = percentageName;
}
@ -481,7 +518,7 @@ export class ParsingFunctions {
if (!identifiers.has(pid.classid)) {
identifiers.set(pid.classid, new Array<string>());
}
identifiers.get(pid.classid).push(pid.content+"");
identifiers.get(pid.classid).push(pid.content + "");
}
} else {
for (let i = 0; i < pid.length; i++) {
@ -489,7 +526,7 @@ export class ParsingFunctions {
if (!identifiers.has(pid[i].classid)) {
identifiers.set(pid[i].classid, new Array<string>());
}
identifiers.get(pid[i].classid).push(pid[i].content+"");
identifiers.get(pid[i].classid).push(pid[i].content + "");
}
}
}
@ -506,10 +543,10 @@ export class ParsingFunctions {
for (let i = 0; i < length; i++) {
subject = Array.isArray(_subjects) ? _subjects[i] : _subjects;
let content: string = subject.code+"";
let content: string = subject.code + "";
let checkAndAddEoscSubjectResp = this.checkAndAddEoscSubject(setOfEoscSubjects, eoscSubjectsFound, subject, content);
let found: boolean = checkAndAddEoscSubjectResp["found"];
if(found) {
if (found) {
setOfEoscSubjects = checkAndAddEoscSubjectResp["setOfEoscSubject"];
eoscSubjectsFound = checkAndAddEoscSubjectResp["eoscSubjectsFound"];
}
@ -519,7 +556,7 @@ export class ParsingFunctions {
}
// publication & dataset landing : for subjects and otherSubjects and classifiedSubjects
parseAllSubjects(_subjects: any, vocabulary: any): [string[], Map<string, string[]>, Map<string, string[]>, string[], string[], ] {
parseAllSubjects(_subjects: any, vocabulary: any): [string[], Map<string, string[]>, Map<string, string[]>, string[], string[],] {
// let eoscSubjectsFound = [];
let subjects: string[];
let otherSubjects: Map<string, string[]>;
@ -536,7 +573,7 @@ export class ParsingFunctions {
subject = Array.isArray(_subjects) ? _subjects[i] : _subjects;
if (subject.classid != "") {
if (subject.classid == "keyword") {
let content: string = subject.content+"";
let content: string = subject.content + "";
// let checkAndAddEoscSubjectResp = this.checkAndAddEoscSubject(setOfEoscSubjects, eoscSubjectsFound, subject, content);
// let found: boolean = checkAndAddEoscSubjectResp["found"];
// if(found) {
@ -550,22 +587,22 @@ export class ParsingFunctions {
// }
} else if (!vocabulary || vocabulary[subject.classid] || subject.classid === "SDG" || subject.classid === "FOS") {
// if (subject.inferred && subject.inferred == true) {
if(subject.classid === "SDG") {
if (subject.classid === "SDG") {
if (sdg == undefined) {
sdg = new Array<string>();
}
sdg.push(subject.content+"");
} else if(subject.classid === "FOS") {
sdg.push(subject.content + "");
} else if (subject.classid === "FOS") {
if (fos == undefined) {
fos = new Array<string>();
}
fos.push(subject.content+"");
fos.push(subject.content + "");
} else {
if (classifiedSubjects == undefined) {
classifiedSubjects = new Map<string, string[]>();
}
let content: string = subject.content+"";
let content: string = subject.content + "";
// let checkAndAddEoscSubjectResp = this.checkAndAddEoscSubject(setOfEoscSubjects, eoscSubjectsFound, subject, content);
// let found: boolean = checkAndAddEoscSubjectResp["found"];
// if(found) {
@ -579,7 +616,7 @@ export class ParsingFunctions {
// }
}
} else {
let content: string = subject.content+"";
let content: string = subject.content + "";
// let checkAndAddEoscSubjectResp = this.checkAndAddEoscSubject(setOfEoscSubjects, eoscSubjectsFound, subject, content);
// let found: boolean = checkAndAddEoscSubjectResp["found"];
// if(found) {
@ -601,7 +638,7 @@ export class ParsingFunctions {
checkAndAddEoscSubject(setOfEoscSubjects: Set<string>, eoscSubjectsFound, subject, content) {
let found: boolean = false;
if(!setOfEoscSubjects.has(content)) {
if (!setOfEoscSubjects.has(content)) {
// looping through our declared array
this.eoscSubjects.forEach(item => {
if (content && content == item.label) {
@ -640,7 +677,7 @@ export class ParsingFunctions {
// initalize if there is concept label or this is the last concept of the category and there were no concepts
// otherwise we could have multiple entries for the same category but without concepts
if(categoryConcept.label || (numOfConcepts == 0 && j == (length1 - 1))) {
if (categoryConcept.label || (numOfConcepts == 0 && j == (length1 - 1))) {
contexts[position] = {
"labelContext": "", "idContext": "",
"labelCategory": "", "idCategory": "",
@ -657,10 +694,12 @@ export class ParsingFunctions {
numOfConcepts++;
}
}
} else if(category.label || (numOfCategories == 0 && z == (length2 - 1))) {
contexts[position] = {"labelContext": "", "idContext": "",
"labelCategory": "", "idCategory": "",
"labelConcept": "", "idConcept": ""};
} else if (category.label || (numOfCategories == 0 && z == (length2 - 1))) {
contexts[position] = {
"labelContext": "", "idContext": "",
"labelCategory": "", "idCategory": "",
"labelConcept": "", "idConcept": ""
};
contexts[position]['labelContext'] = context.label;
contexts[position]['idContext'] = context.id;
contexts[position]['labelCategory'] = category.label ? category.label : null;
@ -672,9 +711,11 @@ export class ParsingFunctions {
}
}
} else {
contexts[position] = {"labelContext": "", "idContext": "",
"labelCategory": "", "idCategory": "",
"labelConcept": "", "idConcept": ""};
contexts[position] = {
"labelContext": "", "idContext": "",
"labelCategory": "", "idCategory": "",
"labelConcept": "", "idConcept": ""
};
contexts[position]['labelContext'] = context.label;
contexts[position]['idContext'] = context.id;
contexts[position]['labelCategory'] = null;
@ -688,11 +729,15 @@ export class ParsingFunctions {
}
return contexts;
}
public static getEnermapsConceptId(contexts: any): string{
let enermapsconcepts = contexts.filter(c=> {return c.idCategory == "enermaps::selection" && c.idConcept});
return enermapsconcepts && enermapsconcepts.length > 0?enermapsconcepts[0].idConcept.split("enermaps::selection::")[1]:null;
public static getEnermapsConceptId(contexts: any): string {
let enermapsconcepts = contexts.filter(c => {
return c.idCategory == "enermaps::selection" && c.idConcept
});
return enermapsconcepts && enermapsconcepts.length > 0 ? enermapsconcepts[0].idConcept.split("enermaps::selection::")[1] : null;
// return "hotmaps_heat_tot_curr_density"
}
parseTypes(types: string[], uniqueTypes: Set<string>, instance: any) {
if (instance && instance.hasOwnProperty("instancetype") && instance['instancetype'].classname) {
if (!uniqueTypes.has(instance['instancetype'].classname)) {
@ -727,7 +772,7 @@ export class ParsingFunctions {
countries.push(_countries.classname);
}
} else {
for (let i = 0; i < countries.length; i++) {
for (let i = 0; i < _countries.length; i++) {
if (_countries[i].classname != "Undetermined" && _countries[i].classname) {
countries.push(_countries[i].classname);
}
@ -758,10 +803,10 @@ export class ParsingFunctions {
citations = Array.isArray(citations) ? citations : [citations];
citations.forEach(citation => {
let reference: Reference = {name: null, ids: []};
if(citation.rawText) {
if (citation.rawText) {
reference.name = citation.rawText;
}
if(citation.id) {
if (citation.id) {
let ids: any[] = Array.isArray(citation.id) ? citation.id : [citation.id];
ids.forEach(id => {
reference.ids.push({
@ -775,35 +820,123 @@ export class ParsingFunctions {
});
return references;
}
static parseRelCanonicalId(record, type){
try{
if(record["result"]["metadata"]["oaf:entity"][("oaf:"+type)]["children"] && record["result"]["metadata"]["oaf:entity"][("oaf:"+type)]["children"][type]){
for(let child of record["result"]["metadata"]["oaf:entity"][("oaf:"+type)]["children"][type]){
static parseRelCanonicalId(record, type) {
try {
if (record["result"]["metadata"]["oaf:entity"][("oaf:" + type)]["children"] && record["result"]["metadata"]["oaf:entity"][("oaf:" + type)]["children"][type]) {
for (let child of record["result"]["metadata"]["oaf:entity"][("oaf:" + type)]["children"][type]) {
return child["objidentifier"];
}
}
}catch(e){
} catch (e) {
// console.error(e);
}
return record["result"]["header"]["dri:objIdentifier"];
return record["result"]["header"]["dri:objIdentifier"];
}
parseDescription(description, stripHTML: boolean = false):string {
parseDescription(description, stripHTML: boolean = false): string {
let abstracts = [];
if(!Array.isArray(description)) {
if (!Array.isArray(description)) {
abstracts = [description ? String(description) : ""];
} else {
abstracts = description.map( x => String(x));
abstracts = description.map(x => String(x));
}
try{
abstracts = abstracts.map( x => StringUtils.HTMLToString(x));
} catch (e) {}
abstracts = abstracts.sort((a,b) => b.length - a.length);
if(stripHTML) {
return abstracts.join(' ');
} else {
return abstracts.length > 0 ? ('<p>' + abstracts.join('</p> <p>') + '</p>') : abstracts.join(' ');
}
try {
abstracts = abstracts.map(x => StringUtils.HTMLToString(x));
} catch (e) {
}
abstracts = abstracts.sort((a, b) => b.length - a.length);
if (stripHTML) {
return abstracts.join(' ');
} else {
return abstracts.length > 0 ? ('<p>' + abstracts.join('</p> <p>') + '</p>') : abstracts.join(' ');
}
}
parseMeasures(elements: any[]): Measure {
if (elements && elements.length) {
let bip: Metric[] = [];
let counts: Metric[] = [];
let measure: Measure = {};
elements.forEach(element => {
if (element.id == 'views') {
counts.push({name: 'views', icon: 'visibility', value: element.count, order: 0});
measure.views = element.count;
}
if (element.id == 'downloads') {
counts.push({name: 'downloads', icon: 'download', value: element.count, order: 1});
measure.downloads = element.count;
}
if (element.id == 'influence_alt') {
bip.push({name: 'citations', icon: 'cite', value: element.score, order: 2});
measure.citations = element.score;
}
if (element.id == 'popularity') {
let metric: Metric = {name: 'popularity', icon: 'fire', value: null, order: 3};
if (element.class == 'C1') {
metric.value = 'Top 0.01%';
} else if (element.class == 'C2') {
metric.value = 'Top 0.1%';
} else if (element.class == 'C3') {
metric.value = 'Top 1%';
} else if (element.class == 'C4') {
metric.value = 'Top 10%';
} else if (element.class == 'A') {
metric.value = 'Exceptional';
} else if (element.class == 'B') {
metric.value = 'Substantial';
} else {
metric.value = 'Average';
}
measure.popularity = metric.value;
bip.push(metric);
}
if (element.id == 'influence') {
let metric: Metric = {name: 'influence', icon: 'landmark', value: null, order: 4};
if (element.class == 'C1') {
metric.value = 'Top 0.01%';
} else if (element.class == 'C2') {
metric.value = 'Top 0.1%';
} else if (element.class == 'C3') {
metric.value = 'Top 1%';
} else if (element.class == 'C4') {
metric.value = 'Top 10%';
} else if (element.class == 'A') {
metric.value = 'Exceptional';
} else if (element.class == 'B') {
metric.value = 'Substantial';
} else {
metric.value = 'Average';
}
measure.influence = metric.value;
bip.push(metric);
}
if (element.id == 'impulse') {
let metric: Metric = {name: 'impulse', icon: 'rocket', value: null, order: 5};
if (element.class == 'C1') {
metric.value = 'Top 0.01%';
} else if (element.class == 'C2') {
metric.value = 'Top 0.1%';
} else if (element.class == 'C3') {
metric.value = 'Top 1%';
} else if (element.class == 'C4') {
metric.value = 'Top 10%';
} else if (element.class == 'A') {
metric.value = 'Exceptional';
} else if (element.class == 'B') {
metric.value = 'Substantial';
} else {
metric.value = 'Average';
}
measure.impulse = metric.value;
bip.push(metric);
}
});
measure.bip = bip.sort((a, b) => a.order - b.order);
measure.counts = counts.sort((a, b) => a.order - b.order);
return measure;
}
return null;
}
}

View File

@ -13,17 +13,18 @@ import {OpenaireEntities} from "../../utils/properties/searchFields";
selector: 'relatedTo, [relatedTo]',
template: `
<ng-container *ngIf="communities && communities.length > 0">
<div class="uk-margin-small-bottom uk-flex uk-flex-between">
<div *ngIf="!mobileView" class="uk-margin-small-bottom uk-flex uk-flex-between">
<span *ngIf="viewAll && !lessBtn" class="clickable uk-h6 uk-flex uk-flex-middle" (click)="viewLessClick()">
<icon class="uk-margin-small-right" name="arrow_back" flex="true" ratio="1.2"></icon>
{{title}}
</span>
<span *ngIf="!viewAll || lessBtn" class="uk-text-light-grey">{{title}}</span>
<a *ngIf="viewAll && lessBtn" (click)="viewAll = !viewAll; lessBtn=false;" class="view-more-less-link">View less</a>
<span *ngIf="!viewAll || lessBtn" class="uk-text-emphasis uk-text-bolder">{{title}}</span>
<a *ngIf="viewAll && lessBtn" (click)="viewAll = !viewAll; lessBtn=false;" class="view-more-less-link uk-link-text">View less</a>
<a *ngIf="communities && communities.length > threshold && !viewAll"
(click)="viewAllClick();" class="view-more-less-link">View all</a>
(click)="viewAllClick();" class="view-more-less-link uk-link-text">View all</a>
</div>
<div *ngFor="let community of communities.slice(0, viewAll?communities.length:threshold)" class="uk-text-truncate">
<div *ngFor="let community of communities.slice(0, viewAll?communities.length:threshold)" class="uk-text-truncate"
[class.uk-margin-small-bottom]="mobileView">
<!-- If there are any communities with dashboard -->
<a *ngIf="community.link" href="{{community.link}}" target="_blank" [attr.uk-tooltip]="community.labelContext" class="custom-external">
{{community.labelContext}}
@ -44,6 +45,7 @@ import {OpenaireEntities} from "../../utils/properties/searchFields";
})
export class RelatedToComponent implements OnInit {
@Input() mobileView: boolean = false;
@Input() contexts: Context[];
@Input() viewAll: boolean = false;
@Output() viewAllClicked = new EventEmitter();

View File

@ -16,23 +16,34 @@ import {FosComponent} from "./fos.component";
import {SdgComponent} from "./sdg.component";
import {IconsModule} from "../../utils/icons/icons.module";
import {AlertModalModule} from "../../utils/modal/alertModal.module";
import { SearchInputModule } from '../../sharedComponents/search-input/search-input.module';
import {EntityMetadataComponent} from "./entity-metadata.component";
import {IconsService} from "../../utils/icons/icons.service";
import {closed_access, open_access, unknown_access} from "../../utils/icons/icons";
import {FullScreenModalModule} from "../../utils/modal/full-screen-modal/full-screen-modal.module";
@NgModule({
imports: [
CommonModule, FormsModule, RouterModule, PagingModule, ShowPublisherModule, IconsModule, AlertModalModule
CommonModule, FormsModule, RouterModule, PagingModule, ShowPublisherModule, IconsModule, AlertModalModule,
SearchInputModule, FullScreenModalModule
],
declarations: [
ShowIdentifiersComponent,ShowSubjectsComponent,
FundedByComponent,AvailableOnComponent,TabTableComponent,
RelatedToComponent, FosComponent, SdgComponent
RelatedToComponent, FosComponent, SdgComponent,
EntityMetadataComponent
],
providers:[
],
exports: [
ShowIdentifiersComponent, ShowSubjectsComponent,
FundedByComponent,AvailableOnComponent, TabTableComponent, ShowPublisherComponent,
RelatedToComponent, FosComponent, SdgComponent
RelatedToComponent, FosComponent, SdgComponent, EntityMetadataComponent
]
})
export class ResultLandingUtilsModule { }
export class ResultLandingUtilsModule {
constructor(private iconsService: IconsService) {
this.iconsService.registerIcons([open_access, closed_access, unknown_access]);
}
}

View File

@ -0,0 +1,176 @@
import {ChangeDetectorRef, Component, Input, ViewChild} from "@angular/core";
import {FormBuilder, UntypedFormGroup, Validators} from "@angular/forms";
import {SdgSelectionComponent} from "../../../sdg/sdg-selection/sdg-selection.component";
import {FosSelectionComponent} from "../../../fos/fos-selection/fos-selection.component";
import {properties} from "../../../../../environments/environment";
import {EnvProperties} from "../../../utils/properties/env-properties";
import {EmailService} from "../../../utils/email/email.service";
import {Subscription} from "rxjs";
import {Composer} from "../../../utils/email/composer";
import {AlertModal} from "../../../utils/modal/alert";
import {StringUtils} from "../../../utils/string-utils.class";
@Component({
selector: 'sdg-fos-suggest',
template: `
<modal-alert #selectionModal [large]="true" (alertOutput)="modalOutput()" (cancelOutput)="modalCancel()"
[okDisabled]="!sent && !selectionStep1 && (form.invalid || sending)">
<sdg-selection *ngIf="subjects && subjectType == 'sdg'" #selection [class.uk-hidden]="!selectionStep1"
[subjects]="subjects" [entityType]="entityType"></sdg-selection>
<fos-selection *ngIf="subjects && subjectType == 'fos'" #selection [class.uk-hidden]="!selectionStep1"
[subjects]="subjects" [contentHeight]="selectionModal.bodyHeight" [inModal]="true"></fos-selection>
<div [class.uk-hidden]="selectionStep1">
<div class="uk-flex uk-flex-column uk-flex-middle">
<ng-container *ngIf="!sent && !error">
<div>Thank you for your feedback.</div>
<div>Before sending us your options, would you like to leave us your e-mail to notify you about the reporting status?</div>
<div input class="uk-width-1-2 uk-margin-medium-top uk-margin-medium-bottom"
[formInput]="form.get('email')" placeholder="E-mail">
<span note>(Optional)</span>
</div>
<div>
<re-captcha (resolved)="handleRecaptcha($event)" [siteKey]="properties.reCaptchaSiteKey"
[ngClass]="sending ? 'uk-hidden':''"></re-captcha>
<loading [ngClass]="sending ? '':'uk-hidden'"></loading>
</div>
</ng-container>
<ng-container *ngIf="sent">
<p>Your feedback is successfully received and it will soon be reviewed by our graph experts!</p>
<icon customClass="uk-text-background" name="check" [ratio]="4"></icon>
</ng-container>
<div *ngIf="error" class="uk-alert uk-alert-danger uk-text-center uk-width-large ng-star-inserted"
role="alert">Email sent failed! Please try again.
</div>
</div>
</div>
</modal-alert>
`
})
export class SdgFosSuggestComponent {
@Input() entityType: string;
@Input() title;
public subjectType: "fos" | "sdg" = "sdg";
public subjects;
public properties: EnvProperties = properties;
public selectionStep1: boolean = true;
@ViewChild("selectionModal") selectionModal: AlertModal;
@ViewChild("selection") selection: SdgSelectionComponent | FosSelectionComponent;
public form: UntypedFormGroup;
public url: string = null;
public sending: boolean = false;
public sent: boolean = false;
public error: boolean = false;
subscriptions: Subscription[] = [];
constructor(private emailService: EmailService, private fb: FormBuilder, private cdr: ChangeDetectorRef) {}
ngOnInit() {
if (typeof window !== "undefined") {
this.url = window.location.href;
}
this.init();
}
ngOnDestroy() {
this.subscriptions.forEach(subscription => {
if (subscription instanceof Subscription) {
subscription.unsubscribe();
}
});
}
init() {
this.form = this.fb.group({
name: this.fb.control(this.title),
url: this.fb.control(this.url),
email: this.fb.control('', Validators.email),
subjects: this.fb.control([]),
recaptcha: this.fb.control('', Validators.required),
});
}
public openSelectionModal() {
this.sent = false;
this.sending = false;
this.error = false;
this.selectionStep1 = true;
this.init();
this.selectionModal.cancelButton = false;
if(this.subjectType == "sdg") {
this.selectionModal.alertTitle = "Please select SDGs that are the most relevant for this "+this.getEntityName(this.entityType)+".";
} else {
this.selectionModal.alertTitle = "Please select Fields of Science that are the most relevant for this "+this.getEntityName(this.entityType)+".";
}
this.selectionModal.okButtonText = "Next";
this.selectionModal.stayOpen = true;
this.cdr.detectChanges();
this.selectionModal.open();
}
public modalOutput() {
this.selectionModal.previousButton = true;
this.selectionModal.okButtonText = "Send feedback";
if(this.selectionStep1) {
this.selectionStep1 = false;
if(this.subjectType == "sdg") {
this.selectionModal.alertTitle = "Please send your feedback on most relevant SDGs for this "+this.getEntityName(this.entityType)+".";
} else {
this.selectionModal.alertTitle = "Please send your feedback on most relevant Fields of Science for this "+this.getEntityName(this.entityType)+".";
}
} else {
this.sending = true;
// email functionality
this.form.get("subjects").setValue(this.selection.getSelectedSubjects().map(subject => subject.id));
this.subscriptions.push(this.emailService.contact(this.properties,
Composer.composeEmailForSdgsSuggestion(this.form.value, [this.properties.feedbackmail], this.subjectType), this.form.get('recaptcha').value).subscribe(sent => {
this.error = !sent;
if (sent) {
if (this.form.get('email').value !== '') {
this.subscriptions.push(this.emailService.contact(this.properties,
Composer.composeEmailForUserAfterFeedback([this.form.get('email').value])).subscribe(sent => {
if (sent) {
//console.log('An email has been sent to user ' + this.form.get('email').value);
}
}));
}
this.init();
this.sent = true;
this.selectionModal.alertTitle = "Thank you for your feedback";
this.selectionModal.okButtonText = "OK";
this.selectionModal.previousButton = false;
this.selectionModal.stayOpen = false;
}
this.sending = false;
}, error => {
console.log(error);
this.error = true;
this.sending = false;
}));
}
}
public modalCancel() {
if(this.subjectType == "sdg") {
this.selectionModal.alertTitle = "Please select SDGs that are the most relevant for this "+this.getEntityName(this.entityType)+".";
} else {
this.selectionModal.alertTitle = "Please select Fields of Science that are the most relevant for this "+this.getEntityName(this.entityType)+".";
}
this.selectionStep1 = true;
this.selectionModal.previousButton = false;
this.selectionModal.okButtonText = "Next";
this.selectionModal.stayOpen = true;
this.error = false;
}
public handleRecaptcha(captchaResponse: string) {
this.form.get('recaptcha').setValue(captchaResponse);
}
private getEntityName (entityType:string) {
return StringUtils.getEntityName(entityType, false);
}
}

View File

@ -0,0 +1,29 @@
import {CommonModule} from "@angular/common";
import {NgModule} from "@angular/core";
import {FormsModule} from "@angular/forms";
import {RecaptchaModule} from "ng-recaptcha";
import {SdgSelectionModule} from "../../../sdg/sdg-selection/sdg-selection.module";
import {FosSelectionModule} from "../../../fos/fos-selection/fos-selection.module";
import {InputModule} from "../../../sharedComponents/input/input.module";
import {SdgFosSuggestComponent} from "./sdg-fos-suggest.component";
import {AlertModalModule} from "../../../utils/modal/alertModal.module";
import {IconsModule} from "../../../utils/icons/icons.module";
import {LoadingModule} from "../../../utils/loading/loading.module";
@NgModule({
imports: [
CommonModule, FormsModule, InputModule, SdgSelectionModule, FosSelectionModule, RecaptchaModule, AlertModalModule, IconsModule, LoadingModule
],
declarations: [
SdgFosSuggestComponent
],
providers: [
],
exports: [
SdgFosSuggestComponent
]
})
export class SdgFosSuggestModule {
}

View File

@ -6,41 +6,68 @@ import {StringUtils} from "../../utils/string-utils.class";
@Component({
selector: 'sdg',
template: `
<div class="uk-text-xsmall" style="color: #EEB204">Beta</div>
<div [class]="'uk-flex uk-flex-between uk-flex-middle uk-margin-'+(viewAll?'':'small-')+'bottom'">
<span *ngIf="viewAll" class="clickable uk-h6 uk-flex uk-flex-middle uk-margin-small-right uk-margin-remove-bottom"
(click)="viewLessClick()">
<icon class="uk-margin-small-right" name="arrow_back" flex="true" ratio="1.2"></icon>
<span uk-tooltip="Sustainable Development Goals">{{title}}</span>
</span>
<span *ngIf="!viewAll" class="uk-text-light-grey uk-text-nowrap uk-margin-small-right" uk-tooltip="Sustainable Development Goals">{{title}}</span>
<!-- <a *ngIf="viewAll && lessBtn" (click)="viewAll = !viewAll; lessBtn=false;">View less</a>-->
<a *ngIf="properties.adminToolsPortalType == 'eosc' && subjects && subjects.length > threshold && !viewAll"
(click)="viewAllClick();" class="view-more-less-link uk-text-truncate" uk-tooltip="View all">
View all</a>
<a *ngIf="properties.adminToolsPortalType !== 'eosc' && subjects && subjects.length > threshold && !viewAll"
(click)="viewAllClick();" class="view-more-less-link uk-text-truncate" uk-tooltip="View all & feedback">
View all & feedback</a>
<a *ngIf="properties.adminToolsPortalType !== 'eosc' && (subjects && subjects.length <= threshold || viewAll)" class="uk-link uk-text-truncate"
(click)="feedbackClick();">Feedback</a>
</div>
<div class="uk-margin-small-bottom uk-flex">
<img src="assets/common-assets/common/The_Global_Goals_Icon_Color.svg"
loading="lazy" alt="sdg_colors" style="width:27px; height:27px">
<div class="uk-margin-small-left">
<div *ngFor="let subject of subjects.slice(0, viewAll?subjects.length:threshold); let i=index" class="uk-text-truncate">
<a *ngIf="properties.adminToolsPortalType !== 'eosc'"
[routerLink]=" properties.searchLinkToResults" [queryParams]="{'sdg': urlEncodeAndQuote(subject)}">
{{subject}}
</a>
<a *ngIf="properties.adminToolsPortalType == 'eosc'" class="custom-external" target="_blank"
[href]="'https://explore.openaire.eu'+properties.searchLinkToResults+'?sdg='+urlEncodeAndQuote(subject)">
{{subject}}
</a>
</div>
<div class="uk-visible@m">
<div class="uk-text-xsmall" style="color: #EEB204">Beta</div>
<div [class]="'uk-flex uk-flex-between uk-flex-middle uk-margin-'+(viewAll?'':'small-')+'bottom'">
<span *ngIf="viewAll" class="clickable uk-h6 uk-flex uk-flex-middle uk-margin-small-right uk-margin-remove-bottom"
(click)="viewLessClick()">
<icon class="uk-margin-small-right" name="arrow_back" flex="true" ratio="1.2"></icon>
<span uk-tooltip="Sustainable Development Goals">{{title}}</span>
</span>
<span *ngIf="!viewAll" class="uk-text-emphasis uk-text-bolder uk-text-nowrap uk-margin-small-right" uk-tooltip="Sustainable Development Goals">
{{title}}
<span *ngIf="subjects && subjects.length > threshold && !viewAll">({{subjects.length}})</span>
</span>
<a *ngIf="properties.adminToolsPortalType == 'eosc' && subjects && subjects.length > threshold && !viewAll"
(click)="viewAllClick();" class="view-more-less-link uk-link uk-link-text uk-text-truncate">
View all</a>
<!-- <a *ngIf="viewAll && lessBtn" (click)="viewAll = !viewAll; lessBtn=false;">View less</a> -->
<a *ngIf="properties.adminToolsPortalType != 'eosc' && subjects && subjects.length > threshold && !viewAll"
(click)="viewAllClick();" class="view-more-less-link uk-link uk-link-text uk-text-truncate">
View all & suggest</a>
<a *ngIf="properties.adminToolsPortalType != 'eosc' && (subjects && subjects.length <= threshold || viewAll)" class="uk-link uk-link-text uk-text-truncate"
(click)="suggestClick();">Suggest</a>
</div>
<div class="uk-margin-small-bottom uk-flex">
<img src="assets/common-assets/common/The_Global_Goals_Icon_Color.svg"
loading="lazy" alt="sdg_colors" style="width:27px; height:27px">
<div class="uk-margin-small-left">
<div *ngFor="let subject of subjects.slice(0, viewAll?subjects.length:threshold); let i=index" class="uk-text-truncate">
<a *ngIf="properties.adminToolsPortalType != 'eosc'"
[routerLink]=" properties.searchLinkToResults" [queryParams]="{'sdg': urlEncodeAndQuote(subject)}">
{{subject}}
</a>
<a *ngIf="properties.adminToolsPortalType == 'eosc'" class="custom-external" target="_blank"
[href]="'https://explore.openaire.eu'+properties.searchLinkToResults+'?sdg='+urlEncodeAndQuote(subject)">
{{subject}}
</a>
</div>
</div>
</div>
</div>
<div class="uk-hidden@m">
<div class="uk-text-xsmall" style="color: #EEB204">Beta</div>
<div class="uk-flex uk-flex-middle uk-flex-wrap">
<img src="assets/common-assets/common/The_Global_Goals_Icon_Color.svg"
loading="lazy" alt="sdg_colors" style="width:18px; height:18px">
<span class="uk-margin-xsmall-left uk-margin-xsmall-right uk-text-meta">SDGs:</span>
<div *ngFor="let subject of subjects.slice(0, viewAll?subjects.length:threshold); let i=index" class="uk-text-truncate">
<a [routerLink]=" properties.searchLinkToResults" [queryParams]="{'sdg': urlEncodeAndQuote(subject)}">{{subject}}</a>
<span *ngIf="(viewAll && i<subjects.length-1) || i<threshold-1">, &nbsp;</span>
</div>
<!-- <div>
{{subjects.slice(0, viewAll?subjects.length:threshold).join(", ")}}
</div> -->
</div>
<div class="uk-text-right uk-margin-small-top">
<a *ngIf="subjects && subjects.length > threshold && !viewAll"
(click)="viewAllClick();" class="view-more-less-link uk-link uk-text-truncate">
View all</a>
<!-- View all & suggest</a>-->
<!-- <a *ngIf="(subjects && subjects.length <= threshold || viewAll)" class="uk-link uk-link-text uk-text-truncate"-->
<!-- (click)="suggestClick();">Suggest</a>-->
</div>
</div>
</div>
`
})
@ -48,9 +75,9 @@ export class SdgComponent {
@Input() subjects: string[];
@Input() viewAll: boolean = false;
@Output() viewAllClicked = new EventEmitter();
@Output() feedbackClicked = new EventEmitter();
@Output() suggestClicked = new EventEmitter();
public lessBtn: boolean = false;
public threshold: number = 4;
public threshold: number = 2;
public routerHelper: RouterHelper = new RouterHelper();
public properties = properties;
public title: string = "SDGs";
@ -70,8 +97,8 @@ export class SdgComponent {
this.viewAllClicked.emit("");
}
public feedbackClick() {
this.feedbackClicked.emit("");
public suggestClick() {
this.suggestClicked.emit('sdg');
}
public urlEncodeAndQuote(str: string): string {

View File

@ -47,14 +47,21 @@ import {properties} from "../../../../environments/environment";
<a (click)="openIdentifiersModal()" class="view-more-less-link">View all</a>
</div>
<modal-alert #identifiersModal>
<modal-alert *ngIf="!isMobile" #identifiersModal>
<div class="uk-text-small">
<ng-container *ngTemplateOutlet="identifiers_template; context: { modal: true}"></ng-container>
</div>
</modal-alert>
<fs-modal *ngIf="isMobile" #identifiersModal>
<div class="uk-text-small">
<ng-container *ngTemplateOutlet="identifiers_template; context: { modal: true}"></ng-container>
</div>
</fs-modal>
`
})
export class ShowIdentifiersComponent implements AfterViewInit {
@Input() isMobile: boolean = false;
@Input() identifiers: Map<string, string[]>;
@Input() showViewAll: boolean = false;
large: Map<string, boolean> = new Map<string, boolean>();
@ -121,9 +128,15 @@ export class ShowIdentifiersComponent implements AfterViewInit {
}
public openIdentifiersModal() {
this.identifiersModal.cancelButton = false;
this.identifiersModal.okButton = false;
this.identifiersModal.alertTitle = "Persistent Identifiers";
this.identifiersModal.open();
if(this.isMobile) {
this.identifiersModal.okButton = false;
this.identifiersModal.title = "Persistent Identifiers";
this.identifiersModal.open();
} else {
this.identifiersModal.cancelButton = false;
this.identifiersModal.okButton = false;
this.identifiersModal.alertTitle = "Persistent Identifiers";
this.identifiersModal.open();
}
}
}

View File

@ -4,77 +4,74 @@ import {EnvProperties} from "../../utils/properties/env-properties";
@Component({
selector: 'showPublisher, [showPublisher]',
template: `
<div *ngIf="publishDate || journal && (journal['journal'] || journal['issn'] || journal['lissn']
|| journal['volume'] || journal['eissn'] || journal['issue'])" class="uk-text-small">
<span *ngIf="publishDate" class="uk-margin-right">
<span class="uk-text-meta">Published: </span>
{{publishDate | date: 'dd MMM yyyy' : 'UTC'}}
</span>
<span *ngIf="journal && (journal['journal'] || journal['issn'] || journal['lissn']
|| journal['volume'] || journal['eissn'] || journal['issue'])">
<span class="uk-text-meta">Journal: </span>
<span *ngIf="journal['journal']">{{journal['journal']}}</span>
<span *ngIf="journal['journal'] && (journal['volume'] || journal['issue'])">, </span>
<ng-container *ngIf="journal['volume']">
<span class="uk-display-inline-block">
volume
<span *ngIf="journal['volume'] > 0">{{journal['volume'] | number}}</span>
<span *ngIf="!(journal['volume'] > 0)">{{journal['volume']}}</span>
</span>
<span *ngIf="journal['issue'] || journal['start_page'] || journal['end_page']">, </span>
</ng-container>
<ng-container *ngIf="journal['issue']">
<span class="uk-display-inline-block">
issue
<span *ngIf="journal['issue'] > 0">{{journal['issue'] | number}}</span>
<span *ngIf="!(journal['issue'] > 0)">{{journal['issue']}}</span>
</span>
<span *ngIf="journal['start_page'] || journal['end_page']">, </span>
</ng-container>
<span *ngIf="(journal['volume'] || journal['issue']) && (journal['start_page'] || journal['end_page'])"
class="uk-display-inline-block">
{{(journal['start_page'] && journal['end_page']) ? 'pages' : 'page'}}
<span *ngIf="journal['start_page']">
<span *ngIf="journal['start_page'] > 0">{{journal['start_page'] | number}}</span>
<span *ngIf="!(journal['start_page'] > 0)">{{journal['start_page']}}</span>
</span>
<span *ngIf="journal['start_page'] && journal['end_page']">-</span>
<span *ngIf="journal['end_page']">
<span *ngIf="journal['end_page'] > 0">{{journal['end_page'] | number}}</span>
<span *ngIf="!(journal['end_page'] > 0)">{{journal['end_page']}}</span>
</span>
</span>
<span *ngIf=" journal['journal'] && (journal['issn'] || journal['eissn'] || journal['lissn'])"> (</span>
<ng-container *ngIf="journal['issn']">
<span class="uk-display-inline-block">issn: {{journal['issn']}}</span>
<span>, </span>
</ng-container>
<ng-container *ngIf="journal['eissn']">
<span class="uk-display-inline-block">eissn: {{journal['eissn']}}</span>
<span>, </span>
</ng-container>
<span *ngIf="journal['lissn']" class="uk-display-inline-block">
<span class="uk-display-inline-block">lissn: {{journal['lissn']}}</span>
<span>, </span>
</span>
<span *ngIf="journal && (journal['issn'] ||journal['lissn'] || journal['eissn'] )">
<a target="_blank" class="uk-display-inline-block custom-external"
[href]="properties.sherpaURL+(journal['issn']?journal['issn']:(journal['eissn']?journal['eissn']:journal['lissn'] ))+properties.sherpaURLSuffix"
uk-tooltip="title: View information on Sherpa/RoMEO ">
<img src="assets/common-assets/common/SHERPA-RoMEO-short-logo.gif" width=16 height=16 alt="" loading="lazy">
Copyright policy
</a>
</span>
<span *ngIf=" journal['journal'] && (journal['issn'] || journal['eissn'] || journal['lissn'])">)</span>
</span>
</div>
<div *ngIf="publisher" class="uk-text-small uk-margin-small-top">
<span class="uk-text-meta">Publisher: </span> {{publisher}}
</div>
<ng-container *ngIf="journal && (journal['journal'] || journal['issn'] || journal['lissn']
|| journal['volume'] || journal['eissn'] || journal['issue'])">
<ng-container *ngIf="journal && (journal['journal'] || journal['issn'] || journal['lissn']
|| journal['volume'] || journal['eissn'] || journal['issue'])">
<span [attr.uk-tooltip]="'cls: uk-active'" [title]="'Journal'">
<span *ngIf="journal['journal']">{{journal['journal']}}</span>
<span *ngIf="journal['journal'] && (journal['volume'] || journal['issue'])">, </span>
<ng-container *ngIf="journal['volume']">
<span class="uk-display-inline-block">
volume
<span *ngIf="journal['volume'] > 0">{{journal['volume'] | number}}</span>
<span *ngIf="!(journal['volume'] > 0)">{{journal['volume']}}</span>
</span>
<span *ngIf="journal['issue'] || journal['start_page'] || journal['end_page']">, </span>
</ng-container>
<ng-container *ngIf="journal['issue']">
<span class="uk-display-inline-block">
issue
<span *ngIf="journal['issue'] > 0">{{journal['issue'] | number}}</span>
<span *ngIf="!(journal['issue'] > 0)">{{journal['issue']}}</span>
</span>
<span *ngIf="journal['start_page'] || journal['end_page']">, </span>
</ng-container>
<span *ngIf="(journal['volume'] || journal['issue']) && (journal['start_page'] || journal['end_page'])"
class="uk-display-inline-block">
{{(journal['start_page'] && journal['end_page']) ? 'pages' : 'page'}}
<span *ngIf="journal['start_page']">
<span *ngIf="journal['start_page'] > 0">{{journal['start_page'] | number}}</span>
<span *ngIf="!(journal['start_page'] > 0)">{{journal['start_page']}}</span>
</span>
<span *ngIf="journal['start_page'] && journal['end_page']">-</span>
<span *ngIf="journal['end_page']">
<span *ngIf="journal['end_page'] > 0">{{journal['end_page'] | number}}</span>
<span *ngIf="!(journal['end_page'] > 0)">{{journal['end_page']}}</span>
</span>
</span>
<span *ngIf=" journal['journal'] && (journal['issn'] || journal['eissn'] || journal['lissn'])"> (</span>
<ng-container *ngIf="journal['issn']">
<span class="uk-display-inline-block">issn: {{journal['issn']}}</span>
<span>, </span>
</ng-container>
<ng-container *ngIf="journal['eissn']">
<span class="uk-display-inline-block">eissn: {{journal['eissn']}}</span>
<span>, </span>
</ng-container>
<span *ngIf="journal['lissn']" class="uk-display-inline-block">
<span class="uk-display-inline-block">lissn: {{journal['lissn']}}</span>
<span>, </span>
</span>
<span *ngIf="journal && (journal['issn'] ||journal['lissn'] || journal['eissn'] )">
<a target="_blank" class="uk-display-inline-block custom-external"
[href]="properties.sherpaURL+(journal['issn']?journal['issn']:(journal['eissn']?journal['eissn']:journal['lissn'] ))+properties.sherpaURLSuffix"
uk-tooltip="title: View information on Sherpa/RoMEO ">
<img src="assets/common-assets/common/SHERPA-RoMEO-short-logo.gif" width=16 height=16 alt="" loading="lazy">
Copyright policy
</a>
</span>
<span *ngIf=" journal['journal'] && (journal['issn'] || journal['eissn'] || journal['lissn'])">)</span>
</span>
</ng-container>
<span *ngIf="publisher" class="uk-margin-xsmall-left uk-margin-xsmall-right bullet"></span>
</ng-container>
<ng-container *ngIf="publisher">
<span [attr.uk-tooltip]="'cls: uk-active'" [title]="'Publisher'">{{publisher}}</span>
</ng-container>
`
})
export class ShowPublisherComponent {
@Input() publishDate: Date;
@Input() publisher;
@Input() journal;
//@Input() sherpaUrl = 'http://www.sherpa.ac.uk/romeo/search.php?issn=';

View File

@ -1,10 +1,11 @@
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {ShowPublisherComponent} from "./showPublisher.component";
import {IconsModule} from '../../utils/icons/icons.module';
@NgModule({
imports: [
CommonModule
CommonModule, IconsModule
],
declarations: [
ShowPublisherComponent

View File

@ -1,9 +1,9 @@
import {
ChangeDetectorRef,
Component,
ElementRef,
ElementRef, EventEmitter,
HostListener,
Input,
Input, Output,
QueryList,
ViewChild,
ViewChildren
@ -13,24 +13,24 @@ import {properties} from "../../../../environments/environment";
@Component({
selector: 'showSubjects',
template: `
<ng-container *ngIf="(classifiedSubjects && classifiedSubjects.size > 0) || (eoscSubjects && eoscSubjects.length > 0)">
<div class="uk-text-meta">
<ng-container *ngIf="!viewAllSubjects && ((classifiedSubjects && classifiedSubjects.size > 0) || (eoscSubjects && eoscSubjects.length > 0))">
<div *ngIf="!viewAllClassifiedSubjects" class="uk-text-meta">
Subjects by Vocabulary
</div>
<ng-container *ngTemplateOutlet="subjects_by_vocabulary_template; context: {customClasses: 'multi-line-ellipsis lines-2', id: 'content'}"></ng-container>
<ng-container *ngTemplateOutlet="subjects_by_vocabulary_template; context: {customClasses: (isMobile && viewAllClassifiedSubjects) ? '' : 'multi-line-ellipsis lines-2', id: 'content'}"></ng-container>
<ng-container *ngIf="eoscSubjects && eoscSubjects.length > 0"><ng-container *ngTemplateOutlet="eosc_subjects_template"></ng-container></ng-container>
<div *ngIf="isClassifiedLarge" class="uk-text-right">
<a (click)="openSubjectsByVocabularyModal()" class="view-more-less-link">View all</a>
<div *ngIf="isClassifiedLarge && !viewAllClassifiedSubjects" class="uk-text-right">
<a (click)="viewAllSubjectsByVocabularyClicked()" class="view-more-less-link">View all</a>
</div>
</ng-container>
<ng-container *ngIf="(subjects && subjects.length > 0) || (otherSubjects && otherSubjects.size > 0)">
<div class="uk-text-meta uk-margin-small-bottom" [class.uk-margin-medium-top]="classifiedSubjects && classifiedSubjects.size > 0">
Subjects
<ng-container *ngIf="!viewAllClassifiedSubjects && ((subjects && subjects.length > 0) || (otherSubjects && otherSubjects.size > 0))">
<div *ngIf="!viewAllSubjects" class="uk-text-meta uk-margin-small-bottom" [class.uk-margin-medium-top]="classifiedSubjects && classifiedSubjects.size > 0">
Keywords
</div>
<ng-container *ngTemplateOutlet="subjects_template; context: {customClasses: 'multi-line-ellipsis lines-2', id: 'content'}"></ng-container>
<div *ngIf="isLarge" class="uk-text-right uk-margin-small-top">
<a (click)="openSubjectsModal()" class="view-more-less-link">View all</a>
<ng-container *ngTemplateOutlet="subjects_template; context: {customClasses: (isMobile && viewAllSubjects) ? '' : 'multi-line-ellipsis lines-2', id: 'content'}"></ng-container>
<div *ngIf="isLarge && !viewAllSubjects" class="uk-text-right uk-margin-small-top">
<a (click)="viewAllSubjectsClicked()" class="view-more-less-link">View all</a>
</div>
</ng-container>
@ -49,7 +49,7 @@ import {properties} from "../../../../environments/environment";
</div>
</ng-template>
<modal-alert #subjectsModal *ngIf="(subjects && subjects.length > 0) || (otherSubjects && otherSubjects.size > 0)">
<modal-alert #subjectsModal *ngIf="!isMobile && ((subjects && subjects.length > 0) || (otherSubjects && otherSubjects.size > 0))">
<div class="uk-text-small">
<ng-container *ngTemplateOutlet="subjects_template"></ng-container>
</div>
@ -94,7 +94,7 @@ import {properties} from "../../../../environments/environment";
</div>
</ng-template>
<modal-alert #subjectsByVocabularyModal *ngIf="(classifiedSubjects && classifiedSubjects.size > 0) || (eoscSubjects && eoscSubjects.length > 0)" large="true">
<modal-alert #subjectsByVocabularyModal *ngIf="!isMobile && ((classifiedSubjects && classifiedSubjects.size > 0) || (eoscSubjects && eoscSubjects.length > 0))" large="true">
<div class="uk-text-small">
<ng-container *ngTemplateOutlet="subjects_by_vocabulary_template"></ng-container>
<ng-container *ngIf="eoscSubjects && eoscSubjects.length > 0"><ng-container *ngTemplateOutlet="eosc_subjects_template"></ng-container></ng-container>
@ -104,12 +104,16 @@ import {properties} from "../../../../environments/environment";
})
export class ShowSubjectsComponent {
@Input() isMobile: boolean = false;
@Input() subjects: string[];
@Input() otherSubjects: Map<string, string[]>;
@Input() classifiedSubjects: Map<string, string[]>;
@Input() eoscSubjects: any[];
isLarge: boolean = false;
isClassifiedLarge: boolean = false;
@Input() viewAllSubjects: boolean = false;
@Input() viewAllClassifiedSubjects: boolean = false;
@Output() viewAllClicked = new EventEmitter();
properties = properties;
specialSubjects = [];
@ViewChildren("content", { read: ElementRef }) content: QueryList<ElementRef>;
@ -206,4 +210,28 @@ export class ShowSubjectsComponent {
this.subjectsByVocabularyModal.alertTitle = "Subjects by Vocabulary";
this.subjectsByVocabularyModal.open();
}
public viewAllSubjectsClicked() {
if(this.isMobile) {
this.viewAllSubjects = true;
this.viewAllClicked.emit({
subtitle: 'Keywords',
id: 'subjects'
});
} else {
this.openSubjectsModal();
}
}
public viewAllSubjectsByVocabularyClicked() {
if(this.isMobile) {
this.viewAllClassifiedSubjects = true;
this.viewAllClicked.emit({
subtitle: 'Subjects by Vocabulary',
id: 'classifiedSubjects'
});
} else {
this.openSubjectsByVocabularyModal();
}
}
}

View File

@ -1,52 +1,56 @@
import {Component, Input} from '@angular/core';
import {ActivatedRoute} from '@angular/router';
import {Component, ElementRef, Input, ViewChild} from '@angular/core';
@Component({
selector: 'showTitle',
template: `
<h1 [ngClass]="classNames" class="uk-h5">
<ng-container *ngTemplateOutlet="_title;"></ng-container>
</h1>
<ng-template #_title>
<div *ngIf="title != undefined" class="landingTitle uk-text-break">
<span *ngIf="title['url'] != undefined && title['url'] != null && title['url'] != ''"
class="custom-external">
<a *ngIf="title['name'] != undefined && title['name'] != ''"
href="{{title['url']}}" target="_blank"
[innerHTML]="title['name']">
</a>
<a *ngIf="title['name'] == undefined || title['name'] == ''"
href="{{title['url']}}" target="_blank">
[no title available]
</a>
</span>
<span *ngIf="(title['name'] != undefined && title['name'] != '') &&
(title['url'] == undefined || title['url'] == null || title['url'] == '')"
[innerHTML]="title['name']">
</span>
<span *ngIf="(title['name'] == undefined || title['name'] == '') &&
(title['url'] == undefined || title['url'] == null || title['url'] == '')"
>
[no title available]
</span>
</div>
<div *ngIf="titleName" class="uk-text-break">
<span [innerHTML]="titleName"></span>
</div>
<div *ngIf="!titleName && !title">
<span>No title available</span>
</div>
</ng-template>
`
selector: 'showTitle',
template: `
<h1 [ngClass]="classNames" class="uk-h6">
<ng-container *ngTemplateOutlet="_title;"></ng-container>
</h1>
})
<ng-template #_title>
<div *ngIf="title != undefined" class="landingTitle uk-text-break">
<span *ngIf="title['url'] != undefined && title['url'] != null && title['url'] != ''"
class="custom-external">
<a *ngIf="title['name'] != undefined && title['name'] != ''"
href="{{title['url']}}" target="_blank"
[innerHTML]="title['name']">
</a>
<a *ngIf="title['name'] == undefined || title['name'] == ''"
href="{{title['url']}}" target="_blank">
[no title available]
</a>
</span>
<span *ngIf="(title['name'] != undefined && title['name'] != '') &&
(title['url'] == undefined || title['url'] == null || title['url'] == '')"
[innerHTML]="title['name']">
</span>
<span *ngIf="(title['name'] == undefined || title['name'] == '') &&
(title['url'] == undefined || title['url'] == null || title['url'] == '')">
[no title available]
</span>
</div>
<div *ngIf="titleName" #titleDiv class="uk-text-break multi-line-ellipsis" [ngClass]="isSticky ? 'lines-1' : 'lines-5'">
<span [innerHTML]="titleName" [attr.uk-tooltip]="showTitleTooltip ? 'cls: uk-active uk-width-large' : 'cls: uk-invisible'"
[title]="titleName"></span>
</div>
<div *ngIf="!titleName && !title">
<span>No title available</span>
</div>
</ng-template>
`
})
export class ShowTitleComponent {
@Input() titleName: string;
@Input() title: { [key: string]: string };
@Input() iconClass:string;
@Input() classNames: string = "";
@Input() isSticky: boolean = false;
@ViewChild("titleDiv") titleDiv: ElementRef;
constructor () {}
get showTitleTooltip():boolean {
return !!this.titleDiv && (this.titleDiv.nativeElement.clientHeight >= 5 * 21);
}
}

View File

@ -27,7 +27,7 @@ import {HelperFunctions} from "../../../utils/HelperFunctions.class";
<ul class="uk-list uk-list-divider uk-margin">
<li *ngFor="let result of results.slice((page-1)*pageSize, page*pageSize)">
<result-preview [modal]="modal" [properties]="properties" [hasLink]="false" [result]="getResultPreview(result)"
[isCard]="false" [prevPath]="prevPath"></result-preview>
[isCard]="false" [prevPath]="prevPath" [isDeletedByInferenceModal]="true"></result-preview>
</li>
</ul>
<no-load-paging *ngIf="results.length > pageSize" [type]="type"

View File

@ -1,5 +1,6 @@
<div id="tm-main" class="landing uk-section uk-padding-remove tm-middle">
<div class="tm-main">
<!-- Desktop view -->
<div id="tm-main" class="uk-visible@m landing uk-section uk-padding-remove tm-middle">
<div *ngIf="!isMobile" class="tm-main">
<div class="organization">
<div *ngIf="properties.adminToolsPortalType == 'eosc'" class="eosc-explore-back-search-bar">
<div class="uk-light uk-container uk-container-large uk-padding-small uk-height-1-1">
@ -13,13 +14,12 @@
</div>
<div *ngIf="!showFeedback" class="uk-grid uk-margin-remove-left" uk-grid>
<!-- left column -->
<div id="landing-left-sidebar" *ngIf="organizationInfo" class="uk-visible@s uk-padding-remove-horizontal">
<!-- <div id="landing-left-sidebar" *ngIf="organizationInfo" class="uk-visible@s uk-padding-remove-horizontal">
<div class="uk-flex uk-flex-column uk-flex-right uk-sticky"
uk-sticky="bottom: true" [attr.offset]="offset">
<div class="uk-margin-large-bottom uk-align-center">
<div class="uk-text-meta uk-text-uppercase">Actions</div>
<ul class="uk-list">
<!-- Share -->
<li class="uk-text-center">
<a (click)="openAddThisModal()" [title]="'Share this '+openaireEntities.ORGANIZATION+' in your social networks'"
[attr.uk-tooltip]="'pos: right; cls: uk-active uk-text-small uk-padding-small'">
@ -28,7 +28,6 @@
</span>
</a>
</li>
<!-- Download -->
<li class="uk-text-center"
[title]="'Download reports'"
[attr.uk-tooltip]="'pos: right; cls: uk-active uk-text-small uk-padding-small'">
@ -41,20 +40,14 @@
</ul>
</div>
</div>
</div>
</div> -->
<!-- center/right column -->
<div class="uk-width-expand uk-padding-remove uk-background-default">
<div *ngIf="errorMessage.length > 0 || showLoading" class="uk-container uk-flex uk-flex-center uk-height-viewport uk-position-relative">
<div *ngIf="errorMessage.length > 0" class="uk-alert uk-alert-danger uk-width-2-3 uk-margin-xlarge-top"
role="alert">{{errorMessage}}</div>
<div *ngIf="showLoading" class="uk-position-center">
<loading></loading>
</div>
</div>
<div id="landing-center-content" class="uk-width-expand uk-padding-remove uk-background-default">
<!-- Graph and feedback -->
<ng-template #graph_and_feedback_template>
<div class="uk-flex uk-flex-between uk-flex-wrap uk-margin-small-bottom uk-margin-small-top" [class.uk-invisible]="!organizationInfo">
<div class="uk-container uk-container-xlarge uk-flex uk-flex-between uk-flex-wrap uk-margin-small-top uk-margin-small-bottom" [class.uk-invisible]="!organizationInfo">
<!-- Last Index Info-->
<a href="https://graph.openaire.eu" target="_blank" class="uk-width-1-1 uk-width-auto@l">
<img src="assets/common-assets/openaire-badge-1.png" alt="Powered by OpenAIRE graph" style="height: 15px;">
@ -70,165 +63,206 @@
</div>
</div>
</ng-template>
<div #graph_and_feedback id="graph_and_feedback" class="uk-padding uk-padding-remove-vertical uk-blur-background uk-text-xsmall uk-visible@m"
uk-sticky="bottom: true;" [attr.offset]="graph_offset">
<div #graph_and_feedback id="graph_and_feedback" class="uk-blur-background uk-text-xsmall uk-visible@m"
uk-sticky="bottom: true;" [attr.offset]="graph_offset">
<ng-container *ngTemplateOutlet="graph_and_feedback_template"></ng-container>
</div>
<div class="uk-margin-large-left uk-margin-large-right" [style]="'margin-bottom: '+graph_height+'px'">
<ng-container *ngIf="organizationInfo">
<!-- Main content -->
<div [attr.style]="'margin-top: '+(graph_height? 'calc(40px + 20px - '+graph_height+'px)': '40px')">
<!-- Schema -->
<schema2jsonld *ngIf="organizationInfo" [data]=organizationInfo
[URL]="properties.domain + properties.baseLink+this.properties.searchLinkToOrganization+organizationInfo.relcanId"
type="organization">
</schema2jsonld>
<!-- Actions for mobile viewport -->
<div class="uk-flex uk-flex-right uk-margin-medium-bottom uk-hidden@s">
<div class="uk-margin-small-right">
<a (click)="openAddThisModal()" [title]="'Share this '+openaireEntities.ORGANIZATION+' in your social networks'"
[attr.uk-tooltip]="'pos: right; cls: uk-active uk-text-small uk-padding-small'">
<span class="uk-icon-button uk-icon landing-action-button landing-action-button-portal">
<icon name="share" visuallyHidden="share"></icon>
<div class="uk-container uk-container-xlarge">
<div *ngIf="errorMessage.length > 0 || showLoading" class="uk-container uk-flex uk-flex-center uk-height-viewport uk-position-relative">
<div *ngIf="errorMessage.length > 0" class="uk-alert uk-alert-danger uk-width-2-3 uk-margin-xlarge-top"
role="alert">{{errorMessage}}</div>
<div *ngIf="showLoading" class="uk-position-center">
<loading></loading>
</div>
</div>
<!-- new action bar -->
<div *ngIf="!showLoading && organizationInfo" class="uk-margin-top uk-margin-bottom">
<div class="uk-flex uk-flex-middle uk-flex-center">
<div class="landing-action-bar uk-box-shadow-small uk-margin-bottom">
<div class="uk-grid uk-grid-small uk-flex-between uk-text-xsmall uk-flex-middle uk-grid-divider" uk-grid>
<div *ngIf="organizationInfo?.deletedByInferenceIds" class="uk-width-auto">
<!-- Versions -->
<a (click)="openDeletedByInference()"
class="uk-flex uk-flex-middle uk-flex-center uk-button-link uk-text-bolder">
<icon flex="true" ratio="0.8" name="versions" visuallyHidden="versions"></icon>
<span class="uk-margin-xsmall-left">
View all {{organizationInfo.deletedByInferenceIds.length}} versions
</span>
</a>
</div>
<div [title]="'Download reports'"
[attr.uk-tooltip]="'pos: right; cls: uk-active uk-text-small uk-padding-small'">
<a class="uk-link-text uk-text-bold uk-text-uppercase" (click)="buildFunderOptions(); openDownloadReportsModal()">
<span class="uk-icon-button uk-icon landing-action-button landing-action-button-portal">
<icon name="download" visuallyHidden="download"></icon>
</span>
</a>
</a>
</div>
<div class="uk-width-expand">
<entity-actions [share]="true" [type]="'organization'">
<div>
<a (click)="buildFunderOptions(); openDownloadReportsModal()"
class="uk-flex uk-flex-middle uk-flex-center uk-button-link uk-text-bolder">
<icon flex="true" ratio="0.8" name="download" visuallyHidden="download"></icon>
<span class="uk-margin-xsmall-left">Download</span>
</a>
</div>
</entity-actions>
</div>
</div>
</div>
<!-- Helper -->
<helper *ngIf="pageContents && pageContents['top'] && pageContents['top'].length > 0"
[texts]="pageContents['top']"></helper>
<!-- Versions -->
<span *ngIf="organizationInfo.deletedByInferenceIds" class="uk-text-primary uk-flex uk-flex-middle">
<icon flex="true" ratio="0.8" name="auto_awesome_motion"></icon>
<a (click)="openDeletedByInference()" class="uk-text-primary uk-text-small uk-margin-small-left">
View all {{organizationInfo.deletedByInferenceIds.length}} versions
</a>
</span>
<!-- Landing header -->
<landing-header [properties]="properties" [title]="organizationInfo.title.name"
[subTitle]="(organizationInfo.name
&& organizationInfo.title.name !== organizationInfo.name)?organizationInfo.name:null"
[entityType]="'organization'">
</landing-header>
<!-- Basic info -->
<div class="uk-text-small">
<!-- Web Page -->
<div *ngIf="organizationInfo.title && organizationInfo.title.url" class="uk-margin-small-bottom uk-display-inline-block">
<span class="uk-text-meta">Web page: </span>
<a [href]="organizationInfo.title.url" target="_blank" class="uk-button uk-button-text uk-text-lowercase uk-text-normal custom-external">
{{organizationInfo.title.url}}
</a>
</div>
<!-- Country -->
<div *ngIf="organizationInfo.country && !organizationInfo.country.toLowerCase().includes('unknown')">
<span class="uk-text-meta">Country: </span>{{organizationInfo.country}}
</div>
</div>
</div>
<!-- Tabs section -->
<div id="main-tabs-div" class="uk-sticky uk-blur-background"
uk-sticky="bottom: true; media: @m" [attr.offset]="offset">
<div class="uk-padding uk-padding-remove-horizontal uk-padding-remove-bottom">
<!-- <showTitle *ngIf="stickyHeader" [titleName]="organizationInfo.title.name" classNames="uk-margin-remove-bottom" class="uk-visible@m"></showTitle>-->
<landing-header *ngIf="stickyHeader" class="uk-visible@m"
[properties]="properties" [title]="organizationInfo.title.name"
[subTitle]="(organizationInfo.name
&& organizationInfo.title.name !== organizationInfo.name)?organizationInfo.name:null"
[entityType]="'organization'" isSticky="true">
</landing-header>
<my-tabs (selectedActiveTab)="onSelectActiveTab($event)" [offsetForSticky]="offset" [(isSticky)]="stickyHeader">
<my-tab [active]="true" [tabTitle]="'Funding / ' +openaireEntities.PROJECTS" [tabId]="'projects'"
[tabNumber]="fetchProjects.searchUtils.totalResults > 0 ? fetchProjects.searchUtils.totalResults : ''">
</my-tab>
<my-tab *ngIf="fetchDataproviders && fetchDataproviders.searchUtils.totalResults > 0"
[tabTitle]="openaireEntities.DATASOURCES" [tabId]="'dataProviders'"
[tabNumber]="fetchDataproviders.searchUtils.totalResults">
</my-tab>
<my-tab *ngIf="fetchPublications && fetchPublications.searchUtils.totalResults > 0"
[tabNumber]="fetchPublications.searchUtils.totalResults"
[tabTitle]="openaireEntities.PUBLICATIONS" [tabId]="'publications'">
</my-tab>
<my-tab *ngIf="fetchDatasets && fetchDatasets.searchUtils.totalResults > 0"
[tabNumber]="fetchDatasets.searchUtils.totalResults"
[tabTitle]="openaireEntities.DATASETS" [tabId]="'datasets'">
</my-tab>
<my-tab *ngIf="fetchSoftware && fetchSoftware.searchUtils.totalResults > 0"
[tabNumber]="fetchSoftware.searchUtils.totalResults"
[tabTitle]="openaireEntities.SOFTWARE" [tabId]="'software'">
</my-tab>
<my-tab *ngIf="fetchOrps && fetchOrps.searchUtils.totalResults > 0"
[tabNumber]="fetchOrps.searchUtils.totalResults"
[tabTitle]="openaireEntities.OTHER" [tabId]="'other'">
</my-tab>
</my-tabs>
</div>
</div>
<!-- Tabs content section -->
<div id="landing-sections" class="uk-text-small">
<div id="projects" class="landing-section landing-section-height-auto uk-padding uk-padding-remove-horizontal">
<projectsInModal [fetchProjects]="fetchProjects"
[organizationId]="organizationId" [properties]=properties [prevPath]="prevPath">
</projectsInModal>
</div>
<div *ngIf="fetchDataproviders && fetchDataproviders.searchUtils.totalResults > 0"
id="dataProviders" class="landing-section uk-padding uk-padding-remove-horizontal">
<search-tab [fetch]="fetchDataproviders" resultType="dataprovider"
[params]="getParamsForSearchLink()"
[searchLinkToAdvancedPage]="properties.searchLinkToAdvancedDataProviders"
[properties]="properties" [prevPath]="prevPath">
</search-tab>
</div>
<div *ngIf="fetchPublications && fetchPublications.searchUtils.totalResults > 0"
id="publications" class="landing-section uk-padding uk-padding-remove-horizontal">
<search-tab [fetch]="fetchPublications" resultType="publication"
[params]="getParamsForSearchLink('publications')"
[searchLinkToAdvancedPage]="properties.searchLinkToAdvancedResults"
[properties]="properties" [prevPath]="prevPath">
</search-tab>
</div>
<div *ngIf="fetchDatasets && fetchDatasets.searchUtils.totalResults > 0"
id="datasets" class="landing-section uk-padding uk-padding-remove-horizontal">
<search-tab [fetch]="fetchDatasets" resultType="dataset"
[params]="getParamsForSearchLink('datasets')"
[searchLinkToAdvancedPage]="properties.searchLinkToAdvancedResults"
[properties]="properties" [prevPath]="prevPath">
</search-tab>
</div>
<div *ngIf="fetchSoftware && fetchSoftware.searchUtils.totalResults > 0"
id="software" class="landing-section uk-padding uk-padding-remove-horizontal">
<search-tab [fetch]="fetchSoftware" resultType="software"
[params]="getParamsForSearchLink('software')"
[searchLinkToAdvancedPage]="properties.searchLinkToAdvancedResults"
[properties]="properties" [prevPath]="prevPath">
</search-tab>
</div>
<div *ngIf="fetchOrps && fetchOrps.searchUtils.totalResults > 0"
id="other" class="landing-section uk-padding uk-padding-remove-horizontal">
<search-tab [fetch]="fetchOrps" resultType="other"
[params]="getParamsForSearchLink('other')"
[searchLinkToAdvancedPage]="properties.searchLinkToAdvancedResults"
[properties]="properties" [prevPath]="prevPath">
</search-tab>
</div>
</div>
<div class="uk-text-xsmall uk-hidden@m">
<ng-container *ngTemplateOutlet="graph_and_feedback_template"></ng-container>
</div>
<!-- Helper -->
<helper *ngIf="pageContents && pageContents['bottom'] && pageContents['bottom'].length > 0"
[texts]="pageContents['bottom']">
</helper>
</ng-container>
</div>
</div>
</div>
<div class="uk-margin-left uk-margin-right" [style]="'margin-bottom: '+graph_height+'px'">
<ng-container *ngIf="organizationInfo">
<!-- Main content -->
<div [attr.style]="'margin-top: '+(graph_height? 'calc(40px + 20px - '+graph_height+'px)': '40px')">
<!-- Schema -->
<schema2jsonld *ngIf="organizationInfo" [data]=organizationInfo
[URL]="properties.domain + properties.baseLink+this.properties.searchLinkToOrganization+organizationInfo.relcanId"
type="organization">
</schema2jsonld>
<!-- Actions for mobile viewport -->
<div class="uk-flex uk-flex-right uk-margin-medium-bottom uk-hidden@s">
<div class="uk-margin-small-right">
<a (click)="openAddThisModal()" [title]="'Share this '+openaireEntities.ORGANIZATION+' in your social networks'"
[attr.uk-tooltip]="'pos: right; cls: uk-active uk-text-small uk-padding-small'">
<span class="uk-icon-button uk-icon landing-action-button landing-action-button-portal">
<icon name="share" visuallyHidden="share"></icon>
</span>
</a>
</div>
<div [title]="'Download reports'"
[attr.uk-tooltip]="'pos: right; cls: uk-active uk-text-small uk-padding-small'">
<a class="uk-link-text uk-text-bold uk-text-uppercase" (click)="buildFunderOptions(); openDownloadReportsModal()">
<span class="uk-icon-button uk-icon landing-action-button landing-action-button-portal">
<icon name="download" visuallyHidden="download"></icon>
</span>
</a>
</div>
</div>
<!-- Helper -->
<helper *ngIf="pageContents && pageContents['top'] && pageContents['top'].length > 0"
[texts]="pageContents['top']"></helper>
<!-- Versions -->
<!-- <span *ngIf="organizationInfo.deletedByInferenceIds" class="uk-text-primary uk-flex uk-flex-middle">
<icon flex="true" ratio="0.8" name="auto_awesome_motion"></icon>
<a (click)="openDeletedByInference()" class="uk-text-primary uk-text-small uk-margin-small-left">
View all {{organizationInfo.deletedByInferenceIds.length}} versions
</a>
</span> -->
<!-- Landing header -->
<landing-header [properties]="properties" [title]="organizationInfo.title.name"
[subTitle]="(organizationInfo.name
&& organizationInfo.title.name !== organizationInfo.name)?organizationInfo.name:null"
[entityType]="'organization'" [prevPath]="prevPath">
</landing-header>
<!-- Basic info -->
<div class="uk-text-small">
<!-- Web Page -->
<div *ngIf="organizationInfo.title && organizationInfo.title.url" class="uk-margin-small-bottom uk-display-inline-block">
<span class="uk-text-meta">Web page: </span>
<a [href]="organizationInfo.title.url" target="_blank" class="uk-button uk-button-text uk-text-lowercase uk-text-normal custom-external">
{{organizationInfo.title.url}}
</a>
</div>
<!-- Country -->
<div *ngIf="organizationInfo.country && !organizationInfo.country.toLowerCase().includes('unknown')">
<span class="uk-text-meta">Country: </span>{{organizationInfo.country}}
</div>
</div>
</div>
<!-- Tabs section -->
<div id="main-tabs-div" class="uk-sticky uk-blur-background"
uk-sticky="bottom: true; media: @m" [attr.offset]="offset">
<div class="uk-padding uk-padding-remove-horizontal uk-padding-remove-bottom">
<!-- <showTitle *ngIf="stickyHeader" [titleName]="organizationInfo.title.name" classNames="uk-margin-remove-bottom" class="uk-visible@m"></showTitle>-->
<landing-header [ngClass]="stickyHeader ? 'uk-visible@m' : 'uk-invisible'"
[properties]="properties" [title]="organizationInfo.title.name"
[entityType]="'organization'" isSticky="true" [prevPath]="prevPath">
</landing-header>
<my-tabs (selectedActiveTab)="onSelectActiveTab($event)" [offsetForSticky]="offset" [(isSticky)]="stickyHeader">
<my-tab [active]="true" [tabTitle]="'Funding / ' +openaireEntities.PROJECTS" [tabId]="'projects'"
[tabNumber]="fetchProjects.searchUtils.totalResults > 0 ? fetchProjects.searchUtils.totalResults : ''">
</my-tab>
<my-tab *ngIf="fetchDataproviders && fetchDataproviders.searchUtils.totalResults > 0"
[tabTitle]="openaireEntities.DATASOURCES" [tabId]="'dataProviders'"
[tabNumber]="fetchDataproviders.searchUtils.totalResults">
</my-tab>
<my-tab *ngIf="fetchPublications && fetchPublications.searchUtils.totalResults > 0"
[tabNumber]="fetchPublications.searchUtils.totalResults"
[tabTitle]="openaireEntities.PUBLICATIONS" [tabId]="'publications'">
</my-tab>
<my-tab *ngIf="fetchDatasets && fetchDatasets.searchUtils.totalResults > 0"
[tabNumber]="fetchDatasets.searchUtils.totalResults"
[tabTitle]="openaireEntities.DATASETS" [tabId]="'datasets'">
</my-tab>
<my-tab *ngIf="fetchSoftware && fetchSoftware.searchUtils.totalResults > 0"
[tabNumber]="fetchSoftware.searchUtils.totalResults"
[tabTitle]="openaireEntities.SOFTWARE" [tabId]="'software'">
</my-tab>
<my-tab *ngIf="fetchOrps && fetchOrps.searchUtils.totalResults > 0"
[tabNumber]="fetchOrps.searchUtils.totalResults"
[tabTitle]="openaireEntities.OTHER" [tabId]="'other'">
</my-tab>
</my-tabs>
</div>
</div>
<!-- Tabs content section -->
<div id="landing-sections" class="uk-text-small">
<div id="projects" class="landing-section landing-section-height-auto uk-padding uk-padding-remove-horizontal">
<projectsInModal [fetchProjects]="fetchProjects"
[organizationId]="organizationId" [properties]=properties [prevPath]="prevPath">
</projectsInModal>
</div>
<div *ngIf="fetchDataproviders && fetchDataproviders.searchUtils.totalResults > 0"
id="dataProviders" class="landing-section uk-padding uk-padding-remove-horizontal">
<search-tab [fetch]="fetchDataproviders" resultType="dataprovider"
[params]="getParamsForSearchLink()"
[searchLinkToAdvancedPage]="properties.searchLinkToAdvancedDataProviders"
[properties]="properties" [prevPath]="prevPath">
</search-tab>
</div>
<div *ngIf="fetchPublications && fetchPublications.searchUtils.totalResults > 0"
id="publications" class="landing-section uk-padding uk-padding-remove-horizontal">
<search-tab [fetch]="fetchPublications" resultType="publication"
[params]="getParamsForSearchLink('publications')"
[searchLinkToAdvancedPage]="properties.searchLinkToAdvancedResults"
[properties]="properties" [prevPath]="prevPath">
</search-tab>
</div>
<div *ngIf="fetchDatasets && fetchDatasets.searchUtils.totalResults > 0"
id="datasets" class="landing-section uk-padding uk-padding-remove-horizontal">
<search-tab [fetch]="fetchDatasets" resultType="dataset"
[params]="getParamsForSearchLink('datasets')"
[searchLinkToAdvancedPage]="properties.searchLinkToAdvancedResults"
[properties]="properties" [prevPath]="prevPath">
</search-tab>
</div>
<div *ngIf="fetchSoftware && fetchSoftware.searchUtils.totalResults > 0"
id="software" class="landing-section uk-padding uk-padding-remove-horizontal">
<search-tab [fetch]="fetchSoftware" resultType="software"
[params]="getParamsForSearchLink('software')"
[searchLinkToAdvancedPage]="properties.searchLinkToAdvancedResults"
[properties]="properties" [prevPath]="prevPath">
</search-tab>
</div>
<div *ngIf="fetchOrps && fetchOrps.searchUtils.totalResults > 0"
id="other" class="landing-section uk-padding uk-padding-remove-horizontal">
<search-tab [fetch]="fetchOrps" resultType="other"
[params]="getParamsForSearchLink('other')"
[searchLinkToAdvancedPage]="properties.searchLinkToAdvancedResults"
[properties]="properties" [prevPath]="prevPath">
</search-tab>
</div>
</div>
<div class="uk-text-xsmall uk-hidden@m">
<ng-container *ngTemplateOutlet="graph_and_feedback_template"></ng-container>
</div>
<!-- Helper -->
<helper *ngIf="pageContents && pageContents['bottom'] && pageContents['bottom'].length > 0"
[texts]="pageContents['bottom']">
</helper>
</ng-container>
</div>
</div>
</div>
</div>
</div>
@ -240,6 +274,114 @@
</feedback>
</div>
<!-- Mobile view -->
<div *ngIf="isMobile" class="uk-hidden@m uk-position-relative landing">
<ng-container *ngIf="organizationInfo">
<div *ngIf="mobileContent == 'info'" class="uk-container uk-section">
<landing-header [properties]="properties" [title]="organizationInfo.title.name"
[subTitle]="(organizationInfo.name
&& organizationInfo.title.name !== organizationInfo.name)?organizationInfo.name:null"
[entityType]="'organization'" [prevPath]="prevPath">
</landing-header>
<div class="uk-section uk-margin-top uk-text-large uk-text-empashis uk-text-bold">
<hr>
<ng-container>
<div class="clickable uk-flex uk-flex-middle uk-flex-between" (click)="openFsModal(fsModal, 'Funding / '+openaireEntities.PROJECTS); onSelectActiveTab('projects')">
<span>Funding / {{openaireEntities.PROJECTS}}</span>
<icon name="chevron_right" [ratio]="1.5" [flex]="true"></icon>
</div>
<hr>
</ng-container>
<ng-container *ngIf="fetchDataproviders && fetchDataproviders.searchUtils.totalResults > 0">
<div class="clickable uk-flex uk-flex-middle uk-flex-between"
(click)="openFsModal(fsModal, openaireEntities.DATASOURCES); onSelectActiveTab('dataProviders')">
<span>{{openaireEntities.DATASOURCES}}</span>
<icon name="chevron_right" [ratio]="1.5" [flex]="true"></icon>
</div>
<hr>
</ng-container>
<ng-container *ngIf="fetchPublications && fetchPublications.searchUtils.totalResults > 0">
<div class="clickable uk-flex uk-flex-middle uk-flex-between"
(click)="openFsModal(fsModal, openaireEntities.PUBLICATIONS); onSelectActiveTab('publications')">
<span>{{openaireEntities.PUBLICATIONS}}</span>
<icon name="chevron_right" [ratio]="1.5" [flex]="true"></icon>
</div>
<hr>
</ng-container>
<ng-container *ngIf="fetchDatasets && fetchDatasets.searchUtils.totalResults > 0">
<div class="clickable uk-flex uk-flex-middle uk-flex-between"
(click)="openFsModal(fsModal, openaireEntities.DATASETS); onSelectActiveTab('datasets')">
<span>{{openaireEntities.DATASETS}}</span>
<icon name="chevron_right" [ratio]="1.5" [flex]="true"></icon>
</div>
<hr>
</ng-container>
<ng-container *ngIf="fetchSoftware && fetchSoftware.searchUtils.totalResults > 0">
<div class="clickable uk-flex uk-flex-middle uk-flex-between"
(click)="openFsModal(fsModal, openaireEntities.SOFTWARE); onSelectActiveTab('software')">
<span>{{openaireEntities.SOFTWARE}}</span>
<icon name="chevron_right" [ratio]="1.5" [flex]="true"></icon>
</div>
<hr>
</ng-container>
<ng-container *ngIf="fetchOrps && fetchOrps.searchUtils.totalResults > 0">
<div class="clickable uk-flex uk-flex-middle uk-flex-between"
(click)="openFsModal(fsModal, openaireEntities.OTHER); onSelectActiveTab('other')">
<span>{{openaireEntities.OTHER}}</span>
<icon name="chevron_right" [ratio]="1.5" [flex]="true"></icon>
</div>
<hr>
</ng-container>
</div>
</div>
<div *ngIf="mobileContent == 'actions'" class="uk-container uk-section">
<ng-container *ngIf="organizationInfo?.deletedByInferenceIds">
<div class="clickable uk-button-link uk-flex uk-flex-middle uk-h6 uk-margin-remove uk-padding-small uk-padding-remove-horizontal"
(click)="deleteByInferenceOpened = true; openFsModal(alertModalDeletedByInferenceFS, 'Other versions')">
<icon [flex]="true" name="versions" visuallyHidden="versions"></icon>
<span class="uk-margin-small-left">
View all {{organizationInfo.deletedByInferenceIds.length}} versions
</span>
</div>
<hr class="uk-margin-remove">
</ng-container>
<ng-container>
<div class="clickable uk-button-link uk-flex uk-flex-middle uk-h6 uk-margin-remove uk-padding-small uk-padding-remove-horizontal"
(click)="openFsModal(addThisFsModal, 'Share this '+openaireEntities.ORGANIZATION+' in your social networks')">
<icon [flex]="true" name="share" visuallyHidden="share"></icon>
<span class="uk-margin-small-left">Share</span>
</div>
<hr class="uk-margin-remove">
</ng-container>
<ng-container>
<div class="clickable uk-button-link uk-flex uk-flex-middle uk-h6 uk-margin-remove uk-padding-small uk-padding-remove-horizontal"
(click)="buildFunderOptions(); openFsModal(downloadReportsFsModal, 'Download')">
<icon [flex]="true" name="download" visuallyHidden="download"></icon>
<span class="uk-margin-small-left">Download</span>
</div>
<hr class="uk-margin-remove">
</ng-container>
</div>
<div class="landing-action-bar-mobile uk-background-default">
<div class="uk-container uk-grid uk-flex-middle uk-child-width-1-2 uk-text-xsmall uk-text-meta">
<div>
<a class="uk-flex uk-flex-column uk-flex-middle uk-flex-center uk-link-reset" (click)="mobileContent = 'info'">
<icon name="corporate_fare" type="outlined" [flex]="true" [ratio]="2" [ngClass]="mobileContent == 'info' ? 'uk-text-primary': ''"></icon>
<span>{{openaireEntities.ORGANIZATION}}</span>
</a>
</div>
<div>
<a class="uk-flex uk-flex-column uk-flex-middle uk-flex-center uk-link-reset" (click)="mobileContent = 'actions'">
<icon name="pending" type="outlined" [flex]="true" [ratio]="2" [ngClass]="mobileContent == 'actions' ? 'uk-text-primary': ''"></icon>
<span>Actions</span>
</a>
</div>
</div>
</div>
</ng-container>
</div>
<!-- MODALS -->
<!-- Other versions -->
<modal-alert #AlertModalDeletedByInference *ngIf="organizationInfo && organizationInfo.deletedByInferenceIds" large="true">
@ -259,96 +401,180 @@
<div class="uk-padding-small uk-margin-small-left uk-margin-small-right">
<div class="uk-padding-small uk-padding-remove-vertical">
<div class="uk-grid uk-grid-divider uk-child-width-1-2@m" uk-grid uk-height-match=".subtitle">
<div class="uk-animation-slide-top-small">
<div class="subtitle uk-flex uk-flex-middle">
<span class="uk-text-nowrap">Content report</span>
</div>
<ul class="uk-list uk-margin-remove-bottom" *ngIf="total > 0">
<li [attr.uk-tooltip]="total > 0 ? 'cls: uk-invisible' : 'cls: uk-active'"
title="No report available">
<div class="uk-flex uk-flex-middle uk-button uk-button-link uk-text-normal"
[class]="total > 0 ? '' : 'uk-disabled uk-text-muted'"
(click)="downloadFile(getCSVAffiliated('results'), openaireEntities.RESULTS_FILE + '-report')">
<icon name="download" flex="true" class="uk-margin-small-right"></icon>
all {{openaireEntities.RESULTS}} (CSV)
</div>
</li>
<li [attr.uk-tooltip]="fetchPublications.searchUtils.totalResults > 0 ? 'cls: uk-invisible' : 'cls: uk-active'"
title="No report available">
<div class="uk-flex uk-flex-middle uk-button uk-button-link uk-text-normal"
[class]="fetchPublications.searchUtils.totalResults > 0 ? '' : 'uk-disabled uk-text-muted'"
(click)="downloadFile(getCSVAffiliated('publications'), openaireEntities.PUBLICATIONS_FILE + '-report')">
<icon name="download" flex="true" class="uk-margin-small-right"></icon>
{{openaireEntities.PUBLICATIONS}} (CSV)
</div>
</li>
<li [attr.uk-tooltip]="fetchDatasets.searchUtils.totalResults > 0 ? 'cls: uk-invisible' : 'cls: uk-active'"
title="No report available">
<div class="uk-flex uk-flex-middle uk-button uk-button-link uk-text-normal"
[class]="fetchDatasets.searchUtils.totalResults > 0 ? '' : 'uk-disabled uk-text-muted'"
(click)="downloadFile(getCSVAffiliated('datasets'), openaireEntities.DATASETS_FILE + '-report')">
<icon name="download" flex="true" class="uk-margin-small-right"></icon>
{{openaireEntities.DATASETS}} (CSV)
</div>
</li>
<li [attr.uk-tooltip]="fetchSoftware.searchUtils.totalResults > 0 ? 'cls: uk-invisible' : 'cls: uk-active'"
title="No report available">
<div class="uk-flex uk-flex-middle uk-button uk-button-link uk-text-normal"
[class]="fetchSoftware.searchUtils.totalResults > 0 ? '' : 'uk-disabled uk-text-muted'"
(click)="downloadFile(getCSVAffiliated('software'), openaireEntities.SOFTWARE_FILE + '-report')">
<icon name="download" flex="true" class="uk-margin-small-right"></icon>
{{openaireEntities.SOFTWARE}} (CSV)
</div>
</li>
<li [attr.uk-tooltip]="fetchOrps.searchUtils.totalResults > 0 ? 'cls: uk-invisible' : 'cls: uk-active'"
title="No report available">
<div class="uk-flex uk-flex-middle uk-button uk-button-link uk-text-normal"
[class]="fetchOrps.searchUtils.totalResults > 0 ? '' : 'uk-disabled uk-text-muted'"
(click)="downloadFile(getCSVAffiliated('other'), openaireEntities.OTHER_FILE + '-report')">
<icon name="download" flex="true" class="uk-margin-small-right"></icon>
{{openaireEntities.OTHER}} (CSV)
</div>
</li>
</ul>
<div *ngIf="total == 0" class="uk-text-muted uk-margin-top">
No reports available
</div>
</div>
<div>
<div class="subtitle uk-flex uk-flex-middle">
<span class="uk-text-nowrap">Funder report</span>
<div input type="select" placeholder="Select a funder to download report" inputClass="flat x-small" class="uk-width-1-1 uk-margin-small-left"
[options]="funderOptions" [(value)]="funder" *ngIf="fetchProjects.funders && fetchProjects.funders.length > 0">
</div>
</div>
<div *ngIf="fetchProjects.funders && fetchProjects.funders.length > 0">
<div class="uk-animation-slide-top-small uk-margin-top" *ngIf="funder && funder != ''">
<ul class="uk-list uk-margin-remove-bottom">
<li>
<div class="uk-flex uk-flex-middle uk-button uk-button-link uk-text-normal"
(click)="downloadFile(getFunderProjects(), funder.name + '-'+openaireEntities.PROJECTS_FILE+'-report')">
<icon name="download" flex="true" class="uk-margin-small-right"></icon>
{{openaireEntities.PROJECTS}} (CSV)
</div>
</li>
<li *ngFor="let contentType of contentTypes">
<div class="uk-flex uk-flex-middle uk-button uk-button-link uk-text-normal"
(click)="confirmOpenApplyAll(contentType[0], contentType[2])">
<icon name="download" flex="true" class="uk-margin-small-right"></icon>
{{contentType[1]}} (CSV)
</div>
</li>
</ul>
</div>
</div>
<div *ngIf="!fetchProjects.funders || fetchProjects.funders.length == 0" class="uk-text-muted uk-margin-top">
No reports available
</div>
</div>
<ng-container *ngTemplateOutlet="downloadOptions"></ng-container>
</div>
</div>
</div>
</modal-alert>
<modal-alert #AlertModalApplyAll (alertOutput)="confirmCloseApplyAll()"></modal-alert>
<modal-alert #AlertModalCsvError></modal-alert>
<modal-loading></modal-loading>
<modal-loading [isMobile]="isMobile" classTitle="uk-tile-default uk-border-bottom"></modal-loading>
<ng-template #downloadOptions>
<div class="uk-animation-slide-top-small">
<div class="subtitle uk-flex uk-flex-middle">
<span class="uk-text-nowrap">Content report</span>
</div>
<ul class="uk-list uk-margin-remove-bottom" *ngIf="total > 0">
<li [attr.uk-tooltip]="total > 0 ? 'cls: uk-invisible' : 'cls: uk-active'"
title="No report available">
<div class="uk-flex uk-flex-middle uk-button uk-button-link uk-text-normal"
[class]="total > 0 ? '' : 'uk-disabled uk-text-muted'"
(click)="downloadFile(getCSVAffiliated('results'), openaireEntities.RESULTS_FILE + '-report')">
<icon name="download" flex="true" class="uk-margin-small-right"></icon>
all {{openaireEntities.RESULTS}} (CSV)
</div>
</li>
<li [attr.uk-tooltip]="fetchPublications.searchUtils.totalResults > 0 ? 'cls: uk-invisible' : 'cls: uk-active'"
title="No report available">
<div class="uk-flex uk-flex-middle uk-button uk-button-link uk-text-normal"
[class]="fetchPublications.searchUtils.totalResults > 0 ? '' : 'uk-disabled uk-text-muted'"
(click)="downloadFile(getCSVAffiliated('publications'), openaireEntities.PUBLICATIONS_FILE + '-report')">
<icon name="download" flex="true" class="uk-margin-small-right"></icon>
{{openaireEntities.PUBLICATIONS}} (CSV)
</div>
</li>
<li [attr.uk-tooltip]="fetchDatasets.searchUtils.totalResults > 0 ? 'cls: uk-invisible' : 'cls: uk-active'"
title="No report available">
<div class="uk-flex uk-flex-middle uk-button uk-button-link uk-text-normal"
[class]="fetchDatasets.searchUtils.totalResults > 0 ? '' : 'uk-disabled uk-text-muted'"
(click)="downloadFile(getCSVAffiliated('datasets'), openaireEntities.DATASETS_FILE + '-report')">
<icon name="download" flex="true" class="uk-margin-small-right"></icon>
{{openaireEntities.DATASETS}} (CSV)
</div>
</li>
<li [attr.uk-tooltip]="fetchSoftware.searchUtils.totalResults > 0 ? 'cls: uk-invisible' : 'cls: uk-active'"
title="No report available">
<div class="uk-flex uk-flex-middle uk-button uk-button-link uk-text-normal"
[class]="fetchSoftware.searchUtils.totalResults > 0 ? '' : 'uk-disabled uk-text-muted'"
(click)="downloadFile(getCSVAffiliated('software'), openaireEntities.SOFTWARE_FILE + '-report')">
<icon name="download" flex="true" class="uk-margin-small-right"></icon>
{{openaireEntities.SOFTWARE}} (CSV)
</div>
</li>
<li [attr.uk-tooltip]="fetchOrps.searchUtils.totalResults > 0 ? 'cls: uk-invisible' : 'cls: uk-active'"
title="No report available">
<div class="uk-flex uk-flex-middle uk-button uk-button-link uk-text-normal"
[class]="fetchOrps.searchUtils.totalResults > 0 ? '' : 'uk-disabled uk-text-muted'"
(click)="downloadFile(getCSVAffiliated('other'), openaireEntities.OTHER_FILE + '-report')">
<icon name="download" flex="true" class="uk-margin-small-right"></icon>
{{openaireEntities.OTHER}} (CSV)
</div>
</li>
</ul>
<div *ngIf="total == 0" class="uk-text-muted uk-margin-top">
No reports available
</div>
</div>
<div [ngClass]="isMobile ? 'uk-margin-large-top' : ''">
<div class="subtitle" [ngClass]="isMobile ? '' : 'uk-flex uk-flex-middle'">
<span class="uk-text-nowrap">Funder report</span>
<div input type="select" placeholder="Select a funder to download report" inputClass="flat x-small"
class="uk-width-1-1" [ngClass]="isMobile ? 'uk-margin-top' : 'uk-margin-small-left'"
[options]="funderOptions" [(value)]="funder" *ngIf="fetchProjects.funders && fetchProjects.funders.length > 0">
</div>
</div>
<div *ngIf="fetchProjects.funders && fetchProjects.funders.length > 0">
<div class="uk-animation-slide-top-small uk-margin-top" *ngIf="funder && funder != ''">
<ul class="uk-list uk-margin-remove-bottom">
<li>
<div class="uk-flex uk-flex-middle uk-button uk-button-link uk-text-normal"
(click)="downloadFile(getFunderProjects(), funder.name + '-'+openaireEntities.PROJECTS_FILE+'-report')">
<icon name="download" flex="true" class="uk-margin-small-right"></icon>
{{openaireEntities.PROJECTS}} (CSV)
</div>
</li>
<li *ngFor="let contentType of contentTypes">
<div class="uk-flex uk-flex-middle uk-button uk-button-link uk-text-normal"
(click)="confirmOpenApplyAll(contentType[0], contentType[2])">
<icon name="download" flex="true" class="uk-margin-small-right"></icon>
{{contentType[1]}} (CSV)
</div>
</li>
</ul>
</div>
</div>
<div *ngIf="!fetchProjects.funders || fetchProjects.funders.length == 0" class="uk-text-muted uk-margin-top">
No reports available
</div>
</div>
</ng-template>
<!--Mobile actions-->
<fs-modal #AlertModalDeletedByInferenceFS *ngIf="organizationInfo && organizationInfo.deletedByInferenceIds" classTitle="uk-tile-default uk-border-bottom">
<organizationsDeletedByInference *ngIf="deleteByInferenceOpened"
[id]="organizationInfo.objIdentifier"
[ids]="organizationInfo.deletedByInferenceIds"
[type]="'organizations'" [prevPath]="prevPath">
</organizationsDeletedByInference>
</fs-modal>
<!-- Share -->
<fs-modal *ngIf="organizationInfo" #addThisFsModal classTitle="uk-tile-default uk-border-bottom" classBody="uk-flex uk-flex-center uk-flex-middle">
<addThis></addThis>
</fs-modal>
<fs-modal *ngIf="organizationInfo" #downloadReportsFsModal classTitle="uk-tile-default uk-border-bottom">
<ng-container *ngTemplateOutlet="downloadOptions"></ng-container>
</fs-modal>
<fs-modal #AlertFsModalApplyAll classTitle="uk-tile-default uk-border-bottom">
<div class="uk-margin-large-top">
<div class="uk-text-center">Do you wish to download a CSV file? Note that this process may take a while.</div>
<div class="uk-margin-medium-top uk-flex uk-flex-middle uk-flex-center">
<button class="uk-button uk-button-primary" (click)="confirmCloseApplyAll()">Yes</button>
<button class="uk-button uk-button-default uk-margin-left" (click)="alertFsApplyAll.cancel()">No</button>
</div>
</div>
</fs-modal>
<fs-modal #AlertFsModalCsvError classTitle="uk-tile-default uk-border-bottom">
<div class="uk-margin-large-top uk-text-center">There was an error in csv downloading. Please try again later.</div>
</fs-modal>
<fs-modal *ngIf="isMobile" #fsModal classTitle="uk-tile-default uk-border-bottom">
<div *ngIf="activeTab == 'projects'" class="landing-section landing-section-height-auto uk-padding uk-padding-remove-horizontal">
<projectsInModal [fetchProjects]="fetchProjects"
[organizationId]="organizationId" [properties]=properties [prevPath]="prevPath">
</projectsInModal>
</div>
<div *ngIf="activeTab == 'dataProviders' && fetchDataproviders && fetchDataproviders.searchUtils.totalResults > 0"
class="landing-section uk-padding uk-padding-remove-horizontal">
<search-tab [fetch]="fetchDataproviders" resultType="dataprovider"
[params]="getParamsForSearchLink()"
[searchLinkToAdvancedPage]="properties.searchLinkToAdvancedDataProviders"
[properties]="properties" [isMobile]="true" [prevPath]="prevPath">
</search-tab>
</div>
<div *ngIf="activeTab == 'publications' && fetchPublications && fetchPublications.searchUtils.totalResults > 0"
class="landing-section uk-padding uk-padding-remove-horizontal">
<search-tab [fetch]="fetchPublications" resultType="publication"
[params]="getParamsForSearchLink('publications')"
[searchLinkToAdvancedPage]="properties.searchLinkToAdvancedResults"
[properties]="properties" [isMobile]="true" [prevPath]="prevPath">
</search-tab>
</div>
<div *ngIf="activeTab == 'datasets' && fetchDatasets && fetchDatasets.searchUtils.totalResults > 0"
class="landing-section uk-padding uk-padding-remove-horizontal">
<search-tab [fetch]="fetchDatasets" resultType="dataset"
[params]="getParamsForSearchLink('datasets')"
[searchLinkToAdvancedPage]="properties.searchLinkToAdvancedResults"
[properties]="properties" [isMobile]="true" [prevPath]="prevPath">
</search-tab>
</div>
<div *ngIf="activeTab == 'software' && fetchSoftware && fetchSoftware.searchUtils.totalResults > 0"
class="landing-section uk-padding uk-padding-remove-horizontal">
<search-tab [fetch]="fetchSoftware" resultType="software"
[params]="getParamsForSearchLink('software')"
[searchLinkToAdvancedPage]="properties.searchLinkToAdvancedResults"
[properties]="properties" [isMobile]="true" [prevPath]="prevPath">
</search-tab>
</div>
<div *ngIf="activeTab == 'other' && fetchOrps && fetchOrps.searchUtils.totalResults > 0"
class="landing-section uk-padding uk-padding-remove-horizontal">
<search-tab [fetch]="fetchOrps" resultType="other"
[params]="getParamsForSearchLink('other')"
[searchLinkToAdvancedPage]="properties.searchLinkToAdvancedResults"
[properties]="properties" [isMobile]="true" [prevPath]="prevPath">
</search-tab>
</div>
</fs-modal>

View File

@ -26,6 +26,8 @@ import {Subscriber} from "rxjs";
import {properties} from "../../../../environments/environment";
import {OpenaireEntities} from '../../utils/properties/searchFields';
import {Option} from '../../sharedComponents/input/input.component';
import {LayoutService} from '../../dashboard/sharedComponents/sidebar/layout.service';
import {FullScreenModalComponent} from "../../utils/modal/full-screen-modal/full-screen-modal.component";
declare var ResizeObserver;
@ -71,17 +73,23 @@ export class OrganizationComponent {
// Active tab variable for responsiveness
public activeTab: string = "";
@ViewChild('fsModal') fsModal: FullScreenModalComponent;
@ViewChild('downloadReportsModal') downloadReportsModal;
@ViewChild('downloadReportsModal') downloadReportsModal;
@ViewChild('downloadReportsFsModal') downloadReportsFsModal: FullScreenModalComponent;
// @ViewChild('downloadReportModal') downloadReportModal;
// @ViewChild('downloadFunderReportModal') downloadFunderReportModal;
@ViewChild('addThisModal') addThisModal;
@ViewChild('addThisFsModal') addThisFsModal: FullScreenModalComponent;
@ViewChild(ModalLoading) loading: ModalLoading;
// Alert box when CSV: Project Publications for a funder is requested
@ViewChild('AlertModalApplyAll') alertApplyAll;
@ViewChild('AlertFsModalApplyAll') alertFsApplyAll;
// Alert box when something is wrong with CSV requests
@ViewChild('AlertModalCsvError') alertCsvError;
@ViewChild('AlertFsModalCsvError') alertFsCsvError;
public routerHelper: RouterHelper = new RouterHelper();
public errorCodes: ErrorCodes = new ErrorCodes();
@ -121,10 +129,13 @@ export class OrganizationComponent {
public feedbackFields: string [] = ['Name', 'Country', 'Other'];
@ViewChild('AlertModalDeletedByInference') alertModalDeletedByInference;
@ViewChild('AlertModalDeletedByInferenceFS') alertModalDeletedByInferenceFS;
// @ViewChild('projectsModal') projectsModal;
public deleteByInferenceOpened: boolean = false;
public isMobile: boolean = false;
public mobileContent: "info" | "actions" = "info";
public viewAllMobile: string = "";
constructor(private element: ElementRef,
private _organizationService: OrganizationService,
@ -141,7 +152,8 @@ export class OrganizationComponent {
private seoService: SEOService,
private _location: Location,
private indexInfoService: IndexInfoService,
private cdr: ChangeDetectorRef) {
private cdr: ChangeDetectorRef,
private layoutService: LayoutService) {
this.fetchProjects = new FetchProjects(this._searchProjectsService);
this.fetchDataproviders = new FetchDataproviders(this._searchDataprovidersService);
this.fetchPublications = new FetchResearchResults(this._searchResearchResultsService);
@ -151,19 +163,21 @@ export class OrganizationComponent {
}
ngOnInit() {
this.properties = properties;
if (typeof document !== 'undefined') {
this.subscriptions.push(this.indexInfoService.getLastIndexDate(this.properties).subscribe(lastIndexUpdate => {
if (lastIndexUpdate) {
this.indexUpdateDate = new Date(lastIndexUpdate);
}
}));
}
//this.getDivContents();
this.getPageContents();
this.updateUrl(this.properties.domain + this.properties.baseLink + this._router.url);
this.seoService.createLinkForCanonicalURL(this.properties.domain +this.properties.baseLink + this._router.url);
this.subscriptions.push(this.layoutService.isMobile.subscribe(isMobile => {
this.isMobile = isMobile;
}));
this.properties = properties;
if (typeof document !== 'undefined') {
this.subscriptions.push(this.indexInfoService.getLastIndexDate(this.properties).subscribe(lastIndexUpdate => {
if (lastIndexUpdate) {
this.indexUpdateDate = new Date(lastIndexUpdate);
}
}));
}
//this.getDivContents();
this.getPageContents();
this.updateUrl(this.properties.domain + this.properties.baseLink + this._router.url);
this.seoService.createLinkForCanonicalURL(this.properties.domain +this.properties.baseLink + this._router.url);
this.subscriptions.push(this.route.queryParams.subscribe(params => {
this.organizationInfo = null;
@ -266,7 +280,8 @@ export class OrganizationComponent {
this.subscriptions.forEach(subscription => {
if (subscription instanceof Subscriber) {
subscription.unsubscribe();
} else if (subscription instanceof (ResizeObserver || IntersectionObserver)) {
} else if ((typeof ResizeObserver != 'undefined' && subscription instanceof ResizeObserver) ||
(typeof IntersectionObserver != 'undefined' && subscription instanceof IntersectionObserver)) {
subscription.disconnect();
}
});
@ -628,13 +643,19 @@ export class OrganizationComponent {
}
public confirmOpenApplyAll(contentType: string, contentFileName: string) {
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();
if(this.isMobile) {
this.alertFsApplyAll.title = "CSV FILE";
this.alertFsApplyAll.okButton = false;
this.alertFsApplyAll.open();
} else {
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.funderId = this.funder.id;
this.funderCount = this.funder.number;
this.funderContentType = contentType;
@ -646,12 +667,19 @@ export class OrganizationComponent {
}
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();
if(this.isMobile) {
this.alertFsCsvError.okButton = true;
this.alertFsCsvError.okButtonText = "OK";
this.alertFsCsvError.title = "ERROR DOWNLOADING CSV FILE";
this.alertFsCsvError.open();
} else {
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 {
@ -686,7 +714,7 @@ export class OrganizationComponent {
}
openDownloadReportsModal() {
this.funder = this.fetchProjects.funders[0];
// this.funder = this.fetchProjects.funders[0];
this.downloadReportsModal.cancelButton = false;
this.downloadReportsModal.okButton = false;
this.downloadReportsModal.alertTitle = "Download";
@ -808,7 +836,7 @@ export class OrganizationComponent {
for(let funder of this.fetchProjects.funders) {
this.funderOptions.push({"label": funder.name, "value": funder});
}
this.funder = this.funderOptions[0];
this.funder = this.funderOptions[0].value;
}
}
@ -816,11 +844,18 @@ export class OrganizationComponent {
HelperFunctions.scroll();
}
public openFsModal(fsModal: FullScreenModalComponent, title: string) {
fsModal.title = title;
fsModal.okButton = false;
fsModal.stayOpenInBack = true;
fsModal.open();
}
public get eoscBackLink() {
if(this.prevPath && this.referrer && ((this.referrer == "https://eosc-search-service.grid.cyfronet.pl/") || (this.referrer == "https://beta.search.marketplace.eosc-portal.eu/") || (this.referrer == "https://search.marketplace.eosc-portal.eu/"))) {
return this.referrer+this.prevPath;
if (this.prevPath && this.referrer && ((this.referrer == "https://eosc-search-service.grid.cyfronet.pl/") || (this.referrer == "https://beta.search.marketplace.eosc-portal.eu/") || (this.referrer == "https://search.marketplace.eosc-portal.eu/"))) {
return this.referrer + this.prevPath;
} else {
return "https://"+(this.properties.environment == "beta" ? "beta." : "")+"search.marketplace.eosc-portal.eu/";
return "https://" + (this.properties.environment == "beta" ? "beta." : "") + "search.marketplace.eosc-portal.eu/";
}
}
}

View File

@ -30,7 +30,10 @@ import {LoadingModule} from '../../utils/loading/loading.module';
import {IconsModule} from '../../utils/icons/icons.module';
import {InputModule} from '../../sharedComponents/input/input.module';
import {IconsService} from '../../utils/icons/icons.service';
import {graph} from "../../utils/icons/icons";
import {graph, versions} from "../../utils/icons/icons";
import {FullScreenModalModule} from "../../utils/modal/full-screen-modal/full-screen-modal.module";
import {EGIDataTransferModule} from "../../utils/dataTransfer/transferData.module";
import {EntityActionsModule} from "../../utils/entity-actions/entity-actions.module";
@NgModule({
@ -48,7 +51,7 @@ import {graph} from "../../utils/icons/icons";
Schema2jsonldModule, SEOServiceModule, HelperModule,
OrganizationsDeletedByInferenceModule, LandingHeaderModule, FeedbackModule,
MatSelectModule,
TabsModule, SearchTabModule, LoadingModule, IconsModule, InputModule
TabsModule, SearchTabModule, LoadingModule, IconsModule, InputModule, FullScreenModalModule, EGIDataTransferModule, EntityActionsModule
],
declarations: [
OrganizationComponent,
@ -60,6 +63,6 @@ import {graph} from "../../utils/icons/icons";
})
export class OrganizationModule {
constructor(private iconsService: IconsService) {
this.iconsService.registerIcons([graph]);
this.iconsService.registerIcons([graph, versions]);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
import {ChangeDetectorRef, Component, ElementRef, HostListener, Input, ViewChild} from '@angular/core';
import {ChangeDetectorRef, Component, ElementRef, Input, ViewChild} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import {Meta, Title} from '@angular/platform-browser';
@ -25,10 +25,14 @@ import {StringUtils} from "../../utils/string-utils.class";
import {ResultPreview} from "../../utils/result-preview/result-preview";
import {SearchResult} from "../../utils/entities/searchResult";
import {IndexInfoService} from "../../utils/indexInfo.service";
import {Subscriber} from "rxjs";
import {Subscriber, Subscription, zip} from "rxjs";
import {properties} from "../../../../environments/environment";
import {Option} from "../../sharedComponents/input/input.component";
import {OpenaireEntities} from "../../utils/properties/searchFields";
import {MetricsService} from '../../services/metrics.service';
import {NumberUtils} from '../../utils/number-utils.class';
import {LayoutService} from '../../dashboard/sharedComponents/sidebar/layout.service';
import {FullScreenModalComponent} from '../../utils/modal/full-screen-modal/full-screen-modal.component';
declare var ResizeObserver;
@ -51,9 +55,13 @@ export class ProjectComponent {
public metricsClicked: boolean;
public viewsFrameUrl: string;
public downloadsFrameUrl: string;
public totalViews: number;
public totalDownloads: number;
public pageViews: number;
/** @deprecated*/
public totalViews: number = null;
/** @deprecated*/
public totalDownloads: number = null;
public hasViews: boolean = false;
public hasDownloads: boolean = false;
// public pageViews: number;
// Statistics tab variables
public statsClicked: boolean;
@ -86,8 +94,11 @@ export class ProjectComponent {
// @ViewChild('statisticsModal') statisticsModal;
// @ViewChild('linkProjectModal') linkProjectModal;
@ViewChild('embedResultsModal') embedResultsModal;
@ViewChild('embedResultsFsModal') embedResultsFsModal: FullScreenModalComponent;
@ViewChild('downloadReportModal') downloadReportModal;
@ViewChild('addThisModal') addThisModal
@ViewChild('downloadReportFsModal') downloadReportFsModal: FullScreenModalComponent;
@ViewChild('addThisModal') addThisModal;
@ViewChild('addThisFsModal') addThisFsModal: FullScreenModalComponent;
// Request results for publications, research data and software only the one time (first time tab is clicked)
private reloadPublications: boolean = true;
@ -163,9 +174,23 @@ export class ProjectComponent {
// public shouldSticky: boolean = true;
subscriptions = [];
private sub: Subscription;
properties: EnvProperties;
public openaireEntities = OpenaireEntities;
public isMobile: boolean = false;
public mobileContent: "info" | "metrics" | "actions" = "info";
public tabMobile: string = "";
public viewAllMobile: string = "";
// Full screen modals for small screens (mobile)
@ViewChild('summaryFsModal') summaryFsModal: FullScreenModalComponent;
@ViewChild('publicationsFsModal') publicationsFsModal: FullScreenModalComponent;
@ViewChild('datasetsFsModal') datasetsFsModal: FullScreenModalComponent;
@ViewChild('softwareFsModal') softwareFsModal: FullScreenModalComponent;
@ViewChild('otherFsModal') otherFsModal: FullScreenModalComponent;
@ViewChild('dmpsFsModal') dmpsFsModal: FullScreenModalComponent;
@ViewChild('statisticsFsModal') statisticsFsModal: FullScreenModalComponent;
constructor(private route: ActivatedRoute,
private _router: Router,
private _location: Location,
@ -179,24 +204,26 @@ export class ProjectComponent {
private _reportsService: ReportsService,
private htmlService: HtmlProjectReportService,
private indexInfoService: IndexInfoService,
private cdr: ChangeDetectorRef) {}
private metricsService: MetricsService,
private cdr: ChangeDetectorRef,
private layoutService: LayoutService) {}
ngOnInit() {
this.properties = properties;
if (typeof document !== 'undefined') {
this.subscriptions.push(this.indexInfoService.getLastIndexDate(this.properties).subscribe(lastIndexUpdate => {
if (lastIndexUpdate) {
this.indexUpdateDate = new Date(lastIndexUpdate);
}
}));
}
//this.getDivContents();
this.getPageContents();
this.updateUrl(this.properties.domain + this.properties.baseLink + this._router.url);
this.seoService.createLinkForCanonicalURL(this.properties.domain +this.properties.baseLink + this._router.url);
this.subscriptions.push(this.layoutService.isMobile.subscribe(isMobile => {
this.isMobile = isMobile;
}));
this.properties = properties;
if (typeof document !== 'undefined') {
this.subscriptions.push(this.indexInfoService.getLastIndexDate(this.properties).subscribe(lastIndexUpdate => {
if (lastIndexUpdate) {
this.indexUpdateDate = new Date(lastIndexUpdate);
}
}));
}
//this.getDivContents();
this.getPageContents();
this.updateUrl(this.properties.domain + this.properties.baseLink + this._router.url);
this.seoService.createLinkForCanonicalURL(this.properties.domain +this.properties.baseLink + this._router.url);
this.subscriptions.push(this.route.queryParams.subscribe(params => {
this.stickyHeader = false;
this.metricsClicked = false;
@ -353,7 +380,8 @@ export class ProjectComponent {
this.subscriptions.forEach(subscription => {
if (subscription instanceof Subscriber) {
subscription.unsubscribe();
} else if (subscription instanceof (ResizeObserver || IntersectionObserver)) {
} else if ((typeof ResizeObserver != 'undefined' && subscription instanceof ResizeObserver) ||
(typeof IntersectionObserver != 'undefined' && subscription instanceof IntersectionObserver)) {
subscription.disconnect();
}
});
@ -510,6 +538,23 @@ export class ProjectComponent {
startDate: this.projectInfo.startDate,
endDate: this.projectInfo.endDate
};
this.hasViews = false;
this.hasDownloads = false;
// ensure that if the API call to index does not have metrics, we get them from old metrics service call
if(this.projectInfo && !this.projectInfo.measure) {
this.getMetrics();
} else if(this.projectInfo && this.projectInfo.measure && this.projectInfo.measure.counts) {
this.projectInfo.measure.counts.forEach(measure => {
if(measure.name == "views" && measure.value > 0) {
this.hasViews = true;
}
if(measure.name == "downloads" && measure.value > 0) {
this.hasDownloads = true;
}
})
}
//old
// this.viewsFrameUrl = this.properties.framesAPIURL + '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":200,"sort":"xaxis","xStyle":{"r":-30,"s":"6","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';
//
@ -567,11 +612,35 @@ export class ProjectComponent {
public metricsResults($event) {
this.totalViews = $event.totalViews;
this.totalDownloads = $event.totalDownloads;
this.pageViews = $event.pageViews;
// this.pageViews = $event.pageViews;
}
private getMetrics() {
let obs;
obs = zip(this.metricsService.getMetricsNumber(this.projectId, "usagestats.projects.views", this.properties),
this.metricsService.getMetricsNumber(this.projectId, "usagestats.projects.downloads", this.properties));
this.sub = obs.subscribe(data => {
if((data[0] && data[0] > 0) || (data[1] && data[1] > 0)) {
this.projectInfo.measure = {counts: []};
if(data[0] && data[0] > 0) {
this.projectInfo.measure.counts.push({name: 'views', order: 0, icon: 'visibility', value: data[0]});
this.hasViews = true;
}
if(data[1] && data[1] > 0) {
this.projectInfo.measure.counts.push({name: 'downloads', order: 1, icon: 'downloads', value: data[1]});
this.hasDownloads = true;
}
this.cdr.detectChanges();
}
// this.totalViews = data[0];
// this.totalDownloads = data[1];
});
}
public get hasMetrics(): boolean {
return !(this.totalViews != null && this.totalDownloads != null && this.pageViews != null) || this.totalViews > 0 || this.totalDownloads > 0||this.pageViews > 0;
// return !(this.totalViews != null && this.totalDownloads != null) || this.totalViews > 0 || this.totalDownloads > 0;
return this.projectInfo.measure?.counts?.length > 0;
}
public viewAllOrganizationsClick() {
@ -583,6 +652,13 @@ export class ProjectComponent {
}
}
public viewAllOrganizationsMobileClicked() {
this.summaryFsModal.title += " - Partners";
this.summaryFsModal.back = true;
this.lessBtnOrganizations = true;
this.viewAllMobile = "organizations";
}
public openOrganizationsModal() {
this.organizationsModal.cancelButton = false;
this.organizationsModal.okButton = false;
@ -971,12 +1047,56 @@ export class ProjectComponent {
];
}
public viewAllDescriptionClicked() {
if(this.isMobile) {
this.summaryFsModal.title += " - Description";
this.summaryFsModal.back = true;
this.viewAllMobile = "description";
} else {
this.openDescriptionModal();
}
}
public openDescriptionModal() {
this.descriptionModal.alertFooter = false;
this.descriptionModal.alertTitle = "Description";
this.descriptionModal.open();
}
public clickedUsageMetrics() {
setTimeout( () => {
this.metricsClicked = true;
});
}
public formatNumber(num: number | string) {
let formatted = NumberUtils.roundNumber(+num);
return formatted.number + formatted.size;
}
public cancelSummaryClicked() {
this.summaryFsModal.title = "Summary";
this.summaryFsModal.back = false;
this.lessBtnOrganizations = false;
this.viewAllMobile = "";
}
public openFsModal(fsModal: FullScreenModalComponent, title: string) {
fsModal.title = title;
fsModal.okButton = false;
fsModal.stayOpenInBack = true;
fsModal.open();
this.tabMobile = title;
}
public getMetricsTooltip(value: string) {
if (value == 'downloads') {
return "<div class='uk-flex uk-flex-middle'><a href='https://usagecounts.openaire.eu/' target='_blank'><img src='assets/common-assets/logo-small-usage-counts.png' loading='lazy' alt='OpenAIRE UsageCounts'></a><span class='uk-text-uppercase uk-margin-small-left'>Downloads provided by <a href='https://usagecounts.openaire.eu/' target='_blank' class='uk-link-reset'><strong>UsageCounts</strong></a></div>";
} else if (value == 'views') {
return "<div class='uk-flex uk-flex-middle'><a href='https://usagecounts.openaire.eu/' target='_blank'><img class='uk-margin-small-right' src='assets/common-assets/logo-small-usage-counts.png' loading='lazy' alt='OpenAIRE UsageCounts'></a><span class='uk-text-uppercase uk-margin-small-left'>Views provided by <a href='https://usagecounts.openaire.eu/' target='_blank' class='uk-link-reset'><strong>UsageCounts</strong></a></div>";
}
}
public addEoscPrevInParams(obj) {
if(properties.adminToolsPortalType == "eosc" && this.prevPath) {
let splitted: string[] = this.prevPath.split("?");

View File

@ -3,7 +3,7 @@ import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {FormsModule} from '@angular/forms';
import {RouterModule} from '@angular/router';
import { MatSelectModule } from "@angular/material/select";
import {MatSelectModule} from "@angular/material/select";
import {ProjectComponent} from './project.component';
import {ProjectServiceModule} from './projectService.module';
@ -31,7 +31,11 @@ import {LoadingModule} from "../../utils/loading/loading.module";
import {IconsModule} from "../../utils/icons/icons.module";
import {InputModule} from "../../sharedComponents/input/input.module";
import {IconsService} from "../../utils/icons/icons.service";
import {graph, link} from "../../utils/icons/icons";
import {graph, link, link_to, open_access} from "../../utils/icons/icons";
import {FullScreenModalModule} from '../../utils/modal/full-screen-modal/full-screen-modal.module';
import {SafeHtmlPipeModule} from '../../utils/pipes/safeHTMLPipe.module';
import {EGIDataTransferModule} from "../../utils/dataTransfer/transferData.module";
import {EntityActionsModule} from "../../utils/entity-actions/entity-actions.module";
@NgModule({
imports: [
@ -41,7 +45,8 @@ import {graph, link} from "../../utils/icons/icons";
SearchResearchResultsServiceModule, ProjectServiceModule,
Schema2jsonldModule, SEOServiceModule, HelperModule,
LandingHeaderModule, MatSelectModule, FeedbackModule, AltMetricsModule,
TabsModule, SearchTabModule, LoadingModule, IconsModule, InputModule
TabsModule, SearchTabModule, LoadingModule, IconsModule, InputModule,
FullScreenModalModule, SafeHtmlPipeModule, EGIDataTransferModule, EntityActionsModule
],
declarations: [
ProjectComponent
@ -55,6 +60,6 @@ import {graph, link} from "../../utils/icons/icons";
})
export class ProjectModule {
constructor(private iconsService: IconsService) {
this.iconsService.registerIcons([link, graph])
this.iconsService.registerIcons([link, graph, link_to, open_access])
}
}

View File

@ -236,6 +236,10 @@ export class ProjectService {
this.projectInfo.urlInfo = "Detailed project information (CORDIS)";
}
if (data[0]?.measure) {
this.projectInfo.measure = this.parsingFunctions.parseMeasures(data[0].measure);
}
return this.projectInfo;
}

View File

@ -24,10 +24,11 @@ import {HelperFunctions} from "../../../utils/HelperFunctions.class";
[page]="page" [pageSize]="pageSize"
[totalResults]="results.length">
</no-load-paging>
<ul class="uk-list uk-list-divider uk-margin">
<ul class="uk-list uk-margin">
<li *ngFor="let result of results.slice((page-1)*pageSize, page*pageSize)">
<result-preview [modal]="modal" [properties]="properties" [hasLink]="false" [result]="getResultPreview(result)"
[showOrcid]="false" [isCard]="false" [prevPath]="prevPath"></result-preview>
[showOrcid]="false" [isCard]="false" [prevPath]="prevPath" [showInline]="true"
[isDeletedByInferenceModal]="true"></result-preview>
</li>
</ul>
<no-load-paging *ngIf="results.length > pageSize" [type]="type"

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
import {ChangeDetectorRef, Component, ElementRef, EventEmitter, HostListener, Input, Output, ViewChild} from '@angular/core';
import {ChangeDetectorRef, Component, ElementRef, Input, ViewChild} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import {Meta, Title} from '@angular/platform-browser';
@ -18,13 +18,16 @@ import {IndexInfoService} from "../../utils/indexInfo.service";
import {Identifier, StringUtils} from "../../utils/string-utils.class";
import {properties} from "../../../../environments/environment";
import {ISVocabulariesService} from "../../utils/staticAutoComplete/ISVocabularies.service";
import {forkJoin, Observable, Subscription, zip} from "rxjs";
import {AnnotationComponent} from "../annotation/annotation.component";
import {Subscription} from "rxjs";
import {ParsingFunctions} from "../landing-utils/parsingFunctions.class";
import {ConnectHelper} from "../../connect/connectHelper";
import {UserManagementService} from "../../services/user-management.service";
import {OpenaireEntities} from "../../utils/properties/searchFields";
import {Option} from "../../sharedComponents/input/input.component";
import {NumberUtils} from '../../utils/number-utils.class';
import {FullScreenModalComponent} from "../../utils/modal/full-screen-modal/full-screen-modal.component";
import {SdgFosSuggestComponent} from '../landing-utils/sdg-fos-suggest/sdg-fos-suggest.component';
import {LayoutService} from "../../dashboard/sharedComponents/sidebar/layout.service";
declare var ResizeObserver;
@ -42,8 +45,11 @@ export class ResultLandingComponent {
enermapsId;
// @ViewChild('linkModal') linkModal;
@ViewChild('citeModal') citeModal;
@ViewChild('citeFsModal') citeFsModal;
@ViewChild('addThisModal') addThisModal;
@ViewChild('addThisFsModal') addThisFsModal;
@ViewChild('AlertModalDeletedByInference') alertModalDeletedByInference;
@ViewChild('AlertModalDeletedByInferenceFS') alertModalDeletedByInferenceFS;
// @ViewChild('relationModal') relationModal;
public deleteByInferenceOpened: boolean = false;
@Input() public resultFromInput: boolean = false;
@ -72,9 +78,14 @@ export class ResultLandingComponent {
public hasAltMetrics: boolean = false;
public viewsFrameUrl: string;
public downloadsFrameUrl: string;
/** @deprecated*/
public totalViews: number = null;
/** @deprecated*/
public totalDownloads: number = null;
public hasViews: boolean = false;
public hasDownloads: boolean = false;
public pageViews: number = null;
public bipFrameUrl: string;
// Custom tab paging variables
public referencesPage: number = 1;
@ -114,7 +125,7 @@ export class ResultLandingComponent {
'Title', 'Authors', 'Access rights',
'Publisher information', 'Funding Information',
'Persistent identifiers', 'Sustainable Development Goals (SDGs)',
'Fields of Science and Technology (FOS)', 'Other'];
'Fields of Science (FoS)', 'Other'];
public pidsArrayString: string = "";
public identifier: Identifier;
@ -142,7 +153,26 @@ export class ResultLandingComponent {
// public shouldSticky: boolean = true;
public mobileContent: "info" | "metrics" | "actions" = "info";
public tabMobile: string = "";
public viewAllMobile: string = "";
public viewAll: string = "";
@ViewChild("sdgFosSuggest") sdgFosSuggest: SdgFosSuggestComponent;
public isMobile: boolean = false;
// Full screen modals for small screens (mobile)
@ViewChild('summaryFsModal') summaryFsModal: FullScreenModalComponent;
@ViewChild('subjectsFsModal') subjectsFsModal: FullScreenModalComponent;
@ViewChild('referencesFsModal') referencesFsModal: FullScreenModalComponent;
@ViewChild('relatedResearchFsModal') relatedResearchFsModal: FullScreenModalComponent;
@ViewChild('bioentitiesFsModal') bioentitiesFsModal: FullScreenModalComponent;
@ViewChild('compatibleEOSCFsModal') compatibleEOSCFsModal: FullScreenModalComponent;
@ViewChild('fundedByFsModal') fundedByFsModal: FullScreenModalComponent;
@ViewChild('relatedCommunitiesFsModal') relatedCommunitiesFsModal: FullScreenModalComponent;
@ViewChild('enermapsToolFsModal') enermapsToolFsModal: FullScreenModalComponent;
@ViewChild('sdgsFsModal') sdgsFsModal: FullScreenModalComponent;
@ViewChild('fosFsModal') fosFsModal: FullScreenModalComponent;
public noCommunities: boolean = false;
public rightSidebarOffcanvasClicked: boolean = false;
@ -161,10 +191,14 @@ export class ResultLandingComponent {
private cdr: ChangeDetectorRef,
private _location: Location,
private indexInfoService: IndexInfoService,
private userManagementService: UserManagementService) {
private userManagementService: UserManagementService,
private layoutService: LayoutService) {
}
ngOnInit() {
this.subscriptions.push(this.layoutService.isMobile.subscribe(isMobile => {
this.isMobile = isMobile;
}));
this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => {
this.isLoggedIn = !!user;
}, error => { this.isLoggedIn = false} ));
@ -347,7 +381,8 @@ export class ResultLandingComponent {
subscription.unsubscribe();
} else if (subscription instanceof Function) {
subscription();
} else if (subscription instanceof (ResizeObserver || IntersectionObserver)) {
} else if ((typeof ResizeObserver != 'undefined' && subscription instanceof ResizeObserver) ||
(typeof IntersectionObserver != 'undefined' && subscription instanceof IntersectionObserver)) {
subscription.disconnect();
}
});
@ -470,6 +505,7 @@ export class ResultLandingComponent {
this.viewsFrameUrl = this.properties.statisticsFrameNewAPIURL + 'chart?json=' + encodeURIComponent('{"library":"HighCharts","chartDescription":{"queries":[{"name":"Monthly views","type":"column","query":{"name":"usagestats.results.views.monthly", "parameters":["' + this.id + '"], "profile":"OpenAIRE All-inclusive" }}],"chart":{"backgroundColor":"#FFFFFFFF","borderColor":"#335cadff","borderRadius":0,"borderWidth":0,"plotBorderColor":"#ccccccff","plotBorderWidth":0},"title":{"text":"Monthly views"},"subtitle":{},"yAxis":{"title":{"text":""}},"xAxis":{"title":{}},"lang":{"noData":"No Data available for the Query"},"exporting":{"enabled":false},"plotOptions":{"series":{"dataLabels":{"enabled":false}}},"legend":{"enabled":false},"credits":{"href":null,"enabled":true,"text":""}}}');
this.downloadsFrameUrl = this.properties.statisticsFrameNewAPIURL + 'chart?json=' +
encodeURIComponent('{"library":"HighCharts","chartDescription":{"queries":[{"name":"Monthly downloads","type":"column","query":{"name":"usagestats.results.downloads.monthly", "parameters":["' + this.id + '"], "profile":"OpenAIRE All-inclusive" }}],"chart":{"backgroundColor":"#FFFFFFFF","borderColor":"#335cadff","borderRadius":0,"borderWidth":0,"plotBorderColor":"#ccccccff","plotBorderWidth":0},"title":{"text":"Monthly downloads"},"subtitle":{},"yAxis":{"title":{"text":""}},"xAxis":{"title":{}},"lang":{"noData":"No Data available for the Query"},"exporting":{"enabled":false},"plotOptions":{"series":{"dataLabels":{"enabled":false}}},"legend":{"enabled":false},"credits":{"href":null,"enabled":true,"text":""}}}');
this.bipFrameUrl = this.properties.bipFrameAPIURL + this.id + (properties.environment == "beta" ? "&src=beta" : "");
let pid:Identifier = Identifier.getPIDFromIdentifiers(this.resultLandingInfo.identifiers);
if (this.type == "result") { // no type was specified - update URL based this.resultLandingInfo.resultType
this.updateUrlWithType(pid);
@ -515,7 +551,7 @@ export class ResultLandingComponent {
this.enermapsId = ParsingFunctions.getEnermapsConceptId(this.resultLandingInfo.contexts);
}
this.relatedClassFilters = [{"label": "All relations", "value": ""}];
if(this.resultLandingInfo.relatedClassFilters.size > 1) {
for (let relClass of this.resultLandingInfo.relatedClassFilters) {
this.relatedClassFilters.push({"label": HelperFunctions.getVocabularyLabel(relClass, this.relationsVocabulary), "value": relClass});
@ -526,6 +562,19 @@ export class ResultLandingComponent {
this.relatedClassSelected = "";
this.filteredRelatedResults = this.resultLandingInfo.relatedResults;
this.hasViews = false;
this.hasDownloads = false;
if(this.resultLandingInfo.measure && this.resultLandingInfo.measure.counts) {
this.resultLandingInfo.measure.counts.forEach(measure => {
if(measure.name == "views" && measure.value > 0) {
this.hasViews = true;
}
if(measure.name == "downloads" && measure.value > 0) {
this.hasDownloads = true;
}
})
}
this.showLoading = false;
this.setActiveTab();
@ -555,14 +604,12 @@ export class ResultLandingComponent {
public get hasPrimaryInfo(): boolean {
return !!this.resultLandingInfo && (
(!!this.resultLandingInfo.description && this.resultLandingInfo.description.length > 0)
|| !!this.resultLandingInfo.subjects
|| (this.resultLandingInfo.classifiedSubjects && this.resultLandingInfo.classifiedSubjects.size > 0)
|| (!!this.resultLandingInfo.organizations && this.resultLandingInfo.organizations.length > 0));
}
public get hasRightSidebarInfo(): boolean {
return (this.resultLandingInfo.eoscSubjects && this.resultLandingInfo.eoscSubjects.length
&& (properties.adminToolsPortalType == 'explore' || properties.adminToolsPortalType == 'eosc'))
&& properties.adminToolsPortalType == 'eosc')
||
(this.resultLandingInfo.sdg && this.resultLandingInfo.sdg.length > 0)
||
@ -571,8 +618,10 @@ export class ResultLandingComponent {
(this.resultLandingInfo.fundedByProjects && this.resultLandingInfo.fundedByProjects.length > 0)
||
(this.resultLandingInfo.contexts && this.resultLandingInfo.contexts.length > 0 && !this.noCommunities)
||
(this.resultLandingInfo.hostedBy_collectedFrom && this.resultLandingInfo.hostedBy_collectedFrom.length > 0);
||
(this.resultLandingInfo.measure && Object.keys(this.resultLandingInfo.measure).length > 0);
// ||
// (this.resultLandingInfo.hostedBy_collectedFrom && this.resultLandingInfo.hostedBy_collectedFrom.length > 0);
}
public get metricsCalculated(): boolean {
@ -903,6 +952,32 @@ export class ResultLandingComponent {
}
}
public viewAllSubjectsMobileClicked(event) {
this.subjectsFsModal.title += " - "+event['subtitle'];
this.subjectsFsModal.back = true;
this.viewAllMobile = event['id'];
}
public viewAllOrganizationsMobileClicked() {
this.summaryFsModal.title += " - Related "+this.openaireEntities.ORGANIZATIONS;
this.summaryFsModal.back = true;
this.lessBtnOrganizations = true;
this.viewAllMobile = "organizations";
}
public cancelSummaryClicked() {
this.summaryFsModal.title = "Summary";
this.summaryFsModal.back = false;
this.lessBtnOrganizations = false;
this.viewAllMobile = "";
}
public cancelSubjectsClicked() {
this.subjectsFsModal.title = "Subjects";
this.subjectsFsModal.back = false;
this.viewAllMobile = "";
}
public openOrganizationsModal() {
this.organizationsModal.cancelButton = false;
this.organizationsModal.okButton = false;
@ -917,12 +992,145 @@ export class ResultLandingComponent {
this.viewAll = "";
}
public sdgsFsModalCancelled() {
if(this.viewAllMobile == "sdg") {
this.viewAllMobile = "";
} else {
this.viewAllMobile = "sdg";
}
}
public fosFsModalCancelled() {
if(this.viewAllMobile == "fos") {
this.viewAllMobile = "";
} else {
this.viewAllMobile = "fos";
}
}
public suggestMobileClicked(value: string) {
if(this.viewAllMobile == 'sdg' || this.viewAllMobile == 'fos') {
this.sdgsFsModal.title += " - Suggest";
this.sdgsFsModal.back = true;
this.sdgFosSuggest.subjects=this.resultLandingInfo.sdg;
this.sdgFosSuggest.subjectType="sdg";
this.viewAllMobile = "sdgSuggest";
}
if(value == 'sdg') {
this.sdgFosSuggest.subjects=this.resultLandingInfo.sdg;
this.sdgFosSuggest.subjectType="sdg";
} else if(value == 'fos') {
this.sdgFosSuggest.subjects=this.resultLandingInfo.fos;
this.sdgFosSuggest.subjectType="fos";
}
}
public suggestClicked(value: string) {
if(value == 'sdg') {
this.sdgFosSuggest.subjects=this.resultLandingInfo.sdg;
this.sdgFosSuggest.subjectType="sdg";
} else if(value == 'fos') {
this.sdgFosSuggest.subjects=this.resultLandingInfo.fos;
this.sdgFosSuggest.subjectType="fos";
}
this.cdr.detectChanges();
this.sdgFosSuggest.openSelectionModal();
}
public viewAllDescriptionClicked() {
if(this.isMobile) {
this.summaryFsModal.title += " - Abstract";
this.summaryFsModal.back = true;
this.viewAllMobile = "description";
} else {
this.openDescriptionModal();
}
}
public openDescriptionModal() {
this.descriptionModal.alertFooter = false;
this.descriptionModal.alertTitle = "Abstract";
this.descriptionModal.open();
}
public clickedUsageMetrics() {
setTimeout( () => {
this.metricsClicked = true;
});
}
public formatNumber(num: number | string) {
let formatted = NumberUtils.roundNumber(+num);
return formatted.number + formatted.size;
}
// private openSdgSelectionModal() {
// this.sdgSelectionModal.cancelButton = false;
// this.sdgSelectionModal.alertTitle = "Please select SDGs that are the most relevant for this publication.";
// this.sdgSelectionModal.okButtonText = "Next";
// this.sdgSelectionModal.stayOpen = true;
// this.sdgSelectionModal.open();
// }
public openFsModal(fsModal: FullScreenModalComponent, title: string) {
fsModal.title = title;
fsModal.okButton = false;
fsModal.stayOpenInBack = true;
fsModal.open();
this.tabMobile = title;
}
/*private openFosSelectionModal() {
this.fosSelectionModal.cancelButton = false;
this.fosSelectionModal.alertTitle = "Please select FOS that are the most relevant for this publication.";
this.fosSelectionModal.open();
}
public sdgModalOutput() {
this.sdgFosSuggest.sdgModalOutput();
}*/
public closeFsModal(fsModal: FullScreenModalComponent) {
fsModal.cancel();
}
public getMetricsTooltip(value: string, compact: boolean) {
if (compact) {
if (value == 'citations') {
return "<div>This is an alternative to the \"Influence\" indicator, which also reflects the overall/total impact of an article in the research community at large, based on the underlying citation network (diachronically).</div>";
} else if (value == 'popularity') {
return "<div>This indicator reflects the \"current\" impact/attention (the \"hype\") of an article in the research community at large, based on the underlying citation network.</div>";
} else if (value == 'influence') {
return "<div>This indicator reflects the overall/total impact of an article in the research community at large, based on the underlying citation network (diachronically).</div>";
} else if (value == 'impulse') {
return "<div>This indicator reflects the initial momentum of an article directly after its publication, based on the underlying citation network.</div>";
}
} else {
if (value == 'citations') {
return "<div>This is an alternative to the \"Influence\" indicator, which also reflects the overall/total impact of an article in the research community at large, based on the underlying citation network (diachronically).</div><div class='uk-flex uk-margin-top'><a href='https://bip.imsi.athenarc.gr/' target='_blank'><img class='uk-margin-small-right' src='assets/common-assets/bip-minimal.svg' loading='lazy' alt='BIP!' style='width: 40px;'></a><span class='uk-text-uppercase'>Citations provided by <a href='https://bip.imsi.athenarc.gr/' target='_blank' class='uk-link-reset'><strong>BIP!</strong></a></div>";
} else if (value == 'popularity') {
return "<div>This indicator reflects the \"current\" impact/attention (the \"hype\") of an article in the research community at large, based on the underlying citation network.</div><div class='uk-flex uk-margin-top'><a href='https://bip.imsi.athenarc.gr/' target='_blank'><img class='uk-margin-small-right' src='assets/common-assets/bip-minimal.svg' loading='lazy' alt='BIP!' style='width: 40px;'></a><span class='uk-text-uppercase'>Popularity provided by <a href='https://bip.imsi.athenarc.gr/' target='_blank' class='uk-link-reset'><strong>BIP!</strong></a></div>";
} else if (value == 'influence') {
return "<div>This indicator reflects the overall/total impact of an article in the research community at large, based on the underlying citation network (diachronically).</div><div class='uk-flex uk-margin-top'><a href='https://bip.imsi.athenarc.gr/' target='_blank'><img class='uk-margin-small-right' src='assets/common-assets/bip-minimal.svg' loading='lazy' alt='BIP!' style='width: 40px;'></a><span class='uk-text-uppercase'>Influence provided by <a href='https://bip.imsi.athenarc.gr/' target='_blank' class='uk-link-reset'><strong>BIP!</strong></a></div>";
} else if (value == 'impulse') {
return "<div>This indicator reflects the initial momentum of an article directly after its publication, based on the underlying citation network.</div><div class='uk-flex uk-margin-top'><a href='https://bip.imsi.athenarc.gr/' target='_blank'><img class='uk-margin-small-right' src='assets/common-assets/bip-minimal.svg' loading='lazy' alt='BIP!' style='width: 40px;'></a><span class='uk-text-uppercase'>Impulse provided by <a href='https://bip.imsi.athenarc.gr/' target='_blank' class='uk-link-reset'><strong>BIP!</strong></a></div>";
} else if (value == 'downloads') {
return "<div class='uk-flex uk-flex-middle'><a href='https://usagecounts.openaire.eu/' target='_blank'><img src='assets/common-assets/logo-small-usage-counts.png' loading='lazy' alt='OpenAIRE UsageCounts'></a><span class='uk-text-uppercase uk-margin-small-left'>Downloads provided by <a href='https://usagecounts.openaire.eu/' target='_blank' class='uk-link-reset'><strong>UsageCounts</strong></a></div>";
} else if (value == 'views') {
return "<div class='uk-flex uk-flex-middle'><a href='https://usagecounts.openaire.eu/' target='_blank'><img src='assets/common-assets/logo-small-usage-counts.png' loading='lazy' alt='OpenAIRE UsageCounts'></a><span class='uk-text-uppercase uk-margin-small-left'>Views provided by <a href='https://usagecounts.openaire.eu/' target='_blank' class='uk-link-reset'><strong>UsageCounts</strong></a></div>";
}
}
}
public isNumber(value): boolean {
return typeof value === 'number';
}
public getAccessLabel(accessRight) : string {
if (accessRight) {
return (accessRight + (accessRight.toLowerCase().endsWith(" access") ? "" : " access"));
}
return "Not available access";
}
public getEoscParams() {
let params = "";
if(this.prevPath) {
@ -953,5 +1161,4 @@ export class ResultLandingComponent {
return "https://"+(this.properties.environment == "beta" ? "beta." : "")+"search.marketplace.eosc-portal.eu/";
}
}
}

View File

@ -1,26 +1,26 @@
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {FormsModule} from '@angular/forms';
import {RouterModule} from '@angular/router';
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {FormsModule} from '@angular/forms';
import {RouterModule} from '@angular/router';
import {SharedModule} from '../../../openaireLibrary/shared/shared.module';
import {MetricsModule} from '../landing-utils/metrics/metrics.module';
import {LandingModule} from '../landing-utils/landing.module';
import {CiteThisModule} from '../landing-utils/citeThis/citeThis.module';
import {IFrameModule} from '../../utils/iframe.module';
import {AltMetricsModule} from '../../utils/altmetrics.module';
import {PagingModule} from '../../utils/paging.module';
import {SharedModule} from '../../../openaireLibrary/shared/shared.module';
import {MetricsModule} from '../landing-utils/metrics/metrics.module';
import {LandingModule} from '../landing-utils/landing.module';
import {CiteThisModule} from '../landing-utils/citeThis/citeThis.module';
import {IFrameModule} from '../../utils/iframe.module';
import {AltMetricsModule} from '../../utils/altmetrics.module';
import {PagingModule} from '../../utils/paging.module';
import {ResultLandingService} from './resultLanding.service';
import {ResultLandingComponent} from './resultLanding.component';
import {Schema2jsonldModule} from '../../sharedComponents/schema2jsonld/schema2jsonld.module';
import { SEOServiceModule } from '../../sharedComponents/SEO/SEOService.module';
import {ResultLandingService} from './resultLanding.service';
import {ResultLandingComponent} from './resultLanding.component';
import {Schema2jsonldModule} from '../../sharedComponents/schema2jsonld/schema2jsonld.module';
import {SEOServiceModule} from '../../sharedComponents/SEO/SEOService.module';
import {DeletedByInferenceModule} from './deletedByInference/deletedByInference.module';
import {ShowAuthorsModule} from "../../utils/authors/showAuthors.module";
import {HelperModule} from "../../utils/helper/helper.module";
import {ResultLandingUtilsModule} from "../landing-utils/resultLandingUtils.module";
import {AlertModalModule} from "../../utils/modal/alertModal.module";
import {DeletedByInferenceModule} from './deletedByInference/deletedByInference.module';
import {ShowAuthorsModule} from "../../utils/authors/showAuthors.module";
import {HelperModule} from "../../utils/helper/helper.module";
import {ResultLandingUtilsModule} from "../landing-utils/resultLandingUtils.module";
import {AlertModalModule} from "../../utils/modal/alertModal.module";
import {AnnotationModule} from "../annotation/annotation.module";
import {LandingHeaderModule} from "../landing-utils/landing-header/landing-header.module";
import {NoLoadPaging} from "../../searchPages/searchUtils/no-load-paging.module";
@ -33,9 +33,14 @@ import {MatFormFieldModule} from "@angular/material/form-field";
import {MatSelectModule} from "@angular/material/select";
import {IconsModule} from "../../utils/icons/icons.module";
import {IconsService} from "../../utils/icons/icons.service";
import {graph, link, quotes} from "../../utils/icons/icons";
import {cite, fire, graph, landmark, link, link_to, quotes, rocket, versions} from "../../utils/icons/icons";
import {InputModule} from "../../sharedComponents/input/input.module";
import {EGIDataTransferModule} from "../../utils/dataTransfer/transferData.module";
import {RecaptchaModule} from 'ng-recaptcha';
import {SdgFosSuggestModule} from '../landing-utils/sdg-fos-suggest/sdg-fos-suggest.module';
import {FullScreenModalModule} from "../../utils/modal/full-screen-modal/full-screen-modal.module";
import {SafeHtmlPipeModule} from '../../utils/pipes/safeHTMLPipe.module';
import {EntityActionsModule} from "../../utils/entity-actions/entity-actions.module";
@NgModule({
imports: [
@ -44,7 +49,8 @@ import {EGIDataTransferModule} from "../../utils/dataTransfer/transferData.modul
MetricsModule, AltMetricsModule, Schema2jsonldModule, SEOServiceModule,
DeletedByInferenceModule, ShowAuthorsModule, HelperModule, ResultLandingUtilsModule, AlertModalModule,
AnnotationModule, LandingHeaderModule, NoLoadPaging, ResultPreviewModule, FeedbackModule, TabsModule, LoadingModule,
OrcidModule, MatFormFieldModule, MatSelectModule, IconsModule, InputModule, EGIDataTransferModule
OrcidModule, MatFormFieldModule, MatSelectModule, IconsModule, InputModule, EGIDataTransferModule, RecaptchaModule,
SdgFosSuggestModule, FullScreenModalModule, SafeHtmlPipeModule, EntityActionsModule
],
declarations: [
ResultLandingComponent
@ -58,6 +64,6 @@ import {EGIDataTransferModule} from "../../utils/dataTransfer/transferData.modul
})
export class ResultLandingModule {
constructor(private iconsService: IconsService) {
this.iconsService.registerIcons([link, graph, quotes])
this.iconsService.registerIcons([link, graph, quotes, cite, link_to, versions, rocket, fire, landmark])
}
}

View File

@ -13,7 +13,7 @@ import {HelperFunctions} from "../../utils/HelperFunctions.class";
@Injectable()
export class ResultLandingService {
constructor(private http: HttpClient ) {
constructor(private http: HttpClient) {
this.parsingFunctions = new ParsingFunctions();
}
@ -39,7 +39,7 @@ export class ResultLandingService {
} else if (identifier) {
// pid = "10.3389/fphys.2014.00466";
let url = properties.searchAPIURLLAst + "resources2";
url += "?pid="+encodeURIComponent(identifier.id) + "&pidtype=" + identifier.class + "&type=";
url += "?pid=" + encodeURIComponent(identifier.id) + "&pidtype=" + identifier.class + "&type=";
if (type === 'publication') {
url += 'publications';
} else if (type === 'dataset') {
@ -56,50 +56,50 @@ export class ResultLandingService {
}
}
getResultLandingInfo (id: string, identifier: Identifier, type: string,
subjectsVocabulary: any,
properties: EnvProperties): any {
getResultLandingInfo(id: string, identifier: Identifier, type: string,
subjectsVocabulary: any,
properties: EnvProperties): any {
let url: string = this.buildResultLandingInfoUrl(id, identifier, type);
let finalUrl: string = (properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url;
return this.http.get(finalUrl)
.pipe(map(res => {
if(!id && identifier) {
if(!res['results'] || res['results'].length == 0) {
throw new HttpErrorResponse({
status: 404,
statusText: "Not found",
url: finalUrl,
error: "Http failure response for "+finalUrl+": 404 Not Found"
});
.pipe(map(res => {
if (!id && identifier) {
if (!res['results'] || res['results'].length == 0) {
throw new HttpErrorResponse({
status: 404,
statusText: "Not found",
url: finalUrl,
error: "Http failure response for " + finalUrl + ": 404 Not Found"
});
}
return res['results'][0];
} else {
return res;
}
return res['results'][0];
} else {
return res;
}
}))
.pipe(map(res => [res['result']['header']['dri:status'], res['result']['metadata']['oaf:entity'], res]))
.pipe(map(res => [
res[1]['oaf:result'], // 0
res[1]['oaf:result']['title'], // 1
res[1]['oaf:result']['rels']['rel'], // 2
res[1]['oaf:result']['children'], // 3
res[1]['oaf:result']['pid'], // 4
res[1]['oaf:result']['journal'], // 5
res[1]['oaf:result']['language'], // 6
res[1]['oaf:result']['eoscifguidelines'], // 7
res[1]['oaf:result']['subject'], // 8
res[1]['oaf:result']['context'], // 9
res[1]['oaf:result']['creator'], // 10
res[1]['oaf:result']['country'] , // 11
res[1]['oaf:result']['programmingLanguage'], // 12 - software
//res[1]['oaf:result']['resulttype'],
(res[1]['extraInfo'] !== undefined && res[1]['extraInfo']['references'] !== undefined)
? res[1]['extraInfo']['references']['reference'] : null, // 13
res[0], // 14
res[2], // 15
]))
.pipe(map(res => this.parseResultLandingInfo(res, subjectsVocabulary, properties)));
}))
.pipe(map(res => [res['result']['header']['dri:status'], res['result']['metadata']['oaf:entity'], res]))
.pipe(map(res => [
res[1]['oaf:result'], // 0
res[1]['oaf:result']['title'], // 1
res[1]['oaf:result']['rels']['rel'], // 2
res[1]['oaf:result']['children'], // 3
res[1]['oaf:result']['pid'], // 4
res[1]['oaf:result']['journal'], // 5
res[1]['oaf:result']['language'], // 6
res[1]['oaf:result']['eoscifguidelines'], // 7
res[1]['oaf:result']['subject'], // 8
res[1]['oaf:result']['context'], // 9
res[1]['oaf:result']['creator'], // 10
res[1]['oaf:result']['country'], // 11
res[1]['oaf:result']['programmingLanguage'], // 12 - software
//res[1]['oaf:result']['resulttype'],
(res[1]['extraInfo'] !== undefined && res[1]['extraInfo']['references'] !== undefined)
? res[1]['extraInfo']['references']['reference'] : null, // 13
res[0], // 14
res[2], // 15
]))
.pipe(map(res => this.parseResultLandingInfo(res, subjectsVocabulary, properties)));
}
// getProvenanceActionVocabulary (properties: EnvProperties): any {
@ -118,16 +118,15 @@ export class ResultLandingService {
// return provenanceActionVocabulary;
// }
private handleError (error: HttpErrorResponse) {
private handleError(error: HttpErrorResponse) {
// 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 throwError(error || 'Server error');
return throwError(error || 'Server error');
}
parseResultLandingInfo (data: any, subjectsVocabulary: any, properties: EnvProperties): any {
parseResultLandingInfo(data: any, subjectsVocabulary: any, properties: EnvProperties): any {
this.resultLandingInfo = new ResultLandingInfo();
// res
this.resultLandingInfo.record = data[15];
this.resultLandingInfo.objIdentifier = data[15]["result"]["header"]["dri:objIdentifier"];
@ -137,25 +136,25 @@ export class ResultLandingService {
// res['result']['metadata']['oaf:entity']['oaf:result']
if (data[0] != null) {
let date: string = (data[0].dateofacceptance ? data[0].dateofacceptance : '') + ''; // transform to string in case it is an integer
this.resultLandingInfo.date = (date && (date).indexOf('-') !== -1) ? date.split('-')[0] : date;
this.resultLandingInfo.dateofacceptance = data[0].dateofacceptance?Dates.getDate(data[0].dateofacceptance):null;
this.resultLandingInfo.date = (date && (date).indexOf('-') !== -1) ? date.split('-')[0] : date;
this.resultLandingInfo.dateofacceptance = data[0].dateofacceptance ? Dates.getDate(data[0].dateofacceptance) : null;
this.resultLandingInfo.publisher = data[0].publisher;
this.resultLandingInfo.description = this.parsingFunctions.parseDescription(data[0] && data[0].description?data[0].description:[]);
this.resultLandingInfo.embargoEndDate = data[0].embargoenddate?Dates.getDate(data[0].embargoenddate):null;
this.resultLandingInfo.description = this.parsingFunctions.parseDescription(data[0] && data[0].description ? data[0].description : []);
this.resultLandingInfo.embargoEndDate = data[0].embargoenddate ? Dates.getDate(data[0].embargoenddate) : null;
}
if(data[0]['bestaccessright'] && data[0]['bestaccessright'].hasOwnProperty("classname")) {
if (data[0]['bestaccessright'] && data[0]['bestaccessright'].hasOwnProperty("classname")) {
this.resultLandingInfo.accessMode = data[0]['bestaccessright'].classname;
}
// res['result']['metadata']['oaf:entity']['oaf:result']['title']
if(data[1] != null) {
if(Array.isArray(data[1])) {
for(let i=0; i<data[1].length; i++) {
if(data[1][i] && data[1][i].content) {
if(!this.resultLandingInfo.title || data[1][i].classid == "main title") {
if (data[1] != null) {
if (Array.isArray(data[1])) {
for (let i = 0; i < data[1].length; i++) {
if (data[1][i] && data[1][i].content) {
if (!this.resultLandingInfo.title || data[1][i].classid == "main title") {
this.resultLandingInfo.title = StringUtils.HTMLToString(String(data[1][i].content));
}
if(!this.resultLandingInfo.subtitle && data[1][i].classid === 'subtitle') {
if (!this.resultLandingInfo.subtitle && data[1][i].classid === 'subtitle') {
this.resultLandingInfo.subtitle = StringUtils.HTMLToString(String(data[1][i].content));
}
// if(data[1][i].classid == "main title") {
@ -163,10 +162,10 @@ export class ResultLandingService {
// }
}
}
if(this.resultLandingInfo.title === this.resultLandingInfo.subtitle) {
if (this.resultLandingInfo.title === this.resultLandingInfo.subtitle) {
this.resultLandingInfo.subtitle = "";
}
if(!this.resultLandingInfo.title) {
if (!this.resultLandingInfo.title) {
this.resultLandingInfo.title = "";
}
// this.resultLandingInfo.title = (data[1][0] && data[1][0].content) ? String(data[1][0].content) : "";
@ -176,26 +175,26 @@ export class ResultLandingService {
}
// res['result']['metadata']['oaf:entity']['oaf:result']['rels']['rel']
if(data[2] != null) {
if (data[2] != null) {
let relation;
let length = Array.isArray(data[2]) ? data[2].length : 1;
for(let i=0; i<length; i++) {
for (let i = 0; i < length; i++) {
relation = Array.isArray(data[2]) ? data[2][i] : data[2];
if(relation.hasOwnProperty("to")) {
if(relation['to'].class && relation['to'].class.toLowerCase() == "isproducedby") {
if (relation.hasOwnProperty("to")) {
if (relation['to'].class && relation['to'].class.toLowerCase() == "isproducedby") {
this.resultLandingInfo.fundedByProjects = this.parsingFunctions.parseFundingByProjects(this.resultLandingInfo.fundedByProjects, relation);
}
if(relation['to'].scheme && relation['to'].scheme == "dnet:result_result_relations") {
if (relation['to'].scheme && relation['to'].scheme == "dnet:result_result_relations") {
let relationName: string = relation.to.class;
if(!this.resultLandingInfo.relatedClassFilters.has(relationName)) {
if (!this.resultLandingInfo.relatedClassFilters.has(relationName)) {
this.resultLandingInfo.relatedClassFilters.add(relationName);
}
let provenanceAction: string = relation.provenanceaction;
this.resultLandingInfo.relatedResults = this.parsingFunctions.parseResults(this.resultLandingInfo.relatedResults, relation, provenanceAction, relationName);
} else if(relation['to'].class && relation['to'].class.toLowerCase() == "hasauthorinstitution") {
} else if (relation['to'].class && relation['to'].class.toLowerCase() == "hasauthorinstitution") {
this.resultLandingInfo.organizations = this.parseRelatedOrganizations(this.resultLandingInfo.organizations, relation);
}
}
@ -203,19 +202,19 @@ export class ResultLandingService {
}
// res['result']['metadata']['oaf:entity']['oaf:result']['children']
if(data[3] != null) {
if(data[3].hasOwnProperty("result")) {
if (data[3] != null) {
if (data[3].hasOwnProperty("result")) {
this.resultLandingInfo.deletedByInferenceIds = [];
let length = Array.isArray(data[3]['result']) ? data[3]['result'].length : 1;
for(let i=0; i<length; i++) {
for (let i = 0; i < length; i++) {
let result = Array.isArray(data[3]['result']) ? data[3]['result'][i] : data[3]['result'];
this.resultLandingInfo.deletedByInferenceIds.push(result.objidentifier);
}
}
if(data[3].hasOwnProperty("instance")) {
if (data[3].hasOwnProperty("instance")) {
this.resultLandingInfo.hostedBy_collectedFrom = new Array<HostedByCollectedFrom>();
@ -227,26 +226,24 @@ export class ResultLandingService {
let length = Array.isArray(data[3]['instance']) ? data[3]['instance'].length : 1;
for(let i=0; i<length; i++) {
for (let i = 0; i < length; i++) {
instance = Array.isArray(data[3]['instance']) ? data[3]['instance'][i] : data[3]['instance'];
this.parsingFunctions.parseTypes(this.resultLandingInfo.types, types, instance);
if(instance.hasOwnProperty("webresource")) {
if (instance.hasOwnProperty("webresource")) {
let url;
if(!Array.isArray(instance['webresource'])) {
if (!Array.isArray(instance['webresource'])) {
url = instance['webresource'].url;
} else {
url = instance['webresource'][0].url;
}
if(url.includes('&amp;')) {
let regExp = /&amp;/gmu;
let newUrl = url.replace(regExp, '&');
url = newUrl;
if (url.includes('&amp;')) {
url = url.replace(/&amp;/gmu, '&');
}
/**********************************************************/
if(instance.hasOwnProperty("hostedby")) {
if (instance.hasOwnProperty("hostedby")) {
this.parsingFunctions.parseHostedBy_collectedFrom(this.resultLandingInfo.hostedBy_collectedFrom, instance, url, this.resultLandingInfo.accessMode);
}
/**********************************************************/
@ -254,57 +251,32 @@ export class ResultLandingService {
}
/* Order Download from via openness*/
this.resultLandingInfo.hostedBy_collectedFrom.sort((a, b) => {
let firstAccessRight: string = (a.accessRight ? a.accessRight.toLowerCase() : null);
let secondAccessRight: string = (b.accessRight ? b.accessRight.toLowerCase() : null);
if (firstAccessRight === secondAccessRight) {
return 0;
} else {
if (firstAccessRight === 'open access') {
return -1;
} else if (secondAccessRight === 'open access') {
return 1;
} else if (firstAccessRight === "open source") {
return -1;
} else if (secondAccessRight === "open source") {
return 1;
} else if (firstAccessRight === "embargo") {
return -1;
} else if (secondAccessRight === "embargo") {
return 1;
} else if (firstAccessRight === "restricted") {
return -1;
} else if (secondAccessRight === "restricted") {
return 1;
} else if (firstAccessRight === "closed access") {
return -1;
} else if (secondAccessRight === "closed access") {
return 1;
} else if (firstAccessRight === "not available") {
return -1;
} else if (secondAccessRight === "not available") {
return 1;
}
}
return 0;
});
this.resultLandingInfo.hostedBy_collectedFrom.sort(this.parsingFunctions.compareHostedByCollectedFrom);
}
if(data[3].hasOwnProperty("externalreference")) {
if (data[3].hasOwnProperty("externalreference")) {
let externalResults: Map<string, Map<string, string>> = this.parseBioentitiesAndSoftware(data[3]);
this.resultLandingInfo.bioentities = externalResults;
}
}
// res['result']['metadata']['oaf:entity']['oaf:result']['pid']
if(data[4] != null) {
if (data[4] != null) {
this.resultLandingInfo.identifiers = this.parsingFunctions.parseIdentifiers(data[4]);
}
// res['result']['metadata']['oaf:entity']['oaf:result']['journal']
if(data[5] != null) {
this.resultLandingInfo.journal = {"journal": "", "issn": "", "lissn": "", "eissn": "", "issue": "", "volume": "", "start_page": "", "end_page": ""}
if (data[5] != null) {
this.resultLandingInfo.journal = {
"journal": "",
"issn": "",
"lissn": "",
"eissn": "",
"issue": "",
"volume": "",
"start_page": "",
"end_page": ""
}
this.resultLandingInfo.journal['journal'] = data[5].content;
this.resultLandingInfo.journal['issn'] = data[5].issn;
@ -317,7 +289,7 @@ export class ResultLandingService {
}
// res['result']['metadata']['oaf:entity']['oaf:result']['language']
if(data[6] != null) {
if (data[6] != null) {
this.resultLandingInfo.languages = this.parsingFunctions.parseLanguages(data[6]);
// let languagesAndCodes: string[][] = this.parsingFunctions.parseLanguages(data[6]);
// this.resultLandingInfo.languages = languagesAndCodes[0];
@ -325,27 +297,31 @@ export class ResultLandingService {
}
// res['result']['metadata']['oaf:entity']['oaf:result']['country']
if(data[11] != null) {
if (data[11] != null) {
this.resultLandingInfo.countries = this.parsingFunctions.parseCountries(data[11]);
}
// res['result']['metadata']['oaf:entity']['oaf:result']['eoscifguidelines']
if(data[7] != null) {
if (data[7] != null) {
this.resultLandingInfo.eoscSubjects = this.parsingFunctions.parseEoscSubjects(data[7]);
}
// res['result']['metadata']['oaf:entity']['oaf:result']['subject']
if(data[8] != null) {
if (data[8] != null) {
let subjectResults: [string[], Map<string, string[]>, Map<string, string[]>, string[], string[]] = this.parsingFunctions.parseAllSubjects(data[8], subjectsVocabulary);
this.resultLandingInfo.subjects = subjectResults[0];
this.resultLandingInfo.otherSubjects = subjectResults[1];
this.resultLandingInfo.classifiedSubjects = subjectResults[2];
this.resultLandingInfo.fos = subjectResults[3];
if(this.resultLandingInfo.fos) {
this.resultLandingInfo.fos.sort((a, b) => a.localeCompare(b))
if (subjectResults[3]) {
subjectResults[3].forEach(element => {
this.resultLandingInfo.fos.push({id: element, label: element.replace(/^\d+/, '').trim()});
});
}
if (this.resultLandingInfo.fos) {
this.resultLandingInfo.fos.sort((a, b) => a.id.localeCompare(b.id));
}
this.resultLandingInfo.sdg = subjectResults[4];
if(this.resultLandingInfo.sdg) {
if (this.resultLandingInfo.sdg) {
this.resultLandingInfo.sdg.sort((a, b) => {
return HelperFunctions.sortSDGs(a, b);
})
@ -357,50 +333,54 @@ export class ResultLandingService {
}
this.resultLandingInfo.hostedBy_collectedFrom = this.parsingFunctions.addPublisherToHostedBy_collectedFrom(
this.resultLandingInfo.hostedBy_collectedFrom, this.resultLandingInfo.publisher,
this.resultLandingInfo.journal, this.resultLandingInfo.identifiers);
this.resultLandingInfo.hostedBy_collectedFrom, this.resultLandingInfo.publisher,
this.resultLandingInfo.journal?.journal, this.resultLandingInfo.identifiers);
// res['result']['metadata']['oaf:entity']['oaf:result']['programmingLanguage']
if(data[12] != null) {
if (data[12] != null) {
this.resultLandingInfo.programmingLanguages = this.parsingFunctions.parseProgrammingLanguages(data[12]);
}
// res['result']['metadata']['oaf:entity']['extraInfo']['references']['reference']
if(data[13] != null) {
if (data[13] != null) {
this.resultLandingInfo.references = this.parsingFunctions.parseReferences(data[13]);
}
// res['result']['metadata']['oaf:entity']['oaf:result']['context']
if(data[9] != null) {
if (data[9] != null) {
this.resultLandingInfo.contexts = this.parsingFunctions.parseContexts(data[9]);
}
// res['result']['header']['dri:status']
if(data[14] != null && data[14] == "under curation") {
if (data[14] != null && data[14] == "under curation") {
this.resultLandingInfo.underCurationMessage = true;
} else {
this.resultLandingInfo.underCurationMessage = false;
}
// res['result']['metadata']['oaf:entity']['oaf:result']['creator']
if(data[10] != null) {
if(this.resultLandingInfo.authors == undefined) {
this.resultLandingInfo.authors = new Array<{"fullName": string, "orcid": string, "orcid_pending": string}>();
if (data[10] != null) {
if (this.resultLandingInfo.authors == undefined) {
this.resultLandingInfo.authors = new Array<{ "fullName": string, "orcid": string, "orcid_pending": string }>();
}
let authors = data[10];
let length = Array.isArray(authors) ? authors.length : 1;
for(let i=0; i<length; i++) {
for (let i = 0; i < length; i++) {
let author = Array.isArray(authors) ? authors[i] : authors;
if(author) {
if(author.orcid) {
if (author) {
if (author.orcid) {
author.orcid = author.orcid.toUpperCase();
}
if(author.orcid_pending) {
if (author.orcid_pending) {
author.orcid_pending = author.orcid_pending.toUpperCase();
}
this.resultLandingInfo['authors'][author.rank] = {"fullName": author.content, "orcid": author.orcid, "orcid_pending": author.orcid_pending};
this.resultLandingInfo['authors'][author.rank] = {
"fullName": author.content,
"orcid": author.orcid,
"orcid_pending": author.orcid_pending
};
}
}
this.resultLandingInfo.authors = this.resultLandingInfo.authors.filter(function (item) {
@ -408,17 +388,23 @@ export class ResultLandingService {
});
}
// res['result']['metadata']['oaf:entity']['oaf:result']['measure']
if (data[0]?.measure) {
this.resultLandingInfo.measure = this.parsingFunctions.parseMeasures(data[0].measure);
}
this.resultLandingInfo.relatedResults = this.parsingFunctions.sortByPercentage(this.resultLandingInfo.relatedResults);
return this.resultLandingInfo;
}
parseRelatedOrganizations(organizations: Organization[], relation: any): Organization[] {
if(organizations == undefined) {
if (organizations == undefined) {
organizations = []
}
let organization: { "name": string, "shortname": string,
let organization: {
"name": string, "shortname": string,
"id": string, "websiteUrl": string,
"country": string, "trust": number
} = {
@ -431,34 +417,34 @@ export class ResultLandingService {
organization.name = relation.legalname;
organization.shortname = relation.legalshortname;
organization.websiteUrl = relation.websiteurl;
if(relation.country) {
if (relation.country) {
organization.country = relation.country.classname;
}
if(relation.trust) {
organization.trust = Math.round(relation.trust*100);
if (relation.trust) {
organization.trust = Math.round(relation.trust * 100);
}
organizations.push(organization);
return organizations;
}
parseBioentitiesAndSoftware(children: any) : Map<string, Map<string, string>> {
parseBioentitiesAndSoftware(children: any): Map<string, Map<string, string>> {
let bioentities: Map<string, Map<string, string>>;
let length = Array.isArray(children['externalreference']) ? children['externalreference'].length : 1;
let externalreference;
for(let i=0; i<length; i++) {
for (let i = 0; i < length; i++) {
externalreference = Array.isArray(children['externalreference']) ? children['externalreference'][i] : children['externalreference'];
if(externalreference.hasOwnProperty("qualifier")) {
if(externalreference['qualifier'].classid == "accessionNumber") {
if (externalreference.hasOwnProperty("qualifier")) {
if (externalreference['qualifier'].classid == "accessionNumber") {
if(bioentities == undefined) {
if (bioentities == undefined) {
bioentities = new Map<string, Map<string, string>>();
}
if(!bioentities.has(externalreference.sitename)) {
if (!bioentities.has(externalreference.sitename)) {
bioentities.set(externalreference.sitename, new Map<string, string>());
}
bioentities.get(externalreference.sitename).set(externalreference.refidentifier, externalreference.url);
@ -471,10 +457,10 @@ export class ResultLandingService {
}
getEnermapsDetails(id: string) {
let url = properties.enermapsURL+"/api/db/metadata?shared_id=eq."+id;
return this.http.get((properties.useLongCache)? (properties.cacheUrl+encodeURIComponent(url)): url)
// return this.http.get(url)
.pipe(map(res => this.parseEnermapsDetails(res)));
let url = properties.enermapsURL + "/api/db/metadata?shared_id=eq." + id;
return this.http.get((properties.useLongCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
// return this.http.get(url)
.pipe(map(res => this.parseEnermapsDetails(res)));
}
parseEnermapsDetails(response: any) {
@ -483,9 +469,9 @@ export class ResultLandingService {
let entries = [];
let keys = metadata ? Object.keys(metadata) : null;
for(let key of keys) {
if(key != "shared_id" && key && metadata[key]) {
entries.push([key+"", metadata[key]+""]);
for (let key of keys) {
if (key != "shared_id" && key && metadata[key]) {
entries.push([key + "", metadata[key] + ""]);
}
}
return entries;

View File

@ -11,101 +11,99 @@ import {ExternalIDV3_0, WorkV3_0} from "./orcidWork";
import {EnvProperties} from "../utils/properties/env-properties";
import {UserManagementService} from "../services/user-management.service";
import {OpenaireEntities} from "../utils/properties/searchFields";
import {FullScreenModalComponent} from "../utils/modal/full-screen-modal/full-screen-modal.component";
declare var UIkit: any;
@Component({
selector: 'orcid-work',
template: `
<ng-container *ngIf="pageType == 'search'">
<ng-container *ngIf="pageType == 'landing' || pageType == 'search'">
<span *ngIf="!putCodes || putCodes.length == 0"
[attr.uk-tooltip]="(!isLoggedIn) ? tooltipNoLoggedInUser : tooltipAdd"
class="uk-margin-remove-bottom">
<a (click)="currentAction='add'; saveWorkPreparation();"
[class]="'uk-button uk-button-link uk-flex uk-flex-middle uk-flex-right@s uk-margin-right '+ ((showLoading || !isLoggedIn) ? 'uk-disabled ' : '') + (!isLoggedIn ? 'half-opacity' : '')">
<icon *ngIf="!showLoading" name="add" ratio="1" flex="true"></icon>
<span *ngIf="showLoading" class="uk-icon icon-button"><loading [top_margin]="false" [size]="'small'"></loading></span>
<span class="uk-margin-small-left uk-flex uk-flex-middle">Add to&#160;
<span class="uk-flex uk-flex-middle">
<span>ORCID&#160;</span>
<img class="" src="assets/common-assets/common/ORCIDiD_icon16x16.png" alt="orcid" style="width:16px; height:16px" loading="lazy">&#160;
</span>
</span>
</a>
</span>
<span *ngIf="putCodes && putCodes.length > 0"
[attr.uk-tooltip]="(!isLoggedIn) ? tooltipNoLoggedInUser : tooltipDelete"
class="uk-margin-remove-bottom">
<a (click)="currentAction='delete'; deleteWorks();"
[class]="'uk-button uk-button-link uk-flex uk-flex-middle uk-flex-right@s uk-margin-right '+ (showLoading ? 'uk-disabled' : '')">
<icon *ngIf="!showLoading" name="delete" ratio="0.8" flex="true"></icon>
<span *ngIf="showLoading" class="uk-icon icon-button"><loading [top_margin]="false" [size]="'small'"></loading></span>
<span class="uk-margin-small-left uk-flex uk-flex-middle">Delete from&#160;
<span class="uk-flex uk-flex-middle">
<span>ORCID&#160;</span>
<img src="assets/common-assets/common/ORCIDiD_icon16x16.png" alt="" loading="lazy">&#160;
</span>
</span>
</a>
</span>
</ng-container>
<ng-container *ngIf="pageType == 'landing'">
<span *ngIf="!putCodes || putCodes.length == 0"
[attr.uk-tooltip]="'pos: right; cls: uk-active uk-text-small uk-padding-small'"
[title]="(!pids || !isLoggedIn) ? (!pids ? tooltipNoPid : tooltipNoLoggedInUser) : tooltipAdd">
<a *ngIf="!showLoading" (click)="currentAction='add'; saveWorkPreparation();"
class="uk-icon-button uk-icon landing-action-button landing-action-button-orcid"
[class.uk-disabled]="showLoading || !isLoggedIn || !pids"
[attr.uk-tooltip]="'pos: bottom; cls: uk-active uk-text-small uk-padding-small'"
[title]="((!pids && (!identifiers || identifiers.size == 0)) || !isLoggedIn) ? ((!pids && (!identifiers || identifiers.size == 0)) ? tooltipNoPid : tooltipNoLoggedInUser) : tooltipAdd">
<a (click)="currentAction='add'; saveWorkPreparation();"
class="uk-flex uk-flex-middle uk-button-link"
[ngClass]="isMobile && !(pageType == 'landing') ? 'uk-margin-left' : 'uk-flex-center'"
[class.uk-text-bolder]="!(isMobile && pageType == 'landing')"
[class.uk-disabled]="showLoading || !isLoggedIn || (!pids && (!identifiers || identifiers.size == 0))"
[class.uk-text-muted]="showLoading || !isLoggedIn || (!pids && (!identifiers || identifiers.size == 0))"
(mouseover)="hoverEvent($event)" (mouseout)="hoverEvent($event)">
<icon *ngIf="!hoverAdd" name="orcid_add" ratio="1.1" visuallyHidden="add"></icon>
<icon *ngIf="hoverAdd" name="add" visuallyHidden="add"></icon>
<icon *ngIf="!showLoading" [class.text-orcid]="!showLoading && isLoggedIn && (pids || identifiers?.size > 0)"
[class.uk-text-muted]="showLoading || !isLoggedIn || (!pids && (!identifiers || identifiers.size == 0))" name="orcid_add" ratio="1"
visuallyHidden="add"></icon>
<span *ngIf="showLoading" class="uk-icon"><loading
[top_margin]="false" [size]="'small'"></loading></span>
<span [ngClass]="(isMobile && pageType == 'landing') ? 'uk-margin-small-left' : 'uk-margin-xsmall-left'">Claim</span>
</a>
<span *ngIf="showLoading" class="uk-icon icon-button uk-icon-button-small"><loading
[top_margin]="false" [size]="'small'"></loading></span>
</span>
<span *ngIf="putCodes && putCodes.length > 0"
[attr.uk-tooltip]="'pos: right; cls: uk-active uk-text-small uk-padding-small'"
[title]="(!pids || !isLoggedIn) ? (!pids ? tooltipNoPid : tooltipNoLoggedInUser) : tooltipDelete">
<a *ngIf="!showLoading" (click)="currentAction='delete'; deleteWorks();"
class="uk-icon-button uk-icon landing-action-button landing-action-button-orcid"
[class.uk-disabled]="showLoading || !isLoggedIn || !pids"
[attr.uk-tooltip]="'pos: bottom; cls: uk-active uk-text-small uk-padding-small'"
[title]="((!pids && (!identifiers || identifiers.size == 0)) || !isLoggedIn) ? ((!pids && (!identifiers || identifiers.size == 0)) ? tooltipNoPid : tooltipNoLoggedInUser) : tooltipDelete">
<a (click)="currentAction='delete'; deleteWorks();"
class="uk-flex uk-flex-middle uk-button-link"
[ngClass]="isMobile && !(pageType == 'landing') ? 'uk-margin-left' : 'uk-flex-center'"
[class.uk-text-bolder]="!(isMobile && pageType == 'landing')"
[class.uk-disabled]="showLoading || !isLoggedIn || (!pids && (!identifiers || identifiers.size == 0))"
[class.uk-text-muted]="showLoading || !isLoggedIn || (!pids && (!identifiers || identifiers.size == 0))"
(mouseover)="hoverEvent($event, 'delete')" (mouseout)="hoverEvent($event, 'delete')">
<icon *ngIf="!showLoading" [class.text-orcid]="!showLoading && isLoggedIn && (pids || identifiers?.size > 0)"
[class.uk-text-muted]="showLoading || !isLoggedIn || (!pids && (!identifiers || identifiers.size == 0))" name="orcid_bin" ratio="1"
visuallyHidden="delete"></icon>
<span *ngIf="showLoading" class="uk-icon"><loading
[top_margin]="false" [size]="'small'"></loading></span>
<span [ngClass]="(isMobile && pageType == 'landing') ? 'uk-margin-small-left' : 'uk-margin-xsmall-left'">Remove</span>
</a>
</span>
<!-- Old 'remove' code -->
<!-- <span *ngIf="putCodes && putCodes.length > 0"
[attr.uk-tooltip]="'pos: bottom; cls: uk-active uk-text-small uk-padding-small'"
[title]="(!pids || !isLoggedIn) ? (!pids ? tooltipNoPid : tooltipNoLoggedInUser) : tooltipDelete">
<a *ngIf="!showLoading" (click)="currentAction='delete'; deleteWorks();"
class="uk-icon-button uk-icon landing-action-button landing-action-button-orcid"
[class.uk-disabled]="showLoading || !isLoggedIn || !pids"
(mouseover)="hoverEvent($event, 'delete')" (mouseout)="hoverEvent($event, 'delete')">
<icon *ngIf="!hoverDelete" name="orcid_bin" ratio="1.1" visuallyHidden="delete"></icon>
<icon *ngIf="hoverDelete" name="delete_outline" class="uk-text-danger" visuallyHidden="delete"></icon>
</a>
<span *ngIf="showLoading" class="uk-icon icon-button uk-icon-button-small"><loading
[top_margin]="false" [size]="'small'"></loading></span>
</span>
</span> -->
</ng-container>
<modal-alert #grantModal [overflowBody]=false (alertOutput)="openGrantWindow()">
<modal-alert *ngIf="!isMobile" #grantModal [overflowBody]=false (alertOutput)="openGrantWindow()">
<div>
<div>{{requestGrantMessage}}</div>
<!-- <div class="uk-margin-medium-top uk-align-right">-->
<!-- <button (click)="closeGrantModal()" type="submit"-->
<!-- class="uk-button uk-padding-small uk-padding-remove-vertical uk-button-default">-->
<!-- <span>Cancel</span>-->
<!-- </button>-->
<!-- <div class="uk-margin-medium-top uk-align-right">-->
<!-- <button (click)="closeGrantModal()" type="submit"-->
<!-- class="uk-button uk-padding-small uk-padding-remove-vertical uk-button-default">-->
<!-- <span>Cancel</span>-->
<!-- </button>-->
<!-- <button (click)="openGrantWindow()" type="submit"-->
<!-- class="uk-button uk-padding-small uk-padding-remove-vertical uk-margin-left uk-button-primary">-->
<!-- <span>Grant OpenAIRE</span>-->
<!-- </button>-->
<!-- <button (click)="openGrantWindow()" type="submit"-->
<!-- class="uk-button uk-padding-small uk-padding-remove-vertical uk-margin-left uk-button-primary">-->
<!-- <span>Grant OpenAIRE</span>-->
<!-- </button>-->
<!--&lt;!&ndash; <button (click)="openGrantWindow()" type="submit"&ndash;&gt;-->
<!--&lt;!&ndash; class="uk-button uk-padding-small uk-padding-remove-vertical uk-margin-left orcid-button">&ndash;&gt;-->
<!--&lt;!&ndash; <img src="assets/common-assets/common/ORCIDiD_icon16x16.png" alt="">{{" "}}&ndash;&gt;-->
<!--&lt;!&ndash; <span>Create or Connect your ORCID iD</span>&ndash;&gt;-->
<!--&lt;!&ndash; </button>&ndash;&gt;-->
<!-- </div>-->
<!--&lt;!&ndash; <button (click)="openGrantWindow()" type="submit"&ndash;&gt;-->
<!--&lt;!&ndash; class="uk-button uk-padding-small uk-padding-remove-vertical uk-margin-left orcid-button">&ndash;&gt;-->
<!--&lt;!&ndash; <img src="assets/common-assets/common/ORCIDiD_icon16x16.png" alt="">{{" "}}&ndash;&gt;-->
<!--&lt;!&ndash; <span>Create or Connect your ORCID iD</span>&ndash;&gt;-->
<!--&lt;!&ndash; </button>&ndash;&gt;-->
<!-- </div>-->
</div>
</modal-alert>
<fs-modal *ngIf="isMobile" #grantFsModal classTitle="uk-tile-default uk-border-bottom">
<div>{{requestGrantMessage}}</div>
<button class="uk-margin-medium-top uk-button uk-button-primary uk-align-center" (click)="openGrantWindow()">
Grant OpenAIRE
</button>
</fs-modal>
<ng-container *ngIf="pageType == 'my_search'">
<span class="uk-margin-bottom uk-flex uk-flex-middle uk-flex-center">
@ -121,7 +119,8 @@ declare var UIkit: any;
[class]="'uk-button uk-button-default action uk-flex uk-flex-middle '+ ((showLoading || !putCodes || putCodes.length == 0) ? 'uk-disabled' : '')">
<icon *ngIf="!showLoading || currentAction!='get'" name="visibility" ratio="1" flex="true"></icon>
<span *ngIf="showLoading && currentAction=='get'" class="uk-icon icon-button"><loading [top_margin]="false" [size]="'small'"></loading></span>
<span *ngIf="showLoading && currentAction=='get'" class="uk-icon icon-button"><loading [top_margin]="false"
[size]="'small'"></loading></span>
<span class="uk-margin-small-left">View ORCID work</span>
</a>
</span>
@ -133,7 +132,8 @@ declare var UIkit: any;
<a (click)="currentAction='update'; updateWorkPreparation()"
[class]="'uk-button uk-button-default action uk-margin-top uk-flex uk-flex-middle '+ ((showLoading || !putCodes || putCodes.length == 0) ? 'uk-disabled' : '')">
<icon *ngIf="!showLoading || currentAction!='update'" name="refresh" ratio="1" flex="true"></icon>
<span *ngIf="showLoading && currentAction=='update'" class="uk-icon icon-button"><loading [top_margin]="false" [size]="'small'"></loading></span>
<span *ngIf="showLoading && currentAction=='update'" class="uk-icon icon-button"><loading [top_margin]="false"
[size]="'small'"></loading></span>
<span class="uk-margin-small-left">Update ORCID work</span>
</a>
</span>
@ -143,8 +143,9 @@ declare var UIkit: any;
<a (click)="currentAction='add'; saveWorkPreparation();"
[class]="'uk-button uk-button-default action uk-margin-top uk-flex uk-flex-middle '+ (showLoading ? 'uk-disabled' : '')">
<icon *ngIf="!showLoading || currentAction!='add'" name="add" ratio="1" flex="true"></icon>
<span *ngIf="showLoading && currentAction=='add'" class="uk-icon icon-button"><loading [top_margin]="false" [size]="'small'"></loading></span>
<span class="uk-margin-small-left">Add to ORCID</span>
<span *ngIf="showLoading && currentAction=='add'" class="uk-icon icon-button"><loading [top_margin]="false"
[size]="'small'"></loading></span>
<span class="uk-margin-small-left">Claim</span>
</a>
</span>
@ -153,8 +154,9 @@ declare var UIkit: any;
<a (click)="currentAction='delete'; deleteWorks();"
[class]="'uk-button uk-button-default action uk-margin-top uk-flex uk-flex-middle '+ (showLoading ? 'uk-disabled' : '')">
<icon *ngIf="!showLoading || currentAction!='delete'" name="delete" ratio="1" flex="true"></icon>
<span *ngIf="showLoading && currentAction=='delete'" class="uk-icon icon-button"><loading [top_margin]="false" [size]="'small'"></loading></span>
<span class="uk-margin-small-left">Delete from ORCID</span>
<span *ngIf="showLoading && currentAction=='delete'" class="uk-icon icon-button"><loading [top_margin]="false"
[size]="'small'"></loading></span>
<span class="uk-margin-small-left">Remove</span>
</a>
</span>
</ng-container>
@ -228,14 +230,16 @@ declare var UIkit: any;
)">
(
</span>
<span *ngIf="contributor['contributor-attributes'] && contributor['contributor-attributes']['contributor-role']">
<span
*ngIf="contributor['contributor-attributes'] && contributor['contributor-attributes']['contributor-role']">
{{contributor['contributor-attributes']['contributor-role']}}
</span>
<span *ngIf="(contributor['contributor-attributes'] && contributor['contributor-attributes']['contributor-role'])
&& (contributor['contributor-attributes']['contributor-sequence'] || (contributor['contributor-orcid'] && contributor['contributor-orcid']['path']))">
,
</span>
<span *ngIf="contributor['contributor-attributes'] && contributor['contributor-attributes']['contributor-sequence']">
<span
*ngIf="contributor['contributor-attributes'] && contributor['contributor-attributes']['contributor-sequence']">
{{contributor['contributor-attributes']['contributor-sequence']}}
</span>
<span *ngIf="contributor['contributor-attributes'] && contributor['contributor-attributes']['contributor-sequence']
@ -261,33 +265,58 @@ declare var UIkit: any;
<modal-alert #propagationModal (alertOutput)="confirmedPropagation()">
<div>
This {{openaireEntities.RESULT}} is the result of <span class="uk-text-bold"> merged {{openaireEntities.RESULTS}} in OpenAIRE</span>.
This {{openaireEntities.RESULT}} is the result of <span
class="uk-text-bold"> merged {{openaireEntities.RESULTS}} in OpenAIRE</span>.
<br><br>
You have already added <span class="uk-text-bold">{{this.putCodes?.length}} works</span> in your ORCID record related to the merged {{openaireEntities.RESULT}}.
You have already added <span class="uk-text-bold">{{this.putCodes?.length}} works</span> in your ORCID record
related to the merged {{openaireEntities.RESULT}}.
<div *ngIf="currentAction == 'delete'">
If you continue with delete action, <span class="uk-text-bold">all these works will be deleted</span>.
</div>
<div *ngIf="currentAction == 'update'">
If you continue with update action, <span class="uk-text-bold">all these works will be deleted and a new merged work will be added</span> instead.
If you continue with update action, <span class="uk-text-bold">all these works will be deleted and a new merged work will be added</span>
instead.
</div>
</div>
<!-- <div class="uk-margin-medium-top uk-align-right">-->
<!-- <button (click)="closePropagationModal()" type="submit"-->
<!-- class="uk-button uk-padding-small uk-padding-remove-vertical uk-button-default">-->
<!-- <span>Cancel</span>-->
<!-- </button>-->
<!-- <div class="uk-margin-medium-top uk-align-right">-->
<!-- <button (click)="closePropagationModal()" type="submit"-->
<!-- class="uk-button uk-padding-small uk-padding-remove-vertical uk-button-default">-->
<!-- <span>Cancel</span>-->
<!-- </button>-->
<!-- <button (click)="confirmedPropagation()" type="submit"-->
<!-- class="uk-button uk-padding-small uk-padding-remove-vertical uk-margin-left uk-button-primary">-->
<!-- <span>Continue</span>-->
<!-- </button>-->
<!-- </div>-->
<!-- <button (click)="confirmedPropagation()" type="submit"-->
<!-- class="uk-button uk-padding-small uk-padding-remove-vertical uk-margin-left uk-button-primary">-->
<!-- <span>Continue</span>-->
<!-- </button>-->
<!-- </div>-->
</modal-alert>
<fs-modal #propagationFsModal classTitle="uk-tile-default uk-border-bottom">
<div>
This {{openaireEntities.RESULT}} is the result of <span
class="uk-text-bold"> merged {{openaireEntities.RESULTS}} in OpenAIRE</span>.
<br><br>
You have already added <span class="uk-text-bold">{{this.putCodes?.length}} works</span> in your ORCID record
related to the merged {{openaireEntities.RESULT}}.
<div *ngIf="currentAction == 'delete'">
If you continue with delete action, <span class="uk-text-bold">all these works will be deleted</span>.
</div>
<div *ngIf="currentAction == 'update'">
If you continue with update action, <span class="uk-text-bold">all these works will be deleted and a new merged work will be added</span>
instead.
</div>
</div>
<button class="uk-margin-medium-top uk-button uk-button-primary uk-align-center" (click)="confirmedPropagation()">
Continue
</button>
</fs-modal>
`
})
export class OrcidWorkComponent {
@Input() isMobile: boolean = false;
@Input() resultId: string = "";
@Input() resultTitle: string = "";
@Input() resultLandingInfo: ResultLandingInfo;
@ -304,8 +333,10 @@ export class OrcidWorkComponent {
@ViewChild('workModal') workModal;
// @ViewChild('saveWorkModal') saveWorkModal;
@ViewChild('grantModal') grantModal;
@ViewChild('grantFsModal') grantFsModal: FullScreenModalComponent;
// @ViewChild('messageModal') messageModal;
@ViewChild('propagationModal') propagationModal;
@ViewChild('propagationFsModal') propagationFsModal;
public requestGrant: boolean = false;
public requestGrantMessage: string = "Please grant OpenAIRE to access and update your ORCID works.";
@ -332,13 +363,13 @@ export class OrcidWorkComponent {
private orcidService: OrcidService,
private resultLandingService: ResultLandingService,
private userManagementService: UserManagementService) {
if(typeof document !== 'undefined') {
if (typeof document !== 'undefined') {
this.tokenUrl = properties.orcidTokenURL
+ "client_id="+properties.orcidClientId
+ "client_id=" + properties.orcidClientId
// + "&response_type=code&scope=/activities/update"
// + "&response_type=code&scope=/authenticate /activities/update /person/update /read-limited"
+ "&response_type=code&scope=/activities/update /read-limited"
+ "&redirect_uri="+location.origin+"/orcid?source=openaire";
+ "&redirect_uri=" + location.origin + "/orcid?source=openaire";
}
}
@ -346,7 +377,7 @@ export class OrcidWorkComponent {
this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => {
if (user) {
this.isLoggedIn = true;
if(!this.givenPutCode) {
if (!this.givenPutCode) {
this.getPutCode();
}
} else {
@ -369,12 +400,12 @@ export class OrcidWorkComponent {
public showUpdateDatesInTooltip() {
const monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
let response: string = "";
if(this.updateDates != null && this.updateDates.length > 0) {
if (this.updateDates != null && this.updateDates.length > 0) {
response += "<br><br> Last update in ORCID<br>";
for(let i=0; i<this.updateDates.length; i++) {
for (let i = 0; i < this.updateDates.length; i++) {
let date: Date = new Date(this.updateDates[i]);
response += "<span>"+date.getDate() + " " + monthNames[date.getMonth()] + " " + date.getFullYear();
if(i < this.updateDates.length - 1) {
response += "<span>" + date.getDate() + " " + monthNames[date.getMonth()] + " " + date.getFullYear();
if (i < this.updateDates.length - 1) {
response += "& ";
}
response += "</span>";
@ -385,8 +416,8 @@ export class OrcidWorkComponent {
public parseIdentifiers(identifiers: ExternalIDV3_0[]): Map<string, string[]> {
let identifiersMap: Map<string, string[]> = new Map<string, string[]>();
for(let identifier of identifiers) {
if(!identifiersMap.has(identifier['external-id-type'])) {
for (let identifier of identifiers) {
if (!identifiersMap.has(identifier['external-id-type'])) {
identifiersMap.set(identifier['external-id-type'], new Array<string>());
}
identifiersMap.get(identifier['external-id-type']).push(identifier['external-id-value']);
@ -395,9 +426,14 @@ export class OrcidWorkComponent {
}
openGrantWindow() {
if(!Session.isLoggedIn()){
if (!Session.isLoggedIn()) {
//this.userValidMessage = "User session has expired. Please login again.";
this._router.navigate(['/user-info'], { queryParams: { "errorCode": LoginErrorCodes.NOT_VALID, "redirectUrl": this._router.url} });
this._router.navigate(['/user-info'], {
queryParams: {
"errorCode": LoginErrorCodes.NOT_VALID,
"redirectUrl": this._router.url
}
});
} else {
// this.tokenUrl = location.origin+"/orcid";
this.window = window.open(this.tokenUrl, '_blank',
@ -448,7 +484,7 @@ export class OrcidWorkComponent {
}
this.pids = pidsArray.join();
}
if(action == "save") {
if (action == "save") {
this.saveWork();
} else if (action == "update") {
this.updateWork();
@ -462,9 +498,14 @@ export class OrcidWorkComponent {
}
public saveWorkPreparation() {
if(!Session.isLoggedIn()){
if (!Session.isLoggedIn()) {
//this.userValidMessage = "User session has expired. Please login again.";
this._router.navigate(['/user-info'], { queryParams: { "errorCode": LoginErrorCodes.NOT_VALID, "redirectUrl": this._router.url} });
this._router.navigate(['/user-info'], {
queryParams: {
"errorCode": LoginErrorCodes.NOT_VALID,
"redirectUrl": this._router.url
}
});
} else {
if (this.requestGrant) {
@ -490,27 +531,27 @@ export class OrcidWorkComponent {
// this.requestGrant = true;
// this.requestGrantMessage = "Please grant OpenAIRE to access and update your ORCID record and works.";
if(response == null) {
if (response == null) {
this.handleError(null);
console.error("Error posting landing info: null");
} else {
this.putCodes.push(""+response['put-code']);
this.putCodes.push("" + response['put-code']);
this.creationDates.push(response['created-date']['value']);
this.updateDates.push(response['last-modified-date']['value']);
// this.closeGrantModal();
// this.message = "You have successfully added work with pids: "+this.pids+" in your ORCID record!";
this.message = "You have successfully added work \""+this.resultTitle+"\" in your ORCID record!";
this.message = "You have successfully added work \"" + this.resultTitle + "\" in your ORCID record!";
// this.openMessageModal("Work added successfully");
// message: 'You have <strong>successfully added</strong> work with pids: <strong>'+this.pids+'</strong> in your ORCID record!',
UIkit.notification({
message: 'You have <strong>successfully added</strong> work "<strong>'+this.resultTitle+'</strong>" in your ORCID record!'
// +
// '<br><br><a class="uk-link" [href]="goToOrcidLinksPage()">Manager your ORCID links</a>'
message: 'You have <strong>successfully added</strong> work "<strong>' + this.resultTitle + '</strong>" in your ORCID record!'
// +
// '<br><br><a class="uk-link" [href]="goToOrcidLinksPage()">Manager your ORCID links</a>'
,
// '<br><br><a class="uk-link" (click)="goToOrcidLinksPage()">Manager your ORCID links</a>',
// '<br><br><a class="uk-link" routerLinkActive="router-link-active" [routerLink]="myOrcidLinksPage">Manager your ORCID links</a>',
// '<br><br><a class="uk-link" (click)="goToOrcidLinksPage()">Manager your ORCID links</a>',
// '<br><br><a class="uk-link" routerLinkActive="router-link-active" [routerLink]="myOrcidLinksPage">Manager your ORCID links</a>',
status: 'success',
timeout: 6000,
pos: 'bottom-right'
@ -531,13 +572,18 @@ export class OrcidWorkComponent {
}
private updateWorkPreparation() {
if(!Session.isLoggedIn()){
this._router.navigate(['/user-info'], { queryParams: { "errorCode": LoginErrorCodes.NOT_VALID, "redirectUrl": this._router.url} });
if (!Session.isLoggedIn()) {
this._router.navigate(['/user-info'], {
queryParams: {
"errorCode": LoginErrorCodes.NOT_VALID,
"redirectUrl": this._router.url
}
});
} else {
if (this.requestGrant) {
this.openGrantModal("Add, delete or edit work in your ORCID record");
} else if(this.putCodes.length > 1) {
} else if (this.putCodes.length > 1) {
this.openPropagationModal("Update ORCID work");
} else {
this.showLoading = true;
@ -554,14 +600,14 @@ export class OrcidWorkComponent {
private updateWork() {
this.subscriptions.push(this.orcidService.updateWork(this.resultLandingInfo, this.pids, this.putCodes[0]).subscribe(
response => {
if(response) {
if (response) {
this.updateDates[0] = response['last-modified-date'].value;
// message: 'You have <strong>successfully updated</strong> work with pids: <strong>' + this.pids + '</strong> in your ORCID record!',
UIkit.notification({
message: 'You have <strong>successfully updated</strong> work "<strong>' + this.resultTitle + '</strong>" in your ORCID record!'
// +
// '<br><br><a routerLinkActive="router-link-active" [routerLink]="myOrcidLinksPage">Manager your ORCID links</a>'
// +
// '<br><br><a routerLinkActive="router-link-active" [routerLink]="myOrcidLinksPage">Manager your ORCID links</a>'
,
status: 'success',
timeout: 6000,
@ -588,24 +634,29 @@ export class OrcidWorkComponent {
}
public getOrcidWorks() {
if(!Session.isLoggedIn()){
this._router.navigate(['/user-info'], { queryParams: { "errorCode": LoginErrorCodes.NOT_VALID, "redirectUrl": this._router.url} });
if (!Session.isLoggedIn()) {
this._router.navigate(['/user-info'], {
queryParams: {
"errorCode": LoginErrorCodes.NOT_VALID,
"redirectUrl": this._router.url
}
});
} else {
this.showLoading = true;
this.subscriptions.push(this.orcidService.getOrcidWorks(this.putCodes).subscribe(
(response) => {
let error: boolean = true;
if(response && response['bulk']) {
if (response && response['bulk']) {
response = response['bulk'].filter(res => {
return (!res.error && res.work);
});
if(response && response.length > 0) {
if (response && response.length > 0) {
error = false;
this.orcidWorks = response;
this.openWorkModal();
}
}
if(error) {
if (error) {
UIkit.notification({
message: 'There was an error getting this work. </br> Please make sure you have not deleted it from your ORCID iD.',
status: 'warning',
@ -625,13 +676,18 @@ export class OrcidWorkComponent {
public deleteWorks(confirmed: boolean = false) {
if(!Session.isLoggedIn()){
this._router.navigate(['/user-info'], { queryParams: { "errorCode": LoginErrorCodes.NOT_VALID, "redirectUrl": this._router.url} });
if (!Session.isLoggedIn()) {
this._router.navigate(['/user-info'], {
queryParams: {
"errorCode": LoginErrorCodes.NOT_VALID,
"redirectUrl": this._router.url
}
});
} else {
if (this.requestGrant) {
this.openGrantModal("Add, delete or edit work in your ORCID record");
} else if(this.putCodes.length > 1 && !confirmed) {
} else if (this.putCodes.length > 1 && !confirmed) {
this.openPropagationModal("Delete ORCID work");
} else {
this.showLoading = true;
@ -668,7 +724,7 @@ export class OrcidWorkComponent {
this.handleError(null);
console.error("Error deleting landing info: null");
} else {
if(this.currentAction == "update") {
if (this.currentAction == "update") {
this.saveWork();
} else {
// this.closeGrantModal();
@ -679,8 +735,8 @@ export class OrcidWorkComponent {
// message: 'You have <strong>successfully deleted</strong> work with pids: <strong>' + this.pids + '</strong> from your ORCID record!',
UIkit.notification({
message: 'You have <strong>successfully deleted</strong> work "<strong>' + this.resultTitle + '</strong>" from your ORCID record!'
// +
// '<br><br><a routerLinkActive="router-link-active" [routerLink]="myOrcidLinksPage">Manager your ORCID links</a>'
// +
// '<br><br><a routerLinkActive="router-link-active" [routerLink]="myOrcidLinksPage">Manager your ORCID links</a>'
,
status: 'success',
timeout: 6000,
@ -700,12 +756,18 @@ export class OrcidWorkComponent {
}
openGrantModal(title: string) {
this.grantModal.cancelButton = true;
this.grantModal.okButton = true;
this.grantModal.okButtonText = "Grant OpenAIRE";
this.grantModal.okButtonLeft = false;
this.grantModal.alertTitle = title;
this.grantModal.open();
if(this.isMobile) {
this.grantFsModal.okButton = false;
this.grantFsModal.title = title;
this.grantFsModal.open();
} else {
this.grantModal.cancelButton = true;
this.grantModal.okButton = true;
this.grantModal.okButtonText = "Grant OpenAIRE";
this.grantModal.okButtonLeft = false;
this.grantModal.alertTitle = title;
this.grantModal.open();
}
}
closeGrantModal() {
@ -735,12 +797,18 @@ export class OrcidWorkComponent {
// }
openPropagationModal(title: string) {
this.propagationModal.cancelButton = true;
this.propagationModal.okButton = true;
this.propagationModal.okButtonText = "Continue";
this.propagationModal.okButtonLeft = false;
this.propagationModal.alertTitle = title;
this.propagationModal.open();
if(this.isMobile) {
this.propagationFsModal.okButton = false;
this.propagationFsModal.title = title;
this.propagationFsModal.open();
} else {
this.propagationModal.cancelButton = true;
this.propagationModal.okButton = true;
this.propagationModal.okButtonText = "Continue";
this.propagationModal.okButtonLeft = false;
this.propagationModal.alertTitle = title;
this.propagationModal.open();
}
}
closePropagationModal() {
@ -748,33 +816,33 @@ export class OrcidWorkComponent {
}
handleError(error) {
if(error && error.status == "401") {
if (error && error.status == "401") {
this.openGrantModal("Add, delete or edit work in your ORCID record");
this.requestGrant = true;
this.requestGrantMessage = "Please grant OpenAIRE to access and update your ORCID record and works. ";
// + "If you have already granted OpenAIRE, you just need to login again to ORCID!";
} else if(error && error.status == "403") {
// + "If you have already granted OpenAIRE, you just need to login again to ORCID!";
} else if (error && error.status == "403") {
this.openGrantModal("Add, delete or edit work in your ORCID record");
this.requestGrant = true;
this.requestGrantMessage = "Please login again to ORCID."
// this.openGrantModal();
} else {
this.message = "";
if(error && error.status == "409") {
if (error && error.status == "409") {
this.message = "There is <span class='uk-text-bold'>already a work in your ORCID record</span> with the same information of the work you are trying to add now. <br><br>";
}
if(this.currentAction == "get") {
if (this.currentAction == "get") {
// this.message += "There was an <span class='uk-text-bold'>error getting</span> work with pids: <span class='uk-text-bold'>" + this.pids + "</span> from your ORCID record. <br> Please try again later.";
this.message += "There was an <span class='uk-text-bold'>error getting</span> work \"<span class='uk-text-bold'>" + this.resultTitle + "</span>\" from your ORCID record. <br> Please try again later.";
} else if(this.currentAction == "add") {
} else if (this.currentAction == "add") {
// this.message += "There was an <span class='uk-text-bold'>error adding</span> work with pids: <span class='uk-text-bold'>"+this.pids+"</span> to your ORCID record. <br> Please try again later.";
this.message += "There was an <span class='uk-text-bold'>error adding</span> work with pids: \"<span class='uk-text-bold'>"+this.pids+"</span>\" to your ORCID record. <br> Please try again later.";
} else if(this.currentAction == "update") {
this.message += "There was an <span class='uk-text-bold'>error adding</span> work with pids: \"<span class='uk-text-bold'>" + this.pids + "</span>\" to your ORCID record. <br> Please try again later.";
} else if (this.currentAction == "update") {
// this.message += "There was an <span class='uk-text-bold'>error updating</span> work with pids: <span class='uk-text-bold'>"+this.pids+"</span> to your ORCID record. <br> Please try again later.";
this.message += "There was an <span class='uk-text-bold'>error updating</span> work \"<span class='uk-text-bold'>"+this.resultTitle+"</span>\" to your ORCID record. <br> Please try again later.";
} else if(this.currentAction == "delete") {
this.message += "There was an <span class='uk-text-bold'>error updating</span> work \"<span class='uk-text-bold'>" + this.resultTitle + "</span>\" to your ORCID record. <br> Please try again later.";
} else if (this.currentAction == "delete") {
// this.message += "There was an <span class='uk-text-bold'>error deleting</span> work with pids: <span class='uk-text-bold'>"+this.pids+"</span> from your ORCID record. <br> Please try again later.";
this.message += "There was an <span class='uk-text-bold'>error deleting</span> work \"<span class='uk-text-bold'>"+this.resultTitle+"</span>\" from your ORCID record. <br> Please try again later.";
this.message += "There was an <span class='uk-text-bold'>error deleting</span> work \"<span class='uk-text-bold'>" + this.resultTitle + "</span>\" from your ORCID record. <br> Please try again later.";
} else {
this.message += "There was an error. Please try again later."
}
@ -803,14 +871,14 @@ export class OrcidWorkComponent {
}
get tooltipNoLoggedInUser() {
return "Add or delete a work from your <span class=\"text-orcid\">ORCID</span> record. Please log in first."
return "Add or delete a work from your <span class=\"text-orcid\">ORCID</span> record. Please log in first."
}
hoverEvent($event, action: string = "add") {
if(action == "add") {
if (action == "add") {
this.hoverAdd = $event.type == "mouseover";
this.hoverDelete = false;
} else if(action == "delete") {
} else if (action == "delete") {
this.hoverDelete = $event.type == "mouseover";
this.hoverAdd = false;
}

View File

@ -15,11 +15,12 @@ import {ResultLandingUtilsModule} from '../landingPages/landing-utils/resultLand
import {IconsModule} from '../utils/icons/icons.module';
import {IconsService} from "../utils/icons/icons.service";
import {orcid_add, orcid_bin} from "../utils/icons/icons";
import {FullScreenModalModule} from "../utils/modal/full-screen-modal/full-screen-modal.module";
@NgModule({
imports: [
CommonModule, RouterModule, AlertModalModule, LoadingModule, ResultLandingUtilsModule,
IconsModule
IconsModule, FullScreenModalModule
],
declarations: [
OrcidComponent,

View File

@ -3,7 +3,7 @@
@sdgs: #E6233D, #DF9F00, #19A220, #D70023, #FF0B00, #00BFE8, #FFC300, #B10240, #FF5D00,
#F50D86, #FF8A00, #CA8A03, #2B772B, #0098DF, #00B91C, #0069A2, #1C336A;
custom-sdg-dot:after {
.custom-sdg-dot:after {
content: "";
background-image: url("~src/assets/common-assets/sdg/sdg-dot-img.svg");
display: inline-block;

View File

@ -10,12 +10,13 @@
<div class="uk-grid uk-flex uk-flex-middle uk-flex-center" uk-grid>
<div class="uk-width-1-1 uk-width-auto@m"><div id="searchImage"></div></div>
<advanced-search-form class="uk-width-expand uk-padding-remove-vertical"
entityType="all"
[entityType]="activeEntity"
[advancedSearchLink]="advancedSearchLink" [advancedSearchLinkParameters]="parameters"
(queryChange)="keywordChanged($event)"
[isDisabled]="disableForms"
[simpleView]="true" [formPlaceholderText]="formPlaceholderText"
[selectedFields]="selectedFields" [showSwitchSearchLink]="true" [dark]="searchForm.dark"
[fieldIdsMap]="fieldIdsMap" [fieldIds]="fieldIds" [entitiesSelection]="true" [customFilter]="customFilter"
[fieldIdsMap]="fieldIdsMap" [fieldIds]="fieldIds" [entitiesSelection]="false" [customFilter]="customFilter"
>
</advanced-search-form>
</div>
@ -26,9 +27,10 @@
</div>
<schema2jsonld *ngIf="name && logoURL" [URL]="properties.domain+ properties.baseLink +'/search/find'"
[logoURL]="properties.domain + properties.baseLink+logoURL" type="search" [name]=name
description="Search for {{openaireEntities.RESULTS}} ({{openaireEntities.PUBLICATIONS}}, {{openaireEntities.DATASETS}}, {{openaireEntities.SOFTWARE}}, {{openaireEntities.OTHER}}), {{openaireEntities.PROJECTS}}, {{openaireEntities.ORGANIZATIONS}}, {{openaireEntities.DATASOURCES}} in the OpenAIRE Research Graph. "></schema2jsonld>
<div class="uk-container-large uk-container uk-margin-large-top uk-margin-medium-bottom">
<div class="uk-width-1-1" uk-slider="finite: true">
description="Search for {{openaireEntities.RESULTS}} ({{openaireEntities.PUBLICATIONS}}, {{openaireEntities.DATASETS}}, {{openaireEntities.SOFTWARE}}, {{openaireEntities.OTHER}}), {{openaireEntities.PROJECTS}}, {{openaireEntities.ORGANIZATIONS}}, {{openaireEntities.DATASOURCES}} in the OpenAIRE Graph. "></schema2jsonld>
<div class="uk-container-large uk-container uk-margin-top">
<div class="uk-width-1-1 uk-background-default uk-padding-small uk-padding-remove-horizontal"
uk-slider="finite: true" uk-sticky="media: @m" [attr.offset]="offset">
<div class="uk-position-relative">
<div class="uk-slider-container">
<ul class="uk-slider-items uk-flex uk-flex-center" style="flex-wrap: nowrap !important;">
@ -37,7 +39,7 @@
<li [class.uk-active]="activeEntity == 'result'">
<a class="uk-text-uppercase">
{{resultsName}}
<span *ngIf=" fetchPublications.searchUtils.totalResults!=null">
<span *ngIf=" fetchPublications.searchUtils.totalResults!=null" class="uk-visible@m">
({{fetchPublications.searchUtils.totalResults | number}})</span>
</a>
</li>
@ -48,7 +50,7 @@
<li [class.uk-active]="activeEntity == 'projects'">
<a class="uk-text-uppercase">
{{projectName}}
<span *ngIf="fetchProjects.searchUtils.totalResults!=null">
<span *ngIf="fetchProjects.searchUtils.totalResults!=null" class="uk-visible@m">
({{fetchProjects.searchUtils.totalResults | number}})</span>
</a>
</li>
@ -59,7 +61,7 @@
<li [class.uk-active]="activeEntity == 'datasources'">
<a class="uk-text-uppercase">
{{dataSourcesName}}
<span *ngIf="fetchDataproviders.searchUtils.totalResults!=null">
<span *ngIf="fetchDataproviders.searchUtils.totalResults!=null" class="uk-visible@m">
({{fetchDataproviders.searchUtils.totalResults | number}})</span>
</a>
</li>
@ -70,7 +72,7 @@
<li [class.uk-active]="activeEntity == 'services'">
<a class="uk-text-uppercase">
{{servicesName}}
<span *ngIf="fetchServices.searchUtils.totalResults!=null">
<span *ngIf="fetchServices.searchUtils.totalResults!=null" class="uk-visible@m">
({{fetchServices.searchUtils.totalResults | number}})</span>
</a>
</li>
@ -81,7 +83,7 @@
<li [class.uk-active]="activeEntity == 'organizations'">
<a class="uk-text-uppercase">
{{organizationsName}}
<span *ngIf="fetchOrganizations.searchUtils.totalResults!=null">
<span *ngIf="fetchOrganizations.searchUtils.totalResults!=null" class="uk-visible@m">
({{fetchOrganizations.searchUtils.totalResults | number}})</span>
</a>
</li>
@ -99,25 +101,25 @@
<search-research-results *ngIf="activeEntity == 'result'" resultType="result" [includeOnlyResultsAndFilter]="true"
(searchPageUpdates)="activeEntityUpdate($event)" [showSwitchSearchLink]="false"
simpleSearchLink="/search/find" [customFilter]="customFilter"></search-research-results>
[simpleSearchLink]="properties.searchLinkToResults" [customFilter]="customFilter"></search-research-results>
<search-projects *ngIf="activeEntity == 'projects'" [includeOnlyResultsAndFilter]="true" [showSwitchSearchLink]="false"
(searchPageUpdates)="activeEntityUpdate($event)"
simpleSearchLink="/search/find" [customFilter]="customFilter">
[simpleSearchLink]="properties.searchLinkToProjects" [customFilter]="customFilter">
</search-projects>
<search-organizations *ngIf="activeEntity == 'organizations'" [includeOnlyResultsAndFilter]="true" [showSwitchSearchLink]="false"
(searchPageUpdates)="activeEntityUpdate($event)"
simpleSearchLink="/search/find" [customFilter]="customFilter">
[simpleSearchLink]="properties.searchLinkToOrganizations" [customFilter]="customFilter">
</search-organizations>
<search-dataproviders *ngIf="activeEntity == 'datasources'" [includeOnlyResultsAndFilter]="true" [showSwitchSearchLink]="false"
(searchPageUpdates)="activeEntityUpdate($event)"
simpleSearchLink="/search/find" [customFilter]="customFilter">
[simpleSearchLink]="properties.searchLinkToDataProviders" [customFilter]="customFilter">
</search-dataproviders>
<search-dataproviders *ngIf="activeEntity == 'services'" [includeOnlyResultsAndFilter]="true" [showSwitchSearchLink]="false"
(searchPageUpdates)="activeEntityUpdate($event)"
simpleSearchLink="/search/find" [customFilter]="customFilter"
[simpleSearchLink]="properties.searchLinkToServices" [customFilter]="customFilter"
type="services" entityType="service" [typeName]="openaireEntities.SERVICES">
</search-dataproviders>

View File

@ -32,12 +32,15 @@ import {SearchDataProvidersComponent} from "../searchDataProviders.component";
import {NewSearchPageComponent, SearchForm} from "../searchUtils/newSearchPage.component";
import {properties} from "../../../../environments/environment";
import {Breadcrumb} from "../../utils/breadcrumbs/breadcrumbs.component";
import {LayoutService} from "../../dashboard/sharedComponents/sidebar/layout.service";
@Component({
selector: 'search-all',
templateUrl: 'searchAll.component.html'
})
export class SearchAllComponent {
isMobile: boolean = false;
reload:{result:boolean, projects:boolean, datasources: boolean, services: boolean, organizations:boolean} =
{result:true, projects:true, datasources: true, services: true, organizations:true};
public pageTitle = "Search in OpenAIRE"
@ -78,14 +81,16 @@ export class SearchAllComponent {
showDataProviders: boolean = false;
showServices: boolean = false;
showOrganizations: boolean = false;
advancedSearchLink: string = "/search/advanced/publications";
advancedSearchLink: string = properties.searchLinkToAdvancedResults;
properties: EnvProperties;
offset: number;
public openaireEntities = OpenaireEntities;
@Input() logoURL;
@Input() name;
@Input() customFilter: SearchCustomFilter = null;
@Input() piwikSiteId = null;
@Input() formPlaceholderText = "Search for "+OpenaireEntities.RESULTS+", "+OpenaireEntities.PROJECTS+", "+OpenaireEntities.DATASOURCES+" & "+OpenaireEntities.ORGANIZATIONS+" in OpenAIRE";
@Input() formPlaceholderText = "Search in Explore"
// @Input() formPlaceholderText = "Search for "+OpenaireEntities.RESULTS+", "+OpenaireEntities.PROJECTS+", "+OpenaireEntities.DATASOURCES+" & "+OpenaireEntities.ORGANIZATIONS+" in OpenAIRE";
@Input() searchForm: SearchForm = {class: 'search-form', dark: true}
@Input() breadcrumbs: Breadcrumb[] = [];
@ -125,6 +130,7 @@ export class SearchAllComponent {
private _title: Title,
private _piwikService: PiwikService,
private config: ConfigurationService,
private layoutService: LayoutService,
private seoService: SEOService, private router: Router, private cdr:ChangeDetectorRef) {
this.fetchPublications = new FetchResearchResults(this._searchResearchResultsService);
this.fetchDataproviders = new FetchDataproviders(this._searchDataprovidersService);
@ -141,8 +147,7 @@ export class SearchAllComponent {
public ngOnInit() {
var description = "Search for "+OpenaireEntities.RESULTS+" ("+OpenaireEntities.PUBLICATIONS+", "+OpenaireEntities.DATASETS+", "+OpenaireEntities.SOFTWARE+", "+OpenaireEntities.OTHER+"), "+OpenaireEntities.PROJECTS+", "+OpenaireEntities.ORGANIZATIONS+", "+OpenaireEntities.DATASOURCES+" in the OpenAIRE Research Graph. ";
var description = "Search for "+OpenaireEntities.RESULTS+" ("+OpenaireEntities.PUBLICATIONS+", "+OpenaireEntities.DATASETS+", "+OpenaireEntities.SOFTWARE+", "+OpenaireEntities.OTHER+"), "+OpenaireEntities.PROJECTS+", "+OpenaireEntities.ORGANIZATIONS+", "+OpenaireEntities.DATASOURCES+" in the OpenAIRE Graph. ";
var title = "OpenAIRE |Search for "+OpenaireEntities.RESULTS+", "+OpenaireEntities.PROJECTS+", "+OpenaireEntities.DATASOURCES+" & "+OpenaireEntities.ORGANIZATIONS;
this.properties = properties;
var url = this.properties.domain + this.properties.baseLink + this._router.url;
@ -195,46 +200,78 @@ export class SearchAllComponent {
this.showDataProviders = true;
this.showServices = false;
}
this.loadAll();
}
this.loadAll();
this.subs.push(this.layoutService.isMobile.subscribe(isMobile => {
this.isMobile = isMobile;
if (typeof document !== 'undefined') {
if(!this.isMobile && document.getElementById("main-menu")) {
this.offset = Number.parseInt(getComputedStyle(document.documentElement).getPropertyValue('--header-height'));
this.cdr.detectChanges();
} else {
this.offset = 0;
this.cdr.detectChanges();
}
}
}))
}
loadAll() {
this.reloadTabs();
this.subs.push(this.route.queryParams.subscribe(params => {
this.parameters = Object.assign({}, params);
this.keyword = (params['keyword']) ? params['keyword'] : (params["q"] ? params["q"] : (params["f0"] && params["f0"] == "q" && params["fv0"]?params["fv0"]:""));
this.subs.push(this.route.queryParams.subscribe(queryParams => {
this.parameters = Object.assign({}, queryParams);
this.keyword = (queryParams['keyword']) ? queryParams['keyword'] : (queryParams["q"] ? queryParams["q"] : (queryParams["f0"] && queryParams["f0"] == "q" && queryParams["fv0"]?queryParams["fv0"]:""));
this.selectedFields[0].value = StringUtils.URIDecode(this.keyword);
this.quickFilter.selected = ((params['qf']== undefined || params["qf"] == "true") == true);
if (params["type"] && params["type"].length > 0) {
this.resultTypes['publication'] = (params["type"].split(",").indexOf("publications") != -1);
this.resultTypes['dataset'] = (params["type"].split(",").indexOf("datasets") != -1);
this.resultTypes['software'] = (params["type"].split(",").indexOf("software") != -1);
this.resultTypes['other'] = (params["type"].split(",").indexOf("other") != -1);
this.quickFilter.selected = ((queryParams['qf']== undefined || queryParams["qf"] == "true") == true);
if (queryParams["type"] && queryParams["type"].length > 0) {
this.resultTypes['publication'] = (queryParams["type"].split(",").indexOf("publications") != -1);
this.resultTypes['dataset'] = (queryParams["type"].split(",").indexOf("datasets") != -1);
this.resultTypes['software'] = (queryParams["type"].split(",").indexOf("software") != -1);
this.resultTypes['other'] = (queryParams["type"].split(",").indexOf("other") != -1);
}
if(this.activeEntity == null && (!params["active"] || params["active"].length ==0)){
this.activeEntity = this.getDefaultEntityToShow();
}else if(params["active"] && params["active"].length >0 ){
this.activeEntity = ((["result","projects","organizations","datasources","services"]).indexOf(params["active"])!= -1)?params["active"]:this.getDefaultEntityToShow();
}else if (this.activeEntity !=null && (!params["active"] || params["active"].length ==0)){
this.parameters["active"]=this.activeEntity;
if((typeof document !== 'undefined') && location.search && location.search.indexOf("active=") == -1){
this.location.go(location.pathname, ((location.search)?(location.search+"&"):("?")) +"active=" + this.activeEntity);
let active = null;
if (queryParams["active"] && queryParams["active"].length > 0) {
active = ((["result","projects","organizations","datasources","services"]).indexOf(queryParams["active"])!= -1)?queryParams["active"]:null;
delete this.parameters['active'];
}
this.subs.push(this.route.params.subscribe(params => {
if(this.activeEntity == null && (!params["entity"] || params["entity"].length == 0)){
if (active) {
this.activeEntity = active;
if((typeof document !== 'undefined')){
if (active == "result") {
active = "research-outcomes";
}
let query = location.search.replace(/(active=)([^&]*)&?/, '');
this.location.go(location.pathname + '/' + active, query == '?' ? '' : query);
}
} else {
this.activeEntity = this.getDefaultEntityToShow();
}
} else if(params["entity"] && params["entity"].length > 0 ){
let entity = params["entity"];
if(entity == "research-outcomes") {
entity = "result";
} else if (entity == "dataproviders") {
entity = "datasources";
}
this.activeEntity = ((["result","projects","organizations","datasources","services"]).indexOf(entity)!= -1)?entity:this.getDefaultEntityToShow();
}
}
if (this.activeEntity == "result") {
this.searchResults();
} else if (this.activeEntity == "projects") {
this.searchProjects();
} else if (this.activeEntity == "datasources") {
this.searchDataProviders();
} else if (this.activeEntity == "services") {
this.searchServices();
} else if (this.activeEntity == "organizations") {
this.searchOrganizations();
}
this.count();
if (this.activeEntity == "result") {
this.searchResults();
} else if (this.activeEntity == "projects") {
this.searchProjects();
} else if (this.activeEntity == "datasources") {
this.searchDataProviders();
} else if (this.activeEntity == "services") {
this.searchServices();
} else if (this.activeEntity == "organizations") {
this.searchOrganizations();
}
this.count();
}));
}));
}
@ -265,7 +302,9 @@ export class SearchAllComponent {
}
public searchResults() {
this.advancedSearchLink = this.properties.searchLinkToAdvancedPublications;//"/search/advanced/publications";
this.advancedSearchLink = this.properties.searchLinkToAdvancedResults;//"/search/advanced/research-outcomes";
this.formPlaceholderText = "Search by title, author, abstract, DOI, orcid...";
if (this.reload[this.activeEntity] &&
this.fetchPublications.searchUtils.status != this.errorCodes.NONE) {
this.reload[this.activeEntity] = false;
@ -276,6 +315,8 @@ export class SearchAllComponent {
public searchProjects() {
this.advancedSearchLink = this.properties.searchLinkToAdvancedProjects;//"/search/advanced/projects";
this.formPlaceholderText = "Search by title, acronym, project code...";
if (this.reload[this.activeEntity] &&
this.fetchProjects.searchUtils.status != this.errorCodes.NONE ) {
this.reload[this.activeEntity] = false;
@ -285,6 +326,8 @@ export class SearchAllComponent {
public searchDataProviders() {
this.advancedSearchLink = this.properties.searchLinkToAdvancedDataProviders;//"/search/advanced/dataproviders";
this.formPlaceholderText = "Search by name, description, subject...";
if ( this.reload[this.activeEntity] &&
this.fetchDataproviders.searchUtils.status != this.errorCodes.NONE) {
this.reload[this.activeEntity] = false;
@ -294,6 +337,8 @@ export class SearchAllComponent {
public searchServices() {
this.advancedSearchLink = this.properties.searchLinkToAdvancedServices;//"/search/advanced/services";
this.formPlaceholderText = "Search by name, description, subject...";
if ( this.reload[this.activeEntity] &&
this.fetchServices.searchUtils.status != this.errorCodes.NONE) {
this.reload[this.activeEntity] = false;
@ -303,6 +348,8 @@ export class SearchAllComponent {
public searchOrganizations() {
this.advancedSearchLink = this.properties.searchLinkToAdvancedOrganizations;//"/search/advanced/organizations";
this.formPlaceholderText = "Search by organization name...";
if (this.reload[this.activeEntity] &&
this.fetchOrganizations.searchUtils.status != this.errorCodes.NONE) {
this.reload[this.activeEntity] = false;
@ -532,33 +579,38 @@ export class SearchAllComponent {
}
}
entityChanged(entity){
if(this.activeEntity == "result") {
this.resultTypes = {publication: true, dataset: true, software: true, other: true};
}
if(this.activeEntity == "result" && this.searchResearchResultsComponent){
this.searchResearchResultsComponent.ngOnDestroy();
}else if(this.activeEntity == "projects" && this.searchProjectsComponent){
this.searchProjectsComponent.ngOnDestroy();
}else if(this.activeEntity == "datasources" && this.searchDataprovidersComponent){
this.searchDataprovidersComponent.ngOnDestroy();
}else if(this.activeEntity == "services" && this.searchDataprovidersComponent){
this.searchDataprovidersComponent.ngOnDestroy();
}else if(this.activeEntity == "organizations" && this.searchOrganizationsComponent){
this.searchOrganizationsComponent.ngOnDestroy();
}
this.activeEntity = entity;
entityChanged(entity) {
if (this.activeEntity !== entity) {
if (this.activeEntity == "result") {
this.resultTypes = {publication: true, dataset: true, software: true, other: true};
}
if (this.activeEntity == "result" && this.searchResearchResultsComponent) {
this.searchResearchResultsComponent.ngOnDestroy();
} else if (this.activeEntity == "projects" && this.searchProjectsComponent) {
this.searchProjectsComponent.ngOnDestroy();
} else if (this.activeEntity == "datasources" && this.searchDataprovidersComponent) {
this.searchDataprovidersComponent.ngOnDestroy();
} else if (this.activeEntity == "services" && this.searchDataprovidersComponent) {
this.searchDataprovidersComponent.ngOnDestroy();
} else if (this.activeEntity == "organizations" && this.searchOrganizationsComponent) {
this.searchOrganizationsComponent.ngOnDestroy();
}
this.activeEntity = entity;
this.parameters = {};
this.reload[entity]= true;
this.parameters["active"] = entity;
if ( this.keyword.length > 0) {
this.parameters["fv0"] = this.keyword;
this.parameters["f0"] = "q";
}
if(this.customFilter){
this.parameters = this.customFilter.getParameters(this.parameters);
}
this.router.navigate(["/search/find"], {queryParams: this.parameters});
this.reload[entity] = true;
if (this.keyword.length > 0) {
this.parameters["fv0"] = this.keyword;
this.parameters["f0"] = "q";
}
if (this.customFilter) {
this.parameters = this.customFilter.getParameters(this.parameters);
}
if (entity == "result") {
entity = "research-outcomes";
this.parameters["resultbestaccessright"] = '"' + encodeURIComponent("Open Access") + '"';
}
this.router.navigate(["/search/find", entity], {queryParams: this.parameters});
}
}
}

View File

@ -35,7 +35,7 @@ import {properties} from "../../../environments/environment";
[includeOnlyResultsAndFilter]="includeOnlyResultsAndFilter"
[piwikSiteId]=piwikSiteId [hasPrefix]="hasPrefix"
[searchForm]="searchForm"
[entitiesSelection]="type=='all' || type == 'services'" [showSwitchSearchLink]="showSwitchSearchLink"
[entitiesSelection]="false" [showSwitchSearchLink]="showSwitchSearchLink"
[filters]="filters"
[simpleView]="simpleView" formPlaceholderText="Search by name, description, subject..."
[showResultCount]="true" [showIndexInfo]="type!='deposit'"

View File

@ -136,7 +136,7 @@
<span class="uk-flex uk-flex-middle">
<icon name="search" [flex]="true"></icon>
<span class="uk-margin-small-left">Search</span>
<span *ngIf="selectedFields.length >= 2" class="uk-margin-xsmall-left">({{selectedFields.length}} Rules)</span>
<!-- <span *ngIf="selectedFields.length >= 2" class="uk-margin-xsmall-left">({{selectedFields.length}} Rules)</span> -->
</span>
</button>
</a>
@ -146,7 +146,8 @@
<div *ngIf="simpleView" class="uk-flex uk-flex-center uk-flex-wrap">
<div class="uk-width-xlarge@l uk-width-large">
<div class="uk-text-small uk-flex uk-flex-right" [class.uk-light]="dark" *ngIf="showSwitchSearchLink">
<a *ngIf ="this.entityType !='all' && this.entityType == this.selectedEntity && advancedSearchLink"
<!-- && this.entityType == this.selectedEntity-->
<a *ngIf ="this.entityType !='all' && advancedSearchLink"
[routerLink]="advancedSearchLink" [queryParams]="advancedSearchLinkParameters" class="uk-margin-small-bottom"
[ngClass]="(isDisabled)?'uk-disabled uk-link-muted':null">Advanced search
</a>
@ -163,25 +164,29 @@
</div>
<div class="uk-flex uk-flex-center uk-child-width-1-1">
<ng-container *ngIf="entitiesSelection">
<advanced-search-input [class.uk-hidden]="disableSelect" [dark]="dark" [disabled]="isDisabled" (searchEmitter)="simpleKeywordChanged()">
<!-- [class.uk-hidden]="disableSelect" -->
<advanced-search-input [dark]="dark" [disabled]="isDisabled" (searchEmitter)="simpleKeywordChanged()">
<entities-selection [simpleView]="true" [currentEntity]="entityType"
(selectionChange)="simpleEntityChanged($event)" (disableSelectEmitter)="disableSelectChange($event)"
[onChangeNavigate]="true" [customFilter]="customFilter" class="uk-width-2-5"></entities-selection>
<div class="uk-width-expand" input placeholder="Scholary works" [searchable]="true" [hint]="formPlaceholderText"
[onChangeNavigate]="true" [customFilter]="customFilter" class="uk-width-2-5"></entities-selection> -->
<div class="uk-width-expand" input placeholder="Search in Explore" [searchable]="true" [hint]="formPlaceholderText"
[(value)]="selectedFields[0].value" tooltip="true"></div>
<!-- <a *ngIf="isMobile" href="#mobile-filters" filters-toggle (click)="filtersClicked.emit(true)" uk-toggle>-->
<!-- <icon name="filters"></icon>-->
<!-- </a>-->
</advanced-search-input>
<div *ngIf="selectedFields[0] && disableSelect" search-input [disabled]="isDisabled" [(value)]="selectedFields[0].value"
[placeholder]="formPlaceholderText" (searchEmitter)="simpleKeywordChanged()" [iconPosition]="isMobile?'left':'right'">
<a *ngIf="isMobile" href="#mobile-filters" filters-toggle (click)="filtersClicked.emit(true)" uk-toggle>
<icon name="filters"></icon>
</a>
</div>
[searchInputClass]="'inner background'" [placeholder]="formPlaceholderText" (searchEmitter)="simpleKeywordChanged()">
<!-- <a *ngIf="isMobile" href="#mobile-filters" filters-toggle (click)="filtersClicked.emit(true)" uk-toggle>-->
<!-- <icon name="filters"></icon>-->
<!-- </a>-->
</div>
</ng-container>
<div *ngIf="selectedFields[0] && !entitiesSelection" search-input [disabled]="isDisabled" [(value)]="selectedFields[0].value"
[placeholder]="formPlaceholderText" (searchEmitter)="simpleKeywordChanged()" [iconPosition]="isMobile?'left':'right'">
<a *ngIf="isMobile" href="#mobile-filters" filters-toggle (click)="filtersClicked.emit(true)" uk-toggle>
<icon name="filters"></icon>
</a>
[searchInputClass]="'inner background'" [placeholder]="formPlaceholderText" (searchEmitter)="simpleKeywordChanged()">
<!-- <a *ngIf="isMobile" href="#mobile-filters" filters-toggle (click)="filtersClicked.emit(true)" uk-toggle>-->
<!-- <icon name="filters"></icon>-->
<!-- </a>-->
</div>
</div>
</div>

View File

@ -116,7 +116,7 @@ export class AdvancedSearchFormComponent implements OnInit, OnDestroy, OnChanges
simpleKeywordChanged() {
// this.selectedFields[0].value = $event.value;
if (this.selectedEntity == this.entityType) {
if ((this.selectedEntity == this.entityType) || !this.entitiesSelection) {
this.queryChanged();
} else {
this.router.navigate([this.selectedEntitySimpleUrl], {queryParams: {q: this.selectedFields[0].value, op: "and"}});

View File

@ -71,6 +71,15 @@
</div>
</h1>
</ng-template>
<ng-template #search_filter let-filter="filter">
<search-filter [filterValuesNum]="filterValuesNum" [showMoreInline]="showMoreFilterValuesInline"
[isDisabled]="disabled"
[filter]="filter" [showResultCount]=showResultCount
(onFilterChange)="filterChanged($event)"
[actionRoute]="true"></search-filter>
</ng-template>
<ng-template #filters_column>
<div [class.filterLoading]="disabled">
<div class="uk-flex uk-flex-middle">
@ -91,25 +100,43 @@
<span *ngIf="searchUtils.refineStatus != errorCodes.NONE" class="uk-text-warning">Filters temporarily unavailable. Please try again later.</span>
</div>
<ul *ngIf="!showUnknownFilters" class="uk-list uk-list-xlarge">
<li *ngIf="filters.length > 0 && filters[0].values.length >0 && filters[0].filterId == 'resultbestaccessright'">
<search-filter [filterValuesNum]="filterValuesNum" [showMoreInline]="showMoreFilterValuesInline"
[isDisabled]="disabled"
[filter]="filters[0]" [showResultCount]=showResultCount
(onFilterChange)="filterChanged($event)" [quickFilter]="quickFilter"
[actionRoute]="true"></search-filter>
<li *ngIf="filters.length > 0 && getFilterById('resultbestaccessright') && getFilterById('resultbestaccessright').values.length >0">
<ng-container *ngTemplateOutlet="search_filter; context: {filter: getFilterById('resultbestaccessright')}"></ng-container>
</li>
<li *ngFor="let filter of rangeFilters">
<range-filter [isDisabled]="disabled" [filter]="filter"
(onFilterChange)="filterChanged($event)" [actionRoute]="true"></range-filter>
<li *ngIf="resultTypes && (filters.length > 0)">
<quick-selections [resultTypes]="resultTypes" (typeChange)="queryChanged($event)"
[isDisabled]="disabled" [vertical]="true"
[actionRoute]="true">
</quick-selections>
</li>
<ng-container *ngFor="let filter of filters ">
<li *ngIf="filter.values && filter.values.length > 0 && filter.filterId != 'resultbestaccessright'">
<search-filter [filterValuesNum]="filterValuesNum" [showMoreInline]="showMoreFilterValuesInline"
[isDisabled]="disabled"
[filter]="filter" [showResultCount]=showResultCount
(onFilterChange)="filterChanged($event)" [actionRoute]="true"></search-filter>
<li *ngIf="filters.length > 0 && getFilterById('instancetypename') && getFilterById('instancetypename').values.length >0">
<ng-container *ngTemplateOutlet="search_filter; context: {filter: getFilterById('instancetypename')}"></ng-container>
</li>
<ng-container *ngIf="entityType == 'result'">
<li *ngFor="let filter of rangeFilters">
<range-filter [isDisabled]="disabled" [filter]="filter"
(onFilterChange)="filterChanged($event)" [actionRoute]="true"></range-filter>
</li>
</ng-container>
<ng-container *ngFor="let filter of filters ">
<li *ngIf="filter.values && filter.values.length > 0
&& filter.filterId != 'resultbestaccessright' && filter.filterId != 'instancetypename' && filter.filterId != 'projectoamandatepublications'">
<!-- <search-filter [filterValuesNum]="filterValuesNum" [showMoreInline]="showMoreFilterValuesInline"-->
<!-- [isDisabled]="disabled"-->
<!-- [filter]="filter" [showResultCount]=showResultCount-->
<!-- (onFilterChange)="filterChanged($event)" [actionRoute]="true"></search-filter>-->
<ng-container *ngTemplateOutlet="search_filter; context: {filter: filter}"></ng-container>
</li>
</ng-container>
<ng-container *ngIf="entityType == 'project'">
<li *ngFor="let filter of rangeFilters">
<range-filter [isDisabled]="disabled" [filter]="filter"
(onFilterChange)="filterChanged($event)" [actionRoute]="true"></range-filter>
</li>
</ng-container>
<li *ngIf="filters.length > 0 && getFilterById('projectoamandatepublications') && getFilterById('projectoamandatepublications').values.length >0">
<ng-container *ngTemplateOutlet="search_filter; context: {filter: getFilterById('projectoamandatepublications')}"></ng-container>
</li>
</ul>
</div>
</ng-template>
@ -139,12 +166,23 @@
</div>
</ng-template>
<ng-template #main let-mobile="mobile">
<div *ngIf="mobile && showRefine && (searchUtils.refineStatus != errorCodes.LOADING || existingFiltersWithValues !== 0)"
class="filters-toggle-button">
<button href="#mobile-filters" uk-toggle="target: #mobile-filters"
class="uk-icon-button uk-button-secondary uk-flex uk-flex-middle"
(click)="showOffCanvas = true; detectChanges()"
[disabled]="disabled"
[class.uk-disabled]="disabled">
<icon name="filters" [flex]="true" ratio="1.2" visuallyHidden="filters"></icon>
</button>
</div>
<!-- TODO - Clean up -->
<div *ngIf="!includeOnlyResultsAndFilter" [class]="usedBy != 'deposit' && usedBy != 'orcid' && (!customFilter || customFilter.queryFieldName != 'communityId') ?
(stickyForm?'':' ') :
(+ (stickyForm?'':' uk-section') +' uk-padding-remove-bottom uk-padding-remove-top ' +
((usedBy == 'deposit' || usedBy == 'orcid') ? ' uk-padding-remove-top ' : ' '))"
[attr.uk-sticky]="((stickyForm || mobile)?'{offset:100;top:90;cls-active:uk-active uk-sticky-below;cls-inactive:uk-sticky '+
[attr.uk-sticky]="((stickyForm || (simpleView && mobile))?'{offset:100;top:90;cls-active:uk-active uk-sticky-below;cls-inactive:uk-sticky '+
(usedBy != 'deposit' && usedBy != 'orcid' && (!customFilter || customFilter.queryFieldName != 'communityId') ?
' uk-position-relative ' :(' uk-section ' ))+'}':null)">
<div class="uk-background-norepeat uk-background-bottom-center" [ngClass]="searchForm.class">
@ -171,7 +209,7 @@
[advancedSearchLinkParameters]="this.routerHelper.createQueryParams(this.parameterNames, this.parameterValues)"
[simpleView]="simpleView" [formPlaceholderText]="formPlaceholderText" [isMobile]="mobile"
[resultTypes]="resultTypes" [quickFilter]="quickFilter" [entitiesSelection]="entitiesSelection"
[showSwitchSearchLink]="showSwitchSearchLink" [customFilter]="customFilter" (filtersClicked)="showOffCanvas = $event"
[showSwitchSearchLink]="showSwitchSearchLink" [customFilter]="customFilter"
>
</advanced-search-form>
</div>
@ -191,16 +229,16 @@
<div [class.uk-margin-top]="properties.adminToolsPortalType == 'eosc'" >
<helper *ngIf="pageContents && pageContents['top'] && pageContents['top'].length > 0"
[texts]="pageContents['top']"></helper>
<div *ngIf="resultTypes" class="uk-flex uk-flex-center uk-padding-small uk-padding-remove-vertical uk-background-muted uk-border-rounded">
<quick-selections class="uk-margin-bottom uk-margin-top" [resultTypes]="resultTypes" (typeChange)="queryChanged($event)"
[isDisabled]="disabled" [actionRoute]="true">
</quick-selections>
</div>
<!-- <div *ngIf="resultTypes" class="uk-flex uk-flex-center uk-padding-small uk-padding-remove-vertical uk-background-muted uk-border-rounded">-->
<!-- <quick-selections class="uk-margin-bottom uk-margin-top" [resultTypes]="resultTypes" (typeChange)="queryChanged($event)"-->
<!-- [isDisabled]="disabled" [actionRoute]="true">-->
<!-- </quick-selections>-->
<!-- </div>-->
<div [class]="showRefine? 'uk-width-4-5@m uk-width-4-5@l uk-width-1-1@s' :'uk-width-1-1'">
<div *ngIf="showRefine && mobile">
<div #mobileFilters id="mobile-filters" uk-offcanvas="overlay: true">
<div class="uk-offcanvas-bar uk-padding-remove-horizontal">
<a class="uk-offcanvas-close uk-icon uk-close" (click)="showOffCanvas=false">
<a class="uk-offcanvas-close uk-icon uk-close" (click)="showOffCanvas=false; detectChanges()">
<icon name="close" ratio="1.5" visuallyHidden="close filters"></icon>
</a>
<div *ngIf="showOffCanvas" class="uk-padding-small uk-padding-remove-vertical">
@ -252,14 +290,20 @@
[href]="openaireLink+this.routerHelper.createQueryParamsString(this.parameterNames, this.parameterValues)"
target="_blank"> OpenAIRE - Explore</a>.
</div>
<div class="uk-flex uk-flex-between uk-flex-middle uk-flex-wrap">
<div class="uk-flex uk-flex-middle uk-flex-wrap uk-child-width-1-1 uk-child-width-auto@m" [class.uk-flex-between]="!mobile"
[class.uk-margin-top]="mobile">
<!-- Total results, number of pages -->
<h6 class="uk-margin-remove">
<div class="uk-width-xlarge@m uk-margin-remove-bottom uk-text-truncate uk-margin-medium-right" [class.uk-h6]="!mobile" [class.uk-text-center]="mobile">
<ng-container *ngIf="results && searchUtils.totalResults > 0">
<span>{{searchUtils.totalResults|number}}</span>
<span class="uk-text-meta uk-text-capitalize"> {{type}}, page </span>
<span>{{searchUtils.page | number}}</span>
<span class="uk-text-meta"> of {{(totalPages(searchUtils.totalResults)|number)}}</span>
<span class="uk-text-meta uk-text-capitalize"> {{type}}</span>
<ng-container *ngIf="searchTerm && simpleView">
<span class="uk-text-meta"> for </span>
<span class="uk-text-bold">{{searchTerm}}</span>
</ng-container>
<ng-container *ngIf="!simpleView && advancedSearchTerms > 0">
<span class="uk-text-bold"> ({{advancedSearchTerms}} rule{{advancedSearchTerms == 1 ? '' : 's'}} applied)</span>
</ng-container>
</ng-container>
<ng-container *ngIf="!loadPaging && oldTotalResults > 0 && searchUtils.status == errorCodes.LOADING">
<span>{{oldTotalResults|number}}</span>
@ -267,9 +311,10 @@
<span>{{searchUtils.page | number}}</span>
<span class="uk-text-meta"> of {{(totalPages(oldTotalResults)|number)}}</span>
</ng-container>
</h6>
</div>
<!-- Download results -->
<div *ngIf="showDownload && (searchUtils.status !== errorCodes.LOADING || !loadPaging)" class="uk-margin-small-bottom uk-margin-small-top">
<div *ngIf="showDownload && (searchUtils.status !== errorCodes.LOADING || !loadPaging)"
class="uk-margin-small-bottom uk-flex uk-margin-small-top" [class.uk-flex-center]="mobile" [class.uk-margin-medium-top]="mobile">
<search-download
*ngIf="( entityType !='community' && entityType != 'stakeholder') && usedBy == 'search'"
[isDisabled]="disabled"

View File

@ -132,7 +132,7 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges {
public pageOptions: number[] = [5, 10, 20, 50];
@Input() basicMetaDescription = [];
@Input() entitiesSelection: boolean = true;
@Input() entitiesSelection: boolean = false;
@Input() showSwitchSearchLink: boolean = true;
// on 1st load, do not show filters until results query returns.
@ -151,6 +151,8 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges {
showOffCanvas:boolean = false;
isMobile: boolean = false;
isServer: boolean;
searchTerm: string = null;
advancedSearchTerms: number = 0;
constructor(private route: ActivatedRoute,
private location: Location,
@ -428,7 +430,9 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges {
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)) {
if (this.searchFieldsHelper.HIDDEN_FIELDS.indexOf(this.refineFields[i]) == -1
|| (selected_filters.indexOf(dependentTo) != -1) || (selected_filters.indexOf(this.refineFields[i]) != -1)
|| (this.resultTypes && this.resultTypes.filterId == dependentTo && this.resultTypes.countSelectedValues > 0)) {
fields.push(this.refineFields[i]);
}
}
@ -1689,6 +1693,14 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges {
this.getRangeFiltersFromURL(params);
this.getRefineFiltersFromURL(params);
this.createAdvancedSearchSelectedFiltersFromURLParameters(params);
this.searchTerm = '';
if(params && params['fv0'] && params['f0'] && params['f0'] == 'q'){
let keyword = StringUtils.URIDecode(params['fv0']);
this.searchTerm = keyword;
}
if(params){
this.advancedSearchTerms = Object.keys(params).filter(key => key.includes('fv')).length;
}
}
removeResultType(type) {
@ -1708,4 +1720,12 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges {
}
return totalPages;
}
}
public getFilterById(filterId: string): Filter {
return this.filters.find(filter => filter.filterId == filterId);
}
detectChanges() {
this.cdr.detectChanges();
}
}

View File

@ -11,27 +11,35 @@ import {OpenaireEntities} from "../../utils/properties/searchFields";
@Component({
selector: 'quick-selections',
template: `
<div *ngIf="quickFilter" class="uk-margin-bottom">
<mat-slide-toggle name="qf" [(ngModel)]="quickFilter.selected" (ngModelChange)="quickFilterChanged()">
<span class="uk-text-bold">{{quickFilter.value}}</span>
</mat-slide-toggle>
</div>
<div class="uk-flex uk-flex-middle uk-text-small uk-text-nowrap">
<div class="uk-width-auto@s uk-width-1-3 uk-flex uk-flex-right uk-text-meta uk-margin-small-right">Include:</div>
<div class="uk-width-expand">
<div class="uk-grid uk-grid-small uk-flex-middle uk-child-width-auto@m uk-child-width-1-2@s uk-child-width-1-1" uk-grid>
<ng-container *ngFor="let value of resultTypes.values">
<div>
<input #input type="checkbox" class="uk-checkbox" [(ngModel)]="value.selected" (ngModelChange)="changed()"/>
<label class="uk-margin-small-left" (click)="input.click()">{{value.name}}</label>
</div>
</ng-container>
<div *ngIf="!vertical && (resultTypes || quickFilter)">
<div *ngIf="quickFilter" class="uk-margin-bottom">
<mat-slide-toggle name="qf" [(ngModel)]="quickFilter.selected" (ngModelChange)="quickFilterChanged()">
<span class="uk-text-bold">{{quickFilter.value}}</span>
</mat-slide-toggle>
</div>
<div class="uk-flex uk-flex-middle uk-text-small uk-text-nowrap">
<div class="uk-width-auto@s uk-width-1-3 uk-flex uk-flex-right uk-text-meta uk-margin-small-right">Include:</div>
<div class="uk-width-expand">
<div class="uk-grid uk-grid-small uk-flex-middle uk-child-width-auto@m uk-child-width-1-2@s uk-child-width-1-1" uk-grid>
<ng-container *ngFor="let value of resultTypes.values">
<div>
<input #input type="checkbox" class="uk-checkbox" [(ngModel)]="value.selected" (ngModelChange)="changed()"/>
<label class="uk-margin-small-left" (click)="input.click()">{{value.name}}</label>
</div>
</ng-container>
</div>
</div>
</div>
</div>
<div *ngIf="vertical && (resultTypes || quickFilter)" [class.uk-disabled]="isDisabled">
<search-filter [isDisabled]="isDisabled" [filter]="resultTypes" [showResultCount]='false'
(onFilterChange)="changed()" [actionRoute]="actionRoute"></search-filter>
</div>
`
})
export class QuickSelectionsComponent {
@Input() vertical: boolean=false;
@Input() resultTypes:Filter;
@Output() typeChange = new EventEmitter();
@Input() isDisabled;

View File

@ -19,7 +19,7 @@
<div class="uk-margin-small-left">
<div class="uk-text-meta">Top 100 values are shown in the filters</div>
<div class="uk-flex uk-flex-bottom uk-margin-top">
<div input class="uk-width-1-2@m uk-margin-right" [placeholder]="{label: 'Search', static: true}" inputClass="inner small" [(value)]="keyword"></div>
<div input class="uk-width-1-2@m uk-margin-right" [placeholder]="{label: 'Search', static: true}" inputClass="inner small" [(value)]="keyword" (valueChange)="initMatching()"></div>
<div *ngIf="showResultCount === true" input type="select" class="uk-width-expand" placeholder="Sort by"
inputClass="border-bottom" [(value)]="sortBy" [options]="sortByOptions" (valueChange)="sort()"></div>
</div>
@ -27,9 +27,13 @@
<div class="uk-overflow-auto uk-height-max-small uk-margin-small-left uk-margin-small-right uk-margin-top">
<ng-container *ngFor="let value of this.sortedValues">
<div *ngIf="filterKeywords(value.name)" title="{{value.name}}"
class="uk-animation-fade uk-text-small">
<ng-container
*ngTemplateOutlet="input_label_wrapper; context: {filter: filter, value: value}"></ng-container>
class="uk-animation-fade uk-text-small">
<ng-container *ngTemplateOutlet="input_label_wrapper; context: {filter: filter, value: value}"></ng-container>
</div>
</ng-container>
<ng-container *ngIf="!hasMatch">
<div class="uk-padding-small uk-text-meta">
No filters available with that term
</div>
</ng-container>
</div>

View File

@ -5,7 +5,8 @@ import {
EventEmitter,
OnInit,
OnChanges,
SimpleChanges
SimpleChanges,
ChangeDetectorRef
} from '@angular/core';
import {Filter, Value} from './searchHelperClasses.class';
import {ActivatedRoute, Router} from "@angular/router";
@ -42,7 +43,11 @@ export class SearchFilterComponent implements OnInit, OnChanges {
sub;
public isOpen: boolean = false;
sortedValues;
constructor(private _router: Router, private route: ActivatedRoute) {
hasMatch: boolean = false;
constructor(private _router: Router,
private route: ActivatedRoute,
private cdr: ChangeDetectorRef) {
}
ngOnDestroy() {
@ -115,6 +120,10 @@ export class SearchFilterComponent implements OnInit, OnChanges {
return false;
}
}
if(!this.hasMatch) {
this.hasMatch = true;
this.cdr.detectChanges();
}
return true;
}
@ -248,7 +257,11 @@ export class SearchFilterComponent implements OnInit, OnChanges {
});
}
this.sortedValues = Object.assign(sorted);
}
initMatching() {
this.hasMatch = false;
this.cdr.detectChanges();
}
toggle(event) {

View File

@ -1,9 +1,9 @@
<ul class="uk-list uk-list-xlarge uk-margin" [ngClass]="custom_class">
<ul class="uk-list uk-margin" [ngClass]="custom_class">
<errorMessages [status]="[status]" [type]="'results'"></errorMessages>
<li *ngFor="let result of previewResults">
<result-preview [properties]="properties" [showOrganizations]="showOrganizations"
[showSubjects]="showSubjects" [result]="result" [showEnermaps]="showEnermaps"
[isCard]="true" [prevPath]="prevPath">
[isCard]="true" [isMobile]="isMobile" [prevPath]="prevPath">
</result-preview>
</li>
</ul>

View File

@ -2,19 +2,20 @@ import {Component, Input, OnChanges, OnInit, SimpleChanges} from '@angular/core'
import {SearchResult} from '../../utils/entities/searchResult';
import {EnvProperties} from '../../utils/properties/env-properties';
import {ResultPreview} from "../../utils/result-preview/result-preview";
import {HttpClient} from "@angular/common/http";
import {OrcidService} from "../../orcid/orcid.service";
import {Session} from "../../login/utils/helper.class";
import {properties} from "../../../../environments/environment";
import {LayoutService} from "../../dashboard/sharedComponents/sidebar/layout.service";
import {Subscription} from "rxjs";
@Component({
selector: 'search-result',
templateUrl: 'searchResult.component.html'
})
export class SearchResultComponent implements OnInit, OnChanges {
export class SearchResultComponent implements OnInit, OnChanges {
@Input() prevPath: string = "";
@Input() results: SearchResult[];
previewResults:ResultPreview[];
previewResults: ResultPreview[];
@Input() status: number;
@Input() type: string;
@Input() showLoading: boolean = false;
@ -23,59 +24,69 @@ export class SearchResultComponent implements OnInit, OnChanges {
@Input() custom_class: string = "";
@Input() properties: EnvProperties;
@Input() showEnermaps: boolean;
public isMobile: boolean = false;
private subscriptions: any[] = [];
constructor( private http: HttpClient/*ATHENA CODE*/
, private orcidService: OrcidService) {
constructor(private orcidService: OrcidService,
private layoutService: LayoutService) {
}
ngOnInit() {
this.subscriptions.push(this.layoutService.isMobile.subscribe(isMobile => {
this.isMobile = isMobile;
}));
}
ngOnInit() {}
sub;
ngOnDestroy() {
if(this.sub){
this.sub.unsubscribe();
}
}
initialize(){
this.previewResults = [];
for(let result of this.results){
this.previewResults.push(this.getResultPreview(result));
}
if((properties.adminToolsPortalType == "explore" || properties.adminToolsPortalType == "community" || properties.adminToolsPortalType == "aggregator")
&& Session.isLoggedIn() && this.results && this.results.length > 0
&& (this.type == "result" || this.type == "publication" || this.type == "dataset" || this.type == "software" || this.type == "other")
) {
this.orcidService.getPutCodes(this.previewResults.map(
previewResult => {
if(previewResult.identifiers) {
let pidsArray: string[] = [];
for(let key of Array.from(previewResult.identifiers.keys())) {
pidsArray = pidsArray.concat(previewResult.identifiers.get(key));
}
return pidsArray;//.join();
}
})).subscribe(
putCodes => {
for (let i = 0; i < this.previewResults.length; i++) {
if(this.previewResults[i].identifiers) {
this.previewResults[i].orcidPutCodes = putCodes[i];
// console.debug(i, this.previewResults[i].orcidPutCodes);
}
}
}, error => {
}
);
}
this.subscriptions.forEach(subscription => {
if(subscription instanceof Subscription) {
subscription.unsubscribe();
}
})
}
ngOnChanges(changes: SimpleChanges): void {
if (changes.results) {
if (changes.results) {
this.initialize();
}
}
initialize() {
this.previewResults = [];
for (let result of this.results) {
this.previewResults.push(this.getResultPreview(result));
}
if ((properties.adminToolsPortalType == "explore" || properties.adminToolsPortalType == "community" || properties.adminToolsPortalType == "aggregator")
&& Session.isLoggedIn() && this.results && this.results.length > 0
&& (this.type == "result" || this.type == "publication" || this.type == "dataset" || this.type == "software" || this.type == "other")
) {
this.subscriptions.push(this.orcidService.getPutCodes(this.previewResults.map(
previewResult => {
if (previewResult.identifiers) {
let pidsArray: string[] = [];
for (let key of Array.from(previewResult.identifiers.keys())) {
pidsArray = pidsArray.concat(previewResult.identifiers.get(key));
}
return pidsArray;//.join();
}
})).subscribe(
putCodes => {
for (let i = 0; i < this.previewResults.length; i++) {
if (this.previewResults[i].identifiers) {
this.previewResults[i].orcidPutCodes = putCodes[i];
// console.debug(i, this.previewResults[i].orcidPutCodes);
}
}
}, error => {
}
));
}
}
public getResultPreview(result: SearchResult): ResultPreview {
return ResultPreview.searchResultConvert(result, (result.entityType)?result.entityType:this.type);
return ResultPreview.searchResultConvert(result, (result.entityType) ? result.entityType : this.type);
}

View File

@ -169,6 +169,8 @@ export class SearchDataprovidersService {
if(resData['pid']) {
result.identifiers = this.parsingFunctions.parseIdentifiers(resData['pid']);
}
// Measure
result.measure = this.parsingFunctions.parseMeasures(resData['measure']);
results.push(result);
}

View File

@ -254,6 +254,8 @@ export class SearchProjectsService {
if(resData.hasOwnProperty("enddate")) {
result.endYear = resData.enddate.split('-')[0];
}
// Measure
result.measure = this.parsingFunctions.parseMeasures(resData['measure']);
results.push(result);
}

View File

@ -7,14 +7,14 @@ import {ParsingFunctions} from '../landingPages/landing-utils/parsingFunctions.c
import {EnvProperties} from '../utils/properties/env-properties';
import {map} from "rxjs/operators";
import {properties} from "../../../environments/environment";
import {HostedByCollectedFrom} from "../utils/result-preview/result-preview";
@Injectable()
export class SearchResearchResultsService {
private sizeOfDescription: number = 270;
public parsingFunctions: ParsingFunctions = new ParsingFunctions();
constructor(private http: HttpClient=null) {
constructor(private http: HttpClient = null) {
}
@ -34,14 +34,14 @@ export class SearchResearchResultsService {
url += "&page=" + (page - 1) + "&size=" + size + "&format=json";
return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
.pipe(map(res => [res['meta'].total, this.parseResults(resultType, res['results'], properties), RefineResultsUtils.parse(res['refineResults'], refineFields, "publication")]));
.pipe(map(res => [res['meta'].total, this.parseResults(resultType, res['results'], properties), RefineResultsUtils.parse(res['refineResults'], refineFields, "publication")]));
}
searchById(resultType: string, id: string, properties: EnvProperties): any {
let url = properties.searchAPIURLLAst + this.getEntityQueryName(resultType, true) + "/" + id + "?format=json";
return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
.pipe(map(res => this.parseResults(resultType, res, properties)));
.pipe(map(res => this.parseResults(resultType, res, properties)));
}
searchAggregators(resultType: string, id: string, params: string, refineParams: string, page: number, size: number, properties: EnvProperties): any {
@ -57,7 +57,7 @@ export class SearchResearchResultsService {
url += "&page=" + (page - 1) + "&size=" + size;
return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
.pipe(map(res => this.parseRefineResults(id, res['refineResults'])));
.pipe(map(res => this.parseRefineResults(id, res['refineResults'])));
}
searchByListOfDOI(resultType: string, DOIs: string[], refineParams: string, page: number, size: number, refineFields: string[], properties: EnvProperties): any {
@ -79,7 +79,7 @@ export class SearchResearchResultsService {
url += "&page=" + (page - 1) + "&size=" + size;
return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
.pipe(map(res => [res['meta'].total, this.parseResults(resultType, res['results'], properties), RefineResultsUtils.parse(res['refineResults'], refineFields, "publication")]));
.pipe(map(res => [res['meta'].total, this.parseResults(resultType, res['results'], properties), RefineResultsUtils.parse(res['refineResults'], refineFields, "publication")]));
}
advancedSearch(resultType: string, params: string, page: number, size: number, sortBy: string, properties: EnvProperties, refineParams: string = null, refineFields: string[] = null, refineQuery: string = null): any {
@ -106,7 +106,7 @@ export class SearchResearchResultsService {
url += "&format=json";
return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
.pipe(map(res => [res['meta'].total, this.parseResults(resultType, res['results'], properties), RefineResultsUtils.parse(res['refineResults'], refineFields, "publication")]));
.pipe(map(res => [res['meta'].total, this.parseResults(resultType, res['results'], properties), RefineResultsUtils.parse(res['refineResults'], refineFields, "publication")]));
}
advancedSearchResults(resultType: string, params: string, page: number, size: number, sortBy: string, properties: EnvProperties, refineParams: string = null, refineFields: string[] = null, refineQuery: string = null): any {
@ -129,7 +129,7 @@ export class SearchResearchResultsService {
// url += "&format=json";
return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
.pipe(map(res => [res['meta'].total, this.parseResults(resultType, res['results'], properties), RefineResultsUtils.parse(res['refineResults'], refineFields, "publication")]));
.pipe(map(res => [res['meta'].total, this.parseResults(resultType, res['results'], properties), RefineResultsUtils.parse(res['refineResults'], refineFields, "publication")]));
}
searchResultForEntity(resultType: string, params: string, page: number, size: number, properties: EnvProperties): any {
@ -147,7 +147,7 @@ export class SearchResearchResultsService {
url += "&page=" + (page - 1) + "&size=" + size;
return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
.pipe(map(res => [res['meta'].total, this.parseResults(resultType, res['results'], properties)]));
.pipe(map(res => [res['meta'].total, this.parseResults(resultType, res['results'], properties)]));
}
//???? why different from above?
@ -157,7 +157,7 @@ export class SearchResearchResultsService {
url += "&sortBy=resultdateofacceptance,descending";
url += "&page=" + (page - 1) + "&size=" + size + "&format=json";
return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
.pipe(map(res => [res['meta'].total, this.parseResults(resultType, res['results'], properties)]));
.pipe(map(res => [res['meta'].total, this.parseResults(resultType, res['results'], properties)]));
}
searchForMyOrcidLinks(resultType: string, orcidQuery: string, typeQuery: string, page: number, size: number): any {
@ -169,12 +169,12 @@ export class SearchResearchResultsService {
url += "&page=" + (page - 1) + "&size=" + size;
return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
.pipe(map(res => [res['meta'].total, this.parseResults(resultType, res['results'], properties)]));
.pipe(map(res => [res['meta'].total, this.parseResults(resultType, res['results'], properties)]));
}
parseResults(resultType: string, data: any, properties: EnvProperties): SearchResult[] {
let results: SearchResult[] = [];
if(data == null) {
if (data == null) {
return results;
}
@ -189,75 +189,70 @@ export class SearchResearchResultsService {
} else {
result.entityType = resultType;
}
result['title'] = {"name": '', "accessMode": ''};
if (Array.isArray(resData['title'])) {
for (let i = 0; i < resData['title'].length; i++) {
if (resData['title'][i] && resData['title'][i].content) {
if (!result.title.name || resData['title'][i].classid == "main title") {
result['title'].name = StringUtils.HTMLToString(String(resData['title'][i].content));
}
if (resData['title'][i].classid == "main title") {
break;
}
}
}
if (!result.title.name) {
result['title'].name = "";
}
// result['title'].name = (resData['title'][0] && resData['title'][0].content) ? String(resData['title'][0].content) : "";
} else {
result['title'].name = (resData['title'] && resData['title'].content) ? StringUtils.HTMLToString(String(resData['title'].content)) : "";
}
if (resData['bestaccessright'] && resData['bestaccessright'].hasOwnProperty("classname")) {
result['title'].accessMode = resData['bestaccessright'].classname;
}
result.types = new Array<string>();
let types = new Set<string>();
let instance;
let length = Array.isArray(resData['children']['instance']) ? resData['children']['instance'].length : 1;
result.hostedBy_collectedFrom = new Array<HostedByCollectedFrom>();
for (let i = 0; i < length; i++) {
instance = Array.isArray(resData['children']['instance']) ? resData['children']['instance'][i] : resData['children']['instance'];
this.parsingFunctions.parseTypes(result.types, types, instance);
if(instance?.hasOwnProperty("hostedby")) {
if(instance.hasOwnProperty("webresource")) {
let url = Array.isArray(instance['webresource'])?instance['webresource'][0].url:instance['webresource'].url;
if(url.includes('&amp;')) {
url = url.replace(/&amp;/gmu, '&');
}
if(instance.hasOwnProperty("hostedby")) {
this.parsingFunctions.parseHostedBy_collectedFrom(result.hostedBy_collectedFrom, instance, url, result.title.accessMode);
}
}
}
}
// Measure
result.measure = new Array<string>();
if (resData['measure'] && Array.isArray(resData['measure'])) {
for (let i = 0; i < resData['measure'].length; i++) {
if (resData['measure'][i].id == 'influence') {
result.measure[1] = resData['measure'][i].class;
if (resData['measure'][i].class == 'C1') {
result.measure[3] = 'Top 0.01% in';
} else if (resData['measure'][i].class == 'C2') {
result.measure[3] = 'Top 0.1% in';
} else if (resData['measure'][i].class == 'C3') {
result.measure[3] = 'Top 1% in';
} else if (resData['measure'][i].class == 'C4') {
result.measure[3] = 'Top 10% in';
} else if (resData['measure'][i].class == 'C5') {
result.measure[3] = 'Average/low';
} else if (resData['measure'][i].class == 'A') {
result.measure[3] = 'Exceptional';
} else if (resData['measure'][i].class == 'B') {
result.measure[3] = 'Substantial';
} else {
result.measure[3] = 'Average';
}
}
if (resData['measure'][i].id == 'popularity') {
result.measure[0] = resData['measure'][i].class;
if (resData['measure'][i].class == 'C1') {
result.measure[2] = 'Top 0.01% in';
} else if (resData['measure'][i].class == 'C2') {
result.measure[2] = 'Top 0.1% in';
} else if (resData['measure'][i].class == 'C3') {
result.measure[2] = 'Top 1% in';
} else if (resData['measure'][i].class == 'C4') {
result.measure[2] = 'Top 10% in';
} else if (resData['measure'][i].class == 'C5') {
result.measure[2] = 'Average/low';
} else if (resData['measure'][i].class == 'A') {
result.measure[2] = 'Exceptional';
} else if (resData['measure'][i].class == 'B') {
result.measure[2] = 'Substantial';
} else {
result.measure[2] = 'Average';
}
}
}
}
result.hostedBy_collectedFrom.sort(this.parsingFunctions.compareHostedByCollectedFrom);
// Measure
result.measure = this.parsingFunctions.parseMeasures(resData['measure']);
/////////////////////////// Athena Code ///////////////////////////
if (resData['pid']) {
if (!Array.isArray(resData['pid'])) {
if (resData['pid'].classid && resData['pid'].classid == 'doi') {
if (resData['pid'].content != '' && resData['pid'].content != null) {
result.DOIs.push((resData['pid'].content+"").replace("https://doi.org/", ""));
result.DOIs.push((resData['pid'].content + "").replace("https://doi.org/", ""));
}
}
} else {
for (let i = 0; i < resData['pid'].length; i++) {
if (resData['pid'][i].classid == 'doi') {
if (resData['pid'][i].content != '' && resData['pid'][i].content != null && resData['pid'][i].content) {
result.DOIs.push((resData['pid'][i].content+"").replace("https://doi.org/", ""));
result.DOIs.push((resData['pid'][i].content + "").replace("https://doi.org/", ""));
}
}
}
@ -313,27 +308,6 @@ export class SearchResearchResultsService {
}
}
result['title'] = {"name": '', "accessMode": ''};
if (Array.isArray(resData['title'])) {
for (let i = 0; i < resData['title'].length; i++) {
if (resData['title'][i] && resData['title'][i].content) {
if (!result.title.name || resData['title'][i].classid == "main title") {
result['title'].name = StringUtils.HTMLToString(String(resData['title'][i].content));
}
if (resData['title'][i].classid == "main title") {
break;
}
}
}
if (!result.title.name) {
result['title'].name = "";
}
// result['title'].name = (resData['title'][0] && resData['title'][0].content) ? String(resData['title'][0].content) : "";
} else {
result['title'].name = (resData['title'] && resData['title'].content) ? StringUtils.HTMLToString(String(resData['title'].content)) : "";
}
result['id'] = Array.isArray(data) ? data[i]['result']['header']['dri:objIdentifier'] : data['result']['header']['dri:objIdentifier'];
result['objId'] = result['id'];
let canId = ParsingFunctions.parseRelCanonicalId(Array.isArray(data) ? data[i] : data, "result");
@ -342,9 +316,6 @@ export class SearchResearchResultsService {
}
result['relcanId'] = result['id'];
if (resData['bestaccessright'] && resData['bestaccessright'].hasOwnProperty("classname")) {
result['title'].accessMode = resData['bestaccessright'].classname;
}
if (resData['rels'].hasOwnProperty("rel")) {
let relLength = Array.isArray(resData['rels']['rel']) ? resData['rels']['rel'].length : 1;
@ -370,10 +341,10 @@ export class SearchResearchResultsService {
for (let i = 0; i < length; i++) {
let author = Array.isArray(authors) ? authors[i] : authors;
if (author) {
if(author.orcid) {
if (author.orcid) {
author.orcid = author.orcid.toUpperCase();
}
if(author.orcid_pending) {
if (author.orcid_pending) {
author.orcid_pending = author.orcid_pending.toUpperCase();
}
result['authors'][author.rank] = {
@ -392,7 +363,7 @@ export class SearchResearchResultsService {
result.year = (date && (date).indexOf('-') !== -1) ? date.split('-')[0] : date;
let abstracts = this.parsingFunctions.parseDescription(resData.description, true);
result.description = abstracts;
result.description = abstracts;
// if (result.description && result.description.length > this.sizeOfDescription) {
// result.description = result.description.substring(0, this.sizeOfDescription) + "...";
// }
@ -412,9 +383,39 @@ export class SearchResearchResultsService {
}
}
}
if(resData['context'] != null) {
if (resData['context'] != null) {
result.enermapsId = ParsingFunctions.getEnermapsConceptId(this.parsingFunctions.parseContexts(resData['context']));
}
if (resData.dateofacceptance && resData.dateofacceptance != null) {
let date: string = (resData.dateofacceptance ? resData.dateofacceptance : '') + ''; // transform to string in case it is an integer
result.date = (date && (date).indexOf('-') !== -1) ? date.split('-')[0] : date;
result.dateofacceptance = resData.dateofacceptance ? Dates.getDate(resData.dateofacceptance) : null;
}
if (resData.journal && resData.journal != null) {
result.journal = {
"journal": "",
"issn": "",
"lissn": "",
"eissn": "",
"issue": "",
"volume": "",
"start_page": "",
"end_page": ""
}
result.journal['journal'] = resData.journal.content;
result.journal['issn'] = resData.journal.issn;
result.journal['lissn'] = resData.journal.lissn;
result.journal['eissn'] = resData.journal.eissn;
result.journal['issue'] = resData.journal.iss;
result.journal['volume'] = resData.journal.vol;
result.journal['start_page'] = resData.journal.sp;
result.journal['end_page'] = resData.journal.ep;
}
result.hostedBy_collectedFrom = this.parsingFunctions.addPublisherToHostedBy_collectedFrom(
result.hostedBy_collectedFrom, result.publisher,
result['journal']?result['journal'].journal:null, result.identifiers);
results.push(result);
}
return results;
@ -496,7 +497,7 @@ export class SearchResearchResultsService {
private numOfResults(url: string, properties: EnvProperties): any {
return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
.pipe(map(res => res['total']));
.pipe(map(res => res['total']));
}
numOfEntityResults(resultType: string, id: string, entity: string, properties: EnvProperties): any {
@ -527,7 +528,7 @@ export class SearchResearchResultsService {
url += refineParams;
}
return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
.pipe(map(res => res['meta']['total']));
.pipe(map(res => res['meta']['total']));
}
numOfSearchResults(resultType: string, params: string, properties: EnvProperties, refineParams: string = null): any {
@ -555,7 +556,7 @@ export class SearchResearchResultsService {
numOfSearchResultsLinkedToPub(resultType: string, properties: EnvProperties): any {
let url = properties.searchAPIURLLAst + "resources?query=" + encodeURIComponent("( (oaftype exact result) and (resulttypeid exact " + resultType + ") and (relresulttype=publication) )") + "&page=0&size=0&format=json";
return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
.pipe(map(res => res['meta']['total']));
.pipe(map(res => res['meta']['total']));
}
countTotalResults(resultType: string, properties: EnvProperties, refineParams: string = null): any {
@ -582,8 +583,8 @@ export class SearchResearchResultsService {
}
public countCollectedResultsWithFundingInfo(datasourceId: string) {
let url = properties.searchAPIURLLAst + "resources?query=" + encodeURIComponent("(oaftype=result and collectedfromdatasourceid exact \""+datasourceId+"\" and relprojectid=*)") + "&page=0&size=0&format=json";
let url = properties.searchAPIURLLAst + "resources?query=" + encodeURIComponent("(oaftype=result and collectedfromdatasourceid exact \"" + datasourceId + "\" and relprojectid=*)") + "&page=0&size=0&format=json";
return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
.pipe(map(res => res['meta']['total']));
.pipe(map(res => res['meta']['total']));
}
}

View File

@ -22,7 +22,10 @@ import {EntitiesSelectionComponent} from "../../searchPages/searchUtils/entities
<ng-content></ng-content>
</div>
</div>
<div class="uk-width-auto">
<div class="uk-width-auto filters-toggle">
<ng-content select="[filters-toggle]"></ng-content>
</div>
<div class="uk-width-auto" [class.uk-flex-first]="iconPosition === 'left'">
<div class="search-icon" [class.disabled]="disabled" (click)="searchEmitter.emit()">
<icon name="search" [flex]="true" ratio="1.3"></icon>
</div>
@ -34,6 +37,7 @@ import {EntitiesSelectionComponent} from "../../searchPages/searchUtils/entities
export class AdvancedSearchInputComponent implements AfterContentInit, OnDestroy {
@ContentChildren(InputComponent) inputs: QueryList<InputComponent>;
@ContentChildren(EntitiesSelectionComponent) entities: QueryList<EntitiesSelectionComponent>;
@Input() iconPosition: 'left' | 'right' = 'right';
@Input() disabled: boolean = false;
@Input() searchInputClass: string = 'inner';
@Input() dark: boolean;

View File

@ -381,6 +381,9 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang
@HostListener('window:keydown.enter', ['$event'])
enter(event: KeyboardEvent) {
if (this.extendEnter) {
this.extendEnter();
}
if (this.opened && this.optionBox) {
event.preventDefault();
if (this.filteredOptions[this.selectedIndex]) {
@ -391,9 +394,6 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang
} else {
this.focus(false, event);
}
if (this.extendEnter) {
this.extendEnter();
}
}
@HostListener('keydown', ['$event'])
@ -642,7 +642,7 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang
return (this.showOptionsOnEmpty) ? options : [];
}
const filterValue = value.toString().toLowerCase();
options = options.filter(option => option.label.toLowerCase().indexOf(filterValue) != -1);
options = options.filter(option => (option.label && option.label.toLowerCase().indexOf(filterValue) != -1));
this.selectedIndex = options.findIndex(option => option.value === this.formControl.value);
if (this.selectedIndex === -1) {
this.selectedIndex = 0;

View File

@ -170,12 +170,28 @@
<ng-container *ngIf="!activeHeader.menuPosition || activeHeader.menuPosition === 'center'">
<ng-container *ngTemplateOutlet="mainMenu"></ng-container>
</ng-container>
<div *ngIf="searchMode" #search_input search-input [(value)]="keyword" placeholder="Search in Explore"
[searchInputClass]="'flat background small-vertical'" (searchEmitter)="goTo()"
class="uk-width-large@l uk-width-medium uk-width-xlarge@xl"></div>
</div>
<div class="uk-navbar-right">
<ng-container *ngIf="activeHeader.menuPosition === 'right'">
<ng-container *ngTemplateOutlet="mainMenu"></ng-container>
</ng-container>
<user-mini *ngIf="userMenu" [user]="user"
<div *ngIf="searchMode" class="uk-flex uk-flex-middle uk-margin-medium-right" (click)="searchMode = false">
<div class="search-icon clickable">
<icon name="close" [flex]="true" ratio="1.5" visuallyHidden="close search mode"></icon>
</div>
</div>
<div *ngIf="!searchMode && hasSearchBar" class="uk-flex uk-flex-middle uk-margin-right" (click)="openSearch($event)">
<div class="search-icon clickable">
<icon name="search" [flex]="true" ratio="1" visuallyHidden="search"></icon>
</div>
</div>
<user-mini *ngIf="!searchMode && userMenu" [user]="user"
[userMenuItems]=userMenuItems [logInUrl]=properties.loginUrl [logOutUrl]=properties.logoutUrl
[cookieDomain]=properties.cookieDomain></user-mini>
<div class="uk-visible@m">
@ -183,7 +199,7 @@
</div>
</div>
<ng-template #mainMenu>
<ul class="uk-navbar-nav" [class.uk-margin-right]="!userMenu">
<ul *ngIf="!searchMode" class="uk-navbar-nav" [class.uk-margin-right]="!userMenu">
<li class="uk-parent" *ngIf="showHomeMenuItem && currentRoute.route !== '/'">
<a routerLink="/">Home</a>
</li>

View File

@ -1,4 +1,13 @@
import {ChangeDetectorRef, Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges} from '@angular/core';
import {
ChangeDetectorRef,
Component, ElementRef,
Input,
OnChanges,
OnDestroy,
OnInit, QueryList,
SimpleChanges, ViewChild,
ViewChildren
} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import {Session, User} from '../login/utils/helper.class';
import {ConfigurationService} from '../utils/configuration/configuration.service';
@ -9,6 +18,9 @@ import {HelpContentService} from '../services/help-content.service';
import {properties} from "../../../environments/environment";
import {LayoutService} from "../dashboard/sharedComponents/sidebar/layout.service";
import {NotificationConfiguration} from "../notifications/notifications-sidebar/notifications-sidebar.component";
import {SearchInputComponent} from "./search-input/search-input.component";
import {Filter} from "../searchPages/searchUtils/searchHelperClasses.class";
import {RouterHelper} from "../utils/routerHelper.class";
declare var UIkit;
@ -57,6 +69,7 @@ export class NavigationBarComponent implements OnInit, OnDestroy, OnChanges {
subs: Subscription[] = [];
showEntity = {};
showPage = {};
public searchMode: boolean = false;
public additionalMenuItems: MenuItem[] = [];
public featuredMenuItems: MenuItem[] = [];
@ -64,13 +77,28 @@ export class NavigationBarComponent implements OnInit, OnDestroy, OnChanges {
public isFeaturedMenuEnabled: boolean = false;
public featuredAlignment: string = MenuAlignment.CENTER.valueOf();
public hasSearchBar: boolean = false;
public resultsQuickFilter: { filter: Filter, selected: boolean, filterId: string, value: string } = {
filter: null,
selected: true,
filterId: "resultbestaccessright",
value: "Open Access"
};
@ViewChild('search_input') search_input: SearchInputComponent;
public routerHelper: RouterHelper = new RouterHelper();
constructor(private router: Router,
private route: ActivatedRoute,
private config: ConfigurationService,
private _helpContentService: HelpContentService,
private layoutService: LayoutService) {}
private layoutService: LayoutService,
private cdr: ChangeDetectorRef) {}
ngOnInit() {
this.subs.push(this.route.queryParams.subscribe(params => {
this.searchMode = false;
this.keyword = "";
}));
this.initialize();
}
@ -145,6 +173,9 @@ export class NavigationBarComponent implements OnInit, OnDestroy, OnChanges {
this.subs.push(this.layoutService.replaceHeader.subscribe(replaceHeader => {
this.setHeader(replaceHeader);
}));
this.subs.push(this.layoutService.hasMenuSearchBar.subscribe(hasSearchBar => {
this.hasSearchBar = hasSearchBar;
}));
}
setHeader(replaceHeader: boolean) {
@ -204,4 +235,29 @@ export class NavigationBarComponent implements OnInit, OnDestroy, OnChanges {
// return MenuItem.isTheActiveMenu(item, this.currentRoute, this.layoutService.activeMenuItem);
// }
}
openSearch(event) {
event.stopPropagation();
this.searchMode = true;
this.cdr.detectChanges();
this.search_input.input.focus(true);
}
goTo() {
let parameterNames = [];
let parameterValues = [];
if (this.resultsQuickFilter && this.resultsQuickFilter.selected) {
parameterNames.push(this.resultsQuickFilter.filterId);
parameterValues.push('"' + encodeURIComponent(this.resultsQuickFilter.value) + '"');
}
if (this.keyword.length > 0) {
parameterNames.push("fv0");
parameterValues.push(this.keyword);
parameterNames.push("f0");
parameterValues.push("q");
}
this.router.navigate([this.properties.searchLinkToAll], {queryParams: this.routerHelper.createQueryParams(parameterNames, parameterValues)});
}
}

View File

@ -10,12 +10,13 @@ import { UserMiniModule} from '../login/userMiniModule.module';
import {SearchBarModule} from "./searchBar/searchBar.module";
import {HelpContentService} from '../services/help-content.service';
import {IconsModule} from "../utils/icons/icons.module";
import {SearchInputModule} from "./search-input/search-input.module";
@NgModule({
imports: [
CommonModule, FormsModule,
RouterModule,
UserMiniModule, IconsModule,
UserMiniModule, IconsModule, SearchInputModule,
// , SearchBarModule
],
declarations: [

View File

@ -1,4 +1,5 @@
import {
AfterViewInit,
ChangeDetectorRef,
Component,
ElementRef,
@ -10,7 +11,6 @@ import {
ViewChild
} from '@angular/core';
import {AbstractControl} from '@angular/forms';
import {MatAutocompleteTrigger} from '@angular/material/autocomplete';
import {InputComponent} from "../input/input.component";
import {ClickEvent} from "../../utils/click/click-outside-or-esc.directive";
@ -33,7 +33,7 @@ import {ClickEvent} from "../../utils/click/click-outside-or-esc.directive";
</div>
<div class="uk-width-auto" [class.uk-flex-first]="iconPosition === 'left'">
<div class="search-icon" [class.disabled]="disabled" (click)="search($event)">
<icon name="search" [flex]="true" ratio="1.3"></icon>
<icon name="search" [flex]="true" [ratio]="ratio"></icon>
</div>
</div>
<div class="uk-width-auto filters-toggle">
@ -44,7 +44,7 @@ import {ClickEvent} from "../../utils/click/click-outside-or-esc.directive";
</div>
`
})
export class SearchInputComponent implements OnInit {
export class SearchInputComponent implements OnInit, AfterViewInit {
@Input() disabled: boolean = false;
@Input() searchInputClass: string = 'inner';
@Input() iconPosition: 'left' | 'right' = 'right';
@ -59,6 +59,7 @@ export class SearchInputComponent implements OnInit {
@ViewChild('input') input: InputComponent;
public expanded: boolean = true;
public initialized: boolean = false;
public ratio: number = 1;
constructor(private cdr: ChangeDetectorRef) {
}
@ -86,6 +87,12 @@ export class SearchInputComponent implements OnInit {
this.initialized = true;
}
ngAfterViewInit() {
if(typeof document !== 'undefined') {
this.ratio = Number.parseFloat(getComputedStyle(this.searchInput.nativeElement).getPropertyValue('--search-input-icon-ratio'));
}
}
expand(value: boolean) {
this.expanded = value;
this.cdr.detectChanges();
@ -118,32 +125,4 @@ export class SearchInputComponent implements OnInit {
get hidden(): boolean {
return !this.expanded && (!this.searchControl?.value && !this.value);
}
/** @deprecated all*/
@Input()
showSearch: boolean = true;
@Input()
control: AbstractControl;
@Input()
loading: boolean = false;
@Input()
selected: any;
@Input()
list: any = null;
@Input()
colorClass: string = 'portal-color';
@Input()
bordered: boolean = false;
@Input()
toggleTitle: string = 'search';
@ViewChild(MatAutocompleteTrigger) trigger: MatAutocompleteTrigger;
@Output()
resetEmitter: EventEmitter<any> = new EventEmitter<any>();
@Output()
closeEmitter: EventEmitter<any> = new EventEmitter<any>();
/** @deprecated*/
closeSearch() {
}
}

View File

@ -2,13 +2,21 @@ import {UrlMatcher, UrlSegment} from "@angular/router";
export class HelperFunctions {
public static scroll() {
public static scroll(smooth: boolean = false) {
HelperFunctions.scrollTo(0,0);
}
public static scrollTo(x,y) {
public static scrollTo(x,y, smooth: boolean = false) {
if (typeof document !== 'undefined') {
window.scrollTo(x,y);
if(!smooth) {
window.scrollTo(x, y);
} else {
window.scrollTo({
top: 0,
left: 0,
behavior: "smooth"
})
}
}
}

View File

@ -6,12 +6,13 @@ declare var loadAltmetrics:any;
@Component({
selector: 'altmetrics',
template: `
<div [innerHTML]="altmetrics | safeHtml"></div>
<div [innerHTML]="altmetrics | safeHtml"></div>
`
})
export class AltMetricsComponent {
@Input() id ;
@Input() id;
@Input() type = 'doi'; // doi or arxiv
@Input() size: string = 'donut';
// public doi="10.7717/peerj.1150";
public altmetrics:string;
@ -26,9 +27,9 @@ export class AltMetricsComponent {
ngOnInit() {
this.sub = this.route.queryParams.subscribe(data => {
if(this.type == "doi"){
this.altmetrics='<div data-badge-popover="right" data-hide-no-mentions="true" data-badge-type="donut" data-doi="'+this.id+'" class="altmetric-embed uk-text-center"> </div>';
this.altmetrics='<div data-badge-details="right" data-hide-no-mentions="true" data-link-target="_blank" data-badge-type="'+this.size+'" data-doi="'+this.id+'" class="altmetric-embed"> </div>';
}else{
this.altmetrics='<div data-badge-popover="right" data-hide-no-mentions="true" data-badge-type="donut" data-arxiv-id="'+this.id+'" class="altmetric-embed uk-text-center"> </div>';
this.altmetrics='<div data-badge-details="right" data-hide-no-mentions="true" data-link-target="_blank" data-badge-type="'+this.size+'" data-arxiv-id="'+this.id+'" class="altmetric-embed"> </div>';
}
if (typeof document !== 'undefined') {
// let yourModule = require('../utils/altmetrics.js');

View File

@ -10,14 +10,15 @@ import {properties} from "../../../../environments/environment";
@Component({
selector: 'showAuthors',
template: `
<ng-template #author_template let-author="author" let-i="i">
<span *ngIf="isSticky || (!author.orcid && !author.orcid_pending) || !testBrowser" style="margin-right: 5px;">
<ng-template #author_template let-author="author" let-i="i" let-italic="italic">
<span *ngIf="isSticky || (!author.orcid && !author.orcid_pending) || !testBrowser" style="margin-right: 5px;"
[class.uk-text-italic]="italic">
{{author.fullName + ";"}}
</span>
<a *ngIf="!isSticky && (author.orcid || author.orcid_pending) && testBrowser" class="uk-flex-inline uk-flex-middle uk-link-text">
<img *ngIf="author.orcid" src="assets/common-assets/common/ORCIDiD_icon16x16.png" alt="orcid" loading="lazy" style="width:16px; height:16px; margin-right: 3px;">
<img *ngIf="!author.orcid && author.orcid_pending" src="assets/common-assets/common/ORCIDiD_iconbw16x16.png" alt="orcid bw" loading="lazy" style="margin-right: 3px;">
<span style="margin-right: 5px;">
<span style="margin-right: 5px;" [class.uk-text-italic]="italic">
{{author.fullName + ";"}}
</span>
</a>
@ -78,39 +79,49 @@ import {properties} from "../../../../environments/environment";
<div *ngIf="authors" class="uk-height-max-medium uk-overflow-auto uk-text-small uk-text-emphasis uk-flex uk-flex-wrap">
<ng-container *ngFor="let author of authors.slice(0, viewAll?authors.length:authorsLimit) let i=index">
<ng-container *ngTemplateOutlet="author_template; context: { author: author, i:i}"></ng-container>
<ng-container *ngTemplateOutlet="author_template; context: { author: author, i:i, italic: true}"></ng-container>
</ng-container>
<span *ngIf="!showAll && authors && authors.length > authorsLimit" class="uk-text-meta">
+{{authors.length-authorsLimit | number}} more
</span>
<span *ngIf="!showAll && authors && authors.length > authorsLimit" class="uk-text-meta">
+{{authors.length-authorsLimit | number}} more
</span>
<span *ngIf="showAll && authors && authors.length > authorsLimit && !viewAll">
<a (click)="viewAllClick();">
+{{authors.length-authorsLimit | number}} Authors
</a>
</span>
</div>
<div *ngIf="viewAll && lessBtn" class="uk-width-1-1 uk-text-right uk-text-small">
<a (click)="viewAll = !viewAll; lessBtn=false;" class="view-more-less-link">View less authors</a>
<div *ngIf="viewAll && lessBtn" class="uk-text-small">
<a (click)="viewAll = !viewAll; lessBtn=false;">View less</a>
</div>
</div>
<modal-alert #authorsModal>
<modal-alert *ngIf="!isMobile" #authorsModal>
<div class="uk-text-small uk-text-emphasis uk-grid uk-grid-column-collapse uk-grid-row-small" uk-grid>
<ng-container *ngFor="let author of authors; let i=index">
<ng-container *ngTemplateOutlet="author_template; context: { author: author, i:i}"></ng-container>
</ng-container>
</div>
</modal-alert>
<fs-modal *ngIf="isMobile" #authorsModal classTitle="uk-tile-default uk-border-bottom">
<div class="uk-text-small uk-text-emphasis uk-grid uk-grid-column-collapse uk-grid-row-small" uk-grid>
<ng-container *ngFor="let author of authors; let i=index">
<ng-container *ngTemplateOutlet="author_template; context: { author: author, i:i}"></ng-container>
</ng-container>
</div>
</fs-modal>
`
})
export class ShowAuthorsComponent {
@Input() isMobile: boolean = false;
@Input() authors: Author[];
@Input() isSticky: boolean = false;
@Input() authorsLimit: number = 7;
@Input() showAll: boolean = true;
@Input() modal: AlertModal;
@Input() viewAll: boolean = false;
@Input() showInline: boolean = false; // do not open modal for "view more" when this is true
public lessBtn: boolean = false;
@ViewChild('authorsModal') authorsModal;
@ -133,7 +144,7 @@ export class ShowAuthorsComponent {
}
public viewAllClick() {
if(this.authors.length <= this.authorsLimit*2) {
if(this.authors.length <= this.authorsLimit*2 || this.showInline) {
this.viewAll = true;
this.lessBtn = true;
} else {
@ -142,10 +153,16 @@ export class ShowAuthorsComponent {
}
public openAuthorsModal() {
this.authorsModal.cancelButton = false;
this.authorsModal.okButton = false;
this.authorsModal.alertTitle = "Authors";
this.authorsModal.open();
if (this.isMobile) {
this.authorsModal.okButton = false;
this.authorsModal.title = "Authors";
this.authorsModal.open();
} else {
this.authorsModal.cancelButton = false;
this.authorsModal.okButton = false;
this.authorsModal.alertTitle = "Authors";
this.authorsModal.open();
}
}
copyToClipboard(element: HTMLInputElement) {

View File

@ -5,10 +5,11 @@ import {RouterModule} from '@angular/router';
import {ShowAuthorsComponent} from './showAuthors.component';
import {AlertModalModule} from "../modal/alertModal.module";
import {FullScreenModalModule} from "../modal/full-screen-modal/full-screen-modal.module";
@NgModule({
imports: [
CommonModule, FormsModule, RouterModule, AlertModalModule
CommonModule, FormsModule, RouterModule, AlertModalModule, FullScreenModalModule
],
declarations: [
ShowAuthorsComponent

View File

@ -1,11 +1,10 @@
<a (click)="open()"
[title]="'Send data to cloud storage'"
[attr.uk-tooltip]="'pos: right; cls: uk-active uk-text-small uk-padding-small'"
> <span icon="cloud-upload"></span>
<span class="uk-icon-button uk-icon landing-action-button landing-action-button-portal">
<span uk-icon="cloud-upload"></span>
</span>
</a>
<a (click)="open()"
[title]="'Send data to cloud storage'"
[attr.uk-tooltip]="'pos: bottom; cls: uk-active uk-text-small uk-padding-small'"
class="uk-flex uk-flex-middle uk-flex-center uk-button-link uk-text-bolder">
<icon flex="true" ratio="0.8" name="cloud_upload" visuallyHidden="upload"></icon>
<span class="uk-margin-xsmall-left">Transfer</span>
</a>
<!-- This is the modal -->

View File

@ -5,18 +5,18 @@ import {EGIDataTransferComponent} from "./transferData.component";
import {InputModule} from "../../sharedComponents/input/input.module";
import {AlertModalModule} from "../modal/alertModal.module";
import {FullScreenModalModule} from "../modal/full-screen-modal/full-screen-modal.module";
import {IconsModule} from '../icons/icons.module';
@NgModule({
imports: [
CommonModule, FormsModule, InputModule, AlertModalModule, FullScreenModalModule
CommonModule, FormsModule, InputModule, AlertModalModule, FullScreenModalModule, IconsModule
],
declarations: [
EGIDataTransferComponent
],
],
exports: [
EGIDataTransferComponent
]
]
})
export class EGIDataTransferModule { }

View File

@ -1,10 +1,6 @@
import {Email} from "./email";
import {Body} from "./body";
import {FormArray} from "@angular/forms";
import {properties} from "../../../../environments/environment";
import {Stakeholder} from "../../monitor/entities/stakeholder";
import {Report} from "../../../../cache-indicators";
import {error} from "protractor";
export class Composer {
private static noteBodySize = "14px";
@ -141,6 +137,31 @@ export class Composer {
return email;
}
public static composeEmailForSdgsSuggestion(info: {name: string, url: string, email: string, subjects: any[]}, recipients: string[], subjectType: "sdg" | "fos"): Email {
let typeName: string = "";
if(subjectType == "sdg") {
typeName = "Sustainable Development Goals (SDGs)";
} else {
typeName = "Fields of Science (FoS)";
}
let email: Email = new Email();
email.subject = 'Feedback report for ' + info.name;
email.body = "<div style='font-size:" + this.noteBodySize + "'>"
+ "<p>A user" + ((info.email)?(" with email " + info.email):"") + " has reported the following "+typeName+" for "
+ "<a href=\'" + info.url + "\'>" + info.name + "</a></p><ul>";
if(info.subjects && info.subjects.length > 0) {
info.subjects.forEach((subject, index) => {
email.body += "<br><li><span><b>" + subject + "</b></span></li>";
});
} else {
email.body += "<br><b>No "+typeName+" selected</b>";
}
email.body += "</ul></div>";
email.recipients = recipients;
return email;
}
public static composeEmailForUserAfterFeedback(recipients: string[]): Email {
let email: Email = new Email();
email.subject = 'Feedback report received';
@ -188,7 +209,7 @@ export class Composer {
return email;
}
public static composeEmailToReportCachingProcess(report: Report) {
public static composeEmailToReportCachingProcess(report: any) {
let email: Email = new Email();
email.recipients = [report.creator];
email.subject = 'OpenAIRE | Monitor Dashboard - ' + report.name + '\'s caching process has been finished';

View File

@ -1,4 +1,5 @@
import {properties} from "../../../../environments/environment";
import {Measure} from "./resultLandingInfo";
export class DataproviderProvenance {
provenance: Map<string, {"urlPrefix": string, "name": string}>;
@ -36,6 +37,7 @@ export class DataProviderInfo {
identifiers: Map<string, string[]>; //key is the classname
fundedContent: string; // search query
measure: Measure;
//collected from datasource api
// aggregationStatus: {"fundedContent": string, "indexRecords": string, "fulltexts": string, "lastUpdateDate": string};

View File

@ -1,25 +1,26 @@
import {Measure} from "./resultLandingInfo";
export class ProjectInfo {
id:string;
acronym: string;
title: string;
funding: {funderName: string, funderShortName: string, code: string, callIdentifier: string,
fundingStream: string, budget: string, contribution: string, currency: string};
startDate: number;
endDate: number;
currentDate: number;
status: string;
openAccessMandatePublications: string;
openAccessMandateDatasets: string;
// specialClause39: string;
organizations: { "acronym": string, "name": string, "id": string }[];//Map<string, string>;
url: string;
urlInfo: string;
description: string;
//publications: any;
researchData: any;
totalPublications: number;
totalDatasets: number;
publicationsStatus: any;
id:string;
acronym: string;
title: string;
funding: {funderName: string, funderShortName: string, code: string, callIdentifier: string,
fundingStream: string, budget: string, contribution: string, currency: string};
startDate: number;
endDate: number;
currentDate: number;
status: string;
openAccessMandatePublications: string;
openAccessMandateDatasets: string;
// specialClause39: string;
organizations: { "acronym": string, "name": string, "id": string }[];//Map<string, string>;
url: string;
urlInfo: string;
description: string;
//publications: any;
researchData: any;
totalPublications: number;
totalDatasets: number;
publicationsStatus: any;
measure: Measure;
}

View File

@ -29,6 +29,30 @@ export interface Context {
logo?: string;
}
export interface Measure {
/** @deprecated*/
downloads?: string;
/** @deprecated*/
views?: string;
/** @deprecated*/
influence?: string;
/** @deprecated*/
popularity?: string;
/** @deprecated*/
citations?: string;
/** @deprecated*/
impulse?: string;
bip?: Metric[]
counts?: Metric[]
}
export interface Metric {
name: string,
order: number,
icon: string,
value: any
}
export class ResultLandingInfo {
relcanId;
objIdentifier: string;
@ -60,7 +84,7 @@ export class ResultLandingInfo {
subjects: string[];
otherSubjects: Map<string, string[]>;
classifiedSubjects: Map<string, string[]>; //<class of subject, subjects>
fos: string[];
fos: {"id": string, "label": string}[] = [];
sdg: string[];
eoscSubjects: any[];
@ -140,4 +164,6 @@ export class ResultLandingInfo {
// SOFTWARE
programmingLanguages: string[];
measure: Measure;
}

View File

@ -1,13 +1,17 @@
import {Author, Organization, Project, ResultTitle} from "../result-preview/result-preview";
import {Author, HostedByCollectedFrom, Journal, Organization, Project, ResultTitle} from "../result-preview/result-preview";
import {Measure, Metric} from "./resultLandingInfo";
export class SearchResult {
title: ResultTitle;
id: string;
relcanId: string;
objId: string;
DOIs: string[]=[];
DOIs: string[] = [];
identifiers: Map<string, string[]>;
measure: Array<string>;
measure: Measure;
date: string;
dateofacceptance: Date;
journal: Journal;
//publications & datasets & orp & software & projects & dataproviders:
description: string;
@ -21,6 +25,7 @@ export class SearchResult {
authors: Author[];
countriesForResults: string[];
languages: string[];
hostedBy_collectedFrom: HostedByCollectedFrom[];
//datasets & orp & software:
publisher: string;
@ -59,7 +64,8 @@ export class SearchResult {
entityType: string;
types: string[];
enermapsId:string;
enermapsId: string;
constructor() {
}

View File

@ -0,0 +1,188 @@
import {Component, Input, OnInit, ViewChild} from "@angular/core";
import {StringUtils} from "../string-utils.class";
import {RouterHelper} from "../routerHelper.class";
import {properties} from "../../../../environments/environment";
import {Router} from "@angular/router";
import {Option} from "../../sharedComponents/input/input.component";
import {OpenaireEntities} from "../properties/searchFields";
import {EnvProperties} from "../properties/env-properties";
@Component({
selector: 'entity-actions',
template: `
<div class="" [ngClass]="isMobile ? 'uk-flex uk-flex-column' : 'uk-grid uk-grid-small uk-child-width-auto'" [attr.uk-grid]="!isMobile ? '' : null">
<div *ngIf="linking && isRouteAvailable('participate/direct-claim')">
<a [queryParams]="routerHelper.createQueryParams(['id','type','linkTo'], [id,type,linkTo])"
routerLinkActive="router-link-active" routerLink="/participate/direct-claim"
[title]="'Link '+openaireEntities.RESULTS+' with a '+openaireEntities.PROJECT+', a '+openaireEntities.COMMUNITY+' or other '+openaireEntities.RESULTS+' and make the new information available in OpenAIRE information space.'"
[attr.uk-tooltip]="'pos: bottom; cls: uk-active uk-text-small uk-padding-small uk-width-medium'"
class="uk-flex uk-flex-middle uk-button-link uk-text-bolder" [ngClass]="isMobile ? 'uk-margin-left uk-margin-xsmall-bottom' : 'uk-flex-center'">
<icon [flex]="true" [ratio]="0.7" name="link_to" visuallyHidden="link"></icon>
<span class="uk-margin-xsmall-left">Link to</span>
</a>
</div>
<div *ngIf="share">
<a (click)="openAddThisModal()"
class="uk-flex uk-flex-middle uk-button-link uk-text-bolder" [ngClass]="isMobile ? 'uk-margin-left uk-margin-xsmall-bottom' : 'uk-flex-center'">
<icon [flex]="true" [ratio]="0.8" name="share" visuallyHidden="share"></icon>
<span class="uk-margin-xsmall-left">Share</span>
</a>
</div>
<div *ngIf="cite">
<a (click)="openCiteModal()"
class="uk-flex uk-flex-middle uk-button-link uk-text-bolder" [ngClass]="isMobile ? 'uk-margin-left uk-margin-xsmall-bottom' : 'uk-flex-center'">
<icon [flex]="true" [ratio]="0.7" name="cite" visuallyHidden="cite"></icon>
<span class="uk-margin-xsmall-left">Cite</span>
</a>
</div>
<div *ngIf="deposit && isRouteAvailable('participate/deposit/learn-how')">
<a routerLinkActive="router-link-active" routerLink="/participate/deposit/learn-how"
[title]="'Find a repository to deposit or publish your research in Open Access'"
[attr.uk-tooltip]="'pos: bottom; cls: uk-active uk-text-small uk-padding-small uk-width-medium'"
class="uk-flex uk-flex-middle uk-button-link uk-text-bolder" [ngClass]="isMobile ? 'uk-margin-left uk-margin-xsmall-bottom' : 'uk-flex-center'">
<icon flex="true" ratio="0.7" name="upload" visuallyHidden="upload"></icon>
<span class="uk-margin-xsmall-left">Deposit</span>
</a>
</div>
<div *ngIf="embed" >
<a (click)="openEmbedResultsModal()"
[title]="'Embed the related '+openaireEntities.RESULTS+' of this '+getTypeName()+' in your website'"
[attr.uk-tooltip]="'pos: bottom; cls: uk-active uk-text-small uk-padding-small uk-width-medium'"
class="uk-flex uk-flex-middle uk-button-link uk-text-bolder" [ngClass]="isMobile ? 'uk-margin-left uk-margin-xsmall-bottom' : 'uk-flex-center'">
<icon flex="true" ratio="0.8" name="code" visuallyHidden="code"></icon>
<span class="uk-margin-xsmall-left">Embed</span>
</a>
</div>
<ng-content></ng-content>
</div>
<modal-alert *ngIf="cite" #citeModal>
<citeThis *ngIf="citeThisClicked" [result]="result" [id]="id"
[type]="getTypeName().toLowerCase()" [piwikSiteId]="properties.piwikSiteId"></citeThis>
</modal-alert>
<modal-alert *ngIf="share" #addThisModal classBody="uk-flex uk-flex-center uk-flex-middle">
<addThis [url]="url"></addThis>
</modal-alert>
<modal-alert *ngIf="result" #embedResultsModal large="true">
<div class="uk-padding-small uk-margin-small-left uk-margin-small-right">
<div class="uk-padding-small uk-padding-remove-vertical">
<div input type="select" placeholder="Select content type to embed" inputClass="flat x-small"
[options]="resultTypesForEmbedding" [(value)]="embed_research_results_type"></div>
<div *ngIf="embed_research_results_type" class="clipboard-wrapper box-content uk-grid uk-margin-auto uk-margin-small-top ">
<pre id="dynamic_content_id" class="uk-overflow-auto uk-padding-small uk-padding-remove-vertical uk-margin-top"><code
>{{getDynamicContent(embed_research_results_type)}}</code></pre>
<div class="uk-width-1-1 uk-padding-small uk-text-right">
<a class="uk-link copy clipboard_btn" data-clipboard-target="#dynamic_content_id" title="Copy script">
COPY SCRIPT
</a>
</div>
</div>
<div class="uk-text-small uk-margin-top">
For further information contact us at
<u><a [href]="'mailto:'+properties.helpdeskEmail" class="uk-link-text">{{properties.helpdeskEmail}}</a></u>
</div>
</div>
</div>
</modal-alert>
`
})
export class EntityActionsComponent implements OnInit {
@Input() result: any;
@Input() type: string;
@Input() id: string;
@Input() linking: boolean = false;
@Input() share: boolean = false;
@Input() cite: boolean = false;
@Input() deposit: boolean = false;
@Input() embed: boolean = false;
@Input() url: string;
@Input() isMobile: boolean = false;
public citeThisClicked: boolean;
public routerHelper: RouterHelper = new RouterHelper();
@ViewChild('citeModal') citeModal;
@ViewChild('embedResultsModal') embedResultsModal;
@ViewChild('downloadReportModal') downloadReportModal;
@ViewChild('addThisModal') addThisModal;
properties: EnvProperties = properties;
openaireEntities = OpenaireEntities;
/* Embed */
public embed_research_results_type: string = "result";
public clipboard;
public resultTypesForEmbedding: Option[]=[
{label: "All "+OpenaireEntities.RESULTS, value: "result"},
{label: OpenaireEntities.PUBLICATIONS, value: "publication"},
{label: OpenaireEntities.DATASETS, value: "dataset"},
{label: OpenaireEntities.SOFTWARE, value: "software"},
{label: OpenaireEntities.OTHER, value: "other"}];
constructor(private router: Router) {
}
ngOnInit() {
this.createClipboard();
}
get linkTo():string {
return this.type === 'project'?'result':'project';
}
public getTypeName(): string {
return StringUtils.getEntityName(this.type, false);
}
public openCiteModal() {
this.citeThisClicked = true;
this.citeModal.cancelButton = false;
this.citeModal.okButton = false;
this.citeModal.alertTitle = "Cite this " + this.getTypeName();
this.citeModal.open();
}
public openAddThisModal() {
this.addThisModal.cancelButton = false;
this.addThisModal.okButton = false;
this.addThisModal.alertTitle = "Share this " + this.getTypeName() + " in your social networks";
this.addThisModal.open();
}
public openEmbedResultsModal() {
this.embedResultsModal.cancelButton = false;
this.embedResultsModal.okButton = false;
this.embedResultsModal.alertTitle = "Embed results";
this.embedResultsModal.open();
}
private createClipboard() {
if (typeof window !== 'undefined') {
delete this.clipboard;
let Clipboard;
Clipboard = require('clipboard');
this.clipboard = new Clipboard('.clipboard_btn');
}
}
getDynamicContent(type: string) {
return "<script type=\"text/javascript\">"
+ "\n<!--"
+ "\ndocument.write('<div id=\"oa_widget\"></div>');"
+ "\ndocument.write('<script type=\"text/javascript\""
+ " src=\"" + this.properties.widgetLink
+ this.result.id + "&type="
+ type
+ "\"></script>');"
+ "\n-->"
+ "\n</script>";
}
isRouteAvailable(routeToCheck: string) {
for (let i = 0; i < this.router.config.length; i++) {
let routePath: string = this.router.config[i].path;
if (routePath == routeToCheck) {
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,18 @@
import {NgModule} from "@angular/core";
import {CommonModule} from "@angular/common";
import {EntityActionsComponent} from "./entity-actions.component";
import {RouterModule} from "@angular/router";
import {IconsModule} from "../icons/icons.module";
import {AlertModalModule} from "../modal/alertModal.module";
import {CiteThisModule} from "../../landingPages/landing-utils/citeThis/citeThis.module";
import {LandingModule} from "../../landingPages/landing-utils/landing.module";
import {InputModule} from "../../sharedComponents/input/input.module";
@NgModule({
imports: [CommonModule, IconsModule, AlertModalModule, CiteThisModule, LandingModule, RouterModule, InputModule],
declarations: [EntityActionsComponent],
exports: [EntityActionsComponent]
})
export class EntityActionsModule {
}

View File

@ -112,4 +112,53 @@ export const login = {
name: 'login',
data: '<svg width="20px" height="20px" viewBox="0 0 700 700" xmlns="http://www.w3.org/2000/svg"><g><path d="m151.67 536.67c0-109.47 88.863-198.34 198.33-198.34s198.33 88.867 198.33 198.34c0 6.4375 5.2266 11.664 11.668 11.664s11.668-5.2266 11.668-11.664c0-122.34-99.332-221.67-221.67-221.67s-221.67 99.328-221.67 221.67c0 6.4375 5.2266 11.664 11.668 11.664s11.668-5.2266 11.668-11.664z" fill-rule="evenodd"/><path d="m349.8 11.668c-77.164 0-139.8 62.637-139.8 139.8s62.637 139.8 139.8 139.8c77.164 0 139.8-62.637 139.8-139.8s-62.637-139.8-139.8-139.8zm0 23.332c64.285 0 116.47 52.184 116.47 116.47 0 64.281-52.184 116.47-116.47 116.47-64.281 0-116.47-52.188-116.47-116.47 0-64.285 52.188-116.47 116.47-116.47z" fill-rule="evenodd"/></g></svg>'
}
export const cite = {
name: 'cite',
data: '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="9.6" viewBox="0 0 12 9.6"> <path id="Icon_metro-quote" data-name="Icon metro-quote" d="M8.355,14.44v4.8h4.8v-4.8h-2.4a2.351,2.351,0,0,1,2.4-2.4V9.64S8.355,9.64,8.355,14.44Zm12-2.4V9.64s-4.8,0-4.8,4.8v4.8h4.8v-4.8h-2.4A2.351,2.351,0,0,1,20.355,12.04Z" transform="translate(-8.355 -9.64)" fill="#211f7e"/> </svg>'
}
export const link_to = {
name: 'link_to',
data: '<svg width="13" height="13.369" viewBox="0 0 13 13.369" xmlns="http://www.w3.org/2000/svg"> <path id="Path_104455" data-name="Path 104455" d="M31.828,5.475,29.7,8.018a3.32,3.32,0,0,1-1.48,1,3.582,3.582,0,0,1-.5.128,3.318,3.318,0,0,1-2.993-1,.7.7,0,0,1,1.026-.958,1.919,1.919,0,0,0,2.409.323,1.865,1.865,0,0,0,.434-.369l2.156-2.572a1.949,1.949,0,0,0-.165-2.7l-.04-.036a1.917,1.917,0,0,0-2.7.239L26.825,3.3A.7.7,0,1,1,25.751,2.4l1.024-1.225A3.312,3.312,0,0,1,31.4.725a3.272,3.272,0,0,1,1.2,2.238A3.443,3.443,0,0,1,31.828,5.475Z" transform="translate(-19.621 0.015)" fill="#211f7e"/> <path id="Path_104456" data-name="Path 104456" d="M7.98,22.786a.691.691,0,0,1-.522.247.673.673,0,0,1-.532-.225,1.785,1.785,0,0,0-.2-.2,1.905,1.905,0,0,0-2.236-.159,1.869,1.869,0,0,0-.44.359l-2.19,2.61-.04.05a1.917,1.917,0,0,0,.323,2.692,1.955,1.955,0,0,0,2.688-.319l.915-1.1a.693.693,0,0,1,.476-.249.7.7,0,0,1,.6,1.148L5.91,28.735A3.427,3.427,0,0,1,3.884,29.9a2.708,2.708,0,0,1-.309.038,3.256,3.256,0,0,1-2.409-.779,3.312,3.312,0,0,1-.381-4.633l2.16-2.588A3.124,3.124,0,0,1,3.3,21.58a3.32,3.32,0,0,1,4.682.291A.7.7,0,0,1,7.98,22.786Z" transform="translate(-0.015 -16.582)"/></svg>'
}
export const versions = {
name: 'versions',
data: '<svg xmlns="http://www.w3.org/2000/svg" width="17" height="12.143" viewBox="0 0 17 12.143"> <path id="Icon_metro-versions" data-name="Icon metro-versions" d="M4.5,17.426H6.927V16.212H5.713V11.355H6.927V10.141H4.5v7.286Zm7.286-9.714V19.855H21.5V7.712H11.784Zm7.286,9.714H14.213V10.141H19.07ZM8.142,18.641H10.57V17.426H9.356V10.141H10.57V8.926H8.142Z" transform="translate(-4.499 -7.712)" fill="#211f7e"/> </svg>'
}
export const rocket = {
name: 'rocket',
data: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M156.6 384.9L125.7 354c-8.5-8.5-11.5-20.8-7.7-32.2c3-8.9 7-20.5 11.8-33.8L24 288c-8.6 0-16.6-4.6-20.9-12.1s-4.2-16.7 .2-24.1l52.5-88.5c13-21.9 36.5-35.3 61.9-35.3l82.3 0c2.4-4 4.8-7.7 7.2-11.3C289.1-4.1 411.1-8.1 483.9 5.3c11.6 2.1 20.6 11.2 22.8 22.8c13.4 72.9 9.3 194.8-111.4 276.7c-3.5 2.4-7.3 4.8-11.3 7.2v82.3c0 25.4-13.4 49-35.3 61.9l-88.5 52.5c-7.4 4.4-16.6 4.5-24.1 .2s-12.1-12.2-12.1-20.9V380.8c-14.1 4.9-26.4 8.9-35.7 11.9c-11.2 3.6-23.4 .5-31.8-7.8zM384 168c22.1 0 40-17.9 40-40s-17.9-40-40-40s-40 17.9-40 40s17.9 40 40 40z"/></svg>'
}
export const fire = {
name: 'fire',
data: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M159.3 5.4c7.8-7.3 19.9-7.2 27.7 .1c27.6 25.9 53.5 53.8 77.7 84c11-14.4 23.5-30.1 37-42.9c7.9-7.4 20.1-7.4 28 .1c34.6 33 63.9 76.6 84.5 118c20.3 40.8 33.8 82.5 33.8 111.9C448 404.2 348.2 512 224 512C98.4 512 0 404.1 0 276.5c0-38.4 17.8-85.3 45.4-131.7C73.3 97.7 112.7 48.6 159.3 5.4zM225.7 416c25.3 0 47.7-7 68.8-21c42.1-29.4 53.4-88.2 28.1-134.4c-2.8-5.6-5.6-11.2-9.8-16.8l-50.6 58.8s-81.4-103.6-87.1-110.6C133.1 243.8 112 273.2 112 306.8C112 375.4 162.6 416 225.7 416z"/></svg>'
}
export const landmark = {
name: 'landmark',
data: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M240.1 4.2c9.8-5.6 21.9-5.6 31.8 0l171.8 98.1L448 104l0 .9 47.9 27.4c12.6 7.2 18.8 22 15.1 36s-16.4 23.8-30.9 23.8H32c-14.5 0-27.2-9.8-30.9-23.8s2.5-28.8 15.1-36L64 104.9V104l4.4-1.6L240.1 4.2zM64 224h64V416h40V224h64V416h48V224h64V416h40V224h64V420.3c.6 .3 1.2 .7 1.8 1.1l48 32c11.7 7.8 17 22.4 12.9 35.9S494.1 512 480 512H32c-14.1 0-26.5-9.2-30.6-22.7s1.1-28.1 12.9-35.9l48-32c.6-.4 1.2-.7 1.8-1.1V224z"/></svg>'
}
export const open_access = {
name: 'open_access',
data: '<svg xmlns="http://www.w3.org/2000/svg" width="640" height="1000" viewBox="0 0 640 1000"> <metadata><rdf:RDF><cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/> <dc:creator>art designer at PLoS, modified by Wikipedia users Nina, Beao, JakobVoss, and AnonMoos</dc:creator> <dc:description>Open Access logo, converted into svg, designed by PLoS. This version with transparent background.</dc:description> <dc:source>http://commons.wikimedia.org/wiki/File:Open_Access_logo_PLoS_white.svg</dc:source> <dc:license rdf:resource="http://creativecommons.org/licenses/by-sa/3.0/"/> <cc:license rdf:resource="http://creativecommons.org/licenses/by-sa/3.0/"/> <cc:attributionName>art designer at PLoS, modified by Wikipedia users Nina, Beao, JakobVoss, and AnonMoos</cc:attributionName> <cc:attributionURL>http://www.plos.org/</cc:attributionURL> </cc:Work></rdf:RDF></metadata> <g stroke="#f68212" stroke-width="104.764" fill="none"> <path d="M111.387,308.135V272.408A209.21,209.214 0 0,1 529.807,272.408V530.834"/> <circle cx="320.004" cy="680.729" r="256.083"/> </g> <circle fill="#f68212" cx="321.01" cy="681.659" r="86.4287"/> </svg>'
}
export const closed_access = {
name: 'closed_access',
data: '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="640" height="1000" viewBox="0 0 640 1000"> <metadata> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <cc:Work xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:creator>Jakob Voss, based on art designer at PLoS, modified by Wikipedia users Nina and Beao</dc:creator> <dc:description>Closed Access logo, derived from PLoS Open Access logo. This version with transparent background.</dc:description> <dc:source>http://commons.wikimedia.org/wiki/File:Closed_Access_logo_transparent.svg</dc:source> <dc:license rdf:resource="http://creativecommons.org/licenses/by-sa/3.0/" /> <cc:license rdf:resource="http://creativecommons.org/licenses/by-sa/3.0/" /> <cc:attributionName>Jakob Voss, based on art designer at PLoS, modified by Wikipedia users Nina and Beao</cc:attributionName> </cc:Work> </rdf:RDF> </metadata> <g transform="translate(-528.67833,-378.69073)"> <path d="m 587.6826,651.09852 -2.7e-4,258.42721 104.764,0 0,-258.42721 c 0,-86.48025 70.36161,-156.8333 156.82974,-156.8333 86.46813,0 156.82523,70.35304 156.82523,156.8333 l 0,258.42721 104.7642,-2.5e-4 0,-258.42696 c 0,-144.2401 -117.35336,-261.59346 -261.58943,-261.59346 -144.23204,0 -261.59374,117.35336 -261.59374,261.59346" style="fill:#848484;fill-opacity:1;fill-rule:nonzero;stroke:none" /> <path d="m 936.11577,1060.3489 c 0,47.7233 -38.69235,86.4157 -86.42773,86.4157 -47.73135,0 -86.42776,-38.6924 -86.42776,-86.4157 0,-47.7515 38.69641,-86.44787 86.42776,-86.44787 47.73538,0 86.42773,38.69637 86.42773,86.44787" style="fill:#848484;fill-opacity:1;fill-rule:nonzero;stroke:none" /> <path d="m 644.97395,1059.416 c 0,-112.32498 91.38747,-203.70437 203.7084,-203.70437 112.3169,0 203.69225,91.3794 203.69225,203.70437 0,112.3128 -91.37537,203.7084 -203.69224,203.7084 -112.32093,0 -203.7084,-91.3956 -203.7084,-203.7084 m -104.76018,0 c 0,170.0686 138.39184,308.4604 308.46858,308.4604 170.08084,0 308.46054,-138.3918 308.46054,-308.4604 0,-170.09295 -138.3797,-308.46857 -308.46056,-308.46857 -170.07674,0 -308.46858,138.37563 -308.46858,308.46857" style="fill:#848484;fill-opacity:1;fill-rule:nonzero;stroke:none" /> </g> </svg>'
}
/** Add new icon under this line to be sure that it will be added on preview */
export const unknown_access = {
name: 'unknown_access',
data: '<svg xmlns="http://www.w3.org/2000/svg" width="373.336" height="490.004" viewBox="0 0 373.336 490.004">\n' +
' <g id="noun-lock-question-mark-250128" transform="translate(-163.328 -34.992)">\n' +
' <path id="Path_119172" data-name="Path 119172" d="M490,198.33H466.668V151.662a116.67,116.67,0,0,0-233.34,0V198.33H210A46.8,46.8,0,0,0,163.328,245v233.33A46.8,46.8,0,0,0,210,525H490a46.8,46.8,0,0,0,46.668-46.668V245A46.8,46.8,0,0,0,490,198.33ZM365.55,469.78H334.441V438.671H365.55ZM397.441,350l-14,14c-10.891,11.668-17.891,20.223-17.891,43.555H334.441v-7.777a61.712,61.712,0,0,1,17.891-43.555l19.445-19.445A30.98,30.98,0,1,0,318.891,315H287.782a62.223,62.223,0,0,1,124.446,0,49.983,49.983,0,0,1-14.785,35Zm24.887-151.67H277.668V151.662c0-39.668,32.668-72.332,72.332-72.332S422.332,112,422.332,151.662Z"/>\n' +
' </g>\n' +
'</svg>'
}

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