[Library|Trunk]

JSONLD:
-Home page: 
-Add description in Website with search action
-In every search page add description based on the filters
-In (project, content provider, organization) landing add description if available otherwise use the title
-In project add id in funder entity

Autocomplete: create event emitter to update entity or refine result label (used in jsonld)

	


git-svn-id: https://svn.driver.research-infrastructures.eu/driver/dnet40/modules/uoa-services-library/trunk/ng-openaire-library/src/app@59152 d315682c-612b-4755-9ff5-7f18f6832af3
This commit is contained in:
argiro.kokogiannaki 2020-07-21 12:41:08 +00:00
parent 048e3b99b5
commit 3828670514
11 changed files with 117 additions and 35 deletions

View File

@ -23,7 +23,7 @@ import {Breadcrumb} from "../utils/breadcrumbs/breadcrumbs.component";
</div>
<div class="uk-container uk-container-large uk-margin-medium-top">
<div class="uk-grid-divider" uk-grid>
<div class="uk-grid-divider uk-grid" uk-grid>
<div class="uk-width-1-2@m uk-width-1-1@s">
<!-- <p class="uk-margin-auto uk-text-large">How to <span class="uk-text-bold">deposit</span> your research...</p>-->
<span class="uk-grid">
@ -136,7 +136,7 @@ import {Breadcrumb} from "../utils/breadcrumbs/breadcrumbs.component";
</div>
</div>
<div class="">
<schema2jsonld *ngIf="url" [URL]="url" [name]="title" type="other"></schema2jsonld>
<schema2jsonld *ngIf="url" [URL]="url" [name]="title" type="other" description=" Find the appropriate repository to deposit your research products of any type (publication, data, software, other) or to include in your data management plan. Search and browse for OpenAIRE compliant repositories registered in OpenDOAR and re3data. "></schema2jsonld>
<div class="uk-section tm-middle uk-container uk-container-large uk-margin-small-top uk-padding-remove-top uk-padding-remove-bottom ">
<div class="uk-container uk-container-large uk-margin-bottom uk-margin-medium-top">
<div class="uk-grid uk-padding">

View File

@ -31,7 +31,8 @@
</div>
</div>
<schema2jsonld *ngIf="name && logoURL" [URL]="properties.baseLink+'/search/find'"
[logoURL]="properties.baseLink+logoURL" type="search" [name]=name></schema2jsonld>
[logoURL]="properties.baseLink+logoURL" type="search" [name]=name
description="Search for research outcomes (publications, datasets, software, other research products), projects, organizations, content providers in the OpenAIRE Research Graph. "></schema2jsonld>
<div class="uk-container-large uk-container">
<ul class=" portalTabs uk-tab uk-width-1-1 " uk-tab="animation: uk-animation-fade">

View File

@ -63,7 +63,8 @@
[selectedValue]=selectedField.value [showSelected]=true
[placeHolderMessage]="'Search for '+selectedField.name" [title]="selectedField.name"
[multipleSelections]=false (selectedValueChanged)="valueChanged($event,i)"
(listUpdated)="listUpdated($event,selectedField.id)"></static-autocomplete>
(listUpdated)="listUpdated($event,selectedField.id)"
(updateValueLabel)="updatedValueLabel($event, i)"></static-autocomplete>
</td>
<td *ngIf="selectedField.type == 'entity'">
<entities-autocomplete [properties]=properties [fieldId]=selectedField.id [entityType]=selectedField.param
@ -71,7 +72,7 @@
[placeHolderMessage]="'Search for '+selectedField.name" [title]="selectedField.name"
[multipleSelections]=false
(selectedValueChanged)="valueChanged($event,i)"
(listUpdated)="listUpdated($event,selectedField.id)">
(updateValueLabel)="updatedValueLabel($event, i)">
</entities-autocomplete>
</td>
@ -98,14 +99,15 @@
<td class=" ">
<span type="button" class="uk-icon-button portal-button-reverse clickable "
(click)="removeField(i)">
<span uk-icon="minus"> </span>
<span class="uk-icon"><svg width="20" height="20" viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg" data-svg="minus"><rect height="1" width="18" y="9" x="1"></rect></svg></span>
</span>
<div *ngIf="i == selectedFields.length-1 " class="uk-margin-small-top">
<span type="button"
class="uk-icon-button portal-button clickable "
(click)="addField()">
<span uk-icon="plus">
</span>
<span class="uk-icon"><svg width="20" height="20" viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg" data-svg="plus"><rect x="9" y="1" width="1" height="17"></rect><rect x="1" y="9" width="17" height="1"></rect></svg></span>
</span>
</div>
</td>

View File

@ -150,6 +150,9 @@ export class AdvancedSearchFormComponent {
valueChanged($event,index:number){
this.selectedFields[index].value = $event.value;
}
updatedValueLabel($event,index:number){
this.selectedFields[index].valueLabel = $event.value;
}
listUpdated($event,fieldId:number){
this.fieldList[fieldId] = $event.value;
}

View File

@ -178,7 +178,7 @@
</div>
</div>
<schema2jsonld *ngIf="!includeOnlyResultsAndFilter && url" [URL]="url" type="search" [name]=pageTitle
[searchAction]=false></schema2jsonld>
[searchAction]=false [description]="metaDescription" ></schema2jsonld>
<div id="tm-main" class=" tm-middle">

View File

@ -57,7 +57,7 @@ export class NewSearchPageComponent {
@Input() rangeFilters: RangeFilter[] = [];
@Input() rangeFields: string[][] = [];
@Input() refineFields = [];
@Input() filters = [];
@Input() filters:Filter[] = [];
selectedFilters: number = 0;
selectedRangeFilters: number = 0;
private searchFieldsHelper: SearchFields = new SearchFields();
@ -101,7 +101,7 @@ export class NewSearchPageComponent {
public errorCodes: ErrorCodes = new ErrorCodes();
breadcrumbs:Breadcrumb[] = [];
url = null;
metaDescription = "";
@Input() entitiesSelection:boolean = true;
@Input() showAdvancedSearchLink:boolean = true;
@ -128,10 +128,8 @@ export class NewSearchPageComponent {
this.resultsPerPage = data.envSpecific.resultsPerPage;
this.csvLimit = data.envSpecific.csvLimit;
this.isPiwikEnabled = data.envSpecific.enablePiwikTrack;
if (typeof window !== 'undefined') {
this.updateUrl(data.envSpecific.baseLink + location.pathname);
this.url = data.envSpecific.baseLink + location.pathname
}
this.updateUrl(data.envSpecific.baseLink +this.router.url);
this.url = data.envSpecific.baseLink + this.router.url;
if (typeof document !== 'undefined' && this.isPiwikEnabled) {
this.piwiksub = this._piwikService.trackView(this.properties, this.pageTitle, this.piwikSiteId).subscribe();
}
@ -142,10 +140,10 @@ export class NewSearchPageComponent {
}
this.customFilterEnabled = params['cf'] && params['cf'] == "true";
});
var description = "Openaire, search, repositories, open access, type, content provider, funder, project, " + this.pageTitle;
this.metaDescription = this.pageTitle;
this.updateTitle(this.pageTitle);
this.updateDescription(description);
this.updateDescription();
this.searchUtils.baseUrl = "/" + this.searchUtils.baseUrl;
this.seoService.createLinkForCanonicalURL(this.properties.baseLink + this.router.url, false);
@ -179,9 +177,43 @@ export class NewSearchPageComponent {
}
}
updateDescription(description: string) {
this._meta.updateTag({content: description}, "name='description'");
this._meta.updateTag({content: description}, "property='og:description'");
updateDescription() {
this.metaDescription = "Search results for ";
if(this.resultTypes){
let array = [];
for(let type of this.resultTypeOptions){
if(this.resultTypes[type.id]== true){
array.push(type.name);
}
}
if(array.length == 0){
this.metaDescription += "research outcomes ";
}else{
this.metaDescription += array.join(", ") + " ";
}
}else{
this.metaDescription = this.pageTitle + " ";
}
let filterArray = [];
for(let filter of this.filters){
if(filter.countSelectedValues> 0){
for(let value of filter.values){
if(value.selected) {
filterArray.push(value.name);
}
}
}
}
for(let field of this.selectedFields){
if((field.type == "entity" || field.type == "refine") && field.valueLabel.length > 0 && filterArray.indexOf(field.valueLabel)==-1){
filterArray.push(field.valueLabel)
}else if(!(field.type == "entity" || field.type == "refine") && field.value.length > 0 && filterArray.indexOf(field.value)==-1) {
filterArray.push(field.value);
}
}
this.metaDescription+= (filterArray.length > 0?" filtered for: ":"") + filterArray.join(", ") + " ";
this._meta.updateTag({content: this.metaDescription}, "name='description'");
this._meta.updateTag({content: this.metaDescription}, "property='og:description'");
}
updateTitle(title: string) {
@ -375,6 +407,7 @@ export class NewSearchPageComponent {
}
}
this.filterFilterValues(this.filters);
this.updateDescription();
return filters;
}

View File

@ -25,6 +25,7 @@ export class AdvancedField{
public name: string; //
public type: string = "keyword"; //keyword, static or dynamic
public value: string = '';
public valueLabel: string = '';
public operatorId: string;
public operatorName: string ="";
public valid: boolean = true;

View File

@ -1,4 +1,4 @@
import {Component, Input} from '@angular/core';
import {Component, Input, OnChanges, OnInit, SimpleChanges} from '@angular/core';
import {OpenAireJsonldConverterService} from './service/open-aire-jsonld-converter.service';
import {JsonldDocumentSerializerService} from './service/jsonld-document-serializer.service';
@ -8,7 +8,7 @@ import {JsonldDocumentSerializerService} from './service/jsonld-document-seriali
<ngx-json-ld [json]="json"></ngx-json-ld>
`
})
export class Schema2jsonldComponent {
export class Schema2jsonldComponent implements OnInit, OnChanges {
@Input() data; // for project, organization, datasource
@Input() URL;
@Input() logoURL; // for home, search
@ -23,14 +23,22 @@ export class Schema2jsonldComponent {
private documentSerializer: JsonldDocumentSerializerService) {
}
ngOnChanges(changes: SimpleChanges): void {
if (changes.description) {
this.createJson();
}
}
ngOnInit() {
this.createJson();
}
createJson(){
var docOvject;
if (this.type == 'project') {
docOvject = this.documentParser.convertProject(this.data, this.URL, this.otherURL);
docOvject = this.documentParser.convertProject(this.data, this.URL);
this.json = this.documentSerializer.serializeOrganization(docOvject);
} else if (this.type == 'organization') {
docOvject = this.documentParser.convertOrganization(this.data, this.URL);
docOvject = this.documentParser.convertOrganization(this.data, this.URL, this.description);
this.json = this.documentSerializer.serializeOrganization(docOvject);
} else if (this.type == 'datasource') {
docOvject = this.documentParser.convertDatasource(this.data, this.URL, this.otherURL);

View File

@ -36,6 +36,9 @@ export class OpenAireJsonldConverterService {
searchPage["name"] = name;
searchPage["url"] = properties.baseLink+"/search/find/";
searchPage["logo"] = logoURL;
if(description){
searchPage["description"] = description;
}
const action ={};
action["@type"]= "SearchAction";
action["@id"]= properties.baseLink+"/#search-action";
@ -53,7 +56,10 @@ export class OpenAireJsonldConverterService {
buffer["url"] = URL;
if(description){
buffer["description"] = description;
} buffer["@id"] = URL;
}else{
buffer["description"] = name;
}
buffer["@id"] = URL;
return buffer;
}
createSearchPage(name, URL, logoURL, searchAction:boolean = true, description:string = null): any {
@ -88,7 +94,7 @@ export class OpenAireJsonldConverterService {
doc.issn = this.getISSN(result);
doc.description = this.getDescription(result);
doc.identifier = this.getIdentifier(result);
doc.id = URL
doc.id = URL;
doc.url = URL;
doc.sameAs = this.getSameAs(result);
doc.creator = this.getCreator(result);
@ -99,40 +105,50 @@ export class OpenAireJsonldConverterService {
return doc;
}
convertProject(project: any, URL, otherUrl): Organization {
convertProject(project: any, URL): Organization {
const doc = new Organization();
doc.title = (project.title)?project.title:project.acronym;
doc.identifier = new Array<Identifier>();
doc.identifier.push({id:project.funding.code, schema: "grantid"});
var funder = new Organization();
funder.title = project.funding.funderShortName;
let funder = new Organization();
funder.id = properties.baseLink+"#funder-"+project.funding.funderShortName;
funder.title = project.funding.funderName;
doc.funder = funder;
doc.url = URL;
doc.id = URL;
doc["description"] = [];
doc["description"].push((project.title)?project.title:project.acronym);
doc.sameAs =[project.url];
return doc;
}
convertOrganization(organization: any, URL): Organization {
convertOrganization(organization: any, URL, description:string = null): Organization {
const doc = new Organization();
doc.title = organization.title.name ;
doc.legalName = organization.name;
doc.areaServed = organization.country;
doc.url = URL;
doc.id = URL;
doc["description"] = [];
doc["description"].push(((organization.title.name?organization.title.name:"") + " - " + (organization.name?organization.name:"")));
return doc;
}
convertDatasource(datasource: any, URL, otherUrl): Organization {
const doc = new Organization();
doc.title = datasource.title.name;
doc.title = datasource.title.name?datasource.title.name:datasource.officialName;
//doc.identifier = datasource.contractNum;
doc.legalName = datasource.officialName;
if(datasource.countries && datasource.countries.length > 0){
doc.areaServed = datasource.countries[0];
}
doc.url = URL;
doc.id = URL;
doc["description"] = [];
doc["description"].push(datasource.description?datasource.description:datasource.title.name?datasource.title.name:datasource.officialName);
if(datasource.oaiPmhURL || otherUrl || datasource.title.url){
doc.sameAs = [];
if(otherUrl){

View File

@ -56,6 +56,7 @@ export class EntitiesAutocompleteComponent {
@Input() title = "Autocomplete";
@Output() addItem = new EventEmitter(); // when selected list changes update parent component
@Output() selectedValueChanged = new EventEmitter(); // when changed a method for filtering will be called
@Output() updateValueLabel = new EventEmitter(); //when the value is id sends an event to update the value (for meta tags)
@Input() public list = []; // the entries resulted after filtering function
@Input() public selected = []; // the entries selected from user
@Input() public keywordlimit = 3; // the minimum length of keyword
@ -181,6 +182,9 @@ export class EntitiesAutocompleteComponent {
this.selectedValueChanged.emit({
value: this.selectedValue
});
this.updateValueLabel.emit({
value:""
});
}
@ -213,6 +217,9 @@ export class EntitiesAutocompleteComponent {
this.selectedValueChanged.emit({
value: this.selectedValue
});
this.updateValueLabel.emit({
value:this.showItem(item)
});
this.focus=false;
}
@ -267,6 +274,9 @@ export class EntitiesAutocompleteComponent {
this.sub = this._search.fetchByType(this.selectedValue,this.entityType, this.properties).subscribe(
data => {
this.selected.push( data[0]);
this.updateValueLabel.emit({
value:this.showItem(this.selected[0])
});
this.showInput = false;
},
err => {

View File

@ -46,6 +46,7 @@ export class StaticAutoCompleteComponent implements OnChanges{
@Input() title = "Autocomplete";
@Output() addItem = new EventEmitter(); // when selected list changes update parent component
@Output() selectedValueChanged = new EventEmitter(); // when changed a method for filtering will be called
@Output() updateValueLabel = new EventEmitter(); //when the value is id sends an event to update the value (for meta tags)
@Output() listUpdated = new EventEmitter(); // when changed a method for filtering will be called
@Input() public list = []; // the entries resulted after filtering function
@Input() public filtered = []; // the entries resulted after filtering function
@ -197,7 +198,9 @@ export class StaticAutoCompleteComponent implements OnChanges{
this.selectedValueChanged.emit({
value: this.selectedValue
});
this.updateValueLabel.emit({
value:""
});
}
}
@ -229,7 +232,9 @@ export class StaticAutoCompleteComponent implements OnChanges{
this.selectedValueChanged.emit({
value: this.selectedValue
});
this.updateValueLabel.emit({
value:this.showItem(item)
});
}
}
@ -279,6 +284,9 @@ export class StaticAutoCompleteComponent implements OnChanges{
this.selectedValue = this.list[i].label;
this.selected.push(this.list[i]);
this.showInput = false;
this.updateValueLabel.emit({
value:this.showItem(this.list[i])
});
return;
}