From f1e46be3cc57845fb3137b76d651f5485409a8d0 Mon Sep 17 00:00:00 2001 From: "konstantina.galouni" Date: Tue, 20 Oct 2020 14:47:54 +0000 Subject: [PATCH] [Trunk | Library]: 1. contexts.service.ts: Add BehaviorSubject for getting communities (with status) only once (providedIn: 'root') - used by searchResearchResults.component.ts & claimContextSearchForm.component.ts. 2. claimContextSearchForm.component.ts & claimContextSearchForm.module.ts: Use 'getPublicCommunitiesByState()' instead of 'getPublicCommunities()' (contexts.service.ts) | Do not import in module (singlet$ 3. refineResults.class.ts: In 'includeValue()' add checks if name is empty or undefined (do not include filter value in that case). 4. searchResearchResults.component.ts: For 'community' filter, add query for getting communities with public status and filtering values accordingly (timeout 300ms after filters request is over). 5. searchResearchResults.component.ts: & searchDataProviders.component.ts & searchOrganizations.component.ts & searchProjects.component.ts: Add methods "filtersReturned()" and "resultsReturned()" - when refine or search query returns with no results or page is out of bounds, stop the other query and initialize statuses and values (stop loading when we know there are no results). 6. newSearchPage.component.html: Improve some checks to better display filters and results (out of bounds message, loading for filters, etc..). git-svn-id: https://svn.driver.research-infrastructures.eu/driver/dnet40/modules/uoa-services-library/trunk/ng-openaire-library/src/app@59648 d315682c-612b-4755-9ff5-7f18f6832af3 --- .../claimContextSearchForm.component.ts | 2 +- .../claimContextSearchForm.module.ts | 2 - .../claim-utils/service/contexts.service.ts | 56 ++++- searchPages/searchDataProviders.component.ts | 136 +++++++---- searchPages/searchOrganizations.component.ts | 131 +++++++---- searchPages/searchProjects.component.ts | 137 +++++++---- .../searchResearchResults.component.ts | 222 ++++++++++++++---- .../searchUtils/newSearchPage.component.html | 4 +- services/servicesUtils/refineResults.class.ts | 2 +- 9 files changed, 498 insertions(+), 194 deletions(-) diff --git a/claims/claim-utils/claimContextSearchForm.component.ts b/claims/claim-utils/claimContextSearchForm.component.ts index 95e3234b..7fc318d8 100644 --- a/claims/claim-utils/claimContextSearchForm.component.ts +++ b/claims/claim-utils/claimContextSearchForm.component.ts @@ -114,7 +114,7 @@ export class ClaimContextSearchFormComponent { } else { this.loading = true; - this._contextService.getPublicCommunities(this.properties.contextsAPI).subscribe( + this._contextService.getPublicCommunitiesByState().subscribe( data => { this.communities = data; if (this.communities.length > 0) { diff --git a/claims/claim-utils/claimContextSearchForm.module.ts b/claims/claim-utils/claimContextSearchForm.module.ts index bb10f27e..1f49f66c 100644 --- a/claims/claim-utils/claimContextSearchForm.module.ts +++ b/claims/claim-utils/claimContextSearchForm.module.ts @@ -2,7 +2,6 @@ import { NgModule } from '@angular/core'; import { SharedModule } from '../../shared/shared.module'; import { ClaimContextSearchFormComponent } from './claimContextSearchForm.component'; - import{ContextsServiceModule} from './service/contextsService.module'; import {StaticAutocompleteModule} from '../../utils/staticAutoComplete/staticAutoComplete.module'; import { RouterModule } from '@angular/router'; import {HelperModule} from '../../utils/helper/helper.module'; @@ -10,7 +9,6 @@ import { ClaimContextSearchFormComponent } from './claimContextSearchForm.compon @NgModule({ imports: [ SharedModule,RouterModule, - ContextsServiceModule, StaticAutocompleteModule, HelperModule diff --git a/claims/claim-utils/service/contexts.service.ts b/claims/claim-utils/service/contexts.service.ts index e73b7cf2..1e2d0266 100644 --- a/claims/claim-utils/service/contexts.service.ts +++ b/claims/claim-utils/service/contexts.service.ts @@ -1,13 +1,25 @@ -import {throwError as observableThrowError} from 'rxjs'; +import {BehaviorSubject, from, Observable, Subscription, throwError as observableThrowError} from 'rxjs'; import {Injectable} from '@angular/core'; import {Response} from '@angular/http'; import {HttpClient} from '@angular/common/http'; import {catchError, map} from "rxjs/operators"; -@Injectable() +import {properties} from "../../../../../environments/environment"; + +@Injectable({ providedIn: 'root' }) export class ContextsService { + private communitiesSubject: BehaviorSubject = new BehaviorSubject(null); + private promise: Promise; + private sub: Subscription = null; + constructor(private http: HttpClient ) { } + ngOnDestroy() { + if(this.sub) { + this.sub.unsubscribe(); + } + } + public getCommunities( apiUrl:string):any { let url = apiUrl + 's/'; return this.http.get(url) @@ -20,6 +32,46 @@ export class ContextsService { return this.http.get(url) .pipe(map(res => this.parseCommunities(res, false) )); } + + public initCommunities() { + let url = properties.contextsAPI + 's/'; + this.promise = new Promise((resolve => { + this.sub = this.http.get((properties.useLongCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url) + .pipe(map(res => this.parseCommunities(res, true) )) + .subscribe( + (communties) => { + this.communitiesSubject.next(communties); + resolve(); + }, + error => { + this.communitiesSubject.error(error); + resolve(); + }); + })); + + } + + async getCommunitiesByStateAsync(getAll: boolean) { + if(!this.promise) { + this.initCommunities(); + } + + await this.promise; + if(getAll) { + return this.communitiesSubject.getValue(); + } else { + return this.communitiesSubject.getValue().filter(community => community.status != 'hidden'); + } + } + + getPublicCommunitiesByState(): Observable { + return from(this.getCommunitiesByStateAsync(false)); + } + + getCommunitiesByState(): Observable { + return from(this.getCommunitiesByStateAsync(true)); + } + parseCommunities(data, getall){ var communities = []; diff --git a/searchPages/searchDataProviders.component.ts b/searchPages/searchDataProviders.component.ts index 9a24d727..02fa4f9b 100644 --- a/searchPages/searchDataProviders.component.ts +++ b/searchPages/searchDataProviders.component.ts @@ -1,6 +1,6 @@ import {Component, EventEmitter, Input, Output, ViewChild} from '@angular/core'; import {ActivatedRoute} from '@angular/router'; -import {AdvancedField} from './searchUtils/searchHelperClasses.class'; +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'; @@ -86,6 +86,8 @@ export class SearchDataProvidersComponent { @Input() showSwitchSearchLink:boolean; @Input() showBreadcrumb: boolean = false; subs: any[] = []; + searchResultsSub: any; + searchFiltersSub: any; metaDescription = []; constructor (private route: ActivatedRoute, private _searchDataProvidersService: SearchDataprovidersService ) { @@ -158,6 +160,12 @@ export class SearchDataProvidersComponent { })); } ngOnDestroy() { + if(this.searchResultsSub) { + this.searchResultsSub.unsubscribe(); + } + if(this.searchFiltersSub) { + this.searchFiltersSub.unsubscribe(); + } for (let sub of this.subs) { sub.unsubscribe(); } @@ -170,19 +178,13 @@ export class SearchDataProvidersComponent { this.searchPageUpdates.emit({disableForms: this.disableForms, disableRefineForms: this.disableRefineForms, searchUtils: this.searchUtils}); let datasourceQueryPrefix = DatasourcesHelperClass.getQueryPrefix(this.type); - this.subs.push(this._searchDataProvidersService.advancedSearchDataproviders( datasourceQueryPrefix +(datasourceQueryPrefix.length > 0 && parameters.length > 0 ?' and (':'') + parameters +(datasourceQueryPrefix.length > 0 && parameters.length > 0 ?' ) ':''), page, size, this.properties, (refine && (this.type=="all" || this.type == "deposit")) ? this.searchPage.getRefineFieldsQuery() : null, this.searchPage.getFields(), refineFieldsFilterQuery, (this.type == "deposit")) + this.searchFiltersSub = this._searchDataProvidersService.advancedSearchDataproviders( datasourceQueryPrefix +(datasourceQueryPrefix.length > 0 && parameters.length > 0 ?' and (':'') + parameters +(datasourceQueryPrefix.length > 0 && parameters.length > 0 ?' ) ':''), page, size, this.properties, (refine && (this.type=="all" || this.type == "deposit")) ? this.searchPage.getRefineFieldsQuery() : null, this.searchPage.getFields(), refineFieldsFilterQuery, (this.type == "deposit")) //.switchMap( .subscribe( data => { - if (refine) { - this.filters = this.searchPage.prepareFiltersToShow(data[2], data[0]); - } - - this.searchUtils.refineStatus = this.errorCodes.DONE; - // if (this.searchUtils.totalResults == 0) { - // this.searchUtils.status = this.errorCodes.NONE; - // } - this.disableRefineForms = false; + let totalResults = data[0]; + let filters = data[2]; + this.filtersReturned(refine, filters, totalResults, page); this.searchPageUpdates.emit({disableForms: this.disableForms, disableRefineForms: this.disableRefineForms, searchUtils: this.searchUtils}) }, err => { @@ -192,10 +194,40 @@ export class SearchDataProvidersComponent { 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.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; + } public getResults(parameters:string, page: number, size: number, refine: boolean, refineFieldsFilterQuery = null){ if(page > this.pagingLimit ) { @@ -224,46 +256,12 @@ export class SearchDataProvidersComponent { //console.info("Advanced Search for Content Providers: Execute search query "+parameters); let datasourceQueryPrefix = DatasourcesHelperClass.getQueryPrefix(this.type); //this._searchDataProvidersService.advancedSearchDataproviders( datasourceQueryPrefix +(datasourceQueryPrefix.length > 0 && parameters.length > 0 ?' and (':'') + parameters +(datasourceQueryPrefix.length > 0 && parameters.length > 0 ?' ) ':''), page, size, this.properties, (refine && (this.type=="all" || this.type == "deposit")) ? this.searchPage.getRefineFieldsQuery() : null, this.searchPage.getFields(), refineFieldsFilterQuery, (this.type == "deposit")).subscribe( - this.subs.push(this._searchDataProvidersService.advancedSearchDataproviders( datasourceQueryPrefix +(datasourceQueryPrefix.length > 0 && parameters.length > 0 ?' and (':'') + parameters +(datasourceQueryPrefix.length > 0 && parameters.length > 0 ?' ) ':''), page, size, this.properties, null, this.searchPage.getFields(), refineFieldsFilterQuery, (this.type == "deposit")).subscribe( + this.searchResultsSub = this._searchDataProvidersService.advancedSearchDataproviders( datasourceQueryPrefix +(datasourceQueryPrefix.length > 0 && parameters.length > 0 ?' and (':'') + parameters +(datasourceQueryPrefix.length > 0 && parameters.length > 0 ?' ) ':''), page, size, this.properties, null, this.searchPage.getFields(), refineFieldsFilterQuery, (this.type == "deposit")).subscribe( data => { - this.searchUtils.totalResults = data[0]; - this.results = data[1]; - //console.log(this.results); - // if (refine) { - // this.filters = - // this.searchPage.prepareFiltersToShow((this.type=="all" || this.type == "deposit")?data[2]:this.filters, this.searchUtils.totalResults); - // }else{ - if(!refine) { - this.searchPage.buildPageURLParameters(this.filters, [], false); - } else if(this.type != "all" && this.type != "deposit") { // static filters - //this.filters = this.searchPage.prepareFiltersToShow(this.filters, this.searchUtils.totalResults); - this.searchPage.prepareFiltersToShow(this.filters, this.searchUtils.totalResults); - this.searchUtils.refineStatus = this.errorCodes.DONE; - } - - this.searchPage.hideFilters = false; - - // this.searchPage.updateBaseUrlWithParameters(); - //var errorCodes:ErrorCodes = new ErrorCodes(); - this.searchUtils.status = this.errorCodes.DONE; - if(this.searchUtils.totalResults == 0 ){ - this.searchUtils.status = this.errorCodes.NONE; - } - //this.searchPage.closeLoading(); - this.disableForms = false; + let totalResults = data[0]; + let results = data[1]; + this.resultsReturned(refine, results, totalResults, page); this.searchPageUpdates.emit({disableForms: this.disableForms, disableRefineForms: this.disableRefineForms, searchUtils: this.searchUtils}); - - 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; - } - } }, err => { //console.log(err); @@ -288,10 +286,46 @@ export class SearchDataProvidersComponent { 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, [], 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; + } + private handleError(message: string, error) { console.error("Content Providers advanced Search Page: "+message, error); } diff --git a/searchPages/searchOrganizations.component.ts b/searchPages/searchOrganizations.component.ts index a7b90023..58c6b464 100644 --- a/searchPages/searchOrganizations.component.ts +++ b/searchPages/searchOrganizations.component.ts @@ -1,6 +1,6 @@ import {Component, EventEmitter, Input, Output, ViewChild} from '@angular/core'; import {ActivatedRoute} from '@angular/router'; -import {AdvancedField} from './searchUtils/searchHelperClasses.class'; +import {AdvancedField, Filter} from './searchUtils/searchHelperClasses.class'; import {SearchOrganizationsService} from '../services/searchOrganizations.service'; import {ErrorCodes} from '../utils/properties/errorCodes'; import {ErrorMessagesComponent} from '../utils/errorMessages.component'; @@ -78,6 +78,8 @@ export class SearchOrganizationsComponent { public resourcesQuery = "(oaftype exact organization)"; subs: any[] = []; + searchResultsSub: any; + searchFiltersSub: any; constructor (private route: ActivatedRoute, private _searchOrganizationsService: SearchOrganizationsService ) { this.results =[]; @@ -145,6 +147,12 @@ export class SearchOrganizationsComponent { })); } ngOnDestroy() { + if(this.searchResultsSub) { + this.searchResultsSub.unsubscribe(); + } + if(this.searchFiltersSub) { + this.searchFiltersSub.unsubscribe(); + } for (let sub of this.subs) { sub.unsubscribe(); } @@ -155,19 +163,13 @@ export class SearchOrganizationsComponent { this.searchUtils.refineStatus = this.errorCodes.LOADING; this.disableRefineForms = true; this.searchPageUpdates.emit({disableForms: this.disableForms, disableRefineForms: this.disableRefineForms, searchUtils: this.searchUtils}); - this.subs.push(this._searchOrganizationsService.advancedSearchOrganizations(parameters, page, size, this.properties,(refine) ? this.searchPage.getRefineFieldsQuery() : null, this.searchPage.getFields(), refineFieldsFilterQuery) + this.searchFiltersSub = this._searchOrganizationsService.advancedSearchOrganizations(parameters, page, size, this.properties,(refine) ? this.searchPage.getRefineFieldsQuery() : null, this.searchPage.getFields(), refineFieldsFilterQuery) //.switchMap( .subscribe( data => { - if (refine) { - this.filters = this.searchPage.prepareFiltersToShow(data[2], data[0]); - } - - this.searchUtils.refineStatus = this.errorCodes.DONE; - // if (this.searchUtils.totalResults == 0) { - // this.searchUtils.status = this.errorCodes.NONE; - // } - this.disableRefineForms = false; + let totalResults = data[0]; + let filters = data[2]; + this.filtersReturned(refine, filters, totalResults, page); this.searchPageUpdates.emit({disableForms: this.disableForms, disableRefineForms: this.disableRefineForms, searchUtils: this.searchUtils}) }, err => { @@ -177,10 +179,41 @@ export class SearchOrganizationsComponent { 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.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; + } + public getResults(parameters:string, page: number, size: number, refine: boolean, refineFieldsFilterQuery = null){ if(page > this.pagingLimit) { size=0; @@ -206,40 +239,12 @@ export class SearchOrganizationsComponent { //console.info("Advanced Search for Organizations: Execute search query "+parameters); //this._searchOrganizationsService.advancedSearchOrganizations(parameters, page, size, this.properties,(refine) ? this.searchPage.getRefineFieldsQuery() : null, this.searchPage.getFields(), refineFieldsFilterQuery).subscribe( - this.subs.push(this._searchOrganizationsService.advancedSearchOrganizations(parameters, page, size, this.properties, null, this.searchPage.getFields(), refineFieldsFilterQuery).subscribe( + this.searchResultsSub = this._searchOrganizationsService.advancedSearchOrganizations(parameters, page, size, this.properties, null, this.searchPage.getFields(), refineFieldsFilterQuery).subscribe( data => { - this.searchUtils.totalResults = data[0]; - this.results = data[1]; - // if (refine) { - // this.filters = this.searchPage.prepareFiltersToShow(data[2], this.searchUtils.totalResults); - // }else{ - if(!refine) { - this.searchPage.buildPageURLParameters(this.filters, [],false); - } - - this.searchPage.hideFilters = false; - - // this.searchPage.updateBaseUrlWithParameters(); - //var errorCodes:ErrorCodes = new ErrorCodes(); - this.searchUtils.status = this.errorCodes.DONE; - if(this.searchUtils.totalResults == 0 ){ - this.searchUtils.status = this.errorCodes.NONE; - } - //this.searchPage.closeLoading(); - this.disableForms = false; + let totalResults = data[0]; + let results = data[1]; + this.resultsReturned(refine, results, totalResults, page); this.searchPageUpdates.emit({disableForms: this.disableForms, disableRefineForms: this.disableRefineForms, searchUtils: this.searchUtils}); - - 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; - } - } }, err => { //console.log(err); @@ -265,10 +270,46 @@ export class SearchOrganizationsComponent { 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, [], 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; + } + private handleError(message: string, error) { console.error("Organizations advanced Search Page: "+message, error); } diff --git a/searchPages/searchProjects.component.ts b/searchPages/searchProjects.component.ts index 857f9258..92fb4888 100644 --- a/searchPages/searchProjects.component.ts +++ b/searchPages/searchProjects.component.ts @@ -1,6 +1,6 @@ import {Component, EventEmitter, Input, Output, ViewChild} from '@angular/core'; import {ActivatedRoute} from '@angular/router'; -import {AdvancedField} from './searchUtils/searchHelperClasses.class'; +import {AdvancedField, Filter} from './searchUtils/searchHelperClasses.class'; import {SearchProjectsService} from '../services/searchProjects.service'; import {ErrorCodes} from '../utils/properties/errorCodes'; import {ErrorMessagesComponent} from '../utils/errorMessages.component'; @@ -81,6 +81,8 @@ export class SearchProjectsComponent { @Input() showSwitchSearchLink:boolean = true; @Input() showBreadcrumb: boolean = false; subs: any[] = []; + searchResultsSub: any; + searchFiltersSub: any; constructor (private route: ActivatedRoute, private _searchProjectsService: SearchProjectsService ) { this.results =[]; @@ -143,6 +145,12 @@ export class SearchProjectsComponent { })); } ngOnDestroy() { + if(this.searchResultsSub) { + this.searchResultsSub.unsubscribe(); + } + if(this.searchFiltersSub) { + this.searchFiltersSub.unsubscribe(); + } for (let sub of this.subs) { sub.unsubscribe(); } @@ -153,20 +161,13 @@ export class SearchProjectsComponent { this.searchUtils.refineStatus = this.errorCodes.LOADING; this.disableRefineForms = true; this.searchPageUpdates.emit({disableForms: this.disableForms, disableRefineForms: this.disableRefineForms, searchUtils: this.searchUtils}); - this.subs.push(this._searchProjectsService.advancedSearchProjects(parameters, page, size, this.properties,(refine) ? this.searchPage.getRefineFieldsQuery() : null, this.searchPage.getFields(), refineFieldsFilterQuery) + this.searchFiltersSub = this._searchProjectsService.advancedSearchProjects(parameters, page, size, this.properties,(refine) ? this.searchPage.getRefineFieldsQuery() : null, this.searchPage.getFields(), refineFieldsFilterQuery) //.switchMap( .subscribe( data => { - if (refine) { - this.filters = this.searchPage.prepareFiltersToShow(data[2], data[0]); - this.rangeFilters = this.searchPage.prepareRangeFiltersToShow(); - } - - this.searchUtils.refineStatus = this.errorCodes.DONE; - // if (this.searchUtils.totalResults == 0) { - // this.searchUtils.status = this.errorCodes.NONE; - // } - this.disableRefineForms = false; + let totalResults = data[0]; + let filters = data[2]; + this.filtersReturned(refine, filters, totalResults, page); this.searchPageUpdates.emit({disableForms: this.disableForms, disableRefineForms: this.disableRefineForms, searchUtils: this.searchUtils}) }, err => { @@ -176,10 +177,43 @@ export class SearchProjectsComponent { 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.rangeFilters = this.searchPage.prepareRangeFiltersToShow(); + } + + 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; + } + public getResults(parameters:string, page: number, size: number, refine: boolean, refineFieldsFilterQuery = null){ if(page > this.pagingLimit) { size=0; @@ -205,42 +239,13 @@ export class SearchProjectsComponent { this.searchUtils.totalResults = 0; //console.info("Advanced Search for Publications: Execute search query "+parameters); - this.subs.push(this._searchProjectsService.advancedSearchProjects(parameters, page, size, this.properties,null, this.searchPage.getFields(), refineFieldsFilterQuery).subscribe( + this.searchResultsSub = this._searchProjectsService.advancedSearchProjects(parameters, page, size, this.properties,null, this.searchPage.getFields(), refineFieldsFilterQuery).subscribe( //this._searchProjectsService.advancedSearchProjects(parameters, page, size, this.properties,(refine) ? this.searchPage.getRefineFieldsQuery() : null, this.searchPage.getFields(), refineFieldsFilterQuery).subscribe( data => { - this.searchUtils.totalResults = data[0]; - this.results = data[1]; - // this.searchPage.updateBaseUrlWithParameters(); - // if (refine) { - // this.filters = this.searchPage.prepareFiltersToShow(data[2], this.searchUtils.totalResults); - // this.rangeFilters = this.searchPage.prepareRangeFiltersToShow(); - // }else{ - if(!refine) { - this.searchPage.buildPageURLParameters(this.filters, this.rangeFilters, false); - } - - this.searchPage.hideFilters = false; - - //var errorCodes:ErrorCodes = new ErrorCodes(); - this.searchUtils.status = this.errorCodes.DONE; - if(this.searchUtils.totalResults == 0 ){ - this.searchUtils.status = this.errorCodes.NONE; - } - //this.searchPage.closeLoading(); - this.disableForms = false; - this.searchPageUpdates.emit({disableForms: this.disableForms, disableRefineForms: this.disableRefineForms, searchUtils: this.searchUtils}) - - 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; - } - } + let totalResults = data[0]; + let results = data[1]; + this.resultsReturned(refine, results, totalResults, page); + this.searchPageUpdates.emit({disableForms: this.disableForms, disableRefineForms: this.disableRefineForms, searchUtils: this.searchUtils}); }, err => { //console.log(err); @@ -266,10 +271,46 @@ export class SearchProjectsComponent { 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.rangeFilters, 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; + } + private handleError(message: string, error) { console.error("Projects advanced Search Page: "+message, error); } diff --git a/searchPages/searchResearchResults.component.ts b/searchPages/searchResearchResults.component.ts index 154033c9..be1d7168 100644 --- a/searchPages/searchResearchResults.component.ts +++ b/searchPages/searchResearchResults.component.ts @@ -10,6 +10,7 @@ import {EnvProperties} from '../utils/properties/env-properties'; import {NewSearchPageComponent} from "./searchUtils/newSearchPage.component"; import {RangeFilter} from "../utils/rangeFilter/rangeFilterHelperClasses.class"; import {properties} from "../../../environments/environment"; +import {ContextsService} from "../claims/claim-utils/service/contexts.service"; @Component({ selector: 'search-research-results', @@ -89,13 +90,22 @@ export class SearchResearchResultsComponent { @Output() searchPageUpdates = new EventEmitter(); @Input() showSwitchSearchLink: boolean = true; subs: any[] = []; + searchResultsSub: any; + searchFiltersSub: any; @Input() stickyForm:boolean = false; - constructor(private route: ActivatedRoute, private _searchResearchResultsService: SearchResearchResultsService) { + + private timeoutId; + private promise: Promise = null; + private publicCommunities = null; + + constructor(private route: ActivatedRoute, private _searchResearchResultsService: SearchResearchResultsService, + private _contextService: ContextsService) { this.results = []; this.errorCodes = new ErrorCodes(); this.errorMessages = new ErrorMessagesComponent(); this.searchUtils.status = this.errorCodes.LOADING; this.searchUtils.refineStatus = this.errorCodes.LOADING; + this.getPublicCommunities(); } ngOnInit() { @@ -156,30 +166,67 @@ export class SearchResearchResultsComponent { } ngOnDestroy() { + if(this.searchResultsSub) { + this.searchResultsSub.unsubscribe(); + } + if(this.searchFiltersSub) { + this.searchFiltersSub.unsubscribe(); + } for (let sub of this.subs) { sub.unsubscribe(); } } - + + public getPublicCommunities() { + this.promise = new Promise(resolve => { + this._contextService.getPublicCommunitiesByState().subscribe( + data => { + if(this.publicCommunities == null) { + this.publicCommunities = data.map(value => value.id); + } + resolve(); + }, + error => { + this.handleError("Error getting communities status", error); + resolve(); + }); + }); + } + + racePromiseWithTimeout() { + const timeoutPromise = new Promise((_, reject) => { + this.timeoutId = setTimeout(() => { + this.publicCommunities = []; + reject(new Error('Request timed out')); + }, 300); + }); + + return Promise.race([this.promise, timeoutPromise]); + } + + public _getFilters(parameters: string, page: number, size: number, sortBy: string, 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}); - this.subs.push(this._searchResearchResultsService.advancedSearchResults(this.resultType, parameters, page, size, sortBy, this.properties, (refine) ? this.searchPage.getRefineFieldsQuery() : null, this.searchPage.getFields(), refineFieldsFilterQuery) + this.searchFiltersSub = this._searchResearchResultsService.advancedSearchResults(this.resultType, parameters, page, size, sortBy, this.properties, (refine) ? this.searchPage.getRefineFieldsQuery() : null, this.searchPage.getFields(), refineFieldsFilterQuery) + // this.subs.push(this._searchResearchResultsService.advancedSearchResults(this.resultType, parameters, page, size, sortBy, this.properties, (refine) ? this.searchPage.getRefineFieldsQuery() : null, this.searchPage.getFields(), refineFieldsFilterQuery) //.switchMap( .subscribe( data => { - if (refine) { - this.filters = this.searchPage.prepareFiltersToShow(data[2], data[0]); - this.rangeFilters = this.searchPage.prepareRangeFiltersToShow(); - } + let totalResults = data[0]; + let filters = data[2]; - this.searchUtils.refineStatus = this.errorCodes.DONE; - // if (this.searchUtils.totalResults == 0) { - // this.searchUtils.status = this.errorCodes.NONE; + // if (refine) { + // this.filters = this.searchPage.prepareFiltersToShow(filters, totalResults); + // this.rangeFilters = this.searchPage.prepareRangeFiltersToShow(); // } - this.disableRefineForms = false; + // + // this.searchUtils.refineStatus = this.errorCodes.DONE; + // + // this.disableRefineForms = false; + this.filtersReturned(refine, filters, totalResults, page); this.searchPageUpdates.emit({disableForms: this.disableForms, disableRefineForms: this.disableRefineForms, searchUtils: this.searchUtils}) }, err => { @@ -189,8 +236,69 @@ export class SearchResearchResultsComponent { this.disableRefineForms = false; this.searchPageUpdates.emit({disableForms: this.disableForms, disableRefineForms: this.disableRefineForms, searchUtils: this.searchUtils}) } - )); + );//); } + } + + public async filtersReturned(refine: boolean, filters: Filter[], totalResults, page: number) { + if(!this.timeoutId) { + try { + await this.racePromiseWithTimeout(); + } catch (error) { + this.handleError("Getting communities status was over 300ms - timeout", error); + } finally { + clearTimeout(this.timeoutId); + } + } + + let communitiesFilter = filters.find(filters => filters.filterId == "community"); + if(communitiesFilter && this.publicCommunities && this.publicCommunities.length > 0) { + communitiesFilter.values = communitiesFilter.values.filter(value => { + let valueId = ""; + if(value.id) { + let idArray = value.id.split("||"); + if(idArray) { + valueId = idArray[0]; + } + } + //for(let publicCom of this.publicCommunities) { + //if(valueId && publicCom['id'] == valueId) { + if(valueId && this.publicCommunities.includes(valueId)) { + return true; + //} + } + }); + } + + if (refine) { + this.filters = this.searchPage.prepareFiltersToShow(filters, totalResults); + this.rangeFilters = this.searchPage.prepareRangeFiltersToShow(); + } + + 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; } public _getResults(parameters: string, page: number, size: number, sortBy: string, refine: boolean, refineFieldsFilterQuery = null) { @@ -212,39 +320,33 @@ export class SearchResearchResultsComponent { this.results = []; this.searchUtils.totalResults = 0; //this.subs.push(this._searchResearchResultsService.advancedSearchResults(this.resultType, parameters, page, size, sortBy, this.properties, (refine) ? this.searchPage.getRefineFieldsQuery() : null, this.searchPage.getFields(), refineFieldsFilterQuery) - this.subs.push(this._searchResearchResultsService.advancedSearchResults(this.resultType, parameters, page, size, sortBy, this.properties, null, this.searchPage.getFields(), refineFieldsFilterQuery) + this.searchResultsSub = this._searchResearchResultsService.advancedSearchResults(this.resultType, parameters, page, size, sortBy, this.properties, null, this.searchPage.getFields(), refineFieldsFilterQuery) + //this.subs.push(this._searchResearchResultsService.advancedSearchResults(this.resultType, parameters, page, size, sortBy, this.properties, null, this.searchPage.getFields(), refineFieldsFilterQuery) .subscribe( data => { - this.searchUtils.totalResults = data[0]; - this.results = data[1]; - // if (refine) { - // this.filters = this.searchPage.prepareFiltersToShow(data[2],this.searchUtils.totalResults); - // this.rangeFilters = this.searchPage.prepareRangeFiltersToShow(); - // } else { - if(!refine) { - this.searchPage.buildPageURLParameters(this.filters, this.rangeFilters, false); - } + let totalResults = data[0]; + let results = data[1]; - this.searchPage.hideFilters = false; + // this.searchUtils.totalResults = totalResults; + // this.results = results; + // // if (refine) { + // // this.filters = this.searchPage.prepareFiltersToShow(data[2],this.searchUtils.totalResults); + // // this.rangeFilters = this.searchPage.prepareRangeFiltersToShow(); + // // } else { + // if(!refine) { + // this.searchPage.buildPageURLParameters(this.filters, this.rangeFilters, false); + // } + // + // this.searchPage.hideFilters = false; + // + // this.searchUtils.status = this.errorCodes.DONE; + // if (this.searchUtils.totalResults == 0) { + // this.searchUtils.status = this.errorCodes.NONE; + // } + // this.disableForms = false; + this.resultsReturned(refine, results, totalResults, page); - this.searchUtils.status = this.errorCodes.DONE; - if (this.searchUtils.totalResults == 0) { - this.searchUtils.status = this.errorCodes.NONE; - } - this.disableForms = false; - this.searchPageUpdates.emit({disableForms: this.disableForms, disableRefineForms: this.disableRefineForms, searchUtils: this.searchUtils}) - - 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; - } - } + this.searchPageUpdates.emit({disableForms: this.disableForms, disableRefineForms: this.disableRefineForms, searchUtils: this.searchUtils}); }, err => { this.handleError("Error getting " + this.getEntityName(this.resultType, true, true), err); @@ -269,9 +371,45 @@ export class SearchResearchResultsComponent { 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.rangeFilters, 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; + } private handleError(message: string, error) { console.error(this.getEntityName(this.resultType, true, true) + " advanced Search Page: " + message, error); diff --git a/searchPages/searchUtils/newSearchPage.component.html b/searchPages/searchUtils/newSearchPage.component.html index 85a01181..8945c257 100644 --- a/searchPages/searchUtils/newSearchPage.component.html +++ b/searchPages/searchUtils/newSearchPage.component.html @@ -276,6 +276,7 @@
- -
+