import { ChangeDetectorRef, Component, ElementRef, EventEmitter, Inject, Input, OnChanges, OnDestroy, OnInit, Output, PLATFORM_ID, SimpleChanges, ViewChild } from '@angular/core'; import {isPlatformServer, Location} from '@angular/common'; import {ActivatedRoute, Router} from '@angular/router'; import {Meta, Title} from '@angular/platform-browser'; import {AdvancedField, Filter, Value} from './searchHelperClasses.class'; import {SearchCustomFilter, SearchUtilsClass} from './searchUtils.class'; import {ModalLoading} from '../../utils/modal/loading.component'; import {Dates, Identifier, 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"; import {OpenaireEntities, SearchFields} from "../../utils/properties/searchFields"; import {RefineResultsUtils} from "../../services/servicesUtils/refineResults.class"; import {RangeFilter} from "../../utils/rangeFilter/rangeFilterHelperClasses.class"; import {ZenodoInformationClass} from "../../deposit/utils/zenodoInformation.class"; import {Breadcrumb} from "../../utils/breadcrumbs/breadcrumbs.component"; import {HelperFunctions} from "../../utils/HelperFunctions.class"; import {properties} from "../../../../environments/environment"; import {AlertModal} from "../../utils/modal/alert"; import {Subscriber} from "rxjs"; import {IndexInfoService} from "../../utils/indexInfo.service"; import {Background} from "../../utils/background-utils"; import {LayoutService} from "../../dashboard/sharedComponents/sidebar/layout.service"; import {Platform} from "@angular/cdk/platform"; export interface SearchForm extends Background {} declare var UIkit: any; @Component({ selector: 'new-search-page', templateUrl: 'newSearchPage.component.html' }) export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges { @ViewChild('mobileFilters') mobileFilters: ElementRef; @Input() hasPrefix: boolean = true; @Input() prefix: string = "OpenAIRE | "; @Input() pageTitle = ""; pageTitleWithFilters = ""; @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[]; @ViewChild(ModalLoading) loading: ModalLoading; @Input() csvParams: string; @Input() csvPath: string; @Input() simpleSearchLink: string = ""; @Input() advancedSearchLink: string = ""; @Input() disableForms: boolean = false; @Input() disableRefineForms: boolean = false; @Input() loadPaging: boolean = true; @Input() oldTotalResults: number = 0; @Input() openaireLink: string; @Input() customFilters: SearchCustomFilter[] = null; @Input() set customFilter(customFilter: SearchCustomFilter | SearchCustomFilter[]) { if(!Array.isArray(customFilter)) { this.customFilters = customFilter?[customFilter]:null; }else{ this.customFilters = customFilter; } } @Input() sort: boolean = true; @Input() sortedByChanged: string = ""; @Input() searchForm: SearchForm = {class: 'search-form', dark: true}; //From simple: @Input() orderedFilters = []; @Input() rangeFilters: RangeFilter[] = []; @Input() rangeFields: string[][] = []; @Input() refineFields = []; @Input() filters: Filter[] = []; @Input() staticFields = []; @Input() staticFilters: Filter[] = []; @Input() staticFieldValues: { [key: string]: {"name": string, "id": string, "count": string}[] } = {}; selectedFilters: number = 0; selectedRangeFilters: number = 0; selectedStaticFilters: number = 0; private searchFieldsHelper: SearchFields = new SearchFields(); @Input() newQueryButton: boolean = true; public showUnknownFilters: boolean = false; // when a filter exists in query but has no results, so no filters returned from the query URLCreatedFilters: Filter[] = []; URLCreatedRangeFilters: RangeFilter[] = []; URLCreatedStaticFilters: Filter[] = []; @Input() showRefine: boolean = true; @Input() tableViewLink: string; @Input() usedBy: string = "search"; @Input() public zenodoInformation: ZenodoInformationClass = new ZenodoInformationClass(); @Input() showIndexInfo: boolean = true; @Input() showResultCount: boolean = true; @Input() showMoreFilterValuesInline: boolean = true; @Input() filterValuesNum: number = 6; @Input() keywordFields = []; @Input() simpleView: boolean = true; @Input() formPlaceholderText = "Type Keywords..."; @Input() resultTypes: Filter = null; resultTypeOptions = { // "publications": {"id": "publication", "name": OpenaireEntities.PUBLICATIONS}, // "datasets": {"id": "dataset", "name": OpenaireEntities.DATASETS}, // "software": {"id": "software", "name": OpenaireEntities.SOFTWARE}, // "other": {"id": "other", "name": OpenaireEntities.OTHER} }; serviceTypeOptions = { // "datasources": {"id": "datasource", "name": OpenaireEntities.DATASOURCES}, // "services": {"id": "service", "name": "Other "+OpenaireEntities.SERVICES} } selectedTypesNum = 0; @Input() quickFilter: { filter: Filter, selected: boolean, filterId: string, value: string }; @Input() includeOnlyResultsAndFilter: boolean = false; @Input() showBreadcrumb: boolean = false; @Input() showDownload: boolean = true; @Input() breadcrumbs: Breadcrumb[] = []; private subscriptions = []; public parameterNames: string[] = []; public parameterValues: string[] = []; filterPillCharactersLimit: number = 35; public csvLimit: number = 0; public pagingLimit: number = 0; public resultsPerPage: number = 0; properties: EnvProperties = properties; public pageContents = null; public divContents = null; public routerHelper: RouterHelper = new RouterHelper(); public errorCodes: ErrorCodes = new ErrorCodes(); url = null; metaDescription = ""; public pageOptions: number[] = [5, 10, 20, 50]; @Input() basicMetaDescription = []; @Input() entitiesSelection: boolean = false; @Input() showSwitchSearchLink: boolean = true; // on 1st load, do not show filters until results query returns. public hideFilters: boolean = true; //Dashboard filterToggle = false; //stickyform @Input() stickyForm: boolean = false; currentValueToRemove; currentFilterToRemove; public indexUpdateDate: Date; showOffCanvas:boolean = false; isMobile: boolean = false; isServer: boolean; searchTerm: string = null; advancedSearchTerms: number = 0; @Input() hasCompactView: boolean = false; // if true, show buttons for compact view public compactView: boolean = false; // if true, show less info (e.g. hide description) on each result @Output() filterRequestAll = new EventEmitter(); 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, private layoutService: LayoutService, @Inject(PLATFORM_ID) private platform: any, private cdr: ChangeDetectorRef, private indexInfoService: IndexInfoService) { this.isServer = isPlatformServer(this.platform); } ngOnInit() { if(properties.adminToolsPortalType !== "explore") { //this.getDivContents(); this.getPageContents(); } this.pagingLimit = this.properties.pagingLimit; this.resultsPerPage = this.properties.resultsPerPage; this.csvLimit = this.properties.csvLimit; this.updateUrl(this.properties.domain + this.properties.baseLink + this.router.url); this.url = this.properties.domain + this.properties.baseLink + this.router.url; if (!this.includeOnlyResultsAndFilter) { this.subscriptions.push(this._piwikService.trackView(this.properties, this.pageTitle).subscribe()); } this.layoutService.isMobile.subscribe(isMobile => { this.isMobile = isMobile; this.cdr.detectChanges(); }); this.route.queryParams.subscribe(params => { if (params['page'] && params['page'] != 1) { HelperFunctions.scrollToId("searchForm"); } if (this.basicMetaDescription.length == 0) { if (this.entityType == "result") { this.basicMetaDescription = [OpenaireEntities.RESULTS, "Discover" + (this.properties.adminToolsCommunity == 'openaire' ? " over 100 million of" : "") + " "+OpenaireEntities.RESULTS+" ", "categorized by research type, year range, funder, languages, "+OpenaireEntities.COMMUNITY+" and "+OpenaireEntities.DATASOURCES+"."]; } else if (this.entityType == "project") { this.basicMetaDescription = ["Research "+OpenaireEntities.PROJECTS, "Discover research "+OpenaireEntities.PROJECTS+" and correlated research categorized by Funder and active year. ", "Statistics data about produced "+OpenaireEntities.RESULTS+" per year available."]; } else if (this.entityType == "organization") { this.basicMetaDescription = ["Research "+OpenaireEntities.ORGANIZATIONS, "Discover worldwide research "+OpenaireEntities.ORGANIZATIONS+" from over 100 countries and correlated research. ", "Funding, "+OpenaireEntities.DATASOURCES+", research "+OpenaireEntities.PUBLICATIONS+" and "+OpenaireEntities.DATASETS+" available."]; } else { this.basicMetaDescription.push(this.pageTitle) } } // console.log("title " + this.pageTitle, this.basicMetaDescription) this.updateMeta(this.pageTitle); }); this.searchUtils.baseUrl = "/" + this.searchUtils.baseUrl; if(this.breadcrumbs.length === 0) { this.breadcrumbs.push({name: 'home', route: '/'}); if (this.simpleView) { this.breadcrumbs.push({name: "Search", route: null}); } else if (!this.simpleView && this.advancedSearchLink) { this.breadcrumbs.push({name: "Advanced Search", route: null}); } } if (typeof document !== 'undefined') { this.subscriptions.push(this.indexInfoService.lastIndexDate.subscribe(lastIndexUpdate => { if (lastIndexUpdate) { this.indexUpdateDate = new Date(lastIndexUpdate); } })); } } private getPageContents() { this.subscriptions.push(this.helper.getPageHelpContents(this.properties, (this.customFilters && this.customFilters[0] && this.customFilters[0].queryFieldName == "communityId") ? this.customFilters[0].valueId : this.properties.adminToolsCommunity, this.router.url).subscribe(contents => { this.pageContents = contents; })); } private getDivContents() { this.subscriptions.push(this.helper.getDivHelpContents(this.properties, (this.customFilters && this.customFilters[0] && this.customFilters[0].queryFieldName == "communityId") ? this.customFilters[0].valueId : this.properties.adminToolsCommunity, this.router.url).subscribe(contents => { this.divContents = contents; })); } ngOnDestroy() { this.subscriptions.forEach(subscription => { if (subscription instanceof Subscriber) { subscription.unsubscribe(); } }); } ngOnChanges(changes: SimpleChanges) { this.cdr.detectChanges(); } get disabled() { return this.disableForms || this.disableRefineForms; } updateMeta(title: string) { let filterArray = []; let filtervalues = []; let filterURL = ""; // if (this.resultTypes && this.resultTypes.countSelectedValues > 0) { // filterURL += ((filterURL.length == 0) ? '?' : '&') + this.resultTypes.filterId + "="; // let filterName = this.resultTypes.title + " "; // for (let value of this.resultTypes.values) { // if (value.selected) { // filterArray.push(filterName + '"' + value.name + '"'); // filtervalues.push(value.name); // filterURL += ((filterName.length == 0) ? ',' : '') + StringUtils.URIEncode('"' + value.id + '"'); // filterName = ""; // } // } // } for (let filter of this.staticFilters) { if (filter.countSelectedValues > 0) { filterURL += ((filterURL.length == 0) ? '?' : '&') + filter.filterId + "="; let filterName = filter.title + " "; for (let value of filter.values) { if (value.selected) { filterArray.push(filterName + '"' + value.name + '"'); filtervalues.push(value.name); filterURL += ((filterName.length == 0) ? ',' : '') + StringUtils.URIEncode('"' + StringUtils.URIEncode(value.id) + '"'); filterName = ""; } } } } for (let filter of this.filters) { if (filter.countSelectedValues > 0) { filterURL += ((filterURL.length == 0) ? '?' : '&') + filter.filterId + "="; let filterName = filter.title + " "; for (let value of filter.values) { if (value.selected) { filterArray.push(filterName + '"' + value.name + '"'); filtervalues.push(value.name); filterURL += ((filterName.length == 0) ? ',' : '') + StringUtils.URIEncode('"' + StringUtils.URIEncode(value.id) + '"'); filterName = ""; } } } } let nonCanonicalizedPage = filterArray.length > 0; this.metaDescription = (nonCanonicalizedPage ? ((this.basicMetaDescription[0] + " filtered by: " + filterArray.join(" and ") + ". ") + (this.basicMetaDescription.length > 1 ? this.basicMetaDescription[1] : "")) : ((this.basicMetaDescription.length > 2 ? this.basicMetaDescription[1] + this.basicMetaDescription[2] : this.basicMetaDescription[0]))); this._meta.updateTag({content: this.metaDescription}, "name='description'"); this._meta.updateTag({content: this.metaDescription}, "property='og:description'"); this.updateTitle(title, (nonCanonicalizedPage ? filtervalues.join(" | ") + " | " : "")); 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) { let _title = (this.hasPrefix ? this.prefix : "") + filters + title; // _title = ((_title.length > 50) ? _title.substring(0, 50) : _title); this.pageTitleWithFilters = _title; this._title.setTitle(_title); this._meta.updateTag({content: _title}, "property='og:title'"); } updateUrl(url: string) { this._meta.updateTag({content: url}, "property='og:url'"); } clearFilters() { for (var i = 0; i < this.filters.length; i++) { for (var j = 0; j < this.filters[i].countSelectedValues; j++) { if (this.filters[i].values[j].selected) { this.filters[i].values[j].selected = false; } this.filters[i].countSelectedValues = 0; this.filters[i].radioValue = ""; } } this.selectedFilters = 0; for (let i = 0; i < this.rangeFilters.length; i++) { this.rangeFilters[i].selectedFromValue = null; this.rangeFilters[i].selectedToValue = null; } this.selectedRangeFilters = 0; // if (this.quickFilter) { // this.removeValueFromQuickFilter(); // } for (var i = 0; i < this.staticFilters.length; i++) { for (var j = 0; j < this.staticFilters[i].countSelectedValues; j++) { if (this.staticFilters[i].values[j].selected) { this.staticFilters[i].values[j].selected = false; } this.staticFilters[i].countSelectedValues = 0; this.staticFilters[i].radioValue = ""; } } this.selectedStaticFilters = 0; // if (this.resultTypes) { // this.resultTypes.values = []; // } this.goTo(1); // this.clearKeywords(); } goTo(page: number = 1, scroll: boolean = true) { if (this.mobileFilters && (typeof document !== 'undefined')) { UIkit.offcanvas(this.mobileFilters.nativeElement).hide(); } this.searchUtils.page = page; this.buildPageURLParameters(this.filters, this.rangeFilters, this.staticFilters, true); this.router.navigate([this.searchUtils.baseUrl], {queryParams: this.routerHelper.createQueryParams(this.parameterNames, this.parameterValues)}); if (scroll) { HelperFunctions.scrollToId("searchForm"); } /* Code For Piwik*/ if (typeof localStorage !== 'undefined') { //console.log("In PreviousRouteRecorder : "+this.router.url ); localStorage.setItem('previousRoute', this.router.url); } this.subscriptions.push(this._piwikService.trackView(this.properties, this.pageTitle).subscribe()); /* End Piwik Code */ } queryChanged($event) { this.cdr.detectChanges(); if ($event == "filters_update") { return; } this.goTo(1, false); } sizeChanged($event) { this.searchUtils.size = $event; this.goTo(1); } sortByChanged($event) { //this.searchUtils.sortBy = $event.value; this.sortedByChanged = $event; this.goTo(1); } getOperatorParameter(parameter: string): string { for (let id of this.fieldIds) { if (this.fieldIdsMap[id]["param"] == parameter) { return this.fieldIdsMap[id]["operator"]; } } } /* * Get A sub-array of this.refineFields array, which contains the ids of the selected filters */ public getSelectedFilters(): Map { var selected: Map = new Map(); var filters = this.URLCreatedFilters; for (var i = 0; i < filters.length; i++) { var filter: Filter = filters[i]; if (filter.countSelectedValues > 0) { let selectedValues: string[] = []; for(let value of filter.values) { if(value.selected) { selectedValues.push(value.id); } } selected.set(filter.filterId, selectedValues); } } return selected; } /* * Get A sub-array of this.refineFields array, which contains the ids of the selected parameters */ private getSelectedParameters(): Map { var selected: Map = new Map(); for (var i = 0; i < this.refineFields.length; i++) { let selectedValues: string[] = []; let index = this.parameterNames.indexOf(this.refineFields[i]); if (index != -1) { for(let values of this.parameterValues[index]) { let split = values.split('"'); for(let value of split) { if(value != "" && value != ",") { selectedValues.push(value); } } } selected.set(this.refineFields[i], selectedValues); } } return selected; } /* * Get A sub-array of this.staticFields array, which contains the ids of the selected filters */ public getSelectedStaticFilters(): Map { var selected: Map = new Map(); var filters = this.URLCreatedStaticFilters; for (var i = 0; i < filters.length; i++) { var filter: Filter = filters[i]; if (filter.countSelectedValues > 0) { let selectedValues: string[] = []; for(let value of filter.values) { if(value.selected) { selectedValues.push(value.id); } } selected.set(filter.filterId, selectedValues); } } return selected; } /* * Get A sub-array of this.staticFields array, which contains the ids of the selected parameters */ private getSelectedStaticParameters(): Map { var selected: Map = new Map(); for (var i = 0; i < this.staticFields.length; i++) { let selectedValues: string[] = []; let index = this.parameterNames.indexOf(this.staticFields[i]); if (index != -1) { let split = this.parameterValues[index].split('"'); for(let value of split) { if(value != "" && value != ",") { selectedValues.push(value); } } selected.set(this.staticFields[i], selectedValues); } } return selected; } /* * Get A sub-array of this.refineFields array, which hides hidden fields (e.g Funding level 0,1,2,..), and contains those that depend on another fields (e.g Funding level 0 if Funder is selected ) */ public getFields(): string[] { var selected_filters: Map = this.getSelectedFilters(); if (selected_filters.size == 0) { selected_filters = this.getSelectedParameters(); } var selected_static_filters: Map = this.getSelectedStaticFilters(); if (selected_static_filters.size == 0) { selected_static_filters = this.getSelectedStaticParameters(); } let all_selected_filters = new Map([...selected_filters, ...selected_static_filters]); // let all_selected_filters = selected_filters.concat(selected_static_filters); var fields: string[] = []; for (var i = 0; i < this.refineFields.length; i++) { var dependentTo = this.searchFieldsHelper.DEPENDENT_FIELDS[this.refineFields[i]]; var dependentToValues = this.searchFieldsHelper.DEPENDENT_FIELDS_AND_VALUES[this.refineFields[i]]; // TODO check again the checks //if filter is not marked as hidden OR it is hidden but it is dependent to a field that it IS selected if (this.searchFieldsHelper.HIDDEN_FIELDS.indexOf(this.refineFields[i]) == -1 || (all_selected_filters.has(this.refineFields[i])) || (!dependentTo && !dependentToValues) || (all_selected_filters.has(dependentTo)) || (dependentToValues && (all_selected_filters.has(dependentToValues.field) && dependentToValues.values.some(dependentValue=> all_selected_filters.get(dependentToValues.field).includes(dependentValue)))) || (this.resultTypes && this.resultTypes.filterId == dependentTo && this.resultTypes.countSelectedValues > 0) // || (this.resultAccesses && this.resultAccesses.filterId == dependentTo && this.resultAccesses.countSelectedValues > 0) ) { fields.push(this.refineFields[i]); } } return fields; } /* * Get a query string of all fields, that want to get from search (e.g. &fields=funderid&fields=projectstartyear&...)) */ public getRefineFieldsQuery(fields: string[] = null): string { if(!fields) { fields = this.getFields(); } var fieldsStr = "" for (var i = 0; i < fields.length; i++) { fieldsStr += "&fields=" + fields[i]; } return "&refine=true" + fieldsStr; } /* * Mark as check the new filters that are selected, when you get them from search */ public checkSelectedFilters(filters: Filter[]) { this.filters = filters; if (this.customFilters) { for (let customFilter of this.customFilters) { if (!customFilter.isHiddenFilter) { customFilter.selected = null; } } } for (var i = 0; i < filters.length; i++) { var filter: Filter = filters[i]; filter.countSelectedValues = 0; if (this.parameterNames.indexOf(filter.filterId) != -1) { let values = (decodeURIComponent(this.parameterValues[this.parameterNames.indexOf(filter.filterId)])).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/, -1); for (let filterValue of filter.values) { if (values.indexOf(StringUtils.quote(filterValue.id)) > -1) { filterValue.selected = true; filter.countSelectedValues++; } else { filterValue.selected = false; } } if (this.customFilters) { for (let customFilter of this.customFilters) { customFilter.selected = customFilter.queryFieldName == filter.filterId && values.indexOf(StringUtils.quote(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 { for (let filterValue of filter.values) { filterValue.selected = false; } } // if (this.quickFilter && filter.filterId == this.quickFilter.filterId) { // this.quickFilter.filter = filter; // } } this.filterFilterValues(this.filters); if (!this.includeOnlyResultsAndFilter) { this.updateMeta(this.pageTitle); } return filters; } /* * Mark as check the new range filters that are selected */ public checkSelectedRangeFilters(filters: RangeFilter[]) { //console.log("checkSelectedRangeFilters: parameterNames.length: "+this.parameterNames.length); this.rangeFilters = filters; for (let i = 0; i < filters.length; i++) { let filter: RangeFilter = filters[i]; if (this.parameterNames.indexOf(filter.filterId) != -1) { //console.log(filter.filterId + " "+this.parameterNames.indexOf(filter.filterId) ); let values = (decodeURIComponent(this.parameterValues[this.parameterNames.indexOf(filter.filterId)])).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/, -1); let operators: string [] = (StringUtils.URIDecode(this.parameterValues[this.parameterNames.indexOf(filter.filterId)])).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/, -1); if (values.length == operators.length) { for (let j = 0; j < values.length; j++) { if (this.fieldIdsMap[filter.originalFilterIdFrom + "-range-" + filter.originalFilterIdTo].filterType == "range") { let value: string = StringUtils.unquote(values[j]); let validDates: boolean = true; let years: string[] = (value.substring(5)).split(":"); let yearFrom: string = (Dates.isValidYear(years[0]) ? years[0] : null); let yearTo: string = (Dates.isValidYear(years[1]) ? years[1] : null); //console.log("checkSelectedRangeFilters: yearFrom: " + yearFrom + " - yearTo: "+yearTo); if (yearFrom) { filter.selectedFromValue = yearFrom; } if (yearTo) { filter.selectedToValue = yearTo; } if (yearFrom && yearTo) { filter.selectedFromAndToValues = yearFrom + "-" + yearTo; } else if (yearFrom) { filter.selectedFromAndToValues = "From " + yearFrom; } else if (yearTo) { filter.selectedFromAndToValues = "Until " + yearTo; } if (!yearFrom && !yearTo) { validDates = false; } // if (value.length < 14) { // validDates = false; // console.log("not valid (length<14)"); // } else { // if (!Dates.isValidYear(value.substring(5, 9)) || !Dates.isValidYear(value.substring(10, 14))) { // validDates = false; // console.log("not valid years"); // } else { // filter.selectedFromValue = value.substring(5, 9); // filter.selectedToValue = value.substring(10, 14); // console.log(filter); // } // } } } } } else { filter.selectedFromValue = null; filter.selectedToValue = null; } } return this.rangeFilters; } public checkSelectedStaticFilters(filters: Filter[]) { for (var i = 0; i < filters.length; i++) { var filter: Filter = filters[i]; filter.countSelectedValues = 0; if (this.parameterNames.indexOf(filter.filterId) != -1) { let values = (decodeURIComponent(this.parameterValues[this.parameterNames.indexOf(filter.filterId)])).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/, -1); for (let filterValue of filter.values) { if (values.indexOf(StringUtils.quote(filterValue.id)) > -1) { filterValue.selected = true; filter.countSelectedValues++; } else { filterValue.selected = false; } } } else { for (let filterValue of filter.values) { filterValue.selected = false; } } } this.filterFilterValues(this.filters); if (!this.includeOnlyResultsAndFilter) { this.updateMeta(this.pageTitle); } this.staticFilters = filters; return filters; } get existingFiltersWithValues() { if (this.filters.length == 0) { return 0; } return this.filters.some(filter => (filter.values && filter.values.length > 0)); } /* * For Funder filters - if funder selected */ public filterFilterValues(filters: Filter[]) { var funders = []; var funder_prefix = []; for (var i = 0; i < filters.length; i++) { var filter: Filter = filters[i]; // console.log(filter.filterId); if (filter.filterId.indexOf("funder") != -1 && this.parameterNames.indexOf(filter.filterId) != -1) { let funders = (decodeURIComponent(this.parameterValues[this.parameterNames.indexOf(filter.filterId)])).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/, -1); for (let funder of funders) { funder_prefix.push(StringUtils.unquote(funder).split("____")[0]); } // console.log(funder_prefix ); } else if (filter.filterId.indexOf("funding") != -1) { // console.log(" funding: "+filter.filterId ); var filteredValues = [] for (let filterValue of filter.values) { var value_prefix = filterValue.id.split("____")[0]; // console.log("Value prefix: "+value_prefix ); if (funder_prefix.indexOf(value_prefix) != -1) { // console.log("here" + value_prefix); filteredValues.push(filterValue); } } if (filteredValues.length > 0) { filter.values = filteredValues; } } } return filters; } public countSelectedFilters(filters: Filter[]): number { this.selectedFilters = 0; for (let filter of filters) { if (filter.countSelectedValues > 0) { this.selectedFilters += filter.countSelectedValues; } } return this.selectedFilters; } public countSelectedRangeFilters(rangeFilters: RangeFilter[]): number { this.selectedRangeFilters = 0; for (let filter of rangeFilters) { if (filter.selectedFromValue || filter.selectedToValue) { this.selectedRangeFilters++; } } return this.selectedRangeFilters; } public countSelectedStaticFilters(filters: Filter[]): number { this.selectedStaticFilters = 0; for (let filter of filters) { if (filter.countSelectedValues > 0) { this.selectedStaticFilters += filter.countSelectedValues; } } return this.selectedStaticFilters; } private clearKeywords() { if (this.searchUtils.keyword.length > 0) { this.searchUtils.keyword = ''; } this.goTo(1); } public removeFilter(value: Value, filter: Filter, forceRemove: boolean = false) { this.currentValueToRemove = value; this.currentFilterToRemove = filter; filter.countSelectedValues--; this.selectedFilters--; if (value.selected == true) { value.selected = false; } if (filter.filterType == "radio") { filter.radioValue = ""; } // if (this.quickFilter && this.quickFilter.filterId == filter.filterId) { // this.removeValueFromQuickFilter(); // } this.goTo(1); } public removeRangeFilter(filter: RangeFilter) { filter.selectedFromValue = null; filter.selectedToValue = null; this.goTo(1); } getSelectedValues(filter): any { var selected = []; if (filter.countSelectedValues > 0) { for (var i = 0; i < filter.values.length; i++) { if (filter.values[i].selected) { selected.push(filter.values[i]); } } } return selected; } filterChanged($event) { /* if (this.quickFilter && this.quickFilter.filter) { this.removeValueFromQuickFilter(); }*/ this.goTo(1); } filterToggled($event) { this.filterRequestAll.emit($event) } /** * if there is a change in the values of the quick filter, this function has to be run, to also update the quickFilter */ /* removeValueFromQuickFilter() { if (this.quickFilter.filter.countSelectedValues == 0) { this.quickFilter.selected = false; } else { let isQuickEnabled = false; for (let filterValue of this.quickFilter.filter.values) { isQuickEnabled = (filterValue.name == this.quickFilter.value) } this.quickFilter.selected = (isQuickEnabled && this.quickFilter.filter.countSelectedValues == 1); } }*/ // for loading public openLoading() { this.loading.open(); } public closeLoading() { this.loading.close(); } /** * Build advanced search Filters based on the URL parameters * @param params */ createAdvancedSearchSelectedFiltersFromNewURLParameters(params) { for (let i = 0; i < Object.keys(params).length; i++) { if (params["f" + i] && params["fv" + i]) { let fieldId = params["f" + i].split(",")[0]; let operator = (params["f" + i].split(",").length > 1) ? params["f" + i].split(",")[1] : "and"; let not: boolean = params["fo" + i] === "not"; let fieldparam = (this.fieldIdsMap[fieldId]) ? this.fieldIdsMap[fieldId].param : ""; if (!this.fieldIdsMap[fieldId]) { console.error("Field: " + fieldId + " not found in fieldIds map"); continue; } let value: string = StringUtils.URIDecode(params["fv" + i]); if (this.fieldIdsMap[fieldId].type == "date") { let validDates: boolean = true; let dateField: AdvancedField = new AdvancedField(fieldId, fieldparam, this.fieldIdsMap[fieldId].name, this.fieldIdsMap[fieldId].type, value, operator, !not); 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, value, operator, !not)); } } } } /** * Build advanced search Filters based on the URL parameters * @param params */ createAdvancedSearchSelectedFiltersFromURLParameters(params) { this.createAdvancedSearchSelectedFiltersFromNewURLParameters(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"); continue; } 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, values[j], operators[j])); } } } } } if (params['keyword'] && params['keyword'].length > 0) { this.selectedFields.push(new AdvancedField(this.fieldIds[0], this.fieldIdsMap[this.fieldIds[0]].param, this.fieldIdsMap[this.fieldIds[0]].name, this.fieldIdsMap[this.fieldIds[0]].type, params['keyword'], "and")); } if (this.selectedFields.length == 0) { this.selectedFields.push(new AdvancedField(this.fieldIds[0], this.fieldIdsMap[this.fieldIds[0]].param, this.fieldIdsMap[this.fieldIds[0]].name, this.fieldIdsMap[this.fieldIds[0]].type, "", "and")); } } /** * Create Search API query based on the selected fields of the advanced form */ getSearchAPIQueryForAdvancedSearhFields(URLparams = null) { 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") { // console.log(this.selectedFields[i].value) /* var op = ""; var doisParams = ""; if ((this.entityType == 'publication' || this.entityType == 'dataset' || this.entityType == 'software' || this.entityType == 'other' || this.entityType == "result")) { var DOIs: Identifier[] = Identifier.getIdentifiersFromString(this.selectedFields[i].value); for (let identifier of DOIs) { // console.log(identifier) // pidclassid exact \"doi\" and pid exact \"10.1016/j.nima.2015.11.134\" //and (authorid exact \"0000-0001-7291-3210 \" )" if(identifier.class == "ORCID"){ doisParams += (doisParams.length > 0 ? " or " : "") +'(authorid="' + identifier.id + '")'; }else{ doisParams += (doisParams.length > 0 ? " or " : "") +'(pidclassid exact "' + identifier.class + '" and pid="' + identifier.id + '")'; } } } if (doisParams.length > 0) { params += this.createQuotedKeywordQuery(this.selectedFields[i].value, this.selectedFields[i].id, this.selectedFields[i].operatorId ,countParams,true, true) + " or " + doisParams; } else { params += this.createQuotedKeywordQuery(this.selectedFields[i].value, this.selectedFields[i].id, this.selectedFields[i].operatorId,countParams,true); }*/ params += NewSearchPageComponent.createKeywordQuery(this.entityType, this.selectedFields[i].value, this.selectedFields[i].id, this.selectedFields[i].operatorId, countParams, this.selectedFields[i].includes); //TODO deposit case // console.log(this.usedBy) // console.log(this.keywordFields) if (this.usedBy == "deposit") { if (this.keywordFields.length > 0) { params += " or (" } for (let j = 0; j < this.keywordFields.length; j++) { if (j > 0) { params += " or " } params += NewSearchPageComponent.createQuotedKeywordQuery(this.selectedFields[i].value, this.keywordFields[j].name, " or ", countParams, false); // let field = this.keywordFields[i]; //keywordQuery += field.name+field.equalityOperator+StringUtils.URIEncode(keyword); // params += field.name+field.equalityOperator+StringUtils.quote(StringUtils.URIEncode(keyword)); } if (this.keywordFields.length > 0) { params += " ) " } } } else if (this.selectedFields[i].type == "identifier") { params += NewSearchPageComponent.createKeywordQuery(this.entityType, this.selectedFields[i].value, this.selectedFields[i].id, this.selectedFields[i].operatorId, countParams); } else if (countParams == 0 && this.selectedFields[i].operatorId == "not" && this.fieldIdsMap[this.selectedFields[i].id].equalityOperator != "=") { params += " " + this.selectedFields[i].id + " <> " + '"' + StringUtils.URIEncode(this.selectedFields[i].value) + '"' + " "; } else if (!this.selectedFields[i].includes) { params += (i > 0?this.selectedFields[i].operatorId:'') + " (*=* NOT " + this.selectedFields[i].id + this.fieldIdsMap[this.selectedFields[i].id].equalityOperator + '"' + StringUtils.URIEncode(this.selectedFields[i].value) + '"' + ") "; } else if (this.fieldIdsMap[this.selectedFields[i].id].equalityOperator == "=") { params += NewSearchPageComponent.createQuotedKeywordQuery(this.selectedFields[i].value, this.selectedFields[i].id, this.selectedFields[i].operatorId, countParams, false); } 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.entityType == "service" && URLparams) { if (URLparams["type"]) { let types1 = URLparams["type"]; types1 = Array.isArray(types1) ? types1.join(',').split(",") : types1.split(","); types1.map(function (t) { return StringUtils.unquote(StringUtils.URIDecode(t)); }); let types = URLparams["type"]; types = Array.isArray(types) ? types.join(',').split(",") : types.split(","); types.map(function (t) { return StringUtils.unquote(StringUtils.URIDecode(t)); }); if (types.indexOf("datasources") == -1 || types.indexOf("services") == -1) { for (let type of types) { params += (params ? ' and ' : '') + ("eosctype exact " + (types.indexOf("datasources") != -1 ? "\"Data Source\"" : "\"Service\"")); // allFqs += "&type=" + StringUtils.unquote(StringUtils.URIDecode(type)); } } } } // console.log("ParameterS:") // console.log(params) return params; } public static createKeywordQuery(entityType: string, value: string, id, operatorId, countParams = 0, includes: boolean = true) { let params = ""; let doisParams = ""; var DOIs: Identifier[] = Identifier.getIdentifiersFromString(value); if ((entityType == 'publication' || entityType == 'dataset' || entityType == 'software' || entityType == 'other' || entityType == "result" || entityType == "dataprovider" || entityType == "service" || entityType == "organization")) { for (let identifier of DOIs) { // console.log(identifier) // pidclassid exact \"doi\" and pid exact \"10.1016/j.nima.2015.11.134\" //and (authorid exact \"0000-0001-7291-3210 \" )" if (identifier.class == "ORCID") { doisParams += (doisParams.length > 0 ? " or " : "") + '(authorid="' + StringUtils.URIEncode(identifier.id) + '")'; // doisParams += (doisParams.length > 0 ? " or " : "") +'(authorid="' + StringUtils.URIEncode(identifier.id) + '" and (authoridtype exact "orcid"))'; } else { doisParams += (doisParams.length > 0 ? " or " : "") + '(pid="' + StringUtils.URIEncode(identifier.id) + '")'; // doisParams += (doisParams.length > 0 ? " or " : "") +'(pidclassid exact "' + identifier.class + '" and pid="' + identifier.id + '")'; } } } if (doisParams.length > 0) { params += this.createQuotedKeywordQuery(value, id, operatorId, countParams, true, true, includes) + " or " + doisParams; } else { //if it is PIDs but no doisquery produced, forced to use quotes as the query will fail due to special characters params += this.createQuotedKeywordQuery(value, id, operatorId, countParams, true, (DOIs.length > 0 && doisParams.length == 0), includes); } return params; } private static createQuotedKeywordQuery(fieldValue: string, fieldId, fieldOperator, countParams: number, isSearchAll: boolean, forceQuotted: boolean = false, includes: boolean = true) { let params = ""; let countQuote = (fieldValue.match(/'/g) || []).length; let countDoubleQuote = (fieldValue.match(/"/g) || []).length; let quotedParts = []; if (countQuote % 2 == 0 && countDoubleQuote % 2 == 0) { quotedParts = (fieldValue) ? fieldValue.match(/(["'])(.*?)*?\1/g) : []; } params += (countParams == 0 ? "" : fieldOperator); if(!includes) { params += "(*=* NOT "; } else { params += " ("; } if (forceQuotted) { /** Remove double quotes **/ fieldValue = fieldValue.replace(/["]+/g, ''); return params + this.getQuotedQueryPart(fieldId, '"' + fieldValue + '"', isSearchAll) + ")"; } if (quotedParts && quotedParts.length == 1 && quotedParts[0] == fieldValue) { params += this.getQuotedQueryPart(fieldId, fieldValue, isSearchAll); } else if (quotedParts && quotedParts.length > 0) { for (let i = 0; i < quotedParts.length; i++) { params += (i > 0) ? " and " : ""; params += this.getQuotedQueryPart(fieldId, quotedParts[i], isSearchAll); } let startPoint = 0; let endPoint = 0; for (let i = 0; i < quotedParts.length; i++) { let index = fieldValue.indexOf(quotedParts[i]); endPoint = (i + 1 < quotedParts.length) ? fieldValue.indexOf(quotedParts[i + 1]) : fieldValue.length; // console.log(fieldValue.indexOf(quotedParts[i+1]) +" - "+fieldValue.length); // console.log(" SP "+ startPoint+" EP: "+endPoint); if (index == startPoint) { startPoint += quotedParts[i].length; } else if (startPoint < index) { endPoint = index; } // console.log(" SP "+ startPoint+" EP: "+endPoint); if (decodeURIComponent(fieldValue.substring(startPoint, endPoint)).split(" ").join("").length > 0) { params += " and " + this.getNoQuotedQueryPart(fieldId, fieldValue.substring(startPoint, endPoint), isSearchAll); } // console.log("For "+i+" " +params+" SP "+ startPoint+" EP: "+endPoint); // startPoint = (i+1 0) { params += " and " + this.getNoQuotedQueryPart(fieldId, fieldValue.substring(startPoint, fieldValue.length), isSearchAll); } } else { params += this.getNoQuotedQueryPart(fieldId, fieldValue, isSearchAll); } params += ")"; return params; } private static getQuotedQueryPart(fieldId: string, value: string, isSearchAll: boolean) { return (isSearchAll ? "__all" : fieldId) + " exact " + StringUtils.URIEncode(value); } private static getNoQuotedQueryPart(fieldId: string, value: string, isSearchAll: boolean) { //split the keywords of the vlaue and query seperately for each keyword using quotes to allow characters like .@ let valueKeywords = value.split(" "); let query = ""; let i = 0; for (let keyword of valueKeywords) { if (keyword.length > 0) { query += (i != 0 ? " and " : "") + (isSearchAll ? "(" : fieldId + "=") + "\"" + StringUtils.URIEncode(this.checkForReservedWords(keyword)) + "\"" + (isSearchAll ? ")" : ""); i++; } } return query; } private static checkForReservedWords(keyword: string) { let reservedWords = ["AND", "OR", "NOT"]; if (reservedWords.indexOf(keyword) != -1) { return keyword.toLowerCase(); } return keyword; } /** * Create Search API query based on the filters of refine fields * @param URLparams * @param firstLoad */ getSearchAPIQueryForRefineFields(URLparams, firstLoad: boolean) { var allFqs = ""; // console.log(this.refineFields) for (var i = 0; i < this.refineFields.length; i++) { var filterId = this.refineFields[i]; if (URLparams[filterId] != undefined) { let values = (StringUtils.URIDecode(StringUtils.URIDecode(URLparams[filterId]))).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/, -1); var countvalues = 0; var fq = ""; let filterOp: string = this.searchFieldsHelper.getFieldOperator(filterId); // console.info(filterId, filterOp); for (let value of values) { if (value && value.length > 0) { countvalues++; var paramId = this.fieldIdsMap[filterId].param; // parameters+='&' + paramId+ '='+ value;//+"&" + this.fieldIdsMap[paramId].operator + "="+((countvalues == 1)?"and":"or"); fq += (fq.length > 0 ? " " + filterOp + " " : "") + filterId + " exact " + (value); } } if (countvalues > 0) { fq = "&fq=" + StringUtils.URIEncode(fq); } allFqs += fq; } } for (var i = 0; i < this.staticFields.length; i++) { var filterId = this.staticFields[i]; if (URLparams[filterId] != undefined && filterId != "type") { let values = (StringUtils.URIDecode(StringUtils.URIDecode(URLparams[filterId]))).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/, -1); var countvalues = 0; var fq = ""; let filterOp: string = this.searchFieldsHelper.getFieldOperator(filterId); for (let value of values) { if (value && value.length > 0) { countvalues++; fq += (fq.length > 0 ? " " + filterOp + " " : "") + filterId + " exact " + (value); } } if (countvalues > 0) { fq = "&fq=" + StringUtils.URIEncode(fq); } allFqs += fq; } } if (this.customFilters) { for (let customFilter of this.customFilters) { if (customFilter.isHiddenFilter) { if(customFilter.customQuery){ allFqs += "&fq=" + StringUtils.URIEncode(customFilter.customQuery); }else { allFqs += "&fq=" + StringUtils.URIEncode(customFilter.queryFieldName + " exact " + StringUtils.quote((customFilter.valueId))); } } } } /* 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; } else { this.quickFilter.selected = false; } if( this.quickFilter.selected && URLparams[this.quickFilter.filterId] == undefined){ // if ((firstLoad && URLparams[this.quickFilter.filterId] == undefined && URLparams["qf"] == undefined) // ||( URLparams[this.quickFilter.filterId] == undefined && URLparams["qf"] == "true")) { allFqs += "&fq=resultbestaccessright exact " + StringUtils.quote(this.quickFilter.value); } }*/ if (this.entityType == "result") { if (URLparams["type"]) { let types = URLparams["type"]; types = Array.isArray(types) ? types.join(',').split(",") : types.split(","); types.map(function (t) { return StringUtils.unquote(StringUtils.URIDecode(t)); }); if (types.indexOf("publications") != -1 && types.indexOf("datasets") != -1 && types.indexOf("software") != -1 && types.indexOf("other") != -1) { allFqs += "&type=results"; } else { for (let type of types) { allFqs += "&type=" + StringUtils.unquote(StringUtils.URIDecode(type)); } } } else { allFqs += "&type=results"; } } else if (this.entityType == "publication") { allFqs += "&type=publications"; } else if (this.entityType == "dataset") { allFqs += "&type=datasets"; } else if (this.entityType == "software") { allFqs += "&type=software"; } else if (this.entityType == "other") { allFqs += "&type=other"; } else if (this.entityType == "project") { allFqs += "&type=projects"; } else if (this.entityType == "organization") { allFqs += "&type=organizations"; } else if (this.entityType == "dataprovider") { allFqs += "&type=datasources"; } else if (this.entityType == "service") { allFqs += "&type=services"; } // console.log("AllFqs (check type): "+allFqs); // console.log("type: "+this.entityType); // var keyword = URLparams['keyword']; // var doiQuery = ""; // var keywordQuery = ""; // if((keyword && keyword.length > 0)){ // if((this.type == 'publications' ||this.type == 'research data' || this.type == 'software' || this.type == 'other research products')){ // var DOIs:string[] = DOI.getDOIsFromString(keyword); // var doisParams = ""; // // for(var i =0 ;i < DOIs.length; i++){ // doisParams+=(doisParams.length > 0?"&":"")+'doi="'+ DOIs[i]+'"'; // } // if(doisParams.length > 0){ // doiQuery += "&"+doisParams; // }else { // keywordQuery += "&q="+StringUtils.URIEncode(keyword); // } // }else{ // if(this.usedBy == "deposit") { // if(this.keywordFields.length > 0) { // keywordQuery = "&fq="; // } // // for(let i=0; i< this.keywordFields.length ; i++) { // if(i > 0) { // keywordQuery += " or "; // } // let field = this.keywordFields[i]; // //keywordQuery += field.name+field.equalityOperator+StringUtils.URIEncode(keyword); // keywordQuery += field.name+field.equalityOperator+StringUtils.quote(StringUtils.URIEncode(keyword)); // } // } else { // keywordQuery += "&q=" + StringUtils.URIEncode(keyword); // } // // } // } //TODO add DOI? return allFqs; } /** * Create Search API query based on the filters of refine fields * @param URLparams */ getSearchAPIQueryForRangeFields(URLparams) { let allFqs = ""; for (let i = 0; i < this.rangeFields.length; i++) { let filterId = this.rangeFields[i][0] + "-range-" + this.rangeFields[i][1]; let filterParam = this.searchFieldsHelper.getFieldParam(filterId, this.entityType); if (URLparams[filterParam] != undefined) { let values = (StringUtils.URIDecode(StringUtils.URIDecode(URLparams[filterParam]))).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/, -1); var countvalues = 0; var fq = ""; var fqFrom = ""; var fqTo = ""; let filterOp: string = this.searchFieldsHelper.getFieldOperator(filterId); for (let value of values) { if (this.fieldIdsMap[filterId].filterType == "range") { let selectedFromValue; let selectedToValue; let years: string[] = (value.substring(5)).split(":"); let yearFrom: string = (Dates.isValidYear(years[0]) ? years[0] : null); //(Number.isInteger(parseInt(years[0], 10)) ? years[0] : null); let yearTo: string = (Dates.isValidYear(years[1]) ? years[1] : null); //console.log("getSearchAPIQueryForRangeFields: yearFrom: " + yearFrom + " - yearTo: "+yearTo); if (yearFrom) { selectedFromValue = yearFrom; } if (yearTo) { selectedToValue = yearTo; } if (yearFrom || yearTo) { // if (value.length <= 14) { // if(Dates.isValidYear(value.substring(5, 9))) { // selectedFromValue = value.substring(5, 9); // } // if(Dates.isValidYear(value.substring(10, 14))) { // selectedToValue = value.substring(10, 14); // } /*if(this.rangeFields[i][0] == this.rangeFields[i][1]) { //console.log(selectedFromValue + " - "+selectedToValue); if (selectedFromValue && selectedToValue) { let equalityOp = this.fieldIdsMap[filterId].equalityOperator; fq += (fq.length > 0 ? " " + filterOp + " " : "") + this.rangeFields[i][0] + equalityOp + "\"" + selectedFromValue + " " + selectedToValue + "\""; fq = "&fq=" + StringUtils.URIEncode(fq); } else if (selectedFromValue) { let equalityOp = this.fieldIdsMap[this.rangeFields[i][0]].equalityOperator; if(equalityOp == " = ") { equalityOp = " >= "; } fq += (fq.length > 0 ? " " + filterOp + " " : "") + this.rangeFields[i][0] + equalityOp + "\"" + selectedFromValue + "\""; fq = "&fq=" + StringUtils.URIEncode(fq); } else if (selectedToValue) { let equalityOp = this.fieldIdsMap[this.rangeFields[i][1]].equalityOperator; if(equalityOp == " = ") { equalityOp = " <= "; } fq += (fq.length > 0 ? " " + filterOp + " " : "") + this.rangeFields[i][0] + equalityOp + "\"" + selectedToValue + "\""; fq = "&fq=" + StringUtils.URIEncode(fq); } } else { let equalityOpFrom = this.fieldIdsMap[this.rangeFields[i][0]].equalityOperator; let equalityOpTo = this.fieldIdsMap[this.rangeFields[i][1]].equalityOperator; if (selectedFromValue) { fq += (fq.length > 0 ? " " + filterOp + " " : "") + this.rangeFields[i][0] + equalityOpFrom + "\"" + selectedFromValue + "\""; // fq = "&fq=" + StringUtils.URIEncode(fq); } if (selectedToValue) { fq += (fq.length > 0 ? " " + filterOp + " " : "") + this.rangeFields[i][1] + equalityOpTo + "\"" + selectedToValue + "\""; // fq = "&fq=" + StringUtils.URIEncode(fq); } if(selectedFromValue || selectedToValue) { fq = "&fq=" + StringUtils.URIEncode(fq); } }*/ fq = NewSearchPageComponent.createRangeFilterQuery(this.rangeFields[i], selectedFromValue, selectedToValue, this.fieldIdsMap[filterId].equalityOperator, this.fieldIdsMap[this.rangeFields[i][0]].equalityOperator, this.fieldIdsMap[this.rangeFields[i][1]].equalityOperator, filterOp); } } } allFqs += fq + fqFrom + fqTo; } } return allFqs; } // createRangeFilterQuery(this.rangeFields[i], selectedFromValue, selectedToValue, this.fieldIdsMap[this.rangeFields[i][0]].equalityOperator, this.fieldIdsMap[this.rangeFields[i][1]].equalityOperator; filterOp ) public static createRangeFilterQuery(rangeField, selectedFromValue, selectedToValue, equalityOp, equalityOpFrom, equalityOpTo, filterOp) { let fq = ""; if (rangeField[0] == rangeField[1]) { //console.log(selectedFromValue + " - "+selectedToValue); if (selectedFromValue && selectedToValue) { fq += (fq.length > 0 ? " " + filterOp + " " : "") + rangeField[0] + equalityOp + "\"" + selectedFromValue + " " + selectedToValue + "\""; fq = "&fq=" + StringUtils.URIEncode(fq); } else if (selectedFromValue) { if (equalityOpFrom == " = ") { equalityOpFrom = " >= "; } fq += (fq.length > 0 ? " " + filterOp + " " : "") + rangeField[0] + equalityOpFrom + "\"" + selectedFromValue + "\""; fq = "&fq=" + StringUtils.URIEncode(fq); } else if (selectedToValue) { if (equalityOpTo == " = ") { equalityOpTo = " <= "; } fq += (fq.length > 0 ? " " + filterOp + " " : "") + rangeField[0] + equalityOpTo + "\"" + selectedToValue + "\""; fq = "&fq=" + StringUtils.URIEncode(fq); } } else { if (selectedFromValue) { fq += (fq.length > 0 ? " " + filterOp + " " : "") + rangeField[0] + equalityOpFrom + "\"" + selectedFromValue + "\""; // fq = "&fq=" + StringUtils.URIEncode(fq); } if (selectedToValue) { fq += (fq.length > 0 ? " " + filterOp + " " : "") + rangeField[1] + equalityOpTo + "\"" + selectedToValue + "\""; // fq = "&fq=" + StringUtils.URIEncode(fq); } if (selectedFromValue || selectedToValue) { fq = "&fq=" + StringUtils.URIEncode(fq); } } return fq; } /** * Sets parameterNames and parameterValues arrays * used in paging, advanced search link, Goto() * @param filters either query filters or filters defined by the URL parameters * @param rangeFilters defined by the URL parameters * @param staticFilters * @param includePage */ buildPageURLParameters(filters: Filter[], rangeFilters: RangeFilter[], staticFilters: Filter[], includePage: boolean) { this.parameterNames.splice(0, this.parameterNames.length); this.parameterValues.splice(0, this.parameterValues.length); for (var i = 0; i < this.selectedFields.length; i++) { //default operator is and 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) : '')); if(!this.selectedFields[i].includes) { this.parameterNames.push("fo" + i); this.parameterValues.push("not"); } this.parameterNames.push("fv" + i); } if (this.selectedFields[i].type == "date") { if (this.selectedFields[i].dateValue.type == "range") { this.parameterValues.push(StringUtils.URIEncode("range" + Dates.getDateToString(this.selectedFields[i].dateValue.from) + ":" + Dates.getDateToString(this.selectedFields[i].dateValue.to))); } else { this.parameterValues.push(StringUtils.URIEncode(this.selectedFields[i].dateValue.type)); } } 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 && this.searchUtils.page != 1) { this.parameterNames.push("page"); this.parameterValues.push("" + this.searchUtils.page); } if (this.searchUtils.size != this.searchUtils.defaultSize) { this.parameterNames.push("size"); this.parameterValues.push("" + this.searchUtils.size); } //if (this.sort && this.searchUtils.sortBy) { if (this.sort && this.sortedByChanged && this.sortedByChanged.length > 0) { this.parameterNames.push("sortBy"); //this.parameterValues.push(this.searchUtils.sortBy); this.parameterValues.push(this.sortedByChanged); } for (let filter of staticFilters) { var filterLimits = ""; if (filter.countSelectedValues > 0) { for (let value of filter.values) { if (value.selected == true) { filterLimits += ((filterLimits.length == 0) ? '' : ',') + '"' + StringUtils.URIEncode(value.id) + '"'; } } if (filterLimits.length > 0) { this.parameterNames.push(filter.filterId); this.parameterValues.push(filterLimits); } } } // if (this.resultTypes && // ( // (this.entityType == 'publication' || this.entityType == 'dataset' || this.entityType == 'software' || this.entityType == 'other' || this.entityType == "result") // || // (this.entityType == "service") // ) // ) { // 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) { for (let value of filter.values) { if (value.selected == true) { filterLimits += ((filterLimits.length == 0) ? '' : ',') + '"' + StringUtils.URIEncode(value.id) + '"'; } } if (filterLimits.length > 0) { this.parameterNames.push(filter.filterId); this.parameterValues.push(filterLimits); } } } for (let filter of rangeFilters) { var filterLimits = ""; let yearFrom: string = (Dates.isValidYear(filter.selectedFromValue) ? filter.selectedFromValue : null); let yearTo: string = (Dates.isValidYear(filter.selectedToValue) ? filter.selectedToValue : null); if (yearFrom || yearTo) { this.parameterNames.push(filter.filterId); this.parameterValues.push("range" + (yearFrom ? yearFrom : "") + ":" + (yearTo ? yearTo : "")); } // if (filter.countSelectedValues > 0) { // for (let value of filter.values) { // if (value.selected == true) { // filterLimits += ((filterLimits.length == 0) ? '' : ',') + '"' + (value.id) + '"'; // } // } // if (filterLimits.length > 0) { // this.parameterNames.push(filter.filterId); // this.parameterValues.push(filterLimits); // } // } } if (this.searchUtils.keyword.length > 0) { this.parameterNames.push("keyword"); this.parameterValues.push(this.searchUtils.keyword); } // if (this.searchUtils.size != this.resultsPerPage) { // // allLimits += ((allLimits.length == 0) ? '?' : '&') + 'size=' + this.searchUtils.size; // this.parameterNames.push("size"); // this.parameterValues.push("" + this.searchUtils.size); // } // if (this.sort && this.searchUtils.sortBy) { // // allLimits += ((allLimits.length == 0) ? '?' : '&') + 'sortBy=' + this.searchUtils.sortBy; // this.parameterNames.push("sortBy"); // this.parameterValues.push(this.searchUtils.sortBy); // } // console.log(this.parameterNames) // console.log(this.parameterValues) } /** * create filters based on URL params * @param URLparams */ getRefineFiltersFromURL(URLparams) { let fields = new SearchFields(); let filters: Filter[] = []; let staticFilters: Filter[] = []; for (let i = 0; i < this.refineFields.length; i++) { let filterId = this.refineFields[i]; if (URLparams[filterId] != undefined) { let filter = new Filter(); filter.title = fields.getFieldName(filterId, this.entityType); filter.filterId = filterId; filter.originalFilterId = filterId; filter.values = []; let values = StringUtils.URIDecode(URLparams[filterId]).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/, -1); for (let value of values) { let v: Value = new Value(); v.name = RefineResultsUtils.keepPartAfterCharacters(StringUtils.unquote(value), "||"); v.name = (v.name.indexOf("::") != -1) ? v.name.substring(v.name.indexOf("::") + 2).split("::").join("|") : v.name; // for funding streams v.id = StringUtils.unquote(value); v.selected = true; filter.values.push(v); // console.log(v) filter.countSelectedValues++; } filters.push(filter) } } /* 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); filter.filterId = this.quickFilter.filterId; filter.originalFilterId = this.quickFilter.filterId; filter.values = []; let v: Value = new Value(); v.name = this.quickFilter.value; v.id = this.quickFilter.value; v.selected = true; filter.values.push(v); filter.countSelectedValues = 1; filters.push(filter) } }*/ for (let i = 0; i < this.staticFields.length; i++) { let filterId = this.staticFields[i]; if (URLparams[filterId] != undefined) { let filter = new Filter(); filter.title = fields.getFieldName(filterId, this.entityType); filter.filterId = filterId; filter.originalFilterId = filterId; filter.values = []; let values = StringUtils.URIDecode(URLparams[filterId]).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/, -1); for (let value of values) { let v: Value = new Value(); v.name = RefineResultsUtils.keepPartAfterCharacters(StringUtils.unquote(value), "||"); v.name = (v.name.indexOf("::") != -1) ? v.name.substring(v.name.indexOf("::") + 2).split("::").join("|") : v.name; // for funding streams v.id = StringUtils.unquote(value); v.selected = true; filter.values.push(v); filter.countSelectedValues++; } staticFilters.push(filter) } } // let options = null; // if ((this.entityType == 'publication' || this.entityType == 'dataset' || this.entityType == 'software' || this.entityType == 'other' || this.entityType == "result")) { // options = this.resultTypeOptions; // } else if (this.entityType == "service") { // options = this.serviceTypeOptions; // } // if (options) { // this.resultTypes = {values:[],filterId:"type", countSelectedValues: 0, filterType: 'checkbox', type:'checkBox', originalFilterId: "", valueIsExact: true, title: "Type",filterOperator:"or"}; // for (let typeOption of Object.keys(options)) { // let type = typeOption; // if ( URLparams["type"] && URLparams["type"].indexOf(type)==-1 || !URLparams["type"]) { // this.resultTypes.values.push({ // name: options[StringUtils.unquote(type)].name, // id: StringUtils.unquote(type), // selected: false, // number: 0 // }); // }else{ // this.resultTypes.values.push({ // name: options[StringUtils.unquote(type)].name, // id: StringUtils.unquote(type), // selected: true, // number: 0 // }); // this.resultTypes.countSelectedValues++; // } // } // } this.URLCreatedFilters = filters; this.URLCreatedStaticFilters = staticFilters; } /** * create range filters based on URL params * @param URLparams */ getRangeFiltersFromURL(URLparams) { let fields = new SearchFields(); let filters: RangeFilter[] = []; for (let i = 0; i < this.rangeFields.length; i++) { let filterId = this.rangeFields[i][0] + "-range-" + this.rangeFields[i][1]; let filterParam = fields.getFieldParam(filterId, this.entityType); //console.log("rangeFilter (from url): filterId - filterParam"); //console.log(filterId + " - "+ filterParam); if (URLparams[filterParam] != undefined) { let filter = new RangeFilter(); filter.title = fields.getFieldName(filterId, this.entityType); filter.filterId = filterParam; filter.originalFilterIdFrom = this.rangeFields[i][0]; filter.originalFilterIdTo = this.rangeFields[i][1]; let values = (decodeURIComponent(URLparams[filterParam])).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/, -1); for (let j = 0; j < values.length; j++) { if (this.fieldIdsMap[filterId].filterType == "range") { let value: string = StringUtils.unquote(values[j]); let validDates: boolean = true; // if (value.length < 14) { // validDates = false; // } else { // if (!Dates.isValidYear(value.substring(5, 9)) || !Dates.isValidYear(value.substring(10, 14))) { // validDates = false; // } else { // filter.selectedFromValue = value.substring(5, 9); // filter.selectedToValue = value.substring(10, 14); // } // } let years: string[] = (value.substring(5)).split(":"); let yearFrom: string = (Dates.isValidYear(years[0]) ? years[0] : null); let yearTo: string = (Dates.isValidYear(years[1]) ? years[1] : null); //console.log("getRangeFiltersFromURL: yearFrom: " + yearFrom + " - yearTo: "+yearTo); if (yearFrom) { filter.selectedFromValue = yearFrom; //filter.selectedFromAndToValues = yearFrom; } /*if(yearFrom && yearTo) { filter.selectedFromAndToValues += "-"; }*/ if (yearTo) { filter.selectedToValue = yearTo; //filter.selectedFromAndToValues += yearTo; } //console.log("filter.selectedFromAndToValues: "+filter.selectedFromAndToValues); if (!yearFrom && !yearTo) { validDates = false; } } } //console.log(filters); filters.push(filter) } } // console.log("Empty Filters"); // console.log(filters); this.URLCreatedRangeFilters = filters; // return filters; } /** * Checks if query has no results, display Filters from URL parameters * Mark checked the selected filters * Count the checked * @param filters */ public prepareFiltersToShow(filters: Filter[], totalResults): Filter[] { if (this.URLCreatedFilters.length > 0 && totalResults == 0) { this.showUnknownFilters = true; this.filters = this.URLCreatedFilters; } else if (totalResults != 0) { this.showUnknownFilters = false; this.filters = filters; } else if ((this.URLCreatedFilters.length == 0 && totalResults == 0)) { this.showUnknownFilters = true; this.filters = filters; } this.buildPageURLParameters(this.URLCreatedFilters, this.URLCreatedRangeFilters, this.URLCreatedStaticFilters, true); //this.checkSelectedRangeFilters(this.rangeFilters); this.checkSelectedFilters(this.filters); this.countSelectedFilters(this.filters); this.updateMeta(this.pageTitle); this.cdr.detectChanges(); return this.filters; } /** * Mark checked the selected range filters */ public prepareRangeFiltersToShow() { this.rangeFilters = RangeFilter.parse(this.rangeFields, this.entityType); // OK //this.buildPageURLRangeParameters(this.rangeFilters, true); this.checkSelectedRangeFilters(this.rangeFilters); this.countSelectedRangeFilters(this.rangeFilters); return this.rangeFilters; } public prepareStaticFiltersToShow() { var selected_filters: Map = this.getSelectedFilters(); if (selected_filters.size == 0) { selected_filters = this.getSelectedParameters(); } var selected_static_filters: Map = this.getSelectedStaticFilters(); if (selected_static_filters.size == 0) { selected_static_filters = this.getSelectedStaticParameters(); } let all_selected_filters = new Map([...selected_filters, ...selected_static_filters]); // let all_selected_filters = selected_filters.concat(selected_static_filters); let staticFields: string[] = []; for (var i = 0; i < this.staticFields.length; i++) { var dependentTo = this.searchFieldsHelper.DEPENDENT_FIELDS[this.staticFields[i]]; var dependentToValues = this.searchFieldsHelper.DEPENDENT_FIELDS_AND_VALUES[this.staticFields[i]]; // TODO check again the checks //if filter is not marked as hidden OR it is hidden but it is dependent to a field that it IS selected if (this.searchFieldsHelper.HIDDEN_FIELDS.indexOf(this.staticFields[i]) == -1 || (all_selected_filters.has(this.staticFields[i])) || (!dependentTo && !dependentToValues) || (all_selected_filters.has(dependentTo)) || (dependentToValues && (all_selected_filters.has(dependentToValues.field) && dependentToValues.values.some(dependentValue=> all_selected_filters.get(dependentToValues.field).includes(dependentValue)))) ) { staticFields.push(this.staticFields[i]); } } this.staticFilters = RefineResultsUtils.parse(this.staticFieldValues, staticFields, this.entityType, "search", true); this.checkSelectedStaticFilters(this.staticFilters); this.countSelectedStaticFilters(this.staticFilters); this.cdr.detectChanges(); return this.staticFilters; } /** * Used to set the variables and search page, and prepare it before the getResults query * @param fieldIds * @param selectedFields * @param refineFields * @param rangeFields * @param fieldIdsMap * @param customFilter * @param params * @param entityType * @param quickFilter */ prepareSearchPage(fieldIds, selectedFields, refineFields, rangeFields, staticFields, fieldIdsMap, customFilter, params, entityType, quickFilter = null) { // console.log(this.refineFields); this.entityType = entityType; this.fieldIds = fieldIds; this.selectedFields = selectedFields; this.refineFields = refineFields; this.rangeFields = rangeFields; this.staticFields = staticFields; this.fieldIdsMap = fieldIdsMap; this.customFilter = customFilter; this.quickFilter = quickFilter; this.getRangeFiltersFromURL(params); this.getRefineFiltersFromURL(params); // this.cdr.detectChanges(); this.createAdvancedSearchSelectedFiltersFromURLParameters(params); this.searchTerm = ''; if(params && params['fv0'] && params['f0'] && params['f0'] == 'q'){ let keyword = StringUtils.URIDecode(params['fv0']); this.searchTerm = keyword; } if(params){ this.advancedSearchTerms = Object.keys(params).filter(key => key.includes('fv')).length; } } removeResultType(type) { for (let value of this.resultTypes.values) { if (type == value.id && value.selected) { value.selected = false; this.goTo(1); break; } } } totalPages(totalResults: number): number { let totalPages: any = totalResults / (this.searchUtils.size); if (!(Number.isInteger(totalPages))) { totalPages = (parseInt(totalPages, 10) + 1); } return totalPages; } public getFilterById(filterId: string): Filter { return this.filters.find(filter => filter.filterId == filterId); } detectChanges() { this.cdr.detectChanges(); } toggleView(compact) { if(compact != this.compactView) { this.compactView = compact; } } }