diff --git a/searchPages/searchDataProviders.component.ts b/searchPages/searchDataProviders.component.ts index fcec42c9..4b8647cc 100644 --- a/searchPages/searchDataProviders.component.ts +++ b/searchPages/searchDataProviders.component.ts @@ -1,4 +1,4 @@ -import {Component, EventEmitter, Input, Output, ViewChild} from '@angular/core'; +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'; @@ -11,12 +11,13 @@ 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"; @Component({ selector: 'search-dataproviders', template: ` - + [sort]="false" [showBreadcrumb]="showBreadcrumb" [basicMetaDescription]="metaDescription" + (filterRequestAll)="filterRequestedAll($event)"> @@ -91,7 +95,16 @@ export class SearchDataProvidersComponent { searchFiltersSub: any; metaDescription = []; - constructor (private route: ActivatedRoute, private _searchDataProvidersService: SearchDataprovidersService ) { + 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(); @@ -101,6 +114,9 @@ export class SearchDataProvidersComponent { } 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){ @@ -143,7 +159,7 @@ export class SearchDataProvidersComponent { this.searchPage.keywordFields = this.searchFields.DEPOSIT_DATASOURCE_KEYWORD_FIELDS; this.searchPage.usedBy = "deposit"; } - this.searchPage.prepareSearchPage(this.fieldIds, this.selectedFields, this.refineFields, [], this.fieldIdsMap,this.customFilter,params, this.entityType); + this.searchPage.prepareSearchPage(this.fieldIds, this.selectedFields, this.refineFields, [], this.staticFields, this.fieldIdsMap,this.customFilter,params, this.entityType); if(refine) { this._getFilters(this.searchPage.getSearchAPIQueryForAdvancedSearhFields(params), this.searchUtils.page, 0, true, this.searchPage.getSearchAPIQueryForRefineFields(params, firstLoad)); } else { @@ -151,6 +167,8 @@ export class SearchDataProvidersComponent { } 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() { @@ -172,7 +190,7 @@ export class SearchDataProvidersComponent { this.searchPageUpdates.emit({disableForms: this.disableForms, disableRefineForms: this.disableRefineForms, searchUtils: this.searchUtils}); let datasourceQueryPrefix = DatasourcesHelperClass.getQueryPrefix(this.type); - 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")) + 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"), true) //.switchMap( .subscribe( data => { @@ -182,6 +200,7 @@ export class SearchDataProvidersComponent { }, 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); @@ -196,6 +215,7 @@ export class SearchDataProvidersComponent { 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) { @@ -279,7 +299,7 @@ export class SearchDataProvidersComponent { this.searchUtils.totalResults = totalResults; this.results = results; if(!refine) { - this.searchPage.buildPageURLParameters(this.filters, [], false); + this.searchPage.buildPageURLParameters(this.filters, [], this.staticFilters, false); } this.searchPage.hideFilters = false; @@ -316,4 +336,41 @@ export class SearchDataProvidersComponent { 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[1][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.isOpen = 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(); + } + ) + } } diff --git a/searchPages/searchOrganizations.component.ts b/searchPages/searchOrganizations.component.ts index 54eeff07..46055ee4 100644 --- a/searchPages/searchOrganizations.component.ts +++ b/searchPages/searchOrganizations.component.ts @@ -1,4 +1,4 @@ -import {Component, EventEmitter, Input, Output, ViewChild} from '@angular/core'; +import {ChangeDetectorRef, Component, EventEmitter, Input, Output, ViewChild} from '@angular/core'; import {ActivatedRoute} from '@angular/router'; import {AdvancedField, Filter} from './searchUtils/searchHelperClasses.class'; import {SearchOrganizationsService} from '../services/searchOrganizations.service'; @@ -9,6 +9,7 @@ import {SearchCustomFilter, SearchUtilsClass} from './searchUtils/searchUtils.cl import {EnvProperties} from '../utils/properties/env-properties'; import {NewSearchPageComponent, SearchForm} from "./searchUtils/newSearchPage.component"; import {properties} from "../../../environments/environment"; +import {RefineFieldResultsService} from "../services/refineFieldResults.service"; @Component({ @@ -36,7 +37,7 @@ import {properties} from "../../../environments/environment"; [simpleView]="simpleView" formPlaceholderText="Search by organization name..." [showSwitchSearchLink]="showSwitchSearchLink" [showBreadcrumb]="showBreadcrumb" - > + (filterRequestAll)="filterRequestedAll($event)"> ` }) @@ -79,7 +80,11 @@ export class SearchOrganizationsComponent { searchResultsSub: any; searchFiltersSub: any; - constructor (private route: ActivatedRoute, private _searchOrganizationsService: SearchOrganizationsService ) { + private refineQuery: string = ""; + + constructor (private route: ActivatedRoute, private _searchOrganizationsService: SearchOrganizationsService, + private _refineFieldsResultsService: RefineFieldResultsService, + private cdr: ChangeDetectorRef) { this.results =[]; this.errorCodes = new ErrorCodes(); this.errorMessages = new ErrorMessagesComponent(); @@ -127,7 +132,7 @@ export class SearchOrganizationsComponent { // this.searchPage.fieldIdsMap = this.fieldIdsMap; // this.searchPage.customFilter = this.customFilter; // this.searchPage.getSelectedFiltersFromUrl(params); - this.searchPage.prepareSearchPage(this.fieldIds, this.selectedFields, this.refineFields, [], this.fieldIdsMap,this.customFilter,params, "organization"); + this.searchPage.prepareSearchPage(this.fieldIds, this.selectedFields, this.refineFields, [], [], this.fieldIdsMap,this.customFilter,params, "organization"); if(refine) { this._getFilters(this.searchPage.getSearchAPIQueryForAdvancedSearhFields(), this.searchUtils.page, 0, true, this.searchPage.getSearchAPIQueryForRefineFields(params, firstLoad)); } else { @@ -135,6 +140,8 @@ export class SearchOrganizationsComponent { } this.getResults(this.searchPage.getSearchAPIQueryForAdvancedSearhFields(), 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() { @@ -154,7 +161,7 @@ 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.searchFiltersSub = 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, true) //.switchMap( .subscribe( data => { @@ -271,7 +278,7 @@ export class SearchOrganizationsComponent { this.searchUtils.totalResults = totalResults; this.results = results; if(!refine) { - this.searchPage.buildPageURLParameters(this.filters, [], false); + this.searchPage.buildPageURLParameters(this.filters, [], [], false); } this.searchPage.hideFilters = false; @@ -308,4 +315,41 @@ export class SearchOrganizationsComponent { private handleError(message: string, error) { console.error("Organizations advanced Search Page: "+message, error); } + + public filterRequestedAll(oldFilter: Filter) { + let fieldsStr: string = "&fields=" + oldFilter.filterId+"&refine=true"; + + this.searchFiltersSub = this._searchOrganizationsService.advancedSearchOrganizations(this.searchPage.getSearchAPIQueryForAdvancedSearhFields(), 1, 0, properties, fieldsStr, [oldFilter.filterId], this.refineQuery).subscribe( + // this.searchFiltersSub = this._refineFieldsResultsService.getAllRefineFieldResultsByFieldName(oldFilter.filterId, "organization", this.properties, this.refineQuery).subscribe( + res => { + let filter: Filter = res[1][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.isOpen = 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(); + } + ) + } } diff --git a/searchPages/searchProjects.component.ts b/searchPages/searchProjects.component.ts index 1ebae061..dd70ff8c 100644 --- a/searchPages/searchProjects.component.ts +++ b/searchPages/searchProjects.component.ts @@ -1,4 +1,4 @@ -import {Component, EventEmitter, Input, Output, ViewChild} from '@angular/core'; +import {ChangeDetectorRef, Component, EventEmitter, Input, Output, ViewChild} from '@angular/core'; import {ActivatedRoute} from '@angular/router'; import {AdvancedField, Filter} from './searchUtils/searchHelperClasses.class'; import {SearchProjectsService} from '../services/searchProjects.service'; @@ -10,6 +10,7 @@ import {EnvProperties} from '../utils/properties/env-properties'; import {NewSearchPageComponent, SearchForm} from "./searchUtils/newSearchPage.component"; import {RangeFilter} from "../utils/rangeFilter/rangeFilterHelperClasses.class"; import {properties} from "../../../environments/environment"; +import {RefineFieldResultsService} from "../services/refineFieldResults.service"; @Component({ selector: 'search-projects', @@ -36,7 +37,7 @@ import {properties} from "../../../environments/environment"; [simpleView]="simpleView" formPlaceholderText="Search by title, acronym, project code..." [showSwitchSearchLink]="showSwitchSearchLink" [sort]="false" [showBreadcrumb]="showBreadcrumb" - > + (filterRequestAll)="filterRequestedAll($event)"> ` @@ -82,8 +83,12 @@ export class SearchProjectsComponent { subs: any[] = []; searchResultsSub: any; searchFiltersSub: any; - - constructor(private route: ActivatedRoute, private _searchProjectsService: SearchProjectsService) { + + private refineQuery: string = ""; + + constructor(private route: ActivatedRoute, private _searchProjectsService: SearchProjectsService, + private _refineFieldsResultsService: RefineFieldResultsService, + private cdr: ChangeDetectorRef) { this.results = []; this.errorCodes = new ErrorCodes(); this.errorMessages = new ErrorMessagesComponent(); @@ -128,7 +133,7 @@ export class SearchProjectsComponent { this.searchPage.fieldIds = this.fieldIds; this.selectedFields = []; - this.searchPage.prepareSearchPage(this.fieldIds, this.selectedFields, this.refineFields, this.rangeFields, this.fieldIdsMap, this.customFilter, params, "project"); + this.searchPage.prepareSearchPage(this.fieldIds, this.selectedFields, this.refineFields, this.rangeFields, [], this.fieldIdsMap, this.customFilter, params, "project"); if (refine) { this._getFilters(this.searchPage.getSearchAPIQueryForAdvancedSearhFields(), this.searchUtils.page, 0, "", true, this.searchPage.getSearchAPIQueryForRangeFields(params) + this.searchPage.getSearchAPIQueryForRefineFields(params, firstLoad)); } else { @@ -136,6 +141,8 @@ export class SearchProjectsComponent { } this.getResults(this.searchPage.getSearchAPIQueryForAdvancedSearhFields(), this.searchUtils.page, this.searchUtils.size, refine, this.searchPage.getSearchAPIQueryForRangeFields(params) + this.searchPage.getSearchAPIQueryForRefineFields(params, firstLoad)); firstLoad = false; + + this.refineQuery = this.searchPage.getSearchAPIQueryForRangeFields(params)+this.searchPage.getSearchAPIQueryForRefineFields(params, firstLoad); })); } @@ -160,7 +167,7 @@ export class SearchProjectsComponent { disableRefineForms: this.disableRefineForms, searchUtils: this.searchUtils }); - this.searchFiltersSub = 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, true) //.switchMap( .subscribe( data => { @@ -297,7 +304,7 @@ export class SearchProjectsComponent { this.searchUtils.totalResults = totalResults; this.results = results; if (!refine) { - this.searchPage.buildPageURLParameters(this.filters, this.rangeFilters, false); + this.searchPage.buildPageURLParameters(this.filters, this.rangeFilters, [], false); } this.searchPage.hideFilters = false; @@ -337,4 +344,41 @@ export class SearchProjectsComponent { private handleError(message: string, error) { console.error("Projects advanced Search Page: " + message, error); } -} + + public filterRequestedAll(oldFilter: Filter) { + let fieldsStr: string = "&fields=" + oldFilter.filterId+"&refine=true"; + + this.searchFiltersSub = this._searchProjectsService.advancedSearchProjects(this.searchPage.getSearchAPIQueryForAdvancedSearhFields(), 1, 0, properties, fieldsStr, [oldFilter.filterId], this.refineQuery).subscribe( + // this.searchFiltersSub = this._refineFieldsResultsService.getAllRefineFieldResultsByFieldName(oldFilter.filterId, "project", this.properties, this.refineQuery).subscribe( + res => { + let filter: Filter = res[1][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.isOpen = 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(); + } + ) + } +} \ No newline at end of file diff --git a/searchPages/searchResearchResults.component.ts b/searchPages/searchResearchResults.component.ts index f4f03fa7..d8e78fe6 100644 --- a/searchPages/searchResearchResults.component.ts +++ b/searchPages/searchResearchResults.component.ts @@ -1,4 +1,4 @@ -import {Component, EventEmitter, Input, Output, ViewChild} from '@angular/core'; +import {ChangeDetectorRef, Component, EventEmitter, Input, Output, ViewChild} from '@angular/core'; import {ActivatedRoute, Router} from '@angular/router'; import {AdvancedField, Filter} from './searchUtils/searchHelperClasses.class'; import {SearchResearchResultsService} from '../services/searchResearchResults.service'; @@ -12,6 +12,8 @@ import {RangeFilter} from "../utils/rangeFilter/rangeFilterHelperClasses.class"; import {properties} from "../../../environments/environment"; import {ContextsService} from "../claims/claim-utils/service/contexts.service"; import {StringUtils} from "../utils/string-utils.class"; +import {RefineResultsUtils} from "../services/servicesUtils/refineResults.class"; +import {RefineFieldResultsService} from "../services/refineFieldResults.service"; @Component({ selector: 'search-research-results', @@ -24,6 +26,8 @@ import {StringUtils} from "../utils/string-utils.class"; [searchUtils]="searchUtils" [sortedByChanged]="searchUtils.sortBy" [fieldIds]="fieldIds" [fieldIdsMap]="fieldIdsMap" [selectedFields]="selectedFields" + [staticFields]="staticFields" [staticFilters]="staticFilters" + [staticFieldValues]="staticFieldValues" [csvParams]="csvParams" [csvPath]="getEntityFileName(resultType)" [simpleSearchLink]="simpleSearchLink" [advancedSearchLink]="advancedSearchLink" [disableForms]="disableForms" @@ -34,10 +38,12 @@ import {StringUtils} from "../utils/string-utils.class"; [searchForm]="searchForm" [filters]="filters" [quickFilter]="quickFilter" [rangeFilters]="rangeFilters" [rangeFields]="rangeFields" + [orderedFilters]="orderedFilters" [simpleView]="simpleView" formPlaceholderText="Search by title, author, abstract, DOI, orcid..." [includeOnlyResultsAndFilter]="includeOnlyResultsAndFilter" [showBreadcrumb]="showBreadcrumb" [showSwitchSearchLink]="showSwitchSearchLink" [stickyForm]="stickyForm" + (filterRequestAll)="filterRequestedAll($event)" > ` @@ -64,6 +70,12 @@ export class SearchResearchResultsComponent { public fieldIdsMap = this.searchFields.RESULT_FIELDS; public rangeFields: string[][] = this.searchFields.RESULT_RANGE_FIELDS; public selectedFields: AdvancedField[] = []; + + public staticFields: string[] = this.searchFields.RESULT_STATIC_FIELDS; + public staticFieldValues = this.searchFields.RESULT_STATIC_FIELD_VALUES; + public staticFilters = RefineResultsUtils.parse(this.staticFieldValues, this.staticFields, this.resultType, "search", true); + public orderedFilters; + public resourcesQuery = "((oaftype exact result) and (resulttypeid exact " + this.resultType + "))"; public csvParams: string; public disableForms: boolean = false; @@ -76,6 +88,7 @@ export class SearchResearchResultsComponent { properties: EnvProperties = properties; public openaireEntities = OpenaireEntities; public refineFields: string[] = this.searchFields.RESULT_REFINE_FIELDS; + public orderedFields = this.searchFields.RESULT_FIELDS_ORDERED; @ViewChild(NewSearchPageComponent, { static: true }) searchPage: NewSearchPageComponent; @Input() simpleView: boolean = true; quickFilter: { filter: Filter, selected: boolean, filterId: string, value: string } = { @@ -101,9 +114,13 @@ export class SearchResearchResultsComponent { @Input() orcidQuery: string = ""; @Input() identifiers: string[] = []; + private refineQuery: string = ""; + constructor(private route: ActivatedRoute, private _router: Router, private _searchResearchResultsService: SearchResearchResultsService, - private _contextService: ContextsService) { + private _refineFieldsResultsService: RefineFieldResultsService, + private _contextService: ContextsService, + private cdr: ChangeDetectorRef) { this.results = []; this.errorCodes = new ErrorCodes(); this.errorMessages = new ErrorMessagesComponent(); @@ -166,8 +183,7 @@ export class SearchResearchResultsComponent { this.searchUtils.sortBy = ""; } this.selectedFields = []; - - this.searchPage.prepareSearchPage(this.fieldIds, this.selectedFields, this.refineFields, this.rangeFields, this.fieldIdsMap,this.customFilter,params, this.resultType, this.quickFilter); + this.searchPage.prepareSearchPage(this.fieldIds, this.selectedFields, this.refineFields, this.rangeFields, this.staticFields, this.fieldIdsMap,this.customFilter,params, this.resultType, this.quickFilter); if(refine) { this._getFilters(this.searchPage.getSearchAPIQueryForAdvancedSearhFields(), this.searchUtils.page, 0, "", true, this.searchPage.getSearchAPIQueryForRangeFields(params)+this.searchPage.getSearchAPIQueryForRefineFields(params, firstLoad)); } else { @@ -175,6 +191,8 @@ export class SearchResearchResultsComponent { } this._getResults(this.searchPage.getSearchAPIQueryForAdvancedSearhFields(), this.searchUtils.page, this.searchUtils.size, this.searchUtils.sortBy, refine, this.searchPage.getSearchAPIQueryForRangeFields(params) + this.searchPage.getSearchAPIQueryForRefineFields(params, firstLoad)); firstLoad = false; + + this.refineQuery = this.searchPage.getSearchAPIQueryForRangeFields(params)+this.searchPage.getSearchAPIQueryForRefineFields(params, firstLoad); })); } @@ -226,7 +244,7 @@ export class SearchResearchResultsComponent { this.searchUtils.refineStatus = this.errorCodes.LOADING; this.disableRefineForms = true; this.searchPageUpdates.emit({disableForms: this.disableForms, disableRefineForms: this.disableRefineForms, searchUtils: this.searchUtils}); - this.searchFiltersSub = 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, true) // 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( @@ -248,6 +266,7 @@ export class SearchResearchResultsComponent { err => { this.filters = this.searchPage.prepareFiltersToShow([], 0); this.rangeFilters = this.searchPage.prepareRangeFiltersToShow(); + this.staticFilters = this.searchPage.prepareStaticFiltersToShow(); this.handleError("Error getting refine filters for " + this.getEntityName(this.resultType, true, true), err); this.searchUtils.refineStatus = this.errorMessages.getErrorCode(err.status); @@ -292,6 +311,45 @@ export class SearchResearchResultsComponent { if (refine) { this.filters = this.searchPage.prepareFiltersToShow(filters, totalResults); this.rangeFilters = this.searchPage.prepareRangeFiltersToShow(); + this.staticFilters = this.searchPage.prepareStaticFiltersToShow(); + + if(this.orderedFields) { + this.orderedFilters = []; + for(let group of this.orderedFields) { + if (group.type == "refine") { + let groupedFilters = {title: group.title, values: []}; + for (let field of group.values) { + let index = this.filters.findIndex(filter => filter.filterId == field); + if (index > -1) { + groupedFilters.values.push(this.filters[index]); + } + } + if (groupedFilters.values.length > 0) { + this.orderedFilters.push(groupedFilters); + } + } else if (group.type == "range") { + let groupedFilters = {title: group.title, values: []}; + let from = group.values[0]; + let to = group.values[1]; + let index = this.rangeFilters.findIndex(filter => filter.originalFilterIdFrom == from && filter.originalFilterIdTo == to); + if (index > -1) { + groupedFilters.values.push(this.rangeFilters[index]); + this.orderedFilters.push(groupedFilters); + } + } else if (group.type == "static") { + let groupedFilters = {title: group.title, values: []}; + for (let field of group.values) { + let index = this.staticFilters.findIndex(filter => filter.filterId == field); + if (index > -1) { + groupedFilters.values.push(this.staticFilters[index]); + } + } + if (groupedFilters.values.length > 0) { + this.orderedFilters.push(groupedFilters); + } + } + } + } } this.searchUtils.refineStatus = this.errorCodes.DONE; @@ -399,7 +457,7 @@ export class SearchResearchResultsComponent { this.searchUtils.totalResults = totalResults; this.results = results; if(!refine) { - this.searchPage.buildPageURLParameters(this.filters, this.rangeFilters, false); + this.searchPage.buildPageURLParameters(this.filters, this.rangeFilters, this.staticFilters, false); } this.searchPage.hideFilters = false; @@ -443,4 +501,62 @@ export class SearchResearchResultsComponent { public getEntityFileName(entityType: string) { return StringUtils.getEntityFileName(entityType); } + + public filterRequestedAll(oldFilter: Filter) { + let fieldsStr: string = "&fields=" + oldFilter.filterId+"&refine=true"; + + this.searchFiltersSub = this._searchResearchResultsService.advancedSearchResults(this.resultType, this.searchPage.getSearchAPIQueryForAdvancedSearhFields(), 1, 0, null, properties, fieldsStr, [oldFilter.filterId], this.refineQuery).subscribe( + // this.searchFiltersSub = this._refineFieldsResultsService.getAllRefineFieldResultsByFieldName(oldFilter.filterId, this.resultType, this.properties, this.refineQuery).subscribe( + res => { + // let filter: Filter = res[1][0]; + let filter: Filter = res[2][0]; + if(filter.values.length == 0) { + filter = oldFilter; + filter.countAllValues = 0; + } else { + filter.countAllValues = filter.values.length; + 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.isOpen = true; + filter.countSelectedValues = oldFilter.countSelectedValues; + filter.radioValue = oldFilter.radioValue; + this.filters[index] = filter; + this.updateOrderedFilter(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.updateOrderedFilter(oldFilter); + + this.cdr.detectChanges(); + } + ) + } + + public updateOrderedFilter(filter: Filter) { + if(this.orderedFilters) { + let groupIndex = 0; + let index; + for(let group of this.orderedFilters) { + index = group.values.findIndex((fltr: Filter) => fltr.filterId == filter.filterId); + if(index != -1) { + break; + } + groupIndex++; + } + this.orderedFilters[groupIndex].values[index] = filter; + } + } } diff --git a/searchPages/searchUtils/advancedSearchForm.component.html b/searchPages/searchUtils/advancedSearchForm.component.html index 8019c91c..92ad54ca 100644 --- a/searchPages/searchUtils/advancedSearchForm.component.html +++ b/searchPages/searchUtils/advancedSearchForm.component.html @@ -59,8 +59,9 @@ (listUpdated)="listUpdated($event,selectedField.id)" [id]="'autocomplete-'+i"> - + + + + +
  • + + + {{filter.title}}: + {{value.name=='true'?'Yes':'No'}} + + + {{value.name}} + + + +
  • +
    +
    +
    @@ -72,11 +94,12 @@ - + @@ -84,7 +107,7 @@ @@ -198,6 +242,7 @@
    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 = ""; + // 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 = ""; + + } } } } @@ -328,9 +351,19 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges { // if (this.quickFilter) { // this.removeValueFromQuickFilter(); // } - if (this.resultTypes) { - this.resultTypes.values = []; + 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(); } @@ -341,7 +374,7 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges { } this.searchUtils.page = page; - this.buildPageURLParameters(this.filters, this.rangeFilters, true); + 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"); @@ -423,11 +456,13 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges { var fields: string[] = []; for (var i = 0; i < this.refineFields.length; i++) { var dependentTo = this.searchFieldsHelper.DEPENDENT_FIELDS[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 || (selected_filters.indexOf(dependentTo) != -1) || (selected_filters.indexOf(this.refineFields[i]) != -1) - || (this.resultTypes && this.resultTypes.filterId == dependentTo && this.resultTypes.countSelectedValues > 0)) { + || (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]); } } @@ -568,6 +603,35 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges { } 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) { @@ -633,6 +697,16 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges { } 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) { @@ -701,6 +775,10 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges { 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 @@ -949,6 +1027,12 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges { 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) { @@ -1112,6 +1196,27 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges { 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; + } + } + this.customFilterEnabled = URLparams["cf"] == "true"; if (this.customFilter && (this.customFilter.isHiddenFilter || this.customFilterEnabled)) { allFqs += "&fq=" + StringUtils.URIEncode(this.customFilter.queryFieldName + " exact " + StringUtils.quote((this.customFilter.valueId))); @@ -1138,7 +1243,7 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges { 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 { @@ -1347,9 +1452,10 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges { * 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[], includePage: boolean) { + 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++) { @@ -1392,31 +1498,47 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges { //this.parameterValues.push(this.searchUtils.sortBy); this.parameterValues.push(this.sortedByChanged); } - 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); + + 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); } } - 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); - }*/ } + + // 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) { @@ -1482,6 +1604,7 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges { 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) { @@ -1523,36 +1646,59 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges { } }*/ - 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++; + 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; } /** @@ -1641,7 +1787,7 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges { this.filters = filters; } - this.buildPageURLParameters(this.URLCreatedFilters, this.URLCreatedRangeFilters, true); + this.buildPageURLParameters(this.URLCreatedFilters, this.URLCreatedRangeFilters, this.URLCreatedStaticFilters, true); //this.checkSelectedRangeFilters(this.rangeFilters); this.checkSelectedFilters(this.filters); @@ -1662,6 +1808,15 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges { this.countSelectedRangeFilters(this.rangeFilters); return this.rangeFilters; } + + public prepareStaticFiltersToShow() { + this.staticFilters = RefineResultsUtils.parse(this.staticFieldValues, this.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 @@ -1675,18 +1830,20 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges { * @param entityType * @param quickFilter */ - prepareSearchPage(fieldIds, selectedFields, refineFields, rangeFields, fieldIdsMap, customFilter, params, entityType, quickFilter = null) { + 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'){ @@ -1697,7 +1854,7 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges { 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) { diff --git a/searchPages/searchUtils/searchFilter.component.html b/searchPages/searchUtils/searchFilter.component.html index fe68a0fd..c797bb2c 100644 --- a/searchPages/searchUtils/searchFilter.component.html +++ b/searchPages/searchUtils/searchFilter.component.html @@ -10,33 +10,41 @@ -
    +
    - View all - View less + View all + View less -
    -
    -
    Top 100 values are shown in the filters
    -
    -
    -
    +
    +
    + +
    +
    + An error occured. Please try again. +
    + +
    +
    Top 100 values are shown in the filters
    +
    +
    +
    +
    -
    -
    - -
    - -
    -
    - -
    - No filters available with that term -
    -
    -
    +
    + +
    + +
    +
    + +
    + No filters available with that term +
    +
    +
    +
    diff --git a/searchPages/searchUtils/searchFilter.component.ts b/searchPages/searchUtils/searchFilter.component.ts index 2f87417f..896cc360 100644 --- a/searchPages/searchUtils/searchFilter.component.ts +++ b/searchPages/searchUtils/searchFilter.component.ts @@ -26,6 +26,7 @@ export class SearchFilterComponent implements OnInit, OnChanges { @Input() addShowMore: boolean = true; @Input() showMoreInline: boolean = true; @Input() filterValuesNum: number = 6; + public hasMoreValues: boolean = false; public showAll: boolean = false; public _maxCharacters: number = 28; @@ -33,6 +34,7 @@ export class SearchFilterComponent implements OnInit, OnChanges { @Output() modalChange = new EventEmitter(); @Output() onFilterChange = new EventEmitter(); + @Output() onFilterToggle = new EventEmitter(); keyword = ""; sortBy: "name" | "num" = "name"; sortByOptions: Option[] = [{label: 'Results number', value: 'num'}, {label: 'Name', value: 'name'}]; @@ -41,7 +43,7 @@ export class SearchFilterComponent implements OnInit, OnChanges { @Input() actionRoute: boolean = false; @Input() quickFilter: { filter: Filter, selected: boolean, filterId: string, value: string }; sub; - public isOpen: boolean = false; + @Input() isOpen: boolean = false; sortedValues; hasMatch: boolean = false; @@ -58,11 +60,12 @@ export class SearchFilterComponent implements OnInit, OnChanges { ngOnInit() { if(this.filterValuesNum == 0){ - this.isOpen = true; + this.filter.isOpen = true; this.sortBy = "num"; - }else{ - this.isOpen = false; } + // else{ + // this.filter.isOpen = false; + // } this.sub = this.route.queryParams.subscribe(params => { this.queryParams = Object.assign({}, params); this.paramPosition = SearchFields.getParameterOrder(this.filter.filterId, this.getEntries(params)); @@ -81,7 +84,10 @@ export class SearchFilterComponent implements OnInit, OnChanges { ngOnChanges(changes: SimpleChanges) { if (changes.filter) { - this.filter.values = this.filter.values.filter(value => !value.name.toLowerCase().includes('unknown') && !value.name.toLowerCase().includes('not available')); + this.hasMoreValues = this.filter.values.length > this.filterValuesNum; + // this.filter.values = this.filter.values.filter(value => !value.name.toLowerCase().includes('unknown') && !value.name.toLowerCase().includes('not available')); + this.filter.values = this.filter.values.filter(value => value && value.name != "unidentified" && value.name != "Undetermined" && !value.name.toLowerCase().includes('unknown') && !value.name.toLowerCase().includes('not available')); + if (this.filter.filterType == "radio") { this.filter.radioValue = ""; this.filter.values.forEach(value => { @@ -95,7 +101,8 @@ export class SearchFilterComponent implements OnInit, OnChanges { } public _formatTitle(title, length) { - return (((title + " (" + length + ")").length > this._maxCharacters) ? (title.substring(0, (this._maxCharacters - (" (" + length + ")").length - ('...').length)) + "...") : title) + " (" + (length > 95 ? "100" : length) + ")"; + // return (((title + " (" + length + ")").length > this._maxCharacters) ? (title.substring(0, (this._maxCharacters - (" (" + length + ")").length - ('...').length)) + "...") : title) + " (" + (length > 95 ? "100" : length) + ")"; + return (((title).length > this._maxCharacters) ? (title.substring(0, (this._maxCharacters - ('...').length)) + "...") : title); } public _formatName(value) { @@ -265,8 +272,18 @@ export class SearchFilterComponent implements OnInit, OnChanges { } toggle(event) { - this.isOpen = !this.isOpen; + this.filter.isOpen = !this.filter.isOpen; event.stopPropagation(); + this.toggleWithoutUpdate(); + } + + toggleWithoutUpdate() { + if(this.filter.countAllValues == 0) { + this.filter.countAllValues = -1; // if request failed, try again automatically if toggled again + } + if(this.filter.isOpen && this.filter.countAllValues < 0) { + this.onFilterToggle.emit(this.filter); + } } disabled(value) { diff --git a/searchPages/searchUtils/searchFilter.module.ts b/searchPages/searchUtils/searchFilter.module.ts index 6f8bc92b..5f014308 100644 --- a/searchPages/searchUtils/searchFilter.module.ts +++ b/searchPages/searchUtils/searchFilter.module.ts @@ -8,11 +8,12 @@ import {ModalModule} from '../../utils/modal/modal.module'; import {RouterModule} from "@angular/router"; import {InputModule} from '../../sharedComponents/input/input.module'; import {IconsModule} from "../../utils/icons/icons.module"; +import {LoadingModule} from "../../utils/loading/loading.module"; @NgModule({ imports: [ CommonModule, FormsModule, ModalModule, RouterModule, - InputModule, IconsModule + InputModule, IconsModule, LoadingModule ], declarations: [ SearchFilterComponent, SearchFilterModalComponent diff --git a/searchPages/searchUtils/searchHelperClasses.class.ts b/searchPages/searchUtils/searchHelperClasses.class.ts index 4663be5f..01a68404 100644 --- a/searchPages/searchUtils/searchHelperClasses.class.ts +++ b/searchPages/searchUtils/searchHelperClasses.class.ts @@ -11,6 +11,8 @@ export class Filter{ public type?: string = "keyword"; public radioValue?: string = ""; // public uniqueValueIdSelected: string; + public countAllValues?: number = -1; // -1: not yet requested, 0: request failed, >0 OK + public isOpen?: boolean = false; } export class Value{ diff --git a/services/refineFieldResults.service.ts b/services/refineFieldResults.service.ts index f43771dd..af653a28 100644 --- a/services/refineFieldResults.service.ts +++ b/services/refineFieldResults.service.ts @@ -29,7 +29,7 @@ export class RefineFieldResultsService { getAllRefineFieldResultsByFieldName(fieldName:string, entityName:string, properties:EnvProperties, refineQuery:string=null):any{ // let keys:string[]=["funder", "relfunder", "fundinglevel"]; - let url = properties.searchAPIURLLAst +this.getSearchAPIURLForEntity(entityName)+"?fields="+fieldName +('&sf='+fieldName)+ "&format=json"; + let url = properties.searchAPIURLLAst +this.getSearchAPIURLForEntity(entityName)+"?fields="+fieldName +('&sf='+fieldName)+ "&format=json&size=0"; if(refineQuery!= null && refineQuery != '' ) { url += refineQuery; } diff --git a/services/searchDataproviders.service.ts b/services/searchDataproviders.service.ts index af05a7f1..1ae052b5 100644 --- a/services/searchDataproviders.service.ts +++ b/services/searchDataproviders.service.ts @@ -31,7 +31,7 @@ export class SearchDataprovidersService { .pipe(map(res => [res['meta'].total, this.parseResults(res['results']),RefineResultsUtils.parse(res['refineResults'],refineFields, "datasource", usedBy)])); } - advancedSearchDataproviders (params: string, page: number, size: number, properties: EnvProperties, refineParams:string=null, refineFields:string[] =null, refineQuery:string = null, depositQuery:boolean = false ):any { + advancedSearchDataproviders (params: string, page: number, size: number, properties: EnvProperties, refineParams:string=null, refineFields:string[] =null, refineQuery:string = null, depositQuery:boolean = false, minRef: boolean = false):any { let url = properties.searchAPIURLLAst+"resources"+(depositQuery?'':2)+"/?format=json"; if(params!= null && params != '' ) { @@ -45,6 +45,7 @@ export class SearchDataprovidersService { url += "&" + refineQuery; } url += "&page="+(page-1)+"&size="+size; + url += minRef ? "&minRef=true" : ""; return this.http.get((properties.useCache)? (properties.cacheUrl+encodeURIComponent(url)): url) .pipe(map(res => [res['meta'].total, this.parseResults(res['results']), RefineResultsUtils.parse(res['refineResults'],refineFields, "datasource")])); diff --git a/services/searchOrganizations.service.ts b/services/searchOrganizations.service.ts index d35f9f97..b4b51c15 100644 --- a/services/searchOrganizations.service.ts +++ b/services/searchOrganizations.service.ts @@ -55,7 +55,7 @@ export class SearchOrganizationsService { //.map(res => res.json()) .pipe(map(res => [res['meta'].total, this.parseResults(res['results']),RefineResultsUtils.parse(res['refineResults'],refineFields, "organization")])); } - advancedSearchOrganizations (params: string, page: number, size: number, properties:EnvProperties, refineParams:string=null, refineFields:string[] =null, refineQuery:string = null ):any { + advancedSearchOrganizations (params: string, page: number, size: number, properties:EnvProperties, refineParams:string=null, refineFields:string[] =null, refineQuery:string = null, minRef: boolean = false):any { // &type=organizations let url = properties.searchAPIURLLAst+"resources2/?format=json"; var basicQuery = "(reldatasourcecompatibilityid exact driver or reldatasourcecompatibilityid exact driver-openaire2.0 or " + @@ -76,6 +76,7 @@ export class SearchOrganizationsService { url += "&" + refineQuery; } url += "&page="+(page-1)+"&size="+size; + url += minRef ? "&minRef=true" : ""; return this.http.get((properties.useCache)? (properties.cacheUrl+encodeURIComponent(url)): url) //.map(res => res.json()) diff --git a/services/searchProjects.service.ts b/services/searchProjects.service.ts index b513b737..8e2fa14d 100644 --- a/services/searchProjects.service.ts +++ b/services/searchProjects.service.ts @@ -49,7 +49,7 @@ export class SearchProjectsService { //.map(res => res.json()) .pipe(map(res => [res['meta'].total, this.parseResults(res['results'])])); } - advancedSearchProjects (params: string, page: number, size: number, properties:EnvProperties, refineParams:string=null, refineFields:string[] =null, refineQuery:string = null ):any { + advancedSearchProjects (params: string, page: number, size: number, properties:EnvProperties, refineParams:string=null, refineFields:string[] =null, refineQuery:string = null, minRef: boolean = false):any { // &type=projects let url = properties.searchAPIURLLAst+"resources2/?format=json"; // var basicQuery = "(oaftype exact project) " @@ -67,6 +67,8 @@ export class SearchProjectsService { url += "&" + refineQuery; } url += "&page="+(page-1)+"&size="+size; + url += minRef ? "&minRef=true" : ""; + // url += "&format=json"; return this.http.get((properties.useCache)? (properties.cacheUrl+encodeURIComponent(url)): url) //.map(res => res.json()) diff --git a/services/searchResearchResults.service.ts b/services/searchResearchResults.service.ts index d81981e1..4c76bf90 100644 --- a/services/searchResearchResults.service.ts +++ b/services/searchResearchResults.service.ts @@ -109,7 +109,7 @@ export class SearchResearchResultsService { .pipe(map(res => [res['meta'].total, this.parseResults(resultType, res['results'], properties), RefineResultsUtils.parse(res['refineResults'], refineFields, "publication")])); } - advancedSearchResults(resultType: string, params: string, page: number, size: number, sortBy: string, properties: EnvProperties, refineParams: string = null, refineFields: string[] = null, refineQuery: string = null): any { + advancedSearchResults(resultType: string, params: string, page: number, size: number, sortBy: string, properties: EnvProperties, refineParams: string = null, refineFields: string[] = null, refineQuery: string = null, minRef: boolean = false): any { let url = properties.searchAPIURLLAst + "resources2/?format=json"; if (params != null && params != '') { url += "&query=(" + params + ")"; @@ -126,6 +126,7 @@ export class SearchResearchResultsService { } url += "&page=" + (page - 1) + "&size=" + size; + url += minRef ? "&minRef=true" : ""; // url += "&format=json"; return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url) diff --git a/services/servicesUtils/refineResults.class.ts b/services/servicesUtils/refineResults.class.ts index b2f67501..01ec207b 100644 --- a/services/servicesUtils/refineResults.class.ts +++ b/services/servicesUtils/refineResults.class.ts @@ -6,7 +6,7 @@ import { SearchFields} from '../../utils/properties/searchFields'; export class RefineResultsUtils { - public static parse (data, fields:string[], entityType:string, usedBy: string="search"):Filter[] { + public static parse (data, fields:string[], entityType:string, usedBy: string="search", staticFilter: boolean = false):Filter[] { // var data = this.json.refineReuslts; var searchFields:SearchFields = new SearchFields(); @@ -33,12 +33,16 @@ export class RefineResultsUtils { value.name =this.removePartAfterCharacters(value,"||"); value.number = field[i].count; value.id = field[i].id; - if(RefineResultsUtils.includeValue(value)){ + //if(RefineResultsUtils.includeValue(value)){ filter.values.push(value); - } + //} } + if(staticFilter) { + filter.countAllValues = filter.values.length; + } + // filter.values.sort(function(a, b){return b.number - a.number}) filters.push(filter); } diff --git a/utils/properties/searchFields.base.ts b/utils/properties/searchFields.base.ts index 12601615..67152fe6 100644 --- a/utils/properties/searchFields.base.ts +++ b/utils/properties/searchFields.base.ts @@ -7,6 +7,8 @@ export class SearchFieldsBase { //RESULTS //Used for datasets and publications and software and orp //In case Datasets or Software should display different fields, use seperate tables for fields + public RESULT_STATIC_FIELDS = ["resultbestaccessright", "type"]; + // "resultacceptanceyear", public RESULT_RANGE_FIELDS = [ ["resultacceptanceyear", "resultacceptanceyear"] @@ -14,10 +16,21 @@ export class SearchFieldsBase { // Remove Collected From Filter "collectedfrom","collectedfrom" public RESULT_REFINE_FIELDS = [ - "resultbestaccessright", "instancetypename", properties.environment!='production'?"foslabel":'fos', "relfunder", + "instancetypename", properties.environment!='production'?"foslabel":'fos', "relfunder", "relfundinglevel0_id", "relfundinglevel1_id", "relfundinglevel2_id", "relproject", "sdg", "country", "resultlanguagename", "resulthostingdatasource", "community"]; + RESULT_FIELDS_ORDERED = [ + {type: "static", title: "", values: ["resultbestaccessright", "type"]}, + {type: "refine", title: "", values: ["instancetypename"]}, + {type: "range", title: "", values: ["resultacceptanceyear", "resultacceptanceyear"]}, + {type: "refine", title: "", values: [ + properties.environment!='production'?"foslabel":'fos', "relfunder", + "relfundinglevel0_id", "relfundinglevel1_id", "relfundinglevel2_id", + "relproject", "sdg", "country", "resultlanguagename", "resulthostingdatasource", "community" + ]} + ]; + public RESULT_ADVANCED_FIELDS: string[] = ["q", "resulttitle", "resultauthor", "authorid", "resultdescription", "resultsubject", "eoscifguidelines", "resultpublisher", "resultbestaccessright", "community", "collectedfromdatasourceid", "resulthostingdatasourceid", "resultdateofacceptance", "relfunder", @@ -203,11 +216,11 @@ export class SearchFieldsBase { }, ["resultbestaccessright"]: { name: "Access", - type: "vocabulary", + type: "static", param: "access", operator: "ac", equalityOperator: " exact ", - filterType: "radio" + filterType: "checkbox" }, ["collectedfrom"]: { name: "Collected From", @@ -272,15 +285,46 @@ export class SearchFieldsBase { operator: "fl", equalityOperator: " exact ", filterType: "checkbox" + }, + ["type"]: { + name: "Type", + type: "static", + param: "type", + operator: "tp", + equalityOperator: " = ", + filterType: "checkbox" } }; + public RESULT_STATIC_FIELD_VALUES: { [key: string]: {"name": string, "id": string, "count": string}[] } = { + ["resultbestaccessright"]: [ + { name: "Open Access", id: "Open Access", count: "0" }, + { name: "Closed Access", id: "Closed Access", count: "0" }, + { name: "Restricted", id: "Restricted", count: "0" }, + { name: "Open Source", id: "Open Source", count: "0" }, + { name: "Embargo", id: "Embargo", count: "0" } + ], + ["type"]: [ + { name: OpenaireEntities.PUBLICATIONS, id: "publications", count: "0" }, + { name: OpenaireEntities.DATASETS, id: "datasets", count: "0" }, + { name: OpenaireEntities.SOFTWARE, id: "software", count: "0" }, + { name: OpenaireEntities.OTHER, id: "other", count: "0" } + ] + }; + //PROJECT public PROJECT_RANGE_FIELDS = [ ["projectendyear", "projectstartyear"] ]; public PROJECT_REFINE_FIELDS: string[] = ["funder", "fundinglevel0_id", "fundinglevel1_id", "fundinglevel2_id", "projectoamandatepublications", "projectstartyear", "projectendyear"]; + + public PROJECT_FIELDS_ORDERED = [ + {type: "refine", title: "", values: ["funder", "fundinglevel0_id", "fundinglevel1_id", "fundinglevel2_id"]}, + {type: "range", title: "", values: ["projectstartyear", "projectendyear"]}, + {type: "refine", title: "", values: ["projectoamandatepublications"]} + ]; + public PROJECT_ADVANCED_FIELDS: string[] = ["q", "projectacronym", "projecttitle", "projectkeywords", "funder", "fundinglevel0_id", "fundinglevel1_id", "fundinglevel2_id", "projectstartdate", "projectenddate", @@ -436,6 +480,8 @@ export class SearchFieldsBase { }; //DATAPROVIDERS + public DATASOURCE_STATIC_FIELDS = ["eosctype"]; + // add Collected From Filter "collectedfromname" public DATASOURCE_REFINE_FIELDS: string[] = ["eoscdatasourcetype", "datasourceodlanguages", "datasourceodcontenttypes", "datasourcecompatibilityname", "country", "collectedfromname", "datasourcethematic", @@ -582,9 +628,24 @@ export class SearchFieldsBase { equalityOperator: " exact ", filterType: "checkbox" }, - ["pid"]: {name: "PID", type: "keyword", param: "pid", operator: "pd", equalityOperator: " exact ", filterType: null} + ["pid"]: {name: "PID", type: "keyword", param: "pid", operator: "pd", equalityOperator: " exact ", filterType: null}, + ["eosctype"]: { + name: "EOSC Type", + type: "static", + param: "type", + operator: "tp", + equalityOperator: " = ", + filterType: "checkbox" + } }; + public DATASOURCE_STATIC_FIELD_VALUES: { [key: string]: {"name": string, "id": string, "count": string}[] } = { + ["eosctype"]: [ + { name: OpenaireEntities.DATASOURCES, id: "Data Source", count: "0" }, + { name: "Other "+OpenaireEntities.SERVICES, id: "Service", count: "0" }, + ] + } + public DEPOSIT_DATASOURCE_KEYWORD_FIELDS: { "name": string, "equalityOperator": string } [] = [ {"name": "relorganizationname", "equalityOperator": "="}, {"name": "relorganizationshortname", "equalityOperator": "="}, diff --git a/utils/staticAutoComplete/staticAutoComplete.component.ts b/utils/staticAutoComplete/staticAutoComplete.component.ts index 55813c50..ed9504c2 100644 --- a/utils/staticAutoComplete/staticAutoComplete.component.ts +++ b/utils/staticAutoComplete/staticAutoComplete.component.ts @@ -59,6 +59,7 @@ export class StaticAutoCompleteComponent implements OnChanges{ @Input() public selectedValue:string = ''; @Input() public vocabularyId:string ; @Input() public fieldName:string ; + @Input() public fieldValues; @Input() public entityName:string ; @Input() public fieldId:string ; @Input() properties:EnvProperties; @@ -115,21 +116,26 @@ export class StaticAutoCompleteComponent implements OnChanges{ } ); }else if(this.fieldName && this.entityName){ - this.sub = this._refineService.getRefineFieldResultsByFieldName(this.fieldName,this.entityName, this.properties).subscribe( - data => { - this.list = data; - this.afterListFetchedActions(); + if(this.fieldValues) { + this.list = this._refineService.parse(this.fieldValues, this.fieldName); + this.afterListFetchedActions(); + } else { + this.sub = this._refineService.getRefineFieldResultsByFieldName(this.fieldName, this.entityName, this.properties).subscribe( + data => { + this.list = data; + this.afterListFetchedActions(); - }, - err => { - //console.log(err); - this.handleError("Error getting results for refine field: "+this.fieldName+" for "+this.entityName, err); - this.warningMessage = "Error, couldn't fetch results..."; - this.showLoading = false; - this.afterListFetchedActions(); - } - ); - }else{ + }, + err => { + //console.log(err); + this.handleError("Error getting results for refine field: " + this.fieldName + " for " + this.entityName, err); + this.warningMessage = "Error, couldn't fetch results..."; + this.showLoading = false; + this.afterListFetchedActions(); + } + ); + } + }else{ this.showLoading = false; }