[develop | DONE | ADDED]: Added relation between products (research product landing) and services (data sources - exclude service type).
1. result-preview.ts: Define interface RelationDatasource and added method "relationDatasourceConvert()". 2. resultLandingInfo.ts: Added fields "relatedServices" and "relatedServicesClassFilters". 3. resultLanding.service.ts: Call parsing for relations "dnet:result_datasource_relations". 4. parsingFunctions.class.ts: Added method "parseDatasources()". 5. resultLanding.component: Follow same schema for related research products (relatedResults) and related services (relatedServices), initialize relation fields and show them.
This commit is contained in:
parent
94e831c548
commit
de793ab3ad
|
@ -1,4 +1,9 @@
|
|||
import {HostedByCollectedFrom, Project, RelationResult} from "../../utils/result-preview/result-preview";
|
||||
import {
|
||||
HostedByCollectedFrom,
|
||||
Project,
|
||||
RelationDatasource,
|
||||
RelationResult
|
||||
} from "../../utils/result-preview/result-preview";
|
||||
import {Context, Measure, Metric, MetricPerDatasource, Reference} from "../../utils/entities/resultLandingInfo";
|
||||
import {Injectable} from '@angular/core';
|
||||
import {properties} from "../../../../environments/environment";
|
||||
|
@ -527,6 +532,56 @@ export class ParsingFunctions {
|
|||
return researchResults;
|
||||
}
|
||||
|
||||
// publication & dataset & software & orp landing : for relatedResearchResults
|
||||
parseDatasources(datasources: RelationDatasource[], relation, provenanceAction: string, relationName: string): RelationDatasource[] {
|
||||
let datasource: RelationDatasource = {
|
||||
name: "",
|
||||
id: "",
|
||||
percentage: null,
|
||||
percentageName: null,
|
||||
class: "",
|
||||
provenanceAction: provenanceAction,
|
||||
relationName: relationName,
|
||||
openaireCompatibility: ""
|
||||
};
|
||||
|
||||
datasource['id'] = relation['to'].content;
|
||||
if(relation["officialname"])
|
||||
datasource.name = relation.officialname;
|
||||
else {
|
||||
datasource['name'] = "[no title available]";
|
||||
}
|
||||
|
||||
let percentageName: string;
|
||||
if (relation.trust) {
|
||||
percentageName = "trust";
|
||||
} else if (relation.similarity) {
|
||||
percentageName = "similarity";
|
||||
}
|
||||
if (percentageName) {
|
||||
datasource['percentage'] = Math.round(relation[percentageName] * 100);
|
||||
datasource['percentageName'] = percentageName;
|
||||
}
|
||||
|
||||
// type
|
||||
if(relation.hasOwnProperty('datasourcetype') && relation['datasourcetype'].hasOwnProperty("classname")) {
|
||||
datasource.class = relation['datasourcetype'].classname;
|
||||
}
|
||||
|
||||
// compatibility
|
||||
if(relation.hasOwnProperty("openairecompatibility")) {
|
||||
datasource.openaireCompatibility = relation['openairecompatibility'].classname;
|
||||
}
|
||||
|
||||
if(datasource.class !== "service" || properties.adminToolsPortalType == "eosc") {
|
||||
if (datasources == undefined) {
|
||||
datasources = [];
|
||||
}
|
||||
datasources.push(datasource);
|
||||
}
|
||||
return datasources;
|
||||
}
|
||||
|
||||
sortByPercentage(results: RelationResult[]): RelationResult[] {
|
||||
if (results) {
|
||||
return results.sort(function (a, b) {
|
||||
|
|
|
@ -153,6 +153,10 @@
|
|||
[tabTitle]="'Related research'" [tabId]="'all_related'"
|
||||
[tabNumber]="resultLandingInfo.relatedResults.length">
|
||||
</my-tab>
|
||||
<my-tab *ngIf="resultLandingInfo.relatedServices?.length > 0"
|
||||
[tabTitle]="openaireEntities.DATASOURCES" [tabId]="'dataProviders'"
|
||||
[tabNumber]="resultLandingInfo.relatedServices.length">
|
||||
</my-tab>
|
||||
<my-tab *ngIf="resultLandingInfo.bioentities && bioentitiesNum> 0"
|
||||
[tabTitle]="'External Databases'" [tabId]="'bioentities'" [tabNumber]="bioentitiesNum">
|
||||
</my-tab>
|
||||
|
@ -179,9 +183,13 @@
|
|||
</ng-container>
|
||||
<ng-container *ngIf="resultLandingInfo.relatedResults?.length > 0">
|
||||
<div id="all_related" class="landing-section">
|
||||
<ng-container *ngTemplateOutlet="relation_in_tab; context: { researchResults: filteredRelatedResults, header: ''}"></ng-container>
|
||||
<ng-container *ngTemplateOutlet="relation_in_tab; context: { related: filteredRelatedResults, props: relatedResults, header: ''}"></ng-container>
|
||||
</div>
|
||||
</ng-container>
|
||||
<div *ngIf="resultLandingInfo.relatedServices?.length > 0"
|
||||
id="dataProviders" class="landing-section">
|
||||
<ng-container *ngTemplateOutlet="relation_in_tab; context: { related: filteredRelatedServices, props: relatedServices, type: 'datasource', header: ''}"></ng-container>
|
||||
</div>
|
||||
<ng-container *ngIf="resultLandingInfo.bioentities && bioentitiesNum> 0">
|
||||
<div id="bioentities" class="landing-section">
|
||||
<ng-container *ngTemplateOutlet="bioentities_content"></ng-container>
|
||||
|
@ -457,6 +465,14 @@
|
|||
</div>
|
||||
<hr>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="resultLandingInfo.relatedServices?.length > 0">
|
||||
<div class="clickable uk-flex uk-flex-middle uk-flex-between"
|
||||
(click)="openFsModal(servicesFsModal, openaireEntities.DATASOURCES); onSelectActiveTab('dataProviders')">
|
||||
<span>{{openaireEntities.DATASOURCES}}</span>
|
||||
<icon name="chevron_right" [ratio]="1.5" [flex]="true"></icon>
|
||||
</div>
|
||||
<hr>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="resultLandingInfo.bioentities && bioentitiesNum> 0">
|
||||
<div class="clickable uk-flex uk-flex-middle uk-flex-between" (click)="openFsModal(bioentitiesFsModal, 'External Databases'); onSelectActiveTab('bioentities')">
|
||||
<span>External Databases</span>
|
||||
|
@ -638,7 +654,15 @@
|
|||
<fs-modal #relatedResearchFsModal classTitle="uk-tile-default uk-border-bottom"
|
||||
*ngIf="resultLandingInfo.relatedResults?.length > 0">
|
||||
<div class="landing-section">
|
||||
<ng-container *ngTemplateOutlet="relation_in_tab; context: { researchResults: filteredRelatedResults, header: ''}"></ng-container>
|
||||
<ng-container *ngTemplateOutlet="relation_in_tab; context: { related: filteredRelatedResults, props: relatedResults, header: ''}"></ng-container>
|
||||
</div>
|
||||
</fs-modal>
|
||||
|
||||
|
||||
<fs-modal *ngIf="isMobile" #servicesFsModal classTitle="uk-tile-default uk-border-bottom">
|
||||
<div *ngIf="activeTab == 'dataProviders' && resultLandingInfo.relatedServices?.length > 0"
|
||||
class="landing-section">
|
||||
<ng-container *ngTemplateOutlet="relation_in_tab; context: { related: filteredRelatedServices, props: relatedServices, type: 'datasource', header: ''}"></ng-container>
|
||||
</div>
|
||||
</fs-modal>
|
||||
|
||||
|
@ -763,34 +787,32 @@
|
|||
</ul>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #relation_in_tab let-researchResults="researchResults" let-header="header">
|
||||
<div
|
||||
*ngIf="researchResults && researchResults.length > 0"
|
||||
class="uk-margin-bottom">
|
||||
<ng-template #relation_in_tab let-related="related" let-props="props" let-type="type" let-header="header">
|
||||
<div *ngIf="related && related.length > 0" class="uk-margin-bottom">
|
||||
<h6 *ngIf="header">{{header}}</h6>
|
||||
<div *ngIf="relatedClassFilters?.length > 1" class="uk-margin-medium-bottom"
|
||||
<div *ngIf="props.classFilters?.length > 1" class="uk-margin-medium-bottom"
|
||||
input type="select" placeholder="Filter by relation" inputClass="flat x-small"
|
||||
[options]="relatedClassFilters" [(value)]="relatedClassSelected"
|
||||
(valueChange)="relatedClassChanged()"></div>
|
||||
[options]="props.classFilters" [(value)]="props.selectedClass"
|
||||
(valueChange)="relatedClassChanged(type)"></div>
|
||||
|
||||
<results-and-pages
|
||||
[type]="openaireEntities.RESULTS"
|
||||
[page]="relatedPage" [pageSize]="pageSize"
|
||||
[totalResults]="researchResults.length">
|
||||
[type]="((type == 'datasource') ? openaireEntities.DATASOURCES : openaireEntities.RESULTS)"
|
||||
[page]="props.page" [pageSize]="pageSize"
|
||||
[totalResults]="related.length">
|
||||
</results-and-pages>
|
||||
<ul class="uk-list uk-list-divider uk-margin">
|
||||
<li *ngFor="let item of researchResults.slice((relatedPage-1)*pageSize, relatedPage*pageSize)">
|
||||
<li *ngFor="let item of related.slice((props.page-1)*pageSize, props.page*pageSize)">
|
||||
<result-preview [properties]="properties"
|
||||
[result]="getResultPreview(item)" [provenanceActionVocabulary]="provenanceActionVocabulary"
|
||||
[result]="getResultPreview(item, type)" [provenanceActionVocabulary]="provenanceActionVocabulary"
|
||||
[relationsVocabulary]="relationsVocabulary"
|
||||
[isCard]="false" [prevPath]="prevPath"></result-preview>
|
||||
</li>
|
||||
</ul>
|
||||
<paging-no-load *ngIf="researchResults.length > pageSize"
|
||||
<paging-no-load *ngIf="related.length > pageSize"
|
||||
class="uk-margin-top"
|
||||
(pageChange)="updateRelatedPage($event)"
|
||||
[currentPage]="relatedPage" [size]="pageSize"
|
||||
[totalResults]="researchResults.length">
|
||||
(pageChange)="updateRelatedPage($event, type)"
|
||||
[currentPage]="props.page" [size]="pageSize"
|
||||
[totalResults]="related.length">
|
||||
</paging-no-load>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
|
|
@ -13,7 +13,7 @@ import {HelperFunctions} from '../../utils/HelperFunctions.class';
|
|||
import {HelperService} from '../../utils/helper/helper.service';
|
||||
import {Location} from "@angular/common";
|
||||
import {MetricsService} from "../../services/metrics.service";
|
||||
import {RelationResult, ResultPreview} from "../../utils/result-preview/result-preview";
|
||||
import {RelationDatasource, RelationResult, ResultPreview} from "../../utils/result-preview/result-preview";
|
||||
import {IndexInfoService} from "../../utils/indexInfo.service";
|
||||
import {Identifier, StringUtils} from "../../utils/string-utils.class";
|
||||
import {properties} from "../../../../environments/environment";
|
||||
|
@ -95,12 +95,7 @@ export class ResultLandingComponent {
|
|||
// Custom tab paging variables
|
||||
public referencesPage: number = 1;
|
||||
public bioentitiesPage: number = 1;
|
||||
public relatedPage: number = 1;
|
||||
public similarPage: number = 1;
|
||||
public supplementaryPage: number = 1;
|
||||
public supplementedByPage: number = 1;
|
||||
public organizationsPage: number = 1;
|
||||
public openCitationsPage: number = 1;
|
||||
|
||||
public pageSize: number = 10;
|
||||
|
||||
// Map counting variables
|
||||
|
@ -139,9 +134,28 @@ export class ResultLandingComponent {
|
|||
public pid: string;
|
||||
public contextsWithLink: any;
|
||||
|
||||
public relatedClassFilters: Option[]=[{"label": "All relations", "value": ""}];
|
||||
public relatedClassSelected: string = "";
|
||||
public filteredRelatedResults: RelationResult[];
|
||||
public relatedResults: {
|
||||
classFilters: Option[],
|
||||
selectedClass: string,
|
||||
page: number
|
||||
} = {
|
||||
classFilters: [{"label": "All relations", "value": ""}],
|
||||
selectedClass: "",
|
||||
page: 1,
|
||||
};
|
||||
filteredRelatedResults: RelationResult[];
|
||||
|
||||
public relatedServices: {
|
||||
classFilters: Option[],
|
||||
selectedClass: string,
|
||||
page: number
|
||||
} = {
|
||||
classFilters: [{"label": "All relations", "value": ""}],
|
||||
selectedClass: "",
|
||||
page: 1
|
||||
}
|
||||
filteredRelatedServices: RelationDatasource[];
|
||||
|
||||
|
||||
public provenanceActionVocabulary = null;
|
||||
public relationsVocabulary = null;
|
||||
|
@ -168,6 +182,7 @@ export class ResultLandingComponent {
|
|||
@ViewChild('subjectsFsModal') subjectsFsModal: FullScreenModalComponent;
|
||||
@ViewChild('referencesFsModal') referencesFsModal: FullScreenModalComponent;
|
||||
@ViewChild('relatedResearchFsModal') relatedResearchFsModal: FullScreenModalComponent;
|
||||
@ViewChild('servicesFsModal') servicesFsModal: FullScreenModalComponent;
|
||||
@ViewChild('bioentitiesFsModal') bioentitiesFsModal: FullScreenModalComponent;
|
||||
@ViewChild('compatibleEOSCFsModal') compatibleEOSCFsModal: FullScreenModalComponent;
|
||||
@ViewChild('fundedByFsModal') fundedByFsModal: FullScreenModalComponent;
|
||||
|
@ -558,20 +573,34 @@ export class ResultLandingComponent {
|
|||
}
|
||||
}
|
||||
}
|
||||
this.relatedClassFilters = [{"label": "All relations", "value": ""}];
|
||||
this.relatedResults.classFilters = [{"label": "All relations", "value": ""}];
|
||||
if (this.resultLandingInfo.relatedClassFilters.size > 1) {
|
||||
for (let relClass of this.resultLandingInfo.relatedClassFilters) {
|
||||
this.relatedClassFilters.push({
|
||||
this.relatedResults.classFilters.push({
|
||||
"label": HelperFunctions.getVocabularyLabel(relClass, this.relationsVocabulary),
|
||||
"value": relClass
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this.relatedClassFilters.pop();
|
||||
this.relatedResults.classFilters.pop();
|
||||
}
|
||||
this.relatedClassSelected = "";
|
||||
this.relatedResults.selectedClass = "";
|
||||
this.filteredRelatedResults = this.resultLandingInfo.relatedResults;
|
||||
|
||||
this.relatedServices.classFilters = [{"label": "All relations", "value": ""}];
|
||||
if (this.resultLandingInfo.relatedServicesClassFilters.size > 1) {
|
||||
for (let relClass of this.resultLandingInfo.relatedServicesClassFilters) {
|
||||
this.relatedServices.classFilters.push({
|
||||
"label": HelperFunctions.getVocabularyLabel(relClass, this.relationsVocabulary),
|
||||
"value": relClass
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this.relatedServices.classFilters.pop();
|
||||
}
|
||||
this.relatedServices.selectedClass = "";
|
||||
this.filteredRelatedServices = this.resultLandingInfo.relatedServices
|
||||
|
||||
this.hasViews = false;
|
||||
this.hasDownloads = false;
|
||||
if (this.resultLandingInfo.measure && this.resultLandingInfo.measure.counts) {
|
||||
|
@ -711,25 +740,14 @@ export class ResultLandingComponent {
|
|||
this.scrollToTabTop('bioentities');
|
||||
}
|
||||
|
||||
public updateRelatedPage($event) {
|
||||
this.relatedPage = $event.value;
|
||||
this.scrollToTabTop('all_related');
|
||||
}
|
||||
|
||||
public updateSimilarPage($event) {
|
||||
this.similarPage = $event.value;
|
||||
}
|
||||
|
||||
public updateSupplementaryPage($event) {
|
||||
this.supplementaryPage = $event.value;
|
||||
}
|
||||
|
||||
public updateSupplementedByPage($event) {
|
||||
this.supplementedByPage = $event.value;
|
||||
}
|
||||
|
||||
public updateOrganizationsPage($event) {
|
||||
this.organizationsPage = $event.value;
|
||||
public updateRelatedPage($event, type) {
|
||||
if(type == "datasource") {
|
||||
this.relatedServices.page = $event.value;
|
||||
this.scrollToTabTop("dataProviders");
|
||||
} else {
|
||||
this.relatedResults.page = $event.value;
|
||||
this.scrollToTabTop('all_related');
|
||||
}
|
||||
}
|
||||
|
||||
scrollToTabTop(tabId:string){
|
||||
|
@ -788,8 +806,11 @@ export class ResultLandingComponent {
|
|||
this.alertModalDeletedByInference.open();
|
||||
}
|
||||
|
||||
public getResultPreview(result: RelationResult): ResultPreview {
|
||||
return ResultPreview.relationResultConvert(result);
|
||||
public getResultPreview(result: RelationResult|RelationDatasource, type: string): ResultPreview {
|
||||
if(type == "datasource") {
|
||||
return ResultPreview.relationDatasourceConvert(<RelationDatasource>result);
|
||||
}
|
||||
return ResultPreview.relationResultConvert(<RelationResult>result);
|
||||
}
|
||||
|
||||
updateUrlWithType(pid) {
|
||||
|
@ -983,9 +1004,14 @@ export class ResultLandingComponent {
|
|||
this.contextsWithLink = contextsWithLink;
|
||||
}
|
||||
|
||||
public relatedClassChanged() {
|
||||
this.relatedPage = 1;
|
||||
this.filteredRelatedResults = this.resultLandingInfo.relatedResults.filter(result => !this.relatedClassSelected || result.relationName.toLowerCase() == this.relatedClassSelected.toLowerCase());
|
||||
public relatedClassChanged(type) {
|
||||
if(type == "datasource") {
|
||||
this.relatedServices.page = 1;
|
||||
this.filteredRelatedServices = this.resultLandingInfo.relatedServices.filter(result => !this.relatedServices.selectedClass || result.relationName.toLowerCase() == this.relatedServices.selectedClass.toLowerCase());
|
||||
} else {
|
||||
this.relatedResults.page = 1;
|
||||
this.filteredRelatedResults = this.resultLandingInfo.relatedResults.filter(result => !this.relatedResults.selectedClass || result.relationName.toLowerCase() == this.relatedResults.selectedClass.toLowerCase());
|
||||
}
|
||||
}
|
||||
|
||||
public viewAllOrganizationsClick() {
|
||||
|
|
|
@ -210,6 +210,19 @@ export class ResultLandingService {
|
|||
this.resultLandingInfo.relatedResults = this.parsingFunctions.parseResults(this.resultLandingInfo.relatedResults, relation, provenanceAction, relationName);
|
||||
} else if (relation['to'].class && relation['to'].class.toLowerCase() == "hasauthorinstitution") {
|
||||
this.resultLandingInfo.organizations = this.parseRelatedOrganizations(this.resultLandingInfo.organizations, relation);
|
||||
} else if (relation['to'].scheme && relation['to'].scheme == "dnet:result_datasource_relations") {
|
||||
let relationName: string = relation.to.class;
|
||||
if (!this.resultLandingInfo.relatedServicesClassFilters.has(relationName)) {
|
||||
this.resultLandingInfo.relatedServicesClassFilters.add(relationName);
|
||||
}
|
||||
|
||||
let provenanceAction: string = relation.provenanceaction;
|
||||
|
||||
// this.resultLandingInfo.relatedResults = this.parsingFunctions.parseResults(this.resultLandingInfo.relatedResults, relation, provenanceAction, relationName);
|
||||
if (this.resultLandingInfo.relatedServices == undefined) {
|
||||
this.resultLandingInfo.relatedServices = [];
|
||||
}
|
||||
this.resultLandingInfo.relatedServices = this.parsingFunctions.parseDatasources(this.resultLandingInfo.relatedServices, relation, provenanceAction, relationName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ import {
|
|||
HostedByCollectedFrom,
|
||||
Journal, OARoutes,
|
||||
Organization,
|
||||
Project,
|
||||
Project, RelationDatasource,
|
||||
RelationResult
|
||||
} from "../result-preview/result-preview";
|
||||
import {isArray} from "rxjs/internal-compatibility";
|
||||
|
@ -194,6 +194,9 @@ export class ResultLandingInfo {
|
|||
organizations: Organization[];
|
||||
openCitations: { "url": string, "title": string, "year": string, "doi": string, "authors": string[] }[];
|
||||
|
||||
relatedServices: RelationDatasource[];
|
||||
relatedServicesClassFilters: Set<string> = new Set();
|
||||
|
||||
// DATASET
|
||||
subtitle: string;
|
||||
|
||||
|
|
|
@ -37,6 +37,17 @@ export interface RelationResult {
|
|||
relationName?: string;
|
||||
}
|
||||
|
||||
export interface RelationDatasource {
|
||||
name: string;
|
||||
id: string;
|
||||
percentage: number;
|
||||
percentageName?: string;
|
||||
class: string
|
||||
provenanceAction?: string;
|
||||
relationName?: string;
|
||||
openaireCompatibility: string;
|
||||
}
|
||||
|
||||
export interface Project {
|
||||
id: string;
|
||||
acronym: string;
|
||||
|
@ -271,6 +282,20 @@ export class ResultPreview {
|
|||
return resultPreview;
|
||||
}
|
||||
|
||||
public static relationDatasourceConvert(result: RelationDatasource): ResultPreview {
|
||||
let resultPreview: ResultPreview = new ResultPreview();
|
||||
resultPreview.id = result.id;
|
||||
resultPreview.title = result.name;
|
||||
resultPreview.resultType = "dataprovider";
|
||||
resultPreview.types = [result.class];
|
||||
resultPreview.relationName = result.relationName;
|
||||
resultPreview.relation = result.percentageName;
|
||||
resultPreview.percentage = result.percentage;
|
||||
resultPreview.provenanceAction = result.provenanceAction;
|
||||
resultPreview.compatibility = result.openaireCompatibility;
|
||||
return resultPreview;
|
||||
}
|
||||
|
||||
public static organizationConvert(result: Organization, relation: string = 'trust'): ResultPreview {
|
||||
let resultPreview: ResultPreview = new ResultPreview();
|
||||
resultPreview.id = result.id;
|
||||
|
|
Loading…
Reference in New Issue