From 2901fe8e484a20472d66a88e0cba407602c2068a Mon Sep 17 00:00:00 2001 From: "argiro.kokogiannaki" Date: Tue, 20 Oct 2020 09:11:15 +0000 Subject: [PATCH] [Library|Trunk] - QuickSelection component: - change resultTypes to a Filter - use search-filter compoonent to show the types - add actionRoute property - Action route: - add in filters and range filters, - set it true in search pages, false for filters in claims git-svn-id: https://svn.driver.research-infrastructures.eu/driver/dnet40/modules/uoa-services-library/trunk/ng-openaire-library/src/app@59632 d315682c-612b-4755-9ff5-7f18f6832af3 --- .../claimProjectSearchForm.component.html | 2 +- .../claimResultSearchForm.component.html | 2 +- .../searchUtils/newSearchPage.component.html | 24 +- .../searchUtils/newSearchPage.component.ts | 73 +++--- .../searchUtils/quick-selections.component.ts | 210 ++++++------------ .../searchUtils/quick-selections.module.ts | 3 +- .../searchUtils/searchFilter.component.html | 14 +- .../searchUtils/searchFilter.component.ts | 41 +++- .../searchUtils/searchFilter.module.ts | 3 +- utils/rangeFilter/rangeFilter.component.html | 40 +++- utils/rangeFilter/rangeFilter.component.ts | 29 ++- 11 files changed, 227 insertions(+), 214 deletions(-) diff --git a/claims/claim-utils/claimProjectSearchForm.component.html b/claims/claim-utils/claimProjectSearchForm.component.html index 1196eb8f..af46f6b8 100644 --- a/claims/claim-utils/claimProjectSearchForm.component.html +++ b/claims/claim-utils/claimProjectSearchForm.component.html @@ -151,7 +151,7 @@ + (onFilterChange)="filterChanged($event)" [actionRoute]="false">
@@ -114,20 +115,20 @@ + (onFilterChange)="filterChanged($event)" [quickFilter]="quickFilter" + [actionRoute]="true">
  • - +
  • + (onFilterChange)="filterChanged($event)" [actionRoute]="true">
  • @@ -135,10 +136,11 @@ + (onFilterChange)="filterChanged($event)" [actionRoute]="true"> +
    diff --git a/searchPages/searchUtils/newSearchPage.component.ts b/searchPages/searchUtils/newSearchPage.component.ts index 03efeb3b..8f5c2c76 100644 --- a/searchPages/searchUtils/newSearchPage.component.ts +++ b/searchPages/searchUtils/newSearchPage.component.ts @@ -1,4 +1,4 @@ -import {Component, ElementRef, Input, Output, ViewChild} from '@angular/core'; +import {ChangeDetectorRef, Component, ElementRef, Input, Output, ViewChild} from '@angular/core'; import {Location} from '@angular/common'; import {ActivatedRoute, Router} from '@angular/router'; import {Meta, Title} from '@angular/platform-browser'; @@ -79,9 +79,9 @@ export class NewSearchPageComponent { @Input() keywordFields = []; @Input() simpleView: boolean = true; @Input() formPlaceholderText = "Type Keywords..."; - @Input() resultTypes = null; - resultTypeOptions = [{"id":"publication", "name":"Publications"},{"id":"dataset", "name":"Research data"}, - {"id":"software", "name":"Software"},{"id":"other", "name":" Other research products"}]; + @Input() resultTypes:Filter = {values:[],filterId:"type", countSelectedValues: 0, filterType: 'checkbox', originalFilterId: "", valueIsExact: true, title: "Result Types",filterOperator:"or"}; + resultTypeOptions = {"publications":{"id":"publication", "name":"Publications"},"datasets":{"id":"dataset", "name":"Research data"}, + "software":{"id":"software", "name":"Software"},"other":{"id":"other", "name":" Other research products"}}; selectedTypesNum = 0; @Input() quickFilter: { filter: Filter, selected: boolean, filterId: string, value: string }; @Input() includeOnlyResultsAndFilter:boolean = false; @@ -130,7 +130,8 @@ export class NewSearchPageComponent { private _piwikService: PiwikService, private router: Router, private seoService: SEOService, - private helper: HelperService) { + private helper: HelperService, + private cdr:ChangeDetectorRef) { } ngOnInit() { @@ -276,10 +277,12 @@ export class NewSearchPageComponent { if (this.quickFilter) { this.removeValueFromQuickFilter(); } - this.resultTypes = {}; - for(let type of this.resultTypeOptions){ - this.resultTypes[type.id]=false; - } + // this.resultTypes = new Filter(); + // this.resultTypes.filterId = ""; + this.resultTypes.values = []; + // for(let type of this.resultTypeOptions){ + // this.resultTypes.values.push({name: type.name , id:type.id,selected:false, number:0}); + // } this.goTo(1); // this.clearKeywords(); } @@ -306,8 +309,11 @@ export class NewSearchPageComponent { /* End Piwik Code */ } - queryChanged() { - + queryChanged($event) { + if($event == "filters_update"){ + this.cdr.detectChanges(); + return; + } this.goTo(1, false); } @@ -1022,12 +1028,17 @@ export class NewSearchPageComponent { if (this.entityType == "result") { if (URLparams["type"]) { - let types = URLparams["type"].split(","); + let types = URLparams["type"]; + types = Array.isArray(types) ? types.join(',').split(","):types.split(","); + types.map( function (t) { + return StringUtils.unquote(StringUtils.URIDecode(t)); + } ); + if(types.indexOf("publications")!=-1 && types.indexOf("datasets")!=-1 && types.indexOf("software")!=-1 && types.indexOf("other")!=-1 ){ allFqs += "&type=results"; }else{ for (let type of types) { - allFqs += "&type=" + type; + allFqs += "&type=" + StringUtils.unquote(StringUtils.URIDecode(type)); } } }else{ @@ -1309,17 +1320,8 @@ public static createRangeFilterQuery(rangeField,selectedFromValue, selectedToVal if (this.resultTypes && this.entityType == "result") { let values = []; - if (this.resultTypes.publication) { - values.push("publications"); - } - if (this.resultTypes.dataset) { - values.push("datasets"); - } - if (this.resultTypes.software) { - values.push("software"); - } - if (this.resultTypes.other) { - values.push("other"); + for(let value of this.resultTypes.values){ + values.push(value.id); } this.selectedTypesNum = 0; if (values.length > 0 && values.length != 4) { @@ -1398,23 +1400,16 @@ public static createRangeFilterQuery(rangeField,selectedFromValue, selectedToVal } } if (this.entityType == "result") { - this.resultTypes = null; - this.resultTypes = { - - }; - + this.resultTypes.values = []; if (URLparams["type"]) { + let types = URLparams["type"]; + types = Array.isArray(types) ? types.join(',').split(","):types.split(","); + for(let type of types){ + if(["publications", "datasets","software", "other"].indexOf(StringUtils.unquote(type))!=-1 && this.resultTypeOptions[StringUtils.unquote(type)]){ + this.resultTypes.values.push({name: this.resultTypeOptions[StringUtils.unquote(type)].name , id:StringUtils.unquote(type),selected:true, number:0}); + } + } - this.resultTypes['publication'] = (URLparams["type"].split(",").indexOf("publications") != -1); - this.resultTypes['dataset'] = (URLparams["type"].split(",").indexOf("datasets") != -1); - this.resultTypes['software'] = (URLparams["type"].split(",").indexOf("software") != -1); - this.resultTypes['other'] = (URLparams["type"].split(",").indexOf("other") != -1); - - } else { - this.resultTypes['publication'] = false; - this.resultTypes['dataset'] = false; - this.resultTypes['software'] = false; - this.resultTypes['other'] = false; } } diff --git a/searchPages/searchUtils/quick-selections.component.ts b/searchPages/searchUtils/quick-selections.component.ts index 4fb6e000..74cfa495 100644 --- a/searchPages/searchUtils/quick-selections.component.ts +++ b/searchPages/searchUtils/quick-selections.component.ts @@ -1,86 +1,48 @@ -import {Component, EventEmitter, Input, OnChanges, Output, SimpleChanges} from '@angular/core'; -import {FormBuilder, FormGroup} from "@angular/forms"; +import {ChangeDetectorRef, Component, EventEmitter, Input, Output} from '@angular/core'; +import {FormBuilder} from "@angular/forms"; import {Filter} from "./searchHelperClasses.class"; import {EnvProperties} from "../../utils/properties/env-properties"; import {ConfigurationService} from "../../utils/configuration/configuration.service"; -import {Subject, Subscription} from "rxjs"; -import {debounceTime} from "rxjs/operators"; +import {Subscription} from "rxjs"; +import {ActivatedRoute, Router} from "@angular/router"; @Component({ selector: 'quick-selections', template: ` -
    {{quickFilter.value}} + class="uk-margin-small-left" name="qf" [(ngModel)]="quickFilter.selected" (ngModelChange)="quickFilterChanged()">
    Include: - Publications - Research data - Software - Other research products + + {{value.name}} +
    -
    -
    +
    - - -
  • -
    -
    Research Type ({{(this.showPublications + this.showDatasets + this.showSoftware + this.showOrp)}})
    - - Clear - -
    -
    -
    -
    -
    - -
    -
    -
    -
    - -
    -
    -
    -
    - -
    -
    -
    -
    - -
    -
    -
    -
    -
  • - + +
    + ` }) -export class QuickSelectionsComponent implements OnChanges { - @Input() resultTypes; +export class QuickSelectionsComponent { + @Input() resultTypes:Filter; @Output() typeChange = new EventEmitter(); @Input() isDisabled; @Input() quickFilter: { filter: Filter, selected: boolean, filterId: string, value: string }; - @Input() QFselected: boolean; - control: FormGroup; initialized = false; @Input() properties: EnvProperties; @Input() vertical: boolean=false; @@ -89,55 +51,23 @@ export class QuickSelectionsComponent implements OnChanges { showSoftware: boolean = false; showOrp: boolean = false; showEntities = false; - selectedTypesNum = 0; - @Input() delayTime = 0; - private clicks = new Subject(); + @Input() actionRoute:boolean = false; + queryParams = {}; subs: Subscription[] = []; - constructor(private _fb: FormBuilder, private config: ConfigurationService) { - - this.control = this._fb.group({ - publication: true, - dataset: true, - software: true, - other: true, - QFselected: true - }); - - + constructor(private _fb: FormBuilder, private config: ConfigurationService, private _router: Router, private route: ActivatedRoute, private cdr:ChangeDetectorRef) { } changed() { - if (!this.initialized && this.isDisabled) { - this.initialized = true; - return; - } - this.clicks.next(); - } - actuallyChanged(){ - let value = this.control.getRawValue(); - this.resultTypes.publication = value.publication; - this.resultTypes.dataset = value.dataset; - this.resultTypes.software = value.software; - this.resultTypes.other = value.other; - if (this.resultTypes && !this.resultTypes.publication && !this.resultTypes.dataset && !this.resultTypes.software && !this.resultTypes.other && !this.vertical) { - this.resultTypes.publication = true; - this.resultTypes.dataset = true; - this.resultTypes.software = true; - this.resultTypes.other = true; - this.setFormValues(); - } this.typeChange.emit({}); } quickFilterChanged() { - let value = this.control.getRawValue(); - this.quickFilter.selected = value.QFselected; if(this.quickFilter.filter) { this.quickFilter.filter.countSelectedValues = 0; - if (value.QFselected) { + if (this.quickFilter.selected) { for (let filterValue of this.quickFilter.filter.values) { if((filterValue.name == this.quickFilter.value)) { filterValue.selected = true @@ -156,13 +86,14 @@ export class QuickSelectionsComponent implements OnChanges { } ngOnInit() { - if (this.resultTypes) { - this.setFormValues(); - } - if(this.properties) { + this.route.queryParams.subscribe(params => { + this.queryParams = Object.assign({}, params); + this.initializeFilters(); + }); + + if(this.properties && !this.initialized) { if(this.properties.adminToolsCommunity !== "monitor") { - //this.subs.push(this.config.getCommunityInformation(this.properties, this.properties.adminToolsCommunity).subscribe(data => { - this.subs.push(this.config.communityInformationState.subscribe(data => { + this.subs.push(this.config.communityInformationState.subscribe(data => { if(data) { var showEntity = {}; for (var i = 0; i < data['entities'].length; i++) { @@ -173,6 +104,8 @@ export class QuickSelectionsComponent implements OnChanges { this.showSoftware = showEntity["software"]; this.showOrp = showEntity["orp"]; this.showEntities = this.showPublications || this.showDatasets || this.showSoftware || this.showOrp; + this.initialized = true; + this.initializeFilters(); } }, error => { this.showPublications = true; @@ -180,6 +113,7 @@ export class QuickSelectionsComponent implements OnChanges { this.showSoftware = true; this.showOrp = true; this.showEntities = true; + this.initializeFilters(); })); } else { this.showPublications = true; @@ -187,59 +121,43 @@ export class QuickSelectionsComponent implements OnChanges { this.showSoftware = true; this.showOrp = true; this.showEntities = true; + this.initialized = true; + this.initializeFilters(); } + + }else{ + this.initializeFilters(); } - this.subs.push(this.clicks.pipe( - debounceTime(this.delayTime) - ).subscribe(e =>{this.actuallyChanged()} )); } - + initializeFilters(){ + if(this.showEntities ){ + let selected = []; + for(let value of this.resultTypes.values){ + if(value.selected){ + selected.push(value.id); + } + } + this.resultTypes.countSelectedValues = selected.length; + this.resultTypes.values = []; + if(this.showPublications){ + this.resultTypes.values.push({name: "Publications" , id:"publications",selected:selected.indexOf("publications")!=-1, number:0}); + } + if(this.showDatasets){ + this.resultTypes.values.push({name: "Research data" , id:"datasets",selected:selected.indexOf("datasets")!=-1, number:0}); + } + if(this.showSoftware){ + this.resultTypes.values.push({name: "Software" , id:"software",selected:selected.indexOf("software")!=-1, number:0}); + } + if(this.showOrp){ + this.resultTypes.values.push({name: "Other research products" , id:"other",selected:selected.indexOf("other")!=-1, number:0}); + } + } + this.typeChange.emit("filters_update"); + } public ngOnDestroy() { for (let sub of this.subs) { sub.unsubscribe(); } } - - ngOnChanges(changes: SimpleChanges): void { - if (changes.isDisabled) { - if (changes.isDisabled.currentValue == true) { - this.control.disable(); - } else if (changes.isDisabled.currentValue == false) { - this.control.enable(); - } - } - - if (changes.QFselected) { - let value = this.control.getRawValue(); - if (changes.QFselected.currentValue != value.QFselected) { - this.setFormValues(); - } - - } - if (changes.resultTypes) { - this.setFormValues(); - } - } - - setFormValues() { - this.control.setValue({ - publication: (this.resultTypes && this.resultTypes.publication)?this.resultTypes.publication:null, - dataset: (this.resultTypes && this.resultTypes.dataset)?this.resultTypes.dataset:null, - software: (this.resultTypes && this.resultTypes.software)?this.resultTypes.software:null, - other: (this.resultTypes && this.resultTypes.other)?this.resultTypes.other:null, - QFselected: this.QFselected - }); - this.selectedTypesNum = (this.resultTypes && this.resultTypes.publication)?this.resultTypes.publication:0 + (this.resultTypes && this.resultTypes.dataset)?this.resultTypes.dataset:0+ (this.resultTypes && this.resultTypes.software)?this.resultTypes.software:0 + (this.resultTypes && this.resultTypes.other)?this.resultTypes.other:null; - } - - clearTypes(){ - this.resultTypes.publication = false; - this.resultTypes.dataset = false; - this.resultTypes.software = false; - this.resultTypes.other = false; - this.setFormValues(); - this.changed() - } - } diff --git a/searchPages/searchUtils/quick-selections.module.ts b/searchPages/searchUtils/quick-selections.module.ts index f2cb5f3c..1140b758 100644 --- a/searchPages/searchUtils/quick-selections.module.ts +++ b/searchPages/searchUtils/quick-selections.module.ts @@ -4,11 +4,12 @@ import {FormsModule, ReactiveFormsModule} from '@angular/forms'; import {RouterModule} from '@angular/router'; import {QuickSelectionsComponent} from "./quick-selections.component"; import {MatCheckboxModule, MatSlideToggleModule} from "@angular/material"; +import {SearchFilterModule} from "./searchFilter.module"; @NgModule({ imports: [ CommonModule, FormsModule, - RouterModule, MatCheckboxModule, ReactiveFormsModule, MatSlideToggleModule + RouterModule, MatCheckboxModule, ReactiveFormsModule, MatSlideToggleModule, SearchFilterModule ], declarations: [ QuickSelectionsComponent, diff --git a/searchPages/searchUtils/searchFilter.component.html b/searchPages/searchUtils/searchFilter.component.html index 45c5cb44..65c88f23 100644 --- a/searchPages/searchUtils/searchFilter.component.html +++ b/searchPages/searchUtils/searchFilter.component.html @@ -12,7 +12,7 @@
    - +
    @@ -59,7 +59,7 @@
    - +
    @@ -89,3 +89,13 @@ + + + + + + + + + diff --git a/searchPages/searchUtils/searchFilter.component.ts b/searchPages/searchUtils/searchFilter.component.ts index b498ad0f..1e3c9617 100644 --- a/searchPages/searchUtils/searchFilter.component.ts +++ b/searchPages/searchUtils/searchFilter.component.ts @@ -10,7 +10,9 @@ import { SimpleChanges } from '@angular/core'; import { Filter, Value} from './searchHelperClasses.class'; - +import {ActivatedRoute, NavigationStart, Router} from "@angular/router"; +import {properties} from "../../../../environments/environment"; +import 'rxjs/add/operator/filter'; @Component({ selector: 'search-filter', templateUrl: 'searchFilter.component.html' @@ -33,13 +35,18 @@ export class SearchFilterComponent implements OnInit, OnChanges{ @Output() onFilterChange = new EventEmitter(); keyword = ""; sortBy = "name"; - + queryParams = {}; + @Input() actionRoute:boolean = false; + @Input() quickFilter: { filter: Filter, selected: boolean, filterId: string, value: string }; public isOpen:boolean=false; - constructor () { + constructor (private _router: Router, private route: ActivatedRoute) { } ngOnInit() { + this.route.queryParams.subscribe(params => { + this.queryParams = Object.assign({}, params); + }); this.filter.values = this.filter.values.filter(value => !value.name.toLowerCase().includes('unknown') && !value.name.toLowerCase().includes('not available')); if(this.filter.filterType == "radio"){ this.filter.radioValue = ""; @@ -229,4 +236,32 @@ export class SearchFilterComponent implements OnInit, OnChanges{ console.log(name); return name; } + getRoute(){ + return properties.baseLink + this._router.url.split("?")[0]; + } + getParams(filter:Filter, value:Value){ + let params = Object.assign({}, this.queryParams); + let qf=false; + if(this.quickFilter && this.quickFilter.filterId == filter.filterId && this.quickFilter.selected && value.id == this.quickFilter.value){ + params['qf']="false"; + qf=true; + } + if(params[filter.filterId] && params[filter.filterId].indexOf(encodeURIComponent(value.id))==-1 && !qf) { + //has other values of this filter --> add this value + params[filter.filterId] = params[filter.filterId] + ',' + '"' + encodeURIComponent(value.id) + '"'; + }else if(params[filter.filterId] && params[filter.filterId].indexOf(encodeURIComponent(value.id))!=-1) { + // has this filter and the value -- > remove it + + let values = params[filter.filterId].split(','); + values.splice(values.indexOf('"' + encodeURIComponent(value.id)+'"'), 1); + params[filter.filterId] =values.join(','); + if(values.length == 0){ + delete params[filter.filterId]; + } + } else if(!qf){ + //has no filter, no value --> add the value + params[filter.filterId] = '"' + encodeURIComponent(value.id) + '"' ; + } + return params; + } } diff --git a/searchPages/searchUtils/searchFilter.module.ts b/searchPages/searchUtils/searchFilter.module.ts index cb1dbcd5..b1511284 100644 --- a/searchPages/searchUtils/searchFilter.module.ts +++ b/searchPages/searchUtils/searchFilter.module.ts @@ -6,10 +6,11 @@ import {SearchFilterComponent} from './searchFilter.component'; import{SearchFilterModalComponent} from './searchFilterModal.component'; import {ModalModule} from '../../utils/modal/modal.module'; import {MatSelectModule} from "@angular/material"; +import {RouterModule} from "@angular/router"; @NgModule({ imports: [ - CommonModule, FormsModule, ModalModule, MatSelectModule + CommonModule, FormsModule, ModalModule, MatSelectModule, RouterModule ], declarations: [ SearchFilterComponent, SearchFilterModalComponent diff --git a/utils/rangeFilter/rangeFilter.component.html b/utils/rangeFilter/rangeFilter.component.html index 2d244911..6aa10f87 100644 --- a/utils/rangeFilter/rangeFilter.component.html +++ b/utils/rangeFilter/rangeFilter.component.html @@ -56,24 +56,52 @@
    diff --git a/utils/rangeFilter/rangeFilter.component.ts b/utils/rangeFilter/rangeFilter.component.ts index 20bd0bbe..3167d3b7 100644 --- a/utils/rangeFilter/rangeFilter.component.ts +++ b/utils/rangeFilter/rangeFilter.component.ts @@ -1,6 +1,9 @@ import {Component, Input, Output, EventEmitter} from '@angular/core'; import { RangeFilter } from './rangeFilterHelperClasses.class'; import { Dates } from "../string-utils.class"; +import {ActivatedRoute, Router} from "@angular/router"; +import {Filter, Value} from "../../searchPages/searchUtils/searchHelperClasses.class"; +import {properties} from "../../../../environments/environment"; @Component({ selector: 'range-filter', @@ -20,10 +23,15 @@ export class RangeFilterComponent { public currentYear: number = Dates.currentYear; @Output() onFilterChange = new EventEmitter(); + @Input() actionRoute:boolean = false; + queryParams = {}; + constructor(private _router: Router, private route: ActivatedRoute) {} - constructor() {} - - ngOnInit() {} + ngOnInit() { + this.route.queryParams.subscribe(params => { + this.queryParams = Object.assign({}, params); + }); + } public _formatTitle(title){ return ((title.length > this._maxCharacters)?(title.substring(0,(this._maxCharacters - ('...').length))+"..."):title); @@ -55,4 +63,19 @@ export class RangeFilterComponent { stringToNum(value: string): number { return +(value); } + getFilterUrl(year:number, selected:boolean){ + return properties.baseLink + (this._router.url.indexOf('year=range') == -1 ? this._router.url: (this._router.url.split("year=range"+this.filter.selectedFromValue+':'+this.filter.selectedToValue).join(''))) + (selected ? '' : (this._router.url.indexOf('?')!=-1?'&':'?') +'year=range'+(this.currentYear - year) + ':'+ this.currentYear); + } + getRoute(){ + return properties.baseLink + this._router.url.split("?")[0]; + } + getParams(year:number, selected:boolean){ + let params = Object.assign({}, this.queryParams); + if(!selected){ + params['year'] = 'range'+(this.currentYear - year) + ':'+ this.currentYear; + }else{ + delete params['year']; + } + return params; + } }