diff --git a/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.html b/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.html index f54883011a..e253e65048 100644 --- a/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.html +++ b/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.html @@ -1,7 +1,7 @@ + [queryParams]="getQueryParams(value) | async"> - + {{value.value}} ({{value.count}}) diff --git a/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts b/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts index a817eb0d9b..0c9eb06baa 100644 --- a/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts +++ b/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts @@ -30,16 +30,16 @@ export class SidebarFacetFilterComponent implements OnInit { this.currentPage = this.filterService.getPage(this.filterConfig.name); } - isChecked(value: FacetValue) { - return this.filterService.isFilterActive(this.filterConfig.name, value.value); + isChecked(value: FacetValue): Observable { + return this.filterService.isFilterActive(this.filterConfig.paramName, value.value); } getSearchLink() { return this.filterService.searchLink; } - getQueryParams(value: FacetValue): Params { - return this.filterService.switchFilterInURL(this.filterConfig, value.value); + getQueryParams(value: FacetValue): Observable { + return this.filterService.getFilterValueURL(this.filterConfig, value.value); } get facetCount(): Observable { diff --git a/src/app/+search-page/search-filters/search-filter/search-filter.component.html b/src/app/+search-page/search-filters/search-filter/search-filter.component.html index c8fd3ff10c..c78ea9f676 100644 --- a/src/app/+search-page/search-filters/search-filter/search-filter.component.html +++ b/src/app/+search-page/search-filters/search-filter/search-filter.component.html @@ -3,6 +3,6 @@ [ngClass]="(isCollapsed() | async) ? 'fa-plus' : 'fa-minus'">
+ [filterValues]="(filterValues | async)?.payload">
\ No newline at end of file diff --git a/src/app/+search-page/search-filters/search-filter/search-filter.component.ts b/src/app/+search-page/search-filters/search-filter/search-filter.component.ts index cbffe6a8e9..211315e397 100644 --- a/src/app/+search-page/search-filters/search-filter/search-filter.component.ts +++ b/src/app/+search-page/search-filters/search-filter/search-filter.component.ts @@ -22,7 +22,7 @@ import { slide } from '../../../shared/animations/slide'; export class SidebarFilterComponent implements OnInit { @Input() filter: SearchFilterConfig; - filterValues: RemoteData; + filterValues: Observable>; constructor(private searchService: SearchService, private filterService: SearchFilterService) { } diff --git a/src/app/+search-page/search-filters/search-filter/search-filter.service.ts b/src/app/+search-page/search-filters/search-filter/search-filter.service.ts index 258f54aa78..098611bdae 100644 --- a/src/app/+search-page/search-filters/search-filter/search-filter.service.ts +++ b/src/app/+search-page/search-filters/search-filter/search-filter.service.ts @@ -10,7 +10,7 @@ import { SearchFilterToggleAction } from './search-filter.actions'; import { hasValue, isNotEmpty } from '../../../shared/empty.util'; -import { ActivatedRoute, Params, Router } from '@angular/router'; +import { ActivatedRoute, convertToParamMap, Params, Router } from '@angular/router'; import { SearchFilterConfig } from '../../search-service/search-filter-config.model'; import { RemoteData } from '../../../core/data/remote-data'; import { PageInfo } from '../../../core/shared/page-info.model'; @@ -21,55 +21,49 @@ import { SearchService } from '../../search-service/search.service'; const filterStateSelector = (state: SearchFiltersState) => state.searchFilter; @Injectable() -export class SearchFilterService implements OnDestroy { - private sub; +export class SearchFilterService { constructor(private store: Store, private route: ActivatedRoute, - private router: Router, private searchService: SearchService) { + this.route.queryParams.subscribe((params) => { + console.log(params); + }) } - isFilterActive(filterName: string, filterValue: string): boolean { - let filterConfig: SearchFilterConfig; - this.sub = this.searchService.getConfig().payload - .subscribe((configuration) => filterConfig = configuration - .find((config: SearchFilterConfig) => config.name === filterName)); - return isNotEmpty(this.route.snapshot.queryParams[filterConfig.paramName]) && [...this.route.snapshot.queryParams[filterConfig.paramName]].indexOf(filterValue, 0) > -1; + isFilterActive(paramName: string, filterValue: string): Observable { + return this.route.queryParamMap.map((map) => map.getAll(paramName).indexOf(filterValue) > -1 ); } - switchFilterInURL(filterConfig: SearchFilterConfig, value: string) { - console.log(this.route.snapshot.queryParams); - if (this.isFilterActive(filterConfig.name, value)) { - return this.removeQueryParameter(filterConfig.paramName, value); - } else { - return this.addQueryParameter(filterConfig.paramName, value); - } - } - - addQueryParameter(paramName: string, value: string): Params { - const currentParams = this.route.snapshot.queryParams; - const newParam = {}; - if ((currentParams[paramName])) { - newParam[paramName] = [...currentParams[paramName], value]; - } else { - newParam[paramName] = [value]; - } - return Object.assign({}, currentParams, newParam); - } - - removeQueryParameter(paramName: string, value: string): Params { - const currentParams = this.route.snapshot.queryParams; - const newParam = {}; - let currentFilterParams = [...currentParams[paramName]]; - if (isNotEmpty(currentFilterParams)) { - const index = currentFilterParams.indexOf(value, 0); - if (index > -1) { - currentFilterParams = currentFilterParams.splice(index, 1); + getFilterValueURL(filterConfig: SearchFilterConfig, value: string): Observable { + return this.isFilterActive(filterConfig.paramName, value).flatMap((isActive) => { + if (isActive) { + return this.removeQueryParameter(filterConfig.paramName, value); + } else { + return this.addQueryParameter(filterConfig.paramName, value); } - newParam[paramName] = currentFilterParams; - } - return Object.assign({}, currentParams, newParam); + }) + } + + addQueryParameter(paramName: string, value: string): Observable { + return this.route.queryParams.map((currentParams) => { + const newParam = {}; + newParam[paramName] = [...convertToParamMap(currentParams).getAll(paramName), value]; + return Object.assign({}, currentParams, newParam); + }); + } + + removeQueryParameter(paramName: string, value: string): Observable { + return this.route.queryParams.map((currentParams) => { + const newParam = {}; + const currentFilterParams = convertToParamMap(currentParams).getAll(paramName); + if (isNotEmpty(currentFilterParams)) { + newParam[paramName] = currentFilterParams.filter((param) => (param !== value)); + } + console.log(Object.assign({}, currentParams, newParam)); + return Object.assign({}, currentParams, newParam); + }); + } get searchLink() { @@ -113,12 +107,6 @@ export class SearchFilterService implements OnDestroy { public increasePage(filterName: string): void { this.store.dispatch(new SearchFilterIncreasePageAction(filterName)); } - - ngOnDestroy(): void { - if (this.sub !== undefined) { - this.sub.unsubscribe(); - } - } } function filterByNameSelector(name: string): MemoizedSelector { diff --git a/src/app/+search-page/search-filters/search-filters.component.html b/src/app/+search-page/search-filters/search-filters.component.html index 270649598f..9d08545923 100644 --- a/src/app/+search-page/search-filters/search-filters.component.html +++ b/src/app/+search-page/search-filters/search-filters.component.html @@ -1,6 +1,6 @@

{{"search.filters.head" | translate}}

-
-
+
+
diff --git a/src/app/+search-page/search-filters/search-filters.component.ts b/src/app/+search-page/search-filters/search-filters.component.ts index 216e8c0832..8380df7e05 100644 --- a/src/app/+search-page/search-filters/search-filters.component.ts +++ b/src/app/+search-page/search-filters/search-filters.component.ts @@ -2,6 +2,7 @@ import { Component, Input } from '@angular/core'; import { SearchService } from '../search-service/search.service'; import { RemoteData } from '../../core/data/remote-data'; import { SearchFilterConfig } from '../search-service/search-filter-config.model'; +import { Observable } from 'rxjs/Observable'; /** * This component renders a simple item page. @@ -16,7 +17,7 @@ import { SearchFilterConfig } from '../search-service/search-filter-config.model }) export class SidebarFiltersComponent { - filters: RemoteData; + filters: Observable>; constructor(private searchService: SearchService) { this.filters = searchService.getConfig(); } diff --git a/src/app/+search-page/search-page.component.html b/src/app/+search-page/search-page.component.html index 56c1b51fed..7efa1077d3 100644 --- a/src/app/+search-page/search-page.component.html +++ b/src/app/+search-page/search-page.component.html @@ -2,7 +2,7 @@
+ resultCount="{{(results | async)?.pageInfo.totalElements}}">
+ [ngClass]="{'active': !(isSidebarCollapsed() | async)}"> + + + Not Active - Sidebar is collapsed + Active- Sidebar is not collapsed +
diff --git a/src/app/+search-page/search-page.component.spec.ts b/src/app/+search-page/search-page.component.spec.ts index f1b86e3270..a0b31d0ff2 100644 --- a/src/app/+search-page/search-page.component.spec.ts +++ b/src/app/+search-page/search-page.component.spec.ts @@ -1,6 +1,6 @@ import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; import { RouterTestingModule } from '@angular/router/testing'; import { Store } from '@ngrx/store'; import { TranslateModule } from '@ngx-translate/core'; @@ -18,7 +18,7 @@ import { By } from '@angular/platform-browser'; import { NgbCollapseModule } from '@ng-bootstrap/ng-bootstrap'; import { SearchSidebarService } from './search-sidebar/search-sidebar.service'; -describe('SearchPageComponent', () => { +fdescribe('SearchPageComponent', () => { let comp: SearchPageComponent; let fixture: ComponentFixture; let searchServiceObject: SearchService; @@ -41,10 +41,11 @@ describe('SearchPageComponent', () => { }) }; const sidebarService = { - isCollapsed: Observable.of(true), - collapse: () => this.isCollapsed = Observable.of(true), - expand: () => this.isCollapsed = Observable.of(false) - } + collapsed: Observable.of(true), + collapse: () => {this.collapsed = Observable.of(true)}, + expand: () => {console.log('expand'); this.collapsed = Observable.of(false)}, + isCollapsed: () => {if (this.collapse) {this.collapsed.subscribe(a => console.log(a))};return this.collapsed}, + }; const mockCommunityList = []; const communityDataServiceStub = { @@ -178,11 +179,12 @@ describe('SearchPageComponent', () => { beforeEach(() => { menu = fixture.debugElement.query(By.css('#search-sidebar-xs')).nativeElement; - comp.isSidebarCollapsed = () => Observable.of(true); - fixture.detectChanges(); + sidebarService.collapse(); }); it('should close the sidebar', () => { + sidebarService.isCollapsed().subscribe((v) => console.log('after closing, is collapsed is...: ', v)); + console.log(menu.classList); expect(menu.classList).not.toContain('active'); }); @@ -193,12 +195,13 @@ describe('SearchPageComponent', () => { beforeEach(() => { menu = fixture.debugElement.query(By.css('#search-sidebar-xs')).nativeElement; - comp.isSidebarCollapsed = () => Observable.of(false); - fixture.detectChanges(); + sidebarService.expand(); }); it('should open the menu', () => { - sidebarService.isCollapsed.subscribe((a) => {console.log(a)}) + sidebarService.isCollapsed().subscribe((v) => console.log('after opening, is collapsed is...: ', v)); + console.log(menu.classList); + debugger; expect(menu.classList).toContain('active'); }); diff --git a/src/app/+search-page/search-page.component.ts b/src/app/+search-page/search-page.component.ts index 3026256ec8..0b084a46d0 100644 --- a/src/app/+search-page/search-page.component.ts +++ b/src/app/+search-page/search-page.component.ts @@ -107,6 +107,6 @@ export class SearchPageComponent implements OnInit, OnDestroy { } public isSidebarCollapsed(): Observable { - return this.sidebarService.isCollapsed; + return this.sidebarService.isCollapsed(); } } diff --git a/src/app/+search-page/search-sidebar/search-sidebar.service.ts b/src/app/+search-page/search-sidebar/search-sidebar.service.ts index c3e10c8ddb..b474062e93 100644 --- a/src/app/+search-page/search-sidebar/search-sidebar.service.ts +++ b/src/app/+search-page/search-sidebar/search-sidebar.service.ts @@ -19,7 +19,8 @@ export class SearchSidebarService { this.isCollapsdeInStored = this.store.select(sidebarCollapsedSelector); } - get isCollapsed(): Observable { + isCollapsed(): Observable { + console.log('NEEN'); return Observable.combineLatest( this.isMobileView, this.isCollapsdeInStored, diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 14719ed266..8e74150cd6 100755 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -46,7 +46,7 @@ export function getMetaReducers(config: GlobalConfig): Array { + let service: RouteService; + const paramName1 = 'name'; + const paramValue1 = 'Test Name'; + const paramName2 = 'id'; + const paramValue2a = 'Test id'; + const paramValue2b = 'another id'; + const nonExistingParamName = 'non existing name'; + const nonExistingParamValue = 'non existing value'; + + const paramObject: Params = {}; + + paramObject[paramName1] = paramValue1; + paramObject[paramName2] = [paramValue2a, paramValue2b]; + + beforeEach(async(() => { + return TestBed.configureTestingModule({ + declarations: [RouteService], + providers: [ + { + provide: ActivatedRoute, + useValue: { + params: Observable.of([paramObject]), + }, + }, + ] + }); + })); + + beforeEach(() => { + service = new RouteService(TestBed.get(ActivatedRoute)); + }); + + describe('hasQueryParam', () => { + it(' should return true when the parameter name exists', () => { + service.hasQueryParam(paramName1).subscribe((status) => { + expect(status).toBeTruthy(); + }); + }); + it(' should return false when the parameter name does not exists', () => { + service.hasQueryParam(nonExistingParamName).subscribe((status) => { + expect(status).toBeFalsy(); + }); + }); + }); +}); diff --git a/src/app/shared/route.service.ts b/src/app/shared/route.service.ts new file mode 100644 index 0000000000..7f045afa9c --- /dev/null +++ b/src/app/shared/route.service.ts @@ -0,0 +1,47 @@ +import { Injectable, OnDestroy } from '@angular/core'; +import { Observable } from 'rxjs/Observable'; +import { ActivatedRoute, convertToParamMap, Params, } from '@angular/router'; +import { isNotEmpty } from './empty.util'; + +@Injectable() +export class RouteService { + + constructor(private route: ActivatedRoute) { + } + + hasQueryParam(paramName: string): Observable { + return this.route.queryParamMap.map((map) => map.has(paramName)); + } + + hasQueryParamWithValue(paramName: string, paramValue: string): Observable { + return this.route.queryParamMap.map((map) => map.getAll(paramName).indexOf(paramValue) > -1); + } + + addQueryParameterValue(paramName: string, paramValue: string): Observable { + return this.route.queryParams.map((currentParams) => { + const newParam = {}; + newParam[paramName] = [...convertToParamMap(currentParams).getAll(paramName), paramValue]; + return Object.assign({}, currentParams, newParam); + }); + } + + removeQueryParameterValue(paramName: string, paramValue: string): Observable { + return this.route.queryParams.map((currentParams) => { + const newParam = {}; + const currentFilterParams = convertToParamMap(currentParams).getAll(paramName); + if (isNotEmpty(currentFilterParams)) { + newParam[paramName] = currentFilterParams.filter((param) => (param !== paramValue)); + } + return Object.assign({}, currentParams, newParam); + }); + } + + removeQueryParameter(paramName: string): Observable { + return this.route.queryParams.map((currentParams) => { + const newParam = {}; + newParam[paramName] = {}; + return Object.assign({}, currentParams, newParam); + }); + + } +}