Download CSV in Dataproviders' search page added | bug fixed in organization landing page (no projects) | publication landing page: identifiers alignment, issn not marked, show more/less functionality added on Collected From, Download From, Published In, Funded By fields

git-svn-id: https://svn.driver.research-infrastructures.eu/driver/dnet40/modules/uoa-services-portal/trunk@44566 d315682c-612b-4755-9ff5-7f18f6832af3
This commit is contained in:
konstantina.galouni 2016-11-18 07:25:01 +00:00
parent 5da8b4e8ac
commit 07ee0faa93
11 changed files with 332 additions and 45 deletions

View File

@ -80,7 +80,7 @@
</ul>
</div>
<table class="table table-striped">
<table class="table table-striped" *ngIf="organizationInfo.projects.size > 0">
<thead>
<tr>
<th class="text-center">Funder</th>
@ -131,14 +131,15 @@
Share - Bookmark
</li>
<li role="separator" class="list-group-item divider"></li>
<div *ngIf="organizationInfo.projects != undefined">
<li *ngFor="let key of organizationInfo.projects.keys()" class="list-group-item">
<a (click)="exportProjects(key)">Download projects report (CSV) for {{key}}</a>
</li>
<li *ngFor="let key of organizationInfo.projects.keys()" class="list-group-item">
<a (click)="exportProjects(key)">Download projects report (CSV) for {{key}}</a>
</li>
<li *ngFor="let key of organizationInfo.projects.keys()" class="list-group-item">
<a (click)="exportPublications(key)">Download publications report (CSV) for {{key}}</a>
</li>
<li *ngFor="let key of organizationInfo.projects.keys()" class="list-group-item">
<a (click)="exportPublications(key)">Download publications report (CSV) for {{key}}</a>
</li>
</div>
</ul>
</div>
</div>

View File

@ -102,6 +102,7 @@ export class OrganizationComponent {
this.fundersSet.add(key);
}.bind(this));
}
this.projectsNum = projectsNum;
},
err => {

View File

@ -22,11 +22,17 @@
<dt *ngIf="publicationInfo.journal != undefined && publicationInfo.journal['journal'] != ''">Journal: </dt>
<dd *ngIf="publicationInfo.journal != undefined && publicationInfo.journal != ''">
{{publicationInfo.journal['journal']}}
<span *ngIf="publicationInfo.journal['issn'] != '' || publicationInfo.journal['lissn'] != ''">
(
</span>
<span *ngIf="publicationInfo.journal['issn'] != ''">
<mark>issn:</mark> {{publicationInfo.journal['issn']}}
issn: {{publicationInfo.journal['issn']}}
</span>
<span *ngIf="publicationInfo.journal['lissn'] != ''">
<mark>lissn:</mark> {{publicationInfo.journal['lissn']}}
lissn: {{publicationInfo.journal['lissn']}}
</span>
<span *ngIf="publicationInfo.journal['issn'] != '' || publicationInfo.journal['lissn'] != ''">
)
</span>
</dd>
<dt *ngIf="publicationInfo.languages != undefined && publicationInfo.languages != 'Undetermined' && publicationInfo.languages != ''"> Languages: </dt>
@ -227,28 +233,60 @@
</li>
<li class="list-group-item" *ngIf="publicationInfo.collectedFrom != undefined">
<dl class="functionsSection">
<dt >Collected from</dt>
<dd *ngFor="let item of publicationInfo.collectedFrom">
<a href="{{item['url']}}">
<dt>Collected from</dt>
<dd *ngIf="showAllCollectedFrom">
<a class="text-muted" (click)="showAllCollectedFrom = !showAllCollectedFrom;">
View less
</a>
</dd>
<dd *ngFor="let item of publicationInfo.collectedFrom let i=index">
<a *ngIf="i<5 || showAllCollectedFrom" href="{{item['url']}}">
{{item['name']}}
</a>
</dd>
<dd *ngIf="showAllCollectedFrom">
<a class="text-muted" (click)="showAllCollectedFrom = !showAllCollectedFrom;">
View less
</a>
</dd>
<dd *ngIf="!showAllCollectedFrom && publicationInfo.collectedFrom.length > 5">
<a class="text-muted" (click)="showAllCollectedFrom = !showAllCollectedFrom;">
View more
</a>
</dd>
</dl>
</li>
<li class="list-group-item" *ngIf="publicationInfo.downloadFrom != undefined && publicationInfo.downloadFrom.size > 0">
<dl class="functionsSection">
<dt class="title">Download from</dt>
<dd class="line" *ngFor="let key of publicationInfo.downloadFrom.keys()">
<div *ngIf="publicationInfo.downloadFrom.get(key)['url'].length > 1">
{{key}}
<span *ngFor="let url of publicationInfo.downloadFrom.get(key)['url']; let i=index;">
<a href="{{url}}">
[{{i+1}}]
</a>
</span>
<dd *ngIf="showAllDownloadFrom">
<a class="text-muted" (click)="showAllDownloadFrom = !showAllDownloadFrom;">
View less
</a>
</dd>
<dd class="line" *ngFor="let key of publicationInfo.downloadFrom.keys() let i=index">
<div *ngIf="i<5 || showAllDownloadFrom">
<div *ngIf="publicationInfo.downloadFrom.get(key)['url'].length > 1">
{{key}}
<span *ngFor="let url of publicationInfo.downloadFrom.get(key)['url']; let i=index;">
<a href="{{url}}">
[{{i+1}}]
</a>
</span>
</div>
<a *ngIf="publicationInfo.downloadFrom.get(key)['url'].length == 1" href="{{publicationInfo.downloadFrom.get(key)['url']}}">
{{key}}
</a>
</div>
<a *ngIf="publicationInfo.downloadFrom.get(key)['url'].length == 1" href="{{publicationInfo.downloadFrom.get(key)['url']}}">
{{key}}
</dd>
<dd *ngIf="showAllDownloadFrom">
<a class="text-muted" (click)="showAllDownloadFrom = !showAllDownloadFrom;">
View less
</a>
</dd>
<dd *ngIf="!showAllDownloadFrom && publicationInfo.downloadFrom.length > 5">
<a class="text-muted" (click)="showAllDownloadFrom = !showAllDownloadFrom;">
View more
</a>
</dd>
</dl>
@ -256,17 +294,34 @@
<li class="list-group-item" *ngIf="publicationInfo.publishedIn != undefined && publicationInfo.publishedIn.length > 0">
<dl class="functionsSection">
<dt class="title">Published in</dt>
<dd class="line" *ngFor="let key of publicationInfo.publishedIn.keys()">
<div *ngIf="publicationInfo.publishedIn.get(key)['url'].length > 1">
{{key}}
<span *ngFor="let url of publicationInfo.publishedIn.get(key)['url']; let i=index">
<a href="{{url}}">
[{{i+1}}]
</a>
</span>
<dd *ngIf="showAllPublishedIn">
<a class="text-muted" (click)="showAllPublishedIn = !showAllPublishedIn;">
View less
</a>
</dd>
<dd class="line" *ngFor="let key of publicationInfo.publishedIn.keys() let i=index">
<div *ngIf="i<5 || showAllPublishedIn">
<div *ngIf="publicationInfo.publishedIn.get(key)['url'].length > 1">
{{key}}
<span *ngFor="let url of publicationInfo.publishedIn.get(key)['url']; let i=index">
<a href="{{url}}">
[{{i+1}}]
</a>
</span>
</div>
<a *ngIf="publicationInfo.publishedIn.get(key)['url'].length == 1" href="{{publicationInfo.publishedIn.get(key)['url']}}">
{{key}}
</a>
</div>
<a *ngIf="publicationInfo.publishedIn.get(key)['url'].length == 1" href="{{publicationInfo.publishedIn.get(key)['url']}}">
{{key}}
</dd>
<dd *ngIf="showAllPublishedIn">
<a class="text-muted" (click)="showAllPublishedIn = !showAllPublishedIn;">
View less
</a>
</dd>
<dd *ngIf="!showAllPublishedIn && publicationInfo.publishedIn.length > 5">
<a class="text-muted" (click)="showAllPublishedIn = !showAllPublishedIn;">
View more
</a>
</dd>
</dl>
@ -275,23 +330,40 @@
<li class="list-group-item">
<dl class="functionsSection" *ngIf="publicationInfo.fundedByProjects != undefined">
<dt class="title">Funded By</dt>
<dd *ngIf="showAllFundedBy">
<a class="text-muted" (click)="showAllFundedBy = !showAllFundedBy;">
View less
</a>
</dd>
<dd
title="{{item['title']}}
| Project Code: {{item['code']}}
| Funder: {{item['funderName']}} ({{item['funderShortname']}})
| Funding: {{item['funding']}}"
class="line" *ngFor="let item of publicationInfo.fundedByProjects">
<a *ngIf="!item['inline']" href="{{item['url']}}">
{{item['funderShortname']?item['funderShortname']:item['funderName']}}
| {{ item['acronym']?item['acronym']:item['title']}}
</a>
<a *ngIf="item['inline']" href="{{item['url']}}">
<mark>
class="line" *ngFor="let item of publicationInfo.fundedByProjects let i=index">
<div *ngIf="i<5 || showAllFundedBy">
<a *ngIf="!item['inline']" href="{{item['url']}}">
{{item['funderShortname']?item['funderShortname']:item['funderName']}}
| {{ item['acronym']?item['acronym']:item['title']}}
</mark>
</a>
</a>
<a *ngIf="item['inline']" href="{{item['url']}}">
<mark>
{{item['funderShortname']?item['funderShortname']:item['funderName']}}
| {{ item['acronym']?item['acronym']:item['title']}}
</mark>
</a>
</div>
</dd>
<dd *ngIf="showAllFundedBy">
<a class="text-muted" (click)="showAllFundedBy = !showAllFundedBy;">
View less
</a>
</dd>
<dd *ngIf="!showAllFundedBy && publicationInfo.fundedByProjects.length > 5">
<a class="text-muted" (click)="showAllFundedBy = !showAllFundedBy;">
View more
</a>
</dd>
</dl>

View File

@ -15,6 +15,11 @@ import {InlineClaimResultComponent} from '../../claimPages/inlineClaims/inlineCl
})
export class PublicationComponent {
private showAllCollectedFrom: boolean = false;
private showAllDownloadFrom: boolean = false;
private showAllFundedBy: boolean = false;
private showAllPublishedIn: boolean = false;
constructor (private _publicationService: PublicationService, private route: ActivatedRoute) {
}

View File

@ -15,6 +15,7 @@ import {SearchAllComponent} from '../searchAll/searchAll.component';//helpers
import {SearchPageComponent} from './searchUtils/searchPage.component';
import {SearchFormComponent} from './searchUtils/searchForm.component';
import {SearchPagingComponent} from './searchUtils/searchPaging.component';
import {SearchDownloadComponent} from './searchUtils/searchDownload.component';
import {SearchResultComponent} from './searchUtils/searchResult.component';
import {SearchFilterComponent} from './searchUtils/searchFilter.component';
@ -55,6 +56,7 @@ import { AdvancedSearchOrganizationsComponent } from './advanced/advancedSearchO
SearchResultComponent,
SearchFilterComponent,
SearchPagingComponent,
SearchDownloadComponent,
AdvancedSearchFormComponent,
SearchPublicationsComponent,
AdvancedSearchPublicationsComponent, AdvancedSearchDataProvidersComponent, AdvancedSearchProjectsComponent,

View File

@ -7,17 +7,19 @@ import {SearchResult} from '../utils/entities/searchResult';
import {OpenaireProperties, ErrorCodes} from '../utils/properties/openaireProperties';
import {SearchFields} from '../utils/properties/searchFields';
import {SearchPageComponent } from './searchUtils/searchPage.component';
import {ExportCSVComponent} from '../utils/exportCSV.component';
@Component({
selector: 'search-dataproviders',
template: `
<search-page pageTitle="Search Dataproviders" type="datasource" [(filters)] = "filters"
[(results)] = "results" [(totalResults)] = "totalResults" [(keyword)] = "keyword"
[(page)] = "page" [(size)] = "size" [(status)] = "status" [baseUrl] = "baseUrl" (queryChange)="queryChanged($event)" >
[(page)] = "page" [(size)] = "size" [(status)] = "status" [baseUrl] = "baseUrl"
(queryChange)="queryChanged($event)" (downloadClick)="downloadClicked($event)">
</search-page>
`
})
export class SearchDataprovidersComponent {
public results =[];
@ -34,6 +36,10 @@ export class SearchDataprovidersComponent {
private refineFields: string[] = this.searchFields.DATAPROVIDER_INDEX;
private indexIdsMap: { [key:string]:string } = this.searchFields.DATAPROVIDER_INDEX_PARAM_MAP;
private fieldIdsMap: { [key:string]:{ name:string, operator:string, type:string, indexField:string }} = this.searchFields.DATAPROVIDER_FIELDS_MAP;
private CSV: any = { "columnNames": [ "Title", "Type", "Coutries", "Compatibility" ],
"export":[]
};
private CSVDownloaded = false;
@ViewChild (SearchPageComponent) searchPage : SearchPageComponent ;
@ -224,4 +230,51 @@ public getResultsForDeposit(id:string, type:string, page: number, size: number){
this._getResults(parameters, true, this.page, this.size);
}
private downloadClicked($event) {
if(!this.CSVDownloaded) {
this.CSVDownloaded = false;
var parameters = $event.value;
//this.getResultsCSV(parameters, false, 1, 1000);
this._searchDataprovidersService.searchDataprovidersCSV(parameters, this.searchPage.getRefineFieldsQuery(), 1, 1000).subscribe(
data => {
this.CSV.export = data;
ExportCSVComponent.downloadCSV(this.CSV, "dataproviders.csv");
var errorCodes:ErrorCodes = new ErrorCodes();
this.status = errorCodes.DONE;
if(this.totalResults == 0 ){
this.status = errorCodes.NONE;
}
},
err => {
console.error(err);
//TODO check erros (service not available, bad request)
// if( ){
// this.status = ErrorCodes.ERROR;
// }
var errorCodes:ErrorCodes = new ErrorCodes();
this.status = errorCodes.ERROR;
}
);
/*
this.CSV.export.push(
[
this.quote(project.name),
this.quote(project.acronym),
this.quote(project.code),
this.quote(project.funder),
this.quote(project.fundingStream),
this.quote(project.fundingLevel1),
this.quote(project.fundingLevel2),
this.quote(project.sc39),
this.quote(project.startDate),
this.quote(project.endDate)
]);
}*/
}
}
}

View File

@ -0,0 +1,56 @@
import {Component, Input, Output, EventEmitter, ViewChild} from '@angular/core';
import {Observable} from 'rxjs/Observable';
import {AlertModal} from '../../utils/modal/alert';
@Component({
selector: 'search-download',
template: `
<div class= "searchDownload">
<div class="text-right" *ngIf="totalResults <= 100000">
<a (click)="download()">Download report (CSV)</a>
</div>
<div class="text-right" *ngIf="totalResults > 100000">
<a (click)="denialOfDownload()">
<span class="glyphicon glyphicon-download" aria-hidden="true"></span>
Download report (CSV)
</a>
</div>
</div>
<modal-alert></modal-alert>
`
})
export class SearchDownloadComponent {
@Input() totalResults:number = 0;
@ViewChild(AlertModal) alertApplyAll;
@Output() downloadClick = new EventEmitter();
constructor () {
}
ngOnInit() {
}
confirmClose(data){
}
download() {
this.downloadClick.emit({
value: true
});
}
denialOfDownload() {
this.alertApplyAll.isOpen = true;
this.alertApplyAll.cancelButton = true;
this.alertApplyAll.okButton = false;
this.alertApplyAll.alertTitle = "Download Results in CSV";
this.alertApplyAll.message = "Sorry, but the results are too many! Use the api instead!";
this.alertApplyAll.cancelButtonText = "Ok";
console.info("denial of Download");
}
}

View File

@ -24,6 +24,7 @@ import {SearchFields} from '../../utils/properties/searchFields';
<div class="col-xs-6 col-sm-9 sidebar-offcanvas" id="sidebar">
<search-form [(keyword)]="keyword" (keywordChange)="keywordChanged($event)"></search-form>
<search-download [totalResults]="totalResults" (downloadClick)="downloadClicked($event)"></search-download>
<search-paging [(page)] = "page" [(size)] = "size" [(results)] = "results" [(baseUrl)] = "baseURLWithParameters" [(totalResults)] = "totalResults" ></search-paging>
<search-result [results]="results" [totalResults]="totalResults" [status]=status [page]="page"></search-result>
</div>
@ -51,6 +52,7 @@ export class SearchPageComponent {
@Input() totalResults: number = 0;
@Input() keyword: string = '';
@Output() queryChange = new EventEmitter();
@Output() downloadClick = new EventEmitter();
@Input() baseUrl:string = '';
@Input() showResultCount:boolean = true;
@Input() showRefine:boolean = true;
@ -273,6 +275,17 @@ export class SearchPageComponent {
this.keyword = $event.value;
this.goTo(1);
}
downloadClicked($event) {
if($event.value == true) {
var queryParameters = this.createSearchQueryParameters(this.filters);
this.downloadClick.emit({
value: queryParameters
});
}
}
/*
* Get A sub-array of this.refineFields array, which contains the ids of the selected filters
*/

View File

@ -95,6 +95,7 @@ export class DataProviderService {
if(mydata['to'].class == "provides" && mydata['to'].type == "organization") {
if(this.dataProviderInfo.organizations == undefined) {
this.dataProviderInfo.organizations = new Array<{"name": string, "url": string}>();
this.dataProviderInfo.countries = new Set<string>();
}
this.dataProviderInfo.organizations[counter] = {"name": "", "url": ""};

View File

@ -82,6 +82,26 @@ export class SearchDataprovidersService {
.map(res => [res['meta'].total, this.parseResults(res['results'])]);
}
searchDataprovidersCSV (params: string, refineParams:string, page: number, size: number):any {
let link = OpenaireProperties.getSearchAPIURL()+"datasources";
let url = link+"?";
if(params!= null && params != '' ) {
url += params;
}
if(refineParams!= null && refineParams != '' ) {
url += refineParams;
}
url += "&page="+page+"&size="+size;
return this.http.get(url)
.map(res => <any> res.json())
//.do(res => console.info(res))
.map(res => this.parseResultsCSV(res['results']));
}
parseResults(data: any): SearchResult[] {
let results: SearchResult[] = [];
@ -143,6 +163,64 @@ export class SearchDataprovidersService {
return results;
}
parseResultsCSV(data: any): any {
let results: any = [];
let length = Array.isArray(data) ? data.length : 1;
for(let i=0; i<length; i++) {
let resData = Array.isArray(data) ? data[i]['result']['metadata']['oaf:entity']['oaf:datasource'] : data['result']['metadata']['oaf:entity']['oaf:datasource'];
var result: any = [];
result.push(this.quote(resData.officialname));
if(resData['datasourcetype'].hasOwnProperty("classname")) {
result.push(this.quote(resData['datasourcetype'].classname));
} else {
result.push('');
}
if(resData['rels'].hasOwnProperty("rel")) {
let countries = [];
let countriesSet: Set<string> = new Set<string>();
let relLength = Array.isArray(resData['rels']['rel']) ? resData['rels']['rel'].length : 1;
for(let i=0; i<relLength; i++) {
let relation = Array.isArray(resData['rels']['rel']) ? resData['rels']['rel'][i] : resData['rels']['rel'];
if(relation.hasOwnProperty("to")) {
if(relation['to'].class == "provides" && relation['to'].type == "organization") {
if(relation.hasOwnProperty('country') &&
relation.country.hasOwnProperty('classname')) {
if(!countriesSet.has(relation.country.classname)) {
countriesSet.add(relation.country.classname);
countries.push(relation.country.classname);
}
}
}
}
}
result.push(this.quote(countries));
} else {
result.push('');
}
if(resData.hasOwnProperty('openairecompatibility')) {
result.push(this.quote(resData['openairecompatibility'].classname));
} else {
result.push('');
}
results.push(result);
}
return results;
}
numOfDataproviders(params: string):any {
console.info("getOfDataproviders : Dataproviders Service + params="+params);
@ -154,4 +232,8 @@ export class SearchDataprovidersService {
.map(res => <any> res.json())
.map(res => res.total);
}
private quote(word: any): string {
return '"'+word+'"';
}
}

View File

@ -3,6 +3,7 @@ export class DataProviderInfo {
type: string;
compatibility: string;
oaiPmhURL: string;
countries: Set<string>;
tabs: {"name": string, "content": string}[];
tabsInTypes = {
"publicationsTab": new Set<string>(