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){ 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) { 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)); return this.cachingRequests.some(partUrl => (url.indexOf(partUrl) !== -1));
} }

View File

@ -1,5 +1,5 @@
<div> <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> <advanced-search-input>
<div input type="select" [(value)]="showOptions.show" placeholder="Type" hint="Select..." <div input type="select" [(value)]="showOptions.show" placeholder="Type" hint="Select..."
[options]="showOptions.selectOptions" class="uk-width-2-5"></div> [options]="showOptions.selectOptions" class="uk-width-2-5"></div>

View File

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

View File

@ -168,7 +168,7 @@ export class ShowOptions {
this.basketShowSources = false; this.basketShowSources = false;
} }
showLinkTo() { showLinkTo() {
console.log(this.linkTo, "showLinkTo") // console.log(this.linkTo, "showLinkTo")
this.show = this.linkTo; this.show = this.linkTo;
this.basketswitchToLinkTo(); this.basketswitchToLinkTo();
HelperFunctions.scroll(); 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)"> <advanced-search-input (searchEmitter)="search(page,size)">
<div input type="select" [(value)]="showOptions.show" placeholder="Type" hint="Select..." <div input type="select" [(value)]="showOptions.show" placeholder="Type" hint="Select..."
[options]="showOptions.selectOptions" class="uk-width-2-5"></div> [options]="showOptions.selectOptions" class="uk-width-2-5"></div>

View File

@ -21,6 +21,7 @@ declare var UIkit:any;
}) })
export class ClaimProjectsSearchFormComponent { export class ClaimProjectsSearchFormComponent {
public query = ''; public query = '';
@Input() public centerAlign: boolean = false;
@Input() public selectedProjects:ClaimEntity[]=[] ; @Input() public selectedProjects:ClaimEntity[]=[] ;
public elementRef; 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)"> <advanced-search-input (searchEmitter)="search(true)">
<div input type="select" [(value)]="showOptions.show" placeholder="Type" hint="Select..." <div input type="select" [(value)]="showOptions.show" placeholder="Type" hint="Select..."
[options]="showOptions.selectOptions" class="uk-width-2-5"></div> [options]="showOptions.selectOptions" class="uk-width-2-5"></div>
@ -8,7 +8,7 @@
</div> </div>
<div *ngIf="!showOptions" class="uk-width-xlarge@l uk-width-large"> <div *ngIf="!showOptions" class="uk-width-xlarge@l uk-width-large">
<div search-input [(value)]="keyword" [placeholder]="'Search for ' + openaireEntities.RESULTS.toLowerCase() + '...'" <div search-input [(value)]="keyword" [placeholder]="'Search for ' + openaireEntities.RESULTS.toLowerCase() + '...'"
(searchEmitter)="search(true)"></div> [searchInputClass]="'inner background'" (searchEmitter)="search(true)"></div>
</div> </div>
<div *ngIf="!showSearchResults"> <div *ngIf="!showSearchResults">
<div class="uk-text-center uk-text-large uk-text-meta uk-margin-large-top"> <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"; source: string = "datacite";
type: string = "dataset"; type: string = "dataset";
showSearchResults: boolean = false; showSearchResults: boolean = false;
@Input() public centerAlign: boolean = false;
@Input() public select: boolean = true; @Input() public select: boolean = true;
@Input() public keyword: string = ''; @Input() public keyword: string = '';
@Input() public selectedResults: ClaimEntity[]; @Input() public selectedResults: ClaimEntity[];

View File

@ -6,13 +6,9 @@ declare var UIkit: any;
@Component({ @Component({
selector: 'claim-results', selector: 'claim-results',
template: ` template: `
<div *ngIf="results.length > 0 " class="uk-margin-top"> <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 *ngFor="let entity of results" class="uk-card">
<div> <div class="uk-padding-small">
<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 class="uk-grid"> <div class="uk-grid">
<div class="uk-width-expand uk-margin-right"> <div class="uk-width-expand uk-margin-right">
<claim-title [entity]="entity" [showIcon]="false"></claim-title> <claim-title [entity]="entity" [showIcon]="false"></claim-title>
@ -20,20 +16,19 @@ declare var UIkit: any;
<claim-project-metadata [entity]="entity"></claim-project-metadata> <claim-project-metadata [entity]="entity"></claim-project-metadata>
</div> </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':''"> <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)"> (click)="add(entity)">
<icon name="add" [flex]="true"></icon> <icon name="add" [flex]="true"></icon>
</button> </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> <icon name="check" [flex]="true"></icon>
</button> </button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div>`, </div>
`
}) })
export class ClaimResultsComponent { export class ClaimResultsComponent {
@Input() results: ClaimEntity[]; @Input() results: ClaimEntity[];
@ -41,6 +36,9 @@ export class ClaimResultsComponent {
@Input() localStoragePrefix: string = ""; @Input() localStoragePrefix: string = "";
@Input() basketLimit; @Input() basketLimit;
ngOnInit() {
}
public isSelected(item: ClaimEntity) { public isSelected(item: ClaimEntity) {
return !!this.selectedResults.find(result => item.id === result.id); return !!this.selectedResults.find(result => item.id === result.id);
} }

View File

@ -16,7 +16,7 @@
</div> </div>
<div [class.uk-padding]="actions" class="uk-padding-remove-vertical"> <div [class.uk-padding]="actions" class="uk-padding-remove-vertical">
<div class="uk-margin-medium-top"> <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> [totalResults]="resultsNum" customClasses="uk-margin-remove"></results-and-pages>
</div> </div>
<div class="uk-grid uk-flex-middle uk-margin-medium-top" uk-grid> <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) { handleErrors(err, message) {
NotificationHandler.rise(message, "danger"); 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) { goTo(page: number = 1) {
@ -290,7 +290,7 @@ export class DisplayClaimsComponent implements OnInit, OnDestroy {
} }
changeKeyword() { 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); this.searchTermStream.next(this.filterForm.get("keyword").value);
} }
} }

View File

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

View File

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

View File

@ -1,122 +1,4 @@
<div class="linking uk-background-default"> <ng-template #destinations_basket>
<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>
</div>
</div>
<div 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"
[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'"
(stepChanged)="stepHasChanged($event)" [active]="this.showOptions.show"
[showStepLine]="!inlineEntity"></step>
<step [status]="stepStatus('claim')" stepId="claim" [stepNumber]="inlineEntity?2:3"
[stepText]="'Summarize and finish'"
(stepChanged)="stepHasChanged($event)" [active]="this.showOptions.show"
[showStepLine]="true"></step>
</stepper>
</div>
</div>
<div id="pageTop"></div>
<metadata-preview *ngIf="showOptions.show=='claim' && properties" class="uk-margin-top"
[results]="results" [sources]="sources"
[localStoragePrefix]="localStoragePrefix" [inlineEntity]="inlineEntity"
[showOptions]="showOptions" [properties]=properties [pageContents]="pageContents"
[defaultColors]="!communityId" [communityId]="communityId"
>
</metadata-preview>
<div id="tm-main" class="uk-section uk-padding-remove-top" *ngIf="showOptions.show != 'claim'">
<div>
<schema2jsonld *ngIf="url" [URL]="url" name="Link your {{openaireEntities.RESULTS}}" type="other"></schema2jsonld>
<div [class]="((showOptions.show == 'claim')?'':' uk-margin-top ')+' uk-container uk-container-large '">
<div *ngIf="properties" class="uk-section uk-padding-remove-top">
<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">
<div *ngIf="showOptions.show=='source'">
<claim-result-search-form [selectedResults]="sources" [properties]=properties
[localStoragePrefix]="localStoragePrefix+'sources'"
[basketLimit]="basketLimit"
></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"
></claim-projects-search-form>
</div>
<div *ngIf="showOptions.show=='context'">
<claim-contexts-search-form [communityId]=communityId [results]="results" [sources]="sources"
[properties]=properties
[localStoragePrefix]="localStoragePrefix+'results'"
[basketLimit]="basketLimit" [showOptions]="showOptions"
></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"
></claim-result-search-form>
</div>
</div>
<!-- Basket-->
<div *ngIf="showOptions.show != 'claim'" class="uk-width-1-3">
<div id="basket" uk-sticky="offset: 220; bottom: !*; media: @m" style="z-index: 0!important;">
<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>
</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>
<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;"> <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" <start-over *ngIf=" (results.length)> 0"
[results]="results" [localStoragePrefix]="localStoragePrefix+'results'" [results]="results" [localStoragePrefix]="localStoragePrefix+'results'"
@ -139,8 +21,163 @@
</div> </div>
</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 *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> </div>
<div *ngIf="!inlineEntity" uk-sticky="offset: 65; bottom: #pageBottom; media: @m" class="uk-blur-background">
<div class="uk-section-xsmall">
<stepper>
<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]="2"
[stepText]="'Link Sources to Entities'"
(stepChanged)="stepHasChanged($event)" [active]="this.showOptions.show"
[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>
</stepper>
</div>
</div>
<div id="pageTop"></div>
<metadata-preview *ngIf="showOptions.show=='claim' && properties" class="uk-margin-top"
[results]="results" [sources]="sources"
[localStoragePrefix]="localStoragePrefix" [inlineEntity]="inlineEntity"
[showOptions]="showOptions" [properties]=properties [pageContents]="pageContents"
[defaultColors]="!communityId" [communityId]="communityId"
>
</metadata-preview>
<div id="tm-main" class="uk-section uk-padding-remove-top" *ngIf="showOptions.show != 'claim'">
<div>
<schema2jsonld *ngIf="url" [URL]="url" name="Link your {{openaireEntities.RESULTS}}" type="other"></schema2jsonld>
<div [class]="((showOptions.show == 'claim')?'':' uk-margin-top ')+' uk-container uk-container-large '">
<div *ngIf="properties" class="uk-section uk-padding-remove-top">
<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" [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'">
<claim-contexts-search-form [communityId]=communityId [results]="results" [sources]="sources"
[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>
<!-- Basket-->
<div *ngIf="showOptions.show != 'claim'" class="uk-width-1-3">
<div id="basket" uk-sticky="offset: 220; bottom: !*; media: @m" style="z-index: 0!important;">
<div class="uk-card uk-card-default linkingBasket">
<div class="uk-card-body uk-padding-small">
<div class="uk-margin-right">
<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" 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>
</div>
</div>
<div *ngIf="showOptions.basketShowLinksTo">
<div class="uk-height-medium uk-overflow-auto">
<ng-container *ngTemplateOutlet="destinations_basket"></ng-container>
</div>
</div>
</ng-container>
</div> </div>
</div> </div>
<div *ngIf="showOptions.show == 'source'" <div *ngIf="showOptions.show == 'source'"
@ -164,7 +201,7 @@
<button class="uk-flex uk-flex-middle uk-button uk-button-text" <button class="uk-flex uk-flex-middle uk-button uk-button-text"
[class.uk-disabled]="results.length == 0" [disabled]="results.length == 0"> [class.uk-disabled]="results.length == 0" [disabled]="results.length == 0">
<icon *ngIf="inlineEntity" name="link" visuallyHidden="link" [flex]="true"></icon> <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> </button>
</div> </div>
</div> </div>

View File

@ -13,6 +13,9 @@ import {Subscriber} from "rxjs";
import {properties} from "../../../../environments/environment"; import {properties} from "../../../../environments/environment";
import {Breadcrumb} from "../../utils/breadcrumbs/breadcrumbs.component"; import {Breadcrumb} from "../../utils/breadcrumbs/breadcrumbs.component";
import {OpenaireEntities} from "../../utils/properties/searchFields"; 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({ @Component({
selector: 'linking-generic', selector: 'linking-generic',
@ -44,10 +47,12 @@ export class LinkingGenericComponent {
@ViewChild(AlertModal) alert; @ViewChild(AlertModal) alert;
public pageContents = null; public pageContents = null;
@Input() breadcrumbs: Breadcrumb[] = []; @Input() breadcrumbs: Breadcrumb[] = [];
public routerHelper: RouterHelper = new RouterHelper();
constructor (private _router: Router, private route: ActivatedRoute, private entitySearch:EntitiesSearchService, constructor (private _router: Router, private route: ActivatedRoute, private entitySearch:EntitiesSearchService,
private _meta: Meta, private _title: Title, private _piwikService:PiwikService, 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 = []; subscriptions = [];
@ -161,6 +166,7 @@ export class LinkingGenericComponent {
this.showOptions.show = 'claim'; this.showOptions.show = 'claim';
} }
this.cdr.detectChanges(); this.cdr.detectChanges();
HelperFunctions.scroll(true);
console.log('stepHasChanged', stepId, this.showOptions.show) 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({ @Component({
selector: 'claim-project-metadata', selector: 'claim-project-metadata',
template: ` template: `
<div *ngIf="entity.type == 'project' && entity.project" class="uk-text-small uk-flex uk-flex-wrap" [style.grid-gap]="shortVersion?'10px':'20px'"> <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"> <div *ngIf="entity.project.funderName">
<span class="uk-text-meta">Funder: </span>{{entity.project.funderName}} <span class="uk-text-meta">Funder: </span>{{entity.project.funderName}}
</div> </div>
<div *ngIf="entity.project.code"> <div *ngIf="entity.project.code">
<span class="uk-text-meta">GrandID: </span>{{entity.project.code}} <span class="uk-text-meta">Project Code: </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>
</div> </div>
` </ng-container>
`,
styleUrls: ['ClaimEntityMetadata.component.less']
}) })

View File

@ -4,29 +4,37 @@ import {ClaimEntity} from '../../claim-utils/claimHelper.class';
@Component({ @Component({
selector: 'claim-result-metadata', selector: 'claim-result-metadata',
template: ` template: `
<div *ngIf="entity.result" class="uk-text-small"> <div *ngIf="entity.result">
<div *ngIf="entity.result.authors && entity.result.authors.length >0 " class="uk-margin-small-bottom"> <!-- display all existing data similar to entity-metadata -->
<span class="uk-text-meta">Authors: </span>{{sliceArray(entity.result.authors)}} <div *ngIf="!shortVersion" class="claim-entity-metadata uk-flex-inline uk-flex-wrap uk-text-xsmall uk-text-emphasis uk-margin-xsmall-top">
</div> <span class="uk-text-capitalize uk-text-italic">
<div *ngIf="!shortVersion && entity.result.editors&& entity.result.editors.length > 0" class="uk-margin-small-bottom"> {{(!entity.result) ? entity.type : ((entity.result && entity.result.source == 'openaire') ? entity.type : (entity.result && entity.result.source + ' result'))}}
<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}}
</span> </span>
<span *ngIf="entity.result.journal!=null"> <span *ngIf="entity.result.publisher!=null">
<span class="uk-text-meta uk-margin-small-bottom">Journal: </span>{{entity.result.journal}} {{entity.result.publisher}}
</span> </span>
<span *ngIf="entity.result.date"> <span *ngIf="entity.result.date">
<span class="uk-text-meta uk-margin-small-bottom">Published: </span>
<span [class]="(getProjectDurationMessage(entity)?'uk-text-warning':'')">{{entity.result.date}}</span> <span [class]="(getProjectDurationMessage(entity)?'uk-text-warning':'')">{{entity.result.date}}</span>
</span> </span>
<div [class]="(getProjectDurationMessage(entity)?'uk-text-warning':'')">{{getProjectDurationMessage(entity)}} <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> </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>
` <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,30 +1,35 @@
import {Component, Input} from '@angular/core'; import {Component, Input} from '@angular/core';
import {ClaimEntity} from '../../claim-utils/claimHelper.class'; import {ClaimEntity} from '../../claim-utils/claimHelper.class';
import {StringUtils} from "../../../utils/string-utils.class";
@Component({ @Component({
selector: 'claim-title', selector: 'claim-title',
template: template: `
`
<div class="uk-grid uk-flex uk-flex-middle"> <div class="uk-grid uk-flex uk-flex-middle">
<span *ngIf="showIcon" > <span *ngIf="showIcon" class="uk-flex">
<span *ngIf=" entity.result" class="material-icons uk-text-small uk-text-meta" >insert_drive_file <span *ngIf="entity.result" class="material-icons uk-text-small uk-text-meta">
insert_drive_file
</span> </span>
<span *ngIf=" entity.project" <span *ngIf="entity.project" class="material-icons uk-text-small uk-text-meta">
class="material-icons uk-text-small uk-text-meta">assignment_turned_in assignment_turned_in
</span> </span>
<span *ngIf="entity.type=='community'" style="margin-right: 2px;" <span *ngIf="entity.type=='community'" class="material-icons uk-text-small uk-text-meta" style="margin-right: 2px;">
class="material-icons uk-text-small uk-text-meta">people people
</span></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"> </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" <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> class="uk-link uk-text-decoration-none uk-width-expand">
<span {{entity.title ? sliceString(entity.title) : '[No title available]'}}
*ngIf="(entity.result && !entity.result.url)">{{entity.title ? sliceString(entity.title) : '[No title available]'}}</span> </a>
<span *ngIf="(entity.result && !entity.result.url)">
{{entity.title ? sliceString(entity.title) : '[No title available]'}}
</span>
<span *ngIf="entity.type=='project' && entity.project"> <span *ngIf="entity.type=='project' && entity.project">
<a *ngIf="entity.project && entity.project.url" target="_blank" [href]="entity.project.url" <a *ngIf="entity.project && entity.project.url" target="_blank" [href]="entity.project.url"
class="uk-text-link"> class="uk-link uk-text-decoration-none uk-width-expand">
<span *ngIf="!shortVersion"> <span *ngIf="!shortVersion">
{{(entity.project.acronym ? '[' + entity.project.acronym + '] ' : '') + entity.title}} {{(entity.project.acronym ? '[' + entity.project.acronym + '] ' : '') + entity.title}}
</span> </span>
@ -32,8 +37,7 @@ import {StringUtils} from "../../../utils/string-utils.class";
{{(entity.project.acronym ? sliceString(entity.project.acronym):sliceString(entity.title))}} {{(entity.project.acronym ? sliceString(entity.project.acronym):sliceString(entity.title))}}
</span> </span>
</a> </a>
<span <span *ngIf="(entity.project && !entity.project.url)">
*ngIf="(entity.project && !entity.project.url)">
<span *ngIf="!shortVersion"> <span *ngIf="!shortVersion">
{{(entity.project.acronym ? '[' + entity.project.acronym + '] ' : '') + entity.title}} {{(entity.project.acronym ? '[' + entity.project.acronym + '] ' : '') + entity.title}}
</span> </span>
@ -41,15 +45,16 @@ import {StringUtils} from "../../../utils/string-utils.class";
{{(entity.project.acronym ? sliceString(entity.project.acronym):sliceString(entity.title))}} {{(entity.project.acronym ? sliceString(entity.project.acronym):sliceString(entity.title))}}
</span> </span>
</span> </span>
</span> </span>
<span *ngIf="entity.type=='community' && entity.context"> <span *ngIf="entity.type=='community' && entity.context">
<span *ngIf=" entity.context.community != entity.context.concept.label"> <span *ngIf=" entity.context.community != entity.context.concept.label">
{{entity.context.community }} > {{entity.context.category}} > {{entity.context.community }} > {{entity.context.category}} >
</span> </span>
<span> {{entity.context.concept.label}}</span> <span>
{{entity.context.concept.label}}
</span> </span>
</span>
</div>
</div> </div>
</div> </div>
` `
@ -57,8 +62,6 @@ import {StringUtils} from "../../../utils/string-utils.class";
}) })
export class ClaimEntityTitleComponent { export class ClaimEntityTitleComponent {
@Input() entity: ClaimEntity; @Input() entity: ClaimEntity;
@Input() slice:boolean = false; @Input() slice:boolean = false;
@Input() sliceSize:number = 45; @Input() sliceSize:number = 45;
@ -66,9 +69,8 @@ export class ClaimEntityTitleComponent {
@Input() showIcon: boolean = false; @Input() showIcon: boolean = false;
ngOnInit() { ngOnInit() {
} }
sliceString(mystr:string): string { sliceString(mystr:string): string {
if(this.slice){ if(this.slice){
// return StringUtils.sliceString(mystr,this.sliceSize); // return StringUtils.sliceString(mystr,this.sliceSize);

View File

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

View File

@ -75,6 +75,11 @@ export class LayoutService {
private isMobileSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false); private isMobileSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
/** Active sidebar Item*/ /** Active sidebar Item*/
private activeSidebarItemSubject: BehaviorSubject<SidebarItem> = new BehaviorSubject<SidebarItem>(null); 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[] = []; private subscriptions: any[] = [];
ngOnDestroy() { ngOnDestroy() {
@ -166,6 +171,12 @@ export class LayoutService {
} else { } else {
this.setActiveMenuItem(''); this.setActiveMenuItem('');
} }
if (data['hasMenuSearchBar'] !== undefined &&
data['hasMenuSearchBar'] === true) {
this.setHasMenuSearchBar(true);
} else {
this.setHasMenuSearchBar(false);
}
} }
})); }));
this.setObserver(); this.setObserver();
@ -292,4 +303,12 @@ export class LayoutService {
setActiveSidebarItem(value: SidebarItem) { setActiveSidebarItem(value: SidebarItem) {
this.activeSidebarItemSubject.next(value); 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-container uk-container-large">
<div class="uk-margin-top uk-flex uk-flex-center"> <div class="uk-margin-top uk-flex uk-flex-center">
<div class="uk-width-large" [class.dark]="searchForm.dark"> <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"> <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"> <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"> <span class="uk-flex uk-flex-middle">

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. 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>
<div class="uk-text-meta uk-margin-top" uk-scrollspy-class> <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> </div>
<!-- TODO: We need a page for the button link --> <!-- TODO: We need a page for the button link -->
<!-- <div> <!-- <div>
@ -113,7 +113,7 @@
<div *ngFor="let subChild of child.children" style="margin-bottom: 5px;"> <div *ngFor="let subChild of child.children" style="margin-bottom: 5px;">
<a [routerLink]="properties.searchLinkToResults" [queryParams]="{'fos': urlEncodeAndQuote(subChild.id)}" <a [routerLink]="properties.searchLinkToResults" [queryParams]="{'fos': urlEncodeAndQuote(subChild.id)}"
class="uk-link-text"> class="uk-link-text">
{{subChild.id}} {{subChild.label}}
</a> </a>
</div> </div>
</div> </div>
@ -139,7 +139,7 @@
</h3> </h3>
<div *ngFor="let subSubItem of subItem.children" style="margin-bottom: 5px;"> <div *ngFor="let subSubItem of subItem.children" style="margin-bottom: 5px;">
<a [routerLink]="properties.searchLinkToResults" [queryParams]="{'fos': urlEncodeAndQuote(subSubItem.id)}" <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> </a>
</div> </div>
</div> </div>

View File

@ -26,7 +26,7 @@ declare var UIkit;
export class FosComponent implements OnInit, OnDestroy { export class FosComponent implements OnInit, OnDestroy {
public url: string = null; public url: string = null;
public pageTitle: string = "OpenAIRE | Fields of Science"; 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; @Input() piwikSiteId = null;
public fos: any[] = []; public fos: any[] = [];

View File

@ -1,5 +1,6 @@
<div class="landing uk-section uk-padding-remove tm-middle"> <!-- Desktop view -->
<div class="tm-main"> <div class="uk-visible@m landing uk-section uk-padding-remove tm-middle">
<div *ngIf="!isMobile" class="tm-main">
<div class="dataprovider"> <div class="dataprovider">
<div *ngIf="properties.adminToolsPortalType == 'eosc'" class="eosc-explore-back-search-bar"> <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"> <div class="uk-light uk-container uk-container-large uk-padding-small uk-height-1-1">
@ -14,7 +15,7 @@
<div *ngIf="!showFeedback" class="uk-grid uk-margin-remove-left" uk-grid> <div *ngIf="!showFeedback" class="uk-grid uk-margin-remove-left" uk-grid>
<!-- left box - actions --> <!-- left box - actions -->
<div id="landing-left-sidebar" *ngIf="dataProviderInfo" class="uk-visible@s uk-padding-remove-horizontal"> <!-- <div id="landing-left-sidebar" *ngIf="dataProviderInfo" class="uk-visible@s uk-padding-remove-horizontal">
<div class="uk-flex uk-flex-column uk-flex-between uk-flex-center uk-sticky" <div class="uk-flex uk-flex-column uk-flex-between uk-flex-center uk-sticky"
uk-sticky="bottom: true" [attr.offset]="offset"> uk-sticky="bottom: true" [attr.offset]="offset">
<div class="uk-align-center uk-text-center uk-margin-medium-top uk-flex uk-flex-column uk-flex-between"> <div class="uk-align-center uk-text-center uk-margin-medium-top uk-flex uk-flex-column uk-flex-between">
@ -29,7 +30,6 @@
<div class="uk-margin-large-bottom uk-align-center"> <div class="uk-margin-large-bottom uk-align-center">
<div class="uk-text-meta uk-text-uppercase">Actions</div> <div class="uk-text-meta uk-text-uppercase">Actions</div>
<ul class="uk-list"> <ul class="uk-list">
<!-- Share -->
<li class="uk-text-center"> <li class="uk-text-center">
<a (click)="openAddThisModal()" <a (click)="openAddThisModal()"
[title]="'Share this '+openaireEntities.DATASOURCE+' in your social networks'" [title]="'Share this '+openaireEntities.DATASOURCE+' in your social networks'"
@ -42,20 +42,13 @@
</ul> </ul>
</div> </div>
</div> </div>
</div> </div> -->
<!-- center box--> <!-- center box-->
<div class="uk-width-expand uk-padding-remove uk-background-default"> <div id="landing-center-content" 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>
<ng-template #graph_and_feedback_template> <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]="!dataProviderInfo"> <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]="!dataProviderInfo">
<!-- Last Index Info--> <!-- Last Index Info-->
<a href="https://graph.openaire.eu" target="_blank" class="uk-width-1-1 uk-width-auto@l"> <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;"> <img src="assets/common-assets/openaire-badge-1.png" alt="Powered by OpenAIRE graph" style="height: 15px;">
@ -72,15 +65,34 @@
</div> </div>
</ng-template> </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" <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"> uk-sticky="bottom: true;" [attr.offset]="graph_offset">
<ng-container *ngTemplateOutlet="graph_and_feedback_template"></ng-container> <ng-container *ngTemplateOutlet="graph_and_feedback_template"></ng-container>
</div> </div>
<div class="uk-margin-large-left uk-margin-large-right" [style]="'margin-bottom: '+graph_height+'px'"> <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>
<div *ngIf="!showLoading && dataProviderInfo" class="uk-visible@s uk-margin-top uk-margin-bottom">
<div class="uk-flex uk-flex-middle uk-flex-center">
<div class="landing-action-bar uk-text-xsmall uk-box-shadow-small uk-margin-bottom">
<entity-actions [share]="true" [type]="'dataprovider'"></entity-actions>
</div>
</div>
</div>
<div class="uk-margin-left uk-margin-right" [style]="'margin-bottom: '+graph_height+'px'">
<ng-container *ngIf="dataProviderInfo"> <ng-container *ngIf="dataProviderInfo">
<div [attr.style]="'margin-top: '+(graph_height? 'calc(40px + 20px - '+graph_height+'px)': '40px')"> <div [attr.style]="'margin-top: '+(graph_height? 'calc(40px + 20px - '+graph_height+'px)': '40px')">
<div class="uk-grid uk-grid-small" uk-grid>
<div class="uk-width-expand">
<!-- schema.org--> <!-- schema.org-->
<schema2jsonld [data]=dataProviderInfo <schema2jsonld [data]=dataProviderInfo
[URL]="canonicalUrl" [URL]="canonicalUrl"
@ -105,17 +117,23 @@
<landing-header [properties]="properties" [title]="dataProviderInfo.title.name" <landing-header [properties]="properties" [title]="dataProviderInfo.title.name"
[subTitle]="(dataProviderInfo.officialName [subTitle]="(dataProviderInfo.officialName
&& dataProviderInfo.title.name !== dataProviderInfo.officialName)?dataProviderInfo.officialName:null" && dataProviderInfo.title.name !== dataProviderInfo.officialName)?dataProviderInfo.officialName:null"
[types]="dataProviderInfo.type ? [dataProviderInfo.type] : null"> [types]="dataProviderInfo.type ? [dataProviderInfo.type] : null"
[entityType]="getTypeName()"
[compatibility]="dataProviderInfo.compatibility"
[aggregationStatus]="dataProviderInfo.aggregationStatus"
[thematic]="dataProviderInfo.thematic" [type]="type"
[journal]="dataProviderInfo.journal" [prevPath]="prevPath">
</landing-header> </landing-header>
<!-- Labels --> <!-- Labels -->
<div class="uk-margin-bottom uk-grid uk-grid-small uk-flex-middle" uk-grid> <!-- Moved inside the landing-header -->
<!-- <div class="uk-margin-bottom uk-grid uk-grid-small uk-flex-middle" uk-grid>
<ng-container *ngIf="dataProviderInfo.compatibility && <ng-container *ngIf="dataProviderInfo.compatibility &&
!(dataProviderInfo.compatibility.info == 'not available' && type == 'service')"> !(dataProviderInfo.compatibility.info == 'not available' && type == 'service')">
<div> <div>
<span class="uk-label uk-text-truncate" [class.uk-label-danger]="dataProviderInfo.compatibility.info == 'not available'" title="Compatibility"> <span class="uk-label uk-text-truncate" [class.uk-label-danger]="dataProviderInfo.compatibility.info == 'not available'" title="Compatibility">
<a *ngIf="dataProviderInfo.compatibility.id" <a *ngIf="dataProviderInfo.compatibility.id"
[queryParams]="addEoscPrevInParams({datasourceId: dataProviderInfo.compatibility.id})" routerLinkActive="router-link-active" [queryParams]="{datasourceId: dataProviderInfo.compatibility.id}" routerLinkActive="router-link-active"
[routerLink]="properties.searchLinkToDataProvider.split('?')[0]"> [routerLink]="properties.searchLinkToDataProvider.split('?')[0]">
{{dataProviderInfo.compatibility.info}} {{dataProviderInfo.compatibility.info}}
<ng-container *ngIf="dataProviderInfo.compatibility.name">{{dataProviderInfo.compatibility.name}}</ng-container> <ng-container *ngIf="dataProviderInfo.compatibility.name">{{dataProviderInfo.compatibility.name}}</ng-container>
@ -149,7 +167,7 @@
<span class="uk-label uk-text-truncate">Thematic</span> <span class="uk-label uk-text-truncate">Thematic</span>
</div> </div>
</ng-container> </ng-container>
</div> </div> -->
<!-- Web Page --> <!-- Web Page -->
<div *ngIf="dataProviderInfo.title && dataProviderInfo.title.url" <div *ngIf="dataProviderInfo.title && dataProviderInfo.title.url"
@ -166,16 +184,58 @@
<showIdentifiers [identifiers]="dataProviderInfo.identifiers" [showViewAll]="true"></showIdentifiers> <showIdentifiers [identifiers]="dataProviderInfo.identifiers" [showViewAll]="true"></showIdentifiers>
</div> </div>
</div> </div>
<div *ngIf="dataProviderInfo && hasMetrics" class="uk-width-1-1 uk-width-medium@s">
<div class="landing-metrics-card uk-card uk-card-secondary uk-text-small uk-flex uk-padding-small">
<div class="uk-width-expand uk-flex uk-flex-middle">
<div class="uk-grid uk-grid-small uk-flex-nowrap" uk-grid uk-height-match="target: > div > .cell">
<div>
<ng-container>
<ng-container *ngFor="let measure of dataProviderInfo.measure.counts; let i = index">
<div *ngIf="measure.value" class="cell uk-flex uk-flex-middle" [class.uk-margin-xsmall-bottom]="i != dataProviderInfo.measure.counts.length - 1">
<icon [name]="measure.icon" [ratio]="0.8" [flex]="true"></icon>
</div>
</ng-container>
</ng-container>
</div>
<div>
<ng-container *ngFor="let measure of dataProviderInfo.measure.counts; let i = index">
<div *ngIf="measure.value" class="cell" [class.uk-margin-xsmall-bottom]="i != dataProviderInfo.measure.counts.length - 1">
<a class="uk-text-capitalize">{{measure.name}}</a>
<ng-container *ngTemplateOutlet="dropInfo; context: {option: measure.name, isCompact: false}"></ng-container>
</div>
</ng-container>
</div>
<ng-template #dropInfo let-option=option>
<div class="uk-dropdown" uk-dropdown="pos: bottom-left; mode:click; container: #modal-container;">
<div class="uk-padding-small uk-width-medium uk-text-small" [innerHTML]="getMetricsTooltip(option) | safeHtml">
</div>
</div>
</ng-template>
<div class="uk-text-uppercase uk-text-bolder">
<ng-container *ngFor="let measure of dataProviderInfo.measure.counts; let i = index">
<div *ngIf="measure.value" [attr.uk-tooltip]="measure.value >= 1000 ? 'cls: uk-active' : 'cls: uk-invisible'"
title="{{measure.value | number}}" class="cell" [class.uk-margin-xsmall-bottom]="i != dataProviderInfo.measure.counts.length - 1">
{{formatNumber(measure.value)}}
</div>
</ng-container>
</div>
</div>
</div>
<div class="uk-width-1-5 uk-flex uk-flex-bottom">
<img src="assets/common-assets/metrics-badge.svg" loading="lazy" alt="Metrics badge">
</div>
</div>
</div>
</div>
</div>
<div id="main-tabs-div" class="uk-sticky uk-blur-background" <div id="main-tabs-div" class="uk-sticky uk-blur-background"
uk-sticky="bottom: true; media: @m" [attr.offset]="offset"> uk-sticky="bottom: true; media: @m" [attr.offset]="offset">
<div class="uk-padding uk-padding-remove-horizontal uk-padding-remove-bottom"> <div class="uk-padding uk-padding-remove-horizontal uk-padding-remove-bottom">
<landing-header *ngIf="stickyHeader" class="uk-visible@m" <landing-header [ngClass]="stickyHeader ? 'uk-visible@m' : 'uk-invisible'"
[properties]="properties" [title]="dataProviderInfo.title.name" [properties]="properties" [title]="dataProviderInfo.title.name"
[subTitle]="(dataProviderInfo.officialName [entityType]="getTypeName()"
&& dataProviderInfo.title.name !== dataProviderInfo.officialName)?dataProviderInfo.officialName:null"
[types]="dataProviderInfo.type ? [dataProviderInfo.type] : null" [types]="dataProviderInfo.type ? [dataProviderInfo.type] : null"
isSticky="true"> isSticky="true" [prevPath]="prevPath">
</landing-header> </landing-header>
<!-- <showTitle *ngIf="stickyHeader" [titleName]="dataProviderInfo.title.name" classNames="uk-margin-remove-bottom" class="uk-visible@m"></showTitle>--> <!-- <showTitle *ngIf="stickyHeader" [titleName]="dataProviderInfo.title.name" classNames="uk-margin-remove-bottom" class="uk-visible@m"></showTitle>-->
<my-tabs (selectedActiveTab)="onSelectActiveTab($event)" [offsetForSticky]="offset" [(isSticky)]="stickyHeader"> <my-tabs (selectedActiveTab)="onSelectActiveTab($event)" [offsetForSticky]="offset" [(isSticky)]="stickyHeader">
@ -208,6 +268,9 @@
|| fetchSoftware.searchUtils.totalResults > 0 || fetchOrps.searchUtils.totalResults > 0)" || fetchSoftware.searchUtils.totalResults > 0 || fetchOrps.searchUtils.totalResults > 0)"
[tabTitle]="'Related '+openaireEntities.DATASOURCES" [tabId]="'relatedDatasources'"> [tabTitle]="'Related '+openaireEntities.DATASOURCES" [tabId]="'relatedDatasources'">
</my-tab> </my-tab>
<my-tab *ngIf="dataProviderInfo && hasMetrics"
[tabTitle]="'Metrics'" [tabId]="'metrics'">
</my-tab>
<my-tab *ngIf="(fetchPublications.searchUtils.totalResults > 0 || fetchDatasets.searchUtils.totalResults > 0 <my-tab *ngIf="(fetchPublications.searchUtils.totalResults > 0 || fetchDatasets.searchUtils.totalResults > 0
|| fetchSoftware.searchUtils.totalResults > 0 || fetchOrps.searchUtils.totalResults > 0)" || fetchSoftware.searchUtils.totalResults > 0 || fetchOrps.searchUtils.totalResults > 0)"
[tabTitle]="'Statistics'" customClass="statistics" [tabId]="'statistics'" [active]="false"> [tabTitle]="'Statistics'" customClass="statistics" [tabId]="'statistics'" [active]="false">
@ -217,231 +280,37 @@
</div> </div>
<div id="landing-sections" class="uk-text-small"> <div id="landing-sections" class="uk-text-small">
<div id="summary" class="landing-section landing-section-height-auto"> <ng-container>
<div class="uk-card uk-card-default card-tab uk-grid uk-margin-remove-left uk-margin-medium-top uk-margin-medium-bottom"> <ng-container *ngTemplateOutlet="summary_content"></ng-container>
<div *ngIf="!(hasPrimaryInfo || (!aggregationStatusIsInitialized || hasAggregationStatusInfo)) && !hasSecondaryInfo"
class="uk-width-expand uk-height-small uk-flex uk-flex-center uk-flex-middle">
<div class="uk-animation-fade uk-text-meta uk-text-large">
No summary information available
</div>
</div>
<div *ngIf="hasPrimaryInfo || (!aggregationStatusIsInitialized || hasAggregationStatusInfo)"
class="uk-width-expand uk-padding uk-inline">
<!-- Description -->
<div *ngIf="dataProviderInfo.description" class="uk-margin-medium-bottom">
<div class="uk-text-justify">
<div class="uk-text-meta uk-margin-small-bottom">Description</div>
<div class="multi-line-ellipsis lines-10">
<div #descriptionDiv class="uk-margin-small-bottom"
[innerHtml]="dataProviderInfo.description"></div>
</div>
<div *ngIf="showViewMoreButton" class="uk-flex uk-flex-right">
<a (click)="openDescriptionModal();" class="view-more-less-link">
View more
</a>
</div>
</div>
</div>
<ul *ngIf="hasJournalInfo" class="uk-list uk-margin-medium-bottom uk-margin-remove-top">
<showPublisher [journal]="dataProviderInfo.journal" [properties]="properties"></showPublisher>
</ul>
<div *ngIf="hasAggregationStatusInfo || dataProviderInfo.fundedContent"
class="uk-margin-medium-bottom uk-animation-fade uk-animation-fast">
<span *ngIf="dataProviderInfo.aggregationStatus?.fulltexts && dataProviderInfo.aggregationStatus?.fulltexts != -1"
class="uk-margin-right uk-display-inline-block">
<div class="uk-text-meta uk-margin-small-bottom">Collected full-texts</div>
{{dataProviderInfo.aggregationStatus.fulltexts | number}}
</span>
<span *ngIf="dataProviderInfo.fundedContent && dataProviderInfo.fundedContent > 0"
class="uk-display-inline-block">
<div class="uk-text-meta uk-margin-small-bottom">Results with funding information</div>
{{dataProviderInfo.fundedContent | number}}
</span>
</div>
<div *ngIf="!aggregationStatusIsInitialized || !dataProviderInfo.fundedContent"
class="uk-animation-fade uk-margin-top uk-width-1-1" role="alert">
<span class="loading-gif uk-align-center"></span>
</div>
<div *ngIf="dataProviderInfo.countries != undefined && dataProviderInfo.countries.length > 0"
class="uk-margin-medium-bottom">
<div class="uk-text-meta uk-margin-small-bottom">Countries</div>
{{dataProviderInfo.countries.join(", ")}}
</div>
<div *ngIf="dataProviderInfo.jurisdiction" class="uk-margin-medium-bottom">
<div class="uk-text-meta uk-margin-small-bottom">Jurisdiction</div>
{{dataProviderInfo.jurisdiction}}
</div>
<div *ngIf="dataProviderInfo.contentpolicy" class="uk-margin-medium-bottom">
<div class="uk-text-meta uk-margin-small-bottom">Content policy</div>
{{dataProviderInfo.contentpolicy}}
</div>
<!-- Subjects -->
<div *ngIf="dataProviderInfo.subjects && dataProviderInfo.subjects.length > 0"
class="uk-margin-medium-bottom uk-margin-bottom">
<div class="uk-height-max-medium uk-overflow-auto">
<div class="uk-text-meta uk-margin-small-bottom">Subjects </div>
<span>{{dataProviderInfo.subjects.slice(0, lessBtnSubjects ? dataProviderInfo.subjects.length : thresholdSubjects).join(", ")}}</span>
<span *ngIf="dataProviderInfo.subjects.length > thresholdSubjects && !lessBtnSubjects"> ... </span>
</div>
<div *ngIf="dataProviderInfo.subjects.length > thresholdSubjects && !lessBtnSubjects"
class="uk-width-1-1 uk-text-right">
<a (click)="viewAllSubjectsClick();" class="view-more-less-link">
View all {{dataProviderInfo.subjects.length | number}} subjects
</a>
</div>
<div *ngIf="viewAllSubjects && lessBtnSubjects" class="uk-width-1-1 uk-text-right">
<a (click)="viewAllSubjects = !viewAllSubjects; lessBtnSubjects=false;" class="view-more-less-link">View less subjects</a>
</div>
</div>
</div>
<div *ngIf="hasSecondaryInfo"
[class]="'uk-inline uk-padding uk-padding-remove-horizontal ' + (hasPrimaryInfo?'uk-width-1-3@m': 'uk-width-expand')">
<div class="uk-padding uk-padding-remove-vertical uk-height-1-1">
<div *ngIf="dataProviderInfo.oaiPmhURL || dataProviderInfo.provenance?.size > 0"
class="uk-margin-medium-bottom">
<div *ngIf="dataProviderInfo.oaiPmhURL" class="uk-margin-medium-bottom">
<div class="uk-text-meta uk-margin-small-bottom">OAI-PMH</div>
<a target="_blank" href="{{dataProviderInfo.oaiPmhURL}}" class="custom-external">
{{dataProviderInfo.oaiPmhURL}}
</a>
</div>
<div *ngIf="dataProviderInfo.provenance?.size > 0" class="uk-display-inline-block">
<div class="uk-text-meta uk-margin-small-bottom">Detailed information @ </div>
<span *ngFor="let provenance of getKeys(dataProviderInfo.provenance); let i=index">
<a *ngIf="dataProviderInfo.provenance.get(provenance).url.length == 1" class="custom-external uk-link-text"
target="_blank" href="{{dataProviderInfo.provenance.get(provenance).url}}">
{{provenance}}
</a>
<ng-container *ngIf="dataProviderInfo.provenance.get(provenance).url.length > 1">
<span class="custom-external">{{provenance}}</span>
<ng-container *ngFor="let url of dataProviderInfo.provenance.get(provenance).url; let i=index">
[<a target="_blank" href="{{url}}">{{i}}</a>]
</ng-container> </ng-container>
</ng-container>
<span *ngIf="i < dataProviderInfo.provenance.size-1">, </span>
</span>
</div>
</div>
<div *ngIf="dataProviderInfo.organizations && dataProviderInfo.organizations.length > 0"
class="uk-margin-medium-bottom">
<div class="uk-text-meta uk-margin-small-bottom">{{openaireEntities.ORGANIZATIONS}}</div>
<ng-container *ngTemplateOutlet="organizations_template; context: { threshold: lessBtnOrganizations ? dataProviderInfo.organizations.length : thresholdOrganizations }"></ng-container>
<div *ngIf="dataProviderInfo.organizations.length > thresholdOrganizations && !lessBtnOrganizations"
class="uk-width-1-1 uk-text-right">
<a (click)="viewAllOrganizationsClick();" class="view-more-less-link">
View all {{dataProviderInfo.organizations.length | number}} organizations
</a>
</div>
<div *ngIf="viewAllOrganizations && lessBtnOrganizations" class="uk-width-1-1 uk-text-right">
<a (click)="viewAllOrganizations = !viewAllOrganizations; lessBtnOrganizations=false;" class="view-more-less-link">View less organizations</a>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Projects-->
<ng-container *ngIf="fetchProjects.searchUtils.totalResults > 0"> <ng-container *ngIf="fetchProjects.searchUtils.totalResults > 0">
<div id="projects" class="landing-section uk-padding uk-padding-remove-horizontal"> <ng-container *ngTemplateOutlet="projects_content"></ng-container>
<search-tab [fetch]="fetchProjects" resultType="project"
[params]="getParamsForSearchLink()"
[searchLinkToAdvancedPage]="properties.searchLinkToAdvancedProjects"
[properties]="properties" [prevPath]="prevPath">
</search-tab>
</div>
</ng-container> </ng-container>
<!-- Datasources -->
<ng-container *ngIf="fetchDataproviders.searchUtils.totalResults > 0"> <ng-container *ngIf="fetchDataproviders.searchUtils.totalResults > 0">
<div id="datasources" class="landing-section uk-padding uk-padding-remove-horizontal"> <ng-container *ngTemplateOutlet="dataproviders_content"></ng-container>
<search-tab [fetch]="fetchDataproviders" resultType="dataprovider"
[params]="getParamsForSearchLink()"
[searchLinkToAdvancedPage]="properties.searchLinkToAdvancedDataProviders"
[properties]="properties" [prevPath]="prevPath">
</search-tab>
</div>
</ng-container> </ng-container>
<!--Publications-->
<ng-container *ngIf="fetchPublications.searchUtils.totalResults > 0"> <ng-container *ngIf="fetchPublications.searchUtils.totalResults > 0">
<div id="publications" class="landing-section uk-padding uk-padding-remove-horizontal"> <ng-container *ngTemplateOutlet="publications_content"></ng-container>
<search-tab [fetch]="fetchPublications" resultType="publication"
[params]="getParamsForSearchLink('publications')"
[searchLinkToAdvancedPage]="properties.searchLinkToAdvancedResults"
[properties]="properties" [prevPath]="prevPath">
</search-tab>
</div>
</ng-container> </ng-container>
<!--Research Data-->
<ng-container *ngIf="fetchDatasets.searchUtils.totalResults > 0"> <ng-container *ngIf="fetchDatasets.searchUtils.totalResults > 0">
<div id="datasets" class="landing-section uk-padding uk-padding-remove-horizontal"> <ng-container *ngTemplateOutlet="datasets_content"></ng-container>
<search-tab [fetch]="fetchDatasets" resultType="dataset"
[params]="getParamsForSearchLink('datasets')"
[searchLinkToAdvancedPage]="properties.searchLinkToAdvancedResults"
[properties]="properties" [prevPath]="prevPath">
</search-tab>
</div>
</ng-container> </ng-container>
<!--Software-->
<ng-container *ngIf="fetchSoftware.searchUtils.totalResults > 0"> <ng-container *ngIf="fetchSoftware.searchUtils.totalResults > 0">
<div id="software" class="landing-section uk-padding uk-padding-remove-horizontal"> <ng-container *ngTemplateOutlet="software_content"></ng-container>
<search-tab [fetch]="fetchSoftware" resultType="software"
[params]="getParamsForSearchLink('software')"
[searchLinkToAdvancedPage]="properties.searchLinkToAdvancedResults"
[properties]="properties" [prevPath]="prevPath">
</search-tab>
</div>
</ng-container> </ng-container>
<!--Other-->
<ng-container *ngIf="fetchOrps.searchUtils.totalResults > 0"> <ng-container *ngIf="fetchOrps.searchUtils.totalResults > 0">
<div id="other" class="landing-section uk-padding uk-padding-remove-horizontal"> <ng-container *ngTemplateOutlet="other_content"></ng-container>
<search-tab [fetch]="fetchOrps" resultType="other"
[params]="getParamsForSearchLink('other')"
[searchLinkToAdvancedPage]="properties.searchLinkToAdvancedResults"
[properties]="properties" [prevPath]="prevPath">
</search-tab>
</div>
</ng-container> </ng-container>
<!--Related Datasources-->
<ng-container *ngIf="(fetchPublications.searchUtils.totalResults > 0 || fetchDatasets.searchUtils.totalResults > 0 <ng-container *ngIf="(fetchPublications.searchUtils.totalResults > 0 || fetchDatasets.searchUtils.totalResults > 0
|| fetchSoftware.searchUtils.totalResults > 0 || fetchOrps.searchUtils.totalResults > 0)"> || fetchSoftware.searchUtils.totalResults > 0 || fetchOrps.searchUtils.totalResults > 0)">
<div id="relatedDatasources" class="landing-section uk-padding uk-padding-remove-horizontal"> <ng-container *ngTemplateOutlet="relatedDatasources_content"></ng-container>
<relatedDatasourcesTab </ng-container>
[dataproviderId]="datasourceId" <ng-container *ngIf="dataProviderInfo && hasMetrics">
[results]="dataProviderInfo.relatedDatasources" <ng-container *ngTemplateOutlet="metricsContent"></ng-container>
[loading]="loadingRelatedDatasources"
[fetchResults]="fetchAggregatorsResults"
[collectedFromName]="dataProviderInfo.title.name"
[properties]=properties
[modal]="relatedDatasourcesModal" [prevPath]="prevPath">
</relatedDatasourcesTab>
</div>
</ng-container> </ng-container>
<!--Statistics-->
<ng-container *ngIf="(fetchPublications.searchUtils.totalResults > 0 || fetchDatasets.searchUtils.totalResults > 0 <ng-container *ngIf="(fetchPublications.searchUtils.totalResults > 0 || fetchDatasets.searchUtils.totalResults > 0
|| fetchSoftware.searchUtils.totalResults > 0 || fetchOrps.searchUtils.totalResults > 0)"> || fetchSoftware.searchUtils.totalResults > 0 || fetchOrps.searchUtils.totalResults > 0)">
<ng-container *ngTemplateOutlet="statistics_content"></ng-container>
<div id="statistics" class="landing-section uk-padding uk-padding-remove-horizontal">
<div class="uk-text-meta uk-text-large uk-text-uppercase uk-margin-medium-bottom">Statistics</div>
<errorMessages [status]="[fetchPublications.searchUtils.status, fetchDatasets.searchUtils.status,
fetchSoftware.searchUtils.status, fetchOrps.searchUtils.status]"
[type]="'statistics'" tab_error_class=true></errorMessages>
<div *ngIf="statsClicked &&
(fetchPublications.searchUtils.status == errorCodes.DONE || fetchDatasets.searchUtils.status == errorCodes.DONE
|| fetchSoftware.searchUtils.status == errorCodes.DONE || fetchOrps.searchUtils.status == errorCodes.DONE)">
<statisticsTab [fetchPublications]="fetchPublications" [fetchDatasets]="fetchDatasets"
[fetchSoftware]="fetchSoftware" [fetchOther]="fetchOrps"
[datasourceId]="datasourceId">
</statisticsTab>
</div>
</div>
</ng-container> </ng-container>
</div> </div>
<div class="uk-text-xsmall uk-hidden@m"><ng-container *ngTemplateOutlet="graph_and_feedback_template"></ng-container></div> <div class="uk-text-xsmall uk-hidden@m"><ng-container *ngTemplateOutlet="graph_and_feedback_template"></ng-container></div>
@ -454,6 +323,188 @@
</div> </div>
</div> </div>
</div> </div>
</div>
<!-- Mobile view -->
<div *ngIf="isMobile" class="uk-hidden@m uk-position-relative landing">
<ng-container *ngIf="dataProviderInfo">
<div *ngIf="mobileContent == 'info'" class="uk-container uk-section">
<landing-header [properties]="properties" [title]="dataProviderInfo.title.name"
[subTitle]="(dataProviderInfo.officialName
&& dataProviderInfo.title.name !== dataProviderInfo.officialName)?dataProviderInfo.officialName:null"
[types]="dataProviderInfo.type ? [dataProviderInfo.type] : null"
[entityType]="getTypeName()"
[compatibility]="dataProviderInfo.compatibility"
[aggregationStatus]="dataProviderInfo.aggregationStatus"
[thematic]="dataProviderInfo.thematic" [type]="type"
[journal]="dataProviderInfo.journal" [prevPath]="prevPath">
</landing-header>
<div *ngIf="dataProviderInfo.title && dataProviderInfo.title.url"
class="uk-text-small uk-margin-small-top">
<span class="uk-text-meta">Web page: </span>
<a [href]="dataProviderInfo.title.url" target="_blank"
class="uk-button uk-button-text uk-text-lowercase uk-text-normal custom-external">
{{dataProviderInfo.title.url}}
</a>
</div>
<div *ngIf="dataProviderInfo.identifiers && dataProviderInfo.identifiers.size > 0" class="uk-margin-small-top uk-text-small">
<showIdentifiers [identifiers]="dataProviderInfo.identifiers" [showViewAll]="true"></showIdentifiers>
</div>
<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(summaryFsModal, 'Summary'); onSelectActiveTab('summary')">
<span>Summary</span>
<icon name="chevron_right" [ratio]="1.5" [flex]="true"></icon>
</div>
<hr>
</ng-container>
<ng-container *ngIf="fetchProjects.searchUtils.totalResults > 0">
<div class="clickable uk-flex uk-flex-middle uk-flex-between" (click)="openFsModal(projectsFsModal, openaireEntities.PROJECTS); onSelectActiveTab('projects')">
<span>{{openaireEntities.PROJECTS}}</span>
<icon name="chevron_right" [ratio]="1.5" [flex]="true"></icon>
</div>
<hr>
</ng-container>
<ng-container *ngIf="fetchDataproviders.searchUtils.totalResults > 0">
<div class="clickable uk-flex uk-flex-middle uk-flex-between" (click)="openFsModal(dataprovidersFsModal, openaireEntities.DATASOURCES); onSelectActiveTab('datasources')">
<span>{{openaireEntities.DATASOURCES}}</span>
<icon name="chevron_right" [ratio]="1.5" [flex]="true"></icon>
</div>
<hr>
</ng-container>
<ng-container *ngIf="fetchPublications.searchUtils.totalResults > 0">
<div class="clickable uk-flex uk-flex-middle uk-flex-between" (click)="openFsModal(publicationsFsModal, 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.searchUtils.totalResults > 0">
<div class="clickable uk-flex uk-flex-middle uk-flex-between" (click)="openFsModal(datasetsFsModal, 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.searchUtils.totalResults > 0">
<div class="clickable uk-flex uk-flex-middle uk-flex-between" (click)="openFsModal(softwareFsModal, 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.searchUtils.totalResults > 0">
<div class="clickable uk-flex uk-flex-middle uk-flex-between" (click)="openFsModal(otherFsModal, openaireEntities.OTHER); onSelectActiveTab('other')">
<span>{{openaireEntities.OTHER}}</span>
<icon name="chevron_right" [ratio]="1.5" [flex]="true"></icon>
</div>
<hr>
</ng-container>
<ng-container *ngIf="(fetchPublications.searchUtils.totalResults > 0 || fetchDatasets.searchUtils.totalResults > 0
|| fetchSoftware.searchUtils.totalResults > 0 || fetchOrps.searchUtils.totalResults > 0)">
<div class="clickable uk-flex uk-flex-middle uk-flex-between" (click)="openFsModal(relatedDatasourcesFsModal, 'Related '+openaireEntities.DATASOURCES); onSelectActiveTab('relatedDatasources')">
<span>Related {{openaireEntities.DATASOURCES}}</span>
<icon name="chevron_right" [ratio]="1.5" [flex]="true"></icon>
</div>
<hr>
</ng-container>
<ng-container *ngIf="(fetchPublications.searchUtils.totalResults > 0 || fetchDatasets.searchUtils.totalResults > 0
|| fetchSoftware.searchUtils.totalResults > 0 || fetchOrps.searchUtils.totalResults > 0)">
<div class="clickable uk-flex uk-flex-middle uk-flex-between" (click)="openFsModal(statisticsFsModal, 'Statistics'); onSelectActiveTab('statistics')">
<span>Statistics</span>
<icon name="chevron_right" [ratio]="1.5" [flex]="true"></icon>
</div>
<hr>
</ng-container>
</div>
</div>
<div *ngIf="mobileContent == 'metrics'" class="uk-container uk-section">
<ng-container *ngTemplateOutlet="metricsContent"></ng-container>
</div>
<div *ngIf="mobileContent == 'actions'" class="uk-container uk-section">
<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.DATASOURCE+' 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>
</div>
<div class="landing-action-bar-mobile uk-background-default">
<div class="uk-container uk-flex-middle uk-grid uk-text-xsmall uk-text-meta" [ngClass]="hasMetrics ? 'uk-child-width-1-3' : 'uk-child-width-1-2'">
<div>
<a class="uk-flex uk-flex-column uk-flex-middle uk-flex-center uk-link-reset" (click)="mobileContent = 'info'">
<icon name="note_add" type="outlined" [flex]="true" [ratio]="2" [ngClass]="mobileContent == 'info' ? 'uk-text-primary': ''"></icon>
<span>{{openaireEntities.DATASOURCE}}</span>
</a>
</div>
<div *ngIf="dataProviderInfo && hasMetrics">
<a class="uk-flex uk-flex-column uk-flex-middle uk-flex-center uk-link-reset" (click)="mobileContent = 'metrics'">
<icon name="bar_chart" type="outlined" [flex]="true" [ratio]="2" [ngClass]="mobileContent == 'metrics' ? 'uk-text-primary': ''"></icon>
<span>Metrics</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>
<fs-modal #summaryFsModal classTitle="uk-tile-default uk-border-bottom" (cancelEmitter)="cancelSummaryClicked()">
<ng-container *ngTemplateOutlet="summary_content"></ng-container>
</fs-modal>
<fs-modal #projectsFsModal classTitle="uk-tile-default uk-border-bottom"
*ngIf="fetchProjects.searchUtils.totalResults > 0">
<ng-container *ngTemplateOutlet="projects_content"></ng-container>
</fs-modal>
<fs-modal #dataprovidersFsModal classTitle="uk-tile-default uk-border-bottom"
*ngIf="fetchDataproviders.searchUtils.totalResults > 0">
<ng-container *ngTemplateOutlet="dataproviders_content"></ng-container>
</fs-modal>
<fs-modal #publicationsFsModal classTitle="uk-tile-default uk-border-bottom"
*ngIf="fetchPublications.searchUtils.totalResults > 0">
<ng-container *ngTemplateOutlet="publications_content"></ng-container>
</fs-modal>
<fs-modal #datasetsFsModal classTitle="uk-tile-default uk-border-bottom"
*ngIf="fetchDatasets.searchUtils.totalResults > 0">
<ng-container *ngTemplateOutlet="datasets_content"></ng-container>
</fs-modal>
<fs-modal #softwareFsModal classTitle="uk-tile-default uk-border-bottom"
*ngIf="fetchSoftware.searchUtils.totalResults > 0">
<ng-container *ngTemplateOutlet="software_content"></ng-container>
</fs-modal>
<fs-modal #otherFsModal classTitle="uk-tile-default uk-border-bottom"
*ngIf="fetchOrps.searchUtils.totalResults > 0">
<ng-container *ngTemplateOutlet="other_content"></ng-container>
</fs-modal>
<fs-modal #relatedDatasourcesFsModal classTitle="uk-tile-default uk-border-bottom"
*ngIf="(fetchPublications.searchUtils.totalResults > 0 || fetchDatasets.searchUtils.totalResults > 0
|| fetchSoftware.searchUtils.totalResults > 0 || fetchOrps.searchUtils.totalResults > 0)">
<ng-container *ngTemplateOutlet="relatedDatasources_content"></ng-container>
</fs-modal>
<fs-modal #statisticsFsModal classTitle="uk-tile-default uk-border-bottom"
*ngIf="(fetchPublications.searchUtils.totalResults > 0 || fetchDatasets.searchUtils.totalResults > 0
|| fetchSoftware.searchUtils.totalResults > 0 || fetchOrps.searchUtils.totalResults > 0)">
<ng-container *ngTemplateOutlet="statistics_content"></ng-container>
</fs-modal>
</ng-container>
</div>
<feedback *ngIf="dataProviderInfo && properties.reCaptchaSiteKey" [dataProviderInfo]="dataProviderInfo" <feedback *ngIf="dataProviderInfo && properties.reCaptchaSiteKey" [dataProviderInfo]="dataProviderInfo"
[properties]="properties" [entityType]="getTypeName()" [fields]="feedbackFields" [properties]="properties" [entityType]="getTypeName()" [fields]="feedbackFields"
@ -495,3 +546,324 @@
<modal-alert *ngIf="dataProviderInfo && dataProviderInfo.subjects" #subjectsModal> <modal-alert *ngIf="dataProviderInfo && dataProviderInfo.subjects" #subjectsModal>
<span>{{dataProviderInfo.subjects.join(", ")}}</span> <span>{{dataProviderInfo.subjects.join(", ")}}</span>
</modal-alert> </modal-alert>
<ng-template #summary_content>
<div id="summary" class="landing-section landing-section-height-auto">
<div class="uk-grid uk-margin-remove-left uk-margin-medium-top uk-margin-medium-bottom" [ngClass]="isMobile ? '' : 'uk-card uk-card-default card-tab'">
<div *ngIf="!(hasPrimaryInfo || (!aggregationStatusIsInitialized || hasAggregationStatusInfo)) && !hasSecondaryInfo"
class="uk-width-expand uk-height-small uk-flex uk-flex-center uk-flex-middle">
<div class="uk-animation-fade uk-text-meta uk-text-large">
No summary information available
</div>
</div>
<div *ngIf="hasPrimaryInfo || (!aggregationStatusIsInitialized || hasAggregationStatusInfo)"
class="uk-width-expand uk-inline" [ngClass]="isMobile ? 'uk-padding-remove' : 'uk-padding'">
<!-- Description -->
<div *ngIf="dataProviderInfo.description && (!viewAllMobile || viewAllMobile == 'description')" class="uk-margin-medium-bottom">
<div class="uk-text-justify">
<div *ngIf="viewAllMobile != 'description'" class="uk-text-meta uk-margin-small-bottom">Description</div>
<div [ngClass]="viewAllMobile == 'description' ? '' : 'multi-line-ellipsis lines-10'">
<div #descriptionDiv class="uk-margin-small-bottom"
[innerHtml]="dataProviderInfo.description"></div>
</div>
<div *ngIf="showViewMoreButton && viewAllMobile != 'description'" class="uk-flex uk-flex-right">
<a (click)="viewAllDescriptionClicked();" class="view-more-less-link">
View more
</a>
</div>
</div>
</div>
<!-- <ul *ngIf="hasJournalInfo" class="uk-list uk-margin-medium-bottom uk-margin-remove-top">
<showPublisher [journal]="dataProviderInfo.journal" [properties]="properties"></showPublisher>
</ul> -->
<ng-container *ngIf="!viewAllMobile">
<div *ngIf="hasAggregationStatusInfo || (dataProviderInfo.fundedContent && dataProviderInfo.fundedContent > 0)"
class="uk-margin-medium-bottom uk-animation-fade uk-animation-fast">
<span *ngIf="dataProviderInfo.aggregationStatus?.fulltexts && dataProviderInfo.aggregationStatus?.fulltexts != -1"
class="uk-margin-right uk-display-inline-block">
<div class="uk-text-meta uk-margin-small-bottom">Collected full-texts</div>
{{dataProviderInfo.aggregationStatus.fulltexts | number}}
</span>
<span *ngIf="dataProviderInfo.fundedContent && dataProviderInfo.fundedContent > 0"
class="uk-display-inline-block">
<div class="uk-text-meta uk-margin-small-bottom">Results with funding information</div>
{{dataProviderInfo.fundedContent | number}}
</span>
</div>
<div *ngIf="!aggregationStatusIsInitialized || !dataProviderInfo.fundedContent"
class="uk-animation-fade uk-margin-top uk-width-1-1" role="alert">
<span class="loading-gif uk-align-center"></span>
</div>
<div *ngIf="dataProviderInfo.countries != undefined && dataProviderInfo.countries.length > 0"
class="uk-margin-medium-bottom">
<div class="uk-text-meta uk-margin-small-bottom">Countries</div>
{{dataProviderInfo.countries.join(", ")}}
</div>
<div *ngIf="dataProviderInfo.jurisdiction" class="uk-margin-medium-bottom">
<div class="uk-text-meta uk-margin-small-bottom">Jurisdiction</div>
{{dataProviderInfo.jurisdiction}}
</div>
<div *ngIf="dataProviderInfo.contentpolicy" class="uk-margin-medium-bottom">
<div class="uk-text-meta uk-margin-small-bottom">Content policy</div>
{{dataProviderInfo.contentpolicy}}
</div>
</ng-container>
<!-- Subjects -->
<div *ngIf="dataProviderInfo.subjects && dataProviderInfo.subjects.length > 0 && (!viewAllMobile || viewAllMobile == 'subjects')"
class="uk-margin-medium-bottom uk-margin-bottom">
<div class="uk-height-max-medium uk-overflow-auto">
<div *ngIf="viewAllMobile != 'subjects'" class="uk-text-meta uk-margin-small-bottom">Subjects </div>
<ng-container *ngIf="!viewAllMobile">
<span>{{dataProviderInfo.subjects.slice(0, lessBtnSubjects ? dataProviderInfo.subjects.length : thresholdSubjects).join(", ")}}</span>
<span *ngIf="dataProviderInfo.subjects.length > thresholdSubjects && !lessBtnSubjects"> ... </span>
</ng-container>
<ng-container *ngIf="viewAllMobile == 'subjects'">
<span>{{dataProviderInfo.subjects.join(", ")}}</span>
</ng-container>
</div>
<div *ngIf="dataProviderInfo.subjects.length > thresholdSubjects && !lessBtnSubjects && viewAllMobile != 'subjects'"
class="uk-width-1-1 uk-text-right">
<a (click)="viewAllSubjectsClick();" class="view-more-less-link">
View all {{dataProviderInfo.subjects.length | number}} subjects
</a>
</div>
<div *ngIf="viewAllSubjects && lessBtnSubjects" class="uk-width-1-1 uk-text-right">
<a (click)="viewAllSubjects = !viewAllSubjects; lessBtnSubjects=false;" class="view-more-less-link">View less subjects</a>
</div>
</div>
</div>
<div *ngIf="hasSecondaryInfo"
[class]="'uk-inline uk-padding-remove-horizontal ' + (hasPrimaryInfo?'uk-width-1-3@m': 'uk-width-expand')" [ngClass]="isMobile ? '' : 'uk-padding'">
<div class="uk-height-1-1" [ngClass]="isMobile ? '' : 'uk-padding uk-padding-remove-vertical'">
<div *ngIf="(dataProviderInfo.oaiPmhURL || dataProviderInfo.provenance?.size > 0) && !viewAllMobile"
class="uk-margin-medium-bottom">
<div *ngIf="dataProviderInfo.oaiPmhURL" class="uk-margin-medium-bottom">
<div class="uk-text-meta uk-margin-small-bottom">OAI-PMH</div>
<a target="_blank" href="{{dataProviderInfo.oaiPmhURL}}" class="custom-external">
{{dataProviderInfo.oaiPmhURL}}
</a>
</div>
<div *ngIf="dataProviderInfo.provenance?.size > 0" class="uk-display-inline-block">
<div class="uk-text-meta uk-margin-small-bottom">Detailed information @ </div>
<span *ngFor="let provenance of getKeys(dataProviderInfo.provenance); let i=index">
<a *ngIf="dataProviderInfo.provenance.get(provenance).url.length == 1" class="custom-external uk-link-text"
target="_blank" href="{{dataProviderInfo.provenance.get(provenance).url}}">
{{provenance}}
</a>
<ng-container *ngIf="dataProviderInfo.provenance.get(provenance).url.length > 1">
<span class="custom-external">{{provenance}}</span>
<ng-container *ngFor="let url of dataProviderInfo.provenance.get(provenance).url; let i=index">
[<a target="_blank" href="{{url}}">{{i}}</a>]
</ng-container>
</ng-container>
<span *ngIf="i < dataProviderInfo.provenance.size-1">, </span>
</span>
</div>
</div>
<div *ngIf="dataProviderInfo.organizations && dataProviderInfo.organizations.length > 0 && (!viewAllMobile || viewAllMobile == 'organizations')"
class="uk-margin-medium-bottom">
<div *ngIf="viewAllMobile != 'organizations'" class="uk-text-meta uk-margin-small-bottom">{{openaireEntities.ORGANIZATIONS}}</div>
<ng-container *ngTemplateOutlet="organizations_template; context: { threshold: (lessBtnOrganizations || viewAllMobile == 'organizations') ? dataProviderInfo.organizations.length : thresholdOrganizations }"></ng-container>
<div *ngIf="dataProviderInfo.organizations.length > thresholdOrganizations && !lessBtnOrganizations && viewAllMobile != 'organizations'"
class="uk-width-1-1 uk-text-right">
<a (click)="viewAllOrganizationsClick();" class="view-more-less-link">
View all {{dataProviderInfo.organizations.length | number}} organizations
</a>
</div>
<div *ngIf="viewAllOrganizations && lessBtnOrganizations" class="uk-width-1-1 uk-text-right">
<a (click)="viewAllOrganizations = !viewAllOrganizations; lessBtnOrganizations=false;" class="view-more-less-link">View less organizations</a>
</div>
</div>
</div>
</div>
</div>
</div>
</ng-template>
<ng-template #projects_content>
<div id="projects" class="landing-section uk-padding uk-padding-remove-horizontal">
<search-tab [fetch]="fetchProjects" resultType="project"
[params]="getParamsForSearchLink()"
[searchLinkToAdvancedPage]="properties.searchLinkToAdvancedProjects"
[properties]="properties" [prevPath]="prevPath">
</search-tab>
</div>
</ng-template>
<ng-template #dataproviders_content>
<div id="datasources" 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>
</ng-template>
<ng-template #publications_content>
<div 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>
</ng-template>
<ng-template #datasets_content>
<div 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>
</ng-template>
<ng-template #software_content>
<div 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>
</ng-template>
<ng-template #other_content>
<div 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>
</ng-template>
<ng-template #relatedDatasources_content>
<div id="relatedDatasources" class="landing-section uk-padding uk-padding-remove-horizontal">
<relatedDatasourcesTab
[dataproviderId]="datasourceId"
[results]="dataProviderInfo.relatedDatasources"
[loading]="loadingRelatedDatasources"
[fetchResults]="fetchAggregatorsResults"
[collectedFromName]="dataProviderInfo.title.name"
[properties]=properties
[modal]="relatedDatasourcesModal" [prevPath]="prevPath">
</relatedDatasourcesTab>
</div>
</ng-template>
<ng-template #statistics_content>
<div id="statistics" class="landing-section uk-padding uk-padding-remove-horizontal">
<div class="uk-text-meta uk-text-large uk-text-uppercase uk-margin-medium-bottom">Statistics</div>
<errorMessages [status]="[fetchPublications.searchUtils.status, fetchDatasets.searchUtils.status,
fetchSoftware.searchUtils.status, fetchOrps.searchUtils.status]"
[type]="'statistics'" tab_error_class=true></errorMessages>
<div *ngIf="statsClicked &&
(fetchPublications.searchUtils.status == errorCodes.DONE || fetchDatasets.searchUtils.status == errorCodes.DONE
|| fetchSoftware.searchUtils.status == errorCodes.DONE || fetchOrps.searchUtils.status == errorCodes.DONE)">
<statisticsTab [fetchPublications]="fetchPublications" [fetchDatasets]="fetchDatasets"
[fetchSoftware]="fetchSoftware" [fetchOther]="fetchOrps"
[datasourceId]="datasourceId">
</statisticsTab>
</div>
</div>
</ng-template>
<ng-template #metricsContent>
<div id="metrics" class="landing-section uk-padding uk-padding-remove-horizontal">
<ul class="uk-subnav uk-subnav-pill-alt uk-margin-remove" uk-switcher>
<li class="uk-padding-remove">
<a href="#">Overview</a>
</li>
<li *ngIf="hasMetrics">
<a href="#" (click)="clickedUsageMetrics()">Usage</a>
</li>
</ul>
<ul class="uk-switcher uk-margin-large-top">
<!-- overview -->
<li>
<div *ngIf="hasMetrics">
<div class="uk-grid-divider" uk-grid>
<div>
<div class="uk-text-center uk-margin-small-bottom">
<a href='https://usagecounts.openaire.eu/' target='_blank'>
<img src="assets/common-assets/logo-small-usage-counts.png" loading="lazy" alt="OpenAIRE UsageCounts">
</a>
</div>
<span class="uk-text-uppercase uk-text-xsmall">Usage by</span>
<span class="uk-display-block uk-text-bolder">
<a href='https://usagecounts.openaire.eu/' target='_blank' class="uk-link-reset">UsageCounts</a>
</span>
</div>
<div>
<table class="uk-table uk-table-small">
<tbody>
<ng-container *ngFor="let measure of dataProviderInfo.measure.counts; let i = index">
<tr>
<td [class.uk-padding-remove-top]="i == 0" [class.uk-padding-remove-bottom]="i == dataProviderInfo.measure.counts.length - 1">
<icon [name]="measure.icon" [flex]="true" [ratio]="1.2" customClass="uk-text-background text-usage-counts"></icon>
</td>
<td class="uk-text-capitalize" [class.uk-padding-remove-top]="i == 0" [class.uk-padding-remove-bottom]="i == dataProviderInfo.measure.counts.length - 1">
{{measure.name}}
</td>
<td class="uk-text-uppercase uk-text-bolder" [class.uk-padding-remove-top]="i == 0" [class.uk-padding-remove-bottom]="i == dataProviderInfo.measure.counts.length - 1"
[attr.uk-tooltip]="measure.value >= 1000 ? 'cls: uk-active' : 'cls: uk-invisible'"
title="{{measure.value | number}}">
{{formatNumber(measure.value)}}
</td>
</tr>
</ng-container>
</tbody>
</table>
</div>
</div>
</div>
</li>
<!-- usage -->
<li *ngIf="hasMetrics">
<div class="uk-flex uk-flex-center uk-flex-middle uk-flex-wrap" [class.uk-flex-column]="isMobile">
<div class="uk-margin-large-right uk-flex uk-flex-center uk-flex-middle uk-flex-wrap" [class.uk-flex-column]="!isMobile">
<ng-container *ngFor="let measure of dataProviderInfo.measure.counts; let i = index">
<div *ngIf="measure.value" class="uk-text-center uk-margin-medium-bottom" [class.uk-margin-medium-right]="isMobile">
<div class="uk-text-background uk-text-bold number metrics-number"
[attr.uk-tooltip]="measure.value >= 1000 ? 'cls: uk-active' : 'cls: uk-invisible'"
title="{{measure.value | number}}">{{formatNumber(measure.value)}}</div>
<div class="uk-text-bold uk-text-capitalize">{{measure.name}}</div>
</div>
</ng-container>
</div>
<ng-container *ngIf="viewsFrameUrl || downloadsFrameUrl">
<div *ngIf="metricsClicked && viewsFrameUrl && hasViews" class="uk-margin-large-right">
<i-frame [height]="300" [url]="viewsFrameUrl" [addClass]="false"
customContainerClass="uk-background-default" customIframeClass="uk-blend-multiply uk-height-1-1">
</i-frame>
</div>
<div *ngIf="metricsClicked && downloadsFrameUrl && hasDownloads" class="uk-margin-large-right">
<i-frame [height]="300" [url]="downloadsFrameUrl" [addClass]="false"
customContainerClass="uk-background-default" customIframeClass="uk-blend-multiply uk-height-1-1"></i-frame>
</div>
</ng-container>
</div>
<div class="uk-text-center uk-margin-large-top">
<span class="uk-text-meta">Powered by</span>
<a href='https://usagecounts.openaire.eu/' target='_blank'>
<img class="uk-margin-small-left uk-margin-small-right uk-width-small" src="assets/common-assets/logo-large-usage-counts.png" loading="lazy" alt="OpenAIRE UsageCounts">
</a>
</div>
</li>
</ul>
</div>
</ng-template>
<fs-modal *ngIf="dataProviderInfo" #addThisFsModal classTitle="uk-tile-default uk-border-bottom" classBody="uk-flex uk-flex-center uk-flex-middle">
<addThis></addThis>
</fs-modal>

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 {ActivatedRoute, Router} from '@angular/router';
import {Meta, Title} from '@angular/platform-browser'; 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 {ResultPreview} from "../../utils/result-preview/result-preview";
import {IndexInfoService} from "../../utils/indexInfo.service"; import {IndexInfoService} from "../../utils/indexInfo.service";
import {properties} from "../../../../environments/environment"; import {properties} from "../../../../environments/environment";
import {Subscriber} from "rxjs"; import {Subscriber, Subscription, zip} from "rxjs";
import {TabComponent} from "../../utils/tabs/tab.component";
import {OpenaireEntities} from "../../utils/properties/searchFields"; 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; declare var ResizeObserver;
@ -64,16 +67,21 @@ export class DataProviderComponent {
public metricsClicked: boolean; public metricsClicked: boolean;
public viewsFrameUrl: string; public viewsFrameUrl: string;
public downloadsFrameUrl: string; public downloadsFrameUrl: string;
public totalViews: number; /** @deprecated*/
public totalDownloads: number; public totalViews: number = null;
public pageViews: number; /** @deprecated*/
public totalDownloads: number = null;
public hasViews: boolean = false;
public hasDownloads: boolean = false;
// public pageViews: number;
// Statistics tab variables // Statistics tab variables
public statsClicked: boolean = false; public statsClicked: boolean = false;
// @ViewChild('statisticsModal') statisticsModal; // @ViewChild('statisticsModal') statisticsModal;
// @ViewChild('relatedDatasourcesModal') relatedDatasourcesModal; // @ViewChild('relatedDatasourcesModal') relatedDatasourcesModal;
@ViewChild('addThisModal') addThisModal @ViewChild('addThisModal') addThisModal;
@ViewChild('addThisFsModal') addThisFsModal: FullScreenModalComponent;
// Variables for publications, research data, projects, datasources, related datasources tabs // Variables for publications, research data, projects, datasources, related datasources tabs
public fetchPublications: FetchResearchResults; public fetchPublications: FetchResearchResults;
@ -144,9 +152,25 @@ export class DataProviderComponent {
// public shouldSticky: boolean = true; // public shouldSticky: boolean = true;
subscriptions = []; subscriptions = [];
private sub: Subscription;
properties: EnvProperties = properties; properties: EnvProperties = properties;
public openaireEntities = OpenaireEntities; 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, constructor(private _dataproviderService: DataProviderService,
private _piwikService: PiwikService, private _piwikService: PiwikService,
private route: ActivatedRoute, private route: ActivatedRoute,
@ -160,7 +184,9 @@ export class DataProviderComponent {
private helper: HelperService, private helper: HelperService,
private _location: Location, private _location: Location,
private indexInfoService: IndexInfoService, private indexInfoService: IndexInfoService,
private cdr: ChangeDetectorRef) { private metricsService: MetricsService,
private cdr: ChangeDetectorRef,
private layoutService: LayoutService) {
this.fetchPublications = new FetchResearchResults(this._searchResearchResultsService); this.fetchPublications = new FetchResearchResults(this._searchResearchResultsService);
this.fetchDatasets = new FetchResearchResults(this._searchResearchResultsService); this.fetchDatasets = new FetchResearchResults(this._searchResearchResultsService);
this.fetchSoftware = new FetchResearchResults(this._searchResearchResultsService); this.fetchSoftware = new FetchResearchResults(this._searchResearchResultsService);
@ -171,6 +197,9 @@ export class DataProviderComponent {
} }
ngOnInit() { ngOnInit() {
this.subscriptions.push(this.layoutService.isMobile.subscribe(isMobile => {
this.isMobile = isMobile;
}));
if (typeof document !== 'undefined') { if (typeof document !== 'undefined') {
this.subscriptions.push(this.indexInfoService.getLastIndexDate(this.properties).subscribe(lastIndexUpdate => { this.subscriptions.push(this.indexInfoService.getLastIndexDate(this.properties).subscribe(lastIndexUpdate => {
if (lastIndexUpdate) { if (lastIndexUpdate) {
@ -328,7 +357,8 @@ export class DataProviderComponent {
this.subscriptions.forEach(subscription => { this.subscriptions.forEach(subscription => {
if (subscription instanceof Subscriber) { if (subscription instanceof Subscriber) {
subscription.unsubscribe(); subscription.unsubscribe();
} else if (subscription instanceof (ResizeObserver || IntersectionObserver)) { } else if ((typeof ResizeObserver != 'undefined' && subscription instanceof ResizeObserver) ||
(typeof IntersectionObserver != 'undefined' && subscription instanceof IntersectionObserver)) {
subscription.disconnect(); subscription.disconnect();
} }
}); });
@ -366,6 +396,7 @@ export class DataProviderComponent {
this.seoService.createLinkForCanonicalURL(this.properties.domain +this.properties.baseLink + this._router.url); this.seoService.createLinkForCanonicalURL(this.properties.domain +this.properties.baseLink + this._router.url);
if (typeof document !== 'undefined') { if (typeof document !== 'undefined') {
this.getDataProviderAggregationStatus(this.dataProviderInfo.originalId); this.getDataProviderAggregationStatus(this.dataProviderInfo.originalId);
// this.getCollectedFulltexts();
this.countResultsWithFundingInfo(); this.countResultsWithFundingInfo();
} else { } else {
this.aggregationStatusIsInitialized = true; this.aggregationStatusIsInitialized = true;
@ -381,6 +412,23 @@ export class DataProviderComponent {
} }
this.showLoading = false; 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(); this.cdr.detectChanges();
// if (this.dataProviderInfo.tabs != undefined && this.dataProviderInfo.tabs.length > 0) { // 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() { private countResultsWithFundingInfo() {
this.subscriptions.push(this._searchResearchResultsService.countCollectedResultsWithFundingInfo(this.datasourceId).subscribe( this.subscriptions.push(this._searchResearchResultsService.countCollectedResultsWithFundingInfo(this.datasourceId).subscribe(
fundedContent => { fundedContent => {
@ -680,11 +742,33 @@ export class DataProviderComponent {
public metricsResults($event) { public metricsResults($event) {
this.totalViews = $event.totalViews; this.totalViews = $event.totalViews;
this.totalDownloads = $event.totalDownloads; 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 { 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() { // public openStatistics() {
@ -714,10 +798,16 @@ export class DataProviderComponent {
this.viewAllOrganizations = true; this.viewAllOrganizations = true;
if(this.dataProviderInfo.organizations.length <= this.thresholdOrganizations*2) { if(this.dataProviderInfo.organizations.length <= this.thresholdOrganizations*2) {
this.lessBtnOrganizations = true; this.lessBtnOrganizations = true;
} else {
if(this.isMobile) {
this.summaryFsModal.title += " - Organizations";
this.summaryFsModal.back = true;
this.viewAllMobile = "organizations";
} else { } else {
this.openOrganizationsModal(); this.openOrganizationsModal();
} }
} }
}
public openOrganizationsModal() { public openOrganizationsModal() {
this.organizationsModal.cancelButton = false; this.organizationsModal.cancelButton = false;
@ -730,10 +820,16 @@ export class DataProviderComponent {
this.viewAllSubjects = true; this.viewAllSubjects = true;
if(this.dataProviderInfo.subjects.length <= this.thresholdSubjects*2) { if(this.dataProviderInfo.subjects.length <= this.thresholdSubjects*2) {
this.lessBtnSubjects = true; this.lessBtnSubjects = true;
} else {
if(this.isMobile) {
this.summaryFsModal.title += " - Subjects";
this.summaryFsModal.back = true;
this.viewAllMobile = "subjects";
} else { } else {
this.openSubjectsModal(); this.openSubjectsModal();
} }
} }
}
public openSubjectsModal() { public openSubjectsModal() {
this.subjectsModal.cancelButton = false; this.subjectsModal.cancelButton = false;
@ -795,7 +891,6 @@ export class DataProviderComponent {
// ((!!this.dataProviderInfo.aggregationStatus.fulltexts && parseInt(this.dataProviderInfo.aggregationStatus.fulltexts) != -1) // ((!!this.dataProviderInfo.aggregationStatus.fulltexts && parseInt(this.dataProviderInfo.aggregationStatus.fulltexts) != -1)
// || (!!this.dataProviderInfo.aggregationStatus.fundedContent && parseInt(this.dataProviderInfo.aggregationStatus.fundedContent) != -1) // || (!!this.dataProviderInfo.aggregationStatus.fundedContent && parseInt(this.dataProviderInfo.aggregationStatus.fundedContent) != -1)
// || !!this.dataProviderInfo.aggregationStatus.lastUpdateDate)); // || !!this.dataProviderInfo.aggregationStatus.lastUpdateDate));
return (!!this.dataProviderInfo.aggregationStatus && return (!!this.dataProviderInfo.aggregationStatus &&
((!!this.dataProviderInfo.aggregationStatus.fulltexts && parseInt(this.dataProviderInfo.aggregationStatus.fulltexts) != -1))); ((!!this.dataProviderInfo.aggregationStatus.fulltexts && parseInt(this.dataProviderInfo.aggregationStatus.fulltexts) != -1)));
} }
@ -837,12 +932,56 @@ export class DataProviderComponent {
return StringUtils.getEntityName(this.type, false); 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() { public openDescriptionModal() {
this.descriptionModal.alertFooter = false; this.descriptionModal.alertFooter = false;
this.descriptionModal.alertTitle = "Description"; this.descriptionModal.alertTitle = "Description";
this.descriptionModal.open(); 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) { public addEoscPrevInParams(obj) {
if(properties.adminToolsPortalType == "eosc" && this.prevPath) { if(properties.adminToolsPortalType == "eosc" && this.prevPath) {
let splitted: string[] = this.prevPath.split("?"); 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 {graph} from "../../utils/icons/icons";
import {LoadingModalModule} from "../../utils/modal/loadingModal.module"; import {LoadingModalModule} from "../../utils/modal/loadingModal.module";
import {ResultLandingUtilsModule} from "../landing-utils/resultLandingUtils.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({ @NgModule({
imports: imports:
@ -42,7 +45,8 @@ import {ResultLandingUtilsModule} from "../landing-utils/resultLandingUtils.modu
DataProvidersServiceModule, ProjectsServiceModule, SearchResearchResultsServiceModule, DataProvidersServiceModule, ProjectsServiceModule, SearchResearchResultsServiceModule,
PagingModule, Schema2jsonldModule, SEOServiceModule, ShowPublisherModule, HelperModule, PagingModule, Schema2jsonldModule, SEOServiceModule, ShowPublisherModule, HelperModule,
LandingHeaderModule, AlertModalModule, NoLoadPaging, FeedbackModule, LandingHeaderModule, AlertModalModule, NoLoadPaging, FeedbackModule,
TabsModule, SearchTabModule, LoadingModule, IconsModule, LoadingModalModule, ResultLandingUtilsModule TabsModule, SearchTabModule, LoadingModule, IconsModule, LoadingModalModule, ResultLandingUtilsModule,
FullScreenModalModule, SafeHtmlPipeModule, EntityActionsModule
], ],
declarations: declarations:
[StatisticsTabComponent, [StatisticsTabComponent,

View File

@ -83,6 +83,11 @@ export class DataProviderService {
.pipe(map(res => this.parseDataproviderAggregationStatus(res))); .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) { private handleError (error: HttpErrorResponse) {
// in a real world app, we may send the error to some remote logging infrastructure // in a real world app, we may send the error to some remote logging infrastructure
// instead of just logging it to the console // instead of just logging it to the console
@ -362,7 +367,10 @@ export class DataProviderService {
}else { }else {
this.dataProviderInfo.journal = null; 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; return this.dataProviderInfo;

View File

@ -1,34 +1,28 @@
import { import {
ChangeDetectorRef,
Component, Component,
EventEmitter, Inject, Input,
Inject,
OnInit, OnInit,
Output,
RendererFactory2, RendererFactory2,
ViewChild,
ViewEncapsulation ViewEncapsulation
} from '@angular/core'; } from '@angular/core';
import {ActivatedRoute} from '@angular/router'; import {ActivatedRoute} from '@angular/router';
import {DOCUMENT} from "@angular/common"; import {DOCUMENT} from "@angular/common";
import {Subscriber} from "rxjs"; import {Subscriber} from "rxjs";
interface addthis { declare var a2a;
layers: Refresh;
init: Function;
toolbox: Function;
}
interface Refresh {
refresh: Function;
}
declare var addthis: addthis;
@Component({ @Component({
selector: 'addThis', selector: 'addThis',
template: ` template: `
<div id="addThis" class="addthis_inline_share_toolbox_lcx9_8cfy"></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"> <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. Do the share buttons not appear? Please make sure, any blocking addon is disabled, and then reload the page.
</div> </div>
@ -37,7 +31,11 @@ declare var addthis: addthis;
export class AddThisComponent implements OnInit { export class AddThisComponent implements OnInit {
subs = []; subs = [];
showWarning = false; 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() { public ngOnDestroy() {
for (let value of this.subs) { for (let value of this.subs) {
if (value instanceof Subscriber) { if (value instanceof Subscriber) {
@ -46,14 +44,41 @@ export class AddThisComponent implements OnInit {
value(); 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() { ngOnInit() {
this.subs.push(this.route.queryParams.subscribe(data => { this.subs.push(this.route.queryParams.subscribe(data => {
this.showWarning = false; this.showWarning = false;
try { try {
if (!this.document.getElementById('addThisScript') && typeof document !== 'undefined') { if (!this.document.getElementById('addToAnyScript') && typeof document !== 'undefined') {
// console.log(" create script AddThis");
const renderer = this.rendererFactory.createRenderer(this.document, { const renderer = this.rendererFactory.createRenderer(this.document, {
id: '-1', id: '-1',
encapsulation: ViewEncapsulation.None, encapsulation: ViewEncapsulation.None,
@ -65,19 +90,18 @@ export class AddThisComponent implements OnInit {
throw new Error('<head> not found within DOCUMENT.'); throw new Error('<head> not found within DOCUMENT.');
} }
const script = renderer.createElement('script'); const script = renderer.createElement('script');
renderer.setAttribute(script, "id", "addThisScript"); renderer.setAttribute(script, "id", "addToAnyScript");
renderer.setAttribute(script, "src", "https://s7.addthis.com/js/300/addthis_widget.js#pubid=ra-559d24521cd8c080"); renderer.setAttribute(script, "src", "https://static.addtoany.com/menu/page.js");
renderer.setAttribute(script, "type", "text/javascript"); renderer.setAttribute(script, "type", "text/javascript");
renderer.appendChild(head, script); renderer.appendChild(head, script);
} }
if (typeof document !== 'undefined') { if (typeof document !== 'undefined') {
if(typeof addthis !== 'undefined' && addthis.layers && addthis.layers.refresh) { if(typeof a2a !== 'undefined' && this.document.getElementById('addToAny'+(this.url ? ('_'+this.url) : '')) && !this.document.getElementById('addToAny'+(this.url ? ('_'+this.url) : '')).innerText) {
// console.log("Add This: Call Refresh") a2a.init_all();
addthis.layers.refresh();
} }
} }
this.subs.push(setTimeout(() => { 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; this.showWarning = true;
} }
}, 4000)); }, 4000));

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 {HostedByCollectedFrom} from "../../utils/result-preview/result-preview";
import {properties} from "../../../../environments/environment"; 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"; import {RouterHelper} from "../../utils/routerHelper.class";
@Component({ @Component({
selector: 'availableOn', selector: 'availableOn',
template: ` template: `
<div class="uk-margin-small-bottom uk-flex uk-flex-between"> <ng-container *ngIf="availableOn && availableOn.length > 0">
<span *ngIf="viewAll && !lessBtn" class="clickable uk-h6 uk-flex uk-flex-middle" (click)="viewLessClick()"> <div class="uk-flex uk-flex-middle" [ngClass]="isMobile && !(usedBy == 'landing') ? 'uk-margin-left uk-margin-xsmall-bottom' : ''">
<icon class="uk-margin-small-right" name="arrow_back" flex="true" ratio="1.2"></icon> <ng-container *ngIf="availableOn[0].downloadUrl">
{{title}} <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> </span>
<span *ngIf="!viewAll || lessBtn" class="uk-margin-small-bottom uk-flex uk-flex-middle"> <ng-container *ngIf="!(isMobile && usedBy == 'landing')">
<span class="uk-text-light-grey uk-margin-small-right">Download from</span> <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> </span>
<a *ngIf="viewAll && lessBtn" (click)="viewAll = !viewAll; lessBtn=false;" class="view-more-less-link">View less</a> </a>
<a *ngIf="availableOn && availableOn.length > threshold && !viewAll" class="view-more-less-link" <div #dropElement uk-drop="mode: click; pos: bottom-left;"
(click)="viewAllClick();">View all {{availableOn.length}} sources</a> 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> </div>
</ng-container>
<div *ngIf="availableOn" class="download-from uk-margin-small-bottom"> <ng-container *ngIf="(isMobile && usedBy == 'landing')">
<div *ngFor="let instance of availableOn.slice(0, viewAll?availableOn.length:threshold) let i=index" <a class="uk-flex uk-flex-between uk-flex-middle uk-flex-center uk-width-expand uk-button-link" (click)="openAvailableListFsModal()">
class="uk-flex uk-flex-top uk-padding-small uk-margin-small-bottom" <span uk-tooltip="Source">{{sliceString(availableOn[0].downloadNames.join("; "), 20)}}</span>
uk-tooltip [title]="instance.accessRight ? instance.accessRight : 'Not available'"> <span>
<span [class]="'uk-margin-small-right ' + (instance.accessRightIcon == 'lock_open' ? 'uk-text-success' : 'uk-text-meta')" <icon [flex]="true" ratio="1.5" name="arrow_right"></icon>
uk-tooltip [title]="instance.accessRight ? instance.accessRight : 'Not available'"> </span>
<icon [name]="instance.accessRightIcon" flex="true" type="outlined"></icon> </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> </span>
<div class="uk-width-expand uk-padding-small uk-padding-remove-left uk-padding-remove-vertical"> <div class="uk-width-expand uk-padding-small uk-padding-remove-left uk-padding-remove-vertical">
<span class="uk-text-emphasis"> <span class="uk-text-emphasis">
@ -56,36 +85,19 @@ import {RouterHelper} from "../../utils/routerHelper.class";
</div> </div>
</div> </div>
</div> </div>
</div> </ng-template>
<!-- <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>-->
` `
}) })
export class AvailableOnComponent { export class AvailableOnComponent {
@Input() isMobile: boolean = false;
@Input() usedBy: "search" | "landing" = "search";
@Input() prevPath: string = ""; @Input() prevPath: string = "";
@Input() availableOn: HostedByCollectedFrom[]; @Input() availableOn: HostedByCollectedFrom[];
@Input() viewAll: boolean = false; /** @deprecated */
@Output() viewAllClicked = new EventEmitter(); @Output() viewAllClicked = new EventEmitter();
public lessBtn: boolean = false; @ViewChild("dropElement") dropElement: ElementRef;
@ViewChild("availableListFsModal") availableListFsModal: FullScreenModalComponent;
public threshold: number = 1; public threshold: number = 1;
public dataProviderUrl = properties.searchLinkToDataProvider.split('?')[0]; public dataProviderUrl = properties.searchLinkToDataProvider.split('?')[0];
public title: string = "Download from"; public title: string = "Download from";
@ -94,38 +106,38 @@ export class AvailableOnComponent {
constructor() { constructor() {
} }
ngOnInit() {} ngOnInit() {
public removeUnknown(value: string): string {
if (value.toLowerCase() === 'unknown') {
return null;
}
return value;
} }
public getKeys(map) { public getKeys(map) {
return Array.from(map.keys()); 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 { public isUrl(str: string): boolean {
return str.startsWith('http://') || str.startsWith('https://') || str.startsWith('//') || str.startsWith('www.'); 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) { public addEoscPrevInParams(obj) {
if(properties.adminToolsPortalType == "eosc" && this.prevPath) { if(properties.adminToolsPortalType == "eosc" && this.prevPath) {
let splitted: string[] = this.prevPath.split("?"); 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 {EnvProperties} from "../../../utils/properties/env-properties";
import {properties} from "../../../../../environments/environment"; import {properties} from "../../../../../environments/environment";
import {PiwikService} from "../../../utils/piwik/piwik.service"; import {PiwikService} from "../../../utils/piwik/piwik.service";
import {ResultPreview} from "../../../utils/result-preview/result-preview";
declare var Cite: any; declare var Cite: any;
// Based on https://citation.js.org/api/tutorial-getting_started.html browser release // 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; properties:EnvProperties;
public citationText: string; public citationText: string;
public citation: Citation = new Citation(); public citation: Citation = new Citation();
@Input() result: ResultLandingInfo; @Input() result: any;
@Input() id: string; @Input() id: string;
@Input() type: string = "article"; @Input() type: string = "article";
@Input() piwikSiteId; @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 * 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 * @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({ @Component({
selector: 'fos', selector: 'fos',
template: ` template: `
<div class="uk-visible@m">
<div class="uk-text-xsmall" style="color: #EEB204">Beta</div> <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'"> <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()"> <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> <icon class="uk-margin-small-right" name="arrow_back" [flex]="true" [ratio]="1.2"></icon>
<span class="uk-text-nowrap">{{title}}</span> <span class="uk-text-nowrap">{{title}}</span>
</span> </span>
<span *ngIf="!viewAll" class="uk-text-light-grey uk-text-nowrap uk-margin-small-right">{{title}}</span> <span *ngIf="!viewAll" class="uk-text-emphasis uk-text-bolder uk-text-nowrap uk-margin-small-right">
<!-- <a *ngIf="viewAll && lessBtn" (click)="viewAll = !viewAll; lessBtn=false;">View less</a>--> {{title}}
<span *ngIf="subjects && subjects.length > threshold && !viewAll">({{subjects.length}})</span>
</span>
<a *ngIf="properties.adminToolsPortalType == 'eosc' && subjects && subjects.length > threshold && !viewAll" <a *ngIf="properties.adminToolsPortalType == 'eosc' && subjects && subjects.length > threshold && !viewAll"
(click)="viewAllClick();" class="view-more-less-link uk-text-truncate" uk-tooltip="View all"> (click)="viewAllClick();" class="view-more-less-link uk-link uk-link-text uk-text-truncate">
<span class="">View all</span> View all
</a> </a>
<a *ngIf="properties.adminToolsPortalType !== 'eosc' && subjects && subjects.length > threshold && !viewAll" <!-- <a *ngIf="viewAll && lessBtn" (click)="viewAll = !viewAll; lessBtn=false;">View less</a> -->
(click)="viewAllClick();" class="view-more-less-link uk-text-truncate" uk-tooltip="View all & feedback"> <a *ngIf="properties.adminToolsPortalType != 'eosc' && subjects && subjects.length > threshold && !viewAll"
<span class="">View all & feedback</span> (click)="viewAllClick();" class="view-more-less-link uk-link uk-link-text uk-text-truncate">
View all & suggest
</a> </a>
<a *ngIf="properties.adminToolsPortalType !== 'eosc' && (subjects && subjects.length <= threshold || viewAll)" class="uk-link uk-text-truncate" <a *ngIf="properties.adminToolsPortalType != 'eosc' && (subjects && subjects.length <= threshold || viewAll)" class="uk-link uk-link-text uk-text-truncate"
(click)="feedbackClick();">Feedback</a> (click)="suggestClick();">Suggest</a>
</div> </div>
<div class="uk-margin-small-top"> <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"> <div *ngFor="let subject of subjects.slice(0, viewAll?subjects.length:threshold); let i=index" class="uk-text-truncate">
<a *ngIf="properties.adminToolsPortalType !== 'eosc'" <a [routerLink]="properties.searchLinkToResults"
[routerLink]="properties.searchLinkToResults" [queryParams]="{'fos': urlEncodeAndQuote(subject)}"> [queryParams]="{'fos': urlEncodeAndQuote(subject.id)}">
{{subject}} {{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>
<a *ngIf="properties.adminToolsPortalType == 'eosc'" class="custom-external" target="_blank" <a *ngIf="properties.adminToolsPortalType == 'eosc'" class="custom-external" target="_blank"
[href]="'https://explore.openaire.eu'+properties.searchLinkToResults+'?fos='+urlEncodeAndQuote(subject)"> [href]="'https://explore.openaire.eu'+properties.searchLinkToResults+'?fos='+urlEncodeAndQuote(subject.id)">
{{subject}} {{subject.label}}
</a> </a>
</div> </div>
</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>
` `
}) })
export class FosComponent { export class FosComponent {
@Input() subjects: string[]; @Input() subjects: {"id": string, "label": string}[];
@Input() viewAll: boolean = false; @Input() viewAll: boolean = false;
@Output() viewAllClicked = new EventEmitter(); @Output() viewAllClicked = new EventEmitter();
@Output() feedbackClicked = new EventEmitter(); @Output() suggestClicked = new EventEmitter();
public lessBtn: boolean = false; public lessBtn: boolean = false;
public threshold: number = 2; public threshold: number = 2;
public routerHelper: RouterHelper = new RouterHelper(); public routerHelper: RouterHelper = new RouterHelper();
@ -66,8 +96,8 @@ export class FosComponent {
this.viewAllClicked.emit(""); this.viewAllClicked.emit("");
} }
public feedbackClick() { public suggestClick() {
this.feedbackClicked.emit(""); this.suggestClicked.emit('fos');
} }
public urlEncodeAndQuote(str: string): string { public urlEncodeAndQuote(str: string): string {

View File

@ -7,29 +7,53 @@ import {RouterHelper} from "../../utils/routerHelper.class";
@Component({ @Component({
selector: 'fundedBy', selector: 'fundedBy',
template: ` 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()"> <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> <icon class="uk-margin-small-right" name="arrow_back" flex="true" ratio="1.2"></icon>
{{title}} {{title}}
</span> </span>
<span *ngIf="!viewAll || lessBtn" class="uk-text-light-grey">{{title}}</span> <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">View less</a> <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" <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> <div *ngIf="!isMobile">
<span *ngFor="let item of fundedByProjects.slice(0, viewAll?fundedByProjects.length:threshold) let i=index"> <span *ngFor="let item of fundedByProjects.slice(0, viewAll?fundedByProjects.length:threshold) let i=index">
<span class="uk-text-emphasis"> <span class="uk-text-emphasis">
<a class="uk-link uk-link-text"> <a class="uk-link uk-link-text">
<span <ng-container *ngTemplateOutlet="funder; context: {item: item}"></ng-container>
*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> </a>
</span> </span>
<div class="default-dropdown uk-margin-remove-top uk-dropdown" <div class="default-dropdown uk-margin-remove-top uk-dropdown"
uk-dropdown="pos: bottom-left; mode:click"> 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"> <div class="uk-padding-small">
<span>Project</span> <span>Project</span>
<div class="uk-margin-bottom"> <div class="uk-margin-bottom">
@ -65,14 +89,12 @@ import {RouterHelper} from "../../utils/routerHelper.class";
<span *ngIf="item.provenanceAction">{{item.provenanceAction}}</span> <span *ngIf="item.provenanceAction">{{item.provenanceAction}}</span>
</div> </div>
</div> </div>
</div> </ng-template>
<span *ngIf="i < (fundedByProjects.slice(0, viewAll?fundedByProjects.length:threshold).length - 1)">, </span>
</span>
</div>
` `
}) })
export class FundedByComponent { export class FundedByComponent {
@Input() isMobile: boolean = false;
@Input() prevPath: string = ""; @Input() prevPath: string = "";
@Input() fundedByProjects: Project[]; @Input() fundedByProjects: Project[];
@Input() viewAll: boolean = false; @Input() viewAll: boolean = false;

View File

@ -6,68 +6,42 @@ import {AlertModal} from "../../../utils/modal/alert";
@Component({ @Component({
selector: 'landing-header', selector: 'landing-header',
template: ` template: `
<div class="title-section" [class.uk-margin-bottom]="!isSticky" [ngClass]="titleClass"> <div class="title-section" [class.uk-margin-small-bottom]="!isSticky" [ngClass]="titleClass">
<div class="uk-text-small"> <div class="uk-margin-small-bottom">
<span *ngIf="entityType" class="uk-text-capitalize uk-text-small"> <showTitle [isSticky]=isSticky [titleName]="title" classNames="uk-margin-remove-bottom"></showTitle>
{{entityType}} <div *ngIf="subTitle && !isSticky">
</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> <span class="uk-text-meta uk-text-small" [innerHTML]="subTitle"></span>
</div> </div>
</div> </div>
<div *ngIf="authors"> <div *ngIf="!isSticky" class="uk-margin-bottom">
<showAuthors [authorsLimit]="authorLimit" [modal]="modal" [showAll]="showAllAuthors" [authors]="authors" [isSticky]="isSticky"></showAuthors> <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>
</div>` <div *ngIf="authors">
<showAuthors [authorsLimit]="authorLimit" [modal]="modal" [showAll]="showAllAuthors" [authors]="authors"
[isSticky]="isSticky" [isMobile]="isMobile"></showAuthors>
</div>
</div>
`
}) })
export class LandingHeaderComponent { export class LandingHeaderComponent {
@Input() isMobile: boolean = false;
@Input() entityType: string; @Input() entityType: string;
@Input() properties: EnvProperties; @Input() properties: EnvProperties;
@Input() types: string[]; @Input() types: string[];
@Input() startDate: number; // project landing @Input() startDate: number; // project landing
@Input() endDate: number; // project landing @Input() endDate: number; // project landing
@Input() currentDate: number; // project landing
@Input() status: string; // project landing @Input() status: string; // project landing
@Input() year: string; @Input() openAccessMandatePublications: boolean // project landing
@Input() openAccessMandateDatasets: boolean // project landing
@Input() date: Date;
@Input() embargoEndDate: Date; @Input() embargoEndDate: Date;
@Input() title: string; @Input() title: string;
@Input() subTitle: string; @Input() subTitle: string;
@ -77,27 +51,14 @@ export class LandingHeaderComponent {
@Input() underCuration: boolean = false; @Input() underCuration: boolean = false;
@Input() modal: AlertModal; @Input() modal: AlertModal;
@Input() titleClass: string = null; @Input() titleClass: string = null;
@Input() isTitleH1:boolean =true;
@Input() isSticky: boolean = false; @Input() isSticky: boolean = false;
public removeUnknown(array: string[], type: boolean = false): string[] { @Input() publisher; // showPublisher component
if (type) { @Input() journal; // showPublisher component
return this.removeDuplicates(array).filter(value => value.toLowerCase() !== 'unknown'); @Input() languages;
} else { @Input() programmingLanguages;
return array.filter(value => value.toLowerCase() !== 'unknown'); @Input() compatibility; // data provider landing
} @Input() aggregationStatus; // data provider landing
} @Input() thematic: boolean; // data provider landing
@Input() type; // data provider landing
public removeDuplicates(array: string[]): string[] { @Input() prevPath: 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;
}
} }

View File

@ -3,9 +3,13 @@ import {LandingHeaderComponent} from "./landing-header.component";
import {CommonModule} from "@angular/common"; import {CommonModule} from "@angular/common";
import {LandingModule} from "../landing.module"; import {LandingModule} from "../landing.module";
import {ShowAuthorsModule} from "../../../utils/authors/showAuthors.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({ @NgModule({
imports: [CommonModule, LandingModule, ShowAuthorsModule], imports: [CommonModule, LandingModule, ShowAuthorsModule, IconsModule, ShowPublisherModule, RouterModule, ResultLandingUtilsModule],
declarations: [LandingHeaderComponent], declarations: [LandingHeaderComponent],
exports: [LandingHeaderComponent] exports: [LandingHeaderComponent]
}) })

View File

@ -1,5 +1,5 @@
import {HostedByCollectedFrom, Journal, Project, RelationResult} from "../../utils/result-preview/result-preview"; import {HostedByCollectedFrom, Project, RelationResult} from "../../utils/result-preview/result-preview";
import {Context, Reference} from "../../utils/entities/resultLandingInfo"; import {Context, Measure, Metric, Reference} from "../../utils/entities/resultLandingInfo";
import {Injectable} from '@angular/core'; import {Injectable} from '@angular/core';
import {properties} from "../../../../environments/environment"; import {properties} from "../../../../environments/environment";
import {StringUtils} from "../../utils/string-utils.class"; 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::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'} {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; public notebookInSubjects: boolean = false;
private notebookKeyword: string = "eosc jupyter notebook"; private notebookKeyword: string = "eosc jupyter notebook";
private notebook_label: string = "EOSC"; private notebook_label: string = "EOSC";
private notebook_value: string = "EOSC Jupyter Notebook"; private notebook_value: string = "EOSC Jupyter Notebook";
public open = 'lock_open'; public open = 'open_access';
public closed = 'lock'; public closed = 'closed_access';
public unknown = 'question_mark'; public unknown = 'unknown_access';
private instanceWithDoiExists: boolean = false; private instanceWithDoiExists: boolean = false;
@ -156,7 +155,7 @@ export class ParsingFunctions {
// publication & dataset landing : for downloadFrom // publication & dataset landing : for downloadFrom
addPublisherToHostedBy_collectedFrom(hostedBy_collectedFrom: HostedByCollectedFrom[], addPublisherToHostedBy_collectedFrom(hostedBy_collectedFrom: HostedByCollectedFrom[],
publisher: string, journal: Journal, publisher: string, journal: string,
identifiers: Map<string, string[]>/*, title: { "name": string, "url": string, "accessMode": string}*/) { identifiers: Map<string, string[]>/*, title: { "name": string, "url": string, "accessMode": string}*/) {
if (!this.instanceWithDoiExists && publisher && identifiers != null && identifiers.has('doi')) { if (!this.instanceWithDoiExists && publisher && identifiers != null && identifiers.has('doi')) {
if (hostedBy_collectedFrom == null) { if (hostedBy_collectedFrom == null) {
@ -172,13 +171,13 @@ export class ParsingFunctions {
accessRightIcon: "" accessRightIcon: ""
}; };
if (journal && journal.journal) { if (journal) {
available.downloadNames.push(publisher + "/ " + journal['journal']); available.downloadNames.push(publisher + "/ " + journal['journal']);
} else { } else {
available.downloadNames.push(publisher); available.downloadNames.push(publisher);
} }
available.downloadUrl = properties.doiURL + identifiers.get("doi")[0];; available.downloadUrl = properties.doiURL + identifiers.get("doi")[0];
available.accessRightIcon = this.unknown; available.accessRightIcon = this.unknown;
/* /*
if(title != undefined && title['url'] == "") { if(title != undefined && title['url'] == "") {
@ -340,9 +339,11 @@ export class ParsingFunctions {
if (available.accessRight) { if (available.accessRight) {
if (available.accessRight.toLowerCase().indexOf('open') !== -1) { if (available.accessRight.toLowerCase().indexOf('open') !== -1) {
available.accessRightIcon = this.open; 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; available.accessRightIcon = this.unknown;
} else { }
else {
available.accessRightIcon = this.closed; available.accessRightIcon = this.closed;
} }
} else { } else {
@ -356,6 +357,42 @@ export class ParsingFunctions {
hostedBy_collectedFrom.push(available); 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 // publication & dataset landing : for downloadFrom and publishedIn
changeBestAccessMode(currentAccessMode: string, accessMode: any): boolean { changeBestAccessMode(currentAccessMode: string, accessMode: any): boolean {
if (!accessMode) { if (!accessMode) {
@ -658,9 +695,11 @@ export class ParsingFunctions {
} }
} }
} else if (category.label || (numOfCategories == 0 && z == (length2 - 1))) { } else if (category.label || (numOfCategories == 0 && z == (length2 - 1))) {
contexts[position] = {"labelContext": "", "idContext": "", contexts[position] = {
"labelContext": "", "idContext": "",
"labelCategory": "", "idCategory": "", "labelCategory": "", "idCategory": "",
"labelConcept": "", "idConcept": ""}; "labelConcept": "", "idConcept": ""
};
contexts[position]['labelContext'] = context.label; contexts[position]['labelContext'] = context.label;
contexts[position]['idContext'] = context.id; contexts[position]['idContext'] = context.id;
contexts[position]['labelCategory'] = category.label ? category.label : null; contexts[position]['labelCategory'] = category.label ? category.label : null;
@ -672,9 +711,11 @@ export class ParsingFunctions {
} }
} }
} else { } else {
contexts[position] = {"labelContext": "", "idContext": "", contexts[position] = {
"labelContext": "", "idContext": "",
"labelCategory": "", "idCategory": "", "labelCategory": "", "idCategory": "",
"labelConcept": "", "idConcept": ""}; "labelConcept": "", "idConcept": ""
};
contexts[position]['labelContext'] = context.label; contexts[position]['labelContext'] = context.label;
contexts[position]['idContext'] = context.id; contexts[position]['idContext'] = context.id;
contexts[position]['labelCategory'] = null; contexts[position]['labelCategory'] = null;
@ -688,11 +729,15 @@ export class ParsingFunctions {
} }
return contexts; return contexts;
} }
public static getEnermapsConceptId(contexts: any): string { public static getEnermapsConceptId(contexts: any): string {
let enermapsconcepts = contexts.filter(c=> {return c.idCategory == "enermaps::selection" && c.idConcept}); 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 enermapsconcepts && enermapsconcepts.length > 0 ? enermapsconcepts[0].idConcept.split("enermaps::selection::")[1] : null;
// return "hotmaps_heat_tot_curr_density" // return "hotmaps_heat_tot_curr_density"
} }
parseTypes(types: string[], uniqueTypes: Set<string>, instance: any) { parseTypes(types: string[], uniqueTypes: Set<string>, instance: any) {
if (instance && instance.hasOwnProperty("instancetype") && instance['instancetype'].classname) { if (instance && instance.hasOwnProperty("instancetype") && instance['instancetype'].classname) {
if (!uniqueTypes.has(instance['instancetype'].classname)) { if (!uniqueTypes.has(instance['instancetype'].classname)) {
@ -727,7 +772,7 @@ export class ParsingFunctions {
countries.push(_countries.classname); countries.push(_countries.classname);
} }
} else { } 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) { if (_countries[i].classname != "Undetermined" && _countries[i].classname) {
countries.push(_countries[i].classname); countries.push(_countries[i].classname);
} }
@ -775,6 +820,7 @@ export class ParsingFunctions {
}); });
return references; return references;
} }
static parseRelCanonicalId(record, type) { static parseRelCanonicalId(record, type) {
try { try {
if (record["result"]["metadata"]["oaf:entity"][("oaf:" + type)]["children"] && record["result"]["metadata"]["oaf:entity"][("oaf:" + type)]["children"][type]) { if (record["result"]["metadata"]["oaf:entity"][("oaf:" + type)]["children"] && record["result"]["metadata"]["oaf:entity"][("oaf:" + type)]["children"][type]) {
@ -798,7 +844,8 @@ export class ParsingFunctions {
} }
try { try {
abstracts = abstracts.map(x => StringUtils.HTMLToString(x)); abstracts = abstracts.map(x => StringUtils.HTMLToString(x));
} catch (e) {} } catch (e) {
}
abstracts = abstracts.sort((a, b) => b.length - a.length); abstracts = abstracts.sort((a, b) => b.length - a.length);
if (stripHTML) { if (stripHTML) {
return abstracts.join(' '); return abstracts.join(' ');
@ -806,4 +853,90 @@ export class ParsingFunctions {
return abstracts.length > 0 ? ('<p>' + abstracts.join('</p> <p>') + '</p>') : abstracts.join(' '); 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]', selector: 'relatedTo, [relatedTo]',
template: ` template: `
<ng-container *ngIf="communities && communities.length > 0"> <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()"> <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> <icon class="uk-margin-small-right" name="arrow_back" flex="true" ratio="1.2"></icon>
{{title}} {{title}}
</span> </span>
<span *ngIf="!viewAll || lessBtn" class="uk-text-light-grey">{{title}}</span> <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">View less</a> <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" <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>
<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 --> <!-- If there are any communities with dashboard -->
<a *ngIf="community.link" href="{{community.link}}" target="_blank" [attr.uk-tooltip]="community.labelContext" class="custom-external"> <a *ngIf="community.link" href="{{community.link}}" target="_blank" [attr.uk-tooltip]="community.labelContext" class="custom-external">
{{community.labelContext}} {{community.labelContext}}
@ -44,6 +45,7 @@ import {OpenaireEntities} from "../../utils/properties/searchFields";
}) })
export class RelatedToComponent implements OnInit { export class RelatedToComponent implements OnInit {
@Input() mobileView: boolean = false;
@Input() contexts: Context[]; @Input() contexts: Context[];
@Input() viewAll: boolean = false; @Input() viewAll: boolean = false;
@Output() viewAllClicked = new EventEmitter(); @Output() viewAllClicked = new EventEmitter();

View File

@ -16,23 +16,34 @@ import {FosComponent} from "./fos.component";
import {SdgComponent} from "./sdg.component"; import {SdgComponent} from "./sdg.component";
import {IconsModule} from "../../utils/icons/icons.module"; import {IconsModule} from "../../utils/icons/icons.module";
import {AlertModalModule} from "../../utils/modal/alertModal.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({ @NgModule({
imports: [ imports: [
CommonModule, FormsModule, RouterModule, PagingModule, ShowPublisherModule, IconsModule, AlertModalModule CommonModule, FormsModule, RouterModule, PagingModule, ShowPublisherModule, IconsModule, AlertModalModule,
SearchInputModule, FullScreenModalModule
], ],
declarations: [ declarations: [
ShowIdentifiersComponent,ShowSubjectsComponent, ShowIdentifiersComponent,ShowSubjectsComponent,
FundedByComponent,AvailableOnComponent,TabTableComponent, FundedByComponent,AvailableOnComponent,TabTableComponent,
RelatedToComponent, FosComponent, SdgComponent RelatedToComponent, FosComponent, SdgComponent,
EntityMetadataComponent
], ],
providers:[ providers:[
], ],
exports: [ exports: [
ShowIdentifiersComponent, ShowSubjectsComponent, ShowIdentifiersComponent, ShowSubjectsComponent,
FundedByComponent,AvailableOnComponent, TabTableComponent, ShowPublisherComponent, 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,6 +6,7 @@ import {StringUtils} from "../../utils/string-utils.class";
@Component({ @Component({
selector: 'sdg', selector: 'sdg',
template: ` template: `
<div class="uk-visible@m">
<div class="uk-text-xsmall" style="color: #EEB204">Beta</div> <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'"> <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" <span *ngIf="viewAll" class="clickable uk-h6 uk-flex uk-flex-middle uk-margin-small-right uk-margin-remove-bottom"
@ -13,24 +14,26 @@ import {StringUtils} from "../../utils/string-utils.class";
<icon class="uk-margin-small-right" name="arrow_back" flex="true" ratio="1.2"></icon> <icon class="uk-margin-small-right" name="arrow_back" flex="true" ratio="1.2"></icon>
<span uk-tooltip="Sustainable Development Goals">{{title}}</span> <span uk-tooltip="Sustainable Development Goals">{{title}}</span>
</span> </span>
<span *ngIf="!viewAll" class="uk-text-light-grey uk-text-nowrap uk-margin-small-right" uk-tooltip="Sustainable Development Goals">{{title}}</span> <span *ngIf="!viewAll" class="uk-text-emphasis uk-text-bolder uk-text-nowrap uk-margin-small-right" uk-tooltip="Sustainable Development Goals">
<!-- <a *ngIf="viewAll && lessBtn" (click)="viewAll = !viewAll; lessBtn=false;">View less</a>--> {{title}}
<span *ngIf="subjects && subjects.length > threshold && !viewAll">({{subjects.length}})</span>
</span>
<a *ngIf="properties.adminToolsPortalType == 'eosc' && subjects && subjects.length > threshold && !viewAll" <a *ngIf="properties.adminToolsPortalType == 'eosc' && subjects && subjects.length > threshold && !viewAll"
(click)="viewAllClick();" class="view-more-less-link uk-text-truncate" uk-tooltip="View all"> (click)="viewAllClick();" class="view-more-less-link uk-link uk-link-text uk-text-truncate">
View all</a> View all</a>
<a *ngIf="properties.adminToolsPortalType !== 'eosc' && subjects && subjects.length > threshold && !viewAll" <!-- <a *ngIf="viewAll && lessBtn" (click)="viewAll = !viewAll; lessBtn=false;">View less</a> -->
(click)="viewAllClick();" class="view-more-less-link uk-text-truncate" uk-tooltip="View all & feedback"> <a *ngIf="properties.adminToolsPortalType != 'eosc' && subjects && subjects.length > threshold && !viewAll"
View all & feedback</a> (click)="viewAllClick();" class="view-more-less-link uk-link uk-link-text uk-text-truncate">
<a *ngIf="properties.adminToolsPortalType !== 'eosc' && (subjects && subjects.length <= threshold || viewAll)" class="uk-link uk-text-truncate" View all & suggest</a>
(click)="feedbackClick();">Feedback</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>
<div class="uk-margin-small-bottom uk-flex"> <div class="uk-margin-small-bottom uk-flex">
<img src="assets/common-assets/common/The_Global_Goals_Icon_Color.svg" <img src="assets/common-assets/common/The_Global_Goals_Icon_Color.svg"
loading="lazy" alt="sdg_colors" style="width:27px; height:27px"> loading="lazy" alt="sdg_colors" style="width:27px; height:27px">
<div class="uk-margin-small-left"> <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"> <div *ngFor="let subject of subjects.slice(0, viewAll?subjects.length:threshold); let i=index" class="uk-text-truncate">
<a *ngIf="properties.adminToolsPortalType !== 'eosc'" <a *ngIf="properties.adminToolsPortalType != 'eosc'"
[routerLink]=" properties.searchLinkToResults" [queryParams]="{'sdg': urlEncodeAndQuote(subject)}"> [routerLink]=" properties.searchLinkToResults" [queryParams]="{'sdg': urlEncodeAndQuote(subject)}">
{{subject}} {{subject}}
</a> </a>
@ -41,6 +44,30 @@ import {StringUtils} from "../../utils/string-utils.class";
</div> </div>
</div> </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>
` `
}) })
@ -48,9 +75,9 @@ export class SdgComponent {
@Input() subjects: string[]; @Input() subjects: string[];
@Input() viewAll: boolean = false; @Input() viewAll: boolean = false;
@Output() viewAllClicked = new EventEmitter(); @Output() viewAllClicked = new EventEmitter();
@Output() feedbackClicked = new EventEmitter(); @Output() suggestClicked = new EventEmitter();
public lessBtn: boolean = false; public lessBtn: boolean = false;
public threshold: number = 4; public threshold: number = 2;
public routerHelper: RouterHelper = new RouterHelper(); public routerHelper: RouterHelper = new RouterHelper();
public properties = properties; public properties = properties;
public title: string = "SDGs"; public title: string = "SDGs";
@ -70,8 +97,8 @@ export class SdgComponent {
this.viewAllClicked.emit(""); this.viewAllClicked.emit("");
} }
public feedbackClick() { public suggestClick() {
this.feedbackClicked.emit(""); this.suggestClicked.emit('sdg');
} }
public urlEncodeAndQuote(str: string): string { 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> <a (click)="openIdentifiersModal()" class="view-more-less-link">View all</a>
</div> </div>
<modal-alert #identifiersModal> <modal-alert *ngIf="!isMobile" #identifiersModal>
<div class="uk-text-small"> <div class="uk-text-small">
<ng-container *ngTemplateOutlet="identifiers_template; context: { modal: true}"></ng-container> <ng-container *ngTemplateOutlet="identifiers_template; context: { modal: true}"></ng-container>
</div> </div>
</modal-alert> </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 { export class ShowIdentifiersComponent implements AfterViewInit {
@Input() isMobile: boolean = false;
@Input() identifiers: Map<string, string[]>; @Input() identifiers: Map<string, string[]>;
@Input() showViewAll: boolean = false; @Input() showViewAll: boolean = false;
large: Map<string, boolean> = new Map<string, boolean>(); large: Map<string, boolean> = new Map<string, boolean>();
@ -121,9 +128,15 @@ export class ShowIdentifiersComponent implements AfterViewInit {
} }
public openIdentifiersModal() { public openIdentifiersModal() {
if(this.isMobile) {
this.identifiersModal.okButton = false;
this.identifiersModal.title = "Persistent Identifiers";
this.identifiersModal.open();
} else {
this.identifiersModal.cancelButton = false; this.identifiersModal.cancelButton = false;
this.identifiersModal.okButton = false; this.identifiersModal.okButton = false;
this.identifiersModal.alertTitle = "Persistent Identifiers"; this.identifiersModal.alertTitle = "Persistent Identifiers";
this.identifiersModal.open(); this.identifiersModal.open();
} }
} }
}

View File

@ -4,15 +4,11 @@ import {EnvProperties} from "../../utils/properties/env-properties";
@Component({ @Component({
selector: 'showPublisher, [showPublisher]', selector: 'showPublisher, [showPublisher]',
template: ` template: `
<div *ngIf="publishDate || journal && (journal['journal'] || journal['issn'] || journal['lissn'] <ng-container *ngIf="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'])"> || journal['volume'] || journal['eissn'] || journal['issue'])">
<span class="uk-text-meta">Journal: </span> <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['journal']}}</span>
<span *ngIf="journal['journal'] && (journal['volume'] || journal['issue'])">, </span> <span *ngIf="journal['journal'] && (journal['volume'] || journal['issue'])">, </span>
<ng-container *ngIf="journal['volume']"> <ng-container *ngIf="journal['volume']">
@ -67,14 +63,15 @@ import {EnvProperties} from "../../utils/properties/env-properties";
</span> </span>
<span *ngIf=" journal['journal'] && (journal['issn'] || journal['eissn'] || journal['lissn'])">)</span> <span *ngIf=" journal['journal'] && (journal['issn'] || journal['eissn'] || journal['lissn'])">)</span>
</span> </span>
</div> </ng-container>
<div *ngIf="publisher" class="uk-text-small uk-margin-small-top"> <span *ngIf="publisher" class="uk-margin-xsmall-left uk-margin-xsmall-right bullet"></span>
<span class="uk-text-meta">Publisher: </span> {{publisher}} </ng-container>
</div> <ng-container *ngIf="publisher">
<span [attr.uk-tooltip]="'cls: uk-active'" [title]="'Publisher'">{{publisher}}</span>
</ng-container>
` `
}) })
export class ShowPublisherComponent { export class ShowPublisherComponent {
@Input() publishDate: Date;
@Input() publisher; @Input() publisher;
@Input() journal; @Input() journal;
//@Input() sherpaUrl = 'http://www.sherpa.ac.uk/romeo/search.php?issn='; //@Input() sherpaUrl = 'http://www.sherpa.ac.uk/romeo/search.php?issn=';

View File

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

View File

@ -1,9 +1,9 @@
import { import {
ChangeDetectorRef, ChangeDetectorRef,
Component, Component,
ElementRef, ElementRef, EventEmitter,
HostListener, HostListener,
Input, Input, Output,
QueryList, QueryList,
ViewChild, ViewChild,
ViewChildren ViewChildren
@ -13,24 +13,24 @@ import {properties} from "../../../../environments/environment";
@Component({ @Component({
selector: 'showSubjects', selector: 'showSubjects',
template: ` template: `
<ng-container *ngIf="(classifiedSubjects && classifiedSubjects.size > 0) || (eoscSubjects && eoscSubjects.length > 0)"> <ng-container *ngIf="!viewAllSubjects && ((classifiedSubjects && classifiedSubjects.size > 0) || (eoscSubjects && eoscSubjects.length > 0))">
<div class="uk-text-meta"> <div *ngIf="!viewAllClassifiedSubjects" class="uk-text-meta">
Subjects by Vocabulary Subjects by Vocabulary
</div> </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> <ng-container *ngIf="eoscSubjects && eoscSubjects.length > 0"><ng-container *ngTemplateOutlet="eosc_subjects_template"></ng-container></ng-container>
<div *ngIf="isClassifiedLarge" class="uk-text-right"> <div *ngIf="isClassifiedLarge && !viewAllClassifiedSubjects" class="uk-text-right">
<a (click)="openSubjectsByVocabularyModal()" class="view-more-less-link">View all</a> <a (click)="viewAllSubjectsByVocabularyClicked()" class="view-more-less-link">View all</a>
</div> </div>
</ng-container> </ng-container>
<ng-container *ngIf="(subjects && subjects.length > 0) || (otherSubjects && otherSubjects.size > 0)"> <ng-container *ngIf="!viewAllClassifiedSubjects && ((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"> <div *ngIf="!viewAllSubjects" class="uk-text-meta uk-margin-small-bottom" [class.uk-margin-medium-top]="classifiedSubjects && classifiedSubjects.size > 0">
Subjects Keywords
</div> </div>
<ng-container *ngTemplateOutlet="subjects_template; context: {customClasses: 'multi-line-ellipsis lines-2', id: 'content'}"></ng-container> <ng-container *ngTemplateOutlet="subjects_template; context: {customClasses: (isMobile && viewAllSubjects) ? '' : 'multi-line-ellipsis lines-2', id: 'content'}"></ng-container>
<div *ngIf="isLarge" class="uk-text-right uk-margin-small-top"> <div *ngIf="isLarge && !viewAllSubjects" class="uk-text-right uk-margin-small-top">
<a (click)="openSubjectsModal()" class="view-more-less-link">View all</a> <a (click)="viewAllSubjectsClicked()" class="view-more-less-link">View all</a>
</div> </div>
</ng-container> </ng-container>
@ -49,7 +49,7 @@ import {properties} from "../../../../environments/environment";
</div> </div>
</ng-template> </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"> <div class="uk-text-small">
<ng-container *ngTemplateOutlet="subjects_template"></ng-container> <ng-container *ngTemplateOutlet="subjects_template"></ng-container>
</div> </div>
@ -94,7 +94,7 @@ import {properties} from "../../../../environments/environment";
</div> </div>
</ng-template> </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"> <div class="uk-text-small">
<ng-container *ngTemplateOutlet="subjects_by_vocabulary_template"></ng-container> <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> <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 { export class ShowSubjectsComponent {
@Input() isMobile: boolean = false;
@Input() subjects: string[]; @Input() subjects: string[];
@Input() otherSubjects: Map<string, string[]>; @Input() otherSubjects: Map<string, string[]>;
@Input() classifiedSubjects: Map<string, string[]>; @Input() classifiedSubjects: Map<string, string[]>;
@Input() eoscSubjects: any[]; @Input() eoscSubjects: any[];
isLarge: boolean = false; isLarge: boolean = false;
isClassifiedLarge: boolean = false; isClassifiedLarge: boolean = false;
@Input() viewAllSubjects: boolean = false;
@Input() viewAllClassifiedSubjects: boolean = false;
@Output() viewAllClicked = new EventEmitter();
properties = properties; properties = properties;
specialSubjects = []; specialSubjects = [];
@ViewChildren("content", { read: ElementRef }) content: QueryList<ElementRef>; @ViewChildren("content", { read: ElementRef }) content: QueryList<ElementRef>;
@ -206,4 +210,28 @@ export class ShowSubjectsComponent {
this.subjectsByVocabularyModal.alertTitle = "Subjects by Vocabulary"; this.subjectsByVocabularyModal.alertTitle = "Subjects by Vocabulary";
this.subjectsByVocabularyModal.open(); 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,12 +1,12 @@
import {Component, Input} from '@angular/core'; import {Component, ElementRef, Input, ViewChild} from '@angular/core';
import {ActivatedRoute} from '@angular/router';
@Component({ @Component({
selector: 'showTitle', selector: 'showTitle',
template: ` template: `
<h1 [ngClass]="classNames" class="uk-h5"> <h1 [ngClass]="classNames" class="uk-h6">
<ng-container *ngTemplateOutlet="_title;"></ng-container> <ng-container *ngTemplateOutlet="_title;"></ng-container>
</h1> </h1>
<ng-template #_title> <ng-template #_title>
<div *ngIf="title != undefined" class="landingTitle uk-text-break"> <div *ngIf="title != undefined" class="landingTitle uk-text-break">
<span *ngIf="title['url'] != undefined && title['url'] != null && title['url'] != ''" <span *ngIf="title['url'] != undefined && title['url'] != null && title['url'] != ''"
@ -25,20 +25,19 @@ import {ActivatedRoute} from '@angular/router';
[innerHTML]="title['name']"> [innerHTML]="title['name']">
</span> </span>
<span *ngIf="(title['name'] == undefined || title['name'] == '') && <span *ngIf="(title['name'] == undefined || title['name'] == '') &&
(title['url'] == undefined || title['url'] == null || title['url'] == '')" (title['url'] == undefined || title['url'] == null || title['url'] == '')">
>
[no title available] [no title available]
</span> </span>
</div> </div>
<div *ngIf="titleName" class="uk-text-break"> <div *ngIf="titleName" #titleDiv class="uk-text-break multi-line-ellipsis" [ngClass]="isSticky ? 'lines-1' : 'lines-5'">
<span [innerHTML]="titleName"></span> <span [innerHTML]="titleName" [attr.uk-tooltip]="showTitleTooltip ? 'cls: uk-active uk-width-large' : 'cls: uk-invisible'"
[title]="titleName"></span>
</div> </div>
<div *ngIf="!titleName && !title"> <div *ngIf="!titleName && !title">
<span>No title available</span> <span>No title available</span>
</div> </div>
</ng-template> </ng-template>
` `
}) })
export class ShowTitleComponent { export class ShowTitleComponent {
@ -46,7 +45,12 @@ export class ShowTitleComponent {
@Input() title: { [key: string]: string }; @Input() title: { [key: string]: string };
@Input() iconClass:string; @Input() iconClass:string;
@Input() classNames: string = ""; @Input() classNames: string = "";
@Input() isSticky: boolean = false;
@ViewChild("titleDiv") titleDiv: ElementRef;
constructor () {} 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"> <ul class="uk-list uk-list-divider uk-margin">
<li *ngFor="let result of results.slice((page-1)*pageSize, page*pageSize)"> <li *ngFor="let result of results.slice((page-1)*pageSize, page*pageSize)">
<result-preview [modal]="modal" [properties]="properties" [hasLink]="false" [result]="getResultPreview(result)" <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> </li>
</ul> </ul>
<no-load-paging *ngIf="results.length > pageSize" [type]="type" <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"> <!-- Desktop view -->
<div class="tm-main"> <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 class="organization">
<div *ngIf="properties.adminToolsPortalType == 'eosc'" class="eosc-explore-back-search-bar"> <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"> <div class="uk-light uk-container uk-container-large uk-padding-small uk-height-1-1">
@ -13,13 +14,12 @@
</div> </div>
<div *ngIf="!showFeedback" class="uk-grid uk-margin-remove-left" uk-grid> <div *ngIf="!showFeedback" class="uk-grid uk-margin-remove-left" uk-grid>
<!-- left column --> <!-- 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" <div class="uk-flex uk-flex-column uk-flex-right uk-sticky"
uk-sticky="bottom: true" [attr.offset]="offset"> uk-sticky="bottom: true" [attr.offset]="offset">
<div class="uk-margin-large-bottom uk-align-center"> <div class="uk-margin-large-bottom uk-align-center">
<div class="uk-text-meta uk-text-uppercase">Actions</div> <div class="uk-text-meta uk-text-uppercase">Actions</div>
<ul class="uk-list"> <ul class="uk-list">
<!-- Share -->
<li class="uk-text-center"> <li class="uk-text-center">
<a (click)="openAddThisModal()" [title]="'Share this '+openaireEntities.ORGANIZATION+' in your social networks'" <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'"> [attr.uk-tooltip]="'pos: right; cls: uk-active uk-text-small uk-padding-small'">
@ -28,7 +28,6 @@
</span> </span>
</a> </a>
</li> </li>
<!-- Download -->
<li class="uk-text-center" <li class="uk-text-center"
[title]="'Download reports'" [title]="'Download reports'"
[attr.uk-tooltip]="'pos: right; cls: uk-active uk-text-small uk-padding-small'"> [attr.uk-tooltip]="'pos: right; cls: uk-active uk-text-small uk-padding-small'">
@ -41,20 +40,14 @@
</ul> </ul>
</div> </div>
</div> </div>
</div> </div> -->
<!-- center/right column --> <!-- center/right column -->
<div class="uk-width-expand uk-padding-remove uk-background-default"> <div id="landing-center-content" 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>
<!-- Graph and feedback --> <!-- Graph and feedback -->
<ng-template #graph_and_feedback_template> <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--> <!-- Last Index Info-->
<a href="https://graph.openaire.eu" target="_blank" class="uk-width-1-1 uk-width-auto@l"> <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;"> <img src="assets/common-assets/openaire-badge-1.png" alt="Powered by OpenAIRE graph" style="height: 15px;">
@ -70,12 +63,54 @@
</div> </div>
</div> </div>
</ng-template> </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"
<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"> uk-sticky="bottom: true;" [attr.offset]="graph_offset">
<ng-container *ngTemplateOutlet="graph_and_feedback_template"></ng-container> <ng-container *ngTemplateOutlet="graph_and_feedback_template"></ng-container>
</div> </div>
<div class="uk-margin-large-left uk-margin-large-right" [style]="'margin-bottom: '+graph_height+'px'"> <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 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>
</div>
</div>
<div class="uk-margin-left uk-margin-right" [style]="'margin-bottom: '+graph_height+'px'">
<ng-container *ngIf="organizationInfo"> <ng-container *ngIf="organizationInfo">
<!-- Main content --> <!-- Main content -->
<div [attr.style]="'margin-top: '+(graph_height? 'calc(40px + 20px - '+graph_height+'px)': '40px')"> <div [attr.style]="'margin-top: '+(graph_height? 'calc(40px + 20px - '+graph_height+'px)': '40px')">
@ -107,17 +142,17 @@
<helper *ngIf="pageContents && pageContents['top'] && pageContents['top'].length > 0" <helper *ngIf="pageContents && pageContents['top'] && pageContents['top'].length > 0"
[texts]="pageContents['top']"></helper> [texts]="pageContents['top']"></helper>
<!-- Versions --> <!-- Versions -->
<span *ngIf="organizationInfo.deletedByInferenceIds" class="uk-text-primary uk-flex uk-flex-middle"> <!-- <span *ngIf="organizationInfo.deletedByInferenceIds" class="uk-text-primary uk-flex uk-flex-middle">
<icon flex="true" ratio="0.8" name="auto_awesome_motion"></icon> <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"> <a (click)="openDeletedByInference()" class="uk-text-primary uk-text-small uk-margin-small-left">
View all {{organizationInfo.deletedByInferenceIds.length}} versions View all {{organizationInfo.deletedByInferenceIds.length}} versions
</a> </a>
</span> </span> -->
<!-- Landing header --> <!-- Landing header -->
<landing-header [properties]="properties" [title]="organizationInfo.title.name" <landing-header [properties]="properties" [title]="organizationInfo.title.name"
[subTitle]="(organizationInfo.name [subTitle]="(organizationInfo.name
&& organizationInfo.title.name !== organizationInfo.name)?organizationInfo.name:null" && organizationInfo.title.name !== organizationInfo.name)?organizationInfo.name:null"
[entityType]="'organization'"> [entityType]="'organization'" [prevPath]="prevPath">
</landing-header> </landing-header>
<!-- Basic info --> <!-- Basic info -->
<div class="uk-text-small"> <div class="uk-text-small">
@ -139,11 +174,9 @@
uk-sticky="bottom: true; media: @m" [attr.offset]="offset"> uk-sticky="bottom: true; media: @m" [attr.offset]="offset">
<div class="uk-padding uk-padding-remove-horizontal uk-padding-remove-bottom"> <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>--> <!-- <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" <landing-header [ngClass]="stickyHeader ? 'uk-visible@m' : 'uk-invisible'"
[properties]="properties" [title]="organizationInfo.title.name" [properties]="properties" [title]="organizationInfo.title.name"
[subTitle]="(organizationInfo.name [entityType]="'organization'" isSticky="true" [prevPath]="prevPath">
&& organizationInfo.title.name !== organizationInfo.name)?organizationInfo.name:null"
[entityType]="'organization'" isSticky="true">
</landing-header> </landing-header>
<my-tabs (selectedActiveTab)="onSelectActiveTab($event)" [offsetForSticky]="offset" [(isSticky)]="stickyHeader"> <my-tabs (selectedActiveTab)="onSelectActiveTab($event)" [offsetForSticky]="offset" [(isSticky)]="stickyHeader">
<my-tab [active]="true" [tabTitle]="'Funding / ' +openaireEntities.PROJECTS" [tabId]="'projects'" <my-tab [active]="true" [tabTitle]="'Funding / ' +openaireEntities.PROJECTS" [tabId]="'projects'"
@ -233,6 +266,7 @@
</div> </div>
</div> </div>
</div> </div>
</div>
<!-- Feedback --> <!-- Feedback -->
<feedback *ngIf="organizationInfo && properties.reCaptchaSiteKey" [organizationInfo]="organizationInfo" <feedback *ngIf="organizationInfo && properties.reCaptchaSiteKey" [organizationInfo]="organizationInfo"
[properties]="properties" [entityType]="'organization'" [fields]="feedbackFields" [properties]="properties" [entityType]="'organization'" [fields]="feedbackFields"
@ -240,6 +274,114 @@
</feedback> </feedback>
</div> </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 --> <!-- MODALS -->
<!-- Other versions --> <!-- Other versions -->
<modal-alert #AlertModalDeletedByInference *ngIf="organizationInfo && organizationInfo.deletedByInferenceIds" large="true"> <modal-alert #AlertModalDeletedByInference *ngIf="organizationInfo && organizationInfo.deletedByInferenceIds" large="true">
@ -259,6 +401,17 @@
<div class="uk-padding-small uk-margin-small-left uk-margin-small-right"> <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-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-grid uk-grid-divider uk-child-width-1-2@m" uk-grid uk-height-match=".subtitle">
<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 [isMobile]="isMobile" classTitle="uk-tile-default uk-border-bottom"></modal-loading>
<ng-template #downloadOptions>
<div class="uk-animation-slide-top-small"> <div class="uk-animation-slide-top-small">
<div class="subtitle uk-flex uk-flex-middle"> <div class="subtitle uk-flex uk-flex-middle">
<span class="uk-text-nowrap">Content report</span> <span class="uk-text-nowrap">Content report</span>
@ -314,10 +467,11 @@
No reports available No reports available
</div> </div>
</div> </div>
<div> <div [ngClass]="isMobile ? 'uk-margin-large-top' : ''">
<div class="subtitle uk-flex uk-flex-middle"> <div class="subtitle" [ngClass]="isMobile ? '' : 'uk-flex uk-flex-middle'">
<span class="uk-text-nowrap">Funder report</span> <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" <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"> [options]="funderOptions" [(value)]="funder" *ngIf="fetchProjects.funders && fetchProjects.funders.length > 0">
</div> </div>
</div> </div>
@ -345,10 +499,82 @@
No reports available No reports available
</div> </div>
</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>
</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>
</modal-alert> <div *ngIf="activeTab == 'dataProviders' && fetchDataproviders && fetchDataproviders.searchUtils.totalResults > 0"
<modal-alert #AlertModalApplyAll (alertOutput)="confirmCloseApplyAll()"></modal-alert> class="landing-section uk-padding uk-padding-remove-horizontal">
<modal-alert #AlertModalCsvError></modal-alert> <search-tab [fetch]="fetchDataproviders" resultType="dataprovider"
<modal-loading></modal-loading> [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 {properties} from "../../../../environments/environment";
import {OpenaireEntities} from '../../utils/properties/searchFields'; import {OpenaireEntities} from '../../utils/properties/searchFields';
import {Option} from '../../sharedComponents/input/input.component'; 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; declare var ResizeObserver;
@ -71,17 +73,23 @@ export class OrganizationComponent {
// Active tab variable for responsiveness // Active tab variable for responsiveness
public activeTab: string = ""; public activeTab: string = "";
@ViewChild('fsModal') fsModal: FullScreenModalComponent;
@ViewChild('downloadReportsModal') downloadReportsModal; @ViewChild('downloadReportsModal') downloadReportsModal;
@ViewChild('downloadReportsFsModal') downloadReportsFsModal: FullScreenModalComponent;
// @ViewChild('downloadReportModal') downloadReportModal; // @ViewChild('downloadReportModal') downloadReportModal;
// @ViewChild('downloadFunderReportModal') downloadFunderReportModal; // @ViewChild('downloadFunderReportModal') downloadFunderReportModal;
@ViewChild('addThisModal') addThisModal; @ViewChild('addThisModal') addThisModal;
@ViewChild('addThisFsModal') addThisFsModal: FullScreenModalComponent;
@ViewChild(ModalLoading) loading: ModalLoading; @ViewChild(ModalLoading) loading: ModalLoading;
// Alert box when CSV: Project Publications for a funder is requested // Alert box when CSV: Project Publications for a funder is requested
@ViewChild('AlertModalApplyAll') alertApplyAll; @ViewChild('AlertModalApplyAll') alertApplyAll;
@ViewChild('AlertFsModalApplyAll') alertFsApplyAll;
// Alert box when something is wrong with CSV requests // Alert box when something is wrong with CSV requests
@ViewChild('AlertModalCsvError') alertCsvError; @ViewChild('AlertModalCsvError') alertCsvError;
@ViewChild('AlertFsModalCsvError') alertFsCsvError;
public routerHelper: RouterHelper = new RouterHelper(); public routerHelper: RouterHelper = new RouterHelper();
public errorCodes: ErrorCodes = new ErrorCodes(); public errorCodes: ErrorCodes = new ErrorCodes();
@ -121,10 +129,13 @@ export class OrganizationComponent {
public feedbackFields: string [] = ['Name', 'Country', 'Other']; public feedbackFields: string [] = ['Name', 'Country', 'Other'];
@ViewChild('AlertModalDeletedByInference') alertModalDeletedByInference; @ViewChild('AlertModalDeletedByInference') alertModalDeletedByInference;
@ViewChild('AlertModalDeletedByInferenceFS') alertModalDeletedByInferenceFS;
// @ViewChild('projectsModal') projectsModal; // @ViewChild('projectsModal') projectsModal;
public deleteByInferenceOpened: boolean = false; public deleteByInferenceOpened: boolean = false;
public isMobile: boolean = false;
public mobileContent: "info" | "actions" = "info";
public viewAllMobile: string = "";
constructor(private element: ElementRef, constructor(private element: ElementRef,
private _organizationService: OrganizationService, private _organizationService: OrganizationService,
@ -141,7 +152,8 @@ export class OrganizationComponent {
private seoService: SEOService, private seoService: SEOService,
private _location: Location, private _location: Location,
private indexInfoService: IndexInfoService, private indexInfoService: IndexInfoService,
private cdr: ChangeDetectorRef) { private cdr: ChangeDetectorRef,
private layoutService: LayoutService) {
this.fetchProjects = new FetchProjects(this._searchProjectsService); this.fetchProjects = new FetchProjects(this._searchProjectsService);
this.fetchDataproviders = new FetchDataproviders(this._searchDataprovidersService); this.fetchDataproviders = new FetchDataproviders(this._searchDataprovidersService);
this.fetchPublications = new FetchResearchResults(this._searchResearchResultsService); this.fetchPublications = new FetchResearchResults(this._searchResearchResultsService);
@ -151,7 +163,9 @@ export class OrganizationComponent {
} }
ngOnInit() { ngOnInit() {
this.subscriptions.push(this.layoutService.isMobile.subscribe(isMobile => {
this.isMobile = isMobile;
}));
this.properties = properties; this.properties = properties;
if (typeof document !== 'undefined') { if (typeof document !== 'undefined') {
this.subscriptions.push(this.indexInfoService.getLastIndexDate(this.properties).subscribe(lastIndexUpdate => { this.subscriptions.push(this.indexInfoService.getLastIndexDate(this.properties).subscribe(lastIndexUpdate => {
@ -266,7 +280,8 @@ export class OrganizationComponent {
this.subscriptions.forEach(subscription => { this.subscriptions.forEach(subscription => {
if (subscription instanceof Subscriber) { if (subscription instanceof Subscriber) {
subscription.unsubscribe(); subscription.unsubscribe();
} else if (subscription instanceof (ResizeObserver || IntersectionObserver)) { } else if ((typeof ResizeObserver != 'undefined' && subscription instanceof ResizeObserver) ||
(typeof IntersectionObserver != 'undefined' && subscription instanceof IntersectionObserver)) {
subscription.disconnect(); subscription.disconnect();
} }
}); });
@ -628,6 +643,11 @@ export class OrganizationComponent {
} }
public confirmOpenApplyAll(contentType: string, contentFileName: string) { public confirmOpenApplyAll(contentType: string, contentFileName: string) {
if(this.isMobile) {
this.alertFsApplyAll.title = "CSV FILE";
this.alertFsApplyAll.okButton = false;
this.alertFsApplyAll.open();
} else {
this.alertApplyAll.cancelButton = true; this.alertApplyAll.cancelButton = true;
this.alertApplyAll.okButton = true; this.alertApplyAll.okButton = true;
this.alertApplyAll.alertTitle = "CSV FILE"; this.alertApplyAll.alertTitle = "CSV FILE";
@ -635,6 +655,7 @@ export class OrganizationComponent {
this.alertApplyAll.okButtonText = "Yes"; this.alertApplyAll.okButtonText = "Yes";
this.alertApplyAll.cancelButtonText = "No"; this.alertApplyAll.cancelButtonText = "No";
this.alertApplyAll.open(); this.alertApplyAll.open();
}
this.funderId = this.funder.id; this.funderId = this.funder.id;
this.funderCount = this.funder.number; this.funderCount = this.funder.number;
this.funderContentType = contentType; this.funderContentType = contentType;
@ -646,6 +667,12 @@ export class OrganizationComponent {
} }
public confirmOpenCsvError() { public confirmOpenCsvError() {
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.cancelButton = false;
this.alertCsvError.okButton = true; this.alertCsvError.okButton = true;
this.alertCsvError.alertTitle = "ERROR DOWNLOADING CSV FILE"; this.alertCsvError.alertTitle = "ERROR DOWNLOADING CSV FILE";
@ -653,6 +680,7 @@ export class OrganizationComponent {
this.alertCsvError.okButtonText = "OK"; this.alertCsvError.okButtonText = "OK";
this.alertCsvError.open(); this.alertCsvError.open();
} }
}
encodeURI(input: string): string { encodeURI(input: string): string {
return StringUtils.URIEncode(input); return StringUtils.URIEncode(input);
@ -686,7 +714,7 @@ export class OrganizationComponent {
} }
openDownloadReportsModal() { openDownloadReportsModal() {
this.funder = this.fetchProjects.funders[0]; // this.funder = this.fetchProjects.funders[0];
this.downloadReportsModal.cancelButton = false; this.downloadReportsModal.cancelButton = false;
this.downloadReportsModal.okButton = false; this.downloadReportsModal.okButton = false;
this.downloadReportsModal.alertTitle = "Download"; this.downloadReportsModal.alertTitle = "Download";
@ -808,7 +836,7 @@ export class OrganizationComponent {
for(let funder of this.fetchProjects.funders) { for(let funder of this.fetchProjects.funders) {
this.funderOptions.push({"label": funder.name, "value": funder}); this.funderOptions.push({"label": funder.name, "value": funder});
} }
this.funder = this.funderOptions[0]; this.funder = this.funderOptions[0].value;
} }
} }
@ -816,6 +844,13 @@ export class OrganizationComponent {
HelperFunctions.scroll(); HelperFunctions.scroll();
} }
public openFsModal(fsModal: FullScreenModalComponent, title: string) {
fsModal.title = title;
fsModal.okButton = false;
fsModal.stayOpenInBack = true;
fsModal.open();
}
public get eoscBackLink() { 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/"))) { 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; return this.referrer + this.prevPath;

View File

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

View File

@ -1,5 +1,6 @@
<div class="landing uk-section uk-padding-remove tm-middle"> <!-- Desktop view -->
<div class="tm-main"> <div class=" uk-visible@m landing uk-section uk-padding-remove tm-middle">
<div *ngIf="!isMobile" class="tm-main">
<div class="project"> <div class="project">
<div *ngIf="properties.adminToolsPortalType == 'eosc'" class="eosc-explore-back-search-bar"> <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"> <div class="uk-light uk-container uk-container-large uk-padding-small uk-height-1-1">
@ -14,7 +15,7 @@
<div *ngIf="!showFeedback" class="uk-grid uk-margin-remove-left" uk-grid> <div *ngIf="!showFeedback" class="uk-grid uk-margin-remove-left" uk-grid>
<!-- left box - actions --> <!-- left box - actions -->
<div id="landing-left-sidebar" *ngIf="projectInfo" class="uk-visible@s uk-padding-remove-horizontal"> <!-- <div id="landing-left-sidebar" *ngIf="projectInfo" class="uk-visible@s uk-padding-remove-horizontal">
<div class="uk-flex uk-flex-column uk-flex-between uk-flex-center uk-sticky" <div class="uk-flex uk-flex-column uk-flex-between uk-flex-center uk-sticky"
uk-sticky="bottom: true" [attr.offset]="offset"> uk-sticky="bottom: true" [attr.offset]="offset">
<div class="uk-align-center uk-text-center uk-margin-medium-top uk-flex uk-flex-column uk-flex-between"> <div class="uk-align-center uk-text-center uk-margin-medium-top uk-flex uk-flex-column uk-flex-between">
@ -29,7 +30,6 @@
<div class="uk-margin-large-bottom uk-align-center"> <div class="uk-margin-large-bottom uk-align-center">
<div class="uk-text-meta uk-text-uppercase">Actions</div> <div class="uk-text-meta uk-text-uppercase">Actions</div>
<ul class="uk-list"> <ul class="uk-list">
<!-- Share -->
<li class="uk-text-center"> <li class="uk-text-center">
<a (click)="openAddThisModal()" <a (click)="openAddThisModal()"
[title]="'Share this '+openaireEntities.PROJECT+' in your social networks'" [title]="'Share this '+openaireEntities.PROJECT+' in your social networks'"
@ -39,7 +39,6 @@
</span> </span>
</a> </a>
</li> </li>
<!-- Link to -->
<li *ngIf="isRouteAvailable('participate/direct-claim')" class="uk-text-center" <li *ngIf="isRouteAvailable('participate/direct-claim')" class="uk-text-center"
[title]="'<span class=\'uk-flex uk-flex-middle\'>Link this project to '+openaireEntities.RESULTS+'<span class=\'material-icons uk-margin-small-left\'>east</span></span>'" [title]="'<span class=\'uk-flex uk-flex-middle\'>Link this project to '+openaireEntities.RESULTS+'<span class=\'material-icons uk-margin-small-left\'>east</span></span>'"
[attr.uk-tooltip]="'pos: right; cls: uk-active uk-text-small uk-padding-small'"> [attr.uk-tooltip]="'pos: right; cls: uk-active uk-text-small uk-padding-small'">
@ -67,7 +66,6 @@
<icon name="code_off" visuallyHidden="code"></icon> <icon name="code_off" visuallyHidden="code"></icon>
</span> </span>
</a> </a>
</li> </li>
<li class="uk-text-center" <li class="uk-text-center"
[title]="'Download report'" [title]="'Download report'"
@ -81,20 +79,13 @@
</ul> </ul>
</div> </div>
</div> </div>
</div> </div> -->
<!-- center box--> <!-- center box-->
<div class="uk-width-expand uk-padding-remove uk-background-default"> <div id="landing-center-content" 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>
<ng-template #graph_and_feedback_template> <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]="!projectInfo"> <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]="!projectInfo">
<!-- Last Index Info--> <!-- Last Index Info-->
<a href="https://graph.openaire.eu" target="_blank" class="uk-width-1-1 uk-width-auto@l"> <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;"> <img src="assets/common-assets/openaire-badge-1.png" alt="Powered by OpenAIRE graph" style="height: 15px;">
@ -111,14 +102,43 @@
</div> </div>
</ng-template> </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" <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"> uk-sticky="bottom: true;" [attr.offset]="graph_offset">
<ng-container *ngTemplateOutlet="graph_and_feedback_template"></ng-container> <ng-container *ngTemplateOutlet="graph_and_feedback_template"></ng-container>
</div> </div>
<div class="uk-margin-large-left uk-margin-large-right" [style]="'margin-bottom: '+graph_height+'px'"> <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 && projectInfo" class="uk-visible@s uk-margin-top uk-margin-bottom">
<div class="uk-flex uk-flex-middle uk-flex-center">
<div class="landing-action-bar uk-text-xsmall uk-box-shadow-small uk-margin-bottom">
<entity-actions [deposit]="true" [share]="true" [linking]="true" [embed]="true"
[type]="'project'" [result]="projectInfo" [id]="projectInfo.id">
<div>
<a (click)="openDownloadReportModal()"
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>
<div class="uk-margin-left uk-margin-right" [style]="'margin-bottom: '+graph_height+'px'">
<ng-container *ngIf="projectInfo"> <ng-container *ngIf="projectInfo">
<div [attr.style]="'margin-top: '+(graph_height? 'calc(40px + 20px - '+graph_height+'px)': '40px')"> <div [attr.style]="'margin-top: '+(graph_height? 'calc(40px + 20px - '+graph_height+'px)': '40px')">
<div class="uk-grid uk-grid-small" uk-grid>
<div class="uk-width-expand">
<!-- schema.org--> <!-- schema.org-->
<schema2jsonld [data]=projectInfo <schema2jsonld [data]=projectInfo
[URL]="properties.domain+properties.baseLink+properties.searchLinkToProject+projectId" [URL]="properties.domain+properties.baseLink+properties.searchLinkToProject+projectId"
@ -158,7 +178,7 @@
[attr.uk-tooltip]="'pos: right; cls: uk-active uk-text-small uk-padding-small'"> [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)="openEmbedResultsModal()"> <a class="uk-link-text uk-text-bold uk-text-uppercase" (click)="openEmbedResultsModal()">
<span class="uk-icon-button uk-icon landing-action-button landing-action-button-portal"> <span class="uk-icon-button uk-icon landing-action-button landing-action-button-portal">
<icon name="code_off" visuallyHidden="code"></icon> <icon name="code" visuallyHidden="code"></icon>
</span> </span>
</a> </a>
</div> </div>
@ -178,12 +198,14 @@
<landing-header [properties]="properties" [title]="projectName" <landing-header [properties]="properties" [title]="projectName"
[subTitle]="projectInfo.acronym ? projectInfo.title : ''" [subTitle]="projectInfo.acronym ? projectInfo.title : ''"
[entityType]="'project'" [entityType]="'project'"
[startDate]="projectInfo.startDate" [startDate]="projectInfo.startDate" [endDate]="projectInfo.endDate"
[endDate]="projectInfo.endDate" [currentDate]="projectInfo.currentDate" [status]="projectInfo.status"
[status]="projectInfo.status"> [openAccessMandatePublications]="projectInfo.openAccessMandatePublications"
[openAccessMandateDatasets]="projectInfo.openAccessMandateDatasets" [prevPath]="prevPath">
</landing-header> </landing-header>
<!-- Labels --> <!-- Labels -->
<div class="uk-margin-bottom uk-grid uk-grid-small uk-flex-middle" uk-grid> <!-- To be moved inside the landing-header -->
<!-- <div class="uk-margin-bottom uk-grid uk-grid-small uk-flex-middle" uk-grid>
<ng-container *ngIf="projectInfo.openAccessMandatePublications != undefined && projectInfo.openAccessMandatePublications && projectInfo.openAccessMandateDatasets != undefined && projectInfo.openAccessMandateDatasets"> <ng-container *ngIf="projectInfo.openAccessMandatePublications != undefined && projectInfo.openAccessMandatePublications && projectInfo.openAccessMandateDatasets != undefined && projectInfo.openAccessMandateDatasets">
<div> <div>
<span class="uk-label uk-label-success uk-text-truncate" <span class="uk-label uk-label-success uk-text-truncate"
@ -213,12 +235,7 @@
</span> </span>
</div> </div>
</ng-container> </ng-container>
<!-- <ng-container *ngIf="projectInfo.specialClause39">--> </div> -->
<!-- <span class="uk-label custom-label label-sc39" title="Special Clause 39">-->
<!-- Special Clause 39-->
<!-- </span>&#160;-->
<!-- </ng-container>-->
</div>
<div class="uk-text-small"> <div class="uk-text-small">
<div *ngIf="projectInfo.funding" class="uk-margin-bottom"> <div *ngIf="projectInfo.funding" class="uk-margin-bottom">
<div class="uk-margin-small-bottom"> <div class="uk-margin-small-bottom">
@ -252,13 +269,13 @@
</span> </span>
</div> </div>
</div> </div>
<div *ngIf="projectInfo.status" class="uk-margin-right"> <!-- <div *ngIf="projectInfo.status" class="uk-margin-right">
<span> <span>
<span class="uk-text-meta">Status: </span> <span class="uk-text-meta">Status: </span>
<span class="uk-text-secondary">{{projectInfo.status}}</span> <span class="uk-text-secondary">{{projectInfo.status}}</span>
</span> </span>
</div> </div> -->
<div *ngIf="projectInfo.startDate || projectInfo.endDate" class="uk-width-large uk-margin-bottom"> <!-- <div *ngIf="projectInfo.startDate || projectInfo.endDate" class="uk-width-large uk-margin-bottom">
<progress *ngIf="projectInfo.startDate && projectInfo.endDate" <progress *ngIf="projectInfo.startDate && projectInfo.endDate"
class="uk-progress uk-box-shadow-inner uk-margin-small-top uk-margin-small-bottom" class="uk-progress uk-box-shadow-inner uk-margin-small-top uk-margin-small-bottom"
[value]="(projectInfo.currentDate > projectInfo.startDate ? projectInfo.currentDate-projectInfo.startDate : 0)" [value]="(projectInfo.currentDate > projectInfo.startDate ? projectInfo.currentDate-projectInfo.startDate : 0)"
@ -275,7 +292,7 @@
<ng-container *ngIf="projectInfo.currentDate < projectInfo.endDate">(Ending)</ng-container> <ng-container *ngIf="projectInfo.currentDate < projectInfo.endDate">(Ending)</ng-container>
</span> </span>
</div> </div>
</div> </div> -->
<div *ngIf="projectInfo.urlInfo" class="uk-margin-bottom"> <div *ngIf="projectInfo.urlInfo" class="uk-margin-bottom">
<a target="_blank" href="{{projectInfo.url}}" class="uk-button uk-button-text custom-external uk-text-capitalize uk-text-normal"> <a target="_blank" href="{{projectInfo.url}}" class="uk-button uk-button-text custom-external uk-text-capitalize uk-text-normal">
{{projectInfo.urlInfo}} {{projectInfo.urlInfo}}
@ -300,19 +317,62 @@
</div> </div>
</div> </div>
</div> </div>
<div *ngIf="projectInfo && hasMetrics" class="uk-width-1-1 uk-width-medium@s">
<div class="landing-metrics-card uk-card uk-card-secondary uk-text-small uk-flex uk-padding-small">
<div class="uk-width-expand uk-flex uk-flex-middle">
<div class="uk-grid uk-grid-small uk-flex-nowrap" uk-grid uk-height-match="target: > div > .cell">
<div>
<ng-container>
<ng-container *ngFor="let measure of projectInfo.measure.counts; let i = index">
<div *ngIf="measure.value" class="cell uk-flex uk-flex-middle" [class.uk-margin-xsmall-bottom]="i != projectInfo.measure.counts.length - 1">
<icon [name]="measure.icon" [ratio]="0.8" [flex]="true"></icon>
</div>
</ng-container>
</ng-container>
</div>
<div>
<ng-container *ngFor="let measure of projectInfo.measure.counts; let i = index">
<div *ngIf="measure.value" class="cell" [class.uk-margin-xsmall-bottom]="i != projectInfo.measure.counts.length - 1">
<a class="uk-text-capitalize">{{measure.name}}</a>
<ng-container *ngTemplateOutlet="dropInfo; context: {option: measure.name, isCompact: false}"></ng-container>
</div>
</ng-container>
</div>
<ng-template #dropInfo let-option=option>
<div class="uk-dropdown" uk-dropdown="pos: bottom-left; mode:click; container: #modal-container;">
<div class="uk-padding-small uk-width-medium uk-text-small" [innerHTML]="getMetricsTooltip(option) | safeHtml">
</div>
</div>
</ng-template>
<div class="uk-text-uppercase uk-text-bolder">
<ng-container *ngFor="let measure of projectInfo.measure.counts; let i = index">
<div *ngIf="measure.value" [attr.uk-tooltip]="measure.value >= 1000 ? 'cls: uk-active' : 'cls: uk-invisible'"
title="{{measure.value | number}}" class="cell" [class.uk-margin-xsmall-bottom]="i != projectInfo.measure.counts.length - 1">
{{formatNumber(measure.value)}}
</div>
</ng-container>
</div>
</div>
</div>
<div class="uk-width-1-5 uk-flex uk-flex-bottom">
<img src="assets/common-assets/metrics-badge.svg" loading="lazy" alt="Metrics badge">
</div>
</div>
</div>
</div>
</div>
<div id="main-tabs-div" class="uk-sticky uk-blur-background" <div id="main-tabs-div" class="uk-sticky uk-blur-background"
uk-sticky="bottom: true; media: @m" [attr.offset]="offset"> uk-sticky="bottom: true; media: @m" [attr.offset]="offset">
<div class="uk-padding uk-padding-remove-horizontal uk-padding-remove-bottom"> <div class="uk-padding uk-padding-remove-horizontal uk-padding-remove-bottom">
<!-- <showTitle *ngIf="stickyHeader" [titleName]="projectName" classNames="uk-margin-remove-bottom" class="uk-visible@m"></showTitle>--> <!-- <showTitle *ngIf="stickyHeader" [titleName]="projectName" classNames="uk-margin-remove-bottom" class="uk-visible@m"></showTitle>-->
<landing-header *ngIf="stickyHeader" class="uk-visible@m" <landing-header [ngClass]="stickyHeader ? 'uk-visible@m' : 'uk-invisible'"
[properties]="properties" [title]="projectName" [properties]="properties" [title]="projectName"
[subTitle]="projectInfo.acronym ? projectInfo.title : ''"
[entityType]="'project'" [entityType]="'project'"
[startDate]="projectInfo.startDate" [startDate]="projectInfo.startDate"
[endDate]="projectInfo.endDate" [endDate]="projectInfo.endDate"
[status]="projectInfo.status" [status]="projectInfo.status"
isSticky="true"> isSticky="true" [prevPath]="prevPath">
</landing-header> </landing-header>
<my-tabs (selectedActiveTab)="onSelectActiveTab($event)" [offsetForSticky]="offset" [(isSticky)]="stickyHeader"> <my-tabs (selectedActiveTab)="onSelectActiveTab($event)" [offsetForSticky]="offset" [(isSticky)]="stickyHeader">
<my-tab tabTitle="Summary" [tabId]="'summary'" [active]="true"></my-tab> <my-tab tabTitle="Summary" [tabId]="'summary'" [active]="true"></my-tab>
@ -328,7 +388,10 @@
<my-tab *ngIf="fetchOrps.searchUtils.totalResults > 0" <my-tab *ngIf="fetchOrps.searchUtils.totalResults > 0"
[tabTitle]="openaireEntities.OTHER" [tabNumber]="fetchOrps.searchUtils.totalResults" [tabTitle]="openaireEntities.OTHER" [tabNumber]="fetchOrps.searchUtils.totalResults"
[tabId]="'other'"></my-tab> [tabId]="'other'"></my-tab>
<my-tab [tabTitle]="'Dmps'" [tabNumber]="fetchDmps.searchUtils.totalResults > 0 ? fetchDmps.searchUtils.totalResults : ''" [tabId]="'dmps'"></my-tab> <my-tab [tabTitle]="'DMPs'" [tabNumber]="fetchDmps.searchUtils.totalResults > 0 ? fetchDmps.searchUtils.totalResults : ''" [tabId]="'dmps'"></my-tab>
<my-tab *ngIf="projectInfo && hasMetrics"
[tabTitle]="'Metrics'" [tabId]="'metrics'">
</my-tab>
<my-tab *ngIf="(fetchPublications.searchUtils.totalResults > 0 || fetchDatasets.searchUtils.totalResults > 0 <my-tab *ngIf="(fetchPublications.searchUtils.totalResults > 0 || fetchDatasets.searchUtils.totalResults > 0
|| fetchSoftware.searchUtils.totalResults > 0 || fetchOrps.searchUtils.totalResults > 0)" || fetchSoftware.searchUtils.totalResults > 0 || fetchOrps.searchUtils.totalResults > 0)"
[tabTitle]="'Statistics'" customClass="statistics" [tabId]="'statistics'" [active]="false"></my-tab> [tabTitle]="'Statistics'" customClass="statistics" [tabId]="'statistics'" [active]="false"></my-tab>
@ -337,160 +400,30 @@
</div> </div>
<div id="landing-sections" class="uk-text-small"> <div id="landing-sections" class="uk-text-small">
<div id="summary" class="landing-section landing-section-height-auto"> <ng-container>
<div class="uk-card uk-card-default card-tab uk-margin-medium-top uk-margin-medium-bottom"> <ng-container *ngTemplateOutlet="summary_content"></ng-container>
<div class="uk-card-body"> </ng-container>
<div class="uk-grid uk-grid-divider" uk-grid> <ng-container *ngIf="fetchPublications.searchUtils.totalResults > 0">
<div *ngIf="!hasPrimaryInfo && !hasSecondaryInfo" class="uk-width-expand uk-height-small uk-flex uk-flex-center uk-flex-middle"> <ng-container *ngTemplateOutlet="publications_content"></ng-container>
<div class="uk-animation-fade uk-text-meta uk-text-large">
No summary information available
</div>
</div>
<div *ngIf="hasPrimaryInfo" class="uk-width-expand">
<!-- Description -->
<div *ngIf="projectInfo.description" class="uk-margin-medium-bottom">
<div class="uk-text-justify ">
<div class="uk-text-meta uk-margin-small-bottom">Description</div>
<div class="multi-line-ellipsis lines-10">
<div #descriptionDiv class="uk-margin-small-bottom"
[innerHtml]="projectInfo.description"></div>
</div>
<div *ngIf="showViewMoreButton" class="uk-flex uk-flex-right">
<a (click)="openDescriptionModal();" class="view-more-less-link">
View more
</a>
</div>
</div>
</div>
</div>
<div *ngIf="hasSecondaryInfo" [class.uk-width-1-3@m]="hasPrimaryInfo" class="uk-width-1-1">
<div class="uk-height-1-1">
<!-- Organizations -->
<div class="uk-text-meta uk-margin-small-bottom">Partners</div>
<div class="uk-margin-medium-bottom">
<ng-container *ngTemplateOutlet="organizations_template; context: { threshold: lessBtnOrganizations ? projectInfo.organizations.length : thresholdOrganizations }"></ng-container>
<div *ngIf="projectInfo.organizations.length > thresholdOrganizations && !lessBtnOrganizations"
class="uk-text-center">
<a (click)="viewAllOrganizationsClick();" class="view-more-less-link">
View all
</a>
</div>
<div *ngIf="viewAllOrganizations && lessBtnOrganizations" class="uk-text-center">
<a (click)="viewAllOrganizations = !viewAllOrganizations; lessBtnOrganizations=false;" class="view-more-less-link">View less</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<ng-container *ngIf="fetchPublications.searchUtils.totalResults > 0">
<div 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>
</ng-container> </ng-container>
<ng-container *ngIf="fetchDatasets.searchUtils.totalResults > 0"> <ng-container *ngIf="fetchDatasets.searchUtils.totalResults > 0">
<div id="datasets" class="landing-section uk-padding uk-padding-remove-horizontal"> <ng-container *ngTemplateOutlet="datasets_content"></ng-container>
<search-tab [fetch]="fetchDatasets" resultType="dataset"
[params]="getParamsForSearchLink('datasets')"
[searchLinkToAdvancedPage]="properties.searchLinkToAdvancedResults"
[properties]="properties" [prevPath]="prevPath">
</search-tab>
</div>
</ng-container> </ng-container>
<ng-container *ngIf="fetchSoftware.searchUtils.totalResults > 0"> <ng-container *ngIf="fetchSoftware.searchUtils.totalResults > 0">
<div id="software" class="landing-section uk-padding uk-padding-remove-horizontal"> <ng-container *ngTemplateOutlet="software_content"></ng-container>
<search-tab [fetch]="fetchSoftware" resultType="software"
[params]="getParamsForSearchLink('software')"
[searchLinkToAdvancedPage]="properties.searchLinkToAdvancedResults"
[properties]="properties" [prevPath]="prevPath">
</search-tab>
</div>
</ng-container> </ng-container>
<ng-container *ngIf="fetchOrps.searchUtils.totalResults > 0"> <ng-container *ngIf="fetchOrps.searchUtils.totalResults > 0">
<div id="other" class="landing-section uk-padding uk-padding-remove-horizontal"> <ng-container *ngTemplateOutlet="other_content"></ng-container>
<search-tab [fetch]="fetchOrps" resultType="other"
[params]="getParamsForSearchLink('other')"
[searchLinkToAdvancedPage]="properties.searchLinkToAdvancedResults"
[properties]="properties" [prevPath]="prevPath">
</search-tab>
</div>
</ng-container> </ng-container>
<ng-container> <ng-container>
<div id="dmps" class="landing-section uk-padding uk-padding-remove-horizontal"> <ng-container *ngTemplateOutlet="dmps_content"></ng-container>
<search-tab [fetch]="fetchDmps" customTitle="Data Management Plans" </ng-container>
[properties]="properties" resultType="DMPs" [prevPath]="prevPath"> <ng-container *ngIf="projectInfo && hasMetrics">
<div class="uk-margin-medium-top uk-margin-bottom uk-width-1-1 uk-flex uk-flex-center uk-flex-middle"> <ng-container *ngTemplateOutlet="metricsContent"></ng-container>
<a *ngIf="properties.adminToolsPortalType == 'eosc' && fetchDmps.searchUtils.totalResults > 0"
class="uk-button uk-button-text uk-margin-right custom-external"
[href]="'https://explore.openaire.eu'+properties.searchLinkToAdvancedResults+
'?f0=relprojectid&fv0='+projectId+'&type=publications&instancetypename=Data Management Plan&qf=false&sortBy=resultdateofacceptance,descending'"
target="_blank">
View all in OpenAIRE
</a>
<a *ngIf="properties.adminToolsPortalType != 'eosc' && fetchDmps.searchUtils.totalResults > 0" class="uk-button uk-button-text uk-margin-right"
[queryParams]="getParamsForSearchLink('publications', 'Data Management Plan')"
[routerLink]="properties.searchLinkToAdvancedResults">
View all
<span *ngIf="fetchDmps.searchUtils.totalResults <= searchNumber">in search page</span>
</a>
<a class="uk-button uk-button-text custom-external" href="https://argos.openaire.eu/splash/" target="_blank">
<img src="assets/common-assets/common/argos_entities.svg"
alt="argos" width="20px" height="20px" loading="lazy">
Start a new DMP in <span class="text-argos">Argos</span>
</a>
</div>
</search-tab>
</div>
</ng-container> </ng-container>
<ng-container *ngIf="(fetchPublications.searchUtils.totalResults > 0 || fetchDatasets.searchUtils.totalResults > 0 <ng-container *ngIf="(fetchPublications.searchUtils.totalResults > 0 || fetchDatasets.searchUtils.totalResults > 0
|| fetchSoftware.searchUtils.totalResults > 0 || fetchOrps.searchUtils.totalResults > 0)"> || fetchSoftware.searchUtils.totalResults > 0 || fetchOrps.searchUtils.totalResults > 0)">
<div id="statistics" class="landing-section uk-padding uk-padding-remove-horizontal"> <ng-container *ngTemplateOutlet="statistics_content"></ng-container>
<div class="uk-text-meta uk-text-large uk-text-uppercase uk-margin-medium-bottom">Statistics</div>
<errorMessages [status]="[fetchPublications.searchUtils.status, fetchDatasets.searchUtils.status,
fetchSoftware.searchUtils.status, fetchOrps.searchUtils.status]"
[type]="'statistics'" tab_error_class=true></errorMessages>
<div
*ngIf="statsClicked &&
(fetchPublications.searchUtils.status == errorCodes.DONE || fetchDatasets.searchUtils.status == errorCodes.DONE
|| fetchSoftware.searchUtils.status == errorCodes.DONE || fetchOrps.searchUtils.status == errorCodes.DONE)"
class="uk-grid uk-child-width-1-1 uk-child-width-1-2@m">
<div class="uk-padding uk-padding-remove-top">
<div class="uk-card uk-card-default uk-card-body">
<div *ngIf="!properties.useNewStatistisTool" class="uk-text-center uk-text-large">Produced
{{openaireEntities.RESULTS}} per year
</div>
<i-frame [url]=chartScientificResultsUrl
customContainerClass="uk-background-default" customIframeClass="uk-blend-multiply"></i-frame>
</div>
</div>
<div class="uk-padding uk-padding-remove-top">
<div class="uk-card uk-card-default uk-card-body">
<div *ngIf="!properties.useNewStatistisTool" class="uk-text-center uk-text-large">Access mode of
{{openaireEntities.RESULTS}}
</div>
<i-frame [url]=chartAccessModeUrl
customContainerClass="uk-background-default" customIframeClass="uk-blend-multiply"></i-frame>
</div>
</div>
<div class="uk-padding uk-padding-remove-top">
<div class="uk-card uk-card-default uk-card-body">
<div *ngIf="!properties.useNewStatistisTool" class="uk-text-center uk-text-large">
{{openaireEntities.RESULTS}} per datasource
</div>
<i-frame [url]=chartDatasourcesUrl
customContainerClass="uk-background-default" customIframeClass="uk-blend-multiply"></i-frame>
</div>
</div>
</div>
</div>
</ng-container> </ng-container>
</div> </div>
@ -502,9 +435,188 @@
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div>
<!-- Mobile view -->
<div *ngIf="isMobile" class="uk-hidden@m uk-position-relative landing">
<ng-container *ngIf="projectInfo">
<div *ngIf="mobileContent == 'info'" class="uk-container uk-section">
<landing-header [properties]="properties" [title]="projectName"
[subTitle]="projectInfo.acronym ? projectInfo.title : ''"
[entityType]="'project'"
[startDate]="projectInfo.startDate" [endDate]="projectInfo.endDate"
[currentDate]="projectInfo.currentDate" [status]="projectInfo.status"
[openAccessMandatePublications]="projectInfo.openAccessMandatePublications"
[openAccessMandateDatasets]="projectInfo.openAccessMandateDatasets" [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(summaryFsModal, 'Summary'); onSelectActiveTab('summary')">
<span>Summary</span>
<icon name="chevron_right" [ratio]="1.5" [flex]="true"></icon>
</div>
<hr>
</ng-container>
<ng-container *ngIf="fetchPublications.searchUtils.totalResults > 0">
<div class="clickable uk-flex uk-flex-middle uk-flex-between" (click)="openFsModal(publicationsFsModal, 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.searchUtils.totalResults > 0">
<div class="clickable uk-flex uk-flex-middle uk-flex-between" (click)="openFsModal(datasetsFsModal, 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.searchUtils.totalResults > 0">
<div class="clickable uk-flex uk-flex-middle uk-flex-between" (click)="openFsModal(softwareFsModal, 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.searchUtils.totalResults > 0">
<div class="clickable uk-flex uk-flex-middle uk-flex-between" (click)="openFsModal(otherFsModal, openaireEntities.OTHER); onSelectActiveTab('other')">
<span>{{openaireEntities.OTHER}}</span>
<icon name="chevron_right" [ratio]="1.5" [flex]="true"></icon>
</div>
<hr>
</ng-container>
<ng-container>
<div class="clickable uk-flex uk-flex-middle uk-flex-between" (click)="openFsModal(dmpsFsModal, 'DMPs'); onSelectActiveTab('dmps')">
<span>DMPs</span>
<icon name="chevron_right" [ratio]="1.5" [flex]="true"></icon>
</div>
<hr>
</ng-container>
<ng-container *ngIf="(fetchPublications.searchUtils.totalResults > 0 || fetchDatasets.searchUtils.totalResults > 0
|| fetchSoftware.searchUtils.totalResults > 0 || fetchOrps.searchUtils.totalResults > 0)">
<div class="clickable uk-flex uk-flex-middle uk-flex-between" (click)="openFsModal(statisticsFsModal, 'Statistics'); onSelectActiveTab('statistics')">
<span>Statistics</span>
<icon name="chevron_right" [ratio]="1.5" [flex]="true"></icon>
</div>
<hr>
</ng-container>
</div>
</div>
<div *ngIf="mobileContent == 'metrics'" class="uk-container uk-section">
<ng-container *ngTemplateOutlet="metricsContent"></ng-container>
</div>
<div *ngIf="mobileContent == 'actions'" class="uk-container uk-section">
<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.PROJECT+' 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 *ngIf="isRouteAvailable('participate/deposit/learn-how')">
<a class="uk-button-link uk-flex uk-flex-middle uk-h6 uk-margin-remove uk-padding-small uk-padding-remove-horizontal"
routerLinkActive="router-link-active" routerLink="/participate/deposit/learn-how">
<icon [flex]="true" name="upload" visuallyHidden="upload"></icon>
<span class="uk-margin-small-left">
Deposit
</span>
</a>
<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(embedResultsFsModal, 'Embed results')">
<icon [flex]="true" name="code" visuallyHidden="code"></icon>
<span class="uk-margin-small-left">Embed</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(downloadReportFsModal, 'Download report')">
<icon [flex]="true" name="download" visuallyHidden="download"></icon>
<span class="uk-margin-small-left">Download</span>
</div>
<hr class="uk-margin-remove">
</ng-container>
<ng-container *ngIf="isRouteAvailable('participate/direct-claim')">
<a class="uk-button-link uk-flex uk-flex-middle uk-h6 uk-margin-remove uk-padding-small uk-padding-remove-horizontal"
[queryParams]="routerHelper.createQueryParams(['id','type','linkTo'],[projectId, 'project','result'])"
routerLinkActive="router-link-active" routerLink="/participate/direct-claim">
<icon [flex]="true" name="link_to" visuallyHidden="link"></icon>
<span class="uk-margin-small-left">
Link to
</span>
</a>
<hr class="uk-margin-remove">
</ng-container>
</div>
<div class="landing-action-bar-mobile uk-background-default">
<div class="uk-container uk-flex-middle uk-grid uk-text-xsmall uk-text-meta" [ngClass]="hasMetrics ? 'uk-child-width-1-3' : 'uk-child-width-1-2'">
<div>
<a class="uk-flex uk-flex-column uk-flex-middle uk-flex-center uk-link-reset" (click)="mobileContent = 'info'">
<icon name="assignment_turned_in" type="outlined" [flex]="true" [ratio]="2" [ngClass]="mobileContent == 'info' ? 'uk-text-primary': ''"></icon>
<span>{{openaireEntities.PROJECT}}</span>
</a>
</div>
<div *ngIf="projectInfo && hasMetrics">
<a class="uk-flex uk-flex-column uk-flex-middle uk-flex-center uk-link-reset" (click)="mobileContent = 'metrics'">
<icon name="bar_chart" type="outlined" [flex]="true" [ratio]="2" [ngClass]="mobileContent == 'metrics' ? 'uk-text-primary': ''"></icon>
<span>Metrics</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>
<fs-modal #summaryFsModal classTitle="uk-tile-default uk-border-bottom" (cancelEmitter)="cancelSummaryClicked()">
<ng-container *ngTemplateOutlet="summary_content"></ng-container>
</fs-modal>
<fs-modal #publicationsFsModal classTitle="uk-tile-default uk-border-bottom"
*ngIf="fetchPublications.searchUtils.totalResults > 0">
<ng-container *ngTemplateOutlet="publications_content"></ng-container>
</fs-modal>
<fs-modal #datasetsFsModal classTitle="uk-tile-default uk-border-bottom"
*ngIf="fetchDatasets.searchUtils.totalResults > 0">
<ng-container *ngTemplateOutlet="datasets_content"></ng-container>
</fs-modal>
<fs-modal #softwareFsModal classTitle="uk-tile-default uk-border-bottom"
*ngIf="fetchSoftware.searchUtils.totalResults > 0">
<ng-container *ngTemplateOutlet="software_content"></ng-container>
</fs-modal>
<fs-modal #otherFsModal classTitle="uk-tile-default uk-border-bottom"
*ngIf="fetchOrps.searchUtils.totalResults > 0">
<ng-container *ngTemplateOutlet="other_content"></ng-container>
</fs-modal>
<fs-modal #dmpsFsModal classTitle="uk-tile-default uk-border-bottom">
<ng-container *ngTemplateOutlet="dmps_content"></ng-container>
</fs-modal>
<fs-modal #statisticsFsModal classTitle="uk-tile-default uk-border-bottom"
*ngIf="(fetchPublications.searchUtils.totalResults > 0 || fetchDatasets.searchUtils.totalResults > 0
|| fetchSoftware.searchUtils.totalResults > 0 || fetchOrps.searchUtils.totalResults > 0)">
<ng-container *ngTemplateOutlet="statistics_content"></ng-container>
</fs-modal>
</ng-container>
</div>
<feedback *ngIf="projectInfo && properties.reCaptchaSiteKey" [projectInfo]="projectInfo" <feedback *ngIf="projectInfo && properties.reCaptchaSiteKey" [projectInfo]="projectInfo"
[properties]="properties" [entityType]="'project'" [title]="projectName" [fields]="feedbackFields" [properties]="properties" [entityType]="'project'" [title]="projectName" [fields]="feedbackFields"
@ -518,51 +630,11 @@
</modal-alert> </modal-alert>
<modal-alert *ngIf="projectInfo" #embedResultsModal large="true"> <modal-alert *ngIf="projectInfo" #embedResultsModal large="true">
<div class="uk-padding-small uk-margin-small-left uk-margin-small-right"> <ng-container *ngTemplateOutlet="embed_content"></ng-container>
<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> </modal-alert>
<modal-alert *ngIf="projectInfo" #downloadReportModal> <modal-alert *ngIf="projectInfo" #downloadReportModal>
<div class="uk-padding-small uk-margin-small-left uk-margin-small-right"> <ng-container *ngTemplateOutlet="download_content"></ng-container>
<div class="uk-padding-small uk-padding-remove-vertical">
<div input type="select" placeholder="Select content type report to download" inputClass="flat x-small"
[options]="resultTypesForDownloading" [(value)]="download_research_results_type" (click)="buildResultTypesForDownloading()"></div>
<div *ngIf="download_research_results_type" class="uk-animation-slide-top-small uk-margin-medium-top">
<ng-container *ngTemplateOutlet="download_research_results_box;
context: { type: download_research_results_type,
fileName_type: getFileNameType(download_research_results_type),
csvParams: getCsvParams(download_research_results_type) }">
</ng-container>
</div>
<div *ngIf="!projectInfo.funding ||
(fetchPublications.searchUtils.totalResults == 0 &&
fetchDatasets.searchUtils.totalResults == 0 &&
fetchSoftware.searchUtils.totalResults == 0 &&
fetchOrps.searchUtils.totalResults == 0)"
class="uk-text-meta uk-margin-medium-top uk-text-center">
No reports available
</div>
</div>
</div>
</modal-alert> </modal-alert>
<ng-template #download_research_results_box <ng-template #download_research_results_box
@ -612,3 +684,306 @@
</span> </span>
<span *ngIf="projectInfo.organizations.length > threshold"> ... </span> <span *ngIf="projectInfo.organizations.length > threshold"> ... </span>
</ng-template> </ng-template>
<ng-template #summary_content>
<div id="summary" class="landing-section landing-section-height-auto">
<div class="uk-margin-medium-top uk-margin-medium-bottom" [ngClass]="isMobile ? '' : 'uk-card uk-card-default card-tab'">
<div [ngClass]="isMobile ? '' : 'uk-card-body'">
<div class="uk-grid uk-grid-divider" uk-grid>
<div *ngIf="!hasPrimaryInfo && !hasSecondaryInfo" class="uk-width-expand uk-height-small uk-flex uk-flex-center uk-flex-middle">
<div class="uk-animation-fade uk-text-meta uk-text-large">
No summary information available
</div>
</div>
<div *ngIf="hasPrimaryInfo && viewAllMobile != 'organizations'" class="uk-width-expand">
<!-- Description -->
<div *ngIf="projectInfo.description && (!viewAllMobile || viewAllMobile == 'description')" class="uk-margin-medium-bottom">
<div class="uk-text-justify">
<div *ngIf="viewAllMobile != 'description'" class="uk-text-meta uk-margin-small-bottom">Description</div>
<div [ngClass]="viewAllMobile == 'description' ? '' : 'multi-line-ellipsis lines-10'">
<div #descriptionDiv class="uk-margin-small-bottom"
[innerHtml]="projectInfo.description"></div>
</div>
<div *ngIf="showViewMoreButton && viewAllMobile != 'description'" class="uk-flex uk-flex-right">
<a (click)="viewAllDescriptionClicked();" class="view-more-less-link">
View more
</a>
</div>
</div>
</div>
</div>
<div *ngIf="hasSecondaryInfo && viewAllMobile != 'description'" [class.uk-width-1-3@m]="hasPrimaryInfo" class="uk-width-1-1">
<div class="uk-height-1-1">
<!-- Organizations -->
<div *ngIf="viewAllMobile != 'organizations'" class="uk-text-meta uk-margin-small-bottom">Partners</div>
<div class="uk-margin-medium-bottom">
<ng-container *ngTemplateOutlet="organizations_template; context: { threshold: lessBtnOrganizations ? projectInfo.organizations.length : thresholdOrganizations }"></ng-container>
<div *ngIf="projectInfo.organizations.length > thresholdOrganizations && !lessBtnOrganizations"
class="uk-text-center">
<a (click)="viewAllOrganizationsClick();" class="view-more-less-link uk-visible@m">
View all
</a>
<a (click)="viewAllOrganizationsMobileClicked()" class="view-more-less-link uk-hidden@m">
View all
</a>
</div>
<div *ngIf="viewAllOrganizations && lessBtnOrganizations" class="uk-text-center">
<a (click)="viewAllOrganizations = !viewAllOrganizations; lessBtnOrganizations=false;" class="view-more-less-link">View less</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</ng-template>
<ng-template #publications_content>
<div 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>
</ng-template>
<ng-template #datasets_content>
<div 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>
</ng-template>
<ng-template #software_content>
<div 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>
</ng-template>
<ng-template #other_content>
<div 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>
</ng-template>
<ng-template #dmps_content>
<div id="dmps" class="landing-section uk-padding uk-padding-remove-horizontal">
<search-tab [fetch]="fetchDmps" customTitle="Data Management Plans"
[properties]="properties" resultType="DMPs" [prevPath]="prevPath">
<div class="uk-margin-medium-top uk-margin-bottom uk-width-1-1 uk-flex uk-flex-center uk-flex-middle">
<a *ngIf="fetchDmps.searchUtils.totalResults > 0" class="uk-button uk-button-text uk-margin-right"
[queryParams]="getParamsForSearchLink('publications', 'Data Management Plan')"
[routerLink]="properties.searchLinkToAdvancedResults">
View all
<span *ngIf="fetchDmps.searchUtils.totalResults <= searchNumber">in search page</span>
</a>
<a class="uk-button uk-button-text custom-external" href="https://argos.openaire.eu/splash/" target="_blank">
<img src="assets/common-assets/common/argos_entities.svg"
alt="argos" width="20px" height="20px" loading="lazy">
Start a new DMP in <span class="text-argos">Argos</span>
</a>
</div>
</search-tab>
</div>
</ng-template>
<ng-template #statistics_content>
<div id="statistics" class="landing-section uk-padding uk-padding-remove-horizontal">
<div class="uk-text-meta uk-text-large uk-text-uppercase uk-margin-medium-bottom">Statistics</div>
<errorMessages [status]="[fetchPublications.searchUtils.status, fetchDatasets.searchUtils.status,
fetchSoftware.searchUtils.status, fetchOrps.searchUtils.status]"
[type]="'statistics'" tab_error_class=true></errorMessages>
<div
*ngIf="statsClicked &&
(fetchPublications.searchUtils.status == errorCodes.DONE || fetchDatasets.searchUtils.status == errorCodes.DONE
|| fetchSoftware.searchUtils.status == errorCodes.DONE || fetchOrps.searchUtils.status == errorCodes.DONE)"
class="uk-grid uk-child-width-1-1 uk-child-width-1-2@m">
<div class="uk-padding uk-padding-remove-top">
<div class="uk-card uk-card-default uk-card-body">
<div *ngIf="!properties.useNewStatistisTool" class="uk-text-center uk-text-large">Produced
{{openaireEntities.RESULTS}} per year
</div>
<i-frame [url]=chartScientificResultsUrl
customContainerClass="uk-background-default" customIframeClass="uk-blend-multiply"></i-frame>
</div>
</div>
<div class="uk-padding uk-padding-remove-top">
<div class="uk-card uk-card-default uk-card-body">
<div *ngIf="!properties.useNewStatistisTool" class="uk-text-center uk-text-large">Access mode of
{{openaireEntities.RESULTS}}
</div>
<i-frame [url]=chartAccessModeUrl
customContainerClass="uk-background-default" customIframeClass="uk-blend-multiply"></i-frame>
</div>
</div>
<div class="uk-padding uk-padding-remove-top">
<div class="uk-card uk-card-default uk-card-body">
<div *ngIf="!properties.useNewStatistisTool" class="uk-text-center uk-text-large">
{{openaireEntities.RESULTS}} per datasource
</div>
<i-frame [url]=chartDatasourcesUrl
customContainerClass="uk-background-default" customIframeClass="uk-blend-multiply"></i-frame>
</div>
</div>
</div>
</div>
</ng-template>
<ng-template #metricsContent>
<div id="metrics" class="landing-section uk-padding uk-padding-remove-horizontal">
<ul class="uk-subnav uk-subnav-pill-alt uk-margin-remove" uk-switcher>
<li class="uk-padding-remove">
<a href="#">Overview</a>
</li>
<li *ngIf="hasMetrics">
<a href="#" (click)="clickedUsageMetrics()">Usage</a>
</li>
</ul>
<ul class="uk-switcher uk-margin-large-top">
<!-- overview -->
<li>
<div *ngIf="hasMetrics">
<div class="uk-grid-divider" uk-grid>
<div>
<div class="uk-text-center uk-margin-small-bottom">
<a href='https://usagecounts.openaire.eu/' target='_blank'>
<img src="assets/common-assets/logo-small-usage-counts.png" loading="lazy" alt="OpenAIRE UsageCounts">
</a>
</div>
<span class="uk-text-uppercase uk-text-xsmall">Usage by</span>
<span class="uk-display-block uk-text-bolder">
<a href='https://usagecounts.openaire.eu/' target='_blank' class="uk-link-reset">UsageCounts</a>
</span>
</div>
<div>
<table class="uk-table uk-table-small">
<tbody>
<ng-container *ngFor="let measure of projectInfo.measure.counts; let i = index">
<tr>
<td [class.uk-padding-remove-top]="i == 0" [class.uk-padding-remove-bottom]="i == projectInfo.measure.counts.length - 1">
<icon [name]="measure.icon" [flex]="true" [ratio]="1.2" customClass="uk-text-background text-usage-counts"></icon>
</td>
<td class="uk-text-capitalize" [class.uk-padding-remove-top]="i == 0" [class.uk-padding-remove-bottom]="i == projectInfo.measure.counts.length - 1">
{{measure.name}}
</td>
<td class="uk-text-uppercase uk-text-bolder" [class.uk-padding-remove-top]="i == 0" [class.uk-padding-remove-bottom]="i == projectInfo.measure.counts.length - 1"
[attr.uk-tooltip]="measure.value >= 1000 ? 'cls: uk-active' : 'cls: uk-invisible'"
title="{{measure.value | number}}">
{{formatNumber(measure.value)}}
</td>
</tr>
</ng-container>
</tbody>
</table>
</div>
</div>
</div>
</li>
<!-- usage -->
<li *ngIf="hasMetrics">
<div class="uk-flex uk-flex-center uk-flex-middle uk-flex-wrap" [class.uk-flex-column]="isMobile">
<div class="uk-margin-large-right uk-flex uk-flex-center uk-flex-middle uk-flex-wrap" [class.uk-flex-column]="!isMobile">
<ng-container *ngFor="let measure of projectInfo.measure.counts; let i = index">
<div *ngIf="measure.value" class="uk-text-center uk-margin-medium-bottom" [class.uk-margin-medium-right]="isMobile">
<div class="uk-text-background uk-text-bold number metrics-number"
[attr.uk-tooltip]="measure.value >= 1000 ? 'cls: uk-active' : 'cls: uk-invisible'"
title="{{measure.value | number}}">{{formatNumber(measure.value)}}</div>
<div class="uk-text-bold uk-text-capitalize">{{measure.name}}</div>
</div>
</ng-container>
</div>
<ng-container *ngIf="viewsFrameUrl || downloadsFrameUrl">
<div *ngIf="metricsClicked && viewsFrameUrl && hasViews" class="uk-margin-large-right">
<i-frame [height]="300" [url]="viewsFrameUrl" [addClass]="false"
customContainerClass="uk-background-default" customIframeClass="uk-blend-multiply uk-height-1-1">
</i-frame>
</div>
<div *ngIf="metricsClicked && downloadsFrameUrl && hasDownloads" class="uk-margin-large-right">
<i-frame [height]="300" [url]="downloadsFrameUrl" [addClass]="false"
customContainerClass="uk-background-default" customIframeClass="uk-blend-multiply uk-height-1-1"></i-frame>
</div>
</ng-container>
</div>
<div class="uk-text-center uk-margin-large-top">
<span class="uk-text-meta">Powered by</span>
<a href='https://usagecounts.openaire.eu/' target='_blank'>
<img class="uk-margin-small-left uk-margin-small-right uk-width-small" src="assets/common-assets/logo-large-usage-counts.png" loading="lazy" alt="OpenAIRE UsageCounts">
</a>
</div>
</li>
</ul>
</div>
</ng-template>
<fs-modal *ngIf="projectInfo" #addThisFsModal classTitle="uk-tile-default uk-border-bottom" classBody="uk-flex uk-flex-center uk-flex-middle">
<addThis></addThis>
</fs-modal>
<fs-modal *ngIf="projectInfo" #embedResultsFsModal classTitle="uk-tile-default uk-border-bottom" classBody="uk-flex uk-flex-center uk-flex-middle">
<ng-container *ngTemplateOutlet="embed_content"></ng-container>
</fs-modal>
<fs-modal *ngIf="projectInfo" #downloadReportFsModal classTitle="uk-tile-default uk-border-bottom" classBody="uk-flex uk-flex-center uk-flex-middle">
<ng-container *ngTemplateOutlet="download_content"></ng-container>
</fs-modal>
<ng-template #embed_content>
<div [ngClass]="isMobile ? 'uk-width-1-1' : 'uk-padding-small uk-margin-small-left uk-margin-small-right'">
<div [ngClass]="isMobile ? '' : '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>
</ng-template>
<ng-template #download_content>
<div [ngClass]="isMobile ? 'uk-width-1-1' : 'uk-padding-small uk-margin-small-left uk-margin-small-right'">
<div [ngClass]="isMobile ? '' : 'uk-padding-small uk-padding-remove-vertical'">
<div input type="select" placeholder="Select content type report to download" inputClass="flat x-small"
[options]="resultTypesForDownloading" [(value)]="download_research_results_type" (click)="buildResultTypesForDownloading()"></div>
<div *ngIf="download_research_results_type" class="uk-animation-slide-top-small uk-margin-medium-top">
<ng-container *ngTemplateOutlet="download_research_results_box;
context: { type: download_research_results_type,
fileName_type: getFileNameType(download_research_results_type),
csvParams: getCsvParams(download_research_results_type) }">
</ng-container>
</div>
<div *ngIf="!projectInfo.funding ||
(fetchPublications.searchUtils.totalResults == 0 &&
fetchDatasets.searchUtils.totalResults == 0 &&
fetchSoftware.searchUtils.totalResults == 0 &&
fetchOrps.searchUtils.totalResults == 0)"
class="uk-text-meta uk-margin-medium-top uk-text-center">
No reports available
</div>
</div>
</div>
</ng-template>

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 {ActivatedRoute, Router} from '@angular/router';
import {Meta, Title} from '@angular/platform-browser'; 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 {ResultPreview} from "../../utils/result-preview/result-preview";
import {SearchResult} from "../../utils/entities/searchResult"; import {SearchResult} from "../../utils/entities/searchResult";
import {IndexInfoService} from "../../utils/indexInfo.service"; import {IndexInfoService} from "../../utils/indexInfo.service";
import {Subscriber} from "rxjs"; import {Subscriber, Subscription, zip} from "rxjs";
import {properties} from "../../../../environments/environment"; import {properties} from "../../../../environments/environment";
import {Option} from "../../sharedComponents/input/input.component"; import {Option} from "../../sharedComponents/input/input.component";
import {OpenaireEntities} from "../../utils/properties/searchFields"; 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; declare var ResizeObserver;
@ -51,9 +55,13 @@ export class ProjectComponent {
public metricsClicked: boolean; public metricsClicked: boolean;
public viewsFrameUrl: string; public viewsFrameUrl: string;
public downloadsFrameUrl: string; public downloadsFrameUrl: string;
public totalViews: number; /** @deprecated*/
public totalDownloads: number; public totalViews: number = null;
public pageViews: number; /** @deprecated*/
public totalDownloads: number = null;
public hasViews: boolean = false;
public hasDownloads: boolean = false;
// public pageViews: number;
// Statistics tab variables // Statistics tab variables
public statsClicked: boolean; public statsClicked: boolean;
@ -86,8 +94,11 @@ export class ProjectComponent {
// @ViewChild('statisticsModal') statisticsModal; // @ViewChild('statisticsModal') statisticsModal;
// @ViewChild('linkProjectModal') linkProjectModal; // @ViewChild('linkProjectModal') linkProjectModal;
@ViewChild('embedResultsModal') embedResultsModal; @ViewChild('embedResultsModal') embedResultsModal;
@ViewChild('embedResultsFsModal') embedResultsFsModal: FullScreenModalComponent;
@ViewChild('downloadReportModal') downloadReportModal; @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) // Request results for publications, research data and software only the one time (first time tab is clicked)
private reloadPublications: boolean = true; private reloadPublications: boolean = true;
@ -163,9 +174,23 @@ export class ProjectComponent {
// public shouldSticky: boolean = true; // public shouldSticky: boolean = true;
subscriptions = []; subscriptions = [];
private sub: Subscription;
properties: EnvProperties; properties: EnvProperties;
public openaireEntities = OpenaireEntities; 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, constructor(private route: ActivatedRoute,
private _router: Router, private _router: Router,
private _location: Location, private _location: Location,
@ -179,10 +204,14 @@ export class ProjectComponent {
private _reportsService: ReportsService, private _reportsService: ReportsService,
private htmlService: HtmlProjectReportService, private htmlService: HtmlProjectReportService,
private indexInfoService: IndexInfoService, private indexInfoService: IndexInfoService,
private cdr: ChangeDetectorRef) {} private metricsService: MetricsService,
private cdr: ChangeDetectorRef,
private layoutService: LayoutService) {}
ngOnInit() { ngOnInit() {
this.subscriptions.push(this.layoutService.isMobile.subscribe(isMobile => {
this.isMobile = isMobile;
}));
this.properties = properties; this.properties = properties;
if (typeof document !== 'undefined') { if (typeof document !== 'undefined') {
this.subscriptions.push(this.indexInfoService.getLastIndexDate(this.properties).subscribe(lastIndexUpdate => { this.subscriptions.push(this.indexInfoService.getLastIndexDate(this.properties).subscribe(lastIndexUpdate => {
@ -195,8 +224,6 @@ export class ProjectComponent {
this.getPageContents(); this.getPageContents();
this.updateUrl(this.properties.domain + this.properties.baseLink + this._router.url); this.updateUrl(this.properties.domain + this.properties.baseLink + this._router.url);
this.seoService.createLinkForCanonicalURL(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.subscriptions.push(this.route.queryParams.subscribe(params => {
this.stickyHeader = false; this.stickyHeader = false;
this.metricsClicked = false; this.metricsClicked = false;
@ -353,7 +380,8 @@ export class ProjectComponent {
this.subscriptions.forEach(subscription => { this.subscriptions.forEach(subscription => {
if (subscription instanceof Subscriber) { if (subscription instanceof Subscriber) {
subscription.unsubscribe(); subscription.unsubscribe();
} else if (subscription instanceof (ResizeObserver || IntersectionObserver)) { } else if ((typeof ResizeObserver != 'undefined' && subscription instanceof ResizeObserver) ||
(typeof IntersectionObserver != 'undefined' && subscription instanceof IntersectionObserver)) {
subscription.disconnect(); subscription.disconnect();
} }
}); });
@ -510,6 +538,23 @@ export class ProjectComponent {
startDate: this.projectInfo.startDate, startDate: this.projectInfo.startDate,
endDate: this.projectInfo.endDate 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 //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'; // 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) { public metricsResults($event) {
this.totalViews = $event.totalViews; this.totalViews = $event.totalViews;
this.totalDownloads = $event.totalDownloads; 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 { 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() { 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() { public openOrganizationsModal() {
this.organizationsModal.cancelButton = false; this.organizationsModal.cancelButton = false;
this.organizationsModal.okButton = 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() { public openDescriptionModal() {
this.descriptionModal.alertFooter = false; this.descriptionModal.alertFooter = false;
this.descriptionModal.alertTitle = "Description"; this.descriptionModal.alertTitle = "Description";
this.descriptionModal.open(); 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) { public addEoscPrevInParams(obj) {
if(properties.adminToolsPortalType == "eosc" && this.prevPath) { if(properties.adminToolsPortalType == "eosc" && this.prevPath) {
let splitted: string[] = this.prevPath.split("?"); let splitted: string[] = this.prevPath.split("?");

View File

@ -31,7 +31,11 @@ import {LoadingModule} from "../../utils/loading/loading.module";
import {IconsModule} from "../../utils/icons/icons.module"; import {IconsModule} from "../../utils/icons/icons.module";
import {InputModule} from "../../sharedComponents/input/input.module"; import {InputModule} from "../../sharedComponents/input/input.module";
import {IconsService} from "../../utils/icons/icons.service"; 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({ @NgModule({
imports: [ imports: [
@ -41,7 +45,8 @@ import {graph, link} from "../../utils/icons/icons";
SearchResearchResultsServiceModule, ProjectServiceModule, SearchResearchResultsServiceModule, ProjectServiceModule,
Schema2jsonldModule, SEOServiceModule, HelperModule, Schema2jsonldModule, SEOServiceModule, HelperModule,
LandingHeaderModule, MatSelectModule, FeedbackModule, AltMetricsModule, LandingHeaderModule, MatSelectModule, FeedbackModule, AltMetricsModule,
TabsModule, SearchTabModule, LoadingModule, IconsModule, InputModule TabsModule, SearchTabModule, LoadingModule, IconsModule, InputModule,
FullScreenModalModule, SafeHtmlPipeModule, EGIDataTransferModule, EntityActionsModule
], ],
declarations: [ declarations: [
ProjectComponent ProjectComponent
@ -55,6 +60,6 @@ import {graph, link} from "../../utils/icons/icons";
}) })
export class ProjectModule { export class ProjectModule {
constructor(private iconsService: IconsService) { 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)"; this.projectInfo.urlInfo = "Detailed project information (CORDIS)";
} }
if (data[0]?.measure) {
this.projectInfo.measure = this.parsingFunctions.parseMeasures(data[0].measure);
}
return this.projectInfo; return this.projectInfo;
} }

View File

@ -24,10 +24,11 @@ import {HelperFunctions} from "../../../utils/HelperFunctions.class";
[page]="page" [pageSize]="pageSize" [page]="page" [pageSize]="pageSize"
[totalResults]="results.length"> [totalResults]="results.length">
</no-load-paging> </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)"> <li *ngFor="let result of results.slice((page-1)*pageSize, page*pageSize)">
<result-preview [modal]="modal" [properties]="properties" [hasLink]="false" [result]="getResultPreview(result)" <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> </li>
</ul> </ul>
<no-load-paging *ngIf="results.length > pageSize" [type]="type" <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 {ActivatedRoute, Router} from '@angular/router';
import {Meta, Title} from '@angular/platform-browser'; 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 {Identifier, StringUtils} from "../../utils/string-utils.class";
import {properties} from "../../../../environments/environment"; import {properties} from "../../../../environments/environment";
import {ISVocabulariesService} from "../../utils/staticAutoComplete/ISVocabularies.service"; import {ISVocabulariesService} from "../../utils/staticAutoComplete/ISVocabularies.service";
import {forkJoin, Observable, Subscription, zip} from "rxjs"; import {Subscription} from "rxjs";
import {AnnotationComponent} from "../annotation/annotation.component";
import {ParsingFunctions} from "../landing-utils/parsingFunctions.class"; import {ParsingFunctions} from "../landing-utils/parsingFunctions.class";
import {ConnectHelper} from "../../connect/connectHelper"; import {ConnectHelper} from "../../connect/connectHelper";
import {UserManagementService} from "../../services/user-management.service"; import {UserManagementService} from "../../services/user-management.service";
import {OpenaireEntities} from "../../utils/properties/searchFields"; import {OpenaireEntities} from "../../utils/properties/searchFields";
import {Option} from "../../sharedComponents/input/input.component"; 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; declare var ResizeObserver;
@ -42,8 +45,11 @@ export class ResultLandingComponent {
enermapsId; enermapsId;
// @ViewChild('linkModal') linkModal; // @ViewChild('linkModal') linkModal;
@ViewChild('citeModal') citeModal; @ViewChild('citeModal') citeModal;
@ViewChild('citeFsModal') citeFsModal;
@ViewChild('addThisModal') addThisModal; @ViewChild('addThisModal') addThisModal;
@ViewChild('addThisFsModal') addThisFsModal;
@ViewChild('AlertModalDeletedByInference') alertModalDeletedByInference; @ViewChild('AlertModalDeletedByInference') alertModalDeletedByInference;
@ViewChild('AlertModalDeletedByInferenceFS') alertModalDeletedByInferenceFS;
// @ViewChild('relationModal') relationModal; // @ViewChild('relationModal') relationModal;
public deleteByInferenceOpened: boolean = false; public deleteByInferenceOpened: boolean = false;
@Input() public resultFromInput: boolean = false; @Input() public resultFromInput: boolean = false;
@ -72,9 +78,14 @@ export class ResultLandingComponent {
public hasAltMetrics: boolean = false; public hasAltMetrics: boolean = false;
public viewsFrameUrl: string; public viewsFrameUrl: string;
public downloadsFrameUrl: string; public downloadsFrameUrl: string;
/** @deprecated*/
public totalViews: number = null; public totalViews: number = null;
/** @deprecated*/
public totalDownloads: number = null; public totalDownloads: number = null;
public hasViews: boolean = false;
public hasDownloads: boolean = false;
public pageViews: number = null; public pageViews: number = null;
public bipFrameUrl: string;
// Custom tab paging variables // Custom tab paging variables
public referencesPage: number = 1; public referencesPage: number = 1;
@ -114,7 +125,7 @@ export class ResultLandingComponent {
'Title', 'Authors', 'Access rights', 'Title', 'Authors', 'Access rights',
'Publisher information', 'Funding Information', 'Publisher information', 'Funding Information',
'Persistent identifiers', 'Sustainable Development Goals (SDGs)', 'Persistent identifiers', 'Sustainable Development Goals (SDGs)',
'Fields of Science and Technology (FOS)', 'Other']; 'Fields of Science (FoS)', 'Other'];
public pidsArrayString: string = ""; public pidsArrayString: string = "";
public identifier: Identifier; public identifier: Identifier;
@ -142,7 +153,26 @@ export class ResultLandingComponent {
// public shouldSticky: boolean = true; // public shouldSticky: boolean = true;
public mobileContent: "info" | "metrics" | "actions" = "info";
public tabMobile: string = "";
public viewAllMobile: string = "";
public viewAll: 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 noCommunities: boolean = false;
public rightSidebarOffcanvasClicked: boolean = false; public rightSidebarOffcanvasClicked: boolean = false;
@ -161,10 +191,14 @@ export class ResultLandingComponent {
private cdr: ChangeDetectorRef, private cdr: ChangeDetectorRef,
private _location: Location, private _location: Location,
private indexInfoService: IndexInfoService, private indexInfoService: IndexInfoService,
private userManagementService: UserManagementService) { private userManagementService: UserManagementService,
private layoutService: LayoutService) {
} }
ngOnInit() { ngOnInit() {
this.subscriptions.push(this.layoutService.isMobile.subscribe(isMobile => {
this.isMobile = isMobile;
}));
this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => { this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => {
this.isLoggedIn = !!user; this.isLoggedIn = !!user;
}, error => { this.isLoggedIn = false} )); }, error => { this.isLoggedIn = false} ));
@ -347,7 +381,8 @@ export class ResultLandingComponent {
subscription.unsubscribe(); subscription.unsubscribe();
} else if (subscription instanceof Function) { } else if (subscription instanceof Function) {
subscription(); subscription();
} else if (subscription instanceof (ResizeObserver || IntersectionObserver)) { } else if ((typeof ResizeObserver != 'undefined' && subscription instanceof ResizeObserver) ||
(typeof IntersectionObserver != 'undefined' && subscription instanceof IntersectionObserver)) {
subscription.disconnect(); 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.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=' + 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":""}}}'); 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); let pid:Identifier = Identifier.getPIDFromIdentifiers(this.resultLandingInfo.identifiers);
if (this.type == "result") { // no type was specified - update URL based this.resultLandingInfo.resultType if (this.type == "result") { // no type was specified - update URL based this.resultLandingInfo.resultType
this.updateUrlWithType(pid); this.updateUrlWithType(pid);
@ -515,7 +551,7 @@ export class ResultLandingComponent {
this.enermapsId = ParsingFunctions.getEnermapsConceptId(this.resultLandingInfo.contexts); this.enermapsId = ParsingFunctions.getEnermapsConceptId(this.resultLandingInfo.contexts);
} }
this.relatedClassFilters = [{"label": "All relations", "value": ""}];
if(this.resultLandingInfo.relatedClassFilters.size > 1) { if(this.resultLandingInfo.relatedClassFilters.size > 1) {
for (let relClass of this.resultLandingInfo.relatedClassFilters) { for (let relClass of this.resultLandingInfo.relatedClassFilters) {
this.relatedClassFilters.push({"label": HelperFunctions.getVocabularyLabel(relClass, this.relationsVocabulary), "value": relClass}); this.relatedClassFilters.push({"label": HelperFunctions.getVocabularyLabel(relClass, this.relationsVocabulary), "value": relClass});
@ -526,6 +562,19 @@ export class ResultLandingComponent {
this.relatedClassSelected = ""; this.relatedClassSelected = "";
this.filteredRelatedResults = this.resultLandingInfo.relatedResults; 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.showLoading = false;
this.setActiveTab(); this.setActiveTab();
@ -555,14 +604,12 @@ export class ResultLandingComponent {
public get hasPrimaryInfo(): boolean { public get hasPrimaryInfo(): boolean {
return !!this.resultLandingInfo && ( return !!this.resultLandingInfo && (
(!!this.resultLandingInfo.description && this.resultLandingInfo.description.length > 0) (!!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)); || (!!this.resultLandingInfo.organizations && this.resultLandingInfo.organizations.length > 0));
} }
public get hasRightSidebarInfo(): boolean { public get hasRightSidebarInfo(): boolean {
return (this.resultLandingInfo.eoscSubjects && this.resultLandingInfo.eoscSubjects.length 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) (this.resultLandingInfo.sdg && this.resultLandingInfo.sdg.length > 0)
|| ||
@ -572,7 +619,9 @@ export class ResultLandingComponent {
|| ||
(this.resultLandingInfo.contexts && this.resultLandingInfo.contexts.length > 0 && !this.noCommunities) (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 { 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() { public openOrganizationsModal() {
this.organizationsModal.cancelButton = false; this.organizationsModal.cancelButton = false;
this.organizationsModal.okButton = false; this.organizationsModal.okButton = false;
@ -917,12 +992,145 @@ export class ResultLandingComponent {
this.viewAll = ""; 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() { public openDescriptionModal() {
this.descriptionModal.alertFooter = false; this.descriptionModal.alertFooter = false;
this.descriptionModal.alertTitle = "Abstract"; this.descriptionModal.alertTitle = "Abstract";
this.descriptionModal.open(); 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() { public getEoscParams() {
let params = ""; let params = "";
if(this.prevPath) { if(this.prevPath) {
@ -953,5 +1161,4 @@ export class ResultLandingComponent {
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

@ -33,9 +33,14 @@ import {MatFormFieldModule} from "@angular/material/form-field";
import {MatSelectModule} from "@angular/material/select"; import {MatSelectModule} from "@angular/material/select";
import {IconsModule} from "../../utils/icons/icons.module"; import {IconsModule} from "../../utils/icons/icons.module";
import {IconsService} from "../../utils/icons/icons.service"; 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 {InputModule} from "../../sharedComponents/input/input.module";
import {EGIDataTransferModule} from "../../utils/dataTransfer/transferData.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({ @NgModule({
imports: [ imports: [
@ -44,7 +49,8 @@ import {EGIDataTransferModule} from "../../utils/dataTransfer/transferData.modul
MetricsModule, AltMetricsModule, Schema2jsonldModule, SEOServiceModule, MetricsModule, AltMetricsModule, Schema2jsonldModule, SEOServiceModule,
DeletedByInferenceModule, ShowAuthorsModule, HelperModule, ResultLandingUtilsModule, AlertModalModule, DeletedByInferenceModule, ShowAuthorsModule, HelperModule, ResultLandingUtilsModule, AlertModalModule,
AnnotationModule, LandingHeaderModule, NoLoadPaging, ResultPreviewModule, FeedbackModule, TabsModule, LoadingModule, 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: [ declarations: [
ResultLandingComponent ResultLandingComponent
@ -58,6 +64,6 @@ import {EGIDataTransferModule} from "../../utils/dataTransfer/transferData.modul
}) })
export class ResultLandingModule { export class ResultLandingModule {
constructor(private iconsService: IconsService) { 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

@ -127,7 +127,6 @@ export class ResultLandingService {
parseResultLandingInfo(data: any, subjectsVocabulary: any, properties: EnvProperties): any { parseResultLandingInfo(data: any, subjectsVocabulary: any, properties: EnvProperties): any {
this.resultLandingInfo = new ResultLandingInfo(); this.resultLandingInfo = new ResultLandingInfo();
// res // res
this.resultLandingInfo.record = data[15]; this.resultLandingInfo.record = data[15];
this.resultLandingInfo.objIdentifier = data[15]["result"]["header"]["dri:objIdentifier"]; this.resultLandingInfo.objIdentifier = data[15]["result"]["header"]["dri:objIdentifier"];
@ -240,9 +239,7 @@ export class ResultLandingService {
url = instance['webresource'][0].url; url = instance['webresource'][0].url;
} }
if (url.includes('&amp;')) { if (url.includes('&amp;')) {
let regExp = /&amp;/gmu; url = url.replace(/&amp;/gmu, '&');
let newUrl = url.replace(regExp, '&');
url = newUrl;
} }
/**********************************************************/ /**********************************************************/
@ -254,41 +251,7 @@ export class ResultLandingService {
} }
/* Order Download from via openness*/ /* Order Download from via openness*/
this.resultLandingInfo.hostedBy_collectedFrom.sort((a, b) => { this.resultLandingInfo.hostedBy_collectedFrom.sort(this.parsingFunctions.compareHostedByCollectedFrom);
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;
});
} }
if (data[3].hasOwnProperty("externalreference")) { if (data[3].hasOwnProperty("externalreference")) {
@ -304,7 +267,16 @@ export class ResultLandingService {
// res['result']['metadata']['oaf:entity']['oaf:result']['journal'] // res['result']['metadata']['oaf:entity']['oaf:result']['journal']
if (data[5] != null) { if (data[5] != null) {
this.resultLandingInfo.journal = {"journal": "", "issn": "", "lissn": "", "eissn": "", "issue": "", "volume": "", "start_page": "", "end_page": ""} this.resultLandingInfo.journal = {
"journal": "",
"issn": "",
"lissn": "",
"eissn": "",
"issue": "",
"volume": "",
"start_page": "",
"end_page": ""
}
this.resultLandingInfo.journal['journal'] = data[5].content; this.resultLandingInfo.journal['journal'] = data[5].content;
this.resultLandingInfo.journal['issn'] = data[5].issn; this.resultLandingInfo.journal['issn'] = data[5].issn;
@ -340,9 +312,13 @@ export class ResultLandingService {
this.resultLandingInfo.subjects = subjectResults[0]; this.resultLandingInfo.subjects = subjectResults[0];
this.resultLandingInfo.otherSubjects = subjectResults[1]; this.resultLandingInfo.otherSubjects = subjectResults[1];
this.resultLandingInfo.classifiedSubjects = subjectResults[2]; this.resultLandingInfo.classifiedSubjects = subjectResults[2];
this.resultLandingInfo.fos = subjectResults[3]; if (subjectResults[3]) {
subjectResults[3].forEach(element => {
this.resultLandingInfo.fos.push({id: element, label: element.replace(/^\d+/, '').trim()});
});
}
if (this.resultLandingInfo.fos) { if (this.resultLandingInfo.fos) {
this.resultLandingInfo.fos.sort((a, b) => a.localeCompare(b)) this.resultLandingInfo.fos.sort((a, b) => a.id.localeCompare(b.id));
} }
this.resultLandingInfo.sdg = subjectResults[4]; this.resultLandingInfo.sdg = subjectResults[4];
if (this.resultLandingInfo.sdg) { if (this.resultLandingInfo.sdg) {
@ -358,7 +334,7 @@ export class ResultLandingService {
this.resultLandingInfo.hostedBy_collectedFrom = this.parsingFunctions.addPublisherToHostedBy_collectedFrom( this.resultLandingInfo.hostedBy_collectedFrom = this.parsingFunctions.addPublisherToHostedBy_collectedFrom(
this.resultLandingInfo.hostedBy_collectedFrom, this.resultLandingInfo.publisher, this.resultLandingInfo.hostedBy_collectedFrom, this.resultLandingInfo.publisher,
this.resultLandingInfo.journal, this.resultLandingInfo.identifiers); this.resultLandingInfo.journal?.journal, this.resultLandingInfo.identifiers);
// res['result']['metadata']['oaf:entity']['oaf:result']['programmingLanguage'] // res['result']['metadata']['oaf:entity']['oaf:result']['programmingLanguage']
if (data[12] != null) { if (data[12] != null) {
@ -400,7 +376,11 @@ export class ResultLandingService {
if (author.orcid_pending) { if (author.orcid_pending) {
author.orcid_pending = author.orcid_pending.toUpperCase(); 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) { this.resultLandingInfo.authors = this.resultLandingInfo.authors.filter(function (item) {
@ -408,6 +388,11 @@ 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); this.resultLandingInfo.relatedResults = this.parsingFunctions.sortByPercentage(this.resultLandingInfo.relatedResults);
return this.resultLandingInfo; return this.resultLandingInfo;
@ -418,7 +403,8 @@ export class ResultLandingService {
organizations = [] organizations = []
} }
let organization: { "name": string, "shortname": string, let organization: {
"name": string, "shortname": string,
"id": string, "websiteUrl": string, "id": string, "websiteUrl": string,
"country": string, "trust": number "country": string, "trust": number
} = { } = {

View File

@ -11,64 +11,55 @@ import {ExternalIDV3_0, WorkV3_0} from "./orcidWork";
import {EnvProperties} from "../utils/properties/env-properties"; import {EnvProperties} from "../utils/properties/env-properties";
import {UserManagementService} from "../services/user-management.service"; import {UserManagementService} from "../services/user-management.service";
import {OpenaireEntities} from "../utils/properties/searchFields"; import {OpenaireEntities} from "../utils/properties/searchFields";
import {FullScreenModalComponent} from "../utils/modal/full-screen-modal/full-screen-modal.component";
declare var UIkit: any; declare var UIkit: any;
@Component({ @Component({
selector: 'orcid-work', selector: 'orcid-work',
template: ` template: `
<ng-container *ngIf="pageType == 'search'"> <ng-container *ngIf="pageType == 'landing' || pageType == 'search'">
<span *ngIf="!putCodes || putCodes.length == 0" <span *ngIf="!putCodes || putCodes.length == 0"
[attr.uk-tooltip]="(!isLoggedIn) ? tooltipNoLoggedInUser : tooltipAdd" [attr.uk-tooltip]="'pos: bottom; cls: uk-active uk-text-small uk-padding-small'"
class="uk-margin-remove-bottom"> [title]="((!pids && (!identifiers || identifiers.size == 0)) || !isLoggedIn) ? ((!pids && (!identifiers || identifiers.size == 0)) ? tooltipNoPid : tooltipNoLoggedInUser) : tooltipAdd">
<a (click)="currentAction='add'; saveWorkPreparation();" <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' : '')"> class="uk-flex uk-flex-middle uk-button-link"
<icon *ngIf="!showLoading" name="add" ratio="1" flex="true"></icon> [ngClass]="isMobile && !(pageType == 'landing') ? 'uk-margin-left' : 'uk-flex-center'"
<span *ngIf="showLoading" class="uk-icon icon-button"><loading [top_margin]="false" [size]="'small'"></loading></span> [class.uk-text-bolder]="!(isMobile && pageType == 'landing')"
<span class="uk-margin-small-left uk-flex uk-flex-middle">Add to&#160; [class.uk-disabled]="showLoading || !isLoggedIn || (!pids && (!identifiers || identifiers.size == 0))"
<span class="uk-flex uk-flex-middle"> [class.uk-text-muted]="showLoading || !isLoggedIn || (!pids && (!identifiers || identifiers.size == 0))"
<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"
(mouseover)="hoverEvent($event)" (mouseout)="hoverEvent($event)"> (mouseover)="hoverEvent($event)" (mouseout)="hoverEvent($event)">
<icon *ngIf="!hoverAdd" name="orcid_add" ratio="1.1" visuallyHidden="add"></icon> <icon *ngIf="!showLoading" [class.text-orcid]="!showLoading && isLoggedIn && (pids || identifiers?.size > 0)"
<icon *ngIf="hoverAdd" name="add" visuallyHidden="add"></icon> [class.uk-text-muted]="showLoading || !isLoggedIn || (!pids && (!identifiers || identifiers.size == 0))" name="orcid_add" ratio="1"
</a> visuallyHidden="add"></icon>
<span *ngIf="showLoading" class="uk-icon icon-button uk-icon-button-small"><loading <span *ngIf="showLoading" class="uk-icon"><loading
[top_margin]="false" [size]="'small'"></loading></span> [top_margin]="false" [size]="'small'"></loading></span>
<span [ngClass]="(isMobile && pageType == 'landing') ? 'uk-margin-small-left' : 'uk-margin-xsmall-left'">Claim</span>
</a>
</span> </span>
<span *ngIf="putCodes && putCodes.length > 0" <span *ngIf="putCodes && putCodes.length > 0"
[attr.uk-tooltip]="'pos: right; cls: uk-active uk-text-small uk-padding-small'" [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"> [title]="(!pids || !isLoggedIn) ? (!pids ? tooltipNoPid : tooltipNoLoggedInUser) : tooltipDelete">
<a *ngIf="!showLoading" (click)="currentAction='delete'; deleteWorks();" <a *ngIf="!showLoading" (click)="currentAction='delete'; deleteWorks();"
class="uk-icon-button uk-icon landing-action-button landing-action-button-orcid" class="uk-icon-button uk-icon landing-action-button landing-action-button-orcid"
@ -79,10 +70,10 @@ declare var UIkit: any;
</a> </a>
<span *ngIf="showLoading" class="uk-icon icon-button uk-icon-button-small"><loading <span *ngIf="showLoading" class="uk-icon icon-button uk-icon-button-small"><loading
[top_margin]="false" [size]="'small'"></loading></span> [top_margin]="false" [size]="'small'"></loading></span>
</span> </span> -->
</ng-container> </ng-container>
<modal-alert #grantModal [overflowBody]=false (alertOutput)="openGrantWindow()"> <modal-alert *ngIf="!isMobile" #grantModal [overflowBody]=false (alertOutput)="openGrantWindow()">
<div> <div>
<div>{{requestGrantMessage}}</div> <div>{{requestGrantMessage}}</div>
@ -106,6 +97,13 @@ declare var UIkit: any;
</div> </div>
</modal-alert> </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'"> <ng-container *ngIf="pageType == 'my_search'">
<span class="uk-margin-bottom uk-flex uk-flex-middle uk-flex-center"> <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' : '')"> [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> <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> <span class="uk-margin-small-left">View ORCID work</span>
</a> </a>
</span> </span>
@ -133,7 +132,8 @@ declare var UIkit: any;
<a (click)="currentAction='update'; updateWorkPreparation()" <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' : '')"> [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> <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> <span class="uk-margin-small-left">Update ORCID work</span>
</a> </a>
</span> </span>
@ -143,8 +143,9 @@ declare var UIkit: any;
<a (click)="currentAction='add'; saveWorkPreparation();" <a (click)="currentAction='add'; saveWorkPreparation();"
[class]="'uk-button uk-button-default action uk-margin-top uk-flex uk-flex-middle '+ (showLoading ? 'uk-disabled' : '')"> [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> <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 *ngIf="showLoading && currentAction=='add'" class="uk-icon icon-button"><loading [top_margin]="false"
<span class="uk-margin-small-left">Add to ORCID</span> [size]="'small'"></loading></span>
<span class="uk-margin-small-left">Claim</span>
</a> </a>
</span> </span>
@ -153,8 +154,9 @@ declare var UIkit: any;
<a (click)="currentAction='delete'; deleteWorks();" <a (click)="currentAction='delete'; deleteWorks();"
[class]="'uk-button uk-button-default action uk-margin-top uk-flex uk-flex-middle '+ (showLoading ? 'uk-disabled' : '')"> [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> <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 *ngIf="showLoading && currentAction=='delete'" class="uk-icon icon-button"><loading [top_margin]="false"
<span class="uk-margin-small-left">Delete from ORCID</span> [size]="'small'"></loading></span>
<span class="uk-margin-small-left">Remove</span>
</a> </a>
</span> </span>
</ng-container> </ng-container>
@ -228,14 +230,16 @@ declare var UIkit: any;
)"> )">
( (
</span> </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']}} {{contributor['contributor-attributes']['contributor-role']}}
</span> </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-sequence'] || (contributor['contributor-orcid'] && contributor['contributor-orcid']['path']))"> && (contributor['contributor-attributes']['contributor-sequence'] || (contributor['contributor-orcid'] && contributor['contributor-orcid']['path']))">
, ,
</span> </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']}} {{contributor['contributor-attributes']['contributor-sequence']}}
</span> </span>
<span *ngIf="contributor['contributor-attributes'] && contributor['contributor-attributes']['contributor-sequence'] <span *ngIf="contributor['contributor-attributes'] && contributor['contributor-attributes']['contributor-sequence']
@ -261,14 +265,17 @@ declare var UIkit: any;
<modal-alert #propagationModal (alertOutput)="confirmedPropagation()"> <modal-alert #propagationModal (alertOutput)="confirmedPropagation()">
<div> <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> <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'"> <div *ngIf="currentAction == 'delete'">
If you continue with delete action, <span class="uk-text-bold">all these works will be deleted</span>. If you continue with delete action, <span class="uk-text-bold">all these works will be deleted</span>.
</div> </div>
<div *ngIf="currentAction == 'update'"> <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> </div>
@ -284,10 +291,32 @@ declare var UIkit: any;
<!-- </button>--> <!-- </button>-->
<!-- </div>--> <!-- </div>-->
</modal-alert> </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 { export class OrcidWorkComponent {
@Input() isMobile: boolean = false;
@Input() resultId: string = ""; @Input() resultId: string = "";
@Input() resultTitle: string = ""; @Input() resultTitle: string = "";
@Input() resultLandingInfo: ResultLandingInfo; @Input() resultLandingInfo: ResultLandingInfo;
@ -304,8 +333,10 @@ export class OrcidWorkComponent {
@ViewChild('workModal') workModal; @ViewChild('workModal') workModal;
// @ViewChild('saveWorkModal') saveWorkModal; // @ViewChild('saveWorkModal') saveWorkModal;
@ViewChild('grantModal') grantModal; @ViewChild('grantModal') grantModal;
@ViewChild('grantFsModal') grantFsModal: FullScreenModalComponent;
// @ViewChild('messageModal') messageModal; // @ViewChild('messageModal') messageModal;
@ViewChild('propagationModal') propagationModal; @ViewChild('propagationModal') propagationModal;
@ViewChild('propagationFsModal') propagationFsModal;
public requestGrant: boolean = false; public requestGrant: boolean = false;
public requestGrantMessage: string = "Please grant OpenAIRE to access and update your ORCID works."; public requestGrantMessage: string = "Please grant OpenAIRE to access and update your ORCID works.";
@ -397,7 +428,12 @@ export class OrcidWorkComponent {
openGrantWindow() { openGrantWindow() {
if (!Session.isLoggedIn()) { if (!Session.isLoggedIn()) {
//this.userValidMessage = "User session has expired. Please login again."; //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 { } else {
// this.tokenUrl = location.origin+"/orcid"; // this.tokenUrl = location.origin+"/orcid";
this.window = window.open(this.tokenUrl, '_blank', this.window = window.open(this.tokenUrl, '_blank',
@ -464,7 +500,12 @@ export class OrcidWorkComponent {
public saveWorkPreparation() { public saveWorkPreparation() {
if (!Session.isLoggedIn()) { if (!Session.isLoggedIn()) {
//this.userValidMessage = "User session has expired. Please login again."; //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 { } else {
if (this.requestGrant) { if (this.requestGrant) {
@ -532,7 +573,12 @@ export class OrcidWorkComponent {
private updateWorkPreparation() { private updateWorkPreparation() {
if (!Session.isLoggedIn()) { if (!Session.isLoggedIn()) {
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 { } else {
if (this.requestGrant) { if (this.requestGrant) {
@ -589,7 +635,12 @@ export class OrcidWorkComponent {
public getOrcidWorks() { public getOrcidWorks() {
if (!Session.isLoggedIn()) { if (!Session.isLoggedIn()) {
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 { } else {
this.showLoading = true; this.showLoading = true;
this.subscriptions.push(this.orcidService.getOrcidWorks(this.putCodes).subscribe( this.subscriptions.push(this.orcidService.getOrcidWorks(this.putCodes).subscribe(
@ -626,7 +677,12 @@ export class OrcidWorkComponent {
public deleteWorks(confirmed: boolean = false) { public deleteWorks(confirmed: boolean = false) {
if (!Session.isLoggedIn()) { if (!Session.isLoggedIn()) {
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 { } else {
if (this.requestGrant) { if (this.requestGrant) {
@ -700,6 +756,11 @@ export class OrcidWorkComponent {
} }
openGrantModal(title: string) { openGrantModal(title: string) {
if(this.isMobile) {
this.grantFsModal.okButton = false;
this.grantFsModal.title = title;
this.grantFsModal.open();
} else {
this.grantModal.cancelButton = true; this.grantModal.cancelButton = true;
this.grantModal.okButton = true; this.grantModal.okButton = true;
this.grantModal.okButtonText = "Grant OpenAIRE"; this.grantModal.okButtonText = "Grant OpenAIRE";
@ -707,6 +768,7 @@ export class OrcidWorkComponent {
this.grantModal.alertTitle = title; this.grantModal.alertTitle = title;
this.grantModal.open(); this.grantModal.open();
} }
}
closeGrantModal() { closeGrantModal() {
this.grantModal.cancel(); this.grantModal.cancel();
@ -735,6 +797,11 @@ export class OrcidWorkComponent {
// } // }
openPropagationModal(title: string) { openPropagationModal(title: string) {
if(this.isMobile) {
this.propagationFsModal.okButton = false;
this.propagationFsModal.title = title;
this.propagationFsModal.open();
} else {
this.propagationModal.cancelButton = true; this.propagationModal.cancelButton = true;
this.propagationModal.okButton = true; this.propagationModal.okButton = true;
this.propagationModal.okButtonText = "Continue"; this.propagationModal.okButtonText = "Continue";
@ -742,6 +809,7 @@ export class OrcidWorkComponent {
this.propagationModal.alertTitle = title; this.propagationModal.alertTitle = title;
this.propagationModal.open(); this.propagationModal.open();
} }
}
closePropagationModal() { closePropagationModal() {
this.propagationModal.cancel(); this.propagationModal.cancel();

View File

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

View File

@ -3,7 +3,7 @@
@sdgs: #E6233D, #DF9F00, #19A220, #D70023, #FF0B00, #00BFE8, #FFC300, #B10240, #FF5D00, @sdgs: #E6233D, #DF9F00, #19A220, #D70023, #FF0B00, #00BFE8, #FFC300, #B10240, #FF5D00,
#F50D86, #FF8A00, #CA8A03, #2B772B, #0098DF, #00B91C, #0069A2, #1C336A; #F50D86, #FF8A00, #CA8A03, #2B772B, #0098DF, #00B91C, #0069A2, #1C336A;
custom-sdg-dot:after { .custom-sdg-dot:after {
content: ""; content: "";
background-image: url("~src/assets/common-assets/sdg/sdg-dot-img.svg"); background-image: url("~src/assets/common-assets/sdg/sdg-dot-img.svg");
display: inline-block; 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-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> <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" <advanced-search-form class="uk-width-expand uk-padding-remove-vertical"
entityType="all" [entityType]="activeEntity"
[advancedSearchLink]="advancedSearchLink" [advancedSearchLinkParameters]="parameters"
(queryChange)="keywordChanged($event)" (queryChange)="keywordChanged($event)"
[isDisabled]="disableForms" [isDisabled]="disableForms"
[simpleView]="true" [formPlaceholderText]="formPlaceholderText" [simpleView]="true" [formPlaceholderText]="formPlaceholderText"
[selectedFields]="selectedFields" [showSwitchSearchLink]="true" [dark]="searchForm.dark" [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> </advanced-search-form>
</div> </div>
@ -26,9 +27,10 @@
</div> </div>
<schema2jsonld *ngIf="name && logoURL" [URL]="properties.domain+ properties.baseLink +'/search/find'" <schema2jsonld *ngIf="name && logoURL" [URL]="properties.domain+ properties.baseLink +'/search/find'"
[logoURL]="properties.domain + properties.baseLink+logoURL" type="search" [name]=name [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> 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-large-top uk-margin-medium-bottom"> <div class="uk-container-large uk-container uk-margin-top">
<div class="uk-width-1-1" uk-slider="finite: true"> <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-position-relative">
<div class="uk-slider-container"> <div class="uk-slider-container">
<ul class="uk-slider-items uk-flex uk-flex-center" style="flex-wrap: nowrap !important;"> <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'"> <li [class.uk-active]="activeEntity == 'result'">
<a class="uk-text-uppercase"> <a class="uk-text-uppercase">
{{resultsName}} {{resultsName}}
<span *ngIf=" fetchPublications.searchUtils.totalResults!=null"> <span *ngIf=" fetchPublications.searchUtils.totalResults!=null" class="uk-visible@m">
({{fetchPublications.searchUtils.totalResults | number}})</span> ({{fetchPublications.searchUtils.totalResults | number}})</span>
</a> </a>
</li> </li>
@ -48,7 +50,7 @@
<li [class.uk-active]="activeEntity == 'projects'"> <li [class.uk-active]="activeEntity == 'projects'">
<a class="uk-text-uppercase"> <a class="uk-text-uppercase">
{{projectName}} {{projectName}}
<span *ngIf="fetchProjects.searchUtils.totalResults!=null"> <span *ngIf="fetchProjects.searchUtils.totalResults!=null" class="uk-visible@m">
({{fetchProjects.searchUtils.totalResults | number}})</span> ({{fetchProjects.searchUtils.totalResults | number}})</span>
</a> </a>
</li> </li>
@ -59,7 +61,7 @@
<li [class.uk-active]="activeEntity == 'datasources'"> <li [class.uk-active]="activeEntity == 'datasources'">
<a class="uk-text-uppercase"> <a class="uk-text-uppercase">
{{dataSourcesName}} {{dataSourcesName}}
<span *ngIf="fetchDataproviders.searchUtils.totalResults!=null"> <span *ngIf="fetchDataproviders.searchUtils.totalResults!=null" class="uk-visible@m">
({{fetchDataproviders.searchUtils.totalResults | number}})</span> ({{fetchDataproviders.searchUtils.totalResults | number}})</span>
</a> </a>
</li> </li>
@ -70,7 +72,7 @@
<li [class.uk-active]="activeEntity == 'services'"> <li [class.uk-active]="activeEntity == 'services'">
<a class="uk-text-uppercase"> <a class="uk-text-uppercase">
{{servicesName}} {{servicesName}}
<span *ngIf="fetchServices.searchUtils.totalResults!=null"> <span *ngIf="fetchServices.searchUtils.totalResults!=null" class="uk-visible@m">
({{fetchServices.searchUtils.totalResults | number}})</span> ({{fetchServices.searchUtils.totalResults | number}})</span>
</a> </a>
</li> </li>
@ -81,7 +83,7 @@
<li [class.uk-active]="activeEntity == 'organizations'"> <li [class.uk-active]="activeEntity == 'organizations'">
<a class="uk-text-uppercase"> <a class="uk-text-uppercase">
{{organizationsName}} {{organizationsName}}
<span *ngIf="fetchOrganizations.searchUtils.totalResults!=null"> <span *ngIf="fetchOrganizations.searchUtils.totalResults!=null" class="uk-visible@m">
({{fetchOrganizations.searchUtils.totalResults | number}})</span> ({{fetchOrganizations.searchUtils.totalResults | number}})</span>
</a> </a>
</li> </li>
@ -99,25 +101,25 @@
<search-research-results *ngIf="activeEntity == 'result'" resultType="result" [includeOnlyResultsAndFilter]="true" <search-research-results *ngIf="activeEntity == 'result'" resultType="result" [includeOnlyResultsAndFilter]="true"
(searchPageUpdates)="activeEntityUpdate($event)" [showSwitchSearchLink]="false" (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" <search-projects *ngIf="activeEntity == 'projects'" [includeOnlyResultsAndFilter]="true" [showSwitchSearchLink]="false"
(searchPageUpdates)="activeEntityUpdate($event)" (searchPageUpdates)="activeEntityUpdate($event)"
simpleSearchLink="/search/find" [customFilter]="customFilter"> [simpleSearchLink]="properties.searchLinkToProjects" [customFilter]="customFilter">
</search-projects> </search-projects>
<search-organizations *ngIf="activeEntity == 'organizations'" [includeOnlyResultsAndFilter]="true" [showSwitchSearchLink]="false" <search-organizations *ngIf="activeEntity == 'organizations'" [includeOnlyResultsAndFilter]="true" [showSwitchSearchLink]="false"
(searchPageUpdates)="activeEntityUpdate($event)" (searchPageUpdates)="activeEntityUpdate($event)"
simpleSearchLink="/search/find" [customFilter]="customFilter"> [simpleSearchLink]="properties.searchLinkToOrganizations" [customFilter]="customFilter">
</search-organizations> </search-organizations>
<search-dataproviders *ngIf="activeEntity == 'datasources'" [includeOnlyResultsAndFilter]="true" [showSwitchSearchLink]="false" <search-dataproviders *ngIf="activeEntity == 'datasources'" [includeOnlyResultsAndFilter]="true" [showSwitchSearchLink]="false"
(searchPageUpdates)="activeEntityUpdate($event)" (searchPageUpdates)="activeEntityUpdate($event)"
simpleSearchLink="/search/find" [customFilter]="customFilter"> [simpleSearchLink]="properties.searchLinkToDataProviders" [customFilter]="customFilter">
</search-dataproviders> </search-dataproviders>
<search-dataproviders *ngIf="activeEntity == 'services'" [includeOnlyResultsAndFilter]="true" [showSwitchSearchLink]="false" <search-dataproviders *ngIf="activeEntity == 'services'" [includeOnlyResultsAndFilter]="true" [showSwitchSearchLink]="false"
(searchPageUpdates)="activeEntityUpdate($event)" (searchPageUpdates)="activeEntityUpdate($event)"
simpleSearchLink="/search/find" [customFilter]="customFilter" [simpleSearchLink]="properties.searchLinkToServices" [customFilter]="customFilter"
type="services" entityType="service" [typeName]="openaireEntities.SERVICES"> type="services" entityType="service" [typeName]="openaireEntities.SERVICES">
</search-dataproviders> </search-dataproviders>

View File

@ -32,12 +32,15 @@ import {SearchDataProvidersComponent} from "../searchDataProviders.component";
import {NewSearchPageComponent, SearchForm} from "../searchUtils/newSearchPage.component"; import {NewSearchPageComponent, SearchForm} from "../searchUtils/newSearchPage.component";
import {properties} from "../../../../environments/environment"; import {properties} from "../../../../environments/environment";
import {Breadcrumb} from "../../utils/breadcrumbs/breadcrumbs.component"; import {Breadcrumb} from "../../utils/breadcrumbs/breadcrumbs.component";
import {LayoutService} from "../../dashboard/sharedComponents/sidebar/layout.service";
@Component({ @Component({
selector: 'search-all', selector: 'search-all',
templateUrl: 'searchAll.component.html' templateUrl: 'searchAll.component.html'
}) })
export class SearchAllComponent { export class SearchAllComponent {
isMobile: boolean = false;
reload:{result:boolean, projects:boolean, datasources: boolean, services: boolean, organizations:boolean} = reload:{result:boolean, projects:boolean, datasources: boolean, services: boolean, organizations:boolean} =
{result:true, projects:true, datasources: true, services: true, organizations:true}; {result:true, projects:true, datasources: true, services: true, organizations:true};
public pageTitle = "Search in OpenAIRE" public pageTitle = "Search in OpenAIRE"
@ -78,14 +81,16 @@ export class SearchAllComponent {
showDataProviders: boolean = false; showDataProviders: boolean = false;
showServices: boolean = false; showServices: boolean = false;
showOrganizations: boolean = false; showOrganizations: boolean = false;
advancedSearchLink: string = "/search/advanced/publications"; advancedSearchLink: string = properties.searchLinkToAdvancedResults;
properties: EnvProperties; properties: EnvProperties;
offset: number;
public openaireEntities = OpenaireEntities; public openaireEntities = OpenaireEntities;
@Input() logoURL; @Input() logoURL;
@Input() name; @Input() name;
@Input() customFilter: SearchCustomFilter = null; @Input() customFilter: SearchCustomFilter = null;
@Input() piwikSiteId = 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() searchForm: SearchForm = {class: 'search-form', dark: true}
@Input() breadcrumbs: Breadcrumb[] = []; @Input() breadcrumbs: Breadcrumb[] = [];
@ -125,6 +130,7 @@ export class SearchAllComponent {
private _title: Title, private _title: Title,
private _piwikService: PiwikService, private _piwikService: PiwikService,
private config: ConfigurationService, private config: ConfigurationService,
private layoutService: LayoutService,
private seoService: SEOService, private router: Router, private cdr:ChangeDetectorRef) { private seoService: SEOService, private router: Router, private cdr:ChangeDetectorRef) {
this.fetchPublications = new FetchResearchResults(this._searchResearchResultsService); this.fetchPublications = new FetchResearchResults(this._searchResearchResultsService);
this.fetchDataproviders = new FetchDataproviders(this._searchDataprovidersService); this.fetchDataproviders = new FetchDataproviders(this._searchDataprovidersService);
@ -141,8 +147,7 @@ export class SearchAllComponent {
public ngOnInit() { 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 Graph. ";
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 title = "OpenAIRE |Search for "+OpenaireEntities.RESULTS+", "+OpenaireEntities.PROJECTS+", "+OpenaireEntities.DATASOURCES+" & "+OpenaireEntities.ORGANIZATIONS; var title = "OpenAIRE |Search for "+OpenaireEntities.RESULTS+", "+OpenaireEntities.PROJECTS+", "+OpenaireEntities.DATASOURCES+" & "+OpenaireEntities.ORGANIZATIONS;
this.properties = properties; this.properties = properties;
var url = this.properties.domain + this.properties.baseLink + this._router.url; var url = this.properties.domain + this.properties.baseLink + this._router.url;
@ -195,33 +200,64 @@ export class SearchAllComponent {
this.showDataProviders = true; this.showDataProviders = true;
this.showServices = false; 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() { loadAll() {
this.reloadTabs(); this.reloadTabs();
this.subs.push(this.route.queryParams.subscribe(params => { this.subs.push(this.route.queryParams.subscribe(queryParams => {
this.parameters = Object.assign({}, params); this.parameters = Object.assign({}, queryParams);
this.keyword = (params['keyword']) ? params['keyword'] : (params["q"] ? params["q"] : (params["f0"] && params["f0"] == "q" && params["fv0"]?params["fv0"]:"")); 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.selectedFields[0].value = StringUtils.URIDecode(this.keyword);
this.quickFilter.selected = ((params['qf']== undefined || params["qf"] == "true") == true); this.quickFilter.selected = ((queryParams['qf']== undefined || queryParams["qf"] == "true") == true);
if (params["type"] && params["type"].length > 0) { if (queryParams["type"] && queryParams["type"].length > 0) {
this.resultTypes['publication'] = (params["type"].split(",").indexOf("publications") != -1); this.resultTypes['publication'] = (queryParams["type"].split(",").indexOf("publications") != -1);
this.resultTypes['dataset'] = (params["type"].split(",").indexOf("datasets") != -1); this.resultTypes['dataset'] = (queryParams["type"].split(",").indexOf("datasets") != -1);
this.resultTypes['software'] = (params["type"].split(",").indexOf("software") != -1); this.resultTypes['software'] = (queryParams["type"].split(",").indexOf("software") != -1);
this.resultTypes['other'] = (params["type"].split(",").indexOf("other") != -1); this.resultTypes['other'] = (queryParams["type"].split(",").indexOf("other") != -1);
} }
if(this.activeEntity == null && (!params["active"] || params["active"].length ==0)){ 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(); 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);
} }
} 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") { if (this.activeEntity == "result") {
this.searchResults(); this.searchResults();
@ -236,6 +272,7 @@ export class SearchAllComponent {
} }
this.count(); this.count();
})); }));
}));
} }
getDefaultEntityToShow(){ getDefaultEntityToShow(){
@ -265,7 +302,9 @@ export class SearchAllComponent {
} }
public searchResults() { 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] && if (this.reload[this.activeEntity] &&
this.fetchPublications.searchUtils.status != this.errorCodes.NONE) { this.fetchPublications.searchUtils.status != this.errorCodes.NONE) {
this.reload[this.activeEntity] = false; this.reload[this.activeEntity] = false;
@ -276,6 +315,8 @@ export class SearchAllComponent {
public searchProjects() { public searchProjects() {
this.advancedSearchLink = this.properties.searchLinkToAdvancedProjects;//"/search/advanced/projects"; this.advancedSearchLink = this.properties.searchLinkToAdvancedProjects;//"/search/advanced/projects";
this.formPlaceholderText = "Search by title, acronym, project code...";
if (this.reload[this.activeEntity] && if (this.reload[this.activeEntity] &&
this.fetchProjects.searchUtils.status != this.errorCodes.NONE ) { this.fetchProjects.searchUtils.status != this.errorCodes.NONE ) {
this.reload[this.activeEntity] = false; this.reload[this.activeEntity] = false;
@ -285,6 +326,8 @@ export class SearchAllComponent {
public searchDataProviders() { public searchDataProviders() {
this.advancedSearchLink = this.properties.searchLinkToAdvancedDataProviders;//"/search/advanced/dataproviders"; this.advancedSearchLink = this.properties.searchLinkToAdvancedDataProviders;//"/search/advanced/dataproviders";
this.formPlaceholderText = "Search by name, description, subject...";
if ( this.reload[this.activeEntity] && if ( this.reload[this.activeEntity] &&
this.fetchDataproviders.searchUtils.status != this.errorCodes.NONE) { this.fetchDataproviders.searchUtils.status != this.errorCodes.NONE) {
this.reload[this.activeEntity] = false; this.reload[this.activeEntity] = false;
@ -294,6 +337,8 @@ export class SearchAllComponent {
public searchServices() { public searchServices() {
this.advancedSearchLink = this.properties.searchLinkToAdvancedServices;//"/search/advanced/services"; this.advancedSearchLink = this.properties.searchLinkToAdvancedServices;//"/search/advanced/services";
this.formPlaceholderText = "Search by name, description, subject...";
if ( this.reload[this.activeEntity] && if ( this.reload[this.activeEntity] &&
this.fetchServices.searchUtils.status != this.errorCodes.NONE) { this.fetchServices.searchUtils.status != this.errorCodes.NONE) {
this.reload[this.activeEntity] = false; this.reload[this.activeEntity] = false;
@ -303,6 +348,8 @@ export class SearchAllComponent {
public searchOrganizations() { public searchOrganizations() {
this.advancedSearchLink = this.properties.searchLinkToAdvancedOrganizations;//"/search/advanced/organizations"; this.advancedSearchLink = this.properties.searchLinkToAdvancedOrganizations;//"/search/advanced/organizations";
this.formPlaceholderText = "Search by organization name...";
if (this.reload[this.activeEntity] && if (this.reload[this.activeEntity] &&
this.fetchOrganizations.searchUtils.status != this.errorCodes.NONE) { this.fetchOrganizations.searchUtils.status != this.errorCodes.NONE) {
this.reload[this.activeEntity] = false; this.reload[this.activeEntity] = false;
@ -533,6 +580,7 @@ export class SearchAllComponent {
} }
entityChanged(entity) { entityChanged(entity) {
if (this.activeEntity !== entity) {
if (this.activeEntity == "result") { if (this.activeEntity == "result") {
this.resultTypes = {publication: true, dataset: true, software: true, other: true}; this.resultTypes = {publication: true, dataset: true, software: true, other: true};
} }
@ -550,7 +598,6 @@ export class SearchAllComponent {
this.activeEntity = entity; this.activeEntity = entity;
this.parameters = {}; this.parameters = {};
this.reload[entity] = true; this.reload[entity] = true;
this.parameters["active"] = entity;
if (this.keyword.length > 0) { if (this.keyword.length > 0) {
this.parameters["fv0"] = this.keyword; this.parameters["fv0"] = this.keyword;
this.parameters["f0"] = "q"; this.parameters["f0"] = "q";
@ -558,7 +605,12 @@ export class SearchAllComponent {
if (this.customFilter) { if (this.customFilter) {
this.parameters = this.customFilter.getParameters(this.parameters); this.parameters = this.customFilter.getParameters(this.parameters);
} }
this.router.navigate(["/search/find"], {queryParams: 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" [includeOnlyResultsAndFilter]="includeOnlyResultsAndFilter"
[piwikSiteId]=piwikSiteId [hasPrefix]="hasPrefix" [piwikSiteId]=piwikSiteId [hasPrefix]="hasPrefix"
[searchForm]="searchForm" [searchForm]="searchForm"
[entitiesSelection]="type=='all' || type == 'services'" [showSwitchSearchLink]="showSwitchSearchLink" [entitiesSelection]="false" [showSwitchSearchLink]="showSwitchSearchLink"
[filters]="filters" [filters]="filters"
[simpleView]="simpleView" formPlaceholderText="Search by name, description, subject..." [simpleView]="simpleView" formPlaceholderText="Search by name, description, subject..."
[showResultCount]="true" [showIndexInfo]="type!='deposit'" [showResultCount]="true" [showIndexInfo]="type!='deposit'"

View File

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

View File

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

View File

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

View File

@ -132,7 +132,7 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges {
public pageOptions: number[] = [5, 10, 20, 50]; public pageOptions: number[] = [5, 10, 20, 50];
@Input() basicMetaDescription = []; @Input() basicMetaDescription = [];
@Input() entitiesSelection: boolean = true; @Input() entitiesSelection: boolean = false;
@Input() showSwitchSearchLink: boolean = true; @Input() showSwitchSearchLink: boolean = true;
// on 1st load, do not show filters until results query returns. // 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; showOffCanvas:boolean = false;
isMobile: boolean = false; isMobile: boolean = false;
isServer: boolean; isServer: boolean;
searchTerm: string = null;
advancedSearchTerms: number = 0;
constructor(private route: ActivatedRoute, constructor(private route: ActivatedRoute,
private location: Location, private location: Location,
@ -428,7 +430,9 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges {
var dependentTo = this.searchFieldsHelper.DEPENDENT_FIELDS[this.refineFields[i]]; var dependentTo = this.searchFieldsHelper.DEPENDENT_FIELDS[this.refineFields[i]];
//if filter is not marked as hidden OR it is hidden but it is dependent to a field that it IS selected //if 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]); fields.push(this.refineFields[i]);
} }
} }
@ -1689,6 +1693,14 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges {
this.getRangeFiltersFromURL(params); this.getRangeFiltersFromURL(params);
this.getRefineFiltersFromURL(params); this.getRefineFiltersFromURL(params);
this.createAdvancedSearchSelectedFiltersFromURLParameters(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) { removeResultType(type) {
@ -1708,4 +1720,12 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges {
} }
return totalPages; return totalPages;
} }
public getFilterById(filterId: string): Filter {
return this.filters.find(filter => filter.filterId == filterId);
}
detectChanges() {
this.cdr.detectChanges();
}
} }

View File

@ -11,6 +11,7 @@ import {OpenaireEntities} from "../../utils/properties/searchFields";
@Component({ @Component({
selector: 'quick-selections', selector: 'quick-selections',
template: ` template: `
<div *ngIf="!vertical && (resultTypes || quickFilter)">
<div *ngIf="quickFilter" class="uk-margin-bottom"> <div *ngIf="quickFilter" class="uk-margin-bottom">
<mat-slide-toggle name="qf" [(ngModel)]="quickFilter.selected" (ngModelChange)="quickFilterChanged()"> <mat-slide-toggle name="qf" [(ngModel)]="quickFilter.selected" (ngModelChange)="quickFilterChanged()">
<span class="uk-text-bold">{{quickFilter.value}}</span> <span class="uk-text-bold">{{quickFilter.value}}</span>
@ -29,9 +30,16 @@ import {OpenaireEntities} from "../../utils/properties/searchFields";
</div> </div>
</div> </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 { export class QuickSelectionsComponent {
@Input() vertical: boolean=false;
@Input() resultTypes:Filter; @Input() resultTypes:Filter;
@Output() typeChange = new EventEmitter(); @Output() typeChange = new EventEmitter();
@Input() isDisabled; @Input() isDisabled;

View File

@ -19,7 +19,7 @@
<div class="uk-margin-small-left"> <div class="uk-margin-small-left">
<div class="uk-text-meta">Top 100 values are shown in the filters</div> <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 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" <div *ngIf="showResultCount === true" input type="select" class="uk-width-expand" placeholder="Sort by"
inputClass="border-bottom" [(value)]="sortBy" [options]="sortByOptions" (valueChange)="sort()"></div> inputClass="border-bottom" [(value)]="sortBy" [options]="sortByOptions" (valueChange)="sort()"></div>
</div> </div>
@ -28,8 +28,12 @@
<ng-container *ngFor="let value of this.sortedValues"> <ng-container *ngFor="let value of this.sortedValues">
<div *ngIf="filterKeywords(value.name)" title="{{value.name}}" <div *ngIf="filterKeywords(value.name)" title="{{value.name}}"
class="uk-animation-fade uk-text-small"> class="uk-animation-fade uk-text-small">
<ng-container <ng-container *ngTemplateOutlet="input_label_wrapper; context: {filter: filter, value: value}"></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> </div>
</ng-container> </ng-container>
</div> </div>

View File

@ -5,7 +5,8 @@ import {
EventEmitter, EventEmitter,
OnInit, OnInit,
OnChanges, OnChanges,
SimpleChanges SimpleChanges,
ChangeDetectorRef
} from '@angular/core'; } from '@angular/core';
import {Filter, Value} from './searchHelperClasses.class'; import {Filter, Value} from './searchHelperClasses.class';
import {ActivatedRoute, Router} from "@angular/router"; import {ActivatedRoute, Router} from "@angular/router";
@ -42,7 +43,11 @@ export class SearchFilterComponent implements OnInit, OnChanges {
sub; sub;
public isOpen: boolean = false; public isOpen: boolean = false;
sortedValues; sortedValues;
constructor(private _router: Router, private route: ActivatedRoute) { hasMatch: boolean = false;
constructor(private _router: Router,
private route: ActivatedRoute,
private cdr: ChangeDetectorRef) {
} }
ngOnDestroy() { ngOnDestroy() {
@ -115,6 +120,10 @@ export class SearchFilterComponent implements OnInit, OnChanges {
return false; return false;
} }
} }
if(!this.hasMatch) {
this.hasMatch = true;
this.cdr.detectChanges();
}
return true; return true;
} }
@ -248,7 +257,11 @@ export class SearchFilterComponent implements OnInit, OnChanges {
}); });
} }
this.sortedValues = Object.assign(sorted); this.sortedValues = Object.assign(sorted);
}
initMatching() {
this.hasMatch = false;
this.cdr.detectChanges();
} }
toggle(event) { 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> <errorMessages [status]="[status]" [type]="'results'"></errorMessages>
<li *ngFor="let result of previewResults"> <li *ngFor="let result of previewResults">
<result-preview [properties]="properties" [showOrganizations]="showOrganizations" <result-preview [properties]="properties" [showOrganizations]="showOrganizations"
[showSubjects]="showSubjects" [result]="result" [showEnermaps]="showEnermaps" [showSubjects]="showSubjects" [result]="result" [showEnermaps]="showEnermaps"
[isCard]="true" [prevPath]="prevPath"> [isCard]="true" [isMobile]="isMobile" [prevPath]="prevPath">
</result-preview> </result-preview>
</li> </li>
</ul> </ul>

View File

@ -2,10 +2,11 @@ import {Component, Input, OnChanges, OnInit, SimpleChanges} from '@angular/core'
import {SearchResult} from '../../utils/entities/searchResult'; import {SearchResult} from '../../utils/entities/searchResult';
import {EnvProperties} from '../../utils/properties/env-properties'; import {EnvProperties} from '../../utils/properties/env-properties';
import {ResultPreview} from "../../utils/result-preview/result-preview"; import {ResultPreview} from "../../utils/result-preview/result-preview";
import {HttpClient} from "@angular/common/http";
import {OrcidService} from "../../orcid/orcid.service"; import {OrcidService} from "../../orcid/orcid.service";
import {Session} from "../../login/utils/helper.class"; import {Session} from "../../login/utils/helper.class";
import {properties} from "../../../../environments/environment"; import {properties} from "../../../../environments/environment";
import {LayoutService} from "../../dashboard/sharedComponents/sidebar/layout.service";
import {Subscription} from "rxjs";
@Component({ @Component({
selector: 'search-result', selector: 'search-result',
@ -23,18 +24,33 @@ export class SearchResultComponent implements OnInit, OnChanges {
@Input() custom_class: string = ""; @Input() custom_class: string = "";
@Input() properties: EnvProperties; @Input() properties: EnvProperties;
@Input() showEnermaps: boolean; @Input() showEnermaps: boolean;
public isMobile: boolean = false;
private subscriptions: any[] = [];
constructor( private http: HttpClient/*ATHENA CODE*/ constructor(private orcidService: OrcidService,
, private orcidService: OrcidService) { private layoutService: LayoutService) {
}
ngOnInit() {
this.subscriptions.push(this.layoutService.isMobile.subscribe(isMobile => {
this.isMobile = isMobile;
}));
} }
ngOnInit() {}
sub;
ngOnDestroy() { ngOnDestroy() {
if(this.sub){ this.subscriptions.forEach(subscription => {
this.sub.unsubscribe(); if(subscription instanceof Subscription) {
subscription.unsubscribe();
}
})
}
ngOnChanges(changes: SimpleChanges): void {
if (changes.results) {
this.initialize();
} }
} }
initialize() { initialize() {
this.previewResults = []; this.previewResults = [];
for (let result of this.results) { for (let result of this.results) {
@ -45,7 +61,7 @@ export class SearchResultComponent implements OnInit, OnChanges {
&& Session.isLoggedIn() && this.results && this.results.length > 0 && Session.isLoggedIn() && this.results && this.results.length > 0
&& (this.type == "result" || this.type == "publication" || this.type == "dataset" || this.type == "software" || this.type == "other") && (this.type == "result" || this.type == "publication" || this.type == "dataset" || this.type == "software" || this.type == "other")
) { ) {
this.orcidService.getPutCodes(this.previewResults.map( this.subscriptions.push(this.orcidService.getPutCodes(this.previewResults.map(
previewResult => { previewResult => {
if (previewResult.identifiers) { if (previewResult.identifiers) {
let pidsArray: string[] = []; let pidsArray: string[] = [];
@ -65,15 +81,10 @@ export class SearchResultComponent implements OnInit, OnChanges {
}, error => { }, error => {
} }
); ));
} }
} }
ngOnChanges(changes: SimpleChanges): void {
if (changes.results) {
this.initialize();
}
}
public getResultPreview(result: SearchResult): ResultPreview { 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']) { if(resData['pid']) {
result.identifiers = this.parsingFunctions.parseIdentifiers(resData['pid']); result.identifiers = this.parsingFunctions.parseIdentifiers(resData['pid']);
} }
// Measure
result.measure = this.parsingFunctions.parseMeasures(resData['measure']);
results.push(result); results.push(result);
} }

View File

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

View File

@ -7,11 +7,11 @@ import {ParsingFunctions} from '../landingPages/landing-utils/parsingFunctions.c
import {EnvProperties} from '../utils/properties/env-properties'; import {EnvProperties} from '../utils/properties/env-properties';
import {map} from "rxjs/operators"; import {map} from "rxjs/operators";
import {properties} from "../../../environments/environment"; import {properties} from "../../../environments/environment";
import {HostedByCollectedFrom} from "../utils/result-preview/result-preview";
@Injectable() @Injectable()
export class SearchResearchResultsService { export class SearchResearchResultsService {
private sizeOfDescription: number = 270;
public parsingFunctions: ParsingFunctions = new ParsingFunctions(); public parsingFunctions: ParsingFunctions = new ParsingFunctions();
constructor(private http: HttpClient = null) { constructor(private http: HttpClient = null) {
@ -189,62 +189,57 @@ export class SearchResearchResultsService {
} else { } else {
result.entityType = resultType; 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>(); result.types = new Array<string>();
let types = new Set<string>(); let types = new Set<string>();
let instance; let instance;
let length = Array.isArray(resData['children']['instance']) ? resData['children']['instance'].length : 1; 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++) { for (let i = 0; i < length; i++) {
instance = Array.isArray(resData['children']['instance']) ? resData['children']['instance'][i] : resData['children']['instance']; instance = Array.isArray(resData['children']['instance']) ? resData['children']['instance'][i] : resData['children']['instance'];
this.parsingFunctions.parseTypes(result.types, types, 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);
}
}
}
}
result.hostedBy_collectedFrom.sort(this.parsingFunctions.compareHostedByCollectedFrom);
// Measure // Measure
result.measure = new Array<string>(); result.measure = this.parsingFunctions.parseMeasures(resData['measure']);
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';
}
}
}
}
/////////////////////////// Athena Code /////////////////////////// /////////////////////////// Athena Code ///////////////////////////
if (resData['pid']) { if (resData['pid']) {
if (!Array.isArray(resData['pid'])) { if (!Array.isArray(resData['pid'])) {
@ -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['id'] = Array.isArray(data) ? data[i]['result']['header']['dri:objIdentifier'] : data['result']['header']['dri:objIdentifier'];
result['objId'] = result['id']; result['objId'] = result['id'];
let canId = ParsingFunctions.parseRelCanonicalId(Array.isArray(data) ? data[i] : data, "result"); let canId = ParsingFunctions.parseRelCanonicalId(Array.isArray(data) ? data[i] : data, "result");
@ -342,9 +316,6 @@ export class SearchResearchResultsService {
} }
result['relcanId'] = result['id']; result['relcanId'] = result['id'];
if (resData['bestaccessright'] && resData['bestaccessright'].hasOwnProperty("classname")) {
result['title'].accessMode = resData['bestaccessright'].classname;
}
if (resData['rels'].hasOwnProperty("rel")) { if (resData['rels'].hasOwnProperty("rel")) {
let relLength = Array.isArray(resData['rels']['rel']) ? resData['rels']['rel'].length : 1; let relLength = Array.isArray(resData['rels']['rel']) ? resData['rels']['rel'].length : 1;
@ -415,6 +386,36 @@ export class SearchResearchResultsService {
if (resData['context'] != null) { if (resData['context'] != null) {
result.enermapsId = ParsingFunctions.getEnermapsConceptId(this.parsingFunctions.parseContexts(resData['context'])); 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); results.push(result);
} }
return results; return results;

View File

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

View File

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

View File

@ -170,12 +170,28 @@
<ng-container *ngIf="!activeHeader.menuPosition || activeHeader.menuPosition === 'center'"> <ng-container *ngIf="!activeHeader.menuPosition || activeHeader.menuPosition === 'center'">
<ng-container *ngTemplateOutlet="mainMenu"></ng-container> <ng-container *ngTemplateOutlet="mainMenu"></ng-container>
</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>
<div class="uk-navbar-right"> <div class="uk-navbar-right">
<ng-container *ngIf="activeHeader.menuPosition === 'right'"> <ng-container *ngIf="activeHeader.menuPosition === 'right'">
<ng-container *ngTemplateOutlet="mainMenu"></ng-container> <ng-container *ngTemplateOutlet="mainMenu"></ng-container>
</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 [userMenuItems]=userMenuItems [logInUrl]=properties.loginUrl [logOutUrl]=properties.logoutUrl
[cookieDomain]=properties.cookieDomain></user-mini> [cookieDomain]=properties.cookieDomain></user-mini>
<div class="uk-visible@m"> <div class="uk-visible@m">
@ -183,7 +199,7 @@
</div> </div>
</div> </div>
<ng-template #mainMenu> <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 !== '/'"> <li class="uk-parent" *ngIf="showHomeMenuItem && currentRoute.route !== '/'">
<a routerLink="/">Home</a> <a routerLink="/">Home</a>
</li> </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 {ActivatedRoute, Router} from '@angular/router';
import {Session, User} from '../login/utils/helper.class'; import {Session, User} from '../login/utils/helper.class';
import {ConfigurationService} from '../utils/configuration/configuration.service'; import {ConfigurationService} from '../utils/configuration/configuration.service';
@ -9,6 +18,9 @@ import {HelpContentService} from '../services/help-content.service';
import {properties} from "../../../environments/environment"; import {properties} from "../../../environments/environment";
import {LayoutService} from "../dashboard/sharedComponents/sidebar/layout.service"; import {LayoutService} from "../dashboard/sharedComponents/sidebar/layout.service";
import {NotificationConfiguration} from "../notifications/notifications-sidebar/notifications-sidebar.component"; 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; declare var UIkit;
@ -57,6 +69,7 @@ export class NavigationBarComponent implements OnInit, OnDestroy, OnChanges {
subs: Subscription[] = []; subs: Subscription[] = [];
showEntity = {}; showEntity = {};
showPage = {}; showPage = {};
public searchMode: boolean = false;
public additionalMenuItems: MenuItem[] = []; public additionalMenuItems: MenuItem[] = [];
public featuredMenuItems: MenuItem[] = []; public featuredMenuItems: MenuItem[] = [];
@ -64,13 +77,28 @@ export class NavigationBarComponent implements OnInit, OnDestroy, OnChanges {
public isFeaturedMenuEnabled: boolean = false; public isFeaturedMenuEnabled: boolean = false;
public featuredAlignment: string = MenuAlignment.CENTER.valueOf(); 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, constructor(private router: Router,
private route: ActivatedRoute, private route: ActivatedRoute,
private config: ConfigurationService, private config: ConfigurationService,
private _helpContentService: HelpContentService, private _helpContentService: HelpContentService,
private layoutService: LayoutService) {} private layoutService: LayoutService,
private cdr: ChangeDetectorRef) {}
ngOnInit() { ngOnInit() {
this.subs.push(this.route.queryParams.subscribe(params => {
this.searchMode = false;
this.keyword = "";
}));
this.initialize(); this.initialize();
} }
@ -145,6 +173,9 @@ export class NavigationBarComponent implements OnInit, OnDestroy, OnChanges {
this.subs.push(this.layoutService.replaceHeader.subscribe(replaceHeader => { this.subs.push(this.layoutService.replaceHeader.subscribe(replaceHeader => {
this.setHeader(replaceHeader); this.setHeader(replaceHeader);
})); }));
this.subs.push(this.layoutService.hasMenuSearchBar.subscribe(hasSearchBar => {
this.hasSearchBar = hasSearchBar;
}));
} }
setHeader(replaceHeader: boolean) { setHeader(replaceHeader: boolean) {
@ -204,4 +235,29 @@ export class NavigationBarComponent implements OnInit, OnDestroy, OnChanges {
// return MenuItem.isTheActiveMenu(item, this.currentRoute, this.layoutService.activeMenuItem); // 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 {SearchBarModule} from "./searchBar/searchBar.module";
import {HelpContentService} from '../services/help-content.service'; import {HelpContentService} from '../services/help-content.service';
import {IconsModule} from "../utils/icons/icons.module"; import {IconsModule} from "../utils/icons/icons.module";
import {SearchInputModule} from "./search-input/search-input.module";
@NgModule({ @NgModule({
imports: [ imports: [
CommonModule, FormsModule, CommonModule, FormsModule,
RouterModule, RouterModule,
UserMiniModule, IconsModule, UserMiniModule, IconsModule, SearchInputModule,
// , SearchBarModule // , SearchBarModule
], ],
declarations: [ declarations: [

View File

@ -1,4 +1,5 @@
import { import {
AfterViewInit,
ChangeDetectorRef, ChangeDetectorRef,
Component, Component,
ElementRef, ElementRef,
@ -10,7 +11,6 @@ import {
ViewChild ViewChild
} from '@angular/core'; } from '@angular/core';
import {AbstractControl} from '@angular/forms'; import {AbstractControl} from '@angular/forms';
import {MatAutocompleteTrigger} from '@angular/material/autocomplete';
import {InputComponent} from "../input/input.component"; import {InputComponent} from "../input/input.component";
import {ClickEvent} from "../../utils/click/click-outside-or-esc.directive"; 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>
<div class="uk-width-auto" [class.uk-flex-first]="iconPosition === 'left'"> <div class="uk-width-auto" [class.uk-flex-first]="iconPosition === 'left'">
<div class="search-icon" [class.disabled]="disabled" (click)="search($event)"> <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> </div>
<div class="uk-width-auto filters-toggle"> <div class="uk-width-auto filters-toggle">
@ -44,7 +44,7 @@ import {ClickEvent} from "../../utils/click/click-outside-or-esc.directive";
</div> </div>
` `
}) })
export class SearchInputComponent implements OnInit { export class SearchInputComponent implements OnInit, AfterViewInit {
@Input() disabled: boolean = false; @Input() disabled: boolean = false;
@Input() searchInputClass: string = 'inner'; @Input() searchInputClass: string = 'inner';
@Input() iconPosition: 'left' | 'right' = 'right'; @Input() iconPosition: 'left' | 'right' = 'right';
@ -59,6 +59,7 @@ export class SearchInputComponent implements OnInit {
@ViewChild('input') input: InputComponent; @ViewChild('input') input: InputComponent;
public expanded: boolean = true; public expanded: boolean = true;
public initialized: boolean = false; public initialized: boolean = false;
public ratio: number = 1;
constructor(private cdr: ChangeDetectorRef) { constructor(private cdr: ChangeDetectorRef) {
} }
@ -86,6 +87,12 @@ export class SearchInputComponent implements OnInit {
this.initialized = true; this.initialized = true;
} }
ngAfterViewInit() {
if(typeof document !== 'undefined') {
this.ratio = Number.parseFloat(getComputedStyle(this.searchInput.nativeElement).getPropertyValue('--search-input-icon-ratio'));
}
}
expand(value: boolean) { expand(value: boolean) {
this.expanded = value; this.expanded = value;
this.cdr.detectChanges(); this.cdr.detectChanges();
@ -118,32 +125,4 @@ export class SearchInputComponent implements OnInit {
get hidden(): boolean { get hidden(): boolean {
return !this.expanded && (!this.searchControl?.value && !this.value); 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 { export class HelperFunctions {
public static scroll() { public static scroll(smooth: boolean = false) {
HelperFunctions.scrollTo(0,0); HelperFunctions.scrollTo(0,0);
} }
public static scrollTo(x,y) { public static scrollTo(x,y, smooth: boolean = false) {
if (typeof document !== 'undefined') { if (typeof document !== 'undefined') {
if(!smooth) {
window.scrollTo(x, y); window.scrollTo(x, y);
} else {
window.scrollTo({
top: 0,
left: 0,
behavior: "smooth"
})
}
} }
} }

View File

@ -12,6 +12,7 @@ declare var loadAltmetrics:any;
export class AltMetricsComponent { export class AltMetricsComponent {
@Input() id; @Input() id;
@Input() type = 'doi'; // doi or arxiv @Input() type = 'doi'; // doi or arxiv
@Input() size: string = 'donut';
// public doi="10.7717/peerj.1150"; // public doi="10.7717/peerj.1150";
public altmetrics:string; public altmetrics:string;
@ -26,9 +27,9 @@ export class AltMetricsComponent {
ngOnInit() { ngOnInit() {
this.sub = this.route.queryParams.subscribe(data => { this.sub = this.route.queryParams.subscribe(data => {
if(this.type == "doi"){ 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{ }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') { if (typeof document !== 'undefined') {
// let yourModule = require('../utils/altmetrics.js'); // let yourModule = require('../utils/altmetrics.js');

View File

@ -10,14 +10,15 @@ import {properties} from "../../../../environments/environment";
@Component({ @Component({
selector: 'showAuthors', selector: 'showAuthors',
template: ` template: `
<ng-template #author_template let-author="author" let-i="i"> <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;"> <span *ngIf="isSticky || (!author.orcid && !author.orcid_pending) || !testBrowser" style="margin-right: 5px;"
[class.uk-text-italic]="italic">
{{author.fullName + ";"}} {{author.fullName + ";"}}
</span> </span>
<a *ngIf="!isSticky && (author.orcid || author.orcid_pending) && testBrowser" class="uk-flex-inline uk-flex-middle uk-link-text"> <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" 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;"> <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 + ";"}} {{author.fullName + ";"}}
</span> </span>
</a> </a>
@ -78,7 +79,7 @@ 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"> <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 *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> </ng-container>
<span *ngIf="!showAll && authors && authors.length > authorsLimit" class="uk-text-meta"> <span *ngIf="!showAll && authors && authors.length > authorsLimit" class="uk-text-meta">
+{{authors.length-authorsLimit | number}} more +{{authors.length-authorsLimit | number}} more
@ -88,29 +89,39 @@ import {properties} from "../../../../environments/environment";
+{{authors.length-authorsLimit | number}} Authors +{{authors.length-authorsLimit | number}} Authors
</a> </a>
</span> </span>
<div *ngIf="viewAll && lessBtn" class="uk-text-small">
<a (click)="viewAll = !viewAll; lessBtn=false;">View less</a>
</div> </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> </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> <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 *ngFor="let author of authors; 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}"></ng-container>
</ng-container> </ng-container>
</div> </div>
</modal-alert> </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 { export class ShowAuthorsComponent {
@Input() isMobile: boolean = false;
@Input() authors: Author[]; @Input() authors: Author[];
@Input() isSticky: boolean = false; @Input() isSticky: boolean = false;
@Input() authorsLimit: number = 7; @Input() authorsLimit: number = 7;
@Input() showAll: boolean = true; @Input() showAll: boolean = true;
@Input() modal: AlertModal; @Input() modal: AlertModal;
@Input() viewAll: boolean = false; @Input() viewAll: boolean = false;
@Input() showInline: boolean = false; // do not open modal for "view more" when this is true
public lessBtn: boolean = false; public lessBtn: boolean = false;
@ViewChild('authorsModal') authorsModal; @ViewChild('authorsModal') authorsModal;
@ -133,7 +144,7 @@ export class ShowAuthorsComponent {
} }
public viewAllClick() { public viewAllClick() {
if(this.authors.length <= this.authorsLimit*2) { if(this.authors.length <= this.authorsLimit*2 || this.showInline) {
this.viewAll = true; this.viewAll = true;
this.lessBtn = true; this.lessBtn = true;
} else { } else {
@ -142,11 +153,17 @@ export class ShowAuthorsComponent {
} }
public openAuthorsModal() { public openAuthorsModal() {
if (this.isMobile) {
this.authorsModal.okButton = false;
this.authorsModal.title = "Authors";
this.authorsModal.open();
} else {
this.authorsModal.cancelButton = false; this.authorsModal.cancelButton = false;
this.authorsModal.okButton = false; this.authorsModal.okButton = false;
this.authorsModal.alertTitle = "Authors"; this.authorsModal.alertTitle = "Authors";
this.authorsModal.open(); this.authorsModal.open();
} }
}
copyToClipboard(element: HTMLInputElement) { copyToClipboard(element: HTMLInputElement) {
element.select(); element.select();

View File

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

View File

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

View File

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

View File

@ -1,10 +1,6 @@
import {Email} from "./email"; import {Email} from "./email";
import {Body} from "./body"; import {Body} from "./body";
import {FormArray} from "@angular/forms";
import {properties} from "../../../../environments/environment"; import {properties} from "../../../../environments/environment";
import {Stakeholder} from "../../monitor/entities/stakeholder";
import {Report} from "../../../../cache-indicators";
import {error} from "protractor";
export class Composer { export class Composer {
private static noteBodySize = "14px"; private static noteBodySize = "14px";
@ -141,6 +137,31 @@ export class Composer {
return email; 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 { public static composeEmailForUserAfterFeedback(recipients: string[]): Email {
let email: Email = new Email(); let email: Email = new Email();
email.subject = 'Feedback report received'; email.subject = 'Feedback report received';
@ -188,7 +209,7 @@ export class Composer {
return email; return email;
} }
public static composeEmailToReportCachingProcess(report: Report) { public static composeEmailToReportCachingProcess(report: any) {
let email: Email = new Email(); let email: Email = new Email();
email.recipients = [report.creator]; email.recipients = [report.creator];
email.subject = 'OpenAIRE | Monitor Dashboard - ' + report.name + '\'s caching process has been finished'; 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 {properties} from "../../../../environments/environment";
import {Measure} from "./resultLandingInfo";
export class DataproviderProvenance { export class DataproviderProvenance {
provenance: Map<string, {"urlPrefix": string, "name": string}>; provenance: Map<string, {"urlPrefix": string, "name": string}>;
@ -36,6 +37,7 @@ export class DataProviderInfo {
identifiers: Map<string, string[]>; //key is the classname identifiers: Map<string, string[]>; //key is the classname
fundedContent: string; // search query fundedContent: string; // search query
measure: Measure;
//collected from datasource api //collected from datasource api
// aggregationStatus: {"fundedContent": string, "indexRecords": string, "fulltexts": string, "lastUpdateDate": string}; // aggregationStatus: {"fundedContent": string, "indexRecords": string, "fulltexts": string, "lastUpdateDate": string};

View File

@ -1,8 +1,9 @@
import {Measure} from "./resultLandingInfo";
export class ProjectInfo { export class ProjectInfo {
id:string; id:string;
acronym: string; acronym: string;
title: string; title: string;
funding: {funderName: string, funderShortName: string, code: string, callIdentifier: string, funding: {funderName: string, funderShortName: string, code: string, callIdentifier: string,
fundingStream: string, budget: string, contribution: string, currency: string}; fundingStream: string, budget: string, contribution: string, currency: string};
startDate: number; startDate: number;
@ -18,8 +19,8 @@ export class ProjectInfo {
description: string; description: string;
//publications: any; //publications: any;
researchData: any; researchData: any;
totalPublications: number; totalPublications: number;
totalDatasets: number; totalDatasets: number;
publicationsStatus: any; publicationsStatus: any;
measure: Measure;
} }

View File

@ -29,6 +29,30 @@ export interface Context {
logo?: string; 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 { export class ResultLandingInfo {
relcanId; relcanId;
objIdentifier: string; objIdentifier: string;
@ -60,7 +84,7 @@ export class ResultLandingInfo {
subjects: string[]; subjects: string[];
otherSubjects: Map<string, string[]>; otherSubjects: Map<string, string[]>;
classifiedSubjects: Map<string, string[]>; //<class of subject, subjects> classifiedSubjects: Map<string, string[]>; //<class of subject, subjects>
fos: string[]; fos: {"id": string, "label": string}[] = [];
sdg: string[]; sdg: string[];
eoscSubjects: any[]; eoscSubjects: any[];
@ -140,4 +164,6 @@ export class ResultLandingInfo {
// SOFTWARE // SOFTWARE
programmingLanguages: string[]; programmingLanguages: string[];
measure: Measure;
} }

View File

@ -1,4 +1,5 @@
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 { export class SearchResult {
title: ResultTitle; title: ResultTitle;
@ -7,7 +8,10 @@ export class SearchResult {
objId: string; objId: string;
DOIs: string[] = []; DOIs: string[] = [];
identifiers: Map<string, string[]>; identifiers: Map<string, string[]>;
measure: Array<string>; measure: Measure;
date: string;
dateofacceptance: Date;
journal: Journal;
//publications & datasets & orp & software & projects & dataproviders: //publications & datasets & orp & software & projects & dataproviders:
description: string; description: string;
@ -21,6 +25,7 @@ export class SearchResult {
authors: Author[]; authors: Author[];
countriesForResults: string[]; countriesForResults: string[];
languages: string[]; languages: string[];
hostedBy_collectedFrom: HostedByCollectedFrom[];
//datasets & orp & software: //datasets & orp & software:
publisher: string; publisher: string;
@ -60,6 +65,7 @@ export class SearchResult {
entityType: string; entityType: string;
types: string[]; types: string[];
enermapsId: string; enermapsId: string;
constructor() { 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', 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>' 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 */ /** 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>'
}

View File

@ -25,7 +25,7 @@ declare var UIkit: any;
<icon name="close" ratio="1.5"></icon> <icon name="close" ratio="1.5"></icon>
</button> </button>
</div> </div>
<div class="uk-modal-body uk-animation-fast uk-text-left" <div #bodyElement class="uk-modal-body uk-animation-fast uk-text-left"
[ngClass]="classBody" [attr.uk-overflow-auto]="overflowBody?'':null"> [ngClass]="classBody" [attr.uk-overflow-auto]="overflowBody?'':null">
<div *ngIf="message" [hidden]=!alertMessage [innerHTML]="message | safeHtml"></div> <div *ngIf="message" [hidden]=!alertMessage [innerHTML]="message | safeHtml"></div>
<ng-content></ng-content> <ng-content></ng-content>
@ -37,6 +37,11 @@ declare var UIkit: any;
<span class="uk-margin-small-left">Don't show this message again</span> <span class="uk-margin-small-left">Don't show this message again</span>
</label> </label>
<div [ngClass]="(choice)?'uk-width-auto':'uk-width-1-1'"> <div [ngClass]="(choice)?'uk-width-auto':'uk-width-1-1'">
<div class="uk-width-1-1" [ngClass]="(previousButton && (cancelButton || okButton)) ? 'uk-flex uk-flex-between uk-grid' : ''">
<div *ngIf="previousButton" class="uk-flex-left">
<button class="uk-button uk-button-default uk-margin-small-left"
(click)="previous()">{{previousButtonText}}</button>
</div>
<div class="uk-flex-right uk-grid uk-grid-small" uk-grid> <div class="uk-flex-right uk-grid uk-grid-small" uk-grid>
<span *ngIf="okButton" [class.uk-flex-last]="!okButtonLeft"> <span *ngIf="okButton" [class.uk-flex-last]="!okButtonLeft">
<button class="uk-button uk-button-primary" [disabled]="okDisabled" <button class="uk-button uk-button-primary" [disabled]="okDisabled"
@ -52,6 +57,7 @@ declare var UIkit: any;
</div> </div>
</div> </div>
</div> </div>
</div>
`, `,
encapsulation: ViewEncapsulation.None, encapsulation: ViewEncapsulation.None,
}) })
@ -66,6 +72,7 @@ export class AlertModal implements OnInit, AfterViewInit, OnDestroy {
@Input() classBody: string = ""; @Input() classBody: string = "";
@Input() large: boolean = false; @Input() large: boolean = false;
@Input() overflowBody: boolean = true; @Input() overflowBody: boolean = true;
@ViewChild("bodyElement") bodyElement: ElementRef;
/** /**
* Caption for the title. * Caption for the title.
*/ */
@ -95,6 +102,17 @@ export class AlertModal implements OnInit, AfterViewInit, OnDestroy {
/** /**
* if the alertMessage is true it will show the contentString inside alert body. * if the alertMessage is true it will show the contentString inside alert body.
*/ */
/**
* Describes if the alert contains Previous Button.
* The default Previous button will emit the callback.
* Defaults to false.
*/
public previousButton: boolean = false;
/**
* Caption for the Previous button.
* Default: Previous
*/
public previousButtonText: string = 'Previous';
public alertMessage: boolean = true; public alertMessage: boolean = true;
/** /**
* Some message/content can be set in message which will be shown in alert body. * Some message/content can be set in message which will be shown in alert body.
@ -215,4 +233,12 @@ export class AlertModal implements OnInit, AfterViewInit, OnDestroy {
UIkit.modal(this.element.nativeElement).hide(); UIkit.modal(this.element.nativeElement).hide();
} }
} }
previous() {
this.cancelOutput.emit();
}
get bodyHeight() {
return (this.bodyElement) ? this.bodyElement.nativeElement.offsetHeight : 0;
}
} }

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