import {Component, Input, ViewChild} from '@angular/core'; import {Output, EventEmitter} from '@angular/core'; import {Location} from '@angular/common'; import {ActivatedRoute, Router} from '@angular/router'; import {Title, Meta} from '@angular/platform-browser'; import {Observable} from 'rxjs/Observable'; import {Filter, Value, AdvancedField} from '../searchUtils/searchHelperClasses.class'; import {SearchResult} from '../../utils/entities/searchResult'; import {SearchFields, FieldDetails} from '../../utils/properties/searchFields'; import {SearchUtilsClass} from './searchUtils.class'; import {ModalLoading} from '../../utils/modal/loading.component'; import {StringUtils, Dates} from '../../utils/string-utils.class'; import {ErrorCodes} from '../../utils/properties/errorCodes'; import {RouterHelper} from '../../utils/routerHelper.class'; import {PiwikService} from '../../utils/piwik/piwik.service'; import {EnvProperties} from '../../utils/properties/env-properties'; import { SEOService } from '../../sharedComponents/SEO/SEO.service'; @Component({ selector: 'advanced-search-page', templateUrl: 'advancedSearchPage.component.html' }) export class AdvancedSearchPageComponent { @Input() piwikSiteId = null; @Input() pageTitle = ""; @Input() results = []; @Input() type; @Input() entityType; @Input() searchUtils:SearchUtilsClass = new SearchUtilsClass(); @Input() fieldIds: string[]; @Input() fieldIdsMap;//:{ [key:string]:{ name:string, operator:string, type:string, indexField:string, equalityOperator:string }} ; @Input() selectedFields:AdvancedField[]; @Input() simpleSearchUrl: string; @ViewChild (ModalLoading) loading : ModalLoading ; @Input() csvParams: string; @Input() csvPath: string; @Input() simpleSearchLink: string = ""; @Input() disableForms:boolean = false; @Input() loadPaging: boolean = true; @Input() oldTotalResults: number = 0; @Input() openaireLink: string; @Input() connectCommunityId: string; @Input() sort: boolean = false; @Input() searchFormClass: string = "searchForm"; piwiksub: any; public parameterNames:string[] =[]; public parameterValues:string[] =[]; public baseURLWithParameters:string = ''; public csvLimit: number = 0; public pagingLimit: number = 0; public resultsPerPage: number = 0; isPiwikEnabled = false; properties:EnvProperties; public routerHelper:RouterHelper = new RouterHelper(); public errorCodes:ErrorCodes = new ErrorCodes(); url = null; @Output() queryChange = new EventEmitter(); constructor (private route: ActivatedRoute, private location: Location, private _meta: Meta, private _title: Title, private _piwikService:PiwikService, private router: Router, private seoService: SEOService) { } ngOnInit() { this.route.data .subscribe((data: { envSpecific: EnvProperties }) => { this.properties = data.envSpecific; this.pagingLimit = data.envSpecific.pagingLimit; 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 } if(typeof document !== 'undefined' && this.isPiwikEnabled){ this.piwiksub = this._piwikService.trackView(this.properties, this.pageTitle, this.piwikSiteId).subscribe(); } }); var title = "Advanced search "+this.pageTitle; var description = "Openaire, search, repositories, open access, type, content provider, funder, project, "+ this.pageTitle; this.updateTitle(title); this.updateDescription(description); this.searchUtils.baseUrl = "/" + this.searchUtils.baseUrl; this.updateBaseUrlWithParameters(); this.seoService.createLinkForCanonicalURL(this.properties.baseLink+this.router.url,false); } ngOnDestroy() { if(this.piwiksub){ this.piwiksub.unsubscribe(); } } updateDescription(description:string) { this._meta.updateTag({content:description},"name='description'"); this._meta.updateTag({content:description},"property='og:description'"); } updateTitle(title:string) { var _prefix ="OpenAIRE | "; var _title = _prefix + ((title.length> 50 ) ?title.substring(0,50):title); this._title.setTitle(_title); this._meta.updateTag({content:_title},"property='og:title'"); } updateUrl(url:string) { this._meta.updateTag({content:url},"property='og:url'"); } public getSelectedFiltersFromUrl(params) { for(var i=0; i< this.fieldIds.length ; i++){ var fieldId = this.fieldIds[i]; var fieldparam = (this.fieldIdsMap[fieldId])?this.fieldIdsMap[fieldId].param:""; if(!this.fieldIdsMap[fieldId]){ console.error("Field: "+fieldId +" not found in fieldIds map"); } var operatorId = this.getOperatorParameter(fieldparam); if(params[fieldparam] != undefined && params[operatorId] != undefined) { var values:string [] = StringUtils.URIDecode(params[fieldparam]).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/,-1); var operators:string [] = (StringUtils.URIDecode(params[operatorId])).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/,-1); if(values.length == operators.length){ for(var j=0; j< values.length ; j++){ if(this.fieldIdsMap[fieldId].type == "date"){ var value:string =StringUtils.unquote(values[j]); var validDates:boolean = true; var dateField:AdvancedField = new AdvancedField(fieldId,fieldparam,this.fieldIdsMap[fieldId].name,this.fieldIdsMap[fieldId].type,value,operators[j]) ; if(value.indexOf("range") != -1){ dateField.dateValue.type="range"; if(value.length < 26 ){ validDates =false; }else{ if(!Dates.isValidDate(value.substring(5,15)) || !Dates.isValidDate(value.substring(16,26))){ validDates =false; }else { dateField.dateValue.from = Dates.getDateFromString(value.substring(5,15)); dateField.dateValue.to = Dates.getDateFromString(value.substring(16,26)); } } // "rangeYYYY-MM-DD:YYYY-MM-DD" }else{ dateField.dateValue.setDatesByType(value); } if(validDates){ this.selectedFields.push(dateField); } } else{ this.selectedFields.push(new AdvancedField(fieldId,fieldparam,this.fieldIdsMap[fieldId].name,this.fieldIdsMap[fieldId].type,StringUtils.unquote(values[j]),operators[j]) ); } } } } } if(this.selectedFields.length == 0){ this.selectedFields.push(new AdvancedField(this.fieldIds[0],fieldparam,this.fieldIdsMap[this.fieldIds[0]].name,this.fieldIdsMap[this.fieldIds[0]].type,"","and")); } } private createUrlParameters(includePage:boolean){ var params=""; this.parameterNames.splice(0,this.parameterNames.length); this.parameterValues.splice(0,this.parameterValues.length); var fields: { [key:string]:{ values:string[], operators:string[] }}={}; for(var i = 0; i< this.selectedFields.length; i++){ if(this.fieldIdsMap[this.selectedFields[i].id] != undefined && (this.selectedFields[i].value.length > 0 || this.selectedFields[i].type == "date" )){ if(!fields[this.selectedFields[i].id]){ fields[this.selectedFields[i].id] = {values:[], operators:[]}; fields[this.selectedFields[i].id].values =[]; fields[this.selectedFields[i].id].operators =[]; } if(this.selectedFields[i].type == "date"){ if(this.selectedFields[i].dateValue.type == "range"){ fields[this.selectedFields[i].id].values.push(StringUtils.quote(StringUtils.URIEncode("range"+Dates.getDateToString(this.selectedFields[i].dateValue.from)+":"+Dates.getDateToString(this.selectedFields[i].dateValue.to)))); }else{ fields[this.selectedFields[i].id].values.push(StringUtils.quote(StringUtils.URIEncode(this.selectedFields[i].dateValue.type))); } }else{ fields[this.selectedFields[i].id].values.push(StringUtils.quote(StringUtils.URIEncode(this.selectedFields[i].value))); } fields[this.selectedFields[i].id].operators.push(this.selectedFields[i].operatorId); } } for(var i = 0; i< this.fieldIds.length; i++){ if(fields[this.fieldIds[i]]){ params+="&"+this.fieldIdsMap[this.fieldIds[i]].param+"="+fields[this.fieldIds[i]].values.join()+ "&"+ this.fieldIdsMap[this.fieldIds[i]].operator+"="+fields[this.fieldIds[i]].operators.join() this.parameterNames.push(this.fieldIdsMap[this.fieldIds[i]].param); this.parameterValues.push(fields[this.fieldIds[i]].values.join()); this.parameterNames.push( this.fieldIdsMap[this.fieldIds[i]].operator); this.parameterValues.push(fields[this.fieldIds[i]].operators.join()); } } if(includePage && this.searchUtils.page != 1){ params += "&page="+this.searchUtils.page; } if(this.searchUtils.size != 10) { params+=((params.length == 0)?'':'&') + 'size=' + this.searchUtils.size; this.parameterNames.push("size"); this.parameterValues.push(""+this.searchUtils.size); } if(this.sort && this.searchUtils.sortBy) { params+=((params.length == 0)?'':'&') + 'sortBy=' + this.searchUtils.sortBy; this.parameterNames.push("sortBy"); this.parameterValues.push(this.searchUtils.sortBy); } return '?'+params; } public createQueryParameters(){ var params=""; var countParams = 0; for(var i = 0; i< this.selectedFields.length; i++){ if(this.fieldIdsMap[this.selectedFields[i].id] != undefined && (this.selectedFields[i].value != "" ||this.selectedFields[i].type == "date")){ //console.log("createQueryParameters::"+this.selectedFields[i].type); if(this.selectedFields[i].type == "date"){ if(this.selectedFields[i].dateValue.type != "any"){ params += (countParams == 0 ? "" : this.selectedFields[i].operatorId) + " " + this.selectedFields[i].id + this.fieldIdsMap[this.selectedFields[i].id].equalityOperator+ '"' + StringUtils.URIEncode(Dates.getDateToString(this.selectedFields[i].dateValue.from)) + " " + StringUtils.URIEncode(Dates.getDateToString(this.selectedFields[i].dateValue.to)) + '"' + " "; } }else{ if(this.selectedFields[i].id == "q"){ var op = ""; // if() params += (countParams == 0 ? "" : this.selectedFields[i].operatorId) + " " + '"' + StringUtils.URIEncode(this.selectedFields[i].value) + '"' + " "; }else if(countParams == 0 && this.selectedFields[i].operatorId == "not"){ params += " "+ this.selectedFields[i].id + " <> "+'"' + StringUtils.URIEncode(this.selectedFields[i].value) +'"' + " "; }else{ params += (countParams == 0 ? "" : this.selectedFields[i].operatorId + " " ) + this.selectedFields[i].id + this.fieldIdsMap[this.selectedFields[i].id].equalityOperator+'"' + encodeURIComponent(this.selectedFields[i].value) +'"' + " "; } } countParams++; } } //community if(this.connectCommunityId ){ params += (countParams == 0 ? "" : " and " ) + "communityId exact "+'"' + this.connectCommunityId +'"' + " "; } return params; } clearFilters(){ } goTo(page:number = 1){ this.searchUtils.page = page; var urlParameters = this.createUrlParameters(true); var queryParameters = this.createQueryParameters(); //this.location.go(location.pathname,urlParameters); this.router.navigate( [this.searchUtils.baseUrl], { queryParams: this.routerHelper.createQueryParams(this.parameterNames, this.parameterValues) } ); this.queryChange.emit({ value: queryParameters }); /* Code For Piwik*/ if (typeof localStorage !== 'undefined') { //console.log("In PreviousRouteRecorder : "+this.router.url ); localStorage.setItem('previousRoute', this.router.url); } if(this.isPiwikEnabled && (typeof document !== 'undefined')){ this.piwiksub = this._piwikService.trackView(this.properties, this.pageTitle, this.piwikSiteId).subscribe(); } /* End Piwik Code */ } queryChanged($event) { this.goTo(1); } pageChanged($event) { this.searchUtils.page = +$event.value; this.goTo(this.searchUtils.page); } sizeChanged($event) { this.searchUtils.size = $event.value; this.goTo(1); } sortByChanged($event) { this.searchUtils.sortBy = $event.value; this.goTo(1); } /* * Update the url with proper parameters. This is used as base url in Paging Component */ public updateBaseUrlWithParameters(){ this.baseURLWithParameters = this.searchUtils.baseUrl + this.createUrlParameters(false); } getOperatorParameter(parameter:string):string{ for (let id of this.fieldIds) { if(this.fieldIdsMap[id]["param"] == parameter){ return this.fieldIdsMap[id]["operator"]; } } } // for loading public openLoading(){ this.loading.open(); } public closeLoading(){ this.loading.close(); } }