import {ChangeDetectorRef, Component, EventEmitter, Input, Output, ViewChild} from '@angular/core'; import {ActivatedRoute} from '@angular/router'; import {AdvancedField, Filter} from './searchUtils/searchHelperClasses.class'; import {SearchDataprovidersService} from '../services/searchDataproviders.service'; import {ErrorCodes} from '../utils/properties/errorCodes'; import {ErrorMessagesComponent} from '../utils/errorMessages.component'; import {OpenaireEntities, SearchFields} from '../utils/properties/searchFields'; import {SearchCustomFilter, SearchUtilsClass} from './searchUtils/searchUtils.class'; import {EnvProperties} from '../utils/properties/env-properties'; import {NewSearchPageComponent, SearchForm} from "./searchUtils/newSearchPage.component"; import {DatasourcesHelperClass} from "./searchUtils/datasourcesHelper.class"; import {properties} from "../../../environments/environment"; import {RefineResultsUtils} from "../services/servicesUtils/refineResults.class"; import {RefineFieldResultsService} from "../services/refineFieldResults.service"; import {zip} from "rxjs"; @Component({ selector: 'search-dataproviders', template: ` ` }) export class SearchDataProvidersComponent { private errorCodes: ErrorCodes; private errorMessages: ErrorMessagesComponent; @Input() customFilters: SearchCustomFilter[] = null; @Input() set customFilter(customFilter: SearchCustomFilter | SearchCustomFilter[]) { if(!Array.isArray(customFilter)) { this.customFilters = customFilter?[customFilter]:null; }else{ this.customFilters = customFilter; } } @Input() tableViewLink; @Input() searchForm: SearchForm = {class: 'search-form', dark: true}; public results =[]; public filters =[]; public searchUtils:SearchUtilsClass = new SearchUtilsClass(); public searchFields:SearchFields = new SearchFields(); public fieldIds: string[] = this.searchFields.DATASOURCE_ADVANCED_FIELDS; public fieldIdsMap= this.searchFields.DATASOURCE_FIELDS; public selectedFields:AdvancedField[] = []; public resourcesQuery = "(oaftype exact datasource)"; public csvParams: string; public disableForms: boolean = false; public disableRefineForms: boolean = false; public loadPaging: boolean = true; public oldTotalResults: number = 0; public pagingLimit: number = 0; properties:EnvProperties = properties; public openaireEntities = OpenaireEntities; @Input() type: "all" | "registries" | "journals" | "compatible" | "deposit" | "services" = "all"; @Input() entityType: "dataprovider" | "service" = "dataprovider"; @Input() typeName = OpenaireEntities.DATASOURCES; public refineFields: string[]; pageTitle; @ViewChild(NewSearchPageComponent, { static: true }) searchPage: NewSearchPageComponent; @Input() simpleView: boolean = true; @Input() simpleSearchLink: string = ""; advancedSearchLink: string = ""; csvPath: string = ""; @Input() hasPrefix: boolean = true; @Input() openaireLink: string = null; @Input() includeOnlyResultsAndFilter: boolean = false; @Output() searchPageUpdates = new EventEmitter(); @Input() showSwitchSearchLink:boolean; @Input() showBreadcrumb: boolean = false; subs: any[] = []; searchResultsSub: any; searchFiltersSub: any; metaDescription = []; public staticFields: string[] = []; public staticFieldValues = this.searchFields.DATASOURCE_STATIC_FIELD_VALUES; public staticFilters = []; private refineQuery: string = ""; constructor (private route: ActivatedRoute, private _searchDataProvidersService: SearchDataprovidersService, private _refineFieldsResultsService: RefineFieldResultsService, private cdr: ChangeDetectorRef) { this.results =[]; this.errorCodes = new ErrorCodes(); this.errorMessages = new ErrorMessagesComponent(); this.searchUtils.status = this.errorCodes.LOADING; this.searchFields.sortFieldsByName(this.fieldIds, this.fieldIdsMap); } ngOnInit() { this.refineFields = DatasourcesHelperClass.getrefineFields(this.type); this.staticFields = this.entityType == "service" ? this.searchFields.DATASOURCE_STATIC_FIELDS : []; this.staticFilters = RefineResultsUtils.parse(this.staticFieldValues, this.staticFields, this.entityType, "search", true); this.pageTitle = DatasourcesHelperClass.getTitle(this.type); this.metaDescription = DatasourcesHelperClass.getDescription(this.type) if(this.showSwitchSearchLink == null){ this.showSwitchSearchLink = (this.type == "all" || this.type == "services"); } this.csvPath = this.entityType == "service" ? OpenaireEntities.SERVICES_FILE : OpenaireEntities.DATASOURCES_FILE; if (!this.simpleSearchLink) { this.simpleSearchLink = this.entityType == "service" ? this.properties.searchLinkToServices : this.properties.searchLinkToDataProviders; } this.advancedSearchLink = this.entityType == "service" ? this.properties.searchLinkToAdvancedServices : this.properties.searchLinkToAdvancedDataProviders; this.searchUtils.baseUrl = (this.simpleView)?this.simpleSearchLink:this.advancedSearchLink; this.pagingLimit = properties.pagingLimit; let firstLoad = true; this.subs.push(this.route.queryParams.subscribe(params => { this.loadPaging = true; if(params['page'] && this.searchUtils.page != params['page']) { this.loadPaging = false; this.oldTotalResults = this.searchUtils.totalResults; } var refine = true; if(this.searchPage.searchUtils.refineStatus == this.errorCodes.DONE) { if (params['page'] != undefined && this.filters && !firstLoad && this.searchUtils.page != +params['page']) { refine = false; } if (params['size'] != undefined && this.filters && !firstLoad && this.searchUtils.size != params['size']) { refine = false; } } let page = (params['page']=== undefined)?0:+params['page']; this.searchUtils.page = ( page < 1 ) ? 1 : page; this.searchUtils.validateSize(params['size']); this.searchPage.fieldIds = this.fieldIds; this.selectedFields =[]; if(this.type == "deposit"){ this.searchPage.keywordFields = this.searchFields.DEPOSIT_DATASOURCE_KEYWORD_FIELDS; this.searchPage.usedBy = "deposit"; } this.searchPage.prepareSearchPage(this.fieldIds, this.selectedFields, this.refineFields, [],this.staticFields, this.fieldIdsMap,this.customFilters,params, this.entityType); if(refine) { this._getFilters(this.searchPage.getSearchAPIQueryForAdvancedSearhFields(params), this.searchUtils.page, 0, true, this.searchPage.getSearchAPIQueryForRefineFields(params, firstLoad)); } else { this.searchUtils.refineStatus = this.errorCodes.DONE; } this.getResults(this.searchPage.getSearchAPIQueryForAdvancedSearhFields(params), this.searchUtils.page, this.searchUtils.size, refine, this.searchPage.getSearchAPIQueryForRefineFields(params, firstLoad)); firstLoad = false; this.refineQuery = this.searchPage.getSearchAPIQueryForRangeFields(params)+this.searchPage.getSearchAPIQueryForRefineFields(params, firstLoad); })); } ngOnDestroy() { if(this.searchResultsSub) { this.searchResultsSub.unsubscribe(); } if(this.searchFiltersSub) { this.searchFiltersSub.unsubscribe(); } for (let sub of this.subs) { sub.unsubscribe(); } } public _getFilters(parameters:string, page: number, size: number, refine: boolean, refineFieldsFilterQuery = null){ if (page <= this.pagingLimit || this.searchUtils.refineStatus == this.errorCodes.LOADING) { this.searchUtils.refineStatus = this.errorCodes.LOADING; this.disableRefineForms = true; this.searchPageUpdates.emit({disableForms: this.disableForms, disableRefineForms: this.disableRefineForms, searchUtils: this.searchUtils}); let datasourceQueryPrefix = DatasourcesHelperClass.getQueryPrefix(this.type); let isDeposit: boolean = (this.type == "deposit"); let parametersFull; let refineQueryFull; if(isDeposit) { parametersFull = datasourceQueryPrefix +(datasourceQueryPrefix.length > 0 && parameters.length > 0 ?' and (':'') + parameters +(datasourceQueryPrefix.length > 0 && parameters.length > 0 ?' ) ':''); refineQueryFull = refineFieldsFilterQuery; } else { parametersFull = parameters; refineQueryFull = refineFieldsFilterQuery+(refineFieldsFilterQuery.length > 0 && datasourceQueryPrefix.length >0 ? "&" : "")+(datasourceQueryPrefix.length>0 ? "fq=" : "")+datasourceQueryPrefix; } let filterQueries; let filterIds = []; let fields = this.searchPage.getFields(); for(let filter of this.searchPage.URLCreatedFilters) { filterIds.push(filter.filterId); fields = fields.filter(field => field != filter.filterId); } if(filterIds.length > 0) { filterQueries = zip(this._searchDataProvidersService.advancedSearchDataproviders(parametersFull, page, size, this.properties, (refine) ? this.searchPage.getRefineFieldsQuery(filterIds) : null, filterIds, refineQueryFull, isDeposit, false), this._searchDataProvidersService.advancedSearchDataproviders(parametersFull, page, size, this.properties, (refine) ? this.searchPage.getRefineFieldsQuery(fields) : null, fields, refineQueryFull, isDeposit, true) ); } else { filterQueries = this._searchDataProvidersService.advancedSearchDataproviders(parametersFull, page, size, this.properties, (refine) ? this.searchPage.getRefineFieldsQuery(fields) : null, fields, refineQueryFull, isDeposit, true) } this.searchFiltersSub = filterQueries.subscribe( data => { let totalResults = filterIds.length > 0 ? data[0][0] : data[0]; let filters = filterIds.length > 0 ? data[0][2].concat(data[1][2]) : data[2]; this.filtersReturned(refine, filters, totalResults, page); }, err => { this.filters = this.searchPage.prepareFiltersToShow([], 0); this.staticFilters = this.searchPage.prepareStaticFiltersToShow(); this.handleError("Error getting refine filters for "+OpenaireEntities.DATASOURCES+": ", err); this.searchUtils.refineStatus = this.errorMessages.getErrorCode(err.status); this.disableRefineForms = false; this.searchPageUpdates.emit({disableForms: this.disableForms, disableRefineForms: this.disableRefineForms, searchUtils: this.searchUtils}) } ); } } public filtersReturned(refine: boolean, filters: Filter[], totalResults, page: number) { if (refine) { this.filters = this.searchPage.prepareFiltersToShow(filters, totalResults); this.staticFilters = this.searchPage.prepareStaticFiltersToShow(); } this.searchUtils.refineStatus = this.errorCodes.DONE; if(totalResults == 0) { this.searchUtils.refineStatus = this.errorCodes.NONE; } if (this.searchUtils.refineStatus == this.errorCodes.DONE) { // Page out of limit!!! let totalPages: any = totalResults / (this.searchUtils.size); if (!(Number.isInteger(totalPages))) { totalPages = (parseInt(totalPages, 10) + 1); } if (totalPages < page) { this.searchUtils.refineStatus = this.errorCodes.OUT_OF_BOUND; } } if(this.searchUtils.refineStatus != this.errorCodes.DONE && this.searchUtils.status != this.searchUtils.refineStatus) { if (this.searchResultsSub) { this.searchResultsSub.unsubscribe(); } this.resultsReturned(refine, [], totalResults, page); } this.disableRefineForms = false; this.searchPageUpdates.emit({disableForms: this.disableForms, disableRefineForms: this.disableRefineForms, searchUtils: this.searchUtils}) } public getResults(parameters:string, page: number, size: number, refine: boolean, refineFieldsFilterQuery = null){ if(page > this.pagingLimit ) { size=0; } if(page <= this.pagingLimit || this.searchUtils.status == this.errorCodes.LOADING) { this.csvParams = (parameters ? ("&fq=("+parameters) : "") + (parameters ? ")" : ""); this.csvParams += (refineFieldsFilterQuery ? refineFieldsFilterQuery : ""); this.searchUtils.status = this.errorCodes.LOADING; this.disableForms = true; this.searchPageUpdates.emit({disableForms: this.disableForms, disableRefineForms: this.disableRefineForms, searchUtils: this.searchUtils}); this.results = []; this.searchUtils.totalResults = 0; let datasourceQueryPrefix = DatasourcesHelperClass.getQueryPrefix(this.type); let isDeposit: boolean = (this.type == "deposit"); let parametersFull; let refineQueryFull; if(isDeposit) { parametersFull = datasourceQueryPrefix +(datasourceQueryPrefix.length > 0 && parameters.length > 0 ?' and (':'') + parameters +(datasourceQueryPrefix.length > 0 && parameters.length > 0 ?' ) ':''); refineQueryFull = refineFieldsFilterQuery; } else { parametersFull = parameters; refineQueryFull = refineFieldsFilterQuery+(refineFieldsFilterQuery.length > 0 && datasourceQueryPrefix.length >0 ? "&" : "")+(datasourceQueryPrefix.length>0 ? "fq=" : "")+datasourceQueryPrefix; } this.searchResultsSub = this._searchDataProvidersService.advancedSearchDataproviders( parametersFull, page, size, this.properties, null, this.searchPage.getFields(), refineQueryFull, isDeposit).subscribe( data => { let totalResults = data[0]; let results = data[1]; this.resultsReturned(refine, results, totalResults, page); }, err => { //console.log(err); this.handleError("Error getting "+OpenaireEntities.DATASOURCES, err); this.searchUtils.status = this.errorMessages.getErrorCode(err.status); //TODO check erros (service not available, bad request) // if( ){ // this.searchUtils.status = errorCodes.ERROR; // } //var errorCodes:ErrorCodes = new ErrorCodes(); //this.searchUtils.status = errorCodes.NOT_AVAILABLE; /*if(err.status == '404') { this.searchUtils.status = this.errorCodes.NOT_FOUND; } else if(err.status == '500') { this.searchUtils.status = this.errorCodes.ERROR; } else { this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; }*/ //this.searchPage.closeLoading(); this.disableForms = false; this.searchPageUpdates.emit({disableForms: this.disableForms, disableRefineForms: this.disableRefineForms, searchUtils: this.searchUtils}); this.searchPage.hideFilters = false; } ); } } public resultsReturned(refine: boolean, results: any, totalResults, page: number) { this.searchUtils.totalResults = totalResults; this.results = results; if(!refine) { this.searchPage.buildPageURLParameters(this.filters, [], this.staticFilters, false); } this.searchPage.hideFilters = false; this.searchUtils.status = this.errorCodes.DONE; if (this.searchUtils.totalResults == 0) { this.searchUtils.status = this.errorCodes.NONE; } if (this.searchUtils.status == this.errorCodes.DONE) { // Page out of limit!!! let totalPages: any = this.searchUtils.totalResults / (this.searchUtils.size); if (!(Number.isInteger(totalPages))) { totalPages = (parseInt(totalPages, 10) + 1); } if (totalPages < page) { this.searchUtils.totalResults = 0; this.searchUtils.status = this.errorCodes.OUT_OF_BOUND; } } if(this.searchUtils.status != this.errorCodes.DONE && this.searchUtils.refineStatus != this.searchUtils.status) { if(this.searchFiltersSub) { this.searchFiltersSub.unsubscribe(); } this.filtersReturned(refine, [], totalResults, page); } this.disableForms = false; this.searchPageUpdates.emit({disableForms: this.disableForms, disableRefineForms: this.disableRefineForms, searchUtils: this.searchUtils}); } private handleError(message: string, error) { console.error(OpenaireEntities.DATASOURCES+" advanced Search Page: "+message, error); } public filterRequestedAll(oldFilter: Filter) { let fieldsStr: string = "&fields=" + oldFilter.filterId+"&refine=true"; this.searchFiltersSub = this._searchDataProvidersService.advancedSearchDataproviders(this.searchPage.getSearchAPIQueryForAdvancedSearhFields(), 1, 0, properties, fieldsStr, [oldFilter.filterId], this.refineQuery).subscribe( // this.searchFiltersSub = this._refineFieldsResultsService.getAllRefineFieldResultsByFieldName(oldFilter.filterId, this.entityType, this.properties, this.refineQuery).subscribe( res => { let filter: Filter = res[2][0]; if(filter.values.length == 0) { filter = oldFilter; filter.countAllValues = 0; } else { filter.countAllValues = filter.values.length; // console.log(filter); for (let value of filter.values) { for (let oldValue of oldFilter.values) { if (oldValue.id == value.id && oldValue.selected) { value.selected = true; break; } } } } let index: number = this.filters.findIndex((fltr: Filter) => fltr.filterId == filter.filterId); filter.isViewAllOpen = true; this.filters[index] = filter; this.cdr.detectChanges(); }, error => { let index: number = this.filters.findIndex((fltr: Filter) => fltr.filterId == oldFilter.filterId); oldFilter.countAllValues = 0; this.filters[index] = oldFilter; this.cdr.detectChanges(); } ) } }