diff --git a/searchPages/searchUtils/newSearchPage.component.ts b/searchPages/searchUtils/newSearchPage.component.ts index cb00309b..d13f5528 100644 --- a/searchPages/searchUtils/newSearchPage.component.ts +++ b/searchPages/searchUtils/newSearchPage.component.ts @@ -166,7 +166,7 @@ export class NewSearchPageComponent { this.basicMetaDescription.push(this.pageTitle) } } - console.log("title " + this.pageTitle, this.basicMetaDescription) + // console.log("title " + this.pageTitle, this.basicMetaDescription) this.updateMeta(this.pageTitle); }); this.searchUtils.baseUrl = "/" + this.searchUtils.baseUrl; @@ -231,7 +231,7 @@ export class NewSearchPageComponent { if(value.selected) { filterArray.push(filterName + '"' + value.name + '"'); filtervalues.push(value.name); - filterURL += ((filterName.length == 0) ? ',' : '') + StringUtils.URIEncode('"' + value.id + '"' ); + filterURL += ((filterName.length == 0) ? ',' : '') + StringUtils.URIEncode( '"' + StringUtils.URIEncode( value.id ) + '"'); filterName = ""; } @@ -244,8 +244,15 @@ export class NewSearchPageComponent { this._meta.updateTag({content: this.metaDescription}, "name='description'"); this._meta.updateTag({content: this.metaDescription}, "property='og:description'"); this.updateTitle(title, (nonCanonicalizedPage ? filtervalues.join(" | ") + " | ": "")); - this.url = this.properties.domain + this.properties.baseLink + this.router.url.split('?')[0] + (nonCanonicalizedPage ? filterURL : ""); - this.seoService.createLinkForCanonicalURL(this.url, true); + filterURL = (nonCanonicalizedPage ? filterURL : ""); + this.url = this.properties.domain + this.properties.baseLink + this.router.url.split('?')[0] + filterURL; + this.seoService.createLinkForCanonicalURL(this.url + (this.searchUtils.page !=1?(filterURL.length > 0?'&':'?')+'page='+this.searchUtils.page:''), true); + this.seoService.createLinkForNextURL(this.url + (filterURL.length > 0 ? '&' : '?') + 'page=' + (this.searchUtils.page + 1), true); + if(this.searchUtils.page != 1) { + this.seoService.createLinkForPrevURL(this.url + (this.searchUtils.page !=2?(filterURL.length > 0?'&':'?')+'page='+(this.searchUtils.page - 1):'') , true); + }else{ + this.seoService.removeLinkForPrevURL(); + } } updateTitle(title: string, filters:string) { @@ -277,9 +284,9 @@ export class NewSearchPageComponent { this.rangeFilters[i].selectedToValue = null; } this.selectedRangeFilters = 0; - if (this.quickFilter) { - this.removeValueFromQuickFilter(); - } + // if (this.quickFilter) { + // this.removeValueFromQuickFilter(); + // } if(this.resultTypes) { this.resultTypes.values = []; } @@ -427,23 +434,23 @@ export class NewSearchPageComponent { if(this.customFilter){ this.customFilter.selected = this.customFilter.queryFieldName == filter.filterId && values.indexOf(StringUtils.quote(this.customFilter.valueId)) != -1; } - } else if (this.quickFilter && this.quickFilter.filterId == filter.filterId && this.quickFilter.selected) { - for (let filterValue of filter.values) { - if (filterValue.id == this.quickFilter.value) { - filterValue.selected = true; - filter.countSelectedValues++; - } else { - filterValue.selected = false; - } - } + // } else if (this.quickFilter && this.quickFilter.filterId == filter.filterId && this.quickFilter.selected) { + // for (let filterValue of filter.values) { + // if (filterValue.id == this.quickFilter.value) { + // filterValue.selected = true; + // filter.countSelectedValues++; + // } else { + // filterValue.selected = false; + // } + // } } else { for (let filterValue of filter.values) { filterValue.selected = false; } } - if (this.quickFilter && filter.filterId == this.quickFilter.filterId) { - this.quickFilter.filter = filter; - } + // if (this.quickFilter && filter.filterId == this.quickFilter.filterId) { + // this.quickFilter.filter = filter; + // } } if (this.parameterNames.indexOf("cf") != -1 && this.parameterValues[this.parameterNames.indexOf("cf")] == "true") { this.customFilter.selected = true; @@ -610,9 +617,9 @@ export class NewSearchPageComponent { if(filter.filterType == "radio"){ filter.radioValue = ""; } - if (this.quickFilter && this.quickFilter.filterId == filter.filterId) { - this.removeValueFromQuickFilter(); - } + // if (this.quickFilter && this.quickFilter.filterId == filter.filterId) { + // this.removeValueFromQuickFilter(); + // } this.goTo(1); } public openRemoveCustomFilterModal() { @@ -648,9 +655,9 @@ export class NewSearchPageComponent { } filterChanged($event) { - if (this.quickFilter && this.quickFilter.filter) { +/* if (this.quickFilter && this.quickFilter.filter) { this.removeValueFromQuickFilter(); - } + }*/ this.goTo(1); } @@ -658,7 +665,7 @@ export class NewSearchPageComponent { /** * if there is a change in the values of the quick filter, this function has to be run, to also update the quickFilter */ - removeValueFromQuickFilter() { +/* removeValueFromQuickFilter() { if (this.quickFilter.filter.countSelectedValues == 0) { this.quickFilter.selected = false; } else { @@ -668,7 +675,7 @@ export class NewSearchPageComponent { } this.quickFilter.selected = (isQuickEnabled && this.quickFilter.filter.countSelectedValues == 1); } - } + }*/ /** * Set selected the value of the custom filter. @@ -1031,7 +1038,7 @@ export class NewSearchPageComponent { allFqs += "&fq=" + StringUtils.URIEncode(this.customFilter.queryFieldName + " exact " + StringUtils.quote((this.customFilter.valueId))); } - if (this.quickFilter && this.entityType == "result") { +/* if (this.quickFilter && this.entityType == "result") { if((URLparams[this.quickFilter.filterId] == undefined && URLparams["qf"] == undefined) || URLparams["qf"] == "true" || ((URLparams[this.quickFilter.filterId] != undefined && StringUtils.URIDecode(URLparams[this.quickFilter.filterId]).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/, -1).indexOf(StringUtils.quote(this.quickFilter.value)) != -1))) { this.quickFilter.selected = true; @@ -1043,7 +1050,7 @@ export class NewSearchPageComponent { // ||( URLparams[this.quickFilter.filterId] == undefined && URLparams["qf"] == "true")) { allFqs += "&fq=resultbestaccessright exact " + StringUtils.quote(this.quickFilter.value); } - } + }*/ if (this.entityType == "result") { if (URLparams["type"]) { @@ -1264,9 +1271,11 @@ public static createRangeFilterQuery(rangeField,selectedFromValue, selectedToVal this.parameterValues.splice(0, this.parameterValues.length); for (var i = 0; i < this.selectedFields.length; i++) { //default operator is and - this.parameterNames.push("f"+i); - this.parameterValues.push(this.selectedFields[i].id + (this.selectedFields[i].operatorId!='and'?(","+this.selectedFields[i].operatorId):'')); - this.parameterNames.push("fv"+i); + if((this.selectedFields[i].value && this.selectedFields[i].value.length > 0) || this.selectedFields[i].type == "date") { + this.parameterNames.push("f" + i); + this.parameterValues.push(this.selectedFields[i].id + (this.selectedFields[i].operatorId != 'and' ? ("," + this.selectedFields[i].operatorId) : '')); + this.parameterNames.push("fv" + i); + } if (this.selectedFields[i].type == "date") { if (this.selectedFields[i].dateValue.type == "range") { @@ -1275,29 +1284,48 @@ public static createRangeFilterQuery(rangeField,selectedFromValue, selectedToVal this.parameterValues.push(StringUtils.URIEncode(this.selectedFields[i].dateValue.type)); } - } else { + } else if(this.selectedFields[i].value && this.selectedFields[i].value.length > 0) { // console.log(this.selectedFields[i].value +" " + StringUtils.URIEncode(this.selectedFields[i].value)) this.parameterValues.push(StringUtils.URIEncode(this.selectedFields[i].value)); } } - if (includePage) { + if (includePage && this.searchUtils.page != 1) { this.parameterNames.push("page"); this.parameterValues.push("" + this.searchUtils.page); } //if (this.searchUtils.size != this.resultsPerPage) { - if (this.resultsPerPageChanged) { + if (this.resultsPerPageChanged && this.searchUtils.size != this.resultsPerPageChanged) { this.parameterNames.push("size"); //this.parameterValues.push("" + this.searchUtils.size); this.parameterValues.push("" + this.resultsPerPageChanged); } //if (this.sort && this.searchUtils.sortBy) { - if (this.sort && this.sortByChanged) { + if (this.sort && this.sortedByChanged && this.sortedByChanged.length > 0) { this.parameterNames.push("sortBy"); //this.parameterValues.push(this.searchUtils.sortBy); this.parameterValues.push(this.sortedByChanged); } + if (this.resultTypes && (this.entityType == 'publication' || this.entityType == 'dataset' || this.entityType == 'software' || this.entityType == 'other' || this.entityType == "result")) { + let values = []; + for(let value of this.resultTypes.values){ + if(value.selected) { + values.push(value.id); + } + } + this.selectedTypesNum = 0; + if (values.length > 0 && values.length != 4) { + this.parameterNames.push("type"); + this.parameterValues.push(values.join(",")); + this.selectedTypesNum = values.length; + } + // + /* if(this.quickFilter) { + this.parameterNames.push("qf"); + this.parameterValues.push("" + this.quickFilter.selected); + }*/ + } for (let filter of filters) { var filterLimits = ""; if (filter.countSelectedValues > 0) { @@ -1337,24 +1365,7 @@ public static createRangeFilterQuery(rangeField,selectedFromValue, selectedToVal this.parameterValues.push(this.searchUtils.keyword); } - if (this.resultTypes && (this.entityType == 'publication' || this.entityType == 'dataset' || this.entityType == 'software' || this.entityType == 'other' || this.entityType == "result")) { - let values = []; - for(let value of this.resultTypes.values){ - if(value.selected) { - values.push(value.id); - } - } - this.selectedTypesNum = 0; - if (values.length > 0 && values.length != 4) { - this.parameterNames.push("type"); - this.parameterValues.push(values.join(",")); - this.selectedTypesNum = values.length; - } - if(this.quickFilter) { - this.parameterNames.push("qf"); - this.parameterValues.push("" + this.quickFilter.selected); - } - } + if(this.customFilterEnabled){ this.parameterNames.push("cf"); this.parameterValues.push("true"); @@ -1404,7 +1415,7 @@ public static createRangeFilterQuery(rangeField,selectedFromValue, selectedToVal } } - if (this.quickFilter) { +/* if (this.quickFilter) { if (this.entityType == "result" && (URLparams[this.quickFilter.filterId] == undefined) && (URLparams["qf"] == undefined || URLparams["qf"] == "true")) { let filter = new Filter(); filter.title = fields.getFieldName(this.quickFilter.filterId, this.entityType); @@ -1419,7 +1430,7 @@ public static createRangeFilterQuery(rangeField,selectedFromValue, selectedToVal filter.countSelectedValues = 1; filters.push(filter) } - } + }*/ if ((this.entityType == 'publication' || this.entityType == 'dataset' || this.entityType == 'software' || this.entityType == 'other' || this.entityType == "result")) { this.resultTypes = {values:[],filterId:"type", countSelectedValues: 0, filterType: 'checkbox', originalFilterId: "", valueIsExact: true, title: "Result Types",filterOperator:"or"}; if (URLparams["type"]) { diff --git a/searchPages/searchUtils/searchFilter.component.ts b/searchPages/searchUtils/searchFilter.component.ts index ac271bb4..9d48cf73 100644 --- a/searchPages/searchUtils/searchFilter.component.ts +++ b/searchPages/searchUtils/searchFilter.component.ts @@ -10,6 +10,7 @@ import { import { Filter, Value} from './searchHelperClasses.class'; import {ActivatedRoute, Router} from "@angular/router"; import 'rxjs/add/operator/filter'; +import {SearchFields} from "../../utils/properties/searchFields"; @Component({ selector: 'search-filter', templateUrl: 'searchFilter.component.html' @@ -33,6 +34,7 @@ export class SearchFilterComponent implements OnInit, OnChanges{ keyword = ""; sortBy = "name"; queryParams = {}; + paramPosition = 0; @Input() actionRoute:boolean = false; @Input() quickFilter: { filter: Filter, selected: boolean, filterId: string, value: string }; sub; @@ -48,6 +50,7 @@ export class SearchFilterComponent implements OnInit, OnChanges{ ngOnInit() { this.sub = this.route.queryParams.subscribe(params => { this.queryParams = Object.assign({}, params); + this.paramPosition = SearchFields.getParameterOrder(this.filter.filterId, this.getEntries(params)); }); this.filter.values = this.filter.values.filter(value => !value.name.toLowerCase().includes('unknown') && !value.name.toLowerCase().includes('not available')); if(this.filter.filterType == "radio"){ @@ -243,12 +246,12 @@ export class SearchFilterComponent implements OnInit, OnChanges{ } getParams(filter:Filter, value:Value){ let params = Object.assign({}, this.queryParams); - let qf=false; +/* let qf=false; if(this.quickFilter && this.quickFilter.filterId == filter.filterId && this.quickFilter.selected && value.id == this.quickFilter.value){ params['qf']="false"; qf=true; - } - if(params[filter.filterId] && this.checkIfValueIndexOf(params[filter.filterId].split(','),value.id)==-1 && !qf) { + }*/ + if(params[filter.filterId] && this.checkIfValueIndexOf(params[filter.filterId].split(','),value.id)==-1 /*&& !qf*/) { //has other values of this filter --> add this value params[filter.filterId] = params[filter.filterId] + ',' + '"' + encodeURIComponent(value.id) + '"'; }else if(params[filter.filterId] && this.checkIfValueIndexOf(params[filter.filterId].split(','),value.id)!=-1) { @@ -260,9 +263,13 @@ export class SearchFilterComponent implements OnInit, OnChanges{ if(values.length == 0){ delete params[filter.filterId]; } - } else if(!qf){ + } else /*if(!qf)*/{ //has no filter, no value --> add the value - params[filter.filterId] = '"' + encodeURIComponent(value.id) + '"' ; + //check the order + let keyValues = this.getEntries(params); + keyValues.splice(this.paramPosition,0, [filter.filterId,'"' + encodeURIComponent(value.id) + '"']); // insert key value at paramPosition. + params = keyValues.reduce((o, key) => Object.assign(o, {[key[0]]:key[1]}), {}); + // params[filter.filterId] = '"' + encodeURIComponent(value.id) + '"' ; } delete params['page']; return params; @@ -277,4 +284,17 @@ export class SearchFilterComponent implements OnInit, OnChanges{ } return -1; } + getEntries(obj) { + if (!Object.entries) { + + var ownProps = Object.keys(obj), + i = ownProps.length, + resArray = new Array(i); // preallocate the Array + while (i--) + resArray[i] = [ownProps[i], obj[ownProps[i]]]; + return resArray; + }else{ + return Object.entries(obj); + } + } } diff --git a/sharedComponents/SEO/SEO.service.ts b/sharedComponents/SEO/SEO.service.ts index 4e38c75b..8543d17f 100644 --- a/sharedComponents/SEO/SEO.service.ts +++ b/sharedComponents/SEO/SEO.service.ts @@ -9,52 +9,88 @@ export class SEOService { @Inject(DOCUMENT) private document) { } - createLinkForCanonicalURL(url:string, addParameters:boolean=true) { - if(this.doc && (typeof this.doc.getElementById === "function" || typeof this.doc.createElement === "function") ){ - if(!addParameters && url && url.indexOf("?") != -1){ - url = url.substring(0,url.indexOf("?")); - } - if (typeof this.doc.getElementById === "function") { - let currentLink: HTMLLinkElement = this.doc.getElementById("relcan"); - if(currentLink ){ - currentLink.setAttribute('href', url); - return ; - } + createLinkForCanonicalURL(url:string, addParameters:boolean=true) { + this.createLink(url,"relcan", "canonical", addParameters) + } + createLinkForCanonicalSearchURL(url:string, addParameters:boolean=true, ) { + this.createLink(url,"relcan", "canonical", addParameters); + this.createLink(url,"relnext", "next", addParameters) + this.createLink(url,"relprev", "prev", addParameters) + } + createLinkForNextURL(url:string, addParameters:boolean=true) { + this.createLink(url,"relnext", "next", addParameters) + } + createLinkForPrevURL(url:string, addParameters:boolean=true) { + this.createLink(url,"relprev", "prev", addParameters) + } + + createLink(url:string, id:string, relname:string, addParameters:boolean=true) { + if(this.doc && (typeof this.doc.getElementById === "function" || typeof this.doc.createElement === "function") ){ + if(!addParameters && url && url.indexOf("?") != -1){ + url = url.substring(0,url.indexOf("?")); + } + if (typeof this.doc.getElementById === "function") { + let currentLink: HTMLLinkElement = this.doc.getElementById(id); + if(currentLink ){ + currentLink.setAttribute('href', url); + return ; } - if (typeof this.doc.createElement === "function") { - let link: HTMLLinkElement = this.doc.createElement('link'); - link.setAttribute('id', 'relcan'); - link.setAttribute('rel', 'canonical'); - this.doc.head.appendChild(link); - link.setAttribute('href', url); + } + if (typeof this.doc.createElement === "function") { + let link: HTMLLinkElement = this.doc.createElement('link'); + link.setAttribute('id', id); + link.setAttribute('rel', relname); + this.doc.head.appendChild(link); + link.setAttribute('href', url); + } + + }else{ + try { + const renderer = this.rendererFactory.createRenderer(this.document, { + id: '-1', + encapsulation: ViewEncapsulation.None, + styles: [], + data: {} + }); + + const link = renderer.createElement('link'); + const head = this.document.head; + + if (head === null) { + throw new Error(' not found within DOCUMENT.'); } + renderer.setAttribute(link, "rel", relname); + renderer.setAttribute(link, "href", (addParameters)?url:url.split("?")[0]); + renderer.setAttribute(link, "id", id); + // [TODO]: get them to update the existing one (if it exists) ? + renderer.appendChild(head, link); + } catch (e) { + console.error('Error within linkService : ', e); + } + } - }else{ - try { - const renderer = this.rendererFactory.createRenderer(this.document, { - id: '-1', - encapsulation: ViewEncapsulation.None, - styles: [], - data: {} - }); - - const link = renderer.createElement('link'); - const head = this.document.head; - - if (head === null) { - throw new Error(' not found within DOCUMENT.'); - } - renderer.setAttribute(link, "rel", "canonical"); - renderer.setAttribute(link, "href", (addParameters)?url:url.split("?")[0]); - renderer.setAttribute(link, "id", "relcan"); - // [TODO]: get them to update the existing one (if it exists) ? - renderer.appendChild(head, link); - } catch (e) { - console.error('Error within linkService : ', e); + } + removeLinkForNextURL() { + this.removeLink("relnext", "next"); + } + removeLinkForPrevURL() { + this.removeLink("relprev", "prev"); + } + removeLink( id:string, relname:string) { + if(this.doc && (typeof this.doc.getElementById === "function" || typeof this.doc.createElement === "function") ){ + if (typeof this.doc.getElementById === "function") { + let currentLink: HTMLLinkElement = this.doc.getElementById(id); + if(currentLink ){ + currentLink.setAttribute('href', ""); + currentLink.setAttribute('rel', ""); + return ; } } - } + + } + + } } diff --git a/timeout-interceptor.service.ts b/timeout-interceptor.service.ts index 0150af9e..87e67ef4 100644 --- a/timeout-interceptor.service.ts +++ b/timeout-interceptor.service.ts @@ -1,13 +1,14 @@ -import { Inject, Injectable, InjectionToken } from '@angular/core'; +import {Inject, Injectable, InjectionToken, PLATFORM_ID} from '@angular/core'; import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http'; import { Observable } from 'rxjs'; import { timeout } from 'rxjs/operators'; +import {isPlatformServer} from "@angular/common"; export const DEFAULT_TIMEOUT = new InjectionToken('defaultTimeout'); @Injectable() export class TimeoutInterceptor implements HttpInterceptor { - constructor(@Inject(DEFAULT_TIMEOUT) protected defaultTimeout: number) { + constructor(@Inject(DEFAULT_TIMEOUT) protected defaultTimeout: number, @Inject(PLATFORM_ID) private platformId: any) { } intercept(req: HttpRequest, next: HttpHandler): Observable> { @@ -15,9 +16,8 @@ export class TimeoutInterceptor implements HttpInterceptor { return next.handle(req); } - const timeoutValue = req.headers.get('timeout') || this.defaultTimeout; + const timeoutValue = isPlatformServer(this.platformId)?3000:6000;//req.headers.get('timeout') || this.defaultTimeout; const timeoutValueNumeric = Number(timeoutValue); - return next.handle(req).pipe(timeout(timeoutValueNumeric)); } } diff --git a/utils/properties/searchFields.ts b/utils/properties/searchFields.ts index 7d7a81e0..f726d23a 100644 --- a/utils/properties/searchFields.ts +++ b/utils/properties/searchFields.ts @@ -678,7 +678,30 @@ export class SearchFields { return "UNDEFINED"; } } - + public static getParameterOrder(fieldId: string, params): number { + let fields = []; + let searchFields = new SearchFields(); + if (searchFields.RESULT_REFINE_FIELDS.indexOf(fieldId) !=-1) { + fields = searchFields.RESULT_REFINE_FIELDS; + } else if (searchFields.PROJECT_REFINE_FIELDS.indexOf(fieldId) !=-1) { + fields = searchFields.PROJECT_REFINE_FIELDS + } else if (searchFields.ORGANIZATION_REFINE_FIELDS.indexOf(fieldId) !=-1) { + fields = searchFields.ORGANIZATION_REFINE_FIELDS; + } else if (searchFields.DATASOURCE_REFINE_FIELDS.indexOf(fieldId) !=-1) { + fields = searchFields.DATASOURCE_REFINE_FIELDS; + } + let index = fields.indexOf(fieldId); + let paramIndex = 0; + if(index != -1){ + for(let keyValue of params){ + if(fields.indexOf(keyValue[0])>index){ + break; + } + paramIndex++ + } + } + return paramIndex; + } /* AND Funder: relfunder, relfundinglevel0_id, relfundinglevel1_id, relfundinglevel2_id