explore-services/explore/src/app/funders/funders.component.ts

284 lines
11 KiB
TypeScript

import {ChangeDetectorRef, Component, OnInit} from '@angular/core';
import {Router} from '@angular/router';
import {Subscriber, Subscription, zip} from "rxjs";
import {Meta, Title} from "@angular/platform-browser";
import {EnvProperties} from "../openaireLibrary/utils/properties/env-properties";
import {PiwikService} from "../openaireLibrary/utils/piwik/piwik.service";
import {SEOService} from "../openaireLibrary/sharedComponents/SEO/SEO.service";
import {Breadcrumb} from "../openaireLibrary/utils/breadcrumbs/breadcrumbs.component";
import {properties} from "../../environments/environment";
import {RefineFieldResultsService} from '../openaireLibrary/services/refineFieldResults.service';
import {StakeholderService} from '../openaireLibrary/monitor/services/stakeholder.service';
import {Option} from '../openaireLibrary/sharedComponents/input/input.component';
import {StringUtils} from '../openaireLibrary/utils/string-utils.class';
import {HelperFunctions} from '../openaireLibrary/utils/HelperFunctions.class';
import {NumberUtils} from '../openaireLibrary/utils/number-utils.class';
import {LayoutService} from '../openaireLibrary/dashboard/sharedComponents/sidebar/layout.service';
import {FormBuilder, FormControl} from '@angular/forms';
import {debounceTime, distinctUntilChanged} from 'rxjs/operators';
@Component({
selector: 'funders',
templateUrl: './funders.component.html',
styleUrls: ['funders.component.less']
})
export class FundersComponent implements OnInit {
private subscriptions: Subscription[] = [];
url: string = null;
pageTitle: string = "OpenAIRE - Explore | Funders";
pageDescription: string = "Funders | Be an integral part of the open R&I ecosystem";
properties: EnvProperties = properties;
breadcrumbs: Breadcrumb[] = [{name: 'home', route: '/'}, {name: 'funders'}];
showLoading: boolean = true;
isMobile: boolean = false;
funders: any[] = [];
displayedFunders: any[] = [];
showOptions: Option[];
sortOptions: Option[];
pageOptions: number[] = [10, 20, 30, 40];
show: string = 'all';
sortBy: string = 'alphAsc';
gridView: boolean = true;
currentPage: number = 1;
pageSize: number = 10;
keywordControl: FormControl;
keyword: string;
fundersNumber: number = 0;
researchProductsNumber: number = 0;
projectsNumber: number = 0;
fundersMap = new Map<string, {
"id": string,
"name": string,
"alias": string,
"researchProducts": number,
"openAccessResearchProducts": number,
"openAccessPercentage": number,
"projects": number,
"monitorDashboard": string,
"monitorDashboardStatus": string,
"logoUrl": string
}>();
constructor(private router: Router,
private meta: Meta,
private title: Title,
private seoService: SEOService,
private piwikService: PiwikService,
private refineFieldResultsService: RefineFieldResultsService,
private stakeholderService: StakeholderService,
private layoutService: LayoutService,
private cdr: ChangeDetectorRef,
private fb: FormBuilder,) {
}
ngOnInit() {
this.title.setTitle('OpenAIRE - Explore | Funders');
this.properties = properties;
this.subscriptions.push( this.piwikService.trackView(this.properties, this.pageTitle).subscribe());
this.url = this.properties.domain + this.router.url;
this.seoService.createLinkForCanonicalURL(this.url);
this.updateUrl(this.url);
this.updateTitle(this.pageTitle);
this.updateDescription(this.pageDescription);
this.subscriptions.push(this.layoutService.isMobile.subscribe(isMobile => {
this.isMobile = isMobile;
this.cdr.detectChanges();
}));
this.showOptions = [
{value: 'all', label: 'All funders'},
{value: 'dashboard', label: 'Funders with dashboard'}
];
this.sortOptions = [
{value: 'alphAsc', label: 'Alphabetically Asc. (A-Z)'},
{value: 'alphDsc', label: 'Alphabetically Dsc. (Z-A)'},
{value: 'oaDsc', label: '"Open Access %" Dsc.'}
];
this.getFunders();
this.keywordControl = this.fb.control('');
this.subscriptions.push(this.keywordControl.valueChanges.pipe(debounceTime(500), distinctUntilChanged()).subscribe(value => {
this.keyword = value;
this.filtering();
}));
}
ngOnDestroy() {
this.subscriptions.forEach(subscription => {
if (subscription instanceof Subscriber) {
subscription.unsubscribe();
}
});
}
private updateDescription(description: string) {
this.meta.updateTag({content: description}, "name='description'");
this.meta.updateTag({content: description}, "property='og:description'");
}
private updateTitle(title: string) {
var title = ((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 getFunders() {
let refineParams = '&fq=resultbestaccessright%20exact%20%22Open%20Access%22';
this.subscriptions.push(
zip(
this.refineFieldResultsService.getRefineFieldsResultsByEntityName(['relfunder'], 'result', this.properties),
this.refineFieldResultsService.getRefineFieldsResultsByEntityName(['relfunder'], 'result', this.properties, refineParams),
this.refineFieldResultsService.getRefineFieldsResultsByEntityName(['funder'], 'project', this.properties),
this.stakeholderService.getStakeholders(this.properties.monitorServiceAPIURL, 'funder')
).subscribe((data: any[]) => {
// storing all needed data to a map
// 1st call
let queriedFunders1 = data[0][1][0].values;
queriedFunders1.forEach(queriedFunder => {
this.fundersMap.set(queriedFunder.id, {
"id": queriedFunder.id,
"name": queriedFunder.name,
"alias": '',
"researchProducts": +queriedFunder.number,
"openAccessResearchProducts": 0,
"openAccessPercentage": 0,
"projects": 0,
"monitorDashboard": '',
"monitorDashboardStatus": '',
"logoUrl": ''
});
});
// 2nd call
let queriedFunders2 = data[1][1][0].values;
queriedFunders2.forEach(queriedFunder => {
if(this.fundersMap.has(queriedFunder.id)) {
this.fundersMap.get(queriedFunder.id).openAccessResearchProducts = +queriedFunder.number;
}
});
// 3rd call
let queriedFunders3 = data[2][1][0].values;
queriedFunders3.forEach(queriedFunder => {
if(+queriedFunder.number > 1) {
if (this.fundersMap.has(queriedFunder.id)) {
this.fundersMap.get(queriedFunder.id).projects = +queriedFunder.number;
} else {
this.fundersMap.set(queriedFunder.id, {
"id": queriedFunder.id,
"name": queriedFunder.name,
"alias": '',
"researchProducts": 0,
"openAccessResearchProducts": 0,
"openAccessPercentage": 0,
"projects": +queriedFunder.number,
"monitorDashboard": '',
"monitorDashboardStatus": '',
"logoUrl": ''
});
}
}
});
// 4th call
let queriedFunders4 = data[3];
queriedFunders4.forEach(queriedFunder => {
let id = queriedFunder.index_id + '||' + queriedFunder.index_name + '||' + queriedFunder.index_shortName;
if(this.fundersMap.has(id)) {
this.fundersMap.get(id).alias = queriedFunder.alias;
this.fundersMap.get(id).monitorDashboard = queriedFunder.alias;
this.fundersMap.get(id).monitorDashboardStatus = queriedFunder.visibility;
this.fundersMap.get(id).logoUrl = (queriedFunder.isUpload ? properties.utilsService + "/download/" : "")+ (queriedFunder.logoUrl);
}
});
this.fundersMap.forEach((value) => {
if(value.openAccessResearchProducts > 0) {
value.openAccessPercentage = Math.round((value.openAccessResearchProducts / value.researchProducts) * 100);
}
});
// convert funders map into an array
this.funders = Array.from(this.fundersMap.values());
// calculate total numbers for intro content
this.calculateNumbers();
// sort funders
this.funders.sort((a, b) => a['name'].localeCompare(b['name']));
// initialize displayedFunders
this.displayedFunders = this.funders;
this.showLoading = false;
})
);
}
private calculateSum(array, property) {
let sum = 0;
array.forEach(element => {
sum += element[property];
});
return sum;
}
private calculateNumbers() {
this.fundersNumber = this.funders.length;
this.researchProductsNumber = this.calculateSum(this.funders, 'researchProducts');
this.projectsNumber = this.calculateSum(this.funders, 'projects');
}
get showContentWithNumbers() {
return this.fundersNumber && this.researchProductsNumber && this.projectsNumber;
}
formatNumber(num: number | string) {
let formatted = NumberUtils.roundNumber(+num);
return formatted.number + formatted.size;
}
urlEncodeAndQuote(str: string): string {
return StringUtils.quote(StringUtils.URIEncode(str));
}
sortByChanged() {
switch(this.sortBy) {
case 'alphAsc':
this.funders = this.funders.sort((a, b) => a['name'].localeCompare(b['name']));
break;
case 'alphDsc':
this.funders = this.funders.sort((a, b) => b['name'].localeCompare(a['name']));
break;
case 'oaDsc':
this.funders = this.funders.sort((a, b) => b['openAccessPercentage'] - a['openAccessPercentage']);
break;
}
this.filtering();
}
sizeChanged($event) {
this.pageSize = $event;
this.currentPage = 1;
}
filtering() {
let displayedFunders = this.funders;
if(!this.keyword){
this.keyword = '';
}
if(this.funders.length) {
displayedFunders = displayedFunders.filter(item => (item['name'] && item['name'].toLowerCase().includes(this.keyword.toLowerCase())) || (item['alias'] && item['alias'].toLowerCase().includes(this.keyword.toLowerCase())));
}
if(this.show == 'dashboard') {
displayedFunders = displayedFunders.filter(funder => funder.monitorDashboard && funder.monitorDashboard?.length > 0 && funder.monitorDashboardStatus != 'PRIVATE');
}
this.displayedFunders = displayedFunders;
this.currentPage = 1;
}
public updateCurrentPage($event) {
this.currentPage = $event.value;
HelperFunctions.scrollToId('target');
}
}