Compare commits

..

No commits in common. "master" and "develop-filters" have entirely different histories.

247 changed files with 5585 additions and 7738 deletions

View File

@ -8,39 +8,29 @@ import { properties } from "../../environments/environment";
export class CacheInterceptorService implements HttpInterceptor {
cachingRequests = [
// Remove 2 following lines when bug with hidden refine filters is solved.
"/resources2/?format=json&refine=true&fields=instancetypename&fields=foslabel&fields=relfunder&fields=relfundinglevel0_id&fields=relproject&fields=sdg&fields=country&fields=resultlanguagename&fields=resulthostingdatasource&fields=community&&fq=resultbestaccessright exact \"Open Access\"&type=results&page=0&size=0",
"/resources2/?format=json&refine=true&fields=resultbestaccessright&fields=instancetypename&fields=fos&fields=relfunder&fields=relfundinglevel0_id&fields=relproject&fields=sdg&fields=country&fields=resultlanguagename&fields=resulthostingdatasource&fields=community&fields=country&&fq=resultbestaccessright exact \"Open Access\"&type=results&page=0&size=0",
"/resources2/?format=json&refine=true&fields=funder&fields=fundinglevel0_id&fields=projectstartyear&fields=projectendyear&fields=projectoamandatepublications&&type=projects&page=0&size=0",
"/resources2/?format=json&refine=true&fields=instancetypename&fields=foslabel&fields=relfunder&fields=sdg&fields=country&fields=resultlanguagename&fields=resulthostingdatasource&fields=community&&type=results&page=0&size=0",
"/resources2/?format=json&refine=true&fields=instancetypename&fields=foslabel&fields=relfunder&fields=relfundinglevel0_id&fields=relproject&fields=sdg&fields=country&fields=resultlanguagename&fields=resulthostingdatasource&fields=community&&fq=resultbestaccessright%20exact%20%22Open%20Access%22&fq=relfunder%20exact%20%22ec__________%3A%3AEC%7C%7CEuropean%20Commission%7C%7CEC%22&type=results&page=0&size=0",
"/resources2/?format=json&refine=true&fields=resultbestaccessright&fields=instancetypename&fields=fos&fields=relfunder&fields=sdg&fields=country&fields=resultlanguagename&fields=resulthostingdatasource&fields=community&&type=results&page=0&size=0",
"/resources2/?format=json&refine=true&fields=resultbestaccessright&fields=instancetypename&fields=fos&fields=relfunder&fields=relfundinglevel0_id&fields=relproject&fields=sdg&fields=country&fields=resultlanguagename&fields=resulthostingdatasource&fields=community&fields=country&&fq=resultbestaccessright%20exact%20%22Open%20Access%22&fq=relfunder%20exact%20%22ec__________%3A%3AEC%7C%7CEuropean%20Commission%7C%7CEC%22&type=results&page=0&size=0",
"/resources2/?format=json&refine=true&fields=instancetypename&fields=foslabel&fields=relfunder&fields=sdg&fields=country&fields=resultlanguagename&fields=resulthostingdatasource&fields=community&&type=publications&page=0&size=0",
"/resources2/?format=json&refine=true&fields=instancetypename&fields=foslabel&fields=relfunder&fields=sdg&fields=country&fields=resultlanguagename&fields=resulthostingdatasource&fields=community&&type=datasets&page=0&size=0",
"/resources2/?format=json&refine=true&fields=instancetypename&fields=foslabel&fields=relfunder&fields=sdg&fields=country&fields=resultlanguagename&fields=resulthostingdatasource&fields=community&&type=software&page=0&size=0",
"/resources2/?format=json&refine=true&fields=instancetypename&fields=foslabel&fields=relfunder&fields=sdg&fields=country&fields=resultlanguagename&fields=resulthostingdatasource&fields=community&&type=other&page=0&size=0",
"/resources2/?format=json&refine=true&fields=resultbestaccessright&fields=instancetypename&fields=fos&fields=relfunder&fields=sdg&fields=country&fields=resultlanguagename&fields=resulthostingdatasource&fields=community&&type=publications&page=0&size=0",
"/resources2/?format=json&refine=true&fields=resultbestaccessright&fields=instancetypename&fields=fos&fields=relfunder&fields=sdg&fields=country&fields=resultlanguagename&fields=resulthostingdatasource&fields=community&&type=datasets&page=0&size=0",
"/resources2/?format=json&refine=true&fields=resultbestaccessright&fields=instancetypename&fields=fos&fields=relfunder&fields=sdg&fields=country&fields=resultlanguagename&fields=resulthostingdatasource&fields=community&&type=software&page=0&size=0",
"/resources2/?format=json&refine=true&fields=resultbestaccessright&fields=instancetypename&fields=fos&fields=relfunder&fields=sdg&fields=country&fields=resultlanguagename&fields=resulthostingdatasource&fields=community&&type=other&page=0&size=0",
"/resources2/?format=json&refine=true&fields=instancetypename&fields=foslabel&fields=relfunder&fields=sdg&fields=country&fields=resultlanguagename&fields=resulthostingdatasource&fields=community&&fq=resultbestaccessright%20exact%20%22Open%20Access%22&type=results&page=0&size=0",
"/resources2/?format=json&refine=true&fields=instancetypename&fields=foslabel&fields=relfunder&fields=sdg&fields=country&fields=resultlanguagename&fields=resulthostingdatasource&fields=community&&fq=resultbestaccessright exact \"Open Access\"&type=results&page=0&size=0",
"/resources2/?format=json&refine=true&fields=funder&fields=projectoamandatepublications&fields=projectstartyear&fields=projectendyear&&type=projects&page=0&size=0",
"/resources2/?format=json&refine=true&fields=resultbestaccessright&fields=instancetypename&fields=fos&fields=relfunder&fields=sdg&fields=country&fields=resultlanguagename&fields=resulthostingdatasource&fields=community&&fq=resultbestaccessright%20exact%20%22Open%20Access%22&type=results&page=0&size=0",
"/resources2/?format=json&refine=true&fields=resultbestaccessright&fields=instancetypename&fields=fos&fields=relfunder&fields=sdg&fields=country&fields=resultlanguagename&fields=resulthostingdatasource&fields=community&&fq=resultbestaccessright exact \"Open Access\"&type=results&page=0&size=0",
"/resources2/?format=json&refine=true&fields=funder&fields=projectstartyear&fields=projectendyear&fields=projectoamandatepublications&&type=projects&page=0&size=0",
"/resources2/?format=json&refine=true&fields=eoscdatasourcetype&fields=datasourceodlanguages&fields=datasourceodcontenttypes&fields=datasourcecompatibilityname&fields=country&fields=collectedfromname&fields=datasourcethematic&fields=datasourcejurisdiction&&type=datasources&page=0&size=0",
// "/resources2/?format=json&query= ( (reldatasourcecompatibilityid exact driver or reldatasourcecompatibilityid exact driver-openaire2.0 or reldatasourcecompatibilityid exact openaire2.0 or reldatasourcecompatibilityid exact openaire3.0 or reldatasourcecompatibilityid exact openaire4.0 or reldatasourcecompatibilityid exact openaire-cris_1.1 or reldatasourcecompatibilityid exact openaire2.0_data or reldatasourcecompatibilityid exact hostedBy or relproject=*) ) &refine=true&fields=country&&type=organizations&page=0&size=0",
"/resources2/?format=json&refine=true&fields=country&&type=organizations&fq=(reldatasourcecompatibilityid exact driver or reldatasourcecompatibilityid exact driver-openaire2.0 or reldatasourcecompatibilityid exact openaire2.0 or reldatasourcecompatibilityid exact openaire3.0 or reldatasourcecompatibilityid exact openaire4.0 or reldatasourcecompatibilityid exact openaire-cris_1.1 or reldatasourcecompatibilityid exact openaire2.0_data or reldatasourcecompatibilityid exact hostedBy or relproject=*)&page=0&size=0&minRef=true",
"/resources2/?format=json&query= ( (reldatasourcecompatibilityid exact driver or reldatasourcecompatibilityid exact driver-openaire2.0 or reldatasourcecompatibilityid exact openaire2.0 or reldatasourcecompatibilityid exact openaire3.0 or reldatasourcecompatibilityid exact openaire4.0 or reldatasourcecompatibilityid exact openaire-cris_1.1 or reldatasourcecompatibilityid exact openaire2.0_data or reldatasourcecompatibilityid exact hostedBy or relproject=*) ) &refine=true&fields=country&&type=organizations&page=0&size=0",
"/resources2/?format=json&size=0&type=organizations&fq=(reldatasourcecompatibilityid exact driver or reldatasourcecompatibilityid exact driver-openaire2.0 or reldatasourcecompatibilityid exact openaire2.0 or reldatasourcecompatibilityid exact openaire3.0 or reldatasourcecompatibilityid exact openaire4.0 or reldatasourcecompatibilityid exact openaire-cris_1.1 or reldatasourcecompatibilityid exact openaire2.0_data or reldatasourcecompatibilityid exact hostedBy or relproject=*)",
// "/projects/?format=json&refine=true&page=1&size=0&fields=funder",
"/projects/?fields=funder&sf=funder&format=json&size=0",
"/results/?fields=relfunder&sf=relfunder&format=json&size=0",
"/projects/?format=json&refine=true&page=1&size=0&fields=funder",
"/resources/?format=json&query=( oaftype exact datasource and (eoscdatasourcetype exact \"Journal Archive\" or eoscdatasourcetype exact \"Repository\"))&refine=true&fields=datasourcetypename&fields=country&fields=datasourceodsubjects&fields=datasourceodcontenttypes&fields=datasourcecompatibilityname&fields=datasourcethematic&fields=datasourcejurisdiction&&type=datasources&page=0&size=0",
"/search/v2/api/datasources/count?format=json", "/search/v2/api/publications/count?format=json", "/search/v2/api/datasets/count?format=json", "/search/v2/api/software/count?format=json", "/search/v2/api/other/count?format=json",
"relresulttype%3Dpublication",
"/resources2/?format=json&size=0&type=projects",
"/resources2/?format=json&size=0&type=datasources",
"/resources2/?format=json&size=0&type=results",
"/resources2/?format=json&size=0&type=results&fq=resultbestaccessright%20exact%20%22Open%20Access%22"
"relresulttype%3Dpublication"
];
@ -63,8 +53,7 @@ export class CacheInterceptorService implements HttpInterceptor {
if (!properties.useLongCache) {
return false;
}
if(url.indexOf("sf=") !== -1 || url.indexOf("refine=true") !== -1 || url.indexOf("/count?format=json") !== -1 || url.indexOf("relresulttype%3Dpublication") !== -1 ||
(url.indexOf("?format=json&size=0&type=") !== -1 && url.indexOf("query=") == -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 false;

View File

@ -129,7 +129,7 @@ export class ClaimContextSearchFormComponent {
}
select(communityId, communityLabel) {
// console.log("SELECT", communityId)
console.log("SELECT", communityId)
this.selectedCommunityId = communityId;
this.selectedCommunityLabel = communityLabel;
this.getCategories();

View File

@ -1,7 +1,6 @@
//Classes used in linking / inlinelinking when selecting an entity
import {HelperFunctions} from "../../utils/HelperFunctions.class";
import {OpenaireEntities} from "../../utils/properties/searchFields";
import {ClaimsProperties} from "./claims.properties";
export class ClaimResult {
public source: string;
@ -29,7 +28,6 @@ export class ClaimResult {
export class ClaimProject {
public funderId: string;
public funderShortname: string;
public funderName: string;
public acronym: string;
public startDate: string;
@ -39,12 +37,6 @@ export class ClaimProject {
public fundingLevel0: string;
public url: string;
}
export class ClaimOrganization {
public name: string;
// public shortName: string;
public url: string;
// public country: string;
}
export class ClaimContext {
public community: string;
@ -79,7 +71,6 @@ export class ClaimEntity {
result: ClaimResult;
project: ClaimProject;
context: ClaimContext;
organization: ClaimOrganization;
constructor() {
this.warningMessages = [];
@ -101,7 +92,6 @@ export class ClaimRecord2Insert {
targetAccessRights: string;
targetEmbargoEndDate: string;
claimedInDashboard: string;
idSuffix:string;
constructor() {
@ -125,12 +115,7 @@ export class ClaimDBContext {
title: string;
openaireId: string;
}
export class ClaimDBOrganization {
openaireId: string;
name: string;
shortName: string;
country: string;
}
export class ClaimDBProject {
openaireId: string;
name: string;
@ -190,18 +175,17 @@ export class ShowOptions {
}
initSelectOptions(claimProperties:ClaimsProperties){
initSelectOptions(){
let options =[];
if(this.linkToEntities.indexOf('result')!=-1){
options.push({value: 'result',label: OpenaireEntities.RESULTS})
}
if(this.linkToEntities.indexOf('project')!=-1){
options.push({value: 'project',label: claimProperties.SELECT_ENTITIES.projects})
options.push({value: 'project',label: OpenaireEntities.PROJECTS})
}
if(this.linkToEntities.indexOf('context')!=-1){
options.push({value: 'context',label: OpenaireEntities.COMMUNITIES})
}
this.selectOptions = options;
// console.log(options, claimProperties.SELECT_ENTITIES.projects)
}
}

View File

@ -1,25 +1,69 @@
<div class="uk-width-expand" [ngClass]="centerAlign ? 'uk-align-center':''">
<div class="uk-width-xlarge@l uk-width-large" [ngClass]="centerAlign ? 'uk-align-center':''">
<advanced-search-input (searchEmitter)="search(page,size)">
<div input type="select" [(value)]="showOptions.show" placeholder="Type" hint="Select..."
[options]="showOptions.selectOptions" class="uk-width-medium@xl uk-width-auto"></div>
<div *ngIf="funderOptions && funderOptions.length > 0" input type="select" [(value)]="selectedFunder" placeholder="Funder" hint="Select Funder..."
[options]="funderOptions" class="uk-width-expand" (valueChange)="funderChanged($event)"></div>
<div class="uk-width-expand" input type="text" [(value)]="keyword" [searchable]="true" placeholder="Projects to link"
[hint]="'Search for ' + openaireEntities.PROJECTS + '...'" tooltip="true" [disabled]="isNoProjectFunder"></div>
[options]="showOptions.selectOptions" class="uk-width-2-5"></div>
<div class="uk-width-expand" input type="text" [(value)]="keyword" [searchable]="true" placeholder="Entities to link"
[hint]="'Search for ' + openaireEntities.PROJECTS + '...'" tooltip="true"></div>
</advanced-search-input>
</div>
<div *ngIf=" openaireResultsStatus != errorCodes.LOADING && !isNoProjectFunder && this.selectedFunder && openaireResults.length == 0">
<div *ngIf="!showResults">
<div class="uk-text-center uk-text-large uk-text-meta uk-margin-large-top">No {{openaireEntities.PROJECT.toLowerCase()}} results yet... <br>Start
searching for {{openaireEntities.PROJECTS.toLowerCase()}} to add them in the Basket
</div>
</div>
<div *ngIf=" openaireResultsStatus != errorCodes.LOADING && this.funderOptions.length > 1 && !this.selectedFunder">
<div class="uk-text-center uk-text-large uk-text-meta uk-margin-large-top">Select funder or search for projects to proceed
</div>
</div>
<div class="uk-margin-top">
<div *ngIf="showResults" class="uk-margin-top">
<div class="uk-grid" uk-grid>
<div *ngIf="!isNoProjectFunder && openaireResultsStatus != errorCodes.LOADING && openaireResultsNum > 1 " class="search-filters uk-width-1-1">
<div class="search-filters uk-width-1-1">
<!--<div *ngIf="countFilters()>0 && openaireResultsNum > 0" class="uk-grid uk-flex uk-flex-bottom">
<div class="uk-grid">
<h6 class="uk-text-bold">Filters</h6>
<a *ngIf="countFilters()>1" (click)="clearFilters()"
[class]="((openaireResultsStatus ==
errorCodes.LOADING)?'uk-disabled uk-link-muted':'')+' portal-link '">
Clear All
</a>
</div>
<div *ngIf="countFilters()>0" class="uk-grid uk-grid-small uk-text-small uk-margin-small-top " uk-grid>
<ng-container *ngFor="let filter of rangeFilters " >
<ng-container *ngIf = "filter.selectedFromAndToValues">
<span [title]="'Remove '+ filter.selectedFromAndToValues" (click) = "removeRangeFilter(filter) " >
<span class="selectedFilterLabel ">
<a [class]="((openaireResultsStatus ==
errorCodes.LOADING)?' uk-disabled':' ')+' uk-link-text '">
<span class=" clickable" aria-hidden="true">
<span class="uk-icon">
<svg width="16" height="16" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" icon="close" ratio="0.8"><path fill="none" stroke="#000" stroke-width="1.6" d="M16,16 L4,4"></path><path fill="none" stroke="#000" stroke-width="1.6" d="M16,4 L4,16"></path></svg>
</span>
</span>
<span class="uk-margin-small-left">{{filter.selectedFromAndToValues}}</span>
</a>
</span>
</span>
</ng-container>
</ng-container>
<ng-container *ngFor="let filter of filters " >
<ng-container *ngIf = "filter.countSelectedValues > 0">
<span *ngFor="let value of getSelectedValues(filter); let i = index; let end = last; "
[title]="'Remove '+value.name" (click) = "removeFilter(value, filter) " >
&lt;!&ndash; if no grid on the div above, remove it and move class 'selectedFilterLabel' on top span &ndash;&gt;
<span class="selectedFilterLabel ">
<a [class]="((openaireResultsStatus ==
errorCodes.LOADING)?' uk-disabled':' ')+' uk-link-text '">
<span class=" clickable" aria-hidden="true">
<span class="uk-icon">
<svg width="16" height="16" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" icon="close" ratio="0.8"><path fill="none" stroke="#000" stroke-width="1.6" d="M16,16 L4,4"></path><path fill="none" stroke="#000" stroke-width="1.6" d="M16,4 L4,16"></path></svg>
</span>
</span>
<span class="uk-margin-small-left" [innerHtml]="(value.name.length > 34)?value.name.substring(0,34)+'...':value.name"></span>
</a>
</span>
</span>
</ng-container>
</ng-container>
</div>
</div>-->
<!-- <ng-container *ngIf="openaireResultsNum > 0">-->
<div class="uk-grid uk-grid-small" uk-grid>
<ng-container *ngFor="let filter of rangeFilters">
<div>
@ -60,12 +104,9 @@
role="alert">Service not available
</div>
<div *ngIf="openaireResultsStatus == errorCodes.LOADING" class="uk-animation-fade uk-margin-top uk-width-1-1"
role="alert">
<loading></loading>
</div>
role="alert"><span class="loading-gif uk-align-center"></span></div>
<claim-results [localStoragePrefix]="localStoragePrefix" [results]=openaireResults
[selectedResults]=selectedProjects [basketLimit]="basketLimit"></claim-results>
<div *ngIf="isNoProjectFunder && openaireResultsStatus != errorCodes.LOADING " class="uk-alert uk-alert-default">No projects for funder <span class=" uk-text-bold">{{selectedFunder.name}}</span>. </div>
<div *ngIf="openaireResultsNum != null && openaireResultsNum > 0 && openaireResultsStatus != errorCodes.LOADING " class="uk-flex uk-flex-center ">
<paging-no-load [currentPage]="openaireResultsPage"
[totalResults]="openaireResultsNum" [term]="keyword"

View File

@ -1,4 +1,4 @@
import {Component, ElementRef, EventEmitter, Input, Output, ViewChild} from '@angular/core';
import {Component, ElementRef, EventEmitter, Input, Output} from '@angular/core';
import {SearchProjectsService} from '../../services/searchProjects.service';
import {ProjectService} from '../../landingPages/project/project.service';
import {ClaimEntity, ClaimProject} from './claimHelper.class';
@ -10,7 +10,6 @@ import {RangeFilter} from "../../utils/rangeFilter/rangeFilterHelperClasses.clas
import {OpenaireEntities, SearchFields} from "../../utils/properties/searchFields";
import {NewSearchPageComponent} from "../../searchPages/searchUtils/newSearchPage.component";
import {Subscriber} from "rxjs";
import { properties } from 'src/environments/environment';
declare var UIkit:any;
@ -27,11 +26,12 @@ export class ClaimProjectsSearchFormComponent {
public elementRef;
@Output() projectSelected = new EventEmitter();
public properties:EnvProperties = properties;
@Input() public properties:EnvProperties;
@Input() public inlineClaim:boolean=false;
@Input() localStoragePrefix:string = "";
@Input() basketLimit;
@Input() showOptions;
public errorCodes:ErrorCodes = new ErrorCodes();
public projects:string[];
public warningMessage = "";
@ -53,85 +53,47 @@ export class ClaimProjectsSearchFormComponent {
public rangeFields:string[][] = this.searchFields.PROJECT_RANGE_FIELDS;
openaireEntities = OpenaireEntities;
sub;
selectedFunder = null;
funderOptions = [];
isNoProjectFunder = false;
constructor(private _service: ProjectService, private _projectService: SearchProjectsService, myElement: ElementRef) {
this.elementRef = myElement;
this.rangeFilters = RangeFilter.parse(this.rangeFields,"project");
this.getFunders();
this.rangeFilters = RangeFilter.parse(this.rangeFields,"project");
}
ngOnDestroy() {
if (this.sub instanceof Subscriber) {
this.sub.unsubscribe();
}
}
getFunders(){
this.openaireResultsStatus = this.errorCodes.LOADING;
this.showResults = true;
this.sub = this._projectService.advancedSearchProjects("", 1, 0, this.properties,
this.refineFieldsQuery, this.refineFields, "&type=projects&sf=funder").subscribe(
data => {
let option = {value : null, label: "No funder selected"};
this.funderOptions.push(option);
for(let v of data[2][0].values){
let option = {value : v, label: v.name};
this.funderOptions.push(option);
}
this.openaireResultsStatus = this.errorCodes.DONE;
}, error =>{
this.openaireResultsStatus = this.errorCodes.ERROR;
})
}
funderChanged(value){
this.keyword = ""
this.selectedFunder = value;
this.isNoProjectFunder = this.selectedFunder && this.selectedFunder.number == 1;
this.openaireResults = [];
if(this.isNoProjectFunder){
this.showResults = true;
this.search(1,1);
}else{
this.openaireResults = [];
}
}
search(page,size) {
/* if (this.keyword.length == 0) {
this.showResults = false;
if(this.keyword.length == 0){
this.showResults =false;
return;
}*/
this.showResults = true;
}
this.showResults =true;
this.openaireResults = [];
this.openaireResultsStatus = this.errorCodes.LOADING;
this.prevFilters = this.filters;
//searchProjects (params: string, refineParams:string, page: number, size: number, refineFields:string[] , properties:EnvProperties ):any {
this.sub = this._projectService.advancedSearchProjects(this.createOpenaireQueryParams(), page, size, this.properties, this.createOpenaireRefineQuery(), [], null).subscribe(
// this.sub = this._projectService.searchProjects(this.createOpenaireQueryParams(),(page==1)? this.refineFieldsQuery:null, page, size, (page==1)?this.refineFields:[], this.properties).subscribe(
this.sub = this._projectService.searchProjects(this.createOpenaireQueryParams(),(page==1)? this.refineFieldsQuery:null, page, size, (page==1)?this.refineFields:[], this.properties).subscribe(
data => {
if (data != null) {
this.openaireResultsPage = page;
this.openaireResultsNum = data[0];
this.openaireResults = ClaimProjectsSearchFormComponent.openaire2ClaimEntity(data[1], this.properties);
if (data[2] && data[2].length > 0) {
this.filters = this.checkSelectedFilters(data[2], this.prevFilters);
}
if(data != null) {
this.openaireResultsPage=page;
this.openaireResultsNum = data[0];
this.openaireResults =ClaimProjectsSearchFormComponent.openaire2ClaimEntity(data[1], this.properties);
if(data[2] && data[2].length > 0){
this.filters = this.checkSelectedFilters( data[2], this.prevFilters);
}
this.openaireResultsStatus = this.errorCodes.DONE;
if (this.openaireResultsNum == 0) {
this.openaireResultsStatus = this.errorCodes.NONE;
this.filters = this.checkSelectedFilters([], this.prevFilters);
this.openaireResultsStatus = this.errorCodes.DONE;
if(this.openaireResultsNum == 0){
this.openaireResultsStatus = this.errorCodes.NONE;
this.filters = this.checkSelectedFilters( [], this.prevFilters);
}
}else {
this.openaireResultsStatus = this.errorCodes.ERROR;
}
/* if(this.isNoProjectFunder && this.claimResultsComponent){
this.claimResultsComponent.add(this.openaireResults[0])
}*/
} else {
this.openaireResultsStatus = this.errorCodes.ERROR;
}
},
},
err => {
this.openaireResultsStatus = this.errorCodes.ERROR;
//console.log(err.status);
@ -139,23 +101,85 @@ export class ClaimProjectsSearchFormComponent {
}
);
}
remove(item){
// select(entity){
// if(this.selectedProjects.length > 50){
// UIkit.notification({
// message : 'Your basket exceeds the number of allowed projects (50)',
// status : 'warning',
// timeout : 1500,
// pos : 'top-center'
// });
// return;
// }
// this.query = "";
// // this.searchTermStream.next(this.query); //clear
// entity = entity.value;
// // var project: ClaimProject = new ClaimProject();
// // project.funderId = entity.funderId;
// // project.funderName = entity.funderName;
// // project.id = entity.id;
// // project.projectName = entity.projectName;
// // project.projectAcronym = entity.projectAcronym;
// // project.startDate = entity.startDate;
// // project.endDate = entity.endDate;
// // project.code = entity.code;
// // project.jurisdiction = entity.jurisdiction;
// // project.fundingLevel0 = entity.fundingLevel0;
//
//
// var index:number =this.selectedProjects.indexOf(entity);
// var found:boolean = false;
// this.warningMessage = "";
//
// for (var _i = 0; _i < this.selectedProjects.length; _i++) {
// let project = this.selectedProjects[_i];
// if(entity.id == project.id){
// found=true;
// this.warningMessage = "Project already in your basket";
// }
// }
//
// if (!found) {
// this.selectedProjects.push(entity);
// if(this.selectedProjects != null){
// localStorage.setItem(this.localStoragePrefix + "projects", JSON.stringify(this.selectedProjects));
// }
// this.projectSelected.emit({
// value: true
// });
//
// }
// }
/* static showItem(item):string{
return ((item.field[1]['@value'])?item.field[1]['@value']+" - ":"" ) + item.field[3]['@value'];
}*/
remove(item){
let index:number =this.selectedProjects.indexOf(item);
if (index > -1) {
this.selectedProjects.splice(index, 1);
}
}
static openaire2ClaimEntity(items, properties:EnvProperties){
/* handleClick(event){
var clickedComponent = event.target;
var inside = false;
do {
if (clickedComponent === this.elementRef.nativeElement) {
inside = true;
}
clickedComponent = clickedComponent.parentNode;
} while (clickedComponent);
}*/
static openaire2ClaimEntity(items, properties:EnvProperties){
const projects: ClaimEntity[] = [];
for(const item of items){
const entity: ClaimEntity = new ClaimEntity();
entity.project = new ClaimProject();
entity.project.funderId = item.funderId;
entity.project.funderShortname = item.funderShortname?item.funderShortname:(entity.project.funderId?entity.project.funderId.split("::")[1]:"");
entity.project.funderName = item.funderName;
entity.project.funderName = item.funderShortname;
entity.id = item.id;
entity.project.url = (item.code !="unidentified") ? properties.searchLinkToProject + entity.id : null;
entity.project.url = properties.searchLinkToProject + entity.id;
entity.title = item.title.name;
entity.project.acronym = item.acronym;
entity.project.startDate = item.startYear;
@ -178,47 +202,43 @@ export class ClaimProjectsSearchFormComponent {
}
createOpenaireQueryParams(): string {
createOpenaireQueryParams():string {
let query = "";
if (this.keyword.length > 0) {
// query += "q=" + StringUtils.quote(StringUtils.URIEncode(this.keyword));
query += StringUtils.quote(StringUtils.URIEncode(this.keyword));
if(this.keyword.length > 0){
query += "q=" + StringUtils.quote(StringUtils.URIEncode(this.keyword));
}
return query;
}
createOpenaireRefineQuery(): string {
/*if(this.startYear.length > 0 ){
query+='&fq=projectstartyear exact \"'+this.startYear+'\"'
}
if(this.endYear.length > 0 ){
query+='&fq=projectendyear exact \"'+this.endYear+'\"'
}*/
let allFqs = "";
for (let filter of this.filters) {
if (filter.countSelectedValues > 0) {
let count_selected = 0;
for (let filter of this.filters){
if(filter.countSelectedValues > 0){
let count_selected=0;
let fq = "";
for (let value of filter.values) {
if (value.selected == true) {
for (let value of filter.values){
if(value.selected == true){
count_selected++;
fq += (fq.length > 0 ? " " + filter.filterOperator + " " : "") + filter.filterId + " exact " + (StringUtils.quote(value.id));
fq+=(fq.length > 0 ? " " + filter.filterOperator + " ":"" ) + filter.filterId + " exact " + (StringUtils.quote(value.id));
}
}
if (count_selected > 0) {
fq = "&fq=" + StringUtils.URIEncode(fq);
if(count_selected > 0){
fq="&fq="+StringUtils.URIEncode(fq);
allFqs += fq;
}
}
}
if(this.selectedFunder){
allFqs += "&fq=" + StringUtils.URIEncode( "funder exact " + (StringUtils.quote(this.selectedFunder.id)));
}
if(!this.isNoProjectFunder || !this.selectedFunder){
allFqs += '&fq=(projectcode<>"unidentified")'
}
for (let i = 0; i < this.rangeFilters.length; i++) {
for (let i=0; i<this.rangeFilters.length; i++){
let filter = this.rangeFilters[i];
//selectedFromValue, selectedToValue, equalityOp, equalityOpFrom, equalityOpTo, filterOp ){
allFqs += NewSearchPageComponent.createRangeFilterQuery(this.rangeFields[i], filter.selectedFromValue, filter.selectedToValue, " within ", ">=", "<=", "and")
allFqs+= NewSearchPageComponent.createRangeFilterQuery(this.rangeFields[i],filter.selectedFromValue, filter.selectedToValue, " within ", ">=" ,"<=", "and" )
}
return allFqs + "&type=projects";
}
return query+allFqs;
}
public yearChanged() {
this.search(this.page, this.size);
@ -253,21 +273,20 @@ export class ClaimProjectsSearchFormComponent {
}
}
filter.countAllValues = filter.values.length;
}
if(filters.length == 0 ){
for(let j=0; j< prevFilters.length ; j++) {
let filter = Object.assign({}, prevFilters[j]);
filter.values = [];
for (let filterValue of prevFilters[j].values) {
if (filterValue.selected) {
filterValue.number = 0;
filter.values.push(filterValue);
for(let j=0; j< prevFilters.length ; j++){
let filter = Object.assign({}, prevFilters[j]);
filter.values = [];
for(let filterValue of prevFilters[j].values) {
if(filterValue.selected){
filterValue.number = 0;
filter.values.push(filterValue);
}
}
filters.push(filter)
}
}
filter.countAllValues = filter.values.length;
filters.push(filter)
}
}
return filters;
}

View File

@ -17,15 +17,14 @@ import {RangeFilterModule} from "../../utils/rangeFilter/rangeFilter.module";
import {AdvancedSearchInputModule} from "../../sharedComponents/advanced-search-input/advanced-search-input.module";
import {InputModule} from "../../sharedComponents/input/input.module";
import {DropdownFilterModule} from "../../utils/dropdown-filter/dropdown-filter.module";
import {LoadingModule} from "../../utils/loading/loading.module";
@NgModule({
imports: [
SharedModule, CommonModule,
// LoadingModalModule,
ProjectServiceModule, ProjectsServiceModule, EntitiesAutocompleteModule, HelperModule,
PagingModule, SearchFilterModule, ClaimResultsModule, RangeFilterModule, AdvancedSearchInputModule, InputModule, DropdownFilterModule, LoadingModule
],
imports: [
SharedModule, CommonModule,
// LoadingModalModule,
ProjectServiceModule, ProjectsServiceModule, EntitiesAutocompleteModule, HelperModule,
PagingModule, SearchFilterModule, ClaimResultsModule, RangeFilterModule, AdvancedSearchInputModule, InputModule, DropdownFilterModule
],
providers:[
],
declarations: [

View File

@ -1,16 +1,14 @@
<div class="uk-flex uk-flex-center uk-flex-left@m">
<div *ngIf="showOptions && showOptions.linkToEntities.length > 0" class="uk-width-xlarge@l uk-width-large" [ngClass]="centerAlign ? 'uk-align-center':''">
<advanced-search-input (searchEmitter)="search(true)">
<div input type="select" [(value)]="showOptions.show" placeholder="Type" hint="Select..."
[options]="showOptions.selectOptions" class="uk-width-2-5"></div>
<div class="uk-width-expand" input type="text" [(value)]="keyword" [searchable]="true" placeholder="Entities to link"
[hint]="'Search for ' + openaireEntities.RESULTS.toLowerCase() + '...'" tooltip="true"></div>
</advanced-search-input>
</div>
<div *ngIf="!showOptions" class="uk-width-xlarge@l uk-width-large">
<div search-input [(value)]="keyword" [placeholder]="'Search for ' + openaireEntities.RESULTS.toLowerCase() + '...'"
[searchInputClass]="'inner background'" (searchEmitter)="search(true)"></div>
</div>
<div *ngIf="showOptions && showOptions.linkToEntities.length > 0" class="uk-width-xlarge@l uk-width-large" [ngClass]="centerAlign ? 'uk-align-center':''">
<advanced-search-input (searchEmitter)="search(true)">
<div input type="select" [(value)]="showOptions.show" placeholder="Type" hint="Select..."
[options]="showOptions.selectOptions" class="uk-width-2-5"></div>
<div class="uk-width-expand" input type="text" [(value)]="keyword" [searchable]="true" placeholder="Entities to link"
[hint]="'Search for ' + openaireEntities.RESULTS.toLowerCase() + '...'" tooltip="true"></div>
</advanced-search-input>
</div>
<div *ngIf="!showOptions" class="uk-width-xlarge@l uk-width-large">
<div search-input [(value)]="keyword" [placeholder]="'Search for ' + openaireEntities.RESULTS.toLowerCase() + '...'"
[searchInputClass]="'inner background'" (searchEmitter)="search(true)"></div>
</div>
<div *ngIf="!showSearchResults">
<div class="uk-text-center uk-text-large uk-text-meta uk-margin-large-top">
@ -51,9 +49,7 @@
</div>
</div>
<div *ngIf="crossrefStatus === errorCodes.LOADING" class="uk-animation-fade uk-margin-top uk-width-1-1"
role="alert">
<loading></loading>
</div>
role="alert"><span class="loading-gif uk-align-center"></span></div>
<div>
<claim-results [localStoragePrefix]=localStoragePrefix [results]=crossrefResults
@ -116,7 +112,7 @@
<div *ngIf="openaireResultsStatus === errorCodes.LOADING"
class="uk-animation-fade uk-margin-top uk-width-1-1"
role="alert"><loading></loading></div>
role="alert"><span class="loading-gif uk-align-center">Loading...</span></div>
<claim-results [localStoragePrefix]=localStoragePrefix
[results]=openaireResults [selectedResults]=selectedResults [basketLimit]="basketLimit"></claim-results>
<div class="uk-flex uk-flex-center" *ngIf=" openaireResultsStatus != errorCodes.LOADING && openaireResultsNum != null && openaireResultsNum > 0" >
@ -179,7 +175,7 @@
</div>
</div>
<div *ngIf="orcidStatus == errorCodes.LOADING" class="uk-animation-fade uk-margin-top uk-width-1-1" role="alert">
<loading></loading></div>
<span class="loading-gif uk-align-center"></span></div>
</div>
</div>
<div *ngIf="activeTab == 'datacite'" id="datacite" class="uk-animation-fade">
@ -192,7 +188,7 @@
<div class="uk-margin-top">
<div *ngIf="dataciteStatus == errorCodes.LOADING" class="uk-animation-fade uk-margin-top uk-width-1-1"
role="alert"><loading></loading></div>
role="alert"><span class="loading-gif uk-align-center"></span></div>
<div>
<claim-results [localStoragePrefix]=localStoragePrefix *ngIf="dataciteResults.length > 0 "
[results]=dataciteResults [selectedResults]=selectedResults [basketLimit]="basketLimit"></claim-results>

View File

@ -865,7 +865,7 @@ export class ClaimResultSearchFormComponent {
}
}
filter.countAllValues = filter.values.length;
}
return filters;
}

View File

@ -22,11 +22,10 @@ import {AdvancedSearchInputModule} from "../../sharedComponents/advanced-search-
import {InputModule} from "../../sharedComponents/input/input.module";
import {SearchInputModule} from "../../sharedComponents/search-input/search-input.module";
import {DropdownFilterModule} from "../../utils/dropdown-filter/dropdown-filter.module";
import {LoadingModule} from "../../utils/loading/loading.module";
@NgModule({
imports: [SharedModule, CommonModule, SearchResearchResultsServiceModule, PagingModule, SearchCrossrefServiceModule,
SearchDataciteServiceModule, HelperModule, SearchFilterModule, ClaimResultsModule, MatSelectModule, QuickSelectionsModule, RangeFilterModule, ClaimProjectsSearchFormModule, AdvancedSearchInputModule, InputModule, SearchInputModule, DropdownFilterModule, LoadingModule],
SearchDataciteServiceModule, HelperModule, SearchFilterModule, ClaimResultsModule, MatSelectModule, QuickSelectionsModule, RangeFilterModule, ClaimProjectsSearchFormModule, AdvancedSearchInputModule, InputModule, SearchInputModule, DropdownFilterModule],
providers:[
SearchOrcidService
],

View File

@ -1,23 +0,0 @@
export class ClaimsProperties{
ALLOW_ORGANIZATION_LINKING:boolean = false;
SELECT_ENTITIES = {
projects:"Funding"
}
INLINE_ENTITY = {
show: true,
guideText : null
}
BASKET ={
source_title: "Source",
target_title: "Link source to"
}
METADATA_PREVIEW ={
source_title: "Source",
target_title: "Link to",
edit_source_title: "Edit",
edit_target_title: "Edit",
edit_target_icon: "edit"
}
}

View File

@ -1,27 +1,25 @@
<schema2jsonld *ngIf="url" [URL]="url" [name]="pageTitle" type="other"></schema2jsonld>
<div class="uk-grid">
<div class="uk-width-expand uk-position-relative uk-margin-small-top">
<div class="uk-width-expand uk-position-relative">
<helper *ngIf="pageContents && pageContents['top'] && pageContents['top'].length > 0"
[texts]="pageContents['top']"></helper>
<div *ngIf="filterForm" [id]="actions?'page_content_actions':null" [class.uk-blur-background]="actions" [attr.uk-sticky]="(actions)?'media: @m':null" [attr.offset]="offset">
<div [class.uk-padding-small]="actions" class="uk-padding-remove-vertical">
<div class="uk-section-xsmall">
<div class="uk-flex uk-flex-right@m uk-flex-center uk-flex-wrap uk-flex-middle">
<div search-input [disabled]="loading" [searchControl]="filterForm.controls.keyword" searchInputClass="outer"
placeholder="Search links" class="uk-width-1-3@xl uk-width-2-5@l uk-width-1-2@m uk-width-1-1"
(searchEmitter)="changeKeyword()" [expandable]="true"></div>
</div>
</div>
</div>
</div>
<div [class.uk-padding]="actions" class="uk-padding-remove-vertical">
<div class="uk-margin-small-top">
<div class="uk-margin-medium-top">
<results-and-pages [type]="resultsNum !== 1?'Links':'Link'" [page]="page" [pageSize]="size" [hasSearch]="true" [searchTerm]="keyword"
[totalResults]="resultsNum" customClasses="uk-margin-remove"></results-and-pages>
</div>
<div class="uk-grid uk-flex-middle uk-margin-small-top" uk-grid>
<div *ngIf="fetchBy != 'User' && properties.environment == 'development'" >
<input [(ngModel)]="mine" [checked]="mine" (ngModelChange)="goTo(1)" type="checkbox" class="uk-checkbox"> Mine
</div>
<div class="uk-grid uk-flex-middle uk-margin-medium-top" uk-grid>
<div>
<dropdown-filter #dropdownFilter dropdownClass="uk-width-medium uk-padding-small"
name="Type of Entity" [disabled]="loading" [count]="entities.length">
@ -45,7 +43,6 @@
type="select" [options]="sortOptions">
</div>
</div>
<div class="uk-width-expand@l uk-width-1-1 uk-flex uk-flex-right@m uk-flex-center">
<paging-no-load [currentPage]="page" [totalResults]="resultsNum" [size]="size"
[loading]="false" (pageChange)="pageChange($event)"></paging-no-load>
@ -59,76 +56,57 @@
<div *ngIf="claims && claims.length == 0" class="uk-card uk-card-default uk-padding-large uk-text-center uk-margin-bottom uk-text-bold">
<div>No links found</div>
</div>
<ng-container *ngIf="claims && claims.length > 0">
<div class="uk-flex uk-flex-middle uk-margin-top uk-margin-small-bottom uk-padding-small uk-padding-remove-horizontal">
<div class="uk-width-xsmall uk-flex uk-flex-center uk-flex-middle">
<label>
<input id="checkAll" type="checkbox" (click)="selectAll($event)" class="uk-checkbox" title="Select All"
[ngModel]="selected.length == claims.length"/>
</label>
</div>
<button class="uk-button uk-button-link" [class.uk-disabled]="selected.length == 0" [disabled]="selected.length == 0"
(click)="deleteOpen()">
<span>Delete ({{selected.length}})</span>
</button>
</div>
<ul class="uk-margin-small-top uk-list uk-list-striped">
<li *ngFor="let claim of claims; let i=index" class="uk-flex uk-flex-middle uk-padding-small uk-padding-remove-horizontal">
<div class="uk-width-xsmall uk-flex uk-flex-center uk-flex-middle">
<input type="checkbox" class="uk-checkbox"
[id]="claim.id" (click)="selectClaim(claim, $event)" [ngModel]="isSelectedClaim(claim.id)">
</div>
<div class="uk-width-expand">
<div class="uk-grid uk-grid-small uk-flex-middle" uk-grid>
<div class="uk-width-expand">
<div class="uk-margin-small-bottom">
<claim-entity [entity]="claim.target" [type]="claim.targetType" [properties]=properties
[externalPortalUrl]=externalPortalUrl [source]="true" [linkAvailable]="isClaimAvailable(claim)"></claim-entity>
</div>
<div class="uk-margin-small-bottom">
<span *ngIf="isClaimAvailable(claim) else notAvailable" class="uk-label uk-label-small uk-label-success"
[attr.uk-tooltip]="'title: The link information is available in the portal and the APIs.'">available</span>
<ng-template #notAvailable>
<span class="uk-label uk-label-small uk-label-danger"
[attr.uk-tooltip]="'title:The link information will be added in the portal and the APIs in the next content provision workflow.'">pending</span>
</ng-template>
</div>
<div class="uk-text-small">
<div *ngIf="showUserEmail" class="uk-margin-xsmall-bottom">
<span class="uk-text-meta">Claimed by:</span>
<span class="uk-margin-xsmall-left">{{claim.userMail}}</span>
</div>
<div>
<span class="uk-text-meta">Claimed date:</span>
<span class="uk-margin-xsmall-left">{{claim.date}}</span>
</div>
</div>
<ul class="uk-margin-small-top uk-list uk-list-xlarge">
<li *ngFor="let claim of claims; let i=index" class="uk-card uk-card-default">
<div class="uk-card-body">
<div class="uk-grid uk-grid-small" uk-grid>
<div class="uk-width-expand">
<div class="uk-margin-bottom">
<claim-entity [entity]="claim.target" [type]="claim.targetType" [properties]=properties
[externalPortalUrl]=externalPortalUrl [source]="true"></claim-entity>
</div>
<div class="uk-visible@m">
<div class="claim-divider">
<icon class="uk-position-center" name="link" customClass="uk-text-primary" ratio="2" [flex]="true"></icon>
</div>
<div class="uk-margin-bottom">
<span *ngIf="isClaimAvailable(claim) else notAvailable" class="uk-label uk-label-success"
[attr.uk-tooltip]="'title: The link information is available in the portal and the APIs.'">available</span>
<ng-template #notAvailable>
<span class="uk-label uk-label-danger"
[attr.uk-tooltip]="'title:The link information will be added in the portal and the APIs in the next content provision workflow.'">pending</span>
</ng-template>
</div>
<div class="uk-width-1-2@m uk-width-1-1">
<claim-entity [entity]="claim.source" [type]="claim.sourceType" [source]="false" [properties]=properties
[externalPortalUrl]=externalPortalUrl></claim-entity>
<div class="uk-text-small">
<div *ngIf="showUserEmail" class="uk-margin-small-bottom">
<span class="uk-text-meta">Claimed by:</span>
<span class="uk-margin-xsmall-left">{{claim.userMail}}</span>
</div>
<div>
<span class="uk-text-meta">Claimed date:</span>
<span class="uk-margin-xsmall-left">{{claim.date}}</span>
</div>
</div>
</div>
<div class="uk-visible@m">
<div class="claim-divider">
<icon class="uk-position-center" name="link" customClass="uk-text-primary" ratio="2" [flex]="true"></icon>
</div>
</div>
<div class="uk-width-1-2@m uk-width-1-1 uk-flex uk-flex-column uk-flex-center">
<claim-entity [entity]="claim.source" [type]="claim.sourceType" [source]="false" [properties]=properties
[externalPortalUrl]=externalPortalUrl></claim-entity>
</div>
</div>
<div class="uk-width-xsmall uk-flex uk-flex-center uk-flex-middle">
<button class="uk-button uk-button-link uk-flex uk-flex-middle" (click)="deleteOpen(i)">
<icon name="delete" [flex]="true"></icon>
</button>
</div>
</li>
</ul>
<div class="uk-margin-medium-top uk-flex uk-flex-center uk-flex-right@m">
<paging-no-load *ngIf="resultsNum" [currentPage]="page" [totalResults]="resultsNum" [size]="size"
(pageChange)="pageChange($event)"></paging-no-load>
</div>
</ng-container>
</div>
<div class="uk-card-footer uk-flex uk-flex-right">
<button class="uk-button uk-button-link uk-flex uk-flex-middle" (click)="deleteOpen(i)">
<icon name="delete" [flex]="true"></icon>
<span class="uk-margin-xsmall-left">Delete</span>
</button>
</div>
</li>
</ul>
<div class="uk-margin-medium-top uk-flex uk-flex-center uk-flex-right@m">
<paging-no-load *ngIf="resultsNum" [currentPage]="page" [totalResults]="resultsNum" [size]="size"
(pageChange)="pageChange($event)"></paging-no-load>
</div>
</div>
</div>
</div>

View File

@ -4,4 +4,14 @@
position: relative;
padding: 0 20px;
height: 100%;
&::before {
content: '';
position: absolute;
top: 0;
left: 50%;
right: 0;
bottom: 0;
border-left: @global-border-width solid @global-border;
}
}

View File

@ -40,7 +40,7 @@ export class DisplayClaimsComponent implements OnInit, OnDestroy {
page: number = 1;
size: number = 50;
keyword: string; // the keyword string to give to the request as parameter
types = ["All", "Project", "Context", "Result", "User", "Organization"];
types = ["All", "Project", "Context", "Result", "User"];
loading: boolean = false;
@Input() fetchBy: string;
@Input() fetchId: string;
@ -52,8 +52,6 @@ export class DisplayClaimsComponent implements OnInit, OnDestroy {
lastIndexDate = null;
public filterForm: FormGroup;
public entities: string[] = [];
selected = [];
mine = false;
allOptions: Option[] = [
{label: OpenaireEntities.PUBLICATIONS, value: "publication"},
@ -112,12 +110,10 @@ export class DisplayClaimsComponent implements OnInit, OnDestroy {
this.updateDescription(description);
this.updateUrl(this.url);
this.subscriptions.push(this._piwikService.trackView(this.properties, this.pageTitle).subscribe());
if(properties.adminToolsPortalType !== "explore") {
this.subscriptions.push(this.helper.getPageHelpContents(this.properties, this.communityId, this._router.url).subscribe(contents => {
this.pageContents = contents;
}));
}
this.subscriptions.push(this.helper.getPageHelpContents(this.properties, this.communityId, this._router.url).subscribe(contents => {
this.pageContents = contents;
}));
this.subscriptions.push(this.indexInfoService.getLastIndexDate(this.properties).subscribe(res => {
this.lastIndexDate = res;
}));
@ -134,7 +130,6 @@ export class DisplayClaimsComponent implements OnInit, OnDestroy {
this.fetchId = this.fetchId ? this.fetchId : '';
}
let page = (params['page'] === undefined) ? 1 : +params['page'];
this.mine = (params['mine'] == 'true' ? true:false);
this.keyword = (params['keyword'] ? params['keyword'] : "");
this.filterForm.get('keyword').setValue(this.keyword);
this.page = (page <= 0) ? 1 : page;
@ -188,16 +183,6 @@ export class DisplayClaimsComponent implements OnInit, OnDestroy {
this.handleErrors(err, "Error getting claims for project with id: " + this.fetchId);
}
);
} else if (this.fetchBy == "Organization") {
this.subResults = this._claimService.getClaimsByOrganization(this.size, this.page, this.fetchId, this.keyword, this.filterForm.get("sort").value.sort, this.filterForm.get("sort").value.descending, types, this.properties.claimsAPIURL, this.mine).subscribe(
data => {
this.manageAPIData(data);
this.loading = false;
},
err => {
this.handleErrors(err, "Error getting claims for project with id: " + this.fetchId);
}
);
} else if (this.fetchBy == "User") {
this.subResults = this._claimService.getClaimsByUser(this.size, this.page, this.fetchId, this.keyword, this.filterForm.get("sort").value.sort, this.filterForm.get("sort").value.descending, types, this.properties.claimsAPIURL).subscribe(
data => {
@ -221,7 +206,7 @@ export class DisplayClaimsComponent implements OnInit, OnDestroy {
}
);
} else if (this.fetchBy == "Context") {
this.subResults = this._claimService.getClaimsBycontext(this.size, this.page, this.fetchId, this.keyword, this.filterForm.get("sort").value.sort, this.filterForm.get("sort").value.descending, types, this.properties.claimsAPIURL, this.mine).subscribe(
this.subResults = this._claimService.getClaimsBycontext(this.size, this.page, this.fetchId, this.keyword, this.filterForm.get("sort").value.sort, this.filterForm.get("sort").value.descending, types, this.properties.claimsAPIURL).subscribe(
data => {
this.manageAPIData(data);
this.loading = false;
@ -232,7 +217,7 @@ export class DisplayClaimsComponent implements OnInit, OnDestroy {
}
);
} else {
this.subResults = this._claimService.getClaims(this.size, this.page, this.keyword, this.filterForm.get("sort").value.sort, this.filterForm.get("sort").value.descending, types, this.properties.claimsAPIURL, this.mine).subscribe(
this.subResults = this._claimService.getClaims(this.size, this.page, this.keyword, this.filterForm.get("sort").value.sort, this.filterForm.get("sort").value.descending, types, this.properties.claimsAPIURL).subscribe(
data => {
this.manageAPIData(data);
this.loading = false;
@ -271,8 +256,15 @@ export class DisplayClaimsComponent implements OnInit, OnDestroy {
types += (types.length > 0 ? ',' : '') + type;
}
params += (this.entities.length > 0) ? (params.length > 0 ? '&' : '') + "types=" + types : "";
if (this.isAdmin) {
params += (this.fetchBy == 'All' ? "" : (params.length > 0 ? '&' : '') + "fetchBy=" + this.fetchBy);
params += (this.fetchId == '' ? "" : (params.length > 0 ? '&' : '') + "fetchId=" + this.fetchId);
}
params += (this.filterForm.get("sort").value.sort == 'date' && this.filterForm.get("sort").value.descending ? "" : (params.length > 0 ? '&' : '') + "sort=" + this.filterForm.get("sort").value.sort + "-" + this.filterForm.get("sort").value.descending);
params += (this.keyword == '' ? "" : (params.length > 0 ? '&' : '') + "keyword=" + this.keyword);
if (this.communityId != null) {
params += "&communityId=" + this.communityId;
}
return params;
}
@ -316,34 +308,23 @@ export class DisplayClaimsComponent implements OnInit, OnDestroy {
}
isSelected(value: string) {
return this.filterForm && this.filterForm.get('entities').value.find(entity => entity === value);
return this.filterForm && this.filterForm.get('entities').value.find(entity => entity === value)
}
deleteOpen(index: number = null) {
deleteOpen(index: number) {
this.index = index;
this.deleteModal.alertTitle = 'Delete Confirmation';
this.deleteModal.message = 'Are you sure you want to delete ' + (this.index != null ? '1' : this.selected.length) + ' link(s)?';
this.deleteModal.message = 'Are you sure you want to delete this link?';
this.deleteModal.okButtonText = 'Yes';
this.deleteModal.open();
}
delete() {
let claimsToBeDeleted = ((this.index != null) ? [this.claims[this.index].id] : this.selected.map(claim => claim.id));
// console.log(claimsToBeDeleted);
this.subscriptions.push(this._claimService.deleteBulk(claimsToBeDeleted, this.properties.claimsAPIURL).subscribe(
this.subscriptions.push(this._claimService.deleteBulk([this.claims[this.index].id], this.properties.claimsAPIURL).subscribe(
res => {
if (this.index != null) {
this.claims.splice(this.index, 1);
this.resultsNum = this.resultsNum - 1;
NotificationHandler.rise('Link has been deleted successfully');
} else {
claimsToBeDeleted.forEach(claimId => {
this.claims.splice(this.claims.findIndex((id) => id == claimId), 1);
});
this.resultsNum = this.resultsNum - claimsToBeDeleted.length;
NotificationHandler.rise(claimsToBeDeleted.length + ' links have been deleted successfully');
}
this.selected = [];
this.claims.splice(this.index, 1);
this.resultsNum = this.resultsNum - 1;
NotificationHandler.rise('Link has been deleted successfully');
let goToPage = this.page;
if (this.totalPages(this.resultsNum) < this.page && this.page > 0) {
goToPage = this.page - 1;
@ -351,8 +332,7 @@ export class DisplayClaimsComponent implements OnInit, OnDestroy {
this.goTo(goToPage);
}, err => {
this.handleErrors(err, "Error deleting claim with id: " + this.claims[this.index].id);
}
));
}));
}
pageChange($event) {
@ -369,7 +349,7 @@ export class DisplayClaimsComponent implements OnInit, OnDestroy {
if (claimDateStr < lastUpdateDateStr) {
return true;
} else {
return claim.target.collectedFrom != "infrastruct_::openaire";
return claim.target.collectedFrom != "infrastruct_::openaire" && claim.indexed;
}
}
@ -380,44 +360,7 @@ export class DisplayClaimsComponent implements OnInit, OnDestroy {
}
return totalPages;
}
selectClaim(item: any, event) {
let value = event.currentTarget.checked;
if (value) {
this.selected.push(item);
} else {
for (var _i = 0; _i < this.selected.length; _i++) {
let claim = this.selected[_i];
if (claim['id'] == item.id) {
this.selected.splice(_i, 1);
}
}
}
}
selectAll(event) {
let value = event.currentTarget.checked;
if (value) {
this.selected = [];
for (let _i = 0; _i < this.claims.length; _i++) {
let claim = this.claims[_i];
this.selected.push(claim);
}
} else {
this.selected = [];
}
}
isSelectedClaim(id: string) {
for (let _i = 0; _i < this.selected.length; _i++) {
let claim = this.selected[_i];
if (claim['id'] == id) {
return true;
}
}
return false;
}
private updateDescription(description: string) {
this._meta.updateTag({content: description}, "name='description'");
this._meta.updateTag({content: description}, "property='og:description'");

View File

@ -17,6 +17,7 @@ import {HelperModule} from '../../../utils/helper/helper.module';
import {Schema2jsonldModule} from '../../../sharedComponents/schema2jsonld/schema2jsonld.module';
import { SEOServiceModule } from '../../../sharedComponents/SEO/SEOService.module';
import {IndexInfoServiceModule} from "../../../utils/indexInfoService.module";
import {PiwikServiceModule} from "../../../utils/piwik/piwikService.module";
import {SearchInputModule} from '../../../sharedComponents/search-input/search-input.module';
import {InputModule} from '../../../sharedComponents/input/input.module';
import {LoadingModule} from '../../../utils/loading/loading.module';
@ -29,7 +30,7 @@ import {link} from "../../../utils/icons/icons";
@NgModule({
imports: [
CommonModule, FormsModule, RouterModule, ClaimServiceModule, LoadingModalModule, AlertModalModule,
ClaimEntityFormatterModule, PagingModule, HelperModule, Schema2jsonldModule, SEOServiceModule,
ClaimEntityFormatterModule, PagingModule, HelperModule, Schema2jsonldModule, SEOServiceModule, PiwikServiceModule,
IndexInfoServiceModule, MatSelectModule, SearchInputModule, MatAutocompleteModule, MatChipsModule, MatFormFieldModule, MatSlideToggleModule, InputModule, LoadingModule, NoLoadPaging, IconsModule, DropdownFilterModule
],

View File

@ -1,6 +1,6 @@
import {Component, Input} from '@angular/core';
import {EnvProperties} from '../../../utils/properties/env-properties';
import {ClaimDBContext, ClaimDBOrganization, ClaimDBProject, ClaimDBResult} from "../claimHelper.class";
import {ClaimDBContext, ClaimDBProject, ClaimDBResult} from "../claimHelper.class";
import {OpenaireEntities} from "../../../utils/properties/searchFields";
import {StringUtils} from "../../../utils/string-utils.class";
@ -15,37 +15,31 @@ import {StringUtils} from "../../../utils/string-utils.class";
<div *ngIf="source" class="uk-text-small">
{{getEntityName(type)}}
</div>
<div>
<span *ngIf="!source" class="uk-text-meta uk-text-small uk-margin-small-right uk-text-nowrap">Link to:</span>
<div class="uk-flex">
<span *ngIf="!source" class="uk-text-meta uk-margin-small-right uk-text-large uk-text-nowrap">Link to:</span>
<publication-title [entity]="entity" param="id"
path="/search/result" [externalPortalUrl]=externalPortalUrl [linkAvailable]="linkAvailable"></publication-title>
path="/search/result" [externalPortalUrl]=externalPortalUrl></publication-title>
</div>
</div>
<div *ngIf="type == 'project'" [attr.uk-tooptip]="getEntityName(type)">
<span class="uk-text-meta uk-text-small uk-margin-small-right uk-text-nowrap">Link to:</span>
<div *ngIf="type == 'project'" [attr.uk-tooptip]="getEntityName(type)"
class="uk-flex">
<span class="uk-text-meta uk-margin-small-right uk-text-large uk-text-nowrap">Link to:</span>
<project-title [project]="entity" [searchLink]=properties.searchLinkToProject
[externalPortalUrl]=externalPortalUrl></project-title>
</div>
<div *ngIf="type == 'organization'" [attr.uk-tooptip]="getEntityName(type)">
<span class="uk-text-meta uk-text-small uk-margin-small-right uk-text-nowrap">Link to:</span>
<organization-title [organization]="entity"></organization-title>
</div>
<div *ngIf="type == 'context'">
<span class="uk-text-meta uk-text-small uk-margin-small-right uk-text-nowrap">Link to:</span>
<h6 class="uk-h6 uk-margin-remove">
<span class="uk-text-truncate" uk-tooltip="Concept">{{entity.title}}</span>
</h6>
<div *ngIf="type == 'context'" class="uk-flex uk-text-large">
<span class="uk-text-meta uk-margin-small-right uk-text-nowrap">Link to:</span>
<span class="uk-text-truncate" uk-tooltip="Concept">{{entity.title}}</span>
</div>
`
})
export class ClaimEntityFormatter {
@Input() entity: ClaimDBResult | ClaimDBContext | ClaimDBProject | ClaimDBOrganization;
@Input() entity: ClaimDBResult | ClaimDBContext | ClaimDBProject;
@Input() type: string;
@Input() properties: EnvProperties;
@Input() externalPortalUrl: string = null;
@Input() source: boolean = true;
@Input() linkAvailable: boolean = true;
public openAIREEntities = OpenaireEntities;
constructor() {

View File

@ -5,19 +5,18 @@ import { RouterModule } from '@angular/router';
import {ProjectTitleFormatter} from './projectTitleFormatter.component';
import {PublicationTitleFormatter} from './publicationTitleFormatter.component';
import {ClaimEntityFormatter} from './claimEntityFormatter.component';
import {OrganizationTitleFormatterComponent} from "./organizationTitleFormatter.component";
@NgModule({
imports: [
CommonModule, RouterModule
],
declarations: [
ProjectTitleFormatter, PublicationTitleFormatter, ClaimEntityFormatter, OrganizationTitleFormatterComponent
ProjectTitleFormatter, PublicationTitleFormatter, ClaimEntityFormatter
],
providers: [ ],
exports: [
ProjectTitleFormatter, PublicationTitleFormatter, ClaimEntityFormatter, OrganizationTitleFormatterComponent
ProjectTitleFormatter, PublicationTitleFormatter, ClaimEntityFormatter
]
})

View File

@ -1,18 +0,0 @@
import {Component, Input} from '@angular/core';
@Component({
selector: 'organization-title',
template: `
<h6 *ngIf="organization" class="uk-margin-remove multi-line-ellipsis lines-2">
<p class="uk-margin-remove">
{{(organization.shortName ? ('[' + organization.shortName + '] ') : '')}}{{organization.name}}
</p>
</h6>
`
})
export class OrganizationTitleFormatterComponent {
@Input() organization: any;
public url: string;
}

View File

@ -10,17 +10,17 @@ import {properties} from "../../../../../environments/environment";
<ng-container>
<h6 class="uk-margin-remove multi-line-ellipsis lines-2">
<p class="uk-margin-remove">
<a *ngIf="externalPortalUrl" [href]="externalPortalUrl + projectUrl + '?projectId='+project['openaireId']" class="uk-link uk-link-heading" [class.uk-disabled]="project.name == 'unidentified'">
<a *ngIf="externalPortalUrl" [href]="externalPortalUrl + projectUrl + '?projectId='+project['openaireId']" class="uk-link uk-link-heading">
{{(project['acronym'] ? ('[' + project['acronym'] + '] ') : '')}}{{project['name']}}
</a>
<a *ngIf="!externalPortalUrl" [routerLink]="projectUrl" [queryParams]="routerHelper.createQueryParam('projectId',project['openaireId'])" class="uk-link uk-link-heading" [class.uk-disabled]="project.name == 'unidentified'">
<a *ngIf="!externalPortalUrl" [routerLink]="projectUrl" [queryParams]="routerHelper.createQueryParam('projectId',project['openaireId'])" class="uk-link uk-link-heading">
{{(project['acronym'] ? ('[' + project['acronym'] + '] ') : '')}}{{project['name']}}
</a>
</p>
</h6>
</ng-container>
<span *ngIf="project['funderName']" class="uk-margin-small-top">
<span class="uk-text-meta">Funder: </span>{{project['funderName']}}
<span class="uk-text-muted">Funder: </span>{{project['funderName']}}
</span>
`
})

View File

@ -10,8 +10,8 @@ import {RouterHelper} from '../../../utils/routerHelper.class';
<h6 class="uk-margin-remove multi-line-ellipsis lines-2">
<p class="uk-margin-remove">
<a *ngIf="!externalPortalUrl" [queryParams]="routerHelper.createQueryParam(param,entity.openaireId)"
[routerLink]="path" class="uk-link uk-link-heading" [class.uk-disabled]="!linkAvailable">{{entity.title?entity.title:"[No title available]"}}</a>
<a *ngIf="externalPortalUrl" [href]="externalPortalUrl + path+'?'+param+'='+entity.openaireId" class="uk-link uk-link-heading custom-external" [class.uk-disabled]="!linkAvailable">{{entity.title?entity.title:"[No title available]"}}</a>
[routerLink]="path" class="uk-link uk-link-heading">{{entity.title?entity.title:"[No title available]"}}</a>
<a *ngIf="externalPortalUrl" [href]="externalPortalUrl + path+'?'+param+'='+entity.openaireId" class="uk-link uk-link-heading custom-external">{{entity.title?entity.title:"[No title available]"}}</a>
</p>
</h6>
</ng-container>
@ -23,6 +23,5 @@ export class PublicationTitleFormatter {
@Input() path: string;
@Input() entity: any;
@Input() externalPortalUrl: string = null;
@Input() linkAvailable: boolean = true;
public routerHelper: RouterHelper = new RouterHelper();
}

View File

@ -12,8 +12,8 @@ export class ClaimsService {
private getClaimRequest(size : number, page : number, url :string, fromCache:boolean):any {
return this.http.get(url, CustomOptions.getAuthOptionsWithBody());
}
getClaims( size : number, page : number, keyword:string, sortby: string, descending: boolean, types: string, apiUrl:string, mine:boolean):any {
let url = apiUrl +"claims"+"?offset="+(size*(page-1) + "&limit="+size)+"&keyword="+keyword+"&sortby="+sortby+"&descending="+descending+(types.length>0?"&"+types:types) + (mine?"&mine=true":"") + (mine?"&mine=true":"");
getClaims( size : number, page : number, keyword:string, sortby: string, descending: boolean, types: string, apiUrl:string):any {
let url = apiUrl +"claims"+"?offset="+(size*(page-1) + "&limit="+size)+"&keyword="+keyword+"&sortby="+sortby+"&descending="+descending+(types.length>0?"&"+types:types);
return this.getClaimRequest(size,page,url,true);
}
@ -23,7 +23,7 @@ export class ClaimsService {
return this.getClaimRequest(size,page,url,false);
}
getClaimsBycontext( size : number, page : number, contextId:string, keyword:string, sortby: string, descending: boolean, types: string , apiUrl:string, mine:boolean):any {
getClaimsBycontext( size : number, page : number, contextId:string, keyword:string, sortby: string, descending: boolean, types: string , apiUrl:string):any {
//console.info('ClaimsService: getClaims for context : '+contextId);
let url = apiUrl +"contexts/"+contextId+"/claims"+"?offset="+(size*(page-1) + "&limit="+size)+"&keyword="+keyword+"&sortby="+sortby+"&descending="+descending+(types.length>0?"&"+types:types);
return this.getClaimRequest(size,page,url,true);
@ -40,10 +40,6 @@ export class ClaimsService {
let url = apiUrl +"projects/"+projectId+"/claims"+"?offset="+(size*(page-1) + "&limit="+size)+"&keyword="+keyword+"&sortby="+sortby+"&descending="+descending+(types.length>0?"&"+types:types);
return this.getClaimRequest(size,page,url,true);
}
getClaimsByOrganization( size : number, page : number, organizationId:string, keyword:string, sortby: string, descending: boolean, types: string, apiUrl:string, mine:boolean):any {
let url = apiUrl +"organizations/"+organizationId+"/claims"+"?offset="+(size*(page-1) + "&limit="+size)+"&keyword="+keyword+"&sortby="+sortby+"&descending="+descending+(types.length>0?"&"+types:types) + (mine?"&mine=true":"");
return this.getClaimRequest(size,page,url,true);
}
deleteClaimById(claimId:string , apiUrl:string):any{
//console.warn('Trying to delete claim with id : '+claimId);

View File

@ -58,20 +58,22 @@ export class SearchDataciteService {
entity.result.journal = null;
entity.result.DOI = item.attributes.doi;
entity.id = item.attributes.doi;
entity.title = Array.isArray(item.attributes.titles) && item.attributes.titles[0].title?item.attributes.titles[0].title:null;
entity.title = item.attributes.title;
entity.result.url = properties.doiURL + item.attributes.doi;
entity.result.source = 'datacite';
entity.type = 'dataset';
entity.result.date = item.attributes.publicationYear;
entity.result.date = item.attributes.published;
entity.result.accessRights = "OPEN";
entity.result.publisher = item.attributes['publisher'];
entity.result.publisher = item.attributes['container-title'];
entity.result.journal = null;
entity.result.record = item;
if (item.attributes.creators) {
if (item.attributes.author) {
entity.result.authors = [];
for (let j = 0; j < item.attributes.creators.length; j++) {
const author = item.attributes.creators[j].name;
entity.result.authors.push(author);
for (let j = 0; j < item.attributes.author.length; j++) {
const author = item.attributes.author[j];
if(author.family || author.literal) {
entity.result.authors.push((author.family) ? author.family + (author.given ? ', ' + author.given : '') : author.literal);
}
}
}
results.push(entity);

View File

@ -21,38 +21,14 @@ export class SearchOrcidService {
let url = properties.searchOrcidURL + term + '/record';
return this.http.get(url, { headers: headers })
//.map(res => res.json()['person'])
.pipe(map(res => res['person']))
.pipe(map(res => [res['name']['given-names'],
res['name']['family-name'],
res['name'], res['name']['institution-name']]))
//.map(res => res.json()['person'])
.pipe(map(res => res['person']))
.pipe(map(res => [res['name']['given-names'],
res['name']['family-name'],
res['name']]))
.pipe(map(res => SearchOrcidService.parseOrcidAuthor(res, authorIds, authors, addId)));
}
.pipe(map(res => SearchOrcidService.parseOrcidAuthor(res, authorIds, authors, addId)));
}
searchOrcidSingleAuthor(term: string, properties: EnvProperties, addId): any {
//var headers = new Headers();
//headers.append('Accept', 'application/orcid+json');
let headers = new HttpHeaders({'Accept': 'application/orcid+json'});
let url ="https://pub.orcid.org/v3.0/expanded-search/?q=orcid:" + term + '&start=0&rows=50';
return this.http.get(url, {headers: headers})
.pipe(map(res => res['expanded-result']))
.pipe(map(res => {
if(res) {
for (let auth_result of res) {
const author = {};
author['id'] = auth_result['orcid-id'];
author['authorGivenName'] = auth_result['given-names'];
author['authorFamilyName'] = auth_result['family-names'];
author['institutions'] = auth_result['institution-name'];
return author;
}
}
return null;
}));
}
searchOrcidAuthors(term: string,
properties: EnvProperties): any {
@ -69,42 +45,14 @@ export class SearchOrcidService {
}
searchOrcidAuthorsNew(term: string,
properties: EnvProperties, size = 10): any {
let headers = new HttpHeaders({'Accept': 'application/orcid+json'});
// let url = properties.searchOrcidURL+'search?defType=edismax&q='+term+'&qf=given-name^1.0+family-name^2.0+other-names^1.0+credit-name^1.0&start=0&rows=10';
let url = /*properties.searchOrcidURL +*/ 'https://pub.orcid.org/v3.0/expanded-search?q=' + StringUtils.URIEncode('{!edismax qf="given-and-family-names^50.0 family-name^10.0 given-names^10.0 credit-name^10.0 other-names^5.0 text^1.0" pf="given-and-family-names^50.0" bq="current-institution-affiliation-name:[* TO *]^100.0 past-institution-affiliation-name:[* TO *]^70" mm=1}') + term + '&start=0&rows=' + size;
// given-and-family-names^50.0 family-name^10.0 given-names^10.0 credit-name^10.0 other-names^5.0 text^1.0" pf="given-and-family-names^50.0" bq="current-institution-affiliation-name:[* TO *]^100.0 past-institution-affiliation-name:[* TO *]^70" mm=1}
// https://pub.orcid.org/v3.0/expanded-search/?q=%7B!edismax%20qf%3D%22given-and-family-names%5E50.0%20family-name%5E10.0%20given-names%5E10.0%20credit-name%5E10.0%20other-names%5E5.0%20text%5E1.0%22%20pf%3D%22given-and-family-names%5E50.0%22%20bq%3D%22current-institution-affiliation-name%3A%5B*%20TO%20*%5D%5E100.0%20past-institution-affiliation-name%3A%5B*%20TO%20*%5D%5E70%22%20mm%3D1%7Dpaolo%20manghi&start=0&rows=50
//q={!edismax qf="given-and-family-names^50.0 family-name^10.0 given-names^5.0 credit-name^10.0 other-names^5.0 text^1.0" pf="given-and-family-names^50.0" mm=1}alessia bardi&start=0&rows=10
let key = url;
return this.http.get(url, {headers: headers})
.pipe(map(res => res['expanded-result']))
.pipe(map(res => {
let authors = [];
if(res) {
for (let auth_result of res) {
const author = {};
author['id'] = auth_result['orcid-id'];
author['authorGivenName'] = auth_result['given-names'];
author['authorFamilyName'] = auth_result['family-names'];
author['institutions'] = auth_result['institution-name'];
authors.push(author);
}
}
return authors;
}));
}
searchOrcidPublications(id: string, properties: EnvProperties, parse: boolean = false): any {
let headers = new HttpHeaders({'Accept': 'application/orcid+json'});
let url = properties.searchOrcidURL + id + '/works';
return this.http.get(url, { headers: headers })
.pipe(map(res => res['group']))
.pipe(map(request => (parse ? SearchOrcidService.parse(id, request) : request)));
}
return this.http.get(url, { headers: headers })
.pipe(map(res => res['group']))
.pipe(map(request => (parse ? SearchOrcidService.parse(id, request) : request)));
}
static parseOrcidAuthor(data: any, authorIds: string[], authors, addId): any {
@ -124,9 +72,6 @@ export class SearchOrcidService {
} else {
author['authorFamilyName'] = "";
}
if (data[3] != null) {
author['institution'] = data[3];
}
authors.push(author);
return true;
}

View File

@ -1,19 +0,0 @@
import { NgModule} from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import {SearchOrcidService} from "./searchOrcid.service";
@NgModule({
imports: [
CommonModule, FormsModule
],
declarations: [
],
providers:[
SearchOrcidService
],
exports: [
]
})
export class SearchOrcidServiceModule { }

View File

@ -37,6 +37,7 @@ export class ClaimsAdminComponent {
@Input() isConnect: boolean = false;
@Input() externalPortalUrl: string;
@Input() claimsInfoURL: string;
@Input() userInfoURL: string;
public user: User = null;
sub;

View File

@ -3,6 +3,9 @@ import { NgModule } from '@angular/core';
import { SharedModule } from '../../../openaireLibrary/shared/shared.module';
import { ClaimsAdminComponent } from './claimsAdmin.component';
import {DisplayClaimsModule} from '../claim-utils/displayClaims/displayClaims.module';
import { AdminLoginGuard} from'../../login/adminLoginGuard.guard';
import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard';
import {IsRouteEnabled} from '../../error/isRouteEnabled.guard';
@NgModule({
imports: [
@ -10,7 +13,7 @@ import {DisplayClaimsModule} from '../claim-utils/displayClaims/displayClaims.mo
DisplayClaimsModule
],
providers:[],
providers:[AdminLoginGuard, PreviousRouteRecorder,IsRouteEnabled],
declarations: [
ClaimsAdminComponent
],

View File

@ -1,7 +1,6 @@
<loading *ngIf="validInput === null" [full]="true" class="uk-position-center"></loading>
<linking-generic *ngIf="validInput" [localStoragePrefix]="localStoragePrefix" [results]="results" [sources]="sources"
[communityId]="communityId" [inlineEntity]="inlineEntity" [showOptions]="showOptions"
pageTitle="Direct Linking" [claimsProperties]="claimsProperties">
pageTitle="Direct Linking">
</linking-generic>
<div *ngIf="validInput== false" id="tm-main" class=" uk-section uk-padding-remove-top tm-middle">

View File

@ -1,7 +1,7 @@
import {Component, Input, ViewChild} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import {EnvProperties} from '../../utils/properties/env-properties';
import {ClaimEntity, ClaimOrganization, ClaimProject, ShowOptions} from '../claim-utils/claimHelper.class';
import {ClaimEntity, ClaimProject, ShowOptions} from '../claim-utils/claimHelper.class';
import {EntitiesSearchService} from '../../utils/entitiesAutoComplete/entitySearch.service';
import {SearchResearchResultsService} from '../../services/searchResearchResults.service';
import {LinkingGenericComponent} from "../linking/linkingGeneric.component";
@ -11,7 +11,6 @@ import {properties} from "../../../../environments/environment";
import {OpenaireEntities} from "../../utils/properties/searchFields";
import {StringUtils} from "../../utils/string-utils.class";
import {ClaimProjectsSearchFormComponent} from "../claim-utils/claimProjectSearchForm.component";
import {ClaimsProperties} from "../claim-utils/claims.properties";
@Component({
@ -25,20 +24,18 @@ export class DirectLinkingComponent {
// linkType: string = "project"; // link type (selected in home page) : project, context, software, etc
/* url Parameters for inline linking */
@Input() id: string = null; //entity id
id: string = null; //entity id
type: string = null; // entity type (publication or dataset)
// linkTo: string = null; // entity type (project or context or entity)
// linkToEntities: string[] = [];
showOptions:ShowOptions = new ShowOptions();
validEntityTypes = ["dataset", "publication", "software", "other", "project", "context", "organization"];
validEntityTypes = ["dataset", "publication", "software", "orp", "project", "context"];
sources: ClaimEntity[] = [];
inlineEntity: ClaimEntity = null;
validInput: boolean = null;//'true;
properties: EnvProperties;
@Input() communityId: string = null;
localStoragePrefix: string = "";
@Input() organizationClaim: boolean = false;
@Input() claimsProperties:ClaimsProperties = new ClaimsProperties();
constructor(private _router: Router, private route: ActivatedRoute,private entitySearch:EntitiesSearchService,
private _searchResearchResultsService: SearchResearchResultsService) {}
subscriptions = [];
@ -51,18 +48,11 @@ export class DirectLinkingComponent {
}
ngOnInit() {
this.properties = properties;
/* if(!this.claimsProperties){
this.claimsProperties = new ClaimsProperties();
}*/
this.subscriptions.push(this.route.queryParams.subscribe(params => {
if(this.organizationClaim){
this.type = "organization";
this.showOptions.linkTo = "result";
}else {
this.id = params['id'];
this.type = params['type'];
this.showOptions.linkTo = params['linkTo'];
}
this.id = params['id'];
this.type = params['type'];
this.showOptions.linkTo = params['linkTo'];
if (this.type != null && this.showOptions.linkTo != null) {
this.type = (this.validEntityTypes.indexOf(this.type) != -1) ? this.type : 'publication';
this.showOptions.linkTo = (this.validEntityTypes.indexOf(this.showOptions.linkTo) != -1 || this.showOptions.linkTo == "result") ? this.showOptions.linkTo : 'project';
@ -78,22 +68,20 @@ export class DirectLinkingComponent {
if (this.type == "project") {
// this.linkType = "project";
this.getProjectById(this.id);
} else if (this.type == "organization") {
this.getOrganizationById(this.id);
} else if (this.type == "publication") {
this.getResearchResultById("publication", this.id);
} else if (this.type == "dataset") {
this.getResearchResultById("dataset", this.id);
} else if (this.type == "software") {
this.getResearchResultById("software", this.id);
} else if (this.type == "other") {
} else if (this.type == "orp") {
this.getResearchResultById("other", this.id);
} else {
this.validInput = this.isValidInput(null);
}
//set which entities it is allowed to link to.
// add first the
if(this.type == "project" || this.type == "organization"){
if(this.type == "project"){
this.showOptions.linkToEntities = ["result"];
this.showOptions.linkTo = "result";
}else{
@ -107,27 +95,24 @@ export class DirectLinkingComponent {
this.showOptions.linkToEntities = ["result","project","context" ];
}
}
} else {
this.validInput = this.isValidInput(null);
}
}));
} else {
this.validInput = this.isValidInput(null);
}
}));
}
isValidInput(result: ClaimEntity) {
if (result == null) {
return false;
} else if (this.type == "organization" && !this.claimsProperties.ALLOW_ORGANIZATION_LINKING) {
} else if (this.type == "project" && this.showOptions.linkTo != "result") {
return false;
} else if ((this.type == "project" || this.type == "organization") && this.showOptions.linkTo != "result") {
} else if (["dataset", "publication", "software", "orp"].indexOf(this.type) != -1 && (["project", "context", "result"].indexOf(this.showOptions.linkTo) == -1)) {
return false;
} else if (["dataset", "publication", "software", "other"].indexOf(this.type) != -1 && (["project", "context", "result"].indexOf(this.showOptions.linkTo) == -1)) {
return false;
} else if (["project", "dataset", "publication", "software", "other", "organization"].indexOf(this.type) == -1) {
} else if (["project", "dataset", "publication", "software", "orp"].indexOf(this.type) == -1) {
return false;
} else {
return true;
@ -145,17 +130,6 @@ export class DirectLinkingComponent {
this.handleError("Error getting project by id: " + id, err);
}));
}
getOrganizationById(id: string) {
this.subscriptions.push(this.entitySearch.fetchByType(id,"organization", this.properties).subscribe(
data => {
this.createClaimEntity(data, "organization");
},
err => {
this.validInput = this.isValidInput(null);
//console.log("An error occured")
this.handleError("Error getting project by id: " + id, err);
}));
}
getResearchResultById(resultType: string, id: string) {
this.subscriptions.push(this._searchResearchResultsService.searchById(resultType, id, this.properties).subscribe(data => {
@ -182,23 +156,12 @@ export class DirectLinkingComponent {
entity.project.code = project.code;
entity.project.endDate = project.endDate;
entity.project.funderId = project.funderId;
entity.project.funderShortname = project.funderShortName?project.funderShortName:(entity.project.funderId.split("::")[1]);
entity.project.funderName = project.funderName;
entity.project.fundingLevel0 = project.fundingLevel0;
entity.project.jurisdiction = project.jurisdiction;
entity.project.startDate = project.startDate;
this.inlineEntity = entity;
}else if(type =="organization"){
let organization = data[0];
let entity:ClaimEntity = new ClaimEntity();
entity.id = organization.id;
entity.type = "organization";
entity.title = organization.label;
entity.organization = new ClaimOrganization();
// entity.organization.url = properties.searchLinkToOrganization + entity.id;
entity.organization.name = organization.label;
this.inlineEntity = entity;
}else{
}else{
results = ClaimResultSearchFormComponent.openaire2ClaimResults(data, this.properties);
}

View File

@ -5,18 +5,20 @@ import { DirectLinkingComponent } from './directLinking.component';
import {EntitySearchServiceModule} from '../../utils/entitiesAutoComplete/entitySearchService.module';
import {SearchResearchResultsServiceModule} from '../../services/searchResearchResultsService.module';
import {LoginGuard} from'../../login/loginGuard.guard';
import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard';
import {IsRouteEnabled} from '../../error/isRouteEnabled.guard';
import {Schema2jsonldModule} from '../../sharedComponents/schema2jsonld/schema2jsonld.module';
import { SEOServiceModule } from '../../sharedComponents/SEO/SEOService.module';
import {LinkingGenericModule} from '../linking/linkingGeneric.module';
import {LoadingModule} from "../../utils/loading/loading.module";
@NgModule({
imports: [
SharedModule,
EntitySearchServiceModule, SearchResearchResultsServiceModule,
Schema2jsonldModule, SEOServiceModule, LinkingGenericModule, LoadingModule
Schema2jsonldModule, SEOServiceModule, LinkingGenericModule
],
providers:[],
providers:[LoginGuard, PreviousRouteRecorder, IsRouteEnabled],
declarations: [
DirectLinkingComponent
], exports:[DirectLinkingComponent]

View File

@ -133,11 +133,11 @@ export class BulkClaimComponent {
}
});
}
upload() {
this.enableUpload = false;
this.showReport = false;
this.errorMessage = "";
console.log(this.filesToUpload);
if (this.filesToUpload.length == 0) {
this.errorMessage = "There is no selected file to upload.";
return;
@ -269,16 +269,11 @@ export class BulkClaimComponent {
}
},
err => {
// console.log(err);
//console.log(err);
BulkClaimComponent.handleError("Error getting crossref by DOIs: " + id, err);
if(err.status == 404) {
this.searchInDatacite(id, accessMode, date, row);
} else {
this.notFoundIds.push(id);
this.notFoundIdsRow.push(row);
this.endOfFetching();
}
this.notFoundIds.push(id);
this.notFoundIdsRow.push(row);
this.endOfFetching();
}
));
}

View File

@ -16,7 +16,6 @@ import {
import {UserManagementService} from "../../../services/user-management.service";
import {Subscriber, timer} from "rxjs";
import {map} from "rxjs/operators";
import {LogService} from "../../../utils/log/log.service";
@Component({
selector: 'claim-insert',
@ -60,7 +59,7 @@ import {LogService} from "../../../utils/log/log.service";
})
export class ClaimInsertComponent {
constructor(private claimService: ClaimsService, private _router: Router, private route: ActivatedRoute,
private userManagementService: UserManagementService, private _logService: LogService) {
private userManagementService: UserManagementService) {
}
subscriptions = [];
ngOnDestroy() {
@ -128,7 +127,6 @@ export class ClaimInsertComponent {
public feedRecordsJob;
public claims2Insert;
public records2Insert
infoToLog = [];
public insert() {
this.confirmOpen();
}
@ -147,7 +145,6 @@ export class ClaimInsertComponent {
this.errorInClaims = [];
this.insertedRecords = [];
this.errorInRecords = [];
this.infoToLog = [];
this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => {
if (!user) {
this.saveAndNavigate();
@ -156,14 +153,13 @@ export class ClaimInsertComponent {
this.loading.open();
let claims: ClaimRecord2Insert[] = [];
let directclaims: DirectIndexRecord[] = [];
let idSuffix = (new Date()).getTime() + "";
let dashboard = this.properties.environment+"_"+this.properties.dashboard + (this.communityId?("_"+this.communityId):'');
for (let j = 0; j < this.sources.length; j++) { // if an external result -> direct insert in the index
const result: ClaimEntity = this.sources[j];
if (result.result && ["crossref", "datacite", "orcid"].indexOf(result.result.source) != -1) {
directclaims.push({
"id": result.id,
"record": ClaimInsertComponent.createDirectClaim(result, this.results, idSuffix)
"record": ClaimInsertComponent.createDirectClaim(result, this.results)
});
}
}
@ -174,12 +170,12 @@ export class ClaimInsertComponent {
if (this.sources.length > 0) {
directclaims.push({
"id": entity.id,
"record": ClaimInsertComponent.createDirectClaim(entity, this.sources, idSuffix)
"record": ClaimInsertComponent.createDirectClaim(entity, this.sources)
});
} else if (this.inlineEntity && this.inlineEntity.type != "organization") {
} else if (this.inlineEntity) {
directclaims.push({
"id": entity.id,
"record": ClaimInsertComponent.createDirectClaim(entity, [this.inlineEntity], idSuffix)
"record": ClaimInsertComponent.createDirectClaim(entity, [this.inlineEntity])
});
}
@ -188,35 +184,28 @@ export class ClaimInsertComponent {
for (let j = 0; j < this.sources.length; j++) {
const result: ClaimEntity = this.sources[j]; // this is a research result
if (entity.result) {
claims.push(ClaimInsertComponent.createResultClaim(result, entity, user.email, dashboard, idSuffix));
claims.push(ClaimInsertComponent.createResultClaim(result, entity, user.email, dashboard));
} else if (entity.context) {
claims.push(ClaimInsertComponent.createContextClaim(result, entity, user.email, dashboard, idSuffix));
claims.push(ClaimInsertComponent.createContextClaim(result, entity, user.email, dashboard));
} else if (entity.project) {
claims.push(ClaimInsertComponent.createProjectClaim(result, entity, user.email, dashboard, idSuffix));
/* } else if (entity.organization) {
claims.push(ClaimInsertComponent.createOrganizationClaim(result, entity, user.email, dashboard, idSuffix));*/
claims.push(ClaimInsertComponent.createProjectClaim(result, entity, user.email, dashboard));
}
this.infoToLog.push([ result.title?result.title: result.id, entity.title?entity.title:entity.id]);
}
if (this.inlineEntity) {
this.infoToLog.push([ this.inlineEntity.title?this.inlineEntity.title: this.inlineEntity.id, entity.title?entity.title:entity.id]);
if (this.inlineEntity.result) {
if (entity.result) {
claims.push(ClaimInsertComponent.createResultClaim(this.inlineEntity, entity, user.email, dashboard, idSuffix));
claims.push(ClaimInsertComponent.createResultClaim(this.inlineEntity, entity, user.email, dashboard));
} else if (entity.context) {
claims.push(ClaimInsertComponent.createContextClaim(this.inlineEntity, entity, user.email, dashboard, idSuffix));
claims.push(ClaimInsertComponent.createContextClaim(this.inlineEntity, entity, user.email, dashboard));
} else if (entity.project) {
claims.push(ClaimInsertComponent.createProjectClaim(this.inlineEntity, entity, user.email, dashboard, idSuffix));
claims.push(ClaimInsertComponent.createProjectClaim(this.inlineEntity, entity, user.email, dashboard));
}
} else if (this.inlineEntity.project) {
if (entity.result) {
claims.push(ClaimInsertComponent.createProjectClaim(entity, this.inlineEntity, user.email, dashboard, idSuffix));
}
} else if (this.inlineEntity.organization) {
if (entity.result) {
claims.push(ClaimInsertComponent.createOrganizationClaim(entity, this.inlineEntity, user.email, dashboard, idSuffix));
claims.push(ClaimInsertComponent.createProjectClaim(entity, this.inlineEntity, user.email, dashboard));
}
}
}
@ -232,7 +221,7 @@ export class ClaimInsertComponent {
data => {
this.feedRecordsJob = data.data;
this.records2Insert = directclaims.length;
// console.log(data);
console.log(data);
// this.insertedRecords = data.insertedIds;
//
// this.errorInRecords = data.errorInClaims;
@ -267,12 +256,6 @@ export class ClaimInsertComponent {
data => {
this.claims2Insert = claims.length;
this.claimsJob = data.data;
if(this.properties.logServiceUrl) {
for(let info of this.infoToLog) {
this.subscriptions.push(this._logService.logLink(this.properties, info[0],info[1]).subscribe(res => {
}));
}
}
this.saveLocalStorage();
let timerSubscription = timer(0, 10000).pipe(
map(() => {
@ -391,18 +374,13 @@ export class ClaimInsertComponent {
localStorage.removeItem(this.localStoragePrefix + "results");
localStorage.removeItem(this.localStoragePrefix + "claimsJob");
localStorage.removeItem(this.localStoragePrefix + "feedRecordsJob");
if(this.properties.myClaimsLink && this.properties.myClaimsLink.indexOf(".") == -1) {
this._router.navigate([this.properties.myClaimsLink], {queryParams: this.params});
}else if(this.properties.myClaimsLink && this.properties.myClaimsLink.indexOf(".") != -1) {
this._router.navigate([this.properties.myClaimsLink], {relativeTo: this.route});
}else{
this._router.navigate(["/"]);
}
this._router.navigate(['/myclaims'], {queryParams: this.params});
}
}
private static createContextClaim(resultEntity: ClaimEntity, contextEntity: ClaimEntity, user: any, dashboard:string, idSuffix:string): ClaimRecord2Insert {
private static createContextClaim(resultEntity: ClaimEntity, contextEntity: ClaimEntity, user: any, dashboard:string): ClaimRecord2Insert {
return {
claimedBy: user,
sourceId: contextEntity.context.concept.id,
@ -415,12 +393,11 @@ export class ClaimInsertComponent {
targetCollectedFrom: resultEntity.result.source,
targetAccessRights: resultEntity.result.accessRights,
targetEmbargoEndDate: ClaimInsertComponent.getEmbargoEndDate(resultEntity),
claimedInDashboard : dashboard,
idSuffix : idSuffix
claimedInDashboard : dashboard
};
}
private static createProjectClaim(resultEntity: ClaimEntity, projectEntity: ClaimEntity, user: any, dashboard:string, idSuffix:string): ClaimRecord2Insert {
private static createProjectClaim(resultEntity: ClaimEntity, projectEntity: ClaimEntity, user: any, dashboard:string): ClaimRecord2Insert {
return {
claimedBy: user,
sourceId: projectEntity.id,
@ -433,29 +410,11 @@ export class ClaimInsertComponent {
targetCollectedFrom: resultEntity.result.source,
targetAccessRights: resultEntity.result.accessRights,
targetEmbargoEndDate: ClaimInsertComponent.getEmbargoEndDate(resultEntity),
claimedInDashboard : dashboard,
idSuffix : idSuffix
};
}
private static createOrganizationClaim(resultEntity: ClaimEntity, organizationEntity: ClaimEntity, user: any, dashboard:string, idSuffix:string): ClaimRecord2Insert {
return {
claimedBy: user,
sourceId: organizationEntity.id,
sourceType: "organization",
sourceCollectedFrom: "openaire",
sourceAccessRights: "OPEN",
sourceEmbargoEndDate: "",
targetId: resultEntity.id,
targetType: resultEntity.type,
targetCollectedFrom: resultEntity.result.source,
targetAccessRights: resultEntity.result.accessRights,
targetEmbargoEndDate: ClaimInsertComponent.getEmbargoEndDate(resultEntity),
claimedInDashboard : dashboard,
idSuffix : idSuffix
claimedInDashboard : dashboard
};
}
private static createResultClaim(inlineResult: ClaimEntity, resultEntity: ClaimEntity, user: string, dashboard:string, idSuffix:string): ClaimRecord2Insert {
private static createResultClaim(inlineResult: ClaimEntity, resultEntity: ClaimEntity, user: string, dashboard:string): ClaimRecord2Insert {
return {
claimedBy: user,
@ -469,9 +428,7 @@ export class ClaimInsertComponent {
targetCollectedFrom: inlineResult.result.source,
targetAccessRights: inlineResult.result.accessRights,
targetEmbargoEndDate: ClaimInsertComponent.getEmbargoEndDate(inlineResult),
claimedInDashboard : dashboard,
idSuffix : idSuffix
claimedInDashboard : dashboard
};
}
@ -481,13 +438,12 @@ export class ClaimInsertComponent {
}
return ""
}
static createOpenAIREId(id, idSuffix:string):string {
return id.indexOf( "::" ) == -1 ? ("userclaim___::" + Md5.hashStr(id + idSuffix)):id;
}
static createDirectClaim(resultEntity: ClaimEntity, results: ClaimEntity[], idSuffix:string) {
static createDirectClaim(resultEntity: ClaimEntity, results: ClaimEntity[]) {
let entity = {};
entity["originalId"] = this.createOpenAIREId(resultEntity.id, idSuffix);
entity["openaireId"] = this.createOpenAIREId(resultEntity.id, idSuffix);
const md5_id = Md5.hashStr(resultEntity.id);
entity["originalId"] = "userclaim___::" + md5_id;
entity["openaireId"] = "userclaim___::" + md5_id;
entity["title"] = resultEntity.title;
entity["title"] = (Array.isArray(resultEntity.title) && resultEntity.title.length > 0) ? resultEntity.title[0] : resultEntity.title;
@ -536,7 +492,7 @@ export class ClaimInsertComponent {
entity["linksToProjects"] = [];
}
let project: ClaimEntity = results[i];
entity["linksToProjects"].push("info:eu-repo/grantAgreement/" + project.project.funderShortname + "/" + project.project.fundingLevel0 + "/" + project.project.code + "/" + project.project.jurisdiction + "/" + project.title + "/" + project.project.acronym);
entity["linksToProjects"].push("info:eu-repo/grantAgreement/" + project.project.funderName + "/" + project.project.fundingLevel0 + "/" + project.project.code + "/" + project.project.jurisdiction + "/" + project.title + "/" + project.project.acronym);
} else if (results[i].context) {

View File

@ -6,11 +6,10 @@ import {LoadingModalModule} from '../../../utils/modal/loadingModal.module';
import {ClaimInsertComponent} from './insertClaim.component';
import {ClaimServiceModule} from '../../claim-utils/service/claimsService.module';
import {IconsModule} from "../../../utils/icons/icons.module";
import {LogServiceModule} from "../../../utils/log/LogService.module";
@NgModule({
imports: [
SharedModule, AlertModalModule, LoadingModalModule, ClaimServiceModule, IconsModule, LogServiceModule
SharedModule, AlertModalModule, LoadingModalModule, ClaimServiceModule, IconsModule
],
declarations: [ClaimInsertComponent],
exports:[ ClaimInsertComponent]

View File

@ -67,19 +67,18 @@
[results]="results" [sources]="sources"
[localStoragePrefix]="localStoragePrefix" [inlineEntity]="inlineEntity"
[showOptions]="showOptions" [properties]=properties [pageContents]="pageContents"
[defaultColors]="!communityId" [communityId]="communityId" [claimsProperties]="claimsProperties"
[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="uk-container uk-container-large">
<div *ngIf="properties && claimsProperties" class="uk-section uk-padding-remove-top">
<div class="uk-container uk-container-large">
<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@m uk-position-z-index uk-flex-first@m uk-flex-last uk-margin-medium-top">
<h2 *ngIf="inlineEntity && claimsProperties.INLINE_ENTITY.show" class="uk-text-center">Link source to</h2>
<div *ngIf="inlineEntity && claimsProperties.INLINE_ENTITY.guideText" class="uk-text-center">{{claimsProperties.INLINE_ENTITY.guideText}}</div>
<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'"
@ -110,22 +109,22 @@
</div>
</div>
<!-- Basket-->
<div *ngIf="showOptions.show != 'claim'" class="uk-width-1-3@m uk-flex-last@m uk-flex-first uk-margin-medium-top">
<div *ngIf="showOptions.show != 'claim'" class="uk-width-1-3">
<div id="basket" uk-sticky="offset: 220; end: !*; media: @m" style="z-index: 0!important;">
<div class="uk-card uk-card-default linkingBasket">
<div class="uk-card-body uk-padding-small">
<div>
<div class="uk-margin-right">
<ng-container *ngIf="inlineEntity">
<div *ngIf="claimsProperties.INLINE_ENTITY.show" class="uk-margin-small-bottom">
<div class="uk-text-emphasis uk-text-bolder">{{claimsProperties.BASKET.source_title}}</div>
<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 *ngIf="claimsProperties.INLINE_ENTITY.show" class="uk-padding-small uk-padding-remove-horizontal"><hr class="uk-margin-remove"/></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">{{claimsProperties.BASKET.target_title}} <span *ngIf="results.length> 0">({{(results.length) | number}})</span></div>
<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>
@ -146,7 +145,7 @@
</li>
</ul>
<div *ngIf="showOptions.basketShowSources">
<div class="uk-height-max-medium uk-overflow-auto uk-padding uk-padding-remove-left uk-padding-remove-vertical">
<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"
@ -174,7 +173,7 @@
</div>
</div>
<div *ngIf="showOptions.basketShowLinksTo">
<div class="uk-height-max-medium uk-overflow-auto uk-padding uk-padding-remove-left uk-padding-remove-vertical">
<div class="uk-height-medium uk-overflow-auto">
<ng-container *ngTemplateOutlet="destinations_basket"></ng-container>
</div>
</div>

View File

@ -18,7 +18,6 @@ import {RouterHelper} from "../../utils/routerHelper.class";
import { Location } from '@angular/common';
import {LoginErrorCodes} from "../../login/utils/guardHelper.class";
import {UserManagementService} from "../../services/user-management.service";
import {ClaimsProperties} from "../claim-utils/claims.properties";
@Component({
selector: 'linking-generic',
@ -42,7 +41,7 @@ export class LinkingGenericComponent {
// show linkToEntities /values: result, project, context
@Input() sources:ClaimEntity[] =[];
properties:EnvProperties = properties;
properties:EnvProperties;
public openaireEntities = OpenaireEntities;
@Input() localStoragePrefix:string = "linking_";
url=null;
@ -50,7 +49,7 @@ export class LinkingGenericComponent {
public pageContents = null;
@Input() breadcrumbs: Breadcrumb[] = [];
public routerHelper: RouterHelper = new RouterHelper();
@Input() claimsProperties:ClaimsProperties = new ClaimsProperties();
constructor (private _router: Router, private route: ActivatedRoute, private entitySearch:EntitiesSearchService,
private _meta: Meta, private _title: Title, private _piwikService:PiwikService,
private seoService: SEOService, private helper: HelperService, private cdr: ChangeDetectorRef,
@ -59,9 +58,6 @@ export class LinkingGenericComponent {
subscriptions = [];
ngOnInit() {
/* if(!this.claimsProperties){
this.claimsProperties = new ClaimsProperties();
}*/
this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => {
if (!user) {
this.saveStateAndRedirectLogin();
@ -72,13 +68,14 @@ export class LinkingGenericComponent {
this.breadcrumbs.push({name: "Link", route: null});
}
this.showOptions.show = 'source';
this.showOptions.initSelectOptions(this.claimsProperties);
this.showOptions.initSelectOptions();
if(this.inlineEntity){
this.showOptions.showLinkTo();
// this.showOptions.basketShowLinksTo = true;
this.showOptions.show = this.showOptions.linkTo;
}
this.properties = properties;
this.url = this.properties.domain + this.properties.baseLink+this._router.url;
var description = "Linking is a functionality provided by OpenAIRE, in order to link research results with a project, a research community or other research results.";
@ -90,11 +87,9 @@ export class LinkingGenericComponent {
this.subscriptions.push(this._piwikService.trackView(this.properties, this.pageTitle).subscribe());
if(properties.adminToolsPortalType !== "explore") {
this.helper.getPageHelpContents(this.properties, this.communityId, this._router.url).subscribe(contents => {
this.pageContents = contents;
})
}
if( typeof localStorage !== 'undefined') {
@ -169,19 +164,19 @@ export class LinkingGenericComponent {
stepHasChanged(stepId){
if(stepId == 'source'){
// console.log("show source")
console.log("show source")
this.showOptions.showSource();
}else if(stepId == 'target'){
// console.log("show target")
console.log("show target")
this.showOptions.show = this.showOptions.linkTo;
this.showOptions.showLinkTo();
}else if(stepId == 'claim'){
// console.log("show target")
console.log("show target")
this.showOptions.show = 'claim';
}
this.cdr.detectChanges();
HelperFunctions.scroll(true);
// console.log('stepHasChanged', stepId, this.showOptions.show)
console.log('stepHasChanged', stepId, this.showOptions.show)
}
stepStatus(stepId){

View File

@ -7,16 +7,20 @@ import {SelectedContextsModule} from './selected/selectedContexts.module';
import {SelectedPublicationsModule} from './selected/selectedResults.module';
import {LinkingGenericComponent} from './linkingGeneric.component';
import {StartOverModule} from '../claim-utils/startOver.module';
import {LoginGuard} from '../../login/loginGuard.guard';
import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard';
import {ClaimContextSearchFormModule} from '../claim-utils/claimContextSearchForm.module';
import {ClaimProjectsSearchFormModule} from '../claim-utils/claimProjectSearchForm.module';
import {BulkClaimModule} from './bulkClaim/bulkClaim.module';
import {ClaimResultSearchFormModule} from '../claim-utils/claimResultSearchForm.module';
import {HelperModule} from '../../utils/helper/helper.module';
import {IsRouteEnabled} from '../../error/isRouteEnabled.guard';
import {Schema2jsonldModule} from '../../sharedComponents/schema2jsonld/schema2jsonld.module';
import {SEOServiceModule} from '../../sharedComponents/SEO/SEOService.module';
import {MetadataPreviewModule} from './selected/metadataPreview.module';
import {ClaimEntitiesMetadataModule} from "./selected/ClaimEntitiesMetadata.module";
import {AlertModalModule} from '../../utils/modal/alertModal.module';
import {PiwikServiceModule} from "../../utils/piwik/piwikService.module";
import {BreadcrumbsModule} from "../../utils/breadcrumbs/breadcrumbs.module";
import {StepperModule} from "../../sharedComponents/stepper/stepper.module";
import {IconsModule} from "../../utils/icons/icons.module";
@ -30,9 +34,10 @@ import {link} from "../../utils/icons/icons";
StartOverModule,
ClaimContextSearchFormModule, ClaimProjectsSearchFormModule, BulkClaimModule, ClaimResultSearchFormModule,
HelperModule, Schema2jsonldModule, SEOServiceModule, MetadataPreviewModule, ClaimEntitiesMetadataModule, AlertModalModule,
PiwikServiceModule,
MatSelectModule, BreadcrumbsModule, StepperModule, IconsModule
],
providers: [],
providers: [LoginGuard, PreviousRouteRecorder, IsRouteEnabled],
declarations: [
LinkingGenericComponent
], exports: [

View File

@ -3,21 +3,13 @@ import {SharedModule} from '../../../../openaireLibrary/shared/shared.module';
import {ClaimEntityTitleComponent} from "./ClaimEntityTitle.component";
import {ClaimEntityResultMetadataComponent} from "./ClaimEntityResultMetadata.component";
import {ClaimEntityProjectMetadataComponent} from "./ClaimEntityProjectMetadata.component";
import {IconsService} from "../../../utils/icons/icons.service";
import {coins} from "../../../utils/icons/icons";
import {IconsModule} from "../../../utils/icons/icons.module";
@NgModule({
imports: [
SharedModule,
IconsModule
SharedModule
],
declarations: [
ClaimEntityTitleComponent, ClaimEntityResultMetadataComponent, ClaimEntityProjectMetadataComponent
], exports:[ ClaimEntityTitleComponent, ClaimEntityResultMetadataComponent, ClaimEntityProjectMetadataComponent]
})
export class ClaimEntitiesMetadataModule {
constructor(private _iconsService:IconsService) {
this._iconsService.registerIcons([coins])
}
}
export class ClaimEntitiesMetadataModule { }

View File

@ -8,28 +8,20 @@ import {ClaimEntity} from '../../claim-utils/claimHelper.class';
<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 == 'project' && entity.project.code == 'unidentified'?'funder':entity.type}}
{{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 *ngIf="shortVersion && entity.type == 'project' && entity.project.code == 'unidentified'" 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">
funder
</span>
</div>
<div *ngIf="entity.project.code!='unidentified'" class="uk-text-small uk-flex uk-flex-wrap" [style.grid-gap]="shortVersion?'0px':'10px'"
<div class="uk-text-small uk-flex uk-flex-wrap" [style.grid-gap]="shortVersion?'10px':'20px'"
[class.uk-margin-small-top]="!shortVersion">
<div *ngIf="entity.project.funderName">
<span class="uk-text-meta">Funder: </span>{{entity.project.funderName}}
</div>
<div *ngIf="entity.project.code">
<span class="uk-text-meta">Project Code: </span>{{entity.project.code}}
</div>
<div *ngIf="entity.project.funderName || entity.project.funderShortname">
<span class="uk-text-meta">Funding: </span>{{entity.project.funderName?entity.project.funderName:entity.project.funderShortname}}
</div>
</div>
</div>
</ng-container>
`,

View File

@ -5,18 +5,16 @@ import {ClaimEntity} from '../../claim-utils/claimHelper.class';
selector: 'claim-title',
template: `
<div class="uk-grid uk-flex uk-flex-middle">
<span *ngIf="showIcon" class="uk-flex uk-margin-xsmall-right">
<icon *ngIf="entity.result" class=" uk-text-small uk-text-meta" name="insert_drive_file">
</icon>
<icon *ngIf="entity.project && entity.project.code !='unidentified'" class=" uk-text-small uk-text-meta" name="assignment_turned_in">
</icon>
<icon *ngIf="entity.project && entity.project.code =='unidentified'" class="uk-text-small uk-text-meta" name="coins" [ratio]="1.4">
</icon>
<icon *ngIf="entity.organization" class=" uk-text-small uk-text-meta" name="account_balance">
</icon>
<icon *ngIf="entity.type=='community'" class=" uk-text-small uk-text-meta" style="margin-right: 2px;" name="people">
</icon>
<span *ngIf="showIcon" class="uk-flex">
<span *ngIf="entity.result" class="material-icons uk-text-small uk-text-meta">
insert_drive_file
</span>
<span *ngIf="entity.project" class="material-icons uk-text-small uk-text-meta">
assignment_turned_in
</span>
<span *ngIf="entity.type=='community'" class="material-icons uk-text-small uk-text-meta" style="margin-right: 2px;">
people
</span>
</span>
<div class="uk-width-expand multi-line-ellipsis lines-3" style="word-break: break-word;"
[class.uk-padding-remove-left]="showIcon" [class.uk-text-truncate]="shortVersion">
@ -29,15 +27,7 @@ import {ClaimEntity} from '../../claim-utils/claimHelper.class';
<span *ngIf="(entity.result && !entity.result.url)">
{{entity.title ? sliceString(entity.title) : '[No title available]'}}
</span>
<span *ngIf="entity.type=='project' && entity.project && entity.project.code =='unidentified'">
<span *ngIf="!shortVersion">
{{(entity.project.funderShortname ? '[' + entity.project.funderShortname + '] ' : '') + entity.project.funderName}}
</span>
<span *ngIf="shortVersion">
{{sliceString(entity.project.funderName)}}
</span>
</span>
<span *ngIf="entity.type=='project' && entity.project && entity.project.code!='unidentified'">
<span *ngIf="entity.type=='project' && entity.project">
<a *ngIf="entity.project && entity.project.url" target="_blank" [href]="entity.project.url"
class="uk-link uk-text-decoration-none uk-width-expand">
<span *ngIf="!shortVersion">
@ -56,9 +46,6 @@ import {ClaimEntity} from '../../claim-utils/claimHelper.class';
</span>
</span>
</span>
<span *ngIf="entity.type=='organization' && entity.organization">
{{sliceString(entity.title)}}
</span>
<span *ngIf="entity.type=='community' && entity.context">
<span *ngIf=" entity.context.community != entity.context.concept.label">
{{entity.context.community }} > {{entity.context.category}} >

View File

@ -6,14 +6,15 @@
<div class="uk-width-expand">
<div class="uk-card uk-card-default">
<div class="uk-card-body">
<div class="uk-grid uk-grid-divider uk-child-width-1-1@s" uk-grid [class.uk-child-width-1-2@m] = "claimsProperties.INLINE_ENTITY.show" >
<div class="uk-grid uk-grid-divider uk-child-width-1-2@m uk-child-width-1-1@s" uk-grid>
<!-- Sources-->
<div *ngIf="claimsProperties.INLINE_ENTITY.show">
<div>
<div class=" uk-margin uk-animation-toggle">
<span class="uk-h6 "> {{claimsProperties.METADATA_PREVIEW.source_title}} ({{sources.length + (inlineEntity ? 1 : 0) | number}})
<span class="uk-h6 "> SOURCES ({{sources.length + (inlineEntity ? 1 : 0) | number}})
</span>
<a *ngIf="!inlineEntity" class="uk-float-right uk-text-small" (click)="showOptions.showSource() "> <span
uk-icon="pencil" class="uk-margin-xsmall-right"></span>{{claimsProperties.METADATA_PREVIEW.edit_source_title}}</a>
uk-icon="pencil" class="uk-margin-xsmall-right"></span>Edit
sources</a>
</div>
<ul *ngIf="inlineEntity" class="uk-list uk-animation-fade uk-list-divider">
<li>
@ -152,15 +153,13 @@
</div>
<!-- Results-->
<div class=" ">
<div class=" uk-margin uk-grid">
<span class=" uk-h6 uk-width-expand"> {{claimsProperties.METADATA_PREVIEW.target_title}} ({{results.length | number}})</span>
<div class=" uk-margin ">
<span class=" uk-h6 "> LINK TO ({{results.length | number}})</span>
<div class="uk-width-auto uk-flex">
<icon [name]="claimsProperties.METADATA_PREVIEW.edit_target_icon" [flex]="true"></icon>
<a class=" uk-margin-left-xsmall uk-text-small" (click)="showOptions.showLinkTo()">
{{claimsProperties.METADATA_PREVIEW.edit_target_title}}</a>
</div>
<a class="uk-float-right uk-text-small" (click)="showOptions.showLinkTo()"> <span
uk-icon="pencil" class="uk-margin-xsmall-right"></span>Edit
entities</a>
</div>
<div *ngIf="results.length == 0">
<div class="uk-alert dangerBorder no-selected-message uk-text-center">

View File

@ -4,7 +4,6 @@ import {ClaimEntity, ClaimsErrorMessage, Message, ShowOptions} from '../../claim
import {EnvProperties} from "../../../utils/properties/env-properties";
import {Dates} from "../../../utils/string-utils.class";
import {HelperFunctions} from "../../../utils/HelperFunctions.class";
import {ClaimsProperties} from "../../claim-utils/claims.properties";
@Component({
selector: 'metadata-preview',
@ -29,7 +28,6 @@ export class MetadataPreviewComponent {
@ViewChild(AlertModal) alertApplyAll;
@Input() localStoragePrefix: string = "";
@Input() communityId:string= null;
@Input() claimsProperties:ClaimsProperties;
errors:ClaimsErrorMessage[] = [];
warnings:Message[] = [];
public commonAccessRights = "OPEN"; // for access rights- changes when user apply a change to every entity

View File

@ -11,17 +11,16 @@ import { MatInputModule } from '@angular/material/input';
import { MatSelectModule } from '@angular/material/select';
import {HelperModule} from "../../../utils/helper/helper.module";
import {SelectedPublicationsModule} from "./selectedResults.module";
import {IconsModule} from "../../../utils/icons/icons.module";
@NgModule({
imports: [
SharedModule,
AlertModalModule,
ClaimEntitiesMetadataModule,
InsertClaimsModule,
MatDatepickerModule, MatNativeDateModule, MatFormFieldModule, MatInputModule, MatSelectModule,
HelperModule, SelectedPublicationsModule, IconsModule
],
imports: [
SharedModule,
AlertModalModule,
ClaimEntitiesMetadataModule,
InsertClaimsModule,
MatDatepickerModule, MatNativeDateModule, MatFormFieldModule, MatInputModule, MatSelectModule,
HelperModule, SelectedPublicationsModule
],
declarations: [MetadataPreviewComponent],
exports:[MetadataPreviewComponent]
})

View File

@ -30,6 +30,7 @@ import {Subscriber} from "rxjs";
export class MyClaimsComponent {
@Input() claimsInfoURL: string;
@Input() communityId:string;
@Input() userInfoURL: string;
public user: User = null;
constructor(private userManagementService: UserManagementService, private _router: Router) {}

View File

@ -3,6 +3,9 @@ import { NgModule } from '@angular/core';
import { SharedModule } from '../../../openaireLibrary/shared/shared.module';
import { MyClaimsComponent } from './myClaims.component';
import {DisplayClaimsModule} from '../claim-utils/displayClaims/displayClaims.module';
import {LoginGuard} from'../../login/loginGuard.guard';
import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard';
import {IsRouteEnabled} from '../../error/isRouteEnabled.guard';
@NgModule({
imports: [
@ -10,7 +13,7 @@ import {DisplayClaimsModule} from '../claim-utils/displayClaims/displayClaims.mo
DisplayClaimsModule
],
providers:[],
providers:[LoginGuard, PreviousRouteRecorder, IsRouteEnabled],
declarations: [
MyClaimsComponent
], exports: [MyClaimsComponent]

View File

@ -6,9 +6,6 @@ import {CommunityInfo} from "./community/communityInfo";
export class ConnectHelper {
public static getCommunityFromDomain(domain: string): string{
if(properties.dashboard === 'irish') {
return properties.adminToolsCommunity;
}
if(properties.environment == "development" &&
(properties.adminToolsPortalType == "connect" || properties.adminToolsPortalType == "community"
|| properties.adminToolsPortalType == "aggregator" || properties.adminToolsPortalType == "eosc")) {

View File

@ -0,0 +1,55 @@
<div *ngIf="!hidden" class="">
<div *ngIf="showSaveResetButtons" class="uk-article-title custom-article-title">
User Email Preferences for Claims Notifications
</div>
<div *ngIf="userValidMessage.length > 0" class = "uk-alert uk-alert-danger uk-animation-fade" role="alert">
{{userValidMessage}}
</div>
<div *ngIf="savedMessage.length > 0" class="uk-alert uk-alert-success uk-animation-fade" role="alert">
{{savedMessage}}
</div>
<errorMessages [status]="[status]" [type]="'notification preferences'"></errorMessages>
<div *ngFor="let notification of notifications; let i=index" >
<!-- <div class="uk-accordion-title">Email preferences for {{preferencesFor}}: <strong>{{notification.openaireName}}</strong></div>-->
<!-- <div class="uk-accordion-content">-->
<form class="uk-form-horizontal"><!-- [formGroup]="myForm"-->
<!--[ngClass]="{'has-error':!myForm.controls.notify.valid && myForm.controls.notify.dirty}"-->
<div class="uk-margin uk-grid">
<div class=" inherit-color uk-width-medium"
title="Get e-mail notification when there are new user links related your community">Notify
for new user links:</div>
<mat-slide-toggle [checked]="notification.notify"
(change)="($event.source.checked = notification.notify);changeNotify(notification, !notification.notify, i)"></mat-slide-toggle>
</div>
<div *ngIf="notification.notify" [class]="notification.notify ? 'uk-margin' :
'uk-margin cursor-not-allowed'">
<div class="uk-form-label inherit-color">Frequency:</div>
<div class="uk-form-controls">
<select [class]="notification.notify ? 'uk-select' : 'uk-select uk-disabled'" id="form-horizontal-select"
[(ngModel)]="notification.frequency" (ngModelChange)="changeFrequency(i)" name="select_frequency">
<option [ngValue]="24" >Daily</option>
<option [ngValue]="48" >Every two days</option>
<option [ngValue]="168">Weekly</option>
</select>
</div>
</div>
<div *ngIf="showSaveResetButtons" class="uk-float-right">
<button type="submit" class="uk-button uk-button-primary" (click)="saveNotification(i)">Save Changes</button>
<button type="submit" class="uk-button" (click)="restoreNotification(i)">Reset</button>
</div>
</form>
</div>
<!-- </div>-->
<!-- </ul>-->
</div>

View File

@ -0,0 +1,259 @@
import {Component, Input} from '@angular/core';
import {Location} from '@angular/common';
import {ActivatedRoute, Router} from '@angular/router';
import {Session} from '../../login/utils/helper.class';
import {EnvProperties} from '../../utils/properties/env-properties';
import {MailPrefsService} from './mailPrefs.service';
import {ConnectHelper} from '../connectHelper';
import {ErrorCodes} from '../../utils/properties/errorCodes';
import {ErrorMessagesComponent} from '../../utils/errorMessages.component';
import {LoginErrorCodes} from '../../login/utils/guardHelper.class';
import {properties} from "../../../../environments/environment";
import {Subscriber} from "rxjs";
declare var UIkit: any;
@Component({
selector: 'mailPrefs',
templateUrl: 'mailPrefs.component.html',
providers:[MailPrefsService]
})
export class MailPrefsComponent {
properties:EnvProperties;
subscriptions = [];
@Input() communityId: string;
public preferencesFor: string = "community";
public status: number;
public notifications = [];
public initialNotifications = [];
public prefsChanged = {};
public hidden: boolean = true;
//public showForbiddenMessage:boolean = false;
public userValidMessage:string = "";
public savedMessage: string = "";
private errorCodes: ErrorCodes;
private errorMessages: ErrorMessagesComponent;
@Input() showSaveResetButtons: boolean = true;
constructor (private _mailPrefsService: MailPrefsService, private route: ActivatedRoute, private _router:Router, private location: Location) {
this.errorCodes = new ErrorCodes();
this.errorMessages = new ErrorMessagesComponent();
this.status = this.errorCodes.LOADING;
}
ngOnInit() {
this.properties = properties;
this.subscriptions.push(this.route.params.subscribe(params => {
this.hidden = true;
console.debug(this.communityId);
if(!this.communityId){
this.communityId = ConnectHelper.getCommunityFromDomain(this.properties.domain);
}
if(!this.communityId) {
this.communityId = params['community'];
}
console.debug(this.communityId, params)
this.getEmailPreferences();
}));
}
getEmailPreferences() {
if(!Session.isLoggedIn()){
//this.userValidMessage = "User session has expired. Please login again.";
if(this.showSaveResetButtons) {
this._router.navigate(['/user-info'], { queryParams: { "errorCode": LoginErrorCodes.NOT_VALID, "redirectUrl": this._router.url} });
}
} else {
this.status = this.errorCodes.LOADING;
this.savedMessage = "";
if(this.communityId && this.communityId != "openaire") {
this.preferencesFor = "community";
this.subscriptions.push(this._mailPrefsService.getUserEmailPreferencesForCommunity(this.communityId, this.properties.claimsAPIURL).subscribe(
data => {
if(data.code == "204") {
this.status = this.errorCodes.NONE;
this.initialNotifications = [{notify: true, frequency:24, openaireId: this.communityId}];
} else {
this.initialNotifications = data.data;
}
this.notifications = JSON.parse(JSON.stringify( this.initialNotifications ));
this.status = this.errorCodes.DONE;
this.hidden = false;
},
err => {
this.hidden = false;
this.handleErrors(err);
this.handleError("Error getting user email preferences for community with id: "+this.communityId, err);
}
));
} else {
this.preferencesFor = "project";
this.subscriptions.push(this._mailPrefsService.getUserEmailPreferencesForOpenaire(this.properties.claimsAPIURL).subscribe(
data => {
if(data.code == "204") {
this.status = this.errorCodes.NONE;
} else {
this.initialNotifications = data.data;
this.notifications = JSON.parse(JSON.stringify( this.initialNotifications ));
//this.notifications = this.initialNotifications.map(x => Object.assign({}, x));
//this.notifications = this.initialNotifications;
this.status = this.errorCodes.DONE;
}
},
err => {
//console.info(err);
this.handleErrors(err);
this.handleError("Error getting user email preferences for openaire", err);
}
));
}
}
}
changeNotify(notification: any, checked: boolean, index: number) {
if(!Session.isLoggedIn()){
//this.userValidMessage = "User session has expired. Please login again.";
if(this.showSaveResetButtons) {
this._router.navigate(['/user-info'], { queryParams: { "errorCode": LoginErrorCodes.NOT_VALID, "redirectUrl": this._router.url} });
}
} else {
this.savedMessage = "";
this.status = this.errorCodes.DONE;
notification.notify = checked;
this.prefsChanged[index] = true;
}
}
changeFrequency(index: number) {
if(!Session.isLoggedIn()){
//this.userValidMessage = "User session has expired. Please login again.";
if(this.showSaveResetButtons) {
this._router.navigate(['/user-info'], { queryParams: { "errorCode": LoginErrorCodes.NOT_VALID, "redirectUrl": this._router.url} });
}
} else {
this.savedMessage = "";
this.status = this.errorCodes.DONE;
if(this.initialNotifications[index].frequency != this.notifications[index].frequency) {
this.prefsChanged[index] = true;
}
}
}
saveNotification(index: number) {
if(this.notifications.length > 0 && this.initialNotifications.length > 0) {
if(!Session.isLoggedIn()){
//this.userValidMessage = "User session has expired. Please login again.";
if(this.showSaveResetButtons) {
this._router.navigate(['/user-info'], { queryParams: { "errorCode": LoginErrorCodes.NOT_VALID, "redirectUrl": this._router.url} });
}
} else {
if(JSON.stringify(this.notifications[index]) != JSON.stringify(this.initialNotifications[index])) {
this.status = this.errorCodes.LOADING;
this.savedMessage = "";
this.subscriptions.push(this._mailPrefsService.saveUserEmailPreferences(this.notifications[index], this.properties.claimsAPIURL).subscribe(
data => {
this.initialNotifications[index] = JSON.parse(JSON.stringify( this.notifications[index] ));
this.status = this.errorCodes.DONE;
/*UIkit.notification({
message : '<strong>Your email preferences for '+this.notifications[index].openaireName+' have been successfully changed<strong>',
status : 'success',
timeout : 3000,
pos : 'top-center'
});*/
this.savedMessage = "Notification settings for claims saved!";
},
err => {
//console.log(err);
this.handleError("Error saving user email preferences: "+JSON.stringify(this.notifications[index]), err);
this.status = this.errorCodes.NOT_SAVED;
}
));
}
else {
/*UIkit.notification({
message : '<strong>No changes selected for '+this.notifications[index].openaireName+' email preferences<strong>',
status : 'primary',
timeout : 3000,
pos : 'top-center'
});*/
this.savedMessage = "Notification settings for claims saved!";
}
}
}
}
restoreNotification(index: number) {
if(!Session.isLoggedIn()){
//this.userValidMessage = "User session has expired. Please login again.";
if(this.showSaveResetButtons) {
this._router.navigate(['/user-info'], { queryParams: { "errorCode": LoginErrorCodes.NOT_VALID, "redirectUrl": this._router.url} });
}
} else {
if(this.notifications.length > 0 && this.initialNotifications.length > 0) {
this.status = this.errorCodes.LOADING;
this.savedMessage = "";
this.notifications[index] = JSON.parse(JSON.stringify( this.initialNotifications[index] ));
this.status = this.errorCodes.DONE;
this.prefsChanged[index] = false;
}
}
}
/*
prefsChanged(index: number) : boolean {
if(this.notifications.length > 0 && this.initialNotifications.length > 0) {
if(JSON.stringify(this.notifications[index]) != JSON.stringify(this.initialNotifications[index])) {
return true;
}
}
return false;
}
*/
ngOnDestroy() {
this.subscriptions.forEach(subscription => {
if (subscription instanceof Subscriber) {
subscription.unsubscribe();
}
});
}
handleErrors(err){
//this.showErrorMessage = true;
//try{
var code = "";
if(!err.status) {
var error = err.json();
code = error.code;
} else {
code = err.status;
}
this.status = this.errorMessages.getErrorCode(code);
}
private handleError(message: string, error) {
console.error("User mail notification preferences Page (for claims): "+message, error);
}
//}catch (e) {
//console.log("Couldn't parse answer as json")
//this.showErrorMessage = true;
//}
}

View File

@ -0,0 +1,23 @@
import { NgModule} from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MailPrefsComponent } from './mailPrefs.component';
import { MailPrefsService } from './mailPrefs.service';
import {ErrorMessagesModule} from '../../utils/errorMessages.module';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
@NgModule({
imports: [
CommonModule, RouterModule, FormsModule, ReactiveFormsModule, ErrorMessagesModule, MatSlideToggleModule
],
declarations: [
MailPrefsComponent
],
providers:[MailPrefsService],
exports: [
MailPrefsComponent
]
})
export class MailPrefsModule { }

View File

@ -15,10 +15,9 @@ import {LoadingModule} from "../../utils/loading/loading.module";
@NgModule({
imports: [
ClassesRoutingModule,
CommonModule, RouterModule, FormsModule,
AlertModalModule, ReactiveFormsModule, AdminToolServiceModule, InputModule,
AdminTabsModule, PageContentModule, SearchInputModule, IconsModule, LoadingModule
AdminTabsModule, PageContentModule, ClassesRoutingModule, SearchInputModule, IconsModule, LoadingModule
],
declarations: [DivIdsComponent],
exports: [DivIdsComponent]

View File

@ -16,10 +16,9 @@ import {PageContentModule} from '../sharedComponents/page-content/page-content.m
@NgModule({
imports: [
ClassHelpContentFormRoutingModule,
CommonModule, FormsModule, RouterModule,
SafeHtmlPipeModule, CKEditorModule,
AlertModalModule, ReactiveFormsModule, AdminToolServiceModule, InputModule, MatSlideToggleModule, IconsModule, LoadingModule, PageContentModule
AlertModalModule, ReactiveFormsModule, ClassHelpContentFormRoutingModule, AdminToolServiceModule, InputModule, MatSlideToggleModule, IconsModule, LoadingModule, PageContentModule
],
declarations: [
ClassContentFormComponent

View File

@ -19,9 +19,8 @@ import {PageContentModule} from '../sharedComponents/page-content/page-content.m
@NgModule({
imports: [
ClassHelpContentsRoutingModule,
CommonModule, RouterModule, FormsModule, SafeHtmlPipeModule,
AlertModalModule, ReactiveFormsModule, MatSlideToggleModule, AdminToolServiceModule, InputModule,
AlertModalModule, ReactiveFormsModule, MatSlideToggleModule, AdminToolServiceModule, InputModule, ClassHelpContentsRoutingModule,
SearchInputModule, IconsModule, LoadingModule, HTMLToStringPipeModule, PageContentModule
],
declarations: [

View File

@ -17,9 +17,8 @@ import {LogoUrlPipeModule} from "../../utils/pipes/logoUrlPipe.module";
@NgModule({
imports: [
EntitiesRoutingModule,
CommonModule, RouterModule, FormsModule, AdminToolServiceModule,
AlertModalModule, ReactiveFormsModule, MatSlideToggleModule, InputModule, PageContentModule, AdminTabsModule, SearchInputModule, IconsModule, LoadingModule, LogoUrlPipeModule
AlertModalModule, ReactiveFormsModule, MatSlideToggleModule, InputModule, PageContentModule, AdminTabsModule, EntitiesRoutingModule, SearchInputModule, IconsModule, LoadingModule, LogoUrlPipeModule
],
declarations: [EntitiesComponent],
exports: [EntitiesComponent]

View File

@ -16,10 +16,9 @@ import {MatSlideToggleModule} from "@angular/material/slide-toggle";
@NgModule({
imports: [
PageHelpContentFormRoutingModule,
CommonModule, FormsModule, RouterModule,
SafeHtmlPipeModule, CKEditorModule,
AlertModalModule, ReactiveFormsModule, AdminToolServiceModule, InputModule, IconsModule, PageContentModule, LoadingModule, MatSlideToggleModule
AlertModalModule, ReactiveFormsModule, PageHelpContentFormRoutingModule, AdminToolServiceModule, InputModule, IconsModule, PageContentModule, LoadingModule, MatSlideToggleModule
],
declarations: [PageContentFormComponent],
exports: [PageContentFormComponent]

View File

@ -17,9 +17,8 @@ import {HTMLToStringPipeModule} from '../../utils/pipes/HTMLToStringPipe.module'
@NgModule({
imports: [
PageHelpContentsRoutingModule,
CommonModule, RouterModule, FormsModule, SafeHtmlPipeModule,
AlertModalModule, ReactiveFormsModule, MatSlideToggleModule, AdminToolServiceModule, InputModule, PageContentModule,
AlertModalModule, ReactiveFormsModule, MatSlideToggleModule, AdminToolServiceModule, InputModule, PageHelpContentsRoutingModule, PageContentModule,
SearchInputModule, IconsModule, LoadingModule, HTMLToStringPipeModule
],
declarations: [

View File

@ -18,9 +18,8 @@ import {LogoUrlPipeModule} from '../../utils/pipes/logoUrlPipe.module';
@NgModule({
imports: [
MenuRoutingModule,
CommonModule, RouterModule, FormsModule, AdminToolServiceModule,
AlertModalModule, ReactiveFormsModule, MatSlideToggleModule, InputModule, PageContentModule, AdminTabsModule, SearchInputModule, IconsModule, LoadingModule,
AlertModalModule, ReactiveFormsModule, MatSlideToggleModule, InputModule, PageContentModule, AdminTabsModule, MenuRoutingModule, SearchInputModule, IconsModule, LoadingModule,
TransitionGroupModule, LogoUrlPipeModule
],
declarations: [MenuComponent],

View File

@ -20,9 +20,8 @@ import {LogoUrlPipeModule} from "../../utils/pipes/logoUrlPipe.module";
@NgModule({
imports: [
PagesRoutingModule,
CommonModule, RouterModule, FormsModule, AlertModalModule, ReactiveFormsModule, MatSlideToggleModule, AdminToolServiceModule, InputModule,
MatAutocompleteModule, MatFormFieldModule, MatChipsModule, AdminTabsModule, PageContentModule, SearchInputModule, IconsModule, LoadingModule, LogoUrlPipeModule
MatAutocompleteModule, MatFormFieldModule, MatChipsModule, AdminTabsModule, PageContentModule, PagesRoutingModule, SearchInputModule, IconsModule, LoadingModule, LogoUrlPipeModule
],
declarations: [PagesComponent],
exports: [PagesComponent]

View File

@ -1,18 +1,17 @@
import {Option} from "../../sharedComponents/input/input.component";
import {StakeholderConfiguration} from "../../monitor-admin/utils/indicator-utils";
import {StakeholderEntities} from "../../monitor/entities/stakeholder";
export class PortalUtils {
export class PortalUtils{
portalTypes: Option[] = [
{value: 'explore', label: 'Explore Portal'},
{value: 'connect', label: 'Connect portal'},
{value: 'monitor', label: 'Monitor portal'},
{value: 'community', label: 'Community Gateway'},
{value: 'funder', label: StakeholderConfiguration.ENTITIES.funder + ' ' + StakeholderConfiguration.ENTITIES.stakeholder},
{value: 'ri', label: StakeholderConfiguration.ENTITIES.ri + ' ' + StakeholderConfiguration.ENTITIES.stakeholder},
{value: 'organization', label: StakeholderConfiguration.ENTITIES.organization + ' ' + StakeholderConfiguration.ENTITIES.stakeholder},
{value: 'project', label: StakeholderConfiguration.ENTITIES.project + ' ' + StakeholderConfiguration.ENTITIES.stakeholder},
{value: 'country', label: StakeholderConfiguration.ENTITIES.country + ' ' + StakeholderConfiguration.ENTITIES.stakeholder},
{value: 'funder', label: StakeholderEntities.FUNDER + ' Dashboard'},
{value: 'ri', label: StakeholderEntities.RI + ' Dashboard'},
{value: 'organization', label: StakeholderEntities.ORGANIZATION + ' Dashboard'},
{value: 'project', label: StakeholderEntities.PROJECT + ' Dashboard'}
];
}

View File

@ -15,10 +15,9 @@ import {LoadingModule} from "../../utils/loading/loading.module";
@NgModule({
imports: [
PortalsRoutingModule,
CommonModule, FormsModule, AlertModalModule,
ReactiveFormsModule,
RouterModule, AdminToolServiceModule, InputModule, AdminTabsModule, PageContentModule, IconsModule, SearchInputModule, LoadingModule
RouterModule, AdminToolServiceModule, InputModule, AdminTabsModule, PageContentModule, PortalsRoutingModule, IconsModule, SearchInputModule, LoadingModule
],
declarations: [PortalsComponent],
exports: [PortalsComponent]

View File

@ -132,6 +132,42 @@ export class PageContentComponent implements OnInit, AfterViewInit, OnDestroy {
this.sticky.footer = UIkit.sticky(this.sticky_footer.nativeElement, {end: true, offset: footer_offset});
}
/**
* @deprecated
*
* Should be smooth
*
* */
private observeBottom() {
let bottom = document.getElementById('bottom');
if (bottom) {
let bottomObs = new IntersectionObserver(entries => {
entries.forEach(entry => {
this.shouldSticky = !entry.isIntersecting;
})
});
this.subscriptions.push(bottomObs);
bottomObs.observe(bottom);
}
}
/**
* @deprecated
* */
private observeHeader() {
if (this.header) {
let headerObs = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.boundingClientRect.height > 0) {
this.layoutService.setReplaceHeader(!entry.isIntersecting);
}
})
});
this.subscriptions.push(headerObs);
headerObs.observe(this.header.nativeElement);
}
}
private observeStickyFooter() {
if (this.sticky_footer) {
let resizeObs = new ResizeObserver(entries => {

View File

@ -1,4 +1,4 @@
import {AfterViewInit, Injectable} from "@angular/core";
import {Injectable} from "@angular/core";
import {BehaviorSubject, Observable, Subscriber} from "rxjs";
import {ActivationStart, Router} from "@angular/router";
import {Icon} from "../../../sharedComponents/menu";
@ -83,16 +83,7 @@ export class LayoutService {
* Add hasStickyHeaderOnMobile: true in order to activate uk-sticky in header of mobile/tablet devices.
* */
private hasStickyHeaderOnMobileSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
/**
* Add a class in root element of the html. (For different theme apply)
* Handle it manually in the component, it doesn't use data
* */
private rootClassSubject: BehaviorSubject<string> = new BehaviorSubject<string>(null);
/**
* Display help pop-up on non-admin pages. (default true for the rest of the pages)
* */
private hasHelpPopUpSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(true);
private isBottomIntersectingSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
private subscriptions: any[] = [];
ngOnDestroy() {
@ -120,20 +111,6 @@ export class LayoutService {
this.subscriptions.push(resizeObs);
resizeObs.observe(document.documentElement);
}
if(typeof document !== "undefined") {
setTimeout(() => {
let bottom = document.getElementById('bottom');
if (bottom) {
let bottomObs = new IntersectionObserver(entries => {
entries.forEach(entry => {
this.isBottomIntersectingSubject.next(entry.isIntersecting);
})
});
this.subscriptions.push(bottomObs);
bottomObs.observe(bottom);
}
}, 500)
}
}
constructor(private router: Router) {
@ -352,26 +329,4 @@ export class LayoutService {
setHasStickyHeaderOnMobile(value: boolean) {
this.hasStickyHeaderOnMobileSubject.next(value);
}
get rootClass(): Observable<string> {
return this.rootClassSubject.asObservable();
}
setRootClass(value: string = null): void {
if(this.rootClassSubject.value != value) {
this.rootClassSubject.next(value);
}
}
get hasHelpPopUp(): Observable<boolean> {
return this.hasHelpPopUpSubject.asObservable();
}
setHasHelpPopUp(value: boolean) {
this.hasHelpPopUpSubject.next(value);
}
get isBottomIntersecting(): Observable<boolean> {
return this.isBottomIntersectingSubject.asObservable();
}
}

View File

@ -28,9 +28,6 @@
[class.hide-on-close]="backItem.icon">{{backItem.title}}</span>
</a>
</div>
<div *ngIf="logoURL" id="sidebar_logo" class="uk-margin-top">
<img [src]="logoURL">
</div>
<div *ngIf="items.length > 0" class="menu_section uk-margin-large-top" [class.mobile]="mobile" style="min-height: 30vh">
<ul #nav class="uk-list uk-nav" [class.uk-list-large]="mobile"
[class.uk-nav-default]="!mobile" [class.uk-nav-primary]="mobile" uk-nav="duration: 400">
@ -40,7 +37,7 @@
<a [routerLink]="getItemRoute(item)" [title]="item.title" (click)="item.items.length === 0?closeOffcanvas():null"
[queryParams]="item.route?item.params:null" [queryParamsHandling]="item.route?queryParamsHandling:null" class="uk-flex uk-flex-middle">
<div *ngIf="item.icon && (item.icon.svg || item.icon.name)" class="uk-width-auto">
<icon class="menu-icon" [customClass]="item.icon.class" [name]="item.icon.name" [ratio]="item.icon.ratio?item.icon.ratio:0.9" [svg]="item.icon.svg" [flex]="true"></icon>
<icon class="menu-icon" [customClass]="item.icon.class" [name]="item.icon.name" ratio="0.9" [svg]="item.icon.svg" [flex]="true"></icon>
</div>
<span [class.hide-on-close]="item.icon" class="uk-width-expand@l uk-text-truncate uk-margin-small-left">{{item.title}}</span>
<span *ngIf="item.items.length > 0" class="uk-nav-parent-icon hide-on-close"></span>

View File

@ -28,7 +28,6 @@ export class SideBarComponent implements OnInit, AfterViewInit, OnDestroy, OnCha
@Input() activeSubItem: string = '';
@Input() backItem: MenuItem = null;
@Input() queryParamsHandling;
@Input() logoURL: string;
@ViewChild("nav") nav: ElementRef;
@ViewChild("sidebar_offcanvas") sidebar_offcanvas: ElementRef;
public offset: number;

View File

@ -1,48 +0,0 @@
import {ChangeDetectorRef, Directive, OnInit} from "@angular/core";
import {BaseComponent} from "../../../sharedComponents/base/base.component";
import {MenuItem} from "../../../sharedComponents/menu";
import {LayoutService} from "./layout.service";
@Directive()
export class SidebarBaseComponent extends BaseComponent implements OnInit {
hasSidebar: boolean = false;
hasInternalSidebar: boolean = false;
hasAdminMenu: boolean = false;
/**
* Menu Items
* */
sideBarItems: MenuItem[] = [];
adminMenuItems: MenuItem[] = [];
backItem: MenuItem = null;
protected layoutService: LayoutService;
protected cdr: ChangeDetectorRef;
constructor() {
super();
}
ngOnInit() {
this.subscriptions.push(this.layoutService.hasSidebar.subscribe(hasSidebar => {
this.hasSidebar = hasSidebar;
this.cdr.detectChanges();
}));
this.subscriptions.push(this.layoutService.hasInternalSidebar.subscribe(hasInternalSidebar => {
this.hasInternalSidebar = hasInternalSidebar;
this.cdr.detectChanges();
}));
this.subscriptions.push(this.layoutService.hasAdminMenu.subscribe(hasAdminMenu => {
this.hasAdminMenu = hasAdminMenu;
this.cdr.detectChanges();
}));
this.layoutService.setOpen(true);
}
public get open() {
return this.layoutService.open;
}
public get hover() {
return this.layoutService.hover;
}
}

View File

@ -8,26 +8,26 @@
<div class="uk-flex uk-flex-left@m uk-flex-center uk-width-expand">
<ul class="uk-subnav uk-subnav-pill">
<li [class.uk-active]="showCurrent" (click)="showCurrent = true">
<a class="uk-text-capitalize">{{roleUtils.roles[role]}}s</a>
<a class="uk-text-capitalize">{{role}}s</a>
</li>
<li [class.uk-active]="!showCurrent" (click)="showCurrent = false">
<a>Pending {{roleUtils.roles[role]}}s</a>
<a>Pending {{role}}s</a>
</li>
</ul>
</div>
<div class="uk-width-expand@m uk-width-1-1 uk-grid uk-flex-right@m uk-flex-center uk-flex-middle" uk-grid>
<div *ngIf="showCurrent" [disabled]="loadActive" search-input class="uk-width-expand@l uk-width-1-1"
[searchControl]="filterForm.get('active')" [expandable]="true" [placeholder]="'Search ' + roleUtils.roles[role] + 's'" searchInputClass="outer">
[searchControl]="filterForm.get('active')" [expandable]="true" [placeholder]="'Search ' + role + 's'" searchInputClass="outer">
</div>
<div *ngIf="!showCurrent" [disabled]="loadPending" search-input class="uk-width-expand@l uk-width-1-1"
[searchControl]="filterForm.get('pending')" [expandable]="true" [placeholder]="'Search invitations'" searchInputClass="outer">
</div>
<div>
<button *ngIf="canInvite" class="uk-button uk-button-default uk-flex uk-flex-middle"
<button *ngIf="exists" class="uk-button uk-button-default uk-flex uk-flex-middle"
[attr.uk-tooltip]="inviteDisableMessage" [class.uk-disabled]="loadPending || loadPending"
[disabled]="loadActive || loadPending || !!inviteDisableMessage" (click)="openInviteModal()">
<icon name="person_add" [flex]="true" type="filled"></icon>
<span class="uk-margin-small-left uk-text-bold uk-text-uppercase">Invite {{roleUtils.roles[role]}}</span>
<span class="uk-margin-small-left uk-text-bold uk-text-uppercase">Invite {{role}}</span>
</button>
<button *ngIf="!exists && isCurator" class="uk-button uk-button-default uk-flex uk-flex-middle"
(click)="openCreateRoleModal()">
@ -47,16 +47,16 @@
<div *ngIf="!loadActive && !loadPending">
<div *ngIf="(showCurrent && showActive.length == 0) || (!showCurrent && showPending.length == 0)"
class="uk-card uk-card-default uk-padding-large uk-text-center uk-margin-bottom uk-text-bold">
<div *ngIf="showCurrent">No {{roleUtils.roles[role]}}s found</div>
<div *ngIf="!showCurrent">No pending {{roleUtils.roles[role]}} invitations found</div>
<div *ngIf="showCurrent">No {{role}}s found</div>
<div *ngIf="!showCurrent">No pending {{role}} invitations found</div>
</div>
<div *ngIf="(showCurrent && showActive.length > 0) || (!showCurrent && showPending.length > 0)">
<no-load-paging *ngIf="showCurrent" [type]="(showActive.length > 1)?(roleUtils.roles[role] + 's'):role"
<no-load-paging *ngIf="showCurrent" [type]="(showActive.length > 1)?(role + 's'):role"
(pageChange)="updateActivePage($event)"
[page]="activePage" [pageSize]="pageSize"
[totalResults]="showActive.length">
</no-load-paging>
<no-load-paging *ngIf="!showCurrent" [type]="roleUtils.roles[role] + ' ' + (showPending.length > 1?'invitations':'invitation')"
<no-load-paging *ngIf="!showCurrent" [type]="role + ' ' + (showPending.length > 1?'invitations':'invitation')"
(pageChange)="updatePendingPage($event)"
[page]="pendingPage" [pageSize]="pageSize"
[totalResults]="showPending.length">
@ -109,12 +109,12 @@
</modal-alert>
<modal-alert #deleteModal [overflowBody]="false" (alertOutput)="deleteActive()" classTitle="uk-background-primary uk-light">
<div *ngIf="selectedUser">
Are you sure you want to remove <span class="uk-text-bold">{{selectedUser}}</span> from {{roleUtils.roles[role]}}s?
Are you sure you want to remove <span class="uk-text-bold">{{selectedUser}}</span> from {{role}}s?
</div>
</modal-alert>
<modal-alert #deletePendingModal [overflowBody]="false" (alertOutput)="deletePending()" classTitle="uk-background-primary uk-light">
<div *ngIf="selectedUser">
Are you sure you want to cancel {{roleUtils.roles[role]}} invitation of <span class="uk-text-bold">{{selectedUser}}</span>?
Are you sure you want to cancel {{role}} invitation of <span class="uk-text-bold">{{selectedUser}}</span>?
</div>
</modal-alert>
<modal-alert #createRoleModal [overflowBody]="false" (alertOutput)="createGroup()" classTitle="uk-background-primary uk-light"

View File

@ -8,12 +8,19 @@ import {
SimpleChanges,
ViewChild
} from '@angular/core';
import {UntypedFormArray, UntypedFormBuilder, UntypedFormGroup, ValidatorFn, Validators} from '@angular/forms';
import {
UntypedFormArray,
UntypedFormBuilder,
UntypedFormControl,
UntypedFormGroup,
ValidatorFn,
Validators
} from '@angular/forms';
import {AlertModal} from "../../../utils/modal/alert";
import {UserRegistryService} from "../../../services/user-registry.service";
import {EnvProperties} from "../../../utils/properties/env-properties";
import {properties} from "../../../../../environments/environment";
import {Role, RoleUtils, Session, User} from "../../../login/utils/helper.class";
import {Role, Session, User} from "../../../login/utils/helper.class";
import {UserManagementService} from "../../../services/user-management.service";
import {Router} from "@angular/router";
import {StringUtils} from "../../../utils/string-utils.class";
@ -22,8 +29,8 @@ import {forkJoin, of, Subscription} from "rxjs";
import {NotificationHandler} from "../../../utils/notification-handler";
import {ClearCacheService} from "../../../services/clear-cache.service";
import {catchError, map, tap} from "rxjs/operators";
import notification = CKEDITOR.plugins.notification;
import {InputComponent} from "../../../sharedComponents/input/input.component";
import {StakeholderUtils} from "../../../monitor-admin/utils/indicator-utils";
class InvitationResponse {
email: string;
@ -44,9 +51,7 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
@Input()
public id: string;
@Input()
set type(type: string) {
this._type = Role.mapType(type);
}
public type: string;
@Input()
public name: string;
@Input()
@ -56,8 +61,6 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
@Input()
public deleteAuthorizationLevel: 'curator' | 'manager' = 'curator';
@Input()
public inviteAuthorizationLevel: 'curator' | 'manager' = 'manager';
@Input()
public message: string = null;
@Input()
public emailComposer: Function;
@ -91,14 +94,12 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
@ViewChild('deleteModal') deleteModal: AlertModal;
@ViewChild('deletePendingModal') deletePendingModal: AlertModal;
@ViewChild('createRoleModal') createRoleModal: AlertModal;
public stakeholderUtils: StakeholderUtils = new StakeholderUtils();
public roleUtils: RoleUtils = new RoleUtils();
private _type: string;
constructor(private userRegistryService: UserRegistryService,
private userManagementService: UserManagementService,
private clearCacheService: ClearCacheService,
private notificationService: NotificationService,
private router: Router,
private cdr: ChangeDetectorRef,
private fb: UntypedFormBuilder) {
}
@ -147,8 +148,9 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
updateLists() {
this.loadActive = true;
this.loadPending = true;
this.subs.push(this.userRegistryService.getActive(this._type, this.id, this.role, true).subscribe(users => {
this.subs.push(this.userRegistryService.getActive(this.type, this.id, this.role).subscribe(users => {
this.active = users;
// users.forEach(user => this.active.push(user));
this.filterActiveBySearch(this.filterForm.value.active);
this.loadActive = false;
this.exists = true;
@ -160,7 +162,7 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
}
this.loadActive = false;
}));
this.subs.push(this.userRegistryService.getPending(this._type, this.id, this.role, true).subscribe(users => {
this.subs.push(this.userRegistryService.getPending(this.type, this.id, this.role).subscribe(users => {
this.pending = users;
this.filterPendingBySearch(this.filterForm.value.pending);
this.loadPending = false;
@ -189,7 +191,7 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
openDeleteModal(item: any) {
if (this.showCurrent) {
this.selectedUser = item.email;
this.deleteModal.alertTitle = 'Delete ' + this.roleUtils.roles[this.role];
this.deleteModal.alertTitle = 'Delete ' + this.role;
this.deleteModal.open();
} else {
this.selectedUser = item;
@ -199,7 +201,7 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
}
openInviteModal() {
this.inviteModal.alertTitle = 'Invite ' + this.roleUtils.roles[this.role];
this.inviteModal.alertTitle = 'Invite ' + this.role;
this.inviteModal.okButtonLeft = false;
this.inviteModal.okButtonText = 'Send';
this.emailsForm = this.fb.array([], Validators.required);
@ -212,8 +214,8 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
this.createRoleModal.okButtonLeft = false;
this.createRoleModal.okButtonText = 'Create';
this.roleFb = this.fb.group({
name: this.fb.control(Role.roleName(this._type, this.id), Validators.required),
description: this.fb.control(Role.roleName(this._type, this.id), Validators.required)
name: this.fb.control(Role.mapType(this.type) + '.' + this.id, Validators.required),
description: this.fb.control(Role.mapType(this.type) + ' ' + this.id, Validators.required)
});
setTimeout(() => {
this.roleFb.get('name').disable();
@ -224,7 +226,7 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
deleteActive() {
this.loadActive = true;
this.subs.push(this.userRegistryService.remove(this._type, this.id, this.selectedUser, this.role).subscribe(() => {
this.subs.push(this.userRegistryService.remove(this.type, this.id, this.selectedUser, this.role).subscribe(() => {
this.active = this.active.filter(user => user.email != this.selectedUser);
if (this.currentActivePage.length === 0) {
this.activePage = 1;
@ -242,13 +244,13 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
deletePending() {
this.loadPending = true;
this.subs.push(this.userRegistryService.cancelInvitation(this._type, this.id, this.selectedUser, this.role).subscribe(() => {
this.subs.push(this.userRegistryService.cancelInvitation(this.type, this.id, this.selectedUser, this.role).subscribe(() => {
this.pending = this.pending.filter(user => user != this.selectedUser);
this.filterPendingBySearch(this.filterForm.value.pending);
if (this.currentPendingPage.length === 0) {
this.pendingPage = 1;
}
NotificationHandler.rise(StringUtils.capitalize(this.roleUtils.roles[this.role]) + ' invitation to ' + this.selectedUser + ' has been <b>canceled</b>');
NotificationHandler.rise(StringUtils.capitalize(this.role) + ' invitation to ' + this.selectedUser + ' has been <b>canceled</b>');
this.loadPending = false;
}, error => {
NotificationHandler.rise('An error has occurred. Please try again later', 'danger');
@ -269,12 +271,12 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
let current = null;
let invitations = (<Array<any>>this.emailsForm.value).map(email => {
current = email;
return this.userRegistryService.invite(this._type, this.id, {
return this.userRegistryService.invite(this.type, this.id, {
link: this.link,
email: this.emailComposer(this.name, email, this.role)
}, this.role).pipe(catchError(error => {
return of(null);
}), map(invitation => new InvitationResponse(email, invitation)));
}, this.role).pipe(map(invitation => new InvitationResponse(email, invitation), catchError(error => {
return of(new InvitationResponse(current, null));
})));
});
this.subs.push(forkJoin(invitations).subscribe(responses => {
let notifications = responses.map(response => {
@ -283,7 +285,7 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
if (!this.pending.includes(response.email)) {
this.pending.push(response.email);
}
if(this.notificationFn && properties.notificationsAPIURL) {
if(this.notificationFn) {
return this.notificationService.sendNotification(this.notificationFn(this.name, response.email, this.role, response.invitation)).pipe(map(notification => {
return notification;
}), tap(() => {
@ -296,8 +298,7 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
return of(null);
}
} else {
NotificationHandler.rise('An error has occurred while sending the invitation mail to ' +
response.email + '.Check if the user is already a ' + this.roleUtils.roles[this.role] + ' or try again later', 'danger');
NotificationHandler.rise('An error has occurred while sending the invitation mail to ' + response.email + '.Please try again later', 'danger');
return of(null);
}
});
@ -312,12 +313,12 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
createGroup() {
this.loadActive = true;
this.loadPending = true;
this.userRegistryService.createRole(this._type, this.id).subscribe(() => {
this.userRegistryService.createRole(this.type, this.id).subscribe(() => {
NotificationHandler.rise('Group has been <b> successfully created</b>');
this.updateLists();
}, error => {
if(error.status === 409) {
NotificationHandler.rise('Group already exists. You can try to invite a ' + this.roleUtils.roles[this.role] + ' instead.', 'warning');
NotificationHandler.rise('Group already exists. You can try to invite a ' + this.role + ' instead.', 'warning');
this.updateLists();
} else {
NotificationHandler.rise('An error has occurred. Please try again later', 'danger');
@ -330,21 +331,17 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
public get canDelete() {
return (this.deleteAuthorizationLevel === 'curator'?this.isCurator:this.isManager);
}
public get canInvite() {
return this.exists && (this.inviteAuthorizationLevel === 'curator'?this.isCurator:this.isManager);
}
public isMe(userId: string) {
return userId && userId.includes(this.user.id) && !this.isCurator;
}
public get isManager(): boolean {
return this.isCurator || !!Session.isManager(this._type, this.id, this.user);
return this.isCurator || !!Session.isManager(this.type, this.id, this.user);
}
public get isCurator(): boolean {
return this.isPortalAdmin || !!Session.isCurator(this._type, this.user);
return this.isPortalAdmin || !!Session.isCurator(this.type, this.user);
}
public get isPortalAdmin(): boolean {

View File

@ -105,7 +105,7 @@ export class SubscribersComponent implements OnInit, OnDestroy, OnChanges {
updateList() {
this.loading = true;
this.subs.push( this.userRegistryService.getActive(this.type, this.id, 'member', true).subscribe(users => {
this.subs.push( this.userRegistryService.getActive(this.type, this.id, 'member').subscribe(users => {
this.subscribers = users;
this.filterBySearch(this.filterForm.value.keyword);
this.loading = false;
@ -141,8 +141,8 @@ export class SubscribersComponent implements OnInit, OnDestroy, OnChanges {
this.createRoleModal.okButtonLeft = false;
this.createRoleModal.okButtonText = 'create';
this.roleFb = this.fb.group({
name: this.fb.control(Role.roleName(this.type, this.id), Validators.required),
description: this.fb.control(Role.roleName(this.type, this.id), Validators.required)
name: this.fb.control(Role.mapType(this.type) + '.' + this.id, Validators.required),
description: this.fb.control(Role.mapType(this.type) + ' ' + this.id, Validators.required)
});
setTimeout(() => {
this.roleFb.get('name').disable();

View File

@ -15,7 +15,7 @@ import {FullScreenModalComponent} from '../utils/modal/full-screen-modal/full-sc
@Component({
selector: 'deposit-first-page',
template: `
<div>
<div class="deposit">
<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>

View File

@ -5,6 +5,7 @@ import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import {PiwikServiceModule} from '../utils/piwik/piwikService.module';
import {HelperModule} from '../utils/helper/helper.module';
import {Schema2jsonldModule} from '../sharedComponents/schema2jsonld/schema2jsonld.module';
import { SEOServiceModule } from '../sharedComponents/SEO/SEOService.module';
@ -17,6 +18,7 @@ import {FullScreenModalModule} from '../utils/modal/full-screen-modal/full-scree
imports: [
CommonModule, FormsModule,
RouterModule,
PiwikServiceModule,
HelperModule,
Schema2jsonldModule, SEOServiceModule, BreadcrumbsModule, SearchInputModule,
FullScreenModalModule

View File

@ -9,6 +9,7 @@ import {SearchResultsModule } from '../searchPages/searchUtils/searchResults.mod
import {DataProvidersServiceModule} from '../services/dataProvidersService.module';
import {SearchFormModule} from '../searchPages/searchUtils/searchForm.module';
import {IsRouteEnabled} from '../error/isRouteEnabled.guard';
import {SearchDataProvidersModule} from "../searchPages/searchDataProviders.module";
import {BreadcrumbsModule} from "../utils/breadcrumbs/breadcrumbs.module";
import {SearchInputModule} from "../sharedComponents/search-input/search-input.module";
@ -24,7 +25,7 @@ import {SearchInputModule} from "../sharedComponents/search-input/search-input.m
declarations: [
SearchDataprovidersToDepositComponent
],
providers:[],
providers:[ IsRouteEnabled],
exports: [
SearchDataprovidersToDepositComponent
]

View File

@ -11,7 +11,7 @@ import * as url from "url";
@Injectable()
export class ErrorInterceptorService implements HttpInterceptor {
private static UNAUTHORIZED_WHITELIST = [properties.orcidAPIURL, properties.registryUrl? (properties.registryUrl + 'verification/'):null, properties.eoscDataTransferAPI].filter(value => !!value);
private static UNAUTHORIZED_WHITELIST = [properties.userInfoUrl, properties.orcidAPIURL, properties.registryUrl? (properties.registryUrl + 'verification/'):null, properties.eoscDataTransferAPI].filter(value => !!value);
private url: string = null;
constructor(private router: Router) {

View File

@ -6,9 +6,7 @@ import {ConfigurationService} from '../utils/configuration/configuration.service
import {ConnectHelper} from '../connect/connectHelper';
import {properties} from "../../../environments/environment";
@Injectable({
providedIn: 'root'
})
@Injectable()
export class IsRouteEnabled {
constructor(private router: Router,

View File

@ -7,9 +7,9 @@
<div class="uk-container uk-container-large uk-section" uk-scrollspy="target: [uk-scrollspy-class]; cls: uk-animation-slide-bottom-medium; delay: 200">
<div class="uk-grid uk-grid-large uk-grid-stack uk-padding-small" uk-grid>
<div class="uk-width-3-5@m uk-width-1-1@s uk-flex uk-flex-column uk-flex-center">
<!-- <span class="uk-align-left uk-margin-remove-bottom">-->
<!-- <span uk-scrollspy-class class="uk-text-large" style="color: #EEB204">Beta</span>-->
<!-- </span>-->
<span class="uk-align-left uk-margin-remove-bottom">
<span uk-scrollspy-class class="uk-text-large" style="color: #EEB204">Beta</span>
</span>
<div style="max-width: 600px;">
<h1 uk-scrollspy-class class="uk-h1 uk-margin-remove-top">
<span>Fields of Science <span class="uk-text-primary">.</span></span>
@ -32,15 +32,13 @@
</div>
</div>
<div class="uk-width-2-5@m uk-width-1-1@s uk-text-center" uk-scrollspy-class>
<img src="assets/common-assets/fos/fos-hero-img.svg" loading="lazy" alt="FoS logo">
<img src="assets/common-assets/fos/fos-hero-img.svg" loading="lazy">
</div>
</div>
</div>
<div *ngIf="fos?.length" id="levels" class="uk-container uk-container-large uk-section"
uk-scrollspy="target: [uk-scrollspy-class]; cls: uk-animation-slide-bottom-medium; delay: 200">
<div *ngIf="fos?.length" class="uk-container uk-container-large uk-section" uk-scrollspy="target: [uk-scrollspy-class]; cls: uk-animation-slide-bottom-medium; delay: 200">
<div class="uk-visible@m">
<div id="keyword_search" uk-sticky="offset: 50;" class="uk-sticky uk-background-default uk-padding uk-padding-remove-bottom uk-padding-remove-horizontal">
<div uk-sticky="offset: 50;" class="uk-sticky uk-background-default uk-padding uk-padding-remove-bottom uk-padding-remove-horizontal">
<div class="uk-flex uk-flex-right uk-margin-small-bottom">
<div search-input [searchControl]="keywordControl" [options]="fosOptions" iconPosition="left" placeholder="Write a key word to filter the content"
searchInputClass="border-bottom" class="uk-width-large"></div>
@ -55,29 +53,11 @@
<ul *ngIf="!keyword" class="uk-tab uk-tab-left">
<li *ngFor="let item of fos; index as i" [class.uk-active]="activeSection === item.id"
class="uk-margin-small-bottom uk-text-capitalize">
<a (click)="selectedParentLevels=[]" routerLink="./" [fragment]="item.id">
<div>
{{item.id}}
<ng-container *ngIf="selectedParentLevels.length > 0 && selectedParentLevels[0].id==item.id">
<div class="uk-margin-left uk-margin-xsmall-top">
<span class="uk-flex uk-flex-middle">
<icon [flex]="true" ratio="1" name="subdirectory_arrow_right"></icon>
{{selectedParentLevels[1].id}}
</span>
<div class="uk-margin-left uk-margin-xsmall-top">
<span class="uk-flex uk-flex-middle">
<icon [flex]="true" ratio="1" name="subdirectory_arrow_right"></icon>
{{selectedParentLevels[2].label}}
</span>
</div>
</div>
</ng-container>
</div>
</a>
<a routerLink="./" [fragment]="item.id">{{item.id}}</a>
</li>
</ul>
<ul *ngIf="keyword?.length" class="uk-tab uk-tab-left">
<li *ngFor="let item of viewResults; index as i"
<li *ngFor="let item of viewResults; index as i"
class="uk-margin-small-bottom uk-text-capitalize" [class.uk-active]="activeSection === item.id">
<a routerLink="./" [fragment]="item.id">{{item.id}}</a>
</li>
@ -111,34 +91,7 @@
</div>
</div>
<div class="uk-width-expand@m">
<div *ngIf="!keyword && selectedParentLevels.length > 0" [id]="selectedParentLevels[0].id+'||'+selectedParentLevels[1].code+'||'+selectedParentLevels[2].code">
<a (click)="backClicked();"
class="uk-button-link uk-flex uk-flex-middle uk-margin-bottom">
<icon name="arrow_back" visuallyHidden="back" flex="true" ratio="1"></icon>
<span class="uk-margin-small-left">Back</span>
</a>
<div>
<h2 class="uk-h4 uk-text-capitalize uk-margin-remove">
<a [routerLink]="properties.searchLinkToResults" [queryParams]="buildFosQueryParam(selectedParentLevels[2])"
class="uk-link-text">
{{selectedParentLevels[2].label}}
</a>
</h2>
<div class="uk-grid uk-child-width-1-3 uk-margin-large-top uk-margin-xlarge-bottom" uk-grid="masonry: false">
<div *ngFor="let level4 of selectedParentLevels[2].children">
<div class="uk-text-capitalize">
<h3 class="uk-h6 uk-margin-small-bottom">
<a [routerLink]="properties.searchLinkToResults" [queryParams]="buildFosQueryParam(level4)"
class="uk-link-text">
{{level4.label}}
</a>
</h3>
</div>
</div>
</div>
</div>
</div>
<ng-container *ngIf="!keyword && selectedParentLevels.length == 0">
<ng-container *ngIf="!keyword">
<div [id]="item.id" *ngFor="let item of fos; index as i">
<div class="uk-text-capitalize">
<h2 class="uk-h4 uk-margin-remove">
@ -157,51 +110,12 @@
{{child.id}}
</a>
</h3>
<!-- class="parent uk-transition-toggle" tabindex="0"-->
<div *ngFor="let subChild of child.children; let i=index" style="margin-bottom: 7px;"
class="uk-flex uk-flex-middle uk-flex-between uk-transition-toggle" tabindex="0">
<!-- <span class="uk-flex uk-flex-between">-->
<a [routerLink]="properties.searchLinkToResults" [queryParams]="buildFosQueryParam(subChild)"
class="uk-link-text uk-width-expand">
{{searchFieldsHelper.getFosParameter() == 'foslabel' ? subChild.label : subChild.id}}
</a>
<span *ngIf="properties.environment == 'development' && subChild.children?.length > 0" (click)="moreClicked(item, child, subChild)"
class="uk-transition-fade uk-width-auto uk-flex uk-flex-middle uk-margin-left label4 uk-text-small uk-text-meta">
<!-- <a class="view-more-less-link uk-link-text uk-text-lowercase">-->
<!-- +{{subChild.children.length}} more-->
<!--&lt;!&ndash; <icon [flex]="true" ratio="1" name="chevron_right"></icon>&ndash;&gt;-->
<!-- </a>-->
<icon [flex]="true" ratio="0.7" name="subdirectory_arrow_right"></icon>
<a class="uk-link-text uk-text-lowercase">
more
</a>
</span>
<!-- <div *ngIf="subChild.children?.length > 0" (click)="selectedParentLevels=[item, child, subChild]"-->
<!-- class="uk-flex uk-flex-middle uk-margin-left label4 uk-text-small uk-text-meta">-->
<!-- <a class="uk-link-text">{{subChild.children.length}} Subcategories</a>-->
<!-- <icon [flex]="true" ratio="1" name="chevron_right"></icon>-->
<!-- </div>-->
<!-- <span *ngIf="subChild?.children?.length > 0" (click)="fosAccordions.set(subChild.id, !fosAccordions.get(subChild.id))" class="uk-accordion-title uk-padding-remove"></span>-->
<!-- </span>-->
<!-- <div *ngIf="fosAccordions.get(subChild.id)" class="uk-margin-left">-->
<!-- <div *ngFor="let level4 of subChild.children" style="margin-bottom: 7px;">-->
<!-- <a [routerLink]="properties.searchLinkToResults" [queryParams]="buildFosQueryParam(level4)"-->
<!-- class="label4 uk-text-small uk-text-meta">-->
<!-- {{searchFieldsHelper.getFosParameter() == 'foslabel' ? level4.label : level4.id}}-->
<!-- </a>-->
<!-- </div>-->
<!-- </div>-->
<!-- uk-transition-slide-top-->
<!-- <div *ngIf="subChild.children?.length > 0" class="uk-transition-slide-top">-->
<!-- <div class="child">-->
<!-- <a class="uk-link uk-margin-left">{{subChild.children.length}} Subcategories ></a>-->
<!-- </div>-->
<!-- </div>-->
</div>
<div *ngFor="let subChild of child.children" style="margin-bottom: 5px;">
<a [routerLink]="properties.searchLinkToResults" [queryParams]="buildFosQueryParam(subChild)"
class="uk-link-text">
{{subChild.label}}
</a>
</div>
</div>
</div>
</div>
@ -223,16 +137,10 @@
class="uk-link-text" [innerHTML]="highlightKeyword(subItem.id)">
</a>
</h3>
<div *ngFor="let subSubItem of subItem.children" style="margin-bottom: 7px;">
<div *ngFor="let subSubItem of subItem.children" style="margin-bottom: 5px;">
<a [routerLink]="properties.searchLinkToResults" [queryParams]="buildFosQueryParam(subSubItem)"
class="uk-link-text" [innerHTML]="highlightKeyword(searchFieldsHelper.getFosParameter() == 'foslabel' ? subSubItem.label : subSubItem.id)">
class="uk-link-text" [innerHTML]="highlightKeyword(subSubItem.label)">
</a>
<div *ngFor="let level4 of subSubItem?.children" class="uk-margin-left">
<a [routerLink]="properties.searchLinkToResults" [queryParams]="buildFosQueryParam(level4)"
class="uk-text-small uk-text-meta uk-margin-xsmall-bottom" [innerHTML]="highlightKeyword(searchFieldsHelper.getFosParameter() == 'foslabel' ? level4.label : level4.id)">
</a>
</div>
</div>
</div>
</div>

View File

@ -15,8 +15,6 @@ import {PiwikService} from "../utils/piwik/piwik.service";
import {debounceTime, distinctUntilChanged} from "rxjs/operators";
import Timeout = NodeJS.Timeout;
import {ISVocabulariesService} from "../utils/staticAutoComplete/ISVocabularies.service";
import {SearchFields} from "../utils/properties/searchFields";
import {HelperFunctions} from "../utils/HelperFunctions.class";
declare var UIkit;
@ -29,8 +27,6 @@ export class FosComponent implements OnInit, OnDestroy {
public url: string = null;
public pageTitle: string = "OpenAIRE | Fields of Science";
public pageDescription: string = "We have integrated a Field-of-Science (FoS) taxonomy into our dataset to organize and discover research more effectively. Using the full capabilities of the OpenAIRE Graph (full-texts, citations, references, venues) we apply AI and bring forward any multidisciplinarity potential.";
public scrollPos = 0;
public selectedParentLevels = [];
public fos: any[] = [];
public fosOptions: string[] = [];
public activeSection: string;
@ -50,7 +46,6 @@ export class FosComponent implements OnInit, OnDestroy {
private timeout: Timeout;
@ViewChild('tabs') tabs: ElementRef;
public sliderInit: boolean = false;
private searchFieldsHelper: SearchFields = new SearchFields();
constructor(
private vocabulariesService: ISVocabulariesService,
@ -85,43 +80,21 @@ export class FosComponent implements OnInit, OnDestroy {
item.classList.remove('uk-active');
});
if (this.route.snapshot.fragment) {
let splitFragment = this.route.snapshot.fragment.split("||");
this.activeSection = this.route.snapshot.fragment.split("||")[0];
let i = this.fos.findIndex(item => (item.id == this.route.snapshot.fragment || this.route.snapshot.fragment.startsWith(item.id+"||")));
if(i <0 || i>this.fos.length-1) {
this._router.navigate(['./'], {fragment: "", relativeTo: this.route, state: {disableScroll: true}});
} else {
if (splitFragment.length > 1) {
let level1 = this.fos[i];
let level2 = null;
let level3 = null;
if (level1.children) {
level2 = level1.children.find(item => item.code == splitFragment[1]);
if (level2 && level2.children) {
level3 = level2.children.find(item => item.code == splitFragment[2]);
this.selectedParentLevels = [this.fos[i], level2, level3];
}
}
if(!level2 || !level3) {
this._router.navigate(['./'], {fragment: level1.id, relativeTo: this.route, state: {disableScroll: true}});
}
} else {
slider.show(i);
}
}
this.activeSection = this.route.snapshot.fragment;
let i = this.fos.findIndex(item => item.id == this.route.snapshot.fragment);
slider.show(i);
} else {
this.activeSection = this.fos[0].id;
}
this.cdr.detectChanges();
});
}
this.subscriptions.push(this.route.fragment.subscribe(fragment => {
if(fragment) {
this.activeSection = fragment.split("||")[0];
this.activeSection = fragment;
if(this.tabs) {
let slider = UIkit.slider(this.tabs.nativeElement);
let i = this.fos.findIndex(item => (item.id == fragment || fragment.startsWith(item.id+"||")));
let i = this.fos.findIndex(item => item.id == fragment);
slider.show(i);
}
} else {
@ -130,16 +103,13 @@ export class FosComponent implements OnInit, OnDestroy {
}));
this.keywordControl = this.fb.control('');
this.subscriptions.push(this.keywordControl.valueChanges.pipe(debounceTime(500), distinctUntilChanged()).subscribe(value => {
if(this.keyword !== undefined || value) {
this.selectedParentLevels = [];
}
this.keyword = value;
this.findMatches(this.keyword);
if (typeof IntersectionObserver !== 'undefined') {
setTimeout(() => {
this.setObserver();
});
}
this.keyword = value;
this.findMatches(this.keyword);
if (typeof IntersectionObserver !== 'undefined') {
setTimeout(() => {
this.setObserver();
});
}
}));
});
}
@ -182,16 +152,11 @@ export class FosComponent implements OnInit, OnDestroy {
this.fos.forEach(fos => {
this.fosOptions.push(fos.id);
if(fos.children) {
fos.children.forEach(l2 => {
this.fosOptions.push(l2.id);
if(l2.children) {
l2.children.forEach(l3 => {
this.fosOptions.push(l3.id);
if(l3.children) {
l3.children.forEach(l4 => {
this.fosOptions.push(l4.id);
})
}
fos.children.forEach(child => {
this.fosOptions.push(child.id);
if(child.children) {
child.children.forEach(child2 => {
this.fosOptions.push(child2.id);
});
}
});
@ -203,29 +168,19 @@ export class FosComponent implements OnInit, OnDestroy {
this.viewResults = JSON.parse(JSON.stringify(this.fos));
let matchLevel1: boolean = false;
let matchLevel2: boolean = false;
let matchLevel3: boolean = false;
// 1st level search
if(this.viewResults.length) {
this.viewResults = this.viewResults.filter(item => {
matchLevel1 = !!item.id.includes(value?.toLowerCase());
// 2nd level search
// // 2nd level search
if(item.children?.length && !matchLevel1) {
item.children = item.children.filter(subItem => {
matchLevel2 = !!subItem.id.includes(value?.toLowerCase());
// 3rd level search
if(subItem.children?.length && !matchLevel2) {
subItem.children = subItem.children.filter(subSubItem => {
matchLevel3 = subSubItem.id.includes(value?.toLowerCase());
// 4th level search
if(subSubItem.children?.length && !matchLevel3) {
subSubItem.children = subSubItem.children.filter(level4Item => {
return level4Item.id.toLowerCase().includes(value?.toLowerCase())
});
}
return subSubItem.children?.length > 0 || matchLevel3;
});
subItem.children = subItem.children.filter(subSubItem => subSubItem.id.includes(value?.toLowerCase()));
}
return subItem.children?.length > 0;
return subItem.children?.length > 0 || matchLevel2;
});
}
return item.children?.length > 0;
@ -234,7 +189,7 @@ export class FosComponent implements OnInit, OnDestroy {
}
highlightKeyword(name) {
if(name.toLowerCase().includes(this.keyword.toLowerCase())) {
if(name.includes(this.keyword.toLowerCase())) {
return name.replace(new RegExp(this.keyword, "gi"), (matchedValue) => `<mark class="highlighted">${matchedValue}</mark>`);
} else {
return name;
@ -262,43 +217,6 @@ export class FosComponent implements OnInit, OnDestroy {
public buildFosQueryParam(fos) {
// return {'foslabel': this.urlEncodeAndQuote(fos.id+"||"+fos.label)};
return (this.searchFieldsHelper.getFosParameter() == 'foslabel' ? ({'foslabel': this.urlEncodeAndQuote(fos.id+"||"+fos.label)}) : ({'fos': this.urlEncodeAndQuote(fos.id)}));
}
public backClicked() {
let id = this.selectedParentLevels[0].id;
this.selectedParentLevels=[];
this.cdr.detectChanges();
if(this.scrollPos) {
HelperFunctions.scrollTo(0, this.scrollPos);
this._router.navigate(['./'], {fragment: id, relativeTo: this.route, state: {disableScroll: true}});
} else {
this._router.navigate(['./'], {
fragment: id,
relativeTo: this.route,
state: {disableScroll: false, behavior: 'auto'}
});
}
this.cdr.detectChanges();
if (typeof IntersectionObserver !== 'undefined') {
setTimeout(() => {
this.setObserver();
}, 200);
}
}
public moreClicked(level1, level2, level3) {
this.scrollPos = window.scrollY;
if(this.observer) {
this.observer.disconnect();
}
this.selectedParentLevels=[level1, level2, level3];
this.cdr.detectChanges();
this._router.navigate(['./'],
{fragment: this.selectedParentLevels[0].id+"||"+this.selectedParentLevels[1].code+"||"+this.selectedParentLevels[2].code,
relativeTo: this.route, state: {disableScroll: false, behavior: 'auto'}});
return (properties.environment !== 'production' ? ({'foslabel': this.urlEncodeAndQuote(fos.id+"||"+fos.label)}) : ({'fos': this.urlEncodeAndQuote(fos.id)}));
}
}

View File

@ -2,11 +2,13 @@ import {CommonModule} from "@angular/common";
import {NgModule} from "@angular/core";
import {FormsModule} from "@angular/forms";
import {RouterModule} from "@angular/router";
import {PreviousRouteRecorder} from "../utils/piwik/previousRouteRecorder.guard";
import {IconsModule} from "../utils/icons/icons.module";
import {BreadcrumbsModule} from "../utils/breadcrumbs/breadcrumbs.module";
import {Schema2jsonldModule} from "../sharedComponents/schema2jsonld/schema2jsonld.module";
import {SearchInputModule} from "../sharedComponents/search-input/search-input.module";
import {SEOServiceModule} from "../sharedComponents/SEO/SEOService.module";
import {PiwikService} from "../utils/piwik/piwik.service";
import {FosRoutingModule} from './fos-routing.module';
import {FosComponent} from './fos.component';
@ -20,7 +22,9 @@ import {FosComponent} from './fos.component';
declarations: [
FosComponent
],
providers: [],
providers: [
PreviousRouteRecorder, PiwikService
],
exports: [
FosComponent
]

View File

@ -0,0 +1,225 @@
import {
Component,
ElementRef,
EventEmitter,
HostListener,
Input,
OnDestroy,
OnInit,
Output,
ViewChild
} from "@angular/core";
import {Annotation, AnnotationService} from "./annotation.service";
import {ResultLandingInfo} from "../../utils/entities/resultLandingInfo";
import {EnvProperties} from "../../utils/properties/env-properties";
import {properties} from "../../../../environments/environment";
import {UserManagementService} from "../../services/user-management.service";
import {COOKIE, Session, User} from "../../login/utils/helper.class";
import {Subscriber} from "rxjs";
@Component({
selector: 'b2note',
template: `
<div *ngIf="annotations && annotations.length > 0" class="sideInfoTitle uk-margin-small-bottom">Annotations</div>
<div class="b2note">
<form #form ngNoForm *ngIf="pid && isLoggedIn"
[action]="properties.b2noteAPIURL + 'widget'"
method="post"
target="b2note_iframe"
class="uk-padding-small uk-padding-remove-vertical">
<!--URL of the annotated record-->
<input
type="hidden"
name="recordurl_tofeed"
[value]="url">
<!--PID of the annotated record-->
<input
type="hidden"
name="pid_tofeed"
[value]="pid">
</form>
<loading *ngIf="loading" class="uk-margin-medium-top"></loading>
<ul *ngIf="annotations && !loading" class="uk-list uk-list-divider">
<li *ngFor="let annotation of annotations.slice(0, visibleAnnotations); let i=index" uk-grid
class="uk-flex uk-flex-top uk-margin-remove-left">
<div [ngClass]="annotation.type" class="type">{{annotation.type}}</div>
<div [class.uk-width-1-3]="annotation.targets"
[class.uk-width-1-6@s]="annotation.targets">{{annotation.text}}</div>
<ul class="uk-width-expand uk-list uk-margin-remove-top" *ngIf="annotation.targets">
<li *ngFor="let target of annotation.targets.slice(0, annotation.targetSize)">
<a *ngIf="target.url" [href]="target.url" target="_blank">{{target.id}}</a>
<a *ngIf="!target.url" routerLink="/search/result"
[queryParams]="searchPid(target.id)">{{target.id}}</a>
</li>
<li *ngIf="annotation.targetSize < annotation.targets.length"><a
(click)="open(i)">+ {{annotation.targets.length - annotation.targetSize}}
more</a></li>
</ul>
</li>
</ul>
<div *ngIf="visibleAnnotations < annotations.length" class="uk-margin-medium-top uk-text-center">
<button class="uk-button uk-button-primary"
(click)="visibleAnnotations = (visibleAnnotations + annotationSize)">Load More
</button>
</div>
</div>
<div [class.uk-hidden]="!visible">
<div class="widget-container" cdkDrag>
<button type="button" class="close" aria-label="Close" (click)="toggleAnnotation($event)">
<span aria-hidden="true">×</span>
</button>
<iframe #iframe id="b2note_iframe" name="b2note_iframe" class="b2note-iframe">
</iframe>
</div>
</div>`,
styleUrls: ['annotation.css']
})
export class AnnotationComponent implements OnInit, OnDestroy {
@Input()
public landingInfo: ResultLandingInfo = null;
@Input()
public id: string = null;
public properties: EnvProperties = properties;
public url: string = null;
public pid: string = null;
public keywords: string[] = [];
public visible: boolean = false;
public annotations: Annotation[] = [];
public annotationSize: number = 10;
public isLoggedIn: boolean = Session.isLoggedIn();
public visibleAnnotations: number;
public loading: boolean = false;
public submitted: boolean = false;
@Output()
public pidEmitter: EventEmitter<string> = new EventEmitter<string>();
@ViewChild('iframe') iframe: ElementRef;
@ViewChild('form') form: ElementRef;
private subscriptions: any[] = [];
constructor(private annotationService: AnnotationService) {
}
@HostListener('window:message', ['$event'])
public onChange(event) {
if (this.properties.b2noteAPIURL.includes(event.origin)) {
if (event.data === "B2NOTE loaded") {
let token = COOKIE.getCookie('AccessToken');
this.iframe.nativeElement.contentWindow.postMessage({token: token}, this.properties.b2noteAPIURL);
} else {
this.getAnnotations();
}
}
}
ngOnInit(): void {
this.visibleAnnotations = this.annotationSize;
if (typeof window !== "undefined") {
let id = this.id;
this.url = window.location.href;
if (this.landingInfo.deletedByInferenceIds) {
id = this.landingInfo.deletedByInferenceIds[0];
this.url = this.url.replace(this.id, id);
}
if (this.landingInfo.identifiers && this.landingInfo.identifiers.size > 0) {
if (this.landingInfo.identifiers.get('doi')) {
this.pid = this.landingInfo.identifiers.get('doi')[0];
} else {
const key: string = this.landingInfo.identifiers.keys().next().value;
if (key) {
this.pid = this.landingInfo.identifiers.get(key)[0];
}
}
}
if (this.pid) {
this.getAnnotations();
}
this.pidEmitter.emit(this.pid);
}
}
public get enabled(): boolean {
return this.pid && this.isLoggedIn;
}
private clearSubscriptions() {
this.subscriptions.forEach(subscription => {
if (subscription instanceof Subscriber) {
subscription.unsubscribe();
}
});
this.subscriptions = [];
}
private getAnnotations() {
if (!this.annotations || this.annotations.length === 0) {
this.loading = true;
}
this.subscriptions.push(this.annotationService.getAllAnnotations(this.pid).subscribe(annotations => {
this.annotations.forEach((annotation, index) => {
if (!annotations.find(element => element.type === annotation.type && element.text === annotation.text)) {
this.annotations.splice(index, 1);
}
});
annotations.forEach(annotation => {
if (!this.annotations.find(element => element.type === annotation.type && element.text === annotation.text)) {
annotation.targetSize = 3;
this.annotationService.getAnnotationTargets(annotation.text, annotation.type).subscribe(targets => {
annotation.targets = targets.filter(target => target.id !== this.pid);
});
this.annotations.push(annotation);
}
});
this.annotations = this.sort(this.annotations);
this.loading = false;
}, error => {
this.loading = false;
}));
}
public sort(annotations: Annotation[]): Annotation[] {
return annotations.sort((a, b) => {
if (a.type === b.type) {
return 1;
} else if (a.type === 'semantic') {
return -1;
} else if (b.type === 'semantic') {
return 1;
} else if (a.type === 'keyword') {
return -1;
} else if (b.type === 'keyword') {
return 1;
}
});
}
public searchPid(pid: string): { [k: string]: any; } {
return {
pid: pid
}
}
ngOnDestroy() {
this.clearSubscriptions();
}
toggleAnnotation(event) {
if (this.visible) {
event.preventDefault();
} else if(!this.submitted) {
this.form.nativeElement.submit();
this.submitted = true;
}
this.visible = !this.visible;
}
open(i: number) {
this.annotations.forEach((annotation, index) => {
if (index != i) {
annotation.targetSize = 3;
} else {
annotation.targetSize = annotation.targets.length
}
});
}
}

View File

@ -0,0 +1,41 @@
.widget-container {
position: fixed;
left: 50%;
top: 50%;
z-index: 1000;
padding: 19px;
margin-left: -167px;
margin-top: -311px;
box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2),
0 2px 2px 0 rgba(0, 0, 0, 0.14),
0 1px 5px 0 rgba(0, 0, 0, 0.12);
border: 1px solid #e3e3e3;
border-radius: 4px;
outline: 0;
min-height: 20px;
background-color: #f5f5f5;
cursor: move;
}
.widget-container:hover, .widget-container:active{
box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2),
0 8px 10px 1px rgba(0, 0, 0, 0.14),
0 3px 14px 2px rgba(0, 0, 0, 0.12);
}
.close {
float: right;
padding: 0;
cursor: pointer;
background: transparent;
border: 0;
font-size: 21px;
font-weight: bold;
opacity: 0.2;
}
.b2note-iframe {
width: 100%;
height: 600px;
border: 1px solid #dddddd;
}

View File

@ -0,0 +1,13 @@
import {NgModule} from "@angular/core";
import {AnnotationComponent} from "./annotation.component";
import {CommonModule} from "@angular/common";
import {DragDropModule} from "@angular/cdk/drag-drop";
import {RouterModule} from "@angular/router";
import {LoadingModule} from "../../utils/loading/loading.module";
@NgModule({
imports: [CommonModule, DragDropModule, RouterModule, LoadingModule],
declarations: [AnnotationComponent],
exports: [AnnotationComponent]
})
export class AnnotationModule {}

View File

@ -0,0 +1,95 @@
import {Injectable} from "@angular/core";
import {HttpClient} from "@angular/common/http";
import {Observable} from "rxjs";
import {EnvProperties} from "../../utils/properties/env-properties";
import {map} from "rxjs/operators";
import {properties} from "../../../../environments/environment";
export interface AnnotationTarget {
id: string;
url: string;
}
export interface Annotation {
text: string;
type: 'semantic' | 'keyword' | 'comment';
targets?: AnnotationTarget[];
targetSize?: number;
}
@Injectable({
providedIn: "root"
})
export class AnnotationService {
api = 'api/';
constructor(private http: HttpClient) {
}
getAllAnnotations(source: string): Observable<Annotation[]> {
let url = properties.b2noteAPIURL + this.api + 'annotations?target-id[]=' + encodeURIComponent(source);
return this.http.get<Annotation[]>(url).pipe(map((response: any[]) => {
return this.parseAnnotations(response);
}));
}
getAnnotationTargets(value: string, type: 'semantic' | 'keyword' | 'comment'): Observable<AnnotationTarget[]> {
let url = properties.b2noteAPIURL + this.api + 'annotations?value=' + encodeURIComponent(value) + '&type[]=' + type;
return this.http.get<AnnotationTarget[]>(url).pipe(map((response: any[]) => {
return this.parseAnnotationTargets(response);
}));
}
private parseAnnotations(response: any[]): Annotation[] {
let annotations: Annotation[] = [];
if (response && response.length > 0) {
response.forEach(value => {
if (value.visibility === 'public') {
let body = value.body;
if (body.type === 'TextualBody') {
if (body.purpose === 'tagging') {
annotations.push({
text: body.value,
type: "keyword"
});
} else {
annotations.push({
text: body.value,
type: "comment"
});
}
} else {
let items = body.items;
let text: string = null;
items.forEach(item => {
if (item.type === 'TextualBody') {
text = item.value;
}
});
annotations.push({
text: text,
type: "semantic"
});
}
}
});
}
return annotations;
}
private parseAnnotationTargets(response: any[]): AnnotationTarget[] {
let targets: AnnotationTarget[] = [];
if (response && response.length > 0) {
response.forEach(value => {
if (value.visibility === 'public') {
targets.push({
id: value.target.id,
url: value.target.source
});
}
});
}
return targets;
}
}

View File

@ -1,12 +0,0 @@
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { PreviousRouteRecorder } from "../../utils/piwik/previousRouteRecorder.guard";
import { DataProviderComponent } from "./dataProvider.component";
@NgModule({
imports: [
RouterModule.forChild([{ path: '', component: DataProviderComponent, canDeactivate: [PreviousRouteRecorder] }])
]
})
export class DataProviderRoutingModule { }

View File

@ -1,10 +1,3 @@
<!-- schema.org-->
<schema2jsonld *ngIf="dataProviderInfo"
[data]=dataProviderInfo [URL]="canonicalUrl" type="datasource"
[otherURL]="(dataProviderInfo.provenance)?provenanceUrls:null"></schema2jsonld>
<div *ngIf="dataProviderInfo && !dataProviderInfo.belongsTo && !isBottomIntersecting" [innerHTML]="dataProviderInfo.message"
class="uk-alert uk-alert-warning uk-position-fixed uk-position-bottom-center uk-text-small" style="z-index: 1000;">
</div>
<!-- Desktop view -->
<div class="uk-visible@m landing uk-section uk-padding-remove tm-middle">
<div *ngIf="!isMobile" class="tm-main">
@ -102,7 +95,11 @@
<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-->
<schema2jsonld [data]=dataProviderInfo
[URL]="canonicalUrl"
type="datasource"
[otherURL]="(dataProviderInfo.provenance)?provenanceUrls:null"></schema2jsonld>
<!-- Actions for mobile viewport -->
<div class="uk-flex uk-flex-right uk-margin-medium-bottom uk-hidden@s">
<div>
@ -191,7 +188,7 @@
</div>
<div *ngIf="dataProviderInfo && hasMetrics" class="uk-width-1-1 uk-width-medium@s">
<div class="landing-metrics-card uk-text-small uk-flex uk-padding-small">
<div class="uk-width-expand uk-flex uk-flex-top">
<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>

View File

@ -148,13 +148,14 @@ export class DataProviderComponent {
@ViewChild("descriptionDiv") descriptionDiv: ElementRef;
@ViewChild('descriptionModal') descriptionModal;
// public shouldSticky: boolean = true;
subscriptions = [];
private sub: Subscription;
properties: EnvProperties = properties;
public openaireEntities = OpenaireEntities;
public isMobile: boolean = false;
public isBottomIntersecting: boolean = false;
public mobileContent: "info" | "metrics" | "actions" = "info";
public tabMobile: string = "";
public viewAllMobile: string = "";
@ -197,11 +198,6 @@ export class DataProviderComponent {
ngOnInit() {
this.subscriptions.push(this.layoutService.isMobile.subscribe(isMobile => {
this.isMobile = isMobile;
this.cdr.detectChanges();
}));
this.subscriptions.push(this.layoutService.isBottomIntersecting.subscribe(isBottomIntersecting => {
this.isBottomIntersecting = isBottomIntersecting;
this.cdr.detectChanges();
}));
if (typeof document !== 'undefined') {
this.subscriptions.push(this.indexInfoService.getLastIndexDate(this.properties).subscribe(lastIndexUpdate => {
@ -210,10 +206,8 @@ export class DataProviderComponent {
}
}));
}
if(properties.adminToolsPortalType !== "explore") {
//this.getDivContents();
this.getPageContents();
}
//this.getDivContents();
this.getPageContents();
this.updateUrl(this.properties.domain + this.properties.baseLink + this._router.url);
this.seoService.createLinkForCanonicalURL(this.properties.domain +this.properties.baseLink + this._router.url);
this.subscriptions.push(this.route.queryParams.subscribe(data => {
@ -265,6 +259,16 @@ export class DataProviderComponent {
} else {
this.offset = 0;
}
// let bottom = document.getElementById('bottom');
// if(bottom) {
// let observer = new IntersectionObserver(entries => {
// entries.forEach(entry => {
// this.shouldSticky = !entry.isIntersecting;
// })
// });
// this.subscriptions.push(observer);
// observer.observe(bottom);
// }
if(this.graph_and_feedback) {
this.observeGraphAndFeedback();
}
@ -383,7 +387,6 @@ export class DataProviderComponent {
this.dataProviderInfo = data;
this.getProvenanceUrls();
this.datasourceId = this.dataProviderInfo.objIdentifier;
this.dataProviderInfo.setBelongsTo(this.datasourceId);
let pid:Identifier = Identifier.getPIDFromIdentifiers(this.dataProviderInfo.identifiers);
this.canonicalUrl = this.properties.domain+ properties.baseLink + ( pid ? (this.linkToLandingPage.split("?")[0] + "?pid=" + encodeURIComponent(pid.id)):
(this.linkToLandingPage + this.dataProviderInfo.relcanId));

View File

@ -36,12 +36,10 @@ import {ResultLandingUtilsModule} from "../landing-utils/resultLandingUtils.modu
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";
import {DataProviderRoutingModule} from "./dataProvider-routing.module";
@NgModule({
imports:
[CommonModule, FormsModule, RouterModule,
DataProviderRoutingModule,
IFrameModule, ErrorMessagesModule, LandingModule,
DataProvidersServiceModule, ProjectsServiceModule, SearchResearchResultsServiceModule,
PagingModule, Schema2jsonldModule, SEOServiceModule, ShowPublisherModule, HelperModule,

View File

@ -17,8 +17,8 @@ import {OpenaireEntities} from "../../utils/properties/searchFields";
</errorMessages>
<div *ngIf="fetchResults.searchUtils.status == errorCodes.DONE && !loading" class="uk-text-small">
<div *ngIf="results.length > 90" class="uk-text-meta uk-margin-medium-bottom">
*Only top 100 {{openaireEntities.DATASOURCES}} that host {{openaireEntities.RESULTS}} which are also available via {{collectedFromName}} are shown.
<div class="uk-text-meta uk-margin-medium-bottom">
*Only top 100 {{openaireEntities.DATASOURCES}} that host {{openaireEntities.RESULTS}} which are also available via the Federated Research Data Repository are shown.
</div>
<results-and-pages *ngIf="results.length >pageSize" [type]="openaireEntities.DATASOURCES"
[page]="page" [pageSize]="pageSize"

View File

@ -9,8 +9,7 @@
<landing-header *ngIf="resultLandingInfo" [properties]="properties" [title]="title"
[subTitle]="resultLandingInfo.subtitle" [underCuration]="resultLandingInfo.underCurationMessage"
[entityType]="entityType" [types]="resultLandingInfo.types"
[year]="resultLandingInfo.date" [embargoEndDate]="resultLandingInfo.embargoEndDate"
[publiclyFunded]="resultLandingInfo.publiclyFunded" [projects]="resultLandingInfo.fundedByProjects">
[year]="resultLandingInfo.date" [embargoEndDate]="resultLandingInfo.embargoEndDate">
</landing-header>
<landing-header *ngIf="organizationInfo" [properties]="properties" [title]="title"
[subTitle]="(organizationInfo.name && organizationInfo.title.name !== organizationInfo.name)?organizationInfo.name:null"

View File

@ -0,0 +1,302 @@
import {Component, Input} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import {Meta, Title} from '@angular/platform-browser';
import {EnvProperties} from '../../utils/properties/env-properties';
import {HtmlProjectReportService} from './htmlProjectReport.service';
import {ProjectService} from '../project/project.service';
import {PiwikService} from '../../utils/piwik/piwik.service';
import {SEOService} from '../../sharedComponents/SEO/SEO.service';
import {HelperService} from "../../utils/helper/helper.service";
import {Subscriber} from "rxjs";
import {properties} from "../../../../environments/environment";
declare var UIkit: any;
@Component({
selector: 'htmlProjectReport',
template: `
<div id="tm-main" class=" uk-section uk-padding-remove-top tm-middle">
<div uk-grid>
<div class="tm-main uk-width-1-1@s uk-width-1-1@m uk-width-1-1@l uk-row-first ">
<helper *ngIf="pageContents && pageContents['top'] && pageContents['top'].length > 0"
[texts]="pageContents['top']" styleName="uk-width-1-1"></helper>
<div class="uk-container uk-margin-top uk-width-1-1">
<div *ngIf="warningMessage" class="uk-alert uk-alert-warning" role="alert">{{warningMessage}}</div>
<div [style.display]="showLoading ? 'inline' : 'none'"
class="uk-animation-fade uk-margin-large-top uk-width-1-1" role="alert"><span
class="loading-gif uk-align-center"></span></div>
<div *ngIf="!showLoading && !warningMessage">
<div *ngIf="header1" class="uk-h4 uk-text-bold ">{{header1}}</div>
<div *ngIf="header1 || htmlResult" class=" ">{{header2}}</div>
<div class="uk-clearfix uk-margin-bottom">
<button *ngIf="htmlResult" class="uk-icon-clipboard uk-button uk-button-primary clipBtn uk-float-right"
(click)="copied()">
Copy to clipboard
</button>
</div>
<!--div class="uk-panel-scrollable custom-html-table-height" *ngIf="htmlResult" id="clipboard" [innerHTML]="htmlResult"></div-->
<div class="uk-overflow-auto custom-html-table-height" *ngIf="htmlResult" id="clipboard"
[innerHTML]="htmlResult"></div>
<div *ngIf="errorMessage" class="uk-alert uk-alert-danger" role="alert">{{errorMessage}}</div>
</div>
</div>
<helper *ngIf="pageContents && pageContents['bottom'] && pageContents['bottom'].length > 0"
[texts]="pageContents['bottom']" styleName="uk-width-1-1"></helper>
</div>
</div>
</div>
`
})
export class HtmlProjectReportComponent {
@Input() communityId = null;
private projectId: string;
private totalResults: number = 10;
private resultsType: string = "publication";
public header1: string = "";
public header2: string = "";
public htmlResult: string = "";
subscriptions = [];
public warningMessage: string = "";
public errorMessage: string = "";
public showLoading: boolean = true;
properties: EnvProperties;
public pageContents = null;
public divContents = null;
constructor(private route: ActivatedRoute,
private htmlService: HtmlProjectReportService,
private _piwikService: PiwikService,
private _projectService: ProjectService,
private _meta: Meta,
private _title: Title,
private _router: Router,
private helper: HelperService,
private seoService: SEOService) {
}
ngOnInit() {
this.properties = properties;
//this.getDivContents();
this.getPageContents();
this.updateUrl(this.properties.domain + this.properties.baseLink + this._router.url);
this.seoService.createLinkForCanonicalURL(this.properties.domain + this.properties.baseLink + this._router.url);
this.subscriptions.push(this.route.queryParams.subscribe(params => {
this.projectId = params['projectId'];
if (params['size'] == parseInt(params['size'], 10)) {
this.totalResults = params['size'];
} else {
this.showLoading = false;
this.warningMessage = "Requested size is not an integer";
}
if (params['type'] && (params['type'] == "publication" || params['type'] == "dataset" || params['type'] == "software" || params['type'] == "other")) {
if (params['type'] == "publication") {
this.resultsType = 'publication';
} else if (params['type'] == "dataset") {
this.resultsType = 'research data';
} else if (params['type'] == "software") {
this.resultsType = 'software';
} else if (params['type'] == "other") {
this.resultsType = "other research product";
}
var title = "Project's " + this.resultsType + " report";
var description = "project, project " + this.resultsType + " report, funding, open access, publications, research data, software, other research products";
this.updateTitle(title);
this.updateDescription(description);
} else {
this.showLoading = false;
this.warningMessage = "Requested type should be publication or research data or software or other research product";
}
//showLoading is true if no warnings
if (this.showLoading) {
if (this.projectId) {
this.createHeaders();
} else {
this.showLoading = false;
this.warningMessage = "No valid project id";
}
}
}));
}
private getPageContents() {
if(this.communityId) {
this.subscriptions.push(this.helper.getPageHelpContents(this.properties, this.communityId, this._router.url).subscribe(contents => {
this.pageContents = contents;
}));
}
}
private getDivContents() {
if(this.communityId) {
this.subscriptions.push(this.helper.getDivHelpContents(this.properties, this.communityId, this._router.url).subscribe(contents => {
this.divContents = contents;
}));
}
}
ngOnDestroy() {
this.subscriptions.forEach(subscription => {
if (subscription instanceof Subscriber) {
subscription.unsubscribe();
}
});
}
private createHeaders() {
this.subscriptions.push(this._projectService.getHTMLInfo(this.projectId, this.properties).subscribe(
data => {
this.createHeader1(data);
if (data.acronym) {
this.updateTitle(data.acronym + " " + this.resultsType + " report");
} else if (data.title) {
this.updateTitle(data.title + " " + this.resultsType + " report");
}
this.subscriptions.push(this._piwikService.trackView(this.properties, ((data.acronym) ? data.acronym : data.title) + " " + this.resultsType + " report").subscribe());
},
err => {
this.handleError("Error getting html information for project id: " + this.projectId, err);
//console.log(err);
this.createClipboard();
}
));
if (this.resultsType == "publication") {
this.header2 += this.totalResults.toLocaleString('en-US') + " publications";
} else if (this.resultsType == "research data") {
this.header2 += this.totalResults.toLocaleString('en-US') + " research data";
} else if (this.resultsType == "software") {
this.header2 += this.totalResults.toLocaleString('en-US') + " software";
} else if (this.resultsType == "other research product") {
this.header2 += this.totalResults.toLocaleString('en-US') + " other";
}
}
private createClipboard() {
let intro: string = '<!doctype html>';
intro += '<html lang="en-gb" dir="ltr" vocab="http://schema.org/">';
intro += '<head>';
intro += '<title>' + this.header1 + '</title>'
intro += '</head>';
if (typeof window !== 'undefined') {
this.subscriptions.push(this.htmlService.getHTML(this.projectId, this.resultsType, this.properties.csvAPIURL).subscribe(
data => {
//let body: string = intro+'<body><h1>'+this.header1+'</h1><h2>'+this.header2+'</h2>'+data+'</body></html>';
let body: string = intro + '<body><h1>' + this.header1 + '</h1><h2>' + this.header2 + '</h2>';
body += "<table><thead><tr> <th>Title</th><th>Authors</th><th>Publication Year</th><th>DOI</th><th>Permanent Identifier</th><th>Publication type</th><th>Journal</th><th>Project Name (GA Number)</th><th>Access Mode</th></tr></thead><tbody>" + data + "</tbody></table>";
body += '</body></html>';
//this.htmlResult = data;
this.htmlResult = "<table><thead><tr> <th>Title</th><th>Authors</th><th>Publication Year</th><th>DOI</th><th>Permanent Identifier</th><th>Publication type</th><th>Journal</th><th>Project Name (GA Number)</th><th>Access Mode</th></tr></thead><tbody>" + data + "</tbody></table>";
let clipboard;
let Clipboard;
Clipboard = require('clipboard');
clipboard = new Clipboard('.clipBtn', {
/*target: function(trigger) {
return document.getElementById("clipboard");
}*/
text: function (trigger) {
return body;//document.getElementById("clipboard").getAttribute('innerHTML');//"aaaa"+tmp+"oo";
}
});
this.showLoading = false;
},
err => {
//console.log(err);
this.handleError("Error getting html for id: " + this.projectId, err);
this.errorMessage = 'Service not available';
this.showLoading = false;
}
));
}
}
createHeader1(data: { "title": string, "acronym": string, "callIdentifier": string }) {
if (this.resultsType == "publication") {
this.header1 += "Publications";
} else if (this.resultsType == "research data") {
this.header1 += "Research Data";
} else if (this.resultsType == "software") {
this.header1 += "Software";
} else if (this.resultsType == "other research product") {
this.header1 += "Other Research Products";
}
if (data != undefined) {
if (data.title != undefined && data.title != "") {
this.header1 += data.title;
}
if ((data.title != undefined && data.title != "") &&
((data.acronym != undefined && data.acronym != "") ||
(data.callIdentifier != undefined && data.callIdentifier != ""))) {
this.header1 += "(";
}
if (data.acronym != undefined && data.acronym != "") {
this.header1 += data.acronym + " - ";
}
if (data.callIdentifier != undefined && data.callIdentifier != "") {
this.header1 += data.callIdentifier;
}
if ((data.title != undefined && data.title != "") &&
((data.acronym != undefined && data.acronym != "") ||
(data.callIdentifier != undefined && data.callIdentifier != ""))) {
this.header1 += ")";
}
}
this.createClipboard();
}
public copied() {
UIkit.notification({
message: '<strong>Raw html is copied. Please paste it on an html file.<strong>',
status: 'success',
timeout: 3000,
pos: 'top-center'
});
}
private updateDescription(description: string) {
this._meta.updateTag({content: description}, "name='description'");
this._meta.updateTag({content: description}, "property='og:description'");
}
private updateTitle(title: string) {
var _prefix = "";
if(!this.communityId) {
_prefix = "OpenAIRE | ";
}
var _title = _prefix + ((title.length > 50) ? title.substring(0, 50) : title);
this._title.setTitle(_title);
this._meta.updateTag({content: _title}, "property='og:title'");
}
private updateUrl(url: string) {
this._meta.updateTag({content: url}, "property='og:url'");
}
private handleError(message: string, error) {
console.error("Html Project Report Page: " + message, error);
}
}

View File

@ -0,0 +1,30 @@
//import {MaterialModule} from '@angular/material';
import { NgModule} from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { ProjectServiceModule} from '../project/projectService.module';
import {HtmlProjectReportService} from './htmlProjectReport.service';
import {HtmlProjectReportComponent} from './htmlProjectReport.component';
import {PiwikServiceModule} from '../../utils/piwik/piwikService.module';
import { SEOServiceModule } from '../../sharedComponents/SEO/SEOService.module';
import {HelperModule} from "../../utils/helper/helper.module";
import {RouterModule} from '@angular/router';
@NgModule({
imports: [
CommonModule, FormsModule, ProjectServiceModule, PiwikServiceModule, SEOServiceModule, HelperModule,
RouterModule
],
declarations: [
HtmlProjectReportComponent
],
providers:[
HtmlProjectReportService
],
exports: [
HtmlProjectReportComponent
]
})
export class HtmlProjectReportModule { }

View File

@ -14,92 +14,78 @@ import {RouterHelper} from "../../utils/routerHelper.class";
<div class="uk-flex uk-flex-middle"
[ngClass]="isMobile ? ('uk-flex-column ' + (!(usedBy == 'landing') ? 'uk-margin-left uk-margin-xsmall-bottom' : '')) : 'uk-grid uk-grid-small uk-child-width-auto'"
[attr.uk-grid]="!isMobile ? '' : null">
<ng-container *ngIf="inModal">
<div class="uk-text-small uk-height-max-small uk-overflow-auto">
<ng-container *ngTemplateOutlet="availableOnList"></ng-container>
</div>
</ng-container>
<ng-container *ngIf="!inModal">
<div *ngIf="availableOn[0].fulltext" class="uk-flex uk-flex-middle"
[ngClass]="isMobile ? 'uk-width-1-1' : 'uk-text-bolder'">
<a [href]="availableOn[0].fulltext" target="_blank"
class="uk-flex uk-flex-middle uk-button-link"
[ngClass]="isMobile ? ((usedBy == 'landing') ? 'uk-width-1-1 uk-padding-small uk-padding-remove-horizontal' : '') : 'uk-flex-center'">
<!-- <icon [flex]="true" [ratio]="0.7" name="download" visuallyHidden="download"></icon>-->
<icon name="download" visuallyHidden="donwload" [flex]="true" [ratio]="(isMobile && usedBy == 'landing') ? 1 : 0.8"></icon>
<span class="uk-margin-xsmall-left">Full-Text</span>
</a>
</div>
<div *ngIf="isMobile && (usedBy == 'landing') && availableOn[0].fulltext" class="uk-width-1-1"><hr></div>
<div *ngIf="availableOn[0].downloadUrl" [ngClass]="isMobile ? 'uk-width-1-1' : ''">
<div class="uk-flex uk-flex-middle" [ngClass]="isMobile ? ((usedBy == 'landing') ? 'uk-padding-small uk-padding-remove-horizontal' : '') : ''">
<span [class]="'uk-margin-xsmall-right ' + (availableOn[0].accessRightIcon == 'open_access' ? 'open-access' : 'closed-access')"
uk-tooltip [title]="getAccessLabel(availableOn[0].accessRight)">
<icon [name]="availableOn[0].accessRightIcon" [flex]="true" [ratio]="(isMobile && usedBy == 'landing') ? 1 : 0.8"></icon>
</span>
<ng-container *ngIf="!isMobile">
<a target="_blank"
class="uk-flex uk-flex-middle uk-flex-center uk-button-link uk-text-bolder">
<span>{{sliceString(availableOn[0].downloadNames.join("; "), 20)}}</span>
<span>
<!-- <icon [flex]="true" [name]="'expand_' + (isOpen?'less':'more')"></icon>-->
<icon [flex]="true" [name]="(isOpen?'arrow_drop_up':'arrow_drop_down')"></icon>
</span>
</a>
<div #dropElement uk-drop="mode: click; pos: bottom-left; flip: false; shift: false" class="uk-drop download-drop">
<div class="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>
<ng-container *ngIf="isMobile">
<a #toggle class="uk-flex uk-flex-between uk-flex-middle uk-flex-center uk-width-expand uk-button-link">
<span>{{sliceString(availableOn[0].downloadNames.join("; "), 20)}}</span>
<span>
<icon [flex]="true" ratio="1.5" name="arrow_right"></icon>
<div *ngIf="properties.environment != 'production' && availableOn[0].fulltext" class="uk-flex uk-flex-middle"
[ngClass]="isMobile ? 'uk-width-1-1' : 'uk-text-bolder'">
<a [href]="availableOn[0].fulltext" target="_blank"
class="uk-flex uk-flex-middle uk-button-link"
[ngClass]="isMobile ? ((usedBy == 'landing') ? 'uk-width-1-1 uk-padding-small uk-padding-remove-horizontal' : '') : 'uk-flex-center'">
<!-- <icon [flex]="true" [ratio]="0.7" name="download" visuallyHidden="download"></icon>-->
<icon name="download" visuallyHidden="donwload" [flex]="true" [ratio]="(isMobile && usedBy == 'landing') ? 1 : 0.8"></icon>
<span class="uk-margin-xsmall-left">Full-Text</span>
</a>
</div>
<div *ngIf="isMobile && (usedBy == 'landing') && availableOn[0].fulltext" class="uk-width-1-1"><hr></div>
<div *ngIf="availableOn[0].downloadUrl" [ngClass]="isMobile ? 'uk-width-1-1' : ''">
<div class="uk-flex uk-flex-middle" [ngClass]="isMobile ? ((usedBy == 'landing') ? 'uk-padding-small uk-padding-remove-horizontal' : '') : ''">
<span [class]="'uk-margin-xsmall-right ' + (availableOn[0].accessRightIcon == 'open_access' ? 'open-access' : 'closed-access')"
uk-tooltip [title]="getAccessLabel(availableOn[0].accessRight)">
<icon [name]="availableOn[0].accessRightIcon" [flex]="true" [ratio]="(isMobile && usedBy == 'landing') ? 1 : 0.8"></icon>
</span>
<ng-container *ngIf="!isMobile">
<a uk-tooltip="Source" target="_blank"
class="uk-flex uk-flex-middle uk-flex-center uk-button-link uk-text-bolder">
<span>{{sliceString(availableOn[0].downloadNames.join("; "), 20)}}</span>
<span>
<!-- <icon [flex]="true" [name]="'expand_' + (isOpen?'less':'more')"></icon>-->
<icon [flex]="true" [name]="(isOpen?'arrow_drop_up':'arrow_drop_down')"></icon>
</span>
</a>
<mobile-dropdown [toggle]="toggle">
<div class="uk-text-emphasis uk-text-bolder uk-text-center uk-padding-small uk-padding-remove-vertical uk-text-uppercase">
Sources
</div>
<div class="uk-text-small download-drop uk-padding uk-padding-remove-horizontal">
</a>
<div #dropElement uk-drop="mode: click; pos: bottom-left; flip: false; shift: false" class="uk-drop download-drop">
<div class="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>
</mobile-dropdown>
</ng-container>
</div>
</div>
</div>
</ng-container>
<ng-container *ngIf="isMobile">
<a #toggle class="uk-flex uk-flex-between uk-flex-middle uk-flex-center uk-width-expand uk-button-link">
<span>{{sliceString(availableOn[0].downloadNames.join("; "), 20)}}</span>
<span>
<icon [flex]="true" ratio="1.5" name="arrow_right"></icon>
</span>
</a>
<mobile-dropdown [toggle]="toggle">
<div class="uk-text-emphasis uk-text-bolder uk-text-center uk-padding-small uk-padding-remove-vertical uk-text-uppercase">
Sources
</div>
<div class="uk-text-small download-drop uk-padding uk-padding-remove-horizontal">
<ng-container *ngTemplateOutlet="availableOnList"></ng-container>
</div>
</mobile-dropdown>
</ng-container>
</div>
</ng-container>
</div>
</div>
</ng-container>
<ng-template #availableOnList>
<div *ngFor="let instance of availableOn let i=index" class="download-drop-item uk-flex uk-flex-top"
[ngClass]="inModal ? 'uk-margin-small-bottom' : ''">
<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" [ratio]="inModal ? 0.8 : 1"></icon>
<icon [name]="instance.accessRightIcon" [flex]="true"></icon>
</span>
<div class="uk-padding-small uk-padding-remove-left uk-padding-remove-vertical"
[ngClass]="inModal ? 'uk-grid' : 'uk-width-expand'">
<div class="uk-width-expand uk-padding-small uk-padding-remove-left uk-padding-remove-vertical">
<span class="uk-text-emphasis">
<a *ngIf="instance.downloadUrl" [href]="instance.downloadUrl" target="_blank"
class="title uk-link-text uk-text-bold custom-external uk-display-inline-block">
{{instance.downloadNames.join("; ")}}
</a>
</span>
<div *ngIf="instance.types?.length > 0 || instance.years?.length > 0 || instance.peerReviewed" class="uk-text-meta">
<div *ngIf="instance.types?.length > 0 || instance.years?.length > 0" class="uk-text-meta">
<span *ngIf="instance.types?.length > 0" class="uk-text-capitalize">{{instance.types.join(" . ")}}</span>
<span *ngIf="instance.types?.length > 0 && instance.years?.length > 0"> . </span>
<span *ngIf="instance.years?.length > 0">{{instance.years.join(" . ")}}</span>
<span *ngIf="(instance.types?.length > 0 || instance.years?.length > 0) && instance.peerReviewed"> . </span>
<span *ngIf="instance.peerReviewed">Peer-reviewed</span>
</div>
<div *ngIf="instance.license" class="uk-text-meta uk-text-truncate" uk-tooltip [title]="instance.license">
License:
@ -109,7 +95,7 @@ import {RouterHelper} from "../../utils/routerHelper.class";
</a>
<ng-template #elseBlock> {{instance.license}}</ng-template>
</div>
<div *ngIf="instance.fulltext" class="uk-text-meta uk-text-truncate" uk-tooltip [title]="instance.fulltext">
<div *ngIf="properties.environment != 'production' && instance.fulltext" class="uk-text-meta uk-text-truncate" uk-tooltip [title]="instance.fulltext">
Full-Text:
<a *ngIf="isUrl(instance.fulltext); else elseBlock"
[href]="instance.fulltext" target="_blank" class="custom-external uk-link-text">
@ -132,7 +118,6 @@ import {RouterHelper} from "../../utils/routerHelper.class";
export class AvailableOnComponent {
@Input() isMobile: boolean = false;
@Input() inModal: boolean = false;
@Input() usedBy: "search" | "landing" = "search";
@Input() prevPath: string = "";
@Input() availableOn: HostedByCollectedFrom[];

View File

@ -31,20 +31,22 @@ import {RouterHelper} from "../../utils/routerHelper.class";
<!-- types -->
<span *ngIf="entityType" class="uk-flex-inline uk-flex-middle uk-flex-wrap"
[class.other-separator]="types && removeUnknown(types, true).length > 0">
<icon *ngIf="entityType.toLowerCase() == 'publication'" name="description" type="outlined"
[flex]="true" [ratio]="0.8" class="uk-margin-xsmall-right"></icon>
<icon *ngIf="entityType.toLowerCase() == 'research data'" name="database" type="outlined"
[flex]="true" [ratio]="0.8" class="uk-margin-xsmall-right"></icon>
<icon *ngIf="entityType.toLowerCase() == 'research software'" name="integration_instructions"
type="outlined" [flex]="true" [ratio]="0.8" class="uk-margin-xsmall-right"></icon>
<icon *ngIf="entityType.toLowerCase() == 'other research product'" name="apps" type="outlined"
[flex]="true" [ratio]="0.8" class="uk-margin-xsmall-right"></icon>
<icon *ngIf="entityType.toLowerCase() == 'project'" name="assignment_turned_in" type="outlined"
[flex]="true" [ratio]="0.8" class="uk-margin-xsmall-right"></icon>
<icon *ngIf="entityType.toLowerCase() == 'data source'" name="note_add" type="outlined"
[flex]="true" [ratio]="0.8" class="uk-margin-xsmall-right"></icon>
<icon *ngIf="entityType.toLowerCase() == 'organization'" name="corporate_fare" type="outlined"
[flex]="true" [ratio]="0.8" class="uk-margin-xsmall-right"></icon>
<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>
@ -89,7 +91,7 @@ import {RouterHelper} from "../../utils/routerHelper.class";
</ng-container>
</span>
<ng-container *ngIf="status">
<span>{{status}} <ng-container *ngIf="currentDate <= endDate && currentDate >= startDate">(M{{calcCurrentMonth}})</ng-container></span>
<span>{{status}}</span>
</ng-container>
<ng-container *ngIf="date">
<span>{{date | date: 'dd MMM yyyy': 'UTC'}}</span>
@ -118,9 +120,8 @@ import {RouterHelper} from "../../utils/routerHelper.class";
<showPublisher *ngIf="publisher || journal" [publisher]="publisher" [journal]="journal"
[properties]="properties"></showPublisher>
<!-- data provider labels -->
<span *ngIf="compatibility && !(compatibility.info == 'not available' && type == 'service')">
<span class="uk-text-meta uk-margin-xsmall-right">Compatibility:</span>
<span>
<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]">
@ -138,11 +139,10 @@ import {RouterHelper} from "../../utils/routerHelper.class";
{{compatibility.name}}
</span>
</span>
</span>
<span *ngIf="compatibilityString">
<span class="uk-text-meta uk-margin-xsmall-right">Compatibility:</span>
<span>{{compatibilityString}}</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>
@ -150,16 +150,13 @@ import {RouterHelper} from "../../utils/routerHelper.class";
<ng-container *ngIf="thematic">
<span>Thematic</span>
</ng-container>
<ng-container *ngIf="publiclyFunded">
<span>Publicly funded</span>
</ng-container>
<!-- Projects -->
<span *ngIf="projects && projects.length > 0">
<span class="uk-text-meta uk-margin-xsmall-right">Funded by:</span>
<span>{{showInline ? projectNames.join(', ') : projectNames.slice(0, projectsLimit).join(', ')}}</span>
<span *ngIf="projects && projects.length > 0"
[attr.uk-tooltip]="projects.length > projectsLimit ? 'cls: uk-invisible' : 'pos: top; cls: uk-active'" title="Funded by">
{{showInline ? projectNames.join(', ') : projectNames.slice(0, projectsLimit).join(', ')}}
<span *ngIf="projects.length > projectsLimit">
<a *ngIf="!showInline" (click)="viewAllProjectsClick();" class="uk-background-muted custom-extra-entities">
+{{projects.length - projectsLimit | number}}{{projects.length == 1000 ? ' more' : ''}} projects
+{{projects.length - projectsLimit | number}} projects
</a>
<a *ngIf="showInline && lessBtn" (click)="showInline = !showInline; lessBtn = false;"
class="uk-background-muted custom-extra-entities">
@ -168,12 +165,12 @@ import {RouterHelper} from "../../utils/routerHelper.class";
</span>
</span>
<!-- Organizations -->
<span *ngIf="organizations && organizations.length > 0">
<span class="uk-text-meta uk-margin-xsmall-right">Partners:</span>
<span>{{showInline ? organizationNames.join(', ') : organizationNames.slice(0, organizationsLimit).join(', ')}}</span>
<span *ngIf="organizations && organizations.length > 0"
[attr.uk-tooltip]="organizations.length > organizationsLimit ? 'cls: uk-invisible' : 'pos: top; cls: uk-active'" title="Partners">
{{showInline ? organizationNames.join(', ') : organizationNames.slice(0, organizationsLimit).join(', ')}}
<span *ngIf="organizations.length > organizationsLimit">
<a *ngIf="!showInline" (click)="viewAllPartnersClick();" class="uk-background-muted custom-extra-entities">
+{{organizations.length - organizationsLimit | number}}{{organizations.length == 1000 ? ' more' : ''}} partners
+{{organizations.length - organizationsLimit | number}} partners
</a>
<a *ngIf="showInline && lessBtn" (click)="showInline = !showInline; lessBtn = false;"
class="uk-background-muted custom-extra-entities">
@ -182,10 +179,9 @@ import {RouterHelper} from "../../utils/routerHelper.class";
</span>
</span>
<!-- Subjects -->
<span *ngIf="subjects && subjects.length > 0" [class.truncated]="subjects.length > 3">
<span uk-tooltip="Subjects" *ngIf="subjects && subjects.length > 0" [class.truncated]="subjects.length > 3">
{{subjects.slice(0, 3).join(', ')}}
</span>
<!-- For tabs in landing -->
<ng-container *ngIf="provenanceAction">
<span>{{provenanceAction}}</span>
</ng-container>
@ -197,7 +193,6 @@ import {RouterHelper} from "../../utils/routerHelper.class";
<modal-alert *ngIf="!isMobile" #partnersModal>
<div *ngIf="organizations?.length == 1000" class="uk-text-meta uk-margin-medium-bottom">Only 1000 Partners<span *ngIf="resultTitle"> of {{resultTitle}}</span> are shown here.</div>
<div class="uk-text-small uk-text-emphasis uk-grid uk-grid-column-collapse uk-grid-row-small" uk-grid>
<ng-container *ngFor="let item of organizations; let i = index">
<div class="uk-margin-xsmall-right">
@ -208,7 +203,6 @@ import {RouterHelper} from "../../utils/routerHelper.class";
</modal-alert>
<modal-alert *ngIf="!isMobile" #projectsModal>
<div *ngIf="projects?.length == 1000" class="uk-text-meta uk-margin-medium-bottom">Only 1000 {{openaireEntities.PROJECTS}}<span *ngIf="resultTitle"> of {{resultTitle}}</span> are shown here.</div>
<div class="uk-text-small uk-text-emphasis uk-grid uk-grid-column-collapse uk-grid-row-small" uk-grid>
<ng-container *ngFor="let item of projects; let i = index">
<div class="uk-margin-xsmall-right">
@ -225,7 +219,6 @@ import {RouterHelper} from "../../utils/routerHelper.class";
styleUrls: ['entity-metadata.component.less']
})
export class EntityMetadataComponent {
@Input() resultTitle: string = null;
@Input() isMobile: boolean = false;
@Input() entityType: string;
@Input() types: string[];
@ -253,7 +246,6 @@ export class EntityMetadataComponent {
@Input() type; // data provider landing
@Input() provenanceAction: string; // search result
@Input() relationName: string; // search result
@Input() publiclyFunded: boolean; // search result
@Input() projects: Project[];
@Input() organizations: Organization[];
@Input() subjects: string[];
@ -298,7 +290,7 @@ export class EntityMetadataComponent {
return this.projects.map(project => {
let value = project.funderShortname ? project.funderShortname : project.funderName;
if (project.acronym || project.title) {
value = (value ? value + ' | ' : '') + (project.acronym ? project.acronym :
value = value + ' | ' + (project.acronym ? project.acronym :
(project.title.length > 25 ? (project.title.slice(0, 25) + '...'): project.title));
}
// if(project.code) {
@ -367,18 +359,4 @@ export class EntityMetadataComponent {
this.projectsModal.open();
}
}
public get calcCurrentMonth() {
let currentDate = new Date(this.currentDate);
let startDate = new Date(this.startDate);
var months;
months = (currentDate.getFullYear() - startDate.getFullYear()) * 12;
months -= startDate.getMonth();
months += currentDate.getMonth();
if(startDate.getDate() > currentDate.getDate()) {
months--;
}
return months <= 0 ? 0 : months+1;
}
}

View File

@ -1,16 +0,0 @@
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {EntityMetadataComponent} from './entity-metadata.component';
import {IconsModule} from '../../utils/icons/icons.module';
import {AlertModalModule} from '../../utils/modal/alertModal.module';
import {ShowPublisherModule} from "./showPublisher.module";
@NgModule({
imports: [
CommonModule, IconsModule, AlertModalModule, ShowPublisherModule
],
declarations: [EntityMetadataComponent],
providers:[],
exports: [EntityMetadataComponent]
})
export class EntityMetadataModule { }

View File

@ -2,13 +2,12 @@ import {Component, EventEmitter, Input, Output} from "@angular/core";
import {RouterHelper} from "../../utils/routerHelper.class";
import {properties} from "../../../../environments/environment";
import {StringUtils} from "../../utils/string-utils.class";
import {SearchFields} from "../../utils/properties/searchFields";
@Component({
selector: 'fos',
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'">
<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>
@ -46,7 +45,7 @@ import {SearchFields} from "../../utils/properties/searchFields";
<div class="uk-hidden@m">
<div *ngIf="!viewAll" 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>-->
<div class="uk-text-xsmall" style="color: #EEB204">Beta</div>
{{title}}
</div>
<div class="uk-width-expand">
@ -97,7 +96,6 @@ export class FosComponent {
public routerHelper: RouterHelper = new RouterHelper();
public properties = properties;
public title: string = "Fields of Science";
private searchFieldsHelper: SearchFields = new SearchFields();
public viewAllClick() {
// if(this.subjects.length <= this.threshold*2) {
@ -124,11 +122,11 @@ export class FosComponent {
public buildFosQueryParam(fos) {
// return {'foslabel': this.urlEncodeAndQuote(fos.id+"||"+fos.label)};
return (this.searchFieldsHelper.getFosParameter() == 'foslabel' ? ({'foslabel': this.urlEncodeAndQuote(fos.id+"||"+fos.label)}) : ({'fos': this.urlEncodeAndQuote(fos.id)}));
return (properties.environment !== 'production' ? ({'foslabel': this.urlEncodeAndQuote(fos.id+"||"+fos.label)}) : ({'fos': this.urlEncodeAndQuote(fos.id)}));
}
public buildFosHrefParam(fos): string {
// return ('foslabel='+this.urlEncodeAndQuote(fos.id+"||"+fos.label));
return (this.searchFieldsHelper.getFosParameter() == 'foslabel' ? ('foslabel='+this.urlEncodeAndQuote(fos.id+"||"+fos.label)) : ('fos='+this.urlEncodeAndQuote(fos.id)));
return (properties.environment !== 'production' ? ('foslabel='+this.urlEncodeAndQuote(fos.id+"||"+fos.label)) : ('fos='+this.urlEncodeAndQuote(fos.id)));
}
}

View File

@ -20,16 +20,14 @@ import {RouterHelper} from "../../utils/routerHelper.class";
</div>
<div *ngIf="!isMobile">
<span *ngFor="let item of fundedByProjects.slice(0, viewAll?fundedByProjects.length:threshold) let i=index">
<span class="uk-text-emphasis" (click)="dropClicked=true">
<span class="uk-text-emphasis">
<a class="uk-link uk-link-text">
<ng-container *ngTemplateOutlet="funder; context: {item: item}"></ng-container>
</a>
</span>
<div class="default-dropdown uk-margin-remove-top uk-dropdown"
uk-dropdown="pos: bottom-left; mode:click">
<ng-container *ngIf="dropClicked">
<ng-container *ngTemplateOutlet="dropInfo; context: { item: item, index: i}"></ng-container>
</ng-container>
<ng-container *ngTemplateOutlet="dropInfo; context: { item: item}"></ng-container>
</div>
<span *ngIf="i < (fundedByProjects.slice(0, viewAll?fundedByProjects.length:threshold).length - 1)">, </span>
</span>
@ -37,13 +35,13 @@ import {RouterHelper} from "../../utils/routerHelper.class";
<div *ngIf="isMobile">
<div *ngFor="let item of fundedByProjects.slice(0, viewAll?fundedByProjects.length:threshold) let i=index"
class="uk-flex uk-flex-middle uk-margin-small-bottom">
<span class="uk-text-emphasis uk-width-expand" (click)="dropClicked=true">
<span class="uk-text-emphasis uk-width-expand">
<ng-container *ngTemplateOutlet="funder; context: {item: item}"></ng-container>
</span>
<a #toggle><icon name="info" visuallyHidden="info" [type]="'outlined'"></icon></a>
<mobile-dropdown [toggle]="toggle">
<div *ngIf="dropClicked" class="uk-margin-remove-top">
<ng-container *ngTemplateOutlet="dropInfo; context: { item: item, index: i}"></ng-container>
<div class="uk-margin-remove-top">
<ng-container *ngTemplateOutlet="dropInfo; context: { item: item}"></ng-container>
</div>
</mobile-dropdown>
</div>
@ -56,7 +54,7 @@ import {RouterHelper} from "../../utils/routerHelper.class";
<span *ngIf="item['acronym'] || item['title']">| {{ item['acronym'] ? item['acronym'] : item['title']}}</span>
</ng-template>
<ng-template #dropInfo let-item=item let-index=index>
<ng-template #dropInfo let-item=item>
<div class="uk-padding-small">
<span>Project</span>
<div class="uk-margin-bottom">
@ -86,7 +84,7 @@ import {RouterHelper} from "../../utils/routerHelper.class";
<span class="uk-text-meta">Funding stream: </span>{{item.funding}}
</li>
</ul>
<div *ngIf="item.provenanceAction || item.validated" class="uk-text-meta">
<div *ngIf="getVocabularyLabel(item, provenanceActionVocabulary, i) || item.validated" class="uk-text-meta">
<span *ngIf="item.validated">Validated by funder</span>
<span *ngIf="item.provenanceAction && item.validated"> | </span>
<span *ngIf="item.provenanceAction">{{item.provenanceAction}}</span>
@ -107,15 +105,8 @@ export class FundedByComponent {
public url = properties.searchLinkToProject.split('?')[0];
public title: string = "Funded by";
@Input() provenanceActionVocabulary = null;
// public provenancesCalculated: boolean[] = [];
public provenancesCalculated: boolean[] = [];
public routerHelper:RouterHelper = new RouterHelper();
public dropClicked: boolean = false;
public ngOnInit() {
this.fundedByProjects.forEach((project, index) => {
this.getVocabularyLabel(project, this.provenanceActionVocabulary, index);
})
}
public viewAllClick() {
if(this.fundedByProjects.length <= this.threshold*2) {
@ -133,11 +124,11 @@ export class FundedByComponent {
}
public getVocabularyLabel(item: any, vocabulary: any, index: number) {
// if(!this.provenancesCalculated[index]) {
// this.provenancesCalculated[index] = true;
if(!this.provenancesCalculated[index]) {
this.provenancesCalculated[index] = true;
item.provenanceAction = HelperFunctions.getVocabularyLabel(item.provenanceAction, vocabulary, false);
// }
// return item.provenanceAction;
}
return item.provenanceAction;
}
public addEoscPrevInParams(obj) {

View File

@ -21,7 +21,7 @@ import {AlertModal} from "../../../utils/modal/alert";
[languages]="languages" [programmingLanguages]="programmingLanguages"
[compatibility]="compatibility" [aggregationStatus]="aggregationStatus"
[thematic]="thematic" [type]="type" [prevPath]="prevPath"
[countries]="countries" [publiclyFunded]="publiclyFunded" [projects]="projects"
[countries]="countries" [projects]="projects"
></entity-metadata>
</div>
<div *ngIf="authors">
@ -63,6 +63,5 @@ export class LandingHeaderComponent {
@Input() type; // data provider landing
@Input() prevPath: string = "";
@Input() countries;
@Input() publiclyFunded;
@Input() projects;
}

View File

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

View File

@ -5,19 +5,24 @@ import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import {TabPagingComponent} from './tabPaging.component';
import {ShowTitleComponent} from './showTitle.component';
import {AddThisComponent} from './addThis.component';
import {PiwikServiceModule} from '../../utils/piwik/piwikService.module';
import {PreviousRouteRecorder} from'../../utils/piwik/previousRouteRecorder.guard';
@NgModule({
imports: [
CommonModule, FormsModule, RouterModule
CommonModule, FormsModule, RouterModule, PiwikServiceModule
],
declarations: [
ShowTitleComponent, AddThisComponent
TabPagingComponent, ShowTitleComponent, AddThisComponent
],
providers:[],
providers:[
PreviousRouteRecorder
],
exports: [
ShowTitleComponent, AddThisComponent
TabPagingComponent, ShowTitleComponent, AddThisComponent
]
})
export class LandingModule { }

View File

@ -39,10 +39,10 @@ export class ParsingFunctions {
let fundedByProject: Project = {
"id": "", "acronym": "", "title": "",
"funderShortname": "", "funderName": "", "funderJurisdiction": "",
"funderShortname": "", "funderName": "",
"funding": "", "code": "", "provenanceAction": "", "validated": false
};
if (relation.title != 'unidentified') {
fundedByProject['id'] = relation['to'].content;
fundedByProject['acronym'] = relation.acronym;
@ -61,7 +61,8 @@ export class ParsingFunctions {
}
if (relation.hasOwnProperty("funding")) {
let funding = this.parseFundingTrees(relation.funding);
let funding: { "funderName": string, "funderShortname": string, "stream": string };
funding = this.parseFundingTrees(relation.funding);
if (funding.funderName) {
fundedByProject['funderName'] = funding.funderName;
@ -69,9 +70,6 @@ export class ParsingFunctions {
if (funding.funderShortname) {
fundedByProject['funderShortname'] = funding.funderShortname;
}
if(funding.funderJurisdiction) {
fundedByProject['funderJurisdiction'] = funding.funderJurisdiction;
}
if (funding.stream) {
fundedByProject['funding'] = funding.stream;
}
@ -81,11 +79,10 @@ export class ParsingFunctions {
}
// publication & research data : for fundedByProjects | project landing : for funding
public parseFundingTrees(fundingTree: any): any {
let funding: { "funderName": string, "funderShortname": string, "funderJurisdiction": string, "stream": string } = {
public parseFundingTrees(fundingTree: any): { "funderName": string, "funderShortname": string, "stream": string } {
let funding: { "funderName": string, "funderShortname": string, "stream": string } = {
"funderName": "",
"funderShortname": "",
"funderJurisdiction": "",
"stream": ""
};
let length = Array.isArray(fundingTree) ? fundingTree.length : 1;
@ -96,7 +93,6 @@ export class ParsingFunctions {
if (fundingData.hasOwnProperty("funder")) {
funding.funderShortname = fundingData['funder'].shortname;
funding.funderName = fundingData['funder'].name;
funding.funderJurisdiction = fundingData['funder'].jurisdiction;
}
funding.stream = this.addFundingLevel0(fundingData, funding.stream);
@ -269,8 +265,7 @@ export class ParsingFunctions {
"types": [],
"years": [],
"license": "",
"fulltext": "",
"peerReviewed": null
"fulltext": ""
};
if (instance.hasOwnProperty("hostedby")) {
@ -363,10 +358,6 @@ export class ParsingFunctions {
if(instance.hasOwnProperty("fulltext")) {
available.fulltext = instance['fulltext'];
}
if(instance.hasOwnProperty("refereed") && instance.refereed.classname == "peerReviewed") {
available.peerReviewed = true;
}
hostedBy_collectedFrom.push(available);
}
@ -542,8 +533,7 @@ export class ParsingFunctions {
if (pid.hasOwnProperty("classid") && pid['classid'] != "") {
if (pid.classid == "doi" || pid.classid == "pmc" || pid.classid == "handle" || pid.classid == "pmid" || pid.classid == "re3data"
|| pid.classid == "swhid"
|| pid.classid == "ROR" || pid.classid == "ISNI" || pid.classid == "Wikidata" || pid.classid == "FundRef") {
|| pid.classid == "swhid") {
if (!identifiers.has(pid.classid)) {
identifiers.set(pid.classid, new Array<string>());
}
@ -552,8 +542,7 @@ export class ParsingFunctions {
} else {
for (let i = 0; i < pid.length; i++) {
if (pid[i].classid == "doi" || pid[i].classid == "pmc" || pid[i].classid == "handle" || pid[i].classid == "pmid" || pid[i].classid == "re3data"
|| pid[i].classid == "swhid"
|| pid[i].classid == "ROR" || pid[i].classid == "ISNI" || pid[i].classid == "Wikidata" || pid[i].classid == "FundRef") {
|| pid[i].classid == "swhid") {
if (!identifiers.has(pid[i].classid)) {
identifiers.set(pid[i].classid, new Array<string>());
}
@ -585,7 +574,7 @@ export class ParsingFunctions {
return eoscSubjectsFound;
}
// publication & dataset landing : for subjects and otherSubjects and classifiedSubjects
parseAllSubjects(_subjects: any, vocabulary: any): [string[], Map<string, string[]>, Map<string, string[]>, string[], string[],] {
// let eoscSubjectsFound = [];
@ -594,12 +583,12 @@ export class ParsingFunctions {
let classifiedSubjects: Map<string, string[]>;
let fos: string[];
let sdg: string[];
let setOfEoscSubjects: Set<string> = new Set();
let subject;
let length = Array.isArray(_subjects) ? _subjects.length : 1;
for (let i = 0; i < length; i++) {
subject = Array.isArray(_subjects) ? _subjects[i] : _subjects;
if (subject.classid != "") {
@ -632,7 +621,7 @@ export class ParsingFunctions {
if (classifiedSubjects == undefined) {
classifiedSubjects = new Map<string, string[]>();
}
let content: string = subject.content + "";
// let checkAndAddEoscSubjectResp = this.checkAndAddEoscSubject(setOfEoscSubjects, eoscSubjectsFound, subject, content);
// let found: boolean = checkAndAddEoscSubjectResp["found"];
@ -643,11 +632,7 @@ export class ParsingFunctions {
if (!classifiedSubjects.has(subject.classname)) {
classifiedSubjects.set(subject.classname, new Array<string>());
}
if(properties.environment == "production") {
classifiedSubjects.get(subject.classname).push(content);
} else {
classifiedSubjects.get(subject.classname).push(subject.classid + ": " + content);
}
classifiedSubjects.get(subject.classname).push(content);
// }
}
} else {
@ -667,17 +652,6 @@ export class ParsingFunctions {
}
}
}
if(properties.environment != "production" && classifiedSubjects != null) {
if (subjects == undefined) {
subjects = new Array<string>();
}
for (let classified of classifiedSubjects.keys()) {
subjects = subjects.concat(classifiedSubjects.get(classified));
}
classifiedSubjects = null;
}
return [subjects, otherSubjects, classifiedSubjects, fos, sdg];
}

View File

@ -116,8 +116,7 @@ export class ProjectsInModalComponent {
}
if (filterLimits.length > 0) {
//this.filterQuery+=' and '+filter.filterId + ' exact '+ filterLimits + ' ';
// this.filterQuery += ' and ( ' + filterLimits + ' ) ';
this.filterQuery += '( ' + filterLimits + ' ) ';
this.filterQuery += ' and ( ' + filterLimits + ' ) ';
}
}

View File

@ -9,6 +9,7 @@ import {ShowSubjectsComponent} from './showSubjects.component';
import {FundedByComponent} from './fundedBy.component';
import {AvailableOnComponent} from './availableOn.component';
import {TabTableComponent} from './tabTable.component';
import {ShowPublisherComponent} from "./showPublisher.component";
import {ShowPublisherModule} from "./showPublisher.module";
import {RelatedToComponent} from "./relatedTo.component";
import {FosComponent} from "./fos.component";
@ -16,11 +17,13 @@ import {SdgComponent} from "./sdg.component";
import {IconsModule} from "../../utils/icons/icons.module";
import {AlertModalModule} from "../../utils/modal/alertModal.module";
import { SearchInputModule } from '../../sharedComponents/search-input/search-input.module';
import {EntityMetadataComponent} from "./entity-metadata.component";
import {IconsService} from "../../utils/icons/icons.service";
import {book, closed_access, cog, database, earth, open_access, unknown_access} from "../../utils/icons/icons";
import {FullScreenModalModule} from "../../utils/modal/full-screen-modal/full-screen-modal.module";
import {MobileDropdownModule} from "../../utils/mobile-dropdown/mobile-dropdown.module";
@NgModule({
imports: [
CommonModule, FormsModule, RouterModule, PagingModule, ShowPublisherModule, IconsModule, AlertModalModule,
@ -29,14 +32,15 @@ import {MobileDropdownModule} from "../../utils/mobile-dropdown/mobile-dropdown.
declarations: [
ShowIdentifiersComponent,ShowSubjectsComponent,
FundedByComponent,AvailableOnComponent,TabTableComponent,
RelatedToComponent, FosComponent, SdgComponent
RelatedToComponent, FosComponent, SdgComponent,
EntityMetadataComponent
],
providers:[
],
exports: [
ShowIdentifiersComponent, ShowSubjectsComponent,
FundedByComponent,AvailableOnComponent, TabTableComponent,
RelatedToComponent, FosComponent, SdgComponent
FundedByComponent,AvailableOnComponent, TabTableComponent, ShowPublisherComponent,
RelatedToComponent, FosComponent, SdgComponent, EntityMetadataComponent
]
})
export class ResultLandingUtilsModule {

View File

@ -15,36 +15,34 @@ import {StringUtils} from "../../../utils/string-utils.class";
template: `
<modal-alert #selectionModal [large]="true" (alertOutput)="modalOutput()" (cancelOutput)="modalCancel()"
[okDisabled]="!sent && !selectionStep1 && (form.invalid || sending)">
<ng-container *ngIf="isOpen">
<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.
<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>
</ng-container>
</div>
</modal-alert>
`
})
@ -64,7 +62,6 @@ export class SdgFosSuggestComponent {
public sent: boolean = false;
public error: boolean = false;
subscriptions: Subscription[] = [];
isOpen: boolean = false;
constructor(private emailService: EmailService, private fb: FormBuilder, private cdr: ChangeDetectorRef) {}

View File

@ -26,9 +26,8 @@ import {properties} from "../../../../environments/environment";
<span class="uk-text-meta uk-text-small" [class.uk-text-uppercase]="key != 're3data'">{{key}}: </span>
<span [class.uk-margin-small-left]="modal">
<ng-container *ngFor="let item of identifiers.get(key) let j=index">
<a *ngIf="key == 'doi' || key == 'pmc' || key == 'pmid' || key == 'handle' || key == 're3data' || key == 'swhid'
|| key == 'ROR' || key == 'ISNI' || key == 'Wikidata' || key == 'FundRef'"
[href]="getUrl(key, item) + item" target="_blank" class="uk-display-inline-block custom-external">
<a *ngIf="key == 'doi' || key == 'pmc' || key == 'pmid' || key == 'handle' || key == 're3data' || key == 'swhid'"
[href]="getUrl(key) + item" target="_blank" class="uk-display-inline-block custom-external">
{{item}}
</a>
<ng-container *ngIf="(j !== (identifiers.get(key).length - 1))">, </ng-container>
@ -114,10 +113,7 @@ export class ShowIdentifiersComponent implements AfterViewInit {
});
}
public getUrl(key: string, value: string): string {
if(value.includes("http://") || value.includes("https://")) {
return "";
}
public getUrl(key: string): string {
if(key == "doi") {
return properties.doiURL;
} else if(key == "pmc") {
@ -130,14 +126,6 @@ export class ShowIdentifiersComponent implements AfterViewInit {
return properties.r3DataURL;
} else if(key == "swhid") {
return properties.swhURL;
} else if(key == "ROR") {
return properties.rorURL;
} else if(key == "ISNI") {
return properties.isniURL;
} else if(key == "Wikidata") {
return properties.wikiDataURL;
} else if(key == "FundRef") {
return properties.fundRefURL;
}
}

View File

@ -5,8 +5,7 @@ import {EnvProperties} from "../../utils/properties/env-properties";
selector: 'showPublisher, [showPublisher]',
template: `
<ng-container *ngIf="publisher">
<span class="uk-text-meta uk-margin-xsmall-right">Publisher:</span>
<span>{{publisher}}</span>
<span [attr.uk-tooltip]="'cls: uk-active'" [title]="'Publisher'">{{publisher}}</span>
<span *ngIf="journal && (journal['journal'] || journal['issn'] || journal['lissn']
|| journal['volume'] || journal['eissn'] || journal['issue'])"
class="uk-margin-xsmall-left uk-margin-xsmall-right bullet"></span>
@ -15,8 +14,7 @@ import {EnvProperties} from "../../utils/properties/env-properties";
|| journal['volume'] || journal['eissn'] || journal['issue'])">
<ng-container *ngIf="journal && (journal['journal'] || journal['issn'] || journal['lissn']
|| journal['volume'] || journal['eissn'] || journal['issue'])">
<span>
<span class="uk-text-meta uk-margin-xsmall-right">Journal:</span>
<span [attr.uk-tooltip]="'cls: uk-active'" [title]="'Journal'">
<span *ngIf="journal['journal']">{{journal['journal']}}</span>
<span *ngIf="journal['journal'] && (journal['volume'] || journal['issue'])">, </span>
<ng-container *ngIf="journal['volume']">

View File

@ -13,7 +13,7 @@ import {properties} from "../../../../environments/environment";
@Component({
selector: 'showSubjects',
template: `
<ng-container *ngIf="properties.environment == 'production' && !viewAllSubjects && ((classifiedSubjects && classifiedSubjects.size > 0) || (eoscSubjects && eoscSubjects.length > 0))">
<ng-container *ngIf="!viewAllSubjects && ((classifiedSubjects && classifiedSubjects.size > 0) || (eoscSubjects && eoscSubjects.length > 0))">
<div *ngIf="!viewAllClassifiedSubjects" class="uk-text-meta">
Subjects by Vocabulary
</div>
@ -22,11 +22,10 @@ import {properties} from "../../../../environments/environment";
<div *ngIf="isClassifiedLarge && !viewAllClassifiedSubjects" class="uk-text-right">
<a (click)="viewAllSubjectsByVocabularyClicked()" class="view-more-less-link">View all</a>
</div>
</ng-container>
<ng-container *ngIf="!viewAllClassifiedSubjects && ((subjects && subjects.length > 0) || (otherSubjects && otherSubjects.size > 0))">
<div *ngIf="!viewAllSubjects" class="uk-text-meta uk-margin-small-bottom"
[class.uk-margin-medium-top]="properties.environment == 'production' && ((classifiedSubjects && classifiedSubjects.size > 0) || (eoscSubjects && eoscSubjects.length > 0))">
<div *ngIf="!viewAllSubjects" class="uk-text-meta uk-margin-small-bottom" [class.uk-margin-medium-top]="classifiedSubjects && classifiedSubjects.size > 0">
Keywords
</div>
<ng-container *ngTemplateOutlet="subjects_template; context: {customClasses: (isMobile && viewAllSubjects) ? '' : 'multi-line-ellipsis lines-2', id: 'content'}"></ng-container>
@ -34,16 +33,6 @@ import {properties} from "../../../../environments/environment";
<a (click)="viewAllSubjectsClicked()" class="view-more-less-link">View all</a>
</div>
</ng-container>
<ng-container *ngIf="properties.environment != 'production' && !viewAllSubjects && ((eoscSubjects && eoscSubjects.length > 0))">
<div class="uk-text-meta uk-margin-small-bottom"
[class.uk-margin-medium-top]="(subjects && subjects.length > 0) || (otherSubjects && otherSubjects.size > 0)">
EOSC Subjects
</div>
<div *ngIf="eoscSubjects && eoscSubjects.length > 0">
<ng-container *ngTemplateOutlet="eosc_subjects_template; context: {id: 'content'}"></ng-container>
</div>
</ng-container>
<ng-template #subjects_template let-customClasses="customClasses" let-id="id">
<div class="uk-text-break" [ngClass]="customClasses">
@ -89,7 +78,7 @@ import {properties} from "../../../../environments/environment";
<ng-template #eosc_subjects_template let-customClasses="customClasses" let-id="id">
<div class="uk-flex-wrap uk-margin-medium-right"
[ngClass]="customClasses">
<p *ngIf="properties.environment == 'production'" class="uk-flex uk-flex-middle uk-margin-bottom">
<p class="uk-flex uk-flex-middle uk-margin-bottom">
<span #classifiedContent [id]="id+'_eosc'">
<span class="uk-margin-small-top uk-display-inline-block">
<span uk-icon="tag"></span>
@ -102,17 +91,13 @@ import {properties} from "../../../../environments/environment";
</span>
</span>
</p>
<p *ngIf="properties.environment != 'production' && eoscSubjects && eoscSubjects.length > 0">
<span #classifiedContent [id]="id+'_eosc'">{{getValue(eoscSubjects).join(', ')}}</span>
</p>
</div>
</ng-template>
<modal-alert #subjectsByVocabularyModal *ngIf="!isMobile && ((classifiedSubjects && classifiedSubjects.size > 0) || (eoscSubjects && eoscSubjects.length > 0))" large="true">
<div class="uk-text-small">
<ng-container *ngTemplateOutlet="subjects_by_vocabulary_template"></ng-container>
<ng-container *ngIf="eoscSubjects && eoscSubjects.length > 0"><ng-container *ngTemplateOutlet="eosc_subjects_template; context: {id: 'content'}"></ng-container></ng-container>
<ng-container *ngIf="eoscSubjects && eoscSubjects.length > 0"><ng-container *ngTemplateOutlet="eosc_subjects_template"></ng-container></ng-container>
</div>
</modal-alert>
`
@ -249,8 +234,4 @@ export class ShowSubjectsComponent {
this.openSubjectsByVocabularyModal();
}
}
getValue(eosSubjects) {
return eosSubjects.map(res => res.value);
}
}

View File

@ -0,0 +1,24 @@
import {Component, Input, Output, EventEmitter} from '@angular/core';
@Component({
selector: 'tabPaging',
template: `
<div class="uk-panel" *ngIf="!showAll && length > 10">
<a (click)="changeShowAll.emit({value: true});">
<div class="uk-float-right">view all {{length | number}}</div>
</a>
</div>
`
})
export class TabPagingComponent {
@Input() showAll: boolean;
@Input() length: number;
@Output() changeShowAll: EventEmitter<any> = new EventEmitter();
constructor () {
}
ngOnInit() {
}
}

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