import {Component, EventEmitter, Input, Output, ViewChild} from '@angular/core'; import {Location} from '@angular/common'; import {ActivatedRoute, Router} from '@angular/router'; import {Meta, Title} from '@angular/platform-browser'; import {AdvancedField} from '../searchUtils/searchHelperClasses.class'; import {SearchCustomFilter, SearchUtilsClass} from './searchUtils.class'; import {ModalLoading} from '../../utils/modal/loading.component'; import {Dates, StringUtils} 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'; import {HelperService} from "../../utils/helper/helper.service"; @Component({ selector: 'advanced-search-page', templateUrl: 'advancedSearchPage.component.html' }) export class AdvancedSearchPageComponent { @Input() piwikSiteId = null; @Input() hasPrefix: boolean = true; @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() customFilter: SearchCustomFilter = null; @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 pageContents = null; public divContents = null; public routerHelper: RouterHelper = new RouterHelper(); public errorCodes: ErrorCodes = new ErrorCodes(); url = null; constructor(private route: ActivatedRoute, private location: Location, private _meta: Meta, private _title: Title, private _piwikService: PiwikService, private router: Router, private seoService: SEOService, private helper: HelperService) { } ngOnInit() { this.route.data .subscribe((data: { envSpecific: EnvProperties }) => { this.properties = data.envSpecific; //this.getDivContents(); this.getPageContents(); 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 description = "Openaire, search, repositories, open access, type, content provider, funder, project, " + this.pageTitle; this.updateTitle(this.pageTitle); this.updateDescription(description); this.searchUtils.baseUrl = "/" + this.searchUtils.baseUrl; this.updateBaseUrlWithParameters(); this.seoService.createLinkForCanonicalURL(this.properties.baseLink + this.router.url, false); } private getPageContents() { this.helper.getPageHelpContents(this.router.url, this.properties, (this.customFilter)?this.customFilter.valueId:null).subscribe(contents => { this.pageContents = contents; }) } private getDivContents() { this.helper.getDivHelpContents(this.router.url, this.properties, (this.customFilter)?this.customFilter.valueId:null).subscribe(contents => { this.divContents = contents; }) } 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 = ""; if(this.hasPrefix) { _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")); } } /** * Create Page URL parameters based on the selected fields of the advanced form * @param includePage */ 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; } /** * Create Search API query based on the selected fields of the advanced form */ 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++; } } if (this.customFilter) { params += (countParams == 0 ? "" : " and ") + this.customFilter.queryFieldName + " exact " + StringUtils.quote((this.customFilter.valueId)); } return params; } goTo(page: number = 1) { this.searchUtils.page = page; this.createUrlParameters(true); this.router.navigate([this.searchUtils.baseUrl], {queryParams: this.routerHelper.createQueryParams(this.parameterNames, this.parameterValues)}); /* 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(); } }